diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-10 14:31:28 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-10 14:31:28 -0800 |
commit | c08f8467939e7d2eebcba7cf2330242c4f53f2f7 (patch) | |
tree | 3430b9acdac374da5fda10d913b52f608494894c /arch | |
parent | bdccc4edeb03ad68c55053b0260bdaaac547bbd9 (diff) | |
parent | cb8e92d8e4d9f8562071b6ab39e1b837e9e7af39 (diff) |
Merge tag 'pci-v3.20-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI changes from Bjorn Helgaas:
"Enumeration
- Move domain assignment from arm64 to generic code (Lorenzo Pieralisi)
- ARM: Remove artificial dependency on pci_sys_data domain (Lorenzo Pieralisi)
- ARM: Move to generic PCI domains (Lorenzo Pieralisi)
- Generate uppercase hex for modalias var in uevent (Ricardo Ribalda Delgado)
- Add and use generic config accessors on ARM, PowerPC (Rob Herring)
Resource management
- Free resources on failure in of_pci_get_host_bridge_resources() (Lorenzo Pieralisi)
- Fix infinite loop with ROM image of size 0 (Michel Dänzer)
PCI device hotplug
- Handle surprise add even if surprise removal isn't supported (Bjorn Helgaas)
Virtualization
- Mark AMD/ATI VGA devices that don't reset on D3hot->D0 transition (Alex Williamson)
- Add DMA alias quirk for Adaptec 3405 (Alex Williamson)
- Add Wellsburg (X99) to Intel PCH root port ACS quirk (Alex Williamson)
- Add ACS quirk for Emulex NICs (Vasundhara Volam)
MSI
- Fail MSI-X mappings if there's no space assigned to MSI-X BAR (Yijing Wang)
Freescale Layerscape host bridge driver
- Fix platform_no_drv_owner.cocci warnings (Julia Lawall)
NVIDIA Tegra host bridge driver
- Remove unnecessary tegra_pcie_fixup_bridge() (Lucas Stach)
Renesas R-Car host bridge driver
- Fix error handling of irq_of_parse_and_map() (Dmitry Torokhov)
TI Keystone host bridge driver
- Fix error handling of irq_of_parse_and_map() (Dmitry Torokhov)
- Fix misspelling of current function in debug output (Julia Lawall)
Xilinx AXI host bridge driver
- Fix harmless format string warning (Arnd Bergmann)
Miscellaneous
- Use standard parsing functions for ASPM sysfs setters (Chris J Arges)
- Add pci_device_to_OF_node() stub for !CONFIG_OF (Kevin Hao)
- Delete unnecessary NULL pointer checks (Markus Elfring)
- Add and use defines for PCIe Max_Read_Request_Size (Rafał Miłecki)
- Include clk.h instead of clk-private.h (Stephen Boyd)"
* tag 'pci-v3.20-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (48 commits)
PCI: Add pci_device_to_OF_node() stub for !CONFIG_OF
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
PCI: versatile: Add DT-based ARM Versatile PB PCIe host driver
ARM: dts: versatile: add PCI controller binding
of/pci: Free resources on failure in of_pci_get_host_bridge_resources()
PCI: versatile: Add DT docs for ARM Versatile PB PCIe driver
PCI: Fail MSI-X mappings if there's no space assigned to MSI-X BAR
r8169: use PCI define for Max_Read_Request_Size
[SCSI] esas2r: use PCI define for Max_Read_Request_Size
tile: use PCI define for Max_Read_Request_Size
rapidio/tsi721: use PCI define for Max_Read_Request_Size
...
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/Kconfig | 3 | ||||
-rw-r--r-- | arch/arm/boot/dts/versatile-pb.dts | 37 | ||||
-rw-r--r-- | arch/arm/include/asm/mach/pci.h | 6 | ||||
-rw-r--r-- | arch/arm/include/asm/pci.h | 7 | ||||
-rw-r--r-- | arch/arm/kernel/bios32.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-cns3xxx/pcie.c | 92 | ||||
-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 | ||||
-rw-r--r-- | arch/arm64/kernel/pci.c | 22 | ||||
-rw-r--r-- | arch/frv/mb93090-mb00/pci-vdk.c | 4 | ||||
-rw-r--r-- | arch/mips/pci/pci-bcm1480.c | 4 | ||||
-rw-r--r-- | arch/mips/pci/pci-octeon.c | 4 | ||||
-rw-r--r-- | arch/mips/pci/pcie-octeon.c | 12 | ||||
-rw-r--r-- | arch/mn10300/unit-asb2305/pci.c | 4 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/celleb_scc_pciex.c | 4 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/pci.c | 209 | ||||
-rw-r--r-- | arch/powerpc/sysdev/fsl_pci.c | 46 | ||||
-rw-r--r-- | arch/tile/kernel/pci.c | 4 | ||||
-rw-r--r-- | arch/x86/pci/xen.c | 4 |
20 files changed, 150 insertions, 548 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 97d07ed60a0b..dcb2e0c55be4 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1279,6 +1279,9 @@ config PCI_DOMAINS bool depends on PCI +config PCI_DOMAINS_GENERIC + def_bool PCI_DOMAINS + config PCI_NANOENGINE bool "BSE nanoEngine PCI support" depends on SA1100_NANOENGINE diff --git a/arch/arm/boot/dts/versatile-pb.dts b/arch/arm/boot/dts/versatile-pb.dts index e36c1e82fea7..b83137f66034 100644 --- a/arch/arm/boot/dts/versatile-pb.dts +++ b/arch/arm/boot/dts/versatile-pb.dts @@ -29,6 +29,43 @@ clock-names = "apb_pclk"; }; + pci-controller@10001000 { + compatible = "arm,versatile-pci"; + device_type = "pci"; + reg = <0x10001000 0x1000 + 0x41000000 0x10000 + 0x42000000 0x100000>; + bus-range = <0 0xff>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + + ranges = <0x01000000 0 0x00000000 0x43000000 0 0x00010000 /* downstream I/O */ + 0x02000000 0 0x50000000 0x50000000 0 0x10000000 /* non-prefetchable memory */ + 0x42000000 0 0x60000000 0x60000000 0 0x10000000>; /* prefetchable memory */ + + interrupt-map-mask = <0x1800 0 0 7>; + interrupt-map = <0x1800 0 0 1 &sic 28 + 0x1800 0 0 2 &sic 29 + 0x1800 0 0 3 &sic 30 + 0x1800 0 0 4 &sic 27 + + 0x1000 0 0 1 &sic 27 + 0x1000 0 0 2 &sic 28 + 0x1000 0 0 3 &sic 29 + 0x1000 0 0 4 &sic 30 + + 0x0800 0 0 1 &sic 30 + 0x0800 0 0 2 &sic 27 + 0x0800 0 0 3 &sic 28 + 0x0800 0 0 4 &sic 29 + + 0x0000 0 0 1 &sic 29 + 0x0000 0 0 2 &sic 30 + 0x0000 0 0 3 &sic 27 + 0x0000 0 0 4 &sic 28>; + }; + fpga { uart@9000 { compatible = "arm,pl011", "arm,primecell"; diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h index 8292b5f81e23..28b9bb35949e 100644 --- a/arch/arm/include/asm/mach/pci.h +++ b/arch/arm/include/asm/mach/pci.h @@ -19,9 +19,6 @@ struct pci_bus; struct device; struct hw_pci { -#ifdef CONFIG_PCI_DOMAINS - int domain; -#endif #ifdef CONFIG_PCI_MSI struct msi_controller *msi_ctrl; #endif @@ -45,9 +42,6 @@ struct hw_pci { * Per-controller structure */ struct pci_sys_data { -#ifdef CONFIG_PCI_DOMAINS - int domain; -#endif #ifdef CONFIG_PCI_MSI struct msi_controller *msi_ctrl; #endif diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h index 7e95d8535e24..585dc33a7a24 100644 --- a/arch/arm/include/asm/pci.h +++ b/arch/arm/include/asm/pci.h @@ -18,13 +18,6 @@ static inline int pcibios_assign_all_busses(void) } #ifdef CONFIG_PCI_DOMAINS -static inline int pci_domain_nr(struct pci_bus *bus) -{ - struct pci_sys_data *root = bus->sysdata; - - return root->domain; -} - static inline int pci_proc_domain(struct pci_bus *bus) { return pci_domain_nr(bus); diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index a4effd6d8f2f..ddd75c58b1e8 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -463,9 +463,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw, if (!sys) panic("PCI: unable to allocate sys data!"); -#ifdef CONFIG_PCI_DOMAINS - sys->domain = hw->domain; -#endif #ifdef CONFIG_PCI_MSI sys->msi_ctrl = hw->msi_ctrl; #endif diff --git a/arch/arm/mach-cns3xxx/pcie.c b/arch/arm/mach-cns3xxx/pcie.c index 45d6bd09e6ef..c622c306c390 100644 --- a/arch/arm/mach-cns3xxx/pcie.c +++ b/arch/arm/mach-cns3xxx/pcie.c @@ -30,18 +30,15 @@ struct cns3xxx_pcie { unsigned int irqs[2]; struct resource res_io; struct resource res_mem; - struct hw_pci hw_pci; - + int port; bool linked; }; -static struct cns3xxx_pcie cns3xxx_pcie[]; /* forward decl. */ - static struct cns3xxx_pcie *sysdata_to_cnspci(void *sysdata) { struct pci_sys_data *root = sysdata; - return &cns3xxx_pcie[root->domain]; + return root->private_data; } static struct cns3xxx_pcie *pdev_to_cnspci(const struct pci_dev *dev) @@ -54,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; @@ -91,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 = ((((*val << shift) & 0xff) | (0x604 << 16)) >> shift) & mask; - *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); - - return PCIBIOS_SUCCESSFUL; + return ret; } static int cns3xxx_pci_setup(int nr, struct pci_sys_data *sys) @@ -158,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) @@ -192,13 +157,7 @@ static struct cns3xxx_pcie cns3xxx_pcie[] = { .flags = IORESOURCE_MEM, }, .irqs = { IRQ_CNS3XXX_PCIE0_RC, IRQ_CNS3XXX_PCIE0_DEVICE, }, - .hw_pci = { - .domain = 0, - .nr_controllers = 1, - .ops = &cns3xxx_pcie_ops, - .setup = cns3xxx_pci_setup, - .map_irq = cns3xxx_pcie_map_irq, - }, + .port = 0, }, [1] = { .host_regs = (void __iomem *)CNS3XXX_PCIE1_HOST_BASE_VIRT, @@ -217,19 +176,13 @@ static struct cns3xxx_pcie cns3xxx_pcie[] = { .flags = IORESOURCE_MEM, }, .irqs = { IRQ_CNS3XXX_PCIE1_RC, IRQ_CNS3XXX_PCIE1_DEVICE, }, - .hw_pci = { - .domain = 1, - .nr_controllers = 1, - .ops = &cns3xxx_pcie_ops, - .setup = cns3xxx_pci_setup, - .map_irq = cns3xxx_pcie_map_irq, - }, + .port = 1, }, }; static void __init cns3xxx_pcie_check_link(struct cns3xxx_pcie *cnspci) { - int port = cnspci->hw_pci.domain; + int port = cnspci->port; u32 reg; unsigned long time; @@ -260,9 +213,9 @@ static void __init cns3xxx_pcie_check_link(struct cns3xxx_pcie *cnspci) static void __init cns3xxx_pcie_hw_init(struct cns3xxx_pcie *cnspci) { - int port = cnspci->hw_pci.domain; + int port = cnspci->port; struct pci_sys_data sd = { - .domain = port, + .private_data = cnspci, }; struct pci_bus bus = { .number = 0, @@ -323,6 +276,14 @@ static int cns3xxx_pcie_abort_handler(unsigned long addr, unsigned int fsr, void __init cns3xxx_pcie_init_late(void) { int i; + void *private_data; + struct hw_pci hw_pci = { + .nr_controllers = 1, + .ops = &cns3xxx_pcie_ops, + .setup = cns3xxx_pci_setup, + .map_irq = cns3xxx_pcie_map_irq, + .private_data = &private_data, + }; pcibios_min_io = 0; pcibios_min_mem = 0; @@ -335,7 +296,8 @@ void __init cns3xxx_pcie_init_late(void) cns3xxx_pwr_soft_rst(0x1 << PM_SOFT_RST_REG_OFFST_PCIE(i)); cns3xxx_pcie_check_link(&cns3xxx_pcie[i]); cns3xxx_pcie_hw_init(&cns3xxx_pcie[i]); - pci_common_init(&cns3xxx_pcie[i].hw_pci); + private_data = &cns3xxx_pcie[i]; + pci_common_init(&hw_pci); } pci_assign_unassigned_resources(); 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, diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c index ce5836c14ec1..6f93c24ca801 100644 --- a/arch/arm64/kernel/pci.c +++ b/arch/arm64/kernel/pci.c @@ -46,25 +46,3 @@ int pcibios_add_device(struct pci_dev *dev) return 0; } - - -#ifdef CONFIG_PCI_DOMAINS_GENERIC -static bool dt_domain_found = false; - -void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent) -{ - int domain = of_get_pci_domain_nr(parent->of_node); - - if (domain >= 0) { - dt_domain_found = true; - } else if (dt_domain_found == true) { - dev_err(parent, "Node %s is missing \"linux,pci-domain\" property in DT\n", - parent->of_node->full_name); - return; - } else { - domain = pci_get_new_domain_nr(); - } - - bus->domain_nr = domain; -} -#endif diff --git a/arch/frv/mb93090-mb00/pci-vdk.c b/arch/frv/mb93090-mb00/pci-vdk.c index efa5d65b0007..b073f4d771a5 100644 --- a/arch/frv/mb93090-mb00/pci-vdk.c +++ b/arch/frv/mb93090-mb00/pci-vdk.c @@ -168,8 +168,8 @@ static int pci_frv_write_config(struct pci_bus *bus, unsigned int devfn, int whe } static struct pci_ops pci_direct_frv = { - pci_frv_read_config, - pci_frv_write_config, + .read = pci_frv_read_config, + .write = pci_frv_write_config, }; /* diff --git a/arch/mips/pci/pci-bcm1480.c b/arch/mips/pci/pci-bcm1480.c index 5ec2a7bae02c..f2355e3e65a1 100644 --- a/arch/mips/pci/pci-bcm1480.c +++ b/arch/mips/pci/pci-bcm1480.c @@ -173,8 +173,8 @@ static int bcm1480_pcibios_write(struct pci_bus *bus, unsigned int devfn, } struct pci_ops bcm1480_pci_ops = { - bcm1480_pcibios_read, - bcm1480_pcibios_write, + .read = bcm1480_pcibios_read, + .write = bcm1480_pcibios_write, }; static struct resource bcm1480_mem_resource = { diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c index d07e04121cc6..bedb72bd3a27 100644 --- a/arch/mips/pci/pci-octeon.c +++ b/arch/mips/pci/pci-octeon.c @@ -327,8 +327,8 @@ static int octeon_write_config(struct pci_bus *bus, unsigned int devfn, static struct pci_ops octeon_pci_ops = { - octeon_read_config, - octeon_write_config, + .read = octeon_read_config, + .write = octeon_write_config, }; static struct resource octeon_pci_mem_resource = { diff --git a/arch/mips/pci/pcie-octeon.c b/arch/mips/pci/pcie-octeon.c index 5e36c33e5543..eb4a17ba4a53 100644 --- a/arch/mips/pci/pcie-octeon.c +++ b/arch/mips/pci/pcie-octeon.c @@ -1792,8 +1792,8 @@ static int octeon_dummy_write_config(struct pci_bus *bus, unsigned int devfn, } static struct pci_ops octeon_pcie0_ops = { - octeon_pcie0_read_config, - octeon_pcie0_write_config, + .read = octeon_pcie0_read_config, + .write = octeon_pcie0_write_config, }; static struct resource octeon_pcie0_mem_resource = { @@ -1813,8 +1813,8 @@ static struct pci_controller octeon_pcie0_controller = { }; static struct pci_ops octeon_pcie1_ops = { - octeon_pcie1_read_config, - octeon_pcie1_write_config, + .read = octeon_pcie1_read_config, + .write = octeon_pcie1_write_config, }; static struct resource octeon_pcie1_mem_resource = { @@ -1834,8 +1834,8 @@ static struct pci_controller octeon_pcie1_controller = { }; static struct pci_ops octeon_dummy_ops = { - octeon_dummy_read_config, - octeon_dummy_write_config, + .read = octeon_dummy_read_config, + .write = octeon_dummy_write_config, }; static struct resource octeon_dummy_mem_resource = { diff --git a/arch/mn10300/unit-asb2305/pci.c b/arch/mn10300/unit-asb2305/pci.c index 471ff398090c..613ca1e55b4b 100644 --- a/arch/mn10300/unit-asb2305/pci.c +++ b/arch/mn10300/unit-asb2305/pci.c @@ -228,8 +228,8 @@ static int pci_ampci_write_config(struct pci_bus *bus, unsigned int devfn, } static struct pci_ops pci_direct_ampci = { - pci_ampci_read_config, - pci_ampci_write_config, + .read = pci_ampci_read_config, + .write = pci_ampci_write_config, }; /* diff --git a/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/arch/powerpc/platforms/cell/celleb_scc_pciex.c index f22387598040..94170e4f2ce7 100644 --- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c +++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c @@ -399,8 +399,8 @@ static int scc_pciex_write_config(struct pci_bus *bus, unsigned int devfn, } static struct pci_ops scc_pciex_pci_ops = { - scc_pciex_read_config, - scc_pciex_write_config, + .read = scc_pciex_read_config, + .write = scc_pciex_write_config, }; static void pciex_clear_intr_all(unsigned int __iomem *base) diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index 04702db35d45..f4071a67ad00 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c @@ -133,17 +133,23 @@ static void __init fixup_bus_range(struct device_node *bridge) |(((unsigned int)(off)) & 0xFCUL) \ |1UL) -static volatile void __iomem *macrisc_cfg_access(struct pci_controller* hose, - u8 bus, u8 dev_fn, u8 offset) +static void __iomem *macrisc_cfg_map_bus(struct pci_bus *bus, + unsigned int dev_fn, + int offset) { unsigned int caddr; + struct pci_controller *hose; - if (bus == hose->first_busno) { + hose = pci_bus_to_host(bus); + if (hose == NULL) + return NULL; + + if (bus->number == hose->first_busno) { if (dev_fn < (11 << 3)) return NULL; caddr = MACRISC_CFA0(dev_fn, offset); } else - caddr = MACRISC_CFA1(bus, dev_fn, offset); + caddr = MACRISC_CFA1(bus->number, dev_fn, offset); /* Uninorth will return garbage if we don't read back the value ! */ do { @@ -154,129 +160,46 @@ static volatile void __iomem *macrisc_cfg_access(struct pci_controller* hose, return hose->cfg_data + offset; } -static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn, - int offset, int len, u32 *val) -{ - struct pci_controller *hose; - volatile void __iomem *addr; - - hose = pci_bus_to_host(bus); - if (hose == NULL) - return PCIBIOS_DEVICE_NOT_FOUND; - if (offset >= 0x100) - return PCIBIOS_BAD_REGISTER_NUMBER; - addr = macrisc_cfg_access(hose, bus->number, devfn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - /* - * Note: the caller has already checked that offset is - * suitably aligned and that len is 1, 2 or 4. - */ - switch (len) { - case 1: - *val = in_8(addr); - break; - case 2: - *val = in_le16(addr); - break; - default: - *val = in_le32(addr); - break; - } - return PCIBIOS_SUCCESSFUL; -} - -static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn, - int offset, int len, u32 val) -{ - struct pci_controller *hose; - volatile void __iomem *addr; - - hose = pci_bus_to_host(bus); - if (hose == NULL) - return PCIBIOS_DEVICE_NOT_FOUND; - if (offset >= 0x100) - return PCIBIOS_BAD_REGISTER_NUMBER; - addr = macrisc_cfg_access(hose, bus->number, devfn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - /* - * Note: the caller has already checked that offset is - * suitably aligned and that len is 1, 2 or 4. - */ - switch (len) { - case 1: - out_8(addr, val); - break; - case 2: - out_le16(addr, val); - break; - default: - out_le32(addr, val); - break; - } - return PCIBIOS_SUCCESSFUL; -} - static struct pci_ops macrisc_pci_ops = { - .read = macrisc_read_config, - .write = macrisc_write_config, + .map_bus = macrisc_cfg_map_bus, + .read = pci_generic_config_read, + .write = pci_generic_config_write, }; #ifdef CONFIG_PPC32 /* * Verify that a specific (bus, dev_fn) exists on chaos */ -static int chaos_validate_dev(struct pci_bus *bus, int devfn, int offset) +static void __iomem *chaos_map_bus(struct pci_bus *bus, unsigned int devfn, + int offset) { struct device_node *np; const u32 *vendor, *device; if (offset >= 0x100) - return PCIBIOS_BAD_REGISTER_NUMBER; + return NULL; np = of_pci_find_child_device(bus->dev.of_node, devfn); if (np == NULL) - return PCIBIOS_DEVICE_NOT_FOUND; + return NULL; vendor = of_get_property(np, "vendor-id", NULL); device = of_get_property(np, "device-id", NULL); if (vendor == NULL || device == NULL) - return PCIBIOS_DEVICE_NOT_FOUND; + return NULL; if ((*vendor == 0x106b) && (*device == 3) && (offset >= 0x10) && (offset != 0x14) && (offset != 0x18) && (offset <= 0x24)) - return PCIBIOS_BAD_REGISTER_NUMBER; - - return PCIBIOS_SUCCESSFUL; -} + return NULL; -static int -chaos_read_config(struct pci_bus *bus, unsigned int devfn, int offset, - int len, u32 *val) -{ - int result = chaos_validate_dev(bus, devfn, offset); - if (result == PCIBIOS_BAD_REGISTER_NUMBER) - *val = ~0U; - if (result != PCIBIOS_SUCCESSFUL) - return result; - return macrisc_read_config(bus, devfn, offset, len, val); -} - -static int -chaos_write_config(struct pci_bus *bus, unsigned int devfn, int offset, - int len, u32 val) -{ - int result = chaos_validate_dev(bus, devfn, offset); - if (result != PCIBIOS_SUCCESSFUL) - return result; - return macrisc_write_config(bus, devfn, offset, len, val); + return macrisc_cfg_map_bus(bus, devfn, offset); } static struct pci_ops chaos_pci_ops = { - .read = chaos_read_config, - .write = chaos_write_config, + .map_bus = chaos_map_bus, + .read = pci_generic_config_read, + .write = pci_generic_config_write, }; static void __init setup_chaos(struct pci_controller *hose, @@ -471,15 +394,24 @@ static struct pci_ops u3_ht_pci_ops = |(((unsigned int)(off)) & 0xfcU) \ |1UL) -static volatile void __iomem *u4_pcie_cfg_access(struct pci_controller* hose, - u8 bus, u8 dev_fn, int offset) +static void __iomem *u4_pcie_cfg_map_bus(struct pci_bus *bus, + unsigned int dev_fn, + int offset) { + struct pci_controller *hose; unsigned int caddr; - if (bus == hose->first_busno) { + if (offset >= 0x1000) + return NULL; + + hose = pci_bus_to_host(bus); + if (!hose) + return NULL; + + if (bus->number == hose->first_busno) { caddr = U4_PCIE_CFA0(dev_fn, offset); } else - caddr = U4_PCIE_CFA1(bus, dev_fn, offset); + caddr = U4_PCIE_CFA1(bus->number, dev_fn, offset); /* Uninorth will return garbage if we don't read back the value ! */ do { @@ -490,74 +422,11 @@ static volatile void __iomem *u4_pcie_cfg_access(struct pci_controller* hose, return hose->cfg_data + offset; } -static int u4_pcie_read_config(struct pci_bus *bus, unsigned int devfn, - int offset, int len, u32 *val) -{ - struct pci_controller *hose; - volatile void __iomem *addr; - - hose = pci_bus_to_host(bus); - if (hose == NULL) - return PCIBIOS_DEVICE_NOT_FOUND; - if (offset >= 0x1000) - return PCIBIOS_BAD_REGISTER_NUMBER; - addr = u4_pcie_cfg_access(hose, bus->number, devfn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - /* - * Note: the caller has already checked that offset is - * suitably aligned and that len is 1, 2 or 4. - */ - switch (len) { - case 1: - *val = in_8(addr); - break; - case 2: - *val = in_le16(addr); - break; - default: - *val = in_le32(addr); - break; - } - return PCIBIOS_SUCCESSFUL; -} - -static int u4_pcie_write_config(struct pci_bus *bus, unsigned int devfn, - int offset, int len, u32 val) -{ - struct pci_controller *hose; - volatile void __iomem *addr; - - hose = pci_bus_to_host(bus); - if (hose == NULL) - return PCIBIOS_DEVICE_NOT_FOUND; - if (offset >= 0x1000) - return PCIBIOS_BAD_REGISTER_NUMBER; - addr = u4_pcie_cfg_access(hose, bus->number, devfn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - /* - * Note: the caller has already checked that offset is - * suitably aligned and that len is 1, 2 or 4. - */ - switch (len) { - case 1: - out_8(addr, val); - break; - case 2: - out_le16(addr, val); - break; - default: - out_le32(addr, val); - break; - } - return PCIBIOS_SUCCESSFUL; -} - static struct pci_ops u4_pcie_pci_ops = { - .read = u4_pcie_read_config, - .write = u4_pcie_write_config, + .map_bus = u4_pcie_cfg_map_bus, + .read = pci_generic_config_read, + .write = pci_generic_config_write, }; static void pmac_pci_fixup_u4_of_node(struct pci_dev *dev) diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 6455c1eada1a..271b67e7670c 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -645,61 +645,21 @@ mapped: return pcie->cfg_type1 + offset; } -static int mpc83xx_pcie_read_config(struct pci_bus *bus, unsigned int devfn, - int offset, int len, u32 *val) -{ - void __iomem *cfg_addr; - - cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset); - if (!cfg_addr) - return PCIBIOS_DEVICE_NOT_FOUND; - - switch (len) { - case 1: - *val = in_8(cfg_addr); - break; - case 2: - *val = in_le16(cfg_addr); - break; - default: - *val = in_le32(cfg_addr); - break; - } - - return PCIBIOS_SUCCESSFUL; -} - static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 val) { struct pci_controller *hose = pci_bus_to_host(bus); - void __iomem *cfg_addr; - - cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset); - if (!cfg_addr) - return PCIBIOS_DEVICE_NOT_FOUND; /* PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS */ if (offset == PCI_PRIMARY_BUS && bus->number == hose->first_busno) val &= 0xffffff00; - switch (len) { - case 1: - out_8(cfg_addr, val); - break; - case 2: - out_le16(cfg_addr, val); - break; - default: - out_le32(cfg_addr, val); - break; - } - - return PCIBIOS_SUCCESSFUL; + return pci_generic_config_write(bus, devfn, offset, len, val); } static struct pci_ops mpc83xx_pcie_ops = { - .read = mpc83xx_pcie_read_config, + .map_bus = mpc83xx_pcie_remap_cfg, + .read = pci_generic_config_read, .write = mpc83xx_pcie_write_config, }; diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c index f70c7892fa25..325df47f114d 100644 --- a/arch/tile/kernel/pci.c +++ b/arch/tile/kernel/pci.c @@ -245,7 +245,7 @@ static void fixup_read_and_payload_sizes(void) { struct pci_dev *dev = NULL; int smallest_max_payload = 0x1; /* Tile maxes out at 256 bytes. */ - int max_read_size = 0x2; /* Limit to 512 byte reads. */ + int max_read_size = PCI_EXP_DEVCTL_READRQ_512B; u16 new_values; /* Scan for the smallest maximum payload size. */ @@ -258,7 +258,7 @@ static void fixup_read_and_payload_sizes(void) } /* Now, set the max_payload_size for all devices to that value. */ - new_values = (max_read_size << 12) | (smallest_max_payload << 5); + new_values = max_read_size | (smallest_max_payload << 5); for_each_pci_dev(dev) pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_PAYLOAD | PCI_EXP_DEVCTL_READRQ, diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 9098d880c476..d22f4b5bbc04 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -298,12 +298,16 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) map_irq.entry_nr = nvec; } else if (type == PCI_CAP_ID_MSIX) { int pos; + unsigned long flags; u32 table_offset, bir; pos = dev->msix_cap; pci_read_config_dword(dev, pos + PCI_MSIX_TABLE, &table_offset); bir = (u8)(table_offset & PCI_MSIX_TABLE_BIR); + flags = pci_resource_flags(dev, bir); + if (!flags || (flags & IORESOURCE_UNSET)) + return -EINVAL; map_irq.table_base = pci_resource_start(dev, bir); map_irq.entry_nr = msidesc->msi_attrib.entry_nr; |