diff options
Diffstat (limited to 'drivers')
35 files changed, 802 insertions, 500 deletions
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index 9e6816ef280a..24b5476449a1 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c | |||
@@ -60,7 +60,7 @@ int node_to_pxm(int node) | |||
60 | return node_to_pxm_map[node]; | 60 | return node_to_pxm_map[node]; |
61 | } | 61 | } |
62 | 62 | ||
63 | void __acpi_map_pxm_to_node(int pxm, int node) | 63 | static void __acpi_map_pxm_to_node(int pxm, int node) |
64 | { | 64 | { |
65 | if (pxm_to_node_map[pxm] == NUMA_NO_NODE || node < pxm_to_node_map[pxm]) | 65 | if (pxm_to_node_map[pxm] == NUMA_NO_NODE || node < pxm_to_node_map[pxm]) |
66 | pxm_to_node_map[pxm] = node; | 66 | pxm_to_node_map[pxm] = node; |
@@ -193,7 +193,7 @@ static int __init acpi_parse_slit(struct acpi_table_header *table) | |||
193 | return 0; | 193 | return 0; |
194 | } | 194 | } |
195 | 195 | ||
196 | void __init __attribute__ ((weak)) | 196 | void __init __weak |
197 | acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa) | 197 | acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa) |
198 | { | 198 | { |
199 | printk(KERN_WARNING PREFIX | 199 | printk(KERN_WARNING PREFIX |
@@ -314,7 +314,7 @@ int __init acpi_numa_init(void) | |||
314 | return 0; | 314 | return 0; |
315 | } | 315 | } |
316 | 316 | ||
317 | int acpi_get_pxm(acpi_handle h) | 317 | static int acpi_get_pxm(acpi_handle h) |
318 | { | 318 | { |
319 | unsigned long long pxm; | 319 | unsigned long long pxm; |
320 | acpi_status status; | 320 | acpi_status status; |
@@ -331,14 +331,14 @@ int acpi_get_pxm(acpi_handle h) | |||
331 | return -1; | 331 | return -1; |
332 | } | 332 | } |
333 | 333 | ||
334 | int acpi_get_node(acpi_handle *handle) | 334 | int acpi_get_node(acpi_handle handle) |
335 | { | 335 | { |
336 | int pxm, node = NUMA_NO_NODE; | 336 | int pxm; |
337 | 337 | ||
338 | pxm = acpi_get_pxm(handle); | 338 | pxm = acpi_get_pxm(handle); |
339 | if (pxm >= 0 && pxm < MAX_PXM_DOMAINS) | 339 | if (pxm < 0 || pxm >= MAX_PXM_DOMAINS) |
340 | node = acpi_map_pxm_to_node(pxm); | 340 | return NUMA_NO_NODE; |
341 | 341 | ||
342 | return node; | 342 | return acpi_map_pxm_to_node(pxm); |
343 | } | 343 | } |
344 | EXPORT_SYMBOL(acpi_get_node); | 344 | EXPORT_SYMBOL(acpi_get_node); |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index a52a5b662f35..5a0bf8ed649b 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -1166,13 +1166,13 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host) | |||
1166 | static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, | 1166 | static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, |
1167 | struct ahci_host_priv *hpriv) | 1167 | struct ahci_host_priv *hpriv) |
1168 | { | 1168 | { |
1169 | int rc, nvec; | 1169 | int nvec; |
1170 | 1170 | ||
1171 | if (hpriv->flags & AHCI_HFLAG_NO_MSI) | 1171 | if (hpriv->flags & AHCI_HFLAG_NO_MSI) |
1172 | goto intx; | 1172 | goto intx; |
1173 | 1173 | ||
1174 | rc = pci_msi_vec_count(pdev); | 1174 | nvec = pci_msi_vec_count(pdev); |
1175 | if (rc < 0) | 1175 | if (nvec < 0) |
1176 | goto intx; | 1176 | goto intx; |
1177 | 1177 | ||
1178 | /* | 1178 | /* |
@@ -1180,21 +1180,19 @@ static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, | |||
1180 | * Message mode could be enforced. In this case assume that advantage | 1180 | * Message mode could be enforced. In this case assume that advantage |
1181 | * of multipe MSIs is negated and use single MSI mode instead. | 1181 | * of multipe MSIs is negated and use single MSI mode instead. |
1182 | */ | 1182 | */ |
1183 | if (rc < n_ports) | 1183 | if (nvec < n_ports) |
1184 | goto single_msi; | 1184 | goto single_msi; |
1185 | 1185 | ||
1186 | nvec = rc; | 1186 | nvec = pci_enable_msi_range(pdev, nvec, nvec); |
1187 | rc = pci_enable_msi_block(pdev, nvec); | 1187 | if (nvec == -ENOSPC) |
1188 | if (rc < 0) | ||
1189 | goto intx; | ||
1190 | else if (rc > 0) | ||
1191 | goto single_msi; | 1188 | goto single_msi; |
1189 | else if (nvec < 0) | ||
1190 | goto intx; | ||
1192 | 1191 | ||
1193 | return nvec; | 1192 | return nvec; |
1194 | 1193 | ||
1195 | single_msi: | 1194 | single_msi: |
1196 | rc = pci_enable_msi(pdev); | 1195 | if (pci_enable_msi(pdev)) |
1197 | if (rc) | ||
1198 | goto intx; | 1196 | goto intx; |
1199 | return 1; | 1197 | return 1; |
1200 | 1198 | ||
diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c index 725c46162bbd..2ac754e18bcf 100644 --- a/drivers/bus/mvebu-mbus.c +++ b/drivers/bus/mvebu-mbus.c | |||
@@ -870,14 +870,14 @@ static void __init mvebu_mbus_get_pcie_resources(struct device_node *np, | |||
870 | ret = of_property_read_u32_array(np, "pcie-mem-aperture", reg, ARRAY_SIZE(reg)); | 870 | ret = of_property_read_u32_array(np, "pcie-mem-aperture", reg, ARRAY_SIZE(reg)); |
871 | if (!ret) { | 871 | if (!ret) { |
872 | mem->start = reg[0]; | 872 | mem->start = reg[0]; |
873 | mem->end = mem->start + reg[1]; | 873 | mem->end = mem->start + reg[1] - 1; |
874 | mem->flags = IORESOURCE_MEM; | 874 | mem->flags = IORESOURCE_MEM; |
875 | } | 875 | } |
876 | 876 | ||
877 | ret = of_property_read_u32_array(np, "pcie-io-aperture", reg, ARRAY_SIZE(reg)); | 877 | ret = of_property_read_u32_array(np, "pcie-io-aperture", reg, ARRAY_SIZE(reg)); |
878 | if (!ret) { | 878 | if (!ret) { |
879 | io->start = reg[0]; | 879 | io->start = reg[0]; |
880 | io->end = io->start + reg[1]; | 880 | io->end = io->start + reg[1] - 1; |
881 | io->flags = IORESOURCE_IO; | 881 | io->flags = IORESOURCE_IO; |
882 | } | 882 | } |
883 | } | 883 | } |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 7f2af9aca038..309023f12d7f 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
@@ -319,7 +319,8 @@ static int drm_open_helper(struct inode *inode, struct file *filp, | |||
319 | pci_dev_put(pci_dev); | 319 | pci_dev_put(pci_dev); |
320 | } | 320 | } |
321 | if (!dev->hose) { | 321 | if (!dev->hose) { |
322 | struct pci_bus *b = pci_bus_b(pci_root_buses.next); | 322 | struct pci_bus *b = list_entry(pci_root_buses.next, |
323 | struct pci_bus, node); | ||
323 | if (b) | 324 | if (b) |
324 | dev->hose = b->sysdata; | 325 | dev->hose = b->sysdata; |
325 | } | 326 | } |
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index e400fbe411de..cff039df056e 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/list.h> | 25 | #include <linux/list.h> |
26 | #include <linux/spinlock.h> | 26 | #include <linux/spinlock.h> |
27 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
28 | #include <linux/irqreturn.h> | ||
28 | 29 | ||
29 | /* | 30 | /* |
30 | * Maximum number of IOMMUs supported | 31 | * Maximum number of IOMMUs supported |
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c index a8c08f332da0..92752fb5b2d3 100644 --- a/drivers/message/i2o/iop.c +++ b/drivers/message/i2o/iop.c | |||
@@ -652,6 +652,44 @@ static int i2o_iop_activate(struct i2o_controller *c) | |||
652 | return i2o_hrt_get(c); | 652 | return i2o_hrt_get(c); |
653 | }; | 653 | }; |
654 | 654 | ||
655 | static void i2o_res_alloc(struct i2o_controller *c, unsigned long flags) | ||
656 | { | ||
657 | i2o_status_block *sb = c->status_block.virt; | ||
658 | struct resource *res = &c->mem_resource; | ||
659 | resource_size_t size, align; | ||
660 | int err; | ||
661 | |||
662 | res->name = c->pdev->bus->name; | ||
663 | res->flags = flags; | ||
664 | res->start = 0; | ||
665 | res->end = 0; | ||
666 | osm_info("%s: requires private memory resources.\n", c->name); | ||
667 | |||
668 | if (flags & IORESOURCE_MEM) { | ||
669 | size = sb->desired_mem_size; | ||
670 | align = 1 << 20; /* unspecified, use 1Mb and play safe */ | ||
671 | } else { | ||
672 | size = sb->desired_io_size; | ||
673 | align = 1 << 12; /* unspecified, use 4Kb and play safe */ | ||
674 | } | ||
675 | |||
676 | err = pci_bus_alloc_resource(c->pdev->bus, res, size, align, 0, 0, | ||
677 | NULL, NULL); | ||
678 | if (err < 0) | ||
679 | return; | ||
680 | |||
681 | if (flags & IORESOURCE_MEM) { | ||
682 | c->mem_alloc = 1; | ||
683 | sb->current_mem_size = resource_size(res); | ||
684 | sb->current_mem_base = res->start; | ||
685 | } else if (flags & IORESOURCE_IO) { | ||
686 | c->io_alloc = 1; | ||
687 | sb->current_io_size = resource_size(res); | ||
688 | sb->current_io_base = res->start; | ||
689 | } | ||
690 | osm_info("%s: allocated PCI space %pR\n", c->name, res); | ||
691 | } | ||
692 | |||
655 | /** | 693 | /** |
656 | * i2o_iop_systab_set - Set the I2O System Table of the specified IOP | 694 | * i2o_iop_systab_set - Set the I2O System Table of the specified IOP |
657 | * @c: I2O controller to which the system table should be send | 695 | * @c: I2O controller to which the system table should be send |
@@ -665,52 +703,13 @@ static int i2o_iop_systab_set(struct i2o_controller *c) | |||
665 | struct i2o_message *msg; | 703 | struct i2o_message *msg; |
666 | i2o_status_block *sb = c->status_block.virt; | 704 | i2o_status_block *sb = c->status_block.virt; |
667 | struct device *dev = &c->pdev->dev; | 705 | struct device *dev = &c->pdev->dev; |
668 | struct resource *root; | ||
669 | int rc; | 706 | int rc; |
670 | 707 | ||
671 | if (sb->current_mem_size < sb->desired_mem_size) { | 708 | if (sb->current_mem_size < sb->desired_mem_size) |
672 | struct resource *res = &c->mem_resource; | 709 | i2o_res_alloc(c, IORESOURCE_MEM); |
673 | res->name = c->pdev->bus->name; | ||
674 | res->flags = IORESOURCE_MEM; | ||
675 | res->start = 0; | ||
676 | res->end = 0; | ||
677 | osm_info("%s: requires private memory resources.\n", c->name); | ||
678 | root = pci_find_parent_resource(c->pdev, res); | ||
679 | if (root == NULL) | ||
680 | osm_warn("%s: Can't find parent resource!\n", c->name); | ||
681 | if (root && allocate_resource(root, res, sb->desired_mem_size, sb->desired_mem_size, sb->desired_mem_size, 1 << 20, /* Unspecified, so use 1Mb and play safe */ | ||
682 | NULL, NULL) >= 0) { | ||
683 | c->mem_alloc = 1; | ||
684 | sb->current_mem_size = resource_size(res); | ||
685 | sb->current_mem_base = res->start; | ||
686 | osm_info("%s: allocated %llu bytes of PCI memory at " | ||
687 | "0x%016llX.\n", c->name, | ||
688 | (unsigned long long)resource_size(res), | ||
689 | (unsigned long long)res->start); | ||
690 | } | ||
691 | } | ||
692 | 710 | ||
693 | if (sb->current_io_size < sb->desired_io_size) { | 711 | if (sb->current_io_size < sb->desired_io_size) |
694 | struct resource *res = &c->io_resource; | 712 | i2o_res_alloc(c, IORESOURCE_IO); |
695 | res->name = c->pdev->bus->name; | ||
696 | res->flags = IORESOURCE_IO; | ||
697 | res->start = 0; | ||
698 | res->end = 0; | ||
699 | osm_info("%s: requires private memory resources.\n", c->name); | ||
700 | root = pci_find_parent_resource(c->pdev, res); | ||
701 | if (root == NULL) | ||
702 | osm_warn("%s: Can't find parent resource!\n", c->name); | ||
703 | if (root && allocate_resource(root, res, sb->desired_io_size, sb->desired_io_size, sb->desired_io_size, 1 << 20, /* Unspecified, so use 1Mb and play safe */ | ||
704 | NULL, NULL) >= 0) { | ||
705 | c->io_alloc = 1; | ||
706 | sb->current_io_size = resource_size(res); | ||
707 | sb->current_mem_base = res->start; | ||
708 | osm_info("%s: allocated %llu bytes of PCI I/O at " | ||
709 | "0x%016llX.\n", c->name, | ||
710 | (unsigned long long)resource_size(res), | ||
711 | (unsigned long long)res->start); | ||
712 | } | ||
713 | } | ||
714 | 713 | ||
715 | msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); | 714 | msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); |
716 | if (IS_ERR(msg)) | 715 | if (IS_ERR(msg)) |
diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h index 80bd829fbd9a..893d5119fa9b 100644 --- a/drivers/misc/mei/hw-me.h +++ b/drivers/misc/mei/hw-me.h | |||
@@ -20,6 +20,7 @@ | |||
20 | #define _MEI_INTERFACE_H_ | 20 | #define _MEI_INTERFACE_H_ |
21 | 21 | ||
22 | #include <linux/mei.h> | 22 | #include <linux/mei.h> |
23 | #include <linux/irqreturn.h> | ||
23 | #include "mei_dev.h" | 24 | #include "mei_dev.h" |
24 | #include "client.h" | 25 | #include "client.h" |
25 | 26 | ||
diff --git a/drivers/misc/mic/card/mic_device.h b/drivers/misc/mic/card/mic_device.h index 347b9b3b7916..306f502be95e 100644 --- a/drivers/misc/mic/card/mic_device.h +++ b/drivers/misc/mic/card/mic_device.h | |||
@@ -29,6 +29,7 @@ | |||
29 | 29 | ||
30 | #include <linux/workqueue.h> | 30 | #include <linux/workqueue.h> |
31 | #include <linux/io.h> | 31 | #include <linux/io.h> |
32 | #include <linux/irqreturn.h> | ||
32 | 33 | ||
33 | /** | 34 | /** |
34 | * struct mic_intr_info - Contains h/w specific interrupt sources info | 35 | * struct mic_intr_info - Contains h/w specific interrupt sources info |
diff --git a/drivers/misc/mic/host/mic_device.h b/drivers/misc/mic/host/mic_device.h index 1a6edce2ecde..0398c696d257 100644 --- a/drivers/misc/mic/host/mic_device.h +++ b/drivers/misc/mic/host/mic_device.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/cdev.h> | 24 | #include <linux/cdev.h> |
25 | #include <linux/idr.h> | 25 | #include <linux/idr.h> |
26 | #include <linux/notifier.h> | 26 | #include <linux/notifier.h> |
27 | #include <linux/irqreturn.h> | ||
27 | 28 | ||
28 | #include "mic_intr.h" | 29 | #include "mic_intr.h" |
29 | 30 | ||
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 17d2b07ee67c..e2501ac6fe84 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile | |||
@@ -33,21 +33,15 @@ obj-$(CONFIG_PCI_IOV) += iov.o | |||
33 | # | 33 | # |
34 | # Some architectures use the generic PCI setup functions | 34 | # Some architectures use the generic PCI setup functions |
35 | # | 35 | # |
36 | obj-$(CONFIG_X86) += setup-bus.o | 36 | obj-$(CONFIG_ALPHA) += setup-irq.o |
37 | obj-$(CONFIG_ALPHA) += setup-bus.o setup-irq.o | 37 | obj-$(CONFIG_ARM) += setup-irq.o |
38 | obj-$(CONFIG_ARM) += setup-bus.o setup-irq.o | 38 | obj-$(CONFIG_UNICORE32) += setup-irq.o |
39 | obj-$(CONFIG_UNICORE32) += setup-bus.o setup-irq.o | 39 | obj-$(CONFIG_SUPERH) += setup-irq.o |
40 | obj-$(CONFIG_PARISC) += setup-bus.o | 40 | obj-$(CONFIG_MIPS) += setup-irq.o |
41 | obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o | ||
42 | obj-$(CONFIG_PPC) += setup-bus.o | ||
43 | obj-$(CONFIG_FRV) += setup-bus.o | ||
44 | obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o | ||
45 | obj-$(CONFIG_X86_VISWS) += setup-irq.o | 41 | obj-$(CONFIG_X86_VISWS) += setup-irq.o |
46 | obj-$(CONFIG_MN10300) += setup-bus.o | 42 | obj-$(CONFIG_TILE) += setup-irq.o |
47 | obj-$(CONFIG_MICROBLAZE) += setup-bus.o | 43 | obj-$(CONFIG_SPARC_LEON) += setup-irq.o |
48 | obj-$(CONFIG_TILE) += setup-bus.o setup-irq.o | 44 | obj-$(CONFIG_M68K) += setup-irq.o |
49 | obj-$(CONFIG_SPARC_LEON) += setup-bus.o setup-irq.o | ||
50 | obj-$(CONFIG_M68K) += setup-bus.o setup-irq.o | ||
51 | 45 | ||
52 | # | 46 | # |
53 | # ACPI Related PCI FW Functions | 47 | # ACPI Related PCI FW Functions |
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 38901665c770..fb8aed307c28 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -132,7 +132,7 @@ static void pci_clip_resource_to_region(struct pci_bus *bus, | |||
132 | 132 | ||
133 | static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res, | 133 | static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res, |
134 | resource_size_t size, resource_size_t align, | 134 | resource_size_t size, resource_size_t align, |
135 | resource_size_t min, unsigned int type_mask, | 135 | resource_size_t min, unsigned long type_mask, |
136 | resource_size_t (*alignf)(void *, | 136 | resource_size_t (*alignf)(void *, |
137 | const struct resource *, | 137 | const struct resource *, |
138 | resource_size_t, | 138 | resource_size_t, |
@@ -144,7 +144,7 @@ static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res, | |||
144 | struct resource *r, avail; | 144 | struct resource *r, avail; |
145 | resource_size_t max; | 145 | resource_size_t max; |
146 | 146 | ||
147 | type_mask |= IORESOURCE_IO | IORESOURCE_MEM; | 147 | type_mask |= IORESOURCE_TYPE_BITS; |
148 | 148 | ||
149 | pci_bus_for_each_resource(bus, r, i) { | 149 | pci_bus_for_each_resource(bus, r, i) { |
150 | if (!r) | 150 | if (!r) |
@@ -200,7 +200,7 @@ static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res, | |||
200 | */ | 200 | */ |
201 | int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | 201 | int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, |
202 | resource_size_t size, resource_size_t align, | 202 | resource_size_t size, resource_size_t align, |
203 | resource_size_t min, unsigned int type_mask, | 203 | resource_size_t min, unsigned long type_mask, |
204 | resource_size_t (*alignf)(void *, | 204 | resource_size_t (*alignf)(void *, |
205 | const struct resource *, | 205 | const struct resource *, |
206 | resource_size_t, | 206 | resource_size_t, |
diff --git a/drivers/pci/host-bridge.c b/drivers/pci/host-bridge.c index 06ace6248c61..47aaf22d814e 100644 --- a/drivers/pci/host-bridge.c +++ b/drivers/pci/host-bridge.c | |||
@@ -32,11 +32,6 @@ void pci_set_host_bridge_release(struct pci_host_bridge *bridge, | |||
32 | bridge->release_data = release_data; | 32 | bridge->release_data = release_data; |
33 | } | 33 | } |
34 | 34 | ||
35 | static bool resource_contains(struct resource *res1, struct resource *res2) | ||
36 | { | ||
37 | return res1->start <= res2->start && res1->end >= res2->end; | ||
38 | } | ||
39 | |||
40 | void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region, | 35 | void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region, |
41 | struct resource *res) | 36 | struct resource *res) |
42 | { | 37 | { |
@@ -45,9 +40,6 @@ void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region, | |||
45 | resource_size_t offset = 0; | 40 | resource_size_t offset = 0; |
46 | 41 | ||
47 | list_for_each_entry(window, &bridge->windows, list) { | 42 | list_for_each_entry(window, &bridge->windows, list) { |
48 | if (resource_type(res) != resource_type(window->res)) | ||
49 | continue; | ||
50 | |||
51 | if (resource_contains(window->res, res)) { | 43 | if (resource_contains(window->res, res)) { |
52 | offset = window->offset; | 44 | offset = window->offset; |
53 | break; | 45 | break; |
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index 47d46c6d8468..a6f67ec8882f 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig | |||
@@ -27,7 +27,7 @@ config PCI_TEGRA | |||
27 | 27 | ||
28 | config PCI_RCAR_GEN2 | 28 | config PCI_RCAR_GEN2 |
29 | bool "Renesas R-Car Gen2 Internal PCI controller" | 29 | bool "Renesas R-Car Gen2 Internal PCI controller" |
30 | depends on ARM && (ARCH_R8A7790 || ARCH_R8A7791 || COMPILE_TEST) | 30 | depends on ARCH_SHMOBILE || (ARM && COMPILE_TEST) |
31 | help | 31 | help |
32 | Say Y here if you want internal PCI support on R-Car Gen2 SoC. | 32 | Say Y here if you want internal PCI support on R-Car Gen2 SoC. |
33 | There are 3 internal PCI controllers available with a single | 33 | There are 3 internal PCI controllers available with a single |
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c index e8663a8c3406..ee082509b0ba 100644 --- a/drivers/pci/host/pci-imx6.c +++ b/drivers/pci/host/pci-imx6.c | |||
@@ -424,20 +424,40 @@ static void imx6_pcie_reset_phy(struct pcie_port *pp) | |||
424 | 424 | ||
425 | static int imx6_pcie_link_up(struct pcie_port *pp) | 425 | static int imx6_pcie_link_up(struct pcie_port *pp) |
426 | { | 426 | { |
427 | u32 rc, ltssm, rx_valid; | 427 | u32 rc, debug_r0, rx_valid; |
428 | int count = 5; | ||
428 | 429 | ||
429 | /* | 430 | /* |
430 | * Test if the PHY reports that the link is up and also that | 431 | * Test if the PHY reports that the link is up and also that the LTSSM |
431 | * the link training finished. It might happen that the PHY | 432 | * training finished. There are three possible states of the link when |
432 | * reports the link is already up, but the link training bit | 433 | * this code is called: |
433 | * is still set, so make sure to check the training is done | 434 | * 1) The link is DOWN (unlikely) |
434 | * as well here. | 435 | * The link didn't come up yet for some reason. This usually means |
436 | * we have a real problem somewhere. Reset the PHY and exit. This | ||
437 | * state calls for inspection of the DEBUG registers. | ||
438 | * 2) The link is UP, but still in LTSSM training | ||
439 | * Wait for the training to finish, which should take a very short | ||
440 | * time. If the training does not finish, we have a problem and we | ||
441 | * need to inspect the DEBUG registers. If the training does finish, | ||
442 | * the link is up and operating correctly. | ||
443 | * 3) The link is UP and no longer in LTSSM training | ||
444 | * The link is up and operating correctly. | ||
435 | */ | 445 | */ |
436 | rc = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1); | 446 | while (1) { |
437 | if ((rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_UP) && | 447 | rc = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1); |
438 | !(rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING)) | 448 | if (!(rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_UP)) |
439 | return 1; | 449 | break; |
440 | 450 | if (!(rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING)) | |
451 | return 1; | ||
452 | if (!count--) | ||
453 | break; | ||
454 | dev_dbg(pp->dev, "Link is up, but still in training\n"); | ||
455 | /* | ||
456 | * Wait a little bit, then re-check if the link finished | ||
457 | * the training. | ||
458 | */ | ||
459 | usleep_range(1000, 2000); | ||
460 | } | ||
441 | /* | 461 | /* |
442 | * From L0, initiate MAC entry to gen2 if EP/RC supports gen2. | 462 | * From L0, initiate MAC entry to gen2 if EP/RC supports gen2. |
443 | * Wait 2ms (LTSSM timeout is 24ms, PHY lock is ~5us in gen2). | 463 | * Wait 2ms (LTSSM timeout is 24ms, PHY lock is ~5us in gen2). |
@@ -446,15 +466,16 @@ static int imx6_pcie_link_up(struct pcie_port *pp) | |||
446 | * to gen2 is stuck | 466 | * to gen2 is stuck |
447 | */ | 467 | */ |
448 | pcie_phy_read(pp->dbi_base, PCIE_PHY_RX_ASIC_OUT, &rx_valid); | 468 | pcie_phy_read(pp->dbi_base, PCIE_PHY_RX_ASIC_OUT, &rx_valid); |
449 | ltssm = readl(pp->dbi_base + PCIE_PHY_DEBUG_R0) & 0x3F; | 469 | debug_r0 = readl(pp->dbi_base + PCIE_PHY_DEBUG_R0); |
450 | 470 | ||
451 | if (rx_valid & 0x01) | 471 | if (rx_valid & 0x01) |
452 | return 0; | 472 | return 0; |
453 | 473 | ||
454 | if (ltssm != 0x0d) | 474 | if ((debug_r0 & 0x3f) != 0x0d) |
455 | return 0; | 475 | return 0; |
456 | 476 | ||
457 | dev_err(pp->dev, "transition to gen2 is stuck, reset PHY!\n"); | 477 | dev_err(pp->dev, "transition to gen2 is stuck, reset PHY!\n"); |
478 | dev_dbg(pp->dev, "debug_r0=%08x debug_r1=%08x\n", debug_r0, rc); | ||
458 | 479 | ||
459 | imx6_pcie_reset_phy(pp); | 480 | imx6_pcie_reset_phy(pp); |
460 | 481 | ||
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index 0e79665afd44..d3d1cfd51e09 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c | |||
@@ -101,7 +101,9 @@ struct mvebu_pcie { | |||
101 | struct mvebu_pcie_port *ports; | 101 | struct mvebu_pcie_port *ports; |
102 | struct msi_chip *msi; | 102 | struct msi_chip *msi; |
103 | struct resource io; | 103 | struct resource io; |
104 | char io_name[30]; | ||
104 | struct resource realio; | 105 | struct resource realio; |
106 | char mem_name[30]; | ||
105 | struct resource mem; | 107 | struct resource mem; |
106 | struct resource busn; | 108 | struct resource busn; |
107 | int nports; | 109 | int nports; |
@@ -672,10 +674,30 @@ static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys) | |||
672 | { | 674 | { |
673 | struct mvebu_pcie *pcie = sys_to_pcie(sys); | 675 | struct mvebu_pcie *pcie = sys_to_pcie(sys); |
674 | int i; | 676 | int i; |
677 | int domain = 0; | ||
675 | 678 | ||
676 | if (resource_size(&pcie->realio) != 0) | 679 | #ifdef CONFIG_PCI_DOMAINS |
680 | domain = sys->domain; | ||
681 | #endif | ||
682 | |||
683 | snprintf(pcie->mem_name, sizeof(pcie->mem_name), "PCI MEM %04x", | ||
684 | domain); | ||
685 | pcie->mem.name = pcie->mem_name; | ||
686 | |||
687 | snprintf(pcie->io_name, sizeof(pcie->io_name), "PCI I/O %04x", domain); | ||
688 | pcie->realio.name = pcie->io_name; | ||
689 | |||
690 | if (request_resource(&iomem_resource, &pcie->mem)) | ||
691 | return 0; | ||
692 | |||
693 | if (resource_size(&pcie->realio) != 0) { | ||
694 | if (request_resource(&ioport_resource, &pcie->realio)) { | ||
695 | release_resource(&pcie->mem); | ||
696 | return 0; | ||
697 | } | ||
677 | pci_add_resource_offset(&sys->resources, &pcie->realio, | 698 | pci_add_resource_offset(&sys->resources, &pcie->realio, |
678 | sys->io_offset); | 699 | sys->io_offset); |
700 | } | ||
679 | pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); | 701 | pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); |
680 | pci_add_resource(&sys->resources, &pcie->busn); | 702 | pci_add_resource(&sys->resources, &pcie->busn); |
681 | 703 | ||
@@ -797,7 +819,7 @@ static int mvebu_get_tgt_attr(struct device_node *np, int devfn, | |||
797 | 819 | ||
798 | for (i = 0; i < nranges; i++) { | 820 | for (i = 0; i < nranges; i++) { |
799 | u32 flags = of_read_number(range, 1); | 821 | u32 flags = of_read_number(range, 1); |
800 | u32 slot = of_read_number(range, 2); | 822 | u32 slot = of_read_number(range + 1, 1); |
801 | u64 cpuaddr = of_read_number(range + na, pna); | 823 | u64 cpuaddr = of_read_number(range + na, pna); |
802 | unsigned long rtype; | 824 | unsigned long rtype; |
803 | 825 | ||
diff --git a/drivers/pci/host/pci-rcar-gen2.c b/drivers/pci/host/pci-rcar-gen2.c index ceec147baec3..fd3e3ab56509 100644 --- a/drivers/pci/host/pci-rcar-gen2.c +++ b/drivers/pci/host/pci-rcar-gen2.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/pci.h> | 18 | #include <linux/pci.h> |
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/pm_runtime.h> | 20 | #include <linux/pm_runtime.h> |
21 | #include <linux/sizes.h> | ||
21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
22 | 23 | ||
23 | /* AHB-PCI Bridge PCI communication registers */ | 24 | /* AHB-PCI Bridge PCI communication registers */ |
@@ -39,9 +40,26 @@ | |||
39 | 40 | ||
40 | #define RCAR_PCI_INT_ENABLE_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x20) | 41 | #define RCAR_PCI_INT_ENABLE_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x20) |
41 | #define RCAR_PCI_INT_STATUS_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x24) | 42 | #define RCAR_PCI_INT_STATUS_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x24) |
43 | #define RCAR_PCI_INT_SIGTABORT (1 << 0) | ||
44 | #define RCAR_PCI_INT_SIGRETABORT (1 << 1) | ||
45 | #define RCAR_PCI_INT_REMABORT (1 << 2) | ||
46 | #define RCAR_PCI_INT_PERR (1 << 3) | ||
47 | #define RCAR_PCI_INT_SIGSERR (1 << 4) | ||
48 | #define RCAR_PCI_INT_RESERR (1 << 5) | ||
49 | #define RCAR_PCI_INT_WIN1ERR (1 << 12) | ||
50 | #define RCAR_PCI_INT_WIN2ERR (1 << 13) | ||
42 | #define RCAR_PCI_INT_A (1 << 16) | 51 | #define RCAR_PCI_INT_A (1 << 16) |
43 | #define RCAR_PCI_INT_B (1 << 17) | 52 | #define RCAR_PCI_INT_B (1 << 17) |
44 | #define RCAR_PCI_INT_PME (1 << 19) | 53 | #define RCAR_PCI_INT_PME (1 << 19) |
54 | #define RCAR_PCI_INT_ALLERRORS (RCAR_PCI_INT_SIGTABORT | \ | ||
55 | RCAR_PCI_INT_SIGRETABORT | \ | ||
56 | RCAR_PCI_INT_SIGRETABORT | \ | ||
57 | RCAR_PCI_INT_REMABORT | \ | ||
58 | RCAR_PCI_INT_PERR | \ | ||
59 | RCAR_PCI_INT_SIGSERR | \ | ||
60 | RCAR_PCI_INT_RESERR | \ | ||
61 | RCAR_PCI_INT_WIN1ERR | \ | ||
62 | RCAR_PCI_INT_WIN2ERR) | ||
45 | 63 | ||
46 | #define RCAR_AHB_BUS_CTR_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x30) | 64 | #define RCAR_AHB_BUS_CTR_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x30) |
47 | #define RCAR_AHB_BUS_MMODE_HTRANS (1 << 0) | 65 | #define RCAR_AHB_BUS_MMODE_HTRANS (1 << 0) |
@@ -74,9 +92,6 @@ | |||
74 | 92 | ||
75 | #define RCAR_PCI_UNIT_REV_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x48) | 93 | #define RCAR_PCI_UNIT_REV_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x48) |
76 | 94 | ||
77 | /* Number of internal PCI controllers */ | ||
78 | #define RCAR_PCI_NR_CONTROLLERS 3 | ||
79 | |||
80 | struct rcar_pci_priv { | 95 | struct rcar_pci_priv { |
81 | struct device *dev; | 96 | struct device *dev; |
82 | void __iomem *reg; | 97 | void __iomem *reg; |
@@ -84,6 +99,7 @@ struct rcar_pci_priv { | |||
84 | struct resource mem_res; | 99 | struct resource mem_res; |
85 | struct resource *cfg_res; | 100 | struct resource *cfg_res; |
86 | int irq; | 101 | int irq; |
102 | unsigned long window_size; | ||
87 | }; | 103 | }; |
88 | 104 | ||
89 | /* PCI configuration space operations */ | 105 | /* PCI configuration space operations */ |
@@ -102,6 +118,10 @@ static void __iomem *rcar_pci_cfg_base(struct pci_bus *bus, unsigned int devfn, | |||
102 | if (slot > 2) | 118 | if (slot > 2) |
103 | return NULL; | 119 | return NULL; |
104 | 120 | ||
121 | /* bridge logic only has registers to 0x40 */ | ||
122 | if (slot == 0x0 && where >= 0x40) | ||
123 | return NULL; | ||
124 | |||
105 | val = slot ? RCAR_AHBPCI_WIN1_DEVICE | RCAR_AHBPCI_WIN_CTR_CFG : | 125 | val = slot ? RCAR_AHBPCI_WIN1_DEVICE | RCAR_AHBPCI_WIN_CTR_CFG : |
106 | RCAR_AHBPCI_WIN1_HOST | RCAR_AHBPCI_WIN_CTR_CFG; | 126 | RCAR_AHBPCI_WIN1_HOST | RCAR_AHBPCI_WIN_CTR_CFG; |
107 | 127 | ||
@@ -156,7 +176,7 @@ static int rcar_pci_write_config(struct pci_bus *bus, unsigned int devfn, | |||
156 | } | 176 | } |
157 | 177 | ||
158 | /* PCI interrupt mapping */ | 178 | /* PCI interrupt mapping */ |
159 | static int __init rcar_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | 179 | static int rcar_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) |
160 | { | 180 | { |
161 | struct pci_sys_data *sys = dev->bus->sysdata; | 181 | struct pci_sys_data *sys = dev->bus->sysdata; |
162 | struct rcar_pci_priv *priv = sys->private_data; | 182 | struct rcar_pci_priv *priv = sys->private_data; |
@@ -164,8 +184,48 @@ static int __init rcar_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |||
164 | return priv->irq; | 184 | return priv->irq; |
165 | } | 185 | } |
166 | 186 | ||
187 | #ifdef CONFIG_PCI_DEBUG | ||
188 | /* if debug enabled, then attach an error handler irq to the bridge */ | ||
189 | |||
190 | static irqreturn_t rcar_pci_err_irq(int irq, void *pw) | ||
191 | { | ||
192 | struct rcar_pci_priv *priv = pw; | ||
193 | u32 status = ioread32(priv->reg + RCAR_PCI_INT_STATUS_REG); | ||
194 | |||
195 | if (status & RCAR_PCI_INT_ALLERRORS) { | ||
196 | dev_err(priv->dev, "error irq: status %08x\n", status); | ||
197 | |||
198 | /* clear the error(s) */ | ||
199 | iowrite32(status & RCAR_PCI_INT_ALLERRORS, | ||
200 | priv->reg + RCAR_PCI_INT_STATUS_REG); | ||
201 | return IRQ_HANDLED; | ||
202 | } | ||
203 | |||
204 | return IRQ_NONE; | ||
205 | } | ||
206 | |||
207 | static void rcar_pci_setup_errirq(struct rcar_pci_priv *priv) | ||
208 | { | ||
209 | int ret; | ||
210 | u32 val; | ||
211 | |||
212 | ret = devm_request_irq(priv->dev, priv->irq, rcar_pci_err_irq, | ||
213 | IRQF_SHARED, "error irq", priv); | ||
214 | if (ret) { | ||
215 | dev_err(priv->dev, "cannot claim IRQ for error handling\n"); | ||
216 | return; | ||
217 | } | ||
218 | |||
219 | val = ioread32(priv->reg + RCAR_PCI_INT_ENABLE_REG); | ||
220 | val |= RCAR_PCI_INT_ALLERRORS; | ||
221 | iowrite32(val, priv->reg + RCAR_PCI_INT_ENABLE_REG); | ||
222 | } | ||
223 | #else | ||
224 | static inline void rcar_pci_setup_errirq(struct rcar_pci_priv *priv) { } | ||
225 | #endif | ||
226 | |||
167 | /* PCI host controller setup */ | 227 | /* PCI host controller setup */ |
168 | static int __init rcar_pci_setup(int nr, struct pci_sys_data *sys) | 228 | static int rcar_pci_setup(int nr, struct pci_sys_data *sys) |
169 | { | 229 | { |
170 | struct rcar_pci_priv *priv = sys->private_data; | 230 | struct rcar_pci_priv *priv = sys->private_data; |
171 | void __iomem *reg = priv->reg; | 231 | void __iomem *reg = priv->reg; |
@@ -183,10 +243,31 @@ static int __init rcar_pci_setup(int nr, struct pci_sys_data *sys) | |||
183 | iowrite32(val, reg + RCAR_USBCTR_REG); | 243 | iowrite32(val, reg + RCAR_USBCTR_REG); |
184 | udelay(4); | 244 | udelay(4); |
185 | 245 | ||
186 | /* De-assert reset and set PCIAHB window1 size to 1GB */ | 246 | /* De-assert reset and reset PCIAHB window1 size */ |
187 | val &= ~(RCAR_USBCTR_PCIAHB_WIN1_MASK | RCAR_USBCTR_PCICLK_MASK | | 247 | val &= ~(RCAR_USBCTR_PCIAHB_WIN1_MASK | RCAR_USBCTR_PCICLK_MASK | |
188 | RCAR_USBCTR_USBH_RST | RCAR_USBCTR_PLL_RST); | 248 | RCAR_USBCTR_USBH_RST | RCAR_USBCTR_PLL_RST); |
189 | iowrite32(val | RCAR_USBCTR_PCIAHB_WIN1_1G, reg + RCAR_USBCTR_REG); | 249 | |
250 | /* Setup PCIAHB window1 size */ | ||
251 | switch (priv->window_size) { | ||
252 | case SZ_2G: | ||
253 | val |= RCAR_USBCTR_PCIAHB_WIN1_2G; | ||
254 | break; | ||
255 | case SZ_1G: | ||
256 | val |= RCAR_USBCTR_PCIAHB_WIN1_1G; | ||
257 | break; | ||
258 | case SZ_512M: | ||
259 | val |= RCAR_USBCTR_PCIAHB_WIN1_512M; | ||
260 | break; | ||
261 | default: | ||
262 | pr_warn("unknown window size %ld - defaulting to 256M\n", | ||
263 | priv->window_size); | ||
264 | priv->window_size = SZ_256M; | ||
265 | /* fall-through */ | ||
266 | case SZ_256M: | ||
267 | val |= RCAR_USBCTR_PCIAHB_WIN1_256M; | ||
268 | break; | ||
269 | } | ||
270 | iowrite32(val, reg + RCAR_USBCTR_REG); | ||
190 | 271 | ||
191 | /* Configure AHB master and slave modes */ | 272 | /* Configure AHB master and slave modes */ |
192 | iowrite32(RCAR_AHB_BUS_MODE, reg + RCAR_AHB_BUS_CTR_REG); | 273 | iowrite32(RCAR_AHB_BUS_MODE, reg + RCAR_AHB_BUS_CTR_REG); |
@@ -197,7 +278,7 @@ static int __init rcar_pci_setup(int nr, struct pci_sys_data *sys) | |||
197 | RCAR_PCI_ARBITER_PCIBP_MODE; | 278 | RCAR_PCI_ARBITER_PCIBP_MODE; |
198 | iowrite32(val, reg + RCAR_PCI_ARBITER_CTR_REG); | 279 | iowrite32(val, reg + RCAR_PCI_ARBITER_CTR_REG); |
199 | 280 | ||
200 | /* PCI-AHB mapping: 0x40000000-0x80000000 */ | 281 | /* PCI-AHB mapping: 0x40000000 base */ |
201 | iowrite32(0x40000000 | RCAR_PCIAHB_PREFETCH16, | 282 | iowrite32(0x40000000 | RCAR_PCIAHB_PREFETCH16, |
202 | reg + RCAR_PCIAHB_WIN1_CTR_REG); | 283 | reg + RCAR_PCIAHB_WIN1_CTR_REG); |
203 | 284 | ||
@@ -224,10 +305,15 @@ static int __init rcar_pci_setup(int nr, struct pci_sys_data *sys) | |||
224 | iowrite32(RCAR_PCI_INT_A | RCAR_PCI_INT_B | RCAR_PCI_INT_PME, | 305 | iowrite32(RCAR_PCI_INT_A | RCAR_PCI_INT_B | RCAR_PCI_INT_PME, |
225 | reg + RCAR_PCI_INT_ENABLE_REG); | 306 | reg + RCAR_PCI_INT_ENABLE_REG); |
226 | 307 | ||
308 | if (priv->irq > 0) | ||
309 | rcar_pci_setup_errirq(priv); | ||
310 | |||
227 | /* Add PCI resources */ | 311 | /* Add PCI resources */ |
228 | pci_add_resource(&sys->resources, &priv->io_res); | 312 | pci_add_resource(&sys->resources, &priv->io_res); |
229 | pci_add_resource(&sys->resources, &priv->mem_res); | 313 | pci_add_resource(&sys->resources, &priv->mem_res); |
230 | 314 | ||
315 | /* Setup bus number based on platform device id */ | ||
316 | sys->busnr = to_platform_device(priv->dev)->id; | ||
231 | return 1; | 317 | return 1; |
232 | } | 318 | } |
233 | 319 | ||
@@ -236,48 +322,13 @@ static struct pci_ops rcar_pci_ops = { | |||
236 | .write = rcar_pci_write_config, | 322 | .write = rcar_pci_write_config, |
237 | }; | 323 | }; |
238 | 324 | ||
239 | static struct hw_pci rcar_hw_pci __initdata = { | 325 | static int rcar_pci_probe(struct platform_device *pdev) |
240 | .map_irq = rcar_pci_map_irq, | ||
241 | .ops = &rcar_pci_ops, | ||
242 | .setup = rcar_pci_setup, | ||
243 | }; | ||
244 | |||
245 | static int rcar_pci_count __initdata; | ||
246 | |||
247 | static int __init rcar_pci_add_controller(struct rcar_pci_priv *priv) | ||
248 | { | ||
249 | void **private_data; | ||
250 | int count; | ||
251 | |||
252 | if (rcar_hw_pci.nr_controllers < rcar_pci_count) | ||
253 | goto add_priv; | ||
254 | |||
255 | /* (Re)allocate private data pointer array if needed */ | ||
256 | count = rcar_pci_count + RCAR_PCI_NR_CONTROLLERS; | ||
257 | private_data = kzalloc(count * sizeof(void *), GFP_KERNEL); | ||
258 | if (!private_data) | ||
259 | return -ENOMEM; | ||
260 | |||
261 | rcar_pci_count = count; | ||
262 | if (rcar_hw_pci.private_data) { | ||
263 | memcpy(private_data, rcar_hw_pci.private_data, | ||
264 | rcar_hw_pci.nr_controllers * sizeof(void *)); | ||
265 | kfree(rcar_hw_pci.private_data); | ||
266 | } | ||
267 | |||
268 | rcar_hw_pci.private_data = private_data; | ||
269 | |||
270 | add_priv: | ||
271 | /* Add private data pointer to the array */ | ||
272 | rcar_hw_pci.private_data[rcar_hw_pci.nr_controllers++] = priv; | ||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static int __init rcar_pci_probe(struct platform_device *pdev) | ||
277 | { | 326 | { |
278 | struct resource *cfg_res, *mem_res; | 327 | struct resource *cfg_res, *mem_res; |
279 | struct rcar_pci_priv *priv; | 328 | struct rcar_pci_priv *priv; |
280 | void __iomem *reg; | 329 | void __iomem *reg; |
330 | struct hw_pci hw; | ||
331 | void *hw_private[1]; | ||
281 | 332 | ||
282 | cfg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 333 | cfg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
283 | reg = devm_ioremap_resource(&pdev->dev, cfg_res); | 334 | reg = devm_ioremap_resource(&pdev->dev, cfg_res); |
@@ -308,31 +359,34 @@ static int __init rcar_pci_probe(struct platform_device *pdev) | |||
308 | priv->reg = reg; | 359 | priv->reg = reg; |
309 | priv->dev = &pdev->dev; | 360 | priv->dev = &pdev->dev; |
310 | 361 | ||
311 | return rcar_pci_add_controller(priv); | 362 | if (priv->irq < 0) { |
363 | dev_err(&pdev->dev, "no valid irq found\n"); | ||
364 | return priv->irq; | ||
365 | } | ||
366 | |||
367 | priv->window_size = SZ_1G; | ||
368 | |||
369 | hw_private[0] = priv; | ||
370 | memset(&hw, 0, sizeof(hw)); | ||
371 | hw.nr_controllers = ARRAY_SIZE(hw_private); | ||
372 | hw.private_data = hw_private; | ||
373 | hw.map_irq = rcar_pci_map_irq; | ||
374 | hw.ops = &rcar_pci_ops; | ||
375 | hw.setup = rcar_pci_setup; | ||
376 | pci_common_init_dev(&pdev->dev, &hw); | ||
377 | return 0; | ||
312 | } | 378 | } |
313 | 379 | ||
314 | static struct platform_driver rcar_pci_driver = { | 380 | static struct platform_driver rcar_pci_driver = { |
315 | .driver = { | 381 | .driver = { |
316 | .name = "pci-rcar-gen2", | 382 | .name = "pci-rcar-gen2", |
383 | .owner = THIS_MODULE, | ||
384 | .suppress_bind_attrs = true, | ||
317 | }, | 385 | }, |
386 | .probe = rcar_pci_probe, | ||
318 | }; | 387 | }; |
319 | 388 | ||
320 | static int __init rcar_pci_init(void) | 389 | module_platform_driver(rcar_pci_driver); |
321 | { | ||
322 | int retval; | ||
323 | |||
324 | retval = platform_driver_probe(&rcar_pci_driver, rcar_pci_probe); | ||
325 | if (!retval) | ||
326 | pci_common_init(&rcar_hw_pci); | ||
327 | |||
328 | /* Private data pointer array is not needed any more */ | ||
329 | kfree(rcar_hw_pci.private_data); | ||
330 | rcar_hw_pci.private_data = NULL; | ||
331 | |||
332 | return retval; | ||
333 | } | ||
334 | |||
335 | subsys_initcall(rcar_pci_init); | ||
336 | 390 | ||
337 | MODULE_LICENSE("GPL v2"); | 391 | MODULE_LICENSE("GPL v2"); |
338 | MODULE_DESCRIPTION("Renesas R-Car Gen2 internal PCI"); | 392 | MODULE_DESCRIPTION("Renesas R-Car Gen2 internal PCI"); |
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index 2e48ecf09e2c..509a29d84509 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c | |||
@@ -798,7 +798,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp) | |||
798 | 798 | ||
799 | /* setup RC BARs */ | 799 | /* setup RC BARs */ |
800 | dw_pcie_writel_rc(pp, 0x00000004, PCI_BASE_ADDRESS_0); | 800 | dw_pcie_writel_rc(pp, 0x00000004, PCI_BASE_ADDRESS_0); |
801 | dw_pcie_writel_rc(pp, 0x00000004, PCI_BASE_ADDRESS_1); | 801 | dw_pcie_writel_rc(pp, 0x00000000, PCI_BASE_ADDRESS_1); |
802 | 802 | ||
803 | /* setup interrupt pins */ | 803 | /* setup interrupt pins */ |
804 | dw_pcie_readl_rc(pp, PCI_INTERRUPT_LINE, &val); | 804 | dw_pcie_readl_rc(pp, PCI_INTERRUPT_LINE, &val); |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 828acf422c17..bccc27ee1030 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -424,7 +424,7 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
424 | */ | 424 | */ |
425 | static unsigned char acpiphp_max_busnr(struct pci_bus *bus) | 425 | static unsigned char acpiphp_max_busnr(struct pci_bus *bus) |
426 | { | 426 | { |
427 | struct list_head *tmp; | 427 | struct pci_bus *tmp; |
428 | unsigned char max, n; | 428 | unsigned char max, n; |
429 | 429 | ||
430 | /* | 430 | /* |
@@ -437,8 +437,8 @@ static unsigned char acpiphp_max_busnr(struct pci_bus *bus) | |||
437 | */ | 437 | */ |
438 | max = bus->busn_res.start; | 438 | max = bus->busn_res.start; |
439 | 439 | ||
440 | list_for_each(tmp, &bus->children) { | 440 | list_for_each_entry(tmp, &bus->children, node) { |
441 | n = pci_bus_max_busnr(pci_bus_b(tmp)); | 441 | n = pci_bus_max_busnr(tmp); |
442 | if (n > max) | 442 | if (n > max) |
443 | max = n; | 443 | max = n; |
444 | } | 444 | } |
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index 31273e155e6c..037e2612c5bd 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c | |||
@@ -920,12 +920,12 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
920 | bus->max_bus_speed = PCI_SPEED_100MHz_PCIX; | 920 | bus->max_bus_speed = PCI_SPEED_100MHz_PCIX; |
921 | break; | 921 | break; |
922 | } | 922 | } |
923 | if (bus_cap & 20) { | 923 | if (bus_cap & 0x20) { |
924 | dbg("bus max supports 66MHz PCI-X\n"); | 924 | dbg("bus max supports 66MHz PCI-X\n"); |
925 | bus->max_bus_speed = PCI_SPEED_66MHz_PCIX; | 925 | bus->max_bus_speed = PCI_SPEED_66MHz_PCIX; |
926 | break; | 926 | break; |
927 | } | 927 | } |
928 | if (bus_cap & 10) { | 928 | if (bus_cap & 0x10) { |
929 | dbg("bus max supports 66MHz PCI\n"); | 929 | dbg("bus max supports 66MHz PCI\n"); |
930 | bus->max_bus_speed = PCI_SPEED_66MHz; | 930 | bus->max_bus_speed = PCI_SPEED_66MHz; |
931 | break; | 931 | break; |
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 88b37cad4b35..8a66866b8cf1 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -76,6 +76,7 @@ struct slot { | |||
76 | struct hotplug_slot *hotplug_slot; | 76 | struct hotplug_slot *hotplug_slot; |
77 | struct delayed_work work; /* work for button event */ | 77 | struct delayed_work work; /* work for button event */ |
78 | struct mutex lock; | 78 | struct mutex lock; |
79 | struct mutex hotplug_lock; | ||
79 | struct workqueue_struct *wq; | 80 | struct workqueue_struct *wq; |
80 | }; | 81 | }; |
81 | 82 | ||
@@ -109,6 +110,8 @@ struct controller { | |||
109 | #define INT_BUTTON_PRESS 7 | 110 | #define INT_BUTTON_PRESS 7 |
110 | #define INT_BUTTON_RELEASE 8 | 111 | #define INT_BUTTON_RELEASE 8 |
111 | #define INT_BUTTON_CANCEL 9 | 112 | #define INT_BUTTON_CANCEL 9 |
113 | #define INT_LINK_UP 10 | ||
114 | #define INT_LINK_DOWN 11 | ||
112 | 115 | ||
113 | #define STATIC_STATE 0 | 116 | #define STATIC_STATE 0 |
114 | #define BLINKINGON_STATE 1 | 117 | #define BLINKINGON_STATE 1 |
@@ -132,6 +135,7 @@ u8 pciehp_handle_attention_button(struct slot *p_slot); | |||
132 | u8 pciehp_handle_switch_change(struct slot *p_slot); | 135 | u8 pciehp_handle_switch_change(struct slot *p_slot); |
133 | u8 pciehp_handle_presence_change(struct slot *p_slot); | 136 | u8 pciehp_handle_presence_change(struct slot *p_slot); |
134 | u8 pciehp_handle_power_fault(struct slot *p_slot); | 137 | u8 pciehp_handle_power_fault(struct slot *p_slot); |
138 | void pciehp_handle_linkstate_change(struct slot *p_slot); | ||
135 | int pciehp_configure_device(struct slot *p_slot); | 139 | int pciehp_configure_device(struct slot *p_slot); |
136 | int pciehp_unconfigure_device(struct slot *p_slot); | 140 | int pciehp_unconfigure_device(struct slot *p_slot); |
137 | void pciehp_queue_pushbutton_work(struct work_struct *work); | 141 | void pciehp_queue_pushbutton_work(struct work_struct *work); |
@@ -153,6 +157,7 @@ void pciehp_green_led_on(struct slot *slot); | |||
153 | void pciehp_green_led_off(struct slot *slot); | 157 | void pciehp_green_led_off(struct slot *slot); |
154 | void pciehp_green_led_blink(struct slot *slot); | 158 | void pciehp_green_led_blink(struct slot *slot); |
155 | int pciehp_check_link_status(struct controller *ctrl); | 159 | int pciehp_check_link_status(struct controller *ctrl); |
160 | bool pciehp_check_link_active(struct controller *ctrl); | ||
156 | void pciehp_release_ctrl(struct controller *ctrl); | 161 | void pciehp_release_ctrl(struct controller *ctrl); |
157 | int pciehp_reset_slot(struct slot *slot, int probe); | 162 | int pciehp_reset_slot(struct slot *slot, int probe); |
158 | 163 | ||
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c index eddddd447d0d..20fea57d2149 100644 --- a/drivers/pci/hotplug/pciehp_acpi.c +++ b/drivers/pci/hotplug/pciehp_acpi.c | |||
@@ -112,6 +112,7 @@ static struct pcie_port_service_driver __initdata dummy_driver = { | |||
112 | static int __init select_detection_mode(void) | 112 | static int __init select_detection_mode(void) |
113 | { | 113 | { |
114 | struct dummy_slot *slot, *tmp; | 114 | struct dummy_slot *slot, *tmp; |
115 | |||
115 | if (pcie_port_service_register(&dummy_driver)) | 116 | if (pcie_port_service_register(&dummy_driver)) |
116 | return PCIEHP_DETECT_ACPI; | 117 | return PCIEHP_DETECT_ACPI; |
117 | pcie_port_service_unregister(&dummy_driver); | 118 | pcie_port_service_unregister(&dummy_driver); |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 53b58debc288..0e0a2fff20a3 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -108,6 +108,7 @@ static int init_slot(struct controller *ctrl) | |||
108 | ops = kzalloc(sizeof(*ops), GFP_KERNEL); | 108 | ops = kzalloc(sizeof(*ops), GFP_KERNEL); |
109 | if (!ops) | 109 | if (!ops) |
110 | goto out; | 110 | goto out; |
111 | |||
111 | ops->enable_slot = enable_slot; | 112 | ops->enable_slot = enable_slot; |
112 | ops->disable_slot = disable_slot; | 113 | ops->disable_slot = disable_slot; |
113 | ops->get_power_status = get_power_status; | 114 | ops->get_power_status = get_power_status; |
@@ -283,8 +284,11 @@ static int pciehp_probe(struct pcie_device *dev) | |||
283 | slot = ctrl->slot; | 284 | slot = ctrl->slot; |
284 | pciehp_get_adapter_status(slot, &occupied); | 285 | pciehp_get_adapter_status(slot, &occupied); |
285 | pciehp_get_power_status(slot, &poweron); | 286 | pciehp_get_power_status(slot, &poweron); |
286 | if (occupied && pciehp_force) | 287 | if (occupied && pciehp_force) { |
288 | mutex_lock(&slot->hotplug_lock); | ||
287 | pciehp_enable_slot(slot); | 289 | pciehp_enable_slot(slot); |
290 | mutex_unlock(&slot->hotplug_lock); | ||
291 | } | ||
288 | /* If empty slot's power status is on, turn power off */ | 292 | /* If empty slot's power status is on, turn power off */ |
289 | if (!occupied && poweron && POWER_CTRL(ctrl)) | 293 | if (!occupied && poweron && POWER_CTRL(ctrl)) |
290 | pciehp_power_off_slot(slot); | 294 | pciehp_power_off_slot(slot); |
@@ -328,10 +332,12 @@ static int pciehp_resume (struct pcie_device *dev) | |||
328 | 332 | ||
329 | /* Check if slot is occupied */ | 333 | /* Check if slot is occupied */ |
330 | pciehp_get_adapter_status(slot, &status); | 334 | pciehp_get_adapter_status(slot, &status); |
335 | mutex_lock(&slot->hotplug_lock); | ||
331 | if (status) | 336 | if (status) |
332 | pciehp_enable_slot(slot); | 337 | pciehp_enable_slot(slot); |
333 | else | 338 | else |
334 | pciehp_disable_slot(slot); | 339 | pciehp_disable_slot(slot); |
340 | mutex_unlock(&slot->hotplug_lock); | ||
335 | return 0; | 341 | return 0; |
336 | } | 342 | } |
337 | #endif /* PM */ | 343 | #endif /* PM */ |
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 50628487597d..c75e6a678dcc 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
@@ -150,6 +150,27 @@ u8 pciehp_handle_power_fault(struct slot *p_slot) | |||
150 | return 1; | 150 | return 1; |
151 | } | 151 | } |
152 | 152 | ||
153 | void pciehp_handle_linkstate_change(struct slot *p_slot) | ||
154 | { | ||
155 | u32 event_type; | ||
156 | struct controller *ctrl = p_slot->ctrl; | ||
157 | |||
158 | /* Link Status Change */ | ||
159 | ctrl_dbg(ctrl, "Data Link Layer State change\n"); | ||
160 | |||
161 | if (pciehp_check_link_active(ctrl)) { | ||
162 | ctrl_info(ctrl, "slot(%s): Link Up event\n", | ||
163 | slot_name(p_slot)); | ||
164 | event_type = INT_LINK_UP; | ||
165 | } else { | ||
166 | ctrl_info(ctrl, "slot(%s): Link Down event\n", | ||
167 | slot_name(p_slot)); | ||
168 | event_type = INT_LINK_DOWN; | ||
169 | } | ||
170 | |||
171 | queue_interrupt_event(p_slot, event_type); | ||
172 | } | ||
173 | |||
153 | /* The following routines constitute the bulk of the | 174 | /* The following routines constitute the bulk of the |
154 | hotplug controller logic | 175 | hotplug controller logic |
155 | */ | 176 | */ |
@@ -212,7 +233,8 @@ static int board_added(struct slot *p_slot) | |||
212 | if (retval) { | 233 | if (retval) { |
213 | ctrl_err(ctrl, "Cannot add device at %04x:%02x:00\n", | 234 | ctrl_err(ctrl, "Cannot add device at %04x:%02x:00\n", |
214 | pci_domain_nr(parent), parent->number); | 235 | pci_domain_nr(parent), parent->number); |
215 | goto err_exit; | 236 | if (retval != -EEXIST) |
237 | goto err_exit; | ||
216 | } | 238 | } |
217 | 239 | ||
218 | pciehp_green_led_on(p_slot); | 240 | pciehp_green_led_on(p_slot); |
@@ -255,6 +277,9 @@ static int remove_board(struct slot *p_slot) | |||
255 | struct power_work_info { | 277 | struct power_work_info { |
256 | struct slot *p_slot; | 278 | struct slot *p_slot; |
257 | struct work_struct work; | 279 | struct work_struct work; |
280 | unsigned int req; | ||
281 | #define DISABLE_REQ 0 | ||
282 | #define ENABLE_REQ 1 | ||
258 | }; | 283 | }; |
259 | 284 | ||
260 | /** | 285 | /** |
@@ -269,30 +294,38 @@ static void pciehp_power_thread(struct work_struct *work) | |||
269 | struct power_work_info *info = | 294 | struct power_work_info *info = |
270 | container_of(work, struct power_work_info, work); | 295 | container_of(work, struct power_work_info, work); |
271 | struct slot *p_slot = info->p_slot; | 296 | struct slot *p_slot = info->p_slot; |
297 | int ret; | ||
272 | 298 | ||
273 | mutex_lock(&p_slot->lock); | 299 | switch (info->req) { |
274 | switch (p_slot->state) { | 300 | case DISABLE_REQ: |
275 | case POWEROFF_STATE: | ||
276 | mutex_unlock(&p_slot->lock); | ||
277 | ctrl_dbg(p_slot->ctrl, | 301 | ctrl_dbg(p_slot->ctrl, |
278 | "Disabling domain:bus:device=%04x:%02x:00\n", | 302 | "Disabling domain:bus:device=%04x:%02x:00\n", |
279 | pci_domain_nr(p_slot->ctrl->pcie->port->subordinate), | 303 | pci_domain_nr(p_slot->ctrl->pcie->port->subordinate), |
280 | p_slot->ctrl->pcie->port->subordinate->number); | 304 | p_slot->ctrl->pcie->port->subordinate->number); |
305 | mutex_lock(&p_slot->hotplug_lock); | ||
281 | pciehp_disable_slot(p_slot); | 306 | pciehp_disable_slot(p_slot); |
307 | mutex_unlock(&p_slot->hotplug_lock); | ||
282 | mutex_lock(&p_slot->lock); | 308 | mutex_lock(&p_slot->lock); |
283 | p_slot->state = STATIC_STATE; | 309 | p_slot->state = STATIC_STATE; |
284 | break; | ||
285 | case POWERON_STATE: | ||
286 | mutex_unlock(&p_slot->lock); | 310 | mutex_unlock(&p_slot->lock); |
287 | if (pciehp_enable_slot(p_slot)) | 311 | break; |
312 | case ENABLE_REQ: | ||
313 | ctrl_dbg(p_slot->ctrl, | ||
314 | "Enabling domain:bus:device=%04x:%02x:00\n", | ||
315 | pci_domain_nr(p_slot->ctrl->pcie->port->subordinate), | ||
316 | p_slot->ctrl->pcie->port->subordinate->number); | ||
317 | mutex_lock(&p_slot->hotplug_lock); | ||
318 | ret = pciehp_enable_slot(p_slot); | ||
319 | mutex_unlock(&p_slot->hotplug_lock); | ||
320 | if (ret) | ||
288 | pciehp_green_led_off(p_slot); | 321 | pciehp_green_led_off(p_slot); |
289 | mutex_lock(&p_slot->lock); | 322 | mutex_lock(&p_slot->lock); |
290 | p_slot->state = STATIC_STATE; | 323 | p_slot->state = STATIC_STATE; |
324 | mutex_unlock(&p_slot->lock); | ||
291 | break; | 325 | break; |
292 | default: | 326 | default: |
293 | break; | 327 | break; |
294 | } | 328 | } |
295 | mutex_unlock(&p_slot->lock); | ||
296 | 329 | ||
297 | kfree(info); | 330 | kfree(info); |
298 | } | 331 | } |
@@ -315,9 +348,11 @@ void pciehp_queue_pushbutton_work(struct work_struct *work) | |||
315 | switch (p_slot->state) { | 348 | switch (p_slot->state) { |
316 | case BLINKINGOFF_STATE: | 349 | case BLINKINGOFF_STATE: |
317 | p_slot->state = POWEROFF_STATE; | 350 | p_slot->state = POWEROFF_STATE; |
351 | info->req = DISABLE_REQ; | ||
318 | break; | 352 | break; |
319 | case BLINKINGON_STATE: | 353 | case BLINKINGON_STATE: |
320 | p_slot->state = POWERON_STATE; | 354 | p_slot->state = POWERON_STATE; |
355 | info->req = ENABLE_REQ; | ||
321 | break; | 356 | break; |
322 | default: | 357 | default: |
323 | kfree(info); | 358 | kfree(info); |
@@ -364,11 +399,10 @@ static void handle_button_press_event(struct slot *p_slot) | |||
364 | */ | 399 | */ |
365 | ctrl_info(ctrl, "Button cancel on Slot(%s)\n", slot_name(p_slot)); | 400 | ctrl_info(ctrl, "Button cancel on Slot(%s)\n", slot_name(p_slot)); |
366 | cancel_delayed_work(&p_slot->work); | 401 | cancel_delayed_work(&p_slot->work); |
367 | if (p_slot->state == BLINKINGOFF_STATE) { | 402 | if (p_slot->state == BLINKINGOFF_STATE) |
368 | pciehp_green_led_on(p_slot); | 403 | pciehp_green_led_on(p_slot); |
369 | } else { | 404 | else |
370 | pciehp_green_led_off(p_slot); | 405 | pciehp_green_led_off(p_slot); |
371 | } | ||
372 | pciehp_set_attention_status(p_slot, 0); | 406 | pciehp_set_attention_status(p_slot, 0); |
373 | ctrl_info(ctrl, "PCI slot #%s - action canceled " | 407 | ctrl_info(ctrl, "PCI slot #%s - action canceled " |
374 | "due to button press\n", slot_name(p_slot)); | 408 | "due to button press\n", slot_name(p_slot)); |
@@ -407,14 +441,81 @@ static void handle_surprise_event(struct slot *p_slot) | |||
407 | INIT_WORK(&info->work, pciehp_power_thread); | 441 | INIT_WORK(&info->work, pciehp_power_thread); |
408 | 442 | ||
409 | pciehp_get_adapter_status(p_slot, &getstatus); | 443 | pciehp_get_adapter_status(p_slot, &getstatus); |
410 | if (!getstatus) | 444 | if (!getstatus) { |
411 | p_slot->state = POWEROFF_STATE; | 445 | p_slot->state = POWEROFF_STATE; |
412 | else | 446 | info->req = DISABLE_REQ; |
447 | } else { | ||
413 | p_slot->state = POWERON_STATE; | 448 | p_slot->state = POWERON_STATE; |
449 | info->req = ENABLE_REQ; | ||
450 | } | ||
414 | 451 | ||
415 | queue_work(p_slot->wq, &info->work); | 452 | queue_work(p_slot->wq, &info->work); |
416 | } | 453 | } |
417 | 454 | ||
455 | /* | ||
456 | * Note: This function must be called with slot->lock held | ||
457 | */ | ||
458 | static void handle_link_event(struct slot *p_slot, u32 event) | ||
459 | { | ||
460 | struct controller *ctrl = p_slot->ctrl; | ||
461 | struct power_work_info *info; | ||
462 | |||
463 | info = kmalloc(sizeof(*info), GFP_KERNEL); | ||
464 | if (!info) { | ||
465 | ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n", | ||
466 | __func__); | ||
467 | return; | ||
468 | } | ||
469 | info->p_slot = p_slot; | ||
470 | info->req = event == INT_LINK_UP ? ENABLE_REQ : DISABLE_REQ; | ||
471 | INIT_WORK(&info->work, pciehp_power_thread); | ||
472 | |||
473 | switch (p_slot->state) { | ||
474 | case BLINKINGON_STATE: | ||
475 | case BLINKINGOFF_STATE: | ||
476 | cancel_delayed_work(&p_slot->work); | ||
477 | /* Fall through */ | ||
478 | case STATIC_STATE: | ||
479 | p_slot->state = event == INT_LINK_UP ? | ||
480 | POWERON_STATE : POWEROFF_STATE; | ||
481 | queue_work(p_slot->wq, &info->work); | ||
482 | break; | ||
483 | case POWERON_STATE: | ||
484 | if (event == INT_LINK_UP) { | ||
485 | ctrl_info(ctrl, | ||
486 | "Link Up event ignored on slot(%s): already powering on\n", | ||
487 | slot_name(p_slot)); | ||
488 | kfree(info); | ||
489 | } else { | ||
490 | ctrl_info(ctrl, | ||
491 | "Link Down event queued on slot(%s): currently getting powered on\n", | ||
492 | slot_name(p_slot)); | ||
493 | p_slot->state = POWEROFF_STATE; | ||
494 | queue_work(p_slot->wq, &info->work); | ||
495 | } | ||
496 | break; | ||
497 | case POWEROFF_STATE: | ||
498 | if (event == INT_LINK_UP) { | ||
499 | ctrl_info(ctrl, | ||
500 | "Link Up event queued on slot(%s): currently getting powered off\n", | ||
501 | slot_name(p_slot)); | ||
502 | p_slot->state = POWERON_STATE; | ||
503 | queue_work(p_slot->wq, &info->work); | ||
504 | } else { | ||
505 | ctrl_info(ctrl, | ||
506 | "Link Down event ignored on slot(%s): already powering off\n", | ||
507 | slot_name(p_slot)); | ||
508 | kfree(info); | ||
509 | } | ||
510 | break; | ||
511 | default: | ||
512 | ctrl_err(ctrl, "Not a valid state on slot(%s)\n", | ||
513 | slot_name(p_slot)); | ||
514 | kfree(info); | ||
515 | break; | ||
516 | } | ||
517 | } | ||
518 | |||
418 | static void interrupt_event_handler(struct work_struct *work) | 519 | static void interrupt_event_handler(struct work_struct *work) |
419 | { | 520 | { |
420 | struct event_info *info = container_of(work, struct event_info, work); | 521 | struct event_info *info = container_of(work, struct event_info, work); |
@@ -433,12 +534,23 @@ static void interrupt_event_handler(struct work_struct *work) | |||
433 | pciehp_green_led_off(p_slot); | 534 | pciehp_green_led_off(p_slot); |
434 | break; | 535 | break; |
435 | case INT_PRESENCE_ON: | 536 | case INT_PRESENCE_ON: |
436 | case INT_PRESENCE_OFF: | ||
437 | if (!HP_SUPR_RM(ctrl)) | 537 | if (!HP_SUPR_RM(ctrl)) |
438 | break; | 538 | break; |
539 | ctrl_dbg(ctrl, "Surprise Insertion\n"); | ||
540 | handle_surprise_event(p_slot); | ||
541 | break; | ||
542 | case INT_PRESENCE_OFF: | ||
543 | /* | ||
544 | * Regardless of surprise capability, we need to | ||
545 | * definitely remove a card that has been pulled out! | ||
546 | */ | ||
439 | ctrl_dbg(ctrl, "Surprise Removal\n"); | 547 | ctrl_dbg(ctrl, "Surprise Removal\n"); |
440 | handle_surprise_event(p_slot); | 548 | handle_surprise_event(p_slot); |
441 | break; | 549 | break; |
550 | case INT_LINK_UP: | ||
551 | case INT_LINK_DOWN: | ||
552 | handle_link_event(p_slot, info->event_type); | ||
553 | break; | ||
442 | default: | 554 | default: |
443 | break; | 555 | break; |
444 | } | 556 | } |
@@ -447,6 +559,9 @@ static void interrupt_event_handler(struct work_struct *work) | |||
447 | kfree(info); | 559 | kfree(info); |
448 | } | 560 | } |
449 | 561 | ||
562 | /* | ||
563 | * Note: This function must be called with slot->hotplug_lock held | ||
564 | */ | ||
450 | int pciehp_enable_slot(struct slot *p_slot) | 565 | int pciehp_enable_slot(struct slot *p_slot) |
451 | { | 566 | { |
452 | u8 getstatus = 0; | 567 | u8 getstatus = 0; |
@@ -479,13 +594,15 @@ int pciehp_enable_slot(struct slot *p_slot) | |||
479 | pciehp_get_latch_status(p_slot, &getstatus); | 594 | pciehp_get_latch_status(p_slot, &getstatus); |
480 | 595 | ||
481 | rc = board_added(p_slot); | 596 | rc = board_added(p_slot); |
482 | if (rc) { | 597 | if (rc) |
483 | pciehp_get_latch_status(p_slot, &getstatus); | 598 | pciehp_get_latch_status(p_slot, &getstatus); |
484 | } | 599 | |
485 | return rc; | 600 | return rc; |
486 | } | 601 | } |
487 | 602 | ||
488 | 603 | /* | |
604 | * Note: This function must be called with slot->hotplug_lock held | ||
605 | */ | ||
489 | int pciehp_disable_slot(struct slot *p_slot) | 606 | int pciehp_disable_slot(struct slot *p_slot) |
490 | { | 607 | { |
491 | u8 getstatus = 0; | 608 | u8 getstatus = 0; |
@@ -494,24 +611,6 @@ int pciehp_disable_slot(struct slot *p_slot) | |||
494 | if (!p_slot->ctrl) | 611 | if (!p_slot->ctrl) |
495 | return 1; | 612 | return 1; |
496 | 613 | ||
497 | if (!HP_SUPR_RM(p_slot->ctrl)) { | ||
498 | pciehp_get_adapter_status(p_slot, &getstatus); | ||
499 | if (!getstatus) { | ||
500 | ctrl_info(ctrl, "No adapter on slot(%s)\n", | ||
501 | slot_name(p_slot)); | ||
502 | return -ENODEV; | ||
503 | } | ||
504 | } | ||
505 | |||
506 | if (MRL_SENS(p_slot->ctrl)) { | ||
507 | pciehp_get_latch_status(p_slot, &getstatus); | ||
508 | if (getstatus) { | ||
509 | ctrl_info(ctrl, "Latch open on slot(%s)\n", | ||
510 | slot_name(p_slot)); | ||
511 | return -ENODEV; | ||
512 | } | ||
513 | } | ||
514 | |||
515 | if (POWER_CTRL(p_slot->ctrl)) { | 614 | if (POWER_CTRL(p_slot->ctrl)) { |
516 | pciehp_get_power_status(p_slot, &getstatus); | 615 | pciehp_get_power_status(p_slot, &getstatus); |
517 | if (!getstatus) { | 616 | if (!getstatus) { |
@@ -536,7 +635,9 @@ int pciehp_sysfs_enable_slot(struct slot *p_slot) | |||
536 | case STATIC_STATE: | 635 | case STATIC_STATE: |
537 | p_slot->state = POWERON_STATE; | 636 | p_slot->state = POWERON_STATE; |
538 | mutex_unlock(&p_slot->lock); | 637 | mutex_unlock(&p_slot->lock); |
638 | mutex_lock(&p_slot->hotplug_lock); | ||
539 | retval = pciehp_enable_slot(p_slot); | 639 | retval = pciehp_enable_slot(p_slot); |
640 | mutex_unlock(&p_slot->hotplug_lock); | ||
540 | mutex_lock(&p_slot->lock); | 641 | mutex_lock(&p_slot->lock); |
541 | p_slot->state = STATIC_STATE; | 642 | p_slot->state = STATIC_STATE; |
542 | break; | 643 | break; |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 14acfccb7670..d7d058fa19a4 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -206,7 +206,7 @@ static void pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) | |||
206 | mutex_unlock(&ctrl->ctrl_lock); | 206 | mutex_unlock(&ctrl->ctrl_lock); |
207 | } | 207 | } |
208 | 208 | ||
209 | static bool check_link_active(struct controller *ctrl) | 209 | bool pciehp_check_link_active(struct controller *ctrl) |
210 | { | 210 | { |
211 | struct pci_dev *pdev = ctrl_dev(ctrl); | 211 | struct pci_dev *pdev = ctrl_dev(ctrl); |
212 | u16 lnk_status; | 212 | u16 lnk_status; |
@@ -225,12 +225,12 @@ static void __pcie_wait_link_active(struct controller *ctrl, bool active) | |||
225 | { | 225 | { |
226 | int timeout = 1000; | 226 | int timeout = 1000; |
227 | 227 | ||
228 | if (check_link_active(ctrl) == active) | 228 | if (pciehp_check_link_active(ctrl) == active) |
229 | return; | 229 | return; |
230 | while (timeout > 0) { | 230 | while (timeout > 0) { |
231 | msleep(10); | 231 | msleep(10); |
232 | timeout -= 10; | 232 | timeout -= 10; |
233 | if (check_link_active(ctrl) == active) | 233 | if (pciehp_check_link_active(ctrl) == active) |
234 | return; | 234 | return; |
235 | } | 235 | } |
236 | ctrl_dbg(ctrl, "Data Link Layer Link Active not %s in 1000 msec\n", | 236 | ctrl_dbg(ctrl, "Data Link Layer Link Active not %s in 1000 msec\n", |
@@ -242,11 +242,6 @@ static void pcie_wait_link_active(struct controller *ctrl) | |||
242 | __pcie_wait_link_active(ctrl, true); | 242 | __pcie_wait_link_active(ctrl, true); |
243 | } | 243 | } |
244 | 244 | ||
245 | static void pcie_wait_link_not_active(struct controller *ctrl) | ||
246 | { | ||
247 | __pcie_wait_link_active(ctrl, false); | ||
248 | } | ||
249 | |||
250 | static bool pci_bus_check_dev(struct pci_bus *bus, int devfn) | 245 | static bool pci_bus_check_dev(struct pci_bus *bus, int devfn) |
251 | { | 246 | { |
252 | u32 l; | 247 | u32 l; |
@@ -332,11 +327,6 @@ static int pciehp_link_enable(struct controller *ctrl) | |||
332 | return __pciehp_link_set(ctrl, true); | 327 | return __pciehp_link_set(ctrl, true); |
333 | } | 328 | } |
334 | 329 | ||
335 | static int pciehp_link_disable(struct controller *ctrl) | ||
336 | { | ||
337 | return __pciehp_link_set(ctrl, false); | ||
338 | } | ||
339 | |||
340 | void pciehp_get_attention_status(struct slot *slot, u8 *status) | 330 | void pciehp_get_attention_status(struct slot *slot, u8 *status) |
341 | { | 331 | { |
342 | struct controller *ctrl = slot->ctrl; | 332 | struct controller *ctrl = slot->ctrl; |
@@ -508,14 +498,6 @@ void pciehp_power_off_slot(struct slot * slot) | |||
508 | { | 498 | { |
509 | struct controller *ctrl = slot->ctrl; | 499 | struct controller *ctrl = slot->ctrl; |
510 | 500 | ||
511 | /* Disable the link at first */ | ||
512 | pciehp_link_disable(ctrl); | ||
513 | /* wait the link is down */ | ||
514 | if (ctrl->link_active_reporting) | ||
515 | pcie_wait_link_not_active(ctrl); | ||
516 | else | ||
517 | msleep(1000); | ||
518 | |||
519 | pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_OFF, PCI_EXP_SLTCTL_PCC); | 501 | pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_OFF, PCI_EXP_SLTCTL_PCC); |
520 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, | 502 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
521 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, | 503 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, |
@@ -540,7 +522,7 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
540 | 522 | ||
541 | detected &= (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD | | 523 | detected &= (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD | |
542 | PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC | | 524 | PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC | |
543 | PCI_EXP_SLTSTA_CC); | 525 | PCI_EXP_SLTSTA_CC | PCI_EXP_SLTSTA_DLLSC); |
544 | detected &= ~intr_loc; | 526 | detected &= ~intr_loc; |
545 | intr_loc |= detected; | 527 | intr_loc |= detected; |
546 | if (!intr_loc) | 528 | if (!intr_loc) |
@@ -579,6 +561,10 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
579 | ctrl->power_fault_detected = 1; | 561 | ctrl->power_fault_detected = 1; |
580 | pciehp_handle_power_fault(slot); | 562 | pciehp_handle_power_fault(slot); |
581 | } | 563 | } |
564 | |||
565 | if (intr_loc & PCI_EXP_SLTSTA_DLLSC) | ||
566 | pciehp_handle_linkstate_change(slot); | ||
567 | |||
582 | return IRQ_HANDLED; | 568 | return IRQ_HANDLED; |
583 | } | 569 | } |
584 | 570 | ||
@@ -596,9 +582,17 @@ void pcie_enable_notification(struct controller *ctrl) | |||
596 | * when it is cleared in the interrupt service routine, and | 582 | * when it is cleared in the interrupt service routine, and |
597 | * next power fault detected interrupt was notified again. | 583 | * next power fault detected interrupt was notified again. |
598 | */ | 584 | */ |
599 | cmd = PCI_EXP_SLTCTL_PDCE; | 585 | |
586 | /* | ||
587 | * Always enable link events: thus link-up and link-down shall | ||
588 | * always be treated as hotplug and unplug respectively. Enable | ||
589 | * presence detect only if Attention Button is not present. | ||
590 | */ | ||
591 | cmd = PCI_EXP_SLTCTL_DLLSCE; | ||
600 | if (ATTN_BUTTN(ctrl)) | 592 | if (ATTN_BUTTN(ctrl)) |
601 | cmd |= PCI_EXP_SLTCTL_ABPE; | 593 | cmd |= PCI_EXP_SLTCTL_ABPE; |
594 | else | ||
595 | cmd |= PCI_EXP_SLTCTL_PDCE; | ||
602 | if (MRL_SENS(ctrl)) | 596 | if (MRL_SENS(ctrl)) |
603 | cmd |= PCI_EXP_SLTCTL_MRLSCE; | 597 | cmd |= PCI_EXP_SLTCTL_MRLSCE; |
604 | if (!pciehp_poll_mode) | 598 | if (!pciehp_poll_mode) |
@@ -606,7 +600,8 @@ void pcie_enable_notification(struct controller *ctrl) | |||
606 | 600 | ||
607 | mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE | | 601 | mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE | |
608 | PCI_EXP_SLTCTL_MRLSCE | PCI_EXP_SLTCTL_PFDE | | 602 | PCI_EXP_SLTCTL_MRLSCE | PCI_EXP_SLTCTL_PFDE | |
609 | PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE); | 603 | PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE | |
604 | PCI_EXP_SLTCTL_DLLSCE); | ||
610 | 605 | ||
611 | pcie_write_cmd(ctrl, cmd, mask); | 606 | pcie_write_cmd(ctrl, cmd, mask); |
612 | } | 607 | } |
@@ -624,33 +619,38 @@ static void pcie_disable_notification(struct controller *ctrl) | |||
624 | 619 | ||
625 | /* | 620 | /* |
626 | * pciehp has a 1:1 bus:slot relationship so we ultimately want a secondary | 621 | * pciehp has a 1:1 bus:slot relationship so we ultimately want a secondary |
627 | * bus reset of the bridge, but if the slot supports surprise removal we need | 622 | * bus reset of the bridge, but at the same time we want to ensure that it is |
628 | * to disable presence detection around the bus reset and clear any spurious | 623 | * not seen as a hot-unplug, followed by the hot-plug of the device. Thus, |
624 | * disable link state notification and presence detection change notification | ||
625 | * momentarily, if we see that they could interfere. Also, clear any spurious | ||
629 | * events after. | 626 | * events after. |
630 | */ | 627 | */ |
631 | int pciehp_reset_slot(struct slot *slot, int probe) | 628 | int pciehp_reset_slot(struct slot *slot, int probe) |
632 | { | 629 | { |
633 | struct controller *ctrl = slot->ctrl; | 630 | struct controller *ctrl = slot->ctrl; |
634 | struct pci_dev *pdev = ctrl_dev(ctrl); | 631 | struct pci_dev *pdev = ctrl_dev(ctrl); |
632 | u16 stat_mask = 0, ctrl_mask = 0; | ||
635 | 633 | ||
636 | if (probe) | 634 | if (probe) |
637 | return 0; | 635 | return 0; |
638 | 636 | ||
639 | if (HP_SUPR_RM(ctrl)) { | 637 | if (!ATTN_BUTTN(ctrl)) { |
640 | pcie_write_cmd(ctrl, 0, PCI_EXP_SLTCTL_PDCE); | 638 | ctrl_mask |= PCI_EXP_SLTCTL_PDCE; |
641 | if (pciehp_poll_mode) | 639 | stat_mask |= PCI_EXP_SLTSTA_PDC; |
642 | del_timer_sync(&ctrl->poll_timer); | ||
643 | } | 640 | } |
641 | ctrl_mask |= PCI_EXP_SLTCTL_DLLSCE; | ||
642 | stat_mask |= PCI_EXP_SLTSTA_DLLSC; | ||
643 | |||
644 | pcie_write_cmd(ctrl, 0, ctrl_mask); | ||
645 | if (pciehp_poll_mode) | ||
646 | del_timer_sync(&ctrl->poll_timer); | ||
644 | 647 | ||
645 | pci_reset_bridge_secondary_bus(ctrl->pcie->port); | 648 | pci_reset_bridge_secondary_bus(ctrl->pcie->port); |
646 | 649 | ||
647 | if (HP_SUPR_RM(ctrl)) { | 650 | pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, stat_mask); |
648 | pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, | 651 | pcie_write_cmd(ctrl, ctrl_mask, ctrl_mask); |
649 | PCI_EXP_SLTSTA_PDC); | 652 | if (pciehp_poll_mode) |
650 | pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PDCE, PCI_EXP_SLTCTL_PDCE); | 653 | int_poll_timeout(ctrl->poll_timer.data); |
651 | if (pciehp_poll_mode) | ||
652 | int_poll_timeout(ctrl->poll_timer.data); | ||
653 | } | ||
654 | 654 | ||
655 | return 0; | 655 | return 0; |
656 | } | 656 | } |
@@ -687,6 +687,7 @@ static int pcie_init_slot(struct controller *ctrl) | |||
687 | 687 | ||
688 | slot->ctrl = ctrl; | 688 | slot->ctrl = ctrl; |
689 | mutex_init(&slot->lock); | 689 | mutex_init(&slot->lock); |
690 | mutex_init(&slot->hotplug_lock); | ||
690 | INIT_DELAYED_WORK(&slot->work, pciehp_queue_pushbutton_work); | 691 | INIT_DELAYED_WORK(&slot->work, pciehp_queue_pushbutton_work); |
691 | ctrl->slot = slot; | 692 | ctrl->slot = slot; |
692 | return 0; | 693 | return 0; |
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index b07d7cc2d697..1b533060ce65 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c | |||
@@ -50,7 +50,7 @@ int pciehp_configure_device(struct slot *p_slot) | |||
50 | "at %04x:%02x:00, cannot hot-add\n", pci_name(dev), | 50 | "at %04x:%02x:00, cannot hot-add\n", pci_name(dev), |
51 | pci_domain_nr(parent), parent->number); | 51 | pci_domain_nr(parent), parent->number); |
52 | pci_dev_put(dev); | 52 | pci_dev_put(dev); |
53 | ret = -EINVAL; | 53 | ret = -EEXIST; |
54 | goto out; | 54 | goto out; |
55 | } | 55 | } |
56 | 56 | ||
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 9dce7c5e2a77..de7a74782f92 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
@@ -170,97 +170,6 @@ static void virtfn_remove(struct pci_dev *dev, int id, int reset) | |||
170 | pci_dev_put(dev); | 170 | pci_dev_put(dev); |
171 | } | 171 | } |
172 | 172 | ||
173 | static int sriov_migration(struct pci_dev *dev) | ||
174 | { | ||
175 | u16 status; | ||
176 | struct pci_sriov *iov = dev->sriov; | ||
177 | |||
178 | if (!iov->num_VFs) | ||
179 | return 0; | ||
180 | |||
181 | if (!(iov->cap & PCI_SRIOV_CAP_VFM)) | ||
182 | return 0; | ||
183 | |||
184 | pci_read_config_word(dev, iov->pos + PCI_SRIOV_STATUS, &status); | ||
185 | if (!(status & PCI_SRIOV_STATUS_VFM)) | ||
186 | return 0; | ||
187 | |||
188 | schedule_work(&iov->mtask); | ||
189 | |||
190 | return 1; | ||
191 | } | ||
192 | |||
193 | static void sriov_migration_task(struct work_struct *work) | ||
194 | { | ||
195 | int i; | ||
196 | u8 state; | ||
197 | u16 status; | ||
198 | struct pci_sriov *iov = container_of(work, struct pci_sriov, mtask); | ||
199 | |||
200 | for (i = iov->initial_VFs; i < iov->num_VFs; i++) { | ||
201 | state = readb(iov->mstate + i); | ||
202 | if (state == PCI_SRIOV_VFM_MI) { | ||
203 | writeb(PCI_SRIOV_VFM_AV, iov->mstate + i); | ||
204 | state = readb(iov->mstate + i); | ||
205 | if (state == PCI_SRIOV_VFM_AV) | ||
206 | virtfn_add(iov->self, i, 1); | ||
207 | } else if (state == PCI_SRIOV_VFM_MO) { | ||
208 | virtfn_remove(iov->self, i, 1); | ||
209 | writeb(PCI_SRIOV_VFM_UA, iov->mstate + i); | ||
210 | state = readb(iov->mstate + i); | ||
211 | if (state == PCI_SRIOV_VFM_AV) | ||
212 | virtfn_add(iov->self, i, 0); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | pci_read_config_word(iov->self, iov->pos + PCI_SRIOV_STATUS, &status); | ||
217 | status &= ~PCI_SRIOV_STATUS_VFM; | ||
218 | pci_write_config_word(iov->self, iov->pos + PCI_SRIOV_STATUS, status); | ||
219 | } | ||
220 | |||
221 | static int sriov_enable_migration(struct pci_dev *dev, int nr_virtfn) | ||
222 | { | ||
223 | int bir; | ||
224 | u32 table; | ||
225 | resource_size_t pa; | ||
226 | struct pci_sriov *iov = dev->sriov; | ||
227 | |||
228 | if (nr_virtfn <= iov->initial_VFs) | ||
229 | return 0; | ||
230 | |||
231 | pci_read_config_dword(dev, iov->pos + PCI_SRIOV_VFM, &table); | ||
232 | bir = PCI_SRIOV_VFM_BIR(table); | ||
233 | if (bir > PCI_STD_RESOURCE_END) | ||
234 | return -EIO; | ||
235 | |||
236 | table = PCI_SRIOV_VFM_OFFSET(table); | ||
237 | if (table + nr_virtfn > pci_resource_len(dev, bir)) | ||
238 | return -EIO; | ||
239 | |||
240 | pa = pci_resource_start(dev, bir) + table; | ||
241 | iov->mstate = ioremap(pa, nr_virtfn); | ||
242 | if (!iov->mstate) | ||
243 | return -ENOMEM; | ||
244 | |||
245 | INIT_WORK(&iov->mtask, sriov_migration_task); | ||
246 | |||
247 | iov->ctrl |= PCI_SRIOV_CTRL_VFM | PCI_SRIOV_CTRL_INTR; | ||
248 | pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); | ||
249 | |||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | static void sriov_disable_migration(struct pci_dev *dev) | ||
254 | { | ||
255 | struct pci_sriov *iov = dev->sriov; | ||
256 | |||
257 | iov->ctrl &= ~(PCI_SRIOV_CTRL_VFM | PCI_SRIOV_CTRL_INTR); | ||
258 | pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); | ||
259 | |||
260 | cancel_work_sync(&iov->mtask); | ||
261 | iounmap(iov->mstate); | ||
262 | } | ||
263 | |||
264 | static int sriov_enable(struct pci_dev *dev, int nr_virtfn) | 173 | static int sriov_enable(struct pci_dev *dev, int nr_virtfn) |
265 | { | 174 | { |
266 | int rc; | 175 | int rc; |
@@ -351,12 +260,6 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) | |||
351 | goto failed; | 260 | goto failed; |
352 | } | 261 | } |
353 | 262 | ||
354 | if (iov->cap & PCI_SRIOV_CAP_VFM) { | ||
355 | rc = sriov_enable_migration(dev, nr_virtfn); | ||
356 | if (rc) | ||
357 | goto failed; | ||
358 | } | ||
359 | |||
360 | kobject_uevent(&dev->dev.kobj, KOBJ_CHANGE); | 263 | kobject_uevent(&dev->dev.kobj, KOBJ_CHANGE); |
361 | iov->num_VFs = nr_virtfn; | 264 | iov->num_VFs = nr_virtfn; |
362 | 265 | ||
@@ -387,9 +290,6 @@ static void sriov_disable(struct pci_dev *dev) | |||
387 | if (!iov->num_VFs) | 290 | if (!iov->num_VFs) |
388 | return; | 291 | return; |
389 | 292 | ||
390 | if (iov->cap & PCI_SRIOV_CAP_VFM) | ||
391 | sriov_disable_migration(dev); | ||
392 | |||
393 | for (i = 0; i < iov->num_VFs; i++) | 293 | for (i = 0; i < iov->num_VFs; i++) |
394 | virtfn_remove(dev, i, 0); | 294 | virtfn_remove(dev, i, 0); |
395 | 295 | ||
@@ -688,25 +588,6 @@ void pci_disable_sriov(struct pci_dev *dev) | |||
688 | EXPORT_SYMBOL_GPL(pci_disable_sriov); | 588 | EXPORT_SYMBOL_GPL(pci_disable_sriov); |
689 | 589 | ||
690 | /** | 590 | /** |
691 | * pci_sriov_migration - notify SR-IOV core of Virtual Function Migration | ||
692 | * @dev: the PCI device | ||
693 | * | ||
694 | * Returns IRQ_HANDLED if the IRQ is handled, or IRQ_NONE if not. | ||
695 | * | ||
696 | * Physical Function driver is responsible to register IRQ handler using | ||
697 | * VF Migration Interrupt Message Number, and call this function when the | ||
698 | * interrupt is generated by the hardware. | ||
699 | */ | ||
700 | irqreturn_t pci_sriov_migration(struct pci_dev *dev) | ||
701 | { | ||
702 | if (!dev->is_physfn) | ||
703 | return IRQ_NONE; | ||
704 | |||
705 | return sriov_migration(dev) ? IRQ_HANDLED : IRQ_NONE; | ||
706 | } | ||
707 | EXPORT_SYMBOL_GPL(pci_sriov_migration); | ||
708 | |||
709 | /** | ||
710 | * pci_num_vf - return number of VFs associated with a PF device_release_driver | 591 | * pci_num_vf - return number of VFs associated with a PF device_release_driver |
711 | * @dev: the PCI device | 592 | * @dev: the PCI device |
712 | * | 593 | * |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index fdbc294821e6..7325d43bf030 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -108,12 +108,12 @@ static bool pcie_ari_disabled; | |||
108 | */ | 108 | */ |
109 | unsigned char pci_bus_max_busnr(struct pci_bus* bus) | 109 | unsigned char pci_bus_max_busnr(struct pci_bus* bus) |
110 | { | 110 | { |
111 | struct list_head *tmp; | 111 | struct pci_bus *tmp; |
112 | unsigned char max, n; | 112 | unsigned char max, n; |
113 | 113 | ||
114 | max = bus->busn_res.end; | 114 | max = bus->busn_res.end; |
115 | list_for_each(tmp, &bus->children) { | 115 | list_for_each_entry(tmp, &bus->children, node) { |
116 | n = pci_bus_max_busnr(pci_bus_b(tmp)); | 116 | n = pci_bus_max_busnr(tmp); |
117 | if(n > max) | 117 | if(n > max) |
118 | max = n; | 118 | max = n; |
119 | } | 119 | } |
@@ -401,33 +401,40 @@ EXPORT_SYMBOL_GPL(pci_find_ht_capability); | |||
401 | * @res: child resource record for which parent is sought | 401 | * @res: child resource record for which parent is sought |
402 | * | 402 | * |
403 | * For given resource region of given device, return the resource | 403 | * For given resource region of given device, return the resource |
404 | * region of parent bus the given region is contained in or where | 404 | * region of parent bus the given region is contained in. |
405 | * it should be allocated from. | ||
406 | */ | 405 | */ |
407 | struct resource * | 406 | struct resource * |
408 | pci_find_parent_resource(const struct pci_dev *dev, struct resource *res) | 407 | pci_find_parent_resource(const struct pci_dev *dev, struct resource *res) |
409 | { | 408 | { |
410 | const struct pci_bus *bus = dev->bus; | 409 | const struct pci_bus *bus = dev->bus; |
410 | struct resource *r; | ||
411 | int i; | 411 | int i; |
412 | struct resource *best = NULL, *r; | ||
413 | 412 | ||
414 | pci_bus_for_each_resource(bus, r, i) { | 413 | pci_bus_for_each_resource(bus, r, i) { |
415 | if (!r) | 414 | if (!r) |
416 | continue; | 415 | continue; |
417 | if (res->start && !(res->start >= r->start && res->end <= r->end)) | 416 | if (res->start && resource_contains(r, res)) { |
418 | continue; /* Not contained */ | 417 | |
419 | if ((res->flags ^ r->flags) & (IORESOURCE_IO | IORESOURCE_MEM)) | 418 | /* |
420 | continue; /* Wrong type */ | 419 | * If the window is prefetchable but the BAR is |
421 | if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH)) | 420 | * not, the allocator made a mistake. |
422 | return r; /* Exact match */ | 421 | */ |
423 | /* We can't insert a non-prefetch resource inside a prefetchable parent .. */ | 422 | if (r->flags & IORESOURCE_PREFETCH && |
424 | if (r->flags & IORESOURCE_PREFETCH) | 423 | !(res->flags & IORESOURCE_PREFETCH)) |
425 | continue; | 424 | return NULL; |
426 | /* .. but we can put a prefetchable resource inside a non-prefetchable one */ | 425 | |
427 | if (!best) | 426 | /* |
428 | best = r; | 427 | * If we're below a transparent bridge, there may |
428 | * be both a positively-decoded aperture and a | ||
429 | * subtractively-decoded region that contain the BAR. | ||
430 | * We want the positively-decoded one, so this depends | ||
431 | * on pci_bus_for_each_resource() giving us those | ||
432 | * first. | ||
433 | */ | ||
434 | return r; | ||
435 | } | ||
429 | } | 436 | } |
430 | return best; | 437 | return NULL; |
431 | } | 438 | } |
432 | 439 | ||
433 | /** | 440 | /** |
@@ -1178,6 +1185,11 @@ int pci_load_and_free_saved_state(struct pci_dev *dev, | |||
1178 | } | 1185 | } |
1179 | EXPORT_SYMBOL_GPL(pci_load_and_free_saved_state); | 1186 | EXPORT_SYMBOL_GPL(pci_load_and_free_saved_state); |
1180 | 1187 | ||
1188 | int __weak pcibios_enable_device(struct pci_dev *dev, int bars) | ||
1189 | { | ||
1190 | return pci_enable_resources(dev, bars); | ||
1191 | } | ||
1192 | |||
1181 | static int do_pci_enable_device(struct pci_dev *dev, int bars) | 1193 | static int do_pci_enable_device(struct pci_dev *dev, int bars) |
1182 | { | 1194 | { |
1183 | int err; | 1195 | int err; |
@@ -1624,29 +1636,27 @@ static void pci_pme_list_scan(struct work_struct *work) | |||
1624 | struct pci_pme_device *pme_dev, *n; | 1636 | struct pci_pme_device *pme_dev, *n; |
1625 | 1637 | ||
1626 | mutex_lock(&pci_pme_list_mutex); | 1638 | mutex_lock(&pci_pme_list_mutex); |
1627 | if (!list_empty(&pci_pme_list)) { | 1639 | list_for_each_entry_safe(pme_dev, n, &pci_pme_list, list) { |
1628 | list_for_each_entry_safe(pme_dev, n, &pci_pme_list, list) { | 1640 | if (pme_dev->dev->pme_poll) { |
1629 | if (pme_dev->dev->pme_poll) { | 1641 | struct pci_dev *bridge; |
1630 | struct pci_dev *bridge; | 1642 | |
1631 | 1643 | bridge = pme_dev->dev->bus->self; | |
1632 | bridge = pme_dev->dev->bus->self; | 1644 | /* |
1633 | /* | 1645 | * If bridge is in low power state, the |
1634 | * If bridge is in low power state, the | 1646 | * configuration space of subordinate devices |
1635 | * configuration space of subordinate devices | 1647 | * may be not accessible |
1636 | * may be not accessible | 1648 | */ |
1637 | */ | 1649 | if (bridge && bridge->current_state != PCI_D0) |
1638 | if (bridge && bridge->current_state != PCI_D0) | 1650 | continue; |
1639 | continue; | 1651 | pci_pme_wakeup(pme_dev->dev, NULL); |
1640 | pci_pme_wakeup(pme_dev->dev, NULL); | 1652 | } else { |
1641 | } else { | 1653 | list_del(&pme_dev->list); |
1642 | list_del(&pme_dev->list); | 1654 | kfree(pme_dev); |
1643 | kfree(pme_dev); | ||
1644 | } | ||
1645 | } | 1655 | } |
1646 | if (!list_empty(&pci_pme_list)) | ||
1647 | schedule_delayed_work(&pci_pme_work, | ||
1648 | msecs_to_jiffies(PME_TIMEOUT)); | ||
1649 | } | 1656 | } |
1657 | if (!list_empty(&pci_pme_list)) | ||
1658 | schedule_delayed_work(&pci_pme_work, | ||
1659 | msecs_to_jiffies(PME_TIMEOUT)); | ||
1650 | mutex_unlock(&pci_pme_list_mutex); | 1660 | mutex_unlock(&pci_pme_list_mutex); |
1651 | } | 1661 | } |
1652 | 1662 | ||
@@ -2193,21 +2203,18 @@ void pci_request_acs(void) | |||
2193 | } | 2203 | } |
2194 | 2204 | ||
2195 | /** | 2205 | /** |
2196 | * pci_enable_acs - enable ACS if hardware support it | 2206 | * pci_std_enable_acs - enable ACS on devices using standard ACS capabilites |
2197 | * @dev: the PCI device | 2207 | * @dev: the PCI device |
2198 | */ | 2208 | */ |
2199 | void pci_enable_acs(struct pci_dev *dev) | 2209 | static int pci_std_enable_acs(struct pci_dev *dev) |
2200 | { | 2210 | { |
2201 | int pos; | 2211 | int pos; |
2202 | u16 cap; | 2212 | u16 cap; |
2203 | u16 ctrl; | 2213 | u16 ctrl; |
2204 | 2214 | ||
2205 | if (!pci_acs_enable) | ||
2206 | return; | ||
2207 | |||
2208 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS); | 2215 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS); |
2209 | if (!pos) | 2216 | if (!pos) |
2210 | return; | 2217 | return -ENODEV; |
2211 | 2218 | ||
2212 | pci_read_config_word(dev, pos + PCI_ACS_CAP, &cap); | 2219 | pci_read_config_word(dev, pos + PCI_ACS_CAP, &cap); |
2213 | pci_read_config_word(dev, pos + PCI_ACS_CTRL, &ctrl); | 2220 | pci_read_config_word(dev, pos + PCI_ACS_CTRL, &ctrl); |
@@ -2225,6 +2232,23 @@ void pci_enable_acs(struct pci_dev *dev) | |||
2225 | ctrl |= (cap & PCI_ACS_UF); | 2232 | ctrl |= (cap & PCI_ACS_UF); |
2226 | 2233 | ||
2227 | pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl); | 2234 | pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl); |
2235 | |||
2236 | return 0; | ||
2237 | } | ||
2238 | |||
2239 | /** | ||
2240 | * pci_enable_acs - enable ACS if hardware support it | ||
2241 | * @dev: the PCI device | ||
2242 | */ | ||
2243 | void pci_enable_acs(struct pci_dev *dev) | ||
2244 | { | ||
2245 | if (!pci_acs_enable) | ||
2246 | return; | ||
2247 | |||
2248 | if (!pci_std_enable_acs(dev)) | ||
2249 | return; | ||
2250 | |||
2251 | pci_dev_specific_enable_acs(dev); | ||
2228 | } | 2252 | } |
2229 | 2253 | ||
2230 | static bool pci_acs_flags_enabled(struct pci_dev *pdev, u16 acs_flags) | 2254 | static bool pci_acs_flags_enabled(struct pci_dev *pdev, u16 acs_flags) |
@@ -4250,6 +4274,7 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev) | |||
4250 | "Rounding up size of resource #%d to %#llx.\n", | 4274 | "Rounding up size of resource #%d to %#llx.\n", |
4251 | i, (unsigned long long)size); | 4275 | i, (unsigned long long)size); |
4252 | } | 4276 | } |
4277 | r->flags |= IORESOURCE_UNSET; | ||
4253 | r->end = size - 1; | 4278 | r->end = size - 1; |
4254 | r->start = 0; | 4279 | r->start = 0; |
4255 | } | 4280 | } |
@@ -4263,6 +4288,7 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev) | |||
4263 | r = &dev->resource[i]; | 4288 | r = &dev->resource[i]; |
4264 | if (!(r->flags & IORESOURCE_MEM)) | 4289 | if (!(r->flags & IORESOURCE_MEM)) |
4265 | continue; | 4290 | continue; |
4291 | r->flags |= IORESOURCE_UNSET; | ||
4266 | r->end = resource_size(r) - 1; | 4292 | r->end = resource_size(r) - 1; |
4267 | r->start = 0; | 4293 | r->start = 0; |
4268 | } | 4294 | } |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 4df38df224f4..6bd082299e31 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -1,8 +1,6 @@ | |||
1 | #ifndef DRIVERS_PCI_H | 1 | #ifndef DRIVERS_PCI_H |
2 | #define DRIVERS_PCI_H | 2 | #define DRIVERS_PCI_H |
3 | 3 | ||
4 | #include <linux/workqueue.h> | ||
5 | |||
6 | #define PCI_CFG_SPACE_SIZE 256 | 4 | #define PCI_CFG_SPACE_SIZE 256 |
7 | #define PCI_CFG_SPACE_EXP_SIZE 4096 | 5 | #define PCI_CFG_SPACE_EXP_SIZE 4096 |
8 | 6 | ||
@@ -240,8 +238,6 @@ struct pci_sriov { | |||
240 | struct pci_dev *dev; /* lowest numbered PF */ | 238 | struct pci_dev *dev; /* lowest numbered PF */ |
241 | struct pci_dev *self; /* this PF */ | 239 | struct pci_dev *self; /* this PF */ |
242 | struct mutex lock; /* lock for VF bus */ | 240 | struct mutex lock; /* lock for VF bus */ |
243 | struct work_struct mtask; /* VF Migration task */ | ||
244 | u8 __iomem *mstate; /* VF Migration State Array */ | ||
245 | }; | 241 | }; |
246 | 242 | ||
247 | #ifdef CONFIG_PCI_ATS | 243 | #ifdef CONFIG_PCI_ATS |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 6e34498ec9f0..ef09f5f2fe6c 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -252,6 +252,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
252 | /* Address above 32-bit boundary; disable the BAR */ | 252 | /* Address above 32-bit boundary; disable the BAR */ |
253 | pci_write_config_dword(dev, pos, 0); | 253 | pci_write_config_dword(dev, pos, 0); |
254 | pci_write_config_dword(dev, pos + 4, 0); | 254 | pci_write_config_dword(dev, pos + 4, 0); |
255 | res->flags |= IORESOURCE_UNSET; | ||
255 | region.start = 0; | 256 | region.start = 0; |
256 | region.end = sz64; | 257 | region.end = sz64; |
257 | bar_disabled = true; | 258 | bar_disabled = true; |
@@ -731,22 +732,6 @@ struct pci_bus *__ref pci_add_new_bus(struct pci_bus *parent, struct pci_dev *de | |||
731 | return child; | 732 | return child; |
732 | } | 733 | } |
733 | 734 | ||
734 | static void pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max) | ||
735 | { | ||
736 | struct pci_bus *parent = child->parent; | ||
737 | |||
738 | /* Attempts to fix that up are really dangerous unless | ||
739 | we're going to re-assign all bus numbers. */ | ||
740 | if (!pcibios_assign_all_busses()) | ||
741 | return; | ||
742 | |||
743 | while (parent->parent && parent->busn_res.end < max) { | ||
744 | parent->busn_res.end = max; | ||
745 | pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, max); | ||
746 | parent = parent->parent; | ||
747 | } | ||
748 | } | ||
749 | |||
750 | /* | 735 | /* |
751 | * If it's a bridge, configure it and scan the bus behind it. | 736 | * If it's a bridge, configure it and scan the bus behind it. |
752 | * For CardBus bridges, we don't scan behind as the devices will | 737 | * For CardBus bridges, we don't scan behind as the devices will |
@@ -782,7 +767,7 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) | |||
782 | /* Check if setup is sensible at all */ | 767 | /* Check if setup is sensible at all */ |
783 | if (!pass && | 768 | if (!pass && |
784 | (primary != bus->number || secondary <= bus->number || | 769 | (primary != bus->number || secondary <= bus->number || |
785 | secondary > subordinate)) { | 770 | secondary > subordinate || subordinate > bus->busn_res.end)) { |
786 | dev_info(&dev->dev, "bridge configuration invalid ([bus %02x-%02x]), reconfiguring\n", | 771 | dev_info(&dev->dev, "bridge configuration invalid ([bus %02x-%02x]), reconfiguring\n", |
787 | secondary, subordinate); | 772 | secondary, subordinate); |
788 | broken = 1; | 773 | broken = 1; |
@@ -805,11 +790,10 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) | |||
805 | goto out; | 790 | goto out; |
806 | 791 | ||
807 | /* | 792 | /* |
808 | * If we already got to this bus through a different bridge, | 793 | * The bus might already exist for two reasons: Either we are |
809 | * don't re-add it. This can happen with the i450NX chipset. | 794 | * rescanning the bus or the bus is reachable through more than |
810 | * | 795 | * one bridge. The second case can happen with the i450NX |
811 | * However, we continue to descend down the hierarchy and | 796 | * chipset. |
812 | * scan remaining child buses. | ||
813 | */ | 797 | */ |
814 | child = pci_find_bus(pci_domain_nr(bus), secondary); | 798 | child = pci_find_bus(pci_domain_nr(bus), secondary); |
815 | if (!child) { | 799 | if (!child) { |
@@ -822,17 +806,19 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) | |||
822 | } | 806 | } |
823 | 807 | ||
824 | cmax = pci_scan_child_bus(child); | 808 | cmax = pci_scan_child_bus(child); |
825 | if (cmax > max) | 809 | if (cmax > subordinate) |
826 | max = cmax; | 810 | dev_warn(&dev->dev, "bridge has subordinate %02x but max busn %02x\n", |
827 | if (child->busn_res.end > max) | 811 | subordinate, cmax); |
828 | max = child->busn_res.end; | 812 | /* subordinate should equal child->busn_res.end */ |
813 | if (subordinate > max) | ||
814 | max = subordinate; | ||
829 | } else { | 815 | } else { |
830 | /* | 816 | /* |
831 | * We need to assign a number to this bus which we always | 817 | * We need to assign a number to this bus which we always |
832 | * do in the second pass. | 818 | * do in the second pass. |
833 | */ | 819 | */ |
834 | if (!pass) { | 820 | if (!pass) { |
835 | if (pcibios_assign_all_busses() || broken) | 821 | if (pcibios_assign_all_busses() || broken || is_cardbus) |
836 | /* Temporarily disable forwarding of the | 822 | /* Temporarily disable forwarding of the |
837 | configuration cycles on all bridges in | 823 | configuration cycles on all bridges in |
838 | this bus segment to avoid possible | 824 | this bus segment to avoid possible |
@@ -844,19 +830,25 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) | |||
844 | goto out; | 830 | goto out; |
845 | } | 831 | } |
846 | 832 | ||
833 | if (max >= bus->busn_res.end) { | ||
834 | dev_warn(&dev->dev, "can't allocate child bus %02x from %pR\n", | ||
835 | max, &bus->busn_res); | ||
836 | goto out; | ||
837 | } | ||
838 | |||
847 | /* Clear errors */ | 839 | /* Clear errors */ |
848 | pci_write_config_word(dev, PCI_STATUS, 0xffff); | 840 | pci_write_config_word(dev, PCI_STATUS, 0xffff); |
849 | 841 | ||
850 | /* Prevent assigning a bus number that already exists. | 842 | /* The bus will already exist if we are rescanning */ |
851 | * This can happen when a bridge is hot-plugged, so in | ||
852 | * this case we only re-scan this bus. */ | ||
853 | child = pci_find_bus(pci_domain_nr(bus), max+1); | 843 | child = pci_find_bus(pci_domain_nr(bus), max+1); |
854 | if (!child) { | 844 | if (!child) { |
855 | child = pci_add_new_bus(bus, dev, ++max); | 845 | child = pci_add_new_bus(bus, dev, max+1); |
856 | if (!child) | 846 | if (!child) |
857 | goto out; | 847 | goto out; |
858 | pci_bus_insert_busn_res(child, max, 0xff); | 848 | pci_bus_insert_busn_res(child, max+1, |
849 | bus->busn_res.end); | ||
859 | } | 850 | } |
851 | max++; | ||
860 | buses = (buses & 0xff000000) | 852 | buses = (buses & 0xff000000) |
861 | | ((unsigned int)(child->primary) << 0) | 853 | | ((unsigned int)(child->primary) << 0) |
862 | | ((unsigned int)(child->busn_res.start) << 8) | 854 | | ((unsigned int)(child->busn_res.start) << 8) |
@@ -878,20 +870,7 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) | |||
878 | 870 | ||
879 | if (!is_cardbus) { | 871 | if (!is_cardbus) { |
880 | child->bridge_ctl = bctl; | 872 | child->bridge_ctl = bctl; |
881 | /* | ||
882 | * Adjust subordinate busnr in parent buses. | ||
883 | * We do this before scanning for children because | ||
884 | * some devices may not be detected if the bios | ||
885 | * was lazy. | ||
886 | */ | ||
887 | pci_fixup_parent_subordinate_busnr(child, max); | ||
888 | /* Now we can scan all subordinate buses... */ | ||
889 | max = pci_scan_child_bus(child); | 873 | max = pci_scan_child_bus(child); |
890 | /* | ||
891 | * now fix it up again since we have found | ||
892 | * the real value of max. | ||
893 | */ | ||
894 | pci_fixup_parent_subordinate_busnr(child, max); | ||
895 | } else { | 874 | } else { |
896 | /* | 875 | /* |
897 | * For CardBus bridges, we leave 4 bus numbers | 876 | * For CardBus bridges, we leave 4 bus numbers |
@@ -922,11 +901,15 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) | |||
922 | } | 901 | } |
923 | } | 902 | } |
924 | max += i; | 903 | max += i; |
925 | pci_fixup_parent_subordinate_busnr(child, max); | ||
926 | } | 904 | } |
927 | /* | 905 | /* |
928 | * Set the subordinate bus number to its real value. | 906 | * Set the subordinate bus number to its real value. |
929 | */ | 907 | */ |
908 | if (max > bus->busn_res.end) { | ||
909 | dev_warn(&dev->dev, "max busn %02x is outside %pR\n", | ||
910 | max, &bus->busn_res); | ||
911 | max = bus->busn_res.end; | ||
912 | } | ||
930 | pci_bus_update_busn_res_end(child, max); | 913 | pci_bus_update_busn_res_end(child, max); |
931 | pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max); | 914 | pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max); |
932 | } | 915 | } |
@@ -1125,10 +1108,10 @@ int pci_setup_device(struct pci_dev *dev) | |||
1125 | pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &dev->subsystem_device); | 1108 | pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &dev->subsystem_device); |
1126 | 1109 | ||
1127 | /* | 1110 | /* |
1128 | * Do the ugly legacy mode stuff here rather than broken chip | 1111 | * Do the ugly legacy mode stuff here rather than broken chip |
1129 | * quirk code. Legacy mode ATA controllers have fixed | 1112 | * quirk code. Legacy mode ATA controllers have fixed |
1130 | * addresses. These are not always echoed in BAR0-3, and | 1113 | * addresses. These are not always echoed in BAR0-3, and |
1131 | * BAR0-3 in a few cases contain junk! | 1114 | * BAR0-3 in a few cases contain junk! |
1132 | */ | 1115 | */ |
1133 | if (class == PCI_CLASS_STORAGE_IDE) { | 1116 | if (class == PCI_CLASS_STORAGE_IDE) { |
1134 | u8 progif; | 1117 | u8 progif; |
@@ -1139,11 +1122,15 @@ int pci_setup_device(struct pci_dev *dev) | |||
1139 | res = &dev->resource[0]; | 1122 | res = &dev->resource[0]; |
1140 | res->flags = LEGACY_IO_RESOURCE; | 1123 | res->flags = LEGACY_IO_RESOURCE; |
1141 | pcibios_bus_to_resource(dev->bus, res, ®ion); | 1124 | pcibios_bus_to_resource(dev->bus, res, ®ion); |
1125 | dev_info(&dev->dev, "legacy IDE quirk: reg 0x10: %pR\n", | ||
1126 | res); | ||
1142 | region.start = 0x3F6; | 1127 | region.start = 0x3F6; |
1143 | region.end = 0x3F6; | 1128 | region.end = 0x3F6; |
1144 | res = &dev->resource[1]; | 1129 | res = &dev->resource[1]; |
1145 | res->flags = LEGACY_IO_RESOURCE; | 1130 | res->flags = LEGACY_IO_RESOURCE; |
1146 | pcibios_bus_to_resource(dev->bus, res, ®ion); | 1131 | pcibios_bus_to_resource(dev->bus, res, ®ion); |
1132 | dev_info(&dev->dev, "legacy IDE quirk: reg 0x14: %pR\n", | ||
1133 | res); | ||
1147 | } | 1134 | } |
1148 | if ((progif & 4) == 0) { | 1135 | if ((progif & 4) == 0) { |
1149 | region.start = 0x170; | 1136 | region.start = 0x170; |
@@ -1151,11 +1138,15 @@ int pci_setup_device(struct pci_dev *dev) | |||
1151 | res = &dev->resource[2]; | 1138 | res = &dev->resource[2]; |
1152 | res->flags = LEGACY_IO_RESOURCE; | 1139 | res->flags = LEGACY_IO_RESOURCE; |
1153 | pcibios_bus_to_resource(dev->bus, res, ®ion); | 1140 | pcibios_bus_to_resource(dev->bus, res, ®ion); |
1141 | dev_info(&dev->dev, "legacy IDE quirk: reg 0x18: %pR\n", | ||
1142 | res); | ||
1154 | region.start = 0x376; | 1143 | region.start = 0x376; |
1155 | region.end = 0x376; | 1144 | region.end = 0x376; |
1156 | res = &dev->resource[3]; | 1145 | res = &dev->resource[3]; |
1157 | res->flags = LEGACY_IO_RESOURCE; | 1146 | res->flags = LEGACY_IO_RESOURCE; |
1158 | pcibios_bus_to_resource(dev->bus, res, ®ion); | 1147 | pcibios_bus_to_resource(dev->bus, res, ®ion); |
1148 | dev_info(&dev->dev, "legacy IDE quirk: reg 0x1c: %pR\n", | ||
1149 | res); | ||
1159 | } | 1150 | } |
1160 | } | 1151 | } |
1161 | break; | 1152 | break; |
@@ -1835,7 +1826,7 @@ int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max) | |||
1835 | res->flags |= IORESOURCE_PCI_FIXED; | 1826 | res->flags |= IORESOURCE_PCI_FIXED; |
1836 | } | 1827 | } |
1837 | 1828 | ||
1838 | conflict = insert_resource_conflict(parent_res, res); | 1829 | conflict = request_resource_conflict(parent_res, res); |
1839 | 1830 | ||
1840 | if (conflict) | 1831 | if (conflict) |
1841 | dev_printk(KERN_DEBUG, &b->dev, | 1832 | dev_printk(KERN_DEBUG, &b->dev, |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 5cb726c193de..e7292065a1b1 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -296,6 +296,7 @@ static void quirk_s3_64M(struct pci_dev *dev) | |||
296 | struct resource *r = &dev->resource[0]; | 296 | struct resource *r = &dev->resource[0]; |
297 | 297 | ||
298 | if ((r->start & 0x3ffffff) || r->end != r->start + 0x3ffffff) { | 298 | if ((r->start & 0x3ffffff) || r->end != r->start + 0x3ffffff) { |
299 | r->flags |= IORESOURCE_UNSET; | ||
299 | r->start = 0; | 300 | r->start = 0; |
300 | r->end = 0x3ffffff; | 301 | r->end = 0x3ffffff; |
301 | } | 302 | } |
@@ -937,6 +938,8 @@ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C | |||
937 | static void quirk_dunord(struct pci_dev *dev) | 938 | static void quirk_dunord(struct pci_dev *dev) |
938 | { | 939 | { |
939 | struct resource *r = &dev->resource [1]; | 940 | struct resource *r = &dev->resource [1]; |
941 | |||
942 | r->flags |= IORESOURCE_UNSET; | ||
940 | r->start = 0; | 943 | r->start = 0; |
941 | r->end = 0xffffff; | 944 | r->end = 0xffffff; |
942 | } | 945 | } |
@@ -1740,6 +1743,7 @@ static void quirk_tc86c001_ide(struct pci_dev *dev) | |||
1740 | struct resource *r = &dev->resource[0]; | 1743 | struct resource *r = &dev->resource[0]; |
1741 | 1744 | ||
1742 | if (r->start & 0x8) { | 1745 | if (r->start & 0x8) { |
1746 | r->flags |= IORESOURCE_UNSET; | ||
1743 | r->start = 0; | 1747 | r->start = 0; |
1744 | r->end = 0xf; | 1748 | r->end = 0xf; |
1745 | } | 1749 | } |
@@ -1769,6 +1773,7 @@ static void quirk_plx_pci9050(struct pci_dev *dev) | |||
1769 | dev_info(&dev->dev, | 1773 | dev_info(&dev->dev, |
1770 | "Re-allocating PLX PCI 9050 BAR %u to length 256 to avoid bit 7 bug\n", | 1774 | "Re-allocating PLX PCI 9050 BAR %u to length 256 to avoid bit 7 bug\n", |
1771 | bar); | 1775 | bar); |
1776 | r->flags |= IORESOURCE_UNSET; | ||
1772 | r->start = 0; | 1777 | r->start = 0; |
1773 | r->end = 0xff; | 1778 | r->end = 0xff; |
1774 | } | 1779 | } |
@@ -3423,6 +3428,61 @@ static int pci_quirk_amd_sb_acs(struct pci_dev *dev, u16 acs_flags) | |||
3423 | #endif | 3428 | #endif |
3424 | } | 3429 | } |
3425 | 3430 | ||
3431 | /* | ||
3432 | * Many Intel PCH root ports do provide ACS-like features to disable peer | ||
3433 | * transactions and validate bus numbers in requests, but do not provide an | ||
3434 | * actual PCIe ACS capability. This is the list of device IDs known to fall | ||
3435 | * into that category as provided by Intel in Red Hat bugzilla 1037684. | ||
3436 | */ | ||
3437 | static const u16 pci_quirk_intel_pch_acs_ids[] = { | ||
3438 | /* Ibexpeak PCH */ | ||
3439 | 0x3b42, 0x3b43, 0x3b44, 0x3b45, 0x3b46, 0x3b47, 0x3b48, 0x3b49, | ||
3440 | 0x3b4a, 0x3b4b, 0x3b4c, 0x3b4d, 0x3b4e, 0x3b4f, 0x3b50, 0x3b51, | ||
3441 | /* Cougarpoint PCH */ | ||
3442 | 0x1c10, 0x1c11, 0x1c12, 0x1c13, 0x1c14, 0x1c15, 0x1c16, 0x1c17, | ||
3443 | 0x1c18, 0x1c19, 0x1c1a, 0x1c1b, 0x1c1c, 0x1c1d, 0x1c1e, 0x1c1f, | ||
3444 | /* Pantherpoint PCH */ | ||
3445 | 0x1e10, 0x1e11, 0x1e12, 0x1e13, 0x1e14, 0x1e15, 0x1e16, 0x1e17, | ||
3446 | 0x1e18, 0x1e19, 0x1e1a, 0x1e1b, 0x1e1c, 0x1e1d, 0x1e1e, 0x1e1f, | ||
3447 | /* Lynxpoint-H PCH */ | ||
3448 | 0x8c10, 0x8c11, 0x8c12, 0x8c13, 0x8c14, 0x8c15, 0x8c16, 0x8c17, | ||
3449 | 0x8c18, 0x8c19, 0x8c1a, 0x8c1b, 0x8c1c, 0x8c1d, 0x8c1e, 0x8c1f, | ||
3450 | /* Lynxpoint-LP PCH */ | ||
3451 | 0x9c10, 0x9c11, 0x9c12, 0x9c13, 0x9c14, 0x9c15, 0x9c16, 0x9c17, | ||
3452 | 0x9c18, 0x9c19, 0x9c1a, 0x9c1b, | ||
3453 | /* Wildcat PCH */ | ||
3454 | 0x9c90, 0x9c91, 0x9c92, 0x9c93, 0x9c94, 0x9c95, 0x9c96, 0x9c97, | ||
3455 | 0x9c98, 0x9c99, 0x9c9a, 0x9c9b, | ||
3456 | }; | ||
3457 | |||
3458 | static bool pci_quirk_intel_pch_acs_match(struct pci_dev *dev) | ||
3459 | { | ||
3460 | int i; | ||
3461 | |||
3462 | /* Filter out a few obvious non-matches first */ | ||
3463 | if (!pci_is_pcie(dev) || pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT) | ||
3464 | return false; | ||
3465 | |||
3466 | for (i = 0; i < ARRAY_SIZE(pci_quirk_intel_pch_acs_ids); i++) | ||
3467 | if (pci_quirk_intel_pch_acs_ids[i] == dev->device) | ||
3468 | return true; | ||
3469 | |||
3470 | return false; | ||
3471 | } | ||
3472 | |||
3473 | #define INTEL_PCH_ACS_FLAGS (PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_SV) | ||
3474 | |||
3475 | static int pci_quirk_intel_pch_acs(struct pci_dev *dev, u16 acs_flags) | ||
3476 | { | ||
3477 | u16 flags = dev->dev_flags & PCI_DEV_FLAGS_ACS_ENABLED_QUIRK ? | ||
3478 | INTEL_PCH_ACS_FLAGS : 0; | ||
3479 | |||
3480 | if (!pci_quirk_intel_pch_acs_match(dev)) | ||
3481 | return -ENOTTY; | ||
3482 | |||
3483 | return acs_flags & ~flags ? 0 : 1; | ||
3484 | } | ||
3485 | |||
3426 | static const struct pci_dev_acs_enabled { | 3486 | static const struct pci_dev_acs_enabled { |
3427 | u16 vendor; | 3487 | u16 vendor; |
3428 | u16 device; | 3488 | u16 device; |
@@ -3434,6 +3494,7 @@ static const struct pci_dev_acs_enabled { | |||
3434 | { PCI_VENDOR_ID_ATI, 0x439d, pci_quirk_amd_sb_acs }, | 3494 | { PCI_VENDOR_ID_ATI, 0x439d, pci_quirk_amd_sb_acs }, |
3435 | { PCI_VENDOR_ID_ATI, 0x4384, pci_quirk_amd_sb_acs }, | 3495 | { PCI_VENDOR_ID_ATI, 0x4384, pci_quirk_amd_sb_acs }, |
3436 | { PCI_VENDOR_ID_ATI, 0x4399, pci_quirk_amd_sb_acs }, | 3496 | { PCI_VENDOR_ID_ATI, 0x4399, pci_quirk_amd_sb_acs }, |
3497 | { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs }, | ||
3437 | { 0 } | 3498 | { 0 } |
3438 | }; | 3499 | }; |
3439 | 3500 | ||
@@ -3461,3 +3522,132 @@ int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags) | |||
3461 | 3522 | ||
3462 | return -ENOTTY; | 3523 | return -ENOTTY; |
3463 | } | 3524 | } |
3525 | |||
3526 | /* Config space offset of Root Complex Base Address register */ | ||
3527 | #define INTEL_LPC_RCBA_REG 0xf0 | ||
3528 | /* 31:14 RCBA address */ | ||
3529 | #define INTEL_LPC_RCBA_MASK 0xffffc000 | ||
3530 | /* RCBA Enable */ | ||
3531 | #define INTEL_LPC_RCBA_ENABLE (1 << 0) | ||
3532 | |||
3533 | /* Backbone Scratch Pad Register */ | ||
3534 | #define INTEL_BSPR_REG 0x1104 | ||
3535 | /* Backbone Peer Non-Posted Disable */ | ||
3536 | #define INTEL_BSPR_REG_BPNPD (1 << 8) | ||
3537 | /* Backbone Peer Posted Disable */ | ||
3538 | #define INTEL_BSPR_REG_BPPD (1 << 9) | ||
3539 | |||
3540 | /* Upstream Peer Decode Configuration Register */ | ||
3541 | #define INTEL_UPDCR_REG 0x1114 | ||
3542 | /* 5:0 Peer Decode Enable bits */ | ||
3543 | #define INTEL_UPDCR_REG_MASK 0x3f | ||
3544 | |||
3545 | static int pci_quirk_enable_intel_lpc_acs(struct pci_dev *dev) | ||
3546 | { | ||
3547 | u32 rcba, bspr, updcr; | ||
3548 | void __iomem *rcba_mem; | ||
3549 | |||
3550 | /* | ||
3551 | * Read the RCBA register from the LPC (D31:F0). PCH root ports | ||
3552 | * are D28:F* and therefore get probed before LPC, thus we can't | ||
3553 | * use pci_get_slot/pci_read_config_dword here. | ||
3554 | */ | ||
3555 | pci_bus_read_config_dword(dev->bus, PCI_DEVFN(31, 0), | ||
3556 | INTEL_LPC_RCBA_REG, &rcba); | ||
3557 | if (!(rcba & INTEL_LPC_RCBA_ENABLE)) | ||
3558 | return -EINVAL; | ||
3559 | |||
3560 | rcba_mem = ioremap_nocache(rcba & INTEL_LPC_RCBA_MASK, | ||
3561 | PAGE_ALIGN(INTEL_UPDCR_REG)); | ||
3562 | if (!rcba_mem) | ||
3563 | return -ENOMEM; | ||
3564 | |||
3565 | /* | ||
3566 | * The BSPR can disallow peer cycles, but it's set by soft strap and | ||
3567 | * therefore read-only. If both posted and non-posted peer cycles are | ||
3568 | * disallowed, we're ok. If either are allowed, then we need to use | ||
3569 | * the UPDCR to disable peer decodes for each port. This provides the | ||
3570 | * PCIe ACS equivalent of PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF | ||
3571 | */ | ||
3572 | bspr = readl(rcba_mem + INTEL_BSPR_REG); | ||
3573 | bspr &= INTEL_BSPR_REG_BPNPD | INTEL_BSPR_REG_BPPD; | ||
3574 | if (bspr != (INTEL_BSPR_REG_BPNPD | INTEL_BSPR_REG_BPPD)) { | ||
3575 | updcr = readl(rcba_mem + INTEL_UPDCR_REG); | ||
3576 | if (updcr & INTEL_UPDCR_REG_MASK) { | ||
3577 | dev_info(&dev->dev, "Disabling UPDCR peer decodes\n"); | ||
3578 | updcr &= ~INTEL_UPDCR_REG_MASK; | ||
3579 | writel(updcr, rcba_mem + INTEL_UPDCR_REG); | ||
3580 | } | ||
3581 | } | ||
3582 | |||
3583 | iounmap(rcba_mem); | ||
3584 | return 0; | ||
3585 | } | ||
3586 | |||
3587 | /* Miscellaneous Port Configuration register */ | ||
3588 | #define INTEL_MPC_REG 0xd8 | ||
3589 | /* MPC: Invalid Receive Bus Number Check Enable */ | ||
3590 | #define INTEL_MPC_REG_IRBNCE (1 << 26) | ||
3591 | |||
3592 | static void pci_quirk_enable_intel_rp_mpc_acs(struct pci_dev *dev) | ||
3593 | { | ||
3594 | u32 mpc; | ||
3595 | |||
3596 | /* | ||
3597 | * When enabled, the IRBNCE bit of the MPC register enables the | ||
3598 | * equivalent of PCI ACS Source Validation (PCI_ACS_SV), which | ||
3599 | * ensures that requester IDs fall within the bus number range | ||
3600 | * of the bridge. Enable if not already. | ||
3601 | */ | ||
3602 | pci_read_config_dword(dev, INTEL_MPC_REG, &mpc); | ||
3603 | if (!(mpc & INTEL_MPC_REG_IRBNCE)) { | ||
3604 | dev_info(&dev->dev, "Enabling MPC IRBNCE\n"); | ||
3605 | mpc |= INTEL_MPC_REG_IRBNCE; | ||
3606 | pci_write_config_word(dev, INTEL_MPC_REG, mpc); | ||
3607 | } | ||
3608 | } | ||
3609 | |||
3610 | static int pci_quirk_enable_intel_pch_acs(struct pci_dev *dev) | ||
3611 | { | ||
3612 | if (!pci_quirk_intel_pch_acs_match(dev)) | ||
3613 | return -ENOTTY; | ||
3614 | |||
3615 | if (pci_quirk_enable_intel_lpc_acs(dev)) { | ||
3616 | dev_warn(&dev->dev, "Failed to enable Intel PCH ACS quirk\n"); | ||
3617 | return 0; | ||
3618 | } | ||
3619 | |||
3620 | pci_quirk_enable_intel_rp_mpc_acs(dev); | ||
3621 | |||
3622 | dev->dev_flags |= PCI_DEV_FLAGS_ACS_ENABLED_QUIRK; | ||
3623 | |||
3624 | dev_info(&dev->dev, "Intel PCH root port ACS workaround enabled\n"); | ||
3625 | |||
3626 | return 0; | ||
3627 | } | ||
3628 | |||
3629 | static const struct pci_dev_enable_acs { | ||
3630 | u16 vendor; | ||
3631 | u16 device; | ||
3632 | int (*enable_acs)(struct pci_dev *dev); | ||
3633 | } pci_dev_enable_acs[] = { | ||
3634 | { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_enable_intel_pch_acs }, | ||
3635 | { 0 } | ||
3636 | }; | ||
3637 | |||
3638 | void pci_dev_specific_enable_acs(struct pci_dev *dev) | ||
3639 | { | ||
3640 | const struct pci_dev_enable_acs *i; | ||
3641 | int ret; | ||
3642 | |||
3643 | for (i = pci_dev_enable_acs; i->enable_acs; i++) { | ||
3644 | if ((i->vendor == dev->vendor || | ||
3645 | i->vendor == (u16)PCI_ANY_ID) && | ||
3646 | (i->device == dev->device || | ||
3647 | i->device == (u16)PCI_ANY_ID)) { | ||
3648 | ret = i->enable_acs(dev); | ||
3649 | if (ret >= 0) | ||
3650 | return; | ||
3651 | } | ||
3652 | } | ||
3653 | } | ||
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index 5d595724e5f4..c1839450d4d6 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c | |||
@@ -197,8 +197,10 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom) | |||
197 | void pci_cleanup_rom(struct pci_dev *pdev) | 197 | void pci_cleanup_rom(struct pci_dev *pdev) |
198 | { | 198 | { |
199 | struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; | 199 | struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; |
200 | |||
200 | if (res->flags & IORESOURCE_ROM_COPY) { | 201 | if (res->flags & IORESOURCE_ROM_COPY) { |
201 | kfree((void*)(unsigned long)res->start); | 202 | kfree((void*)(unsigned long)res->start); |
203 | res->flags |= IORESOURCE_UNSET; | ||
202 | res->flags &= ~IORESOURCE_ROM_COPY; | 204 | res->flags &= ~IORESOURCE_ROM_COPY; |
203 | res->start = 0; | 205 | res->start = 0; |
204 | res->end = 0; | 206 | res->end = 0; |
diff --git a/drivers/pci/search.c b/drivers/pci/search.c index 3ff2ac7c14e2..4a1b972efe7f 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c | |||
@@ -54,14 +54,14 @@ pci_find_upstream_pcie_bridge(struct pci_dev *pdev) | |||
54 | 54 | ||
55 | static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr) | 55 | static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr) |
56 | { | 56 | { |
57 | struct pci_bus* child; | 57 | struct pci_bus *child; |
58 | struct list_head *tmp; | 58 | struct pci_bus *tmp; |
59 | 59 | ||
60 | if(bus->number == busnr) | 60 | if(bus->number == busnr) |
61 | return bus; | 61 | return bus; |
62 | 62 | ||
63 | list_for_each(tmp, &bus->children) { | 63 | list_for_each_entry(tmp, &bus->children, node) { |
64 | child = pci_do_find_bus(pci_bus_b(tmp), busnr); | 64 | child = pci_do_find_bus(tmp, busnr); |
65 | if(child) | 65 | if(child) |
66 | return child; | 66 | return child; |
67 | } | 67 | } |
@@ -111,7 +111,7 @@ pci_find_next_bus(const struct pci_bus *from) | |||
111 | down_read(&pci_bus_sem); | 111 | down_read(&pci_bus_sem); |
112 | n = from ? from->node.next : pci_root_buses.next; | 112 | n = from ? from->node.next : pci_root_buses.next; |
113 | if (n != &pci_root_buses) | 113 | if (n != &pci_root_buses) |
114 | b = pci_bus_b(n); | 114 | b = list_entry(n, struct pci_bus, node); |
115 | up_read(&pci_bus_sem); | 115 | up_read(&pci_bus_sem); |
116 | return b; | 116 | return b; |
117 | } | 117 | } |
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 5c060b152ce6..7eed671d5586 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -44,6 +44,9 @@ void pci_update_resource(struct pci_dev *dev, int resno) | |||
44 | if (!res->flags) | 44 | if (!res->flags) |
45 | return; | 45 | return; |
46 | 46 | ||
47 | if (res->flags & IORESOURCE_UNSET) | ||
48 | return; | ||
49 | |||
47 | /* | 50 | /* |
48 | * Ignore non-moveable resources. This might be legacy resources for | 51 | * Ignore non-moveable resources. This might be legacy resources for |
49 | * which no functional BAR register exists or another important | 52 | * which no functional BAR register exists or another important |
@@ -101,11 +104,6 @@ void pci_update_resource(struct pci_dev *dev, int resno) | |||
101 | 104 | ||
102 | if (disable) | 105 | if (disable) |
103 | pci_write_config_word(dev, PCI_COMMAND, cmd); | 106 | pci_write_config_word(dev, PCI_COMMAND, cmd); |
104 | |||
105 | res->flags &= ~IORESOURCE_UNSET; | ||
106 | dev_dbg(&dev->dev, "BAR %d: set to %pR (PCI address [%#llx-%#llx])\n", | ||
107 | resno, res, (unsigned long long)region.start, | ||
108 | (unsigned long long)region.end); | ||
109 | } | 107 | } |
110 | 108 | ||
111 | int pci_claim_resource(struct pci_dev *dev, int resource) | 109 | int pci_claim_resource(struct pci_dev *dev, int resource) |
@@ -113,18 +111,23 @@ int pci_claim_resource(struct pci_dev *dev, int resource) | |||
113 | struct resource *res = &dev->resource[resource]; | 111 | struct resource *res = &dev->resource[resource]; |
114 | struct resource *root, *conflict; | 112 | struct resource *root, *conflict; |
115 | 113 | ||
114 | if (res->flags & IORESOURCE_UNSET) { | ||
115 | dev_info(&dev->dev, "can't claim BAR %d %pR: no address assigned\n", | ||
116 | resource, res); | ||
117 | return -EINVAL; | ||
118 | } | ||
119 | |||
116 | root = pci_find_parent_resource(dev, res); | 120 | root = pci_find_parent_resource(dev, res); |
117 | if (!root) { | 121 | if (!root) { |
118 | dev_info(&dev->dev, "no compatible bridge window for %pR\n", | 122 | dev_info(&dev->dev, "can't claim BAR %d %pR: no compatible bridge window\n", |
119 | res); | 123 | resource, res); |
120 | return -EINVAL; | 124 | return -EINVAL; |
121 | } | 125 | } |
122 | 126 | ||
123 | conflict = request_resource_conflict(root, res); | 127 | conflict = request_resource_conflict(root, res); |
124 | if (conflict) { | 128 | if (conflict) { |
125 | dev_info(&dev->dev, | 129 | dev_info(&dev->dev, "can't claim BAR %d %pR: address conflict with %s %pR\n", |
126 | "address space collision: %pR conflicts with %s %pR\n", | 130 | resource, res, conflict->name, conflict); |
127 | res, conflict->name, conflict); | ||
128 | return -EBUSY; | 131 | return -EBUSY; |
129 | } | 132 | } |
130 | 133 | ||
@@ -263,6 +266,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
263 | resource_size_t align, size; | 266 | resource_size_t align, size; |
264 | int ret; | 267 | int ret; |
265 | 268 | ||
269 | res->flags |= IORESOURCE_UNSET; | ||
266 | align = pci_resource_alignment(dev, res); | 270 | align = pci_resource_alignment(dev, res); |
267 | if (!align) { | 271 | if (!align) { |
268 | dev_info(&dev->dev, "BAR %d: can't assign %pR " | 272 | dev_info(&dev->dev, "BAR %d: can't assign %pR " |
@@ -282,6 +286,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
282 | ret = pci_revert_fw_address(res, dev, resno, size); | 286 | ret = pci_revert_fw_address(res, dev, resno, size); |
283 | 287 | ||
284 | if (!ret) { | 288 | if (!ret) { |
289 | res->flags &= ~IORESOURCE_UNSET; | ||
285 | res->flags &= ~IORESOURCE_STARTALIGN; | 290 | res->flags &= ~IORESOURCE_STARTALIGN; |
286 | dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); | 291 | dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); |
287 | if (resno < PCI_BRIDGE_RESOURCES) | 292 | if (resno < PCI_BRIDGE_RESOURCES) |
@@ -297,6 +302,7 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz | |||
297 | resource_size_t new_size; | 302 | resource_size_t new_size; |
298 | int ret; | 303 | int ret; |
299 | 304 | ||
305 | res->flags |= IORESOURCE_UNSET; | ||
300 | if (!res->parent) { | 306 | if (!res->parent) { |
301 | dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR " | 307 | dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR " |
302 | "\n", resno, res); | 308 | "\n", resno, res); |
@@ -307,6 +313,7 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz | |||
307 | new_size = resource_size(res) + addsize; | 313 | new_size = resource_size(res) + addsize; |
308 | ret = _pci_assign_resource(dev, resno, new_size, min_align); | 314 | ret = _pci_assign_resource(dev, resno, new_size, min_align); |
309 | if (!ret) { | 315 | if (!ret) { |
316 | res->flags &= ~IORESOURCE_UNSET; | ||
310 | res->flags &= ~IORESOURCE_STARTALIGN; | 317 | res->flags &= ~IORESOURCE_STARTALIGN; |
311 | dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res); | 318 | dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res); |
312 | if (resno < PCI_BRIDGE_RESOURCES) | 319 | if (resno < PCI_BRIDGE_RESOURCES) |
@@ -336,9 +343,15 @@ int pci_enable_resources(struct pci_dev *dev, int mask) | |||
336 | (!(r->flags & IORESOURCE_ROM_ENABLE))) | 343 | (!(r->flags & IORESOURCE_ROM_ENABLE))) |
337 | continue; | 344 | continue; |
338 | 345 | ||
346 | if (r->flags & IORESOURCE_UNSET) { | ||
347 | dev_err(&dev->dev, "can't enable device: BAR %d %pR not assigned\n", | ||
348 | i, r); | ||
349 | return -EINVAL; | ||
350 | } | ||
351 | |||
339 | if (!r->parent) { | 352 | if (!r->parent) { |
340 | dev_err(&dev->dev, "device not available " | 353 | dev_err(&dev->dev, "can't enable device: BAR %d %pR not claimed\n", |
341 | "(can't reserve %pR)\n", r); | 354 | i, r); |
342 | return -EINVAL; | 355 | return -EINVAL; |
343 | } | 356 | } |
344 | 357 | ||
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 8485761e76af..946f90ef6020 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c | |||
@@ -1076,7 +1076,7 @@ static void yenta_config_init(struct yenta_socket *socket) | |||
1076 | */ | 1076 | */ |
1077 | static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge) | 1077 | static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge) |
1078 | { | 1078 | { |
1079 | struct list_head *tmp; | 1079 | struct pci_bus *sibling; |
1080 | unsigned char upper_limit; | 1080 | unsigned char upper_limit; |
1081 | /* | 1081 | /* |
1082 | * We only check and fix the parent bridge: All systems which need | 1082 | * We only check and fix the parent bridge: All systems which need |
@@ -1095,18 +1095,18 @@ static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge) | |||
1095 | /* stay within the limits of the bus range of the parent: */ | 1095 | /* stay within the limits of the bus range of the parent: */ |
1096 | upper_limit = bridge_to_fix->parent->busn_res.end; | 1096 | upper_limit = bridge_to_fix->parent->busn_res.end; |
1097 | 1097 | ||
1098 | /* check the bus ranges of all silbling bridges to prevent overlap */ | 1098 | /* check the bus ranges of all sibling bridges to prevent overlap */ |
1099 | list_for_each(tmp, &bridge_to_fix->parent->children) { | 1099 | list_for_each_entry(sibling, &bridge_to_fix->parent->children, |
1100 | struct pci_bus *silbling = pci_bus_b(tmp); | 1100 | node) { |
1101 | /* | 1101 | /* |
1102 | * If the silbling has a higher secondary bus number | 1102 | * If the sibling has a higher secondary bus number |
1103 | * and it's secondary is equal or smaller than our | 1103 | * and it's secondary is equal or smaller than our |
1104 | * current upper limit, set the new upper limit to | 1104 | * current upper limit, set the new upper limit to |
1105 | * the bus number below the silbling's range: | 1105 | * the bus number below the sibling's range: |
1106 | */ | 1106 | */ |
1107 | if (silbling->busn_res.start > bridge_to_fix->busn_res.end | 1107 | if (sibling->busn_res.start > bridge_to_fix->busn_res.end |
1108 | && silbling->busn_res.start <= upper_limit) | 1108 | && sibling->busn_res.start <= upper_limit) |
1109 | upper_limit = silbling->busn_res.start - 1; | 1109 | upper_limit = sibling->busn_res.start - 1; |
1110 | } | 1110 | } |
1111 | 1111 | ||
1112 | /* Show that the wanted subordinate number is not possible: */ | 1112 | /* Show that the wanted subordinate number is not possible: */ |
diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c index 210357691dc0..9dd49c9839ac 100644 --- a/drivers/vfio/pci/vfio_pci_intrs.c +++ b/drivers/vfio/pci/vfio_pci_intrs.c | |||
@@ -482,15 +482,19 @@ static int vfio_msi_enable(struct vfio_pci_device *vdev, int nvec, bool msix) | |||
482 | for (i = 0; i < nvec; i++) | 482 | for (i = 0; i < nvec; i++) |
483 | vdev->msix[i].entry = i; | 483 | vdev->msix[i].entry = i; |
484 | 484 | ||
485 | ret = pci_enable_msix(pdev, vdev->msix, nvec); | 485 | ret = pci_enable_msix_range(pdev, vdev->msix, 1, nvec); |
486 | if (ret) { | 486 | if (ret < nvec) { |
487 | if (ret > 0) | ||
488 | pci_disable_msix(pdev); | ||
487 | kfree(vdev->msix); | 489 | kfree(vdev->msix); |
488 | kfree(vdev->ctx); | 490 | kfree(vdev->ctx); |
489 | return ret; | 491 | return ret; |
490 | } | 492 | } |
491 | } else { | 493 | } else { |
492 | ret = pci_enable_msi_block(pdev, nvec); | 494 | ret = pci_enable_msi_range(pdev, 1, nvec); |
493 | if (ret) { | 495 | if (ret < nvec) { |
496 | if (ret > 0) | ||
497 | pci_disable_msi(pdev); | ||
494 | kfree(vdev->ctx); | 498 | kfree(vdev->ctx); |
495 | return ret; | 499 | return ret; |
496 | } | 500 | } |