diff options
author | Peter Ujfalusi <peter.ujfalusi@ti.com> | 2012-11-21 18:15:18 -0500 |
---|---|---|
committer | Paul Walmsley <paul@pwsan.com> | 2012-11-21 18:15:18 -0500 |
commit | c567b0584c352e7f97ced003be46bed8581ddd5b (patch) | |
tree | 282feb4b7a0f4b430b363048616f50e27f656594 /arch/arm/mach-omap2/omap_device.c | |
parent | dad4191d79bded6674529084bcf842c00e4d874a (diff) |
ARM: OMAP2+: omap_device: Correct resource handling for DT boot
When booting with DT the OF core can fill up the resources provided within
the DT blob.
The current way of handling the DT boot prevents us from removing hwmod data
for platforms only suppose to boot with DT (OMAP5 for example) since we need
to keep the whole hwmod database intact in order to have more resources in
hwmod than in DT (to be able to append the DMA resource from hwmod).
To fix this issue we just examine the OF provided resources:
If we do not have resources we use hwmod to fill them.
If we have resources we check if we already able to recive DMA resource, if
no we only append the DMA resurce from hwmod to the OF provided ones.
In this way we can start removing hwmod data for devices which have their
resources correctly configured in DT without regressions.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Acked-by: BenoƮt Cousson <b-cousson@ti.com>
[paul@pwsan.com: fixed checkpatch problem; updated to apply]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Diffstat (limited to 'arch/arm/mach-omap2/omap_device.c')
-rw-r--r-- | arch/arm/mach-omap2/omap_device.c | 84 |
1 files changed, 51 insertions, 33 deletions
diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index 8917a0881206..e065daa537c0 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c | |||
@@ -559,55 +559,73 @@ struct omap_device *omap_device_alloc(struct platform_device *pdev, | |||
559 | od->hwmods = hwmods; | 559 | od->hwmods = hwmods; |
560 | od->pdev = pdev; | 560 | od->pdev = pdev; |
561 | 561 | ||
562 | /* Count all resources for the device */ | ||
563 | res_count = omap_device_count_resources(od, IORESOURCE_IRQ | | ||
564 | IORESOURCE_DMA | | ||
565 | IORESOURCE_MEM); | ||
566 | /* | 562 | /* |
563 | * Non-DT Boot: | ||
564 | * Here, pdev->num_resources = 0, and we should get all the | ||
565 | * resources from hwmod. | ||
566 | * | ||
567 | * DT Boot: | 567 | * DT Boot: |
568 | * OF framework will construct the resource structure (currently | 568 | * OF framework will construct the resource structure (currently |
569 | * does for MEM & IRQ resource) and we should respect/use these | 569 | * does for MEM & IRQ resource) and we should respect/use these |
570 | * resources, killing hwmod dependency. | 570 | * resources, killing hwmod dependency. |
571 | * If pdev->num_resources > 0, we assume that MEM & IRQ resources | 571 | * If pdev->num_resources > 0, we assume that MEM & IRQ resources |
572 | * have been allocated by OF layer already (through DTB). | 572 | * have been allocated by OF layer already (through DTB). |
573 | * | 573 | * As preparation for the future we examine the OF provided resources |
574 | * Non-DT Boot: | 574 | * to see if we have DMA resources provided already. In this case |
575 | * Here, pdev->num_resources = 0, and we should get all the | 575 | * there is no need to update the resources for the device, we use the |
576 | * resources from hwmod. | 576 | * OF provided ones. |
577 | * | 577 | * |
578 | * TODO: Once DMA resource is available from OF layer, we should | 578 | * TODO: Once DMA resource is available from OF layer, we should |
579 | * kill filling any resources from hwmod. | 579 | * kill filling any resources from hwmod. |
580 | */ | 580 | */ |
581 | if (res_count > pdev->num_resources) { | 581 | if (!pdev->num_resources) { |
582 | /* Allocate resources memory to account for new resources */ | 582 | /* Count all resources for the device */ |
583 | res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL); | 583 | res_count = omap_device_count_resources(od, IORESOURCE_IRQ | |
584 | if (!res) | 584 | IORESOURCE_DMA | |
585 | goto oda_exit3; | 585 | IORESOURCE_MEM); |
586 | 586 | } else { | |
587 | /* | 587 | /* Take a look if we already have DMA resource via DT */ |
588 | * If pdev->num_resources > 0, then assume that, | 588 | for (i = 0; i < pdev->num_resources; i++) { |
589 | * MEM and IRQ resources will only come from DT and only | 589 | struct resource *r = &pdev->resource[i]; |
590 | * fill DMA resource from hwmod layer. | 590 | |
591 | */ | 591 | /* We have it, no need to touch the resources */ |
592 | if (pdev->num_resources && pdev->resource) { | 592 | if (r->flags == IORESOURCE_DMA) |
593 | dev_dbg(&pdev->dev, "%s(): resources already allocated %d\n", | 593 | goto have_everything; |
594 | __func__, res_count); | ||
595 | memcpy(res, pdev->resource, | ||
596 | sizeof(struct resource) * pdev->num_resources); | ||
597 | _od_fill_dma_resources(od, &res[pdev->num_resources]); | ||
598 | } else { | ||
599 | dev_dbg(&pdev->dev, "%s(): using resources from hwmod %d\n", | ||
600 | __func__, res_count); | ||
601 | omap_device_fill_resources(od, res); | ||
602 | } | 594 | } |
595 | /* Count only DMA resources for the device */ | ||
596 | res_count = omap_device_count_resources(od, IORESOURCE_DMA); | ||
597 | /* The device has no DMA resource, no need for update */ | ||
598 | if (!res_count) | ||
599 | goto have_everything; | ||
603 | 600 | ||
604 | ret = platform_device_add_resources(pdev, res, res_count); | 601 | res_count += pdev->num_resources; |
605 | kfree(res); | 602 | } |
606 | 603 | ||
607 | if (ret) | 604 | /* Allocate resources memory to account for new resources */ |
608 | goto oda_exit3; | 605 | res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL); |
606 | if (!res) | ||
607 | goto oda_exit3; | ||
608 | |||
609 | if (!pdev->num_resources) { | ||
610 | dev_dbg(&pdev->dev, "%s: using %d resources from hwmod\n", | ||
611 | __func__, res_count); | ||
612 | omap_device_fill_resources(od, res); | ||
613 | } else { | ||
614 | dev_dbg(&pdev->dev, | ||
615 | "%s: appending %d DMA resources from hwmod\n", | ||
616 | __func__, res_count - pdev->num_resources); | ||
617 | memcpy(res, pdev->resource, | ||
618 | sizeof(struct resource) * pdev->num_resources); | ||
619 | _od_fill_dma_resources(od, &res[pdev->num_resources]); | ||
609 | } | 620 | } |
610 | 621 | ||
622 | ret = platform_device_add_resources(pdev, res, res_count); | ||
623 | kfree(res); | ||
624 | |||
625 | if (ret) | ||
626 | goto oda_exit3; | ||
627 | |||
628 | have_everything: | ||
611 | if (!pm_lats) { | 629 | if (!pm_lats) { |
612 | pm_lats = omap_default_latency; | 630 | pm_lats = omap_default_latency; |
613 | pm_lats_cnt = ARRAY_SIZE(omap_default_latency); | 631 | pm_lats_cnt = ARRAY_SIZE(omap_default_latency); |