diff options
51 files changed, 744 insertions, 978 deletions
diff --git a/Documentation/devicetree/bindings/pci/versatile.txt b/Documentation/devicetree/bindings/pci/versatile.txt new file mode 100644 index 000000000000..ebd1e7d0403e --- /dev/null +++ b/Documentation/devicetree/bindings/pci/versatile.txt | |||
| @@ -0,0 +1,59 @@ | |||
| 1 | * ARM Versatile Platform Baseboard PCI interface | ||
| 2 | |||
| 3 | PCI host controller found on the ARM Versatile PB board's FPGA. | ||
| 4 | |||
| 5 | Required properties: | ||
| 6 | - compatible: should contain "arm,versatile-pci" to identify the Versatile PCI | ||
| 7 | controller. | ||
| 8 | - reg: base addresses and lengths of the pci controller. There must be 3 | ||
| 9 | entries: | ||
| 10 | - Versatile-specific registers | ||
| 11 | - Self Config space | ||
| 12 | - Config space | ||
| 13 | - #address-cells: set to <3> | ||
| 14 | - #size-cells: set to <2> | ||
| 15 | - device_type: set to "pci" | ||
| 16 | - bus-range: set to <0 0xff> | ||
| 17 | - ranges: ranges for the PCI memory and I/O regions | ||
| 18 | - #interrupt-cells: set to <1> | ||
| 19 | - interrupt-map-mask and interrupt-map: standard PCI properties to define | ||
| 20 | the mapping of the PCI interface to interrupt numbers. | ||
| 21 | |||
| 22 | Example: | ||
| 23 | |||
| 24 | pci-controller@10001000 { | ||
| 25 | compatible = "arm,versatile-pci"; | ||
| 26 | device_type = "pci"; | ||
| 27 | reg = <0x10001000 0x1000 | ||
| 28 | 0x41000000 0x10000 | ||
| 29 | 0x42000000 0x100000>; | ||
| 30 | bus-range = <0 0xff>; | ||
| 31 | #address-cells = <3>; | ||
| 32 | #size-cells = <2>; | ||
| 33 | #interrupt-cells = <1>; | ||
| 34 | |||
| 35 | ranges = <0x01000000 0 0x00000000 0x43000000 0 0x00010000 /* downstream I/O */ | ||
| 36 | 0x02000000 0 0x50000000 0x50000000 0 0x10000000 /* non-prefetchable memory */ | ||
| 37 | 0x42000000 0 0x60000000 0x60000000 0 0x10000000>; /* prefetchable memory */ | ||
| 38 | |||
| 39 | interrupt-map-mask = <0x1800 0 0 7>; | ||
| 40 | interrupt-map = <0x1800 0 0 1 &sic 28 | ||
| 41 | 0x1800 0 0 2 &sic 29 | ||
| 42 | 0x1800 0 0 3 &sic 30 | ||
| 43 | 0x1800 0 0 4 &sic 27 | ||
| 44 | |||
| 45 | 0x1000 0 0 1 &sic 27 | ||
| 46 | 0x1000 0 0 2 &sic 28 | ||
| 47 | 0x1000 0 0 3 &sic 29 | ||
| 48 | 0x1000 0 0 4 &sic 30 | ||
| 49 | |||
| 50 | 0x0800 0 0 1 &sic 30 | ||
| 51 | 0x0800 0 0 2 &sic 27 | ||
| 52 | 0x0800 0 0 3 &sic 28 | ||
| 53 | 0x0800 0 0 4 &sic 29 | ||
| 54 | |||
| 55 | 0x0000 0 0 1 &sic 29 | ||
| 56 | 0x0000 0 0 2 &sic 30 | ||
| 57 | 0x0000 0 0 3 &sic 27 | ||
| 58 | 0x0000 0 0 4 &sic 28>; | ||
| 59 | }; | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 26557b74a8ef..b1ddeb69cd9f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -7277,6 +7277,14 @@ F: include/linux/pci* | |||
| 7277 | F: arch/x86/pci/ | 7277 | F: arch/x86/pci/ |
| 7278 | F: arch/x86/kernel/quirks.c | 7278 | F: arch/x86/kernel/quirks.c |
| 7279 | 7279 | ||
| 7280 | PCI DRIVER FOR ARM VERSATILE PLATFORM | ||
| 7281 | M: Rob Herring <robh@kernel.org> | ||
| 7282 | L: linux-pci@vger.kernel.org | ||
| 7283 | L: linux-arm-kernel@lists.infradead.org | ||
| 7284 | S: Maintained | ||
| 7285 | F: Documentation/devicetree/bindings/pci/versatile.txt | ||
| 7286 | F: drivers/pci/host/pci-versatile.c | ||
| 7287 | |||
| 7280 | PCI DRIVER FOR APPLIEDMICRO XGENE | 7288 | PCI DRIVER FOR APPLIEDMICRO XGENE |
| 7281 | M: Tanmay Inamdar <tinamdar@apm.com> | 7289 | M: Tanmay Inamdar <tinamdar@apm.com> |
| 7282 | L: linux-pci@vger.kernel.org | 7290 | L: linux-pci@vger.kernel.org |
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 | |||
| 1279 | bool | 1279 | bool |
| 1280 | depends on PCI | 1280 | depends on PCI |
| 1281 | 1281 | ||
| 1282 | config PCI_DOMAINS_GENERIC | ||
| 1283 | def_bool PCI_DOMAINS | ||
| 1284 | |||
| 1282 | config PCI_NANOENGINE | 1285 | config PCI_NANOENGINE |
| 1283 | bool "BSE nanoEngine PCI support" | 1286 | bool "BSE nanoEngine PCI support" |
| 1284 | depends on SA1100_NANOENGINE | 1287 | 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 @@ | |||
| 29 | clock-names = "apb_pclk"; | 29 | clock-names = "apb_pclk"; |
| 30 | }; | 30 | }; |
| 31 | 31 | ||
| 32 | pci-controller@10001000 { | ||
| 33 | compatible = "arm,versatile-pci"; | ||
| 34 | device_type = "pci"; | ||
| 35 | reg = <0x10001000 0x1000 | ||
| 36 | 0x41000000 0x10000 | ||
| 37 | 0x42000000 0x100000>; | ||
| 38 | bus-range = <0 0xff>; | ||
| 39 | #address-cells = <3>; | ||
| 40 | #size-cells = <2>; | ||
| 41 | #interrupt-cells = <1>; | ||
| 42 | |||
| 43 | ranges = <0x01000000 0 0x00000000 0x43000000 0 0x00010000 /* downstream I/O */ | ||
| 44 | 0x02000000 0 0x50000000 0x50000000 0 0x10000000 /* non-prefetchable memory */ | ||
| 45 | 0x42000000 0 0x60000000 0x60000000 0 0x10000000>; /* prefetchable memory */ | ||
| 46 | |||
| 47 | interrupt-map-mask = <0x1800 0 0 7>; | ||
| 48 | interrupt-map = <0x1800 0 0 1 &sic 28 | ||
| 49 | 0x1800 0 0 2 &sic 29 | ||
| 50 | 0x1800 0 0 3 &sic 30 | ||
| 51 | 0x1800 0 0 4 &sic 27 | ||
| 52 | |||
| 53 | 0x1000 0 0 1 &sic 27 | ||
| 54 | 0x1000 0 0 2 &sic 28 | ||
| 55 | 0x1000 0 0 3 &sic 29 | ||
| 56 | 0x1000 0 0 4 &sic 30 | ||
| 57 | |||
| 58 | 0x0800 0 0 1 &sic 30 | ||
| 59 | 0x0800 0 0 2 &sic 27 | ||
| 60 | 0x0800 0 0 3 &sic 28 | ||
| 61 | 0x0800 0 0 4 &sic 29 | ||
| 62 | |||
| 63 | 0x0000 0 0 1 &sic 29 | ||
| 64 | 0x0000 0 0 2 &sic 30 | ||
| 65 | 0x0000 0 0 3 &sic 27 | ||
| 66 | 0x0000 0 0 4 &sic 28>; | ||
| 67 | }; | ||
| 68 | |||
| 32 | fpga { | 69 | fpga { |
| 33 | uart@9000 { | 70 | uart@9000 { |
| 34 | compatible = "arm,pl011", "arm,primecell"; | 71 | 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; | |||
| 19 | struct device; | 19 | struct device; |
| 20 | 20 | ||
| 21 | struct hw_pci { | 21 | struct hw_pci { |
| 22 | #ifdef CONFIG_PCI_DOMAINS | ||
| 23 | int domain; | ||
| 24 | #endif | ||
| 25 | #ifdef CONFIG_PCI_MSI | 22 | #ifdef CONFIG_PCI_MSI |
| 26 | struct msi_controller *msi_ctrl; | 23 | struct msi_controller *msi_ctrl; |
| 27 | #endif | 24 | #endif |
| @@ -45,9 +42,6 @@ struct hw_pci { | |||
| 45 | * Per-controller structure | 42 | * Per-controller structure |
| 46 | */ | 43 | */ |
| 47 | struct pci_sys_data { | 44 | struct pci_sys_data { |
| 48 | #ifdef CONFIG_PCI_DOMAINS | ||
| 49 | int domain; | ||
| 50 | #endif | ||
| 51 | #ifdef CONFIG_PCI_MSI | 45 | #ifdef CONFIG_PCI_MSI |
| 52 | struct msi_controller *msi_ctrl; | 46 | struct msi_controller *msi_ctrl; |
| 53 | #endif | 47 | #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) | |||
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | #ifdef CONFIG_PCI_DOMAINS | 20 | #ifdef CONFIG_PCI_DOMAINS |
| 21 | static inline int pci_domain_nr(struct pci_bus *bus) | ||
| 22 | { | ||
| 23 | struct pci_sys_data *root = bus->sysdata; | ||
| 24 | |||
| 25 | return root->domain; | ||
| 26 | } | ||
| 27 | |||
| 28 | static inline int pci_proc_domain(struct pci_bus *bus) | 21 | static inline int pci_proc_domain(struct pci_bus *bus) |
| 29 | { | 22 | { |
| 30 | return pci_domain_nr(bus); | 23 | 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, | |||
| 463 | if (!sys) | 463 | if (!sys) |
| 464 | panic("PCI: unable to allocate sys data!"); | 464 | panic("PCI: unable to allocate sys data!"); |
| 465 | 465 | ||
| 466 | #ifdef CONFIG_PCI_DOMAINS | ||
| 467 | sys->domain = hw->domain; | ||
| 468 | #endif | ||
| 469 | #ifdef CONFIG_PCI_MSI | 466 | #ifdef CONFIG_PCI_MSI |
| 470 | sys->msi_ctrl = hw->msi_ctrl; | 467 | sys->msi_ctrl = hw->msi_ctrl; |
| 471 | #endif | 468 | #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 { | |||
| 30 | unsigned int irqs[2]; | 30 | unsigned int irqs[2]; |
| 31 | struct resource res_io; | 31 | struct resource res_io; |
| 32 | struct resource res_mem; | 32 | struct resource res_mem; |
| 33 | struct hw_pci hw_pci; | 33 | int port; |
| 34 | |||
| 35 | bool linked; | 34 | bool linked; |
| 36 | }; | 35 | }; |
| 37 | 36 | ||
| 38 | static struct cns3xxx_pcie cns3xxx_pcie[]; /* forward decl. */ | ||
| 39 | |||
| 40 | static struct cns3xxx_pcie *sysdata_to_cnspci(void *sysdata) | 37 | static struct cns3xxx_pcie *sysdata_to_cnspci(void *sysdata) |
| 41 | { | 38 | { |
| 42 | struct pci_sys_data *root = sysdata; | 39 | struct pci_sys_data *root = sysdata; |
| 43 | 40 | ||
| 44 | return &cns3xxx_pcie[root->domain]; | 41 | return root->private_data; |
| 45 | } | 42 | } |
| 46 | 43 | ||
| 47 | static struct cns3xxx_pcie *pdev_to_cnspci(const struct pci_dev *dev) | 44 | 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) | |||
| 54 | return sysdata_to_cnspci(bus->sysdata); | 51 | return sysdata_to_cnspci(bus->sysdata); |
| 55 | } | 52 | } |
| 56 | 53 | ||
| 57 | static void __iomem *cns3xxx_pci_cfg_base(struct pci_bus *bus, | 54 | static void __iomem *cns3xxx_pci_map_bus(struct pci_bus *bus, |
| 58 | unsigned int devfn, int where) | 55 | unsigned int devfn, int where) |
| 59 | { | 56 | { |
| 60 | struct cns3xxx_pcie *cnspci = pbus_to_cnspci(bus); | 57 | struct cns3xxx_pcie *cnspci = pbus_to_cnspci(bus); |
| 61 | int busno = bus->number; | 58 | int busno = bus->number; |
| @@ -91,55 +88,22 @@ static void __iomem *cns3xxx_pci_cfg_base(struct pci_bus *bus, | |||
| 91 | static int cns3xxx_pci_read_config(struct pci_bus *bus, unsigned int devfn, | 88 | static int cns3xxx_pci_read_config(struct pci_bus *bus, unsigned int devfn, |
| 92 | int where, int size, u32 *val) | 89 | int where, int size, u32 *val) |
| 93 | { | 90 | { |
| 94 | u32 v; | 91 | int ret; |
| 95 | void __iomem *base; | ||
| 96 | u32 mask = (0x1ull << (size * 8)) - 1; | 92 | u32 mask = (0x1ull << (size * 8)) - 1; |
| 97 | int shift = (where % 4) * 8; | 93 | int shift = (where % 4) * 8; |
| 98 | 94 | ||
| 99 | base = cns3xxx_pci_cfg_base(bus, devfn, where); | 95 | ret = pci_generic_config_read32(bus, devfn, where, size, val); |
| 100 | if (!base) { | ||
| 101 | *val = 0xffffffff; | ||
| 102 | return PCIBIOS_SUCCESSFUL; | ||
| 103 | } | ||
| 104 | |||
| 105 | v = __raw_readl(base); | ||
| 106 | 96 | ||
| 107 | if (bus->number == 0 && devfn == 0 && | 97 | if (ret == PCIBIOS_SUCCESSFUL && !bus->number && !devfn && |
| 108 | (where & 0xffc) == PCI_CLASS_REVISION) { | 98 | (where & 0xffc) == PCI_CLASS_REVISION) |
| 109 | /* | 99 | /* |
| 110 | * RC's class is 0xb, but Linux PCI driver needs 0x604 | 100 | * RC's class is 0xb, but Linux PCI driver needs 0x604 |
| 111 | * for a PCIe bridge. So we must fixup the class code | 101 | * for a PCIe bridge. So we must fixup the class code |
| 112 | * to 0x604 here. | 102 | * to 0x604 here. |
| 113 | */ | 103 | */ |
| 114 | v &= 0xff; | 104 | *val = ((((*val << shift) & 0xff) | (0x604 << 16)) >> shift) & mask; |
| 115 | v |= 0x604 << 16; | ||
| 116 | } | ||
| 117 | 105 | ||
| 118 | *val = (v >> shift) & mask; | 106 | return ret; |
| 119 | |||
| 120 | return PCIBIOS_SUCCESSFUL; | ||
| 121 | } | ||
| 122 | |||
| 123 | static int cns3xxx_pci_write_config(struct pci_bus *bus, unsigned int devfn, | ||
| 124 | int where, int size, u32 val) | ||
| 125 | { | ||
| 126 | u32 v; | ||
| 127 | void __iomem *base; | ||
| 128 | u32 mask = (0x1ull << (size * 8)) - 1; | ||
| 129 | int shift = (where % 4) * 8; | ||
| 130 | |||
| 131 | base = cns3xxx_pci_cfg_base(bus, devfn, where); | ||
| 132 | if (!base) | ||
| 133 | return PCIBIOS_SUCCESSFUL; | ||
| 134 | |||
| 135 | v = __raw_readl(base); | ||
| 136 | |||
| 137 | v &= ~(mask << shift); | ||
| 138 | v |= (val & mask) << shift; | ||
| 139 | |||
| 140 | __raw_writel(v, base); | ||
| 141 | |||
| 142 | return PCIBIOS_SUCCESSFUL; | ||
| 143 | } | 107 | } |
| 144 | 108 | ||
| 145 | static int cns3xxx_pci_setup(int nr, struct pci_sys_data *sys) | 109 | 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) | |||
| 158 | } | 122 | } |
| 159 | 123 | ||
| 160 | static struct pci_ops cns3xxx_pcie_ops = { | 124 | static struct pci_ops cns3xxx_pcie_ops = { |
| 125 | .map_bus = cns3xxx_pci_map_bus, | ||
| 161 | .read = cns3xxx_pci_read_config, | 126 | .read = cns3xxx_pci_read_config, |
| 162 | .write = cns3xxx_pci_write_config, | 127 | .write = pci_generic_config_write, |
| 163 | }; | 128 | }; |
| 164 | 129 | ||
| 165 | static int cns3xxx_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | 130 | 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[] = { | |||
| 192 | .flags = IORESOURCE_MEM, | 157 | .flags = IORESOURCE_MEM, |
| 193 | }, | 158 | }, |
| 194 | .irqs = { IRQ_CNS3XXX_PCIE0_RC, IRQ_CNS3XXX_PCIE0_DEVICE, }, | 159 | .irqs = { IRQ_CNS3XXX_PCIE0_RC, IRQ_CNS3XXX_PCIE0_DEVICE, }, |
| 195 | .hw_pci = { | 160 | .port = 0, |
| 196 | .domain = 0, | ||
| 197 | .nr_controllers = 1, | ||
| 198 | .ops = &cns3xxx_pcie_ops, | ||
| 199 | .setup = cns3xxx_pci_setup, | ||
| 200 | .map_irq = cns3xxx_pcie_map_irq, | ||
| 201 | }, | ||
| 202 | }, | 161 | }, |
| 203 | [1] = { | 162 | [1] = { |
| 204 | .host_regs = (void __iomem *)CNS3XXX_PCIE1_HOST_BASE_VIRT, | 163 | .host_regs = (void __iomem *)CNS3XXX_PCIE1_HOST_BASE_VIRT, |
| @@ -217,19 +176,13 @@ static struct cns3xxx_pcie cns3xxx_pcie[] = { | |||
| 217 | .flags = IORESOURCE_MEM, | 176 | .flags = IORESOURCE_MEM, |
| 218 | }, | 177 | }, |
| 219 | .irqs = { IRQ_CNS3XXX_PCIE1_RC, IRQ_CNS3XXX_PCIE1_DEVICE, }, | 178 | .irqs = { IRQ_CNS3XXX_PCIE1_RC, IRQ_CNS3XXX_PCIE1_DEVICE, }, |
| 220 | .hw_pci = { | 179 | .port = 1, |
| 221 | .domain = 1, | ||
| 222 | .nr_controllers = 1, | ||
| 223 | .ops = &cns3xxx_pcie_ops, | ||
| 224 | .setup = cns3xxx_pci_setup, | ||
| 225 | .map_irq = cns3xxx_pcie_map_irq, | ||
| 226 | }, | ||
| 227 | }, | 180 | }, |
| 228 | }; | 181 | }; |
| 229 | 182 | ||
| 230 | static void __init cns3xxx_pcie_check_link(struct cns3xxx_pcie *cnspci) | 183 | static void __init cns3xxx_pcie_check_link(struct cns3xxx_pcie *cnspci) |
| 231 | { | 184 | { |
| 232 | int port = cnspci->hw_pci.domain; | 185 | int port = cnspci->port; |
| 233 | u32 reg; | 186 | u32 reg; |
| 234 | unsigned long time; | 187 | unsigned long time; |
| 235 | 188 | ||
| @@ -260,9 +213,9 @@ static void __init cns3xxx_pcie_check_link(struct cns3xxx_pcie *cnspci) | |||
| 260 | 213 | ||
| 261 | static void __init cns3xxx_pcie_hw_init(struct cns3xxx_pcie *cnspci) | 214 | static void __init cns3xxx_pcie_hw_init(struct cns3xxx_pcie *cnspci) |
| 262 | { | 215 | { |
| 263 | int port = cnspci->hw_pci.domain; | 216 | int port = cnspci->port; |
| 264 | struct pci_sys_data sd = { | 217 | struct pci_sys_data sd = { |
| 265 | .domain = port, | 218 | .private_data = cnspci, |
| 266 | }; | 219 | }; |
| 267 | struct pci_bus bus = { | 220 | struct pci_bus bus = { |
| 268 | .number = 0, | 221 | .number = 0, |
| @@ -323,6 +276,14 @@ static int cns3xxx_pcie_abort_handler(unsigned long addr, unsigned int fsr, | |||
| 323 | void __init cns3xxx_pcie_init_late(void) | 276 | void __init cns3xxx_pcie_init_late(void) |
| 324 | { | 277 | { |
| 325 | int i; | 278 | int i; |
| 279 | void *private_data; | ||
| 280 | struct hw_pci hw_pci = { | ||
| 281 | .nr_controllers = 1, | ||
| 282 | .ops = &cns3xxx_pcie_ops, | ||
| 283 | .setup = cns3xxx_pci_setup, | ||
| 284 | .map_irq = cns3xxx_pcie_map_irq, | ||
| 285 | .private_data = &private_data, | ||
| 286 | }; | ||
| 326 | 287 | ||
| 327 | pcibios_min_io = 0; | 288 | pcibios_min_io = 0; |
| 328 | pcibios_min_mem = 0; | 289 | pcibios_min_mem = 0; |
| @@ -335,7 +296,8 @@ void __init cns3xxx_pcie_init_late(void) | |||
| 335 | cns3xxx_pwr_soft_rst(0x1 << PM_SOFT_RST_REG_OFFST_PCIE(i)); | 296 | cns3xxx_pwr_soft_rst(0x1 << PM_SOFT_RST_REG_OFFST_PCIE(i)); |
| 336 | cns3xxx_pcie_check_link(&cns3xxx_pcie[i]); | 297 | cns3xxx_pcie_check_link(&cns3xxx_pcie[i]); |
| 337 | cns3xxx_pcie_hw_init(&cns3xxx_pcie[i]); | 298 | cns3xxx_pcie_hw_init(&cns3xxx_pcie[i]); |
| 338 | pci_common_init(&cns3xxx_pcie[i].hw_pci); | 299 | private_data = &cns3xxx_pcie[i]; |
| 300 | pci_common_init(&hw_pci); | ||
| 339 | } | 301 | } |
| 340 | 302 | ||
| 341 | pci_assign_unassigned_resources(); | 303 | 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; | |||
| 356 | * 7:2 register number | 356 | * 7:2 register number |
| 357 | * | 357 | * |
| 358 | */ | 358 | */ |
| 359 | static DEFINE_RAW_SPINLOCK(v3_lock); | ||
| 360 | 359 | ||
| 361 | #undef V3_LB_BASE_PREFETCH | 360 | #undef V3_LB_BASE_PREFETCH |
| 362 | #define V3_LB_BASE_PREFETCH 0 | 361 | #define V3_LB_BASE_PREFETCH 0 |
| @@ -457,67 +456,21 @@ static void v3_close_config_window(void) | |||
| 457 | static int v3_read_config(struct pci_bus *bus, unsigned int devfn, int where, | 456 | static int v3_read_config(struct pci_bus *bus, unsigned int devfn, int where, |
| 458 | int size, u32 *val) | 457 | int size, u32 *val) |
| 459 | { | 458 | { |
| 460 | void __iomem *addr; | 459 | int ret = pci_generic_config_read(bus, devfn, where, size, val); |
| 461 | unsigned long flags; | ||
| 462 | u32 v; | ||
| 463 | |||
| 464 | raw_spin_lock_irqsave(&v3_lock, flags); | ||
| 465 | addr = v3_open_config_window(bus, devfn, where); | ||
| 466 | |||
| 467 | switch (size) { | ||
| 468 | case 1: | ||
| 469 | v = __raw_readb(addr); | ||
| 470 | break; | ||
| 471 | |||
| 472 | case 2: | ||
| 473 | v = __raw_readw(addr); | ||
| 474 | break; | ||
| 475 | |||
| 476 | default: | ||
| 477 | v = __raw_readl(addr); | ||
| 478 | break; | ||
| 479 | } | ||
| 480 | |||
| 481 | v3_close_config_window(); | 460 | v3_close_config_window(); |
| 482 | raw_spin_unlock_irqrestore(&v3_lock, flags); | 461 | return ret; |
| 483 | |||
| 484 | *val = v; | ||
| 485 | return PCIBIOS_SUCCESSFUL; | ||
| 486 | } | 462 | } |
| 487 | 463 | ||
| 488 | static int v3_write_config(struct pci_bus *bus, unsigned int devfn, int where, | 464 | static int v3_write_config(struct pci_bus *bus, unsigned int devfn, int where, |
| 489 | int size, u32 val) | 465 | int size, u32 val) |
| 490 | { | 466 | { |
| 491 | void __iomem *addr; | 467 | int ret = pci_generic_config_write(bus, devfn, where, size, val); |
| 492 | unsigned long flags; | ||
| 493 | |||
| 494 | raw_spin_lock_irqsave(&v3_lock, flags); | ||
| 495 | addr = v3_open_config_window(bus, devfn, where); | ||
| 496 | |||
| 497 | switch (size) { | ||
| 498 | case 1: | ||
| 499 | __raw_writeb((u8)val, addr); | ||
| 500 | __raw_readb(addr); | ||
| 501 | break; | ||
| 502 | |||
| 503 | case 2: | ||
| 504 | __raw_writew((u16)val, addr); | ||
| 505 | __raw_readw(addr); | ||
| 506 | break; | ||
| 507 | |||
| 508 | case 4: | ||
| 509 | __raw_writel(val, addr); | ||
| 510 | __raw_readl(addr); | ||
| 511 | break; | ||
| 512 | } | ||
| 513 | |||
| 514 | v3_close_config_window(); | 468 | v3_close_config_window(); |
| 515 | raw_spin_unlock_irqrestore(&v3_lock, flags); | 469 | return ret; |
| 516 | |||
| 517 | return PCIBIOS_SUCCESSFUL; | ||
| 518 | } | 470 | } |
| 519 | 471 | ||
| 520 | static struct pci_ops pci_v3_ops = { | 472 | static struct pci_ops pci_v3_ops = { |
| 473 | .map_bus = v3_open_config_window, | ||
| 521 | .read = v3_read_config, | 474 | .read = v3_read_config, |
| 522 | .write = v3_write_config, | 475 | .write = v3_write_config, |
| 523 | }; | 476 | }; |
| @@ -658,7 +611,6 @@ static int __init pci_v3_setup(int nr, struct pci_sys_data *sys) | |||
| 658 | */ | 611 | */ |
| 659 | static void __init pci_v3_preinit(void) | 612 | static void __init pci_v3_preinit(void) |
| 660 | { | 613 | { |
| 661 | unsigned long flags; | ||
| 662 | unsigned int temp; | 614 | unsigned int temp; |
| 663 | phys_addr_t io_address = pci_pio_to_address(io_mem.start); | 615 | phys_addr_t io_address = pci_pio_to_address(io_mem.start); |
| 664 | 616 | ||
| @@ -672,8 +624,6 @@ static void __init pci_v3_preinit(void) | |||
| 672 | hook_fault_code(8, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch"); | 624 | hook_fault_code(8, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch"); |
| 673 | hook_fault_code(10, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch"); | 625 | hook_fault_code(10, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch"); |
| 674 | 626 | ||
| 675 | raw_spin_lock_irqsave(&v3_lock, flags); | ||
| 676 | |||
| 677 | /* | 627 | /* |
| 678 | * Unlock V3 registers, but only if they were previously locked. | 628 | * Unlock V3 registers, but only if they were previously locked. |
| 679 | */ | 629 | */ |
| @@ -736,8 +686,6 @@ static void __init pci_v3_preinit(void) | |||
| 736 | v3_writew(V3_LB_CFG, v3_readw(V3_LB_CFG) | (1 << 10)); | 686 | v3_writew(V3_LB_CFG, v3_readw(V3_LB_CFG) | (1 << 10)); |
| 737 | v3_writeb(V3_LB_IMASK, 0x28); | 687 | v3_writeb(V3_LB_IMASK, 0x28); |
| 738 | __raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET); | 688 | __raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET); |
| 739 | |||
| 740 | raw_spin_unlock_irqrestore(&v3_lock, flags); | ||
| 741 | } | 689 | } |
| 742 | 690 | ||
| 743 | static void __init pci_v3_postinit(void) | 691 | 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 @@ | |||
| 38 | 38 | ||
| 39 | 39 | ||
| 40 | static int pci_dbg; | 40 | static int pci_dbg; |
| 41 | static int pci_cfg_dbg; | ||
| 42 | |||
| 43 | 41 | ||
| 44 | static void ks8695_pci_setupconfig(unsigned int bus_nr, unsigned int devfn, unsigned int where) | 42 | static void ks8695_pci_setupconfig(unsigned int bus_nr, unsigned int devfn, unsigned int where) |
| 45 | { | 43 | { |
| @@ -59,75 +57,11 @@ static void ks8695_pci_setupconfig(unsigned int bus_nr, unsigned int devfn, unsi | |||
| 59 | } | 57 | } |
| 60 | } | 58 | } |
| 61 | 59 | ||
| 62 | 60 | static void __iomem *ks8695_pci_map_bus(struct pci_bus *bus, unsigned int devfn, | |
| 63 | /* | 61 | int where) |
| 64 | * The KS8695 datasheet prohibits anything other than 32bit accesses | ||
| 65 | * to the IO registers, so all our configuration must be done with | ||
| 66 | * 32bit operations, and the correct bit masking and shifting. | ||
| 67 | */ | ||
| 68 | |||
| 69 | static int ks8695_pci_readconfig(struct pci_bus *bus, | ||
| 70 | unsigned int devfn, int where, int size, u32 *value) | ||
| 71 | { | ||
| 72 | ks8695_pci_setupconfig(bus->number, devfn, where); | ||
| 73 | |||
| 74 | *value = __raw_readl(KS8695_PCI_VA + KS8695_PBCD); | ||
| 75 | |||
| 76 | switch (size) { | ||
| 77 | case 4: | ||
| 78 | break; | ||
| 79 | case 2: | ||
| 80 | *value = *value >> ((where & 2) * 8); | ||
| 81 | *value &= 0xffff; | ||
| 82 | break; | ||
| 83 | case 1: | ||
| 84 | *value = *value >> ((where & 3) * 8); | ||
| 85 | *value &= 0xff; | ||
| 86 | break; | ||
| 87 | } | ||
| 88 | |||
| 89 | if (pci_cfg_dbg) { | ||
| 90 | printk("read: %d,%08x,%02x,%d: %08x (%08x)\n", | ||
| 91 | bus->number, devfn, where, size, *value, | ||
| 92 | __raw_readl(KS8695_PCI_VA + KS8695_PBCD)); | ||
| 93 | } | ||
| 94 | |||
| 95 | return PCIBIOS_SUCCESSFUL; | ||
| 96 | } | ||
| 97 | |||
| 98 | static int ks8695_pci_writeconfig(struct pci_bus *bus, | ||
| 99 | unsigned int devfn, int where, int size, u32 value) | ||
| 100 | { | 62 | { |
| 101 | unsigned long tmp; | ||
| 102 | |||
| 103 | if (pci_cfg_dbg) { | ||
| 104 | printk("write: %d,%08x,%02x,%d: %08x\n", | ||
| 105 | bus->number, devfn, where, size, value); | ||
| 106 | } | ||
| 107 | |||
| 108 | ks8695_pci_setupconfig(bus->number, devfn, where); | 63 | ks8695_pci_setupconfig(bus->number, devfn, where); |
| 109 | 64 | return KS8695_PCI_VA + KS8695_PBCD; | |
| 110 | switch (size) { | ||
| 111 | case 4: | ||
| 112 | __raw_writel(value, KS8695_PCI_VA + KS8695_PBCD); | ||
| 113 | break; | ||
| 114 | case 2: | ||
| 115 | tmp = __raw_readl(KS8695_PCI_VA + KS8695_PBCD); | ||
| 116 | tmp &= ~(0xffff << ((where & 2) * 8)); | ||
| 117 | tmp |= value << ((where & 2) * 8); | ||
| 118 | |||
| 119 | __raw_writel(tmp, KS8695_PCI_VA + KS8695_PBCD); | ||
| 120 | break; | ||
| 121 | case 1: | ||
| 122 | tmp = __raw_readl(KS8695_PCI_VA + KS8695_PBCD); | ||
| 123 | tmp &= ~(0xff << ((where & 3) * 8)); | ||
| 124 | tmp |= value << ((where & 3) * 8); | ||
| 125 | |||
| 126 | __raw_writel(tmp, KS8695_PCI_VA + KS8695_PBCD); | ||
| 127 | break; | ||
| 128 | } | ||
| 129 | |||
| 130 | return PCIBIOS_SUCCESSFUL; | ||
| 131 | } | 65 | } |
| 132 | 66 | ||
| 133 | static void ks8695_local_writeconfig(int where, u32 value) | 67 | static void ks8695_local_writeconfig(int where, u32 value) |
| @@ -137,8 +71,9 @@ static void ks8695_local_writeconfig(int where, u32 value) | |||
| 137 | } | 71 | } |
| 138 | 72 | ||
| 139 | static struct pci_ops ks8695_pci_ops = { | 73 | static struct pci_ops ks8695_pci_ops = { |
| 140 | .read = ks8695_pci_readconfig, | 74 | .map_bus = ks8695_pci_map_bus, |
| 141 | .write = ks8695_pci_writeconfig, | 75 | .read = pci_generic_config_read32, |
| 76 | .write = pci_generic_config_write32, | ||
| 142 | }; | 77 | }; |
| 143 | 78 | ||
| 144 | static struct resource pci_mem = { | 79 | 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 @@ | |||
| 22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
| 23 | #include <linux/irq.h> | 23 | #include <linux/irq.h> |
| 24 | #include <linux/pci.h> | 24 | #include <linux/pci.h> |
| 25 | #include <linux/spinlock.h> | ||
| 26 | 25 | ||
| 27 | #include <asm/mach/pci.h> | 26 | #include <asm/mach/pci.h> |
| 28 | #include <asm/mach-types.h> | 27 | #include <asm/mach-types.h> |
| @@ -30,97 +29,20 @@ | |||
| 30 | #include <mach/nanoengine.h> | 29 | #include <mach/nanoengine.h> |
| 31 | #include <mach/hardware.h> | 30 | #include <mach/hardware.h> |
| 32 | 31 | ||
| 33 | static DEFINE_SPINLOCK(nano_lock); | 32 | static void __iomem *nanoengine_pci_map_bus(struct pci_bus *bus, |
| 34 | 33 | unsigned int devfn, int where) | |
| 35 | static int nanoengine_get_pci_address(struct pci_bus *bus, | ||
| 36 | unsigned int devfn, int where, void __iomem **address) | ||
| 37 | { | 34 | { |
| 38 | int ret = PCIBIOS_DEVICE_NOT_FOUND; | 35 | if (bus->number != 0 || (devfn >> 3) != 0) |
| 39 | unsigned int busnr = bus->number; | 36 | return NULL; |
| 40 | 37 | ||
| 41 | *address = (void __iomem *)NANO_PCI_CONFIG_SPACE_VIRT + | 38 | return (void __iomem *)NANO_PCI_CONFIG_SPACE_VIRT + |
| 42 | ((bus->number << 16) | (devfn << 8) | (where & ~3)); | 39 | ((bus->number << 16) | (devfn << 8) | (where & ~3)); |
| 43 | |||
| 44 | ret = (busnr > 255 || devfn > 255 || where > 255) ? | ||
| 45 | PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; | ||
| 46 | |||
| 47 | return ret; | ||
| 48 | } | ||
| 49 | |||
| 50 | static int nanoengine_read_config(struct pci_bus *bus, unsigned int devfn, int where, | ||
| 51 | int size, u32 *val) | ||
| 52 | { | ||
| 53 | int ret; | ||
| 54 | void __iomem *address; | ||
| 55 | unsigned long flags; | ||
| 56 | u32 v; | ||
| 57 | |||
| 58 | /* nanoEngine PCI bridge does not return -1 for a non-existing | ||
| 59 | * device. We must fake the answer. We know that the only valid | ||
| 60 | * device is device zero at bus 0, which is the network chip. */ | ||
| 61 | if (bus->number != 0 || (devfn >> 3) != 0) { | ||
| 62 | v = -1; | ||
| 63 | nanoengine_get_pci_address(bus, devfn, where, &address); | ||
| 64 | goto exit_function; | ||
| 65 | } | ||
| 66 | |||
| 67 | spin_lock_irqsave(&nano_lock, flags); | ||
| 68 | |||
| 69 | ret = nanoengine_get_pci_address(bus, devfn, where, &address); | ||
| 70 | if (ret != PCIBIOS_SUCCESSFUL) | ||
| 71 | return ret; | ||
| 72 | v = __raw_readl(address); | ||
| 73 | |||
| 74 | spin_unlock_irqrestore(&nano_lock, flags); | ||
| 75 | |||
| 76 | v >>= ((where & 3) * 8); | ||
| 77 | v &= (unsigned long)(-1) >> ((4 - size) * 8); | ||
| 78 | |||
| 79 | exit_function: | ||
| 80 | *val = v; | ||
| 81 | return PCIBIOS_SUCCESSFUL; | ||
| 82 | } | ||
| 83 | |||
| 84 | static int nanoengine_write_config(struct pci_bus *bus, unsigned int devfn, int where, | ||
| 85 | int size, u32 val) | ||
| 86 | { | ||
| 87 | int ret; | ||
| 88 | void __iomem *address; | ||
| 89 | unsigned long flags; | ||
| 90 | unsigned shift; | ||
| 91 | u32 v; | ||
| 92 | |||
| 93 | shift = (where & 3) * 8; | ||
| 94 | |||
| 95 | spin_lock_irqsave(&nano_lock, flags); | ||
| 96 | |||
| 97 | ret = nanoengine_get_pci_address(bus, devfn, where, &address); | ||
| 98 | if (ret != PCIBIOS_SUCCESSFUL) | ||
| 99 | return ret; | ||
| 100 | v = __raw_readl(address); | ||
| 101 | switch (size) { | ||
| 102 | case 1: | ||
| 103 | v &= ~(0xFF << shift); | ||
| 104 | v |= val << shift; | ||
| 105 | break; | ||
| 106 | case 2: | ||
| 107 | v &= ~(0xFFFF << shift); | ||
| 108 | v |= val << shift; | ||
| 109 | break; | ||
| 110 | case 4: | ||
| 111 | v = val; | ||
| 112 | break; | ||
| 113 | } | ||
| 114 | __raw_writel(v, address); | ||
| 115 | |||
| 116 | spin_unlock_irqrestore(&nano_lock, flags); | ||
| 117 | |||
| 118 | return PCIBIOS_SUCCESSFUL; | ||
| 119 | } | 40 | } |
| 120 | 41 | ||
| 121 | static struct pci_ops pci_nano_ops = { | 42 | static struct pci_ops pci_nano_ops = { |
| 122 | .read = nanoengine_read_config, | 43 | .map_bus = nanoengine_pci_map_bus, |
| 123 | .write = nanoengine_write_config, | 44 | .read = pci_generic_config_read32, |
| 45 | .write = pci_generic_config_write32, | ||
| 124 | }; | 46 | }; |
| 125 | 47 | ||
| 126 | static int __init pci_nanoengine_map_irq(const struct pci_dev *dev, u8 slot, | 48 | 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) | |||
| 46 | 46 | ||
| 47 | return 0; | 47 | return 0; |
| 48 | } | 48 | } |
| 49 | |||
| 50 | |||
| 51 | #ifdef CONFIG_PCI_DOMAINS_GENERIC | ||
| 52 | static bool dt_domain_found = false; | ||
| 53 | |||
| 54 | void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent) | ||
| 55 | { | ||
| 56 | int domain = of_get_pci_domain_nr(parent->of_node); | ||
| 57 | |||
| 58 | if (domain >= 0) { | ||
| 59 | dt_domain_found = true; | ||
| 60 | } else if (dt_domain_found == true) { | ||
| 61 | dev_err(parent, "Node %s is missing \"linux,pci-domain\" property in DT\n", | ||
| 62 | parent->of_node->full_name); | ||
| 63 | return; | ||
| 64 | } else { | ||
| 65 | domain = pci_get_new_domain_nr(); | ||
| 66 | } | ||
| 67 | |||
| 68 | bus->domain_nr = domain; | ||
| 69 | } | ||
| 70 | #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 | |||
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | static struct pci_ops pci_direct_frv = { | 170 | static struct pci_ops pci_direct_frv = { |
| 171 | pci_frv_read_config, | 171 | .read = pci_frv_read_config, |
| 172 | pci_frv_write_config, | 172 | .write = pci_frv_write_config, |
| 173 | }; | 173 | }; |
| 174 | 174 | ||
| 175 | /* | 175 | /* |
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, | |||
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | struct pci_ops bcm1480_pci_ops = { | 175 | struct pci_ops bcm1480_pci_ops = { |
| 176 | bcm1480_pcibios_read, | 176 | .read = bcm1480_pcibios_read, |
| 177 | bcm1480_pcibios_write, | 177 | .write = bcm1480_pcibios_write, |
| 178 | }; | 178 | }; |
| 179 | 179 | ||
| 180 | static struct resource bcm1480_mem_resource = { | 180 | 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, | |||
| 327 | 327 | ||
| 328 | 328 | ||
| 329 | static struct pci_ops octeon_pci_ops = { | 329 | static struct pci_ops octeon_pci_ops = { |
| 330 | octeon_read_config, | 330 | .read = octeon_read_config, |
| 331 | octeon_write_config, | 331 | .write = octeon_write_config, |
| 332 | }; | 332 | }; |
| 333 | 333 | ||
| 334 | static struct resource octeon_pci_mem_resource = { | 334 | 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, | |||
| 1792 | } | 1792 | } |
| 1793 | 1793 | ||
| 1794 | static struct pci_ops octeon_pcie0_ops = { | 1794 | static struct pci_ops octeon_pcie0_ops = { |
| 1795 | octeon_pcie0_read_config, | 1795 | .read = octeon_pcie0_read_config, |
| 1796 | octeon_pcie0_write_config, | 1796 | .write = octeon_pcie0_write_config, |
| 1797 | }; | 1797 | }; |
| 1798 | 1798 | ||
| 1799 | static struct resource octeon_pcie0_mem_resource = { | 1799 | static struct resource octeon_pcie0_mem_resource = { |
| @@ -1813,8 +1813,8 @@ static struct pci_controller octeon_pcie0_controller = { | |||
| 1813 | }; | 1813 | }; |
| 1814 | 1814 | ||
| 1815 | static struct pci_ops octeon_pcie1_ops = { | 1815 | static struct pci_ops octeon_pcie1_ops = { |
| 1816 | octeon_pcie1_read_config, | 1816 | .read = octeon_pcie1_read_config, |
| 1817 | octeon_pcie1_write_config, | 1817 | .write = octeon_pcie1_write_config, |
| 1818 | }; | 1818 | }; |
| 1819 | 1819 | ||
| 1820 | static struct resource octeon_pcie1_mem_resource = { | 1820 | static struct resource octeon_pcie1_mem_resource = { |
| @@ -1834,8 +1834,8 @@ static struct pci_controller octeon_pcie1_controller = { | |||
| 1834 | }; | 1834 | }; |
| 1835 | 1835 | ||
| 1836 | static struct pci_ops octeon_dummy_ops = { | 1836 | static struct pci_ops octeon_dummy_ops = { |
| 1837 | octeon_dummy_read_config, | 1837 | .read = octeon_dummy_read_config, |
| 1838 | octeon_dummy_write_config, | 1838 | .write = octeon_dummy_write_config, |
| 1839 | }; | 1839 | }; |
| 1840 | 1840 | ||
| 1841 | static struct resource octeon_dummy_mem_resource = { | 1841 | 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, | |||
| 228 | } | 228 | } |
| 229 | 229 | ||
| 230 | static struct pci_ops pci_direct_ampci = { | 230 | static struct pci_ops pci_direct_ampci = { |
| 231 | pci_ampci_read_config, | 231 | .read = pci_ampci_read_config, |
| 232 | pci_ampci_write_config, | 232 | .write = pci_ampci_write_config, |
| 233 | }; | 233 | }; |
| 234 | 234 | ||
| 235 | /* | 235 | /* |
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, | |||
| 399 | } | 399 | } |
| 400 | 400 | ||
| 401 | static struct pci_ops scc_pciex_pci_ops = { | 401 | static struct pci_ops scc_pciex_pci_ops = { |
| 402 | scc_pciex_read_config, | 402 | .read = scc_pciex_read_config, |
| 403 | scc_pciex_write_config, | 403 | .write = scc_pciex_write_config, |
| 404 | }; | 404 | }; |
| 405 | 405 | ||
| 406 | static void pciex_clear_intr_all(unsigned int __iomem *base) | 406 | 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) | |||
| 133 | |(((unsigned int)(off)) & 0xFCUL) \ | 133 | |(((unsigned int)(off)) & 0xFCUL) \ |
| 134 | |1UL) | 134 | |1UL) |
| 135 | 135 | ||
| 136 | static volatile void __iomem *macrisc_cfg_access(struct pci_controller* hose, | 136 | static void __iomem *macrisc_cfg_map_bus(struct pci_bus *bus, |
| 137 | u8 bus, u8 dev_fn, u8 offset) | 137 | unsigned int dev_fn, |
| 138 | int offset) | ||
| 138 | { | 139 | { |
| 139 | unsigned int caddr; | 140 | unsigned int caddr; |
| 141 | struct pci_controller *hose; | ||
| 140 | 142 | ||
| 141 | if (bus == hose->first_busno) { | 143 | hose = pci_bus_to_host(bus); |
| 144 | if (hose == NULL) | ||
| 145 | return NULL; | ||
| 146 | |||
| 147 | if (bus->number == hose->first_busno) { | ||
| 142 | if (dev_fn < (11 << 3)) | 148 | if (dev_fn < (11 << 3)) |
| 143 | return NULL; | 149 | return NULL; |
| 144 | caddr = MACRISC_CFA0(dev_fn, offset); | 150 | caddr = MACRISC_CFA0(dev_fn, offset); |
| 145 | } else | 151 | } else |
| 146 | caddr = MACRISC_CFA1(bus, dev_fn, offset); | 152 | caddr = MACRISC_CFA1(bus->number, dev_fn, offset); |
| 147 | 153 | ||
| 148 | /* Uninorth will return garbage if we don't read back the value ! */ | 154 | /* Uninorth will return garbage if we don't read back the value ! */ |
| 149 | do { | 155 | do { |
| @@ -154,129 +160,46 @@ static volatile void __iomem *macrisc_cfg_access(struct pci_controller* hose, | |||
| 154 | return hose->cfg_data + offset; | 160 | return hose->cfg_data + offset; |
| 155 | } | 161 | } |
| 156 | 162 | ||
| 157 | static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn, | ||
| 158 | int offset, int len, u32 *val) | ||
| 159 | { | ||
| 160 | struct pci_controller *hose; | ||
| 161 | volatile void __iomem *addr; | ||
| 162 | |||
| 163 | hose = pci_bus_to_host(bus); | ||
| 164 | if (hose == NULL) | ||
| 165 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 166 | if (offset >= 0x100) | ||
| 167 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
| 168 | addr = macrisc_cfg_access(hose, bus->number, devfn, offset); | ||
| 169 | if (!addr) | ||
| 170 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 171 | /* | ||
| 172 | * Note: the caller has already checked that offset is | ||
| 173 | * suitably aligned and that len is 1, 2 or 4. | ||
| 174 | */ | ||
| 175 | switch (len) { | ||
| 176 | case 1: | ||
| 177 | *val = in_8(addr); | ||
| 178 | break; | ||
| 179 | case 2: | ||
| 180 | *val = in_le16(addr); | ||
| 181 | break; | ||
| 182 | default: | ||
| 183 | *val = in_le32(addr); | ||
| 184 | break; | ||
| 185 | } | ||
| 186 | return PCIBIOS_SUCCESSFUL; | ||
| 187 | } | ||
| 188 | |||
| 189 | static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn, | ||
| 190 | int offset, int len, u32 val) | ||
| 191 | { | ||
| 192 | struct pci_controller *hose; | ||
| 193 | volatile void __iomem *addr; | ||
| 194 | |||
| 195 | hose = pci_bus_to_host(bus); | ||
| 196 | if (hose == NULL) | ||
| 197 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 198 | if (offset >= 0x100) | ||
| 199 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
| 200 | addr = macrisc_cfg_access(hose, bus->number, devfn, offset); | ||
| 201 | if (!addr) | ||
| 202 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 203 | /* | ||
| 204 | * Note: the caller has already checked that offset is | ||
| 205 | * suitably aligned and that len is 1, 2 or 4. | ||
| 206 | */ | ||
| 207 | switch (len) { | ||
| 208 | case 1: | ||
| 209 | out_8(addr, val); | ||
| 210 | break; | ||
| 211 | case 2: | ||
| 212 | out_le16(addr, val); | ||
| 213 | break; | ||
| 214 | default: | ||
| 215 | out_le32(addr, val); | ||
| 216 | break; | ||
| 217 | } | ||
| 218 | return PCIBIOS_SUCCESSFUL; | ||
| 219 | } | ||
| 220 | |||
| 221 | static struct pci_ops macrisc_pci_ops = | 163 | static struct pci_ops macrisc_pci_ops = |
| 222 | { | 164 | { |
| 223 | .read = macrisc_read_config, | 165 | .map_bus = macrisc_cfg_map_bus, |
| 224 | .write = macrisc_write_config, | 166 | .read = pci_generic_config_read, |
| 167 | .write = pci_generic_config_write, | ||
| 225 | }; | 168 | }; |
| 226 | 169 | ||
| 227 | #ifdef CONFIG_PPC32 | 170 | #ifdef CONFIG_PPC32 |
| 228 | /* | 171 | /* |
| 229 | * Verify that a specific (bus, dev_fn) exists on chaos | 172 | * Verify that a specific (bus, dev_fn) exists on chaos |
| 230 | */ | 173 | */ |
| 231 | static int chaos_validate_dev(struct pci_bus *bus, int devfn, int offset) | 174 | static void __iomem *chaos_map_bus(struct pci_bus *bus, unsigned int devfn, |
| 175 | int offset) | ||
| 232 | { | 176 | { |
| 233 | struct device_node *np; | 177 | struct device_node *np; |
| 234 | const u32 *vendor, *device; | 178 | const u32 *vendor, *device; |
| 235 | 179 | ||
| 236 | if (offset >= 0x100) | 180 | if (offset >= 0x100) |
| 237 | return PCIBIOS_BAD_REGISTER_NUMBER; | 181 | return NULL; |
| 238 | np = of_pci_find_child_device(bus->dev.of_node, devfn); | 182 | np = of_pci_find_child_device(bus->dev.of_node, devfn); |
| 239 | if (np == NULL) | 183 | if (np == NULL) |
| 240 | return PCIBIOS_DEVICE_NOT_FOUND; | 184 | return NULL; |
| 241 | 185 | ||
| 242 | vendor = of_get_property(np, "vendor-id", NULL); | 186 | vendor = of_get_property(np, "vendor-id", NULL); |
| 243 | device = of_get_property(np, "device-id", NULL); | 187 | device = of_get_property(np, "device-id", NULL); |
| 244 | if (vendor == NULL || device == NULL) | 188 | if (vendor == NULL || device == NULL) |
| 245 | return PCIBIOS_DEVICE_NOT_FOUND; | 189 | return NULL; |
| 246 | 190 | ||
| 247 | if ((*vendor == 0x106b) && (*device == 3) && (offset >= 0x10) | 191 | if ((*vendor == 0x106b) && (*device == 3) && (offset >= 0x10) |
| 248 | && (offset != 0x14) && (offset != 0x18) && (offset <= 0x24)) | 192 | && (offset != 0x14) && (offset != 0x18) && (offset <= 0x24)) |
| 249 | return PCIBIOS_BAD_REGISTER_NUMBER; | 193 | return NULL; |
| 250 | |||
| 251 | return PCIBIOS_SUCCESSFUL; | ||
| 252 | } | ||
| 253 | 194 | ||
| 254 | static int | 195 | return macrisc_cfg_map_bus(bus, devfn, offset); |
| 255 | chaos_read_config(struct pci_bus *bus, unsigned int devfn, int offset, | ||
| 256 | int len, u32 *val) | ||
| 257 | { | ||
| 258 | int result = chaos_validate_dev(bus, devfn, offset); | ||
| 259 | if (result == PCIBIOS_BAD_REGISTER_NUMBER) | ||
| 260 | *val = ~0U; | ||
| 261 | if (result != PCIBIOS_SUCCESSFUL) | ||
| 262 | return result; | ||
| 263 | return macrisc_read_config(bus, devfn, offset, len, val); | ||
| 264 | } | ||
| 265 | |||
| 266 | static int | ||
| 267 | chaos_write_config(struct pci_bus *bus, unsigned int devfn, int offset, | ||
| 268 | int len, u32 val) | ||
| 269 | { | ||
| 270 | int result = chaos_validate_dev(bus, devfn, offset); | ||
| 271 | if (result != PCIBIOS_SUCCESSFUL) | ||
| 272 | return result; | ||
| 273 | return macrisc_write_config(bus, devfn, offset, len, val); | ||
| 274 | } | 196 | } |
| 275 | 197 | ||
| 276 | static struct pci_ops chaos_pci_ops = | 198 | static struct pci_ops chaos_pci_ops = |
| 277 | { | 199 | { |
| 278 | .read = chaos_read_config, | 200 | .map_bus = chaos_map_bus, |
| 279 | .write = chaos_write_config, | 201 | .read = pci_generic_config_read, |
| 202 | .write = pci_generic_config_write, | ||
| 280 | }; | 203 | }; |
| 281 | 204 | ||
| 282 | static void __init setup_chaos(struct pci_controller *hose, | 205 | static void __init setup_chaos(struct pci_controller *hose, |
| @@ -471,15 +394,24 @@ static struct pci_ops u3_ht_pci_ops = | |||
| 471 | |(((unsigned int)(off)) & 0xfcU) \ | 394 | |(((unsigned int)(off)) & 0xfcU) \ |
| 472 | |1UL) | 395 | |1UL) |
| 473 | 396 | ||
| 474 | static volatile void __iomem *u4_pcie_cfg_access(struct pci_controller* hose, | 397 | static void __iomem *u4_pcie_cfg_map_bus(struct pci_bus *bus, |
| 475 | u8 bus, u8 dev_fn, int offset) | 398 | unsigned int dev_fn, |
| 399 | int offset) | ||
| 476 | { | 400 | { |
| 401 | struct pci_controller *hose; | ||
| 477 | unsigned int caddr; | 402 | unsigned int caddr; |
| 478 | 403 | ||
| 479 | if (bus == hose->first_busno) { | 404 | if (offset >= 0x1000) |
| 405 | return NULL; | ||
| 406 | |||
| 407 | hose = pci_bus_to_host(bus); | ||
| 408 | if (!hose) | ||
| 409 | return NULL; | ||
| 410 | |||
| 411 | if (bus->number == hose->first_busno) { | ||
| 480 | caddr = U4_PCIE_CFA0(dev_fn, offset); | 412 | caddr = U4_PCIE_CFA0(dev_fn, offset); |
| 481 | } else | 413 | } else |
| 482 | caddr = U4_PCIE_CFA1(bus, dev_fn, offset); | 414 | caddr = U4_PCIE_CFA1(bus->number, dev_fn, offset); |
| 483 | 415 | ||
| 484 | /* Uninorth will return garbage if we don't read back the value ! */ | 416 | /* Uninorth will return garbage if we don't read back the value ! */ |
| 485 | do { | 417 | do { |
| @@ -490,74 +422,11 @@ static volatile void __iomem *u4_pcie_cfg_access(struct pci_controller* hose, | |||
| 490 | return hose->cfg_data + offset; | 422 | return hose->cfg_data + offset; |
| 491 | } | 423 | } |
| 492 | 424 | ||
| 493 | static int u4_pcie_read_config(struct pci_bus *bus, unsigned int devfn, | ||
| 494 | int offset, int len, u32 *val) | ||
| 495 | { | ||
| 496 | struct pci_controller *hose; | ||
| 497 | volatile void __iomem *addr; | ||
| 498 | |||
| 499 | hose = pci_bus_to_host(bus); | ||
| 500 | if (hose == NULL) | ||
| 501 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 502 | if (offset >= 0x1000) | ||
| 503 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
| 504 | addr = u4_pcie_cfg_access(hose, bus->number, devfn, offset); | ||
| 505 | if (!addr) | ||
| 506 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 507 | /* | ||
| 508 | * Note: the caller has already checked that offset is | ||
| 509 | * suitably aligned and that len is 1, 2 or 4. | ||
| 510 | */ | ||
| 511 | switch (len) { | ||
| 512 | case 1: | ||
| 513 | *val = in_8(addr); | ||
| 514 | break; | ||
| 515 | case 2: | ||
| 516 | *val = in_le16(addr); | ||
| 517 | break; | ||
| 518 | default: | ||
| 519 | *val = in_le32(addr); | ||
| 520 | break; | ||
| 521 | } | ||
| 522 | return PCIBIOS_SUCCESSFUL; | ||
| 523 | } | ||
| 524 | |||
| 525 | static int u4_pcie_write_config(struct pci_bus *bus, unsigned int devfn, | ||
| 526 | int offset, int len, u32 val) | ||
| 527 | { | ||
| 528 | struct pci_controller *hose; | ||
| 529 | volatile void __iomem *addr; | ||
| 530 | |||
| 531 | hose = pci_bus_to_host(bus); | ||
| 532 | if (hose == NULL) | ||
| 533 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 534 | if (offset >= 0x1000) | ||
| 535 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
| 536 | addr = u4_pcie_cfg_access(hose, bus->number, devfn, offset); | ||
| 537 | if (!addr) | ||
| 538 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 539 | /* | ||
| 540 | * Note: the caller has already checked that offset is | ||
| 541 | * suitably aligned and that len is 1, 2 or 4. | ||
| 542 | */ | ||
| 543 | switch (len) { | ||
| 544 | case 1: | ||
| 545 | out_8(addr, val); | ||
| 546 | break; | ||
| 547 | case 2: | ||
| 548 | out_le16(addr, val); | ||
| 549 | break; | ||
| 550 | default: | ||
| 551 | out_le32(addr, val); | ||
| 552 | break; | ||
| 553 | } | ||
| 554 | return PCIBIOS_SUCCESSFUL; | ||
| 555 | } | ||
| 556 | |||
| 557 | static struct pci_ops u4_pcie_pci_ops = | 425 | static struct pci_ops u4_pcie_pci_ops = |
| 558 | { | 426 | { |
| 559 | .read = u4_pcie_read_config, | 427 | .map_bus = u4_pcie_cfg_map_bus, |
| 560 | .write = u4_pcie_write_config, | 428 | .read = pci_generic_config_read, |
| 429 | .write = pci_generic_config_write, | ||
| 561 | }; | 430 | }; |
| 562 | 431 | ||
| 563 | static void pmac_pci_fixup_u4_of_node(struct pci_dev *dev) | 432 | 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: | |||
| 645 | return pcie->cfg_type1 + offset; | 645 | return pcie->cfg_type1 + offset; |
| 646 | } | 646 | } |
| 647 | 647 | ||
| 648 | static int mpc83xx_pcie_read_config(struct pci_bus *bus, unsigned int devfn, | ||
| 649 | int offset, int len, u32 *val) | ||
| 650 | { | ||
| 651 | void __iomem *cfg_addr; | ||
| 652 | |||
| 653 | cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset); | ||
| 654 | if (!cfg_addr) | ||
| 655 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 656 | |||
| 657 | switch (len) { | ||
| 658 | case 1: | ||
| 659 | *val = in_8(cfg_addr); | ||
| 660 | break; | ||
| 661 | case 2: | ||
| 662 | *val = in_le16(cfg_addr); | ||
| 663 | break; | ||
| 664 | default: | ||
| 665 | *val = in_le32(cfg_addr); | ||
| 666 | break; | ||
| 667 | } | ||
| 668 | |||
| 669 | return PCIBIOS_SUCCESSFUL; | ||
| 670 | } | ||
| 671 | |||
| 672 | static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsigned int devfn, | 648 | static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsigned int devfn, |
| 673 | int offset, int len, u32 val) | 649 | int offset, int len, u32 val) |
| 674 | { | 650 | { |
| 675 | struct pci_controller *hose = pci_bus_to_host(bus); | 651 | struct pci_controller *hose = pci_bus_to_host(bus); |
| 676 | void __iomem *cfg_addr; | ||
| 677 | |||
| 678 | cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset); | ||
| 679 | if (!cfg_addr) | ||
| 680 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 681 | 652 | ||
| 682 | /* PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS */ | 653 | /* PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS */ |
| 683 | if (offset == PCI_PRIMARY_BUS && bus->number == hose->first_busno) | 654 | if (offset == PCI_PRIMARY_BUS && bus->number == hose->first_busno) |
| 684 | val &= 0xffffff00; | 655 | val &= 0xffffff00; |
| 685 | 656 | ||
| 686 | switch (len) { | 657 | return pci_generic_config_write(bus, devfn, offset, len, val); |
| 687 | case 1: | ||
| 688 | out_8(cfg_addr, val); | ||
| 689 | break; | ||
| 690 | case 2: | ||
| 691 | out_le16(cfg_addr, val); | ||
| 692 | break; | ||
| 693 | default: | ||
| 694 | out_le32(cfg_addr, val); | ||
| 695 | break; | ||
| 696 | } | ||
| 697 | |||
| 698 | return PCIBIOS_SUCCESSFUL; | ||
| 699 | } | 658 | } |
| 700 | 659 | ||
| 701 | static struct pci_ops mpc83xx_pcie_ops = { | 660 | static struct pci_ops mpc83xx_pcie_ops = { |
| 702 | .read = mpc83xx_pcie_read_config, | 661 | .map_bus = mpc83xx_pcie_remap_cfg, |
| 662 | .read = pci_generic_config_read, | ||
| 703 | .write = mpc83xx_pcie_write_config, | 663 | .write = mpc83xx_pcie_write_config, |
| 704 | }; | 664 | }; |
| 705 | 665 | ||
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) | |||
| 245 | { | 245 | { |
| 246 | struct pci_dev *dev = NULL; | 246 | struct pci_dev *dev = NULL; |
| 247 | int smallest_max_payload = 0x1; /* Tile maxes out at 256 bytes. */ | 247 | int smallest_max_payload = 0x1; /* Tile maxes out at 256 bytes. */ |
| 248 | int max_read_size = 0x2; /* Limit to 512 byte reads. */ | 248 | int max_read_size = PCI_EXP_DEVCTL_READRQ_512B; |
| 249 | u16 new_values; | 249 | u16 new_values; |
| 250 | 250 | ||
| 251 | /* Scan for the smallest maximum payload size. */ | 251 | /* Scan for the smallest maximum payload size. */ |
| @@ -258,7 +258,7 @@ static void fixup_read_and_payload_sizes(void) | |||
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | /* Now, set the max_payload_size for all devices to that value. */ | 260 | /* Now, set the max_payload_size for all devices to that value. */ |
| 261 | new_values = (max_read_size << 12) | (smallest_max_payload << 5); | 261 | new_values = max_read_size | (smallest_max_payload << 5); |
| 262 | for_each_pci_dev(dev) | 262 | for_each_pci_dev(dev) |
| 263 | pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL, | 263 | pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL, |
| 264 | PCI_EXP_DEVCTL_PAYLOAD | PCI_EXP_DEVCTL_READRQ, | 264 | 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) | |||
| 298 | map_irq.entry_nr = nvec; | 298 | map_irq.entry_nr = nvec; |
| 299 | } else if (type == PCI_CAP_ID_MSIX) { | 299 | } else if (type == PCI_CAP_ID_MSIX) { |
| 300 | int pos; | 300 | int pos; |
| 301 | unsigned long flags; | ||
| 301 | u32 table_offset, bir; | 302 | u32 table_offset, bir; |
| 302 | 303 | ||
| 303 | pos = dev->msix_cap; | 304 | pos = dev->msix_cap; |
| 304 | pci_read_config_dword(dev, pos + PCI_MSIX_TABLE, | 305 | pci_read_config_dword(dev, pos + PCI_MSIX_TABLE, |
| 305 | &table_offset); | 306 | &table_offset); |
| 306 | bir = (u8)(table_offset & PCI_MSIX_TABLE_BIR); | 307 | bir = (u8)(table_offset & PCI_MSIX_TABLE_BIR); |
| 308 | flags = pci_resource_flags(dev, bir); | ||
| 309 | if (!flags || (flags & IORESOURCE_UNSET)) | ||
| 310 | return -EINVAL; | ||
| 307 | 311 | ||
| 308 | map_irq.table_base = pci_resource_start(dev, bir); | 312 | map_irq.table_base = pci_resource_start(dev, bir); |
| 309 | map_irq.entry_nr = msidesc->msi_attrib.entry_nr; | 313 | map_irq.entry_nr = msidesc->msi_attrib.entry_nr; |
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 14a1c5cec3a5..fa274e0f47d7 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
| @@ -4915,7 +4915,7 @@ static void r8168c_hw_jumbo_enable(struct rtl8169_private *tp) | |||
| 4915 | 4915 | ||
| 4916 | RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); | 4916 | RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); |
| 4917 | RTL_W8(Config4, RTL_R8(Config4) | Jumbo_En1); | 4917 | RTL_W8(Config4, RTL_R8(Config4) | Jumbo_En1); |
| 4918 | rtl_tx_performance_tweak(tp->pci_dev, 0x2 << MAX_READ_REQUEST_SHIFT); | 4918 | rtl_tx_performance_tweak(tp->pci_dev, PCI_EXP_DEVCTL_READRQ_512B); |
| 4919 | } | 4919 | } |
| 4920 | 4920 | ||
| 4921 | static void r8168c_hw_jumbo_disable(struct rtl8169_private *tp) | 4921 | static void r8168c_hw_jumbo_disable(struct rtl8169_private *tp) |
| @@ -4948,7 +4948,7 @@ static void r8168e_hw_jumbo_enable(struct rtl8169_private *tp) | |||
| 4948 | RTL_W8(MaxTxPacketSize, 0x3f); | 4948 | RTL_W8(MaxTxPacketSize, 0x3f); |
| 4949 | RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); | 4949 | RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); |
| 4950 | RTL_W8(Config4, RTL_R8(Config4) | 0x01); | 4950 | RTL_W8(Config4, RTL_R8(Config4) | 0x01); |
| 4951 | rtl_tx_performance_tweak(tp->pci_dev, 0x2 << MAX_READ_REQUEST_SHIFT); | 4951 | rtl_tx_performance_tweak(tp->pci_dev, PCI_EXP_DEVCTL_READRQ_512B); |
| 4952 | } | 4952 | } |
| 4953 | 4953 | ||
| 4954 | static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp) | 4954 | static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp) |
| @@ -4964,7 +4964,7 @@ static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp) | |||
| 4964 | static void r8168b_0_hw_jumbo_enable(struct rtl8169_private *tp) | 4964 | static void r8168b_0_hw_jumbo_enable(struct rtl8169_private *tp) |
| 4965 | { | 4965 | { |
| 4966 | rtl_tx_performance_tweak(tp->pci_dev, | 4966 | rtl_tx_performance_tweak(tp->pci_dev, |
| 4967 | (0x2 << MAX_READ_REQUEST_SHIFT) | PCI_EXP_DEVCTL_NOSNOOP_EN); | 4967 | PCI_EXP_DEVCTL_READRQ_512B | PCI_EXP_DEVCTL_NOSNOOP_EN); |
| 4968 | } | 4968 | } |
| 4969 | 4969 | ||
| 4970 | static void r8168b_0_hw_jumbo_disable(struct rtl8169_private *tp) | 4970 | static void r8168b_0_hw_jumbo_disable(struct rtl8169_private *tp) |
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c index 88471d3d98cd..60dc36c865b5 100644 --- a/drivers/of/of_pci.c +++ b/drivers/of/of_pci.c | |||
| @@ -140,6 +140,7 @@ int of_pci_get_host_bridge_resources(struct device_node *dev, | |||
| 140 | unsigned char busno, unsigned char bus_max, | 140 | unsigned char busno, unsigned char bus_max, |
| 141 | struct list_head *resources, resource_size_t *io_base) | 141 | struct list_head *resources, resource_size_t *io_base) |
| 142 | { | 142 | { |
| 143 | struct pci_host_bridge_window *window; | ||
| 143 | struct resource *res; | 144 | struct resource *res; |
| 144 | struct resource *bus_range; | 145 | struct resource *bus_range; |
| 145 | struct of_pci_range range; | 146 | struct of_pci_range range; |
| @@ -225,7 +226,10 @@ int of_pci_get_host_bridge_resources(struct device_node *dev, | |||
| 225 | conversion_failed: | 226 | conversion_failed: |
| 226 | kfree(res); | 227 | kfree(res); |
| 227 | parse_failed: | 228 | parse_failed: |
| 229 | list_for_each_entry(window, resources, list) | ||
| 230 | kfree(window->res); | ||
| 228 | pci_free_resource_list(resources); | 231 | pci_free_resource_list(resources); |
| 232 | kfree(bus_range); | ||
| 229 | return err; | 233 | return err; |
| 230 | } | 234 | } |
| 231 | EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources); | 235 | EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources); |
diff --git a/drivers/pci/access.c b/drivers/pci/access.c index 49dd766852ba..d9b64a175990 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c | |||
| @@ -67,6 +67,93 @@ EXPORT_SYMBOL(pci_bus_write_config_byte); | |||
| 67 | EXPORT_SYMBOL(pci_bus_write_config_word); | 67 | EXPORT_SYMBOL(pci_bus_write_config_word); |
| 68 | EXPORT_SYMBOL(pci_bus_write_config_dword); | 68 | EXPORT_SYMBOL(pci_bus_write_config_dword); |
| 69 | 69 | ||
| 70 | int pci_generic_config_read(struct pci_bus *bus, unsigned int devfn, | ||
| 71 | int where, int size, u32 *val) | ||
| 72 | { | ||
| 73 | void __iomem *addr; | ||
| 74 | |||
| 75 | addr = bus->ops->map_bus(bus, devfn, where); | ||
| 76 | if (!addr) { | ||
| 77 | *val = ~0; | ||
| 78 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 79 | } | ||
| 80 | |||
| 81 | if (size == 1) | ||
| 82 | *val = readb(addr); | ||
| 83 | else if (size == 2) | ||
| 84 | *val = readw(addr); | ||
| 85 | else | ||
| 86 | *val = readl(addr); | ||
| 87 | |||
| 88 | return PCIBIOS_SUCCESSFUL; | ||
| 89 | } | ||
| 90 | EXPORT_SYMBOL_GPL(pci_generic_config_read); | ||
| 91 | |||
| 92 | int pci_generic_config_write(struct pci_bus *bus, unsigned int devfn, | ||
| 93 | int where, int size, u32 val) | ||
| 94 | { | ||
| 95 | void __iomem *addr; | ||
| 96 | |||
| 97 | addr = bus->ops->map_bus(bus, devfn, where); | ||
| 98 | if (!addr) | ||
| 99 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 100 | |||
| 101 | if (size == 1) | ||
| 102 | writeb(val, addr); | ||
| 103 | else if (size == 2) | ||
| 104 | writew(val, addr); | ||
| 105 | else | ||
| 106 | writel(val, addr); | ||
| 107 | |||
| 108 | return PCIBIOS_SUCCESSFUL; | ||
| 109 | } | ||
| 110 | EXPORT_SYMBOL_GPL(pci_generic_config_write); | ||
| 111 | |||
| 112 | int pci_generic_config_read32(struct pci_bus *bus, unsigned int devfn, | ||
| 113 | int where, int size, u32 *val) | ||
| 114 | { | ||
| 115 | void __iomem *addr; | ||
| 116 | |||
| 117 | addr = bus->ops->map_bus(bus, devfn, where & ~0x3); | ||
| 118 | if (!addr) { | ||
| 119 | *val = ~0; | ||
| 120 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 121 | } | ||
| 122 | |||
| 123 | *val = readl(addr); | ||
| 124 | |||
| 125 | if (size <= 2) | ||
| 126 | *val = (*val >> (8 * (where & 3))) & ((1 << (size * 8)) - 1); | ||
| 127 | |||
| 128 | return PCIBIOS_SUCCESSFUL; | ||
| 129 | } | ||
| 130 | EXPORT_SYMBOL_GPL(pci_generic_config_read32); | ||
| 131 | |||
| 132 | int pci_generic_config_write32(struct pci_bus *bus, unsigned int devfn, | ||
| 133 | int where, int size, u32 val) | ||
| 134 | { | ||
| 135 | void __iomem *addr; | ||
| 136 | u32 mask, tmp; | ||
| 137 | |||
| 138 | addr = bus->ops->map_bus(bus, devfn, where & ~0x3); | ||
| 139 | if (!addr) | ||
| 140 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 141 | |||
| 142 | if (size == 4) { | ||
| 143 | writel(val, addr); | ||
| 144 | return PCIBIOS_SUCCESSFUL; | ||
| 145 | } else { | ||
| 146 | mask = ~(((1 << (size * 8)) - 1) << ((where & 0x3) * 8)); | ||
| 147 | } | ||
| 148 | |||
| 149 | tmp = readl(addr) & mask; | ||
| 150 | tmp |= val << ((where & 0x3) * 8); | ||
| 151 | writel(tmp, addr); | ||
| 152 | |||
| 153 | return PCIBIOS_SUCCESSFUL; | ||
| 154 | } | ||
| 155 | EXPORT_SYMBOL_GPL(pci_generic_config_write32); | ||
| 156 | |||
| 70 | /** | 157 | /** |
| 71 | * pci_bus_set_ops - Set raw operations of pci bus | 158 | * pci_bus_set_ops - Set raw operations of pci bus |
| 72 | * @bus: pci bus struct | 159 | * @bus: pci bus struct |
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index c4b6568e486d..7b892a9cc4fc 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig | |||
| @@ -102,4 +102,8 @@ config PCI_LAYERSCAPE | |||
| 102 | help | 102 | help |
| 103 | Say Y here if you want PCIe controller support on Layerscape SoCs. | 103 | Say Y here if you want PCIe controller support on Layerscape SoCs. |
| 104 | 104 | ||
| 105 | config PCI_VERSATILE | ||
| 106 | bool "ARM Versatile PB PCI controller" | ||
| 107 | depends on ARCH_VERSATILE | ||
| 108 | |||
| 105 | endmenu | 109 | endmenu |
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 44c26998027f..e61d91c92bf1 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile | |||
| @@ -12,3 +12,4 @@ obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone-dw.o pci-keystone.o | |||
| 12 | obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o | 12 | obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o |
| 13 | obj-$(CONFIG_PCI_XGENE) += pci-xgene.o | 13 | obj-$(CONFIG_PCI_XGENE) += pci-xgene.o |
| 14 | obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o | 14 | obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o |
| 15 | obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o | ||
diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c index 6eb1aa75bd37..925e29e3d4c8 100644 --- a/drivers/pci/host/pci-host-generic.c +++ b/drivers/pci/host/pci-host-generic.c | |||
| @@ -76,55 +76,9 @@ static struct gen_pci_cfg_bus_ops gen_pci_cfg_ecam_bus_ops = { | |||
| 76 | .map_bus = gen_pci_map_cfg_bus_ecam, | 76 | .map_bus = gen_pci_map_cfg_bus_ecam, |
| 77 | }; | 77 | }; |
| 78 | 78 | ||
| 79 | static int gen_pci_config_read(struct pci_bus *bus, unsigned int devfn, | ||
| 80 | int where, int size, u32 *val) | ||
| 81 | { | ||
| 82 | void __iomem *addr; | ||
| 83 | struct pci_sys_data *sys = bus->sysdata; | ||
| 84 | struct gen_pci *pci = sys->private_data; | ||
| 85 | |||
| 86 | addr = pci->cfg.ops->map_bus(bus, devfn, where); | ||
| 87 | |||
| 88 | switch (size) { | ||
| 89 | case 1: | ||
| 90 | *val = readb(addr); | ||
| 91 | break; | ||
| 92 | case 2: | ||
| 93 | *val = readw(addr); | ||
| 94 | break; | ||
| 95 | default: | ||
| 96 | *val = readl(addr); | ||
| 97 | } | ||
| 98 | |||
| 99 | return PCIBIOS_SUCCESSFUL; | ||
| 100 | } | ||
| 101 | |||
| 102 | static int gen_pci_config_write(struct pci_bus *bus, unsigned int devfn, | ||
| 103 | int where, int size, u32 val) | ||
| 104 | { | ||
| 105 | void __iomem *addr; | ||
| 106 | struct pci_sys_data *sys = bus->sysdata; | ||
| 107 | struct gen_pci *pci = sys->private_data; | ||
| 108 | |||
| 109 | addr = pci->cfg.ops->map_bus(bus, devfn, where); | ||
| 110 | |||
| 111 | switch (size) { | ||
| 112 | case 1: | ||
| 113 | writeb(val, addr); | ||
| 114 | break; | ||
| 115 | case 2: | ||
| 116 | writew(val, addr); | ||
| 117 | break; | ||
| 118 | default: | ||
| 119 | writel(val, addr); | ||
| 120 | } | ||
| 121 | |||
| 122 | return PCIBIOS_SUCCESSFUL; | ||
| 123 | } | ||
| 124 | |||
| 125 | static struct pci_ops gen_pci_ops = { | 79 | static struct pci_ops gen_pci_ops = { |
| 126 | .read = gen_pci_config_read, | 80 | .read = pci_generic_config_read, |
| 127 | .write = gen_pci_config_write, | 81 | .write = pci_generic_config_write, |
| 128 | }; | 82 | }; |
| 129 | 83 | ||
| 130 | static const struct of_device_id gen_pci_of_match[] = { | 84 | static const struct of_device_id gen_pci_of_match[] = { |
| @@ -287,6 +241,7 @@ static int gen_pci_probe(struct platform_device *pdev) | |||
| 287 | 241 | ||
| 288 | of_id = of_match_node(gen_pci_of_match, np); | 242 | of_id = of_match_node(gen_pci_of_match, np); |
| 289 | pci->cfg.ops = of_id->data; | 243 | pci->cfg.ops = of_id->data; |
| 244 | gen_pci_ops.map_bus = pci->cfg.ops->map_bus; | ||
| 290 | pci->host.dev.parent = dev; | 245 | pci->host.dev.parent = dev; |
| 291 | INIT_LIST_HEAD(&pci->host.windows); | 246 | INIT_LIST_HEAD(&pci->host.windows); |
| 292 | INIT_LIST_HEAD(&pci->resources); | 247 | INIT_LIST_HEAD(&pci->resources); |
diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c index 78f79e31ac5c..75333b0c4f0a 100644 --- a/drivers/pci/host/pci-keystone.c +++ b/drivers/pci/host/pci-keystone.c | |||
| @@ -119,7 +119,7 @@ static void ks_pcie_msi_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
| 119 | struct pcie_port *pp = &ks_pcie->pp; | 119 | struct pcie_port *pp = &ks_pcie->pp; |
| 120 | struct irq_chip *chip = irq_desc_get_chip(desc); | 120 | struct irq_chip *chip = irq_desc_get_chip(desc); |
| 121 | 121 | ||
| 122 | dev_dbg(pp->dev, "ks_pci_msi_irq_handler, irq %d\n", irq); | 122 | dev_dbg(pp->dev, "%s, irq %d\n", __func__, irq); |
| 123 | 123 | ||
| 124 | /* | 124 | /* |
| 125 | * The chained irq handler installation would have replaced normal | 125 | * The chained irq handler installation would have replaced normal |
| @@ -197,7 +197,7 @@ static int ks_pcie_get_irq_controller_info(struct keystone_pcie *ks_pcie, | |||
| 197 | */ | 197 | */ |
| 198 | for (temp = 0; temp < max_host_irqs; temp++) { | 198 | for (temp = 0; temp < max_host_irqs; temp++) { |
| 199 | host_irqs[temp] = irq_of_parse_and_map(*np_temp, temp); | 199 | host_irqs[temp] = irq_of_parse_and_map(*np_temp, temp); |
| 200 | if (host_irqs[temp] < 0) | 200 | if (!host_irqs[temp]) |
| 201 | break; | 201 | break; |
| 202 | } | 202 | } |
| 203 | if (temp) { | 203 | if (temp) { |
diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c index 6697b1a4d4fa..68c9e5e9b0a8 100644 --- a/drivers/pci/host/pci-layerscape.c +++ b/drivers/pci/host/pci-layerscape.c | |||
| @@ -167,7 +167,6 @@ MODULE_DEVICE_TABLE(of, ls_pcie_of_match); | |||
| 167 | static struct platform_driver ls_pcie_driver = { | 167 | static struct platform_driver ls_pcie_driver = { |
| 168 | .driver = { | 168 | .driver = { |
| 169 | .name = "layerscape-pcie", | 169 | .name = "layerscape-pcie", |
| 170 | .owner = THIS_MODULE, | ||
| 171 | .of_match_table = ls_pcie_of_match, | 170 | .of_match_table = ls_pcie_of_match, |
| 172 | }, | 171 | }, |
| 173 | }; | 172 | }; |
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index 1dd759596b0a..1309cfbaa719 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c | |||
| @@ -101,9 +101,7 @@ struct mvebu_pcie { | |||
| 101 | struct mvebu_pcie_port *ports; | 101 | struct mvebu_pcie_port *ports; |
| 102 | struct msi_controller *msi; | 102 | struct msi_controller *msi; |
| 103 | struct resource io; | 103 | struct resource io; |
| 104 | char io_name[30]; | ||
| 105 | struct resource realio; | 104 | struct resource realio; |
| 106 | char mem_name[30]; | ||
| 107 | struct resource mem; | 105 | struct resource mem; |
| 108 | struct resource busn; | 106 | struct resource busn; |
| 109 | int nports; | 107 | int nports; |
| @@ -723,18 +721,9 @@ static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys) | |||
| 723 | { | 721 | { |
| 724 | struct mvebu_pcie *pcie = sys_to_pcie(sys); | 722 | struct mvebu_pcie *pcie = sys_to_pcie(sys); |
| 725 | int i; | 723 | int i; |
| 726 | int domain = 0; | ||
| 727 | 724 | ||
| 728 | #ifdef CONFIG_PCI_DOMAINS | 725 | pcie->mem.name = "PCI MEM"; |
| 729 | domain = sys->domain; | 726 | pcie->realio.name = "PCI I/O"; |
| 730 | #endif | ||
| 731 | |||
| 732 | snprintf(pcie->mem_name, sizeof(pcie->mem_name), "PCI MEM %04x", | ||
| 733 | domain); | ||
| 734 | pcie->mem.name = pcie->mem_name; | ||
| 735 | |||
| 736 | snprintf(pcie->io_name, sizeof(pcie->io_name), "PCI I/O %04x", domain); | ||
| 737 | pcie->realio.name = pcie->io_name; | ||
| 738 | 727 | ||
| 739 | if (request_resource(&iomem_resource, &pcie->mem)) | 728 | if (request_resource(&iomem_resource, &pcie->mem)) |
| 740 | return 0; | 729 | return 0; |
diff --git a/drivers/pci/host/pci-rcar-gen2.c b/drivers/pci/host/pci-rcar-gen2.c index d9c042febb1a..dd6b84e6206c 100644 --- a/drivers/pci/host/pci-rcar-gen2.c +++ b/drivers/pci/host/pci-rcar-gen2.c | |||
| @@ -131,52 +131,6 @@ static void __iomem *rcar_pci_cfg_base(struct pci_bus *bus, unsigned int devfn, | |||
| 131 | return priv->reg + (slot >> 1) * 0x100 + where; | 131 | return priv->reg + (slot >> 1) * 0x100 + where; |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | static int rcar_pci_read_config(struct pci_bus *bus, unsigned int devfn, | ||
| 135 | int where, int size, u32 *val) | ||
| 136 | { | ||
| 137 | void __iomem *reg = rcar_pci_cfg_base(bus, devfn, where); | ||
| 138 | |||
| 139 | if (!reg) | ||
| 140 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 141 | |||
| 142 | switch (size) { | ||
| 143 | case 1: | ||
| 144 | *val = ioread8(reg); | ||
| 145 | break; | ||
| 146 | case 2: | ||
| 147 | *val = ioread16(reg); | ||
| 148 | break; | ||
| 149 | default: | ||
| 150 | *val = ioread32(reg); | ||
| 151 | break; | ||
| 152 | } | ||
| 153 | |||
| 154 | return PCIBIOS_SUCCESSFUL; | ||
| 155 | } | ||
| 156 | |||
| 157 | static int rcar_pci_write_config(struct pci_bus *bus, unsigned int devfn, | ||
| 158 | int where, int size, u32 val) | ||
| 159 | { | ||
| 160 | void __iomem *reg = rcar_pci_cfg_base(bus, devfn, where); | ||
| 161 | |||
| 162 | if (!reg) | ||
| 163 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 164 | |||
| 165 | switch (size) { | ||
| 166 | case 1: | ||
| 167 | iowrite8(val, reg); | ||
| 168 | break; | ||
| 169 | case 2: | ||
| 170 | iowrite16(val, reg); | ||
| 171 | break; | ||
| 172 | default: | ||
| 173 | iowrite32(val, reg); | ||
| 174 | break; | ||
| 175 | } | ||
| 176 | |||
| 177 | return PCIBIOS_SUCCESSFUL; | ||
| 178 | } | ||
| 179 | |||
| 180 | /* PCI interrupt mapping */ | 134 | /* PCI interrupt mapping */ |
| 181 | static int rcar_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | 135 | static int rcar_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) |
| 182 | { | 136 | { |
| @@ -325,8 +279,9 @@ static int rcar_pci_setup(int nr, struct pci_sys_data *sys) | |||
| 325 | } | 279 | } |
| 326 | 280 | ||
| 327 | static struct pci_ops rcar_pci_ops = { | 281 | static struct pci_ops rcar_pci_ops = { |
| 328 | .read = rcar_pci_read_config, | 282 | .map_bus = rcar_pci_cfg_base, |
| 329 | .write = rcar_pci_write_config, | 283 | .read = pci_generic_config_read, |
| 284 | .write = pci_generic_config_write, | ||
| 330 | }; | 285 | }; |
| 331 | 286 | ||
| 332 | static int rcar_pci_probe(struct platform_device *pdev) | 287 | static int rcar_pci_probe(struct platform_device *pdev) |
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index a800ae916394..00e92720d7f7 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c | |||
| @@ -480,59 +480,10 @@ static void __iomem *tegra_pcie_conf_address(struct pci_bus *bus, | |||
| 480 | return addr; | 480 | return addr; |
| 481 | } | 481 | } |
| 482 | 482 | ||
| 483 | static int tegra_pcie_read_conf(struct pci_bus *bus, unsigned int devfn, | ||
| 484 | int where, int size, u32 *value) | ||
| 485 | { | ||
| 486 | void __iomem *addr; | ||
| 487 | |||
| 488 | addr = tegra_pcie_conf_address(bus, devfn, where); | ||
| 489 | if (!addr) { | ||
| 490 | *value = 0xffffffff; | ||
| 491 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 492 | } | ||
| 493 | |||
| 494 | *value = readl(addr); | ||
| 495 | |||
| 496 | if (size == 1) | ||
| 497 | *value = (*value >> (8 * (where & 3))) & 0xff; | ||
| 498 | else if (size == 2) | ||
| 499 | *value = (*value >> (8 * (where & 3))) & 0xffff; | ||
| 500 | |||
| 501 | return PCIBIOS_SUCCESSFUL; | ||
| 502 | } | ||
| 503 | |||
| 504 | static int tegra_pcie_write_conf(struct pci_bus *bus, unsigned int devfn, | ||
| 505 | int where, int size, u32 value) | ||
| 506 | { | ||
| 507 | void __iomem *addr; | ||
| 508 | u32 mask, tmp; | ||
| 509 | |||
| 510 | addr = tegra_pcie_conf_address(bus, devfn, where); | ||
| 511 | if (!addr) | ||
| 512 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 513 | |||
| 514 | if (size == 4) { | ||
| 515 | writel(value, addr); | ||
| 516 | return PCIBIOS_SUCCESSFUL; | ||
| 517 | } | ||
| 518 | |||
| 519 | if (size == 2) | ||
| 520 | mask = ~(0xffff << ((where & 0x3) * 8)); | ||
| 521 | else if (size == 1) | ||
| 522 | mask = ~(0xff << ((where & 0x3) * 8)); | ||
| 523 | else | ||
| 524 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
| 525 | |||
| 526 | tmp = readl(addr) & mask; | ||
| 527 | tmp |= value << ((where & 0x3) * 8); | ||
| 528 | writel(tmp, addr); | ||
| 529 | |||
| 530 | return PCIBIOS_SUCCESSFUL; | ||
| 531 | } | ||
| 532 | |||
| 533 | static struct pci_ops tegra_pcie_ops = { | 483 | static struct pci_ops tegra_pcie_ops = { |
| 534 | .read = tegra_pcie_read_conf, | 484 | .map_bus = tegra_pcie_conf_address, |
| 535 | .write = tegra_pcie_write_conf, | 485 | .read = pci_generic_config_read32, |
| 486 | .write = pci_generic_config_write32, | ||
| 536 | }; | 487 | }; |
| 537 | 488 | ||
| 538 | static unsigned long tegra_pcie_port_get_pex_ctrl(struct tegra_pcie_port *port) | 489 | static unsigned long tegra_pcie_port_get_pex_ctrl(struct tegra_pcie_port *port) |
| @@ -625,19 +576,6 @@ static void tegra_pcie_port_free(struct tegra_pcie_port *port) | |||
| 625 | devm_kfree(pcie->dev, port); | 576 | devm_kfree(pcie->dev, port); |
| 626 | } | 577 | } |
| 627 | 578 | ||
| 628 | static void tegra_pcie_fixup_bridge(struct pci_dev *dev) | ||
| 629 | { | ||
| 630 | u16 reg; | ||
| 631 | |||
| 632 | if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) { | ||
| 633 | pci_read_config_word(dev, PCI_COMMAND, ®); | ||
| 634 | reg |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | | ||
| 635 | PCI_COMMAND_MASTER | PCI_COMMAND_SERR); | ||
| 636 | pci_write_config_word(dev, PCI_COMMAND, reg); | ||
| 637 | } | ||
| 638 | } | ||
| 639 | DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_fixup_bridge); | ||
| 640 | |||
| 641 | /* Tegra PCIE root complex wrongly reports device class */ | 579 | /* Tegra PCIE root complex wrongly reports device class */ |
| 642 | static void tegra_pcie_fixup_class(struct pci_dev *dev) | 580 | static void tegra_pcie_fixup_class(struct pci_dev *dev) |
| 643 | { | 581 | { |
diff --git a/drivers/pci/host/pci-versatile.c b/drivers/pci/host/pci-versatile.c new file mode 100644 index 000000000000..341529ca23e8 --- /dev/null +++ b/drivers/pci/host/pci-versatile.c | |||
| @@ -0,0 +1,237 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2004 Koninklijke Philips Electronics NV | ||
| 3 | * | ||
| 4 | * Conversion to platform driver and DT: | ||
| 5 | * Copyright 2014 Linaro Ltd. | ||
| 6 | * | ||
| 7 | * This software is licensed under the terms of the GNU General Public | ||
| 8 | * License version 2, as published by the Free Software Foundation, and | ||
| 9 | * may be copied, distributed, and modified under those terms. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * 14/04/2005 Initial version, colin.king@philips.com | ||
| 17 | */ | ||
| 18 | #include <linux/kernel.h> | ||
| 19 | #include <linux/module.h> | ||
| 20 | #include <linux/of_address.h> | ||
| 21 | #include <linux/of_pci.h> | ||
| 22 | #include <linux/of_platform.h> | ||
| 23 | #include <linux/pci.h> | ||
| 24 | #include <linux/platform_device.h> | ||
| 25 | |||
| 26 | static void __iomem *versatile_pci_base; | ||
| 27 | static void __iomem *versatile_cfg_base[2]; | ||
| 28 | |||
| 29 | #define PCI_IMAP(m) (versatile_pci_base + ((m) * 4)) | ||
| 30 | #define PCI_SMAP(m) (versatile_pci_base + 0x14 + ((m) * 4)) | ||
| 31 | #define PCI_SELFID (versatile_pci_base + 0xc) | ||
| 32 | |||
| 33 | #define VP_PCI_DEVICE_ID 0x030010ee | ||
| 34 | #define VP_PCI_CLASS_ID 0x0b400000 | ||
| 35 | |||
| 36 | static u32 pci_slot_ignore; | ||
| 37 | |||
| 38 | static int __init versatile_pci_slot_ignore(char *str) | ||
| 39 | { | ||
| 40 | int retval; | ||
| 41 | int slot; | ||
| 42 | |||
| 43 | while ((retval = get_option(&str, &slot))) { | ||
| 44 | if ((slot < 0) || (slot > 31)) | ||
| 45 | pr_err("Illegal slot value: %d\n", slot); | ||
| 46 | else | ||
| 47 | pci_slot_ignore |= (1 << slot); | ||
| 48 | } | ||
| 49 | return 1; | ||
| 50 | } | ||
| 51 | __setup("pci_slot_ignore=", versatile_pci_slot_ignore); | ||
| 52 | |||
| 53 | |||
| 54 | static void __iomem *versatile_map_bus(struct pci_bus *bus, | ||
| 55 | unsigned int devfn, int offset) | ||
| 56 | { | ||
| 57 | unsigned int busnr = bus->number; | ||
| 58 | |||
| 59 | if (pci_slot_ignore & (1 << PCI_SLOT(devfn))) | ||
| 60 | return NULL; | ||
| 61 | |||
| 62 | return versatile_cfg_base[1] + ((busnr << 16) | (devfn << 8) | offset); | ||
| 63 | } | ||
| 64 | |||
| 65 | static struct pci_ops pci_versatile_ops = { | ||
| 66 | .map_bus = versatile_map_bus, | ||
| 67 | .read = pci_generic_config_read32, | ||
| 68 | .write = pci_generic_config_write, | ||
| 69 | }; | ||
| 70 | |||
| 71 | static int versatile_pci_parse_request_of_pci_ranges(struct device *dev, | ||
| 72 | struct list_head *res) | ||
| 73 | { | ||
| 74 | int err, mem = 1, res_valid = 0; | ||
| 75 | struct device_node *np = dev->of_node; | ||
| 76 | resource_size_t iobase; | ||
| 77 | struct pci_host_bridge_window *win; | ||
| 78 | |||
| 79 | err = of_pci_get_host_bridge_resources(np, 0, 0xff, res, &iobase); | ||
| 80 | if (err) | ||
| 81 | return err; | ||
| 82 | |||
| 83 | list_for_each_entry(win, res, list) { | ||
| 84 | struct resource *parent, *res = win->res; | ||
| 85 | |||
| 86 | switch (resource_type(res)) { | ||
| 87 | case IORESOURCE_IO: | ||
| 88 | parent = &ioport_resource; | ||
| 89 | err = pci_remap_iospace(res, iobase); | ||
| 90 | if (err) { | ||
| 91 | dev_warn(dev, "error %d: failed to map resource %pR\n", | ||
| 92 | err, res); | ||
| 93 | continue; | ||
| 94 | } | ||
| 95 | break; | ||
| 96 | case IORESOURCE_MEM: | ||
| 97 | parent = &iomem_resource; | ||
| 98 | res_valid |= !(res->flags & IORESOURCE_PREFETCH); | ||
| 99 | |||
| 100 | writel(res->start >> 28, PCI_IMAP(mem)); | ||
| 101 | writel(PHYS_OFFSET >> 28, PCI_SMAP(mem)); | ||
| 102 | mem++; | ||
| 103 | |||
| 104 | break; | ||
| 105 | case IORESOURCE_BUS: | ||
| 106 | default: | ||
| 107 | continue; | ||
| 108 | } | ||
| 109 | |||
| 110 | err = devm_request_resource(dev, parent, res); | ||
| 111 | if (err) | ||
| 112 | goto out_release_res; | ||
| 113 | } | ||
| 114 | |||
| 115 | if (!res_valid) { | ||
| 116 | dev_err(dev, "non-prefetchable memory resource required\n"); | ||
| 117 | err = -EINVAL; | ||
| 118 | goto out_release_res; | ||
| 119 | } | ||
| 120 | |||
| 121 | return 0; | ||
| 122 | |||
| 123 | out_release_res: | ||
| 124 | pci_free_resource_list(res); | ||
| 125 | return err; | ||
| 126 | } | ||
| 127 | |||
| 128 | /* Unused, temporary to satisfy ARM arch code */ | ||
| 129 | struct pci_sys_data sys; | ||
| 130 | |||
| 131 | static int versatile_pci_probe(struct platform_device *pdev) | ||
| 132 | { | ||
| 133 | struct resource *res; | ||
| 134 | int ret, i, myslot = -1; | ||
| 135 | u32 val; | ||
| 136 | void __iomem *local_pci_cfg_base; | ||
| 137 | struct pci_bus *bus; | ||
| 138 | LIST_HEAD(pci_res); | ||
| 139 | |||
| 140 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 141 | if (!res) | ||
| 142 | return -ENODEV; | ||
| 143 | versatile_pci_base = devm_ioremap_resource(&pdev->dev, res); | ||
| 144 | |||
| 145 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
| 146 | if (!res) | ||
| 147 | return -ENODEV; | ||
| 148 | versatile_cfg_base[0] = devm_ioremap_resource(&pdev->dev, res); | ||
| 149 | |||
| 150 | res = platform_get_resource(pdev, IORESOURCE_MEM, 2); | ||
| 151 | if (!res) | ||
| 152 | return -ENODEV; | ||
| 153 | versatile_cfg_base[1] = devm_ioremap_resource(&pdev->dev, res); | ||
| 154 | |||
| 155 | ret = versatile_pci_parse_request_of_pci_ranges(&pdev->dev, &pci_res); | ||
| 156 | if (ret) | ||
| 157 | return ret; | ||
| 158 | |||
| 159 | /* | ||
| 160 | * We need to discover the PCI core first to configure itself | ||
| 161 | * before the main PCI probing is performed | ||
| 162 | */ | ||
| 163 | for (i = 0; i < 32; i++) { | ||
| 164 | if ((readl(versatile_cfg_base[0] + (i << 11) + PCI_VENDOR_ID) == VP_PCI_DEVICE_ID) && | ||
| 165 | (readl(versatile_cfg_base[0] + (i << 11) + PCI_CLASS_REVISION) == VP_PCI_CLASS_ID)) { | ||
| 166 | myslot = i; | ||
| 167 | break; | ||
| 168 | } | ||
| 169 | } | ||
| 170 | if (myslot == -1) { | ||
| 171 | dev_err(&pdev->dev, "Cannot find PCI core!\n"); | ||
| 172 | return -EIO; | ||
| 173 | } | ||
| 174 | /* | ||
| 175 | * Do not to map Versatile FPGA PCI device into memory space | ||
| 176 | */ | ||
| 177 | pci_slot_ignore |= (1 << myslot); | ||
| 178 | |||
| 179 | dev_info(&pdev->dev, "PCI core found (slot %d)\n", myslot); | ||
| 180 | |||
| 181 | writel(myslot, PCI_SELFID); | ||
| 182 | local_pci_cfg_base = versatile_cfg_base[1] + (myslot << 11); | ||
| 183 | |||
| 184 | val = readl(local_pci_cfg_base + PCI_COMMAND); | ||
| 185 | val |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE; | ||
| 186 | writel(val, local_pci_cfg_base + PCI_COMMAND); | ||
| 187 | |||
| 188 | /* | ||
| 189 | * Configure the PCI inbound memory windows to be 1:1 mapped to SDRAM | ||
| 190 | */ | ||
| 191 | writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_0); | ||
| 192 | writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_1); | ||
| 193 | writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_2); | ||
| 194 | |||
| 195 | /* | ||
| 196 | * For many years the kernel and QEMU were symbiotically buggy | ||
| 197 | * in that they both assumed the same broken IRQ mapping. | ||
| 198 | * QEMU therefore attempts to auto-detect old broken kernels | ||
| 199 | * so that they still work on newer QEMU as they did on old | ||
| 200 | * QEMU. Since we now use the correct (ie matching-hardware) | ||
| 201 | * IRQ mapping we write a definitely different value to a | ||
| 202 | * PCI_INTERRUPT_LINE register to tell QEMU that we expect | ||
| 203 | * real hardware behaviour and it need not be backwards | ||
| 204 | * compatible for us. This write is harmless on real hardware. | ||
| 205 | */ | ||
| 206 | writel(0, versatile_cfg_base[0] + PCI_INTERRUPT_LINE); | ||
| 207 | |||
| 208 | pci_add_flags(PCI_ENABLE_PROC_DOMAINS); | ||
| 209 | pci_add_flags(PCI_REASSIGN_ALL_BUS | PCI_REASSIGN_ALL_RSRC); | ||
| 210 | |||
| 211 | bus = pci_scan_root_bus(&pdev->dev, 0, &pci_versatile_ops, &sys, &pci_res); | ||
| 212 | if (!bus) | ||
| 213 | return -ENOMEM; | ||
| 214 | |||
| 215 | pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci); | ||
| 216 | pci_assign_unassigned_bus_resources(bus); | ||
| 217 | |||
| 218 | return 0; | ||
| 219 | } | ||
| 220 | |||
| 221 | static const struct of_device_id versatile_pci_of_match[] = { | ||
| 222 | { .compatible = "arm,versatile-pci", }, | ||
| 223 | { }, | ||
| 224 | }; | ||
| 225 | MODULE_DEVICE_TABLE(of, versatile_pci_of_match); | ||
| 226 | |||
| 227 | static struct platform_driver versatile_pci_driver = { | ||
| 228 | .driver = { | ||
| 229 | .name = "versatile-pci", | ||
| 230 | .of_match_table = versatile_pci_of_match, | ||
| 231 | }, | ||
| 232 | .probe = versatile_pci_probe, | ||
| 233 | }; | ||
| 234 | module_platform_driver(versatile_pci_driver); | ||
| 235 | |||
| 236 | MODULE_DESCRIPTION("Versatile PCI driver"); | ||
| 237 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c index b1d0596457c5..e77d831dc241 100644 --- a/drivers/pci/host/pci-xgene.c +++ b/drivers/pci/host/pci-xgene.c | |||
| @@ -16,7 +16,7 @@ | |||
| 16 | * GNU General Public License for more details. | 16 | * GNU General Public License for more details. |
| 17 | * | 17 | * |
| 18 | */ | 18 | */ |
| 19 | #include <linux/clk-private.h> | 19 | #include <linux/clk.h> |
| 20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
| 21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
| 22 | #include <linux/jiffies.h> | 22 | #include <linux/jiffies.h> |
| @@ -74,92 +74,6 @@ static inline u32 pcie_bar_low_val(u32 addr, u32 flags) | |||
| 74 | return (addr & PCI_BASE_ADDRESS_MEM_MASK) | flags; | 74 | return (addr & PCI_BASE_ADDRESS_MEM_MASK) | flags; |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | /* PCIe Configuration Out/In */ | ||
| 78 | static inline void xgene_pcie_cfg_out32(void __iomem *addr, int offset, u32 val) | ||
| 79 | { | ||
| 80 | writel(val, addr + offset); | ||
| 81 | } | ||
| 82 | |||
| 83 | static inline void xgene_pcie_cfg_out16(void __iomem *addr, int offset, u16 val) | ||
| 84 | { | ||
| 85 | u32 val32 = readl(addr + (offset & ~0x3)); | ||
| 86 | |||
| 87 | switch (offset & 0x3) { | ||
| 88 | case 2: | ||
| 89 | val32 &= ~0xFFFF0000; | ||
| 90 | val32 |= (u32)val << 16; | ||
| 91 | break; | ||
| 92 | case 0: | ||
| 93 | default: | ||
| 94 | val32 &= ~0xFFFF; | ||
| 95 | val32 |= val; | ||
| 96 | break; | ||
| 97 | } | ||
| 98 | writel(val32, addr + (offset & ~0x3)); | ||
| 99 | } | ||
| 100 | |||
| 101 | static inline void xgene_pcie_cfg_out8(void __iomem *addr, int offset, u8 val) | ||
| 102 | { | ||
| 103 | u32 val32 = readl(addr + (offset & ~0x3)); | ||
| 104 | |||
| 105 | switch (offset & 0x3) { | ||
| 106 | case 0: | ||
| 107 | val32 &= ~0xFF; | ||
| 108 | val32 |= val; | ||
| 109 | break; | ||
| 110 | case 1: | ||
| 111 | val32 &= ~0xFF00; | ||
| 112 | val32 |= (u32)val << 8; | ||
| 113 | break; | ||
| 114 | case 2: | ||
| 115 | val32 &= ~0xFF0000; | ||
| 116 | val32 |= (u32)val << 16; | ||
| 117 | break; | ||
| 118 | case 3: | ||
| 119 | default: | ||
| 120 | val32 &= ~0xFF000000; | ||
| 121 | val32 |= (u32)val << 24; | ||
| 122 | break; | ||
| 123 | } | ||
| 124 | writel(val32, addr + (offset & ~0x3)); | ||
| 125 | } | ||
| 126 | |||
| 127 | static inline void xgene_pcie_cfg_in32(void __iomem *addr, int offset, u32 *val) | ||
| 128 | { | ||
| 129 | *val = readl(addr + offset); | ||
| 130 | } | ||
| 131 | |||
| 132 | static inline void xgene_pcie_cfg_in16(void __iomem *addr, int offset, u32 *val) | ||
| 133 | { | ||
| 134 | *val = readl(addr + (offset & ~0x3)); | ||
| 135 | |||
| 136 | switch (offset & 0x3) { | ||
| 137 | case 2: | ||
| 138 | *val >>= 16; | ||
| 139 | break; | ||
| 140 | } | ||
| 141 | |||
| 142 | *val &= 0xFFFF; | ||
| 143 | } | ||
| 144 | |||
| 145 | static inline void xgene_pcie_cfg_in8(void __iomem *addr, int offset, u32 *val) | ||
| 146 | { | ||
| 147 | *val = readl(addr + (offset & ~0x3)); | ||
| 148 | |||
| 149 | switch (offset & 0x3) { | ||
| 150 | case 3: | ||
| 151 | *val = *val >> 24; | ||
| 152 | break; | ||
| 153 | case 2: | ||
| 154 | *val = *val >> 16; | ||
| 155 | break; | ||
| 156 | case 1: | ||
| 157 | *val = *val >> 8; | ||
| 158 | break; | ||
| 159 | } | ||
| 160 | *val &= 0xFF; | ||
| 161 | } | ||
| 162 | |||
| 163 | /* | 77 | /* |
| 164 | * When the address bit [17:16] is 2'b01, the Configuration access will be | 78 | * When the address bit [17:16] is 2'b01, the Configuration access will be |
| 165 | * treated as Type 1 and it will be forwarded to external PCIe device. | 79 | * treated as Type 1 and it will be forwarded to external PCIe device. |
| @@ -213,69 +127,23 @@ static bool xgene_pcie_hide_rc_bars(struct pci_bus *bus, int offset) | |||
| 213 | return false; | 127 | return false; |
| 214 | } | 128 | } |
| 215 | 129 | ||
| 216 | static int xgene_pcie_read_config(struct pci_bus *bus, unsigned int devfn, | 130 | static int xgene_pcie_map_bus(struct pci_bus *bus, unsigned int devfn, |
| 217 | int offset, int len, u32 *val) | 131 | int offset) |
| 218 | { | ||
| 219 | struct xgene_pcie_port *port = bus->sysdata; | ||
| 220 | void __iomem *addr; | ||
| 221 | |||
| 222 | if ((pci_is_root_bus(bus) && devfn != 0) || !port->link_up) | ||
| 223 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 224 | |||
| 225 | if (xgene_pcie_hide_rc_bars(bus, offset)) { | ||
| 226 | *val = 0; | ||
| 227 | return PCIBIOS_SUCCESSFUL; | ||
| 228 | } | ||
| 229 | |||
| 230 | xgene_pcie_set_rtdid_reg(bus, devfn); | ||
| 231 | addr = xgene_pcie_get_cfg_base(bus); | ||
| 232 | switch (len) { | ||
| 233 | case 1: | ||
| 234 | xgene_pcie_cfg_in8(addr, offset, val); | ||
| 235 | break; | ||
| 236 | case 2: | ||
| 237 | xgene_pcie_cfg_in16(addr, offset, val); | ||
| 238 | break; | ||
| 239 | default: | ||
| 240 | xgene_pcie_cfg_in32(addr, offset, val); | ||
| 241 | break; | ||
| 242 | } | ||
| 243 | |||
| 244 | return PCIBIOS_SUCCESSFUL; | ||
| 245 | } | ||
| 246 | |||
| 247 | static int xgene_pcie_write_config(struct pci_bus *bus, unsigned int devfn, | ||
| 248 | int offset, int len, u32 val) | ||
| 249 | { | 132 | { |
| 250 | struct xgene_pcie_port *port = bus->sysdata; | 133 | struct xgene_pcie_port *port = bus->sysdata; |
| 251 | void __iomem *addr; | ||
| 252 | 134 | ||
| 253 | if ((pci_is_root_bus(bus) && devfn != 0) || !port->link_up) | 135 | if ((pci_is_root_bus(bus) && devfn != 0) || !port->link_up || |
| 254 | return PCIBIOS_DEVICE_NOT_FOUND; | 136 | xgene_pcie_hide_rc_bars(bus, offset)) |
| 255 | 137 | return NULL; | |
| 256 | if (xgene_pcie_hide_rc_bars(bus, offset)) | ||
| 257 | return PCIBIOS_SUCCESSFUL; | ||
| 258 | 138 | ||
| 259 | xgene_pcie_set_rtdid_reg(bus, devfn); | 139 | xgene_pcie_set_rtdid_reg(bus, devfn); |
| 260 | addr = xgene_pcie_get_cfg_base(bus); | 140 | return xgene_pcie_get_cfg_base(bus); |
| 261 | switch (len) { | ||
| 262 | case 1: | ||
| 263 | xgene_pcie_cfg_out8(addr, offset, (u8)val); | ||
| 264 | break; | ||
| 265 | case 2: | ||
| 266 | xgene_pcie_cfg_out16(addr, offset, (u16)val); | ||
| 267 | break; | ||
| 268 | default: | ||
| 269 | xgene_pcie_cfg_out32(addr, offset, val); | ||
| 270 | break; | ||
| 271 | } | ||
| 272 | |||
| 273 | return PCIBIOS_SUCCESSFUL; | ||
| 274 | } | 141 | } |
| 275 | 142 | ||
| 276 | static struct pci_ops xgene_pcie_ops = { | 143 | static struct pci_ops xgene_pcie_ops = { |
| 277 | .read = xgene_pcie_read_config, | 144 | .map_bus = xgene_pcie_map_bus, |
| 278 | .write = xgene_pcie_write_config | 145 | .read = pci_generic_config_read32, |
| 146 | .write = pci_generic_config_write32, | ||
| 279 | }; | 147 | }; |
| 280 | 148 | ||
| 281 | static u64 xgene_pcie_set_ib_mask(void __iomem *csr_base, u32 addr, | 149 | static u64 xgene_pcie_set_ib_mask(void __iomem *csr_base, u32 addr, |
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index 17ca98657a28..1f4ea6f2d910 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c | |||
| @@ -511,9 +511,6 @@ int __init dw_pcie_host_init(struct pcie_port *pp) | |||
| 511 | dw_pci.private_data = (void **)&pp; | 511 | dw_pci.private_data = (void **)&pp; |
| 512 | 512 | ||
| 513 | pci_common_init_dev(pp->dev, &dw_pci); | 513 | pci_common_init_dev(pp->dev, &dw_pci); |
| 514 | #ifdef CONFIG_PCI_DOMAINS | ||
| 515 | dw_pci.domain++; | ||
| 516 | #endif | ||
| 517 | 514 | ||
| 518 | return 0; | 515 | return 0; |
| 519 | } | 516 | } |
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c index 748786c402fc..c57bd0ac39a0 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c | |||
| @@ -397,9 +397,6 @@ static void rcar_pcie_enable(struct rcar_pcie *pcie) | |||
| 397 | #endif | 397 | #endif |
| 398 | 398 | ||
| 399 | pci_common_init_dev(&pdev->dev, &rcar_pci); | 399 | pci_common_init_dev(&pdev->dev, &rcar_pci); |
| 400 | #ifdef CONFIG_PCI_DOMAINS | ||
| 401 | rcar_pci.domain++; | ||
| 402 | #endif | ||
| 403 | } | 400 | } |
| 404 | 401 | ||
| 405 | static int phy_wait_for_ack(struct rcar_pcie *pcie) | 402 | static int phy_wait_for_ack(struct rcar_pcie *pcie) |
| @@ -757,7 +754,7 @@ static int rcar_pcie_get_resources(struct platform_device *pdev, | |||
| 757 | goto err_map_reg; | 754 | goto err_map_reg; |
| 758 | 755 | ||
| 759 | i = irq_of_parse_and_map(pdev->dev.of_node, 0); | 756 | i = irq_of_parse_and_map(pdev->dev.of_node, 0); |
| 760 | if (i < 0) { | 757 | if (!i) { |
| 761 | dev_err(pcie->dev, "cannot get platform resources for msi interrupt\n"); | 758 | dev_err(pcie->dev, "cannot get platform resources for msi interrupt\n"); |
| 762 | err = -ENOENT; | 759 | err = -ENOENT; |
| 763 | goto err_map_reg; | 760 | goto err_map_reg; |
| @@ -765,7 +762,7 @@ static int rcar_pcie_get_resources(struct platform_device *pdev, | |||
| 765 | pcie->msi.irq1 = i; | 762 | pcie->msi.irq1 = i; |
| 766 | 763 | ||
| 767 | i = irq_of_parse_and_map(pdev->dev.of_node, 1); | 764 | i = irq_of_parse_and_map(pdev->dev.of_node, 1); |
| 768 | if (i < 0) { | 765 | if (!i) { |
| 769 | dev_err(pcie->dev, "cannot get platform resources for msi interrupt\n"); | 766 | dev_err(pcie->dev, "cannot get platform resources for msi interrupt\n"); |
| 770 | err = -ENOENT; | 767 | err = -ENOENT; |
| 771 | goto err_map_reg; | 768 | goto err_map_reg; |
diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c index ef3ebaf9a738..eac4a4b957ca 100644 --- a/drivers/pci/host/pcie-xilinx.c +++ b/drivers/pci/host/pcie-xilinx.c | |||
| @@ -148,10 +148,10 @@ static inline bool xilinx_pcie_link_is_up(struct xilinx_pcie_port *port) | |||
| 148 | */ | 148 | */ |
| 149 | static void xilinx_pcie_clear_err_interrupts(struct xilinx_pcie_port *port) | 149 | static void xilinx_pcie_clear_err_interrupts(struct xilinx_pcie_port *port) |
| 150 | { | 150 | { |
| 151 | u32 val = pcie_read(port, XILINX_PCIE_REG_RPEFR); | 151 | unsigned long val = pcie_read(port, XILINX_PCIE_REG_RPEFR); |
| 152 | 152 | ||
| 153 | if (val & XILINX_PCIE_RPEFR_ERR_VALID) { | 153 | if (val & XILINX_PCIE_RPEFR_ERR_VALID) { |
| 154 | dev_dbg(port->dev, "Requester ID %d\n", | 154 | dev_dbg(port->dev, "Requester ID %lu\n", |
| 155 | val & XILINX_PCIE_RPEFR_REQ_ID); | 155 | val & XILINX_PCIE_RPEFR_REQ_ID); |
| 156 | pcie_write(port, XILINX_PCIE_RPEFR_ALL_MASK, | 156 | pcie_write(port, XILINX_PCIE_RPEFR_ALL_MASK, |
| 157 | XILINX_PCIE_REG_RPEFR); | 157 | XILINX_PCIE_REG_RPEFR); |
| @@ -189,7 +189,7 @@ static bool xilinx_pcie_valid_device(struct pci_bus *bus, unsigned int devfn) | |||
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | /** | 191 | /** |
| 192 | * xilinx_pcie_config_base - Get configuration base | 192 | * xilinx_pcie_map_bus - Get configuration base |
| 193 | * @bus: PCI Bus structure | 193 | * @bus: PCI Bus structure |
| 194 | * @devfn: Device/function | 194 | * @devfn: Device/function |
| 195 | * @where: Offset from base | 195 | * @where: Offset from base |
| @@ -197,96 +197,26 @@ static bool xilinx_pcie_valid_device(struct pci_bus *bus, unsigned int devfn) | |||
| 197 | * Return: Base address of the configuration space needed to be | 197 | * Return: Base address of the configuration space needed to be |
| 198 | * accessed. | 198 | * accessed. |
| 199 | */ | 199 | */ |
| 200 | static void __iomem *xilinx_pcie_config_base(struct pci_bus *bus, | 200 | static void __iomem *xilinx_pcie_map_bus(struct pci_bus *bus, |
| 201 | unsigned int devfn, int where) | 201 | unsigned int devfn, int where) |
| 202 | { | 202 | { |
| 203 | struct xilinx_pcie_port *port = sys_to_pcie(bus->sysdata); | 203 | struct xilinx_pcie_port *port = sys_to_pcie(bus->sysdata); |
| 204 | int relbus; | 204 | int relbus; |
| 205 | 205 | ||
| 206 | if (!xilinx_pcie_valid_device(bus, devfn)) | ||
| 207 | return NULL; | ||
| 208 | |||
| 206 | relbus = (bus->number << ECAM_BUS_NUM_SHIFT) | | 209 | relbus = (bus->number << ECAM_BUS_NUM_SHIFT) | |
| 207 | (devfn << ECAM_DEV_NUM_SHIFT); | 210 | (devfn << ECAM_DEV_NUM_SHIFT); |
| 208 | 211 | ||
| 209 | return port->reg_base + relbus + where; | 212 | return port->reg_base + relbus + where; |
| 210 | } | 213 | } |
| 211 | 214 | ||
| 212 | /** | ||
| 213 | * xilinx_pcie_read_config - Read configuration space | ||
| 214 | * @bus: PCI Bus structure | ||
| 215 | * @devfn: Device/function | ||
| 216 | * @where: Offset from base | ||
| 217 | * @size: Byte/word/dword | ||
| 218 | * @val: Value to be read | ||
| 219 | * | ||
| 220 | * Return: PCIBIOS_SUCCESSFUL on success | ||
| 221 | * PCIBIOS_DEVICE_NOT_FOUND on failure | ||
| 222 | */ | ||
| 223 | static int xilinx_pcie_read_config(struct pci_bus *bus, unsigned int devfn, | ||
| 224 | int where, int size, u32 *val) | ||
| 225 | { | ||
| 226 | void __iomem *addr; | ||
| 227 | |||
| 228 | if (!xilinx_pcie_valid_device(bus, devfn)) { | ||
| 229 | *val = 0xFFFFFFFF; | ||
| 230 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 231 | } | ||
| 232 | |||
| 233 | addr = xilinx_pcie_config_base(bus, devfn, where); | ||
| 234 | |||
| 235 | switch (size) { | ||
| 236 | case 1: | ||
| 237 | *val = readb(addr); | ||
| 238 | break; | ||
| 239 | case 2: | ||
| 240 | *val = readw(addr); | ||
| 241 | break; | ||
| 242 | default: | ||
| 243 | *val = readl(addr); | ||
| 244 | break; | ||
| 245 | } | ||
| 246 | |||
| 247 | return PCIBIOS_SUCCESSFUL; | ||
| 248 | } | ||
| 249 | |||
| 250 | /** | ||
| 251 | * xilinx_pcie_write_config - Write configuration space | ||
| 252 | * @bus: PCI Bus structure | ||
| 253 | * @devfn: Device/function | ||
| 254 | * @where: Offset from base | ||
| 255 | * @size: Byte/word/dword | ||
| 256 | * @val: Value to be written to device | ||
| 257 | * | ||
| 258 | * Return: PCIBIOS_SUCCESSFUL on success | ||
| 259 | * PCIBIOS_DEVICE_NOT_FOUND on failure | ||
| 260 | */ | ||
| 261 | static int xilinx_pcie_write_config(struct pci_bus *bus, unsigned int devfn, | ||
| 262 | int where, int size, u32 val) | ||
| 263 | { | ||
| 264 | void __iomem *addr; | ||
| 265 | |||
| 266 | if (!xilinx_pcie_valid_device(bus, devfn)) | ||
| 267 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 268 | |||
| 269 | addr = xilinx_pcie_config_base(bus, devfn, where); | ||
| 270 | |||
| 271 | switch (size) { | ||
| 272 | case 1: | ||
| 273 | writeb(val, addr); | ||
| 274 | break; | ||
| 275 | case 2: | ||
| 276 | writew(val, addr); | ||
| 277 | break; | ||
| 278 | default: | ||
| 279 | writel(val, addr); | ||
| 280 | break; | ||
| 281 | } | ||
| 282 | |||
| 283 | return PCIBIOS_SUCCESSFUL; | ||
| 284 | } | ||
| 285 | |||
| 286 | /* PCIe operations */ | 215 | /* PCIe operations */ |
| 287 | static struct pci_ops xilinx_pcie_ops = { | 216 | static struct pci_ops xilinx_pcie_ops = { |
| 288 | .read = xilinx_pcie_read_config, | 217 | .map_bus = xilinx_pcie_map_bus, |
| 289 | .write = xilinx_pcie_write_config, | 218 | .read = pci_generic_config_read, |
| 219 | .write = pci_generic_config_write, | ||
| 290 | }; | 220 | }; |
| 291 | 221 | ||
| 292 | /* MSI functions */ | 222 | /* MSI functions */ |
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index a5a7fd8332ac..46db29395a62 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c | |||
| @@ -214,8 +214,7 @@ static void release_slot(struct hotplug_slot *hotplug_slot) | |||
| 214 | 214 | ||
| 215 | kfree(slot->hotplug_slot->info); | 215 | kfree(slot->hotplug_slot->info); |
| 216 | kfree(slot->hotplug_slot); | 216 | kfree(slot->hotplug_slot); |
| 217 | if (slot->dev) | 217 | pci_dev_put(slot->dev); |
| 218 | pci_dev_put(slot->dev); | ||
| 219 | kfree(slot); | 218 | kfree(slot); |
| 220 | } | 219 | } |
| 221 | 220 | ||
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index ff32e85e1de6..f052e951b23e 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
| @@ -532,8 +532,6 @@ static void interrupt_event_handler(struct work_struct *work) | |||
| 532 | pciehp_green_led_off(p_slot); | 532 | pciehp_green_led_off(p_slot); |
| 533 | break; | 533 | break; |
| 534 | case INT_PRESENCE_ON: | 534 | case INT_PRESENCE_ON: |
| 535 | if (!HP_SUPR_RM(ctrl)) | ||
| 536 | break; | ||
| 537 | ctrl_dbg(ctrl, "Surprise Insertion\n"); | 535 | ctrl_dbg(ctrl, "Surprise Insertion\n"); |
| 538 | handle_surprise_event(p_slot); | 536 | handle_surprise_event(p_slot); |
| 539 | break; | 537 | break; |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index fd60806d3fd0..c3e7dfcf9ff5 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
| @@ -694,11 +694,16 @@ static void __iomem *msix_map_region(struct pci_dev *dev, unsigned nr_entries) | |||
| 694 | { | 694 | { |
| 695 | resource_size_t phys_addr; | 695 | resource_size_t phys_addr; |
| 696 | u32 table_offset; | 696 | u32 table_offset; |
| 697 | unsigned long flags; | ||
| 697 | u8 bir; | 698 | u8 bir; |
| 698 | 699 | ||
| 699 | pci_read_config_dword(dev, dev->msix_cap + PCI_MSIX_TABLE, | 700 | pci_read_config_dword(dev, dev->msix_cap + PCI_MSIX_TABLE, |
| 700 | &table_offset); | 701 | &table_offset); |
| 701 | bir = (u8)(table_offset & PCI_MSIX_TABLE_BIR); | 702 | bir = (u8)(table_offset & PCI_MSIX_TABLE_BIR); |
| 703 | flags = pci_resource_flags(dev, bir); | ||
| 704 | if (!flags || (flags & IORESOURCE_UNSET)) | ||
| 705 | return NULL; | ||
| 706 | |||
| 702 | table_offset &= PCI_MSIX_TABLE_OFFSET; | 707 | table_offset &= PCI_MSIX_TABLE_OFFSET; |
| 703 | phys_addr = pci_resource_start(dev, bir) + table_offset; | 708 | phys_addr = pci_resource_start(dev, bir) + table_offset; |
| 704 | 709 | ||
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 887e6bd95af7..09a66bad8018 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
| @@ -1383,7 +1383,7 @@ static int pci_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
| 1383 | if (add_uevent_var(env, "PCI_SLOT_NAME=%s", pci_name(pdev))) | 1383 | if (add_uevent_var(env, "PCI_SLOT_NAME=%s", pci_name(pdev))) |
| 1384 | return -ENOMEM; | 1384 | return -ENOMEM; |
| 1385 | 1385 | ||
| 1386 | if (add_uevent_var(env, "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x", | 1386 | if (add_uevent_var(env, "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02X", |
| 1387 | pdev->vendor, pdev->device, | 1387 | pdev->vendor, pdev->device, |
| 1388 | pdev->subsystem_vendor, pdev->subsystem_device, | 1388 | pdev->subsystem_vendor, pdev->subsystem_device, |
| 1389 | (u8)(pdev->class >> 16), (u8)(pdev->class >> 8), | 1389 | (u8)(pdev->class >> 16), (u8)(pdev->class >> 8), |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e9d4fd861ba1..460d046ab6fe 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -10,6 +10,8 @@ | |||
| 10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
| 11 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
| 12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
| 13 | #include <linux/of.h> | ||
| 14 | #include <linux/of_pci.h> | ||
| 13 | #include <linux/pci.h> | 15 | #include <linux/pci.h> |
| 14 | #include <linux/pm.h> | 16 | #include <linux/pm.h> |
| 15 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
| @@ -3197,7 +3199,7 @@ static int pci_pm_reset(struct pci_dev *dev, int probe) | |||
| 3197 | { | 3199 | { |
| 3198 | u16 csr; | 3200 | u16 csr; |
| 3199 | 3201 | ||
| 3200 | if (!dev->pm_cap) | 3202 | if (!dev->pm_cap || dev->dev_flags & PCI_DEV_FLAGS_NO_PM_RESET) |
| 3201 | return -ENOTTY; | 3203 | return -ENOTTY; |
| 3202 | 3204 | ||
| 3203 | pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &csr); | 3205 | pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &csr); |
| @@ -4471,6 +4473,53 @@ int pci_get_new_domain_nr(void) | |||
| 4471 | { | 4473 | { |
| 4472 | return atomic_inc_return(&__domain_nr); | 4474 | return atomic_inc_return(&__domain_nr); |
| 4473 | } | 4475 | } |
| 4476 | |||
| 4477 | #ifdef CONFIG_PCI_DOMAINS_GENERIC | ||
| 4478 | void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent) | ||
| 4479 | { | ||
| 4480 | static int use_dt_domains = -1; | ||
| 4481 | int domain = of_get_pci_domain_nr(parent->of_node); | ||
| 4482 | |||
| 4483 | /* | ||
| 4484 | * Check DT domain and use_dt_domains values. | ||
| 4485 | * | ||
| 4486 | * If DT domain property is valid (domain >= 0) and | ||
| 4487 | * use_dt_domains != 0, the DT assignment is valid since this means | ||
| 4488 | * we have not previously allocated a domain number by using | ||
| 4489 | * pci_get_new_domain_nr(); we should also update use_dt_domains to | ||
| 4490 | * 1, to indicate that we have just assigned a domain number from | ||
| 4491 | * DT. | ||
| 4492 | * | ||
| 4493 | * If DT domain property value is not valid (ie domain < 0), and we | ||
| 4494 | * have not previously assigned a domain number from DT | ||
| 4495 | * (use_dt_domains != 1) we should assign a domain number by | ||
| 4496 | * using the: | ||
| 4497 | * | ||
| 4498 | * pci_get_new_domain_nr() | ||
| 4499 | * | ||
| 4500 | * API and update the use_dt_domains value to keep track of method we | ||
| 4501 | * are using to assign domain numbers (use_dt_domains = 0). | ||
| 4502 | * | ||
| 4503 | * All other combinations imply we have a platform that is trying | ||
| 4504 | * to mix domain numbers obtained from DT and pci_get_new_domain_nr(), | ||
| 4505 | * which is a recipe for domain mishandling and it is prevented by | ||
| 4506 | * invalidating the domain value (domain = -1) and printing a | ||
| 4507 | * corresponding error. | ||
| 4508 | */ | ||
| 4509 | if (domain >= 0 && use_dt_domains) { | ||
| 4510 | use_dt_domains = 1; | ||
| 4511 | } else if (domain < 0 && use_dt_domains != 1) { | ||
| 4512 | use_dt_domains = 0; | ||
| 4513 | domain = pci_get_new_domain_nr(); | ||
| 4514 | } else { | ||
| 4515 | dev_err(parent, "Node %s has inconsistent \"linux,pci-domain\" property in DT\n", | ||
| 4516 | parent->of_node->full_name); | ||
| 4517 | domain = -1; | ||
| 4518 | } | ||
| 4519 | |||
| 4520 | bus->domain_nr = domain; | ||
| 4521 | } | ||
| 4522 | #endif | ||
| 4474 | #endif | 4523 | #endif |
| 4475 | 4524 | ||
| 4476 | /** | 4525 | /** |
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index e1e7026b838d..820740a22e94 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
| @@ -859,7 +859,10 @@ static ssize_t link_state_store(struct device *dev, | |||
| 859 | { | 859 | { |
| 860 | struct pci_dev *pdev = to_pci_dev(dev); | 860 | struct pci_dev *pdev = to_pci_dev(dev); |
| 861 | struct pcie_link_state *link, *root = pdev->link_state->root; | 861 | struct pcie_link_state *link, *root = pdev->link_state->root; |
| 862 | u32 val = buf[0] - '0', state = 0; | 862 | u32 val, state = 0; |
| 863 | |||
| 864 | if (kstrtouint(buf, 10, &val)) | ||
| 865 | return -EINVAL; | ||
| 863 | 866 | ||
| 864 | if (aspm_disabled) | 867 | if (aspm_disabled) |
| 865 | return -EPERM; | 868 | return -EPERM; |
| @@ -900,15 +903,14 @@ static ssize_t clk_ctl_store(struct device *dev, | |||
| 900 | size_t n) | 903 | size_t n) |
| 901 | { | 904 | { |
| 902 | struct pci_dev *pdev = to_pci_dev(dev); | 905 | struct pci_dev *pdev = to_pci_dev(dev); |
| 903 | int state; | 906 | bool state; |
| 904 | 907 | ||
| 905 | if (n < 1) | 908 | if (strtobool(buf, &state)) |
| 906 | return -EINVAL; | 909 | return -EINVAL; |
| 907 | state = buf[0]-'0'; | ||
| 908 | 910 | ||
| 909 | down_read(&pci_bus_sem); | 911 | down_read(&pci_bus_sem); |
| 910 | mutex_lock(&aspm_lock); | 912 | mutex_lock(&aspm_lock); |
| 911 | pcie_set_clkpm_nocheck(pdev->link_state, !!state); | 913 | pcie_set_clkpm_nocheck(pdev->link_state, state); |
| 912 | mutex_unlock(&aspm_lock); | 914 | mutex_unlock(&aspm_lock); |
| 913 | up_read(&pci_bus_sem); | 915 | up_read(&pci_bus_sem); |
| 914 | 916 | ||
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 903d5078b5ed..85f247e28a80 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
| @@ -3076,6 +3076,27 @@ static void quirk_no_bus_reset(struct pci_dev *dev) | |||
| 3076 | */ | 3076 | */ |
| 3077 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0030, quirk_no_bus_reset); | 3077 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0030, quirk_no_bus_reset); |
| 3078 | 3078 | ||
| 3079 | static void quirk_no_pm_reset(struct pci_dev *dev) | ||
| 3080 | { | ||
| 3081 | /* | ||
| 3082 | * We can't do a bus reset on root bus devices, but an ineffective | ||
| 3083 | * PM reset may be better than nothing. | ||
| 3084 | */ | ||
| 3085 | if (!pci_is_root_bus(dev->bus)) | ||
| 3086 | dev->dev_flags |= PCI_DEV_FLAGS_NO_PM_RESET; | ||
| 3087 | } | ||
| 3088 | |||
| 3089 | /* | ||
| 3090 | * Some AMD/ATI GPUS (HD8570 - Oland) report that a D3hot->D0 transition | ||
| 3091 | * causes a reset (i.e., they advertise NoSoftRst-). This transition seems | ||
| 3092 | * to have no effect on the device: it retains the framebuffer contents and | ||
| 3093 | * monitor sync. Advertising this support makes other layers, like VFIO, | ||
| 3094 | * assume pci_reset_function() is viable for this device. Mark it as | ||
| 3095 | * unavailable to skip it when testing reset methods. | ||
| 3096 | */ | ||
| 3097 | DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_ATI, PCI_ANY_ID, | ||
| 3098 | PCI_CLASS_DISPLAY_VGA, 8, quirk_no_pm_reset); | ||
| 3099 | |||
| 3079 | #ifdef CONFIG_ACPI | 3100 | #ifdef CONFIG_ACPI |
| 3080 | /* | 3101 | /* |
| 3081 | * Apple: Shutdown Cactus Ridge Thunderbolt controller. | 3102 | * Apple: Shutdown Cactus Ridge Thunderbolt controller. |
| @@ -3576,6 +3597,44 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_JMICRON, | |||
| 3576 | quirk_dma_func1_alias); | 3597 | quirk_dma_func1_alias); |
| 3577 | 3598 | ||
| 3578 | /* | 3599 | /* |
| 3600 | * Some devices DMA with the wrong devfn, not just the wrong function. | ||
| 3601 | * quirk_fixed_dma_alias() uses this table to create fixed aliases, where | ||
| 3602 | * the alias is "fixed" and independent of the device devfn. | ||
| 3603 | * | ||
| 3604 | * For example, the Adaptec 3405 is a PCIe card with an Intel 80333 I/O | ||
| 3605 | * processor. To software, this appears as a PCIe-to-PCI/X bridge with a | ||
| 3606 | * single device on the secondary bus. In reality, the single exposed | ||
| 3607 | * device at 0e.0 is the Address Translation Unit (ATU) of the controller | ||
| 3608 | * that provides a bridge to the internal bus of the I/O processor. The | ||
| 3609 | * controller supports private devices, which can be hidden from PCI config | ||
| 3610 | * space. In the case of the Adaptec 3405, a private device at 01.0 | ||
| 3611 | * appears to be the DMA engine, which therefore needs to become a DMA | ||
| 3612 | * alias for the device. | ||
| 3613 | */ | ||
| 3614 | static const struct pci_device_id fixed_dma_alias_tbl[] = { | ||
| 3615 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x0285, | ||
| 3616 | PCI_VENDOR_ID_ADAPTEC2, 0x02bb), /* Adaptec 3405 */ | ||
| 3617 | .driver_data = PCI_DEVFN(1, 0) }, | ||
| 3618 | { 0 } | ||
| 3619 | }; | ||
| 3620 | |||
| 3621 | static void quirk_fixed_dma_alias(struct pci_dev *dev) | ||
| 3622 | { | ||
| 3623 | const struct pci_device_id *id; | ||
| 3624 | |||
| 3625 | id = pci_match_id(fixed_dma_alias_tbl, dev); | ||
| 3626 | if (id) { | ||
| 3627 | dev->dma_alias_devfn = id->driver_data; | ||
| 3628 | dev->dev_flags |= PCI_DEV_FLAGS_DMA_ALIAS_DEVFN; | ||
| 3629 | dev_info(&dev->dev, "Enabling fixed DMA alias to %02x.%d\n", | ||
| 3630 | PCI_SLOT(dev->dma_alias_devfn), | ||
| 3631 | PCI_FUNC(dev->dma_alias_devfn)); | ||
| 3632 | } | ||
| 3633 | } | ||
| 3634 | |||
| 3635 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ADAPTEC2, 0x0285, quirk_fixed_dma_alias); | ||
| 3636 | |||
| 3637 | /* | ||
| 3579 | * A few PCIe-to-PCI bridges fail to expose a PCIe capability, resulting in | 3638 | * A few PCIe-to-PCI bridges fail to expose a PCIe capability, resulting in |
| 3580 | * using the wrong DMA alias for the device. Some of these devices can be | 3639 | * using the wrong DMA alias for the device. Some of these devices can be |
| 3581 | * used as either forward or reverse bridges, so we need to test whether the | 3640 | * used as either forward or reverse bridges, so we need to test whether the |
| @@ -3678,6 +3737,9 @@ static const u16 pci_quirk_intel_pch_acs_ids[] = { | |||
| 3678 | 0x9c98, 0x9c99, 0x9c9a, 0x9c9b, | 3737 | 0x9c98, 0x9c99, 0x9c9a, 0x9c9b, |
| 3679 | /* Patsburg (X79) PCH */ | 3738 | /* Patsburg (X79) PCH */ |
| 3680 | 0x1d10, 0x1d12, 0x1d14, 0x1d16, 0x1d18, 0x1d1a, 0x1d1c, 0x1d1e, | 3739 | 0x1d10, 0x1d12, 0x1d14, 0x1d16, 0x1d18, 0x1d1a, 0x1d1c, 0x1d1e, |
| 3740 | /* Wellsburg (X99) PCH */ | ||
| 3741 | 0x8d10, 0x8d11, 0x8d12, 0x8d13, 0x8d14, 0x8d15, 0x8d16, 0x8d17, | ||
| 3742 | 0x8d18, 0x8d19, 0x8d1a, 0x8d1b, 0x8d1c, 0x8d1d, 0x8d1e, | ||
| 3681 | }; | 3743 | }; |
| 3682 | 3744 | ||
| 3683 | static bool pci_quirk_intel_pch_acs_match(struct pci_dev *dev) | 3745 | static bool pci_quirk_intel_pch_acs_match(struct pci_dev *dev) |
| @@ -3761,6 +3823,8 @@ static const struct pci_dev_acs_enabled { | |||
| 3761 | { PCI_VENDOR_ID_INTEL, 0x1551, pci_quirk_mf_endpoint_acs }, | 3823 | { PCI_VENDOR_ID_INTEL, 0x1551, pci_quirk_mf_endpoint_acs }, |
| 3762 | { PCI_VENDOR_ID_INTEL, 0x1558, pci_quirk_mf_endpoint_acs }, | 3824 | { PCI_VENDOR_ID_INTEL, 0x1558, pci_quirk_mf_endpoint_acs }, |
| 3763 | { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs }, | 3825 | { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs }, |
| 3826 | { 0x19a2, 0x710, pci_quirk_mf_endpoint_acs }, /* Emulex BE3-R */ | ||
| 3827 | { 0x10df, 0x720, pci_quirk_mf_endpoint_acs }, /* Emulex Skyhawk-R */ | ||
| 3764 | { 0 } | 3828 | { 0 } |
| 3765 | }; | 3829 | }; |
| 3766 | 3830 | ||
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index f955edb9bea7..eb0ad530dc43 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c | |||
| @@ -71,6 +71,7 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size) | |||
| 71 | { | 71 | { |
| 72 | void __iomem *image; | 72 | void __iomem *image; |
| 73 | int last_image; | 73 | int last_image; |
| 74 | unsigned length; | ||
| 74 | 75 | ||
| 75 | image = rom; | 76 | image = rom; |
| 76 | do { | 77 | do { |
| @@ -93,9 +94,9 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size) | |||
| 93 | if (readb(pds + 3) != 'R') | 94 | if (readb(pds + 3) != 'R') |
| 94 | break; | 95 | break; |
| 95 | last_image = readb(pds + 21) & 0x80; | 96 | last_image = readb(pds + 21) & 0x80; |
| 96 | /* this length is reliable */ | 97 | length = readw(pds + 16); |
| 97 | image += readw(pds + 16) * 512; | 98 | image += length * 512; |
| 98 | } while (!last_image); | 99 | } while (length && !last_image); |
| 99 | 100 | ||
| 100 | /* never return a size larger than the PCI resource window */ | 101 | /* never return a size larger than the PCI resource window */ |
| 101 | /* there are known ROMs that get the size wrong */ | 102 | /* there are known ROMs that get the size wrong */ |
diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c index 8bcfecd66281..eeca70ddbf61 100644 --- a/drivers/rapidio/devices/tsi721.c +++ b/drivers/rapidio/devices/tsi721.c | |||
| @@ -2430,7 +2430,7 @@ static int tsi721_probe(struct pci_dev *pdev, | |||
| 2430 | pcie_capability_clear_and_set_word(pdev, PCI_EXP_DEVCTL, | 2430 | pcie_capability_clear_and_set_word(pdev, PCI_EXP_DEVCTL, |
| 2431 | PCI_EXP_DEVCTL_READRQ | PCI_EXP_DEVCTL_RELAX_EN | | 2431 | PCI_EXP_DEVCTL_READRQ | PCI_EXP_DEVCTL_RELAX_EN | |
| 2432 | PCI_EXP_DEVCTL_NOSNOOP_EN, | 2432 | PCI_EXP_DEVCTL_NOSNOOP_EN, |
| 2433 | 0x2 << MAX_READ_REQUEST_SZ_SHIFT); | 2433 | PCI_EXP_DEVCTL_READRQ_512B); |
| 2434 | 2434 | ||
| 2435 | /* Adjust PCIe completion timeout. */ | 2435 | /* Adjust PCIe completion timeout. */ |
| 2436 | pcie_capability_clear_and_set_word(pdev, PCI_EXP_DEVCTL2, 0xf, 0x2); | 2436 | pcie_capability_clear_and_set_word(pdev, PCI_EXP_DEVCTL2, 0xf, 0x2); |
diff --git a/drivers/rapidio/devices/tsi721.h b/drivers/rapidio/devices/tsi721.h index a7b42680a06a..9d2502543ef6 100644 --- a/drivers/rapidio/devices/tsi721.h +++ b/drivers/rapidio/devices/tsi721.h | |||
| @@ -72,8 +72,6 @@ | |||
| 72 | #define TSI721_MSIXPBA_OFFSET 0x2a000 | 72 | #define TSI721_MSIXPBA_OFFSET 0x2a000 |
| 73 | #define TSI721_PCIECFG_EPCTL 0x400 | 73 | #define TSI721_PCIECFG_EPCTL 0x400 |
| 74 | 74 | ||
| 75 | #define MAX_READ_REQUEST_SZ_SHIFT 12 | ||
| 76 | |||
| 77 | /* | 75 | /* |
| 78 | * Event Management Registers | 76 | * Event Management Registers |
| 79 | */ | 77 | */ |
diff --git a/drivers/scsi/esas2r/esas2r_init.c b/drivers/scsi/esas2r/esas2r_init.c index 6776931e25d4..78ce4d61a69b 100644 --- a/drivers/scsi/esas2r/esas2r_init.c +++ b/drivers/scsi/esas2r/esas2r_init.c | |||
| @@ -813,12 +813,13 @@ static void esas2r_init_pci_cfg_space(struct esas2r_adapter *a) | |||
| 813 | pci_read_config_word(a->pcid, pcie_cap_reg + PCI_EXP_DEVCTL, | 813 | pci_read_config_word(a->pcid, pcie_cap_reg + PCI_EXP_DEVCTL, |
| 814 | &devcontrol); | 814 | &devcontrol); |
| 815 | 815 | ||
| 816 | if ((devcontrol & PCI_EXP_DEVCTL_READRQ) > 0x2000) { | 816 | if ((devcontrol & PCI_EXP_DEVCTL_READRQ) > |
| 817 | PCI_EXP_DEVCTL_READRQ_512B) { | ||
| 817 | esas2r_log(ESAS2R_LOG_INFO, | 818 | esas2r_log(ESAS2R_LOG_INFO, |
| 818 | "max read request size > 512B"); | 819 | "max read request size > 512B"); |
| 819 | 820 | ||
| 820 | devcontrol &= ~PCI_EXP_DEVCTL_READRQ; | 821 | devcontrol &= ~PCI_EXP_DEVCTL_READRQ; |
| 821 | devcontrol |= 0x2000; | 822 | devcontrol |= PCI_EXP_DEVCTL_READRQ_512B; |
| 822 | pci_write_config_word(a->pcid, | 823 | pci_write_config_word(a->pcid, |
| 823 | pcie_cap_reg + PCI_EXP_DEVCTL, | 824 | pcie_cap_reg + PCI_EXP_DEVCTL, |
| 824 | devcontrol); | 825 | devcontrol); |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 9603094ed59b..421eb6a9e600 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
| @@ -177,6 +177,8 @@ enum pci_dev_flags { | |||
| 177 | PCI_DEV_FLAG_PCIE_BRIDGE_ALIAS = (__force pci_dev_flags_t) (1 << 5), | 177 | PCI_DEV_FLAG_PCIE_BRIDGE_ALIAS = (__force pci_dev_flags_t) (1 << 5), |
| 178 | /* Do not use bus resets for device */ | 178 | /* Do not use bus resets for device */ |
| 179 | PCI_DEV_FLAGS_NO_BUS_RESET = (__force pci_dev_flags_t) (1 << 6), | 179 | PCI_DEV_FLAGS_NO_BUS_RESET = (__force pci_dev_flags_t) (1 << 6), |
| 180 | /* Do not use PM reset even if device advertises NoSoftRst- */ | ||
| 181 | PCI_DEV_FLAGS_NO_PM_RESET = (__force pci_dev_flags_t) (1 << 7), | ||
| 180 | }; | 182 | }; |
| 181 | 183 | ||
| 182 | enum pci_irq_reroute_variant { | 184 | enum pci_irq_reroute_variant { |
| @@ -562,6 +564,7 @@ static inline int pcibios_err_to_errno(int err) | |||
| 562 | /* Low-level architecture-dependent routines */ | 564 | /* Low-level architecture-dependent routines */ |
| 563 | 565 | ||
| 564 | struct pci_ops { | 566 | struct pci_ops { |
| 567 | void __iomem *(*map_bus)(struct pci_bus *bus, unsigned int devfn, int where); | ||
| 565 | int (*read)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val); | 568 | int (*read)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val); |
| 566 | int (*write)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val); | 569 | int (*write)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val); |
| 567 | }; | 570 | }; |
| @@ -859,6 +862,16 @@ int pci_bus_write_config_word(struct pci_bus *bus, unsigned int devfn, | |||
| 859 | int where, u16 val); | 862 | int where, u16 val); |
| 860 | int pci_bus_write_config_dword(struct pci_bus *bus, unsigned int devfn, | 863 | int pci_bus_write_config_dword(struct pci_bus *bus, unsigned int devfn, |
| 861 | int where, u32 val); | 864 | int where, u32 val); |
| 865 | |||
| 866 | int pci_generic_config_read(struct pci_bus *bus, unsigned int devfn, | ||
| 867 | int where, int size, u32 *val); | ||
| 868 | int pci_generic_config_write(struct pci_bus *bus, unsigned int devfn, | ||
| 869 | int where, int size, u32 val); | ||
| 870 | int pci_generic_config_read32(struct pci_bus *bus, unsigned int devfn, | ||
| 871 | int where, int size, u32 *val); | ||
| 872 | int pci_generic_config_write32(struct pci_bus *bus, unsigned int devfn, | ||
| 873 | int where, int size, u32 val); | ||
| 874 | |||
| 862 | struct pci_ops *pci_bus_set_ops(struct pci_bus *bus, struct pci_ops *ops); | 875 | struct pci_ops *pci_bus_set_ops(struct pci_bus *bus, struct pci_ops *ops); |
| 863 | 876 | ||
| 864 | static inline int pci_read_config_byte(const struct pci_dev *dev, int where, u8 *val) | 877 | static inline int pci_read_config_byte(const struct pci_dev *dev, int where, u8 *val) |
| @@ -1850,6 +1863,8 @@ static inline void pci_set_of_node(struct pci_dev *dev) { } | |||
| 1850 | static inline void pci_release_of_node(struct pci_dev *dev) { } | 1863 | static inline void pci_release_of_node(struct pci_dev *dev) { } |
| 1851 | static inline void pci_set_bus_of_node(struct pci_bus *bus) { } | 1864 | static inline void pci_set_bus_of_node(struct pci_bus *bus) { } |
| 1852 | static inline void pci_release_bus_of_node(struct pci_bus *bus) { } | 1865 | static inline void pci_release_bus_of_node(struct pci_bus *bus) { } |
| 1866 | static inline struct device_node * | ||
| 1867 | pci_device_to_OF_node(const struct pci_dev *pdev) { return NULL; } | ||
| 1853 | #endif /* CONFIG_OF */ | 1868 | #endif /* CONFIG_OF */ |
| 1854 | 1869 | ||
| 1855 | #ifdef CONFIG_EEH | 1870 | #ifdef CONFIG_EEH |
diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index 4a1d0cc38ff2..efe3443572ba 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h | |||
| @@ -451,6 +451,10 @@ | |||
| 451 | #define PCI_EXP_DEVCTL_AUX_PME 0x0400 /* Auxiliary Power PM Enable */ | 451 | #define PCI_EXP_DEVCTL_AUX_PME 0x0400 /* Auxiliary Power PM Enable */ |
| 452 | #define PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800 /* Enable No Snoop */ | 452 | #define PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800 /* Enable No Snoop */ |
| 453 | #define PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */ | 453 | #define PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */ |
| 454 | #define PCI_EXP_DEVCTL_READRQ_128B 0x0000 /* 128 Bytes */ | ||
| 455 | #define PCI_EXP_DEVCTL_READRQ_256B 0x1000 /* 256 Bytes */ | ||
| 456 | #define PCI_EXP_DEVCTL_READRQ_512B 0x2000 /* 512 Bytes */ | ||
| 457 | #define PCI_EXP_DEVCTL_READRQ_1024B 0x3000 /* 1024 Bytes */ | ||
| 454 | #define PCI_EXP_DEVCTL_BCR_FLR 0x8000 /* Bridge Configuration Retry / FLR */ | 458 | #define PCI_EXP_DEVCTL_BCR_FLR 0x8000 /* Bridge Configuration Retry / FLR */ |
| 455 | #define PCI_EXP_DEVSTA 10 /* Device Status */ | 459 | #define PCI_EXP_DEVSTA 10 /* Device Status */ |
| 456 | #define PCI_EXP_DEVSTA_CED 0x0001 /* Correctable Error Detected */ | 460 | #define PCI_EXP_DEVSTA_CED 0x0001 /* Correctable Error Detected */ |
