diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2015-02-02 23:49:29 +0300 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2015-02-02 23:49:29 +0300 |
commit | 2cd59deaefbc5fb88e6e232664377a02ca3122ed (patch) | |
tree | df886f88d157af744e9d2781628ad3318a05abcf /arch/arm | |
parent | 341f3a2bcfa25462b55ec72939fd21692fa0d7c9 (diff) | |
parent | 029e2151fc4a5760b4ab963d7613f8603084232a (diff) | |
download | linux-2cd59deaefbc5fb88e6e232664377a02ca3122ed.tar.xz |
Merge branch 'pci/config' into next
* pci/config:
PCI: xilinx: Convert to use generic config accessors
PCI: xgene: Convert to use generic config accessors
PCI: tegra: Convert to use generic config accessors
PCI: rcar: Convert to use generic config accessors
PCI: generic: Convert to use generic config accessors
powerpc/powermac: Convert PCI to use generic config accessors
powerpc/fsl_pci: Convert PCI to use generic config accessors
ARM: ks8695: Convert PCI to use generic config accessors
ARM: sa1100: Convert PCI to use generic config accessors
ARM: integrator: Convert PCI to use generic config accessors
ARM: cns3xxx: Convert PCI to use generic config accessors
PCI: Add generic config accessors
powerpc/PCI: Add struct pci_ops member names to initialization
mn10300/PCI: Add struct pci_ops member names to initialization
MIPS: PCI: Add struct pci_ops member names to initialization
frv/PCI: Add struct pci_ops member names to initialization
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-cns3xxx/pcie.c | 52 | ||||
-rw-r--r-- | arch/arm/mach-integrator/pci_v3.c | 62 | ||||
-rw-r--r-- | arch/arm/mach-ks8695/pci.c | 77 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/pci-nanoengine.c | 94 |
4 files changed, 29 insertions, 256 deletions
diff --git a/arch/arm/mach-cns3xxx/pcie.c b/arch/arm/mach-cns3xxx/pcie.c index f6bf9f623d70..c622c306c390 100644 --- a/arch/arm/mach-cns3xxx/pcie.c +++ b/arch/arm/mach-cns3xxx/pcie.c @@ -51,8 +51,8 @@ static struct cns3xxx_pcie *pbus_to_cnspci(struct pci_bus *bus) return sysdata_to_cnspci(bus->sysdata); } -static void __iomem *cns3xxx_pci_cfg_base(struct pci_bus *bus, - unsigned int devfn, int where) +static void __iomem *cns3xxx_pci_map_bus(struct pci_bus *bus, + unsigned int devfn, int where) { struct cns3xxx_pcie *cnspci = pbus_to_cnspci(bus); int busno = bus->number; @@ -88,55 +88,22 @@ static void __iomem *cns3xxx_pci_cfg_base(struct pci_bus *bus, static int cns3xxx_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) { - u32 v; - void __iomem *base; + int ret; u32 mask = (0x1ull << (size * 8)) - 1; int shift = (where % 4) * 8; - base = cns3xxx_pci_cfg_base(bus, devfn, where); - if (!base) { - *val = 0xffffffff; - return PCIBIOS_SUCCESSFUL; - } - - v = __raw_readl(base); + ret = pci_generic_config_read32(bus, devfn, where, size, val); - if (bus->number == 0 && devfn == 0 && - (where & 0xffc) == PCI_CLASS_REVISION) { + if (ret == PCIBIOS_SUCCESSFUL && !bus->number && !devfn && + (where & 0xffc) == PCI_CLASS_REVISION) /* * RC's class is 0xb, but Linux PCI driver needs 0x604 * for a PCIe bridge. So we must fixup the class code * to 0x604 here. */ - v &= 0xff; - v |= 0x604 << 16; - } - - *val = (v >> shift) & mask; - - return PCIBIOS_SUCCESSFUL; -} - -static int cns3xxx_pci_write_config(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 val) -{ - u32 v; - void __iomem *base; - u32 mask = (0x1ull << (size * 8)) - 1; - int shift = (where % 4) * 8; - - base = cns3xxx_pci_cfg_base(bus, devfn, where); - if (!base) - return PCIBIOS_SUCCESSFUL; - - v = __raw_readl(base); - - v &= ~(mask << shift); - v |= (val & mask) << shift; - - __raw_writel(v, base); + *val = ((((*val << shift) & 0xff) | (0x604 << 16)) >> shift) & mask; - return PCIBIOS_SUCCESSFUL; + return ret; } static int cns3xxx_pci_setup(int nr, struct pci_sys_data *sys) @@ -155,8 +122,9 @@ static int cns3xxx_pci_setup(int nr, struct pci_sys_data *sys) } static struct pci_ops cns3xxx_pcie_ops = { + .map_bus = cns3xxx_pci_map_bus, .read = cns3xxx_pci_read_config, - .write = cns3xxx_pci_write_config, + .write = pci_generic_config_write, }; static int cns3xxx_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index c186a17c2cff..2565f0e7b5cf 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c @@ -356,7 +356,6 @@ static u64 pre_mem_pci_sz; * 7:2 register number * */ -static DEFINE_RAW_SPINLOCK(v3_lock); #undef V3_LB_BASE_PREFETCH #define V3_LB_BASE_PREFETCH 0 @@ -457,67 +456,21 @@ static void v3_close_config_window(void) static int v3_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) { - void __iomem *addr; - unsigned long flags; - u32 v; - - raw_spin_lock_irqsave(&v3_lock, flags); - addr = v3_open_config_window(bus, devfn, where); - - switch (size) { - case 1: - v = __raw_readb(addr); - break; - - case 2: - v = __raw_readw(addr); - break; - - default: - v = __raw_readl(addr); - break; - } - + int ret = pci_generic_config_read(bus, devfn, where, size, val); v3_close_config_window(); - raw_spin_unlock_irqrestore(&v3_lock, flags); - - *val = v; - return PCIBIOS_SUCCESSFUL; + return ret; } static int v3_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) { - void __iomem *addr; - unsigned long flags; - - raw_spin_lock_irqsave(&v3_lock, flags); - addr = v3_open_config_window(bus, devfn, where); - - switch (size) { - case 1: - __raw_writeb((u8)val, addr); - __raw_readb(addr); - break; - - case 2: - __raw_writew((u16)val, addr); - __raw_readw(addr); - break; - - case 4: - __raw_writel(val, addr); - __raw_readl(addr); - break; - } - + int ret = pci_generic_config_write(bus, devfn, where, size, val); v3_close_config_window(); - raw_spin_unlock_irqrestore(&v3_lock, flags); - - return PCIBIOS_SUCCESSFUL; + return ret; } static struct pci_ops pci_v3_ops = { + .map_bus = v3_open_config_window, .read = v3_read_config, .write = v3_write_config, }; @@ -658,7 +611,6 @@ static int __init pci_v3_setup(int nr, struct pci_sys_data *sys) */ static void __init pci_v3_preinit(void) { - unsigned long flags; unsigned int temp; phys_addr_t io_address = pci_pio_to_address(io_mem.start); @@ -672,8 +624,6 @@ static void __init pci_v3_preinit(void) hook_fault_code(8, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch"); hook_fault_code(10, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch"); - raw_spin_lock_irqsave(&v3_lock, flags); - /* * Unlock V3 registers, but only if they were previously locked. */ @@ -736,8 +686,6 @@ static void __init pci_v3_preinit(void) v3_writew(V3_LB_CFG, v3_readw(V3_LB_CFG) | (1 << 10)); v3_writeb(V3_LB_IMASK, 0x28); __raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET); - - raw_spin_unlock_irqrestore(&v3_lock, flags); } static void __init pci_v3_postinit(void) diff --git a/arch/arm/mach-ks8695/pci.c b/arch/arm/mach-ks8695/pci.c index bb18193b4bac..c1bc4c3716ed 100644 --- a/arch/arm/mach-ks8695/pci.c +++ b/arch/arm/mach-ks8695/pci.c @@ -38,8 +38,6 @@ static int pci_dbg; -static int pci_cfg_dbg; - static void ks8695_pci_setupconfig(unsigned int bus_nr, unsigned int devfn, unsigned int where) { @@ -59,75 +57,11 @@ static void ks8695_pci_setupconfig(unsigned int bus_nr, unsigned int devfn, unsi } } - -/* - * The KS8695 datasheet prohibits anything other than 32bit accesses - * to the IO registers, so all our configuration must be done with - * 32bit operations, and the correct bit masking and shifting. - */ - -static int ks8695_pci_readconfig(struct pci_bus *bus, - unsigned int devfn, int where, int size, u32 *value) -{ - ks8695_pci_setupconfig(bus->number, devfn, where); - - *value = __raw_readl(KS8695_PCI_VA + KS8695_PBCD); - - switch (size) { - case 4: - break; - case 2: - *value = *value >> ((where & 2) * 8); - *value &= 0xffff; - break; - case 1: - *value = *value >> ((where & 3) * 8); - *value &= 0xff; - break; - } - - if (pci_cfg_dbg) { - printk("read: %d,%08x,%02x,%d: %08x (%08x)\n", - bus->number, devfn, where, size, *value, - __raw_readl(KS8695_PCI_VA + KS8695_PBCD)); - } - - return PCIBIOS_SUCCESSFUL; -} - -static int ks8695_pci_writeconfig(struct pci_bus *bus, - unsigned int devfn, int where, int size, u32 value) +static void __iomem *ks8695_pci_map_bus(struct pci_bus *bus, unsigned int devfn, + int where) { - unsigned long tmp; - - if (pci_cfg_dbg) { - printk("write: %d,%08x,%02x,%d: %08x\n", - bus->number, devfn, where, size, value); - } - ks8695_pci_setupconfig(bus->number, devfn, where); - - switch (size) { - case 4: - __raw_writel(value, KS8695_PCI_VA + KS8695_PBCD); - break; - case 2: - tmp = __raw_readl(KS8695_PCI_VA + KS8695_PBCD); - tmp &= ~(0xffff << ((where & 2) * 8)); - tmp |= value << ((where & 2) * 8); - - __raw_writel(tmp, KS8695_PCI_VA + KS8695_PBCD); - break; - case 1: - tmp = __raw_readl(KS8695_PCI_VA + KS8695_PBCD); - tmp &= ~(0xff << ((where & 3) * 8)); - tmp |= value << ((where & 3) * 8); - - __raw_writel(tmp, KS8695_PCI_VA + KS8695_PBCD); - break; - } - - return PCIBIOS_SUCCESSFUL; + return KS8695_PCI_VA + KS8695_PBCD; } static void ks8695_local_writeconfig(int where, u32 value) @@ -137,8 +71,9 @@ static void ks8695_local_writeconfig(int where, u32 value) } static struct pci_ops ks8695_pci_ops = { - .read = ks8695_pci_readconfig, - .write = ks8695_pci_writeconfig, + .map_bus = ks8695_pci_map_bus, + .read = pci_generic_config_read32, + .write = pci_generic_config_write32, }; static struct resource pci_mem = { diff --git a/arch/arm/mach-sa1100/pci-nanoengine.c b/arch/arm/mach-sa1100/pci-nanoengine.c index b704433c529c..d7ae8d50f6d8 100644 --- a/arch/arm/mach-sa1100/pci-nanoengine.c +++ b/arch/arm/mach-sa1100/pci-nanoengine.c @@ -22,7 +22,6 @@ #include <linux/kernel.h> #include <linux/irq.h> #include <linux/pci.h> -#include <linux/spinlock.h> #include <asm/mach/pci.h> #include <asm/mach-types.h> @@ -30,97 +29,20 @@ #include <mach/nanoengine.h> #include <mach/hardware.h> -static DEFINE_SPINLOCK(nano_lock); - -static int nanoengine_get_pci_address(struct pci_bus *bus, - unsigned int devfn, int where, void __iomem **address) +static void __iomem *nanoengine_pci_map_bus(struct pci_bus *bus, + unsigned int devfn, int where) { - int ret = PCIBIOS_DEVICE_NOT_FOUND; - unsigned int busnr = bus->number; + if (bus->number != 0 || (devfn >> 3) != 0) + return NULL; - *address = (void __iomem *)NANO_PCI_CONFIG_SPACE_VIRT + + return (void __iomem *)NANO_PCI_CONFIG_SPACE_VIRT + ((bus->number << 16) | (devfn << 8) | (where & ~3)); - - ret = (busnr > 255 || devfn > 255 || where > 255) ? - PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; - - return ret; -} - -static int nanoengine_read_config(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 *val) -{ - int ret; - void __iomem *address; - unsigned long flags; - u32 v; - - /* nanoEngine PCI bridge does not return -1 for a non-existing - * device. We must fake the answer. We know that the only valid - * device is device zero at bus 0, which is the network chip. */ - if (bus->number != 0 || (devfn >> 3) != 0) { - v = -1; - nanoengine_get_pci_address(bus, devfn, where, &address); - goto exit_function; - } - - spin_lock_irqsave(&nano_lock, flags); - - ret = nanoengine_get_pci_address(bus, devfn, where, &address); - if (ret != PCIBIOS_SUCCESSFUL) - return ret; - v = __raw_readl(address); - - spin_unlock_irqrestore(&nano_lock, flags); - - v >>= ((where & 3) * 8); - v &= (unsigned long)(-1) >> ((4 - size) * 8); - -exit_function: - *val = v; - return PCIBIOS_SUCCESSFUL; -} - -static int nanoengine_write_config(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 val) -{ - int ret; - void __iomem *address; - unsigned long flags; - unsigned shift; - u32 v; - - shift = (where & 3) * 8; - - spin_lock_irqsave(&nano_lock, flags); - - ret = nanoengine_get_pci_address(bus, devfn, where, &address); - if (ret != PCIBIOS_SUCCESSFUL) - return ret; - v = __raw_readl(address); - switch (size) { - case 1: - v &= ~(0xFF << shift); - v |= val << shift; - break; - case 2: - v &= ~(0xFFFF << shift); - v |= val << shift; - break; - case 4: - v = val; - break; - } - __raw_writel(v, address); - - spin_unlock_irqrestore(&nano_lock, flags); - - return PCIBIOS_SUCCESSFUL; } static struct pci_ops pci_nano_ops = { - .read = nanoengine_read_config, - .write = nanoengine_write_config, + .map_bus = nanoengine_pci_map_bus, + .read = pci_generic_config_read32, + .write = pci_generic_config_write32, }; static int __init pci_nanoengine_map_irq(const struct pci_dev *dev, u8 slot, |