mmc: sdhci-esdhc: use writel/readl as general APIs

Add one flag to indicate the GPIO CD/WP is enabled or not
on imx platforms, and reuse the writel/readl as the general
APIs for imx SOCs.

Signed-off-by: Richard Zhu <Hong-Xing.Zhu@freescale.com>
Reviewed-by: Wolfram Sang <w.sang@pengutronix.de>
Signed-off-by: Chris Ball <cjb@laptop.org>

authored by Richard Zhu and committed by Chris Ball e149860d 574e3f56

+38 -8
+37 -7
drivers/mmc/host/sdhci-esdhc-imx.c
··· 16 #include <linux/err.h> 17 #include <linux/clk.h> 18 #include <linux/gpio.h> 19 #include <linux/mmc/host.h> 20 #include <linux/mmc/sdhci-pltfm.h> 21 #include <mach/hardware.h> ··· 24 #include "sdhci.h" 25 #include "sdhci-pltfm.h" 26 #include "sdhci-esdhc.h" 27 28 static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, int reg) 29 { ··· 42 43 static u32 esdhc_readl_le(struct sdhci_host *host, int reg) 44 { 45 /* fake CARD_PRESENT flag on mx25/35 */ 46 u32 val = readl(host->ioaddr + reg); 47 48 - if (unlikely(reg == SDHCI_PRESENT_STATE)) { 49 struct esdhc_platform_data *boarddata = 50 host->mmc->parent->platform_data; 51 ··· 67 68 static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg) 69 { 70 - if (unlikely(reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)) 71 /* 72 * these interrupts won't work with a custom card_detect gpio 73 * (only applied to mx25/35) ··· 92 static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) 93 { 94 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 95 96 switch (reg) { 97 case SDHCI_TRANSFER_MODE: ··· 100 * Postpone this write, we must do it together with a 101 * command write that is down below. 102 */ 103 - pltfm_host->scratchpad = val; 104 return; 105 case SDHCI_COMMAND: 106 - writel(val << 16 | pltfm_host->scratchpad, 107 host->ioaddr + SDHCI_TRANSFER_MODE); 108 return; 109 case SDHCI_BLOCK_SIZE: ··· 163 } 164 165 static struct sdhci_ops sdhci_esdhc_ops = { 166 .read_w = esdhc_readw_le, 167 .write_w = esdhc_writew_le, 168 .write_b = esdhc_writeb_le, 169 .set_clock = esdhc_set_clock, ··· 187 struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data; 188 struct clk *clk; 189 int err; 190 191 clk = clk_get(mmc_dev(host->mmc), NULL); 192 if (IS_ERR(clk)) { ··· 197 clk_enable(clk); 198 pltfm_host->clk = clk; 199 200 - if (cpu_is_mx35() || cpu_is_mx51()) 201 host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; 202 203 if (cpu_is_mx25() || cpu_is_mx35()) { ··· 242 goto no_card_detect_irq; 243 } 244 245 - sdhci_esdhc_ops.write_l = esdhc_writel_le; 246 - sdhci_esdhc_ops.read_l = esdhc_readl_le; 247 /* Now we have a working card_detect again */ 248 host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; 249 } ··· 254 no_card_detect_pin: 255 boarddata->cd_gpio = err; 256 not_supported: 257 return 0; 258 } 259 ··· 262 { 263 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 264 struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data; 265 266 if (boarddata && gpio_is_valid(boarddata->wp_gpio)) 267 gpio_free(boarddata->wp_gpio); ··· 276 277 clk_disable(pltfm_host->clk); 278 clk_put(pltfm_host->clk); 279 } 280 281 struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
··· 16 #include <linux/err.h> 17 #include <linux/clk.h> 18 #include <linux/gpio.h> 19 + #include <linux/slab.h> 20 #include <linux/mmc/host.h> 21 #include <linux/mmc/sdhci-pltfm.h> 22 #include <mach/hardware.h> ··· 23 #include "sdhci.h" 24 #include "sdhci-pltfm.h" 25 #include "sdhci-esdhc.h" 26 + 27 + #define ESDHC_FLAG_GPIO_FOR_CD_WP (1 << 0) 28 + 29 + struct pltfm_imx_data { 30 + int flags; 31 + u32 scratchpad; 32 + }; 33 34 static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, int reg) 35 { ··· 34 35 static u32 esdhc_readl_le(struct sdhci_host *host, int reg) 36 { 37 + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 38 + struct pltfm_imx_data *imx_data = pltfm_host->priv; 39 + 40 /* fake CARD_PRESENT flag on mx25/35 */ 41 u32 val = readl(host->ioaddr + reg); 42 43 + if (unlikely((reg == SDHCI_PRESENT_STATE) 44 + && (imx_data->flags & ESDHC_FLAG_GPIO_FOR_CD_WP))) { 45 struct esdhc_platform_data *boarddata = 46 host->mmc->parent->platform_data; 47 ··· 55 56 static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg) 57 { 58 + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 59 + struct pltfm_imx_data *imx_data = pltfm_host->priv; 60 + 61 + if (unlikely((reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE) 62 + && (imx_data->flags & ESDHC_FLAG_GPIO_FOR_CD_WP))) 63 /* 64 * these interrupts won't work with a custom card_detect gpio 65 * (only applied to mx25/35) ··· 76 static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) 77 { 78 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 79 + struct pltfm_imx_data *imx_data = pltfm_host->priv; 80 81 switch (reg) { 82 case SDHCI_TRANSFER_MODE: ··· 83 * Postpone this write, we must do it together with a 84 * command write that is down below. 85 */ 86 + imx_data->scratchpad = val; 87 return; 88 case SDHCI_COMMAND: 89 + writel(val << 16 | imx_data->scratchpad, 90 host->ioaddr + SDHCI_TRANSFER_MODE); 91 return; 92 case SDHCI_BLOCK_SIZE: ··· 146 } 147 148 static struct sdhci_ops sdhci_esdhc_ops = { 149 + .read_l = esdhc_readl_le, 150 .read_w = esdhc_readw_le, 151 + .write_l = esdhc_writel_le, 152 .write_w = esdhc_writew_le, 153 .write_b = esdhc_writeb_le, 154 .set_clock = esdhc_set_clock, ··· 168 struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data; 169 struct clk *clk; 170 int err; 171 + struct pltfm_imx_data *imx_data; 172 173 clk = clk_get(mmc_dev(host->mmc), NULL); 174 if (IS_ERR(clk)) { ··· 177 clk_enable(clk); 178 pltfm_host->clk = clk; 179 180 + imx_data = kzalloc(sizeof(struct pltfm_imx_data), GFP_KERNEL); 181 + if (!imx_data) { 182 + clk_disable(pltfm_host->clk); 183 + clk_put(pltfm_host->clk); 184 + return -ENOMEM; 185 + } 186 + pltfm_host->priv = imx_data; 187 + 188 + if (!cpu_is_mx25()) 189 host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; 190 191 if (cpu_is_mx25() || cpu_is_mx35()) { ··· 214 goto no_card_detect_irq; 215 } 216 217 + imx_data->flags |= ESDHC_FLAG_GPIO_FOR_CD_WP; 218 /* Now we have a working card_detect again */ 219 host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; 220 } ··· 227 no_card_detect_pin: 228 boarddata->cd_gpio = err; 229 not_supported: 230 + kfree(imx_data); 231 return 0; 232 } 233 ··· 234 { 235 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 236 struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data; 237 + struct pltfm_imx_data *imx_data = pltfm_host->priv; 238 239 if (boarddata && gpio_is_valid(boarddata->wp_gpio)) 240 gpio_free(boarddata->wp_gpio); ··· 247 248 clk_disable(pltfm_host->clk); 249 clk_put(pltfm_host->clk); 250 + kfree(imx_data); 251 } 252 253 struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
+1 -1
drivers/mmc/host/sdhci-pltfm.h
··· 17 18 struct sdhci_pltfm_host { 19 struct clk *clk; 20 - u32 scratchpad; /* to handle quirks across io-accessor calls */ 21 }; 22 23 extern struct sdhci_pltfm_data sdhci_cns3xxx_pdata;
··· 17 18 struct sdhci_pltfm_host { 19 struct clk *clk; 20 + void *priv; /* to handle quirks across io-accessor calls */ 21 }; 22 23 extern struct sdhci_pltfm_data sdhci_cns3xxx_pdata;