driver: i2c: npcx: prevent sleep during I2C transactions
Deep Sleep mode stops SMB module clocks which could interrupt ongoing I2C transactions, so have the I2C driver acquire a PM lock at the beginning of a transaction and release it at the end in order to ensure the module remains active. Signed-off-by: Peter Marheine <pmarheine@chromium.org> Signed-off-by: Jun Lin <CHLin56@nuvoton.com>
This commit is contained in:
parent
2453e4de00
commit
95fb984f0b
1 changed files with 11 additions and 2 deletions
|
@ -3,6 +3,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <zephyr/pm/policy.h>
|
||||
|
||||
#define DT_DRV_COMPAT nuvoton_npcx_i2c_ctrl
|
||||
|
||||
|
@ -817,6 +818,12 @@ int npcx_i2c_ctrl_transfer(const struct device *i2c_dev, struct i2c_msg *msgs,
|
|||
int ret = 0;
|
||||
uint8_t i;
|
||||
|
||||
/*
|
||||
* suspend-to-idle stops SMB module clocks (derived from APB2/APB3), which must remain
|
||||
* active during a transaction
|
||||
*/
|
||||
pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES);
|
||||
|
||||
/* Does bus need recovery? */
|
||||
if (data->oper_state != NPCX_I2C_WRITE_SUSPEND &&
|
||||
data->oper_state != NPCX_I2C_READ_SUSPEND) {
|
||||
|
@ -825,7 +832,7 @@ int npcx_i2c_ctrl_transfer(const struct device *i2c_dev, struct i2c_msg *msgs,
|
|||
ret = i2c_ctrl_recovery(i2c_dev);
|
||||
/* Recovery failed, return it immediately */
|
||||
if (ret) {
|
||||
return ret;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -876,10 +883,12 @@ int npcx_i2c_ctrl_transfer(const struct device *i2c_dev, struct i2c_msg *msgs,
|
|||
* layer still needs to know why the transaction failed.
|
||||
*/
|
||||
if (recovery_error != 0) {
|
||||
return recovery_error;
|
||||
ret = recovery_error;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue