]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
ARM: OMAP: HSMMC: enable use as a module
authorKevin Hilman <khilman@mvista.com>
Wed, 19 Mar 2008 22:47:05 +0000 (15:47 -0700)
committerTony Lindgren <tony@atomide.com>
Thu, 20 Mar 2008 12:59:21 +0000 (14:59 +0200)
When building as a module, the board support code (which is compiled
in) cannot directly call the driver code (which may be in a module.)

This patch the separates the card-detect IRQ usage into board-specific
code and driver code, and adds a couple slot-specific items to the MMC
platform data.

Tested on 3430SDP ES2.

Signed-off-by: Kevin Hilman <khilman@mvista.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
arch/arm/mach-omap2/board-sdp-hsmmc.c
drivers/mmc/host/omap_hsmmc.c
include/asm-arm/arch-omap/mmc.h

index 90e8def5517184caf25d83c1e9bd43a357422f97..7661a799952bb106548b984f1130bae22fee2aa2 100644 (file)
@@ -19,7 +19,7 @@
 #include <asm/arch/board.h>
 #include <asm/io.h>
 
-#ifdef CONFIG_MMC_OMAP_HS
+#if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
 
 #define VMMC1_DEV_GRP          0x27
 #define P1_DEV_GRP             0x20
 #define MMC1_CD_IRQ            0
 #define MMC2_CD_IRQ            1
 
-static irqreturn_t mmc_omap_cd_handler(int irq, void *dev_id)
+static int sdp_mmc_card_detect(int irq)
 {
-       int detect;
-
-       detect = twl4030_get_gpio_datain(MMC1_CD_IRQ);
-       omap_mmc_notify_card_detect(dev_id, 0, detect);
-       return IRQ_HANDLED;
+       return twl4030_get_gpio_datain(irq - IH_TWL4030_GPIO_BASE);
 }
 
 /*
@@ -72,11 +68,6 @@ static int sdp_mmc_late_init(struct device *dev)
        if (ret != 0)
                goto err;
 
-       ret = request_irq(TWL4030_GPIO_IRQ_NO(MMC1_CD_IRQ),
-               mmc_omap_cd_handler, IRQF_DISABLED, "MMC1_CD_IRQ", dev);
-       if (ret < 0)
-               goto err;
-
        return ret;
 err:
        dev_err(dev, "Failed to configure TWL4030 GPIO IRQ\n");
@@ -89,7 +80,6 @@ static void sdp_mmc_cleanup(struct device *dev)
        int ret = 0;
 
        ret = twl4030_free_gpio(MMC1_CD_IRQ);
-       free_irq(TWL4030_GPIO_IRQ_NO(MMC1_CD_IRQ), dev);
        if (ret != 0)
                dev_err(dev, "Failed to configure TWL4030 GPIO IRQ\n");
 }
@@ -259,6 +249,9 @@ static struct omap_mmc_platform_data sdp_mmc_data = {
                .ocr_mask               = MMC_VDD_32_33 | MMC_VDD_33_34 |
                                                MMC_VDD_165_195,
                .name                   = "first slot",
+
+               .card_detect_irq        = TWL4030_GPIO_IRQ_NO(MMC1_CD_IRQ),
+               .card_detect            = sdp_mmc_card_detect,
        },
 };
 
index 3d4a7d1b56284a11d993ee017fbeb7847da0c77e..047c64dc4e895c724e31f4417bf9442ce2efd89e 100644 (file)
@@ -432,11 +432,14 @@ static void mmc_omap_detect(struct work_struct *work)
 /*
  * ISR for handling card insertion and removal
  */
-void omap_mmc_notify_card_detect(struct device *dev, int slot, int detected)
+static irqreturn_t omap_mmc_cd_handler(int irq, void *dev_id)
 {
-       struct mmc_omap_host *host = dev_get_drvdata(dev);
-       host->carddetect = detected;
+       struct mmc_omap_host *host = (struct mmc_omap_host *)dev_id;
+
+       host->carddetect = mmc_slot(host).card_detect(irq);
        schedule_work(&host->mmc_carddetect_work);
+
+       return IRQ_HANDLED;
 }
 
 /*
@@ -797,9 +800,23 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
                goto irq_err;
        }
 
+       /* Request IRQ for card detect */
+       if ((mmc_slot(host).card_detect_irq) && (mmc_slot(host).card_detect)) {
+               ret = request_irq(mmc_slot(host).card_detect_irq,
+                                 omap_mmc_cd_handler, IRQF_DISABLED, "MMC CD",
+                                 host);
+               if (ret) {
+                       dev_dbg(mmc_dev(host->mmc),
+                               "Unable to grab MMC CD IRQ");
+                       free_irq(host->irq, host);
+                       goto irq_err;
+               }
+       }
+
        INIT_WORK(&host->mmc_carddetect_work, mmc_omap_detect);
        if (pdata->init != NULL) {
                if (pdata->init(&pdev->dev) != 0) {
+                       free_irq(mmc_slot(host).card_detect_irq, host);
                        free_irq(host->irq, host);
                        goto irq_err;
                }
@@ -843,6 +860,8 @@ static int omap_mmc_remove(struct platform_device *pdev)
        if (host) {
                host->pdata->cleanup(&pdev->dev);
                free_irq(host->irq, host);
+               if (mmc_slot(host).card_detect_irq)
+                       free_irq(mmc_slot(host).card_detect_irq, host);
                flush_scheduled_work();
 
                clk_disable(host->fclk);
index 4d40db0a9a73cf4f17f68ece8cf753452a94992e..3c2f2c1a9ad163fb8a4bfc48f6774c21090e06ae 100644 (file)
@@ -55,13 +55,16 @@ struct omap_mmc_platform_data {
 
                const char *name;
                u32 ocr_mask;
+
+               /* Card detection IRQs */
+               int card_detect_irq;
+               int (* card_detect)(int irq);
        } slots[OMAP_MMC_MAX_SLOTS];
 };
 
 extern void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info);
 
 /* called from board-specific card detection service routine */
-extern void omap_mmc_notify_card_detect(struct device *dev, int slot, int detected);
 extern void omap_mmc_notify_cover_event(struct device *dev, int slot, int is_closed);
 
 #endif