diff options
Diffstat (limited to 'arch/arm/mach-omap2/mmc-twl4030.c')
-rw-r--r-- | arch/arm/mach-omap2/mmc-twl4030.c | 352 |
1 files changed, 31 insertions, 321 deletions
diff --git a/arch/arm/mach-omap2/mmc-twl4030.c b/arch/arm/mach-omap2/mmc-twl4030.c index 8afe9dd3f150..6f8f29e99ff2 100644 --- a/arch/arm/mach-omap2/mmc-twl4030.c +++ b/arch/arm/mach-omap2/mmc-twl4030.c | |||
@@ -9,26 +9,17 @@ | |||
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | #include <linux/err.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/io.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/module.h> | 14 | #include <linux/string.h> |
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/interrupt.h> | ||
17 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
18 | #include <linux/gpio.h> | ||
19 | #include <linux/mmc/host.h> | ||
20 | #include <linux/regulator/consumer.h> | ||
21 | |||
22 | #include <mach/hardware.h> | 16 | #include <mach/hardware.h> |
23 | #include <plat/control.h> | 17 | #include <plat/control.h> |
24 | #include <plat/mmc.h> | 18 | #include <plat/mmc.h> |
25 | #include <plat/board.h> | ||
26 | 19 | ||
27 | #include "mmc-twl4030.h" | 20 | #include "mmc-twl4030.h" |
28 | 21 | ||
29 | 22 | #if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) | |
30 | #if defined(CONFIG_REGULATOR) && \ | ||
31 | (defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)) | ||
32 | 23 | ||
33 | static u16 control_pbias_offset; | 24 | static u16 control_pbias_offset; |
34 | static u16 control_devconf1_offset; | 25 | static u16 control_devconf1_offset; |
@@ -36,168 +27,9 @@ static u16 control_devconf1_offset; | |||
36 | #define HSMMC_NAME_LEN 9 | 27 | #define HSMMC_NAME_LEN 9 |
37 | 28 | ||
38 | static struct twl_mmc_controller { | 29 | static struct twl_mmc_controller { |
39 | struct omap_mmc_platform_data *mmc; | ||
40 | /* Vcc == configured supply | ||
41 | * Vcc_alt == optional | ||
42 | * - MMC1, supply for DAT4..DAT7 | ||
43 | * - MMC2/MMC2, external level shifter voltage supply, for | ||
44 | * chip (SDIO, eMMC, etc) or transceiver (MMC2 only) | ||
45 | */ | ||
46 | struct regulator *vcc; | ||
47 | struct regulator *vcc_aux; | ||
48 | char name[HSMMC_NAME_LEN + 1]; | 30 | char name[HSMMC_NAME_LEN + 1]; |
49 | } hsmmc[OMAP34XX_NR_MMC]; | 31 | } hsmmc[OMAP34XX_NR_MMC]; |
50 | 32 | ||
51 | static int twl_mmc_card_detect(int irq) | ||
52 | { | ||
53 | unsigned i; | ||
54 | |||
55 | for (i = 0; i < ARRAY_SIZE(hsmmc); i++) { | ||
56 | struct omap_mmc_platform_data *mmc; | ||
57 | |||
58 | mmc = hsmmc[i].mmc; | ||
59 | if (!mmc) | ||
60 | continue; | ||
61 | if (irq != mmc->slots[0].card_detect_irq) | ||
62 | continue; | ||
63 | |||
64 | /* NOTE: assumes card detect signal is active-low */ | ||
65 | return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); | ||
66 | } | ||
67 | return -ENOSYS; | ||
68 | } | ||
69 | |||
70 | static int twl_mmc_get_ro(struct device *dev, int slot) | ||
71 | { | ||
72 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
73 | |||
74 | /* NOTE: assumes write protect signal is active-high */ | ||
75 | return gpio_get_value_cansleep(mmc->slots[0].gpio_wp); | ||
76 | } | ||
77 | |||
78 | static int twl_mmc_get_cover_state(struct device *dev, int slot) | ||
79 | { | ||
80 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
81 | |||
82 | /* NOTE: assumes card detect signal is active-low */ | ||
83 | return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); | ||
84 | } | ||
85 | |||
86 | /* | ||
87 | * MMC Slot Initialization. | ||
88 | */ | ||
89 | static int twl_mmc_late_init(struct device *dev) | ||
90 | { | ||
91 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
92 | int ret = 0; | ||
93 | int i; | ||
94 | |||
95 | /* MMC/SD/SDIO doesn't require a card detect switch */ | ||
96 | if (gpio_is_valid(mmc->slots[0].switch_pin)) { | ||
97 | ret = gpio_request(mmc->slots[0].switch_pin, "mmc_cd"); | ||
98 | if (ret) | ||
99 | goto done; | ||
100 | ret = gpio_direction_input(mmc->slots[0].switch_pin); | ||
101 | if (ret) | ||
102 | goto err; | ||
103 | } | ||
104 | |||
105 | /* require at least main regulator */ | ||
106 | for (i = 0; i < ARRAY_SIZE(hsmmc); i++) { | ||
107 | if (hsmmc[i].name == mmc->slots[0].name) { | ||
108 | struct regulator *reg; | ||
109 | |||
110 | hsmmc[i].mmc = mmc; | ||
111 | |||
112 | reg = regulator_get(dev, "vmmc"); | ||
113 | if (IS_ERR(reg)) { | ||
114 | dev_dbg(dev, "vmmc regulator missing\n"); | ||
115 | /* HACK: until fixed.c regulator is usable, | ||
116 | * we don't require a main regulator | ||
117 | * for MMC2 or MMC3 | ||
118 | */ | ||
119 | if (i != 0) | ||
120 | break; | ||
121 | ret = PTR_ERR(reg); | ||
122 | hsmmc[i].vcc = NULL; | ||
123 | goto err; | ||
124 | } | ||
125 | hsmmc[i].vcc = reg; | ||
126 | mmc->slots[0].ocr_mask = mmc_regulator_get_ocrmask(reg); | ||
127 | |||
128 | /* allow an aux regulator */ | ||
129 | reg = regulator_get(dev, "vmmc_aux"); | ||
130 | hsmmc[i].vcc_aux = IS_ERR(reg) ? NULL : reg; | ||
131 | |||
132 | /* UGLY HACK: workaround regulator framework bugs. | ||
133 | * When the bootloader leaves a supply active, it's | ||
134 | * initialized with zero usecount ... and we can't | ||
135 | * disable it without first enabling it. Until the | ||
136 | * framework is fixed, we need a workaround like this | ||
137 | * (which is safe for MMC, but not in general). | ||
138 | */ | ||
139 | if (regulator_is_enabled(hsmmc[i].vcc) > 0) { | ||
140 | regulator_enable(hsmmc[i].vcc); | ||
141 | regulator_disable(hsmmc[i].vcc); | ||
142 | } | ||
143 | if (hsmmc[i].vcc_aux) { | ||
144 | if (regulator_is_enabled(reg) > 0) { | ||
145 | regulator_enable(reg); | ||
146 | regulator_disable(reg); | ||
147 | } | ||
148 | } | ||
149 | |||
150 | break; | ||
151 | } | ||
152 | } | ||
153 | |||
154 | return 0; | ||
155 | |||
156 | err: | ||
157 | gpio_free(mmc->slots[0].switch_pin); | ||
158 | done: | ||
159 | mmc->slots[0].card_detect_irq = 0; | ||
160 | mmc->slots[0].card_detect = NULL; | ||
161 | |||
162 | dev_err(dev, "err %d configuring card detect\n", ret); | ||
163 | return ret; | ||
164 | } | ||
165 | |||
166 | static void twl_mmc_cleanup(struct device *dev) | ||
167 | { | ||
168 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
169 | int i; | ||
170 | |||
171 | gpio_free(mmc->slots[0].switch_pin); | ||
172 | for(i = 0; i < ARRAY_SIZE(hsmmc); i++) { | ||
173 | regulator_put(hsmmc[i].vcc); | ||
174 | regulator_put(hsmmc[i].vcc_aux); | ||
175 | } | ||
176 | } | ||
177 | |||
178 | #ifdef CONFIG_PM | ||
179 | |||
180 | static int twl_mmc_suspend(struct device *dev, int slot) | ||
181 | { | ||
182 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
183 | |||
184 | disable_irq(mmc->slots[0].card_detect_irq); | ||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | static int twl_mmc_resume(struct device *dev, int slot) | ||
189 | { | ||
190 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
191 | |||
192 | enable_irq(mmc->slots[0].card_detect_irq); | ||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | #else | ||
197 | #define twl_mmc_suspend NULL | ||
198 | #define twl_mmc_resume NULL | ||
199 | #endif | ||
200 | |||
201 | #if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) | 33 | #if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) |
202 | 34 | ||
203 | static int twl4030_mmc_get_context_loss(struct device *dev) | 35 | static int twl4030_mmc_get_context_loss(struct device *dev) |
@@ -210,12 +42,10 @@ static int twl4030_mmc_get_context_loss(struct device *dev) | |||
210 | #define twl4030_mmc_get_context_loss NULL | 42 | #define twl4030_mmc_get_context_loss NULL |
211 | #endif | 43 | #endif |
212 | 44 | ||
213 | static int twl_mmc1_set_power(struct device *dev, int slot, int power_on, | 45 | static void hsmmc1_before_set_reg(struct device *dev, int slot, |
214 | int vdd) | 46 | int power_on, int vdd) |
215 | { | 47 | { |
216 | u32 reg, prog_io; | 48 | u32 reg, prog_io; |
217 | int ret = 0; | ||
218 | struct twl_mmc_controller *c = &hsmmc[0]; | ||
219 | struct omap_mmc_platform_data *mmc = dev->platform_data; | 49 | struct omap_mmc_platform_data *mmc = dev->platform_data; |
220 | 50 | ||
221 | /* | 51 | /* |
@@ -255,11 +85,22 @@ static int twl_mmc1_set_power(struct device *dev, int slot, int power_on, | |||
255 | } | 85 | } |
256 | reg &= ~OMAP2_PBIASLITEPWRDNZ0; | 86 | reg &= ~OMAP2_PBIASLITEPWRDNZ0; |
257 | omap_ctrl_writel(reg, control_pbias_offset); | 87 | omap_ctrl_writel(reg, control_pbias_offset); |
88 | } else { | ||
89 | reg = omap_ctrl_readl(control_pbias_offset); | ||
90 | reg &= ~OMAP2_PBIASLITEPWRDNZ0; | ||
91 | omap_ctrl_writel(reg, control_pbias_offset); | ||
92 | } | ||
93 | } | ||
94 | |||
95 | static void hsmmc1_after_set_reg(struct device *dev, int slot, | ||
96 | int power_on, int vdd) | ||
97 | { | ||
98 | u32 reg; | ||
258 | 99 | ||
259 | ret = mmc_regulator_set_ocr(c->vcc, vdd); | 100 | /* 100ms delay required for PBIAS configuration */ |
101 | msleep(100); | ||
260 | 102 | ||
261 | /* 100ms delay required for PBIAS configuration */ | 103 | if (power_on) { |
262 | msleep(100); | ||
263 | reg = omap_ctrl_readl(control_pbias_offset); | 104 | reg = omap_ctrl_readl(control_pbias_offset); |
264 | reg |= (OMAP2_PBIASLITEPWRDNZ0 | OMAP2_PBIASSPEEDCTRL0); | 105 | reg |= (OMAP2_PBIASLITEPWRDNZ0 | OMAP2_PBIASSPEEDCTRL0); |
265 | if ((1 << vdd) <= MMC_VDD_165_195) | 106 | if ((1 << vdd) <= MMC_VDD_165_195) |
@@ -269,60 +110,19 @@ static int twl_mmc1_set_power(struct device *dev, int slot, int power_on, | |||
269 | omap_ctrl_writel(reg, control_pbias_offset); | 110 | omap_ctrl_writel(reg, control_pbias_offset); |
270 | } else { | 111 | } else { |
271 | reg = omap_ctrl_readl(control_pbias_offset); | 112 | reg = omap_ctrl_readl(control_pbias_offset); |
272 | reg &= ~OMAP2_PBIASLITEPWRDNZ0; | ||
273 | omap_ctrl_writel(reg, control_pbias_offset); | ||
274 | |||
275 | ret = mmc_regulator_set_ocr(c->vcc, 0); | ||
276 | |||
277 | /* 100ms delay required for PBIAS configuration */ | ||
278 | msleep(100); | ||
279 | reg = omap_ctrl_readl(control_pbias_offset); | ||
280 | reg |= (OMAP2_PBIASSPEEDCTRL0 | OMAP2_PBIASLITEPWRDNZ0 | | 113 | reg |= (OMAP2_PBIASSPEEDCTRL0 | OMAP2_PBIASLITEPWRDNZ0 | |
281 | OMAP2_PBIASLITEVMODE0); | 114 | OMAP2_PBIASLITEVMODE0); |
282 | omap_ctrl_writel(reg, control_pbias_offset); | 115 | omap_ctrl_writel(reg, control_pbias_offset); |
283 | } | 116 | } |
284 | |||
285 | return ret; | ||
286 | } | 117 | } |
287 | 118 | ||
288 | static int twl_mmc23_set_power(struct device *dev, int slot, int power_on, int vdd) | 119 | static void hsmmc23_before_set_reg(struct device *dev, int slot, |
120 | int power_on, int vdd) | ||
289 | { | 121 | { |
290 | int ret = 0; | ||
291 | struct twl_mmc_controller *c = NULL; | ||
292 | struct omap_mmc_platform_data *mmc = dev->platform_data; | 122 | struct omap_mmc_platform_data *mmc = dev->platform_data; |
293 | int i; | ||
294 | |||
295 | for (i = 1; i < ARRAY_SIZE(hsmmc); i++) { | ||
296 | if (mmc == hsmmc[i].mmc) { | ||
297 | c = &hsmmc[i]; | ||
298 | break; | ||
299 | } | ||
300 | } | ||
301 | |||
302 | if (c == NULL) | ||
303 | return -ENODEV; | ||
304 | |||
305 | /* If we don't see a Vcc regulator, assume it's a fixed | ||
306 | * voltage always-on regulator. | ||
307 | */ | ||
308 | if (!c->vcc) | ||
309 | return 0; | ||
310 | 123 | ||
311 | /* | ||
312 | * Assume Vcc regulator is used only to power the card ... OMAP | ||
313 | * VDDS is used to power the pins, optionally with a transceiver to | ||
314 | * support cards using voltages other than VDDS (1.8V nominal). When a | ||
315 | * transceiver is used, DAT3..7 are muxed as transceiver control pins. | ||
316 | * | ||
317 | * In some cases this regulator won't support enable/disable; | ||
318 | * e.g. it's a fixed rail for a WLAN chip. | ||
319 | * | ||
320 | * In other cases vcc_aux switches interface power. Example, for | ||
321 | * eMMC cards it represents VccQ. Sometimes transceivers or SDIO | ||
322 | * chips/cards need an interface voltage rail too. | ||
323 | */ | ||
324 | if (power_on) { | 124 | if (power_on) { |
325 | /* only MMC2 supports a CLKIN */ | 125 | /* Only MMC2 supports a CLKIN */ |
326 | if (mmc->slots[0].internal_clock) { | 126 | if (mmc->slots[0].internal_clock) { |
327 | u32 reg; | 127 | u32 reg; |
328 | 128 | ||
@@ -330,76 +130,7 @@ static int twl_mmc23_set_power(struct device *dev, int slot, int power_on, int v | |||
330 | reg |= OMAP2_MMCSDIO2ADPCLKISEL; | 130 | reg |= OMAP2_MMCSDIO2ADPCLKISEL; |
331 | omap_ctrl_writel(reg, control_devconf1_offset); | 131 | omap_ctrl_writel(reg, control_devconf1_offset); |
332 | } | 132 | } |
333 | ret = mmc_regulator_set_ocr(c->vcc, vdd); | ||
334 | /* enable interface voltage rail, if needed */ | ||
335 | if (ret == 0 && c->vcc_aux) { | ||
336 | ret = regulator_enable(c->vcc_aux); | ||
337 | if (ret < 0) | ||
338 | ret = mmc_regulator_set_ocr(c->vcc, 0); | ||
339 | } | ||
340 | } else { | ||
341 | if (c->vcc_aux && (ret = regulator_is_enabled(c->vcc_aux)) > 0) | ||
342 | ret = regulator_disable(c->vcc_aux); | ||
343 | if (ret == 0) | ||
344 | ret = mmc_regulator_set_ocr(c->vcc, 0); | ||
345 | } | ||
346 | |||
347 | return ret; | ||
348 | } | ||
349 | |||
350 | static int twl_mmc1_set_sleep(struct device *dev, int slot, int sleep, int vdd, | ||
351 | int cardsleep) | ||
352 | { | ||
353 | struct twl_mmc_controller *c = &hsmmc[0]; | ||
354 | int mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL; | ||
355 | |||
356 | return regulator_set_mode(c->vcc, mode); | ||
357 | } | ||
358 | |||
359 | static int twl_mmc23_set_sleep(struct device *dev, int slot, int sleep, int vdd, | ||
360 | int cardsleep) | ||
361 | { | ||
362 | struct twl_mmc_controller *c = NULL; | ||
363 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
364 | int i, err, mode; | ||
365 | |||
366 | for (i = 1; i < ARRAY_SIZE(hsmmc); i++) { | ||
367 | if (mmc == hsmmc[i].mmc) { | ||
368 | c = &hsmmc[i]; | ||
369 | break; | ||
370 | } | ||
371 | } | 133 | } |
372 | |||
373 | if (c == NULL) | ||
374 | return -ENODEV; | ||
375 | |||
376 | /* | ||
377 | * If we don't see a Vcc regulator, assume it's a fixed | ||
378 | * voltage always-on regulator. | ||
379 | */ | ||
380 | if (!c->vcc) | ||
381 | return 0; | ||
382 | |||
383 | mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL; | ||
384 | |||
385 | if (!c->vcc_aux) | ||
386 | return regulator_set_mode(c->vcc, mode); | ||
387 | |||
388 | if (cardsleep) { | ||
389 | /* VCC can be turned off if card is asleep */ | ||
390 | struct regulator *vcc_aux = c->vcc_aux; | ||
391 | |||
392 | c->vcc_aux = NULL; | ||
393 | if (sleep) | ||
394 | err = twl_mmc23_set_power(dev, slot, 0, 0); | ||
395 | else | ||
396 | err = twl_mmc23_set_power(dev, slot, 1, vdd); | ||
397 | c->vcc_aux = vcc_aux; | ||
398 | } else | ||
399 | err = regulator_set_mode(c->vcc, mode); | ||
400 | if (err) | ||
401 | return err; | ||
402 | return regulator_set_mode(c->vcc_aux, mode); | ||
403 | } | 134 | } |
404 | 135 | ||
405 | static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata; | 136 | static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata; |
@@ -413,7 +144,6 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) | |||
413 | if (cpu_is_omap2430()) { | 144 | if (cpu_is_omap2430()) { |
414 | control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE; | 145 | control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE; |
415 | control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1; | 146 | control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1; |
416 | nr_hsmmc = 2; | ||
417 | } else { | 147 | } else { |
418 | control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE; | 148 | control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE; |
419 | control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1; | 149 | control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1; |
@@ -448,35 +178,15 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) | |||
448 | mmc->slots[0].wires = c->wires; | 178 | mmc->slots[0].wires = c->wires; |
449 | mmc->slots[0].internal_clock = !c->ext_clock; | 179 | mmc->slots[0].internal_clock = !c->ext_clock; |
450 | mmc->dma_mask = 0xffffffff; | 180 | mmc->dma_mask = 0xffffffff; |
451 | mmc->init = twl_mmc_late_init; | ||
452 | |||
453 | /* note: twl4030 card detect GPIOs can disable VMMCx ... */ | ||
454 | if (gpio_is_valid(c->gpio_cd)) { | ||
455 | mmc->cleanup = twl_mmc_cleanup; | ||
456 | mmc->suspend = twl_mmc_suspend; | ||
457 | mmc->resume = twl_mmc_resume; | ||
458 | |||
459 | mmc->slots[0].switch_pin = c->gpio_cd; | ||
460 | mmc->slots[0].card_detect_irq = gpio_to_irq(c->gpio_cd); | ||
461 | if (c->cover_only) | ||
462 | mmc->slots[0].get_cover_state = twl_mmc_get_cover_state; | ||
463 | else | ||
464 | mmc->slots[0].card_detect = twl_mmc_card_detect; | ||
465 | } else | ||
466 | mmc->slots[0].switch_pin = -EINVAL; | ||
467 | 181 | ||
468 | mmc->get_context_loss_count = | 182 | mmc->get_context_loss_count = |
469 | twl4030_mmc_get_context_loss; | 183 | twl4030_mmc_get_context_loss; |
470 | 184 | ||
471 | /* write protect normally uses an OMAP gpio */ | 185 | mmc->slots[0].switch_pin = c->gpio_cd; |
472 | if (gpio_is_valid(c->gpio_wp)) { | 186 | mmc->slots[0].gpio_wp = c->gpio_wp; |
473 | gpio_request(c->gpio_wp, "mmc_wp"); | ||
474 | gpio_direction_input(c->gpio_wp); | ||
475 | 187 | ||
476 | mmc->slots[0].gpio_wp = c->gpio_wp; | 188 | if (c->cover_only) |
477 | mmc->slots[0].get_ro = twl_mmc_get_ro; | 189 | mmc->slots[0].cover = 1; |
478 | } else | ||
479 | mmc->slots[0].gpio_wp = -EINVAL; | ||
480 | 190 | ||
481 | if (c->nonremovable) | 191 | if (c->nonremovable) |
482 | mmc->slots[0].nonremovable = 1; | 192 | mmc->slots[0].nonremovable = 1; |
@@ -495,8 +205,8 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) | |||
495 | switch (c->mmc) { | 205 | switch (c->mmc) { |
496 | case 1: | 206 | case 1: |
497 | /* on-chip level shifting via PBIAS0/PBIAS1 */ | 207 | /* on-chip level shifting via PBIAS0/PBIAS1 */ |
498 | mmc->slots[0].set_power = twl_mmc1_set_power; | 208 | mmc->slots[0].before_set_reg = hsmmc1_before_set_reg; |
499 | mmc->slots[0].set_sleep = twl_mmc1_set_sleep; | 209 | mmc->slots[0].after_set_reg = hsmmc1_after_set_reg; |
500 | 210 | ||
501 | /* Omap3630 HSMMC1 supports only 4-bit */ | 211 | /* Omap3630 HSMMC1 supports only 4-bit */ |
502 | if (cpu_is_omap3630() && c->wires > 4) { | 212 | if (cpu_is_omap3630() && c->wires > 4) { |
@@ -512,8 +222,8 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) | |||
512 | /* FALLTHROUGH */ | 222 | /* FALLTHROUGH */ |
513 | case 3: | 223 | case 3: |
514 | /* off-chip level shifting, or none */ | 224 | /* off-chip level shifting, or none */ |
515 | mmc->slots[0].set_power = twl_mmc23_set_power; | 225 | mmc->slots[0].before_set_reg = hsmmc23_before_set_reg; |
516 | mmc->slots[0].set_sleep = twl_mmc23_set_sleep; | 226 | mmc->slots[0].after_set_reg = NULL; |
517 | break; | 227 | break; |
518 | default: | 228 | default: |
519 | pr_err("MMC%d configuration not supported!\n", c->mmc); | 229 | pr_err("MMC%d configuration not supported!\n", c->mmc); |