mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
mfd: rk808: power off system in syscore shutdown
The i2c maybe stopped before pm_power_off() is called, which results in the PMIC power off failure issue. Moving PMIC power off operation to syscore shutdown is better. Change-Id: Ib43827ebd49059719b8899f90a696b6c32a6ddd1 Signed-off-by: Joseph Chen <chenjh@rock-chips.com>
This commit is contained in:
@@ -840,6 +840,9 @@ static void rk818_device_shutdown(void)
|
||||
dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n");
|
||||
}
|
||||
|
||||
/* Called in syscore shutdown */
|
||||
static void (*pm_shutdown)(void);
|
||||
|
||||
static void rk8xx_syscore_shutdown(void)
|
||||
{
|
||||
int ret;
|
||||
@@ -866,15 +869,26 @@ static void rk8xx_syscore_shutdown(void)
|
||||
* been stopped or PMIC may not be able to get i2c transfer while
|
||||
* there are too many devices are competiting.
|
||||
*/
|
||||
if (system_state == SYSTEM_POWER_OFF &&
|
||||
(rk808->variant == RK809_ID || rk808->variant == RK817_ID)) {
|
||||
ret = regmap_update_bits(rk808->regmap,
|
||||
RK817_SYS_CFG(3),
|
||||
RK817_SLPPIN_FUNC_MSK,
|
||||
SLPPIN_DN_FUN);
|
||||
if (ret) {
|
||||
dev_warn(&rk808_i2c_client->dev,
|
||||
"Cannot switch to power down function\n");
|
||||
if (system_state == SYSTEM_POWER_OFF) {
|
||||
if (rk808->variant == RK809_ID || rk808->variant == RK817_ID) {
|
||||
ret = regmap_update_bits(rk808->regmap,
|
||||
RK817_SYS_CFG(3),
|
||||
RK817_SLPPIN_FUNC_MSK,
|
||||
SLPPIN_DN_FUN);
|
||||
if (ret) {
|
||||
dev_warn(&rk808_i2c_client->dev,
|
||||
"Cannot switch to power down function\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (pm_shutdown) {
|
||||
dev_info(&rk808_i2c_client->dev, "System power off\n");
|
||||
pm_shutdown();
|
||||
mdelay(10);
|
||||
dev_info(&rk808_i2c_client->dev,
|
||||
"Power off failed !\n");
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1254,7 +1268,6 @@ static int rk808_probe(struct i2c_client *client,
|
||||
nr_cells = ARRAY_SIZE(rk817s);
|
||||
on_source = RK817_ON_SOURCE_REG;
|
||||
off_source = RK817_OFF_SOURCE_REG;
|
||||
register_syscore_ops(&rk808_syscore_ops);
|
||||
suspend_reg = rk817_suspend_reg;
|
||||
suspend_reg_num = ARRAY_SIZE(rk817_suspend_reg);
|
||||
resume_reg = rk817_resume_reg;
|
||||
@@ -1357,8 +1370,12 @@ static int rk808_probe(struct i2c_client *client,
|
||||
if (pm_off) {
|
||||
if (!pm_power_off_prepare)
|
||||
pm_power_off_prepare = rk808->pm_pwroff_prep_fn;
|
||||
if (!pm_power_off_prepare)
|
||||
pm_power_off = rk808->pm_pwroff_fn;
|
||||
|
||||
if (rk808->pm_pwroff_fn) {
|
||||
register_syscore_ops(&rk808_syscore_ops);
|
||||
/* power off system in the syscore shutdown ! */
|
||||
pm_shutdown = rk808->pm_pwroff_fn;
|
||||
}
|
||||
}
|
||||
|
||||
rk8xx_kobj = kobject_create_and_add("rk8xx", NULL);
|
||||
@@ -1401,6 +1418,9 @@ static int rk808_remove(struct i2c_client *client)
|
||||
pm_power_off_prepare == rk808->pm_pwroff_prep_fn)
|
||||
pm_power_off_prepare = NULL;
|
||||
|
||||
if (pm_shutdown)
|
||||
unregister_syscore_ops(&rk808_syscore_ops);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user