|
1 | 1 | /* |
2 | 2 | * MFD core driver for Rockchip RK808 |
3 | 3 | * |
4 | | - * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd |
| 4 | + * Copyright (c) 2014-2018, Fuzhou Rockchip Electronics Co., Ltd |
5 | 5 | * |
6 | 6 | * Author: Chris Zhong <zyw@rock-chips.com> |
7 | 7 | * Author: Zhang Qing <zhangqing@rock-chips.com> |
|
24 | 24 | #include <linux/mfd/core.h> |
25 | 25 | #include <linux/module.h> |
26 | 26 | #include <linux/of_device.h> |
| 27 | +#include <linux/reboot.h> |
27 | 28 | #include <linux/regmap.h> |
28 | 29 | #include <linux/syscore_ops.h> |
29 | 30 |
|
@@ -1029,11 +1030,44 @@ static int rk817_pinctrl_init(struct device *dev, struct rk808 *rk808) |
1029 | 1030 | return 0; |
1030 | 1031 | } |
1031 | 1032 |
|
1032 | | -static void rk817_of_property_prepare(struct regmap *regmap, struct device *dev) |
| 1033 | +struct rk817_reboot_data_t { |
| 1034 | + struct rk808 *rk808; |
| 1035 | + struct notifier_block reboot_notifier; |
| 1036 | +}; |
| 1037 | + |
| 1038 | +static struct rk817_reboot_data_t rk817_reboot_data; |
| 1039 | + |
| 1040 | +static int rk817_reboot_notifier_handler(struct notifier_block *nb, |
| 1041 | + unsigned long action, void *cmd) |
| 1042 | +{ |
| 1043 | + struct rk817_reboot_data_t *data; |
| 1044 | + int ret; |
| 1045 | + struct device *dev; |
| 1046 | + |
| 1047 | + if (action != SYS_RESTART) |
| 1048 | + return NOTIFY_OK; |
| 1049 | + |
| 1050 | + if (!cmd || !strlen(cmd) || !strcmp(cmd, "normal")) |
| 1051 | + return NOTIFY_OK; |
| 1052 | + |
| 1053 | + data = container_of(nb, struct rk817_reboot_data_t, reboot_notifier); |
| 1054 | + dev = &data->rk808->i2c->dev; |
| 1055 | + |
| 1056 | + ret = regmap_update_bits(data->rk808->regmap, RK817_SYS_CFG(3), |
| 1057 | + RK817_RST_FUNC_MSK, RK817_RST_FUNC_REG); |
| 1058 | + if (ret) |
| 1059 | + dev_err(dev, "reboot: force RK817_RST_FUNC_REG error!\n"); |
| 1060 | + else |
| 1061 | + dev_info(dev, "reboot: force RK817_RST_FUNC_REG ok!\n"); |
| 1062 | + return NOTIFY_OK; |
| 1063 | +} |
| 1064 | + |
| 1065 | +static void rk817_of_property_prepare(struct rk808 *rk808, struct device *dev) |
1033 | 1066 | { |
1034 | 1067 | u32 inner; |
1035 | 1068 | int ret, func, msk, val; |
1036 | 1069 | struct device_node *np = dev->of_node; |
| 1070 | + struct regmap *regmap = rk808->regmap; |
1037 | 1071 |
|
1038 | 1072 | ret = of_property_read_u32_index(np, "fb-inner-reg-idxs", 0, &inner); |
1039 | 1073 | if (!ret && inner == RK817_ID_DCDC3) |
@@ -1061,6 +1095,15 @@ static void rk817_of_property_prepare(struct regmap *regmap, struct device *dev) |
1061 | 1095 | regmap_update_bits(regmap, RK817_SYS_CFG(3), msk, val); |
1062 | 1096 |
|
1063 | 1097 | dev_info(dev, "support pmic reset mode:%d,%d\n", ret, func); |
| 1098 | + |
| 1099 | + if (val & RK817_RST_FUNC_REG) |
| 1100 | + return; |
| 1101 | + rk817_reboot_data.rk808 = rk808; |
| 1102 | + rk817_reboot_data.reboot_notifier.notifier_call = |
| 1103 | + rk817_reboot_notifier_handler; |
| 1104 | + ret = register_reboot_notifier(&rk817_reboot_data.reboot_notifier); |
| 1105 | + if (ret) |
| 1106 | + dev_err(dev, "failed to register reboot nb\n"); |
1064 | 1107 | } |
1065 | 1108 |
|
1066 | 1109 | static struct kobject *rk8xx_kobj; |
@@ -1095,7 +1138,7 @@ static int rk808_probe(struct i2c_client *client, |
1095 | 1138 | int ret, i, pm_off = 0; |
1096 | 1139 | unsigned int on, off; |
1097 | 1140 | u8 pmic_id_msb = RK808_ID_MSB, pmic_id_lsb = RK808_ID_LSB; |
1098 | | - void (*of_property_prepare_fn)(struct regmap *regmap, |
| 1141 | + void (*of_property_prepare_fn)(struct rk808 *rk808, |
1099 | 1142 | struct device *dev) = NULL; |
1100 | 1143 | int (*pinctrl_init)(struct device *dev, struct rk808 *rk808) = NULL; |
1101 | 1144 |
|
@@ -1246,7 +1289,7 @@ static int rk808_probe(struct i2c_client *client, |
1246 | 1289 | } |
1247 | 1290 |
|
1248 | 1291 | if (of_property_prepare_fn) |
1249 | | - of_property_prepare_fn(rk808->regmap, &client->dev); |
| 1292 | + of_property_prepare_fn(rk808, &client->dev); |
1250 | 1293 |
|
1251 | 1294 | i2c_set_clientdata(client, rk808); |
1252 | 1295 | rk808->i2c = client; |
|
0 commit comments