From owner-p4-projects@FreeBSD.ORG Mon Feb 15 17:34:11 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 67D401065694; Mon, 15 Feb 2010 17:34:11 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 13AC21065692 for ; Mon, 15 Feb 2010 17:34:11 +0000 (UTC) (envelope-from raj@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 0165F8FC32 for ; Mon, 15 Feb 2010 17:34:11 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id o1FHYAQ7059554 for ; Mon, 15 Feb 2010 17:34:10 GMT (envelope-from raj@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id o1FHYA7w059552 for perforce@freebsd.org; Mon, 15 Feb 2010 17:34:10 GMT (envelope-from raj@freebsd.org) Date: Mon, 15 Feb 2010 17:34:10 GMT Message-Id: <201002151734.o1FHYA7w059552@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to raj@freebsd.org using -f From: Rafal Jaworowski To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 174730 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 15 Feb 2010 17:34:11 -0000 http://p4web.freebsd.org/chv.cgi?CH=174730 Change 174730 by raj@raj_fdt on 2010/02/15 17:33:44 Consolidate FDT attachment of uart(4) driver. - Move all FDT-related routines into one file. - Collapse duplicate code to shared helper routines. - Teach the attachment to be endian-safe. - Make Marvell ARM use the FDT-base console code (remove the file used so far altogether). Affected files ... .. //depot/projects/fdt/sys/arm/mv/files.mv#4 edit .. //depot/projects/fdt/sys/conf/files.powerpc#17 edit .. //depot/projects/fdt/sys/dev/uart/uart_bus_fdt.c#6 edit .. //depot/projects/fdt/sys/dev/uart/uart_cpu_mv.c#2 delete .. //depot/projects/fdt/sys/dev/uart/uart_cpu_powerpc.c#6 edit Differences ... ==== //depot/projects/fdt/sys/arm/mv/files.mv#4 (text+ko) ==== @@ -29,6 +29,5 @@ arm/mv/twsi.c optional iicbus dev/mge/if_mge.c optional mge -dev/uart/uart_cpu_mv.c optional uart dev/uart/uart_dev_ns8250.c optional uart dev/usb/controller/ehci_mv.c optional ehci ==== //depot/projects/fdt/sys/conf/files.powerpc#17 (text+ko) ==== @@ -61,7 +61,7 @@ dev/syscons/scvtb.c optional sc dev/tsec/if_tsec.c optional tsec dev/tsec/if_tsec_fdt.c optional tsec fdt -dev/uart/uart_cpu_powerpc.c optional uart +dev/uart/uart_cpu_powerpc.c optional uart aim kern/syscalls.c optional ktr libkern/ashldi3.c standard libkern/ashrdi3.c standard ==== //depot/projects/fdt/sys/dev/uart/uart_bus_fdt.c#6 (text+ko) ==== @@ -36,13 +36,14 @@ #include #include +#include +#include #include #include #include #include - -#include "../../contrib/dtc/libfdt/libfdt_env.h" +#include static int uart_fdt_probe(device_t); @@ -61,19 +62,10 @@ }; static int -uart_fdt_probe(device_t dev) +uart_fdt_get_clock(phandle_t node, pcell_t *cell) { - struct uart_softc *sc; - phandle_t node; - pcell_t clock, shift; - - if (!ofw_bus_is_compatible(dev, "ns16550")) - return (ENXIO); - - sc = device_get_softc(dev); - sc->sc_class = &uart_ns8250_class; + pcell_t clock; - node = ofw_bus_get_node(dev); if ((OF_getprop(node, "clock-frequency", &clock, sizeof(clock))) <= 0) return (ENXIO); @@ -85,13 +77,124 @@ sizeof(clock))) <= 0) clock = 0; - clock = fdt32_to_cpu(clock); + *cell = fdt32_to_cpu(clock); + return (0); +} + +static int +uart_fdt_get_shift(phandle_t node, pcell_t *cell) +{ + pcell_t shift; if ((OF_getprop(node, "reg-shift", &shift, sizeof(shift))) <= 0) shift = 0; - shift = fdt32_to_cpu(shift); + *cell = fdt32_to_cpu(shift); + return (0); +} + +static int +uart_fdt_probe(device_t dev) +{ + struct uart_softc *sc; + phandle_t node; + pcell_t clock, shift; + int err; + + if (!ofw_bus_is_compatible(dev, "ns16550")) + return (ENXIO); + + sc = device_get_softc(dev); + sc->sc_class = &uart_ns8250_class; + + 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)); } DRIVER_MODULE(uart, simplebus, uart_fdt_driver, uart_devclass, 0, 0); + +/* + * UART console routines. + */ +bus_space_tag_t uart_bus_space_io; +bus_space_tag_t uart_bus_space_mem; + +int +uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) +{ + + return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 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; + + 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 = fdtbus_bs_tag; + + err = fdt_get_regsize(node, &start, &size); + if (err) + return (ENXIO); + start += FDT_IMMR_VA; + + uart_bus_space_mem = fdtbus_bs_tag; + uart_bus_space_io = NULL; + + if (bus_space_map(di->bas.bst, start, size, 0, &di->bas.bsh) != 0) + return (ENXIO); + + return (0); +} ==== //depot/projects/fdt/sys/dev/uart/uart_cpu_powerpc.c#6 (text) ==== @@ -27,47 +27,26 @@ #include __FBSDID("$FreeBSD: src/sys/dev/uart/uart_cpu_powerpc.c,v 1.8 2009/07/23 12:51:27 nwhitehorn Exp $"); -#include "opt_platform.h" - #include #include #include #include #include - -#ifdef FDT -#include -#include -#include -#include -#endif +#include #include - -#ifndef FDT -#include -#endif - #include #include -#ifdef FDT -bus_space_tag_t uart_bus_space_io = fdtbus_bs_tag; -bus_space_tag_t uart_bus_space_mem = fdtbus_bs_tag; -#else bus_space_tag_t uart_bus_space_io = &bs_le_tag; bus_space_tag_t uart_bus_space_mem = &bs_le_tag; -#endif int uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) { -#ifdef FDT - return ((b1->bsh == b2->bsh) ? 1 : 0); -#else + return ((pmap_kextract(b1->bsh) == pmap_kextract(b2->bsh)) ? 1 : 0); -#endif } static int @@ -91,105 +70,6 @@ return (0); } -#ifdef FDT -static int -fdt_uart_addr(phandle_t node, bus_space_tag_t *tag, bus_space_handle_t *handle) -{ - pcell_t prop[4]; - u_long start, size; - pcell_t par_addr_cells, par_size_cells; - int rv, tuples, tuple_size; - ssize_t len; - - if (node == 0) - return (EINVAL); - if (tag == NULL || handle == NULL) - return (EINVAL); - if ((len = OF_getproplen(node, "reg")) <= 0) - return (EINVAL); - if (len > sizeof(prop)) - return (ERANGE); - - par_addr_cells = fdt_parent_addr_cells(node); - if (par_addr_cells > 0) { - rv = OF_searchprop(OF_parent(node), "#size-cells", - &par_size_cells, sizeof(par_size_cells)); - if (rv <= 0) - par_size_cells = 1; - } else - par_size_cells = 0; - - tuple_size = sizeof(pcell_t) * (par_addr_cells + par_size_cells); - len = OF_getprop(node, "reg", prop, sizeof(prop)); - if (len % tuple_size) - return (ENXIO); - - tuples = len / tuple_size; - if (tuples <= 0) - return (ENXIO); - - start = size = 0; - rv = 0; - *tag = uart_bus_space_io; - - /* - * Get address/size. XXX we assume only first 'reg' tuple is used: - * uart nodes usually have only one, so this will break if the range - * to be used is specified in other tuples. - */ - rv = fdt_data_to_res(prop, par_addr_cells, par_size_cells, - &start, &size); - - start += FDT_IMMR_VA; - - rv = bus_space_map(*tag, start, size, 0, handle); - if (rv) - return (ERANGE); - - return (0); -} - -int -uart_cpu_getdev(int devtype, struct uart_devinfo *di) -{ - struct uart_class *class; - phandle_t input, opts; - int error; - - if (devtype != UART_DEV_CONSOLE) - return (ENXIO); - - if ((opts = OF_finddevice("/chosen")) == 0) - return (ENXIO); - - if (ofw_get_uart_console(opts, &input, "stdin", "stdout")) - return (EINVAL); - - class = &uart_quicc_class; - if (fdt_is_compatible(input, "ns16550")) - class = &uart_ns8250_class; - - if (OF_getprop(input, "reg-shift", &di->bas.regshft, - di->bas.regshft) <= 0) - di->bas.regshft = 0; - - di->ops = uart_getops(class); - - if (OF_getprop(input, "current-speed", &di->baudrate, - sizeof(di->baudrate)) <= 0) - di->baudrate = 0; - - di->databits = 8; - di->stopbits = 1; - di->parity = UART_PARITY_NONE; - - error = fdt_uart_addr(input, &di->bas.bst, &di->bas.bsh); - if (error) - return (error); - - return (0); -} -#else int uart_cpu_getdev(int devtype, struct uart_devinfo *di) { @@ -265,4 +145,3 @@ di->parity = UART_PARITY_NONE; return (0); } -#endif