mmc: tmio: Cache interrupt masks
authorSimon Horman <horms@verge.net.au>
Thu, 25 Aug 2011 01:27:25 +0000 (10:27 +0900)
committerChris Ball <cjb@laptop.org>
Wed, 26 Oct 2011 19:43:36 +0000 (15:43 -0400)
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>
drivers/mmc/host/tmio_mmc.h
drivers/mmc/host/tmio_mmc_pio.c

index eeaf64391fbe3d8620dc675853716f704cb0e3e9..1cf8db558d0862ce983aa2bd376183ad98cce335 100644 (file)
@@ -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 */
index 1f16357e7301d1f4ea9a61f994f094bc71e0785b..f0c7830b830111980189cdb36666a91a008d5804 100644 (file)
 
 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)
@@ -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;
        }
@@ -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;
                }
@@ -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;
@@ -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);