1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* |
3 | * st-asc.c: ST Asynchronous serial controller (ASC) driver |
4 | * |
5 | * Copyright (C) 2003-2013 STMicroelectronics (R&D) Limited |
6 | */ |
7 | |
8 | #include <linux/module.h> |
9 | #include <linux/serial.h> |
10 | #include <linux/console.h> |
11 | #include <linux/sysrq.h> |
12 | #include <linux/pinctrl/consumer.h> |
13 | #include <linux/platform_device.h> |
14 | #include <linux/io.h> |
15 | #include <linux/irq.h> |
16 | #include <linux/tty.h> |
17 | #include <linux/tty_flip.h> |
18 | #include <linux/delay.h> |
19 | #include <linux/spinlock.h> |
20 | #include <linux/of.h> |
21 | #include <linux/of_platform.h> |
22 | #include <linux/serial_core.h> |
23 | #include <linux/clk.h> |
24 | #include <linux/gpio/consumer.h> |
25 | |
26 | #define DRIVER_NAME "st-asc" |
27 | #define ASC_SERIAL_NAME "ttyAS" |
28 | #define ASC_FIFO_SIZE 16 |
29 | #define ASC_MAX_PORTS 8 |
30 | |
31 | /* Pinctrl states */ |
32 | #define DEFAULT 0 |
33 | #define NO_HW_FLOWCTRL 1 |
34 | |
35 | struct asc_port { |
36 | struct uart_port port; |
37 | struct gpio_desc *rts; |
38 | struct clk *clk; |
39 | struct pinctrl *pinctrl; |
40 | struct pinctrl_state *states[2]; |
41 | unsigned int hw_flow_control:1; |
42 | unsigned int force_m1:1; |
43 | }; |
44 | |
45 | static struct asc_port asc_ports[ASC_MAX_PORTS]; |
46 | static struct uart_driver asc_uart_driver; |
47 | |
48 | /*---- UART Register definitions ------------------------------*/ |
49 | |
50 | /* Register offsets */ |
51 | |
52 | #define ASC_BAUDRATE 0x00 |
53 | #define ASC_TXBUF 0x04 |
54 | #define ASC_RXBUF 0x08 |
55 | #define ASC_CTL 0x0C |
56 | #define ASC_INTEN 0x10 |
57 | #define ASC_STA 0x14 |
58 | #define ASC_GUARDTIME 0x18 |
59 | #define ASC_TIMEOUT 0x1C |
60 | #define ASC_TXRESET 0x20 |
61 | #define ASC_RXRESET 0x24 |
62 | #define ASC_RETRIES 0x28 |
63 | |
64 | /* ASC_RXBUF */ |
65 | #define ASC_RXBUF_PE 0x100 |
66 | #define ASC_RXBUF_FE 0x200 |
67 | /* |
68 | * Some of status comes from higher bits of the character and some come from |
69 | * the status register. Combining both of them in to single status using dummy |
70 | * bits. |
71 | */ |
72 | #define ASC_RXBUF_DUMMY_RX 0x10000 |
73 | #define ASC_RXBUF_DUMMY_BE 0x20000 |
74 | #define ASC_RXBUF_DUMMY_OE 0x40000 |
75 | |
76 | /* ASC_CTL */ |
77 | |
78 | #define ASC_CTL_MODE_MSK 0x0007 |
79 | #define ASC_CTL_MODE_8BIT 0x0001 |
80 | #define ASC_CTL_MODE_7BIT_PAR 0x0003 |
81 | #define ASC_CTL_MODE_9BIT 0x0004 |
82 | #define ASC_CTL_MODE_8BIT_WKUP 0x0005 |
83 | #define ASC_CTL_MODE_8BIT_PAR 0x0007 |
84 | #define ASC_CTL_STOP_MSK 0x0018 |
85 | #define ASC_CTL_STOP_HALFBIT 0x0000 |
86 | #define ASC_CTL_STOP_1BIT 0x0008 |
87 | #define ASC_CTL_STOP_1_HALFBIT 0x0010 |
88 | #define ASC_CTL_STOP_2BIT 0x0018 |
89 | #define ASC_CTL_PARITYODD 0x0020 |
90 | #define ASC_CTL_LOOPBACK 0x0040 |
91 | #define ASC_CTL_RUN 0x0080 |
92 | #define ASC_CTL_RXENABLE 0x0100 |
93 | #define ASC_CTL_SCENABLE 0x0200 |
94 | #define ASC_CTL_FIFOENABLE 0x0400 |
95 | #define ASC_CTL_CTSENABLE 0x0800 |
96 | #define ASC_CTL_BAUDMODE 0x1000 |
97 | |
98 | /* ASC_GUARDTIME */ |
99 | |
100 | #define ASC_GUARDTIME_MSK 0x00FF |
101 | |
102 | /* ASC_INTEN */ |
103 | |
104 | #define ASC_INTEN_RBE 0x0001 |
105 | #define ASC_INTEN_TE 0x0002 |
106 | #define ASC_INTEN_THE 0x0004 |
107 | #define ASC_INTEN_PE 0x0008 |
108 | #define ASC_INTEN_FE 0x0010 |
109 | #define ASC_INTEN_OE 0x0020 |
110 | #define ASC_INTEN_TNE 0x0040 |
111 | #define ASC_INTEN_TOI 0x0080 |
112 | #define ASC_INTEN_RHF 0x0100 |
113 | |
114 | /* ASC_RETRIES */ |
115 | |
116 | #define ASC_RETRIES_MSK 0x00FF |
117 | |
118 | /* ASC_RXBUF */ |
119 | |
120 | #define ASC_RXBUF_MSK 0x03FF |
121 | |
122 | /* ASC_STA */ |
123 | |
124 | #define ASC_STA_RBF 0x0001 |
125 | #define ASC_STA_TE 0x0002 |
126 | #define ASC_STA_THE 0x0004 |
127 | #define ASC_STA_PE 0x0008 |
128 | #define ASC_STA_FE 0x0010 |
129 | #define ASC_STA_OE 0x0020 |
130 | #define ASC_STA_TNE 0x0040 |
131 | #define ASC_STA_TOI 0x0080 |
132 | #define ASC_STA_RHF 0x0100 |
133 | #define ASC_STA_TF 0x0200 |
134 | #define ASC_STA_NKD 0x0400 |
135 | |
136 | /* ASC_TIMEOUT */ |
137 | |
138 | #define ASC_TIMEOUT_MSK 0x00FF |
139 | |
140 | /* ASC_TXBUF */ |
141 | |
142 | #define ASC_TXBUF_MSK 0x01FF |
143 | |
144 | /*---- Inline function definitions ---------------------------*/ |
145 | |
146 | static inline struct asc_port *to_asc_port(struct uart_port *port) |
147 | { |
148 | return container_of(port, struct asc_port, port); |
149 | } |
150 | |
151 | static inline u32 asc_in(struct uart_port *port, u32 offset) |
152 | { |
153 | #ifdef readl_relaxed |
154 | return readl_relaxed(port->membase + offset); |
155 | #else |
156 | return readl(port->membase + offset); |
157 | #endif |
158 | } |
159 | |
160 | static inline void asc_out(struct uart_port *port, u32 offset, u32 value) |
161 | { |
162 | #ifdef writel_relaxed |
163 | writel_relaxed(value, port->membase + offset); |
164 | #else |
165 | writel(value, port->membase + offset); |
166 | #endif |
167 | } |
168 | |
169 | /* |
170 | * Some simple utility functions to enable and disable interrupts. |
171 | * Note that these need to be called with interrupts disabled. |
172 | */ |
173 | static inline void asc_disable_tx_interrupts(struct uart_port *port) |
174 | { |
175 | u32 intenable = asc_in(port, ASC_INTEN) & ~ASC_INTEN_THE; |
176 | asc_out(port, ASC_INTEN, value: intenable); |
177 | (void)asc_in(port, ASC_INTEN); /* Defeat bus write posting */ |
178 | } |
179 | |
180 | static inline void asc_enable_tx_interrupts(struct uart_port *port) |
181 | { |
182 | u32 intenable = asc_in(port, ASC_INTEN) | ASC_INTEN_THE; |
183 | asc_out(port, ASC_INTEN, value: intenable); |
184 | } |
185 | |
186 | static inline void asc_disable_rx_interrupts(struct uart_port *port) |
187 | { |
188 | u32 intenable = asc_in(port, ASC_INTEN) & ~ASC_INTEN_RBE; |
189 | asc_out(port, ASC_INTEN, value: intenable); |
190 | (void)asc_in(port, ASC_INTEN); /* Defeat bus write posting */ |
191 | } |
192 | |
193 | static inline void asc_enable_rx_interrupts(struct uart_port *port) |
194 | { |
195 | u32 intenable = asc_in(port, ASC_INTEN) | ASC_INTEN_RBE; |
196 | asc_out(port, ASC_INTEN, value: intenable); |
197 | } |
198 | |
199 | static inline u32 asc_txfifo_is_empty(struct uart_port *port) |
200 | { |
201 | return asc_in(port, ASC_STA) & ASC_STA_TE; |
202 | } |
203 | |
204 | static inline u32 asc_txfifo_is_half_empty(struct uart_port *port) |
205 | { |
206 | return asc_in(port, ASC_STA) & ASC_STA_THE; |
207 | } |
208 | |
209 | static inline const char *asc_port_name(struct uart_port *port) |
210 | { |
211 | return to_platform_device(port->dev)->name; |
212 | } |
213 | |
214 | /*----------------------------------------------------------------------*/ |
215 | |
216 | /* |
217 | * This section contains code to support the use of the ASC as a |
218 | * generic serial port. |
219 | */ |
220 | |
221 | static inline unsigned asc_hw_txroom(struct uart_port *port) |
222 | { |
223 | u32 status = asc_in(port, ASC_STA); |
224 | |
225 | if (status & ASC_STA_THE) |
226 | return port->fifosize / 2; |
227 | else if (!(status & ASC_STA_TF)) |
228 | return 1; |
229 | |
230 | return 0; |
231 | } |
232 | |
233 | /* |
234 | * Start transmitting chars. |
235 | * This is called from both interrupt and task level. |
236 | * Either way interrupts are disabled. |
237 | */ |
238 | static void asc_transmit_chars(struct uart_port *port) |
239 | { |
240 | u8 ch; |
241 | |
242 | uart_port_tx_limited(port, ch, asc_hw_txroom(port), |
243 | true, |
244 | asc_out(port, ASC_TXBUF, ch), |
245 | ({})); |
246 | } |
247 | |
248 | static void asc_receive_chars(struct uart_port *port) |
249 | { |
250 | struct tty_port *tport = &port->state->port; |
251 | unsigned long status, mode; |
252 | unsigned long c = 0; |
253 | u8 flag; |
254 | bool ignore_pe = false; |
255 | |
256 | /* |
257 | * Datasheet states: If the MODE field selects an 8-bit frame then |
258 | * this [parity error] bit is undefined. Software should ignore this |
259 | * bit when reading 8-bit frames. |
260 | */ |
261 | mode = asc_in(port, ASC_CTL) & ASC_CTL_MODE_MSK; |
262 | if (mode == ASC_CTL_MODE_8BIT || mode == ASC_CTL_MODE_8BIT_PAR) |
263 | ignore_pe = true; |
264 | |
265 | if (irqd_is_wakeup_set(d: irq_get_irq_data(irq: port->irq))) |
266 | pm_wakeup_event(dev: tport->tty->dev, msec: 0); |
267 | |
268 | while ((status = asc_in(port, ASC_STA)) & ASC_STA_RBF) { |
269 | c = asc_in(port, ASC_RXBUF) | ASC_RXBUF_DUMMY_RX; |
270 | flag = TTY_NORMAL; |
271 | port->icount.rx++; |
272 | |
273 | if (status & ASC_STA_OE || c & ASC_RXBUF_FE || |
274 | (c & ASC_RXBUF_PE && !ignore_pe)) { |
275 | |
276 | if (c & ASC_RXBUF_FE) { |
277 | if (c == (ASC_RXBUF_FE | ASC_RXBUF_DUMMY_RX)) { |
278 | port->icount.brk++; |
279 | if (uart_handle_break(port)) |
280 | continue; |
281 | c |= ASC_RXBUF_DUMMY_BE; |
282 | } else { |
283 | port->icount.frame++; |
284 | } |
285 | } else if (c & ASC_RXBUF_PE) { |
286 | port->icount.parity++; |
287 | } |
288 | /* |
289 | * Reading any data from the RX FIFO clears the |
290 | * overflow error condition. |
291 | */ |
292 | if (status & ASC_STA_OE) { |
293 | port->icount.overrun++; |
294 | c |= ASC_RXBUF_DUMMY_OE; |
295 | } |
296 | |
297 | c &= port->read_status_mask; |
298 | |
299 | if (c & ASC_RXBUF_DUMMY_BE) |
300 | flag = TTY_BREAK; |
301 | else if (c & ASC_RXBUF_PE) |
302 | flag = TTY_PARITY; |
303 | else if (c & ASC_RXBUF_FE) |
304 | flag = TTY_FRAME; |
305 | } |
306 | |
307 | if (uart_handle_sysrq_char(port, ch: c & 0xff)) |
308 | continue; |
309 | |
310 | uart_insert_char(port, status: c, ASC_RXBUF_DUMMY_OE, ch: c & 0xff, flag); |
311 | } |
312 | |
313 | /* Tell the rest of the system the news. New characters! */ |
314 | tty_flip_buffer_push(port: tport); |
315 | } |
316 | |
317 | static irqreturn_t asc_interrupt(int irq, void *ptr) |
318 | { |
319 | struct uart_port *port = ptr; |
320 | u32 status; |
321 | |
322 | uart_port_lock(up: port); |
323 | |
324 | status = asc_in(port, ASC_STA); |
325 | |
326 | if (status & ASC_STA_RBF) { |
327 | /* Receive FIFO not empty */ |
328 | asc_receive_chars(port); |
329 | } |
330 | |
331 | if ((status & ASC_STA_THE) && |
332 | (asc_in(port, ASC_INTEN) & ASC_INTEN_THE)) { |
333 | /* Transmitter FIFO at least half empty */ |
334 | asc_transmit_chars(port); |
335 | } |
336 | |
337 | uart_port_unlock(up: port); |
338 | |
339 | return IRQ_HANDLED; |
340 | } |
341 | |
342 | /*----------------------------------------------------------------------*/ |
343 | |
344 | /* |
345 | * UART Functions |
346 | */ |
347 | |
348 | static unsigned int asc_tx_empty(struct uart_port *port) |
349 | { |
350 | return asc_txfifo_is_empty(port) ? TIOCSER_TEMT : 0; |
351 | } |
352 | |
353 | static void asc_set_mctrl(struct uart_port *port, unsigned int mctrl) |
354 | { |
355 | struct asc_port *ascport = to_asc_port(port); |
356 | |
357 | /* |
358 | * This routine is used for seting signals of: DTR, DCD, CTS and RTS. |
359 | * We use ASC's hardware for CTS/RTS when hardware flow-control is |
360 | * enabled, however if the RTS line is required for another purpose, |
361 | * commonly controlled using HUP from userspace, then we need to toggle |
362 | * it manually, using GPIO. |
363 | * |
364 | * Some boards also have DTR and DCD implemented using PIO pins, code to |
365 | * do this should be hooked in here. |
366 | */ |
367 | |
368 | if (!ascport->rts) |
369 | return; |
370 | |
371 | /* If HW flow-control is enabled, we can't fiddle with the RTS line */ |
372 | if (asc_in(port, ASC_CTL) & ASC_CTL_CTSENABLE) |
373 | return; |
374 | |
375 | gpiod_set_value(desc: ascport->rts, value: mctrl & TIOCM_RTS); |
376 | } |
377 | |
378 | static unsigned int asc_get_mctrl(struct uart_port *port) |
379 | { |
380 | /* |
381 | * This routine is used for geting signals of: DTR, DCD, DSR, RI, |
382 | * and CTS/RTS |
383 | */ |
384 | return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; |
385 | } |
386 | |
387 | /* There are probably characters waiting to be transmitted. */ |
388 | static void asc_start_tx(struct uart_port *port) |
389 | { |
390 | struct circ_buf *xmit = &port->state->xmit; |
391 | |
392 | if (!uart_circ_empty(xmit)) |
393 | asc_enable_tx_interrupts(port); |
394 | } |
395 | |
396 | /* Transmit stop */ |
397 | static void asc_stop_tx(struct uart_port *port) |
398 | { |
399 | asc_disable_tx_interrupts(port); |
400 | } |
401 | |
402 | /* Receive stop */ |
403 | static void asc_stop_rx(struct uart_port *port) |
404 | { |
405 | asc_disable_rx_interrupts(port); |
406 | } |
407 | |
408 | /* Handle breaks - ignored by us */ |
409 | static void asc_break_ctl(struct uart_port *port, int break_state) |
410 | { |
411 | /* Nothing here yet .. */ |
412 | } |
413 | |
414 | /* |
415 | * Enable port for reception. |
416 | */ |
417 | static int asc_startup(struct uart_port *port) |
418 | { |
419 | if (request_irq(irq: port->irq, handler: asc_interrupt, flags: 0, |
420 | name: asc_port_name(port), dev: port)) { |
421 | dev_err(port->dev, "cannot allocate irq.\n" ); |
422 | return -ENODEV; |
423 | } |
424 | |
425 | asc_transmit_chars(port); |
426 | asc_enable_rx_interrupts(port); |
427 | |
428 | return 0; |
429 | } |
430 | |
431 | static void asc_shutdown(struct uart_port *port) |
432 | { |
433 | asc_disable_tx_interrupts(port); |
434 | asc_disable_rx_interrupts(port); |
435 | free_irq(port->irq, port); |
436 | } |
437 | |
438 | static void asc_pm(struct uart_port *port, unsigned int state, |
439 | unsigned int oldstate) |
440 | { |
441 | struct asc_port *ascport = to_asc_port(port); |
442 | unsigned long flags; |
443 | u32 ctl; |
444 | |
445 | switch (state) { |
446 | case UART_PM_STATE_ON: |
447 | clk_prepare_enable(clk: ascport->clk); |
448 | break; |
449 | case UART_PM_STATE_OFF: |
450 | /* |
451 | * Disable the ASC baud rate generator, which is as close as |
452 | * we can come to turning it off. Note this is not called with |
453 | * the port spinlock held. |
454 | */ |
455 | uart_port_lock_irqsave(up: port, flags: &flags); |
456 | ctl = asc_in(port, ASC_CTL) & ~ASC_CTL_RUN; |
457 | asc_out(port, ASC_CTL, value: ctl); |
458 | uart_port_unlock_irqrestore(up: port, flags); |
459 | clk_disable_unprepare(clk: ascport->clk); |
460 | break; |
461 | } |
462 | } |
463 | |
464 | static void asc_set_termios(struct uart_port *port, struct ktermios *termios, |
465 | const struct ktermios *old) |
466 | { |
467 | struct asc_port *ascport = to_asc_port(port); |
468 | struct gpio_desc *gpiod; |
469 | unsigned int baud; |
470 | u32 ctrl_val; |
471 | tcflag_t cflag; |
472 | unsigned long flags; |
473 | |
474 | /* Update termios to reflect hardware capabilities */ |
475 | termios->c_cflag &= ~(CMSPAR | |
476 | (ascport->hw_flow_control ? 0 : CRTSCTS)); |
477 | |
478 | port->uartclk = clk_get_rate(clk: ascport->clk); |
479 | |
480 | baud = uart_get_baud_rate(port, termios, old, min: 0, max: port->uartclk/16); |
481 | cflag = termios->c_cflag; |
482 | |
483 | uart_port_lock_irqsave(up: port, flags: &flags); |
484 | |
485 | /* read control register */ |
486 | ctrl_val = asc_in(port, ASC_CTL); |
487 | |
488 | /* stop serial port and reset value */ |
489 | asc_out(port, ASC_CTL, value: (ctrl_val & ~ASC_CTL_RUN)); |
490 | ctrl_val = ASC_CTL_RXENABLE | ASC_CTL_FIFOENABLE; |
491 | |
492 | /* reset fifo rx & tx */ |
493 | asc_out(port, ASC_TXRESET, value: 1); |
494 | asc_out(port, ASC_RXRESET, value: 1); |
495 | |
496 | /* set character length */ |
497 | if ((cflag & CSIZE) == CS7) { |
498 | ctrl_val |= ASC_CTL_MODE_7BIT_PAR; |
499 | cflag |= PARENB; |
500 | } else { |
501 | ctrl_val |= (cflag & PARENB) ? ASC_CTL_MODE_8BIT_PAR : |
502 | ASC_CTL_MODE_8BIT; |
503 | cflag &= ~CSIZE; |
504 | cflag |= CS8; |
505 | } |
506 | termios->c_cflag = cflag; |
507 | |
508 | /* set stop bit */ |
509 | ctrl_val |= (cflag & CSTOPB) ? ASC_CTL_STOP_2BIT : ASC_CTL_STOP_1BIT; |
510 | |
511 | /* odd parity */ |
512 | if (cflag & PARODD) |
513 | ctrl_val |= ASC_CTL_PARITYODD; |
514 | |
515 | /* hardware flow control */ |
516 | if ((cflag & CRTSCTS)) { |
517 | ctrl_val |= ASC_CTL_CTSENABLE; |
518 | |
519 | /* If flow-control selected, stop handling RTS manually */ |
520 | if (ascport->rts) { |
521 | devm_gpiod_put(dev: port->dev, desc: ascport->rts); |
522 | ascport->rts = NULL; |
523 | |
524 | pinctrl_select_state(p: ascport->pinctrl, |
525 | s: ascport->states[DEFAULT]); |
526 | } |
527 | } else { |
528 | /* If flow-control disabled, it's safe to handle RTS manually */ |
529 | if (!ascport->rts && ascport->states[NO_HW_FLOWCTRL]) { |
530 | pinctrl_select_state(p: ascport->pinctrl, |
531 | s: ascport->states[NO_HW_FLOWCTRL]); |
532 | |
533 | gpiod = devm_gpiod_get(dev: port->dev, con_id: "rts" , flags: GPIOD_OUT_LOW); |
534 | if (!IS_ERR(ptr: gpiod)) { |
535 | gpiod_set_consumer_name(desc: gpiod, |
536 | name: port->dev->of_node->name); |
537 | ascport->rts = gpiod; |
538 | } |
539 | } |
540 | } |
541 | |
542 | if ((baud < 19200) && !ascport->force_m1) { |
543 | asc_out(port, ASC_BAUDRATE, value: (port->uartclk / (16 * baud))); |
544 | } else { |
545 | /* |
546 | * MODE 1: recommended for high bit rates (above 19.2K) |
547 | * |
548 | * baudrate * 16 * 2^16 |
549 | * ASCBaudRate = ------------------------ |
550 | * inputclock |
551 | * |
552 | * To keep maths inside 64bits, we divide inputclock by 16. |
553 | */ |
554 | u64 dividend = (u64)baud * (1 << 16); |
555 | |
556 | do_div(dividend, port->uartclk / 16); |
557 | asc_out(port, ASC_BAUDRATE, value: dividend); |
558 | ctrl_val |= ASC_CTL_BAUDMODE; |
559 | } |
560 | |
561 | uart_update_timeout(port, cflag, baud); |
562 | |
563 | ascport->port.read_status_mask = ASC_RXBUF_DUMMY_OE; |
564 | if (termios->c_iflag & INPCK) |
565 | ascport->port.read_status_mask |= ASC_RXBUF_FE | ASC_RXBUF_PE; |
566 | if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK)) |
567 | ascport->port.read_status_mask |= ASC_RXBUF_DUMMY_BE; |
568 | |
569 | /* |
570 | * Characters to ignore |
571 | */ |
572 | ascport->port.ignore_status_mask = 0; |
573 | if (termios->c_iflag & IGNPAR) |
574 | ascport->port.ignore_status_mask |= ASC_RXBUF_FE | ASC_RXBUF_PE; |
575 | if (termios->c_iflag & IGNBRK) { |
576 | ascport->port.ignore_status_mask |= ASC_RXBUF_DUMMY_BE; |
577 | /* |
578 | * If we're ignoring parity and break indicators, |
579 | * ignore overruns too (for real raw support). |
580 | */ |
581 | if (termios->c_iflag & IGNPAR) |
582 | ascport->port.ignore_status_mask |= ASC_RXBUF_DUMMY_OE; |
583 | } |
584 | |
585 | /* |
586 | * Ignore all characters if CREAD is not set. |
587 | */ |
588 | if (!(termios->c_cflag & CREAD)) |
589 | ascport->port.ignore_status_mask |= ASC_RXBUF_DUMMY_RX; |
590 | |
591 | /* Set the timeout */ |
592 | asc_out(port, ASC_TIMEOUT, value: 20); |
593 | |
594 | /* write final value and enable port */ |
595 | asc_out(port, ASC_CTL, value: (ctrl_val | ASC_CTL_RUN)); |
596 | |
597 | uart_port_unlock_irqrestore(up: port, flags); |
598 | } |
599 | |
600 | static const char *asc_type(struct uart_port *port) |
601 | { |
602 | return (port->type == PORT_ASC) ? DRIVER_NAME : NULL; |
603 | } |
604 | |
605 | static void asc_release_port(struct uart_port *port) |
606 | { |
607 | } |
608 | |
609 | static int asc_request_port(struct uart_port *port) |
610 | { |
611 | return 0; |
612 | } |
613 | |
614 | /* |
615 | * Called when the port is opened, and UPF_BOOT_AUTOCONF flag is set |
616 | * Set type field if successful |
617 | */ |
618 | static void asc_config_port(struct uart_port *port, int flags) |
619 | { |
620 | if ((flags & UART_CONFIG_TYPE)) |
621 | port->type = PORT_ASC; |
622 | } |
623 | |
624 | static int |
625 | asc_verify_port(struct uart_port *port, struct serial_struct *ser) |
626 | { |
627 | /* No user changeable parameters */ |
628 | return -EINVAL; |
629 | } |
630 | |
631 | #ifdef CONFIG_CONSOLE_POLL |
632 | /* |
633 | * Console polling routines for writing and reading from the uart while |
634 | * in an interrupt or debug context (i.e. kgdb). |
635 | */ |
636 | |
637 | static int asc_get_poll_char(struct uart_port *port) |
638 | { |
639 | if (!(asc_in(port, ASC_STA) & ASC_STA_RBF)) |
640 | return NO_POLL_CHAR; |
641 | |
642 | return asc_in(port, ASC_RXBUF); |
643 | } |
644 | |
645 | static void asc_put_poll_char(struct uart_port *port, unsigned char c) |
646 | { |
647 | while (!asc_txfifo_is_half_empty(port)) |
648 | cpu_relax(); |
649 | asc_out(port, ASC_TXBUF, value: c); |
650 | } |
651 | |
652 | #endif /* CONFIG_CONSOLE_POLL */ |
653 | |
654 | /*---------------------------------------------------------------------*/ |
655 | |
656 | static const struct uart_ops asc_uart_ops = { |
657 | .tx_empty = asc_tx_empty, |
658 | .set_mctrl = asc_set_mctrl, |
659 | .get_mctrl = asc_get_mctrl, |
660 | .start_tx = asc_start_tx, |
661 | .stop_tx = asc_stop_tx, |
662 | .stop_rx = asc_stop_rx, |
663 | .break_ctl = asc_break_ctl, |
664 | .startup = asc_startup, |
665 | .shutdown = asc_shutdown, |
666 | .set_termios = asc_set_termios, |
667 | .type = asc_type, |
668 | .release_port = asc_release_port, |
669 | .request_port = asc_request_port, |
670 | .config_port = asc_config_port, |
671 | .verify_port = asc_verify_port, |
672 | .pm = asc_pm, |
673 | #ifdef CONFIG_CONSOLE_POLL |
674 | .poll_get_char = asc_get_poll_char, |
675 | .poll_put_char = asc_put_poll_char, |
676 | #endif /* CONFIG_CONSOLE_POLL */ |
677 | }; |
678 | |
679 | static int asc_init_port(struct asc_port *ascport, |
680 | struct platform_device *pdev) |
681 | { |
682 | struct uart_port *port = &ascport->port; |
683 | struct resource *res; |
684 | int ret; |
685 | |
686 | port->iotype = UPIO_MEM; |
687 | port->flags = UPF_BOOT_AUTOCONF; |
688 | port->ops = &asc_uart_ops; |
689 | port->fifosize = ASC_FIFO_SIZE; |
690 | port->dev = &pdev->dev; |
691 | port->irq = platform_get_irq(pdev, 0); |
692 | port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_ST_ASC_CONSOLE); |
693 | |
694 | port->membase = devm_platform_get_and_ioremap_resource(pdev, index: 0, res: &res); |
695 | if (IS_ERR(ptr: port->membase)) |
696 | return PTR_ERR(ptr: port->membase); |
697 | port->mapbase = res->start; |
698 | |
699 | spin_lock_init(&port->lock); |
700 | |
701 | ascport->clk = devm_clk_get(dev: &pdev->dev, NULL); |
702 | |
703 | if (WARN_ON(IS_ERR(ascport->clk))) |
704 | return -EINVAL; |
705 | /* ensure that clk rate is correct by enabling the clk */ |
706 | ret = clk_prepare_enable(clk: ascport->clk); |
707 | if (ret) |
708 | return ret; |
709 | ascport->port.uartclk = clk_get_rate(clk: ascport->clk); |
710 | WARN_ON(ascport->port.uartclk == 0); |
711 | clk_disable_unprepare(clk: ascport->clk); |
712 | |
713 | ascport->pinctrl = devm_pinctrl_get(dev: &pdev->dev); |
714 | if (IS_ERR(ptr: ascport->pinctrl)) { |
715 | ret = PTR_ERR(ptr: ascport->pinctrl); |
716 | dev_err(&pdev->dev, "Failed to get Pinctrl: %d\n" , ret); |
717 | return ret; |
718 | } |
719 | |
720 | ascport->states[DEFAULT] = |
721 | pinctrl_lookup_state(p: ascport->pinctrl, name: "default" ); |
722 | if (IS_ERR(ptr: ascport->states[DEFAULT])) { |
723 | ret = PTR_ERR(ptr: ascport->states[DEFAULT]); |
724 | dev_err(&pdev->dev, |
725 | "Failed to look up Pinctrl state 'default': %d\n" , ret); |
726 | return ret; |
727 | } |
728 | |
729 | /* "no-hw-flowctrl" state is optional */ |
730 | ascport->states[NO_HW_FLOWCTRL] = |
731 | pinctrl_lookup_state(p: ascport->pinctrl, name: "no-hw-flowctrl" ); |
732 | if (IS_ERR(ptr: ascport->states[NO_HW_FLOWCTRL])) |
733 | ascport->states[NO_HW_FLOWCTRL] = NULL; |
734 | |
735 | return 0; |
736 | } |
737 | |
738 | static struct asc_port *asc_of_get_asc_port(struct platform_device *pdev) |
739 | { |
740 | struct device_node *np = pdev->dev.of_node; |
741 | int id; |
742 | |
743 | if (!np) |
744 | return NULL; |
745 | |
746 | id = of_alias_get_id(np, stem: "serial" ); |
747 | if (id < 0) |
748 | id = of_alias_get_id(np, ASC_SERIAL_NAME); |
749 | |
750 | if (id < 0) |
751 | id = 0; |
752 | |
753 | if (WARN_ON(id >= ASC_MAX_PORTS)) |
754 | return NULL; |
755 | |
756 | asc_ports[id].hw_flow_control = of_property_read_bool(np, |
757 | propname: "uart-has-rtscts" ); |
758 | asc_ports[id].force_m1 = of_property_read_bool(np, propname: "st,force-m1" ); |
759 | asc_ports[id].port.line = id; |
760 | asc_ports[id].rts = NULL; |
761 | |
762 | return &asc_ports[id]; |
763 | } |
764 | |
765 | #ifdef CONFIG_OF |
766 | static const struct of_device_id asc_match[] = { |
767 | { .compatible = "st,asc" , }, |
768 | {}, |
769 | }; |
770 | |
771 | MODULE_DEVICE_TABLE(of, asc_match); |
772 | #endif |
773 | |
774 | static int asc_serial_probe(struct platform_device *pdev) |
775 | { |
776 | int ret; |
777 | struct asc_port *ascport; |
778 | |
779 | ascport = asc_of_get_asc_port(pdev); |
780 | if (!ascport) |
781 | return -ENODEV; |
782 | |
783 | ret = asc_init_port(ascport, pdev); |
784 | if (ret) |
785 | return ret; |
786 | |
787 | ret = uart_add_one_port(reg: &asc_uart_driver, port: &ascport->port); |
788 | if (ret) |
789 | return ret; |
790 | |
791 | platform_set_drvdata(pdev, data: &ascport->port); |
792 | |
793 | return 0; |
794 | } |
795 | |
796 | static int asc_serial_remove(struct platform_device *pdev) |
797 | { |
798 | struct uart_port *port = platform_get_drvdata(pdev); |
799 | |
800 | uart_remove_one_port(reg: &asc_uart_driver, port); |
801 | |
802 | return 0; |
803 | } |
804 | |
805 | #ifdef CONFIG_PM_SLEEP |
806 | static int asc_serial_suspend(struct device *dev) |
807 | { |
808 | struct uart_port *port = dev_get_drvdata(dev); |
809 | |
810 | return uart_suspend_port(reg: &asc_uart_driver, port); |
811 | } |
812 | |
813 | static int asc_serial_resume(struct device *dev) |
814 | { |
815 | struct uart_port *port = dev_get_drvdata(dev); |
816 | |
817 | return uart_resume_port(reg: &asc_uart_driver, port); |
818 | } |
819 | |
820 | #endif /* CONFIG_PM_SLEEP */ |
821 | |
822 | /*----------------------------------------------------------------------*/ |
823 | |
824 | #ifdef CONFIG_SERIAL_ST_ASC_CONSOLE |
825 | static void asc_console_putchar(struct uart_port *port, unsigned char ch) |
826 | { |
827 | unsigned int timeout = 1000000; |
828 | |
829 | /* Wait for upto 1 second in case flow control is stopping us. */ |
830 | while (--timeout && !asc_txfifo_is_half_empty(port)) |
831 | udelay(1); |
832 | |
833 | asc_out(port, ASC_TXBUF, value: ch); |
834 | } |
835 | |
836 | /* |
837 | * Print a string to the serial port trying not to disturb |
838 | * any possible real use of the port... |
839 | */ |
840 | |
841 | static void asc_console_write(struct console *co, const char *s, unsigned count) |
842 | { |
843 | struct uart_port *port = &asc_ports[co->index].port; |
844 | unsigned long flags; |
845 | unsigned long timeout = 1000000; |
846 | int locked = 1; |
847 | u32 intenable; |
848 | |
849 | if (port->sysrq) |
850 | locked = 0; /* asc_interrupt has already claimed the lock */ |
851 | else if (oops_in_progress) |
852 | locked = uart_port_trylock_irqsave(up: port, flags: &flags); |
853 | else |
854 | uart_port_lock_irqsave(up: port, flags: &flags); |
855 | |
856 | /* |
857 | * Disable interrupts so we don't get the IRQ line bouncing |
858 | * up and down while interrupts are disabled. |
859 | */ |
860 | intenable = asc_in(port, ASC_INTEN); |
861 | asc_out(port, ASC_INTEN, value: 0); |
862 | (void)asc_in(port, ASC_INTEN); /* Defeat bus write posting */ |
863 | |
864 | uart_console_write(port, s, count, putchar: asc_console_putchar); |
865 | |
866 | while (--timeout && !asc_txfifo_is_empty(port)) |
867 | udelay(1); |
868 | |
869 | asc_out(port, ASC_INTEN, value: intenable); |
870 | |
871 | if (locked) |
872 | uart_port_unlock_irqrestore(up: port, flags); |
873 | } |
874 | |
875 | static int asc_console_setup(struct console *co, char *options) |
876 | { |
877 | struct asc_port *ascport; |
878 | int baud = 115200; |
879 | int bits = 8; |
880 | int parity = 'n'; |
881 | int flow = 'n'; |
882 | |
883 | if (co->index >= ASC_MAX_PORTS) |
884 | return -ENODEV; |
885 | |
886 | ascport = &asc_ports[co->index]; |
887 | |
888 | /* |
889 | * This driver does not support early console initialization |
890 | * (use ARM early printk support instead), so we only expect |
891 | * this to be called during the uart port registration when the |
892 | * driver gets probed and the port should be mapped at that point. |
893 | */ |
894 | if (ascport->port.mapbase == 0 || ascport->port.membase == NULL) |
895 | return -ENXIO; |
896 | |
897 | if (options) |
898 | uart_parse_options(options, baud: &baud, parity: &parity, bits: &bits, flow: &flow); |
899 | |
900 | return uart_set_options(port: &ascport->port, co, baud, parity, bits, flow); |
901 | } |
902 | |
903 | static struct console asc_console = { |
904 | .name = ASC_SERIAL_NAME, |
905 | .device = uart_console_device, |
906 | .write = asc_console_write, |
907 | .setup = asc_console_setup, |
908 | .flags = CON_PRINTBUFFER, |
909 | .index = -1, |
910 | .data = &asc_uart_driver, |
911 | }; |
912 | |
913 | #define ASC_SERIAL_CONSOLE (&asc_console) |
914 | |
915 | #else |
916 | #define ASC_SERIAL_CONSOLE NULL |
917 | #endif /* CONFIG_SERIAL_ST_ASC_CONSOLE */ |
918 | |
919 | static struct uart_driver asc_uart_driver = { |
920 | .owner = THIS_MODULE, |
921 | .driver_name = DRIVER_NAME, |
922 | .dev_name = ASC_SERIAL_NAME, |
923 | .major = 0, |
924 | .minor = 0, |
925 | .nr = ASC_MAX_PORTS, |
926 | .cons = ASC_SERIAL_CONSOLE, |
927 | }; |
928 | |
929 | static const struct dev_pm_ops asc_serial_pm_ops = { |
930 | SET_SYSTEM_SLEEP_PM_OPS(asc_serial_suspend, asc_serial_resume) |
931 | }; |
932 | |
933 | static struct platform_driver asc_serial_driver = { |
934 | .probe = asc_serial_probe, |
935 | .remove = asc_serial_remove, |
936 | .driver = { |
937 | .name = DRIVER_NAME, |
938 | .pm = &asc_serial_pm_ops, |
939 | .of_match_table = of_match_ptr(asc_match), |
940 | }, |
941 | }; |
942 | |
943 | static int __init asc_init(void) |
944 | { |
945 | int ret; |
946 | static const char banner[] __initconst = |
947 | KERN_INFO "STMicroelectronics ASC driver initialized\n" ; |
948 | |
949 | printk(banner); |
950 | |
951 | ret = uart_register_driver(uart: &asc_uart_driver); |
952 | if (ret) |
953 | return ret; |
954 | |
955 | ret = platform_driver_register(&asc_serial_driver); |
956 | if (ret) |
957 | uart_unregister_driver(uart: &asc_uart_driver); |
958 | |
959 | return ret; |
960 | } |
961 | |
962 | static void __exit asc_exit(void) |
963 | { |
964 | platform_driver_unregister(&asc_serial_driver); |
965 | uart_unregister_driver(uart: &asc_uart_driver); |
966 | } |
967 | |
968 | module_init(asc_init); |
969 | module_exit(asc_exit); |
970 | |
971 | MODULE_ALIAS("platform:" DRIVER_NAME); |
972 | MODULE_AUTHOR("STMicroelectronics (R&D) Limited" ); |
973 | MODULE_DESCRIPTION("STMicroelectronics ASC serial port driver" ); |
974 | MODULE_LICENSE("GPL" ); |
975 | |