aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/tmio_mmc_pio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/tmio_mmc_pio.c')
-rw-r--r--drivers/mmc/host/tmio_mmc_pio.c57
1 files changed, 54 insertions, 3 deletions
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 710339a85c84..8b05d3ceb29c 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -39,6 +39,7 @@
39#include <linux/module.h> 39#include <linux/module.h>
40#include <linux/pagemap.h> 40#include <linux/pagemap.h>
41#include <linux/platform_device.h> 41#include <linux/platform_device.h>
42#include <linux/pm_runtime.h>
42#include <linux/scatterlist.h> 43#include <linux/scatterlist.h>
43#include <linux/workqueue.h> 44#include <linux/workqueue.h>
44#include <linux/spinlock.h> 45#include <linux/spinlock.h>
@@ -834,12 +835,17 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
834 else 835 else
835 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; 836 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
836 837
838 pm_runtime_enable(&pdev->dev);
839 ret = pm_runtime_resume(&pdev->dev);
840 if (ret < 0)
841 goto pm_disable;
842
837 tmio_mmc_clk_stop(_host); 843 tmio_mmc_clk_stop(_host);
838 tmio_mmc_reset(_host); 844 tmio_mmc_reset(_host);
839 845
840 ret = platform_get_irq(pdev, 0); 846 ret = platform_get_irq(pdev, 0);
841 if (ret < 0) 847 if (ret < 0)
842 goto unmap_ctl; 848 goto pm_suspend;
843 849
844 _host->irq = ret; 850 _host->irq = ret;
845 851
@@ -850,7 +856,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
850 ret = request_irq(_host->irq, tmio_mmc_irq, IRQF_DISABLED | 856 ret = request_irq(_host->irq, tmio_mmc_irq, IRQF_DISABLED |
851 IRQF_TRIGGER_FALLING, dev_name(&pdev->dev), _host); 857 IRQF_TRIGGER_FALLING, dev_name(&pdev->dev), _host);
852 if (ret) 858 if (ret)
853 goto unmap_ctl; 859 goto pm_suspend;
854 860
855 spin_lock_init(&_host->lock); 861 spin_lock_init(&_host->lock);
856 862
@@ -860,6 +866,9 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
860 /* See if we also get DMA */ 866 /* See if we also get DMA */
861 tmio_mmc_request_dma(_host, pdata); 867 tmio_mmc_request_dma(_host, pdata);
862 868
869 /* We have to keep the device powered for its card detection to work */
870 pm_runtime_get_noresume(&pdev->dev);
871
863 mmc_add_host(mmc); 872 mmc_add_host(mmc);
864 873
865 /* Unmask the IRQs we want to know about */ 874 /* Unmask the IRQs we want to know about */
@@ -874,7 +883,10 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
874 883
875 return 0; 884 return 0;
876 885
877unmap_ctl: 886pm_suspend:
887 pm_runtime_suspend(&pdev->dev);
888pm_disable:
889 pm_runtime_disable(&pdev->dev);
878 iounmap(_host->ctl); 890 iounmap(_host->ctl);
879host_free: 891host_free:
880 mmc_free_host(mmc); 892 mmc_free_host(mmc);
@@ -885,13 +897,52 @@ EXPORT_SYMBOL(tmio_mmc_host_probe);
885 897
886void tmio_mmc_host_remove(struct tmio_mmc_host *host) 898void tmio_mmc_host_remove(struct tmio_mmc_host *host)
887{ 899{
900 struct platform_device *pdev = host->pdev;
901
888 mmc_remove_host(host->mmc); 902 mmc_remove_host(host->mmc);
889 cancel_delayed_work_sync(&host->delayed_reset_work); 903 cancel_delayed_work_sync(&host->delayed_reset_work);
890 tmio_mmc_release_dma(host); 904 tmio_mmc_release_dma(host);
891 free_irq(host->irq, host); 905 free_irq(host->irq, host);
892 iounmap(host->ctl); 906 iounmap(host->ctl);
893 mmc_free_host(host->mmc); 907 mmc_free_host(host->mmc);
908
909 /* Compensate for pm_runtime_get_sync() in probe() above */
910 pm_runtime_put_sync(&pdev->dev);
911 pm_runtime_disable(&pdev->dev);
894} 912}
895EXPORT_SYMBOL(tmio_mmc_host_remove); 913EXPORT_SYMBOL(tmio_mmc_host_remove);
896 914
915#ifdef CONFIG_PM
916int tmio_mmc_host_suspend(struct device *dev)
917{
918 struct mmc_host *mmc = dev_get_drvdata(dev);
919 struct tmio_mmc_host *host = mmc_priv(mmc);
920 int ret = mmc_suspend_host(mmc);
921
922 if (!ret)
923 tmio_mmc_disable_mmc_irqs(host, TMIO_MASK_ALL);
924
925 host->pm_error = pm_runtime_put_sync(dev);
926
927 return ret;
928}
929EXPORT_SYMBOL(tmio_mmc_host_suspend);
930
931int tmio_mmc_host_resume(struct device *dev)
932{
933 struct mmc_host *mmc = dev_get_drvdata(dev);
934 struct tmio_mmc_host *host = mmc_priv(mmc);
935
936 if (!host->pm_error)
937 pm_runtime_get_sync(dev);
938
939 tmio_mmc_reset(mmc_priv(mmc));
940 tmio_mmc_request_dma(host, host->pdata);
941
942 return mmc_resume_host(mmc);
943}
944EXPORT_SYMBOL(tmio_mmc_host_resume);
945
946#endif /* CONFIG_PM */
947
897MODULE_LICENSE("GPL v2"); 948MODULE_LICENSE("GPL v2");