svn commit: r353919 - head/sys/dev/extres/regulator
Emmanuel Vadot
manu at FreeBSD.org
Wed Oct 23 09:56:54 UTC 2019
Author: manu
Date: Wed Oct 23 09:56:53 2019
New Revision: 353919
URL: https://svnweb.freebsd.org/changeset/base/353919
Log:
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
Modified:
head/sys/dev/extres/regulator/regulator.c
head/sys/dev/extres/regulator/regulator.h
Modified: head/sys/dev/extres/regulator/regulator.c
==============================================================================
--- head/sys/dev/extres/regulator/regulator.c Wed Oct 23 09:54:50 2019 (r353918)
+++ head/sys/dev/extres/regulator/regulator.c Wed Oct 23 09:56:53 2019 (r353919)
@@ -72,6 +72,7 @@ static int regnode_method_status(struct regnode *regno
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, ®node_topo_lock, "Re
#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, ®node_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
@@ -778,6 +797,56 @@ regnode_set_voltage_checked(struct regnode *regnode, s
regnode_delay(udelay);
REGNODE_UNLOCK(regnode);
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
Modified: head/sys/dev/extres/regulator/regulator.h
==============================================================================
--- head/sys/dev/extres/regulator/regulator.h Wed Oct 23 09:54:50 2019 (r353918)
+++ head/sys/dev/extres/regulator/regulator.h Wed Oct 23 09:56:53 2019 (r353919)
@@ -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
More information about the svn-src-all
mailing list