Linux Power Management development
 help / color / mirror / Atom feed
* Re: The "clockevents: Prevent timer interrupt starvation" patch causes lockups
From: Hanabishi @ 2026-04-14 21:35 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Frederic Weisbecker, Eric Naim, LKML, Calvin Owens,
	Peter Zijlstra, Anna-Maria Behnsen, Ingo Molnar, John Stultz,
	Stephen Boyd, Alexander Viro, Christian Brauner, Jan Kara,
	linux-fsdevel, Sebastian Reichel, linux-pm, Pablo Neira Ayuso,
	Florian Westphal, Phil Sutter, netfilter-devel, coreteam
In-Reply-To: <87340xfeje.ffs@tglx>

On 14/04/2026 20:55, Thomas Gleixner wrote:
> The one below should cover all possible holes.
> 
> Thanks,
> 
>          tglx
> ---
> diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
> index b4d730604972..5e22697b098d 100644
> --- a/kernel/time/clockevents.c
> +++ b/kernel/time/clockevents.c
> @@ -94,6 +94,9 @@ static int __clockevents_switch_state(struct clock_event_device *dev,
>   	if (dev->features & CLOCK_EVT_FEAT_DUMMY)
>   		return 0;
>   
> +	/* On state transitions clear the forced flag unconditionally */
> +	dev->next_event_forced = 0;
> +
>   	/* Transition with new state-specific callbacks */
>   	switch (state) {
>   	case CLOCK_EVT_STATE_DETACHED:
> @@ -366,8 +369,10 @@ int clockevents_program_event(struct clock_event_device *dev, ktime_t expires, b
>   	if (delta > (int64_t)dev->min_delta_ns) {
>   		delta = min(delta, (int64_t) dev->max_delta_ns);
>   		cycles = ((u64)delta * dev->mult) >> dev->shift;
> -		if (!dev->set_next_event((unsigned long) cycles, dev))
> +		if (!dev->set_next_event((unsigned long) cycles, dev)) {
> +			dev->next_event_forced = 0;
>   			return 0;
> +		}
>   	}
>   
>   	if (dev->next_event_forced)
> diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
> index 7e57fa31ee26..115e0bf01276 100644
> --- a/kernel/time/tick-broadcast.c
> +++ b/kernel/time/tick-broadcast.c
> @@ -108,6 +108,7 @@ static struct clock_event_device *tick_get_oneshot_wakeup_device(int cpu)
>   
>   static void tick_oneshot_wakeup_handler(struct clock_event_device *wd)
>   {
> +	wd->next_event_forced = 0;
>   	/*
>   	 * If we woke up early and the tick was reprogrammed in the
>   	 * meantime then this may be spurious but harmless.

Ok, it does fix the problem! Thank you.
The patch itself does not apply cleanly for 7.0 though and I had to adapt it a bit.


^ permalink raw reply

* Re: [RFC PATCH 2/2] kernel/module: Decouple klp and ftrace from load_module
From: Song Chen @ 2026-04-15  6:43 UTC (permalink / raw)
  To: Petr Pavlu
  Cc: rafael, lenb, mturquette, sboyd, viresh.kumar, agk, snitzer,
	mpatocka, bmarzins, song, yukuai, linan122, jason.wessel, danielt,
	dianders, horms, davem, edumazet, kuba, pabeni, paulmck, frederic,
	mcgrof, da.gomez, samitolvanen, atomlin, jpoimboe, jikos, mbenes,
	pmladek, joe.lawrence, rostedt, mhiramat, mark.rutland,
	mathieu.desnoyers, linux-modules, linux-kernel,
	linux-trace-kernel, linux-acpi, linux-clk, linux-pm,
	live-patching, dm-devel, linux-raid, kgdb-bugreport, netdev
In-Reply-To: <1191caf5-6a61-4622-a15e-854d3701f4fc@suse.com>

Hi,

On 4/14/26 22:33, Petr Pavlu wrote:
> On 4/13/26 10:07 AM, chensong_2000@189.cn wrote:
>> From: Song Chen <chensong_2000@189.cn>
>>
>> ftrace and livepatch currently have their module load/unload callbacks
>> hard-coded in the module loader as direct function calls to
>> ftrace_module_enable(), klp_module_coming(), klp_module_going()
>> and ftrace_release_mod(). This tight coupling was originally introduced
>> to enforce strict call ordering that could not be guaranteed by the
>> module notifier chain, which only supported forward traversal. Their
>> notifiers were moved in and out back and forth. see [1] and [2].
> 
> I'm unclear about what is meant by the notifiers being moved back and
> forth. The links point to patches that converted ftrace+klp from using
> module notifiers to explicit callbacks due to ordering issues, but this
> switch occurred only once. Have there been other attempts to use
> notifiers again?
> 

Yes,only once,i will rephrase.

>>
>> Now that the notifier chain supports reverse traversal via
>> blocking_notifier_call_chain_reverse(), the ordering can be enforced
>> purely through notifier priority. As a result, the module loader is now
>> decoupled from the implementation details of ftrace and livepatch.
>> What's more, adding a new subsystem with symmetric setup/teardown ordering
>> requirements during module load/unload no longer requires modifying
>> kernel/module/main.c; it only needs to register a notifier_block with an
>> appropriate priority.
>>
>> [1]:https://lore.kernel.org/all/
>> 	alpine.LNX.2.00.1602172216491.22700@cbobk.fhfr.pm/
>> [2]:https://lore.kernel.org/all/
>> 	20160301030034.GC12120@packer-debian-8-amd64.digitalocean.com/
> 
> Nit: Avoid wrapping URLs, as it breaks autolinking and makes the links
> harder to copy.
> 
> Better links would be:
> [1] https://lore.kernel.org/all/1455661953-15838-1-git-send-email-jeyu@redhat.com/
> [2] https://lore.kernel.org/all/1458176139-17455-1-git-send-email-jeyu@redhat.com/
> 
> The first link is the final version of what landed as commit
> 7dcd182bec27 ("ftrace/module: remove ftrace module notifier"). The
> second is commit 7e545d6eca20 ("livepatch/module: remove livepatch
> module notifier").
> 

Thank you, i will update.

>>
>> Signed-off-by: Song Chen <chensong_2000@189.cn>
>> ---
>>   include/linux/module.h  |  8 ++++++++
>>   kernel/livepatch/core.c | 29 ++++++++++++++++++++++++++++-
>>   kernel/module/main.c    | 34 +++++++++++++++-------------------
>>   kernel/trace/ftrace.c   | 38 ++++++++++++++++++++++++++++++++++++++
>>   4 files changed, 89 insertions(+), 20 deletions(-)
>>
>> diff --git a/include/linux/module.h b/include/linux/module.h
>> index 14f391b186c6..0bdd56f9defd 100644
>> --- a/include/linux/module.h
>> +++ b/include/linux/module.h
>> @@ -308,6 +308,14 @@ enum module_state {
>>   	MODULE_STATE_COMING,	/* Full formed, running module_init. */
>>   	MODULE_STATE_GOING,	/* Going away. */
>>   	MODULE_STATE_UNFORMED,	/* Still setting it up. */
>> +	MODULE_STATE_FORMED,
> 
> I don't see a reason to add a new module state. Why is it necessary and
> how does it fit with the existing states?
> 
because once notifier fails in state MODULE_STATE_UNFORMED (now only 
ftrace has someting to do in this state), notifier chain will roll back 
by calling blocking_notifier_call_chain_robust, i'm afraid 
MODULE_STATE_GOING is going to jeopardise the notifers which don't 
handle it appropriately, like:

case MODULE_STATE_COMING:
      kmalloc();
case MODULE_STATE_GOING:
      kfree();


>> +};
>> +
>> +enum module_notifier_prio {
>> +	MODULE_NOTIFIER_PRIO_LOW = INT_MIN,	/* Low prioroty, coming last, going first */
>> +	MODULE_NOTIFIER_PRIO_MID = 0,	/* Normal priority. */
>> +	MODULE_NOTIFIER_PRIO_SECOND_HIGH = INT_MAX - 1,	/* Second high priorigy, coming second*/
>> +	MODULE_NOTIFIER_PRIO_HIGH = INT_MAX,	/* High priorigy, coming first, going late. */
> 
> I suggest being explicit about how the notifiers are ordered. For
> example:
> 
> enum module_notifier_prio {
> 	MODULE_NOTIFIER_PRIO_NORMAL,	/* Normal priority, coming last, going first. */
> 	MODULE_NOTIFIER_PRIO_LIVEPATCH,
> 	MODULE_NOTIFIER_PRIO_FTRACE,	/* High priority, coming first, going late. */
> };
> 

accepted.

>>   };
>>   
>>   struct mod_tree_node {
>> diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
>> index 28d15ba58a26..ce78bb23e24b 100644
>> --- a/kernel/livepatch/core.c
>> +++ b/kernel/livepatch/core.c
>> @@ -1375,13 +1375,40 @@ void *klp_find_section_by_name(const struct module *mod, const char *name,
>>   }
>>   EXPORT_SYMBOL_GPL(klp_find_section_by_name);
>>   
>> +static int klp_module_callback(struct notifier_block *nb, unsigned long op,
>> +			void *module)
>> +{
>> +	struct module *mod = module;
>> +	int err = 0;
>> +
>> +	switch (op) {
>> +	case MODULE_STATE_COMING:
>> +		err = klp_module_coming(mod);
>> +		break;
>> +	case MODULE_STATE_LIVE:
>> +		break;
>> +	case MODULE_STATE_GOING:
>> +		klp_module_going(mod);
>> +		break;
>> +	default:
>> +		break;
>> +	}
> 
> klp_module_coming() and klp_module_going() are now used only in
> kernel/livepatch/core.c where they are also defined. This means the
> functions can be static and their declarations removed from
> include/linux/livepatch.h.
> 
> Nit: The MODULE_STATE_LIVE and default cases in the switch can be
> removed.
> 

accepted.

>> +
>> +	return notifier_from_errno(err);
>> +}
>> +
>> +static struct notifier_block klp_module_nb = {
>> +	.notifier_call = klp_module_callback,
>> +	.priority = MODULE_NOTIFIER_PRIO_SECOND_HIGH
>> +};
>> +
>>   static int __init klp_init(void)
>>   {
>>   	klp_root_kobj = kobject_create_and_add("livepatch", kernel_kobj);
>>   	if (!klp_root_kobj)
>>   		return -ENOMEM;
>>   
>> -	return 0;
>> +	return register_module_notifier(&klp_module_nb);
>>   }
>>   
>>   module_init(klp_init);
>> diff --git a/kernel/module/main.c b/kernel/module/main.c
>> index c3ce106c70af..226dd5b80997 100644
>> --- a/kernel/module/main.c
>> +++ b/kernel/module/main.c
>> @@ -833,10 +833,8 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
>>   	/* Final destruction now no one is using it. */
>>   	if (mod->exit != NULL)
>>   		mod->exit();
>> -	blocking_notifier_call_chain(&module_notify_list,
>> +	blocking_notifier_call_chain_reverse(&module_notify_list,
>>   				     MODULE_STATE_GOING, mod);
>> -	klp_module_going(mod);
>> -	ftrace_release_mod(mod);
>>   
>>   	async_synchronize_full();
>>   
>> @@ -3135,10 +3133,8 @@ static noinline int do_init_module(struct module *mod)
>>   	mod->state = MODULE_STATE_GOING;
>>   	synchronize_rcu();
>>   	module_put(mod);
>> -	blocking_notifier_call_chain(&module_notify_list,
>> +	blocking_notifier_call_chain_reverse(&module_notify_list,
>>   				     MODULE_STATE_GOING, mod);
>> -	klp_module_going(mod);
>> -	ftrace_release_mod(mod);
>>   	free_module(mod);
>>   	wake_up_all(&module_wq);
>>   
> 
> The patch unexpectedly leaves a call to ftrace_free_mem() in
> do_init_module().

Thanks for pointing it out, it was removed when i implemented and 
tested, but when i organized the patch, it was left. I will remove it.

> 
>> @@ -3281,20 +3277,14 @@ static int complete_formation(struct module *mod, struct load_info *info)
>>   	return err;
>>   }
>>   
>> -static int prepare_coming_module(struct module *mod)
>> +static int prepare_module_state_transaction(struct module *mod,
>> +			unsigned long val_up, unsigned long val_down)
>>   {
>>   	int err;
>>   
>> -	ftrace_module_enable(mod);
>> -	err = klp_module_coming(mod);
>> -	if (err)
>> -		return err;
>> -
>>   	err = blocking_notifier_call_chain_robust(&module_notify_list,
>> -			MODULE_STATE_COMING, MODULE_STATE_GOING, mod);
>> +			val_up, val_down, mod);
>>   	err = notifier_to_errno(err);
>> -	if (err)
>> -		klp_module_going(mod);
>>   
>>   	return err;
>>   }
>> @@ -3468,14 +3458,21 @@ static int load_module(struct load_info *info, const char __user *uargs,
>>   	init_build_id(mod, info);
>>   
>>   	/* Ftrace init must be called in the MODULE_STATE_UNFORMED state */
>> -	ftrace_module_init(mod);
>> +	err = prepare_module_state_transaction(mod,
>> +				MODULE_STATE_UNFORMED, MODULE_STATE_FORMED);
> 
> I believe val_down should be MODULE_STATE_GOING to reverse the
> operation. Why is the new state MODULE_STATE_FORMED needed here?
to avoid this:

case MODULE_STATE_COMING:
      kmalloc();
case MODULE_STATE_GOING:
      kfree();



> 
>> +	if (err)
>> +		goto ddebug_cleanup;
>>   
>>   	/* Finally it's fully formed, ready to start executing. */
>>   	err = complete_formation(mod, info);
>> -	if (err)
>> +	if (err) {
>> +		blocking_notifier_call_chain_reverse(&module_notify_list,
>> +				MODULE_STATE_FORMED, mod);
>>   		goto ddebug_cleanup;
>> +	}
>>   
>> -	err = prepare_coming_module(mod);
>> +	err = prepare_module_state_transaction(mod,
>> +				MODULE_STATE_COMING, MODULE_STATE_GOING);
>>   	if (err)
>>   		goto bug_cleanup;
>>   
>> @@ -3522,7 +3519,6 @@ static int load_module(struct load_info *info, const char __user *uargs,
>>   	destroy_params(mod->kp, mod->num_kp);
>>   	blocking_notifier_call_chain(&module_notify_list,
>>   				     MODULE_STATE_GOING, mod);
> 
> My understanding is that all notifier chains for MODULE_STATE_GOING
> should be reversed.
yes, all, from lowest priority notifier to highest.
I will resend patch 1 which was failed due to my proxy setting.

> 
>> -	klp_module_going(mod);
>>    bug_cleanup:
>>   	mod->state = MODULE_STATE_GOING;
>>   	/* module_bug_cleanup needs module_mutex protection */
> 
> The patch removes the klp_module_going() cleanup call in load_module().
> Similarly, the ftrace_release_mod() call under the ddebug_cleanup label
> should be removed and appropriately replaced with a cleanup via
> a notifier.
> 
     err = prepare_module_state_transaction(mod,
                 MODULE_STATE_UNFORMED, MODULE_STATE_FORMED);
     if (err)
         goto ddebug_cleanup;

ftrace will be cleanup in blocking_notifier_call_chain_robust rolling back.

     err = prepare_module_state_transaction(mod,
                 MODULE_STATE_COMING, MODULE_STATE_GOING);

each notifier including ftrace and klp will be cleanup in 
blocking_notifier_call_chain_robust rolling back.

if all notifiers are successful in MODULE_STATE_COMING, they all will be 
clean up in
  coming_cleanup:
     mod->state = MODULE_STATE_GOING;
     destroy_params(mod->kp, mod->num_kp);
     blocking_notifier_call_chain(&module_notify_list,
                      MODULE_STATE_GOING, mod);

if  something wrong underneath.

>> diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
>> index 8df69e702706..efedb98d3db4 100644
>> --- a/kernel/trace/ftrace.c
>> +++ b/kernel/trace/ftrace.c
>> @@ -5241,6 +5241,44 @@ static int __init ftrace_mod_cmd_init(void)
>>   }
>>   core_initcall(ftrace_mod_cmd_init);
>>   
>> +static int ftrace_module_callback(struct notifier_block *nb, unsigned long op,
>> +			void *module)
>> +{
>> +	struct module *mod = module;
>> +
>> +	switch (op) {
>> +	case MODULE_STATE_UNFORMED:
>> +		ftrace_module_init(mod);
>> +		break;
>> +	case MODULE_STATE_COMING:
>> +		ftrace_module_enable(mod);
>> +		break;
>> +	case MODULE_STATE_LIVE:
>> +		ftrace_free_mem(mod, mod->mem[MOD_INIT_TEXT].base,
>> +				mod->mem[MOD_INIT_TEXT].base + mod->mem[MOD_INIT_TEXT].size);
>> +		break;
>> +	case MODULE_STATE_GOING:
>> +	case MODULE_STATE_FORMED:
>> +		ftrace_release_mod(mod);
>> +		break;
>> +	default:
>> +		break;
>> +	}
> 
> ftrace_module_init(), ftrace_module_enable(), ftrace_free_mem() and
> ftrace_release_mod() should be newly used only in kernel/trace/ftrace.c
> where they are also defined. The functions can then be made static and
> removed from include/linux/ftrace.h.
> 
> Nit: The default case in the switch can be removed.
> 

accepted.

>> +
>> +	return notifier_from_errno(0);
> 
> Nit: This can be simply "return NOTIFY_OK;".

accepted
> 
>> +}
>> +
>> +static struct notifier_block ftrace_module_nb = {
>> +	.notifier_call = ftrace_module_callback,
>> +	.priority = MODULE_NOTIFIER_PRIO_HIGH
>> +};
>> +
>> +static int __init ftrace_register_module_notifier(void)
>> +{
>> +	return register_module_notifier(&ftrace_module_nb);
>> +}
>> +core_initcall(ftrace_register_module_notifier);
>> +
>>   static void function_trace_probe_call(unsigned long ip, unsigned long parent_ip,
>>   				      struct ftrace_ops *op, struct ftrace_regs *fregs)
>>   {
> 

Best regards

Song


^ permalink raw reply

* Re: [PATCH v2] pmdomain: imx: Make IMX8M/IMX9 BLK_CTRL tristate
From: Frank Li @ 2026-04-15  6:58 UTC (permalink / raw)
  To: Zhipeng Wang
  Cc: ulfh, s.hauer, kernel, festevam, linux-pm, imx, linux-arm-kernel,
	linux-kernel, xuegang.liu, jindong.yue
In-Reply-To: <20260413053049.3041177-1-zhipeng.wang_1@nxp.com>

On Mon, Apr 13, 2026 at 02:30:49PM +0900, Zhipeng Wang wrote:
> Convert IMX8M_BLK_CTRL and IMX9_BLK_CTRL from bool to tristate
> to allow building as loadable modules.
>
> Add prompt strings to make these options visible and configurable
> in menuconfig, keeping them enabled by default on appropriate platforms.
>
> Also remove the IMX_GPCV2_PM_DOMAINS dependency from IMX9_BLK_CTRL.
> This dependency was incorrect from the beginning - i.MX93 uses a

s/-/because

Reviewed-by: Frank Li <Frank.Li@nxp.com>

> different power domain architecture compared to i.MX8M series:
>
> - i.MX8M uses GPCv2 (General Power Controller v2) for power domain
>   management, hence IMX8M_BLK_CTRL correctly depends on it.
>
> - i.MX93 uses BLK_CTRL directly without GPCv2. The hardware doesn't
>   have GPCv2 at all.
>
> Signed-off-by: Zhipeng Wang <zhipeng.wang_1@nxp.com>
> ---
>  drivers/pmdomain/imx/Kconfig | 11 +++++++----
>  1 file changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/pmdomain/imx/Kconfig b/drivers/pmdomain/imx/Kconfig
> index 00203615c65e..9168d183b0c5 100644
> --- a/drivers/pmdomain/imx/Kconfig
> +++ b/drivers/pmdomain/imx/Kconfig
> @@ -10,15 +10,18 @@ config IMX_GPCV2_PM_DOMAINS
>  	default y if SOC_IMX7D
>
>  config IMX8M_BLK_CTRL
> -	bool
> -	default SOC_IMX8M && IMX_GPCV2_PM_DOMAINS
> +	tristate "i.MX8M BLK CTRL driver"
> +	depends on SOC_IMX8M
> +	depends on IMX_GPCV2_PM_DOMAINS
>  	depends on PM_GENERIC_DOMAINS
>  	depends on COMMON_CLK
> +	default y
>
>  config IMX9_BLK_CTRL
> -	bool
> -	default SOC_IMX9 && IMX_GPCV2_PM_DOMAINS
> +	tristate "i.MX93 BLK CTRL driver"
> +	depends on SOC_IMX9
>  	depends on PM_GENERIC_DOMAINS
> +	default y
>
>  config IMX_SCU_PD
>  	bool "IMX SCU Power Domain driver"
> --
> 2.34.1
>

^ permalink raw reply

* [RFC PATCH 1/2] kernel/notifier: replace single-linked list with double-linked list for reverse traversal
From: chensong_2000 @ 2026-04-15  7:01 UTC (permalink / raw)
  To: rafael, lenb, mturquette, sboyd, viresh.kumar, agk, snitzer,
	mpatocka, bmarzins, song, yukuai, linan122, jason.wessel, danielt,
	dianders, horms, davem, edumazet, kuba, pabeni, paulmck, frederic,
	mcgrof, petr.pavlu, da.gomez, samitolvanen, atomlin, jpoimboe,
	jikos, mbenes, pmladek, joe.lawrence, rostedt, mhiramat,
	mark.rutland, mathieu.desnoyers
  Cc: linux-modules, linux-kernel, linux-trace-kernel, linux-acpi,
	linux-clk, linux-pm, live-patching, dm-devel, linux-raid,
	kgdb-bugreport, netdev, Song Chen

From: Song Chen <chensong_2000@189.cn>

The current notifier chain implementation uses a single-linked list
(struct notifier_block *next), which only supports forward traversal
in priority order. This makes it difficult to handle cleanup/teardown
scenarios that require notifiers to be called in reverse priority order.

A concrete example is the ordering dependency between ftrace and
livepatch during module load/unload. see the detail here [1].

This patch replaces the single-linked list in struct notifier_block
with a struct list_head, converting the notifier chain into a
doubly-linked list sorted in descending priority order. Based on
this, a new function notifier_call_chain_reverse() is introduced,
which traverses the chain in reverse (ascending priority order).
The corresponding blocking_notifier_call_chain_reverse() is also
added as the locking wrapper for blocking notifier chains.

The internal notifier_call_chain_robust() is updated to use
notifier_call_chain_reverse() for rollback: on error, it records
the failing notifier (last_nb) and the count of successfully called
notifiers (nr), then rolls back exactly those nr-1 notifiers in
reverse order starting from last_nb's predecessor, without needing
to know the total length of the chain.

With this change, subsystems with symmetric setup/teardown ordering
requirements can register a single notifier_block with one priority
value, and rely on blocking_notifier_call_chain() for forward
traversal and blocking_notifier_call_chain_reverse() for reverse
traversal, without needing hard-coded call sequences or separate
notifier registrations for each direction.

[1]:https://lore.kernel.org/all
	/alpine.LNX.2.00.1602172216491.22700@cbobk.fhfr.pm/

Signed-off-by: Song Chen <chensong_2000@189.cn>
---
 drivers/acpi/sleep.c      |   1 -
 drivers/clk/clk.c         |   2 +-
 drivers/cpufreq/cpufreq.c |   2 +-
 drivers/md/dm-integrity.c |   1 -
 drivers/md/md.c           |   1 -
 include/linux/notifier.h  |  26 ++---
 kernel/debug/debug_core.c |   1 -
 kernel/notifier.c         | 219 ++++++++++++++++++++++++++++++++------
 net/ipv4/nexthop.c        |   2 +-
 9 files changed, 201 insertions(+), 54 deletions(-)

diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 132a9df98471..b776dbd5a382 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -56,7 +56,6 @@ static int tts_notify_reboot(struct notifier_block *this,
 
 static struct notifier_block tts_notifier = {
 	.notifier_call	= tts_notify_reboot,
-	.next		= NULL,
 	.priority	= 0,
 };
 
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 47093cda9df3..b6fe380d0468 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -4862,7 +4862,7 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb)
 			clk->core->notifier_count--;
 
 			/* XXX the notifier code should handle this better */
-			if (!cn->notifier_head.head) {
+			if (list_empty(&cn->notifier_head.head)) {
 				srcu_cleanup_notifier_head(&cn->notifier_head);
 				list_del(&cn->node);
 				kfree(cn);
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 277884d91913..12637e742ffa 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -445,7 +445,7 @@ static void cpufreq_list_transition_notifiers(void)
 
 	mutex_lock(&cpufreq_transition_notifier_list.mutex);
 
-	for (nb = cpufreq_transition_notifier_list.head; nb; nb = nb->next)
+	list_for_each_entry(nb, &cpufreq_transition_notifier_list.head, entry)
 		pr_info("%pS\n", nb->notifier_call);
 
 	mutex_unlock(&cpufreq_transition_notifier_list.mutex);
diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c
index 06e805902151..ccdf75c40b62 100644
--- a/drivers/md/dm-integrity.c
+++ b/drivers/md/dm-integrity.c
@@ -3909,7 +3909,6 @@ static void dm_integrity_resume(struct dm_target *ti)
 	}
 
 	ic->reboot_notifier.notifier_call = dm_integrity_reboot;
-	ic->reboot_notifier.next = NULL;
 	ic->reboot_notifier.priority = INT_MAX - 1;	/* be notified after md and before hardware drivers */
 	WARN_ON(register_reboot_notifier(&ic->reboot_notifier));
 
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 3ce6f9e9d38e..8249e78636ab 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -10480,7 +10480,6 @@ static int md_notify_reboot(struct notifier_block *this,
 
 static struct notifier_block md_notifier = {
 	.notifier_call	= md_notify_reboot,
-	.next		= NULL,
 	.priority	= INT_MAX, /* before any real devices */
 };
 
diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index 01b6c9d9956f..b2abbdfcaadd 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -53,41 +53,41 @@ typedef	int (*notifier_fn_t)(struct notifier_block *nb,
 
 struct notifier_block {
 	notifier_fn_t notifier_call;
-	struct notifier_block __rcu *next;
+	struct list_head __rcu entry;
 	int priority;
 };
 
 struct atomic_notifier_head {
 	spinlock_t lock;
-	struct notifier_block __rcu *head;
+	struct list_head __rcu head;
 };
 
 struct blocking_notifier_head {
 	struct rw_semaphore rwsem;
-	struct notifier_block __rcu *head;
+	struct list_head __rcu head;
 };
 
 struct raw_notifier_head {
-	struct notifier_block __rcu *head;
+	struct list_head __rcu head;
 };
 
 struct srcu_notifier_head {
 	struct mutex mutex;
 	struct srcu_usage srcuu;
 	struct srcu_struct srcu;
-	struct notifier_block __rcu *head;
+	struct list_head __rcu head;
 };
 
 #define ATOMIC_INIT_NOTIFIER_HEAD(name) do {	\
 		spin_lock_init(&(name)->lock);	\
-		(name)->head = NULL;		\
+		INIT_LIST_HEAD(&(name)->head);		\
 	} while (0)
 #define BLOCKING_INIT_NOTIFIER_HEAD(name) do {	\
 		init_rwsem(&(name)->rwsem);	\
-		(name)->head = NULL;		\
+		INIT_LIST_HEAD(&(name)->head);		\
 	} while (0)
 #define RAW_INIT_NOTIFIER_HEAD(name) do {	\
-		(name)->head = NULL;		\
+		INIT_LIST_HEAD(&(name)->head);		\
 	} while (0)
 
 /* srcu_notifier_heads must be cleaned up dynamically */
@@ -97,17 +97,17 @@ extern void srcu_init_notifier_head(struct srcu_notifier_head *nh);
 
 #define ATOMIC_NOTIFIER_INIT(name) {				\
 		.lock = __SPIN_LOCK_UNLOCKED(name.lock),	\
-		.head = NULL }
+		.head = LIST_HEAD_INIT((name).head) }
 #define BLOCKING_NOTIFIER_INIT(name) {				\
 		.rwsem = __RWSEM_INITIALIZER((name).rwsem),	\
-		.head = NULL }
+		.head = LIST_HEAD_INIT((name).head) }
 #define RAW_NOTIFIER_INIT(name)	{				\
-		.head = NULL }
+		.head = LIST_HEAD_INIT((name).head) }
 
 #define SRCU_NOTIFIER_INIT(name, pcpu)				\
 	{							\
 		.mutex = __MUTEX_INITIALIZER(name.mutex),	\
-		.head = NULL,					\
+		.head = LIST_HEAD_INIT((name).head),					\
 		.srcuu = __SRCU_USAGE_INIT(name.srcuu),		\
 		.srcu = __SRCU_STRUCT_INIT(name.srcu, name.srcuu, pcpu, 0), \
 	}
@@ -170,6 +170,8 @@ extern int atomic_notifier_call_chain(struct atomic_notifier_head *nh,
 		unsigned long val, void *v);
 extern int blocking_notifier_call_chain(struct blocking_notifier_head *nh,
 		unsigned long val, void *v);
+extern int blocking_notifier_call_chain_reverse(struct blocking_notifier_head *nh,
+		unsigned long val, void *v);
 extern int raw_notifier_call_chain(struct raw_notifier_head *nh,
 		unsigned long val, void *v);
 extern int srcu_notifier_call_chain(struct srcu_notifier_head *nh,
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c
index 0b9495187fba..a26a7683d142 100644
--- a/kernel/debug/debug_core.c
+++ b/kernel/debug/debug_core.c
@@ -1054,7 +1054,6 @@ dbg_notify_reboot(struct notifier_block *this, unsigned long code, void *x)
 
 static struct notifier_block dbg_reboot_notifier = {
 	.notifier_call		= dbg_notify_reboot,
-	.next			= NULL,
 	.priority		= INT_MAX,
 };
 
diff --git a/kernel/notifier.c b/kernel/notifier.c
index 2f9fe7c30287..6f4d887771c4 100644
--- a/kernel/notifier.c
+++ b/kernel/notifier.c
@@ -14,39 +14,47 @@
  *	are layered on top of these, with appropriate locking added.
  */
 
-static int notifier_chain_register(struct notifier_block **nl,
+static int notifier_chain_register(struct list_head *nl,
 				   struct notifier_block *n,
 				   bool unique_priority)
 {
-	while ((*nl) != NULL) {
-		if (unlikely((*nl) == n)) {
+	struct notifier_block *cur;
+
+	list_for_each_entry(cur, nl, entry) {
+		if (unlikely(cur == n)) {
 			WARN(1, "notifier callback %ps already registered",
 			     n->notifier_call);
 			return -EEXIST;
 		}
-		if (n->priority > (*nl)->priority)
-			break;
-		if (n->priority == (*nl)->priority && unique_priority)
+
+		if (n->priority == cur->priority && unique_priority)
 			return -EBUSY;
-		nl = &((*nl)->next);
+
+		if (n->priority > cur->priority) {
+			list_add_tail(&n->entry, &cur->entry);
+			goto out;
+		}
 	}
-	n->next = *nl;
-	rcu_assign_pointer(*nl, n);
+
+	list_add_tail(&n->entry, nl);
+out:
 	trace_notifier_register((void *)n->notifier_call);
 	return 0;
 }
 
-static int notifier_chain_unregister(struct notifier_block **nl,
+static int notifier_chain_unregister(struct list_head *nl,
 		struct notifier_block *n)
 {
-	while ((*nl) != NULL) {
-		if ((*nl) == n) {
-			rcu_assign_pointer(*nl, n->next);
+	struct notifier_block *cur;
+
+	list_for_each_entry(cur, nl, entry) {
+		if (cur == n) {
+			list_del(&n->entry);
 			trace_notifier_unregister((void *)n->notifier_call);
 			return 0;
 		}
-		nl = &((*nl)->next);
 	}
+
 	return -ENOENT;
 }
 
@@ -59,25 +67,25 @@ static int notifier_chain_unregister(struct notifier_block **nl,
  *			value of this parameter is -1.
  *	@nr_calls:	Records the number of notifications sent. Don't care
  *			value of this field is NULL.
+ *	@last_nb:  Records the last called notifier block for rolling back
  *	Return:		notifier_call_chain returns the value returned by the
  *			last notifier function called.
  */
-static int notifier_call_chain(struct notifier_block **nl,
+static int notifier_call_chain(struct list_head *nl,
 			       unsigned long val, void *v,
-			       int nr_to_call, int *nr_calls)
+			       int nr_to_call, int *nr_calls,
+				   struct notifier_block **last_nb)
 {
 	int ret = NOTIFY_DONE;
-	struct notifier_block *nb, *next_nb;
-
-	nb = rcu_dereference_raw(*nl);
+	struct notifier_block *nb;
 
-	while (nb && nr_to_call) {
-		next_nb = rcu_dereference_raw(nb->next);
+	if (!nr_to_call)
+		return ret;
 
+	list_for_each_entry(nb, nl, entry) {
 #ifdef CONFIG_DEBUG_NOTIFIERS
 		if (unlikely(!func_ptr_is_kernel_text(nb->notifier_call))) {
 			WARN(1, "Invalid notifier called!");
-			nb = next_nb;
 			continue;
 		}
 #endif
@@ -87,15 +95,118 @@ static int notifier_call_chain(struct notifier_block **nl,
 		if (nr_calls)
 			(*nr_calls)++;
 
+		if (last_nb)
+			*last_nb = nb;
+
 		if (ret & NOTIFY_STOP_MASK)
 			break;
-		nb = next_nb;
-		nr_to_call--;
+
+		if (nr_to_call-- == 0)
+			break;
 	}
 	return ret;
 }
 NOKPROBE_SYMBOL(notifier_call_chain);
 
+/**
+ * notifier_call_chain_reverse - Informs the registered notifiers
+ *			about an event reversely.
+ *	@nl:		Pointer to head of the blocking notifier chain
+ *	@val:		Value passed unmodified to notifier function
+ *	@v:		Pointer passed unmodified to notifier function
+ *	@nr_to_call:	Number of notifier functions to be called. Don't care
+ *			value of this parameter is -1.
+ *	@nr_calls:	Records the number of notifications sent. Don't care
+ *			value of this field is NULL.
+ *	Return:		notifier_call_chain returns the value returned by the
+ *			last notifier function called.
+ */
+static int notifier_call_chain_reverse(struct list_head *nl,
+					struct notifier_block *start,
+					unsigned long val, void *v,
+					int nr_to_call, int *nr_calls)
+{
+	int ret = NOTIFY_DONE;
+	struct notifier_block *nb;
+	bool do_call = (start == NULL);
+
+	if (!nr_to_call)
+		return ret;
+
+	list_for_each_entry_reverse(nb, nl, entry) {
+		if (!do_call) {
+			if (nb == start)
+				do_call = true;
+			continue;
+		}
+#ifdef CONFIG_DEBUG_NOTIFIERS
+		if (unlikely(!func_ptr_is_kernel_text(nb->notifier_call))) {
+			WARN(1, "Invalid notifier called!");
+			continue;
+		}
+#endif
+		trace_notifier_run((void *)nb->notifier_call);
+		ret = nb->notifier_call(nb, val, v);
+
+		if (nr_calls)
+			(*nr_calls)++;
+
+		if (ret & NOTIFY_STOP_MASK)
+			break;
+
+		if (nr_to_call-- == 0)
+			break;
+	}
+	return ret;
+}
+NOKPROBE_SYMBOL(notifier_call_chain_reverse);
+
+/**
+ * notifier_call_chain_rcu - Informs the registered notifiers
+ *			about an event for srcu notifier chain.
+ *	@nl:		Pointer to head of the blocking notifier chain
+ *	@val:		Value passed unmodified to notifier function
+ *	@v:		Pointer passed unmodified to notifier function
+ *	@nr_to_call:	Number of notifier functions to be called. Don't care
+ *			value of this parameter is -1.
+ *	@nr_calls:	Records the number of notifications sent. Don't care
+ *			value of this field is NULL.
+ *	Return:		notifier_call_chain returns the value returned by the
+ *			last notifier function called.
+ */
+static int notifier_call_chain_rcu(struct list_head *nl,
+			       unsigned long val, void *v,
+			       int nr_to_call, int *nr_calls)
+{
+	int ret = NOTIFY_DONE;
+	struct notifier_block *nb;
+
+	if (!nr_to_call)
+		return ret;
+
+	list_for_each_entry_rcu(nb, nl, entry) {
+#ifdef CONFIG_DEBUG_NOTIFIERS
+		if (unlikely(!func_ptr_is_kernel_text(nb->notifier_call))) {
+			WARN(1, "Invalid notifier called!");
+			continue;
+		}
+#endif
+		trace_notifier_run((void *)nb->notifier_call);
+		ret = nb->notifier_call(nb, val, v);
+
+		if (nr_calls)
+			(*nr_calls)++;
+
+		if (ret & NOTIFY_STOP_MASK)
+			break;
+
+		if (nr_to_call-- == 0)
+			break;
+	}
+	return ret;
+}
+NOKPROBE_SYMBOL(notifier_call_chain_rcu);
+
 /**
  * notifier_call_chain_robust - Inform the registered notifiers about an event
  *                              and rollback on error.
@@ -111,15 +222,16 @@ NOKPROBE_SYMBOL(notifier_call_chain);
  *
  * Return:	the return value of the @val_up call.
  */
-static int notifier_call_chain_robust(struct notifier_block **nl,
+static int notifier_call_chain_robust(struct list_head *nl,
 				     unsigned long val_up, unsigned long val_down,
 				     void *v)
 {
 	int ret, nr = 0;
+	struct notifier_block *last_nb = NULL;
 
-	ret = notifier_call_chain(nl, val_up, v, -1, &nr);
+	ret = notifier_call_chain(nl, val_up, v, -1, &nr, &last_nb);
 	if (ret & NOTIFY_STOP_MASK)
-		notifier_call_chain(nl, val_down, v, nr-1, NULL);
+		notifier_call_chain_reverse(nl, last_nb, val_down, v, nr-1, NULL);
 
 	return ret;
 }
@@ -220,7 +332,7 @@ int atomic_notifier_call_chain(struct atomic_notifier_head *nh,
 	int ret;
 
 	rcu_read_lock();
-	ret = notifier_call_chain(&nh->head, val, v, -1, NULL);
+	ret = notifier_call_chain(&nh->head, val, v, -1, NULL, NULL);
 	rcu_read_unlock();
 
 	return ret;
@@ -238,7 +350,7 @@ NOKPROBE_SYMBOL(atomic_notifier_call_chain);
  */
 bool atomic_notifier_call_chain_is_empty(struct atomic_notifier_head *nh)
 {
-	return !rcu_access_pointer(nh->head);
+	return list_empty(&nh->head);
 }
 
 /*
@@ -340,7 +452,7 @@ int blocking_notifier_call_chain_robust(struct blocking_notifier_head *nh,
 	 * racy then it does not matter what the result of the test
 	 * is, we re-check the list after having taken the lock anyway:
 	 */
-	if (rcu_access_pointer(nh->head)) {
+	if (!list_empty(&nh->head)) {
 		down_read(&nh->rwsem);
 		ret = notifier_call_chain_robust(&nh->head, val_up, val_down, v);
 		up_read(&nh->rwsem);
@@ -375,15 +487,52 @@ int blocking_notifier_call_chain(struct blocking_notifier_head *nh,
 	 * racy then it does not matter what the result of the test
 	 * is, we re-check the list after having taken the lock anyway:
 	 */
-	if (rcu_access_pointer(nh->head)) {
+	if (!list_empty(&nh->head)) {
 		down_read(&nh->rwsem);
-		ret = notifier_call_chain(&nh->head, val, v, -1, NULL);
+		ret = notifier_call_chain(&nh->head, val, v, -1, NULL, NULL);
 		up_read(&nh->rwsem);
 	}
 	return ret;
 }
 EXPORT_SYMBOL_GPL(blocking_notifier_call_chain);
 
+/**
+ *	blocking_notifier_call_chain_reverse - Call functions reversely in
+ *				a blocking notifier chain
+ *	@nh: Pointer to head of the blocking notifier chain
+ *	@val: Value passed unmodified to notifier function
+ *	@v: Pointer passed unmodified to notifier function
+ *
+ *	Calls each function in a notifier chain in turn.  The functions
+ *	run in a process context, so they are allowed to block.
+ *
+ *	If the return value of the notifier can be and'ed
+ *	with %NOTIFY_STOP_MASK then blocking_notifier_call_chain()
+ *	will return immediately, with the return value of
+ *	the notifier function which halted execution.
+ *	Otherwise the return value is the return value
+ *	of the last notifier function called.
+ */
+
+int blocking_notifier_call_chain_reverse(struct blocking_notifier_head *nh,
+		unsigned long val, void *v)
+{
+	int ret = NOTIFY_DONE;
+
+	/*
+	 * We check the head outside the lock, but if this access is
+	 * racy then it does not matter what the result of the test
+	 * is, we re-check the list after having taken the lock anyway:
+	 */
+	if (!list_empty(&nh->head)) {
+		down_read(&nh->rwsem);
+		ret = notifier_call_chain_reverse(&nh->head, NULL, val, v, -1, NULL);
+		up_read(&nh->rwsem);
+	}
+	return ret;
+}
+EXPORT_SYMBOL_GPL(blocking_notifier_call_chain_reverse);
+
 /*
  *	Raw notifier chain routines.  There is no protection;
  *	the caller must provide it.  Use at your own risk!
@@ -450,7 +599,7 @@ EXPORT_SYMBOL_GPL(raw_notifier_call_chain_robust);
 int raw_notifier_call_chain(struct raw_notifier_head *nh,
 		unsigned long val, void *v)
 {
-	return notifier_call_chain(&nh->head, val, v, -1, NULL);
+	return notifier_call_chain(&nh->head, val, v, -1, NULL, NULL);
 }
 EXPORT_SYMBOL_GPL(raw_notifier_call_chain);
 
@@ -543,7 +692,7 @@ int srcu_notifier_call_chain(struct srcu_notifier_head *nh,
 	int idx;
 
 	idx = srcu_read_lock(&nh->srcu);
-	ret = notifier_call_chain(&nh->head, val, v, -1, NULL);
+	ret = notifier_call_chain_rcu(&nh->head, val, v, -1, NULL);
 	srcu_read_unlock(&nh->srcu, idx);
 	return ret;
 }
@@ -566,7 +715,7 @@ void srcu_init_notifier_head(struct srcu_notifier_head *nh)
 	mutex_init(&nh->mutex);
 	if (init_srcu_struct(&nh->srcu) < 0)
 		BUG();
-	nh->head = NULL;
+	INIT_LIST_HEAD(&nh->head);
 }
 EXPORT_SYMBOL_GPL(srcu_init_notifier_head);
 
diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c
index c942f1282236..0afcba2967c7 100644
--- a/net/ipv4/nexthop.c
+++ b/net/ipv4/nexthop.c
@@ -90,7 +90,7 @@ static const struct nla_policy rtm_nh_res_bucket_policy_get[] = {
 
 static bool nexthop_notifiers_is_empty(struct net *net)
 {
-	return !net->nexthop.notifier_chain.head;
+	return list_empty(&net->nexthop.notifier_chain.head);
 }
 
 static void
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH v4 02/13] dt-bindings: leds: document Samsung S2M series PMIC RGB LED device
From: Krzysztof Kozlowski @ 2026-04-15  7:03 UTC (permalink / raw)
  To: Kaustabh Chakraborty
  Cc: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, MyungJoo Ham, Chanwoo Choi, Sebastian Reichel,
	André Draszik, Alexandre Belloni, Jonathan Corbet,
	Shuah Khan, Nam Tran, Łukasz Lebiedziński, linux-leds,
	devicetree, linux-kernel, linux-pm, linux-samsung-soc, linux-rtc,
	linux-doc
In-Reply-To: <20260414-s2mu005-pmic-v4-2-7fe7480577e6@disroot.org>

On Tue, Apr 14, 2026 at 12:02:54PM +0530, Kaustabh Chakraborty wrote:
> +description: |
> +  The Samsung S2M series PMIC RGB LED is a three-channel LED device with
> +  8-bit brightness control for each channel, typically used as status
> +  indicators in mobile phones.
> +
> +  This is a part of device tree bindings for S2M and S5M family of Power
> +  Management IC (PMIC).
> +
> +  See also Documentation/devicetree/bindings/mfd/samsung,s2mps11.yaml for
> +  additional information and example.
> +
> +allOf:
> +  - $ref: common.yaml#

Rob's comment is still valid:
1. How do you address one of three LEDs in non-RGB case?
2. Where is multi-color?

And based on this alone without other properties, I say this should be
part of top-level schema.  Separate node is fine, but no need for
separate binding.

Best regards,
Krzysztof


^ permalink raw reply

* Re: [PATCH RFC 05/11] riscv: cpufeature: Add Sdtrig optional CSRs checks
From: Zane Leung @ 2026-04-15  7:05 UTC (permalink / raw)
  To: Max Hsu, Conor Dooley, Rob Herring, Krzysztof Kozlowski,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Rafael J. Wysocki,
	Pavel Machek, Anup Patel, Atish Patra, Paolo Bonzini, Shuah Khan
  Cc: Palmer Dabbelt, linux-riscv, devicetree, linux-kernel, linux-pm,
	kvm, kvm-riscv, linux-kselftest
In-Reply-To: <20240329-dev-maxh-lin-452-6-9-v1-5-1534f93b94a7@sifive.com>


On 3/29/2024 5:26 PM, Max Hsu wrote:
> Sdtrig extension introduce two optional CSRs [hcontext/scontext],
> that will be storing PID/Guest OS ID for the debug feature.
>
> The availability of these two CSRs will be determined by
> DTS and Smstateen extension [h/s]stateen0 CSR bit 57.
>
> If all CPUs hcontext/scontext checks are satisfied, it will enable the
> use_hcontext/use_scontext static branch.
>
> Signed-off-by: Max Hsu <max.hsu@sifive.com>
> ---
>  arch/riscv/include/asm/switch_to.h |   6 ++
>  arch/riscv/kernel/cpufeature.c     | 161 +++++++++++++++++++++++++++++++++++++
>  2 files changed, 167 insertions(+)
>
> diff --git a/arch/riscv/include/asm/switch_to.h b/arch/riscv/include/asm/switch_to.h
> index 7efdb0584d47..07432550ed54 100644
> --- a/arch/riscv/include/asm/switch_to.h
> +++ b/arch/riscv/include/asm/switch_to.h
> @@ -69,6 +69,12 @@ static __always_inline bool has_fpu(void) { return false; }
>  #define __switch_to_fpu(__prev, __next) do { } while (0)
>  #endif
>  
> +DECLARE_STATIC_KEY_FALSE(use_scontext);
> +static __always_inline bool has_scontext(void)
> +{
> +	return static_branch_likely(&use_scontext);
> +}
> +
>  extern struct task_struct *__switch_to(struct task_struct *,
>  				       struct task_struct *);
>  
> diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
> index 080c06b76f53..44ff84b920af 100644
> --- a/arch/riscv/kernel/cpufeature.c
> +++ b/arch/riscv/kernel/cpufeature.c
> @@ -35,6 +35,19 @@ static DECLARE_BITMAP(riscv_isa, RISCV_ISA_EXT_MAX) __read_mostly;
>  /* Per-cpu ISA extensions. */
>  struct riscv_isainfo hart_isa[NR_CPUS];
>  
> +atomic_t hcontext_disable;
> +atomic_t scontext_disable;
> +
> +DEFINE_STATIC_KEY_FALSE_RO(use_hcontext);
> +EXPORT_SYMBOL(use_hcontext);
> +
> +DEFINE_STATIC_KEY_FALSE_RO(use_scontext);
> +EXPORT_SYMBOL(use_scontext);
> +
> +/* Record the maximum number that the hcontext CSR allowed to hold */
> +atomic_long_t hcontext_id_share;
> +EXPORT_SYMBOL(hcontext_id_share);
> +
>  /**
>   * riscv_isa_extension_base() - Get base extension word
>   *
> @@ -719,6 +732,154 @@ unsigned long riscv_get_elf_hwcap(void)
>  	return hwcap;
>  }
>  
> +static void __init sdtrig_percpu_csrs_check(void *data)
> +{
> +	struct device_node *node;
> +	struct device_node *debug_node;
> +	struct device_node *trigger_module;
> +
> +	unsigned int cpu = smp_processor_id();
> +
> +	/*
> +	 * Expect every cpu node has the [h/s]context-present property
> +	 * otherwise, jump to sdtrig_csrs_disable_all to disable all access to
> +	 * [h/s]context CSRs
> +	 */
> +	node = of_cpu_device_node_get(cpu);
> +	if (!node)
> +		goto sdtrig_csrs_disable_all;
> +
> +	debug_node = of_get_compatible_child(node, "riscv,debug-v1.0.0");
> +	of_node_put(node);
> +
> +	if (!debug_node)
> +		goto sdtrig_csrs_disable_all;
> +
> +	trigger_module = of_get_child_by_name(debug_node, "trigger-module");
> +	of_node_put(debug_node);
> +
> +	if (!trigger_module)
> +		goto sdtrig_csrs_disable_all;
> +
> +	if (!(IS_ENABLED(CONFIG_KVM) &&
> +	      of_property_read_bool(trigger_module, "hcontext-present")))
> +		atomic_inc(&hcontext_disable);
> +
> +	if (!of_property_read_bool(trigger_module, "scontext-present"))
> +		atomic_inc(&scontext_disable);
> +
> +	of_node_put(trigger_module);
> +
> +	/*
> +	 * Before access to hcontext/scontext CSRs, if the smstateen
> +	 * extension is present, the accessibility will be controlled
> +	 * by the hstateen0[H]/sstateen0 CSRs.
> +	 */
> +	if (__riscv_isa_extension_available(NULL, RISCV_ISA_EXT_SMSTATEEN)) {
> +		u64 hstateen_bit, sstateen_bit;
> +
> +		if (__riscv_isa_extension_available(NULL, RISCV_ISA_EXT_h)) {
> +#if __riscv_xlen > 32
> +			csr_set(CSR_HSTATEEN0, SMSTATEEN0_HSCONTEXT);
> +			hstateen_bit = csr_read(CSR_HSTATEEN0);
> +#else
> +			csr_set(CSR_HSTATEEN0H, SMSTATEEN0_HSCONTEXT >> 32);
> +			hstateen_bit = csr_read(CSR_HSTATEEN0H) << 32;
> +#endif
> +			if (!(hstateen_bit & SMSTATEEN0_HSCONTEXT))
> +				goto sdtrig_csrs_disable_all;
> +
> +		} else {
> +			if (IS_ENABLED(CONFIG_KVM))
> +				atomic_inc(&hcontext_disable);
> +
> +			/*
> +			 * In RV32, the smstateen extension doesn't provide
> +			 * high 32 bits of sstateen0 CSR which represent
> +			 * accessibility for scontext CSR;
> +			 * The decision is left on whether the dts has the
> +			 * property to access the scontext CSR.
> +			 */
> +#if __riscv_xlen > 32
> +			csr_set(CSR_SSTATEEN0, SMSTATEEN0_HSCONTEXT);
> +			sstateen_bit = csr_read(CSR_SSTATEEN0);
> +
> +			if (!(sstateen_bit & SMSTATEEN0_HSCONTEXT))
> +				atomic_inc(&scontext_disable);
> +#endif
For the supervisor-level sstateen registers, high-half CSRs are not added at this time because
it is expected the upper 32 bits of these registers will always be zeros. see:
https://github.com/riscv/riscv-isa-manual/blob/dca12d638b140d86441ad0b067997c70d2017017/src/priv/smstateen.adoc#L71-L7


> +		}
> +	}
> +
> +	/*
> +	 * The code can only access hcontext/scontext CSRs if:
> +	 * The cpu dts node have [h/s]context-present;
> +	 * If Smstateen extension is presented, then the accessibility bit
> +	 * toward hcontext/scontext CSRs is enabled; Or the Smstateen extension
> +	 * isn't available, thus the access won't be blocked by it.
> +	 *
> +	 * With writing 1 to the every bit of these CSRs, we retrieve the
> +	 * maximum bits that is available on the CSRs. and decide
> +	 * whether it's suit for its context recording operation.
> +	 */
> +	if (IS_ENABLED(CONFIG_KVM) &&
> +	    !atomic_read(&hcontext_disable)) {
> +		unsigned long hcontext_available_bits = 0;
> +
> +		csr_write(CSR_HCONTEXT, -1UL);
> +		hcontext_available_bits = csr_swap(CSR_HCONTEXT, hcontext_available_bits);
> +
> +		/* hcontext CSR is required by at least 1 bit */
> +		if (hcontext_available_bits)
> +			atomic_long_and(hcontext_available_bits, &hcontext_id_share);
> +		else
> +			atomic_inc(&hcontext_disable);
> +	}
> +
> +	if (!atomic_read(&scontext_disable)) {
> +		unsigned long scontext_available_bits = 0;
> +
> +		csr_write(CSR_SCONTEXT, -1UL);
> +		scontext_available_bits = csr_swap(CSR_SCONTEXT, scontext_available_bits);
> +
> +		/* scontext CSR is required by at least the sizeof pid_t */
> +		if (scontext_available_bits < ((1UL << (sizeof(pid_t) << 3)) - 1))
> +			atomic_inc(&scontext_disable);
> +	}
> +
> +	return;
> +
> +sdtrig_csrs_disable_all:
> +	if (IS_ENABLED(CONFIG_KVM))
> +		atomic_inc(&hcontext_disable);
> +
> +	atomic_inc(&scontext_disable);
> +}
> +
> +static int __init sdtrig_enable_csrs_fill(void)
> +{
> +	if (__riscv_isa_extension_available(NULL, RISCV_ISA_EXT_SDTRIG)) {
> +		atomic_long_set(&hcontext_id_share, -1UL);
> +
> +		/* check every CPUs sdtrig extension optional CSRs */
> +		sdtrig_percpu_csrs_check(NULL);
> +		smp_call_function(sdtrig_percpu_csrs_check, NULL, 1);
> +
> +		if (IS_ENABLED(CONFIG_KVM) &&
> +		    !atomic_read(&hcontext_disable)) {
> +			pr_info("riscv-sdtrig: Writing 'GuestOS ID' to hcontext CSR is enabled\n");
> +			static_branch_enable(&use_hcontext);
> +		}
> +
> +		if (!atomic_read(&scontext_disable)) {
> +			pr_info("riscv-sdtrig: Writing 'PID' to scontext CSR is enabled\n");
> +			static_branch_enable(&use_scontext);
> +		}
> +	}
> +	return 0;
> +}
> +
> +arch_initcall(sdtrig_enable_csrs_fill);
> +
>  void riscv_user_isa_enable(void)
>  {
>  	if (riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_ZICBOZ))
>

^ permalink raw reply

* Re: [PATCH v4 05/13] dt-bindings: mfd: s2mps11: add documentation for S2MU005 PMIC
From: Krzysztof Kozlowski @ 2026-04-15  7:17 UTC (permalink / raw)
  To: Kaustabh Chakraborty
  Cc: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, MyungJoo Ham, Chanwoo Choi, Sebastian Reichel,
	André Draszik, Alexandre Belloni, Jonathan Corbet,
	Shuah Khan, Nam Tran, Łukasz Lebiedziński, linux-leds,
	devicetree, linux-kernel, linux-pm, linux-samsung-soc, linux-rtc,
	linux-doc
In-Reply-To: <20260414-s2mu005-pmic-v4-5-7fe7480577e6@disroot.org>

On Tue, Apr 14, 2026 at 12:02:57PM +0530, Kaustabh Chakraborty wrote:
> Samsung's S2MU005 PMIC includes subdevices for a charger, an MUIC (Micro
> USB Interface Controller), and flash and RGB LED controllers.
> 
> Since regulators are not supported by this device, unmark this property
> as required and instead set this in a per-device basis for ones which
> need it.
> 
> Add the compatible and documentation for the S2MU005 PMIC. Also, add an
> example for nodes for supported sub-devices, i.e. charger, extcon,
> flash, and rgb.
> 

Limited review because this does not pass build checks.

> Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
> ---
>  .../devicetree/bindings/mfd/samsung,s2mps11.yaml   | 121 ++++++++++++++++++++-
>  1 file changed, 120 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/mfd/samsung,s2mps11.yaml b/Documentation/devicetree/bindings/mfd/samsung,s2mps11.yaml
> index ac5d0c149796b..d3d305b9aa765 100644
> --- a/Documentation/devicetree/bindings/mfd/samsung,s2mps11.yaml
> +++ b/Documentation/devicetree/bindings/mfd/samsung,s2mps11.yaml
> @@ -26,12 +26,28 @@ properties:
>        - samsung,s2mps15-pmic
>        - samsung,s2mpu02-pmic
>        - samsung,s2mpu05-pmic
> +      - samsung,s2mu005-pmic
>  
>    clocks:
>      $ref: /schemas/clock/samsung,s2mps11.yaml
>      description:
>        Child node describing clock provider.
>  
> +  charger:
> +    $ref: /schemas/power/supply/samsung,s2mu005-charger.yaml
> +    description:
> +      Child node describing battery charger device.
> +
> +  extcon:

You got comment to drop extcon naming. If this stays, it's muic for
example.

> +    $ref: /schemas/extcon/samsung,s2mu005-muic.yaml
> +    description:
> +      Child node describing extcon device.
> +
> +  flash:
> +    $ref: /schemas/leds/samsung,s2mu005-flash.yaml
> +    description:
> +      Child node describing flash LEDs.
> +

Please make it a separate binding file.

>    interrupts:
>      maxItems: 1
>  
> @@ -43,6 +59,11 @@ properties:
>      description:
>        List of child nodes that specify the regulators.
>  
> +  rgb:

led

> +    $ref: /schemas/leds/samsung,s2mu005-rgb.yaml
> +    description:
> +      Child node describing RGB LEDs.
> +
>    samsung,s2mps11-acokb-ground:
>      description: |
>        Indicates that ACOKB pin of S2MPS11 PMIC is connected to the ground so
> @@ -63,7 +84,6 @@ properties:
>  required:
>    - compatible
>    - reg
> -  - regulators
>  
>  additionalProperties: false
>  
> @@ -78,6 +98,8 @@ allOf:
>          regulators:
>            $ref: /schemas/regulator/samsung,s2mps11.yaml
>          samsung,s2mps11-wrstbi-ground: false
> +      required:
> +        - regulators
>  
>    - if:
>        properties:
> @@ -89,6 +111,8 @@ allOf:
>          regulators:
>            $ref: /schemas/regulator/samsung,s2mps13.yaml
>          samsung,s2mps11-acokb-ground: false
> +      required:
> +        - regulators
>  
>    - if:
>        properties:
> @@ -101,6 +125,8 @@ allOf:
>            $ref: /schemas/regulator/samsung,s2mps14.yaml
>          samsung,s2mps11-acokb-ground: false
>          samsung,s2mps11-wrstbi-ground: false
> +      required:
> +        - regulators
>  
>    - if:
>        properties:
> @@ -113,6 +139,8 @@ allOf:
>            $ref: /schemas/regulator/samsung,s2mps15.yaml
>          samsung,s2mps11-acokb-ground: false
>          samsung,s2mps11-wrstbi-ground: false
> +      required:
> +        - regulators
>  
>    - if:
>        properties:
> @@ -125,6 +153,8 @@ allOf:
>            $ref: /schemas/regulator/samsung,s2mpu02.yaml
>          samsung,s2mps11-acokb-ground: false
>          samsung,s2mps11-wrstbi-ground: false
> +      required:
> +        - regulators
>  
>    - if:
>        properties:
> @@ -137,6 +167,18 @@ allOf:
>            $ref: /schemas/regulator/samsung,s2mpu05.yaml
>          samsung,s2mps11-acokb-ground: false
>          samsung,s2mps11-wrstbi-ground: false
> +      required:
> +        - regulators
> +
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: samsung,s2mu005-pmic
> +    then:
> +      properties:
> +        samsung,s2mps11-acokb-ground: false
> +        samsung,s2mps11-wrstbi-ground: false
>  
>  examples:
>    - |
> @@ -278,3 +320,80 @@ examples:
>              };
>          };
>      };
> +
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/leds/common.h>
> +
> +    i2c {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        pmic@3d {
> +            compatible = "samsung,s2mu005-pmic";
> +            reg = <0x3d>;
> +            interrupt-parent = <&gpa2>;
> +            interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
> +
> +            charger {
> +                compatible = "samsung,s2mu005-charger";
> +                monitored-battery = <&battery>;
> +
> +                port {
> +                    charger_to_muic: endpoint {
> +                        remote-endpoint = <&muic_to_charger>;

graph between own nodes is pointless.

Best regards,
Krzysztof


^ permalink raw reply

* Re: [PATCH v4 04/13] dt-bindings: power: supply: document Samsung S2M series PMIC charger device
From: Krzysztof Kozlowski @ 2026-04-15  7:18 UTC (permalink / raw)
  To: Kaustabh Chakraborty
  Cc: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, MyungJoo Ham, Chanwoo Choi, Sebastian Reichel,
	André Draszik, Alexandre Belloni, Jonathan Corbet,
	Shuah Khan, Nam Tran, Łukasz Lebiedziński, linux-leds,
	devicetree, linux-kernel, linux-pm, linux-samsung-soc, linux-rtc,
	linux-doc
In-Reply-To: <20260414-s2mu005-pmic-v4-4-7fe7480577e6@disroot.org>

On Tue, Apr 14, 2026 at 12:02:56PM +0530, Kaustabh Chakraborty wrote:
> +description: |
> +  The Samsung S2M series PMIC battery charger manages power interfacing
> +  of the USB port. It may supply power, as done in USB OTG operation
> +  mode, or it may accept power and redirect it to the battery fuelgauge
> +  for charging.
> +
> +  This is a part of device tree bindings for S2M and S5M family of Power
> +  Management IC (PMIC).
> +
> +  See also Documentation/devicetree/bindings/mfd/samsung,s2mps11.yaml for
> +  additional information and example.
> +
> +allOf:
> +  - $ref: power-supply.yaml#
> +
> +properties:
> +  compatible:
> +    enum:
> +      - samsung,s2mu005-charger
> +
> +  port:
> +    $ref: /schemas/graph.yaml#/properties/port

That port is internal part of the device, thus should be dropped which
leaves you with only one property - monitored battery - and therefore
fold the node into the parent node.

Best regards,
Krzysztof


^ permalink raw reply

* Re: [PATCH v4 07/13] mfd: sec: set DMA coherent mask
From: Krzysztof Kozlowski @ 2026-04-15  7:19 UTC (permalink / raw)
  To: Kaustabh Chakraborty
  Cc: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, MyungJoo Ham, Chanwoo Choi, Sebastian Reichel,
	André Draszik, Alexandre Belloni, Jonathan Corbet,
	Shuah Khan, Nam Tran, Łukasz Lebiedziński, linux-leds,
	devicetree, linux-kernel, linux-pm, linux-samsung-soc, linux-rtc,
	linux-doc
In-Reply-To: <20260414-s2mu005-pmic-v4-7-7fe7480577e6@disroot.org>

On Tue, Apr 14, 2026 at 12:02:59PM +0530, Kaustabh Chakraborty wrote:
> Kernel logs are filled with "DMA mask not set" messages for every
> sub-device. The device does not use DMA for communication, so these
> messages are useless. Disable the coherent DMA mask for the PMIC device,
> which is also propagated to sub-devices.
> 
> Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
> ---
>  Documentation/devicetree/bindings/mfd/samsung,s2mps11.yaml | 3 +++
>  drivers/mfd/sec-common.c                                   | 3 +++
>  2 files changed, 6 insertions(+)
>

Please run scripts/checkpatch.pl on the patches and fix reported
warnings. After that, run also 'scripts/checkpatch.pl --strict' on the
patches and (probably) fix more warnings. Some warnings can be ignored,
especially from --strict run, but the code here looks like it needs a
fix. Feel free to get in touch if the warning is not clear.

Best regards,
Krzysztof


^ permalink raw reply

* Re: [RFC PATCH 0/2] Decouple ftrace/livepatch from module loader via notifier priority and reverse traversal
From: Christoph Hellwig @ 2026-04-15  7:38 UTC (permalink / raw)
  To: chensong_2000
  Cc: rafael, lenb, mturquette, sboyd, viresh.kumar, agk, snitzer,
	mpatocka, bmarzins, song, yukuai, linan122, jason.wessel, danielt,
	dianders, horms, davem, edumazet, kuba, pabeni, paulmck, frederic,
	mcgrof, petr.pavlu, da.gomez, samitolvanen, atomlin, jpoimboe,
	jikos, mbenes, pmladek, joe.lawrence, rostedt, mhiramat,
	mark.rutland, mathieu.desnoyers, linux-modules, linux-kernel,
	linux-trace-kernel, linux-acpi, linux-clk, linux-pm,
	live-patching, dm-devel, linux-raid, kgdb-bugreport, netdev
In-Reply-To: <20260413080140.180616-1-chensong_2000@189.cn>

On Mon, Apr 13, 2026 at 04:01:40PM +0800, chensong_2000@189.cn wrote:
> From: Song Chen <chensong_2000@189.cn>
> 
> This patchset addresses a long-standing tight coupling between the
> module loader and two of its key consumers: ftrace and livepatch.
> 
> Background:
> 
> The module loader currently hard-codes direct calls to
> ftrace_module_enable(), klp_module_coming(), klp_module_going() and
> ftrace_release_mod() inside prepare_coming_module() and the module
> unload path.

And that is bad why?

>  13 files changed, 290 insertions(+), 74 deletions(-)

This is a lot of new complex code touching a lot of places for no obvious
gain.  What is the reason for this series?  Does it prepare for something
else?


^ permalink raw reply

* Re: [RFC PATCH 1/2] kernel/notifier: replace single-linked list with double-linked list for reverse traversal
From: Christoph Hellwig @ 2026-04-15  7:40 UTC (permalink / raw)
  To: chensong_2000
  Cc: rafael, lenb, mturquette, sboyd, viresh.kumar, agk, snitzer,
	mpatocka, bmarzins, song, yukuai, linan122, jason.wessel, danielt,
	dianders, horms, davem, edumazet, kuba, pabeni, paulmck, frederic,
	mcgrof, petr.pavlu, da.gomez, samitolvanen, atomlin, jpoimboe,
	jikos, mbenes, pmladek, joe.lawrence, rostedt, mhiramat,
	mark.rutland, mathieu.desnoyers, linux-modules, linux-kernel,
	linux-trace-kernel, linux-acpi, linux-clk, linux-pm,
	live-patching, dm-devel, linux-raid, kgdb-bugreport, netdev
In-Reply-To: <20260415070137.17860-1-chensong_2000@189.cn>

On Wed, Apr 15, 2026 at 03:01:37PM +0800, chensong_2000@189.cn wrote:
> diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
> index 132a9df98471..b776dbd5a382 100644
> --- a/drivers/acpi/sleep.c
> +++ b/drivers/acpi/sleep.c
> @@ -56,7 +56,6 @@ static int tts_notify_reboot(struct notifier_block *this,
>  
>  static struct notifier_block tts_notifier = {
>  	.notifier_call	= tts_notify_reboot,
> -	.next		= NULL,
>  	.priority	= 0,

IFF this becomes important for some reason (and right now I don't see
it), please start by using proper wrappers for notifiers so that the
implementation details don't leak into the users.  That would actually
be useful on it's own even.


^ permalink raw reply

* [PATCH] PM: hibernate: align default resume swap with image-device checks
From: DaeMyung Kang @ 2026-04-15  8:12 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Len Brown, Pavel Machek, Youngjun Park, Andrew Morton, linux-pm,
	linux-kernel, DaeMyung Kang

snapshot_open(O_RDONLY) pins the configured default resume swap area for
hibernation image writes, but it does not fully propagate that choice to
the image-device checks used by the block layer.

In particular, snapshot_open() uses swsusp_resume_device without
swsusp_resume_block when pinning the default resume swap area, and it
leaves snapshot_state.dev unset even after the pin succeeds. As a
result, the default resume swap selected at open time is not kept
aligned with is_hibernate_resume_dev() and can still be rejected by the
block layer in blkdev_write_iter() with -ETXTBSY until user space
explicitly selects the same area via SNAPSHOT_SET_SWAP_AREA.

Use swsusp_resume_block when pinning the default resume swap area and
record the device immediately after a successful pin so that the
hibernation image-device bookkeeping matches the configured resume
area.  Also clear snapshot_state.dev on the open-time error path so it
never advertises a session that failed to fully open.

uswsusp itself is not affected because it always calls
SNAPSHOT_SET_SWAP_AREA right after open, which immediately overrides
snapshot_state.dev and re-pins the swap area.  The user-visible change
is for minimal hibernation user space that relies on resume= and
resume_offset= alone: such tools no longer have to restate the resume
area via SNAPSHOT_SET_SWAP_AREA just to satisfy blkdev_write_iter()'s
IS_SWAPFILE gate or to obtain SWP_HIBERNATION swapoff protection.  This
also matches the intent of the existing "The image device should be
accessible" comment in snapshot_open().  For the configured default
resume area, this gives snapshot_open() the same pin and
recorded-device state that SNAPSHOT_SET_SWAP_AREA would establish for
that same area, so user space relying on resume= and resume_offset=
does not need a follow-up SNAPSHOT_SET_SWAP_AREA just to satisfy the
IS_SWAPFILE gate and obtain swapoff protection.

Signed-off-by: DaeMyung Kang <charsyam@gmail.com>
---
Based on linux-next/master at commit e6efabc0afca ("Add linux-next
specific files for 20260414").

Tested in QEMU: with swap on a block device pointed to by
/sys/power/resume, opening /dev/snapshot O_RDONLY and then writing to
the swap block device returned -ETXTBSY before this change and -ENOSPC
(i.e. no longer rejected by the IS_SWAPFILE gate) after.

 kernel/power/user.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/kernel/power/user.c b/kernel/power/user.c
index d0fcfba7ac23..c51b8185de4b 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -69,9 +69,13 @@ static int snapshot_open(struct inode *inode, struct file *filp)
 	data = &snapshot_state;
 	filp->private_data = data;
 	memset(&data->handle, 0, sizeof(struct snapshot_handle));
+	data->dev = 0;
 	if ((filp->f_flags & O_ACCMODE) == O_RDONLY) {
 		/* Hibernating.  The image device should be accessible. */
-		data->swap = pin_hibernation_swap_type(swsusp_resume_device, 0);
+		data->swap = pin_hibernation_swap_type(swsusp_resume_device,
+						      swsusp_resume_block);
+		if (data->swap >= 0)
+			data->dev = swsusp_resume_device;
 		data->mode = O_RDONLY;
 		data->free_bitmaps = false;
 		error = pm_notifier_call_chain_robust(PM_HIBERNATION_PREPARE, PM_POST_HIBERNATION);
@@ -92,13 +96,13 @@ static int snapshot_open(struct inode *inode, struct file *filp)
 	}
 	if (error) {
 		unpin_hibernation_swap_type(data->swap);
+		data->dev = 0;
 		hibernate_release();
 	}
 
 	data->frozen = false;
 	data->ready = false;
 	data->platform_support = false;
-	data->dev = 0;
 
  Unlock:
 	unlock_system_sleep(sleep_flags);
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH v7 0/8] Add support for handling PCIe M.2 Key E connectors in devicetree
From: Chen-Yu Tsai @ 2026-04-15  8:31 UTC (permalink / raw)
  To: Andy Shevchenko, Manivannan Sadhasivam
  Cc: Manivannan Sadhasivam, Rob Herring, Greg Kroah-Hartman,
	Jiri Slaby, Nathan Chancellor, Nicolas Schier, Hans de Goede,
	Ilpo Järvinen, Mark Pearson, Derek J. Clark,
	Krzysztof Kozlowski, Conor Dooley, Marcel Holtmann,
	Luiz Augusto von Dentz, Bartosz Golaszewski, Bartosz Golaszewski,
	linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
	linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
	Stephan Gerhold, Dmitry Baryshkov, linux-acpi, Hans de Goede,
	Bartosz Golaszewski, Luca Ceresoli
In-Reply-To: <ad4tJN27opdEooA7@ashevche-desk.local>

On Tue, Apr 14, 2026 at 8:03 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
>
> On Tue, Apr 14, 2026 at 06:29:02PM +0800, Chen-Yu Tsai wrote:
> > On Tue, Apr 14, 2026 at 4:28 PM Andy Shevchenko
> > <andriy.shevchenko@linux.intel.com> wrote:
> > > On Tue, Apr 14, 2026 at 01:03:19PM +0800, Chen-Yu Tsai wrote:
> > > > On Tue, Apr 14, 2026 at 12:08 AM Manivannan Sadhasivam <mani@kernel.org> wrote:
> > > > > On Mon, Apr 13, 2026 at 07:33:12PM +0530, Manivannan Sadhasivam wrote:
> > > > > > On Mon, Apr 13, 2026 at 03:54:59PM +0800, Chen-Yu Tsai wrote:
> > > > > > > On Thu, Mar 26, 2026 at 01:36:28PM +0530, Manivannan Sadhasivam wrote:
>
> ...
>
> > > > > > > - Given that this connector actually represents two devices, how do I
> > > > > > >   say I want the BT part to be a wakeup source, but not the WiFi part?
> > > > > > >   Does wakeup-source even work at this point?
> > > > > >
> > > > > > You can't use the DT property since the devices are not described in DT
> > > > > > statically. But you can still use the per-device 'wakeup' sysfs knob to enable
> > > > > > wakeup.
> > > >
> > > > I see. I think not being able to specify generic properties for the devices
> > > > on the connector is going to be a bit problematic.
> > >
> > > This is nature of the open-connectors, especially on the busses that are
> > > hotpluggable, like PCIe. We never know what is connected there _ahead_.
> >
> > I believe what you mean by "hotpluggable" is "user replaceable".
>
> From the OS perspective it's the same. From platform perspective
> there is a difference, granted.

Yes. I just wanted to clarify.

> > > In other words you can't describe in DT something that may not exist.
> >
> > But this is actually doable with the PCIe slot representation. The
> > properties are put in the device node for the slot. If no card is
> > actually inserted in the slot, then no device is created, and the
> > device node is left as not associated with anything.
>
> But you need to list all devices in the world if you want to support this

Why would I need to? The PCIe slot representation just describes a
PCIe bridge. Granted this might not be entirely correct, but it's
what we currently have.

And even then, there are properties like memory-region or wakeup-source
that are generic and aren't tied to specific devices.

> somehow. Yes, probably many of them (or majority) will be enumerated as is,
> but some may need an assistance via (dynamic) properties or similar mechanisms.

Even if we wanted to add dynamic properties, there is currently no proper
device node to attach them to.

> > It's just that for this new M.2 E-key connector, there aren't separate
> > nodes for each interface. And the system doesn't associate the device
> > node with the device, because it's no longer a child node of the
> > controller or hierarchy, but connected over the OF graph.
> >
> > Moving over to the E-key connector representation seems like one step
> > forward and one step backward in descriptive ability. We gain proper
> > power sequencing, but lose generic properties.
>
> The "key" is property of the connector. Hence if you have an idea what can be
> common for ALL "key":s, that's probably can be abstracted. Note, I'm not
> familiar with the connector framework in the Linux kernel, perhaps it's already
> that kind of abstraction.

I'm not arguing for a even more generic "M.2" connector. The "key" is
already described in the compatible. I'm saying we should have some way
of describing the individual interfaces (PCIe, SDIO, USB, UART, I2S, I2C)
on the connector so further nodes or properties can be attached to them,
either with overlays or dynamically within the kernel. Right now the
are only described as individual ports, but we can't actually tie a
device to a OF graph port.

But maybe I'm overthinking the representation part. AFAICT for Qualcomm's
UART-based BT bit part, Mani just had the driver create a device node
under the UART (by traversing the OF graph to find the UART). If that's
the desired way then the connector binding should mention it. And that
works for me. But I think it's messier and also we're missing an
opportunity to make the M.2 connector a standardized attachment point
for overlays.

Mani, could you also chime in a bit on what you envisioned?

(Added Luca from Bootlin to CC, as I think there are parallels to the
 "Hotplug of Non-discoverable Hardware" work)


Thanks
ChenYu


> > The latter part is solvable, but we likely need child nodes under the
> > connector for the different interfaces. Properties that make sense for
> > one type might not make sense for another.
> >
> > P.S. We could also just add child device nodes under the controller to
> > put the generic properties, but that's splitting the description into
> > multiple parts. Let's not go there if at all possible.
>
> --
> With Best Regards,
> Andy Shevchenko
>
>

^ permalink raw reply

* Re: [PATCH v7 0/8] Add support for handling PCIe M.2 Key E connectors in devicetree
From: Andy Shevchenko @ 2026-04-15  9:07 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Manivannan Sadhasivam, Manivannan Sadhasivam, Rob Herring,
	Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor, Nicolas Schier,
	Hans de Goede, Ilpo Järvinen, Mark Pearson, Derek J. Clark,
	Krzysztof Kozlowski, Conor Dooley, Marcel Holtmann,
	Luiz Augusto von Dentz, Bartosz Golaszewski, Bartosz Golaszewski,
	linux-serial, linux-kernel, linux-kbuild, platform-driver-x86,
	linux-pci, devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
	Stephan Gerhold, Dmitry Baryshkov, linux-acpi, Hans de Goede,
	Bartosz Golaszewski, Luca Ceresoli
In-Reply-To: <CAGXv+5EPA29G-fsH=wWOD8AK6TZFezFhsE0NHPYj_Pt3nT+d_w@mail.gmail.com>

On Wed, Apr 15, 2026 at 04:31:24PM +0800, Chen-Yu Tsai wrote:
> On Tue, Apr 14, 2026 at 8:03 PM Andy Shevchenko
> <andriy.shevchenko@linux.intel.com> wrote:
> > On Tue, Apr 14, 2026 at 06:29:02PM +0800, Chen-Yu Tsai wrote:
> > > On Tue, Apr 14, 2026 at 4:28 PM Andy Shevchenko
> > > <andriy.shevchenko@linux.intel.com> wrote:
> > > > On Tue, Apr 14, 2026 at 01:03:19PM +0800, Chen-Yu Tsai wrote:
> > > > > On Tue, Apr 14, 2026 at 12:08 AM Manivannan Sadhasivam <mani@kernel.org> wrote:
> > > > > > On Mon, Apr 13, 2026 at 07:33:12PM +0530, Manivannan Sadhasivam wrote:
> > > > > > > On Mon, Apr 13, 2026 at 03:54:59PM +0800, Chen-Yu Tsai wrote:
> > > > > > > > On Thu, Mar 26, 2026 at 01:36:28PM +0530, Manivannan Sadhasivam wrote:

...

> > > > > > > > - Given that this connector actually represents two devices, how do I
> > > > > > > >   say I want the BT part to be a wakeup source, but not the WiFi part?
> > > > > > > >   Does wakeup-source even work at this point?
> > > > > > >
> > > > > > > You can't use the DT property since the devices are not described in DT
> > > > > > > statically. But you can still use the per-device 'wakeup' sysfs knob to enable
> > > > > > > wakeup.
> > > > >
> > > > > I see. I think not being able to specify generic properties for the devices
> > > > > on the connector is going to be a bit problematic.
> > > >
> > > > This is nature of the open-connectors, especially on the busses that are
> > > > hotpluggable, like PCIe. We never know what is connected there _ahead_.
> > >
> > > I believe what you mean by "hotpluggable" is "user replaceable".
> >
> > From the OS perspective it's the same. From platform perspective
> > there is a difference, granted.
> 
> Yes. I just wanted to clarify.
> 
> > > > In other words you can't describe in DT something that may not exist.
> > >
> > > But this is actually doable with the PCIe slot representation. The
> > > properties are put in the device node for the slot. If no card is
> > > actually inserted in the slot, then no device is created, and the
> > > device node is left as not associated with anything.
> >
> > But you need to list all devices in the world if you want to support this
> 
> Why would I need to? The PCIe slot representation just describes a
> PCIe bridge. Granted this might not be entirely correct, but it's
> what we currently have.
> 
> And even then, there are properties like memory-region or wakeup-source
> that are generic and aren't tied to specific devices.

Yes,  see below what I replied...

> > somehow. Yes, probably many of them (or majority) will be enumerated as is,

^^^ "the majority" will work without any assistance.

> > but some may need an assistance via (dynamic) properties or similar mechanisms.

> Even if we wanted to add dynamic properties, there is currently no proper
> device node to attach them to.

Isn't that's node created dynamically as well and attached to the PCI bus?

> > > It's just that for this new M.2 E-key connector, there aren't separate
> > > nodes for each interface. And the system doesn't associate the device
> > > node with the device, because it's no longer a child node of the
> > > controller or hierarchy, but connected over the OF graph.
> > >
> > > Moving over to the E-key connector representation seems like one step
> > > forward and one step backward in descriptive ability. We gain proper
> > > power sequencing, but lose generic properties.
> >
> > The "key" is property of the connector. Hence if you have an idea what can be
> > common for ALL "key":s, that's probably can be abstracted. Note, I'm not
> > familiar with the connector framework in the Linux kernel, perhaps it's already
> > that kind of abstraction.
> 
> I'm not arguing for a even more generic "M.2" connector. The "key" is
> already described in the compatible. I'm saying we should have some way
> of describing the individual interfaces (PCIe, SDIO, USB, UART, I2S, I2C)
> on the connector so further nodes or properties can be attached to them,
> either with overlays or dynamically within the kernel. Right now the
> are only described as individual ports, but we can't actually tie a
> device to a OF graph port.

Shouldn't it be described as a DT subtree? Sorry, I am not familiar with DT
enough to understand the issue you have.

> But maybe I'm overthinking the representation part. AFAICT for Qualcomm's
> UART-based BT bit part, Mani just had the driver create a device node
> under the UART (by traversing the OF graph to find the UART). If that's
> the desired way then the connector binding should mention it. And that
> works for me. But I think it's messier and also we're missing an
> opportunity to make the M.2 connector a standardized attachment point
> for overlays.

Okay, now it might get clearer to me, but still, I am not an expert.

> Mani, could you also chime in a bit on what you envisioned?

+1, please elaborate to me as well.

> (Added Luca from Bootlin to CC, as I think there are parallels to the
>  "Hotplug of Non-discoverable Hardware" work)
> 
> > > The latter part is solvable, but we likely need child nodes under the
> > > connector for the different interfaces. Properties that make sense for
> > > one type might not make sense for another.
> > >
> > > P.S. We could also just add child device nodes under the controller to
> > > put the generic properties, but that's splitting the description into
> > > multiple parts. Let's not go there if at all possible.

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply

* Re: [PATCH 3/3] arm64: dts: qcom: pm660: add thermal monitor
From: Konrad Dybcio @ 2026-04-15  9:15 UTC (permalink / raw)
  To: Richard Acayan
  Cc: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Konrad Dybcio, Amit Kucheria, Thara Gopinath,
	Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
	Stephen Boyd, Dmitry Baryshkov, linux-arm-msm, devicetree,
	linux-pm
In-Reply-To: <aaXKyIJQA9SFqt41@rdacayan>

On 3/3/26 3:25 AM, Richard Acayan wrote:
> On Tue, Feb 10, 2026 at 10:59:20AM +0100, Konrad Dybcio wrote:
>> On 2/10/26 3:18 AM, Richard Acayan wrote:
>>> The thermal monitor is used to monitor arbitrary ADC-based thermal
>>> sensors. It is suitable for use in thermal zones. Add support for it in
>>> PM660.
>>>
>>> Signed-off-by: Richard Acayan <mailingradian@gmail.com>
>>> ---
>>>  arch/arm64/boot/dts/qcom/pm660.dtsi | 10 ++++++++++
>>>  1 file changed, 10 insertions(+)
>>>
>>> diff --git a/arch/arm64/boot/dts/qcom/pm660.dtsi b/arch/arm64/boot/dts/qcom/pm660.dtsi
>>> index 156b2ddff0dc..7cedf6980b34 100644
>>> --- a/arch/arm64/boot/dts/qcom/pm660.dtsi
>>> +++ b/arch/arm64/boot/dts/qcom/pm660.dtsi
>>> @@ -197,6 +197,16 @@ channel@85 {
>>>  			};
>>>  		};
>>>  
>>> +		pm660_adc_tm: adc-tm@3400 {
>>> +			compatible = "qcom,spmi-adc-tm-hc";
>>> +			reg = <0x3400>;
>>> +			interrupts = <0x0 0x34 0x0 IRQ_TYPE_EDGE_RISING>;
>>> +			#thermal-sensor-cells = <1>;
>>> +			#address-cells = <1>;
>>> +			#size-cells = <0>;
>>> +			status = "disabled";
>>
>> Can we enable it by default?
> 
> This is for the ADC thermal monitor, and not the ADC itself. I don't see
> the need to allocate channels just so this can be enabled by default,
> since the thermal monitor's purpose is mostly to send interrupts when
> the ADC values go above or below a certain threshold.

Sorry, this fell through the cracks

I see your argument, but at the same time, there are channels that are
always present (e.g. VPH_PWR) and any way to reduce the boilerplate is
welcome

Konrad

^ permalink raw reply

* [PATCH v2 0/2] thermal/drivers/imx: two fixes
From: Felix Gu @ 2026-04-15 13:10 UTC (permalink / raw)
  To: Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
	Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	Oleksij Rempel
  Cc: linux-pm, imx, linux-arm-kernel, linux-kernel, Felix Gu

Signed-off-by: Felix Gu <ustc.gu@gmail.com>
---
Changes in v2:
- Switch to use devm_thermal_of_zone_register() to fix Frank and Daniel's comment.
- Collect Frank's Reviewed-by tag for patch 2.
- Link to v1: https://lore.kernel.org/r/20260412-imx-v1-0-cc3b45d63811@gmail.com

---
Felix Gu (2):
      thermal/drivers/imx: Fix thermal zone leak on probe error path
      thermal/drivers/imxl:Fix runtime PM handling on early returns

 drivers/thermal/imx_thermal.c | 49 ++++++++++++++++++++++---------------------
 1 file changed, 25 insertions(+), 24 deletions(-)
---
base-commit: 66672af7a095d89f082c5327f3b15bc2f93d558e
change-id: 20260411-imx-b022791ea1b9

Best regards,
-- 
Felix Gu <ustc.gu@gmail.com>


^ permalink raw reply

* [PATCH v2 1/2] thermal/drivers/imx: Fix thermal zone leak on probe error path
From: Felix Gu @ 2026-04-15 13:10 UTC (permalink / raw)
  To: Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
	Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	Oleksij Rempel
  Cc: linux-pm, imx, linux-arm-kernel, linux-kernel, Felix Gu
In-Reply-To: <20260415-imx-v2-0-aeacff9e72b2@gmail.com>

If pm_runtime_resume_and_get() fails after the thermal zone has been
registered, the probe error path cleans up runtime PM but skips
thermal_zone_device_unregister(), leaking the thermal zone device.

Switch to use devm_thermal_of_zone_register() to fix the problem.

Fixes: 4cf2ddf16e17 ("thermal/drivers/imx: Implement runtime PM support")
Signed-off-by: Felix Gu <ustc.gu@gmail.com>
---
 drivers/thermal/imx_thermal.c | 35 +++++++++++++++++++----------------
 1 file changed, 19 insertions(+), 16 deletions(-)

diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
index 38c993d1bcb3..3729c3eac748 100644
--- a/drivers/thermal/imx_thermal.c
+++ b/drivers/thermal/imx_thermal.c
@@ -216,6 +216,20 @@ struct imx_thermal_data {
 	const char *temp_grade;
 };
 
+static int imx_thermal_sync_zone_trip(struct thermal_trip *trip, void *arg)
+{
+	struct imx_thermal_data *data = arg;
+	int temp;
+
+	if (trip->type != THERMAL_TRIP_PASSIVE && trip->type != THERMAL_TRIP_CRITICAL)
+		return 0;
+
+	temp = trips[trip->type].temperature;
+	thermal_zone_set_trip_temp(data->tz, trip, temp);
+
+	return 0;
+}
+
 static void imx_set_panic_temp(struct imx_thermal_data *data,
 			       int panic_temp)
 {
@@ -679,13 +693,8 @@ static int imx_thermal_probe(struct platform_device *pdev)
 		goto legacy_cleanup;
 	}
 
-	data->tz = thermal_zone_device_register_with_trips("imx_thermal_zone",
-							   trips,
-							   ARRAY_SIZE(trips),
-							   data,
-							   &imx_tz_ops, NULL,
-							   IMX_PASSIVE_DELAY,
-							   IMX_POLLING_DELAY);
+	data->irq_enabled = true;
+	data->tz = devm_thermal_of_zone_register(dev, 0, data, &imx_tz_ops);
 	if (IS_ERR(data->tz)) {
 		ret = PTR_ERR(data->tz);
 		dev_err(dev, "failed to register thermal zone device %d\n",
@@ -693,6 +702,8 @@ static int imx_thermal_probe(struct platform_device *pdev)
 		goto clk_disable;
 	}
 
+	thermal_zone_for_each_trip(data->tz, imx_thermal_sync_zone_trip, data);
+
 	dev_info(dev, "%s CPU temperature grade - max:%dC"
 		 " critical:%dC passive:%dC\n", data->temp_grade,
 		 data->temp_max / 1000, trips[IMX_TRIP_CRITICAL].temperature / 1000,
@@ -724,25 +735,18 @@ static int imx_thermal_probe(struct platform_device *pdev)
 	if (ret < 0)
 		goto disable_runtime_pm;
 
-	data->irq_enabled = true;
-	ret = thermal_zone_device_enable(data->tz);
-	if (ret)
-		goto thermal_zone_unregister;
-
 	ret = devm_request_threaded_irq(dev, data->irq,
 			imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread,
 			0, "imx_thermal", data);
 	if (ret < 0) {
 		dev_err(dev, "failed to request alarm irq: %d\n", ret);
-		goto thermal_zone_unregister;
+		goto disable_runtime_pm;
 	}
 
 	pm_runtime_put(data->dev);
 
 	return 0;
 
-thermal_zone_unregister:
-	thermal_zone_device_unregister(data->tz);
 disable_runtime_pm:
 	pm_runtime_put_noidle(data->dev);
 	pm_runtime_disable(data->dev);
@@ -761,7 +765,6 @@ static void imx_thermal_remove(struct platform_device *pdev)
 	pm_runtime_put_noidle(data->dev);
 	pm_runtime_disable(data->dev);
 
-	thermal_zone_device_unregister(data->tz);
 	imx_thermal_unregister_legacy_cooling(data);
 }
 

-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 2/2] thermal/drivers/imxl:Fix runtime PM handling on early returns
From: Felix Gu @ 2026-04-15 13:10 UTC (permalink / raw)
  To: Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
	Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	Oleksij Rempel
  Cc: linux-pm, imx, linux-arm-kernel, linux-kernel, Felix Gu
In-Reply-To: <20260415-imx-v2-0-aeacff9e72b2@gmail.com>

Use PM_RUNTIME_ACQUIRE() in imx_get_temp() and imx_set_trip_temp() so
runtime PM references are released correctly even when the functions
return early on errors.

Fixes: 4cf2ddf16e17 ("thermal/drivers/imx: Implement runtime PM support")
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Felix Gu <ustc.gu@gmail.com>
---
 drivers/thermal/imx_thermal.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
index 3729c3eac748..057dbab70266 100644
--- a/drivers/thermal/imx_thermal.c
+++ b/drivers/thermal/imx_thermal.c
@@ -274,8 +274,9 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)
 	u32 val;
 	int ret;
 
-	ret = pm_runtime_resume_and_get(data->dev);
-	if (ret < 0)
+	PM_RUNTIME_ACQUIRE(data->dev, pm);
+	ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
+	if (ret)
 		return ret;
 
 	regmap_read(map, soc_data->temp_data, &val);
@@ -316,8 +317,6 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)
 		enable_irq(data->irq);
 	}
 
-	pm_runtime_put(data->dev);
-
 	return 0;
 }
 
@@ -351,8 +350,9 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz,
 	struct imx_thermal_data *data = thermal_zone_device_priv(tz);
 	int ret;
 
-	ret = pm_runtime_resume_and_get(data->dev);
-	if (ret < 0)
+	PM_RUNTIME_ACQUIRE(data->dev, pm);
+	ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
+	if (ret)
 		return ret;
 
 	/* do not allow passive to be set higher than critical */
@@ -362,8 +362,6 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz,
 	imx_set_alarm_temp(data, temp);
 	trips[IMX_TRIP_PASSIVE].temperature = temp;
 
-	pm_runtime_put(data->dev);
-
 	return 0;
 }
 

-- 
2.43.0


^ permalink raw reply related

* Re: The "clockevents: Prevent timer interrupt starvation" patch causes lockups
From: Eric Naim @ 2026-04-15 13:51 UTC (permalink / raw)
  To: Hanabishi, Thomas Gleixner
  Cc: Frederic Weisbecker, LKML, Calvin Owens, Peter Zijlstra,
	Anna-Maria Behnsen, Ingo Molnar, John Stultz, Stephen Boyd,
	Alexander Viro, Christian Brauner, Jan Kara, linux-fsdevel,
	Sebastian Reichel, linux-pm, Pablo Neira Ayuso, Florian Westphal,
	Phil Sutter, netfilter-devel, coreteam
In-Reply-To: <e6d3dc64-1714-4105-8a38-3942c62d159a@gmail.com>

On 4/15/26 5:35 AM, Hanabishi wrote:
> On 14/04/2026 20:55, Thomas Gleixner wrote:
>> The one below should cover all possible holes.
>>
>> Thanks,
>>
>>          tglx
>> ---
>> diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
>> index b4d730604972..5e22697b098d 100644
>> --- a/kernel/time/clockevents.c
>> +++ b/kernel/time/clockevents.c
>> @@ -94,6 +94,9 @@ static int __clockevents_switch_state(struct
>> clock_event_device *dev,
>>       if (dev->features & CLOCK_EVT_FEAT_DUMMY)
>>           return 0;
>>   +    /* On state transitions clear the forced flag unconditionally */
>> +    dev->next_event_forced = 0;
>> +
>>       /* Transition with new state-specific callbacks */
>>       switch (state) {
>>       case CLOCK_EVT_STATE_DETACHED:
>> @@ -366,8 +369,10 @@ int clockevents_program_event(struct clock_event_device
>> *dev, ktime_t expires, b
>>       if (delta > (int64_t)dev->min_delta_ns) {
>>           delta = min(delta, (int64_t) dev->max_delta_ns);
>>           cycles = ((u64)delta * dev->mult) >> dev->shift;
>> -        if (!dev->set_next_event((unsigned long) cycles, dev))
>> +        if (!dev->set_next_event((unsigned long) cycles, dev)) {
>> +            dev->next_event_forced = 0;
>>               return 0;
>> +        }
>>       }
>>         if (dev->next_event_forced)
>> diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
>> index 7e57fa31ee26..115e0bf01276 100644
>> --- a/kernel/time/tick-broadcast.c
>> +++ b/kernel/time/tick-broadcast.c
>> @@ -108,6 +108,7 @@ static struct clock_event_device
>> *tick_get_oneshot_wakeup_device(int cpu)
>>     static void tick_oneshot_wakeup_handler(struct clock_event_device *wd)
>>   {
>> +    wd->next_event_forced = 0;
>>       /*
>>        * If we woke up early and the tick was reprogrammed in the
>>        * meantime then this may be spurious but harmless.
> 
> Ok, it does fix the problem! Thank you.
> The patch itself does not apply cleanly for 7.0 though and I had to adapt it a
> bit.
> 

Sorry for the delay folks! This patch fixes the regression and a user recently
confirmed it as well.

Feel free to add:
Tested-by: Eric Naim <dnaim@cachyos.org>

-- 
Regards,
  Eric

^ permalink raw reply

* Re: [PATCH v4 04/13] dt-bindings: power: supply: document Samsung S2M series PMIC charger device
From: Kaustabh Chakraborty @ 2026-04-15 14:03 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Kaustabh Chakraborty
  Cc: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, MyungJoo Ham, Chanwoo Choi, Sebastian Reichel,
	André Draszik, Alexandre Belloni, Jonathan Corbet,
	Shuah Khan, Nam Tran, Łukasz Lebiedziński, linux-leds,
	devicetree, linux-kernel, linux-pm, linux-samsung-soc, linux-rtc,
	linux-doc
In-Reply-To: <20260415-swinging-radical-junglefowl-85dcf7@quoll>

On 2026-04-15 09:18 +02:00, Krzysztof Kozlowski wrote:
> On Tue, Apr 14, 2026 at 12:02:56PM +0530, Kaustabh Chakraborty wrote:
>> +description: |
>> +  The Samsung S2M series PMIC battery charger manages power interfacing
>> +  of the USB port. It may supply power, as done in USB OTG operation
>> +  mode, or it may accept power and redirect it to the battery fuelgauge
>> +  for charging.
>> +
>> +  This is a part of device tree bindings for S2M and S5M family of Power
>> +  Management IC (PMIC).
>> +
>> +  See also Documentation/devicetree/bindings/mfd/samsung,s2mps11.yaml for
>> +  additional information and example.
>> +
>> +allOf:
>> +  - $ref: power-supply.yaml#
>> +
>> +properties:
>> +  compatible:
>> +    enum:
>> +      - samsung,s2mu005-charger
>> +
>> +  port:
>> +    $ref: /schemas/graph.yaml#/properties/port
>
> That port is internal part of the device, thus should be dropped which
> leaves you with only one property - monitored battery - and therefore
> fold the node into the parent node.

And that monitored-battery belongs to power-supply.yaml. Do I then
include the allOf block in the mfd/samsung,s2mps11.yaml under the
s2mu005 compatible?

>
> Best regards,
> Krzysztof


^ permalink raw reply

* Re: [PATCH v4 05/13] dt-bindings: mfd: s2mps11: add documentation for S2MU005 PMIC
From: Kaustabh Chakraborty @ 2026-04-15 14:22 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Kaustabh Chakraborty
  Cc: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, MyungJoo Ham, Chanwoo Choi, Sebastian Reichel,
	André Draszik, Alexandre Belloni, Jonathan Corbet,
	Shuah Khan, Nam Tran, Łukasz Lebiedziński, linux-leds,
	devicetree, linux-kernel, linux-pm, linux-samsung-soc, linux-rtc,
	linux-doc
In-Reply-To: <20260415-notorious-dainty-starfish-58a13c@quoll>

On 2026-04-15 09:17 +02:00, Krzysztof Kozlowski wrote:
> On Tue, Apr 14, 2026 at 12:02:57PM +0530, Kaustabh Chakraborty wrote:
>>  
>>    clocks:
>>      $ref: /schemas/clock/samsung,s2mps11.yaml
>>      description:
>>        Child node describing clock provider.
>>  
>> +  charger:
>> +    $ref: /schemas/power/supply/samsung,s2mu005-charger.yaml
>> +    description:
>> +      Child node describing battery charger device.
>> +
>> +  extcon:
>
> You got comment to drop extcon naming. If this stays, it's muic for
> example.
>
>> +    $ref: /schemas/extcon/samsung,s2mu005-muic.yaml
>> +    description:
>> +      Child node describing extcon device.
>> +
>> +  flash:
>> +    $ref: /schemas/leds/samsung,s2mu005-flash.yaml
>> +    description:
>> +      Child node describing flash LEDs.
>> +
>
> Please make it a separate binding file.

What do you mean by that?

>
>>    interrupts:
>>      maxItems: 1
>>  
>> @@ -43,6 +59,11 @@ properties:
>>      description:
>>        List of child nodes that specify the regulators.
>>  
>> +  rgb:
>
> led

Well flash ones are also LEDs. Would you rather have `flash { ... }` and
`rgb { ... }` under `led { ... }` instead?

>
>> +    $ref: /schemas/leds/samsung,s2mu005-rgb.yaml
>> +    description:
>> +      Child node describing RGB LEDs.
>> +

^ permalink raw reply

* Re: [PATCH v4 05/13] dt-bindings: mfd: s2mps11: add documentation for S2MU005 PMIC
From: Krzysztof Kozlowski @ 2026-04-15 14:27 UTC (permalink / raw)
  To: Kaustabh Chakraborty
  Cc: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, MyungJoo Ham, Chanwoo Choi, Sebastian Reichel,
	André Draszik, Alexandre Belloni, Jonathan Corbet,
	Shuah Khan, Nam Tran, Łukasz Lebiedziński, linux-leds,
	devicetree, linux-kernel, linux-pm, linux-samsung-soc, linux-rtc,
	linux-doc
In-Reply-To: <DHTSO9L6YZTQ.WYM9ERXBGNGB@disroot.org>

On 15/04/2026 16:22, Kaustabh Chakraborty wrote:
> On 2026-04-15 09:17 +02:00, Krzysztof Kozlowski wrote:
>> On Tue, Apr 14, 2026 at 12:02:57PM +0530, Kaustabh Chakraborty wrote:
>>>  
>>>    clocks:
>>>      $ref: /schemas/clock/samsung,s2mps11.yaml
>>>      description:
>>>        Child node describing clock provider.
>>>  
>>> +  charger:
>>> +    $ref: /schemas/power/supply/samsung,s2mu005-charger.yaml
>>> +    description:
>>> +      Child node describing battery charger device.
>>> +
>>> +  extcon:
>>
>> You got comment to drop extcon naming. If this stays, it's muic for
>> example.
>>
>>> +    $ref: /schemas/extcon/samsung,s2mu005-muic.yaml
>>> +    description:
>>> +      Child node describing extcon device.
>>> +
>>> +  flash:
>>> +    $ref: /schemas/leds/samsung,s2mu005-flash.yaml
>>> +    description:
>>> +      Child node describing flash LEDs.
>>> +
>>
>> Please make it a separate binding file.
> 
> What do you mean by that?

I mean, S2MU005 should go to its own file.

> 
>>
>>>    interrupts:
>>>      maxItems: 1
>>>  
>>> @@ -43,6 +59,11 @@ properties:
>>>      description:
>>>        List of child nodes that specify the regulators.
>>>  
>>> +  rgb:
>>
>> led
> 
> Well flash ones are also LEDs. Would you rather have `flash { ... }` and
> `rgb { ... }` under `led { ... }` instead?

There is no approved name "rgb" for LEDs. What is the name for flash LEDs?

Best regards,
Krzysztof

^ permalink raw reply

* Re: [PATCH v4 04/13] dt-bindings: power: supply: document Samsung S2M series PMIC charger device
From: Krzysztof Kozlowski @ 2026-04-15 14:39 UTC (permalink / raw)
  To: Kaustabh Chakraborty
  Cc: Lee Jones, Pavel Machek, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, MyungJoo Ham, Chanwoo Choi, Sebastian Reichel,
	André Draszik, Alexandre Belloni, Jonathan Corbet,
	Shuah Khan, Nam Tran, Łukasz Lebiedziński, linux-leds,
	devicetree, linux-kernel, linux-pm, linux-samsung-soc, linux-rtc,
	linux-doc
In-Reply-To: <DHTS9H2EIM2D.2TC17F9WBOOR1@disroot.org>

On 15/04/2026 16:03, Kaustabh Chakraborty wrote:
> On 2026-04-15 09:18 +02:00, Krzysztof Kozlowski wrote:
>> On Tue, Apr 14, 2026 at 12:02:56PM +0530, Kaustabh Chakraborty wrote:
>>> +description: |
>>> +  The Samsung S2M series PMIC battery charger manages power interfacing
>>> +  of the USB port. It may supply power, as done in USB OTG operation
>>> +  mode, or it may accept power and redirect it to the battery fuelgauge
>>> +  for charging.
>>> +
>>> +  This is a part of device tree bindings for S2M and S5M family of Power
>>> +  Management IC (PMIC).
>>> +
>>> +  See also Documentation/devicetree/bindings/mfd/samsung,s2mps11.yaml for
>>> +  additional information and example.
>>> +
>>> +allOf:
>>> +  - $ref: power-supply.yaml#
>>> +
>>> +properties:
>>> +  compatible:
>>> +    enum:
>>> +      - samsung,s2mu005-charger
>>> +
>>> +  port:
>>> +    $ref: /schemas/graph.yaml#/properties/port
>>
>> That port is internal part of the device, thus should be dropped which
>> leaves you with only one property - monitored battery - and therefore
>> fold the node into the parent node.
> 
> And that monitored-battery belongs to power-supply.yaml. Do I then
> include the allOf block in the mfd/samsung,s2mps11.yaml under the
> s2mu005 compatible?

allOf does not go under the compatible. The entire device schema should
have $ref to power-supply.yaml, just like many other devices have that
or different $ref.

Best regards,
Krzysztof

^ permalink raw reply

* Re: [PATCH v7 0/8] Add support for handling PCIe M.2 Key E connectors in devicetree
From: Herve Codina @ 2026-04-15 14:56 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Andy Shevchenko, Manivannan Sadhasivam, Manivannan Sadhasivam,
	Rob Herring, Greg Kroah-Hartman, Jiri Slaby, Nathan Chancellor,
	Nicolas Schier, Hans de Goede, Ilpo Järvinen, Mark Pearson,
	Derek J. Clark, Krzysztof Kozlowski, Conor Dooley,
	Marcel Holtmann, Luiz Augusto von Dentz, Bartosz Golaszewski,
	Bartosz Golaszewski, linux-serial, linux-kernel, linux-kbuild,
	platform-driver-x86, linux-pci, devicetree, linux-arm-msm,
	linux-bluetooth, linux-pm, Stephan Gerhold, Dmitry Baryshkov,
	linux-acpi, Hans de Goede, Bartosz Golaszewski, Luca Ceresoli
In-Reply-To: <CAGXv+5EPA29G-fsH=wWOD8AK6TZFezFhsE0NHPYj_Pt3nT+d_w@mail.gmail.com>

Hi Chen, all,

...
 
> 
> I'm not arguing for a even more generic "M.2" connector. The "key" is
> already described in the compatible. I'm saying we should have some way
> of describing the individual interfaces (PCIe, SDIO, USB, UART, I2S, I2C)
> on the connector so further nodes or properties can be attached to them,
> either with overlays or dynamically within the kernel. Right now the
> are only described as individual ports, but we can't actually tie a
> device to a OF graph port.
> 
> But maybe I'm overthinking the representation part. AFAICT for Qualcomm's
> UART-based BT bit part, Mani just had the driver create a device node
> under the UART (by traversing the OF graph to find the UART). If that's
> the desired way then the connector binding should mention it. And that
> works for me. But I think it's messier and also we're missing an
> opportunity to make the M.2 connector a standardized attachment point
> for overlays.
> 
> Mani, could you also chime in a bit on what you envisioned?
> 
> (Added Luca from Bootlin to CC, as I think there are parallels to the
>  "Hotplug of Non-discoverable Hardware" work)
>

Related to "Hotplug of Non-discoverable Hardware",

I would add entries for busses in the connector without using an OF graph.

For I2C and later SPI, this was is done.

You already have an i2c-parent property but no node where an i2c device
can be added.

The last discussion related to hotplug, connectors and DT led to the RFC
series [1].

It is a huge series. The last patch give a real example of representation:
  https://lore.kernel.org/all/20260112142009.1006236-78-herve.codina@bootlin.com/

In your case I would see some thing like:

    connector {
        compatible = "pcie-m2-e-connector";
        vpcie3v3-supply = <&vreg_wcn_3p3>;
        vpcie1v8-supply = <&vreg_l15b_1p8>;

	/*
	 * If those GPIOs have to be used by components available in
	 * the connected board, a Nexus node should be used.
         */
        w-disable1-gpios = <&tlmm 115 GPIO_ACTIVE_LOW>;
        w-disable2-gpios = <&tlmm 116 GPIO_ACTIVE_LOW>;
        viocfg-gpios = <&tlmm 117 GPIO_ACTIVE_HIGH>;
        uart-wake-gpios = <&tlmm 118 GPIO_ACTIVE_LOW>;
        sdio-wake-gpios = <&tlmm 119 GPIO_ACTIVE_LOW>;
        sdio-reset-gpios = <&tlmm 120 GPIO_ACTIVE_LOW>;

	conn-i2c {
		i2c-parent = <&i2c0>;

		/*
 		 * Here i2c devices available on the board
		 * connected to the connector can be described.
		 */
	};

	/* Same kind to description for other busses */
	conn-pcie {
		pci-parent = <&xxxxx>;

		/*
		 * The PCIe bus has abilities to discover devices.
		 * Not sure this node is needed.
		 *
		 * If a PCI device need a DT description to describe
		 * stuffs behind the device, what has been done for LAN966x
		 * could be re-used [2] and [3]
		 */
	};

	conn_uart {
		uart-parent = <&uart-ctrl>;

		/* uart child (maybe a serdes) should be describe here
	};

	...
    };

Of course, some DT symbols need to be exported in order to have them usable from
the DT describing the connected board.

This notion of exported symbol is not yet available upstream and is the purpose of
the RFC series [1].

[1] https://lore.kernel.org/all/20260112142009.1006236-1-herve.codina@bootlin.com/
[2] https://elixir.bootlin.com/linux/v7.0/source/drivers/misc/lan966x_pci.c
[3] https://elixir.bootlin.com/linux/v7.0/source/drivers/misc/lan966x_pci.dtso

Feel free to ask for more specific question if needed.

Best regards,
Hervé

> 
> Thanks
> ChenYu
> 
> 
> > > The latter part is solvable, but we likely need child nodes under the
> > > connector for the different interfaces. Properties that make sense for
> > > one type might not make sense for another.
> > >
> > > P.S. We could also just add child device nodes under the controller to
> > > put the generic properties, but that's splitting the description into
> > > multiple parts. Let's not go there if at all possible.  
> >
> > --
> > With Best Regards,
> > Andy Shevchenko
> >
> >  



-- 
Hervé Codina, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply

* [PATCH] thermal/drivers/sprd: Use for_each_child_of_node_scoped() in probe
From: Felix Gu @ 2026-04-15 15:07 UTC (permalink / raw)
  To: Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
	Orson Zhai, Baolin Wang, Chunyan Zhang
  Cc: linux-pm, linux-kernel, Felix Gu

Use for_each_child_of_node_scoped() to avoid manual cleanup
of_node_put() in early exits from the loop, simplify the code.

Signed-off-by: Felix Gu <ustc.gu@gmail.com>
---
 drivers/thermal/sprd_thermal.c | 25 ++++++++-----------------
 1 file changed, 8 insertions(+), 17 deletions(-)

diff --git a/drivers/thermal/sprd_thermal.c b/drivers/thermal/sprd_thermal.c
index d683fcb0f8ab..069bc13ffc57 100644
--- a/drivers/thermal/sprd_thermal.c
+++ b/drivers/thermal/sprd_thermal.c
@@ -331,7 +331,6 @@ static void sprd_thm_toggle_sensor(struct sprd_thermal_sensor *sen, bool on)
 static int sprd_thm_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
-	struct device_node *sen_child;
 	struct sprd_thermal_data *thm;
 	struct sprd_thermal_sensor *sen;
 	const struct sprd_thm_variant_data *pdata;
@@ -380,12 +379,10 @@ static int sprd_thm_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	for_each_child_of_node(np, sen_child) {
+	for_each_child_of_node_scoped(np, sen_child) {
 		sen = devm_kzalloc(&pdev->dev, sizeof(*sen), GFP_KERNEL);
-		if (!sen) {
-			ret = -ENOMEM;
-			goto of_put;
-		}
+		if (!sen)
+			return -ENOMEM;
 
 		sen->data = thm;
 		sen->dev = &pdev->dev;
@@ -393,13 +390,13 @@ static int sprd_thm_probe(struct platform_device *pdev)
 		ret = of_property_read_u32(sen_child, "reg", &sen->id);
 		if (ret) {
 			dev_err(&pdev->dev, "get sensor reg failed");
-			goto of_put;
+			return ret;
 		}
 
 		ret = sprd_thm_sensor_calibration(sen_child, thm, sen);
 		if (ret) {
 			dev_err(&pdev->dev, "efuse cal analysis failed");
-			goto of_put;
+			return ret;
 		}
 
 		sprd_thm_sensor_init(thm, sen);
@@ -411,31 +408,25 @@ static int sprd_thm_probe(struct platform_device *pdev)
 		if (IS_ERR(sen->tzd)) {
 			dev_err(&pdev->dev, "register thermal zone failed %d\n",
 				sen->id);
-			ret = PTR_ERR(sen->tzd);
-			goto of_put;
+			return PTR_ERR(sen->tzd);
 		}
 
 		thm->sensor[sen->id] = sen;
 	}
-	/* sen_child set to NULL at this point */
 
 	ret = sprd_thm_set_ready(thm);
 	if (ret)
-		goto of_put;
+		return ret;
 
 	ret = sprd_thm_wait_temp_ready(thm);
 	if (ret)
-		goto of_put;
+		return ret;
 
 	for (i = 0; i < thm->nr_sensors; i++)
 		sprd_thm_toggle_sensor(thm->sensor[i], true);
 
 	platform_set_drvdata(pdev, thm);
 	return 0;
-
-of_put:
-	of_node_put(sen_child);
-	return ret;
 }
 
 #ifdef CONFIG_PM_SLEEP

---
base-commit: 936c21068d7ade00325e40d82bfd2f3f29d9f659
change-id: 20260415-sprd-3034c3aa9649

Best regards,
-- 
Felix Gu <ustc.gu@gmail.com>


^ 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