aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci-driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/pci-driver.c')
-rw-r--r--drivers/pci/pci-driver.c132
1 files changed, 77 insertions, 55 deletions
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index b4cdd690ae71..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);
@@ -434,7 +450,7 @@ static int pci_pm_suspend(struct device *dev)
434static int pci_pm_suspend_noirq(struct device *dev) 450static int pci_pm_suspend_noirq(struct device *dev)
435{ 451{
436 struct pci_dev *pci_dev = to_pci_dev(dev); 452 struct pci_dev *pci_dev = to_pci_dev(dev);
437 struct pci_driver *drv = pci_dev->driver; 453 struct device_driver *drv = dev->driver;
438 int error = 0; 454 int error = 0;
439 455
440 if (drv && drv->pm) { 456 if (drv && drv->pm) {
@@ -442,8 +458,10 @@ static int pci_pm_suspend_noirq(struct device *dev)
442 error = drv->pm->suspend_noirq(dev); 458 error = drv->pm->suspend_noirq(dev);
443 suspend_report_result(drv->pm->suspend_noirq, error); 459 suspend_report_result(drv->pm->suspend_noirq, error);
444 } 460 }
445 } else { 461 } else if (pci_has_legacy_pm_support(pci_dev)) {
446 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);
447 } 465 }
448 466
449 return error; 467 return error;
@@ -453,15 +471,17 @@ static int pci_pm_resume(struct device *dev)
453{ 471{
454 struct pci_dev *pci_dev = to_pci_dev(dev); 472 struct pci_dev *pci_dev = to_pci_dev(dev);
455 struct device_driver *drv = dev->driver; 473 struct device_driver *drv = dev->driver;
456 int error; 474 int error = 0;
457 475
458 pci_fixup_device(pci_fixup_resume, pci_dev); 476 pci_fixup_device(pci_fixup_resume, pci_dev);
459 477
460 if (drv && drv->pm) { 478 if (drv && drv->pm) {
461 error = drv->pm->resume ? drv->pm->resume(dev) : 479 if (drv->pm->resume)
462 pci_default_pm_resume(pci_dev); 480 error = drv->pm->resume(dev);
463 } else { 481 } else if (pci_has_legacy_pm_support(pci_dev)) {
464 error = pci_legacy_resume(dev); 482 error = pci_legacy_resume(dev);
483 } else {
484 error = pci_default_pm_resume_late(pci_dev);
465 } 485 }
466 486
467 return error; 487 return error;
@@ -470,16 +490,18 @@ static int pci_pm_resume(struct device *dev)
470static int pci_pm_resume_noirq(struct device *dev) 490static int pci_pm_resume_noirq(struct device *dev)
471{ 491{
472 struct pci_dev *pci_dev = to_pci_dev(dev); 492 struct pci_dev *pci_dev = to_pci_dev(dev);
473 struct pci_driver *drv = pci_dev->driver; 493 struct device_driver *drv = dev->driver;
474 int error = 0; 494 int error = 0;
475 495
476 pci_fixup_device(pci_fixup_resume_early, pci_dev); 496 pci_fixup_device(pci_fixup_resume_early, to_pci_dev(dev));
477 497
478 if (drv && drv->pm) { 498 if (drv && drv->pm) {
479 if (drv->pm->resume_noirq) 499 if (drv->pm->resume_noirq)
480 error = drv->pm->resume_noirq(dev); 500 error = drv->pm->resume_noirq(dev);
481 } else { 501 } else if (pci_has_legacy_pm_support(pci_dev)) {
482 error = pci_legacy_resume_early(dev); 502 error = pci_legacy_resume_early(dev);
503 } else {
504 pci_default_pm_resume_early(pci_dev);
483 } 505 }
484 506
485 return error; 507 return error;
@@ -506,10 +528,8 @@ static int pci_pm_freeze(struct device *dev)
506 if (drv->pm->freeze) { 528 if (drv->pm->freeze) {
507 error = drv->pm->freeze(dev); 529 error = drv->pm->freeze(dev);
508 suspend_report_result(drv->pm->freeze, error); 530 suspend_report_result(drv->pm->freeze, error);
509 } else {
510 pci_default_pm_suspend(pci_dev);
511 } 531 }
512 } else { 532 } else if (pci_has_legacy_pm_support(pci_dev)) {
513 error = pci_legacy_suspend(dev, PMSG_FREEZE); 533 error = pci_legacy_suspend(dev, PMSG_FREEZE);
514 pci_fixup_device(pci_fixup_suspend, pci_dev); 534 pci_fixup_device(pci_fixup_suspend, pci_dev);
515 } 535 }
@@ -520,7 +540,7 @@ static int pci_pm_freeze(struct device *dev)
520static int pci_pm_freeze_noirq(struct device *dev) 540static int pci_pm_freeze_noirq(struct device *dev)
521{ 541{
522 struct pci_dev *pci_dev = to_pci_dev(dev); 542 struct pci_dev *pci_dev = to_pci_dev(dev);
523 struct pci_driver *drv = pci_dev->driver; 543 struct device_driver *drv = dev->driver;
524 int error = 0; 544 int error = 0;
525 545
526 if (drv && drv->pm) { 546 if (drv && drv->pm) {
@@ -528,8 +548,10 @@ static int pci_pm_freeze_noirq(struct device *dev)
528 error = drv->pm->freeze_noirq(dev); 548 error = drv->pm->freeze_noirq(dev);
529 suspend_report_result(drv->pm->freeze_noirq, error); 549 suspend_report_result(drv->pm->freeze_noirq, error);
530 } 550 }
531 } else { 551 } else if (pci_has_legacy_pm_support(pci_dev)) {
532 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);
533 } 555 }
534 556
535 return error; 557 return error;
@@ -537,14 +559,15 @@ static int pci_pm_freeze_noirq(struct device *dev)
537 559
538static int pci_pm_thaw(struct device *dev) 560static int pci_pm_thaw(struct device *dev)
539{ 561{
562 struct pci_dev *pci_dev = to_pci_dev(dev);
540 struct device_driver *drv = dev->driver; 563 struct device_driver *drv = dev->driver;
541 int error = 0; 564 int error = 0;
542 565
543 if (drv && drv->pm) { 566 if (drv && drv->pm) {
544 if (drv->pm->thaw) 567 if (drv->pm->thaw)
545 error = drv->pm->thaw(dev); 568 error = drv->pm->thaw(dev);
546 } else { 569 } else if (pci_has_legacy_pm_support(pci_dev)) {
547 pci_fixup_device(pci_fixup_resume, to_pci_dev(dev)); 570 pci_fixup_device(pci_fixup_resume, pci_dev);
548 error = pci_legacy_resume(dev); 571 error = pci_legacy_resume(dev);
549 } 572 }
550 573
@@ -554,14 +577,14 @@ static int pci_pm_thaw(struct device *dev)
554static int pci_pm_thaw_noirq(struct device *dev) 577static int pci_pm_thaw_noirq(struct device *dev)
555{ 578{
556 struct pci_dev *pci_dev = to_pci_dev(dev); 579 struct pci_dev *pci_dev = to_pci_dev(dev);
557 struct pci_driver *drv = pci_dev->driver; 580 struct device_driver *drv = dev->driver;
558 int error = 0; 581 int error = 0;
559 582
560 if (drv && drv->pm) { 583 if (drv && drv->pm) {
561 if (drv->pm->thaw_noirq) 584 if (drv->pm->thaw_noirq)
562 error = drv->pm->thaw_noirq(dev); 585 error = drv->pm->thaw_noirq(dev);
563 } else { 586 } else if (pci_has_legacy_pm_support(pci_dev)) {
564 pci_fixup_device(pci_fixup_resume_early, pci_dev); 587 pci_fixup_device(pci_fixup_resume_early, to_pci_dev(dev));
565 error = pci_legacy_resume_early(dev); 588 error = pci_legacy_resume_early(dev);
566 } 589 }
567 590
@@ -570,17 +593,18 @@ static int pci_pm_thaw_noirq(struct device *dev)
570 593
571static int pci_pm_poweroff(struct device *dev) 594static int pci_pm_poweroff(struct device *dev)
572{ 595{
596 struct pci_dev *pci_dev = to_pci_dev(dev);
573 struct device_driver *drv = dev->driver; 597 struct device_driver *drv = dev->driver;
574 int error = 0; 598 int error = 0;
575 599
576 pci_fixup_device(pci_fixup_suspend, to_pci_dev(dev)); 600 pci_fixup_device(pci_fixup_suspend, pci_dev);
577 601
578 if (drv && drv->pm) { 602 if (drv && drv->pm) {
579 if (drv->pm->poweroff) { 603 if (drv->pm->poweroff) {
580 error = drv->pm->poweroff(dev); 604 error = drv->pm->poweroff(dev);
581 suspend_report_result(drv->pm->poweroff, error); 605 suspend_report_result(drv->pm->poweroff, error);
582 } 606 }
583 } else { 607 } else if (pci_has_legacy_pm_support(pci_dev)) {
584 error = pci_legacy_suspend(dev, PMSG_HIBERNATE); 608 error = pci_legacy_suspend(dev, PMSG_HIBERNATE);
585 } 609 }
586 610
@@ -589,8 +613,7 @@ static int pci_pm_poweroff(struct device *dev)
589 613
590static int pci_pm_poweroff_noirq(struct device *dev) 614static int pci_pm_poweroff_noirq(struct device *dev)
591{ 615{
592 struct pci_dev *pci_dev = to_pci_dev(dev); 616 struct device_driver *drv = dev->driver;
593 struct pci_driver *drv = pci_dev->driver;
594 int error = 0; 617 int error = 0;
595 618
596 if (drv && drv->pm) { 619 if (drv && drv->pm) {
@@ -598,7 +621,7 @@ static int pci_pm_poweroff_noirq(struct device *dev)
598 error = drv->pm->poweroff_noirq(dev); 621 error = drv->pm->poweroff_noirq(dev);
599 suspend_report_result(drv->pm->poweroff_noirq, error); 622 suspend_report_result(drv->pm->poweroff_noirq, error);
600 } 623 }
601 } else { 624 } else if (pci_has_legacy_pm_support(to_pci_dev(dev))) {
602 error = pci_legacy_suspend_late(dev, PMSG_HIBERNATE); 625 error = pci_legacy_suspend_late(dev, PMSG_HIBERNATE);
603 } 626 }
604 627
@@ -609,13 +632,15 @@ static int pci_pm_restore(struct device *dev)
609{ 632{
610 struct pci_dev *pci_dev = to_pci_dev(dev); 633 struct pci_dev *pci_dev = to_pci_dev(dev);
611 struct device_driver *drv = dev->driver; 634 struct device_driver *drv = dev->driver;
612 int error; 635 int error = 0;
613 636
614 if (drv && drv->pm) { 637 if (drv && drv->pm) {
615 error = drv->pm->restore ? drv->pm->restore(dev) : 638 if (drv->pm->restore)
616 pci_default_pm_resume(pci_dev); 639 error = drv->pm->restore(dev);
617 } else { 640 } else if (pci_has_legacy_pm_support(pci_dev)) {
618 error = pci_legacy_resume(dev); 641 error = pci_legacy_resume(dev);
642 } else {
643 error = pci_default_pm_resume_late(pci_dev);
619 } 644 }
620 pci_fixup_device(pci_fixup_resume, pci_dev); 645 pci_fixup_device(pci_fixup_resume, pci_dev);
621 646
@@ -625,7 +650,7 @@ static int pci_pm_restore(struct device *dev)
625static int pci_pm_restore_noirq(struct device *dev) 650static int pci_pm_restore_noirq(struct device *dev)
626{ 651{
627 struct pci_dev *pci_dev = to_pci_dev(dev); 652 struct pci_dev *pci_dev = to_pci_dev(dev);
628 struct pci_driver *drv = pci_dev->driver; 653 struct device_driver *drv = dev->driver;
629 int error = 0; 654 int error = 0;
630 655
631 pci_fixup_device(pci_fixup_resume, pci_dev); 656 pci_fixup_device(pci_fixup_resume, pci_dev);
@@ -633,8 +658,10 @@ static int pci_pm_restore_noirq(struct device *dev)
633 if (drv && drv->pm) { 658 if (drv && drv->pm) {
634 if (drv->pm->restore_noirq) 659 if (drv->pm->restore_noirq)
635 error = drv->pm->restore_noirq(dev); 660 error = drv->pm->restore_noirq(dev);
636 } else { 661 } else if (pci_has_legacy_pm_support(pci_dev)) {
637 error = pci_legacy_resume_early(dev); 662 error = pci_legacy_resume_early(dev);
663 } else {
664 pci_default_pm_resume_early(pci_dev);
638 } 665 }
639 pci_fixup_device(pci_fixup_resume_early, pci_dev); 666 pci_fixup_device(pci_fixup_resume_early, pci_dev);
640 667
@@ -654,17 +681,15 @@ static int pci_pm_restore_noirq(struct device *dev)
654 681
655#endif /* !CONFIG_HIBERNATION */ 682#endif /* !CONFIG_HIBERNATION */
656 683
657struct pm_ext_ops pci_pm_ops = { 684struct dev_pm_ops pci_dev_pm_ops = {
658 .base = { 685 .prepare = pci_pm_prepare,
659 .prepare = pci_pm_prepare, 686 .complete = pci_pm_complete,
660 .complete = pci_pm_complete, 687 .suspend = pci_pm_suspend,
661 .suspend = pci_pm_suspend, 688 .resume = pci_pm_resume,
662 .resume = pci_pm_resume, 689 .freeze = pci_pm_freeze,
663 .freeze = pci_pm_freeze, 690 .thaw = pci_pm_thaw,
664 .thaw = pci_pm_thaw, 691 .poweroff = pci_pm_poweroff,
665 .poweroff = pci_pm_poweroff, 692 .restore = pci_pm_restore,
666 .restore = pci_pm_restore,
667 },
668 .suspend_noirq = pci_pm_suspend_noirq, 693 .suspend_noirq = pci_pm_suspend_noirq,
669 .resume_noirq = pci_pm_resume_noirq, 694 .resume_noirq = pci_pm_resume_noirq,
670 .freeze_noirq = pci_pm_freeze_noirq, 695 .freeze_noirq = pci_pm_freeze_noirq,
@@ -673,7 +698,7 @@ struct pm_ext_ops pci_pm_ops = {
673 .restore_noirq = pci_pm_restore_noirq, 698 .restore_noirq = pci_pm_restore_noirq,
674}; 699};
675 700
676#define PCI_PM_OPS_PTR &pci_pm_ops 701#define PCI_PM_OPS_PTR (&pci_dev_pm_ops)
677 702
678#else /* !CONFIG_PM_SLEEP */ 703#else /* !CONFIG_PM_SLEEP */
679 704
@@ -703,9 +728,6 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner,
703 drv->driver.owner = owner; 728 drv->driver.owner = owner;
704 drv->driver.mod_name = mod_name; 729 drv->driver.mod_name = mod_name;
705 730
706 if (drv->pm)
707 drv->driver.pm = &drv->pm->base;
708
709 spin_lock_init(&drv->dynids.lock); 731 spin_lock_init(&drv->dynids.lock);
710 INIT_LIST_HEAD(&drv->dynids.list); 732 INIT_LIST_HEAD(&drv->dynids.list);
711 733