aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorEmmanuel Vadot <manu@FreeBSD.org>2018-04-04 06:44:24 +0000
committerEmmanuel Vadot <manu@FreeBSD.org>2018-04-04 06:44:24 +0000
commit3f0140123623153986748eb52e549999022f8e31 (patch)
tree17da7a52be9a1a0abef8a3075e110ad723c4b9ec /sys/dev
parent9f6fffc7312725f767237797fffa596826fa36d9 (diff)
Notes
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/extres/regulator/regulator.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/sys/dev/extres/regulator/regulator.c b/sys/dev/extres/regulator/regulator.c
index 7b79766d05274..45129f068d426 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, &regnode_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, &regnode_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
*/