newton: improve irda FIR driver
authorlyx <lyx@rock-chips.com>
Wed, 24 Aug 2011 02:57:16 +0000 (19:57 -0700)
committerlyx <lyx@rock-chips.com>
Wed, 24 Aug 2011 06:29:00 +0000 (23:29 -0700)
1.修改FIR帧长度上报机制,如果收到多个帧,上报方式由原来的frame1+frame2+...修改为每次只报一个帧的长度

drivers/net/irda/ir_serial.c

index 2ab7e5add6724594693a4b39bc1e049af7861117..09d9965eee5a7343fe4a8df96418076f087f0de4 100755 (executable)
 #include "bu92725guw.h"\r
 #include "ir_serial.h"\r
 \r
+\r
+#define MAX_FRAME_NUM 20\r
+struct rev_frame_length {\r
+       unsigned long frame_length[MAX_FRAME_NUM];\r
+       int iRead;\r
+       int iWrite;\r
+       int iCount;\r
+};\r
+\r
+#define frame_read_empty(f)              ((f)->iCount == 0)\r
+#define frame_write_full(f)              ((f)->iCount == MAX_FRAME_NUM)\r
+#define frame_length_buf_clear(f) ((f)->iCount = (f)->iWrite = (f)->iRead = 0)\r
+\r
 struct bu92747_port {\r
        struct device           *dev;\r
        struct irda_info *pdata;\r
        struct uart_port port;\r
 \r
        /*for FIR fream read*/\r
-       unsigned long last_frame_length;\r
+       struct rev_frame_length rev_frames;\r
+       //unsigned long last_frame_length;\r
        unsigned long cur_frame_length; \r
-       wait_queue_head_t data_ready_wq;\r
-       atomic_t data_ready;\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
@@ -75,6 +89,37 @@ static u8 g_receive_buf[BU92725GUW_FIFO_SIZE];
 #define BU92747_IRDA_DBG(x...)\r
 #endif\r
 \r
+static int add_frame_length(struct rev_frame_length *f, unsigned long length)\r
+{\r
+       if (frame_write_full(f))\r
+               return -1;\r
+\r
+       f->frame_length[f->iWrite] = length;\r
+       printk("add one frame, length=%d\n", f->frame_length[f->iWrite]);\r
+       f->iCount++;\r
+       printk("now frame iCount=%d\n", f->iCount);\r
+       f->iWrite = (f->iWrite+1) % MAX_FRAME_NUM;\r
+       printk("now frame iWrite=%d\n", f->iWrite);\r
+       \r
+       \r
+       return 0;\r
+}\r
+\r
+static int get_frame_length(struct rev_frame_length *f, unsigned long *length)\r
+{\r
+       if (frame_read_empty(f))\r
+               return -1;\r
+\r
+       *length = f->frame_length[f->iRead];\r
+       printk("read one frame, length=%d\n", *length);\r
+       f->iCount--;\r
+       printk("now frame iCount=%d\n", f->iCount);\r
+       f->iRead = (f->iRead+1) % MAX_FRAME_NUM;\r
+       printk("now frame iRead=%d\n", f->iRead);\r
+       \r
+       return 0;\r
+}\r
+\r
 static int bu92747_irda_do_rx(struct bu92747_port *s)\r
 {\r
        int i;\r
@@ -171,6 +216,7 @@ static irqreturn_t bu92747_irda_irq(int irqno, void *dev_id)
        struct bu92747_port *s = dev_id;\r
        u32 irq_src = 0;\r
        unsigned long len;\r
+       struct rev_frame_length *f = &(s->rev_frames);\r
 \r
        dev_dbg(s->dev, "%s\n", __func__);\r
        BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
@@ -193,20 +239,25 @@ static irqreturn_t bu92747_irda_irq(int irqno, void *dev_id)
                len = bu92747_irda_do_rx(s);\r
                if (!IS_FIR(s))\r
                        tty_flip_buffer_push(s->port.state->port.tty);\r
-               else\r
+               else {\r
                        spin_lock(&s->data_lock);\r
                        s->cur_frame_length += len;\r
                        spin_unlock(&s->data_lock);\r
+               }\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
                        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
+                       if (add_frame_length(f, s->cur_frame_length) == 0) {\r
+                               s->cur_frame_length = 0;\r
+                               //atomic_set(&(s->data_ready), 1);\r
+                               //wake_up(&(s->data_ready_wq) );\r
+                       }\r
+                       else {\r
+                               printk("line %d: FIR frame length buf full......\n", __LINE__);                         \r
+                       }\r
                        spin_unlock(&s->data_lock);\r
                }\r
        }\r
@@ -337,6 +388,7 @@ static void bu92747_irda_shutdown(struct uart_port *port)
 \r
        BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
        dev_dbg(s->dev, "%s\n", __func__);\r
+       struct rev_frame_length *f = &(s->rev_frames);\r
 \r
        if (s->suspending)\r
                return;\r
@@ -350,8 +402,8 @@ static void bu92747_irda_shutdown(struct uart_port *port)
        }\r
 \r
        spin_lock(&s->data_lock);\r
-       atomic_set(&(s->data_ready), 0);\r
-       s->last_frame_length = 0;\r
+       //atomic_set(&(s->data_ready), 0);\r
+       frame_length_buf_clear(f);\r
        s->cur_frame_length = 0;\r
        spin_unlock(&s->data_lock);\r
                \r
@@ -370,6 +422,7 @@ static int bu92747_irda_startup(struct uart_port *port)
                                                  struct bu92747_port,\r
                                                  port);\r
        char b[32];\r
+       struct rev_frame_length *f = &(s->rev_frames);\r
 \r
        BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);\r
        dev_dbg(s->dev, "%s\n", __func__);\r
@@ -378,7 +431,7 @@ static int bu92747_irda_startup(struct uart_port *port)
        s->rx_enabled = 1;\r
        \r
        spin_lock(&s->data_lock);\r
-       s->last_frame_length = 0;\r
+       frame_length_buf_clear(f);\r
        s->cur_frame_length = 0;\r
        spin_unlock(&s->data_lock);\r
 \r
@@ -396,7 +449,7 @@ static int bu92747_irda_startup(struct uart_port *port)
        }\r
        INIT_WORK(&s->work, bu92747_irda_work);\r
 \r
-       atomic_set(&(s->data_ready), 0);\r
+       //atomic_set(&(s->data_ready), 0);\r
 \r
        if (request_irq(s->irq, bu92747_irda_irq,\r
                        IRQ_TYPE_LEVEL_LOW, "bu92747_irda", s) < 0) {\r
@@ -504,7 +557,9 @@ bu92747_irda_set_termios(struct uart_port *port, struct ktermios *termios,
 \r
 static int bu92747_get_frame_length(struct bu92747_port *s)\r
 {\r
-       unsigned long len;\r
+       struct rev_frame_length *f = &(s->rev_frames);\r
+       unsigned long len = 0;\r
+#if 0\r
        wait_event_interruptible_timeout(s->data_ready_wq, \r
                                                                         atomic_read(&(s->data_ready) ),\r
                                                                         msecs_to_jiffies(1000) );\r
@@ -512,11 +567,12 @@ static int bu92747_get_frame_length(struct bu92747_port *s)
                printk("waiting 'data_ready_wq' timed out.");\r
                return -1;\r
        }\r
-\r
+#endif\r
        spin_lock(&s->data_lock);\r
-       len = s->last_frame_length;\r
-       s->last_frame_length = 0;\r
-       atomic_set(&(s->data_ready), 0);\r
+       if (get_frame_length(f, &len) != 0) {\r
+               printk("line %d: FIR data not ready......\n", __LINE__);\r
+               //atomic_set(&(s->data_ready), 0);\r
+       }\r
        spin_unlock(&s->data_lock);\r
        \r
        return len;\r
@@ -649,7 +705,7 @@ static int __devinit bu92747_irda_probe(struct platform_device *pdev)
        if (bu92747s[i]->pdata->irda_pwr_ctl)\r
                bu92747s[i]->pdata->irda_pwr_ctl(0);\r
        \r
-       init_waitqueue_head(&(bu92747s[i]->data_ready_wq));\r
+       //init_waitqueue_head(&(bu92747s[i]->data_ready_wq));\r
 \r
        spin_lock_init(&(bu92747s[i]->data_lock));\r
 \r