]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/mmc/host/tmio_mmc_pio.c
mmc: host: tmio: disable clocks when unbinding
[karo-tx-linux.git] / drivers / mmc / host / tmio_mmc_pio.c
index 2064fa1a5bf11f9a5ca994b94087e389703bb550..4a498ae7d6d7fca8dd56b999c6e5a7157666a376 100644 (file)
@@ -140,12 +140,10 @@ static void tmio_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
 
                host->sdio_irq_mask = TMIO_SDIO_MASK_ALL &
                                        ~TMIO_SDIO_STAT_IOIRQ;
-               sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0001);
                sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask);
        } else if (!enable && host->sdio_irq_enabled) {
                host->sdio_irq_mask = TMIO_SDIO_MASK_ALL;
                sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask);
-               sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0000);
 
                host->sdio_irq_enabled = false;
                pm_runtime_mark_last_busy(mmc_dev(mmc));
@@ -902,6 +900,12 @@ static int tmio_mmc_clk_enable(struct tmio_mmc_host *host)
        return host->clk_enable(host);
 }
 
+static void tmio_mmc_clk_disable(struct tmio_mmc_host *host)
+{
+       if (host->clk_disable)
+               host->clk_disable(host);
+}
+
 static void tmio_mmc_power_on(struct tmio_mmc_host *host, unsigned short vdd)
 {
        struct mmc_host *mmc = host->mmc;
@@ -1145,7 +1149,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host,
 
        ret = mmc_of_parse(mmc);
        if (ret < 0)
-               goto host_free;
+               return ret;
 
        _host->pdata = pdata;
        platform_set_drvdata(pdev, mmc);
@@ -1155,14 +1159,12 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host,
 
        ret = tmio_mmc_init_ocr(_host);
        if (ret < 0)
-               goto host_free;
+               return ret;
 
        _host->ctl = devm_ioremap(&pdev->dev,
                                  res_ctl->start, resource_size(res_ctl));
-       if (!_host->ctl) {
-               ret = -ENOMEM;
-               goto host_free;
-       }
+       if (!_host->ctl)
+               return -ENOMEM;
 
        tmio_mmc_ops.card_busy = _host->card_busy;
        tmio_mmc_ops.start_signal_voltage_switch = _host->start_signal_voltage_switch;
@@ -1179,8 +1181,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host,
 
        _host->native_hotplug = !(pdata->flags & TMIO_MMC_USE_GPIO_CD ||
                                  mmc->caps & MMC_CAP_NEEDS_POLL ||
-                                 !mmc_card_is_removable(mmc) ||
-                                 mmc->slot.cd_irq >= 0);
+                                 !mmc_card_is_removable(mmc));
 
        /*
         * On Gen2+, eMMC with NONREMOVABLE currently fails because native
@@ -1200,10 +1201,8 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host,
         * Check the sanity of mmc->f_min to prevent tmio_mmc_set_clock() from
         * looping forever...
         */
-       if (mmc->f_min == 0) {
-               ret = -EINVAL;
-               goto host_free;
-       }
+       if (mmc->f_min == 0)
+               return -EINVAL;
 
        /*
         * While using internal tmio hardware logic for card detection, we need
@@ -1232,7 +1231,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host,
        if (pdata->flags & TMIO_MMC_SDIO_IRQ) {
                _host->sdio_irq_mask = TMIO_SDIO_MASK_ALL;
                sd_ctrl_write16(_host, CTL_SDIO_IRQ_MASK, _host->sdio_irq_mask);
-               sd_ctrl_write16(_host, CTL_TRANSACTION_CTL, 0x0000);
+               sd_ctrl_write16(_host, CTL_TRANSACTION_CTL, 0x0001);
        }
 
        spin_lock_init(&_host->lock);
@@ -1268,10 +1267,6 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host,
        }
 
        return 0;
-
-host_free:
-
-       return ret;
 }
 EXPORT_SYMBOL(tmio_mmc_host_probe);
 
@@ -1280,6 +1275,9 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host)
        struct platform_device *pdev = host->pdev;
        struct mmc_host *mmc = host->mmc;
 
+       if (host->pdata->flags & TMIO_MMC_SDIO_IRQ)
+               sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0000);
+
        if (!host->native_hotplug)
                pm_runtime_get_sync(&pdev->dev);
 
@@ -1292,6 +1290,8 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host)
 
        pm_runtime_put_sync(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
+
+       tmio_mmc_clk_disable(host);
 }
 EXPORT_SYMBOL(tmio_mmc_host_remove);
 
@@ -1306,8 +1306,7 @@ int tmio_mmc_host_runtime_suspend(struct device *dev)
        if (host->clk_cache)
                tmio_mmc_clk_stop(host);
 
-       if (host->clk_disable)
-               host->clk_disable(host);
+       tmio_mmc_clk_disable(host);
 
        return 0;
 }