Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

of/device: Add input id to of_dma_configure()

Devices sitting on proprietary busses have a device ID space that
is owned by the respective bus and related firmware bindings. In order
to let the generic OF layer handle the input translations to
an IOMMU id, for such busses the current of_dma_configure() interface
should be extended in order to allow the bus layer to provide the
device input id parameter - that is retrieved/assigned in bus
specific code and firmware.

Augment of_dma_configure() to add an optional input_id parameter,
leaving current functionality unchanged.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Laurentiu Tudor <laurentiu.tudor@nxp.com>
Link: https://lore.kernel.org/r/20200619082013.13661-8-lorenzo.pieralisi@arm.com
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>

authored by

Lorenzo Pieralisi and committed by
Catalin Marinas
a081bd4a 746a71d0

+72 -47
+3 -1
drivers/bus/fsl-mc/fsl-mc-bus.c
··· 118 118 static int fsl_mc_dma_configure(struct device *dev) 119 119 { 120 120 struct device *dma_dev = dev; 121 + struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); 122 + u32 input_id = mc_dev->icid; 121 123 122 124 while (dev_is_fsl_mc(dma_dev)) 123 125 dma_dev = dma_dev->parent; 124 126 125 - return of_dma_configure(dev, dma_dev->of_node, 0); 127 + return of_dma_configure_id(dev, dma_dev->of_node, 0, &input_id); 126 128 } 127 129 128 130 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
+46 -39
drivers/iommu/of_iommu.c
··· 118 118 return ret; 119 119 } 120 120 121 + static int of_iommu_configure_dev_id(struct device_node *master_np, 122 + struct device *dev, 123 + const u32 *id) 124 + { 125 + struct of_phandle_args iommu_spec = { .args_count = 1 }; 126 + int err; 127 + 128 + err = of_map_id(master_np, *id, "iommu-map", 129 + "iommu-map-mask", &iommu_spec.np, 130 + iommu_spec.args); 131 + if (err) 132 + return err == -ENODEV ? NO_IOMMU : err; 133 + 134 + err = of_iommu_xlate(dev, &iommu_spec); 135 + of_node_put(iommu_spec.np); 136 + return err; 137 + } 138 + 139 + static int of_iommu_configure_dev(struct device_node *master_np, 140 + struct device *dev) 141 + { 142 + struct of_phandle_args iommu_spec; 143 + int err = NO_IOMMU, idx = 0; 144 + 145 + while (!of_parse_phandle_with_args(master_np, "iommus", 146 + "#iommu-cells", 147 + idx, &iommu_spec)) { 148 + err = of_iommu_xlate(dev, &iommu_spec); 149 + of_node_put(iommu_spec.np); 150 + idx++; 151 + if (err) 152 + break; 153 + } 154 + 155 + return err; 156 + } 157 + 121 158 struct of_pci_iommu_alias_info { 122 159 struct device *dev; 123 160 struct device_node *np; ··· 163 126 static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data) 164 127 { 165 128 struct of_pci_iommu_alias_info *info = data; 166 - struct of_phandle_args iommu_spec = { .args_count = 1 }; 167 - int err; 129 + u32 input_id = alias; 168 130 169 - err = of_map_id(info->np, alias, "iommu-map", "iommu-map-mask", 170 - &iommu_spec.np, iommu_spec.args); 171 - if (err) 172 - return err == -ENODEV ? NO_IOMMU : err; 173 - 174 - err = of_iommu_xlate(info->dev, &iommu_spec); 175 - of_node_put(iommu_spec.np); 176 - return err; 131 + return of_iommu_configure_dev_id(info->np, info->dev, &input_id); 177 132 } 178 133 179 - static int of_fsl_mc_iommu_init(struct fsl_mc_device *mc_dev, 180 - struct device_node *master_np) 134 + static int of_iommu_configure_device(struct device_node *master_np, 135 + struct device *dev, const u32 *id) 181 136 { 182 - struct of_phandle_args iommu_spec = { .args_count = 1 }; 183 - int err; 184 - 185 - err = of_map_id(master_np, mc_dev->icid, "iommu-map", 186 - "iommu-map-mask", &iommu_spec.np, 187 - iommu_spec.args); 188 - if (err) 189 - return err == -ENODEV ? NO_IOMMU : err; 190 - 191 - err = of_iommu_xlate(&mc_dev->dev, &iommu_spec); 192 - of_node_put(iommu_spec.np); 193 - return err; 137 + return (id) ? of_iommu_configure_dev_id(master_np, dev, id) : 138 + of_iommu_configure_dev(master_np, dev); 194 139 } 195 140 196 141 const struct iommu_ops *of_iommu_configure(struct device *dev, 197 - struct device_node *master_np) 142 + struct device_node *master_np, 143 + const u32 *id) 198 144 { 199 145 const struct iommu_ops *ops = NULL; 200 146 struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); ··· 208 188 pci_request_acs(); 209 189 err = pci_for_each_dma_alias(to_pci_dev(dev), 210 190 of_pci_iommu_init, &info); 211 - } else if (dev_is_fsl_mc(dev)) { 212 - err = of_fsl_mc_iommu_init(to_fsl_mc_device(dev), master_np); 213 191 } else { 214 - struct of_phandle_args iommu_spec; 215 - int idx = 0; 216 - 217 - while (!of_parse_phandle_with_args(master_np, "iommus", 218 - "#iommu-cells", 219 - idx, &iommu_spec)) { 220 - err = of_iommu_xlate(dev, &iommu_spec); 221 - of_node_put(iommu_spec.np); 222 - idx++; 223 - if (err) 224 - break; 225 - } 192 + err = of_iommu_configure_device(master_np, dev, id); 226 193 227 194 fwspec = dev_iommu_fwspec_get(dev); 228 195 if (!err && fwspec)
+5 -3
drivers/of/device.c
··· 78 78 * @np: Pointer to OF node having DMA configuration 79 79 * @force_dma: Whether device is to be set up by of_dma_configure() even if 80 80 * DMA capability is not explicitly described by firmware. 81 + * @id: Optional const pointer value input id 81 82 * 82 83 * Try to get devices's DMA configuration from DT and update it 83 84 * accordingly. ··· 87 86 * can use a platform bus notifier and handle BUS_NOTIFY_ADD_DEVICE events 88 87 * to fix up DMA configuration. 89 88 */ 90 - int of_dma_configure(struct device *dev, struct device_node *np, bool force_dma) 89 + int of_dma_configure_id(struct device *dev, struct device_node *np, 90 + bool force_dma, const u32 *id) 91 91 { 92 92 u64 dma_addr, paddr, size = 0; 93 93 int ret; ··· 162 160 dev_dbg(dev, "device is%sdma coherent\n", 163 161 coherent ? " " : " not "); 164 162 165 - iommu = of_iommu_configure(dev, np); 163 + iommu = of_iommu_configure(dev, np, id); 166 164 if (PTR_ERR(iommu) == -EPROBE_DEFER) 167 165 return -EPROBE_DEFER; 168 166 ··· 173 171 174 172 return 0; 175 173 } 176 - EXPORT_SYMBOL_GPL(of_dma_configure); 174 + EXPORT_SYMBOL_GPL(of_dma_configure_id); 177 175 178 176 int of_device_register(struct platform_device *pdev) 179 177 {
+14 -2
include/linux/of_device.h
··· 55 55 return of_node_get(cpu_dev->of_node); 56 56 } 57 57 58 - int of_dma_configure(struct device *dev, 58 + int of_dma_configure_id(struct device *dev, 59 59 struct device_node *np, 60 - bool force_dma); 60 + bool force_dma, const u32 *id); 61 + static inline int of_dma_configure(struct device *dev, 62 + struct device_node *np, 63 + bool force_dma) 64 + { 65 + return of_dma_configure_id(dev, np, force_dma, NULL); 66 + } 61 67 #else /* CONFIG_OF */ 62 68 63 69 static inline int of_driver_match_device(struct device *dev, ··· 112 106 return NULL; 113 107 } 114 108 109 + static inline int of_dma_configure_id(struct device *dev, 110 + struct device_node *np, 111 + bool force_dma) 112 + { 113 + return 0; 114 + } 115 115 static inline int of_dma_configure(struct device *dev, 116 116 struct device_node *np, 117 117 bool force_dma)
+4 -2
include/linux/of_iommu.h
··· 13 13 size_t *size); 14 14 15 15 extern const struct iommu_ops *of_iommu_configure(struct device *dev, 16 - struct device_node *master_np); 16 + struct device_node *master_np, 17 + const u32 *id); 17 18 18 19 #else 19 20 ··· 26 25 } 27 26 28 27 static inline const struct iommu_ops *of_iommu_configure(struct device *dev, 29 - struct device_node *master_np) 28 + struct device_node *master_np, 29 + const u32 *id) 30 30 { 31 31 return NULL; 32 32 }