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