aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pcie/portdrv_pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/pcie/portdrv_pci.c')
-rw-r--r--drivers/pci/pcie/portdrv_pci.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index a49452e2aed9..127e8f169d9c 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -15,6 +15,7 @@
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/pcieport_if.h> 16#include <linux/pcieport_if.h>
17#include <linux/aer.h> 17#include <linux/aer.h>
18#include <linux/dmi.h>
18 19
19#include "portdrv.h" 20#include "portdrv.h"
20#include "aer/aerdrv.h" 21#include "aer/aerdrv.h"
@@ -24,7 +25,7 @@
24 */ 25 */
25#define DRIVER_VERSION "v1.0" 26#define DRIVER_VERSION "v1.0"
26#define DRIVER_AUTHOR "tom.l.nguyen@intel.com" 27#define DRIVER_AUTHOR "tom.l.nguyen@intel.com"
27#define DRIVER_DESC "PCIE Port Bus Driver" 28#define DRIVER_DESC "PCIe Port Bus Driver"
28MODULE_AUTHOR(DRIVER_AUTHOR); 29MODULE_AUTHOR(DRIVER_AUTHOR);
29MODULE_DESCRIPTION(DRIVER_DESC); 30MODULE_DESCRIPTION(DRIVER_DESC);
30MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
@@ -63,7 +64,7 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = {
63 * pcie_portdrv_probe - Probe PCI-Express port devices 64 * pcie_portdrv_probe - Probe PCI-Express port devices
64 * @dev: PCI-Express port device being probed 65 * @dev: PCI-Express port device being probed
65 * 66 *
66 * If detected invokes the pcie_port_device_register() method for 67 * If detected invokes the pcie_port_device_register() method for
67 * this port device. 68 * this port device.
68 * 69 *
69 */ 70 */
@@ -78,7 +79,7 @@ static int __devinit pcie_portdrv_probe(struct pci_dev *dev,
78 (dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))) 79 (dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)))
79 return -ENODEV; 80 return -ENODEV;
80 81
81 if (!dev->irq && dev->pin) { 82 if (!dev->irq && dev->pin) {
82 dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; " 83 dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; "
83 "check vendor BIOS\n", dev->vendor, dev->device); 84 "check vendor BIOS\n", dev->vendor, dev->device);
84 } 85 }
@@ -91,7 +92,7 @@ static int __devinit pcie_portdrv_probe(struct pci_dev *dev,
91 return 0; 92 return 0;
92} 93}
93 94
94static void pcie_portdrv_remove (struct pci_dev *dev) 95static void pcie_portdrv_remove(struct pci_dev *dev)
95{ 96{
96 pcie_port_device_remove(dev); 97 pcie_port_device_remove(dev);
97 pci_disable_device(dev); 98 pci_disable_device(dev);
@@ -129,14 +130,13 @@ static int error_detected_iter(struct device *device, void *data)
129static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev, 130static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev,
130 enum pci_channel_state error) 131 enum pci_channel_state error)
131{ 132{
132 struct aer_broadcast_data result_data = 133 struct aer_broadcast_data data = {error, PCI_ERS_RESULT_CAN_RECOVER};
133 {error, PCI_ERS_RESULT_CAN_RECOVER}; 134 int ret;
134 int retval;
135 135
136 /* can not fail */ 136 /* can not fail */
137 retval = device_for_each_child(&dev->dev, &result_data, error_detected_iter); 137 ret = device_for_each_child(&dev->dev, &data, error_detected_iter);
138 138
139 return result_data.result; 139 return data.result;
140} 140}
141 141
142static int mmio_enabled_iter(struct device *device, void *data) 142static int mmio_enabled_iter(struct device *device, void *data)
@@ -274,10 +274,36 @@ static struct pci_driver pcie_portdriver = {
274 .driver.pm = PCIE_PORTDRV_PM_OPS, 274 .driver.pm = PCIE_PORTDRV_PM_OPS,
275}; 275};
276 276
277static int __init dmi_pcie_pme_disable_msi(const struct dmi_system_id *d)
278{
279 pr_notice("%s detected: will not use MSI for PCIe PME signaling\n",
280 d->ident);
281 pcie_pme_disable_msi();
282 return 0;
283}
284
285static struct dmi_system_id __initdata pcie_portdrv_dmi_table[] = {
286 /*
287 * Boxes that should not use MSI for PCIe PME signaling.
288 */
289 {
290 .callback = dmi_pcie_pme_disable_msi,
291 .ident = "MSI Wind U-100",
292 .matches = {
293 DMI_MATCH(DMI_SYS_VENDOR,
294 "MICRO-STAR INTERNATIONAL CO., LTD"),
295 DMI_MATCH(DMI_PRODUCT_NAME, "U-100"),
296 },
297 },
298 {}
299};
300
277static int __init pcie_portdrv_init(void) 301static int __init pcie_portdrv_init(void)
278{ 302{
279 int retval; 303 int retval;
280 304
305 dmi_check_system(pcie_portdrv_dmi_table);
306
281 retval = pcie_port_bus_register(); 307 retval = pcie_port_bus_register();
282 if (retval) { 308 if (retval) {
283 printk(KERN_WARNING "PCIE: bus_register error: %d\n", retval); 309 printk(KERN_WARNING "PCIE: bus_register error: %d\n", retval);
@@ -290,7 +316,7 @@ static int __init pcie_portdrv_init(void)
290 return retval; 316 return retval;
291} 317}
292 318
293static void __exit pcie_portdrv_exit(void) 319static void __exit pcie_portdrv_exit(void)
294{ 320{
295 pci_unregister_driver(&pcie_portdriver); 321 pci_unregister_driver(&pcie_portdriver);
296 pcie_port_bus_unregister(); 322 pcie_port_bus_unregister();