Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH bpf-next v12 3/5] bpf: Add helper to detect indirect jump targets
From: Emil Tsalapatis @ 2026-04-03 18:02 UTC (permalink / raw)
  To: Xu Kuohai, bpf, linux-kernel, linux-arm-kernel
  Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Eduard Zingerman, Yonghong Song, Puranjay Mohan,
	Anton Protopopov, Alexis Lothoré, Shahab Vahedi,
	Russell King, Tiezhu Yang, Hengqi Chen, Johan Almbladh,
	Paul Burton, Hari Bathini, Christophe Leroy, Naveen N Rao,
	Luke Nelson, Xi Wang, Björn Töpel, Pu Lehui,
	Ilya Leoshkevich, Heiko Carstens, Vasily Gorbik, David S . Miller,
	Wang YanQing
In-Reply-To: <20260403132811.753894-4-xukuohai@huaweicloud.com>

On Fri Apr 3, 2026 at 9:28 AM EDT, Xu Kuohai wrote:
> From: Xu Kuohai <xukuohai@huawei.com>
>
> Introduce helper bpf_insn_is_indirect_target to check whether a BPF
> instruction is an indirect jump target.
>
> Since the verifier knows which instructions are indirect jump targets,
> add a new flag indirect_target to struct bpf_insn_aux_data to mark
> them. The verifier sets this flag when verifying an indirect jump target
> instruction, and the helper checks the flag to determine whether an
> instruction is an indirect jump target.

Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>

>
> Reviewed-by: Anton Protopopov <a.s.protopopov@gmail.com>
> Signed-off-by: Xu Kuohai <xukuohai@huawei.com>
> ---
>  include/linux/bpf.h          |  2 ++
>  include/linux/bpf_verifier.h |  9 +++++----
>  kernel/bpf/core.c            |  9 +++++++++
>  kernel/bpf/verifier.c        | 18 ++++++++++++++++++
>  4 files changed, 34 insertions(+), 4 deletions(-)
>
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index 05b34a6355b0..90760e250865 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -1541,6 +1541,8 @@ bool bpf_has_frame_pointer(unsigned long ip);
>  int bpf_jit_charge_modmem(u32 size);
>  void bpf_jit_uncharge_modmem(u32 size);
>  bool bpf_prog_has_trampoline(const struct bpf_prog *prog);
> +bool bpf_insn_is_indirect_target(const struct bpf_verifier_env *env, const struct bpf_prog *prog,
> +				 int insn_idx);
>  #else
>  static inline int bpf_trampoline_link_prog(struct bpf_tramp_link *link,
>  					   struct bpf_trampoline *tr,
> diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
> index b129e0aaee20..cc53877639a5 100644
> --- a/include/linux/bpf_verifier.h
> +++ b/include/linux/bpf_verifier.h
> @@ -578,16 +578,17 @@ struct bpf_insn_aux_data {
>  
>  	/* below fields are initialized once */
>  	unsigned int orig_idx; /* original instruction index */
> -	bool jmp_point;
> -	bool prune_point;
> +	u32 jmp_point:1;
> +	u32 prune_point:1;
>  	/* ensure we check state equivalence and save state checkpoint and
>  	 * this instruction, regardless of any heuristics
>  	 */
> -	bool force_checkpoint;
> +	u32 force_checkpoint:1;
>  	/* true if instruction is a call to a helper function that
>  	 * accepts callback function as a parameter.
>  	 */
> -	bool calls_callback;
> +	u32 calls_callback:1;
> +	u32 indirect_target:1; /* if it is an indirect jump target */
>  	/*
>  	 * CFG strongly connected component this instruction belongs to,
>  	 * zero if it is a singleton SCC.
> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> index 093ab0f68c81..439575fa6976 100644
> --- a/kernel/bpf/core.c
> +++ b/kernel/bpf/core.c
> @@ -1570,6 +1570,15 @@ struct bpf_prog *bpf_jit_blind_constants(struct bpf_verifier_env *env, struct bp
>  	clone->blinded = 1;
>  	return clone;
>  }
> +
> +bool bpf_insn_is_indirect_target(const struct bpf_verifier_env *env, const struct bpf_prog *prog,
> +				 int insn_idx)
> +{
> +	if (!env)
> +		return false;
> +	insn_idx += prog->aux->subprog_start;
> +	return env->insn_aux_data[insn_idx].indirect_target;
> +}
>  #endif /* CONFIG_BPF_JIT */
>  
>  /* Base function for offset calculation. Needs to go into .text section,
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 5084a754a748..e078e6ad5b00 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -4049,6 +4049,11 @@ static bool is_jmp_point(struct bpf_verifier_env *env, int insn_idx)
>  	return env->insn_aux_data[insn_idx].jmp_point;
>  }
>  
> +static void mark_indirect_target(struct bpf_verifier_env *env, int idx)
> +{
> +	env->insn_aux_data[idx].indirect_target = true;
> +}
> +
>  #define LR_FRAMENO_BITS	3
>  #define LR_SPI_BITS	6
>  #define LR_ENTRY_BITS	(LR_SPI_BITS + LR_FRAMENO_BITS + 1)
> @@ -21227,12 +21232,14 @@ static int check_indirect_jump(struct bpf_verifier_env *env, struct bpf_insn *in
>  	}
>  
>  	for (i = 0; i < n - 1; i++) {
> +		mark_indirect_target(env, env->gotox_tmp_buf->items[i]);
>  		other_branch = push_stack(env, env->gotox_tmp_buf->items[i],
>  					  env->insn_idx, env->cur_state->speculative);
>  		if (IS_ERR(other_branch))
>  			return PTR_ERR(other_branch);
>  	}
>  	env->insn_idx = env->gotox_tmp_buf->items[n-1];
> +	mark_indirect_target(env, env->insn_idx);
>  	return 0;
>  }
>  
> @@ -22158,6 +22165,17 @@ static void adjust_insn_aux_data(struct bpf_verifier_env *env,
>  		data[i].seen = old_seen;
>  		data[i].zext_dst = insn_has_def32(insn + i);
>  	}
> +
> +	/* The indirect_target flag of the original instruction was moved to the last of the
> +	 * new instructions by the above memmove and memset, but the indirect jump target is
> +	 * actually the first instruction, so move it back. This also matches with the behavior
> +	 * of bpf_insn_array_adjust(), which preserves xlated_off to point to the first new
> +	 * instruction.
> +	 */
> +	if (data[off + cnt - 1].indirect_target) {
> +		data[off].indirect_target = 1;
> +		data[off + cnt - 1].indirect_target = 0;
> +	}
>  }
>  
>  static void adjust_subprog_starts(struct bpf_verifier_env *env, u32 off, u32 len)



^ permalink raw reply

* Re: [PATCH v20 06/10] power: reset: Add psci-reboot-mode driver
From: Shivendra Pratap @ 2026-04-03 17:45 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Arnd Bergmann, Bjorn Andersson, Sebastian Reichel, Rob Herring,
	Souvik Chakravarty, Krzysztof Kozlowski, Andy Yan,
	Matthias Brugger, Mark Rutland, Conor Dooley, Konrad Dybcio,
	John Stultz, Moritz Fischer, Bartosz Golaszewski, Sudeep Holla,
	Florian Fainelli, Krzysztof Kozlowski, Dmitry Baryshkov,
	Mukesh Ojha, Andre Draszik, Kathiravan Thirumoorthy, linux-pm,
	linux-kernel, linux-arm-kernel, linux-arm-msm, devicetree,
	Srinivas Kandagatla
In-Reply-To: <ac/hru3IIiU0+Lp9@lpieralisi>



On 03-04-2026 21:20, Lorenzo Pieralisi wrote:
> On Fri, Apr 03, 2026 at 12:05:27AM +0530, Shivendra Pratap wrote:
>>
>>
>> On 01-04-2026 20:07, Lorenzo Pieralisi wrote:
>>> On Tue, Mar 31, 2026 at 11:30:09PM +0530, Shivendra Pratap wrote:
>>>>
>>>>
>>>> On 27-03-2026 19:25, Lorenzo Pieralisi wrote:
>>>>> On Wed, Mar 04, 2026 at 11:33:06PM +0530, Shivendra Pratap wrote:
>>>>>> PSCI supports different types of resets like COLD reset, ARCH WARM
>>
>> [snip..]
>>
>>>>>> + * Predefined reboot-modes are defined as per the values
>>>>>> + * of enum reboot_mode defined in the kernel: reboot.c.
>>>>>> + */
>>>>>> +static struct mode_info psci_resets[] = {
>>>>>> +	{ .mode = "warm", .magic = REBOOT_WARM},
>>>>>> +	{ .mode = "soft", .magic = REBOOT_SOFT},
>>>>>> +	{ .mode = "cold", .magic = REBOOT_COLD},
>>>
>>> These strings match the command userspace issue right ? I think that we
>>> should make them match the corresponding PSCI reset types, the list above
>>> maps command to reboot_mode values and those can belong to any reboot
>>> mode driver to be honest they don't make much sense in a PSCI reboot
>>> mode driver only.
>>>
>>> It is a question for everyone here: would it make sense to make these
>>> predefined resets a set of strings, eg:
>>>
>>> psci-system-reset
>>> psci-system-reset2-arch-warm-reset
>>>
>>> and then vendor resets:
>>>
>>> psci-system-reset2-vendor-reset
>>
>> Can you share bit more details on this? We are already defining the string
>> from userspace in the struct - eg: ".mode = "warm".
> 
> "warm","soft","cold" are not strictly speaking PSCI concepts and mean nothing
> well defined to user space and even if they did, they would not belong in
> the PSCI reboot mode driver but in generic code.
> 
> Spelling out what a reset is might help instead, again, this is just my
> opinion, I don't know how the semantics of resets have been handled thus
> far.
> 
> If userspace issues a LINUX_REBOOT_CMD_RESTART2 with arg, say,
> "psci-system-reset2-arch-warm-reset" it is pretty clear what it wants
> to do in PSCI.

ok. got it.

so it predef-modes.

reboot psci-system-reset2-arch-warm-reset =>goes for => ARCH WARM RESET.
etc..

> 
> Again, it is a suggestion, comments welcome.
> 
>> yes we can move away from enum reboot_mode and use custom psci defines one -
>> Ack.
>>
>>>
>>
>> [snip ..]
>>
>>>>>> +
>>>>>> +/*
>>>>>> + * arg1 is reset_type(Low 32 bit of magic).
>>>>>> + * arg2 is cookie(High 32 bit of magic).
>>>>>> + * If reset_type is 0, cookie will be used to decide the reset command.
>>>>>> + */
>>>>>> +static int psci_reboot_mode_write(struct reboot_mode_driver *reboot, u64 magic)
>>>>>> +{
>>>>>> +	u32 reset_type = REBOOT_MODE_ARG1(magic);
>>>>>> +	u32 cookie = REBOOT_MODE_ARG2(magic);
>>>>>> +
>>>>>> +	if (reset_type == 0) {
>>>>>> +		if (cookie == REBOOT_WARM || cookie == REBOOT_SOFT)
>>>>>> +			psci_set_reset_cmd(true, 0, 0);
>>>>>> +		else
>>>>>> +			psci_set_reset_cmd(false, 0, 0);
>>>>>> +	} else {
>>>>>> +		psci_set_reset_cmd(true, reset_type, cookie);
>>>>>> +	}
>>>>>
>>>>> I don't think that psci_set_reset_cmd() has the right interface (and this
>>>>> nested if is too complicated for my taste). All we need to pass is reset-type
>>>>> and cookie (and if the reset is one of the predefined ones, reset-type is 0
>>>>> and cookie is the REBOOT_* cookie).
>>>>>
>>>>> Then the PSCI firmware driver will take the action according to what
>>>>> resets are available.
>>>>>
>>>>> How does it sound ?
>>>>
>>>> So we mean these checks will move to the psci driver? Sorry for re-iterating
>>>> the question.
>>>
>>> Given what I say above, I believe that something we can do is mapping the magic
>>> to an enum like:
>>>
>>> PSCI_SYSTEM_RESET
>>> PSCI_SYSTEM_RESET2_ARCH_SYSTEM_WARM_RESET
>>> PSCI_SYSTEM_RESET2_VENDOR_RESET
>>>
>>> and can add a probe function into PSCI driver similar to psci_has_osi_support() but
>>> to probe for SYSTEM_RESET2 and initialize the predefined strings accordingly,
>>> depending on its presence.
>>
>> Not able to get it cleanly.
>>
>> 1. Will move away from reboot_mode enum for pre-defined modes and define new
>> enum defining these modes- fine.
>> 2. get SYSTEM_RESET2 is supported from psci exported function -- fine, but
>> how we use it here now, as we do not want to send the reset_cmd from
>> psci_set_reset_cmd now?
> 
> You do keep psci_set_reset_cmd() but all it is used for is setting a struct
> shared with the PSCI driver where you initialize the enum above, possibly
> with a cookie if it is a vendor reset.
> 
>> 3. For pre-defined modes, warm/soft or cold - reset_type and cookie, both
>> are zero, sys_reset2 or sys_reset2 decides the ARCH reset vs cold reset.
>> 4. For vendor-rest , we use sys_reset2 with reset_type and cookie.
> 
> Yes.

Ack.


>> All above is done in reboot_notifier call at psci-reboot-mode.
>> --
>>
>> Now in the final restart_notifier->psci_sys_reset --
>>
>> If panic is in progress, we do not use any of the cmd based reset params and
>> go with the legacy reset. So we need to preserve the values that were set
>> from psci-reboot-mode.
>>
>> Did not understand the proposed suggestion in above usecase. Need more input
>> on this.
> 
> I explained above. The reboot mode driver sets the command to carry out
> depending on the string coming from user space and whether PSCI supports
> SYSTEM_RESET2 or not.

got it. working on it. thanks.


>> --
>>
>> One other option is to have a restart_notifier in psci-reboot-mode, with
>> lesser priority than psci_sys_rest and then handle all the case including
>> panic and sys_reset2.
> 
> No.

Ack.

thanks,
Shivendra


^ permalink raw reply

* [PATCH WIP v3 06/11] Input: stmfts - use client to make future code cleaner
From: David Heidelberg via B4 Relay @ 2026-04-03 17:08 UTC (permalink / raw)
  To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
	Bjorn Andersson, Konrad Dybcio
  Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
	linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
	phone-devel, David Heidelberg
In-Reply-To: <20260403-stmfts5-v3-0-5da768cfd201@ixit.cz>

From: Petr Hodina <petr.hodina@protonmail.com>

Make code cleaner, compiler will optimize it away anyway.

Preparation for FTM5 support, where more steps are needed.

Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: David Heidelberg <david@ixit.cz>
---
 drivers/input/touchscreen/stmfts.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index a90528b76f52b..5f7de5e687da2 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -763,9 +763,10 @@ static int stmfts_runtime_suspend(struct device *dev)
 static int stmfts_runtime_resume(struct device *dev)
 {
 	struct stmfts_data *sdata = dev_get_drvdata(dev);
+	struct i2c_client *client = sdata->client;
 	int ret;
 
-	ret = i2c_smbus_write_byte(sdata->client, STMFTS_SLEEP_OUT);
+	ret = i2c_smbus_write_byte(client, STMFTS_SLEEP_OUT);
 	if (ret)
 		dev_err(dev, "failed to resume device: %d\n", ret);
 

-- 
2.53.0




^ permalink raw reply related

* [PATCH WIP v3 00/11] Input: support for STM FTS5
From: David Heidelberg via B4 Relay @ 2026-04-03 17:08 UTC (permalink / raw)
  To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
	Bjorn Andersson, Konrad Dybcio
  Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
	linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
	phone-devel, David Heidelberg

Used on various phones. Minimal basic support.

Includes device-tree enabling touchscreen on Pixel 3.

Sending as WIP, as not all comments we're addressed, but please feel
free to apply any patch which does look ready for inclusion.

What is missing:
 - switching between AP and SLPI mode (to be able to wake up phone by touch)
 - firmware loading
 - anything above basic touch

Signed-off-by: David Heidelberg <david@ixit.cz>
---
TODO for v4:
- wrap everything below enabling the supplies into stmfts_configure()
  to avoid bunch of gotos to power off on error? (Dmitry T.)
- finish chip specific ops and potentinally remove is_fts5. (Dmitry T.)

Changes in v3:
- s/touchscreen_pins/touchscreen_irq_n. (Konrad)
- Use interrupts-extended. (Konrad)
- Fixed rebase conflict against 8665ceb926ec ("Input: stmfts - use guard notation when acquiring mutex")
- Rename switch-gpios to mode-switch-gpios.
- Do not define properties in if:then: branches. (Krzysztof)
- Link to v2: https://lore.kernel.org/r/20260315-stmfts5-v2-0-70bc83ee9591@ixit.cz

Changes in v2:
- Fix typo in the binding s/switch-gpio/switch-gpios/.
- Deduplacate allOf. (Rob yamllint)
- Add missing S-off-by. (Dmitry B.)
- Dropped irq-gpios as it's not needed. (Konrad)
- Correct x and y touchscreen area size. (Konrad)
- Correct reset introduction commit description. (Krzysztof)
- Partially implemented chip specific ops. (Dmitry T.)
- Separeted license naming cleanup into separate commit (Dmitry T.)
- Link to v1: https://lore.kernel.org/r/20260301-stmfts5-v1-0-22c458b9ac68@ixit.cz

---
David Heidelberg (7):
      Input: stmfts - Fix the MODULE_LICENSE() string
      Input: stmfts - Use dev struct directly
      Input: stmfts - Switch to devm_regulator_bulk_get_const
      Input: stmfts - abstract reading information from the firmware
      Input: stmfts - disable regulators when power on fails
      dt-bindings: input: touchscreen: st,stmfts: Introduce reset GPIO
      dt-bindings: input: touchscreen: st,stmfts: Introduce STM FTS5

Petr Hodina (4):
      Input: stmfts - use client to make future code cleaner
      Input: stmfts - add optional reset GPIO support
      Input: stmfts - support FTS5
      arm64: dts: qcom: sdm845-google: Add STM FTS touchscreen support

 .../bindings/input/touchscreen/st,stmfts.yaml      |  19 +-
 .../arm64/boot/dts/qcom/sdm845-google-blueline.dts |  19 +-
 arch/arm64/boot/dts/qcom/sdm845-google-common.dtsi |   2 +-
 drivers/input/touchscreen/stmfts.c                 | 594 +++++++++++++++++++--
 4 files changed, 574 insertions(+), 60 deletions(-)
---
base-commit: cc13002a9f984d37906e9476f3e532a8cdd126f5
change-id: 20260214-stmfts5-b47311fbd732

Best regards,
-- 
David Heidelberg <david@ixit.cz>




^ permalink raw reply

* [PATCH WIP v3 10/11] Input: stmfts - support FTS5
From: David Heidelberg via B4 Relay @ 2026-04-03 17:08 UTC (permalink / raw)
  To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
	Bjorn Andersson, Konrad Dybcio
  Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
	linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
	phone-devel, David Heidelberg
In-Reply-To: <20260403-stmfts5-v3-0-5da768cfd201@ixit.cz>

From: Petr Hodina <petr.hodina@protonmail.com>

Introduce basic FTS5 support.

FTS support SLPI and AP mode, introduce mode-switch GPIO to switch between
those two. Currently we can handle only full power AP mode, so we just
keep the AP on.

Useful for devices like Pixel 3 (blueline) and many others.

Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Co-developed-by: David Heidelberg <david@ixit.cz>
Signed-off-by: David Heidelberg <david@ixit.cz>
---
 drivers/input/touchscreen/stmfts.c | 481 +++++++++++++++++++++++++++++++++++--
 1 file changed, 460 insertions(+), 21 deletions(-)

diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index 04110006f54a0..e0fa1c4af1987 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -1,8 +1,11 @@
 // SPDX-License-Identifier: GPL-2.0
-// STMicroelectronics FTS Touchscreen device driver
-//
-// Copyright (c) 2017 Samsung Electronics Co., Ltd.
-// Copyright (c) 2017 Andi Shyti <andi@etezian.org>
+/* STMicroelectronics FTS Touchscreen device driver
+ *
+ * Copyright 2017 Samsung Electronics Co., Ltd.
+ * Copyright 2017 Andi Shyti <andi@etezian.org>
+ * Copyright David Heidelberg <david@ixit.cz>
+ * Copyright Petr Hodina <petr.hodina@protonmail.com>
+ */
 
 #include <linux/delay.h>
 #include <linux/i2c.h>
@@ -12,6 +15,7 @@
 #include <linux/irq.h>
 #include <linux/leds.h>
 #include <linux/module.h>
+#include <linux/of_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
 
@@ -34,6 +38,7 @@
 #define STMFTS_FULL_FORCE_CALIBRATION		0xa2
 #define STMFTS_MS_CX_TUNING			0xa3
 #define STMFTS_SS_CX_TUNING			0xa4
+#define STMFTS5_SET_SCAN_MODE			0xa0
 
 /* events */
 #define STMFTS_EV_NO_EVENT			0x00
@@ -51,12 +56,32 @@
 #define STMFTS_EV_STATUS			0x16
 #define STMFTS_EV_DEBUG				0xdb
 
+/* events FTS5 */
+#define STMFTS5_EV_CONTROLLER_READY		0x03
+/* FTM5 event IDs (full byte, not masked) */
+#define STMFTS5_EV_MULTI_TOUCH_ENTER		0x13
+#define STMFTS5_EV_MULTI_TOUCH_MOTION		0x23
+#define STMFTS5_EV_MULTI_TOUCH_LEAVE		0x33
+#define STMFTS5_EV_STATUS_UPDATE		0x43
+#define STMFTS5_EV_USER_REPORT			0x53
+#define STMFTS5_EV_DEBUG			0xe3
+#define STMFTS5_EV_ERROR			0xf3
+
 /* multi touch related event masks */
 #define STMFTS_MASK_EVENT_ID			0x0f
 #define STMFTS_MASK_TOUCH_ID			0xf0
 #define STMFTS_MASK_LEFT_EVENT			0x0f
 #define STMFTS_MASK_X_MSB			0x0f
 #define STMFTS_MASK_Y_LSB			0xf0
+#define STMFTS5_MASK_TOUCH_TYPE			0x0f
+
+/* touch type classifications */
+#define STMFTS_TOUCH_TYPE_INVALID		0x00
+#define STMFTS_TOUCH_TYPE_FINGER		0x01
+#define STMFTS_TOUCH_TYPE_GLOVE			0x02
+#define STMFTS_TOUCH_TYPE_STYLUS		0x03
+#define STMFTS_TOUCH_TYPE_PALM			0x04
+#define STMFTS_TOUCH_TYPE_HOVER			0x05
 
 /* key related event masks */
 #define STMFTS_MASK_KEY_NO_TOUCH		0x00
@@ -75,9 +100,12 @@ static const struct regulator_bulk_data stmfts_supplies[] = {
 };
 
 struct stmfts_data {
+	const struct stmfts_chip_ops *ops;
+
 	struct i2c_client *client;
 	struct input_dev *input;
 	struct gpio_desc *reset_gpio;
+	struct gpio_desc *mode_switch_gpio;
 	struct led_classdev led_cdev;
 	struct mutex mutex;
 
@@ -101,12 +129,24 @@ struct stmfts_data {
 
 	struct completion cmd_done;
 
+	unsigned long touch_id;
+	unsigned long stylus_id;
+
+	bool is_fts5;
 	bool use_key;
 	bool led_status;
 	bool hover_enabled;
+	bool stylus_enabled;
 	bool running;
 };
 
+struct stmfts_chip_ops {
+	int  (*power_on)(struct stmfts_data *sdata);
+	int  (*input_open)(struct input_dev *dev);
+	void (*input_close)(struct input_dev *dev);
+	void (*parse_events)(struct stmfts_data *sdata);
+};
+
 static int stmfts_brightness_set(struct led_classdev *led_cdev,
 					enum led_brightness value)
 {
@@ -169,6 +209,7 @@ static int stmfts_read_events(struct stmfts_data *sdata)
 	return ret == ARRAY_SIZE(msgs) ? 0 : -EIO;
 }
 
+/* FTS4 event handling functions */
 static void stmfts_report_contact_event(struct stmfts_data *sdata,
 					const u8 event[])
 {
@@ -204,6 +245,157 @@ static void stmfts_report_contact_release(struct stmfts_data *sdata,
 	input_sync(sdata->input);
 }
 
+/* FTS5 event handling functions */
+static void stmfts5_report_contact_event(struct stmfts_data *sdata,
+					 const u8 event[])
+{
+	u8 area;
+	u8 maj;
+	u8 min;
+	/* FTM5 event format:
+	 * event[0] = event ID (0x13/0x23)
+	 * event[1] = touch type (low 4 bits) | touch ID (high 4 bits)
+	 * event[2] = X LSB
+	 * event[3] = X MSB (low 4 bits) | Y MSB (high 4 bits)
+	 * event[4] = Y LSB
+	 * event[5] = pressure
+	 * event[6] = major (low 4 bits) | minor (high 4 bits)
+	 * event[7] = minor (high 2 bits)
+	 */
+	u8 touch_id = (event[1] & STMFTS_MASK_TOUCH_ID) >> 4;
+	u8 touch_type = event[1] & STMFTS5_MASK_TOUCH_TYPE;
+	int x, y, distance;
+	unsigned int tool = MT_TOOL_FINGER;
+	bool touch_condition = true;
+
+	/* Parse coordinates with better precision */
+	x = (((int)event[3] & STMFTS_MASK_X_MSB) << 8) | event[2];
+	y = ((int)event[4] << 4) | ((event[3] & STMFTS_MASK_Y_LSB) >> 4);
+
+	/* Parse pressure - ensure non-zero for active touch */
+	area = event[5];
+	if (area <= 0 && touch_type != STMFTS_TOUCH_TYPE_HOVER) {
+		/* Should not happen for contact events. Set minimum pressure
+		 * to prevent touch from being dropped
+		 */
+		dev_warn_once(&sdata->client->dev,
+			      "zero pressure on contact event, slot %d\n", touch_id);
+		area = 1;
+	}
+
+	/* Parse touch area with improved bit extraction */
+	maj = (((event[0] & 0x0C) << 2) | ((event[6] & 0xF0) >> 4));
+	min = (((event[7] & 0xC0) >> 2) | (event[6] & 0x0F));
+
+	/* Distance is 0 for touching, max for hovering */
+	distance = 0;
+
+	/* Classify touch type and set appropriate tool and parameters */
+	switch (touch_type) {
+	case STMFTS_TOUCH_TYPE_STYLUS:
+		if (sdata->stylus_enabled) {
+			tool = MT_TOOL_PEN;
+			__set_bit(touch_id, &sdata->stylus_id);
+			__clear_bit(touch_id, &sdata->touch_id);
+			break;
+		}
+		fallthrough; /* Report as finger if stylus not enabled */
+
+	case STMFTS_TOUCH_TYPE_FINGER:
+	case STMFTS_TOUCH_TYPE_GLOVE:
+		tool = MT_TOOL_FINGER;
+		__set_bit(touch_id, &sdata->touch_id);
+		__clear_bit(touch_id, &sdata->stylus_id);
+		break;
+
+	case STMFTS_TOUCH_TYPE_PALM:
+		/* Palm touch - report but can be filtered by userspace */
+		tool = MT_TOOL_PALM;
+		__set_bit(touch_id, &sdata->touch_id);
+		__clear_bit(touch_id, &sdata->stylus_id);
+		break;
+
+	case STMFTS_TOUCH_TYPE_HOVER:
+		tool = MT_TOOL_FINGER;
+		touch_condition = false;
+		area = 0;
+		distance = 255;
+		__set_bit(touch_id, &sdata->touch_id);
+		__clear_bit(touch_id, &sdata->stylus_id);
+		break;
+
+	case STMFTS_TOUCH_TYPE_INVALID:
+	default:
+		dev_warn(&sdata->client->dev,
+			 "invalid touch type %d for slot %d\n",
+			 touch_type, touch_id);
+		return;
+	}
+
+	/* Boundary check - some devices report max value, adjust */
+	if (x >= sdata->prop.max_x)
+		x = sdata->prop.max_x - 1;
+	if (y >= sdata->prop.max_y)
+		y = sdata->prop.max_y - 1;
+
+	input_mt_slot(sdata->input, touch_id);
+	input_report_key(sdata->input, BTN_TOUCH, touch_condition);
+	input_mt_report_slot_state(sdata->input, tool, true);
+
+	input_report_abs(sdata->input, ABS_MT_POSITION_X, x);
+	input_report_abs(sdata->input, ABS_MT_POSITION_Y, y);
+	input_report_abs(sdata->input, ABS_MT_TOUCH_MAJOR, maj);
+	input_report_abs(sdata->input, ABS_MT_TOUCH_MINOR, min);
+	input_report_abs(sdata->input, ABS_MT_PRESSURE, area);
+	input_report_abs(sdata->input, ABS_MT_DISTANCE, distance);
+
+	input_sync(sdata->input);
+}
+
+static void stmfts5_report_contact_release(struct stmfts_data *sdata,
+					   const u8 event[])
+{
+	/* FTM5 format: touch ID is in high 4 bits of event[1] */
+	u8 touch_id = (event[1] & STMFTS_MASK_TOUCH_ID) >> 4;
+	u8 touch_type = event[1] & STMFTS5_MASK_TOUCH_TYPE;
+	unsigned int tool = MT_TOOL_FINGER;
+
+	/* Determine tool type based on touch classification */
+	switch (touch_type) {
+	case STMFTS_TOUCH_TYPE_STYLUS:
+		if (sdata->stylus_enabled) {
+			tool = MT_TOOL_PEN;
+			__clear_bit(touch_id, &sdata->stylus_id);
+		} else {
+			__clear_bit(touch_id, &sdata->touch_id);
+		}
+		break;
+
+	case STMFTS_TOUCH_TYPE_PALM:
+		tool = MT_TOOL_PALM;
+		__clear_bit(touch_id, &sdata->touch_id);
+		break;
+
+	case STMFTS_TOUCH_TYPE_FINGER:
+	case STMFTS_TOUCH_TYPE_GLOVE:
+	case STMFTS_TOUCH_TYPE_HOVER:
+	default:
+		tool = MT_TOOL_FINGER;
+		__clear_bit(touch_id, &sdata->touch_id);
+		break;
+	}
+
+	input_mt_slot(sdata->input, touch_id);
+	input_report_abs(sdata->input, ABS_MT_PRESSURE, 0);
+	input_mt_report_slot_state(sdata->input, tool, false);
+
+	/* Report BTN_TOUCH only if no touches remain */
+	if (!sdata->touch_id && !sdata->stylus_id)
+		input_report_key(sdata->input, BTN_TOUCH, 0);
+
+	input_sync(sdata->input);
+}
+
 static void stmfts_report_hover_event(struct stmfts_data *sdata,
 				      const u8 event[])
 {
@@ -251,7 +443,6 @@ static void stmfts_parse_events(struct stmfts_data *sdata)
 		u8 *event = &sdata->data[i * STMFTS_EVENT_SIZE];
 
 		switch (event[0]) {
-
 		case STMFTS_EV_CONTROLLER_READY:
 		case STMFTS_EV_SLEEP_OUT_CONTROLLER_READY:
 		case STMFTS_EV_STATUS:
@@ -264,7 +455,6 @@ static void stmfts_parse_events(struct stmfts_data *sdata)
 		}
 
 		switch (event[0] & STMFTS_MASK_EVENT_ID) {
-
 		case STMFTS_EV_MULTI_TOUCH_ENTER:
 		case STMFTS_EV_MULTI_TOUCH_MOTION:
 			stmfts_report_contact_event(sdata, event);
@@ -298,6 +488,45 @@ static void stmfts_parse_events(struct stmfts_data *sdata)
 	}
 }
 
+static void stmfts5_parse_events(struct stmfts_data *sdata)
+{
+	for (int i = 0; i < STMFTS_STACK_DEPTH; i++) {
+		u8 *event = &sdata->data[i * STMFTS_EVENT_SIZE];
+
+		switch (event[0]) {
+		case STMFTS5_EV_CONTROLLER_READY:
+			complete(&sdata->cmd_done);
+			fallthrough;
+
+		case STMFTS_EV_NO_EVENT:
+		case STMFTS5_EV_STATUS_UPDATE:
+		case STMFTS5_EV_USER_REPORT:
+		case STMFTS5_EV_DEBUG:
+			return;
+
+		case STMFTS5_EV_MULTI_TOUCH_ENTER:
+		case STMFTS5_EV_MULTI_TOUCH_MOTION:
+			stmfts5_report_contact_event(sdata, event);
+			break;
+
+		case STMFTS5_EV_MULTI_TOUCH_LEAVE:
+			stmfts5_report_contact_release(sdata, event);
+			break;
+
+		case STMFTS5_EV_ERROR:
+			dev_warn(&sdata->client->dev,
+				 "error code: 0x%x%x%x%x%x%x",
+				 event[6], event[5], event[4],
+				 event[3], event[2], event[1]);
+			break;
+
+		default:
+			dev_err(&sdata->client->dev,
+				"unknown FTS5 event %#02x\n", event[0]);
+		}
+	}
+}
+
 static irqreturn_t stmfts_irq_handler(int irq, void *dev)
 {
 	struct stmfts_data *sdata = dev;
@@ -310,7 +539,7 @@ static irqreturn_t stmfts_irq_handler(int irq, void *dev)
 		dev_err(&sdata->client->dev,
 			"failed to read events: %d\n", err);
 	else
-		stmfts_parse_events(sdata);
+		sdata->ops->parse_events(sdata);
 
 	return IRQ_HANDLED;
 }
@@ -332,6 +561,25 @@ static int stmfts_command(struct stmfts_data *sdata, const u8 cmd)
 	return 0;
 }
 
+static int stmfts5_set_scan_mode(struct stmfts_data *sdata, const u8 val)
+{
+	int err;
+
+	u8 scan_mode_cmd[3] = { STMFTS5_SET_SCAN_MODE, 0x00, val };
+	struct i2c_msg msg = {
+		.addr = sdata->client->addr,
+		.len = sizeof(scan_mode_cmd),
+		.buf = scan_mode_cmd,
+	};
+
+	err = i2c_transfer(sdata->client->adapter, &msg, 1);
+	if (err != 1)
+		return err < 0 ? err : -EIO;
+
+	return 0;
+
+}
+
 static int stmfts_input_open(struct input_dev *dev)
 {
 	struct stmfts_data *sdata = input_get_drvdata(dev);
@@ -371,6 +619,28 @@ static int stmfts_input_open(struct input_dev *dev)
 	return 0;
 }
 
+static int stmfts5_input_open(struct input_dev *dev)
+{
+	struct stmfts_data *sdata = input_get_drvdata(dev);
+	int err;
+
+	err = pm_runtime_resume_and_get(&sdata->client->dev);
+	if (err)
+		return err;
+
+	mutex_lock(&sdata->mutex);
+	sdata->running = true;
+	mutex_unlock(&sdata->mutex);
+
+	err = stmfts5_set_scan_mode(sdata, 0xff);
+	if (err) {
+		pm_runtime_put_sync(&sdata->client->dev);
+		return err;
+	}
+
+	return 0;
+}
+
 static void stmfts_input_close(struct input_dev *dev)
 {
 	struct stmfts_data *sdata = input_get_drvdata(dev);
@@ -404,6 +674,23 @@ static void stmfts_input_close(struct input_dev *dev)
 	pm_runtime_put_sync(&sdata->client->dev);
 }
 
+static void stmfts5_input_close(struct input_dev *dev)
+{
+	struct stmfts_data *sdata = input_get_drvdata(dev);
+	int err;
+
+	err = stmfts5_set_scan_mode(sdata, 0x00);
+	if (err)
+		dev_warn(&sdata->client->dev,
+			 "failed to disable touchscreen: %d\n", err);
+
+	mutex_lock(&sdata->mutex);
+	sdata->running = false;
+	mutex_unlock(&sdata->mutex);
+
+	pm_runtime_put_sync(&sdata->client->dev);
+}
+
 static ssize_t stmfts_sysfs_chip_id(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
@@ -484,7 +771,7 @@ static ssize_t stmfts_sysfs_hover_enable_write(struct device *dev,
 	guard(mutex)(&sdata->mutex);
 
 	if (hover != sdata->hover_enabled) {
-		if (sdata->running) {
+		if (sdata->running && !sdata->is_fts5) {
 			err = i2c_smbus_write_byte(sdata->client,
 					   value ? STMFTS_SS_HOVER_SENSE_ON :
 						   STMFTS_SS_HOVER_SENSE_OFF);
@@ -614,6 +901,41 @@ static int stmfts_power_on(struct stmfts_data *sdata)
 	return err;
 }
 
+static int stmfts5_power_on(struct stmfts_data *sdata)
+{
+	int err, ret;
+	u8 event[STMFTS_EVENT_SIZE];
+
+	err = regulator_bulk_enable(ARRAY_SIZE(stmfts_supplies),
+				    sdata->supplies);
+	if (err)
+		return err;
+
+	/* Power stabilization delay */
+	msleep(20);
+
+	if (sdata->reset_gpio)
+		stmfts_reset(sdata);
+
+	/* Verify I2C communication */
+	ret = i2c_smbus_read_i2c_block_data(sdata->client,
+					    STMFTS_READ_ALL_EVENT,
+					    sizeof(event), event);
+	if (ret < 0) {
+		err = ret;
+		goto power_off;
+	}
+
+	enable_irq(sdata->client->irq);
+
+	return 0;
+
+power_off:
+	regulator_bulk_disable(ARRAY_SIZE(stmfts_supplies),
+			       sdata->supplies);
+	return err;
+}
+
 static void stmfts_power_off(void *data)
 {
 	struct stmfts_data *sdata = data;
@@ -623,6 +945,11 @@ static void stmfts_power_off(void *data)
 	if (sdata->reset_gpio)
 		gpiod_set_value_cansleep(sdata->reset_gpio, 1);
 
+	if (sdata->is_fts5) {
+		i2c_smbus_write_byte(sdata->client, STMFTS_SLEEP_IN);
+		msleep(20);
+	}
+
 	regulator_bulk_disable(ARRAY_SIZE(stmfts_supplies),
 			       sdata->supplies);
 }
@@ -656,6 +983,7 @@ static int stmfts_probe(struct i2c_client *client)
 	struct device *dev = &client->dev;
 	int err;
 	struct stmfts_data *sdata;
+	const struct of_device_id *match;
 
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
 						I2C_FUNC_SMBUS_BYTE_DATA |
@@ -672,6 +1000,13 @@ static int stmfts_probe(struct i2c_client *client)
 	mutex_init(&sdata->mutex);
 	init_completion(&sdata->cmd_done);
 
+	match = of_match_device(dev->driver->of_match_table, dev);
+	sdata->ops = of_device_get_match_data(dev);
+	if (match && of_device_is_compatible(dev->of_node, "st,stmfts5"))
+		sdata->is_fts5 = true;
+	else
+		sdata->is_fts5 = false;
+
 	err = devm_regulator_bulk_get_const(dev,
 					    ARRAY_SIZE(stmfts_supplies),
 					    stmfts_supplies,
@@ -685,34 +1020,80 @@ static int stmfts_probe(struct i2c_client *client)
 		return dev_err_probe(dev, PTR_ERR(sdata->reset_gpio),
 				     "Failed to get GPIO 'reset'\n");
 
+	if (sdata->is_fts5) {
+		sdata->mode_switch_gpio = devm_gpiod_get_optional(&client->dev,
+								  "mode-switch",
+								  GPIOD_OUT_HIGH);
+		if (IS_ERR(sdata->mode_switch_gpio))
+			return dev_err_probe(dev, PTR_ERR(sdata->mode_switch_gpio),
+					     "Failed to get GPIO 'switch'\n");
+
+	}
+
 	sdata->input = devm_input_allocate_device(dev);
 	if (!sdata->input)
 		return -ENOMEM;
 
 	sdata->input->name = STMFTS_DEV_NAME;
 	sdata->input->id.bustype = BUS_I2C;
-	sdata->input->open = stmfts_input_open;
-	sdata->input->close = stmfts_input_close;
+	sdata->input->open = sdata->ops->input_open;
+	sdata->input->close = sdata->ops->input_close;
+
+	/* FTS5-specific input properties */
+	if (sdata->is_fts5) {
+		/* Mark as direct input device for calibration support */
+		__set_bit(INPUT_PROP_DIRECT, sdata->input->propbit);
+
+		/* Set up basic touch capabilities */
+		input_set_capability(sdata->input, EV_KEY, BTN_TOUCH);
+	}
 
 	input_set_capability(sdata->input, EV_ABS, ABS_MT_POSITION_X);
 	input_set_capability(sdata->input, EV_ABS, ABS_MT_POSITION_Y);
 	touchscreen_parse_properties(sdata->input, true, &sdata->prop);
 
+	/* Set resolution for accurate calibration (FTS5) */
+	if (sdata->is_fts5 && !input_abs_get_res(sdata->input, ABS_MT_POSITION_X)) {
+		input_abs_set_res(sdata->input, ABS_MT_POSITION_X, 10);
+		input_abs_set_res(sdata->input, ABS_MT_POSITION_Y, 10);
+	}
+
+	/* Enhanced MT parameters */
 	input_set_abs_params(sdata->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
 	input_set_abs_params(sdata->input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0);
-	input_set_abs_params(sdata->input, ABS_MT_ORIENTATION, 0, 255, 0, 0);
 	input_set_abs_params(sdata->input, ABS_MT_PRESSURE, 0, 255, 0, 0);
-	input_set_abs_params(sdata->input, ABS_DISTANCE, 0, 255, 0, 0);
+
+	if (sdata->is_fts5) {
+		input_set_abs_params(sdata->input, ABS_MT_DISTANCE, 0, 255, 0, 0);
+
+		/* Enable stylus support if requested */
+		sdata->stylus_enabled = device_property_read_bool(dev,
+								  "stylus-enabled");
+	} else {
+		input_set_abs_params(sdata->input, ABS_MT_ORIENTATION, 0, 255, 0, 0);
+		input_set_abs_params(sdata->input, ABS_DISTANCE, 0, 255, 0, 0);
+	}
 
 	sdata->use_key = device_property_read_bool(dev,
 						   "touch-key-connected");
-	if (sdata->use_key) {
+	if (sdata->use_key && !sdata->is_fts5) {
 		input_set_capability(sdata->input, EV_KEY, KEY_MENU);
 		input_set_capability(sdata->input, EV_KEY, KEY_BACK);
 	}
 
-	err = input_mt_init_slots(sdata->input,
-				  STMFTS_MAX_FINGERS, INPUT_MT_DIRECT);
+	/* Initialize touch tracking bitmaps (FTS5) */
+	if (sdata->is_fts5) {
+		sdata->touch_id = 0;
+		sdata->stylus_id = 0;
+
+		/* Initialize MT slots with support for pen tool type */
+		err = input_mt_init_slots(sdata->input, STMFTS_MAX_FINGERS,
+					  INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
+	} else {
+		err = input_mt_init_slots(sdata->input, STMFTS_MAX_FINGERS,
+					  INPUT_MT_DIRECT);
+	}
+
 	if (err)
 		return err;
 
@@ -732,9 +1113,11 @@ static int stmfts_probe(struct i2c_client *client)
 	if (err)
 		return err;
 
-	dev_dbg(dev, "initializing ST-Microelectronics FTS...\n");
+	dev_dbg(dev, "initializing ST-Microelectronics FTS%s...\n",
+		sdata->is_fts5 ? "5" : "");
+
 
-	err = stmfts_power_on(sdata);
+	err = sdata->ops->power_on(sdata);
 	if (err)
 		return err;
 
@@ -746,7 +1129,7 @@ static int stmfts_probe(struct i2c_client *client)
 	if (err)
 		return err;
 
-	if (sdata->use_key) {
+	if (sdata->use_key && !sdata->is_fts5) {
 		err = stmfts_enable_led(sdata);
 		if (err) {
 			/*
@@ -790,8 +1173,47 @@ static int stmfts_runtime_resume(struct device *dev)
 	int ret;
 
 	ret = i2c_smbus_write_byte(client, STMFTS_SLEEP_OUT);
-	if (ret)
+	if (ret) {
 		dev_err(dev, "failed to resume device: %d\n", ret);
+		return ret;
+	}
+
+	if (sdata->is_fts5) {
+		msleep(20);
+
+		/* Perform capacitance tuning after wakeup */
+		ret = i2c_smbus_write_byte(client, STMFTS_MS_CX_TUNING);
+		if (ret)
+			dev_warn(dev, "MS_CX_TUNING failed: %d\n", ret);
+		msleep(20);
+
+		ret = i2c_smbus_write_byte(client, STMFTS_SS_CX_TUNING);
+		if (ret)
+			dev_warn(dev, "SS_CX_TUNING failed: %d\n", ret);
+		msleep(20);
+
+		/* Force calibration */
+		ret = i2c_smbus_write_byte(client, STMFTS_FULL_FORCE_CALIBRATION);
+		if (ret)
+			dev_warn(dev, "FORCE_CALIBRATION failed: %d\n", ret);
+		msleep(50);
+
+		/* Enable controller interrupts */
+		u8 int_enable_cmd[4] = {0xB6, 0x00, 0x2C, 0x01};
+		struct i2c_msg msg = {
+			.addr = client->addr,
+			.len = 4,
+			.buf = int_enable_cmd,
+		};
+
+		ret = i2c_transfer(client->adapter, &msg, 1);
+		if (ret != 1)
+			return ret < 0 ? ret : -EIO;
+
+		msleep(20);
+
+		return 0;
+	}
 
 	return ret;
 }
@@ -809,7 +1231,7 @@ static int stmfts_resume(struct device *dev)
 {
 	struct stmfts_data *sdata = dev_get_drvdata(dev);
 
-	return stmfts_power_on(sdata);
+	return sdata->ops->power_on(sdata);
 }
 
 static const struct dev_pm_ops stmfts_pm_ops = {
@@ -818,8 +1240,23 @@ static const struct dev_pm_ops stmfts_pm_ops = {
 };
 
 #ifdef CONFIG_OF
+static const struct stmfts_chip_ops stmfts4_ops = {
+	.power_on	= stmfts_power_on,
+	.input_open	= stmfts_input_open,
+	.input_close	= stmfts_input_close,
+	.parse_events	= stmfts_parse_events,
+};
+
+static const struct stmfts_chip_ops stmfts5_ops = {
+	.power_on	= stmfts5_power_on,
+	.input_open	= stmfts5_input_open,
+	.input_close	= stmfts5_input_close,
+	.parse_events	= stmfts5_parse_events,
+};
+
 static const struct of_device_id stmfts_of_match[] = {
-	{ .compatible = "st,stmfts", },
+	{ .compatible = "st,stmfts",	.data = &stmfts4_ops },
+	{ .compatible = "st,stmfts5",	.data = &stmfts5_ops },
 	{ },
 };
 MODULE_DEVICE_TABLE(of, stmfts_of_match);
@@ -847,5 +1284,7 @@ static struct i2c_driver stmfts_driver = {
 module_i2c_driver(stmfts_driver);
 
 MODULE_AUTHOR("Andi Shyti <andi.shyti@samsung.com>");
+MODULE_AUTHOR("David Heidelberg <david@ixit.cz>");
+MODULE_AUTHOR("Petr Hodina <petr.hodina@protonmail.com>");
 MODULE_DESCRIPTION("STMicroelectronics FTS Touch Screen");
 MODULE_LICENSE("GPL");

-- 
2.53.0




^ permalink raw reply related

* [PATCH WIP v3 04/11] Input: stmfts - abstract reading information from the firmware
From: David Heidelberg via B4 Relay @ 2026-04-03 17:08 UTC (permalink / raw)
  To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
	Bjorn Andersson, Konrad Dybcio
  Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
	linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
	phone-devel, David Heidelberg
In-Reply-To: <20260403-stmfts5-v3-0-5da768cfd201@ixit.cz>

From: David Heidelberg <david@ixit.cz>

Improves readability and makes splitting power on function in following
commit easier.

Signed-off-by: David Heidelberg <david@ixit.cz>
---
 drivers/input/touchscreen/stmfts.c | 36 ++++++++++++++++++++++++------------
 1 file changed, 24 insertions(+), 12 deletions(-)

diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index ff884e04ad4c8..71d9b747ccfc5 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -518,22 +518,11 @@ static struct attribute *stmfts_sysfs_attrs[] = {
 };
 ATTRIBUTE_GROUPS(stmfts_sysfs);
 
-static int stmfts_power_on(struct stmfts_data *sdata)
+static int stmfts_read_system_info(struct stmfts_data *sdata)
 {
 	int err;
 	u8 reg[8];
 
-	err = regulator_bulk_enable(ARRAY_SIZE(stmfts_supplies),
-				    sdata->supplies);
-	if (err)
-		return err;
-
-	/*
-	 * The datasheet does not specify the power on time, but considering
-	 * that the reset time is < 10ms, I sleep 20ms to be sure
-	 */
-	msleep(20);
-
 	err = i2c_smbus_read_i2c_block_data(sdata->client, STMFTS_READ_INFO,
 					    sizeof(reg), reg);
 	if (err < 0)
@@ -547,6 +536,29 @@ static int stmfts_power_on(struct stmfts_data *sdata)
 	sdata->config_id = reg[4];
 	sdata->config_ver = reg[5];
 
+	return 0;
+}
+
+static int stmfts_power_on(struct stmfts_data *sdata)
+{
+	int err;
+
+	err = regulator_bulk_enable(ARRAY_SIZE(stmfts_supplies),
+				    sdata->supplies);
+	if (err)
+		return err;
+
+	/*
+	 * The datasheet does not specify the power on time, but considering
+	 * that the reset time is < 10ms, I sleep 20ms to be sure
+	 */
+	msleep(20);
+
+
+	err = stmfts_read_system_info(sdata);
+	if (err)
+		return err;
+
 	enable_irq(sdata->client->irq);
 
 	msleep(50);

-- 
2.53.0




^ permalink raw reply related

* [PATCH WIP v3 11/11] arm64: dts: qcom: sdm845-google: Add STM FTS touchscreen support
From: David Heidelberg via B4 Relay @ 2026-04-03 17:08 UTC (permalink / raw)
  To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
	Bjorn Andersson, Konrad Dybcio
  Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
	linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
	phone-devel, David Heidelberg
In-Reply-To: <20260403-stmfts5-v3-0-5da768cfd201@ixit.cz>

From: Petr Hodina <petr.hodina@protonmail.com>

Basic touchscreen connected to second i2c bus.

Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Co-developed-by: David Heidelberg <david@ixit.cz>
Signed-off-by: David Heidelberg <david@ixit.cz>
---
 arch/arm64/boot/dts/qcom/sdm845-google-blueline.dts | 19 ++++++++++++++++++-
 arch/arm64/boot/dts/qcom/sdm845-google-common.dtsi  |  2 +-
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/sdm845-google-blueline.dts b/arch/arm64/boot/dts/qcom/sdm845-google-blueline.dts
index fa89be500fb85..8fb988130b551 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-google-blueline.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-google-blueline.dts
@@ -26,7 +26,24 @@ &i2c2 {
 
 	status = "okay";
 
-	/* ST,FTS @ 49 */
+	touchscreen@49 {
+		compatible = "st,stmfts5";
+		reg = <0x49>;
+
+		pinctrl-0 = <&touchscreen_irq_n>, <&touchscreen_reset>;
+		pinctrl-names = "default";
+
+		interrupts-extended = <&tlmm 125 IRQ_TYPE_LEVEL_LOW>;
+
+		mode-switch-gpios = <&tlmm 136 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&tlmm 99 GPIO_ACTIVE_LOW>;
+
+		avdd-supply = <&vreg_l14a_1p8>;
+		vdd-supply = <&vreg_l19a_3p3>;
+
+		touchscreen-size-x = <1080>;
+		touchscreen-size-y = <2160>;
+	};
 };
 
 &mdss_dsi0 {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-google-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-google-common.dtsi
index 6930066857768..4653c63ec26d2 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-google-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-google-common.dtsi
@@ -466,7 +466,7 @@ touchscreen_reset: ts-reset-state {
 		bias-pull-up;
 	};
 
-	touchscreen_pins: ts-pins-gpio-state {
+	touchscreen_irq_n: ts-irq-n-gpio-state {
 		pins = "gpio125";
 		function = "gpio";
 		drive-strength = <2>;

-- 
2.53.0




^ permalink raw reply related

* [PATCH WIP v3 02/11] Input: stmfts - Use dev struct directly
From: David Heidelberg via B4 Relay @ 2026-04-03 17:08 UTC (permalink / raw)
  To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
	Bjorn Andersson, Konrad Dybcio
  Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
	linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
	phone-devel, David Heidelberg
In-Reply-To: <20260403-stmfts5-v3-0-5da768cfd201@ixit.cz>

From: David Heidelberg <david@ixit.cz>

Makes the code better readable and noticably shorter.

Signed-off-by: David Heidelberg <david@ixit.cz>
---
 drivers/input/touchscreen/stmfts.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index def6bd0c8e059..7b1e975a85668 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -619,6 +619,7 @@ static int stmfts_enable_led(struct stmfts_data *sdata)
 
 static int stmfts_probe(struct i2c_client *client)
 {
+	struct device *dev = &client->dev;
 	int err;
 	struct stmfts_data *sdata;
 
@@ -627,7 +628,7 @@ static int stmfts_probe(struct i2c_client *client)
 						I2C_FUNC_SMBUS_I2C_BLOCK))
 		return -ENODEV;
 
-	sdata = devm_kzalloc(&client->dev, sizeof(*sdata), GFP_KERNEL);
+	sdata = devm_kzalloc(dev, sizeof(*sdata), GFP_KERNEL);
 	if (!sdata)
 		return -ENOMEM;
 
@@ -639,13 +640,13 @@ static int stmfts_probe(struct i2c_client *client)
 
 	sdata->regulators[STMFTS_REGULATOR_VDD].supply = "vdd";
 	sdata->regulators[STMFTS_REGULATOR_AVDD].supply = "avdd";
-	err = devm_regulator_bulk_get(&client->dev,
+	err = devm_regulator_bulk_get(dev,
 				      ARRAY_SIZE(sdata->regulators),
 				      sdata->regulators);
 	if (err)
 		return err;
 
-	sdata->input = devm_input_allocate_device(&client->dev);
+	sdata->input = devm_input_allocate_device(dev);
 	if (!sdata->input)
 		return -ENOMEM;
 
@@ -664,7 +665,7 @@ static int stmfts_probe(struct i2c_client *client)
 	input_set_abs_params(sdata->input, ABS_MT_PRESSURE, 0, 255, 0, 0);
 	input_set_abs_params(sdata->input, ABS_DISTANCE, 0, 255, 0, 0);
 
-	sdata->use_key = device_property_read_bool(&client->dev,
+	sdata->use_key = device_property_read_bool(dev,
 						   "touch-key-connected");
 	if (sdata->use_key) {
 		input_set_capability(sdata->input, EV_KEY, KEY_MENU);
@@ -685,20 +686,20 @@ static int stmfts_probe(struct i2c_client *client)
 	 * interrupts. To be on the safe side it's better to not enable
 	 * the interrupts during their request.
 	 */
-	err = devm_request_threaded_irq(&client->dev, client->irq,
+	err = devm_request_threaded_irq(dev, client->irq,
 					NULL, stmfts_irq_handler,
 					IRQF_ONESHOT | IRQF_NO_AUTOEN,
 					"stmfts_irq", sdata);
 	if (err)
 		return err;
 
-	dev_dbg(&client->dev, "initializing ST-Microelectronics FTS...\n");
+	dev_dbg(dev, "initializing ST-Microelectronics FTS...\n");
 
 	err = stmfts_power_on(sdata);
 	if (err)
 		return err;
 
-	err = devm_add_action_or_reset(&client->dev, stmfts_power_off, sdata);
+	err = devm_add_action_or_reset(dev, stmfts_power_off, sdata);
 	if (err)
 		return err;
 
@@ -715,13 +716,13 @@ static int stmfts_probe(struct i2c_client *client)
 			 * without LEDs. The ledvdd regulator pointer will be
 			 * used as a flag.
 			 */
-			dev_warn(&client->dev, "unable to use touchkey leds\n");
+			dev_warn(dev, "unable to use touchkey leds\n");
 			sdata->ledvdd = NULL;
 		}
 	}
 
-	pm_runtime_enable(&client->dev);
-	device_enable_async_suspend(&client->dev);
+	pm_runtime_enable(dev);
+	device_enable_async_suspend(dev);
 
 	return 0;
 }

-- 
2.53.0




^ permalink raw reply related

* [PATCH WIP v3 08/11] Input: stmfts - add optional reset GPIO support
From: David Heidelberg via B4 Relay @ 2026-04-03 17:08 UTC (permalink / raw)
  To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
	Bjorn Andersson, Konrad Dybcio
  Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
	linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
	phone-devel, David Heidelberg
In-Reply-To: <20260403-stmfts5-v3-0-5da768cfd201@ixit.cz>

From: Petr Hodina <petr.hodina@protonmail.com>

Add support for an optional "reset-gpios" property. If present, the
driver drives the reset line high at probe time and releases it during
power-on, after the regulators have been enabled.

Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Co-developed-by: David Heidelberg <david@ixit.cz>
Signed-off-by: David Heidelberg <david@ixit.cz>
---
 drivers/input/touchscreen/stmfts.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index 5f7de5e687da2..04110006f54a0 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -77,6 +77,7 @@ static const struct regulator_bulk_data stmfts_supplies[] = {
 struct stmfts_data {
 	struct i2c_client *client;
 	struct input_dev *input;
+	struct gpio_desc *reset_gpio;
 	struct led_classdev led_cdev;
 	struct mutex mutex;
 
@@ -539,6 +540,15 @@ static int stmfts_read_system_info(struct stmfts_data *sdata)
 	return 0;
 }
 
+static void stmfts_reset(struct stmfts_data *sdata)
+{
+	gpiod_set_value_cansleep(sdata->reset_gpio, 1);
+	msleep(20);
+
+	gpiod_set_value_cansleep(sdata->reset_gpio, 0);
+	msleep(50);
+}
+
 static int stmfts_power_on(struct stmfts_data *sdata)
 {
 	int err;
@@ -548,6 +558,9 @@ static int stmfts_power_on(struct stmfts_data *sdata)
 	if (err)
 		return err;
 
+	if (sdata->reset_gpio)
+		stmfts_reset(sdata);
+
 	/*
 	 * The datasheet does not specify the power on time, but considering
 	 * that the reset time is < 10ms, I sleep 20ms to be sure
@@ -606,6 +619,10 @@ static void stmfts_power_off(void *data)
 	struct stmfts_data *sdata = data;
 
 	disable_irq(sdata->client->irq);
+
+	if (sdata->reset_gpio)
+		gpiod_set_value_cansleep(sdata->reset_gpio, 1);
+
 	regulator_bulk_disable(ARRAY_SIZE(stmfts_supplies),
 			       sdata->supplies);
 }
@@ -662,6 +679,12 @@ static int stmfts_probe(struct i2c_client *client)
 	if (err)
 		return err;
 
+	sdata->reset_gpio = devm_gpiod_get_optional(dev, "reset",
+						    GPIOD_OUT_HIGH);
+	if (IS_ERR(sdata->reset_gpio))
+		return dev_err_probe(dev, PTR_ERR(sdata->reset_gpio),
+				     "Failed to get GPIO 'reset'\n");
+
 	sdata->input = devm_input_allocate_device(dev);
 	if (!sdata->input)
 		return -ENOMEM;

-- 
2.53.0




^ permalink raw reply related

* [PATCH WIP v3 07/11] dt-bindings: input: touchscreen: st,stmfts: Introduce reset GPIO
From: David Heidelberg via B4 Relay @ 2026-04-03 17:08 UTC (permalink / raw)
  To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
	Bjorn Andersson, Konrad Dybcio
  Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
	linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
	phone-devel, David Heidelberg
In-Reply-To: <20260403-stmfts5-v3-0-5da768cfd201@ixit.cz>

From: David Heidelberg <david@ixit.cz>

FTS has associated reset GPIO, document it.

Signed-off-by: David Heidelberg <david@ixit.cz>
---
 Documentation/devicetree/bindings/input/touchscreen/st,stmfts.yaml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/input/touchscreen/st,stmfts.yaml b/Documentation/devicetree/bindings/input/touchscreen/st,stmfts.yaml
index 12256ae7df90d..64c4f24ea3dd0 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/st,stmfts.yaml
+++ b/Documentation/devicetree/bindings/input/touchscreen/st,stmfts.yaml
@@ -40,6 +40,10 @@ properties:
   vdd-supply:
     description: Power supply
 
+  reset-gpios:
+    description: Reset GPIO (active-low)
+    maxItems: 1
+
 required:
   - compatible
   - reg

-- 
2.53.0




^ permalink raw reply related

* [PATCH WIP v3 09/11] dt-bindings: input: touchscreen: st,stmfts: Introduce STM FTS5
From: David Heidelberg via B4 Relay @ 2026-04-03 17:08 UTC (permalink / raw)
  To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
	Bjorn Andersson, Konrad Dybcio
  Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
	linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
	phone-devel, David Heidelberg
In-Reply-To: <20260403-stmfts5-v3-0-5da768cfd201@ixit.cz>

From: David Heidelberg <david@ixit.cz>

Introduce more recent STM FTS5 touchscreen support.

Signed-off-by: David Heidelberg <david@ixit.cz>
---
 .../devicetree/bindings/input/touchscreen/st,stmfts.yaml  | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/input/touchscreen/st,stmfts.yaml b/Documentation/devicetree/bindings/input/touchscreen/st,stmfts.yaml
index 64c4f24ea3dd0..441fc92b9a4ed 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/st,stmfts.yaml
+++ b/Documentation/devicetree/bindings/input/touchscreen/st,stmfts.yaml
@@ -16,10 +16,19 @@ description:
 
 allOf:
   - $ref: touchscreen.yaml#
+  - if:
+      properties:
+        compatible:
+          const: st,stmfts5
+    then:
+      required:
+        - mode-switch-gpios
 
 properties:
   compatible:
-    const: st,stmfts
+    enum:
+      - st,stmfts
+      - st,stmfts5
 
   reg:
     maxItems: 1
@@ -40,6 +49,10 @@ properties:
   vdd-supply:
     description: Power supply
 
+  mode-switch-gpios:
+    description: Switch between touchscreen SLPI and AP mode.
+    maxItems: 1
+
   reset-gpios:
     description: Reset GPIO (active-low)
     maxItems: 1

-- 
2.53.0




^ permalink raw reply related

* [PATCH WIP v3 05/11] Input: stmfts - disable regulators when power on fails
From: David Heidelberg via B4 Relay @ 2026-04-03 17:08 UTC (permalink / raw)
  To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
	Bjorn Andersson, Konrad Dybcio
  Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
	linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
	phone-devel, David Heidelberg
In-Reply-To: <20260403-stmfts5-v3-0-5da768cfd201@ixit.cz>

From: David Heidelberg <david@ixit.cz>

We must power off regulators after failing at power on phase.

Signed-off-by: David Heidelberg <david@ixit.cz>
---
 drivers/input/touchscreen/stmfts.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index 71d9b747ccfc5..a90528b76f52b 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -557,7 +557,7 @@ static int stmfts_power_on(struct stmfts_data *sdata)
 
 	err = stmfts_read_system_info(sdata);
 	if (err)
-		return err;
+		goto power_off;
 
 	enable_irq(sdata->client->irq);
 
@@ -565,11 +565,11 @@ static int stmfts_power_on(struct stmfts_data *sdata)
 
 	err = stmfts_command(sdata, STMFTS_SYSTEM_RESET);
 	if (err)
-		return err;
+		goto power_off;
 
 	err = stmfts_command(sdata, STMFTS_SLEEP_OUT);
 	if (err)
-		return err;
+		goto power_off;
 
 	/* optional tuning */
 	err = stmfts_command(sdata, STMFTS_MS_CX_TUNING);
@@ -585,7 +585,7 @@ static int stmfts_power_on(struct stmfts_data *sdata)
 
 	err = stmfts_command(sdata, STMFTS_FULL_FORCE_CALIBRATION);
 	if (err)
-		return err;
+		goto power_off;
 
 	/*
 	 * At this point no one is using the touchscreen
@@ -594,6 +594,11 @@ static int stmfts_power_on(struct stmfts_data *sdata)
 	(void) i2c_smbus_write_byte(sdata->client, STMFTS_SLEEP_IN);
 
 	return 0;
+
+power_off:
+	regulator_bulk_disable(ARRAY_SIZE(stmfts_supplies),
+			       sdata->supplies);
+	return err;
 }
 
 static void stmfts_power_off(void *data)

-- 
2.53.0




^ permalink raw reply related

* [PATCH WIP v3 01/11] Input: stmfts - Fix the MODULE_LICENSE() string
From: David Heidelberg via B4 Relay @ 2026-04-03 17:08 UTC (permalink / raw)
  To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
	Bjorn Andersson, Konrad Dybcio
  Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
	linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
	phone-devel, David Heidelberg
In-Reply-To: <20260403-stmfts5-v3-0-5da768cfd201@ixit.cz>

From: David Heidelberg <david@ixit.cz>

Replace the bogus "GPL v2" with "GPL" as MODULE_LICNSE() string. The
value does not declare the module's exact license, but only lets the
module loader test whether the module is Free Software or not.

See commit bf7fbeeae6db ("module: Cure the MODULE_LICENSE "GPL" vs.
"GPL v2" bogosity") in the details of the issue. The fix is to use
"GPL" for all modules under any variant of the GPL.

Signed-off-by: David Heidelberg <david@ixit.cz>
---
 drivers/input/touchscreen/stmfts.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index 8af87d0b6eb64..def6bd0c8e059 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -807,4 +807,4 @@ module_i2c_driver(stmfts_driver);
 
 MODULE_AUTHOR("Andi Shyti <andi.shyti@samsung.com>");
 MODULE_DESCRIPTION("STMicroelectronics FTS Touch Screen");
-MODULE_LICENSE("GPL v2");
+MODULE_LICENSE("GPL");

-- 
2.53.0




^ permalink raw reply related

* [PATCH WIP v3 03/11] Input: stmfts - Switch to devm_regulator_bulk_get_const
From: David Heidelberg via B4 Relay @ 2026-04-03 17:08 UTC (permalink / raw)
  To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
	Bjorn Andersson, Konrad Dybcio
  Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
	linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
	phone-devel, David Heidelberg
In-Reply-To: <20260403-stmfts5-v3-0-5da768cfd201@ixit.cz>

From: David Heidelberg <david@ixit.cz>

Switch to devm_regulator_bulk_get_const() to stop setting the supplies
list in probe(), and move the regulator_bulk_data struct in static const.

Signed-off-by: David Heidelberg <david@ixit.cz>
---
 drivers/input/touchscreen/stmfts.c | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index 7b1e975a85668..ff884e04ad4c8 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -69,9 +69,9 @@
 #define STMFTS_MAX_FINGERS	10
 #define STMFTS_DEV_NAME		"stmfts"
 
-enum stmfts_regulators {
-	STMFTS_REGULATOR_VDD,
-	STMFTS_REGULATOR_AVDD,
+static const struct regulator_bulk_data stmfts_supplies[] = {
+	{ .supply = "vdd" },
+	{ .supply = "avdd" },
 };
 
 struct stmfts_data {
@@ -82,7 +82,7 @@ struct stmfts_data {
 
 	struct touchscreen_properties prop;
 
-	struct regulator_bulk_data regulators[2];
+	struct regulator_bulk_data *supplies;
 
 	/*
 	 * Presence of ledvdd will be used also to check
@@ -523,8 +523,8 @@ static int stmfts_power_on(struct stmfts_data *sdata)
 	int err;
 	u8 reg[8];
 
-	err = regulator_bulk_enable(ARRAY_SIZE(sdata->regulators),
-				    sdata->regulators);
+	err = regulator_bulk_enable(ARRAY_SIZE(stmfts_supplies),
+				    sdata->supplies);
 	if (err)
 		return err;
 
@@ -589,8 +589,8 @@ static void stmfts_power_off(void *data)
 	struct stmfts_data *sdata = data;
 
 	disable_irq(sdata->client->irq);
-	regulator_bulk_disable(ARRAY_SIZE(sdata->regulators),
-						sdata->regulators);
+	regulator_bulk_disable(ARRAY_SIZE(stmfts_supplies),
+			       sdata->supplies);
 }
 
 static int stmfts_enable_led(struct stmfts_data *sdata)
@@ -638,11 +638,10 @@ static int stmfts_probe(struct i2c_client *client)
 	mutex_init(&sdata->mutex);
 	init_completion(&sdata->cmd_done);
 
-	sdata->regulators[STMFTS_REGULATOR_VDD].supply = "vdd";
-	sdata->regulators[STMFTS_REGULATOR_AVDD].supply = "avdd";
-	err = devm_regulator_bulk_get(dev,
-				      ARRAY_SIZE(sdata->regulators),
-				      sdata->regulators);
+	err = devm_regulator_bulk_get_const(dev,
+					    ARRAY_SIZE(stmfts_supplies),
+					    stmfts_supplies,
+					    &sdata->supplies);
 	if (err)
 		return err;
 

-- 
2.53.0




^ permalink raw reply related

* Re: [PATCH v1] PCI: imx6: Add force_suspend flag to override L1SS suspend skip
From: mani @ 2026-04-03 17:03 UTC (permalink / raw)
  To: Hongxing Zhu
  Cc: Bjorn Helgaas, Frank Li, jingoohan1@gmail.com,
	l.stach@pengutronix.de, lpieralisi@kernel.org,
	kwilczynski@kernel.org, robh@kernel.org, bhelgaas@google.com,
	s.hauer@pengutronix.de, kernel@pengutronix.de, festevam@gmail.com,
	linux-pci@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	imx@lists.linux.dev, linux-kernel@vger.kernel.org,
	stable@vger.kernel.org
In-Reply-To: <AS8PR04MB8833137860C682F9E1E743E08C48A@AS8PR04MB8833.eurprd04.prod.outlook.com>

On Tue, Mar 24, 2026 at 02:01:58AM +0000, Hongxing Zhu wrote:
> > -----Original Message-----
> > From: Bjorn Helgaas <helgaas@kernel.org>
> > Sent: 2026年3月24日 6:09
> > To: Hongxing Zhu <hongxing.zhu@nxp.com>
> > Cc: Frank Li <frank.li@nxp.com>; jingoohan1@gmail.com;
> > l.stach@pengutronix.de; lpieralisi@kernel.org; kwilczynski@kernel.org;
> > mani@kernel.org; robh@kernel.org; bhelgaas@google.com;
> > s.hauer@pengutronix.de; kernel@pengutronix.de; festevam@gmail.com;
> > linux-pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> > imx@lists.linux.dev; linux-kernel@vger.kernel.org; stable@vger.kernel.org
> > Subject: Re: [PATCH v1] PCI: imx6: Add force_suspend flag to override L1SS
> > suspend skip
> > 
> > On Wed, Mar 18, 2026 at 02:55:45AM +0000, Hongxing Zhu wrote:
> > > > -----Original Message-----
> > > > From: Bjorn Helgaas <helgaas@kernel.org>
> > > ... [messed up quoting]
> > 
> > > > On Tue, Mar 17, 2026 at 02:12:56PM +0800, Richard Zhu wrote:
> > > > > Add a force_suspend flag to allow platform drivers to force the
> > > > > PCIe link into L2 state during suspend, even when L1SS (ASPM L1
> > > > > Sub-States) is enabled.
> > > > >
> > > > > By default, the DesignWare PCIe host controller skips L2 suspend
> > > > > when L1SS is supported to meet low resume latency requirements for
> > > > > devices like NVMe. However, some platforms like i.MX PCIe need to
> > > > > enter L2 state for proper power management regardless of L1SS
> > support.
> > > > >
> > > > > Enable force_suspend for i.MX PCIe to ensure the link enters L2
> > > > > during system suspend.
> > > >
> > > > I'm a little bit skeptical about this.
> > > >
> > > > What exactly does a "low resume latency requirement" mean?  Is this
> > > > an actual functional requirement that's special to NVMe, or is it
> > > > just the desire for low resume latency that everybody has for all
> > > > devices?
> > >
> > > From my understanding, L1SS mode is characterized by lower latency
> > > when compared to L2 or L3 modes.
> > >
> > > It can be used on all devices, avoiding frequent power on/off cycles.
> > > NVMe can also extend the service life of the equipment.
> > 
> > All the above applies to all platforms, so it's not an argument for
> > i.MX-specific code here.
> >
> Hi Bjorn:
> Thanks for your kindly review. 
> Yes, it is.
> > > > Is there something special about i.MX here?  Why do we want i.MX to
> > > > be different from other host controllers?
> > >
> > > i.MX PCIe loses power supply during Deep Sleep Mode (DSM), requiring
> > > full reinitialization after system wake-up.
> > 
> > I don't know what DSM means in PCIe or how it would help justify this
> > change.
> > 
> i.MX PCIe power is gated off during suspend, requiring full reinitialization
> on resume
> 

Is this an unconditional behavior? What if the PCIe device is configured as a
wakeup source like WOL, WOW? And if you connect NVMe, this behavior will result
in resume failure as NVMe driver expects the power to be retained if ASPM is
supported.

- Mani

-- 
மணிவண்ணன் சதாசிவம்


^ permalink raw reply

* Re: [PATCH] ASoC: imx-rpmsg: Add DSD format support with dynamic DAI format switching
From: Mark Brown @ 2026-04-03 14:13 UTC (permalink / raw)
  To: festevam, nicoleotsuka, lgirdwood, perex, tiwai, Frank.Li,
	s.hauer, kernel, linux-sound, linuxppc-dev, imx, linux-arm-kernel,
	linux-kernel, Chancel Liu
In-Reply-To: <20260326055614.3614104-1-chancel.liu@nxp.com>

On Thu, 26 Mar 2026 14:56:14 +0900, Chancel Liu wrote:
> ASoC: imx-rpmsg: Add DSD format support with dynamic DAI format switching

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-7.1

Thanks!

[1/1] ASoC: imx-rpmsg: Add DSD format support with dynamic DAI format switching
      https://git.kernel.org/broonie/sound/c/ccd7e53b7d6f

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 bpf-next v12 2/5] bpf: Pass bpf_verifier_env to JIT
From: Emil Tsalapatis @ 2026-04-03 16:38 UTC (permalink / raw)
  To: Xu Kuohai, bpf, linux-kernel, linux-arm-kernel
  Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Eduard Zingerman, Yonghong Song, Puranjay Mohan,
	Anton Protopopov, Alexis Lothoré, Shahab Vahedi,
	Russell King, Tiezhu Yang, Hengqi Chen, Johan Almbladh,
	Paul Burton, Hari Bathini, Christophe Leroy, Naveen N Rao,
	Luke Nelson, Xi Wang, Björn Töpel, Pu Lehui,
	Ilya Leoshkevich, Heiko Carstens, Vasily Gorbik, David S . Miller,
	Wang YanQing
In-Reply-To: <20260403132811.753894-3-xukuohai@huaweicloud.com>

On Fri Apr 3, 2026 at 9:28 AM EDT, Xu Kuohai wrote:
> From: Xu Kuohai <xukuohai@huawei.com>
>
> Pass bpf_verifier_env to bpf_int_jit_compile(). The follow-up patch will
> use env->insn_aux_data in the JIT stage to detect indirect jump targets.
>
> Since bpf_prog_select_runtime() can be called by cbpf and lib/test_bpf.c
> code without verifier, introduce helper __bpf_prog_select_runtime()
> to accept the env parameter.
>
> Remove the call to bpf_prog_select_runtime() in bpf_prog_load(), and
> switch to call __bpf_prog_select_runtime() in the verifier, with env
> variable passed. The original bpf_prog_select_runtime() is preserved for
> cbpf and lib/test_bpf.c, where env is NULL.
>
> Now all constants blinding calls are moved into the verifier, except
> the cbpf and lib/test_bpf.c cases. The instructions arrays are adjusted
> by bpf_patch_insn_data() function for normal cases, so there is no need
> to call adjust_insn_arrays() in bpf_jit_blind_constants(). Remove it.
>

Provided the bot comments are fixed (also check the comment Sashiko raises about a
kvmalloc()-to-vfree mismatch):

Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>

> Reviewed-by: Anton Protopopov <a.s.protopopov@gmail.com>
> Signed-off-by: Xu Kuohai <xukuohai@huawei.com>
> ---
>  arch/arc/net/bpf_jit_core.c      |  2 +-
>  arch/arm/net/bpf_jit_32.c        |  2 +-
>  arch/arm64/net/bpf_jit_comp.c    |  2 +-
>  arch/loongarch/net/bpf_jit.c     |  2 +-
>  arch/mips/net/bpf_jit_comp.c     |  2 +-
>  arch/parisc/net/bpf_jit_core.c   |  2 +-
>  arch/powerpc/net/bpf_jit_comp.c  |  2 +-
>  arch/riscv/net/bpf_jit_core.c    |  2 +-
>  arch/s390/net/bpf_jit_comp.c     |  2 +-
>  arch/sparc/net/bpf_jit_comp_64.c |  2 +-
>  arch/x86/net/bpf_jit_comp.c      |  2 +-
>  arch/x86/net/bpf_jit_comp32.c    |  2 +-
>  include/linux/filter.h           | 17 +++++-
>  kernel/bpf/core.c                | 93 +++++++++++++++++---------------
>  kernel/bpf/syscall.c             |  4 --
>  kernel/bpf/verifier.c            | 36 +++++++------
>  16 files changed, 98 insertions(+), 76 deletions(-)
>
> diff --git a/arch/arc/net/bpf_jit_core.c b/arch/arc/net/bpf_jit_core.c
> index 973ceae48675..639a2736f029 100644
> --- a/arch/arc/net/bpf_jit_core.c
> +++ b/arch/arc/net/bpf_jit_core.c
> @@ -1400,7 +1400,7 @@ static struct bpf_prog *do_extra_pass(struct bpf_prog *prog)
>   * (re)locations involved that their addresses are not known
>   * during the first run.
>   */
> -struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
> +struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)
>  {
>  	vm_dump(prog);
>  
> diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
> index e6b1bb2de627..1628b6fc70a4 100644
> --- a/arch/arm/net/bpf_jit_32.c
> +++ b/arch/arm/net/bpf_jit_32.c
> @@ -2142,7 +2142,7 @@ bool bpf_jit_needs_zext(void)
>  	return true;
>  }
>  
> -struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
> +struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)
>  {
>  	struct bpf_binary_header *header;
>  	struct jit_ctx ctx;
> diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
> index cd5a72fff500..7212ec89dfe3 100644
> --- a/arch/arm64/net/bpf_jit_comp.c
> +++ b/arch/arm64/net/bpf_jit_comp.c
> @@ -2006,7 +2006,7 @@ struct arm64_jit_data {
>  	struct jit_ctx ctx;
>  };
>  
> -struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
> +struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)
>  {
>  	int image_size, prog_size, extable_size, extable_align, extable_offset;
>  	struct bpf_binary_header *header;
> diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c
> index fcc8c0c29fb0..5149ce4cef7e 100644
> --- a/arch/loongarch/net/bpf_jit.c
> +++ b/arch/loongarch/net/bpf_jit.c
> @@ -1920,7 +1920,7 @@ int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
>  	return ret < 0 ? ret : ret * LOONGARCH_INSN_SIZE;
>  }
>  
> -struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
> +struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)
>  {
>  	bool extra_pass = false;
>  	u8 *image_ptr, *ro_image_ptr;
> diff --git a/arch/mips/net/bpf_jit_comp.c b/arch/mips/net/bpf_jit_comp.c
> index d2b6c955f18e..6ee4abe6a1f7 100644
> --- a/arch/mips/net/bpf_jit_comp.c
> +++ b/arch/mips/net/bpf_jit_comp.c
> @@ -909,7 +909,7 @@ bool bpf_jit_needs_zext(void)
>  	return true;
>  }
>  
> -struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
> +struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)
>  {
>  	struct bpf_binary_header *header = NULL;
>  	struct jit_context ctx;
> diff --git a/arch/parisc/net/bpf_jit_core.c b/arch/parisc/net/bpf_jit_core.c
> index 35dca372b5df..172770132440 100644
> --- a/arch/parisc/net/bpf_jit_core.c
> +++ b/arch/parisc/net/bpf_jit_core.c
> @@ -41,7 +41,7 @@ bool bpf_jit_needs_zext(void)
>  	return true;
>  }
>  
> -struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
> +struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)
>  {
>  	unsigned int prog_size = 0, extable_size = 0;
>  	bool extra_pass = false;
> diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> index 711028bebea3..27fecb4cc063 100644
> --- a/arch/powerpc/net/bpf_jit_comp.c
> +++ b/arch/powerpc/net/bpf_jit_comp.c
> @@ -129,7 +129,7 @@ bool bpf_jit_needs_zext(void)
>  	return true;
>  }
>  
> -struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
> +struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *fp)
>  {
>  	u32 proglen;
>  	u32 alloclen;
> diff --git a/arch/riscv/net/bpf_jit_core.c b/arch/riscv/net/bpf_jit_core.c
> index 527baa50dc68..768ac686b359 100644
> --- a/arch/riscv/net/bpf_jit_core.c
> +++ b/arch/riscv/net/bpf_jit_core.c
> @@ -41,7 +41,7 @@ bool bpf_jit_needs_zext(void)
>  	return true;
>  }
>  
> -struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
> +struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)
>  {
>  	unsigned int prog_size = 0, extable_size = 0;
>  	bool extra_pass = false;
> diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c
> index 2dfc279b1be2..94128fe6be23 100644
> --- a/arch/s390/net/bpf_jit_comp.c
> +++ b/arch/s390/net/bpf_jit_comp.c
> @@ -2312,7 +2312,7 @@ static struct bpf_binary_header *bpf_jit_alloc(struct bpf_jit *jit,
>  /*
>   * Compile eBPF program "fp"
>   */
> -struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
> +struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *fp)
>  {
>  	struct bpf_binary_header *header;
>  	struct s390_jit_data *jit_data;
> diff --git a/arch/sparc/net/bpf_jit_comp_64.c b/arch/sparc/net/bpf_jit_comp_64.c
> index e83e29137566..2fa0e9375127 100644
> --- a/arch/sparc/net/bpf_jit_comp_64.c
> +++ b/arch/sparc/net/bpf_jit_comp_64.c
> @@ -1477,7 +1477,7 @@ struct sparc64_jit_data {
>  	struct jit_ctx ctx;
>  };
>  
> -struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
> +struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)
>  {
>  	struct sparc64_jit_data *jit_data;
>  	struct bpf_binary_header *header;
> diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
> index 77d00a8dec87..72d9a5faa230 100644
> --- a/arch/x86/net/bpf_jit_comp.c
> +++ b/arch/x86/net/bpf_jit_comp.c
> @@ -3713,7 +3713,7 @@ struct x64_jit_data {
>  #define MAX_PASSES 20
>  #define PADDING_PASSES (MAX_PASSES - 5)
>  
> -struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
> +struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)
>  {
>  	struct bpf_binary_header *rw_header = NULL;
>  	struct bpf_binary_header *header = NULL;
> diff --git a/arch/x86/net/bpf_jit_comp32.c b/arch/x86/net/bpf_jit_comp32.c
> index 5f259577614a..852baf2e4db4 100644
> --- a/arch/x86/net/bpf_jit_comp32.c
> +++ b/arch/x86/net/bpf_jit_comp32.c
> @@ -2518,7 +2518,7 @@ bool bpf_jit_needs_zext(void)
>  	return true;
>  }
>  
> -struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
> +struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)
>  {
>  	struct bpf_binary_header *header = NULL;
>  	int proglen, oldproglen = 0;
> diff --git a/include/linux/filter.h b/include/linux/filter.h
> index d396e55c9a1d..83f37d38c5c1 100644
> --- a/include/linux/filter.h
> +++ b/include/linux/filter.h
> @@ -1107,6 +1107,8 @@ static inline int sk_filter_reason(struct sock *sk, struct sk_buff *skb,
>  	return sk_filter_trim_cap(sk, skb, 1, reason);
>  }
>  
> +struct bpf_prog *__bpf_prog_select_runtime(struct bpf_verifier_env *env, struct bpf_prog *fp,
> +					   int *err);
>  struct bpf_prog *bpf_prog_select_runtime(struct bpf_prog *fp, int *err);
>  void bpf_prog_free(struct bpf_prog *fp);
>  
> @@ -1152,7 +1154,7 @@ u64 __bpf_call_base(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5);
>  	((u64 (*)(u64, u64, u64, u64, u64, const struct bpf_insn *)) \
>  	 (void *)__bpf_call_base)
>  
> -struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog);
> +struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog);
>  void bpf_jit_compile(struct bpf_prog *prog);
>  bool bpf_jit_needs_zext(void);
>  bool bpf_jit_inlines_helper_call(s32 imm);
> @@ -1187,12 +1189,25 @@ struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off,
>  #ifdef CONFIG_BPF_SYSCALL
>  struct bpf_prog *bpf_patch_insn_data(struct bpf_verifier_env *env, u32 off,
>  				     const struct bpf_insn *patch, u32 len);
> +struct bpf_insn_aux_data *bpf_dup_insn_aux_data(struct bpf_verifier_env *env);
> +void bpf_restore_insn_aux_data(struct bpf_verifier_env *env,
> +			       struct bpf_insn_aux_data *orig_insn_aux);
>  #else
>  static inline struct bpf_prog *bpf_patch_insn_data(struct bpf_verifier_env *env, u32 off,
>  						   const struct bpf_insn *patch, u32 len)
>  {
>  	return ERR_PTR(-ENOTSUPP);
>  }
> +
> +static inline struct bpf_insn_aux_data *bpf_dup_insn_aux_data(struct bpf_verifier_env *env)
> +{
> +	return NULL;
> +}
> +
> +static inline void bpf_restore_insn_aux_data(struct bpf_verifier_env *env,
> +					     struct bpf_insn_aux_data *orig_insn_aux)
> +{
> +}
>  #endif /* CONFIG_BPF_SYSCALL */
>  
>  int bpf_remove_insns(struct bpf_prog *prog, u32 off, u32 cnt);
> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> index cc61fe57b98d..093ab0f68c81 100644
> --- a/kernel/bpf/core.c
> +++ b/kernel/bpf/core.c
> @@ -1489,23 +1489,6 @@ void bpf_jit_prog_release_other(struct bpf_prog *fp, struct bpf_prog *fp_other)
>  	bpf_prog_clone_free(fp_other);
>  }
>  
> -static void adjust_insn_arrays(struct bpf_prog *prog, u32 off, u32 len)
> -{
> -#ifdef CONFIG_BPF_SYSCALL
> -	struct bpf_map *map;
> -	int i;
> -
> -	if (len <= 1)
> -		return;
> -
> -	for (i = 0; i < prog->aux->used_map_cnt; i++) {
> -		map = prog->aux->used_maps[i];
> -		if (map->map_type == BPF_MAP_TYPE_INSN_ARRAY)
> -			bpf_insn_array_adjust(map, off, len);
> -	}
> -#endif
> -}
> -
>  /* Now this function is used only to blind the main prog and must be invoked only when
>   * bpf_prog_need_blind() returns true.
>   */
> @@ -1577,12 +1560,6 @@ struct bpf_prog *bpf_jit_blind_constants(struct bpf_verifier_env *env, struct bp
>  
>  		if (env)
>  			env->prog = clone;
> -		else
> -			/* Instructions arrays must be updated using absolute xlated offsets.
> -			 * The arrays have already been adjusted by bpf_patch_insn_data() when
> -			 * env is not NULL.
> -			 */
> -			adjust_insn_arrays(clone, i, rewritten);
>  
>  		/* Walk new program and skip insns we just inserted. */
>  		insn = clone->insnsi + i + insn_delta;
> @@ -2551,47 +2528,63 @@ static bool bpf_prog_select_interpreter(struct bpf_prog *fp)
>  	return select_interpreter;
>  }
>  
> -static struct bpf_prog *bpf_prog_jit_compile(struct bpf_prog *prog)
> +static struct bpf_prog *bpf_prog_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)
>  {
>  #ifdef CONFIG_BPF_JIT
>  	bool blinded = false;
>  	struct bpf_prog *orig_prog = prog;
> +	struct bpf_insn_aux_data *orig_insn_aux;
>  
>  	if (bpf_prog_need_blind(orig_prog)) {
> -		prog = bpf_jit_blind_constants(NULL, orig_prog);
> +		if (env) {
> +			/* If env is not NULL, we are called from the end of bpf_check(), at this
> +			 * point, only insn_aux_data is used after failure, so we only restore it
> +			 * here.
> +			 */
> +			orig_insn_aux = bpf_dup_insn_aux_data(env);
> +			if (!orig_insn_aux)
> +				return orig_prog;
> +		}
> +		prog = bpf_jit_blind_constants(env, orig_prog);
>  		/* If blinding was requested and we failed during blinding, we must fall
>  		 * back to the interpreter.
>  		 */
> -		if (IS_ERR(prog))
> -			return orig_prog;
> +		if (IS_ERR(prog)) {
> +			prog = orig_prog;
> +			if (env)
> +				goto out_restore;
> +			else
> +				return prog;
> +		}
>  		blinded = true;
>  	}
>  
> -	prog = bpf_int_jit_compile(prog);
> +	prog = bpf_int_jit_compile(env, prog);
>  	if (blinded) {
>  		if (!prog->jited) {
>  			bpf_jit_prog_release_other(orig_prog, prog);
>  			prog = orig_prog;
> +			if (env)
> +				goto out_restore;
>  		} else {
>  			bpf_jit_prog_release_other(prog, orig_prog);
> +			if (env)
> +				goto out_free;
>  		}
>  	}
> +
> +	return prog;
> +
> +out_restore:
> +	bpf_restore_insn_aux_data(env, orig_insn_aux);
> +out_free:
> +	kvfree(orig_insn_aux);
>  #endif
>  	return prog;
>  }
>  
> -/**
> - *	bpf_prog_select_runtime - select exec runtime for BPF program
> - *	@fp: bpf_prog populated with BPF program
> - *	@err: pointer to error variable
> - *
> - * Try to JIT eBPF program, if JIT is not available, use interpreter.
> - * The BPF program will be executed via bpf_prog_run() function.
> - *
> - * Return: the &fp argument along with &err set to 0 for success or
> - * a negative errno code on failure
> - */
> -struct bpf_prog *bpf_prog_select_runtime(struct bpf_prog *fp, int *err)
> +struct bpf_prog *__bpf_prog_select_runtime(struct bpf_verifier_env *env, struct bpf_prog *fp,
> +					   int *err)
>  {
>  	/* In case of BPF to BPF calls, verifier did all the prep
>  	 * work with regards to JITing, etc.
> @@ -2619,7 +2612,7 @@ struct bpf_prog *bpf_prog_select_runtime(struct bpf_prog *fp, int *err)
>  		if (*err)
>  			return fp;
>  
> -		fp = bpf_prog_jit_compile(fp);
> +		fp = bpf_prog_jit_compile(env, fp);
>  		bpf_prog_jit_attempt_done(fp);
>  		if (!fp->jited && jit_needed) {
>  			*err = -ENOTSUPP;
> @@ -2645,6 +2638,22 @@ struct bpf_prog *bpf_prog_select_runtime(struct bpf_prog *fp, int *err)
>  
>  	return fp;
>  }
> +
> +/**
> + *	bpf_prog_select_runtime - select exec runtime for BPF program
> + *	@fp: bpf_prog populated with BPF program
> + *	@err: pointer to error variable
> + *
> + * Try to JIT eBPF program, if JIT is not available, use interpreter.
> + * The BPF program will be executed via bpf_prog_run() function.
> + *
> + * Return: the &fp argument along with &err set to 0 for success or
> + * a negative errno code on failure
> + */
> +struct bpf_prog *bpf_prog_select_runtime(struct bpf_prog *fp, int *err)
> +{
> +	return __bpf_prog_select_runtime(NULL, fp, err);
> +}
>  EXPORT_SYMBOL_GPL(bpf_prog_select_runtime);
>  
>  static unsigned int __bpf_prog_ret1(const void *ctx,
> @@ -3132,7 +3141,7 @@ const struct bpf_func_proto bpf_tail_call_proto = {
>   * It is encouraged to implement bpf_int_jit_compile() instead, so that
>   * eBPF and implicitly also cBPF can get JITed!
>   */
> -struct bpf_prog * __weak bpf_int_jit_compile(struct bpf_prog *prog)
> +struct bpf_prog * __weak bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)
>  {
>  	return prog;
>  }
> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
> index e1505c9cd09e..553dca175640 100644
> --- a/kernel/bpf/syscall.c
> +++ b/kernel/bpf/syscall.c
> @@ -3090,10 +3090,6 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
>  	if (err < 0)
>  		goto free_used_maps;
>  
> -	prog = bpf_prog_select_runtime(prog, &err);
> -	if (err < 0)
> -		goto free_used_maps;
> -
>  	err = bpf_prog_mark_insn_arrays_ready(prog);
>  	if (err < 0)
>  		goto free_used_maps;
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 66cef3744fde..5084a754a748 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -22983,7 +22983,7 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
>  	return 0;
>  }
>  
> -static u32 *dup_subprog_starts(struct bpf_verifier_env *env)
> +static u32 *bpf_dup_subprog_starts(struct bpf_verifier_env *env)
>  {
>  	u32 *starts = NULL;
>  
> @@ -22995,13 +22995,13 @@ static u32 *dup_subprog_starts(struct bpf_verifier_env *env)
>  	return starts;
>  }
>  
> -static void restore_subprog_starts(struct bpf_verifier_env *env, u32 *orig_starts)
> +static void bpf_restore_subprog_starts(struct bpf_verifier_env *env, u32 *orig_starts)
>  {
>  	for (int i = 0; i < env->subprog_cnt; i++)
>  		env->subprog_info[i].start = orig_starts[i];
>  }
>  
> -static struct bpf_insn_aux_data *dup_insn_aux_data(struct bpf_verifier_env *env)
> +struct bpf_insn_aux_data *bpf_dup_insn_aux_data(struct bpf_verifier_env *env)
>  {
>  	size_t size;
>  
> @@ -23009,8 +23009,8 @@ static struct bpf_insn_aux_data *dup_insn_aux_data(struct bpf_verifier_env *env)
>  	return kvmemdup(env->insn_aux_data, size, GFP_KERNEL_ACCOUNT);
>  }
>  
> -static void restore_insn_aux_data(struct bpf_verifier_env *env,
> -				  struct bpf_insn_aux_data *orig_insn_aux)
> +void bpf_restore_insn_aux_data(struct bpf_verifier_env *env,
> +			       struct bpf_insn_aux_data *orig_insn_aux)
>  {
>  	/* the expanded elements are zero-filled, so no special handling is required */
>  	vfree(env->insn_aux_data);
> @@ -23153,7 +23153,7 @@ static int __jit_subprogs(struct bpf_verifier_env *env)
>  		func[i]->aux->might_sleep = env->subprog_info[i].might_sleep;
>  		if (!i)
>  			func[i]->aux->exception_boundary = env->seen_exception;
> -		func[i] = bpf_int_jit_compile(func[i]);
> +		func[i] = bpf_int_jit_compile(env, func[i]);
>  		if (!func[i]->jited) {
>  			err = -ENOTSUPP;
>  			goto out_free;
> @@ -23197,7 +23197,7 @@ static int __jit_subprogs(struct bpf_verifier_env *env)
>  	}
>  	for (i = 0; i < env->subprog_cnt; i++) {
>  		old_bpf_func = func[i]->bpf_func;
> -		tmp = bpf_int_jit_compile(func[i]);
> +		tmp = bpf_int_jit_compile(env, func[i]);
>  		if (tmp != func[i] || func[i]->bpf_func != old_bpf_func) {
>  			verbose(env, "JIT doesn't support bpf-to-bpf calls\n");
>  			err = -ENOTSUPP;
> @@ -23297,12 +23297,12 @@ static int jit_subprogs(struct bpf_verifier_env *env)
>  
>  	prog = orig_prog = env->prog;
>  	if (bpf_prog_need_blind(orig_prog)) {
> -		orig_insn_aux = dup_insn_aux_data(env);
> +		orig_insn_aux = bpf_dup_insn_aux_data(env);
>  		if (!orig_insn_aux) {
>  			err = -ENOMEM;
>  			goto out_cleanup;
>  		}
> -		orig_subprog_starts = dup_subprog_starts(env);
> +		orig_subprog_starts = bpf_dup_subprog_starts(env);
>  		if (!orig_subprog_starts) {
>  			err = -ENOMEM;
>  			goto out_free_aux;
> @@ -23347,8 +23347,8 @@ static int jit_subprogs(struct bpf_verifier_env *env)
>  	return 0;
>  
>  out_restore:
> -	restore_subprog_starts(env, orig_subprog_starts);
> -	restore_insn_aux_data(env, orig_insn_aux);
> +	bpf_restore_subprog_starts(env, orig_subprog_starts);
> +	bpf_restore_insn_aux_data(env, orig_insn_aux);
>  	kvfree(orig_subprog_starts);
>  out_free_aux:
>  	kvfree(orig_insn_aux);
> @@ -26523,6 +26523,14 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3
>  
>  	adjust_btf_func(env);
>  
> +	/* extension progs temporarily inherit the attach_type of their targets
> +	   for verification purposes, so set it back to zero before returning
> +	 */
> +	if (env->prog->type == BPF_PROG_TYPE_EXT)
> +		env->prog->expected_attach_type = 0;
> +
> +	env->prog = __bpf_prog_select_runtime(env, env->prog, &ret);
> +
>  err_release_maps:
>  	if (ret)
>  		release_insn_arrays(env);
> @@ -26534,12 +26542,6 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3
>  	if (!env->prog->aux->used_btfs)
>  		release_btfs(env);
>  
> -	/* extension progs temporarily inherit the attach_type of their targets
> -	   for verification purposes, so set it back to zero before returning
> -	 */
> -	if (env->prog->type == BPF_PROG_TYPE_EXT)
> -		env->prog->expected_attach_type = 0;
> -
>  	*prog = env->prog;
>  
>  	module_put(env->attach_btf_mod);



^ permalink raw reply

* Re: [PATCH v3 2/2] mailbox: Make mbox_send_message() return error code when tx fails
From: Jassi Brar @ 2026-04-03 16:36 UTC (permalink / raw)
  To: Joonwon Kang
  Cc: angelogioacchino.delregno, jonathanh, linux-arm-kernel,
	linux-kernel, linux-mediatek, linux-tegra, matthias.bgg, stable,
	thierry.reding, akpm
In-Reply-To: <20260403151950.2592581-1-joonwonkang@google.com>

On Fri, Apr 3, 2026 at 10:19 AM Joonwon Kang <joonwonkang@google.com> wrote:
>
> > On Thu, Apr 2, 2026 at 12:07 PM Joonwon Kang <joonwonkang@google.com> wrote:
> > >
> > > When the mailbox controller failed transmitting message, the error code
> > > was only passed to the client's tx done handler and not to
> > > mbox_send_message(). For this reason, the function could return a false
> > > success. This commit resolves the issue by introducing the tx status and
> > > checking it before mbox_send_message() returns.
> > >
> > Can you please share the scenario when this becomes necessary? This
> > can potentially change the ground underneath some clients, so we have
> > to be sure this is really useful.
>
> I would say the problem here is generic enough to apply to all the cases where
> the send result needs to be checked. Since the return value of the send API is
> not the real send result, any users who believe that this blocking send API
> will return the real send result could fall for that. For example, users may
> think the send was successful even though it was not actually. I believe it is
> uncommon that users have to register a callback solely to get the send result
> even though they are using the blocking send API already. Also, I guess there
> is no special reason why only the mailbox send API should work this way among
> other typical blocking send APIs. For these reasons, this patch makes the send
> API return the real send result. This way, users will not need to register the
> redundant callback and I think the return value will align with their common
> expectation.
>
Clients submit a message into the Mailbox subsystem to be sent out to
the remote side which can happen immediately or later.
If submission fails, clients get immediately notified. If transmission
fails (which is now internal to the subsystem) it is reported to the
client by a callback.
If the API was called mbox_submit_message (which it actually is)
instead of mbox_send_message, there would be no confusion.
We can argue how good/bad the current implementation is, but the fact
is that it is here. And I am reluctant to cause churn without good
reason.
Again, as I said, any, _legal_, setup scenario will help me come over
my reluctance.

Thanks
Jassi


^ permalink raw reply

* Re: [PATCH 2/2] crypto: atmel-sha204a - add Thorsten Blum as maintainer
From: Nicolas Ferre @ 2026-04-03 16:30 UTC (permalink / raw)
  To: Thorsten Blum, Herbert Xu, David S. Miller, Alexandre Belloni,
	Claudiu Beznea
  Cc: linux-crypto, linux-arm-kernel, linux-kernel
In-Reply-To: <20260403112135.903162-7-thorsten.blum@linux.dev>

On 03/04/2026 at 13:21, Thorsten Blum wrote:
> Add a MAINTAINERS entry for the atmel-sha204a driver and Thorsten Blum
> as maintainer.
> 
> Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>

Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com>

Thanks Thorsten for taking care of those components.

Best regards,
   Nicolas

> ---
>   MAINTAINERS | 6 ++++++
>   1 file changed, 6 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index c23110384b91..7317d80592cf 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -17197,6 +17197,12 @@ S:     Supported
>   F:     Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml
>   F:     drivers/spi/spi-at91-usart.c
> 
> +MICROCHIP ATSHA204A DRIVER
> +M:     Thorsten Blum <thorsten.blum@linux.dev>
> +L:     linux-crypto@vger.kernel.org
> +S:     Maintained
> +F:     drivers/crypto/atmel-sha204a.c
> +
>   MICROCHIP AUDIO ASOC DRIVERS
>   M:     Claudiu Beznea <claudiu.beznea@tuxon.dev>
>   M:     Andrei Simion <andrei.simion@microchip.com>



^ permalink raw reply

* Re: [PATCH 1/2] crypto: atmel-ecc - add Thorsten Blum as maintainer
From: Nicolas Ferre @ 2026-04-03 16:29 UTC (permalink / raw)
  To: Thorsten Blum, Herbert Xu, David S. Miller, Alexandre Belloni,
	Claudiu Beznea
  Cc: linux-crypto, linux-arm-kernel, linux-kernel
In-Reply-To: <20260403112135.903162-5-thorsten.blum@linux.dev>

On 03/04/2026 at 13:21, Thorsten Blum wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> Add Thorsten Blum as maintainer of the atmel-ecc driver.
> 
> Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>

Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com>

> ---
>   MAINTAINERS | 5 +++--
>   1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index c3fe46d7c4bc..c23110384b91 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -17216,9 +17216,10 @@ F:     Documentation/devicetree/bindings/media/microchip,csi2dc.yaml
>   F:     drivers/media/platform/microchip/microchip-csi2dc.c
> 
>   MICROCHIP ECC DRIVER
> +M:     Thorsten Blum <thorsten.blum@linux.dev>
>   L:     linux-crypto@vger.kernel.org
> -S:     Orphan
> -F:     drivers/crypto/atmel-ecc.*
> +S:     Maintained
> +F:     drivers/crypto/atmel-ecc.c
> 
>   MICROCHIP EIC DRIVER
>   M:     Claudiu Beznea <claudiu.beznea@tuxon.dev>



^ permalink raw reply

* Re: [PATCH V10 04/13] PCI: imx6: Assert PERST# before enabling regulators
From: Manivannan Sadhasivam @ 2026-04-03 16:29 UTC (permalink / raw)
  To: Sherry Sun
  Cc: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
	lpieralisi, kwilczynski, bhelgaas, hongxing.zhu, l.stach, imx,
	linux-pci, linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <20260402095107.205439-5-sherry.sun@nxp.com>

On Thu, Apr 02, 2026 at 05:50:58PM +0800, Sherry Sun wrote:
> According to the PCIe initialization requirements, PERST# signal should
> be asserted before applying power to the PCIe device, and deasserted
> after power and reference clock are stable.
> 

Spec wording is not quite like this. Spec mandates asserting PERST# *before*
stopping refclk and powering down the device and deasserting it *after* applying
power and refclk stable.

I believe you want to assert PERST# before enabling regulator to prevent the
endpoint from functioning? If so, is it due to refclk not available yet or some
other reason?

> Currently, the driver enables the vpcie3v3aux regulator in
> imx_pcie_probe() before PERST# is asserted in imx_pcie_host_init(),
> which violates the PCIe power sequencing requirements. However, there
> is no issue so far because PERST# is requested as GPIOD_OUT_HIGH in
> imx_pcie_probe(), which guarantees that PERST# is asserted before
> enabling the vpcie3v3aux regulator.
> 
> This is prepare for the upcoming changes that will parse the reset
> property using the new Root Port binding, which will use GPIOD_ASIS
> when requesting the reset GPIO. With GPIOD_ASIS, the GPIO state is not
> guaranteed, so explicit sequencing is required.
> 
> Fix the power sequencing by:
> 1. Moving vpcie3v3aux regulator enable from probe to
>    imx_pcie_host_init(), where it can be properly sequenced with PERST#.
> 2. Moving imx_pcie_assert_perst() before regulator and clock enable to
>    ensure correct ordering.
> 
> The vpcie3v3aux regulator is kept enabled for the entire PCIe controller
> lifecycle and automatically disabled on device removal via devm cleanup.
> 

vpcie3v3aux handling should be in a separate patch.

- Mani

> Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
> ---
>  drivers/pci/controller/dwc/pci-imx6.c | 49 +++++++++++++++++++++------
>  1 file changed, 39 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index 45d70ae7e04f..948ffb75d122 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -166,6 +166,8 @@ struct imx_pcie {
>  	u32			tx_swing_full;
>  	u32			tx_swing_low;
>  	struct regulator	*vpcie;
> +	struct regulator	*vpcie_aux;
> +	bool			vpcie_aux_enabled;
>  	struct regulator	*vph;
>  	void __iomem		*phy_base;
>  
> @@ -1220,6 +1222,13 @@ static void imx_pcie_disable_device(struct pci_host_bridge *bridge,
>  	imx_pcie_remove_lut(imx_pcie, pci_dev_id(pdev));
>  }
>  
> +static void imx_pcie_vpcie_aux_disable(void *data)
> +{
> +	struct regulator *vpcie_aux = data;
> +
> +	regulator_disable(vpcie_aux);
> +}
> +
>  static void imx_pcie_assert_perst(struct imx_pcie *imx_pcie, bool assert)
>  {
>  	if (assert) {
> @@ -1240,6 +1249,24 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
>  	struct imx_pcie *imx_pcie = to_imx_pcie(pci);
>  	int ret;
>  
> +	imx_pcie_assert_perst(imx_pcie, true);
> +
> +	/* Keep 3.3Vaux supply enabled for the entire PCIe controller lifecycle */
> +	if (imx_pcie->vpcie_aux && !imx_pcie->vpcie_aux_enabled) {
> +		ret = regulator_enable(imx_pcie->vpcie_aux);
> +		if (ret) {
> +			dev_err(dev, "failed to enable vpcie_aux regulator: %d\n",
> +				ret);
> +			return ret;
> +		}
> +		imx_pcie->vpcie_aux_enabled = true;
> +
> +		ret = devm_add_action_or_reset(dev, imx_pcie_vpcie_aux_disable,
> +					       imx_pcie->vpcie_aux);
> +		if (ret)
> +			return ret;
> +	}
> +
>  	if (imx_pcie->vpcie) {
>  		ret = regulator_enable(imx_pcie->vpcie);
>  		if (ret) {
> @@ -1249,25 +1276,24 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
>  		}
>  	}
>  
> +	ret = imx_pcie_clk_enable(imx_pcie);
> +	if (ret) {
> +		dev_err(dev, "unable to enable pcie clocks: %d\n", ret);
> +		goto err_reg_disable;
> +	}
> +
>  	if (pp->bridge && imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_LUT)) {
>  		pp->bridge->enable_device = imx_pcie_enable_device;
>  		pp->bridge->disable_device = imx_pcie_disable_device;
>  	}
>  
>  	imx_pcie_assert_core_reset(imx_pcie);
> -	imx_pcie_assert_perst(imx_pcie, true);
>  
>  	if (imx_pcie->drvdata->init_phy)
>  		imx_pcie->drvdata->init_phy(imx_pcie);
>  
>  	imx_pcie_configure_type(imx_pcie);
>  
> -	ret = imx_pcie_clk_enable(imx_pcie);
> -	if (ret) {
> -		dev_err(dev, "unable to enable pcie clocks: %d\n", ret);
> -		goto err_reg_disable;
> -	}
> -
>  	if (imx_pcie->phy) {
>  		ret = phy_init(imx_pcie->phy);
>  		if (ret) {
> @@ -1780,9 +1806,12 @@ static int imx_pcie_probe(struct platform_device *pdev)
>  	of_property_read_u32(node, "fsl,max-link-speed", &pci->max_link_speed);
>  	imx_pcie->supports_clkreq = of_property_read_bool(node, "supports-clkreq");
>  
> -	ret = devm_regulator_get_enable_optional(&pdev->dev, "vpcie3v3aux");
> -	if (ret < 0 && ret != -ENODEV)
> -		return dev_err_probe(dev, ret, "failed to enable Vaux supply\n");
> +	imx_pcie->vpcie_aux = devm_regulator_get_optional(&pdev->dev, "vpcie3v3aux");
> +	if (IS_ERR(imx_pcie->vpcie_aux)) {
> +		if (PTR_ERR(imx_pcie->vpcie_aux) != -ENODEV)
> +			return PTR_ERR(imx_pcie->vpcie_aux);
> +		imx_pcie->vpcie_aux = NULL;
> +	}
>  
>  	imx_pcie->vpcie = devm_regulator_get_optional(&pdev->dev, "vpcie");
>  	if (IS_ERR(imx_pcie->vpcie)) {
> -- 
> 2.37.1
> 

-- 
மணிவண்ணன் சதாசிவம்


^ permalink raw reply

* Re: [PATCH V10 03/13] PCI: dwc: Parse Root Port nodes in dw_pcie_host_init()
From: Manivannan Sadhasivam @ 2026-04-03 16:20 UTC (permalink / raw)
  To: Sherry Sun
  Cc: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
	lpieralisi, kwilczynski, bhelgaas, hongxing.zhu, l.stach, imx,
	linux-pci, linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <20260402095107.205439-4-sherry.sun@nxp.com>

On Thu, Apr 02, 2026 at 05:50:57PM +0800, Sherry Sun wrote:
> Add support for parsing Root Port child nodes in dw_pcie_host_init()
> using pci_host_common_parse_ports(). This allows DWC-based drivers to
> specify Root Port properties (like reset GPIOs) in individual Root Port
> nodes rather than in the host bridge node.
> 
> Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
> ---
>  drivers/pci/controller/dwc/pcie-designware-host.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index da152c31bb2e..f6fca984fb34 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -20,6 +20,7 @@
>  #include <linux/platform_device.h>
>  
>  #include "../../pci.h"
> +#include "../pci-host-common.h"
>  #include "pcie-designware.h"
>  
>  static struct pci_ops dw_pcie_ops;
> @@ -581,6 +582,13 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
>  
>  	pp->bridge = bridge;
>  
> +	/* Parse Root Port nodes if present */
> +	ret = pci_host_common_parse_ports(dev, bridge);
> +	if (ret && ret != -ENOENT) {
> +		dev_err(dev, "Failed to parse Root Port nodes: %d\n", ret);
> +		return ret;

Won't this change break drivers that parse Root Ports on their own? Either you
need to modify them also in this change or call this API from imx6 driver and
let other drivers switch to it in a phased manner.

I perfer the latter.

- Mani

-- 
மணிவண்ணன் சதாசிவம்


^ permalink raw reply

* Re: [PATCH v3 1/2] mailbox: Use per-thread completion to fix wrong completion order
From: Jassi Brar @ 2026-04-03 16:19 UTC (permalink / raw)
  To: Joonwon Kang
  Cc: angelogioacchino.delregno, jonathanh, linux-arm-kernel,
	linux-kernel, linux-mediatek, linux-tegra, matthias.bgg, stable,
	thierry.reding
In-Reply-To: <20260403145119.2581034-1-joonwonkang@google.com>

On Fri, Apr 3, 2026 at 9:51 AM Joonwon Kang <joonwonkang@google.com> wrote:
>
> > On Thu, Apr 2, 2026 at 12:07 PM Joonwon Kang <joonwonkang@google.com> wrote:
> > >
> > > Previously, a sender thread in mbox_send_message() could be woken up at
> > > a wrong time in blocking mode. It is because there was only a single
> > > completion for a channel whereas messages from multiple threads could be
> > > sent in any order; since the shared completion could be signalled in any
> > > order, it could wake up a wrong sender thread.
> > >
> > > This commit resolves the false wake-up issue with the following changes:
> > > - Completions are created just as many as the number of concurrent sender
> > >   threads
> > > - A completion is created on a sender thread's stack
> > > - Each slot of the message queue, i.e. `msg_data`, contains a pointer to
> > >   its target completion
> > > - tx_tick() signals the completion of the currently active slot of the
> > >   message queue
> > >
> > I think I reviewed it already or is this happening on
> > one-channel-one-client usage? Because mailbox api does not support
> > channels shared among multiple clients.
>
> Yes, this patch is handling the one-channel-one-client usage but when that
> single channel is shared between multiple threads.

hmm.... how is this not single-channel-multiple-clients ?
A channel is returned as an opaque token to the clients, if that
client shares that with other threads - they will race.
It is the job of the original client to serialize its threads' access
to the channel.

> From my understanding, the
> discussion back then ended with how to circumvent the issue rather than whether
> we will eventually solve this in the mailbox framework or not, and if yes, how
> we will, and if not, why.

It will be interesting to see how many current clients actually need
to share channels. If there are enough, it makes sense to implement
some helper api
on top of existing code, instead of changing its nature totally.

Thanks
Jassi


^ permalink raw reply

* Re: [PATCH v10 00/12] barrier: Add smp_cond_load_{relaxed, acquire}_timeout()
From: Okanovic, Haris @ 2026-04-03 16:12 UTC (permalink / raw)
  To: ankur.a.arora@oracle.com
  Cc: joao.m.martins@oracle.com, xueshuai@linux.alibaba.com,
	david.laight.linux@gmail.com, boris.ostrovsky@oracle.com,
	memxor@gmail.com, zhenglifeng1@huawei.com, konrad.wilk@oracle.com,
	cl@gentwo.org, akpm@linux-foundation.org,
	linux-kernel@vger.kernel.org, catalin.marinas@arm.com,
	ast@kernel.org, rdunlap@infradead.org, daniel.lezcano@linaro.org,
	arnd@arndb.de, linux-arch@vger.kernel.org, will@kernel.org,
	mark.rutland@arm.com, peterz@infradead.org, bpf@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, Okanovic, Haris,
	rafael@kernel.org, linux-pm@vger.kernel.org
In-Reply-To: <20260316013651.3225328-1-ankur.a.arora@oracle.com>

Can we merge this series? I think there's an approval from every named
maintainer at this point.

Besides `perf sched` microbenchamrk that Ankur has been running, I've
observed 4-6% improvements in memcahed, cassandra, mysql, and
postgresql under certain loads. Other applications likely benefit too.

Thanks,
Haris Okanovic
AWS Graviton Software


On Sun, 2026-03-15 at 18:36 -0700, Ankur Arora wrote:
> CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you can confirm the sender and know the content is safe.
> 
> 
> 
> Hi,
> 
> This series adds waited variants of the smp_cond_load() primitives:
> smp_cond_load_relaxed_timeout(), and smp_cond_load_acquire_timeout().
> 
> With this version, the main remaining things are:
> 
>   - Review by PeterZ of the new interface tif_need_resched_relaxed_wait()
>     (patch 11, "sched: add need-resched timed wait interface").
> 
>   - Review of the BPF changes. This version simplifies the rqspinlock
>     changes by reusing the original error handling path
>     (patches 9, 10 "bpf/rqspinlock: switch check_timeout() to a clock
>     interface", "bpf/rqspinlock: Use smp_cond_load_acquire_timeout()").
> 
>   - Review of WFET handling. (patch 4, "arm64: support WFET in
>     smp_cond_load_relaxed_timeout()").
> 
> The new interfaces are meant for contexts where you want to wait on a
> condition variable for a finite duration. This is easy enough to do with
> a loop around cpu_relax(). There are, however, architectures (ex. arm64)
> that allow waiting on a cacheline instead.
> 
> So, these interfaces handle a mixture of spin/wait with a
> smp_cond_load() thrown in. The interfaces are:
> 
>    smp_cond_load_relaxed_timeout(ptr, cond_expr, time_expr, timeout)
>    smp_cond_load_acquire_timeout(ptr, cond_expr, time_expr, timeout)
> 
> The parameters, time_expr, timeout determine when to bail out.
> 
> Also add tif_need_resched_relaxed_wait() which wraps the pattern used
> in poll_idle() and abstracts out details of the interface and those
> of the scheduler.
> 
> In addition add atomic_cond_read_*_timeout(), atomic64_cond_read_*_timeout(),
> and atomic_long wrappers to the interfaces.
> 
> Finally update poll_idle() and resilient queued spinlocks to use them.
> 
> Changelog:
>   v9 [9]:
>    - s/@cond/@cond_expr/ (Randy Dunlap)
>    - Clarify that SMP_TIMEOUT_POLL_COUNT is only around memory
>      addresses. (David Laight)
>    - Add the missing config ARCH_HAS_CPU_RELAX in arch/arm64/Kconfig.
>      (Catalin Marinas).
>    - Switch to arch_counter_get_cntvct_stable() (via __delay_cycles())
>      in the cmpwait path instead of using arch_timer_read_counter().
>      (Catalin Marinas)
> 
>   v8 [0]:
>    - Defer evaluation of @time_expr_ns to when we hit the slowpath.
>       (comment from Alexei Starovoitov).
> 
>    - Mention that cpu_poll_relax() is better than raw CPU polling
>      only where ARCH_HAS_CPU_RELAX is defined.
>      - also define ARCH_HAS_CPU_RELAX for arm64.
>       (Came out of a discussion with Will Deacon.)
> 
>    - Split out WFET and WFE handling. I was doing both of these
>      in a common handler.
>      (From Will Deacon and in an earlier revision by Catalin Marinas.)
> 
>    - Add mentions of atomic_cond_read_{relaxed,acquire}(),
>      atomic_cond_read_{relaxed,acquire}_timeout() in
>      Documentation/atomic_t.txt.
> 
>    - Use the BIT() macro to do the checking in tif_bitset_relaxed_wait().
> 
>    - Cleanup unnecessary assignments, casts etc in poll_idle().
>      (From Rafael Wysocki.)
> 
>    - Fixup warnings from kernel build robot
> 
> 
>   v7 [1]:
>    - change the interface to separately provide the timeout. This is
>      useful for supporting WFET and similar primitives which can do
>      timed waiting (suggested by Arnd Bergmann).
> 
>    - Adapting rqspinlock code to this changed interface also
>      necessitated allowing time_expr to fail.
>    - rqspinlock changes to adapt to the new smp_cond_load_acquire_timeout().
> 
>    - add WFET support (suggested by Arnd Bergmann).
>    - add support for atomic-long wrappers.
>    - add a new scheduler interface tif_need_resched_relaxed_wait() which
>      encapsulates the polling logic used by poll_idle().
>      - interface suggested by (Rafael J. Wysocki).
> 
> 
>   v6 [2]:
>    - fixup missing timeout parameters in atomic64_cond_read_*_timeout()
>    - remove a race between setting of TIF_NEED_RESCHED and the call to
>      smp_cond_load_relaxed_timeout(). This would mean that dev->poll_time_limit
>      would be set even if we hadn't spent any time waiting.
>      (The original check compared against local_clock(), which would have been
>      fine, but I was instead using a cheaper check against _TIF_NEED_RESCHED.)
>    (Both from meta-CI bot)
> 
> 
>   v5 [3]:
>    - use cpu_poll_relax() instead of cpu_relax().
>    - instead of defining an arm64 specific
>      smp_cond_load_relaxed_timeout(), just define the appropriate
>      cpu_poll_relax().
>    - re-read the target pointer when we exit due to the time-check.
>    - s/SMP_TIMEOUT_SPIN_COUNT/SMP_TIMEOUT_POLL_COUNT/
>    (Suggested by Will Deacon)
> 
>    - add atomic_cond_read_*_timeout() and atomic64_cond_read_*_timeout()
>      interfaces.
>    - rqspinlock: use atomic_cond_read_acquire_timeout().
>    - cpuidle: use smp_cond_load_relaxed_tiemout() for polling.
>    (Suggested by Catalin Marinas)
> 
>    - rqspinlock: define SMP_TIMEOUT_POLL_COUNT to be 16k for non arm64
> 
> 
>   v4 [4]:
>     - naming change 's/timewait/timeout/'
>     - resilient spinlocks: get rid of res_smp_cond_load_acquire_waiting()
>       and fixup use of RES_CHECK_TIMEOUT().
>     (Both suggested by Catalin Marinas)
> 
>   v3 [5]:
>     - further interface simplifications (suggested by Catalin Marinas)
> 
>   v2 [6]:
>     - simplified the interface (suggested by Catalin Marinas)
>        - get rid of wait_policy, and a multitude of constants
>        - adds a slack parameter
>       This helped remove a fair amount of duplicated code duplication and in
>       hindsight unnecessary constants.
> 
>   v1 [7]:
>      - add wait_policy (coarse and fine)
>      - derive spin-count etc at runtime instead of using arbitrary
>        constants.
> 
> Haris Okanovic tested v4 of this series with poll_idle()/haltpoll patches. [8]
> 
> Comments appreciated!
> 
> Thanks
> Ankur
> 
>  [0] https://lore.kernel.org/lkml/20251215044919.460086-1-ankur.a.arora@oracle.com/
>  [1] https://lore.kernel.org/lkml/20251028053136.692462-1-ankur.a.arora@oracle.com/
>  [2] https://lore.kernel.org/lkml/20250911034655.3916002-1-ankur.a.arora@oracle.com/
>  [3] https://lore.kernel.org/lkml/20250911034655.3916002-1-ankur.a.arora@oracle.com/
>  [4] https://lore.kernel.org/lkml/20250829080735.3598416-1-ankur.a.arora@oracle.com/
>  [5] https://lore.kernel.org/lkml/20250627044805.945491-1-ankur.a.arora@oracle.com/
>  [6] https://lore.kernel.org/lkml/20250502085223.1316925-1-ankur.a.arora@oracle.com/
>  [7] https://lore.kernel.org/lkml/20250203214911.898276-1-ankur.a.arora@oracle.com/
>  [8] https://lore.kernel.org/lkml/2cecbf7fb23ee83a4ce027e1be3f46f97efd585c.camel@amazon.com/
>  [9] https://lore.kernel.org/lkml/20260209023153.2661784-1-ankur.a.arora@oracle.com/
> 
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Will Deacon <will@kernel.org>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
> Cc: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> Cc: Alexei Starovoitov <ast@kernel.org>
> Cc: bpf@vger.kernel.org
> Cc: linux-arch@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-pm@vger.kernel.org
> 
> Ankur Arora (12):
>   asm-generic: barrier: Add smp_cond_load_relaxed_timeout()
>   arm64: barrier: Support smp_cond_load_relaxed_timeout()
>   arm64/delay: move some constants out to a separate header
>   arm64: support WFET in smp_cond_load_relaxed_timeout()
>   arm64: rqspinlock: Remove private copy of
>     smp_cond_load_acquire_timewait()
>   asm-generic: barrier: Add smp_cond_load_acquire_timeout()
>   atomic: Add atomic_cond_read_*_timeout()
>   locking/atomic: scripts: build atomic_long_cond_read_*_timeout()
>   bpf/rqspinlock: switch check_timeout() to a clock interface
>   bpf/rqspinlock: Use smp_cond_load_acquire_timeout()
>   sched: add need-resched timed wait interface
>   cpuidle/poll_state: Wait for need-resched via
>     tif_need_resched_relaxed_wait()
> 
>  Documentation/atomic_t.txt           | 14 +++--
>  arch/arm64/Kconfig                   |  3 +
>  arch/arm64/include/asm/barrier.h     | 23 +++++++
>  arch/arm64/include/asm/cmpxchg.h     | 62 +++++++++++++++----
>  arch/arm64/include/asm/delay-const.h | 27 +++++++++
>  arch/arm64/include/asm/rqspinlock.h  | 85 --------------------------
>  arch/arm64/lib/delay.c               | 15 ++---
>  drivers/cpuidle/poll_state.c         | 21 +------
>  drivers/soc/qcom/rpmh-rsc.c          |  8 +--
>  include/asm-generic/barrier.h        | 90 ++++++++++++++++++++++++++++
>  include/linux/atomic.h               | 10 ++++
>  include/linux/atomic/atomic-long.h   | 18 +++---
>  include/linux/sched/idle.h           | 29 +++++++++
>  kernel/bpf/rqspinlock.c              | 77 +++++++++++++++---------
>  scripts/atomic/gen-atomic-long.sh    | 16 +++--
>  15 files changed, 320 insertions(+), 178 deletions(-)
>  create mode 100644 arch/arm64/include/asm/delay-const.h
> 
> --
> 2.31.1
> 

-- 
Regards,
Haris Okanovic
AWS Graviton Software


^ permalink raw reply

* [PATCH v2 2/8] dt-bindings: i2c: amlogic: Add compatible for T7 SOC
From: Ronald Claveau @ 2026-04-03 16:08 UTC (permalink / raw)
  To: Neil Armstrong, Lee Jones, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Andi Shyti, Kevin Hilman, Jerome Brunet,
	Martin Blumenstingl, Beniamino Galvani, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Liam Girdwood, Mark Brown
  Cc: linux-amlogic, devicetree, linux-kernel, linux-i2c,
	linux-arm-kernel, linux-pm, Ronald Claveau
In-Reply-To: <20260403-add-mcu-fan-khadas-vim4-v2-0-70536b22439a@aliel.fr>

Add the T7 SOC compatible which fallback to AXG compatible.

Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
---
 .../devicetree/bindings/i2c/amlogic,meson6-i2c.yaml         | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/i2c/amlogic,meson6-i2c.yaml b/Documentation/devicetree/bindings/i2c/amlogic,meson6-i2c.yaml
index c4cc8af182807..7b59b60b62e5b 100644
--- a/Documentation/devicetree/bindings/i2c/amlogic,meson6-i2c.yaml
+++ b/Documentation/devicetree/bindings/i2c/amlogic,meson6-i2c.yaml
@@ -16,10 +16,15 @@ allOf:
 
 properties:
   compatible:
-    enum:
-      - amlogic,meson6-i2c # Meson6, Meson8 and compatible SoCs
-      - amlogic,meson-gxbb-i2c # GXBB and compatible SoCs
-      - amlogic,meson-axg-i2c # AXG and compatible SoCs
+    oneOf:
+      - items:
+          - enum:
+              - amlogic,t7-i2c
+          - const: amlogic,meson-axg-i2c
+      - enum:
+          - amlogic,meson6-i2c # Meson6, Meson8 and compatible SoCs
+          - amlogic,meson-gxbb-i2c # GXBB and compatible SoCs
+          - amlogic,meson-axg-i2c # AXG and compatible SoCs
 
   reg:
     maxItems: 1

-- 
2.49.0



^ 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