diff --git a/drivers/soc/rockchip/rockchip_pm_config.c b/drivers/soc/rockchip/rockchip_pm_config.c index 13427dd10820..3e9d6cab17c5 100644 --- a/drivers/soc/rockchip/rockchip_pm_config.c +++ b/drivers/soc/rockchip/rockchip_pm_config.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -51,11 +52,6 @@ static struct rk_on_off_regulator_list { } on_off_regs_list[RK_PM_STATE_MAX]; #endif -static struct rk_sleep_config { - u32 mode_config; - u32 wakeup_config; -} sleep_config[RK_PM_STATE_MAX]; - /* rk_tag related defines */ #define sleep_tag_next(t) \ ((struct rk_sleep_tag *)((__u32 *)(t) + (t)->hdr.size)) @@ -81,6 +77,8 @@ struct rk_mcu_sleep_tags { struct rk_sleep_tag slp_tags; }; +struct rk_sleep_config *sleep_config; + static const struct of_device_id pm_match_table[] = { { .compatible = "rockchip,pm-px30",}, { .compatible = "rockchip,pm-rk1808",}, @@ -253,6 +251,18 @@ static int parse_on_off_regulator(struct device_node *node, enum rk_pm_state sta return 0; } + +const struct rk_sleep_config *rockchip_get_cur_sleep_config(void) +{ + suspend_state_t suspend_state = mem_sleep_current; + enum rk_pm_state state = suspend_state - PM_SUSPEND_MEM; + + if (state >= RK_PM_STATE_MAX) + return NULL; + + return &sleep_config[state]; +} +EXPORT_SYMBOL_GPL(rockchip_get_cur_sleep_config); #endif static int parse_mcu_sleep_config(struct device_node *node) @@ -368,13 +378,7 @@ static int pm_config_probe(struct platform_device *pdev) { const struct of_device_id *match_id; struct device_node *node; - struct rk_sleep_config *config = &sleep_config[RK_PM_MEM]; - u32 pwm_regulator_config = 0; - int gpio_temp[10]; - u32 sleep_debug_en = 0; - u32 apios_suspend = 0; - u32 io_ret_config = 0; - u32 sleep_pin_config[2] = {0}; + struct rk_sleep_config *config; enum of_gpio_flags flags; int i = 0; @@ -392,6 +396,14 @@ static int pm_config_probe(struct platform_device *pdev) return -ENODEV; } + sleep_config = + devm_kmalloc_array(&pdev->dev, RK_PM_STATE_MAX, + sizeof(*sleep_config), GFP_KERNEL); + if (!sleep_config) + return -ENOMEM; + + config = &sleep_config[RK_PM_MEM]; + if (of_property_read_u32_array(node, "rockchip,sleep-mode-config", &config->mode_config, 1)) @@ -408,48 +420,56 @@ static int pm_config_probe(struct platform_device *pdev) if (of_property_read_u32_array(node, "rockchip,pwm-regulator-config", - &pwm_regulator_config, 1)) + &config->pwm_regulator_config, 1)) dev_warn(&pdev->dev, "not set pwm-regulator-config\n"); else sip_smc_set_suspend_mode(PWM_REGULATOR_CONFIG, - pwm_regulator_config, + config->pwm_regulator_config, 0); length = of_gpio_named_count(node, "rockchip,power-ctrl"); if (length > 0 && length < 10) { + config->power_ctrl_config_cnt = length; + config->power_ctrl_config = + devm_kmalloc_array(&pdev->dev, length, + sizeof(u32), GFP_KERNEL); + if (!config->power_ctrl_config) + return -ENOMEM; + for (i = 0; i < length; i++) { - gpio_temp[i] = of_get_named_gpio_flags(node, - "rockchip,power-ctrl", - i, - &flags); - if (!gpio_is_valid(gpio_temp[i])) + config->power_ctrl_config[i] = + of_get_named_gpio_flags(node, + "rockchip,power-ctrl", + i, + &flags); + if (!gpio_is_valid(config->power_ctrl_config[i])) break; sip_smc_set_suspend_mode(GPIO_POWER_CONFIG, i, - gpio_temp[i]); + config->power_ctrl_config[i]); } } sip_smc_set_suspend_mode(GPIO_POWER_CONFIG, i, PM_INVALID_GPIO); if (!of_property_read_u32_array(node, "rockchip,sleep-debug-en", - &sleep_debug_en, 1)) + &config->sleep_debug_en, 1)) sip_smc_set_suspend_mode(SUSPEND_DEBUG_ENABLE, - sleep_debug_en, + config->sleep_debug_en, 0); if (!of_property_read_u32_array(node, "rockchip,apios-suspend", - &apios_suspend, 1)) + &config->apios_suspend, 1)) sip_smc_set_suspend_mode(APIOS_SUSPEND_CONFIG, - apios_suspend, + config->apios_suspend, 0); if (!of_property_read_u32_array(node, "rockchip,sleep-io-ret-config", - &io_ret_config, 1)) { - ret = sip_smc_set_suspend_mode(SUSPEND_IO_RET_CONFIG, io_ret_config, 0); + &config->io_ret_config, 1)) { + ret = sip_smc_set_suspend_mode(SUSPEND_IO_RET_CONFIG, config->io_ret_config, 0); if (ret) dev_warn(&pdev->dev, "sleep-io-ret-config failed (%d), check parameters or update trust\n", @@ -458,8 +478,10 @@ static int pm_config_probe(struct platform_device *pdev) if (!of_property_read_u32_array(node, "rockchip,sleep-pin-config", - sleep_pin_config, 2)) { - ret = sip_smc_set_suspend_mode(SLEEP_PIN_CONFIG, sleep_pin_config[0], sleep_pin_config[1]); + config->sleep_pin_config, 2)) { + ret = sip_smc_set_suspend_mode(SLEEP_PIN_CONFIG, + config->sleep_pin_config[0], + config->sleep_pin_config[1]); if (ret) dev_warn(&pdev->dev, "sleep-pin-config failed (%d), check parameters or update trust\n", diff --git a/include/linux/rockchip/rockchip_pm_config.h b/include/linux/rockchip/rockchip_pm_config.h new file mode 100644 index 000000000000..f77e5c66928e --- /dev/null +++ b/include/linux/rockchip/rockchip_pm_config.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2023 Rockchip Electronics Co., Ltd. + */ + +#ifndef __ROCKCHIP_PM_CONFIG_H +#define __ROCKCHIP_PM_CONFIG_H + +struct rk_sleep_config { + u32 mode_config; + u32 wakeup_config; + u32 sleep_debug_en; + u32 pwm_regulator_config; + u32 *power_ctrl_config; + u32 power_ctrl_config_cnt; + u32 apios_suspend; + u32 io_ret_config; + u32 sleep_pin_config[2]; +}; + +#if IS_REACHABLE(CONFIG_ROCKCHIP_SUSPEND_MODE) +const struct rk_sleep_config *rockchip_get_cur_sleep_config(void); +#else +static inline const struct rk_sleep_config *rockchip_get_cur_sleep_config(void) +{ + return NULL; +} +#endif + +#endif /* __ROCKCHIP_PM_CONFIG_H */