ARM: 7280/1: mmc: mmci: Cache MMCICLOCK and MMCIPOWER register
authorUlf Hansson <ulf.hansson@stericsson.com>
Wed, 18 Jan 2012 08:17:27 +0000 (09:17 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Thu, 2 Feb 2012 17:02:15 +0000 (17:02 +0000)
Instead of reading a register value everytime we need to
apply a new value for it, maintain a cached copy for it.
This also means we are able to skip writes that are not
needed.

Tested-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
drivers/mmc/host/mmci.c
drivers/mmc/host/mmci.h

index 1f8832699cdf63873a81856009da456874135a59..f36d8b8c891f65491882b18bbbf778b4b2c74204 100644 (file)
@@ -118,6 +118,28 @@ static struct variant_data variant_ux500v2 = {
        .signal_direction       = true,
 };
 
+/*
+ * This must be called with host->lock held
+ */
+static void mmci_write_clkreg(struct mmci_host *host, u32 clk)
+{
+       if (host->clk_reg != clk) {
+               host->clk_reg = clk;
+               writel(clk, host->base + MMCICLOCK);
+       }
+}
+
+/*
+ * This must be called with host->lock held
+ */
+static void mmci_write_pwrreg(struct mmci_host *host, u32 pwr)
+{
+       if (host->pwr_reg != pwr) {
+               host->pwr_reg = pwr;
+               writel(pwr, host->base + MMCIPOWER);
+       }
+}
+
 /*
  * This must be called with host->lock held
  */
@@ -165,7 +187,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
        if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8)
                clk |= MCI_ST_8BIT_BUS;
 
-       writel(clk, host->base + MMCICLOCK);
+       mmci_write_clkreg(host, clk);
 }
 
 static void
@@ -846,14 +868,13 @@ static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int rem
                 */
                if (variant->sdio &&
                    mmc_card_sdio(host->mmc->card)) {
+                       u32 clk;
                        if (count < 8)
-                               writel(readl(host->base + MMCICLOCK) &
-                                       ~variant->clkreg_enable,
-                                       host->base + MMCICLOCK);
+                               clk = host->clk_reg & ~variant->clkreg_enable;
                        else
-                               writel(readl(host->base + MMCICLOCK) |
-                                       variant->clkreg_enable,
-                                       host->base + MMCICLOCK);
+                               clk = host->clk_reg | variant->clkreg_enable;
+
+                       mmci_write_clkreg(host, clk);
                }
 
                /*
@@ -1114,11 +1135,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        spin_lock_irqsave(&host->lock, flags);
 
        mmci_set_clkreg(host, ios->clock);
-
-       if (host->pwr != pwr) {
-               host->pwr = pwr;
-               writel(pwr, host->base + MMCIPOWER);
-       }
+       mmci_write_pwrreg(host, pwr);
 
        spin_unlock_irqrestore(&host->lock, flags);
 
index 89eb2e3556d3a0c77a44d84d05a568963d6adcf4..d437ccf62d6bcc76a41862f68b48408f0711c5af 100644 (file)
@@ -179,7 +179,8 @@ struct mmci_host {
 
        unsigned int            mclk;
        unsigned int            cclk;
-       u32                     pwr;
+       u32                     pwr_reg;
+       u32                     clk_reg;
        struct mmci_platform_data *plat;
        struct variant_data     *variant;