omap_hsmmc: Change while(); loops with finite version

Replace the infinite 'while() ;' loops
with a finite loop version.

Signed-off-by: Jean Pihet <jpihet@mvista.com>
Acked-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
This commit is contained in:
Jean Pihet 2009-02-06 16:42:51 +01:00 committed by Pierre Ossman
parent c232f457e4
commit 3ebf74b1de

View File

@ -376,6 +376,32 @@ static void mmc_omap_report_irq(struct mmc_omap_host *host, u32 status)
} }
#endif /* CONFIG_MMC_DEBUG */ #endif /* CONFIG_MMC_DEBUG */
/*
* MMC controller internal state machines reset
*
* Used to reset command or data internal state machines, using respectively
* SRC or SRD bit of SYSCTL register
* Can be called from interrupt context
*/
static inline void mmc_omap_reset_controller_fsm(struct mmc_omap_host *host,
unsigned long bit)
{
unsigned long i = 0;
unsigned long limit = (loops_per_jiffy *
msecs_to_jiffies(MMC_TIMEOUT_MS));
OMAP_HSMMC_WRITE(host->base, SYSCTL,
OMAP_HSMMC_READ(host->base, SYSCTL) | bit);
while ((OMAP_HSMMC_READ(host->base, SYSCTL) & bit) &&
(i++ < limit))
cpu_relax();
if (OMAP_HSMMC_READ(host->base, SYSCTL) & bit)
dev_err(mmc_dev(host->mmc),
"Timeout waiting on controller reset in %s\n",
__func__);
}
/* /*
* MMC controller IRQ handler * MMC controller IRQ handler
@ -404,13 +430,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
(status & CMD_CRC)) { (status & CMD_CRC)) {
if (host->cmd) { if (host->cmd) {
if (status & CMD_TIMEOUT) { if (status & CMD_TIMEOUT) {
OMAP_HSMMC_WRITE(host->base, SYSCTL, mmc_omap_reset_controller_fsm(host, SRC);
OMAP_HSMMC_READ(host->base,
SYSCTL) | SRC);
while (OMAP_HSMMC_READ(host->base,
SYSCTL) & SRC)
;
host->cmd->error = -ETIMEDOUT; host->cmd->error = -ETIMEDOUT;
} else { } else {
host->cmd->error = -EILSEQ; host->cmd->error = -EILSEQ;
@ -419,12 +439,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
} }
if (host->data) { if (host->data) {
mmc_dma_cleanup(host); mmc_dma_cleanup(host);
OMAP_HSMMC_WRITE(host->base, SYSCTL, mmc_omap_reset_controller_fsm(host, SRD);
OMAP_HSMMC_READ(host->base,
SYSCTL) | SRD);
while (OMAP_HSMMC_READ(host->base,
SYSCTL) & SRD)
;
} }
} }
if ((status & DATA_TIMEOUT) || if ((status & DATA_TIMEOUT) ||
@ -434,12 +449,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
mmc_dma_cleanup(host); mmc_dma_cleanup(host);
else else
host->data->error = -EILSEQ; host->data->error = -EILSEQ;
OMAP_HSMMC_WRITE(host->base, SYSCTL, mmc_omap_reset_controller_fsm(host, SRD);
OMAP_HSMMC_READ(host->base,
SYSCTL) | SRD);
while (OMAP_HSMMC_READ(host->base,
SYSCTL) & SRD)
;
end_trans = 1; end_trans = 1;
} }
} }
@ -547,11 +557,7 @@ static void mmc_omap_detect(struct work_struct *work)
if (host->carddetect) { if (host->carddetect) {
mmc_detect_change(host->mmc, (HZ * 200) / 1000); mmc_detect_change(host->mmc, (HZ * 200) / 1000);
} else { } else {
OMAP_HSMMC_WRITE(host->base, SYSCTL, mmc_omap_reset_controller_fsm(host, SRD);
OMAP_HSMMC_READ(host->base, SYSCTL) | SRD);
while (OMAP_HSMMC_READ(host->base, SYSCTL) & SRD)
;
mmc_detect_change(host->mmc, (HZ * 50) / 1000); mmc_detect_change(host->mmc, (HZ * 50) / 1000);
} }
} }