lkml.org 
[lkml]   [2018]   [Jan]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 1/5] USB: serial: f81232: clear overrun flag
    Date
    The F81232 will report data and LSR with bulk like following format:
    bulk-in data: [LSR(1Byte)+DATA(1Byte)][LSR(1Byte)+DATA(1Byte)]...

    LSR will auto clear frame/parity/break error flag when reading by H/W,
    but overrrun will only cleared when reading LSR. So this patch add a
    worker to read LSR when OE.

    Signed-off-by: Ji-Ze Hong (Peter Hong) <hpeter+linux_kernel@gmail.com>
    ---
    drivers/usb/serial/f81232.c | 20 ++++++++++++++++++++
    1 file changed, 20 insertions(+)

    diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c
    index 96036f87b1de..46836041c50e 100644
    --- a/drivers/usb/serial/f81232.c
    +++ b/drivers/usb/serial/f81232.c
    @@ -41,12 +41,14 @@ MODULE_DEVICE_TABLE(usb, id_table);
    #define FIFO_CONTROL_REGISTER (0x02 + SERIAL_BASE_ADDRESS)
    #define LINE_CONTROL_REGISTER (0x03 + SERIAL_BASE_ADDRESS)
    #define MODEM_CONTROL_REGISTER (0x04 + SERIAL_BASE_ADDRESS)
    +#define LINE_STATUS_REGISTER (0x05 + SERIAL_BASE_ADDRESS)
    #define MODEM_STATUS_REGISTER (0x06 + SERIAL_BASE_ADDRESS)

    struct f81232_private {
    struct mutex lock;
    u8 modem_control;
    u8 modem_status;
    + struct work_struct lsr_work;
    struct work_struct interrupt_work;
    struct usb_serial_port *port;
    };
    @@ -282,6 +284,7 @@ static void f81232_read_int_callback(struct urb *urb)
    static void f81232_process_read_urb(struct urb *urb)
    {
    struct usb_serial_port *port = urb->context;
    + struct f81232_private *priv = usb_get_serial_port_data(port);
    unsigned char *data = urb->transfer_buffer;
    char tty_flag;
    unsigned int i;
    @@ -315,6 +318,7 @@ static void f81232_process_read_urb(struct urb *urb)

    if (lsr & UART_LSR_OE) {
    port->icount.overrun++;
    + schedule_work(&priv->lsr_work);
    tty_insert_flip_char(&port->port, 0,
    TTY_OVERRUN);
    }
    @@ -623,6 +627,21 @@ static void f81232_interrupt_work(struct work_struct *work)
    f81232_read_msr(priv->port);
    }

    +static void f81232_lsr_worker(struct work_struct *work)
    +{
    + struct f81232_private *priv;
    + struct usb_serial_port *port;
    + int status;
    + u8 tmp;
    +
    + priv = container_of(work, struct f81232_private, lsr_work);
    + port = priv->port;
    +
    + status = f81232_get_register(port, LINE_STATUS_REGISTER, &tmp);
    + if (status)
    + dev_warn(&port->dev, "read LSR failed: %d\n", status);
    +}
    +
    static int f81232_port_probe(struct usb_serial_port *port)
    {
    struct f81232_private *priv;
    @@ -633,6 +652,7 @@ static int f81232_port_probe(struct usb_serial_port *port)

    mutex_init(&priv->lock);
    INIT_WORK(&priv->interrupt_work, f81232_interrupt_work);
    + INIT_WORK(&priv->lsr_work, f81232_lsr_worker);

    usb_set_serial_port_data(port, priv);

    --
    2.7.4
    \
     
     \ /
      Last update: 2018-01-22 08:59    [W:4.758 / U:0.208 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site