Second try. It turns out I was just masking a problem and these particular cards can't run faster than /5 for f_max:

diff --git a/drivers/mfd/glamo/Kconfig b/drivers/mfd/glamo/Kconfig
index 86a7c40..7317807 100644
--- a/drivers/mfd/glamo/Kconfig
+++ b/drivers/mfd/glamo/Kconfig
@@ -36,6 +36,7 @@ config MFD_GLAMO_SPI_FB
config MFD_GLAMO_MCI
        tristate "Glamo S3C SD/MMC Card Interface support"
        depends on MFD_GLAMO && MMC
+       select CRC7
        help
          This selects a driver for the MCI interface found in
          the S-Media GLAMO chip, as used in Openmoko
diff --git a/drivers/mfd/glamo/glamo-mci.c b/drivers/mfd/glamo/glamo-mci.c
index 789352d..9eaba86 100644
--- a/drivers/mfd/glamo/glamo-mci.c
+++ b/drivers/mfd/glamo/glamo-mci.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/dma-mapping.h>
#include <linux/clk.h>
+#include <linux/crc7.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/host.h>
#include <linux/platform_device.h>
@@ -38,23 +39,6 @@ extern struct glamo_mci_pdata glamo_mci_def_pdata;

static void glamo_mci_send_request(struct mmc_host *mmc);

-unsigned char CRC7(u8 * pu8, int cnt)
-{
-       u8 crc = 0;
-
-       while (cnt--) {
-               int n;
-               u8 d = *pu8++;
-               for (n = 0; n < 8; n++) {
-                       crc <<= 1;
-                       if ((d & 0x80) ^ (crc & 0x80))
-                               crc ^= 0x09;
-                       d <<= 1;
-               }
-       }
-       return (crc << 1) | 1;
-}
-
/* these _dly versions account for the dead time rules for reg access */
static u16 readw_dly(u16 __iomem * pu16)
{
@@ -188,15 +172,15 @@ static void glamo_mci_irq(unsigned int irq, struct 
irq_desc *desc)
        writew(GLAMO_IRQ_MMC,
               glamo_mci_def_pdata.pglamo->base + GLAMO_REG_IRQ_CLEAR);

-       if (status & (GLAMO_STAT1_MMC_RTOUT |
-                     GLAMO_STAT1_MMC_DTOUT))
+       if (status & GLAMO_STAT1_MMC_DTOUT)
                cmd->error = -ETIMEDOUT;
        if (status & (GLAMO_STAT1_MMC_BWERR |
                      GLAMO_STAT1_MMC_BRERR))
                cmd->error = -EILSEQ;
        if (cmd->error) {
-               dev_info(&host->pdev->dev, "Error after cmd: 0x%x\n", status);
-               goto done;
+               dev_info(&host->pdev->dev, "Error in irq after cmd: 0x%x\n", 
status);
+               if (!(status & GLAMO_STAT1_MMC_RB_DRDY))
+                       goto done;
        }

        if (host->pio_active == XFER_READ)
@@ -227,7 +211,7 @@ static int glamo_mci_send_command(struct glamo_mci_host 
*host,

        /* if we can't do it, reject as busy */
        if (!(readw_dly(host->base + GLAMO_REG_MMC_RB_STAT1) &
-            GLAMO_STAT1_MMC_IDLE)) {
+                GLAMO_STAT1_MMC_IDLE)) {
                host->mrq = NULL;
                cmd->error = -EBUSY;
                mmc_request_done(host->mmc, cmd->mrq);
@@ -240,7 +224,7 @@ static int glamo_mci_send_command(struct glamo_mci_host 
*host,
        u8a[2] = (u8)(cmd->arg >> 16);
        u8a[3] = (u8)(cmd->arg >> 8);
        u8a[4] = (u8)cmd->arg;
-       u8a[5] = CRC7(&u8a[0], 5); /* CRC7 on first 5 bytes of packet */
+       u8a[5] = crc7(0, &u8a[0], 5) | 0x01; /* CRC7 on first 5 bytes of packet 
*/

        /* issue the wire-order array including CRC in register order */
        writew_dly((u8a[4] << 8) | u8a[5], host->base + GLAMO_REG_MMC_CMD_REG1);
@@ -336,7 +320,7 @@ static int glamo_mci_send_command(struct glamo_mci_host 
*host,
        /* enforce timeout */
        if (cmd->data) {
                if (cmd->data->timeout_clks)
-                       writew_dly(cmd->data->timeout_clks >> 4, /* / 16 clks */
+                       writew_dly((cmd->data->timeout_clks >> 4) | 1, /* / 16 
clks */
                                        host->base + GLAMO_REG_MMC_TIMEOUT);
                else
                        writew_dly(0xfff, host->base + GLAMO_REG_MMC_TIMEOUT);
@@ -468,20 +452,22 @@ static void glamo_mci_send_request(struct mmc_host *mmc)

        if (cmd->error) {
                dev_info(&host->pdev->dev, "Error after cmd: 0x%x\n", status);
-               goto done;
        }
-       /*
-        * mangle the response registers in two different exciting
-        * undocumented ways discovered by trial and error
-        */
-       if (mmc_resp_type(cmd) == MMC_RSP_R2)
-               /* grab the response */
-               for (n = 0; n < 8; n++) /* super mangle power 1 */
-                       pu16[n ^ 6] = readw_dly(&reg_resp[n]);
-       else
-               for (n = 0; n < 3; n++) /* super mangle power 2 */
-                       pu16[n] = (readw_dly(&reg_resp[n]) >> 8) |
-                                 (readw_dly(&reg_resp[n + 1]) << 8);
+
+       if (status & GLAMO_STAT1_MMC_RB_RRDY) {
+               /*
+                * mangle the response registers in two different exciting
+                * undocumented ways discovered by trial and error
+                */
+               if (mmc_resp_type(cmd) == MMC_RSP_R2)
+                       /* grab the response */
+                       for (n = 0; n < 8; n++) /* super mangle power 1 */
+                               pu16[n ^ 6] = readw_dly(&reg_resp[n]);
+               else
+                       for (n = 0; n < 3; n++) /* super mangle power 2 */
+                               pu16[n] = (readw_dly(&reg_resp[n]) >> 8) |
+                                         (readw_dly(&reg_resp[n + 1]) << 8);
+       }
        /*
         * if we don't have bulk data to take care of, we're done
         */
@@ -753,7 +739,7 @@ static int glamo_mci_probe(struct platform_device *pdev)
         * held at /4 due to concerns of 100R recommended series resistor
         * allows 16MHz @ 4-bit --> 8MBytes/sec raw
         */
-       mmc->f_max   = host->clk_rate / 3;
+       mmc->f_max   = host->clk_rate / 5;

        mmc->max_blk_count   = (1 << 16) - 1; /* GLAMO_REG_MMC_RB_BLKCNT */
        mmc->max_blk_size    = (1 << 12) - 1; /* GLAMO_REG_MMC_RB_BLKLEN */


Reply via email to