Tue Mar 3 21:56:25 2015 UTC ()
use irq instead of polling hack now that gic is fixed


(jmcneill)
diff -r1.3 -r1.4 src/sys/arch/arm/amlogic/amlogic_com.c

cvs diff -r1.3 -r1.4 src/sys/arch/arm/amlogic/Attic/amlogic_com.c (switch to unified diff)

--- src/sys/arch/arm/amlogic/Attic/amlogic_com.c 2015/03/01 23:39:28 1.3
+++ src/sys/arch/arm/amlogic/Attic/amlogic_com.c 2015/03/03 21:56:25 1.4
@@ -1,488 +1,445 @@ @@ -1,488 +1,445 @@
1/* $NetBSD: amlogic_com.c,v 1.3 2015/03/01 23:39:28 jmcneill Exp $ */ 1/* $NetBSD: amlogic_com.c,v 1.4 2015/03/03 21:56:25 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2013 The NetBSD Foundation, Inc. 4 * Copyright (c) 2013 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Matt Thomas of 3am Software Foundry. 8 * by Matt Thomas of 3am Software Foundry.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include "locators.h" 32#include "locators.h"
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35 35
36__KERNEL_RCSID(1, "$NetBSD: amlogic_com.c,v 1.3 2015/03/01 23:39:28 jmcneill Exp $"); 36__KERNEL_RCSID(1, "$NetBSD: amlogic_com.c,v 1.4 2015/03/03 21:56:25 jmcneill Exp $");
37 
38#define AMLOGIC_COM_INTRPOLL 
39#define AMLOGIC_COM_INTRPOLL_RATE 10 
40 37
41#include <sys/param.h> 38#include <sys/param.h>
42#include <sys/bus.h> 39#include <sys/bus.h>
43#include <sys/device.h> 40#include <sys/device.h>
44#include <sys/conf.h> 41#include <sys/conf.h>
45#include <sys/intr.h> 42#include <sys/intr.h>
46#include <sys/systm.h> 43#include <sys/systm.h>
47#include <sys/time.h> 44#include <sys/time.h>
48#include <sys/termios.h> 45#include <sys/termios.h>
49#include <sys/kauth.h> 46#include <sys/kauth.h>
50#include <sys/lwp.h> 47#include <sys/lwp.h>
51#include <sys/tty.h> 48#include <sys/tty.h>
52 49
53#include <dev/cons.h> 50#include <dev/cons.h>
54 51
55#include <arm/amlogic/amlogic_reg.h> 52#include <arm/amlogic/amlogic_reg.h>
56#include <arm/amlogic/amlogic_var.h> 53#include <arm/amlogic/amlogic_var.h>
57#include <arm/amlogic/amlogic_comreg.h> 54#include <arm/amlogic/amlogic_comreg.h>
58#include <arm/amlogic/amlogic_comvar.h> 55#include <arm/amlogic/amlogic_comvar.h>
59 56
60static int amlogic_com_match(device_t, cfdata_t, void *); 57static int amlogic_com_match(device_t, cfdata_t, void *);
61static void amlogic_com_attach(device_t, device_t, void *); 58static void amlogic_com_attach(device_t, device_t, void *);
62 59
63static int amlogic_com_intr(void *); 60static int amlogic_com_intr(void *);
64 61
65#ifdef AMLOGIC_COM_INTRPOLL 
66static void amlogic_com_intrpoll(void *); 
67#endif 
68 
69static int amlogic_com_cngetc(dev_t); 62static int amlogic_com_cngetc(dev_t);
70static void amlogic_com_cnputc(dev_t, int); 63static void amlogic_com_cnputc(dev_t, int);
71static void amlogic_com_cnpollc(dev_t, int); 64static void amlogic_com_cnpollc(dev_t, int);
72 65
73static void amlogic_com_start(struct tty *); 66static void amlogic_com_start(struct tty *);
74static int amlogic_com_param(struct tty *, struct termios *); 67static int amlogic_com_param(struct tty *, struct termios *);
75 68
76extern struct cfdriver amlogiccom_cd; 69extern struct cfdriver amlogiccom_cd;
77 70
78struct amlogic_com_softc { 71struct amlogic_com_softc {
79 device_t sc_dev; 72 device_t sc_dev;
80 bus_space_tag_t sc_bst; 73 bus_space_tag_t sc_bst;
81 bus_space_handle_t sc_bsh; 74 bus_space_handle_t sc_bsh;
82 void *sc_ih; 75 void *sc_ih;
83 76
84 struct tty *sc_tty; 77 struct tty *sc_tty;
85 78
86 int sc_ospeed; 79 int sc_ospeed;
87 tcflag_t sc_cflag; 80 tcflag_t sc_cflag;
88 81
89 u_char sc_buf[1024]; 82 u_char sc_buf[1024];
90 
91#ifdef AMLOGIC_COM_INTRPOLL 
92 callout_t sc_intrpoll_ch; 
93#endif 
94}; 83};
95 84
96static struct amlogic_com_softc amlogic_com_cnsc; 85static struct amlogic_com_softc amlogic_com_cnsc;
97 86
98static struct cnm_state amlogic_com_cnm_state; 87static struct cnm_state amlogic_com_cnm_state;
99 88
100struct consdev amlogic_com_consdev = { 89struct consdev amlogic_com_consdev = {
101 .cn_getc = amlogic_com_cngetc, 90 .cn_getc = amlogic_com_cngetc,
102 .cn_putc = amlogic_com_cnputc, 91 .cn_putc = amlogic_com_cnputc,
103 .cn_pollc = amlogic_com_cnpollc, 92 .cn_pollc = amlogic_com_cnpollc,
104 .cn_dev = NODEV, 93 .cn_dev = NODEV,
105 .cn_pri = CN_NORMAL, 94 .cn_pri = CN_NORMAL,
106}; 95};
107 96
108static dev_type_open(amlogic_com_open); 97static dev_type_open(amlogic_com_open);
109static dev_type_open(amlogic_com_close); 98static dev_type_open(amlogic_com_close);
110static dev_type_read(amlogic_com_read); 99static dev_type_read(amlogic_com_read);
111static dev_type_write(amlogic_com_write); 100static dev_type_write(amlogic_com_write);
112static dev_type_ioctl(amlogic_com_ioctl); 101static dev_type_ioctl(amlogic_com_ioctl);
113static dev_type_tty(amlogic_com_tty); 102static dev_type_tty(amlogic_com_tty);
114static dev_type_poll(amlogic_com_poll); 103static dev_type_poll(amlogic_com_poll);
115static dev_type_stop(amlogic_com_stop); 104static dev_type_stop(amlogic_com_stop);
116 105
117const struct cdevsw amlogiccom_cdevsw = { 106const struct cdevsw amlogiccom_cdevsw = {
118 .d_open = amlogic_com_open, 107 .d_open = amlogic_com_open,
119 .d_close = amlogic_com_close, 108 .d_close = amlogic_com_close,
120 .d_read = amlogic_com_read, 109 .d_read = amlogic_com_read,
121 .d_write = amlogic_com_write, 110 .d_write = amlogic_com_write,
122 .d_ioctl = amlogic_com_ioctl, 111 .d_ioctl = amlogic_com_ioctl,
123 .d_stop = amlogic_com_stop, 112 .d_stop = amlogic_com_stop,
124 .d_tty = amlogic_com_tty, 113 .d_tty = amlogic_com_tty,
125 .d_poll = amlogic_com_poll, 114 .d_poll = amlogic_com_poll,
126 .d_mmap = nommap, 115 .d_mmap = nommap,
127 .d_kqfilter = ttykqfilter, 116 .d_kqfilter = ttykqfilter,
128 .d_discard = nodiscard, 117 .d_discard = nodiscard,
129 .d_flag = D_TTY 118 .d_flag = D_TTY
130}; 119};
131 120
132static int amlogic_com_cmajor = -1; 121static int amlogic_com_cmajor = -1;
133 122
134CFATTACH_DECL_NEW(amlogic_com, sizeof(struct amlogic_com_softc), 123CFATTACH_DECL_NEW(amlogic_com, sizeof(struct amlogic_com_softc),
135 amlogic_com_match, amlogic_com_attach, NULL, NULL); 124 amlogic_com_match, amlogic_com_attach, NULL, NULL);
136 125
137static int 126static int
138amlogic_com_match(device_t parent, cfdata_t cf, void *aux) 127amlogic_com_match(device_t parent, cfdata_t cf, void *aux)
139{ 128{
140 return 1; 129 return 1;
141} 130}
142 131
143static void 132static void
144amlogic_com_attach(device_t parent, device_t self, void *aux) 133amlogic_com_attach(device_t parent, device_t self, void *aux)
145{ 134{
146 struct amlogic_com_softc * const sc = device_private(self); 135 struct amlogic_com_softc * const sc = device_private(self);
147 struct amlogicio_attach_args * const aio = aux; 136 struct amlogicio_attach_args * const aio = aux;
148 const struct amlogic_locators * const loc = &aio->aio_loc; 137 const struct amlogic_locators * const loc = &aio->aio_loc;
149 const bus_addr_t iobase = AMLOGIC_CORE_BASE + loc->loc_offset; 138 const bus_addr_t iobase = AMLOGIC_CORE_BASE + loc->loc_offset;
150 struct tty *tp; 139 struct tty *tp;
151 int major, minor; 140 int major, minor;
152 uint32_t misc, control; 141 uint32_t misc, control;
153 142
154 sc->sc_dev = self; 143 sc->sc_dev = self;
155 sc->sc_bst = aio->aio_core_bst; 144 sc->sc_bst = aio->aio_core_bst;
156 bus_space_subregion(aio->aio_core_bst, aio->aio_bsh, 145 bus_space_subregion(aio->aio_core_bst, aio->aio_bsh,
157 loc->loc_offset, loc->loc_size, &sc->sc_bsh); 146 loc->loc_offset, loc->loc_size, &sc->sc_bsh);
158 147
159#ifdef AMLOGIC_COM_INTRPOLL 
160 callout_init(&sc->sc_intrpoll_ch, CALLOUT_MPSAFE); 
161 callout_setfunc(&sc->sc_intrpoll_ch, amlogic_com_intrpoll, sc); 
162#else 
163 sc->sc_ih = intr_establish(loc->loc_intr, IPL_SERIAL, 148 sc->sc_ih = intr_establish(loc->loc_intr, IPL_SERIAL,
164 IST_EDGE | IST_MPSAFE, amlogic_com_intr, sc); 149 IST_EDGE | IST_MPSAFE, amlogic_com_intr, sc);
165 if (sc->sc_ih == NULL) { 150 if (sc->sc_ih == NULL) {
166 aprint_error(": failed to establish interrupt %d\n", 151 aprint_error(": failed to establish interrupt %d\n",
167 loc->loc_intr); 152 loc->loc_intr);
168 return; 153 return;
169 } 154 }
170#endif 
171 155
172 if (amlogic_com_cmajor == -1) { 156 if (amlogic_com_cmajor == -1) {
173 /* allocate a major number */ 157 /* allocate a major number */
174 int bmajor = -1, cmajor = -1; 158 int bmajor = -1, cmajor = -1;
175 int error = devsw_attach("amlogiccom", NULL, &bmajor, 159 int error = devsw_attach("amlogiccom", NULL, &bmajor,
176 &amlogiccom_cdevsw, &cmajor); 160 &amlogiccom_cdevsw, &cmajor);
177 if (error) { 161 if (error) {
178 aprint_error(": couldn't allocate major number\n"); 162 aprint_error(": couldn't allocate major number\n");
179 return; 163 return;
180 } 164 }
181 amlogic_com_cmajor = cmajor; 165 amlogic_com_cmajor = cmajor;
182 } 166 }
183 167
184 major = cdevsw_lookup_major(&amlogiccom_cdevsw); 168 major = cdevsw_lookup_major(&amlogiccom_cdevsw);
185 minor = device_unit(self); 169 minor = device_unit(self);
186 170
187 tp = sc->sc_tty = tty_alloc(); 171 tp = sc->sc_tty = tty_alloc();
188 tp->t_oproc = amlogic_com_start; 172 tp->t_oproc = amlogic_com_start;
189 tp->t_param = amlogic_com_param; 173 tp->t_param = amlogic_com_param;
190 tp->t_dev = makedev(major, minor); 174 tp->t_dev = makedev(major, minor);
191 tp->t_sc = sc; 175 tp->t_sc = sc;
192 tty_attach(tp); 176 tty_attach(tp);
193 177
194 aprint_naive("\n"); 178 aprint_naive("\n");
195 if (amlogic_com_is_console(iobase)) { 179 if (amlogic_com_is_console(iobase)) {
196 cn_tab->cn_dev = tp->t_dev; 180 cn_tab->cn_dev = tp->t_dev;
197 aprint_normal(": console"); 181 aprint_normal(": console");
198 } 182 }
199 aprint_normal("\n"); 183 aprint_normal("\n");
200 184
201#ifdef AMLOGIC_COM_INTRPOLL 
202 aprint_normal_dev(self, "polling\n"); 
203#else 
204 aprint_normal_dev(self, "interrupting at irq %d\n", loc->loc_intr); 185 aprint_normal_dev(self, "interrupting at irq %d\n", loc->loc_intr);
205#endif 
206 186
207 misc = bus_space_read_4(sc->sc_bst, sc->sc_bsh, UART_MISC_REG); 187 misc = bus_space_read_4(sc->sc_bst, sc->sc_bsh, UART_MISC_REG);
208 misc &= ~UART_MISC_TX_IRQ_CNT; 188 misc &= ~UART_MISC_TX_IRQ_CNT;
209 misc |= __SHIFTIN(0, UART_MISC_TX_IRQ_CNT); 189 misc |= __SHIFTIN(0, UART_MISC_TX_IRQ_CNT);
210 misc &= ~UART_MISC_RX_IRQ_CNT; 190 misc &= ~UART_MISC_RX_IRQ_CNT;
211 misc |= __SHIFTIN(1, UART_MISC_RX_IRQ_CNT); 191 misc |= __SHIFTIN(1, UART_MISC_RX_IRQ_CNT);
212 bus_space_write_4(sc->sc_bst, sc->sc_bsh, UART_MISC_REG, misc); 192 bus_space_write_4(sc->sc_bst, sc->sc_bsh, UART_MISC_REG, misc);
213 193
214 control = bus_space_read_4(sc->sc_bst, sc->sc_bsh, UART_CONTROL_REG); 194 control = bus_space_read_4(sc->sc_bst, sc->sc_bsh, UART_CONTROL_REG);
215 control &= ~UART_CONTROL_TX_INT_EN; 195 control &= ~UART_CONTROL_TX_INT_EN;
216#ifdef AMLOGIC_COM_INTRPOLL 
217 control &= ~UART_CONTROL_RX_INT_EN; 
218#else 
219 control |= UART_CONTROL_RX_INT_EN; 196 control |= UART_CONTROL_RX_INT_EN;
220#endif 
221 bus_space_write_4(sc->sc_bst, sc->sc_bsh, UART_CONTROL_REG, control); 197 bus_space_write_4(sc->sc_bst, sc->sc_bsh, UART_CONTROL_REG, control);
222 
223#ifdef AMLOGIC_COM_INTRPOLL 
224 callout_schedule(&sc->sc_intrpoll_ch, AMLOGIC_COM_INTRPOLL_RATE); 
225#endif 
226} 198}
227 199
228static int 200static int
229amlogic_com_cngetc(dev_t dev) 201amlogic_com_cngetc(dev_t dev)
230{ 202{
231 bus_space_tag_t bst = amlogic_com_cnsc.sc_bst; 203 bus_space_tag_t bst = amlogic_com_cnsc.sc_bst;
232 bus_space_handle_t bsh = amlogic_com_cnsc.sc_bsh; 204 bus_space_handle_t bsh = amlogic_com_cnsc.sc_bsh;
233 uint32_t status; 205 uint32_t status;
234 int s, c; 206 int s, c;
235 207
236 s = splserial(); 208 s = splserial();
237 209
238 status = bus_space_read_4(bst, bsh, UART_STATUS_REG); 210 status = bus_space_read_4(bst, bsh, UART_STATUS_REG);
239 if (status & UART_STATUS_RX_EMPTY) { 211 if (status & UART_STATUS_RX_EMPTY) {
240 splx(s); 212 splx(s);
241 return -1; 213 return -1;
242 } 214 }
243 215
244 c = bus_space_read_4(bst, bsh, UART_RFIFO_REG); 216 c = bus_space_read_4(bst, bsh, UART_RFIFO_REG);
245#if defined(DDB) 217#if defined(DDB)
246 extern int db_active; 218 extern int db_active;
247 if (!db_active) 219 if (!db_active)
248#endif 220#endif
249 { 221 {
250 int cn_trapped __unused = 0; 222 int cn_trapped __unused = 0;
251 cn_check_magic(dev, c, amlogic_com_cnm_state); 223 cn_check_magic(dev, c, amlogic_com_cnm_state);
252 } 224 }
253 225
254 splx(s); 226 splx(s);
255 227
256 return c & 0xff; 228 return c & 0xff;
257} 229}
258 230
259static void 231static void
260amlogic_com_cnputc(dev_t dev, int c) 232amlogic_com_cnputc(dev_t dev, int c)
261{ 233{
262 bus_space_tag_t bst = amlogic_com_cnsc.sc_bst; 234 bus_space_tag_t bst = amlogic_com_cnsc.sc_bst;
263 bus_space_handle_t bsh = amlogic_com_cnsc.sc_bsh; 235 bus_space_handle_t bsh = amlogic_com_cnsc.sc_bsh;
264 int s; 236 int s;
265 237
266 s = splserial(); 238 s = splserial();
267 239
268 while ((bus_space_read_4(bst, bsh, UART_STATUS_REG) & UART_STATUS_TX_FULL) != 0) 240 while ((bus_space_read_4(bst, bsh, UART_STATUS_REG) & UART_STATUS_TX_FULL) != 0)
269 ; 241 ;
270 242
271 bus_space_write_4(bst, bsh, UART_WFIFO_REG, c); 243 bus_space_write_4(bst, bsh, UART_WFIFO_REG, c);
272 244
273 splx(s); 245 splx(s);
274} 246}
275  247
276 248
277static void 249static void
278amlogic_com_cnpollc(dev_t dev, int on) 250amlogic_com_cnpollc(dev_t dev, int on)
279{ 251{
280} 252}
281 253
282bool 254bool
283amlogic_com_cnattach(bus_space_tag_t bst, bus_space_handle_t bsh, 255amlogic_com_cnattach(bus_space_tag_t bst, bus_space_handle_t bsh,
284 int ospeed, tcflag_t cflag) 256 int ospeed, tcflag_t cflag)
285{ 257{
286 struct amlogic_com_softc *sc = &amlogic_com_cnsc; 258 struct amlogic_com_softc *sc = &amlogic_com_cnsc;
287 259
288 cn_tab = &amlogic_com_consdev; 260 cn_tab = &amlogic_com_consdev;
289 cn_init_magic(&amlogic_com_cnm_state); 261 cn_init_magic(&amlogic_com_cnm_state);
290 cn_set_magic("\047\001"); 262 cn_set_magic("\047\001");
291 263
292 sc->sc_bst = bst; 264 sc->sc_bst = bst;
293 sc->sc_bsh = bsh; 265 sc->sc_bsh = bsh;
294 sc->sc_ospeed = ospeed; 266 sc->sc_ospeed = ospeed;
295 sc->sc_cflag = cflag; 267 sc->sc_cflag = cflag;
296 268
297 return true; 269 return true;
298} 270}
299 271
300bool 272bool
301amlogic_com_is_console(bus_addr_t iobase) 273amlogic_com_is_console(bus_addr_t iobase)
302{ 274{
303 return iobase == CONSADDR; 275 return iobase == CONSADDR;
304} 276}
305 277
306static int 278static int
307amlogic_com_open(dev_t dev, int flag, int mode, lwp_t *l) 279amlogic_com_open(dev_t dev, int flag, int mode, lwp_t *l)
308{ 280{
309 struct amlogic_com_softc *sc = 281 struct amlogic_com_softc *sc =
310 device_lookup_private(&amlogiccom_cd, minor(dev)); 282 device_lookup_private(&amlogiccom_cd, minor(dev));
311 struct tty *tp = sc->sc_tty; 283 struct tty *tp = sc->sc_tty;
312 284
313 if (kauth_authorize_device_tty(l->l_cred, 285 if (kauth_authorize_device_tty(l->l_cred,
314 KAUTH_DEVICE_TTY_OPEN, tp) != 0) { 286 KAUTH_DEVICE_TTY_OPEN, tp) != 0) {
315 return EBUSY; 287 return EBUSY;
316 } 288 }
317 289
318 if ((tp->t_state & TS_ISOPEN) == 0 && tp->t_wopen == 0) { 290 if ((tp->t_state & TS_ISOPEN) == 0 && tp->t_wopen == 0) {
319 tp->t_dev = dev; 291 tp->t_dev = dev;
320 ttychars(tp); 292 ttychars(tp);
321 tp->t_iflag = TTYDEF_IFLAG; 293 tp->t_iflag = TTYDEF_IFLAG;
322 tp->t_oflag = TTYDEF_OFLAG; 294 tp->t_oflag = TTYDEF_OFLAG;
323 tp->t_cflag = TTYDEF_CFLAG; 295 tp->t_cflag = TTYDEF_CFLAG;
324 tp->t_lflag = TTYDEF_LFLAG; 296 tp->t_lflag = TTYDEF_LFLAG;
325 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 297 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
326 ttsetwater(tp); 298 ttsetwater(tp);
327 } 299 }
328 tp->t_state |= TS_CARR_ON; 300 tp->t_state |= TS_CARR_ON;
329 301
330 return tp->t_linesw->l_open(dev, tp); 302 return tp->t_linesw->l_open(dev, tp);
331} 303}
332 304
333static int 305static int
334amlogic_com_close(dev_t dev, int flag, int mode, lwp_t *l) 306amlogic_com_close(dev_t dev, int flag, int mode, lwp_t *l)
335{ 307{
336 struct amlogic_com_softc *sc = 308 struct amlogic_com_softc *sc =
337 device_lookup_private(&amlogiccom_cd, minor(dev)); 309 device_lookup_private(&amlogiccom_cd, minor(dev));
338 struct tty *tp = sc->sc_tty; 310 struct tty *tp = sc->sc_tty;
339 311
340 tp->t_linesw->l_close(tp, flag); 312 tp->t_linesw->l_close(tp, flag);
341 ttyclose(tp); 313 ttyclose(tp);
342 314
343 return 0; 315 return 0;
344} 316}
345 317
346static int 318static int
347amlogic_com_read(dev_t dev, struct uio *uio, int flag) 319amlogic_com_read(dev_t dev, struct uio *uio, int flag)
348{ 320{
349 struct amlogic_com_softc *sc = 321 struct amlogic_com_softc *sc =
350 device_lookup_private(&amlogiccom_cd, minor(dev)); 322 device_lookup_private(&amlogiccom_cd, minor(dev));
351 struct tty *tp = sc->sc_tty; 323 struct tty *tp = sc->sc_tty;
352 324
353 return tp->t_linesw->l_read(tp, uio, flag); 325 return tp->t_linesw->l_read(tp, uio, flag);
354} 326}
355 327
356static int 328static int
357amlogic_com_write(dev_t dev, struct uio *uio, int flag) 329amlogic_com_write(dev_t dev, struct uio *uio, int flag)
358{ 330{
359 struct amlogic_com_softc *sc = 331 struct amlogic_com_softc *sc =
360 device_lookup_private(&amlogiccom_cd, minor(dev)); 332 device_lookup_private(&amlogiccom_cd, minor(dev));
361 struct tty *tp = sc->sc_tty; 333 struct tty *tp = sc->sc_tty;
362 334
363 return tp->t_linesw->l_write(tp, uio, flag); 335 return tp->t_linesw->l_write(tp, uio, flag);
364} 336}
365 337
366static int 338static int
367amlogic_com_poll(dev_t dev, int events, lwp_t *l) 339amlogic_com_poll(dev_t dev, int events, lwp_t *l)
368{ 340{
369 struct amlogic_com_softc *sc = 341 struct amlogic_com_softc *sc =
370 device_lookup_private(&amlogiccom_cd, minor(dev)); 342 device_lookup_private(&amlogiccom_cd, minor(dev));
371 struct tty *tp = sc->sc_tty; 343 struct tty *tp = sc->sc_tty;
372 344
373 return tp->t_linesw->l_poll(tp, events, l); 345 return tp->t_linesw->l_poll(tp, events, l);
374} 346}
375 347
376static int 348static int
377amlogic_com_ioctl(dev_t dev, u_long cmd, void *data, int flag, lwp_t *l) 349amlogic_com_ioctl(dev_t dev, u_long cmd, void *data, int flag, lwp_t *l)
378{ 350{
379 struct amlogic_com_softc *sc = 351 struct amlogic_com_softc *sc =
380 device_lookup_private(&amlogiccom_cd, minor(dev)); 352 device_lookup_private(&amlogiccom_cd, minor(dev));
381 struct tty *tp = sc->sc_tty; 353 struct tty *tp = sc->sc_tty;
382 int error; 354 int error;
383 355
384 error = tp->t_linesw->l_ioctl(tp, cmd, data, flag, l); 356 error = tp->t_linesw->l_ioctl(tp, cmd, data, flag, l);
385 if (error != EPASSTHROUGH) 357 if (error != EPASSTHROUGH)
386 return error; 358 return error;
387 359
388 return ttioctl(tp, cmd, data, flag, l); 360 return ttioctl(tp, cmd, data, flag, l);
389} 361}
390 362
391static struct tty * 363static struct tty *
392amlogic_com_tty(dev_t dev) 364amlogic_com_tty(dev_t dev)
393{ 365{
394 struct amlogic_com_softc *sc = 366 struct amlogic_com_softc *sc =
395 device_lookup_private(&amlogiccom_cd, minor(dev)); 367 device_lookup_private(&amlogiccom_cd, minor(dev));
396 368
397 return sc->sc_tty; 369 return sc->sc_tty;
398} 370}
399 371
400static void 372static void
401amlogic_com_stop(struct tty *tp, int flag) 373amlogic_com_stop(struct tty *tp, int flag)
402{ 374{
403} 375}
404 376
405static void 377static void
406amlogic_com_start(struct tty *tp) 378amlogic_com_start(struct tty *tp)
407{ 379{
408 struct amlogic_com_softc *sc = tp->t_sc; 380 struct amlogic_com_softc *sc = tp->t_sc;
409 u_char *p = sc->sc_buf; 381 u_char *p = sc->sc_buf;
410 int s, brem; 382 int s, brem;
411 383
412 s = spltty(); 384 s = spltty();
413 385
414 if (tp->t_state & (TS_TTSTOP | TS_BUSY | TS_TIMEOUT)) { 386 if (tp->t_state & (TS_TTSTOP | TS_BUSY | TS_TIMEOUT)) {
415 splx(s); 387 splx(s);
416 return; 388 return;
417 } 389 }
418 tp->t_state |= TS_BUSY; 390 tp->t_state |= TS_BUSY;
419 391
420 splx(s); 392 splx(s);
421 393
422 for (brem = q_to_b(&tp->t_outq, sc->sc_buf, sizeof(sc->sc_buf)); 394 for (brem = q_to_b(&tp->t_outq, sc->sc_buf, sizeof(sc->sc_buf));
423 brem > 0; 395 brem > 0;
424 brem--, p++) { 396 brem--, p++) {
425 while ((bus_space_read_4(sc->sc_bst, sc->sc_bsh, 397 while ((bus_space_read_4(sc->sc_bst, sc->sc_bsh,
426 UART_STATUS_REG) & UART_STATUS_TX_FULL) != 0) 398 UART_STATUS_REG) & UART_STATUS_TX_FULL) != 0)
427 ; 399 ;
428 400
429 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 401 bus_space_write_4(sc->sc_bst, sc->sc_bsh,
430 UART_WFIFO_REG, *p); 402 UART_WFIFO_REG, *p);
431 } 403 }
432 404
433 s = spltty(); 405 s = spltty();
434 tp->t_state &= ~TS_BUSY; 406 tp->t_state &= ~TS_BUSY;
435 if (ttypull(tp)) { 407 if (ttypull(tp)) {
436 tp->t_state |= TS_TIMEOUT; 408 tp->t_state |= TS_TIMEOUT;
437 callout_schedule(&tp->t_rstrt_ch, 1); 409 callout_schedule(&tp->t_rstrt_ch, 1);
438 } 410 }
439 splx(s); 411 splx(s);
440} 412}
441 413
442static int 414static int
443amlogic_com_param(struct tty *tp, struct termios *t) 415amlogic_com_param(struct tty *tp, struct termios *t)
444{ 416{
445 417
446 tp->t_ispeed = t->c_ispeed; 418 tp->t_ispeed = t->c_ispeed;
447 tp->t_ospeed = t->c_ospeed; 419 tp->t_ospeed = t->c_ospeed;
448 tp->t_cflag = t->c_cflag; 420 tp->t_cflag = t->c_cflag;
449 421
450 return 0; 422 return 0;
451} 423}
452 424
453static int 425static int
454amlogic_com_intr(void *priv) 426amlogic_com_intr(void *priv)
455{ 427{
456 struct amlogic_com_softc *sc = priv; 428 struct amlogic_com_softc *sc = priv;
457 struct tty *tp = sc->sc_tty; 429 struct tty *tp = sc->sc_tty;
458 uint32_t status, c; 430 uint32_t status, c;
459 431
460 for (;;) { 432 for (;;) {
461 status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 433 status = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
462 UART_STATUS_REG); 434 UART_STATUS_REG);
463 if (status & UART_STATUS_RX_EMPTY) { 435 if (status & UART_STATUS_RX_EMPTY) {
464 break; 436 break;
465 } 437 }
466 438
467 c = bus_space_read_4(sc->sc_bst, sc->sc_bsh, UART_RFIFO_REG); 439 c = bus_space_read_4(sc->sc_bst, sc->sc_bsh, UART_RFIFO_REG);
468 cn_check_magic(tp->t_dev, c, amlogic_com_cnm_state); 440 cn_check_magic(tp->t_dev, c, amlogic_com_cnm_state);
469 tp->t_linesw->l_rint(c & 0xff, tp); 441 tp->t_linesw->l_rint(c & 0xff, tp);
470 } 442 }
471 443
472 return 0; 444 return 0;
473} 445}
474 
475#ifdef AMLOGIC_COM_INTRPOLL 
476static void 
477amlogic_com_intrpoll(void *priv) 
478{ 
479 struct amlogic_com_softc *sc = priv; 
480 int s; 
481 
482 s = splserial(); 
483 amlogic_com_intr(sc); 
484 splx(s); 
485 
486 callout_schedule(&sc->sc_intrpoll_ch, AMLOGIC_COM_INTRPOLL_RATE); 
487} 
488#endif