diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-03-19 02:38:50 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-03-19 02:38:50 -0400 |
commit | 97eb3f24352ec6632c2127b35d8087d2a809a9b9 (patch) | |
tree | 722948059bbd325bbca232269490124231df80d4 /drivers/pci | |
parent | 439581ec07fa9cf3f519dd461a2cf41cfd3adcb4 (diff) | |
parent | def179c271ac9b5020deca798470521f14d11edd (diff) |
Merge branch 'next' into for-linus
Diffstat (limited to 'drivers/pci')
28 files changed, 206 insertions, 175 deletions
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 5b1630e4e9e3..a9523fdc6911 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig | |||
@@ -45,6 +45,7 @@ config XEN_PCIDEV_FRONTEND | |||
45 | depends on PCI && X86 && XEN | 45 | depends on PCI && X86 && XEN |
46 | select HOTPLUG | 46 | select HOTPLUG |
47 | select PCI_XEN | 47 | select PCI_XEN |
48 | select XEN_XENBUS_FRONTEND | ||
48 | default y | 49 | default y |
49 | help | 50 | help |
50 | The PCI device frontend driver allows the kernel to import arbitrary | 51 | The PCI device frontend driver allows the kernel to import arbitrary |
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index f01e344cf4bd..98e6fdf34d30 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile | |||
@@ -49,6 +49,7 @@ obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o | |||
49 | obj-$(CONFIG_X86_VISWS) += setup-irq.o | 49 | obj-$(CONFIG_X86_VISWS) += setup-irq.o |
50 | obj-$(CONFIG_MN10300) += setup-bus.o | 50 | obj-$(CONFIG_MN10300) += setup-bus.o |
51 | obj-$(CONFIG_MICROBLAZE) += setup-bus.o | 51 | obj-$(CONFIG_MICROBLAZE) += setup-bus.o |
52 | obj-$(CONFIG_TILE) += setup-bus.o setup-irq.o | ||
52 | 53 | ||
53 | # | 54 | # |
54 | # ACPI Related PCI FW Functions | 55 | # ACPI Related PCI FW Functions |
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 5624db8c9ad0..69546e9213dd 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -64,49 +64,6 @@ void pci_bus_remove_resources(struct pci_bus *bus) | |||
64 | } | 64 | } |
65 | } | 65 | } |
66 | 66 | ||
67 | /* | ||
68 | * Find the highest-address bus resource below the cursor "res". If the | ||
69 | * cursor is NULL, return the highest resource. | ||
70 | */ | ||
71 | static struct resource *pci_bus_find_resource_prev(struct pci_bus *bus, | ||
72 | unsigned int type, | ||
73 | struct resource *res) | ||
74 | { | ||
75 | struct resource *r, *prev = NULL; | ||
76 | int i; | ||
77 | |||
78 | pci_bus_for_each_resource(bus, r, i) { | ||
79 | if (!r) | ||
80 | continue; | ||
81 | |||
82 | if ((r->flags & IORESOURCE_TYPE_BITS) != type) | ||
83 | continue; | ||
84 | |||
85 | /* If this resource is at or past the cursor, skip it */ | ||
86 | if (res) { | ||
87 | if (r == res) | ||
88 | continue; | ||
89 | if (r->end > res->end) | ||
90 | continue; | ||
91 | if (r->end == res->end && r->start > res->start) | ||
92 | continue; | ||
93 | } | ||
94 | |||
95 | if (!prev) | ||
96 | prev = r; | ||
97 | |||
98 | /* | ||
99 | * A small resource is higher than a large one that ends at | ||
100 | * the same address. | ||
101 | */ | ||
102 | if (r->end > prev->end || | ||
103 | (r->end == prev->end && r->start > prev->start)) | ||
104 | prev = r; | ||
105 | } | ||
106 | |||
107 | return prev; | ||
108 | } | ||
109 | |||
110 | /** | 67 | /** |
111 | * pci_bus_alloc_resource - allocate a resource from a parent bus | 68 | * pci_bus_alloc_resource - allocate a resource from a parent bus |
112 | * @bus: PCI bus | 69 | * @bus: PCI bus |
@@ -132,10 +89,9 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | |||
132 | resource_size_t), | 89 | resource_size_t), |
133 | void *alignf_data) | 90 | void *alignf_data) |
134 | { | 91 | { |
135 | int ret = -ENOMEM; | 92 | int i, ret = -ENOMEM; |
136 | struct resource *r; | 93 | struct resource *r; |
137 | resource_size_t max = -1; | 94 | resource_size_t max = -1; |
138 | unsigned int type = res->flags & IORESOURCE_TYPE_BITS; | ||
139 | 95 | ||
140 | type_mask |= IORESOURCE_IO | IORESOURCE_MEM; | 96 | type_mask |= IORESOURCE_IO | IORESOURCE_MEM; |
141 | 97 | ||
@@ -143,9 +99,10 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | |||
143 | if (!(res->flags & IORESOURCE_MEM_64)) | 99 | if (!(res->flags & IORESOURCE_MEM_64)) |
144 | max = PCIBIOS_MAX_MEM_32; | 100 | max = PCIBIOS_MAX_MEM_32; |
145 | 101 | ||
146 | /* Look for space at highest addresses first */ | 102 | pci_bus_for_each_resource(bus, r, i) { |
147 | r = pci_bus_find_resource_prev(bus, type, NULL); | 103 | if (!r) |
148 | for ( ; r; r = pci_bus_find_resource_prev(bus, type, r)) { | 104 | continue; |
105 | |||
149 | /* type_mask must match */ | 106 | /* type_mask must match */ |
150 | if ((res->flags ^ r->flags) & type_mask) | 107 | if ((res->flags ^ r->flags) & type_mask) |
151 | continue; | 108 | continue; |
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 0157708d474d..09933eb9126b 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c | |||
@@ -1417,6 +1417,11 @@ int __init enable_drhd_fault_handling(void) | |||
1417 | (unsigned long long)drhd->reg_base_addr, ret); | 1417 | (unsigned long long)drhd->reg_base_addr, ret); |
1418 | return -1; | 1418 | return -1; |
1419 | } | 1419 | } |
1420 | |||
1421 | /* | ||
1422 | * Clear any previous faults. | ||
1423 | */ | ||
1424 | dmar_fault(iommu->irq, iommu); | ||
1420 | } | 1425 | } |
1421 | 1426 | ||
1422 | return 0; | 1427 | return 0; |
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index bab52047baa8..7722108e78df 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h | |||
@@ -36,7 +36,6 @@ | |||
36 | #define _ACPIPHP_H | 36 | #define _ACPIPHP_H |
37 | 37 | ||
38 | #include <linux/acpi.h> | 38 | #include <linux/acpi.h> |
39 | #include <linux/kobject.h> | ||
40 | #include <linux/mutex.h> | 39 | #include <linux/mutex.h> |
41 | #include <linux/pci_hotplug.h> | 40 | #include <linux/pci_hotplug.h> |
42 | 41 | ||
diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c index 5becbdee4027..2850e64dedae 100644 --- a/drivers/pci/hotplug/ibmphp_ebda.c +++ b/drivers/pci/hotplug/ibmphp_ebda.c | |||
@@ -276,6 +276,12 @@ int __init ibmphp_access_ebda (void) | |||
276 | 276 | ||
277 | for (;;) { | 277 | for (;;) { |
278 | offset = next_offset; | 278 | offset = next_offset; |
279 | |||
280 | /* Make sure what we read is still in the mapped section */ | ||
281 | if (WARN(offset > (ebda_sz * 1024 - 4), | ||
282 | "ibmphp_ebda: next read is beyond ebda_sz\n")) | ||
283 | break; | ||
284 | |||
279 | next_offset = readw (io_mem + offset); /* offset of next blk */ | 285 | next_offset = readw (io_mem + offset); /* offset of next blk */ |
280 | 286 | ||
281 | offset += 2; | 287 | offset += 2; |
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c index 2574700db461..5f7226223a62 100644 --- a/drivers/pci/hotplug/pciehp_acpi.c +++ b/drivers/pci/hotplug/pciehp_acpi.c | |||
@@ -115,7 +115,8 @@ static struct pcie_port_service_driver __initdata dummy_driver = { | |||
115 | static int __init select_detection_mode(void) | 115 | static int __init select_detection_mode(void) |
116 | { | 116 | { |
117 | struct dummy_slot *slot, *tmp; | 117 | struct dummy_slot *slot, *tmp; |
118 | pcie_port_service_register(&dummy_driver); | 118 | if (pcie_port_service_register(&dummy_driver)) |
119 | return PCIEHP_DETECT_ACPI; | ||
119 | pcie_port_service_unregister(&dummy_driver); | 120 | pcie_port_service_unregister(&dummy_driver); |
120 | list_for_each_entry_safe(slot, tmp, &dummy_slots, list) { | 121 | list_for_each_entry_safe(slot, tmp, &dummy_slots, list) { |
121 | list_del(&slot->list); | 122 | list_del(&slot->list); |
diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c index 2ea9cf1a8d02..b283bbea6d24 100644 --- a/drivers/pci/hotplug/rpaphp_slot.c +++ b/drivers/pci/hotplug/rpaphp_slot.c | |||
@@ -24,7 +24,6 @@ | |||
24 | */ | 24 | */ |
25 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/kobject.h> | ||
28 | #include <linux/sysfs.h> | 27 | #include <linux/sysfs.h> |
29 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
30 | #include <linux/string.h> | 29 | #include <linux/string.h> |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 7c24dcef2989..44b0aeee83e5 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -168,8 +168,9 @@ static u32 __msix_mask_irq(struct msi_desc *desc, u32 flag) | |||
168 | u32 mask_bits = desc->masked; | 168 | u32 mask_bits = desc->masked; |
169 | unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + | 169 | unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + |
170 | PCI_MSIX_ENTRY_VECTOR_CTRL; | 170 | PCI_MSIX_ENTRY_VECTOR_CTRL; |
171 | mask_bits &= ~1; | 171 | mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; |
172 | mask_bits |= flag; | 172 | if (flag) |
173 | mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT; | ||
173 | writel(mask_bits, desc->mask_base + offset); | 174 | writel(mask_bits, desc->mask_base + offset); |
174 | 175 | ||
175 | return mask_bits; | 176 | return mask_bits; |
diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h index feff3bee6fe5..65c42f80f23e 100644 --- a/drivers/pci/msi.h +++ b/drivers/pci/msi.h | |||
@@ -6,12 +6,6 @@ | |||
6 | #ifndef MSI_H | 6 | #ifndef MSI_H |
7 | #define MSI_H | 7 | #define MSI_H |
8 | 8 | ||
9 | #define PCI_MSIX_ENTRY_SIZE 16 | ||
10 | #define PCI_MSIX_ENTRY_LOWER_ADDR 0 | ||
11 | #define PCI_MSIX_ENTRY_UPPER_ADDR 4 | ||
12 | #define PCI_MSIX_ENTRY_DATA 8 | ||
13 | #define PCI_MSIX_ENTRY_VECTOR_CTRL 12 | ||
14 | |||
15 | #define msi_control_reg(base) (base + PCI_MSI_FLAGS) | 9 | #define msi_control_reg(base) (base + PCI_MSI_FLAGS) |
16 | #define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO) | 10 | #define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO) |
17 | #define msi_upper_address_reg(base) (base + PCI_MSI_ADDRESS_HI) | 11 | #define msi_upper_address_reg(base) (base + PCI_MSI_ADDRESS_HI) |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 24e19c594e57..6fe0772e0e7d 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -46,9 +46,9 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) | |||
46 | struct pci_dev *pci_dev = context; | 46 | struct pci_dev *pci_dev = context; |
47 | 47 | ||
48 | if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_dev) { | 48 | if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_dev) { |
49 | pci_wakeup_event(pci_dev); | ||
49 | pci_check_pme_status(pci_dev); | 50 | pci_check_pme_status(pci_dev); |
50 | pm_runtime_resume(&pci_dev->dev); | 51 | pm_runtime_resume(&pci_dev->dev); |
51 | pci_wakeup_event(pci_dev); | ||
52 | if (pci_dev->subordinate) | 52 | if (pci_dev->subordinate) |
53 | pci_pme_wakeup_bus(pci_dev->subordinate); | 53 | pci_pme_wakeup_bus(pci_dev->subordinate); |
54 | } | 54 | } |
@@ -399,6 +399,7 @@ static int __init acpi_pci_init(void) | |||
399 | 399 | ||
400 | if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { | 400 | if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { |
401 | printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n"); | 401 | printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n"); |
402 | pcie_clear_aspm(); | ||
402 | pcie_no_aspm(); | 403 | pcie_no_aspm(); |
403 | } | 404 | } |
404 | 405 | ||
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 8a6f797de8e5..88246dd46452 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -338,7 +338,7 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev, | |||
338 | } | 338 | } |
339 | 339 | ||
340 | /** | 340 | /** |
341 | * __pci_device_probe() | 341 | * __pci_device_probe - check if a driver wants to claim a specific PCI device |
342 | * @drv: driver to call to check if it wants the PCI device | 342 | * @drv: driver to call to check if it wants the PCI device |
343 | * @pci_dev: PCI device being probed | 343 | * @pci_dev: PCI device being probed |
344 | * | 344 | * |
@@ -449,7 +449,8 @@ static int pci_restore_standard_config(struct pci_dev *pci_dev) | |||
449 | return error; | 449 | return error; |
450 | } | 450 | } |
451 | 451 | ||
452 | return pci_restore_state(pci_dev); | 452 | pci_restore_state(pci_dev); |
453 | return 0; | ||
453 | } | 454 | } |
454 | 455 | ||
455 | static void pci_pm_default_resume_early(struct pci_dev *pci_dev) | 456 | static void pci_pm_default_resume_early(struct pci_dev *pci_dev) |
diff --git a/drivers/pci/pci-stub.c b/drivers/pci/pci-stub.c index f7b68ca6cc98..775e933c2225 100644 --- a/drivers/pci/pci-stub.c +++ b/drivers/pci/pci-stub.c | |||
@@ -47,6 +47,10 @@ static int __init pci_stub_init(void) | |||
47 | if (rc) | 47 | if (rc) |
48 | return rc; | 48 | return rc; |
49 | 49 | ||
50 | /* no ids passed actually */ | ||
51 | if (ids[0] == '\0') | ||
52 | return 0; | ||
53 | |||
50 | /* add ids specified in the module parameter */ | 54 | /* add ids specified in the module parameter */ |
51 | p = ids; | 55 | p = ids; |
52 | while ((id = strsep(&p, ","))) { | 56 | while ((id = strsep(&p, ","))) { |
@@ -54,6 +58,9 @@ static int __init pci_stub_init(void) | |||
54 | subdevice = PCI_ANY_ID, class=0, class_mask=0; | 58 | subdevice = PCI_ANY_ID, class=0, class_mask=0; |
55 | int fields; | 59 | int fields; |
56 | 60 | ||
61 | if (!strlen(id)) | ||
62 | continue; | ||
63 | |||
57 | fields = sscanf(id, "%x:%x:%x:%x:%x:%x", | 64 | fields = sscanf(id, "%x:%x:%x:%x:%x:%x", |
58 | &vendor, &device, &subvendor, &subdevice, | 65 | &vendor, &device, &subvendor, &subdevice, |
59 | &class, &class_mask); | 66 | &class, &class_mask); |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index b5a7d9bfcb24..8ecaac983923 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -705,17 +705,21 @@ void pci_remove_legacy_files(struct pci_bus *b) | |||
705 | 705 | ||
706 | #ifdef HAVE_PCI_MMAP | 706 | #ifdef HAVE_PCI_MMAP |
707 | 707 | ||
708 | int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma) | 708 | int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma, |
709 | enum pci_mmap_api mmap_api) | ||
709 | { | 710 | { |
710 | unsigned long nr, start, size; | 711 | unsigned long nr, start, size, pci_start; |
711 | 712 | ||
713 | if (pci_resource_len(pdev, resno) == 0) | ||
714 | return 0; | ||
712 | nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; | 715 | nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; |
713 | start = vma->vm_pgoff; | 716 | start = vma->vm_pgoff; |
714 | size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1; | 717 | size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1; |
715 | if (start < size && size - start >= nr) | 718 | pci_start = (mmap_api == PCI_MMAP_PROCFS) ? |
719 | pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0; | ||
720 | if (start >= pci_start && start < pci_start + size && | ||
721 | start + nr <= pci_start + size) | ||
716 | return 1; | 722 | return 1; |
717 | WARN(1, "process \"%s\" tried to map 0x%08lx-0x%08lx on %s BAR %d (size 0x%08lx)\n", | ||
718 | current->comm, start, start+nr, pci_name(pdev), resno, size); | ||
719 | return 0; | 723 | return 0; |
720 | } | 724 | } |
721 | 725 | ||
@@ -745,8 +749,15 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, | |||
745 | if (i >= PCI_ROM_RESOURCE) | 749 | if (i >= PCI_ROM_RESOURCE) |
746 | return -ENODEV; | 750 | return -ENODEV; |
747 | 751 | ||
748 | if (!pci_mmap_fits(pdev, i, vma)) | 752 | if (!pci_mmap_fits(pdev, i, vma, PCI_MMAP_SYSFS)) { |
753 | WARN(1, "process \"%s\" tried to map 0x%08lx bytes " | ||
754 | "at page 0x%08lx on %s BAR %d (start 0x%16Lx, size 0x%16Lx)\n", | ||
755 | current->comm, vma->vm_end-vma->vm_start, vma->vm_pgoff, | ||
756 | pci_name(pdev), i, | ||
757 | (u64)pci_resource_start(pdev, i), | ||
758 | (u64)pci_resource_len(pdev, i)); | ||
749 | return -EINVAL; | 759 | return -EINVAL; |
760 | } | ||
750 | 761 | ||
751 | /* pci_mmap_page_range() expects the same kind of entry as coming | 762 | /* pci_mmap_page_range() expects the same kind of entry as coming |
752 | * from /proc/bus/pci/ which is a "user visible" value. If this is | 763 | * from /proc/bus/pci/ which is a "user visible" value. If this is |
@@ -1138,7 +1149,7 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) | |||
1138 | sysfs_bin_attr_init(attr); | 1149 | sysfs_bin_attr_init(attr); |
1139 | attr->size = rom_size; | 1150 | attr->size = rom_size; |
1140 | attr->attr.name = "rom"; | 1151 | attr->attr.name = "rom"; |
1141 | attr->attr.mode = S_IRUSR; | 1152 | attr->attr.mode = S_IRUSR | S_IWUSR; |
1142 | attr->read = pci_read_rom; | 1153 | attr->read = pci_read_rom; |
1143 | attr->write = pci_write_rom; | 1154 | attr->write = pci_write_rom; |
1144 | retval = sysfs_create_bin_file(&pdev->dev.kobj, attr); | 1155 | retval = sysfs_create_bin_file(&pdev->dev.kobj, attr); |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e98c8104297b..b714d787bddd 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -937,14 +937,13 @@ pci_save_state(struct pci_dev *dev) | |||
937 | * pci_restore_state - Restore the saved state of a PCI device | 937 | * pci_restore_state - Restore the saved state of a PCI device |
938 | * @dev: - PCI device that we're dealing with | 938 | * @dev: - PCI device that we're dealing with |
939 | */ | 939 | */ |
940 | int | 940 | void pci_restore_state(struct pci_dev *dev) |
941 | pci_restore_state(struct pci_dev *dev) | ||
942 | { | 941 | { |
943 | int i; | 942 | int i; |
944 | u32 val; | 943 | u32 val; |
945 | 944 | ||
946 | if (!dev->state_saved) | 945 | if (!dev->state_saved) |
947 | return 0; | 946 | return; |
948 | 947 | ||
949 | /* PCI Express register must be restored first */ | 948 | /* PCI Express register must be restored first */ |
950 | pci_restore_pcie_state(dev); | 949 | pci_restore_pcie_state(dev); |
@@ -968,8 +967,6 @@ pci_restore_state(struct pci_dev *dev) | |||
968 | pci_restore_iov_state(dev); | 967 | pci_restore_iov_state(dev); |
969 | 968 | ||
970 | dev->state_saved = false; | 969 | dev->state_saved = false; |
971 | |||
972 | return 0; | ||
973 | } | 970 | } |
974 | 971 | ||
975 | static int do_pci_enable_device(struct pci_dev *dev, int bars) | 972 | static int do_pci_enable_device(struct pci_dev *dev, int bars) |
@@ -1007,6 +1004,18 @@ static int __pci_enable_device_flags(struct pci_dev *dev, | |||
1007 | int err; | 1004 | int err; |
1008 | int i, bars = 0; | 1005 | int i, bars = 0; |
1009 | 1006 | ||
1007 | /* | ||
1008 | * Power state could be unknown at this point, either due to a fresh | ||
1009 | * boot or a device removal call. So get the current power state | ||
1010 | * so that things like MSI message writing will behave as expected | ||
1011 | * (e.g. if the device really is in D0 at enable time). | ||
1012 | */ | ||
1013 | if (dev->pm_cap) { | ||
1014 | u16 pmcsr; | ||
1015 | pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); | ||
1016 | dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); | ||
1017 | } | ||
1018 | |||
1010 | if (atomic_add_return(1, &dev->enable_cnt) > 1) | 1019 | if (atomic_add_return(1, &dev->enable_cnt) > 1) |
1011 | return 0; /* already enabled */ | 1020 | return 0; /* already enabled */ |
1012 | 1021 | ||
@@ -1288,22 +1297,6 @@ bool pci_check_pme_status(struct pci_dev *dev) | |||
1288 | return ret; | 1297 | return ret; |
1289 | } | 1298 | } |
1290 | 1299 | ||
1291 | /* | ||
1292 | * Time to wait before the system can be put into a sleep state after reporting | ||
1293 | * a wakeup event signaled by a PCI device. | ||
1294 | */ | ||
1295 | #define PCI_WAKEUP_COOLDOWN 100 | ||
1296 | |||
1297 | /** | ||
1298 | * pci_wakeup_event - Report a wakeup event related to a given PCI device. | ||
1299 | * @dev: Device to report the wakeup event for. | ||
1300 | */ | ||
1301 | void pci_wakeup_event(struct pci_dev *dev) | ||
1302 | { | ||
1303 | if (device_may_wakeup(&dev->dev)) | ||
1304 | pm_wakeup_event(&dev->dev, PCI_WAKEUP_COOLDOWN); | ||
1305 | } | ||
1306 | |||
1307 | /** | 1300 | /** |
1308 | * pci_pme_wakeup - Wake up a PCI device if its PME Status bit is set. | 1301 | * pci_pme_wakeup - Wake up a PCI device if its PME Status bit is set. |
1309 | * @dev: Device to handle. | 1302 | * @dev: Device to handle. |
@@ -1315,8 +1308,8 @@ void pci_wakeup_event(struct pci_dev *dev) | |||
1315 | static int pci_pme_wakeup(struct pci_dev *dev, void *ign) | 1308 | static int pci_pme_wakeup(struct pci_dev *dev, void *ign) |
1316 | { | 1309 | { |
1317 | if (pci_check_pme_status(dev)) { | 1310 | if (pci_check_pme_status(dev)) { |
1318 | pm_request_resume(&dev->dev); | ||
1319 | pci_wakeup_event(dev); | 1311 | pci_wakeup_event(dev); |
1312 | pm_request_resume(&dev->dev); | ||
1320 | } | 1313 | } |
1321 | return 0; | 1314 | return 0; |
1322 | } | 1315 | } |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index f5c7c382765f..f69d6e0fda75 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -22,8 +22,13 @@ extern void pci_remove_firmware_label_files(struct pci_dev *pdev); | |||
22 | #endif | 22 | #endif |
23 | extern void pci_cleanup_rom(struct pci_dev *dev); | 23 | extern void pci_cleanup_rom(struct pci_dev *dev); |
24 | #ifdef HAVE_PCI_MMAP | 24 | #ifdef HAVE_PCI_MMAP |
25 | enum pci_mmap_api { | ||
26 | PCI_MMAP_SYSFS, /* mmap on /sys/bus/pci/devices/<BDF>/resource<N> */ | ||
27 | PCI_MMAP_PROCFS /* mmap on /proc/bus/pci/<BDF> */ | ||
28 | }; | ||
25 | extern int pci_mmap_fits(struct pci_dev *pdev, int resno, | 29 | extern int pci_mmap_fits(struct pci_dev *pdev, int resno, |
26 | struct vm_area_struct *vma); | 30 | struct vm_area_struct *vmai, |
31 | enum pci_mmap_api mmap_api); | ||
27 | #endif | 32 | #endif |
28 | int pci_probe_reset_function(struct pci_dev *dev); | 33 | int pci_probe_reset_function(struct pci_dev *dev); |
29 | 34 | ||
@@ -69,6 +74,12 @@ extern void pci_pm_init(struct pci_dev *dev); | |||
69 | extern void platform_pci_wakeup_init(struct pci_dev *dev); | 74 | extern void platform_pci_wakeup_init(struct pci_dev *dev); |
70 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); | 75 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); |
71 | 76 | ||
77 | static inline void pci_wakeup_event(struct pci_dev *dev) | ||
78 | { | ||
79 | /* Wait 100 ms before the system can be put into a sleep state. */ | ||
80 | pm_wakeup_event(&dev->dev, 100); | ||
81 | } | ||
82 | |||
72 | static inline bool pci_is_bridge(struct pci_dev *pci_dev) | 83 | static inline bool pci_is_bridge(struct pci_dev *pci_dev) |
73 | { | 84 | { |
74 | return !!(pci_dev->subordinate); | 85 | return !!(pci_dev->subordinate); |
@@ -135,14 +146,6 @@ static inline void pci_no_msi(void) { } | |||
135 | static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } | 146 | static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } |
136 | #endif | 147 | #endif |
137 | 148 | ||
138 | #ifdef CONFIG_PCIEAER | ||
139 | void pci_no_aer(void); | ||
140 | bool pci_aer_available(void); | ||
141 | #else | ||
142 | static inline void pci_no_aer(void) { } | ||
143 | static inline bool pci_aer_available(void) { return false; } | ||
144 | #endif | ||
145 | |||
146 | static inline int pci_no_d1d2(struct pci_dev *dev) | 149 | static inline int pci_no_d1d2(struct pci_dev *dev) |
147 | { | 150 | { |
148 | unsigned int parent_dstates = 0; | 151 | unsigned int parent_dstates = 0; |
diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig index dda70981b7a6..dc29348264c6 100644 --- a/drivers/pci/pcie/Kconfig +++ b/drivers/pci/pcie/Kconfig | |||
@@ -31,7 +31,7 @@ source "drivers/pci/pcie/aer/Kconfig" | |||
31 | # PCI Express ASPM | 31 | # PCI Express ASPM |
32 | # | 32 | # |
33 | config PCIEASPM | 33 | config PCIEASPM |
34 | bool "PCI Express ASPM control" if EMBEDDED | 34 | bool "PCI Express ASPM control" if EXPERT |
35 | depends on PCI && PCIEPORTBUS | 35 | depends on PCI && PCIEPORTBUS |
36 | default y | 36 | default y |
37 | help | 37 | help |
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index 2b2b6508efde..58ad7917553c 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/pci.h> | 19 | #include <linux/pci.h> |
20 | #include <linux/pci-acpi.h> | ||
20 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
21 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
22 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h index 9656e3060412..80c11d131499 100644 --- a/drivers/pci/pcie/aer/aerdrv.h +++ b/drivers/pci/pcie/aer/aerdrv.h | |||
@@ -132,7 +132,6 @@ static inline int aer_osc_setup(struct pcie_device *pciedev) | |||
132 | 132 | ||
133 | #ifdef CONFIG_ACPI_APEI | 133 | #ifdef CONFIG_ACPI_APEI |
134 | extern int pcie_aer_get_firmware_first(struct pci_dev *pci_dev); | 134 | extern int pcie_aer_get_firmware_first(struct pci_dev *pci_dev); |
135 | extern bool aer_acpi_firmware_first(void); | ||
136 | #else | 135 | #else |
137 | static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev) | 136 | static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev) |
138 | { | 137 | { |
@@ -140,8 +139,6 @@ static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev) | |||
140 | return pci_dev->__aer_firmware_first; | 139 | return pci_dev->__aer_firmware_first; |
141 | return 0; | 140 | return 0; |
142 | } | 141 | } |
143 | |||
144 | static inline bool aer_acpi_firmware_first(void) { return false; } | ||
145 | #endif | 142 | #endif |
146 | 143 | ||
147 | static inline void pcie_aer_force_firmware_first(struct pci_dev *pci_dev, | 144 | static inline void pcie_aer_force_firmware_first(struct pci_dev *pci_dev, |
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 71222814c1ec..3188cd96b338 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
@@ -68,7 +68,7 @@ struct pcie_link_state { | |||
68 | struct aspm_latency acceptable[8]; | 68 | struct aspm_latency acceptable[8]; |
69 | }; | 69 | }; |
70 | 70 | ||
71 | static int aspm_disabled, aspm_force; | 71 | static int aspm_disabled, aspm_force, aspm_clear_state; |
72 | static DEFINE_MUTEX(aspm_lock); | 72 | static DEFINE_MUTEX(aspm_lock); |
73 | static LIST_HEAD(link_list); | 73 | static LIST_HEAD(link_list); |
74 | 74 | ||
@@ -139,7 +139,7 @@ static void pcie_set_clkpm(struct pcie_link_state *link, int enable) | |||
139 | { | 139 | { |
140 | /* Don't enable Clock PM if the link is not Clock PM capable */ | 140 | /* Don't enable Clock PM if the link is not Clock PM capable */ |
141 | if (!link->clkpm_capable && enable) | 141 | if (!link->clkpm_capable && enable) |
142 | return; | 142 | enable = 0; |
143 | /* Need nothing if the specified equals to current state */ | 143 | /* Need nothing if the specified equals to current state */ |
144 | if (link->clkpm_enabled == enable) | 144 | if (link->clkpm_enabled == enable) |
145 | return; | 145 | return; |
@@ -498,6 +498,10 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) | |||
498 | struct pci_dev *child; | 498 | struct pci_dev *child; |
499 | int pos; | 499 | int pos; |
500 | u32 reg32; | 500 | u32 reg32; |
501 | |||
502 | if (aspm_clear_state) | ||
503 | return -EINVAL; | ||
504 | |||
501 | /* | 505 | /* |
502 | * Some functions in a slot might not all be PCIe functions, | 506 | * Some functions in a slot might not all be PCIe functions, |
503 | * very strange. Disable ASPM for the whole slot | 507 | * very strange. Disable ASPM for the whole slot |
@@ -563,12 +567,15 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev) | |||
563 | struct pcie_link_state *link; | 567 | struct pcie_link_state *link; |
564 | int blacklist = !!pcie_aspm_sanity_check(pdev); | 568 | int blacklist = !!pcie_aspm_sanity_check(pdev); |
565 | 569 | ||
566 | if (aspm_disabled || !pci_is_pcie(pdev) || pdev->link_state) | 570 | if (!pci_is_pcie(pdev) || pdev->link_state) |
567 | return; | 571 | return; |
568 | if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && | 572 | if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && |
569 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) | 573 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) |
570 | return; | 574 | return; |
571 | 575 | ||
576 | if (aspm_disabled && !aspm_clear_state) | ||
577 | return; | ||
578 | |||
572 | /* VIA has a strange chipset, root port is under a bridge */ | 579 | /* VIA has a strange chipset, root port is under a bridge */ |
573 | if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT && | 580 | if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT && |
574 | pdev->bus->self) | 581 | pdev->bus->self) |
@@ -641,7 +648,7 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev) | |||
641 | struct pci_dev *parent = pdev->bus->self; | 648 | struct pci_dev *parent = pdev->bus->self; |
642 | struct pcie_link_state *link, *root, *parent_link; | 649 | struct pcie_link_state *link, *root, *parent_link; |
643 | 650 | ||
644 | if (aspm_disabled || !pci_is_pcie(pdev) || | 651 | if ((aspm_disabled && !aspm_clear_state) || !pci_is_pcie(pdev) || |
645 | !parent || !parent->link_state) | 652 | !parent || !parent->link_state) |
646 | return; | 653 | return; |
647 | if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && | 654 | if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && |
@@ -899,6 +906,12 @@ static int __init pcie_aspm_disable(char *str) | |||
899 | 906 | ||
900 | __setup("pcie_aspm=", pcie_aspm_disable); | 907 | __setup("pcie_aspm=", pcie_aspm_disable); |
901 | 908 | ||
909 | void pcie_clear_aspm(void) | ||
910 | { | ||
911 | if (!aspm_force) | ||
912 | aspm_clear_state = 1; | ||
913 | } | ||
914 | |||
902 | void pcie_no_aspm(void) | 915 | void pcie_no_aspm(void) |
903 | { | 916 | { |
904 | if (!aspm_force) | 917 | if (!aspm_force) |
diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c index 2f3c90407227..0057344a3fcb 100644 --- a/drivers/pci/pcie/pme.c +++ b/drivers/pci/pcie/pme.c | |||
@@ -26,9 +26,6 @@ | |||
26 | #include "../pci.h" | 26 | #include "../pci.h" |
27 | #include "portdrv.h" | 27 | #include "portdrv.h" |
28 | 28 | ||
29 | #define PCI_EXP_RTSTA_PME 0x10000 /* PME status */ | ||
30 | #define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */ | ||
31 | |||
32 | /* | 29 | /* |
33 | * If this switch is set, MSI will not be used for PCIe PME signaling. This | 30 | * If this switch is set, MSI will not be used for PCIe PME signaling. This |
34 | * causes the PCIe port driver to use INTx interrupts only, but it turns out | 31 | * causes the PCIe port driver to use INTx interrupts only, but it turns out |
@@ -74,22 +71,6 @@ void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable) | |||
74 | } | 71 | } |
75 | 72 | ||
76 | /** | 73 | /** |
77 | * pcie_pme_clear_status - Clear root port PME interrupt status. | ||
78 | * @dev: PCIe root port or event collector. | ||
79 | */ | ||
80 | static void pcie_pme_clear_status(struct pci_dev *dev) | ||
81 | { | ||
82 | int rtsta_pos; | ||
83 | u32 rtsta; | ||
84 | |||
85 | rtsta_pos = pci_pcie_cap(dev) + PCI_EXP_RTSTA; | ||
86 | |||
87 | pci_read_config_dword(dev, rtsta_pos, &rtsta); | ||
88 | rtsta |= PCI_EXP_RTSTA_PME; | ||
89 | pci_write_config_dword(dev, rtsta_pos, rtsta); | ||
90 | } | ||
91 | |||
92 | /** | ||
93 | * pcie_pme_walk_bus - Scan a PCI bus for devices asserting PME#. | 74 | * pcie_pme_walk_bus - Scan a PCI bus for devices asserting PME#. |
94 | * @bus: PCI bus to scan. | 75 | * @bus: PCI bus to scan. |
95 | * | 76 | * |
@@ -103,8 +84,8 @@ static bool pcie_pme_walk_bus(struct pci_bus *bus) | |||
103 | list_for_each_entry(dev, &bus->devices, bus_list) { | 84 | list_for_each_entry(dev, &bus->devices, bus_list) { |
104 | /* Skip PCIe devices in case we started from a root port. */ | 85 | /* Skip PCIe devices in case we started from a root port. */ |
105 | if (!pci_is_pcie(dev) && pci_check_pme_status(dev)) { | 86 | if (!pci_is_pcie(dev) && pci_check_pme_status(dev)) { |
106 | pm_request_resume(&dev->dev); | ||
107 | pci_wakeup_event(dev); | 87 | pci_wakeup_event(dev); |
88 | pm_request_resume(&dev->dev); | ||
108 | ret = true; | 89 | ret = true; |
109 | } | 90 | } |
110 | 91 | ||
@@ -206,8 +187,8 @@ static void pcie_pme_handle_request(struct pci_dev *port, u16 req_id) | |||
206 | /* The device is there, but we have to check its PME status. */ | 187 | /* The device is there, but we have to check its PME status. */ |
207 | found = pci_check_pme_status(dev); | 188 | found = pci_check_pme_status(dev); |
208 | if (found) { | 189 | if (found) { |
209 | pm_request_resume(&dev->dev); | ||
210 | pci_wakeup_event(dev); | 190 | pci_wakeup_event(dev); |
191 | pm_request_resume(&dev->dev); | ||
211 | } | 192 | } |
212 | pci_dev_put(dev); | 193 | pci_dev_put(dev); |
213 | } else if (devfn) { | 194 | } else if (devfn) { |
@@ -253,7 +234,7 @@ static void pcie_pme_work_fn(struct work_struct *work) | |||
253 | * Clear PME status of the port. If there are other | 234 | * Clear PME status of the port. If there are other |
254 | * pending PMEs, the status will be set again. | 235 | * pending PMEs, the status will be set again. |
255 | */ | 236 | */ |
256 | pcie_pme_clear_status(port); | 237 | pcie_clear_root_pme_status(port); |
257 | 238 | ||
258 | spin_unlock_irq(&data->lock); | 239 | spin_unlock_irq(&data->lock); |
259 | pcie_pme_handle_request(port, rtsta & 0xffff); | 240 | pcie_pme_handle_request(port, rtsta & 0xffff); |
@@ -378,7 +359,7 @@ static int pcie_pme_probe(struct pcie_device *srv) | |||
378 | 359 | ||
379 | port = srv->port; | 360 | port = srv->port; |
380 | pcie_pme_interrupt_enable(port, false); | 361 | pcie_pme_interrupt_enable(port, false); |
381 | pcie_pme_clear_status(port); | 362 | pcie_clear_root_pme_status(port); |
382 | 363 | ||
383 | ret = request_irq(srv->irq, pcie_pme_irq, IRQF_SHARED, "PCIe PME", srv); | 364 | ret = request_irq(srv->irq, pcie_pme_irq, IRQF_SHARED, "PCIe PME", srv); |
384 | if (ret) { | 365 | if (ret) { |
@@ -402,7 +383,7 @@ static int pcie_pme_suspend(struct pcie_device *srv) | |||
402 | 383 | ||
403 | spin_lock_irq(&data->lock); | 384 | spin_lock_irq(&data->lock); |
404 | pcie_pme_interrupt_enable(port, false); | 385 | pcie_pme_interrupt_enable(port, false); |
405 | pcie_pme_clear_status(port); | 386 | pcie_clear_root_pme_status(port); |
406 | data->noirq = true; | 387 | data->noirq = true; |
407 | spin_unlock_irq(&data->lock); | 388 | spin_unlock_irq(&data->lock); |
408 | 389 | ||
@@ -422,7 +403,7 @@ static int pcie_pme_resume(struct pcie_device *srv) | |||
422 | 403 | ||
423 | spin_lock_irq(&data->lock); | 404 | spin_lock_irq(&data->lock); |
424 | data->noirq = false; | 405 | data->noirq = false; |
425 | pcie_pme_clear_status(port); | 406 | pcie_clear_root_pme_status(port); |
426 | pcie_pme_interrupt_enable(port, true); | 407 | pcie_pme_interrupt_enable(port, true); |
427 | spin_unlock_irq(&data->lock); | 408 | spin_unlock_irq(&data->lock); |
428 | 409 | ||
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index 7b5aba0a3291..bd00a01aef14 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h | |||
@@ -20,9 +20,6 @@ | |||
20 | 20 | ||
21 | #define get_descriptor_id(type, service) (((type - 4) << 4) | service) | 21 | #define get_descriptor_id(type, service) (((type - 4) << 4) | service) |
22 | 22 | ||
23 | extern bool pcie_ports_disabled; | ||
24 | extern bool pcie_ports_auto; | ||
25 | |||
26 | extern struct bus_type pcie_port_bus_type; | 23 | extern struct bus_type pcie_port_bus_type; |
27 | extern int pcie_port_device_register(struct pci_dev *dev); | 24 | extern int pcie_port_device_register(struct pci_dev *dev); |
28 | #ifdef CONFIG_PM | 25 | #ifdef CONFIG_PM |
@@ -35,6 +32,8 @@ extern void pcie_port_bus_unregister(void); | |||
35 | 32 | ||
36 | struct pci_dev; | 33 | struct pci_dev; |
37 | 34 | ||
35 | extern void pcie_clear_root_pme_status(struct pci_dev *dev); | ||
36 | |||
38 | #ifdef CONFIG_PCIE_PME | 37 | #ifdef CONFIG_PCIE_PME |
39 | extern bool pcie_pme_msi_disabled; | 38 | extern bool pcie_pme_msi_disabled; |
40 | 39 | ||
diff --git a/drivers/pci/pcie/portdrv_acpi.c b/drivers/pci/pcie/portdrv_acpi.c index 5982b6a63b89..a86b56e5f2f2 100644 --- a/drivers/pci/pcie/portdrv_acpi.c +++ b/drivers/pci/pcie/portdrv_acpi.c | |||
@@ -33,7 +33,7 @@ | |||
33 | */ | 33 | */ |
34 | int pcie_port_acpi_setup(struct pci_dev *port, int *srv_mask) | 34 | int pcie_port_acpi_setup(struct pci_dev *port, int *srv_mask) |
35 | { | 35 | { |
36 | acpi_status status; | 36 | struct acpi_pci_root *root; |
37 | acpi_handle handle; | 37 | acpi_handle handle; |
38 | u32 flags; | 38 | u32 flags; |
39 | 39 | ||
@@ -44,26 +44,11 @@ int pcie_port_acpi_setup(struct pci_dev *port, int *srv_mask) | |||
44 | if (!handle) | 44 | if (!handle) |
45 | return -EINVAL; | 45 | return -EINVAL; |
46 | 46 | ||
47 | flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL | 47 | root = acpi_pci_find_root(handle); |
48 | | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | 48 | if (!root) |
49 | | OSC_PCI_EXPRESS_PME_CONTROL; | ||
50 | |||
51 | if (pci_aer_available()) { | ||
52 | if (aer_acpi_firmware_first()) | ||
53 | dev_dbg(&port->dev, "PCIe errors handled by BIOS.\n"); | ||
54 | else | ||
55 | flags |= OSC_PCI_EXPRESS_AER_CONTROL; | ||
56 | } | ||
57 | |||
58 | status = acpi_pci_osc_control_set(handle, &flags, | ||
59 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
60 | if (ACPI_FAILURE(status)) { | ||
61 | dev_dbg(&port->dev, "ACPI _OSC request failed (code %d)\n", | ||
62 | status); | ||
63 | return -ENODEV; | 49 | return -ENODEV; |
64 | } | ||
65 | 50 | ||
66 | dev_info(&port->dev, "ACPI _OSC control granted for 0x%02x\n", flags); | 51 | flags = root->osc_control_set; |
67 | 52 | ||
68 | *srv_mask = PCIE_PORT_SERVICE_VC; | 53 | *srv_mask = PCIE_PORT_SERVICE_VC; |
69 | if (flags & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL) | 54 | if (flags & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL) |
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index a9c222d79ebc..5130d0d22390 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
@@ -241,17 +241,17 @@ static int get_port_device_capability(struct pci_dev *dev) | |||
241 | int cap_mask; | 241 | int cap_mask; |
242 | int err; | 242 | int err; |
243 | 243 | ||
244 | if (pcie_ports_disabled) | ||
245 | return 0; | ||
246 | |||
244 | err = pcie_port_platform_notify(dev, &cap_mask); | 247 | err = pcie_port_platform_notify(dev, &cap_mask); |
245 | if (pcie_ports_auto) { | 248 | if (!pcie_ports_auto) { |
246 | if (err) { | ||
247 | pcie_no_aspm(); | ||
248 | return 0; | ||
249 | } | ||
250 | } else { | ||
251 | cap_mask = PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP | 249 | cap_mask = PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP |
252 | | PCIE_PORT_SERVICE_VC; | 250 | | PCIE_PORT_SERVICE_VC; |
253 | if (pci_aer_available()) | 251 | if (pci_aer_available()) |
254 | cap_mask |= PCIE_PORT_SERVICE_AER; | 252 | cap_mask |= PCIE_PORT_SERVICE_AER; |
253 | } else if (err) { | ||
254 | return 0; | ||
255 | } | 255 | } |
256 | 256 | ||
257 | pos = pci_pcie_cap(dev); | 257 | pos = pci_pcie_cap(dev); |
@@ -349,15 +349,18 @@ int pcie_port_device_register(struct pci_dev *dev) | |||
349 | int status, capabilities, i, nr_service; | 349 | int status, capabilities, i, nr_service; |
350 | int irqs[PCIE_PORT_DEVICE_MAXSERVICES]; | 350 | int irqs[PCIE_PORT_DEVICE_MAXSERVICES]; |
351 | 351 | ||
352 | /* Get and check PCI Express port services */ | ||
353 | capabilities = get_port_device_capability(dev); | ||
354 | if (!capabilities) | ||
355 | return -ENODEV; | ||
356 | |||
357 | /* Enable PCI Express port device */ | 352 | /* Enable PCI Express port device */ |
358 | status = pci_enable_device(dev); | 353 | status = pci_enable_device(dev); |
359 | if (status) | 354 | if (status) |
360 | return status; | 355 | return status; |
356 | |||
357 | /* Get and check PCI Express port services */ | ||
358 | capabilities = get_port_device_capability(dev); | ||
359 | if (!capabilities) { | ||
360 | pcie_no_aspm(); | ||
361 | return 0; | ||
362 | } | ||
363 | |||
361 | pci_set_master(dev); | 364 | pci_set_master(dev); |
362 | /* | 365 | /* |
363 | * Initialize service irqs. Don't use service devices that | 366 | * Initialize service irqs. Don't use service devices that |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index f9033e190fb6..e0610bda1dea 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -57,6 +57,22 @@ __setup("pcie_ports=", pcie_port_setup); | |||
57 | 57 | ||
58 | /* global data */ | 58 | /* global data */ |
59 | 59 | ||
60 | /** | ||
61 | * pcie_clear_root_pme_status - Clear root port PME interrupt status. | ||
62 | * @dev: PCIe root port or event collector. | ||
63 | */ | ||
64 | void pcie_clear_root_pme_status(struct pci_dev *dev) | ||
65 | { | ||
66 | int rtsta_pos; | ||
67 | u32 rtsta; | ||
68 | |||
69 | rtsta_pos = pci_pcie_cap(dev) + PCI_EXP_RTSTA; | ||
70 | |||
71 | pci_read_config_dword(dev, rtsta_pos, &rtsta); | ||
72 | rtsta |= PCI_EXP_RTSTA_PME; | ||
73 | pci_write_config_dword(dev, rtsta_pos, rtsta); | ||
74 | } | ||
75 | |||
60 | static int pcie_portdrv_restore_config(struct pci_dev *dev) | 76 | static int pcie_portdrv_restore_config(struct pci_dev *dev) |
61 | { | 77 | { |
62 | int retval; | 78 | int retval; |
@@ -69,6 +85,20 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev) | |||
69 | } | 85 | } |
70 | 86 | ||
71 | #ifdef CONFIG_PM | 87 | #ifdef CONFIG_PM |
88 | static int pcie_port_resume_noirq(struct device *dev) | ||
89 | { | ||
90 | struct pci_dev *pdev = to_pci_dev(dev); | ||
91 | |||
92 | /* | ||
93 | * Some BIOSes forget to clear Root PME Status bits after system wakeup | ||
94 | * which breaks ACPI-based runtime wakeup on PCI Express, so clear those | ||
95 | * bits now just in case (shouldn't hurt). | ||
96 | */ | ||
97 | if(pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) | ||
98 | pcie_clear_root_pme_status(pdev); | ||
99 | return 0; | ||
100 | } | ||
101 | |||
72 | static const struct dev_pm_ops pcie_portdrv_pm_ops = { | 102 | static const struct dev_pm_ops pcie_portdrv_pm_ops = { |
73 | .suspend = pcie_port_device_suspend, | 103 | .suspend = pcie_port_device_suspend, |
74 | .resume = pcie_port_device_resume, | 104 | .resume = pcie_port_device_resume, |
@@ -76,6 +106,7 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = { | |||
76 | .thaw = pcie_port_device_resume, | 106 | .thaw = pcie_port_device_resume, |
77 | .poweroff = pcie_port_device_suspend, | 107 | .poweroff = pcie_port_device_suspend, |
78 | .restore = pcie_port_device_resume, | 108 | .restore = pcie_port_device_resume, |
109 | .resume_noirq = pcie_port_resume_noirq, | ||
79 | }; | 110 | }; |
80 | 111 | ||
81 | #define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops) | 112 | #define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops) |
@@ -327,10 +358,8 @@ static int __init pcie_portdrv_init(void) | |||
327 | { | 358 | { |
328 | int retval; | 359 | int retval; |
329 | 360 | ||
330 | if (pcie_ports_disabled) { | 361 | if (pcie_ports_disabled) |
331 | pcie_no_aspm(); | 362 | return pci_register_driver(&pcie_portdriver); |
332 | return -EACCES; | ||
333 | } | ||
334 | 363 | ||
335 | dmi_check_system(pcie_portdrv_dmi_table); | 364 | dmi_check_system(pcie_portdrv_dmi_table); |
336 | 365 | ||
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 297b72c880a1..27911b55c2a5 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/proc_fs.h> | 11 | #include <linux/proc_fs.h> |
12 | #include <linux/seq_file.h> | 12 | #include <linux/seq_file.h> |
13 | #include <linux/smp_lock.h> | ||
14 | #include <linux/capability.h> | 13 | #include <linux/capability.h> |
15 | #include <asm/uaccess.h> | 14 | #include <asm/uaccess.h> |
16 | #include <asm/byteorder.h> | 15 | #include <asm/byteorder.h> |
@@ -257,7 +256,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) | |||
257 | 256 | ||
258 | /* Make sure the caller is mapping a real resource for this device */ | 257 | /* Make sure the caller is mapping a real resource for this device */ |
259 | for (i = 0; i < PCI_ROM_RESOURCE; i++) { | 258 | for (i = 0; i < PCI_ROM_RESOURCE; i++) { |
260 | if (pci_mmap_fits(dev, i, vma)) | 259 | if (pci_mmap_fits(dev, i, vma, PCI_MMAP_PROCFS)) |
261 | break; | 260 | break; |
262 | } | 261 | } |
263 | 262 | ||
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index f5c63fe9db5c..53a786fd0d40 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -2136,6 +2136,24 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB, | |||
2136 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82875_HB, | 2136 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82875_HB, |
2137 | quirk_unhide_mch_dev6); | 2137 | quirk_unhide_mch_dev6); |
2138 | 2138 | ||
2139 | #ifdef CONFIG_TILE | ||
2140 | /* | ||
2141 | * The Tilera TILEmpower platform needs to set the link speed | ||
2142 | * to 2.5GT(Giga-Transfers)/s (Gen 1). The default link speed | ||
2143 | * setting is 5GT/s (Gen 2). 0x98 is the Link Control2 PCIe | ||
2144 | * capability register of the PEX8624 PCIe switch. The switch | ||
2145 | * supports link speed auto negotiation, but falsely sets | ||
2146 | * the link speed to 5GT/s. | ||
2147 | */ | ||
2148 | static void __devinit quirk_tile_plx_gen1(struct pci_dev *dev) | ||
2149 | { | ||
2150 | if (tile_plx_gen1) { | ||
2151 | pci_write_config_dword(dev, 0x98, 0x1); | ||
2152 | mdelay(50); | ||
2153 | } | ||
2154 | } | ||
2155 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8624, quirk_tile_plx_gen1); | ||
2156 | #endif /* CONFIG_TILE */ | ||
2139 | 2157 | ||
2140 | #ifdef CONFIG_PCI_MSI | 2158 | #ifdef CONFIG_PCI_MSI |
2141 | /* Some chipsets do not support MSI. We cannot easily rely on setting | 2159 | /* Some chipsets do not support MSI. We cannot easily rely on setting |
@@ -2311,6 +2329,9 @@ static void __devinit nvbridge_check_legacy_irq_routing(struct pci_dev *dev) | |||
2311 | { | 2329 | { |
2312 | u32 cfg; | 2330 | u32 cfg; |
2313 | 2331 | ||
2332 | if (!pci_find_capability(dev, PCI_CAP_ID_HT)) | ||
2333 | return; | ||
2334 | |||
2314 | pci_read_config_dword(dev, 0x74, &cfg); | 2335 | pci_read_config_dword(dev, 0x74, &cfg); |
2315 | 2336 | ||
2316 | if (cfg & ((1 << 2) | (1 << 15))) { | 2337 | if (cfg & ((1 << 2) | (1 << 15))) { |
@@ -2746,6 +2767,29 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_m | |||
2746 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); | 2767 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); |
2747 | #endif /*CONFIG_MMC_RICOH_MMC*/ | 2768 | #endif /*CONFIG_MMC_RICOH_MMC*/ |
2748 | 2769 | ||
2770 | #if defined(CONFIG_DMAR) || defined(CONFIG_INTR_REMAP) | ||
2771 | #define VTUNCERRMSK_REG 0x1ac | ||
2772 | #define VTD_MSK_SPEC_ERRORS (1 << 31) | ||
2773 | /* | ||
2774 | * This is a quirk for masking vt-d spec defined errors to platform error | ||
2775 | * handling logic. With out this, platforms using Intel 7500, 5500 chipsets | ||
2776 | * (and the derivative chipsets like X58 etc) seem to generate NMI/SMI (based | ||
2777 | * on the RAS config settings of the platform) when a vt-d fault happens. | ||
2778 | * The resulting SMI caused the system to hang. | ||
2779 | * | ||
2780 | * VT-d spec related errors are already handled by the VT-d OS code, so no | ||
2781 | * need to report the same error through other channels. | ||
2782 | */ | ||
2783 | static void vtd_mask_spec_errors(struct pci_dev *dev) | ||
2784 | { | ||
2785 | u32 word; | ||
2786 | |||
2787 | pci_read_config_dword(dev, VTUNCERRMSK_REG, &word); | ||
2788 | pci_write_config_dword(dev, VTUNCERRMSK_REG, word | VTD_MSK_SPEC_ERRORS); | ||
2789 | } | ||
2790 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x342e, vtd_mask_spec_errors); | ||
2791 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x3c28, vtd_mask_spec_errors); | ||
2792 | #endif | ||
2749 | 2793 | ||
2750 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, | 2794 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, |
2751 | struct pci_fixup *end) | 2795 | struct pci_fixup *end) |
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c index a87c4985326e..3a5a6fcc0ead 100644 --- a/drivers/pci/xen-pcifront.c +++ b/drivers/pci/xen-pcifront.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/spinlock.h> | 13 | #include <linux/spinlock.h> |
14 | #include <linux/pci.h> | 14 | #include <linux/pci.h> |
15 | #include <linux/msi.h> | 15 | #include <linux/msi.h> |
16 | #include <xen/xenbus.h> | ||
17 | #include <xen/interface/io/pciif.h> | 16 | #include <xen/interface/io/pciif.h> |
18 | #include <asm/xen/pci.h> | 17 | #include <asm/xen/pci.h> |
19 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
@@ -576,8 +575,9 @@ static pci_ers_result_t pcifront_common_process(int cmd, | |||
576 | 575 | ||
577 | pcidev = pci_get_bus_and_slot(bus, devfn); | 576 | pcidev = pci_get_bus_and_slot(bus, devfn); |
578 | if (!pcidev || !pcidev->driver) { | 577 | if (!pcidev || !pcidev->driver) { |
579 | dev_err(&pcidev->dev, | 578 | dev_err(&pdev->xdev->dev, "device or AER driver is NULL\n"); |
580 | "device or driver is NULL\n"); | 579 | if (pcidev) |
580 | pci_dev_put(pcidev); | ||
581 | return result; | 581 | return result; |
582 | } | 582 | } |
583 | pdrv = pcidev->driver; | 583 | pdrv = pcidev->driver; |