diff options
Diffstat (limited to 'drivers/watchdog/da9062_wdt.c')
-rw-r--r-- | drivers/watchdog/da9062_wdt.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/watchdog/da9062_wdt.c b/drivers/watchdog/da9062_wdt.c index f02cbd530538..426962547df1 100644 --- a/drivers/watchdog/da9062_wdt.c +++ b/drivers/watchdog/da9062_wdt.c @@ -155,11 +155,20 @@ static int da9062_wdt_restart(struct watchdog_device *wdd, unsigned long action, { struct da9062_watchdog *wdt = watchdog_get_drvdata(wdd); struct i2c_client *client = to_i2c_client(wdt->hw->dev); + union i2c_smbus_data msg; int ret; - /* Don't use regmap because it is not atomic safe */ - ret = i2c_smbus_write_byte_data(client, DA9062AA_CONTROL_F, - DA9062AA_SHUTDOWN_MASK); + /* + * Don't use regmap because it is not atomic safe. Additionally, use + * unlocked flavor of i2c_smbus_xfer to avoid scenario where i2c bus + * might be previously locked by some process unable to release the + * lock due to interrupts already being disabled at this late stage. + */ + msg.byte = DA9062AA_SHUTDOWN_MASK; + ret = __i2c_smbus_xfer(client->adapter, client->addr, client->flags, + I2C_SMBUS_WRITE, DA9062AA_CONTROL_F, + I2C_SMBUS_BYTE_DATA, &msg); + if (ret < 0) dev_alert(wdt->hw->dev, "Failed to shutdown (err = %d)\n", ret); |