#include <linux/kthread.h>
#include <linux/spi/spi.h>
+#include <linux/pm.h>
#include "mrst_max3110.h"
struct task_struct *main_thread;
struct task_struct *read_thread;
struct mutex thread_mutex;
+ struct mutex io_mutex;
u32 baud;
u16 cur_conf;
struct spi_transfer x;
int ret;
+ mutex_lock(&max->io_mutex);
spi_message_init(&message);
memset(&x, 0, sizeof x);
x.len = len;
/* Do the i/o */
ret = spi_sync(spi, &message);
+ mutex_unlock(&max->io_mutex);
return ret;
}
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");
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;
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);
struct spi_device *spi = to_spi_device(dev);
struct uart_max3110 *max = spi_get_drvdata(spi);
- disable_irq(max->irq);
+ if (max->irq > 0)
+ disable_irq(max->irq);
uart_suspend_port(&serial_m3110_reg, &max->port);
max3110_out(max, max->cur_conf | WC_SW_SHDI);
return 0;
max3110_out(max, max->cur_conf);
uart_resume_port(&serial_m3110_reg, &max->port);
- enable_irq(max->irq);
+ if (max->irq > 0)
+ enable_irq(max->irq);
return 0;
}
max->irq = (u16)spi->irq;
mutex_init(&max->thread_mutex);
+ mutex_init(&max->io_mutex);
max->word_7bits = 0;
max->parity = 0;
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;
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);