Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: rk8xx-core: Allow to customize RK806 reset mode

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>
Link: https://lore.kernel.org/r/20250627-rk8xx-rst-fun-v4-2-ce05d041b45f@cherry.de
Signed-off-by: Lee Jones <lee@kernel.org>

authored by

Quentin Schulz and committed by
Lee Jones
db8db85c 404005d1

+14
+12
drivers/mfd/rk8xx-core.c
··· 10 10 * Author: Wadim Egorov <w.egorov@phytec.de> 11 11 */ 12 12 13 + #include <linux/bitfield.h> 13 14 #include <linux/interrupt.h> 14 15 #include <linux/mfd/rk808.h> 15 16 #include <linux/mfd/core.h> ··· 700 699 const struct mfd_cell *cells; 701 700 int dual_support = 0; 702 701 int nr_pre_init_regs; 702 + u32 rst_fun = 0; 703 703 int nr_cells; 704 704 int ret; 705 705 int i; ··· 728 726 cells = rk806s; 729 727 nr_cells = ARRAY_SIZE(rk806s); 730 728 dual_support = IRQF_SHARED; 729 + 730 + ret = device_property_read_u32(dev, "rockchip,reset-mode", &rst_fun); 731 + if (ret) 732 + break; 733 + 734 + ret = regmap_update_bits(rk808->regmap, RK806_SYS_CFG3, RK806_RST_FUN_MSK, 735 + FIELD_PREP(RK806_RST_FUN_MSK, rst_fun)); 736 + if (ret) 737 + return dev_err_probe(dev, ret, 738 + "Failed to configure requested restart/reset behavior\n"); 731 739 break; 732 740 case RK808_ID: 733 741 rk808->regmap_irq_chip = &rk808_irq_chip;
+2
include/linux/mfd/rk808.h
··· 812 812 #define RK806_INT_POL_H BIT(1) 813 813 #define RK806_INT_POL_L 0 814 814 815 + /* SYS_CFG3 */ 816 + #define RK806_RST_FUN_MSK GENMASK(7, 6) 815 817 #define RK806_SLAVE_RESTART_FUN_MSK BIT(1) 816 818 #define RK806_SLAVE_RESTART_FUN_EN BIT(1) 817 819 #define RK806_SLAVE_RESTART_FUN_OFF 0