Merge branches 'acpi-scan', 'acpi-bus' and 'acpi-platform'
[platform/kernel/linux-starfive.git] / drivers / acpi / scan.c
index 42cec81..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"
 
@@ -29,8 +30,6 @@ extern struct acpi_device *acpi_root;
 #define ACPI_BUS_HID                   "LNXSYBUS"
 #define ACPI_BUS_DEVICE_NAME           "System Bus"
 
-#define ACPI_IS_ROOT_DEVICE(device)    (!(device)->parent)
-
 #define INVALID_ACPI_HANDLE    ((acpi_handle)empty_zero_page)
 
 static const char *dummy_hid = "device";
@@ -429,7 +428,7 @@ void acpi_device_hotplug(struct acpi_device *adev, u32 src)
        acpi_evaluate_ost(adev->handle, src, ost_code, NULL);
 
  out:
-       acpi_bus_put_acpi_device(adev);
+       acpi_put_acpi_dev(adev);
        mutex_unlock(&acpi_scan_lock);
        unlock_device_hotplug();
 }
@@ -599,11 +598,22 @@ static void get_acpi_device(void *dev)
        acpi_dev_get(dev);
 }
 
-struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle)
+/**
+ * acpi_get_acpi_dev - Retrieve ACPI device object and reference count it.
+ * @handle: ACPI handle associated with the requested ACPI device object.
+ *
+ * Return a pointer to the ACPI device object associated with @handle and bump
+ * up that object's reference counter (under the ACPI Namespace lock), if
+ * present, or return NULL otherwise.
+ *
+ * The ACPI device object reference acquired by this function needs to be
+ * dropped via acpi_dev_put().
+ */
+struct acpi_device *acpi_get_acpi_dev(acpi_handle handle)
 {
        return handle_to_device(handle, get_acpi_device);
 }
-EXPORT_SYMBOL_GPL(acpi_bus_get_acpi_device);
+EXPORT_SYMBOL_GPL(acpi_get_acpi_dev);
 
 static struct acpi_device_bus_id *acpi_device_bus_id_match(const char *dev_id)
 {
@@ -632,7 +642,7 @@ static int acpi_device_set_name(struct acpi_device *device,
        return 0;
 }
 
-static int acpi_tie_acpi_dev(struct acpi_device *adev)
+int acpi_tie_acpi_dev(struct acpi_device *adev)
 {
        acpi_handle handle = adev->handle;
        acpi_status status;
@@ -662,8 +672,7 @@ static void acpi_store_pld_crc(struct acpi_device *adev)
        ACPI_FREE(pld);
 }
 
-static int __acpi_device_add(struct acpi_device *device,
-                            void (*release)(struct device *))
+int acpi_device_add(struct acpi_device *device)
 {
        struct acpi_device_bus_id *acpi_device_bus_id;
        int result;
@@ -719,11 +728,6 @@ static int __acpi_device_add(struct acpi_device *device,
 
        mutex_unlock(&acpi_device_lock);
 
-       if (device->parent)
-               device->dev.parent = &device->parent->dev;
-
-       device->dev.bus = &acpi_bus_type;
-       device->dev.release = release;
        result = device_add(&device->dev);
        if (result) {
                dev_err(&device->dev, "Error registering device\n");
@@ -750,17 +754,6 @@ err_unlock:
        return result;
 }
 
-int acpi_device_add(struct acpi_device *adev, void (*release)(struct device *))
-{
-       int ret;
-
-       ret = acpi_tie_acpi_dev(adev);
-       if (ret)
-               return ret;
-
-       return __acpi_device_add(adev, release);
-}
-
 /* --------------------------------------------------------------------------
                                  Device Enumeration
    -------------------------------------------------------------------------- */
@@ -805,10 +798,9 @@ static const char * const acpi_honor_dep_ids[] = {
        NULL
 };
 
-static struct acpi_device *acpi_bus_get_parent(acpi_handle handle)
+static struct acpi_device *acpi_find_parent_acpi_dev(acpi_handle handle)
 {
-       struct acpi_device *device;
-       acpi_status status;
+       struct acpi_device *adev;
 
        /*
         * Fixed hardware devices do not appear in the namespace and do not
@@ -819,13 +811,18 @@ static struct acpi_device *acpi_bus_get_parent(acpi_handle handle)
                return acpi_root;
 
        do {
+               acpi_status status;
+
                status = acpi_get_parent(handle, &handle);
-               if (ACPI_FAILURE(status))
-                       return status == AE_NULL_ENTRY ? NULL : acpi_root;
+               if (ACPI_FAILURE(status)) {
+                       if (status != AE_NULL_ENTRY)
+                               return acpi_root;
 
-               device = acpi_fetch_acpi_dev(handle);
-       } while (!device);
-       return device;
+                       return NULL;
+               }
+               adev = acpi_fetch_acpi_dev(handle);
+       } while (!adev);
+       return adev;
 }
 
 acpi_status
@@ -1112,7 +1109,7 @@ static void acpi_device_get_busid(struct acpi_device *device)
         * The device's Bus ID is simply the object name.
         * TBD: Shouldn't this value be unique (within the ACPI namespace)?
         */
-       if (ACPI_IS_ROOT_DEVICE(device)) {
+       if (!acpi_dev_parent(device)) {
                strcpy(device->pnp.bus_id, "ACPI");
                return;
        }
@@ -1467,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
@@ -1510,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);
@@ -1624,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;
@@ -1648,7 +1637,7 @@ static void acpi_init_coherency(struct acpi_device *adev)
 {
        unsigned long long cca = 0;
        acpi_status status;
-       struct acpi_device *parent = adev->parent;
+       struct acpi_device *parent = acpi_dev_parent(adev);
 
        if (parent && parent->flags.cca_seen) {
                /*
@@ -1692,7 +1681,7 @@ static int acpi_check_serial_bus_slave(struct acpi_resource *ares, void *data)
 
 static bool acpi_is_indirect_io_slave(struct acpi_device *device)
 {
-       struct acpi_device *parent = device->parent;
+       struct acpi_device *parent = acpi_dev_parent(device);
        static const struct acpi_device_id indirect_io_hosts[] = {
                {"HISI0191", 0},
                {}
@@ -1762,12 +1751,16 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device)
 }
 
 void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
-                            int type)
+                            int type, void (*release)(struct device *))
 {
+       struct acpi_device *parent = acpi_find_parent_acpi_dev(handle);
+
        INIT_LIST_HEAD(&device->pnp.ids);
        device->device_type = type;
        device->handle = handle;
-       device->parent = acpi_bus_get_parent(handle);
+       device->dev.parent = parent ? &parent->dev : NULL;
+       device->dev.release = release;
+       device->dev.bus = &acpi_bus_type;
        fwnode_init(&device->fwnode, &acpi_device_fwnode_ops);
        acpi_set_device_status(device, ACPI_STA_DEFAULT);
        acpi_device_get_busid(device);
@@ -1821,7 +1814,7 @@ static int acpi_add_single_object(struct acpi_device **child,
        if (!device)
                return -ENOMEM;
 
-       acpi_init_device_object(device, handle, type);
+       acpi_init_device_object(device, handle, type, acpi_device_release);
        /*
         * Getting the status is delayed till here so that we can call
         * acpi_bus_get_status() and use its quirk handling.  Note that
@@ -1851,7 +1844,7 @@ static int acpi_add_single_object(struct acpi_device **child,
                mutex_unlock(&acpi_dep_list_lock);
 
        if (!result)
-               result = __acpi_device_add(device, acpi_device_release);
+               result = acpi_device_add(device);
 
        if (result) {
                acpi_device_release(&device->dev);
@@ -1862,8 +1855,8 @@ static int acpi_add_single_object(struct acpi_device **child,
        acpi_device_add_finalize(device);
 
        acpi_handle_debug(handle, "Added as %s, parent %s\n",
-                         dev_name(&device->dev), device->parent ?
-                               dev_name(&device->parent->dev) : "(null)");
+                         dev_name(&device->dev), device->dev.parent ?
+                               dev_name(device->dev.parent) : "(null)");
 
        *child = device;
        return 0;
@@ -2235,11 +2228,24 @@ ok:
        return 0;
 }
 
-static int acpi_dev_get_first_consumer_dev_cb(struct acpi_dep_data *dep, void *data)
+static int acpi_dev_get_next_consumer_dev_cb(struct acpi_dep_data *dep, void *data)
 {
-       struct acpi_device *adev;
+       struct acpi_device **adev_p = data;
+       struct acpi_device *adev = *adev_p;
 
-       adev = acpi_bus_get_acpi_device(dep->consumer);
+       /*
+        * If we're passed a 'previous' consumer device then we need to skip
+        * any consumers until we meet the previous one, and then NULL @data
+        * so the next one can be returned.
+        */
+       if (adev) {
+               if (dep->consumer == adev->handle)
+                       *adev_p = NULL;
+
+               return 0;
+       }
+
+       adev = acpi_get_acpi_dev(dep->consumer);
        if (adev) {
                *(struct acpi_device **)data = adev;
                return 1;
@@ -2292,7 +2298,7 @@ static bool acpi_scan_clear_dep_queue(struct acpi_device *adev)
 
 static int acpi_scan_clear_dep(struct acpi_dep_data *dep, void *data)
 {
-       struct acpi_device *adev = acpi_bus_get_acpi_device(dep->consumer);
+       struct acpi_device *adev = acpi_get_acpi_dev(dep->consumer);
 
        if (adev) {
                adev->dep_unmet--;
@@ -2368,25 +2374,32 @@ bool acpi_dev_ready_for_enumeration(const struct acpi_device *device)
 EXPORT_SYMBOL_GPL(acpi_dev_ready_for_enumeration);
 
 /**
- * acpi_dev_get_first_consumer_dev - Return ACPI device dependent on @supplier
+ * acpi_dev_get_next_consumer_dev - Return the next adev dependent on @supplier
  * @supplier: Pointer to the dependee device
+ * @start: Pointer to the current dependent device
  *
- * Returns the first &struct acpi_device which declares itself dependent on
+ * Returns the next &struct acpi_device which declares itself dependent on
  * @supplier via the _DEP buffer, parsed from the acpi_dep_list.
  *
- * The caller is responsible for putting the reference to adev when it is no
- * longer needed.
+ * If the returned adev is not passed as @start to this function, the caller is
+ * responsible for putting the reference to adev when it is no longer needed.
  */
-struct acpi_device *acpi_dev_get_first_consumer_dev(struct acpi_device *supplier)
+struct acpi_device *acpi_dev_get_next_consumer_dev(struct acpi_device *supplier,
+                                                  struct acpi_device *start)
 {
-       struct acpi_device *adev = NULL;
+       struct acpi_device *adev = start;
 
        acpi_walk_dep_device_list(supplier->handle,
-                                 acpi_dev_get_first_consumer_dev_cb, &adev);
+                                 acpi_dev_get_next_consumer_dev_cb, &adev);
+
+       acpi_dev_put(start);
+
+       if (adev == start)
+               return NULL;
 
        return adev;
 }
-EXPORT_SYMBOL_GPL(acpi_dev_get_first_consumer_dev);
+EXPORT_SYMBOL_GPL(acpi_dev_get_next_consumer_dev);
 
 /**
  * acpi_bus_scan - Add ACPI device node objects in a given namespace scope.