The patch titled mmc: proper timeout handling has been added to the -mm tree. Its filename is mmc-proper-timeout-handling.patch See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this ------------------------------------------------------ Subject: mmc: proper timeout handling From: Pierre Ossman <drzeus@xxxxxxxxx> Use the give timeout clock and calculate a proper timeout instead of using the maximum at all times. Signed-off-by: Pierre Ossman <drzeus@xxxxxxxxx> Cc: Russell King <rmk@xxxxxxxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> --- drivers/mmc/sdhci.c | 47 +++++++++++++++++++++++++++++++++++++++--- drivers/mmc/sdhci.h | 4 +++ 2 files changed, 48 insertions(+), 3 deletions(-) diff -puN drivers/mmc/sdhci.c~mmc-proper-timeout-handling drivers/mmc/sdhci.c --- 25/drivers/mmc/sdhci.c~mmc-proper-timeout-handling Tue Jun 27 14:28:31 2006 +++ 25-akpm/drivers/mmc/sdhci.c Tue Jun 27 14:28:31 2006 @@ -128,9 +128,6 @@ static void sdhci_init(struct sdhci_host writel(intmask, host->ioaddr + SDHCI_INT_ENABLE); writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE); - - /* This is unknown magic. */ - writeb(0xE, host->ioaddr + SDHCI_TIMEOUT_CONTROL); } static void sdhci_activate_led(struct sdhci_host *host) @@ -274,6 +271,8 @@ static void sdhci_transfer_pio(struct sd static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) { u16 mode; + u8 count; + unsigned target_timeout, current_timeout; WARN_ON(host->data); @@ -287,6 +286,37 @@ static void sdhci_prepare_data(struct sd DBG("tsac %d ms nsac %d clk\n", data->timeout_ns / 1000000, data->timeout_clks); + /* timeout in us */ + target_timeout = data->timeout_ns / 1000 + + data->timeout_clks / host->clock; + + /* + * Figure out needed cycles. + * We do this in steps in order to fit inside a 32 bit int. + * The first step is the minimum timeout, which will have a + * minimum resolution of 6 bits: + * (1) 2^13*1000 > 2^22, + * (2) host->timeout_clk < 2^16 + * => + * (1) / (2) > 2^6 + */ + count = 0; + current_timeout = (1 << 13) * 1000 / host->timeout_clk; + while (current_timeout < target_timeout) { + count++; + current_timeout <<= 1; + if (count >= 0xF) + break; + } + + if (count >= 0xF) { + printk(KERN_WARNING "%s: Too large timeout requested!\n", + mmc_hostname(host->mmc)); + count = 0xE; + } + + writeb(count, host->ioaddr + SDHCI_TIMEOUT_CONTROL); + mode = SDHCI_TRNS_BLK_CNT_EN; if (data->blocks > 1) mode |= SDHCI_TRNS_MULTI; @@ -1096,6 +1126,17 @@ static int __devinit sdhci_probe_slot(st } host->max_clk *= 1000000; + host->timeout_clk = + (caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT; + if (host->timeout_clk == 0) { + printk(KERN_ERR "%s: Hardware doesn't specify timeout clock " + "frequency.\n", host->slot_descr); + ret = -ENODEV; + goto unmap; + } + if (caps & SDHCI_TIMEOUT_CLK_UNIT) + host->timeout_clk *= 1000; + /* * Set host parameters. */ diff -puN drivers/mmc/sdhci.h~mmc-proper-timeout-handling drivers/mmc/sdhci.h --- 25/drivers/mmc/sdhci.h~mmc-proper-timeout-handling Tue Jun 27 14:28:31 2006 +++ 25-akpm/drivers/mmc/sdhci.h Tue Jun 27 14:28:31 2006 @@ -125,6 +125,9 @@ /* 3E-3F reserved */ #define SDHCI_CAPABILITIES 0x40 +#define SDHCI_TIMEOUT_CLK_MASK 0x0000003F +#define SDHCI_TIMEOUT_CLK_SHIFT 0 +#define SDHCI_TIMEOUT_CLK_UNIT 0x00000080 #define SDHCI_CLOCK_BASE_MASK 0x00003F00 #define SDHCI_CLOCK_BASE_SHIFT 8 #define SDHCI_CAN_DO_DMA 0x00400000 @@ -156,6 +159,7 @@ struct sdhci_host { #define SDHCI_USE_DMA (1<<0) unsigned int max_clk; /* Max possible freq (MHz) */ + unsigned int timeout_clk; /* Timeout freq (KHz) */ unsigned int clock; /* Current clock (MHz) */ unsigned short power; /* Current voltage */ _ Patches currently in -mm which might be from drzeus@xxxxxxxxx are mmc-check-sdhci-base-clock.patch mmc-print-device-id.patch mmc-support-for-multiple-voltages.patch mmc-fix-timeout-loops-in-sdhci.patch mmc-fix-sdhci-reset-timeout.patch mmc-proper-timeout-handling.patch mmc-correct-register-order.patch mmc-fix-interrupt-handling.patch mmc-fix-sdhci-pio-routines.patch mmc-avoid-sdhci-dma-boundaries.patch mmc-test-for-invalid-block-size.patch mmc-check-only-relevant-inhibit-bits.patch mmc-check-controller-version.patch mmc-reset-sdhci-controller-early.patch mmc-more-dma-capabilities-tests.patch mmc-support-controller-specific-quirks.patch mmc-version-bump-sdhci.patch mmc-add-sdhci-controller-ids.patch mmc-quirk-for-broken-reset.patch mmc-force-dma-on-some-controllers.patch mmc-remove-duplicate-error-message.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html