diff options
Diffstat (limited to 'arch/arm/mach-omap2/omap_device.c')
-rw-r--r-- | arch/arm/mach-omap2/omap_device.c | 87 |
1 files changed, 55 insertions, 32 deletions
diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index 0ef934fec364..e065daa537c0 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c | |||
@@ -441,19 +441,21 @@ int omap_device_get_context_loss_count(struct platform_device *pdev) | |||
441 | /** | 441 | /** |
442 | * omap_device_count_resources - count number of struct resource entries needed | 442 | * omap_device_count_resources - count number of struct resource entries needed |
443 | * @od: struct omap_device * | 443 | * @od: struct omap_device * |
444 | * @flags: Type of resources to include when counting (IRQ/DMA/MEM) | ||
444 | * | 445 | * |
445 | * Count the number of struct resource entries needed for this | 446 | * Count the number of struct resource entries needed for this |
446 | * omap_device @od. Used by omap_device_build_ss() to determine how | 447 | * omap_device @od. Used by omap_device_build_ss() to determine how |
447 | * much memory to allocate before calling | 448 | * much memory to allocate before calling |
448 | * omap_device_fill_resources(). Returns the count. | 449 | * omap_device_fill_resources(). Returns the count. |
449 | */ | 450 | */ |
450 | static int omap_device_count_resources(struct omap_device *od) | 451 | static int omap_device_count_resources(struct omap_device *od, |
452 | unsigned long flags) | ||
451 | { | 453 | { |
452 | int c = 0; | 454 | int c = 0; |
453 | int i; | 455 | int i; |
454 | 456 | ||
455 | for (i = 0; i < od->hwmods_cnt; i++) | 457 | for (i = 0; i < od->hwmods_cnt; i++) |
456 | c += omap_hwmod_count_resources(od->hwmods[i]); | 458 | c += omap_hwmod_count_resources(od->hwmods[i], flags); |
457 | 459 | ||
458 | pr_debug("omap_device: %s: counted %d total resources across %d hwmods\n", | 460 | pr_debug("omap_device: %s: counted %d total resources across %d hwmods\n", |
459 | od->pdev->name, c, od->hwmods_cnt); | 461 | od->pdev->name, c, od->hwmods_cnt); |
@@ -557,52 +559,73 @@ struct omap_device *omap_device_alloc(struct platform_device *pdev, | |||
557 | od->hwmods = hwmods; | 559 | od->hwmods = hwmods; |
558 | od->pdev = pdev; | 560 | od->pdev = pdev; |
559 | 561 | ||
560 | res_count = omap_device_count_resources(od); | ||
561 | /* | 562 | /* |
563 | * Non-DT Boot: | ||
564 | * Here, pdev->num_resources = 0, and we should get all the | ||
565 | * resources from hwmod. | ||
566 | * | ||
562 | * DT Boot: | 567 | * DT Boot: |
563 | * OF framework will construct the resource structure (currently | 568 | * OF framework will construct the resource structure (currently |
564 | * does for MEM & IRQ resource) and we should respect/use these | 569 | * does for MEM & IRQ resource) and we should respect/use these |
565 | * resources, killing hwmod dependency. | 570 | * resources, killing hwmod dependency. |
566 | * If pdev->num_resources > 0, we assume that MEM & IRQ resources | 571 | * If pdev->num_resources > 0, we assume that MEM & IRQ resources |
567 | * have been allocated by OF layer already (through DTB). | 572 | * have been allocated by OF layer already (through DTB). |
568 | * | 573 | * As preparation for the future we examine the OF provided resources |
569 | * Non-DT Boot: | 574 | * to see if we have DMA resources provided already. In this case |
570 | * 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 |
571 | * resources from hwmod. | 576 | * OF provided ones. |
572 | * | 577 | * |
573 | * TODO: Once DMA resource is available from OF layer, we should | 578 | * TODO: Once DMA resource is available from OF layer, we should |
574 | * kill filling any resources from hwmod. | 579 | * kill filling any resources from hwmod. |
575 | */ | 580 | */ |
576 | if (res_count > pdev->num_resources) { | 581 | if (!pdev->num_resources) { |
577 | /* Allocate resources memory to account for new resources */ | 582 | /* Count all resources for the device */ |
578 | res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL); | 583 | res_count = omap_device_count_resources(od, IORESOURCE_IRQ | |
579 | if (!res) | 584 | IORESOURCE_DMA | |
580 | goto oda_exit3; | 585 | IORESOURCE_MEM); |
581 | 586 | } else { | |
582 | /* | 587 | /* Take a look if we already have DMA resource via DT */ |
583 | * If pdev->num_resources > 0, then assume that, | 588 | for (i = 0; i < pdev->num_resources; i++) { |
584 | * MEM and IRQ resources will only come from DT and only | 589 | struct resource *r = &pdev->resource[i]; |
585 | * fill DMA resource from hwmod layer. | 590 | |
586 | */ | 591 | /* We have it, no need to touch the resources */ |
587 | if (pdev->num_resources && pdev->resource) { | 592 | if (r->flags == IORESOURCE_DMA) |
588 | dev_dbg(&pdev->dev, "%s(): resources already allocated %d\n", | 593 | goto have_everything; |
589 | __func__, res_count); | ||
590 | memcpy(res, pdev->resource, | ||
591 | sizeof(struct resource) * pdev->num_resources); | ||
592 | _od_fill_dma_resources(od, &res[pdev->num_resources]); | ||
593 | } else { | ||
594 | dev_dbg(&pdev->dev, "%s(): using resources from hwmod %d\n", | ||
595 | __func__, res_count); | ||
596 | omap_device_fill_resources(od, res); | ||
597 | } | 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; | ||
598 | 600 | ||
599 | ret = platform_device_add_resources(pdev, res, res_count); | 601 | res_count += pdev->num_resources; |
600 | kfree(res); | 602 | } |
601 | 603 | ||
602 | if (ret) | 604 | /* Allocate resources memory to account for new resources */ |
603 | 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]); | ||
604 | } | 620 | } |
605 | 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: | ||
606 | if (!pm_lats) { | 629 | if (!pm_lats) { |
607 | pm_lats = omap_default_latency; | 630 | pm_lats = omap_default_latency; |
608 | pm_lats_cnt = ARRAY_SIZE(omap_default_latency); | 631 | pm_lats_cnt = ARRAY_SIZE(omap_default_latency); |