diff options
-rw-r--r-- | drivers/acpi/acpi_lpss.c | 53 |
1 files changed, 35 insertions, 18 deletions
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index 93d160661f4c..f6b71afb80ea 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c | |||
@@ -499,14 +499,15 @@ static void acpi_lpss_set_ltr(struct device *dev, s32 val) | |||
499 | /** | 499 | /** |
500 | * acpi_lpss_save_ctx() - Save the private registers of LPSS device | 500 | * acpi_lpss_save_ctx() - Save the private registers of LPSS device |
501 | * @dev: LPSS device | 501 | * @dev: LPSS device |
502 | * @pdata: pointer to the private data of the LPSS device | ||
502 | * | 503 | * |
503 | * Most LPSS devices have private registers which may loose their context when | 504 | * Most LPSS devices have private registers which may loose their context when |
504 | * the device is powered down. acpi_lpss_save_ctx() saves those registers into | 505 | * the device is powered down. acpi_lpss_save_ctx() saves those registers into |
505 | * prv_reg_ctx array. | 506 | * prv_reg_ctx array. |
506 | */ | 507 | */ |
507 | static void acpi_lpss_save_ctx(struct device *dev) | 508 | static void acpi_lpss_save_ctx(struct device *dev, |
509 | struct lpss_private_data *pdata) | ||
508 | { | 510 | { |
509 | struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); | ||
510 | unsigned int i; | 511 | unsigned int i; |
511 | 512 | ||
512 | for (i = 0; i < LPSS_PRV_REG_COUNT; i++) { | 513 | for (i = 0; i < LPSS_PRV_REG_COUNT; i++) { |
@@ -521,12 +522,13 @@ static void acpi_lpss_save_ctx(struct device *dev) | |||
521 | /** | 522 | /** |
522 | * acpi_lpss_restore_ctx() - Restore the private registers of LPSS device | 523 | * acpi_lpss_restore_ctx() - Restore the private registers of LPSS device |
523 | * @dev: LPSS device | 524 | * @dev: LPSS device |
525 | * @pdata: pointer to the private data of the LPSS device | ||
524 | * | 526 | * |
525 | * Restores the registers that were previously stored with acpi_lpss_save_ctx(). | 527 | * Restores the registers that were previously stored with acpi_lpss_save_ctx(). |
526 | */ | 528 | */ |
527 | static void acpi_lpss_restore_ctx(struct device *dev) | 529 | static void acpi_lpss_restore_ctx(struct device *dev, |
530 | struct lpss_private_data *pdata) | ||
528 | { | 531 | { |
529 | struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); | ||
530 | unsigned int i; | 532 | unsigned int i; |
531 | 533 | ||
532 | /* | 534 | /* |
@@ -549,23 +551,31 @@ static void acpi_lpss_restore_ctx(struct device *dev) | |||
549 | #ifdef CONFIG_PM_SLEEP | 551 | #ifdef CONFIG_PM_SLEEP |
550 | static int acpi_lpss_suspend_late(struct device *dev) | 552 | static int acpi_lpss_suspend_late(struct device *dev) |
551 | { | 553 | { |
552 | int ret = pm_generic_suspend_late(dev); | 554 | struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); |
555 | int ret; | ||
553 | 556 | ||
557 | ret = pm_generic_suspend_late(dev); | ||
554 | if (ret) | 558 | if (ret) |
555 | return ret; | 559 | return ret; |
556 | 560 | ||
557 | acpi_lpss_save_ctx(dev); | 561 | if (pdata->dev_desc->flags & LPSS_SAVE_CTX) |
562 | acpi_lpss_save_ctx(dev, pdata); | ||
563 | |||
558 | return acpi_dev_suspend_late(dev); | 564 | return acpi_dev_suspend_late(dev); |
559 | } | 565 | } |
560 | 566 | ||
561 | static int acpi_lpss_resume_early(struct device *dev) | 567 | static int acpi_lpss_resume_early(struct device *dev) |
562 | { | 568 | { |
563 | int ret = acpi_dev_resume_early(dev); | 569 | struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); |
570 | int ret; | ||
564 | 571 | ||
572 | ret = acpi_dev_resume_early(dev); | ||
565 | if (ret) | 573 | if (ret) |
566 | return ret; | 574 | return ret; |
567 | 575 | ||
568 | acpi_lpss_restore_ctx(dev); | 576 | if (pdata->dev_desc->flags & LPSS_SAVE_CTX) |
577 | acpi_lpss_restore_ctx(dev, pdata); | ||
578 | |||
569 | return pm_generic_resume_early(dev); | 579 | return pm_generic_resume_early(dev); |
570 | } | 580 | } |
571 | #endif /* CONFIG_PM_SLEEP */ | 581 | #endif /* CONFIG_PM_SLEEP */ |
@@ -573,23 +583,31 @@ static int acpi_lpss_resume_early(struct device *dev) | |||
573 | #ifdef CONFIG_PM_RUNTIME | 583 | #ifdef CONFIG_PM_RUNTIME |
574 | static int acpi_lpss_runtime_suspend(struct device *dev) | 584 | static int acpi_lpss_runtime_suspend(struct device *dev) |
575 | { | 585 | { |
576 | int ret = pm_generic_runtime_suspend(dev); | 586 | struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); |
587 | int ret; | ||
577 | 588 | ||
589 | ret = pm_generic_runtime_suspend(dev); | ||
578 | if (ret) | 590 | if (ret) |
579 | return ret; | 591 | return ret; |
580 | 592 | ||
581 | acpi_lpss_save_ctx(dev); | 593 | if (pdata->dev_desc->flags & LPSS_SAVE_CTX) |
594 | acpi_lpss_save_ctx(dev, pdata); | ||
595 | |||
582 | return acpi_dev_runtime_suspend(dev); | 596 | return acpi_dev_runtime_suspend(dev); |
583 | } | 597 | } |
584 | 598 | ||
585 | static int acpi_lpss_runtime_resume(struct device *dev) | 599 | static int acpi_lpss_runtime_resume(struct device *dev) |
586 | { | 600 | { |
587 | int ret = acpi_dev_runtime_resume(dev); | 601 | struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); |
602 | int ret; | ||
588 | 603 | ||
604 | ret = acpi_dev_runtime_resume(dev); | ||
589 | if (ret) | 605 | if (ret) |
590 | return ret; | 606 | return ret; |
591 | 607 | ||
592 | acpi_lpss_restore_ctx(dev); | 608 | if (pdata->dev_desc->flags & LPSS_SAVE_CTX) |
609 | acpi_lpss_restore_ctx(dev, pdata); | ||
610 | |||
593 | return pm_generic_runtime_resume(dev); | 611 | return pm_generic_runtime_resume(dev); |
594 | } | 612 | } |
595 | #endif /* CONFIG_PM_RUNTIME */ | 613 | #endif /* CONFIG_PM_RUNTIME */ |
@@ -631,22 +649,21 @@ static int acpi_lpss_platform_notify(struct notifier_block *nb, | |||
631 | return 0; | 649 | return 0; |
632 | 650 | ||
633 | pdata = acpi_driver_data(adev); | 651 | pdata = acpi_driver_data(adev); |
634 | if (!pdata || !pdata->mmio_base) | 652 | if (!pdata) |
635 | return 0; | 653 | return 0; |
636 | 654 | ||
637 | if (pdata->mmio_size < pdata->dev_desc->prv_offset + LPSS_LTR_SIZE) { | 655 | if (pdata->mmio_base && |
656 | pdata->mmio_size < pdata->dev_desc->prv_offset + LPSS_LTR_SIZE) { | ||
638 | dev_err(&pdev->dev, "MMIO size insufficient to access LTR\n"); | 657 | dev_err(&pdev->dev, "MMIO size insufficient to access LTR\n"); |
639 | return 0; | 658 | return 0; |
640 | } | 659 | } |
641 | 660 | ||
642 | switch (action) { | 661 | switch (action) { |
643 | case BUS_NOTIFY_BOUND_DRIVER: | 662 | case BUS_NOTIFY_BOUND_DRIVER: |
644 | if (pdata->dev_desc->flags & LPSS_SAVE_CTX) | 663 | pdev->dev.pm_domain = &acpi_lpss_pm_domain; |
645 | pdev->dev.pm_domain = &acpi_lpss_pm_domain; | ||
646 | break; | 664 | break; |
647 | case BUS_NOTIFY_UNBOUND_DRIVER: | 665 | case BUS_NOTIFY_UNBOUND_DRIVER: |
648 | if (pdata->dev_desc->flags & LPSS_SAVE_CTX) | 666 | pdev->dev.pm_domain = NULL; |
649 | pdev->dev.pm_domain = NULL; | ||
650 | break; | 667 | break; |
651 | case BUS_NOTIFY_ADD_DEVICE: | 668 | case BUS_NOTIFY_ADD_DEVICE: |
652 | if (pdata->dev_desc->flags & LPSS_LTR) | 669 | if (pdata->dev_desc->flags & LPSS_LTR) |