aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/pci-driver.c109
-rw-r--r--drivers/pci/pci.c2
-rw-r--r--drivers/pci/pci.h1
3 files changed, 74 insertions, 38 deletions
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index bfaa77d88537..750ee79c178f 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -316,21 +316,10 @@ static void pci_device_shutdown(struct device *dev)
316 316
317/* 317/*
318 * Default "suspend" method for devices that have no driver provided suspend, 318 * Default "suspend" method for devices that have no driver provided suspend,
319 * or not even a driver at all (first part).
320 */
321static void pci_default_pm_suspend_early(struct pci_dev *pci_dev)
322{
323 /* If device is enabled at this point, disable it */
324 pci_disable_enabled_device(pci_dev);
325}
326
327/*
328 * Default "suspend" method for devices that have no driver provided suspend,
329 * or not even a driver at all (second part). 319 * or not even a driver at all (second part).
330 */ 320 */
331static void pci_default_pm_suspend_late(struct pci_dev *pci_dev) 321static void pci_default_pm_suspend_late(struct pci_dev *pci_dev)
332{ 322{
333 pci_save_state(pci_dev);
334 /* 323 /*
335 * mark its power state as "unknown", since we don't know if 324 * mark its power state as "unknown", since we don't know if
336 * e.g. the BIOS will change its device state when we suspend. 325 * e.g. the BIOS will change its device state when we suspend.
@@ -341,16 +330,6 @@ static void pci_default_pm_suspend_late(struct pci_dev *pci_dev)
341 330
342/* 331/*
343 * Default "resume" method for devices that have no driver provided resume, 332 * Default "resume" method for devices that have no driver provided resume,
344 * or not even a driver at all (first part).
345 */
346static void pci_default_pm_resume_early(struct pci_dev *pci_dev)
347{
348 /* restore the PCI config space */
349 pci_restore_state(pci_dev);
350}
351
352/*
353 * Default "resume" method for devices that have no driver provided resume,
354 * or not even a driver at all (second part). 333 * or not even a driver at all (second part).
355 */ 334 */
356static int pci_default_pm_resume_late(struct pci_dev *pci_dev) 335static int pci_default_pm_resume_late(struct pci_dev *pci_dev)
@@ -379,9 +358,10 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state)
379 i = drv->suspend(pci_dev, state); 358 i = drv->suspend(pci_dev, state);
380 suspend_report_result(drv->suspend, i); 359 suspend_report_result(drv->suspend, i);
381 } else { 360 } else {
361 pci_save_state(pci_dev);
382 /* 362 /*
383 * For compatibility with existing code with legacy PM support 363 * This is for compatibility with existing code with legacy PM
384 * don't call pci_default_pm_suspend_early() here. 364 * support.
385 */ 365 */
386 pci_default_pm_suspend_late(pci_dev); 366 pci_default_pm_suspend_late(pci_dev);
387 } 367 }
@@ -410,7 +390,8 @@ static int pci_legacy_resume(struct device *dev)
410 if (drv && drv->resume) { 390 if (drv && drv->resume) {
411 error = drv->resume(pci_dev); 391 error = drv->resume(pci_dev);
412 } else { 392 } else {
413 pci_default_pm_resume_early(pci_dev); 393 /* restore the PCI config space */
394 pci_restore_state(pci_dev);
414 error = pci_default_pm_resume_late(pci_dev); 395 error = pci_default_pm_resume_late(pci_dev);
415 } 396 }
416 return error; 397 return error;
@@ -429,22 +410,72 @@ static int pci_legacy_resume_early(struct device *dev)
429 410
430/* Auxiliary functions used by the new power management framework */ 411/* Auxiliary functions used by the new power management framework */
431 412
413static int pci_restore_standard_config(struct pci_dev *pci_dev)
414{
415 struct pci_dev *parent = pci_dev->bus->self;
416 int error = 0;
417
418 /* Check if the device's bus is operational */
419 if (!parent || parent->current_state == PCI_D0) {
420 pci_restore_state(pci_dev);
421 pci_update_current_state(pci_dev, PCI_D0);
422 } else {
423 dev_warn(&pci_dev->dev, "unable to restore config, "
424 "bridge %s in low power state D%d\n", pci_name(parent),
425 parent->current_state);
426 pci_dev->current_state = PCI_UNKNOWN;
427 error = -EAGAIN;
428 }
429
430 return error;
431}
432
432static bool pci_is_bridge(struct pci_dev *pci_dev) 433static bool pci_is_bridge(struct pci_dev *pci_dev)
433{ 434{
434 return !!(pci_dev->subordinate); 435 return !!(pci_dev->subordinate);
435} 436}
436 437
438static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev)
439{
440 if (pci_restore_standard_config(pci_dev))
441 pci_fixup_device(pci_fixup_resume_early, pci_dev);
442}
443
437static int pci_pm_default_resume(struct pci_dev *pci_dev) 444static int pci_pm_default_resume(struct pci_dev *pci_dev)
438{ 445{
446 /*
447 * pci_restore_standard_config() should have been called once already,
448 * but it would have failed if the device's parent bridge had not been
449 * in power state D0 at that time. Check it and try again if necessary.
450 */
451 if (pci_dev->current_state == PCI_UNKNOWN) {
452 int error = pci_restore_standard_config(pci_dev);
453 if (error)
454 return error;
455 }
456
457 pci_fixup_device(pci_fixup_resume, pci_dev);
458
439 if (!pci_is_bridge(pci_dev)) 459 if (!pci_is_bridge(pci_dev))
440 pci_enable_wake(pci_dev, PCI_D0, false); 460 pci_enable_wake(pci_dev, PCI_D0, false);
441 461
442 return pci_default_pm_resume_late(pci_dev); 462 return pci_default_pm_resume_late(pci_dev);
443} 463}
444 464
465static void pci_pm_default_suspend_generic(struct pci_dev *pci_dev)
466{
467 /* If device is enabled at this point, disable it */
468 pci_disable_enabled_device(pci_dev);
469 /*
470 * Save state with interrupts enabled, because in principle the bus the
471 * device is on may be put into a low power state after this code runs.
472 */
473 pci_save_state(pci_dev);
474}
475
445static void pci_pm_default_suspend(struct pci_dev *pci_dev) 476static void pci_pm_default_suspend(struct pci_dev *pci_dev)
446{ 477{
447 pci_default_pm_suspend_early(pci_dev); 478 pci_pm_default_suspend_generic(pci_dev);
448 479
449 if (!pci_is_bridge(pci_dev)) 480 if (!pci_is_bridge(pci_dev))
450 pci_prepare_to_sleep(pci_dev); 481 pci_prepare_to_sleep(pci_dev);
@@ -529,12 +560,13 @@ static int pci_pm_resume(struct device *dev)
529 struct device_driver *drv = dev->driver; 560 struct device_driver *drv = dev->driver;
530 int error = 0; 561 int error = 0;
531 562
532 pci_fixup_device(pci_fixup_resume, pci_dev);
533
534 if (drv && drv->pm) { 563 if (drv && drv->pm) {
564 pci_fixup_device(pci_fixup_resume, pci_dev);
565
535 if (drv->pm->resume) 566 if (drv->pm->resume)
536 error = drv->pm->resume(dev); 567 error = drv->pm->resume(dev);
537 } else if (pci_has_legacy_pm_support(pci_dev)) { 568 } else if (pci_has_legacy_pm_support(pci_dev)) {
569 pci_fixup_device(pci_fixup_resume, pci_dev);
538 error = pci_legacy_resume(dev); 570 error = pci_legacy_resume(dev);
539 } else { 571 } else {
540 error = pci_pm_default_resume(pci_dev); 572 error = pci_pm_default_resume(pci_dev);
@@ -549,15 +581,16 @@ static int pci_pm_resume_noirq(struct device *dev)
549 struct device_driver *drv = dev->driver; 581 struct device_driver *drv = dev->driver;
550 int error = 0; 582 int error = 0;
551 583
552 pci_fixup_device(pci_fixup_resume_early, to_pci_dev(dev));
553
554 if (drv && drv->pm) { 584 if (drv && drv->pm) {
585 pci_fixup_device(pci_fixup_resume_early, pci_dev);
586
555 if (drv->pm->resume_noirq) 587 if (drv->pm->resume_noirq)
556 error = drv->pm->resume_noirq(dev); 588 error = drv->pm->resume_noirq(dev);
557 } else if (pci_has_legacy_pm_support(pci_dev)) { 589 } else if (pci_has_legacy_pm_support(pci_dev)) {
590 pci_fixup_device(pci_fixup_resume_early, pci_dev);
558 error = pci_legacy_resume_early(dev); 591 error = pci_legacy_resume_early(dev);
559 } else { 592 } else {
560 pci_default_pm_resume_early(pci_dev); 593 pci_pm_default_resume_noirq(pci_dev);
561 } 594 }
562 595
563 return error; 596 return error;
@@ -589,7 +622,7 @@ static int pci_pm_freeze(struct device *dev)
589 error = pci_legacy_suspend(dev, PMSG_FREEZE); 622 error = pci_legacy_suspend(dev, PMSG_FREEZE);
590 pci_fixup_device(pci_fixup_suspend, pci_dev); 623 pci_fixup_device(pci_fixup_suspend, pci_dev);
591 } else { 624 } else {
592 pci_default_pm_suspend_early(pci_dev); 625 pci_pm_default_suspend_generic(pci_dev);
593 } 626 }
594 627
595 return error; 628 return error;
@@ -647,7 +680,7 @@ static int pci_pm_thaw_noirq(struct device *dev)
647 pci_fixup_device(pci_fixup_resume_early, to_pci_dev(dev)); 680 pci_fixup_device(pci_fixup_resume_early, to_pci_dev(dev));
648 error = pci_legacy_resume_early(dev); 681 error = pci_legacy_resume_early(dev);
649 } else { 682 } else {
650 pci_default_pm_resume_early(pci_dev); 683 pci_update_current_state(pci_dev, PCI_D0);
651 } 684 }
652 685
653 return error; 686 return error;
@@ -698,12 +731,13 @@ static int pci_pm_restore(struct device *dev)
698 struct device_driver *drv = dev->driver; 731 struct device_driver *drv = dev->driver;
699 int error = 0; 732 int error = 0;
700 733
701 pci_fixup_device(pci_fixup_resume, pci_dev);
702
703 if (drv && drv->pm) { 734 if (drv && drv->pm) {
735 pci_fixup_device(pci_fixup_resume, pci_dev);
736
704 if (drv->pm->restore) 737 if (drv->pm->restore)
705 error = drv->pm->restore(dev); 738 error = drv->pm->restore(dev);
706 } else if (pci_has_legacy_pm_support(pci_dev)) { 739 } else if (pci_has_legacy_pm_support(pci_dev)) {
740 pci_fixup_device(pci_fixup_resume, pci_dev);
707 error = pci_legacy_resume(dev); 741 error = pci_legacy_resume(dev);
708 } else { 742 } else {
709 error = pci_pm_default_resume(pci_dev); 743 error = pci_pm_default_resume(pci_dev);
@@ -718,15 +752,16 @@ static int pci_pm_restore_noirq(struct device *dev)
718 struct device_driver *drv = dev->driver; 752 struct device_driver *drv = dev->driver;
719 int error = 0; 753 int error = 0;
720 754
721 pci_fixup_device(pci_fixup_resume_early, pci_dev);
722
723 if (drv && drv->pm) { 755 if (drv && drv->pm) {
756 pci_fixup_device(pci_fixup_resume_early, pci_dev);
757
724 if (drv->pm->restore_noirq) 758 if (drv->pm->restore_noirq)
725 error = drv->pm->restore_noirq(dev); 759 error = drv->pm->restore_noirq(dev);
726 } else if (pci_has_legacy_pm_support(pci_dev)) { 760 } else if (pci_has_legacy_pm_support(pci_dev)) {
761 pci_fixup_device(pci_fixup_resume_early, pci_dev);
727 error = pci_legacy_resume_early(dev); 762 error = pci_legacy_resume_early(dev);
728 } else { 763 } else {
729 pci_default_pm_resume_early(pci_dev); 764 pci_pm_default_resume_noirq(pci_dev);
730 } 765 }
731 766
732 return error; 767 return error;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 6e309c8b47df..e491fdedf705 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -527,7 +527,7 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
527 * @dev: PCI device to handle. 527 * @dev: PCI device to handle.
528 * @state: State to cache in case the device doesn't have the PM capability 528 * @state: State to cache in case the device doesn't have the PM capability
529 */ 529 */
530static void pci_update_current_state(struct pci_dev *dev, pci_power_t state) 530void pci_update_current_state(struct pci_dev *dev, pci_power_t state)
531{ 531{
532 if (dev->pm_cap) { 532 if (dev->pm_cap) {
533 u16 pmcsr; 533 u16 pmcsr;
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 881dc15f8efd..1351bb4addde 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -44,6 +44,7 @@ struct pci_platform_pm_ops {
44}; 44};
45 45
46extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops); 46extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops);
47extern void pci_update_current_state(struct pci_dev *dev, pci_power_t state);
47extern void pci_disable_enabled_device(struct pci_dev *dev); 48extern void pci_disable_enabled_device(struct pci_dev *dev);
48extern void pci_pm_init(struct pci_dev *dev); 49extern void pci_pm_init(struct pci_dev *dev);
49extern void platform_pci_wakeup_init(struct pci_dev *dev); 50extern void platform_pci_wakeup_init(struct pci_dev *dev);