* [PATCH 1/4] max3110: wake up fixes
@ 2011-08-26 10:24 Alan Cox
2011-08-26 10:25 ` [PATCH 2/4] x86/mrst: Add platform data for Max3110 devices Alan Cox
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Alan Cox @ 2011-08-26 10:24 UTC (permalink / raw)
To: greg, linux-serial
From: Dirk Brandewie <dirk.brandewie@gmail.com>
The main thread is waiting on on a wait_queue but wake_up_process() is
used to wake the thread. This reads weirdly. Change wake_up_process() to
wake_up().
Tested on the Moorestown tablet build
Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>
Signed-off-by: Alan Cox <alan@linux.intel.com>
---
drivers/tty/serial/mrst_max3110.c | 11 +++++++----
1 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/tty/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c
index 23bc743..9c2cd8c 100644
--- a/drivers/tty/serial/mrst_max3110.c
+++ b/drivers/tty/serial/mrst_max3110.c
@@ -207,7 +207,7 @@ static void serial_m3110_con_write(struct console *co,
uart_console_write(&pmax->port, s, count, serial_m3110_con_putchar);
if (!test_and_set_bit(CON_TX_NEEDED, &pmax->uart_flags))
- wake_up_process(pmax->main_thread);
+ wake_up(&pmax->wq);
}
static int __init
@@ -301,6 +301,7 @@ static void send_circ_buf(struct uart_max3110 *max,
}
/* Fail to send msg to console is not very critical */
+
ret = max3110_write_then_read(max, obuf, ibuf, blen, 0);
if (ret)
pr_warning(PR_FMT "%s(): get err msg %d\n",
@@ -349,7 +350,7 @@ static void serial_m3110_start_tx(struct uart_port *port)
container_of(port, struct uart_max3110, port);
if (!test_and_set_bit(UART_TX_NEEDED, &max->uart_flags))
- wake_up_process(max->main_thread);
+ wake_up(&max->wq);
}
static void receive_chars(struct uart_max3110 *max, unsigned char *str, int len)
@@ -424,7 +425,8 @@ static int max3110_main_thread(void *_max)
pr_info(PR_FMT "start main thread\n");
do {
- wait_event_interruptible(*wq, max->uart_flags || kthread_should_stop());
+ wait_event_interruptible(*wq,
+ max->uart_flags || kthread_should_stop());
mutex_lock(&max->thread_mutex);
@@ -452,8 +454,9 @@ static irqreturn_t serial_m3110_irq(int irq, void *dev_id)
/* max3110's irq is a falling edge, not level triggered,
* so no need to disable the irq */
+
if (!test_and_set_bit(BIT_IRQ_PENDING, &max->uart_flags))
- wake_up_process(max->main_thread);
+ wake_up(&max->wq);
return IRQ_HANDLED;
}
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH 2/4] x86/mrst: Add platform data for Max3110 devices 2011-08-26 10:24 [PATCH 1/4] max3110: wake up fixes Alan Cox @ 2011-08-26 10:25 ` Alan Cox 2011-08-26 10:25 ` [PATCH 3/4] max3110: add sysrq support Alan Cox 2011-08-26 10:26 ` [PATCH 4/4] max3110: Fix up port->tty backreferencing Alan Cox 2 siblings, 0 replies; 4+ messages in thread From: Alan Cox @ 2011-08-26 10:25 UTC (permalink / raw) To: greg, linux-serial From: Feng Tang <feng.tang@intel.com> Those info will be used when spi controller driver setup max3110 as a slave device Signed-off-by: Feng Tang <feng.tang@intel.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com> --- arch/x86/platform/mrst/mrst.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/arch/x86/platform/mrst/mrst.c b/arch/x86/platform/mrst/mrst.c index 7000e74..b8da1b9 100644 --- a/arch/x86/platform/mrst/mrst.c +++ b/arch/x86/platform/mrst/mrst.c @@ -14,6 +14,8 @@ #include <linux/init.h> #include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/scatterlist.h> #include <linux/sfi.h> #include <linux/intel_pmic_gpio.h> #include <linux/spi/spi.h> @@ -392,6 +394,7 @@ static void __init *max3111_platform_data(void *info) struct spi_board_info *spi_info = info; int intr = get_gpio_by_name("max3111_int"); + spi_info->mode = SPI_MODE_0; if (intr == -1) return NULL; spi_info->irq = intr + MRST_IRQ_OFFSET; ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3/4] max3110: add sysrq support 2011-08-26 10:24 [PATCH 1/4] max3110: wake up fixes Alan Cox 2011-08-26 10:25 ` [PATCH 2/4] x86/mrst: Add platform data for Max3110 devices Alan Cox @ 2011-08-26 10:25 ` Alan Cox 2011-08-26 10:26 ` [PATCH 4/4] max3110: Fix up port->tty backreferencing Alan Cox 2 siblings, 0 replies; 4+ messages in thread From: Alan Cox @ 2011-08-26 10:25 UTC (permalink / raw) To: greg, linux-serial From: Alexander Shishkin <alexander.shishkin@linux.intel.com> 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: Alexander Shishkin <alexander.shishkin@linux.intel.com> Signed-off-by: Alan Cox <alan@linux.intel.com> --- drivers/tty/serial/mrst_max3110.c | 99 ++++++++++++++++--------------------- drivers/tty/serial/mrst_max3110.h | 1 2 files changed, 44 insertions(+), 56 deletions(-) diff --git a/drivers/tty/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c index 9c2cd8c..4f90411 100644 --- a/drivers/tty/serial/mrst_max3110.c +++ b/drivers/tty/serial/mrst_max3110.c @@ -27,6 +27,10 @@ * interrupt for a low speed UART device */ +#ifdef CONFIG_MAGIC_SYSRQ +#define SUPPORT_SYSRQ +#endif + #include <linux/module.h> #include <linux/ioport.h> #include <linux/irq.h> @@ -73,9 +77,9 @@ struct uart_max3110 { /* global data structure, may need be removed */ static struct uart_max3110 *pmax; -static void receive_chars(struct uart_max3110 *max, - unsigned char *str, int len); -static int max3110_read_multi(struct uart_max3110 *max, u8 *buf); +static int receive_chars(struct uart_max3110 *max, + unsigned short *str, int len); +static int max3110_read_multi(struct uart_max3110 *max); static void max3110_con_receive(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) { void *buf; u16 *obuf, *ibuf; - u8 ch; int ret; buf = kzalloc(8, GFP_KERNEL | GFP_DMA); @@ -125,11 +128,7 @@ static int max3110_out(struct uart_max3110 *max, const u16 out) goto exit; } - /* If some valid data is read back */ - if (*ibuf & MAX3110_READ_DATA_AVAILABLE) { - ch = *ibuf & 0xff; - receive_chars(max, &ch, 1); - } + receive_chars(max, ibuf, 1); exit: kfree(buf); @@ -142,12 +141,11 @@ exit: * * 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; u16 *obuf, *ibuf; - u8 *pbuf, valid_str[M3110_RX_FIFO_DEPTH]; - int i, j, blen; + int ret, blen; blen = M3110_RX_FIFO_DEPTH * sizeof(u16); buf = kzalloc(blen * 2, GFP_KERNEL | GFP_DMA); @@ -165,19 +163,10 @@ static int max3110_read_multi(struct uart_max3110 *max, u8 *rxbuf) return 0; } - /* If caller doesn't provide a buffer, then handle received char */ - 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); + ret = receive_chars(max, ibuf, M3110_RX_FIFO_DEPTH); kfree(buf); - return j; + return ret; } 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, { void *buf; u16 *obuf, *ibuf; - u8 valid_str[WORDS_PER_XFER]; - int i, j, len, blen, dma_size, left, ret = 0; + int i, len, blen, dma_size, left, ret = 0; dma_size = WORDS_PER_XFER * sizeof(u16) * 2; @@ -307,13 +295,7 @@ static void send_circ_buf(struct uart_max3110 *max, pr_warning(PR_FMT "%s(): get err msg %d\n", __func__, ret); - for (i = 0, j = 0; i < len; i++) { - if (ibuf[i] & MAX3110_READ_DATA_AVAILABLE) - valid_str[j++] = ibuf[i] & 0xff; - } - - if (j) - receive_chars(max, valid_str, j); + receive_chars(max, ibuf, len); max->port.icount.tx += len; left -= len; @@ -353,30 +335,48 @@ static void serial_m3110_start_tx(struct uart_port *port) 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 tty_struct *tty; - int usable; + char buf[M3110_RX_FIFO_DEPTH]; + int r, w, usable; /* If uart is not opened, just return */ if (!port->state) - return; + return 0; tty = port->state->port.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) { - usable = tty_buffer_request_room(tty, len); + if (!w) + return 0; + + for (r = 0; w; r += usable, w -= usable) { + usable = tty_buffer_request_room(tty, w); if (usable) { - tty_insert_flip_string(tty, str, usable); - str += usable; + tty_insert_flip_string(tty, buf + r, usable); port->icount.rx += usable; } - len -= usable; } tty_flip_buffer_push(tty); + + return r; } /* @@ -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) { - int loop = 1, num, total = 0; - u8 recv_buf[512], *pbuf; + int loop = 1, num; - pbuf = recv_buf; do { - num = max3110_read_multi(max, pbuf); + num = max3110_read_multi(max); if (num) { loop = 5; - pbuf += num; - total += num; - - if (total >= 504) { - receive_chars(max, recv_buf, total); - pbuf = recv_buf; - total = 0; - } } } while (--loop); - - if (total) - receive_chars(max, recv_buf, total); } static int max3110_main_thread(void *_max) diff --git a/drivers/tty/serial/mrst_max3110.h b/drivers/tty/serial/mrst_max3110.h index c37ea48..35af073 100644 --- a/drivers/tty/serial/mrst_max3110.h +++ b/drivers/tty/serial/mrst_max3110.h @@ -7,6 +7,7 @@ /* status bits for all 4 MAX3110 operate modes */ #define MAX3110_READ_DATA_AVAILABLE (1 << 15) #define MAX3110_WRITE_BUF_EMPTY (1 << 14) +#define MAX3110_BREAK (1 << 10) #define WC_TAG (3 << 14) #define RC_TAG (1 << 14) ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 4/4] max3110: Fix up port->tty backreferencing 2011-08-26 10:24 [PATCH 1/4] max3110: wake up fixes Alan Cox 2011-08-26 10:25 ` [PATCH 2/4] x86/mrst: Add platform data for Max3110 devices Alan Cox 2011-08-26 10:25 ` [PATCH 3/4] max3110: add sysrq support Alan Cox @ 2011-08-26 10:26 ` Alan Cox 2 siblings, 0 replies; 4+ messages in thread From: Alan Cox @ 2011-08-26 10:26 UTC (permalink / raw) To: greg, linux-serial From: Alan Cox <alan@linux.intel.com> We want to keep refcounts properly on this against hangup. Signed-off-by: Alan Cox <alan@linux.intel.com> --- drivers/tty/serial/mrst_max3110.c | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c index 4f90411..f3ddbcd 100644 --- a/drivers/tty/serial/mrst_max3110.c +++ b/drivers/tty/serial/mrst_max3110.c @@ -347,7 +347,7 @@ receive_chars(struct uart_max3110 *max, unsigned short *str, int len) if (!port->state) return 0; - tty = port->state->port.tty; + tty = tty_port_tty_get(&port->state->port); if (!tty) return 0; @@ -364,8 +364,10 @@ receive_chars(struct uart_max3110 *max, unsigned short *str, int len) } } - if (!w) + if (!w) { + tty_kref_put(tty); return 0; + } for (r = 0; w; r += usable, w -= usable) { usable = tty_buffer_request_room(tty, w); @@ -375,6 +377,7 @@ receive_chars(struct uart_max3110 *max, unsigned short *str, int len) } } tty_flip_buffer_push(tty); + tty_kref_put(tty); return r; } ^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2011-08-26 11:21 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-08-26 10:24 [PATCH 1/4] max3110: wake up fixes Alan Cox 2011-08-26 10:25 ` [PATCH 2/4] x86/mrst: Add platform data for Max3110 devices Alan Cox 2011-08-26 10:25 ` [PATCH 3/4] max3110: add sysrq support Alan Cox 2011-08-26 10:26 ` [PATCH 4/4] max3110: Fix up port->tty backreferencing Alan Cox
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).