]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/arm/mach-omap2/omap_device.c
Merge branch 'stable/for-jens-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git...
[karo-tx-linux.git] / arch / arm / mach-omap2 / omap_device.c
index 0ef934fec364a674d98e09cb625425e8461e4bcb..e065daa537c07bd8c8946d394d9ab60c0b120c3b 100644 (file)
@@ -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);