uart_cpu.h revision 168281
1236769Sobrien/*-
2236769Sobrien * Copyright (c) 2003, 2004 Marcel Moolenaar
3292068Ssjg * All rights reserved.
4236769Sobrien *
5236769Sobrien * Redistribution and use in source and binary forms, with or without
6236769Sobrien * modification, are permitted provided that the following conditions
7276305Sngie * are met:
8292068Ssjg *
9276305Sngie * 1. Redistributions of source code must retain the above copyright
10236769Sobrien *    notice, this list of conditions and the following disclaimer.
11246223Ssjg * 2. Redistributions in binary form must reproduce the above copyright
12246223Ssjg *    notice, this list of conditions and the following disclaimer in the
13246223Ssjg *    documentation and/or other materials provided with the distribution.
14246223Ssjg *
15246223Ssjg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16246223Ssjg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17236769Sobrien * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18236769Sobrien * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19236769Sobrien * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20236769Sobrien * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21236769Sobrien * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22236769Sobrien * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23236769Sobrien * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24236769Sobrien * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25236769Sobrien *
26236769Sobrien * $FreeBSD: head/sys/dev/uart/uart_cpu.h 168281 2007-04-02 22:00:22Z marcel $
27236769Sobrien */
28236769Sobrien
29236769Sobrien#ifndef _DEV_UART_CPU_H_
30236769Sobrien#define _DEV_UART_CPU_H_
31236769Sobrien
32236769Sobrien#include <sys/kdb.h>
33236769Sobrien#include <sys/lock.h>
34236769Sobrien#include <sys/mutex.h>
35236769Sobrien
36236769Sobrien/*
37236769Sobrien * Low-level operations for use by console and/or debug port support.
38236769Sobrien */
39236769Sobrienstruct uart_ops {
40236769Sobrien	int (*probe)(struct uart_bas *);
41236769Sobrien	void (*init)(struct uart_bas *, int, int, int, int);
42236769Sobrien	void (*term)(struct uart_bas *);
43236769Sobrien	void (*putc)(struct uart_bas *, int);
44236769Sobrien	int (*rxready)(struct uart_bas *);
45236769Sobrien	int (*getc)(struct uart_bas *, struct mtx *);
46236769Sobrien};
47236769Sobrien
48236769Sobrienextern bus_space_tag_t uart_bus_space_io;
49237578Sobrienextern bus_space_tag_t uart_bus_space_mem;
50236769Sobrien
51236769Sobrien/*
52236769Sobrien * Console and debug port device info.
53236769Sobrien */
54236769Sobrienstruct uart_softc;
55236769Sobrienstruct uart_devinfo {
56236769Sobrien	SLIST_ENTRY(uart_devinfo) next;
57236769Sobrien	struct uart_ops *ops;
58236769Sobrien	struct uart_bas bas;
59236769Sobrien	int	baudrate;
60236769Sobrien	int	databits;
61236769Sobrien	int	stopbits;
62236769Sobrien	int	parity;
63236769Sobrien	int	type;
64236769Sobrien#define	UART_DEV_CONSOLE	0
65236769Sobrien#define	UART_DEV_DBGPORT	1
66236769Sobrien#define	UART_DEV_KEYBOARD	2
67236769Sobrien	int	(*attach)(struct uart_softc*);
68236769Sobrien	int	(*detach)(struct uart_softc*);
69236769Sobrien	void	*cookie;		/* Type dependent use. */
70236769Sobrien	struct mtx *hwmtx;
71236769Sobrien};
72236769Sobrien
73236769Sobrienint uart_cpu_eqres(struct uart_bas *, struct uart_bas *);
74236769Sobrienint uart_cpu_getdev(int, struct uart_devinfo *);
75236769Sobrien
76236769Sobrienint uart_getenv(int, struct uart_devinfo *, struct uart_class *);
77236769Sobrienconst char *uart_getname(struct uart_class *);
78236769Sobrienstruct uart_ops *uart_getops(struct uart_class *);
79236769Sobrienint uart_getrange(struct uart_class *);
80236769Sobrien
81236769Sobrienvoid uart_add_sysdev(struct uart_devinfo *);
82276305Sngie
83276305Sngie/*
84276305Sngie * Operations for low-level access to the UART. Primarily for use
85292068Ssjg * by console and debug port logic.
86292068Ssjg */
87276305Sngie
88276305Sngiestatic __inline void
89276305Sngieuart_lock(struct mtx *hwmtx)
90276305Sngie{
91276305Sngie	if (!kdb_active && hwmtx != NULL)
92276305Sngie		mtx_lock_spin(hwmtx);
93276305Sngie}
94276305Sngie
95276305Sngiestatic __inline void
96236769Sobrienuart_unlock(struct mtx *hwmtx)
97236769Sobrien{
98236769Sobrien	if (!kdb_active && hwmtx != NULL)
99236769Sobrien		mtx_unlock_spin(hwmtx);
100236769Sobrien}
101236769Sobrien
102236769Sobrienstatic __inline int
103236769Sobrienuart_probe(struct uart_devinfo *di)
104292068Ssjg{
105292068Ssjg	int res;
106292068Ssjg
107292068Ssjg	uart_lock(di->hwmtx);
108292068Ssjg	res = di->ops->probe(&di->bas);
109292068Ssjg	uart_unlock(di->hwmtx);
110292068Ssjg	return (res);
111292068Ssjg}
112236769Sobrien
113236769Sobrienstatic __inline void
114236769Sobrienuart_init(struct uart_devinfo *di)
115236769Sobrien{
116292068Ssjg	uart_lock(di->hwmtx);
117292068Ssjg	di->ops->init(&di->bas, di->baudrate, di->databits, di->stopbits,
118236769Sobrien	    di->parity);
119236769Sobrien	uart_unlock(di->hwmtx);
120236769Sobrien}
121236769Sobrien
122236769Sobrienstatic __inline void
123236769Sobrienuart_term(struct uart_devinfo *di)
124236769Sobrien{
125236769Sobrien	uart_lock(di->hwmtx);
126236769Sobrien	di->ops->term(&di->bas);
127236769Sobrien	uart_unlock(di->hwmtx);
128236769Sobrien}
129236769Sobrien
130236769Sobrienstatic __inline void
131236769Sobrienuart_putc(struct uart_devinfo *di, int c)
132236769Sobrien{
133236769Sobrien	uart_lock(di->hwmtx);
134236769Sobrien	di->ops->putc(&di->bas, c);
135236769Sobrien	uart_unlock(di->hwmtx);
136236769Sobrien}
137236769Sobrien
138236769Sobrienstatic __inline int
139236769Sobrienuart_rxready(struct uart_devinfo *di)
140236769Sobrien{
141236769Sobrien	int res;
142236769Sobrien
143236769Sobrien	uart_lock(di->hwmtx);
144236769Sobrien	res = di->ops->rxready(&di->bas);
145236769Sobrien	uart_unlock(di->hwmtx);
146236769Sobrien	return (res);
147236769Sobrien}
148236769Sobrien
149236769Sobrienstatic __inline int
150236769Sobrienuart_poll(struct uart_devinfo *di)
151236769Sobrien{
152236769Sobrien	int res;
153236769Sobrien
154292068Ssjg	uart_lock(di->hwmtx);
155236769Sobrien	if (di->ops->rxready(&di->bas))
156236769Sobrien		res = di->ops->getc(&di->bas, NULL);
157236769Sobrien	else
158236769Sobrien		res = -1;
159236769Sobrien	uart_unlock(di->hwmtx);
160236769Sobrien	return (res);
161236769Sobrien}
162236769Sobrien
163236769Sobrienstatic __inline int
164236769Sobrienuart_getc(struct uart_devinfo *di)
165236769Sobrien{
166236769Sobrien
167236769Sobrien	return (di->ops->getc(&di->bas, di->hwmtx));
168236769Sobrien}
169236769Sobrien
170236769Sobrien#endif /* _DEV_UART_CPU_H_ */
171236769Sobrien