RE: [PATCH 2/6 v3] iommu: of: make of_pci_map_rid() available for other devices too
> -Original Message- > From: Rob Herring [mailto:r...@kernel.org] > Sent: Friday, April 27, 2018 10:46 PM > To: Nipun Gupta <nipun.gu...@nxp.com> > Cc: robin.mur...@arm.com; will.dea...@arm.com; mark.rutl...@arm.com; > catalin.mari...@arm.com; h...@lst.de; gre...@linuxfoundation.org; > j...@8bytes.org; m.szyprow...@samsung.com; shawn...@kernel.org; > frowand.l...@gmail.com; bhelg...@google.com; iommu@lists.linux- > foundation.org; linux-kernel@vger.kernel.org; devicet...@vger.kernel.org; > linux-arm-ker...@lists.infradead.org; linuxppc-...@lists.ozlabs.org; linux- > p...@vger.kernel.org; Bharat Bhushan <bharat.bhus...@nxp.com>; > stuyo...@gmail.com; Laurentiu Tudor <laurentiu.tu...@nxp.com>; Leo Li > <leoyang...@nxp.com> > Subject: Re: [PATCH 2/6 v3] iommu: of: make of_pci_map_rid() available for > other devices too > > On Fri, Apr 27, 2018 at 03:57:02PM +0530, Nipun Gupta wrote: > > iommu-map property is also used by devices with fsl-mc. This > > patch moves the of_pci_map_rid to generic location, so that it > > can be used by other busses too. > > > > 'of_pci_map_rid' is renamed here to 'of_map_rid' and there is no > > functional change done in the API. > > > > Signed-off-by: Nipun Gupta <nipun.gu...@nxp.com> > > --- > > drivers/iommu/of_iommu.c | 6 +-- > > drivers/of/address.c | 102 > + > > drivers/of/irq.c | 7 ++-- > > drivers/pci/of.c | 101 > > > > include/linux/of_address.h | 11 + > > include/linux/of_pci.h | 10 - > > 6 files changed, 120 insertions(+), 117 deletions(-) > > of/address.c isn't really the best fit either, though I don't have a > better suggestion. > > I'm guessing this breaks on Sparc which doesn't build of/address.c. > I guess move it to base.c and of.h if that is the case. Sure, that makes sense. Thank you for the suggestion !! I'll spin off new version with this change. Regards, Nipun > > Rob
RE: [PATCH 2/6 v3] iommu: of: make of_pci_map_rid() available for other devices too
> -Original Message- > From: Rob Herring [mailto:r...@kernel.org] > Sent: Friday, April 27, 2018 10:46 PM > To: Nipun Gupta > Cc: robin.mur...@arm.com; will.dea...@arm.com; mark.rutl...@arm.com; > catalin.mari...@arm.com; h...@lst.de; gre...@linuxfoundation.org; > j...@8bytes.org; m.szyprow...@samsung.com; shawn...@kernel.org; > frowand.l...@gmail.com; bhelg...@google.com; iommu@lists.linux- > foundation.org; linux-kernel@vger.kernel.org; devicet...@vger.kernel.org; > linux-arm-ker...@lists.infradead.org; linuxppc-...@lists.ozlabs.org; linux- > p...@vger.kernel.org; Bharat Bhushan ; > stuyo...@gmail.com; Laurentiu Tudor ; Leo Li > > Subject: Re: [PATCH 2/6 v3] iommu: of: make of_pci_map_rid() available for > other devices too > > On Fri, Apr 27, 2018 at 03:57:02PM +0530, Nipun Gupta wrote: > > iommu-map property is also used by devices with fsl-mc. This > > patch moves the of_pci_map_rid to generic location, so that it > > can be used by other busses too. > > > > 'of_pci_map_rid' is renamed here to 'of_map_rid' and there is no > > functional change done in the API. > > > > Signed-off-by: Nipun Gupta > > --- > > drivers/iommu/of_iommu.c | 6 +-- > > drivers/of/address.c | 102 > + > > drivers/of/irq.c | 7 ++-- > > drivers/pci/of.c | 101 > > > > include/linux/of_address.h | 11 + > > include/linux/of_pci.h | 10 - > > 6 files changed, 120 insertions(+), 117 deletions(-) > > of/address.c isn't really the best fit either, though I don't have a > better suggestion. > > I'm guessing this breaks on Sparc which doesn't build of/address.c. > I guess move it to base.c and of.h if that is the case. Sure, that makes sense. Thank you for the suggestion !! I'll spin off new version with this change. Regards, Nipun > > Rob
Re: [PATCH 2/6 v3] iommu: of: make of_pci_map_rid() available for other devices too
Hi Nipun, Thank you for the patch! Yet something to improve: [auto build test ERROR on linus/master] [also build test ERROR on v4.17-rc2 next-20180426] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Nipun-Gupta/Docs-dt-add-fsl-mc-iommu-map-device-tree-binding/20180428-111415 config: sparc64-allyesconfig (attached as .config) compiler: sparc64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=sparc64 All errors (new ones prefixed by >>): `.exit.data' referenced in section `.exit.text' of drivers/tty/n_hdlc.o: defined in discarded section `.exit.data' of drivers/tty/n_hdlc.o `.exit.data' referenced in section `.exit.text' of drivers/tty/n_hdlc.o: defined in discarded section `.exit.data' of drivers/tty/n_hdlc.o `.exit.data' referenced in section `.exit.text' of drivers/tty/n_hdlc.o: defined in discarded section `.exit.data' of drivers/tty/n_hdlc.o `.exit.data' referenced in section `.exit.text' of drivers/tty/n_hdlc.o: defined in discarded section `.exit.data' of drivers/tty/n_hdlc.o drivers/iommu/of_iommu.o: In function `of_pci_iommu_init': >> of_iommu.c:(.text+0x398): undefined reference to `of_map_rid' --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH 2/6 v3] iommu: of: make of_pci_map_rid() available for other devices too
Hi Nipun, Thank you for the patch! Yet something to improve: [auto build test ERROR on linus/master] [also build test ERROR on v4.17-rc2 next-20180426] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Nipun-Gupta/Docs-dt-add-fsl-mc-iommu-map-device-tree-binding/20180428-111415 config: sparc64-allyesconfig (attached as .config) compiler: sparc64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=sparc64 All errors (new ones prefixed by >>): `.exit.data' referenced in section `.exit.text' of drivers/tty/n_hdlc.o: defined in discarded section `.exit.data' of drivers/tty/n_hdlc.o `.exit.data' referenced in section `.exit.text' of drivers/tty/n_hdlc.o: defined in discarded section `.exit.data' of drivers/tty/n_hdlc.o `.exit.data' referenced in section `.exit.text' of drivers/tty/n_hdlc.o: defined in discarded section `.exit.data' of drivers/tty/n_hdlc.o `.exit.data' referenced in section `.exit.text' of drivers/tty/n_hdlc.o: defined in discarded section `.exit.data' of drivers/tty/n_hdlc.o drivers/iommu/of_iommu.o: In function `of_pci_iommu_init': >> of_iommu.c:(.text+0x398): undefined reference to `of_map_rid' --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH 2/6 v3] iommu: of: make of_pci_map_rid() available for other devices too
On Fri, Apr 27, 2018 at 03:57:02PM +0530, Nipun Gupta wrote: > iommu-map property is also used by devices with fsl-mc. This > patch moves the of_pci_map_rid to generic location, so that it > can be used by other busses too. > > 'of_pci_map_rid' is renamed here to 'of_map_rid' and there is no > functional change done in the API. > > Signed-off-by: Nipun Gupta> --- > drivers/iommu/of_iommu.c | 6 +-- > drivers/of/address.c | 102 > + > drivers/of/irq.c | 7 ++-- > drivers/pci/of.c | 101 > include/linux/of_address.h | 11 + > include/linux/of_pci.h | 10 - > 6 files changed, 120 insertions(+), 117 deletions(-) of/address.c isn't really the best fit either, though I don't have a better suggestion. I'm guessing this breaks on Sparc which doesn't build of/address.c. I guess move it to base.c and of.h if that is the case. Rob
Re: [PATCH 2/6 v3] iommu: of: make of_pci_map_rid() available for other devices too
On Fri, Apr 27, 2018 at 03:57:02PM +0530, Nipun Gupta wrote: > iommu-map property is also used by devices with fsl-mc. This > patch moves the of_pci_map_rid to generic location, so that it > can be used by other busses too. > > 'of_pci_map_rid' is renamed here to 'of_map_rid' and there is no > functional change done in the API. > > Signed-off-by: Nipun Gupta > --- > drivers/iommu/of_iommu.c | 6 +-- > drivers/of/address.c | 102 > + > drivers/of/irq.c | 7 ++-- > drivers/pci/of.c | 101 > include/linux/of_address.h | 11 + > include/linux/of_pci.h | 10 - > 6 files changed, 120 insertions(+), 117 deletions(-) of/address.c isn't really the best fit either, though I don't have a better suggestion. I'm guessing this breaks on Sparc which doesn't build of/address.c. I guess move it to base.c and of.h if that is the case. Rob
[PATCH 2/6 v3] iommu: of: make of_pci_map_rid() available for other devices too
iommu-map property is also used by devices with fsl-mc. This patch moves the of_pci_map_rid to generic location, so that it can be used by other busses too. 'of_pci_map_rid' is renamed here to 'of_map_rid' and there is no functional change done in the API. Signed-off-by: Nipun Gupta--- drivers/iommu/of_iommu.c | 6 +-- drivers/of/address.c | 102 + drivers/of/irq.c | 7 ++-- drivers/pci/of.c | 101 include/linux/of_address.h | 11 + include/linux/of_pci.h | 10 - 6 files changed, 120 insertions(+), 117 deletions(-) diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index 5c36a8b..ea9ecef 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -149,9 +150,8 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data) struct of_phandle_args iommu_spec = { .args_count = 1 }; int err; - err = of_pci_map_rid(info->np, alias, "iommu-map", -"iommu-map-mask", _spec.np, -iommu_spec.args); + err = of_map_rid(info->np, alias, "iommu-map", "iommu-map-mask", +_spec.np, iommu_spec.args); if (err) return err == -ENODEV ? NO_IOMMU : err; diff --git a/drivers/of/address.c b/drivers/of/address.c index 5334991..4163f24 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -985,3 +985,105 @@ bool of_dma_is_coherent(struct device_node *np) return false; } EXPORT_SYMBOL_GPL(of_dma_is_coherent); + +/** + * of_map_rid - Translate a requester ID through a downstream mapping. + * @np: root complex device node. + * @rid: device requester ID to map. + * @map_name: property name of the map to use. + * @map_mask_name: optional property name of the mask to use. + * @target: optional pointer to a target device node. + * @id_out: optional pointer to receive the translated ID. + * + * Given a device requester ID, look up the appropriate implementation-defined + * platform ID and/or the target device which receives transactions on that + * ID, as per the "iommu-map" and "msi-map" bindings. Either of @target or + * @id_out may be NULL if only the other is required. If @target points to + * a non-NULL device node pointer, only entries targeting that node will be + * matched; if it points to a NULL value, it will receive the device node of + * the first matching target phandle, with a reference held. + * + * Return: 0 on success or a standard error code on failure. + */ +int of_map_rid(struct device_node *np, u32 rid, + const char *map_name, const char *map_mask_name, + struct device_node **target, u32 *id_out) +{ + u32 map_mask, masked_rid; + int map_len; + const __be32 *map = NULL; + + if (!np || !map_name || (!target && !id_out)) + return -EINVAL; + + map = of_get_property(np, map_name, _len); + if (!map) { + if (target) + return -ENODEV; + /* Otherwise, no map implies no translation */ + *id_out = rid; + return 0; + } + + if (!map_len || map_len % (4 * sizeof(*map))) { + pr_err("%pOF: Error: Bad %s length: %d\n", np, + map_name, map_len); + return -EINVAL; + } + + /* The default is to select all bits. */ + map_mask = 0x; + + /* +* Can be overridden by "{iommu,msi}-map-mask" property. +* If of_property_read_u32() fails, the default is used. +*/ + if (map_mask_name) + of_property_read_u32(np, map_mask_name, _mask); + + masked_rid = map_mask & rid; + for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) { + struct device_node *phandle_node; + u32 rid_base = be32_to_cpup(map + 0); + u32 phandle = be32_to_cpup(map + 1); + u32 out_base = be32_to_cpup(map + 2); + u32 rid_len = be32_to_cpup(map + 3); + + if (rid_base & ~map_mask) { + pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores rid-base (0x%x)\n", + np, map_name, map_name, + map_mask, rid_base); + return -EFAULT; + } + + if (masked_rid < rid_base || masked_rid >= rid_base + rid_len) + continue; + + phandle_node = of_find_node_by_phandle(phandle); + if (!phandle_node) + return -ENODEV; + + if (target) { + if (*target) + of_node_put(phandle_node); + else +
[PATCH 2/6 v3] iommu: of: make of_pci_map_rid() available for other devices too
iommu-map property is also used by devices with fsl-mc. This patch moves the of_pci_map_rid to generic location, so that it can be used by other busses too. 'of_pci_map_rid' is renamed here to 'of_map_rid' and there is no functional change done in the API. Signed-off-by: Nipun Gupta --- drivers/iommu/of_iommu.c | 6 +-- drivers/of/address.c | 102 + drivers/of/irq.c | 7 ++-- drivers/pci/of.c | 101 include/linux/of_address.h | 11 + include/linux/of_pci.h | 10 - 6 files changed, 120 insertions(+), 117 deletions(-) diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index 5c36a8b..ea9ecef 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -149,9 +150,8 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data) struct of_phandle_args iommu_spec = { .args_count = 1 }; int err; - err = of_pci_map_rid(info->np, alias, "iommu-map", -"iommu-map-mask", _spec.np, -iommu_spec.args); + err = of_map_rid(info->np, alias, "iommu-map", "iommu-map-mask", +_spec.np, iommu_spec.args); if (err) return err == -ENODEV ? NO_IOMMU : err; diff --git a/drivers/of/address.c b/drivers/of/address.c index 5334991..4163f24 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -985,3 +985,105 @@ bool of_dma_is_coherent(struct device_node *np) return false; } EXPORT_SYMBOL_GPL(of_dma_is_coherent); + +/** + * of_map_rid - Translate a requester ID through a downstream mapping. + * @np: root complex device node. + * @rid: device requester ID to map. + * @map_name: property name of the map to use. + * @map_mask_name: optional property name of the mask to use. + * @target: optional pointer to a target device node. + * @id_out: optional pointer to receive the translated ID. + * + * Given a device requester ID, look up the appropriate implementation-defined + * platform ID and/or the target device which receives transactions on that + * ID, as per the "iommu-map" and "msi-map" bindings. Either of @target or + * @id_out may be NULL if only the other is required. If @target points to + * a non-NULL device node pointer, only entries targeting that node will be + * matched; if it points to a NULL value, it will receive the device node of + * the first matching target phandle, with a reference held. + * + * Return: 0 on success or a standard error code on failure. + */ +int of_map_rid(struct device_node *np, u32 rid, + const char *map_name, const char *map_mask_name, + struct device_node **target, u32 *id_out) +{ + u32 map_mask, masked_rid; + int map_len; + const __be32 *map = NULL; + + if (!np || !map_name || (!target && !id_out)) + return -EINVAL; + + map = of_get_property(np, map_name, _len); + if (!map) { + if (target) + return -ENODEV; + /* Otherwise, no map implies no translation */ + *id_out = rid; + return 0; + } + + if (!map_len || map_len % (4 * sizeof(*map))) { + pr_err("%pOF: Error: Bad %s length: %d\n", np, + map_name, map_len); + return -EINVAL; + } + + /* The default is to select all bits. */ + map_mask = 0x; + + /* +* Can be overridden by "{iommu,msi}-map-mask" property. +* If of_property_read_u32() fails, the default is used. +*/ + if (map_mask_name) + of_property_read_u32(np, map_mask_name, _mask); + + masked_rid = map_mask & rid; + for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) { + struct device_node *phandle_node; + u32 rid_base = be32_to_cpup(map + 0); + u32 phandle = be32_to_cpup(map + 1); + u32 out_base = be32_to_cpup(map + 2); + u32 rid_len = be32_to_cpup(map + 3); + + if (rid_base & ~map_mask) { + pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores rid-base (0x%x)\n", + np, map_name, map_name, + map_mask, rid_base); + return -EFAULT; + } + + if (masked_rid < rid_base || masked_rid >= rid_base + rid_len) + continue; + + phandle_node = of_find_node_by_phandle(phandle); + if (!phandle_node) + return -ENODEV; + + if (target) { + if (*target) + of_node_put(phandle_node); + else +