aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/extres
diff options
context:
space:
mode:
authorEmmanuel Vadot <manu@FreeBSD.org>2019-10-23 09:56:53 +0000
committerEmmanuel Vadot <manu@FreeBSD.org>2019-10-23 09:56:53 +0000
commita601368040cc2137435893973243b2d91d2a659b (patch)
tree8b02523b5451d549a95b1544d0e42eccdac50d33 /sys/dev/extres
parentf66cb502db61d02c183152e9286ac79f870cd2b8 (diff)
downloadsrc-a601368040cc2137435893973243b2d91d2a659b.tar.gz
src-a601368040cc2137435893973243b2d91d2a659b.zip
regulator: Add a regnode_set_constraint function
This method check that boot_on or always_on is set to 1 and if it is it will try to enable the regulator. The binding docs aren't clear on what to do but Linux enable the regulator if any of those properties is set so we want to do the same. The function first check the status to see if the regulator is already enabled it then get the voltage to check if it is in a acceptable range and then enables it. This will be either called from the regnode_init method (if it's needed by the platform) or by a SYSINIT at SI_SUB_LAST Reviewed by: mmel MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D22106
Notes
Notes: svn path=/head/; revision=353919
Diffstat (limited to 'sys/dev/extres')
-rw-r--r--sys/dev/extres/regulator/regulator.c69
-rw-r--r--sys/dev/extres/regulator/regulator.h1
2 files changed, 70 insertions, 0 deletions
diff --git a/sys/dev/extres/regulator/regulator.c b/sys/dev/extres/regulator/regulator.c
index 53fe55b2bd0e..82e8d066818a 100644
--- a/sys/dev/extres/regulator/regulator.c
+++ b/sys/dev/extres/regulator/regulator.c
@@ -72,6 +72,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_constraint(void *dummy);
static void regulator_shutdown(void *dummy);
/*
@@ -154,9 +155,27 @@ 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_constraint, SI_SUB_LAST, SI_ORDER_ANY, regulator_constraint,
+ NULL);
SYSINIT(regulator_shutdown, SI_SUB_LAST, SI_ORDER_ANY, regulator_shutdown,
NULL);
+static void
+regulator_constraint(void *dummy)
+{
+ struct regnode *entry;
+ int rv;
+
+ REG_TOPO_SLOCK();
+ TAILQ_FOREACH(entry, &regnode_list, reglist_link) {
+ rv = regnode_set_constraint(entry);
+ if (rv != 0 && bootverbose)
+ printf("regulator: setting constraint on %s failed (%d)\n",
+ entry->name, rv);
+ }
+ REG_TOPO_UNLOCK();
+}
+
/*
* Disable unused regulator
* We run this function at SI_SUB_LAST which mean that every driver that needs
@@ -780,6 +799,56 @@ regnode_set_voltage_checked(struct regnode *regnode, struct regulator *reg,
return (rv);
}
+int
+regnode_set_constraint(struct regnode *regnode)
+{
+ int status, rv, uvolt;
+
+ if (regnode->std_param.boot_on != true &&
+ regnode->std_param.always_on != true)
+ return (0);
+
+ rv = regnode_status(regnode, &status);
+ if (rv != 0) {
+ if (bootverbose)
+ printf("Cannot get regulator status for %s\n",
+ regnode_get_name(regnode));
+ return (rv);
+ }
+
+ if (status == REGULATOR_STATUS_ENABLED)
+ return (0);
+
+ rv = regnode_get_voltage(regnode, &uvolt);
+ if (rv != 0) {
+ if (bootverbose)
+ printf("Cannot get regulator voltage for %s\n",
+ regnode_get_name(regnode));
+ return (rv);
+ }
+
+ if (uvolt < regnode->std_param.min_uvolt ||
+ uvolt > regnode->std_param.max_uvolt) {
+ if (bootverbose)
+ printf("Regulator %s current voltage %d is not in the"
+ " acceptable range : %d<->%d\n",
+ regnode_get_name(regnode),
+ uvolt, regnode->std_param.min_uvolt,
+ regnode->std_param.max_uvolt);
+ return (ERANGE);
+ }
+
+ rv = regnode_enable(regnode);
+ if (rv != 0) {
+ if (bootverbose)
+ printf("Cannot enable regulator %s\n",
+ regnode_get_name(regnode));
+ return (rv);
+ }
+
+ return (0);
+}
+
#ifdef FDT
phandle_t
regnode_get_ofw_node(struct regnode *regnode)
diff --git a/sys/dev/extres/regulator/regulator.h b/sys/dev/extres/regulator/regulator.h
index 7ef6524df35a..b0bbb8a54b6e 100644
--- a/sys/dev/extres/regulator/regulator.h
+++ b/sys/dev/extres/regulator/regulator.h
@@ -116,6 +116,7 @@ int regnode_stop(struct regnode *regnode, int depth);
int regnode_status(struct regnode *regnode, int *status);
int regnode_get_voltage(struct regnode *regnode, int *uvolt);
int regnode_set_voltage(struct regnode *regnode, int min_uvolt, int max_uvolt);
+int regnode_set_constraint(struct regnode *regnode);
#ifdef FDT
phandle_t regnode_get_ofw_node(struct regnode *regnode);
#endif