Date: Mon, 13 Aug 2018 08:47:54 +0000 (UTC) From: Michal Meloun <mmel@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r337705 - stable/11/sys/dev/extres/regulator Message-ID: <201808130847.w7D8lshj070000@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mmel Date: Mon Aug 13 08:47:54 2018 New Revision: 337705 URL: https://svnweb.freebsd.org/changeset/base/337705 Log: MFC r335249: Fix handling of enable counter for shared GPIO line in fixed regulator. Modified: stable/11/sys/dev/extres/regulator/regnode_if.m stable/11/sys/dev/extres/regulator/regulator.c stable/11/sys/dev/extres/regulator/regulator_fixed.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/dev/extres/regulator/regnode_if.m ============================================================================== --- stable/11/sys/dev/extres/regulator/regnode_if.m Mon Aug 13 07:28:25 2018 (r337704) +++ stable/11/sys/dev/extres/regulator/regnode_if.m Mon Aug 13 08:47:54 2018 (r337705) @@ -31,6 +31,15 @@ HEADER { struct regnode; } +CODE { + static int + regnode_default_stop(struct regnode *regnode, int *udelay) + { + + return(REGNODE_ENABLE(regnode, false, udelay)); + } +} + # # Initialize regulator # Returns 0 on success or a standard errno value. @@ -80,3 +89,12 @@ METHOD int get_voltage { struct regnode *regnode; int *uvolt; }; + +# +# Stop (shutdown) regulator +# Returns 0 on success or a standard errno value. +# +METHOD int stop { + struct regnode *regnode; + int *udelay; +} DEFAULT regnode_default_stop; Modified: stable/11/sys/dev/extres/regulator/regulator.c ============================================================================== --- stable/11/sys/dev/extres/regulator/regulator.c Mon Aug 13 07:28:25 2018 (r337704) +++ stable/11/sys/dev/extres/regulator/regulator.c Mon Aug 13 08:47:54 2018 (r337705) @@ -515,7 +515,7 @@ regnode_stop(struct regnode *regnode, int depth) /* Disable regulator for each node in chain, starting from consumer */ if ((regnode->enable_cnt == 0) && ((regnode->flags & REGULATOR_FLAGS_NOT_DISABLE) == 0)) { - rv = REGNODE_ENABLE(regnode, false, &udelay); + rv = REGNODE_STOP(regnode, &udelay); if (rv != 0) { REGNODE_UNLOCK(regnode); return (rv); @@ -527,7 +527,7 @@ regnode_stop(struct regnode *regnode, int depth) rv = regnode_resolve_parent(regnode); if (rv != 0) return (rv); - if (regnode->parent != NULL) + if (regnode->parent != NULL && regnode->parent->enable_cnt == 0) rv = regnode_stop(regnode->parent, depth + 1); return (rv); } Modified: stable/11/sys/dev/extres/regulator/regulator_fixed.c ============================================================================== --- stable/11/sys/dev/extres/regulator/regulator_fixed.c Mon Aug 13 07:28:25 2018 (r337704) +++ stable/11/sys/dev/extres/regulator/regulator_fixed.c Mon Aug 13 08:47:54 2018 (r337705) @@ -56,6 +56,7 @@ struct gpio_entry { struct gpiobus_pin gpio_pin; int use_cnt; int enable_cnt; + bool always_on; }; static gpio_list_t gpio_list = TAILQ_HEAD_INITIALIZER(gpio_list); static struct mtx gpio_list_mtx; @@ -71,12 +72,14 @@ static int regnode_fixed_init(struct regnode *regnode) static int regnode_fixed_enable(struct regnode *regnode, bool enable, int *udelay); static int regnode_fixed_status(struct regnode *regnode, int *status); +static int regnode_fixed_stop(struct regnode *regnode, int *udelay); static regnode_method_t regnode_fixed_methods[] = { /* Regulator interface */ REGNODEMETHOD(regnode_init, regnode_fixed_init), REGNODEMETHOD(regnode_enable, regnode_fixed_enable), REGNODEMETHOD(regnode_status, regnode_fixed_status), + REGNODEMETHOD(regnode_stop, regnode_fixed_stop), REGNODEMETHOD_END }; DEFINE_CLASS_1(regnode_fixed, regnode_fixed_class, regnode_fixed_methods, @@ -188,8 +191,6 @@ regnode_fixed_enable(struct regnode *regnode, bool ena dev = regnode_get_device(regnode); *udelay = 0; - if (sc->param->always_on && !enable) - return (0); if (sc->gpio_entry == NULL) return (0); pin = &sc->gpio_entry->gpio_pin; @@ -204,6 +205,8 @@ regnode_fixed_enable(struct regnode *regnode, bool ena if (sc->gpio_entry->enable_cnt >= 1) return (0); } + if (sc->gpio_entry->always_on && !enable) + return (0); if (!sc->param->enable_active_high) enable = !enable; rv = GPIO_PIN_SET(pin->dev, pin->pin, enable); @@ -215,7 +218,43 @@ regnode_fixed_enable(struct regnode *regnode, bool ena return (0); } +/* + * Stop (physicaly shutdown) regulator. + * Take shared GPIO pins in account + */ static int +regnode_fixed_stop(struct regnode *regnode, int *udelay) +{ + device_t dev; + struct regnode_fixed_sc *sc; + struct gpiobus_pin *pin; + int rv; + + sc = regnode_get_softc(regnode); + dev = regnode_get_device(regnode); + + *udelay = 0; + if (sc->gpio_entry == NULL) + return (0); + if (sc->gpio_entry->always_on) + return (0); + pin = &sc->gpio_entry->gpio_pin; + if (sc->gpio_entry->enable_cnt > 0) { + /* Other regulator(s) are enabled. */ + /* XXXX Any diagnostic message? Or error? */ + return (0); + } + rv = GPIO_PIN_SET(pin->dev, pin->pin, + sc->param->enable_active_high ? false: true); + if (rv != 0) { + device_printf(dev, "Cannot set GPIO pin: %d\n", pin->pin); + return (rv); + } + *udelay = sc->param->enable_delay; + return (0); +} + +static int regnode_fixed_status(struct regnode *regnode, int *status) { struct regnode_fixed_sc *sc; @@ -264,6 +303,10 @@ regnode_fixed_register(device_t dev, struct regnode_fi device_printf(dev, "Cannot register regulator.\n"); return(ENXIO); } + + if (sc->gpio_entry != NULL) + sc->gpio_entry->always_on |= sc->param->always_on; + return (0); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201808130847.w7D8lshj070000>