Loading drivers/regulator/core.c +23 −0 Original line number Diff line number Diff line Loading @@ -4105,6 +4105,29 @@ int regulator_set_voltage_time_sel(struct regulator_dev *rdev, } EXPORT_SYMBOL_GPL(regulator_set_voltage_time_sel); int regulator_sync_voltage_rdev(struct regulator_dev *rdev) { int ret; regulator_lock(rdev); if (!rdev->desc->ops->set_voltage && !rdev->desc->ops->set_voltage_sel) { ret = -EINVAL; goto out; } /* balance only, if regulator is coupled */ if (rdev->coupling_desc.n_coupled > 1) ret = regulator_balance_voltage(rdev, PM_SUSPEND_ON); else ret = -EOPNOTSUPP; out: regulator_unlock(rdev); return ret; } /** * regulator_sync_voltage - re-apply last regulator output voltage * @regulator: regulator source Loading drivers/soc/tegra/common.c +97 −0 Original line number Diff line number Diff line Loading @@ -3,9 +3,16 @@ * Copyright (C) 2014 NVIDIA CORPORATION. All rights reserved. */ #define dev_fmt(fmt) "tegra-soc: " fmt #include <linux/clk.h> #include <linux/device.h> #include <linux/export.h> #include <linux/of.h> #include <linux/pm_opp.h> #include <soc/tegra/common.h> #include <soc/tegra/fuse.h> static const struct of_device_id tegra_machine_match[] = { { .compatible = "nvidia,tegra20", }, Loading @@ -31,3 +38,93 @@ bool soc_is_tegra(void) return match != NULL; } static int tegra_core_dev_init_opp_state(struct device *dev) { unsigned long rate; struct clk *clk; int err; clk = devm_clk_get(dev, NULL); if (IS_ERR(clk)) { dev_err(dev, "failed to get clk: %pe\n", clk); return PTR_ERR(clk); } rate = clk_get_rate(clk); if (!rate) { dev_err(dev, "failed to get clk rate\n"); return -EINVAL; } /* first dummy rate-setting initializes voltage vote */ err = dev_pm_opp_set_rate(dev, rate); if (err) { dev_err(dev, "failed to initialize OPP clock: %d\n", err); return err; } return 0; } /** * devm_tegra_core_dev_init_opp_table() - initialize OPP table * @dev: device for which OPP table is initialized * @params: pointer to the OPP table configuration * * This function will initialize OPP table and sync OPP state of a Tegra SoC * core device. * * Return: 0 on success or errorno. */ int devm_tegra_core_dev_init_opp_table(struct device *dev, struct tegra_core_opp_params *params) { u32 hw_version; int err; err = devm_pm_opp_set_clkname(dev, NULL); if (err) { dev_err(dev, "failed to set OPP clk: %d\n", err); return err; } /* Tegra114+ doesn't support OPP yet */ if (!of_machine_is_compatible("nvidia,tegra20") && !of_machine_is_compatible("nvidia,tegra30")) return -ENODEV; if (of_machine_is_compatible("nvidia,tegra20")) hw_version = BIT(tegra_sku_info.soc_process_id); else hw_version = BIT(tegra_sku_info.soc_speedo_id); err = devm_pm_opp_set_supported_hw(dev, &hw_version, 1); if (err) { dev_err(dev, "failed to set OPP supported HW: %d\n", err); return err; } /* * Older device-trees have an empty OPP table, we will get * -ENODEV from devm_pm_opp_of_add_table() in this case. */ err = devm_pm_opp_of_add_table(dev); if (err) { if (err == -ENODEV) dev_err_once(dev, "OPP table not found, please update device-tree\n"); else dev_err(dev, "failed to add OPP table: %d\n", err); return err; } if (params->init_state) { err = tegra_core_dev_init_opp_state(dev); if (err) return err; } return 0; } EXPORT_SYMBOL_GPL(devm_tegra_core_dev_init_opp_table); drivers/soc/tegra/regulators-tegra20.c +74 −1 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include <linux/init.h> #include <linux/kernel.h> #include <linux/of.h> #include <linux/reboot.h> #include <linux/regulator/coupler.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> Loading @@ -21,7 +22,10 @@ struct tegra_regulator_coupler { struct regulator_dev *core_rdev; struct regulator_dev *cpu_rdev; struct regulator_dev *rtc_rdev; int core_min_uV; struct notifier_block reboot_notifier; int core_min_uV, cpu_min_uV; bool sys_reboot_mode_req; bool sys_reboot_mode; }; static inline struct tegra_regulator_coupler * Loading Loading @@ -242,6 +246,10 @@ static int tegra20_cpu_voltage_update(struct tegra_regulator_coupler *tegra, if (cpu_uV < 0) return cpu_uV; /* store boot voltage level */ if (!tegra->cpu_min_uV) tegra->cpu_min_uV = cpu_uV; /* * CPU's regulator may not have any consumers, hence the voltage * must not be changed in that case because CPU simply won't Loading @@ -250,6 +258,10 @@ static int tegra20_cpu_voltage_update(struct tegra_regulator_coupler *tegra, if (!cpu_min_uV_consumers) cpu_min_uV = cpu_uV; /* restore boot voltage level */ if (tegra->sys_reboot_mode) cpu_min_uV = max(cpu_min_uV, tegra->cpu_min_uV); if (cpu_min_uV > cpu_uV) { err = tegra20_core_rtc_update(tegra, core_rdev, rtc_rdev, cpu_uV, cpu_min_uV); Loading Loading @@ -290,6 +302,8 @@ static int tegra20_regulator_balance_voltage(struct regulator_coupler *coupler, return -EINVAL; } tegra->sys_reboot_mode = READ_ONCE(tegra->sys_reboot_mode_req); if (rdev == cpu_rdev) return tegra20_cpu_voltage_update(tegra, cpu_rdev, core_rdev, rtc_rdev); Loading @@ -303,6 +317,51 @@ static int tegra20_regulator_balance_voltage(struct regulator_coupler *coupler, return -EPERM; } static int tegra20_regulator_prepare_reboot(struct tegra_regulator_coupler *tegra, bool sys_reboot_mode) { int err; if (!tegra->core_rdev || !tegra->rtc_rdev || !tegra->cpu_rdev) return 0; WRITE_ONCE(tegra->sys_reboot_mode_req, true); /* * Some devices use CPU soft-reboot method and in this case we * should ensure that voltages are sane for the reboot by restoring * the minimum boot levels. */ err = regulator_sync_voltage_rdev(tegra->cpu_rdev); if (err) return err; err = regulator_sync_voltage_rdev(tegra->core_rdev); if (err) return err; WRITE_ONCE(tegra->sys_reboot_mode_req, sys_reboot_mode); return 0; } static int tegra20_regulator_reboot(struct notifier_block *notifier, unsigned long event, void *cmd) { struct tegra_regulator_coupler *tegra; int ret; if (event != SYS_RESTART) return NOTIFY_DONE; tegra = container_of(notifier, struct tegra_regulator_coupler, reboot_notifier); ret = tegra20_regulator_prepare_reboot(tegra, true); return notifier_from_errno(ret); } static int tegra20_regulator_attach(struct regulator_coupler *coupler, struct regulator_dev *rdev) { Loading Loading @@ -335,6 +394,14 @@ static int tegra20_regulator_detach(struct regulator_coupler *coupler, { struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler); /* * We don't expect regulators to be decoupled during reboot, * this may race with the reboot handler and shouldn't ever * happen in practice. */ if (WARN_ON_ONCE(system_state > SYSTEM_RUNNING)) return -EPERM; if (tegra->core_rdev == rdev) { tegra->core_rdev = NULL; return 0; Loading @@ -359,13 +426,19 @@ static struct tegra_regulator_coupler tegra20_coupler = { .detach_regulator = tegra20_regulator_detach, .balance_voltage = tegra20_regulator_balance_voltage, }, .reboot_notifier.notifier_call = tegra20_regulator_reboot, }; static int __init tegra_regulator_coupler_init(void) { int err; if (!of_machine_is_compatible("nvidia,tegra20")) return 0; err = register_reboot_notifier(&tegra20_coupler.reboot_notifier); WARN_ON(err); return regulator_coupler_register(&tegra20_coupler.coupler); } arch_initcall(tegra_regulator_coupler_init); drivers/soc/tegra/regulators-tegra30.c +74 −1 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include <linux/init.h> #include <linux/kernel.h> #include <linux/of.h> #include <linux/reboot.h> #include <linux/regulator/coupler.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> Loading @@ -22,7 +23,10 @@ struct tegra_regulator_coupler { struct regulator_coupler coupler; struct regulator_dev *core_rdev; struct regulator_dev *cpu_rdev; int core_min_uV; struct notifier_block reboot_notifier; int core_min_uV, cpu_min_uV; bool sys_reboot_mode_req; bool sys_reboot_mode; }; static inline struct tegra_regulator_coupler * Loading Loading @@ -172,6 +176,10 @@ static int tegra30_voltage_update(struct tegra_regulator_coupler *tegra, if (cpu_uV < 0) return cpu_uV; /* store boot voltage level */ if (!tegra->cpu_min_uV) tegra->cpu_min_uV = cpu_uV; /* * CPU's regulator may not have any consumers, hence the voltage * must not be changed in that case because CPU simply won't Loading @@ -195,6 +203,10 @@ static int tegra30_voltage_update(struct tegra_regulator_coupler *tegra, if (err) return err; /* restore boot voltage level */ if (tegra->sys_reboot_mode) cpu_min_uV = max(cpu_min_uV, tegra->cpu_min_uV); if (core_min_limited_uV > core_uV) { pr_err("core voltage constraint violated: %d %d %d\n", core_uV, core_min_limited_uV, cpu_uV); Loading Loading @@ -263,9 +275,56 @@ static int tegra30_regulator_balance_voltage(struct regulator_coupler *coupler, return -EINVAL; } tegra->sys_reboot_mode = READ_ONCE(tegra->sys_reboot_mode_req); return tegra30_voltage_update(tegra, cpu_rdev, core_rdev); } static int tegra30_regulator_prepare_reboot(struct tegra_regulator_coupler *tegra, bool sys_reboot_mode) { int err; if (!tegra->core_rdev || !tegra->cpu_rdev) return 0; WRITE_ONCE(tegra->sys_reboot_mode_req, true); /* * Some devices use CPU soft-reboot method and in this case we * should ensure that voltages are sane for the reboot by restoring * the minimum boot levels. */ err = regulator_sync_voltage_rdev(tegra->cpu_rdev); if (err) return err; err = regulator_sync_voltage_rdev(tegra->core_rdev); if (err) return err; WRITE_ONCE(tegra->sys_reboot_mode_req, sys_reboot_mode); return 0; } static int tegra30_regulator_reboot(struct notifier_block *notifier, unsigned long event, void *cmd) { struct tegra_regulator_coupler *tegra; int ret; if (event != SYS_RESTART) return NOTIFY_DONE; tegra = container_of(notifier, struct tegra_regulator_coupler, reboot_notifier); ret = tegra30_regulator_prepare_reboot(tegra, true); return notifier_from_errno(ret); } static int tegra30_regulator_attach(struct regulator_coupler *coupler, struct regulator_dev *rdev) { Loading @@ -292,6 +351,14 @@ static int tegra30_regulator_detach(struct regulator_coupler *coupler, { struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler); /* * We don't expect regulators to be decoupled during reboot, * this may race with the reboot handler and shouldn't ever * happen in practice. */ if (WARN_ON_ONCE(system_state > SYSTEM_RUNNING)) return -EPERM; if (tegra->core_rdev == rdev) { tegra->core_rdev = NULL; return 0; Loading @@ -311,13 +378,19 @@ static struct tegra_regulator_coupler tegra30_coupler = { .detach_regulator = tegra30_regulator_detach, .balance_voltage = tegra30_regulator_balance_voltage, }, .reboot_notifier.notifier_call = tegra30_regulator_reboot, }; static int __init tegra_regulator_coupler_init(void) { int err; if (!of_machine_is_compatible("nvidia,tegra30")) return 0; err = register_reboot_notifier(&tegra30_coupler.reboot_notifier); WARN_ON(err); return regulator_coupler_register(&tegra30_coupler.coupler); } arch_initcall(tegra_regulator_coupler_init); include/linux/regulator/driver.h +1 −0 Original line number Diff line number Diff line Loading @@ -540,6 +540,7 @@ int regulator_set_current_limit_regmap(struct regulator_dev *rdev, int regulator_get_current_limit_regmap(struct regulator_dev *rdev); void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data); int regulator_set_ramp_delay_regmap(struct regulator_dev *rdev, int ramp_delay); int regulator_sync_voltage_rdev(struct regulator_dev *rdev); /* * Helper functions intended to be used by regulator drivers prior registering Loading Loading
drivers/regulator/core.c +23 −0 Original line number Diff line number Diff line Loading @@ -4105,6 +4105,29 @@ int regulator_set_voltage_time_sel(struct regulator_dev *rdev, } EXPORT_SYMBOL_GPL(regulator_set_voltage_time_sel); int regulator_sync_voltage_rdev(struct regulator_dev *rdev) { int ret; regulator_lock(rdev); if (!rdev->desc->ops->set_voltage && !rdev->desc->ops->set_voltage_sel) { ret = -EINVAL; goto out; } /* balance only, if regulator is coupled */ if (rdev->coupling_desc.n_coupled > 1) ret = regulator_balance_voltage(rdev, PM_SUSPEND_ON); else ret = -EOPNOTSUPP; out: regulator_unlock(rdev); return ret; } /** * regulator_sync_voltage - re-apply last regulator output voltage * @regulator: regulator source Loading
drivers/soc/tegra/common.c +97 −0 Original line number Diff line number Diff line Loading @@ -3,9 +3,16 @@ * Copyright (C) 2014 NVIDIA CORPORATION. All rights reserved. */ #define dev_fmt(fmt) "tegra-soc: " fmt #include <linux/clk.h> #include <linux/device.h> #include <linux/export.h> #include <linux/of.h> #include <linux/pm_opp.h> #include <soc/tegra/common.h> #include <soc/tegra/fuse.h> static const struct of_device_id tegra_machine_match[] = { { .compatible = "nvidia,tegra20", }, Loading @@ -31,3 +38,93 @@ bool soc_is_tegra(void) return match != NULL; } static int tegra_core_dev_init_opp_state(struct device *dev) { unsigned long rate; struct clk *clk; int err; clk = devm_clk_get(dev, NULL); if (IS_ERR(clk)) { dev_err(dev, "failed to get clk: %pe\n", clk); return PTR_ERR(clk); } rate = clk_get_rate(clk); if (!rate) { dev_err(dev, "failed to get clk rate\n"); return -EINVAL; } /* first dummy rate-setting initializes voltage vote */ err = dev_pm_opp_set_rate(dev, rate); if (err) { dev_err(dev, "failed to initialize OPP clock: %d\n", err); return err; } return 0; } /** * devm_tegra_core_dev_init_opp_table() - initialize OPP table * @dev: device for which OPP table is initialized * @params: pointer to the OPP table configuration * * This function will initialize OPP table and sync OPP state of a Tegra SoC * core device. * * Return: 0 on success or errorno. */ int devm_tegra_core_dev_init_opp_table(struct device *dev, struct tegra_core_opp_params *params) { u32 hw_version; int err; err = devm_pm_opp_set_clkname(dev, NULL); if (err) { dev_err(dev, "failed to set OPP clk: %d\n", err); return err; } /* Tegra114+ doesn't support OPP yet */ if (!of_machine_is_compatible("nvidia,tegra20") && !of_machine_is_compatible("nvidia,tegra30")) return -ENODEV; if (of_machine_is_compatible("nvidia,tegra20")) hw_version = BIT(tegra_sku_info.soc_process_id); else hw_version = BIT(tegra_sku_info.soc_speedo_id); err = devm_pm_opp_set_supported_hw(dev, &hw_version, 1); if (err) { dev_err(dev, "failed to set OPP supported HW: %d\n", err); return err; } /* * Older device-trees have an empty OPP table, we will get * -ENODEV from devm_pm_opp_of_add_table() in this case. */ err = devm_pm_opp_of_add_table(dev); if (err) { if (err == -ENODEV) dev_err_once(dev, "OPP table not found, please update device-tree\n"); else dev_err(dev, "failed to add OPP table: %d\n", err); return err; } if (params->init_state) { err = tegra_core_dev_init_opp_state(dev); if (err) return err; } return 0; } EXPORT_SYMBOL_GPL(devm_tegra_core_dev_init_opp_table);
drivers/soc/tegra/regulators-tegra20.c +74 −1 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include <linux/init.h> #include <linux/kernel.h> #include <linux/of.h> #include <linux/reboot.h> #include <linux/regulator/coupler.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> Loading @@ -21,7 +22,10 @@ struct tegra_regulator_coupler { struct regulator_dev *core_rdev; struct regulator_dev *cpu_rdev; struct regulator_dev *rtc_rdev; int core_min_uV; struct notifier_block reboot_notifier; int core_min_uV, cpu_min_uV; bool sys_reboot_mode_req; bool sys_reboot_mode; }; static inline struct tegra_regulator_coupler * Loading Loading @@ -242,6 +246,10 @@ static int tegra20_cpu_voltage_update(struct tegra_regulator_coupler *tegra, if (cpu_uV < 0) return cpu_uV; /* store boot voltage level */ if (!tegra->cpu_min_uV) tegra->cpu_min_uV = cpu_uV; /* * CPU's regulator may not have any consumers, hence the voltage * must not be changed in that case because CPU simply won't Loading @@ -250,6 +258,10 @@ static int tegra20_cpu_voltage_update(struct tegra_regulator_coupler *tegra, if (!cpu_min_uV_consumers) cpu_min_uV = cpu_uV; /* restore boot voltage level */ if (tegra->sys_reboot_mode) cpu_min_uV = max(cpu_min_uV, tegra->cpu_min_uV); if (cpu_min_uV > cpu_uV) { err = tegra20_core_rtc_update(tegra, core_rdev, rtc_rdev, cpu_uV, cpu_min_uV); Loading Loading @@ -290,6 +302,8 @@ static int tegra20_regulator_balance_voltage(struct regulator_coupler *coupler, return -EINVAL; } tegra->sys_reboot_mode = READ_ONCE(tegra->sys_reboot_mode_req); if (rdev == cpu_rdev) return tegra20_cpu_voltage_update(tegra, cpu_rdev, core_rdev, rtc_rdev); Loading @@ -303,6 +317,51 @@ static int tegra20_regulator_balance_voltage(struct regulator_coupler *coupler, return -EPERM; } static int tegra20_regulator_prepare_reboot(struct tegra_regulator_coupler *tegra, bool sys_reboot_mode) { int err; if (!tegra->core_rdev || !tegra->rtc_rdev || !tegra->cpu_rdev) return 0; WRITE_ONCE(tegra->sys_reboot_mode_req, true); /* * Some devices use CPU soft-reboot method and in this case we * should ensure that voltages are sane for the reboot by restoring * the minimum boot levels. */ err = regulator_sync_voltage_rdev(tegra->cpu_rdev); if (err) return err; err = regulator_sync_voltage_rdev(tegra->core_rdev); if (err) return err; WRITE_ONCE(tegra->sys_reboot_mode_req, sys_reboot_mode); return 0; } static int tegra20_regulator_reboot(struct notifier_block *notifier, unsigned long event, void *cmd) { struct tegra_regulator_coupler *tegra; int ret; if (event != SYS_RESTART) return NOTIFY_DONE; tegra = container_of(notifier, struct tegra_regulator_coupler, reboot_notifier); ret = tegra20_regulator_prepare_reboot(tegra, true); return notifier_from_errno(ret); } static int tegra20_regulator_attach(struct regulator_coupler *coupler, struct regulator_dev *rdev) { Loading Loading @@ -335,6 +394,14 @@ static int tegra20_regulator_detach(struct regulator_coupler *coupler, { struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler); /* * We don't expect regulators to be decoupled during reboot, * this may race with the reboot handler and shouldn't ever * happen in practice. */ if (WARN_ON_ONCE(system_state > SYSTEM_RUNNING)) return -EPERM; if (tegra->core_rdev == rdev) { tegra->core_rdev = NULL; return 0; Loading @@ -359,13 +426,19 @@ static struct tegra_regulator_coupler tegra20_coupler = { .detach_regulator = tegra20_regulator_detach, .balance_voltage = tegra20_regulator_balance_voltage, }, .reboot_notifier.notifier_call = tegra20_regulator_reboot, }; static int __init tegra_regulator_coupler_init(void) { int err; if (!of_machine_is_compatible("nvidia,tegra20")) return 0; err = register_reboot_notifier(&tegra20_coupler.reboot_notifier); WARN_ON(err); return regulator_coupler_register(&tegra20_coupler.coupler); } arch_initcall(tegra_regulator_coupler_init);
drivers/soc/tegra/regulators-tegra30.c +74 −1 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include <linux/init.h> #include <linux/kernel.h> #include <linux/of.h> #include <linux/reboot.h> #include <linux/regulator/coupler.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> Loading @@ -22,7 +23,10 @@ struct tegra_regulator_coupler { struct regulator_coupler coupler; struct regulator_dev *core_rdev; struct regulator_dev *cpu_rdev; int core_min_uV; struct notifier_block reboot_notifier; int core_min_uV, cpu_min_uV; bool sys_reboot_mode_req; bool sys_reboot_mode; }; static inline struct tegra_regulator_coupler * Loading Loading @@ -172,6 +176,10 @@ static int tegra30_voltage_update(struct tegra_regulator_coupler *tegra, if (cpu_uV < 0) return cpu_uV; /* store boot voltage level */ if (!tegra->cpu_min_uV) tegra->cpu_min_uV = cpu_uV; /* * CPU's regulator may not have any consumers, hence the voltage * must not be changed in that case because CPU simply won't Loading @@ -195,6 +203,10 @@ static int tegra30_voltage_update(struct tegra_regulator_coupler *tegra, if (err) return err; /* restore boot voltage level */ if (tegra->sys_reboot_mode) cpu_min_uV = max(cpu_min_uV, tegra->cpu_min_uV); if (core_min_limited_uV > core_uV) { pr_err("core voltage constraint violated: %d %d %d\n", core_uV, core_min_limited_uV, cpu_uV); Loading Loading @@ -263,9 +275,56 @@ static int tegra30_regulator_balance_voltage(struct regulator_coupler *coupler, return -EINVAL; } tegra->sys_reboot_mode = READ_ONCE(tegra->sys_reboot_mode_req); return tegra30_voltage_update(tegra, cpu_rdev, core_rdev); } static int tegra30_regulator_prepare_reboot(struct tegra_regulator_coupler *tegra, bool sys_reboot_mode) { int err; if (!tegra->core_rdev || !tegra->cpu_rdev) return 0; WRITE_ONCE(tegra->sys_reboot_mode_req, true); /* * Some devices use CPU soft-reboot method and in this case we * should ensure that voltages are sane for the reboot by restoring * the minimum boot levels. */ err = regulator_sync_voltage_rdev(tegra->cpu_rdev); if (err) return err; err = regulator_sync_voltage_rdev(tegra->core_rdev); if (err) return err; WRITE_ONCE(tegra->sys_reboot_mode_req, sys_reboot_mode); return 0; } static int tegra30_regulator_reboot(struct notifier_block *notifier, unsigned long event, void *cmd) { struct tegra_regulator_coupler *tegra; int ret; if (event != SYS_RESTART) return NOTIFY_DONE; tegra = container_of(notifier, struct tegra_regulator_coupler, reboot_notifier); ret = tegra30_regulator_prepare_reboot(tegra, true); return notifier_from_errno(ret); } static int tegra30_regulator_attach(struct regulator_coupler *coupler, struct regulator_dev *rdev) { Loading @@ -292,6 +351,14 @@ static int tegra30_regulator_detach(struct regulator_coupler *coupler, { struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler); /* * We don't expect regulators to be decoupled during reboot, * this may race with the reboot handler and shouldn't ever * happen in practice. */ if (WARN_ON_ONCE(system_state > SYSTEM_RUNNING)) return -EPERM; if (tegra->core_rdev == rdev) { tegra->core_rdev = NULL; return 0; Loading @@ -311,13 +378,19 @@ static struct tegra_regulator_coupler tegra30_coupler = { .detach_regulator = tegra30_regulator_detach, .balance_voltage = tegra30_regulator_balance_voltage, }, .reboot_notifier.notifier_call = tegra30_regulator_reboot, }; static int __init tegra_regulator_coupler_init(void) { int err; if (!of_machine_is_compatible("nvidia,tegra30")) return 0; err = register_reboot_notifier(&tegra30_coupler.reboot_notifier); WARN_ON(err); return regulator_coupler_register(&tegra30_coupler.coupler); } arch_initcall(tegra_regulator_coupler_init);
include/linux/regulator/driver.h +1 −0 Original line number Diff line number Diff line Loading @@ -540,6 +540,7 @@ int regulator_set_current_limit_regmap(struct regulator_dev *rdev, int regulator_get_current_limit_regmap(struct regulator_dev *rdev); void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data); int regulator_set_ramp_delay_regmap(struct regulator_dev *rdev, int ramp_delay); int regulator_sync_voltage_rdev(struct regulator_dev *rdev); /* * Helper functions intended to be used by regulator drivers prior registering Loading