aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/dw_mmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/dw_mmc.c')
-rw-r--r--drivers/mmc/host/dw_mmc.c86
1 files changed, 41 insertions, 45 deletions
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index c0667c8af2bd..323c5022c2ca 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -232,7 +232,7 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)
232{ 232{
233 struct mmc_data *data; 233 struct mmc_data *data;
234 struct dw_mci_slot *slot = mmc_priv(mmc); 234 struct dw_mci_slot *slot = mmc_priv(mmc);
235 struct dw_mci_drv_data *drv_data = slot->host->drv_data; 235 const struct dw_mci_drv_data *drv_data = slot->host->drv_data;
236 u32 cmdr; 236 u32 cmdr;
237 cmd->error = -EINPROGRESS; 237 cmd->error = -EINPROGRESS;
238 238
@@ -617,13 +617,13 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
617 cmd, arg, cmd_status); 617 cmd, arg, cmd_status);
618} 618}
619 619
620static void dw_mci_setup_bus(struct dw_mci_slot *slot) 620static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
621{ 621{
622 struct dw_mci *host = slot->host; 622 struct dw_mci *host = slot->host;
623 u32 div; 623 u32 div;
624 u32 clk_en_a; 624 u32 clk_en_a;
625 625
626 if (slot->clock != host->current_speed) { 626 if (slot->clock != host->current_speed || force_clkinit) {
627 div = host->bus_hz / slot->clock; 627 div = host->bus_hz / slot->clock;
628 if (host->bus_hz % slot->clock && host->bus_hz > slot->clock) 628 if (host->bus_hz % slot->clock && host->bus_hz > slot->clock)
629 /* 629 /*
@@ -683,9 +683,6 @@ static void __dw_mci_start_request(struct dw_mci *host,
683 if (host->pdata->select_slot) 683 if (host->pdata->select_slot)
684 host->pdata->select_slot(slot->id); 684 host->pdata->select_slot(slot->id);
685 685
686 /* Slot specific timing and width adjustment */
687 dw_mci_setup_bus(slot);
688
689 host->cur_slot = slot; 686 host->cur_slot = slot;
690 host->mrq = mrq; 687 host->mrq = mrq;
691 688
@@ -773,22 +770,19 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
773static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 770static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
774{ 771{
775 struct dw_mci_slot *slot = mmc_priv(mmc); 772 struct dw_mci_slot *slot = mmc_priv(mmc);
776 struct dw_mci_drv_data *drv_data = slot->host->drv_data; 773 const struct dw_mci_drv_data *drv_data = slot->host->drv_data;
777 u32 regs; 774 u32 regs;
778 775
779 /* set default 1 bit mode */
780 slot->ctype = SDMMC_CTYPE_1BIT;
781
782 switch (ios->bus_width) { 776 switch (ios->bus_width) {
783 case MMC_BUS_WIDTH_1:
784 slot->ctype = SDMMC_CTYPE_1BIT;
785 break;
786 case MMC_BUS_WIDTH_4: 777 case MMC_BUS_WIDTH_4:
787 slot->ctype = SDMMC_CTYPE_4BIT; 778 slot->ctype = SDMMC_CTYPE_4BIT;
788 break; 779 break;
789 case MMC_BUS_WIDTH_8: 780 case MMC_BUS_WIDTH_8:
790 slot->ctype = SDMMC_CTYPE_8BIT; 781 slot->ctype = SDMMC_CTYPE_8BIT;
791 break; 782 break;
783 default:
784 /* set default 1 bit mode */
785 slot->ctype = SDMMC_CTYPE_1BIT;
792 } 786 }
793 787
794 regs = mci_readl(slot->host, UHS_REG); 788 regs = mci_readl(slot->host, UHS_REG);
@@ -812,6 +806,9 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
812 if (drv_data && drv_data->set_ios) 806 if (drv_data && drv_data->set_ios)
813 drv_data->set_ios(slot->host, ios); 807 drv_data->set_ios(slot->host, ios);
814 808
809 /* Slot specific timing and width adjustment */
810 dw_mci_setup_bus(slot, false);
811
815 switch (ios->power_mode) { 812 switch (ios->power_mode) {
816 case MMC_POWER_UP: 813 case MMC_POWER_UP:
817 set_bit(DW_MMC_CARD_NEED_INIT, &slot->flags); 814 set_bit(DW_MMC_CARD_NEED_INIT, &slot->flags);
@@ -1817,7 +1814,7 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
1817{ 1814{
1818 struct mmc_host *mmc; 1815 struct mmc_host *mmc;
1819 struct dw_mci_slot *slot; 1816 struct dw_mci_slot *slot;
1820 struct dw_mci_drv_data *drv_data = host->drv_data; 1817 const struct dw_mci_drv_data *drv_data = host->drv_data;
1821 int ctrl_id, ret; 1818 int ctrl_id, ret;
1822 u8 bus_width; 1819 u8 bus_width;
1823 1820
@@ -1850,6 +1847,9 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
1850 if (host->pdata->caps) 1847 if (host->pdata->caps)
1851 mmc->caps = host->pdata->caps; 1848 mmc->caps = host->pdata->caps;
1852 1849
1850 if (host->pdata->pm_caps)
1851 mmc->pm_caps = host->pdata->pm_caps;
1852
1853 if (host->dev->of_node) { 1853 if (host->dev->of_node) {
1854 ctrl_id = of_alias_get_id(host->dev->of_node, "mshc"); 1854 ctrl_id = of_alias_get_id(host->dev->of_node, "mshc");
1855 if (ctrl_id < 0) 1855 if (ctrl_id < 0)
@@ -1911,7 +1911,7 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
1911#endif /* CONFIG_MMC_DW_IDMAC */ 1911#endif /* CONFIG_MMC_DW_IDMAC */
1912 } 1912 }
1913 1913
1914 host->vmmc = regulator_get(mmc_dev(mmc), "vmmc"); 1914 host->vmmc = devm_regulator_get(mmc_dev(mmc), "vmmc");
1915 if (IS_ERR(host->vmmc)) { 1915 if (IS_ERR(host->vmmc)) {
1916 pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc)); 1916 pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc));
1917 host->vmmc = NULL; 1917 host->vmmc = NULL;
@@ -1960,7 +1960,7 @@ static void dw_mci_cleanup_slot(struct dw_mci_slot *slot, unsigned int id)
1960static void dw_mci_init_dma(struct dw_mci *host) 1960static void dw_mci_init_dma(struct dw_mci *host)
1961{ 1961{
1962 /* Alloc memory for sg translation */ 1962 /* Alloc memory for sg translation */
1963 host->sg_cpu = dma_alloc_coherent(host->dev, PAGE_SIZE, 1963 host->sg_cpu = dmam_alloc_coherent(host->dev, PAGE_SIZE,
1964 &host->sg_dma, GFP_KERNEL); 1964 &host->sg_dma, GFP_KERNEL);
1965 if (!host->sg_cpu) { 1965 if (!host->sg_cpu) {
1966 dev_err(host->dev, "%s: could not alloc DMA memory\n", 1966 dev_err(host->dev, "%s: could not alloc DMA memory\n",
@@ -2038,7 +2038,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
2038 struct dw_mci_board *pdata; 2038 struct dw_mci_board *pdata;
2039 struct device *dev = host->dev; 2039 struct device *dev = host->dev;
2040 struct device_node *np = dev->of_node; 2040 struct device_node *np = dev->of_node;
2041 struct dw_mci_drv_data *drv_data = host->drv_data; 2041 const struct dw_mci_drv_data *drv_data = host->drv_data;
2042 int idx, ret; 2042 int idx, ret;
2043 2043
2044 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 2044 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
@@ -2072,6 +2072,12 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
2072 return ERR_PTR(ret); 2072 return ERR_PTR(ret);
2073 } 2073 }
2074 2074
2075 if (of_find_property(np, "keep-power-in-suspend", NULL))
2076 pdata->pm_caps |= MMC_PM_KEEP_POWER;
2077
2078 if (of_find_property(np, "enable-sdio-wakeup", NULL))
2079 pdata->pm_caps |= MMC_PM_WAKE_SDIO_IRQ;
2080
2075 return pdata; 2081 return pdata;
2076} 2082}
2077 2083
@@ -2084,7 +2090,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
2084 2090
2085int dw_mci_probe(struct dw_mci *host) 2091int dw_mci_probe(struct dw_mci *host)
2086{ 2092{
2087 struct dw_mci_drv_data *drv_data = host->drv_data; 2093 const struct dw_mci_drv_data *drv_data = host->drv_data;
2088 int width, i, ret = 0; 2094 int width, i, ret = 0;
2089 u32 fifo_size; 2095 u32 fifo_size;
2090 int init_slots = 0; 2096 int init_slots = 0;
@@ -2103,26 +2109,24 @@ int dw_mci_probe(struct dw_mci *host)
2103 return -ENODEV; 2109 return -ENODEV;
2104 } 2110 }
2105 2111
2106 host->biu_clk = clk_get(host->dev, "biu"); 2112 host->biu_clk = devm_clk_get(host->dev, "biu");
2107 if (IS_ERR(host->biu_clk)) { 2113 if (IS_ERR(host->biu_clk)) {
2108 dev_dbg(host->dev, "biu clock not available\n"); 2114 dev_dbg(host->dev, "biu clock not available\n");
2109 } else { 2115 } else {
2110 ret = clk_prepare_enable(host->biu_clk); 2116 ret = clk_prepare_enable(host->biu_clk);
2111 if (ret) { 2117 if (ret) {
2112 dev_err(host->dev, "failed to enable biu clock\n"); 2118 dev_err(host->dev, "failed to enable biu clock\n");
2113 clk_put(host->biu_clk);
2114 return ret; 2119 return ret;
2115 } 2120 }
2116 } 2121 }
2117 2122
2118 host->ciu_clk = clk_get(host->dev, "ciu"); 2123 host->ciu_clk = devm_clk_get(host->dev, "ciu");
2119 if (IS_ERR(host->ciu_clk)) { 2124 if (IS_ERR(host->ciu_clk)) {
2120 dev_dbg(host->dev, "ciu clock not available\n"); 2125 dev_dbg(host->dev, "ciu clock not available\n");
2121 } else { 2126 } else {
2122 ret = clk_prepare_enable(host->ciu_clk); 2127 ret = clk_prepare_enable(host->ciu_clk);
2123 if (ret) { 2128 if (ret) {
2124 dev_err(host->dev, "failed to enable ciu clock\n"); 2129 dev_err(host->dev, "failed to enable ciu clock\n");
2125 clk_put(host->ciu_clk);
2126 goto err_clk_biu; 2130 goto err_clk_biu;
2127 } 2131 }
2128 } 2132 }
@@ -2224,7 +2228,8 @@ int dw_mci_probe(struct dw_mci *host)
2224 if (!host->card_workqueue) 2228 if (!host->card_workqueue)
2225 goto err_dmaunmap; 2229 goto err_dmaunmap;
2226 INIT_WORK(&host->card_work, dw_mci_work_routine_card); 2230 INIT_WORK(&host->card_work, dw_mci_work_routine_card);
2227 ret = request_irq(host->irq, dw_mci_interrupt, host->irq_flags, "dw-mci", host); 2231 ret = devm_request_irq(host->dev, host->irq, dw_mci_interrupt,
2232 host->irq_flags, "dw-mci", host);
2228 if (ret) 2233 if (ret)
2229 goto err_workqueue; 2234 goto err_workqueue;
2230 2235
@@ -2262,7 +2267,7 @@ int dw_mci_probe(struct dw_mci *host)
2262 } else { 2267 } else {
2263 dev_dbg(host->dev, "attempted to initialize %d slots, " 2268 dev_dbg(host->dev, "attempted to initialize %d slots, "
2264 "but failed on all\n", host->num_slots); 2269 "but failed on all\n", host->num_slots);
2265 goto err_init_slot; 2270 goto err_workqueue;
2266 } 2271 }
2267 2272
2268 /* 2273 /*
@@ -2282,33 +2287,24 @@ int dw_mci_probe(struct dw_mci *host)
2282 2287
2283 return 0; 2288 return 0;
2284 2289
2285err_init_slot:
2286 free_irq(host->irq, host);
2287
2288err_workqueue: 2290err_workqueue:
2289 destroy_workqueue(host->card_workqueue); 2291 destroy_workqueue(host->card_workqueue);
2290 2292
2291err_dmaunmap: 2293err_dmaunmap:
2292 if (host->use_dma && host->dma_ops->exit) 2294 if (host->use_dma && host->dma_ops->exit)
2293 host->dma_ops->exit(host); 2295 host->dma_ops->exit(host);
2294 dma_free_coherent(host->dev, PAGE_SIZE,
2295 host->sg_cpu, host->sg_dma);
2296 2296
2297 if (host->vmmc) { 2297 if (host->vmmc)
2298 regulator_disable(host->vmmc); 2298 regulator_disable(host->vmmc);
2299 regulator_put(host->vmmc);
2300 }
2301 2299
2302err_clk_ciu: 2300err_clk_ciu:
2303 if (!IS_ERR(host->ciu_clk)) { 2301 if (!IS_ERR(host->ciu_clk))
2304 clk_disable_unprepare(host->ciu_clk); 2302 clk_disable_unprepare(host->ciu_clk);
2305 clk_put(host->ciu_clk); 2303
2306 }
2307err_clk_biu: 2304err_clk_biu:
2308 if (!IS_ERR(host->biu_clk)) { 2305 if (!IS_ERR(host->biu_clk))
2309 clk_disable_unprepare(host->biu_clk); 2306 clk_disable_unprepare(host->biu_clk);
2310 clk_put(host->biu_clk); 2307
2311 }
2312 return ret; 2308 return ret;
2313} 2309}
2314EXPORT_SYMBOL(dw_mci_probe); 2310EXPORT_SYMBOL(dw_mci_probe);
@@ -2330,24 +2326,19 @@ void dw_mci_remove(struct dw_mci *host)
2330 mci_writel(host, CLKENA, 0); 2326 mci_writel(host, CLKENA, 0);
2331 mci_writel(host, CLKSRC, 0); 2327 mci_writel(host, CLKSRC, 0);
2332 2328
2333 free_irq(host->irq, host);
2334 destroy_workqueue(host->card_workqueue); 2329 destroy_workqueue(host->card_workqueue);
2335 dma_free_coherent(host->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
2336 2330
2337 if (host->use_dma && host->dma_ops->exit) 2331 if (host->use_dma && host->dma_ops->exit)
2338 host->dma_ops->exit(host); 2332 host->dma_ops->exit(host);
2339 2333
2340 if (host->vmmc) { 2334 if (host->vmmc)
2341 regulator_disable(host->vmmc); 2335 regulator_disable(host->vmmc);
2342 regulator_put(host->vmmc);
2343 }
2344 2336
2345 if (!IS_ERR(host->ciu_clk)) 2337 if (!IS_ERR(host->ciu_clk))
2346 clk_disable_unprepare(host->ciu_clk); 2338 clk_disable_unprepare(host->ciu_clk);
2339
2347 if (!IS_ERR(host->biu_clk)) 2340 if (!IS_ERR(host->biu_clk))
2348 clk_disable_unprepare(host->biu_clk); 2341 clk_disable_unprepare(host->biu_clk);
2349 clk_put(host->ciu_clk);
2350 clk_put(host->biu_clk);
2351} 2342}
2352EXPORT_SYMBOL(dw_mci_remove); 2343EXPORT_SYMBOL(dw_mci_remove);
2353 2344
@@ -2411,6 +2402,11 @@ int dw_mci_resume(struct dw_mci *host)
2411 struct dw_mci_slot *slot = host->slot[i]; 2402 struct dw_mci_slot *slot = host->slot[i];
2412 if (!slot) 2403 if (!slot)
2413 continue; 2404 continue;
2405 if (slot->mmc->pm_flags & MMC_PM_KEEP_POWER) {
2406 dw_mci_set_ios(slot->mmc, &slot->mmc->ios);
2407 dw_mci_setup_bus(slot, true);
2408 }
2409
2414 ret = mmc_resume_host(host->slot[i]->mmc); 2410 ret = mmc_resume_host(host->slot[i]->mmc);
2415 if (ret < 0) 2411 if (ret < 0)
2416 return ret; 2412 return ret;