|
15 | 15 | #include <linux/module.h>
|
16 | 16 | #include <linux/of.h>
|
17 | 17 | #include <linux/of_device.h>
|
| 18 | +#include <linux/pm_runtime.h> |
18 | 19 | #include <linux/reset.h>
|
19 | 20 | #include <linux/sizes.h>
|
20 | 21 |
|
@@ -539,6 +540,8 @@ static int dwcmshc_probe(struct platform_device *pdev)
|
539 | 540 | sdhci_enable_v4_mode(host);
|
540 | 541 | #endif
|
541 | 542 |
|
| 543 | + pm_runtime_enable(dev); |
| 544 | + |
542 | 545 | host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY;
|
543 | 546 |
|
544 | 547 | err = sdhci_setup_host(host);
|
@@ -639,7 +642,58 @@ static int dwcmshc_resume(struct device *dev)
|
639 | 642 | }
|
640 | 643 | #endif
|
641 | 644 |
|
642 |
| -static SIMPLE_DEV_PM_OPS(dwcmshc_pmops, dwcmshc_suspend, dwcmshc_resume); |
| 645 | +#ifdef CONFIG_PM |
| 646 | + |
| 647 | +#ifdef CONFIG_ACPI |
| 648 | +static void dwcmshc_enable_card_clk(struct sdhci_host *host) |
| 649 | +{ |
| 650 | + u16 ctrl; |
| 651 | + |
| 652 | + ctrl = sdhci_readw(host, SDHCI_CLOCK_CONTROL); |
| 653 | + ctrl |= SDHCI_CLOCK_CARD_EN; |
| 654 | + sdhci_writew(host, ctrl, SDHCI_CLOCK_CONTROL); |
| 655 | +} |
| 656 | + |
| 657 | +static void dwcmshc_disable_card_clk(struct sdhci_host *host) |
| 658 | +{ |
| 659 | + u16 ctrl; |
| 660 | + |
| 661 | + ctrl = sdhci_readw(host, SDHCI_CLOCK_CONTROL); |
| 662 | + ctrl &= ~SDHCI_CLOCK_CARD_EN; |
| 663 | + sdhci_writew(host, ctrl, SDHCI_CLOCK_CONTROL); |
| 664 | +} |
| 665 | +#endif |
| 666 | + |
| 667 | +static int dwcmshc_runtime_suspend(struct device *dev) |
| 668 | +{ |
| 669 | + struct sdhci_host *host = dev_get_drvdata(dev); |
| 670 | + int ret = 0; |
| 671 | + |
| 672 | + ret = sdhci_runtime_suspend_host(host); |
| 673 | + if (!ret) |
| 674 | + dwcmshc_disable_card_clk(host); |
| 675 | + |
| 676 | + return ret; |
| 677 | +} |
| 678 | + |
| 679 | +static int dwcmshc_runtime_resume(struct device *dev) |
| 680 | +{ |
| 681 | + struct sdhci_host *host = dev_get_drvdata(dev); |
| 682 | + int ret = 0; |
| 683 | + |
| 684 | + dwcmshc_enable_card_clk(host); |
| 685 | + ret = sdhci_runtime_resume_host(host, 0); |
| 686 | + |
| 687 | + return ret; |
| 688 | +} |
| 689 | + |
| 690 | +#endif |
| 691 | + |
| 692 | +static const struct dev_pm_ops dwcmshc_pmops = { |
| 693 | + SET_SYSTEM_SLEEP_PM_OPS(dwcmshc_suspend, dwcmshc_resume) |
| 694 | + SET_RUNTIME_PM_OPS(dwcmshc_runtime_suspend, |
| 695 | + dwcmshc_runtime_resume, NULL) |
| 696 | +}; |
643 | 697 |
|
644 | 698 | static struct platform_driver sdhci_dwcmshc_driver = {
|
645 | 699 | .driver = {
|
|
0 commit comments