X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fmips%2Fpci%2Fops-tx4927.c;h=2a9d7227fe87c98053aa076df91092ff56cb662c;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=9044ff9765ac98427dec5abd1bdcb0e063e2008d;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/arch/mips/pci/ops-tx4927.c b/arch/mips/pci/ops-tx4927.c index 9044ff976..2a9d7227f 100644 --- a/arch/mips/pci/ops-tx4927.c +++ b/arch/mips/pci/ops-tx4927.c @@ -4,6 +4,7 @@ * ahennessy@mvista.com * * Copyright (C) 2000-2001 Toshiba Corporation + * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) * * Based on arch/mips/ddb5xxx/ddb5477/pci_ops.c * @@ -12,6 +13,9 @@ * Much of the code is derived from the original DDB5074 port by * Geert Uytterhoeven * + * Copyright 2004 MontaVista Software Inc. + * Author: Manish Lachwani (mlachwani@mvista.com) + * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your @@ -38,39 +42,26 @@ #include #include -#include +#include #include -#include /* initialize in setup */ struct resource pci_io_resource = { - "pci IO space", - (PCIBIOS_MIN_IO), - ((PCIBIOS_MIN_IO) + (TX4927_PCIIO_SIZE)) - 1, - IORESOURCE_IO + .name = "TX4927 PCI IO SPACE", + .start = 0x1000, + .end = (0x1000 + (TX4927_PCIIO_SIZE)) - 1, + .flags = IORESOURCE_IO }; /* initialize in setup */ struct resource pci_mem_resource = { - "pci memory space", - TX4927_PCIMEM, - TX4927_PCIMEM + TX4927_PCIMEM_SIZE - 1, - IORESOURCE_MEM -}; - -extern struct pci_ops tx4927_pci_ops; - -/* - * h/w only supports devices 0x00 to 0x14 - */ -struct pci_controller tx4927_controller = { - .pci_ops = &tx4927_pci_ops, - .io_resource = &pci_io_resource, - .mem_resource = &pci_mem_resource, + .name = "TX4927 PCI MEM SPACE", + .start = TX4927_PCIMEM, + .end = TX4927_PCIMEM + TX4927_PCIMEM_SIZE - 1, + .flags = IORESOURCE_MEM }; -static int mkaddr(unsigned char bus, unsigned char dev_fn, - unsigned char where, int *flagsp) +static int mkaddr(int bus, int dev_fn, int where, int *flagsp) { if (bus > 0) { /* Type 1 configuration */ @@ -107,107 +98,49 @@ static int check_abort(int flags) return code; } -/* - * We can't address 8 and 16 bit words directly. Instead we have to - * read/write a 32bit word and mask/modify the data we actually want. - */ -static int tx4927_pcibios_read_config_byte(struct pci_dev *dev, - int where, unsigned char *val) +static int tx4927_pcibios_read_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 * val) { - int flags, retval; - unsigned char bus, func_num; + int flags, retval, dev, busno, func; - db_assert((where & 3) == 0); - db_assert(where < (1 << 8)); + busno = bus->number; + dev = PCI_SLOT(devfn); + func = PCI_FUNC(devfn); /* check if the bus is top-level */ - if (dev->bus->parent != NULL) { - bus = dev->bus->number; - db_assert(bus != 0); + if (bus->parent != NULL) { + busno = bus->number; } else { - bus = 0; + busno = 0; } - func_num = PCI_FUNC(dev->devfn); - if (mkaddr(bus, dev->devfn, where, &flags)) + if (mkaddr(busno, devfn, where, &flags)) return -1; -#ifdef __BIG_ENDIAN - *val = - *(volatile u8 *) ((ulong) & tx4927_pcicptr-> - g2pcfgdata | ((where & 3) ^ 3)); + + switch (size) { + case 1: + *val = *(volatile u8 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | +#ifdef __LITTLE_ENDIAN + (where & 3)); #else - *val = - *(volatile u8 *) ((ulong) & tx4927_pcicptr-> - g2pcfgdata | (where & 3)); + ((where & 0x3) ^ 0x3)); #endif - retval = check_abort(flags); - if (retval == PCIBIOS_DEVICE_NOT_FOUND) - *val = 0xff; - return retval; -} - -static int tx4927_pcibios_read_config_word(struct pci_dev *dev, - int where, unsigned short *val) -{ - int flags, retval; - unsigned char bus, func_num; - - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - db_assert((where & 3) == 0); - db_assert(where < (1 << 8)); - - /* check if the bus is top-level */ - if (dev->bus->parent != NULL) { - bus = dev->bus->number; - db_assert(bus != 0); - } else { - bus = 0; - } - - func_num = PCI_FUNC(dev->devfn); - if (mkaddr(bus, dev->devfn, where, &flags)) - return -1; -#ifdef __BIG_ENDIAN - *val = - *(volatile u16 *) ((ulong) & tx4927_pcicptr-> - g2pcfgdata | ((where & 3) ^ 2)); + break; + case 2: + *val = *(volatile u16 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | +#ifdef __LITTLE_ENDIAN + (where & 3)); #else - *val = - *(volatile u16 *) ((ulong) & tx4927_pcicptr-> - g2pcfgdata | (where & 3)); + ((where & 0x3) ^ 0x2)); #endif - retval = check_abort(flags); - if (retval == PCIBIOS_DEVICE_NOT_FOUND) - *val = 0xffff; - return retval; -} - -static int tx4927_pcibios_read_config_dword(struct pci_dev *dev, - int where, unsigned int *val) -{ - int flags, retval; - unsigned char bus, func_num; - - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - - db_assert((where & 3) == 0); - db_assert(where < (1 << 8)); - - /* check if the bus is top-level */ - if (dev->bus->parent != NULL) { - bus = dev->bus->number; - db_assert(bus != 0); - } else { - bus = 0; + break; + case 4: + *val = tx4927_pcicptr->g2pcfgdata; + break; } - func_num = PCI_FUNC(dev->devfn); - if (mkaddr(bus, dev->devfn, where, &flags)) - return -1; - *val = tx4927_pcicptr->g2pcfgdata; retval = check_abort(flags); if (retval == PCIBIOS_DEVICE_NOT_FOUND) *val = 0xffffffff; @@ -215,92 +148,62 @@ static int tx4927_pcibios_read_config_dword(struct pci_dev *dev, return retval; } -static int tx4927_pcibios_write_config_byte(struct pci_dev *dev, - int where, unsigned char val) +static int tx4927_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 val) { - int flags; - unsigned char bus, func_num; + int flags, dev, busno, func; + busno = bus->number; + dev = PCI_SLOT(devfn); + func = PCI_FUNC(devfn); /* check if the bus is top-level */ - if (dev->bus->parent != NULL) { - bus = dev->bus->number; - db_assert(bus != 0); + if (bus->parent != NULL) { + busno = bus->number; } else { - bus = 0; + busno = 0; } - func_num = PCI_FUNC(dev->devfn); - if (mkaddr(bus, dev->devfn, where, &flags)) + if (mkaddr(busno, devfn, where, &flags)) return -1; -#ifdef __BIG_ENDIAN - *(volatile u8 *) ((ulong) & tx4927_pcicptr-> - g2pcfgdata | ((where & 3) ^ 3)) = val; + + switch (size) { + case 1: + *(volatile u8 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | +#ifdef __LITTLE_ENDIAN + (where & 3)) = val; #else - *(volatile u8 *) ((ulong) & tx4927_pcicptr-> - g2pcfgdata | (where & 3)) = val; + ((where & 0x3) ^ 0x3)) = val; #endif - return check_abort(flags); -} + break; -static int tx4927_pcibios_write_config_word(struct pci_dev *dev, - int where, unsigned short val) -{ - int flags; - unsigned char bus, func_num; - - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - /* check if the bus is top-level */ - if (dev->bus->parent != NULL) { - bus = dev->bus->number; - db_assert(bus != 0); - } else { - bus = 0; - } - - func_num = PCI_FUNC(dev->devfn); - if (mkaddr(bus, dev->devfn, where, &flags)) - return -1; -#ifdef __BIG_ENDIAN - *(volatile u16 *) ((ulong) & tx4927_pcicptr-> - g2pcfgdata | ((where & 3) ^ 2)) = val; + case 2: + *(volatile u16 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | +#ifdef __LITTLE_ENDIAN + (where & 3)) = val; #else - *(volatile u16 *) ((ulong) & tx4927_pcicptr-> - g2pcfgdata | (where & 3)) = val; + ((where & 0x3) ^ 0x2)) = val; #endif - return check_abort(flags); -} - -static int tx4927_pcibios_write_config_dword(struct pci_dev *dev, - int where, unsigned int val) -{ - int flags; - unsigned char bus, func_num; - - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - - /* check if the bus is top-level */ - if (dev->bus->parent != NULL) { - bus = dev->bus->number; - db_assert(bus != 0); - } else { - bus = 0; + break; + case 4: + tx4927_pcicptr->g2pcfgdata = val; + break; } - func_num = PCI_FUNC(dev->devfn); - if (mkaddr(bus, dev->devfn, where, &flags)) - return -1; - tx4927_pcicptr->g2pcfgdata = val; return check_abort(flags); } struct pci_ops tx4927_pci_ops = { - tx4927_pcibios_read_config_byte, - tx4927_pcibios_read_config_word, - tx4927_pcibios_read_config_dword, - tx4927_pcibios_write_config_byte, - tx4927_pcibios_write_config_word, - tx4927_pcibios_write_config_dword + tx4927_pcibios_read_config, + tx4927_pcibios_write_config +}; + +/* + * h/w only supports devices 0x00 to 0x14 + */ +struct pci_controller tx4927_controller = { + .pci_ops = &tx4927_pci_ops, + .io_resource = &pci_io_resource, + .mem_resource = &pci_mem_resource, };