aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-02-02 22:28:58 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-02-02 22:28:58 -0500
commitb1792e367053968f2ddb48bc911d314143ce6242 (patch)
tree31ac3fddb0b14a202e9ceaa9681c1335ba35210c /drivers
parent859281ff370977f917ec2195f86a5bfccf1fc6d6 (diff)
parent71a082efc9fdc12068a3cee6cebb1330b00ebeee (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6: PCI hotplug: Change link order of pciehp & acpiphp PCI hotplug: fakephp: Allocate PCI resources before adding the device PCI MSI: Fix undefined shift by 32 PCI PM: Do not wait for buses in B2 or B3 during resume PCI PM: Power up devices before restoring their state PCI PM: Fix hibernation breakage on EeePC 701 PCI: irq and pci_ids patch for Intel Tigerpoint DeviceIDs PCI PM: Fix suspend error paths and testing facility breakage
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pci/hotplug/Makefile6
-rw-r--r--drivers/pci/hotplug/fakephp.c42
-rw-r--r--drivers/pci/msi.c13
-rw-r--r--drivers/pci/pci-driver.c21
-rw-r--r--drivers/pci/pci.c32
5 files changed, 78 insertions, 36 deletions
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile
index e31fb91652ce..2aa117c8cd87 100644
--- a/drivers/pci/hotplug/Makefile
+++ b/drivers/pci/hotplug/Makefile
@@ -5,11 +5,15 @@
5obj-$(CONFIG_HOTPLUG_PCI) += pci_hotplug.o 5obj-$(CONFIG_HOTPLUG_PCI) += pci_hotplug.o
6obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o 6obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o
7obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o 7obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o
8
9# pciehp should be linked before acpiphp in order to allow the native driver
10# to attempt to bind first. We can then fall back to generic support.
11
12obj-$(CONFIG_HOTPLUG_PCI_PCIE) += pciehp.o
8obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o 13obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o
9obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o 14obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o
10obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550) += cpcihp_zt5550.o 15obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550) += cpcihp_zt5550.o
11obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC) += cpcihp_generic.o 16obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC) += cpcihp_generic.o
12obj-$(CONFIG_HOTPLUG_PCI_PCIE) += pciehp.o
13obj-$(CONFIG_HOTPLUG_PCI_SHPC) += shpchp.o 17obj-$(CONFIG_HOTPLUG_PCI_SHPC) += shpchp.o
14obj-$(CONFIG_HOTPLUG_PCI_RPA) += rpaphp.o 18obj-$(CONFIG_HOTPLUG_PCI_RPA) += rpaphp.o
15obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o 19obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c
index b0e7de9e536d..d8649e127298 100644
--- a/drivers/pci/hotplug/fakephp.c
+++ b/drivers/pci/hotplug/fakephp.c
@@ -195,13 +195,13 @@ static void remove_slot_worker(struct work_struct *work)
195 * Tries hard not to re-enable already existing devices; 195 * Tries hard not to re-enable already existing devices;
196 * also handles scanning of subfunctions. 196 * also handles scanning of subfunctions.
197 */ 197 */
198static void pci_rescan_slot(struct pci_dev *temp) 198static int pci_rescan_slot(struct pci_dev *temp)
199{ 199{
200 struct pci_bus *bus = temp->bus; 200 struct pci_bus *bus = temp->bus;
201 struct pci_dev *dev; 201 struct pci_dev *dev;
202 int func; 202 int func;
203 int retval;
204 u8 hdr_type; 203 u8 hdr_type;
204 int count = 0;
205 205
206 if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) { 206 if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) {
207 temp->hdr_type = hdr_type & 0x7f; 207 temp->hdr_type = hdr_type & 0x7f;
@@ -213,17 +213,12 @@ static void pci_rescan_slot(struct pci_dev *temp)
213 dbg("New device on %s function %x:%x\n", 213 dbg("New device on %s function %x:%x\n",
214 bus->name, temp->devfn >> 3, 214 bus->name, temp->devfn >> 3,
215 temp->devfn & 7); 215 temp->devfn & 7);
216 retval = pci_bus_add_device(dev); 216 count++;
217 if (retval)
218 dev_err(&dev->dev, "error adding "
219 "device, continuing.\n");
220 else
221 add_slot(dev);
222 } 217 }
223 } 218 }
224 /* multifunction device? */ 219 /* multifunction device? */
225 if (!(hdr_type & 0x80)) 220 if (!(hdr_type & 0x80))
226 return; 221 return count;
227 222
228 /* continue scanning for other functions */ 223 /* continue scanning for other functions */
229 for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) { 224 for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) {
@@ -239,16 +234,13 @@ static void pci_rescan_slot(struct pci_dev *temp)
239 dbg("New device on %s function %x:%x\n", 234 dbg("New device on %s function %x:%x\n",
240 bus->name, temp->devfn >> 3, 235 bus->name, temp->devfn >> 3,
241 temp->devfn & 7); 236 temp->devfn & 7);
242 retval = pci_bus_add_device(dev); 237 count++;
243 if (retval)
244 dev_err(&dev->dev, "error adding "
245 "device, continuing.\n");
246 else
247 add_slot(dev);
248 } 238 }
249 } 239 }
250 } 240 }
251 } 241 }
242
243 return count;
252} 244}
253 245
254 246
@@ -262,6 +254,8 @@ static void pci_rescan_bus(const struct pci_bus *bus)
262{ 254{
263 unsigned int devfn; 255 unsigned int devfn;
264 struct pci_dev *dev; 256 struct pci_dev *dev;
257 int retval;
258 int found = 0;
265 dev = alloc_pci_dev(); 259 dev = alloc_pci_dev();
266 if (!dev) 260 if (!dev)
267 return; 261 return;
@@ -270,7 +264,23 @@ static void pci_rescan_bus(const struct pci_bus *bus)
270 dev->sysdata = bus->sysdata; 264 dev->sysdata = bus->sysdata;
271 for (devfn = 0; devfn < 0x100; devfn += 8) { 265 for (devfn = 0; devfn < 0x100; devfn += 8) {
272 dev->devfn = devfn; 266 dev->devfn = devfn;
273 pci_rescan_slot(dev); 267 found += pci_rescan_slot(dev);
268 }
269
270 if (found) {
271 pci_bus_assign_resources(bus);
272 list_for_each_entry(dev, &bus->devices, bus_list) {
273 /* Skip already-added devices */
274 if (dev->is_added)
275 continue;
276 retval = pci_bus_add_device(dev);
277 if (retval)
278 dev_err(&dev->dev,
279 "Error adding device, continuing\n");
280 else
281 add_slot(dev);
282 }
283 pci_bus_add_devices(bus);
274 } 284 }
275 kfree(dev); 285 kfree(dev);
276} 286}
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 896a15d70f5b..44f15ff70c1d 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -103,6 +103,16 @@ static void msix_set_enable(struct pci_dev *dev, int enable)
103 } 103 }
104} 104}
105 105
106/*
107 * Essentially, this is ((1 << (1 << x)) - 1), but without the
108 * undefinedness of a << 32.
109 */
110static inline __attribute_const__ u32 msi_mask(unsigned x)
111{
112 static const u32 mask[] = { 1, 2, 4, 0xf, 0xff, 0xffff, 0xffffffff };
113 return mask[x];
114}
115
106static void msix_flush_writes(struct irq_desc *desc) 116static void msix_flush_writes(struct irq_desc *desc)
107{ 117{
108 struct msi_desc *entry; 118 struct msi_desc *entry;
@@ -407,8 +417,7 @@ static int msi_capability_init(struct pci_dev *dev)
407 417
408 /* All MSIs are unmasked by default, Mask them all */ 418 /* All MSIs are unmasked by default, Mask them all */
409 pci_read_config_dword(dev, base, &maskbits); 419 pci_read_config_dword(dev, base, &maskbits);
410 temp = (1 << multi_msi_capable(control)); 420 temp = msi_mask((control & PCI_MSI_FLAGS_QMASK) >> 1);
411 temp = ((temp - 1) & ~temp);
412 maskbits |= temp; 421 maskbits |= temp;
413 pci_write_config_dword(dev, base, maskbits); 422 pci_write_config_dword(dev, base, maskbits);
414 entry->msi_attrib.maskbits_mask = temp; 423 entry->msi_attrib.maskbits_mask = temp;
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 9de07b75b993..ab1d615425a8 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -370,6 +370,7 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state)
370 } 370 }
371 371
372 pci_save_state(pci_dev); 372 pci_save_state(pci_dev);
373 pci_dev->state_saved = true;
373 /* 374 /*
374 * This is for compatibility with existing code with legacy PM support. 375 * This is for compatibility with existing code with legacy PM support.
375 */ 376 */
@@ -419,6 +420,7 @@ static int pci_legacy_resume(struct device *dev)
419static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev) 420static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev)
420{ 421{
421 pci_restore_standard_config(pci_dev); 422 pci_restore_standard_config(pci_dev);
423 pci_dev->state_saved = false;
422 pci_fixup_device(pci_fixup_resume_early, pci_dev); 424 pci_fixup_device(pci_fixup_resume_early, pci_dev);
423} 425}
424 426
@@ -555,6 +557,13 @@ static int pci_pm_resume(struct device *dev)
555 struct device_driver *drv = dev->driver; 557 struct device_driver *drv = dev->driver;
556 int error = 0; 558 int error = 0;
557 559
560 /*
561 * This is necessary for the suspend error path in which resume is
562 * called without restoring the standard config registers of the device.
563 */
564 if (pci_dev->state_saved)
565 pci_restore_standard_config(pci_dev);
566
558 if (pci_has_legacy_pm_support(pci_dev)) 567 if (pci_has_legacy_pm_support(pci_dev))
559 return pci_legacy_resume(dev); 568 return pci_legacy_resume(dev);
560 569
@@ -660,7 +669,10 @@ static int pci_pm_poweroff(struct device *dev)
660 if (pci_has_legacy_pm_support(pci_dev)) 669 if (pci_has_legacy_pm_support(pci_dev))
661 return pci_legacy_suspend(dev, PMSG_HIBERNATE); 670 return pci_legacy_suspend(dev, PMSG_HIBERNATE);
662 671
663 if (drv && drv->pm && drv->pm->poweroff) { 672 if (!drv || !drv->pm)
673 return 0;
674
675 if (drv->pm->poweroff) {
664 error = drv->pm->poweroff(dev); 676 error = drv->pm->poweroff(dev);
665 suspend_report_result(drv->pm->poweroff, error); 677 suspend_report_result(drv->pm->poweroff, error);
666 } 678 }
@@ -710,6 +722,13 @@ static int pci_pm_restore(struct device *dev)
710 struct device_driver *drv = dev->driver; 722 struct device_driver *drv = dev->driver;
711 int error = 0; 723 int error = 0;
712 724
725 /*
726 * This is necessary for the hibernation error path in which restore is
727 * called without restoring the standard config registers of the device.
728 */
729 if (pci_dev->state_saved)
730 pci_restore_standard_config(pci_dev);
731
713 if (pci_has_legacy_pm_support(pci_dev)) 732 if (pci_has_legacy_pm_support(pci_dev))
714 return pci_legacy_resume(dev); 733 return pci_legacy_resume(dev);
715 734
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 17bd9325a245..48807556b47a 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1393,35 +1393,35 @@ int pci_restore_standard_config(struct pci_dev *dev)
1393 pci_power_t prev_state; 1393 pci_power_t prev_state;
1394 int error; 1394 int error;
1395 1395
1396 pci_restore_state(dev);
1397 pci_update_current_state(dev, PCI_D0); 1396 pci_update_current_state(dev, PCI_D0);
1398 1397
1399 prev_state = dev->current_state; 1398 prev_state = dev->current_state;
1400 if (prev_state == PCI_D0) 1399 if (prev_state == PCI_D0)
1401 return 0; 1400 goto Restore;
1402 1401
1403 error = pci_raw_set_power_state(dev, PCI_D0, false); 1402 error = pci_raw_set_power_state(dev, PCI_D0, false);
1404 if (error) 1403 if (error)
1405 return error; 1404 return error;
1406 1405
1407 if (pci_is_bridge(dev)) { 1406 /*
1408 if (prev_state > PCI_D1) 1407 * This assumes that we won't get a bus in B2 or B3 from the BIOS, but
1409 mdelay(PCI_PM_BUS_WAIT); 1408 * we've made this assumption forever and it appears to be universally
1410 } else { 1409 * satisfied.
1411 switch(prev_state) { 1410 */
1412 case PCI_D3cold: 1411 switch(prev_state) {
1413 case PCI_D3hot: 1412 case PCI_D3cold:
1414 mdelay(pci_pm_d3_delay); 1413 case PCI_D3hot:
1415 break; 1414 mdelay(pci_pm_d3_delay);
1416 case PCI_D2: 1415 break;
1417 udelay(PCI_PM_D2_DELAY); 1416 case PCI_D2:
1418 break; 1417 udelay(PCI_PM_D2_DELAY);
1419 } 1418 break;
1420 } 1419 }
1421 1420
1422 dev->current_state = PCI_D0; 1421 dev->current_state = PCI_D0;
1423 1422
1424 return 0; 1423 Restore:
1424 return pci_restore_state(dev);
1425} 1425}
1426 1426
1427/** 1427/**