aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/synclink_gt.c59
1 files changed, 57 insertions, 2 deletions
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 3cfc9e1f8882..8511e2e43c18 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -214,6 +214,7 @@ struct slgt_desc
214 char *buf; /* virtual address of data buffer */ 214 char *buf; /* virtual address of data buffer */
215 unsigned int pdesc; /* physical address of this descriptor */ 215 unsigned int pdesc; /* physical address of this descriptor */
216 dma_addr_t buf_dma_addr; 216 dma_addr_t buf_dma_addr;
217 unsigned short buf_count;
217}; 218};
218 219
219#define set_desc_buffer(a,b) (a).pbuf = cpu_to_le32((unsigned int)(b)) 220#define set_desc_buffer(a,b) (a).pbuf = cpu_to_le32((unsigned int)(b))
@@ -466,6 +467,7 @@ static void tx_start(struct slgt_info *info);
466static void tx_stop(struct slgt_info *info); 467static void tx_stop(struct slgt_info *info);
467static void tx_set_idle(struct slgt_info *info); 468static void tx_set_idle(struct slgt_info *info);
468static unsigned int free_tbuf_count(struct slgt_info *info); 469static unsigned int free_tbuf_count(struct slgt_info *info);
470static unsigned int tbuf_bytes(struct slgt_info *info);
469static void reset_tbufs(struct slgt_info *info); 471static void reset_tbufs(struct slgt_info *info);
470static void tdma_reset(struct slgt_info *info); 472static void tdma_reset(struct slgt_info *info);
471static void tdma_start(struct slgt_info *info); 473static void tdma_start(struct slgt_info *info);
@@ -1388,10 +1390,12 @@ done:
1388static int chars_in_buffer(struct tty_struct *tty) 1390static int chars_in_buffer(struct tty_struct *tty)
1389{ 1391{
1390 struct slgt_info *info = tty->driver_data; 1392 struct slgt_info *info = tty->driver_data;
1393 int count;
1391 if (sanity_check(info, tty->name, "chars_in_buffer")) 1394 if (sanity_check(info, tty->name, "chars_in_buffer"))
1392 return 0; 1395 return 0;
1393 DBGINFO(("%s chars_in_buffer()=%d\n", info->device_name, info->tx_count)); 1396 count = tbuf_bytes(info);
1394 return info->tx_count; 1397 DBGINFO(("%s chars_in_buffer()=%d\n", info->device_name, count));
1398 return count;
1395} 1399}
1396 1400
1397/* 1401/*
@@ -4671,6 +4675,56 @@ static unsigned int free_tbuf_count(struct slgt_info *info)
4671} 4675}
4672 4676
4673/* 4677/*
4678 * return number of bytes in unsent transmit DMA buffers
4679 * and the serial controller tx FIFO
4680 */
4681static unsigned int tbuf_bytes(struct slgt_info *info)
4682{
4683 unsigned int total_count = 0;
4684 unsigned int i = info->tbuf_current;
4685 unsigned int reg_value;
4686 unsigned int count;
4687 unsigned int active_buf_count = 0;
4688
4689 /*
4690 * Add descriptor counts for all tx DMA buffers.
4691 * If count is zero (cleared by DMA controller after read),
4692 * the buffer is complete or is actively being read from.
4693 *
4694 * Record buf_count of last buffer with zero count starting
4695 * from current ring position. buf_count is mirror
4696 * copy of count and is not cleared by serial controller.
4697 * If DMA controller is active, that buffer is actively
4698 * being read so add to total.
4699 */
4700 do {
4701 count = desc_count(info->tbufs[i]);
4702 if (count)
4703 total_count += count;
4704 else if (!total_count)
4705 active_buf_count = info->tbufs[i].buf_count;
4706 if (++i == info->tbuf_count)
4707 i = 0;
4708 } while (i != info->tbuf_current);
4709
4710 /* read tx DMA status register */
4711 reg_value = rd_reg32(info, TDCSR);
4712
4713 /* if tx DMA active, last zero count buffer is in use */
4714 if (reg_value & BIT0)
4715 total_count += active_buf_count;
4716
4717 /* add tx FIFO count = reg_value[15..8] */
4718 total_count += (reg_value >> 8) & 0xff;
4719
4720 /* if transmitter active add one byte for shift register */
4721 if (info->tx_active)
4722 total_count++;
4723
4724 return total_count;
4725}
4726
4727/*
4674 * load transmit DMA buffer(s) with data 4728 * load transmit DMA buffer(s) with data
4675 */ 4729 */
4676static void tx_load(struct slgt_info *info, const char *buf, unsigned int size) 4730static void tx_load(struct slgt_info *info, const char *buf, unsigned int size)
@@ -4708,6 +4762,7 @@ static void tx_load(struct slgt_info *info, const char *buf, unsigned int size)
4708 set_desc_eof(*d, 0); 4762 set_desc_eof(*d, 0);
4709 4763
4710 set_desc_count(*d, count); 4764 set_desc_count(*d, count);
4765 d->buf_count = count;
4711 } 4766 }
4712 4767
4713 info->tbuf_current = i; 4768 info->tbuf_current = i;