static int
thunder_pem_fdt_alloc_msi(device_t pci, device_t child, int count, int maxcount,
    int *irqs)
{
	phandle_t msi_parent;

	ofw_bus_msimap(ofw_bus_get_node(pci), pci_get_rid(child), &msi_parent,
	    NULL);
	return (intr_alloc_msi(pci, child, msi_parent, count, maxcount,
	    irqs));
}
Exemple #2
0
/*
 * UART Driver interface.
 */
static int
jz4780_uart_get_shift(device_t dev)
{
    phandle_t node;
    pcell_t shift;

    node = ofw_bus_get_node(dev);
    if ((OF_getencprop(node, "reg-shift", &shift, sizeof(shift))) <= 0)
        shift = 2;
    return ((int)shift);
}
Exemple #3
0
static int
ofw_cpu_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
{
	uint32_t cell;

	switch (index) {
	case CPU_IVAR_PCPU:
		OF_getprop(ofw_bus_get_node(dev), "reg", &cell, sizeof(cell));
		*result = (uintptr_t)(pcpu_find(cell));
		return (0);
	case CPU_IVAR_NOMINAL_MHZ:
		cell = 0;
		OF_getprop(ofw_bus_get_node(dev), "clock-frequency",
		    &cell, sizeof(cell));
		cell /= 1000000; /* convert to MHz */
		*result = (uintptr_t)(cell);
		return (0);
	}

	return (ENOENT);
}
Exemple #4
0
static int
awusbphy_init(device_t dev)
{
    struct awusbphy_softc *sc;
    phandle_t node;
    char pname[20];
    int error, off;
    regulator_t reg;
    hwreset_t rst;
    clk_t clk;

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

    /* Enable clocks */
    for (off = 0; clk_get_by_ofw_index(dev, off, &clk) == 0; off++) {
        error = clk_enable(clk);
        if (error != 0) {
            device_printf(dev, "couldn't enable clock %s\n",
                          clk_get_name(clk));
            return (error);
        }
    }

    /* De-assert resets */
    for (off = 0; hwreset_get_by_ofw_idx(dev, off, &rst) == 0; off++) {
        error = hwreset_deassert(rst);
        if (error != 0) {
            device_printf(dev, "couldn't de-assert reset %d\n",
                          off);
            return (error);
        }
    }

    /* Get regulators */
    for (off = 0; off < USBPHY_NPHYS; off++) {
        snprintf(pname, sizeof(pname), "usb%d_vbus-supply", off);
        if (regulator_get_by_ofw_property(dev, pname, &reg) == 0)
            sc->reg[off] = reg;
    }

    /* Get GPIOs */
    error = gpio_pin_get_by_ofw_property(dev, node, "usb0_id_det-gpios",
                                         &sc->id_det_pin);
    if (error == 0)
        sc->id_det_valid = 1;
    error = gpio_pin_get_by_ofw_property(dev, node, "usb0_vbus_det-gpios",
                                         &sc->vbus_det_pin);
    if (error == 0)
        sc->vbus_det_valid = 1;

    return (0);
}
Exemple #5
0
u_int
OF_getscsinitid(device_t dev)
{
	phandle_t node;
	uint32_t id;

	for (node = ofw_bus_get_node(dev); node != 0; node = OF_parent(node))
		if (OF_getprop(node, "scsi-initiator-id", &id,
		    sizeof(id)) > 0)
			return (id);
	return (7);
}
Exemple #6
0
static int
aw_oscclk_attach(device_t dev)
{
	struct clk_fixed_def def;
	struct clkdom *clkdom;
	phandle_t node;
	uint32_t freq;
	int error;

	node = ofw_bus_get_node(dev);

	if (OF_getencprop(node, "clock-frequency", &freq,  sizeof(freq)) <= 0) {
		device_printf(dev, "missing clock-frequency property\n");
		error = ENXIO;
		goto fail;
	}

	clkdom = clkdom_create(dev);

	memset(&def, 0, sizeof(def));
	def.clkdef.id = 1;
	def.freq = freq;
	error = clk_parse_ofw_clk_name(dev, node, &def.clkdef.name);
	if (error != 0) {
		device_printf(dev, "cannot parse clock name\n");
		error = ENXIO;
		goto fail;
	}

	error = clknode_fixed_register(clkdom, &def);
	if (error != 0) {
		device_printf(dev, "cannot register fixed clock\n");
		error = ENXIO;
		goto fail;
	}

	if (clkdom_finit(clkdom) != 0) {
		device_printf(dev, "cannot finalize clkdom initialization\n");
		error = ENXIO;
		goto fail;
	}

	if (bootverbose)
		clkdom_dump(clkdom);

	free(__DECONST(char *, def.clkdef.name), M_OFWPROP);

	return (0);

fail:
	free(__DECONST(char *, def.clkdef.name), M_OFWPROP);
	return (error);
}
static int
opalflash_attach(device_t dev)
{
	struct opalflash_softc *sc;
	phandle_t node;
	cell_t flash_blocksize, opal_id;
	uint32_t regs[2];

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

	node = ofw_bus_get_node(dev);
	OF_getencprop(node, "ibm,opal-id", &opal_id, sizeof(opal_id));
	sc->sc_opal_id = opal_id;

	if (OF_getencprop(node, "ibm,flash-block-size",
	    &flash_blocksize, sizeof(flash_blocksize)) < 0) {
		device_printf(dev, "Cannot determine flash block size.\n");
		return (ENXIO);
	}

	if (!OF_hasprop(node, "no-erase"))
		sc->sc_erase = true;

	OPALFLASH_LOCK_INIT(sc);

	if (OF_getencprop(node, "reg", regs, sizeof(regs)) < 0) {
		device_printf(dev, "Unable to get flash size.\n");
		return (ENXIO);
	}

	sc->sc_disk = disk_alloc();
	sc->sc_disk->d_name = "opalflash";
	sc->sc_disk->d_open = opalflash_open;
	sc->sc_disk->d_close = opalflash_close;
	sc->sc_disk->d_strategy = opalflash_strategy;
	sc->sc_disk->d_ioctl = opalflash_ioctl;
	sc->sc_disk->d_getattr = opalflash_getattr;
	sc->sc_disk->d_drv1 = sc;
	sc->sc_disk->d_maxsize = DFLTPHYS;
	sc->sc_disk->d_mediasize = regs[1];
	sc->sc_disk->d_unit = device_get_unit(sc->sc_dev);
	sc->sc_disk->d_sectorsize = FLASH_BLOCKSIZE;
	    sc->sc_disk->d_stripesize = flash_blocksize;
	sc->sc_disk->d_dump = NULL;

	disk_create(sc->sc_disk, DISK_VERSION);
	bioq_init(&sc->sc_bio_queue);

	kproc_create(&opalflash_task, sc, &sc->sc_p, 0, 0, "task: OPAL Flash");

	return (0);
}
Exemple #8
0
void
phy_register_provider(device_t provider_dev)
{
    phandle_t xref, node;

    node = ofw_bus_get_node(provider_dev);
    if (node <= 0)
        panic("%s called on not ofw based device.\n", __func__);

    xref = OF_xref_from_node(node);
    OF_device_register_xref(xref, provider_dev);
}
Exemple #9
0
static int
aw_nmi_attach(device_t dev)
{
	struct aw_nmi_softc *sc;
	phandle_t xref;

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

	if (bus_alloc_resources(dev, aw_nmi_res_spec, sc->res) != 0) {
		device_printf(dev, "can't allocate device resources\n");
		return (ENXIO);
	}
	if ((bus_setup_intr(dev, sc->res[1], INTR_TYPE_MISC,
	    aw_nmi_intr, NULL, sc, &sc->intrcookie))) {
		device_printf(dev, "unable to register interrupt handler\n");
		bus_release_resources(dev, aw_nmi_res_spec, sc->res);
		return (ENXIO);
	}

	switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) {
	case A20_NMI:
		sc->enable_reg = A20_NMI_IRQ_ENABLE_REG;
		break;
	case A31_NMI:
		sc->enable_reg = A31_NMI_IRQ_ENABLE_REG;
		break;
	}

	/* Disable and clear interrupts */
	SC_NMI_WRITE(sc, sc->enable_reg, !NMI_IRQ_ENABLE);
	SC_NMI_WRITE(sc, NMI_IRQ_PENDING_REG, NMI_IRQ_ACK);

	xref = OF_xref_from_node(ofw_bus_get_node(dev));
	/* Register our isrc */
	sc->intr.irq = 0;
	sc->intr.pol = INTR_POLARITY_CONFORM;
	sc->intr.tri = INTR_TRIGGER_CONFORM;
	if (intr_isrc_register(&sc->intr.isrc, sc->dev, 0, "%s,%u",
	      device_get_nameunit(sc->dev), sc->intr.irq) != 0)
		goto error;

	if (intr_pic_register(dev, (intptr_t)xref) == NULL) {
		device_printf(dev, "could not register pic\n");
		goto error;
	}
	return (0);

error:
	bus_teardown_intr(dev, sc->res[1], sc->intrcookie);
	bus_release_resources(dev, aw_nmi_res_spec, sc->res);
	return (ENXIO);
}
Exemple #10
0
static int
edma_attach(device_t dev)
{
	struct edma_softc *sc;
	phandle_t node;
	int dts_value;
	int len;

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

	if ((node = ofw_bus_get_node(sc->dev)) == -1)
		return (ENXIO);

	if ((len = OF_getproplen(node, "device-id")) <= 0)
		return (ENXIO);

	OF_getprop(node, "device-id", &dts_value, len);
	sc->device_id = fdt32_to_cpu(dts_value);

	sc->dma_stop = dma_stop;
	sc->dma_setup = dma_setup;
	sc->dma_request = dma_request;
	sc->channel_configure = channel_configure;
	sc->channel_free = channel_free;

	if (bus_alloc_resources(dev, edma_spec, sc->res)) {
		device_printf(dev, "could not allocate resources\n");
		return (ENXIO);
	}

	/* Memory interface */
	sc->bst = rman_get_bustag(sc->res[0]);
	sc->bsh = rman_get_bushandle(sc->res[0]);
	sc->bst_tcd = rman_get_bustag(sc->res[1]);
	sc->bsh_tcd = rman_get_bushandle(sc->res[1]);

	/* Setup interrupt handlers */
	if (bus_setup_intr(dev, sc->res[2], INTR_TYPE_BIO | INTR_MPSAFE,
		NULL, edma_transfer_complete_intr, sc, &sc->tc_ih)) {
		device_printf(dev, "Unable to alloc DMA intr resource.\n");
		return (ENXIO);
	}

	if (bus_setup_intr(dev, sc->res[3], INTR_TYPE_BIO | INTR_MPSAFE,
		NULL, edma_err_intr, sc, &sc->err_ih)) {
		device_printf(dev, "Unable to alloc DMA Err intr resource.\n");
		return (ENXIO);
	}

	return (0);
}
Exemple #11
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));
}
Exemple #12
0
static int
rtaspci_attach(device_t dev)
{
	struct		rtaspci_softc *sc;

	sc = device_get_softc(dev);

	if (OF_getencprop(ofw_bus_get_node(dev), "reg", (pcell_t *)&sc->sc_pcir,
	    sizeof(sc->sc_pcir)) == -1)
		return (ENXIO);

	sc->read_pci_config = rtas_token_lookup("read-pci-config");
	sc->write_pci_config = rtas_token_lookup("write-pci-config");
	sc->ex_read_pci_config = rtas_token_lookup("ibm,read-pci-config");
	sc->ex_write_pci_config = rtas_token_lookup("ibm,write-pci-config");

	sc->sc_extended_config = 0;
	OF_getencprop(ofw_bus_get_node(dev), "ibm,pci-config-space-type",
	    &sc->sc_extended_config, sizeof(sc->sc_extended_config));

	return (ofw_pci_attach(dev));
}
Exemple #13
0
static int
ofw_pcibus_child_pnpinfo_str_method(device_t cbdev, device_t child, char *buf,
    size_t buflen)
{
	pci_child_pnpinfo_str_method(cbdev, child, buf, buflen);

	if (ofw_bus_get_node(child) != -1)  {
		strlcat(buf, " ", buflen); /* Separate info */
		ofw_bus_gen_child_pnpinfo_str(cbdev, child, buf, buflen);
	}

	return (0);
}
Exemple #14
0
static int
opaldev_attach(device_t dev)
{
	phandle_t child;
	device_t cdev;
	uint64_t junk;
	int i, rv;
	struct ofw_bus_devinfo *dinfo;
	struct resource *irq;

	/* Test for RTC support and register clock if it works */
	rv = opal_call(OPAL_RTC_READ, vtophys(&junk), vtophys(&junk));
	do {
		rv = opal_call(OPAL_RTC_READ, vtophys(&junk), vtophys(&junk));
		if (rv == OPAL_BUSY_EVENT)
			rv = opal_call(OPAL_POLL_EVENTS, 0);
	} while (rv == OPAL_BUSY_EVENT);

	if (rv == OPAL_SUCCESS)
		clock_register(dev, 2000);
	
	EVENTHANDLER_REGISTER(shutdown_final, opal_shutdown, NULL,
	    SHUTDOWN_PRI_LAST);

	/* Bind to interrupts */
	for (i = 0; (irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &i,
	    RF_ACTIVE)) != NULL; i++)
		bus_setup_intr(dev, irq, INTR_TYPE_TTY | INTR_MPSAFE |
		    INTR_ENTROPY, NULL, opal_intr, (void *)rman_get_start(irq),
		    NULL);

	for (child = OF_child(ofw_bus_get_node(dev)); child != 0;
	    child = OF_peer(child)) {
		dinfo = malloc(sizeof(*dinfo), M_DEVBUF, M_WAITOK | M_ZERO);
		if (ofw_bus_gen_setup_devinfo(dinfo, child) != 0) {
			free(dinfo, M_DEVBUF);
			continue;
		}
		cdev = device_add_child(dev, NULL, -1);
		if (cdev == NULL) {
			device_printf(dev, "<%s>: device_add_child failed\n",
			    dinfo->obd_name);
			ofw_bus_gen_destroy_devinfo(dinfo);
			free(dinfo, M_DEVBUF);
			continue;
		}
		device_set_ivars(cdev, dinfo);
	}

	return (bus_generic_attach(dev));
}
Exemple #15
0
void
ofw_pcib_gen_setup(device_t bridge)
{
	struct ofw_pcib_gen_softc *sc;

	sc = device_get_softc(bridge);
	sc->ops_pcib_sc.dev = bridge;
	sc->ops_node = ofw_bus_get_node(bridge);
	KASSERT(sc->ops_node != 0,
	    ("ofw_pcib_gen_setup: no ofw pci parent bus!"));

	ofw_bus_setup_iinfo(sc->ops_node, &sc->ops_iinfo,
	    sizeof(ofw_pci_intr_t));
}
Exemple #16
0
static int
a20_if_dwc_init(device_t dev)
{
	const char *tx_parent_name;
	char *phy_type;
	clk_t clk_tx, clk_tx_parent;
	regulator_t reg;
	phandle_t node;
	int error;

	node = ofw_bus_get_node(dev);

	/* Configure PHY for MII or RGMII mode */
	if (OF_getprop_alloc(node, "phy-mode", 1, (void **)&phy_type)) {
		error = clk_get_by_ofw_name(dev, 0, "allwinner_gmac_tx", &clk_tx);
		if (error != 0) {
			device_printf(dev, "could not get tx clk\n");
			return (error);
		}

		if (strcmp(phy_type, "rgmii") == 0)
			tx_parent_name = "gmac_int_tx";
		else
			tx_parent_name = "mii_phy_tx";

		error = clk_get_by_name(dev, tx_parent_name, &clk_tx_parent);
		if (error != 0) {
			device_printf(dev, "could not get clock '%s'\n",
			    tx_parent_name);
			return (error);
		}

		error = clk_set_parent_by_clk(clk_tx, clk_tx_parent);
		if (error != 0) {
			device_printf(dev, "could not set tx clk parent\n");
			return (error);
		}
	}

	/* Enable PHY regulator if applicable */
	if (regulator_get_by_ofw_property(dev, 0, "phy-supply", &reg) == 0) {
		error = regulator_enable(reg);
		if (error != 0) {
			device_printf(dev, "could not enable PHY regulator\n");
			return (error);
		}
	}

	return (0);
}
Exemple #17
0
static int
mtk_gpio_detach(device_t dev)
{
	struct mtk_gpio_softc *sc = device_get_softc(dev);
	phandle_t node;

	node = ofw_bus_get_node(dev);
	intr_pic_deregister(dev, OF_xref_from_node(node));
	if (sc->intrhand != NULL)
		bus_teardown_intr(dev, sc->res[1], sc->intrhand);
	bus_release_resources(dev, mtk_gpio_spec, sc->res);
	MTK_GPIO_LOCK_DESTROY(sc);
	return (0);
}
Exemple #18
0
static int
zy7_phy_config(device_t dev, bus_space_tag_t io_tag, bus_space_handle_t bsh)
{
	phandle_t node;
	char buf[64];
	uint32_t portsc;
	int tries;

	node = ofw_bus_get_node(dev);

	if (OF_getprop(node, "phy_type", buf, sizeof(buf)) > 0) {
		portsc = bus_space_read_4(io_tag, bsh, ZY7_USB_PORTSC(1));
		portsc &= ~(ZY7_USB_PORTSC_PTS_MASK | ZY7_USB_PORTSC_PTW |
			    ZY7_USB_PORTSC_PTS2);

		if (strcmp(buf,"ulpi") == 0)
			portsc |= ZY7_USB_PORTSC_PTS_ULPI;
		else if (strcmp(buf,"utmi") == 0)
			portsc |= ZY7_USB_PORTSC_PTS_UTMI;
		else if (strcmp(buf,"utmi-wide") == 0)
			portsc |= (ZY7_USB_PORTSC_PTS_UTMI |
				   ZY7_USB_PORTSC_PTW);
		else if (strcmp(buf, "serial") == 0)
			portsc |= ZY7_USB_PORTSC_PTS_SERIAL;

		bus_space_write_4(io_tag, bsh, ZY7_USB_PORTSC(1), portsc);
	}

	if (OF_getprop(node, "phy_vbus_ext", buf, sizeof(buf)) >= 0) {

		/* Tell PHY that VBUS is supplied externally. */
		bus_space_write_4(io_tag, bsh, ZY7_USB_ULPI_VIEWPORT,
				  ZY7_USB_ULPI_VIEWPORT_RUN |
				  ZY7_USB_ULPI_VIEWPORT_RW |
				  (0 << ZY7_USB_ULPI_VIEWPORT_PORT_SHIFT) |
				  (0x0b << ZY7_USB_ULPI_VIEWPORT_ADDR_SHIFT) |
				  (0x60 << ZY7_USB_ULPI_VIEWPORT_DATAWR_SHIFT)
			);

		tries = 100;
		while ((bus_space_read_4(io_tag, bsh, ZY7_USB_ULPI_VIEWPORT) &
			ZY7_USB_ULPI_VIEWPORT_RUN) != 0) {
			if (--tries < 0)
				return (-1);
			DELAY(1);
		}
	}

	return (0);
}
Exemple #19
0
static int
openpic_ofw_attach(device_t dev)
{
	phandle_t xref, node;

	node = ofw_bus_get_node(dev);

	if (OF_getprop(node, "phandle", &xref, sizeof(xref)) == -1 &&
	    OF_getprop(node, "ibm,phandle", &xref, sizeof(xref)) == -1 &&
	    OF_getprop(node, "linux,phandle", &xref, sizeof(xref)) == -1)
		xref = node;

	return (openpic_common_attach(dev, xref));
}
Exemple #20
0
static int
tegra_uart_probe(device_t dev)
{
	struct tegra_softc *sc;
	phandle_t node;
	uint64_t freq;
	int shift;
	int rv;
	const struct ofw_compat_data *cd;

	sc = device_get_softc(dev);
	if (!ofw_bus_status_okay(dev))
		return (ENXIO);
	cd = ofw_bus_search_compatible(dev, compat_data);
	if (cd->ocd_data == 0)
		return (ENXIO);
	sc->ns8250_base.base.sc_class = (struct uart_class *)cd->ocd_data;

	rv = hwreset_get_by_ofw_name(dev, "serial", &sc->reset);
	if (rv != 0) {
		device_printf(dev, "Cannot get 'serial' reset\n");
		return (ENXIO);
	}
	rv = hwreset_deassert(sc->reset);
	if (rv != 0) {
		device_printf(dev, "Cannot unreset 'serial' reset\n");
		return (ENXIO);
	}

	node = ofw_bus_get_node(dev);
	shift = uart_fdt_get_shift1(node);
	rv = clk_get_by_ofw_index(dev, 0, &sc->clk);
	if (rv != 0) {
		device_printf(dev, "Cannot get UART clock: %d\n", rv);
		return (ENXIO);
	}
	rv = clk_enable(sc->clk);
	if (rv != 0) {
		device_printf(dev, "Cannot enable UART clock: %d\n", rv);
		return (ENXIO);
	}
	rv = clk_get_freq(sc->clk, &freq);
	if (rv != 0) {
		device_printf(dev, "Cannot enable UART clock: %d\n", rv);
		return (ENXIO);
	}
	device_printf(dev, "got UART clock: %lld\n", freq);
	return (uart_bus_probe(dev, shift, (int)freq, 0, 0));
}
Exemple #21
0
static int
nexus_attach(device_t dev)
{
    struct nexus_devinfo *ndi;
    struct nexus_softc *sc;
    device_t cdev;
    phandle_t node;

    if (strcmp(device_get_name(device_get_parent(dev)), "root") == 0) {
        node = OF_peer(0);
        if (node == -1)
            panic("%s: OF_peer failed.", __func__);

        sc = device_get_softc(dev);
        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,
                                   IV_MAX - 1) != 0 ||
                rman_manage_region(&sc->sc_mem_rman, 0ULL, ~0ULL) != 0)
            panic("%s: failed to set up rmans.", __func__);
    } else
        node = ofw_bus_get_node(dev);

    /*
     * 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 ((ndi = nexus_setup_dinfo(dev, node)) == NULL)
            continue;
        cdev = device_add_child(dev, NULL, -1);
        if (cdev == NULL) {
            device_printf(dev, "<%s>: device_add_child failed\n",
                          ndi->ndi_obdinfo.obd_name);
            nexus_destroy_dinfo(ndi);
            continue;
        }
        device_set_ivars(cdev, ndi);
    }
    return (bus_generic_attach(dev));
}
Exemple #22
0
static int
simplebus_attach(device_t dev)
{
	struct		simplebus_softc *sc;
	struct		simplebus_devinfo *di;
	phandle_t	node;
	device_t	cdev;

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

	sc->dev = dev;
	sc->node = node;

	/*
	 * Some important numbers
	 */
	sc->acells = 2;
	OF_getencprop(node, "#address-cells", &sc->acells, sizeof(sc->acells));
	sc->scells = 1;
	OF_getencprop(node, "#size-cells", &sc->scells, sizeof(sc->scells));

	if (simplebus_fill_ranges(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(node); node > 0; node = OF_peer(node)) {
		if ((di = simplebus_setup_dinfo(dev, node)) == NULL)
			continue;
		cdev = device_add_child(dev, NULL, -1);
		if (cdev == NULL) {
			device_printf(dev, "<%s>: device_add_child failed\n",
			    di->obdinfo.obd_name);
			resource_list_free(&di->rl);
			ofw_bus_gen_destroy_devinfo(&di->obdinfo);
			free(di, M_DEVBUF);
			continue;
		}
		device_set_ivars(cdev, di);
	}

	return (bus_generic_attach(dev));
}
Exemple #23
0
static int
quicc_fdt_probe(device_t dev)
{
	phandle_t par;
	pcell_t clock;

	if (!ofw_bus_is_compatible(dev, "fsl,cpm2"))
		return (ENXIO);

	par = OF_parent(ofw_bus_get_node(dev));
	if (OF_getprop(par, "bus-frequency", &clock, sizeof(clock)) <= 0)
		clock = 0;

	return (quicc_bfe_probe(dev, (uintptr_t)clock));
}
Exemple #24
0
ofw_pci_intr_t
ofw_pci_route_interrupt_common(device_t bridge, device_t dev, int pin)
{
    struct ofw_pci_softc *sc;
    struct ofw_pci_register reg;
    ofw_pci_intr_t pintr, mintr;

    sc = device_get_softc(bridge);
    pintr = pin;
    if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo,
                            &reg, sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr),
                            NULL) != 0)
        return (mintr);
    return (PCI_INVALID_IRQ);
}
Exemple #25
0
static int
ofw_pcib_pci_probe(device_t dev)
{

	if ((pci_get_class(dev) != PCIC_BRIDGE) ||
	    (pci_get_subclass(dev) != PCIS_BRIDGE_PCI)) {
		return (ENXIO);
	}

	if (ofw_bus_get_node(dev) == -1)
		return (ENXIO);

	device_set_desc(dev, "OFW PCI-PCI bridge");
	return (0);
}
Exemple #26
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);
}
Exemple #27
0
static int
tegra_lic_attach(device_t dev)
{
	struct tegra_lic_sc *sc;
	phandle_t node;
	phandle_t parent_xref;
	int i, rv;

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

	rv = OF_getencprop(node, "interrupt-parent", &parent_xref,
	    sizeof(parent_xref));
	if (rv <= 0) {
		device_printf(dev, "Cannot read parent node property\n");
		goto fail;
	}
	sc->parent = OF_device_from_xref(parent_xref);
	if (sc->parent == NULL) {
		device_printf(dev, "Cannott find parent controller\n");
		goto fail;
	}

	if (bus_alloc_resources(dev, lic_spec, sc->mem_res)) {
		device_printf(dev, "Cannott allocate resources\n");
		goto fail;
	}

	/* Disable all interrupts, route all to irq */
	for (i = 0; i < nitems(lic_spec); i++) {
		if (sc->mem_res[i] == NULL)
			continue;
		WR4(sc, i, LIC_CPU_IER_CLR, 0xFFFFFFFF);
		WR4(sc, i, LIC_CPU_IEP_CLASS, 0);
	}


	if (intr_pic_register(dev, OF_xref_from_node(node)) == NULL) {
		device_printf(dev, "Cannot register PIC\n");
		goto fail;
	}
	return (0);

fail:
	bus_release_resources(dev, lic_spec, sc->mem_res);
	return (ENXIO);
}
Exemple #28
0
static int
bcm_intc_attach(device_t dev)
{
	struct		bcm_intc_softc *sc = device_get_softc(dev);
	int		rid = 0;
	intptr_t	xref;
	sc->sc_dev = dev;

	if (bcm_intc_sc)
		return (ENXIO);

	sc->intc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
	if (sc->intc_res == NULL) {
		device_printf(dev, "could not allocate memory resource\n");
		return (ENXIO);
	}

	xref = OF_xref_from_node(ofw_bus_get_node(dev));
	if (bcm_intc_pic_register(sc, xref) != 0) {
		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->intc_res);
		device_printf(dev, "could not register PIC\n");
		return (ENXIO);
	}

	rid = 0;
	sc->intc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
	    RF_ACTIVE);
	if (sc->intc_irq_res == NULL) {
		if (intr_pic_claim_root(dev, xref, bcm2835_intc_intr, sc, 0) != 0) {
			/* XXX clean up */
			device_printf(dev, "could not set PIC as a root\n");
			return (ENXIO);
		}
	} else {
		if (bus_setup_intr(dev, sc->intc_irq_res, INTR_TYPE_CLK,
		    bcm2835_intc_intr, NULL, sc, &sc->intc_irq_hdl)) {
			/* XXX clean up */
			device_printf(dev, "could not setup irq handler\n");
			return (ENXIO);
		}
	}
	sc->intc_bst = rman_get_bustag(sc->intc_res);
	sc->intc_bsh = rman_get_bushandle(sc->intc_res);

	bcm_intc_sc = sc;

	return (0);
}
Exemple #29
0
static int
aml8726_gpio_attach(device_t dev)
{
	struct aml8726_gpio_softc *sc = device_get_softc(dev);
	phandle_t node;
	pcell_t prop;

	sc->dev = dev;

	node = ofw_bus_get_node(dev);

	if (OF_getencprop(node, "pin-count",
	    &prop, sizeof(prop)) <= 0) {
		device_printf(dev, "missing pin-count attribute in FDT\n");
		return (ENXIO);
	}
	sc->npins = prop;

	if (sc->npins > 32)
		return (ENXIO);

	if (bus_alloc_resources(dev, aml8726_gpio_spec, sc->res)) {
		device_printf(dev, "can not allocate resources for device\n");
		return (ENXIO);
	}

	/*
	 * The GPIOAO OUT bits occupy the upper word of the OEN register.
	 */
	if (rman_get_start(sc->res[1]) == rman_get_start(sc->res[0]))
	  if (sc->npins > 16) {
		device_printf(dev,
		    "too many pins for overlapping OEN and OUT\n");
		bus_release_resources(dev, aml8726_gpio_spec, sc->res);
		return (ENXIO);
		}

	AML_GPIO_LOCK_INIT(sc);

	sc->busdev = gpiobus_attach_bus(dev);
	if (sc->busdev == NULL) {
		AML_GPIO_LOCK_DESTROY(sc);
		bus_release_resources(dev, aml8726_gpio_spec, sc->res);
		return (ENXIO);
	}

	return (0);
}
Exemple #30
0
static int
get_panel_info(struct fimd_softc *sc, struct panel_info *panel)
{
	phandle_t node;
	pcell_t dts_value[3];
	int len;

	if ((node = ofw_bus_get_node(sc->dev)) == -1)
		return (ENXIO);

	/* panel size */
	if ((len = OF_getproplen(node, "panel-size")) <= 0)
		return (ENXIO);
	OF_getprop(node, "panel-size", &dts_value, len);
	panel->width = fdt32_to_cpu(dts_value[0]);
	panel->height = fdt32_to_cpu(dts_value[1]);

	/* hsync */
	if ((len = OF_getproplen(node, "panel-hsync")) <= 0)
		return (ENXIO);
	OF_getprop(node, "panel-hsync", &dts_value, len);
	panel->h_back_porch = fdt32_to_cpu(dts_value[0]);
	panel->h_pulse_width = fdt32_to_cpu(dts_value[1]);
	panel->h_front_porch = fdt32_to_cpu(dts_value[2]);

	/* vsync */
	if ((len = OF_getproplen(node, "panel-vsync")) <= 0)
		return (ENXIO);
	OF_getprop(node, "panel-vsync", &dts_value, len);
	panel->v_back_porch = fdt32_to_cpu(dts_value[0]);
	panel->v_pulse_width = fdt32_to_cpu(dts_value[1]);
	panel->v_front_porch = fdt32_to_cpu(dts_value[2]);

	/* clk divider */
	if ((len = OF_getproplen(node, "panel-clk-div")) <= 0)
		return (ENXIO);
	OF_getprop(node, "panel-clk-div", &dts_value, len);
	panel->clk_div = fdt32_to_cpu(dts_value[0]);

	/* backlight pin */
	if ((len = OF_getproplen(node, "panel-backlight-pin")) <= 0)
		return (ENXIO);
	OF_getprop(node, "panel-backlight-pin", &dts_value, len);
	panel->backlight_pin = fdt32_to_cpu(dts_value[0]);

	return (0);
}