diff options
-rw-r--r-- | drivers/mmc/host/tmio_mmc_pio.c | 35 | ||||
-rw-r--r-- | include/linux/mfd/tmio.h | 3 |
2 files changed, 35 insertions, 3 deletions
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c index 4318c1a74ba0..c6c0334a20e1 100644 --- a/drivers/mmc/host/tmio_mmc_pio.c +++ b/drivers/mmc/host/tmio_mmc_pio.c | |||
@@ -752,6 +752,22 @@ fail: | |||
752 | mmc_request_done(mmc, mrq); | 752 | mmc_request_done(mmc, mrq); |
753 | } | 753 | } |
754 | 754 | ||
755 | static int tmio_mmc_clk_update(struct mmc_host *mmc) | ||
756 | { | ||
757 | struct tmio_mmc_host *host = mmc_priv(mmc); | ||
758 | struct tmio_mmc_data *pdata = host->pdata; | ||
759 | int ret; | ||
760 | |||
761 | if (!pdata->clk_enable) | ||
762 | return -ENOTSUPP; | ||
763 | |||
764 | ret = pdata->clk_enable(host->pdev, &mmc->f_max); | ||
765 | if (!ret) | ||
766 | mmc->f_min = mmc->f_max / 512; | ||
767 | |||
768 | return ret; | ||
769 | } | ||
770 | |||
755 | /* Set MMC clock / power. | 771 | /* Set MMC clock / power. |
756 | * Note: This controller uses a simple divider scheme therefore it cannot | 772 | * Note: This controller uses a simple divider scheme therefore it cannot |
757 | * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as | 773 | * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as |
@@ -798,6 +814,7 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
798 | */ | 814 | */ |
799 | if (ios->power_mode == MMC_POWER_ON && ios->clock) { | 815 | if (ios->power_mode == MMC_POWER_ON && ios->clock) { |
800 | if (!host->power) { | 816 | if (!host->power) { |
817 | tmio_mmc_clk_update(mmc); | ||
801 | pm_runtime_get_sync(dev); | 818 | pm_runtime_get_sync(dev); |
802 | host->power = true; | 819 | host->power = true; |
803 | } | 820 | } |
@@ -811,9 +828,12 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
811 | if (host->set_pwr && ios->power_mode == MMC_POWER_OFF) | 828 | if (host->set_pwr && ios->power_mode == MMC_POWER_OFF) |
812 | host->set_pwr(host->pdev, 0); | 829 | host->set_pwr(host->pdev, 0); |
813 | if (host->power) { | 830 | if (host->power) { |
831 | struct tmio_mmc_data *pdata = host->pdata; | ||
814 | tmio_mmc_clk_stop(host); | 832 | tmio_mmc_clk_stop(host); |
815 | host->power = false; | 833 | host->power = false; |
816 | pm_runtime_put(dev); | 834 | pm_runtime_put(dev); |
835 | if (pdata->clk_disable) | ||
836 | pdata->clk_disable(host->pdev); | ||
817 | } | 837 | } |
818 | } | 838 | } |
819 | 839 | ||
@@ -907,8 +927,6 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host, | |||
907 | 927 | ||
908 | mmc->ops = &tmio_mmc_ops; | 928 | mmc->ops = &tmio_mmc_ops; |
909 | mmc->caps = MMC_CAP_4_BIT_DATA | pdata->capabilities; | 929 | mmc->caps = MMC_CAP_4_BIT_DATA | pdata->capabilities; |
910 | mmc->f_max = pdata->hclk; | ||
911 | mmc->f_min = mmc->f_max / 512; | ||
912 | mmc->max_segs = 32; | 930 | mmc->max_segs = 32; |
913 | mmc->max_blk_size = 512; | 931 | mmc->max_blk_size = 512; |
914 | mmc->max_blk_count = (PAGE_CACHE_SIZE / mmc->max_blk_size) * | 932 | mmc->max_blk_count = (PAGE_CACHE_SIZE / mmc->max_blk_size) * |
@@ -930,6 +948,11 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host, | |||
930 | if (ret < 0) | 948 | if (ret < 0) |
931 | goto pm_disable; | 949 | goto pm_disable; |
932 | 950 | ||
951 | if (tmio_mmc_clk_update(mmc) < 0) { | ||
952 | mmc->f_max = pdata->hclk; | ||
953 | mmc->f_min = mmc->f_max / 512; | ||
954 | } | ||
955 | |||
933 | /* | 956 | /* |
934 | * There are 4 different scenarios for the card detection: | 957 | * There are 4 different scenarios for the card detection: |
935 | * 1) an external gpio irq handles the cd (best for power savings) | 958 | * 1) an external gpio irq handles the cd (best for power savings) |
@@ -975,7 +998,13 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host, | |||
975 | /* See if we also get DMA */ | 998 | /* See if we also get DMA */ |
976 | tmio_mmc_request_dma(_host, pdata); | 999 | tmio_mmc_request_dma(_host, pdata); |
977 | 1000 | ||
978 | mmc_add_host(mmc); | 1001 | ret = mmc_add_host(mmc); |
1002 | if (pdata->clk_disable) | ||
1003 | pdata->clk_disable(pdev); | ||
1004 | if (ret < 0) { | ||
1005 | tmio_mmc_host_remove(_host); | ||
1006 | return ret; | ||
1007 | } | ||
979 | 1008 | ||
980 | dev_pm_qos_expose_latency_limit(&pdev->dev, 100); | 1009 | dev_pm_qos_expose_latency_limit(&pdev->dev, 100); |
981 | 1010 | ||
diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h index f5171dbf8850..b332c4c7857b 100644 --- a/include/linux/mfd/tmio.h +++ b/include/linux/mfd/tmio.h | |||
@@ -110,6 +110,9 @@ struct tmio_mmc_data { | |||
110 | void (*set_clk_div)(struct platform_device *host, int state); | 110 | void (*set_clk_div)(struct platform_device *host, int state); |
111 | int (*get_cd)(struct platform_device *host); | 111 | int (*get_cd)(struct platform_device *host); |
112 | int (*write16_hook)(struct tmio_mmc_host *host, int addr); | 112 | int (*write16_hook)(struct tmio_mmc_host *host, int addr); |
113 | /* clock management callbacks */ | ||
114 | int (*clk_enable)(struct platform_device *pdev, unsigned int *f); | ||
115 | void (*clk_disable)(struct platform_device *pdev); | ||
113 | }; | 116 | }; |
114 | 117 | ||
115 | /* | 118 | /* |