newton: improve irda driver
authorlyx <lyx@rock-chips.com>
Fri, 19 Aug 2011 13:13:13 +0000 (06:13 -0700)
committerlyx <lyx@rock-chips.com>
Fri, 19 Aug 2011 13:18:55 +0000 (06:18 -0700)
drivers/net/irda/ir_serial.c

index a1c12abfcca6461ed871b235d8f8fb3a56a3e7f3..2ab7e5add6724594693a4b39bc1e049af7861117 100755 (executable)
@@ -37,6 +37,7 @@ struct bu92747_port {
        unsigned long cur_frame_length; \r
        wait_queue_head_t data_ready_wq;\r
        atomic_t data_ready;\r
+       spinlock_t data_lock; \r
 \r
        int tx_empty;           /* last TX empty bit */\r
 \r
@@ -193,16 +194,20 @@ static irqreturn_t bu92747_irda_irq(int irqno, void *dev_id)
                if (!IS_FIR(s))\r
                        tty_flip_buffer_push(s->port.state->port.tty);\r
                else\r
+                       spin_lock(&s->data_lock);\r
                        s->cur_frame_length += len;\r
+                       spin_unlock(&s->data_lock);\r
        }\r
        \r
        if ((irq_src & REG_INT_EOF) && (s->port.state->port.tty != NULL)) {\r
                tty_flip_buffer_push(s->port.state->port.tty);\r
                if (IS_FIR(s)) {\r
-                       s->last_frame_length = s->cur_frame_length;\r
+                       spin_lock(&s->data_lock);\r
+                       s->last_frame_length += s->cur_frame_length;\r
                        s->cur_frame_length = 0;\r
                        atomic_set(&(s->data_ready), 1);\r
                        wake_up(&(s->data_ready_wq) );\r
+                       spin_unlock(&s->data_lock);\r
                }\r
        }\r
        \r
@@ -343,10 +348,12 @@ static void bu92747_irda_shutdown(struct uart_port *port)
                destroy_workqueue(s->workqueue);\r
                s->workqueue = NULL;\r
        }\r
-       \r
+\r
+       spin_lock(&s->data_lock);\r
        atomic_set(&(s->data_ready), 0);\r
        s->last_frame_length = 0;\r
        s->cur_frame_length = 0;\r
+       spin_unlock(&s->data_lock);\r
                \r
        if (s->irq)\r
                free_irq(s->irq, s);\r
@@ -369,8 +376,11 @@ static int bu92747_irda_startup(struct uart_port *port)
 \r
        s->baud = 9600;\r
        s->rx_enabled = 1;\r
+       \r
+       spin_lock(&s->data_lock);\r
        s->last_frame_length = 0;\r
        s->cur_frame_length = 0;\r
+       spin_unlock(&s->data_lock);\r
 \r
        if (s->suspending)\r
                return 0;\r
@@ -503,10 +513,11 @@ static int bu92747_get_frame_length(struct bu92747_port *s)
                return -1;\r
        }\r
 \r
+       spin_lock(&s->data_lock);\r
        len = s->last_frame_length;\r
        s->last_frame_length = 0;\r
-       \r
        atomic_set(&(s->data_ready), 0);\r
+       spin_unlock(&s->data_lock);\r
        \r
        return len;\r
 }\r
@@ -640,6 +651,8 @@ static int __devinit bu92747_irda_probe(struct platform_device *pdev)
        \r
        init_waitqueue_head(&(bu92747s[i]->data_ready_wq));\r
 \r
+       spin_lock_init(&(bu92747s[i]->data_lock));\r
+\r
        mutex_unlock(&bu92747s_lock);\r
        \r
        return 0;\r