serial: sh-sci: Make RX/TX DMA function names consistent
[platform/kernel/linux-starfive.git] / drivers / tty / serial / sh-sci.c
index cc56cb3..cb3d5d3 100644 (file)
@@ -1243,12 +1243,22 @@ static int sci_dma_rx_find_active(struct sci_port *s)
        return -1;
 }
 
-static void sci_rx_dma_release(struct sci_port *s)
+static void sci_dma_rx_chan_invalidate(struct sci_port *s)
+{
+       unsigned int i;
+
+       s->chan_rx = NULL;
+       for (i = 0; i < ARRAY_SIZE(s->cookie_rx); i++)
+               s->cookie_rx[i] = -EINVAL;
+       s->active_rx = 0;
+}
+
+static void sci_dma_rx_release(struct sci_port *s)
 {
        struct dma_chan *chan = s->chan_rx_saved;
 
-       s->chan_rx_saved = s->chan_rx = NULL;
-       s->cookie_rx[0] = s->cookie_rx[1] = -EINVAL;
+       s->chan_rx_saved = NULL;
+       sci_dma_rx_chan_invalidate(s);
        dmaengine_terminate_sync(chan);
        dma_free_coherent(chan->device->dev, s->buf_len_rx * 2, s->rx_buf[0],
                          sg_dma_address(&s->sg_rx[0]));
@@ -1264,6 +1274,20 @@ static void start_hrtimer_us(struct hrtimer *hrt, unsigned long usec)
        hrtimer_start(hrt, t, HRTIMER_MODE_REL);
 }
 
+static void sci_dma_rx_reenable_irq(struct sci_port *s)
+{
+       struct uart_port *port = &s->port;
+       u16 scr;
+
+       /* Direct new serial port interrupts back to CPU */
+       scr = serial_port_in(port, SCSCR);
+       if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
+               scr &= ~SCSCR_RDRQE;
+               enable_irq(s->irqs[SCIx_RXI_IRQ]);
+       }
+       serial_port_out(port, SCSCR, scr | SCSCR_RIE);
+}
+
 static void sci_dma_rx_complete(void *arg)
 {
        struct sci_port *s = arg;
@@ -1313,12 +1337,13 @@ fail:
        dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n");
        /* Switch to PIO */
        spin_lock_irqsave(&port->lock, flags);
-       s->chan_rx = NULL;
-       sci_start_rx(port);
+       dmaengine_terminate_async(chan);
+       sci_dma_rx_chan_invalidate(s);
+       sci_dma_rx_reenable_irq(s);
        spin_unlock_irqrestore(&port->lock, flags);
 }
 
-static void sci_tx_dma_release(struct sci_port *s)
+static void sci_dma_tx_release(struct sci_port *s)
 {
        struct dma_chan *chan = s->chan_tx_saved;
 
@@ -1331,7 +1356,7 @@ static void sci_tx_dma_release(struct sci_port *s)
        dma_release_channel(chan);
 }
 
-static void sci_submit_rx(struct sci_port *s)
+static int sci_dma_rx_submit(struct sci_port *s, bool port_lock_held)
 {
        struct dma_chan *chan = s->chan_rx;
        struct uart_port *port = &s->port;
@@ -1359,22 +1384,22 @@ static void sci_submit_rx(struct sci_port *s)
        s->active_rx = s->cookie_rx[0];
 
        dma_async_issue_pending(chan);
-       return;
+       return 0;
 
 fail:
+       /* Switch to PIO */
+       if (!port_lock_held)
+               spin_lock_irqsave(&port->lock, flags);
        if (i)
                dmaengine_terminate_async(chan);
-       for (i = 0; i < 2; i++)
-               s->cookie_rx[i] = -EINVAL;
-       s->active_rx = -EINVAL;
-       /* Switch to PIO */
-       spin_lock_irqsave(&port->lock, flags);
-       s->chan_rx = NULL;
+       sci_dma_rx_chan_invalidate(s);
        sci_start_rx(port);
-       spin_unlock_irqrestore(&port->lock, flags);
+       if (!port_lock_held)
+               spin_unlock_irqrestore(&port->lock, flags);
+       return -EAGAIN;
 }
 
-static void work_fn_tx(struct work_struct *work)
+static void sci_dma_tx_work_fn(struct work_struct *work)
 {
        struct sci_port *s = container_of(work, struct sci_port, work_tx);
        struct dma_async_tx_descriptor *desc;
@@ -1433,7 +1458,7 @@ switch_to_pio:
        return;
 }
 
-static enum hrtimer_restart rx_timer_fn(struct hrtimer *t)
+static enum hrtimer_restart sci_dma_rx_timer_fn(struct hrtimer *t)
 {
        struct sci_port *s = container_of(t, struct sci_port, rx_timer);
        struct dma_chan *chan = s->chan_rx;
@@ -1443,7 +1468,6 @@ static enum hrtimer_restart rx_timer_fn(struct hrtimer *t)
        unsigned long flags;
        unsigned int read;
        int active, count;
-       u16 scr;
 
        dev_dbg(port->dev, "DMA Rx timed out\n");
 
@@ -1491,15 +1515,9 @@ static enum hrtimer_restart rx_timer_fn(struct hrtimer *t)
        }
 
        if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
-               sci_submit_rx(s);
+               sci_dma_rx_submit(s, true);
 
-       /* Direct new serial port interrupts back to CPU */
-       scr = serial_port_in(port, SCSCR);
-       if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
-               scr &= ~SCSCR_RDRQE;
-               enable_irq(s->irqs[SCIx_RXI_IRQ]);
-       }
-       serial_port_out(port, SCSCR, scr | SCSCR_RIE);
+       sci_dma_rx_reenable_irq(s);
 
        spin_unlock_irqrestore(&port->lock, flags);
 
@@ -1577,7 +1595,7 @@ static void sci_request_dma(struct uart_port *port)
                                __func__, UART_XMIT_SIZE,
                                port->state->xmit.buf, &s->tx_dma_addr);
 
-                       INIT_WORK(&s->work_tx, work_fn_tx);
+                       INIT_WORK(&s->work_tx, sci_dma_tx_work_fn);
                        s->chan_tx_saved = s->chan_tx = chan;
                }
        }
@@ -1612,12 +1630,12 @@ static void sci_request_dma(struct uart_port *port)
                }
 
                hrtimer_init(&s->rx_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-               s->rx_timer.function = rx_timer_fn;
+               s->rx_timer.function = sci_dma_rx_timer_fn;
 
                s->chan_rx_saved = s->chan_rx = chan;
 
                if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
-                       sci_submit_rx(s);
+                       sci_dma_rx_submit(s, false);
        }
 }
 
@@ -1626,9 +1644,9 @@ static void sci_free_dma(struct uart_port *port)
        struct sci_port *s = to_sci_port(port);
 
        if (s->chan_tx_saved)
-               sci_tx_dma_release(s);
+               sci_dma_tx_release(s);
        if (s->chan_rx_saved)
-               sci_rx_dma_release(s);
+               sci_dma_rx_release(s);
 }
 
 static void sci_flush_buffer(struct uart_port *port)
@@ -1666,8 +1684,10 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
                        disable_irq_nosync(irq);
                        scr |= SCSCR_RDRQE;
                } else {
+                       if (sci_dma_rx_submit(s, false) < 0)
+                               goto handle_pio;
+
                        scr &= ~SCSCR_RIE;
-                       sci_submit_rx(s);
                }
                serial_port_out(port, SCSCR, scr);
                /* Clear current interrupt */
@@ -1679,6 +1699,8 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
 
                return IRQ_HANDLED;
        }
+
+handle_pio:
 #endif
 
        if (s->rx_trigger > 1 && s->rx_fifo_timeout > 0) {
@@ -1693,7 +1715,7 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
         * of whether the I_IXOFF is set, otherwise, how is the interrupt
         * to be disabled?
         */
-       sci_receive_chars(ptr);
+       sci_receive_chars(port);
 
        return IRQ_HANDLED;
 }
@@ -1749,7 +1771,7 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr)
        } else {
                sci_handle_fifo_overrun(port);
                if (!s->chan_rx)
-                       sci_receive_chars(ptr);
+                       sci_receive_chars(port);
        }
 
        sci_clear_SCxSR(port, SCxSR_ERROR_CLEAR(port));