aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/mmci.c
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@stericsson.com>2012-01-18 03:17:27 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-02-02 12:02:15 -0500
commit7437cfa532842ce75189826742bddf1ba137f58e (patch)
treea668a44a7c54b9f8e73c816831ad0958cc61fc18 /drivers/mmc/host/mmci.c
parent393e5e24165d0bef60489ecd0baef085e9af2e5a (diff)
ARM: 7280/1: mmc: mmci: Cache MMCICLOCK and MMCIPOWER register
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>
Diffstat (limited to 'drivers/mmc/host/mmci.c')
-rw-r--r--drivers/mmc/host/mmci.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 1f8832699cdf..f36d8b8c891f 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -121,6 +121,28 @@ static struct variant_data variant_ux500v2 = {
121/* 121/*
122 * This must be called with host->lock held 122 * This must be called with host->lock held
123 */ 123 */
124static void mmci_write_clkreg(struct mmci_host *host, u32 clk)
125{
126 if (host->clk_reg != clk) {
127 host->clk_reg = clk;
128 writel(clk, host->base + MMCICLOCK);
129 }
130}
131
132/*
133 * This must be called with host->lock held
134 */
135static void mmci_write_pwrreg(struct mmci_host *host, u32 pwr)
136{
137 if (host->pwr_reg != pwr) {
138 host->pwr_reg = pwr;
139 writel(pwr, host->base + MMCIPOWER);
140 }
141}
142
143/*
144 * This must be called with host->lock held
145 */
124static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) 146static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
125{ 147{
126 struct variant_data *variant = host->variant; 148 struct variant_data *variant = host->variant;
@@ -165,7 +187,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
165 if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8) 187 if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8)
166 clk |= MCI_ST_8BIT_BUS; 188 clk |= MCI_ST_8BIT_BUS;
167 189
168 writel(clk, host->base + MMCICLOCK); 190 mmci_write_clkreg(host, clk);
169} 191}
170 192
171static void 193static void
@@ -846,14 +868,13 @@ static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int rem
846 */ 868 */
847 if (variant->sdio && 869 if (variant->sdio &&
848 mmc_card_sdio(host->mmc->card)) { 870 mmc_card_sdio(host->mmc->card)) {
871 u32 clk;
849 if (count < 8) 872 if (count < 8)
850 writel(readl(host->base + MMCICLOCK) & 873 clk = host->clk_reg & ~variant->clkreg_enable;
851 ~variant->clkreg_enable,
852 host->base + MMCICLOCK);
853 else 874 else
854 writel(readl(host->base + MMCICLOCK) | 875 clk = host->clk_reg | variant->clkreg_enable;
855 variant->clkreg_enable, 876
856 host->base + MMCICLOCK); 877 mmci_write_clkreg(host, clk);
857 } 878 }
858 879
859 /* 880 /*
@@ -1114,11 +1135,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1114 spin_lock_irqsave(&host->lock, flags); 1135 spin_lock_irqsave(&host->lock, flags);
1115 1136
1116 mmci_set_clkreg(host, ios->clock); 1137 mmci_set_clkreg(host, ios->clock);
1117 1138 mmci_write_pwrreg(host, pwr);
1118 if (host->pwr != pwr) {
1119 host->pwr = pwr;
1120 writel(pwr, host->base + MMCIPOWER);
1121 }
1122 1139
1123 spin_unlock_irqrestore(&host->lock, flags); 1140 spin_unlock_irqrestore(&host->lock, flags);
1124 1141