Deleted Added
full compact
exynos_uart.c (279724) exynos_uart.c (281438)
1/*
2 * Copyright (c) 2003 Marcel Moolenaar
3 * Copyright (c) 2007-2009 Andrew Turner
4 * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
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
29#include <sys/cdefs.h>
1/*
2 * Copyright (c) 2003 Marcel Moolenaar
3 * Copyright (c) 2007-2009 Andrew Turner
4 * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
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
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: head/sys/arm/samsung/exynos/exynos_uart.c 279724 2015-03-07 15:24:15Z ian $");
30__FBSDID("$FreeBSD: head/sys/arm/samsung/exynos/exynos_uart.c 281438 2015-04-11 17:16:23Z andrew $");
31
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/bus.h>
35#include <sys/conf.h>
36#include <sys/cons.h>
37#include <sys/tty.h>
38#include <sys/rman.h>
39#include <machine/bus.h>
40#include <machine/intr.h>
41
42#include <dev/uart/uart.h>
43#include <dev/uart/uart_cpu.h>
44#include <dev/uart/uart_cpu_fdt.h>
45#include <dev/uart/uart_bus.h>
46
47#include <arm/samsung/exynos/exynos_uart.h>
48
49#include "uart_if.h"
50
51#define DEF_CLK 100000000
52
53static int sscomspeed(long, long);
54static int exynos4210_uart_param(struct uart_bas *, int, int, int, int);
55
56/*
57 * Low-level UART interface.
58 */
59static int exynos4210_probe(struct uart_bas *bas);
60static void exynos4210_init(struct uart_bas *bas, int, int, int, int);
61static void exynos4210_term(struct uart_bas *bas);
62static void exynos4210_putc(struct uart_bas *bas, int);
63static int exynos4210_rxready(struct uart_bas *bas);
64static int exynos4210_getc(struct uart_bas *bas, struct mtx *mtx);
65
66extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
67
68static int
69sscomspeed(long speed, long frequency)
70{
71 int x;
72
73 if (speed <= 0 || frequency <= 0)
74 return (-1);
75 x = (frequency / 16) / speed;
76 return (x-1);
77}
78
79static int
80exynos4210_uart_param(struct uart_bas *bas, int baudrate, int databits,
81 int stopbits, int parity)
82{
83 int brd, ulcon;
84
85 ulcon = 0;
86
87 switch(databits) {
88 case 5:
89 ulcon |= ULCON_LENGTH_5;
90 break;
91 case 6:
92 ulcon |= ULCON_LENGTH_6;
93 break;
94 case 7:
95 ulcon |= ULCON_LENGTH_7;
96 break;
97 case 8:
98 ulcon |= ULCON_LENGTH_8;
99 break;
100 default:
101 return (EINVAL);
102 }
103
104 switch (parity) {
105 case UART_PARITY_NONE:
106 ulcon |= ULCON_PARITY_NONE;
107 break;
108 case UART_PARITY_ODD:
109 ulcon |= ULCON_PARITY_ODD;
110 break;
111 case UART_PARITY_EVEN:
112 ulcon |= ULCON_PARITY_EVEN;
113 break;
114 case UART_PARITY_MARK:
115 case UART_PARITY_SPACE:
116 default:
117 return (EINVAL);
118 }
119
120 if (stopbits == 2)
121 ulcon |= ULCON_STOP;
122
123 uart_setreg(bas, SSCOM_ULCON, ulcon);
124
125 brd = sscomspeed(baudrate, bas->rclk);
126 uart_setreg(bas, SSCOM_UBRDIV, brd);
127
128 return (0);
129}
130
131struct uart_ops uart_exynos4210_ops = {
132 .probe = exynos4210_probe,
133 .init = exynos4210_init,
134 .term = exynos4210_term,
135 .putc = exynos4210_putc,
136 .rxready = exynos4210_rxready,
137 .getc = exynos4210_getc,
138};
139
140static int
141exynos4210_probe(struct uart_bas *bas)
142{
143
144 return (0);
145}
146
147static void
148exynos4210_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
149 int parity)
150{
151
152 if (bas->rclk == 0)
153 bas->rclk = DEF_CLK;
154
155 KASSERT(bas->rclk != 0, ("exynos4210_init: Invalid rclk"));
156
157 uart_setreg(bas, SSCOM_UCON, 0);
158 uart_setreg(bas, SSCOM_UFCON,
159 UFCON_TXTRIGGER_8 | UFCON_RXTRIGGER_8 |
160 UFCON_TXFIFO_RESET | UFCON_RXFIFO_RESET |
161 UFCON_FIFO_ENABLE);
162 exynos4210_uart_param(bas, baudrate, databits, stopbits, parity);
163
164 /* Enable UART. */
165 uart_setreg(bas, SSCOM_UCON, UCON_TXMODE_INT | UCON_RXMODE_INT |
166 UCON_TOINT);
167 uart_setreg(bas, SSCOM_UMCON, UMCON_RTS);
168}
169
170static void
171exynos4210_term(struct uart_bas *bas)
172{
173 /* XXX */
174}
175
176static void
177exynos4210_putc(struct uart_bas *bas, int c)
178{
179
180 while ((bus_space_read_4(bas->bst, bas->bsh, SSCOM_UFSTAT) &
181 UFSTAT_TXFULL) == UFSTAT_TXFULL)
182 continue;
183
184 uart_setreg(bas, SSCOM_UTXH, c);
185}
186
187static int
188exynos4210_rxready(struct uart_bas *bas)
189{
190
191 return ((uart_getreg(bas, SSCOM_UTRSTAT) & UTRSTAT_RXREADY) ==
192 UTRSTAT_RXREADY);
193}
194
195static int
196exynos4210_getc(struct uart_bas *bas, struct mtx *mtx)
197{
198 int utrstat;
199
200 utrstat = bus_space_read_1(bas->bst, bas->bsh, SSCOM_UTRSTAT);
201 while (!(utrstat & UTRSTAT_RXREADY)) {
202 utrstat = bus_space_read_1(bas->bst, bas->bsh, SSCOM_UTRSTAT);
203 continue;
204 }
205
206 return (bus_space_read_1(bas->bst, bas->bsh, SSCOM_URXH));
207}
208
209static int exynos4210_bus_probe(struct uart_softc *sc);
210static int exynos4210_bus_attach(struct uart_softc *sc);
211static int exynos4210_bus_flush(struct uart_softc *, int);
212static int exynos4210_bus_getsig(struct uart_softc *);
213static int exynos4210_bus_ioctl(struct uart_softc *, int, intptr_t);
214static int exynos4210_bus_ipend(struct uart_softc *);
215static int exynos4210_bus_param(struct uart_softc *, int, int, int, int);
216static int exynos4210_bus_receive(struct uart_softc *);
217static int exynos4210_bus_setsig(struct uart_softc *, int);
218static int exynos4210_bus_transmit(struct uart_softc *);
219
220static kobj_method_t exynos4210_methods[] = {
221 KOBJMETHOD(uart_probe, exynos4210_bus_probe),
222 KOBJMETHOD(uart_attach, exynos4210_bus_attach),
223 KOBJMETHOD(uart_flush, exynos4210_bus_flush),
224 KOBJMETHOD(uart_getsig, exynos4210_bus_getsig),
225 KOBJMETHOD(uart_ioctl, exynos4210_bus_ioctl),
226 KOBJMETHOD(uart_ipend, exynos4210_bus_ipend),
227 KOBJMETHOD(uart_param, exynos4210_bus_param),
228 KOBJMETHOD(uart_receive, exynos4210_bus_receive),
229 KOBJMETHOD(uart_setsig, exynos4210_bus_setsig),
230 KOBJMETHOD(uart_transmit, exynos4210_bus_transmit),
231
232 {0, 0 }
233};
234
235int
236exynos4210_bus_probe(struct uart_softc *sc)
237{
238
239 sc->sc_txfifosz = 16;
240 sc->sc_rxfifosz = 16;
241
242 return (0);
243}
244
245static int
246exynos4210_bus_attach(struct uart_softc *sc)
247{
248
249 sc->sc_hwiflow = 0;
250 sc->sc_hwoflow = 0;
251
252 return (0);
253}
254
255static int
256exynos4210_bus_transmit(struct uart_softc *sc)
257{
258 int i;
259 int reg;
260
261 uart_lock(sc->sc_hwmtx);
262
263 for (i = 0; i < sc->sc_txdatasz; i++) {
264 exynos4210_putc(&sc->sc_bas, sc->sc_txbuf[i]);
265 uart_barrier(&sc->sc_bas);
266 }
267
268 sc->sc_txbusy = 1;
269
270 uart_unlock(sc->sc_hwmtx);
271
272 /* unmask TX interrupt */
273 reg = bus_space_read_4(sc->sc_bas.bst, sc->sc_bas.bsh, SSCOM_UINTM);
274 reg &= ~(1 << 2);
275 bus_space_write_4(sc->sc_bas.bst, sc->sc_bas.bsh, SSCOM_UINTM, reg);
276
277 return (0);
278}
279
280static int
281exynos4210_bus_setsig(struct uart_softc *sc, int sig)
282{
283
284 return (0);
285}
286
287static int
288exynos4210_bus_receive(struct uart_softc *sc)
289{
290 struct uart_bas *bas;
291
292 bas = &sc->sc_bas;
293 while (bus_space_read_4(bas->bst, bas->bsh,
294 SSCOM_UFSTAT) & UFSTAT_RXCOUNT)
295 uart_rx_put(sc, uart_getreg(&sc->sc_bas, SSCOM_URXH));
296
297 return (0);
298}
299
300static int
301exynos4210_bus_param(struct uart_softc *sc, int baudrate, int databits,
302 int stopbits, int parity)
303{
304 int error;
305
306 if (sc->sc_bas.rclk == 0)
307 sc->sc_bas.rclk = DEF_CLK;
308
309 KASSERT(sc->sc_bas.rclk != 0, ("exynos4210_init: Invalid rclk"));
310
311 uart_lock(sc->sc_hwmtx);
312 error = exynos4210_uart_param(&sc->sc_bas, baudrate, databits, stopbits,
313 parity);
314 uart_unlock(sc->sc_hwmtx);
315
316 return (error);
317}
318
319static int
320exynos4210_bus_ipend(struct uart_softc *sc)
321{
322 uint32_t ints;
323 uint32_t txempty, rxready;
324 int reg;
325 int ipend;
326
327 uart_lock(sc->sc_hwmtx);
328 ints = bus_space_read_4(sc->sc_bas.bst, sc->sc_bas.bsh, SSCOM_UINTP);
329 bus_space_write_4(sc->sc_bas.bst, sc->sc_bas.bsh, SSCOM_UINTP, ints);
330
331 txempty = (1 << 2);
332 rxready = (1 << 0);
333
334 ipend = 0;
335 if ((ints & txempty) > 0) {
336 if (sc->sc_txbusy != 0)
337 ipend |= SER_INT_TXIDLE;
338
339 /* mask TX interrupt */
340 reg = bus_space_read_4(sc->sc_bas.bst, sc->sc_bas.bsh,
341 SSCOM_UINTM);
342 reg |= (1 << 2);
343 bus_space_write_4(sc->sc_bas.bst, sc->sc_bas.bsh,
344 SSCOM_UINTM, reg);
345 }
346
347 if ((ints & rxready) > 0) {
348 ipend |= SER_INT_RXREADY;
349 }
350
351 uart_unlock(sc->sc_hwmtx);
352 return (ipend);
353}
354
355static int
356exynos4210_bus_flush(struct uart_softc *sc, int what)
357{
358
359 return (0);
360}
361
362static int
363exynos4210_bus_getsig(struct uart_softc *sc)
364{
365
366 return (0);
367}
368
369static int
370exynos4210_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
371{
372
373 return (EINVAL);
374}
375
376static struct uart_class uart_exynos4210_class = {
377 "exynos4210 class",
378 exynos4210_methods,
379 1,
380 .uc_ops = &uart_exynos4210_ops,
381 .uc_range = 8,
382 .uc_rclk = 0,
31
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/bus.h>
35#include <sys/conf.h>
36#include <sys/cons.h>
37#include <sys/tty.h>
38#include <sys/rman.h>
39#include <machine/bus.h>
40#include <machine/intr.h>
41
42#include <dev/uart/uart.h>
43#include <dev/uart/uart_cpu.h>
44#include <dev/uart/uart_cpu_fdt.h>
45#include <dev/uart/uart_bus.h>
46
47#include <arm/samsung/exynos/exynos_uart.h>
48
49#include "uart_if.h"
50
51#define DEF_CLK 100000000
52
53static int sscomspeed(long, long);
54static int exynos4210_uart_param(struct uart_bas *, int, int, int, int);
55
56/*
57 * Low-level UART interface.
58 */
59static int exynos4210_probe(struct uart_bas *bas);
60static void exynos4210_init(struct uart_bas *bas, int, int, int, int);
61static void exynos4210_term(struct uart_bas *bas);
62static void exynos4210_putc(struct uart_bas *bas, int);
63static int exynos4210_rxready(struct uart_bas *bas);
64static int exynos4210_getc(struct uart_bas *bas, struct mtx *mtx);
65
66extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
67
68static int
69sscomspeed(long speed, long frequency)
70{
71 int x;
72
73 if (speed <= 0 || frequency <= 0)
74 return (-1);
75 x = (frequency / 16) / speed;
76 return (x-1);
77}
78
79static int
80exynos4210_uart_param(struct uart_bas *bas, int baudrate, int databits,
81 int stopbits, int parity)
82{
83 int brd, ulcon;
84
85 ulcon = 0;
86
87 switch(databits) {
88 case 5:
89 ulcon |= ULCON_LENGTH_5;
90 break;
91 case 6:
92 ulcon |= ULCON_LENGTH_6;
93 break;
94 case 7:
95 ulcon |= ULCON_LENGTH_7;
96 break;
97 case 8:
98 ulcon |= ULCON_LENGTH_8;
99 break;
100 default:
101 return (EINVAL);
102 }
103
104 switch (parity) {
105 case UART_PARITY_NONE:
106 ulcon |= ULCON_PARITY_NONE;
107 break;
108 case UART_PARITY_ODD:
109 ulcon |= ULCON_PARITY_ODD;
110 break;
111 case UART_PARITY_EVEN:
112 ulcon |= ULCON_PARITY_EVEN;
113 break;
114 case UART_PARITY_MARK:
115 case UART_PARITY_SPACE:
116 default:
117 return (EINVAL);
118 }
119
120 if (stopbits == 2)
121 ulcon |= ULCON_STOP;
122
123 uart_setreg(bas, SSCOM_ULCON, ulcon);
124
125 brd = sscomspeed(baudrate, bas->rclk);
126 uart_setreg(bas, SSCOM_UBRDIV, brd);
127
128 return (0);
129}
130
131struct uart_ops uart_exynos4210_ops = {
132 .probe = exynos4210_probe,
133 .init = exynos4210_init,
134 .term = exynos4210_term,
135 .putc = exynos4210_putc,
136 .rxready = exynos4210_rxready,
137 .getc = exynos4210_getc,
138};
139
140static int
141exynos4210_probe(struct uart_bas *bas)
142{
143
144 return (0);
145}
146
147static void
148exynos4210_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
149 int parity)
150{
151
152 if (bas->rclk == 0)
153 bas->rclk = DEF_CLK;
154
155 KASSERT(bas->rclk != 0, ("exynos4210_init: Invalid rclk"));
156
157 uart_setreg(bas, SSCOM_UCON, 0);
158 uart_setreg(bas, SSCOM_UFCON,
159 UFCON_TXTRIGGER_8 | UFCON_RXTRIGGER_8 |
160 UFCON_TXFIFO_RESET | UFCON_RXFIFO_RESET |
161 UFCON_FIFO_ENABLE);
162 exynos4210_uart_param(bas, baudrate, databits, stopbits, parity);
163
164 /* Enable UART. */
165 uart_setreg(bas, SSCOM_UCON, UCON_TXMODE_INT | UCON_RXMODE_INT |
166 UCON_TOINT);
167 uart_setreg(bas, SSCOM_UMCON, UMCON_RTS);
168}
169
170static void
171exynos4210_term(struct uart_bas *bas)
172{
173 /* XXX */
174}
175
176static void
177exynos4210_putc(struct uart_bas *bas, int c)
178{
179
180 while ((bus_space_read_4(bas->bst, bas->bsh, SSCOM_UFSTAT) &
181 UFSTAT_TXFULL) == UFSTAT_TXFULL)
182 continue;
183
184 uart_setreg(bas, SSCOM_UTXH, c);
185}
186
187static int
188exynos4210_rxready(struct uart_bas *bas)
189{
190
191 return ((uart_getreg(bas, SSCOM_UTRSTAT) & UTRSTAT_RXREADY) ==
192 UTRSTAT_RXREADY);
193}
194
195static int
196exynos4210_getc(struct uart_bas *bas, struct mtx *mtx)
197{
198 int utrstat;
199
200 utrstat = bus_space_read_1(bas->bst, bas->bsh, SSCOM_UTRSTAT);
201 while (!(utrstat & UTRSTAT_RXREADY)) {
202 utrstat = bus_space_read_1(bas->bst, bas->bsh, SSCOM_UTRSTAT);
203 continue;
204 }
205
206 return (bus_space_read_1(bas->bst, bas->bsh, SSCOM_URXH));
207}
208
209static int exynos4210_bus_probe(struct uart_softc *sc);
210static int exynos4210_bus_attach(struct uart_softc *sc);
211static int exynos4210_bus_flush(struct uart_softc *, int);
212static int exynos4210_bus_getsig(struct uart_softc *);
213static int exynos4210_bus_ioctl(struct uart_softc *, int, intptr_t);
214static int exynos4210_bus_ipend(struct uart_softc *);
215static int exynos4210_bus_param(struct uart_softc *, int, int, int, int);
216static int exynos4210_bus_receive(struct uart_softc *);
217static int exynos4210_bus_setsig(struct uart_softc *, int);
218static int exynos4210_bus_transmit(struct uart_softc *);
219
220static kobj_method_t exynos4210_methods[] = {
221 KOBJMETHOD(uart_probe, exynos4210_bus_probe),
222 KOBJMETHOD(uart_attach, exynos4210_bus_attach),
223 KOBJMETHOD(uart_flush, exynos4210_bus_flush),
224 KOBJMETHOD(uart_getsig, exynos4210_bus_getsig),
225 KOBJMETHOD(uart_ioctl, exynos4210_bus_ioctl),
226 KOBJMETHOD(uart_ipend, exynos4210_bus_ipend),
227 KOBJMETHOD(uart_param, exynos4210_bus_param),
228 KOBJMETHOD(uart_receive, exynos4210_bus_receive),
229 KOBJMETHOD(uart_setsig, exynos4210_bus_setsig),
230 KOBJMETHOD(uart_transmit, exynos4210_bus_transmit),
231
232 {0, 0 }
233};
234
235int
236exynos4210_bus_probe(struct uart_softc *sc)
237{
238
239 sc->sc_txfifosz = 16;
240 sc->sc_rxfifosz = 16;
241
242 return (0);
243}
244
245static int
246exynos4210_bus_attach(struct uart_softc *sc)
247{
248
249 sc->sc_hwiflow = 0;
250 sc->sc_hwoflow = 0;
251
252 return (0);
253}
254
255static int
256exynos4210_bus_transmit(struct uart_softc *sc)
257{
258 int i;
259 int reg;
260
261 uart_lock(sc->sc_hwmtx);
262
263 for (i = 0; i < sc->sc_txdatasz; i++) {
264 exynos4210_putc(&sc->sc_bas, sc->sc_txbuf[i]);
265 uart_barrier(&sc->sc_bas);
266 }
267
268 sc->sc_txbusy = 1;
269
270 uart_unlock(sc->sc_hwmtx);
271
272 /* unmask TX interrupt */
273 reg = bus_space_read_4(sc->sc_bas.bst, sc->sc_bas.bsh, SSCOM_UINTM);
274 reg &= ~(1 << 2);
275 bus_space_write_4(sc->sc_bas.bst, sc->sc_bas.bsh, SSCOM_UINTM, reg);
276
277 return (0);
278}
279
280static int
281exynos4210_bus_setsig(struct uart_softc *sc, int sig)
282{
283
284 return (0);
285}
286
287static int
288exynos4210_bus_receive(struct uart_softc *sc)
289{
290 struct uart_bas *bas;
291
292 bas = &sc->sc_bas;
293 while (bus_space_read_4(bas->bst, bas->bsh,
294 SSCOM_UFSTAT) & UFSTAT_RXCOUNT)
295 uart_rx_put(sc, uart_getreg(&sc->sc_bas, SSCOM_URXH));
296
297 return (0);
298}
299
300static int
301exynos4210_bus_param(struct uart_softc *sc, int baudrate, int databits,
302 int stopbits, int parity)
303{
304 int error;
305
306 if (sc->sc_bas.rclk == 0)
307 sc->sc_bas.rclk = DEF_CLK;
308
309 KASSERT(sc->sc_bas.rclk != 0, ("exynos4210_init: Invalid rclk"));
310
311 uart_lock(sc->sc_hwmtx);
312 error = exynos4210_uart_param(&sc->sc_bas, baudrate, databits, stopbits,
313 parity);
314 uart_unlock(sc->sc_hwmtx);
315
316 return (error);
317}
318
319static int
320exynos4210_bus_ipend(struct uart_softc *sc)
321{
322 uint32_t ints;
323 uint32_t txempty, rxready;
324 int reg;
325 int ipend;
326
327 uart_lock(sc->sc_hwmtx);
328 ints = bus_space_read_4(sc->sc_bas.bst, sc->sc_bas.bsh, SSCOM_UINTP);
329 bus_space_write_4(sc->sc_bas.bst, sc->sc_bas.bsh, SSCOM_UINTP, ints);
330
331 txempty = (1 << 2);
332 rxready = (1 << 0);
333
334 ipend = 0;
335 if ((ints & txempty) > 0) {
336 if (sc->sc_txbusy != 0)
337 ipend |= SER_INT_TXIDLE;
338
339 /* mask TX interrupt */
340 reg = bus_space_read_4(sc->sc_bas.bst, sc->sc_bas.bsh,
341 SSCOM_UINTM);
342 reg |= (1 << 2);
343 bus_space_write_4(sc->sc_bas.bst, sc->sc_bas.bsh,
344 SSCOM_UINTM, reg);
345 }
346
347 if ((ints & rxready) > 0) {
348 ipend |= SER_INT_RXREADY;
349 }
350
351 uart_unlock(sc->sc_hwmtx);
352 return (ipend);
353}
354
355static int
356exynos4210_bus_flush(struct uart_softc *sc, int what)
357{
358
359 return (0);
360}
361
362static int
363exynos4210_bus_getsig(struct uart_softc *sc)
364{
365
366 return (0);
367}
368
369static int
370exynos4210_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
371{
372
373 return (EINVAL);
374}
375
376static struct uart_class uart_exynos4210_class = {
377 "exynos4210 class",
378 exynos4210_methods,
379 1,
380 .uc_ops = &uart_exynos4210_ops,
381 .uc_range = 8,
382 .uc_rclk = 0,
383 .uc_rshift = 0
383};
384
385static struct ofw_compat_data compat_data[] = {
386 {"exynos", (uintptr_t)&uart_exynos4210_class},
387 {NULL, (uintptr_t)NULL},
388};
389UART_FDT_CLASS_AND_DEVICE(compat_data);
384};
385
386static struct ofw_compat_data compat_data[] = {
387 {"exynos", (uintptr_t)&uart_exynos4210_class},
388 {NULL, (uintptr_t)NULL},
389};
390UART_FDT_CLASS_AND_DEVICE(compat_data);