Commit | Line | Data |
---|---|---|
90c62bf0 | 1 | /* |
d02a900b | 2 | * linux/arch/arm/mach-omap2/hsmmc.c |
90c62bf0 TL |
3 | * |
4 | * Copyright (C) 2007-2008 Texas Instruments | |
5 | * Copyright (C) 2008 Nokia Corporation | |
6 | * Author: Texas Instruments | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License version 2 as | |
10 | * published by the Free Software Foundation. | |
11 | */ | |
db0fefc5 AH |
12 | #include <linux/kernel.h> |
13 | #include <linux/slab.h> | |
14 | #include <linux/string.h> | |
90c62bf0 | 15 | #include <linux/delay.h> |
5e4698fc | 16 | #include <linux/gpio.h> |
826c71a0 | 17 | #include <linux/mmc/host.h> |
4b25408f | 18 | #include <linux/platform_data/gpio-omap.h> |
55143438 | 19 | #include <linux/platform_data/hsmmc-omap.h> |
4b25408f | 20 | |
e4c060db | 21 | #include "soc.h" |
25c7d49e | 22 | #include "omap_device.h" |
1d5aef49 | 23 | #include "omap-pm.h" |
90c62bf0 | 24 | |
d8d0a61c | 25 | #include "mux.h" |
d02a900b | 26 | #include "hsmmc.h" |
4814ced5 | 27 | #include "control.h" |
90c62bf0 | 28 | |
db0fefc5 | 29 | #if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) |
90c62bf0 TL |
30 | |
31 | static u16 control_pbias_offset; | |
32 | static u16 control_devconf1_offset; | |
33 | ||
34 | #define HSMMC_NAME_LEN 9 | |
35 | ||
80412ca8 AF |
36 | static void omap_hsmmc1_before_set_reg(struct device *dev, |
37 | int power_on, int vdd) | |
90c62bf0 | 38 | { |
555d503f | 39 | u32 reg, prog_io; |
55143438 | 40 | struct omap_hsmmc_platform_data *mmc = dev->platform_data; |
90c62bf0 | 41 | |
326119c9 | 42 | if (mmc->remux) |
80412ca8 | 43 | mmc->remux(dev, power_on); |
ce6f0016 | 44 | |
0329c377 DB |
45 | /* |
46 | * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the | |
b583f26d | 47 | * card with Vcc regulator (from twl4030 or whatever). OMAP has both |
0329c377 DB |
48 | * 1.8V and 3.0V modes, controlled by the PBIAS register. |
49 | * | |
50 | * In 8-bit modes, OMAP VMMC1A (for DAT4..7) needs a supply, which | |
51 | * is most naturally TWL VSIM; those pins also use PBIAS. | |
b583f26d DB |
52 | * |
53 | * FIXME handle VMMC1A as needed ... | |
0329c377 | 54 | */ |
90c62bf0 TL |
55 | if (power_on) { |
56 | if (cpu_is_omap2430()) { | |
57 | reg = omap_ctrl_readl(OMAP243X_CONTROL_DEVCONF1); | |
58 | if ((1 << vdd) >= MMC_VDD_30_31) | |
59 | reg |= OMAP243X_MMC1_ACTIVE_OVERWRITE; | |
60 | else | |
61 | reg &= ~OMAP243X_MMC1_ACTIVE_OVERWRITE; | |
62 | omap_ctrl_writel(reg, OMAP243X_CONTROL_DEVCONF1); | |
63 | } | |
64 | ||
326119c9 | 65 | if (mmc->internal_clock) { |
90c62bf0 TL |
66 | reg = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); |
67 | reg |= OMAP2_MMCSDIO1ADPCLKISEL; | |
68 | omap_ctrl_writel(reg, OMAP2_CONTROL_DEVCONF0); | |
69 | } | |
70 | ||
71 | reg = omap_ctrl_readl(control_pbias_offset); | |
555d503f | 72 | if (cpu_is_omap3630()) { |
6a53bc75 | 73 | /* Set MMC I/O to 52MHz */ |
555d503f M |
74 | prog_io = omap_ctrl_readl(OMAP343X_CONTROL_PROG_IO1); |
75 | prog_io |= OMAP3630_PRG_SDMMC1_SPEEDCTRL; | |
76 | omap_ctrl_writel(prog_io, OMAP343X_CONTROL_PROG_IO1); | |
77 | } else { | |
78 | reg |= OMAP2_PBIASSPEEDCTRL0; | |
79 | } | |
90c62bf0 TL |
80 | reg &= ~OMAP2_PBIASLITEPWRDNZ0; |
81 | omap_ctrl_writel(reg, control_pbias_offset); | |
db0fefc5 AH |
82 | } else { |
83 | reg = omap_ctrl_readl(control_pbias_offset); | |
84 | reg &= ~OMAP2_PBIASLITEPWRDNZ0; | |
85 | omap_ctrl_writel(reg, control_pbias_offset); | |
86 | } | |
87 | } | |
88 | ||
80412ca8 | 89 | static void omap_hsmmc1_after_set_reg(struct device *dev, int power_on, int vdd) |
db0fefc5 AH |
90 | { |
91 | u32 reg; | |
90c62bf0 | 92 | |
db0fefc5 AH |
93 | /* 100ms delay required for PBIAS configuration */ |
94 | msleep(100); | |
90c62bf0 | 95 | |
db0fefc5 | 96 | if (power_on) { |
90c62bf0 TL |
97 | reg = omap_ctrl_readl(control_pbias_offset); |
98 | reg |= (OMAP2_PBIASLITEPWRDNZ0 | OMAP2_PBIASSPEEDCTRL0); | |
99 | if ((1 << vdd) <= MMC_VDD_165_195) | |
100 | reg &= ~OMAP2_PBIASLITEVMODE0; | |
101 | else | |
102 | reg |= OMAP2_PBIASLITEVMODE0; | |
103 | omap_ctrl_writel(reg, control_pbias_offset); | |
104 | } else { | |
90c62bf0 TL |
105 | reg = omap_ctrl_readl(control_pbias_offset); |
106 | reg |= (OMAP2_PBIASSPEEDCTRL0 | OMAP2_PBIASLITEPWRDNZ0 | | |
107 | OMAP2_PBIASLITEVMODE0); | |
108 | omap_ctrl_writel(reg, control_pbias_offset); | |
109 | } | |
90c62bf0 TL |
110 | } |
111 | ||
55143438 | 112 | static void hsmmc2_select_input_clk_src(struct omap_hsmmc_platform_data *mmc) |
e62245ba IG |
113 | { |
114 | u32 reg; | |
115 | ||
d82e5190 | 116 | reg = omap_ctrl_readl(control_devconf1_offset); |
326119c9 | 117 | if (mmc->internal_clock) |
e62245ba | 118 | reg |= OMAP2_MMCSDIO2ADPCLKISEL; |
d82e5190 GI |
119 | else |
120 | reg &= ~OMAP2_MMCSDIO2ADPCLKISEL; | |
121 | omap_ctrl_writel(reg, control_devconf1_offset); | |
e62245ba IG |
122 | } |
123 | ||
80412ca8 | 124 | static void hsmmc2_before_set_reg(struct device *dev, int power_on, int vdd) |
90c62bf0 | 125 | { |
55143438 | 126 | struct omap_hsmmc_platform_data *mmc = dev->platform_data; |
b583f26d | 127 | |
326119c9 | 128 | if (mmc->remux) |
80412ca8 | 129 | mmc->remux(dev, power_on); |
ce6f0016 | 130 | |
e62245ba IG |
131 | if (power_on) |
132 | hsmmc2_select_input_clk_src(mmc); | |
133 | } | |
90c62bf0 | 134 | |
80412ca8 | 135 | static int am35x_hsmmc2_set_power(struct device *dev, int power_on, int vdd) |
e62245ba | 136 | { |
55143438 | 137 | struct omap_hsmmc_platform_data *mmc = dev->platform_data; |
e62245ba IG |
138 | |
139 | if (power_on) | |
140 | hsmmc2_select_input_clk_src(mmc); | |
141 | ||
142 | return 0; | |
9b7c18e0 AH |
143 | } |
144 | ||
80412ca8 | 145 | static int nop_mmc_set_power(struct device *dev, int power_on, int vdd) |
03e7e170 | 146 | { |
147 | return 0; | |
148 | } | |
149 | ||
55143438 AF |
150 | static inline void omap_hsmmc_mux(struct omap_hsmmc_platform_data |
151 | *mmc_controller, int controller_nr) | |
d8d0a61c | 152 | { |
b7a5646f AF |
153 | if (gpio_is_valid(mmc_controller->gpio_cd) && |
154 | (mmc_controller->gpio_cd < OMAP_MAX_GPIO_LINES)) | |
155 | omap_mux_init_gpio(mmc_controller->gpio_cd, | |
156 | OMAP_PIN_INPUT_PULLUP); | |
157 | if (gpio_is_valid(mmc_controller->gpio_cod) && | |
158 | (mmc_controller->gpio_cod < OMAP_MAX_GPIO_LINES)) | |
159 | omap_mux_init_gpio(mmc_controller->gpio_cod, | |
326119c9 AF |
160 | OMAP_PIN_INPUT_PULLUP); |
161 | if (gpio_is_valid(mmc_controller->gpio_wp) && | |
162 | (mmc_controller->gpio_wp < OMAP_MAX_GPIO_LINES)) | |
163 | omap_mux_init_gpio(mmc_controller->gpio_wp, | |
164 | OMAP_PIN_INPUT_PULLUP); | |
d8d0a61c KK |
165 | if (cpu_is_omap34xx()) { |
166 | if (controller_nr == 0) { | |
167 | omap_mux_init_signal("sdmmc1_clk", | |
168 | OMAP_PIN_INPUT_PULLUP); | |
169 | omap_mux_init_signal("sdmmc1_cmd", | |
170 | OMAP_PIN_INPUT_PULLUP); | |
171 | omap_mux_init_signal("sdmmc1_dat0", | |
172 | OMAP_PIN_INPUT_PULLUP); | |
326119c9 | 173 | if (mmc_controller->caps & |
d8d0a61c KK |
174 | (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) { |
175 | omap_mux_init_signal("sdmmc1_dat1", | |
176 | OMAP_PIN_INPUT_PULLUP); | |
177 | omap_mux_init_signal("sdmmc1_dat2", | |
178 | OMAP_PIN_INPUT_PULLUP); | |
179 | omap_mux_init_signal("sdmmc1_dat3", | |
180 | OMAP_PIN_INPUT_PULLUP); | |
181 | } | |
326119c9 | 182 | if (mmc_controller->caps & |
d8d0a61c KK |
183 | MMC_CAP_8_BIT_DATA) { |
184 | omap_mux_init_signal("sdmmc1_dat4", | |
185 | OMAP_PIN_INPUT_PULLUP); | |
186 | omap_mux_init_signal("sdmmc1_dat5", | |
187 | OMAP_PIN_INPUT_PULLUP); | |
188 | omap_mux_init_signal("sdmmc1_dat6", | |
189 | OMAP_PIN_INPUT_PULLUP); | |
190 | omap_mux_init_signal("sdmmc1_dat7", | |
191 | OMAP_PIN_INPUT_PULLUP); | |
192 | } | |
193 | } | |
194 | if (controller_nr == 1) { | |
195 | /* MMC2 */ | |
196 | omap_mux_init_signal("sdmmc2_clk", | |
197 | OMAP_PIN_INPUT_PULLUP); | |
198 | omap_mux_init_signal("sdmmc2_cmd", | |
199 | OMAP_PIN_INPUT_PULLUP); | |
200 | omap_mux_init_signal("sdmmc2_dat0", | |
201 | OMAP_PIN_INPUT_PULLUP); | |
202 | ||
203 | /* | |
204 | * For 8 wire configurations, Lines DAT4, 5, 6 and 7 | |
205 | * need to be muxed in the board-*.c files | |
206 | */ | |
326119c9 | 207 | if (mmc_controller->caps & |
d8d0a61c KK |
208 | (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) { |
209 | omap_mux_init_signal("sdmmc2_dat1", | |
210 | OMAP_PIN_INPUT_PULLUP); | |
211 | omap_mux_init_signal("sdmmc2_dat2", | |
212 | OMAP_PIN_INPUT_PULLUP); | |
213 | omap_mux_init_signal("sdmmc2_dat3", | |
214 | OMAP_PIN_INPUT_PULLUP); | |
215 | } | |
326119c9 | 216 | if (mmc_controller->caps & |
d8d0a61c KK |
217 | MMC_CAP_8_BIT_DATA) { |
218 | omap_mux_init_signal("sdmmc2_dat4.sdmmc2_dat4", | |
219 | OMAP_PIN_INPUT_PULLUP); | |
220 | omap_mux_init_signal("sdmmc2_dat5.sdmmc2_dat5", | |
221 | OMAP_PIN_INPUT_PULLUP); | |
222 | omap_mux_init_signal("sdmmc2_dat6.sdmmc2_dat6", | |
223 | OMAP_PIN_INPUT_PULLUP); | |
224 | omap_mux_init_signal("sdmmc2_dat7.sdmmc2_dat7", | |
225 | OMAP_PIN_INPUT_PULLUP); | |
226 | } | |
227 | } | |
228 | ||
229 | /* | |
230 | * For MMC3 the pins need to be muxed in the board-*.c files | |
231 | */ | |
232 | } | |
233 | } | |
234 | ||
d1589f09 | 235 | static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, |
55143438 | 236 | struct omap_hsmmc_platform_data *mmc) |
4621d5f8 KK |
237 | { |
238 | char *hc_name; | |
239 | ||
240 | hc_name = kzalloc(sizeof(char) * (HSMMC_NAME_LEN + 1), GFP_KERNEL); | |
241 | if (!hc_name) { | |
242 | pr_err("Cannot allocate memory for controller slot name\n"); | |
243 | kfree(hc_name); | |
244 | return -ENOMEM; | |
245 | } | |
246 | ||
247 | if (c->name) | |
248 | strncpy(hc_name, c->name, HSMMC_NAME_LEN); | |
249 | else | |
250 | snprintf(hc_name, (HSMMC_NAME_LEN + 1), "mmc%islot%i", | |
251 | c->mmc, 1); | |
326119c9 | 252 | mmc->name = hc_name; |
326119c9 AF |
253 | mmc->caps = c->caps; |
254 | mmc->internal_clock = !c->ext_clock; | |
b30e321b | 255 | mmc->reg_offset = 0; |
4621d5f8 | 256 | |
b7a5646f AF |
257 | if (c->cover_only) { |
258 | /* detect if mobile phone cover removed */ | |
259 | mmc->gpio_cd = -EINVAL; | |
260 | mmc->gpio_cod = c->gpio_cd; | |
261 | } else { | |
262 | /* card detect pin on the mmc socket itself */ | |
263 | mmc->gpio_cd = c->gpio_cd; | |
264 | mmc->gpio_cod = -EINVAL; | |
265 | } | |
326119c9 | 266 | mmc->gpio_wp = c->gpio_wp; |
4621d5f8 | 267 | |
326119c9 AF |
268 | mmc->remux = c->remux; |
269 | mmc->init_card = c->init_card; | |
4621d5f8 | 270 | |
4621d5f8 | 271 | if (c->nonremovable) |
326119c9 | 272 | mmc->nonremovable = 1; |
4621d5f8 | 273 | |
4621d5f8 KK |
274 | /* |
275 | * NOTE: MMC slots should have a Vcc regulator set up. | |
276 | * This may be from a TWL4030-family chip, another | |
277 | * controllable regulator, or a fixed supply. | |
278 | * | |
279 | * temporary HACK: ocr_mask instead of fixed supply | |
280 | */ | |
68a88b98 | 281 | if (soc_is_am35xx()) |
326119c9 | 282 | mmc->ocr_mask = MMC_VDD_165_195 | |
e89715a7 A |
283 | MMC_VDD_26_27 | |
284 | MMC_VDD_27_28 | | |
285 | MMC_VDD_29_30 | | |
286 | MMC_VDD_30_31 | | |
287 | MMC_VDD_31_32; | |
288 | else | |
326119c9 | 289 | mmc->ocr_mask = c->ocr_mask; |
4621d5f8 | 290 | |
68a88b98 | 291 | if (!soc_is_am35xx()) |
326119c9 | 292 | mmc->features |= HSMMC_HAS_PBIAS; |
4621d5f8 | 293 | |
4621d5f8 KK |
294 | switch (c->mmc) { |
295 | case 1: | |
326119c9 | 296 | if (mmc->features & HSMMC_HAS_PBIAS) { |
4621d5f8 | 297 | /* on-chip level shifting via PBIAS0/PBIAS1 */ |
326119c9 | 298 | mmc->before_set_reg = |
b30e321b | 299 | omap_hsmmc1_before_set_reg; |
326119c9 | 300 | mmc->after_set_reg = |
b30e321b | 301 | omap_hsmmc1_after_set_reg; |
4621d5f8 KK |
302 | } |
303 | ||
68a88b98 | 304 | if (soc_is_am35xx()) |
326119c9 | 305 | mmc->set_power = nop_mmc_set_power; |
e62245ba | 306 | |
4621d5f8 KK |
307 | /* OMAP3630 HSMMC1 supports only 4-bit */ |
308 | if (cpu_is_omap3630() && | |
309 | (c->caps & MMC_CAP_8_BIT_DATA)) { | |
310 | c->caps &= ~MMC_CAP_8_BIT_DATA; | |
311 | c->caps |= MMC_CAP_4_BIT_DATA; | |
326119c9 | 312 | mmc->caps = c->caps; |
4621d5f8 KK |
313 | } |
314 | break; | |
315 | case 2: | |
68a88b98 | 316 | if (soc_is_am35xx()) |
326119c9 | 317 | mmc->set_power = am35x_hsmmc2_set_power; |
e62245ba | 318 | |
4621d5f8 KK |
319 | if (c->ext_clock) |
320 | c->transceiver = 1; | |
321 | if (c->transceiver && (c->caps & MMC_CAP_8_BIT_DATA)) { | |
322 | c->caps &= ~MMC_CAP_8_BIT_DATA; | |
323 | c->caps |= MMC_CAP_4_BIT_DATA; | |
324 | } | |
326119c9 | 325 | if (mmc->features & HSMMC_HAS_PBIAS) { |
4621d5f8 | 326 | /* off-chip level shifting, or none */ |
326119c9 AF |
327 | mmc->before_set_reg = hsmmc2_before_set_reg; |
328 | mmc->after_set_reg = NULL; | |
4621d5f8 KK |
329 | } |
330 | break; | |
ffa1e4ed | 331 | case 3: |
4621d5f8 KK |
332 | case 4: |
333 | case 5: | |
326119c9 AF |
334 | mmc->before_set_reg = NULL; |
335 | mmc->after_set_reg = NULL; | |
4621d5f8 KK |
336 | break; |
337 | default: | |
338 | pr_err("MMC%d configuration not supported!\n", c->mmc); | |
339 | kfree(hc_name); | |
340 | return -ENODEV; | |
341 | } | |
342 | return 0; | |
343 | } | |
344 | ||
97899e55 | 345 | static int omap_hsmmc_done; |
3b972bf0 TL |
346 | |
347 | void omap_hsmmc_late_init(struct omap2_hsmmc_info *c) | |
348 | { | |
349 | struct platform_device *pdev; | |
55143438 | 350 | struct omap_hsmmc_platform_data *mmc_pdata; |
3b972bf0 TL |
351 | int res; |
352 | ||
353 | if (omap_hsmmc_done != 1) | |
354 | return; | |
355 | ||
356 | omap_hsmmc_done++; | |
357 | ||
358 | for (; c->mmc; c++) { | |
359 | if (!c->deferred) | |
360 | continue; | |
361 | ||
362 | pdev = c->pdev; | |
363 | if (!pdev) | |
364 | continue; | |
365 | ||
366 | mmc_pdata = pdev->dev.platform_data; | |
367 | if (!mmc_pdata) | |
368 | continue; | |
369 | ||
b7a5646f AF |
370 | if (c->cover_only) { |
371 | /* detect if mobile phone cover removed */ | |
372 | mmc_pdata->gpio_cd = -EINVAL; | |
373 | mmc_pdata->gpio_cod = c->gpio_cd; | |
374 | } else { | |
375 | /* card detect pin on the mmc socket itself */ | |
376 | mmc_pdata->gpio_cd = c->gpio_cd; | |
377 | mmc_pdata->gpio_cod = -EINVAL; | |
378 | } | |
326119c9 | 379 | mmc_pdata->gpio_wp = c->gpio_wp; |
3b972bf0 TL |
380 | |
381 | res = omap_device_register(pdev); | |
382 | if (res) | |
383 | pr_err("Could not late init MMC %s\n", | |
384 | c->name); | |
385 | } | |
386 | } | |
387 | ||
4621d5f8 KK |
388 | #define MAX_OMAP_MMC_HWMOD_NAME_LEN 16 |
389 | ||
6028505c | 390 | static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo, |
3b972bf0 | 391 | int ctrl_nr) |
4621d5f8 KK |
392 | { |
393 | struct omap_hwmod *oh; | |
3b972bf0 TL |
394 | struct omap_hwmod *ohs[1]; |
395 | struct omap_device *od; | |
3528c58e | 396 | struct platform_device *pdev; |
4621d5f8 | 397 | char oh_name[MAX_OMAP_MMC_HWMOD_NAME_LEN]; |
55143438 AF |
398 | struct omap_hsmmc_platform_data *mmc_data; |
399 | struct omap_hsmmc_dev_attr *mmc_dev_attr; | |
4621d5f8 | 400 | char *name; |
3b972bf0 | 401 | int res; |
4621d5f8 | 402 | |
55143438 | 403 | mmc_data = kzalloc(sizeof(*mmc_data), GFP_KERNEL); |
4621d5f8 KK |
404 | if (!mmc_data) { |
405 | pr_err("Cannot allocate memory for mmc device!\n"); | |
3b972bf0 | 406 | return; |
4621d5f8 KK |
407 | } |
408 | ||
3b972bf0 TL |
409 | res = omap_hsmmc_pdata_init(hsmmcinfo, mmc_data); |
410 | if (res < 0) | |
411 | goto free_mmc; | |
412 | ||
4621d5f8 KK |
413 | omap_hsmmc_mux(mmc_data, (ctrl_nr - 1)); |
414 | ||
0005ae73 | 415 | name = "omap_hsmmc"; |
3b972bf0 | 416 | res = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN, |
4621d5f8 | 417 | "mmc%d", ctrl_nr); |
3b972bf0 | 418 | WARN(res >= MAX_OMAP_MMC_HWMOD_NAME_LEN, |
4621d5f8 | 419 | "String buffer overflow in MMC%d device setup\n", ctrl_nr); |
3b972bf0 | 420 | |
4621d5f8 KK |
421 | oh = omap_hwmod_lookup(oh_name); |
422 | if (!oh) { | |
423 | pr_err("Could not look up %s\n", oh_name); | |
3b972bf0 | 424 | goto free_name; |
4621d5f8 | 425 | } |
3b972bf0 | 426 | ohs[0] = oh; |
4621d5f8 KK |
427 | if (oh->dev_attr != NULL) { |
428 | mmc_dev_attr = oh->dev_attr; | |
429 | mmc_data->controller_flags = mmc_dev_attr->flags; | |
26c547fd GI |
430 | /* |
431 | * erratum 2.1.1.128 doesn't apply if board has | |
432 | * a transceiver is attached | |
433 | */ | |
434 | if (hsmmcinfo->transceiver) | |
435 | mmc_data->controller_flags &= | |
436 | ~OMAP_HSMMC_BROKEN_MULTIBLOCK_READ; | |
4621d5f8 KK |
437 | } |
438 | ||
3b972bf0 TL |
439 | pdev = platform_device_alloc(name, ctrl_nr - 1); |
440 | if (!pdev) { | |
441 | pr_err("Could not allocate pdev for %s\n", name); | |
442 | goto free_name; | |
4621d5f8 | 443 | } |
3b972bf0 TL |
444 | dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); |
445 | ||
c1d1cd59 | 446 | od = omap_device_alloc(pdev, ohs, 1); |
64de3a00 | 447 | if (IS_ERR(od)) { |
3b972bf0 TL |
448 | pr_err("Could not allocate od for %s\n", name); |
449 | goto put_pdev; | |
450 | } | |
451 | ||
452 | res = platform_device_add_data(pdev, mmc_data, | |
55143438 | 453 | sizeof(struct omap_hsmmc_platform_data)); |
3b972bf0 TL |
454 | if (res) { |
455 | pr_err("Could not add pdata for %s\n", name); | |
456 | goto put_pdev; | |
457 | } | |
458 | ||
459 | hsmmcinfo->pdev = pdev; | |
460 | ||
461 | if (hsmmcinfo->deferred) | |
462 | goto free_mmc; | |
463 | ||
464 | res = omap_device_register(pdev); | |
465 | if (res) { | |
466 | pr_err("Could not register od for %s\n", name); | |
467 | goto free_od; | |
468 | } | |
469 | ||
470 | goto free_mmc; | |
471 | ||
472 | free_od: | |
473 | omap_device_delete(od); | |
474 | ||
475 | put_pdev: | |
476 | platform_device_put(pdev); | |
477 | ||
478 | free_name: | |
326119c9 | 479 | kfree(mmc_data->name); |
4621d5f8 | 480 | |
3b972bf0 | 481 | free_mmc: |
4621d5f8 KK |
482 | kfree(mmc_data); |
483 | } | |
90c62bf0 | 484 | |
d1589f09 | 485 | void __init omap_hsmmc_init(struct omap2_hsmmc_info *controllers) |
90c62bf0 | 486 | { |
97899e55 TL |
487 | if (omap_hsmmc_done) |
488 | return; | |
489 | ||
490 | omap_hsmmc_done = 1; | |
491 | ||
b30e321b TL |
492 | if (cpu_is_omap2430()) { |
493 | control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE; | |
494 | control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1; | |
90c62bf0 | 495 | } else { |
b30e321b TL |
496 | control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE; |
497 | control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1; | |
90c62bf0 TL |
498 | } |
499 | ||
4621d5f8 | 500 | for (; controllers->mmc; controllers++) |
3b972bf0 | 501 | omap_hsmmc_init_one(controllers, controllers->mmc); |
01971f65 | 502 | |
90c62bf0 TL |
503 | } |
504 | ||
505 | #endif |