diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/pcie/aer/aerdrv.h | 17 | ||||
-rw-r--r-- | drivers/pci/pcie/aer/aerdrv_acpi.c | 77 | ||||
-rw-r--r-- | drivers/pci/pcie/aer/aerdrv_core.c | 8 | ||||
-rw-r--r-- | drivers/pci/probe.c | 8 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 5 |
5 files changed, 102 insertions, 13 deletions
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h index 7aaae2d2bd67..80c11d131499 100644 --- a/drivers/pci/pcie/aer/aerdrv.h +++ b/drivers/pci/pcie/aer/aerdrv.h | |||
@@ -130,4 +130,21 @@ static inline int aer_osc_setup(struct pcie_device *pciedev) | |||
130 | } | 130 | } |
131 | #endif | 131 | #endif |
132 | 132 | ||
133 | #ifdef CONFIG_ACPI_APEI | ||
134 | extern int pcie_aer_get_firmware_first(struct pci_dev *pci_dev); | ||
135 | #else | ||
136 | static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev) | ||
137 | { | ||
138 | if (pci_dev->__aer_firmware_first_valid) | ||
139 | return pci_dev->__aer_firmware_first; | ||
140 | return 0; | ||
141 | } | ||
142 | #endif | ||
143 | |||
144 | static inline void pcie_aer_force_firmware_first(struct pci_dev *pci_dev, | ||
145 | int enable) | ||
146 | { | ||
147 | pci_dev->__aer_firmware_first = !!enable; | ||
148 | pci_dev->__aer_firmware_first_valid = 1; | ||
149 | } | ||
133 | #endif /* _AERDRV_H_ */ | 150 | #endif /* _AERDRV_H_ */ |
diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c index 04814087658d..f278d7b0d95d 100644 --- a/drivers/pci/pcie/aer/aerdrv_acpi.c +++ b/drivers/pci/pcie/aer/aerdrv_acpi.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/acpi.h> | 16 | #include <linux/acpi.h> |
17 | #include <linux/pci-acpi.h> | 17 | #include <linux/pci-acpi.h> |
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <acpi/apei.h> | ||
19 | #include "aerdrv.h" | 20 | #include "aerdrv.h" |
20 | 21 | ||
21 | /** | 22 | /** |
@@ -53,3 +54,79 @@ int aer_osc_setup(struct pcie_device *pciedev) | |||
53 | 54 | ||
54 | return 0; | 55 | return 0; |
55 | } | 56 | } |
57 | |||
58 | #ifdef CONFIG_ACPI_APEI | ||
59 | static inline int hest_match_pci(struct acpi_hest_aer_common *p, | ||
60 | struct pci_dev *pci) | ||
61 | { | ||
62 | return (0 == pci_domain_nr(pci->bus) && | ||
63 | p->bus == pci->bus->number && | ||
64 | p->device == PCI_SLOT(pci->devfn) && | ||
65 | p->function == PCI_FUNC(pci->devfn)); | ||
66 | } | ||
67 | |||
68 | struct aer_hest_parse_info { | ||
69 | struct pci_dev *pci_dev; | ||
70 | int firmware_first; | ||
71 | }; | ||
72 | |||
73 | static int aer_hest_parse(struct acpi_hest_header *hest_hdr, void *data) | ||
74 | { | ||
75 | struct aer_hest_parse_info *info = data; | ||
76 | struct acpi_hest_aer_common *p; | ||
77 | u8 pcie_type = 0; | ||
78 | u8 bridge = 0; | ||
79 | int ff = 0; | ||
80 | |||
81 | switch (hest_hdr->type) { | ||
82 | case ACPI_HEST_TYPE_AER_ROOT_PORT: | ||
83 | pcie_type = PCI_EXP_TYPE_ROOT_PORT; | ||
84 | break; | ||
85 | case ACPI_HEST_TYPE_AER_ENDPOINT: | ||
86 | pcie_type = PCI_EXP_TYPE_ENDPOINT; | ||
87 | break; | ||
88 | case ACPI_HEST_TYPE_AER_BRIDGE: | ||
89 | if ((info->pci_dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) | ||
90 | bridge = 1; | ||
91 | break; | ||
92 | default: | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | p = (struct acpi_hest_aer_common *)(hest_hdr + 1); | ||
97 | if (p->flags & ACPI_HEST_GLOBAL) { | ||
98 | if ((info->pci_dev->is_pcie && | ||
99 | info->pci_dev->pcie_type == pcie_type) || bridge) | ||
100 | ff = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST); | ||
101 | } else | ||
102 | if (hest_match_pci(p, info->pci_dev)) | ||
103 | ff = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST); | ||
104 | info->firmware_first = ff; | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static void aer_set_firmware_first(struct pci_dev *pci_dev) | ||
110 | { | ||
111 | int rc; | ||
112 | struct aer_hest_parse_info info = { | ||
113 | .pci_dev = pci_dev, | ||
114 | .firmware_first = 0, | ||
115 | }; | ||
116 | |||
117 | rc = apei_hest_parse(aer_hest_parse, &info); | ||
118 | |||
119 | if (rc) | ||
120 | pci_dev->__aer_firmware_first = 0; | ||
121 | else | ||
122 | pci_dev->__aer_firmware_first = info.firmware_first; | ||
123 | pci_dev->__aer_firmware_first_valid = 1; | ||
124 | } | ||
125 | |||
126 | int pcie_aer_get_firmware_first(struct pci_dev *dev) | ||
127 | { | ||
128 | if (!dev->__aer_firmware_first_valid) | ||
129 | aer_set_firmware_first(dev); | ||
130 | return dev->__aer_firmware_first; | ||
131 | } | ||
132 | #endif | ||
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index df2d686fe3dd..8af4f619bba2 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c | |||
@@ -36,7 +36,7 @@ int pci_enable_pcie_error_reporting(struct pci_dev *dev) | |||
36 | u16 reg16 = 0; | 36 | u16 reg16 = 0; |
37 | int pos; | 37 | int pos; |
38 | 38 | ||
39 | if (dev->aer_firmware_first) | 39 | if (pcie_aer_get_firmware_first(dev)) |
40 | return -EIO; | 40 | return -EIO; |
41 | 41 | ||
42 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | 42 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
@@ -63,7 +63,7 @@ int pci_disable_pcie_error_reporting(struct pci_dev *dev) | |||
63 | u16 reg16 = 0; | 63 | u16 reg16 = 0; |
64 | int pos; | 64 | int pos; |
65 | 65 | ||
66 | if (dev->aer_firmware_first) | 66 | if (pcie_aer_get_firmware_first(dev)) |
67 | return -EIO; | 67 | return -EIO; |
68 | 68 | ||
69 | pos = pci_pcie_cap(dev); | 69 | pos = pci_pcie_cap(dev); |
@@ -771,7 +771,7 @@ void aer_isr(struct work_struct *work) | |||
771 | */ | 771 | */ |
772 | int aer_init(struct pcie_device *dev) | 772 | int aer_init(struct pcie_device *dev) |
773 | { | 773 | { |
774 | if (dev->port->aer_firmware_first) { | 774 | if (pcie_aer_get_firmware_first(dev->port)) { |
775 | dev_printk(KERN_DEBUG, &dev->device, | 775 | dev_printk(KERN_DEBUG, &dev->device, |
776 | "PCIe errors handled by platform firmware.\n"); | 776 | "PCIe errors handled by platform firmware.\n"); |
777 | goto out; | 777 | goto out; |
@@ -785,7 +785,7 @@ out: | |||
785 | if (forceload) { | 785 | if (forceload) { |
786 | dev_printk(KERN_DEBUG, &dev->device, | 786 | dev_printk(KERN_DEBUG, &dev->device, |
787 | "aerdrv forceload requested.\n"); | 787 | "aerdrv forceload requested.\n"); |
788 | dev->port->aer_firmware_first = 0; | 788 | pcie_aer_force_firmware_first(dev->port, 0); |
789 | return 0; | 789 | return 0; |
790 | } | 790 | } |
791 | return -ENXIO; | 791 | return -ENXIO; |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index c82548afcd5c..f4adba2d1dd3 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -10,7 +10,6 @@ | |||
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> | ||
14 | #include "pci.h" | 13 | #include "pci.h" |
15 | 14 | ||
16 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ | 15 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ |
@@ -904,12 +903,6 @@ void set_pcie_hotplug_bridge(struct pci_dev *pdev) | |||
904 | pdev->is_hotplug_bridge = 1; | 903 | pdev->is_hotplug_bridge = 1; |
905 | } | 904 | } |
906 | 905 | ||
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 | |||
913 | #define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) | 906 | #define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) |
914 | 907 | ||
915 | /** | 908 | /** |
@@ -939,7 +932,6 @@ int pci_setup_device(struct pci_dev *dev) | |||
939 | dev->multifunction = !!(hdr_type & 0x80); | 932 | dev->multifunction = !!(hdr_type & 0x80); |
940 | dev->error_state = pci_channel_io_normal; | 933 | dev->error_state = pci_channel_io_normal; |
941 | set_pcie_port_type(dev); | 934 | set_pcie_port_type(dev); |
942 | set_pci_aer_firmware_first(dev); | ||
943 | 935 | ||
944 | list_for_each_entry(slot, &dev->bus->slots, list) | 936 | list_for_each_entry(slot, &dev->bus->slots, list) |
945 | if (PCI_SLOT(dev->devfn) == slot->number) | 937 | if (PCI_SLOT(dev->devfn) == slot->number) |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index b7512cf08c58..477345d41641 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -1457,7 +1457,8 @@ static void quirk_jmicron_ata(struct pci_dev *pdev) | |||
1457 | conf5 &= ~(1 << 24); /* Clear bit 24 */ | 1457 | conf5 &= ~(1 << 24); /* Clear bit 24 */ |
1458 | 1458 | ||
1459 | switch (pdev->device) { | 1459 | switch (pdev->device) { |
1460 | case PCI_DEVICE_ID_JMICRON_JMB360: | 1460 | case PCI_DEVICE_ID_JMICRON_JMB360: /* SATA single port */ |
1461 | case PCI_DEVICE_ID_JMICRON_JMB362: /* SATA dual ports */ | ||
1461 | /* The controller should be in single function ahci mode */ | 1462 | /* The controller should be in single function ahci mode */ |
1462 | conf1 |= 0x0002A100; /* Set 8, 13, 15, 17 */ | 1463 | conf1 |= 0x0002A100; /* Set 8, 13, 15, 17 */ |
1463 | break; | 1464 | break; |
@@ -1493,12 +1494,14 @@ static void quirk_jmicron_ata(struct pci_dev *pdev) | |||
1493 | } | 1494 | } |
1494 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB360, quirk_jmicron_ata); | 1495 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB360, quirk_jmicron_ata); |
1495 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, quirk_jmicron_ata); | 1496 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, quirk_jmicron_ata); |
1497 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB362, quirk_jmicron_ata); | ||
1496 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, quirk_jmicron_ata); | 1498 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, quirk_jmicron_ata); |
1497 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata); | 1499 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata); |
1498 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata); | 1500 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata); |
1499 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata); | 1501 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata); |
1500 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB360, quirk_jmicron_ata); | 1502 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB360, quirk_jmicron_ata); |
1501 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, quirk_jmicron_ata); | 1503 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, quirk_jmicron_ata); |
1504 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB362, quirk_jmicron_ata); | ||
1502 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, quirk_jmicron_ata); | 1505 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, quirk_jmicron_ata); |
1503 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata); | 1506 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata); |
1504 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata); | 1507 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata); |