All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/5] ASoC: qcom and pinctrl: add LPASS LPR voting and Hawi LPASS LPI TLMM
@ 2026-07-13 18:45 Prasad Kumpatla
  2026-07-13 18:45 ` [PATCH v2 1/5] pinctrl: qcom: lpass-lpi: make mutex cleanup devm-managed Prasad Kumpatla
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Prasad Kumpatla @ 2026-07-13 18:45 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.

Changes in v2:
	- Add mutex cleanup devm-managed in LPASS LPI Pinctrl. 
	- Addressed Bart Comments related to newline and readability.
	- Link to v1: https://lore.kernel.org/linux-arm-msm/20260708114924.1069239-1-prasad.kumpatla@oss.qualcomm.com/

Prasad Kumpatla (5):
  pinctrl: qcom: lpass-lpi: make mutex cleanup devm-managed
  ASoC: dt-bindings: qcom: 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.c      |  22 +-
 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                  |  17 +-
 sound/soc/qcom/qdsp6/q6prm.h                  |   1 +
 11 files changed, 407 insertions(+), 21 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 v2 1/5] pinctrl: qcom: lpass-lpi: make mutex cleanup devm-managed
  2026-07-13 18:45 [PATCH v2 0/5] ASoC: qcom and pinctrl: add LPASS LPR voting and Hawi LPASS LPI TLMM Prasad Kumpatla
@ 2026-07-13 18:45 ` Prasad Kumpatla
  2026-07-13 18:55   ` sashiko-bot
  2026-07-13 18:45 ` [PATCH v2 2/5] ASoC: dt-bindings: qcom: add LPASS LPR vote clock ID Prasad Kumpatla
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Prasad Kumpatla @ 2026-07-13 18:45 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

The driver registers its pin controller using devm_pinctrl_register(),
which keeps the pinctrl device alive until devres teardown, after
.remove() returns. Explicitly destroying pctrl->lock in .remove() and
the probe error path leaves the mutex destroyed while the pinctrl
device is still accessible, risking a panic on concurrent debugfs
access during unbind.

Switch to devm_mutex_init() so the mutex lifetime is automatically
aligned with the devm-managed pinctrl device, and remove now
redundant mutex_destroy() calls and err_pinctrl label.

Signed-off-by: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
---
 drivers/pinctrl/qcom/pinctrl-lpass-lpi.c | 22 +++++++---------------
 1 file changed, 7 insertions(+), 15 deletions(-)

diff --git a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c
index 5fd4a4eba..b3e365470 100644
--- a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c
+++ b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c
@@ -559,31 +559,25 @@ int lpi_pinctrl_probe(struct platform_device *pdev)
 	pctrl->chip.label = dev_name(dev);
 	pctrl->chip.can_sleep = true;
 
-	mutex_init(&pctrl->lock);
+	ret = devm_mutex_init(&pdev->dev, &pctrl->lock);
+	if (ret)
+		return ret;
 
 	pctrl->ctrl = devm_pinctrl_register(dev, &pctrl->desc, pctrl);
-	if (IS_ERR(pctrl->ctrl)) {
-		ret = PTR_ERR(pctrl->ctrl);
-		dev_err(dev, "failed to add pin controller\n");
-		goto err_pinctrl;
-	}
+	if (IS_ERR(pctrl->ctrl))
+		return PTR_ERR(pctrl->ctrl);
 
 	ret = lpi_build_pin_desc_groups(pctrl);
 	if (ret)
-		goto err_pinctrl;
+		return ret;
 
 	ret = devm_gpiochip_add_data(dev, &pctrl->chip, pctrl);
 	if (ret) {
 		dev_err(pctrl->dev, "can't add gpio chip\n");
-		goto err_pinctrl;
+		return ret;
 	}
 
 	return 0;
-
-err_pinctrl:
-	mutex_destroy(&pctrl->lock);
-
-	return ret;
 }
 EXPORT_SYMBOL_GPL(lpi_pinctrl_probe);
 
@@ -592,8 +586,6 @@ void lpi_pinctrl_remove(struct platform_device *pdev)
 	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);
 }
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 2/5] ASoC: dt-bindings: qcom: add LPASS LPR vote clock ID
  2026-07-13 18:45 [PATCH v2 0/5] ASoC: qcom and pinctrl: add LPASS LPR voting and Hawi LPASS LPI TLMM Prasad Kumpatla
  2026-07-13 18:45 ` [PATCH v2 1/5] pinctrl: qcom: lpass-lpi: make mutex cleanup devm-managed Prasad Kumpatla
@ 2026-07-13 18:45 ` Prasad Kumpatla
  2026-07-13 18:57   ` sashiko-bot
  2026-07-13 18:45 ` [PATCH v2 3/5] ASoC: qcom: q6prm: add support for LPASS LPR resource voting Prasad Kumpatla
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Prasad Kumpatla @ 2026-07-13 18:45 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,
	Bartosz Golaszewski

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.

Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
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 v2 3/5] ASoC: qcom: q6prm: add support for LPASS LPR resource voting
  2026-07-13 18:45 [PATCH v2 0/5] ASoC: qcom and pinctrl: add LPASS LPR voting and Hawi LPASS LPI TLMM Prasad Kumpatla
  2026-07-13 18:45 ` [PATCH v2 1/5] pinctrl: qcom: lpass-lpi: make mutex cleanup devm-managed Prasad Kumpatla
  2026-07-13 18:45 ` [PATCH v2 2/5] ASoC: dt-bindings: qcom: add LPASS LPR vote clock ID Prasad Kumpatla
@ 2026-07-13 18:45 ` Prasad Kumpatla
  2026-07-14  7:43   ` Srinivas Kandagatla
  2026-07-13 18:45 ` [PATCH v2 4/5] dt-bindings: pinctrl: qcom,hawi-lpass-lpi-pinctrl: Add Hawi LPI pinctrl Prasad Kumpatla
  2026-07-13 18:45 ` [PATCH v2 5/5] pinctrl: qcom: hawi-lpass-lpi: add Hawi LPASS LPI TLMM Prasad Kumpatla
  4 siblings, 1 reply; 10+ messages in thread
From: Prasad Kumpatla @ 2026-07-13 18:45 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              | 17 +++++++++++++----
 sound/soc/qcom/qdsp6/q6prm.h              |  1 +
 4 files changed, 17 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..7a7a1d3d5 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);
 
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 v2 4/5] dt-bindings: pinctrl: qcom,hawi-lpass-lpi-pinctrl: Add Hawi LPI pinctrl
  2026-07-13 18:45 [PATCH v2 0/5] ASoC: qcom and pinctrl: add LPASS LPR voting and Hawi LPASS LPI TLMM Prasad Kumpatla
                   ` (2 preceding siblings ...)
  2026-07-13 18:45 ` [PATCH v2 3/5] ASoC: qcom: q6prm: add support for LPASS LPR resource voting Prasad Kumpatla
@ 2026-07-13 18:45 ` Prasad Kumpatla
  2026-07-13 18:45 ` [PATCH v2 5/5] pinctrl: qcom: hawi-lpass-lpi: add Hawi LPASS LPI TLMM Prasad Kumpatla
  4 siblings, 0 replies; 10+ messages in thread
From: Prasad Kumpatla @ 2026-07-13 18:45 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 v2 5/5] pinctrl: qcom: hawi-lpass-lpi: add Hawi LPASS LPI TLMM
  2026-07-13 18:45 [PATCH v2 0/5] ASoC: qcom and pinctrl: add LPASS LPR voting and Hawi LPASS LPI TLMM Prasad Kumpatla
                   ` (3 preceding siblings ...)
  2026-07-13 18:45 ` [PATCH v2 4/5] dt-bindings: pinctrl: qcom,hawi-lpass-lpi-pinctrl: Add Hawi LPI pinctrl Prasad Kumpatla
@ 2026-07-13 18:45 ` Prasad Kumpatla
  4 siblings, 0 replies; 10+ messages in thread
From: Prasad Kumpatla @ 2026-07-13 18:45 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 v2 1/5] pinctrl: qcom: lpass-lpi: make mutex cleanup devm-managed
  2026-07-13 18:45 ` [PATCH v2 1/5] pinctrl: qcom: lpass-lpi: make mutex cleanup devm-managed Prasad Kumpatla
@ 2026-07-13 18:55   ` sashiko-bot
  0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-07-13 18:55 UTC (permalink / raw)
  To: Prasad Kumpatla; +Cc: devicetree, conor+dt, robh

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] Data races and Use-After-Free (UAF) vulnerabilities due to early registration and lockless mutation of generic pin groups.
--

--- Patch [1]: [PATCH v2 1/5] pinctrl: qcom: lpass-lpi: make mutex cleanup devm-managed ---
commit 808f67e14184e3ba9ce98d89331c2be909c075e0
Author: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>

pinctrl: qcom: lpass-lpi: make mutex cleanup devm-managed

The driver registers its pin controller using devm_pinctrl_register(),
which keeps the pinctrl device alive until devres teardown, after
.remove() returns. This explicitly replaces mutex_init and
mutex_destroy with devm_mutex_init to align the lifetime automatically.

> diff --git a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c
> index 5fd4a4eba654d..b3e36547030f8 100644
> --- a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c
> +++ b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c
> @@ -559,31 +559,25 @@ int lpi_pinctrl_probe(struct platform_device *pdev)
>  	pctrl->chip.label = dev_name(dev);
>  	pctrl->chip.can_sleep = true;
>  
> -	mutex_init(&pctrl->lock);
> +	ret = devm_mutex_init(&pdev->dev, &pctrl->lock);
> +	if (ret)
> +		return ret;
>  
>  	pctrl->ctrl = devm_pinctrl_register(dev, &pctrl->desc, pctrl);
> -	if (IS_ERR(pctrl->ctrl)) {
> -		ret = PTR_ERR(pctrl->ctrl);
> -		dev_err(dev, "failed to add pin controller\n");
> -		goto err_pinctrl;
> -	}
> +	if (IS_ERR(pctrl->ctrl))
> +		return PTR_ERR(pctrl->ctrl);
>  
>  	ret = lpi_build_pin_desc_groups(pctrl);

[Severity: High]
This is a pre-existing issue, but does this sequence leave the device
vulnerable to data races via debugfs?

When devm_pinctrl_register() is called, it fully registers the device and
exposes it to userspace via debugfs.

Afterward, lpi_build_pin_desc_groups() populates the groups via
pinctrl_generic_add_group(). This modifies pctldev->pin_group_tree and
num_groups without acquiring pctldev->mutex. 

If there is a concurrent debugfs read to the pingroups file, it takes the mutex
and iterates the tree, creating a data race.

>  	if (ret)
> -		goto err_pinctrl;
> +		return ret;
>  
>  	ret = devm_gpiochip_add_data(dev, &pctrl->chip, pctrl);
>  	if (ret) {
>  		dev_err(pctrl->dev, "can't add gpio chip\n");
> -		goto err_pinctrl;
> +		return ret;
>  	}

[Severity: High]
This is a pre-existing issue, but could this error path trigger a
use-after-free?

If devm_gpiochip_add_data() fails, devres unwinds in last-in first-out order.
It will free the group objects (allocated via devm_kzalloc) before executing
devm_pinctrl_dev_release() to unregister the device.

This leaves dangling pointers in the radix tree while debugfs is still active.

>  
>  	return 0;
> -
> -err_pinctrl:
> -	mutex_destroy(&pctrl->lock);
> -
> -	return ret;
>  }
>  EXPORT_SYMBOL_GPL(lpi_pinctrl_probe);
>  
> @@ -592,8 +586,6 @@ void lpi_pinctrl_remove(struct platform_device *pdev)
>  	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);

[Severity: High]
This is a pre-existing issue, but can this lockless removal also trigger a
use-after-free?

The driver locklessly calls pinctrl_generic_remove_group(), which deletes
the group from the radix tree and frees it via devm_kfree(). 

Since the device is not unregistered until devres teardown (after remove()
returns), concurrent debugfs reads while this loop is running will
dereference the freed group_desc.

>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260713184549.929569-1-prasad.kumpatla@oss.qualcomm.com?part=1

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 2/5] ASoC: dt-bindings: qcom: add LPASS LPR vote clock ID
  2026-07-13 18:45 ` [PATCH v2 2/5] ASoC: dt-bindings: qcom: add LPASS LPR vote clock ID Prasad Kumpatla
@ 2026-07-13 18:57   ` sashiko-bot
  0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-07-13 18:57 UTC (permalink / raw)
  To: Prasad Kumpatla; +Cc: conor+dt, robh, devicetree

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Adding the clock ID `LPASS_HW_LPR_VOTE` (104) without updating the hardcoded driver limit `Q6DSP_MAX_CLK_ID` causes valid device tree requests to be rejected and creates an out-of-bounds write hazard.
- [High] The driver implementation for the newly added `LPASS_HW_LPR_VOTE` clock ID and `PARAM_ID_RSC_CPU_LPR` parameter is completely missing.
--

--- Patch [2]: [PATCH v2 2/5] ASoC: dt-bindings: qcom: add LPASS LPR vote clock ID ---
commit 806d87026efc23f9d5588f86e5e4c815dd4852cd
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.

> 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.

[Severity: High]
Is the driver implementation for this functionality missing from this patch?

Looking at sound/soc/qcom/qdsp6/q6prm-clocks.c, the q6prm_clks[] array does
not appear to map the new LPASS_HW_LPR_VOTE clock ID, which means it will
not be registered during probe.

Additionally, q6prm_set_hw_core_req() hardcodes PARAM_ID_RSC_HW_CORE and
does not seem to have the logic to handle the newly documented
PARAM_ID_RSC_CPU_LPR parameter ID:

sound/soc/qcom/qdsp6/q6prm.c:q6prm_set_hw_core_req() {
    ...
    param_data->param_id = PARAM_ID_RSC_HW_CORE;
    ...
}

Are there corresponding driver changes expected to accompany this binding?

> 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
>  
> -#define Q6AFE_MAX_CLK_ID			104
> +#define Q6AFE_MAX_CLK_ID			105

[Severity: High]
Does the hardcoded limit in the driver also need to be updated to support
this new clock ID?

In sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c, Q6DSP_MAX_CLK_ID is hardcoded
to 104. Since LPASS_HW_LPR_VOTE is exactly 104, device tree requests for
it will fail the bounds check and be rejected:

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) {
        dev_err(cc->dev, "Invalid clk specifier (%d, %d)\n", idx, attr);
        return ERR_PTR(-EINVAL);
    }
    ...
}

Also, if the provider driver is updated to register this clock, will it
cause an out-of-bounds array write during probe? The target array seems to
be sized based on the old maximum limit (104 elements):

sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c:q6dsp_clock_dev_probe() {
    ...
    cc->clks[id] = clk;
    ...
}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260713184549.929569-1-prasad.kumpatla@oss.qualcomm.com?part=2

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 3/5] ASoC: qcom: q6prm: add support for LPASS LPR resource voting
  2026-07-13 18:45 ` [PATCH v2 3/5] ASoC: qcom: q6prm: add support for LPASS LPR resource voting Prasad Kumpatla
@ 2026-07-14  7:43   ` Srinivas Kandagatla
  2026-07-14  8:43     ` Prasad Kumpatla
  0 siblings, 1 reply; 10+ messages in thread
From: Srinivas Kandagatla @ 2026-07-14  7:43 UTC (permalink / raw)
  To: Prasad Kumpatla, Bjorn Andersson, Bartosz Golaszewski,
	Linus Walleij, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Liam Girdwood, Mark Brown, Srinivas Kandagatla, Jaroslav Kysela,
	Takashi Iwai
  Cc: Krzysztof Kozlowski, linux-arm-msm, linux-gpio, devicetree,
	linux-kernel, linux-sound

On 7/13/26 7:45 PM, Prasad Kumpatla wrote:
> 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              | 17 +++++++++++++----
>  sound/soc/qcom/qdsp6/q6prm.h              |  1 +
>  4 files changed, 17 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..7a7a1d3d5 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;

this does not make sense, this should be set based on enable flag, here
you are disabling the LPR for both enable and disable request.


> +	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);
> -
unnecessary change.

>  }
>  EXPORT_SYMBOL_GPL(q6prm_vote_lpass_core_hw);
>  
> 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);


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 3/5] ASoC: qcom: q6prm: add support for LPASS LPR resource voting
  2026-07-14  7:43   ` Srinivas Kandagatla
@ 2026-07-14  8:43     ` Prasad Kumpatla
  0 siblings, 0 replies; 10+ messages in thread
From: Prasad Kumpatla @ 2026-07-14  8:43 UTC (permalink / raw)
  To: Srinivas Kandagatla, Bjorn Andersson, Bartosz Golaszewski,
	Linus Walleij, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Liam Girdwood, Mark Brown, Srinivas Kandagatla, Jaroslav Kysela,
	Takashi Iwai
  Cc: Krzysztof Kozlowski, linux-arm-msm, linux-gpio, devicetree,
	linux-kernel, linux-sound


On 7/14/2026 1:13 PM, Srinivas Kandagatla wrote:
> On 7/13/26 7:45 PM, Prasad Kumpatla wrote:
>> 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              | 17 +++++++++++++----
>>   sound/soc/qcom/qdsp6/q6prm.h              |  1 +
>>   4 files changed, 17 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..7a7a1d3d5 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;
> this does not make sense, this should be set based on enable flag, here
> you are disabling the LPR for both enable and disable request.
Hi Srini,

The intent here is slightly different from a typical enable/disable 
state variable.
For PARAM_ID_RSC_CPU_LPR, the payload field (lpr_state) identifies the 
low-power
resource being controlled, and the DSP API defines a single valid value: 
LPR_CPU_SS_SLEEP_DISABLED(0x1).

The actual operation is encoded by the PRM command:
PRM_CMD_REQUEST_HW_RSC + LPR_CPU_SS_SLEEP_DISABLED  -  Requests the 
resource and prevents the subsystem from entering the corresponding 
low-power state.
PRM_CMD_RELEASE_HW_RSC + LPR_CPU_SS_SLEEP_DISABLED    - Releases the 
resource, allowing the subsystem to enter that low-power state again.

In other words, the payload does not represent the desired runtime state 
and is therefore not toggled based on the enable flag.
Instead, the request/release opcode determines whether the low-power 
state is being blocked or re-enabled, while lpr_state remains 
LPR_CPU_SS_SLEEP_DISABLED for both operations.

Hope this clarifies why the payload remains unchanged across request and 
release paths.

>
>
>> +	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);
>> -
> unnecessary change.
Agreed, the whitespace change is unrelated and will be dropped in the 
next revision.

Thanks,
Prasad

>
>>   }
>>   EXPORT_SYMBOL_GPL(q6prm_vote_lpass_core_hw);
>>   
>> 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);

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-07-14  8:44 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-13 18:45 [PATCH v2 0/5] ASoC: qcom and pinctrl: add LPASS LPR voting and Hawi LPASS LPI TLMM Prasad Kumpatla
2026-07-13 18:45 ` [PATCH v2 1/5] pinctrl: qcom: lpass-lpi: make mutex cleanup devm-managed Prasad Kumpatla
2026-07-13 18:55   ` sashiko-bot
2026-07-13 18:45 ` [PATCH v2 2/5] ASoC: dt-bindings: qcom: add LPASS LPR vote clock ID Prasad Kumpatla
2026-07-13 18:57   ` sashiko-bot
2026-07-13 18:45 ` [PATCH v2 3/5] ASoC: qcom: q6prm: add support for LPASS LPR resource voting Prasad Kumpatla
2026-07-14  7:43   ` Srinivas Kandagatla
2026-07-14  8:43     ` Prasad Kumpatla
2026-07-13 18:45 ` [PATCH v2 4/5] dt-bindings: pinctrl: qcom,hawi-lpass-lpi-pinctrl: Add Hawi LPI pinctrl Prasad Kumpatla
2026-07-13 18:45 ` [PATCH v2 5/5] pinctrl: qcom: hawi-lpass-lpi: add Hawi LPASS LPI TLMM Prasad Kumpatla

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.