Diff below allows enabling of more complex regulators. The "fixed" regulator support is split off in its own function. We now respect the "regulator-allways-on" property by leaving the regulator alone, assuming it is already turned on.
ok? Index: dev/ofw/ofw_regulator.c =================================================================== RCS file: /cvs/src/sys/dev/ofw/ofw_regulator.c,v retrieving revision 1.3 diff -u -p -r1.3 ofw_regulator.c --- dev/ofw/ofw_regulator.c 16 Dec 2017 21:12:03 -0000 1.3 +++ dev/ofw/ofw_regulator.c 17 Dec 2017 13:55:57 -0000 @@ -50,21 +50,13 @@ regulator_register(struct regulator_devi } int -regulator_set(uint32_t phandle, int enable) +regulator_fixed_set(int node, int enable) { uint32_t *gpio; uint32_t startup_delay; int active; - int node; int len; - node = OF_getnodebyphandle(phandle); - if (node == 0) - return -1; - - if (!OF_is_compatible(node, "regulator-fixed")) - return -1; - pinctrl_byname(node, "default"); if (OF_getproplen(node, "enable-active-high") == 0) @@ -91,6 +83,34 @@ regulator_set(uint32_t phandle, int enab delay(startup_delay); return 0; +} + +int +regulator_set(uint32_t phandle, int enable) +{ + struct regulator_device *rd; + int node; + + node = OF_getnodebyphandle(phandle); + if (node == 0) + return ENODEV; + + /* Don't mess around with regulators that are always on. */ + if (OF_getproplen(node, "regulator-always-on") == 0) + return 0; + + LIST_FOREACH(rd, ®ulator_devices, rd_list) { + if (rd->rd_phandle == phandle) + break; + } + + if (rd && rd->rd_enable) + return rd->rd_enable(rd->rd_cookie, enable); + + if (OF_is_compatible(node, "regulator-fixed")) + return regulator_fixed_set(node, enable); + + return ENODEV; } int Index: dev/ofw/ofw_regulator.h =================================================================== RCS file: /cvs/src/sys/dev/ofw/ofw_regulator.h,v retrieving revision 1.4 diff -u -p -r1.4 ofw_regulator.h --- dev/ofw/ofw_regulator.h 16 Dec 2017 21:12:03 -0000 1.4 +++ dev/ofw/ofw_regulator.h 17 Dec 2017 13:55:57 -0000 @@ -23,6 +23,7 @@ struct regulator_device { void *rd_cookie; uint32_t (*rd_get_voltage)(void *); int (*rd_set_voltage)(void *, uint32_t); + int (*rd_enable)(void *, int); uint32_t rd_min, rd_max;