Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 270246
b: refs/heads/master
c: 7729c7a
h: refs/heads/master
v: v3
  • Loading branch information
Simon Horman authored and Chris Ball committed Oct 26, 2011
1 parent 59ffbaf commit 01c2673
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 49 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 54680fe7f6ad0fb0c52e330484e2cf1609587862
refs/heads/master: 7729c7a232a95360fa17ffe8beb1adb621bc0ba0
3 changes: 3 additions & 0 deletions trunk/drivers/mmc/host/tmio_mmc.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ void tmio_mmc_do_data_irq(struct tmio_mmc_host *host);
void tmio_mmc_enable_mmc_irqs(struct tmio_mmc_host *host, u32 i);
void tmio_mmc_disable_mmc_irqs(struct tmio_mmc_host *host, u32 i);
irqreturn_t tmio_mmc_irq(int irq, void *devid);
irqreturn_t tmio_mmc_sdcard_irq(int irq, void *devid);
irqreturn_t tmio_mmc_card_detect_irq(int irq, void *devid);
irqreturn_t tmio_mmc_sdio_irq(int irq, void *devid);

static inline char *tmio_mmc_kmap_atomic(struct scatterlist *sg,
unsigned long *flags)
Expand Down
131 changes: 83 additions & 48 deletions trunk/drivers/mmc/host/tmio_mmc_pio.c
Original file line number Diff line number Diff line change
Expand Up @@ -545,44 +545,20 @@ static void tmio_mmc_cmd_irq(struct tmio_mmc_host *host,
spin_unlock(&host->lock);
}

irqreturn_t tmio_mmc_irq(int irq, void *devid)
static void tmio_mmc_card_irq_status(struct tmio_mmc_host *host,
int *ireg, int *status)
{
struct tmio_mmc_host *host = devid;
struct mmc_host *mmc = host->mmc;
struct tmio_mmc_data *pdata = host->pdata;
unsigned int ireg, status;
unsigned int sdio_ireg, sdio_status;

pr_debug("MMC IRQ begin\n");

status = sd_ctrl_read32(host, CTL_STATUS);
ireg = status & TMIO_MASK_IRQ & ~host->sdcard_irq_mask;
*status = sd_ctrl_read32(host, CTL_STATUS);
*ireg = *status & TMIO_MASK_IRQ & ~host->sdcard_irq_mask;

sdio_ireg = 0;
if (!ireg && pdata->flags & TMIO_MMC_SDIO_IRQ) {
sdio_status = sd_ctrl_read16(host, CTL_SDIO_STATUS);
sdio_ireg = sdio_status & TMIO_SDIO_MASK_ALL &
~host->sdio_irq_mask;

sd_ctrl_write16(host, CTL_SDIO_STATUS, sdio_status & ~TMIO_SDIO_MASK_ALL);

if (sdio_ireg && !host->sdio_irq_enabled) {
pr_warning("tmio_mmc: Spurious SDIO IRQ, disabling! 0x%04x 0x%04x 0x%04x\n",
sdio_status, host->sdio_irq_mask, sdio_ireg);
tmio_mmc_enable_sdio_irq(mmc, 0);
goto out;
}

if (mmc->caps & MMC_CAP_SDIO_IRQ &&
sdio_ireg & TMIO_SDIO_STAT_IOIRQ)
mmc_signal_sdio_irq(mmc);

if (sdio_ireg)
goto out;
}
pr_debug_status(*status);
pr_debug_status(*ireg);
}

pr_debug_status(status);
pr_debug_status(ireg);
static bool __tmio_mmc_card_detect_irq(struct tmio_mmc_host *host,
int ireg, int status)
{
struct mmc_host *mmc = host->mmc;

/* Card insert / remove attempts */
if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) {
Expand All @@ -592,43 +568,102 @@ irqreturn_t tmio_mmc_irq(int irq, void *devid)
((ireg & TMIO_STAT_CARD_INSERT) && !mmc->card)) &&
!work_pending(&mmc->detect.work))
mmc_detect_change(host->mmc, msecs_to_jiffies(100));
goto out;
return true;
}

/* CRC and other errors */
/* if (ireg & TMIO_STAT_ERR_IRQ)
* handled |= tmio_error_irq(host, irq, stat);
*/
return false;
}

irqreturn_t tmio_mmc_card_detect_irq(int irq, void *devid)
{
unsigned int ireg, status;
struct tmio_mmc_host *host = devid;

tmio_mmc_card_irq_status(host, &ireg, &status);
__tmio_mmc_card_detect_irq(host, ireg, status);

return IRQ_HANDLED;
}
EXPORT_SYMBOL(tmio_mmc_card_detect_irq);

static bool __tmio_mmc_sdcard_irq(struct tmio_mmc_host *host,
int ireg, int status)
{
/* Command completion */
if (ireg & (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT)) {
tmio_mmc_ack_mmc_irqs(host,
TMIO_STAT_CMDRESPEND |
TMIO_STAT_CMDTIMEOUT);
tmio_mmc_cmd_irq(host, status);
goto out;
return true;
}

/* Data transfer */
if (ireg & (TMIO_STAT_RXRDY | TMIO_STAT_TXRQ)) {
tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_RXRDY | TMIO_STAT_TXRQ);
tmio_mmc_pio_irq(host);
goto out;
return true;
}

/* Data transfer completion */
if (ireg & TMIO_STAT_DATAEND) {
tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_DATAEND);
tmio_mmc_data_irq(host);
goto out;
return true;
}

pr_warning("tmio_mmc: Spurious irq, disabling! "
"0x%08x 0x%08x 0x%08x\n", status, host->sdcard_irq_mask, ireg);
pr_debug_status(status);
tmio_mmc_disable_mmc_irqs(host, status & ~host->sdcard_irq_mask);
return false;
}

irqreturn_t tmio_mmc_sdcard_irq(int irq, void *devid)
{
unsigned int ireg, status;
struct tmio_mmc_host *host = devid;

tmio_mmc_card_irq_status(host, &ireg, &status);
__tmio_mmc_sdcard_irq(host, ireg, status);

return IRQ_HANDLED;
}
EXPORT_SYMBOL(tmio_mmc_sdcard_irq);

irqreturn_t tmio_mmc_sdio_irq(int irq, void *devid)
{
struct tmio_mmc_host *host = devid;
struct mmc_host *mmc = host->mmc;
struct tmio_mmc_data *pdata = host->pdata;
unsigned int ireg, status;

if (!(pdata->flags & TMIO_MMC_SDIO_IRQ))
return IRQ_HANDLED;

status = sd_ctrl_read16(host, CTL_SDIO_STATUS);
ireg = status & TMIO_SDIO_MASK_ALL & ~host->sdcard_irq_mask;

sd_ctrl_write16(host, CTL_SDIO_STATUS, status & ~TMIO_SDIO_MASK_ALL);

if (mmc->caps & MMC_CAP_SDIO_IRQ && ireg & TMIO_SDIO_STAT_IOIRQ)
mmc_signal_sdio_irq(mmc);

return IRQ_HANDLED;
}
EXPORT_SYMBOL(tmio_mmc_sdio_irq);

irqreturn_t tmio_mmc_irq(int irq, void *devid)
{
struct tmio_mmc_host *host = devid;
unsigned int ireg, status;

pr_debug("MMC IRQ begin\n");

tmio_mmc_card_irq_status(host, &ireg, &status);
if (__tmio_mmc_card_detect_irq(host, ireg, status))
return IRQ_HANDLED;
if (__tmio_mmc_sdcard_irq(host, ireg, status))
return IRQ_HANDLED;

tmio_mmc_sdio_irq(irq, devid);

out:
return IRQ_HANDLED;
}
EXPORT_SYMBOL(tmio_mmc_irq);
Expand Down

0 comments on commit 01c2673

Please sign in to comment.