From 5804a6c03966ed6abc3979e10435362a1cd72505 Mon Sep 17 00:00:00 2001 From: Laurentiu Tudor Date: Thu, 13 Feb 2020 11:59:12 +0200 Subject: bus: fsl-mc: add custom .dma_configure implementation The devices on this bus are not discovered by way of device tree but by queries to the firmware. It makes little sense to trick the generic of layer into thinking that these devices are of related so that we can get our dma configuration. Instead of doing that, add our custom dma configuration implementation. Signed-off-by: Laurentiu Tudor --- drivers/bus/fsl-mc/fsl-mc-bus.c | 42 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index 836ee25d5951..ce3d81b84f7f 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c @@ -128,14 +128,56 @@ static int fsl_mc_dma_configure(struct device *dev) struct device *dma_dev = dev; struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); u32 input_id = mc_dev->icid; + struct iommu_fwspec *fwspec; + const struct iommu_ops *iommu_ops; + int ret; + + /* Skip DMA setup for devices that are not DMA masters */ + if (dev->type == &fsl_mc_bus_dpmcp_type || + dev->type == &fsl_mc_bus_dpbp_type || + dev->type == &fsl_mc_bus_dpcon_type || + dev->type == &fsl_mc_bus_dpio_type) + return 0; while (dev_is_fsl_mc(dma_dev)) dma_dev = dma_dev->parent; + +#if 0 if (dev_of_node(dma_dev)) return of_dma_configure_id(dev, dma_dev->of_node, 0, &input_id); return acpi_dma_configure_id(dev, DEV_DMA_COHERENT, &input_id); +#else + fwspec = dev_iommu_fwspec_get(dma_dev); + if (!fwspec) + return -ENODEV; + iommu_ops = iommu_ops_from_fwnode(fwspec->iommu_fwnode); + if (!iommu_ops) + return -ENODEV; + + ret = iommu_fwspec_init(dev, fwspec->iommu_fwnode, iommu_ops); + if (ret) + return ret; + + ret = iommu_fwspec_add_ids(dev, &input_id, 1); + if (ret) { + iommu_fwspec_free(dev); + return ret; + } + + if (!device_iommu_mapped(dev)) { + ret = iommu_probe_device(dev); + if (ret) { + iommu_fwspec_free(dev); + return ret; + } + } + + arch_setup_dma_ops(dev, 0, *dma_dev->dma_mask + 1, iommu_ops, true); + + return 0; +#endif } static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, -- cgit