On Wed, Jan 13, 2021 at 7:48 AM Florian Fainelli <f.fainelli@xxxxxxxxx> wrote: > > On 1/5/21 7:41 PM, Claire Chang wrote: > > If a device is not behind an IOMMU, we look up the device node and set > > up the restricted DMA when the restricted-dma-pool is presented. > > > > Signed-off-by: Claire Chang <tientzu@xxxxxxxxxxxx> > > --- > > [snip] > > > +int of_dma_set_restricted_buffer(struct device *dev) > > +{ > > + struct device_node *node; > > + int count, i; > > + > > + if (!dev->of_node) > > + return 0; > > + > > + count = of_property_count_elems_of_size(dev->of_node, "memory-region", > > + sizeof(phandle)); > > You could have an early check for count < 0, along with an error > message, if that is deemed useful. > > > + for (i = 0; i < count; i++) { > > + node = of_parse_phandle(dev->of_node, "memory-region", i); > > + if (of_device_is_compatible(node, "restricted-dma-pool")) > > And you may want to add here an of_device_is_available(node). A platform > that provides the Device Tree firmware and try to support multiple > different SoCs may try to determine if an IOMMU is present, and if it > is, it could be marking the restriced-dma-pool region with a 'status = > "disabled"' property, or any variant of that scheme. This function is called only when there is no IOMMU present (check in drivers/of/device.c). I can still add of_device_is_available(node) here if you think it's helpful. > > > + return of_reserved_mem_device_init_by_idx( > > + dev, dev->of_node, i); > > This does not seem to be supporting more than one memory region, did not > you want something like instead: > > ret = of_reserved_mem_device_init_by_idx(...); > if (ret) > return ret; > Yes. This implement only supports one restriced-dma-pool memory region with the assumption that there is only one memory region with the compatible string, restricted-dma-pool, in the dts. IIUC, it's similar to shared-dma-pool. > > + } > > + > > + return 0; > > +} > > diff --git a/drivers/of/device.c b/drivers/of/device.c > > index aedfaaafd3e7..e2c7409956ab 100644 > > --- a/drivers/of/device.c > > +++ b/drivers/of/device.c > > @@ -182,6 +182,10 @@ int of_dma_configure_id(struct device *dev, struct device_node *np, > > arch_setup_dma_ops(dev, dma_start, size, iommu, coherent); > > > > dev->dma_range_map = map; > > + > > + if (!iommu) > > + return of_dma_set_restricted_buffer(dev); > > + > > return 0; > > } > > EXPORT_SYMBOL_GPL(of_dma_configure_id); > > diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h > > index d9e6a324de0a..28a2dfa197ba 100644 > > --- a/drivers/of/of_private.h > > +++ b/drivers/of/of_private.h > > @@ -161,12 +161,17 @@ struct bus_dma_region; > > #if defined(CONFIG_OF_ADDRESS) && defined(CONFIG_HAS_DMA) > > int of_dma_get_range(struct device_node *np, > > const struct bus_dma_region **map); > > +int of_dma_set_restricted_buffer(struct device *dev); > > #else > > static inline int of_dma_get_range(struct device_node *np, > > const struct bus_dma_region **map) > > { > > return -ENODEV; > > } > > +static inline int of_dma_get_restricted_buffer(struct device *dev) > > +{ > > + return -ENODEV; > > +} > > #endif > > > > #endif /* _LINUX_OF_PRIVATE_H */ > > > > > -- > Florian