From 0dc5b4e01ca52f480cecc82972d92958ca6ce733 Mon Sep 17 00:00:00 2001 From: David Wu Date: Wed, 27 Jan 2021 10:08:48 +0800 Subject: [PATCH] i2c: i2c-rk3x: Clean wakeup warning form i2c restart This patch fixs the following warning: [ 41.482651] WARNING: CPU: 0 PID: 1 at kernel/sched/core.c:1763 set_task_cpu+0x1c0/0x220 [ 41.589204] Call trace: [ 41.589441] set_task_cpu+0x1c0/0x220 [ 41.589776] try_to_wake_up+0x2a8/0x408 [ 41.590124] default_wake_function+0x14/0x1c [ 41.590511] autoremove_wake_function+0x18/0x58 [ 41.590920] __wake_up_common+0xbc/0x138 [ 41.591280] __wake_up_common_lock+0x74/0xc4 [ 41.591662] __wake_up+0x14/0x1c [ 41.591966] rk3x_i2c_irq+0x43c/0x620 [ 41.592300] rk3x_i2c_restart_notify+0x3c/0xe4 [ 41.592708] atomic_notifier_call_chain+0x4c/0x84 [ 41.593139] do_kernel_pre_restart+0x20/0x28 [ 41.593525] machine_restart+0x20/0x58 [ 41.593864] kernel_restart+0xf4/0x100 [ 41.594200] __arm64_sys_reboot+0x140/0x20c [ 41.594585] el0_svc_common+0x98/0x160 [ 41.594921] el0_svc_compat_handler+0x18/0x20 [ 41.595315] el0_svc_compat+0x8/0x34 [ 41.595638] ---[ end trace 8a090dd86c5af601 ]--- Signed-off-by: David Wu Change-Id: I075d2189ece5f54822ac6515ee3d390aa46e8708 --- drivers/i2c/busses/i2c-rk3x.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c index 87f7aba54384..62715a318fde 100644 --- a/drivers/i2c/busses/i2c-rk3x.c +++ b/drivers/i2c/busses/i2c-rk3x.c @@ -196,6 +196,7 @@ struct rk3x_i2c_soc_data { * @processed: byte length which has been send or received * @error: error code for i2c transfer * @i2c_restart_nb: make sure the i2c transfer to be finished + * @system_restarting: true if system is restarting */ struct rk3x_i2c { struct i2c_adapter adap; @@ -229,11 +230,18 @@ struct rk3x_i2c { unsigned int suspended:1; struct notifier_block i2c_restart_nb; + bool system_restarting; }; static int rk3x_i2c_fill_transmit_buf(struct rk3x_i2c *i2c, bool sended); static void rk3x_i2c_prepare_read(struct rk3x_i2c *i2c); +static inline void rk3x_i2c_wake_up(struct rk3x_i2c *i2c) +{ + if (!i2c->system_restarting) + wake_up(&i2c->wait); +} + static inline void i2c_writel(struct rk3x_i2c *i2c, u32 value, unsigned int offset) { @@ -335,7 +343,7 @@ static void rk3x_i2c_stop(struct rk3x_i2c *i2c, int error) i2c_writel(i2c, ctrl, REG_CON); /* signal that we are finished with the current msg */ - wake_up(&i2c->wait); + rk3x_i2c_wake_up(i2c); } } @@ -488,7 +496,7 @@ static void rk3x_i2c_handle_stop(struct rk3x_i2c *i2c, unsigned int ipd) i2c->state = STATE_IDLE; /* signal rk3x_i2c_xfer that we are finished */ - wake_up(&i2c->wait); + rk3x_i2c_wake_up(i2c); } static irqreturn_t rk3x_i2c_irq(int irqno, void *dev_id) @@ -1145,6 +1153,7 @@ static int rk3x_i2c_restart_notify(struct notifier_block *this, u32 val; if (i2c->state != STATE_IDLE) { + i2c->system_restarting = true; /* complete the unfinished job */ while (tmo-- && i2c->busy) { udelay(1);