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
36262649Simpstruct uart_softc;
37262649Simp
38119815Smarcel/*
39119815Smarcel * Low-level operations for use by console and/or debug port support.
40119815Smarcel */
41119815Smarcelstruct uart_ops {
42119815Smarcel	int (*probe)(struct uart_bas *);
43119815Smarcel	void (*init)(struct uart_bas *, int, int, int, int);
44119815Smarcel	void (*term)(struct uart_bas *);
45119815Smarcel	void (*putc)(struct uart_bas *, int);
46166100Smarius	int (*rxready)(struct uart_bas *);
47157380Smarcel	int (*getc)(struct uart_bas *, struct mtx *);
48119815Smarcel};
49119815Smarcel
50127215Smarcelextern bus_space_tag_t uart_bus_space_io;
51127215Smarcelextern bus_space_tag_t uart_bus_space_mem;
52127215Smarcel
53119815Smarcel/*
54119815Smarcel * Console and debug port device info.
55119815Smarcel */
56119815Smarcelstruct uart_devinfo {
57119815Smarcel	SLIST_ENTRY(uart_devinfo) next;
58168281Smarcel	struct uart_ops *ops;
59119815Smarcel	struct uart_bas bas;
60119815Smarcel	int	baudrate;
61119815Smarcel	int	databits;
62119815Smarcel	int	stopbits;
63119815Smarcel	int	parity;
64119815Smarcel	int	type;
65119815Smarcel#define	UART_DEV_CONSOLE	0
66119815Smarcel#define	UART_DEV_DBGPORT	1
67119815Smarcel#define	UART_DEV_KEYBOARD	2
68119815Smarcel	int	(*attach)(struct uart_softc*);
69119815Smarcel	int	(*detach)(struct uart_softc*);
70119815Smarcel	void	*cookie;		/* Type dependent use. */
71157300Smarcel	struct mtx *hwmtx;
72262649Simp	struct uart_softc *sc;		/* valid only from start of attach */
73119815Smarcel};
74119815Smarcel
75119866Smarcelint uart_cpu_eqres(struct uart_bas *, struct uart_bas *);
76119866Smarcelint uart_cpu_getdev(int, struct uart_devinfo *);
77119815Smarcel
78168281Smarcelint uart_getenv(int, struct uart_devinfo *, struct uart_class *);
79168281Smarcelconst char *uart_getname(struct uart_class *);
80168281Smarcelstruct uart_ops *uart_getops(struct uart_class *);
81168281Smarcelint uart_getrange(struct uart_class *);
82168281Smarcel
83127215Smarcelvoid uart_add_sysdev(struct uart_devinfo *);
84119815Smarcel
85119815Smarcel/*
86119815Smarcel * Operations for low-level access to the UART. Primarily for use
87119815Smarcel * by console and debug port logic.
88119815Smarcel */
89157300Smarcel
90157300Smarcelstatic __inline void
91157300Smarceluart_lock(struct mtx *hwmtx)
92157300Smarcel{
93157300Smarcel	if (!kdb_active && hwmtx != NULL)
94157300Smarcel		mtx_lock_spin(hwmtx);
95157300Smarcel}
96157300Smarcel
97157300Smarcelstatic __inline void
98157300Smarceluart_unlock(struct mtx *hwmtx)
99157300Smarcel{
100157300Smarcel	if (!kdb_active && hwmtx != NULL)
101157300Smarcel		mtx_unlock_spin(hwmtx);
102157300Smarcel}
103157300Smarcel
104119815Smarcelstatic __inline int
105119815Smarceluart_probe(struct uart_devinfo *di)
106119815Smarcel{
107157300Smarcel	int res;
108157300Smarcel
109157300Smarcel	uart_lock(di->hwmtx);
110168281Smarcel	res = di->ops->probe(&di->bas);
111157300Smarcel	uart_unlock(di->hwmtx);
112157300Smarcel	return (res);
113119815Smarcel}
114119815Smarcel
115119815Smarcelstatic __inline void
116119815Smarceluart_init(struct uart_devinfo *di)
117119815Smarcel{
118157300Smarcel	uart_lock(di->hwmtx);
119168281Smarcel	di->ops->init(&di->bas, di->baudrate, di->databits, di->stopbits,
120119815Smarcel	    di->parity);
121157300Smarcel	uart_unlock(di->hwmtx);
122119815Smarcel}
123119815Smarcel
124119815Smarcelstatic __inline void
125119815Smarceluart_term(struct uart_devinfo *di)
126119815Smarcel{
127157300Smarcel	uart_lock(di->hwmtx);
128168281Smarcel	di->ops->term(&di->bas);
129157300Smarcel	uart_unlock(di->hwmtx);
130119815Smarcel}
131119815Smarcel
132119815Smarcelstatic __inline void
133119815Smarceluart_putc(struct uart_devinfo *di, int c)
134119815Smarcel{
135157300Smarcel	uart_lock(di->hwmtx);
136168281Smarcel	di->ops->putc(&di->bas, c);
137157300Smarcel	uart_unlock(di->hwmtx);
138119815Smarcel}
139119815Smarcel
140119815Smarcelstatic __inline int
141166100Smariusuart_rxready(struct uart_devinfo *di)
142166100Smarius{
143166100Smarius	int res;
144166100Smarius
145166100Smarius	uart_lock(di->hwmtx);
146168281Smarcel	res = di->ops->rxready(&di->bas);
147166100Smarius	uart_unlock(di->hwmtx);
148166100Smarius	return (res);
149166100Smarius}
150166100Smarius
151166100Smariusstatic __inline int
152119815Smarceluart_poll(struct uart_devinfo *di)
153119815Smarcel{
154157300Smarcel	int res;
155157300Smarcel
156157300Smarcel	uart_lock(di->hwmtx);
157168281Smarcel	if (di->ops->rxready(&di->bas))
158168281Smarcel		res = di->ops->getc(&di->bas, NULL);
159166100Smarius	else
160166100Smarius		res = -1;
161157300Smarcel	uart_unlock(di->hwmtx);
162157300Smarcel	return (res);
163119815Smarcel}
164119815Smarcel
165119815Smarcelstatic __inline int
166119815Smarceluart_getc(struct uart_devinfo *di)
167119815Smarcel{
168157300Smarcel
169168281Smarcel	return (di->ops->getc(&di->bas, di->hwmtx));
170119815Smarcel}
171119815Smarcel
172262649Simpvoid uart_grab(struct uart_devinfo *di);
173262649Simpvoid uart_ungrab(struct uart_devinfo *di);
174262649Simp
175119815Smarcel#endif /* _DEV_UART_CPU_H_ */
176