Ejemplo n.º 1
0
static int
jz4780_pinctrl_attach(device_t dev)
{
	struct jz4780_pinctrl_softc *sc;
	struct resource_list *rs;
	struct resource_list_entry *re;
	phandle_t dt_parent, dt_child;
	int i, ret;

	sc = device_get_softc(dev);
	sc->dev = dev;

	/*
	 * Fetch our own resource list to dole memory between children
	 */
	rs = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev);
	if (rs == NULL)
		return (ENXIO);
	re = resource_list_find(rs, SYS_RES_MEMORY, 0);
	if (re == NULL)
		return (ENXIO);

	simplebus_init(dev, 0);

	/* Iterate over this node children, looking for pin controllers */
	dt_parent = ofw_bus_get_node(dev);
	i = 0;
	for (dt_child = OF_child(dt_parent); dt_child != 0;
	    dt_child = OF_peer(dt_child)) {
		struct simplebus_devinfo *ndi;
		device_t child;
		bus_addr_t phys;
		bus_size_t size;

		/* Add gpio controller child */
		if (!OF_hasprop(dt_child, "gpio-controller"))
			continue;
		child = simplebus_add_device(dev, dt_child, 0,  NULL, -1, NULL);
		if (child == NULL)
			break;
		/* Setup child resources */
		phys = CHIP_REG_OFFSET(re->start, i);
		size = CHIP_REG_STRIDE;
		if (phys + size - 1 <= re->end) {
			ndi = device_get_ivars(child);
			resource_list_add(&ndi->rl, SYS_RES_MEMORY, 0,
			    phys, phys + size - 1, size);
		}
		i++;
	}

	ret = bus_generic_attach(dev);
	if (ret == 0) {
	    fdt_pinctrl_register(dev, "ingenic,pins");
	    fdt_pinctrl_configure_tree(dev);
	}
	return (ret);
}
Ejemplo n.º 2
0
static int
aw_ccu_attach(device_t dev)
{
	struct aw_ccu_softc *sc;
	phandle_t node, child;
	device_t cdev;
	int error;

	sc = device_get_softc(dev);
	node = ofw_bus_get_node(dev);

	simplebus_init(dev, node);

	sc->flags = aw_ccu_search_compatible()->ocd_data;

	/*
	 * Map registers. The DT doesn't have a "reg" property
	 * for the /clocks node and child nodes have conflicting "reg"
	 * properties.
	 */
	sc->bst = bus_get_bus_tag(dev);
	if (sc->flags & CLOCK_CCU) {
		error = bus_space_map(sc->bst, CCU_BASE, CCU_SIZE, 0,
		    &sc->ccu_bsh);
		if (error != 0) {
			device_printf(dev, "couldn't map CCU: %d\n", error);
			return (error);
		}
	}
	if (sc->flags & CLOCK_PRCM) {
		error = bus_space_map(sc->bst, PRCM_BASE, PRCM_SIZE, 0,
		    &sc->prcm_bsh);
		if (error != 0) {
			device_printf(dev, "couldn't map PRCM: %d\n", error);
			return (error);
		}
	}
	if (sc->flags & CLOCK_SYSCTRL) {
		error = bus_space_map(sc->bst, SYSCTRL_BASE, SYSCTRL_SIZE, 0,
		    &sc->sysctrl_bsh);
		if (error != 0) {
			device_printf(dev, "couldn't map SYSCTRL: %d\n", error);
			return (error);
		}
	}

	mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF);

	/* Attach child devices */
	for (child = OF_child(node); child > 0; child = OF_peer(child)) {
		cdev = simplebus_add_device(dev, child, 0, NULL, -1, NULL);
		if (cdev != NULL)
			device_probe_and_attach(cdev);
	}

	return (bus_generic_attach(dev));
}
Ejemplo n.º 3
0
static int
mdionexus_ofw_bus_attach(device_t dev)
{
	struct simplebus_softc *sc;
	struct mdionexus_ofw_devinfo *di;
	device_t child;
	phandle_t parent, node;

	parent = ofw_bus_get_node(dev);
	simplebus_init(dev, parent);

	sc = (struct simplebus_softc *)device_get_softc(dev);

	if (mdionexus_ofw_fill_ranges(parent, sc) < 0) {
		device_printf(dev, "could not get ranges\n");
		return (ENXIO);
	}
	/* Iterate through all bus subordinates */
	for (node = OF_child(parent); node > 0; node = OF_peer(node)) {
		/* Allocate and populate devinfo. */
		di = malloc(sizeof(*di), M_THUNDER_MDIO, M_WAITOK | M_ZERO);
		if (ofw_bus_gen_setup_devinfo(&di->di_dinfo, node) != 0) {
			free(di, M_THUNDER_MDIO);
			continue;
		}

		/* Initialize and populate resource list. */
		resource_list_init(&di->di_rl);
		ofw_bus_reg_to_rl(dev, node, sc->acells, sc->scells,
		    &di->di_rl);
#ifndef INTRNG
		ofw_bus_intr_to_rl(dev, node, &di->di_rl, NULL);
#endif

		/* Add newbus device for this FDT node */
		child = device_add_child(dev, NULL, -1);
		if (child == NULL) {
			resource_list_free(&di->di_rl);
			ofw_bus_gen_destroy_devinfo(&di->di_dinfo);
			free(di, M_THUNDER_MDIO);
			continue;
		}

		device_set_ivars(child, di);
	}

	return (0);
}
Ejemplo n.º 4
0
static int
ofwbus_attach(device_t dev)
{
	struct ofwbus_softc *sc;
	phandle_t node;
	struct ofw_bus_devinfo obd;

	sc = device_get_softc(dev);

	node = OF_peer(0);

	/*
	 * If no Open Firmware, bail early
	 */
	if (node == -1)
		return (ENXIO);

	/*
	 * ofwbus bus starts on unamed node in FDT, so we cannot make
	 * ofw_bus_devinfo from it. Pass node to simplebus_init directly.
	 */
	simplebus_init(dev, node);
	sc->sc_intr_rman.rm_type = RMAN_ARRAY;
	sc->sc_intr_rman.rm_descr = "Interrupts";
	sc->sc_mem_rman.rm_type = RMAN_ARRAY;
	sc->sc_mem_rman.rm_descr = "Device Memory";
	if (rman_init(&sc->sc_intr_rman) != 0 ||
	    rman_init(&sc->sc_mem_rman) != 0 ||
	    rman_manage_region(&sc->sc_intr_rman, 0, ~0) != 0 ||
	    rman_manage_region(&sc->sc_mem_rman, 0, BUS_SPACE_MAXADDR) != 0)
		panic("%s: failed to set up rmans.", __func__);

	/*
	 * Allow devices to identify.
	 */
	bus_generic_probe(dev);

	/*
	 * Now walk the OFW tree and attach top-level devices.
	 */
	for (node = OF_child(node); node > 0; node = OF_peer(node)) {
		if (ofw_bus_gen_setup_devinfo(&obd, node) != 0)
			continue;
		simplebus_add_device(dev, node, 0, NULL, -1, NULL);
	}
	return (bus_generic_attach(dev));
}
Ejemplo n.º 5
0
static int
ofw_clkbus_attach(device_t dev)
{
	struct ofw_clkbus_softc *sc;
	phandle_t node, child;
	device_t cdev;

	sc = device_get_softc(dev);
	node  = ofw_bus_get_node(dev);
	simplebus_init(dev, node);

	for (child = OF_child(node); child > 0; child = OF_peer(child)) {
		cdev = simplebus_add_device(dev, child, 0, NULL, -1, NULL);
		if (cdev != NULL)
			device_probe_and_attach(cdev);
	}

	return (bus_generic_attach(dev));
}
Ejemplo n.º 6
0
static int
simplebus_attach(device_t dev)
{
	struct		simplebus_softc *sc;
	phandle_t	node;

	sc = device_get_softc(dev);
	simplebus_init(dev, 0);
	if (simplebus_fill_ranges(sc->node, sc) < 0) {
		device_printf(dev, "could not get ranges\n");
		return (ENXIO);
	}

	/*
	 * In principle, simplebus could have an interrupt map, but ignore that
	 * for now
	 */

	for (node = OF_child(sc->node); node > 0; node = OF_peer(node))
		simplebus_add_device(dev, node, 0, NULL, -1, NULL);
	return (bus_generic_attach(dev));
}