1
0
Fork 0

Char: cyclades, make the isr code readable

Due to large indent the code was wrapped and unreadable.  Create 3 function
instead of one and reorder the code, so it is readable now.

Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
hifive-unleashed-5.1
Jiri Slaby 2007-10-18 03:06:21 -07:00 committed by Linus Torvalds
parent ebafeeff0f
commit ce97a09767
1 changed files with 294 additions and 327 deletions

View File

@ -980,17 +980,16 @@ static unsigned detect_isa_irq(void __iomem * address)
}
#endif /* CONFIG_ISA */
static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
void __iomem * base_addr, int status, int index)
static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
void __iomem *base_addr)
{
struct cyclades_port *info;
struct tty_struct *tty;
int char_count;
int j, len, mdm_change, mdm_status, outch;
int j, len, index = cinfo->bus_index;
int save_xir, channel, save_car;
char data;
if (status & CySRReceive) { /* reception interrupt */
#ifdef CY_DEBUG_INTERRUPTS
printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip);
#endif
@ -1004,22 +1003,19 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
/* if there is nowhere to put the data, discard it */
if (info->tty == NULL) {
j = (readb(base_addr + (CyRIVR << index)) &
CyIVRMask);
j = (readb(base_addr + (CyRIVR << index)) & CyIVRMask);
if (j == CyIVRRxEx) { /* exception */
data = readb(base_addr + (CyRDSR << index));
} else { /* normal character reception */
char_count = readb(base_addr +
(CyRDCR << index));
while (char_count--) {
data = readb(base_addr +
(CyRDSR << index));
char_count = readb(base_addr + (CyRDCR << index));
while (char_count--)
data = readb(base_addr + (CyRDSR << index));
}
goto end;
}
} else { /* there is an open port for this data */
/* there is an open port for this data */
tty = info->tty;
j = (readb(base_addr + (CyRIVR << index)) &
CyIVRMask);
j = readb(base_addr + (CyRIVR << index)) & CyIVRMask;
if (j == CyIVRRxEx) { /* exception */
data = readb(base_addr + (CyRDSR << index));
@ -1041,86 +1037,60 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
if (tty_buffer_request_room(tty, 1)) {
if (data & info->read_status_mask) {
if (data & CyBREAK) {
tty_insert_flip_char(
tty,
readb(
base_addr +
(CyRDSR <<
index)),
TTY_BREAK);
tty_insert_flip_char(tty,
readb(base_addr + (CyRDSR <<
index)), TTY_BREAK);
info->icount.rx++;
if (info->flags &
ASYNC_SAK) {
if (info->flags & ASYNC_SAK)
do_SAK(tty);
}
} else if (data & CyFRAME) {
tty_insert_flip_char(
tty,
readb(
base_addr +
(CyRDSR <<
index)),
TTY_FRAME);
tty_insert_flip_char( tty,
readb(base_addr + (CyRDSR <<
index)), TTY_FRAME);
info->icount.rx++;
info->idle_stats.
frame_errs++;
info->idle_stats.frame_errs++;
} else if (data & CyPARITY) {
/* Pieces of seven... */
tty_insert_flip_char(
tty,
readb(
base_addr +
(CyRDSR <<
index)),
TTY_PARITY);
tty_insert_flip_char(tty,
readb(base_addr + (CyRDSR <<
index)), TTY_PARITY);
info->icount.rx++;
info->idle_stats.
parity_errs++;
info->idle_stats.parity_errs++;
} else if (data & CyOVERRUN) {
tty_insert_flip_char(
tty, 0,
tty_insert_flip_char(tty, 0,
TTY_OVERRUN);
info->icount.rx++;
/* If the flip buffer itself is
overflowing, we still lose
the next incoming character.
*/
tty_insert_flip_char(
tty,
readb(
base_addr +
(CyRDSR <<
index)),
TTY_FRAME);
tty_insert_flip_char(tty,
readb(base_addr + (CyRDSR <<
index)), TTY_FRAME);
info->icount.rx++;
info->idle_stats.
overruns++;
info->idle_stats.overruns++;
/* These two conditions may imply */
/* a normal read should be done. */
/* } else if(data & CyTIMEOUT) { */
/* } else if(data & CySPECHAR) { */
} else {
tty_insert_flip_char(
tty, 0,
TTY_NORMAL);
info->icount.rx++;
}
} else {
tty_insert_flip_char(tty, 0,
TTY_NORMAL);
info->icount.rx++;
}
} else {
/* there was a software buffer
overrun and nothing could be
done about it!!! */
tty_insert_flip_char(tty, 0, TTY_NORMAL);
info->icount.rx++;
}
} else {
/* there was a software buffer overrun and nothing
* could be done about it!!! */
info->icount.buf_overrun++;
info->idle_stats.overruns++;
}
} else { /* normal character reception */
/* load # chars available from the chip */
char_count = readb(base_addr +
(CyRDCR << index));
char_count = readb(base_addr + (CyRDCR << index));
#ifdef CY_ENABLE_MONITORING
++info->mon.int_count;
@ -1131,10 +1101,8 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
#endif
len = tty_buffer_request_room(tty, char_count);
while (len--) {
data = readb(base_addr +
(CyRDSR << index));
tty_insert_flip_char(tty, data,
TTY_NORMAL);
data = readb(base_addr + (CyRDSR << index));
tty_insert_flip_char(tty, data, TTY_NORMAL);
info->idle_stats.recv_bytes++;
info->icount.rx++;
#ifdef CY_16Y_HACK
@ -1144,14 +1112,21 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
info->idle_stats.recv_idle = jiffies;
}
tty_schedule_flip(tty);
}
end:
/* end of service */
cy_writeb(base_addr + (CyRIR << index), (save_xir & 0x3f));
cy_writeb(base_addr + (CyCAR << index), (save_car));
cy_writeb(base_addr + (CyRIR << index), save_xir & 0x3f);
cy_writeb(base_addr + (CyCAR << index), save_car);
spin_unlock(&cinfo->card_lock);
}
if (status & CySRTransmit) { /* transmission interrupt */
static void cyy_chip_tx(struct cyclades_card *cinfo, int chip,
void __iomem *base_addr)
{
struct cyclades_port *info;
int char_count;
int outch;
int save_xir, channel, save_car, index = cinfo->bus_index;
/* Since we only get here when the transmit buffer
is empty, we know we can always stuff a dozen
characters. */
@ -1169,16 +1144,14 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
/* validate the port# (as configured and open) */
if (channel + chip * 4 >= cinfo->nports) {
cy_writeb(base_addr + (CySRER << index),
readb(base_addr + (CySRER << index)) &
~CyTxRdy);
goto txend;
readb(base_addr + (CySRER << index)) & ~CyTxRdy);
goto end;
}
info = &cinfo->ports[channel + chip * 4];
if (info->tty == NULL) {
cy_writeb(base_addr + (CySRER << index),
readb(base_addr + (CySRER << index)) &
~CyTxRdy);
goto txend;
readb(base_addr + (CySRER << index)) & ~CyTxRdy);
goto end;
}
/* load the on-chip space for outbound data */
@ -1209,42 +1182,37 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
while (char_count-- > 0) {
if (!info->xmit_cnt) {
if (readb(base_addr + (CySRER << index)) &
CyTxMpty) {
if (readb(base_addr + (CySRER << index)) & CyTxMpty) {
cy_writeb(base_addr + (CySRER << index),
readb(base_addr +
(CySRER << index)) &
readb(base_addr + (CySRER << index)) &
~CyTxMpty);
} else {
cy_writeb(base_addr + (CySRER << index),
(readb(base_addr +
(CySRER << index)) &
(readb(base_addr + (CySRER << index)) &
~CyTxRdy) | CyTxMpty);
}
goto txdone;
goto done;
}
if (info->xmit_buf == NULL) {
cy_writeb(base_addr + (CySRER << index),
readb(base_addr + (CySRER << index)) &
~CyTxRdy);
goto txdone;
goto done;
}
if (info->tty->stopped || info->tty->hw_stopped) {
cy_writeb(base_addr + (CySRER << index),
readb(base_addr + (CySRER << index)) &
~CyTxRdy);
goto txdone;
goto done;
}
/* Because the Embedded Transmit Commands have
been enabled, we must check to see if the
escape character, NULL, is being sent. If it
is, we must ensure that there is room for it
to be doubled in the output stream. Therefore
we no longer advance the pointer when the
character is fetched, but rather wait until
after the check for a NULL output character.
This is necessary because there may not be
room for the two chars needed to send a NULL.)
/* Because the Embedded Transmit Commands have been enabled,
* we must check to see if the escape character, NULL, is being
* sent. If it is, we must ensure that there is room for it to
* be doubled in the output stream. Therefore we no longer
* advance the pointer when the character is fetched, but
* rather wait until after the check for a NULL output
* character. This is necessary because there may not be room
* for the two chars needed to send a NULL.)
*/
outch = info->xmit_buf[info->xmit_tail];
if (outch) {
@ -1258,26 +1226,29 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
info->xmit_cnt--;
info->xmit_tail = (info->xmit_tail + 1) &
(SERIAL_XMIT_SIZE - 1);
cy_writeb(base_addr + (CyTDR << index),
outch);
cy_writeb(base_addr + (CyTDR << index),
0);
cy_writeb(base_addr + (CyTDR << index), outch);
cy_writeb(base_addr + (CyTDR << index), 0);
info->icount.tx++;
char_count--;
}
}
}
txdone:
done:
tty_wakeup(info->tty);
txend:
end:
/* end of service */
cy_writeb(base_addr + (CyTIR << index), (save_xir & 0x3f));
cy_writeb(base_addr + (CyCAR << index), (save_car));
cy_writeb(base_addr + (CyTIR << index), save_xir & 0x3f);
cy_writeb(base_addr + (CyCAR << index), save_car);
spin_unlock(&cinfo->card_lock);
}
if (status & CySRModem) { /* modem interrupt */
static void cyy_chip_modem(struct cyclades_card *cinfo, int chip,
void __iomem *base_addr)
{
struct cyclades_port *info;
int mdm_change, mdm_status;
int save_xir, channel, save_car, index = cinfo->bus_index;
/* determine the channel & change to that context */
spin_lock(&cinfo->card_lock);
@ -1290,7 +1261,9 @@ txend:
mdm_change = readb(base_addr + (CyMISR << index));
mdm_status = readb(base_addr + (CyMSVR1 << index));
if (info->tty) {
if (!info->tty)
goto end;
if (mdm_change & CyANY_DELTA) {
/* For statistics only */
if (mdm_change & CyDCD)
@ -1305,26 +1278,21 @@ txend:
wake_up_interruptible(&info->delta_msr_wait);
}
if ((mdm_change & CyDCD) &&
(info->flags & ASYNC_CHECK_CD)) {
if ((mdm_change & CyDCD) && (info->flags & ASYNC_CHECK_CD)) {
if (!(mdm_status & CyDCD)) {
tty_hangup(info->tty);
info->flags &= ~ASYNC_NORMAL_ACTIVE;
}
wake_up_interruptible(&info->open_wait);
}
if ((mdm_change & CyCTS) &&
(info->flags & ASYNC_CTS_FLOW)) {
if ((mdm_change & CyCTS) && (info->flags & ASYNC_CTS_FLOW)) {
if (info->tty->hw_stopped) {
if (mdm_status & CyCTS) {
/* cy_start isn't used
because... !!! */
info->tty->hw_stopped = 0;
cy_writeb(base_addr +
(CySRER << index),
readb(base_addr +
(CySRER <<
index))|
cy_writeb(base_addr + (CySRER << index),
readb(base_addr + (CySRER << index)) |
CyTxRdy);
tty_wakeup(info->tty);
}
@ -1333,11 +1301,8 @@ txend:
/* cy_stop isn't used
because ... !!! */
info->tty->hw_stopped = 1;
cy_writeb(base_addr +
(CySRER << index),
readb(base_addr +
(CySRER <<
index)) &
cy_writeb(base_addr + (CySRER << index),
readb(base_addr + (CySRER << index)) &
~CyTxRdy);
}
}
@ -1346,13 +1311,12 @@ txend:
}
if (mdm_change & CyRI) {
}*/
}
end:
/* end of service */
cy_writeb(base_addr + (CyMIR << index), (save_xir & 0x3f));
cy_writeb(base_addr + (CyMIR << index), save_xir & 0x3f);
cy_writeb(base_addr + (CyCAR << index), save_car);
spin_unlock(&cinfo->card_lock);
}
}
/* The real interrupt service routine is called
whenever the card wants its hand held--chars
@ -1401,11 +1365,14 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id)
chips to be checked in a round-robin fashion (after
draining each of a bunch (1000) of characters).
*/
if (1000 < too_many++) {
if (1000 < too_many++)
break;
}
cyy_intr_chip(cinfo, chip, base_addr, status,
index);
if (status & CySRReceive) /* rx intr */
cyy_chip_rx(cinfo, chip, base_addr);
if (status & CySRTransmit) /* tx intr */
cyy_chip_tx(cinfo, chip, base_addr);
if (status & CySRModem) /* modem intr */
cyy_chip_modem(cinfo, chip, base_addr);
}
}
} while (had_work);