aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/hsmmc.c
diff options
context:
space:
mode:
authorKishore Kadiyala <kishore.kadiyala@ti.com>2011-02-28 10:18:04 -0500
committerTony Lindgren <tony@atomide.com>2011-03-01 16:13:25 -0500
commit4621d5f8cb435b1ba74efe6e0a7125febb40186b (patch)
tree7dc7961bd638dc6f8a8de4f8cdda1871564a8200 /arch/arm/mach-omap2/hsmmc.c
parentd8d0a61c658e252de3077f6076f13423642caf67 (diff)
OMAP: adapt hsmmc to hwmod framework
OMAP2420 platform consists of mmc block as in omap1 and not the hsmmc block as present in omap2430, omap3, omap4 platforms. Removing all base address macro defines except keeping one for OMAP2420 and adapting only hsmmc device registration and driver to hwmod framework. Changes involves: 1) Remove controller reset in devices.c which is taken care of by hwmod framework. 2) Using omap-device layer to register device and utilizing data from hwmod data file for base address, dma channel number, Irq_number, device attribute. 3) Update the driver to use dev_attr to find whether controller supports dual volt cards Signed-off-by: Paul Walmsley <paul@pwsan.com> Signed-off-by: Kishore Kadiyala <kishore.kadiyala@ti.com> Reviewed-by: Balaji T K <balajitk@ti.com> Cc: Benoit Cousson <b-cousson@ti.com> CC: Kevin Hilman <khilman@deeprootsystems.com> Cc: Tony Lindgren <tony@atomide.com> Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm/mach-omap2/hsmmc.c')
-rw-r--r--arch/arm/mach-omap2/hsmmc.c346
1 files changed, 197 insertions, 149 deletions
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 1348ac3d60e3..d492bc4d3428 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -17,6 +17,7 @@
17#include <plat/mmc.h> 17#include <plat/mmc.h>
18#include <plat/omap-pm.h> 18#include <plat/omap-pm.h>
19#include <plat/mux.h> 19#include <plat/mux.h>
20#include <plat/omap_device.h>
20 21
21#include "mux.h" 22#include "mux.h"
22#include "hsmmc.h" 23#include "hsmmc.h"
@@ -30,10 +31,6 @@ static u16 control_mmc1;
30 31
31#define HSMMC_NAME_LEN 9 32#define HSMMC_NAME_LEN 9
32 33
33static struct hsmmc_controller {
34 char name[HSMMC_NAME_LEN + 1];
35} hsmmc[OMAP34XX_NR_MMC];
36
37#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) 34#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
38 35
39static int hsmmc_get_context_loss(struct device *dev) 36static int hsmmc_get_context_loss(struct device *dev)
@@ -287,13 +284,203 @@ static inline void omap_hsmmc_mux(struct omap_mmc_platform_data *mmc_controller,
287 } 284 }
288} 285}
289 286
290static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata; 287static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
288 struct omap_mmc_platform_data *mmc)
289{
290 char *hc_name;
291
292 hc_name = kzalloc(sizeof(char) * (HSMMC_NAME_LEN + 1), GFP_KERNEL);
293 if (!hc_name) {
294 pr_err("Cannot allocate memory for controller slot name\n");
295 kfree(hc_name);
296 return -ENOMEM;
297 }
298
299 if (c->name)
300 strncpy(hc_name, c->name, HSMMC_NAME_LEN);
301 else
302 snprintf(hc_name, (HSMMC_NAME_LEN + 1), "mmc%islot%i",
303 c->mmc, 1);
304 mmc->slots[0].name = hc_name;
305 mmc->nr_slots = 1;
306 mmc->slots[0].caps = c->caps;
307 mmc->slots[0].internal_clock = !c->ext_clock;
308 mmc->dma_mask = 0xffffffff;
309 if (cpu_is_omap44xx())
310 mmc->reg_offset = OMAP4_MMC_REG_OFFSET;
311 else
312 mmc->reg_offset = 0;
313
314 mmc->get_context_loss_count = hsmmc_get_context_loss;
315
316 mmc->slots[0].switch_pin = c->gpio_cd;
317 mmc->slots[0].gpio_wp = c->gpio_wp;
318
319 mmc->slots[0].remux = c->remux;
320 mmc->slots[0].init_card = c->init_card;
321
322 if (c->cover_only)
323 mmc->slots[0].cover = 1;
324
325 if (c->nonremovable)
326 mmc->slots[0].nonremovable = 1;
327
328 if (c->power_saving)
329 mmc->slots[0].power_saving = 1;
330
331 if (c->no_off)
332 mmc->slots[0].no_off = 1;
333
334 if (c->vcc_aux_disable_is_sleep)
335 mmc->slots[0].vcc_aux_disable_is_sleep = 1;
336
337 /*
338 * NOTE: MMC slots should have a Vcc regulator set up.
339 * This may be from a TWL4030-family chip, another
340 * controllable regulator, or a fixed supply.
341 *
342 * temporary HACK: ocr_mask instead of fixed supply
343 */
344 mmc->slots[0].ocr_mask = c->ocr_mask;
345
346 if (cpu_is_omap3517() || cpu_is_omap3505())
347 mmc->slots[0].set_power = nop_mmc_set_power;
348 else
349 mmc->slots[0].features |= HSMMC_HAS_PBIAS;
350
351 if (cpu_is_omap44xx() && (omap_rev() > OMAP4430_REV_ES1_0))
352 mmc->slots[0].features |= HSMMC_HAS_UPDATED_RESET;
353
354 switch (c->mmc) {
355 case 1:
356 if (mmc->slots[0].features & HSMMC_HAS_PBIAS) {
357 /* on-chip level shifting via PBIAS0/PBIAS1 */
358 if (cpu_is_omap44xx()) {
359 mmc->slots[0].before_set_reg =
360 omap4_hsmmc1_before_set_reg;
361 mmc->slots[0].after_set_reg =
362 omap4_hsmmc1_after_set_reg;
363 } else {
364 mmc->slots[0].before_set_reg =
365 omap_hsmmc1_before_set_reg;
366 mmc->slots[0].after_set_reg =
367 omap_hsmmc1_after_set_reg;
368 }
369 }
370
371 /* OMAP3630 HSMMC1 supports only 4-bit */
372 if (cpu_is_omap3630() &&
373 (c->caps & MMC_CAP_8_BIT_DATA)) {
374 c->caps &= ~MMC_CAP_8_BIT_DATA;
375 c->caps |= MMC_CAP_4_BIT_DATA;
376 mmc->slots[0].caps = c->caps;
377 }
378 break;
379 case 2:
380 if (c->ext_clock)
381 c->transceiver = 1;
382 if (c->transceiver && (c->caps & MMC_CAP_8_BIT_DATA)) {
383 c->caps &= ~MMC_CAP_8_BIT_DATA;
384 c->caps |= MMC_CAP_4_BIT_DATA;
385 }
386 /* FALLTHROUGH */
387 case 3:
388 if (mmc->slots[0].features & HSMMC_HAS_PBIAS) {
389 /* off-chip level shifting, or none */
390 mmc->slots[0].before_set_reg = hsmmc23_before_set_reg;
391 mmc->slots[0].after_set_reg = NULL;
392 }
393 break;
394 case 4:
395 case 5:
396 mmc->slots[0].before_set_reg = NULL;
397 mmc->slots[0].after_set_reg = NULL;
398 break;
399 default:
400 pr_err("MMC%d configuration not supported!\n", c->mmc);
401 kfree(hc_name);
402 return -ENODEV;
403 }
404 return 0;
405}
406
407static struct omap_device_pm_latency omap_hsmmc_latency[] = {
408 [0] = {
409 .deactivate_func = omap_device_idle_hwmods,
410 .activate_func = omap_device_enable_hwmods,
411 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
412 },
413 /*
414 * XXX There should also be an entry here to power off/on the
415 * MMC regulators/PBIAS cells, etc.
416 */
417};
418
419#define MAX_OMAP_MMC_HWMOD_NAME_LEN 16
420
421void __init omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr)
422{
423 struct omap_hwmod *oh;
424 struct omap_device *od;
425 struct omap_device_pm_latency *ohl;
426 char oh_name[MAX_OMAP_MMC_HWMOD_NAME_LEN];
427 struct omap_mmc_platform_data *mmc_data;
428 struct omap_mmc_dev_attr *mmc_dev_attr;
429 char *name;
430 int l;
431 int ohl_cnt = 0;
432
433 mmc_data = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL);
434 if (!mmc_data) {
435 pr_err("Cannot allocate memory for mmc device!\n");
436 goto done;
437 }
438
439 if (omap_hsmmc_pdata_init(hsmmcinfo, mmc_data) < 0) {
440 pr_err("%s fails!\n", __func__);
441 goto done;
442 }
443 omap_hsmmc_mux(mmc_data, (ctrl_nr - 1));
444
445 name = "mmci-omap-hs";
446 ohl = omap_hsmmc_latency;
447 ohl_cnt = ARRAY_SIZE(omap_hsmmc_latency);
448
449 l = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN,
450 "mmc%d", ctrl_nr);
451 WARN(l >= MAX_OMAP_MMC_HWMOD_NAME_LEN,
452 "String buffer overflow in MMC%d device setup\n", ctrl_nr);
453 oh = omap_hwmod_lookup(oh_name);
454 if (!oh) {
455 pr_err("Could not look up %s\n", oh_name);
456 kfree(mmc_data->slots[0].name);
457 goto done;
458 }
459
460 if (oh->dev_attr != NULL) {
461 mmc_dev_attr = oh->dev_attr;
462 mmc_data->controller_flags = mmc_dev_attr->flags;
463 }
464
465 od = omap_device_build(name, ctrl_nr - 1, oh, mmc_data,
466 sizeof(struct omap_mmc_platform_data), ohl, ohl_cnt, false);
467 if (IS_ERR(od)) {
468 WARN(1, "Cant build omap_device for %s:%s.\n", name, oh->name);
469 kfree(mmc_data->slots[0].name);
470 goto done;
471 }
472 /*
473 * return device handle to board setup code
474 * required to populate for regulator framework structure
475 */
476 hsmmcinfo->dev = &od->pdev.dev;
477
478done:
479 kfree(mmc_data);
480}
291 481
292void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers) 482void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
293{ 483{
294 struct omap2_hsmmc_info *c;
295 int nr_hsmmc = ARRAY_SIZE(hsmmc_data);
296 int i;
297 u32 reg; 484 u32 reg;
298 485
299 if (!cpu_is_omap44xx()) { 486 if (!cpu_is_omap44xx()) {
@@ -319,148 +506,9 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
319 omap4_ctrl_pad_writel(reg, control_mmc1); 506 omap4_ctrl_pad_writel(reg, control_mmc1);
320 } 507 }
321 508
322 for (c = controllers; c->mmc; c++) { 509 for (; controllers->mmc; controllers++)
323 struct hsmmc_controller *hc = hsmmc + c->mmc - 1; 510 omap_init_hsmmc(controllers, controllers->mmc);
324 struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1];
325
326 if (!c->mmc || c->mmc > nr_hsmmc) {
327 pr_debug("MMC%d: no such controller\n", c->mmc);
328 continue;
329 }
330 if (mmc) {
331 pr_debug("MMC%d: already configured\n", c->mmc);
332 continue;
333 }
334
335 mmc = kzalloc(sizeof(struct omap_mmc_platform_data),
336 GFP_KERNEL);
337 if (!mmc) {
338 pr_err("Cannot allocate memory for mmc device!\n");
339 goto done;
340 }
341
342 if (c->name)
343 strncpy(hc->name, c->name, HSMMC_NAME_LEN);
344 else
345 snprintf(hc->name, ARRAY_SIZE(hc->name),
346 "mmc%islot%i", c->mmc, 1);
347 mmc->slots[0].name = hc->name;
348 mmc->nr_slots = 1;
349 mmc->slots[0].caps = c->caps;
350 mmc->slots[0].internal_clock = !c->ext_clock;
351 mmc->dma_mask = 0xffffffff;
352 if (cpu_is_omap44xx())
353 mmc->reg_offset = OMAP4_MMC_REG_OFFSET;
354 else
355 mmc->reg_offset = 0;
356
357 mmc->get_context_loss_count = hsmmc_get_context_loss;
358
359 mmc->slots[0].switch_pin = c->gpio_cd;
360 mmc->slots[0].gpio_wp = c->gpio_wp;
361
362 mmc->slots[0].remux = c->remux;
363 mmc->slots[0].init_card = c->init_card;
364
365 if (c->cover_only)
366 mmc->slots[0].cover = 1;
367
368 if (c->nonremovable)
369 mmc->slots[0].nonremovable = 1;
370
371 if (c->power_saving)
372 mmc->slots[0].power_saving = 1;
373
374 if (c->no_off)
375 mmc->slots[0].no_off = 1;
376
377 if (c->vcc_aux_disable_is_sleep)
378 mmc->slots[0].vcc_aux_disable_is_sleep = 1;
379
380 /* NOTE: MMC slots should have a Vcc regulator set up.
381 * This may be from a TWL4030-family chip, another
382 * controllable regulator, or a fixed supply.
383 *
384 * temporary HACK: ocr_mask instead of fixed supply
385 */
386 mmc->slots[0].ocr_mask = c->ocr_mask;
387
388 if (cpu_is_omap3517() || cpu_is_omap3505())
389 mmc->slots[0].set_power = nop_mmc_set_power;
390 else
391 mmc->slots[0].features |= HSMMC_HAS_PBIAS;
392
393 if (cpu_is_omap44xx() && (omap_rev() > OMAP4430_REV_ES1_0))
394 mmc->slots[0].features |= HSMMC_HAS_UPDATED_RESET;
395
396 switch (c->mmc) {
397 case 1:
398 if (mmc->slots[0].features & HSMMC_HAS_PBIAS) {
399 /* on-chip level shifting via PBIAS0/PBIAS1 */
400 if (cpu_is_omap44xx()) {
401 mmc->slots[0].before_set_reg =
402 omap4_hsmmc1_before_set_reg;
403 mmc->slots[0].after_set_reg =
404 omap4_hsmmc1_after_set_reg;
405 } else {
406 mmc->slots[0].before_set_reg =
407 omap_hsmmc1_before_set_reg;
408 mmc->slots[0].after_set_reg =
409 omap_hsmmc1_after_set_reg;
410 }
411 }
412
413 /* Omap3630 HSMMC1 supports only 4-bit */
414 if (cpu_is_omap3630() &&
415 (c->caps & MMC_CAP_8_BIT_DATA)) {
416 c->caps &= ~MMC_CAP_8_BIT_DATA;
417 c->caps |= MMC_CAP_4_BIT_DATA;
418 mmc->slots[0].caps = c->caps;
419 }
420 break;
421 case 2:
422 if (c->ext_clock)
423 c->transceiver = 1;
424 if (c->transceiver && (c->caps & MMC_CAP_8_BIT_DATA)) {
425 c->caps &= ~MMC_CAP_8_BIT_DATA;
426 c->caps |= MMC_CAP_4_BIT_DATA;
427 }
428 /* FALLTHROUGH */
429 case 3:
430 if (mmc->slots[0].features & HSMMC_HAS_PBIAS) {
431 /* off-chip level shifting, or none */
432 mmc->slots[0].before_set_reg = hsmmc23_before_set_reg;
433 mmc->slots[0].after_set_reg = NULL;
434 }
435 break;
436 case 4:
437 case 5:
438 mmc->slots[0].before_set_reg = NULL;
439 mmc->slots[0].after_set_reg = NULL;
440 break;
441 default:
442 pr_err("MMC%d configuration not supported!\n", c->mmc);
443 kfree(mmc);
444 continue;
445 }
446 hsmmc_data[c->mmc - 1] = mmc;
447 omap_hsmmc_mux(hsmmc_data[c->mmc - 1], (c->mmc - 1));
448 }
449
450 omap2_init_mmc(hsmmc_data, OMAP34XX_NR_MMC);
451
452 /* pass the device nodes back to board setup code */
453 for (c = controllers; c->mmc; c++) {
454 struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1];
455 511
456 if (!c->mmc || c->mmc > nr_hsmmc)
457 continue;
458 c->dev = mmc->dev;
459 }
460
461done:
462 for (i = 0; i < nr_hsmmc; i++)
463 kfree(hsmmc_data[i]);
464} 512}
465 513
466#endif 514#endif