update mmc stack from linux2.6.35
authorlbt <lbt@rock-chip.com>
Tue, 22 Mar 2011 11:09:19 +0000 (19:09 +0800)
committerlbt <lbt@rock-chip.com>
Tue, 22 Mar 2011 11:13:19 +0000 (19:13 +0800)
    sdio: add quirk to clamp byte mode transfer

    Some SDIO cards expect byte transfers not to exceed the configured block
    transfer size.  Add a quirk to that effect.

drivers/mmc/core/sdio.c
drivers/mmc/core/sdio_io.c
drivers/mmc/host/rk29_sdmmc.c
include/linux/mmc/card.h
include/linux/mmc/host.h

index ac9102487e25886bffe0f82675094036068e707f..a0ea736432a040bab7481ba92491adbec55152fe 100644 (file)
@@ -262,6 +262,13 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
        }
 
        card->type = MMC_TYPE_SDIO;
+        
+         /*
+         * Call the optional HC's init_card function to handle quirks.
+         */
+        if (host->ops->init_card)
+                host->ops->init_card(host, card);
+
 
        /*
         * For native busses:  set card RCA and quit open drain mode.
index 6bb0654a0d4ea49be7261ee414268ed4228c9c67..6c1d8474ce7da9f63d3edf177d122c8433b78353 100755 (executable)
@@ -189,7 +189,12 @@ static inline unsigned int sdio_max_byte_size(struct sdio_func *func)
 {
        unsigned mval = min(func->card->host->max_seg_size,
                            func->card->host->max_blk_size);
-       mval = min(mval, func->max_blksize);
+
+        if (mmc_blksz_for_byte_mode(func->card))
+                mval = min(mval, func->cur_blksize);
+        else
+                mval = min(mval, func->max_blksize);
+
        return min(mval, 512u); /* maximum size for byte mode */
 }
 
index 2af2f30095d14529da77dd5022efd30db3a480b5..f3a62f4c9998049474872ae303cca261ff7196fb 100755 (executable)
@@ -31,6 +31,7 @@
 #include <linux/irq.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/mmc.h>
+#include <linux/mmc/card.h>
 
 #include <mach/board.h>
 #include <mach/rk29_iomap.h>
@@ -704,6 +705,11 @@ static void rk29_sdmmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
        spin_unlock_irqrestore(&host->lock, flags);
 }
 
+static void  rk29_sdmmc_init_card(struct mmc_host *mmc, struct mmc_card *card)
+{
+        card->quirks = MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
+
+}
 static const struct mmc_host_ops rk29_sdmmc_ops[] = {
        {
                .request        = rk29_sdmmc_request,
@@ -715,6 +721,7 @@ static const struct mmc_host_ops rk29_sdmmc_ops[] = {
                .request        = rk29_sdmmc_request,
                .set_ios        = rk29_sdmmc_set_ios,
                .enable_sdio_irq = rk29_sdmmc_enable_sdio_irq,
+                .init_card       = rk29_sdmmc_init_card,
        },
 };
 
index 2ee22e8af11042d9ab266b30300b9a63f9e7d61a..590a7e8043ba6c99909d8fdb9b64824904fde39c 100644 (file)
@@ -99,6 +99,7 @@ struct mmc_card {
 #define MMC_STATE_BLOCKADDR    (1<<3)          /* card uses block-addressing */
        unsigned int            quirks;         /* card quirks */
 #define MMC_QUIRK_LENIENT_FN0  (1<<0)          /* allow SDIO FN0 writes outside of the VS CCCR range */
+#define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1)    /* use func->cur_blksize */
 
        u32                     raw_cid[4];     /* raw card CID */
        u32                     raw_csd[4];     /* raw card CSD */
@@ -139,6 +140,11 @@ static inline int mmc_card_lenient_fn0(const struct mmc_card *c)
        return c->quirks & MMC_QUIRK_LENIENT_FN0;
 }
 
+static inline int mmc_blksz_for_byte_mode(const struct mmc_card *c)
+{
+        return c->quirks & MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
+}
+
 #define mmc_card_name(c)       ((c)->cid.prod_name)
 #define mmc_card_id(c)         (dev_name(&(c)->dev))
 
index c3b88ff5654f47b6a368b472c5b95502d7f253ff..6c731a48c962c1429beee283dd2a752d3be813ee 100644 (file)
@@ -107,6 +107,9 @@ struct mmc_host_ops {
        int     (*get_cd)(struct mmc_host *host);
 
        void    (*enable_sdio_irq)(struct mmc_host *host, int enable);
+        
+        /* optional callback for HC quirks */
+        void    (*init_card)(struct mmc_host *host, struct mmc_card *card);
 };
 
 struct mmc_card;