diff options
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r-- | arch/arm/plat-omap/include/plat/omap_hwmod.h | 1 | ||||
-rw-r--r-- | arch/arm/plat-omap/omap_device.c | 71 |
2 files changed, 60 insertions, 12 deletions
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 6132972aff37..5857b9cd6eb9 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h | |||
@@ -615,6 +615,7 @@ int omap_hwmod_softreset(struct omap_hwmod *oh); | |||
615 | 615 | ||
616 | int omap_hwmod_count_resources(struct omap_hwmod *oh); | 616 | int omap_hwmod_count_resources(struct omap_hwmod *oh); |
617 | int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res); | 617 | int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res); |
618 | int omap_hwmod_fill_dma_resources(struct omap_hwmod *oh, struct resource *res); | ||
618 | int omap_hwmod_get_resource_byname(struct omap_hwmod *oh, unsigned int type, | 619 | int omap_hwmod_get_resource_byname(struct omap_hwmod *oh, unsigned int type, |
619 | const char *name, struct resource *res); | 620 | const char *name, struct resource *res); |
620 | 621 | ||
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index ff57b5aeba4e..6f5c58096819 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c | |||
@@ -494,6 +494,33 @@ static int omap_device_fill_resources(struct omap_device *od, | |||
494 | } | 494 | } |
495 | 495 | ||
496 | /** | 496 | /** |
497 | * _od_fill_dma_resources - fill in array of struct resource with dma resources | ||
498 | * @od: struct omap_device * | ||
499 | * @res: pointer to an array of struct resource to be filled in | ||
500 | * | ||
501 | * Populate one or more empty struct resource pointed to by @res with | ||
502 | * the dma resource data for this omap_device @od. Used by | ||
503 | * omap_device_alloc() after calling omap_device_count_resources(). | ||
504 | * | ||
505 | * Ideally this function would not be needed at all. If we have | ||
506 | * mechanism to get dma resources from DT. | ||
507 | * | ||
508 | * Returns 0. | ||
509 | */ | ||
510 | static int _od_fill_dma_resources(struct omap_device *od, | ||
511 | struct resource *res) | ||
512 | { | ||
513 | int i, r; | ||
514 | |||
515 | for (i = 0; i < od->hwmods_cnt; i++) { | ||
516 | r = omap_hwmod_fill_dma_resources(od->hwmods[i], res); | ||
517 | res += r; | ||
518 | } | ||
519 | |||
520 | return 0; | ||
521 | } | ||
522 | |||
523 | /** | ||
497 | * omap_device_alloc - allocate an omap_device | 524 | * omap_device_alloc - allocate an omap_device |
498 | * @pdev: platform_device that will be included in this omap_device | 525 | * @pdev: platform_device that will be included in this omap_device |
499 | * @oh: ptr to the single omap_hwmod that backs this omap_device | 526 | * @oh: ptr to the single omap_hwmod that backs this omap_device |
@@ -532,24 +559,44 @@ struct omap_device *omap_device_alloc(struct platform_device *pdev, | |||
532 | od->hwmods = hwmods; | 559 | od->hwmods = hwmods; |
533 | od->pdev = pdev; | 560 | od->pdev = pdev; |
534 | 561 | ||
562 | res_count = omap_device_count_resources(od); | ||
535 | /* | 563 | /* |
536 | * HACK: Ideally the resources from DT should match, and hwmod | 564 | * DT Boot: |
537 | * should just add the missing ones. Since the name is not | 565 | * OF framework will construct the resource structure (currently |
538 | * properly populated by DT, stick to hwmod resources only. | 566 | * does for MEM & IRQ resource) and we should respect/use these |
567 | * resources, killing hwmod dependency. | ||
568 | * If pdev->num_resources > 0, we assume that MEM & IRQ resources | ||
569 | * have been allocated by OF layer already (through DTB). | ||
570 | * | ||
571 | * Non-DT Boot: | ||
572 | * Here, pdev->num_resources = 0, and we should get all the | ||
573 | * resources from hwmod. | ||
574 | * | ||
575 | * TODO: Once DMA resource is available from OF layer, we should | ||
576 | * kill filling any resources from hwmod. | ||
539 | */ | 577 | */ |
540 | if (pdev->num_resources && pdev->resource) | 578 | if (res_count > pdev->num_resources) { |
541 | dev_warn(&pdev->dev, "%s(): resources already allocated %d\n", | 579 | /* Allocate resources memory to account for new resources */ |
542 | __func__, pdev->num_resources); | ||
543 | |||
544 | res_count = omap_device_count_resources(od); | ||
545 | if (res_count > 0) { | ||
546 | dev_dbg(&pdev->dev, "%s(): resources allocated from hwmod %d\n", | ||
547 | __func__, res_count); | ||
548 | res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL); | 580 | res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL); |
549 | if (!res) | 581 | if (!res) |
550 | goto oda_exit3; | 582 | goto oda_exit3; |
551 | 583 | ||
552 | omap_device_fill_resources(od, res); | 584 | /* |
585 | * If pdev->num_resources > 0, then assume that, | ||
586 | * MEM and IRQ resources will only come from DT and only | ||
587 | * fill DMA resource from hwmod layer. | ||
588 | */ | ||
589 | if (pdev->num_resources && pdev->resource) { | ||
590 | dev_dbg(&pdev->dev, "%s(): resources already allocated %d\n", | ||
591 | __func__, res_count); | ||
592 | memcpy(res, pdev->resource, | ||
593 | sizeof(struct resource) * pdev->num_resources); | ||
594 | _od_fill_dma_resources(od, &res[pdev->num_resources]); | ||
595 | } else { | ||
596 | dev_dbg(&pdev->dev, "%s(): using resources from hwmod %d\n", | ||
597 | __func__, res_count); | ||
598 | omap_device_fill_resources(od, res); | ||
599 | } | ||
553 | 600 | ||
554 | ret = platform_device_add_resources(pdev, res, res_count); | 601 | ret = platform_device_add_resources(pdev, res, res_count); |
555 | kfree(res); | 602 | kfree(res); |