Skip to content

Commit 62babf2

Browse files
FROMLIST: of: Factor arguments passed to of_map_id() into a struct
Change of_map_id() to take a pointer to struct of_phandle_args instead of passing target device node and translated IDs separately. Update all callers accordingly. Add an explicit filter_np parameter to of_map_id() and of_map_msi_id() to separate the filter input from the output. Previously, the target parameter served dual purpose: as an input filter (if non-NULL, only match entries targeting that node) and as an output (receiving the matched node with a reference held). Now filter_np is the explicit input filter and arg->np is the pure output. Previously, of_map_id() would call of_node_put() on the matched node when a filter was provided, making reference ownership inconsistent. Remove this internal of_node_put() call so that of_map_id() now always transfers ownership of the matched node reference to the caller via arg->np. Callers are now consistently responsible for releasing this reference with of_node_put(arg->np) when done. Link: https://lore.kernel.org/all/20260408-parse_iommu_cells-v13-2-fa921e92661b@oss.qualcomm.com/ Acked-by: Frank Li <Frank.Li@nxp.com> Suggested-by: Rob Herring (Arm) <robh@kernel.org> Suggested-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Signed-off-by: Charan Teja Kalla <charan.kalla@oss.qualcomm.com> [Conflict: irq-gic-its-msi-parent.c was refactored to split of_pmsi_get_msi_info() into of_pmsi_get_dev_id() and of_v5_pmsi_get_msi_info(); updated both of_map_id() calls.] Signed-off-by: Vijayanand Jitta <vijayanand.jitta@oss.qualcomm.com>
1 parent 7a3860c commit 62babf2

9 files changed

Lines changed: 93 additions & 72 deletions

File tree

drivers/cdx/cdx_msi.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,22 +121,23 @@ static int cdx_msi_prepare(struct irq_domain *msi_domain,
121121
struct device *dev,
122122
int nvec, msi_alloc_info_t *info)
123123
{
124+
struct of_phandle_args msi_spec = {};
124125
struct cdx_device *cdx_dev = to_cdx_device(dev);
125126
struct device *parent = cdx_dev->cdx->dev;
126127
struct msi_domain_info *msi_info;
127-
u32 dev_id;
128128
int ret;
129129

130130
/* Retrieve device ID from requestor ID using parent device */
131-
ret = of_map_msi_id(parent->of_node, cdx_dev->msi_dev_id, NULL, &dev_id);
131+
ret = of_map_msi_id(parent->of_node, cdx_dev->msi_dev_id, NULL, &msi_spec);
132132
if (ret) {
133133
dev_err(dev, "of_map_id failed for MSI: %d\n", ret);
134134
return ret;
135135
}
136+
of_node_put(msi_spec.np);
136137

137138
#ifdef GENERIC_MSI_DOMAIN_OPS
138139
/* Set the device Id to be passed to the GIC-ITS */
139-
info->scratchpad[0].ul = dev_id;
140+
info->scratchpad[0].ul = msi_spec.args[0];
140141
#endif
141142

142143
msi_info = msi_get_domain_info(msi_domain->parent);

drivers/iommu/of_iommu.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ static int of_iommu_configure_dev_id(struct device_node *master_np,
4545
struct device *dev,
4646
const u32 *id)
4747
{
48-
struct of_phandle_args iommu_spec = { .args_count = 1 };
48+
struct of_phandle_args iommu_spec = {};
4949
int err;
5050

51-
err = of_map_iommu_id(master_np, *id, &iommu_spec.np, iommu_spec.args);
51+
err = of_map_iommu_id(master_np, *id, &iommu_spec);
5252
if (err)
5353
return err;
5454

drivers/irqchip/irq-gic-its-msi-parent.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,13 @@ static int of_pmsi_get_dev_id(struct irq_domain *domain, struct device *dev,
164164
} while (!ret);
165165

166166
if (ret) {
167-
struct device_node *np = NULL;
167+
struct of_phandle_args msi_spec = {};
168168

169-
ret = of_map_msi_id(dev->of_node, dev->id, &np, dev_id);
170-
if (np)
171-
of_node_put(np);
169+
ret = of_map_msi_id(dev->of_node, dev->id, NULL, &msi_spec);
170+
if (!ret) {
171+
of_node_put(msi_spec.np);
172+
*dev_id = msi_spec.args[0];
173+
}
172174
}
173175

174176
return ret;
@@ -209,12 +211,13 @@ static int of_v5_pmsi_get_msi_info(struct irq_domain *domain, struct device *dev
209211
} while (!ret);
210212

211213
if (ret) {
212-
struct device_node *np = NULL;
214+
struct of_phandle_args msi_spec = {};
213215

214-
ret = of_map_msi_id(dev->of_node, dev->id, &np, dev_id);
215-
if (np) {
216-
ret = its_translate_frame_address(np, pa);
217-
of_node_put(np);
216+
ret = of_map_msi_id(dev->of_node, dev->id, NULL, &msi_spec);
217+
if (!ret) {
218+
*dev_id = msi_spec.args[0];
219+
ret = its_translate_frame_address(msi_spec.np, pa);
220+
of_node_put(msi_spec.np);
218221
}
219222
}
220223

drivers/of/base.c

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2055,36 +2055,37 @@ int of_find_last_cache_level(unsigned int cpu)
20552055
* @id: device ID to map.
20562056
* @map_name: property name of the map to use.
20572057
* @map_mask_name: optional property name of the mask to use.
2058-
* @target: optional pointer to a target device node.
2059-
* @id_out: optional pointer to receive the translated ID.
2058+
* @filter_np: optional device node to filter matches by, or NULL to match any.
2059+
* If non-NULL, only map entries targeting this node will be matched.
2060+
* @arg: pointer to a &struct of_phandle_args for the result. On success,
2061+
* @arg->args[0] will contain the translated ID. If a map entry was
2062+
* matched, @arg->np will be set to the target node with a reference
2063+
* held that the caller must release with of_node_put().
20602064
*
20612065
* Given a device ID, look up the appropriate implementation-defined
20622066
* platform ID and/or the target device which receives transactions on that
2063-
* ID, as per the "iommu-map" and "msi-map" bindings. Either of @target or
2064-
* @id_out may be NULL if only the other is required. If @target points to
2065-
* a non-NULL device node pointer, only entries targeting that node will be
2066-
* matched; if it points to a NULL value, it will receive the device node of
2067-
* the first matching target phandle, with a reference held.
2067+
* ID, as per the "iommu-map" and "msi-map" bindings.
20682068
*
20692069
* Return: 0 on success or a standard error code on failure.
20702070
*/
20712071
int of_map_id(const struct device_node *np, u32 id,
20722072
const char *map_name, const char *map_mask_name,
2073-
struct device_node **target, u32 *id_out)
2073+
const struct device_node *filter_np, struct of_phandle_args *arg)
20742074
{
20752075
u32 map_mask, masked_id;
20762076
int map_len;
20772077
const __be32 *map = NULL;
20782078

2079-
if (!np || !map_name || (!target && !id_out))
2079+
if (!np || !map_name || !arg)
20802080
return -EINVAL;
20812081

20822082
map = of_get_property(np, map_name, &map_len);
20832083
if (!map) {
2084-
if (target)
2084+
if (filter_np)
20852085
return -ENODEV;
20862086
/* Otherwise, no map implies no translation */
2087-
*id_out = id;
2087+
arg->args[0] = id;
2088+
arg->args_count = 1;
20882089
return 0;
20892090
}
20902091

@@ -2126,18 +2127,14 @@ int of_map_id(const struct device_node *np, u32 id,
21262127
if (!phandle_node)
21272128
return -ENODEV;
21282129

2129-
if (target) {
2130-
if (*target)
2131-
of_node_put(phandle_node);
2132-
else
2133-
*target = phandle_node;
2134-
2135-
if (*target != phandle_node)
2136-
continue;
2130+
if (filter_np && filter_np != phandle_node) {
2131+
of_node_put(phandle_node);
2132+
continue;
21372133
}
21382134

2139-
if (id_out)
2140-
*id_out = masked_id - id_base + out_base;
2135+
arg->np = phandle_node;
2136+
arg->args[0] = masked_id - id_base + out_base;
2137+
arg->args_count = 1;
21412138

21422139
pr_debug("%pOF: %s, using mask %08x, id-base: %08x, out-base: %08x, length: %08x, id: %08x -> %08x\n",
21432140
np, map_name, map_mask, id_base, out_base,
@@ -2146,11 +2143,11 @@ int of_map_id(const struct device_node *np, u32 id,
21462143
}
21472144

21482145
pr_info("%pOF: no %s translation for id 0x%x on %pOF\n", np, map_name,
2149-
id, target && *target ? *target : NULL);
2146+
id, filter_np);
21502147

21512148
/* Bypasses translation */
2152-
if (id_out)
2153-
*id_out = id;
2149+
arg->args[0] = id;
2150+
arg->args_count = 1;
21542151
return 0;
21552152
}
21562153
EXPORT_SYMBOL_GPL(of_map_id);
@@ -2160,17 +2157,19 @@ EXPORT_SYMBOL_GPL(of_map_id);
21602157
* @np: root complex device node.
21612158
* @id: Requester ID of the device (e.g. PCI RID/BDF or a platform
21622159
* stream/device ID) used as the lookup key in the iommu-map table.
2163-
* @target: optional pointer to a target device node.
2164-
* @id_out: optional pointer to receive the translated ID.
2160+
* @arg: pointer to a &struct of_phandle_args for the result. On success,
2161+
* @arg->args[0] contains the translated ID. If a map entry was matched,
2162+
* @arg->np holds a reference to the target node that the caller must
2163+
* release with of_node_put().
21652164
*
21662165
* Convenience wrapper around of_map_id() using "iommu-map" and "iommu-map-mask".
21672166
*
21682167
* Return: 0 on success or a standard error code on failure.
21692168
*/
21702169
int of_map_iommu_id(const struct device_node *np, u32 id,
2171-
struct device_node **target, u32 *id_out)
2170+
struct of_phandle_args *arg)
21722171
{
2173-
return of_map_id(np, id, "iommu-map", "iommu-map-mask", target, id_out);
2172+
return of_map_id(np, id, "iommu-map", "iommu-map-mask", NULL, arg);
21742173
}
21752174
EXPORT_SYMBOL_GPL(of_map_iommu_id);
21762175

@@ -2179,16 +2178,21 @@ EXPORT_SYMBOL_GPL(of_map_iommu_id);
21792178
* @np: root complex device node.
21802179
* @id: Requester ID of the device (e.g. PCI RID/BDF or a platform
21812180
* stream/device ID) used as the lookup key in the msi-map table.
2182-
* @target: optional pointer to a target device node.
2183-
* @id_out: optional pointer to receive the translated ID.
2181+
* @filter_np: optional MSI controller node to filter matches by, or NULL
2182+
* to match any. If non-NULL, only map entries targeting this node will
2183+
* be matched.
2184+
* @arg: pointer to a &struct of_phandle_args for the result. On success,
2185+
* @arg->args[0] contains the translated ID. If a map entry was matched,
2186+
* @arg->np holds a reference to the target node that the caller must
2187+
* release with of_node_put().
21842188
*
21852189
* Convenience wrapper around of_map_id() using "msi-map" and "msi-map-mask".
21862190
*
21872191
* Return: 0 on success or a standard error code on failure.
21882192
*/
21892193
int of_map_msi_id(const struct device_node *np, u32 id,
2190-
struct device_node **target, u32 *id_out)
2194+
const struct device_node *filter_np, struct of_phandle_args *arg)
21912195
{
2192-
return of_map_id(np, id, "msi-map", "msi-map-mask", target, id_out);
2196+
return of_map_id(np, id, "msi-map", "msi-map-mask", filter_np, arg);
21932197
}
21942198
EXPORT_SYMBOL_GPL(of_map_msi_id);

drivers/of/irq.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -725,8 +725,16 @@ u32 of_msi_xlate(struct device *dev, struct device_node **msi_np, u32 id_in)
725725
* "msi-map" or an "msi-parent" property.
726726
*/
727727
for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent) {
728-
if (!of_map_msi_id(parent_dev->of_node, id_in, msi_np, &id_out))
728+
struct of_phandle_args msi_spec = {};
729+
730+
if (!of_map_msi_id(parent_dev->of_node, id_in, *msi_np, &msi_spec)) {
731+
id_out = msi_spec.args[0];
732+
if (!*msi_np)
733+
*msi_np = msi_spec.np;
734+
else
735+
of_node_put(msi_spec.np);
729736
break;
737+
}
730738
if (!of_check_msi_parent(parent_dev->of_node, msi_np))
731739
break;
732740
}

drivers/pci/controller/dwc/pci-imx6.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,41 +1118,41 @@ static void imx_pcie_remove_lut(struct imx_pcie *imx_pcie, u16 rid)
11181118

11191119
static int imx_pcie_add_lut_by_rid(struct imx_pcie *imx_pcie, u32 rid)
11201120
{
1121+
struct of_phandle_args iommu_spec = {};
1122+
struct of_phandle_args msi_spec = {};
11211123
struct device *dev = imx_pcie->pci->dev;
1122-
struct device_node *target;
11231124
u32 sid_i, sid_m;
11241125
int err_i, err_m;
11251126
u32 sid = 0;
11261127

1127-
target = NULL;
1128-
err_i = of_map_iommu_id(dev->of_node, rid, &target, &sid_i);
1129-
if (target) {
1130-
of_node_put(target);
1131-
} else {
1128+
err_i = of_map_iommu_id(dev->of_node, rid, &iommu_spec);
1129+
if (!err_i)
1130+
sid_i = iommu_spec.args[0];
1131+
of_node_put(iommu_spec.np);
1132+
if (!err_i && !iommu_spec.np) {
11321133
/*
1133-
* "target == NULL && err_i == 0" means RID out of map range.
1134-
* Use 1:1 map RID to streamID. Hardware can't support this
1135-
* because the streamID is only 6 bits
1134+
* "iommu_spec.np == NULL && err_i == 0" means RID out of map
1135+
* range. Use 1:1 map RID to streamID. Hardware can't support
1136+
* this because the streamID is only 6 bits.
11361137
*/
11371138
err_i = -EINVAL;
11381139
}
11391140

1140-
target = NULL;
1141-
err_m = of_map_msi_id(dev->of_node, rid, &target, &sid_m);
1142-
1141+
err_m = of_map_msi_id(dev->of_node, rid, NULL, &msi_spec);
1142+
if (!err_m)
1143+
sid_m = msi_spec.args[0];
1144+
of_node_put(msi_spec.np);
11431145
/*
1144-
* err_m target
1146+
* err_m msi_spec.np
11451147
* 0 NULL RID out of range. Use 1:1 map RID to
11461148
* streamID, Current hardware can't
11471149
* support it, so return -EINVAL.
11481150
* != 0 NULL msi-map does not exist, use built-in MSI
11491151
* 0 != NULL Get correct streamID from RID
11501152
* != 0 != NULL Invalid combination
11511153
*/
1152-
if (!err_m && !target)
1154+
if (!err_m && !msi_spec.np)
11531155
return -EINVAL;
1154-
else if (target)
1155-
of_node_put(target); /* Find streamID map entry for RID in msi-map */
11561156

11571157
/*
11581158
* msi-map iommu-map

drivers/pci/controller/pcie-apple.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,7 @@ static int apple_pcie_enable_device(struct pci_host_bridge *bridge, struct pci_d
782782
{
783783
u32 sid, rid = pci_dev_id(pdev);
784784
struct apple_pcie_port *port;
785+
struct of_phandle_args iommu_spec = {};
785786
int idx, err;
786787

787788
port = apple_pcie_get_port(pdev);
@@ -791,10 +792,12 @@ static int apple_pcie_enable_device(struct pci_host_bridge *bridge, struct pci_d
791792
dev_dbg(&pdev->dev, "added to bus %s, index %d\n",
792793
pci_name(pdev->bus->self), port->idx);
793794

794-
err = of_map_iommu_id(port->pcie->dev->of_node, rid, NULL, &sid);
795+
err = of_map_iommu_id(port->pcie->dev->of_node, rid, &iommu_spec);
795796
if (err)
796797
return err;
797798

799+
of_node_put(iommu_spec.np);
800+
sid = iommu_spec.args[0];
798801
mutex_lock(&port->pcie->lock);
799802

800803
idx = bitmap_find_free_region(port->sid_map, port->sid_map_sz, 0);

drivers/xen/grant-dma-ops.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,13 +315,13 @@ static int xen_dt_grant_init_backend_domid(struct device *dev,
315315
struct device_node *np,
316316
domid_t *backend_domid)
317317
{
318-
struct of_phandle_args iommu_spec = { .args_count = 1 };
318+
struct of_phandle_args iommu_spec = {};
319319

320320
if (dev_is_pci(dev)) {
321321
struct pci_dev *pdev = to_pci_dev(dev);
322322
u32 rid = PCI_DEVID(pdev->bus->number, pdev->devfn);
323323

324-
if (of_map_iommu_id(np, rid, &iommu_spec.np, iommu_spec.args)) {
324+
if (of_map_iommu_id(np, rid, &iommu_spec)) {
325325
dev_dbg(dev, "Cannot translate ID\n");
326326
return -ESRCH;
327327
}

include/linux/of.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -458,13 +458,13 @@ bool of_console_check(const struct device_node *dn, char *name, int index);
458458

459459
int of_map_id(const struct device_node *np, u32 id,
460460
const char *map_name, const char *map_mask_name,
461-
struct device_node **target, u32 *id_out);
461+
const struct device_node *filter_np, struct of_phandle_args *arg);
462462

463463
int of_map_iommu_id(const struct device_node *np, u32 id,
464-
struct device_node **target, u32 *id_out);
464+
struct of_phandle_args *arg);
465465

466466
int of_map_msi_id(const struct device_node *np, u32 id,
467-
struct device_node **target, u32 *id_out);
467+
const struct device_node *filter_np, struct of_phandle_args *arg);
468468

469469
phys_addr_t of_dma_get_max_cpu_address(struct device_node *np);
470470

@@ -913,19 +913,21 @@ static inline void of_property_clear_flag(struct property *p, unsigned long flag
913913

914914
static inline int of_map_id(const struct device_node *np, u32 id,
915915
const char *map_name, const char *map_mask_name,
916-
struct device_node **target, u32 *id_out)
916+
const struct device_node *filter_np,
917+
struct of_phandle_args *arg)
917918
{
918919
return -EINVAL;
919920
}
920921

921922
static inline int of_map_iommu_id(const struct device_node *np, u32 id,
922-
struct device_node **target, u32 *id_out)
923+
struct of_phandle_args *arg)
923924
{
924925
return -EINVAL;
925926
}
926927

927928
static inline int of_map_msi_id(const struct device_node *np, u32 id,
928-
struct device_node **target, u32 *id_out)
929+
const struct device_node *filter_np,
930+
struct of_phandle_args *arg)
929931
{
930932
return -EINVAL;
931933
}

0 commit comments

Comments
 (0)