Skip to contentSkip to conversation

i2c: spacemit: Avoid sleeping during bus reset in atomic context

PATCH In review Anand Moon 4 participants 11 messages Nov 10 – Nov 11

Subsystems (5)
lore
Share & tools
lore

Anand Moon

author
#0 lore raw

PATCH 1/2 i2c: spacemit: Avoid sleeping during bus reset in atomic context

The spacemit_i2c_conditionally_reset_bus() function uses usleep_range() to wait after triggering a bus reset request. However, this function can be invoked during atomic I2C transfers (such as power-off or restart handlers running in atomic notifier chains), where sleeping is illegal.

Replace the sleep operation with the driver's internal helper, spacemit_i2c_delay(), which conditionally uses udelay() when running in an atomic context, avoiding "scheduling while atomic" bugs.

Assisted-by LLM
Cc Troy Mitchell <[email protected]>
Cc Alex Elder <[email protected]>
---
 drivers/i2c/busses/i2c-k1.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i2c/busses/i2c-k1.c +1 -1
index ff32876e24d3..f4b21d7efaaf 100644
@@ -332,7 +332,7 @@ static void spacemit_i2c_conditionally_reset_bus(struct spacemit_i2c_dev *i2c)
 		writel(FIELD_PREP(SPACEMIT_RCR_FIELD_RST_CYC, 1),
 		       i2c->base + SPACEMIT_IRCR);
 		writel(SPACEMIT_CR_RSTREQ, i2c->base + SPACEMIT_ICR);
-		usleep_range(20, 30);
+		spacemit_i2c_delay(i2c, 20);
 	}
 
 	/* check sda again here */

base-commit: b3dfbde62cf1981c4638939c159dfd087b7a72e9

Signature · 1 line
2.56.0
author
#1 lore raw

PATCH 2/2 power: reset: spacemit-p1: Use atomic I2C transfers for power-off and restart

The SpacemiT P1 power-off and restart handlers use regmap_set_bits() to access the PMIC. However, these handlers run in an atomic notifier context (specifically within an rcu_read_lock() critical section), while the I2C-backed regmap uses a sleepable mutex.

This triggers a "WARNING: suspicious RCU usage" warning due to an illegal context switch in the RCU read-side critical section during shutdown on the Banana Pi BPI-F3:

[  563.803475] WARNING: suspicious RCU usage
[  563.807813] 7.3.1-ARCH-RISC-V #1 Not tainted
[  563.816614] ./include/linux/rcupdate.h:387 Illegal context switch in RCU read-side critical section!
...
[  563.841445] locks held by shutdown/1: 2, last CPU#0:
[  563.846694]  #0: ffffffff8404fb20 (system_transition_mutex){+.+.}-{4:4}, at: __do_sys_reboot+0x230/0x29e
[  563.856806]  #1: ffffffff84167860 (rcu_read_lock){....}-{1:3}, at: atomic_notifier_call_chain+0x4a/0x1c2

Replace the regmap operations with atomic I2C transfers to avoid sleeping in an atomic context. Preserve unrelated register bits through read-modify-write operations and check for atomic I2C support before registering the handlers.

Obtain the I2C client from the parent device and verify that the adapter supports atomic transfers before registering the handlers.

Tested on the Banana Pi BPI-F3 (SpacemiT K1).

Assisted-by LLM
Cc Troy Mitchell <[email protected]>
Cc Aurelien Jarno <[email protected]>
Fixes 28124cc0fb8c ("driver: reset: spacemit-p1: add driver for poweroff/reboot")
---
 drivers/power/reset/spacemit-p1-reboot.c | 86 ++++++++++++++++++++----
 1 file changed, 74 insertions(+), 12 deletions(-)
drivers/power/reset/spacemit-p1-reboot.c +74 -12
index c0454b547718..8fcb3eadddf3 100644
@@ -4,8 +4,9 @@
  */
 
 #include <linux/bits.h>
+#include <linux/errno.h>
+#include <linux/i2c.h>
 #include <linux/platform_device.h>
-#include <linux/regmap.h>
 #include <linux/reboot.h>
 
 /* Power Control Register 2 */
@@ -13,13 +14,68 @@
 #define PWR_CTRL2_SHUTDOWN	BIT(2)	/* Shutdown request */
 #define PWR_CTRL2_RST		BIT(1)	/* Reset request */
 
+static int spacemit_p1_read_atomic(struct i2c_client *client,
+				   u8 reg, u8 *val)
+{
+	struct i2c_msg msgs[] = {
+		{
+			.addr = client->addr,
+			.flags = client->flags & I2C_M_TEN,
+			.len = 1,
+			.buf = &reg,
+		},
+		{
+			.addr = client->addr,
+			.flags = (client->flags & I2C_M_TEN) | I2C_M_RD,
+			.len = 1,
+			.buf = val,
+		},
+	};
+	int ret;
+
+	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+
+	return ret == ARRAY_SIZE(msgs) ? 0 : ret < 0 ? ret : -EIO;
+}
+
+static int spacemit_p1_write_atomic(struct i2c_client *client,
+				    u8 reg, u8 val)
+{
+	u8 buf[] = { reg, val };
+	struct i2c_msg msg = {
+		.addr = client->addr,
+		.flags = client->flags & I2C_M_TEN,
+		.len = sizeof(buf),
+		.buf = buf,
+	};
+	int ret;
+
+	ret = i2c_transfer(client->adapter, &msg, 1);
+
+	return ret == 1 ? 0 : ret < 0 ? ret : -EIO;
+}
+
+static int spacemit_p1_update_bits_atomic(struct i2c_client *client,
+					  u8 reg, u8 mask)
+{
+	u8 val;
+	int ret;
+
+	ret = spacemit_p1_read_atomic(client, reg, &val);
+	if (ret)
+		return ret;
+
+	return spacemit_p1_write_atomic(client, reg, val | mask);
+}
+
 static int spacemit_p1_pwroff_handler(struct sys_off_data *data)
 {
-	struct regmap *regmap = data->cb_data;
+	struct i2c_client *client = data->cb_data;
 	int ret;
 
 	/* Put the PMIC into shutdown state */
-	ret = regmap_set_bits(regmap, PWR_CTRL2, PWR_CTRL2_SHUTDOWN);
+	ret = spacemit_p1_update_bits_atomic(client, PWR_CTRL2,
+					     PWR_CTRL2_SHUTDOWN);
 	if (ret) {
 		dev_err(data->dev, "shutdown failed: %d\n", ret);
 		return notifier_from_errno(ret);
@@ -30,11 +86,12 @@ static int spacemit_p1_pwroff_handler(struct sys_off_data *data)
 
 static int spacemit_p1_restart_handler(struct sys_off_data *data)
 {
-	struct regmap *regmap = data->cb_data;
+	struct i2c_client *client = data->cb_data;
 	int ret;
 
 	/* Put the PMIC into reset state */
-	ret = regmap_set_bits(regmap, PWR_CTRL2, PWR_CTRL2_RST);
+	ret = spacemit_p1_update_bits_atomic(client, PWR_CTRL2,
+					     PWR_CTRL2_RST);
 	if (ret) {
 		dev_err(data->dev, "restart failed: %d\n", ret);
 		return notifier_from_errno(ret);
@@ -46,21 +103,26 @@ static int spacemit_p1_restart_handler(struct sys_off_data *data)
 static int spacemit_p1_reboot_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct regmap *regmap;
+	struct i2c_client *client;
 	int ret;
 
-	regmap = dev_get_regmap(dev->parent, NULL);
-	if (!regmap)
-		return -ENODEV;
+	client = i2c_verify_client(dev->parent);
+	if (!client)
+		return dev_err_probe(dev, -ENODEV,
+				     "Failed to find parent I2C client\n");
+
+	if (!client->adapter->algo->xfer_atomic)
+		return dev_err_probe(dev, -EOPNOTSUPP,
+				     "Atomic I2C transfers not supported\n");
 
-	ret = devm_register_power_off_handler(dev, &spacemit_p1_pwroff_handler,
-					      regmap);
+	ret = devm_register_power_off_handler(dev, spacemit_p1_pwroff_handler,
+					      client);
 	if (ret)
 		return dev_err_probe(dev, ret,
 				     "Failed to register power off handler\n");
 
 	ret = devm_register_restart_handler(dev, spacemit_p1_restart_handler,
-					    regmap);
+					    client);
 	if (ret)
 		return dev_err_probe(dev, ret,
 				     "Failed to register restart handler\n");
Signature · 1 line
2.56.0
#2 lore raw

Re: [PATCH v1 2/2] power: reset: spacemit-p1: Use atomic I2C transfers for power-off and restart

Hi Anand,

Quoted 22 lines · Anand Moon

The SpacemiT P1 power-off and restart handlers use regmap_set_bits() to access the PMIC. However, these handlers run in an atomic notifier context (specifically within an rcu_read_lock() critical section), while the I2C-backed regmap uses a sleepable mutex.

This triggers a "WARNING: suspicious RCU usage" warning due to an illegal context switch in the RCU read-side critical section during shutdown on the Banana Pi BPI-F3:

[  563.803475] WARNING: suspicious RCU usage
[  563.807813] 7.3.1-ARCH-RISC-V #1 Not tainted
[  563.816614] ./include/linux/rcupdate.h:387 Illegal context switch in RCU read-side critical section!
...
[  563.841445] locks held by shutdown/1: 2, last CPU#0:
[  563.846694]  #0: ffffffff8404fb20 (system_transition_mutex){+.+.}-{4:4}, at: __do_sys_reboot+0x230/0x29e
[  563.856806]  #1: ffffffff84167860 (rcu_read_lock){....}-{1:3}, at: atomic_notifier_call_chain+0x4a/0x1c2

Replace the regmap operations with atomic I2C transfers to avoid sleeping in an atomic context. Preserve unrelated register bits through read-modify-write operations and check for atomic I2C support before registering the handlers.

Quoted 4 lines

Obtain the I2C client from the parent device and verify that the adapter supports atomic transfers before registering the handlers.

Tested on the Banana Pi BPI-F3 (SpacemiT K1).

While the patch looks correct, I am not sure this is the correct approach, as opposed to the one proposed by Troy [1].

Indeed bypassing regmap and using i2c atomic transfers needs to be done by all affected drivers. For instance the VisionFive 2 board, which use an axp15060 PMIC is also affected by this issue. And the corresponding driver is shared between architectures, which make this kind of change more difficult.

For the BPI-F3, note that with OpenSBI 1.9, the reboot is handled through the SBI SRST extension, preventing this issue to happen. On the long term, I am not sure we should keep this driver.

Regards
Aurelien

[1] https://lore.kernel.org/linux-riscv/20261104-v7-0-rc1-rv-dis-int-before-restart-v5-1-956ec09c900d@linux.dev/

Signature · 2 lines
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
[email protected]                     http://aurel32.net
maintainer
#3 lore raw

Re: [PATCH v1 2/2] power: reset: spacemit-p1: Use atomic I2C transfers for power-off and restart

Hi Aurelien,

Quoted 39 lines · Aurelien Jarno

Hi Anand,

Quoted 22 lines · Anand Moon

The SpacemiT P1 power-off and restart handlers use regmap_set_bits() to access the PMIC. However, these handlers run in an atomic notifier context (specifically within an rcu_read_lock() critical section), while the I2C-backed regmap uses a sleepable mutex.

This triggers a "WARNING: suspicious RCU usage" warning due to an illegal context switch in the RCU read-side critical section during shutdown on the Banana Pi BPI-F3:

[  563.803475] WARNING: suspicious RCU usage
[  563.807813] 7.3.1-ARCH-RISC-V #1 Not tainted
[  563.816614] ./include/linux/rcupdate.h:387 Illegal context switch in RCU read-side critical section!
...
[  563.841445] locks held by shutdown/1: 2, last CPU#0:
[  563.846694]  #0: ffffffff8404fb20 (system_transition_mutex){+.+.}-{4:4}, at: __do_sys_reboot+0x230/0x29e
[  563.856806]  #1: ffffffff84167860 (rcu_read_lock){....}-{1:3}, at: atomic_notifier_call_chain+0x4a/0x1c2

Replace the regmap operations with atomic I2C transfers to avoid sleeping in an atomic context. Preserve unrelated register bits through read-modify-write operations and check for atomic I2C support before registering the handlers.

Quoted 4 lines

Obtain the I2C client from the parent device and verify that the adapter supports atomic transfers before registering the handlers.

Tested on the Banana Pi BPI-F3 (SpacemiT K1).

While the patch looks correct, I am not sure this is the correct approach, as opposed to the one proposed by Troy [1].

Indeed bypassing regmap and using i2c atomic transfers needs to be done by all affected drivers. For instance the VisionFive 2 board, which use an axp15060 PMIC is also affected by this issue. And the corresponding driver is shared between architectures, which make this kind of change more difficult.

Quoted 4 lines

For the BPI-F3, note that with OpenSBI 1.9, the reboot is handled through the SBI SRST extension, preventing this issue to happen. On the long term, I am not sure we should keep this driver.

That only covers restart. The SBI restart handler is registered at priority 192 and runs before the P1 one at SYS_OFF_PRIO_DEFAULT. Power off is the other way around: sbi_srst_power_off() goes through register_platform_power_off(), i.e. SYS_OFF_PRIO_PLATFORM, so the P1 power-off handler still runs first and still hits this on shutdown, even with OpenSBI 1.9.

So until this driver goes away, BPI-F3 still needs the arch fix [1] for power-off.

Signature · 1 line
Troy Mitchell
#4 lore raw

Re: [PATCH v1 2/2] power: reset: spacemit-p1: Use atomic I2C transfers for power-off and restart

Hi Troy,

Quoted 53 lines · Troy Mitchell

Hi Aurelien,

Quoted 39 lines · Aurelien Jarno

Hi Anand,

Quoted 22 lines · Anand Moon

The SpacemiT P1 power-off and restart handlers use regmap_set_bits() to access the PMIC. However, these handlers run in an atomic notifier context (specifically within an rcu_read_lock() critical section), while the I2C-backed regmap uses a sleepable mutex.

This triggers a "WARNING: suspicious RCU usage" warning due to an illegal context switch in the RCU read-side critical section during shutdown on the Banana Pi BPI-F3:

[  563.803475] WARNING: suspicious RCU usage
[  563.807813] 7.3.1-ARCH-RISC-V #1 Not tainted
[  563.816614] ./include/linux/rcupdate.h:387 Illegal context switch in RCU read-side critical section!
...
[  563.841445] locks held by shutdown/1: 2, last CPU#0:
[  563.846694]  #0: ffffffff8404fb20 (system_transition_mutex){+.+.}-{4:4}, at: __do_sys_reboot+0x230/0x29e
[  563.856806]  #1: ffffffff84167860 (rcu_read_lock){....}-{1:3}, at: atomic_notifier_call_chain+0x4a/0x1c2

Replace the regmap operations with atomic I2C transfers to avoid sleeping in an atomic context. Preserve unrelated register bits through read-modify-write operations and check for atomic I2C support before registering the handlers.

Quoted 4 lines

Obtain the I2C client from the parent device and verify that the adapter supports atomic transfers before registering the handlers.

Tested on the Banana Pi BPI-F3 (SpacemiT K1).

While the patch looks correct, I am not sure this is the correct approach, as opposed to the one proposed by Troy [1].

Indeed bypassing regmap and using i2c atomic transfers needs to be done by all affected drivers. For instance the VisionFive 2 board, which use an axp15060 PMIC is also affected by this issue. And the corresponding driver is shared between architectures, which make this kind of change more difficult.

Quoted 4 lines

For the BPI-F3, note that with OpenSBI 1.9, the reboot is handled through the SBI SRST extension, preventing this issue to happen. On the long term, I am not sure we should keep this driver.

That only covers restart. The SBI restart handler is registered at priority 192 and runs before the P1 one at SYS_OFF_PRIO_DEFAULT. Power off is the other way around: sbi_srst_power_off() goes through register_platform_power_off(), i.e. SYS_OFF_PRIO_PLATFORM, so the P1 power-off handler still runs first and still hits this on shutdown, even with OpenSBI 1.9.

Quoted 4 lines

So until this driver goes away, BPI-F3 still needs the arch fix [1] for power-off.

We also need a more global fix for the other boards like the VisionFive 2, so definitely we need the above fix instead of patching the drivers.

Aurelien

Signature · 2 lines
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
[email protected]                     http://aurel32.net
author
#5 lore raw

Re: [PATCH v1 2/2] power: reset: spacemit-p1: Use atomic I2C transfers for power-off and restart

Hi Troy. Aurelien,

Thanks for your review comments.

Quoted 57 lines · Aurelien Jarno

Hi Troy,

Quoted 53 lines · Troy Mitchell

Hi Aurelien,

Quoted 39 lines · Aurelien Jarno

Hi Anand,

Quoted 22 lines · Anand Moon

The SpacemiT P1 power-off and restart handlers use regmap_set_bits() to access the PMIC. However, these handlers run in an atomic notifier context (specifically within an rcu_read_lock() critical section), while the I2C-backed regmap uses a sleepable mutex.

This triggers a "WARNING: suspicious RCU usage" warning due to an illegal context switch in the RCU read-side critical section during shutdown on the Banana Pi BPI-F3:

[  563.803475] WARNING: suspicious RCU usage
[  563.807813] 7.3.1-ARCH-RISC-V #1 Not tainted
[  563.816614] ./include/linux/rcupdate.h:387 Illegal context switch in RCU read-side critical section!
...
[  563.841445] locks held by shutdown/1: 2, last CPU#0:
[  563.846694]  #0: ffffffff8404fb20 (system_transition_mutex){+.+.}-{4:4}, at: __do_sys_reboot+0x230/0x29e
[  563.856806]  #1: ffffffff84167860 (rcu_read_lock){....}-{1:3}, at: atomic_notifier_call_chain+0x4a/0x1c2

Replace the regmap operations with atomic I2C transfers to avoid sleeping in an atomic context. Preserve unrelated register bits through read-modify-write operations and check for atomic I2C support before registering the handlers.

Quoted 4 lines

Obtain the I2C client from the parent device and verify that the adapter supports atomic transfers before registering the handlers.

Tested on the Banana Pi BPI-F3 (SpacemiT K1).

While the patch looks correct, I am not sure this is the correct approach, as opposed to the one proposed by Troy [1].

Indeed bypassing regmap and using i2c atomic transfers needs to be done by all affected drivers. For instance the VisionFive 2 board, which use an axp15060 PMIC is also affected by this issue. And the corresponding driver is shared between architectures, which make this kind of change more difficult.

Quoted 4 lines

For the BPI-F3, note that with OpenSBI 1.9, the reboot is handled through the SBI SRST extension, preventing this issue to happen. On the long term, I am not sure we should keep this driver.

That only covers restart. The SBI restart handler is registered at priority 192 and runs before the P1 one at SYS_OFF_PRIO_DEFAULT. Power off is the other way around: sbi_srst_power_off() goes through register_platform_power_off(), i.e. SYS_OFF_PRIO_PLATFORM, so the P1 power-off handler still runs first and still hits this on shutdown, even with OpenSBI 1.9.

I had previously tested the OpenSBI P1 PMIC driver in a Yocto-based environment:

[1] https://lore.kernel.org/all/[email protected]/

With this driver registered in OpenSBI, Linux can delegate reboot and power-off operations to firmware through the SBI SRST extension.

The power-off sequence is:

    Linux kernel_power_off()
      -> RISC-V machine power-off
      -> SBI SRST shutdown
      -> OpenSBI system_reset()
      -> SpacemiT P1 PMIC
      -> Power off

I have now rebuilt the Linux kernel with:

# CONFIG_POWER_RESET_SPACEMIT_P1 is not set

Both reboot and power-off work correctly on the Banana Pi BPI-F3, and I have not observed any issues.

alarm@k1:~$ sudo poweroff

Broadcast message from root@k1 on pts/1 (Wed 2026-11-11 10:34:03 UTC):

The system will power off now!

[ 1744.735287] systemd-shutdown[1]: Sending SIGTERM to remaining processes...
[ 1745.071304] systemd-journald[245]: Received SIGTERM from PID 1
(systemd-shutdow).
[ 1745.504595] systemd-shutdown[1]: Sending SIGKILL to remaining processes...
[ 1745.790159] systemd-shutdown[1]: Unmounting file systems.
[ 1745.822902] (sd-umount)[658]: Unmounting
'/run/credentials/systemd-journald.service'.
[ 1745.861214] (sd-remount)[659]: Remounting '/' read-only with options ''.
[ 1746.079291] EXT4-fs (mmcblk1p7): re-mounted
ccb95ca0-2804-4ade-938f-23116f90c193 ro.
[ 1746.272104] systemd-shutdown[1]: All filesystems unmounted.
[ 1746.272471] systemd-shutdown[1]: Deactivating swaps.
[ 1746.273712] systemd-shutdown[1]: All swaps deactivated.
[ 1746.273956] systemd-shutdown[1]: Detaching loop devices.
[ 1746.464867] systemd-shutdown[1]: All loop devices detached.
[ 1746.465346] systemd-shutdown[1]: Stopping MD devices.
[ 1746.471149] systemd-shutdown[1]: All MD devices stopped.
[ 1746.471417] systemd-shutdown[1]: Detaching DM devices.
[ 1746.476047] systemd-shutdown[1]: All DM devices detached.
[ 1746.476377] systemd-shutdown[1]: All filesystems, swaps, loop
devices, MD devices and DM devices detached.
[ 1746.533569] systemd-shutdown[1]: Successfully changed into root pivot.
[ 1746.533862] systemd-shutdown[1]: Entering exitrd...
[ 1746.686127] shutdown[1]: Syncing filesystems and block devices.
[ 1746.701832] shutdown[1]: Sending SIGTERM to remaining processes...
[ 1746.934370] shutdown[1]: Sending SIGKILL to remaining processes...
[ 1747.164219] shutdown[1]: Unmounting file systems.
[ 1747.203935] (sd-umoun[662]: Unmounting '/run/credentials'.
[ 1747.232643] (sd-umoun[663]: Unmounting '/oldroot/sys/kernel/config'.
[ 1747.269882] (sd-umoun[664]: Unmounting '/oldroot/sys/kernel/tracing'.
[ 1747.298218] (sd-umoun[665]: Unmounting '/oldroot/sys/kernel/debug'.
[ 1747.327488] (sd-umoun[666]: Unmounting '/oldroot/dev/hugepages'.
[ 1747.359053] (sd-umoun[667]: Unmounting '/oldroot/dev/mqueue'.
[ 1747.387798] (sd-umoun[668]: Unmounting '/oldroot/run'.
[ 1747.425939] (sd-umoun[669]: Unmounting '/oldroot/proc'.
[ 1747.473927] (sd-umoun[670]: Unmounting '/oldroot/sys/fs/bpf'.
[ 1747.527910] (sd-umoun[671]: Unmounting '/oldroot/sys/fs/pstore'.
[ 1747.588367] (sd-umoun[672]: Unmounting '/oldroot/sys/fs/cgroup'.
[ 1747.630489] (sd-umoun[673]: Unmounting '/oldroot/sys/kernel/security'.
[ 1747.664244] (sd-umoun[674]: Unmounting '/oldroot/sys'.
[ 1747.704716] (sd-umoun[675]: Unmounting '/oldroot/dev/pts'.
[ 1747.755218] (sd-umoun[676]: Unmounting '/oldroot/dev/shm'.
[ 1747.791652] (sd-umoun[677]: Unmounting '/oldroot/dev'.
[ 1747.826501] (sd-umoun[678]: Unmounting '/oldroot'.
[ 1748.451336] EXT4-fs (mmcblk1p7): unmounting filesystem
ccb95ca0-2804-4ade-938f-23116f90c193.
[ 1748.643359] shutdown[1]: All filesystems unmounted.
[ 1748.643640] shutdown[1]: Deactivating swaps.
[ 1748.644512] shutdown[1]: All swaps deactivated.
[ 1748.644722] shutdown[1]: Detaching loop devices.
[ 1748.732490] shutdown[1]: All loop devices detached.
[ 1748.732764] shutdown[1]: Stopping MD devices.
[ 1748.754002] shutdown[1]: All MD devices stopped.
[ 1748.754286] shutdown[1]: Detaching DM devices.
[ 1748.759617] shutdown[1]: All DM devices detached.
[ 1748.759885] shutdown[1]: All filesystems, swaps, loop devices, MD
devices and DM devices detached.
[ 1748.770510] shutdown[1]: Syncing filesystems and block devices.
[ 1748.791699] shutdown[1]: Powering off.
[ 1749.009246] reboot: Power down

Given that OpenSBI already handles both operations,
I agree that the Linux P1 power-off and reset driver may no longer be necessary, at least on systems using firmware with the appropriate SBI SRST support.

Quoted 8 lines
Quoted 4 lines

So until this driver goes away, BPI-F3 still needs the arch fix [1] for power-off.

We also need a more global fix for the other boards like the VisionFive 2, so definitely we need the above fix instead of patching the drivers.

Maybe we need an opensbi driver for VisionFive 2 dev boards; any thoughts

Quoted 5 lines

Aurelien

--
Aurelien Jarno GPG: 4096R/1DDD8C9B
[email protected] http://aurel32.net

Thanks
-Anand

maintainer Reviewed-by on v1 1/2
#6 lore raw
In reply to Anand Moon
Quoted 8 lines · Anand Moon

The spacemit_i2c_conditionally_reset_bus() function uses usleep_range() to wait after triggering a bus reset request. However, this function can be invoked during atomic I2C transfers (such as power-off or restart handlers running in atomic notifier chains), where sleeping is illegal.

Replace the sleep operation with the driver's internal helper, spacemit_i2c_delay(), which conditionally uses udelay() when running in an atomic context, avoiding "scheduling while atomic" bugs.

This usleep_range() was left behind when the PIO path and spacemit_i2c_delay() were added, so please add:

Fixes 5dd75dac1b35 ("i2c: spacemit: introduce pio for k1")

Otherwise, LGTM.

Signature · 1 line
Troy Mitchell
maintainer
#7 lore raw
In reply to Anand Moon
Quoted 10 lines · Anand Moon

The spacemit_i2c_conditionally_reset_bus() function uses usleep_range() to wait after triggering a bus reset request. However, this function can be invoked during atomic I2C transfers (such as power-off or restart handlers running in atomic notifier chains), where sleeping is illegal.

Replace the sleep operation with the driver's internal helper, spacemit_i2c_delay(), which conditionally uses udelay() when running in an atomic context, avoiding "scheduling while atomic" bugs.

Assisted-by LLM

Also, please drop this tag. The same applies to patch 2. See commit 1e035297ffda.

Signature · 1 line
Troy Mitchell
author
#8 lore raw

Hi Troy,

Quoted 7 lines · Troy Mitchell
Quoted 5 lines · Anand Moon

The spacemit_i2c_conditionally_reset_bus() function uses usleep_range() to wait after triggering a bus reset request. However, this function can be invoked during atomic I2C transfers (such as power-off or restart handlers running in atomic notifier chains), where sleeping is illegal.

Quoted 8 lines
Quoted 5 lines

Replace the sleep operation with the driver's internal helper, spacemit_i2c_delay(), which conditionally uses udelay() when running in an atomic context, avoiding "scheduling while atomic" bugs.

Assisted-by LLM

Also, please drop this tag. The same applies to patch 2. See commit 1e035297ffda.

Ok once I get positive feedback on both patches, I will drop this tag and resubmit.

Quoted 3 lines

--
Troy Mitchell

Thanks
-Anand

Reviewed-by on v1 1/2
#9 lore raw
In reply to Anand Moon
Quoted 31 lines · Anand Moon

The spacemit_i2c_conditionally_reset_bus() function uses usleep_range() to wait after triggering a bus reset request. However, this function can be invoked during atomic I2C transfers (such as power-off or restart handlers running in atomic notifier chains), where sleeping is illegal.

Replace the sleep operation with the driver's internal helper, spacemit_i2c_delay(), which conditionally uses udelay() when running in an atomic context, avoiding "scheduling while atomic" bugs.

Assisted-by LLM
Cc Troy Mitchell <[email protected]>
Cc Alex Elder <[email protected]>
---
 drivers/i2c/busses/i2c-k1.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i2c/busses/i2c-k1.c +1 -1
index ff32876e24d3..f4b21d7efaaf 100644
@@ -332,7 +332,7 @@ static void spacemit_i2c_conditionally_reset_bus(struct spacemit_i2c_dev *i2c)
 		writel(FIELD_PREP(SPACEMIT_RCR_FIELD_RST_CYC, 1),
 		       i2c->base + SPACEMIT_IRCR);
 		writel(SPACEMIT_CR_RSTREQ, i2c->base + SPACEMIT_ICR);
-		usleep_range(20, 30);
+		spacemit_i2c_delay(i2c, 20);
 	}
 
 	/* check sda again here */
Quoted 1 line

base-commit: b3dfbde62cf1981c4638939c159dfd087b7a72e9

Signature · 2 lines
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
[email protected]                     http://aurel32.net
Reviewed-by on v1 1/2
#10 lore raw
In reply to Anand Moon
Quoted 31 lines · Anand Moon

The spacemit_i2c_conditionally_reset_bus() function uses usleep_range() to wait after triggering a bus reset request. However, this function can be invoked during atomic I2C transfers (such as power-off or restart handlers running in atomic notifier chains), where sleeping is illegal.

Replace the sleep operation with the driver's internal helper, spacemit_i2c_delay(), which conditionally uses udelay() when running in an atomic context, avoiding "scheduling while atomic" bugs.

Assisted-by LLM
Cc Troy Mitchell <[email protected]>
Cc Alex Elder <[email protected]>
---
  drivers/i2c/busses/i2c-k1.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i2c/busses/i2c-k1.c +1 -1
index ff32876e24d3..f4b21d7efaaf 100644
@@ -332,7 +332,7 @@ static void spacemit_i2c_conditionally_reset_bus(struct spacemit_i2c_dev *i2c)
  		writel(FIELD_PREP(SPACEMIT_RCR_FIELD_RST_CYC, 1),
  		       i2c->base + SPACEMIT_IRCR);
  		writel(SPACEMIT_CR_RSTREQ, i2c->base + SPACEMIT_ICR);
-		usleep_range(20, 30);
+		spacemit_i2c_delay(i2c, 20);
  	}
 
  	/* check sda again here */
Quoted 1 line

base-commit: b3dfbde62cf1981c4638939c159dfd087b7a72e9

The use_pio flag is set for atomic transfers, so spacemit_i2c_delay() will use udelay() regardless of the delay period.

Looks good.