1248590Smm/*-
2248590Smm * Copyright (c) 2006 Benno Rice.  All rights reserved.
3248590Smm *
4248590Smm * Redistribution and use in source and binary forms, with or without
5248590Smm * modification, are permitted provided that the following conditions
6248590Smm * are met:
7248590Smm * 1. Redistributions of source code must retain the above copyright
8248590Smm *    notice, this list of conditions and the following disclaimer.
9248590Smm * 2. Redistributions in binary form must reproduce the above copyright
10248590Smm *    notice, this list of conditions and the following disclaimer in the
11248590Smm *    documentation and/or other materials provided with the distribution.
12248590Smm *
13248590Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14248590Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15248590Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16248590Smm * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17248590Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18248590Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19248590Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20248590Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21248590Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22248590Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23248590Smm */
24248590Smm
25248590Smm#include <sys/cdefs.h>
26248590Smm__FBSDID("$FreeBSD: releng/11.0/sys/arm/xscale/pxa/uart_bus_pxa.c 234004 2012-04-07 23:47:08Z stas $");
27248590Smm
28248590Smm#include <sys/param.h>
29248590Smm#include <sys/systm.h>
30248590Smm#include <sys/bus.h>
31248590Smm#include <sys/conf.h>
32248590Smm#include <sys/kernel.h>
33248590Smm#include <sys/module.h>
34248590Smm#include <machine/bus.h>
35248590Smm#include <sys/rman.h>
36248590Smm#include <machine/resource.h>
37248590Smm
38248590Smm#include <dev/pci/pcivar.h>
39248590Smm
40248590Smm#include <dev/uart/uart.h>
41248590Smm#include <dev/uart/uart_bus.h>
42248590Smm#include <dev/uart/uart_cpu.h>
43248590Smm
44248590Smm#include <dev/ic/ns16550.h>
45248590Smm
46248590Smm#include <arm/xscale/pxa/pxavar.h>
47248590Smm#include <arm/xscale/pxa/pxareg.h>
48248590Smm
49248590Smm#include "uart_if.h"
50248590Smm
51248590Smm#define	PXA_UART_UUE	0x40	/* UART Unit Enable */
52248590Smm
53248590Smmstatic int uart_pxa_probe(device_t dev);
54248590Smm
55248590Smmstatic device_method_t uart_pxa_methods[] = {
56248590Smm	/* Device interface */
57248590Smm	DEVMETHOD(device_probe,		uart_pxa_probe),
58248590Smm	DEVMETHOD(device_attach,	uart_bus_attach),
59248590Smm	DEVMETHOD(device_detach,	uart_bus_detach),
60248590Smm	{ 0, 0 }
61248590Smm};
62248590Smm
63248590Smmstatic driver_t uart_pxa_driver = {
64248590Smm	uart_driver_name,
65248590Smm	uart_pxa_methods,
66248590Smm	sizeof(struct uart_softc),
67248590Smm};
68248590Smm
69248590Smmstatic int
70248590Smmuart_pxa_probe(device_t dev)
71248590Smm{
72248590Smm	bus_space_handle_t	base;
73248590Smm	struct			uart_softc *sc;
74248590Smm
75248590Smm	base = (bus_space_handle_t)pxa_get_base(dev);
76248590Smm#ifdef QEMU_WORKAROUNDS
77248590Smm	/*
78248590Smm	 * QEMU really exposes only the first uart unless
79248590Smm	 * you specify several of them in the configuration.
80248590Smm	 * Otherwise all the rest of UARTs stay unconnected,
81248590Smm	 * which causes problems in the ns16550 attach routine.
82248590Smm	 * Unfortunately, even if you provide qemu with 4 uarts
83248590Smm	 * on the command line, it has a bug where it segfaults
84248590Smm	 * trying to enable bluetooth on the HWUART.  So we just
85248590Smm	 * allow the FFUART to be attached.
86248590Smm	 * Also, don't check the UUE (UART Unit Enable) bit, as
87248590Smm	 * the gumstix bootloader doesn't set it.
88248590Smm	 */
89248590Smm	if (base != PXA2X0_FFUART_BASE)
90248590Smm		return (ENXIO);
91248590Smm#else
92248590Smm	/* Check to see if the enable bit's on. */
93248590Smm	if ((bus_space_read_4(obio_tag, base,
94248590Smm	    (REG_IER << 2)) & PXA_UART_UUE) == 0)
95248590Smm		return (ENXIO);
96248590Smm#endif
97248590Smm	sc = device_get_softc(dev);
98248590Smm	sc->sc_class = &uart_ns8250_class;
99248590Smm
100248590Smm	return(uart_bus_probe(dev, 2, PXA2X0_COM_FREQ, 0, 0));
101248590Smm}
102248590Smm
103248590SmmDRIVER_MODULE(uart, pxa, uart_pxa_driver, uart_devclass, 0, 0);
104248590Smm