git: 929db0457513 - stable/13 - gpiopower: trigger low, high and both edges
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 17 Feb 2024 19:22:32 UTC
The branch stable/13 has been updated by avg: URL: https://cgit.FreeBSD.org/src/commit/?id=929db0457513b577c4e256f6633dc72f76151c91 commit 929db0457513b577c4e256f6633dc72f76151c91 Author: Andriy Gapon <avg@FreeBSD.org> AuthorDate: 2024-01-28 11:29:41 +0000 Commit: Andriy Gapon <avg@FreeBSD.org> CommitDate: 2024-02-17 19:22:08 +0000 gpiopower: trigger low, high and both edges Power off or reset may be activated either by low or high signal or by an edge. So, try everything. Also, the driver now supports DTS properties for timings. Finally, the driver does not change the pin configuration during attach. It is assumed that the pin is already in a state that does not trigger the power event (otherwise we wouldn't be running). (cherry picked from commit 320e4beb97618c6964380bfa404a3e96c5de7663) --- sys/dev/gpio/gpiopower.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/sys/dev/gpio/gpiopower.c b/sys/dev/gpio/gpiopower.c index a3dd8b02622f..a60214e2a51e 100644 --- a/sys/dev/gpio/gpiopower.c +++ b/sys/dev/gpio/gpiopower.c @@ -34,6 +34,7 @@ #include <sys/module.h> #include <sys/reboot.h> +#include <dev/fdt/fdt_common.h> #include <dev/ofw/ofw_bus.h> #include <dev/gpio/gpiobusvar.h> @@ -41,6 +42,9 @@ struct gpiopower_softc { gpio_pin_t sc_pin; int sc_rbmask; + int sc_hi_period; + int sc_lo_period; + int sc_timeout; }; static void gpiopower_assert(device_t dev, int howto); @@ -65,6 +69,7 @@ gpiopower_attach(device_t dev) { struct gpiopower_softc *sc; phandle_t node; + uint32_t prop; sc = device_get_softc(dev); @@ -81,9 +86,20 @@ gpiopower_attach(device_t dev) sc->sc_rbmask = RB_HALT | RB_POWEROFF; else sc->sc_rbmask = 0; + + sc->sc_hi_period = 100000; + sc->sc_lo_period = 100000; + sc->sc_timeout = 1000000; + + if ((OF_getprop(node, "active-delay-ms", &prop, sizeof(prop))) > 0) + sc->sc_hi_period = fdt32_to_cpu(prop) * 1000; + if ((OF_getprop(node, "inactive-delay-ms", &prop, sizeof(prop))) > 0) + sc->sc_lo_period = fdt32_to_cpu(prop) * 1000; + if ((OF_getprop(node, "timeout-ms", &prop, sizeof(prop))) > 0) + sc->sc_timeout = fdt32_to_cpu(prop) * 1000; + EVENTHANDLER_REGISTER(shutdown_final, gpiopower_assert, dev, SHUTDOWN_PRI_LAST); - gpio_pin_setflags(sc->sc_pin, GPIO_PIN_OUTPUT); return (0); } @@ -108,10 +124,16 @@ gpiopower_assert(device_t dev, int howto) else return; + gpio_pin_setflags(sc->sc_pin, GPIO_PIN_OUTPUT); + gpio_pin_set_active(sc->sc_pin, true); + DELAY(sc->sc_hi_period); + gpio_pin_set_active(sc->sc_pin, false); + DELAY(sc->sc_lo_period); gpio_pin_set_active(sc->sc_pin, true); + DELAY(sc->sc_timeout); - /* Wait a second for it to trip */ - DELAY(10000000); + device_printf(dev, "%s failed\n", + (howto & RB_POWEROFF) != 0 ? "power off" : "reset"); } static devclass_t gpiopower_devclass;