From: Greg Kroah-Hartman Date: Sat, 28 Jan 2023 09:29:47 +0000 (+0100) Subject: 5.15-stable patches X-Git-Tag: v5.10.166~52 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6c56cab3e046923fc457cc8747e6a3e8e5f4f306;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches added patches: i2c-mv64xxx-add-atomic_xfer-method-to-driver.patch i2c-mv64xxx-remove-shutdown-method-from-driver.patch --- diff --git a/queue-5.15/i2c-mv64xxx-add-atomic_xfer-method-to-driver.patch b/queue-5.15/i2c-mv64xxx-add-atomic_xfer-method-to-driver.patch new file mode 100644 index 00000000000..822f73307d4 --- /dev/null +++ b/queue-5.15/i2c-mv64xxx-add-atomic_xfer-method-to-driver.patch @@ -0,0 +1,146 @@ +From 544a8d75f3d6e60e160cd92dc56321484598a993 Mon Sep 17 00:00:00 2001 +From: Chris Morgan +Date: Wed, 30 Mar 2022 12:16:57 -0500 +Subject: i2c: mv64xxx: Add atomic_xfer method to driver + +From: Chris Morgan + +commit 544a8d75f3d6e60e160cd92dc56321484598a993 upstream. + +Add an atomic_xfer method to the driver so that it behaves correctly +when controlling a PMIC that is responsible for device shutdown. + +The atomic_xfer method added is similar to the one from the i2c-rk3x +driver. When running an atomic_xfer a bool flag in the driver data is +set, the interrupt is not unmasked on transfer start, and the IRQ +handler is manually invoked while waiting for pending transfers to +complete. + +Signed-off-by: Chris Morgan +Acked-by: Gregory CLEMENT +Signed-off-by: Wolfram Sang +Cc: Tong Zhang +Signed-off-by: Greg Kroah-Hartman +--- + drivers/i2c/busses/i2c-mv64xxx.c | 52 ++++++++++++++++++++++++++++++++++----- + 1 file changed, 46 insertions(+), 6 deletions(-) + +--- a/drivers/i2c/busses/i2c-mv64xxx.c ++++ b/drivers/i2c/busses/i2c-mv64xxx.c +@@ -150,6 +150,7 @@ struct mv64xxx_i2c_data { + /* Clk div is 2 to the power n, not 2 to the power n + 1 */ + bool clk_n_base_0; + struct i2c_bus_recovery_info rinfo; ++ bool atomic; + }; + + static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = { +@@ -179,7 +180,10 @@ mv64xxx_i2c_prepare_for_io(struct mv64xx + u32 dir = 0; + + drv_data->cntl_bits = MV64XXX_I2C_REG_CONTROL_ACK | +- MV64XXX_I2C_REG_CONTROL_INTEN | MV64XXX_I2C_REG_CONTROL_TWSIEN; ++ MV64XXX_I2C_REG_CONTROL_TWSIEN; ++ ++ if (!drv_data->atomic) ++ drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_INTEN; + + if (msg->flags & I2C_M_RD) + dir = 1; +@@ -409,7 +413,8 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c + case MV64XXX_I2C_ACTION_RCV_DATA_STOP: + drv_data->msg->buf[drv_data->byte_posn++] = + readl(drv_data->reg_base + drv_data->reg_offsets.data); +- drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN; ++ if (!drv_data->atomic) ++ drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN; + writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP, + drv_data->reg_base + drv_data->reg_offsets.control); + drv_data->block = 0; +@@ -427,7 +432,8 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c + drv_data->rc = -EIO; + fallthrough; + case MV64XXX_I2C_ACTION_SEND_STOP: +- drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN; ++ if (!drv_data->atomic) ++ drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN; + writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP, + drv_data->reg_base + drv_data->reg_offsets.control); + drv_data->block = 0; +@@ -575,6 +581,17 @@ mv64xxx_i2c_wait_for_completion(struct m + spin_unlock_irqrestore(&drv_data->lock, flags); + } + ++static void mv64xxx_i2c_wait_polling(struct mv64xxx_i2c_data *drv_data) ++{ ++ ktime_t timeout = ktime_add_ms(ktime_get(), drv_data->adapter.timeout); ++ ++ while (READ_ONCE(drv_data->block) && ++ ktime_compare(ktime_get(), timeout) < 0) { ++ udelay(5); ++ mv64xxx_i2c_intr(0, drv_data); ++ } ++} ++ + static int + mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg, + int is_last) +@@ -590,7 +607,11 @@ mv64xxx_i2c_execute_msg(struct mv64xxx_i + mv64xxx_i2c_send_start(drv_data); + spin_unlock_irqrestore(&drv_data->lock, flags); + +- mv64xxx_i2c_wait_for_completion(drv_data); ++ if (!drv_data->atomic) ++ mv64xxx_i2c_wait_for_completion(drv_data); ++ else ++ mv64xxx_i2c_wait_polling(drv_data); ++ + return drv_data->rc; + } + +@@ -717,7 +738,7 @@ mv64xxx_i2c_functionality(struct i2c_ada + } + + static int +-mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) ++mv64xxx_i2c_xfer_core(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) + { + struct mv64xxx_i2c_data *drv_data = i2c_get_adapdata(adap); + int rc, ret = num; +@@ -730,7 +751,7 @@ mv64xxx_i2c_xfer(struct i2c_adapter *ada + drv_data->msgs = msgs; + drv_data->num_msgs = num; + +- if (mv64xxx_i2c_can_offload(drv_data)) ++ if (mv64xxx_i2c_can_offload(drv_data) && !drv_data->atomic) + rc = mv64xxx_i2c_offload_xfer(drv_data); + else + rc = mv64xxx_i2c_execute_msg(drv_data, &msgs[0], num == 1); +@@ -747,8 +768,27 @@ mv64xxx_i2c_xfer(struct i2c_adapter *ada + return ret; + } + ++static int ++mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) ++{ ++ struct mv64xxx_i2c_data *drv_data = i2c_get_adapdata(adap); ++ ++ drv_data->atomic = 0; ++ return mv64xxx_i2c_xfer_core(adap, msgs, num); ++} ++ ++static int mv64xxx_i2c_xfer_atomic(struct i2c_adapter *adap, ++ struct i2c_msg msgs[], int num) ++{ ++ struct mv64xxx_i2c_data *drv_data = i2c_get_adapdata(adap); ++ ++ drv_data->atomic = 1; ++ return mv64xxx_i2c_xfer_core(adap, msgs, num); ++} ++ + static const struct i2c_algorithm mv64xxx_i2c_algo = { + .master_xfer = mv64xxx_i2c_xfer, ++ .master_xfer_atomic = mv64xxx_i2c_xfer_atomic, + .functionality = mv64xxx_i2c_functionality, + }; + diff --git a/queue-5.15/i2c-mv64xxx-remove-shutdown-method-from-driver.patch b/queue-5.15/i2c-mv64xxx-remove-shutdown-method-from-driver.patch new file mode 100644 index 00000000000..b194ba7791d --- /dev/null +++ b/queue-5.15/i2c-mv64xxx-remove-shutdown-method-from-driver.patch @@ -0,0 +1,57 @@ +From 09b343038e3470e4d0da45f0ee09fb42107e5314 Mon Sep 17 00:00:00 2001 +From: Chris Morgan +Date: Fri, 25 Mar 2022 13:06:25 -0500 +Subject: i2c: mv64xxx: Remove shutdown method from driver + +From: Chris Morgan + +commit 09b343038e3470e4d0da45f0ee09fb42107e5314 upstream. + +When I attempt to shut down (or reboot) my R8 based NTC CHIP with this +i2c driver I get the following error: "i2c i2c-0: mv64xxx: I2C bus +locked, block: 1, time_left: 0". Reboots are successful but shutdowns +freeze. If I comment out the shutdown routine the device both reboots +and shuts down successfully without receiving this error (however it +does receive a warning of missing atomic_xfer). + +It appears that very few i2c drivers have a shutdown method, I assume +because these devices are often used to communicate with PMICs (such +as in my case with the R8 based NTC CHIP). I'm proposing we simply +remove this method so long as it doesn't cause trouble for others +downstream. I'll work on an atomic_xfer method and submit that in +a different patch. + +Signed-off-by: Chris Morgan +Acked-by: Gregory CLEMENT +Signed-off-by: Wolfram Sang +Cc: Tong Zhang +Signed-off-by: Greg Kroah-Hartman +--- + drivers/i2c/busses/i2c-mv64xxx.c | 9 --------- + 1 file changed, 9 deletions(-) + +--- a/drivers/i2c/busses/i2c-mv64xxx.c ++++ b/drivers/i2c/busses/i2c-mv64xxx.c +@@ -1047,14 +1047,6 @@ mv64xxx_i2c_remove(struct platform_devic + return 0; + } + +-static void +-mv64xxx_i2c_shutdown(struct platform_device *pd) +-{ +- pm_runtime_disable(&pd->dev); +- if (!pm_runtime_status_suspended(&pd->dev)) +- mv64xxx_i2c_runtime_suspend(&pd->dev); +-} +- + static const struct dev_pm_ops mv64xxx_i2c_pm_ops = { + SET_RUNTIME_PM_OPS(mv64xxx_i2c_runtime_suspend, + mv64xxx_i2c_runtime_resume, NULL) +@@ -1065,7 +1057,6 @@ static const struct dev_pm_ops mv64xxx_i + static struct platform_driver mv64xxx_i2c_driver = { + .probe = mv64xxx_i2c_probe, + .remove = mv64xxx_i2c_remove, +- .shutdown = mv64xxx_i2c_shutdown, + .driver = { + .name = MV64XXX_I2C_CTLR_NAME, + .pm = &mv64xxx_i2c_pm_ops, diff --git a/queue-5.15/series b/queue-5.15/series index d971ea262cc..b248c0c38ed 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -149,3 +149,5 @@ tracing-make-sure-trace_printk-can-output-as-soon-as-it-can-be-used.patch trace_events_hist-add-check-for-return-value-of-create_hist_field.patch ftrace-scripts-update-the-instructions-for-ftrace-bisect.sh.patch cifs-fix-oops-due-to-uncleared-server-smbd_conn-in-reconnect.patch +i2c-mv64xxx-remove-shutdown-method-from-driver.patch +i2c-mv64xxx-add-atomic_xfer-method-to-driver.patch