]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
of: dma: Move range size workaround to of_dma_get_range()
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Thu, 14 May 2015 23:00:04 +0000 (02:00 +0300)
committerSrinivas Kandagatla <srinivas.kandagatla@linaro.org>
Mon, 11 Jan 2016 09:54:33 +0000 (09:54 +0000)
Invalid dma-ranges values should be worked around when retrieving the
DMA range in of_dma_get_range(), not by all callers of the function.
This isn't much of a problem now that we have a single caller, but that
situation will change when moving DMA configuration to device probe
time.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
drivers/of/address.c
drivers/of/device.c

index 9582c5703b3c905486da173d08a2f986883bda26..561a0d1d2573ede73aab5763ca50c40e985653d5 100644 (file)
@@ -931,8 +931,8 @@ EXPORT_SYMBOL(of_io_request_and_map);
  *     CPU addr (phys_addr_t)  : pna cells
  *     size                    : nsize cells
  *
- * It returns -ENODEV if "dma-ranges" property was not found
- * for this device in DT.
+ * Return 0 on success, -ENODEV if the "dma-ranges" property was not found for
+ * this device in DT, or -EINVAL if the CPU address or size is invalid.
  */
 int of_dma_get_range(struct device_node *np, u64 *dma_addr, u64 *paddr, u64 *size)
 {
@@ -993,6 +993,22 @@ int of_dma_get_range(struct device_node *np, u64 *dma_addr, u64 *paddr, u64 *siz
        *dma_addr = dmaaddr;
 
        *size = of_read_number(ranges + naddr + pna, nsize);
+       /*
+        * DT nodes sometimes incorrectly set the size as a mask. Work around
+        * those incorrect DT by computing the size as mask + 1.
+        */
+       if (*size & 1) {
+               pr_warn("%s: size 0x%llx for dma-range in node(%s) set as mask\n",
+                       __func__, *size, np->full_name);
+               *size = *size + 1;
+       }
+
+       if (!*size) {
+               pr_err("%s: invalid size zero for dma-range in node(%s)\n",
+                      __func__, np->full_name);
+               ret = -EINVAL;
+               goto out;
+       }
 
        pr_debug("dma_addr(%llx) cpu_addr(%llx) size(%llx)\n",
                 *dma_addr, *paddr, *size);
index e5f47cec75f34e046b15efbc5bcdc50073eff5c0..fc7597c63ec12cf4cbc8045e379cef3b1796d809 100644 (file)
@@ -110,21 +110,6 @@ void of_dma_configure(struct device *dev, struct device_node *np)
                size = dev->coherent_dma_mask + 1;
        } else {
                offset = PFN_DOWN(paddr - dma_addr);
-
-               /*
-                * Add a work around to treat the size as mask + 1 in case
-                * it is defined in DT as a mask.
-                */
-               if (size & 1) {
-                       dev_warn(dev, "Invalid size 0x%llx for dma-range\n",
-                                size);
-                       size = size + 1;
-               }
-
-               if (!size) {
-                       dev_err(dev, "Adjusted size 0x%llx invalid\n", size);
-                       return;
-               }
                dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
        }