[PATCH 13/22] mmc: omap_hsmmc: fix few bugs when set the clock divisor
Grazvydas Ignotas
notasas at gmail.com
Thu May 5 08:53:45 EDT 2011
On Thu, May 5, 2011 at 2:51 PM, Adrian Hunter <adrian.hunter at nokia.com> wrote:
> From: Andy Shevchenko <ext-andriy.shevchenko at nokia.com>
>
> There are two pieces of code which similar, but not the same. Each of them
> contains a bug.
>
> The SYSCTL register should be read before write in the
> omap_hsmmc_context_restore() to remain the state of the reserved bits.
>
> Before set the clock divisor and DTO bits the value from the SYSCTL register
> should be masked properly. We were lucky to have no problems with DTO bits. So,
> make sure we have clear DTO bits properly in the omap_hsmmc_set_ios().
>
> Additionally get rid of msleep(1). The actual time rare higher than 30us on
> OMAP 3630.
>
> The result pieces of code are split to omap_hsmmc_set_clock() function.
>
> Signed-off-by: Andy Shevchenko <ext-andriy.shevchenko at nokia.com>
> Signed-off-by: Adrian Hunter <adrian.hunter at nokia.com>
> ---
> drivers/mmc/host/omap_hsmmc.c | 59 +++++++++++++++++++---------------------
> 1 files changed, 28 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
> index ae6d204..3c76911 100644
> --- a/drivers/mmc/host/omap_hsmmc.c
> +++ b/drivers/mmc/host/omap_hsmmc.c
> @@ -619,6 +619,32 @@ static u16 calc_divisor(struct mmc_ios *ios)
> return dsor;
> }
>
> +static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host)
> +{
> + struct mmc_ios *ios = &host->mmc->ios;
> + unsigned long regval;
> + unsigned long timeout;
> +
> + dev_dbg(mmc_dev(host->mmc), "Set clock to %uHz\n", ios->clock);
> +
> + omap_hsmmc_stop_clock(host);
> +
> + regval = OMAP_HSMMC_READ(host->base, SYSCTL);
> + regval = regval & ~(CLKD_MASK | DTO_MASK);
> + regval = regval | (calc_divisor(ios) << 6) | (DTO << 16);
> + OMAP_HSMMC_WRITE(host->base, SYSCTL, regval);
> + OMAP_HSMMC_WRITE(host->base, SYSCTL,
> + OMAP_HSMMC_READ(host->base, SYSCTL) | ICE);
> +
> + /* Wait till the ICS bit is set */
> + timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
> + while ((OMAP_HSMMC_READ(host->base, SYSCTL) & ICS) != ICS
> + && time_before(jiffies, timeout))
> + ;
Since you are busywaiting now, cpu_relax() is advisable I guess.
More information about the linux-arm-kernel
mailing list