Devicetree
 help / color / mirror / Atom feed
* [PATCH v4 2/4] ASoC: qcom: q6prm: add support for LPASS LPR resource voting
From: Prasad Kumpatla @ 2026-07-20 13:05 UTC (permalink / raw)
  To: Bartosz Golaszewski, Bjorn Andersson, 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
In-Reply-To: <20260720130511.493295-1-prasad.kumpatla@oss.qualcomm.com>

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
update Q6DSP_MAX_CLK_ID to 105 to keep the q6dsp clock ID range
consistent with the dt-bindings.

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              | 16 +++++++++++++---
 sound/soc/qcom/qdsp6/q6prm.h              |  1 +
 4 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c b/sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c
index 03838582a..ab7d20580 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			105
 #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..1f3ce4cc0 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_DISABLE	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_DISABLE;
+	else
+		req->hw_clk_id = hw_block_id;
 
 	return q6prm_send_cmd_sync(prm, pkt, rsp_opcode);
 }
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

* [PATCH v4 0/4] ASoC: qcom and pinctrl: add LPASS LPR voting and Hawi LPASS LPI TLMM
From: Prasad Kumpatla @ 2026-07-20 13:05 UTC (permalink / raw)
  To: Bartosz Golaszewski, Bjorn Andersson, 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.

Chanes in v4:
	- Addressed Krzysztof comments, Drop Q6AFE_MAX_CLK_ID from the bindings
	  since it is not used in-tree.
	- Link to v3: https://lore.kernel.org/linux-arm-msm/20260715133243.3170821-1-prasad.kumpatla@oss.qualcomm.com/

Changes in v3:
	- Drop the mutex cleanup patch from this series. Since this change
	  is not required for Hawi enablement, keep the current series 
	  focused on LPASS LPR voting and LPASS LPI TLMM support, and 
	  address the cleanup in a dedicated follow-up series.
	 - As Srini suggested changed LPR_CPU_SS_SLEEP_DISABLED to LPR_CPU_SS_SLEEP_DISABLE in patch#2.
	 - Link to v2: https://lore.kernel.org/all/20260713184549.929569-1-prasad.kumpatla@oss.qualcomm.com/

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 (4):
  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.h      |  17 ++
 .../sound/qcom,q6dsp-lpass-ports.h            |   2 +-
 sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c     |   2 +-
 sound/soc/qcom/qdsp6/q6prm-clocks.c           |   2 +
 sound/soc/qcom/qdsp6/q6prm.c                  |  16 +-
 sound/soc/qcom/qdsp6/q6prm.h                  |   1 +
 10 files changed, 399 insertions(+), 5 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

* [PATCH v4 3/4] dt-bindings: pinctrl: qcom,hawi-lpass-lpi-pinctrl: Add Hawi LPI pinctrl
From: Prasad Kumpatla @ 2026-07-20 13:05 UTC (permalink / raw)
  To: Bartosz Golaszewski, Bjorn Andersson, 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,
	Krzysztof Kozlowski
In-Reply-To: <20260720130511.493295-1-prasad.kumpatla@oss.qualcomm.com>

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.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
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

* [PATCH v4 4/4] pinctrl: qcom: hawi-lpass-lpi: add Hawi LPASS LPI TLMM
From: Prasad Kumpatla @ 2026-07-20 13:05 UTC (permalink / raw)
  To: Bartosz Golaszewski, Bjorn Andersson, 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
In-Reply-To: <20260720130511.493295-1-prasad.kumpatla@oss.qualcomm.com>

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

* [PATCH v4 1/4] ASoC: dt-bindings: qcom: add LPASS LPR vote clock ID
From: Prasad Kumpatla @ 2026-07-20 13:05 UTC (permalink / raw)
  To: Bartosz Golaszewski, Bjorn Andersson, 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
In-Reply-To: <20260720130511.493295-1-prasad.kumpatla@oss.qualcomm.com>

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.

Drop Q6AFE_MAX_CLK_ID from the bindings since it is not used in-tree.

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 | 2 +-
 1 file changed, 1 insertion(+), 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..ce5e8589d 100644
--- a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
+++ b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
@@ -236,8 +236,8 @@
 #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 LPASS_CLK_ATTRIBUTE_INVALID		0x0
 #define LPASS_CLK_ATTRIBUTE_COUPLE_NO		0x1
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH v2 2/4] arm64: dts: qcom: shikra-cqm-evk: Enable display and add ili7807s panel
From: Dmitry Baryshkov @ 2026-07-20 13:06 UTC (permalink / raw)
  To: Arpit Saini
  Cc: Nabige Aala, Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-arm-msm, devicetree,
	linux-kernel
In-Reply-To: <cdeffa46-3f9f-4956-8548-bdd158720307@oss.qualcomm.com>

On Fri, Jul 10, 2026 at 06:36:10PM +0530, Arpit Saini wrote:
> Hi Dmitry,
> 
> On 7/10/2026 6:19 PM, Dmitry Baryshkov wrote:
> > On Mon, Jul 06, 2026 at 11:34:42AM +0530, Nabige Aala wrote:
> > > From: Arpit Saini <arpit.saini@oss.qualcomm.com>
> > > 
> > > Enable the Qualcomm Shikra MDSS display subsystem on the Shikra CQM EVK
> > > board and add the DLC0697 MIPI DSI display panel node. Pin pm4125_l5
> > > to 1.232V with regulator-allow-set-load for DSI PHY PLL stability.
> > > 
> > > Signed-off-by: Arpit Saini <arpit.saini@oss.qualcomm.com>
> > > Signed-off-by: Nabige Aala <nabige.aala@oss.qualcomm.com>
> > > ---
> > >   arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts | 126 ++++++++++++++++++++++++++++
> > >   1 file changed, 126 insertions(+)
> > > +
> > > +	panel_bl_en: panel-bl-en-state {
> > > +		pins = "gpio91";
> > > +		function = "gpio";
> > > +		drive-strength = <2>;
> > > +		bias-disable;
> > > +		output-high;
> > > +	};
> > > +
> > > +	panel_bl_en_suspend: panel-bl-en-suspend-state {
> > > +		pins = "gpio91";
> > > +		function = "gpio";
> > > +		drive-strength = <2>;
> > > +		bias-pull-down;
> > > +		output-low;
> > > +	};
> > Is it an actual GPIO going to the panel or is it a regulator on one of
> > the daughter / whatever cards?
> 
> This GPIO is part of the daughter card, it is not going to the panel.

Then it's not related to the panel too.

-- 
With best wishes
Dmitry

^ permalink raw reply

* Re: [PATCH v3 0/2] drm/panel: Add Novatek NT36536 panel driver
From: Neil Armstrong @ 2026-07-20 13:09 UTC (permalink / raw)
  To: Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Pengyu Luo
  Cc: Neil Armstrong, dri-devel, devicetree, linux-kernel
In-Reply-To: <20260709142846.12463-1-mitltlatltl@gmail.com>

Hi,

On Thu, 09 Jul 2026 22:28:44 +0800, Pengyu Luo wrote:
> Add a driver for panels using the Novatek NT36536 Display Driver IC,
> including support for the CSOT PP8807HB1-1, a dual-link 10-bit panel
> found in LENOVO Legion Y700 Gen4.

Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next)

[1/2] dt-bindings: display: panel: Add Novatek NT36536
      https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/bebb0bac0b0fd0ca39c640462a6334b07bd093b5
[2/2] drm/panel: Add Novatek NT36536 panel driver
      https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/0355a14085b93260a2211d7da9a79ddb2fd85556

-- 
Neil

^ permalink raw reply

* Re: [PATCH v2 1/7] dt-bindings: reset: Add MT6589 toprgu reset IDs
From: AngeloGioacchino Del Regno @ 2026-07-20 13:11 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Luca Leonardo Scorcia
  Cc: linux-mediatek, Wim Van Sebroeck, Guenter Roeck, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	Philipp Zabel, linux-watchdog, devicetree, linux-kernel,
	linux-arm-kernel
In-Reply-To: <20260720-gabby-strategic-goose-b61c4e@quoll>

On 7/20/26 08:25, Krzysztof Kozlowski wrote:
> On Fri, Jul 17, 2026 at 06:39:12PM +0200, Luca Leonardo Scorcia wrote:
>> Add reset constants for the 12 MT6589 toprgu resets.
> 
> 
> This is not a single-patch patchset. Seven patches.
> 
> So one posting per 24h, so we actually have a possibility to review it.
> 

krzk, that's because Sashiko provides reviews instantly, and people just go and
fix things to make it easier on us maintainers to provide reviews (and avoiding
to see the same Sashiko complaints from us).

That said, this gets into personal preference territory, and I'm not trying to
start any conversation about that specifically...

>>
>> Signed-off-by: Luca Leonardo Scorcia <l.scorcia@gmail.com>
>> ---
>>   .../reset/mediatek,mt6589-resets.h            | 24 +++++++++++++++++++
>>   1 file changed, 24 insertions(+)
>>   create mode 100644 include/dt-bindings/reset/mediatek,mt6589-resets.h
>>
>> diff --git a/include/dt-bindings/reset/mediatek,mt6589-resets.h b/include/dt-bindings/reset/mediatek,mt6589-resets.h
>> new file mode 100644
>> index 000000000000..ee08c39df513
>> --- /dev/null
>> +++ b/include/dt-bindings/reset/mediatek,mt6589-resets.h
> 
> 
> Why is this header being added outside of patch documenting compatible?
> You have entire commit msg to say something useful instead of repeating
> the subject.

Because he wrote it all in the cover letter... which is something that gets
read right now, but gets lost once the commits are picked - so all context and
explaining are completely lost.

Luca, that's why krzk is complaining :-)

Just write the information in each commit's description, so that it doesn't get
lost, and so that the next one trying to understand what went on with the toprgu
can just read it there. :-)

Cheers,
Angelo

^ permalink raw reply

* Re: [PATCH 5/5] drm: panel: jd9365da: Add DCLTek 300250 9.35in display
From: Neil Armstrong @ 2026-07-20 13:11 UTC (permalink / raw)
  To: Marc-Olivier Champagne, Jagan Teki, Jessica Zhang, David Airlie,
	Simona Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley
  Cc: Hugo Villeneuve, dri-devel, devicetree, linux-kernel,
	Jerome Oufella, Felix Boucher, Quentin Lehoux
In-Reply-To: <20260708213500.1867092-6-marc-olivier.champagne@savoirfairelinux.com>

On 7/8/26 23:35, Marc-Olivier Champagne wrote:
> The DCLTek dt300250 is a LCD panel using the jd9365da controller.
> Add the panel to the driver.
> 
> Suggested-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
> Signed-off-by: Marc-Olivier Champagne <marc-olivier.champagne@savoirfairelinux.com>
> ---
>   .../gpu/drm/panel/panel-jadard-jd9365da-h3.c  | 246 ++++++++++++++++++
>   1 file changed, 246 insertions(+)
> 
> diff --git a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c
> index a79dc8f8d5af..970c64d6054d 100644
> --- a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c
> +++ b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c
> @@ -2931,6 +2931,248 @@ static const struct jadard_panel_desc waveshare_10_1_inch_b_desc = {
>   		MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
>   };
>   
> +static int dcltek_dt300250_init_cmds(struct jadard *jadard)
> +{
> +	struct mipi_dsi_multi_context dsi_ctx = { .dsi = jadard->dsi };
> +
> +	jd9365da_switch_page(&dsi_ctx, 0x00);
> +	jadard_enable_standard_cmds(&dsi_ctx);
> +
> +	jd9365da_switch_page(&dsi_ctx, 0x01);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x00);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x01, 0x2B);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x03, 0x10);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x04, 0x2B);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0C, 0x74);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x17, 0x00);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x18, 0xCF);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x19, 0x01);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1A, 0x00);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1B, 0xCF);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1C, 0x01);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x24, 0xFE);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x37, 0x09);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x38, 0x04);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x39, 0x00);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3A, 0x01);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3C, 0x5C);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3D, 0xFF);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3E, 0xFF);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3F, 0x7F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x40, 0x02);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x41, 0xC8);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x42, 0x66);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x43, 0x10);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x44, 0x0F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x45, 0x28);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x55, 0x02);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x57, 0x8D);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x59, 0x0A);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5A, 0x29);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5B, 0x1A);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5D, 0x7F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5E, 0x65);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5F, 0x53);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x60, 0x45);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x61, 0x3E);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x62, 0x30);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x63, 0x33);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x64, 0x1F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x65, 0x3B);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x66, 0x3C);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x67, 0x3F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x68, 0x5D);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x69, 0x49);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6A, 0x4D);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6B, 0x3D);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6C, 0x37);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6D, 0x28);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6E, 0x15);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6F, 0x00);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x70, 0x7F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x71, 0x65);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x72, 0x53);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x73, 0x45);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x74, 0x3E);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x75, 0x30);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x76, 0x33);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x77, 0x1F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x78, 0x3B);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x79, 0x3C);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7A, 0x3F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7B, 0x5D);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7C, 0x49);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7D, 0x4D);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7E, 0x3D);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7F, 0x44);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x80, 0x28);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x81, 0x15);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x82, 0x00);
> +
> +	jd9365da_switch_page(&dsi_ctx, 0x02);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x41);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x01, 0x5F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x02, 0x5F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x03, 0x4B);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x04, 0x5F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x05, 0x5C);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x06, 0x5F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x07, 0x49);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x08, 0x5F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x09, 0x5A);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0A, 0x5F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0B, 0x47);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0C, 0x5F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0D, 0x4F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0E, 0x5F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0F, 0x45);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x10, 0x5F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x11, 0x4D);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x12, 0x5F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x13, 0x5E);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x14, 0x51);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x15, 0x5F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x16, 0x40);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x17, 0x5F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x18, 0x5F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x19, 0x4A);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1A, 0x5F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1B, 0x5B);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1C, 0x5F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1D, 0x48);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1E, 0x5F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1F, 0x59);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x20, 0x5F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x21, 0x46);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x22, 0x5F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x23, 0x4E);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x24, 0x5F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x25, 0x44);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x26, 0x5F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x27, 0x4C);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x28, 0x5F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x29, 0x5E);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2A, 0x50);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2B, 0x5F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2C, 0x10);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2D, 0x1F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2E, 0x1F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2F, 0x0C);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x30, 0x1F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x31, 0x04);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x32, 0x1F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x33, 0x0E);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x34, 0x1F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x35, 0x06);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x36, 0x1F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x37, 0x19);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x38, 0x1F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x39, 0x08);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3A, 0x1F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3B, 0x1B);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3C, 0x1F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3D, 0x0A);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3E, 0x1E);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3F, 0x1F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x40, 0x00);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x41, 0x1F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x42, 0x11);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x43, 0x1F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x44, 0x1F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x45, 0x0D);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x46, 0x1F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x47, 0x05);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x48, 0x1F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x49, 0x0F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4A, 0x1F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4B, 0x07);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4C, 0x1F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4D, 0x1A);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4E, 0x1F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4F, 0x09);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x50, 0x1F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x51, 0x1C);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x52, 0x1F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x53, 0x0B);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x54, 0x1E);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x55, 0x1F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x56, 0x01);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x57, 0x1F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x58, 0x40);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5B, 0x10);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5C, 0x01);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5D, 0x70);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5E, 0x01);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5F, 0x02);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x60, 0x70);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x61, 0x01);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x62, 0x02);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x63, 0x06);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x64, 0x4A);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x65, 0x56);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x66, 0x4F);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x67, 0xF7);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x68, 0x01);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x69, 0x06);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6A, 0x4A);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6B, 0x10);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6C, 0x00);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6D, 0x00);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6E, 0x00);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6F, 0x88);
> +
> +	jd9365da_switch_page(&dsi_ctx, 0x04);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x0E);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x02, 0xB3);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x09, 0x60);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0e, 0x4A);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x37, 0x58);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2b, 0x0F);
> +
> +	jd9365da_switch_page(&dsi_ctx, 0x05);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x15, 0x34);
> +	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x16, 0x76);
> +
> +	jd9365da_switch_page(&dsi_ctx, 0x00);
> +
> +	mipi_dsi_msleep(&dsi_ctx, 120);
> +
> +	mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
> +
> +	mipi_dsi_msleep(&dsi_ctx, 120);
> +
> +	mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);
> +
> +	mipi_dsi_msleep(&dsi_ctx, 20);
> +
> +	mipi_dsi_dcs_set_tear_on_multi(&dsi_ctx, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
> +
> +	return dsi_ctx.accum_err;
> +}
> +
> +static const struct jadard_panel_desc dcltek_dt300250_desc = {
> +	.mode_4ln = &(const struct drm_display_mode) {
> +		.clock		= (600 + 48 + 32 + 80) * (1600 + 18 + 6 + 23) * 60 / 1000,
> +
> +		.hdisplay	= 600,
> +		.hsync_start	= 600 + 48,
> +		.hsync_end	= 600 + 48 + 32,
> +		.htotal		= 600 + 48 + 32 + 80,
> +
> +		.vdisplay	= 1600,
> +		.vsync_start	= 1600 + 18,
> +		.vsync_end	= 1600 + 18 + 6,
> +		.vtotal		= 1600 + 18 + 6 + 23,
> +
> +		.width_mm	= 83,
> +		.height_mm	= 221,
> +		.type		= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
> +	},
> +	.lanes = 4,
> +	.format = MIPI_DSI_FMT_RGB888,
> +	.init = dcltek_dt300250_init_cmds,
> +};
> +
>   static int jadard_dsi_probe(struct mipi_dsi_device *dsi)
>   {
>   	struct device *dev = &dsi->dev;
> @@ -3039,6 +3281,10 @@ static const struct of_device_id jadard_of_match[] = {
>   		.compatible = "chongzhou,cz101b4001",
>   		.data = &cz101b4001_desc
>   	},
> +	{
> +		.compatible = "dcltek,dt300250",
> +		.data = &dcltek_dt300250_desc
> +	},
>   	{
>   		.compatible = "kingdisplay,kd101ne3-40ti",
>   		.data = &kingdisplay_kd101ne3_40ti_desc

Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>

Thanks,
Neil

^ permalink raw reply

* Re: [PATCH v4 4/4] pinctrl: qcom: hawi-lpass-lpi: add Hawi LPASS LPI TLMM
From: sashiko-bot @ 2026-07-20 13:16 UTC (permalink / raw)
  To: Prasad Kumpatla; +Cc: conor+dt, devicetree, robh
In-Reply-To: <20260720130511.493295-5-prasad.kumpatla@oss.qualcomm.com>

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

Pre-existing issues:
- [High] Use of destroyed mutex during device removal or probe failure.
--

--- Patch [4]: [PATCH v4 4/4] pinctrl: qcom: hawi-lpass-lpi: add Hawi LPASS LPI TLMM ---
commit d1a3c124f6b76999c46378d71d6ae4c570d93507
Author: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>

pinctrl: qcom: hawi-lpass-lpi: add Hawi LPASS LPI TLMM

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 various mux functions.

> 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
> @@ -0,0 +1,244 @@
[ ... ]
> +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,

[Severity: High]
This is a pre-existing issue and was not introduced by the patch under review,
but since this driver uses lpi_pinctrl_remove() and lpi_pinctrl_probe()
from drivers/pinctrl/qcom/pinctrl-lpass-lpi.c, I wanted to ask about a
potential mutex lifetime issue.

During device unbind, lpi_pinctrl_remove() explicitly calls
mutex_destroy(&pctrl->lock). However, the driver uses devm_pinctrl_register()
and devm_gpiochip_add_data(), meaning the pinctrl and gpiochip subsystems
are not unregistered until after remove() returns and devres callbacks execute.

In this window, the subsystems remain active. Can a concurrent GPIO access
(e.g., from userspace via sysfs/chardev or another driver) invoke callbacks
like lpi_gpio_set() -> lpi_config_set(), which attempt to acquire the
destroyed mutex?

drivers/pinctrl/qcom/pinctrl-lpass-lpi.c:lpi_config_set() {
    ...
	guard(mutex)(&pctrl->lock);
    ...
}

The probe error path in lpi_pinctrl_probe() similarly destroys the mutex
via err_pinctrl: while the previously registered pinctrl device (via
devm_pinctrl_register) remains active until devres cleanup.

Should the driver use devm_mutex_init() instead of manual mutex_destroy()
to ensure the mutex outlives the devres-managed subsystem devices?

> +};
> +
> +module_platform_driver(lpi_pinctrl_driver);

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

^ permalink raw reply

* Re: [PATCH v4 1/4] ASoC: dt-bindings: qcom: add LPASS LPR vote clock ID
From: sashiko-bot @ 2026-07-20 13:16 UTC (permalink / raw)
  To: Prasad Kumpatla; +Cc: conor+dt, robh, devicetree
In-Reply-To: <20260720130511.493295-2-prasad.kumpatla@oss.qualcomm.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] The newly added clock ID `LPASS_HW_LPR_VOTE` (104) exceeds the driver's hardcoded `Q6DSP_MAX_CLK_ID` limit, rendering it unusable and creating an out-of-bounds array write hazard.
--

--- Patch [1]: [PATCH v4 1/4] ASoC: dt-bindings: qcom: add LPASS LPR vote clock ID ---
commit de8b22fd20a65bf92d9b09b0009733d46893c763
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. Exposing this as a q6prm
clock ID allows clients to request the LPR vote using the existing
qcom,q6prm clock provider interface. Drop Q6AFE_MAX_CLK_ID from the
bindings since it is not used in-tree.

> diff --git a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
> index 45850f2d43425..ce5e8589dd1a7 100644
> --- a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
> +++ b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
> @@ -236,8 +236,8 @@
>  #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]
With LPASS_HW_LPR_VOTE being set to 104, does this exceed the driver's maximum
clock limit?

Looking at sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c, Q6DSP_MAX_CLK_ID is
set to 104:

sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c:
#define Q6DSP_MAX_CLK_ID			104

This causes q6dsp_of_clk_hw_get() to reject the new clock ID:

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);
	}
    ...
}

Will this also cause an out of bounds write during probe if the ID is used?

The clock array is sized with Q6DSP_MAX_CLK_ID:

sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c:
struct q6dsp_cc {
	struct device *dev;
	struct q6dsp_clk *clks[Q6DSP_MAX_CLK_ID];
	const struct q6dsp_clk_desc *desc;
};

If ID 104 is added to the driver's clock array in the future,
q6dsp_clock_dev_probe() will write past the end of the clks array,
overwriting the adjacent desc pointer.

>  
> -#define Q6AFE_MAX_CLK_ID			104
>  
>  #define LPASS_CLK_ATTRIBUTE_INVALID		0x0
>  #define LPASS_CLK_ATTRIBUTE_COUPLE_NO		0x1

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

^ permalink raw reply

* Re: (subset) [PATCH v2 0/5] spi: atmel-quadspi: add support for LAN969x
From: Mark Brown @ 2026-07-19 21:15 UTC (permalink / raw)
  To: robh, krzk+dt, conor+dt, nicolas.ferre, alexandre.belloni,
	claudiu.beznea, tudor.ambarus, linux-spi, devicetree,
	linux-arm-kernel, linux-kernel, daniel.machon, Robert Marko
  Cc: luka.perkov
In-Reply-To: <20260709112006.390742-1-robert.marko@sartura.hr>

On Thu, 09 Jul 2026 13:19:06 +0200, Robert Marko wrote:
> spi: atmel-quadspi: add support for LAN969x
> 
> This series adds QSPI support for the Microchip LAN969x which has two QSPI
> controllers based on SAMA7G5.
> 
> It requires pad calibration, supports DMA, and supports 100 MHz operation.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-7.3

Thanks!

[1/5] dt-bindings: spi: Document LAN969x QSPI
      https://git.kernel.org/broonie/spi/c/f718ea6cb3f3
[2/5] spi: atmel-quadspi: add controller init callback
      https://git.kernel.org/broonie/spi/c/cbbd5a945e85
[3/5] spi: atmel-quadspi: use init callback for gclk variants
      https://git.kernel.org/broonie/spi/c/b881f1d8d1df
[4/5] spi: atmel-quadspi: add LAN969x QSPI support
      https://git.kernel.org/broonie/spi/c/a3e4130b6ef9

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


^ permalink raw reply

* Re: [PATCH 1/3] dt-bindings: soc: mediatek: pwrap: Add compatible for MT6589 SoC
From: AngeloGioacchino Del Regno @ 2026-07-20 13:27 UTC (permalink / raw)
  To: Akari Tsuyukusa, Sen Chu, Sean Wang, Macpaul Lin, Lee Jones,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	Flora Fu, Alexandre Mergnat
  Cc: open list:MEDIATEK BOARD LEVEL SHUTDOWN DRIVERS,
	open list:MULTIFUNCTION DEVICES (MFD),
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:ARM/Mediatek SoC support,
	moderated list:ARM/Mediatek SoC support,
	moderated list:ARM/Mediatek SoC support
In-Reply-To: <20260716171733.300885-2-akkun11.open@gmail.com>

On 7/16/26 19:17, Akari Tsuyukusa wrote:
> Add compatible string for MediaTek MT6589 PWRAP.
> Also update the description since MT6589 has pwrap bridge.
> 
> Signed-off-by: Akari Tsuyukusa <akkun11.open@gmail.com>
> ---
>   .../devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml     | 5 +++--
>   1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml
> index e7c4a3984c60..a487ed39e6cb 100644
> --- a/Documentation/devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml
> +++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml
> @@ -19,8 +19,8 @@ description:
>   
>     IP Pairing
>   
> -  On MT8135 the pins of some SoC internal peripherals can be on the PMIC.
> -  The signals of these pins are routed over the SPI bus using the pwrap
> +  On MT6589 and MT8135, the pins of some SoC internal peripherals can be on the

Soon, this will become

"On MT6589, MT8135, MT1234, MT3456, MT...." :-)

So, perhaps, it's a better idea if we say:

"In some SoCs, some of the internal peripherals may be accessible only
through the PMIC.
The signals of these pins are routed (blahblah)"

Cheers,
Angelo


^ permalink raw reply

* Re: [PATCH 3/3] soc: mediatek: pwrap: add MT6589 PWARP and MT6320 PMIC support
From: AngeloGioacchino Del Regno @ 2026-07-20 13:27 UTC (permalink / raw)
  To: Akari Tsuyukusa, Sen Chu, Sean Wang, Macpaul Lin, Lee Jones,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	Flora Fu, Alexandre Mergnat
  Cc: open list:MEDIATEK BOARD LEVEL SHUTDOWN DRIVERS,
	open list:MULTIFUNCTION DEVICES (MFD),
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:ARM/Mediatek SoC support,
	moderated list:ARM/Mediatek SoC support,
	moderated list:ARM/Mediatek SoC support
In-Reply-To: <20260716171733.300885-4-akkun11.open@gmail.com>

On 7/16/26 19:17, Akari Tsuyukusa wrote:
> Add support for MediaTek MT6589 PWRAP and MT6320 PMIC which are used
> together.
> 
> Since the PWRAP Bridge hardware on MT6589 is identical to the one on
> MT8135, refactor the existing register definitions:
> - Rename the MT8135-specific "PWRAP_MT8135_BRIDGE_" prefix to a generic
>    "PWRAP_BRIDGE_" prefix to reflect that they are shared across SoCs.
> - Add the full set of PWRAP Bridge registers to match the hardware
>    specification, rather than defining only a subset of them.
> 
> Signed-off-by: Akari Tsuyukusa <akkun11.open@gmail.com>
> ---
>   drivers/soc/mediatek/mtk-pmic-wrap.c | 292 +++++++++++++++++++++------
>   1 file changed, 235 insertions(+), 57 deletions(-)
> 
> diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
> index 0bcd85826375..3a5b007d60f5 100644
> --- a/drivers/soc/mediatek/mtk-pmic-wrap.c
> +++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
> @@ -17,15 +17,31 @@
>   #define PWRAP_POLL_DELAY_US	10
>   #define PWRAP_POLL_TIMEOUT_US	10000
>   
> -#define PWRAP_MT8135_BRIDGE_IORD_ARB_EN		0x4
> -#define PWRAP_MT8135_BRIDGE_WACS3_EN		0x10
> -#define PWRAP_MT8135_BRIDGE_INIT_DONE3		0x14
> -#define PWRAP_MT8135_BRIDGE_WACS4_EN		0x24
> -#define PWRAP_MT8135_BRIDGE_INIT_DONE4		0x28
> -#define PWRAP_MT8135_BRIDGE_INT_EN		0x38
> -#define PWRAP_MT8135_BRIDGE_TIMER_EN		0x48
> -#define PWRAP_MT8135_BRIDGE_WDT_UNIT		0x50
> -#define PWRAP_MT8135_BRIDGE_WDT_SRC_EN		0x54

Yeah I understand why you're renaming those, but choose:

a. You avoid renaming and add the rest as PWRAP_MT8135_XXXX; or
b. You make two commits, one for the rename (and explaining why) and one
    for introducing MT6589 support.

Your choice.

> +/* MT6589 and MT8135 specific PWARP Bridge registers */
> +#define PWRAP_BRIDGE_IARB_INIT		0x0
> +#define PWRAP_BRIDGE_IORD_ARB_EN	0x4
> +#define PWRAP_BRIDGE_IARB_STA0		0x8
> +#define PWRAP_BRIDGE_IARB_STA1		0xc
> +#define PWRAP_BRIDGE_WACS3_EN		0x10
> +#define PWRAP_BRIDGE_INIT_DONE3		0x14
> +#define PWRAP_BRIDGE_WACS3_CMD		0x18
> +#define PWRAP_BRIDGE_WACS3_RDATA	0x1c
> +#define PWRAP_BRIDGE_WACS3_VLDCLR	0x20
> +#define PWRAP_BRIDGE_WACS4_EN		0x24
> +#define PWRAP_BRIDGE_INIT_DONE4		0x28
> +#define PWRAP_BRIDGE_WACS4_CMD		0x2c
> +#define PWRAP_BRIDGE_WACS4_RDATA	0x30
> +#define PWRAP_BRIDGE_WACS4_VLDCLR	0x34
> +#define PWRAP_BRIDGE_INT_EN		0x38
> +#define PWRAP_BRIDGE_INT_FLG_RAW	0x3c
> +#define PWRAP_BRIDGE_INT_FLG		0x40
> +#define PWRAP_BRIDGE_INT_CLR		0x44
> +#define PWRAP_BRIDGE_TIMER_EN		0x48
> +#define PWRAP_BRIDGE_TIMER_STA		0x4c
> +#define PWRAP_BRIDGE_WDT_UNIT		0x50
> +#define PWRAP_BRIDGE_WDT_SRC_EN		0x54
> +#define PWRAP_BRIDGE_WDT_FLG		0x58
> +#define PWRAP_BRIDGE_DEBUG_INT_SEL	0x5c
>   
>   /* macro for wrapper status */
>   #define PWRAP_GET_WACS_RDATA(x)		(((x) >> 0) & 0x0000ffff)
> @@ -100,6 +116,24 @@ enum dew_regs {
>   	PWRAP_DEW_CIPHER_MODE,
>   	PWRAP_DEW_CIPHER_SWRST,
>   
> +	/* MT6320 only regs */
> +	PWRAP_DEW_CIPHER_IV0,
> +	PWRAP_DEW_CIPHER_IV1,
> +	PWRAP_DEW_CIPHER_IV2,
> +	PWRAP_DEW_CIPHER_IV3,
> +	PWRAP_DEW_CIPHER_IV4,
> +	PWRAP_DEW_CIPHER_IV5,
> +
> +	/* MT6320 and MT6397 only regs */
> +	PWRAP_DEW_EVENT_OUT_EN,
> +	PWRAP_DEW_EVENT_SRC_EN,
> +	PWRAP_DEW_EVENT_SRC,
> +	PWRAP_DEW_EVENT_FLAG,
> +	PWRAP_DEW_MON_FLAG_SEL,
> +	PWRAP_DEW_EVENT_TEST,
> +	PWRAP_DEW_CIPHER_LOAD,
> +	PWRAP_DEW_CIPHER_START,
> +
>   	/* MT6323 only regs */
>   	PWRAP_DEW_CIPHER_EN,
>   	PWRAP_DEW_RDDMY_NO,
> @@ -142,16 +176,34 @@ enum dew_regs {
>   	PWRAP_DEW_RG_WDATA_MASK,
>   	PWRAP_DEW_RG_SPI_RECORD_CLR,
>   	PWRAP_DEW_RG_CMD_ALERT_CLR,
> +};
>   
> -	/* MT6397 only regs */
> -	PWRAP_DEW_EVENT_OUT_EN,
> -	PWRAP_DEW_EVENT_SRC_EN,
> -	PWRAP_DEW_EVENT_SRC,
> -	PWRAP_DEW_EVENT_FLAG,
> -	PWRAP_DEW_MON_FLAG_SEL,
> -	PWRAP_DEW_EVENT_TEST,
> -	PWRAP_DEW_CIPHER_LOAD,
> -	PWRAP_DEW_CIPHER_START,
> +static const u32 mt6320_regs[] = {
> +	[PWRAP_DEW_EVENT_OUT_EN] =	0x0000,
> +	[PWRAP_DEW_DIO_EN] =		0x0002,
> +	[PWRAP_DEW_EVENT_SRC_EN] =	0x0004,
> +	[PWRAP_DEW_EVENT_SRC] =		0x0006,
> +	[PWRAP_DEW_EVENT_FLAG] =	0x0008,
> +	[PWRAP_DEW_READ_TEST] =		0x000a,
> +	[PWRAP_DEW_WRITE_TEST] =	0x000c,
> +	[PWRAP_DEW_CRC_EN] =		0x000e,
> +	[PWRAP_DEW_CRC_VAL] =		0x0010,
> +	[PWRAP_DEW_MON_GRP_SEL] =	0x0012,
> +	[PWRAP_DEW_MON_FLAG_SEL] =	0x0014,
> +	[PWRAP_DEW_EVENT_TEST] =	0x0016,
> +	[PWRAP_DEW_CIPHER_KEY_SEL] =	0x0018,
> +	[PWRAP_DEW_CIPHER_IV_SEL] =	0x001a,
> +	[PWRAP_DEW_CIPHER_LOAD] =	0x001c,
> +	[PWRAP_DEW_CIPHER_START] =	0x001e,
> +	[PWRAP_DEW_CIPHER_RDY] =	0x0020,
> +	[PWRAP_DEW_CIPHER_MODE] =	0x0022,
> +	[PWRAP_DEW_CIPHER_SWRST] =	0x0024,
> +	[PWRAP_DEW_CIPHER_IV0] =	0x0026,
> +	[PWRAP_DEW_CIPHER_IV1] =	0x0028,
> +	[PWRAP_DEW_CIPHER_IV2] =	0x002a,
> +	[PWRAP_DEW_CIPHER_IV3] =	0x002c,
> +	[PWRAP_DEW_CIPHER_IV4] =	0x002e,
> +	[PWRAP_DEW_CIPHER_IV5] =	0x0030,
>   };
>   
>   static const u32 mt6323_regs[] = {
> @@ -386,6 +438,22 @@ enum pwrap_regs {
>   	PWRAP_EINT_STA1_ADR,
>   	PWRAP_SWINF_2_WDATA_31_0,
>   	PWRAP_SWINF_2_RDATA_31_0,
> +	PWRAP_DVFS_ADR0,
> +	PWRAP_DVFS_WDATA0,
> +	PWRAP_DVFS_ADR1,
> +	PWRAP_DVFS_WDATA1,
> +	PWRAP_DVFS_ADR2,
> +	PWRAP_DVFS_WDATA2,
> +	PWRAP_DVFS_ADR3,
> +	PWRAP_DVFS_WDATA3,
> +	PWRAP_DVFS_ADR4,
> +	PWRAP_DVFS_WDATA4,
> +	PWRAP_DVFS_ADR5,
> +	PWRAP_DVFS_WDATA5,
> +	PWRAP_DVFS_ADR6,
> +	PWRAP_DVFS_WDATA6,
> +	PWRAP_DVFS_ADR7,
> +	PWRAP_DVFS_WDATA7,
>   
>   	/* MT2701 only regs */
>   	PWRAP_ADC_CMD_ADDR,
> @@ -394,6 +462,24 @@ enum pwrap_regs {
>   	PWRAP_ADC_RDATA_ADDR1,
>   	PWRAP_ADC_RDATA_ADDR2,
>   
> +	/* MT6589 only regs */
> +	PWRAP_CIPHER_IV0,
> +	PWRAP_CIPHER_IV1,
> +	PWRAP_CIPHER_IV2,
> +
> +	/* MT6589 and MT8135 only regs */
> +	PWRAP_CSHEXT,
> +	PWRAP_EVENT_IN_EN,
> +	PWRAP_EVENT_DST_EN,
> +	PWRAP_RRARB_INIT,
> +	PWRAP_RRARB_EN,
> +	PWRAP_RRARB_STA0,
> +	PWRAP_RRARB_STA1,
> +	PWRAP_EVENT_STA,
> +	PWRAP_EVENT_STACLR,
> +	PWRAP_CIPHER_LOAD,
> +	PWRAP_CIPHER_START,
> +
>   	/* MT7622 only regs */
>   	PWRAP_STA,
>   	PWRAP_CLR,
> @@ -422,38 +508,9 @@ enum pwrap_regs {
>   	PWRAP_DVFS_STEP_CTRL2,
>   	PWRAP_SPI2_CTRL,
>   
> -	/* MT8135 only regs */
> -	PWRAP_CSHEXT,
> -	PWRAP_EVENT_IN_EN,
> -	PWRAP_EVENT_DST_EN,
> -	PWRAP_RRARB_INIT,
> -	PWRAP_RRARB_EN,
> -	PWRAP_RRARB_STA0,
> -	PWRAP_RRARB_STA1,
> -	PWRAP_EVENT_STA,
> -	PWRAP_EVENT_STACLR,
> -	PWRAP_CIPHER_LOAD,
> -	PWRAP_CIPHER_START,
> -

Why are you reordering stuff around? I don't understand.

If you have a reason, make sure it's a good one, and make a different commit
just for the reordering, because otherwise the diff for this one gets a bit
hard to read.


Cheers,
Angelo

>   	/* MT8173 only regs */
>   	PWRAP_RDDMY,
>   	PWRAP_SI_CK_CON,
> -	PWRAP_DVFS_ADR0,
> -	PWRAP_DVFS_WDATA0,
> -	PWRAP_DVFS_ADR1,
> -	PWRAP_DVFS_WDATA1,
> -	PWRAP_DVFS_ADR2,
> -	PWRAP_DVFS_WDATA2,
> -	PWRAP_DVFS_ADR3,
> -	PWRAP_DVFS_WDATA3,
> -	PWRAP_DVFS_ADR4,
> -	PWRAP_DVFS_WDATA4,
> -	PWRAP_DVFS_ADR5,
> -	PWRAP_DVFS_WDATA5,
> -	PWRAP_DVFS_ADR6,
> -	PWRAP_DVFS_WDATA6,
> -	PWRAP_DVFS_ADR7,
> -	PWRAP_DVFS_WDATA7,
>   	PWRAP_SPMINF_STA,
>   	PWRAP_CIPHER_EN,

^ permalink raw reply

* Re: [PATCH v2 4/8] dt-bindings: mfd: syscon: add ESWIN EIC7700 compatible
From: Pinkesh Vaghela @ 2026-07-20 13:28 UTC (permalink / raw)
  To: Lee Jones
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Andi Shyti,
	Mika Westerberg, linux-i2c@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-riscv@lists.infradead.org, Min Lin, Yulin Lu,
	Samuel Holland, Darshan Prajapati, Pritesh Patel
In-Reply-To: <20260716122833.GE1260374@google.com>

Hi Lee,

On Thursday, July 16, 2026 5:59 PM, Lee Jones wrote:
> On Mon, 06 Jul 2026, Pinkesh Vaghela wrote:
> 
> > Document ESWIN EIC7700 SoC compatible for syscon registers.
> >
> > Acked-by: Conor Dooley <conor.dooley@microchip.com>
> > Signed-off-by: Pinkesh Vaghela <pinkesh.vaghela@einfochips.com>
> > ---
> >  Documentation/devicetree/bindings/mfd/syscon.yaml | 2 ++
> >  1 file changed, 2 insertions(+)
> 
> Still doesn't apply.  What tree did you rebase on?
> 
> Whatever you rebase on needs to have the following commit:
> 
>    1d02f2a79ebe ("dt-bindings: mfd: syscon: Drop custom select for older
> dtschema")

We rebased the patches to v7.2-rc2 on master branch of mainline tree
before sending v2.
We see that the patch series you are referring to is not present in
v7.2-rc4 as well. However, they are present in linux-next.

Could you please suggest on which tree should I rebase and send this patch?

Regards,
Pinkesh

> 
> --
> Lee Jones

^ permalink raw reply

* Re: [PATCH 3/3] nvmem: mtk-efuse: add mt6572 support
From: Roman Vivchar @ 2026-07-20 13:33 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno
  Cc: Srinivas Kandagatla, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, Andrew-CT Chen, Lala Lin,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <2aa16ed7-5d36-4e78-929e-84b9d6befe77@collabora.com>

Hi Angelo,

On Monday, July 20th, 2026 at 3:48 PM, AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> wrote:

> On 7/15/26 16:27, Roman Vivchar via B4 Relay wrote:
> > From: Roman Vivchar <rva333@protonmail.com>
> >
> > Add a platform data struct for the efuse controller.
> >
> > Signed-off-by: Roman Vivchar <rva333@protonmail.com>
> > ---
> >   drivers/nvmem/mtk-efuse.c | 6 ++++++
> >   1 file changed, 6 insertions(+)
> >
> > diff --git a/drivers/nvmem/mtk-efuse.c b/drivers/nvmem/mtk-efuse.c
> > index 1462f2760818..a79434608465 100644
> > --- a/drivers/nvmem/mtk-efuse.c
> > +++ b/drivers/nvmem/mtk-efuse.c
> > @@ -124,6 +124,11 @@ static int mtk_efuse_probe(struct platform_device *pdev)
> >   	return 0;
> >   }
> >
> > +static const struct mtk_efuse_pdata mtk_mt6572_efuse_pdata = {
> > +	.uses_post_processing = false,
>
> Are you sure this SoC (or any other compatible with it) doesn't have any GPU speed
> binning?
>
> If you're really sure
>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

It does, but we can't really rely on it. The GPU is complicated here...

Something like this:
- mfgcfg
  ^- mfg_pre ('safe' UNIVPLL div or 'unsafe' mfg mux)
     ^- mfg (if you're here and your chip is NOT mt6572w then be prepared
	         for crashes)
        ^- whpll (or any other parent, but downstream uses WHPLL as GPU
                  clock source)

There is GPU speedbin, but it means either GPU scaling is fine and mfg
mux is safe (0, unfused) or that the GPU must stay at UNIVPLL divider
(1, fused off).

My current solution is using assigned-clocks and assigned-clock-parents
in the each board which we've tested manually.
&gpu {
        /* Switch to WHPLL */
        assigned-clocks = <&topckgen CLK_TOP_MFG_SEL>,
                          <&topckgen CLK_TOP_MFG_PRE_SEL>;
        assigned-clock-parents = <&topckgen CLK_TOP_MFG_PRE_500M>,
                                 <&topckgen CLK_TOP_MFG_SEL>;

        operating-points-v2 = <&gpu_opp_table>;
        nvmem-cells = <&gpu_speedbin>;
        nvmem-cell-names = "speedbin";
		status = "okay";
};

On boards with GPU frequency fused off the entire setup is omitted
except status = "okay";

Let me know if you have some other idea how this should be handled.

Best regards,
Roman

^ permalink raw reply

* [PATCH v16 01/12] media: mediatek: jpeg: fix jpeg cores' amounts setting
From: Kyrie Wu @ 2026-07-20 13:34 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
	Bin Liu, kyrie wu, Hans Verkuil, irui wang, Nicolas Dufresne,
	linux-media, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek
  Cc: Kyrie Wu
In-Reply-To: <20260720133432.1042046-1-kyrie.wu@mediatek.com>

Different ICs have different amounts of cores,
use a variable to set the cores' amounts.

Fixes: 934e8bccac95 ("mtk-jpegenc: support jpegenc multi-hardware")
Fixes: 0fa49df4222f ("media: mtk-jpegdec: support jpegdec multi-hardware")
Signed-off-by: Kyrie Wu <kyrie.wu@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c  | 11 ++++++-----
 drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h  |  2 ++
 .../media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c    |  2 ++
 .../media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c    |  2 ++
 4 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
index d147ec483..41c4cf8dc 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -1325,7 +1325,8 @@ static int mtk_jpeg_probe(struct platform_device *pdev)
 		for_each_child_of_node(pdev->dev.of_node, child)
 			num_child++;
 
-		atomic_set(&jpeg->hw_rdy, num_child);
+		jpeg->max_hw_count = num_child;
+		atomic_set(&jpeg->hw_rdy, 0);
 		atomic_set(&jpeg->hw_index, 0);
 
 		jpeg->workqueue = alloc_ordered_workqueue(MTK_JPEG_NAME,
@@ -1462,7 +1463,7 @@ static int mtk_jpegenc_get_hw(struct mtk_jpeg_ctx *ctx)
 	int i;
 
 	spin_lock_irqsave(&jpeg->hw_lock, flags);
-	for (i = 0; i < MTK_JPEGENC_HW_MAX; i++) {
+	for (i = 0; i < jpeg->max_hw_count; i++) {
 		comp_jpeg = jpeg->enc_hw_dev[i];
 		if (comp_jpeg->hw_state == MTK_JPEG_HW_IDLE) {
 			hw_id = i;
@@ -1509,7 +1510,7 @@ static int mtk_jpegdec_get_hw(struct mtk_jpeg_ctx *ctx)
 	int i;
 
 	spin_lock_irqsave(&jpeg->hw_lock, flags);
-	for (i = 0; i < MTK_JPEGDEC_HW_MAX; i++) {
+	for (i = 0; i < jpeg->max_hw_count; i++) {
 		comp_jpeg = jpeg->dec_hw_dev[i];
 		if (comp_jpeg->hw_state == MTK_JPEG_HW_IDLE) {
 			hw_id = i;
@@ -1592,7 +1593,7 @@ static void mtk_jpegenc_worker(struct work_struct *work)
 		jpeg_work);
 	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 
-	for (i = 0; i < MTK_JPEGENC_HW_MAX; i++)
+	for (i = 0; i < jpeg->max_hw_count; i++)
 		comp_jpeg[i] = jpeg->enc_hw_dev[i];
 	i = 0;
 
@@ -1687,7 +1688,7 @@ static void mtk_jpegdec_worker(struct work_struct *work)
 	struct mtk_jpeg_fb fb;
 	unsigned long flags;
 
-	for (i = 0; i < MTK_JPEGDEC_HW_MAX; i++)
+	for (i = 0; i < jpeg->max_hw_count; i++)
 		comp_jpeg[i] = jpeg->dec_hw_dev[i];
 	i = 0;
 
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
index 02ed0ed5b..6be5cf30d 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
@@ -212,6 +212,7 @@ struct mtk_jpegdec_comp_dev {
  * @reg_decbase:	jpg decode register base addr
  * @dec_hw_dev:	jpg decode hardware device
  * @hw_index:		jpg hw index
+ * @max_hw_count:	jpeg hw-core count
  */
 struct mtk_jpeg_dev {
 	struct mutex		lock;
@@ -234,6 +235,7 @@ struct mtk_jpeg_dev {
 	void __iomem *reg_decbase[MTK_JPEGDEC_HW_MAX];
 	struct mtk_jpegdec_comp_dev *dec_hw_dev[MTK_JPEGDEC_HW_MAX];
 	atomic_t hw_index;
+	u32 max_hw_count;
 };
 
 /**
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
index 32372781d..9ca68cde4 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
@@ -668,6 +668,8 @@ static int mtk_jpegdec_hw_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, dev);
 	pm_runtime_enable(&pdev->dev);
 
+	atomic_inc(&master_dev->hw_rdy);
+
 	return 0;
 }
 
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
index b6f5b2249..a3f414f92 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
@@ -390,6 +390,8 @@ static int mtk_jpegenc_hw_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, dev);
 	pm_runtime_enable(&pdev->dev);
 
+	atomic_inc(&master_dev->hw_rdy);
+
 	return 0;
 }
 
-- 
2.51.0.windows.2


^ permalink raw reply related

* [PATCH v16 02/12] media: mediatek: jpeg: fix jpeg buffer payload size setting
From: Kyrie Wu @ 2026-07-20 13:34 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
	Bin Liu, kyrie wu, Hans Verkuil, irui wang, Nicolas Dufresne,
	linux-media, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek
  Cc: Kyrie Wu
In-Reply-To: <20260720133432.1042046-1-kyrie.wu@mediatek.com>

For multi-core jpegdec, if one core gets resolution change event,
the payload size, representing the size of Y/C data, needs to change.
But others are decoding at the same time and it can not be changed
immediately, which results in the payload size not matching the real
buffer length.
The payload size must be less than the real buffer length to avoid
warning logs.

Fixes: 0fa49df4222f ("media: mtk-jpegdec: support jpegdec multi-hardware")
Signed-off-by: Kyrie Wu <kyrie.wu@mediatek.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
---
 .../platform/mediatek/jpeg/mtk_jpeg_core.c    | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
index 41c4cf8dc..34135706a 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -702,6 +702,7 @@ static int mtk_jpeg_buf_prepare(struct vb2_buffer *vb)
 	struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
 	struct mtk_jpeg_q_data *q_data = NULL;
 	struct v4l2_plane_pix_format plane_fmt = {};
+	size_t max_size;
 	int i;
 
 	q_data = mtk_jpeg_get_q_data(ctx, vb->vb2_queue->type);
@@ -710,12 +711,20 @@ static int mtk_jpeg_buf_prepare(struct vb2_buffer *vb)
 
 	for (i = 0; i < q_data->fmt->colplanes; i++) {
 		plane_fmt = q_data->pix_mp.plane_fmt[i];
+		max_size = plane_fmt.sizeimage;
+
 		if (ctx->enable_exif &&
-		    q_data->fmt->fourcc == V4L2_PIX_FMT_JPEG)
-			vb2_set_plane_payload(vb, i, plane_fmt.sizeimage +
-					      MTK_JPEG_MAX_EXIF_SIZE);
-		else
-			vb2_set_plane_payload(vb, i,  plane_fmt.sizeimage);
+			q_data->fmt->fourcc == V4L2_PIX_FMT_JPEG) {
+			max_size += MTK_JPEG_MAX_EXIF_SIZE;
+
+			vb2_set_plane_payload(vb, i,
+					      MIN(vb->planes[i].length,
+						  max_size));
+		} else {
+			vb2_set_plane_payload(vb, i,
+					      MIN(plane_fmt.sizeimage,
+						  vb->planes[i].length));
+		}
 	}
 
 	return 0;
-- 
2.51.0.windows.2


^ permalink raw reply related

* [PATCH v16 00/12] Enable jpeg enc & dec multi-hardwares for MT8196
From: Kyrie Wu @ 2026-07-20 13:34 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
	Bin Liu, kyrie wu, Hans Verkuil, irui wang, Nicolas Dufresne,
	linux-media, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek
  Cc: Kyrie Wu

This series have the follow changing:
Firstly fix some bugs, including resolution change handleing, stop
streaming sw flow, fix buffer layout and clock setting to support multi-hw
jpeg working and others.
Secondly add mt8196 jpegdec and jpegenc compatible to support MT8196
kernel driver.
Lastly, Add smmu setting to support smmu and iommu at the same time.

This series has been tested with MT8196 tast test.
Encoding and decoding worked for this chip.

Patches 1 fix jpeg hw count setting to support different chips.
Patches 2 fix jpeg buffer payload setting to handle buffer
size bug while resolution changed.
Patches 3 fix jpeg dst buffer layout.
Patches 4 fix multi-core stop streaming flow
Patches 5 fix multi-core clk suspend/resume setting
Patches 6 fix buffer state update timing
Patches 7 fix decoding resolution change operation
Patches 8 fix remove buffer operation
Patches 9-11 Adds jpeg encoder and decoder compatible.
Patches 12 add jpeg smmu sid setting.
---
Changes compared with v15:
--Set max_hw_count from the DT child count and update hw_rdy from child hardware probes in patch 1.
--Fix patch 2 commit message wording per review.
--Rework patch 6 commit message per review.
--Remove redundant devm_clk_bulk_get() calls in patch 5 per review comments.
--Use %pe to print smmu_regmap error pointer in patch 12 to fix media-ci/static warnings.

Changes compared with v14:
--Rebased on top of the latest media tree

Changes compared with v13:
--Rebased on top of the latest media tree

Changes compared with v12:
--Rebased on top of the latest media tree
--fix kernel rebot build warnings in patch 5

Changes compared with v11:
--Rebased on top of the latest media tree
--Some modifications for patch v11's review comments.
--add reviewer to commit messages

Changes compared with v10:
--Rebased on top of the latest media tree
--add reviewer to commit messages

Changes compared with v9:
--Rebased on top of the latest media tree

Changes compared with v8:
--Rebased on top of the latest media tree

Changes compared with v7:
--Rebased on top of the latest media tree

Changes compared with v6:
--Rebased on top of the latest media tree

Changes compared with v5:
--reorder the patches set.
--fix commit message of patch 1-8.

Changes compared with v4:
--fix kernel robot build errors for patch 4.
--add reviewer for patch 1 and patch 2.

Changes compared with v3:
--change patch subject of jpeg encoder and decoder compatible.

Changes compared with v2:
--refactor smmu sid setting function interface
--Some modifications for patch v2's review comments.

Changes compared with v1:
--refine jpeg dt-bindings for MT8196
--optimize software code to manage jpeg HW count
--refactor smmu sid setting function interface
--Some modifications for patch v1's review comments.

Kyrie Wu (12):
  media: mediatek: jpeg: fix jpeg cores' amounts setting
  media: mediatek: jpeg: fix jpeg buffer payload size setting
  media: mediatek: jpeg: fix buffer structure size and layout
  media: mediatek: jpeg: Fix buffer completion on multi-core streaming
    stop
  media: mediatek: jpeg: Fix multi-core clk suspend and resume setting
  media: mediatek: jpeg: fix buffer state update timing
  media: mediatek: jpeg: fix resolution change event handling in decoder
  media: mediatek: jpeg: fix remove buffer removal timing for multi-core
  media: dt-bindings: mediatek,jpeg: Add mediatek, mt8196-jpgdec
    compatible
  media: dt-bindings: mediatek,jpeg: Add mediatek, mt8196-jpgenc
    compatible
  media: mediatek: jpeg: add jpeg compatible
  media: mediatek: jpeg: add jpeg smmu sid setting

 .../media/mediatek,mt8195-jpegdec.yaml        |   8 +-
 .../media/mediatek,mt8195-jpegenc.yaml        |   8 +-
 .../platform/mediatek/jpeg/mtk_jpeg_core.c    | 156 +++++++++++++-----
 .../platform/mediatek/jpeg/mtk_jpeg_core.h    |  19 ++-
 .../platform/mediatek/jpeg/mtk_jpeg_dec_hw.c  |  84 +++++++++-
 .../platform/mediatek/jpeg/mtk_jpeg_enc_hw.c  |  82 ++++++++-
 6 files changed, 300 insertions(+), 57 deletions(-)

-- 
2.51.0.windows.2


^ permalink raw reply

* [PATCH v16 04/12] media: mediatek: jpeg: Fix buffer completion on multi-core streaming stop
From: Kyrie Wu @ 2026-07-20 13:34 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
	Bin Liu, kyrie wu, Hans Verkuil, irui wang, Nicolas Dufresne,
	linux-media, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek
  Cc: Kyrie Wu
In-Reply-To: <20260720133432.1042046-1-kyrie.wu@mediatek.com>

Enhances the Mediatek JPEG driver's stability and reliability by ensuring
that all queued buffers are processed before stopping the streaming in
multi-core environments. It introduces a call to
`vb2_wait_for_all_buffers()` in the `mtk_jpeg_enc_stop_streaming()` and
`mtk_jpeg_dec_stop_streaming()` functions when the `multi_core` variant
is enabled. This change ensures that no buffers are left unprocessed,
preventing potential data loss or corruption during multi-core flow.

Fixes: 0fa49df4222f ("media: mtk-jpegdec: support jpegdec multi-hardware")
Fixes: dedc21500334 ("media: mtk-jpegdec: add jpeg decode worker interface")
Fixes: 934e8bccac95 ("mtk-jpegenc: support jpegenc multi-hardware")
Fixes: 5fb1c2361e56 ("mtk-jpegenc: add jpeg encode worker interface")
Signed-off-by: Kyrie Wu <kyrie.wu@mediatek.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
---
 drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
index 7856a556c..d0fb68bc8 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -850,8 +850,12 @@ static struct vb2_v4l2_buffer *mtk_jpeg_buf_remove(struct mtk_jpeg_ctx *ctx,
 static void mtk_jpeg_enc_stop_streaming(struct vb2_queue *q)
 {
 	struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q);
+	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 	struct vb2_v4l2_buffer *vb;
 
+	if (jpeg->variant->multi_core)
+		vb2_wait_for_all_buffers(q);
+
 	while ((vb = mtk_jpeg_buf_remove(ctx, q->type)))
 		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
 }
@@ -859,6 +863,7 @@ static void mtk_jpeg_enc_stop_streaming(struct vb2_queue *q)
 static void mtk_jpeg_dec_stop_streaming(struct vb2_queue *q)
 {
 	struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q);
+	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 	struct vb2_v4l2_buffer *vb;
 
 	/*
@@ -866,6 +871,9 @@ static void mtk_jpeg_dec_stop_streaming(struct vb2_queue *q)
 	 * Before STREAMOFF, we still have to return the old resolution and
 	 * subsampling. Update capture queue when the stream is off.
 	 */
+	if (jpeg->variant->multi_core)
+		vb2_wait_for_all_buffers(q);
+
 	if (ctx->state == MTK_JPEG_SOURCE_CHANGE &&
 	    V4L2_TYPE_IS_CAPTURE(q->type)) {
 		struct mtk_jpeg_src_buf *src_buf;
-- 
2.51.0.windows.2


^ permalink raw reply related

* [PATCH v16 03/12] media: mediatek: jpeg: fix buffer structure size and layout
From: Kyrie Wu @ 2026-07-20 13:34 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
	Bin Liu, kyrie wu, Hans Verkuil, irui wang, Nicolas Dufresne,
	linux-media, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek
  Cc: Kyrie Wu
In-Reply-To: <20260720133432.1042046-1-kyrie.wu@mediatek.com>

Updates the `buf_struct_size` in the JPEG driver to use the correct
structure `mtk_jpeg_src_buf` instead of `v4l2_m2m_buffer`, ensuring
proper handling of source buffers. The previous buffer size led to
mismatches and potential issues during video buffer handling.

Moves `frame_num` in the `mtk_jpeg_src_buf` structure to align with
other members appropriately. The first field of the driver-specific
buffer structure must be the subsystem-specificstruct
(vb2_v4l2_buffer in the case of V4L2).

Fixes: 5fb1c2361e56 ("mtk-jpegenc: add jpeg encode worker interface")
Signed-off-by: Kyrie Wu <kyrie.wu@mediatek.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
---
 drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c | 2 +-
 drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
index 34135706a..7856a556c 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -1092,7 +1092,7 @@ static int mtk_jpeg_queue_init(void *priv, struct vb2_queue *src_vq,
 	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
 	dst_vq->io_modes = VB2_DMABUF | VB2_MMAP;
 	dst_vq->drv_priv = ctx;
-	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+	dst_vq->buf_struct_size = sizeof(struct mtk_jpeg_src_buf);
 	dst_vq->ops = jpeg->variant->qops;
 	dst_vq->mem_ops = &vb2_dma_contig_memops;
 	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
index 6be5cf30d..148fd4175 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
@@ -85,10 +85,10 @@ struct mtk_jpeg_variant {
 };
 
 struct mtk_jpeg_src_buf {
-	u32 frame_num;
 	struct vb2_v4l2_buffer b;
 	struct list_head list;
 	u32 bs_size;
+	u32 frame_num;
 	struct mtk_jpeg_dec_param dec_param;
 
 	struct mtk_jpeg_ctx *curr_ctx;
-- 
2.51.0.windows.2


^ permalink raw reply related

* [PATCH v16 05/12] media: mediatek: jpeg: Fix multi-core clk suspend and resume setting
From: Kyrie Wu @ 2026-07-20 13:34 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
	Bin Liu, kyrie wu, Hans Verkuil, irui wang, Nicolas Dufresne,
	linux-media, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek
  Cc: Kyrie Wu
In-Reply-To: <20260720133432.1042046-1-kyrie.wu@mediatek.com>

The suspend/resume callback function is defined in the dev_pm_ops
structure, which is defined in platform_driver. For multiple-core
architecture, each hardware driver will register a platform_driver
structure, so it is necessary to add a suspend/resume callback
function for each hardware to support this operation.

Fixes: 934e8bccac95 ("mtk-jpegenc: support jpegenc multi-hardware")
Fixes: 0fa49df4222f ("media: mtk-jpegdec: support jpegdec multi-hardware")
Signed-off-by: Kyrie Wu <kyrie.wu@mediatek.com>
---
 .../platform/mediatek/jpeg/mtk_jpeg_core.c    | 28 +++-------
 .../platform/mediatek/jpeg/mtk_jpeg_dec_hw.c  | 55 +++++++++++++++++--
 .../platform/mediatek/jpeg/mtk_jpeg_enc_hw.c  | 53 ++++++++++++++++--
 3 files changed, 107 insertions(+), 29 deletions(-)

diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
index d0fb68bc8..a5a1f6126 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -1115,6 +1115,9 @@ static void mtk_jpeg_clk_on(struct mtk_jpeg_dev *jpeg)
 {
 	int ret;
 
+	if (jpeg->variant->multi_core)
+		return;
+
 	ret = clk_bulk_prepare_enable(jpeg->variant->num_clks,
 				      jpeg->variant->clks);
 	if (ret)
@@ -1123,6 +1126,9 @@ static void mtk_jpeg_clk_on(struct mtk_jpeg_dev *jpeg)
 
 static void mtk_jpeg_clk_off(struct mtk_jpeg_dev *jpeg)
 {
+	if (jpeg->variant->multi_core)
+		return;
+
 	clk_bulk_disable_unprepare(jpeg->variant->num_clks,
 				   jpeg->variant->clks);
 }
@@ -1648,13 +1654,6 @@ static void mtk_jpegenc_worker(struct work_struct *work)
 		goto enc_end;
 	}
 
-	ret = clk_prepare_enable(comp_jpeg[hw_id]->venc_clk.clks->clk);
-	if (ret) {
-		dev_err(jpeg->dev, "%s : %d, jpegenc clk_prepare_enable fail\n",
-			__func__, __LINE__);
-		goto enc_end;
-	}
-
 	v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
 	v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
 
@@ -1751,20 +1750,13 @@ static void mtk_jpegdec_worker(struct work_struct *work)
 	jpeg_dst_buf->frame_num = ctx->total_frame_num;
 
 	mtk_jpegdec_set_hw_param(ctx, hw_id, src_buf, dst_buf);
-	ret = pm_runtime_get_sync(comp_jpeg[hw_id]->dev);
+	ret = pm_runtime_resume_and_get(comp_jpeg[hw_id]->dev);
 	if (ret < 0) {
 		dev_err(jpeg->dev, "%s : %d, pm_runtime_get_sync fail !!!\n",
 			__func__, __LINE__);
 		goto dec_end;
 	}
 
-	ret = clk_prepare_enable(comp_jpeg[hw_id]->jdec_clk.clks->clk);
-	if (ret) {
-		dev_err(jpeg->dev, "%s : %d, jpegdec clk_prepare_enable fail\n",
-			__func__, __LINE__);
-		goto clk_end;
-	}
-
 	v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
 	v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
 
@@ -1774,7 +1766,7 @@ static void mtk_jpegdec_worker(struct work_struct *work)
 				 &dst_buf->vb2_buf, &fb)) {
 		dev_err(jpeg->dev, "%s : %d, mtk_jpeg_set_dec_dst fail\n",
 			__func__, __LINE__);
-		goto setdst_end;
+		goto set_dst_fail;
 	}
 
 	schedule_delayed_work(&comp_jpeg[hw_id]->job_timeout_work,
@@ -1795,9 +1787,7 @@ static void mtk_jpegdec_worker(struct work_struct *work)
 
 	return;
 
-setdst_end:
-	clk_disable_unprepare(comp_jpeg[hw_id]->jdec_clk.clks->clk);
-clk_end:
+set_dst_fail:
 	pm_runtime_put(comp_jpeg[hw_id]->dev);
 dec_end:
 	v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
index 9ca68cde4..970c0a30e 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
@@ -533,13 +533,12 @@ static void mtk_jpegdec_timeout_work(struct work_struct *work)
 	v4l2_m2m_buf_copy_metadata(src_buf, dst_buf);
 
 	mtk_jpeg_dec_reset(cjpeg->reg_base);
-	clk_disable_unprepare(cjpeg->jdec_clk.clks->clk);
-	pm_runtime_put(cjpeg->dev);
 	cjpeg->hw_state = MTK_JPEG_HW_IDLE;
 	atomic_inc(&master_jpeg->hw_rdy);
 	wake_up(&master_jpeg->hw_wq);
 	v4l2_m2m_buf_done(src_buf, buf_state);
 	mtk_jpegdec_put_buf(cjpeg);
+	pm_runtime_put(cjpeg->dev);
 }
 
 static irqreturn_t mtk_jpegdec_hw_irq_handler(int irq, void *priv)
@@ -547,7 +546,6 @@ static irqreturn_t mtk_jpegdec_hw_irq_handler(int irq, void *priv)
 	struct vb2_v4l2_buffer *src_buf, *dst_buf;
 	struct mtk_jpeg_src_buf *jpeg_src_buf;
 	enum vb2_buffer_state buf_state;
-	struct mtk_jpeg_ctx *ctx;
 	u32 dec_irq_ret;
 	u32 irq_status;
 	int i;
@@ -557,7 +555,6 @@ static irqreturn_t mtk_jpegdec_hw_irq_handler(int irq, void *priv)
 
 	cancel_delayed_work(&jpeg->job_timeout_work);
 
-	ctx = jpeg->hw_param.curr_ctx;
 	src_buf = jpeg->hw_param.src_buffer;
 	dst_buf = jpeg->hw_param.dst_buffer;
 	v4l2_m2m_buf_copy_metadata(src_buf, dst_buf);
@@ -580,12 +577,11 @@ static irqreturn_t mtk_jpegdec_hw_irq_handler(int irq, void *priv)
 	buf_state = VB2_BUF_STATE_DONE;
 	v4l2_m2m_buf_done(src_buf, buf_state);
 	mtk_jpegdec_put_buf(jpeg);
-	pm_runtime_put(ctx->jpeg->dev);
-	clk_disable_unprepare(jpeg->jdec_clk.clks->clk);
 
 	jpeg->hw_state = MTK_JPEG_HW_IDLE;
 	wake_up(&master_jpeg->hw_wq);
 	atomic_inc(&master_jpeg->hw_rdy);
+	pm_runtime_put(jpeg->dev);
 
 	return IRQ_HANDLED;
 }
@@ -673,11 +669,58 @@ static int mtk_jpegdec_hw_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static int mtk_jpegdec_pm_suspend(struct device *dev)
+{
+	struct mtk_jpegdec_comp_dev *jpeg = dev_get_drvdata(dev);
+
+	clk_bulk_disable_unprepare(jpeg->jdec_clk.clk_num,
+				   jpeg->jdec_clk.clks);
+
+	return 0;
+}
+
+static int mtk_jpegdec_pm_resume(struct device *dev)
+{
+	struct mtk_jpegdec_comp_dev *jpeg = dev_get_drvdata(dev);
+
+	return clk_bulk_prepare_enable(jpeg->jdec_clk.clk_num,
+				       jpeg->jdec_clk.clks);
+}
+
+static int mtk_jpegdec_suspend(struct device *dev)
+{
+	struct mtk_jpegdec_comp_dev *jpeg = dev_get_drvdata(dev);
+
+	v4l2_m2m_suspend(jpeg->master_dev->m2m_dev);
+
+	return pm_runtime_force_suspend(dev);
+}
+
+static int mtk_jpegdec_resume(struct device *dev)
+{
+	struct mtk_jpegdec_comp_dev *jpeg = dev_get_drvdata(dev);
+	int ret;
+
+	ret = pm_runtime_force_resume(dev);
+	if (ret < 0)
+		return ret;
+
+	v4l2_m2m_resume(jpeg->master_dev->m2m_dev);
+
+	return 0;
+}
+
+static const struct dev_pm_ops mtk_jpegdec_pm_ops = {
+	SYSTEM_SLEEP_PM_OPS(mtk_jpegdec_suspend, mtk_jpegdec_resume)
+	RUNTIME_PM_OPS(mtk_jpegdec_pm_suspend, mtk_jpegdec_pm_resume, NULL)
+};
+
 static struct platform_driver mtk_jpegdec_hw_driver = {
 	.probe = mtk_jpegdec_hw_probe,
 	.driver = {
 		.name = "mtk-jpegdec-hw",
 		.of_match_table = mtk_jpegdec_hw_ids,
+		.pm             = &mtk_jpegdec_pm_ops,
 	},
 };
 
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
index a3f414f92..5f5f071d8 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
@@ -264,13 +264,12 @@ static void mtk_jpegenc_timeout_work(struct work_struct *work)
 	v4l2_m2m_buf_copy_metadata(src_buf, dst_buf);
 
 	mtk_jpeg_enc_reset(cjpeg->reg_base);
-	clk_disable_unprepare(cjpeg->venc_clk.clks->clk);
-	pm_runtime_put(cjpeg->dev);
 	cjpeg->hw_state = MTK_JPEG_HW_IDLE;
 	atomic_inc(&master_jpeg->hw_rdy);
 	wake_up(&master_jpeg->hw_wq);
 	v4l2_m2m_buf_done(src_buf, buf_state);
 	mtk_jpegenc_put_buf(cjpeg);
+	pm_runtime_put(cjpeg->dev);
 }
 
 static irqreturn_t mtk_jpegenc_hw_irq_handler(int irq, void *priv)
@@ -304,12 +303,11 @@ static irqreturn_t mtk_jpegenc_hw_irq_handler(int irq, void *priv)
 	buf_state = VB2_BUF_STATE_DONE;
 	v4l2_m2m_buf_done(src_buf, buf_state);
 	mtk_jpegenc_put_buf(jpeg);
-	pm_runtime_put(ctx->jpeg->dev);
-	clk_disable_unprepare(jpeg->venc_clk.clks->clk);
 
 	jpeg->hw_state = MTK_JPEG_HW_IDLE;
 	wake_up(&master_jpeg->hw_wq);
 	atomic_inc(&master_jpeg->hw_rdy);
+	pm_runtime_put(jpeg->dev);
 
 	return IRQ_HANDLED;
 }
@@ -395,11 +393,58 @@ static int mtk_jpegenc_hw_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static int mtk_jpegenc_pm_suspend(struct device *dev)
+{
+	struct mtk_jpegenc_comp_dev *jpeg = dev_get_drvdata(dev);
+
+	clk_bulk_disable_unprepare(jpeg->venc_clk.clk_num,
+				   jpeg->venc_clk.clks);
+
+	return 0;
+}
+
+static int mtk_jpegenc_pm_resume(struct device *dev)
+{
+	struct mtk_jpegenc_comp_dev *jpeg = dev_get_drvdata(dev);
+
+	return clk_bulk_prepare_enable(jpeg->venc_clk.clk_num,
+				       jpeg->venc_clk.clks);
+}
+
+static int mtk_jpegenc_suspend(struct device *dev)
+{
+	struct mtk_jpegenc_comp_dev *jpeg = dev_get_drvdata(dev);
+
+	v4l2_m2m_suspend(jpeg->master_dev->m2m_dev);
+
+	return pm_runtime_force_suspend(dev);
+}
+
+static int mtk_jpegenc_resume(struct device *dev)
+{
+	struct mtk_jpegenc_comp_dev *jpeg = dev_get_drvdata(dev);
+	int ret;
+
+	ret = pm_runtime_force_resume(dev);
+	if (ret < 0)
+		return ret;
+
+	v4l2_m2m_resume(jpeg->master_dev->m2m_dev);
+
+	return 0;
+}
+
+static const struct dev_pm_ops mtk_jpegenc_pm_ops = {
+	SYSTEM_SLEEP_PM_OPS(mtk_jpegenc_suspend, mtk_jpegenc_resume)
+	RUNTIME_PM_OPS(mtk_jpegenc_pm_suspend, mtk_jpegenc_pm_resume, NULL)
+};
+
 static struct platform_driver mtk_jpegenc_hw_driver = {
 	.probe = mtk_jpegenc_hw_probe,
 	.driver = {
 		.name = "mtk-jpegenc-hw",
 		.of_match_table = mtk_jpegenc_drv_ids,
+		.pm = &mtk_jpegenc_pm_ops,
 	},
 };
 
-- 
2.51.0.windows.2


^ permalink raw reply related

* [PATCH v16 06/12] media: mediatek: jpeg: fix buffer state update timing
From: Kyrie Wu @ 2026-07-20 13:34 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
	Bin Liu, kyrie wu, Hans Verkuil, irui wang, Nicolas Dufresne,
	linux-media, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek
  Cc: Kyrie Wu
In-Reply-To: <20260720133432.1042046-1-kyrie.wu@mediatek.com>

Update the destination buffer state only after the decoder has selected
a hardware core and resumed its runtime PM state successfully. This avoids
assigning frame tracking data to buffers that will be returned early, such
as when a source resolution change is detected.

Protect the destination buffer state update with the hardware spinlock so
the completion path observes a consistent context and frame number. Stop
walking the done queue after completing the next expected frame, since the
remaining buffers still need to wait for their own frame order.

Fixes: dedc21500334 ("media: mtk-jpegdec: add jpeg decode worker interface")
Signed-off-by: Kyrie Wu <kyrie.wu@mediatek.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
---
 drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c   | 9 +++------
 drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c | 1 +
 drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c | 1 +
 3 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
index a5a1f6126..e152ebae0 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -1735,7 +1735,6 @@ static void mtk_jpegdec_worker(struct work_struct *work)
 
 	v4l2_m2m_buf_copy_metadata(src_buf, dst_buf);
 	jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf);
-	jpeg_dst_buf = mtk_jpeg_vb2_to_srcbuf(&dst_buf->vb2_buf);
 
 	if (mtk_jpeg_check_resolution_change(ctx,
 					     &jpeg_src_buf->dec_param)) {
@@ -1744,11 +1743,6 @@ static void mtk_jpegdec_worker(struct work_struct *work)
 		goto getbuf_fail;
 	}
 
-	jpeg_src_buf->curr_ctx = ctx;
-	jpeg_src_buf->frame_num = ctx->total_frame_num;
-	jpeg_dst_buf->curr_ctx = ctx;
-	jpeg_dst_buf->frame_num = ctx->total_frame_num;
-
 	mtk_jpegdec_set_hw_param(ctx, hw_id, src_buf, dst_buf);
 	ret = pm_runtime_resume_and_get(comp_jpeg[hw_id]->dev);
 	if (ret < 0) {
@@ -1773,6 +1767,9 @@ static void mtk_jpegdec_worker(struct work_struct *work)
 			      msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
 
 	spin_lock_irqsave(&comp_jpeg[hw_id]->hw_lock, flags);
+	jpeg_dst_buf = mtk_jpeg_vb2_to_srcbuf(&dst_buf->vb2_buf);
+	jpeg_dst_buf->curr_ctx = ctx;
+	jpeg_dst_buf->frame_num = ctx->total_frame_num;
 	ctx->total_frame_num++;
 	mtk_jpeg_dec_reset(comp_jpeg[hw_id]->reg_base);
 	mtk_jpeg_dec_set_config(comp_jpeg[hw_id]->reg_base,
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
index 970c0a30e..426150bff 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
@@ -513,6 +513,7 @@ static void mtk_jpegdec_put_buf(struct mtk_jpegdec_comp_dev *jpeg)
 				v4l2_m2m_buf_done(&tmp_dst_done_buf->b,
 						  VB2_BUF_STATE_DONE);
 				ctx->last_done_frame_num++;
+				break;
 			}
 		}
 	}
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
index 5f5f071d8..eb34698d2 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c
@@ -242,6 +242,7 @@ static void mtk_jpegenc_put_buf(struct mtk_jpegenc_comp_dev *jpeg)
 				v4l2_m2m_buf_done(&tmp_dst_done_buf->b,
 						  VB2_BUF_STATE_DONE);
 				ctx->last_done_frame_num++;
+				break;
 			}
 		}
 	}
-- 
2.51.0.windows.2


^ permalink raw reply related

* [PATCH v16 08/12] media: mediatek: jpeg: fix remove buffer removal timing for multi-core
From: Kyrie Wu @ 2026-07-20 13:34 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
	Bin Liu, kyrie wu, Hans Verkuil, irui wang, Nicolas Dufresne,
	linux-media, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek
  Cc: Kyrie Wu
In-Reply-To: <20260720133432.1042046-1-kyrie.wu@mediatek.com>

Move calls to v4l2_m2m_src/dst_buf_remove() inside of the spinlock
protected scope to ensure all necessary operations are performed
before buffers are removed from their queues and ensure proper
synchronization of buffer handling to avoid buffer lost.

Fixes: 86379bd9d399 ("media: mtk-jpeg: Fixes jpeg enc&dec worker sw flow")
Signed-off-by: Kyrie Wu <kyrie.wu@mediatek.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
---
 drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
index edd9e2d0a..0907960db 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -1654,9 +1654,6 @@ static void mtk_jpegenc_worker(struct work_struct *work)
 		goto enc_end;
 	}
 
-	v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
-	v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
-
 	schedule_delayed_work(&comp_jpeg[hw_id]->job_timeout_work,
 			      msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
 
@@ -1674,6 +1671,8 @@ static void mtk_jpegenc_worker(struct work_struct *work)
 			     &src_buf->vb2_buf);
 	mtk_jpeg_set_enc_params(ctx, comp_jpeg[hw_id]->reg_base);
 	mtk_jpeg_enc_start(comp_jpeg[hw_id]->reg_base);
+	v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+	v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
 	v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
 	spin_unlock_irqrestore(&comp_jpeg[hw_id]->hw_lock, flags);
 
@@ -1755,9 +1754,6 @@ static void mtk_jpegdec_worker(struct work_struct *work)
 		goto dec_end;
 	}
 
-	v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
-	v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
-
 	mtk_jpeg_set_dec_src(ctx, &src_buf->vb2_buf, &bs);
 	if (mtk_jpeg_set_dec_dst(ctx,
 				 &jpeg_src_buf->dec_param,
@@ -1782,6 +1778,8 @@ static void mtk_jpegdec_worker(struct work_struct *work)
 				jpeg_src_buf->bs_size,
 				&bs,
 				&fb);
+	v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+	v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
 	mtk_jpeg_dec_start(comp_jpeg[hw_id]->reg_base);
 	v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
 	spin_unlock_irqrestore(&comp_jpeg[hw_id]->hw_lock, flags);
-- 
2.51.0.windows.2


^ permalink raw reply related

* [PATCH v16 07/12] media: mediatek: jpeg: fix resolution change event handling in decoder
From: Kyrie Wu @ 2026-07-20 13:34 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
	Bin Liu, kyrie wu, Hans Verkuil, irui wang, Nicolas Dufresne,
	linux-media, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek
  Cc: Kyrie Wu
In-Reply-To: <20260720133432.1042046-1-kyrie.wu@mediatek.com>

This patch refines the handling of resolution change events within
JPEG decoder worker. The `mtk_jpeg_set_queue_data` function is now
called to set up queue data before signaling a source change through
`mtk_jpeg_queue_src_chg_event`. By reorganizing these calls, the
patch ensures that necessary queue information is updated prior to
transitioning the context state to `MTK_JPEG_SOURCE_CHANGE`.
A condition is added to exit early if the context is already in the
`MTK_JPEG_SOURCE_CHANGE` state, preventing redundant operations and
improving processing efficiency.

Fixes: dedc21500334 ("media: mtk-jpegdec: add jpeg decode worker interface")
Signed-off-by: Kyrie Wu <kyrie.wu@mediatek.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
---
 drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
index e152ebae0..edd9e2d0a 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -1738,11 +1738,15 @@ static void mtk_jpegdec_worker(struct work_struct *work)
 
 	if (mtk_jpeg_check_resolution_change(ctx,
 					     &jpeg_src_buf->dec_param)) {
-		mtk_jpeg_queue_src_chg_event(ctx);
+		mtk_jpeg_set_queue_data(ctx, &jpeg_src_buf->dec_param);
 		ctx->state = MTK_JPEG_SOURCE_CHANGE;
+		mtk_jpeg_queue_src_chg_event(ctx);
 		goto getbuf_fail;
 	}
 
+	if (ctx->state == MTK_JPEG_SOURCE_CHANGE)
+		goto getbuf_fail;
+
 	mtk_jpegdec_set_hw_param(ctx, hw_id, src_buf, dst_buf);
 	ret = pm_runtime_resume_and_get(comp_jpeg[hw_id]->dev);
 	if (ret < 0) {
-- 
2.51.0.windows.2


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox