blob: d257d38e37329a69f5089aaad1c060f8fc1db1c5 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Fintek F81232 USB to serial adaptor driver
4 *
5 * Copyright (C) 2012 Greg Kroah-Hartman (gregkh@linuxfoundation.org)
6 * Copyright (C) 2012 Linux Foundation
7 */
8
9#include <linux/kernel.h>
10#include <linux/errno.h>
11#include <linux/slab.h>
12#include <linux/tty.h>
13#include <linux/tty_driver.h>
14#include <linux/tty_flip.h>
15#include <linux/serial.h>
16#include <linux/module.h>
17#include <linux/moduleparam.h>
18#include <linux/mutex.h>
19#include <linux/uaccess.h>
20#include <linux/usb.h>
21#include <linux/usb/serial.h>
22#include <linux/serial_reg.h>
23
24static const struct usb_device_id id_table[] = {
25 { USB_DEVICE(0x1934, 0x0706) },
26 { } /* Terminating entry */
27};
28MODULE_DEVICE_TABLE(usb, id_table);
29
30/* Maximum baudrate for F81232 */
31#define F81232_MAX_BAUDRATE 1500000
32#define F81232_DEF_BAUDRATE 9600
33
34/* USB Control EP parameter */
35#define F81232_REGISTER_REQUEST 0xa0
36#define F81232_GET_REGISTER 0xc0
37#define F81232_SET_REGISTER 0x40
38
39#define SERIAL_BASE_ADDRESS 0x0120
40#define RECEIVE_BUFFER_REGISTER (0x00 + SERIAL_BASE_ADDRESS)
41#define INTERRUPT_ENABLE_REGISTER (0x01 + SERIAL_BASE_ADDRESS)
42#define FIFO_CONTROL_REGISTER (0x02 + SERIAL_BASE_ADDRESS)
43#define LINE_CONTROL_REGISTER (0x03 + SERIAL_BASE_ADDRESS)
44#define MODEM_CONTROL_REGISTER (0x04 + SERIAL_BASE_ADDRESS)
45#define LINE_STATUS_REGISTER (0x05 + SERIAL_BASE_ADDRESS)
46#define MODEM_STATUS_REGISTER (0x06 + SERIAL_BASE_ADDRESS)
47
48/*
49 * F81232 Clock registers (106h)
50 *
51 * Bit1-0: Clock source selector
52 * 00: 1.846MHz.
53 * 01: 18.46MHz.
54 * 10: 24MHz.
55 * 11: 14.77MHz.
56 */
57#define F81232_CLK_REGISTER 0x106
58#define F81232_CLK_1_846_MHZ 0
59#define F81232_CLK_18_46_MHZ BIT(0)
60#define F81232_CLK_24_MHZ BIT(1)
61#define F81232_CLK_14_77_MHZ (BIT(1) | BIT(0))
62#define F81232_CLK_MASK GENMASK(1, 0)
63
64struct f81232_private {
65 struct mutex lock;
66 u8 modem_control;
67 u8 modem_status;
68 u8 shadow_lcr;
69 speed_t baud_base;
70 struct work_struct lsr_work;
71 struct work_struct interrupt_work;
72 struct usb_serial_port *port;
73};
74
75static u32 const baudrate_table[] = { 115200, 921600, 1152000, 1500000 };
76static u8 const clock_table[] = { F81232_CLK_1_846_MHZ, F81232_CLK_14_77_MHZ,
77 F81232_CLK_18_46_MHZ, F81232_CLK_24_MHZ };
78
79static int calc_baud_divisor(speed_t baudrate, speed_t clockrate)
80{
81 return DIV_ROUND_CLOSEST(clockrate, baudrate);
82}
83
84static int f81232_get_register(struct usb_serial_port *port, u16 reg, u8 *val)
85{
86 int status;
87 u8 *tmp;
88 struct usb_device *dev = port->serial->dev;
89
90 tmp = kmalloc(sizeof(*val), GFP_KERNEL);
91 if (!tmp)
92 return -ENOMEM;
93
94 status = usb_control_msg(dev,
95 usb_rcvctrlpipe(dev, 0),
96 F81232_REGISTER_REQUEST,
97 F81232_GET_REGISTER,
98 reg,
99 0,
100 tmp,
101 sizeof(*val),
102 USB_CTRL_GET_TIMEOUT);
103 if (status != sizeof(*val)) {
104 dev_err(&port->dev, "%s failed status: %d\n", __func__, status);
105
106 if (status < 0)
107 status = usb_translate_errors(status);
108 else
109 status = -EIO;
110 } else {
111 status = 0;
112 *val = *tmp;
113 }
114
115 kfree(tmp);
116 return status;
117}
118
119static int f81232_set_register(struct usb_serial_port *port, u16 reg, u8 val)
120{
121 int status;
122 u8 *tmp;
123 struct usb_device *dev = port->serial->dev;
124
125 tmp = kmalloc(sizeof(val), GFP_KERNEL);
126 if (!tmp)
127 return -ENOMEM;
128
129 *tmp = val;
130
131 status = usb_control_msg(dev,
132 usb_sndctrlpipe(dev, 0),
133 F81232_REGISTER_REQUEST,
134 F81232_SET_REGISTER,
135 reg,
136 0,
137 tmp,
138 sizeof(val),
139 USB_CTRL_SET_TIMEOUT);
140 if (status != sizeof(val)) {
141 dev_err(&port->dev, "%s failed status: %d\n", __func__, status);
142
143 if (status < 0)
144 status = usb_translate_errors(status);
145 else
146 status = -EIO;
147 } else {
148 status = 0;
149 }
150
151 kfree(tmp);
152 return status;
153}
154
155static int f81232_set_mask_register(struct usb_serial_port *port, u16 reg,
156 u8 mask, u8 val)
157{
158 int status;
159 u8 tmp;
160
161 status = f81232_get_register(port, reg, &tmp);
162 if (status)
163 return status;
164
165 tmp = (tmp & ~mask) | (val & mask);
166
167 return f81232_set_register(port, reg, tmp);
168}
169
170static void f81232_read_msr(struct usb_serial_port *port)
171{
172 int status;
173 u8 current_msr;
174 struct tty_struct *tty;
175 struct f81232_private *priv = usb_get_serial_port_data(port);
176
177 mutex_lock(&priv->lock);
178 status = f81232_get_register(port, MODEM_STATUS_REGISTER,
179 &current_msr);
180 if (status) {
181 dev_err(&port->dev, "%s fail, status: %d\n", __func__, status);
182 mutex_unlock(&priv->lock);
183 return;
184 }
185
186 if (!(current_msr & UART_MSR_ANY_DELTA)) {
187 mutex_unlock(&priv->lock);
188 return;
189 }
190
191 priv->modem_status = current_msr;
192
193 if (current_msr & UART_MSR_DCTS)
194 port->icount.cts++;
195 if (current_msr & UART_MSR_DDSR)
196 port->icount.dsr++;
197 if (current_msr & UART_MSR_TERI)
198 port->icount.rng++;
199 if (current_msr & UART_MSR_DDCD) {
200 port->icount.dcd++;
201 tty = tty_port_tty_get(&port->port);
202 if (tty) {
203 usb_serial_handle_dcd_change(port, tty,
204 current_msr & UART_MSR_DCD);
205
206 tty_kref_put(tty);
207 }
208 }
209
210 wake_up_interruptible(&port->port.delta_msr_wait);
211 mutex_unlock(&priv->lock);
212}
213
214static int f81232_set_mctrl(struct usb_serial_port *port,
215 unsigned int set, unsigned int clear)
216{
217 u8 val;
218 int status;
219 struct f81232_private *priv = usb_get_serial_port_data(port);
220
221 if (((set | clear) & (TIOCM_DTR | TIOCM_RTS)) == 0)
222 return 0; /* no change */
223
224 /* 'set' takes precedence over 'clear' */
225 clear &= ~set;
226
227 /* force enable interrupt with OUT2 */
228 mutex_lock(&priv->lock);
229 val = UART_MCR_OUT2 | priv->modem_control;
230
231 if (clear & TIOCM_DTR)
232 val &= ~UART_MCR_DTR;
233
234 if (clear & TIOCM_RTS)
235 val &= ~UART_MCR_RTS;
236
237 if (set & TIOCM_DTR)
238 val |= UART_MCR_DTR;
239
240 if (set & TIOCM_RTS)
241 val |= UART_MCR_RTS;
242
243 dev_dbg(&port->dev, "%s new:%02x old:%02x\n", __func__,
244 val, priv->modem_control);
245
246 status = f81232_set_register(port, MODEM_CONTROL_REGISTER, val);
247 if (status) {
248 dev_err(&port->dev, "%s set MCR status < 0\n", __func__);
249 mutex_unlock(&priv->lock);
250 return status;
251 }
252
253 priv->modem_control = val;
254 mutex_unlock(&priv->lock);
255
256 return 0;
257}
258
259static void f81232_update_line_status(struct usb_serial_port *port,
260 unsigned char *data,
261 size_t actual_length)
262{
263 struct f81232_private *priv = usb_get_serial_port_data(port);
264
265 if (!actual_length)
266 return;
267
268 switch (data[0] & 0x07) {
269 case 0x00: /* msr change */
270 dev_dbg(&port->dev, "IIR: MSR Change: %02x\n", data[0]);
271 schedule_work(&priv->interrupt_work);
272 break;
273 case 0x02: /* tx-empty */
274 break;
275 case 0x04: /* rx data available */
276 break;
277 case 0x06: /* lsr change */
278 /* we can forget it. the LSR will read from bulk-in */
279 dev_dbg(&port->dev, "IIR: LSR Change: %02x\n", data[0]);
280 break;
281 }
282}
283
284static void f81232_read_int_callback(struct urb *urb)
285{
286 struct usb_serial_port *port = urb->context;
287 unsigned char *data = urb->transfer_buffer;
288 unsigned int actual_length = urb->actual_length;
289 int status = urb->status;
290 int retval;
291
292 switch (status) {
293 case 0:
294 /* success */
295 break;
296 case -ECONNRESET:
297 case -ENOENT:
298 case -ESHUTDOWN:
299 /* this urb is terminated, clean up */
300 dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
301 __func__, status);
302 return;
303 default:
304 dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
305 __func__, status);
306 goto exit;
307 }
308
309 usb_serial_debug_data(&port->dev, __func__,
310 urb->actual_length, urb->transfer_buffer);
311
312 f81232_update_line_status(port, data, actual_length);
313
314exit:
315 retval = usb_submit_urb(urb, GFP_ATOMIC);
316 if (retval)
317 dev_err(&urb->dev->dev,
318 "%s - usb_submit_urb failed with result %d\n",
319 __func__, retval);
320}
321
322static void f81232_process_read_urb(struct urb *urb)
323{
324 struct usb_serial_port *port = urb->context;
325 struct f81232_private *priv = usb_get_serial_port_data(port);
326 unsigned char *data = urb->transfer_buffer;
327 char tty_flag;
328 unsigned int i;
329 u8 lsr;
330
331 /*
332 * When opening the port we get a 1-byte packet with the current LSR,
333 * which we discard.
334 */
335 if ((urb->actual_length < 2) || (urb->actual_length % 2))
336 return;
337
338 /* bulk-in data: [LSR(1Byte)+DATA(1Byte)][LSR(1Byte)+DATA(1Byte)]... */
339
340 for (i = 0; i < urb->actual_length; i += 2) {
341 tty_flag = TTY_NORMAL;
342 lsr = data[i];
343
344 if (lsr & UART_LSR_BRK_ERROR_BITS) {
345 if (lsr & UART_LSR_BI) {
346 tty_flag = TTY_BREAK;
347 port->icount.brk++;
348 usb_serial_handle_break(port);
349 } else if (lsr & UART_LSR_PE) {
350 tty_flag = TTY_PARITY;
351 port->icount.parity++;
352 } else if (lsr & UART_LSR_FE) {
353 tty_flag = TTY_FRAME;
354 port->icount.frame++;
355 }
356
357 if (lsr & UART_LSR_OE) {
358 port->icount.overrun++;
359 schedule_work(&priv->lsr_work);
360 tty_insert_flip_char(&port->port, 0,
361 TTY_OVERRUN);
362 }
363 }
364
365 if (port->port.console && port->sysrq) {
366 if (usb_serial_handle_sysrq_char(port, data[i + 1]))
367 continue;
368 }
369
370 tty_insert_flip_char(&port->port, data[i + 1], tty_flag);
371 }
372
373 tty_flip_buffer_push(&port->port);
374}
375
376static void f81232_break_ctl(struct tty_struct *tty, int break_state)
377{
378 struct usb_serial_port *port = tty->driver_data;
379 struct f81232_private *priv = usb_get_serial_port_data(port);
380 int status;
381
382 mutex_lock(&priv->lock);
383
384 if (break_state)
385 priv->shadow_lcr |= UART_LCR_SBC;
386 else
387 priv->shadow_lcr &= ~UART_LCR_SBC;
388
389 status = f81232_set_register(port, LINE_CONTROL_REGISTER,
390 priv->shadow_lcr);
391 if (status)
392 dev_err(&port->dev, "set break failed: %d\n", status);
393
394 mutex_unlock(&priv->lock);
395}
396
397static int f81232_find_clk(speed_t baudrate)
398{
399 int idx;
400
401 for (idx = 0; idx < ARRAY_SIZE(baudrate_table); ++idx) {
402 if (baudrate <= baudrate_table[idx] &&
403 baudrate_table[idx] % baudrate == 0)
404 return idx;
405 }
406
407 return -EINVAL;
408}
409
410static void f81232_set_baudrate(struct tty_struct *tty,
411 struct usb_serial_port *port, speed_t baudrate,
412 speed_t old_baudrate)
413{
414 struct f81232_private *priv = usb_get_serial_port_data(port);
415 u8 lcr;
416 int divisor;
417 int status = 0;
418 int i;
419 int idx;
420 speed_t baud_list[] = { baudrate, old_baudrate, F81232_DEF_BAUDRATE };
421
422 for (i = 0; i < ARRAY_SIZE(baud_list); ++i) {
423 baudrate = baud_list[i];
424 if (baudrate == 0) {
425 tty_encode_baud_rate(tty, 0, 0);
426 return;
427 }
428
429 idx = f81232_find_clk(baudrate);
430 if (idx >= 0) {
431 tty_encode_baud_rate(tty, baudrate, baudrate);
432 break;
433 }
434 }
435
436 if (idx < 0)
437 return;
438
439 priv->baud_base = baudrate_table[idx];
440 divisor = calc_baud_divisor(baudrate, priv->baud_base);
441
442 status = f81232_set_mask_register(port, F81232_CLK_REGISTER,
443 F81232_CLK_MASK, clock_table[idx]);
444 if (status) {
445 dev_err(&port->dev, "%s failed to set CLK_REG: %d\n",
446 __func__, status);
447 return;
448 }
449
450 status = f81232_get_register(port, LINE_CONTROL_REGISTER,
451 &lcr); /* get LCR */
452 if (status) {
453 dev_err(&port->dev, "%s failed to get LCR: %d\n",
454 __func__, status);
455 return;
456 }
457
458 status = f81232_set_register(port, LINE_CONTROL_REGISTER,
459 lcr | UART_LCR_DLAB); /* Enable DLAB */
460 if (status) {
461 dev_err(&port->dev, "%s failed to set DLAB: %d\n",
462 __func__, status);
463 return;
464 }
465
466 status = f81232_set_register(port, RECEIVE_BUFFER_REGISTER,
467 divisor & 0x00ff); /* low */
468 if (status) {
469 dev_err(&port->dev, "%s failed to set baudrate MSB: %d\n",
470 __func__, status);
471 goto reapply_lcr;
472 }
473
474 status = f81232_set_register(port, INTERRUPT_ENABLE_REGISTER,
475 (divisor & 0xff00) >> 8); /* high */
476 if (status) {
477 dev_err(&port->dev, "%s failed to set baudrate LSB: %d\n",
478 __func__, status);
479 }
480
481reapply_lcr:
482 status = f81232_set_register(port, LINE_CONTROL_REGISTER,
483 lcr & ~UART_LCR_DLAB);
484 if (status) {
485 dev_err(&port->dev, "%s failed to set DLAB: %d\n",
486 __func__, status);
487 }
488}
489
490static int f81232_port_enable(struct usb_serial_port *port)
491{
492 u8 val;
493 int status;
494
495 /* fifo on, trigger8, clear TX/RX*/
496 val = UART_FCR_TRIGGER_8 | UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
497 UART_FCR_CLEAR_XMIT;
498
499 status = f81232_set_register(port, FIFO_CONTROL_REGISTER, val);
500 if (status) {
501 dev_err(&port->dev, "%s failed to set FCR: %d\n",
502 __func__, status);
503 return status;
504 }
505
506 /* MSR Interrupt only, LSR will read from Bulk-in odd byte */
507 status = f81232_set_register(port, INTERRUPT_ENABLE_REGISTER,
508 UART_IER_MSI);
509 if (status) {
510 dev_err(&port->dev, "%s failed to set IER: %d\n",
511 __func__, status);
512 return status;
513 }
514
515 return 0;
516}
517
518static int f81232_port_disable(struct usb_serial_port *port)
519{
520 int status;
521
522 status = f81232_set_register(port, INTERRUPT_ENABLE_REGISTER, 0);
523 if (status) {
524 dev_err(&port->dev, "%s failed to set IER: %d\n",
525 __func__, status);
526 return status;
527 }
528
529 return 0;
530}
531
532static void f81232_set_termios(struct tty_struct *tty,
533 struct usb_serial_port *port, struct ktermios *old_termios)
534{
535 struct f81232_private *priv = usb_get_serial_port_data(port);
536 u8 new_lcr = 0;
537 int status = 0;
538 speed_t baudrate;
539 speed_t old_baud;
540
541 /* Don't change anything if nothing has changed */
542 if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios))
543 return;
544
545 if (C_BAUD(tty) == B0)
546 f81232_set_mctrl(port, 0, TIOCM_DTR | TIOCM_RTS);
547 else if (old_termios && (old_termios->c_cflag & CBAUD) == B0)
548 f81232_set_mctrl(port, TIOCM_DTR | TIOCM_RTS, 0);
549
550 baudrate = tty_get_baud_rate(tty);
551 if (baudrate > 0) {
552 if (old_termios)
553 old_baud = tty_termios_baud_rate(old_termios);
554 else
555 old_baud = F81232_DEF_BAUDRATE;
556
557 f81232_set_baudrate(tty, port, baudrate, old_baud);
558 }
559
560 if (C_PARENB(tty)) {
561 new_lcr |= UART_LCR_PARITY;
562
563 if (!C_PARODD(tty))
564 new_lcr |= UART_LCR_EPAR;
565
566 if (C_CMSPAR(tty))
567 new_lcr |= UART_LCR_SPAR;
568 }
569
570 if (C_CSTOPB(tty))
571 new_lcr |= UART_LCR_STOP;
572
573 switch (C_CSIZE(tty)) {
574 case CS5:
575 new_lcr |= UART_LCR_WLEN5;
576 break;
577 case CS6:
578 new_lcr |= UART_LCR_WLEN6;
579 break;
580 case CS7:
581 new_lcr |= UART_LCR_WLEN7;
582 break;
583 default:
584 case CS8:
585 new_lcr |= UART_LCR_WLEN8;
586 break;
587 }
588
589 mutex_lock(&priv->lock);
590
591 new_lcr |= (priv->shadow_lcr & UART_LCR_SBC);
592 status = f81232_set_register(port, LINE_CONTROL_REGISTER, new_lcr);
593 if (status) {
594 dev_err(&port->dev, "%s failed to set LCR: %d\n",
595 __func__, status);
596 }
597
598 priv->shadow_lcr = new_lcr;
599
600 mutex_unlock(&priv->lock);
601}
602
603static int f81232_tiocmget(struct tty_struct *tty)
604{
605 int r;
606 struct usb_serial_port *port = tty->driver_data;
607 struct f81232_private *port_priv = usb_get_serial_port_data(port);
608 u8 mcr, msr;
609
610 /* force get current MSR changed state */
611 f81232_read_msr(port);
612
613 mutex_lock(&port_priv->lock);
614 mcr = port_priv->modem_control;
615 msr = port_priv->modem_status;
616 mutex_unlock(&port_priv->lock);
617
618 r = (mcr & UART_MCR_DTR ? TIOCM_DTR : 0) |
619 (mcr & UART_MCR_RTS ? TIOCM_RTS : 0) |
620 (msr & UART_MSR_CTS ? TIOCM_CTS : 0) |
621 (msr & UART_MSR_DCD ? TIOCM_CAR : 0) |
622 (msr & UART_MSR_RI ? TIOCM_RI : 0) |
623 (msr & UART_MSR_DSR ? TIOCM_DSR : 0);
624
625 return r;
626}
627
628static int f81232_tiocmset(struct tty_struct *tty,
629 unsigned int set, unsigned int clear)
630{
631 struct usb_serial_port *port = tty->driver_data;
632
633 return f81232_set_mctrl(port, set, clear);
634}
635
636static int f81232_open(struct tty_struct *tty, struct usb_serial_port *port)
637{
638 int result;
639
640 result = f81232_port_enable(port);
641 if (result)
642 return result;
643
644 /* Setup termios */
645 if (tty)
646 f81232_set_termios(tty, port, NULL);
647
648 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
649 if (result) {
650 dev_err(&port->dev, "%s - failed submitting interrupt urb,"
651 " error %d\n", __func__, result);
652 return result;
653 }
654
655 result = usb_serial_generic_open(tty, port);
656 if (result) {
657 usb_kill_urb(port->interrupt_in_urb);
658 return result;
659 }
660
661 return 0;
662}
663
664static void f81232_close(struct usb_serial_port *port)
665{
666 struct f81232_private *port_priv = usb_get_serial_port_data(port);
667
668 f81232_port_disable(port);
669 usb_serial_generic_close(port);
670 usb_kill_urb(port->interrupt_in_urb);
671 flush_work(&port_priv->interrupt_work);
672 flush_work(&port_priv->lsr_work);
673}
674
675static void f81232_dtr_rts(struct usb_serial_port *port, int on)
676{
677 if (on)
678 f81232_set_mctrl(port, TIOCM_DTR | TIOCM_RTS, 0);
679 else
680 f81232_set_mctrl(port, 0, TIOCM_DTR | TIOCM_RTS);
681}
682
683static int f81232_carrier_raised(struct usb_serial_port *port)
684{
685 u8 msr;
686 struct f81232_private *priv = usb_get_serial_port_data(port);
687
688 mutex_lock(&priv->lock);
689 msr = priv->modem_status;
690 mutex_unlock(&priv->lock);
691
692 if (msr & UART_MSR_DCD)
693 return 1;
694 return 0;
695}
696
697static int f81232_get_serial_info(struct tty_struct *tty,
698 struct serial_struct *ss)
699{
700 struct usb_serial_port *port = tty->driver_data;
701 struct f81232_private *priv = usb_get_serial_port_data(port);
702
703 ss->type = PORT_16550A;
704 ss->line = port->minor;
705 ss->port = port->port_number;
706 ss->baud_base = priv->baud_base;
707 return 0;
708}
709
710static void f81232_interrupt_work(struct work_struct *work)
711{
712 struct f81232_private *priv =
713 container_of(work, struct f81232_private, interrupt_work);
714
715 f81232_read_msr(priv->port);
716}
717
718static void f81232_lsr_worker(struct work_struct *work)
719{
720 struct f81232_private *priv;
721 struct usb_serial_port *port;
722 int status;
723 u8 tmp;
724
725 priv = container_of(work, struct f81232_private, lsr_work);
726 port = priv->port;
727
728 status = f81232_get_register(port, LINE_STATUS_REGISTER, &tmp);
729 if (status)
730 dev_warn(&port->dev, "read LSR failed: %d\n", status);
731}
732
733static int f81232_port_probe(struct usb_serial_port *port)
734{
735 struct f81232_private *priv;
736
737 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
738 if (!priv)
739 return -ENOMEM;
740
741 mutex_init(&priv->lock);
742 INIT_WORK(&priv->interrupt_work, f81232_interrupt_work);
743 INIT_WORK(&priv->lsr_work, f81232_lsr_worker);
744
745 usb_set_serial_port_data(port, priv);
746
747 port->port.drain_delay = 256;
748 priv->port = port;
749
750 return 0;
751}
752
753static int f81232_port_remove(struct usb_serial_port *port)
754{
755 struct f81232_private *priv;
756
757 priv = usb_get_serial_port_data(port);
758 kfree(priv);
759
760 return 0;
761}
762
763static int f81232_suspend(struct usb_serial *serial, pm_message_t message)
764{
765 struct usb_serial_port *port = serial->port[0];
766 struct f81232_private *port_priv = usb_get_serial_port_data(port);
767 int i;
768
769 for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i)
770 usb_kill_urb(port->read_urbs[i]);
771
772 usb_kill_urb(port->interrupt_in_urb);
773
774 if (port_priv) {
775 flush_work(&port_priv->interrupt_work);
776 flush_work(&port_priv->lsr_work);
777 }
778
779 return 0;
780}
781
782static int f81232_resume(struct usb_serial *serial)
783{
784 struct usb_serial_port *port = serial->port[0];
785 int result;
786
787 if (tty_port_initialized(&port->port)) {
788 result = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);
789 if (result) {
790 dev_err(&port->dev, "submit interrupt urb failed: %d\n",
791 result);
792 return result;
793 }
794 }
795
796 return usb_serial_generic_resume(serial);
797}
798
799static struct usb_serial_driver f81232_device = {
800 .driver = {
801 .owner = THIS_MODULE,
802 .name = "f81232",
803 },
804 .id_table = id_table,
805 .num_ports = 1,
806 .bulk_in_size = 256,
807 .bulk_out_size = 256,
808 .open = f81232_open,
809 .close = f81232_close,
810 .dtr_rts = f81232_dtr_rts,
811 .carrier_raised = f81232_carrier_raised,
812 .get_serial = f81232_get_serial_info,
813 .break_ctl = f81232_break_ctl,
814 .set_termios = f81232_set_termios,
815 .tiocmget = f81232_tiocmget,
816 .tiocmset = f81232_tiocmset,
817 .tiocmiwait = usb_serial_generic_tiocmiwait,
818 .process_read_urb = f81232_process_read_urb,
819 .read_int_callback = f81232_read_int_callback,
820 .port_probe = f81232_port_probe,
821 .port_remove = f81232_port_remove,
822 .suspend = f81232_suspend,
823 .resume = f81232_resume,
824};
825
826static struct usb_serial_driver * const serial_drivers[] = {
827 &f81232_device,
828 NULL,
829};
830
831module_usb_serial_driver(serial_drivers, id_table);
832
833MODULE_DESCRIPTION("Fintek F81232 USB to serial adaptor driver");
834MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@linuxfoundation.org>");
835MODULE_AUTHOR("Peter Hong <peter_hong@fintek.com.tw>");
836MODULE_LICENSE("GPL v2");