Skip to content

Commit a081bd4

Browse files
Lorenzo Pieralisictmarinas
authored andcommitted
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 <[email protected]> Reviewed-by: Rob Herring <[email protected]> Cc: Rob Herring <[email protected]> Cc: Robin Murphy <[email protected]> Cc: Joerg Roedel <[email protected]> Cc: Laurentiu Tudor <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Catalin Marinas <[email protected]>
1 parent 746a71d commit a081bd4

File tree

5 files changed

+70
-45
lines changed

5 files changed

+70
-45
lines changed

drivers/bus/fsl-mc/fsl-mc-bus.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,13 @@ static int fsl_mc_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
118118
static int fsl_mc_dma_configure(struct device *dev)
119119
{
120120
struct device *dma_dev = dev;
121+
struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
122+
u32 input_id = mc_dev->icid;
121123

122124
while (dev_is_fsl_mc(dma_dev))
123125
dma_dev = dma_dev->parent;
124126

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);
126128
}
127129

128130
static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,

drivers/iommu/of_iommu.c

Lines changed: 44 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -118,46 +118,66 @@ static int of_iommu_xlate(struct device *dev,
118118
return ret;
119119
}
120120

121-
struct of_pci_iommu_alias_info {
122-
struct device *dev;
123-
struct device_node *np;
124-
};
125-
126-
static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
121+
static int of_iommu_configure_dev_id(struct device_node *master_np,
122+
struct device *dev,
123+
const u32 *id)
127124
{
128-
struct of_pci_iommu_alias_info *info = data;
129125
struct of_phandle_args iommu_spec = { .args_count = 1 };
130126
int err;
131127

132-
err = of_map_id(info->np, alias, "iommu-map", "iommu-map-mask",
133-
&iommu_spec.np, iommu_spec.args);
128+
err = of_map_id(master_np, *id, "iommu-map",
129+
"iommu-map-mask", &iommu_spec.np,
130+
iommu_spec.args);
134131
if (err)
135132
return err == -ENODEV ? NO_IOMMU : err;
136133

137-
err = of_iommu_xlate(info->dev, &iommu_spec);
134+
err = of_iommu_xlate(dev, &iommu_spec);
138135
of_node_put(iommu_spec.np);
139136
return err;
140137
}
141138

142-
static int of_fsl_mc_iommu_init(struct fsl_mc_device *mc_dev,
143-
struct device_node *master_np)
139+
static int of_iommu_configure_dev(struct device_node *master_np,
140+
struct device *dev)
144141
{
145-
struct of_phandle_args iommu_spec = { .args_count = 1 };
146-
int err;
147-
148-
err = of_map_id(master_np, mc_dev->icid, "iommu-map",
149-
"iommu-map-mask", &iommu_spec.np,
150-
iommu_spec.args);
151-
if (err)
152-
return err == -ENODEV ? NO_IOMMU : err;
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+
}
153154

154-
err = of_iommu_xlate(&mc_dev->dev, &iommu_spec);
155-
of_node_put(iommu_spec.np);
156155
return err;
157156
}
158157

158+
struct of_pci_iommu_alias_info {
159+
struct device *dev;
160+
struct device_node *np;
161+
};
162+
163+
static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
164+
{
165+
struct of_pci_iommu_alias_info *info = data;
166+
u32 input_id = alias;
167+
168+
return of_iommu_configure_dev_id(info->np, info->dev, &input_id);
169+
}
170+
171+
static int of_iommu_configure_device(struct device_node *master_np,
172+
struct device *dev, const u32 *id)
173+
{
174+
return (id) ? of_iommu_configure_dev_id(master_np, dev, id) :
175+
of_iommu_configure_dev(master_np, dev);
176+
}
177+
159178
const struct iommu_ops *of_iommu_configure(struct device *dev,
160-
struct device_node *master_np)
179+
struct device_node *master_np,
180+
const u32 *id)
161181
{
162182
const struct iommu_ops *ops = NULL;
163183
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
@@ -188,21 +208,8 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
188208
pci_request_acs();
189209
err = pci_for_each_dma_alias(to_pci_dev(dev),
190210
of_pci_iommu_init, &info);
191-
} else if (dev_is_fsl_mc(dev)) {
192-
err = of_fsl_mc_iommu_init(to_fsl_mc_device(dev), master_np);
193211
} else {
194-
struct of_phandle_args iommu_spec;
195-
int idx = 0;
196-
197-
while (!of_parse_phandle_with_args(master_np, "iommus",
198-
"#iommu-cells",
199-
idx, &iommu_spec)) {
200-
err = of_iommu_xlate(dev, &iommu_spec);
201-
of_node_put(iommu_spec.np);
202-
idx++;
203-
if (err)
204-
break;
205-
}
212+
err = of_iommu_configure_device(master_np, dev, id);
206213

207214
fwspec = dev_iommu_fwspec_get(dev);
208215
if (!err && fwspec)

drivers/of/device.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ int of_device_add(struct platform_device *ofdev)
7878
* @np: Pointer to OF node having DMA configuration
7979
* @force_dma: Whether device is to be set up by of_dma_configure() even if
8080
* DMA capability is not explicitly described by firmware.
81+
* @id: Optional const pointer value input id
8182
*
8283
* Try to get devices's DMA configuration from DT and update it
8384
* accordingly.
@@ -86,7 +87,8 @@ int of_device_add(struct platform_device *ofdev)
8687
* can use a platform bus notifier and handle BUS_NOTIFY_ADD_DEVICE events
8788
* to fix up DMA configuration.
8889
*/
89-
int of_dma_configure(struct device *dev, struct device_node *np, bool force_dma)
90+
int of_dma_configure_id(struct device *dev, struct device_node *np,
91+
bool force_dma, const u32 *id)
9092
{
9193
u64 dma_addr, paddr, size = 0;
9294
int ret;
@@ -160,7 +162,7 @@ int of_dma_configure(struct device *dev, struct device_node *np, bool force_dma)
160162
dev_dbg(dev, "device is%sdma coherent\n",
161163
coherent ? " " : " not ");
162164

163-
iommu = of_iommu_configure(dev, np);
165+
iommu = of_iommu_configure(dev, np, id);
164166
if (PTR_ERR(iommu) == -EPROBE_DEFER)
165167
return -EPROBE_DEFER;
166168

@@ -171,7 +173,7 @@ int of_dma_configure(struct device *dev, struct device_node *np, bool force_dma)
171173

172174
return 0;
173175
}
174-
EXPORT_SYMBOL_GPL(of_dma_configure);
176+
EXPORT_SYMBOL_GPL(of_dma_configure_id);
175177

176178
int of_device_register(struct platform_device *pdev)
177179
{

include/linux/of_device.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,15 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
5555
return of_node_get(cpu_dev->of_node);
5656
}
5757

58-
int of_dma_configure(struct device *dev,
58+
int of_dma_configure_id(struct device *dev,
5959
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+
}
6167
#else /* CONFIG_OF */
6268

6369
static inline int of_driver_match_device(struct device *dev,
@@ -106,6 +112,12 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
106112
return NULL;
107113
}
108114

115+
static inline int of_dma_configure_id(struct device *dev,
116+
struct device_node *np,
117+
bool force_dma)
118+
{
119+
return 0;
120+
}
109121
static inline int of_dma_configure(struct device *dev,
110122
struct device_node *np,
111123
bool force_dma)

include/linux/of_iommu.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ extern int of_get_dma_window(struct device_node *dn, const char *prefix,
1313
size_t *size);
1414

1515
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);
1718

1819
#else
1920

@@ -25,7 +26,8 @@ static inline int of_get_dma_window(struct device_node *dn, const char *prefix,
2526
}
2627

2728
static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
28-
struct device_node *master_np)
29+
struct device_node *master_np,
30+
const u32 *id)
2931
{
3032
return NULL;
3133
}

0 commit comments

Comments
 (0)