提交 51808f05 编写于 作者: A Alexander Shishkin 提交者: Greg Kroah-Hartman

max3110: add sysrq support

This patch moves several occurences of similar code inside receive_chars(),
which now also takes care of checking for break and calling sysrq handling
code.
Signed-off-by: NAlexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: NAlan Cox <alan@linux.intel.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
上级 efe3ed98
...@@ -27,6 +27,10 @@ ...@@ -27,6 +27,10 @@
* interrupt for a low speed UART device * interrupt for a low speed UART device
*/ */
#ifdef CONFIG_MAGIC_SYSRQ
#define SUPPORT_SYSRQ
#endif
#include <linux/module.h> #include <linux/module.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/irq.h> #include <linux/irq.h>
...@@ -73,9 +77,9 @@ struct uart_max3110 { ...@@ -73,9 +77,9 @@ struct uart_max3110 {
/* global data structure, may need be removed */ /* global data structure, may need be removed */
static struct uart_max3110 *pmax; static struct uart_max3110 *pmax;
static void receive_chars(struct uart_max3110 *max, static int receive_chars(struct uart_max3110 *max,
unsigned char *str, int len); unsigned short *str, int len);
static int max3110_read_multi(struct uart_max3110 *max, u8 *buf); static int max3110_read_multi(struct uart_max3110 *max);
static void max3110_con_receive(struct uart_max3110 *max); static void max3110_con_receive(struct uart_max3110 *max);
static int max3110_write_then_read(struct uart_max3110 *max, static int max3110_write_then_read(struct uart_max3110 *max,
...@@ -108,7 +112,6 @@ static int max3110_out(struct uart_max3110 *max, const u16 out) ...@@ -108,7 +112,6 @@ static int max3110_out(struct uart_max3110 *max, const u16 out)
{ {
void *buf; void *buf;
u16 *obuf, *ibuf; u16 *obuf, *ibuf;
u8 ch;
int ret; int ret;
buf = kzalloc(8, GFP_KERNEL | GFP_DMA); buf = kzalloc(8, GFP_KERNEL | GFP_DMA);
...@@ -125,11 +128,7 @@ static int max3110_out(struct uart_max3110 *max, const u16 out) ...@@ -125,11 +128,7 @@ static int max3110_out(struct uart_max3110 *max, const u16 out)
goto exit; goto exit;
} }
/* If some valid data is read back */ receive_chars(max, ibuf, 1);
if (*ibuf & MAX3110_READ_DATA_AVAILABLE) {
ch = *ibuf & 0xff;
receive_chars(max, &ch, 1);
}
exit: exit:
kfree(buf); kfree(buf);
...@@ -142,12 +141,11 @@ static int max3110_out(struct uart_max3110 *max, const u16 out) ...@@ -142,12 +141,11 @@ static int max3110_out(struct uart_max3110 *max, const u16 out)
* *
* Return how many valide bytes are read back * Return how many valide bytes are read back
*/ */
static int max3110_read_multi(struct uart_max3110 *max, u8 *rxbuf) static int max3110_read_multi(struct uart_max3110 *max)
{ {
void *buf; void *buf;
u16 *obuf, *ibuf; u16 *obuf, *ibuf;
u8 *pbuf, valid_str[M3110_RX_FIFO_DEPTH]; int ret, blen;
int i, j, blen;
blen = M3110_RX_FIFO_DEPTH * sizeof(u16); blen = M3110_RX_FIFO_DEPTH * sizeof(u16);
buf = kzalloc(blen * 2, GFP_KERNEL | GFP_DMA); buf = kzalloc(blen * 2, GFP_KERNEL | GFP_DMA);
...@@ -165,19 +163,10 @@ static int max3110_read_multi(struct uart_max3110 *max, u8 *rxbuf) ...@@ -165,19 +163,10 @@ static int max3110_read_multi(struct uart_max3110 *max, u8 *rxbuf)
return 0; return 0;
} }
/* If caller doesn't provide a buffer, then handle received char */ ret = receive_chars(max, ibuf, M3110_RX_FIFO_DEPTH);
pbuf = rxbuf ? rxbuf : valid_str;
for (i = 0, j = 0; i < M3110_RX_FIFO_DEPTH; i++) {
if (ibuf[i] & MAX3110_READ_DATA_AVAILABLE)
pbuf[j++] = ibuf[i] & 0xff;
}
if (j && (pbuf == valid_str))
receive_chars(max, valid_str, j);
kfree(buf); kfree(buf);
return j; return ret;
} }
static void serial_m3110_con_putchar(struct uart_port *port, int ch) static void serial_m3110_con_putchar(struct uart_port *port, int ch)
...@@ -276,8 +265,7 @@ static void send_circ_buf(struct uart_max3110 *max, ...@@ -276,8 +265,7 @@ static void send_circ_buf(struct uart_max3110 *max,
{ {
void *buf; void *buf;
u16 *obuf, *ibuf; u16 *obuf, *ibuf;
u8 valid_str[WORDS_PER_XFER]; int i, len, blen, dma_size, left, ret = 0;
int i, j, len, blen, dma_size, left, ret = 0;
dma_size = WORDS_PER_XFER * sizeof(u16) * 2; dma_size = WORDS_PER_XFER * sizeof(u16) * 2;
...@@ -307,13 +295,7 @@ static void send_circ_buf(struct uart_max3110 *max, ...@@ -307,13 +295,7 @@ static void send_circ_buf(struct uart_max3110 *max,
pr_warning(PR_FMT "%s(): get err msg %d\n", pr_warning(PR_FMT "%s(): get err msg %d\n",
__func__, ret); __func__, ret);
for (i = 0, j = 0; i < len; i++) { receive_chars(max, ibuf, len);
if (ibuf[i] & MAX3110_READ_DATA_AVAILABLE)
valid_str[j++] = ibuf[i] & 0xff;
}
if (j)
receive_chars(max, valid_str, j);
max->port.icount.tx += len; max->port.icount.tx += len;
left -= len; left -= len;
...@@ -353,30 +335,48 @@ static void serial_m3110_start_tx(struct uart_port *port) ...@@ -353,30 +335,48 @@ static void serial_m3110_start_tx(struct uart_port *port)
wake_up(&max->wq); wake_up(&max->wq);
} }
static void receive_chars(struct uart_max3110 *max, unsigned char *str, int len) static int
receive_chars(struct uart_max3110 *max, unsigned short *str, int len)
{ {
struct uart_port *port = &max->port; struct uart_port *port = &max->port;
struct tty_struct *tty; struct tty_struct *tty;
int usable; char buf[M3110_RX_FIFO_DEPTH];
int r, w, usable;
/* If uart is not opened, just return */ /* If uart is not opened, just return */
if (!port->state) if (!port->state)
return; return 0;
tty = port->state->port.tty; tty = port->state->port.tty;
if (!tty) if (!tty)
return; return 0;
for (r = 0, w = 0; r < len; r++) {
if (str[r] & MAX3110_BREAK &&
uart_handle_break(port))
continue;
if (str[r] & MAX3110_READ_DATA_AVAILABLE) {
if (uart_handle_sysrq_char(port, str[r] & 0xff))
continue;
buf[w++] = str[r] & 0xff;
}
}
while (len) { if (!w)
usable = tty_buffer_request_room(tty, len); return 0;
for (r = 0; w; r += usable, w -= usable) {
usable = tty_buffer_request_room(tty, w);
if (usable) { if (usable) {
tty_insert_flip_string(tty, str, usable); tty_insert_flip_string(tty, buf + r, usable);
str += usable;
port->icount.rx += usable; port->icount.rx += usable;
} }
len -= usable;
} }
tty_flip_buffer_push(tty); tty_flip_buffer_push(tty);
return r;
} }
/* /*
...@@ -391,28 +391,15 @@ static void receive_chars(struct uart_max3110 *max, unsigned char *str, int len) ...@@ -391,28 +391,15 @@ static void receive_chars(struct uart_max3110 *max, unsigned char *str, int len)
*/ */
static void max3110_con_receive(struct uart_max3110 *max) static void max3110_con_receive(struct uart_max3110 *max)
{ {
int loop = 1, num, total = 0; int loop = 1, num;
u8 recv_buf[512], *pbuf;
pbuf = recv_buf;
do { do {
num = max3110_read_multi(max, pbuf); num = max3110_read_multi(max);
if (num) { if (num) {
loop = 5; loop = 5;
pbuf += num;
total += num;
if (total >= 504) {
receive_chars(max, recv_buf, total);
pbuf = recv_buf;
total = 0;
}
} }
} while (--loop); } while (--loop);
if (total)
receive_chars(max, recv_buf, total);
} }
static int max3110_main_thread(void *_max) static int max3110_main_thread(void *_max)
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
/* status bits for all 4 MAX3110 operate modes */ /* status bits for all 4 MAX3110 operate modes */
#define MAX3110_READ_DATA_AVAILABLE (1 << 15) #define MAX3110_READ_DATA_AVAILABLE (1 << 15)
#define MAX3110_WRITE_BUF_EMPTY (1 << 14) #define MAX3110_WRITE_BUF_EMPTY (1 << 14)
#define MAX3110_BREAK (1 << 10)
#define WC_TAG (3 << 14) #define WC_TAG (3 << 14)
#define RC_TAG (1 << 14) #define RC_TAG (1 << 14)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册