summaryrefslogtreecommitdiffstats
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)
/**
* omap_device_count_resources - count number of struct resource entries needed
* @od: struct omap_device *
+ * @flags: Type of resources to include when counting (IRQ/DMA/MEM)
*
* Count the number of struct resource entries needed for this
* omap_device @od. Used by omap_device_build_ss() to determine how
* much memory to allocate before calling
* omap_device_fill_resources(). Returns the count.
*/
-static int omap_device_count_resources(struct omap_device *od)
+static int omap_device_count_resources(struct omap_device *od,
+ unsigned long flags)
{
int c = 0;
int i;
for (i = 0; i < od->hwmods_cnt; i++)
- c += omap_hwmod_count_resources(od->hwmods[i]);
+ c += omap_hwmod_count_resources(od->hwmods[i], flags);
pr_debug("omap_device: %s: counted %d total resources across %d hwmods\n",
od->pdev->name, c, od->hwmods_cnt);
@@ -557,52 +559,73 @@ struct omap_device *omap_device_alloc(struct platform_device *pdev,
od->hwmods = hwmods;
od->pdev = pdev;
- res_count = omap_device_count_resources(od);
/*
+ * Non-DT Boot:
+ * Here, pdev->num_resources = 0, and we should get all the
+ * resources from hwmod.
+ *
* DT Boot:
* OF framework will construct the resource structure (currently
* does for MEM & IRQ resource) and we should respect/use these
* resources, killing hwmod dependency.
* If pdev->num_resources > 0, we assume that MEM & IRQ resources
* have been allocated by OF layer already (through DTB).
- *
- * Non-DT Boot:
- * Here, pdev->num_resources = 0, and we should get all the
- * resources from hwmod.
+ * As preparation for the future we examine the OF provided resources
+ * to see if we have DMA resources provided already. In this case
+ * there is no need to update the resources for the device, we use the
+ * OF provided ones.
*
* TODO: Once DMA resource is available from OF layer, we should
* kill filling any resources from hwmod.
*/
- if (res_count > pdev->num_resources) {
- /* Allocate resources memory to account for new resources */
- res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
- if (!res)
- goto oda_exit3;
-
- /*
- * If pdev->num_resources > 0, then assume that,
- * MEM and IRQ resources will only come from DT and only
- * fill DMA resource from hwmod layer.
- */
- if (pdev->num_resources && pdev->resource) {
- dev_dbg(&pdev->dev, "%s(): resources already allocated %d\n",
- __func__, res_count);
- memcpy(res, pdev->resource,
- sizeof(struct resource) * pdev->num_resources);
- _od_fill_dma_resources(od, &res[pdev->num_resources]);
- } else {
- dev_dbg(&pdev->dev, "%s(): using resources from hwmod %d\n",
- __func__, res_count);
- omap_device_fill_resources(od, res);
+ if (!pdev->num_resources) {
+ /* Count all resources for the device */
+ res_count = omap_device_count_resources(od, IORESOURCE_IRQ |
+ IORESOURCE_DMA |
+ IORESOURCE_MEM);
+ } else {
+ /* Take a look if we already have DMA resource via DT */
+ for (i = 0; i < pdev->num_resources; i++) {
+ struct resource *r = &pdev->resource[i];
+
+ /* We have it, no need to touch the resources */
+ if (r->flags == IORESOURCE_DMA)
+ goto have_everything;
}
+ /* Count only DMA resources for the device */
+ res_count = omap_device_count_resources(od, IORESOURCE_DMA);
+ /* The device has no DMA resource, no need for update */
+ if (!res_count)
+ goto have_everything;
- ret = platform_device_add_resources(pdev, res, res_count);
- kfree(res);
+ res_count += pdev->num_resources;
+ }
- if (ret)
- goto oda_exit3;
+ /* Allocate resources memory to account for new resources */
+ res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
+ if (!res)
+ goto oda_exit3;
+
+ if (!pdev->num_resources) {
+ dev_dbg(&pdev->dev, "%s: using %d resources from hwmod\n",
+ __func__, res_count);
+ omap_device_fill_resources(od, res);
+ } else {
+ dev_dbg(&pdev->dev,
+ "%s: appending %d DMA resources from hwmod\n",
+ __func__, res_count - pdev->num_resources);
+ memcpy(res, pdev->resource,
+ sizeof(struct resource) * pdev->num_resources);
+ _od_fill_dma_resources(od, &res[pdev->num_resources]);
}
+ ret = platform_device_add_resources(pdev, res, res_count);
+ kfree(res);
+
+ if (ret)
+ goto oda_exit3;
+
+have_everything:
if (!pm_lats) {
pm_lats = omap_default_latency;
pm_lats_cnt = ARRAY_SIZE(omap_default_latency);
OpenPOWER on IntegriCloud