mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Lee Jones <lee@kernel.org>
To: Pavel Skripkin <paskripkin@gmail.com>
Cc: ejona86@gmail.com, mfd@lists.linux.dev, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] mfd/rk8xx: fix sleep during RCU read side critical section
Date: Mon, 2 Nov 2026 10:13:01 +0000	[thread overview]
Message-ID: <20261102101301.GC13023@google.com> (raw)
In-Reply-To: <20261029192223.462367-1-paskripkin@gmail.com>

Nit for when you resubmit this.

The subject line does not match the expected format for the subsystem.

<end>

On Thu, 29 Oct 2026, Pavel Skripkin wrote:

> SPI does not support atomic transfers, so it's dangerous to call from
> atomic notif chains, since it can cause stall during reboot on
> orangepi5 (see trace below).
> 
> Commit 128115b520c6 ("mfd: rk8xx: Register poweroff handler in atomic phase")
> moved shutdown methods to atomic notif chain, since i2c transfer didn't
> work during PREPARE step. I don't have an access to rk3288 based boards and
> patch reasoning is not completely clear.
> 
> That's why this patch hacks notifier registration only for SPI based
> PMICs.
> 
> 66.145226] reboot: Power down
> [  266.145581] ------------[ cut here ]------------
> [  266.145986] Voluntary context switch within RCU read-side critical section!
> [  266.146007] WARNING: kernel/rcu/tree_plugin.h:330 at rcu_note_context_switch+0x3dc/0x5d8, CPU#0: systemd-shutdow/1
> [  266.147525] Modules linked in:
> [  266.147800] CPU: 0 UID: 0 PID: 1 Comm: systemd-shutdow Not tainted 7.3.0-opi5-test+ #2 PREEMPT
> [  266.148560] Hardware name: Xunlong Orange Pi 5 (DT)
> [  266.148987] pstate: 604000c9 (nZCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> [  266.149596] pc : rcu_note_context_switch+0x3dc/0x5d8
> [  266.150034] lr : rcu_note_context_switch+0x3dc/0x5d8
> [  266.150472] sp : ffff80008005b4e0
> [  266.150764] x29: ffff80008005b4e0 x28: ffff000100903000 x27: ffffc7018d616000
> [  266.151393] x26: 0000c4fe4deb68c0 x25: ffffc7018d639260 x24: 0000000000000000
> [  266.152021] x23: ffff000100903000 x22: ffff0002fee4ef80 x21: ffffc7018d616f80
> [  266.152649] x20: 0000000000000000 x19: ffff000100903000 x18: 0000000000000000
> [  266.153277] x17: ffff80008005b8b8 x16: 0000000000000000 x15: 0000000000000000
> [  266.153904] x14: 0000000000000a37 x13: ffffc7018d82a478 x12: ffff390171838000
> [  266.154532] x11: ffff0002fee3a198 x10: 0000000000000001 x9 : ffffc7018d6642d0
> [  266.155161] x8 : 0000000100000001 x7 : 0000000000000000 x6 : 7261746e756c6f56
> [  266.155789] x5 : ffffc7018d93e807 x4 : ffffc7018cd48369 x3 : ffff80008005b058
> [  266.156416] x2 : 00000000000002a8 x1 : 0000000000000001 x0 : 000000000000003f
> [  266.157044] Call trace:
> [  266.157262]  rcu_note_context_switch+0x3dc/0x5d8 (P)
> [  266.157703]  __schedule+0x80/0x1540
> [  266.158015]  schedule+0x5c/0xe0
> [  266.158296]  schedule_timeout+0x7c/0xe8
> [  266.158636]  wait_for_common+0xbc/0x188
> [  266.158977]  wait_for_completion_timeout+0x1c/0x30
> [  266.159401]  spi_transfer_one_message+0x2c0/0x838
> [  266.159819]  __spi_pump_transfer_message+0x1f0/0x448
> [  266.160258]  __spi_sync+0x224/0x450
> [  266.160569]  spi_write_then_read+0x134/0x1b8
> [  266.160947]  rk806_spi_bus_read+0x4c/0x70
> [  266.161304]  _regmap_raw_read+0x1a0/0x368
> [  266.161661]  _regmap_bus_read+0x48/0x88
> [  266.162001]  _regmap_read+0x17c/0x260
> [  266.162326]  _regmap_update_bits+0x7c/0x138
> [  266.162696]  regmap_update_bits_base+0x6c/0xa8
> [  266.163089]  rk808_power_off+0xec/0x120
> [  266.163429]  sys_off_notify+0x34/0x50
> [  266.163756]  atomic_notifier_call_chain+0x78/0x170
> [  266.164178]  do_kernel_power_off+0xf0/0x170
> [  266.164549]  machine_power_off+0x20/0x38
> [  266.164900]  kernel_power_off+0xf4/0x110
> [  266.165248]  __arm64_sys_reboot+0x27c/0x290
> [  266.165619]  invoke_syscall+0x4c/0xf8
> [  266.165944]  el0_svc_common+0x94/0xe8
> [  266.166268]  do_el0_svc+0x24/0x38
> [  266.166562]  el0_svc+0x34/0x90
> [  266.166833]  el0t_64_sync_handler+0x68/0xe0
> [  266.167203]  el0t_64_sync+0x17c/0x180
> [  266.167528] ---[ end trace 0000000000000000 ]---
> 
> CC: Eric Anderson <ejona86@gmail.com>
> Fixes: 128115b520c6 ("mfd: rk8xx: Register poweroff handler in atomic phase")
> Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
> ---
> 
> Hey Eric!
> 
> I don't have rk3288 board to test. However, I strongly suspect that
> patch does not affect your case.
> 
> I've tried to track down root cause of i2c hung, but no luck. Based on
> FDT i2c is directly connected to GIC, so IRQs must be enabled during
> PREPARE step.
> 
> Would be great if you test that patch.
> 
> ---
>  drivers/mfd/rk8xx-core.c  | 19 ++++++++++++++++---
>  drivers/mfd/rk8xx-i2c.c   |  2 +-
>  drivers/mfd/rk8xx-spi.c   |  2 +-
>  include/linux/mfd/rk808.h |  2 +-
>  4 files changed, 19 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mfd/rk8xx-core.c b/drivers/mfd/rk8xx-core.c
> index 21182df45d1b..c4c5907c9fcd 100644
> --- a/drivers/mfd/rk8xx-core.c
> +++ b/drivers/mfd/rk8xx-core.c
> @@ -761,7 +761,7 @@ void rk8xx_shutdown(struct device *dev)
>  }
>  EXPORT_SYMBOL_GPL(rk8xx_shutdown);
>  
> -int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap *regmap)
> +int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap *regmap, bool spi)
>  {
>  	struct rk808 *rk808;
>  	const struct rk808_reg_data *pre_init_reg;
> @@ -874,8 +874,21 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
>  
>  	if (device_property_read_bool(dev, "system-power-controller") ||
>  	    device_property_read_bool(dev, "rockchip,system-power-controller")) {
> +		/* There is no support for atomic SPI transfers (yet?). Thus it's not possible to
> +		 * perform SPI i/o during atomic notify handler.
> +		 *
> +		 * Patch 128115b520c6 claims that i2c does not work during _PREPARE state, so be
> +		 * extra careful while changing modes here.
> +		 */
> +		enum sys_off_mode off_mode =
> +			spi ? SYS_OFF_MODE_POWER_OFF_PREPARE :
> +			      SYS_OFF_MODE_POWER_OFF;
> +		enum sys_off_mode restart_mode =
> +			spi ? SYS_OFF_MODE_RESTART_PREPARE :
> +			      SYS_OFF_MODE_RESTART;
> +
>  		ret = devm_register_sys_off_handler(dev,
> -				    SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_HIGH,
> +				    off_mode, SYS_OFF_PRIO_HIGH,
>  				    &rk808_power_off, rk808);
>  		if (ret)
>  			return dev_err_probe(dev, ret,
> @@ -885,7 +898,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
>  		case RK809_ID:
>  		case RK817_ID:
>  			ret = devm_register_sys_off_handler(dev,
> -							    SYS_OFF_MODE_RESTART, SYS_OFF_PRIO_HIGH,
> +							    restart_mode, SYS_OFF_PRIO_HIGH,
>  							    &rk808_restart, rk808);
>  			if (ret)
>  				dev_warn(dev, "failed to register rst handler, %d\n", ret);
> diff --git a/drivers/mfd/rk8xx-i2c.c b/drivers/mfd/rk8xx-i2c.c
> index 161b25fbe146..f6e137ba394f 100644
> --- a/drivers/mfd/rk8xx-i2c.c
> +++ b/drivers/mfd/rk8xx-i2c.c
> @@ -243,7 +243,7 @@ static int rk8xx_i2c_probe(struct i2c_client *client)
>  		return dev_err_probe(&client->dev, PTR_ERR(regmap),
>  				     "regmap initialization failed\n");
>  
> -	return rk8xx_probe(&client->dev, data->variant, client->irq, regmap);
> +	return rk8xx_probe(&client->dev, data->variant, client->irq, regmap, false);
>  }
>  
>  static void rk8xx_i2c_shutdown(struct i2c_client *client)
> diff --git a/drivers/mfd/rk8xx-spi.c b/drivers/mfd/rk8xx-spi.c
> index bb85fe60518f..fba4b0582c8b 100644
> --- a/drivers/mfd/rk8xx-spi.c
> +++ b/drivers/mfd/rk8xx-spi.c
> @@ -94,7 +94,7 @@ static int rk8xx_spi_probe(struct spi_device *spi)
>  		return dev_err_probe(&spi->dev, PTR_ERR(regmap),
>  				     "Failed to init regmap\n");
>  
> -	return rk8xx_probe(&spi->dev, RK806_ID, spi->irq, regmap);
> +	return rk8xx_probe(&spi->dev, RK806_ID, spi->irq, regmap, true);
>  }
>  
>  static const struct of_device_id rk8xx_spi_of_match[] = {
> diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
> index 7ffc904c864c..c55aa2effd18 100644
> --- a/include/linux/mfd/rk808.h
> +++ b/include/linux/mfd/rk808.h
> @@ -1469,7 +1469,7 @@ struct rk808 {
>  };
>  
>  void rk8xx_shutdown(struct device *dev);
> -int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap *regmap);
> +int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap *regmap, bool spi);
>  int rk8xx_suspend(struct device *dev);
>  int rk8xx_resume(struct device *dev);
>  
> -- 
> 2.55.0
> 

-- 
Lee Jones

      parent reply	other threads:[~2026-11-02 10:13 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-29 19:22 Pavel Skripkin
2026-10-30  4:28 ` Eric Anderson
2026-10-30 14:44   ` Pavel Skripkin
2026-10-30 19:14     ` Eric Anderson
2026-11-02 10:13 ` Lee Jones [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261102101301.GC13023@google.com \
    --to=lee@kernel.org \
    --cc=ejona86@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mfd@lists.linux.dev \
    --cc=paskripkin@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®