3 * Copyright (C) 2011 liuyixing <lyx@rock-chips.com>
\r
5 * This program is free software; you can redistribute it and/or modify
\r
6 * it under the terms of the GNU General Public License as published by
\r
7 * the Free Software Foundation; either version 2 of the License, or
\r
8 * (at your option) any later version.
\r
11 *note: serial driver for IrDA(SIR and FIR) device
\r
15 #include <linux/delay.h>
\r
16 #include <linux/slab.h>
\r
17 #include <linux/device.h>
\r
18 #include <linux/serial_core.h>
\r
19 #include <linux/serial.h>
\r
20 #include <linux/freezer.h>
\r
21 #include <mach/board.h>
\r
22 #include <linux/irq.h>
\r
23 #include <mach/gpio.h>
\r
24 #include <asm/uaccess.h>
\r
25 #include <asm/atomic.h>
\r
27 #include "bu92725guw.h"
\r
28 #include "ir_serial.h"
\r
31 #define MAX_FRAME_NUM 20
\r
32 struct rev_frame_length {
\r
33 unsigned long frame_length[MAX_FRAME_NUM];
\r
39 #define frame_read_empty(f) ((f)->iCount == 0)
\r
40 #define frame_write_full(f) ((f)->iCount == MAX_FRAME_NUM)
\r
41 #define frame_length_buf_clear(f) ((f)->iCount = (f)->iWrite = (f)->iRead = 0)
\r
43 struct bu92747_port {
\r
45 struct irda_info *pdata;
\r
46 struct uart_port port;
\r
48 /*for FIR fream read*/
\r
49 struct rev_frame_length rev_frames;
\r
50 //unsigned long last_frame_length;
\r
51 unsigned long cur_frame_length;
\r
52 //wait_queue_head_t data_ready_wq;
\r
53 //atomic_t data_ready;
\r
54 spinlock_t data_lock;
\r
56 int tx_empty; /* last TX empty bit */
\r
58 spinlock_t conf_lock; /* shared data */
\r
59 int baud; /* current baud rate */
\r
61 int rx_enabled; /* if we should rx chars */
\r
64 int irq; /* irq assigned to the bu92747 */
\r
66 int minor; /* minor number */
\r
68 struct workqueue_struct *workqueue;
\r
69 struct work_struct work;
\r
70 /* set to 1 to make the workhandler exit as soon as possible */
\r
74 /* need to know we are suspending to avoid deadlock on workqueue */
\r
79 #define MAX_BU92747 1
\r
80 #define BU92747_MAJOR 204
\r
81 #define BU92747_MINOR 209
\r
83 static struct bu92747_port *bu92747s[MAX_BU92747]; /* the chips */
\r
84 static DEFINE_MUTEX(bu92747s_lock); /* race on probe */
\r
85 #define IS_FIR(s) ((s)->baud >= 4000000)
\r
86 static int max_rate = 4000000;
\r
87 static u8 g_receive_buf[BU92725GUW_FIFO_SIZE];
\r
90 #define IRDA_DBG_FUNC(x...) printk(x)
\r
92 #define IRDA_DBG_FUNC(x...)
\r
96 #define IRDA_DBG_RECV(x...) printk(x)
\r
98 #define IRDA_DBG_RECV(x...)
\r
102 #define IRDA_DBG_SENT(x...) printk(x)
\r
104 #define IRDA_DBG_SENT(x...)
\r
107 /* race on startup&shutdown, mutex lock with CIR driver */
\r
108 static DEFINE_MUTEX(irda_cir_lock);
\r
109 int bu92747_try_lock(void)
\r
111 if (mutex_trylock(&irda_cir_lock))
\r
117 void bu92747_unlock(void)
\r
119 return mutex_unlock(&irda_cir_lock);
\r
122 static int add_frame_length(struct rev_frame_length *f, unsigned long length)
\r
124 if (frame_write_full(f))
\r
127 f->frame_length[f->iWrite] = length;
\r
129 f->iWrite = (f->iWrite+1) % MAX_FRAME_NUM;
\r
134 static int get_frame_length(struct rev_frame_length *f, unsigned long *length)
\r
136 if (frame_read_empty(f))
\r
139 *length = f->frame_length[f->iRead];
\r
141 f->iRead = (f->iRead+1) % MAX_FRAME_NUM;
\r
146 static int bu92747_irda_do_rx(struct bu92747_port *s)
\r
149 //unsigned int ch, flag;
\r
151 struct tty_struct *tty = s->port.state->port.tty;
\r
152 IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
\r
154 if (s->rx_enabled == 0) {
\r
155 BU92725GUW_clr_fifo();
\r
156 BU92725GUW_reset();
\r
160 len = BU92725GUW_get_data(g_receive_buf);
\r
163 //printk("receive data:\n");
\r
164 for (i=0;i<len;i++) {
\r
165 ch = g_receive_buf[i];
\r
166 uart_insert_char(&s->port, 0, 0, ch, flag);
\r
167 s->port.icount.rx++;
\r
168 //printk("%d ", ch);
\r
173 IRDA_DBG_RECV("line %d, enter %s, receive %d data........\n", __LINE__, __func__, len);
\r
174 tty_insert_flip_string(tty, g_receive_buf, len);
\r
175 s->port.icount.rx += len;
\r
181 static int bu92747_irda_do_tx(struct bu92747_port *s)
\r
184 struct circ_buf *xmit = &s->port.state->xmit;
\r
185 int len = uart_circ_chars_pending(xmit);
\r
187 IRDA_DBG_SENT("line %d, enter %s, sending %d data\n", __LINE__, __FUNCTION__, len);
\r
190 irda_hw_tx_enable_irq(BU92725GUW_FIR);
\r
193 irda_hw_tx_enable_irq(BU92725GUW_SIR);
\r
200 /* [Modify] AIC 2011/09/27
\r
201 * BU92725GUW_send_data(xmit->buf+xmit->tail, len, NULL, 0);
\r
203 if ( (xmit->tail + len) > UART_XMIT_SIZE ) {
\r
204 len1 = UART_XMIT_SIZE - xmit->tail;
\r
206 BU92725GUW_send_data(xmit->buf+xmit->tail, len1, xmit->buf, len2);
\r
208 BU92725GUW_send_data(xmit->buf+xmit->tail, len, NULL, 0);
\r
210 /* [Modify-end] AIC 2011/09/27 */
\r
211 s->port.icount.tx += len;
\r
212 xmit->tail = (xmit->tail + len) & (UART_XMIT_SIZE - 1);
\r
215 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
\r
216 uart_write_wakeup(&s->port);
\r
221 static void bu92747_irda_dowork(struct bu92747_port *s)
\r
223 if (!s->force_end_work && !work_pending(&s->work) &&
\r
224 !freezing(current) && !s->suspending)
\r
225 queue_work(s->workqueue, &s->work);
\r
228 static void bu92747_irda_work(struct work_struct *w)
\r
230 struct bu92747_port *s = container_of(w, struct bu92747_port, work);
\r
231 struct circ_buf *xmit = &s->port.state->xmit;
\r
233 IRDA_DBG_SENT("line %d, enter %s \n", __LINE__, __FUNCTION__);
\r
235 if (!s->force_end_work && !freezing(current)) {
\r
236 if (!uart_circ_empty(xmit) && !uart_tx_stopped(&s->port)) {
\r
238 bu92747_irda_do_tx(s);
\r
240 bu92747_irda_dowork(s);
\r
245 static irqreturn_t bu92747_irda_irq(int irqno, void *dev_id)
\r
247 struct bu92747_port *s = dev_id;
\r
250 struct rev_frame_length *f = &(s->rev_frames);
\r
252 irq_src = irda_hw_get_irqsrc();
\r
253 IRDA_DBG_RECV("[%s][%d], 0x%x\n",__FUNCTION__,__LINE__, irq_src);
\r
256 if (irq_src & (REG_INT_CRC | REG_INT_OE | REG_INT_FE
\r
257 | REG_INT_AC | REG_INT_DECE | REG_INT_RDOE | REG_INT_DEX)) {
\r
258 printk("[%s][%d]: do err, REG_EIR = 0x%x\n", __FUNCTION__, __LINE__, irq_src);
\r
259 BU92725GUW_clr_fifo();
\r
260 BU92725GUW_reset();
\r
261 if ((BU92725GUW_SEND==irda_hw_get_mode())
\r
262 || (BU92725GUW_MULTI_SEND==irda_hw_get_mode())) {
\r
267 if (irq_src & (REG_INT_DRX | FRM_EVT_RX_EOFRX | FRM_EVT_RX_RDE)) {
\r
268 //fixing CA001 (IrSimple mode sending) failing issue
\r
269 /* modified to process a frame ending processing first, when RDE_EI and EOF_EI are happen at the same time.
\r
270 * Before the modification, disconnect packet was processed as the previous packet,
\r
271 * not as a disconnect packet. The packets were combined.
\r
273 if ((irq_src & REG_INT_EOF) && (s->port.state->port.tty != NULL)) {
\r
274 tty_flip_buffer_push(s->port.state->port.tty);
\r
276 spin_lock(&s->data_lock);
\r
277 if (add_frame_length(f, s->cur_frame_length) == 0) {
\r
278 s->cur_frame_length = 0;
\r
281 printk("func %s,line %d: FIR frame length buf full......\n", __FUNCTION__, __LINE__);
\r
283 spin_unlock(&s->data_lock);
\r
288 len = bu92747_irda_do_rx(s);
\r
290 tty_flip_buffer_push(s->port.state->port.tty);
\r
292 spin_lock(&s->data_lock);
\r
293 s->cur_frame_length += len;
\r
294 spin_unlock(&s->data_lock);
\r
298 if ((irq_src & REG_INT_EOF) && (s->port.state->port.tty != NULL)) {
\r
299 spin_lock(&s->data_lock); // [Modify] AIC 2011/09/30
\r
300 tty_flip_buffer_push(s->port.state->port.tty);
\r
302 /* [Modify] AIC 2011/09/30
\r
303 * spin_lock(&s->data_lock);
\r
305 if (add_frame_length(f, s->cur_frame_length) == 0) {
\r
306 s->cur_frame_length = 0;
\r
309 printk("func %s,line %d: FIR frame length buf full......\n", __FUNCTION__, __LINE__);
\r
311 /* [Modify] AIC 2011/09/30
\r
312 * spin_unlock(&s->data_lock);
\r
315 spin_unlock(&s->data_lock); // [Modify] AIC 2011/09/30
\r
318 /* [Modify] AIC 2011/09/27
\r
320 * if (irq_src & (FRM_EVT_TX_TXE | FRM_EVT_TX_WRE)) {
\r
322 * irda_hw_set_moderx();
\r
325 /* [Modify] AIC 2011/09/29
\r
327 * if (irq_src & (FRM_EVT_TX_TXE | FRM_EVT_TX_WRE)) {
\r
329 * if ( irq_src & FRM_EVT_TX_TXE ) {
\r
330 * irda_hw_set_moderx();
\r
333 if ( (irq_src & (FRM_EVT_TX_TXE | FRM_EVT_TX_WRE)) &&
\r
334 (BU92725GUW_get_length_in_fifo_buffer() == 0) ) {
\r
337 if ( irq_src & FRM_EVT_TX_TXE ) {
\r
338 irda_hw_set_moderx();
\r
341 /* [Modify-end] AIC 2011/09/29 */
\r
344 if (irq_src & REG_INT_TO) {
\r
345 printk("[%s][%d]: do timeout err\n", __FUNCTION__, __LINE__);
\r
346 BU92725GUW_clr_fifo();
\r
347 BU92725GUW_reset();
\r
348 if ((BU92725GUW_SEND==irda_hw_get_mode())
\r
349 || (BU92725GUW_MULTI_SEND==irda_hw_get_mode())) {
\r
354 return IRQ_HANDLED;
\r
358 static void bu92747_irda_stop_tx(struct uart_port *port)
\r
360 IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
\r
363 static void bu92747_irda_start_tx(struct uart_port *port)
\r
365 struct bu92747_port *s = container_of(port,
\r
366 struct bu92747_port,
\r
368 IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
\r
370 //wait for start cmd
\r
374 bu92747_irda_dowork(s);
\r
377 static void bu92747_irda_stop_rx(struct uart_port *port)
\r
379 struct bu92747_port *s = container_of(port,
\r
380 struct bu92747_port,
\r
383 IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
\r
388 static unsigned int bu92747_irda_tx_empty(struct uart_port *port)
\r
390 struct bu92747_port *s = container_of(port,
\r
391 struct bu92747_port,
\r
394 IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
\r
396 /* may not be truly up-to-date */
\r
397 return s->tx_empty;
\r
400 static const char *bu92747_irda_type(struct uart_port *port)
\r
402 struct bu92747_port *s = container_of(port,
\r
403 struct bu92747_port,
\r
406 IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
\r
408 return s->port.type == PORT_IRDA ? "BU92747" : NULL;
\r
411 static void bu92747_irda_release_port(struct uart_port *port)
\r
413 IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
\r
416 static void bu92747_irda_config_port(struct uart_port *port, int flags)
\r
418 struct bu92747_port *s = container_of(port,
\r
419 struct bu92747_port,
\r
422 IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
\r
424 if (flags & UART_CONFIG_TYPE)
\r
425 s->port.type = PORT_IRDA;
\r
428 static int bu92747_irda_verify_port(struct uart_port *port,
\r
429 struct serial_struct *ser)
\r
433 IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
\r
435 if (ser->type == PORT_UNKNOWN || ser->type == PORT_IRDA)
\r
441 static void bu92747_irda_shutdown(struct uart_port *port)
\r
443 struct bu92747_port *s = container_of(port,
\r
444 struct bu92747_port,
\r
446 struct rev_frame_length *f = &(s->rev_frames);
\r
448 printk("line %d, enter %s \n", __LINE__, __FUNCTION__);
\r
454 s->force_end_work = 1;
\r
456 if (s->workqueue) {
\r
457 flush_workqueue(s->workqueue);
\r
458 destroy_workqueue(s->workqueue);
\r
459 s->workqueue = NULL;
\r
462 spin_lock(&s->data_lock);
\r
463 frame_length_buf_clear(f);
\r
464 s->cur_frame_length = 0;
\r
465 spin_unlock(&s->data_lock);
\r
468 free_irq(s->irq, s);
\r
470 irda_hw_shutdown();
\r
471 if (s->pdata->irda_pwr_ctl)
\r
472 s->pdata->irda_pwr_ctl(0);
\r
477 static int bu92747_irda_startup(struct uart_port *port)
\r
479 struct bu92747_port *s = container_of(port,
\r
480 struct bu92747_port,
\r
483 struct rev_frame_length *f = &(s->rev_frames);
\r
485 printk("line %d, enter %s \n", __LINE__, __FUNCTION__);
\r
492 if (!bu92747_try_lock()) {
\r
493 printk("func %s, cannot get bu92747 lock, bu92747 in using\n", __func__);
\r
499 spin_lock(&s->data_lock);
\r
500 frame_length_buf_clear(f);
\r
501 s->cur_frame_length = 0;
\r
502 spin_unlock(&s->data_lock);
\r
505 s->force_end_work = 0;
\r
507 sprintf(b, "bu92747_irda-%d", s->minor);
\r
508 s->workqueue = create_rt_workqueue(b);
\r
509 if (!s->workqueue) {
\r
510 dev_warn(s->dev, "cannot create workqueue\n");
\r
514 INIT_WORK(&s->work, bu92747_irda_work);
\r
516 if (request_irq(s->irq, bu92747_irda_irq,
\r
517 IRQF_TRIGGER_LOW, "bu92747_irda", s) < 0) {
\r
518 dev_warn(s->dev, "cannot allocate irq %d\n", s->irq);
\r
520 destroy_workqueue(s->workqueue);
\r
521 s->workqueue = NULL;
\r
526 disable_irq(s->irq);
\r
528 if (s->pdata->irda_pwr_ctl)
\r
529 s->pdata->irda_pwr_ctl(1);
\r
532 irda_hw_set_moderx();
\r
534 enable_irq(s->irq);
\r
541 static int bu92747_irda_request_port(struct uart_port *port)
\r
543 IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
\r
547 static void bu92747_irda_break_ctl(struct uart_port *port, int break_state)
\r
549 IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
\r
552 static unsigned int bu92747_irda_get_mctrl(struct uart_port *port)
\r
554 return TIOCM_DSR | TIOCM_CAR;
\r
557 static void bu92747_irda_set_mctrl(struct uart_port *port, unsigned int mctrl)
\r
559 IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
\r
563 bu92747_irda_set_termios(struct uart_port *port, struct ktermios *termios,
\r
564 struct ktermios *old)
\r
566 struct bu92747_port *s = container_of(port,
\r
567 struct bu92747_port,
\r
571 struct tty_struct *tty = s->port.state->port.tty;
\r
573 IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
\r
577 cflag = termios->c_cflag;
\r
578 baud = uart_get_baud_rate(port, termios, old, 0, max_rate);
\r
587 if (s->baud!=baud) {
\r
588 IRDA_DBG_RECV("func %s:irda set baudrate %d........\n", __FUNCTION__, baud);
\r
589 irda_hw_set_speed(baud);
\r
599 uart_update_timeout(port, termios->c_cflag, baud);
\r
603 static int bu92747_get_frame_length(struct bu92747_port *s)
\r
605 struct rev_frame_length *f = &(s->rev_frames);
\r
606 unsigned long len = 0;
\r
608 spin_lock(&s->data_lock);
\r
609 if (get_frame_length(f, &len) != 0) {
\r
610 IRDA_DBG_RECV("func %s, line %d: FIR data not ready......\n", __FUNCTION__, __LINE__);
\r
613 spin_unlock(&s->data_lock);
\r
618 static int bu92747_irda_ioctl(struct uart_port *port, unsigned int cmd, unsigned long arg)
\r
620 struct bu92747_port *s = container_of(port,
\r
621 struct bu92747_port,
\r
623 void __user *argp = (void __user *)arg;
\r
624 unsigned long len = 0;
\r
626 IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
\r
629 case TTYIR_GETLENGTH:
\r
630 len = bu92747_get_frame_length(s);
\r
632 if (copy_to_user(argp, &len, sizeof(len)))
\r
639 case TTYIR_STARTSEND:
\r
640 bu92747_irda_dowork(s);
\r
643 ret = -ENOIOCTLCMD;
\r
650 static struct uart_ops bu92747_irda_ops = {
\r
651 .tx_empty = bu92747_irda_tx_empty,
\r
652 .set_mctrl = bu92747_irda_set_mctrl,
\r
653 .get_mctrl = bu92747_irda_get_mctrl,
\r
654 .stop_tx = bu92747_irda_stop_tx,
\r
655 .start_tx = bu92747_irda_start_tx,
\r
656 .stop_rx = bu92747_irda_stop_rx,
\r
657 //.enable_ms = bu92747_irda_enable_ms,
\r
658 .break_ctl = bu92747_irda_break_ctl,
\r
659 .startup = bu92747_irda_startup,
\r
660 .shutdown = bu92747_irda_shutdown,
\r
661 .set_termios = bu92747_irda_set_termios,
\r
662 .type = bu92747_irda_type,
\r
663 .release_port = bu92747_irda_release_port,
\r
664 .request_port = bu92747_irda_request_port,
\r
665 .config_port = bu92747_irda_config_port,
\r
666 .verify_port = bu92747_irda_verify_port,
\r
667 .ioctl = bu92747_irda_ioctl,
\r
670 static struct uart_driver bu92747_irda_uart_driver = {
\r
671 .owner = THIS_MODULE,
\r
672 .driver_name = "ttyIr",
\r
673 .dev_name = "ttyIr",
\r
674 .major = BU92747_MAJOR,
\r
675 .minor = BU92747_MINOR,
\r
679 static int uart_driver_registered;
\r
680 static int __devinit bu92747_irda_probe(struct platform_device *pdev)
\r
683 struct irda_info *platdata = pdev->dev.platform_data;
\r
685 IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
\r
687 dev_warn(&pdev->dev, "no platform data info\n");
\r
691 mutex_lock(&bu92747s_lock);
\r
693 if (!uart_driver_registered) {
\r
694 uart_driver_registered = 1;
\r
695 retval = uart_register_driver(&bu92747_irda_uart_driver);
\r
697 printk(KERN_ERR "Couldn't register bu92747 uart driver\n");
\r
698 mutex_unlock(&bu92747s_lock);
\r
703 for (i = 0; i < MAX_BU92747; i++)
\r
706 if (i == MAX_BU92747) {
\r
707 dev_warn(&pdev->dev, "too many bu92747 chips\n");
\r
708 mutex_unlock(&bu92747s_lock);
\r
712 bu92747s[i] = kzalloc(sizeof(struct bu92747_port), GFP_KERNEL);
\r
713 if (!bu92747s[i]) {
\r
714 dev_warn(&pdev->dev,
\r
715 "kmalloc for bu92747 structure %d failed!\n", i);
\r
716 mutex_unlock(&bu92747s_lock);
\r
719 bu92747s[i]->dev = &pdev->dev;
\r
720 bu92747s[i]->irq_pin = platdata->intr_pin;
\r
721 bu92747s[i]->irq = gpio_to_irq(platdata->intr_pin);
\r
722 if (platdata->iomux_init)
\r
723 platdata->iomux_init();
\r
724 bu92747s[i]->pdata = platdata;
\r
725 spin_lock_init(&bu92747s[i]->conf_lock);
\r
726 dev_set_drvdata(&pdev->dev, bu92747s[i]);
\r
727 bu92747s[i]->minor = i;
\r
728 dev_dbg(&pdev->dev, "%s: adding port %d\n", __func__, i);
\r
729 bu92747s[i]->port.irq = bu92747s[i]->irq;
\r
730 bu92747s[i]->port.fifosize = BU92725GUW_FIFO_SIZE;
\r
731 bu92747s[i]->port.ops = &bu92747_irda_ops;
\r
732 bu92747s[i]->port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
\r
733 bu92747s[i]->port.line = i;
\r
734 bu92747s[i]->port.type = PORT_IRDA;
\r
735 bu92747s[i]->port.dev = &pdev->dev;
\r
736 retval = uart_add_one_port(&bu92747_irda_uart_driver, &bu92747s[i]->port);
\r
738 dev_warn(&pdev->dev,
\r
739 "uart_add_one_port failed for line %d with error %d\n",
\r
741 bu92747s[i]->open_flag = 0;
\r
742 bu92747s[i]->suspending = 0;
\r
743 /* set shutdown mode to save power. Will be woken-up on open */
\r
744 if (bu92747s[i]->pdata->irda_pwr_ctl)
\r
745 bu92747s[i]->pdata->irda_pwr_ctl(0);
\r
747 spin_lock_init(&(bu92747s[i]->data_lock));
\r
749 mutex_unlock(&bu92747s_lock);
\r
754 static int __devexit bu92747_irda_remove(struct platform_device *pdev)
\r
756 struct bu92747_port *s = dev_get_drvdata(&pdev->dev);
\r
759 IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
\r
760 mutex_lock(&bu92747s_lock);
\r
762 /* find out the index for the chip we are removing */
\r
763 for (i = 0; i < MAX_BU92747; i++)
\r
764 if (bu92747s[i] == s)
\r
767 dev_dbg(&pdev->dev, "%s: removing port %d\n", __func__, i);
\r
768 uart_remove_one_port(&bu92747_irda_uart_driver, &bu92747s[i]->port);
\r
769 kfree(bu92747s[i]);
\r
770 bu92747s[i] = NULL;
\r
772 /* check if this is the last chip we have */
\r
773 for (i = 0; i < MAX_BU92747; i++)
\r
775 mutex_unlock(&bu92747s_lock);
\r
778 pr_debug("removing bu92747 driver\n");
\r
779 uart_unregister_driver(&bu92747_irda_uart_driver);
\r
781 mutex_unlock(&bu92747s_lock);
\r
787 static int bu92747_irda_suspend(struct platform_device *pdev, pm_message_t state)
\r
789 struct bu92747_port *s = dev_get_drvdata(&pdev->dev);
\r
791 if (s->open_flag) {
\r
792 printk("line %d, enter %s \n", __LINE__, __FUNCTION__);
\r
793 disable_irq(s->irq);
\r
794 cancel_work_sync(&s->work);
\r
796 uart_suspend_port(&bu92747_irda_uart_driver, &s->port);
\r
798 irda_hw_shutdown();
\r
799 if (s->pdata->irda_pwr_ctl)
\r
800 s->pdata->irda_pwr_ctl(0);
\r
806 static int bu92747_irda_resume(struct platform_device *pdev)
\r
808 struct bu92747_port *s = dev_get_drvdata(&pdev->dev);
\r
810 if (s->open_flag) {
\r
811 printk("line %d, enter %s \n", __LINE__, __FUNCTION__);
\r
812 if (s->pdata->irda_pwr_ctl)
\r
813 s->pdata->irda_pwr_ctl(1);
\r
816 irda_hw_set_speed(s->baud);
\r
817 irda_hw_set_moderx();
\r
819 uart_resume_port(&bu92747_irda_uart_driver, &s->port);
\r
824 enable_irq(s->irq);
\r
825 if (s->workqueue && !IS_FIR(s))
\r
826 bu92747_irda_dowork(s);
\r
832 #define bu92747_irda_suspend NULL
\r
833 #define bu92747_irda_resume NULL
\r
836 static struct platform_driver bu92747_irda_driver = {
\r
838 .name = "bu92747_irda",
\r
839 .owner = THIS_MODULE,
\r
841 .probe = bu92747_irda_probe,
\r
842 .remove = bu92747_irda_remove,
\r
843 .suspend = bu92747_irda_suspend,
\r
844 .resume = bu92747_irda_resume,
\r
847 static int __init bu92747_irda_init(void)
\r
849 if (platform_driver_register(&bu92747_irda_driver) != 0) {
\r
850 printk("Could not register irda driver\n");
\r
856 static void __exit bu92747_irda_exit(void)
\r
858 platform_driver_unregister(&bu92747_irda_driver);
\r
861 module_init(bu92747_irda_init);
\r
862 module_exit(bu92747_irda_exit);
\r
863 MODULE_DESCRIPTION("BU92747 irda driver");
\r
864 MODULE_AUTHOR("liuyixing <lyx@rock-chips.com>");
\r
865 MODULE_LICENSE("GPL");
\r