aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci-driver.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-02-11 03:22:04 -0500
committerIngo Molnar <mingo@elte.hu>2009-02-11 03:22:04 -0500
commit95fd4845ed0ffcab305b4f30ce1c12dc34f1b56c (patch)
treeaa2aac22a5b329b778a6771a87bbf1945ad49bbd /drivers/pci/pci-driver.c
parentd278c48435625cb6b7edcf6a547620768b175709 (diff)
parent8e4921515c1a379539607eb443d51c30f4f7f338 (diff)
Merge commit 'v2.6.29-rc4' into perfcounters/core
Conflicts: arch/x86/kernel/setup_percpu.c arch/x86/mm/fault.c drivers/acpi/processor_idle.c kernel/irq/handle.c
Diffstat (limited to 'drivers/pci/pci-driver.c')
-rw-r--r--drivers/pci/pci-driver.c266
1 files changed, 147 insertions, 119 deletions
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index c697f2680856..93eac1423585 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -355,17 +355,34 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state)
355 int i = 0; 355 int i = 0;
356 356
357 if (drv && drv->suspend) { 357 if (drv && drv->suspend) {
358 pci_power_t prev = pci_dev->current_state;
359
360 pci_dev->state_saved = false;
361
358 i = drv->suspend(pci_dev, state); 362 i = drv->suspend(pci_dev, state);
359 suspend_report_result(drv->suspend, i); 363 suspend_report_result(drv->suspend, i);
360 } else { 364 if (i)
361 pci_save_state(pci_dev); 365 return i;
362 /* 366
363 * This is for compatibility with existing code with legacy PM 367 if (pci_dev->state_saved)
364 * support. 368 goto Fixup;
365 */ 369
366 pci_pm_set_unknown_state(pci_dev); 370 if (pci_dev->current_state != PCI_D0
371 && pci_dev->current_state != PCI_UNKNOWN) {
372 WARN_ONCE(pci_dev->current_state != prev,
373 "PCI PM: Device state not saved by %pF\n",
374 drv->suspend);
375 goto Fixup;
376 }
367 } 377 }
368 378
379 pci_save_state(pci_dev);
380 /*
381 * This is for compatibility with existing code with legacy PM support.
382 */
383 pci_pm_set_unknown_state(pci_dev);
384
385 Fixup:
369 pci_fixup_device(pci_fixup_suspend, pci_dev); 386 pci_fixup_device(pci_fixup_suspend, pci_dev);
370 387
371 return i; 388 return i;
@@ -386,108 +403,47 @@ static int pci_legacy_suspend_late(struct device *dev, pm_message_t state)
386 403
387static int pci_legacy_resume_early(struct device *dev) 404static int pci_legacy_resume_early(struct device *dev)
388{ 405{
389 int error = 0;
390 struct pci_dev * pci_dev = to_pci_dev(dev); 406 struct pci_dev * pci_dev = to_pci_dev(dev);
391 struct pci_driver * drv = pci_dev->driver; 407 struct pci_driver * drv = pci_dev->driver;
392 408
393 pci_fixup_device(pci_fixup_resume_early, pci_dev); 409 return drv && drv->resume_early ?
394 410 drv->resume_early(pci_dev) : 0;
395 if (drv && drv->resume_early)
396 error = drv->resume_early(pci_dev);
397 return error;
398} 411}
399 412
400static int pci_legacy_resume(struct device *dev) 413static int pci_legacy_resume(struct device *dev)
401{ 414{
402 int error;
403 struct pci_dev * pci_dev = to_pci_dev(dev); 415 struct pci_dev * pci_dev = to_pci_dev(dev);
404 struct pci_driver * drv = pci_dev->driver; 416 struct pci_driver * drv = pci_dev->driver;
405 417
406 pci_fixup_device(pci_fixup_resume, pci_dev); 418 pci_fixup_device(pci_fixup_resume, pci_dev);
407 419
408 if (drv && drv->resume) { 420 return drv && drv->resume ?
409 error = drv->resume(pci_dev); 421 drv->resume(pci_dev) : pci_pm_reenable_device(pci_dev);
410 } else {
411 /* restore the PCI config space */
412 pci_restore_state(pci_dev);
413 error = pci_pm_reenable_device(pci_dev);
414 }
415 return error;
416} 422}
417 423
418/* Auxiliary functions used by the new power management framework */ 424/* Auxiliary functions used by the new power management framework */
419 425
420static int pci_restore_standard_config(struct pci_dev *pci_dev)
421{
422 struct pci_dev *parent = pci_dev->bus->self;
423 int error = 0;
424
425 /* Check if the device's bus is operational */
426 if (!parent || parent->current_state == PCI_D0) {
427 pci_restore_state(pci_dev);
428 pci_update_current_state(pci_dev, PCI_D0);
429 } else {
430 dev_warn(&pci_dev->dev, "unable to restore config, "
431 "bridge %s in low power state D%d\n", pci_name(parent),
432 parent->current_state);
433 pci_dev->current_state = PCI_UNKNOWN;
434 error = -EAGAIN;
435 }
436
437 return error;
438}
439
440static bool pci_is_bridge(struct pci_dev *pci_dev)
441{
442 return !!(pci_dev->subordinate);
443}
444
445static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev) 426static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev)
446{ 427{
447 if (pci_restore_standard_config(pci_dev)) 428 pci_restore_standard_config(pci_dev);
448 pci_fixup_device(pci_fixup_resume_early, pci_dev); 429 pci_dev->state_saved = false;
430 pci_fixup_device(pci_fixup_resume_early, pci_dev);
449} 431}
450 432
451static int pci_pm_default_resume(struct pci_dev *pci_dev) 433static void pci_pm_default_resume(struct pci_dev *pci_dev)
452{ 434{
453 /*
454 * pci_restore_standard_config() should have been called once already,
455 * but it would have failed if the device's parent bridge had not been
456 * in power state D0 at that time. Check it and try again if necessary.
457 */
458 if (pci_dev->current_state == PCI_UNKNOWN) {
459 int error = pci_restore_standard_config(pci_dev);
460 if (error)
461 return error;
462 }
463
464 pci_fixup_device(pci_fixup_resume, pci_dev); 435 pci_fixup_device(pci_fixup_resume, pci_dev);
465 436
466 if (!pci_is_bridge(pci_dev)) 437 if (!pci_is_bridge(pci_dev))
467 pci_enable_wake(pci_dev, PCI_D0, false); 438 pci_enable_wake(pci_dev, PCI_D0, false);
468
469 return pci_pm_reenable_device(pci_dev);
470}
471
472static void pci_pm_default_suspend_generic(struct pci_dev *pci_dev)
473{
474 /* If device is enabled at this point, disable it */
475 pci_disable_enabled_device(pci_dev);
476 /*
477 * Save state with interrupts enabled, because in principle the bus the
478 * device is on may be put into a low power state after this code runs.
479 */
480 pci_save_state(pci_dev);
481} 439}
482 440
483static void pci_pm_default_suspend(struct pci_dev *pci_dev) 441static void pci_pm_default_suspend(struct pci_dev *pci_dev)
484{ 442{
485 pci_pm_default_suspend_generic(pci_dev); 443 /* Disable non-bridge devices without PM support */
486
487 if (!pci_is_bridge(pci_dev)) 444 if (!pci_is_bridge(pci_dev))
488 pci_prepare_to_sleep(pci_dev); 445 pci_disable_enabled_device(pci_dev);
489 446 pci_save_state(pci_dev);
490 pci_fixup_device(pci_fixup_suspend, pci_dev);
491} 447}
492 448
493static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev) 449static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev)
@@ -532,21 +488,49 @@ static void pci_pm_complete(struct device *dev)
532static int pci_pm_suspend(struct device *dev) 488static int pci_pm_suspend(struct device *dev)
533{ 489{
534 struct pci_dev *pci_dev = to_pci_dev(dev); 490 struct pci_dev *pci_dev = to_pci_dev(dev);
535 struct device_driver *drv = dev->driver; 491 struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
536 int error = 0;
537 492
538 if (pci_has_legacy_pm_support(pci_dev)) 493 if (pci_has_legacy_pm_support(pci_dev))
539 return pci_legacy_suspend(dev, PMSG_SUSPEND); 494 return pci_legacy_suspend(dev, PMSG_SUSPEND);
540 495
541 if (drv && drv->pm && drv->pm->suspend) { 496 if (!pm) {
542 error = drv->pm->suspend(dev); 497 pci_pm_default_suspend(pci_dev);
543 suspend_report_result(drv->pm->suspend, error); 498 goto Fixup;
544 } 499 }
545 500
546 if (!error) 501 pci_dev->state_saved = false;
547 pci_pm_default_suspend(pci_dev);
548 502
549 return error; 503 if (pm->suspend) {
504 pci_power_t prev = pci_dev->current_state;
505 int error;
506
507 error = pm->suspend(dev);
508 suspend_report_result(pm->suspend, error);
509 if (error)
510 return error;
511
512 if (pci_dev->state_saved)
513 goto Fixup;
514
515 if (pci_dev->current_state != PCI_D0
516 && pci_dev->current_state != PCI_UNKNOWN) {
517 WARN_ONCE(pci_dev->current_state != prev,
518 "PCI PM: State of device not saved by %pF\n",
519 pm->suspend);
520 goto Fixup;
521 }
522 }
523
524 if (!pci_dev->state_saved) {
525 pci_save_state(pci_dev);
526 if (!pci_is_bridge(pci_dev))
527 pci_prepare_to_sleep(pci_dev);
528 }
529
530 Fixup:
531 pci_fixup_device(pci_fixup_suspend, pci_dev);
532
533 return 0;
550} 534}
551 535
552static int pci_pm_suspend_noirq(struct device *dev) 536static int pci_pm_suspend_noirq(struct device *dev)
@@ -575,11 +559,11 @@ static int pci_pm_resume_noirq(struct device *dev)
575 struct device_driver *drv = dev->driver; 559 struct device_driver *drv = dev->driver;
576 int error = 0; 560 int error = 0;
577 561
562 pci_pm_default_resume_noirq(pci_dev);
563
578 if (pci_has_legacy_pm_support(pci_dev)) 564 if (pci_has_legacy_pm_support(pci_dev))
579 return pci_legacy_resume_early(dev); 565 return pci_legacy_resume_early(dev);
580 566
581 pci_pm_default_resume_noirq(pci_dev);
582
583 if (drv && drv->pm && drv->pm->resume_noirq) 567 if (drv && drv->pm && drv->pm->resume_noirq)
584 error = drv->pm->resume_noirq(dev); 568 error = drv->pm->resume_noirq(dev);
585 569
@@ -589,18 +573,29 @@ static int pci_pm_resume_noirq(struct device *dev)
589static int pci_pm_resume(struct device *dev) 573static int pci_pm_resume(struct device *dev)
590{ 574{
591 struct pci_dev *pci_dev = to_pci_dev(dev); 575 struct pci_dev *pci_dev = to_pci_dev(dev);
592 struct device_driver *drv = dev->driver; 576 struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
593 int error = 0; 577 int error = 0;
594 578
579 /*
580 * This is necessary for the suspend error path in which resume is
581 * called without restoring the standard config registers of the device.
582 */
583 if (pci_dev->state_saved)
584 pci_restore_standard_config(pci_dev);
585
595 if (pci_has_legacy_pm_support(pci_dev)) 586 if (pci_has_legacy_pm_support(pci_dev))
596 return pci_legacy_resume(dev); 587 return pci_legacy_resume(dev);
597 588
598 error = pci_pm_default_resume(pci_dev); 589 pci_pm_default_resume(pci_dev);
599 590
600 if (!error && drv && drv->pm && drv->pm->resume) 591 if (pm) {
601 error = drv->pm->resume(dev); 592 if (pm->resume)
593 error = pm->resume(dev);
594 } else {
595 pci_pm_reenable_device(pci_dev);
596 }
602 597
603 return error; 598 return 0;
604} 599}
605 600
606#else /* !CONFIG_SUSPEND */ 601#else /* !CONFIG_SUSPEND */
@@ -617,21 +612,31 @@ static int pci_pm_resume(struct device *dev)
617static int pci_pm_freeze(struct device *dev) 612static int pci_pm_freeze(struct device *dev)
618{ 613{
619 struct pci_dev *pci_dev = to_pci_dev(dev); 614 struct pci_dev *pci_dev = to_pci_dev(dev);
620 struct device_driver *drv = dev->driver; 615 struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
621 int error = 0;
622 616
623 if (pci_has_legacy_pm_support(pci_dev)) 617 if (pci_has_legacy_pm_support(pci_dev))
624 return pci_legacy_suspend(dev, PMSG_FREEZE); 618 return pci_legacy_suspend(dev, PMSG_FREEZE);
625 619
626 if (drv && drv->pm && drv->pm->freeze) { 620 if (!pm) {
627 error = drv->pm->freeze(dev); 621 pci_pm_default_suspend(pci_dev);
628 suspend_report_result(drv->pm->freeze, error); 622 return 0;
629 } 623 }
630 624
631 if (!error) 625 pci_dev->state_saved = false;
632 pci_pm_default_suspend_generic(pci_dev);
633 626
634 return error; 627 if (pm->freeze) {
628 int error;
629
630 error = pm->freeze(dev);
631 suspend_report_result(pm->freeze, error);
632 if (error)
633 return error;
634 }
635
636 if (!pci_dev->state_saved)
637 pci_save_state(pci_dev);
638
639 return 0;
635} 640}
636 641
637static int pci_pm_freeze_noirq(struct device *dev) 642static int pci_pm_freeze_noirq(struct device *dev)
@@ -674,16 +679,18 @@ static int pci_pm_thaw_noirq(struct device *dev)
674static int pci_pm_thaw(struct device *dev) 679static int pci_pm_thaw(struct device *dev)
675{ 680{
676 struct pci_dev *pci_dev = to_pci_dev(dev); 681 struct pci_dev *pci_dev = to_pci_dev(dev);
677 struct device_driver *drv = dev->driver; 682 struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
678 int error = 0; 683 int error = 0;
679 684
680 if (pci_has_legacy_pm_support(pci_dev)) 685 if (pci_has_legacy_pm_support(pci_dev))
681 return pci_legacy_resume(dev); 686 return pci_legacy_resume(dev);
682 687
683 pci_pm_reenable_device(pci_dev); 688 if (pm) {
684 689 if (pm->thaw)
685 if (drv && drv->pm && drv->pm->thaw) 690 error = pm->thaw(dev);
686 error = drv->pm->thaw(dev); 691 } else {
692 pci_pm_reenable_device(pci_dev);
693 }
687 694
688 return error; 695 return error;
689} 696}
@@ -691,19 +698,29 @@ static int pci_pm_thaw(struct device *dev)
691static int pci_pm_poweroff(struct device *dev) 698static int pci_pm_poweroff(struct device *dev)
692{ 699{
693 struct pci_dev *pci_dev = to_pci_dev(dev); 700 struct pci_dev *pci_dev = to_pci_dev(dev);
694 struct device_driver *drv = dev->driver; 701 struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
695 int error = 0; 702 int error = 0;
696 703
697 if (pci_has_legacy_pm_support(pci_dev)) 704 if (pci_has_legacy_pm_support(pci_dev))
698 return pci_legacy_suspend(dev, PMSG_HIBERNATE); 705 return pci_legacy_suspend(dev, PMSG_HIBERNATE);
699 706
700 if (drv && drv->pm && drv->pm->poweroff) { 707 if (!pm) {
701 error = drv->pm->poweroff(dev); 708 pci_pm_default_suspend(pci_dev);
702 suspend_report_result(drv->pm->poweroff, error); 709 goto Fixup;
703 } 710 }
704 711
705 if (!error) 712 pci_dev->state_saved = false;
706 pci_pm_default_suspend(pci_dev); 713
714 if (pm->poweroff) {
715 error = pm->poweroff(dev);
716 suspend_report_result(pm->poweroff, error);
717 }
718
719 if (!pci_dev->state_saved && !pci_is_bridge(pci_dev))
720 pci_prepare_to_sleep(pci_dev);
721
722 Fixup:
723 pci_fixup_device(pci_fixup_suspend, pci_dev);
707 724
708 return error; 725 return error;
709} 726}
@@ -730,11 +747,11 @@ static int pci_pm_restore_noirq(struct device *dev)
730 struct device_driver *drv = dev->driver; 747 struct device_driver *drv = dev->driver;
731 int error = 0; 748 int error = 0;
732 749
750 pci_pm_default_resume_noirq(pci_dev);
751
733 if (pci_has_legacy_pm_support(pci_dev)) 752 if (pci_has_legacy_pm_support(pci_dev))
734 return pci_legacy_resume_early(dev); 753 return pci_legacy_resume_early(dev);
735 754
736 pci_pm_default_resume_noirq(pci_dev);
737
738 if (drv && drv->pm && drv->pm->restore_noirq) 755 if (drv && drv->pm && drv->pm->restore_noirq)
739 error = drv->pm->restore_noirq(dev); 756 error = drv->pm->restore_noirq(dev);
740 757
@@ -744,16 +761,27 @@ static int pci_pm_restore_noirq(struct device *dev)
744static int pci_pm_restore(struct device *dev) 761static int pci_pm_restore(struct device *dev)
745{ 762{
746 struct pci_dev *pci_dev = to_pci_dev(dev); 763 struct pci_dev *pci_dev = to_pci_dev(dev);
747 struct device_driver *drv = dev->driver; 764 struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
748 int error = 0; 765 int error = 0;
749 766
767 /*
768 * This is necessary for the hibernation error path in which restore is
769 * called without restoring the standard config registers of the device.
770 */
771 if (pci_dev->state_saved)
772 pci_restore_standard_config(pci_dev);
773
750 if (pci_has_legacy_pm_support(pci_dev)) 774 if (pci_has_legacy_pm_support(pci_dev))
751 return pci_legacy_resume(dev); 775 return pci_legacy_resume(dev);
752 776
753 error = pci_pm_default_resume(pci_dev); 777 pci_pm_default_resume(pci_dev);
754 778
755 if (!error && drv && drv->pm && drv->pm->restore) 779 if (pm) {
756 error = drv->pm->restore(dev); 780 if (pm->restore)
781 error = pm->restore(dev);
782 } else {
783 pci_pm_reenable_device(pci_dev);
784 }
757 785
758 return error; 786 return error;
759} 787}