* [PATCH v1 0/4] ASoC: qcom and pinctrl: add LPASS LPR voting and Hawi LPASS LPI TLMM
@ 2026-07-08 11:49 Prasad Kumpatla
2026-07-08 11:49 ` [PATCH v1 1/4] ASoC: dt-bindings: qcom: add LPASS LPR vote clock ID Prasad Kumpatla
` (3 more replies)
0 siblings, 4 replies; 10+ messages in thread
From: Prasad Kumpatla @ 2026-07-08 11:49 UTC (permalink / raw)
To: Bjorn Andersson, Bartosz Golaszewski, Linus Walleij, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Liam Girdwood, Mark Brown,
Srinivas Kandagatla, Jaroslav Kysela, Takashi Iwai,
Prasad Kumpatla
Cc: Krzysztof Kozlowski, Srinivas Kandagatla, linux-arm-msm,
linux-gpio, devicetree, linux-kernel, linux-sound
This series adds support for LPASS low-power resource (LPR) voting
through PRM and introduces LPASS LPI TLMM pinctrl support for newer
platforms such as Hawi.
On such platforms, LPASS requires LPR resource voting via PRM to keep
the subsystem active. This is handled by adding a new clock ID and
support for PARAM_ID_RSC_CPU_LPR in q6prm.
Additionally, a new LPASS LPI TLMM block is introduced, requiring a
dedicated DT binding and pinctrl driver.
Prasad Kumpatla (4):
dt-bindings: sound: qcom,q6prm: add LPASS LPR vote clock ID
ASoC: qcom: q6prm: add support for LPASS LPR resource voting
dt-bindings: pinctrl: qcom,hawi-lpass-lpi-pinctrl: Add Hawi LPI
pinctrl
pinctrl: qcom: hawi-lpass-lpi: add Hawi LPASS LPI TLMM
.../pinctrl/qcom,hawi-lpass-lpi-pinctrl.yaml | 109 ++++++++
drivers/pinctrl/qcom/Kconfig | 10 +
drivers/pinctrl/qcom/Makefile | 1 +
drivers/pinctrl/qcom/pinctrl-hawi-lpass-lpi.c | 244 ++++++++++++++++++
drivers/pinctrl/qcom/pinctrl-lpass-lpi.h | 17 ++
.../sound/qcom,q6dsp-lpass-ports.h | 3 +-
sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c | 2 +-
sound/soc/qcom/qdsp6/q6prm-clocks.c | 2 +
sound/soc/qcom/qdsp6/q6prm.c | 18 +-
sound/soc/qcom/qdsp6/q6prm.h | 1 +
10 files changed, 401 insertions(+), 6 deletions(-)
create mode 100644 Documentation/devicetree/bindings/pinctrl/qcom,hawi-lpass-lpi-pinctrl.yaml
create mode 100644 drivers/pinctrl/qcom/pinctrl-hawi-lpass-lpi.c
--
2.34.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v1 1/4] ASoC: dt-bindings: qcom: add LPASS LPR vote clock ID
2026-07-08 11:49 [PATCH v1 0/4] ASoC: qcom and pinctrl: add LPASS LPR voting and Hawi LPASS LPI TLMM Prasad Kumpatla
@ 2026-07-08 11:49 ` Prasad Kumpatla
2026-07-08 12:00 ` sashiko-bot
2026-07-09 8:20 ` Bartosz Golaszewski
2026-07-08 11:49 ` [PATCH v1 2/4] ASoC: qcom: q6prm: add support for LPASS LPR resource voting Prasad Kumpatla
` (2 subsequent siblings)
3 siblings, 2 replies; 10+ messages in thread
From: Prasad Kumpatla @ 2026-07-08 11:49 UTC (permalink / raw)
To: Bjorn Andersson, Bartosz Golaszewski, Linus Walleij, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Liam Girdwood, Mark Brown,
Srinivas Kandagatla, Jaroslav Kysela, Takashi Iwai,
Prasad Kumpatla
Cc: Krzysztof Kozlowski, Srinivas Kandagatla, linux-arm-msm,
linux-gpio, devicetree, linux-kernel, linux-sound
Add a new clock ID, LPASS_HW_LPR_VOTE, to represent the LPASS low-power
resource (LPR) vote through the PRM interface.
The LPASS PRM supports a resource voting mechanism to control low-power
states via PARAM_ID_RSC_CPU_LPR. Exposing this as a q6prm clock ID allows
clients to request the LPR vote using the existing qcom,q6prm clock
provider interface.
This functionality is required on newer platforms (e.g. Hawi) where LPASS
clients need to explicitly manage LPR resource voting via PRM.
Also update Q6AFE_MAX_CLK_ID to account for the newly added clock ID.
Signed-off-by: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
---
include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
index 45850f2d4..06ca2c287 100644
--- a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
+++ b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
@@ -236,8 +236,9 @@
#define LPASS_HW_AVTIMER_VOTE 101
#define LPASS_HW_MACRO_VOTE 102
#define LPASS_HW_DCODEC_VOTE 103
+#define LPASS_HW_LPR_VOTE 104
-#define Q6AFE_MAX_CLK_ID 104
+#define Q6AFE_MAX_CLK_ID 105
#define LPASS_CLK_ATTRIBUTE_INVALID 0x0
#define LPASS_CLK_ATTRIBUTE_COUPLE_NO 0x1
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v1 2/4] ASoC: qcom: q6prm: add support for LPASS LPR resource voting
2026-07-08 11:49 [PATCH v1 0/4] ASoC: qcom and pinctrl: add LPASS LPR voting and Hawi LPASS LPI TLMM Prasad Kumpatla
2026-07-08 11:49 ` [PATCH v1 1/4] ASoC: dt-bindings: qcom: add LPASS LPR vote clock ID Prasad Kumpatla
@ 2026-07-08 11:49 ` Prasad Kumpatla
2026-07-09 8:23 ` Bartosz Golaszewski
2026-07-08 11:49 ` [PATCH v1 3/4] dt-bindings: pinctrl: qcom,hawi-lpass-lpi-pinctrl: Add Hawi LPI pinctrl Prasad Kumpatla
2026-07-08 11:49 ` [PATCH v1 4/4] pinctrl: qcom: hawi-lpass-lpi: add Hawi LPASS LPI TLMM Prasad Kumpatla
3 siblings, 1 reply; 10+ messages in thread
From: Prasad Kumpatla @ 2026-07-08 11:49 UTC (permalink / raw)
To: Bjorn Andersson, Bartosz Golaszewski, Linus Walleij, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Liam Girdwood, Mark Brown,
Srinivas Kandagatla, Jaroslav Kysela, Takashi Iwai,
Prasad Kumpatla
Cc: Krzysztof Kozlowski, Srinivas Kandagatla, linux-arm-msm,
linux-gpio, devicetree, linux-kernel, linux-sound
Add support for issuing LPASS low-power resource (LPR) votes through
the PRM interface.
Some platforms (e.g. Hawi) require the LPASS to be kept active via LPR
resource voting instead of the existing hardware core vote mechanism.
Handle this by introducing support for PARAM_ID_RSC_CPU_LPR when the
LPR vote clock ID is requested.
For LPR requests, use the appropriate parameter ID and payload format
to disable CPU subsystem sleep, ensuring that the LPASS register space
remains accessible.
Also add the corresponding clock mapping for LPASS_HW_LPR_VOTE and make
the q6dsp clock ID range consistent with the dt-bindings by deriving
it from Q6AFE_MAX_CLK_ID.
Signed-off-by: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
---
sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c | 2 +-
sound/soc/qcom/qdsp6/q6prm-clocks.c | 2 ++
sound/soc/qcom/qdsp6/q6prm.c | 18 ++++++++++++++----
sound/soc/qcom/qdsp6/q6prm.h | 1 +
4 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c b/sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c
index 03838582a..79527a367 100644
--- a/sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c
+++ b/sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c
@@ -12,7 +12,7 @@
#include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h>
#include "q6dsp-lpass-clocks.h"
-#define Q6DSP_MAX_CLK_ID 104
+#define Q6DSP_MAX_CLK_ID Q6AFE_MAX_CLK_ID
#define Q6DSP_LPASS_CLK_ROOT_DEFAULT 0
diff --git a/sound/soc/qcom/qdsp6/q6prm-clocks.c b/sound/soc/qcom/qdsp6/q6prm-clocks.c
index 4c574b48a..2b2b3872e 100644
--- a/sound/soc/qcom/qdsp6/q6prm-clocks.c
+++ b/sound/soc/qcom/qdsp6/q6prm-clocks.c
@@ -63,6 +63,8 @@ static const struct q6dsp_clk_init q6prm_clks[] = {
"LPASS_HW_MACRO"),
Q6DSP_VOTE_CLK(LPASS_HW_DCODEC_VOTE, Q6PRM_HW_CORE_ID_DCODEC,
"LPASS_HW_DCODEC"),
+ Q6DSP_VOTE_CLK(LPASS_HW_LPR_VOTE, Q6PRM_HW_LPR_VOTE,
+ "LPASS_HW_LPR_VOTE"),
};
static const struct q6dsp_clk_desc q6dsp_clk_q6prm __maybe_unused = {
diff --git a/sound/soc/qcom/qdsp6/q6prm.c b/sound/soc/qcom/qdsp6/q6prm.c
index 04892fb44..22ace8bcb 100644
--- a/sound/soc/qcom/qdsp6/q6prm.c
+++ b/sound/soc/qcom/qdsp6/q6prm.c
@@ -31,10 +31,16 @@ struct q6prm {
#define PARAM_ID_RSC_HW_CORE 0x08001032
#define PARAM_ID_RSC_LPASS_CORE 0x0800102B
#define PARAM_ID_RSC_AUDIO_HW_CLK 0x0800102C
+#define PARAM_ID_RSC_CPU_LPR 0x08001A6E
+
+#define LPR_CPU_SS_SLEEP_DISABLED 0x1
struct prm_cmd_request_hw_core {
struct apm_module_param_data param_data;
- uint32_t hw_clk_id;
+ union {
+ u32 hw_clk_id;
+ u32 lpr_state;
+ };
} __packed;
struct prm_cmd_request_rsc {
@@ -62,6 +68,7 @@ static int q6prm_set_hw_core_req(struct device *dev, uint32_t hw_block_id, bool
struct prm_cmd_request_hw_core *req;
gpr_device_t *gdev = prm->gdev;
uint32_t opcode, rsp_opcode;
+ bool lpr_req = hw_block_id == Q6PRM_HW_LPR_VOTE;
if (enable) {
opcode = PRM_CMD_REQUEST_HW_RSC;
@@ -82,10 +89,13 @@ static int q6prm_set_hw_core_req(struct device *dev, uint32_t hw_block_id, bool
param_data->module_instance_id = GPR_PRM_MODULE_IID;
param_data->error_code = 0;
- param_data->param_id = PARAM_ID_RSC_HW_CORE;
+ param_data->param_id = lpr_req ? PARAM_ID_RSC_CPU_LPR : PARAM_ID_RSC_HW_CORE;
param_data->param_size = sizeof(*req) - APM_MODULE_PARAM_DATA_SIZE;
- req->hw_clk_id = hw_block_id;
+ if (lpr_req)
+ req->lpr_state = LPR_CPU_SS_SLEEP_DISABLED;
+ else
+ req->hw_clk_id = hw_block_id;
return q6prm_send_cmd_sync(prm, pkt, rsp_opcode);
}
@@ -94,7 +104,6 @@ int q6prm_vote_lpass_core_hw(struct device *dev, uint32_t hw_block_id,
const char *client_name, uint32_t *client_handle)
{
return q6prm_set_hw_core_req(dev, hw_block_id, true);
-
}
EXPORT_SYMBOL_GPL(q6prm_vote_lpass_core_hw);
@@ -210,6 +219,7 @@ static int prm_probe(gpr_device_t *gdev)
cc->gdev = gdev;
mutex_init(&cc->lock);
init_waitqueue_head(&cc->wait);
+
dev_set_drvdata(dev, cc);
if (!q6apm_is_adsp_ready())
diff --git a/sound/soc/qcom/qdsp6/q6prm.h b/sound/soc/qcom/qdsp6/q6prm.h
index a988a3208..bd5ee0c40 100644
--- a/sound/soc/qcom/qdsp6/q6prm.h
+++ b/sound/soc/qcom/qdsp6/q6prm.h
@@ -87,6 +87,7 @@
#define Q6PRM_LPASS_CLK_ROOT_DEFAULT 0
#define Q6PRM_HW_CORE_ID_LPASS 1
#define Q6PRM_HW_CORE_ID_DCODEC 2
+#define Q6PRM_HW_LPR_VOTE 3
int q6prm_set_lpass_clock(struct device *dev, int clk_id, int clk_attr,
int clk_root, unsigned int freq);
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v1 3/4] dt-bindings: pinctrl: qcom,hawi-lpass-lpi-pinctrl: Add Hawi LPI pinctrl
2026-07-08 11:49 [PATCH v1 0/4] ASoC: qcom and pinctrl: add LPASS LPR voting and Hawi LPASS LPI TLMM Prasad Kumpatla
2026-07-08 11:49 ` [PATCH v1 1/4] ASoC: dt-bindings: qcom: add LPASS LPR vote clock ID Prasad Kumpatla
2026-07-08 11:49 ` [PATCH v1 2/4] ASoC: qcom: q6prm: add support for LPASS LPR resource voting Prasad Kumpatla
@ 2026-07-08 11:49 ` Prasad Kumpatla
2026-07-08 11:49 ` [PATCH v1 4/4] pinctrl: qcom: hawi-lpass-lpi: add Hawi LPASS LPI TLMM Prasad Kumpatla
3 siblings, 0 replies; 10+ messages in thread
From: Prasad Kumpatla @ 2026-07-08 11:49 UTC (permalink / raw)
To: Bjorn Andersson, Bartosz Golaszewski, Linus Walleij, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Liam Girdwood, Mark Brown,
Srinivas Kandagatla, Jaroslav Kysela, Takashi Iwai,
Prasad Kumpatla
Cc: Krzysztof Kozlowski, Srinivas Kandagatla, linux-arm-msm,
linux-gpio, devicetree, linux-kernel, linux-sound
Add bindings for the pin controller in Low Power Audio SubSystem (LPASS)
of Qualcomm Hawi SoC.
The controller has 23 GPIOs (gpio0-gpio22) with functions including
SoundWire, I2S, DMIC, VA I2S, ext_mclk1, slimbus and lpass_lpi_dbg_clk.
Signed-off-by: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
---
.../pinctrl/qcom,hawi-lpass-lpi-pinctrl.yaml | 109 ++++++++++++++++++
1 file changed, 109 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pinctrl/qcom,hawi-lpass-lpi-pinctrl.yaml
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,hawi-lpass-lpi-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,hawi-lpass-lpi-pinctrl.yaml
new file mode 100644
index 000000000..af6858175
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,hawi-lpass-lpi-pinctrl.yaml
@@ -0,0 +1,109 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/qcom,hawi-lpass-lpi-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Hawi SoC LPASS LPI TLMM
+
+maintainers:
+ - Krzysztof Kozlowski <krzk@kernel.org>
+ - Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
+ - Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
+
+description:
+ Top Level Mode Multiplexer pin controller in the Low Power Audio SubSystem
+ (LPASS) Low Power Island (LPI) of Qualcomm Hawi SoC.
+
+properties:
+ compatible:
+ const: qcom,hawi-lpass-lpi-pinctrl
+
+ reg:
+ items:
+ - description: LPASS LPI TLMM Control and Status registers
+
+ clocks:
+ items:
+ - description: LPASS LPR(Low Power Resource) voting clock
+ - description: LPASS Audio voting clock
+
+ clock-names:
+ items:
+ - const: lpr
+ - const: audio
+
+patternProperties:
+ "-state$":
+ oneOf:
+ - $ref: "#/$defs/qcom-hawi-lpass-state"
+ - patternProperties:
+ "-pins$":
+ $ref: "#/$defs/qcom-hawi-lpass-state"
+ additionalProperties: false
+
+$defs:
+ qcom-hawi-lpass-state:
+ type: object
+ description:
+ Pinctrl node's client devices use subnodes for desired pin configuration.
+ Client device subnodes use below standard properties.
+ $ref: qcom,lpass-lpi-common.yaml#/$defs/qcom-tlmm-state
+ unevaluatedProperties: false
+
+ properties:
+ pins:
+ description:
+ List of gpio pins affected by the properties specified in this
+ subnode.
+ items:
+ pattern: "^gpio([0-9]|1[0-9]|2[0-2])$"
+
+ function:
+ enum: [dmic1_clk, dmic1_data, dmic2_clk, dmic2_data, dmic3_clk,
+ dmic3_data, dmic4_clk, dmic4_data, ext_mclk1_a, ext_mclk1_b,
+ ext_mclk1_c, ext_mclk1_d, ext_mclk1_e, gpio, i2s0_clk,
+ i2s0_data, i2s0_ws, i2s1_clk, i2s1_data, i2s1_ws, i2s2_clk,
+ i2s2_data, i2s2_ws, i2s3_clk, i2s3_data, i2s3_ws,
+ lpass_lpi_dbg_clk, qca_swr_clk, qca_swr_data, slimbus_clk,
+ slimbus_data, swr_rx_clk, swr_rx_data, swr_tx_clk, swr_tx_clk1,
+ swr_tx_data, va_i2s0_clk, va_i2s0_data, va_i2s0_ws,
+ wsa2_swr_clk, wsa2_swr_data, wsa_swr_clk, wsa_swr_data]
+ description:
+ Specify the alternative function to be configured for the specified
+ pins.
+
+allOf:
+ - $ref: qcom,lpass-lpi-common.yaml#
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h>
+
+ lpass_tlmm: pinctrl@7f60000 {
+ compatible = "qcom,hawi-lpass-lpi-pinctrl";
+ reg = <0x07f60000 0x20000>;
+
+ clocks = <&q6prmcc LPASS_HW_LPR_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+ <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
+ clock-names = "lpr", "audio";
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&lpass_tlmm 0 0 23>;
+
+ tx-swr-sleep-clk-state {
+ pins = "gpio0";
+ function = "swr_tx_clk";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ };
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v1 4/4] pinctrl: qcom: hawi-lpass-lpi: add Hawi LPASS LPI TLMM
2026-07-08 11:49 [PATCH v1 0/4] ASoC: qcom and pinctrl: add LPASS LPR voting and Hawi LPASS LPI TLMM Prasad Kumpatla
` (2 preceding siblings ...)
2026-07-08 11:49 ` [PATCH v1 3/4] dt-bindings: pinctrl: qcom,hawi-lpass-lpi-pinctrl: Add Hawi LPI pinctrl Prasad Kumpatla
@ 2026-07-08 11:49 ` Prasad Kumpatla
2026-07-08 11:57 ` sashiko-bot
3 siblings, 1 reply; 10+ messages in thread
From: Prasad Kumpatla @ 2026-07-08 11:49 UTC (permalink / raw)
To: Bjorn Andersson, Bartosz Golaszewski, Linus Walleij, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Liam Girdwood, Mark Brown,
Srinivas Kandagatla, Jaroslav Kysela, Takashi Iwai,
Prasad Kumpatla
Cc: Krzysztof Kozlowski, Srinivas Kandagatla, linux-arm-msm,
linux-gpio, devicetree, linux-kernel, linux-sound, Konrad Dybcio
Add pin controller driver for the Low Power Audio SubSystem (LPASS)
Low Power Island (LPI) of Qualcomm Hawi SoC.
The controller has 23 GPIOs with SoundWire, I2S, DMIC, VA I2S,
ext_mclk1 and slimbus mux functions.
Two pins (gpio13, gpio22) require 6 mux slots due to a test_bus
entry occupying a middle hardware slot. Add LPI_PINGROUP6 macro
to pinctrl-lpass-lpi.h to support pins with 5 alternate functions.
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
---
drivers/pinctrl/qcom/Kconfig | 10 +
drivers/pinctrl/qcom/Makefile | 1 +
drivers/pinctrl/qcom/pinctrl-hawi-lpass-lpi.c | 244 ++++++++++++++++++
drivers/pinctrl/qcom/pinctrl-lpass-lpi.h | 17 ++
4 files changed, 272 insertions(+)
create mode 100644 drivers/pinctrl/qcom/pinctrl-hawi-lpass-lpi.c
diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig
index 18db35022..707067b92 100644
--- a/drivers/pinctrl/qcom/Kconfig
+++ b/drivers/pinctrl/qcom/Kconfig
@@ -62,6 +62,16 @@ config PINCTRL_LPASS_LPI
Qualcomm Technologies Inc LPASS (Low Power Audio SubSystem) LPI
(Low Power Island) found on the Qualcomm Technologies Inc SoCs.
+config PINCTRL_HAWI_LPASS_LPI
+ tristate "Qualcomm Technologies Inc Hawi LPASS LPI pin controller driver"
+ depends on ARM64 || COMPILE_TEST
+ depends on PINCTRL_LPASS_LPI
+ help
+ This is the pinctrl, pinmux, pinconf and gpiolib driver for the
+ Qualcomm Technologies Inc LPASS (Low Power Audio SubSystem) LPI
+ (Low Power Island) found on the Qualcomm Technologies Inc Hawi
+ platform.
+
config PINCTRL_MILOS_LPASS_LPI
tristate "Qualcomm Milos LPASS LPI pin controller driver"
depends on ARM64 || COMPILE_TEST
diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile
index 43ecd246a..987a79f9d 100644
--- a/drivers/pinctrl/qcom/Makefile
+++ b/drivers/pinctrl/qcom/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_PINCTRL_APQ8084) += pinctrl-apq8084.o
obj-$(CONFIG_PINCTRL_ELIZA) += pinctrl-eliza.o
obj-$(CONFIG_PINCTRL_GLYMUR) += pinctrl-glymur.o
obj-$(CONFIG_PINCTRL_HAWI) += pinctrl-hawi.o
+obj-$(CONFIG_PINCTRL_HAWI_LPASS_LPI) += pinctrl-hawi-lpass-lpi.o
obj-$(CONFIG_PINCTRL_IPQ4019) += pinctrl-ipq4019.o
obj-$(CONFIG_PINCTRL_IPQ5018) += pinctrl-ipq5018.o
obj-$(CONFIG_PINCTRL_IPQ8064) += pinctrl-ipq8064.o
diff --git a/drivers/pinctrl/qcom/pinctrl-hawi-lpass-lpi.c b/drivers/pinctrl/qcom/pinctrl-hawi-lpass-lpi.c
new file mode 100644
index 000000000..7036bf4c6
--- /dev/null
+++ b/drivers/pinctrl/qcom/pinctrl-hawi-lpass-lpi.c
@@ -0,0 +1,244 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <linux/gpio/driver.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_clock.h>
+#include <linux/pm_runtime.h>
+
+#include "pinctrl-lpass-lpi.h"
+
+enum lpass_lpi_functions {
+ LPI_MUX_dmic1_clk,
+ LPI_MUX_dmic1_data,
+ LPI_MUX_dmic2_clk,
+ LPI_MUX_dmic2_data,
+ LPI_MUX_dmic3_clk,
+ LPI_MUX_dmic3_data,
+ LPI_MUX_dmic4_clk,
+ LPI_MUX_dmic4_data,
+ LPI_MUX_ext_mclk1_a,
+ LPI_MUX_ext_mclk1_b,
+ LPI_MUX_ext_mclk1_c,
+ LPI_MUX_ext_mclk1_d,
+ LPI_MUX_ext_mclk1_e,
+ LPI_MUX_i2s0_clk,
+ LPI_MUX_i2s0_data,
+ LPI_MUX_i2s0_ws,
+ LPI_MUX_i2s1_clk,
+ LPI_MUX_i2s1_data,
+ LPI_MUX_i2s1_ws,
+ LPI_MUX_i2s2_clk,
+ LPI_MUX_i2s2_data,
+ LPI_MUX_i2s2_ws,
+ LPI_MUX_i2s3_clk,
+ LPI_MUX_i2s3_data,
+ LPI_MUX_i2s3_ws,
+ LPI_MUX_lpass_lpi_dbg_clk,
+ LPI_MUX_qca_swr_clk,
+ LPI_MUX_qca_swr_data,
+ LPI_MUX_slimbus_clk,
+ LPI_MUX_slimbus_data,
+ LPI_MUX_swr_rx_clk,
+ LPI_MUX_swr_rx_data,
+ LPI_MUX_swr_tx_clk,
+ LPI_MUX_swr_tx_clk1,
+ LPI_MUX_swr_tx_data,
+ LPI_MUX_va_i2s0_clk,
+ LPI_MUX_va_i2s0_data,
+ LPI_MUX_va_i2s0_ws,
+ LPI_MUX_wsa2_swr_clk,
+ LPI_MUX_wsa2_swr_data,
+ LPI_MUX_wsa_swr_clk,
+ LPI_MUX_wsa_swr_data,
+ LPI_MUX_gpio,
+ LPI_MUX__,
+};
+
+static const struct pinctrl_pin_desc hawi_lpi_pins[] = {
+ PINCTRL_PIN(0, "gpio0"),
+ PINCTRL_PIN(1, "gpio1"),
+ PINCTRL_PIN(2, "gpio2"),
+ PINCTRL_PIN(3, "gpio3"),
+ PINCTRL_PIN(4, "gpio4"),
+ PINCTRL_PIN(5, "gpio5"),
+ PINCTRL_PIN(6, "gpio6"),
+ PINCTRL_PIN(7, "gpio7"),
+ PINCTRL_PIN(8, "gpio8"),
+ PINCTRL_PIN(9, "gpio9"),
+ PINCTRL_PIN(10, "gpio10"),
+ PINCTRL_PIN(11, "gpio11"),
+ PINCTRL_PIN(12, "gpio12"),
+ PINCTRL_PIN(13, "gpio13"),
+ PINCTRL_PIN(14, "gpio14"),
+ PINCTRL_PIN(15, "gpio15"),
+ PINCTRL_PIN(16, "gpio16"),
+ PINCTRL_PIN(17, "gpio17"),
+ PINCTRL_PIN(18, "gpio18"),
+ PINCTRL_PIN(19, "gpio19"),
+ PINCTRL_PIN(20, "gpio20"),
+ PINCTRL_PIN(21, "gpio21"),
+ PINCTRL_PIN(22, "gpio22"),
+};
+
+static const char * const gpio_groups[] = {
+ "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
+ "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
+ "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
+ "gpio22",
+};
+
+static const char * const swr_tx_clk_groups[] = { "gpio0" };
+static const char * const i2s0_clk_groups[] = { "gpio0" };
+static const char * const swr_tx_data_groups[] = { "gpio1", "gpio2", "gpio14" };
+static const char * const i2s0_ws_groups[] = { "gpio1" };
+static const char * const swr_rx_clk_groups[] = { "gpio3" };
+static const char * const i2s0_data_groups[] = { "gpio2", "gpio3", "gpio4", "gpio5" };
+static const char * const swr_rx_data_groups[] = { "gpio4", "gpio5" };
+static const char * const ext_mclk1_c_groups[] = { "gpio5" };
+static const char * const dmic1_clk_groups[] = { "gpio6" };
+static const char * const va_i2s0_clk_groups[] = { "gpio6" };
+static const char * const dmic1_data_groups[] = { "gpio7" };
+static const char * const va_i2s0_ws_groups[] = { "gpio7" };
+static const char * const dmic2_clk_groups[] = { "gpio8" };
+static const char * const va_i2s0_data_groups[] = { "gpio8", "gpio9" };
+static const char * const dmic2_data_groups[] = { "gpio9" };
+static const char * const ext_mclk1_b_groups[] = { "gpio9" };
+static const char * const i2s1_clk_groups[] = { "gpio10" };
+static const char * const wsa_swr_clk_groups[] = { "gpio10" };
+static const char * const i2s1_ws_groups[] = { "gpio11" };
+static const char * const wsa_swr_data_groups[] = { "gpio11", "gpio21" };
+static const char * const dmic3_clk_groups[] = { "gpio12" };
+static const char * const i2s3_clk_groups[] = { "gpio12" };
+static const char * const dmic3_data_groups[] = { "gpio13" };
+static const char * const i2s3_ws_groups[] = { "gpio13" };
+static const char * const ext_mclk1_a_groups[] = { "gpio13" };
+static const char * const lpass_lpi_dbg_clk_groups[] = { "gpio13" };
+static const char * const swr_tx_clk1_groups[] = { "gpio14" };
+static const char * const ext_mclk1_d_groups[] = { "gpio14" };
+static const char * const i2s1_data_groups[] = { "gpio15", "gpio16", "gpio21", "gpio22" };
+static const char * const wsa2_swr_clk_groups[] = { "gpio15" };
+static const char * const wsa2_swr_data_groups[] = { "gpio16", "gpio22" };
+static const char * const dmic4_clk_groups[] = { "gpio17" };
+static const char * const i2s3_data_groups[] = { "gpio17", "gpio18" };
+static const char * const dmic4_data_groups[] = { "gpio18" };
+static const char * const i2s2_clk_groups[] = { "gpio19" };
+static const char * const slimbus_clk_groups[] = { "gpio19" };
+static const char * const qca_swr_clk_groups[] = { "gpio19" };
+static const char * const i2s2_ws_groups[] = { "gpio20" };
+static const char * const slimbus_data_groups[] = { "gpio20" };
+static const char * const qca_swr_data_groups[] = { "gpio20" };
+static const char * const i2s2_data_groups[] = { "gpio21", "gpio22" };
+static const char * const ext_mclk1_e_groups[] = { "gpio22" };
+
+static const struct lpi_pingroup hawi_groups[] = {
+ LPI_PINGROUP(0, 11, swr_tx_clk, i2s0_clk, _, _),
+ LPI_PINGROUP(1, 11, swr_tx_data, i2s0_ws, _, _),
+ LPI_PINGROUP(2, 11, swr_tx_data, i2s0_data, _, _),
+ LPI_PINGROUP(3, 11, swr_rx_clk, i2s0_data, _, _),
+ LPI_PINGROUP(4, 11, swr_rx_data, i2s0_data, _, _),
+ LPI_PINGROUP(5, 11, swr_rx_data, ext_mclk1_c, i2s0_data, _),
+ LPI_PINGROUP(6, LPI_NO_SLEW, dmic1_clk, va_i2s0_clk, _, _),
+ LPI_PINGROUP(7, LPI_NO_SLEW, dmic1_data, va_i2s0_ws, _, _),
+ LPI_PINGROUP(8, LPI_NO_SLEW, dmic2_clk, va_i2s0_data, _, _),
+ LPI_PINGROUP(9, LPI_NO_SLEW, dmic2_data, va_i2s0_data, ext_mclk1_b, _),
+ LPI_PINGROUP(10, 11, i2s1_clk, wsa_swr_clk, _, _),
+ LPI_PINGROUP(11, 11, i2s1_ws, wsa_swr_data, _, _),
+ LPI_PINGROUP(12, LPI_NO_SLEW, dmic3_clk, i2s3_clk, _, _),
+ LPI_PINGROUP6(13, LPI_NO_SLEW, dmic3_data, i2s3_ws, ext_mclk1_a, _, lpass_lpi_dbg_clk),
+ LPI_PINGROUP(14, 11, swr_tx_data, swr_tx_clk1, ext_mclk1_d, _),
+ LPI_PINGROUP(15, 11, i2s1_data, wsa2_swr_clk, _, _),
+ LPI_PINGROUP(16, 11, i2s1_data, wsa2_swr_data, _, _),
+ LPI_PINGROUP(17, LPI_NO_SLEW, dmic4_clk, i2s3_data, _, _),
+ LPI_PINGROUP(18, LPI_NO_SLEW, dmic4_data, i2s3_data, _, _),
+ LPI_PINGROUP(19, LPI_NO_SLEW, i2s2_clk, slimbus_clk, qca_swr_clk, _),
+ LPI_PINGROUP(20, LPI_NO_SLEW, i2s2_ws, slimbus_data, qca_swr_data, _),
+ LPI_PINGROUP(21, 11, i2s2_data, _, wsa_swr_data, i2s1_data),
+ LPI_PINGROUP6(22, 11, i2s2_data, ext_mclk1_e, _, i2s1_data, wsa2_swr_data),
+};
+
+static const struct lpi_function hawi_functions[] = {
+ LPI_FUNCTION(gpio),
+ LPI_FUNCTION(dmic1_clk),
+ LPI_FUNCTION(dmic1_data),
+ LPI_FUNCTION(dmic2_clk),
+ LPI_FUNCTION(dmic2_data),
+ LPI_FUNCTION(dmic3_clk),
+ LPI_FUNCTION(dmic3_data),
+ LPI_FUNCTION(dmic4_clk),
+ LPI_FUNCTION(dmic4_data),
+ LPI_FUNCTION(ext_mclk1_a),
+ LPI_FUNCTION(ext_mclk1_b),
+ LPI_FUNCTION(ext_mclk1_c),
+ LPI_FUNCTION(ext_mclk1_d),
+ LPI_FUNCTION(ext_mclk1_e),
+ LPI_FUNCTION(i2s0_clk),
+ LPI_FUNCTION(i2s0_data),
+ LPI_FUNCTION(i2s0_ws),
+ LPI_FUNCTION(i2s1_clk),
+ LPI_FUNCTION(i2s1_data),
+ LPI_FUNCTION(i2s1_ws),
+ LPI_FUNCTION(i2s2_clk),
+ LPI_FUNCTION(i2s2_data),
+ LPI_FUNCTION(i2s2_ws),
+ LPI_FUNCTION(i2s3_clk),
+ LPI_FUNCTION(i2s3_data),
+ LPI_FUNCTION(i2s3_ws),
+ LPI_FUNCTION(lpass_lpi_dbg_clk),
+ LPI_FUNCTION(qca_swr_clk),
+ LPI_FUNCTION(qca_swr_data),
+ LPI_FUNCTION(slimbus_clk),
+ LPI_FUNCTION(slimbus_data),
+ LPI_FUNCTION(swr_rx_clk),
+ LPI_FUNCTION(swr_rx_data),
+ LPI_FUNCTION(swr_tx_clk),
+ LPI_FUNCTION(swr_tx_clk1),
+ LPI_FUNCTION(swr_tx_data),
+ LPI_FUNCTION(va_i2s0_clk),
+ LPI_FUNCTION(va_i2s0_data),
+ LPI_FUNCTION(va_i2s0_ws),
+ LPI_FUNCTION(wsa2_swr_clk),
+ LPI_FUNCTION(wsa2_swr_data),
+ LPI_FUNCTION(wsa_swr_clk),
+ LPI_FUNCTION(wsa_swr_data),
+};
+
+static const struct lpi_pinctrl_variant_data hawi_lpi_data = {
+ .pins = hawi_lpi_pins,
+ .npins = ARRAY_SIZE(hawi_lpi_pins),
+ .groups = hawi_groups,
+ .ngroups = ARRAY_SIZE(hawi_groups),
+ .functions = hawi_functions,
+ .nfunctions = ARRAY_SIZE(hawi_functions),
+ .flags = LPI_FLAG_SLEW_RATE_SAME_REG,
+};
+
+static const struct of_device_id lpi_pinctrl_of_match[] = {
+ {
+ .compatible = "qcom,hawi-lpass-lpi-pinctrl",
+ .data = &hawi_lpi_data,
+ },
+ { }
+};
+MODULE_DEVICE_TABLE(of, lpi_pinctrl_of_match);
+
+static const struct dev_pm_ops lpi_pinctrl_pm_ops = {
+ RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
+};
+
+static struct platform_driver lpi_pinctrl_driver = {
+ .driver = {
+ .name = "qcom-hawi-lpass-lpi-pinctrl",
+ .of_match_table = lpi_pinctrl_of_match,
+ .pm = pm_ptr(&lpi_pinctrl_pm_ops),
+ },
+ .probe = lpi_pinctrl_probe,
+ .remove = lpi_pinctrl_remove,
+};
+
+module_platform_driver(lpi_pinctrl_driver);
+MODULE_DESCRIPTION("Qualcomm Hawi LPI GPIO pin control driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.h b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.h
index 6ba0c4eba..056c4a774 100644
--- a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.h
+++ b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.h
@@ -92,6 +92,23 @@ struct pinctrl_pin_desc;
.pin_offset = 0, \
}
+#define LPI_PINGROUP6(id, soff, f1, f2, f3, f4, f5) \
+ { \
+ .pin = id, \
+ .slew_offset = soff, \
+ .slew_base_spare_1 = false, \
+ .funcs = (int[]){ \
+ LPI_MUX_gpio, \
+ LPI_MUX_##f1, \
+ LPI_MUX_##f2, \
+ LPI_MUX_##f3, \
+ LPI_MUX_##f4, \
+ LPI_MUX_##f5, \
+ }, \
+ .nfuncs = 6, \
+ .pin_offset = 0, \
+ }
+
/*
* Slew rate control is done in the same register as rest of the
* pin configuration.
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v1 4/4] pinctrl: qcom: hawi-lpass-lpi: add Hawi LPASS LPI TLMM
2026-07-08 11:49 ` [PATCH v1 4/4] pinctrl: qcom: hawi-lpass-lpi: add Hawi LPASS LPI TLMM Prasad Kumpatla
@ 2026-07-08 11:57 ` sashiko-bot
0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-07-08 11:57 UTC (permalink / raw)
To: Prasad Kumpatla; +Cc: devicetree, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Premature destruction of `pctrl->lock` mutex before pinctrl device unregistration creates a use-after-free window.
--
--- Patch [4]: [PATCH v1 4/4] pinctrl: qcom: hawi-lpass-lpi: add Hawi LPASS LPI TLMM ---
commit 38f7bb1223fcfb1f3a3b0698eedf3998e066c226
Author: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
pinctrl: qcom: hawi-lpass-lpi: add Hawi LPASS LPI TLMM
This commit adds a new pin controller driver for the Low Power Audio
SubSystem (LPASS) Low Power Island (LPI) of the Qualcomm Hawi SoC. It
supports 23 GPIOs with various alternate functions and includes a custom
pingroup macro to handle test_bus mux slot offsets.
> diff --git a/drivers/pinctrl/qcom/pinctrl-hawi-lpass-lpi.c b/drivers/pinctrl/qcom/pinctrl-hawi-lpass-lpi.c
> new file mode 100644
> index 0000000000000..7036bf4c66920
> --- /dev/null
> +++ b/drivers/pinctrl/qcom/pinctrl-hawi-lpass-lpi.c
[ ... ]
> +static struct platform_driver lpi_pinctrl_driver = {
> + .driver = {
> + .name = "qcom-hawi-lpass-lpi-pinctrl",
> + .of_match_table = lpi_pinctrl_of_match,
> + .pm = pm_ptr(&lpi_pinctrl_pm_ops),
> + },
> + .probe = lpi_pinctrl_probe,
> + .remove = lpi_pinctrl_remove,
[Severity: High]
This isn't a bug introduced by this patch, but does the core driver destroy
the mutex while the pinctrl device is still registered?
Looking at the core driver drivers/pinctrl/qcom/pinctrl-lpass-lpi.c:
drivers/pinctrl/qcom/pinctrl-lpass-lpi.c:lpi_pinctrl_remove() {
struct lpi_pinctrl *pctrl = platform_get_drvdata(pdev);
int i;
mutex_destroy(&pctrl->lock);
for (i = 0; i < pctrl->data->npins; i++)
pinctrl_generic_remove_group(pctrl->ctrl, i);
}
The core driver uses devm_pinctrl_register() to register the pinctrl device,
which ties its unregistration to the devres teardown phase that occurs after
lpi_pinctrl_remove() returns.
Could this create a window where the pinctrl device is still fully registered
and visible to the system, but its lock is destroyed? If an unprivileged
local user reads pinctrl debugfs while the device unbinds, could this
trigger a kernel panic or oops by operating on a destroyed mutex?
The same pattern also appears in the err_pinctrl path of lpi_pinctrl_probe():
drivers/pinctrl/qcom/pinctrl-lpass-lpi.c:lpi_pinctrl_probe() {
...
err_pinctrl:
mutex_destroy(&pctrl->lock);
return ret;
}
Here, the mutex is destroyed in the error path while the devm-registered
pinctrl device is still live globally until devres unregisters it.
> +};
> +
> +module_platform_driver(lpi_pinctrl_driver);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260708114924.1069239-1-prasad.kumpatla@oss.qualcomm.com?part=4
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v1 1/4] ASoC: dt-bindings: qcom: add LPASS LPR vote clock ID
2026-07-08 11:49 ` [PATCH v1 1/4] ASoC: dt-bindings: qcom: add LPASS LPR vote clock ID Prasad Kumpatla
@ 2026-07-08 12:00 ` sashiko-bot
2026-07-09 8:20 ` Bartosz Golaszewski
1 sibling, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-07-08 12:00 UTC (permalink / raw)
To: Prasad Kumpatla; +Cc: devicetree, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] The newly added clock ID LPASS_HW_LPR_VOTE is missing from the q6prm clock driver.
- [High] Q6DSP_MAX_CLK_ID is hardcoded to 104 in the driver, rejecting lookups for the new clock ID.
--
--- Patch [1]: [PATCH v1 1/4] ASoC: dt-bindings: qcom: add LPASS LPR vote clock ID ---
commit fe14afabf9a256155105b2b26aa6c17a00fb25dd
Author: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
ASoC: dt-bindings: qcom: add LPASS LPR vote clock ID
Add a new clock ID, LPASS_HW_LPR_VOTE, to represent the LPASS low-power
resource (LPR) vote through the PRM interface. Also update Q6AFE_MAX_CLK_ID
to account for the newly added clock ID. This allows clients to explicitly
manage LPR resource voting via PRM.
> diff --git a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
> index 45850f2d43425..06ca2c287ab2f 100644
> --- a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
> +++ b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
> @@ -236,8 +236,9 @@
> #define LPASS_HW_AVTIMER_VOTE 101
> #define LPASS_HW_MACRO_VOTE 102
> #define LPASS_HW_DCODEC_VOTE 103
> +#define LPASS_HW_LPR_VOTE 104
[Severity: High]
Is the corresponding driver implementation missing for this new clock ID?
Looking at the clock provider in sound/soc/qcom/qdsp6/q6prm-clocks.c, the
q6prm_clks array doesn't appear to have an entry for LPASS_HW_LPR_VOTE,
which means the clock would never be registered when a client device attempts
to request it.
[Severity: High]
Will the hardcoded limit in the driver reject lookups for this new ID?
In sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c, Q6DSP_MAX_CLK_ID is hardcoded
to 104. When a client device requests the new clock ID 104, it looks like it
would be rejected here:
sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c:q6dsp_of_clk_hw_get() {
...
if (idx >= Q6DSP_MAX_CLK_ID || attr > LPASS_CLK_ATTRIBUTE_COUPLE_DIVISOR) {
...
return ERR_PTR(-EINVAL);
}
...
}
Could this result in -EINVAL being returned instead of the expected clock?
Also, if the clock is later added to the initialization array without updating
the Q6DSP_MAX_CLK_ID macro, is there a risk of an out-of-bounds write during
driver initialization since the array size remains 104?
>
> -#define Q6AFE_MAX_CLK_ID 104
> +#define Q6AFE_MAX_CLK_ID 105
>
> #define LPASS_CLK_ATTRIBUTE_INVALID 0x0
> #define LPASS_CLK_ATTRIBUTE_COUPLE_NO 0x1
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260708114924.1069239-1-prasad.kumpatla@oss.qualcomm.com?part=1
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v1 1/4] ASoC: dt-bindings: qcom: add LPASS LPR vote clock ID
2026-07-08 11:49 ` [PATCH v1 1/4] ASoC: dt-bindings: qcom: add LPASS LPR vote clock ID Prasad Kumpatla
2026-07-08 12:00 ` sashiko-bot
@ 2026-07-09 8:20 ` Bartosz Golaszewski
1 sibling, 0 replies; 10+ messages in thread
From: Bartosz Golaszewski @ 2026-07-09 8:20 UTC (permalink / raw)
To: Prasad Kumpatla
Cc: Krzysztof Kozlowski, Srinivas Kandagatla, linux-arm-msm,
linux-gpio, devicetree, linux-kernel, linux-sound,
Bjorn Andersson, Bartosz Golaszewski, Linus Walleij, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Liam Girdwood, Mark Brown,
Srinivas Kandagatla, Jaroslav Kysela, Takashi Iwai
On Wed, 8 Jul 2026 13:49:21 +0200, Prasad Kumpatla
<prasad.kumpatla@oss.qualcomm.com> said:
> Add a new clock ID, LPASS_HW_LPR_VOTE, to represent the LPASS low-power
> resource (LPR) vote through the PRM interface.
>
> The LPASS PRM supports a resource voting mechanism to control low-power
> states via PARAM_ID_RSC_CPU_LPR. Exposing this as a q6prm clock ID allows
> clients to request the LPR vote using the existing qcom,q6prm clock
> provider interface.
>
> This functionality is required on newer platforms (e.g. Hawi) where LPASS
> clients need to explicitly manage LPR resource voting via PRM.
>
> Also update Q6AFE_MAX_CLK_ID to account for the newly added clock ID.
>
> Signed-off-by: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
> ---
> include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
> index 45850f2d4..06ca2c287 100644
> --- a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
> +++ b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
> @@ -236,8 +236,9 @@
> #define LPASS_HW_AVTIMER_VOTE 101
> #define LPASS_HW_MACRO_VOTE 102
> #define LPASS_HW_DCODEC_VOTE 103
> +#define LPASS_HW_LPR_VOTE 104
>
> -#define Q6AFE_MAX_CLK_ID 104
> +#define Q6AFE_MAX_CLK_ID 105
>
> #define LPASS_CLK_ATTRIBUTE_INVALID 0x0
> #define LPASS_CLK_ATTRIBUTE_COUPLE_NO 0x1
> --
> 2.34.1
>
>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v1 2/4] ASoC: qcom: q6prm: add support for LPASS LPR resource voting
2026-07-08 11:49 ` [PATCH v1 2/4] ASoC: qcom: q6prm: add support for LPASS LPR resource voting Prasad Kumpatla
@ 2026-07-09 8:23 ` Bartosz Golaszewski
2026-07-09 12:37 ` Mark Brown
0 siblings, 1 reply; 10+ messages in thread
From: Bartosz Golaszewski @ 2026-07-09 8:23 UTC (permalink / raw)
To: Prasad Kumpatla
Cc: Krzysztof Kozlowski, Srinivas Kandagatla, linux-arm-msm,
linux-gpio, devicetree, linux-kernel, linux-sound,
Bjorn Andersson, Bartosz Golaszewski, Linus Walleij, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Liam Girdwood, Mark Brown,
Srinivas Kandagatla, Jaroslav Kysela, Takashi Iwai
On Wed, 8 Jul 2026 13:49:22 +0200, Prasad Kumpatla
<prasad.kumpatla@oss.qualcomm.com> said:
> Add support for issuing LPASS low-power resource (LPR) votes through
> the PRM interface.
>
> Some platforms (e.g. Hawi) require the LPASS to be kept active via LPR
> resource voting instead of the existing hardware core vote mechanism.
> Handle this by introducing support for PARAM_ID_RSC_CPU_LPR when the
> LPR vote clock ID is requested.
>
> For LPR requests, use the appropriate parameter ID and payload format
> to disable CPU subsystem sleep, ensuring that the LPASS register space
> remains accessible.
>
> Also add the corresponding clock mapping for LPASS_HW_LPR_VOTE and make
> the q6dsp clock ID range consistent with the dt-bindings by deriving
> it from Q6AFE_MAX_CLK_ID.
>
> Signed-off-by: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
> ---
> sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c | 2 +-
> sound/soc/qcom/qdsp6/q6prm-clocks.c | 2 ++
> sound/soc/qcom/qdsp6/q6prm.c | 18 ++++++++++++++----
> sound/soc/qcom/qdsp6/q6prm.h | 1 +
> 4 files changed, 18 insertions(+), 5 deletions(-)
>
> diff --git a/sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c b/sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c
> index 03838582a..79527a367 100644
> --- a/sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c
> +++ b/sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c
> @@ -12,7 +12,7 @@
> #include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h>
> #include "q6dsp-lpass-clocks.h"
>
> -#define Q6DSP_MAX_CLK_ID 104
> +#define Q6DSP_MAX_CLK_ID Q6AFE_MAX_CLK_ID
> #define Q6DSP_LPASS_CLK_ROOT_DEFAULT 0
>
>
> diff --git a/sound/soc/qcom/qdsp6/q6prm-clocks.c b/sound/soc/qcom/qdsp6/q6prm-clocks.c
> index 4c574b48a..2b2b3872e 100644
> --- a/sound/soc/qcom/qdsp6/q6prm-clocks.c
> +++ b/sound/soc/qcom/qdsp6/q6prm-clocks.c
> @@ -63,6 +63,8 @@ static const struct q6dsp_clk_init q6prm_clks[] = {
> "LPASS_HW_MACRO"),
> Q6DSP_VOTE_CLK(LPASS_HW_DCODEC_VOTE, Q6PRM_HW_CORE_ID_DCODEC,
> "LPASS_HW_DCODEC"),
> + Q6DSP_VOTE_CLK(LPASS_HW_LPR_VOTE, Q6PRM_HW_LPR_VOTE,
> + "LPASS_HW_LPR_VOTE"),
> };
>
> static const struct q6dsp_clk_desc q6dsp_clk_q6prm __maybe_unused = {
> diff --git a/sound/soc/qcom/qdsp6/q6prm.c b/sound/soc/qcom/qdsp6/q6prm.c
> index 04892fb44..22ace8bcb 100644
> --- a/sound/soc/qcom/qdsp6/q6prm.c
> +++ b/sound/soc/qcom/qdsp6/q6prm.c
> @@ -31,10 +31,16 @@ struct q6prm {
> #define PARAM_ID_RSC_HW_CORE 0x08001032
> #define PARAM_ID_RSC_LPASS_CORE 0x0800102B
> #define PARAM_ID_RSC_AUDIO_HW_CLK 0x0800102C
> +#define PARAM_ID_RSC_CPU_LPR 0x08001A6E
> +
> +#define LPR_CPU_SS_SLEEP_DISABLED 0x1
>
> struct prm_cmd_request_hw_core {
> struct apm_module_param_data param_data;
> - uint32_t hw_clk_id;
> + union {
> + u32 hw_clk_id;
> + u32 lpr_state;
> + };
> } __packed;
>
> struct prm_cmd_request_rsc {
> @@ -62,6 +68,7 @@ static int q6prm_set_hw_core_req(struct device *dev, uint32_t hw_block_id, bool
> struct prm_cmd_request_hw_core *req;
> gpr_device_t *gdev = prm->gdev;
> uint32_t opcode, rsp_opcode;
> + bool lpr_req = hw_block_id == Q6PRM_HW_LPR_VOTE;
Please use braces here for better readability.
>
> if (enable) {
> opcode = PRM_CMD_REQUEST_HW_RSC;
> @@ -82,10 +89,13 @@ static int q6prm_set_hw_core_req(struct device *dev, uint32_t hw_block_id, bool
>
> param_data->module_instance_id = GPR_PRM_MODULE_IID;
> param_data->error_code = 0;
> - param_data->param_id = PARAM_ID_RSC_HW_CORE;
> + param_data->param_id = lpr_req ? PARAM_ID_RSC_CPU_LPR : PARAM_ID_RSC_HW_CORE;
> param_data->param_size = sizeof(*req) - APM_MODULE_PARAM_DATA_SIZE;
>
> - req->hw_clk_id = hw_block_id;
> + if (lpr_req)
> + req->lpr_state = LPR_CPU_SS_SLEEP_DISABLED;
> + else
> + req->hw_clk_id = hw_block_id;
>
> return q6prm_send_cmd_sync(prm, pkt, rsp_opcode);
> }
> @@ -94,7 +104,6 @@ int q6prm_vote_lpass_core_hw(struct device *dev, uint32_t hw_block_id,
> const char *client_name, uint32_t *client_handle)
> {
> return q6prm_set_hw_core_req(dev, hw_block_id, true);
> -
> }
> EXPORT_SYMBOL_GPL(q6prm_vote_lpass_core_hw);
>
> @@ -210,6 +219,7 @@ static int prm_probe(gpr_device_t *gdev)
> cc->gdev = gdev;
> mutex_init(&cc->lock);
> init_waitqueue_head(&cc->wait);
> +
> dev_set_drvdata(dev, cc);
These newline ninja changes are just unneeded noise in this patch.
>
> if (!q6apm_is_adsp_ready())
> diff --git a/sound/soc/qcom/qdsp6/q6prm.h b/sound/soc/qcom/qdsp6/q6prm.h
> index a988a3208..bd5ee0c40 100644
> --- a/sound/soc/qcom/qdsp6/q6prm.h
> +++ b/sound/soc/qcom/qdsp6/q6prm.h
> @@ -87,6 +87,7 @@
> #define Q6PRM_LPASS_CLK_ROOT_DEFAULT 0
> #define Q6PRM_HW_CORE_ID_LPASS 1
> #define Q6PRM_HW_CORE_ID_DCODEC 2
> +#define Q6PRM_HW_LPR_VOTE 3
>
> int q6prm_set_lpass_clock(struct device *dev, int clk_id, int clk_attr,
> int clk_root, unsigned int freq);
> --
> 2.34.1
>
>
Bart
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v1 2/4] ASoC: qcom: q6prm: add support for LPASS LPR resource voting
2026-07-09 8:23 ` Bartosz Golaszewski
@ 2026-07-09 12:37 ` Mark Brown
0 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2026-07-09 12:37 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Prasad Kumpatla, Krzysztof Kozlowski, Srinivas Kandagatla,
linux-arm-msm, linux-gpio, devicetree, linux-kernel, linux-sound,
Bjorn Andersson, Linus Walleij, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Liam Girdwood, Srinivas Kandagatla, Jaroslav Kysela,
Takashi Iwai
[-- Attachment #1: Type: text/plain, Size: 481 bytes --]
On Thu, Jul 09, 2026 at 01:23:24AM -0700, Bartosz Golaszewski wrote:
> On Wed, 8 Jul 2026 13:49:22 +0200, Prasad Kumpatla
> <prasad.kumpatla@oss.qualcomm.com> said:
> > Add support for issuing LPASS low-power resource (LPR) votes through
> > the PRM interface.
Please delete unneeded context from mails when replying. Doing this
makes it much easier to find your reply in the message, helping ensure
it won't be missed by people scrolling through the irrelevant quoted
material.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-07-09 12:37 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-08 11:49 [PATCH v1 0/4] ASoC: qcom and pinctrl: add LPASS LPR voting and Hawi LPASS LPI TLMM Prasad Kumpatla
2026-07-08 11:49 ` [PATCH v1 1/4] ASoC: dt-bindings: qcom: add LPASS LPR vote clock ID Prasad Kumpatla
2026-07-08 12:00 ` sashiko-bot
2026-07-09 8:20 ` Bartosz Golaszewski
2026-07-08 11:49 ` [PATCH v1 2/4] ASoC: qcom: q6prm: add support for LPASS LPR resource voting Prasad Kumpatla
2026-07-09 8:23 ` Bartosz Golaszewski
2026-07-09 12:37 ` Mark Brown
2026-07-08 11:49 ` [PATCH v1 3/4] dt-bindings: pinctrl: qcom,hawi-lpass-lpi-pinctrl: Add Hawi LPI pinctrl Prasad Kumpatla
2026-07-08 11:49 ` [PATCH v1 4/4] pinctrl: qcom: hawi-lpass-lpi: add Hawi LPASS LPI TLMM Prasad Kumpatla
2026-07-08 11:57 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox