mmc: mxcmmc: Use mmc_regulator_get_supply() API
[linux-2.6-block.git] / drivers / mmc / host / mxcmmc.c
index f7199c83f5cf8e85c49ed54b575502d0187fc8c3..ed1cb93c3784b54a62916e9aeb0540db2bf303e6 100644 (file)
@@ -124,9 +124,8 @@ enum mxcmci_type {
 
 struct mxcmci_host {
        struct mmc_host         *mmc;
-       struct resource         *res;
        void __iomem            *base;
-       int                     irq;
+       dma_addr_t              phys_base;
        int                     detect_irq;
        struct dma_chan         *dma;
        struct dma_async_tx_descriptor *desc;
@@ -154,8 +153,6 @@ struct mxcmci_host {
        struct work_struct      datawork;
        spinlock_t              lock;
 
-       struct regulator        *vcc;
-
        int                     burstlen;
        int                     dmareq;
        struct dma_slave_config dma_slave_config;
@@ -241,37 +238,15 @@ static inline void mxcmci_writew(struct mxcmci_host *host, u16 val, int reg)
 
 static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios);
 
-static inline void mxcmci_init_ocr(struct mxcmci_host *host)
-{
-       host->vcc = regulator_get(mmc_dev(host->mmc), "vmmc");
-
-       if (IS_ERR(host->vcc)) {
-               host->vcc = NULL;
-       } else {
-               host->mmc->ocr_avail = mmc_regulator_get_ocrmask(host->vcc);
-               if (host->pdata && host->pdata->ocr_avail)
-                       dev_warn(mmc_dev(host->mmc),
-                               "pdata->ocr_avail will not be used\n");
-       }
-
-       if (host->vcc == NULL) {
-               /* fall-back to platform data */
-               if (host->pdata && host->pdata->ocr_avail)
-                       host->mmc->ocr_avail = host->pdata->ocr_avail;
-               else
-                       host->mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
-       }
-}
-
-static inline void mxcmci_set_power(struct mxcmci_host *host,
-                                   unsigned char power_mode,
-                                   unsigned int vdd)
+static void mxcmci_set_power(struct mxcmci_host *host, unsigned int vdd)
 {
-       if (host->vcc) {
-               if (power_mode == MMC_POWER_UP)
-                       mmc_regulator_set_ocr(host->mmc, host->vcc, vdd);
-               else if (power_mode == MMC_POWER_OFF)
-                       mmc_regulator_set_ocr(host->mmc, host->vcc, 0);
+       if (!IS_ERR(host->mmc->supply.vmmc)) {
+               if (host->power_mode == MMC_POWER_UP)
+                       mmc_regulator_set_ocr(host->mmc,
+                                             host->mmc->supply.vmmc, vdd);
+               else if (host->power_mode == MMC_POWER_OFF)
+                       mmc_regulator_set_ocr(host->mmc,
+                                             host->mmc->supply.vmmc, 0);
        }
 
        if (host->pdata && host->pdata->setpower)
@@ -299,7 +274,6 @@ static void mxcmci_softreset(struct mxcmci_host *host)
 
        mxcmci_writew(host, 0xff, MMC_REG_RES_TO);
 }
-static int mxcmci_setup_dma(struct mmc_host *mmc);
 
 #if IS_ENABLED(CONFIG_PPC_MPC512x)
 static inline void buffer_swap32(u32 *buf, int len)
@@ -868,8 +842,8 @@ static int mxcmci_setup_dma(struct mmc_host *mmc)
        struct mxcmci_host *host = mmc_priv(mmc);
        struct dma_slave_config *config = &host->dma_slave_config;
 
-       config->dst_addr = host->res->start + MMC_REG_BUFFER_ACCESS;
-       config->src_addr = host->res->start + MMC_REG_BUFFER_ACCESS;
+       config->dst_addr = host->phys_base + MMC_REG_BUFFER_ACCESS;
+       config->src_addr = host->phys_base + MMC_REG_BUFFER_ACCESS;
        config->dst_addr_width = 4;
        config->src_addr_width = 4;
        config->dst_maxburst = host->burstlen;
@@ -911,8 +885,8 @@ static void mxcmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                host->cmdat &= ~CMD_DAT_CONT_BUS_WIDTH_4;
 
        if (host->power_mode != ios->power_mode) {
-               mxcmci_set_power(host, ios->power_mode, ios->vdd);
                host->power_mode = ios->power_mode;
+               mxcmci_set_power(host, ios->vdd);
 
                if (ios->power_mode == MMC_POWER_ON)
                        host->cmdat |= CMD_DAT_CONT_INIT;
@@ -1040,8 +1014,8 @@ static const struct mmc_host_ops mxcmci_ops = {
 static int mxcmci_probe(struct platform_device *pdev)
 {
        struct mmc_host *mmc;
-       struct mxcmci_host *host = NULL;
-       struct resource *iores, *r;
+       struct mxcmci_host *host;
+       struct resource *res;
        int ret = 0, irq;
        bool dat3_card_detect = false;
        dma_cap_mask_t mask;
@@ -1052,21 +1026,25 @@ static int mxcmci_probe(struct platform_device *pdev)
 
        of_id = of_match_device(mxcmci_of_match, &pdev->dev);
 
-       iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        irq = platform_get_irq(pdev, 0);
-       if (!iores || irq < 0)
+       if (irq < 0)
                return -EINVAL;
 
-       r = request_mem_region(iores->start, resource_size(iores), pdev->name);
-       if (!r)
-               return -EBUSY;
+       mmc = mmc_alloc_host(sizeof(*host), &pdev->dev);
+       if (!mmc)
+               return -ENOMEM;
+
+       host = mmc_priv(mmc);
 
-       mmc = mmc_alloc_host(sizeof(struct mxcmci_host), &pdev->dev);
-       if (!mmc) {
-               ret = -ENOMEM;
-               goto out_release_mem;
+       host->base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(host->base)) {
+               ret = PTR_ERR(host->base);
+               goto out_free;
        }
 
+       host->phys_base = res->start;
+
        ret = mmc_of_parse(mmc);
        if (ret)
                goto out_free;
@@ -1084,13 +1062,6 @@ static int mxcmci_probe(struct platform_device *pdev)
        mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
        mmc->max_seg_size = mmc->max_req_size;
 
-       host = mmc_priv(mmc);
-       host->base = ioremap(r->start, resource_size(r));
-       if (!host->base) {
-               ret = -ENOMEM;
-               goto out_free;
-       }
-
        if (of_id) {
                const struct platform_device_id *id_entry = of_id->data;
                host->devtype = id_entry->driver_data;
@@ -1112,7 +1083,14 @@ static int mxcmci_probe(struct platform_device *pdev)
                        && !of_property_read_bool(pdev->dev.of_node, "cd-gpios"))
                dat3_card_detect = true;
 
-       mxcmci_init_ocr(host);
+       ret = mmc_regulator_get_supply(mmc);
+       if (ret) {
+               if (pdata && ret != -EPROBE_DEFER)
+                       mmc->ocr_avail = pdata->ocr_avail ? :
+                               MMC_VDD_32_33 | MMC_VDD_33_34;
+               else
+                       goto out_free;
+       }
 
        if (dat3_card_detect)
                host->default_irq_mask =
@@ -1120,19 +1098,16 @@ static int mxcmci_probe(struct platform_device *pdev)
        else
                host->default_irq_mask = 0;
 
-       host->res = r;
-       host->irq = irq;
-
        host->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
        if (IS_ERR(host->clk_ipg)) {
                ret = PTR_ERR(host->clk_ipg);
-               goto out_iounmap;
+               goto out_free;
        }
 
        host->clk_per = devm_clk_get(&pdev->dev, "per");
        if (IS_ERR(host->clk_per)) {
                ret = PTR_ERR(host->clk_per);
-               goto out_iounmap;
+               goto out_free;
        }
 
        clk_prepare_enable(host->clk_per);
@@ -1159,9 +1134,9 @@ static int mxcmci_probe(struct platform_device *pdev)
        if (!host->pdata) {
                host->dma = dma_request_slave_channel(&pdev->dev, "rx-tx");
        } else {
-               r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
-               if (r) {
-                       host->dmareq = r->start;
+               res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+               if (res) {
+                       host->dmareq = res->start;
                        host->dma_data.peripheral_type = IMX_DMATYPE_SDHC;
                        host->dma_data.priority = DMA_PRIO_LOW;
                        host->dma_data.dma_request = host->dmareq;
@@ -1178,7 +1153,8 @@ static int mxcmci_probe(struct platform_device *pdev)
 
        INIT_WORK(&host->datawork, mxcmci_datawork);
 
-       ret = request_irq(host->irq, mxcmci_irq, 0, DRIVER_NAME, host);
+       ret = devm_request_irq(&pdev->dev, irq, mxcmci_irq, 0,
+                              dev_name(&pdev->dev), host);
        if (ret)
                goto out_free_dma;
 
@@ -1188,7 +1164,7 @@ static int mxcmci_probe(struct platform_device *pdev)
                ret = host->pdata->init(&pdev->dev, mxcmci_detect_irq,
                                host->mmc);
                if (ret)
-                       goto out_free_irq;
+                       goto out_free_dma;
        }
 
        init_timer(&host->watchdog);
@@ -1199,20 +1175,17 @@ static int mxcmci_probe(struct platform_device *pdev)
 
        return 0;
 
-out_free_irq:
-       free_irq(host->irq, host);
 out_free_dma:
        if (host->dma)
                dma_release_channel(host->dma);
+
 out_clk_put:
        clk_disable_unprepare(host->clk_per);
        clk_disable_unprepare(host->clk_ipg);
-out_iounmap:
-       iounmap(host->base);
+
 out_free:
        mmc_free_host(mmc);
-out_release_mem:
-       release_mem_region(iores->start, resource_size(iores));
+
        return ret;
 }
 
@@ -1223,30 +1196,21 @@ static int mxcmci_remove(struct platform_device *pdev)
 
        mmc_remove_host(mmc);
 
-       if (host->vcc)
-               regulator_put(host->vcc);
-
        if (host->pdata && host->pdata->exit)
                host->pdata->exit(&pdev->dev, mmc);
 
-       free_irq(host->irq, host);
-       iounmap(host->base);
-
        if (host->dma)
                dma_release_channel(host->dma);
 
        clk_disable_unprepare(host->clk_per);
        clk_disable_unprepare(host->clk_ipg);
 
-       release_mem_region(host->res->start, resource_size(host->res));
-
        mmc_free_host(mmc);
 
        return 0;
 }
 
-#ifdef CONFIG_PM
-static int mxcmci_suspend(struct device *dev)
+static int __maybe_unused mxcmci_suspend(struct device *dev)
 {
        struct mmc_host *mmc = dev_get_drvdata(dev);
        struct mxcmci_host *host = mmc_priv(mmc);
@@ -1256,7 +1220,7 @@ static int mxcmci_suspend(struct device *dev)
        return 0;
 }
 
-static int mxcmci_resume(struct device *dev)
+static int __maybe_unused mxcmci_resume(struct device *dev)
 {
        struct mmc_host *mmc = dev_get_drvdata(dev);
        struct mxcmci_host *host = mmc_priv(mmc);
@@ -1266,11 +1230,7 @@ static int mxcmci_resume(struct device *dev)
        return 0;
 }
 
-static const struct dev_pm_ops mxcmci_pm_ops = {
-       .suspend        = mxcmci_suspend,
-       .resume         = mxcmci_resume,
-};
-#endif
+static SIMPLE_DEV_PM_OPS(mxcmci_pm_ops, mxcmci_suspend, mxcmci_resume);
 
 static struct platform_driver mxcmci_driver = {
        .probe          = mxcmci_probe,
@@ -1279,9 +1239,7 @@ static struct platform_driver mxcmci_driver = {
        .driver         = {
                .name           = DRIVER_NAME,
                .owner          = THIS_MODULE,
-#ifdef CONFIG_PM
                .pm     = &mxcmci_pm_ops,
-#endif
                .of_match_table = mxcmci_of_match,
        }
 };