Message ID | 20240707002055.1835121-2-cristian.marussi@arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Make SCMI transport as standalone drivers | expand |
On 7/6/2024 5:20 PM, Cristian Marussi wrote: > From: Peng Fan <peng.fan@nxp.com> > > To get the address of shmem could be generalized by introducing > setup_shmem_iomap. Then the duplicated code in mailbox.c, optee.c > and smc.c could be dropped. > > Signed-off-by: Peng Fan <peng.fan@nxp.com> > [ Cristian: make use of the new helper also in smc.c ] > Signed-off-by: Cristian Marussi <cristian.marussi@arm.com> > --- > drivers/firmware/arm_scmi/common.h | 2 ++ > drivers/firmware/arm_scmi/mailbox.c | 27 ++++------------------ > drivers/firmware/arm_scmi/optee.c | 35 ++++------------------------ > drivers/firmware/arm_scmi/shmem.c | 36 +++++++++++++++++++++++++++++ > drivers/firmware/arm_scmi/smc.c | 23 +++--------------- > 5 files changed, 49 insertions(+), 74 deletions(-) > > diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h > index 4b8c5250cdb5..b4c217641e3a 100644 > --- a/drivers/firmware/arm_scmi/common.h > +++ b/drivers/firmware/arm_scmi/common.h > @@ -327,6 +327,8 @@ bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem, > struct scmi_xfer *xfer); > bool shmem_channel_free(struct scmi_shared_mem __iomem *shmem); > bool shmem_channel_intr_enabled(struct scmi_shared_mem __iomem *shmem); > +void __iomem *setup_shmem_iomap(struct scmi_chan_info *cinfo, struct device *dev, > + bool tx); > > /* declarations for message passing transports */ > struct scmi_msg_payld; > diff --git a/drivers/firmware/arm_scmi/mailbox.c b/drivers/firmware/arm_scmi/mailbox.c > index 0219a12e3209..b0a579f31905 100644 > --- a/drivers/firmware/arm_scmi/mailbox.c > +++ b/drivers/firmware/arm_scmi/mailbox.c > @@ -178,11 +178,8 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, > const char *desc = tx ? "Tx" : "Rx"; > struct device *cdev = cinfo->dev; > struct scmi_mailbox *smbox; > - struct device_node *shmem; > - int ret, a2p_rx_chan, p2a_chan, p2a_rx_chan, idx = tx ? 0 : 1; > + int ret, a2p_rx_chan, p2a_chan, p2a_rx_chan; > struct mbox_client *cl; > - resource_size_t size; > - struct resource res; > > ret = mailbox_chan_validate(cdev, &a2p_rx_chan, &p2a_chan, &p2a_rx_chan); > if (ret) > @@ -195,25 +192,9 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, > if (!smbox) > return -ENOMEM; > > - shmem = of_parse_phandle(cdev->of_node, "shmem", idx); > - if (!of_device_is_compatible(shmem, "arm,scmi-shmem")) { > - of_node_put(shmem); > - return -ENXIO; > - } > - > - ret = of_address_to_resource(shmem, 0, &res); > - of_node_put(shmem); > - if (ret) { > - dev_err(cdev, "failed to get SCMI %s shared memory\n", desc); > - return ret; > - } > - > - size = resource_size(&res); > - smbox->shmem = devm_ioremap(dev, res.start, size); > - if (!smbox->shmem) { > - dev_err(dev, "failed to ioremap SCMI %s shared memory\n", desc); > - return -EADDRNOTAVAIL; > - } > + smbox->shmem = setup_shmem_iomap(cinfo, dev, tx); > + if (IS_ERR(smbox->shmem)) > + return PTR_ERR(smbox->shmem); > > cl = &smbox->cl; > cl->dev = cdev; > diff --git a/drivers/firmware/arm_scmi/optee.c b/drivers/firmware/arm_scmi/optee.c > index 4e7944b91e38..8abcd668108c 100644 > --- a/drivers/firmware/arm_scmi/optee.c > +++ b/drivers/firmware/arm_scmi/optee.c > @@ -368,38 +368,11 @@ static int setup_dynamic_shmem(struct device *dev, struct scmi_optee_channel *ch > static int setup_static_shmem(struct device *dev, struct scmi_chan_info *cinfo, > struct scmi_optee_channel *channel) > { > - struct device_node *np; > - resource_size_t size; > - struct resource res; > - int ret; > - > - np = of_parse_phandle(cinfo->dev->of_node, "shmem", 0); > - if (!of_device_is_compatible(np, "arm,scmi-shmem")) { > - ret = -ENXIO; > - goto out; > - } > - > - ret = of_address_to_resource(np, 0, &res); > - if (ret) { > - dev_err(dev, "Failed to get SCMI Tx shared memory\n"); > - goto out; > - } > - > - size = resource_size(&res); > + channel->req.shmem = setup_shmem_iomap(cinfo, dev, true); > + if (IS_ERR(channel->req.shmem)) > + return PTR_ERR(channel->req.shmem); > > - channel->req.shmem = devm_ioremap(dev, res.start, size); > - if (!channel->req.shmem) { > - dev_err(dev, "Failed to ioremap SCMI Tx shared memory\n"); > - ret = -EADDRNOTAVAIL; > - goto out; > - } > - > - ret = 0; > - > -out: > - of_node_put(np); > - > - return ret; > + return 0; > } > > static int setup_shmem(struct device *dev, struct scmi_chan_info *cinfo, > diff --git a/drivers/firmware/arm_scmi/shmem.c b/drivers/firmware/arm_scmi/shmem.c > index b74e5a740f2c..c31f188d74ef 100644 > --- a/drivers/firmware/arm_scmi/shmem.c > +++ b/drivers/firmware/arm_scmi/shmem.c > @@ -7,6 +7,8 @@ > > #include <linux/ktime.h> > #include <linux/io.h> > +#include <linux/of.h> > +#include <linux/of_address.h> > #include <linux/processor.h> > #include <linux/types.h> > > @@ -133,3 +135,37 @@ bool shmem_channel_intr_enabled(struct scmi_shared_mem __iomem *shmem) > { > return ioread32(&shmem->flags) & SCMI_SHMEM_FLAG_INTR_ENABLED; > } > + > +void *__iomem > +setup_shmem_iomap(struct scmi_chan_info *cinfo, struct device *dev, bool tx) > +{ > + const char *desc = tx ? "Tx" : "Rx"; > + int ret, idx = tx ? 0 : 1; > + struct device *cdev = cinfo->dev; > + struct device_node *shmem; > + resource_size_t size; > + struct resource res; > + void __iomem *addr; > + > + shmem = of_parse_phandle(cdev->of_node, "shmem", idx); > + if (!of_device_is_compatible(shmem, "arm,scmi-shmem")) { > + of_node_put(shmem); > + return ERR_PTR(-ENXIO); > + } > + > + ret = of_address_to_resource(shmem, 0, &res); > + of_node_put(shmem); > + if (ret) { > + dev_err(cdev, "failed to get SCMI %s shared memory\n", desc); > + return ERR_PTR(ret); > + } > + > + size = resource_size(&res); > + addr = devm_ioremap(dev, res.start, size); > + if (!addr) { > + dev_err(dev, "failed to ioremap SCMI %s shared memory\n", desc); > + return ERR_PTR(-EADDRNOTAVAIL); > + } > + > + return addr; > +} > diff --git a/drivers/firmware/arm_scmi/smc.c b/drivers/firmware/arm_scmi/smc.c > index 39936e1dd30e..a640a4312472 100644 > --- a/drivers/firmware/arm_scmi/smc.c > +++ b/drivers/firmware/arm_scmi/smc.c > @@ -132,7 +132,6 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, > struct scmi_smc *scmi_info; > resource_size_t size; > struct resource res; > - struct device_node *np; > u32 func_id; > int ret; > > @@ -143,25 +142,9 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, > if (!scmi_info) > return -ENOMEM; > > - np = of_parse_phandle(cdev->of_node, "shmem", 0); > - if (!of_device_is_compatible(np, "arm,scmi-shmem")) { > - of_node_put(np); > - return -ENXIO; > - } > - > - ret = of_address_to_resource(np, 0, &res); > - of_node_put(np); > - if (ret) { > - dev_err(cdev, "failed to get SCMI Tx shared memory\n"); > - return ret; > - } > - > - size = resource_size(&res); Hi Peng/Cristian, This will break Qualcomm smc transport as we need shmem 'size' to get to the cap-id. Thanks, -Nikunj > - scmi_info->shmem = devm_ioremap(dev, res.start, size); > - if (!scmi_info->shmem) { > - dev_err(dev, "failed to ioremap SCMI Tx shared memory\n"); > - return -EADDRNOTAVAIL; > - } > + scmi_info->shmem = setup_shmem_iomap(cinfo, dev, tx); > + if (IS_ERR(scmi_info->shmem)) > + return PTR_ERR(scmi_info->shmem); > > ret = of_property_read_u32(dev->of_node, "arm,smc-id", &func_id); > if (ret < 0)
Hi Cristian, kernel test robot noticed the following build warnings: [auto build test WARNING on soc/for-next] [also build test WARNING on next-20240703] [cannot apply to linus/master v6.10-rc7] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Cristian-Marussi/firmware-arm_scmi-Introduce-setup_shmem_iomap/20240707-082513 base: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next patch link: https://lore.kernel.org/r/20240707002055.1835121-2-cristian.marussi%40arm.com patch subject: [PATCH 1/8] firmware: arm_scmi: Introduce setup_shmem_iomap config: arm-randconfig-r111-20240708 (https://download.01.org/0day-ci/archive/20240708/202407080937.AYEaDXCD-lkp@intel.com/config) compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project a0c6b8aef853eedaa0980f07c0a502a5a8a9740e) reproduce: (https://download.01.org/0day-ci/archive/20240708/202407080937.AYEaDXCD-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202407080937.AYEaDXCD-lkp@intel.com/ sparse warnings: (new ones prefixed by >>) >> drivers/firmware/arm_scmi/shmem.c:170:16: sparse: sparse: incorrect type in return expression (different address spaces) @@ expected void * @@ got void [noderef] __iomem *[assigned] addr @@ drivers/firmware/arm_scmi/shmem.c:170:16: sparse: expected void * drivers/firmware/arm_scmi/shmem.c:170:16: sparse: got void [noderef] __iomem *[assigned] addr drivers/firmware/arm_scmi/shmem.c:139:6: sparse: sparse: symbol 'setup_shmem_iomap' redeclared with different type (different address spaces): drivers/firmware/arm_scmi/shmem.c:139:6: sparse: void *extern [addressable] [noderef] [toplevel] __iomem setup_shmem_iomap( ... ) drivers/firmware/arm_scmi/shmem.c: note: in included file: drivers/firmware/arm_scmi/common.h:330:14: sparse: note: previously declared as: drivers/firmware/arm_scmi/common.h:330:14: sparse: void [noderef] __iomem *extern [addressable] [toplevel] setup_shmem_iomap( ... ) vim +170 drivers/firmware/arm_scmi/shmem.c 138 139 void *__iomem 140 setup_shmem_iomap(struct scmi_chan_info *cinfo, struct device *dev, bool tx) 141 { 142 const char *desc = tx ? "Tx" : "Rx"; 143 int ret, idx = tx ? 0 : 1; 144 struct device *cdev = cinfo->dev; 145 struct device_node *shmem; 146 resource_size_t size; 147 struct resource res; 148 void __iomem *addr; 149 150 shmem = of_parse_phandle(cdev->of_node, "shmem", idx); 151 if (!of_device_is_compatible(shmem, "arm,scmi-shmem")) { 152 of_node_put(shmem); 153 return ERR_PTR(-ENXIO); 154 } 155 156 ret = of_address_to_resource(shmem, 0, &res); 157 of_node_put(shmem); 158 if (ret) { 159 dev_err(cdev, "failed to get SCMI %s shared memory\n", desc); 160 return ERR_PTR(ret); 161 } 162 163 size = resource_size(&res); 164 addr = devm_ioremap(dev, res.start, size); 165 if (!addr) { 166 dev_err(dev, "failed to ioremap SCMI %s shared memory\n", desc); 167 return ERR_PTR(-EADDRNOTAVAIL); 168 } 169 > 170 return addr;
On Sun, Jul 07, 2024 at 09:48:58AM -0700, Nikunj Kela wrote: > > On 7/6/2024 5:20 PM, Cristian Marussi wrote: > > From: Peng Fan <peng.fan@nxp.com> > > > > To get the address of shmem could be generalized by introducing > > setup_shmem_iomap. Then the duplicated code in mailbox.c, optee.c > > and smc.c could be dropped. > > > > Signed-off-by: Peng Fan <peng.fan@nxp.com> > > [ Cristian: make use of the new helper also in smc.c ] > > Signed-off-by: Cristian Marussi <cristian.marussi@arm.com> > > --- > > drivers/firmware/arm_scmi/common.h | 2 ++ > > drivers/firmware/arm_scmi/mailbox.c | 27 ++++------------------ > > drivers/firmware/arm_scmi/optee.c | 35 ++++------------------------ > > drivers/firmware/arm_scmi/shmem.c | 36 +++++++++++++++++++++++++++++ > > drivers/firmware/arm_scmi/smc.c | 23 +++--------------- > > 5 files changed, 49 insertions(+), 74 deletions(-) > > > > diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h > > index 4b8c5250cdb5..b4c217641e3a 100644 > > --- a/drivers/firmware/arm_scmi/common.h > > +++ b/drivers/firmware/arm_scmi/common.h > > @@ -327,6 +327,8 @@ bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem, > > struct scmi_xfer *xfer); > > bool shmem_channel_free(struct scmi_shared_mem __iomem *shmem); > > bool shmem_channel_intr_enabled(struct scmi_shared_mem __iomem *shmem); > > +void __iomem *setup_shmem_iomap(struct scmi_chan_info *cinfo, struct device *dev, > > + bool tx); > > > > /* declarations for message passing transports */ > > struct scmi_msg_payld; > > diff --git a/drivers/firmware/arm_scmi/mailbox.c b/drivers/firmware/arm_scmi/mailbox.c > > index 0219a12e3209..b0a579f31905 100644 > > --- a/drivers/firmware/arm_scmi/mailbox.c > > +++ b/drivers/firmware/arm_scmi/mailbox.c > > @@ -178,11 +178,8 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, > > const char *desc = tx ? "Tx" : "Rx"; > > struct device *cdev = cinfo->dev; > > struct scmi_mailbox *smbox; > > - struct device_node *shmem; > > - int ret, a2p_rx_chan, p2a_chan, p2a_rx_chan, idx = tx ? 0 : 1; > > + int ret, a2p_rx_chan, p2a_chan, p2a_rx_chan; > > struct mbox_client *cl; > > - resource_size_t size; > > - struct resource res; > > > > ret = mailbox_chan_validate(cdev, &a2p_rx_chan, &p2a_chan, &p2a_rx_chan); > > if (ret) > > @@ -195,25 +192,9 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, > > if (!smbox) > > return -ENOMEM; > > > > - shmem = of_parse_phandle(cdev->of_node, "shmem", idx); > > - if (!of_device_is_compatible(shmem, "arm,scmi-shmem")) { > > - of_node_put(shmem); > > - return -ENXIO; > > - } > > - > > - ret = of_address_to_resource(shmem, 0, &res); > > - of_node_put(shmem); > > - if (ret) { > > - dev_err(cdev, "failed to get SCMI %s shared memory\n", desc); > > - return ret; > > - } > > - > > - size = resource_size(&res); > > - smbox->shmem = devm_ioremap(dev, res.start, size); > > - if (!smbox->shmem) { > > - dev_err(dev, "failed to ioremap SCMI %s shared memory\n", desc); > > - return -EADDRNOTAVAIL; > > - } > > + smbox->shmem = setup_shmem_iomap(cinfo, dev, tx); > > + if (IS_ERR(smbox->shmem)) > > + return PTR_ERR(smbox->shmem); > > > > cl = &smbox->cl; > > cl->dev = cdev; > > diff --git a/drivers/firmware/arm_scmi/optee.c b/drivers/firmware/arm_scmi/optee.c > > index 4e7944b91e38..8abcd668108c 100644 > > --- a/drivers/firmware/arm_scmi/optee.c > > +++ b/drivers/firmware/arm_scmi/optee.c > > @@ -368,38 +368,11 @@ static int setup_dynamic_shmem(struct device *dev, struct scmi_optee_channel *ch > > static int setup_static_shmem(struct device *dev, struct scmi_chan_info *cinfo, > > struct scmi_optee_channel *channel) > > { > > - struct device_node *np; > > - resource_size_t size; > > - struct resource res; > > - int ret; > > - > > - np = of_parse_phandle(cinfo->dev->of_node, "shmem", 0); > > - if (!of_device_is_compatible(np, "arm,scmi-shmem")) { > > - ret = -ENXIO; > > - goto out; > > - } > > - > > - ret = of_address_to_resource(np, 0, &res); > > - if (ret) { > > - dev_err(dev, "Failed to get SCMI Tx shared memory\n"); > > - goto out; > > - } > > - > > - size = resource_size(&res); > > + channel->req.shmem = setup_shmem_iomap(cinfo, dev, true); > > + if (IS_ERR(channel->req.shmem)) > > + return PTR_ERR(channel->req.shmem); > > > > - channel->req.shmem = devm_ioremap(dev, res.start, size); > > - if (!channel->req.shmem) { > > - dev_err(dev, "Failed to ioremap SCMI Tx shared memory\n"); > > - ret = -EADDRNOTAVAIL; > > - goto out; > > - } > > - > > - ret = 0; > > - > > -out: > > - of_node_put(np); > > - > > - return ret; > > + return 0; > > } > > > > static int setup_shmem(struct device *dev, struct scmi_chan_info *cinfo, > > diff --git a/drivers/firmware/arm_scmi/shmem.c b/drivers/firmware/arm_scmi/shmem.c > > index b74e5a740f2c..c31f188d74ef 100644 > > --- a/drivers/firmware/arm_scmi/shmem.c > > +++ b/drivers/firmware/arm_scmi/shmem.c > > @@ -7,6 +7,8 @@ > > > > #include <linux/ktime.h> > > #include <linux/io.h> > > +#include <linux/of.h> > > +#include <linux/of_address.h> > > #include <linux/processor.h> > > #include <linux/types.h> > > > > @@ -133,3 +135,37 @@ bool shmem_channel_intr_enabled(struct scmi_shared_mem __iomem *shmem) > > { > > return ioread32(&shmem->flags) & SCMI_SHMEM_FLAG_INTR_ENABLED; > > } > > + > > +void *__iomem > > +setup_shmem_iomap(struct scmi_chan_info *cinfo, struct device *dev, bool tx) > > +{ > > + const char *desc = tx ? "Tx" : "Rx"; > > + int ret, idx = tx ? 0 : 1; > > + struct device *cdev = cinfo->dev; > > + struct device_node *shmem; > > + resource_size_t size; > > + struct resource res; > > + void __iomem *addr; > > + > > + shmem = of_parse_phandle(cdev->of_node, "shmem", idx); > > + if (!of_device_is_compatible(shmem, "arm,scmi-shmem")) { > > + of_node_put(shmem); > > + return ERR_PTR(-ENXIO); > > + } > > + > > + ret = of_address_to_resource(shmem, 0, &res); > > + of_node_put(shmem); > > + if (ret) { > > + dev_err(cdev, "failed to get SCMI %s shared memory\n", desc); > > + return ERR_PTR(ret); > > + } > > + > > + size = resource_size(&res); > > + addr = devm_ioremap(dev, res.start, size); > > + if (!addr) { > > + dev_err(dev, "failed to ioremap SCMI %s shared memory\n", desc); > > + return ERR_PTR(-EADDRNOTAVAIL); > > + } > > + > > + return addr; > > +} > > diff --git a/drivers/firmware/arm_scmi/smc.c b/drivers/firmware/arm_scmi/smc.c > > index 39936e1dd30e..a640a4312472 100644 > > --- a/drivers/firmware/arm_scmi/smc.c > > +++ b/drivers/firmware/arm_scmi/smc.c > > @@ -132,7 +132,6 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, > > struct scmi_smc *scmi_info; > > resource_size_t size; > > struct resource res; > > - struct device_node *np; > > u32 func_id; > > int ret; > > > > @@ -143,25 +142,9 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, > > if (!scmi_info) > > return -ENOMEM; > > > > - np = of_parse_phandle(cdev->of_node, "shmem", 0); > > - if (!of_device_is_compatible(np, "arm,scmi-shmem")) { > > - of_node_put(np); > > - return -ENXIO; > > - } > > - > > - ret = of_address_to_resource(np, 0, &res); > > - of_node_put(np); > > - if (ret) { > > - dev_err(cdev, "failed to get SCMI Tx shared memory\n"); > > - return ret; > > - } > > - > > - size = resource_size(&res); > > Hi Peng/Cristian, > > This will break Qualcomm smc transport as we need shmem 'size' to get to > the cap-id. > ...ops..sorry....that's on me I quickly extended Peng patch to address also SMC and missed this...I'l review... Thanks for havig a look ! Cristian
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h index 4b8c5250cdb5..b4c217641e3a 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -327,6 +327,8 @@ bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem, struct scmi_xfer *xfer); bool shmem_channel_free(struct scmi_shared_mem __iomem *shmem); bool shmem_channel_intr_enabled(struct scmi_shared_mem __iomem *shmem); +void __iomem *setup_shmem_iomap(struct scmi_chan_info *cinfo, struct device *dev, + bool tx); /* declarations for message passing transports */ struct scmi_msg_payld; diff --git a/drivers/firmware/arm_scmi/mailbox.c b/drivers/firmware/arm_scmi/mailbox.c index 0219a12e3209..b0a579f31905 100644 --- a/drivers/firmware/arm_scmi/mailbox.c +++ b/drivers/firmware/arm_scmi/mailbox.c @@ -178,11 +178,8 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, const char *desc = tx ? "Tx" : "Rx"; struct device *cdev = cinfo->dev; struct scmi_mailbox *smbox; - struct device_node *shmem; - int ret, a2p_rx_chan, p2a_chan, p2a_rx_chan, idx = tx ? 0 : 1; + int ret, a2p_rx_chan, p2a_chan, p2a_rx_chan; struct mbox_client *cl; - resource_size_t size; - struct resource res; ret = mailbox_chan_validate(cdev, &a2p_rx_chan, &p2a_chan, &p2a_rx_chan); if (ret) @@ -195,25 +192,9 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, if (!smbox) return -ENOMEM; - shmem = of_parse_phandle(cdev->of_node, "shmem", idx); - if (!of_device_is_compatible(shmem, "arm,scmi-shmem")) { - of_node_put(shmem); - return -ENXIO; - } - - ret = of_address_to_resource(shmem, 0, &res); - of_node_put(shmem); - if (ret) { - dev_err(cdev, "failed to get SCMI %s shared memory\n", desc); - return ret; - } - - size = resource_size(&res); - smbox->shmem = devm_ioremap(dev, res.start, size); - if (!smbox->shmem) { - dev_err(dev, "failed to ioremap SCMI %s shared memory\n", desc); - return -EADDRNOTAVAIL; - } + smbox->shmem = setup_shmem_iomap(cinfo, dev, tx); + if (IS_ERR(smbox->shmem)) + return PTR_ERR(smbox->shmem); cl = &smbox->cl; cl->dev = cdev; diff --git a/drivers/firmware/arm_scmi/optee.c b/drivers/firmware/arm_scmi/optee.c index 4e7944b91e38..8abcd668108c 100644 --- a/drivers/firmware/arm_scmi/optee.c +++ b/drivers/firmware/arm_scmi/optee.c @@ -368,38 +368,11 @@ static int setup_dynamic_shmem(struct device *dev, struct scmi_optee_channel *ch static int setup_static_shmem(struct device *dev, struct scmi_chan_info *cinfo, struct scmi_optee_channel *channel) { - struct device_node *np; - resource_size_t size; - struct resource res; - int ret; - - np = of_parse_phandle(cinfo->dev->of_node, "shmem", 0); - if (!of_device_is_compatible(np, "arm,scmi-shmem")) { - ret = -ENXIO; - goto out; - } - - ret = of_address_to_resource(np, 0, &res); - if (ret) { - dev_err(dev, "Failed to get SCMI Tx shared memory\n"); - goto out; - } - - size = resource_size(&res); + channel->req.shmem = setup_shmem_iomap(cinfo, dev, true); + if (IS_ERR(channel->req.shmem)) + return PTR_ERR(channel->req.shmem); - channel->req.shmem = devm_ioremap(dev, res.start, size); - if (!channel->req.shmem) { - dev_err(dev, "Failed to ioremap SCMI Tx shared memory\n"); - ret = -EADDRNOTAVAIL; - goto out; - } - - ret = 0; - -out: - of_node_put(np); - - return ret; + return 0; } static int setup_shmem(struct device *dev, struct scmi_chan_info *cinfo, diff --git a/drivers/firmware/arm_scmi/shmem.c b/drivers/firmware/arm_scmi/shmem.c index b74e5a740f2c..c31f188d74ef 100644 --- a/drivers/firmware/arm_scmi/shmem.c +++ b/drivers/firmware/arm_scmi/shmem.c @@ -7,6 +7,8 @@ #include <linux/ktime.h> #include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> #include <linux/processor.h> #include <linux/types.h> @@ -133,3 +135,37 @@ bool shmem_channel_intr_enabled(struct scmi_shared_mem __iomem *shmem) { return ioread32(&shmem->flags) & SCMI_SHMEM_FLAG_INTR_ENABLED; } + +void *__iomem +setup_shmem_iomap(struct scmi_chan_info *cinfo, struct device *dev, bool tx) +{ + const char *desc = tx ? "Tx" : "Rx"; + int ret, idx = tx ? 0 : 1; + struct device *cdev = cinfo->dev; + struct device_node *shmem; + resource_size_t size; + struct resource res; + void __iomem *addr; + + shmem = of_parse_phandle(cdev->of_node, "shmem", idx); + if (!of_device_is_compatible(shmem, "arm,scmi-shmem")) { + of_node_put(shmem); + return ERR_PTR(-ENXIO); + } + + ret = of_address_to_resource(shmem, 0, &res); + of_node_put(shmem); + if (ret) { + dev_err(cdev, "failed to get SCMI %s shared memory\n", desc); + return ERR_PTR(ret); + } + + size = resource_size(&res); + addr = devm_ioremap(dev, res.start, size); + if (!addr) { + dev_err(dev, "failed to ioremap SCMI %s shared memory\n", desc); + return ERR_PTR(-EADDRNOTAVAIL); + } + + return addr; +} diff --git a/drivers/firmware/arm_scmi/smc.c b/drivers/firmware/arm_scmi/smc.c index 39936e1dd30e..a640a4312472 100644 --- a/drivers/firmware/arm_scmi/smc.c +++ b/drivers/firmware/arm_scmi/smc.c @@ -132,7 +132,6 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, struct scmi_smc *scmi_info; resource_size_t size; struct resource res; - struct device_node *np; u32 func_id; int ret; @@ -143,25 +142,9 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, if (!scmi_info) return -ENOMEM; - np = of_parse_phandle(cdev->of_node, "shmem", 0); - if (!of_device_is_compatible(np, "arm,scmi-shmem")) { - of_node_put(np); - return -ENXIO; - } - - ret = of_address_to_resource(np, 0, &res); - of_node_put(np); - if (ret) { - dev_err(cdev, "failed to get SCMI Tx shared memory\n"); - return ret; - } - - size = resource_size(&res); - scmi_info->shmem = devm_ioremap(dev, res.start, size); - if (!scmi_info->shmem) { - dev_err(dev, "failed to ioremap SCMI Tx shared memory\n"); - return -EADDRNOTAVAIL; - } + scmi_info->shmem = setup_shmem_iomap(cinfo, dev, tx); + if (IS_ERR(scmi_info->shmem)) + return PTR_ERR(scmi_info->shmem); ret = of_property_read_u32(dev->of_node, "arm,smc-id", &func_id); if (ret < 0)