diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/pci | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/pci')
76 files changed, 3686 insertions, 1847 deletions
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index fdc864f9cf23..7858a117e80b 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig | |||
@@ -21,17 +21,6 @@ config PCI_MSI | |||
21 | 21 | ||
22 | If you don't know what to do here, say N. | 22 | If you don't know what to do here, say N. |
23 | 23 | ||
24 | config PCI_LEGACY | ||
25 | bool "Enable deprecated pci_find_* API" | ||
26 | depends on PCI | ||
27 | default y | ||
28 | help | ||
29 | Say Y here if you want to include support for the deprecated | ||
30 | pci_find_slot() and pci_find_device() APIs. Most drivers have | ||
31 | been converted over to using the proper hotplug APIs, so this | ||
32 | option serves to include/exclude only a few drivers that are | ||
33 | still using this API. | ||
34 | |||
35 | config PCI_DEBUG | 24 | config PCI_DEBUG |
36 | bool "PCI Debugging" | 25 | bool "PCI Debugging" |
37 | depends on PCI && DEBUG_KERNEL | 26 | depends on PCI && DEBUG_KERNEL |
@@ -69,3 +58,10 @@ config PCI_IOV | |||
69 | physical resources. | 58 | physical resources. |
70 | 59 | ||
71 | If unsure, say N. | 60 | If unsure, say N. |
61 | |||
62 | config PCI_IOAPIC | ||
63 | bool | ||
64 | depends on PCI | ||
65 | depends on ACPI | ||
66 | depends on HOTPLUG | ||
67 | default y | ||
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 4a7f11d8f432..0b51857fbaf7 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile | |||
@@ -2,18 +2,19 @@ | |||
2 | # Makefile for the PCI bus specific drivers. | 2 | # Makefile for the PCI bus specific drivers. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += access.o bus.o probe.o remove.o pci.o quirks.o \ | 5 | obj-y += access.o bus.o probe.o remove.o pci.o \ |
6 | pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \ | 6 | pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \ |
7 | irq.o | 7 | irq.o vpd.o |
8 | obj-$(CONFIG_PROC_FS) += proc.o | 8 | obj-$(CONFIG_PROC_FS) += proc.o |
9 | obj-$(CONFIG_SYSFS) += slot.o | 9 | obj-$(CONFIG_SYSFS) += slot.o |
10 | 10 | ||
11 | obj-$(CONFIG_PCI_LEGACY) += legacy.o | 11 | obj-$(CONFIG_PCI_QUIRKS) += quirks.o |
12 | CFLAGS_legacy.o += -Wno-deprecated-declarations | ||
13 | 12 | ||
14 | # Build PCI Express stuff if needed | 13 | # Build PCI Express stuff if needed |
15 | obj-$(CONFIG_PCIEPORTBUS) += pcie/ | 14 | obj-$(CONFIG_PCIEPORTBUS) += pcie/ |
16 | 15 | ||
16 | obj-$(CONFIG_PCI_IOAPIC) += ioapic.o | ||
17 | |||
17 | obj-$(CONFIG_HOTPLUG) += hotplug.o | 18 | obj-$(CONFIG_HOTPLUG) += hotplug.o |
18 | 19 | ||
19 | # Build the PCI Hotplug drivers if we were asked to | 20 | # Build the PCI Hotplug drivers if we were asked to |
@@ -47,6 +48,7 @@ obj-$(CONFIG_PPC) += setup-bus.o | |||
47 | obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o | 48 | obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o |
48 | obj-$(CONFIG_X86_VISWS) += setup-irq.o | 49 | obj-$(CONFIG_X86_VISWS) += setup-irq.o |
49 | obj-$(CONFIG_MN10300) += setup-bus.o | 50 | obj-$(CONFIG_MN10300) += setup-bus.o |
51 | obj-$(CONFIG_MICROBLAZE) += setup-bus.o | ||
50 | 52 | ||
51 | # | 53 | # |
52 | # ACPI Related PCI FW Functions | 54 | # ACPI Related PCI FW Functions |
diff --git a/drivers/pci/access.c b/drivers/pci/access.c index db23200c4874..2f646fe1260f 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <linux/pci.h> | 2 | #include <linux/pci.h> |
3 | #include <linux/module.h> | 3 | #include <linux/module.h> |
4 | #include <linux/sched.h> | 4 | #include <linux/sched.h> |
5 | #include <linux/slab.h> | ||
5 | #include <linux/ioport.h> | 6 | #include <linux/ioport.h> |
6 | #include <linux/wait.h> | 7 | #include <linux/wait.h> |
7 | 8 | ||
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index cef28a79103f..628ea20a8841 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -14,9 +14,56 @@ | |||
14 | #include <linux/ioport.h> | 14 | #include <linux/ioport.h> |
15 | #include <linux/proc_fs.h> | 15 | #include <linux/proc_fs.h> |
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/slab.h> | ||
17 | 18 | ||
18 | #include "pci.h" | 19 | #include "pci.h" |
19 | 20 | ||
21 | void pci_bus_add_resource(struct pci_bus *bus, struct resource *res, | ||
22 | unsigned int flags) | ||
23 | { | ||
24 | struct pci_bus_resource *bus_res; | ||
25 | |||
26 | bus_res = kzalloc(sizeof(struct pci_bus_resource), GFP_KERNEL); | ||
27 | if (!bus_res) { | ||
28 | dev_err(&bus->dev, "can't add %pR resource\n", res); | ||
29 | return; | ||
30 | } | ||
31 | |||
32 | bus_res->res = res; | ||
33 | bus_res->flags = flags; | ||
34 | list_add_tail(&bus_res->list, &bus->resources); | ||
35 | } | ||
36 | |||
37 | struct resource *pci_bus_resource_n(const struct pci_bus *bus, int n) | ||
38 | { | ||
39 | struct pci_bus_resource *bus_res; | ||
40 | |||
41 | if (n < PCI_BRIDGE_RESOURCE_NUM) | ||
42 | return bus->resource[n]; | ||
43 | |||
44 | n -= PCI_BRIDGE_RESOURCE_NUM; | ||
45 | list_for_each_entry(bus_res, &bus->resources, list) { | ||
46 | if (n-- == 0) | ||
47 | return bus_res->res; | ||
48 | } | ||
49 | return NULL; | ||
50 | } | ||
51 | EXPORT_SYMBOL_GPL(pci_bus_resource_n); | ||
52 | |||
53 | void pci_bus_remove_resources(struct pci_bus *bus) | ||
54 | { | ||
55 | struct pci_bus_resource *bus_res, *tmp; | ||
56 | int i; | ||
57 | |||
58 | for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) | ||
59 | bus->resource[i] = 0; | ||
60 | |||
61 | list_for_each_entry_safe(bus_res, tmp, &bus->resources, list) { | ||
62 | list_del(&bus_res->list); | ||
63 | kfree(bus_res); | ||
64 | } | ||
65 | } | ||
66 | |||
20 | /** | 67 | /** |
21 | * pci_bus_alloc_resource - allocate a resource from a parent bus | 68 | * pci_bus_alloc_resource - allocate a resource from a parent bus |
22 | * @bus: PCI bus | 69 | * @bus: PCI bus |
@@ -36,11 +83,14 @@ int | |||
36 | pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | 83 | pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, |
37 | resource_size_t size, resource_size_t align, | 84 | resource_size_t size, resource_size_t align, |
38 | resource_size_t min, unsigned int type_mask, | 85 | resource_size_t min, unsigned int type_mask, |
39 | void (*alignf)(void *, struct resource *, resource_size_t, | 86 | resource_size_t (*alignf)(void *, |
40 | resource_size_t), | 87 | const struct resource *, |
88 | resource_size_t, | ||
89 | resource_size_t), | ||
41 | void *alignf_data) | 90 | void *alignf_data) |
42 | { | 91 | { |
43 | int i, ret = -ENOMEM; | 92 | int i, ret = -ENOMEM; |
93 | struct resource *r; | ||
44 | resource_size_t max = -1; | 94 | resource_size_t max = -1; |
45 | 95 | ||
46 | type_mask |= IORESOURCE_IO | IORESOURCE_MEM; | 96 | type_mask |= IORESOURCE_IO | IORESOURCE_MEM; |
@@ -49,8 +99,7 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | |||
49 | if (!(res->flags & IORESOURCE_MEM_64)) | 99 | if (!(res->flags & IORESOURCE_MEM_64)) |
50 | max = PCIBIOS_MAX_MEM_32; | 100 | max = PCIBIOS_MAX_MEM_32; |
51 | 101 | ||
52 | for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { | 102 | pci_bus_for_each_resource(bus, r, i) { |
53 | struct resource *r = bus->resource[i]; | ||
54 | if (!r) | 103 | if (!r) |
55 | continue; | 104 | continue; |
56 | 105 | ||
@@ -240,9 +289,9 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), | |||
240 | next = dev->bus_list.next; | 289 | next = dev->bus_list.next; |
241 | 290 | ||
242 | /* Run device routines with the device locked */ | 291 | /* Run device routines with the device locked */ |
243 | down(&dev->dev.sem); | 292 | device_lock(&dev->dev); |
244 | retval = cb(dev, userdata); | 293 | retval = cb(dev, userdata); |
245 | up(&dev->dev.sem); | 294 | device_unlock(&dev->dev); |
246 | if (retval) | 295 | if (retval) |
247 | break; | 296 | break; |
248 | } | 297 | } |
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index b952ebc7a78b..33ead97f0c4b 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/interrupt.h> | 35 | #include <linux/interrupt.h> |
36 | #include <linux/tboot.h> | 36 | #include <linux/tboot.h> |
37 | #include <linux/dmi.h> | 37 | #include <linux/dmi.h> |
38 | #include <linux/slab.h> | ||
38 | 39 | ||
39 | #define PREFIX "DMAR: " | 40 | #define PREFIX "DMAR: " |
40 | 41 | ||
@@ -320,7 +321,7 @@ found: | |||
320 | for (bus = dev->bus; bus; bus = bus->parent) { | 321 | for (bus = dev->bus; bus; bus = bus->parent) { |
321 | struct pci_dev *bridge = bus->self; | 322 | struct pci_dev *bridge = bus->self; |
322 | 323 | ||
323 | if (!bridge || !bridge->is_pcie || | 324 | if (!bridge || !pci_is_pcie(bridge) || |
324 | bridge->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) | 325 | bridge->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) |
325 | return 0; | 326 | return 0; |
326 | 327 | ||
@@ -339,6 +340,35 @@ found: | |||
339 | } | 340 | } |
340 | #endif | 341 | #endif |
341 | 342 | ||
343 | #ifdef CONFIG_ACPI_NUMA | ||
344 | static int __init | ||
345 | dmar_parse_one_rhsa(struct acpi_dmar_header *header) | ||
346 | { | ||
347 | struct acpi_dmar_rhsa *rhsa; | ||
348 | struct dmar_drhd_unit *drhd; | ||
349 | |||
350 | rhsa = (struct acpi_dmar_rhsa *)header; | ||
351 | for_each_drhd_unit(drhd) { | ||
352 | if (drhd->reg_base_addr == rhsa->base_address) { | ||
353 | int node = acpi_map_pxm_to_node(rhsa->proximity_domain); | ||
354 | |||
355 | if (!node_online(node)) | ||
356 | node = -1; | ||
357 | drhd->iommu->node = node; | ||
358 | return 0; | ||
359 | } | ||
360 | } | ||
361 | WARN(1, "Your BIOS is broken; RHSA refers to non-existent DMAR unit at %llx\n" | ||
362 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", | ||
363 | drhd->reg_base_addr, | ||
364 | dmi_get_system_info(DMI_BIOS_VENDOR), | ||
365 | dmi_get_system_info(DMI_BIOS_VERSION), | ||
366 | dmi_get_system_info(DMI_PRODUCT_VERSION)); | ||
367 | |||
368 | return 0; | ||
369 | } | ||
370 | #endif | ||
371 | |||
342 | static void __init | 372 | static void __init |
343 | dmar_table_print_dmar_entry(struct acpi_dmar_header *header) | 373 | dmar_table_print_dmar_entry(struct acpi_dmar_header *header) |
344 | { | 374 | { |
@@ -458,7 +488,9 @@ parse_dmar_table(void) | |||
458 | #endif | 488 | #endif |
459 | break; | 489 | break; |
460 | case ACPI_DMAR_HARDWARE_AFFINITY: | 490 | case ACPI_DMAR_HARDWARE_AFFINITY: |
461 | /* We don't do anything with RHSA (yet?) */ | 491 | #ifdef CONFIG_ACPI_NUMA |
492 | ret = dmar_parse_one_rhsa(entry_header); | ||
493 | #endif | ||
462 | break; | 494 | break; |
463 | default: | 495 | default: |
464 | printk(KERN_WARNING PREFIX | 496 | printk(KERN_WARNING PREFIX |
@@ -582,6 +614,8 @@ int __init dmar_table_init(void) | |||
582 | return 0; | 614 | return 0; |
583 | } | 615 | } |
584 | 616 | ||
617 | static int bios_warned; | ||
618 | |||
585 | int __init check_zero_address(void) | 619 | int __init check_zero_address(void) |
586 | { | 620 | { |
587 | struct acpi_table_dmar *dmar; | 621 | struct acpi_table_dmar *dmar; |
@@ -601,6 +635,9 @@ int __init check_zero_address(void) | |||
601 | } | 635 | } |
602 | 636 | ||
603 | if (entry_header->type == ACPI_DMAR_TYPE_HARDWARE_UNIT) { | 637 | if (entry_header->type == ACPI_DMAR_TYPE_HARDWARE_UNIT) { |
638 | void __iomem *addr; | ||
639 | u64 cap, ecap; | ||
640 | |||
604 | drhd = (void *)entry_header; | 641 | drhd = (void *)entry_header; |
605 | if (!drhd->address) { | 642 | if (!drhd->address) { |
606 | /* Promote an attitude of violence to a BIOS engineer today */ | 643 | /* Promote an attitude of violence to a BIOS engineer today */ |
@@ -609,17 +646,40 @@ int __init check_zero_address(void) | |||
609 | dmi_get_system_info(DMI_BIOS_VENDOR), | 646 | dmi_get_system_info(DMI_BIOS_VENDOR), |
610 | dmi_get_system_info(DMI_BIOS_VERSION), | 647 | dmi_get_system_info(DMI_BIOS_VERSION), |
611 | dmi_get_system_info(DMI_PRODUCT_VERSION)); | 648 | dmi_get_system_info(DMI_PRODUCT_VERSION)); |
612 | #ifdef CONFIG_DMAR | 649 | bios_warned = 1; |
613 | dmar_disabled = 1; | 650 | goto failed; |
614 | #endif | 651 | } |
615 | return 0; | 652 | |
653 | addr = early_ioremap(drhd->address, VTD_PAGE_SIZE); | ||
654 | if (!addr ) { | ||
655 | printk("IOMMU: can't validate: %llx\n", drhd->address); | ||
656 | goto failed; | ||
657 | } | ||
658 | cap = dmar_readq(addr + DMAR_CAP_REG); | ||
659 | ecap = dmar_readq(addr + DMAR_ECAP_REG); | ||
660 | early_iounmap(addr, VTD_PAGE_SIZE); | ||
661 | if (cap == (uint64_t)-1 && ecap == (uint64_t)-1) { | ||
662 | /* Promote an attitude of violence to a BIOS engineer today */ | ||
663 | WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n" | ||
664 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", | ||
665 | drhd->address, | ||
666 | dmi_get_system_info(DMI_BIOS_VENDOR), | ||
667 | dmi_get_system_info(DMI_BIOS_VERSION), | ||
668 | dmi_get_system_info(DMI_PRODUCT_VERSION)); | ||
669 | bios_warned = 1; | ||
670 | goto failed; | ||
616 | } | 671 | } |
617 | break; | ||
618 | } | 672 | } |
619 | 673 | ||
620 | entry_header = ((void *)entry_header + entry_header->length); | 674 | entry_header = ((void *)entry_header + entry_header->length); |
621 | } | 675 | } |
622 | return 1; | 676 | return 1; |
677 | |||
678 | failed: | ||
679 | #ifdef CONFIG_DMAR | ||
680 | dmar_disabled = 1; | ||
681 | #endif | ||
682 | return 0; | ||
623 | } | 683 | } |
624 | 684 | ||
625 | void __init detect_intel_iommu(void) | 685 | void __init detect_intel_iommu(void) |
@@ -645,9 +705,15 @@ void __init detect_intel_iommu(void) | |||
645 | "x2apic and Intr-remapping.\n"); | 705 | "x2apic and Intr-remapping.\n"); |
646 | #endif | 706 | #endif |
647 | #ifdef CONFIG_DMAR | 707 | #ifdef CONFIG_DMAR |
648 | if (ret && !no_iommu && !iommu_detected && !swiotlb && | 708 | if (ret && !no_iommu && !iommu_detected && !dmar_disabled) { |
649 | !dmar_disabled) | ||
650 | iommu_detected = 1; | 709 | iommu_detected = 1; |
710 | /* Make sure ACS will be enabled */ | ||
711 | pci_request_acs(); | ||
712 | } | ||
713 | #endif | ||
714 | #ifdef CONFIG_X86 | ||
715 | if (ret) | ||
716 | x86_init.iommu.iommu_init = intel_iommu_init; | ||
651 | #endif | 717 | #endif |
652 | } | 718 | } |
653 | early_acpi_os_unmap_memory(dmar_tbl, dmar_tbl_size); | 719 | early_acpi_os_unmap_memory(dmar_tbl, dmar_tbl_size); |
@@ -664,6 +730,18 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) | |||
664 | int agaw = 0; | 730 | int agaw = 0; |
665 | int msagaw = 0; | 731 | int msagaw = 0; |
666 | 732 | ||
733 | if (!drhd->reg_base_addr) { | ||
734 | if (!bios_warned) { | ||
735 | WARN(1, "Your BIOS is broken; DMAR reported at address zero!\n" | ||
736 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", | ||
737 | dmi_get_system_info(DMI_BIOS_VENDOR), | ||
738 | dmi_get_system_info(DMI_BIOS_VERSION), | ||
739 | dmi_get_system_info(DMI_PRODUCT_VERSION)); | ||
740 | bios_warned = 1; | ||
741 | } | ||
742 | return -EINVAL; | ||
743 | } | ||
744 | |||
667 | iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); | 745 | iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); |
668 | if (!iommu) | 746 | if (!iommu) |
669 | return -ENOMEM; | 747 | return -ENOMEM; |
@@ -680,13 +758,16 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) | |||
680 | iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); | 758 | iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); |
681 | 759 | ||
682 | if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) { | 760 | if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) { |
683 | /* Promote an attitude of violence to a BIOS engineer today */ | 761 | if (!bios_warned) { |
684 | WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n" | 762 | /* Promote an attitude of violence to a BIOS engineer today */ |
685 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", | 763 | WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n" |
686 | drhd->reg_base_addr, | 764 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", |
687 | dmi_get_system_info(DMI_BIOS_VENDOR), | 765 | drhd->reg_base_addr, |
688 | dmi_get_system_info(DMI_BIOS_VERSION), | 766 | dmi_get_system_info(DMI_BIOS_VENDOR), |
689 | dmi_get_system_info(DMI_PRODUCT_VERSION)); | 767 | dmi_get_system_info(DMI_BIOS_VERSION), |
768 | dmi_get_system_info(DMI_PRODUCT_VERSION)); | ||
769 | bios_warned = 1; | ||
770 | } | ||
690 | goto err_unmap; | 771 | goto err_unmap; |
691 | } | 772 | } |
692 | 773 | ||
@@ -709,6 +790,8 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) | |||
709 | iommu->agaw = agaw; | 790 | iommu->agaw = agaw; |
710 | iommu->msagaw = msagaw; | 791 | iommu->msagaw = msagaw; |
711 | 792 | ||
793 | iommu->node = -1; | ||
794 | |||
712 | /* the registers might be more than one page */ | 795 | /* the registers might be more than one page */ |
713 | map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap), | 796 | map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap), |
714 | cap_max_fault_reg_offset(iommu->cap)); | 797 | cap_max_fault_reg_offset(iommu->cap)); |
@@ -1050,6 +1133,7 @@ static void __dmar_enable_qi(struct intel_iommu *iommu) | |||
1050 | int dmar_enable_qi(struct intel_iommu *iommu) | 1133 | int dmar_enable_qi(struct intel_iommu *iommu) |
1051 | { | 1134 | { |
1052 | struct q_inval *qi; | 1135 | struct q_inval *qi; |
1136 | struct page *desc_page; | ||
1053 | 1137 | ||
1054 | if (!ecap_qis(iommu->ecap)) | 1138 | if (!ecap_qis(iommu->ecap)) |
1055 | return -ENOENT; | 1139 | return -ENOENT; |
@@ -1066,13 +1150,16 @@ int dmar_enable_qi(struct intel_iommu *iommu) | |||
1066 | 1150 | ||
1067 | qi = iommu->qi; | 1151 | qi = iommu->qi; |
1068 | 1152 | ||
1069 | qi->desc = (void *)(get_zeroed_page(GFP_ATOMIC)); | 1153 | |
1070 | if (!qi->desc) { | 1154 | desc_page = alloc_pages_node(iommu->node, GFP_ATOMIC | __GFP_ZERO, 0); |
1155 | if (!desc_page) { | ||
1071 | kfree(qi); | 1156 | kfree(qi); |
1072 | iommu->qi = 0; | 1157 | iommu->qi = 0; |
1073 | return -ENOMEM; | 1158 | return -ENOMEM; |
1074 | } | 1159 | } |
1075 | 1160 | ||
1161 | qi->desc = page_address(desc_page); | ||
1162 | |||
1076 | qi->desc_status = kmalloc(QI_LENGTH * sizeof(int), GFP_ATOMIC); | 1163 | qi->desc_status = kmalloc(QI_LENGTH * sizeof(int), GFP_ATOMIC); |
1077 | if (!qi->desc_status) { | 1164 | if (!qi->desc_status) { |
1078 | free_page((unsigned long) qi->desc); | 1165 | free_page((unsigned long) qi->desc); |
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile index 3625b094bf7e..6cd9f3c9887d 100644 --- a/drivers/pci/hotplug/Makefile +++ b/drivers/pci/hotplug/Makefile | |||
@@ -6,18 +6,22 @@ obj-$(CONFIG_HOTPLUG_PCI) += pci_hotplug.o | |||
6 | obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o | 6 | obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o |
7 | obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o | 7 | obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o |
8 | 8 | ||
9 | # pciehp should be linked before acpiphp in order to allow the native driver | 9 | # native drivers should be linked before acpiphp in order to allow the |
10 | # to attempt to bind first. We can then fall back to generic support. | 10 | # native driver to attempt to bind first. We can then fall back to |
11 | # generic support. | ||
11 | 12 | ||
12 | obj-$(CONFIG_HOTPLUG_PCI_PCIE) += pciehp.o | 13 | obj-$(CONFIG_HOTPLUG_PCI_PCIE) += pciehp.o |
13 | obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o | ||
14 | obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o | ||
15 | obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550) += cpcihp_zt5550.o | 14 | obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550) += cpcihp_zt5550.o |
16 | obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC) += cpcihp_generic.o | 15 | obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC) += cpcihp_generic.o |
17 | obj-$(CONFIG_HOTPLUG_PCI_SHPC) += shpchp.o | 16 | obj-$(CONFIG_HOTPLUG_PCI_SHPC) += shpchp.o |
18 | obj-$(CONFIG_HOTPLUG_PCI_RPA) += rpaphp.o | 17 | obj-$(CONFIG_HOTPLUG_PCI_RPA) += rpaphp.o |
19 | obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o | 18 | obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o |
20 | obj-$(CONFIG_HOTPLUG_PCI_SGI) += sgi_hotplug.o | 19 | obj-$(CONFIG_HOTPLUG_PCI_SGI) += sgi_hotplug.o |
20 | obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o | ||
21 | |||
22 | # acpiphp_ibm extends acpiphp, so should be linked afterwards. | ||
23 | |||
24 | obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o | ||
21 | 25 | ||
22 | # Link this last so it doesn't claim devices that have a real hotplug driver | 26 | # Link this last so it doesn't claim devices that have a real hotplug driver |
23 | obj-$(CONFIG_HOTPLUG_PCI_FAKE) += fakephp.o | 27 | obj-$(CONFIG_HOTPLUG_PCI_FAKE) += fakephp.o |
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index a73028ec52e5..45fcc1e96df9 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/pci_hotplug.h> | 32 | #include <linux/pci_hotplug.h> |
33 | #include <linux/acpi.h> | 33 | #include <linux/acpi.h> |
34 | #include <linux/pci-acpi.h> | 34 | #include <linux/pci-acpi.h> |
35 | #include <linux/slab.h> | ||
35 | 36 | ||
36 | #define MY_NAME "acpi_pcihp" | 37 | #define MY_NAME "acpi_pcihp" |
37 | 38 | ||
@@ -362,6 +363,8 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags) | |||
362 | status = acpi_pci_osc_control_set(handle, flags); | 363 | status = acpi_pci_osc_control_set(handle, flags); |
363 | if (ACPI_SUCCESS(status)) | 364 | if (ACPI_SUCCESS(status)) |
364 | goto got_one; | 365 | goto got_one; |
366 | if (status == AE_SUPPORT) | ||
367 | goto no_control; | ||
365 | kfree(string.pointer); | 368 | kfree(string.pointer); |
366 | string = (struct acpi_buffer){ ACPI_ALLOCATE_BUFFER, NULL }; | 369 | string = (struct acpi_buffer){ ACPI_ALLOCATE_BUFFER, NULL }; |
367 | } | 370 | } |
@@ -394,10 +397,9 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags) | |||
394 | if (ACPI_FAILURE(status)) | 397 | if (ACPI_FAILURE(status)) |
395 | break; | 398 | break; |
396 | } | 399 | } |
397 | 400 | no_control: | |
398 | dbg("Cannot get control of hotplug hardware for pci %s\n", | 401 | dbg("Cannot get control of hotplug hardware for pci %s\n", |
399 | pci_name(pdev)); | 402 | pci_name(pdev)); |
400 | |||
401 | kfree(string.pointer); | 403 | kfree(string.pointer); |
402 | return -ENODEV; | 404 | return -ENODEV; |
403 | got_one: | 405 | got_one: |
@@ -471,7 +473,7 @@ int acpi_pci_detect_ejectable(acpi_handle handle) | |||
471 | return found; | 473 | return found; |
472 | 474 | ||
473 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, | 475 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, |
474 | check_hotplug, (void *)&found, NULL); | 476 | check_hotplug, NULL, (void *)&found, NULL); |
475 | return found; | 477 | return found; |
476 | } | 478 | } |
477 | EXPORT_SYMBOL_GPL(acpi_pci_detect_ejectable); | 479 | EXPORT_SYMBOL_GPL(acpi_pci_detect_ejectable); |
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index 7d938df79206..bab52047baa8 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h | |||
@@ -146,12 +146,6 @@ struct acpiphp_attention_info | |||
146 | struct module *owner; | 146 | struct module *owner; |
147 | }; | 147 | }; |
148 | 148 | ||
149 | struct acpiphp_ioapic { | ||
150 | struct pci_dev *dev; | ||
151 | u32 gsi_base; | ||
152 | struct list_head list; | ||
153 | }; | ||
154 | |||
155 | /* PCI bus bridge HID */ | 149 | /* PCI bus bridge HID */ |
156 | #define ACPI_PCI_HOST_HID "PNP0A03" | 150 | #define ACPI_PCI_HOST_HID "PNP0A03" |
157 | 151 | ||
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index 4dd7114964ac..efa9f2de51c1 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c | |||
@@ -332,8 +332,6 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot) | |||
332 | slot->hotplug_slot->info->attention_status = 0; | 332 | slot->hotplug_slot->info->attention_status = 0; |
333 | slot->hotplug_slot->info->latch_status = acpiphp_get_latch_status(slot->acpi_slot); | 333 | slot->hotplug_slot->info->latch_status = acpiphp_get_latch_status(slot->acpi_slot); |
334 | slot->hotplug_slot->info->adapter_status = acpiphp_get_adapter_status(slot->acpi_slot); | 334 | slot->hotplug_slot->info->adapter_status = acpiphp_get_adapter_status(slot->acpi_slot); |
335 | slot->hotplug_slot->info->max_bus_speed = PCI_SPEED_UNKNOWN; | ||
336 | slot->hotplug_slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN; | ||
337 | 335 | ||
338 | acpiphp_slot->slot = slot; | 336 | acpiphp_slot->slot = slot; |
339 | snprintf(name, SLOT_NAME_SIZE, "%llu", slot->acpi_slot->sun); | 337 | snprintf(name, SLOT_NAME_SIZE, "%llu", slot->acpi_slot->sun); |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 58d25a163a8b..cb23aa2ebf96 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -47,13 +47,12 @@ | |||
47 | #include <linux/pci_hotplug.h> | 47 | #include <linux/pci_hotplug.h> |
48 | #include <linux/pci-acpi.h> | 48 | #include <linux/pci-acpi.h> |
49 | #include <linux/mutex.h> | 49 | #include <linux/mutex.h> |
50 | #include <linux/slab.h> | ||
50 | 51 | ||
51 | #include "../pci.h" | 52 | #include "../pci.h" |
52 | #include "acpiphp.h" | 53 | #include "acpiphp.h" |
53 | 54 | ||
54 | static LIST_HEAD(bridge_list); | 55 | static LIST_HEAD(bridge_list); |
55 | static LIST_HEAD(ioapic_list); | ||
56 | static DEFINE_SPINLOCK(ioapic_list_lock); | ||
57 | 56 | ||
58 | #define MY_NAME "acpiphp_glue" | 57 | #define MY_NAME "acpiphp_glue" |
59 | 58 | ||
@@ -266,7 +265,7 @@ static int detect_ejectable_slots(acpi_handle handle) | |||
266 | int found = acpi_pci_detect_ejectable(handle); | 265 | int found = acpi_pci_detect_ejectable(handle); |
267 | if (!found) { | 266 | if (!found) { |
268 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, | 267 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, |
269 | is_pci_dock_device, (void *)&found, NULL); | 268 | is_pci_dock_device, NULL, (void *)&found, NULL); |
270 | } | 269 | } |
271 | return found; | 270 | return found; |
272 | } | 271 | } |
@@ -281,7 +280,7 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge) | |||
281 | 280 | ||
282 | /* register all slot objects under this bridge */ | 281 | /* register all slot objects under this bridge */ |
283 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1, | 282 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1, |
284 | register_slot, bridge, NULL); | 283 | register_slot, NULL, bridge, NULL); |
285 | if (ACPI_FAILURE(status)) { | 284 | if (ACPI_FAILURE(status)) { |
286 | list_del(&bridge->list); | 285 | list_del(&bridge->list); |
287 | return; | 286 | return; |
@@ -311,17 +310,13 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge) | |||
311 | /* find acpiphp_func from acpiphp_bridge */ | 310 | /* find acpiphp_func from acpiphp_bridge */ |
312 | static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle) | 311 | static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle) |
313 | { | 312 | { |
314 | struct list_head *node, *l; | ||
315 | struct acpiphp_bridge *bridge; | 313 | struct acpiphp_bridge *bridge; |
316 | struct acpiphp_slot *slot; | 314 | struct acpiphp_slot *slot; |
317 | struct acpiphp_func *func; | 315 | struct acpiphp_func *func; |
318 | 316 | ||
319 | list_for_each(node, &bridge_list) { | 317 | list_for_each_entry(bridge, &bridge_list, list) { |
320 | bridge = list_entry(node, struct acpiphp_bridge, list); | ||
321 | for (slot = bridge->slots; slot; slot = slot->next) { | 318 | for (slot = bridge->slots; slot; slot = slot->next) { |
322 | list_for_each(l, &slot->funcs) { | 319 | list_for_each_entry(func, &slot->funcs, sibling) { |
323 | func = list_entry(l, struct acpiphp_func, | ||
324 | sibling); | ||
325 | if (func->handle == handle) | 320 | if (func->handle == handle) |
326 | return func; | 321 | return func; |
327 | } | 322 | } |
@@ -447,7 +442,7 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
447 | 442 | ||
448 | /* search P2P bridges under this p2p bridge */ | 443 | /* search P2P bridges under this p2p bridge */ |
449 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, | 444 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, |
450 | find_p2p_bridge, NULL, NULL); | 445 | find_p2p_bridge, NULL, NULL, NULL); |
451 | if (ACPI_FAILURE(status)) | 446 | if (ACPI_FAILURE(status)) |
452 | warn("find_p2p_bridge failed (error code = 0x%x)\n", status); | 447 | warn("find_p2p_bridge failed (error code = 0x%x)\n", status); |
453 | 448 | ||
@@ -485,7 +480,7 @@ static int add_bridge(acpi_handle handle) | |||
485 | 480 | ||
486 | /* search P2P bridges under this host bridge */ | 481 | /* search P2P bridges under this host bridge */ |
487 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, | 482 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, |
488 | find_p2p_bridge, NULL, NULL); | 483 | find_p2p_bridge, NULL, NULL, NULL); |
489 | 484 | ||
490 | if (ACPI_FAILURE(status)) | 485 | if (ACPI_FAILURE(status)) |
491 | warn("find_p2p_bridge failed (error code = 0x%x)\n", status); | 486 | warn("find_p2p_bridge failed (error code = 0x%x)\n", status); |
@@ -495,21 +490,19 @@ static int add_bridge(acpi_handle handle) | |||
495 | 490 | ||
496 | static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) | 491 | static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) |
497 | { | 492 | { |
498 | struct list_head *head; | 493 | struct acpiphp_bridge *bridge; |
499 | list_for_each(head, &bridge_list) { | 494 | |
500 | struct acpiphp_bridge *bridge = list_entry(head, | 495 | list_for_each_entry(bridge, &bridge_list, list) |
501 | struct acpiphp_bridge, list); | ||
502 | if (bridge->handle == handle) | 496 | if (bridge->handle == handle) |
503 | return bridge; | 497 | return bridge; |
504 | } | ||
505 | 498 | ||
506 | return NULL; | 499 | return NULL; |
507 | } | 500 | } |
508 | 501 | ||
509 | static void cleanup_bridge(struct acpiphp_bridge *bridge) | 502 | static void cleanup_bridge(struct acpiphp_bridge *bridge) |
510 | { | 503 | { |
511 | struct list_head *list, *tmp; | 504 | struct acpiphp_slot *slot, *next; |
512 | struct acpiphp_slot *slot; | 505 | struct acpiphp_func *func, *tmp; |
513 | acpi_status status; | 506 | acpi_status status; |
514 | acpi_handle handle = bridge->handle; | 507 | acpi_handle handle = bridge->handle; |
515 | 508 | ||
@@ -530,10 +523,8 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
530 | 523 | ||
531 | slot = bridge->slots; | 524 | slot = bridge->slots; |
532 | while (slot) { | 525 | while (slot) { |
533 | struct acpiphp_slot *next = slot->next; | 526 | next = slot->next; |
534 | list_for_each_safe (list, tmp, &slot->funcs) { | 527 | list_for_each_entry_safe(func, tmp, &slot->funcs, sibling) { |
535 | struct acpiphp_func *func; | ||
536 | func = list_entry(list, struct acpiphp_func, sibling); | ||
537 | if (is_dock_device(func->handle)) { | 528 | if (is_dock_device(func->handle)) { |
538 | unregister_hotplug_dock_device(func->handle); | 529 | unregister_hotplug_dock_device(func->handle); |
539 | unregister_dock_notifier(&func->nb); | 530 | unregister_dock_notifier(&func->nb); |
@@ -545,7 +536,7 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
545 | if (ACPI_FAILURE(status)) | 536 | if (ACPI_FAILURE(status)) |
546 | err("failed to remove notify handler\n"); | 537 | err("failed to remove notify handler\n"); |
547 | } | 538 | } |
548 | list_del(list); | 539 | list_del(&func->sibling); |
549 | kfree(func); | 540 | kfree(func); |
550 | } | 541 | } |
551 | acpiphp_unregister_hotplug_slot(slot); | 542 | acpiphp_unregister_hotplug_slot(slot); |
@@ -573,7 +564,7 @@ cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
573 | /* cleanup p2p bridges under this P2P bridge | 564 | /* cleanup p2p bridges under this P2P bridge |
574 | in a depth-first manner */ | 565 | in a depth-first manner */ |
575 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, | 566 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, |
576 | cleanup_p2p_bridge, NULL, NULL); | 567 | cleanup_p2p_bridge, NULL, NULL, NULL); |
577 | 568 | ||
578 | bridge = acpiphp_handle_to_bridge(handle); | 569 | bridge = acpiphp_handle_to_bridge(handle); |
579 | if (bridge) | 570 | if (bridge) |
@@ -589,7 +580,7 @@ static void remove_bridge(acpi_handle handle) | |||
589 | /* cleanup p2p bridges under this host bridge | 580 | /* cleanup p2p bridges under this host bridge |
590 | in a depth-first manner */ | 581 | in a depth-first manner */ |
591 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, | 582 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, |
592 | (u32)1, cleanup_p2p_bridge, NULL, NULL); | 583 | (u32)1, cleanup_p2p_bridge, NULL, NULL, NULL); |
593 | 584 | ||
594 | /* | 585 | /* |
595 | * On root bridges with hotplug slots directly underneath (ie, | 586 | * On root bridges with hotplug slots directly underneath (ie, |
@@ -606,204 +597,17 @@ static void remove_bridge(acpi_handle handle) | |||
606 | handle_hotplug_event_bridge); | 597 | handle_hotplug_event_bridge); |
607 | } | 598 | } |
608 | 599 | ||
609 | static struct pci_dev * get_apic_pci_info(acpi_handle handle) | ||
610 | { | ||
611 | struct pci_dev *dev; | ||
612 | |||
613 | dev = acpi_get_pci_dev(handle); | ||
614 | if (!dev) | ||
615 | return NULL; | ||
616 | |||
617 | if ((dev->class != PCI_CLASS_SYSTEM_PIC_IOAPIC) && | ||
618 | (dev->class != PCI_CLASS_SYSTEM_PIC_IOXAPIC)) | ||
619 | { | ||
620 | pci_dev_put(dev); | ||
621 | return NULL; | ||
622 | } | ||
623 | |||
624 | return dev; | ||
625 | } | ||
626 | |||
627 | static int get_gsi_base(acpi_handle handle, u32 *gsi_base) | ||
628 | { | ||
629 | acpi_status status; | ||
630 | int result = -1; | ||
631 | unsigned long long gsb; | ||
632 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
633 | union acpi_object *obj; | ||
634 | void *table; | ||
635 | |||
636 | status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb); | ||
637 | if (ACPI_SUCCESS(status)) { | ||
638 | *gsi_base = (u32)gsb; | ||
639 | return 0; | ||
640 | } | ||
641 | |||
642 | status = acpi_evaluate_object(handle, "_MAT", NULL, &buffer); | ||
643 | if (ACPI_FAILURE(status) || !buffer.length || !buffer.pointer) | ||
644 | return -1; | ||
645 | |||
646 | obj = buffer.pointer; | ||
647 | if (obj->type != ACPI_TYPE_BUFFER) | ||
648 | goto out; | ||
649 | |||
650 | table = obj->buffer.pointer; | ||
651 | switch (((struct acpi_subtable_header *)table)->type) { | ||
652 | case ACPI_MADT_TYPE_IO_SAPIC: | ||
653 | *gsi_base = ((struct acpi_madt_io_sapic *)table)->global_irq_base; | ||
654 | result = 0; | ||
655 | break; | ||
656 | case ACPI_MADT_TYPE_IO_APIC: | ||
657 | *gsi_base = ((struct acpi_madt_io_apic *)table)->global_irq_base; | ||
658 | result = 0; | ||
659 | break; | ||
660 | default: | ||
661 | break; | ||
662 | } | ||
663 | out: | ||
664 | kfree(buffer.pointer); | ||
665 | return result; | ||
666 | } | ||
667 | |||
668 | static acpi_status | ||
669 | ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
670 | { | ||
671 | acpi_status status; | ||
672 | unsigned long long sta; | ||
673 | acpi_handle tmp; | ||
674 | struct pci_dev *pdev; | ||
675 | u32 gsi_base; | ||
676 | u64 phys_addr; | ||
677 | struct acpiphp_ioapic *ioapic; | ||
678 | |||
679 | /* Evaluate _STA if present */ | ||
680 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); | ||
681 | if (ACPI_SUCCESS(status) && sta != ACPI_STA_ALL) | ||
682 | return AE_CTRL_DEPTH; | ||
683 | |||
684 | /* Scan only PCI bus scope */ | ||
685 | status = acpi_get_handle(handle, "_HID", &tmp); | ||
686 | if (ACPI_SUCCESS(status)) | ||
687 | return AE_CTRL_DEPTH; | ||
688 | |||
689 | if (get_gsi_base(handle, &gsi_base)) | ||
690 | return AE_OK; | ||
691 | |||
692 | ioapic = kmalloc(sizeof(*ioapic), GFP_KERNEL); | ||
693 | if (!ioapic) | ||
694 | return AE_NO_MEMORY; | ||
695 | |||
696 | pdev = get_apic_pci_info(handle); | ||
697 | if (!pdev) | ||
698 | goto exit_kfree; | ||
699 | |||
700 | if (pci_enable_device(pdev)) | ||
701 | goto exit_pci_dev_put; | ||
702 | |||
703 | pci_set_master(pdev); | ||
704 | |||
705 | if (pci_request_region(pdev, 0, "I/O APIC(acpiphp)")) | ||
706 | goto exit_pci_disable_device; | ||
707 | |||
708 | phys_addr = pci_resource_start(pdev, 0); | ||
709 | if (acpi_register_ioapic(handle, phys_addr, gsi_base)) | ||
710 | goto exit_pci_release_region; | ||
711 | |||
712 | ioapic->gsi_base = gsi_base; | ||
713 | ioapic->dev = pdev; | ||
714 | spin_lock(&ioapic_list_lock); | ||
715 | list_add_tail(&ioapic->list, &ioapic_list); | ||
716 | spin_unlock(&ioapic_list_lock); | ||
717 | |||
718 | return AE_OK; | ||
719 | |||
720 | exit_pci_release_region: | ||
721 | pci_release_region(pdev, 0); | ||
722 | exit_pci_disable_device: | ||
723 | pci_disable_device(pdev); | ||
724 | exit_pci_dev_put: | ||
725 | pci_dev_put(pdev); | ||
726 | exit_kfree: | ||
727 | kfree(ioapic); | ||
728 | |||
729 | return AE_OK; | ||
730 | } | ||
731 | |||
732 | static acpi_status | ||
733 | ioapic_remove(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
734 | { | ||
735 | acpi_status status; | ||
736 | unsigned long long sta; | ||
737 | acpi_handle tmp; | ||
738 | u32 gsi_base; | ||
739 | struct acpiphp_ioapic *pos, *n, *ioapic = NULL; | ||
740 | |||
741 | /* Evaluate _STA if present */ | ||
742 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); | ||
743 | if (ACPI_SUCCESS(status) && sta != ACPI_STA_ALL) | ||
744 | return AE_CTRL_DEPTH; | ||
745 | |||
746 | /* Scan only PCI bus scope */ | ||
747 | status = acpi_get_handle(handle, "_HID", &tmp); | ||
748 | if (ACPI_SUCCESS(status)) | ||
749 | return AE_CTRL_DEPTH; | ||
750 | |||
751 | if (get_gsi_base(handle, &gsi_base)) | ||
752 | return AE_OK; | ||
753 | |||
754 | acpi_unregister_ioapic(handle, gsi_base); | ||
755 | |||
756 | spin_lock(&ioapic_list_lock); | ||
757 | list_for_each_entry_safe(pos, n, &ioapic_list, list) { | ||
758 | if (pos->gsi_base != gsi_base) | ||
759 | continue; | ||
760 | ioapic = pos; | ||
761 | list_del(&ioapic->list); | ||
762 | break; | ||
763 | } | ||
764 | spin_unlock(&ioapic_list_lock); | ||
765 | |||
766 | if (!ioapic) | ||
767 | return AE_OK; | ||
768 | |||
769 | pci_release_region(ioapic->dev, 0); | ||
770 | pci_disable_device(ioapic->dev); | ||
771 | pci_dev_put(ioapic->dev); | ||
772 | kfree(ioapic); | ||
773 | |||
774 | return AE_OK; | ||
775 | } | ||
776 | |||
777 | static int acpiphp_configure_ioapics(acpi_handle handle) | ||
778 | { | ||
779 | ioapic_add(handle, 0, NULL, NULL); | ||
780 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, | ||
781 | ACPI_UINT32_MAX, ioapic_add, NULL, NULL); | ||
782 | return 0; | ||
783 | } | ||
784 | |||
785 | static int acpiphp_unconfigure_ioapics(acpi_handle handle) | ||
786 | { | ||
787 | ioapic_remove(handle, 0, NULL, NULL); | ||
788 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, | ||
789 | ACPI_UINT32_MAX, ioapic_remove, NULL, NULL); | ||
790 | return 0; | ||
791 | } | ||
792 | |||
793 | static int power_on_slot(struct acpiphp_slot *slot) | 600 | static int power_on_slot(struct acpiphp_slot *slot) |
794 | { | 601 | { |
795 | acpi_status status; | 602 | acpi_status status; |
796 | struct acpiphp_func *func; | 603 | struct acpiphp_func *func; |
797 | struct list_head *l; | ||
798 | int retval = 0; | 604 | int retval = 0; |
799 | 605 | ||
800 | /* if already enabled, just skip */ | 606 | /* if already enabled, just skip */ |
801 | if (slot->flags & SLOT_POWEREDON) | 607 | if (slot->flags & SLOT_POWEREDON) |
802 | goto err_exit; | 608 | goto err_exit; |
803 | 609 | ||
804 | list_for_each (l, &slot->funcs) { | 610 | list_for_each_entry(func, &slot->funcs, sibling) { |
805 | func = list_entry(l, struct acpiphp_func, sibling); | ||
806 | |||
807 | if (func->flags & FUNC_HAS_PS0) { | 611 | if (func->flags & FUNC_HAS_PS0) { |
808 | dbg("%s: executing _PS0\n", __func__); | 612 | dbg("%s: executing _PS0\n", __func__); |
809 | status = acpi_evaluate_object(func->handle, "_PS0", NULL, NULL); | 613 | status = acpi_evaluate_object(func->handle, "_PS0", NULL, NULL); |
@@ -829,7 +633,6 @@ static int power_off_slot(struct acpiphp_slot *slot) | |||
829 | { | 633 | { |
830 | acpi_status status; | 634 | acpi_status status; |
831 | struct acpiphp_func *func; | 635 | struct acpiphp_func *func; |
832 | struct list_head *l; | ||
833 | 636 | ||
834 | int retval = 0; | 637 | int retval = 0; |
835 | 638 | ||
@@ -837,9 +640,7 @@ static int power_off_slot(struct acpiphp_slot *slot) | |||
837 | if ((slot->flags & SLOT_POWEREDON) == 0) | 640 | if ((slot->flags & SLOT_POWEREDON) == 0) |
838 | goto err_exit; | 641 | goto err_exit; |
839 | 642 | ||
840 | list_for_each (l, &slot->funcs) { | 643 | list_for_each_entry(func, &slot->funcs, sibling) { |
841 | func = list_entry(l, struct acpiphp_func, sibling); | ||
842 | |||
843 | if (func->flags & FUNC_HAS_PS3) { | 644 | if (func->flags & FUNC_HAS_PS3) { |
844 | status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL); | 645 | status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL); |
845 | if (ACPI_FAILURE(status)) { | 646 | if (ACPI_FAILURE(status)) { |
@@ -920,12 +721,6 @@ static int acpiphp_bus_add(struct acpiphp_func *func) | |||
920 | -ret_val); | 721 | -ret_val); |
921 | goto acpiphp_bus_add_out; | 722 | goto acpiphp_bus_add_out; |
922 | } | 723 | } |
923 | /* | ||
924 | * try to start anyway. We could have failed to add | ||
925 | * simply because this bus had previously been added | ||
926 | * on another add. Don't bother with the return value | ||
927 | * we just keep going. | ||
928 | */ | ||
929 | ret_val = acpi_bus_start(device); | 724 | ret_val = acpi_bus_start(device); |
930 | 725 | ||
931 | acpiphp_bus_add_out: | 726 | acpiphp_bus_add_out: |
@@ -955,6 +750,24 @@ static int acpiphp_bus_trim(acpi_handle handle) | |||
955 | return retval; | 750 | return retval; |
956 | } | 751 | } |
957 | 752 | ||
753 | static void acpiphp_set_acpi_region(struct acpiphp_slot *slot) | ||
754 | { | ||
755 | struct acpiphp_func *func; | ||
756 | union acpi_object params[2]; | ||
757 | struct acpi_object_list arg_list; | ||
758 | |||
759 | list_for_each_entry(func, &slot->funcs, sibling) { | ||
760 | arg_list.count = 2; | ||
761 | arg_list.pointer = params; | ||
762 | params[0].type = ACPI_TYPE_INTEGER; | ||
763 | params[0].integer.value = ACPI_ADR_SPACE_PCI_CONFIG; | ||
764 | params[1].type = ACPI_TYPE_INTEGER; | ||
765 | params[1].integer.value = 1; | ||
766 | /* _REG is optional, we don't care about if there is failure */ | ||
767 | acpi_evaluate_object(func->handle, "_REG", &arg_list, NULL); | ||
768 | } | ||
769 | } | ||
770 | |||
958 | /** | 771 | /** |
959 | * enable_device - enable, configure a slot | 772 | * enable_device - enable, configure a slot |
960 | * @slot: slot to be enabled | 773 | * @slot: slot to be enabled |
@@ -966,7 +779,6 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
966 | { | 779 | { |
967 | struct pci_dev *dev; | 780 | struct pci_dev *dev; |
968 | struct pci_bus *bus = slot->bridge->pci_bus; | 781 | struct pci_bus *bus = slot->bridge->pci_bus; |
969 | struct list_head *l; | ||
970 | struct acpiphp_func *func; | 782 | struct acpiphp_func *func; |
971 | int retval = 0; | 783 | int retval = 0; |
972 | int num, max, pass; | 784 | int num, max, pass; |
@@ -1006,21 +818,17 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
1006 | } | 818 | } |
1007 | } | 819 | } |
1008 | 820 | ||
1009 | list_for_each (l, &slot->funcs) { | 821 | list_for_each_entry(func, &slot->funcs, sibling) |
1010 | func = list_entry(l, struct acpiphp_func, sibling); | ||
1011 | acpiphp_bus_add(func); | 822 | acpiphp_bus_add(func); |
1012 | } | ||
1013 | 823 | ||
1014 | pci_bus_assign_resources(bus); | 824 | pci_bus_assign_resources(bus); |
1015 | acpiphp_sanitize_bus(bus); | 825 | acpiphp_sanitize_bus(bus); |
1016 | acpiphp_set_hpp_values(bus); | 826 | acpiphp_set_hpp_values(bus); |
1017 | list_for_each_entry(func, &slot->funcs, sibling) | 827 | acpiphp_set_acpi_region(slot); |
1018 | acpiphp_configure_ioapics(func->handle); | ||
1019 | pci_enable_bridges(bus); | 828 | pci_enable_bridges(bus); |
1020 | pci_bus_add_devices(bus); | 829 | pci_bus_add_devices(bus); |
1021 | 830 | ||
1022 | list_for_each (l, &slot->funcs) { | 831 | list_for_each_entry(func, &slot->funcs, sibling) { |
1023 | func = list_entry(l, struct acpiphp_func, sibling); | ||
1024 | dev = pci_get_slot(bus, PCI_DEVFN(slot->device, | 832 | dev = pci_get_slot(bus, PCI_DEVFN(slot->device, |
1025 | func->function)); | 833 | func->function)); |
1026 | if (!dev) | 834 | if (!dev) |
@@ -1091,7 +899,6 @@ static int disable_device(struct acpiphp_slot *slot) | |||
1091 | } | 899 | } |
1092 | 900 | ||
1093 | list_for_each_entry(func, &slot->funcs, sibling) { | 901 | list_for_each_entry(func, &slot->funcs, sibling) { |
1094 | acpiphp_unconfigure_ioapics(func->handle); | ||
1095 | acpiphp_bus_trim(func->handle); | 902 | acpiphp_bus_trim(func->handle); |
1096 | } | 903 | } |
1097 | 904 | ||
@@ -1119,12 +926,9 @@ static unsigned int get_slot_status(struct acpiphp_slot *slot) | |||
1119 | acpi_status status; | 926 | acpi_status status; |
1120 | unsigned long long sta = 0; | 927 | unsigned long long sta = 0; |
1121 | u32 dvid; | 928 | u32 dvid; |
1122 | struct list_head *l; | ||
1123 | struct acpiphp_func *func; | 929 | struct acpiphp_func *func; |
1124 | 930 | ||
1125 | list_for_each (l, &slot->funcs) { | 931 | list_for_each_entry(func, &slot->funcs, sibling) { |
1126 | func = list_entry(l, struct acpiphp_func, sibling); | ||
1127 | |||
1128 | if (func->flags & FUNC_HAS_STA) { | 932 | if (func->flags & FUNC_HAS_STA) { |
1129 | status = acpi_evaluate_integer(func->handle, "_STA", NULL, &sta); | 933 | status = acpi_evaluate_integer(func->handle, "_STA", NULL, &sta); |
1130 | if (ACPI_SUCCESS(status) && sta) | 934 | if (ACPI_SUCCESS(status) && sta) |
@@ -1152,13 +956,10 @@ int acpiphp_eject_slot(struct acpiphp_slot *slot) | |||
1152 | { | 956 | { |
1153 | acpi_status status; | 957 | acpi_status status; |
1154 | struct acpiphp_func *func; | 958 | struct acpiphp_func *func; |
1155 | struct list_head *l; | ||
1156 | struct acpi_object_list arg_list; | 959 | struct acpi_object_list arg_list; |
1157 | union acpi_object arg; | 960 | union acpi_object arg; |
1158 | 961 | ||
1159 | list_for_each (l, &slot->funcs) { | 962 | list_for_each_entry(func, &slot->funcs, sibling) { |
1160 | func = list_entry(l, struct acpiphp_func, sibling); | ||
1161 | |||
1162 | /* We don't want to call _EJ0 on non-existing functions. */ | 963 | /* We don't want to call _EJ0 on non-existing functions. */ |
1163 | if ((func->flags & FUNC_HAS_EJ0)) { | 964 | if ((func->flags & FUNC_HAS_EJ0)) { |
1164 | /* _EJ0 method take one argument */ | 965 | /* _EJ0 method take one argument */ |
@@ -1275,7 +1076,6 @@ static int acpiphp_configure_bridge (acpi_handle handle) | |||
1275 | acpiphp_sanitize_bus(bus); | 1076 | acpiphp_sanitize_bus(bus); |
1276 | acpiphp_set_hpp_values(bus); | 1077 | acpiphp_set_hpp_values(bus); |
1277 | pci_enable_bridges(bus); | 1078 | pci_enable_bridges(bus); |
1278 | acpiphp_configure_ioapics(handle); | ||
1279 | return 0; | 1079 | return 0; |
1280 | } | 1080 | } |
1281 | 1081 | ||
@@ -1367,7 +1167,7 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont | |||
1367 | bridge = acpiphp_handle_to_bridge(handle); | 1167 | bridge = acpiphp_handle_to_bridge(handle); |
1368 | if (type == ACPI_NOTIFY_BUS_CHECK) { | 1168 | if (type == ACPI_NOTIFY_BUS_CHECK) { |
1369 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, ACPI_UINT32_MAX, | 1169 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, ACPI_UINT32_MAX, |
1370 | count_sub_bridges, &num_sub_bridges, NULL); | 1170 | count_sub_bridges, NULL, &num_sub_bridges, NULL); |
1371 | } | 1171 | } |
1372 | 1172 | ||
1373 | if (!bridge && !num_sub_bridges) { | 1173 | if (!bridge && !num_sub_bridges) { |
@@ -1388,7 +1188,7 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont | |||
1388 | } | 1188 | } |
1389 | if (num_sub_bridges) | 1189 | if (num_sub_bridges) |
1390 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, | 1190 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, |
1391 | ACPI_UINT32_MAX, check_sub_bridges, NULL, NULL); | 1191 | ACPI_UINT32_MAX, check_sub_bridges, NULL, NULL, NULL); |
1392 | break; | 1192 | break; |
1393 | 1193 | ||
1394 | case ACPI_NOTIFY_DEVICE_CHECK: | 1194 | case ACPI_NOTIFY_DEVICE_CHECK: |
@@ -1512,7 +1312,7 @@ int __init acpiphp_glue_init(void) | |||
1512 | int num = 0; | 1312 | int num = 0; |
1513 | 1313 | ||
1514 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | 1314 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, |
1515 | ACPI_UINT32_MAX, find_root_bridges, &num, NULL); | 1315 | ACPI_UINT32_MAX, find_root_bridges, NULL, &num, NULL); |
1516 | 1316 | ||
1517 | if (num <= 0) | 1317 | if (num <= 0) |
1518 | return -1; | 1318 | return -1; |
@@ -1542,7 +1342,7 @@ int __init acpiphp_get_num_slots(void) | |||
1542 | struct acpiphp_bridge *bridge; | 1342 | struct acpiphp_bridge *bridge; |
1543 | int num_slots = 0; | 1343 | int num_slots = 0; |
1544 | 1344 | ||
1545 | list_for_each_entry (bridge, &bridge_list, list) { | 1345 | list_for_each_entry(bridge, &bridge_list, list) { |
1546 | dbg("Bus %04x:%02x has %d slot%s\n", | 1346 | dbg("Bus %04x:%02x has %d slot%s\n", |
1547 | pci_domain_nr(bridge->pci_bus), | 1347 | pci_domain_nr(bridge->pci_bus), |
1548 | bridge->pci_bus->number, bridge->nr_slots, | 1348 | bridge->pci_bus->number, bridge->nr_slots, |
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index e7be66dbac21..6ecbfb27db9d 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c | |||
@@ -26,6 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/slab.h> | ||
29 | #include <linux/module.h> | 30 | #include <linux/module.h> |
30 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
31 | #include <acpi/acpi_bus.h> | 32 | #include <acpi/acpi_bus.h> |
@@ -434,7 +435,7 @@ static int __init ibm_acpiphp_init(void) | |||
434 | dbg("%s\n", __func__); | 435 | dbg("%s\n", __func__); |
435 | 436 | ||
436 | if (acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | 437 | if (acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, |
437 | ACPI_UINT32_MAX, ibm_find_acpi_device, | 438 | ACPI_UINT32_MAX, ibm_find_acpi_device, NULL, |
438 | &ibm_acpi_handle, NULL) != FOUND_APCI) { | 439 | &ibm_acpi_handle, NULL) != FOUND_APCI) { |
439 | err("%s: acpi_walk_namespace failed\n", __func__); | 440 | err("%s: acpi_walk_namespace failed\n", __func__); |
440 | retval = -ENODEV; | 441 | retval = -ENODEV; |
diff --git a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c index 148fb463b81c..fb3f84661bdc 100644 --- a/drivers/pci/hotplug/cpcihp_generic.c +++ b/drivers/pci/hotplug/cpcihp_generic.c | |||
@@ -162,6 +162,7 @@ static int __init cpcihp_generic_init(void) | |||
162 | dev = pci_get_slot(bus, PCI_DEVFN(bridge_slot, 0)); | 162 | dev = pci_get_slot(bus, PCI_DEVFN(bridge_slot, 0)); |
163 | if(!dev || dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { | 163 | if(!dev || dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { |
164 | err("Invalid bridge device %s", bridge); | 164 | err("Invalid bridge device %s", bridge); |
165 | pci_dev_put(dev); | ||
165 | return -EINVAL; | 166 | return -EINVAL; |
166 | } | 167 | } |
167 | bus = dev->subordinate; | 168 | bus = dev->subordinate; |
diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h index 9c6a9fd26812..d8ffc7366801 100644 --- a/drivers/pci/hotplug/cpqphp.h +++ b/drivers/pci/hotplug/cpqphp.h | |||
@@ -310,8 +310,6 @@ struct controller { | |||
310 | u8 first_slot; | 310 | u8 first_slot; |
311 | u8 add_support; | 311 | u8 add_support; |
312 | u8 push_flag; | 312 | u8 push_flag; |
313 | enum pci_bus_speed speed; | ||
314 | enum pci_bus_speed speed_capability; | ||
315 | u8 push_button; /* 0 = no pushbutton, 1 = pushbutton present */ | 313 | u8 push_button; /* 0 = no pushbutton, 1 = pushbutton present */ |
316 | u8 slot_switch_type; /* 0 = no switch, 1 = switch present */ | 314 | u8 slot_switch_type; /* 0 = no switch, 1 = switch present */ |
317 | u8 defeature_PHP; /* 0 = PHP not supported, 1 = PHP supported */ | 315 | u8 defeature_PHP; /* 0 = PHP not supported, 1 = PHP supported */ |
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index 075b4f4b6e0d..f184d1d2ecbe 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c | |||
@@ -583,30 +583,6 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) | |||
583 | return 0; | 583 | return 0; |
584 | } | 584 | } |
585 | 585 | ||
586 | static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) | ||
587 | { | ||
588 | struct slot *slot = hotplug_slot->private; | ||
589 | struct controller *ctrl = slot->ctrl; | ||
590 | |||
591 | dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); | ||
592 | |||
593 | *value = ctrl->speed_capability; | ||
594 | |||
595 | return 0; | ||
596 | } | ||
597 | |||
598 | static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) | ||
599 | { | ||
600 | struct slot *slot = hotplug_slot->private; | ||
601 | struct controller *ctrl = slot->ctrl; | ||
602 | |||
603 | dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); | ||
604 | |||
605 | *value = ctrl->speed; | ||
606 | |||
607 | return 0; | ||
608 | } | ||
609 | |||
610 | static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = { | 586 | static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = { |
611 | .set_attention_status = set_attention_status, | 587 | .set_attention_status = set_attention_status, |
612 | .enable_slot = process_SI, | 588 | .enable_slot = process_SI, |
@@ -616,8 +592,6 @@ static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = { | |||
616 | .get_attention_status = get_attention_status, | 592 | .get_attention_status = get_attention_status, |
617 | .get_latch_status = get_latch_status, | 593 | .get_latch_status = get_latch_status, |
618 | .get_adapter_status = get_adapter_status, | 594 | .get_adapter_status = get_adapter_status, |
619 | .get_max_bus_speed = get_max_bus_speed, | ||
620 | .get_cur_bus_speed = get_cur_bus_speed, | ||
621 | }; | 595 | }; |
622 | 596 | ||
623 | #define SLOT_NAME_SIZE 10 | 597 | #define SLOT_NAME_SIZE 10 |
@@ -629,6 +603,7 @@ static int ctrl_slot_setup(struct controller *ctrl, | |||
629 | struct slot *slot; | 603 | struct slot *slot; |
630 | struct hotplug_slot *hotplug_slot; | 604 | struct hotplug_slot *hotplug_slot; |
631 | struct hotplug_slot_info *hotplug_slot_info; | 605 | struct hotplug_slot_info *hotplug_slot_info; |
606 | struct pci_bus *bus = ctrl->pci_bus; | ||
632 | u8 number_of_slots; | 607 | u8 number_of_slots; |
633 | u8 slot_device; | 608 | u8 slot_device; |
634 | u8 slot_number; | 609 | u8 slot_number; |
@@ -694,7 +669,7 @@ static int ctrl_slot_setup(struct controller *ctrl, | |||
694 | slot->capabilities |= PCISLOT_64_BIT_SUPPORTED; | 669 | slot->capabilities |= PCISLOT_64_BIT_SUPPORTED; |
695 | if (is_slot66mhz(slot)) | 670 | if (is_slot66mhz(slot)) |
696 | slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED; | 671 | slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED; |
697 | if (ctrl->speed == PCI_SPEED_66MHz) | 672 | if (bus->cur_bus_speed == PCI_SPEED_66MHz) |
698 | slot->capabilities |= PCISLOT_66_MHZ_OPERATION; | 673 | slot->capabilities |= PCISLOT_66_MHZ_OPERATION; |
699 | 674 | ||
700 | ctrl_slot = | 675 | ctrl_slot = |
@@ -844,6 +819,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
844 | u32 rc; | 819 | u32 rc; |
845 | struct controller *ctrl; | 820 | struct controller *ctrl; |
846 | struct pci_func *func; | 821 | struct pci_func *func; |
822 | struct pci_bus *bus; | ||
847 | int err; | 823 | int err; |
848 | 824 | ||
849 | err = pci_enable_device(pdev); | 825 | err = pci_enable_device(pdev); |
@@ -852,6 +828,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
852 | pci_name(pdev), err); | 828 | pci_name(pdev), err); |
853 | return err; | 829 | return err; |
854 | } | 830 | } |
831 | bus = pdev->subordinate; | ||
855 | 832 | ||
856 | /* Need to read VID early b/c it's used to differentiate CPQ and INTC | 833 | /* Need to read VID early b/c it's used to differentiate CPQ and INTC |
857 | * discovery | 834 | * discovery |
@@ -929,22 +906,22 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
929 | pci_read_config_byte(pdev, 0x41, &bus_cap); | 906 | pci_read_config_byte(pdev, 0x41, &bus_cap); |
930 | if (bus_cap & 0x80) { | 907 | if (bus_cap & 0x80) { |
931 | dbg("bus max supports 133MHz PCI-X\n"); | 908 | dbg("bus max supports 133MHz PCI-X\n"); |
932 | ctrl->speed_capability = PCI_SPEED_133MHz_PCIX; | 909 | bus->max_bus_speed = PCI_SPEED_133MHz_PCIX; |
933 | break; | 910 | break; |
934 | } | 911 | } |
935 | if (bus_cap & 0x40) { | 912 | if (bus_cap & 0x40) { |
936 | dbg("bus max supports 100MHz PCI-X\n"); | 913 | dbg("bus max supports 100MHz PCI-X\n"); |
937 | ctrl->speed_capability = PCI_SPEED_100MHz_PCIX; | 914 | bus->max_bus_speed = PCI_SPEED_100MHz_PCIX; |
938 | break; | 915 | break; |
939 | } | 916 | } |
940 | if (bus_cap & 20) { | 917 | if (bus_cap & 20) { |
941 | dbg("bus max supports 66MHz PCI-X\n"); | 918 | dbg("bus max supports 66MHz PCI-X\n"); |
942 | ctrl->speed_capability = PCI_SPEED_66MHz_PCIX; | 919 | bus->max_bus_speed = PCI_SPEED_66MHz_PCIX; |
943 | break; | 920 | break; |
944 | } | 921 | } |
945 | if (bus_cap & 10) { | 922 | if (bus_cap & 10) { |
946 | dbg("bus max supports 66MHz PCI\n"); | 923 | dbg("bus max supports 66MHz PCI\n"); |
947 | ctrl->speed_capability = PCI_SPEED_66MHz; | 924 | bus->max_bus_speed = PCI_SPEED_66MHz; |
948 | break; | 925 | break; |
949 | } | 926 | } |
950 | 927 | ||
@@ -955,7 +932,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
955 | case PCI_SUB_HPC_ID: | 932 | case PCI_SUB_HPC_ID: |
956 | /* Original 6500/7000 implementation */ | 933 | /* Original 6500/7000 implementation */ |
957 | ctrl->slot_switch_type = 1; | 934 | ctrl->slot_switch_type = 1; |
958 | ctrl->speed_capability = PCI_SPEED_33MHz; | 935 | bus->max_bus_speed = PCI_SPEED_33MHz; |
959 | ctrl->push_button = 0; | 936 | ctrl->push_button = 0; |
960 | ctrl->pci_config_space = 1; | 937 | ctrl->pci_config_space = 1; |
961 | ctrl->defeature_PHP = 1; | 938 | ctrl->defeature_PHP = 1; |
@@ -966,7 +943,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
966 | /* First Pushbutton implementation */ | 943 | /* First Pushbutton implementation */ |
967 | ctrl->push_flag = 1; | 944 | ctrl->push_flag = 1; |
968 | ctrl->slot_switch_type = 1; | 945 | ctrl->slot_switch_type = 1; |
969 | ctrl->speed_capability = PCI_SPEED_33MHz; | 946 | bus->max_bus_speed = PCI_SPEED_33MHz; |
970 | ctrl->push_button = 1; | 947 | ctrl->push_button = 1; |
971 | ctrl->pci_config_space = 1; | 948 | ctrl->pci_config_space = 1; |
972 | ctrl->defeature_PHP = 1; | 949 | ctrl->defeature_PHP = 1; |
@@ -976,7 +953,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
976 | case PCI_SUB_HPC_ID_INTC: | 953 | case PCI_SUB_HPC_ID_INTC: |
977 | /* Third party (6500/7000) */ | 954 | /* Third party (6500/7000) */ |
978 | ctrl->slot_switch_type = 1; | 955 | ctrl->slot_switch_type = 1; |
979 | ctrl->speed_capability = PCI_SPEED_33MHz; | 956 | bus->max_bus_speed = PCI_SPEED_33MHz; |
980 | ctrl->push_button = 0; | 957 | ctrl->push_button = 0; |
981 | ctrl->pci_config_space = 1; | 958 | ctrl->pci_config_space = 1; |
982 | ctrl->defeature_PHP = 1; | 959 | ctrl->defeature_PHP = 1; |
@@ -987,7 +964,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
987 | /* First 66 Mhz implementation */ | 964 | /* First 66 Mhz implementation */ |
988 | ctrl->push_flag = 1; | 965 | ctrl->push_flag = 1; |
989 | ctrl->slot_switch_type = 1; | 966 | ctrl->slot_switch_type = 1; |
990 | ctrl->speed_capability = PCI_SPEED_66MHz; | 967 | bus->max_bus_speed = PCI_SPEED_66MHz; |
991 | ctrl->push_button = 1; | 968 | ctrl->push_button = 1; |
992 | ctrl->pci_config_space = 1; | 969 | ctrl->pci_config_space = 1; |
993 | ctrl->defeature_PHP = 1; | 970 | ctrl->defeature_PHP = 1; |
@@ -998,7 +975,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
998 | /* First PCI-X implementation, 100MHz */ | 975 | /* First PCI-X implementation, 100MHz */ |
999 | ctrl->push_flag = 1; | 976 | ctrl->push_flag = 1; |
1000 | ctrl->slot_switch_type = 1; | 977 | ctrl->slot_switch_type = 1; |
1001 | ctrl->speed_capability = PCI_SPEED_100MHz_PCIX; | 978 | bus->max_bus_speed = PCI_SPEED_100MHz_PCIX; |
1002 | ctrl->push_button = 1; | 979 | ctrl->push_button = 1; |
1003 | ctrl->pci_config_space = 1; | 980 | ctrl->pci_config_space = 1; |
1004 | ctrl->defeature_PHP = 1; | 981 | ctrl->defeature_PHP = 1; |
@@ -1015,9 +992,9 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1015 | case PCI_VENDOR_ID_INTEL: | 992 | case PCI_VENDOR_ID_INTEL: |
1016 | /* Check for speed capability (0=33, 1=66) */ | 993 | /* Check for speed capability (0=33, 1=66) */ |
1017 | if (subsystem_deviceid & 0x0001) | 994 | if (subsystem_deviceid & 0x0001) |
1018 | ctrl->speed_capability = PCI_SPEED_66MHz; | 995 | bus->max_bus_speed = PCI_SPEED_66MHz; |
1019 | else | 996 | else |
1020 | ctrl->speed_capability = PCI_SPEED_33MHz; | 997 | bus->max_bus_speed = PCI_SPEED_33MHz; |
1021 | 998 | ||
1022 | /* Check for push button */ | 999 | /* Check for push button */ |
1023 | if (subsystem_deviceid & 0x0002) | 1000 | if (subsystem_deviceid & 0x0002) |
@@ -1079,7 +1056,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1079 | pdev->bus->number); | 1056 | pdev->bus->number); |
1080 | 1057 | ||
1081 | dbg("Hotplug controller capabilities:\n"); | 1058 | dbg("Hotplug controller capabilities:\n"); |
1082 | dbg(" speed_capability %d\n", ctrl->speed_capability); | 1059 | dbg(" speed_capability %d\n", bus->max_bus_speed); |
1083 | dbg(" slot_switch_type %s\n", ctrl->slot_switch_type ? | 1060 | dbg(" slot_switch_type %s\n", ctrl->slot_switch_type ? |
1084 | "switch present" : "no switch"); | 1061 | "switch present" : "no switch"); |
1085 | dbg(" defeature_PHP %s\n", ctrl->defeature_PHP ? | 1062 | dbg(" defeature_PHP %s\n", ctrl->defeature_PHP ? |
@@ -1142,7 +1119,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1142 | } | 1119 | } |
1143 | 1120 | ||
1144 | /* Check for 66Mhz operation */ | 1121 | /* Check for 66Mhz operation */ |
1145 | ctrl->speed = get_controller_speed(ctrl); | 1122 | bus->cur_bus_speed = get_controller_speed(ctrl); |
1146 | 1123 | ||
1147 | 1124 | ||
1148 | /******************************************************** | 1125 | /******************************************************** |
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index 0ff689afa757..e43908d9b5df 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c | |||
@@ -1130,12 +1130,13 @@ static int is_bridge(struct pci_func * func) | |||
1130 | static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_slot) | 1130 | static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_slot) |
1131 | { | 1131 | { |
1132 | struct slot *slot; | 1132 | struct slot *slot; |
1133 | struct pci_bus *bus = ctrl->pci_bus; | ||
1133 | u8 reg; | 1134 | u8 reg; |
1134 | u8 slot_power = readb(ctrl->hpc_reg + SLOT_POWER); | 1135 | u8 slot_power = readb(ctrl->hpc_reg + SLOT_POWER); |
1135 | u16 reg16; | 1136 | u16 reg16; |
1136 | u32 leds = readl(ctrl->hpc_reg + LED_CONTROL); | 1137 | u32 leds = readl(ctrl->hpc_reg + LED_CONTROL); |
1137 | 1138 | ||
1138 | if (ctrl->speed == adapter_speed) | 1139 | if (bus->cur_bus_speed == adapter_speed) |
1139 | return 0; | 1140 | return 0; |
1140 | 1141 | ||
1141 | /* We don't allow freq/mode changes if we find another adapter running | 1142 | /* We don't allow freq/mode changes if we find another adapter running |
@@ -1152,7 +1153,7 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ | |||
1152 | * lower speed/mode, we allow the new adapter to function at | 1153 | * lower speed/mode, we allow the new adapter to function at |
1153 | * this rate if supported | 1154 | * this rate if supported |
1154 | */ | 1155 | */ |
1155 | if (ctrl->speed < adapter_speed) | 1156 | if (bus->cur_bus_speed < adapter_speed) |
1156 | return 0; | 1157 | return 0; |
1157 | 1158 | ||
1158 | return 1; | 1159 | return 1; |
@@ -1161,20 +1162,20 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ | |||
1161 | /* If the controller doesn't support freq/mode changes and the | 1162 | /* If the controller doesn't support freq/mode changes and the |
1162 | * controller is running at a higher mode, we bail | 1163 | * controller is running at a higher mode, we bail |
1163 | */ | 1164 | */ |
1164 | if ((ctrl->speed > adapter_speed) && (!ctrl->pcix_speed_capability)) | 1165 | if ((bus->cur_bus_speed > adapter_speed) && (!ctrl->pcix_speed_capability)) |
1165 | return 1; | 1166 | return 1; |
1166 | 1167 | ||
1167 | /* But we allow the adapter to run at a lower rate if possible */ | 1168 | /* But we allow the adapter to run at a lower rate if possible */ |
1168 | if ((ctrl->speed < adapter_speed) && (!ctrl->pcix_speed_capability)) | 1169 | if ((bus->cur_bus_speed < adapter_speed) && (!ctrl->pcix_speed_capability)) |
1169 | return 0; | 1170 | return 0; |
1170 | 1171 | ||
1171 | /* We try to set the max speed supported by both the adapter and | 1172 | /* We try to set the max speed supported by both the adapter and |
1172 | * controller | 1173 | * controller |
1173 | */ | 1174 | */ |
1174 | if (ctrl->speed_capability < adapter_speed) { | 1175 | if (bus->max_bus_speed < adapter_speed) { |
1175 | if (ctrl->speed == ctrl->speed_capability) | 1176 | if (bus->cur_bus_speed == bus->max_bus_speed) |
1176 | return 0; | 1177 | return 0; |
1177 | adapter_speed = ctrl->speed_capability; | 1178 | adapter_speed = bus->max_bus_speed; |
1178 | } | 1179 | } |
1179 | 1180 | ||
1180 | writel(0x0L, ctrl->hpc_reg + LED_CONTROL); | 1181 | writel(0x0L, ctrl->hpc_reg + LED_CONTROL); |
@@ -1229,8 +1230,8 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ | |||
1229 | pci_write_config_byte(ctrl->pci_dev, 0x43, reg); | 1230 | pci_write_config_byte(ctrl->pci_dev, 0x43, reg); |
1230 | 1231 | ||
1231 | /* Only if mode change...*/ | 1232 | /* Only if mode change...*/ |
1232 | if (((ctrl->speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) || | 1233 | if (((bus->cur_bus_speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) || |
1233 | ((ctrl->speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz))) | 1234 | ((bus->cur_bus_speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz))) |
1234 | set_SOGO(ctrl); | 1235 | set_SOGO(ctrl); |
1235 | 1236 | ||
1236 | wait_for_ctrl_irq(ctrl); | 1237 | wait_for_ctrl_irq(ctrl); |
@@ -1243,7 +1244,7 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ | |||
1243 | set_SOGO(ctrl); | 1244 | set_SOGO(ctrl); |
1244 | wait_for_ctrl_irq(ctrl); | 1245 | wait_for_ctrl_irq(ctrl); |
1245 | 1246 | ||
1246 | ctrl->speed = adapter_speed; | 1247 | bus->cur_bus_speed = adapter_speed; |
1247 | slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); | 1248 | slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); |
1248 | 1249 | ||
1249 | info("Successfully changed frequency/mode for adapter in slot %d\n", | 1250 | info("Successfully changed frequency/mode for adapter in slot %d\n", |
@@ -1269,6 +1270,7 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ | |||
1269 | */ | 1270 | */ |
1270 | static u32 board_replaced(struct pci_func *func, struct controller *ctrl) | 1271 | static u32 board_replaced(struct pci_func *func, struct controller *ctrl) |
1271 | { | 1272 | { |
1273 | struct pci_bus *bus = ctrl->pci_bus; | ||
1272 | u8 hp_slot; | 1274 | u8 hp_slot; |
1273 | u8 temp_byte; | 1275 | u8 temp_byte; |
1274 | u8 adapter_speed; | 1276 | u8 adapter_speed; |
@@ -1309,7 +1311,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl) | |||
1309 | wait_for_ctrl_irq (ctrl); | 1311 | wait_for_ctrl_irq (ctrl); |
1310 | 1312 | ||
1311 | adapter_speed = get_adapter_speed(ctrl, hp_slot); | 1313 | adapter_speed = get_adapter_speed(ctrl, hp_slot); |
1312 | if (ctrl->speed != adapter_speed) | 1314 | if (bus->cur_bus_speed != adapter_speed) |
1313 | if (set_controller_speed(ctrl, adapter_speed, hp_slot)) | 1315 | if (set_controller_speed(ctrl, adapter_speed, hp_slot)) |
1314 | rc = WRONG_BUS_FREQUENCY; | 1316 | rc = WRONG_BUS_FREQUENCY; |
1315 | 1317 | ||
@@ -1426,6 +1428,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) | |||
1426 | u32 temp_register = 0xFFFFFFFF; | 1428 | u32 temp_register = 0xFFFFFFFF; |
1427 | u32 rc = 0; | 1429 | u32 rc = 0; |
1428 | struct pci_func *new_slot = NULL; | 1430 | struct pci_func *new_slot = NULL; |
1431 | struct pci_bus *bus = ctrl->pci_bus; | ||
1429 | struct slot *p_slot; | 1432 | struct slot *p_slot; |
1430 | struct resource_lists res_lists; | 1433 | struct resource_lists res_lists; |
1431 | 1434 | ||
@@ -1456,7 +1459,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) | |||
1456 | wait_for_ctrl_irq (ctrl); | 1459 | wait_for_ctrl_irq (ctrl); |
1457 | 1460 | ||
1458 | adapter_speed = get_adapter_speed(ctrl, hp_slot); | 1461 | adapter_speed = get_adapter_speed(ctrl, hp_slot); |
1459 | if (ctrl->speed != adapter_speed) | 1462 | if (bus->cur_bus_speed != adapter_speed) |
1460 | if (set_controller_speed(ctrl, adapter_speed, hp_slot)) | 1463 | if (set_controller_speed(ctrl, adapter_speed, hp_slot)) |
1461 | rc = WRONG_BUS_FREQUENCY; | 1464 | rc = WRONG_BUS_FREQUENCY; |
1462 | 1465 | ||
diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c index e6089bdb6e5b..56215322930a 100644 --- a/drivers/pci/hotplug/cpqphp_sysfs.c +++ b/drivers/pci/hotplug/cpqphp_sysfs.c | |||
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/slab.h> | ||
31 | #include <linux/types.h> | 32 | #include <linux/types.h> |
32 | #include <linux/proc_fs.h> | 33 | #include <linux/proc_fs.h> |
33 | #include <linux/workqueue.h> | 34 | #include <linux/workqueue.h> |
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c index 6151389fd903..5317e4d7d96e 100644 --- a/drivers/pci/hotplug/fakephp.c +++ b/drivers/pci/hotplug/fakephp.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/pci.h> | 20 | #include <linux/pci.h> |
21 | #include <linux/device.h> | 21 | #include <linux/device.h> |
22 | #include <linux/slab.h> | ||
22 | #include "../pci.h" | 23 | #include "../pci.h" |
23 | 24 | ||
24 | struct legacy_slot { | 25 | struct legacy_slot { |
@@ -73,7 +74,7 @@ static void legacy_release(struct kobject *kobj) | |||
73 | } | 74 | } |
74 | 75 | ||
75 | static struct kobj_type legacy_ktype = { | 76 | static struct kobj_type legacy_ktype = { |
76 | .sysfs_ops = &(struct sysfs_ops){ | 77 | .sysfs_ops = &(const struct sysfs_ops){ |
77 | .store = legacy_store, .show = legacy_show | 78 | .store = legacy_store, .show = legacy_show |
78 | }, | 79 | }, |
79 | .release = &legacy_release, | 80 | .release = &legacy_release, |
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index 7485ffda950c..d934dd4fa873 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c | |||
@@ -395,89 +395,40 @@ static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 * value) | |||
395 | return rc; | 395 | return rc; |
396 | } | 396 | } |
397 | 397 | ||
398 | static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) | 398 | static int get_max_bus_speed(struct slot *slot) |
399 | { | 399 | { |
400 | int rc = -ENODEV; | 400 | int rc; |
401 | struct slot *pslot; | ||
402 | u8 mode = 0; | 401 | u8 mode = 0; |
402 | enum pci_bus_speed speed; | ||
403 | struct pci_bus *bus = slot->hotplug_slot->pci_slot->bus; | ||
403 | 404 | ||
404 | debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __func__, | 405 | debug("%s - Entry slot[%p]\n", __func__, slot); |
405 | hotplug_slot, value); | ||
406 | 406 | ||
407 | ibmphp_lock_operations(); | 407 | ibmphp_lock_operations(); |
408 | 408 | mode = slot->supported_bus_mode; | |
409 | if (hotplug_slot) { | 409 | speed = slot->supported_speed; |
410 | pslot = hotplug_slot->private; | ||
411 | if (pslot) { | ||
412 | rc = 0; | ||
413 | mode = pslot->supported_bus_mode; | ||
414 | *value = pslot->supported_speed; | ||
415 | switch (*value) { | ||
416 | case BUS_SPEED_33: | ||
417 | break; | ||
418 | case BUS_SPEED_66: | ||
419 | if (mode == BUS_MODE_PCIX) | ||
420 | *value += 0x01; | ||
421 | break; | ||
422 | case BUS_SPEED_100: | ||
423 | case BUS_SPEED_133: | ||
424 | *value = pslot->supported_speed + 0x01; | ||
425 | break; | ||
426 | default: | ||
427 | /* Note (will need to change): there would be soon 256, 512 also */ | ||
428 | rc = -ENODEV; | ||
429 | } | ||
430 | } | ||
431 | } | ||
432 | |||
433 | ibmphp_unlock_operations(); | 410 | ibmphp_unlock_operations(); |
434 | debug("%s - Exit rc[%d] value[%x]\n", __func__, rc, *value); | ||
435 | return rc; | ||
436 | } | ||
437 | 411 | ||
438 | static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) | 412 | switch (speed) { |
439 | { | 413 | case BUS_SPEED_33: |
440 | int rc = -ENODEV; | 414 | break; |
441 | struct slot *pslot; | 415 | case BUS_SPEED_66: |
442 | u8 mode = 0; | 416 | if (mode == BUS_MODE_PCIX) |
443 | 417 | speed += 0x01; | |
444 | debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __func__, | 418 | break; |
445 | hotplug_slot, value); | 419 | case BUS_SPEED_100: |
446 | 420 | case BUS_SPEED_133: | |
447 | ibmphp_lock_operations(); | 421 | speed += 0x01; |
448 | 422 | break; | |
449 | if (hotplug_slot) { | 423 | default: |
450 | pslot = hotplug_slot->private; | 424 | /* Note (will need to change): there would be soon 256, 512 also */ |
451 | if (pslot) { | 425 | rc = -ENODEV; |
452 | rc = get_cur_bus_info(&pslot); | ||
453 | if (!rc) { | ||
454 | mode = pslot->bus_on->current_bus_mode; | ||
455 | *value = pslot->bus_on->current_speed; | ||
456 | switch (*value) { | ||
457 | case BUS_SPEED_33: | ||
458 | break; | ||
459 | case BUS_SPEED_66: | ||
460 | if (mode == BUS_MODE_PCIX) | ||
461 | *value += 0x01; | ||
462 | else if (mode == BUS_MODE_PCI) | ||
463 | ; | ||
464 | else | ||
465 | *value = PCI_SPEED_UNKNOWN; | ||
466 | break; | ||
467 | case BUS_SPEED_100: | ||
468 | case BUS_SPEED_133: | ||
469 | *value += 0x01; | ||
470 | break; | ||
471 | default: | ||
472 | /* Note of change: there would also be 256, 512 soon */ | ||
473 | rc = -ENODEV; | ||
474 | } | ||
475 | } | ||
476 | } | ||
477 | } | 426 | } |
478 | 427 | ||
479 | ibmphp_unlock_operations(); | 428 | if (!rc) |
480 | debug("%s - Exit rc[%d] value[%x]\n", __func__, rc, *value); | 429 | bus->max_bus_speed = speed; |
430 | |||
431 | debug("%s - Exit rc[%d] speed[%x]\n", __func__, rc, speed); | ||
481 | return rc; | 432 | return rc; |
482 | } | 433 | } |
483 | 434 | ||
@@ -572,6 +523,7 @@ static int __init init_ops(void) | |||
572 | if (slot_cur->bus_on->current_speed == 0xFF) | 523 | if (slot_cur->bus_on->current_speed == 0xFF) |
573 | if (get_cur_bus_info(&slot_cur)) | 524 | if (get_cur_bus_info(&slot_cur)) |
574 | return -1; | 525 | return -1; |
526 | get_max_bus_speed(slot_cur); | ||
575 | 527 | ||
576 | if (slot_cur->ctrl->options == 0xFF) | 528 | if (slot_cur->ctrl->options == 0xFF) |
577 | if (get_hpc_options(slot_cur, &slot_cur->ctrl->options)) | 529 | if (get_hpc_options(slot_cur, &slot_cur->ctrl->options)) |
@@ -655,6 +607,7 @@ static int validate(struct slot *slot_cur, int opn) | |||
655 | int ibmphp_update_slot_info(struct slot *slot_cur) | 607 | int ibmphp_update_slot_info(struct slot *slot_cur) |
656 | { | 608 | { |
657 | struct hotplug_slot_info *info; | 609 | struct hotplug_slot_info *info; |
610 | struct pci_bus *bus = slot_cur->hotplug_slot->pci_slot->bus; | ||
658 | int rc; | 611 | int rc; |
659 | u8 bus_speed; | 612 | u8 bus_speed; |
660 | u8 mode; | 613 | u8 mode; |
@@ -700,8 +653,7 @@ int ibmphp_update_slot_info(struct slot *slot_cur) | |||
700 | bus_speed = PCI_SPEED_UNKNOWN; | 653 | bus_speed = PCI_SPEED_UNKNOWN; |
701 | } | 654 | } |
702 | 655 | ||
703 | info->cur_bus_speed = bus_speed; | 656 | bus->cur_bus_speed = bus_speed; |
704 | info->max_bus_speed = slot_cur->hotplug_slot->info->max_bus_speed; | ||
705 | // To do: bus_names | 657 | // To do: bus_names |
706 | 658 | ||
707 | rc = pci_hp_change_slot_info(slot_cur->hotplug_slot, info); | 659 | rc = pci_hp_change_slot_info(slot_cur->hotplug_slot, info); |
@@ -1326,8 +1278,6 @@ struct hotplug_slot_ops ibmphp_hotplug_slot_ops = { | |||
1326 | .get_attention_status = get_attention_status, | 1278 | .get_attention_status = get_attention_status, |
1327 | .get_latch_status = get_latch_status, | 1279 | .get_latch_status = get_latch_status, |
1328 | .get_adapter_status = get_adapter_present, | 1280 | .get_adapter_status = get_adapter_present, |
1329 | .get_max_bus_speed = get_max_bus_speed, | ||
1330 | .get_cur_bus_speed = get_cur_bus_speed, | ||
1331 | /* .get_max_adapter_speed = get_max_adapter_speed, | 1281 | /* .get_max_adapter_speed = get_max_adapter_speed, |
1332 | .get_bus_name_status = get_bus_name, | 1282 | .get_bus_name_status = get_bus_name, |
1333 | */ | 1283 | */ |
diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c index c1abac8ab5c3..5becbdee4027 100644 --- a/drivers/pci/hotplug/ibmphp_ebda.c +++ b/drivers/pci/hotplug/ibmphp_ebda.c | |||
@@ -245,7 +245,7 @@ static void __init print_ebda_hpc (void) | |||
245 | 245 | ||
246 | int __init ibmphp_access_ebda (void) | 246 | int __init ibmphp_access_ebda (void) |
247 | { | 247 | { |
248 | u8 format, num_ctlrs, rio_complete, hs_complete; | 248 | u8 format, num_ctlrs, rio_complete, hs_complete, ebda_sz; |
249 | u16 ebda_seg, num_entries, next_offset, offset, blk_id, sub_addr, re, rc_id, re_id, base; | 249 | u16 ebda_seg, num_entries, next_offset, offset, blk_id, sub_addr, re, rc_id, re_id, base; |
250 | int rc = 0; | 250 | int rc = 0; |
251 | 251 | ||
@@ -260,7 +260,16 @@ int __init ibmphp_access_ebda (void) | |||
260 | iounmap (io_mem); | 260 | iounmap (io_mem); |
261 | debug ("returned ebda segment: %x\n", ebda_seg); | 261 | debug ("returned ebda segment: %x\n", ebda_seg); |
262 | 262 | ||
263 | io_mem = ioremap(ebda_seg<<4, 1024); | 263 | io_mem = ioremap(ebda_seg<<4, 1); |
264 | if (!io_mem) | ||
265 | return -ENOMEM; | ||
266 | ebda_sz = readb(io_mem); | ||
267 | iounmap(io_mem); | ||
268 | debug("ebda size: %d(KiB)\n", ebda_sz); | ||
269 | if (ebda_sz == 0) | ||
270 | return -ENOMEM; | ||
271 | |||
272 | io_mem = ioremap(ebda_seg<<4, (ebda_sz * 1024)); | ||
264 | if (!io_mem ) | 273 | if (!io_mem ) |
265 | return -ENOMEM; | 274 | return -ENOMEM; |
266 | next_offset = 0x180; | 275 | next_offset = 0x180; |
diff --git a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c index 83f337c891a9..1aaf3f32d3cd 100644 --- a/drivers/pci/hotplug/ibmphp_hpc.c +++ b/drivers/pci/hotplug/ibmphp_hpc.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/mutex.h> | 36 | #include <linux/mutex.h> |
37 | #include <linux/sched.h> | 37 | #include <linux/sched.h> |
38 | #include <linux/semaphore.h> | ||
38 | #include <linux/kthread.h> | 39 | #include <linux/kthread.h> |
39 | #include "ibmphp.h" | 40 | #include "ibmphp.h" |
40 | 41 | ||
@@ -890,7 +891,7 @@ static int poll_hpc(void *data) | |||
890 | msleep(POLL_INTERVAL_SEC * 1000); | 891 | msleep(POLL_INTERVAL_SEC * 1000); |
891 | 892 | ||
892 | if (kthread_should_stop()) | 893 | if (kthread_should_stop()) |
893 | break; | 894 | goto out_sleep; |
894 | 895 | ||
895 | down (&semOperations); | 896 | down (&semOperations); |
896 | 897 | ||
@@ -904,6 +905,7 @@ static int poll_hpc(void *data) | |||
904 | /* give up the hardware semaphore */ | 905 | /* give up the hardware semaphore */ |
905 | up (&semOperations); | 906 | up (&semOperations); |
906 | /* sleep for a short time just for good measure */ | 907 | /* sleep for a short time just for good measure */ |
908 | out_sleep: | ||
907 | msleep(100); | 909 | msleep(100); |
908 | } | 910 | } |
909 | up (&sem_exit); | 911 | up (&sem_exit); |
diff --git a/drivers/pci/hotplug/ibmphp_res.c b/drivers/pci/hotplug/ibmphp_res.c index ec73294d1fa6..e2dc289f767c 100644 --- a/drivers/pci/hotplug/ibmphp_res.c +++ b/drivers/pci/hotplug/ibmphp_res.c | |||
@@ -40,7 +40,7 @@ static void update_resources (struct bus_node *bus_cur, int type, int rangeno); | |||
40 | static int once_over (void); | 40 | static int once_over (void); |
41 | static int remove_ranges (struct bus_node *, struct bus_node *); | 41 | static int remove_ranges (struct bus_node *, struct bus_node *); |
42 | static int update_bridge_ranges (struct bus_node **); | 42 | static int update_bridge_ranges (struct bus_node **); |
43 | static int add_range (int type, struct range_node *, struct bus_node *); | 43 | static int add_bus_range (int type, struct range_node *, struct bus_node *); |
44 | static void fix_resources (struct bus_node *); | 44 | static void fix_resources (struct bus_node *); |
45 | static struct bus_node *find_bus_wprev (u8, struct bus_node **, u8); | 45 | static struct bus_node *find_bus_wprev (u8, struct bus_node **, u8); |
46 | 46 | ||
@@ -133,7 +133,7 @@ static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node | |||
133 | newrange->rangeno = 1; | 133 | newrange->rangeno = 1; |
134 | else { | 134 | else { |
135 | /* need to insert our range */ | 135 | /* need to insert our range */ |
136 | add_range (flag, newrange, newbus); | 136 | add_bus_range (flag, newrange, newbus); |
137 | debug ("%d resource Primary Bus inserted on bus %x [%x - %x]\n", flag, newbus->busno, newrange->start, newrange->end); | 137 | debug ("%d resource Primary Bus inserted on bus %x [%x - %x]\n", flag, newbus->busno, newrange->start, newrange->end); |
138 | } | 138 | } |
139 | 139 | ||
@@ -384,7 +384,7 @@ int __init ibmphp_rsrc_init (void) | |||
384 | * Input: type of the resource, range to add, current bus | 384 | * Input: type of the resource, range to add, current bus |
385 | * Output: 0 or -1, bus and range ptrs | 385 | * Output: 0 or -1, bus and range ptrs |
386 | ********************************************************************************/ | 386 | ********************************************************************************/ |
387 | static int add_range (int type, struct range_node *range, struct bus_node *bus_cur) | 387 | static int add_bus_range (int type, struct range_node *range, struct bus_node *bus_cur) |
388 | { | 388 | { |
389 | struct range_node *range_cur = NULL; | 389 | struct range_node *range_cur = NULL; |
390 | struct range_node *range_prev; | 390 | struct range_node *range_prev; |
@@ -455,7 +455,7 @@ static int add_range (int type, struct range_node *range, struct bus_node *bus_c | |||
455 | 455 | ||
456 | /******************************************************************************* | 456 | /******************************************************************************* |
457 | * This routine goes through the list of resources of type 'type' and updates | 457 | * This routine goes through the list of resources of type 'type' and updates |
458 | * the range numbers that they correspond to. It was called from add_range fnc | 458 | * the range numbers that they correspond to. It was called from add_bus_range fnc |
459 | * | 459 | * |
460 | * Input: bus, type of the resource, the rangeno starting from which to update | 460 | * Input: bus, type of the resource, the rangeno starting from which to update |
461 | ******************************************************************************/ | 461 | ******************************************************************************/ |
@@ -1999,7 +1999,7 @@ static int __init update_bridge_ranges (struct bus_node **bus) | |||
1999 | 1999 | ||
2000 | if (bus_sec->noIORanges > 0) { | 2000 | if (bus_sec->noIORanges > 0) { |
2001 | if (!range_exists_already (range, bus_sec, IO)) { | 2001 | if (!range_exists_already (range, bus_sec, IO)) { |
2002 | add_range (IO, range, bus_sec); | 2002 | add_bus_range (IO, range, bus_sec); |
2003 | ++bus_sec->noIORanges; | 2003 | ++bus_sec->noIORanges; |
2004 | } else { | 2004 | } else { |
2005 | kfree (range); | 2005 | kfree (range); |
@@ -2048,7 +2048,7 @@ static int __init update_bridge_ranges (struct bus_node **bus) | |||
2048 | 2048 | ||
2049 | if (bus_sec->noMemRanges > 0) { | 2049 | if (bus_sec->noMemRanges > 0) { |
2050 | if (!range_exists_already (range, bus_sec, MEM)) { | 2050 | if (!range_exists_already (range, bus_sec, MEM)) { |
2051 | add_range (MEM, range, bus_sec); | 2051 | add_bus_range (MEM, range, bus_sec); |
2052 | ++bus_sec->noMemRanges; | 2052 | ++bus_sec->noMemRanges; |
2053 | } else { | 2053 | } else { |
2054 | kfree (range); | 2054 | kfree (range); |
@@ -2102,7 +2102,7 @@ static int __init update_bridge_ranges (struct bus_node **bus) | |||
2102 | 2102 | ||
2103 | if (bus_sec->noPFMemRanges > 0) { | 2103 | if (bus_sec->noPFMemRanges > 0) { |
2104 | if (!range_exists_already (range, bus_sec, PFMEM)) { | 2104 | if (!range_exists_already (range, bus_sec, PFMEM)) { |
2105 | add_range (PFMEM, range, bus_sec); | 2105 | add_bus_range (PFMEM, range, bus_sec); |
2106 | ++bus_sec->noPFMemRanges; | 2106 | ++bus_sec->noPFMemRanges; |
2107 | } else { | 2107 | } else { |
2108 | kfree (range); | 2108 | kfree (range); |
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index 0325d989bb46..6d2eea93298f 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/kobject.h> | 33 | #include <linux/kobject.h> |
34 | #include <linux/sysfs.h> | 34 | #include <linux/sysfs.h> |
35 | #include <linux/pagemap.h> | 35 | #include <linux/pagemap.h> |
36 | #include <linux/slab.h> | ||
37 | #include <linux/init.h> | 36 | #include <linux/init.h> |
38 | #include <linux/mount.h> | 37 | #include <linux/mount.h> |
39 | #include <linux/namei.h> | 38 | #include <linux/namei.h> |
@@ -64,32 +63,6 @@ static int debug; | |||
64 | static LIST_HEAD(pci_hotplug_slot_list); | 63 | static LIST_HEAD(pci_hotplug_slot_list); |
65 | static DEFINE_MUTEX(pci_hp_mutex); | 64 | static DEFINE_MUTEX(pci_hp_mutex); |
66 | 65 | ||
67 | /* these strings match up with the values in pci_bus_speed */ | ||
68 | static char *pci_bus_speed_strings[] = { | ||
69 | "33 MHz PCI", /* 0x00 */ | ||
70 | "66 MHz PCI", /* 0x01 */ | ||
71 | "66 MHz PCIX", /* 0x02 */ | ||
72 | "100 MHz PCIX", /* 0x03 */ | ||
73 | "133 MHz PCIX", /* 0x04 */ | ||
74 | NULL, /* 0x05 */ | ||
75 | NULL, /* 0x06 */ | ||
76 | NULL, /* 0x07 */ | ||
77 | NULL, /* 0x08 */ | ||
78 | "66 MHz PCIX 266", /* 0x09 */ | ||
79 | "100 MHz PCIX 266", /* 0x0a */ | ||
80 | "133 MHz PCIX 266", /* 0x0b */ | ||
81 | NULL, /* 0x0c */ | ||
82 | NULL, /* 0x0d */ | ||
83 | NULL, /* 0x0e */ | ||
84 | NULL, /* 0x0f */ | ||
85 | NULL, /* 0x10 */ | ||
86 | "66 MHz PCIX 533", /* 0x11 */ | ||
87 | "100 MHz PCIX 533", /* 0x12 */ | ||
88 | "133 MHz PCIX 533", /* 0x13 */ | ||
89 | "2.5 GT/s PCI-E", /* 0x14 */ | ||
90 | "5.0 GT/s PCI-E", /* 0x15 */ | ||
91 | }; | ||
92 | |||
93 | #ifdef CONFIG_HOTPLUG_PCI_CPCI | 66 | #ifdef CONFIG_HOTPLUG_PCI_CPCI |
94 | extern int cpci_hotplug_init(int debug); | 67 | extern int cpci_hotplug_init(int debug); |
95 | extern void cpci_hotplug_exit(void); | 68 | extern void cpci_hotplug_exit(void); |
@@ -118,8 +91,6 @@ GET_STATUS(power_status, u8) | |||
118 | GET_STATUS(attention_status, u8) | 91 | GET_STATUS(attention_status, u8) |
119 | GET_STATUS(latch_status, u8) | 92 | GET_STATUS(latch_status, u8) |
120 | GET_STATUS(adapter_status, u8) | 93 | GET_STATUS(adapter_status, u8) |
121 | GET_STATUS(max_bus_speed, enum pci_bus_speed) | ||
122 | GET_STATUS(cur_bus_speed, enum pci_bus_speed) | ||
123 | 94 | ||
124 | static ssize_t power_read_file(struct pci_slot *slot, char *buf) | 95 | static ssize_t power_read_file(struct pci_slot *slot, char *buf) |
125 | { | 96 | { |
@@ -263,60 +234,6 @@ static struct pci_slot_attribute hotplug_slot_attr_presence = { | |||
263 | .show = presence_read_file, | 234 | .show = presence_read_file, |
264 | }; | 235 | }; |
265 | 236 | ||
266 | static char *unknown_speed = "Unknown bus speed"; | ||
267 | |||
268 | static ssize_t max_bus_speed_read_file(struct pci_slot *slot, char *buf) | ||
269 | { | ||
270 | char *speed_string; | ||
271 | int retval; | ||
272 | enum pci_bus_speed value; | ||
273 | |||
274 | retval = get_max_bus_speed(slot->hotplug, &value); | ||
275 | if (retval) | ||
276 | goto exit; | ||
277 | |||
278 | if (value == PCI_SPEED_UNKNOWN) | ||
279 | speed_string = unknown_speed; | ||
280 | else | ||
281 | speed_string = pci_bus_speed_strings[value]; | ||
282 | |||
283 | retval = sprintf (buf, "%s\n", speed_string); | ||
284 | |||
285 | exit: | ||
286 | return retval; | ||
287 | } | ||
288 | |||
289 | static struct pci_slot_attribute hotplug_slot_attr_max_bus_speed = { | ||
290 | .attr = {.name = "max_bus_speed", .mode = S_IFREG | S_IRUGO}, | ||
291 | .show = max_bus_speed_read_file, | ||
292 | }; | ||
293 | |||
294 | static ssize_t cur_bus_speed_read_file(struct pci_slot *slot, char *buf) | ||
295 | { | ||
296 | char *speed_string; | ||
297 | int retval; | ||
298 | enum pci_bus_speed value; | ||
299 | |||
300 | retval = get_cur_bus_speed(slot->hotplug, &value); | ||
301 | if (retval) | ||
302 | goto exit; | ||
303 | |||
304 | if (value == PCI_SPEED_UNKNOWN) | ||
305 | speed_string = unknown_speed; | ||
306 | else | ||
307 | speed_string = pci_bus_speed_strings[value]; | ||
308 | |||
309 | retval = sprintf (buf, "%s\n", speed_string); | ||
310 | |||
311 | exit: | ||
312 | return retval; | ||
313 | } | ||
314 | |||
315 | static struct pci_slot_attribute hotplug_slot_attr_cur_bus_speed = { | ||
316 | .attr = {.name = "cur_bus_speed", .mode = S_IFREG | S_IRUGO}, | ||
317 | .show = cur_bus_speed_read_file, | ||
318 | }; | ||
319 | |||
320 | static ssize_t test_write_file(struct pci_slot *pci_slot, const char *buf, | 237 | static ssize_t test_write_file(struct pci_slot *pci_slot, const char *buf, |
321 | size_t count) | 238 | size_t count) |
322 | { | 239 | { |
@@ -391,26 +308,6 @@ static bool has_adapter_file(struct pci_slot *pci_slot) | |||
391 | return false; | 308 | return false; |
392 | } | 309 | } |
393 | 310 | ||
394 | static bool has_max_bus_speed_file(struct pci_slot *pci_slot) | ||
395 | { | ||
396 | struct hotplug_slot *slot = pci_slot->hotplug; | ||
397 | if ((!slot) || (!slot->ops)) | ||
398 | return false; | ||
399 | if (slot->ops->get_max_bus_speed) | ||
400 | return true; | ||
401 | return false; | ||
402 | } | ||
403 | |||
404 | static bool has_cur_bus_speed_file(struct pci_slot *pci_slot) | ||
405 | { | ||
406 | struct hotplug_slot *slot = pci_slot->hotplug; | ||
407 | if ((!slot) || (!slot->ops)) | ||
408 | return false; | ||
409 | if (slot->ops->get_cur_bus_speed) | ||
410 | return true; | ||
411 | return false; | ||
412 | } | ||
413 | |||
414 | static bool has_test_file(struct pci_slot *pci_slot) | 311 | static bool has_test_file(struct pci_slot *pci_slot) |
415 | { | 312 | { |
416 | struct hotplug_slot *slot = pci_slot->hotplug; | 313 | struct hotplug_slot *slot = pci_slot->hotplug; |
@@ -456,20 +353,6 @@ static int fs_add_slot(struct pci_slot *slot) | |||
456 | goto exit_adapter; | 353 | goto exit_adapter; |
457 | } | 354 | } |
458 | 355 | ||
459 | if (has_max_bus_speed_file(slot)) { | ||
460 | retval = sysfs_create_file(&slot->kobj, | ||
461 | &hotplug_slot_attr_max_bus_speed.attr); | ||
462 | if (retval) | ||
463 | goto exit_max_speed; | ||
464 | } | ||
465 | |||
466 | if (has_cur_bus_speed_file(slot)) { | ||
467 | retval = sysfs_create_file(&slot->kobj, | ||
468 | &hotplug_slot_attr_cur_bus_speed.attr); | ||
469 | if (retval) | ||
470 | goto exit_cur_speed; | ||
471 | } | ||
472 | |||
473 | if (has_test_file(slot)) { | 356 | if (has_test_file(slot)) { |
474 | retval = sysfs_create_file(&slot->kobj, | 357 | retval = sysfs_create_file(&slot->kobj, |
475 | &hotplug_slot_attr_test.attr); | 358 | &hotplug_slot_attr_test.attr); |
@@ -480,14 +363,6 @@ static int fs_add_slot(struct pci_slot *slot) | |||
480 | goto exit; | 363 | goto exit; |
481 | 364 | ||
482 | exit_test: | 365 | exit_test: |
483 | if (has_cur_bus_speed_file(slot)) | ||
484 | sysfs_remove_file(&slot->kobj, | ||
485 | &hotplug_slot_attr_cur_bus_speed.attr); | ||
486 | exit_cur_speed: | ||
487 | if (has_max_bus_speed_file(slot)) | ||
488 | sysfs_remove_file(&slot->kobj, | ||
489 | &hotplug_slot_attr_max_bus_speed.attr); | ||
490 | exit_max_speed: | ||
491 | if (has_adapter_file(slot)) | 366 | if (has_adapter_file(slot)) |
492 | sysfs_remove_file(&slot->kobj, | 367 | sysfs_remove_file(&slot->kobj, |
493 | &hotplug_slot_attr_presence.attr); | 368 | &hotplug_slot_attr_presence.attr); |
@@ -523,14 +398,6 @@ static void fs_remove_slot(struct pci_slot *slot) | |||
523 | sysfs_remove_file(&slot->kobj, | 398 | sysfs_remove_file(&slot->kobj, |
524 | &hotplug_slot_attr_presence.attr); | 399 | &hotplug_slot_attr_presence.attr); |
525 | 400 | ||
526 | if (has_max_bus_speed_file(slot)) | ||
527 | sysfs_remove_file(&slot->kobj, | ||
528 | &hotplug_slot_attr_max_bus_speed.attr); | ||
529 | |||
530 | if (has_cur_bus_speed_file(slot)) | ||
531 | sysfs_remove_file(&slot->kobj, | ||
532 | &hotplug_slot_attr_cur_bus_speed.attr); | ||
533 | |||
534 | if (has_test_file(slot)) | 401 | if (has_test_file(slot)) |
535 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr); | 402 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr); |
536 | 403 | ||
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 3070f77eb56a..4ed76b47b6dc 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -91,7 +91,6 @@ struct controller { | |||
91 | struct slot *slot; | 91 | struct slot *slot; |
92 | wait_queue_head_t queue; /* sleep & wake process */ | 92 | wait_queue_head_t queue; /* sleep & wake process */ |
93 | u32 slot_cap; | 93 | u32 slot_cap; |
94 | u8 cap_base; | ||
95 | struct timer_list poll_timer; | 94 | struct timer_list poll_timer; |
96 | unsigned int cmd_busy:1; | 95 | unsigned int cmd_busy:1; |
97 | unsigned int no_cmd_complete:1; | 96 | unsigned int no_cmd_complete:1; |
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c index 37c8d3d0323e..1f4000a5a108 100644 --- a/drivers/pci/hotplug/pciehp_acpi.c +++ b/drivers/pci/hotplug/pciehp_acpi.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/acpi.h> | 26 | #include <linux/acpi.h> |
27 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
28 | #include <linux/pci_hotplug.h> | 28 | #include <linux/pci_hotplug.h> |
29 | #include <linux/slab.h> | ||
29 | #include "pciehp.h" | 30 | #include "pciehp.h" |
30 | 31 | ||
31 | #define PCIEHP_DETECT_PCIE (0) | 32 | #define PCIEHP_DETECT_PCIE (0) |
@@ -87,7 +88,8 @@ static int __init dummy_probe(struct pcie_device *dev) | |||
87 | /* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */ | 88 | /* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */ |
88 | if (pciehp_get_hp_hw_control_from_firmware(pdev)) | 89 | if (pciehp_get_hp_hw_control_from_firmware(pdev)) |
89 | return -ENODEV; | 90 | return -ENODEV; |
90 | if (!(pos = pci_find_capability(pdev, PCI_CAP_ID_EXP))) | 91 | pos = pci_pcie_cap(pdev); |
92 | if (!pos) | ||
91 | return -ENODEV; | 93 | return -ENODEV; |
92 | pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &slot_cap); | 94 | pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &slot_cap); |
93 | slot = kzalloc(sizeof(*slot), GFP_KERNEL); | 95 | slot = kzalloc(sizeof(*slot), GFP_KERNEL); |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index bc234719b1df..3588ea61b0dd 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/moduleparam.h> | 31 | #include <linux/moduleparam.h> |
32 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
33 | #include <linux/slab.h> | ||
33 | #include <linux/types.h> | 34 | #include <linux/types.h> |
34 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
35 | #include "pciehp.h" | 36 | #include "pciehp.h" |
@@ -69,20 +70,6 @@ static int get_power_status (struct hotplug_slot *slot, u8 *value); | |||
69 | static int get_attention_status (struct hotplug_slot *slot, u8 *value); | 70 | static int get_attention_status (struct hotplug_slot *slot, u8 *value); |
70 | static int get_latch_status (struct hotplug_slot *slot, u8 *value); | 71 | static int get_latch_status (struct hotplug_slot *slot, u8 *value); |
71 | static int get_adapter_status (struct hotplug_slot *slot, u8 *value); | 72 | static int get_adapter_status (struct hotplug_slot *slot, u8 *value); |
72 | static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); | ||
73 | static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); | ||
74 | |||
75 | static struct hotplug_slot_ops pciehp_hotplug_slot_ops = { | ||
76 | .set_attention_status = set_attention_status, | ||
77 | .enable_slot = enable_slot, | ||
78 | .disable_slot = disable_slot, | ||
79 | .get_power_status = get_power_status, | ||
80 | .get_attention_status = get_attention_status, | ||
81 | .get_latch_status = get_latch_status, | ||
82 | .get_adapter_status = get_adapter_status, | ||
83 | .get_max_bus_speed = get_max_bus_speed, | ||
84 | .get_cur_bus_speed = get_cur_bus_speed, | ||
85 | }; | ||
86 | 73 | ||
87 | /** | 74 | /** |
88 | * release_slot - free up the memory used by a slot | 75 | * release_slot - free up the memory used by a slot |
@@ -95,6 +82,7 @@ static void release_slot(struct hotplug_slot *hotplug_slot) | |||
95 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | 82 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", |
96 | __func__, hotplug_slot_name(hotplug_slot)); | 83 | __func__, hotplug_slot_name(hotplug_slot)); |
97 | 84 | ||
85 | kfree(hotplug_slot->ops); | ||
98 | kfree(hotplug_slot->info); | 86 | kfree(hotplug_slot->info); |
99 | kfree(hotplug_slot); | 87 | kfree(hotplug_slot); |
100 | } | 88 | } |
@@ -104,6 +92,7 @@ static int init_slot(struct controller *ctrl) | |||
104 | struct slot *slot = ctrl->slot; | 92 | struct slot *slot = ctrl->slot; |
105 | struct hotplug_slot *hotplug = NULL; | 93 | struct hotplug_slot *hotplug = NULL; |
106 | struct hotplug_slot_info *info = NULL; | 94 | struct hotplug_slot_info *info = NULL; |
95 | struct hotplug_slot_ops *ops = NULL; | ||
107 | char name[SLOT_NAME_SIZE]; | 96 | char name[SLOT_NAME_SIZE]; |
108 | int retval = -ENOMEM; | 97 | int retval = -ENOMEM; |
109 | 98 | ||
@@ -115,11 +104,26 @@ static int init_slot(struct controller *ctrl) | |||
115 | if (!info) | 104 | if (!info) |
116 | goto out; | 105 | goto out; |
117 | 106 | ||
107 | /* Setup hotplug slot ops */ | ||
108 | ops = kzalloc(sizeof(*ops), GFP_KERNEL); | ||
109 | if (!ops) | ||
110 | goto out; | ||
111 | ops->enable_slot = enable_slot; | ||
112 | ops->disable_slot = disable_slot; | ||
113 | ops->get_power_status = get_power_status; | ||
114 | ops->get_adapter_status = get_adapter_status; | ||
115 | if (MRL_SENS(ctrl)) | ||
116 | ops->get_latch_status = get_latch_status; | ||
117 | if (ATTN_LED(ctrl)) { | ||
118 | ops->get_attention_status = get_attention_status; | ||
119 | ops->set_attention_status = set_attention_status; | ||
120 | } | ||
121 | |||
118 | /* register this slot with the hotplug pci core */ | 122 | /* register this slot with the hotplug pci core */ |
119 | hotplug->info = info; | 123 | hotplug->info = info; |
120 | hotplug->private = slot; | 124 | hotplug->private = slot; |
121 | hotplug->release = &release_slot; | 125 | hotplug->release = &release_slot; |
122 | hotplug->ops = &pciehp_hotplug_slot_ops; | 126 | hotplug->ops = ops; |
123 | slot->hotplug_slot = hotplug; | 127 | slot->hotplug_slot = hotplug; |
124 | snprintf(name, SLOT_NAME_SIZE, "%u", PSN(ctrl)); | 128 | snprintf(name, SLOT_NAME_SIZE, "%u", PSN(ctrl)); |
125 | 129 | ||
@@ -128,17 +132,12 @@ static int init_slot(struct controller *ctrl) | |||
128 | ctrl->pcie->port->subordinate->number, PSN(ctrl)); | 132 | ctrl->pcie->port->subordinate->number, PSN(ctrl)); |
129 | retval = pci_hp_register(hotplug, | 133 | retval = pci_hp_register(hotplug, |
130 | ctrl->pcie->port->subordinate, 0, name); | 134 | ctrl->pcie->port->subordinate, 0, name); |
131 | if (retval) { | 135 | if (retval) |
132 | ctrl_err(ctrl, | 136 | ctrl_err(ctrl, |
133 | "pci_hp_register failed with error %d\n", retval); | 137 | "pci_hp_register failed with error %d\n", retval); |
134 | goto out; | ||
135 | } | ||
136 | get_power_status(hotplug, &info->power_status); | ||
137 | get_attention_status(hotplug, &info->attention_status); | ||
138 | get_latch_status(hotplug, &info->latch_status); | ||
139 | get_adapter_status(hotplug, &info->adapter_status); | ||
140 | out: | 138 | out: |
141 | if (retval) { | 139 | if (retval) { |
140 | kfree(ops); | ||
142 | kfree(info); | 141 | kfree(info); |
143 | kfree(hotplug); | 142 | kfree(hotplug); |
144 | } | 143 | } |
@@ -160,12 +159,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) | |||
160 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | 159 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", |
161 | __func__, slot_name(slot)); | 160 | __func__, slot_name(slot)); |
162 | 161 | ||
163 | hotplug_slot->info->attention_status = status; | 162 | return pciehp_set_attention_status(slot, status); |
164 | |||
165 | if (ATTN_LED(slot->ctrl)) | ||
166 | pciehp_set_attention_status(slot, status); | ||
167 | |||
168 | return 0; | ||
169 | } | 163 | } |
170 | 164 | ||
171 | 165 | ||
@@ -193,92 +187,41 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) | |||
193 | static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) | 187 | static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) |
194 | { | 188 | { |
195 | struct slot *slot = hotplug_slot->private; | 189 | struct slot *slot = hotplug_slot->private; |
196 | int retval; | ||
197 | 190 | ||
198 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | 191 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", |
199 | __func__, slot_name(slot)); | 192 | __func__, slot_name(slot)); |
200 | 193 | ||
201 | retval = pciehp_get_power_status(slot, value); | 194 | return pciehp_get_power_status(slot, value); |
202 | if (retval < 0) | ||
203 | *value = hotplug_slot->info->power_status; | ||
204 | |||
205 | return 0; | ||
206 | } | 195 | } |
207 | 196 | ||
208 | static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) | 197 | static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) |
209 | { | 198 | { |
210 | struct slot *slot = hotplug_slot->private; | 199 | struct slot *slot = hotplug_slot->private; |
211 | int retval; | ||
212 | 200 | ||
213 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | 201 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", |
214 | __func__, slot_name(slot)); | 202 | __func__, slot_name(slot)); |
215 | 203 | ||
216 | retval = pciehp_get_attention_status(slot, value); | 204 | return pciehp_get_attention_status(slot, value); |
217 | if (retval < 0) | ||
218 | *value = hotplug_slot->info->attention_status; | ||
219 | |||
220 | return 0; | ||
221 | } | 205 | } |
222 | 206 | ||
223 | static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) | 207 | static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) |
224 | { | 208 | { |
225 | struct slot *slot = hotplug_slot->private; | 209 | struct slot *slot = hotplug_slot->private; |
226 | int retval; | ||
227 | 210 | ||
228 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | 211 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", |
229 | __func__, slot_name(slot)); | 212 | __func__, slot_name(slot)); |
230 | 213 | ||
231 | retval = pciehp_get_latch_status(slot, value); | 214 | return pciehp_get_latch_status(slot, value); |
232 | if (retval < 0) | ||
233 | *value = hotplug_slot->info->latch_status; | ||
234 | |||
235 | return 0; | ||
236 | } | 215 | } |
237 | 216 | ||
238 | static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) | 217 | static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) |
239 | { | 218 | { |
240 | struct slot *slot = hotplug_slot->private; | 219 | struct slot *slot = hotplug_slot->private; |
241 | int retval; | ||
242 | 220 | ||
243 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | 221 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", |
244 | __func__, slot_name(slot)); | 222 | __func__, slot_name(slot)); |
245 | 223 | ||
246 | retval = pciehp_get_adapter_status(slot, value); | 224 | return pciehp_get_adapter_status(slot, value); |
247 | if (retval < 0) | ||
248 | *value = hotplug_slot->info->adapter_status; | ||
249 | |||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, | ||
254 | enum pci_bus_speed *value) | ||
255 | { | ||
256 | struct slot *slot = hotplug_slot->private; | ||
257 | int retval; | ||
258 | |||
259 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | ||
260 | __func__, slot_name(slot)); | ||
261 | |||
262 | retval = pciehp_get_max_link_speed(slot, value); | ||
263 | if (retval < 0) | ||
264 | *value = PCI_SPEED_UNKNOWN; | ||
265 | |||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) | ||
270 | { | ||
271 | struct slot *slot = hotplug_slot->private; | ||
272 | int retval; | ||
273 | |||
274 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | ||
275 | __func__, slot_name(slot)); | ||
276 | |||
277 | retval = pciehp_get_cur_link_speed(slot, value); | ||
278 | if (retval < 0) | ||
279 | *value = PCI_SPEED_UNKNOWN; | ||
280 | |||
281 | return 0; | ||
282 | } | 225 | } |
283 | 226 | ||
284 | static int pciehp_probe(struct pcie_device *dev) | 227 | static int pciehp_probe(struct pcie_device *dev) |
@@ -286,14 +229,13 @@ static int pciehp_probe(struct pcie_device *dev) | |||
286 | int rc; | 229 | int rc; |
287 | struct controller *ctrl; | 230 | struct controller *ctrl; |
288 | struct slot *slot; | 231 | struct slot *slot; |
289 | u8 value; | 232 | u8 occupied, poweron; |
290 | struct pci_dev *pdev = dev->port; | ||
291 | 233 | ||
292 | if (pciehp_force) | 234 | if (pciehp_force) |
293 | dev_info(&dev->device, | 235 | dev_info(&dev->device, |
294 | "Bypassing BIOS check for pciehp use on %s\n", | 236 | "Bypassing BIOS check for pciehp use on %s\n", |
295 | pci_name(pdev)); | 237 | pci_name(dev->port)); |
296 | else if (pciehp_get_hp_hw_control_from_firmware(pdev)) | 238 | else if (pciehp_get_hp_hw_control_from_firmware(dev->port)) |
297 | goto err_out_none; | 239 | goto err_out_none; |
298 | 240 | ||
299 | ctrl = pcie_init(dev); | 241 | ctrl = pcie_init(dev); |
@@ -318,23 +260,18 @@ static int pciehp_probe(struct pcie_device *dev) | |||
318 | rc = pcie_init_notification(ctrl); | 260 | rc = pcie_init_notification(ctrl); |
319 | if (rc) { | 261 | if (rc) { |
320 | ctrl_err(ctrl, "Notification initialization failed\n"); | 262 | ctrl_err(ctrl, "Notification initialization failed\n"); |
321 | goto err_out_release_ctlr; | 263 | goto err_out_free_ctrl_slot; |
322 | } | 264 | } |
323 | 265 | ||
324 | /* Check if slot is occupied */ | 266 | /* Check if slot is occupied */ |
325 | slot = ctrl->slot; | 267 | slot = ctrl->slot; |
326 | pciehp_get_adapter_status(slot, &value); | 268 | pciehp_get_adapter_status(slot, &occupied); |
327 | if (value) { | 269 | pciehp_get_power_status(slot, &poweron); |
328 | if (pciehp_force) | 270 | if (occupied && pciehp_force) |
329 | pciehp_enable_slot(slot); | 271 | pciehp_enable_slot(slot); |
330 | } else { | 272 | /* If empty slot's power status is on, turn power off */ |
331 | /* Power off slot if not occupied */ | 273 | if (!occupied && poweron && POWER_CTRL(ctrl)) |
332 | if (POWER_CTRL(ctrl)) { | 274 | pciehp_power_off_slot(slot); |
333 | rc = pciehp_power_off_slot(slot); | ||
334 | if (rc) | ||
335 | goto err_out_free_ctrl_slot; | ||
336 | } | ||
337 | } | ||
338 | 275 | ||
339 | return 0; | 276 | return 0; |
340 | 277 | ||
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 84487d126e4d..8f58148be044 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | #include <linux/slab.h> | ||
33 | #include <linux/pci.h> | 34 | #include <linux/pci.h> |
34 | #include <linux/workqueue.h> | 35 | #include <linux/workqueue.h> |
35 | #include "../pci.h" | 36 | #include "../pci.h" |
@@ -142,23 +143,9 @@ u8 pciehp_handle_power_fault(struct slot *p_slot) | |||
142 | 143 | ||
143 | /* power fault */ | 144 | /* power fault */ |
144 | ctrl_dbg(ctrl, "Power fault interrupt received\n"); | 145 | ctrl_dbg(ctrl, "Power fault interrupt received\n"); |
145 | 146 | ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot)); | |
146 | if (!pciehp_query_power_fault(p_slot)) { | 147 | event_type = INT_POWER_FAULT; |
147 | /* | 148 | ctrl_info(ctrl, "Power fault bit %x set\n", 0); |
148 | * power fault Cleared | ||
149 | */ | ||
150 | ctrl_info(ctrl, "Power fault cleared on Slot(%s)\n", | ||
151 | slot_name(p_slot)); | ||
152 | event_type = INT_POWER_FAULT_CLEAR; | ||
153 | } else { | ||
154 | /* | ||
155 | * power fault | ||
156 | */ | ||
157 | ctrl_info(ctrl, "Power fault on Slot(%s)\n", slot_name(p_slot)); | ||
158 | event_type = INT_POWER_FAULT; | ||
159 | ctrl_info(ctrl, "Power fault bit %x set\n", 0); | ||
160 | } | ||
161 | |||
162 | queue_interrupt_event(p_slot, event_type); | 149 | queue_interrupt_event(p_slot, event_type); |
163 | 150 | ||
164 | return 1; | 151 | return 1; |
@@ -224,13 +211,12 @@ static int board_added(struct slot *p_slot) | |||
224 | retval = pciehp_check_link_status(ctrl); | 211 | retval = pciehp_check_link_status(ctrl); |
225 | if (retval) { | 212 | if (retval) { |
226 | ctrl_err(ctrl, "Failed to check link status\n"); | 213 | ctrl_err(ctrl, "Failed to check link status\n"); |
227 | set_slot_off(ctrl, p_slot); | 214 | goto err_exit; |
228 | return retval; | ||
229 | } | 215 | } |
230 | 216 | ||
231 | /* Check for a power fault */ | 217 | /* Check for a power fault */ |
232 | if (pciehp_query_power_fault(p_slot)) { | 218 | if (ctrl->power_fault_detected || pciehp_query_power_fault(p_slot)) { |
233 | ctrl_dbg(ctrl, "Power fault detected\n"); | 219 | ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot)); |
234 | retval = -EIO; | 220 | retval = -EIO; |
235 | goto err_exit; | 221 | goto err_exit; |
236 | } | 222 | } |
@@ -356,6 +342,7 @@ void pciehp_queue_pushbutton_work(struct work_struct *work) | |||
356 | p_slot->state = POWERON_STATE; | 342 | p_slot->state = POWERON_STATE; |
357 | break; | 343 | break; |
358 | default: | 344 | default: |
345 | kfree(info); | ||
359 | goto out; | 346 | goto out; |
360 | } | 347 | } |
361 | queue_work(pciehp_wq, &info->work); | 348 | queue_work(pciehp_wq, &info->work); |
@@ -363,25 +350,6 @@ void pciehp_queue_pushbutton_work(struct work_struct *work) | |||
363 | mutex_unlock(&p_slot->lock); | 350 | mutex_unlock(&p_slot->lock); |
364 | } | 351 | } |
365 | 352 | ||
366 | static int update_slot_info(struct slot *slot) | ||
367 | { | ||
368 | struct hotplug_slot_info *info; | ||
369 | int result; | ||
370 | |||
371 | info = kmalloc(sizeof(*info), GFP_KERNEL); | ||
372 | if (!info) | ||
373 | return -ENOMEM; | ||
374 | |||
375 | pciehp_get_power_status(slot, &info->power_status); | ||
376 | pciehp_get_attention_status(slot, &info->attention_status); | ||
377 | pciehp_get_latch_status(slot, &info->latch_status); | ||
378 | pciehp_get_adapter_status(slot, &info->adapter_status); | ||
379 | |||
380 | result = pci_hp_change_slot_info(slot->hotplug_slot, info); | ||
381 | kfree (info); | ||
382 | return result; | ||
383 | } | ||
384 | |||
385 | /* | 353 | /* |
386 | * Note: This function must be called with slot->lock held | 354 | * Note: This function must be called with slot->lock held |
387 | */ | 355 | */ |
@@ -442,7 +410,6 @@ static void handle_button_press_event(struct slot *p_slot) | |||
442 | * to hot-add or hot-remove is undergoing | 410 | * to hot-add or hot-remove is undergoing |
443 | */ | 411 | */ |
444 | ctrl_info(ctrl, "Button ignore on Slot(%s)\n", slot_name(p_slot)); | 412 | ctrl_info(ctrl, "Button ignore on Slot(%s)\n", slot_name(p_slot)); |
445 | update_slot_info(p_slot); | ||
446 | break; | 413 | break; |
447 | default: | 414 | default: |
448 | ctrl_warn(ctrl, "Not a valid state\n"); | 415 | ctrl_warn(ctrl, "Not a valid state\n"); |
@@ -500,11 +467,9 @@ static void interrupt_event_handler(struct work_struct *work) | |||
500 | if (!HP_SUPR_RM(ctrl)) | 467 | if (!HP_SUPR_RM(ctrl)) |
501 | break; | 468 | break; |
502 | ctrl_dbg(ctrl, "Surprise Removal\n"); | 469 | ctrl_dbg(ctrl, "Surprise Removal\n"); |
503 | update_slot_info(p_slot); | ||
504 | handle_surprise_event(p_slot); | 470 | handle_surprise_event(p_slot); |
505 | break; | 471 | break; |
506 | default: | 472 | default: |
507 | update_slot_info(p_slot); | ||
508 | break; | 473 | break; |
509 | } | 474 | } |
510 | mutex_unlock(&p_slot->lock); | 475 | mutex_unlock(&p_slot->lock); |
@@ -547,9 +512,6 @@ int pciehp_enable_slot(struct slot *p_slot) | |||
547 | if (rc) { | 512 | if (rc) { |
548 | pciehp_get_latch_status(p_slot, &getstatus); | 513 | pciehp_get_latch_status(p_slot, &getstatus); |
549 | } | 514 | } |
550 | |||
551 | update_slot_info(p_slot); | ||
552 | |||
553 | return rc; | 515 | return rc; |
554 | } | 516 | } |
555 | 517 | ||
@@ -590,10 +552,7 @@ int pciehp_disable_slot(struct slot *p_slot) | |||
590 | } | 552 | } |
591 | } | 553 | } |
592 | 554 | ||
593 | ret = remove_board(p_slot); | 555 | return remove_board(p_slot); |
594 | update_slot_info(p_slot); | ||
595 | |||
596 | return ret; | ||
597 | } | 556 | } |
598 | 557 | ||
599 | int pciehp_sysfs_enable_slot(struct slot *p_slot) | 558 | int pciehp_sysfs_enable_slot(struct slot *p_slot) |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 9ef4605c1ef6..0cd42047d89b 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
37 | #include <linux/interrupt.h> | 37 | #include <linux/interrupt.h> |
38 | #include <linux/time.h> | 38 | #include <linux/time.h> |
39 | #include <linux/slab.h> | ||
39 | 40 | ||
40 | #include "../pci.h" | 41 | #include "../pci.h" |
41 | #include "pciehp.h" | 42 | #include "pciehp.h" |
@@ -45,25 +46,25 @@ static atomic_t pciehp_num_controllers = ATOMIC_INIT(0); | |||
45 | static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value) | 46 | static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value) |
46 | { | 47 | { |
47 | struct pci_dev *dev = ctrl->pcie->port; | 48 | struct pci_dev *dev = ctrl->pcie->port; |
48 | return pci_read_config_word(dev, ctrl->cap_base + reg, value); | 49 | return pci_read_config_word(dev, pci_pcie_cap(dev) + reg, value); |
49 | } | 50 | } |
50 | 51 | ||
51 | static inline int pciehp_readl(struct controller *ctrl, int reg, u32 *value) | 52 | static inline int pciehp_readl(struct controller *ctrl, int reg, u32 *value) |
52 | { | 53 | { |
53 | struct pci_dev *dev = ctrl->pcie->port; | 54 | struct pci_dev *dev = ctrl->pcie->port; |
54 | return pci_read_config_dword(dev, ctrl->cap_base + reg, value); | 55 | return pci_read_config_dword(dev, pci_pcie_cap(dev) + reg, value); |
55 | } | 56 | } |
56 | 57 | ||
57 | static inline int pciehp_writew(struct controller *ctrl, int reg, u16 value) | 58 | static inline int pciehp_writew(struct controller *ctrl, int reg, u16 value) |
58 | { | 59 | { |
59 | struct pci_dev *dev = ctrl->pcie->port; | 60 | struct pci_dev *dev = ctrl->pcie->port; |
60 | return pci_write_config_word(dev, ctrl->cap_base + reg, value); | 61 | return pci_write_config_word(dev, pci_pcie_cap(dev) + reg, value); |
61 | } | 62 | } |
62 | 63 | ||
63 | static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value) | 64 | static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value) |
64 | { | 65 | { |
65 | struct pci_dev *dev = ctrl->pcie->port; | 66 | struct pci_dev *dev = ctrl->pcie->port; |
66 | return pci_write_config_dword(dev, ctrl->cap_base + reg, value); | 67 | return pci_write_config_dword(dev, pci_pcie_cap(dev) + reg, value); |
67 | } | 68 | } |
68 | 69 | ||
69 | /* Power Control Command */ | 70 | /* Power Control Command */ |
@@ -318,8 +319,8 @@ int pciehp_get_attention_status(struct slot *slot, u8 *status) | |||
318 | return retval; | 319 | return retval; |
319 | } | 320 | } |
320 | 321 | ||
321 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n", | 322 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n", __func__, |
322 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_ctrl); | 323 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl); |
323 | 324 | ||
324 | atten_led_state = (slot_ctrl & PCI_EXP_SLTCTL_AIC) >> 6; | 325 | atten_led_state = (slot_ctrl & PCI_EXP_SLTCTL_AIC) >> 6; |
325 | 326 | ||
@@ -356,8 +357,8 @@ int pciehp_get_power_status(struct slot *slot, u8 *status) | |||
356 | ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__); | 357 | ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__); |
357 | return retval; | 358 | return retval; |
358 | } | 359 | } |
359 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x value read %x\n", | 360 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x value read %x\n", __func__, |
360 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_ctrl); | 361 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl); |
361 | 362 | ||
362 | pwr_state = (slot_ctrl & PCI_EXP_SLTCTL_PCC) >> 10; | 363 | pwr_state = (slot_ctrl & PCI_EXP_SLTCTL_PCC) >> 10; |
363 | 364 | ||
@@ -427,27 +428,24 @@ int pciehp_set_attention_status(struct slot *slot, u8 value) | |||
427 | struct controller *ctrl = slot->ctrl; | 428 | struct controller *ctrl = slot->ctrl; |
428 | u16 slot_cmd; | 429 | u16 slot_cmd; |
429 | u16 cmd_mask; | 430 | u16 cmd_mask; |
430 | int rc; | ||
431 | 431 | ||
432 | cmd_mask = PCI_EXP_SLTCTL_AIC; | 432 | cmd_mask = PCI_EXP_SLTCTL_AIC; |
433 | switch (value) { | 433 | switch (value) { |
434 | case 0 : /* turn off */ | 434 | case 0 : /* turn off */ |
435 | slot_cmd = 0x00C0; | 435 | slot_cmd = 0x00C0; |
436 | break; | 436 | break; |
437 | case 1: /* turn on */ | 437 | case 1: /* turn on */ |
438 | slot_cmd = 0x0040; | 438 | slot_cmd = 0x0040; |
439 | break; | 439 | break; |
440 | case 2: /* turn blink */ | 440 | case 2: /* turn blink */ |
441 | slot_cmd = 0x0080; | 441 | slot_cmd = 0x0080; |
442 | break; | 442 | break; |
443 | default: | 443 | default: |
444 | return -1; | 444 | return -EINVAL; |
445 | } | 445 | } |
446 | rc = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 446 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
447 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", | 447 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
448 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); | 448 | return pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
449 | |||
450 | return rc; | ||
451 | } | 449 | } |
452 | 450 | ||
453 | void pciehp_green_led_on(struct slot *slot) | 451 | void pciehp_green_led_on(struct slot *slot) |
@@ -459,8 +457,8 @@ void pciehp_green_led_on(struct slot *slot) | |||
459 | slot_cmd = 0x0100; | 457 | slot_cmd = 0x0100; |
460 | cmd_mask = PCI_EXP_SLTCTL_PIC; | 458 | cmd_mask = PCI_EXP_SLTCTL_PIC; |
461 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 459 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
462 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", | 460 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
463 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); | 461 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
464 | } | 462 | } |
465 | 463 | ||
466 | void pciehp_green_led_off(struct slot *slot) | 464 | void pciehp_green_led_off(struct slot *slot) |
@@ -472,8 +470,8 @@ void pciehp_green_led_off(struct slot *slot) | |||
472 | slot_cmd = 0x0300; | 470 | slot_cmd = 0x0300; |
473 | cmd_mask = PCI_EXP_SLTCTL_PIC; | 471 | cmd_mask = PCI_EXP_SLTCTL_PIC; |
474 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 472 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
475 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", | 473 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
476 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); | 474 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
477 | } | 475 | } |
478 | 476 | ||
479 | void pciehp_green_led_blink(struct slot *slot) | 477 | void pciehp_green_led_blink(struct slot *slot) |
@@ -485,8 +483,8 @@ void pciehp_green_led_blink(struct slot *slot) | |||
485 | slot_cmd = 0x0200; | 483 | slot_cmd = 0x0200; |
486 | cmd_mask = PCI_EXP_SLTCTL_PIC; | 484 | cmd_mask = PCI_EXP_SLTCTL_PIC; |
487 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 485 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
488 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", | 486 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
489 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); | 487 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
490 | } | 488 | } |
491 | 489 | ||
492 | int pciehp_power_on_slot(struct slot * slot) | 490 | int pciehp_power_on_slot(struct slot * slot) |
@@ -495,6 +493,7 @@ int pciehp_power_on_slot(struct slot * slot) | |||
495 | u16 slot_cmd; | 493 | u16 slot_cmd; |
496 | u16 cmd_mask; | 494 | u16 cmd_mask; |
497 | u16 slot_status; | 495 | u16 slot_status; |
496 | u16 lnk_status; | ||
498 | int retval = 0; | 497 | int retval = 0; |
499 | 498 | ||
500 | /* Clear sticky power-fault bit from previous power failures */ | 499 | /* Clear sticky power-fault bit from previous power failures */ |
@@ -514,58 +513,27 @@ int pciehp_power_on_slot(struct slot * slot) | |||
514 | return retval; | 513 | return retval; |
515 | } | 514 | } |
516 | } | 515 | } |
516 | ctrl->power_fault_detected = 0; | ||
517 | 517 | ||
518 | slot_cmd = POWER_ON; | 518 | slot_cmd = POWER_ON; |
519 | cmd_mask = PCI_EXP_SLTCTL_PCC; | 519 | cmd_mask = PCI_EXP_SLTCTL_PCC; |
520 | if (!pciehp_poll_mode) { | ||
521 | /* Enable power fault detection turned off at power off time */ | ||
522 | slot_cmd |= PCI_EXP_SLTCTL_PFDE; | ||
523 | cmd_mask |= PCI_EXP_SLTCTL_PFDE; | ||
524 | } | ||
525 | |||
526 | retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 520 | retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
527 | if (retval) { | 521 | if (retval) { |
528 | ctrl_err(ctrl, "Write %x command failed!\n", slot_cmd); | 522 | ctrl_err(ctrl, "Write %x command failed!\n", slot_cmd); |
529 | return retval; | 523 | return retval; |
530 | } | 524 | } |
531 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", | 525 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
532 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); | 526 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
533 | |||
534 | ctrl->power_fault_detected = 0; | ||
535 | return retval; | ||
536 | } | ||
537 | |||
538 | static inline int pcie_mask_bad_dllp(struct controller *ctrl) | ||
539 | { | ||
540 | struct pci_dev *dev = ctrl->pcie->port; | ||
541 | int pos; | ||
542 | u32 reg; | ||
543 | |||
544 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | ||
545 | if (!pos) | ||
546 | return 0; | ||
547 | pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, ®); | ||
548 | if (reg & PCI_ERR_COR_BAD_DLLP) | ||
549 | return 0; | ||
550 | reg |= PCI_ERR_COR_BAD_DLLP; | ||
551 | pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg); | ||
552 | return 1; | ||
553 | } | ||
554 | 527 | ||
555 | static inline void pcie_unmask_bad_dllp(struct controller *ctrl) | 528 | retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); |
556 | { | 529 | if (retval) { |
557 | struct pci_dev *dev = ctrl->pcie->port; | 530 | ctrl_err(ctrl, "%s: Cannot read LNKSTA register\n", |
558 | u32 reg; | 531 | __func__); |
559 | int pos; | 532 | return retval; |
533 | } | ||
534 | pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status); | ||
560 | 535 | ||
561 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | 536 | return retval; |
562 | if (!pos) | ||
563 | return; | ||
564 | pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, ®); | ||
565 | if (!(reg & PCI_ERR_COR_BAD_DLLP)) | ||
566 | return; | ||
567 | reg &= ~PCI_ERR_COR_BAD_DLLP; | ||
568 | pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg); | ||
569 | } | 537 | } |
570 | 538 | ||
571 | int pciehp_power_off_slot(struct slot * slot) | 539 | int pciehp_power_off_slot(struct slot * slot) |
@@ -573,38 +541,18 @@ int pciehp_power_off_slot(struct slot * slot) | |||
573 | struct controller *ctrl = slot->ctrl; | 541 | struct controller *ctrl = slot->ctrl; |
574 | u16 slot_cmd; | 542 | u16 slot_cmd; |
575 | u16 cmd_mask; | 543 | u16 cmd_mask; |
576 | int retval = 0; | 544 | int retval; |
577 | int changed; | ||
578 | |||
579 | /* | ||
580 | * Set Bad DLLP Mask bit in Correctable Error Mask | ||
581 | * Register. This is the workaround against Bad DLLP error | ||
582 | * that sometimes happens during turning power off the slot | ||
583 | * which conforms to PCI Express 1.0a spec. | ||
584 | */ | ||
585 | changed = pcie_mask_bad_dllp(ctrl); | ||
586 | 545 | ||
587 | slot_cmd = POWER_OFF; | 546 | slot_cmd = POWER_OFF; |
588 | cmd_mask = PCI_EXP_SLTCTL_PCC; | 547 | cmd_mask = PCI_EXP_SLTCTL_PCC; |
589 | if (!pciehp_poll_mode) { | ||
590 | /* Disable power fault detection */ | ||
591 | slot_cmd &= ~PCI_EXP_SLTCTL_PFDE; | ||
592 | cmd_mask |= PCI_EXP_SLTCTL_PFDE; | ||
593 | } | ||
594 | |||
595 | retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 548 | retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
596 | if (retval) { | 549 | if (retval) { |
597 | ctrl_err(ctrl, "Write command failed!\n"); | 550 | ctrl_err(ctrl, "Write command failed!\n"); |
598 | retval = -1; | 551 | return retval; |
599 | goto out; | ||
600 | } | 552 | } |
601 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", | 553 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
602 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); | 554 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
603 | out: | 555 | return 0; |
604 | if (changed) | ||
605 | pcie_unmask_bad_dllp(ctrl); | ||
606 | |||
607 | return retval; | ||
608 | } | 556 | } |
609 | 557 | ||
610 | static irqreturn_t pcie_isr(int irq, void *dev_id) | 558 | static irqreturn_t pcie_isr(int irq, void *dev_id) |
@@ -672,37 +620,6 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
672 | return IRQ_HANDLED; | 620 | return IRQ_HANDLED; |
673 | } | 621 | } |
674 | 622 | ||
675 | int pciehp_get_max_link_speed(struct slot *slot, enum pci_bus_speed *value) | ||
676 | { | ||
677 | struct controller *ctrl = slot->ctrl; | ||
678 | enum pcie_link_speed lnk_speed; | ||
679 | u32 lnk_cap; | ||
680 | int retval = 0; | ||
681 | |||
682 | retval = pciehp_readl(ctrl, PCI_EXP_LNKCAP, &lnk_cap); | ||
683 | if (retval) { | ||
684 | ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__); | ||
685 | return retval; | ||
686 | } | ||
687 | |||
688 | switch (lnk_cap & 0x000F) { | ||
689 | case 1: | ||
690 | lnk_speed = PCIE_2_5GB; | ||
691 | break; | ||
692 | case 2: | ||
693 | lnk_speed = PCIE_5_0GB; | ||
694 | break; | ||
695 | default: | ||
696 | lnk_speed = PCIE_LNK_SPEED_UNKNOWN; | ||
697 | break; | ||
698 | } | ||
699 | |||
700 | *value = lnk_speed; | ||
701 | ctrl_dbg(ctrl, "Max link speed = %d\n", lnk_speed); | ||
702 | |||
703 | return retval; | ||
704 | } | ||
705 | |||
706 | int pciehp_get_max_lnk_width(struct slot *slot, | 623 | int pciehp_get_max_lnk_width(struct slot *slot, |
707 | enum pcie_link_width *value) | 624 | enum pcie_link_width *value) |
708 | { | 625 | { |
@@ -753,38 +670,6 @@ int pciehp_get_max_lnk_width(struct slot *slot, | |||
753 | return retval; | 670 | return retval; |
754 | } | 671 | } |
755 | 672 | ||
756 | int pciehp_get_cur_link_speed(struct slot *slot, enum pci_bus_speed *value) | ||
757 | { | ||
758 | struct controller *ctrl = slot->ctrl; | ||
759 | enum pcie_link_speed lnk_speed = PCI_SPEED_UNKNOWN; | ||
760 | int retval = 0; | ||
761 | u16 lnk_status; | ||
762 | |||
763 | retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); | ||
764 | if (retval) { | ||
765 | ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n", | ||
766 | __func__); | ||
767 | return retval; | ||
768 | } | ||
769 | |||
770 | switch (lnk_status & PCI_EXP_LNKSTA_CLS) { | ||
771 | case 1: | ||
772 | lnk_speed = PCIE_2_5GB; | ||
773 | break; | ||
774 | case 2: | ||
775 | lnk_speed = PCIE_5_0GB; | ||
776 | break; | ||
777 | default: | ||
778 | lnk_speed = PCIE_LNK_SPEED_UNKNOWN; | ||
779 | break; | ||
780 | } | ||
781 | |||
782 | *value = lnk_speed; | ||
783 | ctrl_dbg(ctrl, "Current link speed = %d\n", lnk_speed); | ||
784 | |||
785 | return retval; | ||
786 | } | ||
787 | |||
788 | int pciehp_get_cur_lnk_width(struct slot *slot, | 673 | int pciehp_get_cur_lnk_width(struct slot *slot, |
789 | enum pcie_link_width *value) | 674 | enum pcie_link_width *value) |
790 | { | 675 | { |
@@ -840,11 +725,19 @@ int pcie_enable_notification(struct controller *ctrl) | |||
840 | { | 725 | { |
841 | u16 cmd, mask; | 726 | u16 cmd, mask; |
842 | 727 | ||
728 | /* | ||
729 | * TBD: Power fault detected software notification support. | ||
730 | * | ||
731 | * Power fault detected software notification is not enabled | ||
732 | * now, because it caused power fault detected interrupt storm | ||
733 | * on some machines. On those machines, power fault detected | ||
734 | * bit in the slot status register was set again immediately | ||
735 | * when it is cleared in the interrupt service routine, and | ||
736 | * next power fault detected interrupt was notified again. | ||
737 | */ | ||
843 | cmd = PCI_EXP_SLTCTL_PDCE; | 738 | cmd = PCI_EXP_SLTCTL_PDCE; |
844 | if (ATTN_BUTTN(ctrl)) | 739 | if (ATTN_BUTTN(ctrl)) |
845 | cmd |= PCI_EXP_SLTCTL_ABPE; | 740 | cmd |= PCI_EXP_SLTCTL_ABPE; |
846 | if (POWER_CTRL(ctrl)) | ||
847 | cmd |= PCI_EXP_SLTCTL_PFDE; | ||
848 | if (MRL_SENS(ctrl)) | 741 | if (MRL_SENS(ctrl)) |
849 | cmd |= PCI_EXP_SLTCTL_MRLSCE; | 742 | cmd |= PCI_EXP_SLTCTL_MRLSCE; |
850 | if (!pciehp_poll_mode) | 743 | if (!pciehp_poll_mode) |
@@ -866,7 +759,8 @@ static void pcie_disable_notification(struct controller *ctrl) | |||
866 | u16 mask; | 759 | u16 mask; |
867 | mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE | | 760 | mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE | |
868 | PCI_EXP_SLTCTL_MRLSCE | PCI_EXP_SLTCTL_PFDE | | 761 | PCI_EXP_SLTCTL_MRLSCE | PCI_EXP_SLTCTL_PFDE | |
869 | PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE); | 762 | PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE | |
763 | PCI_EXP_SLTCTL_DLLSCE); | ||
870 | if (pcie_write_cmd(ctrl, 0, mask)) | 764 | if (pcie_write_cmd(ctrl, 0, mask)) |
871 | ctrl_warn(ctrl, "Cannot disable software notification\n"); | 765 | ctrl_warn(ctrl, "Cannot disable software notification\n"); |
872 | } | 766 | } |
@@ -934,13 +828,13 @@ static inline void dbg_ctrl(struct controller *ctrl) | |||
934 | pdev->subsystem_device); | 828 | pdev->subsystem_device); |
935 | ctrl_info(ctrl, " Subsystem Vendor ID : 0x%04x\n", | 829 | ctrl_info(ctrl, " Subsystem Vendor ID : 0x%04x\n", |
936 | pdev->subsystem_vendor); | 830 | pdev->subsystem_vendor); |
937 | ctrl_info(ctrl, " PCIe Cap offset : 0x%02x\n", ctrl->cap_base); | 831 | ctrl_info(ctrl, " PCIe Cap offset : 0x%02x\n", |
832 | pci_pcie_cap(pdev)); | ||
938 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | 833 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { |
939 | if (!pci_resource_len(pdev, i)) | 834 | if (!pci_resource_len(pdev, i)) |
940 | continue; | 835 | continue; |
941 | ctrl_info(ctrl, " PCI resource [%d] : 0x%llx@0x%llx\n", | 836 | ctrl_info(ctrl, " PCI resource [%d] : %pR\n", |
942 | i, (unsigned long long)pci_resource_len(pdev, i), | 837 | i, &pdev->resource[i]); |
943 | (unsigned long long)pci_resource_start(pdev, i)); | ||
944 | } | 838 | } |
945 | ctrl_info(ctrl, "Slot Capabilities : 0x%08x\n", ctrl->slot_cap); | 839 | ctrl_info(ctrl, "Slot Capabilities : 0x%08x\n", ctrl->slot_cap); |
946 | ctrl_info(ctrl, " Physical Slot Number : %d\n", PSN(ctrl)); | 840 | ctrl_info(ctrl, " Physical Slot Number : %d\n", PSN(ctrl)); |
@@ -978,8 +872,7 @@ struct controller *pcie_init(struct pcie_device *dev) | |||
978 | goto abort; | 872 | goto abort; |
979 | } | 873 | } |
980 | ctrl->pcie = dev; | 874 | ctrl->pcie = dev; |
981 | ctrl->cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP); | 875 | if (!pci_pcie_cap(pdev)) { |
982 | if (!ctrl->cap_base) { | ||
983 | ctrl_err(ctrl, "Cannot find PCI Express capability\n"); | 876 | ctrl_err(ctrl, "Cannot find PCI Express capability\n"); |
984 | goto abort_ctrl; | 877 | goto abort_ctrl; |
985 | } | 878 | } |
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index 21733108adde..0a16444c14c9 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c | |||
@@ -53,17 +53,15 @@ static int __ref pciehp_add_bridge(struct pci_dev *dev) | |||
53 | busnr = pci_scan_bridge(parent, dev, busnr, pass); | 53 | busnr = pci_scan_bridge(parent, dev, busnr, pass); |
54 | if (!dev->subordinate) | 54 | if (!dev->subordinate) |
55 | return -1; | 55 | return -1; |
56 | pci_bus_size_bridges(dev->subordinate); | 56 | |
57 | pci_bus_assign_resources(parent); | ||
58 | pci_enable_bridges(parent); | ||
59 | pci_bus_add_devices(parent); | ||
60 | return 0; | 57 | return 0; |
61 | } | 58 | } |
62 | 59 | ||
63 | int pciehp_configure_device(struct slot *p_slot) | 60 | int pciehp_configure_device(struct slot *p_slot) |
64 | { | 61 | { |
65 | struct pci_dev *dev; | 62 | struct pci_dev *dev; |
66 | struct pci_bus *parent = p_slot->ctrl->pcie->port->subordinate; | 63 | struct pci_dev *bridge = p_slot->ctrl->pcie->port; |
64 | struct pci_bus *parent = bridge->subordinate; | ||
67 | int num, fn; | 65 | int num, fn; |
68 | struct controller *ctrl = p_slot->ctrl; | 66 | struct controller *ctrl = p_slot->ctrl; |
69 | 67 | ||
@@ -96,12 +94,25 @@ int pciehp_configure_device(struct slot *p_slot) | |||
96 | (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { | 94 | (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { |
97 | pciehp_add_bridge(dev); | 95 | pciehp_add_bridge(dev); |
98 | } | 96 | } |
97 | pci_dev_put(dev); | ||
98 | } | ||
99 | |||
100 | pci_assign_unassigned_bridge_resources(bridge); | ||
101 | |||
102 | for (fn = 0; fn < 8; fn++) { | ||
103 | dev = pci_get_slot(parent, PCI_DEVFN(0, fn)); | ||
104 | if (!dev) | ||
105 | continue; | ||
106 | if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { | ||
107 | pci_dev_put(dev); | ||
108 | continue; | ||
109 | } | ||
99 | pci_configure_slot(dev); | 110 | pci_configure_slot(dev); |
100 | pci_dev_put(dev); | 111 | pci_dev_put(dev); |
101 | } | 112 | } |
102 | 113 | ||
103 | pci_bus_assign_resources(parent); | ||
104 | pci_bus_add_devices(parent); | 114 | pci_bus_add_devices(parent); |
115 | |||
105 | return 0; | 116 | return 0; |
106 | } | 117 | } |
107 | 118 | ||
diff --git a/drivers/pci/hotplug/pcihp_slot.c b/drivers/pci/hotplug/pcihp_slot.c index cc8ec3aa41a7..80b461c98557 100644 --- a/drivers/pci/hotplug/pcihp_slot.c +++ b/drivers/pci/hotplug/pcihp_slot.c | |||
@@ -43,7 +43,7 @@ static void program_hpp_type0(struct pci_dev *dev, struct hpp_type0 *hpp) | |||
43 | * Perhaps we *should* use default settings for PCIe, but | 43 | * Perhaps we *should* use default settings for PCIe, but |
44 | * pciehp didn't, so we won't either. | 44 | * pciehp didn't, so we won't either. |
45 | */ | 45 | */ |
46 | if (dev->is_pcie) | 46 | if (pci_is_pcie(dev)) |
47 | return; | 47 | return; |
48 | dev_info(&dev->dev, "using default PCI settings\n"); | 48 | dev_info(&dev->dev, "using default PCI settings\n"); |
49 | hpp = &pci_default_type0; | 49 | hpp = &pci_default_type0; |
@@ -102,7 +102,7 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp) | |||
102 | return; | 102 | return; |
103 | 103 | ||
104 | /* Find PCI Express capability */ | 104 | /* Find PCI Express capability */ |
105 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 105 | pos = pci_pcie_cap(dev); |
106 | if (!pos) | 106 | if (!pos) |
107 | return; | 107 | return; |
108 | 108 | ||
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index 4e3e0382c16e..083034710fa6 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
22 | #include <linux/string.h> | 22 | #include <linux/string.h> |
23 | #include <linux/vmalloc.h> | ||
23 | 24 | ||
24 | #include <asm/pci-bridge.h> | 25 | #include <asm/pci-bridge.h> |
25 | #include <linux/mutex.h> | 26 | #include <linux/mutex.h> |
@@ -430,6 +431,8 @@ int dlpar_remove_slot(char *drc_name) | |||
430 | rc = dlpar_remove_pci_slot(drc_name, dn); | 431 | rc = dlpar_remove_pci_slot(drc_name, dn); |
431 | break; | 432 | break; |
432 | } | 433 | } |
434 | vm_unmap_aliases(); | ||
435 | |||
433 | printk(KERN_INFO "%s: slot %s removed\n", DLPAR_MODULE_NAME, drc_name); | 436 | printk(KERN_INFO "%s: slot %s removed\n", DLPAR_MODULE_NAME, drc_name); |
434 | exit: | 437 | exit: |
435 | mutex_unlock(&rpadlpar_mutex); | 438 | mutex_unlock(&rpadlpar_mutex); |
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index c159223389ec..ef7411c660b9 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c | |||
@@ -27,9 +27,9 @@ | |||
27 | #include <linux/moduleparam.h> | 27 | #include <linux/moduleparam.h> |
28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
29 | #include <linux/pci_hotplug.h> | 29 | #include <linux/pci_hotplug.h> |
30 | #include <linux/slab.h> | ||
31 | #include <linux/smp.h> | 30 | #include <linux/smp.h> |
32 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | #include <linux/vmalloc.h> | ||
33 | #include <asm/eeh.h> /* for eeh_add_device() */ | 33 | #include <asm/eeh.h> /* for eeh_add_device() */ |
34 | #include <asm/rtas.h> /* rtas_call */ | 34 | #include <asm/rtas.h> /* rtas_call */ |
35 | #include <asm/pci-bridge.h> /* for pci_controller */ | 35 | #include <asm/pci-bridge.h> /* for pci_controller */ |
@@ -130,10 +130,9 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value) | |||
130 | return 0; | 130 | return 0; |
131 | } | 131 | } |
132 | 132 | ||
133 | static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) | 133 | static enum pci_bus_speed get_max_bus_speed(struct slot *slot) |
134 | { | 134 | { |
135 | struct slot *slot = (struct slot *)hotplug_slot->private; | 135 | enum pci_bus_speed speed; |
136 | |||
137 | switch (slot->type) { | 136 | switch (slot->type) { |
138 | case 1: | 137 | case 1: |
139 | case 2: | 138 | case 2: |
@@ -141,30 +140,30 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe | |||
141 | case 4: | 140 | case 4: |
142 | case 5: | 141 | case 5: |
143 | case 6: | 142 | case 6: |
144 | *value = PCI_SPEED_33MHz; /* speed for case 1-6 */ | 143 | speed = PCI_SPEED_33MHz; /* speed for case 1-6 */ |
145 | break; | 144 | break; |
146 | case 7: | 145 | case 7: |
147 | case 8: | 146 | case 8: |
148 | *value = PCI_SPEED_66MHz; | 147 | speed = PCI_SPEED_66MHz; |
149 | break; | 148 | break; |
150 | case 11: | 149 | case 11: |
151 | case 14: | 150 | case 14: |
152 | *value = PCI_SPEED_66MHz_PCIX; | 151 | speed = PCI_SPEED_66MHz_PCIX; |
153 | break; | 152 | break; |
154 | case 12: | 153 | case 12: |
155 | case 15: | 154 | case 15: |
156 | *value = PCI_SPEED_100MHz_PCIX; | 155 | speed = PCI_SPEED_100MHz_PCIX; |
157 | break; | 156 | break; |
158 | case 13: | 157 | case 13: |
159 | case 16: | 158 | case 16: |
160 | *value = PCI_SPEED_133MHz_PCIX; | 159 | speed = PCI_SPEED_133MHz_PCIX; |
161 | break; | 160 | break; |
162 | default: | 161 | default: |
163 | *value = PCI_SPEED_UNKNOWN; | 162 | speed = PCI_SPEED_UNKNOWN; |
164 | break; | 163 | break; |
165 | |||
166 | } | 164 | } |
167 | return 0; | 165 | |
166 | return speed; | ||
168 | } | 167 | } |
169 | 168 | ||
170 | static int get_children_props(struct device_node *dn, const int **drc_indexes, | 169 | static int get_children_props(struct device_node *dn, const int **drc_indexes, |
@@ -408,6 +407,8 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) | |||
408 | slot->state = NOT_VALID; | 407 | slot->state = NOT_VALID; |
409 | return -EINVAL; | 408 | return -EINVAL; |
410 | } | 409 | } |
410 | |||
411 | slot->bus->max_bus_speed = get_max_bus_speed(slot); | ||
411 | return 0; | 412 | return 0; |
412 | } | 413 | } |
413 | 414 | ||
@@ -418,6 +419,8 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) | |||
418 | return -EINVAL; | 419 | return -EINVAL; |
419 | 420 | ||
420 | pcibios_remove_pci_devices(slot->bus); | 421 | pcibios_remove_pci_devices(slot->bus); |
422 | vm_unmap_aliases(); | ||
423 | |||
421 | slot->state = NOT_CONFIGURED; | 424 | slot->state = NOT_CONFIGURED; |
422 | return 0; | 425 | return 0; |
423 | } | 426 | } |
@@ -429,7 +432,6 @@ struct hotplug_slot_ops rpaphp_hotplug_slot_ops = { | |||
429 | .get_power_status = get_power_status, | 432 | .get_power_status = get_power_status, |
430 | .get_attention_status = get_attention_status, | 433 | .get_attention_status = get_attention_status, |
431 | .get_adapter_status = get_adapter_status, | 434 | .get_adapter_status = get_adapter_status, |
432 | .get_max_bus_speed = get_max_bus_speed, | ||
433 | }; | 435 | }; |
434 | 436 | ||
435 | module_init(rpaphp_init); | 437 | module_init(rpaphp_init); |
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index 8aebe1e9d3d6..72d507b6a2aa 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/pci.h> | 15 | #include <linux/pci.h> |
16 | #include <linux/pci_hotplug.h> | 16 | #include <linux/pci_hotplug.h> |
17 | #include <linux/proc_fs.h> | 17 | #include <linux/proc_fs.h> |
18 | #include <linux/slab.h> | ||
18 | #include <linux/types.h> | 19 | #include <linux/types.h> |
19 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
20 | 21 | ||
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index bd588eb8e922..d2627e1c3ac1 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h | |||
@@ -121,7 +121,7 @@ struct controller { | |||
121 | #define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 | 121 | #define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 |
122 | #define PCI_DEVICE_ID_AMD_POGO_7458 0x7458 | 122 | #define PCI_DEVICE_ID_AMD_POGO_7458 0x7458 |
123 | 123 | ||
124 | /* AMD PCIX bridge registers */ | 124 | /* AMD PCI-X bridge registers */ |
125 | #define PCIX_MEM_BASE_LIMIT_OFFSET 0x1C | 125 | #define PCIX_MEM_BASE_LIMIT_OFFSET 0x1C |
126 | #define PCIX_MISCII_OFFSET 0x48 | 126 | #define PCIX_MISCII_OFFSET 0x48 |
127 | #define PCIX_MISC_BRIDGE_ERRORS_OFFSET 0x80 | 127 | #define PCIX_MISC_BRIDGE_ERRORS_OFFSET 0x80 |
@@ -333,8 +333,6 @@ struct hpc_ops { | |||
333 | int (*set_attention_status)(struct slot *slot, u8 status); | 333 | int (*set_attention_status)(struct slot *slot, u8 status); |
334 | int (*get_latch_status)(struct slot *slot, u8 *status); | 334 | int (*get_latch_status)(struct slot *slot, u8 *status); |
335 | int (*get_adapter_status)(struct slot *slot, u8 *status); | 335 | int (*get_adapter_status)(struct slot *slot, u8 *status); |
336 | int (*get_max_bus_speed)(struct slot *slot, enum pci_bus_speed *speed); | ||
337 | int (*get_cur_bus_speed)(struct slot *slot, enum pci_bus_speed *speed); | ||
338 | int (*get_adapter_speed)(struct slot *slot, enum pci_bus_speed *speed); | 336 | int (*get_adapter_speed)(struct slot *slot, enum pci_bus_speed *speed); |
339 | int (*get_mode1_ECC_cap)(struct slot *slot, u8 *mode); | 337 | int (*get_mode1_ECC_cap)(struct slot *slot, u8 *mode); |
340 | int (*get_prog_int)(struct slot *slot, u8 *prog_int); | 338 | int (*get_prog_int)(struct slot *slot, u8 *prog_int); |
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 8a520a3d0f59..a7bd5048396e 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/moduleparam.h> | 31 | #include <linux/moduleparam.h> |
32 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
33 | #include <linux/types.h> | 33 | #include <linux/types.h> |
34 | #include <linux/slab.h> | ||
34 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
35 | #include <linux/workqueue.h> | 36 | #include <linux/workqueue.h> |
36 | #include "shpchp.h" | 37 | #include "shpchp.h" |
@@ -65,8 +66,6 @@ static int get_power_status (struct hotplug_slot *slot, u8 *value); | |||
65 | static int get_attention_status (struct hotplug_slot *slot, u8 *value); | 66 | static int get_attention_status (struct hotplug_slot *slot, u8 *value); |
66 | static int get_latch_status (struct hotplug_slot *slot, u8 *value); | 67 | static int get_latch_status (struct hotplug_slot *slot, u8 *value); |
67 | static int get_adapter_status (struct hotplug_slot *slot, u8 *value); | 68 | static int get_adapter_status (struct hotplug_slot *slot, u8 *value); |
68 | static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); | ||
69 | static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); | ||
70 | 69 | ||
71 | static struct hotplug_slot_ops shpchp_hotplug_slot_ops = { | 70 | static struct hotplug_slot_ops shpchp_hotplug_slot_ops = { |
72 | .set_attention_status = set_attention_status, | 71 | .set_attention_status = set_attention_status, |
@@ -76,8 +75,6 @@ static struct hotplug_slot_ops shpchp_hotplug_slot_ops = { | |||
76 | .get_attention_status = get_attention_status, | 75 | .get_attention_status = get_attention_status, |
77 | .get_latch_status = get_latch_status, | 76 | .get_latch_status = get_latch_status, |
78 | .get_adapter_status = get_adapter_status, | 77 | .get_adapter_status = get_adapter_status, |
79 | .get_max_bus_speed = get_max_bus_speed, | ||
80 | .get_cur_bus_speed = get_cur_bus_speed, | ||
81 | }; | 78 | }; |
82 | 79 | ||
83 | /** | 80 | /** |
@@ -279,37 +276,6 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value) | |||
279 | return 0; | 276 | return 0; |
280 | } | 277 | } |
281 | 278 | ||
282 | static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, | ||
283 | enum pci_bus_speed *value) | ||
284 | { | ||
285 | struct slot *slot = get_slot(hotplug_slot); | ||
286 | int retval; | ||
287 | |||
288 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | ||
289 | __func__, slot_name(slot)); | ||
290 | |||
291 | retval = slot->hpc_ops->get_max_bus_speed(slot, value); | ||
292 | if (retval < 0) | ||
293 | *value = PCI_SPEED_UNKNOWN; | ||
294 | |||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) | ||
299 | { | ||
300 | struct slot *slot = get_slot(hotplug_slot); | ||
301 | int retval; | ||
302 | |||
303 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | ||
304 | __func__, slot_name(slot)); | ||
305 | |||
306 | retval = slot->hpc_ops->get_cur_bus_speed(slot, value); | ||
307 | if (retval < 0) | ||
308 | *value = PCI_SPEED_UNKNOWN; | ||
309 | |||
310 | return 0; | ||
311 | } | ||
312 | |||
313 | static int is_shpc_capable(struct pci_dev *dev) | 279 | static int is_shpc_capable(struct pci_dev *dev) |
314 | { | 280 | { |
315 | if ((dev->vendor == PCI_VENDOR_ID_AMD) || (dev->device == | 281 | if ((dev->vendor == PCI_VENDOR_ID_AMD) || (dev->device == |
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index b8ab2796e66a..3387fbfb0c54 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | #include <linux/slab.h> | ||
33 | #include <linux/pci.h> | 34 | #include <linux/pci.h> |
34 | #include <linux/workqueue.h> | 35 | #include <linux/workqueue.h> |
35 | #include "../pci.h" | 36 | #include "../pci.h" |
@@ -285,17 +286,8 @@ static int board_added(struct slot *p_slot) | |||
285 | return WRONG_BUS_FREQUENCY; | 286 | return WRONG_BUS_FREQUENCY; |
286 | } | 287 | } |
287 | 288 | ||
288 | rc = p_slot->hpc_ops->get_cur_bus_speed(p_slot, &bsp); | 289 | bsp = ctrl->pci_dev->bus->cur_bus_speed; |
289 | if (rc) { | 290 | msp = ctrl->pci_dev->bus->max_bus_speed; |
290 | ctrl_err(ctrl, "Can't get bus operation speed\n"); | ||
291 | return WRONG_BUS_FREQUENCY; | ||
292 | } | ||
293 | |||
294 | rc = p_slot->hpc_ops->get_max_bus_speed(p_slot, &msp); | ||
295 | if (rc) { | ||
296 | ctrl_err(ctrl, "Can't get max bus operation speed\n"); | ||
297 | msp = bsp; | ||
298 | } | ||
299 | 291 | ||
300 | /* Check if there are other slots or devices on the same bus */ | 292 | /* Check if there are other slots or devices on the same bus */ |
301 | if (!list_empty(&ctrl->pci_dev->subordinate->devices)) | 293 | if (!list_empty(&ctrl->pci_dev->subordinate->devices)) |
@@ -462,6 +454,7 @@ void shpchp_queue_pushbutton_work(struct work_struct *work) | |||
462 | p_slot->state = POWERON_STATE; | 454 | p_slot->state = POWERON_STATE; |
463 | break; | 455 | break; |
464 | default: | 456 | default: |
457 | kfree(info); | ||
465 | goto out; | 458 | goto out; |
466 | } | 459 | } |
467 | queue_work(shpchp_wq, &info->work); | 460 | queue_work(shpchp_wq, &info->work); |
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 86dc39847769..5f5e8d2e3552 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c | |||
@@ -660,6 +660,75 @@ static int hpc_slot_disable(struct slot * slot) | |||
660 | return retval; | 660 | return retval; |
661 | } | 661 | } |
662 | 662 | ||
663 | static int shpc_get_cur_bus_speed(struct controller *ctrl) | ||
664 | { | ||
665 | int retval = 0; | ||
666 | struct pci_bus *bus = ctrl->pci_dev->subordinate; | ||
667 | enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; | ||
668 | u16 sec_bus_reg = shpc_readw(ctrl, SEC_BUS_CONFIG); | ||
669 | u8 pi = shpc_readb(ctrl, PROG_INTERFACE); | ||
670 | u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7); | ||
671 | |||
672 | if ((pi == 1) && (speed_mode > 4)) { | ||
673 | retval = -ENODEV; | ||
674 | goto out; | ||
675 | } | ||
676 | |||
677 | switch (speed_mode) { | ||
678 | case 0x0: | ||
679 | bus_speed = PCI_SPEED_33MHz; | ||
680 | break; | ||
681 | case 0x1: | ||
682 | bus_speed = PCI_SPEED_66MHz; | ||
683 | break; | ||
684 | case 0x2: | ||
685 | bus_speed = PCI_SPEED_66MHz_PCIX; | ||
686 | break; | ||
687 | case 0x3: | ||
688 | bus_speed = PCI_SPEED_100MHz_PCIX; | ||
689 | break; | ||
690 | case 0x4: | ||
691 | bus_speed = PCI_SPEED_133MHz_PCIX; | ||
692 | break; | ||
693 | case 0x5: | ||
694 | bus_speed = PCI_SPEED_66MHz_PCIX_ECC; | ||
695 | break; | ||
696 | case 0x6: | ||
697 | bus_speed = PCI_SPEED_100MHz_PCIX_ECC; | ||
698 | break; | ||
699 | case 0x7: | ||
700 | bus_speed = PCI_SPEED_133MHz_PCIX_ECC; | ||
701 | break; | ||
702 | case 0x8: | ||
703 | bus_speed = PCI_SPEED_66MHz_PCIX_266; | ||
704 | break; | ||
705 | case 0x9: | ||
706 | bus_speed = PCI_SPEED_100MHz_PCIX_266; | ||
707 | break; | ||
708 | case 0xa: | ||
709 | bus_speed = PCI_SPEED_133MHz_PCIX_266; | ||
710 | break; | ||
711 | case 0xb: | ||
712 | bus_speed = PCI_SPEED_66MHz_PCIX_533; | ||
713 | break; | ||
714 | case 0xc: | ||
715 | bus_speed = PCI_SPEED_100MHz_PCIX_533; | ||
716 | break; | ||
717 | case 0xd: | ||
718 | bus_speed = PCI_SPEED_133MHz_PCIX_533; | ||
719 | break; | ||
720 | default: | ||
721 | retval = -ENODEV; | ||
722 | break; | ||
723 | } | ||
724 | |||
725 | out: | ||
726 | bus->cur_bus_speed = bus_speed; | ||
727 | dbg("Current bus speed = %d\n", bus_speed); | ||
728 | return retval; | ||
729 | } | ||
730 | |||
731 | |||
663 | static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) | 732 | static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) |
664 | { | 733 | { |
665 | int retval; | 734 | int retval; |
@@ -720,6 +789,8 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) | |||
720 | retval = shpc_write_cmd(slot, 0, cmd); | 789 | retval = shpc_write_cmd(slot, 0, cmd); |
721 | if (retval) | 790 | if (retval) |
722 | ctrl_err(ctrl, "%s: Write command failed!\n", __func__); | 791 | ctrl_err(ctrl, "%s: Write command failed!\n", __func__); |
792 | else | ||
793 | shpc_get_cur_bus_speed(ctrl); | ||
723 | 794 | ||
724 | return retval; | 795 | return retval; |
725 | } | 796 | } |
@@ -803,10 +874,10 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) | |||
803 | return IRQ_HANDLED; | 874 | return IRQ_HANDLED; |
804 | } | 875 | } |
805 | 876 | ||
806 | static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) | 877 | static int shpc_get_max_bus_speed(struct controller *ctrl) |
807 | { | 878 | { |
808 | int retval = 0; | 879 | int retval = 0; |
809 | struct controller *ctrl = slot->ctrl; | 880 | struct pci_bus *bus = ctrl->pci_dev->subordinate; |
810 | enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; | 881 | enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; |
811 | u8 pi = shpc_readb(ctrl, PROG_INTERFACE); | 882 | u8 pi = shpc_readb(ctrl, PROG_INTERFACE); |
812 | u32 slot_avail1 = shpc_readl(ctrl, SLOT_AVAIL1); | 883 | u32 slot_avail1 = shpc_readl(ctrl, SLOT_AVAIL1); |
@@ -842,79 +913,12 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) | |||
842 | retval = -ENODEV; | 913 | retval = -ENODEV; |
843 | } | 914 | } |
844 | 915 | ||
845 | *value = bus_speed; | 916 | bus->max_bus_speed = bus_speed; |
846 | ctrl_dbg(ctrl, "Max bus speed = %d\n", bus_speed); | 917 | ctrl_dbg(ctrl, "Max bus speed = %d\n", bus_speed); |
847 | 918 | ||
848 | return retval; | 919 | return retval; |
849 | } | 920 | } |
850 | 921 | ||
851 | static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value) | ||
852 | { | ||
853 | int retval = 0; | ||
854 | struct controller *ctrl = slot->ctrl; | ||
855 | enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; | ||
856 | u16 sec_bus_reg = shpc_readw(ctrl, SEC_BUS_CONFIG); | ||
857 | u8 pi = shpc_readb(ctrl, PROG_INTERFACE); | ||
858 | u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7); | ||
859 | |||
860 | if ((pi == 1) && (speed_mode > 4)) { | ||
861 | *value = PCI_SPEED_UNKNOWN; | ||
862 | return -ENODEV; | ||
863 | } | ||
864 | |||
865 | switch (speed_mode) { | ||
866 | case 0x0: | ||
867 | *value = PCI_SPEED_33MHz; | ||
868 | break; | ||
869 | case 0x1: | ||
870 | *value = PCI_SPEED_66MHz; | ||
871 | break; | ||
872 | case 0x2: | ||
873 | *value = PCI_SPEED_66MHz_PCIX; | ||
874 | break; | ||
875 | case 0x3: | ||
876 | *value = PCI_SPEED_100MHz_PCIX; | ||
877 | break; | ||
878 | case 0x4: | ||
879 | *value = PCI_SPEED_133MHz_PCIX; | ||
880 | break; | ||
881 | case 0x5: | ||
882 | *value = PCI_SPEED_66MHz_PCIX_ECC; | ||
883 | break; | ||
884 | case 0x6: | ||
885 | *value = PCI_SPEED_100MHz_PCIX_ECC; | ||
886 | break; | ||
887 | case 0x7: | ||
888 | *value = PCI_SPEED_133MHz_PCIX_ECC; | ||
889 | break; | ||
890 | case 0x8: | ||
891 | *value = PCI_SPEED_66MHz_PCIX_266; | ||
892 | break; | ||
893 | case 0x9: | ||
894 | *value = PCI_SPEED_100MHz_PCIX_266; | ||
895 | break; | ||
896 | case 0xa: | ||
897 | *value = PCI_SPEED_133MHz_PCIX_266; | ||
898 | break; | ||
899 | case 0xb: | ||
900 | *value = PCI_SPEED_66MHz_PCIX_533; | ||
901 | break; | ||
902 | case 0xc: | ||
903 | *value = PCI_SPEED_100MHz_PCIX_533; | ||
904 | break; | ||
905 | case 0xd: | ||
906 | *value = PCI_SPEED_133MHz_PCIX_533; | ||
907 | break; | ||
908 | default: | ||
909 | *value = PCI_SPEED_UNKNOWN; | ||
910 | retval = -ENODEV; | ||
911 | break; | ||
912 | } | ||
913 | |||
914 | ctrl_dbg(ctrl, "Current bus speed = %d\n", bus_speed); | ||
915 | return retval; | ||
916 | } | ||
917 | |||
918 | static struct hpc_ops shpchp_hpc_ops = { | 922 | static struct hpc_ops shpchp_hpc_ops = { |
919 | .power_on_slot = hpc_power_on_slot, | 923 | .power_on_slot = hpc_power_on_slot, |
920 | .slot_enable = hpc_slot_enable, | 924 | .slot_enable = hpc_slot_enable, |
@@ -926,8 +930,6 @@ static struct hpc_ops shpchp_hpc_ops = { | |||
926 | .get_latch_status = hpc_get_latch_status, | 930 | .get_latch_status = hpc_get_latch_status, |
927 | .get_adapter_status = hpc_get_adapter_status, | 931 | .get_adapter_status = hpc_get_adapter_status, |
928 | 932 | ||
929 | .get_max_bus_speed = hpc_get_max_bus_speed, | ||
930 | .get_cur_bus_speed = hpc_get_cur_bus_speed, | ||
931 | .get_adapter_speed = hpc_get_adapter_speed, | 933 | .get_adapter_speed = hpc_get_adapter_speed, |
932 | .get_mode1_ECC_cap = hpc_get_mode1_ECC_cap, | 934 | .get_mode1_ECC_cap = hpc_get_mode1_ECC_cap, |
933 | .get_prog_int = hpc_get_prog_int, | 935 | .get_prog_int = hpc_get_prog_int, |
@@ -1086,6 +1088,9 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) | |||
1086 | } | 1088 | } |
1087 | ctrl_dbg(ctrl, "HPC at %s irq=%x\n", pci_name(pdev), pdev->irq); | 1089 | ctrl_dbg(ctrl, "HPC at %s irq=%x\n", pci_name(pdev), pdev->irq); |
1088 | 1090 | ||
1091 | shpc_get_max_bus_speed(ctrl); | ||
1092 | shpc_get_cur_bus_speed(ctrl); | ||
1093 | |||
1089 | /* | 1094 | /* |
1090 | * If this is the first controller to be initialized, | 1095 | * If this is the first controller to be initialized, |
1091 | * initialize the shpchpd work queue | 1096 | * initialize the shpchpd work queue |
diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c index 29fa9d26adae..071b7dc0094b 100644 --- a/drivers/pci/hotplug/shpchp_sysfs.c +++ b/drivers/pci/hotplug/shpchp_sysfs.c | |||
@@ -47,8 +47,7 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha | |||
47 | bus = pdev->subordinate; | 47 | bus = pdev->subordinate; |
48 | 48 | ||
49 | out += sprintf(buf, "Free resources: memory\n"); | 49 | out += sprintf(buf, "Free resources: memory\n"); |
50 | for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) { | 50 | pci_bus_for_each_resource(bus, res, index) { |
51 | res = bus->resource[index]; | ||
52 | if (res && (res->flags & IORESOURCE_MEM) && | 51 | if (res && (res->flags & IORESOURCE_MEM) && |
53 | !(res->flags & IORESOURCE_PREFETCH)) { | 52 | !(res->flags & IORESOURCE_PREFETCH)) { |
54 | out += sprintf(out, "start = %8.8llx, " | 53 | out += sprintf(out, "start = %8.8llx, " |
@@ -58,8 +57,7 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha | |||
58 | } | 57 | } |
59 | } | 58 | } |
60 | out += sprintf(out, "Free resources: prefetchable memory\n"); | 59 | out += sprintf(out, "Free resources: prefetchable memory\n"); |
61 | for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) { | 60 | pci_bus_for_each_resource(bus, res, index) { |
62 | res = bus->resource[index]; | ||
63 | if (res && (res->flags & IORESOURCE_MEM) && | 61 | if (res && (res->flags & IORESOURCE_MEM) && |
64 | (res->flags & IORESOURCE_PREFETCH)) { | 62 | (res->flags & IORESOURCE_PREFETCH)) { |
65 | out += sprintf(out, "start = %8.8llx, " | 63 | out += sprintf(out, "start = %8.8llx, " |
@@ -69,8 +67,7 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha | |||
69 | } | 67 | } |
70 | } | 68 | } |
71 | out += sprintf(out, "Free resources: IO\n"); | 69 | out += sprintf(out, "Free resources: IO\n"); |
72 | for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) { | 70 | pci_bus_for_each_resource(bus, res, index) { |
73 | res = bus->resource[index]; | ||
74 | if (res && (res->flags & IORESOURCE_IO)) { | 71 | if (res && (res->flags & IORESOURCE_IO)) { |
75 | out += sprintf(out, "start = %8.8llx, " | 72 | out += sprintf(out, "start = %8.8llx, " |
76 | "length = %8.8llx\n", | 73 | "length = %8.8llx\n", |
diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c index 737a1c44b07a..98abf8b91294 100644 --- a/drivers/pci/htirq.c +++ b/drivers/pci/htirq.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include <linux/pci.h> | 10 | #include <linux/pci.h> |
11 | #include <linux/spinlock.h> | 11 | #include <linux/spinlock.h> |
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/gfp.h> | ||
14 | #include <linux/htirq.h> | 13 | #include <linux/htirq.h> |
15 | 14 | ||
16 | /* Global ht irq lock. | 15 | /* Global ht irq lock. |
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 1840a0578a42..417312528ddf 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -277,6 +277,7 @@ static int hw_pass_through = 1; | |||
277 | 277 | ||
278 | struct dmar_domain { | 278 | struct dmar_domain { |
279 | int id; /* domain id */ | 279 | int id; /* domain id */ |
280 | int nid; /* node id */ | ||
280 | unsigned long iommu_bmp; /* bitmap of iommus this domain uses*/ | 281 | unsigned long iommu_bmp; /* bitmap of iommus this domain uses*/ |
281 | 282 | ||
282 | struct list_head devices; /* all devices' list */ | 283 | struct list_head devices; /* all devices' list */ |
@@ -304,7 +305,7 @@ struct device_domain_info { | |||
304 | int segment; /* PCI domain */ | 305 | int segment; /* PCI domain */ |
305 | u8 bus; /* PCI bus number */ | 306 | u8 bus; /* PCI bus number */ |
306 | u8 devfn; /* PCI devfn number */ | 307 | u8 devfn; /* PCI devfn number */ |
307 | struct pci_dev *dev; /* it's NULL for PCIE-to-PCI bridge */ | 308 | struct pci_dev *dev; /* it's NULL for PCIe-to-PCI bridge */ |
308 | struct intel_iommu *iommu; /* IOMMU used by this device */ | 309 | struct intel_iommu *iommu; /* IOMMU used by this device */ |
309 | struct dmar_domain *domain; /* pointer to domain */ | 310 | struct dmar_domain *domain; /* pointer to domain */ |
310 | }; | 311 | }; |
@@ -386,30 +387,14 @@ static struct kmem_cache *iommu_domain_cache; | |||
386 | static struct kmem_cache *iommu_devinfo_cache; | 387 | static struct kmem_cache *iommu_devinfo_cache; |
387 | static struct kmem_cache *iommu_iova_cache; | 388 | static struct kmem_cache *iommu_iova_cache; |
388 | 389 | ||
389 | static inline void *iommu_kmem_cache_alloc(struct kmem_cache *cachep) | 390 | static inline void *alloc_pgtable_page(int node) |
390 | { | 391 | { |
391 | unsigned int flags; | 392 | struct page *page; |
392 | void *vaddr; | 393 | void *vaddr = NULL; |
393 | |||
394 | /* trying to avoid low memory issues */ | ||
395 | flags = current->flags & PF_MEMALLOC; | ||
396 | current->flags |= PF_MEMALLOC; | ||
397 | vaddr = kmem_cache_alloc(cachep, GFP_ATOMIC); | ||
398 | current->flags &= (~PF_MEMALLOC | flags); | ||
399 | return vaddr; | ||
400 | } | ||
401 | |||
402 | 394 | ||
403 | static inline void *alloc_pgtable_page(void) | 395 | page = alloc_pages_node(node, GFP_ATOMIC | __GFP_ZERO, 0); |
404 | { | 396 | if (page) |
405 | unsigned int flags; | 397 | vaddr = page_address(page); |
406 | void *vaddr; | ||
407 | |||
408 | /* trying to avoid low memory issues */ | ||
409 | flags = current->flags & PF_MEMALLOC; | ||
410 | current->flags |= PF_MEMALLOC; | ||
411 | vaddr = (void *)get_zeroed_page(GFP_ATOMIC); | ||
412 | current->flags &= (~PF_MEMALLOC | flags); | ||
413 | return vaddr; | 398 | return vaddr; |
414 | } | 399 | } |
415 | 400 | ||
@@ -420,7 +405,7 @@ static inline void free_pgtable_page(void *vaddr) | |||
420 | 405 | ||
421 | static inline void *alloc_domain_mem(void) | 406 | static inline void *alloc_domain_mem(void) |
422 | { | 407 | { |
423 | return iommu_kmem_cache_alloc(iommu_domain_cache); | 408 | return kmem_cache_alloc(iommu_domain_cache, GFP_ATOMIC); |
424 | } | 409 | } |
425 | 410 | ||
426 | static void free_domain_mem(void *vaddr) | 411 | static void free_domain_mem(void *vaddr) |
@@ -430,7 +415,7 @@ static void free_domain_mem(void *vaddr) | |||
430 | 415 | ||
431 | static inline void * alloc_devinfo_mem(void) | 416 | static inline void * alloc_devinfo_mem(void) |
432 | { | 417 | { |
433 | return iommu_kmem_cache_alloc(iommu_devinfo_cache); | 418 | return kmem_cache_alloc(iommu_devinfo_cache, GFP_ATOMIC); |
434 | } | 419 | } |
435 | 420 | ||
436 | static inline void free_devinfo_mem(void *vaddr) | 421 | static inline void free_devinfo_mem(void *vaddr) |
@@ -440,7 +425,7 @@ static inline void free_devinfo_mem(void *vaddr) | |||
440 | 425 | ||
441 | struct iova *alloc_iova_mem(void) | 426 | struct iova *alloc_iova_mem(void) |
442 | { | 427 | { |
443 | return iommu_kmem_cache_alloc(iommu_iova_cache); | 428 | return kmem_cache_alloc(iommu_iova_cache, GFP_ATOMIC); |
444 | } | 429 | } |
445 | 430 | ||
446 | void free_iova_mem(struct iova *iova) | 431 | void free_iova_mem(struct iova *iova) |
@@ -589,7 +574,8 @@ static struct context_entry * device_to_context_entry(struct intel_iommu *iommu, | |||
589 | root = &iommu->root_entry[bus]; | 574 | root = &iommu->root_entry[bus]; |
590 | context = get_context_addr_from_root(root); | 575 | context = get_context_addr_from_root(root); |
591 | if (!context) { | 576 | if (!context) { |
592 | context = (struct context_entry *)alloc_pgtable_page(); | 577 | context = (struct context_entry *) |
578 | alloc_pgtable_page(iommu->node); | ||
593 | if (!context) { | 579 | if (!context) { |
594 | spin_unlock_irqrestore(&iommu->lock, flags); | 580 | spin_unlock_irqrestore(&iommu->lock, flags); |
595 | return NULL; | 581 | return NULL; |
@@ -732,7 +718,7 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, | |||
732 | if (!dma_pte_present(pte)) { | 718 | if (!dma_pte_present(pte)) { |
733 | uint64_t pteval; | 719 | uint64_t pteval; |
734 | 720 | ||
735 | tmp_page = alloc_pgtable_page(); | 721 | tmp_page = alloc_pgtable_page(domain->nid); |
736 | 722 | ||
737 | if (!tmp_page) | 723 | if (!tmp_page) |
738 | return NULL; | 724 | return NULL; |
@@ -868,7 +854,7 @@ static int iommu_alloc_root_entry(struct intel_iommu *iommu) | |||
868 | struct root_entry *root; | 854 | struct root_entry *root; |
869 | unsigned long flags; | 855 | unsigned long flags; |
870 | 856 | ||
871 | root = (struct root_entry *)alloc_pgtable_page(); | 857 | root = (struct root_entry *)alloc_pgtable_page(iommu->node); |
872 | if (!root) | 858 | if (!root) |
873 | return -ENOMEM; | 859 | return -ENOMEM; |
874 | 860 | ||
@@ -1263,6 +1249,7 @@ static struct dmar_domain *alloc_domain(void) | |||
1263 | if (!domain) | 1249 | if (!domain) |
1264 | return NULL; | 1250 | return NULL; |
1265 | 1251 | ||
1252 | domain->nid = -1; | ||
1266 | memset(&domain->iommu_bmp, 0, sizeof(unsigned long)); | 1253 | memset(&domain->iommu_bmp, 0, sizeof(unsigned long)); |
1267 | domain->flags = 0; | 1254 | domain->flags = 0; |
1268 | 1255 | ||
@@ -1420,9 +1407,10 @@ static int domain_init(struct dmar_domain *domain, int guest_width) | |||
1420 | domain->iommu_snooping = 0; | 1407 | domain->iommu_snooping = 0; |
1421 | 1408 | ||
1422 | domain->iommu_count = 1; | 1409 | domain->iommu_count = 1; |
1410 | domain->nid = iommu->node; | ||
1423 | 1411 | ||
1424 | /* always allocate the top pgd */ | 1412 | /* always allocate the top pgd */ |
1425 | domain->pgd = (struct dma_pte *)alloc_pgtable_page(); | 1413 | domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid); |
1426 | if (!domain->pgd) | 1414 | if (!domain->pgd) |
1427 | return -ENOMEM; | 1415 | return -ENOMEM; |
1428 | __iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE); | 1416 | __iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE); |
@@ -1523,12 +1511,15 @@ static int domain_context_mapping_one(struct dmar_domain *domain, int segment, | |||
1523 | 1511 | ||
1524 | /* Skip top levels of page tables for | 1512 | /* Skip top levels of page tables for |
1525 | * iommu which has less agaw than default. | 1513 | * iommu which has less agaw than default. |
1514 | * Unnecessary for PT mode. | ||
1526 | */ | 1515 | */ |
1527 | for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) { | 1516 | if (translation != CONTEXT_TT_PASS_THROUGH) { |
1528 | pgd = phys_to_virt(dma_pte_addr(pgd)); | 1517 | for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) { |
1529 | if (!dma_pte_present(pgd)) { | 1518 | pgd = phys_to_virt(dma_pte_addr(pgd)); |
1530 | spin_unlock_irqrestore(&iommu->lock, flags); | 1519 | if (!dma_pte_present(pgd)) { |
1531 | return -ENOMEM; | 1520 | spin_unlock_irqrestore(&iommu->lock, flags); |
1521 | return -ENOMEM; | ||
1522 | } | ||
1532 | } | 1523 | } |
1533 | } | 1524 | } |
1534 | } | 1525 | } |
@@ -1577,6 +1568,8 @@ static int domain_context_mapping_one(struct dmar_domain *domain, int segment, | |||
1577 | spin_lock_irqsave(&domain->iommu_lock, flags); | 1568 | spin_lock_irqsave(&domain->iommu_lock, flags); |
1578 | if (!test_and_set_bit(iommu->seq_id, &domain->iommu_bmp)) { | 1569 | if (!test_and_set_bit(iommu->seq_id, &domain->iommu_bmp)) { |
1579 | domain->iommu_count++; | 1570 | domain->iommu_count++; |
1571 | if (domain->iommu_count == 1) | ||
1572 | domain->nid = iommu->node; | ||
1580 | domain_update_iommu_cap(domain); | 1573 | domain_update_iommu_cap(domain); |
1581 | } | 1574 | } |
1582 | spin_unlock_irqrestore(&domain->iommu_lock, flags); | 1575 | spin_unlock_irqrestore(&domain->iommu_lock, flags); |
@@ -1611,7 +1604,7 @@ domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev, | |||
1611 | return ret; | 1604 | return ret; |
1612 | parent = parent->bus->self; | 1605 | parent = parent->bus->self; |
1613 | } | 1606 | } |
1614 | if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */ | 1607 | if (pci_is_pcie(tmp)) /* this is a PCIe-to-PCI bridge */ |
1615 | return domain_context_mapping_one(domain, | 1608 | return domain_context_mapping_one(domain, |
1616 | pci_domain_nr(tmp->subordinate), | 1609 | pci_domain_nr(tmp->subordinate), |
1617 | tmp->subordinate->number, 0, | 1610 | tmp->subordinate->number, 0, |
@@ -1651,7 +1644,7 @@ static int domain_context_mapped(struct pci_dev *pdev) | |||
1651 | return ret; | 1644 | return ret; |
1652 | parent = parent->bus->self; | 1645 | parent = parent->bus->self; |
1653 | } | 1646 | } |
1654 | if (tmp->is_pcie) | 1647 | if (pci_is_pcie(tmp)) |
1655 | return device_context_mapped(iommu, tmp->subordinate->number, | 1648 | return device_context_mapped(iommu, tmp->subordinate->number, |
1656 | 0); | 1649 | 0); |
1657 | else | 1650 | else |
@@ -1821,7 +1814,7 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) | |||
1821 | 1814 | ||
1822 | dev_tmp = pci_find_upstream_pcie_bridge(pdev); | 1815 | dev_tmp = pci_find_upstream_pcie_bridge(pdev); |
1823 | if (dev_tmp) { | 1816 | if (dev_tmp) { |
1824 | if (dev_tmp->is_pcie) { | 1817 | if (pci_is_pcie(dev_tmp)) { |
1825 | bus = dev_tmp->subordinate->number; | 1818 | bus = dev_tmp->subordinate->number; |
1826 | devfn = 0; | 1819 | devfn = 0; |
1827 | } else { | 1820 | } else { |
@@ -1991,6 +1984,16 @@ static int iommu_prepare_identity_map(struct pci_dev *pdev, | |||
1991 | "IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n", | 1984 | "IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n", |
1992 | pci_name(pdev), start, end); | 1985 | pci_name(pdev), start, end); |
1993 | 1986 | ||
1987 | if (end < start) { | ||
1988 | WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n" | ||
1989 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", | ||
1990 | dmi_get_system_info(DMI_BIOS_VENDOR), | ||
1991 | dmi_get_system_info(DMI_BIOS_VERSION), | ||
1992 | dmi_get_system_info(DMI_PRODUCT_VERSION)); | ||
1993 | ret = -EIO; | ||
1994 | goto error; | ||
1995 | } | ||
1996 | |||
1994 | if (end >> agaw_to_width(domain->agaw)) { | 1997 | if (end >> agaw_to_width(domain->agaw)) { |
1995 | WARN(1, "Your BIOS is broken; RMRR exceeds permitted address width (%d bits)\n" | 1998 | WARN(1, "Your BIOS is broken; RMRR exceeds permitted address width (%d bits)\n" |
1996 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", | 1999 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", |
@@ -2182,7 +2185,7 @@ static int iommu_should_identity_map(struct pci_dev *pdev, int startup) | |||
2182 | * the 1:1 domain, just in _case_ one of their siblings turns out | 2185 | * the 1:1 domain, just in _case_ one of their siblings turns out |
2183 | * not to be able to map all of memory. | 2186 | * not to be able to map all of memory. |
2184 | */ | 2187 | */ |
2185 | if (!pdev->is_pcie) { | 2188 | if (!pci_is_pcie(pdev)) { |
2186 | if (!pci_is_root_bus(pdev->bus)) | 2189 | if (!pci_is_root_bus(pdev->bus)) |
2187 | return 0; | 2190 | return 0; |
2188 | if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI) | 2191 | if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI) |
@@ -3228,6 +3231,9 @@ static int device_notifier(struct notifier_block *nb, | |||
3228 | struct pci_dev *pdev = to_pci_dev(dev); | 3231 | struct pci_dev *pdev = to_pci_dev(dev); |
3229 | struct dmar_domain *domain; | 3232 | struct dmar_domain *domain; |
3230 | 3233 | ||
3234 | if (iommu_no_mapping(dev)) | ||
3235 | return 0; | ||
3236 | |||
3231 | domain = find_domain(pdev); | 3237 | domain = find_domain(pdev); |
3232 | if (!domain) | 3238 | if (!domain) |
3233 | return 0; | 3239 | return 0; |
@@ -3266,7 +3272,7 @@ int __init intel_iommu_init(void) | |||
3266 | * Check the need for DMA-remapping initialization now. | 3272 | * Check the need for DMA-remapping initialization now. |
3267 | * Above initialization will also be used by Interrupt-remapping. | 3273 | * Above initialization will also be used by Interrupt-remapping. |
3268 | */ | 3274 | */ |
3269 | if (no_iommu || swiotlb || dmar_disabled) | 3275 | if (no_iommu || dmar_disabled) |
3270 | return -ENODEV; | 3276 | return -ENODEV; |
3271 | 3277 | ||
3272 | iommu_init_mempool(); | 3278 | iommu_init_mempool(); |
@@ -3287,7 +3293,9 @@ int __init intel_iommu_init(void) | |||
3287 | "PCI-DMA: Intel(R) Virtualization Technology for Directed I/O\n"); | 3293 | "PCI-DMA: Intel(R) Virtualization Technology for Directed I/O\n"); |
3288 | 3294 | ||
3289 | init_timer(&unmap_timer); | 3295 | init_timer(&unmap_timer); |
3290 | force_iommu = 1; | 3296 | #ifdef CONFIG_SWIOTLB |
3297 | swiotlb = 0; | ||
3298 | #endif | ||
3291 | dma_ops = &intel_dma_ops; | 3299 | dma_ops = &intel_dma_ops; |
3292 | 3300 | ||
3293 | init_iommu_sysfs(); | 3301 | init_iommu_sysfs(); |
@@ -3317,7 +3325,7 @@ static void iommu_detach_dependent_devices(struct intel_iommu *iommu, | |||
3317 | parent->devfn); | 3325 | parent->devfn); |
3318 | parent = parent->bus->self; | 3326 | parent = parent->bus->self; |
3319 | } | 3327 | } |
3320 | if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */ | 3328 | if (pci_is_pcie(tmp)) /* this is a PCIe-to-PCI bridge */ |
3321 | iommu_detach_dev(iommu, | 3329 | iommu_detach_dev(iommu, |
3322 | tmp->subordinate->number, 0); | 3330 | tmp->subordinate->number, 0); |
3323 | else /* this is a legacy PCI bridge */ | 3331 | else /* this is a legacy PCI bridge */ |
@@ -3453,6 +3461,7 @@ static struct dmar_domain *iommu_alloc_vm_domain(void) | |||
3453 | return NULL; | 3461 | return NULL; |
3454 | 3462 | ||
3455 | domain->id = vm_domid++; | 3463 | domain->id = vm_domid++; |
3464 | domain->nid = -1; | ||
3456 | memset(&domain->iommu_bmp, 0, sizeof(unsigned long)); | 3465 | memset(&domain->iommu_bmp, 0, sizeof(unsigned long)); |
3457 | domain->flags = DOMAIN_FLAG_VIRTUAL_MACHINE; | 3466 | domain->flags = DOMAIN_FLAG_VIRTUAL_MACHINE; |
3458 | 3467 | ||
@@ -3479,9 +3488,10 @@ static int md_domain_init(struct dmar_domain *domain, int guest_width) | |||
3479 | domain->iommu_coherency = 0; | 3488 | domain->iommu_coherency = 0; |
3480 | domain->iommu_snooping = 0; | 3489 | domain->iommu_snooping = 0; |
3481 | domain->max_addr = 0; | 3490 | domain->max_addr = 0; |
3491 | domain->nid = -1; | ||
3482 | 3492 | ||
3483 | /* always allocate the top pgd */ | 3493 | /* always allocate the top pgd */ |
3484 | domain->pgd = (struct dma_pte *)alloc_pgtable_page(); | 3494 | domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid); |
3485 | if (!domain->pgd) | 3495 | if (!domain->pgd) |
3486 | return -ENOMEM; | 3496 | return -ENOMEM; |
3487 | domain_flush_cache(domain, domain->pgd, PAGE_SIZE); | 3497 | domain_flush_cache(domain, domain->pgd, PAGE_SIZE); |
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c index 0ed78a764ded..6ee98a56946f 100644 --- a/drivers/pci/intr_remapping.c +++ b/drivers/pci/intr_remapping.c | |||
@@ -1,7 +1,9 @@ | |||
1 | #include <linux/interrupt.h> | 1 | #include <linux/interrupt.h> |
2 | #include <linux/dmar.h> | 2 | #include <linux/dmar.h> |
3 | #include <linux/spinlock.h> | 3 | #include <linux/spinlock.h> |
4 | #include <linux/slab.h> | ||
4 | #include <linux/jiffies.h> | 5 | #include <linux/jiffies.h> |
6 | #include <linux/hpet.h> | ||
5 | #include <linux/pci.h> | 7 | #include <linux/pci.h> |
6 | #include <linux/irq.h> | 8 | #include <linux/irq.h> |
7 | #include <asm/io_apic.h> | 9 | #include <asm/io_apic.h> |
@@ -14,7 +16,8 @@ | |||
14 | #include "pci.h" | 16 | #include "pci.h" |
15 | 17 | ||
16 | static struct ioapic_scope ir_ioapic[MAX_IO_APICS]; | 18 | static struct ioapic_scope ir_ioapic[MAX_IO_APICS]; |
17 | static int ir_ioapic_num; | 19 | static struct hpet_scope ir_hpet[MAX_HPET_TBS]; |
20 | static int ir_ioapic_num, ir_hpet_num; | ||
18 | int intr_remapping_enabled; | 21 | int intr_remapping_enabled; |
19 | 22 | ||
20 | static int disable_intremap; | 23 | static int disable_intremap; |
@@ -343,6 +346,16 @@ int flush_irte(int irq) | |||
343 | return rc; | 346 | return rc; |
344 | } | 347 | } |
345 | 348 | ||
349 | struct intel_iommu *map_hpet_to_ir(u8 hpet_id) | ||
350 | { | ||
351 | int i; | ||
352 | |||
353 | for (i = 0; i < MAX_HPET_TBS; i++) | ||
354 | if (ir_hpet[i].id == hpet_id) | ||
355 | return ir_hpet[i].iommu; | ||
356 | return NULL; | ||
357 | } | ||
358 | |||
346 | struct intel_iommu *map_ioapic_to_ir(int apic) | 359 | struct intel_iommu *map_ioapic_to_ir(int apic) |
347 | { | 360 | { |
348 | int i; | 361 | int i; |
@@ -470,6 +483,36 @@ int set_ioapic_sid(struct irte *irte, int apic) | |||
470 | return 0; | 483 | return 0; |
471 | } | 484 | } |
472 | 485 | ||
486 | int set_hpet_sid(struct irte *irte, u8 id) | ||
487 | { | ||
488 | int i; | ||
489 | u16 sid = 0; | ||
490 | |||
491 | if (!irte) | ||
492 | return -1; | ||
493 | |||
494 | for (i = 0; i < MAX_HPET_TBS; i++) { | ||
495 | if (ir_hpet[i].id == id) { | ||
496 | sid = (ir_hpet[i].bus << 8) | ir_hpet[i].devfn; | ||
497 | break; | ||
498 | } | ||
499 | } | ||
500 | |||
501 | if (sid == 0) { | ||
502 | pr_warning("Failed to set source-id of HPET block (%d)\n", id); | ||
503 | return -1; | ||
504 | } | ||
505 | |||
506 | /* | ||
507 | * Should really use SQ_ALL_16. Some platforms are broken. | ||
508 | * While we figure out the right quirks for these broken platforms, use | ||
509 | * SQ_13_IGNORE_3 for now. | ||
510 | */ | ||
511 | set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_13_IGNORE_3, sid); | ||
512 | |||
513 | return 0; | ||
514 | } | ||
515 | |||
473 | int set_msi_sid(struct irte *irte, struct pci_dev *dev) | 516 | int set_msi_sid(struct irte *irte, struct pci_dev *dev) |
474 | { | 517 | { |
475 | struct pci_dev *bridge; | 518 | struct pci_dev *bridge; |
@@ -478,7 +521,7 @@ int set_msi_sid(struct irte *irte, struct pci_dev *dev) | |||
478 | return -1; | 521 | return -1; |
479 | 522 | ||
480 | /* PCIe device or Root Complex integrated PCI device */ | 523 | /* PCIe device or Root Complex integrated PCI device */ |
481 | if (dev->is_pcie || !dev->bus->parent) { | 524 | if (pci_is_pcie(dev) || !dev->bus->parent) { |
482 | set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_ALL_16, | 525 | set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_ALL_16, |
483 | (dev->bus->number << 8) | dev->devfn); | 526 | (dev->bus->number << 8) | dev->devfn); |
484 | return 0; | 527 | return 0; |
@@ -486,7 +529,7 @@ int set_msi_sid(struct irte *irte, struct pci_dev *dev) | |||
486 | 529 | ||
487 | bridge = pci_find_upstream_pcie_bridge(dev); | 530 | bridge = pci_find_upstream_pcie_bridge(dev); |
488 | if (bridge) { | 531 | if (bridge) { |
489 | if (bridge->is_pcie) /* this is a PCIE-to-PCI/PCIX bridge */ | 532 | if (pci_is_pcie(bridge))/* this is a PCIe-to-PCI/PCIX bridge */ |
490 | set_irte_sid(irte, SVT_VERIFY_BUS, SQ_ALL_16, | 533 | set_irte_sid(irte, SVT_VERIFY_BUS, SQ_ALL_16, |
491 | (bridge->bus->number << 8) | dev->bus->number); | 534 | (bridge->bus->number << 8) | dev->bus->number); |
492 | else /* this is a legacy PCI bridge */ | 535 | else /* this is a legacy PCI bridge */ |
@@ -548,7 +591,8 @@ static int setup_intr_remapping(struct intel_iommu *iommu, int mode) | |||
548 | if (!iommu->ir_table) | 591 | if (!iommu->ir_table) |
549 | return -ENOMEM; | 592 | return -ENOMEM; |
550 | 593 | ||
551 | pages = alloc_pages(GFP_ATOMIC | __GFP_ZERO, INTR_REMAP_PAGE_ORDER); | 594 | pages = alloc_pages_node(iommu->node, GFP_ATOMIC | __GFP_ZERO, |
595 | INTR_REMAP_PAGE_ORDER); | ||
552 | 596 | ||
553 | if (!pages) { | 597 | if (!pages) { |
554 | printk(KERN_ERR "failed to allocate pages of order %d\n", | 598 | printk(KERN_ERR "failed to allocate pages of order %d\n", |
@@ -711,6 +755,34 @@ error: | |||
711 | return -1; | 755 | return -1; |
712 | } | 756 | } |
713 | 757 | ||
758 | static void ir_parse_one_hpet_scope(struct acpi_dmar_device_scope *scope, | ||
759 | struct intel_iommu *iommu) | ||
760 | { | ||
761 | struct acpi_dmar_pci_path *path; | ||
762 | u8 bus; | ||
763 | int count; | ||
764 | |||
765 | bus = scope->bus; | ||
766 | path = (struct acpi_dmar_pci_path *)(scope + 1); | ||
767 | count = (scope->length - sizeof(struct acpi_dmar_device_scope)) | ||
768 | / sizeof(struct acpi_dmar_pci_path); | ||
769 | |||
770 | while (--count > 0) { | ||
771 | /* | ||
772 | * Access PCI directly due to the PCI | ||
773 | * subsystem isn't initialized yet. | ||
774 | */ | ||
775 | bus = read_pci_config_byte(bus, path->dev, path->fn, | ||
776 | PCI_SECONDARY_BUS); | ||
777 | path++; | ||
778 | } | ||
779 | ir_hpet[ir_hpet_num].bus = bus; | ||
780 | ir_hpet[ir_hpet_num].devfn = PCI_DEVFN(path->dev, path->fn); | ||
781 | ir_hpet[ir_hpet_num].iommu = iommu; | ||
782 | ir_hpet[ir_hpet_num].id = scope->enumeration_id; | ||
783 | ir_hpet_num++; | ||
784 | } | ||
785 | |||
714 | static void ir_parse_one_ioapic_scope(struct acpi_dmar_device_scope *scope, | 786 | static void ir_parse_one_ioapic_scope(struct acpi_dmar_device_scope *scope, |
715 | struct intel_iommu *iommu) | 787 | struct intel_iommu *iommu) |
716 | { | 788 | { |
@@ -740,8 +812,8 @@ static void ir_parse_one_ioapic_scope(struct acpi_dmar_device_scope *scope, | |||
740 | ir_ioapic_num++; | 812 | ir_ioapic_num++; |
741 | } | 813 | } |
742 | 814 | ||
743 | static int ir_parse_ioapic_scope(struct acpi_dmar_header *header, | 815 | static int ir_parse_ioapic_hpet_scope(struct acpi_dmar_header *header, |
744 | struct intel_iommu *iommu) | 816 | struct intel_iommu *iommu) |
745 | { | 817 | { |
746 | struct acpi_dmar_hardware_unit *drhd; | 818 | struct acpi_dmar_hardware_unit *drhd; |
747 | struct acpi_dmar_device_scope *scope; | 819 | struct acpi_dmar_device_scope *scope; |
@@ -765,6 +837,17 @@ static int ir_parse_ioapic_scope(struct acpi_dmar_header *header, | |||
765 | drhd->address); | 837 | drhd->address); |
766 | 838 | ||
767 | ir_parse_one_ioapic_scope(scope, iommu); | 839 | ir_parse_one_ioapic_scope(scope, iommu); |
840 | } else if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_HPET) { | ||
841 | if (ir_hpet_num == MAX_HPET_TBS) { | ||
842 | printk(KERN_WARNING "Exceeded Max HPET blocks\n"); | ||
843 | return -1; | ||
844 | } | ||
845 | |||
846 | printk(KERN_INFO "HPET id %d under DRHD base" | ||
847 | " 0x%Lx\n", scope->enumeration_id, | ||
848 | drhd->address); | ||
849 | |||
850 | ir_parse_one_hpet_scope(scope, iommu); | ||
768 | } | 851 | } |
769 | start += scope->length; | 852 | start += scope->length; |
770 | } | 853 | } |
@@ -785,7 +868,7 @@ int __init parse_ioapics_under_ir(void) | |||
785 | struct intel_iommu *iommu = drhd->iommu; | 868 | struct intel_iommu *iommu = drhd->iommu; |
786 | 869 | ||
787 | if (ecap_ir_support(iommu->ecap)) { | 870 | if (ecap_ir_support(iommu->ecap)) { |
788 | if (ir_parse_ioapic_scope(drhd->hdr, iommu)) | 871 | if (ir_parse_ioapic_hpet_scope(drhd->hdr, iommu)) |
789 | return -1; | 872 | return -1; |
790 | 873 | ||
791 | ir_supported = 1; | 874 | ir_supported = 1; |
diff --git a/drivers/pci/intr_remapping.h b/drivers/pci/intr_remapping.h index 63a263c18415..5662fecfee60 100644 --- a/drivers/pci/intr_remapping.h +++ b/drivers/pci/intr_remapping.h | |||
@@ -7,4 +7,11 @@ struct ioapic_scope { | |||
7 | unsigned int devfn; /* PCI devfn number */ | 7 | unsigned int devfn; /* PCI devfn number */ |
8 | }; | 8 | }; |
9 | 9 | ||
10 | struct hpet_scope { | ||
11 | struct intel_iommu *iommu; | ||
12 | u8 id; | ||
13 | unsigned int bus; | ||
14 | unsigned int devfn; | ||
15 | }; | ||
16 | |||
10 | #define IR_X2APIC_MODE(mode) (mode ? (1 << 11) : 0) | 17 | #define IR_X2APIC_MODE(mode) (mode ? (1 << 11) : 0) |
diff --git a/drivers/pci/ioapic.c b/drivers/pci/ioapic.c new file mode 100644 index 000000000000..203508b227b7 --- /dev/null +++ b/drivers/pci/ioapic.c | |||
@@ -0,0 +1,127 @@ | |||
1 | /* | ||
2 | * IOAPIC/IOxAPIC/IOSAPIC driver | ||
3 | * | ||
4 | * Copyright (C) 2009 Fujitsu Limited. | ||
5 | * (c) Copyright 2009 Hewlett-Packard Development Company, L.P. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * This driver manages PCI I/O APICs added by hotplug after boot. We try to | ||
14 | * claim all I/O APIC PCI devices, but those present at boot were registered | ||
15 | * when we parsed the ACPI MADT, so we'll fail when we try to re-register | ||
16 | * them. | ||
17 | */ | ||
18 | |||
19 | #include <linux/pci.h> | ||
20 | #include <linux/acpi.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <acpi/acpi_bus.h> | ||
23 | |||
24 | struct ioapic { | ||
25 | acpi_handle handle; | ||
26 | u32 gsi_base; | ||
27 | }; | ||
28 | |||
29 | static int ioapic_probe(struct pci_dev *dev, const struct pci_device_id *ent) | ||
30 | { | ||
31 | acpi_handle handle; | ||
32 | acpi_status status; | ||
33 | unsigned long long gsb; | ||
34 | struct ioapic *ioapic; | ||
35 | int ret; | ||
36 | char *type; | ||
37 | struct resource *res; | ||
38 | |||
39 | handle = DEVICE_ACPI_HANDLE(&dev->dev); | ||
40 | if (!handle) | ||
41 | return -EINVAL; | ||
42 | |||
43 | status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb); | ||
44 | if (ACPI_FAILURE(status)) | ||
45 | return -EINVAL; | ||
46 | |||
47 | /* | ||
48 | * The previous code in acpiphp evaluated _MAT if _GSB failed, but | ||
49 | * ACPI spec 4.0 sec 6.2.2 requires _GSB for hot-pluggable I/O APICs. | ||
50 | */ | ||
51 | |||
52 | ioapic = kzalloc(sizeof(*ioapic), GFP_KERNEL); | ||
53 | if (!ioapic) | ||
54 | return -ENOMEM; | ||
55 | |||
56 | ioapic->handle = handle; | ||
57 | ioapic->gsi_base = (u32) gsb; | ||
58 | |||
59 | if (dev->class == PCI_CLASS_SYSTEM_PIC_IOAPIC) | ||
60 | type = "IOAPIC"; | ||
61 | else | ||
62 | type = "IOxAPIC"; | ||
63 | |||
64 | ret = pci_enable_device(dev); | ||
65 | if (ret < 0) | ||
66 | goto exit_free; | ||
67 | |||
68 | pci_set_master(dev); | ||
69 | |||
70 | if (pci_request_region(dev, 0, type)) | ||
71 | goto exit_disable; | ||
72 | |||
73 | res = &dev->resource[0]; | ||
74 | if (acpi_register_ioapic(ioapic->handle, res->start, ioapic->gsi_base)) | ||
75 | goto exit_release; | ||
76 | |||
77 | pci_set_drvdata(dev, ioapic); | ||
78 | dev_info(&dev->dev, "%s at %pR, GSI %u\n", type, res, ioapic->gsi_base); | ||
79 | return 0; | ||
80 | |||
81 | exit_release: | ||
82 | pci_release_region(dev, 0); | ||
83 | exit_disable: | ||
84 | pci_disable_device(dev); | ||
85 | exit_free: | ||
86 | kfree(ioapic); | ||
87 | return -ENODEV; | ||
88 | } | ||
89 | |||
90 | static void ioapic_remove(struct pci_dev *dev) | ||
91 | { | ||
92 | struct ioapic *ioapic = pci_get_drvdata(dev); | ||
93 | |||
94 | acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base); | ||
95 | pci_release_region(dev, 0); | ||
96 | pci_disable_device(dev); | ||
97 | kfree(ioapic); | ||
98 | } | ||
99 | |||
100 | |||
101 | static struct pci_device_id ioapic_devices[] = { | ||
102 | { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | ||
103 | PCI_CLASS_SYSTEM_PIC_IOAPIC << 8, 0xffff00, }, | ||
104 | { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | ||
105 | PCI_CLASS_SYSTEM_PIC_IOXAPIC << 8, 0xffff00, }, | ||
106 | { } | ||
107 | }; | ||
108 | |||
109 | static struct pci_driver ioapic_driver = { | ||
110 | .name = "ioapic", | ||
111 | .id_table = ioapic_devices, | ||
112 | .probe = ioapic_probe, | ||
113 | .remove = __devexit_p(ioapic_remove), | ||
114 | }; | ||
115 | |||
116 | static int __init ioapic_init(void) | ||
117 | { | ||
118 | return pci_register_driver(&ioapic_driver); | ||
119 | } | ||
120 | |||
121 | static void __exit ioapic_exit(void) | ||
122 | { | ||
123 | pci_unregister_driver(&ioapic_driver); | ||
124 | } | ||
125 | |||
126 | module_init(ioapic_init); | ||
127 | module_exit(ioapic_exit); | ||
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index e03fe98f0619..ce6a3666b3d9 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
@@ -9,6 +9,7 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/pci.h> | 11 | #include <linux/pci.h> |
12 | #include <linux/slab.h> | ||
12 | #include <linux/mutex.h> | 13 | #include <linux/mutex.h> |
13 | #include <linux/string.h> | 14 | #include <linux/string.h> |
14 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
@@ -555,7 +556,7 @@ int pci_iov_init(struct pci_dev *dev) | |||
555 | { | 556 | { |
556 | int pos; | 557 | int pos; |
557 | 558 | ||
558 | if (!dev->is_pcie) | 559 | if (!pci_is_pcie(dev)) |
559 | return -ENODEV; | 560 | return -ENODEV; |
560 | 561 | ||
561 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV); | 562 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV); |
@@ -706,6 +707,21 @@ irqreturn_t pci_sriov_migration(struct pci_dev *dev) | |||
706 | } | 707 | } |
707 | EXPORT_SYMBOL_GPL(pci_sriov_migration); | 708 | EXPORT_SYMBOL_GPL(pci_sriov_migration); |
708 | 709 | ||
710 | /** | ||
711 | * pci_num_vf - return number of VFs associated with a PF device_release_driver | ||
712 | * @dev: the PCI device | ||
713 | * | ||
714 | * Returns number of VFs, or 0 if SR-IOV is not enabled. | ||
715 | */ | ||
716 | int pci_num_vf(struct pci_dev *dev) | ||
717 | { | ||
718 | if (!dev || !dev->is_physfn) | ||
719 | return 0; | ||
720 | else | ||
721 | return dev->sriov->nr_virtfn; | ||
722 | } | ||
723 | EXPORT_SYMBOL_GPL(pci_num_vf); | ||
724 | |||
709 | static int ats_alloc_one(struct pci_dev *dev, int ps) | 725 | static int ats_alloc_one(struct pci_dev *dev, int ps) |
710 | { | 726 | { |
711 | int pos; | 727 | int pos; |
diff --git a/drivers/pci/legacy.c b/drivers/pci/legacy.c deleted file mode 100644 index 871f65c15936..000000000000 --- a/drivers/pci/legacy.c +++ /dev/null | |||
@@ -1,34 +0,0 @@ | |||
1 | #include <linux/init.h> | ||
2 | #include <linux/pci.h> | ||
3 | #include <linux/module.h> | ||
4 | #include <linux/interrupt.h> | ||
5 | #include "pci.h" | ||
6 | |||
7 | /** | ||
8 | * pci_find_device - begin or continue searching for a PCI device by vendor/device id | ||
9 | * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids | ||
10 | * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids | ||
11 | * @from: Previous PCI device found in search, or %NULL for new search. | ||
12 | * | ||
13 | * Iterates through the list of known PCI devices. If a PCI device is found | ||
14 | * with a matching @vendor and @device, a pointer to its device structure is | ||
15 | * returned. Otherwise, %NULL is returned. | ||
16 | * A new search is initiated by passing %NULL as the @from argument. | ||
17 | * Otherwise if @from is not %NULL, searches continue from next device | ||
18 | * on the global list. | ||
19 | * | ||
20 | * NOTE: Do not use this function any more; use pci_get_device() instead, as | ||
21 | * the PCI device returned by this function can disappear at any moment in | ||
22 | * time. | ||
23 | */ | ||
24 | struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device, | ||
25 | struct pci_dev *from) | ||
26 | { | ||
27 | struct pci_dev *pdev; | ||
28 | |||
29 | pci_dev_get(from); | ||
30 | pdev = pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from); | ||
31 | pci_dev_put(pdev); | ||
32 | return pdev; | ||
33 | } | ||
34 | EXPORT_SYMBOL(pci_find_device); | ||
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index f9cf3173b23d..77b68eaf021e 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/smp.h> | 18 | #include <linux/smp.h> |
19 | #include <linux/errno.h> | 19 | #include <linux/errno.h> |
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/slab.h> | ||
21 | 22 | ||
22 | #include "pci.h" | 23 | #include "pci.h" |
23 | #include "msi.h" | 24 | #include "msi.h" |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 33317df47699..2e7a3bf13824 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -16,8 +16,144 @@ | |||
16 | #include <acpi/acpi_bus.h> | 16 | #include <acpi/acpi_bus.h> |
17 | 17 | ||
18 | #include <linux/pci-acpi.h> | 18 | #include <linux/pci-acpi.h> |
19 | #include <linux/pm_runtime.h> | ||
19 | #include "pci.h" | 20 | #include "pci.h" |
20 | 21 | ||
22 | static DEFINE_MUTEX(pci_acpi_pm_notify_mtx); | ||
23 | |||
24 | /** | ||
25 | * pci_acpi_wake_bus - Wake-up notification handler for root buses. | ||
26 | * @handle: ACPI handle of a device the notification is for. | ||
27 | * @event: Type of the signaled event. | ||
28 | * @context: PCI root bus to wake up devices on. | ||
29 | */ | ||
30 | static void pci_acpi_wake_bus(acpi_handle handle, u32 event, void *context) | ||
31 | { | ||
32 | struct pci_bus *pci_bus = context; | ||
33 | |||
34 | if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_bus) | ||
35 | pci_pme_wakeup_bus(pci_bus); | ||
36 | } | ||
37 | |||
38 | /** | ||
39 | * pci_acpi_wake_dev - Wake-up notification handler for PCI devices. | ||
40 | * @handle: ACPI handle of a device the notification is for. | ||
41 | * @event: Type of the signaled event. | ||
42 | * @context: PCI device object to wake up. | ||
43 | */ | ||
44 | static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) | ||
45 | { | ||
46 | struct pci_dev *pci_dev = context; | ||
47 | |||
48 | if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_dev) { | ||
49 | pci_check_pme_status(pci_dev); | ||
50 | pm_runtime_resume(&pci_dev->dev); | ||
51 | if (pci_dev->subordinate) | ||
52 | pci_pme_wakeup_bus(pci_dev->subordinate); | ||
53 | } | ||
54 | } | ||
55 | |||
56 | /** | ||
57 | * add_pm_notifier - Register PM notifier for given ACPI device. | ||
58 | * @dev: ACPI device to add the notifier for. | ||
59 | * @context: PCI device or bus to check for PME status if an event is signaled. | ||
60 | * | ||
61 | * NOTE: @dev need not be a run-wake or wake-up device to be a valid source of | ||
62 | * PM wake-up events. For example, wake-up events may be generated for bridges | ||
63 | * if one of the devices below the bridge is signaling PME, even if the bridge | ||
64 | * itself doesn't have a wake-up GPE associated with it. | ||
65 | */ | ||
66 | static acpi_status add_pm_notifier(struct acpi_device *dev, | ||
67 | acpi_notify_handler handler, | ||
68 | void *context) | ||
69 | { | ||
70 | acpi_status status = AE_ALREADY_EXISTS; | ||
71 | |||
72 | mutex_lock(&pci_acpi_pm_notify_mtx); | ||
73 | |||
74 | if (dev->wakeup.flags.notifier_present) | ||
75 | goto out; | ||
76 | |||
77 | status = acpi_install_notify_handler(dev->handle, | ||
78 | ACPI_SYSTEM_NOTIFY, | ||
79 | handler, context); | ||
80 | if (ACPI_FAILURE(status)) | ||
81 | goto out; | ||
82 | |||
83 | dev->wakeup.flags.notifier_present = true; | ||
84 | |||
85 | out: | ||
86 | mutex_unlock(&pci_acpi_pm_notify_mtx); | ||
87 | return status; | ||
88 | } | ||
89 | |||
90 | /** | ||
91 | * remove_pm_notifier - Unregister PM notifier from given ACPI device. | ||
92 | * @dev: ACPI device to remove the notifier from. | ||
93 | */ | ||
94 | static acpi_status remove_pm_notifier(struct acpi_device *dev, | ||
95 | acpi_notify_handler handler) | ||
96 | { | ||
97 | acpi_status status = AE_BAD_PARAMETER; | ||
98 | |||
99 | mutex_lock(&pci_acpi_pm_notify_mtx); | ||
100 | |||
101 | if (!dev->wakeup.flags.notifier_present) | ||
102 | goto out; | ||
103 | |||
104 | status = acpi_remove_notify_handler(dev->handle, | ||
105 | ACPI_SYSTEM_NOTIFY, | ||
106 | handler); | ||
107 | if (ACPI_FAILURE(status)) | ||
108 | goto out; | ||
109 | |||
110 | dev->wakeup.flags.notifier_present = false; | ||
111 | |||
112 | out: | ||
113 | mutex_unlock(&pci_acpi_pm_notify_mtx); | ||
114 | return status; | ||
115 | } | ||
116 | |||
117 | /** | ||
118 | * pci_acpi_add_bus_pm_notifier - Register PM notifier for given PCI bus. | ||
119 | * @dev: ACPI device to add the notifier for. | ||
120 | * @pci_bus: PCI bus to walk checking for PME status if an event is signaled. | ||
121 | */ | ||
122 | acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev, | ||
123 | struct pci_bus *pci_bus) | ||
124 | { | ||
125 | return add_pm_notifier(dev, pci_acpi_wake_bus, pci_bus); | ||
126 | } | ||
127 | |||
128 | /** | ||
129 | * pci_acpi_remove_bus_pm_notifier - Unregister PCI bus PM notifier. | ||
130 | * @dev: ACPI device to remove the notifier from. | ||
131 | */ | ||
132 | acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev) | ||
133 | { | ||
134 | return remove_pm_notifier(dev, pci_acpi_wake_bus); | ||
135 | } | ||
136 | |||
137 | /** | ||
138 | * pci_acpi_add_pm_notifier - Register PM notifier for given PCI device. | ||
139 | * @dev: ACPI device to add the notifier for. | ||
140 | * @pci_dev: PCI device to check for the PME status if an event is signaled. | ||
141 | */ | ||
142 | acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev, | ||
143 | struct pci_dev *pci_dev) | ||
144 | { | ||
145 | return add_pm_notifier(dev, pci_acpi_wake_dev, pci_dev); | ||
146 | } | ||
147 | |||
148 | /** | ||
149 | * pci_acpi_remove_pm_notifier - Unregister PCI device PM notifier. | ||
150 | * @dev: ACPI device to remove the notifier from. | ||
151 | */ | ||
152 | acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev) | ||
153 | { | ||
154 | return remove_pm_notifier(dev, pci_acpi_wake_dev); | ||
155 | } | ||
156 | |||
21 | /* | 157 | /* |
22 | * _SxD returns the D-state with the highest power | 158 | * _SxD returns the D-state with the highest power |
23 | * (lowest D-state number) supported in the S-state "x". | 159 | * (lowest D-state number) supported in the S-state "x". |
@@ -112,11 +248,7 @@ static bool acpi_pci_can_wakeup(struct pci_dev *dev) | |||
112 | static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable) | 248 | static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable) |
113 | { | 249 | { |
114 | while (bus->parent) { | 250 | while (bus->parent) { |
115 | struct pci_dev *bridge = bus->self; | 251 | if (!acpi_pm_device_sleep_wake(&bus->self->dev, enable)) |
116 | int ret; | ||
117 | |||
118 | ret = acpi_pm_device_sleep_wake(&bridge->dev, enable); | ||
119 | if (!ret || bridge->is_pcie) | ||
120 | return; | 252 | return; |
121 | bus = bus->parent; | 253 | bus = bus->parent; |
122 | } | 254 | } |
@@ -131,9 +263,81 @@ static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable) | |||
131 | if (acpi_pci_can_wakeup(dev)) | 263 | if (acpi_pci_can_wakeup(dev)) |
132 | return acpi_pm_device_sleep_wake(&dev->dev, enable); | 264 | return acpi_pm_device_sleep_wake(&dev->dev, enable); |
133 | 265 | ||
134 | if (!dev->is_pcie) | 266 | acpi_pci_propagate_wakeup_enable(dev->bus, enable); |
135 | acpi_pci_propagate_wakeup_enable(dev->bus, enable); | 267 | return 0; |
268 | } | ||
269 | |||
270 | /** | ||
271 | * acpi_dev_run_wake - Enable/disable wake-up for given device. | ||
272 | * @phys_dev: Device to enable/disable the platform to wake-up the system for. | ||
273 | * @enable: Whether enable or disable the wake-up functionality. | ||
274 | * | ||
275 | * Find the ACPI device object corresponding to @pci_dev and try to | ||
276 | * enable/disable the GPE associated with it. | ||
277 | */ | ||
278 | static int acpi_dev_run_wake(struct device *phys_dev, bool enable) | ||
279 | { | ||
280 | struct acpi_device *dev; | ||
281 | acpi_handle handle; | ||
282 | int error = -ENODEV; | ||
283 | |||
284 | if (!device_run_wake(phys_dev)) | ||
285 | return -EINVAL; | ||
286 | |||
287 | handle = DEVICE_ACPI_HANDLE(phys_dev); | ||
288 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &dev))) { | ||
289 | dev_dbg(phys_dev, "ACPI handle has no context in %s!\n", | ||
290 | __func__); | ||
291 | return -ENODEV; | ||
292 | } | ||
293 | |||
294 | if (enable) { | ||
295 | if (!dev->wakeup.run_wake_count++) { | ||
296 | acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0); | ||
297 | acpi_enable_gpe(dev->wakeup.gpe_device, | ||
298 | dev->wakeup.gpe_number, | ||
299 | ACPI_GPE_TYPE_RUNTIME); | ||
300 | } | ||
301 | } else if (dev->wakeup.run_wake_count > 0) { | ||
302 | if (!--dev->wakeup.run_wake_count) { | ||
303 | acpi_disable_gpe(dev->wakeup.gpe_device, | ||
304 | dev->wakeup.gpe_number, | ||
305 | ACPI_GPE_TYPE_RUNTIME); | ||
306 | acpi_disable_wakeup_device_power(dev); | ||
307 | } | ||
308 | } else { | ||
309 | error = -EALREADY; | ||
310 | } | ||
311 | |||
312 | return error; | ||
313 | } | ||
314 | |||
315 | static void acpi_pci_propagate_run_wake(struct pci_bus *bus, bool enable) | ||
316 | { | ||
317 | while (bus->parent) { | ||
318 | struct pci_dev *bridge = bus->self; | ||
319 | |||
320 | if (bridge->pme_interrupt) | ||
321 | return; | ||
322 | if (!acpi_dev_run_wake(&bridge->dev, enable)) | ||
323 | return; | ||
324 | bus = bus->parent; | ||
325 | } | ||
326 | |||
327 | /* We have reached the root bus. */ | ||
328 | if (bus->bridge) | ||
329 | acpi_dev_run_wake(bus->bridge, enable); | ||
330 | } | ||
331 | |||
332 | static int acpi_pci_run_wake(struct pci_dev *dev, bool enable) | ||
333 | { | ||
334 | if (dev->pme_interrupt) | ||
335 | return 0; | ||
336 | |||
337 | if (!acpi_dev_run_wake(&dev->dev, enable)) | ||
338 | return 0; | ||
136 | 339 | ||
340 | acpi_pci_propagate_run_wake(dev->bus, enable); | ||
137 | return 0; | 341 | return 0; |
138 | } | 342 | } |
139 | 343 | ||
@@ -143,13 +347,14 @@ static struct pci_platform_pm_ops acpi_pci_platform_pm = { | |||
143 | .choose_state = acpi_pci_choose_state, | 347 | .choose_state = acpi_pci_choose_state, |
144 | .can_wakeup = acpi_pci_can_wakeup, | 348 | .can_wakeup = acpi_pci_can_wakeup, |
145 | .sleep_wake = acpi_pci_sleep_wake, | 349 | .sleep_wake = acpi_pci_sleep_wake, |
350 | .run_wake = acpi_pci_run_wake, | ||
146 | }; | 351 | }; |
147 | 352 | ||
148 | /* ACPI bus type */ | 353 | /* ACPI bus type */ |
149 | static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) | 354 | static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) |
150 | { | 355 | { |
151 | struct pci_dev * pci_dev; | 356 | struct pci_dev * pci_dev; |
152 | acpi_integer addr; | 357 | u64 addr; |
153 | 358 | ||
154 | pci_dev = to_pci_dev(dev); | 359 | pci_dev = to_pci_dev(dev); |
155 | /* Please ref to ACPI spec for the syntax of _ADR */ | 360 | /* Please ref to ACPI spec for the syntax of _ADR */ |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index e5d47be3c6d7..f9a0aec3abcf 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
19 | #include <linux/cpu.h> | 19 | #include <linux/cpu.h> |
20 | #include <linux/pm_runtime.h> | ||
20 | #include "pci.h" | 21 | #include "pci.h" |
21 | 22 | ||
22 | struct pci_dynid { | 23 | struct pci_dynid { |
@@ -404,6 +405,35 @@ static void pci_device_shutdown(struct device *dev) | |||
404 | pci_msix_shutdown(pci_dev); | 405 | pci_msix_shutdown(pci_dev); |
405 | } | 406 | } |
406 | 407 | ||
408 | #ifdef CONFIG_PM_OPS | ||
409 | |||
410 | /* Auxiliary functions used for system resume and run-time resume. */ | ||
411 | |||
412 | /** | ||
413 | * pci_restore_standard_config - restore standard config registers of PCI device | ||
414 | * @pci_dev: PCI device to handle | ||
415 | */ | ||
416 | static int pci_restore_standard_config(struct pci_dev *pci_dev) | ||
417 | { | ||
418 | pci_update_current_state(pci_dev, PCI_UNKNOWN); | ||
419 | |||
420 | if (pci_dev->current_state != PCI_D0) { | ||
421 | int error = pci_set_power_state(pci_dev, PCI_D0); | ||
422 | if (error) | ||
423 | return error; | ||
424 | } | ||
425 | |||
426 | return pci_restore_state(pci_dev); | ||
427 | } | ||
428 | |||
429 | static void pci_pm_default_resume_early(struct pci_dev *pci_dev) | ||
430 | { | ||
431 | pci_restore_standard_config(pci_dev); | ||
432 | pci_fixup_device(pci_fixup_resume_early, pci_dev); | ||
433 | } | ||
434 | |||
435 | #endif | ||
436 | |||
407 | #ifdef CONFIG_PM_SLEEP | 437 | #ifdef CONFIG_PM_SLEEP |
408 | 438 | ||
409 | /* | 439 | /* |
@@ -520,29 +550,6 @@ static int pci_legacy_resume(struct device *dev) | |||
520 | 550 | ||
521 | /* Auxiliary functions used by the new power management framework */ | 551 | /* Auxiliary functions used by the new power management framework */ |
522 | 552 | ||
523 | /** | ||
524 | * pci_restore_standard_config - restore standard config registers of PCI device | ||
525 | * @pci_dev: PCI device to handle | ||
526 | */ | ||
527 | static int pci_restore_standard_config(struct pci_dev *pci_dev) | ||
528 | { | ||
529 | pci_update_current_state(pci_dev, PCI_UNKNOWN); | ||
530 | |||
531 | if (pci_dev->current_state != PCI_D0) { | ||
532 | int error = pci_set_power_state(pci_dev, PCI_D0); | ||
533 | if (error) | ||
534 | return error; | ||
535 | } | ||
536 | |||
537 | return pci_restore_state(pci_dev); | ||
538 | } | ||
539 | |||
540 | static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev) | ||
541 | { | ||
542 | pci_restore_standard_config(pci_dev); | ||
543 | pci_fixup_device(pci_fixup_resume_early, pci_dev); | ||
544 | } | ||
545 | |||
546 | static void pci_pm_default_resume(struct pci_dev *pci_dev) | 553 | static void pci_pm_default_resume(struct pci_dev *pci_dev) |
547 | { | 554 | { |
548 | pci_fixup_device(pci_fixup_resume, pci_dev); | 555 | pci_fixup_device(pci_fixup_resume, pci_dev); |
@@ -581,6 +588,17 @@ static int pci_pm_prepare(struct device *dev) | |||
581 | struct device_driver *drv = dev->driver; | 588 | struct device_driver *drv = dev->driver; |
582 | int error = 0; | 589 | int error = 0; |
583 | 590 | ||
591 | /* | ||
592 | * PCI devices suspended at run time need to be resumed at this | ||
593 | * point, because in general it is necessary to reconfigure them for | ||
594 | * system suspend. Namely, if the device is supposed to wake up the | ||
595 | * system from the sleep state, we may need to reconfigure it for this | ||
596 | * purpose. In turn, if the device is not supposed to wake up the | ||
597 | * system from the sleep state, we'll have to prevent it from signaling | ||
598 | * wake-up. | ||
599 | */ | ||
600 | pm_runtime_resume(dev); | ||
601 | |||
584 | if (drv && drv->pm && drv->pm->prepare) | 602 | if (drv && drv->pm && drv->pm->prepare) |
585 | error = drv->pm->prepare(dev); | 603 | error = drv->pm->prepare(dev); |
586 | 604 | ||
@@ -595,6 +613,13 @@ static void pci_pm_complete(struct device *dev) | |||
595 | drv->pm->complete(dev); | 613 | drv->pm->complete(dev); |
596 | } | 614 | } |
597 | 615 | ||
616 | #else /* !CONFIG_PM_SLEEP */ | ||
617 | |||
618 | #define pci_pm_prepare NULL | ||
619 | #define pci_pm_complete NULL | ||
620 | |||
621 | #endif /* !CONFIG_PM_SLEEP */ | ||
622 | |||
598 | #ifdef CONFIG_SUSPEND | 623 | #ifdef CONFIG_SUSPEND |
599 | 624 | ||
600 | static int pci_pm_suspend(struct device *dev) | 625 | static int pci_pm_suspend(struct device *dev) |
@@ -681,7 +706,7 @@ static int pci_pm_resume_noirq(struct device *dev) | |||
681 | struct device_driver *drv = dev->driver; | 706 | struct device_driver *drv = dev->driver; |
682 | int error = 0; | 707 | int error = 0; |
683 | 708 | ||
684 | pci_pm_default_resume_noirq(pci_dev); | 709 | pci_pm_default_resume_early(pci_dev); |
685 | 710 | ||
686 | if (pci_has_legacy_pm_support(pci_dev)) | 711 | if (pci_has_legacy_pm_support(pci_dev)) |
687 | return pci_legacy_resume_early(dev); | 712 | return pci_legacy_resume_early(dev); |
@@ -879,7 +904,7 @@ static int pci_pm_restore_noirq(struct device *dev) | |||
879 | struct device_driver *drv = dev->driver; | 904 | struct device_driver *drv = dev->driver; |
880 | int error = 0; | 905 | int error = 0; |
881 | 906 | ||
882 | pci_pm_default_resume_noirq(pci_dev); | 907 | pci_pm_default_resume_early(pci_dev); |
883 | 908 | ||
884 | if (pci_has_legacy_pm_support(pci_dev)) | 909 | if (pci_has_legacy_pm_support(pci_dev)) |
885 | return pci_legacy_resume_early(dev); | 910 | return pci_legacy_resume_early(dev); |
@@ -931,6 +956,84 @@ static int pci_pm_restore(struct device *dev) | |||
931 | 956 | ||
932 | #endif /* !CONFIG_HIBERNATION */ | 957 | #endif /* !CONFIG_HIBERNATION */ |
933 | 958 | ||
959 | #ifdef CONFIG_PM_RUNTIME | ||
960 | |||
961 | static int pci_pm_runtime_suspend(struct device *dev) | ||
962 | { | ||
963 | struct pci_dev *pci_dev = to_pci_dev(dev); | ||
964 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | ||
965 | pci_power_t prev = pci_dev->current_state; | ||
966 | int error; | ||
967 | |||
968 | if (!pm || !pm->runtime_suspend) | ||
969 | return -ENOSYS; | ||
970 | |||
971 | error = pm->runtime_suspend(dev); | ||
972 | suspend_report_result(pm->runtime_suspend, error); | ||
973 | if (error) | ||
974 | return error; | ||
975 | |||
976 | pci_fixup_device(pci_fixup_suspend, pci_dev); | ||
977 | |||
978 | if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0 | ||
979 | && pci_dev->current_state != PCI_UNKNOWN) { | ||
980 | WARN_ONCE(pci_dev->current_state != prev, | ||
981 | "PCI PM: State of device not saved by %pF\n", | ||
982 | pm->runtime_suspend); | ||
983 | return 0; | ||
984 | } | ||
985 | |||
986 | if (!pci_dev->state_saved) | ||
987 | pci_save_state(pci_dev); | ||
988 | |||
989 | pci_finish_runtime_suspend(pci_dev); | ||
990 | |||
991 | return 0; | ||
992 | } | ||
993 | |||
994 | static int pci_pm_runtime_resume(struct device *dev) | ||
995 | { | ||
996 | struct pci_dev *pci_dev = to_pci_dev(dev); | ||
997 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | ||
998 | |||
999 | if (!pm || !pm->runtime_resume) | ||
1000 | return -ENOSYS; | ||
1001 | |||
1002 | pci_pm_default_resume_early(pci_dev); | ||
1003 | __pci_enable_wake(pci_dev, PCI_D0, true, false); | ||
1004 | pci_fixup_device(pci_fixup_resume, pci_dev); | ||
1005 | |||
1006 | return pm->runtime_resume(dev); | ||
1007 | } | ||
1008 | |||
1009 | static int pci_pm_runtime_idle(struct device *dev) | ||
1010 | { | ||
1011 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | ||
1012 | |||
1013 | if (!pm) | ||
1014 | return -ENOSYS; | ||
1015 | |||
1016 | if (pm->runtime_idle) { | ||
1017 | int ret = pm->runtime_idle(dev); | ||
1018 | if (ret) | ||
1019 | return ret; | ||
1020 | } | ||
1021 | |||
1022 | pm_runtime_suspend(dev); | ||
1023 | |||
1024 | return 0; | ||
1025 | } | ||
1026 | |||
1027 | #else /* !CONFIG_PM_RUNTIME */ | ||
1028 | |||
1029 | #define pci_pm_runtime_suspend NULL | ||
1030 | #define pci_pm_runtime_resume NULL | ||
1031 | #define pci_pm_runtime_idle NULL | ||
1032 | |||
1033 | #endif /* !CONFIG_PM_RUNTIME */ | ||
1034 | |||
1035 | #ifdef CONFIG_PM_OPS | ||
1036 | |||
934 | const struct dev_pm_ops pci_dev_pm_ops = { | 1037 | const struct dev_pm_ops pci_dev_pm_ops = { |
935 | .prepare = pci_pm_prepare, | 1038 | .prepare = pci_pm_prepare, |
936 | .complete = pci_pm_complete, | 1039 | .complete = pci_pm_complete, |
@@ -946,15 +1049,18 @@ const struct dev_pm_ops pci_dev_pm_ops = { | |||
946 | .thaw_noirq = pci_pm_thaw_noirq, | 1049 | .thaw_noirq = pci_pm_thaw_noirq, |
947 | .poweroff_noirq = pci_pm_poweroff_noirq, | 1050 | .poweroff_noirq = pci_pm_poweroff_noirq, |
948 | .restore_noirq = pci_pm_restore_noirq, | 1051 | .restore_noirq = pci_pm_restore_noirq, |
1052 | .runtime_suspend = pci_pm_runtime_suspend, | ||
1053 | .runtime_resume = pci_pm_runtime_resume, | ||
1054 | .runtime_idle = pci_pm_runtime_idle, | ||
949 | }; | 1055 | }; |
950 | 1056 | ||
951 | #define PCI_PM_OPS_PTR (&pci_dev_pm_ops) | 1057 | #define PCI_PM_OPS_PTR (&pci_dev_pm_ops) |
952 | 1058 | ||
953 | #else /* !CONFIG_PM_SLEEP */ | 1059 | #else /* !COMFIG_PM_OPS */ |
954 | 1060 | ||
955 | #define PCI_PM_OPS_PTR NULL | 1061 | #define PCI_PM_OPS_PTR NULL |
956 | 1062 | ||
957 | #endif /* !CONFIG_PM_SLEEP */ | 1063 | #endif /* !COMFIG_PM_OPS */ |
958 | 1064 | ||
959 | /** | 1065 | /** |
960 | * __pci_register_driver - register a new pci driver | 1066 | * __pci_register_driver - register a new pci driver |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 0f6382f090ee..fad93983bfed 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
24 | #include <linux/capability.h> | 24 | #include <linux/capability.h> |
25 | #include <linux/pci-aspm.h> | 25 | #include <linux/pci-aspm.h> |
26 | #include <linux/slab.h> | ||
26 | #include "pci.h" | 27 | #include "pci.h" |
27 | 28 | ||
28 | static int sysfs_initialized; /* = 0 */ | 29 | static int sysfs_initialized; /* = 0 */ |
@@ -74,7 +75,12 @@ static ssize_t local_cpus_show(struct device *dev, | |||
74 | const struct cpumask *mask; | 75 | const struct cpumask *mask; |
75 | int len; | 76 | int len; |
76 | 77 | ||
78 | #ifdef CONFIG_NUMA | ||
79 | mask = (dev_to_node(dev) == -1) ? cpu_online_mask : | ||
80 | cpumask_of_node(dev_to_node(dev)); | ||
81 | #else | ||
77 | mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); | 82 | mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); |
83 | #endif | ||
78 | len = cpumask_scnprintf(buf, PAGE_SIZE-2, mask); | 84 | len = cpumask_scnprintf(buf, PAGE_SIZE-2, mask); |
79 | buf[len++] = '\n'; | 85 | buf[len++] = '\n'; |
80 | buf[len] = '\0'; | 86 | buf[len] = '\0'; |
@@ -88,7 +94,12 @@ static ssize_t local_cpulist_show(struct device *dev, | |||
88 | const struct cpumask *mask; | 94 | const struct cpumask *mask; |
89 | int len; | 95 | int len; |
90 | 96 | ||
97 | #ifdef CONFIG_NUMA | ||
98 | mask = (dev_to_node(dev) == -1) ? cpu_online_mask : | ||
99 | cpumask_of_node(dev_to_node(dev)); | ||
100 | #else | ||
91 | mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); | 101 | mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); |
102 | #endif | ||
92 | len = cpulist_scnprintf(buf, PAGE_SIZE-2, mask); | 103 | len = cpulist_scnprintf(buf, PAGE_SIZE-2, mask); |
93 | buf[len++] = '\n'; | 104 | buf[len++] = '\n'; |
94 | buf[len] = '\0'; | 105 | buf[len] = '\0'; |
@@ -176,6 +187,21 @@ numa_node_show(struct device *dev, struct device_attribute *attr, char *buf) | |||
176 | #endif | 187 | #endif |
177 | 188 | ||
178 | static ssize_t | 189 | static ssize_t |
190 | dma_mask_bits_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
191 | { | ||
192 | struct pci_dev *pdev = to_pci_dev(dev); | ||
193 | |||
194 | return sprintf (buf, "%d\n", fls64(pdev->dma_mask)); | ||
195 | } | ||
196 | |||
197 | static ssize_t | ||
198 | consistent_dma_mask_bits_show(struct device *dev, struct device_attribute *attr, | ||
199 | char *buf) | ||
200 | { | ||
201 | return sprintf (buf, "%d\n", fls64(dev->coherent_dma_mask)); | ||
202 | } | ||
203 | |||
204 | static ssize_t | ||
179 | msi_bus_show(struct device *dev, struct device_attribute *attr, char *buf) | 205 | msi_bus_show(struct device *dev, struct device_attribute *attr, char *buf) |
180 | { | 206 | { |
181 | struct pci_dev *pdev = to_pci_dev(dev); | 207 | struct pci_dev *pdev = to_pci_dev(dev); |
@@ -306,6 +332,8 @@ struct device_attribute pci_dev_attrs[] = { | |||
306 | #ifdef CONFIG_NUMA | 332 | #ifdef CONFIG_NUMA |
307 | __ATTR_RO(numa_node), | 333 | __ATTR_RO(numa_node), |
308 | #endif | 334 | #endif |
335 | __ATTR_RO(dma_mask_bits), | ||
336 | __ATTR_RO(consistent_dma_mask_bits), | ||
309 | __ATTR(enable, 0600, is_enabled_show, is_enabled_store), | 337 | __ATTR(enable, 0600, is_enabled_show, is_enabled_store), |
310 | __ATTR(broken_parity_status,(S_IRUGO|S_IWUSR), | 338 | __ATTR(broken_parity_status,(S_IRUGO|S_IWUSR), |
311 | broken_parity_status_show,broken_parity_status_store), | 339 | broken_parity_status_show,broken_parity_status_store), |
@@ -615,6 +643,7 @@ void pci_create_legacy_files(struct pci_bus *b) | |||
615 | if (!b->legacy_io) | 643 | if (!b->legacy_io) |
616 | goto kzalloc_err; | 644 | goto kzalloc_err; |
617 | 645 | ||
646 | sysfs_bin_attr_init(b->legacy_io); | ||
618 | b->legacy_io->attr.name = "legacy_io"; | 647 | b->legacy_io->attr.name = "legacy_io"; |
619 | b->legacy_io->size = 0xffff; | 648 | b->legacy_io->size = 0xffff; |
620 | b->legacy_io->attr.mode = S_IRUSR | S_IWUSR; | 649 | b->legacy_io->attr.mode = S_IRUSR | S_IWUSR; |
@@ -628,6 +657,7 @@ void pci_create_legacy_files(struct pci_bus *b) | |||
628 | 657 | ||
629 | /* Allocated above after the legacy_io struct */ | 658 | /* Allocated above after the legacy_io struct */ |
630 | b->legacy_mem = b->legacy_io + 1; | 659 | b->legacy_mem = b->legacy_io + 1; |
660 | sysfs_bin_attr_init(b->legacy_mem); | ||
631 | b->legacy_mem->attr.name = "legacy_mem"; | 661 | b->legacy_mem->attr.name = "legacy_mem"; |
632 | b->legacy_mem->size = 1024*1024; | 662 | b->legacy_mem->size = 1024*1024; |
633 | b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR; | 663 | b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR; |
@@ -773,6 +803,7 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine) | |||
773 | if (res_attr) { | 803 | if (res_attr) { |
774 | char *res_attr_name = (char *)(res_attr + 1); | 804 | char *res_attr_name = (char *)(res_attr + 1); |
775 | 805 | ||
806 | sysfs_bin_attr_init(res_attr); | ||
776 | if (write_combine) { | 807 | if (write_combine) { |
777 | pdev->res_attr_wc[num] = res_attr; | 808 | pdev->res_attr_wc[num] = res_attr; |
778 | sprintf(res_attr_name, "resource%d_wc", num); | 809 | sprintf(res_attr_name, "resource%d_wc", num); |
@@ -945,6 +976,7 @@ static int pci_create_capabilities_sysfs(struct pci_dev *dev) | |||
945 | if (!attr) | 976 | if (!attr) |
946 | return -ENOMEM; | 977 | return -ENOMEM; |
947 | 978 | ||
979 | sysfs_bin_attr_init(attr); | ||
948 | attr->size = dev->vpd->len; | 980 | attr->size = dev->vpd->len; |
949 | attr->attr.name = "vpd"; | 981 | attr->attr.name = "vpd"; |
950 | attr->attr.mode = S_IRUSR | S_IWUSR; | 982 | attr->attr.mode = S_IRUSR | S_IWUSR; |
@@ -1011,6 +1043,7 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) | |||
1011 | retval = -ENOMEM; | 1043 | retval = -ENOMEM; |
1012 | goto err_resource_files; | 1044 | goto err_resource_files; |
1013 | } | 1045 | } |
1046 | sysfs_bin_attr_init(attr); | ||
1014 | attr->size = rom_size; | 1047 | attr->size = rom_size; |
1015 | attr->attr.name = "rom"; | 1048 | attr->attr.name = "rom"; |
1016 | attr->attr.mode = S_IRUSR; | 1049 | attr->attr.mode = S_IRUSR; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 4e4c295a049f..37499127c801 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/pci.h> | 13 | #include <linux/pci.h> |
14 | #include <linux/pm.h> | 14 | #include <linux/pm.h> |
15 | #include <linux/slab.h> | ||
15 | #include <linux/module.h> | 16 | #include <linux/module.h> |
16 | #include <linux/spinlock.h> | 17 | #include <linux/spinlock.h> |
17 | #include <linux/string.h> | 18 | #include <linux/string.h> |
@@ -19,8 +20,8 @@ | |||
19 | #include <linux/pci-aspm.h> | 20 | #include <linux/pci-aspm.h> |
20 | #include <linux/pm_wakeup.h> | 21 | #include <linux/pm_wakeup.h> |
21 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
22 | #include <asm/dma.h> /* isa_dma_bridge_buggy */ | ||
23 | #include <linux/device.h> | 23 | #include <linux/device.h> |
24 | #include <linux/pm_runtime.h> | ||
24 | #include <asm/setup.h> | 25 | #include <asm/setup.h> |
25 | #include "pci.h" | 26 | #include "pci.h" |
26 | 27 | ||
@@ -29,7 +30,23 @@ const char *pci_power_names[] = { | |||
29 | }; | 30 | }; |
30 | EXPORT_SYMBOL_GPL(pci_power_names); | 31 | EXPORT_SYMBOL_GPL(pci_power_names); |
31 | 32 | ||
32 | unsigned int pci_pm_d3_delay = PCI_PM_D3_WAIT; | 33 | int isa_dma_bridge_buggy; |
34 | EXPORT_SYMBOL(isa_dma_bridge_buggy); | ||
35 | |||
36 | int pci_pci_problems; | ||
37 | EXPORT_SYMBOL(pci_pci_problems); | ||
38 | |||
39 | unsigned int pci_pm_d3_delay; | ||
40 | |||
41 | static void pci_dev_d3_sleep(struct pci_dev *dev) | ||
42 | { | ||
43 | unsigned int delay = dev->d3_delay; | ||
44 | |||
45 | if (delay < pci_pm_d3_delay) | ||
46 | delay = pci_pm_d3_delay; | ||
47 | |||
48 | msleep(delay); | ||
49 | } | ||
33 | 50 | ||
34 | #ifdef CONFIG_PCI_DOMAINS | 51 | #ifdef CONFIG_PCI_DOMAINS |
35 | int pci_domains_supported = 1; | 52 | int pci_domains_supported = 1; |
@@ -47,6 +64,15 @@ unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE; | |||
47 | unsigned long pci_hotplug_io_size = DEFAULT_HOTPLUG_IO_SIZE; | 64 | unsigned long pci_hotplug_io_size = DEFAULT_HOTPLUG_IO_SIZE; |
48 | unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE; | 65 | unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE; |
49 | 66 | ||
67 | /* | ||
68 | * The default CLS is used if arch didn't set CLS explicitly and not | ||
69 | * all pci devices agree on the same value. Arch can override either | ||
70 | * the dfl or actual value as it sees fit. Don't forget this is | ||
71 | * measured in 32-bit words, not bytes. | ||
72 | */ | ||
73 | u8 pci_dfl_cache_line_size __devinitdata = L1_CACHE_BYTES >> 2; | ||
74 | u8 pci_cache_line_size; | ||
75 | |||
50 | /** | 76 | /** |
51 | * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children | 77 | * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children |
52 | * @bus: pointer to PCI bus structure to search | 78 | * @bus: pointer to PCI bus structure to search |
@@ -278,6 +304,49 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap) | |||
278 | } | 304 | } |
279 | EXPORT_SYMBOL_GPL(pci_find_ext_capability); | 305 | EXPORT_SYMBOL_GPL(pci_find_ext_capability); |
280 | 306 | ||
307 | /** | ||
308 | * pci_bus_find_ext_capability - find an extended capability | ||
309 | * @bus: the PCI bus to query | ||
310 | * @devfn: PCI device to query | ||
311 | * @cap: capability code | ||
312 | * | ||
313 | * Like pci_find_ext_capability() but works for pci devices that do not have a | ||
314 | * pci_dev structure set up yet. | ||
315 | * | ||
316 | * Returns the address of the requested capability structure within the | ||
317 | * device's PCI configuration space or 0 in case the device does not | ||
318 | * support it. | ||
319 | */ | ||
320 | int pci_bus_find_ext_capability(struct pci_bus *bus, unsigned int devfn, | ||
321 | int cap) | ||
322 | { | ||
323 | u32 header; | ||
324 | int ttl; | ||
325 | int pos = PCI_CFG_SPACE_SIZE; | ||
326 | |||
327 | /* minimum 8 bytes per capability */ | ||
328 | ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8; | ||
329 | |||
330 | if (!pci_bus_read_config_dword(bus, devfn, pos, &header)) | ||
331 | return 0; | ||
332 | if (header == 0xffffffff || header == 0) | ||
333 | return 0; | ||
334 | |||
335 | while (ttl-- > 0) { | ||
336 | if (PCI_EXT_CAP_ID(header) == cap) | ||
337 | return pos; | ||
338 | |||
339 | pos = PCI_EXT_CAP_NEXT(header); | ||
340 | if (pos < PCI_CFG_SPACE_SIZE) | ||
341 | break; | ||
342 | |||
343 | if (!pci_bus_read_config_dword(bus, devfn, pos, &header)) | ||
344 | break; | ||
345 | } | ||
346 | |||
347 | return 0; | ||
348 | } | ||
349 | |||
281 | static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap) | 350 | static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap) |
282 | { | 351 | { |
283 | int rc, ttl = PCI_FIND_CAP_TTL; | 352 | int rc, ttl = PCI_FIND_CAP_TTL; |
@@ -361,10 +430,9 @@ pci_find_parent_resource(const struct pci_dev *dev, struct resource *res) | |||
361 | { | 430 | { |
362 | const struct pci_bus *bus = dev->bus; | 431 | const struct pci_bus *bus = dev->bus; |
363 | int i; | 432 | int i; |
364 | struct resource *best = NULL; | 433 | struct resource *best = NULL, *r; |
365 | 434 | ||
366 | for(i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { | 435 | pci_bus_for_each_resource(bus, r, i) { |
367 | struct resource *r = bus->resource[i]; | ||
368 | if (!r) | 436 | if (!r) |
369 | continue; | 437 | continue; |
370 | if (res->start && !(res->start >= r->start && res->end <= r->end)) | 438 | if (res->start && !(res->start >= r->start && res->end <= r->end)) |
@@ -373,8 +441,12 @@ pci_find_parent_resource(const struct pci_dev *dev, struct resource *res) | |||
373 | continue; /* Wrong type */ | 441 | continue; /* Wrong type */ |
374 | if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH)) | 442 | if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH)) |
375 | return r; /* Exact match */ | 443 | return r; /* Exact match */ |
376 | if ((res->flags & IORESOURCE_PREFETCH) && !(r->flags & IORESOURCE_PREFETCH)) | 444 | /* We can't insert a non-prefetch resource inside a prefetchable parent .. */ |
377 | best = r; /* Approximating prefetchable by non-prefetchable */ | 445 | if (r->flags & IORESOURCE_PREFETCH) |
446 | continue; | ||
447 | /* .. but we can put a prefetchable resource inside a non-prefetchable one */ | ||
448 | if (!best) | ||
449 | best = r; | ||
378 | } | 450 | } |
379 | return best; | 451 | return best; |
380 | } | 452 | } |
@@ -434,6 +506,12 @@ static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable) | |||
434 | pci_platform_pm->sleep_wake(dev, enable) : -ENODEV; | 506 | pci_platform_pm->sleep_wake(dev, enable) : -ENODEV; |
435 | } | 507 | } |
436 | 508 | ||
509 | static inline int platform_pci_run_wake(struct pci_dev *dev, bool enable) | ||
510 | { | ||
511 | return pci_platform_pm ? | ||
512 | pci_platform_pm->run_wake(dev, enable) : -ENODEV; | ||
513 | } | ||
514 | |||
437 | /** | 515 | /** |
438 | * pci_raw_set_power_state - Use PCI PM registers to set the power state of | 516 | * pci_raw_set_power_state - Use PCI PM registers to set the power state of |
439 | * given PCI device | 517 | * given PCI device |
@@ -509,7 +587,7 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
509 | /* Mandatory power management transition delays */ | 587 | /* Mandatory power management transition delays */ |
510 | /* see PCI PM 1.1 5.6.1 table 18 */ | 588 | /* see PCI PM 1.1 5.6.1 table 18 */ |
511 | if (state == PCI_D3hot || dev->current_state == PCI_D3hot) | 589 | if (state == PCI_D3hot || dev->current_state == PCI_D3hot) |
512 | msleep(pci_pm_d3_delay); | 590 | pci_dev_d3_sleep(dev); |
513 | else if (state == PCI_D2 || dev->current_state == PCI_D2) | 591 | else if (state == PCI_D2 || dev->current_state == PCI_D2) |
514 | udelay(PCI_PM_D2_DELAY); | 592 | udelay(PCI_PM_D2_DELAY); |
515 | 593 | ||
@@ -601,7 +679,7 @@ static void __pci_start_power_transition(struct pci_dev *dev, pci_power_t state) | |||
601 | */ | 679 | */ |
602 | int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state) | 680 | int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state) |
603 | { | 681 | { |
604 | return state > PCI_D0 ? | 682 | return state >= PCI_D0 ? |
605 | pci_platform_power_transition(dev, state) : -EINVAL; | 683 | pci_platform_power_transition(dev, state) : -EINVAL; |
606 | } | 684 | } |
607 | EXPORT_SYMBOL_GPL(__pci_complete_power_transition); | 685 | EXPORT_SYMBOL_GPL(__pci_complete_power_transition); |
@@ -638,10 +716,6 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
638 | */ | 716 | */ |
639 | return 0; | 717 | return 0; |
640 | 718 | ||
641 | /* Check if we're already there */ | ||
642 | if (dev->current_state == state) | ||
643 | return 0; | ||
644 | |||
645 | __pci_start_power_transition(dev, state); | 719 | __pci_start_power_transition(dev, state); |
646 | 720 | ||
647 | /* This device is quirked not to be put into D3, so | 721 | /* This device is quirked not to be put into D3, so |
@@ -728,8 +802,8 @@ static int pci_save_pcie_state(struct pci_dev *dev) | |||
728 | u16 *cap; | 802 | u16 *cap; |
729 | u16 flags; | 803 | u16 flags; |
730 | 804 | ||
731 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 805 | pos = pci_pcie_cap(dev); |
732 | if (pos <= 0) | 806 | if (!pos) |
733 | return 0; | 807 | return 0; |
734 | 808 | ||
735 | save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); | 809 | save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); |
@@ -837,7 +911,7 @@ pci_save_state(struct pci_dev *dev) | |||
837 | int i; | 911 | int i; |
838 | /* XXX: 100% dword access ok here? */ | 912 | /* XXX: 100% dword access ok here? */ |
839 | for (i = 0; i < 16; i++) | 913 | for (i = 0; i < 16; i++) |
840 | pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]); | 914 | pci_read_config_dword(dev, i * 4, &dev->saved_config_space[i]); |
841 | dev->state_saved = true; | 915 | dev->state_saved = true; |
842 | if ((i = pci_save_pcie_state(dev)) != 0) | 916 | if ((i = pci_save_pcie_state(dev)) != 0) |
843 | return i; | 917 | return i; |
@@ -1140,11 +1214,11 @@ pci_disable_device(struct pci_dev *dev) | |||
1140 | 1214 | ||
1141 | /** | 1215 | /** |
1142 | * pcibios_set_pcie_reset_state - set reset state for device dev | 1216 | * pcibios_set_pcie_reset_state - set reset state for device dev |
1143 | * @dev: the PCI-E device reset | 1217 | * @dev: the PCIe device reset |
1144 | * @state: Reset state to enter into | 1218 | * @state: Reset state to enter into |
1145 | * | 1219 | * |
1146 | * | 1220 | * |
1147 | * Sets the PCI-E reset state for the device. This is the default | 1221 | * Sets the PCIe reset state for the device. This is the default |
1148 | * implementation. Architecture implementations can override this. | 1222 | * implementation. Architecture implementations can override this. |
1149 | */ | 1223 | */ |
1150 | int __attribute__ ((weak)) pcibios_set_pcie_reset_state(struct pci_dev *dev, | 1224 | int __attribute__ ((weak)) pcibios_set_pcie_reset_state(struct pci_dev *dev, |
@@ -1155,7 +1229,7 @@ int __attribute__ ((weak)) pcibios_set_pcie_reset_state(struct pci_dev *dev, | |||
1155 | 1229 | ||
1156 | /** | 1230 | /** |
1157 | * pci_set_pcie_reset_state - set reset state for device dev | 1231 | * pci_set_pcie_reset_state - set reset state for device dev |
1158 | * @dev: the PCI-E device reset | 1232 | * @dev: the PCIe device reset |
1159 | * @state: Reset state to enter into | 1233 | * @state: Reset state to enter into |
1160 | * | 1234 | * |
1161 | * | 1235 | * |
@@ -1167,6 +1241,66 @@ int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state) | |||
1167 | } | 1241 | } |
1168 | 1242 | ||
1169 | /** | 1243 | /** |
1244 | * pci_check_pme_status - Check if given device has generated PME. | ||
1245 | * @dev: Device to check. | ||
1246 | * | ||
1247 | * Check the PME status of the device and if set, clear it and clear PME enable | ||
1248 | * (if set). Return 'true' if PME status and PME enable were both set or | ||
1249 | * 'false' otherwise. | ||
1250 | */ | ||
1251 | bool pci_check_pme_status(struct pci_dev *dev) | ||
1252 | { | ||
1253 | int pmcsr_pos; | ||
1254 | u16 pmcsr; | ||
1255 | bool ret = false; | ||
1256 | |||
1257 | if (!dev->pm_cap) | ||
1258 | return false; | ||
1259 | |||
1260 | pmcsr_pos = dev->pm_cap + PCI_PM_CTRL; | ||
1261 | pci_read_config_word(dev, pmcsr_pos, &pmcsr); | ||
1262 | if (!(pmcsr & PCI_PM_CTRL_PME_STATUS)) | ||
1263 | return false; | ||
1264 | |||
1265 | /* Clear PME status. */ | ||
1266 | pmcsr |= PCI_PM_CTRL_PME_STATUS; | ||
1267 | if (pmcsr & PCI_PM_CTRL_PME_ENABLE) { | ||
1268 | /* Disable PME to avoid interrupt flood. */ | ||
1269 | pmcsr &= ~PCI_PM_CTRL_PME_ENABLE; | ||
1270 | ret = true; | ||
1271 | } | ||
1272 | |||
1273 | pci_write_config_word(dev, pmcsr_pos, pmcsr); | ||
1274 | |||
1275 | return ret; | ||
1276 | } | ||
1277 | |||
1278 | /** | ||
1279 | * pci_pme_wakeup - Wake up a PCI device if its PME Status bit is set. | ||
1280 | * @dev: Device to handle. | ||
1281 | * @ign: Ignored. | ||
1282 | * | ||
1283 | * Check if @dev has generated PME and queue a resume request for it in that | ||
1284 | * case. | ||
1285 | */ | ||
1286 | static int pci_pme_wakeup(struct pci_dev *dev, void *ign) | ||
1287 | { | ||
1288 | if (pci_check_pme_status(dev)) | ||
1289 | pm_request_resume(&dev->dev); | ||
1290 | return 0; | ||
1291 | } | ||
1292 | |||
1293 | /** | ||
1294 | * pci_pme_wakeup_bus - Walk given bus and wake up devices on it, if necessary. | ||
1295 | * @bus: Top bus of the subtree to walk. | ||
1296 | */ | ||
1297 | void pci_pme_wakeup_bus(struct pci_bus *bus) | ||
1298 | { | ||
1299 | if (bus) | ||
1300 | pci_walk_bus(bus, pci_pme_wakeup, NULL); | ||
1301 | } | ||
1302 | |||
1303 | /** | ||
1170 | * pci_pme_capable - check the capability of PCI device to generate PME# | 1304 | * pci_pme_capable - check the capability of PCI device to generate PME# |
1171 | * @dev: PCI device to handle. | 1305 | * @dev: PCI device to handle. |
1172 | * @state: PCI state from which device will issue PME#. | 1306 | * @state: PCI state from which device will issue PME#. |
@@ -1202,14 +1336,15 @@ void pci_pme_active(struct pci_dev *dev, bool enable) | |||
1202 | 1336 | ||
1203 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr); | 1337 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr); |
1204 | 1338 | ||
1205 | dev_printk(KERN_INFO, &dev->dev, "PME# %s\n", | 1339 | dev_printk(KERN_DEBUG, &dev->dev, "PME# %s\n", |
1206 | enable ? "enabled" : "disabled"); | 1340 | enable ? "enabled" : "disabled"); |
1207 | } | 1341 | } |
1208 | 1342 | ||
1209 | /** | 1343 | /** |
1210 | * pci_enable_wake - enable PCI device as wakeup event source | 1344 | * __pci_enable_wake - enable PCI device as wakeup event source |
1211 | * @dev: PCI device affected | 1345 | * @dev: PCI device affected |
1212 | * @state: PCI state from which device will issue wakeup events | 1346 | * @state: PCI state from which device will issue wakeup events |
1347 | * @runtime: True if the events are to be generated at run time | ||
1213 | * @enable: True to enable event generation; false to disable | 1348 | * @enable: True to enable event generation; false to disable |
1214 | * | 1349 | * |
1215 | * This enables the device as a wakeup event source, or disables it. | 1350 | * This enables the device as a wakeup event source, or disables it. |
@@ -1225,11 +1360,12 @@ void pci_pme_active(struct pci_dev *dev, bool enable) | |||
1225 | * Error code depending on the platform is returned if both the platform and | 1360 | * Error code depending on the platform is returned if both the platform and |
1226 | * the native mechanism fail to enable the generation of wake-up events | 1361 | * the native mechanism fail to enable the generation of wake-up events |
1227 | */ | 1362 | */ |
1228 | int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable) | 1363 | int __pci_enable_wake(struct pci_dev *dev, pci_power_t state, |
1364 | bool runtime, bool enable) | ||
1229 | { | 1365 | { |
1230 | int ret = 0; | 1366 | int ret = 0; |
1231 | 1367 | ||
1232 | if (enable && !device_may_wakeup(&dev->dev)) | 1368 | if (enable && !runtime && !device_may_wakeup(&dev->dev)) |
1233 | return -EINVAL; | 1369 | return -EINVAL; |
1234 | 1370 | ||
1235 | /* Don't do the same thing twice in a row for one device. */ | 1371 | /* Don't do the same thing twice in a row for one device. */ |
@@ -1249,19 +1385,24 @@ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable) | |||
1249 | pci_pme_active(dev, true); | 1385 | pci_pme_active(dev, true); |
1250 | else | 1386 | else |
1251 | ret = 1; | 1387 | ret = 1; |
1252 | error = platform_pci_sleep_wake(dev, true); | 1388 | error = runtime ? platform_pci_run_wake(dev, true) : |
1389 | platform_pci_sleep_wake(dev, true); | ||
1253 | if (ret) | 1390 | if (ret) |
1254 | ret = error; | 1391 | ret = error; |
1255 | if (!ret) | 1392 | if (!ret) |
1256 | dev->wakeup_prepared = true; | 1393 | dev->wakeup_prepared = true; |
1257 | } else { | 1394 | } else { |
1258 | platform_pci_sleep_wake(dev, false); | 1395 | if (runtime) |
1396 | platform_pci_run_wake(dev, false); | ||
1397 | else | ||
1398 | platform_pci_sleep_wake(dev, false); | ||
1259 | pci_pme_active(dev, false); | 1399 | pci_pme_active(dev, false); |
1260 | dev->wakeup_prepared = false; | 1400 | dev->wakeup_prepared = false; |
1261 | } | 1401 | } |
1262 | 1402 | ||
1263 | return ret; | 1403 | return ret; |
1264 | } | 1404 | } |
1405 | EXPORT_SYMBOL(__pci_enable_wake); | ||
1265 | 1406 | ||
1266 | /** | 1407 | /** |
1267 | * pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold | 1408 | * pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold |
@@ -1371,6 +1512,66 @@ int pci_back_from_sleep(struct pci_dev *dev) | |||
1371 | } | 1512 | } |
1372 | 1513 | ||
1373 | /** | 1514 | /** |
1515 | * pci_finish_runtime_suspend - Carry out PCI-specific part of runtime suspend. | ||
1516 | * @dev: PCI device being suspended. | ||
1517 | * | ||
1518 | * Prepare @dev to generate wake-up events at run time and put it into a low | ||
1519 | * power state. | ||
1520 | */ | ||
1521 | int pci_finish_runtime_suspend(struct pci_dev *dev) | ||
1522 | { | ||
1523 | pci_power_t target_state = pci_target_state(dev); | ||
1524 | int error; | ||
1525 | |||
1526 | if (target_state == PCI_POWER_ERROR) | ||
1527 | return -EIO; | ||
1528 | |||
1529 | __pci_enable_wake(dev, target_state, true, pci_dev_run_wake(dev)); | ||
1530 | |||
1531 | error = pci_set_power_state(dev, target_state); | ||
1532 | |||
1533 | if (error) | ||
1534 | __pci_enable_wake(dev, target_state, true, false); | ||
1535 | |||
1536 | return error; | ||
1537 | } | ||
1538 | |||
1539 | /** | ||
1540 | * pci_dev_run_wake - Check if device can generate run-time wake-up events. | ||
1541 | * @dev: Device to check. | ||
1542 | * | ||
1543 | * Return true if the device itself is cabable of generating wake-up events | ||
1544 | * (through the platform or using the native PCIe PME) or if the device supports | ||
1545 | * PME and one of its upstream bridges can generate wake-up events. | ||
1546 | */ | ||
1547 | bool pci_dev_run_wake(struct pci_dev *dev) | ||
1548 | { | ||
1549 | struct pci_bus *bus = dev->bus; | ||
1550 | |||
1551 | if (device_run_wake(&dev->dev)) | ||
1552 | return true; | ||
1553 | |||
1554 | if (!dev->pme_support) | ||
1555 | return false; | ||
1556 | |||
1557 | while (bus->parent) { | ||
1558 | struct pci_dev *bridge = bus->self; | ||
1559 | |||
1560 | if (device_run_wake(&bridge->dev)) | ||
1561 | return true; | ||
1562 | |||
1563 | bus = bus->parent; | ||
1564 | } | ||
1565 | |||
1566 | /* We have reached the root bus. */ | ||
1567 | if (bus->bridge) | ||
1568 | return device_run_wake(bus->bridge); | ||
1569 | |||
1570 | return false; | ||
1571 | } | ||
1572 | EXPORT_SYMBOL_GPL(pci_dev_run_wake); | ||
1573 | |||
1574 | /** | ||
1374 | * pci_pm_init - Initialize PM functions of given PCI device | 1575 | * pci_pm_init - Initialize PM functions of given PCI device |
1375 | * @dev: PCI device to handle. | 1576 | * @dev: PCI device to handle. |
1376 | */ | 1577 | */ |
@@ -1379,7 +1580,10 @@ void pci_pm_init(struct pci_dev *dev) | |||
1379 | int pm; | 1580 | int pm; |
1380 | u16 pmc; | 1581 | u16 pmc; |
1381 | 1582 | ||
1583 | pm_runtime_forbid(&dev->dev); | ||
1584 | device_enable_async_suspend(&dev->dev); | ||
1382 | dev->wakeup_prepared = false; | 1585 | dev->wakeup_prepared = false; |
1586 | |||
1383 | dev->pm_cap = 0; | 1587 | dev->pm_cap = 0; |
1384 | 1588 | ||
1385 | /* find PCI PM capability in list */ | 1589 | /* find PCI PM capability in list */ |
@@ -1396,6 +1600,7 @@ void pci_pm_init(struct pci_dev *dev) | |||
1396 | } | 1600 | } |
1397 | 1601 | ||
1398 | dev->pm_cap = pm; | 1602 | dev->pm_cap = pm; |
1603 | dev->d3_delay = PCI_PM_D3_WAIT; | ||
1399 | 1604 | ||
1400 | dev->d1_support = false; | 1605 | dev->d1_support = false; |
1401 | dev->d2_support = false; | 1606 | dev->d2_support = false; |
@@ -1413,7 +1618,8 @@ void pci_pm_init(struct pci_dev *dev) | |||
1413 | 1618 | ||
1414 | pmc &= PCI_PM_CAP_PME_MASK; | 1619 | pmc &= PCI_PM_CAP_PME_MASK; |
1415 | if (pmc) { | 1620 | if (pmc) { |
1416 | dev_info(&dev->dev, "PME# supported from%s%s%s%s%s\n", | 1621 | dev_printk(KERN_DEBUG, &dev->dev, |
1622 | "PME# supported from%s%s%s%s%s\n", | ||
1417 | (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "", | 1623 | (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "", |
1418 | (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "", | 1624 | (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "", |
1419 | (pmc & PCI_PM_CAP_PME_D2) ? " D2" : "", | 1625 | (pmc & PCI_PM_CAP_PME_D2) ? " D2" : "", |
@@ -1510,7 +1716,7 @@ void pci_enable_ari(struct pci_dev *dev) | |||
1510 | u16 ctrl; | 1716 | u16 ctrl; |
1511 | struct pci_dev *bridge; | 1717 | struct pci_dev *bridge; |
1512 | 1718 | ||
1513 | if (!dev->is_pcie || dev->devfn) | 1719 | if (!pci_is_pcie(dev) || dev->devfn) |
1514 | return; | 1720 | return; |
1515 | 1721 | ||
1516 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); | 1722 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); |
@@ -1518,10 +1724,10 @@ void pci_enable_ari(struct pci_dev *dev) | |||
1518 | return; | 1724 | return; |
1519 | 1725 | ||
1520 | bridge = dev->bus->self; | 1726 | bridge = dev->bus->self; |
1521 | if (!bridge || !bridge->is_pcie) | 1727 | if (!bridge || !pci_is_pcie(bridge)) |
1522 | return; | 1728 | return; |
1523 | 1729 | ||
1524 | pos = pci_find_capability(bridge, PCI_CAP_ID_EXP); | 1730 | pos = pci_pcie_cap(bridge); |
1525 | if (!pos) | 1731 | if (!pos) |
1526 | return; | 1732 | return; |
1527 | 1733 | ||
@@ -1536,6 +1742,54 @@ void pci_enable_ari(struct pci_dev *dev) | |||
1536 | bridge->ari_enabled = 1; | 1742 | bridge->ari_enabled = 1; |
1537 | } | 1743 | } |
1538 | 1744 | ||
1745 | static int pci_acs_enable; | ||
1746 | |||
1747 | /** | ||
1748 | * pci_request_acs - ask for ACS to be enabled if supported | ||
1749 | */ | ||
1750 | void pci_request_acs(void) | ||
1751 | { | ||
1752 | pci_acs_enable = 1; | ||
1753 | } | ||
1754 | |||
1755 | /** | ||
1756 | * pci_enable_acs - enable ACS if hardware support it | ||
1757 | * @dev: the PCI device | ||
1758 | */ | ||
1759 | void pci_enable_acs(struct pci_dev *dev) | ||
1760 | { | ||
1761 | int pos; | ||
1762 | u16 cap; | ||
1763 | u16 ctrl; | ||
1764 | |||
1765 | if (!pci_acs_enable) | ||
1766 | return; | ||
1767 | |||
1768 | if (!pci_is_pcie(dev)) | ||
1769 | return; | ||
1770 | |||
1771 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS); | ||
1772 | if (!pos) | ||
1773 | return; | ||
1774 | |||
1775 | pci_read_config_word(dev, pos + PCI_ACS_CAP, &cap); | ||
1776 | pci_read_config_word(dev, pos + PCI_ACS_CTRL, &ctrl); | ||
1777 | |||
1778 | /* Source Validation */ | ||
1779 | ctrl |= (cap & PCI_ACS_SV); | ||
1780 | |||
1781 | /* P2P Request Redirect */ | ||
1782 | ctrl |= (cap & PCI_ACS_RR); | ||
1783 | |||
1784 | /* P2P Completion Redirect */ | ||
1785 | ctrl |= (cap & PCI_ACS_CR); | ||
1786 | |||
1787 | /* Upstream Forwarding */ | ||
1788 | ctrl |= (cap & PCI_ACS_UF); | ||
1789 | |||
1790 | pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl); | ||
1791 | } | ||
1792 | |||
1539 | /** | 1793 | /** |
1540 | * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge | 1794 | * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge |
1541 | * @dev: the PCI device | 1795 | * @dev: the PCI device |
@@ -1669,9 +1923,7 @@ static int __pci_request_region(struct pci_dev *pdev, int bar, const char *res_n | |||
1669 | return 0; | 1923 | return 0; |
1670 | 1924 | ||
1671 | err_out: | 1925 | err_out: |
1672 | dev_warn(&pdev->dev, "BAR %d: can't reserve %s region %pR\n", | 1926 | dev_warn(&pdev->dev, "BAR %d: can't reserve %pR\n", bar, |
1673 | bar, | ||
1674 | pci_resource_flags(pdev, bar) & IORESOURCE_IO ? "I/O" : "mem", | ||
1675 | &pdev->resource[bar]); | 1927 | &pdev->resource[bar]); |
1676 | return -EBUSY; | 1928 | return -EBUSY; |
1677 | } | 1929 | } |
@@ -1866,31 +2118,6 @@ void pci_clear_master(struct pci_dev *dev) | |||
1866 | __pci_set_master(dev, false); | 2118 | __pci_set_master(dev, false); |
1867 | } | 2119 | } |
1868 | 2120 | ||
1869 | #ifdef PCI_DISABLE_MWI | ||
1870 | int pci_set_mwi(struct pci_dev *dev) | ||
1871 | { | ||
1872 | return 0; | ||
1873 | } | ||
1874 | |||
1875 | int pci_try_set_mwi(struct pci_dev *dev) | ||
1876 | { | ||
1877 | return 0; | ||
1878 | } | ||
1879 | |||
1880 | void pci_clear_mwi(struct pci_dev *dev) | ||
1881 | { | ||
1882 | } | ||
1883 | |||
1884 | #else | ||
1885 | |||
1886 | #ifndef PCI_CACHE_LINE_BYTES | ||
1887 | #define PCI_CACHE_LINE_BYTES L1_CACHE_BYTES | ||
1888 | #endif | ||
1889 | |||
1890 | /* This can be overridden by arch code. */ | ||
1891 | /* Don't forget this is measured in 32-bit words, not bytes */ | ||
1892 | u8 pci_cache_line_size = PCI_CACHE_LINE_BYTES / 4; | ||
1893 | |||
1894 | /** | 2121 | /** |
1895 | * pci_set_cacheline_size - ensure the CACHE_LINE_SIZE register is programmed | 2122 | * pci_set_cacheline_size - ensure the CACHE_LINE_SIZE register is programmed |
1896 | * @dev: the PCI device for which MWI is to be enabled | 2123 | * @dev: the PCI device for which MWI is to be enabled |
@@ -1901,13 +2128,12 @@ u8 pci_cache_line_size = PCI_CACHE_LINE_BYTES / 4; | |||
1901 | * | 2128 | * |
1902 | * RETURNS: An appropriate -ERRNO error value on error, or zero for success. | 2129 | * RETURNS: An appropriate -ERRNO error value on error, or zero for success. |
1903 | */ | 2130 | */ |
1904 | static int | 2131 | int pci_set_cacheline_size(struct pci_dev *dev) |
1905 | pci_set_cacheline_size(struct pci_dev *dev) | ||
1906 | { | 2132 | { |
1907 | u8 cacheline_size; | 2133 | u8 cacheline_size; |
1908 | 2134 | ||
1909 | if (!pci_cache_line_size) | 2135 | if (!pci_cache_line_size) |
1910 | return -EINVAL; /* The system doesn't support MWI. */ | 2136 | return -EINVAL; |
1911 | 2137 | ||
1912 | /* Validate current setting: the PCI_CACHE_LINE_SIZE must be | 2138 | /* Validate current setting: the PCI_CACHE_LINE_SIZE must be |
1913 | equal to or multiple of the right value. */ | 2139 | equal to or multiple of the right value. */ |
@@ -1928,6 +2154,24 @@ pci_set_cacheline_size(struct pci_dev *dev) | |||
1928 | 2154 | ||
1929 | return -EINVAL; | 2155 | return -EINVAL; |
1930 | } | 2156 | } |
2157 | EXPORT_SYMBOL_GPL(pci_set_cacheline_size); | ||
2158 | |||
2159 | #ifdef PCI_DISABLE_MWI | ||
2160 | int pci_set_mwi(struct pci_dev *dev) | ||
2161 | { | ||
2162 | return 0; | ||
2163 | } | ||
2164 | |||
2165 | int pci_try_set_mwi(struct pci_dev *dev) | ||
2166 | { | ||
2167 | return 0; | ||
2168 | } | ||
2169 | |||
2170 | void pci_clear_mwi(struct pci_dev *dev) | ||
2171 | { | ||
2172 | } | ||
2173 | |||
2174 | #else | ||
1931 | 2175 | ||
1932 | /** | 2176 | /** |
1933 | * pci_set_mwi - enables memory-write-invalidate PCI transaction | 2177 | * pci_set_mwi - enables memory-write-invalidate PCI transaction |
@@ -2051,33 +2295,6 @@ void pci_msi_off(struct pci_dev *dev) | |||
2051 | } | 2295 | } |
2052 | } | 2296 | } |
2053 | 2297 | ||
2054 | #ifndef HAVE_ARCH_PCI_SET_DMA_MASK | ||
2055 | /* | ||
2056 | * These can be overridden by arch-specific implementations | ||
2057 | */ | ||
2058 | int | ||
2059 | pci_set_dma_mask(struct pci_dev *dev, u64 mask) | ||
2060 | { | ||
2061 | if (!pci_dma_supported(dev, mask)) | ||
2062 | return -EIO; | ||
2063 | |||
2064 | dev->dma_mask = mask; | ||
2065 | |||
2066 | return 0; | ||
2067 | } | ||
2068 | |||
2069 | int | ||
2070 | pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) | ||
2071 | { | ||
2072 | if (!pci_dma_supported(dev, mask)) | ||
2073 | return -EIO; | ||
2074 | |||
2075 | dev->dev.coherent_dma_mask = mask; | ||
2076 | |||
2077 | return 0; | ||
2078 | } | ||
2079 | #endif | ||
2080 | |||
2081 | #ifndef HAVE_ARCH_PCI_SET_DMA_MAX_SEGMENT_SIZE | 2298 | #ifndef HAVE_ARCH_PCI_SET_DMA_MAX_SEGMENT_SIZE |
2082 | int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size) | 2299 | int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size) |
2083 | { | 2300 | { |
@@ -2099,9 +2316,9 @@ static int pcie_flr(struct pci_dev *dev, int probe) | |||
2099 | int i; | 2316 | int i; |
2100 | int pos; | 2317 | int pos; |
2101 | u32 cap; | 2318 | u32 cap; |
2102 | u16 status; | 2319 | u16 status, control; |
2103 | 2320 | ||
2104 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 2321 | pos = pci_pcie_cap(dev); |
2105 | if (!pos) | 2322 | if (!pos) |
2106 | return -ENOTTY; | 2323 | return -ENOTTY; |
2107 | 2324 | ||
@@ -2126,8 +2343,10 @@ static int pcie_flr(struct pci_dev *dev, int probe) | |||
2126 | "proceeding with reset anyway\n"); | 2343 | "proceeding with reset anyway\n"); |
2127 | 2344 | ||
2128 | clear: | 2345 | clear: |
2129 | pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, | 2346 | pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &control); |
2130 | PCI_EXP_DEVCTL_BCR_FLR); | 2347 | control |= PCI_EXP_DEVCTL_BCR_FLR; |
2348 | pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, control); | ||
2349 | |||
2131 | msleep(100); | 2350 | msleep(100); |
2132 | 2351 | ||
2133 | return 0; | 2352 | return 0; |
@@ -2191,12 +2410,12 @@ static int pci_pm_reset(struct pci_dev *dev, int probe) | |||
2191 | csr &= ~PCI_PM_CTRL_STATE_MASK; | 2410 | csr &= ~PCI_PM_CTRL_STATE_MASK; |
2192 | csr |= PCI_D3hot; | 2411 | csr |= PCI_D3hot; |
2193 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr); | 2412 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr); |
2194 | msleep(pci_pm_d3_delay); | 2413 | pci_dev_d3_sleep(dev); |
2195 | 2414 | ||
2196 | csr &= ~PCI_PM_CTRL_STATE_MASK; | 2415 | csr &= ~PCI_PM_CTRL_STATE_MASK; |
2197 | csr |= PCI_D0; | 2416 | csr |= PCI_D0; |
2198 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr); | 2417 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr); |
2199 | msleep(pci_pm_d3_delay); | 2418 | pci_dev_d3_sleep(dev); |
2200 | 2419 | ||
2201 | return 0; | 2420 | return 0; |
2202 | } | 2421 | } |
@@ -2237,9 +2456,13 @@ static int pci_dev_reset(struct pci_dev *dev, int probe) | |||
2237 | if (!probe) { | 2456 | if (!probe) { |
2238 | pci_block_user_cfg_access(dev); | 2457 | pci_block_user_cfg_access(dev); |
2239 | /* block PM suspend, driver probe, etc. */ | 2458 | /* block PM suspend, driver probe, etc. */ |
2240 | down(&dev->dev.sem); | 2459 | device_lock(&dev->dev); |
2241 | } | 2460 | } |
2242 | 2461 | ||
2462 | rc = pci_dev_specific_reset(dev, probe); | ||
2463 | if (rc != -ENOTTY) | ||
2464 | goto done; | ||
2465 | |||
2243 | rc = pcie_flr(dev, probe); | 2466 | rc = pcie_flr(dev, probe); |
2244 | if (rc != -ENOTTY) | 2467 | if (rc != -ENOTTY) |
2245 | goto done; | 2468 | goto done; |
@@ -2255,7 +2478,7 @@ static int pci_dev_reset(struct pci_dev *dev, int probe) | |||
2255 | rc = pci_parent_bus_reset(dev, probe); | 2478 | rc = pci_parent_bus_reset(dev, probe); |
2256 | done: | 2479 | done: |
2257 | if (!probe) { | 2480 | if (!probe) { |
2258 | up(&dev->dev.sem); | 2481 | device_unlock(&dev->dev); |
2259 | pci_unblock_user_cfg_access(dev); | 2482 | pci_unblock_user_cfg_access(dev); |
2260 | } | 2483 | } |
2261 | 2484 | ||
@@ -2350,18 +2573,17 @@ EXPORT_SYMBOL_GPL(pci_reset_function); | |||
2350 | */ | 2573 | */ |
2351 | int pcix_get_max_mmrbc(struct pci_dev *dev) | 2574 | int pcix_get_max_mmrbc(struct pci_dev *dev) |
2352 | { | 2575 | { |
2353 | int err, cap; | 2576 | int cap; |
2354 | u32 stat; | 2577 | u32 stat; |
2355 | 2578 | ||
2356 | cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); | 2579 | cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); |
2357 | if (!cap) | 2580 | if (!cap) |
2358 | return -EINVAL; | 2581 | return -EINVAL; |
2359 | 2582 | ||
2360 | err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat); | 2583 | if (pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat)) |
2361 | if (err) | ||
2362 | return -EINVAL; | 2584 | return -EINVAL; |
2363 | 2585 | ||
2364 | return (stat & PCI_X_STATUS_MAX_READ) >> 12; | 2586 | return 512 << ((stat & PCI_X_STATUS_MAX_READ) >> 21); |
2365 | } | 2587 | } |
2366 | EXPORT_SYMBOL(pcix_get_max_mmrbc); | 2588 | EXPORT_SYMBOL(pcix_get_max_mmrbc); |
2367 | 2589 | ||
@@ -2374,18 +2596,17 @@ EXPORT_SYMBOL(pcix_get_max_mmrbc); | |||
2374 | */ | 2596 | */ |
2375 | int pcix_get_mmrbc(struct pci_dev *dev) | 2597 | int pcix_get_mmrbc(struct pci_dev *dev) |
2376 | { | 2598 | { |
2377 | int ret, cap; | 2599 | int cap; |
2378 | u32 cmd; | 2600 | u16 cmd; |
2379 | 2601 | ||
2380 | cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); | 2602 | cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); |
2381 | if (!cap) | 2603 | if (!cap) |
2382 | return -EINVAL; | 2604 | return -EINVAL; |
2383 | 2605 | ||
2384 | ret = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd); | 2606 | if (pci_read_config_word(dev, cap + PCI_X_CMD, &cmd)) |
2385 | if (!ret) | 2607 | return -EINVAL; |
2386 | ret = 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2); | ||
2387 | 2608 | ||
2388 | return ret; | 2609 | return 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2); |
2389 | } | 2610 | } |
2390 | EXPORT_SYMBOL(pcix_get_mmrbc); | 2611 | EXPORT_SYMBOL(pcix_get_mmrbc); |
2391 | 2612 | ||
@@ -2400,28 +2621,27 @@ EXPORT_SYMBOL(pcix_get_mmrbc); | |||
2400 | */ | 2621 | */ |
2401 | int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) | 2622 | int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) |
2402 | { | 2623 | { |
2403 | int cap, err = -EINVAL; | 2624 | int cap; |
2404 | u32 stat, cmd, v, o; | 2625 | u32 stat, v, o; |
2626 | u16 cmd; | ||
2405 | 2627 | ||
2406 | if (mmrbc < 512 || mmrbc > 4096 || !is_power_of_2(mmrbc)) | 2628 | if (mmrbc < 512 || mmrbc > 4096 || !is_power_of_2(mmrbc)) |
2407 | goto out; | 2629 | return -EINVAL; |
2408 | 2630 | ||
2409 | v = ffs(mmrbc) - 10; | 2631 | v = ffs(mmrbc) - 10; |
2410 | 2632 | ||
2411 | cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); | 2633 | cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); |
2412 | if (!cap) | 2634 | if (!cap) |
2413 | goto out; | 2635 | return -EINVAL; |
2414 | 2636 | ||
2415 | err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat); | 2637 | if (pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat)) |
2416 | if (err) | 2638 | return -EINVAL; |
2417 | goto out; | ||
2418 | 2639 | ||
2419 | if (v > (stat & PCI_X_STATUS_MAX_READ) >> 21) | 2640 | if (v > (stat & PCI_X_STATUS_MAX_READ) >> 21) |
2420 | return -E2BIG; | 2641 | return -E2BIG; |
2421 | 2642 | ||
2422 | err = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd); | 2643 | if (pci_read_config_word(dev, cap + PCI_X_CMD, &cmd)) |
2423 | if (err) | 2644 | return -EINVAL; |
2424 | goto out; | ||
2425 | 2645 | ||
2426 | o = (cmd & PCI_X_CMD_MAX_READ) >> 2; | 2646 | o = (cmd & PCI_X_CMD_MAX_READ) >> 2; |
2427 | if (o != v) { | 2647 | if (o != v) { |
@@ -2431,10 +2651,10 @@ int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) | |||
2431 | 2651 | ||
2432 | cmd &= ~PCI_X_CMD_MAX_READ; | 2652 | cmd &= ~PCI_X_CMD_MAX_READ; |
2433 | cmd |= v << 2; | 2653 | cmd |= v << 2; |
2434 | err = pci_write_config_dword(dev, cap + PCI_X_CMD, cmd); | 2654 | if (pci_write_config_word(dev, cap + PCI_X_CMD, cmd)) |
2655 | return -EIO; | ||
2435 | } | 2656 | } |
2436 | out: | 2657 | return 0; |
2437 | return err; | ||
2438 | } | 2658 | } |
2439 | EXPORT_SYMBOL(pcix_set_mmrbc); | 2659 | EXPORT_SYMBOL(pcix_set_mmrbc); |
2440 | 2660 | ||
@@ -2450,7 +2670,7 @@ int pcie_get_readrq(struct pci_dev *dev) | |||
2450 | int ret, cap; | 2670 | int ret, cap; |
2451 | u16 ctl; | 2671 | u16 ctl; |
2452 | 2672 | ||
2453 | cap = pci_find_capability(dev, PCI_CAP_ID_EXP); | 2673 | cap = pci_pcie_cap(dev); |
2454 | if (!cap) | 2674 | if (!cap) |
2455 | return -EINVAL; | 2675 | return -EINVAL; |
2456 | 2676 | ||
@@ -2480,7 +2700,7 @@ int pcie_set_readrq(struct pci_dev *dev, int rq) | |||
2480 | 2700 | ||
2481 | v = (ffs(rq) - 8) << 12; | 2701 | v = (ffs(rq) - 8) << 12; |
2482 | 2702 | ||
2483 | cap = pci_find_capability(dev, PCI_CAP_ID_EXP); | 2703 | cap = pci_pcie_cap(dev); |
2484 | if (!cap) | 2704 | if (!cap) |
2485 | goto out; | 2705 | goto out; |
2486 | 2706 | ||
@@ -2540,7 +2760,24 @@ int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type) | |||
2540 | return reg; | 2760 | return reg; |
2541 | } | 2761 | } |
2542 | 2762 | ||
2543 | dev_err(&dev->dev, "BAR: invalid resource #%d\n", resno); | 2763 | dev_err(&dev->dev, "BAR %d: invalid resource\n", resno); |
2764 | return 0; | ||
2765 | } | ||
2766 | |||
2767 | /* Some architectures require additional programming to enable VGA */ | ||
2768 | static arch_set_vga_state_t arch_set_vga_state; | ||
2769 | |||
2770 | void __init pci_register_set_vga_state(arch_set_vga_state_t func) | ||
2771 | { | ||
2772 | arch_set_vga_state = func; /* NULL disables */ | ||
2773 | } | ||
2774 | |||
2775 | static int pci_set_vga_state_arch(struct pci_dev *dev, bool decode, | ||
2776 | unsigned int command_bits, bool change_bridge) | ||
2777 | { | ||
2778 | if (arch_set_vga_state) | ||
2779 | return arch_set_vga_state(dev, decode, command_bits, | ||
2780 | change_bridge); | ||
2544 | return 0; | 2781 | return 0; |
2545 | } | 2782 | } |
2546 | 2783 | ||
@@ -2557,9 +2794,15 @@ int pci_set_vga_state(struct pci_dev *dev, bool decode, | |||
2557 | struct pci_bus *bus; | 2794 | struct pci_bus *bus; |
2558 | struct pci_dev *bridge; | 2795 | struct pci_dev *bridge; |
2559 | u16 cmd; | 2796 | u16 cmd; |
2797 | int rc; | ||
2560 | 2798 | ||
2561 | WARN_ON(command_bits & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY)); | 2799 | WARN_ON(command_bits & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY)); |
2562 | 2800 | ||
2801 | /* ARCH specific VGA enables */ | ||
2802 | rc = pci_set_vga_state_arch(dev, decode, command_bits, change_bridge); | ||
2803 | if (rc) | ||
2804 | return rc; | ||
2805 | |||
2563 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | 2806 | pci_read_config_word(dev, PCI_COMMAND, &cmd); |
2564 | if (decode == true) | 2807 | if (decode == true) |
2565 | cmd |= command_bits; | 2808 | cmd |= command_bits; |
@@ -2590,7 +2833,7 @@ int pci_set_vga_state(struct pci_dev *dev, bool decode, | |||
2590 | 2833 | ||
2591 | #define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE | 2834 | #define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE |
2592 | static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0}; | 2835 | static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0}; |
2593 | spinlock_t resource_alignment_lock = SPIN_LOCK_UNLOCKED; | 2836 | static DEFINE_SPINLOCK(resource_alignment_lock); |
2594 | 2837 | ||
2595 | /** | 2838 | /** |
2596 | * pci_specified_resource_alignment - get resource alignment specified by user. | 2839 | * pci_specified_resource_alignment - get resource alignment specified by user. |
@@ -2723,6 +2966,11 @@ int __attribute__ ((weak)) pci_ext_cfg_avail(struct pci_dev *dev) | |||
2723 | return 1; | 2966 | return 1; |
2724 | } | 2967 | } |
2725 | 2968 | ||
2969 | void __weak pci_fixup_cardbus(struct pci_bus *bus) | ||
2970 | { | ||
2971 | } | ||
2972 | EXPORT_SYMBOL(pci_fixup_cardbus); | ||
2973 | |||
2726 | static int __init pci_setup(char *str) | 2974 | static int __init pci_setup(char *str) |
2727 | { | 2975 | { |
2728 | while (str) { | 2976 | while (str) { |
@@ -2784,8 +3032,6 @@ EXPORT_SYMBOL(pci_set_mwi); | |||
2784 | EXPORT_SYMBOL(pci_try_set_mwi); | 3032 | EXPORT_SYMBOL(pci_try_set_mwi); |
2785 | EXPORT_SYMBOL(pci_clear_mwi); | 3033 | EXPORT_SYMBOL(pci_clear_mwi); |
2786 | EXPORT_SYMBOL_GPL(pci_intx); | 3034 | EXPORT_SYMBOL_GPL(pci_intx); |
2787 | EXPORT_SYMBOL(pci_set_dma_mask); | ||
2788 | EXPORT_SYMBOL(pci_set_consistent_dma_mask); | ||
2789 | EXPORT_SYMBOL(pci_assign_resource); | 3035 | EXPORT_SYMBOL(pci_assign_resource); |
2790 | EXPORT_SYMBOL(pci_find_parent_resource); | 3036 | EXPORT_SYMBOL(pci_find_parent_resource); |
2791 | EXPORT_SYMBOL(pci_select_bars); | 3037 | EXPORT_SYMBOL(pci_select_bars); |
@@ -2795,10 +3041,8 @@ EXPORT_SYMBOL(pci_save_state); | |||
2795 | EXPORT_SYMBOL(pci_restore_state); | 3041 | EXPORT_SYMBOL(pci_restore_state); |
2796 | EXPORT_SYMBOL(pci_pme_capable); | 3042 | EXPORT_SYMBOL(pci_pme_capable); |
2797 | EXPORT_SYMBOL(pci_pme_active); | 3043 | EXPORT_SYMBOL(pci_pme_active); |
2798 | EXPORT_SYMBOL(pci_enable_wake); | ||
2799 | EXPORT_SYMBOL(pci_wake_from_d3); | 3044 | EXPORT_SYMBOL(pci_wake_from_d3); |
2800 | EXPORT_SYMBOL(pci_target_state); | 3045 | EXPORT_SYMBOL(pci_target_state); |
2801 | EXPORT_SYMBOL(pci_prepare_to_sleep); | 3046 | EXPORT_SYMBOL(pci_prepare_to_sleep); |
2802 | EXPORT_SYMBOL(pci_back_from_sleep); | 3047 | EXPORT_SYMBOL(pci_back_from_sleep); |
2803 | EXPORT_SYMBOL_GPL(pci_set_pcie_reset_state); | 3048 | EXPORT_SYMBOL_GPL(pci_set_pcie_reset_state); |
2804 | |||
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index d92d1954a2fb..4eb10f48d270 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -35,6 +35,10 @@ int pci_probe_reset_function(struct pci_dev *dev); | |||
35 | * | 35 | * |
36 | * @sleep_wake: enables/disables the system wake up capability of given device | 36 | * @sleep_wake: enables/disables the system wake up capability of given device |
37 | * | 37 | * |
38 | * @run_wake: enables/disables the platform to generate run-time wake-up events | ||
39 | * for given device (the device's wake-up capability has to be | ||
40 | * enabled by @sleep_wake for this feature to work) | ||
41 | * | ||
38 | * If given platform is generally capable of power managing PCI devices, all of | 42 | * If given platform is generally capable of power managing PCI devices, all of |
39 | * these callbacks are mandatory. | 43 | * these callbacks are mandatory. |
40 | */ | 44 | */ |
@@ -44,11 +48,16 @@ struct pci_platform_pm_ops { | |||
44 | pci_power_t (*choose_state)(struct pci_dev *dev); | 48 | pci_power_t (*choose_state)(struct pci_dev *dev); |
45 | bool (*can_wakeup)(struct pci_dev *dev); | 49 | bool (*can_wakeup)(struct pci_dev *dev); |
46 | int (*sleep_wake)(struct pci_dev *dev, bool enable); | 50 | int (*sleep_wake)(struct pci_dev *dev, bool enable); |
51 | int (*run_wake)(struct pci_dev *dev, bool enable); | ||
47 | }; | 52 | }; |
48 | 53 | ||
49 | extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops); | 54 | extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops); |
50 | extern void pci_update_current_state(struct pci_dev *dev, pci_power_t state); | 55 | extern void pci_update_current_state(struct pci_dev *dev, pci_power_t state); |
51 | extern void pci_disable_enabled_device(struct pci_dev *dev); | 56 | extern void pci_disable_enabled_device(struct pci_dev *dev); |
57 | extern bool pci_check_pme_status(struct pci_dev *dev); | ||
58 | extern int pci_finish_runtime_suspend(struct pci_dev *dev); | ||
59 | extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); | ||
60 | extern void pci_pme_wakeup_bus(struct pci_bus *bus); | ||
52 | extern void pci_pm_init(struct pci_dev *dev); | 61 | extern void pci_pm_init(struct pci_dev *dev); |
53 | extern void platform_pci_wakeup_init(struct pci_dev *dev); | 62 | extern void platform_pci_wakeup_init(struct pci_dev *dev); |
54 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); | 63 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); |
@@ -311,4 +320,21 @@ static inline int pci_resource_alignment(struct pci_dev *dev, | |||
311 | return resource_alignment(res); | 320 | return resource_alignment(res); |
312 | } | 321 | } |
313 | 322 | ||
323 | extern void pci_enable_acs(struct pci_dev *dev); | ||
324 | |||
325 | struct pci_dev_reset_methods { | ||
326 | u16 vendor; | ||
327 | u16 device; | ||
328 | int (*reset)(struct pci_dev *dev, int probe); | ||
329 | }; | ||
330 | |||
331 | #ifdef CONFIG_PCI_QUIRKS | ||
332 | extern int pci_dev_specific_reset(struct pci_dev *dev, int probe); | ||
333 | #else | ||
334 | static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe) | ||
335 | { | ||
336 | return -ENOTTY; | ||
337 | } | ||
338 | #endif | ||
339 | |||
314 | #endif /* DRIVERS_PCI_H */ | 340 | #endif /* DRIVERS_PCI_H */ |
diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig index 5a0c6ad53f8e..b8b494b3e0d0 100644 --- a/drivers/pci/pcie/Kconfig +++ b/drivers/pci/pcie/Kconfig | |||
@@ -46,3 +46,7 @@ config PCIEASPM_DEBUG | |||
46 | help | 46 | help |
47 | This enables PCI Express ASPM debug support. It will add per-device | 47 | This enables PCI Express ASPM debug support. It will add per-device |
48 | interface to control ASPM. | 48 | interface to control ASPM. |
49 | |||
50 | config PCIE_PME | ||
51 | def_bool y | ||
52 | depends on PCIEPORTBUS && PM_RUNTIME && EXPERIMENTAL && ACPI | ||
diff --git a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile index 11f6bb1eae24..ea654545e7c4 100644 --- a/drivers/pci/pcie/Makefile +++ b/drivers/pci/pcie/Makefile | |||
@@ -11,3 +11,5 @@ obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o | |||
11 | 11 | ||
12 | # Build PCI Express AER if needed | 12 | # Build PCI Express AER if needed |
13 | obj-$(CONFIG_PCIEAER) += aer/ | 13 | obj-$(CONFIG_PCIEAER) += aer/ |
14 | |||
15 | obj-$(CONFIG_PCIE_PME) += pme/ | ||
diff --git a/drivers/pci/pcie/aer/Kconfig.debug b/drivers/pci/pcie/aer/Kconfig.debug index b8c925c1f6aa..9142949734f5 100644 --- a/drivers/pci/pcie/aer/Kconfig.debug +++ b/drivers/pci/pcie/aer/Kconfig.debug | |||
@@ -3,14 +3,14 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | config PCIEAER_INJECT | 5 | config PCIEAER_INJECT |
6 | tristate "PCIE AER error injector support" | 6 | tristate "PCIe AER error injector support" |
7 | depends on PCIEAER | 7 | depends on PCIEAER |
8 | default n | 8 | default n |
9 | help | 9 | help |
10 | This enables PCI Express Root Port Advanced Error Reporting | 10 | This enables PCI Express Root Port Advanced Error Reporting |
11 | (AER) software error injector. | 11 | (AER) software error injector. |
12 | 12 | ||
13 | Debuging PCIE AER code is quite difficult because it is hard | 13 | Debugging PCIe AER code is quite difficult because it is hard |
14 | to trigger various real hardware errors. Software based | 14 | to trigger various real hardware errors. Software based |
15 | error injection can fake almost all kinds of errors with the | 15 | error injection can fake almost all kinds of errors with the |
16 | help of a user space helper tool aer-inject, which can be | 16 | help of a user space helper tool aer-inject, which can be |
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c index 62d15f652bb6..f8f425b8731d 100644 --- a/drivers/pci/pcie/aer/aer_inject.c +++ b/drivers/pci/pcie/aer/aer_inject.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * PCIE AER software error injection support. | 2 | * PCIe AER software error injection support. |
3 | * | 3 | * |
4 | * Debuging PCIE AER code is quite difficult because it is hard to | 4 | * Debuging PCIe AER code is quite difficult because it is hard to |
5 | * trigger various real hardware errors. Software based error | 5 | * trigger various real hardware errors. Software based error |
6 | * injection can fake almost all kinds of errors with the help of a | 6 | * injection can fake almost all kinds of errors with the help of a |
7 | * user space helper tool aer-inject, which can be gotten from: | 7 | * user space helper tool aer-inject, which can be gotten from: |
@@ -21,8 +21,10 @@ | |||
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/miscdevice.h> | 22 | #include <linux/miscdevice.h> |
23 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
24 | #include <linux/slab.h> | ||
24 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
25 | #include <linux/uaccess.h> | 26 | #include <linux/uaccess.h> |
27 | #include <linux/stddef.h> | ||
26 | #include "aerdrv.h" | 28 | #include "aerdrv.h" |
27 | 29 | ||
28 | struct aer_error_inj { | 30 | struct aer_error_inj { |
@@ -35,10 +37,12 @@ struct aer_error_inj { | |||
35 | u32 header_log1; | 37 | u32 header_log1; |
36 | u32 header_log2; | 38 | u32 header_log2; |
37 | u32 header_log3; | 39 | u32 header_log3; |
40 | u16 domain; | ||
38 | }; | 41 | }; |
39 | 42 | ||
40 | struct aer_error { | 43 | struct aer_error { |
41 | struct list_head list; | 44 | struct list_head list; |
45 | u16 domain; | ||
42 | unsigned int bus; | 46 | unsigned int bus; |
43 | unsigned int devfn; | 47 | unsigned int devfn; |
44 | int pos_cap_err; | 48 | int pos_cap_err; |
@@ -66,22 +70,27 @@ static LIST_HEAD(pci_bus_ops_list); | |||
66 | /* Protect einjected and pci_bus_ops_list */ | 70 | /* Protect einjected and pci_bus_ops_list */ |
67 | static DEFINE_SPINLOCK(inject_lock); | 71 | static DEFINE_SPINLOCK(inject_lock); |
68 | 72 | ||
69 | static void aer_error_init(struct aer_error *err, unsigned int bus, | 73 | static void aer_error_init(struct aer_error *err, u16 domain, |
70 | unsigned int devfn, int pos_cap_err) | 74 | unsigned int bus, unsigned int devfn, |
75 | int pos_cap_err) | ||
71 | { | 76 | { |
72 | INIT_LIST_HEAD(&err->list); | 77 | INIT_LIST_HEAD(&err->list); |
78 | err->domain = domain; | ||
73 | err->bus = bus; | 79 | err->bus = bus; |
74 | err->devfn = devfn; | 80 | err->devfn = devfn; |
75 | err->pos_cap_err = pos_cap_err; | 81 | err->pos_cap_err = pos_cap_err; |
76 | } | 82 | } |
77 | 83 | ||
78 | /* inject_lock must be held before calling */ | 84 | /* inject_lock must be held before calling */ |
79 | static struct aer_error *__find_aer_error(unsigned int bus, unsigned int devfn) | 85 | static struct aer_error *__find_aer_error(u16 domain, unsigned int bus, |
86 | unsigned int devfn) | ||
80 | { | 87 | { |
81 | struct aer_error *err; | 88 | struct aer_error *err; |
82 | 89 | ||
83 | list_for_each_entry(err, &einjected, list) { | 90 | list_for_each_entry(err, &einjected, list) { |
84 | if (bus == err->bus && devfn == err->devfn) | 91 | if (domain == err->domain && |
92 | bus == err->bus && | ||
93 | devfn == err->devfn) | ||
85 | return err; | 94 | return err; |
86 | } | 95 | } |
87 | return NULL; | 96 | return NULL; |
@@ -90,7 +99,10 @@ static struct aer_error *__find_aer_error(unsigned int bus, unsigned int devfn) | |||
90 | /* inject_lock must be held before calling */ | 99 | /* inject_lock must be held before calling */ |
91 | static struct aer_error *__find_aer_error_by_dev(struct pci_dev *dev) | 100 | static struct aer_error *__find_aer_error_by_dev(struct pci_dev *dev) |
92 | { | 101 | { |
93 | return __find_aer_error(dev->bus->number, dev->devfn); | 102 | int domain = pci_domain_nr(dev->bus); |
103 | if (domain < 0) | ||
104 | return NULL; | ||
105 | return __find_aer_error((u16)domain, dev->bus->number, dev->devfn); | ||
94 | } | 106 | } |
95 | 107 | ||
96 | /* inject_lock must be held before calling */ | 108 | /* inject_lock must be held before calling */ |
@@ -172,11 +184,15 @@ static int pci_read_aer(struct pci_bus *bus, unsigned int devfn, int where, | |||
172 | struct aer_error *err; | 184 | struct aer_error *err; |
173 | unsigned long flags; | 185 | unsigned long flags; |
174 | struct pci_ops *ops; | 186 | struct pci_ops *ops; |
187 | int domain; | ||
175 | 188 | ||
176 | spin_lock_irqsave(&inject_lock, flags); | 189 | spin_lock_irqsave(&inject_lock, flags); |
177 | if (size != sizeof(u32)) | 190 | if (size != sizeof(u32)) |
178 | goto out; | 191 | goto out; |
179 | err = __find_aer_error(bus->number, devfn); | 192 | domain = pci_domain_nr(bus); |
193 | if (domain < 0) | ||
194 | goto out; | ||
195 | err = __find_aer_error((u16)domain, bus->number, devfn); | ||
180 | if (!err) | 196 | if (!err) |
181 | goto out; | 197 | goto out; |
182 | 198 | ||
@@ -200,11 +216,15 @@ int pci_write_aer(struct pci_bus *bus, unsigned int devfn, int where, int size, | |||
200 | unsigned long flags; | 216 | unsigned long flags; |
201 | int rw1cs; | 217 | int rw1cs; |
202 | struct pci_ops *ops; | 218 | struct pci_ops *ops; |
219 | int domain; | ||
203 | 220 | ||
204 | spin_lock_irqsave(&inject_lock, flags); | 221 | spin_lock_irqsave(&inject_lock, flags); |
205 | if (size != sizeof(u32)) | 222 | if (size != sizeof(u32)) |
206 | goto out; | 223 | goto out; |
207 | err = __find_aer_error(bus->number, devfn); | 224 | domain = pci_domain_nr(bus); |
225 | if (domain < 0) | ||
226 | goto out; | ||
227 | err = __find_aer_error((u16)domain, bus->number, devfn); | ||
208 | if (!err) | 228 | if (!err) |
209 | goto out; | 229 | goto out; |
210 | 230 | ||
@@ -262,7 +282,7 @@ out: | |||
262 | static struct pci_dev *pcie_find_root_port(struct pci_dev *dev) | 282 | static struct pci_dev *pcie_find_root_port(struct pci_dev *dev) |
263 | { | 283 | { |
264 | while (1) { | 284 | while (1) { |
265 | if (!dev->is_pcie) | 285 | if (!pci_is_pcie(dev)) |
266 | break; | 286 | break; |
267 | if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) | 287 | if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) |
268 | return dev; | 288 | return dev; |
@@ -302,28 +322,31 @@ static int aer_inject(struct aer_error_inj *einj) | |||
302 | unsigned long flags; | 322 | unsigned long flags; |
303 | unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn); | 323 | unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn); |
304 | int pos_cap_err, rp_pos_cap_err; | 324 | int pos_cap_err, rp_pos_cap_err; |
305 | u32 sever; | 325 | u32 sever, cor_mask, uncor_mask; |
306 | int ret = 0; | 326 | int ret = 0; |
307 | 327 | ||
308 | dev = pci_get_bus_and_slot(einj->bus, devfn); | 328 | dev = pci_get_domain_bus_and_slot((int)einj->domain, einj->bus, devfn); |
309 | if (!dev) | 329 | if (!dev) |
310 | return -EINVAL; | 330 | return -ENODEV; |
311 | rpdev = pcie_find_root_port(dev); | 331 | rpdev = pcie_find_root_port(dev); |
312 | if (!rpdev) { | 332 | if (!rpdev) { |
313 | ret = -EINVAL; | 333 | ret = -ENOTTY; |
314 | goto out_put; | 334 | goto out_put; |
315 | } | 335 | } |
316 | 336 | ||
317 | pos_cap_err = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | 337 | pos_cap_err = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
318 | if (!pos_cap_err) { | 338 | if (!pos_cap_err) { |
319 | ret = -EIO; | 339 | ret = -ENOTTY; |
320 | goto out_put; | 340 | goto out_put; |
321 | } | 341 | } |
322 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever); | 342 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever); |
343 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_COR_MASK, &cor_mask); | ||
344 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_MASK, | ||
345 | &uncor_mask); | ||
323 | 346 | ||
324 | rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR); | 347 | rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR); |
325 | if (!rp_pos_cap_err) { | 348 | if (!rp_pos_cap_err) { |
326 | ret = -EIO; | 349 | ret = -ENOTTY; |
327 | goto out_put; | 350 | goto out_put; |
328 | } | 351 | } |
329 | 352 | ||
@@ -344,7 +367,8 @@ static int aer_inject(struct aer_error_inj *einj) | |||
344 | if (!err) { | 367 | if (!err) { |
345 | err = err_alloc; | 368 | err = err_alloc; |
346 | err_alloc = NULL; | 369 | err_alloc = NULL; |
347 | aer_error_init(err, einj->bus, devfn, pos_cap_err); | 370 | aer_error_init(err, einj->domain, einj->bus, devfn, |
371 | pos_cap_err); | ||
348 | list_add(&err->list, &einjected); | 372 | list_add(&err->list, &einjected); |
349 | } | 373 | } |
350 | err->uncor_status |= einj->uncor_status; | 374 | err->uncor_status |= einj->uncor_status; |
@@ -354,11 +378,27 @@ static int aer_inject(struct aer_error_inj *einj) | |||
354 | err->header_log2 = einj->header_log2; | 378 | err->header_log2 = einj->header_log2; |
355 | err->header_log3 = einj->header_log3; | 379 | err->header_log3 = einj->header_log3; |
356 | 380 | ||
381 | if (einj->cor_status && !(einj->cor_status & ~cor_mask)) { | ||
382 | ret = -EINVAL; | ||
383 | printk(KERN_WARNING "The correctable error(s) is masked " | ||
384 | "by device\n"); | ||
385 | spin_unlock_irqrestore(&inject_lock, flags); | ||
386 | goto out_put; | ||
387 | } | ||
388 | if (einj->uncor_status && !(einj->uncor_status & ~uncor_mask)) { | ||
389 | ret = -EINVAL; | ||
390 | printk(KERN_WARNING "The uncorrectable error(s) is masked " | ||
391 | "by device\n"); | ||
392 | spin_unlock_irqrestore(&inject_lock, flags); | ||
393 | goto out_put; | ||
394 | } | ||
395 | |||
357 | rperr = __find_aer_error_by_dev(rpdev); | 396 | rperr = __find_aer_error_by_dev(rpdev); |
358 | if (!rperr) { | 397 | if (!rperr) { |
359 | rperr = rperr_alloc; | 398 | rperr = rperr_alloc; |
360 | rperr_alloc = NULL; | 399 | rperr_alloc = NULL; |
361 | aer_error_init(rperr, rpdev->bus->number, rpdev->devfn, | 400 | aer_error_init(rperr, pci_domain_nr(rpdev->bus), |
401 | rpdev->bus->number, rpdev->devfn, | ||
362 | rp_pos_cap_err); | 402 | rp_pos_cap_err); |
363 | list_add(&rperr->list, &einjected); | 403 | list_add(&rperr->list, &einjected); |
364 | } | 404 | } |
@@ -392,8 +432,14 @@ static int aer_inject(struct aer_error_inj *einj) | |||
392 | if (ret) | 432 | if (ret) |
393 | goto out_put; | 433 | goto out_put; |
394 | 434 | ||
395 | if (find_aer_device(rpdev, &edev)) | 435 | if (find_aer_device(rpdev, &edev)) { |
436 | if (!get_service_data(edev)) { | ||
437 | printk(KERN_WARNING "AER service is not initialized\n"); | ||
438 | ret = -EINVAL; | ||
439 | goto out_put; | ||
440 | } | ||
396 | aer_irq(-1, edev); | 441 | aer_irq(-1, edev); |
442 | } | ||
397 | else | 443 | else |
398 | ret = -EINVAL; | 444 | ret = -EINVAL; |
399 | out_put: | 445 | out_put: |
@@ -411,10 +457,11 @@ static ssize_t aer_inject_write(struct file *filp, const char __user *ubuf, | |||
411 | 457 | ||
412 | if (!capable(CAP_SYS_ADMIN)) | 458 | if (!capable(CAP_SYS_ADMIN)) |
413 | return -EPERM; | 459 | return -EPERM; |
414 | 460 | if (usize < offsetof(struct aer_error_inj, domain) || | |
415 | if (usize != sizeof(struct aer_error_inj)) | 461 | usize > sizeof(einj)) |
416 | return -EINVAL; | 462 | return -EINVAL; |
417 | 463 | ||
464 | memset(&einj, 0, sizeof(einj)); | ||
418 | if (copy_from_user(&einj, ubuf, usize)) | 465 | if (copy_from_user(&einj, ubuf, usize)) |
419 | return -EFAULT; | 466 | return -EFAULT; |
420 | 467 | ||
@@ -452,7 +499,7 @@ static void __exit aer_inject_exit(void) | |||
452 | } | 499 | } |
453 | 500 | ||
454 | spin_lock_irqsave(&inject_lock, flags); | 501 | spin_lock_irqsave(&inject_lock, flags); |
455 | list_for_each_entry_safe(err, err_next, &pci_bus_ops_list, list) { | 502 | list_for_each_entry_safe(err, err_next, &einjected, list) { |
456 | list_del(&err->list); | 503 | list_del(&err->list); |
457 | kfree(err); | 504 | kfree(err); |
458 | } | 505 | } |
@@ -462,5 +509,5 @@ static void __exit aer_inject_exit(void) | |||
462 | module_init(aer_inject_init); | 509 | module_init(aer_inject_init); |
463 | module_exit(aer_inject_exit); | 510 | module_exit(aer_inject_exit); |
464 | 511 | ||
465 | MODULE_DESCRIPTION("PCIE AER software error injector"); | 512 | MODULE_DESCRIPTION("PCIe AER software error injector"); |
466 | MODULE_LICENSE("GPL"); | 513 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index 40c3cc5d1caf..7a711ee314b7 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/pcieport_if.h> | 27 | #include <linux/pcieport_if.h> |
28 | #include <linux/slab.h> | ||
28 | 29 | ||
29 | #include "aerdrv.h" | 30 | #include "aerdrv.h" |
30 | #include "../../pci.h" | 31 | #include "../../pci.h" |
@@ -53,7 +54,7 @@ static struct pci_error_handlers aer_error_handlers = { | |||
53 | 54 | ||
54 | static struct pcie_port_service_driver aerdriver = { | 55 | static struct pcie_port_service_driver aerdriver = { |
55 | .name = "aer", | 56 | .name = "aer", |
56 | .port_type = PCIE_RC_PORT, | 57 | .port_type = PCI_EXP_TYPE_ROOT_PORT, |
57 | .service = PCIE_PORT_SERVICE_AER, | 58 | .service = PCIE_PORT_SERVICE_AER, |
58 | 59 | ||
59 | .probe = aer_probe, | 60 | .probe = aer_probe, |
@@ -155,7 +156,7 @@ static struct aer_rpc *aer_alloc_rpc(struct pcie_device *dev) | |||
155 | mutex_init(&rpc->rpc_mutex); | 156 | mutex_init(&rpc->rpc_mutex); |
156 | init_waitqueue_head(&rpc->wait_release); | 157 | init_waitqueue_head(&rpc->wait_release); |
157 | 158 | ||
158 | /* Use PCIE bus function to store rpc into PCIE device */ | 159 | /* Use PCIe bus function to store rpc into PCIe device */ |
159 | set_service_data(dev, rpc); | 160 | set_service_data(dev, rpc); |
160 | 161 | ||
161 | return rpc; | 162 | return rpc; |
@@ -243,11 +244,17 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev) | |||
243 | 244 | ||
244 | /* Assert Secondary Bus Reset */ | 245 | /* Assert Secondary Bus Reset */ |
245 | pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &p2p_ctrl); | 246 | pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &p2p_ctrl); |
246 | p2p_ctrl |= PCI_CB_BRIDGE_CTL_CB_RESET; | 247 | p2p_ctrl |= PCI_BRIDGE_CTL_BUS_RESET; |
247 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl); | 248 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl); |
248 | 249 | ||
250 | /* | ||
251 | * we should send hot reset message for 2ms to allow it time to | ||
252 | * propogate to all downstream ports | ||
253 | */ | ||
254 | msleep(2); | ||
255 | |||
249 | /* De-assert Secondary Bus Reset */ | 256 | /* De-assert Secondary Bus Reset */ |
250 | p2p_ctrl &= ~PCI_CB_BRIDGE_CTL_CB_RESET; | 257 | p2p_ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET; |
251 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl); | 258 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl); |
252 | 259 | ||
253 | /* | 260 | /* |
@@ -295,7 +302,7 @@ static void aer_error_resume(struct pci_dev *dev) | |||
295 | u16 reg16; | 302 | u16 reg16; |
296 | 303 | ||
297 | /* Clean up Root device status */ | 304 | /* Clean up Root device status */ |
298 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 305 | pos = pci_pcie_cap(dev); |
299 | pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, ®16); | 306 | pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, ®16); |
300 | pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, reg16); | 307 | pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, reg16); |
301 | 308 | ||
diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c index 8edb2f300e8f..04814087658d 100644 --- a/drivers/pci/pcie/aer/aerdrv_acpi.c +++ b/drivers/pci/pcie/aer/aerdrv_acpi.c | |||
@@ -24,7 +24,7 @@ | |||
24 | * | 24 | * |
25 | * @return: Zero on success. Nonzero otherwise. | 25 | * @return: Zero on success. Nonzero otherwise. |
26 | * | 26 | * |
27 | * Invoked when PCIE bus loads AER service driver. To avoid conflict with | 27 | * Invoked when PCIe bus loads AER service driver. To avoid conflict with |
28 | * BIOS AER support requires BIOS to yield AER control to OS native driver. | 28 | * BIOS AER support requires BIOS to yield AER control to OS native driver. |
29 | **/ | 29 | **/ |
30 | int aer_osc_setup(struct pcie_device *pciedev) | 30 | int aer_osc_setup(struct pcie_device *pciedev) |
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 9f5ccbeb4fa5..aceb04b67b60 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/pm.h> | 23 | #include <linux/pm.h> |
24 | #include <linux/suspend.h> | 24 | #include <linux/suspend.h> |
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <linux/slab.h> | ||
26 | #include "aerdrv.h" | 27 | #include "aerdrv.h" |
27 | 28 | ||
28 | static int forceload; | 29 | static int forceload; |
@@ -35,11 +36,14 @@ int pci_enable_pcie_error_reporting(struct pci_dev *dev) | |||
35 | u16 reg16 = 0; | 36 | u16 reg16 = 0; |
36 | int pos; | 37 | int pos; |
37 | 38 | ||
39 | if (dev->aer_firmware_first) | ||
40 | return -EIO; | ||
41 | |||
38 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | 42 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
39 | if (!pos) | 43 | if (!pos) |
40 | return -EIO; | 44 | return -EIO; |
41 | 45 | ||
42 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 46 | pos = pci_pcie_cap(dev); |
43 | if (!pos) | 47 | if (!pos) |
44 | return -EIO; | 48 | return -EIO; |
45 | 49 | ||
@@ -60,7 +64,10 @@ int pci_disable_pcie_error_reporting(struct pci_dev *dev) | |||
60 | u16 reg16 = 0; | 64 | u16 reg16 = 0; |
61 | int pos; | 65 | int pos; |
62 | 66 | ||
63 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 67 | if (dev->aer_firmware_first) |
68 | return -EIO; | ||
69 | |||
70 | pos = pci_pcie_cap(dev); | ||
64 | if (!pos) | 71 | if (!pos) |
65 | return -EIO; | 72 | return -EIO; |
66 | 73 | ||
@@ -78,48 +85,27 @@ EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting); | |||
78 | int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev) | 85 | int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev) |
79 | { | 86 | { |
80 | int pos; | 87 | int pos; |
81 | u32 status, mask; | 88 | u32 status; |
82 | 89 | ||
83 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | 90 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
84 | if (!pos) | 91 | if (!pos) |
85 | return -EIO; | 92 | return -EIO; |
86 | 93 | ||
87 | pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status); | 94 | pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status); |
88 | pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask); | 95 | if (status) |
89 | if (dev->error_state == pci_channel_io_normal) | 96 | pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status); |
90 | status &= ~mask; /* Clear corresponding nonfatal bits */ | ||
91 | else | ||
92 | status &= mask; /* Clear corresponding fatal bits */ | ||
93 | pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status); | ||
94 | 97 | ||
95 | return 0; | 98 | return 0; |
96 | } | 99 | } |
97 | EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status); | 100 | EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status); |
98 | 101 | ||
99 | #if 0 | ||
100 | int pci_cleanup_aer_correct_error_status(struct pci_dev *dev) | ||
101 | { | ||
102 | int pos; | ||
103 | u32 status; | ||
104 | |||
105 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | ||
106 | if (!pos) | ||
107 | return -EIO; | ||
108 | |||
109 | pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &status); | ||
110 | pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, status); | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | #endif /* 0 */ | ||
115 | |||
116 | static int set_device_error_reporting(struct pci_dev *dev, void *data) | 102 | static int set_device_error_reporting(struct pci_dev *dev, void *data) |
117 | { | 103 | { |
118 | bool enable = *((bool *)data); | 104 | bool enable = *((bool *)data); |
119 | 105 | ||
120 | if (dev->pcie_type == PCIE_RC_PORT || | 106 | if ((dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) || |
121 | dev->pcie_type == PCIE_SW_UPSTREAM_PORT || | 107 | (dev->pcie_type == PCI_EXP_TYPE_UPSTREAM) || |
122 | dev->pcie_type == PCIE_SW_DOWNSTREAM_PORT) { | 108 | (dev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)) { |
123 | if (enable) | 109 | if (enable) |
124 | pci_enable_pcie_error_reporting(dev); | 110 | pci_enable_pcie_error_reporting(dev); |
125 | else | 111 | else |
@@ -218,7 +204,7 @@ static int find_device_iter(struct pci_dev *dev, void *data) | |||
218 | */ | 204 | */ |
219 | if (atomic_read(&dev->enable_cnt) == 0) | 205 | if (atomic_read(&dev->enable_cnt) == 0) |
220 | return 0; | 206 | return 0; |
221 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 207 | pos = pci_pcie_cap(dev); |
222 | if (!pos) | 208 | if (!pos) |
223 | return 0; | 209 | return 0; |
224 | /* Check if AER is enabled */ | 210 | /* Check if AER is enabled */ |
@@ -431,10 +417,9 @@ static int find_aer_service_iter(struct device *device, void *data) | |||
431 | result = (struct find_aer_service_data *) data; | 417 | result = (struct find_aer_service_data *) data; |
432 | 418 | ||
433 | if (device->bus == &pcie_port_bus_type) { | 419 | if (device->bus == &pcie_port_bus_type) { |
434 | struct pcie_port_data *port_data; | 420 | struct pcie_device *pcie = to_pcie_device(device); |
435 | 421 | ||
436 | port_data = pci_get_drvdata(to_pcie_device(device)->port); | 422 | if (pcie->port->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) |
437 | if (port_data->port_type == PCIE_SW_DOWNSTREAM_PORT) | ||
438 | result->is_downstream = 1; | 423 | result->is_downstream = 1; |
439 | 424 | ||
440 | driver = device->driver; | 425 | driver = device->driver; |
@@ -603,7 +588,7 @@ static void handle_error_source(struct pcie_device *aerdev, | |||
603 | * aer_enable_rootport - enable Root Port's interrupts when receiving messages | 588 | * aer_enable_rootport - enable Root Port's interrupts when receiving messages |
604 | * @rpc: pointer to a Root Port data structure | 589 | * @rpc: pointer to a Root Port data structure |
605 | * | 590 | * |
606 | * Invoked when PCIE bus loads AER service driver. | 591 | * Invoked when PCIe bus loads AER service driver. |
607 | */ | 592 | */ |
608 | void aer_enable_rootport(struct aer_rpc *rpc) | 593 | void aer_enable_rootport(struct aer_rpc *rpc) |
609 | { | 594 | { |
@@ -612,8 +597,8 @@ void aer_enable_rootport(struct aer_rpc *rpc) | |||
612 | u16 reg16; | 597 | u16 reg16; |
613 | u32 reg32; | 598 | u32 reg32; |
614 | 599 | ||
615 | pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); | 600 | pos = pci_pcie_cap(pdev); |
616 | /* Clear PCIE Capability's Device Status */ | 601 | /* Clear PCIe Capability's Device Status */ |
617 | pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, ®16); | 602 | pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, ®16); |
618 | pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16); | 603 | pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16); |
619 | 604 | ||
@@ -647,7 +632,7 @@ void aer_enable_rootport(struct aer_rpc *rpc) | |||
647 | * disable_root_aer - disable Root Port's interrupts when receiving messages | 632 | * disable_root_aer - disable Root Port's interrupts when receiving messages |
648 | * @rpc: pointer to a Root Port data structure | 633 | * @rpc: pointer to a Root Port data structure |
649 | * | 634 | * |
650 | * Invoked when PCIE bus unloads AER service driver. | 635 | * Invoked when PCIe bus unloads AER service driver. |
651 | */ | 636 | */ |
652 | static void disable_root_aer(struct aer_rpc *rpc) | 637 | static void disable_root_aer(struct aer_rpc *rpc) |
653 | { | 638 | { |
@@ -874,8 +859,22 @@ void aer_delete_rootport(struct aer_rpc *rpc) | |||
874 | */ | 859 | */ |
875 | int aer_init(struct pcie_device *dev) | 860 | int aer_init(struct pcie_device *dev) |
876 | { | 861 | { |
877 | if (aer_osc_setup(dev) && !forceload) | 862 | if (dev->port->aer_firmware_first) { |
878 | return -ENXIO; | 863 | dev_printk(KERN_DEBUG, &dev->device, |
864 | "PCIe errors handled by platform firmware.\n"); | ||
865 | goto out; | ||
866 | } | ||
867 | |||
868 | if (aer_osc_setup(dev)) | ||
869 | goto out; | ||
879 | 870 | ||
880 | return 0; | 871 | return 0; |
872 | out: | ||
873 | if (forceload) { | ||
874 | dev_printk(KERN_DEBUG, &dev->device, | ||
875 | "aerdrv forceload requested.\n"); | ||
876 | dev->port->aer_firmware_first = 0; | ||
877 | return 0; | ||
878 | } | ||
879 | return -ENXIO; | ||
881 | } | 880 | } |
diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c b/drivers/pci/pcie/aer/aerdrv_errprint.c index 44acde72294f..9d3e4c8d0184 100644 --- a/drivers/pci/pcie/aer/aerdrv_errprint.c +++ b/drivers/pci/pcie/aer/aerdrv_errprint.c | |||
@@ -184,7 +184,7 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info) | |||
184 | 184 | ||
185 | if (info->status == 0) { | 185 | if (info->status == 0) { |
186 | AER_PR(info, dev, | 186 | AER_PR(info, dev, |
187 | "PCIE Bus Error: severity=%s, type=Unaccessible, " | 187 | "PCIe Bus Error: severity=%s, type=Unaccessible, " |
188 | "id=%04x(Unregistered Agent ID)\n", | 188 | "id=%04x(Unregistered Agent ID)\n", |
189 | aer_error_severity_string[info->severity], id); | 189 | aer_error_severity_string[info->severity], id); |
190 | } else { | 190 | } else { |
@@ -194,7 +194,7 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info) | |||
194 | agent = AER_GET_AGENT(info->severity, info->status); | 194 | agent = AER_GET_AGENT(info->severity, info->status); |
195 | 195 | ||
196 | AER_PR(info, dev, | 196 | AER_PR(info, dev, |
197 | "PCIE Bus Error: severity=%s, type=%s, id=%04x(%s)\n", | 197 | "PCIe Bus Error: severity=%s, type=%s, id=%04x(%s)\n", |
198 | aer_error_severity_string[info->severity], | 198 | aer_error_severity_string[info->severity], |
199 | aer_error_layer[layer], id, aer_agent_string[agent]); | 199 | aer_error_layer[layer], id, aer_agent_string[agent]); |
200 | 200 | ||
diff --git a/drivers/pci/pcie/aer/ecrc.c b/drivers/pci/pcie/aer/ecrc.c index a928d8ab6bda..a2747a663bc9 100644 --- a/drivers/pci/pcie/aer/ecrc.c +++ b/drivers/pci/pcie/aer/ecrc.c | |||
@@ -51,7 +51,7 @@ static int enable_ecrc_checking(struct pci_dev *dev) | |||
51 | int pos; | 51 | int pos; |
52 | u32 reg32; | 52 | u32 reg32; |
53 | 53 | ||
54 | if (!dev->is_pcie) | 54 | if (!pci_is_pcie(dev)) |
55 | return -ENODEV; | 55 | return -ENODEV; |
56 | 56 | ||
57 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | 57 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
@@ -79,7 +79,7 @@ static int disable_ecrc_checking(struct pci_dev *dev) | |||
79 | int pos; | 79 | int pos; |
80 | u32 reg32; | 80 | u32 reg32; |
81 | 81 | ||
82 | if (!dev->is_pcie) | 82 | if (!pci_is_pcie(dev)) |
83 | return -ENODEV; | 83 | return -ENODEV; |
84 | 84 | ||
85 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | 85 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 5b7056cec00c..be53d98fa384 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * File: drivers/pci/pcie/aspm.c | 2 | * File: drivers/pci/pcie/aspm.c |
3 | * Enabling PCIE link L0s/L1 state and Clock Power Management | 3 | * Enabling PCIe link L0s/L1 state and Clock Power Management |
4 | * | 4 | * |
5 | * Copyright (C) 2007 Intel | 5 | * Copyright (C) 2007 Intel |
6 | * Copyright (C) Zhang Yanmin (yanmin.zhang@intel.com) | 6 | * Copyright (C) Zhang Yanmin (yanmin.zhang@intel.com) |
@@ -122,7 +122,7 @@ static void pcie_set_clkpm_nocheck(struct pcie_link_state *link, int enable) | |||
122 | struct pci_bus *linkbus = link->pdev->subordinate; | 122 | struct pci_bus *linkbus = link->pdev->subordinate; |
123 | 123 | ||
124 | list_for_each_entry(child, &linkbus->devices, bus_list) { | 124 | list_for_each_entry(child, &linkbus->devices, bus_list) { |
125 | pos = pci_find_capability(child, PCI_CAP_ID_EXP); | 125 | pos = pci_pcie_cap(child); |
126 | if (!pos) | 126 | if (!pos) |
127 | return; | 127 | return; |
128 | pci_read_config_word(child, pos + PCI_EXP_LNKCTL, ®16); | 128 | pci_read_config_word(child, pos + PCI_EXP_LNKCTL, ®16); |
@@ -156,7 +156,7 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist) | |||
156 | 156 | ||
157 | /* All functions should have the same cap and state, take the worst */ | 157 | /* All functions should have the same cap and state, take the worst */ |
158 | list_for_each_entry(child, &linkbus->devices, bus_list) { | 158 | list_for_each_entry(child, &linkbus->devices, bus_list) { |
159 | pos = pci_find_capability(child, PCI_CAP_ID_EXP); | 159 | pos = pci_pcie_cap(child); |
160 | if (!pos) | 160 | if (!pos) |
161 | return; | 161 | return; |
162 | pci_read_config_dword(child, pos + PCI_EXP_LNKCAP, ®32); | 162 | pci_read_config_dword(child, pos + PCI_EXP_LNKCAP, ®32); |
@@ -191,23 +191,23 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) | |||
191 | * Configuration, so just check one function | 191 | * Configuration, so just check one function |
192 | */ | 192 | */ |
193 | child = list_entry(linkbus->devices.next, struct pci_dev, bus_list); | 193 | child = list_entry(linkbus->devices.next, struct pci_dev, bus_list); |
194 | BUG_ON(!child->is_pcie); | 194 | BUG_ON(!pci_is_pcie(child)); |
195 | 195 | ||
196 | /* Check downstream component if bit Slot Clock Configuration is 1 */ | 196 | /* Check downstream component if bit Slot Clock Configuration is 1 */ |
197 | cpos = pci_find_capability(child, PCI_CAP_ID_EXP); | 197 | cpos = pci_pcie_cap(child); |
198 | pci_read_config_word(child, cpos + PCI_EXP_LNKSTA, ®16); | 198 | pci_read_config_word(child, cpos + PCI_EXP_LNKSTA, ®16); |
199 | if (!(reg16 & PCI_EXP_LNKSTA_SLC)) | 199 | if (!(reg16 & PCI_EXP_LNKSTA_SLC)) |
200 | same_clock = 0; | 200 | same_clock = 0; |
201 | 201 | ||
202 | /* Check upstream component if bit Slot Clock Configuration is 1 */ | 202 | /* Check upstream component if bit Slot Clock Configuration is 1 */ |
203 | ppos = pci_find_capability(parent, PCI_CAP_ID_EXP); | 203 | ppos = pci_pcie_cap(parent); |
204 | pci_read_config_word(parent, ppos + PCI_EXP_LNKSTA, ®16); | 204 | pci_read_config_word(parent, ppos + PCI_EXP_LNKSTA, ®16); |
205 | if (!(reg16 & PCI_EXP_LNKSTA_SLC)) | 205 | if (!(reg16 & PCI_EXP_LNKSTA_SLC)) |
206 | same_clock = 0; | 206 | same_clock = 0; |
207 | 207 | ||
208 | /* Configure downstream component, all functions */ | 208 | /* Configure downstream component, all functions */ |
209 | list_for_each_entry(child, &linkbus->devices, bus_list) { | 209 | list_for_each_entry(child, &linkbus->devices, bus_list) { |
210 | cpos = pci_find_capability(child, PCI_CAP_ID_EXP); | 210 | cpos = pci_pcie_cap(child); |
211 | pci_read_config_word(child, cpos + PCI_EXP_LNKCTL, ®16); | 211 | pci_read_config_word(child, cpos + PCI_EXP_LNKCTL, ®16); |
212 | child_reg[PCI_FUNC(child->devfn)] = reg16; | 212 | child_reg[PCI_FUNC(child->devfn)] = reg16; |
213 | if (same_clock) | 213 | if (same_clock) |
@@ -247,7 +247,7 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) | |||
247 | dev_printk(KERN_ERR, &parent->dev, | 247 | dev_printk(KERN_ERR, &parent->dev, |
248 | "ASPM: Could not configure common clock\n"); | 248 | "ASPM: Could not configure common clock\n"); |
249 | list_for_each_entry(child, &linkbus->devices, bus_list) { | 249 | list_for_each_entry(child, &linkbus->devices, bus_list) { |
250 | cpos = pci_find_capability(child, PCI_CAP_ID_EXP); | 250 | cpos = pci_pcie_cap(child); |
251 | pci_write_config_word(child, cpos + PCI_EXP_LNKCTL, | 251 | pci_write_config_word(child, cpos + PCI_EXP_LNKCTL, |
252 | child_reg[PCI_FUNC(child->devfn)]); | 252 | child_reg[PCI_FUNC(child->devfn)]); |
253 | } | 253 | } |
@@ -300,7 +300,7 @@ static void pcie_get_aspm_reg(struct pci_dev *pdev, | |||
300 | u16 reg16; | 300 | u16 reg16; |
301 | u32 reg32; | 301 | u32 reg32; |
302 | 302 | ||
303 | pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); | 303 | pos = pci_pcie_cap(pdev); |
304 | pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, ®32); | 304 | pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, ®32); |
305 | info->support = (reg32 & PCI_EXP_LNKCAP_ASPMS) >> 10; | 305 | info->support = (reg32 & PCI_EXP_LNKCAP_ASPMS) >> 10; |
306 | info->latency_encoding_l0s = (reg32 & PCI_EXP_LNKCAP_L0SEL) >> 12; | 306 | info->latency_encoding_l0s = (reg32 & PCI_EXP_LNKCAP_L0SEL) >> 12; |
@@ -420,7 +420,7 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) | |||
420 | child->pcie_type != PCI_EXP_TYPE_LEG_END) | 420 | child->pcie_type != PCI_EXP_TYPE_LEG_END) |
421 | continue; | 421 | continue; |
422 | 422 | ||
423 | pos = pci_find_capability(child, PCI_CAP_ID_EXP); | 423 | pos = pci_pcie_cap(child); |
424 | pci_read_config_dword(child, pos + PCI_EXP_DEVCAP, ®32); | 424 | pci_read_config_dword(child, pos + PCI_EXP_DEVCAP, ®32); |
425 | /* Calculate endpoint L0s acceptable latency */ | 425 | /* Calculate endpoint L0s acceptable latency */ |
426 | encoding = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6; | 426 | encoding = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6; |
@@ -436,7 +436,7 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) | |||
436 | static void pcie_config_aspm_dev(struct pci_dev *pdev, u32 val) | 436 | static void pcie_config_aspm_dev(struct pci_dev *pdev, u32 val) |
437 | { | 437 | { |
438 | u16 reg16; | 438 | u16 reg16; |
439 | int pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); | 439 | int pos = pci_pcie_cap(pdev); |
440 | 440 | ||
441 | pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, ®16); | 441 | pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, ®16); |
442 | reg16 &= ~0x3; | 442 | reg16 &= ~0x3; |
@@ -499,11 +499,11 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) | |||
499 | int pos; | 499 | int pos; |
500 | u32 reg32; | 500 | u32 reg32; |
501 | /* | 501 | /* |
502 | * Some functions in a slot might not all be PCIE functions, | 502 | * Some functions in a slot might not all be PCIe functions, |
503 | * very strange. Disable ASPM for the whole slot | 503 | * very strange. Disable ASPM for the whole slot |
504 | */ | 504 | */ |
505 | list_for_each_entry(child, &pdev->subordinate->devices, bus_list) { | 505 | list_for_each_entry(child, &pdev->subordinate->devices, bus_list) { |
506 | pos = pci_find_capability(child, PCI_CAP_ID_EXP); | 506 | pos = pci_pcie_cap(child); |
507 | if (!pos) | 507 | if (!pos) |
508 | return -EINVAL; | 508 | return -EINVAL; |
509 | /* | 509 | /* |
@@ -563,7 +563,7 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev) | |||
563 | struct pcie_link_state *link; | 563 | struct pcie_link_state *link; |
564 | int blacklist = !!pcie_aspm_sanity_check(pdev); | 564 | int blacklist = !!pcie_aspm_sanity_check(pdev); |
565 | 565 | ||
566 | if (aspm_disabled || !pdev->is_pcie || pdev->link_state) | 566 | if (aspm_disabled || !pci_is_pcie(pdev) || pdev->link_state) |
567 | return; | 567 | return; |
568 | if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && | 568 | if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && |
569 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) | 569 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) |
@@ -629,7 +629,8 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev) | |||
629 | struct pci_dev *parent = pdev->bus->self; | 629 | struct pci_dev *parent = pdev->bus->self; |
630 | struct pcie_link_state *link, *root, *parent_link; | 630 | struct pcie_link_state *link, *root, *parent_link; |
631 | 631 | ||
632 | if (aspm_disabled || !pdev->is_pcie || !parent || !parent->link_state) | 632 | if (aspm_disabled || !pci_is_pcie(pdev) || |
633 | !parent || !parent->link_state) | ||
633 | return; | 634 | return; |
634 | if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && | 635 | if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && |
635 | (parent->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)) | 636 | (parent->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)) |
@@ -670,7 +671,7 @@ void pcie_aspm_pm_state_change(struct pci_dev *pdev) | |||
670 | { | 671 | { |
671 | struct pcie_link_state *link = pdev->link_state; | 672 | struct pcie_link_state *link = pdev->link_state; |
672 | 673 | ||
673 | if (aspm_disabled || !pdev->is_pcie || !link) | 674 | if (aspm_disabled || !pci_is_pcie(pdev) || !link) |
674 | return; | 675 | return; |
675 | if ((pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && | 676 | if ((pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && |
676 | (pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)) | 677 | (pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)) |
@@ -696,7 +697,7 @@ void pci_disable_link_state(struct pci_dev *pdev, int state) | |||
696 | struct pci_dev *parent = pdev->bus->self; | 697 | struct pci_dev *parent = pdev->bus->self; |
697 | struct pcie_link_state *link; | 698 | struct pcie_link_state *link; |
698 | 699 | ||
699 | if (aspm_disabled || !pdev->is_pcie) | 700 | if (aspm_disabled || !pci_is_pcie(pdev)) |
700 | return; | 701 | return; |
701 | if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT || | 702 | if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT || |
702 | pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) | 703 | pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) |
@@ -841,8 +842,9 @@ void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev) | |||
841 | { | 842 | { |
842 | struct pcie_link_state *link_state = pdev->link_state; | 843 | struct pcie_link_state *link_state = pdev->link_state; |
843 | 844 | ||
844 | if (!pdev->is_pcie || (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && | 845 | if (!pci_is_pcie(pdev) || |
845 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state) | 846 | (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && |
847 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state) | ||
846 | return; | 848 | return; |
847 | 849 | ||
848 | if (link_state->aspm_support) | 850 | if (link_state->aspm_support) |
@@ -857,8 +859,9 @@ void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev) | |||
857 | { | 859 | { |
858 | struct pcie_link_state *link_state = pdev->link_state; | 860 | struct pcie_link_state *link_state = pdev->link_state; |
859 | 861 | ||
860 | if (!pdev->is_pcie || (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && | 862 | if (!pci_is_pcie(pdev) || |
861 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state) | 863 | (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && |
864 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state) | ||
862 | return; | 865 | return; |
863 | 866 | ||
864 | if (link_state->aspm_support) | 867 | if (link_state->aspm_support) |
diff --git a/drivers/pci/pcie/pme/Makefile b/drivers/pci/pcie/pme/Makefile new file mode 100644 index 000000000000..8b9238053080 --- /dev/null +++ b/drivers/pci/pcie/pme/Makefile | |||
@@ -0,0 +1,8 @@ | |||
1 | # | ||
2 | # Makefile for PCI-Express Root Port PME signaling driver | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_PCIE_PME) += pmedriver.o | ||
6 | |||
7 | pmedriver-objs := pcie_pme.o | ||
8 | pmedriver-$(CONFIG_ACPI) += pcie_pme_acpi.o | ||
diff --git a/drivers/pci/pcie/pme/pcie_pme.c b/drivers/pci/pcie/pme/pcie_pme.c new file mode 100644 index 000000000000..aac285a16b62 --- /dev/null +++ b/drivers/pci/pcie/pme/pcie_pme.c | |||
@@ -0,0 +1,506 @@ | |||
1 | /* | ||
2 | * PCIe Native PME support | ||
3 | * | ||
4 | * Copyright (C) 2007 - 2009 Intel Corp | ||
5 | * Copyright (C) 2007 - 2009 Shaohua Li <shaohua.li@intel.com> | ||
6 | * Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc. | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General Public | ||
9 | * License V2. See the file "COPYING" in the main directory of this archive | ||
10 | * for more details. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/pci.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/errno.h> | ||
17 | #include <linux/slab.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/device.h> | ||
21 | #include <linux/pcieport_if.h> | ||
22 | #include <linux/acpi.h> | ||
23 | #include <linux/pci-acpi.h> | ||
24 | #include <linux/pm_runtime.h> | ||
25 | |||
26 | #include "../../pci.h" | ||
27 | #include "pcie_pme.h" | ||
28 | |||
29 | #define PCI_EXP_RTSTA_PME 0x10000 /* PME status */ | ||
30 | #define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */ | ||
31 | |||
32 | /* | ||
33 | * If set, this switch will prevent the PCIe root port PME service driver from | ||
34 | * being registered. Consequently, the interrupt-based PCIe PME signaling will | ||
35 | * not be used by any PCIe root ports in that case. | ||
36 | */ | ||
37 | static bool pcie_pme_disabled; | ||
38 | |||
39 | /* | ||
40 | * The PCI Express Base Specification 2.0, Section 6.1.8, states the following: | ||
41 | * "In order to maintain compatibility with non-PCI Express-aware system | ||
42 | * software, system power management logic must be configured by firmware to use | ||
43 | * the legacy mechanism of signaling PME by default. PCI Express-aware system | ||
44 | * software must notify the firmware prior to enabling native, interrupt-based | ||
45 | * PME signaling." However, if the platform doesn't provide us with a suitable | ||
46 | * notification mechanism or the notification fails, it is not clear whether or | ||
47 | * not we are supposed to use the interrupt-based PCIe PME signaling. The | ||
48 | * switch below can be used to indicate the desired behaviour. When set, it | ||
49 | * will make the kernel use the interrupt-based PCIe PME signaling regardless of | ||
50 | * the platform notification status, although the kernel will attempt to notify | ||
51 | * the platform anyway. When unset, it will prevent the kernel from using the | ||
52 | * the interrupt-based PCIe PME signaling if the platform notification fails, | ||
53 | * which is the default. | ||
54 | */ | ||
55 | static bool pcie_pme_force_enable; | ||
56 | |||
57 | /* | ||
58 | * If this switch is set, MSI will not be used for PCIe PME signaling. This | ||
59 | * causes the PCIe port driver to use INTx interrupts only, but it turns out | ||
60 | * that using MSI for PCIe PME signaling doesn't play well with PCIe PME-based | ||
61 | * wake-up from system sleep states. | ||
62 | */ | ||
63 | bool pcie_pme_msi_disabled; | ||
64 | |||
65 | static int __init pcie_pme_setup(char *str) | ||
66 | { | ||
67 | if (!strcmp(str, "off")) | ||
68 | pcie_pme_disabled = true; | ||
69 | else if (!strcmp(str, "force")) | ||
70 | pcie_pme_force_enable = true; | ||
71 | else if (!strcmp(str, "nomsi")) | ||
72 | pcie_pme_msi_disabled = true; | ||
73 | return 1; | ||
74 | } | ||
75 | __setup("pcie_pme=", pcie_pme_setup); | ||
76 | |||
77 | /** | ||
78 | * pcie_pme_platform_setup - Ensure that the kernel controls the PCIe PME. | ||
79 | * @srv: PCIe PME root port service to use for carrying out the check. | ||
80 | * | ||
81 | * Notify the platform that the native PCIe PME is going to be used and return | ||
82 | * 'true' if the control of the PCIe PME registers has been acquired from the | ||
83 | * platform. | ||
84 | */ | ||
85 | static bool pcie_pme_platform_setup(struct pcie_device *srv) | ||
86 | { | ||
87 | if (!pcie_pme_platform_notify(srv)) | ||
88 | return true; | ||
89 | return pcie_pme_force_enable; | ||
90 | } | ||
91 | |||
92 | struct pcie_pme_service_data { | ||
93 | spinlock_t lock; | ||
94 | struct pcie_device *srv; | ||
95 | struct work_struct work; | ||
96 | bool noirq; /* Don't enable the PME interrupt used by this service. */ | ||
97 | }; | ||
98 | |||
99 | /** | ||
100 | * pcie_pme_interrupt_enable - Enable/disable PCIe PME interrupt generation. | ||
101 | * @dev: PCIe root port or event collector. | ||
102 | * @enable: Enable or disable the interrupt. | ||
103 | */ | ||
104 | static void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable) | ||
105 | { | ||
106 | int rtctl_pos; | ||
107 | u16 rtctl; | ||
108 | |||
109 | rtctl_pos = pci_pcie_cap(dev) + PCI_EXP_RTCTL; | ||
110 | |||
111 | pci_read_config_word(dev, rtctl_pos, &rtctl); | ||
112 | if (enable) | ||
113 | rtctl |= PCI_EXP_RTCTL_PMEIE; | ||
114 | else | ||
115 | rtctl &= ~PCI_EXP_RTCTL_PMEIE; | ||
116 | pci_write_config_word(dev, rtctl_pos, rtctl); | ||
117 | } | ||
118 | |||
119 | /** | ||
120 | * pcie_pme_clear_status - Clear root port PME interrupt status. | ||
121 | * @dev: PCIe root port or event collector. | ||
122 | */ | ||
123 | static void pcie_pme_clear_status(struct pci_dev *dev) | ||
124 | { | ||
125 | int rtsta_pos; | ||
126 | u32 rtsta; | ||
127 | |||
128 | rtsta_pos = pci_pcie_cap(dev) + PCI_EXP_RTSTA; | ||
129 | |||
130 | pci_read_config_dword(dev, rtsta_pos, &rtsta); | ||
131 | rtsta |= PCI_EXP_RTSTA_PME; | ||
132 | pci_write_config_dword(dev, rtsta_pos, rtsta); | ||
133 | } | ||
134 | |||
135 | /** | ||
136 | * pcie_pme_walk_bus - Scan a PCI bus for devices asserting PME#. | ||
137 | * @bus: PCI bus to scan. | ||
138 | * | ||
139 | * Scan given PCI bus and all buses under it for devices asserting PME#. | ||
140 | */ | ||
141 | static bool pcie_pme_walk_bus(struct pci_bus *bus) | ||
142 | { | ||
143 | struct pci_dev *dev; | ||
144 | bool ret = false; | ||
145 | |||
146 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
147 | /* Skip PCIe devices in case we started from a root port. */ | ||
148 | if (!pci_is_pcie(dev) && pci_check_pme_status(dev)) { | ||
149 | pm_request_resume(&dev->dev); | ||
150 | ret = true; | ||
151 | } | ||
152 | |||
153 | if (dev->subordinate && pcie_pme_walk_bus(dev->subordinate)) | ||
154 | ret = true; | ||
155 | } | ||
156 | |||
157 | return ret; | ||
158 | } | ||
159 | |||
160 | /** | ||
161 | * pcie_pme_from_pci_bridge - Check if PCIe-PCI bridge generated a PME. | ||
162 | * @bus: Secondary bus of the bridge. | ||
163 | * @devfn: Device/function number to check. | ||
164 | * | ||
165 | * PME from PCI devices under a PCIe-PCI bridge may be converted to an in-band | ||
166 | * PCIe PME message. In such that case the bridge should use the Requester ID | ||
167 | * of device/function number 0 on its secondary bus. | ||
168 | */ | ||
169 | static bool pcie_pme_from_pci_bridge(struct pci_bus *bus, u8 devfn) | ||
170 | { | ||
171 | struct pci_dev *dev; | ||
172 | bool found = false; | ||
173 | |||
174 | if (devfn) | ||
175 | return false; | ||
176 | |||
177 | dev = pci_dev_get(bus->self); | ||
178 | if (!dev) | ||
179 | return false; | ||
180 | |||
181 | if (pci_is_pcie(dev) && dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) { | ||
182 | down_read(&pci_bus_sem); | ||
183 | if (pcie_pme_walk_bus(bus)) | ||
184 | found = true; | ||
185 | up_read(&pci_bus_sem); | ||
186 | } | ||
187 | |||
188 | pci_dev_put(dev); | ||
189 | return found; | ||
190 | } | ||
191 | |||
192 | /** | ||
193 | * pcie_pme_handle_request - Find device that generated PME and handle it. | ||
194 | * @port: Root port or event collector that generated the PME interrupt. | ||
195 | * @req_id: PCIe Requester ID of the device that generated the PME. | ||
196 | */ | ||
197 | static void pcie_pme_handle_request(struct pci_dev *port, u16 req_id) | ||
198 | { | ||
199 | u8 busnr = req_id >> 8, devfn = req_id & 0xff; | ||
200 | struct pci_bus *bus; | ||
201 | struct pci_dev *dev; | ||
202 | bool found = false; | ||
203 | |||
204 | /* First, check if the PME is from the root port itself. */ | ||
205 | if (port->devfn == devfn && port->bus->number == busnr) { | ||
206 | if (pci_check_pme_status(port)) { | ||
207 | pm_request_resume(&port->dev); | ||
208 | found = true; | ||
209 | } else { | ||
210 | /* | ||
211 | * Apparently, the root port generated the PME on behalf | ||
212 | * of a non-PCIe device downstream. If this is done by | ||
213 | * a root port, the Requester ID field in its status | ||
214 | * register may contain either the root port's, or the | ||
215 | * source device's information (PCI Express Base | ||
216 | * Specification, Rev. 2.0, Section 6.1.9). | ||
217 | */ | ||
218 | down_read(&pci_bus_sem); | ||
219 | found = pcie_pme_walk_bus(port->subordinate); | ||
220 | up_read(&pci_bus_sem); | ||
221 | } | ||
222 | goto out; | ||
223 | } | ||
224 | |||
225 | /* Second, find the bus the source device is on. */ | ||
226 | bus = pci_find_bus(pci_domain_nr(port->bus), busnr); | ||
227 | if (!bus) | ||
228 | goto out; | ||
229 | |||
230 | /* Next, check if the PME is from a PCIe-PCI bridge. */ | ||
231 | found = pcie_pme_from_pci_bridge(bus, devfn); | ||
232 | if (found) | ||
233 | goto out; | ||
234 | |||
235 | /* Finally, try to find the PME source on the bus. */ | ||
236 | down_read(&pci_bus_sem); | ||
237 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
238 | pci_dev_get(dev); | ||
239 | if (dev->devfn == devfn) { | ||
240 | found = true; | ||
241 | break; | ||
242 | } | ||
243 | pci_dev_put(dev); | ||
244 | } | ||
245 | up_read(&pci_bus_sem); | ||
246 | |||
247 | if (found) { | ||
248 | /* The device is there, but we have to check its PME status. */ | ||
249 | found = pci_check_pme_status(dev); | ||
250 | if (found) | ||
251 | pm_request_resume(&dev->dev); | ||
252 | pci_dev_put(dev); | ||
253 | } else if (devfn) { | ||
254 | /* | ||
255 | * The device is not there, but we can still try to recover by | ||
256 | * assuming that the PME was reported by a PCIe-PCI bridge that | ||
257 | * used devfn different from zero. | ||
258 | */ | ||
259 | dev_dbg(&port->dev, "PME interrupt generated for " | ||
260 | "non-existent device %02x:%02x.%d\n", | ||
261 | busnr, PCI_SLOT(devfn), PCI_FUNC(devfn)); | ||
262 | found = pcie_pme_from_pci_bridge(bus, 0); | ||
263 | } | ||
264 | |||
265 | out: | ||
266 | if (!found) | ||
267 | dev_dbg(&port->dev, "Spurious native PME interrupt!\n"); | ||
268 | } | ||
269 | |||
270 | /** | ||
271 | * pcie_pme_work_fn - Work handler for PCIe PME interrupt. | ||
272 | * @work: Work structure giving access to service data. | ||
273 | */ | ||
274 | static void pcie_pme_work_fn(struct work_struct *work) | ||
275 | { | ||
276 | struct pcie_pme_service_data *data = | ||
277 | container_of(work, struct pcie_pme_service_data, work); | ||
278 | struct pci_dev *port = data->srv->port; | ||
279 | int rtsta_pos; | ||
280 | u32 rtsta; | ||
281 | |||
282 | rtsta_pos = pci_pcie_cap(port) + PCI_EXP_RTSTA; | ||
283 | |||
284 | spin_lock_irq(&data->lock); | ||
285 | |||
286 | for (;;) { | ||
287 | if (data->noirq) | ||
288 | break; | ||
289 | |||
290 | pci_read_config_dword(port, rtsta_pos, &rtsta); | ||
291 | if (rtsta & PCI_EXP_RTSTA_PME) { | ||
292 | /* | ||
293 | * Clear PME status of the port. If there are other | ||
294 | * pending PMEs, the status will be set again. | ||
295 | */ | ||
296 | pcie_pme_clear_status(port); | ||
297 | |||
298 | spin_unlock_irq(&data->lock); | ||
299 | pcie_pme_handle_request(port, rtsta & 0xffff); | ||
300 | spin_lock_irq(&data->lock); | ||
301 | |||
302 | continue; | ||
303 | } | ||
304 | |||
305 | /* No need to loop if there are no more PMEs pending. */ | ||
306 | if (!(rtsta & PCI_EXP_RTSTA_PENDING)) | ||
307 | break; | ||
308 | |||
309 | spin_unlock_irq(&data->lock); | ||
310 | cpu_relax(); | ||
311 | spin_lock_irq(&data->lock); | ||
312 | } | ||
313 | |||
314 | if (!data->noirq) | ||
315 | pcie_pme_interrupt_enable(port, true); | ||
316 | |||
317 | spin_unlock_irq(&data->lock); | ||
318 | } | ||
319 | |||
320 | /** | ||
321 | * pcie_pme_irq - Interrupt handler for PCIe root port PME interrupt. | ||
322 | * @irq: Interrupt vector. | ||
323 | * @context: Interrupt context pointer. | ||
324 | */ | ||
325 | static irqreturn_t pcie_pme_irq(int irq, void *context) | ||
326 | { | ||
327 | struct pci_dev *port; | ||
328 | struct pcie_pme_service_data *data; | ||
329 | int rtsta_pos; | ||
330 | u32 rtsta; | ||
331 | unsigned long flags; | ||
332 | |||
333 | port = ((struct pcie_device *)context)->port; | ||
334 | data = get_service_data((struct pcie_device *)context); | ||
335 | |||
336 | rtsta_pos = pci_pcie_cap(port) + PCI_EXP_RTSTA; | ||
337 | |||
338 | spin_lock_irqsave(&data->lock, flags); | ||
339 | pci_read_config_dword(port, rtsta_pos, &rtsta); | ||
340 | |||
341 | if (!(rtsta & PCI_EXP_RTSTA_PME)) { | ||
342 | spin_unlock_irqrestore(&data->lock, flags); | ||
343 | return IRQ_NONE; | ||
344 | } | ||
345 | |||
346 | pcie_pme_interrupt_enable(port, false); | ||
347 | spin_unlock_irqrestore(&data->lock, flags); | ||
348 | |||
349 | /* We don't use pm_wq, because it's freezable. */ | ||
350 | schedule_work(&data->work); | ||
351 | |||
352 | return IRQ_HANDLED; | ||
353 | } | ||
354 | |||
355 | /** | ||
356 | * pcie_pme_set_native - Set the PME interrupt flag for given device. | ||
357 | * @dev: PCI device to handle. | ||
358 | * @ign: Ignored. | ||
359 | */ | ||
360 | static int pcie_pme_set_native(struct pci_dev *dev, void *ign) | ||
361 | { | ||
362 | dev_info(&dev->dev, "Signaling PME through PCIe PME interrupt\n"); | ||
363 | |||
364 | device_set_run_wake(&dev->dev, true); | ||
365 | dev->pme_interrupt = true; | ||
366 | return 0; | ||
367 | } | ||
368 | |||
369 | /** | ||
370 | * pcie_pme_mark_devices - Set the PME interrupt flag for devices below a port. | ||
371 | * @port: PCIe root port or event collector to handle. | ||
372 | * | ||
373 | * For each device below given root port, including the port itself (or for each | ||
374 | * root complex integrated endpoint if @port is a root complex event collector) | ||
375 | * set the flag indicating that it can signal run-time wake-up events via PCIe | ||
376 | * PME interrupts. | ||
377 | */ | ||
378 | static void pcie_pme_mark_devices(struct pci_dev *port) | ||
379 | { | ||
380 | pcie_pme_set_native(port, NULL); | ||
381 | if (port->subordinate) { | ||
382 | pci_walk_bus(port->subordinate, pcie_pme_set_native, NULL); | ||
383 | } else { | ||
384 | struct pci_bus *bus = port->bus; | ||
385 | struct pci_dev *dev; | ||
386 | |||
387 | /* Check if this is a root port event collector. */ | ||
388 | if (port->pcie_type != PCI_EXP_TYPE_RC_EC || !bus) | ||
389 | return; | ||
390 | |||
391 | down_read(&pci_bus_sem); | ||
392 | list_for_each_entry(dev, &bus->devices, bus_list) | ||
393 | if (pci_is_pcie(dev) | ||
394 | && dev->pcie_type == PCI_EXP_TYPE_RC_END) | ||
395 | pcie_pme_set_native(dev, NULL); | ||
396 | up_read(&pci_bus_sem); | ||
397 | } | ||
398 | } | ||
399 | |||
400 | /** | ||
401 | * pcie_pme_probe - Initialize PCIe PME service for given root port. | ||
402 | * @srv: PCIe service to initialize. | ||
403 | */ | ||
404 | static int pcie_pme_probe(struct pcie_device *srv) | ||
405 | { | ||
406 | struct pci_dev *port; | ||
407 | struct pcie_pme_service_data *data; | ||
408 | int ret; | ||
409 | |||
410 | if (!pcie_pme_platform_setup(srv)) | ||
411 | return -EACCES; | ||
412 | |||
413 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
414 | if (!data) | ||
415 | return -ENOMEM; | ||
416 | |||
417 | spin_lock_init(&data->lock); | ||
418 | INIT_WORK(&data->work, pcie_pme_work_fn); | ||
419 | data->srv = srv; | ||
420 | set_service_data(srv, data); | ||
421 | |||
422 | port = srv->port; | ||
423 | pcie_pme_interrupt_enable(port, false); | ||
424 | pcie_pme_clear_status(port); | ||
425 | |||
426 | ret = request_irq(srv->irq, pcie_pme_irq, IRQF_SHARED, "PCIe PME", srv); | ||
427 | if (ret) { | ||
428 | kfree(data); | ||
429 | } else { | ||
430 | pcie_pme_mark_devices(port); | ||
431 | pcie_pme_interrupt_enable(port, true); | ||
432 | } | ||
433 | |||
434 | return ret; | ||
435 | } | ||
436 | |||
437 | /** | ||
438 | * pcie_pme_suspend - Suspend PCIe PME service device. | ||
439 | * @srv: PCIe service device to suspend. | ||
440 | */ | ||
441 | static int pcie_pme_suspend(struct pcie_device *srv) | ||
442 | { | ||
443 | struct pcie_pme_service_data *data = get_service_data(srv); | ||
444 | struct pci_dev *port = srv->port; | ||
445 | |||
446 | spin_lock_irq(&data->lock); | ||
447 | pcie_pme_interrupt_enable(port, false); | ||
448 | pcie_pme_clear_status(port); | ||
449 | data->noirq = true; | ||
450 | spin_unlock_irq(&data->lock); | ||
451 | |||
452 | synchronize_irq(srv->irq); | ||
453 | |||
454 | return 0; | ||
455 | } | ||
456 | |||
457 | /** | ||
458 | * pcie_pme_resume - Resume PCIe PME service device. | ||
459 | * @srv - PCIe service device to resume. | ||
460 | */ | ||
461 | static int pcie_pme_resume(struct pcie_device *srv) | ||
462 | { | ||
463 | struct pcie_pme_service_data *data = get_service_data(srv); | ||
464 | struct pci_dev *port = srv->port; | ||
465 | |||
466 | spin_lock_irq(&data->lock); | ||
467 | data->noirq = false; | ||
468 | pcie_pme_clear_status(port); | ||
469 | pcie_pme_interrupt_enable(port, true); | ||
470 | spin_unlock_irq(&data->lock); | ||
471 | |||
472 | return 0; | ||
473 | } | ||
474 | |||
475 | /** | ||
476 | * pcie_pme_remove - Prepare PCIe PME service device for removal. | ||
477 | * @srv - PCIe service device to resume. | ||
478 | */ | ||
479 | static void pcie_pme_remove(struct pcie_device *srv) | ||
480 | { | ||
481 | pcie_pme_suspend(srv); | ||
482 | free_irq(srv->irq, srv); | ||
483 | kfree(get_service_data(srv)); | ||
484 | } | ||
485 | |||
486 | static struct pcie_port_service_driver pcie_pme_driver = { | ||
487 | .name = "pcie_pme", | ||
488 | .port_type = PCI_EXP_TYPE_ROOT_PORT, | ||
489 | .service = PCIE_PORT_SERVICE_PME, | ||
490 | |||
491 | .probe = pcie_pme_probe, | ||
492 | .suspend = pcie_pme_suspend, | ||
493 | .resume = pcie_pme_resume, | ||
494 | .remove = pcie_pme_remove, | ||
495 | }; | ||
496 | |||
497 | /** | ||
498 | * pcie_pme_service_init - Register the PCIe PME service driver. | ||
499 | */ | ||
500 | static int __init pcie_pme_service_init(void) | ||
501 | { | ||
502 | return pcie_pme_disabled ? | ||
503 | -ENODEV : pcie_port_service_register(&pcie_pme_driver); | ||
504 | } | ||
505 | |||
506 | module_init(pcie_pme_service_init); | ||
diff --git a/drivers/pci/pcie/pme/pcie_pme.h b/drivers/pci/pcie/pme/pcie_pme.h new file mode 100644 index 000000000000..b30d2b7c9775 --- /dev/null +++ b/drivers/pci/pcie/pme/pcie_pme.h | |||
@@ -0,0 +1,28 @@ | |||
1 | /* | ||
2 | * drivers/pci/pcie/pme/pcie_pme.h | ||
3 | * | ||
4 | * PCI Express Root Port PME signaling support | ||
5 | * | ||
6 | * Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc. | ||
7 | */ | ||
8 | |||
9 | #ifndef _PCIE_PME_H_ | ||
10 | #define _PCIE_PME_H_ | ||
11 | |||
12 | struct pcie_device; | ||
13 | |||
14 | #ifdef CONFIG_ACPI | ||
15 | extern int pcie_pme_acpi_setup(struct pcie_device *srv); | ||
16 | |||
17 | static inline int pcie_pme_platform_notify(struct pcie_device *srv) | ||
18 | { | ||
19 | return pcie_pme_acpi_setup(srv); | ||
20 | } | ||
21 | #else /* !CONFIG_ACPI */ | ||
22 | static inline int pcie_pme_platform_notify(struct pcie_device *srv) | ||
23 | { | ||
24 | return 0; | ||
25 | } | ||
26 | #endif /* !CONFIG_ACPI */ | ||
27 | |||
28 | #endif | ||
diff --git a/drivers/pci/pcie/pme/pcie_pme_acpi.c b/drivers/pci/pcie/pme/pcie_pme_acpi.c new file mode 100644 index 000000000000..83ab2287ae3f --- /dev/null +++ b/drivers/pci/pcie/pme/pcie_pme_acpi.c | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | * PCIe Native PME support, ACPI-related part | ||
3 | * | ||
4 | * Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc. | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License V2. See the file "COPYING" in the main directory of this archive | ||
8 | * for more details. | ||
9 | */ | ||
10 | |||
11 | #include <linux/pci.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/errno.h> | ||
14 | #include <linux/acpi.h> | ||
15 | #include <linux/pci-acpi.h> | ||
16 | #include <linux/pcieport_if.h> | ||
17 | |||
18 | /** | ||
19 | * pcie_pme_acpi_setup - Request the ACPI BIOS to release control over PCIe PME. | ||
20 | * @srv - PCIe PME service for a root port or event collector. | ||
21 | * | ||
22 | * Invoked when the PCIe bus type loads PCIe PME service driver. To avoid | ||
23 | * conflict with the BIOS PCIe support requires the BIOS to yield PCIe PME | ||
24 | * control to the kernel. | ||
25 | */ | ||
26 | int pcie_pme_acpi_setup(struct pcie_device *srv) | ||
27 | { | ||
28 | acpi_status status = AE_NOT_FOUND; | ||
29 | struct pci_dev *port = srv->port; | ||
30 | acpi_handle handle; | ||
31 | int error = 0; | ||
32 | |||
33 | if (acpi_pci_disabled) | ||
34 | return -ENOSYS; | ||
35 | |||
36 | dev_info(&port->dev, "Requesting control of PCIe PME from ACPI BIOS\n"); | ||
37 | |||
38 | handle = acpi_find_root_bridge_handle(port); | ||
39 | if (!handle) | ||
40 | return -EINVAL; | ||
41 | |||
42 | status = acpi_pci_osc_control_set(handle, | ||
43 | OSC_PCI_EXPRESS_PME_CONTROL | | ||
44 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
45 | if (ACPI_FAILURE(status)) { | ||
46 | dev_info(&port->dev, | ||
47 | "Failed to receive control of PCIe PME service: %s\n", | ||
48 | (status == AE_SUPPORT || status == AE_NOT_FOUND) ? | ||
49 | "no _OSC support" : "ACPI _OSC failed"); | ||
50 | error = -ENODEV; | ||
51 | } | ||
52 | |||
53 | return error; | ||
54 | } | ||
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index 17ad53868f9f..813a5c3427b6 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h | |||
@@ -11,31 +11,16 @@ | |||
11 | 11 | ||
12 | #include <linux/compiler.h> | 12 | #include <linux/compiler.h> |
13 | 13 | ||
14 | #if !defined(PCI_CAP_ID_PME) | 14 | #define PCIE_PORT_DEVICE_MAXSERVICES 4 |
15 | #define PCI_CAP_ID_PME 1 | ||
16 | #endif | ||
17 | |||
18 | #if !defined(PCI_CAP_ID_EXP) | ||
19 | #define PCI_CAP_ID_EXP 0x10 | ||
20 | #endif | ||
21 | |||
22 | #define PORT_TYPE_MASK 0xf | ||
23 | #define PORT_TO_SLOT_MASK 0x100 | ||
24 | #define SLOT_HP_CAPABLE_MASK 0x40 | ||
25 | #define PCIE_CAPABILITIES_REG 0x2 | ||
26 | #define PCIE_SLOT_CAPABILITIES_REG 0x14 | ||
27 | #define PCIE_PORT_DEVICE_MAXSERVICES 4 | ||
28 | #define PCIE_PORT_MSI_VECTOR_MASK 0x1f | ||
29 | /* | 15 | /* |
30 | * According to the PCI Express Base Specification 2.0, the indices of the MSI-X | 16 | * According to the PCI Express Base Specification 2.0, the indices of |
31 | * table entires used by port services must not exceed 31 | 17 | * the MSI-X table entires used by port services must not exceed 31 |
32 | */ | 18 | */ |
33 | #define PCIE_PORT_MAX_MSIX_ENTRIES 32 | 19 | #define PCIE_PORT_MAX_MSIX_ENTRIES 32 |
34 | 20 | ||
35 | #define get_descriptor_id(type, service) (((type - 4) << 4) | service) | 21 | #define get_descriptor_id(type, service) (((type - 4) << 4) | service) |
36 | 22 | ||
37 | extern struct bus_type pcie_port_bus_type; | 23 | extern struct bus_type pcie_port_bus_type; |
38 | extern int pcie_port_device_probe(struct pci_dev *dev); | ||
39 | extern int pcie_port_device_register(struct pci_dev *dev); | 24 | extern int pcie_port_device_register(struct pci_dev *dev); |
40 | #ifdef CONFIG_PM | 25 | #ifdef CONFIG_PM |
41 | extern int pcie_port_device_suspend(struct device *dev); | 26 | extern int pcie_port_device_suspend(struct device *dev); |
@@ -45,4 +30,21 @@ extern void pcie_port_device_remove(struct pci_dev *dev); | |||
45 | extern int __must_check pcie_port_bus_register(void); | 30 | extern int __must_check pcie_port_bus_register(void); |
46 | extern void pcie_port_bus_unregister(void); | 31 | extern void pcie_port_bus_unregister(void); |
47 | 32 | ||
33 | #ifdef CONFIG_PCIE_PME | ||
34 | extern bool pcie_pme_msi_disabled; | ||
35 | |||
36 | static inline void pcie_pme_disable_msi(void) | ||
37 | { | ||
38 | pcie_pme_msi_disabled = true; | ||
39 | } | ||
40 | |||
41 | static inline bool pcie_pme_no_msi(void) | ||
42 | { | ||
43 | return pcie_pme_msi_disabled; | ||
44 | } | ||
45 | #else /* !CONFIG_PCIE_PME */ | ||
46 | static inline void pcie_pme_disable_msi(void) {} | ||
47 | static inline bool pcie_pme_no_msi(void) { return false; } | ||
48 | #endif /* !CONFIG_PCIE_PME */ | ||
49 | |||
48 | #endif /* _PORTDRV_H_ */ | 50 | #endif /* _PORTDRV_H_ */ |
diff --git a/drivers/pci/pcie/portdrv_bus.c b/drivers/pci/pcie/portdrv_bus.c index ef3a4eeaebb4..18bf90f748f6 100644 --- a/drivers/pci/pcie/portdrv_bus.c +++ b/drivers/pci/pcie/portdrv_bus.c | |||
@@ -26,7 +26,6 @@ EXPORT_SYMBOL_GPL(pcie_port_bus_type); | |||
26 | static int pcie_port_bus_match(struct device *dev, struct device_driver *drv) | 26 | static int pcie_port_bus_match(struct device *dev, struct device_driver *drv) |
27 | { | 27 | { |
28 | struct pcie_device *pciedev; | 28 | struct pcie_device *pciedev; |
29 | struct pcie_port_data *port_data; | ||
30 | struct pcie_port_service_driver *driver; | 29 | struct pcie_port_service_driver *driver; |
31 | 30 | ||
32 | if (drv->bus != &pcie_port_bus_type || dev->bus != &pcie_port_bus_type) | 31 | if (drv->bus != &pcie_port_bus_type || dev->bus != &pcie_port_bus_type) |
@@ -38,10 +37,8 @@ static int pcie_port_bus_match(struct device *dev, struct device_driver *drv) | |||
38 | if (driver->service != pciedev->service) | 37 | if (driver->service != pciedev->service) |
39 | return 0; | 38 | return 0; |
40 | 39 | ||
41 | port_data = pci_get_drvdata(pciedev->port); | 40 | if ((driver->port_type != PCIE_ANY_PORT) && |
42 | 41 | (driver->port_type != pciedev->port->pcie_type)) | |
43 | if (driver->port_type != PCIE_ANY_PORT | ||
44 | && driver->port_type != port_data->port_type) | ||
45 | return 0; | 42 | return 0; |
46 | 43 | ||
47 | return 1; | 44 | return 1; |
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 52f84fca9f7d..e73effbe402c 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
@@ -27,7 +27,7 @@ | |||
27 | */ | 27 | */ |
28 | static void release_pcie_device(struct device *dev) | 28 | static void release_pcie_device(struct device *dev) |
29 | { | 29 | { |
30 | kfree(to_pcie_device(dev)); | 30 | kfree(to_pcie_device(dev)); |
31 | } | 31 | } |
32 | 32 | ||
33 | /** | 33 | /** |
@@ -108,9 +108,9 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask) | |||
108 | * the value in this field indicates which MSI-X Table entry is | 108 | * the value in this field indicates which MSI-X Table entry is |
109 | * used to generate the interrupt message." | 109 | * used to generate the interrupt message." |
110 | */ | 110 | */ |
111 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 111 | pos = pci_pcie_cap(dev); |
112 | pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, ®16); | 112 | pci_read_config_word(dev, pos + PCI_EXP_FLAGS, ®16); |
113 | entry = (reg16 >> 9) & PCIE_PORT_MSI_VECTOR_MASK; | 113 | entry = (reg16 & PCI_EXP_FLAGS_IRQ) >> 9; |
114 | if (entry >= nr_entries) | 114 | if (entry >= nr_entries) |
115 | goto Error; | 115 | goto Error; |
116 | 116 | ||
@@ -177,37 +177,48 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask) | |||
177 | } | 177 | } |
178 | 178 | ||
179 | /** | 179 | /** |
180 | * assign_interrupt_mode - choose interrupt mode for PCI Express port services | 180 | * init_service_irqs - initialize irqs for PCI Express port services |
181 | * (INTx, MSI-X, MSI) and set up vectors | ||
182 | * @dev: PCI Express port to handle | 181 | * @dev: PCI Express port to handle |
183 | * @vectors: Array of interrupt vectors to populate | 182 | * @irqs: Array of irqs to populate |
184 | * @mask: Bitmask of port capabilities returned by get_port_device_capability() | 183 | * @mask: Bitmask of port capabilities returned by get_port_device_capability() |
185 | * | 184 | * |
186 | * Return value: Interrupt mode associated with the port | 185 | * Return value: Interrupt mode associated with the port |
187 | */ | 186 | */ |
188 | static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask) | 187 | static int init_service_irqs(struct pci_dev *dev, int *irqs, int mask) |
189 | { | 188 | { |
190 | int irq, interrupt_mode = PCIE_PORT_NO_IRQ; | 189 | int i, irq = -1; |
191 | int i; | 190 | |
191 | /* We have to use INTx if MSI cannot be used for PCIe PME. */ | ||
192 | if ((mask & PCIE_PORT_SERVICE_PME) && pcie_pme_no_msi()) { | ||
193 | if (dev->pin) | ||
194 | irq = dev->irq; | ||
195 | goto no_msi; | ||
196 | } | ||
192 | 197 | ||
193 | /* Try to use MSI-X if supported */ | 198 | /* Try to use MSI-X if supported */ |
194 | if (!pcie_port_enable_msix(dev, vectors, mask)) | 199 | if (!pcie_port_enable_msix(dev, irqs, mask)) |
195 | return PCIE_PORT_MSIX_MODE; | 200 | return 0; |
196 | 201 | ||
197 | /* We're not going to use MSI-X, so try MSI and fall back to INTx */ | 202 | /* We're not going to use MSI-X, so try MSI and fall back to INTx */ |
198 | if (!pci_enable_msi(dev)) | 203 | if (!pci_enable_msi(dev) || dev->pin) |
199 | interrupt_mode = PCIE_PORT_MSI_MODE; | 204 | irq = dev->irq; |
200 | |||
201 | if (interrupt_mode == PCIE_PORT_NO_IRQ && dev->pin) | ||
202 | interrupt_mode = PCIE_PORT_INTx_MODE; | ||
203 | 205 | ||
204 | irq = interrupt_mode != PCIE_PORT_NO_IRQ ? dev->irq : -1; | 206 | no_msi: |
205 | for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) | 207 | for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) |
206 | vectors[i] = irq; | 208 | irqs[i] = irq; |
209 | irqs[PCIE_PORT_SERVICE_VC_SHIFT] = -1; | ||
207 | 210 | ||
208 | vectors[PCIE_PORT_SERVICE_VC_SHIFT] = -1; | 211 | if (irq < 0) |
212 | return -ENODEV; | ||
213 | return 0; | ||
214 | } | ||
209 | 215 | ||
210 | return interrupt_mode; | 216 | static void cleanup_service_irqs(struct pci_dev *dev) |
217 | { | ||
218 | if (dev->msix_enabled) | ||
219 | pci_disable_msix(dev); | ||
220 | else if (dev->msi_enabled) | ||
221 | pci_disable_msi(dev); | ||
211 | } | 222 | } |
212 | 223 | ||
213 | /** | 224 | /** |
@@ -226,13 +237,12 @@ static int get_port_device_capability(struct pci_dev *dev) | |||
226 | u16 reg16; | 237 | u16 reg16; |
227 | u32 reg32; | 238 | u32 reg32; |
228 | 239 | ||
229 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 240 | pos = pci_pcie_cap(dev); |
230 | pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, ®16); | 241 | pci_read_config_word(dev, pos + PCI_EXP_FLAGS, ®16); |
231 | /* Hot-Plug Capable */ | 242 | /* Hot-Plug Capable */ |
232 | if (reg16 & PORT_TO_SLOT_MASK) { | 243 | if (reg16 & PCI_EXP_FLAGS_SLOT) { |
233 | pci_read_config_dword(dev, | 244 | pci_read_config_dword(dev, pos + PCI_EXP_SLTCAP, ®32); |
234 | pos + PCIE_SLOT_CAPABILITIES_REG, ®32); | 245 | if (reg32 & PCI_EXP_SLTCAP_HPC) |
235 | if (reg32 & SLOT_HP_CAPABLE_MASK) | ||
236 | services |= PCIE_PORT_SERVICE_HP; | 246 | services |= PCIE_PORT_SERVICE_HP; |
237 | } | 247 | } |
238 | /* AER capable */ | 248 | /* AER capable */ |
@@ -241,80 +251,48 @@ static int get_port_device_capability(struct pci_dev *dev) | |||
241 | /* VC support */ | 251 | /* VC support */ |
242 | if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC)) | 252 | if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC)) |
243 | services |= PCIE_PORT_SERVICE_VC; | 253 | services |= PCIE_PORT_SERVICE_VC; |
254 | /* Root ports are capable of generating PME too */ | ||
255 | if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) | ||
256 | services |= PCIE_PORT_SERVICE_PME; | ||
244 | 257 | ||
245 | return services; | 258 | return services; |
246 | } | 259 | } |
247 | 260 | ||
248 | /** | 261 | /** |
249 | * pcie_device_init - initialize PCI Express port service device | 262 | * pcie_device_init - allocate and initialize PCI Express port service device |
250 | * @dev: Port service device to initialize | 263 | * @pdev: PCI Express port to associate the service device with |
251 | * @parent: PCI Express port to associate the service device with | 264 | * @service: Type of service to associate with the service device |
252 | * @port_type: Type of the port | ||
253 | * @service_type: Type of service to associate with the service device | ||
254 | * @irq: Interrupt vector to associate with the service device | 265 | * @irq: Interrupt vector to associate with the service device |
255 | */ | 266 | */ |
256 | static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev, | 267 | static int pcie_device_init(struct pci_dev *pdev, int service, int irq) |
257 | int service_type, int irq) | ||
258 | { | 268 | { |
259 | struct pcie_port_data *port_data = pci_get_drvdata(parent); | 269 | int retval; |
270 | struct pcie_device *pcie; | ||
260 | struct device *device; | 271 | struct device *device; |
261 | int port_type = port_data->port_type; | ||
262 | 272 | ||
263 | dev->port = parent; | 273 | pcie = kzalloc(sizeof(*pcie), GFP_KERNEL); |
264 | dev->irq = irq; | 274 | if (!pcie) |
265 | dev->service = service_type; | 275 | return -ENOMEM; |
276 | pcie->port = pdev; | ||
277 | pcie->irq = irq; | ||
278 | pcie->service = service; | ||
266 | 279 | ||
267 | /* Initialize generic device interface */ | 280 | /* Initialize generic device interface */ |
268 | device = &dev->device; | 281 | device = &pcie->device; |
269 | memset(device, 0, sizeof(struct device)); | ||
270 | device->bus = &pcie_port_bus_type; | 282 | device->bus = &pcie_port_bus_type; |
271 | device->driver = NULL; | ||
272 | dev_set_drvdata(device, NULL); | ||
273 | device->release = release_pcie_device; /* callback to free pcie dev */ | 283 | device->release = release_pcie_device; /* callback to free pcie dev */ |
274 | dev_set_name(device, "%s:pcie%02x", | 284 | dev_set_name(device, "%s:pcie%02x", |
275 | pci_name(parent), get_descriptor_id(port_type, service_type)); | 285 | pci_name(pdev), |
276 | device->parent = &parent->dev; | 286 | get_descriptor_id(pdev->pcie_type, service)); |
277 | } | 287 | device->parent = &pdev->dev; |
278 | 288 | device_enable_async_suspend(device); | |
279 | /** | 289 | |
280 | * alloc_pcie_device - allocate PCI Express port service device structure | 290 | retval = device_register(device); |
281 | * @parent: PCI Express port to associate the service device with | 291 | if (retval) |
282 | * @port_type: Type of the port | 292 | kfree(pcie); |
283 | * @service_type: Type of service to associate with the service device | 293 | else |
284 | * @irq: Interrupt vector to associate with the service device | 294 | get_device(device); |
285 | */ | 295 | return retval; |
286 | static struct pcie_device* alloc_pcie_device(struct pci_dev *parent, | ||
287 | int service_type, int irq) | ||
288 | { | ||
289 | struct pcie_device *device; | ||
290 | |||
291 | device = kzalloc(sizeof(struct pcie_device), GFP_KERNEL); | ||
292 | if (!device) | ||
293 | return NULL; | ||
294 | |||
295 | pcie_device_init(parent, device, service_type, irq); | ||
296 | return device; | ||
297 | } | ||
298 | |||
299 | /** | ||
300 | * pcie_port_device_probe - check if device is a PCI Express port | ||
301 | * @dev: Device to check | ||
302 | */ | ||
303 | int pcie_port_device_probe(struct pci_dev *dev) | ||
304 | { | ||
305 | int pos, type; | ||
306 | u16 reg; | ||
307 | |||
308 | if (!(pos = pci_find_capability(dev, PCI_CAP_ID_EXP))) | ||
309 | return -ENODEV; | ||
310 | |||
311 | pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, ®); | ||
312 | type = (reg >> 4) & PORT_TYPE_MASK; | ||
313 | if ( type == PCIE_RC_PORT || type == PCIE_SW_UPSTREAM_PORT || | ||
314 | type == PCIE_SW_DOWNSTREAM_PORT ) | ||
315 | return 0; | ||
316 | |||
317 | return -ENODEV; | ||
318 | } | 296 | } |
319 | 297 | ||
320 | /** | 298 | /** |
@@ -326,77 +304,49 @@ int pcie_port_device_probe(struct pci_dev *dev) | |||
326 | */ | 304 | */ |
327 | int pcie_port_device_register(struct pci_dev *dev) | 305 | int pcie_port_device_register(struct pci_dev *dev) |
328 | { | 306 | { |
329 | struct pcie_port_data *port_data; | 307 | int status, capabilities, i, nr_service; |
330 | int status, capabilities, irq_mode, i, nr_serv; | 308 | int irqs[PCIE_PORT_DEVICE_MAXSERVICES]; |
331 | int vectors[PCIE_PORT_DEVICE_MAXSERVICES]; | ||
332 | u16 reg16; | ||
333 | |||
334 | port_data = kzalloc(sizeof(*port_data), GFP_KERNEL); | ||
335 | if (!port_data) | ||
336 | return -ENOMEM; | ||
337 | pci_set_drvdata(dev, port_data); | ||
338 | |||
339 | /* Get port type */ | ||
340 | pci_read_config_word(dev, | ||
341 | pci_find_capability(dev, PCI_CAP_ID_EXP) + | ||
342 | PCIE_CAPABILITIES_REG, ®16); | ||
343 | port_data->port_type = (reg16 >> 4) & PORT_TYPE_MASK; | ||
344 | 309 | ||
310 | /* Get and check PCI Express port services */ | ||
345 | capabilities = get_port_device_capability(dev); | 311 | capabilities = get_port_device_capability(dev); |
346 | /* Root ports are capable of generating PME too */ | 312 | if (!capabilities) |
347 | if (port_data->port_type == PCIE_RC_PORT) | 313 | return -ENODEV; |
348 | capabilities |= PCIE_PORT_SERVICE_PME; | ||
349 | |||
350 | irq_mode = assign_interrupt_mode(dev, vectors, capabilities); | ||
351 | if (irq_mode == PCIE_PORT_NO_IRQ) { | ||
352 | /* | ||
353 | * Don't use service devices that require interrupts if there is | ||
354 | * no way to generate them. | ||
355 | */ | ||
356 | if (!(capabilities & PCIE_PORT_SERVICE_VC)) { | ||
357 | status = -ENODEV; | ||
358 | goto Error; | ||
359 | } | ||
360 | capabilities = PCIE_PORT_SERVICE_VC; | ||
361 | } | ||
362 | port_data->port_irq_mode = irq_mode; | ||
363 | 314 | ||
315 | /* Enable PCI Express port device */ | ||
364 | status = pci_enable_device(dev); | 316 | status = pci_enable_device(dev); |
365 | if (status) | 317 | if (status) |
366 | goto Error; | 318 | return status; |
367 | pci_set_master(dev); | 319 | pci_set_master(dev); |
320 | /* | ||
321 | * Initialize service irqs. Don't use service devices that | ||
322 | * require interrupts if there is no way to generate them. | ||
323 | */ | ||
324 | status = init_service_irqs(dev, irqs, capabilities); | ||
325 | if (status) { | ||
326 | capabilities &= PCIE_PORT_SERVICE_VC; | ||
327 | if (!capabilities) | ||
328 | goto error_disable; | ||
329 | } | ||
368 | 330 | ||
369 | /* Allocate child services if any */ | 331 | /* Allocate child services if any */ |
370 | for (i = 0, nr_serv = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) { | 332 | status = -ENODEV; |
371 | struct pcie_device *child; | 333 | nr_service = 0; |
334 | for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) { | ||
372 | int service = 1 << i; | 335 | int service = 1 << i; |
373 | |||
374 | if (!(capabilities & service)) | 336 | if (!(capabilities & service)) |
375 | continue; | 337 | continue; |
376 | 338 | if (!pcie_device_init(dev, service, irqs[i])) | |
377 | child = alloc_pcie_device(dev, service, vectors[i]); | 339 | nr_service++; |
378 | if (!child) | ||
379 | continue; | ||
380 | |||
381 | status = device_register(&child->device); | ||
382 | if (status) { | ||
383 | kfree(child); | ||
384 | continue; | ||
385 | } | ||
386 | |||
387 | get_device(&child->device); | ||
388 | nr_serv++; | ||
389 | } | ||
390 | if (!nr_serv) { | ||
391 | pci_disable_device(dev); | ||
392 | status = -ENODEV; | ||
393 | goto Error; | ||
394 | } | 340 | } |
341 | if (!nr_service) | ||
342 | goto error_cleanup_irqs; | ||
395 | 343 | ||
396 | return 0; | 344 | return 0; |
397 | 345 | ||
398 | Error: | 346 | error_cleanup_irqs: |
399 | kfree(port_data); | 347 | cleanup_service_irqs(dev); |
348 | error_disable: | ||
349 | pci_disable_device(dev); | ||
400 | return status; | 350 | return status; |
401 | } | 351 | } |
402 | 352 | ||
@@ -405,12 +355,11 @@ static int suspend_iter(struct device *dev, void *data) | |||
405 | { | 355 | { |
406 | struct pcie_port_service_driver *service_driver; | 356 | struct pcie_port_service_driver *service_driver; |
407 | 357 | ||
408 | if ((dev->bus == &pcie_port_bus_type) && | 358 | if ((dev->bus == &pcie_port_bus_type) && dev->driver) { |
409 | (dev->driver)) { | 359 | service_driver = to_service_driver(dev->driver); |
410 | service_driver = to_service_driver(dev->driver); | 360 | if (service_driver->suspend) |
411 | if (service_driver->suspend) | 361 | service_driver->suspend(to_pcie_device(dev)); |
412 | service_driver->suspend(to_pcie_device(dev)); | 362 | } |
413 | } | ||
414 | return 0; | 363 | return 0; |
415 | } | 364 | } |
416 | 365 | ||
@@ -464,21 +413,9 @@ static int remove_iter(struct device *dev, void *data) | |||
464 | */ | 413 | */ |
465 | void pcie_port_device_remove(struct pci_dev *dev) | 414 | void pcie_port_device_remove(struct pci_dev *dev) |
466 | { | 415 | { |
467 | struct pcie_port_data *port_data = pci_get_drvdata(dev); | ||
468 | |||
469 | device_for_each_child(&dev->dev, NULL, remove_iter); | 416 | device_for_each_child(&dev->dev, NULL, remove_iter); |
417 | cleanup_service_irqs(dev); | ||
470 | pci_disable_device(dev); | 418 | pci_disable_device(dev); |
471 | |||
472 | switch (port_data->port_irq_mode) { | ||
473 | case PCIE_PORT_MSIX_MODE: | ||
474 | pci_disable_msix(dev); | ||
475 | break; | ||
476 | case PCIE_PORT_MSI_MODE: | ||
477 | pci_disable_msi(dev); | ||
478 | break; | ||
479 | } | ||
480 | |||
481 | kfree(port_data); | ||
482 | } | 419 | } |
483 | 420 | ||
484 | /** | 421 | /** |
@@ -565,6 +502,7 @@ int pcie_port_service_register(struct pcie_port_service_driver *new) | |||
565 | 502 | ||
566 | return driver_register(&new->driver); | 503 | return driver_register(&new->driver); |
567 | } | 504 | } |
505 | EXPORT_SYMBOL(pcie_port_service_register); | ||
568 | 506 | ||
569 | /** | 507 | /** |
570 | * pcie_port_service_unregister - unregister PCI Express port service driver | 508 | * pcie_port_service_unregister - unregister PCI Express port service driver |
@@ -574,6 +512,4 @@ void pcie_port_service_unregister(struct pcie_port_service_driver *drv) | |||
574 | { | 512 | { |
575 | driver_unregister(&drv->driver); | 513 | driver_unregister(&drv->driver); |
576 | } | 514 | } |
577 | |||
578 | EXPORT_SYMBOL(pcie_port_service_register); | ||
579 | EXPORT_SYMBOL(pcie_port_service_unregister); | 515 | EXPORT_SYMBOL(pcie_port_service_unregister); |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index f635e476d632..3debed25e46b 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -12,9 +12,9 @@ | |||
12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
13 | #include <linux/pm.h> | 13 | #include <linux/pm.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/slab.h> | ||
16 | #include <linux/pcieport_if.h> | 15 | #include <linux/pcieport_if.h> |
17 | #include <linux/aer.h> | 16 | #include <linux/aer.h> |
17 | #include <linux/dmi.h> | ||
18 | 18 | ||
19 | #include "portdrv.h" | 19 | #include "portdrv.h" |
20 | #include "aer/aerdrv.h" | 20 | #include "aer/aerdrv.h" |
@@ -24,7 +24,7 @@ | |||
24 | */ | 24 | */ |
25 | #define DRIVER_VERSION "v1.0" | 25 | #define DRIVER_VERSION "v1.0" |
26 | #define DRIVER_AUTHOR "tom.l.nguyen@intel.com" | 26 | #define DRIVER_AUTHOR "tom.l.nguyen@intel.com" |
27 | #define DRIVER_DESC "PCIE Port Bus Driver" | 27 | #define DRIVER_DESC "PCIe Port Bus Driver" |
28 | MODULE_AUTHOR(DRIVER_AUTHOR); | 28 | MODULE_AUTHOR(DRIVER_AUTHOR); |
29 | MODULE_DESCRIPTION(DRIVER_DESC); | 29 | MODULE_DESCRIPTION(DRIVER_DESC); |
30 | MODULE_LICENSE("GPL"); | 30 | MODULE_LICENSE("GPL"); |
@@ -43,7 +43,7 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev) | |||
43 | } | 43 | } |
44 | 44 | ||
45 | #ifdef CONFIG_PM | 45 | #ifdef CONFIG_PM |
46 | static struct dev_pm_ops pcie_portdrv_pm_ops = { | 46 | static const struct dev_pm_ops pcie_portdrv_pm_ops = { |
47 | .suspend = pcie_port_device_suspend, | 47 | .suspend = pcie_port_device_suspend, |
48 | .resume = pcie_port_device_resume, | 48 | .resume = pcie_port_device_resume, |
49 | .freeze = pcie_port_device_suspend, | 49 | .freeze = pcie_port_device_suspend, |
@@ -63,20 +63,22 @@ static struct dev_pm_ops pcie_portdrv_pm_ops = { | |||
63 | * pcie_portdrv_probe - Probe PCI-Express port devices | 63 | * pcie_portdrv_probe - Probe PCI-Express port devices |
64 | * @dev: PCI-Express port device being probed | 64 | * @dev: PCI-Express port device being probed |
65 | * | 65 | * |
66 | * If detected invokes the pcie_port_device_register() method for | 66 | * If detected invokes the pcie_port_device_register() method for |
67 | * this port device. | 67 | * this port device. |
68 | * | 68 | * |
69 | */ | 69 | */ |
70 | static int __devinit pcie_portdrv_probe (struct pci_dev *dev, | 70 | static int __devinit pcie_portdrv_probe(struct pci_dev *dev, |
71 | const struct pci_device_id *id ) | 71 | const struct pci_device_id *id) |
72 | { | 72 | { |
73 | int status; | 73 | int status; |
74 | 74 | ||
75 | status = pcie_port_device_probe(dev); | 75 | if (!pci_is_pcie(dev) || |
76 | if (status) | 76 | ((dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && |
77 | return status; | 77 | (dev->pcie_type != PCI_EXP_TYPE_UPSTREAM) && |
78 | (dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))) | ||
79 | return -ENODEV; | ||
78 | 80 | ||
79 | if (!dev->irq && dev->pin) { | 81 | if (!dev->irq && dev->pin) { |
80 | dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; " | 82 | dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; " |
81 | "check vendor BIOS\n", dev->vendor, dev->device); | 83 | "check vendor BIOS\n", dev->vendor, dev->device); |
82 | } | 84 | } |
@@ -89,7 +91,7 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev, | |||
89 | return 0; | 91 | return 0; |
90 | } | 92 | } |
91 | 93 | ||
92 | static void pcie_portdrv_remove (struct pci_dev *dev) | 94 | static void pcie_portdrv_remove(struct pci_dev *dev) |
93 | { | 95 | { |
94 | pcie_port_device_remove(dev); | 96 | pcie_port_device_remove(dev); |
95 | pci_disable_device(dev); | 97 | pci_disable_device(dev); |
@@ -127,14 +129,13 @@ static int error_detected_iter(struct device *device, void *data) | |||
127 | static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev, | 129 | static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev, |
128 | enum pci_channel_state error) | 130 | enum pci_channel_state error) |
129 | { | 131 | { |
130 | struct aer_broadcast_data result_data = | 132 | struct aer_broadcast_data data = {error, PCI_ERS_RESULT_CAN_RECOVER}; |
131 | {error, PCI_ERS_RESULT_CAN_RECOVER}; | 133 | int ret; |
132 | int retval; | ||
133 | 134 | ||
134 | /* can not fail */ | 135 | /* can not fail */ |
135 | retval = device_for_each_child(&dev->dev, &result_data, error_detected_iter); | 136 | ret = device_for_each_child(&dev->dev, &data, error_detected_iter); |
136 | 137 | ||
137 | return result_data.result; | 138 | return data.result; |
138 | } | 139 | } |
139 | 140 | ||
140 | static int mmio_enabled_iter(struct device *device, void *data) | 141 | static int mmio_enabled_iter(struct device *device, void *data) |
@@ -272,10 +273,36 @@ static struct pci_driver pcie_portdriver = { | |||
272 | .driver.pm = PCIE_PORTDRV_PM_OPS, | 273 | .driver.pm = PCIE_PORTDRV_PM_OPS, |
273 | }; | 274 | }; |
274 | 275 | ||
276 | static int __init dmi_pcie_pme_disable_msi(const struct dmi_system_id *d) | ||
277 | { | ||
278 | pr_notice("%s detected: will not use MSI for PCIe PME signaling\n", | ||
279 | d->ident); | ||
280 | pcie_pme_disable_msi(); | ||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | static struct dmi_system_id __initdata pcie_portdrv_dmi_table[] = { | ||
285 | /* | ||
286 | * Boxes that should not use MSI for PCIe PME signaling. | ||
287 | */ | ||
288 | { | ||
289 | .callback = dmi_pcie_pme_disable_msi, | ||
290 | .ident = "MSI Wind U-100", | ||
291 | .matches = { | ||
292 | DMI_MATCH(DMI_SYS_VENDOR, | ||
293 | "MICRO-STAR INTERNATIONAL CO., LTD"), | ||
294 | DMI_MATCH(DMI_PRODUCT_NAME, "U-100"), | ||
295 | }, | ||
296 | }, | ||
297 | {} | ||
298 | }; | ||
299 | |||
275 | static int __init pcie_portdrv_init(void) | 300 | static int __init pcie_portdrv_init(void) |
276 | { | 301 | { |
277 | int retval; | 302 | int retval; |
278 | 303 | ||
304 | dmi_check_system(pcie_portdrv_dmi_table); | ||
305 | |||
279 | retval = pcie_port_bus_register(); | 306 | retval = pcie_port_bus_register(); |
280 | if (retval) { | 307 | if (retval) { |
281 | printk(KERN_WARNING "PCIE: bus_register error: %d\n", retval); | 308 | printk(KERN_WARNING "PCIE: bus_register error: %d\n", retval); |
@@ -288,7 +315,7 @@ static int __init pcie_portdrv_init(void) | |||
288 | return retval; | 315 | return retval; |
289 | } | 316 | } |
290 | 317 | ||
291 | static void __exit pcie_portdrv_exit(void) | 318 | static void __exit pcie_portdrv_exit(void) |
292 | { | 319 | { |
293 | pci_unregister_driver(&pcie_portdriver); | 320 | pci_unregister_driver(&pcie_portdriver); |
294 | pcie_port_bus_unregister(); | 321 | pcie_port_bus_unregister(); |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 8105e32117f6..c82548afcd5c 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/cpumask.h> | 11 | #include <linux/cpumask.h> |
12 | #include <linux/pci-aspm.h> | 12 | #include <linux/pci-aspm.h> |
13 | #include <acpi/acpi_hest.h> | ||
13 | #include "pci.h" | 14 | #include "pci.h" |
14 | 15 | ||
15 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ | 16 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ |
@@ -88,6 +89,7 @@ static void release_pcibus_dev(struct device *dev) | |||
88 | 89 | ||
89 | if (pci_bus->bridge) | 90 | if (pci_bus->bridge) |
90 | put_device(pci_bus->bridge); | 91 | put_device(pci_bus->bridge); |
92 | pci_bus_remove_resources(pci_bus); | ||
91 | kfree(pci_bus); | 93 | kfree(pci_bus); |
92 | } | 94 | } |
93 | 95 | ||
@@ -163,12 +165,12 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
163 | { | 165 | { |
164 | u32 l, sz, mask; | 166 | u32 l, sz, mask; |
165 | 167 | ||
166 | mask = type ? ~PCI_ROM_ADDRESS_ENABLE : ~0; | 168 | mask = type ? PCI_ROM_ADDRESS_MASK : ~0; |
167 | 169 | ||
168 | res->name = pci_name(dev); | 170 | res->name = pci_name(dev); |
169 | 171 | ||
170 | pci_read_config_dword(dev, pos, &l); | 172 | pci_read_config_dword(dev, pos, &l); |
171 | pci_write_config_dword(dev, pos, mask); | 173 | pci_write_config_dword(dev, pos, l | mask); |
172 | pci_read_config_dword(dev, pos, &sz); | 174 | pci_read_config_dword(dev, pos, &sz); |
173 | pci_write_config_dword(dev, pos, l); | 175 | pci_write_config_dword(dev, pos, l); |
174 | 176 | ||
@@ -223,9 +225,13 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
223 | goto fail; | 225 | goto fail; |
224 | 226 | ||
225 | if ((sizeof(resource_size_t) < 8) && (sz64 > 0x100000000ULL)) { | 227 | if ((sizeof(resource_size_t) < 8) && (sz64 > 0x100000000ULL)) { |
226 | dev_err(&dev->dev, "can't handle 64-bit BAR\n"); | 228 | dev_err(&dev->dev, "reg %x: can't handle 64-bit BAR\n", |
229 | pos); | ||
227 | goto fail; | 230 | goto fail; |
228 | } else if ((sizeof(resource_size_t) < 8) && l) { | 231 | } |
232 | |||
233 | res->flags |= IORESOURCE_MEM_64; | ||
234 | if ((sizeof(resource_size_t) < 8) && l) { | ||
229 | /* Address above 32-bit boundary; disable the BAR */ | 235 | /* Address above 32-bit boundary; disable the BAR */ |
230 | pci_write_config_dword(dev, pos, 0); | 236 | pci_write_config_dword(dev, pos, 0); |
231 | pci_write_config_dword(dev, pos + 4, 0); | 237 | pci_write_config_dword(dev, pos + 4, 0); |
@@ -234,14 +240,9 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
234 | } else { | 240 | } else { |
235 | res->start = l64; | 241 | res->start = l64; |
236 | res->end = l64 + sz64; | 242 | res->end = l64 + sz64; |
237 | dev_printk(KERN_DEBUG, &dev->dev, | 243 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", |
238 | "reg %x %s: %pR\n", pos, | 244 | pos, res); |
239 | (res->flags & IORESOURCE_PREFETCH) ? | ||
240 | "64bit mmio pref" : "64bit mmio", | ||
241 | res); | ||
242 | } | 245 | } |
243 | |||
244 | res->flags |= IORESOURCE_MEM_64; | ||
245 | } else { | 246 | } else { |
246 | sz = pci_size(l, sz, mask); | 247 | sz = pci_size(l, sz, mask); |
247 | 248 | ||
@@ -251,11 +252,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
251 | res->start = l; | 252 | res->start = l; |
252 | res->end = l + sz; | 253 | res->end = l + sz; |
253 | 254 | ||
254 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x %s: %pR\n", pos, | 255 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res); |
255 | (res->flags & IORESOURCE_IO) ? "io port" : | ||
256 | ((res->flags & IORESOURCE_PREFETCH) ? | ||
257 | "32bit mmio pref" : "32bit mmio"), | ||
258 | res); | ||
259 | } | 256 | } |
260 | 257 | ||
261 | out: | 258 | out: |
@@ -285,23 +282,12 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) | |||
285 | } | 282 | } |
286 | } | 283 | } |
287 | 284 | ||
288 | void __devinit pci_read_bridge_bases(struct pci_bus *child) | 285 | static void __devinit pci_read_bridge_io(struct pci_bus *child) |
289 | { | 286 | { |
290 | struct pci_dev *dev = child->self; | 287 | struct pci_dev *dev = child->self; |
291 | u8 io_base_lo, io_limit_lo; | 288 | u8 io_base_lo, io_limit_lo; |
292 | u16 mem_base_lo, mem_limit_lo; | ||
293 | unsigned long base, limit; | 289 | unsigned long base, limit; |
294 | struct resource *res; | 290 | struct resource *res; |
295 | int i; | ||
296 | |||
297 | if (pci_is_root_bus(child)) /* It's a host bus, nothing to read */ | ||
298 | return; | ||
299 | |||
300 | if (dev->transparent) { | ||
301 | dev_info(&dev->dev, "transparent bridge\n"); | ||
302 | for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++) | ||
303 | child->resource[i] = child->parent->resource[i - 3]; | ||
304 | } | ||
305 | 291 | ||
306 | res = child->resource[0]; | 292 | res = child->resource[0]; |
307 | pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo); | 293 | pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo); |
@@ -317,27 +303,50 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) | |||
317 | limit |= (io_limit_hi << 16); | 303 | limit |= (io_limit_hi << 16); |
318 | } | 304 | } |
319 | 305 | ||
320 | if (base <= limit) { | 306 | if (base && base <= limit) { |
321 | res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; | 307 | res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; |
322 | if (!res->start) | 308 | if (!res->start) |
323 | res->start = base; | 309 | res->start = base; |
324 | if (!res->end) | 310 | if (!res->end) |
325 | res->end = limit + 0xfff; | 311 | res->end = limit + 0xfff; |
326 | dev_printk(KERN_DEBUG, &dev->dev, "bridge io port: %pR\n", res); | 312 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); |
313 | } else { | ||
314 | dev_printk(KERN_DEBUG, &dev->dev, | ||
315 | " bridge window [io %#06lx-%#06lx] (disabled)\n", | ||
316 | base, limit); | ||
327 | } | 317 | } |
318 | } | ||
319 | |||
320 | static void __devinit pci_read_bridge_mmio(struct pci_bus *child) | ||
321 | { | ||
322 | struct pci_dev *dev = child->self; | ||
323 | u16 mem_base_lo, mem_limit_lo; | ||
324 | unsigned long base, limit; | ||
325 | struct resource *res; | ||
328 | 326 | ||
329 | res = child->resource[1]; | 327 | res = child->resource[1]; |
330 | pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo); | 328 | pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo); |
331 | pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo); | 329 | pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo); |
332 | base = (mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16; | 330 | base = (mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16; |
333 | limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16; | 331 | limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16; |
334 | if (base <= limit) { | 332 | if (base && base <= limit) { |
335 | res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; | 333 | res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; |
336 | res->start = base; | 334 | res->start = base; |
337 | res->end = limit + 0xfffff; | 335 | res->end = limit + 0xfffff; |
338 | dev_printk(KERN_DEBUG, &dev->dev, "bridge 32bit mmio: %pR\n", | 336 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); |
339 | res); | 337 | } else { |
338 | dev_printk(KERN_DEBUG, &dev->dev, | ||
339 | " bridge window [mem %#010lx-%#010lx] (disabled)\n", | ||
340 | base, limit + 0xfffff); | ||
340 | } | 341 | } |
342 | } | ||
343 | |||
344 | static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child) | ||
345 | { | ||
346 | struct pci_dev *dev = child->self; | ||
347 | u16 mem_base_lo, mem_limit_lo; | ||
348 | unsigned long base, limit; | ||
349 | struct resource *res; | ||
341 | 350 | ||
342 | res = child->resource[2]; | 351 | res = child->resource[2]; |
343 | pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo); | 352 | pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo); |
@@ -368,16 +377,52 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) | |||
368 | #endif | 377 | #endif |
369 | } | 378 | } |
370 | } | 379 | } |
371 | if (base <= limit) { | 380 | if (base && base <= limit) { |
372 | res->flags = (mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) | | 381 | res->flags = (mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) | |
373 | IORESOURCE_MEM | IORESOURCE_PREFETCH; | 382 | IORESOURCE_MEM | IORESOURCE_PREFETCH; |
374 | if (res->flags & PCI_PREF_RANGE_TYPE_64) | 383 | if (res->flags & PCI_PREF_RANGE_TYPE_64) |
375 | res->flags |= IORESOURCE_MEM_64; | 384 | res->flags |= IORESOURCE_MEM_64; |
376 | res->start = base; | 385 | res->start = base; |
377 | res->end = limit + 0xfffff; | 386 | res->end = limit + 0xfffff; |
378 | dev_printk(KERN_DEBUG, &dev->dev, "bridge %sbit mmio pref: %pR\n", | 387 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); |
379 | (res->flags & PCI_PREF_RANGE_TYPE_64) ? "64" : "32", | 388 | } else { |
380 | res); | 389 | dev_printk(KERN_DEBUG, &dev->dev, |
390 | " bridge window [mem %#010lx-%#010lx pref] (disabled)\n", | ||
391 | base, limit + 0xfffff); | ||
392 | } | ||
393 | } | ||
394 | |||
395 | void __devinit pci_read_bridge_bases(struct pci_bus *child) | ||
396 | { | ||
397 | struct pci_dev *dev = child->self; | ||
398 | struct resource *res; | ||
399 | int i; | ||
400 | |||
401 | if (pci_is_root_bus(child)) /* It's a host bus, nothing to read */ | ||
402 | return; | ||
403 | |||
404 | dev_info(&dev->dev, "PCI bridge to [bus %02x-%02x]%s\n", | ||
405 | child->secondary, child->subordinate, | ||
406 | dev->transparent ? " (subtractive decode)" : ""); | ||
407 | |||
408 | pci_bus_remove_resources(child); | ||
409 | for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) | ||
410 | child->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i]; | ||
411 | |||
412 | pci_read_bridge_io(child); | ||
413 | pci_read_bridge_mmio(child); | ||
414 | pci_read_bridge_mmio_pref(child); | ||
415 | |||
416 | if (dev->transparent) { | ||
417 | pci_bus_for_each_resource(child->parent, res, i) { | ||
418 | if (res) { | ||
419 | pci_bus_add_resource(child, res, | ||
420 | PCI_SUBTRACTIVE_DECODE); | ||
421 | dev_printk(KERN_DEBUG, &dev->dev, | ||
422 | " bridge window %pR (subtractive decode)\n", | ||
423 | res); | ||
424 | } | ||
425 | } | ||
381 | } | 426 | } |
382 | } | 427 | } |
383 | 428 | ||
@@ -391,10 +436,147 @@ static struct pci_bus * pci_alloc_bus(void) | |||
391 | INIT_LIST_HEAD(&b->children); | 436 | INIT_LIST_HEAD(&b->children); |
392 | INIT_LIST_HEAD(&b->devices); | 437 | INIT_LIST_HEAD(&b->devices); |
393 | INIT_LIST_HEAD(&b->slots); | 438 | INIT_LIST_HEAD(&b->slots); |
439 | INIT_LIST_HEAD(&b->resources); | ||
440 | b->max_bus_speed = PCI_SPEED_UNKNOWN; | ||
441 | b->cur_bus_speed = PCI_SPEED_UNKNOWN; | ||
394 | } | 442 | } |
395 | return b; | 443 | return b; |
396 | } | 444 | } |
397 | 445 | ||
446 | static unsigned char pcix_bus_speed[] = { | ||
447 | PCI_SPEED_UNKNOWN, /* 0 */ | ||
448 | PCI_SPEED_66MHz_PCIX, /* 1 */ | ||
449 | PCI_SPEED_100MHz_PCIX, /* 2 */ | ||
450 | PCI_SPEED_133MHz_PCIX, /* 3 */ | ||
451 | PCI_SPEED_UNKNOWN, /* 4 */ | ||
452 | PCI_SPEED_66MHz_PCIX_ECC, /* 5 */ | ||
453 | PCI_SPEED_100MHz_PCIX_ECC, /* 6 */ | ||
454 | PCI_SPEED_133MHz_PCIX_ECC, /* 7 */ | ||
455 | PCI_SPEED_UNKNOWN, /* 8 */ | ||
456 | PCI_SPEED_66MHz_PCIX_266, /* 9 */ | ||
457 | PCI_SPEED_100MHz_PCIX_266, /* A */ | ||
458 | PCI_SPEED_133MHz_PCIX_266, /* B */ | ||
459 | PCI_SPEED_UNKNOWN, /* C */ | ||
460 | PCI_SPEED_66MHz_PCIX_533, /* D */ | ||
461 | PCI_SPEED_100MHz_PCIX_533, /* E */ | ||
462 | PCI_SPEED_133MHz_PCIX_533 /* F */ | ||
463 | }; | ||
464 | |||
465 | static unsigned char pcie_link_speed[] = { | ||
466 | PCI_SPEED_UNKNOWN, /* 0 */ | ||
467 | PCIE_SPEED_2_5GT, /* 1 */ | ||
468 | PCIE_SPEED_5_0GT, /* 2 */ | ||
469 | PCIE_SPEED_8_0GT, /* 3 */ | ||
470 | PCI_SPEED_UNKNOWN, /* 4 */ | ||
471 | PCI_SPEED_UNKNOWN, /* 5 */ | ||
472 | PCI_SPEED_UNKNOWN, /* 6 */ | ||
473 | PCI_SPEED_UNKNOWN, /* 7 */ | ||
474 | PCI_SPEED_UNKNOWN, /* 8 */ | ||
475 | PCI_SPEED_UNKNOWN, /* 9 */ | ||
476 | PCI_SPEED_UNKNOWN, /* A */ | ||
477 | PCI_SPEED_UNKNOWN, /* B */ | ||
478 | PCI_SPEED_UNKNOWN, /* C */ | ||
479 | PCI_SPEED_UNKNOWN, /* D */ | ||
480 | PCI_SPEED_UNKNOWN, /* E */ | ||
481 | PCI_SPEED_UNKNOWN /* F */ | ||
482 | }; | ||
483 | |||
484 | void pcie_update_link_speed(struct pci_bus *bus, u16 linksta) | ||
485 | { | ||
486 | bus->cur_bus_speed = pcie_link_speed[linksta & 0xf]; | ||
487 | } | ||
488 | EXPORT_SYMBOL_GPL(pcie_update_link_speed); | ||
489 | |||
490 | static unsigned char agp_speeds[] = { | ||
491 | AGP_UNKNOWN, | ||
492 | AGP_1X, | ||
493 | AGP_2X, | ||
494 | AGP_4X, | ||
495 | AGP_8X | ||
496 | }; | ||
497 | |||
498 | static enum pci_bus_speed agp_speed(int agp3, int agpstat) | ||
499 | { | ||
500 | int index = 0; | ||
501 | |||
502 | if (agpstat & 4) | ||
503 | index = 3; | ||
504 | else if (agpstat & 2) | ||
505 | index = 2; | ||
506 | else if (agpstat & 1) | ||
507 | index = 1; | ||
508 | else | ||
509 | goto out; | ||
510 | |||
511 | if (agp3) { | ||
512 | index += 2; | ||
513 | if (index == 5) | ||
514 | index = 0; | ||
515 | } | ||
516 | |||
517 | out: | ||
518 | return agp_speeds[index]; | ||
519 | } | ||
520 | |||
521 | |||
522 | static void pci_set_bus_speed(struct pci_bus *bus) | ||
523 | { | ||
524 | struct pci_dev *bridge = bus->self; | ||
525 | int pos; | ||
526 | |||
527 | pos = pci_find_capability(bridge, PCI_CAP_ID_AGP); | ||
528 | if (!pos) | ||
529 | pos = pci_find_capability(bridge, PCI_CAP_ID_AGP3); | ||
530 | if (pos) { | ||
531 | u32 agpstat, agpcmd; | ||
532 | |||
533 | pci_read_config_dword(bridge, pos + PCI_AGP_STATUS, &agpstat); | ||
534 | bus->max_bus_speed = agp_speed(agpstat & 8, agpstat & 7); | ||
535 | |||
536 | pci_read_config_dword(bridge, pos + PCI_AGP_COMMAND, &agpcmd); | ||
537 | bus->cur_bus_speed = agp_speed(agpstat & 8, agpcmd & 7); | ||
538 | } | ||
539 | |||
540 | pos = pci_find_capability(bridge, PCI_CAP_ID_PCIX); | ||
541 | if (pos) { | ||
542 | u16 status; | ||
543 | enum pci_bus_speed max; | ||
544 | pci_read_config_word(bridge, pos + 2, &status); | ||
545 | |||
546 | if (status & 0x8000) { | ||
547 | max = PCI_SPEED_133MHz_PCIX_533; | ||
548 | } else if (status & 0x4000) { | ||
549 | max = PCI_SPEED_133MHz_PCIX_266; | ||
550 | } else if (status & 0x0002) { | ||
551 | if (((status >> 12) & 0x3) == 2) { | ||
552 | max = PCI_SPEED_133MHz_PCIX_ECC; | ||
553 | } else { | ||
554 | max = PCI_SPEED_133MHz_PCIX; | ||
555 | } | ||
556 | } else { | ||
557 | max = PCI_SPEED_66MHz_PCIX; | ||
558 | } | ||
559 | |||
560 | bus->max_bus_speed = max; | ||
561 | bus->cur_bus_speed = pcix_bus_speed[(status >> 6) & 0xf]; | ||
562 | |||
563 | return; | ||
564 | } | ||
565 | |||
566 | pos = pci_find_capability(bridge, PCI_CAP_ID_EXP); | ||
567 | if (pos) { | ||
568 | u32 linkcap; | ||
569 | u16 linksta; | ||
570 | |||
571 | pci_read_config_dword(bridge, pos + PCI_EXP_LNKCAP, &linkcap); | ||
572 | bus->max_bus_speed = pcie_link_speed[linkcap & 0xf]; | ||
573 | |||
574 | pci_read_config_word(bridge, pos + PCI_EXP_LNKSTA, &linksta); | ||
575 | pcie_update_link_speed(bus, linksta); | ||
576 | } | ||
577 | } | ||
578 | |||
579 | |||
398 | static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, | 580 | static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, |
399 | struct pci_dev *bridge, int busnr) | 581 | struct pci_dev *bridge, int busnr) |
400 | { | 582 | { |
@@ -434,6 +616,8 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, | |||
434 | child->self = bridge; | 616 | child->self = bridge; |
435 | child->bridge = get_device(&bridge->dev); | 617 | child->bridge = get_device(&bridge->dev); |
436 | 618 | ||
619 | pci_set_bus_speed(child); | ||
620 | |||
437 | /* Set up default resource pointers and names.. */ | 621 | /* Set up default resource pointers and names.. */ |
438 | for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) { | 622 | for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) { |
439 | child->resource[i] = &bridge->resource[PCI_BRIDGE_RESOURCES+i]; | 623 | child->resource[i] = &bridge->resource[PCI_BRIDGE_RESOURCES+i]; |
@@ -489,16 +673,20 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, | |||
489 | int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); | 673 | int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); |
490 | u32 buses, i, j = 0; | 674 | u32 buses, i, j = 0; |
491 | u16 bctl; | 675 | u16 bctl; |
676 | u8 primary, secondary, subordinate; | ||
492 | int broken = 0; | 677 | int broken = 0; |
493 | 678 | ||
494 | pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); | 679 | pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); |
680 | primary = buses & 0xFF; | ||
681 | secondary = (buses >> 8) & 0xFF; | ||
682 | subordinate = (buses >> 16) & 0xFF; | ||
495 | 683 | ||
496 | dev_dbg(&dev->dev, "scanning behind bridge, config %06x, pass %d\n", | 684 | dev_dbg(&dev->dev, "scanning [bus %02x-%02x] behind bridge, pass %d\n", |
497 | buses & 0xffffff, pass); | 685 | secondary, subordinate, pass); |
498 | 686 | ||
499 | /* Check if setup is sensible at all */ | 687 | /* Check if setup is sensible at all */ |
500 | if (!pass && | 688 | if (!pass && |
501 | ((buses & 0xff) != bus->number || ((buses >> 8) & 0xff) <= bus->number)) { | 689 | (primary != bus->number || secondary <= bus->number)) { |
502 | dev_dbg(&dev->dev, "bus configuration invalid, reconfiguring\n"); | 690 | dev_dbg(&dev->dev, "bus configuration invalid, reconfiguring\n"); |
503 | broken = 1; | 691 | broken = 1; |
504 | } | 692 | } |
@@ -509,15 +697,15 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, | |||
509 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, | 697 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, |
510 | bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT); | 698 | bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT); |
511 | 699 | ||
512 | if ((buses & 0xffff00) && !pcibios_assign_all_busses() && !is_cardbus && !broken) { | 700 | if ((secondary || subordinate) && !pcibios_assign_all_busses() && |
513 | unsigned int cmax, busnr; | 701 | !is_cardbus && !broken) { |
702 | unsigned int cmax; | ||
514 | /* | 703 | /* |
515 | * Bus already configured by firmware, process it in the first | 704 | * Bus already configured by firmware, process it in the first |
516 | * pass and just note the configuration. | 705 | * pass and just note the configuration. |
517 | */ | 706 | */ |
518 | if (pass) | 707 | if (pass) |
519 | goto out; | 708 | goto out; |
520 | busnr = (buses >> 8) & 0xFF; | ||
521 | 709 | ||
522 | /* | 710 | /* |
523 | * If we already got to this bus through a different bridge, | 711 | * If we already got to this bus through a different bridge, |
@@ -526,13 +714,13 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, | |||
526 | * However, we continue to descend down the hierarchy and | 714 | * However, we continue to descend down the hierarchy and |
527 | * scan remaining child buses. | 715 | * scan remaining child buses. |
528 | */ | 716 | */ |
529 | child = pci_find_bus(pci_domain_nr(bus), busnr); | 717 | child = pci_find_bus(pci_domain_nr(bus), secondary); |
530 | if (!child) { | 718 | if (!child) { |
531 | child = pci_add_new_bus(bus, dev, busnr); | 719 | child = pci_add_new_bus(bus, dev, secondary); |
532 | if (!child) | 720 | if (!child) |
533 | goto out; | 721 | goto out; |
534 | child->primary = buses & 0xFF; | 722 | child->primary = primary; |
535 | child->subordinate = (buses >> 16) & 0xFF; | 723 | child->subordinate = subordinate; |
536 | child->bridge_ctl = bctl; | 724 | child->bridge_ctl = bctl; |
537 | } | 725 | } |
538 | 726 | ||
@@ -651,13 +839,14 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, | |||
651 | (child->number > bus->subordinate) || | 839 | (child->number > bus->subordinate) || |
652 | (child->number < bus->number) || | 840 | (child->number < bus->number) || |
653 | (child->subordinate < bus->number)) { | 841 | (child->subordinate < bus->number)) { |
654 | pr_debug("PCI: Bus #%02x (-#%02x) is %s " | 842 | dev_info(&child->dev, "[bus %02x-%02x] %s " |
655 | "hidden behind%s bridge #%02x (-#%02x)\n", | 843 | "hidden behind%s bridge %s [bus %02x-%02x]\n", |
656 | child->number, child->subordinate, | 844 | child->number, child->subordinate, |
657 | (bus->number > child->subordinate && | 845 | (bus->number > child->subordinate && |
658 | bus->subordinate < child->number) ? | 846 | bus->subordinate < child->number) ? |
659 | "wholly" : "partially", | 847 | "wholly" : "partially", |
660 | bus->self->transparent ? " transparent" : "", | 848 | bus->self->transparent ? " transparent" : "", |
849 | dev_name(&bus->dev), | ||
661 | bus->number, bus->subordinate); | 850 | bus->number, bus->subordinate); |
662 | } | 851 | } |
663 | bus = bus->parent; | 852 | bus = bus->parent; |
@@ -684,7 +873,7 @@ static void pci_read_irq(struct pci_dev *dev) | |||
684 | dev->irq = irq; | 873 | dev->irq = irq; |
685 | } | 874 | } |
686 | 875 | ||
687 | static void set_pcie_port_type(struct pci_dev *pdev) | 876 | void set_pcie_port_type(struct pci_dev *pdev) |
688 | { | 877 | { |
689 | int pos; | 878 | int pos; |
690 | u16 reg16; | 879 | u16 reg16; |
@@ -693,17 +882,18 @@ static void set_pcie_port_type(struct pci_dev *pdev) | |||
693 | if (!pos) | 882 | if (!pos) |
694 | return; | 883 | return; |
695 | pdev->is_pcie = 1; | 884 | pdev->is_pcie = 1; |
885 | pdev->pcie_cap = pos; | ||
696 | pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); | 886 | pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); |
697 | pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4; | 887 | pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4; |
698 | } | 888 | } |
699 | 889 | ||
700 | static void set_pcie_hotplug_bridge(struct pci_dev *pdev) | 890 | void set_pcie_hotplug_bridge(struct pci_dev *pdev) |
701 | { | 891 | { |
702 | int pos; | 892 | int pos; |
703 | u16 reg16; | 893 | u16 reg16; |
704 | u32 reg32; | 894 | u32 reg32; |
705 | 895 | ||
706 | pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); | 896 | pos = pci_pcie_cap(pdev); |
707 | if (!pos) | 897 | if (!pos) |
708 | return; | 898 | return; |
709 | pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); | 899 | pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); |
@@ -714,6 +904,12 @@ static void set_pcie_hotplug_bridge(struct pci_dev *pdev) | |||
714 | pdev->is_hotplug_bridge = 1; | 904 | pdev->is_hotplug_bridge = 1; |
715 | } | 905 | } |
716 | 906 | ||
907 | static void set_pci_aer_firmware_first(struct pci_dev *pdev) | ||
908 | { | ||
909 | if (acpi_hest_firmware_first_pci(pdev)) | ||
910 | pdev->aer_firmware_first = 1; | ||
911 | } | ||
912 | |||
717 | #define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) | 913 | #define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) |
718 | 914 | ||
719 | /** | 915 | /** |
@@ -731,6 +927,7 @@ int pci_setup_device(struct pci_dev *dev) | |||
731 | u32 class; | 927 | u32 class; |
732 | u8 hdr_type; | 928 | u8 hdr_type; |
733 | struct pci_slot *slot; | 929 | struct pci_slot *slot; |
930 | int pos = 0; | ||
734 | 931 | ||
735 | if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type)) | 932 | if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type)) |
736 | return -EIO; | 933 | return -EIO; |
@@ -742,6 +939,7 @@ int pci_setup_device(struct pci_dev *dev) | |||
742 | dev->multifunction = !!(hdr_type & 0x80); | 939 | dev->multifunction = !!(hdr_type & 0x80); |
743 | dev->error_state = pci_channel_io_normal; | 940 | dev->error_state = pci_channel_io_normal; |
744 | set_pcie_port_type(dev); | 941 | set_pcie_port_type(dev); |
942 | set_pci_aer_firmware_first(dev); | ||
745 | 943 | ||
746 | list_for_each_entry(slot, &dev->bus->slots, list) | 944 | list_for_each_entry(slot, &dev->bus->slots, list) |
747 | if (PCI_SLOT(dev->devfn) == slot->number) | 945 | if (PCI_SLOT(dev->devfn) == slot->number) |
@@ -822,6 +1020,11 @@ int pci_setup_device(struct pci_dev *dev) | |||
822 | dev->transparent = ((dev->class & 0xff) == 1); | 1020 | dev->transparent = ((dev->class & 0xff) == 1); |
823 | pci_read_bases(dev, 2, PCI_ROM_ADDRESS1); | 1021 | pci_read_bases(dev, 2, PCI_ROM_ADDRESS1); |
824 | set_pcie_hotplug_bridge(dev); | 1022 | set_pcie_hotplug_bridge(dev); |
1023 | pos = pci_find_capability(dev, PCI_CAP_ID_SSVID); | ||
1024 | if (pos) { | ||
1025 | pci_read_config_word(dev, pos + PCI_SSVID_VENDOR_ID, &dev->subsystem_vendor); | ||
1026 | pci_read_config_word(dev, pos + PCI_SSVID_DEVICE_ID, &dev->subsystem_device); | ||
1027 | } | ||
825 | break; | 1028 | break; |
826 | 1029 | ||
827 | case PCI_HEADER_TYPE_CARDBUS: /* CardBus bridge header */ | 1030 | case PCI_HEADER_TYPE_CARDBUS: /* CardBus bridge header */ |
@@ -907,7 +1110,7 @@ int pci_cfg_space_size(struct pci_dev *dev) | |||
907 | if (class == PCI_CLASS_BRIDGE_HOST) | 1110 | if (class == PCI_CLASS_BRIDGE_HOST) |
908 | return pci_cfg_space_size_ext(dev); | 1111 | return pci_cfg_space_size_ext(dev); |
909 | 1112 | ||
910 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 1113 | pos = pci_pcie_cap(dev); |
911 | if (!pos) { | 1114 | if (!pos) { |
912 | pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); | 1115 | pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); |
913 | if (!pos) | 1116 | if (!pos) |
@@ -1014,6 +1217,9 @@ static void pci_init_capabilities(struct pci_dev *dev) | |||
1014 | 1217 | ||
1015 | /* Single Root I/O Virtualization */ | 1218 | /* Single Root I/O Virtualization */ |
1016 | pci_iov_init(dev); | 1219 | pci_iov_init(dev); |
1220 | |||
1221 | /* Enable ACS P2P upstream forwarding */ | ||
1222 | pci_enable_acs(dev); | ||
1017 | } | 1223 | } |
1018 | 1224 | ||
1019 | void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) | 1225 | void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) |
@@ -1067,6 +1273,45 @@ struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn) | |||
1067 | } | 1273 | } |
1068 | EXPORT_SYMBOL(pci_scan_single_device); | 1274 | EXPORT_SYMBOL(pci_scan_single_device); |
1069 | 1275 | ||
1276 | static unsigned next_ari_fn(struct pci_dev *dev, unsigned fn) | ||
1277 | { | ||
1278 | u16 cap; | ||
1279 | unsigned pos, next_fn; | ||
1280 | |||
1281 | if (!dev) | ||
1282 | return 0; | ||
1283 | |||
1284 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); | ||
1285 | if (!pos) | ||
1286 | return 0; | ||
1287 | pci_read_config_word(dev, pos + 4, &cap); | ||
1288 | next_fn = cap >> 8; | ||
1289 | if (next_fn <= fn) | ||
1290 | return 0; | ||
1291 | return next_fn; | ||
1292 | } | ||
1293 | |||
1294 | static unsigned next_trad_fn(struct pci_dev *dev, unsigned fn) | ||
1295 | { | ||
1296 | return (fn + 1) % 8; | ||
1297 | } | ||
1298 | |||
1299 | static unsigned no_next_fn(struct pci_dev *dev, unsigned fn) | ||
1300 | { | ||
1301 | return 0; | ||
1302 | } | ||
1303 | |||
1304 | static int only_one_child(struct pci_bus *bus) | ||
1305 | { | ||
1306 | struct pci_dev *parent = bus->self; | ||
1307 | if (!parent || !pci_is_pcie(parent)) | ||
1308 | return 0; | ||
1309 | if (parent->pcie_type == PCI_EXP_TYPE_ROOT_PORT || | ||
1310 | parent->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) | ||
1311 | return 1; | ||
1312 | return 0; | ||
1313 | } | ||
1314 | |||
1070 | /** | 1315 | /** |
1071 | * pci_scan_slot - scan a PCI slot on a bus for devices. | 1316 | * pci_scan_slot - scan a PCI slot on a bus for devices. |
1072 | * @bus: PCI bus to scan | 1317 | * @bus: PCI bus to scan |
@@ -1080,21 +1325,30 @@ EXPORT_SYMBOL(pci_scan_single_device); | |||
1080 | */ | 1325 | */ |
1081 | int pci_scan_slot(struct pci_bus *bus, int devfn) | 1326 | int pci_scan_slot(struct pci_bus *bus, int devfn) |
1082 | { | 1327 | { |
1083 | int fn, nr = 0; | 1328 | unsigned fn, nr = 0; |
1084 | struct pci_dev *dev; | 1329 | struct pci_dev *dev; |
1330 | unsigned (*next_fn)(struct pci_dev *, unsigned) = no_next_fn; | ||
1331 | |||
1332 | if (only_one_child(bus) && (devfn > 0)) | ||
1333 | return 0; /* Already scanned the entire slot */ | ||
1085 | 1334 | ||
1086 | dev = pci_scan_single_device(bus, devfn); | 1335 | dev = pci_scan_single_device(bus, devfn); |
1087 | if (dev && !dev->is_added) /* new device? */ | 1336 | if (!dev) |
1337 | return 0; | ||
1338 | if (!dev->is_added) | ||
1088 | nr++; | 1339 | nr++; |
1089 | 1340 | ||
1090 | if (dev && dev->multifunction) { | 1341 | if (pci_ari_enabled(bus)) |
1091 | for (fn = 1; fn < 8; fn++) { | 1342 | next_fn = next_ari_fn; |
1092 | dev = pci_scan_single_device(bus, devfn + fn); | 1343 | else if (dev->multifunction) |
1093 | if (dev) { | 1344 | next_fn = next_trad_fn; |
1094 | if (!dev->is_added) | 1345 | |
1095 | nr++; | 1346 | for (fn = next_fn(dev, 0); fn > 0; fn = next_fn(dev, fn)) { |
1096 | dev->multifunction = 1; | 1347 | dev = pci_scan_single_device(bus, devfn + fn); |
1097 | } | 1348 | if (dev) { |
1349 | if (!dev->is_added) | ||
1350 | nr++; | ||
1351 | dev->multifunction = 1; | ||
1098 | } | 1352 | } |
1099 | } | 1353 | } |
1100 | 1354 | ||
@@ -1110,7 +1364,7 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) | |||
1110 | unsigned int devfn, pass, max = bus->secondary; | 1364 | unsigned int devfn, pass, max = bus->secondary; |
1111 | struct pci_dev *dev; | 1365 | struct pci_dev *dev; |
1112 | 1366 | ||
1113 | pr_debug("PCI: Scanning bus %04x:%02x\n", pci_domain_nr(bus), bus->number); | 1367 | dev_dbg(&bus->dev, "scanning bus\n"); |
1114 | 1368 | ||
1115 | /* Go find them, Rover! */ | 1369 | /* Go find them, Rover! */ |
1116 | for (devfn = 0; devfn < 0x100; devfn += 8) | 1370 | for (devfn = 0; devfn < 0x100; devfn += 8) |
@@ -1124,8 +1378,7 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) | |||
1124 | * all PCI-to-PCI bridges on this bus. | 1378 | * all PCI-to-PCI bridges on this bus. |
1125 | */ | 1379 | */ |
1126 | if (!bus->is_added) { | 1380 | if (!bus->is_added) { |
1127 | pr_debug("PCI: Fixups for bus %04x:%02x\n", | 1381 | dev_dbg(&bus->dev, "fixups for bus\n"); |
1128 | pci_domain_nr(bus), bus->number); | ||
1129 | pcibios_fixup_bus(bus); | 1382 | pcibios_fixup_bus(bus); |
1130 | if (pci_is_root_bus(bus)) | 1383 | if (pci_is_root_bus(bus)) |
1131 | bus->is_added = 1; | 1384 | bus->is_added = 1; |
@@ -1145,8 +1398,7 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) | |||
1145 | * | 1398 | * |
1146 | * Return how far we've got finding sub-buses. | 1399 | * Return how far we've got finding sub-buses. |
1147 | */ | 1400 | */ |
1148 | pr_debug("PCI: Bus scan for %04x:%02x returning with max=%02x\n", | 1401 | dev_dbg(&bus->dev, "bus scan returning with max=%02x\n", max); |
1149 | pci_domain_nr(bus), bus->number, max); | ||
1150 | return max; | 1402 | return max; |
1151 | } | 1403 | } |
1152 | 1404 | ||
@@ -1154,7 +1406,7 @@ struct pci_bus * pci_create_bus(struct device *parent, | |||
1154 | int bus, struct pci_ops *ops, void *sysdata) | 1406 | int bus, struct pci_ops *ops, void *sysdata) |
1155 | { | 1407 | { |
1156 | int error; | 1408 | int error; |
1157 | struct pci_bus *b; | 1409 | struct pci_bus *b, *b2; |
1158 | struct device *dev; | 1410 | struct device *dev; |
1159 | 1411 | ||
1160 | b = pci_alloc_bus(); | 1412 | b = pci_alloc_bus(); |
@@ -1170,9 +1422,10 @@ struct pci_bus * pci_create_bus(struct device *parent, | |||
1170 | b->sysdata = sysdata; | 1422 | b->sysdata = sysdata; |
1171 | b->ops = ops; | 1423 | b->ops = ops; |
1172 | 1424 | ||
1173 | if (pci_find_bus(pci_domain_nr(b), bus)) { | 1425 | b2 = pci_find_bus(pci_domain_nr(b), bus); |
1426 | if (b2) { | ||
1174 | /* If we already got to this bus through a different bridge, ignore it */ | 1427 | /* If we already got to this bus through a different bridge, ignore it */ |
1175 | pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus); | 1428 | dev_dbg(&b2->dev, "bus already known\n"); |
1176 | goto err_out; | 1429 | goto err_out; |
1177 | } | 1430 | } |
1178 | 1431 | ||
@@ -1187,6 +1440,7 @@ struct pci_bus * pci_create_bus(struct device *parent, | |||
1187 | if (error) | 1440 | if (error) |
1188 | goto dev_reg_err; | 1441 | goto dev_reg_err; |
1189 | b->bridge = get_device(dev); | 1442 | b->bridge = get_device(dev); |
1443 | device_enable_async_suspend(b->bridge); | ||
1190 | 1444 | ||
1191 | if (!parent) | 1445 | if (!parent) |
1192 | set_dev_node(b->bridge, pcibus_to_node(b)); | 1446 | set_dev_node(b->bridge, pcibus_to_node(b)); |
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 593bb844b8db..449e890267a2 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c | |||
@@ -6,6 +6,7 @@ | |||
6 | 6 | ||
7 | #include <linux/init.h> | 7 | #include <linux/init.h> |
8 | #include <linux/pci.h> | 8 | #include <linux/pci.h> |
9 | #include <linux/slab.h> | ||
9 | #include <linux/module.h> | 10 | #include <linux/module.h> |
10 | #include <linux/proc_fs.h> | 11 | #include <linux/proc_fs.h> |
11 | #include <linux/seq_file.h> | 12 | #include <linux/seq_file.h> |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 245d2cdb4765..27c0e6eb7136 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -25,14 +25,9 @@ | |||
25 | #include <linux/dmi.h> | 25 | #include <linux/dmi.h> |
26 | #include <linux/pci-aspm.h> | 26 | #include <linux/pci-aspm.h> |
27 | #include <linux/ioport.h> | 27 | #include <linux/ioport.h> |
28 | #include <asm/dma.h> /* isa_dma_bridge_buggy */ | ||
28 | #include "pci.h" | 29 | #include "pci.h" |
29 | 30 | ||
30 | int isa_dma_bridge_buggy; | ||
31 | EXPORT_SYMBOL(isa_dma_bridge_buggy); | ||
32 | int pci_pci_problems; | ||
33 | EXPORT_SYMBOL(pci_pci_problems); | ||
34 | |||
35 | #ifdef CONFIG_PCI_QUIRKS | ||
36 | /* | 31 | /* |
37 | * This quirk function disables memory decoding and releases memory resources | 32 | * This quirk function disables memory decoding and releases memory resources |
38 | * of the device specified by kernel's boot parameter 'pci=resource_alignment='. | 33 | * of the device specified by kernel's boot parameter 'pci=resource_alignment='. |
@@ -338,6 +333,23 @@ static void __devinit quirk_s3_64M(struct pci_dev *dev) | |||
338 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_868, quirk_s3_64M); | 333 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_868, quirk_s3_64M); |
339 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_968, quirk_s3_64M); | 334 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_968, quirk_s3_64M); |
340 | 335 | ||
336 | /* | ||
337 | * Some CS5536 BIOSes (for example, the Soekris NET5501 board w/ comBIOS | ||
338 | * ver. 1.33 20070103) don't set the correct ISA PCI region header info. | ||
339 | * BAR0 should be 8 bytes; instead, it may be set to something like 8k | ||
340 | * (which conflicts w/ BAR1's memory range). | ||
341 | */ | ||
342 | static void __devinit quirk_cs5536_vsa(struct pci_dev *dev) | ||
343 | { | ||
344 | if (pci_resource_len(dev, 0) != 8) { | ||
345 | struct resource *res = &dev->resource[0]; | ||
346 | res->end = res->start + 8 - 1; | ||
347 | dev_info(&dev->dev, "CS5536 ISA bridge bug detected " | ||
348 | "(incorrect header); workaround applied.\n"); | ||
349 | } | ||
350 | } | ||
351 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, quirk_cs5536_vsa); | ||
352 | |||
341 | static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region, | 353 | static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region, |
342 | unsigned size, int nr, const char *name) | 354 | unsigned size, int nr, const char *name) |
343 | { | 355 | { |
@@ -356,8 +368,9 @@ static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region, | |||
356 | bus_region.end = res->end; | 368 | bus_region.end = res->end; |
357 | pcibios_bus_to_resource(dev, res, &bus_region); | 369 | pcibios_bus_to_resource(dev, res, &bus_region); |
358 | 370 | ||
359 | pci_claim_resource(dev, nr); | 371 | if (pci_claim_resource(dev, nr) == 0) |
360 | dev_info(&dev->dev, "quirk: region %04x-%04x claimed by %s\n", region, region + size - 1, name); | 372 | dev_info(&dev->dev, "quirk: %pR claimed by %s\n", |
373 | res, name); | ||
361 | } | 374 | } |
362 | } | 375 | } |
363 | 376 | ||
@@ -1680,6 +1693,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_ | |||
1680 | */ | 1693 | */ |
1681 | #define AMD_813X_MISC 0x40 | 1694 | #define AMD_813X_MISC 0x40 |
1682 | #define AMD_813X_NOIOAMODE (1<<0) | 1695 | #define AMD_813X_NOIOAMODE (1<<0) |
1696 | #define AMD_813X_REV_B1 0x12 | ||
1683 | #define AMD_813X_REV_B2 0x13 | 1697 | #define AMD_813X_REV_B2 0x13 |
1684 | 1698 | ||
1685 | static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) | 1699 | static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) |
@@ -1688,7 +1702,8 @@ static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) | |||
1688 | 1702 | ||
1689 | if (noioapicquirk) | 1703 | if (noioapicquirk) |
1690 | return; | 1704 | return; |
1691 | if (dev->revision == AMD_813X_REV_B2) | 1705 | if ((dev->revision == AMD_813X_REV_B1) || |
1706 | (dev->revision == AMD_813X_REV_B2)) | ||
1692 | return; | 1707 | return; |
1693 | 1708 | ||
1694 | pci_read_config_dword(dev, AMD_813X_MISC, &pci_config_dword); | 1709 | pci_read_config_dword(dev, AMD_813X_MISC, &pci_config_dword); |
@@ -1698,8 +1713,10 @@ static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) | |||
1698 | dev_info(&dev->dev, "disabled boot interrupts on device [%04x:%04x]\n", | 1713 | dev_info(&dev->dev, "disabled boot interrupts on device [%04x:%04x]\n", |
1699 | dev->vendor, dev->device); | 1714 | dev->vendor, dev->device); |
1700 | } | 1715 | } |
1701 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_amd_813x_boot_interrupt); | 1716 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_amd_813x_boot_interrupt); |
1702 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8132_BRIDGE, quirk_disable_amd_813x_boot_interrupt); | 1717 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_amd_813x_boot_interrupt); |
1718 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8132_BRIDGE, quirk_disable_amd_813x_boot_interrupt); | ||
1719 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8132_BRIDGE, quirk_disable_amd_813x_boot_interrupt); | ||
1703 | 1720 | ||
1704 | #define AMD_8111_PCI_IRQ_ROUTING 0x56 | 1721 | #define AMD_8111_PCI_IRQ_ROUTING 0x56 |
1705 | 1722 | ||
@@ -1961,11 +1978,25 @@ static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev) | |||
1961 | /* | 1978 | /* |
1962 | * Disable PCI Bus Parking and PCI Master read caching on CX700 | 1979 | * Disable PCI Bus Parking and PCI Master read caching on CX700 |
1963 | * which causes unspecified timing errors with a VT6212L on the PCI | 1980 | * which causes unspecified timing errors with a VT6212L on the PCI |
1964 | * bus leading to USB2.0 packet loss. The defaults are that these | 1981 | * bus leading to USB2.0 packet loss. |
1965 | * features are turned off but some BIOSes turn them on. | 1982 | * |
1983 | * This quirk is only enabled if a second (on the external PCI bus) | ||
1984 | * VT6212L is found -- the CX700 core itself also contains a USB | ||
1985 | * host controller with the same PCI ID as the VT6212L. | ||
1966 | */ | 1986 | */ |
1967 | 1987 | ||
1988 | /* Count VT6212L instances */ | ||
1989 | struct pci_dev *p = pci_get_device(PCI_VENDOR_ID_VIA, | ||
1990 | PCI_DEVICE_ID_VIA_8235_USB_2, NULL); | ||
1968 | uint8_t b; | 1991 | uint8_t b; |
1992 | |||
1993 | /* p should contain the first (internal) VT6212L -- see if we have | ||
1994 | an external one by searching again */ | ||
1995 | p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235_USB_2, p); | ||
1996 | if (!p) | ||
1997 | return; | ||
1998 | pci_dev_put(p); | ||
1999 | |||
1969 | if (pci_read_config_byte(dev, 0x76, &b) == 0) { | 2000 | if (pci_read_config_byte(dev, 0x76, &b) == 0) { |
1970 | if (b & 0x40) { | 2001 | if (b & 0x40) { |
1971 | /* Turn off PCI Bus Parking */ | 2002 | /* Turn off PCI Bus Parking */ |
@@ -1992,7 +2023,7 @@ static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev) | |||
1992 | } | 2023 | } |
1993 | } | 2024 | } |
1994 | } | 2025 | } |
1995 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_caching); | 2026 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_caching); |
1996 | 2027 | ||
1997 | /* | 2028 | /* |
1998 | * For Broadcom 5706, 5708, 5709 rev. A nics, any read beyond the | 2029 | * For Broadcom 5706, 5708, 5709 rev. A nics, any read beyond the |
@@ -2092,6 +2123,10 @@ static void __devinit quirk_disable_msi(struct pci_dev *dev) | |||
2092 | } | 2123 | } |
2093 | } | 2124 | } |
2094 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi); | 2125 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi); |
2126 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x9602, quirk_disable_msi); | ||
2127 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASUSTEK, 0x9602, quirk_disable_msi); | ||
2128 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AI, 0x9602, quirk_disable_msi); | ||
2129 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0xa238, quirk_disable_msi); | ||
2095 | 2130 | ||
2096 | /* Go through the list of Hypertransport capabilities and | 2131 | /* Go through the list of Hypertransport capabilities and |
2097 | * return 1 if a HT MSI capability is found and enabled */ | 2132 | * return 1 if a HT MSI capability is found and enabled */ |
@@ -2513,9 +2548,95 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e7, quirk_i82576_sriov); | |||
2513 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e8, quirk_i82576_sriov); | 2548 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e8, quirk_i82576_sriov); |
2514 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x150a, quirk_i82576_sriov); | 2549 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x150a, quirk_i82576_sriov); |
2515 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x150d, quirk_i82576_sriov); | 2550 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x150d, quirk_i82576_sriov); |
2551 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1518, quirk_i82576_sriov); | ||
2516 | 2552 | ||
2517 | #endif /* CONFIG_PCI_IOV */ | 2553 | #endif /* CONFIG_PCI_IOV */ |
2518 | 2554 | ||
2555 | /* | ||
2556 | * This is a quirk for the Ricoh MMC controller found as a part of | ||
2557 | * some mulifunction chips. | ||
2558 | |||
2559 | * This is very similiar and based on the ricoh_mmc driver written by | ||
2560 | * Philip Langdale. Thank you for these magic sequences. | ||
2561 | * | ||
2562 | * These chips implement the four main memory card controllers (SD, MMC, MS, xD) | ||
2563 | * and one or both of cardbus or firewire. | ||
2564 | * | ||
2565 | * It happens that they implement SD and MMC | ||
2566 | * support as separate controllers (and PCI functions). The linux SDHCI | ||
2567 | * driver supports MMC cards but the chip detects MMC cards in hardware | ||
2568 | * and directs them to the MMC controller - so the SDHCI driver never sees | ||
2569 | * them. | ||
2570 | * | ||
2571 | * To get around this, we must disable the useless MMC controller. | ||
2572 | * At that point, the SDHCI controller will start seeing them | ||
2573 | * It seems to be the case that the relevant PCI registers to deactivate the | ||
2574 | * MMC controller live on PCI function 0, which might be the cardbus controller | ||
2575 | * or the firewire controller, depending on the particular chip in question | ||
2576 | * | ||
2577 | * This has to be done early, because as soon as we disable the MMC controller | ||
2578 | * other pci functions shift up one level, e.g. function #2 becomes function | ||
2579 | * #1, and this will confuse the pci core. | ||
2580 | */ | ||
2581 | |||
2582 | #ifdef CONFIG_MMC_RICOH_MMC | ||
2583 | static void ricoh_mmc_fixup_rl5c476(struct pci_dev *dev) | ||
2584 | { | ||
2585 | /* disable via cardbus interface */ | ||
2586 | u8 write_enable; | ||
2587 | u8 write_target; | ||
2588 | u8 disable; | ||
2589 | |||
2590 | /* disable must be done via function #0 */ | ||
2591 | if (PCI_FUNC(dev->devfn)) | ||
2592 | return; | ||
2593 | |||
2594 | pci_read_config_byte(dev, 0xB7, &disable); | ||
2595 | if (disable & 0x02) | ||
2596 | return; | ||
2597 | |||
2598 | pci_read_config_byte(dev, 0x8E, &write_enable); | ||
2599 | pci_write_config_byte(dev, 0x8E, 0xAA); | ||
2600 | pci_read_config_byte(dev, 0x8D, &write_target); | ||
2601 | pci_write_config_byte(dev, 0x8D, 0xB7); | ||
2602 | pci_write_config_byte(dev, 0xB7, disable | 0x02); | ||
2603 | pci_write_config_byte(dev, 0x8E, write_enable); | ||
2604 | pci_write_config_byte(dev, 0x8D, write_target); | ||
2605 | |||
2606 | dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via cardbus function)\n"); | ||
2607 | dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n"); | ||
2608 | } | ||
2609 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, ricoh_mmc_fixup_rl5c476); | ||
2610 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, ricoh_mmc_fixup_rl5c476); | ||
2611 | |||
2612 | static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev) | ||
2613 | { | ||
2614 | /* disable via firewire interface */ | ||
2615 | u8 write_enable; | ||
2616 | u8 disable; | ||
2617 | |||
2618 | /* disable must be done via function #0 */ | ||
2619 | if (PCI_FUNC(dev->devfn)) | ||
2620 | return; | ||
2621 | |||
2622 | pci_read_config_byte(dev, 0xCB, &disable); | ||
2623 | |||
2624 | if (disable & 0x02) | ||
2625 | return; | ||
2626 | |||
2627 | pci_read_config_byte(dev, 0xCA, &write_enable); | ||
2628 | pci_write_config_byte(dev, 0xCA, 0x57); | ||
2629 | pci_write_config_byte(dev, 0xCB, disable | 0x02); | ||
2630 | pci_write_config_byte(dev, 0xCA, write_enable); | ||
2631 | |||
2632 | dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via firewire function)\n"); | ||
2633 | dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n"); | ||
2634 | } | ||
2635 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); | ||
2636 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); | ||
2637 | #endif /*CONFIG_MMC_RICOH_MMC*/ | ||
2638 | |||
2639 | |||
2519 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, | 2640 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, |
2520 | struct pci_fixup *end) | 2641 | struct pci_fixup *end) |
2521 | { | 2642 | { |
@@ -2591,20 +2712,115 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) | |||
2591 | } | 2712 | } |
2592 | pci_do_fixups(dev, start, end); | 2713 | pci_do_fixups(dev, start, end); |
2593 | } | 2714 | } |
2715 | EXPORT_SYMBOL(pci_fixup_device); | ||
2594 | 2716 | ||
2595 | static int __init pci_apply_final_quirks(void) | 2717 | static int __init pci_apply_final_quirks(void) |
2596 | { | 2718 | { |
2597 | struct pci_dev *dev = NULL; | 2719 | struct pci_dev *dev = NULL; |
2720 | u8 cls = 0; | ||
2721 | u8 tmp; | ||
2722 | |||
2723 | if (pci_cache_line_size) | ||
2724 | printk(KERN_DEBUG "PCI: CLS %u bytes\n", | ||
2725 | pci_cache_line_size << 2); | ||
2598 | 2726 | ||
2599 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | 2727 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { |
2600 | pci_fixup_device(pci_fixup_final, dev); | 2728 | pci_fixup_device(pci_fixup_final, dev); |
2729 | /* | ||
2730 | * If arch hasn't set it explicitly yet, use the CLS | ||
2731 | * value shared by all PCI devices. If there's a | ||
2732 | * mismatch, fall back to the default value. | ||
2733 | */ | ||
2734 | if (!pci_cache_line_size) { | ||
2735 | pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp); | ||
2736 | if (!cls) | ||
2737 | cls = tmp; | ||
2738 | if (!tmp || cls == tmp) | ||
2739 | continue; | ||
2740 | |||
2741 | printk(KERN_DEBUG "PCI: CLS mismatch (%u != %u), " | ||
2742 | "using %u bytes\n", cls << 2, tmp << 2, | ||
2743 | pci_dfl_cache_line_size << 2); | ||
2744 | pci_cache_line_size = pci_dfl_cache_line_size; | ||
2745 | } | ||
2746 | } | ||
2747 | if (!pci_cache_line_size) { | ||
2748 | printk(KERN_DEBUG "PCI: CLS %u bytes, default %u\n", | ||
2749 | cls << 2, pci_dfl_cache_line_size << 2); | ||
2750 | pci_cache_line_size = cls ? cls : pci_dfl_cache_line_size; | ||
2601 | } | 2751 | } |
2602 | 2752 | ||
2603 | return 0; | 2753 | return 0; |
2604 | } | 2754 | } |
2605 | 2755 | ||
2606 | fs_initcall_sync(pci_apply_final_quirks); | 2756 | fs_initcall_sync(pci_apply_final_quirks); |
2607 | #else | 2757 | |
2608 | void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) {} | 2758 | /* |
2609 | #endif | 2759 | * Followings are device-specific reset methods which can be used to |
2610 | EXPORT_SYMBOL(pci_fixup_device); | 2760 | * reset a single function if other methods (e.g. FLR, PM D0->D3) are |
2761 | * not available. | ||
2762 | */ | ||
2763 | static int reset_intel_generic_dev(struct pci_dev *dev, int probe) | ||
2764 | { | ||
2765 | int pos; | ||
2766 | |||
2767 | /* only implement PCI_CLASS_SERIAL_USB at present */ | ||
2768 | if (dev->class == PCI_CLASS_SERIAL_USB) { | ||
2769 | pos = pci_find_capability(dev, PCI_CAP_ID_VNDR); | ||
2770 | if (!pos) | ||
2771 | return -ENOTTY; | ||
2772 | |||
2773 | if (probe) | ||
2774 | return 0; | ||
2775 | |||
2776 | pci_write_config_byte(dev, pos + 0x4, 1); | ||
2777 | msleep(100); | ||
2778 | |||
2779 | return 0; | ||
2780 | } else { | ||
2781 | return -ENOTTY; | ||
2782 | } | ||
2783 | } | ||
2784 | |||
2785 | static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe) | ||
2786 | { | ||
2787 | int pos; | ||
2788 | |||
2789 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | ||
2790 | if (!pos) | ||
2791 | return -ENOTTY; | ||
2792 | |||
2793 | if (probe) | ||
2794 | return 0; | ||
2795 | |||
2796 | pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, | ||
2797 | PCI_EXP_DEVCTL_BCR_FLR); | ||
2798 | msleep(100); | ||
2799 | |||
2800 | return 0; | ||
2801 | } | ||
2802 | |||
2803 | #define PCI_DEVICE_ID_INTEL_82599_SFP_VF 0x10ed | ||
2804 | |||
2805 | static const struct pci_dev_reset_methods pci_dev_reset_methods[] = { | ||
2806 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF, | ||
2807 | reset_intel_82599_sfp_virtfn }, | ||
2808 | { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, | ||
2809 | reset_intel_generic_dev }, | ||
2810 | { 0 } | ||
2811 | }; | ||
2812 | |||
2813 | int pci_dev_specific_reset(struct pci_dev *dev, int probe) | ||
2814 | { | ||
2815 | const struct pci_dev_reset_methods *i; | ||
2816 | |||
2817 | for (i = pci_dev_reset_methods; i->reset; i++) { | ||
2818 | if ((i->vendor == dev->vendor || | ||
2819 | i->vendor == (u16)PCI_ANY_ID) && | ||
2820 | (i->device == dev->device || | ||
2821 | i->device == (u16)PCI_ANY_ID)) | ||
2822 | return i->reset(dev, probe); | ||
2823 | } | ||
2824 | |||
2825 | return -ENOTTY; | ||
2826 | } | ||
diff --git a/drivers/pci/search.c b/drivers/pci/search.c index ec415352d9ba..20d03f772289 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c | |||
@@ -9,15 +9,16 @@ | |||
9 | 9 | ||
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/pci.h> | 11 | #include <linux/pci.h> |
12 | #include <linux/slab.h> | ||
12 | #include <linux/module.h> | 13 | #include <linux/module.h> |
13 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
14 | #include "pci.h" | 15 | #include "pci.h" |
15 | 16 | ||
16 | DECLARE_RWSEM(pci_bus_sem); | 17 | DECLARE_RWSEM(pci_bus_sem); |
17 | /* | 18 | /* |
18 | * find the upstream PCIE-to-PCI bridge of a PCI device | 19 | * find the upstream PCIe-to-PCI bridge of a PCI device |
19 | * if the device is PCIE, return NULL | 20 | * if the device is PCIE, return NULL |
20 | * if the device isn't connected to a PCIE bridge (that is its parent is a | 21 | * if the device isn't connected to a PCIe bridge (that is its parent is a |
21 | * legacy PCI bridge and the bridge is directly connected to bus 0), return its | 22 | * legacy PCI bridge and the bridge is directly connected to bus 0), return its |
22 | * parent | 23 | * parent |
23 | */ | 24 | */ |
@@ -26,18 +27,18 @@ pci_find_upstream_pcie_bridge(struct pci_dev *pdev) | |||
26 | { | 27 | { |
27 | struct pci_dev *tmp = NULL; | 28 | struct pci_dev *tmp = NULL; |
28 | 29 | ||
29 | if (pdev->is_pcie) | 30 | if (pci_is_pcie(pdev)) |
30 | return NULL; | 31 | return NULL; |
31 | while (1) { | 32 | while (1) { |
32 | if (pci_is_root_bus(pdev->bus)) | 33 | if (pci_is_root_bus(pdev->bus)) |
33 | break; | 34 | break; |
34 | pdev = pdev->bus->self; | 35 | pdev = pdev->bus->self; |
35 | /* a p2p bridge */ | 36 | /* a p2p bridge */ |
36 | if (!pdev->is_pcie) { | 37 | if (!pci_is_pcie(pdev)) { |
37 | tmp = pdev; | 38 | tmp = pdev; |
38 | continue; | 39 | continue; |
39 | } | 40 | } |
40 | /* PCI device should connect to a PCIE bridge */ | 41 | /* PCI device should connect to a PCIe bridge */ |
41 | if (pdev->pcie_type != PCI_EXP_TYPE_PCI_BRIDGE) { | 42 | if (pdev->pcie_type != PCI_EXP_TYPE_PCI_BRIDGE) { |
42 | /* Busted hardware? */ | 43 | /* Busted hardware? */ |
43 | WARN_ON_ONCE(1); | 44 | WARN_ON_ONCE(1); |
@@ -149,32 +150,33 @@ struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn) | |||
149 | } | 150 | } |
150 | 151 | ||
151 | /** | 152 | /** |
152 | * pci_get_bus_and_slot - locate PCI device from a given PCI bus & slot | 153 | * pci_get_domain_bus_and_slot - locate PCI device for a given PCI domain (segment), bus, and slot |
153 | * @bus: number of PCI bus on which desired PCI device resides | 154 | * @domain: PCI domain/segment on which the PCI device resides. |
154 | * @devfn: encodes number of PCI slot in which the desired PCI | 155 | * @bus: PCI bus on which desired PCI device resides |
155 | * device resides and the logical device number within that slot | 156 | * @devfn: encodes number of PCI slot in which the desired PCI device |
156 | * in case of multi-function devices. | 157 | * resides and the logical device number within that slot in case of |
157 | * | 158 | * multi-function devices. |
158 | * Note: the bus/slot search is limited to PCI domain (segment) 0. | ||
159 | * | 159 | * |
160 | * Given a PCI bus and slot/function number, the desired PCI device | 160 | * Given a PCI domain, bus, and slot/function number, the desired PCI |
161 | * is located in system global list of PCI devices. If the device | 161 | * device is located in the list of PCI devices. If the device is |
162 | * is found, a pointer to its data structure is returned. If no | 162 | * found, its reference count is increased and this function returns a |
163 | * device is found, %NULL is returned. The returned device has its | 163 | * pointer to its data structure. The caller must decrement the |
164 | * reference count bumped by one. | 164 | * reference count by calling pci_dev_put(). If no device is found, |
165 | * %NULL is returned. | ||
165 | */ | 166 | */ |
166 | 167 | struct pci_dev *pci_get_domain_bus_and_slot(int domain, unsigned int bus, | |
167 | struct pci_dev * pci_get_bus_and_slot(unsigned int bus, unsigned int devfn) | 168 | unsigned int devfn) |
168 | { | 169 | { |
169 | struct pci_dev *dev = NULL; | 170 | struct pci_dev *dev = NULL; |
170 | 171 | ||
171 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | 172 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { |
172 | if (pci_domain_nr(dev->bus) == 0 && | 173 | if (pci_domain_nr(dev->bus) == domain && |
173 | (dev->bus->number == bus && dev->devfn == devfn)) | 174 | (dev->bus->number == bus && dev->devfn == devfn)) |
174 | return dev; | 175 | return dev; |
175 | } | 176 | } |
176 | return NULL; | 177 | return NULL; |
177 | } | 178 | } |
179 | EXPORT_SYMBOL(pci_get_domain_bus_and_slot); | ||
178 | 180 | ||
179 | static int match_pci_dev_by_id(struct device *dev, void *data) | 181 | static int match_pci_dev_by_id(struct device *dev, void *data) |
180 | { | 182 | { |
@@ -354,5 +356,4 @@ EXPORT_SYMBOL(pci_find_next_bus); | |||
354 | EXPORT_SYMBOL(pci_get_device); | 356 | EXPORT_SYMBOL(pci_get_device); |
355 | EXPORT_SYMBOL(pci_get_subsys); | 357 | EXPORT_SYMBOL(pci_get_subsys); |
356 | EXPORT_SYMBOL(pci_get_slot); | 358 | EXPORT_SYMBOL(pci_get_slot); |
357 | EXPORT_SYMBOL(pci_get_bus_and_slot); | ||
358 | EXPORT_SYMBOL(pci_get_class); | 359 | EXPORT_SYMBOL(pci_get_class); |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index cb1a027eb552..19b111383f62 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -27,37 +27,91 @@ | |||
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include "pci.h" | 28 | #include "pci.h" |
29 | 29 | ||
30 | static void pbus_assign_resources_sorted(const struct pci_bus *bus) | 30 | struct resource_list_x { |
31 | { | 31 | struct resource_list_x *next; |
32 | struct pci_dev *dev; | ||
33 | struct resource *res; | 32 | struct resource *res; |
34 | struct resource_list head, *list, *tmp; | 33 | struct pci_dev *dev; |
35 | int idx; | 34 | resource_size_t start; |
35 | resource_size_t end; | ||
36 | unsigned long flags; | ||
37 | }; | ||
36 | 38 | ||
37 | head.next = NULL; | 39 | static void add_to_failed_list(struct resource_list_x *head, |
38 | list_for_each_entry(dev, &bus->devices, bus_list) { | 40 | struct pci_dev *dev, struct resource *res) |
39 | u16 class = dev->class >> 8; | 41 | { |
42 | struct resource_list_x *list = head; | ||
43 | struct resource_list_x *ln = list->next; | ||
44 | struct resource_list_x *tmp; | ||
40 | 45 | ||
41 | /* Don't touch classless devices or host bridges or ioapics. */ | 46 | tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); |
42 | if (class == PCI_CLASS_NOT_DEFINED || | 47 | if (!tmp) { |
43 | class == PCI_CLASS_BRIDGE_HOST) | 48 | pr_warning("add_to_failed_list: kmalloc() failed!\n"); |
44 | continue; | 49 | return; |
50 | } | ||
45 | 51 | ||
46 | /* Don't touch ioapic devices already enabled by firmware */ | 52 | tmp->next = ln; |
47 | if (class == PCI_CLASS_SYSTEM_PIC) { | 53 | tmp->res = res; |
48 | u16 command; | 54 | tmp->dev = dev; |
49 | pci_read_config_word(dev, PCI_COMMAND, &command); | 55 | tmp->start = res->start; |
50 | if (command & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) | 56 | tmp->end = res->end; |
51 | continue; | 57 | tmp->flags = res->flags; |
52 | } | 58 | list->next = tmp; |
59 | } | ||
60 | |||
61 | static void free_failed_list(struct resource_list_x *head) | ||
62 | { | ||
63 | struct resource_list_x *list, *tmp; | ||
53 | 64 | ||
54 | pdev_sort_resources(dev, &head); | 65 | for (list = head->next; list;) { |
66 | tmp = list; | ||
67 | list = list->next; | ||
68 | kfree(tmp); | ||
55 | } | 69 | } |
56 | 70 | ||
57 | for (list = head.next; list;) { | 71 | head->next = NULL; |
72 | } | ||
73 | |||
74 | static void __dev_sort_resources(struct pci_dev *dev, | ||
75 | struct resource_list *head) | ||
76 | { | ||
77 | u16 class = dev->class >> 8; | ||
78 | |||
79 | /* Don't touch classless devices or host bridges or ioapics. */ | ||
80 | if (class == PCI_CLASS_NOT_DEFINED || class == PCI_CLASS_BRIDGE_HOST) | ||
81 | return; | ||
82 | |||
83 | /* Don't touch ioapic devices already enabled by firmware */ | ||
84 | if (class == PCI_CLASS_SYSTEM_PIC) { | ||
85 | u16 command; | ||
86 | pci_read_config_word(dev, PCI_COMMAND, &command); | ||
87 | if (command & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) | ||
88 | return; | ||
89 | } | ||
90 | |||
91 | pdev_sort_resources(dev, head); | ||
92 | } | ||
93 | |||
94 | static void __assign_resources_sorted(struct resource_list *head, | ||
95 | struct resource_list_x *fail_head) | ||
96 | { | ||
97 | struct resource *res; | ||
98 | struct resource_list *list, *tmp; | ||
99 | int idx; | ||
100 | |||
101 | for (list = head->next; list;) { | ||
58 | res = list->res; | 102 | res = list->res; |
59 | idx = res - &list->dev->resource[0]; | 103 | idx = res - &list->dev->resource[0]; |
104 | |||
60 | if (pci_assign_resource(list->dev, idx)) { | 105 | if (pci_assign_resource(list->dev, idx)) { |
106 | if (fail_head && !pci_is_root_bus(list->dev->bus)) { | ||
107 | /* | ||
108 | * if the failed res is for ROM BAR, and it will | ||
109 | * be enabled later, don't add it to the list | ||
110 | */ | ||
111 | if (!((idx == PCI_ROM_RESOURCE) && | ||
112 | (!(res->flags & IORESOURCE_ROM_ENABLE)))) | ||
113 | add_to_failed_list(fail_head, list->dev, res); | ||
114 | } | ||
61 | res->start = 0; | 115 | res->start = 0; |
62 | res->end = 0; | 116 | res->end = 0; |
63 | res->flags = 0; | 117 | res->flags = 0; |
@@ -68,56 +122,77 @@ static void pbus_assign_resources_sorted(const struct pci_bus *bus) | |||
68 | } | 122 | } |
69 | } | 123 | } |
70 | 124 | ||
125 | static void pdev_assign_resources_sorted(struct pci_dev *dev, | ||
126 | struct resource_list_x *fail_head) | ||
127 | { | ||
128 | struct resource_list head; | ||
129 | |||
130 | head.next = NULL; | ||
131 | __dev_sort_resources(dev, &head); | ||
132 | __assign_resources_sorted(&head, fail_head); | ||
133 | |||
134 | } | ||
135 | |||
136 | static void pbus_assign_resources_sorted(const struct pci_bus *bus, | ||
137 | struct resource_list_x *fail_head) | ||
138 | { | ||
139 | struct pci_dev *dev; | ||
140 | struct resource_list head; | ||
141 | |||
142 | head.next = NULL; | ||
143 | list_for_each_entry(dev, &bus->devices, bus_list) | ||
144 | __dev_sort_resources(dev, &head); | ||
145 | |||
146 | __assign_resources_sorted(&head, fail_head); | ||
147 | } | ||
148 | |||
71 | void pci_setup_cardbus(struct pci_bus *bus) | 149 | void pci_setup_cardbus(struct pci_bus *bus) |
72 | { | 150 | { |
73 | struct pci_dev *bridge = bus->self; | 151 | struct pci_dev *bridge = bus->self; |
152 | struct resource *res; | ||
74 | struct pci_bus_region region; | 153 | struct pci_bus_region region; |
75 | 154 | ||
76 | dev_info(&bridge->dev, "CardBus bridge, secondary bus %04x:%02x\n", | 155 | dev_info(&bridge->dev, "CardBus bridge to [bus %02x-%02x]\n", |
77 | pci_domain_nr(bus), bus->number); | 156 | bus->secondary, bus->subordinate); |
78 | 157 | ||
79 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[0]); | 158 | res = bus->resource[0]; |
80 | if (bus->resource[0]->flags & IORESOURCE_IO) { | 159 | pcibios_resource_to_bus(bridge, ®ion, res); |
160 | if (res->flags & IORESOURCE_IO) { | ||
81 | /* | 161 | /* |
82 | * The IO resource is allocated a range twice as large as it | 162 | * The IO resource is allocated a range twice as large as it |
83 | * would normally need. This allows us to set both IO regs. | 163 | * would normally need. This allows us to set both IO regs. |
84 | */ | 164 | */ |
85 | dev_info(&bridge->dev, " IO window: %#08lx-%#08lx\n", | 165 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
86 | (unsigned long)region.start, | ||
87 | (unsigned long)region.end); | ||
88 | pci_write_config_dword(bridge, PCI_CB_IO_BASE_0, | 166 | pci_write_config_dword(bridge, PCI_CB_IO_BASE_0, |
89 | region.start); | 167 | region.start); |
90 | pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0, | 168 | pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0, |
91 | region.end); | 169 | region.end); |
92 | } | 170 | } |
93 | 171 | ||
94 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[1]); | 172 | res = bus->resource[1]; |
95 | if (bus->resource[1]->flags & IORESOURCE_IO) { | 173 | pcibios_resource_to_bus(bridge, ®ion, res); |
96 | dev_info(&bridge->dev, " IO window: %#08lx-%#08lx\n", | 174 | if (res->flags & IORESOURCE_IO) { |
97 | (unsigned long)region.start, | 175 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
98 | (unsigned long)region.end); | ||
99 | pci_write_config_dword(bridge, PCI_CB_IO_BASE_1, | 176 | pci_write_config_dword(bridge, PCI_CB_IO_BASE_1, |
100 | region.start); | 177 | region.start); |
101 | pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1, | 178 | pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1, |
102 | region.end); | 179 | region.end); |
103 | } | 180 | } |
104 | 181 | ||
105 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]); | 182 | res = bus->resource[2]; |
106 | if (bus->resource[2]->flags & IORESOURCE_MEM) { | 183 | pcibios_resource_to_bus(bridge, ®ion, res); |
107 | dev_info(&bridge->dev, " PREFETCH window: %#08lx-%#08lx\n", | 184 | if (res->flags & IORESOURCE_MEM) { |
108 | (unsigned long)region.start, | 185 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
109 | (unsigned long)region.end); | ||
110 | pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0, | 186 | pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0, |
111 | region.start); | 187 | region.start); |
112 | pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0, | 188 | pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0, |
113 | region.end); | 189 | region.end); |
114 | } | 190 | } |
115 | 191 | ||
116 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[3]); | 192 | res = bus->resource[3]; |
117 | if (bus->resource[3]->flags & IORESOURCE_MEM) { | 193 | pcibios_resource_to_bus(bridge, ®ion, res); |
118 | dev_info(&bridge->dev, " MEM window: %#08lx-%#08lx\n", | 194 | if (res->flags & IORESOURCE_MEM) { |
119 | (unsigned long)region.start, | 195 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
120 | (unsigned long)region.end); | ||
121 | pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1, | 196 | pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1, |
122 | region.start); | 197 | region.start); |
123 | pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1, | 198 | pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1, |
@@ -137,37 +212,29 @@ EXPORT_SYMBOL(pci_setup_cardbus); | |||
137 | config space writes, so it's quite possible that an I/O window of | 212 | config space writes, so it's quite possible that an I/O window of |
138 | the bridge will have some undesirable address (e.g. 0) after the | 213 | the bridge will have some undesirable address (e.g. 0) after the |
139 | first write. Ditto 64-bit prefetchable MMIO. */ | 214 | first write. Ditto 64-bit prefetchable MMIO. */ |
140 | static void pci_setup_bridge(struct pci_bus *bus) | 215 | static void pci_setup_bridge_io(struct pci_bus *bus) |
141 | { | 216 | { |
142 | struct pci_dev *bridge = bus->self; | 217 | struct pci_dev *bridge = bus->self; |
218 | struct resource *res; | ||
143 | struct pci_bus_region region; | 219 | struct pci_bus_region region; |
144 | u32 l, bu, lu, io_upper16; | 220 | u32 l, io_upper16; |
145 | int pref_mem64; | ||
146 | |||
147 | if (pci_is_enabled(bridge)) | ||
148 | return; | ||
149 | |||
150 | dev_info(&bridge->dev, "PCI bridge, secondary bus %04x:%02x\n", | ||
151 | pci_domain_nr(bus), bus->number); | ||
152 | 221 | ||
153 | /* Set up the top and bottom of the PCI I/O segment for this bus. */ | 222 | /* Set up the top and bottom of the PCI I/O segment for this bus. */ |
154 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[0]); | 223 | res = bus->resource[0]; |
155 | if (bus->resource[0]->flags & IORESOURCE_IO) { | 224 | pcibios_resource_to_bus(bridge, ®ion, res); |
225 | if (res->flags & IORESOURCE_IO) { | ||
156 | pci_read_config_dword(bridge, PCI_IO_BASE, &l); | 226 | pci_read_config_dword(bridge, PCI_IO_BASE, &l); |
157 | l &= 0xffff0000; | 227 | l &= 0xffff0000; |
158 | l |= (region.start >> 8) & 0x00f0; | 228 | l |= (region.start >> 8) & 0x00f0; |
159 | l |= region.end & 0xf000; | 229 | l |= region.end & 0xf000; |
160 | /* Set up upper 16 bits of I/O base/limit. */ | 230 | /* Set up upper 16 bits of I/O base/limit. */ |
161 | io_upper16 = (region.end & 0xffff0000) | (region.start >> 16); | 231 | io_upper16 = (region.end & 0xffff0000) | (region.start >> 16); |
162 | dev_info(&bridge->dev, " IO window: %#04lx-%#04lx\n", | 232 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
163 | (unsigned long)region.start, | 233 | } else { |
164 | (unsigned long)region.end); | ||
165 | } | ||
166 | else { | ||
167 | /* Clear upper 16 bits of I/O base/limit. */ | 234 | /* Clear upper 16 bits of I/O base/limit. */ |
168 | io_upper16 = 0; | 235 | io_upper16 = 0; |
169 | l = 0x00f0; | 236 | l = 0x00f0; |
170 | dev_info(&bridge->dev, " IO window: disabled\n"); | 237 | dev_info(&bridge->dev, " bridge window [io disabled]\n"); |
171 | } | 238 | } |
172 | /* Temporarily disable the I/O range before updating PCI_IO_BASE. */ | 239 | /* Temporarily disable the I/O range before updating PCI_IO_BASE. */ |
173 | pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0x0000ffff); | 240 | pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0x0000ffff); |
@@ -175,22 +242,35 @@ static void pci_setup_bridge(struct pci_bus *bus) | |||
175 | pci_write_config_dword(bridge, PCI_IO_BASE, l); | 242 | pci_write_config_dword(bridge, PCI_IO_BASE, l); |
176 | /* Update upper 16 bits of I/O base/limit. */ | 243 | /* Update upper 16 bits of I/O base/limit. */ |
177 | pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, io_upper16); | 244 | pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, io_upper16); |
245 | } | ||
178 | 246 | ||
179 | /* Set up the top and bottom of the PCI Memory segment | 247 | static void pci_setup_bridge_mmio(struct pci_bus *bus) |
180 | for this bus. */ | 248 | { |
181 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[1]); | 249 | struct pci_dev *bridge = bus->self; |
182 | if (bus->resource[1]->flags & IORESOURCE_MEM) { | 250 | struct resource *res; |
251 | struct pci_bus_region region; | ||
252 | u32 l; | ||
253 | |||
254 | /* Set up the top and bottom of the PCI Memory segment for this bus. */ | ||
255 | res = bus->resource[1]; | ||
256 | pcibios_resource_to_bus(bridge, ®ion, res); | ||
257 | if (res->flags & IORESOURCE_MEM) { | ||
183 | l = (region.start >> 16) & 0xfff0; | 258 | l = (region.start >> 16) & 0xfff0; |
184 | l |= region.end & 0xfff00000; | 259 | l |= region.end & 0xfff00000; |
185 | dev_info(&bridge->dev, " MEM window: %#08lx-%#08lx\n", | 260 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
186 | (unsigned long)region.start, | 261 | } else { |
187 | (unsigned long)region.end); | ||
188 | } | ||
189 | else { | ||
190 | l = 0x0000fff0; | 262 | l = 0x0000fff0; |
191 | dev_info(&bridge->dev, " MEM window: disabled\n"); | 263 | dev_info(&bridge->dev, " bridge window [mem disabled]\n"); |
192 | } | 264 | } |
193 | pci_write_config_dword(bridge, PCI_MEMORY_BASE, l); | 265 | pci_write_config_dword(bridge, PCI_MEMORY_BASE, l); |
266 | } | ||
267 | |||
268 | static void pci_setup_bridge_mmio_pref(struct pci_bus *bus) | ||
269 | { | ||
270 | struct pci_dev *bridge = bus->self; | ||
271 | struct resource *res; | ||
272 | struct pci_bus_region region; | ||
273 | u32 l, bu, lu; | ||
194 | 274 | ||
195 | /* Clear out the upper 32 bits of PREF limit. | 275 | /* Clear out the upper 32 bits of PREF limit. |
196 | If PCI_PREF_BASE_UPPER32 was non-zero, this temporarily | 276 | If PCI_PREF_BASE_UPPER32 was non-zero, this temporarily |
@@ -198,38 +278,55 @@ static void pci_setup_bridge(struct pci_bus *bus) | |||
198 | pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0); | 278 | pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0); |
199 | 279 | ||
200 | /* Set up PREF base/limit. */ | 280 | /* Set up PREF base/limit. */ |
201 | pref_mem64 = 0; | ||
202 | bu = lu = 0; | 281 | bu = lu = 0; |
203 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]); | 282 | res = bus->resource[2]; |
204 | if (bus->resource[2]->flags & IORESOURCE_PREFETCH) { | 283 | pcibios_resource_to_bus(bridge, ®ion, res); |
205 | int width = 8; | 284 | if (res->flags & IORESOURCE_PREFETCH) { |
206 | l = (region.start >> 16) & 0xfff0; | 285 | l = (region.start >> 16) & 0xfff0; |
207 | l |= region.end & 0xfff00000; | 286 | l |= region.end & 0xfff00000; |
208 | if (bus->resource[2]->flags & IORESOURCE_MEM_64) { | 287 | if (res->flags & IORESOURCE_MEM_64) { |
209 | pref_mem64 = 1; | ||
210 | bu = upper_32_bits(region.start); | 288 | bu = upper_32_bits(region.start); |
211 | lu = upper_32_bits(region.end); | 289 | lu = upper_32_bits(region.end); |
212 | width = 16; | ||
213 | } | 290 | } |
214 | dev_info(&bridge->dev, " PREFETCH window: %#0*llx-%#0*llx\n", | 291 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
215 | width, (unsigned long long)region.start, | 292 | } else { |
216 | width, (unsigned long long)region.end); | ||
217 | } | ||
218 | else { | ||
219 | l = 0x0000fff0; | 293 | l = 0x0000fff0; |
220 | dev_info(&bridge->dev, " PREFETCH window: disabled\n"); | 294 | dev_info(&bridge->dev, " bridge window [mem pref disabled]\n"); |
221 | } | 295 | } |
222 | pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l); | 296 | pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l); |
223 | 297 | ||
224 | if (pref_mem64) { | 298 | /* Set the upper 32 bits of PREF base & limit. */ |
225 | /* Set the upper 32 bits of PREF base & limit. */ | 299 | pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu); |
226 | pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu); | 300 | pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu); |
227 | pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu); | 301 | } |
228 | } | 302 | |
303 | static void __pci_setup_bridge(struct pci_bus *bus, unsigned long type) | ||
304 | { | ||
305 | struct pci_dev *bridge = bus->self; | ||
306 | |||
307 | dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n", | ||
308 | bus->secondary, bus->subordinate); | ||
309 | |||
310 | if (type & IORESOURCE_IO) | ||
311 | pci_setup_bridge_io(bus); | ||
312 | |||
313 | if (type & IORESOURCE_MEM) | ||
314 | pci_setup_bridge_mmio(bus); | ||
315 | |||
316 | if (type & IORESOURCE_PREFETCH) | ||
317 | pci_setup_bridge_mmio_pref(bus); | ||
229 | 318 | ||
230 | pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl); | 319 | pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl); |
231 | } | 320 | } |
232 | 321 | ||
322 | static void pci_setup_bridge(struct pci_bus *bus) | ||
323 | { | ||
324 | unsigned long type = IORESOURCE_IO | IORESOURCE_MEM | | ||
325 | IORESOURCE_PREFETCH; | ||
326 | |||
327 | __pci_setup_bridge(bus, type); | ||
328 | } | ||
329 | |||
233 | /* Check whether the bridge supports optional I/O and | 330 | /* Check whether the bridge supports optional I/O and |
234 | prefetchable memory ranges. If not, the respective | 331 | prefetchable memory ranges. If not, the respective |
235 | base/limit registers must be read-only and read as 0. */ | 332 | base/limit registers must be read-only and read as 0. */ |
@@ -265,8 +362,11 @@ static void pci_bridge_check_ranges(struct pci_bus *bus) | |||
265 | } | 362 | } |
266 | if (pmem) { | 363 | if (pmem) { |
267 | b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH; | 364 | b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH; |
268 | if ((pmem & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) | 365 | if ((pmem & PCI_PREF_RANGE_TYPE_MASK) == |
366 | PCI_PREF_RANGE_TYPE_64) { | ||
269 | b_res[2].flags |= IORESOURCE_MEM_64; | 367 | b_res[2].flags |= IORESOURCE_MEM_64; |
368 | b_res[2].flags |= PCI_PREF_RANGE_TYPE_64; | ||
369 | } | ||
270 | } | 370 | } |
271 | 371 | ||
272 | /* double check if bridge does support 64 bit pref */ | 372 | /* double check if bridge does support 64 bit pref */ |
@@ -295,8 +395,7 @@ static struct resource *find_free_bus_resource(struct pci_bus *bus, unsigned lon | |||
295 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | | 395 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | |
296 | IORESOURCE_PREFETCH; | 396 | IORESOURCE_PREFETCH; |
297 | 397 | ||
298 | for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { | 398 | pci_bus_for_each_resource(bus, r, i) { |
299 | r = bus->resource[i]; | ||
300 | if (r == &ioport_resource || r == &iomem_resource) | 399 | if (r == &ioport_resource || r == &iomem_resource) |
301 | continue; | 400 | continue; |
302 | if (r && (r->flags & type_mask) == type && !r->parent) | 401 | if (r && (r->flags & type_mask) == type && !r->parent) |
@@ -313,7 +412,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size) | |||
313 | { | 412 | { |
314 | struct pci_dev *dev; | 413 | struct pci_dev *dev; |
315 | struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); | 414 | struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); |
316 | unsigned long size = 0, size1 = 0; | 415 | unsigned long size = 0, size1 = 0, old_size; |
317 | 416 | ||
318 | if (!b_res) | 417 | if (!b_res) |
319 | return; | 418 | return; |
@@ -338,13 +437,22 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size) | |||
338 | } | 437 | } |
339 | if (size < min_size) | 438 | if (size < min_size) |
340 | size = min_size; | 439 | size = min_size; |
440 | old_size = resource_size(b_res); | ||
441 | if (old_size == 1) | ||
442 | old_size = 0; | ||
341 | /* To be fixed in 2.5: we should have sort of HAVE_ISA | 443 | /* To be fixed in 2.5: we should have sort of HAVE_ISA |
342 | flag in the struct pci_bus. */ | 444 | flag in the struct pci_bus. */ |
343 | #if defined(CONFIG_ISA) || defined(CONFIG_EISA) | 445 | #if defined(CONFIG_ISA) || defined(CONFIG_EISA) |
344 | size = (size & 0xff) + ((size & ~0xffUL) << 2); | 446 | size = (size & 0xff) + ((size & ~0xffUL) << 2); |
345 | #endif | 447 | #endif |
346 | size = ALIGN(size + size1, 4096); | 448 | size = ALIGN(size + size1, 4096); |
449 | if (size < old_size) | ||
450 | size = old_size; | ||
347 | if (!size) { | 451 | if (!size) { |
452 | if (b_res->start || b_res->end) | ||
453 | dev_info(&bus->self->dev, "disabling bridge window " | ||
454 | "%pR to [bus %02x-%02x] (unused)\n", b_res, | ||
455 | bus->secondary, bus->subordinate); | ||
348 | b_res->flags = 0; | 456 | b_res->flags = 0; |
349 | return; | 457 | return; |
350 | } | 458 | } |
@@ -360,7 +468,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
360 | unsigned long type, resource_size_t min_size) | 468 | unsigned long type, resource_size_t min_size) |
361 | { | 469 | { |
362 | struct pci_dev *dev; | 470 | struct pci_dev *dev; |
363 | resource_size_t min_align, align, size; | 471 | resource_size_t min_align, align, size, old_size; |
364 | resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */ | 472 | resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */ |
365 | int order, max_order; | 473 | int order, max_order; |
366 | struct resource *b_res = find_free_bus_resource(bus, type); | 474 | struct resource *b_res = find_free_bus_resource(bus, type); |
@@ -390,8 +498,9 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
390 | align = pci_resource_alignment(dev, r); | 498 | align = pci_resource_alignment(dev, r); |
391 | order = __ffs(align) - 20; | 499 | order = __ffs(align) - 20; |
392 | if (order > 11) { | 500 | if (order > 11) { |
393 | dev_warn(&dev->dev, "BAR %d bad alignment %llx: " | 501 | dev_warn(&dev->dev, "disabling BAR %d: %pR " |
394 | "%pR\n", i, (unsigned long long)align, r); | 502 | "(bad alignment %#llx)\n", i, r, |
503 | (unsigned long long) align); | ||
395 | r->flags = 0; | 504 | r->flags = 0; |
396 | continue; | 505 | continue; |
397 | } | 506 | } |
@@ -409,6 +518,11 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
409 | } | 518 | } |
410 | if (size < min_size) | 519 | if (size < min_size) |
411 | size = min_size; | 520 | size = min_size; |
521 | old_size = resource_size(b_res); | ||
522 | if (old_size == 1) | ||
523 | old_size = 0; | ||
524 | if (size < old_size) | ||
525 | size = old_size; | ||
412 | 526 | ||
413 | align = 0; | 527 | align = 0; |
414 | min_align = 0; | 528 | min_align = 0; |
@@ -425,6 +539,10 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
425 | } | 539 | } |
426 | size = ALIGN(size, min_align); | 540 | size = ALIGN(size, min_align); |
427 | if (!size) { | 541 | if (!size) { |
542 | if (b_res->start || b_res->end) | ||
543 | dev_info(&bus->self->dev, "disabling bridge window " | ||
544 | "%pR to [bus %02x-%02x] (unused)\n", b_res, | ||
545 | bus->secondary, bus->subordinate); | ||
428 | b_res->flags = 0; | 546 | b_res->flags = 0; |
429 | return 1; | 547 | return 1; |
430 | } | 548 | } |
@@ -541,23 +659,25 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus) | |||
541 | } | 659 | } |
542 | EXPORT_SYMBOL(pci_bus_size_bridges); | 660 | EXPORT_SYMBOL(pci_bus_size_bridges); |
543 | 661 | ||
544 | void __ref pci_bus_assign_resources(const struct pci_bus *bus) | 662 | static void __ref __pci_bus_assign_resources(const struct pci_bus *bus, |
663 | struct resource_list_x *fail_head) | ||
545 | { | 664 | { |
546 | struct pci_bus *b; | 665 | struct pci_bus *b; |
547 | struct pci_dev *dev; | 666 | struct pci_dev *dev; |
548 | 667 | ||
549 | pbus_assign_resources_sorted(bus); | 668 | pbus_assign_resources_sorted(bus, fail_head); |
550 | 669 | ||
551 | list_for_each_entry(dev, &bus->devices, bus_list) { | 670 | list_for_each_entry(dev, &bus->devices, bus_list) { |
552 | b = dev->subordinate; | 671 | b = dev->subordinate; |
553 | if (!b) | 672 | if (!b) |
554 | continue; | 673 | continue; |
555 | 674 | ||
556 | pci_bus_assign_resources(b); | 675 | __pci_bus_assign_resources(b, fail_head); |
557 | 676 | ||
558 | switch (dev->class >> 8) { | 677 | switch (dev->class >> 8) { |
559 | case PCI_CLASS_BRIDGE_PCI: | 678 | case PCI_CLASS_BRIDGE_PCI: |
560 | pci_setup_bridge(b); | 679 | if (!pci_is_enabled(dev)) |
680 | pci_setup_bridge(b); | ||
561 | break; | 681 | break; |
562 | 682 | ||
563 | case PCI_CLASS_BRIDGE_CARDBUS: | 683 | case PCI_CLASS_BRIDGE_CARDBUS: |
@@ -571,21 +691,133 @@ void __ref pci_bus_assign_resources(const struct pci_bus *bus) | |||
571 | } | 691 | } |
572 | } | 692 | } |
573 | } | 693 | } |
694 | |||
695 | void __ref pci_bus_assign_resources(const struct pci_bus *bus) | ||
696 | { | ||
697 | __pci_bus_assign_resources(bus, NULL); | ||
698 | } | ||
574 | EXPORT_SYMBOL(pci_bus_assign_resources); | 699 | EXPORT_SYMBOL(pci_bus_assign_resources); |
575 | 700 | ||
701 | static void __ref __pci_bridge_assign_resources(const struct pci_dev *bridge, | ||
702 | struct resource_list_x *fail_head) | ||
703 | { | ||
704 | struct pci_bus *b; | ||
705 | |||
706 | pdev_assign_resources_sorted((struct pci_dev *)bridge, fail_head); | ||
707 | |||
708 | b = bridge->subordinate; | ||
709 | if (!b) | ||
710 | return; | ||
711 | |||
712 | __pci_bus_assign_resources(b, fail_head); | ||
713 | |||
714 | switch (bridge->class >> 8) { | ||
715 | case PCI_CLASS_BRIDGE_PCI: | ||
716 | pci_setup_bridge(b); | ||
717 | break; | ||
718 | |||
719 | case PCI_CLASS_BRIDGE_CARDBUS: | ||
720 | pci_setup_cardbus(b); | ||
721 | break; | ||
722 | |||
723 | default: | ||
724 | dev_info(&bridge->dev, "not setting up bridge for bus " | ||
725 | "%04x:%02x\n", pci_domain_nr(b), b->number); | ||
726 | break; | ||
727 | } | ||
728 | } | ||
729 | static void pci_bridge_release_resources(struct pci_bus *bus, | ||
730 | unsigned long type) | ||
731 | { | ||
732 | int idx; | ||
733 | bool changed = false; | ||
734 | struct pci_dev *dev; | ||
735 | struct resource *r; | ||
736 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | | ||
737 | IORESOURCE_PREFETCH; | ||
738 | |||
739 | dev = bus->self; | ||
740 | for (idx = PCI_BRIDGE_RESOURCES; idx <= PCI_BRIDGE_RESOURCE_END; | ||
741 | idx++) { | ||
742 | r = &dev->resource[idx]; | ||
743 | if ((r->flags & type_mask) != type) | ||
744 | continue; | ||
745 | if (!r->parent) | ||
746 | continue; | ||
747 | /* | ||
748 | * if there are children under that, we should release them | ||
749 | * all | ||
750 | */ | ||
751 | release_child_resources(r); | ||
752 | if (!release_resource(r)) { | ||
753 | dev_printk(KERN_DEBUG, &dev->dev, | ||
754 | "resource %d %pR released\n", idx, r); | ||
755 | /* keep the old size */ | ||
756 | r->end = resource_size(r) - 1; | ||
757 | r->start = 0; | ||
758 | r->flags = 0; | ||
759 | changed = true; | ||
760 | } | ||
761 | } | ||
762 | |||
763 | if (changed) { | ||
764 | /* avoiding touch the one without PREF */ | ||
765 | if (type & IORESOURCE_PREFETCH) | ||
766 | type = IORESOURCE_PREFETCH; | ||
767 | __pci_setup_bridge(bus, type); | ||
768 | } | ||
769 | } | ||
770 | |||
771 | enum release_type { | ||
772 | leaf_only, | ||
773 | whole_subtree, | ||
774 | }; | ||
775 | /* | ||
776 | * try to release pci bridge resources that is from leaf bridge, | ||
777 | * so we can allocate big new one later | ||
778 | */ | ||
779 | static void __ref pci_bus_release_bridge_resources(struct pci_bus *bus, | ||
780 | unsigned long type, | ||
781 | enum release_type rel_type) | ||
782 | { | ||
783 | struct pci_dev *dev; | ||
784 | bool is_leaf_bridge = true; | ||
785 | |||
786 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
787 | struct pci_bus *b = dev->subordinate; | ||
788 | if (!b) | ||
789 | continue; | ||
790 | |||
791 | is_leaf_bridge = false; | ||
792 | |||
793 | if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) | ||
794 | continue; | ||
795 | |||
796 | if (rel_type == whole_subtree) | ||
797 | pci_bus_release_bridge_resources(b, type, | ||
798 | whole_subtree); | ||
799 | } | ||
800 | |||
801 | if (pci_is_root_bus(bus)) | ||
802 | return; | ||
803 | |||
804 | if ((bus->self->class >> 8) != PCI_CLASS_BRIDGE_PCI) | ||
805 | return; | ||
806 | |||
807 | if ((rel_type == whole_subtree) || is_leaf_bridge) | ||
808 | pci_bridge_release_resources(bus, type); | ||
809 | } | ||
810 | |||
576 | static void pci_bus_dump_res(struct pci_bus *bus) | 811 | static void pci_bus_dump_res(struct pci_bus *bus) |
577 | { | 812 | { |
578 | int i; | 813 | struct resource *res; |
814 | int i; | ||
579 | 815 | ||
580 | for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { | 816 | pci_bus_for_each_resource(bus, res, i) { |
581 | struct resource *res = bus->resource[i]; | 817 | if (!res || !res->end || !res->flags) |
582 | if (!res || !res->end) | ||
583 | continue; | 818 | continue; |
584 | 819 | ||
585 | dev_printk(KERN_DEBUG, &bus->dev, "resource %d %s %pR\n", i, | 820 | dev_printk(KERN_DEBUG, &bus->dev, "resource %d %pR\n", i, res); |
586 | (res->flags & IORESOURCE_IO) ? "io: " : | ||
587 | ((res->flags & IORESOURCE_PREFETCH)? "pref mem":"mem:"), | ||
588 | res); | ||
589 | } | 821 | } |
590 | } | 822 | } |
591 | 823 | ||
@@ -627,3 +859,65 @@ pci_assign_unassigned_resources(void) | |||
627 | pci_bus_dump_resources(bus); | 859 | pci_bus_dump_resources(bus); |
628 | } | 860 | } |
629 | } | 861 | } |
862 | |||
863 | void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge) | ||
864 | { | ||
865 | struct pci_bus *parent = bridge->subordinate; | ||
866 | int tried_times = 0; | ||
867 | struct resource_list_x head, *list; | ||
868 | int retval; | ||
869 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | | ||
870 | IORESOURCE_PREFETCH; | ||
871 | |||
872 | head.next = NULL; | ||
873 | |||
874 | again: | ||
875 | pci_bus_size_bridges(parent); | ||
876 | __pci_bridge_assign_resources(bridge, &head); | ||
877 | retval = pci_reenable_device(bridge); | ||
878 | pci_set_master(bridge); | ||
879 | pci_enable_bridges(parent); | ||
880 | |||
881 | tried_times++; | ||
882 | |||
883 | if (!head.next) | ||
884 | return; | ||
885 | |||
886 | if (tried_times >= 2) { | ||
887 | /* still fail, don't need to try more */ | ||
888 | free_failed_list(&head); | ||
889 | return; | ||
890 | } | ||
891 | |||
892 | printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n", | ||
893 | tried_times + 1); | ||
894 | |||
895 | /* | ||
896 | * Try to release leaf bridge's resources that doesn't fit resource of | ||
897 | * child device under that bridge | ||
898 | */ | ||
899 | for (list = head.next; list;) { | ||
900 | struct pci_bus *bus = list->dev->bus; | ||
901 | unsigned long flags = list->flags; | ||
902 | |||
903 | pci_bus_release_bridge_resources(bus, flags & type_mask, | ||
904 | whole_subtree); | ||
905 | list = list->next; | ||
906 | } | ||
907 | /* restore size and flags */ | ||
908 | for (list = head.next; list;) { | ||
909 | struct resource *res = list->res; | ||
910 | |||
911 | res->start = list->start; | ||
912 | res->end = list->end; | ||
913 | res->flags = list->flags; | ||
914 | if (list->dev->subordinate) | ||
915 | res->flags = 0; | ||
916 | |||
917 | list = list->next; | ||
918 | } | ||
919 | free_failed_list(&head); | ||
920 | |||
921 | goto again; | ||
922 | } | ||
923 | EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources); | ||
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index c54526b206b5..17bed18d24ad 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -51,12 +51,6 @@ void pci_update_resource(struct pci_dev *dev, int resno) | |||
51 | 51 | ||
52 | pcibios_resource_to_bus(dev, ®ion, res); | 52 | pcibios_resource_to_bus(dev, ®ion, res); |
53 | 53 | ||
54 | dev_dbg(&dev->dev, "BAR %d: got res %pR bus [%#llx-%#llx] " | ||
55 | "flags %#lx\n", resno, res, | ||
56 | (unsigned long long)region.start, | ||
57 | (unsigned long long)region.end, | ||
58 | (unsigned long)res->flags); | ||
59 | |||
60 | new = region.start | (res->flags & PCI_REGION_FLAG_MASK); | 54 | new = region.start | (res->flags & PCI_REGION_FLAG_MASK); |
61 | if (res->flags & IORESOURCE_IO) | 55 | if (res->flags & IORESOURCE_IO) |
62 | mask = (u32)PCI_BASE_ADDRESS_IO_MASK; | 56 | mask = (u32)PCI_BASE_ADDRESS_IO_MASK; |
@@ -91,40 +85,39 @@ void pci_update_resource(struct pci_dev *dev, int resno) | |||
91 | } | 85 | } |
92 | } | 86 | } |
93 | res->flags &= ~IORESOURCE_UNSET; | 87 | res->flags &= ~IORESOURCE_UNSET; |
94 | dev_dbg(&dev->dev, "BAR %d: moved to bus [%#llx-%#llx] flags %#lx\n", | 88 | dev_info(&dev->dev, "BAR %d: set to %pR (PCI address [%#llx-%#llx]\n", |
95 | resno, (unsigned long long)region.start, | 89 | resno, res, (unsigned long long)region.start, |
96 | (unsigned long long)region.end, res->flags); | 90 | (unsigned long long)region.end); |
97 | } | 91 | } |
98 | 92 | ||
99 | int pci_claim_resource(struct pci_dev *dev, int resource) | 93 | int pci_claim_resource(struct pci_dev *dev, int resource) |
100 | { | 94 | { |
101 | struct resource *res = &dev->resource[resource]; | 95 | struct resource *res = &dev->resource[resource]; |
102 | struct resource *root; | 96 | struct resource *root, *conflict; |
103 | int err; | ||
104 | 97 | ||
105 | root = pci_find_parent_resource(dev, res); | 98 | root = pci_find_parent_resource(dev, res); |
99 | if (!root) { | ||
100 | dev_err(&dev->dev, "no compatible bridge window for %pR\n", | ||
101 | res); | ||
102 | return -EINVAL; | ||
103 | } | ||
106 | 104 | ||
107 | err = -EINVAL; | 105 | conflict = request_resource_conflict(root, res); |
108 | if (root != NULL) | 106 | if (conflict) { |
109 | err = request_resource(root, res); | 107 | dev_err(&dev->dev, |
110 | 108 | "address space collision: %pR conflicts with %s %pR\n", | |
111 | if (err) { | 109 | res, conflict->name, conflict); |
112 | const char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge"; | 110 | return -EBUSY; |
113 | dev_err(&dev->dev, "BAR %d: %s of %s %pR\n", | ||
114 | resource, | ||
115 | root ? "address space collision on" : | ||
116 | "no parent found for", | ||
117 | dtype, res); | ||
118 | } | 111 | } |
119 | 112 | ||
120 | return err; | 113 | return 0; |
121 | } | 114 | } |
122 | EXPORT_SYMBOL(pci_claim_resource); | 115 | EXPORT_SYMBOL(pci_claim_resource); |
123 | 116 | ||
124 | #ifdef CONFIG_PCI_QUIRKS | 117 | #ifdef CONFIG_PCI_QUIRKS |
125 | void pci_disable_bridge_window(struct pci_dev *dev) | 118 | void pci_disable_bridge_window(struct pci_dev *dev) |
126 | { | 119 | { |
127 | dev_dbg(&dev->dev, "Disabling bridge window.\n"); | 120 | dev_info(&dev->dev, "disabling bridge mem windows\n"); |
128 | 121 | ||
129 | /* MMIO Base/Limit */ | 122 | /* MMIO Base/Limit */ |
130 | pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0); | 123 | pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0); |
@@ -165,6 +158,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, | |||
165 | 158 | ||
166 | if (!ret) { | 159 | if (!ret) { |
167 | res->flags &= ~IORESOURCE_STARTALIGN; | 160 | res->flags &= ~IORESOURCE_STARTALIGN; |
161 | dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); | ||
168 | if (resno < PCI_BRIDGE_RESOURCES) | 162 | if (resno < PCI_BRIDGE_RESOURCES) |
169 | pci_update_resource(dev, resno); | 163 | pci_update_resource(dev, resno); |
170 | } | 164 | } |
@@ -178,12 +172,12 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
178 | resource_size_t align; | 172 | resource_size_t align; |
179 | struct pci_bus *bus; | 173 | struct pci_bus *bus; |
180 | int ret; | 174 | int ret; |
175 | char *type; | ||
181 | 176 | ||
182 | align = pci_resource_alignment(dev, res); | 177 | align = pci_resource_alignment(dev, res); |
183 | if (!align) { | 178 | if (!align) { |
184 | dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus " | 179 | dev_info(&dev->dev, "BAR %d: can't assign %pR " |
185 | "alignment) %pR flags %#lx\n", | 180 | "(bogus alignment)\n", resno, res); |
186 | resno, res, res->flags); | ||
187 | return -EINVAL; | 181 | return -EINVAL; |
188 | } | 182 | } |
189 | 183 | ||
@@ -198,9 +192,20 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
198 | break; | 192 | break; |
199 | } | 193 | } |
200 | 194 | ||
201 | if (ret) | 195 | if (ret) { |
202 | dev_info(&dev->dev, "BAR %d: can't allocate %s resource %pR\n", | 196 | if (res->flags & IORESOURCE_MEM) |
203 | resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res); | 197 | if (res->flags & IORESOURCE_PREFETCH) |
198 | type = "mem pref"; | ||
199 | else | ||
200 | type = "mem"; | ||
201 | else if (res->flags & IORESOURCE_IO) | ||
202 | type = "io"; | ||
203 | else | ||
204 | type = "unknown"; | ||
205 | dev_info(&dev->dev, | ||
206 | "BAR %d: can't assign %s (size %#llx)\n", | ||
207 | resno, type, (unsigned long long) resource_size(res)); | ||
208 | } | ||
204 | 209 | ||
205 | return ret; | 210 | return ret; |
206 | } | 211 | } |
@@ -225,9 +230,8 @@ void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) | |||
225 | 230 | ||
226 | r_align = pci_resource_alignment(dev, r); | 231 | r_align = pci_resource_alignment(dev, r); |
227 | if (!r_align) { | 232 | if (!r_align) { |
228 | dev_warn(&dev->dev, "BAR %d: bogus alignment " | 233 | dev_warn(&dev->dev, "BAR %d: %pR has bogus alignment\n", |
229 | "%pR flags %#lx\n", | 234 | i, r); |
230 | i, r, r->flags); | ||
231 | continue; | 235 | continue; |
232 | } | 236 | } |
233 | for (list = head; ; list = list->next) { | 237 | for (list = head; ; list = list->next) { |
@@ -274,8 +278,8 @@ int pci_enable_resources(struct pci_dev *dev, int mask) | |||
274 | continue; | 278 | continue; |
275 | 279 | ||
276 | if (!r->parent) { | 280 | if (!r->parent) { |
277 | dev_err(&dev->dev, "device not available because of " | 281 | dev_err(&dev->dev, "device not available " |
278 | "BAR %d %pR collisions\n", i, r); | 282 | "(can't reserve %pR)\n", r); |
279 | return -EINVAL; | 283 | return -EINVAL; |
280 | } | 284 | } |
281 | 285 | ||
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index 8c02b6c53bdb..659eaa0fc48f 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c | |||
@@ -6,6 +6,7 @@ | |||
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <linux/kobject.h> | 8 | #include <linux/kobject.h> |
9 | #include <linux/slab.h> | ||
9 | #include <linux/pci.h> | 10 | #include <linux/pci.h> |
10 | #include <linux/err.h> | 11 | #include <linux/err.h> |
11 | #include "pci.h" | 12 | #include "pci.h" |
@@ -29,7 +30,7 @@ static ssize_t pci_slot_attr_store(struct kobject *kobj, | |||
29 | return attribute->store ? attribute->store(slot, buf, len) : -EIO; | 30 | return attribute->store ? attribute->store(slot, buf, len) : -EIO; |
30 | } | 31 | } |
31 | 32 | ||
32 | static struct sysfs_ops pci_slot_sysfs_ops = { | 33 | static const struct sysfs_ops pci_slot_sysfs_ops = { |
33 | .show = pci_slot_attr_show, | 34 | .show = pci_slot_attr_show, |
34 | .store = pci_slot_attr_store, | 35 | .store = pci_slot_attr_store, |
35 | }; | 36 | }; |
@@ -47,6 +48,55 @@ static ssize_t address_read_file(struct pci_slot *slot, char *buf) | |||
47 | slot->number); | 48 | slot->number); |
48 | } | 49 | } |
49 | 50 | ||
51 | /* these strings match up with the values in pci_bus_speed */ | ||
52 | static char *pci_bus_speed_strings[] = { | ||
53 | "33 MHz PCI", /* 0x00 */ | ||
54 | "66 MHz PCI", /* 0x01 */ | ||
55 | "66 MHz PCI-X", /* 0x02 */ | ||
56 | "100 MHz PCI-X", /* 0x03 */ | ||
57 | "133 MHz PCI-X", /* 0x04 */ | ||
58 | NULL, /* 0x05 */ | ||
59 | NULL, /* 0x06 */ | ||
60 | NULL, /* 0x07 */ | ||
61 | NULL, /* 0x08 */ | ||
62 | "66 MHz PCI-X 266", /* 0x09 */ | ||
63 | "100 MHz PCI-X 266", /* 0x0a */ | ||
64 | "133 MHz PCI-X 266", /* 0x0b */ | ||
65 | "Unknown AGP", /* 0x0c */ | ||
66 | "1x AGP", /* 0x0d */ | ||
67 | "2x AGP", /* 0x0e */ | ||
68 | "4x AGP", /* 0x0f */ | ||
69 | "8x AGP", /* 0x10 */ | ||
70 | "66 MHz PCI-X 533", /* 0x11 */ | ||
71 | "100 MHz PCI-X 533", /* 0x12 */ | ||
72 | "133 MHz PCI-X 533", /* 0x13 */ | ||
73 | "2.5 GT/s PCIe", /* 0x14 */ | ||
74 | "5.0 GT/s PCIe", /* 0x15 */ | ||
75 | "8.0 GT/s PCIe", /* 0x16 */ | ||
76 | }; | ||
77 | |||
78 | static ssize_t bus_speed_read(enum pci_bus_speed speed, char *buf) | ||
79 | { | ||
80 | const char *speed_string; | ||
81 | |||
82 | if (speed < ARRAY_SIZE(pci_bus_speed_strings)) | ||
83 | speed_string = pci_bus_speed_strings[speed]; | ||
84 | else | ||
85 | speed_string = "Unknown"; | ||
86 | |||
87 | return sprintf(buf, "%s\n", speed_string); | ||
88 | } | ||
89 | |||
90 | static ssize_t max_speed_read_file(struct pci_slot *slot, char *buf) | ||
91 | { | ||
92 | return bus_speed_read(slot->bus->max_bus_speed, buf); | ||
93 | } | ||
94 | |||
95 | static ssize_t cur_speed_read_file(struct pci_slot *slot, char *buf) | ||
96 | { | ||
97 | return bus_speed_read(slot->bus->cur_bus_speed, buf); | ||
98 | } | ||
99 | |||
50 | static void pci_slot_release(struct kobject *kobj) | 100 | static void pci_slot_release(struct kobject *kobj) |
51 | { | 101 | { |
52 | struct pci_dev *dev; | 102 | struct pci_dev *dev; |
@@ -66,9 +116,15 @@ static void pci_slot_release(struct kobject *kobj) | |||
66 | 116 | ||
67 | static struct pci_slot_attribute pci_slot_attr_address = | 117 | static struct pci_slot_attribute pci_slot_attr_address = |
68 | __ATTR(address, (S_IFREG | S_IRUGO), address_read_file, NULL); | 118 | __ATTR(address, (S_IFREG | S_IRUGO), address_read_file, NULL); |
119 | static struct pci_slot_attribute pci_slot_attr_max_speed = | ||
120 | __ATTR(max_bus_speed, (S_IFREG | S_IRUGO), max_speed_read_file, NULL); | ||
121 | static struct pci_slot_attribute pci_slot_attr_cur_speed = | ||
122 | __ATTR(cur_bus_speed, (S_IFREG | S_IRUGO), cur_speed_read_file, NULL); | ||
69 | 123 | ||
70 | static struct attribute *pci_slot_default_attrs[] = { | 124 | static struct attribute *pci_slot_default_attrs[] = { |
71 | &pci_slot_attr_address.attr, | 125 | &pci_slot_attr_address.attr, |
126 | &pci_slot_attr_max_speed.attr, | ||
127 | &pci_slot_attr_cur_speed.attr, | ||
72 | NULL, | 128 | NULL, |
73 | }; | 129 | }; |
74 | 130 | ||
diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c new file mode 100644 index 000000000000..a5a5ca17cfe6 --- /dev/null +++ b/drivers/pci/vpd.c | |||
@@ -0,0 +1,61 @@ | |||
1 | /* | ||
2 | * File: vpd.c | ||
3 | * Purpose: Provide PCI VPD support | ||
4 | * | ||
5 | * Copyright (C) 2010 Broadcom Corporation. | ||
6 | */ | ||
7 | |||
8 | #include <linux/pci.h> | ||
9 | |||
10 | int pci_vpd_find_tag(const u8 *buf, unsigned int off, unsigned int len, u8 rdt) | ||
11 | { | ||
12 | int i; | ||
13 | |||
14 | for (i = off; i < len; ) { | ||
15 | u8 val = buf[i]; | ||
16 | |||
17 | if (val & PCI_VPD_LRDT) { | ||
18 | /* Don't return success of the tag isn't complete */ | ||
19 | if (i + PCI_VPD_LRDT_TAG_SIZE > len) | ||
20 | break; | ||
21 | |||
22 | if (val == rdt) | ||
23 | return i; | ||
24 | |||
25 | i += PCI_VPD_LRDT_TAG_SIZE + | ||
26 | pci_vpd_lrdt_size(&buf[i]); | ||
27 | } else { | ||
28 | u8 tag = val & ~PCI_VPD_SRDT_LEN_MASK; | ||
29 | |||
30 | if (tag == rdt) | ||
31 | return i; | ||
32 | |||
33 | if (tag == PCI_VPD_SRDT_END) | ||
34 | break; | ||
35 | |||
36 | i += PCI_VPD_SRDT_TAG_SIZE + | ||
37 | pci_vpd_srdt_size(&buf[i]); | ||
38 | } | ||
39 | } | ||
40 | |||
41 | return -ENOENT; | ||
42 | } | ||
43 | EXPORT_SYMBOL_GPL(pci_vpd_find_tag); | ||
44 | |||
45 | int pci_vpd_find_info_keyword(const u8 *buf, unsigned int off, | ||
46 | unsigned int len, const char *kw) | ||
47 | { | ||
48 | int i; | ||
49 | |||
50 | for (i = off; i + PCI_VPD_INFO_FLD_HDR_SIZE <= off + len;) { | ||
51 | if (buf[i + 0] == kw[0] && | ||
52 | buf[i + 1] == kw[1]) | ||
53 | return i; | ||
54 | |||
55 | i += PCI_VPD_INFO_FLD_HDR_SIZE + | ||
56 | pci_vpd_info_field_size(&buf[i]); | ||
57 | } | ||
58 | |||
59 | return -ENOENT; | ||
60 | } | ||
61 | EXPORT_SYMBOL_GPL(pci_vpd_find_info_keyword); | ||