Commit dabe2c13 authored by Jiri Slaby's avatar Jiri Slaby Committed by Greg Kroah-Hartman

cyclades: push down tty_port_tty_get

Now, the tty is not needed at all places in the ISR. So we can just
request in on demand when really needed.

This cleans TX and RX paths a bit as the indentation level can be
dropped by two now when we also invert the char_count if condition.
Signed-off-by: default avatarJiri Slaby <jslaby@suse.cz>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 6732c8bb
...@@ -917,7 +917,7 @@ cyz_issue_cmd(struct cyclades_card *cinfo, ...@@ -917,7 +917,7 @@ cyz_issue_cmd(struct cyclades_card *cinfo,
return 0; return 0;
} /* cyz_issue_cmd */ } /* cyz_issue_cmd */
static void cyz_handle_rx(struct cyclades_port *info, struct tty_struct *tty) static void cyz_handle_rx(struct cyclades_port *info)
{ {
struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl; struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl;
struct cyclades_card *cinfo = info->card; struct cyclades_card *cinfo = info->card;
...@@ -940,80 +940,77 @@ static void cyz_handle_rx(struct cyclades_port *info, struct tty_struct *tty) ...@@ -940,80 +940,77 @@ static void cyz_handle_rx(struct cyclades_port *info, struct tty_struct *tty)
else else
char_count = rx_put - rx_get + rx_bufsize; char_count = rx_put - rx_get + rx_bufsize;
if (char_count) { if (!char_count)
return;
#ifdef CY_ENABLE_MONITORING #ifdef CY_ENABLE_MONITORING
info->mon.int_count++; info->mon.int_count++;
info->mon.char_count += char_count; info->mon.char_count += char_count;
if (char_count > info->mon.char_max) if (char_count > info->mon.char_max)
info->mon.char_max = char_count; info->mon.char_max = char_count;
info->mon.char_last = char_count; info->mon.char_last = char_count;
#endif #endif
if (tty == NULL) {
/* flush received characters */
new_rx_get = (new_rx_get + char_count) &
(rx_bufsize - 1);
info->rflush_count++;
} else {
#ifdef BLOCKMOVE #ifdef BLOCKMOVE
/* we'd like to use memcpy(t, f, n) and memset(s, c, count) /* we'd like to use memcpy(t, f, n) and memset(s, c, count)
for performance, but because of buffer boundaries, there for performance, but because of buffer boundaries, there
may be several steps to the operation */ may be several steps to the operation */
while (1) { while (1) {
len = tty_prepare_flip_string(port, &buf, len = tty_prepare_flip_string(port, &buf,
char_count); char_count);
if (!len) if (!len)
break; break;
len = min_t(unsigned int, min(len, char_count), len = min_t(unsigned int, min(len, char_count),
rx_bufsize - new_rx_get); rx_bufsize - new_rx_get);
memcpy_fromio(buf, cinfo->base_addr + memcpy_fromio(buf, cinfo->base_addr +
rx_bufaddr + new_rx_get, len); rx_bufaddr + new_rx_get, len);
new_rx_get = (new_rx_get + len) & new_rx_get = (new_rx_get + len) &
(rx_bufsize - 1); (rx_bufsize - 1);
char_count -= len; char_count -= len;
info->icount.rx += len; info->icount.rx += len;
info->idle_stats.recv_bytes += len; info->idle_stats.recv_bytes += len;
} }
#else #else
len = tty_buffer_request_room(port, char_count); len = tty_buffer_request_room(port, char_count);
while (len--) { while (len--) {
data = readb(cinfo->base_addr + rx_bufaddr + data = readb(cinfo->base_addr + rx_bufaddr +
new_rx_get); new_rx_get);
new_rx_get = (new_rx_get + 1) & new_rx_get = (new_rx_get + 1) &
(rx_bufsize - 1); (rx_bufsize - 1);
tty_insert_flip_char(port, data, TTY_NORMAL); tty_insert_flip_char(port, data, TTY_NORMAL);
info->idle_stats.recv_bytes++; info->idle_stats.recv_bytes++;
info->icount.rx++; info->icount.rx++;
} }
#endif #endif
#ifdef CONFIG_CYZ_INTR #ifdef CONFIG_CYZ_INTR
/* Recalculate the number of chars in the RX buffer and issue /* Recalculate the number of chars in the RX buffer and issue
a cmd in case it's higher than the RX high water mark */ a cmd in case it's higher than the RX high water mark */
rx_put = readl(&buf_ctrl->rx_put); rx_put = readl(&buf_ctrl->rx_put);
if (rx_put >= rx_get) if (rx_put >= rx_get)
char_count = rx_put - rx_get; char_count = rx_put - rx_get;
else else
char_count = rx_put - rx_get + rx_bufsize; char_count = rx_put - rx_get + rx_bufsize;
if (char_count >= readl(&buf_ctrl->rx_threshold) && if (char_count >= readl(&buf_ctrl->rx_threshold) &&
!timer_pending(&cyz_rx_full_timer[ !timer_pending(&cyz_rx_full_timer[
info->line])) info->line]))
mod_timer(&cyz_rx_full_timer[info->line], mod_timer(&cyz_rx_full_timer[info->line],
jiffies + 1); jiffies + 1);
#endif #endif
info->idle_stats.recv_idle = jiffies; info->idle_stats.recv_idle = jiffies;
tty_schedule_flip(&info->port); tty_schedule_flip(&info->port);
}
/* Update rx_get */ /* Update rx_get */
cy_writel(&buf_ctrl->rx_get, new_rx_get); cy_writel(&buf_ctrl->rx_get, new_rx_get);
}
} }
static void cyz_handle_tx(struct cyclades_port *info, struct tty_struct *tty) static void cyz_handle_tx(struct cyclades_port *info)
{ {
struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl; struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl;
struct cyclades_card *cinfo = info->card; struct cyclades_card *cinfo = info->card;
struct tty_struct *tty;
u8 data; u8 data;
unsigned int char_count; unsigned int char_count;
#ifdef BLOCKMOVE #ifdef BLOCKMOVE
...@@ -1033,63 +1030,63 @@ static void cyz_handle_tx(struct cyclades_port *info, struct tty_struct *tty) ...@@ -1033,63 +1030,63 @@ static void cyz_handle_tx(struct cyclades_port *info, struct tty_struct *tty)
else else
char_count = tx_get - tx_put - 1; char_count = tx_get - tx_put - 1;
if (char_count) { if (!char_count)
return;
if (tty == NULL)
goto ztxdone; tty = tty_port_tty_get(&info->port);
if (tty == NULL)
goto ztxdone;
if (info->x_char) { /* send special char */ if (info->x_char) { /* send special char */
data = info->x_char; data = info->x_char;
cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data); cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data);
tx_put = (tx_put + 1) & (tx_bufsize - 1); tx_put = (tx_put + 1) & (tx_bufsize - 1);
info->x_char = 0; info->x_char = 0;
char_count--; char_count--;
info->icount.tx++; info->icount.tx++;
} }
#ifdef BLOCKMOVE #ifdef BLOCKMOVE
while (0 < (small_count = min_t(unsigned int, while (0 < (small_count = min_t(unsigned int,
tx_bufsize - tx_put, min_t(unsigned int, tx_bufsize - tx_put, min_t(unsigned int,
(SERIAL_XMIT_SIZE - info->xmit_tail), (SERIAL_XMIT_SIZE - info->xmit_tail),
min_t(unsigned int, info->xmit_cnt, min_t(unsigned int, info->xmit_cnt,
char_count))))) { char_count))))) {
memcpy_toio((char *)(cinfo->base_addr + tx_bufaddr + memcpy_toio((char *)(cinfo->base_addr + tx_bufaddr + tx_put),
tx_put), &info->port.xmit_buf[info->xmit_tail],
&info->port.xmit_buf[info->xmit_tail], small_count);
small_count);
tx_put = (tx_put + small_count) & (tx_bufsize - 1);
tx_put = (tx_put + small_count) & (tx_bufsize - 1); char_count -= small_count;
char_count -= small_count; info->icount.tx += small_count;
info->icount.tx += small_count; info->xmit_cnt -= small_count;
info->xmit_cnt -= small_count; info->xmit_tail = (info->xmit_tail + small_count) &
info->xmit_tail = (info->xmit_tail + small_count) & (SERIAL_XMIT_SIZE - 1);
(SERIAL_XMIT_SIZE - 1); }
}
#else #else
while (info->xmit_cnt && char_count) { while (info->xmit_cnt && char_count) {
data = info->port.xmit_buf[info->xmit_tail]; data = info->port.xmit_buf[info->xmit_tail];
info->xmit_cnt--; info->xmit_cnt--;
info->xmit_tail = (info->xmit_tail + 1) & info->xmit_tail = (info->xmit_tail + 1) &
(SERIAL_XMIT_SIZE - 1); (SERIAL_XMIT_SIZE - 1);
cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data); cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data);
tx_put = (tx_put + 1) & (tx_bufsize - 1); tx_put = (tx_put + 1) & (tx_bufsize - 1);
char_count--; char_count--;
info->icount.tx++; info->icount.tx++;
} }
#endif #endif
tty_wakeup(tty); tty_wakeup(tty);
tty_kref_put(tty);
ztxdone: ztxdone:
/* Update tx_put */ /* Update tx_put */
cy_writel(&buf_ctrl->tx_put, tx_put); cy_writel(&buf_ctrl->tx_put, tx_put);
}
} }
static void cyz_handle_cmd(struct cyclades_card *cinfo) static void cyz_handle_cmd(struct cyclades_card *cinfo)
{ {
struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl; struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl;
struct tty_struct *tty;
struct cyclades_port *info; struct cyclades_port *info;
__u32 channel, param, fw_ver; __u32 channel, param, fw_ver;
__u8 cmd; __u8 cmd;
...@@ -1102,9 +1099,6 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) ...@@ -1102,9 +1099,6 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
special_count = 0; special_count = 0;
delta_count = 0; delta_count = 0;
info = &cinfo->ports[channel]; info = &cinfo->ports[channel];
tty = tty_port_tty_get(&info->port);
if (tty == NULL)
continue;
switch (cmd) { switch (cmd) {
case C_CM_PR_ERROR: case C_CM_PR_ERROR:
...@@ -1130,8 +1124,14 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) ...@@ -1130,8 +1124,14 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
readl(&info->u.cyz.ch_ctrl->rs_status); readl(&info->u.cyz.ch_ctrl->rs_status);
if (dcd & C_RS_DCD) if (dcd & C_RS_DCD)
wake_up_interruptible(&info->port.open_wait); wake_up_interruptible(&info->port.open_wait);
else else {
tty_hangup(tty); struct tty_struct *tty;
tty = tty_port_tty_get(&info->port);
if (tty) {
tty_hangup(tty);
tty_kref_put(tty);
}
}
} }
break; break;
case C_CM_MCTS: case C_CM_MCTS:
...@@ -1160,7 +1160,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) ...@@ -1160,7 +1160,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, " printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, "
"port %ld\n", info->card, channel); "port %ld\n", info->card, channel);
#endif #endif
cyz_handle_rx(info, tty); cyz_handle_rx(info);
break; break;
case C_CM_TXBEMPTY: case C_CM_TXBEMPTY:
case C_CM_TXLOWWM: case C_CM_TXLOWWM:
...@@ -1170,7 +1170,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) ...@@ -1170,7 +1170,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, " printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, "
"port %ld\n", info->card, channel); "port %ld\n", info->card, channel);
#endif #endif
cyz_handle_tx(info, tty); cyz_handle_tx(info);
break; break;
#endif /* CONFIG_CYZ_INTR */ #endif /* CONFIG_CYZ_INTR */
case C_CM_FATAL: case C_CM_FATAL:
...@@ -1183,7 +1183,6 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) ...@@ -1183,7 +1183,6 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
wake_up_interruptible(&info->port.delta_msr_wait); wake_up_interruptible(&info->port.delta_msr_wait);
if (special_count) if (special_count)
tty_schedule_flip(&info->port); tty_schedule_flip(&info->port);
tty_kref_put(tty);
} }
} }
...@@ -1249,17 +1248,11 @@ static void cyz_poll(unsigned long arg) ...@@ -1249,17 +1248,11 @@ static void cyz_poll(unsigned long arg)
cyz_handle_cmd(cinfo); cyz_handle_cmd(cinfo);
for (port = 0; port < cinfo->nports; port++) { for (port = 0; port < cinfo->nports; port++) {
struct tty_struct *tty;
info = &cinfo->ports[port]; info = &cinfo->ports[port];
tty = tty_port_tty_get(&info->port);
/* OK to pass NULL to the handle functions below.
They need to drop the data in that case. */
if (!info->throttle) if (!info->throttle)
cyz_handle_rx(info, tty); cyz_handle_rx(info);
cyz_handle_tx(info, tty); cyz_handle_tx(info);
tty_kref_put(tty);
} }
/* poll every 'cyz_polling_cycle' period */ /* poll every 'cyz_polling_cycle' period */
expires = jiffies + cyz_polling_cycle; expires = jiffies + cyz_polling_cycle;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment