Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 23 Oct 2019 09:56:53 +0000 (UTC)
From:      Emmanuel Vadot <manu@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r353919 - head/sys/dev/extres/regulator
Message-ID:  <201910230956.x9N9urvZ087980@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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, &regnode_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, &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
@@ -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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201910230956.x9N9urvZ087980>