Skip to content

Commit

Permalink
mmc: tmio: Cache interrupt masks
Browse files Browse the repository at this point in the history
This avoids the need to look up the masks each time an interrupt is handled.
As suggested by Guennadi.

Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Acked-by: Magnus Damm <magnus.damm@gmail.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Signed-off-by: Chris Ball <cjb@laptop.org>
  • Loading branch information
Simon Horman authored and Chris Ball committed Oct 26, 2011
1 parent ad5fd97 commit 54680fe
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 16 deletions.
4 changes: 4 additions & 0 deletions drivers/mmc/host/tmio_mmc.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ struct tmio_mmc_host {
struct delayed_work delayed_reset_work;
struct work_struct done;

/* Cache IRQ mask */
u32 sdcard_irq_mask;
u32 sdio_irq_mask;

spinlock_t lock; /* protect host private data */
unsigned long last_req_ts;
struct mutex ios_lock; /* protect set_ios() context */
Expand Down
34 changes: 18 additions & 16 deletions drivers/mmc/host/tmio_mmc_pio.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@

void tmio_mmc_enable_mmc_irqs(struct tmio_mmc_host *host, u32 i)
{
u32 mask = sd_ctrl_read32(host, CTL_IRQ_MASK) & ~(i & TMIO_MASK_IRQ);
sd_ctrl_write32(host, CTL_IRQ_MASK, mask);
host->sdcard_irq_mask &= ~(i & TMIO_MASK_IRQ);
sd_ctrl_write32(host, CTL_IRQ_MASK, host->sdcard_irq_mask);
}

void tmio_mmc_disable_mmc_irqs(struct tmio_mmc_host *host, u32 i)
{
u32 mask = sd_ctrl_read32(host, CTL_IRQ_MASK) | (i & TMIO_MASK_IRQ);
sd_ctrl_write32(host, CTL_IRQ_MASK, mask);
host->sdcard_irq_mask |= (i & TMIO_MASK_IRQ);
sd_ctrl_write32(host, CTL_IRQ_MASK, host->sdcard_irq_mask);
}

static void tmio_mmc_ack_mmc_irqs(struct tmio_mmc_host *host, u32 i)
Expand Down Expand Up @@ -127,11 +127,13 @@ static void tmio_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)

if (enable) {
host->sdio_irq_enabled = 1;
host->sdio_irq_mask = TMIO_SDIO_MASK_ALL &
~TMIO_SDIO_STAT_IOIRQ;
sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0001);
sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK,
(TMIO_SDIO_MASK_ALL & ~TMIO_SDIO_STAT_IOIRQ));
sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask);
} else {
sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, TMIO_SDIO_MASK_ALL);
host->sdio_irq_mask = TMIO_SDIO_MASK_ALL;
sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask);
sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0000);
host->sdio_irq_enabled = 0;
}
Expand Down Expand Up @@ -548,26 +550,25 @@ irqreturn_t tmio_mmc_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, irq_mask, status;
unsigned int sdio_ireg, sdio_irq_mask, sdio_status;
unsigned int ireg, status;
unsigned int sdio_ireg, sdio_status;

pr_debug("MMC IRQ begin\n");

status = sd_ctrl_read32(host, CTL_STATUS);
irq_mask = sd_ctrl_read32(host, CTL_IRQ_MASK);
ireg = status & TMIO_MASK_IRQ & ~irq_mask;
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_irq_mask = sd_ctrl_read16(host, CTL_SDIO_IRQ_MASK);
sdio_ireg = sdio_status & TMIO_SDIO_MASK_ALL & ~sdio_irq_mask;
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, sdio_irq_mask, sdio_ireg);
sdio_status, host->sdio_irq_mask, sdio_ireg);
tmio_mmc_enable_sdio_irq(mmc, 0);
goto out;
}
Expand Down Expand Up @@ -623,9 +624,9 @@ irqreturn_t tmio_mmc_irq(int irq, void *devid)
}

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

out:
return IRQ_HANDLED;
Expand Down Expand Up @@ -882,6 +883,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
tmio_mmc_clk_stop(_host);
tmio_mmc_reset(_host);

_host->sdcard_irq_mask = sd_ctrl_read32(_host, CTL_IRQ_MASK);
tmio_mmc_disable_mmc_irqs(_host, TMIO_MASK_ALL);
if (pdata->flags & TMIO_MMC_SDIO_IRQ)
tmio_mmc_enable_sdio_irq(mmc, 0);
Expand Down

0 comments on commit 54680fe

Please sign in to comment.