Merge tag 'iommu-updates-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / drivers / acpi / arm64 / iort.c
index e34937e..3b23fb7 100644 (file)
@@ -806,23 +806,6 @@ static struct acpi_iort_node *iort_get_msi_resv_iommu(struct device *dev)
        return NULL;
 }
 
-static inline const struct iommu_ops *iort_fwspec_iommu_ops(struct device *dev)
-{
-       struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
-
-       return (fwspec && fwspec->ops) ? fwspec->ops : NULL;
-}
-
-static inline int iort_add_device_replay(struct device *dev)
-{
-       int err = 0;
-
-       if (dev->bus && !device_iommu_mapped(dev))
-               err = iommu_probe_device(dev);
-
-       return err;
-}
-
 /**
  * iort_iommu_msi_get_resv_regions - Reserved region driver helper
  * @dev: Device from iommu_get_resv_regions()
@@ -900,18 +883,6 @@ static inline bool iort_iommu_driver_enabled(u8 type)
        }
 }
 
-static int arm_smmu_iort_xlate(struct device *dev, u32 streamid,
-                              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, &streamid, 1);
-
-       return ret;
-}
-
 static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
 {
        struct acpi_iort_root_complex *pci_rc;
@@ -946,7 +917,7 @@ static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
                return iort_iommu_driver_enabled(node->type) ?
                       -EPROBE_DEFER : -ENODEV;
 
-       return arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops);
+       return acpi_iommu_fwspec_init(dev, streamid, iort_fwnode, ops);
 }
 
 struct iort_pci_alias_info {
@@ -968,13 +939,15 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
 static void iort_named_component_init(struct device *dev,
                                      struct acpi_iort_node *node)
 {
-       struct property_entry props[2] = {};
+       struct property_entry props[3] = {};
        struct acpi_iort_named_component *nc;
 
        nc = (struct acpi_iort_named_component *)node->node_data;
        props[0] = PROPERTY_ENTRY_U32("pasid-num-bits",
                                      FIELD_GET(ACPI_IORT_NC_PASID_BITS,
                                                nc->node_flags));
+       if (nc->node_flags & ACPI_IORT_NC_STALL_SUPPORTED)
+               props[1] = PROPERTY_ENTRY_BOOL("dma-can-stall");
 
        if (device_create_managed_software_node(dev, props, NULL))
                dev_warn(dev, "Could not add device properties\n");
@@ -1020,24 +993,13 @@ static int iort_nc_iommu_map_id(struct device *dev,
  * @dev: device to configure
  * @id_in: optional input id const value pointer
  *
- * Returns: iommu_ops pointer on configuration success
- *          NULL on configuration failure
+ * Returns: 0 on success, <0 on failure
  */
-const struct iommu_ops *iort_iommu_configure_id(struct device *dev,
-                                               const u32 *id_in)
+int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
 {
        struct acpi_iort_node *node;
-       const struct iommu_ops *ops;
        int err = -ENODEV;
 
-       /*
-        * If we already translated the fwspec there
-        * is nothing left to do, return the iommu_ops.
-        */
-       ops = iort_fwspec_iommu_ops(dev);
-       if (ops)
-               return ops;
-
        if (dev_is_pci(dev)) {
                struct iommu_fwspec *fwspec;
                struct pci_bus *bus = to_pci_dev(dev)->bus;
@@ -1046,7 +1008,7 @@ const struct iommu_ops *iort_iommu_configure_id(struct device *dev,
                node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
                                      iort_match_node_callback, &bus->dev);
                if (!node)
-                       return NULL;
+                       return -ENODEV;
 
                info.node = node;
                err = pci_for_each_dma_alias(to_pci_dev(dev),
@@ -1059,7 +1021,7 @@ const struct iommu_ops *iort_iommu_configure_id(struct device *dev,
                node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
                                      iort_match_node_callback, dev);
                if (!node)
-                       return NULL;
+                       return -ENODEV;
 
                err = id_in ? iort_nc_iommu_map_id(dev, node, id_in) :
                              iort_nc_iommu_map(dev, node);
@@ -1068,32 +1030,14 @@ const struct iommu_ops *iort_iommu_configure_id(struct device *dev,
                        iort_named_component_init(dev, node);
        }
 
-       /*
-        * If we have reason to believe the IOMMU driver missed the initial
-        * add_device callback for dev, replay it to get things in order.
-        */
-       if (!err) {
-               ops = iort_fwspec_iommu_ops(dev);
-               err = iort_add_device_replay(dev);
-       }
-
-       /* Ignore all other errors apart from EPROBE_DEFER */
-       if (err == -EPROBE_DEFER) {
-               ops = ERR_PTR(err);
-       } else if (err) {
-               dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-               ops = NULL;
-       }
-
-       return ops;
+       return err;
 }
 
 #else
 int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head)
 { return 0; }
-const struct iommu_ops *iort_iommu_configure_id(struct device *dev,
-                                               const u32 *input_id)
-{ return NULL; }
+int iort_iommu_configure_id(struct device *dev, const u32 *input_id)
+{ return -ENODEV; }
 #endif
 
 static int nc_dma_get_range(struct device *dev, u64 *size)
@@ -1144,56 +1088,18 @@ static int rc_dma_get_range(struct device *dev, u64 *size)
 }
 
 /**
- * iort_dma_setup() - Set-up device DMA parameters.
+ * iort_dma_get_ranges() - Look up DMA addressing limit for the device
+ * @dev: device to lookup
+ * @size: DMA range size result pointer
  *
- * @dev: device to configure
- * @dma_addr: device DMA address result pointer
- * @dma_size: DMA range size result pointer
+ * Return: 0 on success, an error otherwise.
  */
-void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size)
+int iort_dma_get_ranges(struct device *dev, u64 *size)
 {
-       u64 end, mask, dmaaddr = 0, size = 0, offset = 0;
-       int ret;
-
-       /*
-        * If @dev is expected to be DMA-capable then the bus code that created
-        * it should have initialised its dma_mask pointer by this point. For
-        * now, we'll continue the legacy behaviour of coercing it to the
-        * coherent mask if not, but we'll no longer do so quietly.
-        */
-       if (!dev->dma_mask) {
-               dev_warn(dev, "DMA mask not set\n");
-               dev->dma_mask = &dev->coherent_dma_mask;
-       }
-
-       if (dev->coherent_dma_mask)
-               size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
+       if (dev_is_pci(dev))
+               return rc_dma_get_range(dev, size);
        else
-               size = 1ULL << 32;
-
-       ret = acpi_dma_get_range(dev, &dmaaddr, &offset, &size);
-       if (ret == -ENODEV)
-               ret = dev_is_pci(dev) ? rc_dma_get_range(dev, &size)
-                                     : nc_dma_get_range(dev, &size);
-
-       if (!ret) {
-               /*
-                * Limit coherent and dma mask based on size retrieved from
-                * firmware.
-                */
-               end = dmaaddr + size - 1;
-               mask = DMA_BIT_MASK(ilog2(end) + 1);
-               dev->bus_dma_limit = end;
-               dev->coherent_dma_mask = min(dev->coherent_dma_mask, mask);
-               *dev->dma_mask = min(*dev->dma_mask, mask);
-       }
-
-       *dma_addr = dmaaddr;
-       *dma_size = size;
-
-       ret = dma_direct_set_offset(dev, dmaaddr + offset, dmaaddr, size);
-
-       dev_dbg(dev, "dma_offset(%#08llx)%s\n", offset, ret ? " failed!" : "");
+               return nc_dma_get_range(dev, size);
 }
 
 static void __init acpi_iort_register_irq(int hwirq, const char *name,