Merge tag 'for-linus-5.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw...
[linux-2.6-microblaze.git] / drivers / acpi / scan.c
index f8eaddb..b24513e 100644 (file)
@@ -3,12 +3,16 @@
  * scan.c - support for transforming the ACPI namespace into individual objects
  */
 
+#define pr_fmt(fmt) "ACPI: " fmt
+
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/acpi.h>
 #include <linux/acpi_iort.h>
+#include <linux/acpi_viot.h>
+#include <linux/iommu.h>
 #include <linux/signal.h>
 #include <linux/kthread.h>
 #include <linux/dmi.h>
@@ -723,7 +727,7 @@ static int __acpi_device_add(struct acpi_device *device,
 
        result = acpi_device_setup_files(device);
        if (result)
-               printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n",
+               pr_err("Error creating sysfs interface for device %s\n",
                       dev_name(&device->dev));
 
        return 0;
@@ -1325,8 +1329,7 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp,
 
                acpi_get_object_info(handle, &info);
                if (!info) {
-                       pr_err(PREFIX "%s: Error reading device info\n",
-                                       __func__);
+                       pr_err("%s: Error reading device info\n", __func__);
                        return;
                }
 
@@ -1410,7 +1413,7 @@ void acpi_free_pnp_ids(struct acpi_device_pnp *pnp)
  *
  * Return false if DMA is not supported. Otherwise, return true
  */
-bool acpi_dma_supported(struct acpi_device *adev)
+bool acpi_dma_supported(const struct acpi_device *adev)
 {
        if (!adev)
                return false;
@@ -1525,6 +1528,78 @@ int acpi_dma_get_range(struct device *dev, u64 *dma_addr, u64 *offset,
        return ret >= 0 ? 0 : ret;
 }
 
+#ifdef CONFIG_IOMMU_API
+int acpi_iommu_fwspec_init(struct device *dev, u32 id,
+                          struct fwnode_handle *fwnode,
+                          const struct iommu_ops *ops)
+{
+       int ret = iommu_fwspec_init(dev, fwnode, ops);
+
+       if (!ret)
+               ret = iommu_fwspec_add_ids(dev, &id, 1);
+
+       return ret;
+}
+
+static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev)
+{
+       struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+
+       return fwspec ? fwspec->ops : NULL;
+}
+
+static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
+                                                      const u32 *id_in)
+{
+       int err;
+       const struct iommu_ops *ops;
+
+       /*
+        * If we already translated the fwspec there is nothing left to do,
+        * return the iommu_ops.
+        */
+       ops = acpi_iommu_fwspec_ops(dev);
+       if (ops)
+               return ops;
+
+       err = iort_iommu_configure_id(dev, id_in);
+       if (err && err != -EPROBE_DEFER)
+               err = viot_iommu_configure(dev);
+
+       /*
+        * If we have reason to believe the IOMMU driver missed the initial
+        * iommu_probe_device() call for dev, replay it to get things in order.
+        */
+       if (!err && dev->bus && !device_iommu_mapped(dev))
+               err = iommu_probe_device(dev);
+
+       /* Ignore all other errors apart from EPROBE_DEFER */
+       if (err == -EPROBE_DEFER) {
+               return ERR_PTR(err);
+       } else if (err) {
+               dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
+               return NULL;
+       }
+       return acpi_iommu_fwspec_ops(dev);
+}
+
+#else /* !CONFIG_IOMMU_API */
+
+int acpi_iommu_fwspec_init(struct device *dev, u32 id,
+                          struct fwnode_handle *fwnode,
+                          const struct iommu_ops *ops)
+{
+       return -ENODEV;
+}
+
+static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
+                                                      const u32 *id_in)
+{
+       return NULL;
+}
+
+#endif /* !CONFIG_IOMMU_API */
+
 /**
  * acpi_dma_configure_id - Set-up DMA configuration for the device.
  * @dev: The pointer to the device
@@ -1542,9 +1617,9 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
                return 0;
        }
 
-       iort_dma_setup(dev, &dma_addr, &size);
+       acpi_arch_dma_setup(dev, &dma_addr, &size);
 
-       iommu = iort_iommu_configure_id(dev, input_id);
+       iommu = acpi_iommu_configure_id(dev, input_id);
        if (PTR_ERR(iommu) == -EPROBE_DEFER)
                return -EPROBE_DEFER;
 
@@ -2403,7 +2478,7 @@ static void __init acpi_get_spcr_uart_addr(void)
        status = acpi_get_table(ACPI_SIG_SPCR, 0,
                                (struct acpi_table_header **)&spcr_ptr);
        if (ACPI_FAILURE(status)) {
-               pr_warn(PREFIX "STAO table present, but SPCR is missing\n");
+               pr_warn("STAO table present, but SPCR is missing\n");
                return;
        }
 
@@ -2444,7 +2519,7 @@ int __init acpi_scan_init(void)
                                (struct acpi_table_header **)&stao_ptr);
        if (ACPI_SUCCESS(status)) {
                if (stao_ptr->header.length > sizeof(struct acpi_table_stao))
-                       pr_info(PREFIX "STAO Name List not yet supported.\n");
+                       pr_info("STAO Name List not yet supported.\n");
 
                if (stao_ptr->ignore_uart)
                        acpi_get_spcr_uart_addr();