Skip to content

Commit 7a85065

Browse files
committed
Revert "Revert "mfd: rk808: power off system in syscore shutdown""
This reverts commit 58c1b9e.
1 parent 61e2341 commit 7a85065

1 file changed

Lines changed: 33 additions & 8 deletions

File tree

drivers/mfd/rk808.c

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
* more details.
1717
*/
1818

19+
#include <linux/delay.h>
1920
#include <linux/i2c.h>
2021
#include <linux/interrupt.h>
2122
#include <linux/kernel.h>
@@ -24,6 +25,7 @@
2425
#include <linux/module.h>
2526
#include <linux/of_device.h>
2627
#include <linux/regmap.h>
28+
#include <linux/syscore_ops.h>
2729

2830
struct rk808_reg_data {
2931
int addr;
@@ -812,7 +814,7 @@ static void rk808_device_shutdown_prepare(void)
812814
}
813815
}
814816

815-
static void rk808_device_shutdown(void)
817+
static void rk808_syscore_shutdown(void)
816818
{
817819
int ret;
818820
struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
@@ -830,13 +832,35 @@ static void rk808_device_shutdown(void)
830832
regmap_update_bits(rk808->regmap,
831833
RK808_RTC_INT_REG,
832834
(0x3 << 2), (0x0 << 2));
833-
if (pm_shutdown) {
834-
ret = pm_shutdown(rk808->regmap);
835-
if (ret)
836-
dev_err(&rk808_i2c_client->dev, "power off error!\n");
835+
/*
836+
* For PMIC that power off supplies by write register via i2c bus,
837+
* it's better to do power off at syscore shutdown here.
838+
*
839+
* Because when run to kernel's "pm_power_off" call, i2c may has
840+
* been stopped or PMIC may not be able to get i2c transfer while
841+
* there are too many devices are competiting.
842+
*/
843+
if (system_state == SYSTEM_POWER_OFF) {
844+
/* power off supplies ! */
845+
if (pm_shutdown) {
846+
dev_info(&rk808_i2c_client->dev, "System power off\n");
847+
ret = pm_shutdown(rk808->regmap);
848+
if (ret)
849+
dev_err(&rk808_i2c_client->dev,
850+
"System power off error!\n");
851+
mdelay(10);
852+
dev_info(&rk808_i2c_client->dev,
853+
"Cpu should never reach here, stop!\n");
854+
while (1)
855+
;
856+
}
837857
}
838858
}
839859

860+
static struct syscore_ops rk808_syscore_ops = {
861+
.shutdown = rk808_syscore_shutdown,
862+
};
863+
840864
static ssize_t rk8xx_dbg_store(struct device *dev,
841865
struct device_attribute *attr,
842866
const char *buf, size_t count)
@@ -1104,7 +1128,7 @@ static int rk808_probe(struct i2c_client *client,
11041128
}
11051129
if (pm_shutdown_fn) {
11061130
pm_shutdown = pm_shutdown_fn;
1107-
pm_power_off = rk808_device_shutdown;
1131+
register_syscore_ops(&rk808_syscore_ops);
11081132
}
11091133
}
11101134

@@ -1170,10 +1194,11 @@ static int rk808_remove(struct i2c_client *client)
11701194

11711195
regmap_del_irq_chip(client->irq, rk808->irq_data);
11721196
mfd_remove_devices(&client->dev);
1173-
if (pm_power_off == rk808_device_shutdown)
1174-
pm_power_off = NULL;
1197+
11751198
if (pm_power_off_prepare == rk808_device_shutdown_prepare)
11761199
pm_power_off_prepare = NULL;
1200+
if (pm_shutdown)
1201+
unregister_syscore_ops(&rk808_syscore_ops);
11771202

11781203
return 0;
11791204
}

0 commit comments

Comments
 (0)