/*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2025 Bojan Novković #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "syscon_if.h" #include "hwreset_if.h" struct cvitek_reset_softc { device_t dev; struct mtx mtx; struct syscon *syscon; }; static int cvitek_reset_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_is_compatible(dev, "cvitek,reset")) { device_set_desc(dev, "CVITEK reset controller"); return (BUS_PROBE_DEFAULT); } return (ENXIO); } static int cvitek_reset_attach(device_t dev) { struct cvitek_reset_softc *sc; int error; sc = device_get_softc(dev); sc->dev = dev; error = syscon_get_by_ofw_property(dev, ofw_bus_get_node(dev), "syscon", &sc->syscon); if (error != 0) { device_printf(dev, "Couldn't get syscon handle\n"); return (error); } mtx_init(&sc->mtx, device_get_nameunit(sc->dev), NULL, MTX_DEF); hwreset_register_ofw_provider(dev); return (0); } static int cvitek_reset_assert(device_t dev, intptr_t id, bool reset) { struct cvitek_reset_softc *sc; uint32_t offset, val; uint32_t bit; sc = device_get_softc(dev); bit = id % 32; offset = id / 32; mtx_lock(&sc->mtx); val = SYSCON_READ_4(sc->syscon, offset); if (reset) val &= ~(1 << bit); else val |= (1 << bit); SYSCON_WRITE_4(sc->syscon, offset, val); mtx_unlock(&sc->mtx); return (0); } static device_method_t cvitek_reset_methods[] = { DEVMETHOD(device_probe, cvitek_reset_probe), DEVMETHOD(device_attach, cvitek_reset_attach), DEVMETHOD(hwreset_assert, cvitek_reset_assert), DEVMETHOD_END }; static driver_t cvitek_reset_driver = { "cvitek_reset", cvitek_reset_methods, sizeof(struct cvitek_reset_softc) }; DRIVER_MODULE(cvitek_reset, simplebus, cvitek_reset_driver, 0, 0);