lkml.org 
[lkml]   [2013]   [Oct]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 1/2] mrst_max3110: fix unbalanced IRQ issue during resume
Date
From: "Chen, Jie" <jie.d.chen@intel.com>

During resume, a startup will request_irq again, meantime resume function's
enable_irq will cause unbalanced IRQ issue.
Fix this issue by moving request_irq to probe function.

Signed-off-by: David Cohen <david.a.cohen@linux.intel.com>
Signed-off-by: Chen, Jie <jie.d.chen@intel.com>
---
drivers/tty/serial/mrst_max3110.c | 35 +++++++++++++++++------------------
1 file changed, 17 insertions(+), 18 deletions(-)

diff --git a/drivers/tty/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c
index a67e708..6f618dd 100644
--- a/drivers/tty/serial/mrst_max3110.c
+++ b/drivers/tty/serial/mrst_max3110.c
@@ -43,6 +43,7 @@

#include <linux/kthread.h>
#include <linux/spi/spi.h>
+#include <linux/pm.h>

#include "mrst_max3110.h"

@@ -491,19 +492,9 @@ static int serial_m3110_startup(struct uart_port *port)
port->state->port.low_latency = 1;

if (max->irq) {
- max->read_thread = NULL;
- ret = request_irq(max->irq, serial_m3110_irq,
- IRQ_TYPE_EDGE_FALLING, "max3110", max);
- if (ret) {
- max->irq = 0;
- pr_err(PR_FMT "unable to allocate IRQ, polling\n");
- } else {
- /* Enable RX IRQ only */
- config |= WC_RXA_IRQ_ENABLE;
- }
- }
-
- if (max->irq == 0) {
+ /* Enable RX IRQ only */
+ config |= WC_RXA_IRQ_ENABLE;
+ } else {
/* If IRQ is disabled, start a read thread for input data */
max->read_thread =
kthread_run(max3110_read_thread, max, "max3110_read");
@@ -517,8 +508,6 @@ static int serial_m3110_startup(struct uart_port *port)

ret = max3110_out(max, config);
if (ret) {
- if (max->irq)
- free_irq(max->irq, max);
if (max->read_thread)
kthread_stop(max->read_thread);
max->read_thread = NULL;
@@ -540,9 +529,6 @@ static void serial_m3110_shutdown(struct uart_port *port)
max->read_thread = NULL;
}

- if (max->irq)
- free_irq(max->irq, max);
-
/* Disable interrupts from this port */
config = WC_TAG | WC_SW_SHDI;
max3110_out(max, config);
@@ -840,6 +826,16 @@ static int serial_m3110_probe(struct spi_device *spi)
goto err_kthread;
}

+ if (max->irq) {
+ ret = request_irq(max->irq, serial_m3110_irq,
+ IRQ_TYPE_EDGE_FALLING, "max3110", max);
+ if (ret) {
+ max->irq = 0;
+ dev_warn(&spi->dev,
+ "unable to allocate IRQ, will use polling method\n");
+ }
+ }
+
spi_set_drvdata(spi, max);
pmax = max;

@@ -867,6 +863,9 @@ static int serial_m3110_remove(struct spi_device *dev)

free_page((unsigned long)max->con_xmit.buf);

+ if (max->irq)
+ free_irq(max->irq, max);
+
if (max->main_thread)
kthread_stop(max->main_thread);

--
1.8.4.rc3


\
 
 \ /
  Last update: 2013-10-22 22:21    [W:0.353 / U:0.060 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site