Index: sys/arm/allwinner/aw_syscon.c =================================================================== --- sys/arm/allwinner/aw_syscon.c +++ sys/arm/allwinner/aw_syscon.c @@ -40,6 +40,8 @@ #include #include +#include + #include #include #include Index: sys/arm/ti/ti_scm_syscon.c =================================================================== --- sys/arm/ti/ti_scm_syscon.c +++ sys/arm/ti/ti_scm_syscon.c @@ -52,6 +52,7 @@ #include "syscon_if.h" #include +#include #include "clkdev_if.h" #if 0 @@ -60,218 +61,82 @@ #define DPRINTF(dev, msg...) #endif -MALLOC_DECLARE(M_SYSCON); +/* Redifine from syscon_generic.c */ +#define SYSCON_LOCK(_sc) mtx_lock_spin(&(_sc)->mtx) +#define SYSCON_UNLOCK(_sc) mtx_unlock_spin(&(_sc)->mtx) -struct ti_scm_syscon_softc { - struct simplebus_softc sc_simplebus; - device_t dev; - struct syscon * syscon; - struct resource * res[1]; - bus_space_tag_t bst; - bus_space_handle_t bsh; - struct mtx mtx; -}; - -static struct resource_spec ti_scm_syscon_res_spec[] = { - { SYS_RES_MEMORY, 0, RF_ACTIVE | RF_SHAREABLE }, - { -1, 0 } -}; - -/* Device */ -static struct ofw_compat_data compat_data[] = { - { "syscon", 1 }, - { NULL, 0 } -}; - -/* --- dev/extres/syscon syscon_method_t interface --- */ -static int -ti_scm_syscon_write_4(struct syscon *syscon, bus_size_t offset, uint32_t val) -{ - struct ti_scm_syscon_softc *sc; - - sc = device_get_softc(syscon->pdev); - DPRINTF(sc->dev, "offset=%lx write %x\n", offset, val); - mtx_lock(&sc->mtx); - bus_space_write_4(sc->bst, sc->bsh, offset, val); - mtx_unlock(&sc->mtx); - return (0); -} - -static uint32_t -ti_scm_syscon_read_4(struct syscon *syscon, bus_size_t offset) -{ - struct ti_scm_syscon_softc *sc; - uint32_t val; - - sc = device_get_softc(syscon->pdev); - - mtx_lock(&sc->mtx); - val = bus_space_read_4(sc->bst, sc->bsh, offset); - mtx_unlock(&sc->mtx); - DPRINTF(sc->dev, "offset=%lx Read %x\n", offset, val); - return (val); -} -static int -ti_scm_syscon_modify_4(struct syscon *syscon, bus_size_t offset, uint32_t clr, uint32_t set) -{ - struct ti_scm_syscon_softc *sc; - uint32_t reg; - - sc = device_get_softc(syscon->pdev); - - mtx_lock(&sc->mtx); - reg = bus_space_read_4(sc->bst, sc->bsh, offset); - reg &= ~clr; - reg |= set; - bus_space_write_4(sc->bst, sc->bsh, offset, reg); - mtx_unlock(&sc->mtx); - DPRINTF(sc->dev, "offset=%lx reg: %x (clr %x set %x)\n", offset, reg, clr, set); - - return (0); -} - -static syscon_method_t ti_scm_syscon_reg_methods[] = { - SYSCONMETHOD(syscon_read_4, ti_scm_syscon_read_4), - SYSCONMETHOD(syscon_write_4, ti_scm_syscon_write_4), - SYSCONMETHOD(syscon_modify_4, ti_scm_syscon_modify_4), - - SYSCONMETHOD_END -}; - -DEFINE_CLASS_1(ti_scm_syscon_reg, ti_scm_syscon_reg_class, ti_scm_syscon_reg_methods, - 0, syscon_class); - /* device interface */ static int ti_scm_syscon_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) return (ENXIO); - - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) + if (! (ofw_bus_is_compatible(dev, "syscon") && ofw_bus_is_compatible(dev, "simple-bus")) ) return (ENXIO); device_set_desc(dev, "TI OMAP Control Module Syscon"); return(BUS_PROBE_DEFAULT); } -static int -ti_scm_syscon_attach(device_t dev) -{ - struct ti_scm_syscon_softc *sc; - phandle_t node, child; - int err; - - sc = device_get_softc(dev); - sc->dev = dev; - - if (bus_alloc_resources(dev, ti_scm_syscon_res_spec, sc->res)) { - device_printf(sc->dev, "Cant allocate resources\n"); - return (ENXIO); - } - - sc->dev = dev; - sc->bst = rman_get_bustag(sc->res[0]); - sc->bsh = rman_get_bushandle(sc->res[0]); - - mtx_init(&sc->mtx, device_get_nameunit(sc->dev), NULL, MTX_DEF); - node = ofw_bus_get_node(sc->dev); - - /* dev/extres/syscon interface */ - sc->syscon = syscon_create_ofw_node(dev, &ti_scm_syscon_reg_class, node); - if (sc->syscon == NULL) { - device_printf(dev, "Failed to create/register syscon\n"); - return (ENXIO); - } - - simplebus_init(sc->dev, node); - - err = bus_generic_probe(sc->dev); - for (child = OF_child(node); child != 0; child = OF_peer(child)) { - simplebus_add_device(sc->dev, child, 0, NULL, -1, NULL); - } - - return (bus_generic_attach(sc->dev)); -} - -/* syscon interface */ -static int -ti_scm_syscon_get_handle(device_t dev, struct syscon **syscon) -{ - struct ti_scm_syscon_softc *sc; - - sc = device_get_softc(dev); - *syscon = sc->syscon; - if (*syscon == NULL) - return (ENODEV); - return (0); -} - /* clkdev interface */ static int -ti_scm_syscon_clk_write_4(device_t dev, bus_addr_t addr, uint32_t val) +ti_scm_syscon_clk_write_4(device_t dev, bus_addr_t offset, uint32_t val) { - struct ti_scm_syscon_softc *sc; + struct syscon_generic_softc *sc; sc = device_get_softc(dev); - DPRINTF(sc->dev, "offset=%lx write %x\n", addr, val); - bus_space_write_4(sc->bst, sc->bsh, addr, val); + bus_write_4(sc->mem_res, offset, val); + return (0); } static int -ti_scm_syscon_clk_read_4(device_t dev, bus_addr_t addr, uint32_t *val) +ti_scm_syscon_clk_read_4(device_t dev, bus_addr_t offset, uint32_t *val) { - struct ti_scm_syscon_softc *sc; + struct syscon_generic_softc *sc; sc = device_get_softc(dev); + *val = bus_read_4(sc->mem_res, offset); - *val = bus_space_read_4(sc->bst, sc->bsh, addr); - DPRINTF(sc->dev, "offset=%lx Read %x\n", addr, *val); return (0); } static int -ti_scm_syscon_clk_modify_4(device_t dev, bus_addr_t addr, uint32_t clr, uint32_t set) +ti_scm_syscon_clk_modify_4(device_t dev, bus_addr_t offset, uint32_t clear_bits, uint32_t set_bits) { - struct ti_scm_syscon_softc *sc; - uint32_t reg; + struct syscon_generic_softc *sc; + uint32_t val; sc = device_get_softc(dev); + val = bus_read_4(sc->mem_res, offset); + val &= ~clear_bits; + val |= set_bits; + bus_write_4(sc->mem_res, offset, val); - reg = bus_space_read_4(sc->bst, sc->bsh, addr); - reg &= ~clr; - reg |= set; - bus_space_write_4(sc->bst, sc->bsh, addr, reg); - DPRINTF(sc->dev, "offset=%lx reg: %x (clr %x set %x)\n", addr, reg, clr, set); - return (0); } static void ti_scm_syscon_clk_device_lock(device_t dev) { - struct ti_scm_syscon_softc *sc; + struct syscon_generic_softc *sc; sc = device_get_softc(dev); - mtx_lock(&sc->mtx); + SYSCON_LOCK(sc); } static void ti_scm_syscon_clk_device_unlock(device_t dev) { - struct ti_scm_syscon_softc *sc; + struct syscon_generic_softc *sc; + sc = device_get_softc(dev); - mtx_unlock(&sc->mtx); + SYSCON_UNLOCK(sc); } static device_method_t ti_scm_syscon_methods[] = { DEVMETHOD(device_probe, ti_scm_syscon_probe), - DEVMETHOD(device_attach, ti_scm_syscon_attach), - /* syscon interface */ - DEVMETHOD(syscon_get_handle, ti_scm_syscon_get_handle), - /* clkdev interface */ DEVMETHOD(clkdev_write_4, ti_scm_syscon_clk_write_4), DEVMETHOD(clkdev_read_4, ti_scm_syscon_clk_read_4), @@ -283,7 +148,7 @@ }; DEFINE_CLASS_1(ti_scm_syscon, ti_scm_syscon_driver, ti_scm_syscon_methods, - sizeof(struct ti_scm_syscon_softc), simplebus_driver); + sizeof(struct syscon_generic_softc), syscon_generic_driver); static devclass_t ti_scm_syscon_devclass; Index: sys/dev/extres/syscon/syscon_generic.h =================================================================== --- sys/dev/extres/syscon/syscon_generic.h +++ sys/dev/extres/syscon/syscon_generic.h @@ -30,6 +30,7 @@ #define DEV_SYSCON_GENERIC_H struct syscon_generic_softc { + struct simplebus_softc sc_simplebus; device_t dev; struct syscon *syscon; struct resource *mem_res; Index: sys/dev/extres/syscon/syscon_generic.c =================================================================== --- sys/dev/extres/syscon/syscon_generic.c +++ sys/dev/extres/syscon/syscon_generic.c @@ -46,6 +46,8 @@ #include +#include + #include #include @@ -77,14 +79,14 @@ #define SYSCON_ASSERT_LOCKED(_sc) mtx_assert(&(_sc)->mtx, MA_OWNED); #define SYSCON_ASSERT_UNLOCKED(_sc) mtx_assert(&(_sc)->mtx, MA_NOTOWNED); -static syscon_method_t syscon_generic_methods[] = { +static syscon_method_t syscon_generic_syscon_methods[] = { SYSCONMETHOD(syscon_read_4, syscon_generic_read_4), SYSCONMETHOD(syscon_write_4, syscon_generic_write_4), SYSCONMETHOD(syscon_modify_4, syscon_generic_modify_4), SYSCONMETHOD_END }; -DEFINE_CLASS_1(syscon_generic, syscon_generic_class, syscon_generic_methods, +DEFINE_CLASS_1(syscon_generic_syscon, syscon_generic_syscon_class, syscon_generic_syscon_methods, 0, syscon_class); static uint32_t @@ -153,6 +155,8 @@ { struct syscon_generic_softc *sc; int rid; + phandle_t node, child; + device_t cdev; sc = device_get_softc(dev); sc->dev = dev; @@ -166,12 +170,24 @@ } SYSCON_LOCK_INIT(sc); - sc->syscon = syscon_create_ofw_node(dev, &syscon_generic_class, - ofw_bus_get_node(dev)); + node = ofw_bus_get_node(sc->dev); + sc->syscon = syscon_create_ofw_node(dev, &syscon_generic_syscon_class, + node); if (sc->syscon == NULL) { device_printf(dev, "Failed to create/register syscon\n"); return (ENXIO); } + + if (ofw_bus_is_compatible(dev, "simple-bus")) { + simplebus_init(sc->dev, node); + + for (child = OF_child(node); child != 0; child = OF_peer(child)) { + cdev = simplebus_add_device(sc->dev, child, 0, NULL, -1, NULL); + if (cdev != NULL) + device_probe_and_attach(cdev); + } + } + return (0); } @@ -186,6 +202,10 @@ free(sc->syscon, M_SYSCON); } + /* Memory allocated in simplebus_init */ + if (sc->sc_simplebus.ranges != NULL) + free(sc->sc_simplebus.ranges, M_DEVBUF); + SYSCON_LOCK_DESTROY(sc); if (sc->mem_res != NULL) @@ -202,8 +222,8 @@ DEVMETHOD_END }; -DEFINE_CLASS_0(syscon_generic, syscon_generic_driver, syscon_generic_dmethods, - sizeof(struct syscon_generic_softc)); +DEFINE_CLASS_1(syscon_generic, syscon_generic_driver, syscon_generic_dmethods, + sizeof(struct syscon_generic_softc), simplebus_driver); static devclass_t syscon_generic_devclass; EARLY_DRIVER_MODULE(syscon_generic, simplebus, syscon_generic_driver,