Ejemplo n.º 1
0
void
vbus_attach(device_t parent, device_t self, void *aux)
{
        struct vbus_softc *sc = device_private(self);
	struct mainbus_attach_args *ma = aux;
	int node;

	sc->sc_bustag = vbus_alloc_bus_tag(sc, ma->ma_bustag);
	sc->sc_dmatag = ma->ma_dmatag;
	printf("\n");

	for (node = OF_child(ma->ma_node); node; node = OF_peer(node)) {
		struct vbus_attach_args va;
		char buf[32];

		bzero(&va, sizeof(va));
		va.va_node = node;
		if (OF_getprop(node, "name", buf, sizeof(buf)) <= 0)
			continue;
		va.va_name = buf;
		va.va_bustag = sc->sc_bustag;
		va.va_dmatag = sc->sc_dmatag;
		prom_getprop(node, "reg", sizeof(*va.va_reg),
			     &va.va_nreg, (void **)&va.va_reg);
		prom_getprop(node, "interrupts", sizeof(*va.va_intr),
			     &va.va_nintr, (void **)&va.va_intr);
		config_found(self, &va, vbus_print);
	}

	struct vbus_attach_args va;
	bzero(&va, sizeof(va));
	va.va_name = "rtc";
	config_found(self, &va, vbus_print);

}
Ejemplo n.º 2
0
static int
bare_probe(platform_t plat)
{
	phandle_t cpus, child;
	uint32_t sr;
	int i, law_max, tgt;

	if ((cpus = OF_finddevice("/cpus")) != 0) {
		for (maxcpu = 0, child = OF_child(cpus); child != 0;
		    child = OF_peer(child), maxcpu++)
			;
	} else
		maxcpu = 1;

	/*
	 * Clear local access windows. Skip DRAM entries, so we don't shoot
	 * ourselves in the foot.
	 */
	law_max = law_getmax();
	for (i = 0; i < law_max; i++) {
		sr = ccsr_read4(OCP85XX_LAWSR(i));
		if ((sr & 0x80000000) == 0)
			continue;
		tgt = (sr & 0x01f00000) >> 20;
		if (tgt == OCP85XX_TGTIF_RAM1 || tgt == OCP85XX_TGTIF_RAM2 ||
		    tgt == OCP85XX_TGTIF_RAM_INTL)
			continue;

		ccsr_write4(OCP85XX_LAWSR(i), sr & 0x7fffffff);
	}

	return (BUS_PROBE_GENERIC);
}
Ejemplo n.º 3
0
static int
localbus_attach(device_t dev)
{
	device_t dev_child;
	struct localbus_softc *sc;
	struct localbus_devinfo *di;
	phandle_t dt_node, dt_child;

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

	/*
	 * Walk localbus and add direct subordinates as our children.
	 */
	dt_node = ofw_bus_get_node(dev);
	for (dt_child = OF_child(dt_node); dt_child != 0;
	    dt_child = OF_peer(dt_child)) {

		/* Check and process 'status' property. */
		if (!(fdt_is_enabled(dt_child)))
			continue;

		if (!(fdt_pm_is_enabled(dt_child)))
			continue;

		di = malloc(sizeof(*di), M_LOCALBUS, M_WAITOK | M_ZERO);
		if (ofw_bus_gen_setup_devinfo(&di->di_ofw, dt_child) != 0) {
			free(di, M_LOCALBUS);
			device_printf(dev, "could not set up devinfo\n");
			continue;
		}

		resource_list_init(&di->di_res);
		if (fdt_localbus_reg_decode(dt_child, sc, di)) {
			device_printf(dev, "could not process 'reg' "
			    "property\n");
			ofw_bus_gen_destroy_devinfo(&di->di_ofw);
			free(di, M_LOCALBUS);
			continue;
		}

		/* Add newbus device for this FDT node */
		dev_child = device_add_child(dev, NULL, -1);
		if (dev_child == NULL) {
			device_printf(dev, "could not add child: %s\n",
			    di->di_ofw.obd_name);
			resource_list_free(&di->di_res);
			ofw_bus_gen_destroy_devinfo(&di->di_ofw);
			free(di, M_LOCALBUS);
			continue;
		}
#ifdef DEBUG
		device_printf(dev, "added child: %s\n\n", di->di_ofw.obd_name);
#endif
		device_set_ivars(dev_child, di);
	}

	return (bus_generic_attach(dev));
}
Ejemplo n.º 4
0
/*
 * Search the OFW's device tree for a named node, and return the package
 * handle for it.
 */
int
oskit_linux_ofw_findnode(char *name)
{
	int	node, child;
	int	oskit_linux_ofw_findnode_child(char *, int);

	if (!(node = OF_peer(0)))
		panic("No OFW root");

	for (child = OF_child(node); child; child = OF_peer(child)) {
		if ((node = oskit_linux_ofw_findnode_child(name, child)))
			return node;
	}

	return 0;
}
Ejemplo n.º 5
0
phandle_t
ofw_bus_find_compatible(phandle_t node, const char *onecompat)
{
	phandle_t child, ret;
	void *compat;
	int len;

	/*
	 * Traverse all children of 'start' node, and find first with
	 * matching 'compatible' property.
	 */
	for (child = OF_child(node); child != 0; child = OF_peer(child)) {
		len = OF_getprop_alloc(child, "compatible", 1, &compat);
		if (len >= 0) {
			ret = ofw_bus_node_is_compatible(compat, len,
			    onecompat);
			free(compat, M_OFWPROP);
			if (ret != 0)
				return (child);
		}

		ret = ofw_bus_find_compatible(child, onecompat);
		if (ret != 0)
			return (ret);
	}
	return (0);
}
Ejemplo n.º 6
0
static void 
pci_from_fdt_node(device_t dev_par, phandle_t dt_node, char *name,
    char *type, char *compat)
{
	u_long reg_base, reg_size;
	phandle_t dt_child;

	/*
	 * Retrieve 'reg' property.
	 */
	if (fdt_regsize(dt_node, &reg_base, &reg_size) != 0) {
		device_printf(dev_par, "could not retrieve 'reg' prop\n");
		return;
	}

	/*
	 * Walk the PCI node and instantiate newbus devices representing
	 * logical resources (bridges / ports).
	 */
	for (dt_child = OF_child(dt_node); dt_child != 0;
	    dt_child = OF_peer(dt_child)) {

		if (!(fdt_is_enabled(dt_child)))
			continue;

		newbus_pci_create(dev_par, dt_child, reg_base, reg_size);
	}
}
static int
lebuffer_attach(device_t dev)
{
	struct lebuffer_devinfo *ldi;
	device_t cdev;
	phandle_t child;
	int children;

	children = 0;
	for (child = OF_child(ofw_bus_get_node(dev)); child != 0;
	    child = OF_peer(child)) {
		if ((ldi = lebuffer_setup_dinfo(dev, child)) == NULL)
			continue;
		if (children != 0) {
			device_printf(dev,
			    "<%s>: only one child per buffer supported\n",
			    ldi->ldi_obdinfo.obd_name);
			lebuffer_destroy_dinfo(ldi);
			continue;
		}
		if ((cdev = device_add_child(dev, NULL, -1)) == NULL) {
			device_printf(dev, "<%s>: device_add_child failed\n",
			    ldi->ldi_obdinfo.obd_name);
			lebuffer_destroy_dinfo(ldi);
			continue;
		}
		device_set_ivars(cdev, ldi);
		children++;
	}
	return (bus_generic_attach(dev));
}
Ejemplo n.º 8
0
static int 
ofw_cpulist_attach(device_t dev) 
{
	struct ofw_cpulist_softc *sc;
	phandle_t root, child;
	device_t cdev;
	struct ofw_bus_devinfo *dinfo;

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

	sc->sc_addr_cells = 1;
	OF_getencprop(root, "#address-cells", &sc->sc_addr_cells,
	    sizeof(sc->sc_addr_cells));

	for (child = OF_child(root); child != 0; child = OF_peer(child)) {
		dinfo = malloc(sizeof(*dinfo), M_OFWCPU, M_WAITOK | M_ZERO);

                if (ofw_bus_gen_setup_devinfo(dinfo, child) != 0) {
                        free(dinfo, M_OFWCPU);
                        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_OFWCPU);
                        continue;
                }
		device_set_ivars(cdev, dinfo);
	}

	return (bus_generic_attach(dev));
}
Ejemplo n.º 9
0
static phandle_t
find_bsp(phandle_t node, uint32_t bspid, u_int cpu_impl)
{
	char type[sizeof("cpu")];
	phandle_t child;
	uint32_t cpuid;

	for (; node != 0; node = OF_peer(node)) {
		child = OF_child(node);
		if (child > 0) {
			child = find_bsp(child, bspid, cpu_impl);
			if (child > 0)
				return (child);
		} else {
			if (OF_getprop(node, "device_type", type,
			    sizeof(type)) <= 0)
				continue;
			if (strcmp(type, "cpu") != 0)
				continue;
			if (OF_getprop(node, cpu_cpuid_prop(cpu_impl), &cpuid,
			    sizeof(cpuid)) <= 0)
				continue;
			if (cpuid == bspid)
				return (node);
		}
	}
	return (0);
}
Ejemplo n.º 10
0
static int
ofw_pcibus_attach(device_t dev)
{
	device_t pcib;
	struct ofw_pci_register pcir;
	struct ofw_pcibus_devinfo *dinfo;
	phandle_t node, child;
	uint32_t clock;
	u_int busno, domain, func, slot;

	pcib = device_get_parent(dev);
	domain = pcib_get_domain(dev);
	busno = pcib_get_bus(dev);
	if (bootverbose)
		device_printf(dev, "domain=%d, physical bus=%d\n",
		    domain, busno);
	node = ofw_bus_get_node(dev);

	/*
	 * Add the PCI side of the host-PCI bridge itself to the bus.
	 * Note that we exclude the host-PCIe bridges here as these
	 * have no configuration space implemented themselves.
	 */
	if (strcmp(device_get_name(device_get_parent(pcib)), "nexus") == 0 &&
	    ofw_bus_get_type(pcib) != NULL &&
	    strcmp(ofw_bus_get_type(pcib), OFW_TYPE_PCIE) != 0 &&
	    (dinfo = (struct ofw_pcibus_devinfo *)pci_read_device(pcib,
	    domain, busno, 0, 0, sizeof(*dinfo))) != NULL) {
		if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, node) != 0)
			pci_freecfg((struct pci_devinfo *)dinfo);
		else
			pci_add_child(dev, (struct pci_devinfo *)dinfo);
	}

	if (OF_getprop(ofw_bus_get_node(pcib), "clock-frequency", &clock,
	    sizeof(clock)) == -1)
		clock = 33000000;
	for (child = OF_child(node); child != 0; child = OF_peer(child)) {
		if (OF_getprop(child, "reg", &pcir, sizeof(pcir)) == -1)
			continue;
		slot = OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi);
		func = OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi);
		/* Some OFW device trees contain dupes. */
		if (pci_find_dbsf(domain, busno, slot, func) != NULL)
			continue;
		ofw_pcibus_setup_device(pcib, clock, busno, slot, func);
		dinfo = (struct ofw_pcibus_devinfo *)pci_read_device(pcib,
		    domain, busno, slot, func, sizeof(*dinfo));
		if (dinfo == NULL)
			continue;
		if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, child) !=
		    0) {
			pci_freecfg((struct pci_devinfo *)dinfo);
			continue;
		}
		pci_add_child(dev, (struct pci_devinfo *)dinfo);
	}

	return (bus_generic_attach(dev));
}
Ejemplo n.º 11
0
phandle_t
ofw_pci_find_node(int bus, int slot, int func)
{
	phandle_t node, bnode;
	struct ofw_pci_register pcir;

	/*
	 * Retrieve the bus node from the mapping that was created on
	 * initialization. The bus numbers the firmware uses cannot be trusted,
	 * so they might have needed to be changed and this is necessary.
	 */
	if (bus >= pci_bus_map_sz)
		return (0);
	bnode = pci_bus_map[bus];
	if (bnode == 0)
		return (0);
	for (node = OF_child(bnode); node != 0 && node != -1;
	     node = OF_peer(node)) {
		if (OF_getprop(node, "reg", &pcir, sizeof(pcir)) == -1)
			continue;
		if (OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi) == slot &&
		    OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi) == func)
			return (node);
	}
	return (0);
}
Ejemplo n.º 12
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.º 13
0
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));
}
Ejemplo n.º 14
0
static int
mtk_pinctrl_configure(device_t dev, phandle_t cfgxref)
{
	struct mtk_pin_group *pintable;
	phandle_t node, child;
	uint32_t socid;
	int ret;

	node = OF_node_from_xref(cfgxref);
	ret = 0;

	/* Now, get the system type, so we can get the proper GPIO mode array */
	socid = mtk_soc_get_socid();

	switch (socid) {
	case MTK_SOC_RT3050: /* fallthrough */
	case MTK_SOC_RT3052:
	case MTK_SOC_RT3350:
		pintable = rt3050_pintable;
		break;
	case MTK_SOC_RT3352:
		pintable = rt3352_pintable;
		break;
	case MTK_SOC_RT3662: /* fallthrough */
	case MTK_SOC_RT3883:
		pintable = rt3883_pintable;
		break;
	case MTK_SOC_RT5350:
		pintable = rt5350_pintable;
		break;
	case MTK_SOC_MT7620A: /* fallthrough */
	case MTK_SOC_MT7620N:
		pintable = mt7620_pintable;
		break;
	case MTK_SOC_MT7628: /* fallthrough */
	case MTK_SOC_MT7688:
		pintable = mt7628_pintable;
		break;
	case MTK_SOC_MT7621:
		pintable = mt7621_pintable;
		break;
	default:
		ret = ENOENT;
		goto out;
	}

	/*
	 * OpenWRT dts files have single child within the pinctrl nodes, which
	 * contains the 'ralink,group' and 'ralink,function' properties.
	 */ 
	for (child = OF_child(node); child != 0 && child != -1;
	    child = OF_peer(child)) {
		if ((ret = mtk_pinctrl_process_node(dev, pintable, child)) != 0)
			return (ret);
	}

out:
	return (ret);
}
Ejemplo n.º 15
0
static int
openprom_node_valid(phandle_t node)
{

	if (node == 0)
		return (0);
	return (openprom_node_search(OF_peer(0), node));
}
Ejemplo n.º 16
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.º 17
0
/*
 * Verify target ID is valid (exists in the OPENPROM tree), as
 * listed from node ID sid forward.
 */
int
openpromcheckid(int sid, int tid)
{
	for (; sid != 0; sid = OF_peer(sid))
		if (sid == tid || openpromcheckid(OF_child(sid), tid))
			return (1);

	return (0);
}
Ejemplo n.º 18
0
static int
bare_probe(platform_t plat)
{

	if (OF_peer(0) == -1) /* Needs device tree to work */
		return (ENXIO);

	return (BUS_PROBE_GENERIC);
}
Ejemplo n.º 19
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.º 20
0
static int
central_attach(device_t dev)
{
	struct central_devinfo *cdi;
	struct sbus_regs *reg;
	struct central_softc *sc;
	phandle_t child;
	phandle_t node;
	device_t cdev;
	int nreg;
	int i;

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

	sc->sc_nrange = OF_getprop_alloc(node, "ranges",
	    sizeof(*sc->sc_ranges), (void **)&sc->sc_ranges);
	if (sc->sc_nrange == -1) {
		device_printf(dev, "can't get ranges\n");
		return (ENXIO);
	}

	for (child = OF_child(node); child != 0; child = OF_peer(child)) {
		cdi = malloc(sizeof(*cdi), M_DEVBUF, M_WAITOK | M_ZERO);
		if (ofw_bus_gen_setup_devinfo(&cdi->cdi_obdinfo, child) != 0) {
			free(cdi, M_DEVBUF);
			continue;
		}
		nreg = OF_getprop_alloc(child, "reg", sizeof(*reg),
		    (void **)&reg);
		if (nreg == -1) {
			device_printf(dev, "<%s>: incomplete\n",
			    cdi->cdi_obdinfo.obd_name);
			ofw_bus_gen_destroy_devinfo(&cdi->cdi_obdinfo);
			free(cdi, M_DEVBUF);
			continue;
		}
		resource_list_init(&cdi->cdi_rl);
		for (i = 0; i < nreg; i++)
			resource_list_add(&cdi->cdi_rl, SYS_RES_MEMORY, i,
			    reg[i].sbr_offset, reg[i].sbr_offset +
			    reg[i].sbr_size, reg[i].sbr_size);
		free(reg, M_OFWPROP);
		cdev = device_add_child(dev, NULL, -1);
		if (cdev == NULL) {
			device_printf(dev, "<%s>: device_add_child failed\n",
			    cdi->cdi_obdinfo.obd_name);
			resource_list_free(&cdi->cdi_rl);
			ofw_bus_gen_destroy_devinfo(&cdi->cdi_obdinfo);
			free(cdi, M_DEVBUF);
			continue;
		}
		device_set_ivars(cdev, cdi);
	}

	return (bus_generic_attach(dev));
}
Ejemplo n.º 21
0
/*
 * Bus capability support for GICv3.
 * Collects and configures device informations and finally
 * adds ITS device as a child of GICv3 in Newbus hierarchy.
 */
static int
gic_v3_ofw_bus_attach(device_t dev)
{
	struct gic_v3_ofw_devinfo *di;
	device_t child;
	phandle_t parent, node;
	pcell_t addr_cells, size_cells;

	parent = ofw_bus_get_node(dev);
	if (parent > 0) {
		addr_cells = 2;
		OF_getencprop(parent, "#address-cells", &addr_cells,
		    sizeof(addr_cells));
		size_cells = 2;
		OF_getencprop(parent, "#size-cells", &size_cells,
		    sizeof(size_cells));
		/* Iterate through all GIC subordinates */
		for (node = OF_child(parent); node > 0; node = OF_peer(node)) {
			/* Allocate and populate devinfo. */
			di = malloc(sizeof(*di), M_GIC_V3, M_WAITOK | M_ZERO);
			if (ofw_bus_gen_setup_devinfo(&di->di_dinfo, node)) {
				if (bootverbose) {
					device_printf(dev,
					    "Could not set up devinfo for ITS\n");
				}
				free(di, M_GIC_V3);
				continue;
			}

			/* Initialize and populate resource list. */
			resource_list_init(&di->di_rl);
			ofw_bus_reg_to_rl(dev, node, addr_cells, size_cells,
			    &di->di_rl);

			/* Should not have any interrupts, so don't add any */

			/* Add newbus device for this FDT node */
			child = device_add_child(dev, NULL, -1);
			if (!child) {
				if (bootverbose) {
					device_printf(dev,
					    "Could not add child: %s\n",
					    di->di_dinfo.obd_name);
				}
				resource_list_free(&di->di_rl);
				ofw_bus_gen_destroy_devinfo(&di->di_dinfo);
				free(di, M_GIC_V3);
				continue;
			}

			device_set_ivars(child, di);
		}
	}

	return (bus_generic_attach(dev));
}
Ejemplo n.º 22
0
static int
powermac_smp_next_cpu(platform_t plat, struct cpuref *cpuref)
{
	char buf[8];
	phandle_t cpu;
	int res;

	cpu = OF_peer(cpuref->cr_hwref);
	while (cpu != 0) {
		res = OF_getprop(cpu, "device_type", buf, sizeof(buf));
		if (res > 0 && strcmp(buf, "cpu") == 0)
			break;
		cpu = OF_peer(cpu);
	}
	if (cpu == 0)
		return (ENOENT);

	return (powermac_smp_fill_cpuref(cpuref, cpu));
}
Ejemplo n.º 23
0
/*
 * Verify target ID is valid (exists in the OPENPROM tree), as
 * listed from node ID sid forward.
 */
static int
openfirm_checkid(phandle_t sid, phandle_t tid)
{

	for (; sid != 0; sid = OF_peer(sid))
		if (sid == tid || openfirm_checkid(OF_child(sid), tid))
			return (1);

	return (0);
}
Ejemplo n.º 24
0
static int
chrp_smp_next_cpu(platform_t plat, struct cpuref *cpuref)
{
	char buf[8];
	phandle_t cpu;
	int i, res, cpuid;

	/* Check for whether it should be the next thread */
	res = OF_getproplen(cpuref->cr_hwref, "ibm,ppc-interrupt-server#s");
	if (res > 0) {
		cell_t interrupt_servers[res/sizeof(cell_t)];
		OF_getprop(cpuref->cr_hwref, "ibm,ppc-interrupt-server#s",
		    interrupt_servers, res);
		for (i = 0; i < res/sizeof(cell_t) - 1; i++) {
			if (interrupt_servers[i] == cpuref->cr_cpuid) {
				cpuref->cr_cpuid = interrupt_servers[i+1];
				return (0);
			}
		}
	}

	/* Next CPU core/package */
	cpu = OF_peer(cpuref->cr_hwref);
	while (cpu != 0) {
		res = OF_getprop(cpu, "device_type", buf, sizeof(buf));
		if (res > 0 && strcmp(buf, "cpu") == 0)
			break;
		cpu = OF_peer(cpu);
	}
	if (cpu == 0)
		return (ENOENT);

	cpuref->cr_hwref = cpu;
	res = OF_getprop(cpu, "ibm,ppc-interrupt-server#s", &cpuid,
	    sizeof(cpuid));
	if (res <= 0)
		res = OF_getprop(cpu, "reg", &cpuid, sizeof(cpuid));
	if (res <= 0)
		cpuid = 0;
	cpuref->cr_cpuid = cpuid;

	return (0);
}
Ejemplo n.º 25
0
static int
nexus_fdt_probe(device_t dev)
{

	if (OF_peer(0) == 0)
		return (ENXIO);

	device_quiet(dev);
	return (BUS_PROBE_DEFAULT);
}
Ejemplo n.º 26
0
void
ki2c_attach(struct device *parent, struct device *self, void *aux)
{
	struct ki2c_softc *sc = (struct ki2c_softc *)self;
	struct confargs *ca = aux;
	int node = ca->ca_node;
	int rate, count = 0;
	char name[32];

	ca->ca_reg[0] += ca->ca_baseaddr;

	if (OF_getprop(node, "AAPL,i2c-rate", &rate, 4) != 4) {
		printf(": cannot get i2c-rate\n");
		return;
	}
	if (OF_getprop(node, "AAPL,address", &sc->sc_paddr, 4) != 4) {
		printf(": unable to find i2c address\n");
		return;
	}
	if (OF_getprop(node, "AAPL,address-step", &sc->sc_regstep, 4) != 4) {
		printf(": unable to find i2c address step\n");
		return;
	}
	sc->sc_reg = mapiodev(sc->sc_paddr, (DATA+1)*sc->sc_regstep);

	printf("\n");

	ki2c_writereg(sc, STATUS, 0);
	ki2c_writereg(sc, ISR, 0);
	ki2c_writereg(sc, IER, 0);

	ki2c_setmode(sc, I2C_STDSUBMODE, 0);
	ki2c_setspeed(sc, I2C_100kHz);		/* XXX rate */

	lockinit(&sc->sc_buslock, PZERO, sc->sc_dev.dv_xname, 0, 0);
	ki2c_writereg(sc, IER,I2C_INT_DATA|I2C_INT_ADDR|I2C_INT_STOP);

	for (node = OF_child(ca->ca_node); node; node = OF_peer(node)) {
		if (OF_getprop(node, "name", &name, sizeof name) > 0) {
			if (strcmp(name, "i2c-bus") == 0) {
				ki2c_attach_bus(sc, &sc->sc_bus[count], node);
				if (++count >= KI2C_MAX_BUSSES)
					break;
			}
		}
	}

	/* 
	 * If we didn't find any i2c-bus nodes, there is only a single
	 * i2c bus.
	 */

	if (count == 0)
		ki2c_attach_bus(sc, &sc->sc_bus[0], ca->ca_node);
}
Ejemplo n.º 27
0
static int 
vdevice_attach(device_t dev) 
{
	phandle_t root, child;
	device_t cdev;
	int icells, i, nintr, *intr;
	phandle_t iparent;
	struct vdevice_devinfo *dinfo;

	root = ofw_bus_get_node(dev);

	for (child = OF_child(root); child != 0; child = OF_peer(child)) {
		dinfo = malloc(sizeof(*dinfo), M_DEVBUF, M_WAITOK | M_ZERO);

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

		if (OF_searchprop(child, "#interrupt-cells", &icells,
		    sizeof(icells)) <= 0)
			icells = 2;
		if (OF_getprop(child, "interrupt-parent", &iparent,
		    sizeof(iparent)) <= 0)
			iparent = -1;
		nintr = OF_getprop_alloc(child, "interrupts", sizeof(*intr),
		    (void **)&intr);
		if (nintr > 0) {
			for (i = 0; i < nintr; i += icells) {
				u_int irq = intr[i];
				if (iparent != -1)
					irq = ofw_bus_map_intr(dev, iparent,
					    icells, &intr[i]);

				resource_list_add(&dinfo->mdi_resources,
				    SYS_RES_IRQ, i, irq, irq, i);
			}
		}

                cdev = device_add_child(dev, NULL, -1);
                if (cdev == NULL) {
                        device_printf(dev, "<%s>: device_add_child failed\n",
                            dinfo->mdi_obdinfo.obd_name);
                        ofw_bus_gen_destroy_devinfo(&dinfo->mdi_obdinfo);
                        free(dinfo, M_DEVBUF);
                        continue;
                }
		device_set_ivars(cdev, dinfo);
	}

	return (bus_generic_attach(dev));
}
Ejemplo n.º 28
0
/*
 * Probe for other CPUs.
 */
void
cpu_mp_setmaxid(void)
{

	CPU_SETOF(curcpu, &all_cpus);
	mp_ncpus = 1;

	foreach_ap(OF_child(OF_peer(0)), ap_count);
	mp_ncpus = MIN(mp_ncpus, MAXCPU);
	mp_maxid = mp_ncpus - 1;
}
Ejemplo n.º 29
0
static void
ofwbus_identify(driver_t *driver, device_t parent)
{

	/* Check if Open Firmware has been instantiated */
	if (OF_peer(0) == 0)
		return;

	if (device_find_child(parent, "ofwbus", -1) == NULL)
		BUS_ADD_CHILD(parent, 0, "ofwbus", -1);
}
Ejemplo n.º 30
0
static int
ofwbus_probe(device_t dev)
{

#ifdef __aarch64__
	if (OF_peer(0) == 0)
		return (ENXIO);
#endif

	device_set_desc(dev, "Open Firmware Device Tree");
	return (BUS_PROBE_NOWILDCARD);
}