SDMMC:
authorxbw <xbw@rock-chips.com>
Sun, 23 Mar 2014 22:12:08 +0000 (06:12 +0800)
committerxbw <xbw@rock-chips.com>
Sun, 23 Mar 2014 22:12:08 +0000 (06:12 +0800)
1.add the flag for emmc-disk.
2.the process of insert-remove card is ok.
3.modify the sdio-detect for sdio wifi.

drivers/mmc/card/block.c
drivers/mmc/core/host.c
drivers/mmc/host/rk_sdmmc.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_gpio.c [changed mode: 0644->0755]
include/linux/genhd.h [changed mode: 0644->0755]
include/linux/mmc/host.h
include/linux/mmc/rk_mmc.h
include/linux/rfkill-wlan.h
net/rfkill/rfkill-wlan.c

index 98bc2c205259729729aeb4a0e368ac99aec9b354..8d4d8837fb00a52bce02a9a2419803aaf555c8b7 100755 (executable)
@@ -2412,6 +2412,14 @@ static int mmc_blk_probe(struct mmc_card *card)
 
 #ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
        mmc_set_bus_resume_policy(card->host, 1);
+#endif
+#if defined(CONFIG_MMC_DW_ROCKCHIP)
+    if(card->host->restrict_caps & RESTRICT_CARD_TYPE_EMMC){
+        this_card = card;
+        md->disk->emmc_disk = 1;
+    }else {
+        md->disk->emmc_disk = 0;
+    }
 #endif
        if (mmc_add_disk(md))
                goto out;
@@ -2432,10 +2440,6 @@ static int mmc_blk_probe(struct mmc_card *card)
                pm_runtime_set_active(&card->dev);
                pm_runtime_enable(&card->dev);
        }
-#if defined(CONFIG_MMC_DW_ROCKCHIP)
-    if(card->host->restrict_caps & RESTRICT_CARD_TYPE_EMMC)
-        this_card = card;
-#endif
 
        return 0;
 
index 7767f14e359baea7ecb2432f93495f20418ed90f..dbd5f78fe39eb562bbfc76a7dc6ee36ae104bd8b 100755 (executable)
@@ -604,7 +604,7 @@ EXPORT_SYMBOL(mmc_free_host);
  *  OR, rescan host from argument.
  *
  */
-int mmc_host_rescan(struct mmc_host *host)
+int mmc_host_rescan(struct mmc_host *host, int val)
 {
     if(NULL != primary_sdio_host){
         if(!host)
@@ -618,9 +618,10 @@ int mmc_host_rescan(struct mmc_host *host)
     }
 
     printk("%s:mmc host rescan start!\n", mmc_hostname(host));
-                              
-    mmc_detect_change(host, msecs_to_jiffies(10));
 
+    if (!(host->caps & MMC_CAP_NONREMOVABLE) && host->ops->set_sdio_status)
+               host->ops->set_sdio_status(host, val);
+       
     return 0;
 }
 EXPORT_SYSMBOL(mmc_host_rescan);
index 4d792a609b8aec20ea1897aa73139bebc04c8af6..568fb02af48ce667993cab0a54a3de0b308f621d 100755 (executable)
@@ -62,6 +62,8 @@
 #define SDMMC_DATA_TIMEOUT_SDIO        250
 #define SDMMC_DATA_TIMEOUT_EMMC        2500
 
+//#define SDMMC_WAIT_FOR_UNBUSY        2500
+
 #ifdef CONFIG_MMC_DW_IDMAC
 #define IDMAC_INT_CLR          (SDMMC_IDMAC_INT_AI | SDMMC_IDMAC_INT_NI | \
                                 SDMMC_IDMAC_INT_CES | SDMMC_IDMAC_INT_DU | \
@@ -336,6 +338,21 @@ static u32 dw_mci_prep_stop_abort(struct dw_mci *host, struct mmc_command *cmd)
 static void dw_mci_start_command(struct dw_mci *host,
                                 struct mmc_command *cmd, u32 cmd_flags)
 {
+#ifdef SDMMC_WAIT_FOR_UNBUSY
+    unsigned long   time_loop = jiffies + msecs_to_jiffies(SDMMC_WAIT_FOR_UNBUSY);
+    unsigned int    status;
+    bool ret=1;
+
+    while ((ret=time_before(jiffies, time_loop))&&(test_bit(DW_MMC_CARD_PRESENT, &host->cur_slot->flags))){
+       status = mci_readl(host, STATUS);
+       if (!(status & (SDMMC_STAUTS_DATA_BUSY|SDMMC_STAUTS_MC_BUSY)))
+               break;
+    } ;
+    if(!ret)
+        printk("%d..%s:  cmd=%d,wait for unbusy timeout.......[%s]\n", 
+            __LINE__, __FUNCTION__,cmd->opcode,mmc_hostname(host->mmc));
+#endif            
+    host->pre_cmd = host->cmd;
        host->cmd = cmd;
        dev_vdbg(host->dev,
                 "start command: ARGR=0x%08x CMDR=0x%08x\n",
@@ -343,7 +360,8 @@ static void dw_mci_start_command(struct dw_mci *host,
 
        mci_writel(host, CMDARG, cmd->arg);
        wmb();
-    MMC_DBG_INFO_FUNC(host->mmc,"%d..%s start cmd=%d, arg=0x%x[%s]",__LINE__, __FUNCTION__,cmd->opcode, cmd->arg,mmc_hostname(host->mmc));
+    MMC_DBG_INFO_FUNC(host->mmc,"Line%d..%s start cmd=%d, arg=0x%x[%s]",\
+        __LINE__, __FUNCTION__,cmd->opcode, cmd->arg,mmc_hostname(host->mmc));
     //dw_mci_regs_printk(host);
 
     if(host->mmc->hold_reg_flag)
@@ -784,10 +802,23 @@ static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data)
 
 static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
 {
-       struct dw_mci *host = slot->host;
+       struct dw_mci *host = slot->host;       
        unsigned long timeout = jiffies + msecs_to_jiffies(500);
        unsigned int cmd_status = 0;
-
+#ifdef SDMMC_WAIT_FOR_UNBUSY
+       timeout = jiffies + msecs_to_jiffies(SDMMC_WAIT_FOR_UNBUSY);
+    bool ret=0;
+    if(test_bit(DW_MMC_CARD_PRESENT, &slot->flags)) {
+        while (ret=time_before(jiffies, timeout)) {
+               cmd_status = mci_readl(host, STATUS);
+               if (!(cmd_status & (SDMMC_STAUTS_DATA_BUSY|SDMMC_STAUTS_MC_BUSY)))
+                       break;
+        } ;
+        if(!ret)
+            printk("%d..%s:  wait for unbusy timeout.......[%s]\n", \
+                __LINE__, __FUNCTION__, mmc_hostname(host->mmc));
+    }
+#endif    
        mci_writel(host, CMDARG, arg);
        wmb();
        mci_writel(host, CMD, SDMMC_CMD_START | cmd);
@@ -1000,9 +1031,9 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 
        if (!test_bit(DW_MMC_CARD_PRESENT, &slot->flags)) {
                spin_unlock_bh(&host->lock);
-               mrq->cmd->error = -ENOMEDIUM;
-               
-               MMC_DBG_CMD_FUNC(host->mmc, "dw_mci_reqeust--reqeuest done, cmd=%d [%s]",mrq->cmd->opcode, mmc_hostname(host->mmc));
+               mrq->cmd->error = -ENOMEDIUM;           
+               MMC_DBG_CMD_FUNC(host->mmc, "%d..%s: no card,so reqeuest done, cmd=%d [%s]",\
+                   __LINE__, __FUNCTION__, mrq->cmd->opcode, mmc_hostname(host->mmc));
             
                mmc_request_done(mmc, mrq);
                return;
@@ -1020,11 +1051,33 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        struct dw_mci_slot *slot = mmc_priv(mmc);
        const struct dw_mci_drv_data *drv_data = slot->host->drv_data;
        u32 regs;
-
+#ifdef SDMMC_WAIT_FOR_UNBUSY   
+    unsigned long   time_loop = jiffies + msecs_to_jiffies(SDMMC_WAIT_FOR_UNBUSY);
+    bool ret=0;
+
+    if(!test_bit(DW_MMC_CARD_PRESENT, &slot->flags)){
+        printk("%d..%s:  no card. [%s]\n", \
+            __LINE__, __FUNCTION__, mmc_hostname(mmc));
+        goto EXIT_POWER;
+    }
+    
+    while (ret=time_before(jiffies, time_loop)) {
+       regs = mci_readl(slot->host, STATUS);
+       if (!(regs & (SDMMC_STAUTS_DATA_BUSY|SDMMC_STAUTS_MC_BUSY)))
+               break;
+    } ;
+    if(!ret)
+    {
+        printk("slot->flags=%d ", slot->flags);
+        dump_stack();
+        printk("%d..%s:  wait for unbusy timeout.......[%s]\n", \
+            __LINE__, __FUNCTION__, mmc_hostname(mmc));
+            }
+#endif
        switch (ios->bus_width) {
        case MMC_BUS_WIDTH_4:
                slot->ctype = SDMMC_CTYPE_4BIT;
-               break;  
+               break;                  
        case MMC_BUS_WIDTH_8: 
                slot->ctype = SDMMC_CTYPE_8BIT;
                break;  
@@ -1057,6 +1110,7 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        /* Slot specific timing and width adjustment */
        dw_mci_setup_bus(slot, false);
 
+EXIT_POWER:
        switch (ios->power_mode) {
        case MMC_POWER_UP:
                set_bit(DW_MMC_CARD_NEED_INIT, &slot->flags);
@@ -1103,6 +1157,29 @@ static int dw_mci_get_ro(struct mmc_host *mmc)
        return read_only;
 }
 
+static int dw_mci_set_sdio_status(struct mmc_host *mmc, int val)
+{
+    struct dw_mci_slot *slot = mmc_priv(mmc);
+       struct dw_mci_board *brd = slot->host->pdata;
+       struct dw_mci *host = slot->host;
+    if (!(mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO))
+        return 0;
+        
+    spin_lock_bh(&host->lock);
+    if(val)
+        set_bit(DW_MMC_CARD_PRESENT, &slot->flags);
+    else
+        clear_bit(DW_MMC_CARD_PRESENT, &slot->flags);
+    
+    spin_unlock_bh(&host->lock);
+    
+    mmc_detect_change(slot->mmc, 20);    
+
+    return 0;
+}
+
+
+
 static int dw_mci_get_cd(struct mmc_host *mmc)
 {
        int present;
@@ -1111,13 +1188,8 @@ static int dw_mci_get_cd(struct mmc_host *mmc)
        struct dw_mci *host = slot->host;
        int gpio_cd = mmc_gpio_get_cd(mmc);
        
-    if (mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO){
-        spin_lock_bh(&host->lock);
-        set_bit(DW_MMC_CARD_PRESENT, &slot->flags);
-        spin_unlock_bh(&host->lock);
-        
-        return 1;
-    }
+    if (mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO)
+        return test_bit(DW_MMC_CARD_PRESENT, &slot->flags);
 
        /* Use platform get_cd function, else try onboard card detect */
        if (brd->quirks & DW_MCI_QUIRK_BROKEN_CARD_DETECTION)
@@ -1259,11 +1331,35 @@ static const struct mmc_host_ops dw_mci_ops = {
        .set_ios                = dw_mci_set_ios,
        .get_ro                 = dw_mci_get_ro,
        .get_cd                 = dw_mci_get_cd,
+       .set_sdio_status    = dw_mci_set_sdio_status,
        .hw_reset       = dw_mci_hw_reset,
        .enable_sdio_irq        = dw_mci_enable_sdio_irq,
        .execute_tuning         = dw_mci_execute_tuning,
 };
 
+static void dw_mci_enable_irq(struct dw_mci *host, bool irqflag)
+{
+       unsigned long flags;
+
+    if(!host)
+        return;
+    
+       local_irq_save(flags);
+       if(host->irq_state != irqflag)
+       {
+           host->irq_state = irqflag;
+           if(irqflag)
+           {
+               enable_irq(host->irq);
+           }
+           else
+           {
+               disable_irq(host->irq);
+           }
+       }
+       local_irq_restore(flags);
+}
+
 static void dw_mci_deal_data_end(struct dw_mci *host, struct mmc_request *mrq)
        __releases(&host->lock)
        __acquires(&host->lock)
@@ -2135,8 +2231,8 @@ static void dw_mci_work_routine_card(struct work_struct *work)
                while (present != slot->last_detect_state) {
                        dev_dbg(&slot->mmc->class_dev, "card %s\n",
                                present ? "inserted" : "removed");
-            MMC_DBG_BOOT_FUNC(mmc, "card %s,  devname=%s \n",
-                               present ? "inserted" : "removed", mmc_hostname(mmc));
+            MMC_DBG_BOOT_FUNC(mmc, "  The card is %s.  ===!!!!!!==[%s]\n",
+                               present ? "inserted" : "removed.", mmc_hostname(mmc));
 
                        spin_lock_bh(&host->lock);
 
@@ -2408,12 +2504,12 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
                mmc->f_min = DW_MCI_FREQ_MIN;
                mmc->f_max = DW_MCI_FREQ_MAX;
                
-        printk("%d..%s: fmin=%d, fmax=%d \n", __LINE__,__FUNCTION__,mmc->f_min, mmc->f_max);    
+        printk("%d..%s: fmin=%d, fmax=%d [%s]\n", __LINE__,__FUNCTION__,mmc->f_min, mmc->f_max, mmc_hostname(mmc));    
        } else {
                mmc->f_min = freq[0];
                mmc->f_max = freq[1];
                
-        printk("%d..%s: fmin=%d, fmax=%d \n", __LINE__,__FUNCTION__,mmc->f_min, mmc->f_max);    
+        printk("%d..%s: fmin=%d, fmax=%d [%s]\n", __LINE__,__FUNCTION__,mmc->f_min, mmc->f_max,  mmc_hostname(mmc));    
        }
 #endif
 
@@ -2512,26 +2608,38 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
     //pwr_en   
     slot->pwr_en_gpio = dw_mci_of_get_pwr_en_gpio(host->dev, slot->id);
 
-if (gpio_is_valid(slot->pwr_en_gpio))
-{
-    host->vmmc = NULL;
-}else{
-
-       host->vmmc = devm_regulator_get(mmc_dev(mmc), "vmmc");
-       if (IS_ERR(host->vmmc)) {
-               pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc));
-               host->vmmc = NULL;
-       } else {
-               ret = regulator_enable(host->vmmc);
-               if (ret) {
-                       dev_err(host->dev,
-                               "failed to enable regulator: %d\n", ret);
-                       goto err_setup_bus;
-               }
-       }
-}
+    if (!(mmc->restrict_caps & RESTRICT_CARD_TYPE_SD))//(gpio_is_valid(slot->pwr_en_gpio))
+    {
+        host->vmmc = NULL;
+    }else{
+
+        if(mmc->restrict_caps & RESTRICT_CARD_TYPE_SD)
+        {
+           host->vmmc = devm_regulator_get(mmc_dev(mmc), "vmmc");
+       }
+       else
+       {
+           host->vmmc = NULL;
+       }
+        
+       if (IS_ERR(host->vmmc)) {
+               pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc));
+               host->vmmc = NULL;
+       } else {
+               ret = regulator_enable(host->vmmc);
+               if (ret) {
+                       dev_err(host->dev,
+                               "failed to enable regulator: %d\n", ret);
+                       goto err_setup_bus;
+               }
+       }
+    }
+    
        slot->wp_gpio = dw_mci_of_get_wp_gpio(host->dev, slot->id);
        dw_mci_of_get_cd_gpio(host->dev, slot->id, mmc);
+       
+    if (mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO)
+        clear_bit(DW_MMC_CARD_PRESENT, &slot->flags);
 
        ret = mmc_add_host(mmc);
        if (ret)
@@ -2542,7 +2650,7 @@ if (gpio_is_valid(slot->pwr_en_gpio))
 #endif
 
        /* Card initially undetected */
-       slot->last_detect_state = 0;
+       slot->last_detect_state = 1;
 
        return 0;
 
@@ -2658,11 +2766,12 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
                                "assuming 1 slot is available\n");
                pdata->num_slots = 1;
        }
-
+#if 0
        /* get quirks */
        for (idx = 0; idx < ARRAY_SIZE(of_quirks); idx++)
                if (of_get_property(np, of_quirks[idx].quirk, NULL))
                        pdata->quirks |= of_quirks[idx].id;
+#endif
 
        if (of_property_read_u32(np, "fifo-depth", &pdata->fifo_depth))
                dev_info(dev, "fifo-depth property not found, using "
@@ -2717,6 +2826,7 @@ int dw_mci_probe(struct dw_mci *host)
        int width, i, ret = 0;
        u32 fifo_size;
        int init_slots = 0;
+       u32 regs;
 
        if (!host->pdata) {
                host->pdata = dw_mci_parse_dt(host);
@@ -2785,6 +2895,7 @@ int dw_mci_probe(struct dw_mci *host)
        }
 
        host->quirks = host->pdata->quirks;
+    host->irq_state = true;
 
        spin_lock_init(&host->lock);
        INIT_LIST_HEAD(&host->queue);
@@ -2884,14 +2995,26 @@ int dw_mci_probe(struct dw_mci *host)
        else
                host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1;
 
+       /* We need at least one slot to succeed */
+       for (i = 0; i < host->num_slots; i++) {
+               ret = dw_mci_init_slot(host, i);
+               if (ret)
+                       dev_dbg(host->dev, "slot %d init failed\n", i);
+               else
+                       init_slots++;
+       }
+       
        /*
         * Enable interrupts for command done, data over, data empty, card det,
         * receive ready and error such as transmit, receive timeout, crc error
         */
        mci_writel(host, RINTSTS, 0xFFFFFFFF);
-       mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER |
-                  SDMMC_INT_TXDR | SDMMC_INT_RXDR |
-                  DW_MCI_ERROR_FLAGS | SDMMC_INT_CD);
+       regs = SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | SDMMC_INT_TXDR | 
+              SDMMC_INT_RXDR | DW_MCI_ERROR_FLAGS;
+       if(!(host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO))
+           regs |= SDMMC_INT_CD;
+       mci_writel(host, INTMASK, regs);
+               
        mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */
 
        dev_info(host->dev, "DW MMC controller at irq %d, "
@@ -2899,15 +3022,6 @@ int dw_mci_probe(struct dw_mci *host)
                 "%u deep fifo\n",
                 host->irq, width, fifo_size);
 
-       /* We need at least one slot to succeed */
-       for (i = 0; i < host->num_slots; i++) {
-               ret = dw_mci_init_slot(host, i);
-               if (ret)
-                       dev_dbg(host->dev, "slot %d init failed\n", i);
-               else
-                       init_slots++;
-       }
-
        if (init_slots) {
                dev_info(host->dev, "%d slots initialized\n", init_slots);
        } else {
@@ -3012,6 +3126,7 @@ EXPORT_SYMBOL(dw_mci_suspend);
 int dw_mci_resume(struct dw_mci *host)
 {
        int i, ret;
+       u32 regs;
 
        if (host->vmmc) {
                ret = regulator_enable(host->vmmc);
@@ -3040,9 +3155,11 @@ int dw_mci_resume(struct dw_mci *host)
        mci_writel(host, TMOUT, 0xFFFFFFFF);
 
        mci_writel(host, RINTSTS, 0xFFFFFFFF);
-       mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER |
-                  SDMMC_INT_TXDR | SDMMC_INT_RXDR |
-                  DW_MCI_ERROR_FLAGS | SDMMC_INT_CD);
+       regs = SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | SDMMC_INT_TXDR | SDMMC_INT_RXDR |
+                  DW_MCI_ERROR_FLAGS;
+       if(!(host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO))
+           regs |= SDMMC_INT_CD;          
+       mci_writel(host, INTMASK, regs);
        mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE);
 
        for (i = 0; i < host->num_slots; i++) {
old mode 100644 (file)
new mode 100755 (executable)
index e9c0960..ecaee23
@@ -47,7 +47,7 @@ void bcm_wlan_power_on(int flag)
                printk("======== PULL WL_REG_ON HIGH! ========\n");
                rockchip_wifi_power(1);
         msleep(100);
-        rockchip_wifi_set_carddetect();
+        rockchip_wifi_set_carddetect(1);
        } else {
                printk("======== PULL WL_REG_ON HIGH! (flag = %d) ========\n", flag);
                rockchip_wifi_power(1);
old mode 100644 (file)
new mode 100755 (executable)
index 9f3c275..904f3da
@@ -200,6 +200,8 @@ struct gendisk {
        struct blk_integrity *integrity;
 #endif
        int node_id;
+       
+       int emmc_disk;//for emmc devive; added by xbw at 2014-03-22
 };
 
 static inline struct gendisk *part_to_disk(struct hd_struct *part)
index fd2a7075f76547af51f827569f7b31b981eb3bf9..168120afbcd43fee02f54e74e5776641ebffeeae 100755 (executable)
@@ -124,6 +124,7 @@ struct mmc_host_ops {
        void    (*set_ios)(struct mmc_host *host, struct mmc_ios *ios);
        int     (*get_ro)(struct mmc_host *host);
        int     (*get_cd)(struct mmc_host *host);
+       int     (*set_sdio_status)(struct mmc_host *host, int val);//added by xbw,at 2014-03-24
 
        void    (*enable_sdio_irq)(struct mmc_host *host, int enable);
 
index 130b2ec80dbe5cbfa3c11ebfc62d0ad6db3659a4..a2984f83bab9cef8852671e0c0d1345900f1467d 100755 (executable)
@@ -190,6 +190,7 @@ struct dw_mci {
 
        /* Workaround flags */
        u32                     quirks;
+       bool        irq_state;
 
        struct regulator        *vmmc;  /* Power regulator */
        unsigned long           irq_flags; /* IRQ flags */
index 2c1849b284488096fed3bd79b61c6b0a02807253..8711e8afc050d86df29ea4f2ab11c8ec930dbebb 100755 (executable)
@@ -40,7 +40,7 @@ struct rksdmmc_gpio_wifi_moudle {
 
 void *rockchip_mem_prealloc(int section, unsigned long size);
 int rockchip_wifi_power(int on);
-int rockchip_wifi_set_carddetect(void);
+int rockchip_wifi_set_carddetect(int val);
 int rockchip_wifi_get_oob_irq(void);
 int rockchip_wifi_reset(int on);
 int rockchip_wifi_mac_addr(unsigned char *buf);
index 0b449fb9733bd5af535a33df3e6fd8075e3d3571..b87bdd8e08b8aa959fac9f6253d90719da37f69f 100755 (executable)
@@ -268,10 +268,10 @@ EXPORT_SYMBOL(rockchip_wifi_power);
  * Wifi Sdio Detect Func
  *
  *************************************************************************/
-extern int mmc_host_rescan(struct mmc_host *host);
-int rockchip_wifi_set_carddetect(void)
+extern int mmc_host_rescan(struct mmc_host *host, int val);
+int rockchip_wifi_set_carddetect(int val)
 {
-    return mmc_host_rescan(NULL);//NULL => SDIO host
+    return mmc_host_rescan(NULL, val);//NULL => SDIO host
 }
 EXPORT_SYMBOL(rockchip_wifi_set_carddetect);