1139749Simp/*-
2127215Smarcel * Copyright (c) 2003, 2004 Marcel Moolenaar
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 *
9119815Smarcel * 1. Redistributions of source code must retain the above copyright
10119815Smarcel *    notice, this list of conditions and the following disclaimer.
11119815Smarcel * 2. Redistributions in binary form must reproduce the above copyright
12119815Smarcel *    notice, this list of conditions and the following disclaimer in the
13119815Smarcel *    documentation and/or other materials provided with the distribution.
14119815Smarcel *
15119815Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16119815Smarcel * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17119815Smarcel * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18119815Smarcel * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19119815Smarcel * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20119815Smarcel * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21119815Smarcel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22119815Smarcel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23119815Smarcel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24119815Smarcel * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25119815Smarcel *
26119815Smarcel * $FreeBSD$
27119815Smarcel */
28119815Smarcel
29119815Smarcel#ifndef _DEV_UART_CPU_H_
30119815Smarcel#define _DEV_UART_CPU_H_
31119815Smarcel
32157300Smarcel#include <sys/kdb.h>
33157300Smarcel#include <sys/lock.h>
34157300Smarcel#include <sys/mutex.h>
35157300Smarcel
36119815Smarcel/*
37119815Smarcel * Low-level operations for use by console and/or debug port support.
38119815Smarcel */
39119815Smarcelstruct uart_ops {
40119815Smarcel	int (*probe)(struct uart_bas *);
41119815Smarcel	void (*init)(struct uart_bas *, int, int, int, int);
42119815Smarcel	void (*term)(struct uart_bas *);
43119815Smarcel	void (*putc)(struct uart_bas *, int);
44166100Smarius	int (*rxready)(struct uart_bas *);
45157380Smarcel	int (*getc)(struct uart_bas *, struct mtx *);
46119815Smarcel};
47119815Smarcel
48127215Smarcelextern bus_space_tag_t uart_bus_space_io;
49127215Smarcelextern bus_space_tag_t uart_bus_space_mem;
50127215Smarcel
51119815Smarcel/*
52119815Smarcel * Console and debug port device info.
53119815Smarcel */
54119815Smarcelstruct uart_softc;
55119815Smarcelstruct uart_devinfo {
56119815Smarcel	SLIST_ENTRY(uart_devinfo) next;
57168281Smarcel	struct uart_ops *ops;
58119815Smarcel	struct uart_bas bas;
59119815Smarcel	int	baudrate;
60119815Smarcel	int	databits;
61119815Smarcel	int	stopbits;
62119815Smarcel	int	parity;
63119815Smarcel	int	type;
64119815Smarcel#define	UART_DEV_CONSOLE	0
65119815Smarcel#define	UART_DEV_DBGPORT	1
66119815Smarcel#define	UART_DEV_KEYBOARD	2
67119815Smarcel	int	(*attach)(struct uart_softc*);
68119815Smarcel	int	(*detach)(struct uart_softc*);
69119815Smarcel	void	*cookie;		/* Type dependent use. */
70157300Smarcel	struct mtx *hwmtx;
71119815Smarcel};
72119815Smarcel
73119866Smarcelint uart_cpu_eqres(struct uart_bas *, struct uart_bas *);
74119866Smarcelint uart_cpu_getdev(int, struct uart_devinfo *);
75119815Smarcel
76168281Smarcelint uart_getenv(int, struct uart_devinfo *, struct uart_class *);
77168281Smarcelconst char *uart_getname(struct uart_class *);
78168281Smarcelstruct uart_ops *uart_getops(struct uart_class *);
79168281Smarcelint uart_getrange(struct uart_class *);
80168281Smarcel
81127215Smarcelvoid uart_add_sysdev(struct uart_devinfo *);
82119815Smarcel
83119815Smarcel/*
84119815Smarcel * Operations for low-level access to the UART. Primarily for use
85119815Smarcel * by console and debug port logic.
86119815Smarcel */
87157300Smarcel
88157300Smarcelstatic __inline void
89157300Smarceluart_lock(struct mtx *hwmtx)
90157300Smarcel{
91157300Smarcel	if (!kdb_active && hwmtx != NULL)
92157300Smarcel		mtx_lock_spin(hwmtx);
93157300Smarcel}
94157300Smarcel
95157300Smarcelstatic __inline void
96157300Smarceluart_unlock(struct mtx *hwmtx)
97157300Smarcel{
98157300Smarcel	if (!kdb_active && hwmtx != NULL)
99157300Smarcel		mtx_unlock_spin(hwmtx);
100157300Smarcel}
101157300Smarcel
102119815Smarcelstatic __inline int
103119815Smarceluart_probe(struct uart_devinfo *di)
104119815Smarcel{
105157300Smarcel	int res;
106157300Smarcel
107157300Smarcel	uart_lock(di->hwmtx);
108168281Smarcel	res = di->ops->probe(&di->bas);
109157300Smarcel	uart_unlock(di->hwmtx);
110157300Smarcel	return (res);
111119815Smarcel}
112119815Smarcel
113119815Smarcelstatic __inline void
114119815Smarceluart_init(struct uart_devinfo *di)
115119815Smarcel{
116157300Smarcel	uart_lock(di->hwmtx);
117168281Smarcel	di->ops->init(&di->bas, di->baudrate, di->databits, di->stopbits,
118119815Smarcel	    di->parity);
119157300Smarcel	uart_unlock(di->hwmtx);
120119815Smarcel}
121119815Smarcel
122119815Smarcelstatic __inline void
123119815Smarceluart_term(struct uart_devinfo *di)
124119815Smarcel{
125157300Smarcel	uart_lock(di->hwmtx);
126168281Smarcel	di->ops->term(&di->bas);
127157300Smarcel	uart_unlock(di->hwmtx);
128119815Smarcel}
129119815Smarcel
130119815Smarcelstatic __inline void
131119815Smarceluart_putc(struct uart_devinfo *di, int c)
132119815Smarcel{
133157300Smarcel	uart_lock(di->hwmtx);
134168281Smarcel	di->ops->putc(&di->bas, c);
135157300Smarcel	uart_unlock(di->hwmtx);
136119815Smarcel}
137119815Smarcel
138119815Smarcelstatic __inline int
139166100Smariusuart_rxready(struct uart_devinfo *di)
140166100Smarius{
141166100Smarius	int res;
142166100Smarius
143166100Smarius	uart_lock(di->hwmtx);
144168281Smarcel	res = di->ops->rxready(&di->bas);
145166100Smarius	uart_unlock(di->hwmtx);
146166100Smarius	return (res);
147166100Smarius}
148166100Smarius
149166100Smariusstatic __inline int
150119815Smarceluart_poll(struct uart_devinfo *di)
151119815Smarcel{
152157300Smarcel	int res;
153157300Smarcel
154157300Smarcel	uart_lock(di->hwmtx);
155168281Smarcel	if (di->ops->rxready(&di->bas))
156168281Smarcel		res = di->ops->getc(&di->bas, NULL);
157166100Smarius	else
158166100Smarius		res = -1;
159157300Smarcel	uart_unlock(di->hwmtx);
160157300Smarcel	return (res);
161119815Smarcel}
162119815Smarcel
163119815Smarcelstatic __inline int
164119815Smarceluart_getc(struct uart_devinfo *di)
165119815Smarcel{
166157300Smarcel
167168281Smarcel	return (di->ops->getc(&di->bas, di->hwmtx));
168119815Smarcel}
169119815Smarcel
170119815Smarcel#endif /* _DEV_UART_CPU_H_ */
171