diff options
Diffstat (limited to 'drivers/staging/media/lirc')
-rw-r--r-- | drivers/staging/media/lirc/lirc_imon.c | 97 | ||||
-rw-r--r-- | drivers/staging/media/lirc/lirc_sir.c | 75 |
2 files changed, 69 insertions, 103 deletions
diff --git a/drivers/staging/media/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c index 335b98a54..62ec9f70d 100644 --- a/drivers/staging/media/lirc/lirc_imon.c +++ b/drivers/staging/media/lirc/lirc_imon.c @@ -693,10 +693,9 @@ static int imon_probe(struct usb_interface *interface, int ifnum; int lirc_minor = 0; int num_endpts; - int retval = 0; + int retval = -ENOMEM; int display_ep_found = 0; int ir_ep_found = 0; - int alloc_status = 0; int vfd_proto_6p = 0; struct imon_context *context = NULL; int i; @@ -706,10 +705,8 @@ static int imon_probe(struct usb_interface *interface, mutex_lock(&driver_lock); context = kzalloc(sizeof(struct imon_context), GFP_KERNEL); - if (!context) { - alloc_status = 1; - goto alloc_status_switch; - } + if (!context) + goto driver_unlock; /* * Try to auto-detect the type of display if the user hasn't set @@ -775,8 +772,7 @@ static int imon_probe(struct usb_interface *interface, dev_err(dev, "%s: no valid input (IR) endpoint found.\n", __func__); retval = -ENODEV; - alloc_status = 2; - goto alloc_status_switch; + goto free_context; } /* Determine if display requires 6 packets */ @@ -790,31 +786,26 @@ static int imon_probe(struct usb_interface *interface, driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL); if (!driver) { - alloc_status = 2; - goto alloc_status_switch; + goto free_context; } rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); if (!rbuf) { - alloc_status = 3; - goto alloc_status_switch; + goto free_driver; } if (lirc_buffer_init(rbuf, BUF_CHUNK_SIZE, BUF_SIZE)) { dev_err(dev, "%s: lirc_buffer_init failed\n", __func__); - alloc_status = 4; - goto alloc_status_switch; + goto free_rbuf; } rx_urb = usb_alloc_urb(0, GFP_KERNEL); if (!rx_urb) { dev_err(dev, "%s: usb_alloc_urb failed for IR urb\n", __func__); - alloc_status = 5; - goto alloc_status_switch; + goto free_lirc_buf; } tx_urb = usb_alloc_urb(0, GFP_KERNEL); if (!tx_urb) { dev_err(dev, "%s: usb_alloc_urb failed for display urb\n", __func__); - alloc_status = 6; - goto alloc_status_switch; + goto free_rx_urb; } mutex_init(&context->ctx_lock); @@ -840,11 +831,11 @@ static int imon_probe(struct usb_interface *interface, lirc_minor = lirc_register_driver(driver); if (lirc_minor < 0) { dev_err(dev, "%s: lirc_register_driver failed\n", __func__); - alloc_status = 7; - goto unlock; - } else - dev_info(dev, "Registered iMON driver (lirc minor: %d)\n", - lirc_minor); + goto free_tx_urb; + } + + dev_info(dev, "Registered iMON driver (lirc minor: %d)\n", + lirc_minor); /* Needed while unregistering! */ driver->minor = lirc_minor; @@ -872,11 +863,9 @@ static int imon_probe(struct usb_interface *interface, context->rx_endpoint->bInterval); retval = usb_submit_urb(context->rx_urb, GFP_KERNEL); - if (retval) { dev_err(dev, "usb_submit_urb failed for intf0 (%d)\n", retval); - alloc_status = 8; - goto unlock; + goto unregister_lirc; } usb_set_intfdata(interface, context); @@ -895,39 +884,31 @@ static int imon_probe(struct usb_interface *interface, dev_info(dev, "iMON device (%04x:%04x, intf%d) on usb<%d:%d> initialized\n", vendor, product, ifnum, usbdev->bus->busnum, usbdev->devnum); -unlock: - mutex_unlock(&context->ctx_lock); -alloc_status_switch: - - switch (alloc_status) { - case 8: - lirc_unregister_driver(driver->minor); - case 7: - usb_free_urb(tx_urb); - case 6: - usb_free_urb(rx_urb); - /* fall-through */ - case 5: - if (rbuf) - lirc_buffer_free(rbuf); - /* fall-through */ - case 4: - kfree(rbuf); - /* fall-through */ - case 3: - kfree(driver); - /* fall-through */ - case 2: - kfree(context); - context = NULL; - case 1: - if (retval != -ENODEV) - retval = -ENOMEM; - break; - case 0: - retval = 0; - } + /* Everything went fine. Just unlock and return retval (with is 0) */ + goto driver_unlock; + +unregister_lirc: + lirc_unregister_driver(driver->minor); + +free_tx_urb: + usb_free_urb(tx_urb); + +free_rx_urb: + usb_free_urb(rx_urb); + +free_lirc_buf: + lirc_buffer_free(rbuf); + +free_rbuf: + kfree(rbuf); + +free_driver: + kfree(driver); +free_context: + kfree(context); + context = NULL; +driver_unlock: mutex_unlock(&driver_lock); return retval; diff --git a/drivers/staging/media/lirc/lirc_sir.c b/drivers/staging/media/lirc/lirc_sir.c index 29087f66e..4f326e97a 100644 --- a/drivers/staging/media/lirc/lirc_sir.c +++ b/drivers/staging/media/lirc/lirc_sir.c @@ -44,7 +44,7 @@ #include <linux/ioport.h> #include <linux/kernel.h> #include <linux/serial_reg.h> -#include <linux/time.h> +#include <linux/ktime.h> #include <linux/string.h> #include <linux/types.h> #include <linux/wait.h> @@ -127,9 +127,9 @@ static int threshold = 3; static DEFINE_SPINLOCK(timer_lock); static struct timer_list timerlist; /* time of last signal change detected */ -static struct timeval last_tv = {0, 0}; +static ktime_t last; /* time of last UART data ready interrupt */ -static struct timeval last_intr_tv = {0, 0}; +static ktime_t last_intr_time; static int last_value; static DECLARE_WAIT_QUEUE_HEAD(lirc_read_queue); @@ -400,20 +400,6 @@ static void drop_chrdev(void) } /* SECTION: Hardware */ -static long delta(struct timeval *tv1, struct timeval *tv2) -{ - unsigned long deltv; - - deltv = tv2->tv_sec - tv1->tv_sec; - if (deltv > 15) - deltv = 0xFFFFFF; - else - deltv = deltv*1000000 + - tv2->tv_usec - - tv1->tv_usec; - return deltv; -} - static void sir_timeout(unsigned long data) { /* @@ -432,12 +418,14 @@ static void sir_timeout(unsigned long data) /* clear unread bits in UART and restart */ outb(UART_FCR_CLEAR_RCVR, io + UART_FCR); /* determine 'virtual' pulse end: */ - pulse_end = delta(&last_tv, &last_intr_tv); + pulse_end = min_t(unsigned long, + ktime_us_delta(last, last_intr_time), + PULSE_MASK); dev_dbg(driver.dev, "timeout add %d for %lu usec\n", last_value, pulse_end); add_read_queue(last_value, pulse_end); last_value = 0; - last_tv = last_intr_tv; + last = last_intr_time; } spin_unlock_irqrestore(&timer_lock, flags); } @@ -445,9 +433,9 @@ static void sir_timeout(unsigned long data) static irqreturn_t sir_interrupt(int irq, void *dev_id) { unsigned char data; - struct timeval curr_tv; - static unsigned long deltv; - unsigned long deltintrtv; + ktime_t curr_time; + static unsigned long delt; + unsigned long deltintr; unsigned long flags; int iir, lsr; @@ -471,49 +459,46 @@ static irqreturn_t sir_interrupt(int irq, void *dev_id) do { del_timer(&timerlist); data = inb(io + UART_RX); - do_gettimeofday(&curr_tv); - deltv = delta(&last_tv, &curr_tv); - deltintrtv = delta(&last_intr_tv, &curr_tv); + curr_time = ktime_get(); + delt = min_t(unsigned long, + ktime_us_delta(last, curr_time), + PULSE_MASK); + deltintr = min_t(unsigned long, + ktime_us_delta(last_intr_time, + curr_time), + PULSE_MASK); dev_dbg(driver.dev, "t %lu, d %d\n", - deltintrtv, (int)data); + deltintr, (int)data); /* * if nothing came in last X cycles, * it was gap */ - if (deltintrtv > TIME_CONST * threshold) { + if (deltintr > TIME_CONST * threshold) { if (last_value) { dev_dbg(driver.dev, "GAP\n"); /* simulate signal change */ add_read_queue(last_value, - deltv - - deltintrtv); + delt - + deltintr); last_value = 0; - last_tv.tv_sec = - last_intr_tv.tv_sec; - last_tv.tv_usec = - last_intr_tv.tv_usec; - deltv = deltintrtv; + last = last_intr_time; + delt = deltintr; } } data = 1; if (data ^ last_value) { /* - * deltintrtv > 2*TIME_CONST, remember? + * deltintr > 2*TIME_CONST, remember? * the other case is timeout */ add_read_queue(last_value, - deltv-TIME_CONST); + delt-TIME_CONST); last_value = data; - last_tv = curr_tv; - if (last_tv.tv_usec >= TIME_CONST) { - last_tv.tv_usec -= TIME_CONST; - } else { - last_tv.tv_sec--; - last_tv.tv_usec += 1000000 - - TIME_CONST; - } + last = curr_time; + last = ktime_sub_us(last, + TIME_CONST); } - last_intr_tv = curr_tv; + last_intr_time = curr_time; if (data) { /* * start timer for end of |