diff options
author | Tony Xie <tony.xie@rock-chips.com> | 2018-04-17 15:27:32 +0800 |
---|---|---|
committer | Tao Huang <huangtao@rock-chips.com> | 2018-04-24 11:37:19 +0800 |
commit | 6e3ddcaf170335abb9e53b7ee143f65396ebb2d7 (patch) | |
tree | 62d029b639ea3beafa40827ab4e666bc59397351 /drivers/mfd | |
parent | cea2a68180efd9d06c93b8cc4b5f8d18af063be0 (diff) |
mfd: rk808: Set only resetting pmic register for 817&809.
If the system needs hold register values when system will reboot.
need to set only resetting pmic register for 817&809 forcedly.
Change-Id: Ib4b850c86ec3079cd7e374bc96460ee1532854a2
Signed-off-by: Tony Xie <tony.xie@rock-chips.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r-- | drivers/mfd/rk808.c | 51 |
1 files changed, 47 insertions, 4 deletions
diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c index c35477a8bfc8..d73fd528c88d 100644 --- a/drivers/mfd/rk808.c +++ b/drivers/mfd/rk808.c @@ -1,7 +1,7 @@ /* * MFD core driver for Rockchip RK808 * - * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd + * Copyright (c) 2014-2018, Fuzhou Rockchip Electronics Co., Ltd * * Author: Chris Zhong <zyw@rock-chips.com> * Author: Zhang Qing <zhangqing@rock-chips.com> @@ -24,6 +24,7 @@ #include <linux/mfd/core.h> #include <linux/module.h> #include <linux/of_device.h> +#include <linux/reboot.h> #include <linux/regmap.h> #include <linux/syscore_ops.h> @@ -1029,11 +1030,44 @@ static int rk817_pinctrl_init(struct device *dev, struct rk808 *rk808) return 0; } -static void rk817_of_property_prepare(struct regmap *regmap, struct device *dev) +struct rk817_reboot_data_t { + struct rk808 *rk808; + struct notifier_block reboot_notifier; +}; + +static struct rk817_reboot_data_t rk817_reboot_data; + +static int rk817_reboot_notifier_handler(struct notifier_block *nb, + unsigned long action, void *cmd) +{ + struct rk817_reboot_data_t *data; + int ret; + struct device *dev; + + if (action != SYS_RESTART) + return NOTIFY_OK; + + if (!cmd || !strlen(cmd) || !strcmp(cmd, "normal")) + return NOTIFY_OK; + + data = container_of(nb, struct rk817_reboot_data_t, reboot_notifier); + dev = &data->rk808->i2c->dev; + + ret = regmap_update_bits(data->rk808->regmap, RK817_SYS_CFG(3), + RK817_RST_FUNC_MSK, RK817_RST_FUNC_REG); + if (ret) + dev_err(dev, "reboot: force RK817_RST_FUNC_REG error!\n"); + else + dev_info(dev, "reboot: force RK817_RST_FUNC_REG ok!\n"); + return NOTIFY_OK; +} + +static void rk817_of_property_prepare(struct rk808 *rk808, struct device *dev) { u32 inner; int ret, func, msk, val; struct device_node *np = dev->of_node; + struct regmap *regmap = rk808->regmap; ret = of_property_read_u32_index(np, "fb-inner-reg-idxs", 0, &inner); if (!ret && inner == RK817_ID_DCDC3) @@ -1061,6 +1095,15 @@ static void rk817_of_property_prepare(struct regmap *regmap, struct device *dev) regmap_update_bits(regmap, RK817_SYS_CFG(3), msk, val); dev_info(dev, "support pmic reset mode:%d,%d\n", ret, func); + + if (val & RK817_RST_FUNC_REG) + return; + rk817_reboot_data.rk808 = rk808; + rk817_reboot_data.reboot_notifier.notifier_call = + rk817_reboot_notifier_handler; + ret = register_reboot_notifier(&rk817_reboot_data.reboot_notifier); + if (ret) + dev_err(dev, "failed to register reboot nb\n"); } static struct kobject *rk8xx_kobj; @@ -1095,7 +1138,7 @@ static int rk808_probe(struct i2c_client *client, int ret, i, pm_off = 0; unsigned int on, off; u8 pmic_id_msb = RK808_ID_MSB, pmic_id_lsb = RK808_ID_LSB; - void (*of_property_prepare_fn)(struct regmap *regmap, + void (*of_property_prepare_fn)(struct rk808 *rk808, struct device *dev) = NULL; int (*pinctrl_init)(struct device *dev, struct rk808 *rk808) = NULL; @@ -1246,7 +1289,7 @@ static int rk808_probe(struct i2c_client *client, } if (of_property_prepare_fn) - of_property_prepare_fn(rk808->regmap, &client->dev); + of_property_prepare_fn(rk808, &client->dev); i2c_set_clientdata(client, rk808); rk808->i2c = client; |