diff options
-rw-r--r-- | drivers/serial/mrst_max3110.c | 46 |
1 files changed, 18 insertions, 28 deletions
diff --git a/drivers/serial/mrst_max3110.c b/drivers/serial/mrst_max3110.c index 0341853e0c28..f6ad1ecbff79 100644 --- a/drivers/serial/mrst_max3110.c +++ b/drivers/serial/mrst_max3110.c | |||
@@ -48,6 +48,10 @@ | |||
48 | 48 | ||
49 | #define PR_FMT "mrst_max3110: " | 49 | #define PR_FMT "mrst_max3110: " |
50 | 50 | ||
51 | #define UART_TX_NEEDED 1 | ||
52 | #define CON_TX_NEEDED 2 | ||
53 | #define BIT_IRQ_PENDING 3 | ||
54 | |||
51 | struct uart_max3110 { | 55 | struct uart_max3110 { |
52 | struct uart_port port; | 56 | struct uart_port port; |
53 | struct spi_device *spi; | 57 | struct spi_device *spi; |
@@ -63,15 +67,13 @@ struct uart_max3110 { | |||
63 | u8 clock; | 67 | u8 clock; |
64 | u8 parity, word_7bits; | 68 | u8 parity, word_7bits; |
65 | 69 | ||
66 | atomic_t uart_tx_need; | 70 | unsigned long uart_flags; |
67 | 71 | ||
68 | /* console related */ | 72 | /* console related */ |
69 | struct circ_buf con_xmit; | 73 | struct circ_buf con_xmit; |
70 | atomic_t con_tx_need; | ||
71 | 74 | ||
72 | /* irq related */ | 75 | /* irq related */ |
73 | u16 irq; | 76 | u16 irq; |
74 | atomic_t irq_pending; | ||
75 | }; | 77 | }; |
76 | 78 | ||
77 | /* global data structure, may need be removed */ | 79 | /* global data structure, may need be removed */ |
@@ -176,10 +178,9 @@ static void serial_m3110_con_putchar(struct uart_port *port, int ch) | |||
176 | xmit->head = (xmit->head + 1) & (PAGE_SIZE - 1); | 178 | xmit->head = (xmit->head + 1) & (PAGE_SIZE - 1); |
177 | } | 179 | } |
178 | 180 | ||
179 | if (!atomic_read(&max->con_tx_need)) { | 181 | |
180 | atomic_set(&max->con_tx_need, 1); | 182 | if (!test_and_set_bit(CON_TX_NEEDED, &max->uart_flags)) |
181 | wake_up_process(max->main_thread); | 183 | wake_up_process(max->main_thread); |
182 | } | ||
183 | } | 184 | } |
184 | 185 | ||
185 | /* | 186 | /* |
@@ -318,10 +319,8 @@ static void serial_m3110_start_tx(struct uart_port *port) | |||
318 | struct uart_max3110 *max = | 319 | struct uart_max3110 *max = |
319 | container_of(port, struct uart_max3110, port); | 320 | container_of(port, struct uart_max3110, port); |
320 | 321 | ||
321 | if (!atomic_read(&max->uart_tx_need)) { | 322 | if (!test_and_set_bit(UART_TX_NEEDED, &max->uart_flags)) |
322 | atomic_set(&max->uart_tx_need, 1); | ||
323 | wake_up_process(max->main_thread); | 323 | wake_up_process(max->main_thread); |
324 | } | ||
325 | } | 324 | } |
326 | 325 | ||
327 | static void receive_chars(struct uart_max3110 *max, unsigned char *str, int len) | 326 | static void receive_chars(struct uart_max3110 *max, unsigned char *str, int len) |
@@ -392,32 +391,23 @@ static int max3110_main_thread(void *_max) | |||
392 | pr_info(PR_FMT "start main thread\n"); | 391 | pr_info(PR_FMT "start main thread\n"); |
393 | 392 | ||
394 | do { | 393 | do { |
395 | wait_event_interruptible(*wq, (atomic_read(&max->irq_pending) || | 394 | wait_event_interruptible(*wq, max->uart_flags || kthread_should_stop()); |
396 | atomic_read(&max->con_tx_need) || | ||
397 | atomic_read(&max->uart_tx_need)) || | ||
398 | kthread_should_stop()); | ||
399 | 395 | ||
400 | mutex_lock(&max->thread_mutex); | 396 | mutex_lock(&max->thread_mutex); |
401 | 397 | ||
402 | #ifdef CONFIG_MRST_MAX3110_IRQ | 398 | if (test_and_clear_bit(BIT_IRQ_PENDING, &max->uart_flags)) |
403 | if (atomic_read(&max->irq_pending)) { | ||
404 | max3110_console_receive(max); | 399 | max3110_console_receive(max); |
405 | atomic_set(&max->irq_pending, 0); | ||
406 | } | ||
407 | #endif | ||
408 | 400 | ||
409 | /* first handle console output */ | 401 | /* first handle console output */ |
410 | if (atomic_read(&max->con_tx_need)) { | 402 | if (test_and_clear_bit(CON_TX_NEEDED, &max->uart_flags)) |
411 | send_circ_buf(max, xmit); | 403 | send_circ_buf(max, xmit); |
412 | atomic_set(&max->con_tx_need, 0); | ||
413 | } | ||
414 | 404 | ||
415 | /* handle uart output */ | 405 | /* handle uart output */ |
416 | if (atomic_read(&max->uart_tx_need)) { | 406 | if (test_and_clear_bit(UART_TX_NEEDED, &max->uart_flags)) |
417 | transmit_char(max); | 407 | transmit_char(max); |
418 | atomic_set(&max->uart_tx_need, 0); | 408 | |
419 | } | ||
420 | mutex_unlock(&max->thread_mutex); | 409 | mutex_unlock(&max->thread_mutex); |
410 | |||
421 | } while (!kthread_should_stop()); | 411 | } while (!kthread_should_stop()); |
422 | 412 | ||
423 | return ret; | 413 | return ret; |
@@ -430,10 +420,9 @@ static irqreturn_t serial_m3110_irq(int irq, void *dev_id) | |||
430 | 420 | ||
431 | /* max3110's irq is a falling edge, not level triggered, | 421 | /* max3110's irq is a falling edge, not level triggered, |
432 | * so no need to disable the irq */ | 422 | * so no need to disable the irq */ |
433 | if (!atomic_read(&max->irq_pending)) { | 423 | if (!test_and_set_bit(BIT_IRQ_PENDING, &max->uart_flags)) |
434 | atomic_inc(&max->irq_pending); | ||
435 | wake_up_process(max->main_thread); | 424 | wake_up_process(max->main_thread); |
436 | } | 425 | |
437 | return IRQ_HANDLED; | 426 | return IRQ_HANDLED; |
438 | } | 427 | } |
439 | #else | 428 | #else |
@@ -753,7 +742,8 @@ static int serial_m3110_probe(struct spi_device *spi) | |||
753 | max->baud = 0; | 742 | max->baud = 0; |
754 | 743 | ||
755 | max->cur_conf = 0; | 744 | max->cur_conf = 0; |
756 | atomic_set(&max->irq_pending, 0); | 745 | max->uart_flags = 0; |
746 | |||
757 | /* Check if reading configuration register returns something sane */ | 747 | /* Check if reading configuration register returns something sane */ |
758 | 748 | ||
759 | res = RC_TAG; | 749 | res = RC_TAG; |