1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Derived from many drivers using generic_serial interface, |
4 | * especially serial_tx3912.c by Steven J. Hill and r39xx_serial.c |
5 | * (was in Linux/VR tree) by Jim Pick. |
6 | * |
7 | * Copyright (C) 1999 Harald Koerfgen |
8 | * Copyright (C) 2000 Jim Pick <jim@jimpick.com> |
9 | * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com) |
10 | * Copyright (C) 2000-2002 Toshiba Corporation |
11 | * |
12 | * Serial driver for TX3927/TX4927/TX4925/TX4938 internal SIO controller |
13 | */ |
14 | |
15 | #include <linux/module.h> |
16 | #include <linux/ioport.h> |
17 | #include <linux/init.h> |
18 | #include <linux/console.h> |
19 | #include <linux/delay.h> |
20 | #include <linux/platform_device.h> |
21 | #include <linux/pci.h> |
22 | #include <linux/serial_core.h> |
23 | #include <linux/serial.h> |
24 | #include <linux/tty.h> |
25 | #include <linux/tty_flip.h> |
26 | |
27 | #include <linux/io.h> |
28 | |
29 | #define PASS_LIMIT 256 |
30 | |
31 | #if !defined(CONFIG_SERIAL_TXX9_STDSERIAL) |
32 | /* "ttyS" is used for standard serial driver */ |
33 | #define TXX9_TTY_NAME "ttyTX" |
34 | #define TXX9_TTY_MINOR_START 196 |
35 | #define TXX9_TTY_MAJOR 204 |
36 | #else |
37 | /* acts like standard serial driver */ |
38 | #define TXX9_TTY_NAME "ttyS" |
39 | #define TXX9_TTY_MINOR_START 64 |
40 | #define TXX9_TTY_MAJOR TTY_MAJOR |
41 | #endif |
42 | |
43 | /* flag aliases */ |
44 | #define UPF_TXX9_HAVE_CTS_LINE UPF_BUGGY_UART |
45 | #define UPF_TXX9_USE_SCLK UPF_MAGIC_MULTIPLIER |
46 | |
47 | #ifdef CONFIG_PCI |
48 | /* support for Toshiba TC86C001 SIO */ |
49 | #define ENABLE_SERIAL_TXX9_PCI |
50 | #endif |
51 | |
52 | /* |
53 | * Number of serial ports |
54 | */ |
55 | #define UART_NR CONFIG_SERIAL_TXX9_NR_UARTS |
56 | |
57 | #define TXX9_REGION_SIZE 0x24 |
58 | |
59 | /* TXX9 Serial Registers */ |
60 | #define TXX9_SILCR 0x00 |
61 | #define TXX9_SIDICR 0x04 |
62 | #define TXX9_SIDISR 0x08 |
63 | #define TXX9_SICISR 0x0c |
64 | #define TXX9_SIFCR 0x10 |
65 | #define TXX9_SIFLCR 0x14 |
66 | #define TXX9_SIBGR 0x18 |
67 | #define TXX9_SITFIFO 0x1c |
68 | #define TXX9_SIRFIFO 0x20 |
69 | |
70 | /* SILCR : Line Control */ |
71 | #define TXX9_SILCR_SCS_MASK 0x00000060 |
72 | #define TXX9_SILCR_SCS_IMCLK 0x00000000 |
73 | #define TXX9_SILCR_SCS_IMCLK_BG 0x00000020 |
74 | #define TXX9_SILCR_SCS_SCLK 0x00000040 |
75 | #define TXX9_SILCR_SCS_SCLK_BG 0x00000060 |
76 | #define TXX9_SILCR_UEPS 0x00000010 |
77 | #define TXX9_SILCR_UPEN 0x00000008 |
78 | #define TXX9_SILCR_USBL_MASK 0x00000004 |
79 | #define TXX9_SILCR_USBL_1BIT 0x00000000 |
80 | #define TXX9_SILCR_USBL_2BIT 0x00000004 |
81 | #define TXX9_SILCR_UMODE_MASK 0x00000003 |
82 | #define TXX9_SILCR_UMODE_8BIT 0x00000000 |
83 | #define TXX9_SILCR_UMODE_7BIT 0x00000001 |
84 | |
85 | /* SIDICR : DMA/Int. Control */ |
86 | #define TXX9_SIDICR_TDE 0x00008000 |
87 | #define TXX9_SIDICR_RDE 0x00004000 |
88 | #define TXX9_SIDICR_TIE 0x00002000 |
89 | #define TXX9_SIDICR_RIE 0x00001000 |
90 | #define TXX9_SIDICR_SPIE 0x00000800 |
91 | #define TXX9_SIDICR_CTSAC 0x00000600 |
92 | #define TXX9_SIDICR_STIE_MASK 0x0000003f |
93 | #define TXX9_SIDICR_STIE_OERS 0x00000020 |
94 | #define TXX9_SIDICR_STIE_CTSS 0x00000010 |
95 | #define TXX9_SIDICR_STIE_RBRKD 0x00000008 |
96 | #define TXX9_SIDICR_STIE_TRDY 0x00000004 |
97 | #define TXX9_SIDICR_STIE_TXALS 0x00000002 |
98 | #define TXX9_SIDICR_STIE_UBRKD 0x00000001 |
99 | |
100 | /* SIDISR : DMA/Int. Status */ |
101 | #define TXX9_SIDISR_UBRK 0x00008000 |
102 | #define TXX9_SIDISR_UVALID 0x00004000 |
103 | #define TXX9_SIDISR_UFER 0x00002000 |
104 | #define TXX9_SIDISR_UPER 0x00001000 |
105 | #define TXX9_SIDISR_UOER 0x00000800 |
106 | #define TXX9_SIDISR_ERI 0x00000400 |
107 | #define TXX9_SIDISR_TOUT 0x00000200 |
108 | #define TXX9_SIDISR_TDIS 0x00000100 |
109 | #define TXX9_SIDISR_RDIS 0x00000080 |
110 | #define TXX9_SIDISR_STIS 0x00000040 |
111 | #define TXX9_SIDISR_RFDN_MASK 0x0000001f |
112 | |
113 | /* SICISR : Change Int. Status */ |
114 | #define TXX9_SICISR_OERS 0x00000020 |
115 | #define TXX9_SICISR_CTSS 0x00000010 |
116 | #define TXX9_SICISR_RBRKD 0x00000008 |
117 | #define TXX9_SICISR_TRDY 0x00000004 |
118 | #define TXX9_SICISR_TXALS 0x00000002 |
119 | #define TXX9_SICISR_UBRKD 0x00000001 |
120 | |
121 | /* SIFCR : FIFO Control */ |
122 | #define TXX9_SIFCR_SWRST 0x00008000 |
123 | #define TXX9_SIFCR_RDIL_MASK 0x00000180 |
124 | #define TXX9_SIFCR_RDIL_1 0x00000000 |
125 | #define TXX9_SIFCR_RDIL_4 0x00000080 |
126 | #define TXX9_SIFCR_RDIL_8 0x00000100 |
127 | #define TXX9_SIFCR_RDIL_12 0x00000180 |
128 | #define TXX9_SIFCR_RDIL_MAX 0x00000180 |
129 | #define TXX9_SIFCR_TDIL_MASK 0x00000018 |
130 | #define TXX9_SIFCR_TDIL_1 0x00000000 |
131 | #define TXX9_SIFCR_TDIL_4 0x00000001 |
132 | #define TXX9_SIFCR_TDIL_8 0x00000010 |
133 | #define TXX9_SIFCR_TDIL_MAX 0x00000010 |
134 | #define TXX9_SIFCR_TFRST 0x00000004 |
135 | #define TXX9_SIFCR_RFRST 0x00000002 |
136 | #define TXX9_SIFCR_FRSTE 0x00000001 |
137 | #define TXX9_SIO_TX_FIFO 8 |
138 | #define TXX9_SIO_RX_FIFO 16 |
139 | |
140 | /* SIFLCR : Flow Control */ |
141 | #define TXX9_SIFLCR_RCS 0x00001000 |
142 | #define TXX9_SIFLCR_TES 0x00000800 |
143 | #define TXX9_SIFLCR_RTSSC 0x00000200 |
144 | #define TXX9_SIFLCR_RSDE 0x00000100 |
145 | #define TXX9_SIFLCR_TSDE 0x00000080 |
146 | #define TXX9_SIFLCR_RTSTL_MASK 0x0000001e |
147 | #define TXX9_SIFLCR_RTSTL_MAX 0x0000001e |
148 | #define TXX9_SIFLCR_TBRK 0x00000001 |
149 | |
150 | /* SIBGR : Baudrate Control */ |
151 | #define TXX9_SIBGR_BCLK_MASK 0x00000300 |
152 | #define TXX9_SIBGR_BCLK_T0 0x00000000 |
153 | #define TXX9_SIBGR_BCLK_T2 0x00000100 |
154 | #define TXX9_SIBGR_BCLK_T4 0x00000200 |
155 | #define TXX9_SIBGR_BCLK_T6 0x00000300 |
156 | #define TXX9_SIBGR_BRD_MASK 0x000000ff |
157 | |
158 | static inline unsigned int sio_in(struct uart_port *up, int offset) |
159 | { |
160 | switch (up->iotype) { |
161 | default: |
162 | return __raw_readl(addr: up->membase + offset); |
163 | case UPIO_PORT: |
164 | return inl(port: up->iobase + offset); |
165 | } |
166 | } |
167 | |
168 | static inline void |
169 | sio_out(struct uart_port *up, int offset, int value) |
170 | { |
171 | switch (up->iotype) { |
172 | default: |
173 | __raw_writel(val: value, addr: up->membase + offset); |
174 | break; |
175 | case UPIO_PORT: |
176 | outl(value, port: up->iobase + offset); |
177 | break; |
178 | } |
179 | } |
180 | |
181 | static inline void |
182 | sio_mask(struct uart_port *up, int offset, unsigned int value) |
183 | { |
184 | sio_out(up, offset, value: sio_in(up, offset) & ~value); |
185 | } |
186 | static inline void |
187 | sio_set(struct uart_port *up, int offset, unsigned int value) |
188 | { |
189 | sio_out(up, offset, value: sio_in(up, offset) | value); |
190 | } |
191 | |
192 | static inline void |
193 | sio_quot_set(struct uart_port *up, int quot) |
194 | { |
195 | quot >>= 1; |
196 | if (quot < 256) |
197 | sio_out(up, TXX9_SIBGR, value: quot | TXX9_SIBGR_BCLK_T0); |
198 | else if (quot < (256 << 2)) |
199 | sio_out(up, TXX9_SIBGR, value: (quot >> 2) | TXX9_SIBGR_BCLK_T2); |
200 | else if (quot < (256 << 4)) |
201 | sio_out(up, TXX9_SIBGR, value: (quot >> 4) | TXX9_SIBGR_BCLK_T4); |
202 | else if (quot < (256 << 6)) |
203 | sio_out(up, TXX9_SIBGR, value: (quot >> 6) | TXX9_SIBGR_BCLK_T6); |
204 | else |
205 | sio_out(up, TXX9_SIBGR, value: 0xff | TXX9_SIBGR_BCLK_T6); |
206 | } |
207 | |
208 | static void serial_txx9_stop_tx(struct uart_port *up) |
209 | { |
210 | sio_mask(up, TXX9_SIDICR, TXX9_SIDICR_TIE); |
211 | } |
212 | |
213 | static void serial_txx9_start_tx(struct uart_port *up) |
214 | { |
215 | sio_set(up, TXX9_SIDICR, TXX9_SIDICR_TIE); |
216 | } |
217 | |
218 | static void serial_txx9_stop_rx(struct uart_port *up) |
219 | { |
220 | up->read_status_mask &= ~TXX9_SIDISR_RDIS; |
221 | } |
222 | |
223 | static void serial_txx9_initialize(struct uart_port *up) |
224 | { |
225 | unsigned int tmout = 10000; |
226 | |
227 | sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST); |
228 | /* TX4925 BUG WORKAROUND. Accessing SIOC register |
229 | * immediately after soft reset causes bus error. */ |
230 | udelay(1); |
231 | while ((sio_in(up, TXX9_SIFCR) & TXX9_SIFCR_SWRST) && --tmout) |
232 | udelay(1); |
233 | /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */ |
234 | sio_set(up, TXX9_SIFCR, |
235 | TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1); |
236 | /* initial settings */ |
237 | sio_out(up, TXX9_SILCR, |
238 | TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT | |
239 | ((up->flags & UPF_TXX9_USE_SCLK) ? |
240 | TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG)); |
241 | sio_quot_set(up, quot: uart_get_divisor(port: up, baud: 9600)); |
242 | sio_out(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */); |
243 | sio_out(up, TXX9_SIDICR, value: 0); |
244 | } |
245 | |
246 | static inline void |
247 | receive_chars(struct uart_port *up, unsigned int *status) |
248 | { |
249 | unsigned int disr = *status; |
250 | int max_count = 256; |
251 | unsigned int next_ignore_status_mask; |
252 | u8 ch, flag; |
253 | |
254 | do { |
255 | ch = sio_in(up, TXX9_SIRFIFO); |
256 | flag = TTY_NORMAL; |
257 | up->icount.rx++; |
258 | |
259 | /* mask out RFDN_MASK bit added by previous overrun */ |
260 | next_ignore_status_mask = |
261 | up->ignore_status_mask & ~TXX9_SIDISR_RFDN_MASK; |
262 | if (unlikely(disr & (TXX9_SIDISR_UBRK | TXX9_SIDISR_UPER | |
263 | TXX9_SIDISR_UFER | TXX9_SIDISR_UOER))) { |
264 | /* |
265 | * For statistics only |
266 | */ |
267 | if (disr & TXX9_SIDISR_UBRK) { |
268 | disr &= ~(TXX9_SIDISR_UFER | TXX9_SIDISR_UPER); |
269 | up->icount.brk++; |
270 | /* |
271 | * We do the SysRQ and SAK checking |
272 | * here because otherwise the break |
273 | * may get masked by ignore_status_mask |
274 | * or read_status_mask. |
275 | */ |
276 | if (uart_handle_break(port: up)) |
277 | goto ignore_char; |
278 | } else if (disr & TXX9_SIDISR_UPER) |
279 | up->icount.parity++; |
280 | else if (disr & TXX9_SIDISR_UFER) |
281 | up->icount.frame++; |
282 | if (disr & TXX9_SIDISR_UOER) { |
283 | up->icount.overrun++; |
284 | /* |
285 | * The receiver read buffer still hold |
286 | * a char which caused overrun. |
287 | * Ignore next char by adding RFDN_MASK |
288 | * to ignore_status_mask temporarily. |
289 | */ |
290 | next_ignore_status_mask |= |
291 | TXX9_SIDISR_RFDN_MASK; |
292 | } |
293 | |
294 | /* |
295 | * Mask off conditions which should be ingored. |
296 | */ |
297 | disr &= up->read_status_mask; |
298 | |
299 | if (disr & TXX9_SIDISR_UBRK) { |
300 | flag = TTY_BREAK; |
301 | } else if (disr & TXX9_SIDISR_UPER) |
302 | flag = TTY_PARITY; |
303 | else if (disr & TXX9_SIDISR_UFER) |
304 | flag = TTY_FRAME; |
305 | } |
306 | if (uart_handle_sysrq_char(port: up, ch)) |
307 | goto ignore_char; |
308 | |
309 | uart_insert_char(port: up, status: disr, TXX9_SIDISR_UOER, ch, flag); |
310 | |
311 | ignore_char: |
312 | up->ignore_status_mask = next_ignore_status_mask; |
313 | disr = sio_in(up, TXX9_SIDISR); |
314 | } while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0)); |
315 | |
316 | tty_flip_buffer_push(port: &up->state->port); |
317 | |
318 | *status = disr; |
319 | } |
320 | |
321 | static inline void transmit_chars(struct uart_port *up) |
322 | { |
323 | u8 ch; |
324 | |
325 | uart_port_tx_limited(up, ch, TXX9_SIO_TX_FIFO, |
326 | true, |
327 | sio_out(up, TXX9_SITFIFO, ch), |
328 | ({})); |
329 | } |
330 | |
331 | static irqreturn_t serial_txx9_interrupt(int irq, void *dev_id) |
332 | { |
333 | int pass_counter = 0; |
334 | struct uart_port *up = dev_id; |
335 | unsigned int status; |
336 | |
337 | while (1) { |
338 | uart_port_lock(up); |
339 | status = sio_in(up, TXX9_SIDISR); |
340 | if (!(sio_in(up, TXX9_SIDICR) & TXX9_SIDICR_TIE)) |
341 | status &= ~TXX9_SIDISR_TDIS; |
342 | if (!(status & (TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS | |
343 | TXX9_SIDISR_TOUT))) { |
344 | uart_port_unlock(up); |
345 | break; |
346 | } |
347 | |
348 | if (status & TXX9_SIDISR_RDIS) |
349 | receive_chars(up, status: &status); |
350 | if (status & TXX9_SIDISR_TDIS) |
351 | transmit_chars(up); |
352 | /* Clear TX/RX Int. Status */ |
353 | sio_mask(up, TXX9_SIDISR, |
354 | TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS | |
355 | TXX9_SIDISR_TOUT); |
356 | uart_port_unlock(up); |
357 | |
358 | if (pass_counter++ > PASS_LIMIT) |
359 | break; |
360 | } |
361 | |
362 | return pass_counter ? IRQ_HANDLED : IRQ_NONE; |
363 | } |
364 | |
365 | static unsigned int serial_txx9_tx_empty(struct uart_port *up) |
366 | { |
367 | unsigned long flags; |
368 | unsigned int ret; |
369 | |
370 | uart_port_lock_irqsave(up, flags: &flags); |
371 | ret = (sio_in(up, TXX9_SICISR) & TXX9_SICISR_TXALS) ? TIOCSER_TEMT : 0; |
372 | uart_port_unlock_irqrestore(up, flags); |
373 | |
374 | return ret; |
375 | } |
376 | |
377 | static unsigned int serial_txx9_get_mctrl(struct uart_port *up) |
378 | { |
379 | unsigned int ret; |
380 | |
381 | /* no modem control lines */ |
382 | ret = TIOCM_CAR | TIOCM_DSR; |
383 | ret |= (sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS; |
384 | ret |= (sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS; |
385 | |
386 | return ret; |
387 | } |
388 | |
389 | static void serial_txx9_set_mctrl(struct uart_port *up, unsigned int mctrl) |
390 | { |
391 | |
392 | if (mctrl & TIOCM_RTS) |
393 | sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSSC); |
394 | else |
395 | sio_set(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSSC); |
396 | } |
397 | |
398 | static void serial_txx9_break_ctl(struct uart_port *up, int break_state) |
399 | { |
400 | unsigned long flags; |
401 | |
402 | uart_port_lock_irqsave(up, flags: &flags); |
403 | if (break_state == -1) |
404 | sio_set(up, TXX9_SIFLCR, TXX9_SIFLCR_TBRK); |
405 | else |
406 | sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_TBRK); |
407 | uart_port_unlock_irqrestore(up, flags); |
408 | } |
409 | |
410 | #if defined(CONFIG_SERIAL_TXX9_CONSOLE) || defined(CONFIG_CONSOLE_POLL) |
411 | /* |
412 | * Wait for transmitter & holding register to empty |
413 | */ |
414 | static void wait_for_xmitr(struct uart_port *up) |
415 | { |
416 | unsigned int tmout = 10000; |
417 | |
418 | /* Wait up to 10ms for the character(s) to be sent. */ |
419 | while (--tmout && |
420 | !(sio_in(up, TXX9_SICISR) & TXX9_SICISR_TXALS)) |
421 | udelay(1); |
422 | |
423 | /* Wait up to 1s for flow control if necessary */ |
424 | if (up->flags & UPF_CONS_FLOW) { |
425 | tmout = 1000000; |
426 | while (--tmout && |
427 | (sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS)) |
428 | udelay(1); |
429 | } |
430 | } |
431 | #endif |
432 | |
433 | #ifdef CONFIG_CONSOLE_POLL |
434 | /* |
435 | * Console polling routines for writing and reading from the uart while |
436 | * in an interrupt or debug context. |
437 | */ |
438 | |
439 | static int serial_txx9_get_poll_char(struct uart_port *up) |
440 | { |
441 | unsigned int ier; |
442 | unsigned char c; |
443 | |
444 | /* |
445 | * First save the IER then disable the interrupts |
446 | */ |
447 | ier = sio_in(up, TXX9_SIDICR); |
448 | sio_out(up, TXX9_SIDICR, value: 0); |
449 | |
450 | while (sio_in(up, TXX9_SIDISR) & TXX9_SIDISR_UVALID) |
451 | ; |
452 | |
453 | c = sio_in(up, TXX9_SIRFIFO); |
454 | |
455 | /* |
456 | * Finally, clear RX interrupt status |
457 | * and restore the IER |
458 | */ |
459 | sio_mask(up, TXX9_SIDISR, TXX9_SIDISR_RDIS); |
460 | sio_out(up, TXX9_SIDICR, value: ier); |
461 | return c; |
462 | } |
463 | |
464 | |
465 | static void serial_txx9_put_poll_char(struct uart_port *up, unsigned char c) |
466 | { |
467 | unsigned int ier; |
468 | |
469 | /* |
470 | * First save the IER then disable the interrupts |
471 | */ |
472 | ier = sio_in(up, TXX9_SIDICR); |
473 | sio_out(up, TXX9_SIDICR, value: 0); |
474 | |
475 | wait_for_xmitr(up); |
476 | /* |
477 | * Send the character out. |
478 | */ |
479 | sio_out(up, TXX9_SITFIFO, value: c); |
480 | |
481 | /* |
482 | * Finally, wait for transmitter to become empty |
483 | * and restore the IER |
484 | */ |
485 | wait_for_xmitr(up); |
486 | sio_out(up, TXX9_SIDICR, value: ier); |
487 | } |
488 | |
489 | #endif /* CONFIG_CONSOLE_POLL */ |
490 | |
491 | static int serial_txx9_startup(struct uart_port *up) |
492 | { |
493 | unsigned long flags; |
494 | int retval; |
495 | |
496 | /* |
497 | * Clear the FIFO buffers and disable them. |
498 | * (they will be reenabled in set_termios()) |
499 | */ |
500 | sio_set(up, TXX9_SIFCR, |
501 | TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | TXX9_SIFCR_FRSTE); |
502 | /* clear reset */ |
503 | sio_mask(up, TXX9_SIFCR, |
504 | TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | TXX9_SIFCR_FRSTE); |
505 | sio_out(up, TXX9_SIDICR, value: 0); |
506 | |
507 | /* |
508 | * Clear the interrupt registers. |
509 | */ |
510 | sio_out(up, TXX9_SIDISR, value: 0); |
511 | |
512 | retval = request_irq(irq: up->irq, handler: serial_txx9_interrupt, |
513 | IRQF_SHARED, name: "serial_txx9" , dev: up); |
514 | if (retval) |
515 | return retval; |
516 | |
517 | /* |
518 | * Now, initialize the UART |
519 | */ |
520 | uart_port_lock_irqsave(up, flags: &flags); |
521 | serial_txx9_set_mctrl(up, mctrl: up->mctrl); |
522 | uart_port_unlock_irqrestore(up, flags); |
523 | |
524 | /* Enable RX/TX */ |
525 | sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_RSDE | TXX9_SIFLCR_TSDE); |
526 | |
527 | /* |
528 | * Finally, enable interrupts. |
529 | */ |
530 | sio_set(up, TXX9_SIDICR, TXX9_SIDICR_RIE); |
531 | |
532 | return 0; |
533 | } |
534 | |
535 | static void serial_txx9_shutdown(struct uart_port *up) |
536 | { |
537 | unsigned long flags; |
538 | |
539 | /* |
540 | * Disable interrupts from this port |
541 | */ |
542 | sio_out(up, TXX9_SIDICR, value: 0); /* disable all intrs */ |
543 | |
544 | uart_port_lock_irqsave(up, flags: &flags); |
545 | serial_txx9_set_mctrl(up, mctrl: up->mctrl); |
546 | uart_port_unlock_irqrestore(up, flags); |
547 | |
548 | /* |
549 | * Disable break condition |
550 | */ |
551 | sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_TBRK); |
552 | |
553 | #ifdef CONFIG_SERIAL_TXX9_CONSOLE |
554 | if (up->cons && up->line == up->cons->index) { |
555 | free_irq(up->irq, up); |
556 | return; |
557 | } |
558 | #endif |
559 | /* reset FIFOs */ |
560 | sio_set(up, TXX9_SIFCR, |
561 | TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | TXX9_SIFCR_FRSTE); |
562 | /* clear reset */ |
563 | sio_mask(up, TXX9_SIFCR, |
564 | TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | TXX9_SIFCR_FRSTE); |
565 | |
566 | /* Disable RX/TX */ |
567 | sio_set(up, TXX9_SIFLCR, TXX9_SIFLCR_RSDE | TXX9_SIFLCR_TSDE); |
568 | |
569 | free_irq(up->irq, up); |
570 | } |
571 | |
572 | static void |
573 | serial_txx9_set_termios(struct uart_port *up, struct ktermios *termios, |
574 | const struct ktermios *old) |
575 | { |
576 | unsigned int cval, fcr = 0; |
577 | unsigned long flags; |
578 | unsigned int baud, quot; |
579 | |
580 | /* |
581 | * We don't support modem control lines. |
582 | */ |
583 | termios->c_cflag &= ~(HUPCL | CMSPAR); |
584 | termios->c_cflag |= CLOCAL; |
585 | |
586 | cval = sio_in(up, TXX9_SILCR); |
587 | /* byte size and parity */ |
588 | cval &= ~TXX9_SILCR_UMODE_MASK; |
589 | switch (termios->c_cflag & CSIZE) { |
590 | case CS7: |
591 | cval |= TXX9_SILCR_UMODE_7BIT; |
592 | break; |
593 | default: |
594 | case CS5: /* not supported */ |
595 | case CS6: /* not supported */ |
596 | case CS8: |
597 | cval |= TXX9_SILCR_UMODE_8BIT; |
598 | termios->c_cflag &= ~CSIZE; |
599 | termios->c_cflag |= CS8; |
600 | break; |
601 | } |
602 | |
603 | cval &= ~TXX9_SILCR_USBL_MASK; |
604 | if (termios->c_cflag & CSTOPB) |
605 | cval |= TXX9_SILCR_USBL_2BIT; |
606 | else |
607 | cval |= TXX9_SILCR_USBL_1BIT; |
608 | cval &= ~(TXX9_SILCR_UPEN | TXX9_SILCR_UEPS); |
609 | if (termios->c_cflag & PARENB) |
610 | cval |= TXX9_SILCR_UPEN; |
611 | if (!(termios->c_cflag & PARODD)) |
612 | cval |= TXX9_SILCR_UEPS; |
613 | |
614 | /* |
615 | * Ask the core to calculate the divisor for us. |
616 | */ |
617 | baud = uart_get_baud_rate(port: up, termios, old, min: 0, max: up->uartclk/16/2); |
618 | quot = uart_get_divisor(port: up, baud); |
619 | |
620 | /* Set up FIFOs */ |
621 | /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */ |
622 | fcr = TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1; |
623 | |
624 | /* |
625 | * Ok, we're now changing the port state. Do it with |
626 | * interrupts disabled. |
627 | */ |
628 | uart_port_lock_irqsave(up, flags: &flags); |
629 | |
630 | /* |
631 | * Update the per-port timeout. |
632 | */ |
633 | uart_update_timeout(port: up, cflag: termios->c_cflag, baud); |
634 | |
635 | up->read_status_mask = TXX9_SIDISR_UOER | |
636 | TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS; |
637 | if (termios->c_iflag & INPCK) |
638 | up->read_status_mask |= TXX9_SIDISR_UFER | TXX9_SIDISR_UPER; |
639 | if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK)) |
640 | up->read_status_mask |= TXX9_SIDISR_UBRK; |
641 | |
642 | /* |
643 | * Characteres to ignore |
644 | */ |
645 | up->ignore_status_mask = 0; |
646 | if (termios->c_iflag & IGNPAR) |
647 | up->ignore_status_mask |= TXX9_SIDISR_UPER | TXX9_SIDISR_UFER; |
648 | if (termios->c_iflag & IGNBRK) { |
649 | up->ignore_status_mask |= TXX9_SIDISR_UBRK; |
650 | /* |
651 | * If we're ignoring parity and break indicators, |
652 | * ignore overruns too (for real raw support). |
653 | */ |
654 | if (termios->c_iflag & IGNPAR) |
655 | up->ignore_status_mask |= TXX9_SIDISR_UOER; |
656 | } |
657 | |
658 | /* |
659 | * ignore all characters if CREAD is not set |
660 | */ |
661 | if ((termios->c_cflag & CREAD) == 0) |
662 | up->ignore_status_mask |= TXX9_SIDISR_RDIS; |
663 | |
664 | /* CTS flow control flag */ |
665 | if ((termios->c_cflag & CRTSCTS) && |
666 | (up->flags & UPF_TXX9_HAVE_CTS_LINE)) { |
667 | sio_set(up, TXX9_SIFLCR, |
668 | TXX9_SIFLCR_RCS | TXX9_SIFLCR_TES); |
669 | } else { |
670 | sio_mask(up, TXX9_SIFLCR, |
671 | TXX9_SIFLCR_RCS | TXX9_SIFLCR_TES); |
672 | } |
673 | |
674 | sio_out(up, TXX9_SILCR, value: cval); |
675 | sio_quot_set(up, quot); |
676 | sio_out(up, TXX9_SIFCR, value: fcr); |
677 | |
678 | serial_txx9_set_mctrl(up, mctrl: up->mctrl); |
679 | uart_port_unlock_irqrestore(up, flags); |
680 | } |
681 | |
682 | static void |
683 | serial_txx9_pm(struct uart_port *port, unsigned int state, |
684 | unsigned int oldstate) |
685 | { |
686 | /* |
687 | * If oldstate was -1 this is called from |
688 | * uart_configure_port(). In this case do not initialize the |
689 | * port now, because the port was already initialized (for |
690 | * non-console port) or should not be initialized here (for |
691 | * console port). If we initialized the port here we lose |
692 | * serial console settings. |
693 | */ |
694 | if (state == 0 && oldstate != -1) |
695 | serial_txx9_initialize(up: port); |
696 | } |
697 | |
698 | static int serial_txx9_request_resource(struct uart_port *up) |
699 | { |
700 | unsigned int size = TXX9_REGION_SIZE; |
701 | int ret = 0; |
702 | |
703 | switch (up->iotype) { |
704 | default: |
705 | if (!up->mapbase) |
706 | break; |
707 | |
708 | if (!request_mem_region(up->mapbase, size, "serial_txx9" )) { |
709 | ret = -EBUSY; |
710 | break; |
711 | } |
712 | |
713 | if (up->flags & UPF_IOREMAP) { |
714 | up->membase = ioremap(offset: up->mapbase, size); |
715 | if (!up->membase) { |
716 | release_mem_region(up->mapbase, size); |
717 | ret = -ENOMEM; |
718 | } |
719 | } |
720 | break; |
721 | |
722 | case UPIO_PORT: |
723 | if (!request_region(up->iobase, size, "serial_txx9" )) |
724 | ret = -EBUSY; |
725 | break; |
726 | } |
727 | return ret; |
728 | } |
729 | |
730 | static void serial_txx9_release_resource(struct uart_port *up) |
731 | { |
732 | unsigned int size = TXX9_REGION_SIZE; |
733 | |
734 | switch (up->iotype) { |
735 | default: |
736 | if (!up->mapbase) |
737 | break; |
738 | |
739 | if (up->flags & UPF_IOREMAP) { |
740 | iounmap(addr: up->membase); |
741 | up->membase = NULL; |
742 | } |
743 | |
744 | release_mem_region(up->mapbase, size); |
745 | break; |
746 | |
747 | case UPIO_PORT: |
748 | release_region(up->iobase, size); |
749 | break; |
750 | } |
751 | } |
752 | |
753 | static void serial_txx9_release_port(struct uart_port *up) |
754 | { |
755 | serial_txx9_release_resource(up); |
756 | } |
757 | |
758 | static int serial_txx9_request_port(struct uart_port *up) |
759 | { |
760 | return serial_txx9_request_resource(up); |
761 | } |
762 | |
763 | static void serial_txx9_config_port(struct uart_port *up, int uflags) |
764 | { |
765 | int ret; |
766 | |
767 | /* |
768 | * Find the region that we can probe for. This in turn |
769 | * tells us whether we can probe for the type of port. |
770 | */ |
771 | ret = serial_txx9_request_resource(up); |
772 | if (ret < 0) |
773 | return; |
774 | up->type = PORT_TXX9; |
775 | up->fifosize = TXX9_SIO_TX_FIFO; |
776 | |
777 | #ifdef CONFIG_SERIAL_TXX9_CONSOLE |
778 | if (up->line == up->cons->index) |
779 | return; |
780 | #endif |
781 | serial_txx9_initialize(up); |
782 | } |
783 | |
784 | static const char * |
785 | serial_txx9_type(struct uart_port *port) |
786 | { |
787 | return "txx9" ; |
788 | } |
789 | |
790 | static const struct uart_ops serial_txx9_pops = { |
791 | .tx_empty = serial_txx9_tx_empty, |
792 | .set_mctrl = serial_txx9_set_mctrl, |
793 | .get_mctrl = serial_txx9_get_mctrl, |
794 | .stop_tx = serial_txx9_stop_tx, |
795 | .start_tx = serial_txx9_start_tx, |
796 | .stop_rx = serial_txx9_stop_rx, |
797 | .break_ctl = serial_txx9_break_ctl, |
798 | .startup = serial_txx9_startup, |
799 | .shutdown = serial_txx9_shutdown, |
800 | .set_termios = serial_txx9_set_termios, |
801 | .pm = serial_txx9_pm, |
802 | .type = serial_txx9_type, |
803 | .release_port = serial_txx9_release_port, |
804 | .request_port = serial_txx9_request_port, |
805 | .config_port = serial_txx9_config_port, |
806 | #ifdef CONFIG_CONSOLE_POLL |
807 | .poll_get_char = serial_txx9_get_poll_char, |
808 | .poll_put_char = serial_txx9_put_poll_char, |
809 | #endif |
810 | }; |
811 | |
812 | static struct uart_port serial_txx9_ports[UART_NR]; |
813 | |
814 | static void __init serial_txx9_register_ports(struct uart_driver *drv, |
815 | struct device *dev) |
816 | { |
817 | int i; |
818 | |
819 | for (i = 0; i < UART_NR; i++) { |
820 | struct uart_port *up = &serial_txx9_ports[i]; |
821 | |
822 | up->line = i; |
823 | up->ops = &serial_txx9_pops; |
824 | up->dev = dev; |
825 | if (up->iobase || up->mapbase) |
826 | uart_add_one_port(reg: drv, port: up); |
827 | } |
828 | } |
829 | |
830 | #ifdef CONFIG_SERIAL_TXX9_CONSOLE |
831 | |
832 | static void serial_txx9_console_putchar(struct uart_port *up, unsigned char ch) |
833 | { |
834 | wait_for_xmitr(up); |
835 | sio_out(up, TXX9_SITFIFO, ch); |
836 | } |
837 | |
838 | /* |
839 | * Print a string to the serial port trying not to disturb |
840 | * any possible real use of the port... |
841 | * |
842 | * The console_lock must be held when we get here. |
843 | */ |
844 | static void |
845 | serial_txx9_console_write(struct console *co, const char *s, unsigned int count) |
846 | { |
847 | struct uart_port *up = &serial_txx9_ports[co->index]; |
848 | unsigned int ier, flcr; |
849 | |
850 | /* |
851 | * First save the UER then disable the interrupts |
852 | */ |
853 | ier = sio_in(up, TXX9_SIDICR); |
854 | sio_out(up, TXX9_SIDICR, 0); |
855 | /* |
856 | * Disable flow-control if enabled (and unnecessary) |
857 | */ |
858 | flcr = sio_in(up, TXX9_SIFLCR); |
859 | if (!(up->flags & UPF_CONS_FLOW) && (flcr & TXX9_SIFLCR_TES)) |
860 | sio_out(up, TXX9_SIFLCR, flcr & ~TXX9_SIFLCR_TES); |
861 | |
862 | uart_console_write(up, s, count, serial_txx9_console_putchar); |
863 | |
864 | /* |
865 | * Finally, wait for transmitter to become empty |
866 | * and restore the IER |
867 | */ |
868 | wait_for_xmitr(up); |
869 | sio_out(up, TXX9_SIFLCR, flcr); |
870 | sio_out(up, TXX9_SIDICR, ier); |
871 | } |
872 | |
873 | static int __init serial_txx9_console_setup(struct console *co, char *options) |
874 | { |
875 | struct uart_port *up; |
876 | int baud = 9600; |
877 | int bits = 8; |
878 | int parity = 'n'; |
879 | int flow = 'n'; |
880 | |
881 | /* |
882 | * Check whether an invalid uart number has been specified, and |
883 | * if so, search for the first available port that does have |
884 | * console support. |
885 | */ |
886 | if (co->index >= UART_NR) |
887 | co->index = 0; |
888 | up = &serial_txx9_ports[co->index]; |
889 | if (!up->ops) |
890 | return -ENODEV; |
891 | |
892 | serial_txx9_initialize(up); |
893 | |
894 | if (options) |
895 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
896 | |
897 | return uart_set_options(up, co, baud, parity, bits, flow); |
898 | } |
899 | |
900 | static struct uart_driver serial_txx9_reg; |
901 | static struct console serial_txx9_console = { |
902 | .name = TXX9_TTY_NAME, |
903 | .write = serial_txx9_console_write, |
904 | .device = uart_console_device, |
905 | .setup = serial_txx9_console_setup, |
906 | .flags = CON_PRINTBUFFER, |
907 | .index = -1, |
908 | .data = &serial_txx9_reg, |
909 | }; |
910 | |
911 | static int __init serial_txx9_console_init(void) |
912 | { |
913 | register_console(&serial_txx9_console); |
914 | return 0; |
915 | } |
916 | console_initcall(serial_txx9_console_init); |
917 | |
918 | #define SERIAL_TXX9_CONSOLE &serial_txx9_console |
919 | #else |
920 | #define SERIAL_TXX9_CONSOLE NULL |
921 | #endif |
922 | |
923 | static struct uart_driver serial_txx9_reg = { |
924 | .owner = THIS_MODULE, |
925 | .driver_name = "serial_txx9" , |
926 | .dev_name = TXX9_TTY_NAME, |
927 | .major = TXX9_TTY_MAJOR, |
928 | .minor = TXX9_TTY_MINOR_START, |
929 | .nr = UART_NR, |
930 | .cons = SERIAL_TXX9_CONSOLE, |
931 | }; |
932 | |
933 | int __init early_serial_txx9_setup(struct uart_port *port) |
934 | { |
935 | if (port->line >= ARRAY_SIZE(serial_txx9_ports)) |
936 | return -ENODEV; |
937 | |
938 | serial_txx9_ports[port->line] = *port; |
939 | serial_txx9_ports[port->line].ops = &serial_txx9_pops; |
940 | serial_txx9_ports[port->line].flags |= |
941 | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT; |
942 | return 0; |
943 | } |
944 | |
945 | static DEFINE_MUTEX(serial_txx9_mutex); |
946 | |
947 | /** |
948 | * serial_txx9_register_port - register a serial port |
949 | * @port: serial port template |
950 | * |
951 | * Configure the serial port specified by the request. |
952 | * |
953 | * The port is then probed and if necessary the IRQ is autodetected |
954 | * If this fails an error is returned. |
955 | * |
956 | * On success the port is ready to use and the line number is returned. |
957 | */ |
958 | static int serial_txx9_register_port(struct uart_port *port) |
959 | { |
960 | int i; |
961 | struct uart_port *uart; |
962 | int ret = -ENOSPC; |
963 | |
964 | mutex_lock(&serial_txx9_mutex); |
965 | for (i = 0; i < UART_NR; i++) { |
966 | uart = &serial_txx9_ports[i]; |
967 | if (uart_match_port(port1: uart, port2: port)) { |
968 | uart_remove_one_port(reg: &serial_txx9_reg, port: uart); |
969 | break; |
970 | } |
971 | } |
972 | if (i == UART_NR) { |
973 | /* Find unused port */ |
974 | for (i = 0; i < UART_NR; i++) { |
975 | uart = &serial_txx9_ports[i]; |
976 | if (!(uart->iobase || uart->mapbase)) |
977 | break; |
978 | } |
979 | } |
980 | if (i < UART_NR) { |
981 | uart->iobase = port->iobase; |
982 | uart->membase = port->membase; |
983 | uart->irq = port->irq; |
984 | uart->uartclk = port->uartclk; |
985 | uart->iotype = port->iotype; |
986 | uart->flags = port->flags |
987 | | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT; |
988 | uart->mapbase = port->mapbase; |
989 | if (port->dev) |
990 | uart->dev = port->dev; |
991 | ret = uart_add_one_port(reg: &serial_txx9_reg, port: uart); |
992 | if (ret == 0) |
993 | ret = uart->line; |
994 | } |
995 | mutex_unlock(lock: &serial_txx9_mutex); |
996 | return ret; |
997 | } |
998 | |
999 | /** |
1000 | * serial_txx9_unregister_port - remove a txx9 serial port at runtime |
1001 | * @line: serial line number |
1002 | * |
1003 | * Remove one serial port. This may not be called from interrupt |
1004 | * context. We hand the port back to the our control. |
1005 | */ |
1006 | static void serial_txx9_unregister_port(int line) |
1007 | { |
1008 | struct uart_port *uart = &serial_txx9_ports[line]; |
1009 | |
1010 | mutex_lock(&serial_txx9_mutex); |
1011 | uart_remove_one_port(reg: &serial_txx9_reg, port: uart); |
1012 | uart->flags = 0; |
1013 | uart->type = PORT_UNKNOWN; |
1014 | uart->iobase = 0; |
1015 | uart->mapbase = 0; |
1016 | uart->membase = NULL; |
1017 | uart->dev = NULL; |
1018 | mutex_unlock(lock: &serial_txx9_mutex); |
1019 | } |
1020 | |
1021 | /* |
1022 | * Register a set of serial devices attached to a platform device. |
1023 | */ |
1024 | static int serial_txx9_probe(struct platform_device *dev) |
1025 | { |
1026 | struct uart_port *p = dev_get_platdata(dev: &dev->dev); |
1027 | struct uart_port port; |
1028 | int ret, i; |
1029 | |
1030 | memset(&port, 0, sizeof(struct uart_port)); |
1031 | for (i = 0; p && p->uartclk != 0; p++, i++) { |
1032 | port.iobase = p->iobase; |
1033 | port.membase = p->membase; |
1034 | port.irq = p->irq; |
1035 | port.uartclk = p->uartclk; |
1036 | port.iotype = p->iotype; |
1037 | port.flags = p->flags; |
1038 | port.mapbase = p->mapbase; |
1039 | port.dev = &dev->dev; |
1040 | port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_TXX9_CONSOLE); |
1041 | ret = serial_txx9_register_port(port: &port); |
1042 | if (ret < 0) { |
1043 | dev_err(&dev->dev, "unable to register port at index %d " |
1044 | "(IO%lx MEM%llx IRQ%d): %d\n" , i, |
1045 | p->iobase, (unsigned long long)p->mapbase, |
1046 | p->irq, ret); |
1047 | } |
1048 | } |
1049 | return 0; |
1050 | } |
1051 | |
1052 | /* |
1053 | * Remove serial ports registered against a platform device. |
1054 | */ |
1055 | static int serial_txx9_remove(struct platform_device *dev) |
1056 | { |
1057 | int i; |
1058 | |
1059 | for (i = 0; i < UART_NR; i++) { |
1060 | struct uart_port *up = &serial_txx9_ports[i]; |
1061 | |
1062 | if (up->dev == &dev->dev) |
1063 | serial_txx9_unregister_port(line: i); |
1064 | } |
1065 | return 0; |
1066 | } |
1067 | |
1068 | #ifdef CONFIG_PM |
1069 | static int serial_txx9_suspend(struct platform_device *dev, pm_message_t state) |
1070 | { |
1071 | int i; |
1072 | |
1073 | for (i = 0; i < UART_NR; i++) { |
1074 | struct uart_port *up = &serial_txx9_ports[i]; |
1075 | |
1076 | if (up->type != PORT_UNKNOWN && up->dev == &dev->dev) |
1077 | uart_suspend_port(reg: &serial_txx9_reg, port: up); |
1078 | } |
1079 | |
1080 | return 0; |
1081 | } |
1082 | |
1083 | static int serial_txx9_resume(struct platform_device *dev) |
1084 | { |
1085 | int i; |
1086 | |
1087 | for (i = 0; i < UART_NR; i++) { |
1088 | struct uart_port *up = &serial_txx9_ports[i]; |
1089 | |
1090 | if (up->type != PORT_UNKNOWN && up->dev == &dev->dev) |
1091 | uart_resume_port(reg: &serial_txx9_reg, port: up); |
1092 | } |
1093 | |
1094 | return 0; |
1095 | } |
1096 | #endif |
1097 | |
1098 | static struct platform_driver serial_txx9_plat_driver = { |
1099 | .probe = serial_txx9_probe, |
1100 | .remove = serial_txx9_remove, |
1101 | #ifdef CONFIG_PM |
1102 | .suspend = serial_txx9_suspend, |
1103 | .resume = serial_txx9_resume, |
1104 | #endif |
1105 | .driver = { |
1106 | .name = "serial_txx9" , |
1107 | }, |
1108 | }; |
1109 | |
1110 | #ifdef ENABLE_SERIAL_TXX9_PCI |
1111 | /* |
1112 | * Probe one serial board. Unfortunately, there is no rhyme nor reason |
1113 | * to the arrangement of serial ports on a PCI card. |
1114 | */ |
1115 | static int |
1116 | pciserial_txx9_init_one(struct pci_dev *dev, const struct pci_device_id *ent) |
1117 | { |
1118 | struct uart_port port; |
1119 | int line; |
1120 | int rc; |
1121 | |
1122 | rc = pci_enable_device(dev); |
1123 | if (rc) |
1124 | return rc; |
1125 | |
1126 | memset(&port, 0, sizeof(port)); |
1127 | port.ops = &serial_txx9_pops; |
1128 | port.flags |= UPF_TXX9_HAVE_CTS_LINE; |
1129 | port.uartclk = 66670000; |
1130 | port.irq = dev->irq; |
1131 | port.iotype = UPIO_PORT; |
1132 | port.iobase = pci_resource_start(dev, 1); |
1133 | port.dev = &dev->dev; |
1134 | line = serial_txx9_register_port(port: &port); |
1135 | if (line < 0) { |
1136 | printk(KERN_WARNING "Couldn't register serial port %s: %d\n" , pci_name(dev), line); |
1137 | pci_disable_device(dev); |
1138 | return line; |
1139 | } |
1140 | pci_set_drvdata(pdev: dev, data: &serial_txx9_ports[line]); |
1141 | |
1142 | return 0; |
1143 | } |
1144 | |
1145 | static void pciserial_txx9_remove_one(struct pci_dev *dev) |
1146 | { |
1147 | struct uart_port *up = pci_get_drvdata(pdev: dev); |
1148 | |
1149 | if (up) { |
1150 | serial_txx9_unregister_port(line: up->line); |
1151 | pci_disable_device(dev); |
1152 | } |
1153 | } |
1154 | |
1155 | #ifdef CONFIG_PM |
1156 | static int pciserial_txx9_suspend_one(struct pci_dev *dev, pm_message_t state) |
1157 | { |
1158 | struct uart_port *up = pci_get_drvdata(pdev: dev); |
1159 | |
1160 | if (up) |
1161 | uart_suspend_port(reg: &serial_txx9_reg, port: up); |
1162 | pci_save_state(dev); |
1163 | pci_set_power_state(dev, state: pci_choose_state(dev, state)); |
1164 | return 0; |
1165 | } |
1166 | |
1167 | static int pciserial_txx9_resume_one(struct pci_dev *dev) |
1168 | { |
1169 | struct uart_port *up = pci_get_drvdata(pdev: dev); |
1170 | |
1171 | pci_set_power_state(dev, PCI_D0); |
1172 | pci_restore_state(dev); |
1173 | if (up) |
1174 | uart_resume_port(reg: &serial_txx9_reg, port: up); |
1175 | return 0; |
1176 | } |
1177 | #endif |
1178 | |
1179 | static const struct pci_device_id serial_txx9_pci_tbl[] = { |
1180 | { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC) }, |
1181 | { 0, } |
1182 | }; |
1183 | |
1184 | static struct pci_driver serial_txx9_pci_driver = { |
1185 | .name = "serial_txx9" , |
1186 | .probe = pciserial_txx9_init_one, |
1187 | .remove = pciserial_txx9_remove_one, |
1188 | #ifdef CONFIG_PM |
1189 | .suspend = pciserial_txx9_suspend_one, |
1190 | .resume = pciserial_txx9_resume_one, |
1191 | #endif |
1192 | .id_table = serial_txx9_pci_tbl, |
1193 | }; |
1194 | |
1195 | MODULE_DEVICE_TABLE(pci, serial_txx9_pci_tbl); |
1196 | #endif /* ENABLE_SERIAL_TXX9_PCI */ |
1197 | |
1198 | static struct platform_device *serial_txx9_plat_devs; |
1199 | |
1200 | static int __init serial_txx9_init(void) |
1201 | { |
1202 | int ret; |
1203 | |
1204 | ret = uart_register_driver(uart: &serial_txx9_reg); |
1205 | if (ret) |
1206 | goto out; |
1207 | |
1208 | serial_txx9_plat_devs = platform_device_alloc(name: "serial_txx9" , id: -1); |
1209 | if (!serial_txx9_plat_devs) { |
1210 | ret = -ENOMEM; |
1211 | goto unreg_uart_drv; |
1212 | } |
1213 | |
1214 | ret = platform_device_add(pdev: serial_txx9_plat_devs); |
1215 | if (ret) |
1216 | goto put_dev; |
1217 | |
1218 | serial_txx9_register_ports(drv: &serial_txx9_reg, |
1219 | dev: &serial_txx9_plat_devs->dev); |
1220 | |
1221 | ret = platform_driver_register(&serial_txx9_plat_driver); |
1222 | if (ret) |
1223 | goto del_dev; |
1224 | |
1225 | #ifdef ENABLE_SERIAL_TXX9_PCI |
1226 | ret = pci_register_driver(&serial_txx9_pci_driver); |
1227 | if (ret) { |
1228 | platform_driver_unregister(&serial_txx9_plat_driver); |
1229 | } |
1230 | #endif |
1231 | if (ret == 0) |
1232 | goto out; |
1233 | |
1234 | del_dev: |
1235 | platform_device_del(pdev: serial_txx9_plat_devs); |
1236 | put_dev: |
1237 | platform_device_put(pdev: serial_txx9_plat_devs); |
1238 | unreg_uart_drv: |
1239 | uart_unregister_driver(uart: &serial_txx9_reg); |
1240 | out: |
1241 | return ret; |
1242 | } |
1243 | |
1244 | static void __exit serial_txx9_exit(void) |
1245 | { |
1246 | int i; |
1247 | |
1248 | #ifdef ENABLE_SERIAL_TXX9_PCI |
1249 | pci_unregister_driver(dev: &serial_txx9_pci_driver); |
1250 | #endif |
1251 | platform_driver_unregister(&serial_txx9_plat_driver); |
1252 | platform_device_unregister(serial_txx9_plat_devs); |
1253 | for (i = 0; i < UART_NR; i++) { |
1254 | struct uart_port *up = &serial_txx9_ports[i]; |
1255 | if (up->iobase || up->mapbase) |
1256 | uart_remove_one_port(reg: &serial_txx9_reg, port: up); |
1257 | } |
1258 | |
1259 | uart_unregister_driver(uart: &serial_txx9_reg); |
1260 | } |
1261 | |
1262 | module_init(serial_txx9_init); |
1263 | module_exit(serial_txx9_exit); |
1264 | |
1265 | MODULE_LICENSE("GPL" ); |
1266 | MODULE_DESCRIPTION("TX39/49 serial driver" ); |
1267 | |
1268 | MODULE_ALIAS_CHARDEV_MAJOR(TXX9_TTY_MAJOR); |
1269 | |