Merge branches 'acpi-scan', 'acpi-bus' and 'acpi-platform'
[platform/kernel/linux-starfive.git] / drivers / acpi / scan.c
index d027742..558664d 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/platform_data/x86/apple.h>
 #include <linux/pgtable.h>
 #include <linux/crc32.h>
+#include <linux/dma-direct.h>
 
 #include "internal.h"
 
@@ -1463,25 +1464,21 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
  * acpi_dma_get_range() - Get device DMA parameters.
  *
  * @dev: device to configure
- * @dma_addr: pointer device DMA address result
- * @offset: pointer to the DMA offset result
- * @size: pointer to DMA range size result
+ * @map: pointer to DMA ranges result
  *
- * Evaluate DMA regions and return respectively DMA region start, offset
- * and size in dma_addr, offset and size on parsing success; it does not
- * update the passed in values on failure.
+ * Evaluate DMA regions and return pointer to DMA regions on
+ * parsing success; it does not update the passed in values on failure.
  *
  * Return 0 on success, < 0 on failure.
  */
-int acpi_dma_get_range(struct device *dev, u64 *dma_addr, u64 *offset,
-                      u64 *size)
+int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map)
 {
        struct acpi_device *adev;
        LIST_HEAD(list);
        struct resource_entry *rentry;
        int ret;
        struct device *dma_dev = dev;
-       u64 len, dma_start = U64_MAX, dma_end = 0, dma_offset = 0;
+       struct bus_dma_region *r;
 
        /*
         * Walk the device tree chasing an ACPI companion with a _DMA
@@ -1506,31 +1503,28 @@ int acpi_dma_get_range(struct device *dev, u64 *dma_addr, u64 *offset,
 
        ret = acpi_dev_get_dma_resources(adev, &list);
        if (ret > 0) {
+               r = kcalloc(ret + 1, sizeof(*r), GFP_KERNEL);
+               if (!r) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+
                list_for_each_entry(rentry, &list, node) {
-                       if (dma_offset && rentry->offset != dma_offset) {
+                       if (rentry->res->start >= rentry->res->end) {
+                               kfree(r);
                                ret = -EINVAL;
-                               dev_warn(dma_dev, "Can't handle multiple windows with different offsets\n");
+                               dev_dbg(dma_dev, "Invalid DMA regions configuration\n");
                                goto out;
                        }
-                       dma_offset = rentry->offset;
 
-                       /* Take lower and upper limits */
-                       if (rentry->res->start < dma_start)
-                               dma_start = rentry->res->start;
-                       if (rentry->res->end > dma_end)
-                               dma_end = rentry->res->end;
-               }
-
-               if (dma_start >= dma_end) {
-                       ret = -EINVAL;
-                       dev_dbg(dma_dev, "Invalid DMA regions configuration\n");
-                       goto out;
+                       r->cpu_start = rentry->res->start;
+                       r->dma_start = rentry->res->start - rentry->offset;
+                       r->size = resource_size(rentry->res);
+                       r->offset = rentry->offset;
+                       r++;
                }
 
-               *dma_addr = dma_start - dma_offset;
-               len = dma_end - dma_start;
-               *size = max(len, len + 1);
-               *offset = dma_offset;
+               *map = r;
        }
  out:
        acpi_dev_free_resource_list(&list);
@@ -1620,20 +1614,19 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
                          const u32 *input_id)
 {
        const struct iommu_ops *iommu;
-       u64 dma_addr = 0, size = 0;
 
        if (attr == DEV_DMA_NOT_SUPPORTED) {
                set_dma_ops(dev, &dma_dummy_ops);
                return 0;
        }
 
-       acpi_arch_dma_setup(dev, &dma_addr, &size);
+       acpi_arch_dma_setup(dev);
 
        iommu = acpi_iommu_configure_id(dev, input_id);
        if (PTR_ERR(iommu) == -EPROBE_DEFER)
                return -EPROBE_DEFER;
 
-       arch_setup_dma_ops(dev, dma_addr, size,
+       arch_setup_dma_ops(dev, 0, U64_MAX,
                                iommu, attr == DEV_DMA_COHERENT);
 
        return 0;