From 3f0140123623153986748eb52e549999022f8e31 Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Wed, 4 Apr 2018 06:44:24 +0000 Subject: [PATCH] regulator: Disable unused regulator bootloaders such as u-boot might enable regulators, or simply regulators could be enabled by default by the PMIC, even if we don't have a driver for the device or subsystem. Disable unused regulators just before going to userland. A tunable hw.regulator.disable_unused is added to not disable them in case this causes problems on some board but the default behavior is to disable everything unused. I prefer to break thinks now and fix them rather than never switch to the case were we disable regulators. Tested on : Pine64-LTS (an idle board goes from ~0.33A to ~0.27A) Tested on : BananaPi M2 Differential Revision: https://reviews.freebsd.org/D14781 --- sys/dev/extres/regulator/regulator.c | 31 ++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/sys/dev/extres/regulator/regulator.c b/sys/dev/extres/regulator/regulator.c index 7b79766d0527..45129f068d42 100644 --- a/sys/dev/extres/regulator/regulator.c +++ b/sys/dev/extres/regulator/regulator.c @@ -71,6 +71,7 @@ static int regnode_method_status(struct regnode *regnode, int *status); static int regnode_method_set_voltage(struct regnode *regnode, int min_uvolt, int max_uvolt, int *udelay); static int regnode_method_get_voltage(struct regnode *regnode, int *uvolt); +static void regulator_shutdown(void *dummy); /* * Regulator controller methods. @@ -151,6 +152,36 @@ SX_SYSINIT(regulator_topology, ®node_topo_lock, "Regulator topology lock"); #define REGNODE_XLOCK(_sc) sx_xlock(&((_sc)->lock)) #define REGNODE_UNLOCK(_sc) sx_unlock(&((_sc)->lock)) +SYSINIT(regulator_shutdown, SI_SUB_LAST, SI_ORDER_ANY, regulator_shutdown, + NULL); + +/* + * Disable unused regulator + * We run this function at SI_SUB_LAST which mean that every driver that needs + * regulator should have already enable them. + * All the remaining regulators should be those left enabled by the bootloader + * or enable by default by the PMIC. + */ +static void +regulator_shutdown(void *dummy) +{ + struct regnode *entry; + int disable = 1; + + REG_TOPO_SLOCK(); + TUNABLE_INT_FETCH("hw.regulator.disable_unused", &disable); + TAILQ_FOREACH(entry, ®node_list, reglist_link) { + if (entry->enable_cnt == 0 && + entry->std_param.always_on == 0 && disable) { + if (bootverbose) + printf("regulator: shuting down %s\n", + entry->name); + regnode_stop(entry, 0); + } + } + REG_TOPO_UNLOCK(); +} + /* * sysctl handler */