uart_cpu.h revision 330897
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2003, 2004 Marcel Moolenaar
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * $FreeBSD: stable/11/sys/dev/uart/uart_cpu.h 330897 2018-03-14 03:19:51Z eadler $
29 */
30
31#ifndef _DEV_UART_CPU_H_
32#define _DEV_UART_CPU_H_
33
34#include <sys/kdb.h>
35#include <sys/lock.h>
36#include <sys/mutex.h>
37
38struct uart_softc;
39
40/*
41 * Low-level operations for use by console and/or debug port support.
42 */
43struct uart_ops {
44	int (*probe)(struct uart_bas *);
45	void (*init)(struct uart_bas *, int, int, int, int);
46	void (*term)(struct uart_bas *);
47	void (*putc)(struct uart_bas *, int);
48	int (*rxready)(struct uart_bas *);
49	int (*getc)(struct uart_bas *, struct mtx *);
50};
51
52extern bus_space_tag_t uart_bus_space_io;
53extern bus_space_tag_t uart_bus_space_mem;
54
55/*
56 * Console and debug port device info.
57 */
58struct uart_devinfo {
59	SLIST_ENTRY(uart_devinfo) next;
60	struct uart_ops *ops;
61	struct uart_bas bas;
62	int	baudrate;
63	int	databits;
64	int	stopbits;
65	int	parity;
66	int	type;
67#define	UART_DEV_CONSOLE	0
68#define	UART_DEV_DBGPORT	1
69#define	UART_DEV_KEYBOARD	2
70	int	(*attach)(struct uart_softc*);
71	int	(*detach)(struct uart_softc*);
72	void	*cookie;		/* Type dependent use. */
73	struct mtx *hwmtx;
74	struct uart_softc *sc;		/* valid only from start of attach */
75};
76
77int uart_cpu_eqres(struct uart_bas *, struct uart_bas *);
78int uart_cpu_getdev(int, struct uart_devinfo *);
79
80int uart_getenv(int, struct uart_devinfo *, struct uart_class *);
81const char *uart_getname(struct uart_class *);
82struct uart_ops *uart_getops(struct uart_class *);
83int uart_getrange(struct uart_class *);
84u_int uart_getregshift(struct uart_class *);
85
86void uart_add_sysdev(struct uart_devinfo *);
87
88/*
89 * Operations for low-level access to the UART. Primarily for use
90 * by console and debug port logic.
91 */
92
93static __inline void
94uart_lock(struct mtx *hwmtx)
95{
96	if (!kdb_active && hwmtx != NULL)
97		mtx_lock_spin(hwmtx);
98}
99
100static __inline void
101uart_unlock(struct mtx *hwmtx)
102{
103	if (!kdb_active && hwmtx != NULL)
104		mtx_unlock_spin(hwmtx);
105}
106
107static __inline int
108uart_probe(struct uart_devinfo *di)
109{
110	int res;
111
112	uart_lock(di->hwmtx);
113	res = di->ops->probe(&di->bas);
114	uart_unlock(di->hwmtx);
115	return (res);
116}
117
118static __inline void
119uart_init(struct uart_devinfo *di)
120{
121	uart_lock(di->hwmtx);
122	di->ops->init(&di->bas, di->baudrate, di->databits, di->stopbits,
123	    di->parity);
124	uart_unlock(di->hwmtx);
125}
126
127static __inline void
128uart_term(struct uart_devinfo *di)
129{
130	uart_lock(di->hwmtx);
131	di->ops->term(&di->bas);
132	uart_unlock(di->hwmtx);
133}
134
135static __inline void
136uart_putc(struct uart_devinfo *di, int c)
137{
138	uart_lock(di->hwmtx);
139	di->ops->putc(&di->bas, c);
140	uart_unlock(di->hwmtx);
141}
142
143static __inline int
144uart_rxready(struct uart_devinfo *di)
145{
146	int res;
147
148	uart_lock(di->hwmtx);
149	res = di->ops->rxready(&di->bas);
150	uart_unlock(di->hwmtx);
151	return (res);
152}
153
154static __inline int
155uart_poll(struct uart_devinfo *di)
156{
157	int res;
158
159	uart_lock(di->hwmtx);
160	if (di->ops->rxready(&di->bas))
161		res = di->ops->getc(&di->bas, NULL);
162	else
163		res = -1;
164	uart_unlock(di->hwmtx);
165	return (res);
166}
167
168static __inline int
169uart_getc(struct uart_devinfo *di)
170{
171
172	return (di->ops->getc(&di->bas, di->hwmtx));
173}
174
175void uart_grab(struct uart_devinfo *di);
176void uart_ungrab(struct uart_devinfo *di);
177
178#endif /* _DEV_UART_CPU_H_ */
179