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: releng/11.0/sys/dev/uart/uart_cpu.h 281438 2015-04-11 17:16:23Z andrew $
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
36260890Simpstruct uart_softc;
37260890Simp
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;
72260890Simp	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 *);
82281438Sandrewu_int uart_getregshift(struct uart_class *);
83168281Smarcel
84127215Smarcelvoid uart_add_sysdev(struct uart_devinfo *);
85119815Smarcel
86119815Smarcel/*
87119815Smarcel * Operations for low-level access to the UART. Primarily for use
88119815Smarcel * by console and debug port logic.
89119815Smarcel */
90157300Smarcel
91157300Smarcelstatic __inline void
92157300Smarceluart_lock(struct mtx *hwmtx)
93157300Smarcel{
94157300Smarcel	if (!kdb_active && hwmtx != NULL)
95157300Smarcel		mtx_lock_spin(hwmtx);
96157300Smarcel}
97157300Smarcel
98157300Smarcelstatic __inline void
99157300Smarceluart_unlock(struct mtx *hwmtx)
100157300Smarcel{
101157300Smarcel	if (!kdb_active && hwmtx != NULL)
102157300Smarcel		mtx_unlock_spin(hwmtx);
103157300Smarcel}
104157300Smarcel
105119815Smarcelstatic __inline int
106119815Smarceluart_probe(struct uart_devinfo *di)
107119815Smarcel{
108157300Smarcel	int res;
109157300Smarcel
110157300Smarcel	uart_lock(di->hwmtx);
111168281Smarcel	res = di->ops->probe(&di->bas);
112157300Smarcel	uart_unlock(di->hwmtx);
113157300Smarcel	return (res);
114119815Smarcel}
115119815Smarcel
116119815Smarcelstatic __inline void
117119815Smarceluart_init(struct uart_devinfo *di)
118119815Smarcel{
119157300Smarcel	uart_lock(di->hwmtx);
120168281Smarcel	di->ops->init(&di->bas, di->baudrate, di->databits, di->stopbits,
121119815Smarcel	    di->parity);
122157300Smarcel	uart_unlock(di->hwmtx);
123119815Smarcel}
124119815Smarcel
125119815Smarcelstatic __inline void
126119815Smarceluart_term(struct uart_devinfo *di)
127119815Smarcel{
128157300Smarcel	uart_lock(di->hwmtx);
129168281Smarcel	di->ops->term(&di->bas);
130157300Smarcel	uart_unlock(di->hwmtx);
131119815Smarcel}
132119815Smarcel
133119815Smarcelstatic __inline void
134119815Smarceluart_putc(struct uart_devinfo *di, int c)
135119815Smarcel{
136157300Smarcel	uart_lock(di->hwmtx);
137168281Smarcel	di->ops->putc(&di->bas, c);
138157300Smarcel	uart_unlock(di->hwmtx);
139119815Smarcel}
140119815Smarcel
141119815Smarcelstatic __inline int
142166100Smariusuart_rxready(struct uart_devinfo *di)
143166100Smarius{
144166100Smarius	int res;
145166100Smarius
146166100Smarius	uart_lock(di->hwmtx);
147168281Smarcel	res = di->ops->rxready(&di->bas);
148166100Smarius	uart_unlock(di->hwmtx);
149166100Smarius	return (res);
150166100Smarius}
151166100Smarius
152166100Smariusstatic __inline int
153119815Smarceluart_poll(struct uart_devinfo *di)
154119815Smarcel{
155157300Smarcel	int res;
156157300Smarcel
157157300Smarcel	uart_lock(di->hwmtx);
158168281Smarcel	if (di->ops->rxready(&di->bas))
159168281Smarcel		res = di->ops->getc(&di->bas, NULL);
160166100Smarius	else
161166100Smarius		res = -1;
162157300Smarcel	uart_unlock(di->hwmtx);
163157300Smarcel	return (res);
164119815Smarcel}
165119815Smarcel
166119815Smarcelstatic __inline int
167119815Smarceluart_getc(struct uart_devinfo *di)
168119815Smarcel{
169157300Smarcel
170168281Smarcel	return (di->ops->getc(&di->bas, di->hwmtx));
171119815Smarcel}
172119815Smarcel
173260890Simpvoid uart_grab(struct uart_devinfo *di);
174260890Simpvoid uart_ungrab(struct uart_devinfo *di);
175260890Simp
176119815Smarcel#endif /* _DEV_UART_CPU_H_ */
177