aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/omap_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/omap_device.c')
-rw-r--r--arch/arm/mach-omap2/omap_device.c87
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 */
450static int omap_device_count_resources(struct omap_device *od) 451static 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
628have_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);