aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/hsmmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/hsmmc.c')
-rw-r--r--arch/arm/mach-omap2/hsmmc.c125
1 files changed, 98 insertions, 27 deletions
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index ad0adb5a1e0e..a97876da7fad 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -428,69 +428,140 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
428 return 0; 428 return 0;
429} 429}
430 430
431static int omap_hsmmc_done;
432
433void omap_hsmmc_late_init(struct omap2_hsmmc_info *c)
434{
435 struct platform_device *pdev;
436 struct omap_mmc_platform_data *mmc_pdata;
437 int res;
438
439 if (omap_hsmmc_done != 1)
440 return;
441
442 omap_hsmmc_done++;
443
444 for (; c->mmc; c++) {
445 if (!c->deferred)
446 continue;
447
448 pdev = c->pdev;
449 if (!pdev)
450 continue;
451
452 mmc_pdata = pdev->dev.platform_data;
453 if (!mmc_pdata)
454 continue;
455
456 mmc_pdata->slots[0].switch_pin = c->gpio_cd;
457 mmc_pdata->slots[0].gpio_wp = c->gpio_wp;
458
459 res = omap_device_register(pdev);
460 if (res)
461 pr_err("Could not late init MMC %s\n",
462 c->name);
463 }
464}
465
431#define MAX_OMAP_MMC_HWMOD_NAME_LEN 16 466#define MAX_OMAP_MMC_HWMOD_NAME_LEN 16
432 467
433void __init omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr) 468static void omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo,
469 int ctrl_nr)
434{ 470{
435 struct omap_hwmod *oh; 471 struct omap_hwmod *oh;
472 struct omap_hwmod *ohs[1];
473 struct omap_device *od;
436 struct platform_device *pdev; 474 struct platform_device *pdev;
437 char oh_name[MAX_OMAP_MMC_HWMOD_NAME_LEN]; 475 char oh_name[MAX_OMAP_MMC_HWMOD_NAME_LEN];
438 struct omap_mmc_platform_data *mmc_data; 476 struct omap_mmc_platform_data *mmc_data;
439 struct omap_mmc_dev_attr *mmc_dev_attr; 477 struct omap_mmc_dev_attr *mmc_dev_attr;
440 char *name; 478 char *name;
441 int l; 479 int res;
442 480
443 mmc_data = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL); 481 mmc_data = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL);
444 if (!mmc_data) { 482 if (!mmc_data) {
445 pr_err("Cannot allocate memory for mmc device!\n"); 483 pr_err("Cannot allocate memory for mmc device!\n");
446 goto done; 484 return;
447 } 485 }
448 486
449 if (omap_hsmmc_pdata_init(hsmmcinfo, mmc_data) < 0) { 487 res = omap_hsmmc_pdata_init(hsmmcinfo, mmc_data);
450 pr_err("%s fails!\n", __func__); 488 if (res < 0)
451 goto done; 489 goto free_mmc;
452 } 490
453 omap_hsmmc_mux(mmc_data, (ctrl_nr - 1)); 491 omap_hsmmc_mux(mmc_data, (ctrl_nr - 1));
454 492
455 name = "omap_hsmmc"; 493 name = "omap_hsmmc";
456 494 res = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN,
457 l = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN,
458 "mmc%d", ctrl_nr); 495 "mmc%d", ctrl_nr);
459 WARN(l >= MAX_OMAP_MMC_HWMOD_NAME_LEN, 496 WARN(res >= MAX_OMAP_MMC_HWMOD_NAME_LEN,
460 "String buffer overflow in MMC%d device setup\n", ctrl_nr); 497 "String buffer overflow in MMC%d device setup\n", ctrl_nr);
498
461 oh = omap_hwmod_lookup(oh_name); 499 oh = omap_hwmod_lookup(oh_name);
462 if (!oh) { 500 if (!oh) {
463 pr_err("Could not look up %s\n", oh_name); 501 pr_err("Could not look up %s\n", oh_name);
464 kfree(mmc_data->slots[0].name); 502 goto free_name;
465 goto done;
466 } 503 }
467 504 ohs[0] = oh;
468 if (oh->dev_attr != NULL) { 505 if (oh->dev_attr != NULL) {
469 mmc_dev_attr = oh->dev_attr; 506 mmc_dev_attr = oh->dev_attr;
470 mmc_data->controller_flags = mmc_dev_attr->flags; 507 mmc_data->controller_flags = mmc_dev_attr->flags;
471 } 508 }
472 509
473 pdev = omap_device_build(name, ctrl_nr - 1, oh, mmc_data, 510 pdev = platform_device_alloc(name, ctrl_nr - 1);
474 sizeof(struct omap_mmc_platform_data), NULL, 0, false); 511 if (!pdev) {
475 if (IS_ERR(pdev)) { 512 pr_err("Could not allocate pdev for %s\n", name);
476 WARN(1, "Can't build omap_device for %s:%s.\n", name, oh->name); 513 goto free_name;
477 kfree(mmc_data->slots[0].name);
478 goto done;
479 } 514 }
480 /* 515 dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
481 * return device handle to board setup code 516
482 * required to populate for regulator framework structure 517 od = omap_device_alloc(pdev, ohs, 1, NULL, 0);
483 */ 518 if (!od) {
484 hsmmcinfo->dev = &pdev->dev; 519 pr_err("Could not allocate od for %s\n", name);
520 goto put_pdev;
521 }
522
523 res = platform_device_add_data(pdev, mmc_data,
524 sizeof(struct omap_mmc_platform_data));
525 if (res) {
526 pr_err("Could not add pdata for %s\n", name);
527 goto put_pdev;
528 }
529
530 hsmmcinfo->pdev = pdev;
531
532 if (hsmmcinfo->deferred)
533 goto free_mmc;
485 534
486done: 535 res = omap_device_register(pdev);
536 if (res) {
537 pr_err("Could not register od for %s\n", name);
538 goto free_od;
539 }
540
541 goto free_mmc;
542
543free_od:
544 omap_device_delete(od);
545
546put_pdev:
547 platform_device_put(pdev);
548
549free_name:
550 kfree(mmc_data->slots[0].name);
551
552free_mmc:
487 kfree(mmc_data); 553 kfree(mmc_data);
488} 554}
489 555
490void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers) 556void __init omap_hsmmc_init(struct omap2_hsmmc_info *controllers)
491{ 557{
492 u32 reg; 558 u32 reg;
493 559
560 if (omap_hsmmc_done)
561 return;
562
563 omap_hsmmc_done = 1;
564
494 if (!cpu_is_omap44xx()) { 565 if (!cpu_is_omap44xx()) {
495 if (cpu_is_omap2430()) { 566 if (cpu_is_omap2430()) {
496 control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE; 567 control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE;
@@ -515,7 +586,7 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
515 } 586 }
516 587
517 for (; controllers->mmc; controllers++) 588 for (; controllers->mmc; controllers++)
518 omap_init_hsmmc(controllers, controllers->mmc); 589 omap_hsmmc_init_one(controllers, controllers->mmc);
519 590
520} 591}
521 592