aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/synclink_gt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/synclink_gt.c')
-rw-r--r--drivers/char/synclink_gt.c77
1 files changed, 68 insertions, 9 deletions
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 67986ea0d479..1386625fc4ca 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -214,6 +214,7 @@ struct slgt_desc
214#define set_desc_next(a,b) (a).next = cpu_to_le32((unsigned int)(b)) 214#define set_desc_next(a,b) (a).next = cpu_to_le32((unsigned int)(b))
215#define set_desc_count(a,b)(a).count = cpu_to_le16((unsigned short)(b)) 215#define set_desc_count(a,b)(a).count = cpu_to_le16((unsigned short)(b))
216#define set_desc_eof(a,b) (a).status = cpu_to_le16((b) ? (le16_to_cpu((a).status) | BIT0) : (le16_to_cpu((a).status) & ~BIT0)) 216#define set_desc_eof(a,b) (a).status = cpu_to_le16((b) ? (le16_to_cpu((a).status) | BIT0) : (le16_to_cpu((a).status) & ~BIT0))
217#define set_desc_status(a, b) (a).status = cpu_to_le16((unsigned short)(b))
217#define desc_count(a) (le16_to_cpu((a).count)) 218#define desc_count(a) (le16_to_cpu((a).count))
218#define desc_status(a) (le16_to_cpu((a).status)) 219#define desc_status(a) (le16_to_cpu((a).status))
219#define desc_complete(a) (le16_to_cpu((a).status) & BIT15) 220#define desc_complete(a) (le16_to_cpu((a).status) & BIT15)
@@ -297,6 +298,7 @@ struct slgt_info {
297 u32 max_frame_size; /* as set by device config */ 298 u32 max_frame_size; /* as set by device config */
298 299
299 unsigned int rbuf_fill_level; 300 unsigned int rbuf_fill_level;
301 unsigned int rx_pio;
300 unsigned int if_mode; 302 unsigned int if_mode;
301 unsigned int base_clock; 303 unsigned int base_clock;
302 304
@@ -331,6 +333,8 @@ struct slgt_info {
331 struct slgt_desc *rbufs; 333 struct slgt_desc *rbufs;
332 unsigned int rbuf_current; 334 unsigned int rbuf_current;
333 unsigned int rbuf_index; 335 unsigned int rbuf_index;
336 unsigned int rbuf_fill_index;
337 unsigned short rbuf_fill_count;
334 338
335 unsigned int tbuf_count; 339 unsigned int tbuf_count;
336 struct slgt_desc *tbufs; 340 struct slgt_desc *tbufs;
@@ -2110,6 +2114,40 @@ static void ri_change(struct slgt_info *info, unsigned short status)
2110 info->pending_bh |= BH_STATUS; 2114 info->pending_bh |= BH_STATUS;
2111} 2115}
2112 2116
2117static void isr_rxdata(struct slgt_info *info)
2118{
2119 unsigned int count = info->rbuf_fill_count;
2120 unsigned int i = info->rbuf_fill_index;
2121 unsigned short reg;
2122
2123 while (rd_reg16(info, SSR) & IRQ_RXDATA) {
2124 reg = rd_reg16(info, RDR);
2125 DBGISR(("isr_rxdata %s RDR=%04X\n", info->device_name, reg));
2126 if (desc_complete(info->rbufs[i])) {
2127 /* all buffers full */
2128 rx_stop(info);
2129 info->rx_restart = 1;
2130 continue;
2131 }
2132 info->rbufs[i].buf[count++] = (unsigned char)reg;
2133 /* async mode saves status byte to buffer for each data byte */
2134 if (info->params.mode == MGSL_MODE_ASYNC)
2135 info->rbufs[i].buf[count++] = (unsigned char)(reg >> 8);
2136 if (count == info->rbuf_fill_level || (reg & BIT10)) {
2137 /* buffer full or end of frame */
2138 set_desc_count(info->rbufs[i], count);
2139 set_desc_status(info->rbufs[i], BIT15 | (reg >> 8));
2140 info->rbuf_fill_count = count = 0;
2141 if (++i == info->rbuf_count)
2142 i = 0;
2143 info->pending_bh |= BH_RECEIVE;
2144 }
2145 }
2146
2147 info->rbuf_fill_index = i;
2148 info->rbuf_fill_count = count;
2149}
2150
2113static void isr_serial(struct slgt_info *info) 2151static void isr_serial(struct slgt_info *info)
2114{ 2152{
2115 unsigned short status = rd_reg16(info, SSR); 2153 unsigned short status = rd_reg16(info, SSR);
@@ -2125,6 +2163,8 @@ static void isr_serial(struct slgt_info *info)
2125 if (info->tx_count) 2163 if (info->tx_count)
2126 isr_txeom(info, status); 2164 isr_txeom(info, status);
2127 } 2165 }
2166 if (info->rx_pio && (status & IRQ_RXDATA))
2167 isr_rxdata(info);
2128 if ((status & IRQ_RXBREAK) && (status & RXBREAK)) { 2168 if ((status & IRQ_RXBREAK) && (status & RXBREAK)) {
2129 info->icount.brk++; 2169 info->icount.brk++;
2130 /* process break detection if tty control allows */ 2170 /* process break detection if tty control allows */
@@ -2141,7 +2181,8 @@ static void isr_serial(struct slgt_info *info)
2141 } else { 2181 } else {
2142 if (status & (IRQ_TXIDLE + IRQ_TXUNDER)) 2182 if (status & (IRQ_TXIDLE + IRQ_TXUNDER))
2143 isr_txeom(info, status); 2183 isr_txeom(info, status);
2144 2184 if (info->rx_pio && (status & IRQ_RXDATA))
2185 isr_rxdata(info);
2145 if (status & IRQ_RXIDLE) { 2186 if (status & IRQ_RXIDLE) {
2146 if (status & RXIDLE) 2187 if (status & RXIDLE)
2147 info->icount.rxidle++; 2188 info->icount.rxidle++;
@@ -2642,6 +2683,10 @@ static int rx_enable(struct slgt_info *info, int enable)
2642 return -EINVAL; 2683 return -EINVAL;
2643 } 2684 }
2644 info->rbuf_fill_level = rbuf_fill_level; 2685 info->rbuf_fill_level = rbuf_fill_level;
2686 if (rbuf_fill_level < 128)
2687 info->rx_pio = 1; /* PIO mode */
2688 else
2689 info->rx_pio = 0; /* DMA mode */
2645 rx_stop(info); /* restart receiver to use new fill level */ 2690 rx_stop(info); /* restart receiver to use new fill level */
2646 } 2691 }
2647 2692
@@ -3844,15 +3889,27 @@ static void rx_start(struct slgt_info *info)
3844 rdma_reset(info); 3889 rdma_reset(info);
3845 reset_rbufs(info); 3890 reset_rbufs(info);
3846 3891
3847 /* set 1st descriptor address */ 3892 if (info->rx_pio) {
3848 wr_reg32(info, RDDAR, info->rbufs[0].pdesc); 3893 /* rx request when rx FIFO not empty */
3849 3894 wr_reg16(info, SCR, (unsigned short)(rd_reg16(info, SCR) & ~BIT14));
3850 if (info->params.mode != MGSL_MODE_ASYNC) { 3895 slgt_irq_on(info, IRQ_RXDATA);
3851 /* enable rx DMA and DMA interrupt */ 3896 if (info->params.mode == MGSL_MODE_ASYNC) {
3852 wr_reg32(info, RDCSR, (BIT2 + BIT0)); 3897 /* enable saving of rx status */
3898 wr_reg32(info, RDCSR, BIT6);
3899 }
3853 } else { 3900 } else {
3854 /* enable saving of rx status, rx DMA and DMA interrupt */ 3901 /* rx request when rx FIFO half full */
3855 wr_reg32(info, RDCSR, (BIT6 + BIT2 + BIT0)); 3902 wr_reg16(info, SCR, (unsigned short)(rd_reg16(info, SCR) | BIT14));
3903 /* set 1st descriptor address */
3904 wr_reg32(info, RDDAR, info->rbufs[0].pdesc);
3905
3906 if (info->params.mode != MGSL_MODE_ASYNC) {
3907 /* enable rx DMA and DMA interrupt */
3908 wr_reg32(info, RDCSR, (BIT2 + BIT0));
3909 } else {
3910 /* enable saving of rx status, rx DMA and DMA interrupt */
3911 wr_reg32(info, RDCSR, (BIT6 + BIT2 + BIT0));
3912 }
3856 } 3913 }
3857 3914
3858 slgt_irq_on(info, IRQ_RXOVER); 3915 slgt_irq_on(info, IRQ_RXOVER);
@@ -4470,6 +4527,8 @@ static void free_rbufs(struct slgt_info *info, unsigned int i, unsigned int last
4470static void reset_rbufs(struct slgt_info *info) 4527static void reset_rbufs(struct slgt_info *info)
4471{ 4528{
4472 free_rbufs(info, 0, info->rbuf_count - 1); 4529 free_rbufs(info, 0, info->rbuf_count - 1);
4530 info->rbuf_fill_index = 0;
4531 info->rbuf_fill_count = 0;
4473} 4532}
4474 4533
4475/* 4534/*