[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251125063842.v742i2rg7krcpd57@hu-mojha-hyd.qualcomm.com>
Date: Tue, 25 Nov 2025 12:08:42 +0530
From: Mukesh Ojha <mukesh.ojha@....qualcomm.com>
To: Shivendra Pratap <shivendra.pratap@....qualcomm.com>
Cc: Bjorn Andersson <andersson@...nel.org>,
Konrad Dybcio <konradybcio@...nel.org>, linux-arm-msm@...r.kernel.org,
linux-kernel@...r.kernel.org,
Unnathi Chalicheemala <unnathi.chalicheemala@....qualcomm.com>,
Bartosz Golaszewski <bartosz.golaszewski@...aro.org>
Subject: Re: [PATCH v9 1/3] firmware: qcom_scm: Add API to get waitqueue IRQ
info
On Sun, Nov 23, 2025 at 07:49:30PM +0530, Shivendra Pratap wrote:
> From: Unnathi Chalicheemala <unnathi.chalicheemala@....qualcomm.com>
>
> Bootloader and firmware for SM8650 and older chipsets expect node
> name as "qcom_scm", in order to patch the wait queue IRQ information.
> However, DeviceTree uses node name "scm" and this mismatch prevents
> firmware from correctly identifying waitqueue IRQ information. Waitqueue
> IRQ is used for signaling between secure and non-secure worlds.
>
> To resolve this, introduce qcom_scm_get_waitq_irq() that'll get the
> hardware IRQ number to be used from firmware instead of relying on data
> provided by devicetree, thereby bypassing the DeviceTree node name
> mismatch.
>
> This hardware IRQ number is converted to a Linux IRQ number using newly
> defined fill_irq_fwspec_params(). This Linux IRQ number is then supplied
nit: qcom_scm_fill_irq_fwspec_params() ?
> to the threaded_irq call.
>
> Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@...aro.org>
> Signed-off-by: Unnathi Chalicheemala <unnathi.chalicheemala@....qualcomm.com>
> Signed-off-by: Shivendra Pratap <shivendra.pratap@....qualcomm.com>
> ---
> drivers/firmware/qcom/qcom_scm.c | 62 +++++++++++++++++++++++++++++++++++++++-
> drivers/firmware/qcom/qcom_scm.h | 1 +
> 2 files changed, 62 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> index e777b7cb9b127944fe112f453cae9cbc40c06cae..28979f95e51fbee94b84c1570a4d88a76f72db4e 100644
> --- a/drivers/firmware/qcom/qcom_scm.c
> +++ b/drivers/firmware/qcom/qcom_scm.c
> @@ -29,12 +29,18 @@
> #include <linux/reset-controller.h>
> #include <linux/sizes.h>
> #include <linux/types.h>
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
>
> #include "qcom_scm.h"
> #include "qcom_tzmem.h"
>
> static u32 download_mode;
>
> +#define GIC_SPI_BASE 32
> +#define GIC_MAX_SPI 1019 // SPIs in GICv3 spec range from 32..1019
> +#define GIC_ESPI_BASE 4096
> +#define GIC_MAX_ESPI 5119 // ESPIs in GICv3 spec range from 4096..5119
> +
> struct qcom_scm {
> struct device *dev;
> struct clk *core_clk;
> @@ -2223,6 +2229,57 @@ bool qcom_scm_is_available(void)
> }
> EXPORT_SYMBOL_GPL(qcom_scm_is_available);
>
> +static int qcom_scm_fill_irq_fwspec_params(struct irq_fwspec *fwspec, u32 virq)
nit: s/virq/hwirq ?
> +{
> + if (virq >= GIC_SPI_BASE && virq <= GIC_MAX_SPI) {
> + fwspec->param[0] = GIC_SPI;
> + fwspec->param[1] = virq - GIC_SPI_BASE;
> + } else if (virq >= GIC_ESPI_BASE && virq <= GIC_MAX_ESPI) {
> + fwspec->param[0] = GIC_ESPI;
> + fwspec->param[1] = virq - GIC_ESPI_BASE;
> + } else {
> + WARN(1, "Unexpected virq: %d\n", virq);
> + return -ENXIO;
> + }
> + fwspec->param[2] = IRQ_TYPE_EDGE_RISING;
> + fwspec->param_count = 3;
> +
> + return 0;
> +}
> +
> +static int qcom_scm_get_waitq_irq(struct qcom_scm *scm)
> +{
> + int ret;
> + u32 hwirq;
> + struct qcom_scm_desc desc = {
> + .svc = QCOM_SCM_SVC_WAITQ,
> + .cmd = QCOM_SCM_WAITQ_GET_INFO,
> + .owner = ARM_SMCCC_OWNER_SIP
> + };
> + struct qcom_scm_res res;
> + struct irq_fwspec fwspec;
> + struct device_node *parent_irq_node;
Since, this is newly introduce function.
please follow reverse xmas tree..
> +
> + ret = qcom_scm_call_atomic(scm->dev, &desc, &res);
> + if (ret)
> + return ret;
> +
> + hwirq = res.result[1] & GENMASK(15, 0);
> +
> + ret = qcom_scm_fill_irq_fwspec_params(&fwspec, hwirq);
> + if (ret)
> + return ret;
> + parent_irq_node = of_irq_find_parent(scm->dev->of_node);
> + if (!parent_irq_node)
> + return -ENODEV;
> +
> + fwspec.fwnode = of_fwnode_handle(parent_irq_node);
> +
> + ret = irq_create_fwspec_mapping(&fwspec);
> +
> + return ret;
return irq_create_fwspec_mapping(&fwspec);
> +}
> +
> static int qcom_scm_assert_valid_wq_ctx(u32 wq_ctx)
> {
> /* FW currently only supports a single wq_ctx (zero).
> @@ -2396,7 +2453,10 @@ static int qcom_scm_probe(struct platform_device *pdev)
> return dev_err_probe(scm->dev, PTR_ERR(scm->mempool),
> "Failed to create the SCM memory pool\n");
>
> - irq = platform_get_irq_optional(pdev, 0);
> + irq = qcom_scm_get_waitq_irq(scm);
> + if (irq < 0)
> + irq = platform_get_irq_optional(pdev, 0);
> +
> if (irq < 0) {
> if (irq != -ENXIO)
> return irq;
> diff --git a/drivers/firmware/qcom/qcom_scm.h b/drivers/firmware/qcom/qcom_scm.h
> index a56c8212cc0c41021e5a067d52b7d5dcc49107ea..8b1e2ea18a59ac143907a381b73236148bace189 100644
> --- a/drivers/firmware/qcom/qcom_scm.h
> +++ b/drivers/firmware/qcom/qcom_scm.h
> @@ -152,6 +152,7 @@ int qcom_scm_shm_bridge_enable(struct device *scm_dev);
> #define QCOM_SCM_SVC_WAITQ 0x24
> #define QCOM_SCM_WAITQ_RESUME 0x02
> #define QCOM_SCM_WAITQ_GET_WQ_CTX 0x03
> +#define QCOM_SCM_WAITQ_GET_INFO 0x04
>
> #define QCOM_SCM_SVC_GPU 0x28
> #define QCOM_SCM_SVC_GPU_INIT_REGS 0x01
>
> --
> 2.34.1
>
--
-Mukesh Ojha
Powered by blists - more mailing lists