Ejemplo n.º 1
0
static int
uart_fdt_probe(device_t dev)
{
	struct uart_softc *sc;
	phandle_t node;
	pcell_t clock, shift;
	int err;
	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 == (uintptr_t)NULL)
		return (ENXIO);

	sc->sc_class = (struct uart_class *)cd->ocd_data;

	node = ofw_bus_get_node(dev);

	if ((err = uart_fdt_get_clock(node, &clock)) != 0)
		return (err);
	uart_fdt_get_shift(node, &shift);

	return (uart_bus_probe(dev, (int)shift, (int)clock, 0, 0));
}
Ejemplo n.º 2
0
static int
uart_fdt_probe(device_t dev)
{
	struct uart_softc *sc;
	phandle_t node;
	pcell_t clock, shift;
	int err;

	sc = device_get_softc(dev);
	if (ofw_bus_is_compatible(dev, "ns16550"))
		sc->sc_class = &uart_ns8250_class;
	else if (ofw_bus_is_compatible(dev, "lpc,uart"))
		sc->sc_class = &uart_lpc_class;
	else if (ofw_bus_is_compatible(dev, "arm,pl011"))
		sc->sc_class = &uart_pl011_class;
	else
		return (ENXIO);

	node = ofw_bus_get_node(dev);

	if ((err = uart_fdt_get_clock(node, &clock)) != 0)
		return (err);
	uart_fdt_get_shift(node, &shift);

	return (uart_bus_probe(dev, (int)shift, (int)clock, 0, 0));
}
Ejemplo n.º 3
0
int
uart_cpu_getdev(int devtype, struct uart_devinfo *di)
{
	char buf[64];
	struct uart_class *class;
	phandle_t node, chosen;
	pcell_t shift, br, rclk;
	u_long start, size;
	int err;

	uart_bus_space_mem = fdtbus_bs_tag;
	uart_bus_space_io = NULL;

	/* Allow overriding the FDT uning the environment. */
	class = &uart_ns8250_class;
	err = uart_getenv(devtype, di, class);
	if (!err)
		return (0);

	if (devtype != UART_DEV_CONSOLE)
		return (ENXIO);

	/*
	 * Retrieve /chosen/std{in,out}.
	 */
	if ((chosen = OF_finddevice("/chosen")) == 0)
		return (ENXIO);
	if (OF_getprop(chosen, "stdin", buf, sizeof(buf)) <= 0)
		return (ENXIO);
	if ((node = OF_finddevice(buf)) == 0)
		return (ENXIO);
	if (OF_getprop(chosen, "stdout", buf, sizeof(buf)) <= 0)
		return (ENXIO);
	if (OF_finddevice(buf) != node)
		/* Only stdin == stdout is supported. */
		return (ENXIO);
	/*
	 * Retrieve serial attributes.
	 */
	uart_fdt_get_shift(node, &shift);

	if (OF_getprop(node, "current-speed", &br, sizeof(br)) <= 0)
		br = 0;
	br = fdt32_to_cpu(br);

	if ((err = uart_fdt_get_clock(node, &rclk)) != 0)
		return (err);
	/*
	 * Finalize configuration.
	 */
	class = &uart_quicc_class;
	if (fdt_is_compatible(node, "ns16550"))
		class = &uart_ns8250_class;

	di->bas.chan = 0;
	di->bas.regshft = (u_int)shift;
	di->baudrate = 0;
	di->bas.rclk = (u_int)rclk;
	di->ops = uart_getops(class);
	di->databits = 8;
	di->stopbits = 1;
	di->parity = UART_PARITY_NONE;
	di->bas.bst = uart_bus_space_mem;

	err = fdt_regsize(node, &start, &size);
	if (err)
		return (ENXIO);
	start += fdt_immr_va;

	return (bus_space_map(di->bas.bst, start, size, 0, &di->bas.bsh));
}