Skip to content

Commit e149860

Browse files
Richard Zhucjb
authored andcommitted
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 <[email protected]> Reviewed-by: Wolfram Sang <[email protected]> Signed-off-by: Chris Ball <[email protected]>
1 parent 574e3f5 commit e149860

File tree

2 files changed

+38
-8
lines changed

2 files changed

+38
-8
lines changed

drivers/mmc/host/sdhci-esdhc-imx.c

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/err.h>
1717
#include <linux/clk.h>
1818
#include <linux/gpio.h>
19+
#include <linux/slab.h>
1920
#include <linux/mmc/host.h>
2021
#include <linux/mmc/sdhci-pltfm.h>
2122
#include <mach/hardware.h>
@@ -24,6 +25,13 @@
2425
#include "sdhci-pltfm.h"
2526
#include "sdhci-esdhc.h"
2627

28+
#define ESDHC_FLAG_GPIO_FOR_CD_WP (1 << 0)
29+
30+
struct pltfm_imx_data {
31+
int flags;
32+
u32 scratchpad;
33+
};
34+
2735
static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, int reg)
2836
{
2937
void __iomem *base = host->ioaddr + (reg & ~0x3);
@@ -34,10 +42,14 @@ static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, i
3442

3543
static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
3644
{
45+
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
46+
struct pltfm_imx_data *imx_data = pltfm_host->priv;
47+
3748
/* fake CARD_PRESENT flag on mx25/35 */
3849
u32 val = readl(host->ioaddr + reg);
3950

40-
if (unlikely(reg == SDHCI_PRESENT_STATE)) {
51+
if (unlikely((reg == SDHCI_PRESENT_STATE)
52+
&& (imx_data->flags & ESDHC_FLAG_GPIO_FOR_CD_WP))) {
4153
struct esdhc_platform_data *boarddata =
4254
host->mmc->parent->platform_data;
4355

@@ -55,7 +67,11 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
5567

5668
static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg)
5769
{
58-
if (unlikely(reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE))
70+
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
71+
struct pltfm_imx_data *imx_data = pltfm_host->priv;
72+
73+
if (unlikely((reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)
74+
&& (imx_data->flags & ESDHC_FLAG_GPIO_FOR_CD_WP)))
5975
/*
6076
* these interrupts won't work with a custom card_detect gpio
6177
* (only applied to mx25/35)
@@ -76,17 +92,18 @@ static u16 esdhc_readw_le(struct sdhci_host *host, int reg)
7692
static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
7793
{
7894
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
95+
struct pltfm_imx_data *imx_data = pltfm_host->priv;
7996

8097
switch (reg) {
8198
case SDHCI_TRANSFER_MODE:
8299
/*
83100
* Postpone this write, we must do it together with a
84101
* command write that is down below.
85102
*/
86-
pltfm_host->scratchpad = val;
103+
imx_data->scratchpad = val;
87104
return;
88105
case SDHCI_COMMAND:
89-
writel(val << 16 | pltfm_host->scratchpad,
106+
writel(val << 16 | imx_data->scratchpad,
90107
host->ioaddr + SDHCI_TRANSFER_MODE);
91108
return;
92109
case SDHCI_BLOCK_SIZE:
@@ -146,7 +163,9 @@ static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
146163
}
147164

148165
static struct sdhci_ops sdhci_esdhc_ops = {
166+
.read_l = esdhc_readl_le,
149167
.read_w = esdhc_readw_le,
168+
.write_l = esdhc_writel_le,
150169
.write_w = esdhc_writew_le,
151170
.write_b = esdhc_writeb_le,
152171
.set_clock = esdhc_set_clock,
@@ -168,6 +187,7 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
168187
struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data;
169188
struct clk *clk;
170189
int err;
190+
struct pltfm_imx_data *imx_data;
171191

172192
clk = clk_get(mmc_dev(host->mmc), NULL);
173193
if (IS_ERR(clk)) {
@@ -177,7 +197,15 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
177197
clk_enable(clk);
178198
pltfm_host->clk = clk;
179199

180-
if (cpu_is_mx35() || cpu_is_mx51())
200+
imx_data = kzalloc(sizeof(struct pltfm_imx_data), GFP_KERNEL);
201+
if (!imx_data) {
202+
clk_disable(pltfm_host->clk);
203+
clk_put(pltfm_host->clk);
204+
return -ENOMEM;
205+
}
206+
pltfm_host->priv = imx_data;
207+
208+
if (!cpu_is_mx25())
181209
host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
182210

183211
if (cpu_is_mx25() || cpu_is_mx35()) {
@@ -214,8 +242,7 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
214242
goto no_card_detect_irq;
215243
}
216244

217-
sdhci_esdhc_ops.write_l = esdhc_writel_le;
218-
sdhci_esdhc_ops.read_l = esdhc_readl_le;
245+
imx_data->flags |= ESDHC_FLAG_GPIO_FOR_CD_WP;
219246
/* Now we have a working card_detect again */
220247
host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
221248
}
@@ -227,13 +254,15 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
227254
no_card_detect_pin:
228255
boarddata->cd_gpio = err;
229256
not_supported:
257+
kfree(imx_data);
230258
return 0;
231259
}
232260

233261
static void esdhc_pltfm_exit(struct sdhci_host *host)
234262
{
235263
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
236264
struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data;
265+
struct pltfm_imx_data *imx_data = pltfm_host->priv;
237266

238267
if (boarddata && gpio_is_valid(boarddata->wp_gpio))
239268
gpio_free(boarddata->wp_gpio);
@@ -247,6 +276,7 @@ static void esdhc_pltfm_exit(struct sdhci_host *host)
247276

248277
clk_disable(pltfm_host->clk);
249278
clk_put(pltfm_host->clk);
279+
kfree(imx_data);
250280
}
251281

252282
struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {

drivers/mmc/host/sdhci-pltfm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
struct sdhci_pltfm_host {
1919
struct clk *clk;
20-
u32 scratchpad; /* to handle quirks across io-accessor calls */
20+
void *priv; /* to handle quirks across io-accessor calls */
2121
};
2222

2323
extern struct sdhci_pltfm_data sdhci_cns3xxx_pdata;

0 commit comments

Comments
 (0)