예제 #1
0
파일: obio.c 프로젝트: hmatyschok/MeshBSD
static int
obio_attach(device_t dev)
{
	struct obio_softc *sc = device_get_softc(dev);
	int rid;

	sc->oba_mem_rman.rm_type = RMAN_ARRAY;
	sc->oba_mem_rman.rm_descr = "OBIO memeory";
	if (rman_init(&sc->oba_mem_rman) != 0 ||
	    rman_manage_region(&sc->oba_mem_rman, OBIO_MEM_START,
	        OBIO_MEM_START + OBIO_MEM_SIZE) != 0)
		panic("obio_attach: failed to set up I/O rman");

	sc->oba_irq_rman.rm_type = RMAN_ARRAY;
	sc->oba_irq_rman.rm_descr = "OBIO IRQ";

	if (rman_init(&sc->oba_irq_rman) != 0 ||
	    rman_manage_region(&sc->oba_irq_rman, 0, NIRQS-1) != 0)
		panic("obio_attach: failed to set up IRQ rman");

	/* Hook up our interrupt handler. */
	if ((sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
	    ADM5120_INTR, ADM5120_INTR, 1,
	    RF_SHAREABLE | RF_ACTIVE)) == NULL) {
		device_printf(dev, "unable to allocate IRQ resource\n");
		return (ENXIO);
	}

	if ((bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC, obio_intr, NULL,
	    sc, &sc->sc_ih))) {
		device_printf(dev,
		    "WARNING: unable to register interrupt handler\n");
		return (ENXIO);
	}

	/* Hook up our FAST interrupt handler. */
	if ((sc->sc_fast_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
	    ADM5120_FAST_INTR, ADM5120_FAST_INTR, 1,
	    RF_SHAREABLE | RF_ACTIVE)) == NULL) {
		device_printf(dev, "unable to allocate IRQ resource\n");
		return (ENXIO);
	}

	if ((bus_setup_intr(dev, sc->sc_fast_irq, INTR_TYPE_MISC, obio_intr,
	    NULL, sc, &sc->sc_fast_ih))) {
		device_printf(dev,
		    "WARNING: unable to register interrupt handler\n");
		return (ENXIO);
	}

	/* disable all interrupts */
	REG_WRITE(ICU_ENABLE_REG, ICU_INT_MASK);

	bus_generic_probe(dev);
	bus_enumerate_hinted_children(dev);
	bus_generic_attach(dev);

	return (0);
}
예제 #2
0
파일: ofw_spibus.c 프로젝트: 2asoft/freebsd
static int
ofw_spibus_attach(device_t dev)
{
	struct spibus_softc *sc = device_get_softc(dev);
	struct ofw_spibus_devinfo *dinfo;
	phandle_t child;
	pcell_t clock, paddr;
	device_t childdev;

	sc->dev = dev;

	bus_generic_probe(dev);
	bus_enumerate_hinted_children(dev);

	/*
	 * Attach those children represented in the device tree.
	 */
	for (child = OF_child(ofw_bus_get_node(dev)); child != 0;
	    child = OF_peer(child)) {
		/*
		 * Try to get the CS number first from the spi-chipselect
		 * property, then try the reg property.
		 */
		if (OF_getencprop(child, "spi-chipselect", &paddr,
		    sizeof(paddr)) == -1) {
			if (OF_getencprop(child, "reg", &paddr,
			    sizeof(paddr)) == -1)
				continue;
		}

		/*
		 * Get the maximum clock frequency for device, zero means
		 * use the default bus speed.
		 */
		if (OF_getencprop(child, "spi-max-frequency", &clock,
		    sizeof(clock)) == -1)
			clock = 0;

		/*
		 * Now set up the SPI and OFW bus layer devinfo and add it
		 * to the bus.
		 */
		dinfo = malloc(sizeof(struct ofw_spibus_devinfo), M_DEVBUF,
		    M_NOWAIT | M_ZERO);
		if (dinfo == NULL)
			continue;
		dinfo->opd_dinfo.cs = paddr;
		dinfo->opd_dinfo.clock = clock;
		if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, child) !=
		    0) {
			free(dinfo, M_DEVBUF);
			continue;
		}
		childdev = device_add_child(dev, NULL, -1);
		device_set_ivars(childdev, dinfo);
	}

	return (bus_generic_attach(dev));
}
예제 #3
0
static int
ixp425_attach(device_t dev)
{
	struct ixp425_softc *sc;

	device_printf(dev, "%b\n", ixp4xx_read_feature_bits(), EXP_FCTRL_BITS);

	sc = device_get_softc(dev);
	sc->sc_iot = &ixp425_bs_tag;
	KASSERT(ixp425_softc == NULL, ("%s called twice?", __func__));
	ixp425_softc = sc;

	intr_enabled = 0;
	ixp425_set_intrmask();
	ixp425_set_intrsteer();
	if (cpu_is_ixp43x()) {
		intr_enabled2 = 0;
		ixp435_set_intrmask();
		ixp435_set_intrsteer();
	}

	if (bus_dma_tag_create(NULL, 1, 0, BUS_SPACE_MAXADDR_32BIT,
	    BUS_SPACE_MAXADDR, NULL, NULL,  0xffffffff, 0xff, 0xffffffff, 0, 
	    NULL, NULL, &sc->sc_dmat))
		panic("%s: failed to create dma tag", __func__);

	sc->sc_irq_rman.rm_type = RMAN_ARRAY;
	sc->sc_irq_rman.rm_descr = "IXP4XX IRQs";
	if (rman_init(&sc->sc_irq_rman) != 0 ||
	    rman_manage_region(&sc->sc_irq_rman, 0, cpu_is_ixp43x() ? 63 : 31) != 0)
		panic("%s: failed to set up IRQ rman", __func__);

	sc->sc_mem_rman.rm_type = RMAN_ARRAY;
	sc->sc_mem_rman.rm_descr = "IXP4XX Memory";
	if (rman_init(&sc->sc_mem_rman) != 0 ||
	    rman_manage_region(&sc->sc_mem_rman, 0, ~0) != 0)
		panic("%s: failed to set up memory rman", __func__);

	BUS_ADD_CHILD(dev, 0, "pcib", 0);
	BUS_ADD_CHILD(dev, 0, "ixpclk", 0);
	BUS_ADD_CHILD(dev, 0, "ixpiic", 0);
	/* XXX move to hints? */
	BUS_ADD_CHILD(dev, 0, "ixpwdog", 0);

	/* attach wired devices via hints */
	bus_enumerate_hinted_children(dev);

	if (bus_space_map(sc->sc_iot, IXP425_GPIO_HWBASE, IXP425_GPIO_SIZE,
	    0, &sc->sc_gpio_ioh))
		panic("%s: unable to map GPIO registers", __func__);
	if (bus_space_map(sc->sc_iot, IXP425_EXP_HWBASE, IXP425_EXP_SIZE,
	    0, &sc->sc_exp_ioh))
		panic("%s: unable to map Expansion Bus registers", __func__);

	bus_generic_probe(dev);
	bus_generic_attach(dev);

	return (0);
}
예제 #4
0
파일: mdio.c 프로젝트: 2asoft/freebsd
static int
mdio_attach(device_t dev)
{

	bus_generic_probe(dev);
	bus_enumerate_hinted_children(dev);
	return (bus_generic_attach(dev));
}
예제 #5
0
static int
spibus_attach(device_t dev)
{
	struct spibus_softc *sc = SPIBUS_SOFTC(dev);

	sc->dev = dev;
	bus_enumerate_hinted_children(dev);
	return (bus_generic_attach(dev));
}
예제 #6
0
static int
smbus_attach(device_t dev)
{
	struct smbus_softc *sc = device_get_softc(dev);

	mtx_init(&sc->lock, device_get_nameunit(dev), "smbus", MTX_DEF);
	bus_generic_probe(dev);
	bus_enumerate_hinted_children(dev);
	bus_generic_attach(dev);

	return (0);
}
예제 #7
0
static int
ofw_iicbus_attach(device_t dev)
{
	struct iicbus_softc *sc = IICBUS_SOFTC(dev);
	struct ofw_iicbus_devinfo *dinfo;
	phandle_t child;
	pcell_t paddr;
	device_t childdev;
	uint32_t addr;

	sc->dev = dev;
	mtx_init(&sc->lock, "iicbus", NULL, MTX_DEF);
	iicbus_reset(dev, IIC_FASTEST, 0, NULL);

	bus_generic_probe(dev);
	bus_enumerate_hinted_children(dev);

	/*
	 * Attach those children represented in the device tree.
	 */
	for (child = OF_child(ofw_bus_get_node(dev)); child != 0;
	    child = OF_peer(child)) {
		/*
		 * Try to get the I2C address first from the i2c-address
		 * property, then try the reg property.  It moves around
		 * on different systems.
		 */
		if (OF_getprop(child, "i2c-address", &paddr, sizeof(paddr)) == -1)
			if (OF_getprop(child, "reg", &paddr, sizeof(paddr)) == -1)
				continue;

		addr = fdt32_to_cpu(paddr);
		/*
		 * Now set up the I2C and OFW bus layer devinfo and add it
		 * to the bus.
		 */
		dinfo = malloc(sizeof(struct ofw_iicbus_devinfo), M_DEVBUF,
		    M_NOWAIT | M_ZERO);
		if (dinfo == NULL)
			continue;
		dinfo->opd_dinfo.addr = addr;
		if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, child) !=
		    0) {
			free(dinfo, M_DEVBUF);
			continue;
		}
		childdev = device_add_child(dev, NULL, -1);
		device_set_ivars(childdev, dinfo);
	}

	return (bus_generic_attach(dev));
}
예제 #8
0
static int
apb_attach(device_t dev)
{
	struct apb_softc *sc = device_get_softc(dev);
	int rid = 0;

	device_set_desc(dev, "APB Bus bridge");

	sc->apb_mem_rman.rm_type = RMAN_ARRAY;
	sc->apb_mem_rman.rm_descr = "APB memory window";

	if (rman_init(&sc->apb_mem_rman) != 0 ||
	    rman_manage_region(&sc->apb_mem_rman, 
			AR71XX_APB_BASE, 
			AR71XX_APB_BASE + AR71XX_APB_SIZE - 1) != 0)
		panic("apb_attach: failed to set up memory rman");

	sc->apb_irq_rman.rm_type = RMAN_ARRAY;
	sc->apb_irq_rman.rm_descr = "APB IRQ";

	if (rman_init(&sc->apb_irq_rman) != 0 ||
	    rman_manage_region(&sc->apb_irq_rman, 
			APB_IRQ_BASE, APB_IRQ_END) != 0)
		panic("apb_attach: failed to set up IRQ rman");

	if ((sc->sc_misc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 
	    RF_SHAREABLE | RF_ACTIVE)) == NULL) {
		device_printf(dev, "unable to allocate IRQ resource\n");
		return (ENXIO);
	}

	if ((bus_setup_intr(dev, sc->sc_misc_irq, INTR_TYPE_MISC, 
	    apb_filter, NULL, sc, &sc->sc_misc_ih))) {
		device_printf(dev,
		    "WARNING: unable to register interrupt handler\n");
		return (ENXIO);
	}

	bus_generic_probe(dev);
	bus_enumerate_hinted_children(dev);
	bus_generic_attach(dev);

	/*
	 * Unmask performance counter IRQ
	 */
	apb_unmask_irq((void*)APB_INTR_PMC);
	sc->sc_intr_counter[APB_INTR_PMC] = mips_intrcnt_create("apb irq5: pmc");

	return (0);
}
예제 #9
0
파일: gpiobus.c 프로젝트: fengsi/freebsd
static int
gpiobus_attach(device_t dev)
{
	int err;

	err = gpiobus_init_softc(dev);
	if (err != 0)
		return (err);

	/*
	 * Get parent's pins and mark them as unmapped
	 */
	bus_generic_probe(dev);
	bus_enumerate_hinted_children(dev);

	return (bus_generic_attach(dev));
}
예제 #10
0
파일: obio.c 프로젝트: JabirTech/Source
static int
obio_attach(device_t dev)
{
	struct obio_softc *sc = device_get_softc(dev);
	int rid, irq;

	sc->oba_mem_rman.rm_type = RMAN_ARRAY;
	sc->oba_mem_rman.rm_descr = "OBIO memeory";
	if (rman_init(&sc->oba_mem_rman) != 0 ||
	    rman_manage_region(&sc->oba_mem_rman, OBIO_MEM_START,
	        OBIO_MEM_START + OBIO_MEM_SIZE) != 0)
		panic("obio_attach: failed to set up I/O rman");

	sc->oba_irq_rman.rm_type = RMAN_ARRAY;
	sc->oba_irq_rman.rm_descr = "OBIO IRQ";

	if (rman_init(&sc->oba_irq_rman) != 0 ||
	    rman_manage_region(&sc->oba_irq_rman, IRQ_BASE, IRQ_END) != 0)
		panic("obio_attach: failed to set up IRQ rman");

	/* Hook up our interrupt handlers. We should handle IRQ0..IRQ4*/
	for(irq = 0; irq < 5; irq++) {
		if ((sc->sc_irq[irq] = bus_alloc_resource(dev, SYS_RES_IRQ, 
		    &rid, irq, irq, 1, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
			device_printf(dev, "unable to allocate IRQ resource\n");
			return (ENXIO);
		}

		if ((bus_setup_intr(dev, sc->sc_irq[irq], INTR_TYPE_MISC, 
		    obio_intr, NULL, sc, &sc->sc_ih[irq]))) {
			device_printf(dev,
			    "WARNING: unable to register interrupt handler\n");
			return (ENXIO);
		}
	}

	bus_generic_probe(dev);
	bus_enumerate_hinted_children(dev);
	bus_generic_attach(dev);

	return (0);
}
예제 #11
0
/*
 * We add all the devices which we know about.
 * The generic attach routine will attach them if they are alive.
 */
static int
iicbus_attach(device_t dev)
{
#if SCAN_IICBUS
	unsigned char addr;
#endif
	struct iicbus_softc *sc = IICBUS_SOFTC(dev);
	int strict;

	sc->dev = dev;
	mtx_init(&sc->lock, "iicbus", NULL, MTX_DEF);
	iicbus_init_frequency(dev, 0);
	iicbus_reset(dev, IIC_FASTEST, 0, NULL);
	if (resource_int_value(device_get_name(dev),
		device_get_unit(dev), "strict", &strict) == 0)
		sc->strict = strict;
	else
		sc->strict = 1;

	/* device probing is meaningless since the bus is supposed to be
	 * hot-plug. Moreover, some I2C chips do not appreciate random
	 * accesses like stop after start to fast, reads for less than
	 * x bytes...
	 */
#if SCAN_IICBUS
	printf("Probing for devices on iicbus%d:", device_get_unit(dev));

	/* probe any devices */
	for (addr = 16; addr < 240; addr++) {
		if (iic_probe_device(dev, (u_char)addr)) {
			printf(" <%x>", addr);
		}
	}
	printf("\n");
#endif
	bus_generic_probe(dev);
	bus_enumerate_hinted_children(dev);
	bus_generic_attach(dev);
        return (0);
}
예제 #12
0
static int
gpiobus_attach(device_t dev)
{
	struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev);
	int res;

	sc->sc_busdev = dev;
	sc->sc_dev = device_get_parent(dev);
	res = GPIO_PIN_MAX(sc->sc_dev, &sc->sc_npins);
	if (res)
		return (ENXIO);

	KASSERT(sc->sc_npins != 0, ("GPIO device with no pins"));

	/*
	 * Increase to get number of pins
	 */
	sc->sc_npins++;

	sc->sc_pins_mapped = malloc(sizeof(int) * sc->sc_npins, M_DEVBUF, 
	    M_NOWAIT | M_ZERO);

	if (!sc->sc_pins_mapped)
		return (ENOMEM);

	/* init bus lock */
	GPIOBUS_LOCK_INIT(sc);

	/*
	 * Get parent's pins and mark them as unmapped
	 */
	bus_generic_probe(dev);
	bus_enumerate_hinted_children(dev);

	return (bus_generic_attach(dev));
}
예제 #13
0
static int
ofw_gpiobus_attach(device_t dev)
{
	int err;
	phandle_t child;

	err = gpiobus_init_softc(dev);
	if (err != 0)
		return (err);
	bus_generic_probe(dev);
	bus_enumerate_hinted_children(dev);
	/*
	 * Attach the children represented in the device tree.
	 */
	for (child = OF_child(ofw_bus_get_node(dev)); child != 0;
	    child = OF_peer(child)) {
		if (!OF_hasprop(child, "gpios"))
			continue;
		if (ofw_gpiobus_add_fdt_child(dev, NULL, child) == NULL)
			continue;
	}

	return (bus_generic_attach(dev));
}
예제 #14
0
파일: apb.c 프로젝트: jaredmcneill/freebsd
static int
apb_attach(device_t dev)
{
	struct apb_softc *sc = device_get_softc(dev);
#ifdef INTRNG
	intptr_t xref = pic_xref(dev);
	int miscirq;
#else
	int rid = 0;
#endif

	sc->apb_dev = dev;

	sc->apb_mem_rman.rm_type = RMAN_ARRAY;
	sc->apb_mem_rman.rm_descr = "APB memory window";

	if(ar531x_soc >= AR531X_SOC_AR5315) {
		if (rman_init(&sc->apb_mem_rman) != 0 ||
		    rman_manage_region(&sc->apb_mem_rman, 
			AR5315_APB_BASE, 
			AR5315_APB_BASE + AR5315_APB_SIZE - 1) != 0)
			panic("apb_attach: failed to set up memory rman");
	} else {
		if (rman_init(&sc->apb_mem_rman) != 0 ||
		    rman_manage_region(&sc->apb_mem_rman, 
			AR5312_APB_BASE, 
			AR5312_APB_BASE + AR5312_APB_SIZE - 1) != 0)
			panic("apb_attach: failed to set up memory rman");
	}

	sc->apb_irq_rman.rm_type = RMAN_ARRAY;
	sc->apb_irq_rman.rm_descr = "APB IRQ";

	if (rman_init(&sc->apb_irq_rman) != 0 ||
	    rman_manage_region(&sc->apb_irq_rman, 
			APB_IRQ_BASE, APB_IRQ_END) != 0)
		panic("apb_attach: failed to set up IRQ rman");

#ifndef INTRNG
	if ((sc->sc_misc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 
	    RF_SHAREABLE | RF_ACTIVE)) == NULL) {
		device_printf(dev, "unable to allocate IRQ resource\n");
		return (ENXIO);
	}

	if ((bus_setup_intr(dev, sc->sc_misc_irq, INTR_TYPE_MISC, 
	    apb_filter, NULL, sc, &sc->sc_misc_ih))) {
		device_printf(dev,
		    "WARNING: unable to register interrupt handler\n");
		return (ENXIO);
	}
#else
	/* Register the interrupts */
	if (apb_pic_register_isrcs(sc) != 0) {
		device_printf(dev, "could not register PIC ISRCs\n");
		return (ENXIO);
	}

	/*
	 * Now, when everything is initialized, it's right time to
	 * register interrupt controller to interrupt framefork.
	 */
	if (intr_pic_register(dev, xref) == NULL) {
		device_printf(dev, "could not register PIC\n");
		return (ENXIO);
	}

	if(ar531x_soc >= AR531X_SOC_AR5315) {
		miscirq = AR5315_CPU_IRQ_MISC;
	} else {
		miscirq = AR5312_IRQ_MISC;
	}
	cpu_establish_hardintr("aric", apb_filter, NULL, sc, miscirq,
	    INTR_TYPE_MISC, NULL);
#endif

	/* mask all misc interrupt */
	if(ar531x_soc >= AR531X_SOC_AR5315) {
		ATH_WRITE_REG(AR5315_SYSREG_BASE
			+ AR5315_SYSREG_MISC_INTMASK, 0);
	} else {
		ATH_WRITE_REG(AR5312_SYSREG_BASE
			+ AR5312_SYSREG_MISC_INTMASK, 0);
	}

	bus_generic_probe(dev);
	bus_enumerate_hinted_children(dev);
	bus_generic_attach(dev);

	return (0);
}
예제 #15
0
static int
ofw_iicbus_attach(device_t dev)
{
	struct iicbus_softc *sc = IICBUS_SOFTC(dev);
	struct ofw_iicbus_devinfo *dinfo;
	phandle_t child, node, root;
	pcell_t freq, paddr;
	device_t childdev;
	ssize_t compatlen;
	char compat[255];
	char *curstr;
	u_int iic_addr_8bit = 0;

	sc->dev = dev;
	mtx_init(&sc->lock, "iicbus", NULL, MTX_DEF);

	/*
	 * If there is a clock-frequency property for the device node, use it as
	 * the starting value for the bus frequency.  Then call the common
	 * routine that handles the tunable/sysctl which allows the FDT value to
	 * be overridden by the user.
	 */
	node = ofw_bus_get_node(dev);
	freq = 0;
	OF_getencprop(node, "clock-frequency", &freq, sizeof(freq));
	iicbus_init_frequency(dev, freq);
	
	iicbus_reset(dev, IIC_FASTEST, 0, NULL);

	bus_generic_probe(dev);
	bus_enumerate_hinted_children(dev);

	/*
	 * Check if we're running on a PowerMac, needed for the I2C
	 * address below.
	 */
	root = OF_peer(0);
	compatlen = OF_getprop(root, "compatible", compat,
				sizeof(compat));
	if (compatlen != -1) {
	    for (curstr = compat; curstr < compat + compatlen;
		curstr += strlen(curstr) + 1) {
		if (strncmp(curstr, "MacRISC", 7) == 0)
		    iic_addr_8bit = 1;
	    }
	}

	/*
	 * Attach those children represented in the device tree.
	 */
	for (child = OF_child(node); child != 0; child = OF_peer(child)) {
		/*
		 * Try to get the I2C address first from the i2c-address
		 * property, then try the reg property.  It moves around
		 * on different systems.
		 */
		if (OF_getencprop(child, "i2c-address", &paddr,
		    sizeof(paddr)) == -1)
			if (OF_getencprop(child, "reg", &paddr,
			    sizeof(paddr)) == -1)
				continue;

		/*
		 * Now set up the I2C and OFW bus layer devinfo and add it
		 * to the bus.
		 */
		dinfo = malloc(sizeof(struct ofw_iicbus_devinfo), M_DEVBUF,
		    M_NOWAIT | M_ZERO);
		if (dinfo == NULL)
			continue;
		/*
		 * FreeBSD drivers expect I2C addresses to be expressed as
		 * 8-bit values.  Apple OFW data contains 8-bit values, but
		 * Linux FDT data contains 7-bit values, so shift them up to
		 * 8-bit format.
		 */
		if (iic_addr_8bit)
		    dinfo->opd_dinfo.addr = paddr;
		else
		    dinfo->opd_dinfo.addr = paddr << 1;

		if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, child) !=
		    0) {
			free(dinfo, M_DEVBUF);
			continue;
		}

		childdev = device_add_child(dev, NULL, -1);
		resource_list_init(&dinfo->opd_dinfo.rl);
		ofw_bus_intr_to_rl(childdev, child,
					&dinfo->opd_dinfo.rl, NULL);
		device_set_ivars(childdev, dinfo);
	}

	/* Register bus */
	OF_device_register_xref(OF_xref_from_node(node), dev);
	return (bus_generic_attach(dev));
}
예제 #16
0
static int
ofw_iicbus_attach(device_t dev)
{
	struct iicbus_softc *sc = IICBUS_SOFTC(dev);
	struct ofw_iicbus_devinfo *dinfo;
	phandle_t child, node;
	pcell_t freq, paddr;
	device_t childdev;

	sc->dev = dev;
	mtx_init(&sc->lock, "iicbus", NULL, MTX_DEF);

	/*
	 * If there is a clock-frequency property for the device node, use it as
	 * the starting value for the bus frequency.  Then call the common
	 * routine that handles the tunable/sysctl which allows the FDT value to
	 * be overridden by the user.
	 */
	node = ofw_bus_get_node(dev);
	freq = 0;
	OF_getencprop(node, "clock-frequency", &freq, sizeof(freq));
	iicbus_init_frequency(dev, freq);
	
	iicbus_reset(dev, IIC_FASTEST, 0, NULL);

	bus_generic_probe(dev);
	bus_enumerate_hinted_children(dev);

	/*
	 * Attach those children represented in the device tree.
	 */
	for (child = OF_child(node); child != 0; child = OF_peer(child)) {
		/*
		 * Try to get the I2C address first from the i2c-address
		 * property, then try the reg property.  It moves around
		 * on different systems.
		 */
		if (OF_getencprop(child, "i2c-address", &paddr,
		    sizeof(paddr)) == -1)
			if (OF_getencprop(child, "reg", &paddr,
			    sizeof(paddr)) == -1)
				continue;

		/*
		 * Now set up the I2C and OFW bus layer devinfo and add it
		 * to the bus.
		 */
		dinfo = malloc(sizeof(struct ofw_iicbus_devinfo), M_DEVBUF,
		    M_NOWAIT | M_ZERO);
		if (dinfo == NULL)
			continue;
		/*
		 * FreeBSD drivers expect I2C addresses to be expressed as
		 * 8-bit values.  Apple OFW data contains 8-bit values, but
		 * Linux FDT data contains 7-bit values, so shift them up to
		 * 8-bit format.
		 */
#ifdef AIM
		dinfo->opd_dinfo.addr = paddr;
#else
		dinfo->opd_dinfo.addr = paddr << 1;
#endif
		if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, child) !=
		    0) {
			free(dinfo, M_DEVBUF);
			continue;
		}

		childdev = device_add_child(dev, NULL, -1);
		resource_list_init(&dinfo->opd_dinfo.rl);
		ofw_bus_intr_to_rl(childdev, child,
					&dinfo->opd_dinfo.rl, NULL);
		device_set_ivars(childdev, dinfo);
	}

	return (bus_generic_attach(dev));
}
예제 #17
0
파일: obio.c 프로젝트: 2asoft/freebsd
static int
obio_attach(device_t dev)
{
	struct obio_softc *sc = device_get_softc(dev);
	int rid;

	sc->oba_mem_rman.rm_type = RMAN_ARRAY;
	sc->oba_mem_rman.rm_descr = "OBIO memory";
	if (rman_init(&sc->oba_mem_rman) != 0 ||
	    rman_manage_region(&sc->oba_mem_rman, OBIO_MEM_START,
	        OBIO_MEM_END) != 0)
		panic("obio_attach: failed to set up I/O rman");

	sc->oba_irq_rman.rm_type = RMAN_ARRAY;
	sc->oba_irq_rman.rm_descr = "OBIO IRQ";
	if (rman_init(&sc->oba_irq_rman) != 0 ||
	    rman_manage_region(&sc->oba_irq_rman, 0, NIRQS-1) != 0)
		panic("obio_attach: failed to set up IRQ rman");

	/* Hook up our interrupt handler. */
	if ((sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
	    RT305X_INTR, RT305X_INTR, 1,
	    RF_SHAREABLE | RF_ACTIVE)) == NULL) {
		device_printf(dev, "unable to allocate IRQ resource\n");
		return (ENXIO);
	}

	if ((bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC, obio_intr, NULL,
	    sc, &sc->sc_ih))) {
		device_printf(dev,
		    "WARNING: unable to register interrupt handler\n");
		return (ENXIO);
	}

	/* Hook up our FAST interrupt handler. */
	if ((sc->sc_fast_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
	    RT305X_FAST_INTR, RT305X_FAST_INTR, 1,
	    RF_SHAREABLE | RF_ACTIVE)) == NULL) {
		device_printf(dev, "unable to allocate IRQ resource\n");
		return (ENXIO);
	}

	if ((bus_setup_intr(dev, sc->sc_fast_irq, INTR_TYPE_MISC, obio_intr,
	    NULL, sc, &sc->sc_fast_ih))) {
		device_printf(dev,
		    "WARNING: unable to register interrupt handler\n");
		return (ENXIO);
	}

	/* disable all interrupts */
	rt305x_ic_set(IC_INT_DIS, IC_INT_MASK|IC_LINE_GLOBAL);

	bus_generic_probe(dev);

	obio_add_res_child(dev, "rt305x_sysctl", 0, 
	    SYSCTL_BASE, (SYSCTL_END - SYSCTL_BASE + 1),
	    IC_SYSCTL);
	obio_add_res_child(dev, "rt305x_ic", 0, 
	    INTCTL_BASE, (INTCTL_END - INTCTL_BASE + 1),
	    -1);
#ifdef notyet
	obio_add_res_child(dev, "timer",0, 
	    TIMER_BASE, (TIMER_END - TIMER_BASE  + 1),
	    IC_TIMER0);
	obio_add_res_child(dev, "rt305x_memc", 0,
	    MEMCTRL_BASE, (MEMCTRL_END - MEMCTRL_BASE + 1),
	    -1);
	obio_add_res_child(dev, "pcm", 	0, 
	    PCM_BASE, (PCM_END - PCM_BASE  + 1),
	    IC_PCM);
#endif
	obio_add_res_child(dev, "uart", 0, 
	    UART_BASE, (UART_END - UART_BASE + 1),
	    IC_UART);
	obio_add_res_child(dev, "gpio", 0, 
	    PIO_BASE, (PIO_END - PIO_BASE  + 1),
	    IC_PIO);
#ifdef notyet
	obio_add_res_child(dev, "rt305x_dma", 0,
	    GDMA_BASE, (GDMA_END - GDMA_BASE + 1),
	    IC_DMA);
	obio_add_res_child(dev, "rt305x_nandc", 0,
	    NANDFC_BASE, (NANDFC_END - NANDFC_BASE  + 1),
	    IC_NAND);
	obio_add_res_child(dev, "i2c", 	0,
	    I2C_BASE, (I2C_END - I2C_BASE  + 1),
	    -1);
	obio_add_res_child(dev, "i2s", 0,
	    I2S_BASE, (I2S_END - I2S_BASE  + 1),
	    IC_I2S);
#endif
	obio_add_res_child(dev, "spi", 0, 
	    SPI_BASE, (SPI_END - SPI_BASE  + 1),
	    -1);
	obio_add_res_child(dev, "uart", 1,
	    UARTLITE_BASE, (UARTLITE_END - UARTLITE_BASE + 1),
	    IC_UARTLITE);
#if !defined(RT5350) && !defined(MT7620)
	obio_add_res_child(dev, "cfi", 	0,
	    FLASH_BASE, (FLASH_END - FLASH_BASE  + 1),
	    -1);
	obio_add_res_child(dev, "dwcotg", 0,
	    USB_OTG_BASE, (USB_OTG_END - USB_OTG_BASE  + 1),
	    IC_OTG);
#else
	obio_add_res_child(dev, "ehci", 0,
	    USB_OTG_BASE, (USB_OTG_END - USB_OTG_BASE  + 1),
	    IC_OTG);
	obio_add_res_child(dev, "ohci", 0,
	    USB_OHCI_BASE, (USB_OHCI_END - USB_OHCI_BASE + 1),
	    IC_OTG);
#endif
	obio_add_res_child(dev, "switch", 0,
	    ETHSW_BASE, (ETHSW_END - ETHSW_BASE  + 1),
	    IC_ETHSW);

	bus_enumerate_hinted_children(dev);
	bus_generic_attach(dev);

	/* enable IC */
	rt305x_ic_set(IC_INT_ENA, IC_LINE_GLOBAL);

	return (0);
}