Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 146242
b: refs/heads/master
c: 5ba5a5d
h: refs/heads/master
v: v3
  • Loading branch information
Paul Fulghum authored and Linus Torvalds committed Jun 11, 2009
1 parent 8fdfbfb commit 249bc0a
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 739e0285cbb162c8ddd0061fda581ee54a34c19a
refs/heads/master: 5ba5a5d21204f61ff655b322a90ed91c75194e4b
77 changes: 68 additions & 9 deletions trunk/drivers/char/synclink_gt.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ struct slgt_desc
#define set_desc_next(a,b) (a).next = cpu_to_le32((unsigned int)(b))
#define set_desc_count(a,b)(a).count = cpu_to_le16((unsigned short)(b))
#define set_desc_eof(a,b) (a).status = cpu_to_le16((b) ? (le16_to_cpu((a).status) | BIT0) : (le16_to_cpu((a).status) & ~BIT0))
#define set_desc_status(a, b) (a).status = cpu_to_le16((unsigned short)(b))
#define desc_count(a) (le16_to_cpu((a).count))
#define desc_status(a) (le16_to_cpu((a).status))
#define desc_complete(a) (le16_to_cpu((a).status) & BIT15)
Expand Down Expand Up @@ -297,6 +298,7 @@ struct slgt_info {
u32 max_frame_size; /* as set by device config */

unsigned int rbuf_fill_level;
unsigned int rx_pio;
unsigned int if_mode;
unsigned int base_clock;

Expand Down Expand Up @@ -331,6 +333,8 @@ struct slgt_info {
struct slgt_desc *rbufs;
unsigned int rbuf_current;
unsigned int rbuf_index;
unsigned int rbuf_fill_index;
unsigned short rbuf_fill_count;

unsigned int tbuf_count;
struct slgt_desc *tbufs;
Expand Down Expand Up @@ -2110,6 +2114,40 @@ static void ri_change(struct slgt_info *info, unsigned short status)
info->pending_bh |= BH_STATUS;
}

static void isr_rxdata(struct slgt_info *info)
{
unsigned int count = info->rbuf_fill_count;
unsigned int i = info->rbuf_fill_index;
unsigned short reg;

while (rd_reg16(info, SSR) & IRQ_RXDATA) {
reg = rd_reg16(info, RDR);
DBGISR(("isr_rxdata %s RDR=%04X\n", info->device_name, reg));
if (desc_complete(info->rbufs[i])) {
/* all buffers full */
rx_stop(info);
info->rx_restart = 1;
continue;
}
info->rbufs[i].buf[count++] = (unsigned char)reg;
/* async mode saves status byte to buffer for each data byte */
if (info->params.mode == MGSL_MODE_ASYNC)
info->rbufs[i].buf[count++] = (unsigned char)(reg >> 8);
if (count == info->rbuf_fill_level || (reg & BIT10)) {
/* buffer full or end of frame */
set_desc_count(info->rbufs[i], count);
set_desc_status(info->rbufs[i], BIT15 | (reg >> 8));
info->rbuf_fill_count = count = 0;
if (++i == info->rbuf_count)
i = 0;
info->pending_bh |= BH_RECEIVE;
}
}

info->rbuf_fill_index = i;
info->rbuf_fill_count = count;
}

static void isr_serial(struct slgt_info *info)
{
unsigned short status = rd_reg16(info, SSR);
Expand All @@ -2125,6 +2163,8 @@ static void isr_serial(struct slgt_info *info)
if (info->tx_count)
isr_txeom(info, status);
}
if (info->rx_pio && (status & IRQ_RXDATA))
isr_rxdata(info);
if ((status & IRQ_RXBREAK) && (status & RXBREAK)) {
info->icount.brk++;
/* process break detection if tty control allows */
Expand All @@ -2141,7 +2181,8 @@ static void isr_serial(struct slgt_info *info)
} else {
if (status & (IRQ_TXIDLE + IRQ_TXUNDER))
isr_txeom(info, status);

if (info->rx_pio && (status & IRQ_RXDATA))
isr_rxdata(info);
if (status & IRQ_RXIDLE) {
if (status & RXIDLE)
info->icount.rxidle++;
Expand Down Expand Up @@ -2642,6 +2683,10 @@ static int rx_enable(struct slgt_info *info, int enable)
return -EINVAL;
}
info->rbuf_fill_level = rbuf_fill_level;
if (rbuf_fill_level < 128)
info->rx_pio = 1; /* PIO mode */
else
info->rx_pio = 0; /* DMA mode */
rx_stop(info); /* restart receiver to use new fill level */
}

Expand Down Expand Up @@ -3844,15 +3889,27 @@ static void rx_start(struct slgt_info *info)
rdma_reset(info);
reset_rbufs(info);

/* set 1st descriptor address */
wr_reg32(info, RDDAR, info->rbufs[0].pdesc);

if (info->params.mode != MGSL_MODE_ASYNC) {
/* enable rx DMA and DMA interrupt */
wr_reg32(info, RDCSR, (BIT2 + BIT0));
if (info->rx_pio) {
/* rx request when rx FIFO not empty */
wr_reg16(info, SCR, (unsigned short)(rd_reg16(info, SCR) & ~BIT14));
slgt_irq_on(info, IRQ_RXDATA);
if (info->params.mode == MGSL_MODE_ASYNC) {
/* enable saving of rx status */
wr_reg32(info, RDCSR, BIT6);
}
} else {
/* enable saving of rx status, rx DMA and DMA interrupt */
wr_reg32(info, RDCSR, (BIT6 + BIT2 + BIT0));
/* rx request when rx FIFO half full */
wr_reg16(info, SCR, (unsigned short)(rd_reg16(info, SCR) | BIT14));
/* set 1st descriptor address */
wr_reg32(info, RDDAR, info->rbufs[0].pdesc);

if (info->params.mode != MGSL_MODE_ASYNC) {
/* enable rx DMA and DMA interrupt */
wr_reg32(info, RDCSR, (BIT2 + BIT0));
} else {
/* enable saving of rx status, rx DMA and DMA interrupt */
wr_reg32(info, RDCSR, (BIT6 + BIT2 + BIT0));
}
}

slgt_irq_on(info, IRQ_RXOVER);
Expand Down Expand Up @@ -4470,6 +4527,8 @@ static void free_rbufs(struct slgt_info *info, unsigned int i, unsigned int last
static void reset_rbufs(struct slgt_info *info)
{
free_rbufs(info, 0, info->rbuf_count - 1);
info->rbuf_fill_index = 0;
info->rbuf_fill_count = 0;
}

/*
Expand Down

0 comments on commit 249bc0a

Please sign in to comment.