[PATCH v2 2/4] mfd: rk8xx-core: allow to customize RK806 reset mode

Quentin Schulz posted 4 patches 6 months, 2 weeks ago
There is a newer version of this series
[PATCH v2 2/4] mfd: rk8xx-core: allow to customize RK806 reset mode
Posted by Quentin Schulz 6 months, 2 weeks ago
From: Quentin Schulz <quentin.schulz@cherry.de>

The RK806 PMIC has a bitfield for configuring the restart/reset behavior
(which I assume Rockchip calls "function") whenever the PMIC is reset
either programmatically (c.f. DEV_RST in the datasheet) or via PWRCTRL
or RESETB pins.

For RK806, the following values are possible for RST_FUN:

0b00 means "restart PMU"
0b01 means "Reset all the power off reset registers, forcing
	the state to switch to ACTIVE mode"
0b10 means "Reset all the power off reset registers, forcing
	the state to switch to ACTIVE mode, and simultaneously
	pull down the RESETB PIN for 5mS before releasing"
0b11 means the same as for 0b10 just above.

This adds the appropriate logic in the driver to parse the new
rockchip,reset-mode DT property to pass this information. It just
happens that the values in the binding match the values to write in the
bitfield so no mapping is necessary.

If it is missing, the register is left untouched and relies either on
the silicon default or on whatever was set earlier in the boot stages
(e.g. the bootloader).

Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
---
 drivers/mfd/rk8xx-core.c  | 14 ++++++++++++++
 include/linux/mfd/rk808.h |  2 ++
 2 files changed, 16 insertions(+)

diff --git a/drivers/mfd/rk8xx-core.c b/drivers/mfd/rk8xx-core.c
index 71c2b80a4678d627e86cfbec8135f08e262559d3..32294af0b843fa20677513b1e1a5a6c8e76be4b6 100644
--- a/drivers/mfd/rk8xx-core.c
+++ b/drivers/mfd/rk8xx-core.c
@@ -699,6 +699,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
 	const struct mfd_cell *cells;
 	int dual_support = 0;
 	int nr_pre_init_regs;
+	u32 rst_fun = 0;
 	int nr_cells;
 	int ret;
 	int i;
@@ -726,6 +727,19 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
 		cells = rk806s;
 		nr_cells = ARRAY_SIZE(rk806s);
 		dual_support = IRQF_SHARED;
+
+		ret = device_property_read_u32(dev, "rockchip,reset-mode", &rst_fun);
+		if (ret) {
+			dev_dbg(dev,
+				"rockchip,reset-mode property missing, not setting RST_FUN\n");
+			break;
+		}
+
+		ret = regmap_update_bits(rk808->regmap, RK806_SYS_CFG3,
+					 RK806_RST_FUN_MSK,
+					 FIELD_PREP(RK806_RST_FUN_MSK, rst_fun));
+		if (ret)
+			return dev_err_probe(dev, ret, "RST_FUN write err\n");
 		break;
 	case RK808_ID:
 		rk808->regmap_irq_chip = &rk808_irq_chip;
diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
index 69cbea78b430b562a23d995263369d475daa6287..28170ee08898ca59c76a741a1d42763a42b72380 100644
--- a/include/linux/mfd/rk808.h
+++ b/include/linux/mfd/rk808.h
@@ -812,6 +812,8 @@ enum rk806_pin_dr_sel {
 #define RK806_INT_POL_H			BIT(1)
 #define RK806_INT_POL_L			0
 
+/* SYS_CFG3 */
+#define RK806_RST_FUN_MSK		GENMASK(7, 6)
 #define RK806_SLAVE_RESTART_FUN_MSK	BIT(1)
 #define RK806_SLAVE_RESTART_FUN_EN	BIT(1)
 #define RK806_SLAVE_RESTART_FUN_OFF	0

-- 
2.49.0
Re: [PATCH v2 2/4] mfd: rk8xx-core: allow to customize RK806 reset mode
Posted by kernel test robot 6 months, 2 weeks ago
Hi Quentin,

kernel test robot noticed the following build errors:

[auto build test ERROR on ec7714e4947909190ffb3041a03311a975350fe0]

url:    https://github.com/intel-lab-lkp/linux/commits/Quentin-Schulz/dt-bindings-mfd-rk806-allow-to-customize-PMIC-reset-mode/20250605-234243
base:   ec7714e4947909190ffb3041a03311a975350fe0
patch link:    https://lore.kernel.org/r/20250605-rk8xx-rst-fun-v2-2-143d190596dd%40cherry.de
patch subject: [PATCH v2 2/4] mfd: rk8xx-core: allow to customize RK806 reset mode
config: arc-randconfig-001-20250607 (https://download.01.org/0day-ci/archive/20250607/202506071321.Ze0gsxC0-lkp@intel.com/config)
compiler: arc-linux-gcc (GCC) 15.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250607/202506071321.Ze0gsxC0-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202506071321.Ze0gsxC0-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/mfd/rk8xx-core.c: In function 'rk8xx_probe':
>> drivers/mfd/rk8xx-core.c:740:42: error: implicit declaration of function 'FIELD_PREP' [-Wimplicit-function-declaration]
     740 |                                          FIELD_PREP(RK806_RST_FUN_MSK, rst_fun));
         |                                          ^~~~~~~~~~


vim +/FIELD_PREP +740 drivers/mfd/rk8xx-core.c

   694	
   695	int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap *regmap)
   696	{
   697		struct rk808 *rk808;
   698		const struct rk808_reg_data *pre_init_reg;
   699		const struct mfd_cell *cells;
   700		int dual_support = 0;
   701		int nr_pre_init_regs;
   702		u32 rst_fun = 0;
   703		int nr_cells;
   704		int ret;
   705		int i;
   706	
   707		rk808 = devm_kzalloc(dev, sizeof(*rk808), GFP_KERNEL);
   708		if (!rk808)
   709			return -ENOMEM;
   710		rk808->dev = dev;
   711		rk808->variant = variant;
   712		rk808->regmap = regmap;
   713		dev_set_drvdata(dev, rk808);
   714	
   715		switch (rk808->variant) {
   716		case RK805_ID:
   717			rk808->regmap_irq_chip = &rk805_irq_chip;
   718			pre_init_reg = rk805_pre_init_reg;
   719			nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg);
   720			cells = rk805s;
   721			nr_cells = ARRAY_SIZE(rk805s);
   722			break;
   723		case RK806_ID:
   724			rk808->regmap_irq_chip = &rk806_irq_chip;
   725			pre_init_reg = rk806_pre_init_reg;
   726			nr_pre_init_regs = ARRAY_SIZE(rk806_pre_init_reg);
   727			cells = rk806s;
   728			nr_cells = ARRAY_SIZE(rk806s);
   729			dual_support = IRQF_SHARED;
   730	
   731			ret = device_property_read_u32(dev, "rockchip,reset-mode", &rst_fun);
   732			if (ret) {
   733				dev_dbg(dev,
   734					"rockchip,reset-mode property missing, not setting RST_FUN\n");
   735				break;
   736			}
   737	
   738			ret = regmap_update_bits(rk808->regmap, RK806_SYS_CFG3,
   739						 RK806_RST_FUN_MSK,
 > 740						 FIELD_PREP(RK806_RST_FUN_MSK, rst_fun));
   741			if (ret)
   742				return dev_err_probe(dev, ret, "RST_FUN write err\n");
   743			break;
   744		case RK808_ID:
   745			rk808->regmap_irq_chip = &rk808_irq_chip;
   746			pre_init_reg = rk808_pre_init_reg;
   747			nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg);
   748			cells = rk808s;
   749			nr_cells = ARRAY_SIZE(rk808s);
   750			break;
   751		case RK816_ID:
   752			rk808->regmap_irq_chip = &rk816_irq_chip;
   753			pre_init_reg = rk816_pre_init_reg;
   754			nr_pre_init_regs = ARRAY_SIZE(rk816_pre_init_reg);
   755			cells = rk816s;
   756			nr_cells = ARRAY_SIZE(rk816s);
   757			break;
   758		case RK818_ID:
   759			rk808->regmap_irq_chip = &rk818_irq_chip;
   760			pre_init_reg = rk818_pre_init_reg;
   761			nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg);
   762			cells = rk818s;
   763			nr_cells = ARRAY_SIZE(rk818s);
   764			break;
   765		case RK809_ID:
   766		case RK817_ID:
   767			rk808->regmap_irq_chip = &rk817_irq_chip;
   768			pre_init_reg = rk817_pre_init_reg;
   769			nr_pre_init_regs = ARRAY_SIZE(rk817_pre_init_reg);
   770			cells = rk817s;
   771			nr_cells = ARRAY_SIZE(rk817s);
   772			break;
   773		default:
   774			dev_err(dev, "Unsupported RK8XX ID %lu\n", rk808->variant);
   775			return -EINVAL;
   776		}
   777	
   778		if (!irq)
   779			return dev_err_probe(dev, -EINVAL, "No interrupt support, no core IRQ\n");
   780	
   781		ret = devm_regmap_add_irq_chip(dev, rk808->regmap, irq,
   782					       IRQF_ONESHOT | dual_support, -1,
   783					       rk808->regmap_irq_chip, &rk808->irq_data);
   784		if (ret)
   785			return dev_err_probe(dev, ret, "Failed to add irq_chip\n");
   786	
   787		for (i = 0; i < nr_pre_init_regs; i++) {
   788			ret = regmap_update_bits(rk808->regmap,
   789						pre_init_reg[i].addr,
   790						pre_init_reg[i].mask,
   791						pre_init_reg[i].value);
   792			if (ret)
   793				return dev_err_probe(dev, ret, "0x%x write err\n",
   794						     pre_init_reg[i].addr);
   795		}
   796	
   797		ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, cells, nr_cells, NULL, 0,
   798				      regmap_irq_get_domain(rk808->irq_data));
   799		if (ret)
   800			return dev_err_probe(dev, ret, "failed to add MFD devices\n");
   801	
   802		if (device_property_read_bool(dev, "system-power-controller") ||
   803		    device_property_read_bool(dev, "rockchip,system-power-controller")) {
   804			ret = devm_register_sys_off_handler(dev,
   805					    SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_PRIO_HIGH,
   806					    &rk808_power_off, rk808);
   807			if (ret)
   808				return dev_err_probe(dev, ret,
   809						     "failed to register poweroff handler\n");
   810	
   811			switch (rk808->variant) {
   812			case RK809_ID:
   813			case RK817_ID:
   814				ret = devm_register_sys_off_handler(dev,
   815								    SYS_OFF_MODE_RESTART, SYS_OFF_PRIO_HIGH,
   816								    &rk808_restart, rk808);
   817				if (ret)
   818					dev_warn(dev, "failed to register rst handler, %d\n", ret);
   819				break;
   820			default:
   821				dev_dbg(dev, "pmic controlled board reset not supported\n");
   822				break;
   823			}
   824		}
   825	
   826		return 0;
   827	}
   828	EXPORT_SYMBOL_GPL(rk8xx_probe);
   829	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH v2 2/4] mfd: rk8xx-core: allow to customize RK806 reset mode
Posted by Quentin Schulz 6 months, 1 week ago
Hi all,

On 6/7/25 7:46 AM, kernel test robot wrote:
> Hi Quentin,
> 
> kernel test robot noticed the following build errors:
> 
> [auto build test ERROR on ec7714e4947909190ffb3041a03311a975350fe0]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Quentin-Schulz/dt-bindings-mfd-rk806-allow-to-customize-PMIC-reset-mode/20250605-234243
> base:   ec7714e4947909190ffb3041a03311a975350fe0
> patch link:    https://lore.kernel.org/r/20250605-rk8xx-rst-fun-v2-2-143d190596dd%40cherry.de
> patch subject: [PATCH v2 2/4] mfd: rk8xx-core: allow to customize RK806 reset mode
> config: arc-randconfig-001-20250607 (https://download.01.org/0day-ci/archive/20250607/202506071321.Ze0gsxC0-lkp@intel.com/config)
> compiler: arc-linux-gcc (GCC) 15.1.0
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250607/202506071321.Ze0gsxC0-lkp@intel.com/reproduce)
> 
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202506071321.Ze0gsxC0-lkp@intel.com/
> 
> All errors (new ones prefixed by >>):
> 
>     drivers/mfd/rk8xx-core.c: In function 'rk8xx_probe':
>>> drivers/mfd/rk8xx-core.c:740:42: error: implicit declaration of function 'FIELD_PREP' [-Wimplicit-function-declaration]

This should be simply fixed with the addition of

#include <linux/bitfield.h>

Though somehow I cannot reproduce the error locally as I get:

COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-15.1.0 
~/work/upstream/lkp-tests/kbuild/make.cross W=1 O=build/0day ARCH=arc 
olddefconfig
Compiler will be installed in /home/qschulz/0day
lftpget -c 
https://cdn.kernel.org/pub/tools/crosstool/files/bin/x86_64/15.1.0/x86_64-gcc-15.1.0-nolibc-sparc-linux.tar.xz
/home/qschulz/work/upstream/linux
tar Jxf 
/home/qschulz/0day/15.1.0/x86_64-gcc-15.1.0-nolibc-sparc-linux.tar.xz -C 
/home/qschulz/0day
No gcc cross compiler for arc
setup_crosstool failed

But I'm pretty sure that should be enough to fix it :)

Since it's a minor change, I'll give this v2 some time on the ML to 
hopefully gather some feedback before I send a v3.

Cheers,
Quentin