aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/pci-driver.c94
1 files changed, 63 insertions, 31 deletions
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 4042d211c3e5..99d867bcf22a 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -300,6 +300,14 @@ static void pci_device_shutdown(struct device *dev)
300 300
301#ifdef CONFIG_PM_SLEEP 301#ifdef CONFIG_PM_SLEEP
302 302
303static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev)
304{
305 struct pci_driver *drv = pci_dev->driver;
306
307 return drv && (drv->suspend || drv->suspend_late || drv->resume
308 || drv->resume_early);
309}
310
303/* 311/*
304 * Default "suspend" method for devices that have no driver provided suspend, 312 * Default "suspend" method for devices that have no driver provided suspend,
305 * or not even a driver at all. 313 * or not even a driver at all.
@@ -317,14 +325,22 @@ static void pci_default_pm_suspend(struct pci_dev *pci_dev)
317 325
318/* 326/*
319 * Default "resume" method for devices that have no driver provided resume, 327 * Default "resume" method for devices that have no driver provided resume,
320 * or not even a driver at all. 328 * or not even a driver at all (first part).
321 */ 329 */
322static int pci_default_pm_resume(struct pci_dev *pci_dev) 330static void pci_default_pm_resume_early(struct pci_dev *pci_dev)
323{ 331{
324 int retval = 0;
325
326 /* restore the PCI config space */ 332 /* restore the PCI config space */
327 pci_restore_state(pci_dev); 333 pci_restore_state(pci_dev);
334}
335
336/*
337 * Default "resume" method for devices that have no driver provided resume,
338 * or not even a driver at all (second part).
339 */
340static int pci_default_pm_resume_late(struct pci_dev *pci_dev)
341{
342 int retval;
343
328 /* if the device was enabled before suspend, reenable */ 344 /* if the device was enabled before suspend, reenable */
329 retval = pci_reenable_device(pci_dev); 345 retval = pci_reenable_device(pci_dev);
330 /* 346 /*
@@ -371,10 +387,12 @@ static int pci_legacy_resume(struct device *dev)
371 struct pci_dev * pci_dev = to_pci_dev(dev); 387 struct pci_dev * pci_dev = to_pci_dev(dev);
372 struct pci_driver * drv = pci_dev->driver; 388 struct pci_driver * drv = pci_dev->driver;
373 389
374 if (drv && drv->resume) 390 if (drv && drv->resume) {
375 error = drv->resume(pci_dev); 391 error = drv->resume(pci_dev);
376 else 392 } else {
377 error = pci_default_pm_resume(pci_dev); 393 pci_default_pm_resume_early(pci_dev);
394 error = pci_default_pm_resume_late(pci_dev);
395 }
378 return error; 396 return error;
379} 397}
380 398
@@ -420,10 +438,8 @@ static int pci_pm_suspend(struct device *dev)
420 if (drv->pm->suspend) { 438 if (drv->pm->suspend) {
421 error = drv->pm->suspend(dev); 439 error = drv->pm->suspend(dev);
422 suspend_report_result(drv->pm->suspend, error); 440 suspend_report_result(drv->pm->suspend, error);
423 } else {
424 pci_default_pm_suspend(pci_dev);
425 } 441 }
426 } else { 442 } else if (pci_has_legacy_pm_support(pci_dev)) {
427 error = pci_legacy_suspend(dev, PMSG_SUSPEND); 443 error = pci_legacy_suspend(dev, PMSG_SUSPEND);
428 } 444 }
429 pci_fixup_device(pci_fixup_suspend, pci_dev); 445 pci_fixup_device(pci_fixup_suspend, pci_dev);
@@ -433,6 +449,7 @@ static int pci_pm_suspend(struct device *dev)
433 449
434static int pci_pm_suspend_noirq(struct device *dev) 450static int pci_pm_suspend_noirq(struct device *dev)
435{ 451{
452 struct pci_dev *pci_dev = to_pci_dev(dev);
436 struct device_driver *drv = dev->driver; 453 struct device_driver *drv = dev->driver;
437 int error = 0; 454 int error = 0;
438 455
@@ -441,8 +458,10 @@ static int pci_pm_suspend_noirq(struct device *dev)
441 error = drv->pm->suspend_noirq(dev); 458 error = drv->pm->suspend_noirq(dev);
442 suspend_report_result(drv->pm->suspend_noirq, error); 459 suspend_report_result(drv->pm->suspend_noirq, error);
443 } 460 }
444 } else { 461 } else if (pci_has_legacy_pm_support(pci_dev)) {
445 error = pci_legacy_suspend_late(dev, PMSG_SUSPEND); 462 error = pci_legacy_suspend_late(dev, PMSG_SUSPEND);
463 } else {
464 pci_default_pm_suspend(pci_dev);
446 } 465 }
447 466
448 return error; 467 return error;
@@ -452,15 +471,17 @@ static int pci_pm_resume(struct device *dev)
452{ 471{
453 struct pci_dev *pci_dev = to_pci_dev(dev); 472 struct pci_dev *pci_dev = to_pci_dev(dev);
454 struct device_driver *drv = dev->driver; 473 struct device_driver *drv = dev->driver;
455 int error; 474 int error = 0;
456 475
457 pci_fixup_device(pci_fixup_resume, pci_dev); 476 pci_fixup_device(pci_fixup_resume, pci_dev);
458 477
459 if (drv && drv->pm) { 478 if (drv && drv->pm) {
460 error = drv->pm->resume ? drv->pm->resume(dev) : 479 if (drv->pm->resume)
461 pci_default_pm_resume(pci_dev); 480 error = drv->pm->resume(dev);
462 } else { 481 } else if (pci_has_legacy_pm_support(pci_dev)) {
463 error = pci_legacy_resume(dev); 482 error = pci_legacy_resume(dev);
483 } else {
484 error = pci_default_pm_resume_late(pci_dev);
464 } 485 }
465 486
466 return error; 487 return error;
@@ -468,6 +489,7 @@ static int pci_pm_resume(struct device *dev)
468 489
469static int pci_pm_resume_noirq(struct device *dev) 490static int pci_pm_resume_noirq(struct device *dev)
470{ 491{
492 struct pci_dev *pci_dev = to_pci_dev(dev);
471 struct device_driver *drv = dev->driver; 493 struct device_driver *drv = dev->driver;
472 int error = 0; 494 int error = 0;
473 495
@@ -476,8 +498,10 @@ static int pci_pm_resume_noirq(struct device *dev)
476 if (drv && drv->pm) { 498 if (drv && drv->pm) {
477 if (drv->pm->resume_noirq) 499 if (drv->pm->resume_noirq)
478 error = drv->pm->resume_noirq(dev); 500 error = drv->pm->resume_noirq(dev);
479 } else { 501 } else if (pci_has_legacy_pm_support(pci_dev)) {
480 error = pci_legacy_resume_early(dev); 502 error = pci_legacy_resume_early(dev);
503 } else {
504 pci_default_pm_resume_early(pci_dev);
481 } 505 }
482 506
483 return error; 507 return error;
@@ -504,10 +528,8 @@ static int pci_pm_freeze(struct device *dev)
504 if (drv->pm->freeze) { 528 if (drv->pm->freeze) {
505 error = drv->pm->freeze(dev); 529 error = drv->pm->freeze(dev);
506 suspend_report_result(drv->pm->freeze, error); 530 suspend_report_result(drv->pm->freeze, error);
507 } else {
508 pci_default_pm_suspend(pci_dev);
509 } 531 }
510 } else { 532 } else if (pci_has_legacy_pm_support(pci_dev)) {
511 error = pci_legacy_suspend(dev, PMSG_FREEZE); 533 error = pci_legacy_suspend(dev, PMSG_FREEZE);
512 pci_fixup_device(pci_fixup_suspend, pci_dev); 534 pci_fixup_device(pci_fixup_suspend, pci_dev);
513 } 535 }
@@ -517,6 +539,7 @@ static int pci_pm_freeze(struct device *dev)
517 539
518static int pci_pm_freeze_noirq(struct device *dev) 540static int pci_pm_freeze_noirq(struct device *dev)
519{ 541{
542 struct pci_dev *pci_dev = to_pci_dev(dev);
520 struct device_driver *drv = dev->driver; 543 struct device_driver *drv = dev->driver;
521 int error = 0; 544 int error = 0;
522 545
@@ -525,8 +548,10 @@ static int pci_pm_freeze_noirq(struct device *dev)
525 error = drv->pm->freeze_noirq(dev); 548 error = drv->pm->freeze_noirq(dev);
526 suspend_report_result(drv->pm->freeze_noirq, error); 549 suspend_report_result(drv->pm->freeze_noirq, error);
527 } 550 }
528 } else { 551 } else if (pci_has_legacy_pm_support(pci_dev)) {
529 error = pci_legacy_suspend_late(dev, PMSG_FREEZE); 552 error = pci_legacy_suspend_late(dev, PMSG_FREEZE);
553 } else {
554 pci_default_pm_suspend(pci_dev);
530 } 555 }
531 556
532 return error; 557 return error;
@@ -534,14 +559,15 @@ static int pci_pm_freeze_noirq(struct device *dev)
534 559
535static int pci_pm_thaw(struct device *dev) 560static int pci_pm_thaw(struct device *dev)
536{ 561{
562 struct pci_dev *pci_dev = to_pci_dev(dev);
537 struct device_driver *drv = dev->driver; 563 struct device_driver *drv = dev->driver;
538 int error = 0; 564 int error = 0;
539 565
540 if (drv && drv->pm) { 566 if (drv && drv->pm) {
541 if (drv->pm->thaw) 567 if (drv->pm->thaw)
542 error = drv->pm->thaw(dev); 568 error = drv->pm->thaw(dev);
543 } else { 569 } else if (pci_has_legacy_pm_support(pci_dev)) {
544 pci_fixup_device(pci_fixup_resume, to_pci_dev(dev)); 570 pci_fixup_device(pci_fixup_resume, pci_dev);
545 error = pci_legacy_resume(dev); 571 error = pci_legacy_resume(dev);
546 } 572 }
547 573
@@ -550,13 +576,14 @@ static int pci_pm_thaw(struct device *dev)
550 576
551static int pci_pm_thaw_noirq(struct device *dev) 577static int pci_pm_thaw_noirq(struct device *dev)
552{ 578{
579 struct pci_dev *pci_dev = to_pci_dev(dev);
553 struct device_driver *drv = dev->driver; 580 struct device_driver *drv = dev->driver;
554 int error = 0; 581 int error = 0;
555 582
556 if (drv && drv->pm) { 583 if (drv && drv->pm) {
557 if (drv->pm->thaw_noirq) 584 if (drv->pm->thaw_noirq)
558 error = drv->pm->thaw_noirq(dev); 585 error = drv->pm->thaw_noirq(dev);
559 } else { 586 } else if (pci_has_legacy_pm_support(pci_dev)) {
560 pci_fixup_device(pci_fixup_resume_early, to_pci_dev(dev)); 587 pci_fixup_device(pci_fixup_resume_early, to_pci_dev(dev));
561 error = pci_legacy_resume_early(dev); 588 error = pci_legacy_resume_early(dev);
562 } 589 }
@@ -566,17 +593,18 @@ static int pci_pm_thaw_noirq(struct device *dev)
566 593
567static int pci_pm_poweroff(struct device *dev) 594static int pci_pm_poweroff(struct device *dev)
568{ 595{
596 struct pci_dev *pci_dev = to_pci_dev(dev);
569 struct device_driver *drv = dev->driver; 597 struct device_driver *drv = dev->driver;
570 int error = 0; 598 int error = 0;
571 599
572 pci_fixup_device(pci_fixup_suspend, to_pci_dev(dev)); 600 pci_fixup_device(pci_fixup_suspend, pci_dev);
573 601
574 if (drv && drv->pm) { 602 if (drv && drv->pm) {
575 if (drv->pm->poweroff) { 603 if (drv->pm->poweroff) {
576 error = drv->pm->poweroff(dev); 604 error = drv->pm->poweroff(dev);
577 suspend_report_result(drv->pm->poweroff, error); 605 suspend_report_result(drv->pm->poweroff, error);
578 } 606 }
579 } else { 607 } else if (pci_has_legacy_pm_support(pci_dev)) {
580 error = pci_legacy_suspend(dev, PMSG_HIBERNATE); 608 error = pci_legacy_suspend(dev, PMSG_HIBERNATE);
581 } 609 }
582 610
@@ -593,7 +621,7 @@ static int pci_pm_poweroff_noirq(struct device *dev)
593 error = drv->pm->poweroff_noirq(dev); 621 error = drv->pm->poweroff_noirq(dev);
594 suspend_report_result(drv->pm->poweroff_noirq, error); 622 suspend_report_result(drv->pm->poweroff_noirq, error);
595 } 623 }
596 } else { 624 } else if (pci_has_legacy_pm_support(to_pci_dev(dev))) {
597 error = pci_legacy_suspend_late(dev, PMSG_HIBERNATE); 625 error = pci_legacy_suspend_late(dev, PMSG_HIBERNATE);
598 } 626 }
599 627
@@ -604,13 +632,15 @@ static int pci_pm_restore(struct device *dev)
604{ 632{
605 struct pci_dev *pci_dev = to_pci_dev(dev); 633 struct pci_dev *pci_dev = to_pci_dev(dev);
606 struct device_driver *drv = dev->driver; 634 struct device_driver *drv = dev->driver;
607 int error; 635 int error = 0;
608 636
609 if (drv && drv->pm) { 637 if (drv && drv->pm) {
610 error = drv->pm->restore ? drv->pm->restore(dev) : 638 if (drv->pm->restore)
611 pci_default_pm_resume(pci_dev); 639 error = drv->pm->restore(dev);
612 } else { 640 } else if (pci_has_legacy_pm_support(pci_dev)) {
613 error = pci_legacy_resume(dev); 641 error = pci_legacy_resume(dev);
642 } else {
643 error = pci_default_pm_resume_late(pci_dev);
614 } 644 }
615 pci_fixup_device(pci_fixup_resume, pci_dev); 645 pci_fixup_device(pci_fixup_resume, pci_dev);
616 646
@@ -628,8 +658,10 @@ static int pci_pm_restore_noirq(struct device *dev)
628 if (drv && drv->pm) { 658 if (drv && drv->pm) {
629 if (drv->pm->restore_noirq) 659 if (drv->pm->restore_noirq)
630 error = drv->pm->restore_noirq(dev); 660 error = drv->pm->restore_noirq(dev);
631 } else { 661 } else if (pci_has_legacy_pm_support(pci_dev)) {
632 error = pci_legacy_resume_early(dev); 662 error = pci_legacy_resume_early(dev);
663 } else {
664 pci_default_pm_resume_early(pci_dev);
633 } 665 }
634 pci_fixup_device(pci_fixup_resume_early, pci_dev); 666 pci_fixup_device(pci_fixup_resume_early, pci_dev);
635 667