diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/hotplug/Kconfig | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpci_hotplug_pci.c | 54 | ||||
-rw-r--r-- | drivers/pci/pci-driver.c | 3 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 59 |
4 files changed, 102 insertions, 16 deletions
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig index 3c148eaf2f4d..8a60f391ffcf 100644 --- a/drivers/pci/hotplug/Kconfig +++ b/drivers/pci/hotplug/Kconfig | |||
@@ -76,7 +76,7 @@ config HOTPLUG_PCI_IBM | |||
76 | 76 | ||
77 | config HOTPLUG_PCI_ACPI | 77 | config HOTPLUG_PCI_ACPI |
78 | tristate "ACPI PCI Hotplug driver" | 78 | tristate "ACPI PCI Hotplug driver" |
79 | depends on ACPI_DOCK && HOTPLUG_PCI | 79 | depends on (!ACPI_DOCK && ACPI && HOTPLUG_PCI) || (ACPI_DOCK && HOTPLUG_PCI) |
80 | help | 80 | help |
81 | Say Y here if you have a system that supports PCI Hotplug using | 81 | Say Y here if you have a system that supports PCI Hotplug using |
82 | ACPI. | 82 | ACPI. |
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index 02be74caa89f..4afcaffd031c 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c | |||
@@ -254,8 +254,8 @@ int cpci_led_off(struct slot* slot) | |||
254 | 254 | ||
255 | int cpci_configure_slot(struct slot* slot) | 255 | int cpci_configure_slot(struct slot* slot) |
256 | { | 256 | { |
257 | unsigned char busnr; | 257 | struct pci_bus *parent; |
258 | struct pci_bus *child; | 258 | int fn; |
259 | 259 | ||
260 | dbg("%s - enter", __FUNCTION__); | 260 | dbg("%s - enter", __FUNCTION__); |
261 | 261 | ||
@@ -276,23 +276,53 @@ int cpci_configure_slot(struct slot* slot) | |||
276 | */ | 276 | */ |
277 | n = pci_scan_slot(slot->bus, slot->devfn); | 277 | n = pci_scan_slot(slot->bus, slot->devfn); |
278 | dbg("%s: pci_scan_slot returned %d", __FUNCTION__, n); | 278 | dbg("%s: pci_scan_slot returned %d", __FUNCTION__, n); |
279 | if (n > 0) | ||
280 | pci_bus_add_devices(slot->bus); | ||
281 | slot->dev = pci_get_slot(slot->bus, slot->devfn); | 279 | slot->dev = pci_get_slot(slot->bus, slot->devfn); |
282 | if (slot->dev == NULL) { | 280 | if (slot->dev == NULL) { |
283 | err("Could not find PCI device for slot %02x", slot->number); | 281 | err("Could not find PCI device for slot %02x", slot->number); |
284 | return 1; | 282 | return -ENODEV; |
285 | } | 283 | } |
286 | } | 284 | } |
287 | 285 | parent = slot->dev->bus; | |
288 | if (slot->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { | 286 | |
289 | pci_read_config_byte(slot->dev, PCI_SECONDARY_BUS, &busnr); | 287 | for (fn = 0; fn < 8; fn++) { |
290 | child = pci_add_new_bus(slot->dev->bus, slot->dev, busnr); | 288 | struct pci_dev *dev; |
291 | pci_do_scan_bus(child); | 289 | |
292 | pci_bus_size_bridges(child); | 290 | dev = pci_get_slot(parent, PCI_DEVFN(PCI_SLOT(slot->devfn), fn)); |
291 | if (!dev) | ||
292 | continue; | ||
293 | if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || | ||
294 | (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { | ||
295 | /* Find an unused bus number for the new bridge */ | ||
296 | struct pci_bus *child; | ||
297 | unsigned char busnr, start = parent->secondary; | ||
298 | unsigned char end = parent->subordinate; | ||
299 | |||
300 | for (busnr = start; busnr <= end; busnr++) { | ||
301 | if (!pci_find_bus(pci_domain_nr(parent), | ||
302 | busnr)) | ||
303 | break; | ||
304 | } | ||
305 | if (busnr >= end) { | ||
306 | err("No free bus for hot-added bridge\n"); | ||
307 | pci_dev_put(dev); | ||
308 | continue; | ||
309 | } | ||
310 | child = pci_add_new_bus(parent, dev, busnr); | ||
311 | if (!child) { | ||
312 | err("Cannot add new bus for %s\n", | ||
313 | pci_name(dev)); | ||
314 | pci_dev_put(dev); | ||
315 | continue; | ||
316 | } | ||
317 | child->subordinate = pci_do_scan_bus(child); | ||
318 | pci_bus_size_bridges(child); | ||
319 | } | ||
320 | pci_dev_put(dev); | ||
293 | } | 321 | } |
294 | 322 | ||
295 | pci_bus_assign_resources(slot->dev->bus); | 323 | pci_bus_assign_resources(parent); |
324 | pci_bus_add_devices(parent); | ||
325 | pci_enable_bridges(parent); | ||
296 | 326 | ||
297 | dbg("%s - exit", __FUNCTION__); | 327 | dbg("%s - exit", __FUNCTION__); |
298 | return 0; | 328 | return 0; |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 10e1a905c144..474e9cd0e9e4 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -139,9 +139,8 @@ const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, | |||
139 | /** | 139 | /** |
140 | * pci_match_device - Tell if a PCI device structure has a matching | 140 | * pci_match_device - Tell if a PCI device structure has a matching |
141 | * PCI device id structure | 141 | * PCI device id structure |
142 | * @ids: array of PCI device id structures to search in | ||
143 | * @dev: the PCI device structure to match against | ||
144 | * @drv: the PCI driver to match against | 142 | * @drv: the PCI driver to match against |
143 | * @dev: the PCI device structure to match against | ||
145 | * | 144 | * |
146 | * Used by a driver to check whether a PCI device present in the | 145 | * Used by a driver to check whether a PCI device present in the |
147 | * system is in its list of supported devices. Returns the matching | 146 | * system is in its list of supported devices. Returns the matching |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 2d967b460d98..b4970387a16f 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -438,6 +438,7 @@ static void __devinit quirk_ich6_lpc_acpi(struct pci_dev *dev) | |||
438 | pci_read_config_dword(dev, 0x48, ®ion); | 438 | pci_read_config_dword(dev, 0x48, ®ion); |
439 | quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1, "ICH6 GPIO"); | 439 | quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1, "ICH6 GPIO"); |
440 | } | 440 | } |
441 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0, quirk_ich6_lpc_acpi ); | ||
441 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, quirk_ich6_lpc_acpi ); | 442 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, quirk_ich6_lpc_acpi ); |
442 | 443 | ||
443 | /* | 444 | /* |
@@ -1091,7 +1092,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asu | |||
1091 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc ); | 1092 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc ); |
1092 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); | 1093 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); |
1093 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); | 1094 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); |
1094 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc ); | ||
1095 | 1095 | ||
1096 | static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev) | 1096 | static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev) |
1097 | { | 1097 | { |
@@ -1518,6 +1518,63 @@ static void __devinit quirk_netmos(struct pci_dev *dev) | |||
1518 | } | 1518 | } |
1519 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, quirk_netmos); | 1519 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, quirk_netmos); |
1520 | 1520 | ||
1521 | static void __devinit quirk_e100_interrupt(struct pci_dev *dev) | ||
1522 | { | ||
1523 | u16 command; | ||
1524 | u32 bar; | ||
1525 | u8 __iomem *csr; | ||
1526 | u8 cmd_hi; | ||
1527 | |||
1528 | switch (dev->device) { | ||
1529 | /* PCI IDs taken from drivers/net/e100.c */ | ||
1530 | case 0x1029: | ||
1531 | case 0x1030 ... 0x1034: | ||
1532 | case 0x1038 ... 0x103E: | ||
1533 | case 0x1050 ... 0x1057: | ||
1534 | case 0x1059: | ||
1535 | case 0x1064 ... 0x106B: | ||
1536 | case 0x1091 ... 0x1095: | ||
1537 | case 0x1209: | ||
1538 | case 0x1229: | ||
1539 | case 0x2449: | ||
1540 | case 0x2459: | ||
1541 | case 0x245D: | ||
1542 | case 0x27DC: | ||
1543 | break; | ||
1544 | default: | ||
1545 | return; | ||
1546 | } | ||
1547 | |||
1548 | /* | ||
1549 | * Some firmware hands off the e100 with interrupts enabled, | ||
1550 | * which can cause a flood of interrupts if packets are | ||
1551 | * received before the driver attaches to the device. So | ||
1552 | * disable all e100 interrupts here. The driver will | ||
1553 | * re-enable them when it's ready. | ||
1554 | */ | ||
1555 | pci_read_config_word(dev, PCI_COMMAND, &command); | ||
1556 | pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar); | ||
1557 | |||
1558 | if (!(command & PCI_COMMAND_MEMORY) || !bar) | ||
1559 | return; | ||
1560 | |||
1561 | csr = ioremap(bar, 8); | ||
1562 | if (!csr) { | ||
1563 | printk(KERN_WARNING "PCI: Can't map %s e100 registers\n", | ||
1564 | pci_name(dev)); | ||
1565 | return; | ||
1566 | } | ||
1567 | |||
1568 | cmd_hi = readb(csr + 3); | ||
1569 | if (cmd_hi == 0) { | ||
1570 | printk(KERN_WARNING "PCI: Firmware left %s e100 interrupts " | ||
1571 | "enabled, disabling\n", pci_name(dev)); | ||
1572 | writeb(1, csr + 3); | ||
1573 | } | ||
1574 | |||
1575 | iounmap(csr); | ||
1576 | } | ||
1577 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_e100_interrupt); | ||
1521 | 1578 | ||
1522 | static void __devinit fixup_rev1_53c810(struct pci_dev* dev) | 1579 | static void __devinit fixup_rev1_53c810(struct pci_dev* dev) |
1523 | { | 1580 | { |