1119815Smarcel/*-
2119815Smarcel * Copyright (c) 2001 by Thomas Moestl <tmm@FreeBSD.org>.
3119815Smarcel * All rights reserved.
4119815Smarcel *
5119815Smarcel * Redistribution and use in source and binary forms, with or without
6119815Smarcel * modification, are permitted provided that the following conditions
7119815Smarcel * are met:
8119815Smarcel * 1. Redistributions of source code must retain the above copyright
9119815Smarcel *    notice, this list of conditions and the following disclaimer.
10119815Smarcel * 2. Redistributions in binary form must reproduce the above copyright
11119815Smarcel *    notice, this list of conditions and the following disclaimer in the
12119815Smarcel *    documentation and/or other materials provided with the distribution.
13119815Smarcel *
14119815Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15119815Smarcel * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16119815Smarcel * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17119815Smarcel * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
18119815Smarcel * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19119815Smarcel * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20119815Smarcel * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21119815Smarcel * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22119815Smarcel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23119815Smarcel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24119815Smarcel * SUCH DAMAGE.
25119815Smarcel */
26119815Smarcel
27119815Smarcel#include <sys/cdefs.h>
28119815Smarcel__FBSDID("$FreeBSD: releng/11.0/sys/dev/uart/uart_bus_ebus.c 200926 2009-12-23 22:31:43Z marius $");
29119815Smarcel
30119815Smarcel#include <sys/param.h>
31119815Smarcel#include <sys/systm.h>
32119815Smarcel#include <sys/bus.h>
33119815Smarcel#include <sys/kernel.h>
34130026Sphk#include <sys/module.h>
35133589Smarius
36133589Smarius#include <dev/ofw/ofw_bus.h>
37133589Smarius
38119815Smarcel#include <machine/bus.h>
39119815Smarcel#include <sys/rman.h>
40119815Smarcel#include <machine/resource.h>
41146974Smarius#include <machine/ver.h>
42119815Smarcel
43119815Smarcel#include <dev/uart/uart.h>
44119815Smarcel#include <dev/uart/uart_bus.h>
45119815Smarcel#include <dev/uart/uart_cpu.h>
46119815Smarcel
47119815Smarcelstatic int uart_ebus_probe(device_t dev);
48119815Smarcel
49119815Smarcelstatic device_method_t uart_ebus_methods[] = {
50119815Smarcel	/* Device interface */
51119815Smarcel	DEVMETHOD(device_probe,		uart_ebus_probe),
52119815Smarcel	DEVMETHOD(device_attach,	uart_bus_attach),
53119815Smarcel	DEVMETHOD(device_detach,	uart_bus_detach),
54119815Smarcel	{ 0, 0 }
55119815Smarcel};
56119815Smarcel
57119815Smarcelstatic driver_t uart_ebus_driver = {
58119815Smarcel	uart_driver_name,
59119815Smarcel	uart_ebus_methods,
60119815Smarcel	sizeof(struct uart_softc),
61119815Smarcel};
62119815Smarcel
63119815Smarcelstatic int
64119815Smarceluart_ebus_probe(device_t dev)
65119815Smarcel{
66127817Smarcel	const char *nm, *cmpt;
67119815Smarcel	struct uart_softc *sc;
68146974Smarius	struct uart_devinfo dummy;
69119815Smarcel
70119815Smarcel	sc = device_get_softc(dev);
71119815Smarcel	sc->sc_class = NULL;
72119815Smarcel
73133589Smarius	nm = ofw_bus_get_name(dev);
74133589Smarius	cmpt = ofw_bus_get_compat(dev);
75155322Smarius	if (cmpt == NULL)
76155322Smarius		cmpt = "";
77155322Smarius	if (!strcmp(nm, "lom-console") || !strcmp(nm, "su") ||
78155322Smarius	    !strcmp(nm, "su_pnp") || !strcmp(cmpt, "rsc-console") ||
79155322Smarius	    !strcmp(cmpt, "rsc-control") || !strcmp(cmpt, "su") ||
80200926Smarius	    !strcmp(cmpt, "su16550") || !strcmp(cmpt, "su16552")) {
81146974Smarius		/*
82146974Smarius		 * On AXi and AXmp boards the NS16550 (used to connect
83146974Smarius		 * keyboard/mouse) share their IRQ lines with the i8042.
84146974Smarius		 * Any IRQ activity (typically during attach) of the
85146974Smarius		 * NS16550 used to connect the keyboard when actually the
86146974Smarius		 * PS/2 keyboard is selected in OFW causes interaction
87146974Smarius		 * with the OBP i8042 driver resulting in a hang and vice
88146974Smarius		 * versa. As RS232 keyboards and mice obviously aren't
89146974Smarius		 * meant to be used in parallel with PS/2 ones on these
90146974Smarius		 * boards don't attach to the NS16550 in case the RS232
91146974Smarius		 * keyboard isn't selected in order to prevent such hangs.
92146974Smarius		 */
93146974Smarius		if ((!strcmp(sparc64_model, "SUNW,UltraAX-MP") ||
94146974Smarius		    !strcmp(sparc64_model, "SUNW,UltraSPARC-IIi-Engine")) &&
95146974Smarius		    uart_cpu_getdev(UART_DEV_KEYBOARD, &dummy)) {
96146974Smarius				device_disable(dev);
97146974Smarius				return (ENXIO);
98146974Smarius		}
99119815Smarcel		sc->sc_class = &uart_ns8250_class;
100120452Smarcel		return (uart_bus_probe(dev, 0, 0, 0, 0));
101119815Smarcel	}
102119815Smarcel
103119815Smarcel	return (ENXIO);
104119815Smarcel}
105119815Smarcel
106119815SmarcelDRIVER_MODULE(uart, ebus, uart_ebus_driver, uart_devclass, 0, 0);
107