diff options
Diffstat (limited to 'drivers/tty/serial/amba-pl011.c')
-rw-r--r-- | drivers/tty/serial/amba-pl011.c | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 02016fcd91b8..8d94c194f090 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c | |||
@@ -246,6 +246,7 @@ static int pl011_sgbuf_init(struct dma_chan *chan, struct pl011_sgbuf *sg, | |||
246 | sg_set_page(&sg->sg, phys_to_page(dma_addr), | 246 | sg_set_page(&sg->sg, phys_to_page(dma_addr), |
247 | PL011_DMA_BUFFER_SIZE, offset_in_page(dma_addr)); | 247 | PL011_DMA_BUFFER_SIZE, offset_in_page(dma_addr)); |
248 | sg_dma_address(&sg->sg) = dma_addr; | 248 | sg_dma_address(&sg->sg) = dma_addr; |
249 | sg_dma_len(&sg->sg) = PL011_DMA_BUFFER_SIZE; | ||
249 | 250 | ||
250 | return 0; | 251 | return 0; |
251 | } | 252 | } |
@@ -321,10 +322,26 @@ static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port * | |||
321 | .src_maxburst = uap->fifosize >> 2, | 322 | .src_maxburst = uap->fifosize >> 2, |
322 | .device_fc = false, | 323 | .device_fc = false, |
323 | }; | 324 | }; |
325 | struct dma_slave_caps caps; | ||
324 | 326 | ||
327 | /* | ||
328 | * Some DMA controllers provide information on their capabilities. | ||
329 | * If the controller does, check for suitable residue processing | ||
330 | * otherwise assime all is well. | ||
331 | */ | ||
332 | if (0 == dma_get_slave_caps(chan, &caps)) { | ||
333 | if (caps.residue_granularity == | ||
334 | DMA_RESIDUE_GRANULARITY_DESCRIPTOR) { | ||
335 | dma_release_channel(chan); | ||
336 | dev_info(uap->port.dev, | ||
337 | "RX DMA disabled - no residue processing\n"); | ||
338 | return; | ||
339 | } | ||
340 | } | ||
325 | dmaengine_slave_config(chan, &rx_conf); | 341 | dmaengine_slave_config(chan, &rx_conf); |
326 | uap->dmarx.chan = chan; | 342 | uap->dmarx.chan = chan; |
327 | 343 | ||
344 | uap->dmarx.auto_poll_rate = false; | ||
328 | if (plat && plat->dma_rx_poll_enable) { | 345 | if (plat && plat->dma_rx_poll_enable) { |
329 | /* Set poll rate if specified. */ | 346 | /* Set poll rate if specified. */ |
330 | if (plat->dma_rx_poll_rate) { | 347 | if (plat->dma_rx_poll_rate) { |
@@ -345,9 +362,24 @@ static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port * | |||
345 | plat->dma_rx_poll_timeout; | 362 | plat->dma_rx_poll_timeout; |
346 | else | 363 | else |
347 | uap->dmarx.poll_timeout = 3000; | 364 | uap->dmarx.poll_timeout = 3000; |
348 | } else | 365 | } else if (!plat && dev->of_node) { |
349 | uap->dmarx.auto_poll_rate = false; | 366 | uap->dmarx.auto_poll_rate = of_property_read_bool( |
350 | 367 | dev->of_node, "auto-poll"); | |
368 | if (uap->dmarx.auto_poll_rate) { | ||
369 | u32 x; | ||
370 | |||
371 | if (0 == of_property_read_u32(dev->of_node, | ||
372 | "poll-rate-ms", &x)) | ||
373 | uap->dmarx.poll_rate = x; | ||
374 | else | ||
375 | uap->dmarx.poll_rate = 100; | ||
376 | if (0 == of_property_read_u32(dev->of_node, | ||
377 | "poll-timeout-ms", &x)) | ||
378 | uap->dmarx.poll_timeout = x; | ||
379 | else | ||
380 | uap->dmarx.poll_timeout = 3000; | ||
381 | } | ||
382 | } | ||
351 | dev_info(uap->port.dev, "DMA channel RX %s\n", | 383 | dev_info(uap->port.dev, "DMA channel RX %s\n", |
352 | dma_chan_name(uap->dmarx.chan)); | 384 | dma_chan_name(uap->dmarx.chan)); |
353 | } | 385 | } |
@@ -501,7 +533,11 @@ static int pl011_dma_tx_refill(struct uart_amba_port *uap) | |||
501 | memcpy(&dmatx->buf[0], &xmit->buf[xmit->tail], count); | 533 | memcpy(&dmatx->buf[0], &xmit->buf[xmit->tail], count); |
502 | else { | 534 | else { |
503 | size_t first = UART_XMIT_SIZE - xmit->tail; | 535 | size_t first = UART_XMIT_SIZE - xmit->tail; |
504 | size_t second = xmit->head; | 536 | size_t second; |
537 | |||
538 | if (first > count) | ||
539 | first = count; | ||
540 | second = count - first; | ||
505 | 541 | ||
506 | memcpy(&dmatx->buf[0], &xmit->buf[xmit->tail], first); | 542 | memcpy(&dmatx->buf[0], &xmit->buf[xmit->tail], first); |
507 | if (second) | 543 | if (second) |
@@ -988,7 +1024,7 @@ static void pl011_dma_startup(struct uart_amba_port *uap) | |||
988 | if (!uap->dmatx.chan) | 1024 | if (!uap->dmatx.chan) |
989 | return; | 1025 | return; |
990 | 1026 | ||
991 | uap->dmatx.buf = kmalloc(PL011_DMA_BUFFER_SIZE, GFP_KERNEL); | 1027 | uap->dmatx.buf = kmalloc(PL011_DMA_BUFFER_SIZE, GFP_KERNEL | __GFP_DMA); |
992 | if (!uap->dmatx.buf) { | 1028 | if (!uap->dmatx.buf) { |
993 | dev_err(uap->port.dev, "no memory for DMA TX buffer\n"); | 1029 | dev_err(uap->port.dev, "no memory for DMA TX buffer\n"); |
994 | uap->port.fifosize = uap->fifosize; | 1030 | uap->port.fifosize = uap->fifosize; |
@@ -1689,6 +1725,8 @@ static void pl011_shutdown(struct uart_port *port) | |||
1689 | plat->exit(); | 1725 | plat->exit(); |
1690 | } | 1726 | } |
1691 | 1727 | ||
1728 | if (uap->port.ops->flush_buffer) | ||
1729 | uap->port.ops->flush_buffer(port); | ||
1692 | } | 1730 | } |
1693 | 1731 | ||
1694 | static void | 1732 | static void |