Integrae the XBW-version of SDMMC-drver into RK29SDK, and the xbw-version is set...
authorxbw <xbw@rock-chips.com>
Mon, 18 Jul 2011 03:41:08 +0000 (20:41 -0700)
committerxbw <xbw@rock-chips.com>
Mon, 18 Jul 2011 03:41:08 +0000 (20:41 -0700)
14 files changed:
arch/arm/mach-rk29/board-rk29sdk.c
drivers/mmc/card/block.c
drivers/mmc/core/bus.c
drivers/mmc/core/core.c
drivers/mmc/core/host.c
drivers/mmc/core/mmc.c
drivers/mmc/core/sd.c
drivers/mmc/core/sdio.c
drivers/mmc/host/Kconfig
drivers/mmc/host/Makefile
fs/partitions/check.c
fs/partitions/msdos.c
include/linux/mmc/host.h
include/linux/mmc/mmc.h

index a9867898e0ccc177f7a1e93526406ecd31be2480..9058b26641d3ecab90076456806befd5e9ab2ac1 100755 (executable)
@@ -1011,7 +1011,13 @@ static int rk29_sdmmc0_cfg_gpio(void)
        rk29_mux_api_set(GPIO1D3_SDMMC0DATA1_NAME, GPIO1H_SDMMC0_DATA1);
        rk29_mux_api_set(GPIO1D4_SDMMC0DATA2_NAME, GPIO1H_SDMMC0_DATA2);
        rk29_mux_api_set(GPIO1D5_SDMMC0DATA3_NAME, GPIO1H_SDMMC0_DATA3);
+
+#ifdef CONFIG_SDMMC_RK29_OLD   
        rk29_mux_api_set(GPIO2A2_SDMMC0DETECTN_NAME, GPIO2L_GPIO2A2);
+#else
+       rk29_mux_api_set(GPIO2A2_SDMMC0DETECTN_NAME, GPIO2L_SDMMC0_DETECT_N);//Modifyed by xbw.
+#endif
+
        rk29_mux_api_set(GPIO5D5_SDMMC0PWREN_NAME, GPIO5H_GPIO5D5);   ///GPIO5H_SDMMC0_PWR_EN);  ///GPIO5H_GPIO5D5);
        gpio_request(RK29_PIN5_PD5,"sdmmc");
 #if 0
index 98f74b0087b5b6d8de81b800622ee594c76246d1..23a0e3f20d7e7d0669d66da6e1e784ddf657dffb 100644 (file)
 
 MODULE_ALIAS("mmc:block");
 
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
+static DEFINE_MUTEX(block_mutex); //added by xbw at 2011-04-21
+#endif
+
 /*
  * max 8 partitions per card
  */
@@ -105,6 +109,10 @@ static int mmc_blk_open(struct block_device *bdev, fmode_t mode)
 {
        struct mmc_blk_data *md = mmc_blk_get(bdev->bd_disk);
        int ret = -ENXIO;
+       
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
+       mutex_lock(&block_mutex); //added by xbw at 2011-04-21
+#endif
 
        if (md) {
                if (md->usage == 2)
@@ -116,6 +124,9 @@ static int mmc_blk_open(struct block_device *bdev, fmode_t mode)
                        ret = -EROFS;
                }
        }
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
+       mutex_unlock(&block_mutex);
+#endif 
 
        return ret;
 }
@@ -123,8 +134,17 @@ static int mmc_blk_open(struct block_device *bdev, fmode_t mode)
 static int mmc_blk_release(struct gendisk *disk, fmode_t mode)
 {
        struct mmc_blk_data *md = disk->private_data;
+       
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
+       mutex_lock(&block_mutex); //added by xbw at 2011-04-21
+#endif
 
        mmc_blk_put(md);
+
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)      
+       mutex_unlock(&block_mutex);
+#endif
+
        return 0;
 }
 
@@ -224,6 +244,13 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card)
        return result;
 }
 
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) //Deleted by xbw@2011-03-21
+//static u32 get_card_status(struct mmc_card *card, struct request *req)
+//{
+//   return 0;
+//}
+
+#else
 static u32 get_card_status(struct mmc_card *card, struct request *req)
 {
        struct mmc_command cmd;
@@ -240,6 +267,7 @@ static u32 get_card_status(struct mmc_card *card, struct request *req)
                       req->rq_disk->disk_name, err);
        return cmd.resp[0];
 }
+#endif
 
 static int
 mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card)
@@ -285,13 +313,22 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
        mmc_claim_host(card->host);
 
        do {
-               struct mmc_command cmd;
+           #if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) 
+               //struct mmc_command cmd;//Deleted by xbw@2011-03-21
+               #else
+               struct mmc_command cmd; 
+               #endif
+               
                u32 readcmd, writecmd, status = 0;
 
                memset(&brq, 0, sizeof(struct mmc_blk_request));
                brq.mrq.cmd = &brq.cmd;
                brq.mrq.data = &brq.data;
-
+               
+               #if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
+               brq.cmd.retries = 2; //suppot retry read-write; added by xbw@2011-03-21
+        #endif
+        
                brq.cmd.arg = blk_rq_pos(req);
                if (!mmc_card_blockaddr(card))
                        brq.cmd.arg <<= 9;
@@ -371,6 +408,11 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
 
                mmc_queue_bounce_post(mq);
 
+        #if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) 
+        //not turn CMD18 to CMD17. deleted by xbw at 2011-04-21
+
+        #else
+
                /*
                 * Check for errors here, but don't jump to cmd_err
                 * until later as we need to wait for the card to leave
@@ -387,7 +429,8 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
                        status = get_card_status(card, req);
                } else if (disable_multi == 1) {
                        disable_multi = 0;
-               }
+               }   
+        #endif
 
                if (brq.cmd.error) {
                        printk(KERN_DEBUG "%s: error %d sending read/write "
@@ -414,6 +457,10 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
                               brq.stop.resp[0], status);
                }
 
+ #if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)  
+ //Deleted by xbw@2011-03-21
+
+ #else
                if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
                        do {
                                int err;
@@ -443,8 +490,9 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
                                goto cmd_err;
 #endif
                }
+#endif         
 
-               if (brq.cmd.error || brq.stop.error || brq.data.error) {
+               if (brq.cmd.error || brq.stop.error || brq.data.error) {                
                        if (rq_data_dir(req) == READ) {
                                /*
                                 * After an error, we redo I/O one sector at a
@@ -572,6 +620,11 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
 
        sprintf(md->disk->disk_name, "mmcblk%d", devidx);
 
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)  
+       printk("%s..%d **** devidx=%d, dev_use[0]=%lu, disk_name=%s *** ==xbw[%s]==\n",\
+           __FUNCTION__,__LINE__, devidx, dev_use[0], md->disk->disk_name,mmc_hostname(card->host));
+#endif
+    
        blk_queue_logical_block_size(md->queue.queue, 512);
 
        if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) {
index 812b22035626e27ada163564a701d029f09c70a6..ab9a939963d860dfeaa740ea15a08d5893f14628 100755 (executable)
@@ -279,7 +279,9 @@ void mmc_remove_card(struct mmc_card *card)
 #endif
 
        if (mmc_card_present(card)) {
+#if defined(CONFIG_SDMMC_RK29) && defined(CONFIG_SDMMC_RK29_OLD)
                mmc_card_clr_present(card);
+#endif         
                if (mmc_host_is_spi(card->host)) {
                        printk(KERN_INFO "%s: SPI card removed\n",
                                mmc_hostname(card->host));
index 5148f8e5ea71b086b6bad57195b01d7d3d0a15ce..dd2a7a006438ab1b6697b77aadf880362a950124 100644 (file)
@@ -202,7 +202,11 @@ void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
 
        mmc_start_request(host, mrq);
 
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
+    wait_for_completion_timeout(&complete,HZ*3); //for cmd dead. Modifyed by xbw at 2011-06-02
+#else    
        wait_for_completion(&complete);
+#endif
 }
 
 EXPORT_SYMBOL(mmc_wait_for_req);
@@ -1059,7 +1063,155 @@ void mmc_detect_change(struct mmc_host *host, unsigned long delay)
 
 EXPORT_SYMBOL(mmc_detect_change);
 
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)  
+void mmc_rescan(struct work_struct *work)
+{
+       struct mmc_host *host =
+               container_of(work, struct mmc_host, detect.work);
+       u32 ocr;
+       int err;
+       int extend_wakelock = 0;
+
+    
+       mmc_bus_get(host);
+
+       /* if there is a card registered, check whether it is still present */
+       if ((host->bus_ops != NULL) && host->bus_ops->detect && !host->bus_dead)
+               host->bus_ops->detect(host);
+
+       /* If the card was removed the bus will be marked
+        * as dead - extend the wakelock so userspace
+        * can respond */
+       if (host->bus_dead)
+               extend_wakelock = 1;
+
+       mmc_bus_put(host);
+
+
+       mmc_bus_get(host);
+
+       /* if there still is a card present, stop here */
+       if (host->bus_ops != NULL) {
+               mmc_bus_put(host);
+               goto out;
+       }
+
+       /* detect a newly inserted card */
+
+       /*
+        * Only we can add a new handler, so it's safe to
+        * release the lock here.
+        */
+       mmc_bus_put(host);
+    printk("\n%s...%d..  ===== mmc_rescan Begin....======xbw[%s]=====\n",__FILE__, __LINE__, mmc_hostname(host));
+
+       if (host->ops->get_cd && host->ops->get_cd(host) == 0)
+       {
+           printk("\n=================\n%s..%d..  ====find no SDMMC host.====xbw[%s]=====\n", \
+               __FUNCTION__, __LINE__, mmc_hostname(host));
+               
+               goto out;
+       }
+
+       mmc_claim_host(host);
+       
+       mmc_power_up(host);
+       
+       mmc_go_idle(host);
+
+    /*
+        In oder to improve the initialization process in rockchip IC, I modify the following code about the the initialization process of SDIO-SD-MMC.
+        So I deleted the CMD8 and add a conditional to distinguish between the two card type,i.e.SDMMC process and SDIO process.
+        For detail,please refer to "RK29XX Technical Reference Manual" and "SD-MMC-SDIO Specifications".
+        Noted by xbw@2011-04-09
+    */
+
+    //mmc_send_if_cond(host, host->ocr_avail); //deleted by xbw@2011-04-09
+
+     if( strncmp( mmc_hostname(host) ,"mmc0" , strlen("mmc0")) ){
+       /*
+        * First we search for SDIO...
+        */
+       err = mmc_send_io_op_cond(host, 0, &ocr);
+       if (!err) {
+               printk("\n%s..%d..  ===== Begin to identify card as SDIO-card===xbw[%s]===\n",__FUNCTION__, __LINE__, mmc_hostname(host));
+
+               if (mmc_attach_sdio(host, ocr))
+               {
+                   printk("\n=====\n %s..%d..  ===== Initialize SDIO-card unsuccessfully!!! ===xbw[%s]===\n=====\n",\
+                       __FUNCTION__,  __LINE__, mmc_hostname(host));
+                       
+                       mmc_power_off(host);
+               }
+               else
+               {
+                   printk("%s..%d..  ===== Initialize SDIO successfully. ===xbw[%s]===\n",__FUNCTION__,  __LINE__, mmc_hostname(host));
+               }
+               extend_wakelock = 1;
+               goto out;
+       }
+    }
+
+
+    /*
+     * ...then normal SD...
+     */
+    err = mmc_send_app_op_cond(host, 0, &ocr);
+    if (!err) {
+       printk("\n%s..%d..  ===== Begin to identify card as SD-card ===xbw[%s]===\n",__FUNCTION__, __LINE__, mmc_hostname(host));
+
+       if (mmc_attach_sd(host, ocr))
+       {
+           printk("\n=====\n%s..%d..  ===== Initialize SD-card unsuccessfully!!! ===xbw[%s]===\n====\n",\
+               __FUNCTION__,  __LINE__, mmc_hostname(host));
+               
+               mmc_power_off(host);
+       }
+       else
+       {
+           printk("%s..%d..  ===== Initialize SD-card successfully. ===xbw[%s]===\n",__FUNCTION__,  __LINE__, mmc_hostname(host));
+       }
+       extend_wakelock = 1;
+       goto out;
+    }
+
+    /*
+     * ...and finally MMC.
+     */
+    err = mmc_send_op_cond(host, 0, &ocr);
+    if (!err) {
+        printk("\n%s..%d..  ===== Begin to identify card as MMC-card ===xbw[%s]===\n", __FUNCTION__, __LINE__, mmc_hostname(host));
+
+       if (mmc_attach_mmc(host, ocr))
+       {
+           printk("\n =====\n%s..%d..  ===== Initialize MMC-card unsuccessfully!!! ===xbw[%s]===\n======\n",\
+               __FUNCTION__,  __LINE__, mmc_hostname(host));
+               
+               mmc_power_off(host);
+       }
+       else
+       {
+           printk("%s...%d..  ===== Initialize MMC-card successfully. ===xbw[%s]===\n",__FUNCTION__,  __LINE__, mmc_hostname(host));
+       }
+       extend_wakelock = 1;
+       goto out;
+    }
+
+       mmc_release_host(host);
+       mmc_power_off(host);
+
+out:
+
+       if (extend_wakelock)
+               wake_lock_timeout(&mmc_delayed_work_wake_lock, HZ / 2);
+       else
+               wake_unlock(&mmc_delayed_work_wake_lock);
+
+       if (host->caps & MMC_CAP_NEEDS_POLL)
+               mmc_schedule_delayed_work(&host->detect, HZ);
+}
 
+#else
 void mmc_rescan(struct work_struct *work)
 {
        struct mmc_host *host =
@@ -1067,6 +1219,8 @@ void mmc_rescan(struct work_struct *work)
        u32 ocr;
        int err;
        int extend_wakelock = 0;
+       
+#if defined(CONFIG_SDMMC_RK29) && defined(CONFIG_SDMMC_RK29_OLD)       
        unsigned long flags;
 
        spin_lock_irqsave(&host->lock, flags);
@@ -1077,6 +1231,7 @@ void mmc_rescan(struct work_struct *work)
        }
 
        spin_unlock_irqrestore(&host->lock, flags);
+#endif
 
 
        mmc_bus_get(host);
@@ -1165,6 +1320,7 @@ out:
        if (host->caps & MMC_CAP_NEEDS_POLL)
                mmc_schedule_delayed_work(&host->detect, HZ);
 }
+#endif
 
 void mmc_start_host(struct mmc_host *host)
 {
@@ -1301,6 +1457,23 @@ int mmc_suspend_host(struct mmc_host *host, pm_message_t state)
        if (host->bus_ops && !host->bus_dead) {
                if (host->bus_ops->suspend)
                        err = host->bus_ops->suspend(host);
+                       
+#if defined(CONFIG_SDMMC_RK29) && defined(CONFIG_SDMMC_RK29_OLD)
+        //deleted all detail code.
+#else
+               if (err == -ENOSYS || !host->bus_ops->resume) {
+                       /*
+                        * We simply "remove" the card in this case.
+                        * It will be redetected on resume.
+                        */
+                       if (host->bus_ops->remove)
+                               host->bus_ops->remove(host);
+                       mmc_claim_host(host);
+                       mmc_detach_bus(host);
+                       mmc_release_host(host);
+                       err = 0;
+               }
+#endif         
        }
        mmc_bus_put(host);
 
@@ -1331,6 +1504,8 @@ int mmc_resume_host(struct mmc_host *host)
                mmc_power_up(host);
                mmc_select_voltage(host, host->ocr);
                BUG_ON(!host->bus_ops->resume);
+               
+#if defined(CONFIG_SDMMC_RK29) && defined(CONFIG_SDMMC_RK29_OLD)
                err = host->bus_ops->resume(host);
                if (err) {
                        printk(KERN_WARNING "%s: error %d during resume "
@@ -1338,13 +1513,44 @@ int mmc_resume_host(struct mmc_host *host)
                                            mmc_hostname(host), err);
                        err = 0;
                }
+
+#elif defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)  
+        //panic if the card is being removed during the resume, deleted by xbw at 2011-06-20
+               host->bus_ops->resume(host);
+
+#else
+               err = host->bus_ops->resume(host);
+               if (err) {
+                       printk(KERN_WARNING "%s: error %d during resume "
+                                           "(card was removed?)\n",
+                                           mmc_hostname(host), err);
+                       if (host->bus_ops->remove)
+                               host->bus_ops->remove(host);
+                       mmc_claim_host(host);
+                       mmc_detach_bus(host);
+                       mmc_release_host(host);
+                       /* no need to bother upper layers */
+                       err = 0;
+               }               
+#endif
        }
        mmc_bus_put(host);
 
+#if defined(CONFIG_SDMMC_RK29) && defined(CONFIG_SDMMC_RK29_OLD)
+    //delete the detect_change.
+#else
+       /*
+        * We add a slight delay here so that resume can progress
+        * in parallel.
+        */
+       mmc_detect_change(host, 1);
+#endif
        return err;
 }
 EXPORT_SYMBOL(mmc_resume_host);
 
+///old driver add the function reforming to kernel2.6.38
+#if defined(CONFIG_SDMMC_RK29) && defined(CONFIG_SDMMC_RK29_OLD) 
 /* Do the card removal on suspend if card is assumed removeable
  * Do that in pm notifier while userspace isn't yet frozen, so we will be able
    to sync the card.
@@ -1390,6 +1596,8 @@ int mmc_pm_notify(struct notifier_block *notify_block,
 
        return 0;
 }
+#endif// endif---defined(CONFIG_SDMMC_RK29) && defined(CONFIG_SDMMC_RK29_OLD) 
+
 #endif
 
 #ifdef CONFIG_MMC_EMBEDDED_SDIO
index 94f35ca5c413b39677c19540aaef65aa37456821..07b4d72f27fed55ef32aa1349545e426d9fe1dd3 100644 (file)
@@ -16,8 +16,9 @@
 #include <linux/idr.h>
 #include <linux/pagemap.h>
 #include <linux/leds.h>
+#if defined(CONFIG_SDMMC_RK29) && defined(CONFIG_SDMMC_RK29_OLD)  
 #include <linux/suspend.h>
-
+#endif
 #include <linux/mmc/host.h>
 
 #include "core.h"
@@ -85,8 +86,10 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
        init_waitqueue_head(&host->wq);
        INIT_DELAYED_WORK(&host->detect, mmc_rescan);
        INIT_DELAYED_WORK_DEFERRABLE(&host->disable, mmc_host_deeper_disable);
+#if defined(CONFIG_SDMMC_RK29) && defined(CONFIG_SDMMC_RK29_OLD)  // old driver, add pm reform to kernel2.6.38 
 #ifdef CONFIG_PM
        host->pm_notify.notifier_call = mmc_pm_notify;
+#endif
 #endif
 
        /*
@@ -136,8 +139,11 @@ int mmc_add_host(struct mmc_host *host)
 #endif
 
        mmc_start_host(host);
+
+#if defined(CONFIG_SDMMC_RK29) && defined(CONFIG_SDMMC_RK29_OLD)  // old driver, add pm reform to kernel2.6.38         
         if (!(host->pm_flags & MMC_PM_IGNORE_PM_NOTIFY))
           register_pm_notifier(&host->pm_notify);
+#endif
 
        return 0;
 }
@@ -154,8 +160,11 @@ EXPORT_SYMBOL(mmc_add_host);
  */
 void mmc_remove_host(struct mmc_host *host)
 {
+#if defined(CONFIG_SDMMC_RK29) && defined(CONFIG_SDMMC_RK29_OLD)  // old driver, add pm reform to kernel2.6.38 
         if (!(host->pm_flags & MMC_PM_IGNORE_PM_NOTIFY))       
            unregister_pm_notifier(&host->pm_notify);
+ #endif
        mmc_stop_host(host);
 
 #ifdef CONFIG_DEBUG_FS
index 32af45c419f449d2f1cc9f07d058d667306a61a8..b6f8867fa07688f2dbc37f34187d66f1c028018c 100644 (file)
@@ -321,7 +321,13 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
        /* The extra bit indicates that we support high capacity */
        err = mmc_send_op_cond(host, ocr | (1 << 30), NULL);
        if (err)
+       {
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) 
+           printk("%s..%d..  ====*Identify the card as MMC , but OCR error, so fail to initialize.===xbw[%s]===\n",\
+               __FUNCTION__, __LINE__, mmc_hostname(host));
+#endif         
                goto err;
+       }
 
        /*
         * For SPI, enable CRC as appropriate.
@@ -438,6 +444,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                if (max_dtr > card->ext_csd.hs_max_dtr)
                        max_dtr = card->ext_csd.hs_max_dtr;
        } else if (max_dtr > card->csd.max_dtr) {
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
+        //in order to expand the compatibility of card. Added by xbw@2011-03-21
+               card->csd.max_dtr = (card->csd.max_dtr > MMC_FPP_FREQ) ? MMC_FPP_FREQ : (card->csd.max_dtr); 
+#endif
                max_dtr = card->csd.max_dtr;
        }
 
@@ -660,6 +670,9 @@ static void mmc_attach_bus_ops(struct mmc_host *host)
 int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
 {
        int err;
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)      
+       int retry_times = 3;
+#endif 
 
        BUG_ON(!host);
        WARN_ON(!host->claimed);
@@ -704,10 +717,33 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
                goto err;
 
        mmc_release_host(host);
-
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
+//modifyed by xbw at 2011--04-11
+Retry_add:
        err = mmc_add_card(host->card);
        if (err)
+       {
+           //retry add the card; Added by xbw
+        if((--retry_times >= 0))
+        {        
+            printk("\n%s..%s..%d   ****error in add partition, so retry.  ===xbw[%s]===\n",__FUNCTION__,__FILE__,__LINE__, mmc_hostname(host));   
+            /* sleep some time */
+            set_current_state(TASK_INTERRUPTIBLE);
+            schedule_timeout(HZ/2);
+            
+            goto Retry_add;
+        }
+
                goto remove_card;
+    
+       }
+#else
+    err = mmc_add_card(host->card);
+       if (err)
+               goto remove_card;
+#endif
+               
 
        return 0;
 
index 8fe5e9ece251634762e6dfba96523ed9494f55fe..cae635fc8ed804cf489a9ac72660235ffabd1ec9 100755 (executable)
@@ -362,7 +362,13 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
 
        err = mmc_send_app_op_cond(host, ocr, NULL);
        if (err)
+       {
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)      
+           printk("%s..%d..  ====*Identify the card as SD , but OCR error, so fail to initialize.===xbw[%s]===\n", \
+               __FUNCTION__, __LINE__, mmc_hostname(host));
+#endif         
                goto err;
+       }
 
        /*
         * Fetch CID from card.
@@ -458,6 +464,13 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
                                printk(KERN_WARNING
                                       "%s: read switch failed (attempt %d)\n",
                                       mmc_hostname(host), retries);
+
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)                                      
+                               if(0 == host->re_initialized_flags)
+                               {
+                                        break; //Added by xbw at 2011-06-21
+                               } 
+#endif                         
                        }
                }
 #else
@@ -496,6 +509,11 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
                if (max_dtr > card->sw_caps.hs_max_dtr)
                        max_dtr = card->sw_caps.hs_max_dtr;
        } else if (max_dtr > card->csd.max_dtr) {
+
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) 
+        //in order to expand the compatibility of card. Added by xbw@2011-03-21
+           card->csd.max_dtr = (card->csd.max_dtr > SD_FPP_FREQ) ? SD_FPP_FREQ : (card->csd.max_dtr); 
+#endif
                max_dtr = card->csd.max_dtr;
        }
 
@@ -576,6 +594,15 @@ static void mmc_sd_detect(struct mmc_host *host)
                err = mmc_send_status(host->card, NULL);
                if (err) {
                        retries--;
+
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)                
+                 if(0 == host->re_initialized_flags)
+                       {
+                                retries = 0;
+                                break; //Added by xbw at 2011-06-21
+                       }
+#endif                 
+                       
                        udelay(5);
                        continue;
                }
@@ -643,6 +670,13 @@ static int mmc_sd_resume(struct mmc_host *host)
                               mmc_hostname(host), err, retries);
                        mdelay(5);
                        retries--;
+                       
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)                                              
+                       if(0 == host->re_initialized_flags)
+                       {
+                                break; //Added by xbw at 2011-06-21
+                       }
+#endif                 
                        continue;
                }
                break;
@@ -715,6 +749,10 @@ static void mmc_sd_attach_bus_ops(struct mmc_host *host)
 int mmc_attach_sd(struct mmc_host *host, u32 ocr)
 {
        int err;
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)      
+       int retry_times = 3;
+#endif 
+       
 #ifdef CONFIG_MMC_PARANOID_SD_INIT
        int retries;
 #endif
@@ -772,6 +810,14 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr)
                err = mmc_sd_init_card(host, host->ocr, NULL);
                if (err) {
                        retries--;
+
+       #if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)               
+                       if(0 == host->re_initialized_flags)
+                       {
+                                retries = 0;
+                                break; //Added by xbw at 2011-06-21
+                       }
+       #endif          
                        continue;
                }
                break;
@@ -790,9 +836,31 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr)
 
        mmc_release_host(host);
 
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) 
+//modifyed by xbw at 2011--04-11
+Retry_add:
        err = mmc_add_card(host->card);
+       if (err)
+       {
+           //retry add the card; Added by xbw
+        if((--retry_times >= 0))
+        {        
+            printk("\n%s..%s..%d   ****error in add partition, so retry.  ===xbw[%s]===\n",__FUNCTION__,__FILE__,__LINE__, mmc_hostname(host));   
+            /* sleep some time */
+            set_current_state(TASK_INTERRUPTIBLE);
+            schedule_timeout(HZ/2);
+            
+            goto Retry_add;
+        }
+
+               goto remove_card;
+    
+       }
+#else
+    err = mmc_add_card(host->card);
        if (err)
                goto remove_card;
+#endif 
 
        return 0;
 
index 21fffa2094bd996ef46903e0493c9cdd13d46e2c..7280140bfea7f199d4a736f29c000f1ace655951 100644 (file)
@@ -241,7 +241,13 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
         */
        err = mmc_send_io_op_cond(host, host->ocr, &ocr);
        if (err)
+       {
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)      
+           printk("%s..%d..  ====*Identify the card as SDIO , but OCR error, so fail to initialize.===xbw[%s]===\n", \
+               __FUNCTION__, __LINE__, mmc_hostname(host));
+#endif         
                goto err;
+       }
 
        /*
         * For SPI, enable CRC as appropriate.
@@ -278,6 +284,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
                if (err)
                        goto remove;
 
+#if defined(CONFIG_SDMMC_RK29) && defined(CONFIG_SDMMC_RK29_OLD)  //old driver add the code ,reform to kernel2.6.38  
                /*
                 * Update oldcard with the new RCA received from the SDIO
                 * device -- we're doing this so that it's updated in the
@@ -285,6 +292,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
                 */
                if (oldcard)
                        oldcard->rca = card->rca;
+#endif
 
                mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
        }
index fa8f13bb5444278a9637c99e128485525de1ca9d..fd98a80234f366ac9ee71464d28b1e1642e2c5a5 100644 (file)
@@ -35,18 +35,24 @@ config SDMMC_RK29
                SDMMC0 used for sd/mmc card, and SDMMC1 used for sdio.
 if SDMMC_RK29
     comment "Now, there are two SDMMC controllers selected, SDMMC0 and SDMMC1."
+       config SDMMC_RK29_OLD
+               bool "Old driver (DEPRECATED)"
+               help
+                        You will select old,origin driver for your project if you say Yes.
+                        It is not good to select the driver.
+
        config SDMMC0_RK29
                tristate "RK29 SDMMC0 controller support(sdmmc)"
                default y
                depends on ARCH_RK29 
                help
                        This supports the use of the SDMMC0 controller on Rk29 processors.
-       config EMMC_RK29
-               tristate "RK29 EMMC controller support(sdmmc)"
-               default y
-               depends on SDMMC0_RK29
-               help
-                       This supports the use of the EMMC controller on Rk29 processors.
+#      config EMMC_RK29
+#              tristate "RK29 EMMC controller support(sdmmc)"
+#              default y
+#              depends on SDMMC0_RK29
+#              help
+#                      This supports the use of the EMMC controller on Rk29 processors.
        config SDMMC1_RK29
                tristate "RK29 SDMMC1 controller support(sdio)"
                default y
index 8230c5f949b1908db5fd4956d88ebd47e521148a..1fdec539bbea14ecf665c063bb11464ee286d3af 100644 (file)
@@ -6,7 +6,12 @@ ifeq ($(CONFIG_MMC_DEBUG),y)
        EXTRA_CFLAGS            += -DDEBUG
 endif
 
+ifeq ($(CONFIG_SDMMC_RK29_OLD),y)
+obj-$(CONFIG_SDMMC_RK29)       += rk29_sdmmc_old.o
+else
 obj-$(CONFIG_SDMMC_RK29)       += rk29_sdmmc.o
+endif
+
 obj-$(CONFIG_SDMMC_RK2818)     += rk2818-sdmmc.o
 obj-$(CONFIG_MMC_ARMMMCI)      += mmci.o
 obj-$(CONFIG_MMC_PXA)          += pxamci.o
index 5689a0a889a9a936335b94280efff4cb61f0dabc..934637a9a6dac2bd196dcd495b015d916712ed80 100644 (file)
@@ -541,7 +541,16 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
        int p, highest, res;
 
        if (bdev->bd_part_count)
+       {
+       #if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) 
+           if(179 == MAJOR(bdev->bd_dev))
+           {
+               printk("%s..%d.. The sdcard partition have been using.So device busy! ====xbw===\n",__FUNCTION__, __LINE__);
+           }
+       #endif    
+           
                return -EBUSY;
+       }
        res = invalidate_partition(disk, 0);
        if (res)
                return res;
@@ -556,7 +565,15 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
        check_disk_size_change(disk, bdev);
        bdev->bd_invalidated = 0;
        if (!get_capacity(disk) || !(state = check_partition(disk, bdev)))
+       {
+       #if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) 
+           if(179 == MAJOR(bdev->bd_dev))
+           {
+               printk("%s..%d... ==== check partition fail. partitionAddr=%x ====xbw===\n",__FUNCTION__, __LINE__, state);
+           }
+        #endif             
                return 0;
+       }
        if (IS_ERR(state))      /* I/O error reading the partition table */
                return -EIO;
 
index 90be97f1f5a8c8ce5cf737c3e52020e0e516a291..630cd66c4e6d3e7b41b51bb8ca4197ecd610e525 100644 (file)
@@ -440,6 +440,13 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
                return 0;
        }
 
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) 
+    if(179 == MAJOR(bdev->bd_dev))
+    {
+           printk("\n%s..%d... ==== Begin to parse sdcard-partition.  ====xbw[mmc0]===\n",__FUNCTION__, __LINE__);
+       }
+#endif
+
        /*
         * Now that the 55aa signature is present, this is probably
         * either the boot sector of a FAT filesystem or a DOS-type
@@ -449,6 +456,12 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
        p = (struct partition *) (data + 0x1be);
        for (slot = 1; slot <= 4; slot++, p++) {
                if (p->boot_ind != 0 && p->boot_ind != 0x80) {
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) 
+                   if(179 == MAJOR(bdev->bd_dev))
+                   {
+                           printk("%s..%d... ==== The sdcard has not MBR.  ====xbw[mmc0]===\n",__FUNCTION__, __LINE__);
+                       }
+#endif
                        /*
                         * Even without a valid boot inidicator value
                         * its still possible this is valid FAT filesystem
@@ -459,9 +472,21 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
                                && fat_valid_media(fb->media)) {
                                printk("\n");
                                put_dev_sector(sect);
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) 
+                               if(179 == MAJOR(bdev->bd_dev))
+                               {
+                                   printk("%s..%d... ==== The DBR(slot=%d) is valid. ====xbw[mmc0]===\n",__FUNCTION__, __LINE__, slot);
+                               }
+#endif
                                return 1;
                        } else {
                                put_dev_sector(sect);
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) 
+                               if(179 == MAJOR(bdev->bd_dev))
+                               {
+                                   printk("%s..%d... ==== The DBR is invalid. ====xbw[mmc0]===\n",__FUNCTION__, __LINE__);
+                               }
+#endif
                                return 0;
                        }
                }
@@ -484,13 +509,25 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
         * First find the primary and DOS-type extended partitions.
         * On the second pass look inside *BSD, Unixware and Solaris partitions.
         */
-
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) 
+    if(179 == MAJOR(bdev->bd_dev))
+    {
+        printk("%s..%d... ==== The sdcard has MBR. ====xbw[mmc0]===\n", __FUNCTION__, __LINE__);
+    }
+#endif    
        state->next = 5;
        for (slot = 1 ; slot <= 4 ; slot++, p++) {
                sector_t start = start_sect(p)*sector_size;
                sector_t size = nr_sects(p)*sector_size;
                if (!size)
                        continue;
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) 
+           if(179 == MAJOR(bdev->bd_dev))
+           {
+                   printk("%s..%d... ==== partition-%d, size=%luKB  ====xbw[mmc0]===\n",\
+                       __FUNCTION__, __LINE__, slot, size/2);
+               }
+#endif 
                if (is_extended_partition(p)) {
                        /*
                         * prevent someone doing mkfs or mkswap on an
@@ -500,6 +537,12 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
                         */
                        sector_t n = 2;
                        n = min(size, max(sector_size, n));
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)                      
+            if(179 == MAJOR(bdev->bd_dev))
+            {
+                           printk("%s...%d... ==== extend partition-%d....====xbw[mmc0]===\n",__FUNCTION__, __LINE__, slot);
+                       }
+#endif                 
                        put_partition(state, slot, start, n);
 
                        printk(" <");
@@ -507,6 +550,12 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
                        printk(" >");
                        continue;
                }
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) 
+               if(179 == MAJOR(bdev->bd_dev))
+               {
+                   printk("%s..%d... ==== main partition-%d....====xbw[mmc0]===\n",__FUNCTION__, __LINE__, slot);
+               }
+#endif         
                put_partition(state, slot, start, size);
                if (SYS_IND(p) == LINUX_RAID_PARTITION)
                        state->parts[slot].flags = 1;
index 01f21a50a2bf6c21bac992b8336ee5d006e25cc8..f19c1cf7a66f4cb2aaf6d749c1b866f2a9e0bf37 100644 (file)
@@ -203,6 +203,8 @@ struct mmc_host {
 #define MMC_BUSRESUME_MANUAL_RESUME    (1 << 0)
 #define MMC_BUSRESUME_NEEDS_RESUME     (1 << 1)
 
+    unsigned int               re_initialized_flags; //in order to begin the rescan ;  added by xbw@2011-04-07
+
        unsigned int            sdio_irqs;
        struct task_struct      *sdio_irq_thread;
        atomic_t                sdio_irq_thread_abort;
index c02c8db737011c848499c43580b64632980ff404..b96f110efbb47a0c67841fc9eefe841787e0887a 100644 (file)
@@ -282,5 +282,18 @@ struct _mmc_csd {
 #define MMC_SWITCH_MODE_CLEAR_BITS     0x02    /* Clear bits which are 1 in value */
 #define MMC_SWITCH_MODE_WRITE_BYTE     0x03    /* Set target to value */
 
+
+/*
+* some limit value of SDMMC about protocol  ; Added by xbw at 2011-03-21
+*/
+#define FOD_FREQ              (300000)    //  in the identify stage, unit: hz,  max is 400Khz,
+                                       //  the least frequency is FREQ_HCLK_MAX/8
+#define SD_FPP_FREQ           (24000000)  //   normal sd freq,  25Mhz
+#define SDHC_FPP_FREQ         (49000000)  // SDHC in the highspeed. unit is hz,  max is 50Mhz.
+#define MMC_FPP_FREQ          (19000000)  // MMC freq, unit is hz,   max is 20MHz
+#define MMCHS_26_FPP_FREQ     (24000000)  //  highspeed mode support 26M  HS-MMC, unit is hz, max is 26Mhz, 
+#define MMCHS_52_FPP_FREQ     (49000000)  //  highspeed support 52M HS-MMC,   unit is hz,   max is 52Mhz,
+
+
 #endif  /* MMC_MMC_PROTOCOL_H */