From: peng.fan@nxp.com To: sudeep.holla@arm.com, robh+dt@kernel.org Cc: viresh.kumar@linaro.org, f.fainelli@gmail.com, linux-imx@nxp.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Peng Fan <peng.fan@nxp.com> Subject: [PATCH V5 2/2] firmware: arm_scmi: add smc/hvc transport Date: Sun, 8 Mar 2020 21:24:39 +0800 [thread overview] Message-ID: <1583673879-20714-3-git-send-email-peng.fan@nxp.com> (raw) In-Reply-To: <1583673879-20714-1-git-send-email-peng.fan@nxp.com> From: Peng Fan <peng.fan@nxp.com> Take arm,smc-id as the 1st arg, leave the other args as zero for now. There is no Rx, only Tx because of smc/hvc not support Rx. Signed-off-by: Peng Fan <peng.fan@nxp.com> --- drivers/firmware/arm_scmi/Makefile | 2 +- drivers/firmware/arm_scmi/common.h | 1 + drivers/firmware/arm_scmi/driver.c | 1 + drivers/firmware/arm_scmi/smc.c | 152 +++++++++++++++++++++++++++++++++++++ 4 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 drivers/firmware/arm_scmi/smc.c diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi/Makefile index 6694d0d908d6..6b1b0d6c6d0e 100644 --- a/drivers/firmware/arm_scmi/Makefile +++ b/drivers/firmware/arm_scmi/Makefile @@ -2,6 +2,6 @@ obj-y = scmi-bus.o scmi-driver.o scmi-protocols.o scmi-transport.o scmi-bus-y = bus.o scmi-driver-y = driver.o -scmi-transport-y = mailbox.o shmem.o +scmi-transport-y = mailbox.o shmem.o smc.o scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o obj-$(CONFIG_ARM_SCMI_POWER_DOMAIN) += scmi_pm_domain.o diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h index 5ac06469b01c..94fc2b2df940 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -210,6 +210,7 @@ struct scmi_desc { }; extern const struct scmi_desc scmi_mailbox_desc; +extern const struct scmi_desc scmi_smc_desc; void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr); void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id); diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index dbec767222e9..e76a3fab1074 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -827,6 +827,7 @@ ATTRIBUTE_GROUPS(versions); /* Each compatible listed below must have descriptor associated with it */ static const struct of_device_id scmi_of_match[] = { { .compatible = "arm,scmi", .data = &scmi_mailbox_desc }, + { .compatible = "arm,scmi-smc", .data = &scmi_smc_desc}, { /* Sentinel */ }, }; diff --git a/drivers/firmware/arm_scmi/smc.c b/drivers/firmware/arm_scmi/smc.c new file mode 100644 index 000000000000..336168e40f49 --- /dev/null +++ b/drivers/firmware/arm_scmi/smc.c @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * System Control and Management Interface (SCMI) Message SMC/HVC + * Transport driver + * + * Copyright 2020 NXP + */ + +#include <linux/arm-smccc.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/mutex.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/slab.h> + +#include "common.h" + +/** + * struct scmi_smc - Structure representing a SCMI smc transport + * + * @cinfo: SCMI channel info + * @shmem: Transmit/Receive shared memory area + * @func_id: smc/hvc call function id + */ + +struct scmi_smc { + struct scmi_chan_info *cinfo; + struct scmi_shared_mem __iomem *shmem; + u32 func_id; +}; + +static DEFINE_MUTEX(smc_mutex); + +static bool smc_chan_available(struct device *dev, int idx) +{ + return true; +} + +static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, + bool tx) +{ + struct device *cdev = cinfo->dev; + struct scmi_smc *scmi_info; + resource_size_t size; + struct resource res; + struct device_node *np; + u32 func_id; + int ret; + + if (!tx) + return -ENODEV; + + scmi_info = devm_kzalloc(dev, sizeof(*scmi_info), GFP_KERNEL); + if (!scmi_info) + return -ENOMEM; + + np = of_parse_phandle(cdev->of_node, "shmem", 0); + if (!np) + np = of_parse_phandle(dev->of_node, "shmem", 0); + 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; + } + + ret = of_property_read_u32(dev->of_node, "arm,smc-id", &func_id); + if (ret < 0) + return ret; + + scmi_info->func_id = func_id; + scmi_info->cinfo = cinfo; + cinfo->transport_info = scmi_info; + + return 0; +} + +static int smc_chan_free(int id, void *p, void *data) +{ + struct scmi_chan_info *cinfo = p; + struct scmi_smc *scmi_info = cinfo->transport_info; + + cinfo->transport_info = NULL; + scmi_info->cinfo = NULL; + + scmi_free_channel(cinfo, data, id); + + return 0; +} + +static int smc_send_message(struct scmi_chan_info *cinfo, + struct scmi_xfer *xfer) +{ + struct scmi_smc *scmi_info = cinfo->transport_info; + struct arm_smccc_res res; + + mutex_lock(&smc_mutex); + + shmem_tx_prepare(scmi_info->shmem, xfer); + + arm_smccc_1_1_invoke(scmi_info->func_id, 0, 0, 0, 0, 0, 0, 0, &res); + scmi_rx_callback(scmi_info->cinfo, shmem_read_header(scmi_info->shmem)); + + mutex_unlock(&smc_mutex); + + return res.a0; +} + +static void smc_mark_txdone(struct scmi_chan_info *cinfo, int ret) +{ +} + +static void smc_fetch_response(struct scmi_chan_info *cinfo, + struct scmi_xfer *xfer) +{ + struct scmi_smc *scmi_info = cinfo->transport_info; + + shmem_fetch_response(scmi_info->shmem, xfer); +} + +static bool +smc_poll_done(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer) +{ + struct scmi_smc *scmi_info = cinfo->transport_info; + + return shmem_poll_done(scmi_info->shmem, xfer); +} + +static struct scmi_transport_ops scmi_smc_ops = { + .chan_available = smc_chan_available, + .chan_setup = smc_chan_setup, + .chan_free = smc_chan_free, + .send_message = smc_send_message, + .mark_txdone = smc_mark_txdone, + .fetch_response = smc_fetch_response, + .poll_done = smc_poll_done, +}; + +const struct scmi_desc scmi_smc_desc = { + .ops = &scmi_smc_ops, + .max_rx_timeout_ms = 30, + .max_msg = 1, + .max_msg_size = 128, +}; -- 2.16.4
WARNING: multiple messages have this Message-ID (diff)
From: peng.fan@nxp.com To: sudeep.holla@arm.com, robh+dt@kernel.org Cc: devicetree@vger.kernel.org, Peng Fan <peng.fan@nxp.com>, f.fainelli@gmail.com, viresh.kumar@linaro.org, linux-kernel@vger.kernel.org, linux-imx@nxp.com, linux-arm-kernel@lists.infradead.org Subject: [PATCH V5 2/2] firmware: arm_scmi: add smc/hvc transport Date: Sun, 8 Mar 2020 21:24:39 +0800 [thread overview] Message-ID: <1583673879-20714-3-git-send-email-peng.fan@nxp.com> (raw) In-Reply-To: <1583673879-20714-1-git-send-email-peng.fan@nxp.com> From: Peng Fan <peng.fan@nxp.com> Take arm,smc-id as the 1st arg, leave the other args as zero for now. There is no Rx, only Tx because of smc/hvc not support Rx. Signed-off-by: Peng Fan <peng.fan@nxp.com> --- drivers/firmware/arm_scmi/Makefile | 2 +- drivers/firmware/arm_scmi/common.h | 1 + drivers/firmware/arm_scmi/driver.c | 1 + drivers/firmware/arm_scmi/smc.c | 152 +++++++++++++++++++++++++++++++++++++ 4 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 drivers/firmware/arm_scmi/smc.c diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi/Makefile index 6694d0d908d6..6b1b0d6c6d0e 100644 --- a/drivers/firmware/arm_scmi/Makefile +++ b/drivers/firmware/arm_scmi/Makefile @@ -2,6 +2,6 @@ obj-y = scmi-bus.o scmi-driver.o scmi-protocols.o scmi-transport.o scmi-bus-y = bus.o scmi-driver-y = driver.o -scmi-transport-y = mailbox.o shmem.o +scmi-transport-y = mailbox.o shmem.o smc.o scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o obj-$(CONFIG_ARM_SCMI_POWER_DOMAIN) += scmi_pm_domain.o diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h index 5ac06469b01c..94fc2b2df940 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -210,6 +210,7 @@ struct scmi_desc { }; extern const struct scmi_desc scmi_mailbox_desc; +extern const struct scmi_desc scmi_smc_desc; void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr); void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id); diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index dbec767222e9..e76a3fab1074 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -827,6 +827,7 @@ ATTRIBUTE_GROUPS(versions); /* Each compatible listed below must have descriptor associated with it */ static const struct of_device_id scmi_of_match[] = { { .compatible = "arm,scmi", .data = &scmi_mailbox_desc }, + { .compatible = "arm,scmi-smc", .data = &scmi_smc_desc}, { /* Sentinel */ }, }; diff --git a/drivers/firmware/arm_scmi/smc.c b/drivers/firmware/arm_scmi/smc.c new file mode 100644 index 000000000000..336168e40f49 --- /dev/null +++ b/drivers/firmware/arm_scmi/smc.c @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * System Control and Management Interface (SCMI) Message SMC/HVC + * Transport driver + * + * Copyright 2020 NXP + */ + +#include <linux/arm-smccc.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/mutex.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/slab.h> + +#include "common.h" + +/** + * struct scmi_smc - Structure representing a SCMI smc transport + * + * @cinfo: SCMI channel info + * @shmem: Transmit/Receive shared memory area + * @func_id: smc/hvc call function id + */ + +struct scmi_smc { + struct scmi_chan_info *cinfo; + struct scmi_shared_mem __iomem *shmem; + u32 func_id; +}; + +static DEFINE_MUTEX(smc_mutex); + +static bool smc_chan_available(struct device *dev, int idx) +{ + return true; +} + +static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, + bool tx) +{ + struct device *cdev = cinfo->dev; + struct scmi_smc *scmi_info; + resource_size_t size; + struct resource res; + struct device_node *np; + u32 func_id; + int ret; + + if (!tx) + return -ENODEV; + + scmi_info = devm_kzalloc(dev, sizeof(*scmi_info), GFP_KERNEL); + if (!scmi_info) + return -ENOMEM; + + np = of_parse_phandle(cdev->of_node, "shmem", 0); + if (!np) + np = of_parse_phandle(dev->of_node, "shmem", 0); + 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; + } + + ret = of_property_read_u32(dev->of_node, "arm,smc-id", &func_id); + if (ret < 0) + return ret; + + scmi_info->func_id = func_id; + scmi_info->cinfo = cinfo; + cinfo->transport_info = scmi_info; + + return 0; +} + +static int smc_chan_free(int id, void *p, void *data) +{ + struct scmi_chan_info *cinfo = p; + struct scmi_smc *scmi_info = cinfo->transport_info; + + cinfo->transport_info = NULL; + scmi_info->cinfo = NULL; + + scmi_free_channel(cinfo, data, id); + + return 0; +} + +static int smc_send_message(struct scmi_chan_info *cinfo, + struct scmi_xfer *xfer) +{ + struct scmi_smc *scmi_info = cinfo->transport_info; + struct arm_smccc_res res; + + mutex_lock(&smc_mutex); + + shmem_tx_prepare(scmi_info->shmem, xfer); + + arm_smccc_1_1_invoke(scmi_info->func_id, 0, 0, 0, 0, 0, 0, 0, &res); + scmi_rx_callback(scmi_info->cinfo, shmem_read_header(scmi_info->shmem)); + + mutex_unlock(&smc_mutex); + + return res.a0; +} + +static void smc_mark_txdone(struct scmi_chan_info *cinfo, int ret) +{ +} + +static void smc_fetch_response(struct scmi_chan_info *cinfo, + struct scmi_xfer *xfer) +{ + struct scmi_smc *scmi_info = cinfo->transport_info; + + shmem_fetch_response(scmi_info->shmem, xfer); +} + +static bool +smc_poll_done(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer) +{ + struct scmi_smc *scmi_info = cinfo->transport_info; + + return shmem_poll_done(scmi_info->shmem, xfer); +} + +static struct scmi_transport_ops scmi_smc_ops = { + .chan_available = smc_chan_available, + .chan_setup = smc_chan_setup, + .chan_free = smc_chan_free, + .send_message = smc_send_message, + .mark_txdone = smc_mark_txdone, + .fetch_response = smc_fetch_response, + .poll_done = smc_poll_done, +}; + +const struct scmi_desc scmi_smc_desc = { + .ops = &scmi_smc_ops, + .max_rx_timeout_ms = 30, + .max_msg = 1, + .max_msg_size = 128, +}; -- 2.16.4 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2020-03-08 13:31 UTC|newest] Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-03-08 13:24 [PATCH V5 0/2] firmware: arm_scmi: add smc/hvc transports support peng.fan 2020-03-08 13:24 ` peng.fan 2020-03-08 13:24 ` [PATCH V5 1/2] dt-bindings: arm: arm,scmi: add smc/hvc transport peng.fan 2020-03-08 13:24 ` peng.fan 2020-03-08 16:43 ` Florian Fainelli 2020-03-08 16:43 ` Florian Fainelli 2020-03-08 13:24 ` peng.fan [this message] 2020-03-08 13:24 ` [PATCH V5 2/2] firmware: arm_scmi: " peng.fan 2020-03-20 8:27 ` [PATCH V5 0/2] firmware: arm_scmi: add smc/hvc transports support Peng Fan 2020-03-20 8:27 ` Peng Fan 2020-03-20 8:37 ` Sudeep Holla 2020-03-20 8:37 ` Sudeep Holla 2020-03-20 8:40 ` Peng Fan 2020-03-20 8:40 ` Peng Fan 2020-03-27 16:32 ` Sudeep Holla 2020-03-27 16:32 ` Sudeep Holla 2020-03-30 14:05 ` Sudeep Holla 2020-03-30 14:05 ` Sudeep Holla 2020-04-15 10:58 ` [PATCH V5 2/2] firmware: arm_scmi: add smc/hvc transport Etienne Carriere 2020-04-15 10:58 ` Etienne Carriere 2020-04-15 13:16 ` Sudeep Holla 2020-04-15 13:16 ` Sudeep Holla 2020-04-15 14:15 ` Etienne Carriere 2020-04-15 14:15 ` Etienne Carriere
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1583673879-20714-3-git-send-email-peng.fan@nxp.com \ --to=peng.fan@nxp.com \ --cc=devicetree@vger.kernel.org \ --cc=f.fainelli@gmail.com \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-imx@nxp.com \ --cc=linux-kernel@vger.kernel.org \ --cc=robh+dt@kernel.org \ --cc=sudeep.holla@arm.com \ --cc=viresh.kumar@linaro.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.