mmc: sh_mmcif: support generic card-detection
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Thu, 14 Jun 2012 12:24:35 +0000 (14:24 +0200)
committerChris Ball <cjb@laptop.org>
Sat, 21 Jul 2012 04:02:22 +0000 (00:02 -0400)
Extend the sh_mmcif driver to support GPIO card detection, provided by the
slot function module. The original .get_cd() platform callback is also
preserved for now.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Chris Ball <cjb@laptop.org>
drivers/mmc/host/sh_mmcif.c
include/linux/mmc/sh_mmcif.h

index 68b31f7c290b6942c636fb38f44fc0489237a1b9..b2af7136cd27445d33225e36d5314005dcfb39b6 100644 (file)
@@ -54,6 +54,7 @@
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/sdio.h>
 #include <linux/mmc/sh_mmcif.h>
+#include <linux/mmc/slot-gpio.h>
 #include <linux/mod_devicetable.h>
 #include <linux/pagemap.h>
 #include <linux/platform_device.h>
@@ -1000,6 +1001,10 @@ static int sh_mmcif_get_cd(struct mmc_host *mmc)
 {
        struct sh_mmcif_host *host = mmc_priv(mmc);
        struct sh_mmcif_plat_data *p = host->pd->dev.platform_data;
+       int ret = mmc_gpio_get_cd(mmc);
+
+       if (ret >= 0)
+               return ret;
 
        if (!p || !p->get_cd)
                return -ENOSYS;
@@ -1372,6 +1377,12 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
                goto ereqirq1;
        }
 
+       if (pd && pd->use_cd_gpio) {
+               ret = mmc_gpio_request_cd(mmc, pd->cd_gpio);
+               if (ret < 0)
+                       goto erqcd;
+       }
+
        clk_disable(host->hclk);
        ret = mmc_add_host(mmc);
        if (ret < 0)
@@ -1385,6 +1396,9 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
        return ret;
 
 emmcaddh:
+       if (pd && pd->use_cd_gpio)
+               mmc_gpio_free_cd(mmc);
+erqcd:
        free_irq(irq[1], host);
 ereqirq1:
        free_irq(irq[0], host);
@@ -1405,6 +1419,7 @@ ealloch:
 static int __devexit sh_mmcif_remove(struct platform_device *pdev)
 {
        struct sh_mmcif_host *host = platform_get_drvdata(pdev);
+       struct sh_mmcif_plat_data *pd = pdev->dev.platform_data;
        int irq[2];
 
        host->dying = true;
@@ -1413,6 +1428,9 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev)
 
        dev_pm_qos_hide_latency_limit(&pdev->dev);
 
+       if (pd && pd->use_cd_gpio)
+               mmc_gpio_free_cd(host->mmc);
+
        mmc_remove_host(host->mmc);
        sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
 
index 05f0e3db1c12b6681a820ff48519b0abe03b983b..c2f73cbb4d5cb14912a01efa59983b21e5ff081a 100644 (file)
@@ -44,6 +44,8 @@ struct sh_mmcif_plat_data {
        struct sh_mmcif_dma     *dma;           /* Deprecated. Instead */
        unsigned int            slave_id_tx;    /* use embedded slave_id_[tr]x */
        unsigned int            slave_id_rx;
+       bool                    use_cd_gpio : 1;
+       unsigned int            cd_gpio;
        u8                      sup_pclk;       /* 1 :SH7757, 0: SH7724/SH7372 */
        unsigned long           caps;
        u32                     ocr;