X-Git-Url: https://git.karo-electronics.de/?a=blobdiff_plain;f=drivers%2Ftty%2Fserial%2Fsh-sci.c;h=e318f002da399e70862a504575f6d1fdf74598a0;hb=47aceb927fffa77b0328b6fde846a6b2182dad01;hp=1b2f894bdc9e0e6ed15cf93feb405337b1d0d07b;hpb=425afcff13a4bea2a3cf6f395cbc66fc158852be;p=karo-tx-linux.git diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 1b2f894bdc9e..e318f002da39 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -84,6 +84,7 @@ struct sci_port { unsigned int overrun_reg; unsigned int overrun_mask; unsigned int error_mask; + unsigned int error_clear; unsigned int sampling_rate; resource_size_t reg_size; @@ -103,13 +104,11 @@ struct sci_port { struct dma_chan *chan_rx; #ifdef CONFIG_SERIAL_SH_SCI_DMA - struct dma_async_tx_descriptor *desc_tx; - struct dma_async_tx_descriptor *desc_rx[2]; dma_cookie_t cookie_tx; dma_cookie_t cookie_rx[2]; dma_cookie_t active_rx; - struct scatterlist sg_tx; - unsigned int sg_len_tx; + dma_addr_t tx_dma_addr; + unsigned int tx_dma_len; struct scatterlist sg_rx[2]; size_t buf_len_rx; struct sh_dmae_slave param_tx; @@ -146,7 +145,7 @@ struct plat_sci_reg { /* Helper for invalidating specific entries of an inherited map. */ #define sci_reg_invalid { .offset = 0, .size = 0 } -static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { +static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCIx_PROBE_REGTYPE] = { [0 ... SCIx_NR_REGS - 1] = sci_reg_invalid, }, @@ -399,7 +398,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { */ static unsigned int sci_serial_in(struct uart_port *p, int offset) { - struct plat_sci_reg *reg = sci_getreg(p, offset); + const struct plat_sci_reg *reg = sci_getreg(p, offset); if (reg->size == 8) return ioread8(p->membase + (reg->offset << p->regshift)); @@ -413,7 +412,7 @@ static unsigned int sci_serial_in(struct uart_port *p, int offset) static void sci_serial_out(struct uart_port *p, int offset, int value) { - struct plat_sci_reg *reg = sci_getreg(p, offset); + const struct plat_sci_reg *reg = sci_getreg(p, offset); if (reg->size == 8) iowrite8(value, p->membase + (reg->offset << p->regshift)); @@ -489,6 +488,22 @@ static void sci_port_disable(struct sci_port *sci_port) pm_runtime_put_sync(sci_port->port.dev); } +static void sci_clear_SCxSR(struct uart_port *port, unsigned int mask) +{ + if (port->type == PORT_SCI) { + /* Just store the mask */ + serial_port_out(port, SCxSR, mask); + } else if (to_sci_port(port)->overrun_mask == SCIFA_ORER) { + /* SCIFA/SCIFB and SCIF on SH7705/SH7720/SH7721 */ + /* Only clear the status bits we want to clear */ + serial_port_out(port, SCxSR, + serial_port_in(port, SCxSR) & mask); + } else { + /* Store the mask, clear parity/framing errors */ + serial_port_out(port, SCxSR, mask & ~(SCIF_FERC | SCIF_PERC)); + } +} + #if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_SH_SCI_CONSOLE) #ifdef CONFIG_CONSOLE_POLL @@ -500,7 +515,7 @@ static int sci_poll_get_char(struct uart_port *port) do { status = serial_port_in(port, SCxSR); if (status & SCxSR_ERRORS(port)) { - serial_port_out(port, SCxSR, SCxSR_ERROR_CLEAR(port)); + sci_clear_SCxSR(port, SCxSR_ERROR_CLEAR(port)); continue; } break; @@ -513,7 +528,7 @@ static int sci_poll_get_char(struct uart_port *port) /* Dummy read */ serial_port_in(port, SCxSR); - serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); + sci_clear_SCxSR(port, SCxSR_RDxF_CLEAR(port)); return c; } @@ -528,14 +543,14 @@ static void sci_poll_put_char(struct uart_port *port, unsigned char c) } while (!(status & SCxSR_TDxE(port))); serial_port_out(port, SCxTDR, c); - serial_port_out(port, SCxSR, SCxSR_TDxE_CLEAR(port) & ~SCxSR_TEND(port)); + sci_clear_SCxSR(port, SCxSR_TDxE_CLEAR(port) & ~SCxSR_TEND(port)); } #endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */ static void sci_init_pins(struct uart_port *port, unsigned int cflag) { struct sci_port *s = to_sci_port(port); - struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + SCSPTR; + const struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + SCSPTR; /* * Use port-specific handler if provided. @@ -565,7 +580,7 @@ static void sci_init_pins(struct uart_port *port, unsigned int cflag) static int sci_txfill(struct uart_port *port) { - struct plat_sci_reg *reg; + const struct plat_sci_reg *reg; reg = sci_getreg(port, SCTFDR); if (reg->size) @@ -585,7 +600,7 @@ static int sci_txroom(struct uart_port *port) static int sci_rxfill(struct uart_port *port) { - struct plat_sci_reg *reg; + const struct plat_sci_reg *reg; reg = sci_getreg(port, SCRFDR); if (reg->size) @@ -655,7 +670,7 @@ static void sci_transmit_chars(struct uart_port *port) port->icount.tx++; } while (--count > 0); - serial_port_out(port, SCxSR, SCxSR_TDxE_CLEAR(port)); + sci_clear_SCxSR(port, SCxSR_TDxE_CLEAR(port)); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); @@ -666,7 +681,7 @@ static void sci_transmit_chars(struct uart_port *port) if (port->type != PORT_SCI) { serial_port_in(port, SCxSR); /* Dummy read */ - serial_port_out(port, SCxSR, SCxSR_TDxE_CLEAR(port)); + sci_clear_SCxSR(port, SCxSR_TDxE_CLEAR(port)); } ctrl |= SCSCR_TIE; @@ -750,7 +765,7 @@ static void sci_receive_chars(struct uart_port *port) } serial_port_in(port, SCxSR); /* dummy read */ - serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); + sci_clear_SCxSR(port, SCxSR_RDxF_CLEAR(port)); copied += count; port->icount.rx += count; @@ -761,7 +776,7 @@ static void sci_receive_chars(struct uart_port *port) tty_flip_buffer_push(tport); } else { serial_port_in(port, SCxSR); /* dummy read */ - serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); + sci_clear_SCxSR(port, SCxSR_RDxF_CLEAR(port)); } } @@ -866,7 +881,7 @@ static int sci_handle_fifo_overrun(struct uart_port *port) { struct tty_port *tport = &port->state->port; struct sci_port *s = to_sci_port(port); - struct plat_sci_reg *reg; + const struct plat_sci_reg *reg; int copied = 0; u16 status; @@ -943,7 +958,8 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr) } serial_port_out(port, SCSCR, scr); /* Clear current interrupt */ - serial_port_out(port, SCxSR, ssr & ~(1 | SCxSR_RDxF(port))); + serial_port_out(port, SCxSR, + ssr & ~(SCIF_DR | SCxSR_RDxF(port))); dev_dbg(port->dev, "Rx IRQ %lu: setup t-out in %u jiffies\n", jiffies, s->rx_timeout); mod_timer(&s->rx_timer, jiffies + s->rx_timeout); @@ -982,14 +998,14 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr) if (sci_handle_errors(port)) { /* discard character in rx buffer */ serial_port_in(port, SCxSR); - serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); + sci_clear_SCxSR(port, SCxSR_RDxF_CLEAR(port)); } } else { sci_handle_fifo_overrun(port); sci_rx_interrupt(irq, ptr); } - serial_port_out(port, SCxSR, SCxSR_ERROR_CLEAR(port)); + sci_clear_SCxSR(port, SCxSR_ERROR_CLEAR(port)); /* Kick the transmission */ sci_tx_interrupt(irq, ptr); @@ -1003,7 +1019,7 @@ static irqreturn_t sci_br_interrupt(int irq, void *ptr) /* Handle BREAKs */ sci_handle_breaks(port); - serial_port_out(port, SCxSR, SCxSR_BREAK_CLEAR(port)); + sci_clear_SCxSR(port, SCxSR_BREAK_CLEAR(port)); return IRQ_HANDLED; } @@ -1048,11 +1064,8 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) * DR flags */ if (((ssr_status & SCxSR_RDxF(port)) || s->chan_rx) && - (scr_status & SCSCR_RIE)) { - if (port->type == PORT_SCIF || port->type == PORT_HSCIF) - sci_handle_fifo_overrun(port); + (scr_status & SCSCR_RIE)) ret = sci_rx_interrupt(irq, ptr); - } /* Error Interrupt */ if ((ssr_status & SCxSR_ERRORS(port)) && err_enabled) @@ -1063,8 +1076,10 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) ret = sci_br_interrupt(irq, ptr); /* Overrun Interrupt */ - if (orer_status & s->overrun_mask) + if (orer_status & s->overrun_mask) { sci_handle_fifo_overrun(port); + ret = IRQ_HANDLED; + } return ret; } @@ -1092,7 +1107,7 @@ static int sci_notifier(struct notifier_block *self, return NOTIFY_OK; } -static struct sci_irq_desc { +static const struct sci_irq_desc { const char *desc; irq_handler_t handler; } sci_irq_desc[] = { @@ -1134,7 +1149,7 @@ static int sci_request_irq(struct sci_port *port) int i, j, ret = 0; for (i = j = 0; i < SCIx_NR_IRQS; i++, j++) { - struct sci_irq_desc *desc; + const struct sci_irq_desc *desc; int irq; if (SCIx_IRQ_IS_MUXED(port)) { @@ -1154,11 +1169,8 @@ static int sci_request_irq(struct sci_port *port) desc = sci_irq_desc + i; port->irqstr[j] = kasprintf(GFP_KERNEL, "%s:%s", dev_name(up->dev), desc->desc); - if (!port->irqstr[j]) { - dev_err(up->dev, "Failed to allocate %s IRQ string\n", - desc->desc); + if (!port->irqstr[j]) goto out_nomem; - } ret = request_irq(irq, desc->handler, up->irqflags, port->irqstr[j], port); @@ -1232,7 +1244,7 @@ static unsigned int sci_tx_empty(struct uart_port *port) static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl) { if (mctrl & TIOCM_LOOP) { - struct plat_sci_reg *reg; + const struct plat_sci_reg *reg; /* * Standard loopback mode for SCFCR ports. @@ -1266,13 +1278,10 @@ static void sci_dma_tx_complete(void *arg) spin_lock_irqsave(&port->lock, flags); - xmit->tail += sg_dma_len(&s->sg_tx); + xmit->tail += s->tx_dma_len; xmit->tail &= UART_XMIT_SIZE - 1; - port->icount.tx += sg_dma_len(&s->sg_tx); - - async_tx_ack(s->desc_tx); - s->desc_tx = NULL; + port->icount.tx += s->tx_dma_len; if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); @@ -1305,7 +1314,8 @@ static int sci_dma_rx_push(struct sci_port *s, size_t count) } else if (s->active_rx == s->cookie_rx[1]) { active = 1; } else { - dev_err(port->dev, "cookie %d not found!\n", s->active_rx); + dev_err(port->dev, "%s: Rx cookie %d not found!\n", __func__, + s->active_rx); return 0; } @@ -1331,8 +1341,8 @@ static void sci_dma_rx_complete(void *arg) unsigned long flags; int count; - dev_dbg(port->dev, "%s(%d) active #%d\n", - __func__, port->line, s->active_rx); + dev_dbg(port->dev, "%s(%d) active cookie %d\n", __func__, port->line, + s->active_rx); spin_lock_irqsave(&port->lock, flags); @@ -1355,10 +1365,9 @@ static void sci_rx_dma_release(struct sci_port *s, bool enable_pio) s->chan_rx = NULL; s->cookie_rx[0] = s->cookie_rx[1] = -EINVAL; + dma_free_coherent(chan->device->dev, s->buf_len_rx * 2, + sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0])); dma_release_channel(chan); - if (sg_dma_address(&s->sg_rx[0])) - dma_free_coherent(port->dev, s->buf_len_rx * 2, - sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0])); if (enable_pio) sci_start_rx(port); } @@ -1370,6 +1379,8 @@ static void sci_tx_dma_release(struct sci_port *s, bool enable_pio) s->chan_tx = NULL; s->cookie_tx = -EINVAL; + dma_unmap_single(chan->device->dev, s->tx_dma_addr, UART_XMIT_SIZE, + DMA_TO_DEVICE); dma_release_channel(chan); if (enable_pio) sci_start_tx(port); @@ -1385,36 +1396,34 @@ static void sci_submit_rx(struct sci_port *s) struct dma_async_tx_descriptor *desc; desc = dmaengine_prep_slave_sg(chan, - sg, 1, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT); + sg, 1, DMA_DEV_TO_MEM, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!desc) + goto fail; - if (desc) { - s->desc_rx[i] = desc; - desc->callback = sci_dma_rx_complete; - desc->callback_param = s; - s->cookie_rx[i] = desc->tx_submit(desc); - } + desc->callback = sci_dma_rx_complete; + desc->callback_param = s; + s->cookie_rx[i] = dmaengine_submit(desc); + if (dma_submit_error(s->cookie_rx[i])) + goto fail; - if (!desc || s->cookie_rx[i] < 0) { - if (i) { - async_tx_ack(s->desc_rx[0]); - s->cookie_rx[0] = -EINVAL; - } - if (desc) { - async_tx_ack(desc); - s->cookie_rx[i] = -EINVAL; - } - dev_warn(s->port.dev, - "failed to re-start DMA, using PIO\n"); - sci_rx_dma_release(s, true); - return; - } - dev_dbg(s->port.dev, "%s(): cookie %d to #%d\n", - __func__, s->cookie_rx[i], i); + dev_dbg(s->port.dev, "%s(): cookie %d to #%d\n", __func__, + s->cookie_rx[i], i); } s->active_rx = s->cookie_rx[0]; dma_async_issue_pending(chan); + return; + +fail: + if (i) + dmaengine_terminate_all(chan); + for (i = 0; i < 2; i++) + s->cookie_rx[i] = -EINVAL; + s->active_rx = -EINVAL; + dev_warn(s->port.dev, "Failed to re-start Rx DMA, using PIO\n"); + sci_rx_dma_release(s, true); } static void work_fn_rx(struct work_struct *work) @@ -1422,6 +1431,8 @@ static void work_fn_rx(struct work_struct *work) struct sci_port *s = container_of(work, struct sci_port, work_rx); struct uart_port *port = &s->port; struct dma_async_tx_descriptor *desc; + struct dma_tx_state state; + enum dma_status status; int new; if (s->active_rx == s->cookie_rx[0]) { @@ -1429,26 +1440,26 @@ static void work_fn_rx(struct work_struct *work) } else if (s->active_rx == s->cookie_rx[1]) { new = 1; } else { - dev_err(port->dev, "cookie %d not found!\n", s->active_rx); + dev_err(port->dev, "%s: Rx cookie %d not found!\n", __func__, + s->active_rx); return; } - desc = s->desc_rx[new]; - if (dma_async_is_tx_complete(s->chan_rx, s->active_rx, NULL, NULL) != - DMA_COMPLETE) { + status = dmaengine_tx_status(s->chan_rx, s->active_rx, &state); + if (status != DMA_COMPLETE) { /* Handle incomplete DMA receive */ struct dma_chan *chan = s->chan_rx; - struct shdma_desc *sh_desc = container_of(desc, - struct shdma_desc, async_tx); unsigned long flags; + unsigned int read; int count; dmaengine_terminate_all(chan); - dev_dbg(port->dev, "Read %zu bytes with cookie %d\n", - sh_desc->partial, sh_desc->cookie); + read = sg_dma_len(&s->sg_rx[new]) - state.residue; + dev_dbg(port->dev, "Read %u bytes with cookie %d\n", read, + s->active_rx); spin_lock_irqsave(&port->lock, flags); - count = sci_dma_rx_push(s, sh_desc->partial); + count = sci_dma_rx_push(s, read); spin_unlock_irqrestore(&port->lock, flags); if (count) @@ -1459,17 +1470,27 @@ static void work_fn_rx(struct work_struct *work) return; } - s->cookie_rx[new] = desc->tx_submit(desc); - if (s->cookie_rx[new] < 0) { - dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n"); - sci_rx_dma_release(s, true); - return; - } + desc = dmaengine_prep_slave_sg(s->chan_rx, &s->sg_rx[new], 1, + DMA_DEV_TO_MEM, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!desc) + goto fail; + + desc->callback = sci_dma_rx_complete; + desc->callback_param = s; + s->cookie_rx[new] = dmaengine_submit(desc); + if (dma_submit_error(s->cookie_rx[new])) + goto fail; s->active_rx = s->cookie_rx[!new]; - dev_dbg(port->dev, "%s: cookie %d #%d, new active #%d\n", + dev_dbg(port->dev, "%s: cookie %d #%d, new active cookie %d\n", __func__, s->cookie_rx[new], new, s->active_rx); + return; + +fail: + dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n"); + sci_rx_dma_release(s, true); } static void work_fn_tx(struct work_struct *work) @@ -1479,7 +1500,7 @@ static void work_fn_tx(struct work_struct *work) struct dma_chan *chan = s->chan_tx; struct uart_port *port = &s->port; struct circ_buf *xmit = &port->state->xmit; - struct scatterlist *sg = &s->sg_tx; + dma_addr_t buf; /* * DMA is idle now. @@ -1489,33 +1510,31 @@ static void work_fn_tx(struct work_struct *work) * consistent xmit buffer state. */ spin_lock_irq(&port->lock); - sg->offset = xmit->tail & (UART_XMIT_SIZE - 1); - sg_dma_address(sg) = (sg_dma_address(sg) & ~(UART_XMIT_SIZE - 1)) + - sg->offset; - sg_dma_len(sg) = min((int)CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE), + buf = s->tx_dma_addr + (xmit->tail & (UART_XMIT_SIZE - 1)); + s->tx_dma_len = min_t(unsigned int, + CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE), CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE)); spin_unlock_irq(&port->lock); - BUG_ON(!sg_dma_len(sg)); - - desc = dmaengine_prep_slave_sg(chan, - sg, s->sg_len_tx, DMA_MEM_TO_DEV, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + desc = dmaengine_prep_slave_single(chan, buf, s->tx_dma_len, + DMA_MEM_TO_DEV, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!desc) { + dev_warn(port->dev, "Failed preparing Tx DMA descriptor\n"); /* switch to PIO */ sci_tx_dma_release(s, true); return; } - dma_sync_sg_for_device(port->dev, sg, 1, DMA_TO_DEVICE); + dma_sync_single_for_device(chan->device->dev, buf, s->tx_dma_len, + DMA_TO_DEVICE); spin_lock_irq(&port->lock); - s->desc_tx = desc; desc->callback = sci_dma_tx_complete; desc->callback_param = s; spin_unlock_irq(&port->lock); - s->cookie_tx = desc->tx_submit(desc); - if (s->cookie_tx < 0) { + s->cookie_tx = dmaengine_submit(desc); + if (dma_submit_error(s->cookie_tx)) { dev_warn(port->dev, "Failed submitting Tx DMA descriptor\n"); /* switch to PIO */ sci_tx_dma_release(s, true); @@ -1546,7 +1565,7 @@ static void sci_start_tx(struct uart_port *port) } if (s->chan_tx && !uart_circ_empty(&s->port.state->xmit) && - s->cookie_tx < 0) { + dma_submit_error(s->cookie_tx)) { s->cookie_tx = 0; schedule_work(&s->work_tx); } @@ -1603,7 +1622,7 @@ static void sci_stop_rx(struct uart_port *port) static void sci_break_ctl(struct uart_port *port, int break_state) { struct sci_port *s = to_sci_port(port); - struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + SCSPTR; + const struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + SCSPTR; unsigned short scscr, scsptr; /* check wheter the port has SCSPTR */ @@ -1663,7 +1682,6 @@ static void sci_request_dma(struct uart_port *port) struct sh_dmae_slave *param; struct dma_chan *chan; dma_cap_mask_t mask; - int nent; dev_dbg(port->dev, "%s: port %d\n", __func__, port->line); @@ -1683,22 +1701,20 @@ static void sci_request_dma(struct uart_port *port) dev_dbg(port->dev, "%s: TX: got channel %p\n", __func__, chan); if (chan) { s->chan_tx = chan; - sg_init_table(&s->sg_tx, 1); /* UART circular tx buffer is an aligned page. */ - BUG_ON((uintptr_t)port->state->xmit.buf & ~PAGE_MASK); - sg_set_page(&s->sg_tx, virt_to_page(port->state->xmit.buf), - UART_XMIT_SIZE, - (uintptr_t)port->state->xmit.buf & ~PAGE_MASK); - nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE); - if (!nent) - sci_tx_dma_release(s, false); - else - dev_dbg(port->dev, "%s: mapped %d@%p to %pad\n", - __func__, - sg_dma_len(&s->sg_tx), port->state->xmit.buf, - &sg_dma_address(&s->sg_tx)); - - s->sg_len_tx = nent; + s->tx_dma_addr = dma_map_single(chan->device->dev, + port->state->xmit.buf, + UART_XMIT_SIZE, + DMA_TO_DEVICE); + if (dma_mapping_error(chan->device->dev, s->tx_dma_addr)) { + dev_warn(port->dev, "Failed mapping Tx DMA descriptor\n"); + dma_release_channel(chan); + s->chan_tx = NULL; + } else { + dev_dbg(port->dev, "%s: mapped %lu@%p to %pad\n", + __func__, UART_XMIT_SIZE, + port->state->xmit.buf, &s->tx_dma_addr); + } INIT_WORK(&s->work_tx, work_fn_tx); } @@ -1717,14 +1733,17 @@ static void sci_request_dma(struct uart_port *port) s->chan_rx = chan; - s->buf_len_rx = 2 * max(16, (int)port->fifosize); - buf[0] = dma_alloc_coherent(port->dev, s->buf_len_rx * 2, - &dma[0], GFP_KERNEL); + s->buf_len_rx = 2 * max_t(size_t, 16, port->fifosize); + buf[0] = dma_alloc_coherent(chan->device->dev, + s->buf_len_rx * 2, &dma[0], + GFP_KERNEL); if (!buf[0]) { dev_warn(port->dev, - "failed to allocate dma buffer, using PIO\n"); - sci_rx_dma_release(s, true); + "Failed to allocate Rx dma buffer, using PIO\n"); + dma_release_channel(chan); + s->chan_rx = NULL; + sci_start_rx(port); return; } @@ -1892,7 +1911,7 @@ static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, static void sci_reset(struct uart_port *port) { - struct plat_sci_reg *reg; + const struct plat_sci_reg *reg; unsigned int status; do { @@ -1910,7 +1929,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct sci_port *s = to_sci_port(port); - struct plat_sci_reg *reg; + const struct plat_sci_reg *reg; unsigned int baud, smr_val = 0, max_baud, cks = 0; int t = -1; unsigned int srr = 15; @@ -1951,7 +1970,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, sci_reset(port); - smr_val |= serial_port_in(port, SCSMR) & 3; + smr_val |= serial_port_in(port, SCSMR) & SCSMR_CKS; uart_update_timeout(port, termios->c_cflag, baud); @@ -1996,13 +2015,13 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, #ifdef CONFIG_SERIAL_SH_SCI_DMA /* * Calculate delay for 2 DMA buffers (4 FIFO). - * See drivers/serial/serial_core.c::uart_update_timeout(). With 10 - * bits (CS8), 250Hz, 115200 baud and 64 bytes FIFO, the above function - * calculates 1 jiffie for the data plus 5 jiffies for the "slop(e)." - * Then below we calculate 5 jiffies (20ms) for 2 DMA buffers (4 FIFO - * sizes), but when performing a faster transfer, value obtained by - * this formula is may not enough. Therefore, if value is smaller than - * 20msec, this sets 20msec as timeout of DMA. + * See serial_core.c::uart_update_timeout(). + * With 10 bits (CS8), 250Hz, 115200 baud and 64 bytes FIFO, the above + * function calculates 1 jiffie for the data plus 5 jiffies for the + * "slop(e)." Then below we calculate 5 jiffies (20ms) for 2 DMA + * buffers (4 FIFO sizes), but when performing a faster transfer, the + * value obtained by this formula is too small. Therefore, if the value + * is smaller than 20ms, use 20ms as the timeout value for DMA. */ if (s->chan_rx) { unsigned int bits; @@ -2187,7 +2206,6 @@ static int sci_init_single(struct platform_device *dev, { struct uart_port *port = &sci_port->port; const struct resource *res; - unsigned int sampling_rate; unsigned int i; int ret; @@ -2232,37 +2250,37 @@ static int sci_init_single(struct platform_device *dev, port->fifosize = 256; sci_port->overrun_reg = SCxSR; sci_port->overrun_mask = SCIFA_ORER; - sampling_rate = 16; + sci_port->sampling_rate = 16; break; case PORT_HSCIF: port->fifosize = 128; - sampling_rate = 0; sci_port->overrun_reg = SCLSR; sci_port->overrun_mask = SCLSR_ORER; + sci_port->sampling_rate = 0; break; case PORT_SCIFA: port->fifosize = 64; sci_port->overrun_reg = SCxSR; sci_port->overrun_mask = SCIFA_ORER; - sampling_rate = 16; + sci_port->sampling_rate = 16; break; case PORT_SCIF: port->fifosize = 16; if (p->regtype == SCIx_SH7705_SCIF_REGTYPE) { sci_port->overrun_reg = SCxSR; sci_port->overrun_mask = SCIFA_ORER; - sampling_rate = 16; + sci_port->sampling_rate = 16; } else { sci_port->overrun_reg = SCLSR; sci_port->overrun_mask = SCLSR_ORER; - sampling_rate = 32; + sci_port->sampling_rate = 32; } break; default: port->fifosize = 1; sci_port->overrun_reg = SCxSR; sci_port->overrun_mask = SCI_ORER; - sampling_rate = 32; + sci_port->sampling_rate = 32; break; } @@ -2270,8 +2288,8 @@ static int sci_init_single(struct platform_device *dev, * match the SoC datasheet, this should be investigated. Let platform * data override the sampling rate for now. */ - sci_port->sampling_rate = p->sampling_rate ? p->sampling_rate - : sampling_rate; + if (p->sampling_rate) + sci_port->sampling_rate = p->sampling_rate; if (!early) { sci_port->iclk = clk_get(&dev->dev, "sci_ick"); @@ -2303,15 +2321,22 @@ static int sci_init_single(struct platform_device *dev, /* * Establish some sensible defaults for the error detection. */ - sci_port->error_mask = (p->type == PORT_SCI) ? - SCI_DEFAULT_ERROR_MASK : SCIF_DEFAULT_ERROR_MASK; + if (p->type == PORT_SCI) { + sci_port->error_mask = SCI_DEFAULT_ERROR_MASK; + sci_port->error_clear = SCI_ERROR_CLEAR; + } else { + sci_port->error_mask = SCIF_DEFAULT_ERROR_MASK; + sci_port->error_clear = SCIF_ERROR_CLEAR; + } /* * Make the error mask inclusive of overrun detection, if * supported. */ - if (sci_port->overrun_reg == SCxSR) + if (sci_port->overrun_reg == SCxSR) { sci_port->error_mask |= sci_port->overrun_mask; + sci_port->error_clear &= ~sci_port->overrun_mask; + } port->type = p->type; port->flags = UPF_FIXED_PORT | p->flags; @@ -2564,10 +2589,8 @@ sci_parse_dt(struct platform_device *pdev, unsigned int *dev_id) info = match->data; p = devm_kzalloc(&pdev->dev, sizeof(struct plat_sci_port), GFP_KERNEL); - if (!p) { - dev_err(&pdev->dev, "failed to allocate DT config data\n"); + if (!p) return NULL; - } /* Get the line number for the aliases node. */ id = of_alias_get_id(np, "serial");