X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmedia%2Fdvb%2FcinergyT2%2FcinergyT2.c;h=d64b96cb0c469ea9e325eca7e557e0f084ce7c39;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=96c57fde95a0da96efd4e16f47c8417837ee7a2c;hpb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;p=linux-2.6.git diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c index 96c57fde9..d64b96cb0 100644 --- a/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/drivers/media/dvb/cinergyT2/cinergyT2.c @@ -22,21 +22,20 @@ * */ -#include #include #include -#include #include #include #include #include #include +#include +#include #include "dmxdev.h" #include "dvb_demux.h" #include "dvb_net.h" - #ifdef CONFIG_DVB_CINERGYT2_TUNING #define STREAM_URB_COUNT (CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT) #define STREAM_BUF_SIZE (CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE) @@ -49,7 +48,7 @@ #define STREAM_URB_COUNT (32) #define STREAM_BUF_SIZE (512) /* bytes */ #define ENABLE_RC (1) - #define RC_QUERY_INTERVAL (100) /* milliseconds */ + #define RC_QUERY_INTERVAL (50) /* milliseconds */ #define QUERY_INTERVAL (333) /* milliseconds */ #endif @@ -62,7 +61,7 @@ MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); #define dprintk(level, args...) \ do { \ if ((debug & level)) { \ - printk("%s: %s(): ", __stringify(KBUILD_MODNAME), \ + printk("%s: %s(): ", KBUILD_MODNAME, \ __FUNCTION__); \ printk(args); } \ } while (0) @@ -118,7 +117,7 @@ static struct dvb_frontend_info cinergyt2_fe_info = { struct cinergyt2 { struct dvb_demux demux; struct usb_device *udev; - struct semaphore sem; + struct mutex sem; struct dvb_adapter adapter; struct dvb_device *fedev; struct dmxdev dmxdev; @@ -129,19 +128,24 @@ struct cinergyt2 { struct dvbt_set_parameters_msg param; struct dvbt_get_status_msg status; - struct work_struct query_work; + struct delayed_work query_work; wait_queue_head_t poll_wq; int pending_fe_events; + int disconnect_pending; + atomic_t inuse; void *streambuf; dma_addr_t streambuf_dmahandle; struct urb *stream_urb [STREAM_URB_COUNT]; #ifdef ENABLE_RC - struct input_dev rc_input_dev; - struct work_struct rc_query_work; + struct input_dev *rc_input_dev; + char phys[64]; + struct delayed_work rc_query_work; int rc_input_event; + u32 rc_last_code; + unsigned long last_event_jiffies; #endif }; @@ -156,7 +160,7 @@ struct cinergyt2_rc_event { uint32_t value; } __attribute__((packed)); -static const uint32_t rc_keys [] = { +static const uint32_t rc_keys[] = { CINERGYT2_RC_EVENT_TYPE_NEC, 0xfe01eb04, KEY_POWER, CINERGYT2_RC_EVENT_TYPE_NEC, 0xfd02eb04, KEY_1, CINERGYT2_RC_EVENT_TYPE_NEC, 0xfc03eb04, KEY_2, @@ -235,7 +239,7 @@ static void cinergyt2_sleep (struct cinergyt2 *cinergyt2, int sleep) cinergyt2->sleeping = sleep; } -static void cinergyt2_stream_irq (struct urb *urb, struct pt_regs *regs); +static void cinergyt2_stream_irq (struct urb *urb); static int cinergyt2_submit_stream_urb (struct cinergyt2 *cinergyt2, struct urb *urb) { @@ -255,7 +259,7 @@ static int cinergyt2_submit_stream_urb (struct cinergyt2 *cinergyt2, struct urb return err; } -static void cinergyt2_stream_irq (struct urb *urb, struct pt_regs *regs) +static void cinergyt2_stream_irq (struct urb *urb) { struct cinergyt2 *cinergyt2 = urb->context; @@ -272,10 +276,9 @@ static void cinergyt2_free_stream_urbs (struct cinergyt2 *cinergyt2) int i; for (i=0; istream_urb[i]) - usb_free_urb(cinergyt2->stream_urb[i]); + usb_free_urb(cinergyt2->stream_urb[i]); - pci_free_consistent(NULL, STREAM_URB_COUNT*STREAM_BUF_SIZE, + usb_buffer_free(cinergyt2->udev, STREAM_URB_COUNT*STREAM_BUF_SIZE, cinergyt2->streambuf, cinergyt2->streambuf_dmahandle); } @@ -283,9 +286,8 @@ static int cinergyt2_alloc_stream_urbs (struct cinergyt2 *cinergyt2) { int i; - cinergyt2->streambuf = pci_alloc_consistent(NULL, - STREAM_URB_COUNT*STREAM_BUF_SIZE, - &cinergyt2->streambuf_dmahandle); + cinergyt2->streambuf = usb_buffer_alloc(cinergyt2->udev, STREAM_URB_COUNT*STREAM_BUF_SIZE, + GFP_KERNEL, &cinergyt2->streambuf_dmahandle); if (!cinergyt2->streambuf) { dprintk(1, "failed to alloc consistent stream memory area, bailing out!\n"); return -ENOMEM; @@ -318,8 +320,7 @@ static void cinergyt2_stop_stream_xfer (struct cinergyt2 *cinergyt2) cinergyt2_control_stream_transfer(cinergyt2, 0); for (i=0; istream_urb[i]) - usb_kill_urb(cinergyt2->stream_urb[i]); + usb_kill_urb(cinergyt2->stream_urb[i]); } static int cinergyt2_start_stream_xfer (struct cinergyt2 *cinergyt2) @@ -343,14 +344,14 @@ static int cinergyt2_start_feed(struct dvb_demux_feed *dvbdmxfeed) struct dvb_demux *demux = dvbdmxfeed->demux; struct cinergyt2 *cinergyt2 = demux->priv; - if (down_interruptible(&cinergyt2->sem)) + if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) return -ERESTARTSYS; if (cinergyt2->streaming == 0) cinergyt2_start_stream_xfer(cinergyt2); cinergyt2->streaming++; - up(&cinergyt2->sem); + mutex_unlock(&cinergyt2->sem); return 0; } @@ -359,13 +360,13 @@ static int cinergyt2_stop_feed(struct dvb_demux_feed *dvbdmxfeed) struct dvb_demux *demux = dvbdmxfeed->demux; struct cinergyt2 *cinergyt2 = demux->priv; - if (down_interruptible(&cinergyt2->sem)) + if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) return -ERESTARTSYS; if (--cinergyt2->streaming == 0) cinergyt2_stop_stream_xfer(cinergyt2); - up(&cinergyt2->sem); + mutex_unlock(&cinergyt2->sem); return 0; } @@ -479,38 +480,60 @@ static int cinergyt2_open (struct inode *inode, struct file *file) { struct dvb_device *dvbdev = file->private_data; struct cinergyt2 *cinergyt2 = dvbdev->priv; - int err; + int err = -ERESTARTSYS; + + if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) + return -ERESTARTSYS; - if ((err = dvb_generic_open(inode, file))) + if ((err = dvb_generic_open(inode, file))) { + mutex_unlock(&cinergyt2->sem); return err; + } - if (down_interruptible(&cinergyt2->sem)) - return -ERESTARTSYS; if ((file->f_flags & O_ACCMODE) != O_RDONLY) { cinergyt2_sleep(cinergyt2, 0); schedule_delayed_work(&cinergyt2->query_work, HZ/2); } - up(&cinergyt2->sem); + atomic_inc(&cinergyt2->inuse); + + mutex_unlock(&cinergyt2->sem); return 0; } +static void cinergyt2_unregister(struct cinergyt2 *cinergyt2) +{ + dvb_net_release(&cinergyt2->dvbnet); + dvb_dmxdev_release(&cinergyt2->dmxdev); + dvb_dmx_release(&cinergyt2->demux); + dvb_unregister_device(cinergyt2->fedev); + dvb_unregister_adapter(&cinergyt2->adapter); + + cinergyt2_free_stream_urbs(cinergyt2); + kfree(cinergyt2); +} + static int cinergyt2_release (struct inode *inode, struct file *file) { struct dvb_device *dvbdev = file->private_data; struct cinergyt2 *cinergyt2 = dvbdev->priv; - if (down_interruptible(&cinergyt2->sem)) + if (mutex_lock_interruptible(&cinergyt2->sem)) return -ERESTARTSYS; - if ((file->f_flags & O_ACCMODE) != O_RDONLY) { + if (!cinergyt2->disconnect_pending && (file->f_flags & O_ACCMODE) != O_RDONLY) { cancel_delayed_work(&cinergyt2->query_work); flush_scheduled_work(); cinergyt2_sleep(cinergyt2, 1); } - up(&cinergyt2->sem); + mutex_unlock(&cinergyt2->sem); + + if (atomic_dec_and_test(&cinergyt2->inuse) && cinergyt2->disconnect_pending) { + warn("delayed unregister in release"); + cinergyt2_unregister(cinergyt2); + } return dvb_generic_release(inode, file); } @@ -519,8 +542,19 @@ static unsigned int cinergyt2_poll (struct file *file, struct poll_table_struct { struct dvb_device *dvbdev = file->private_data; struct cinergyt2 *cinergyt2 = dvbdev->priv; + unsigned int mask = 0; + + if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) + return -ERESTARTSYS; + poll_wait(file, &cinergyt2->poll_wq, wait); - return (POLLIN | POLLRDNORM | POLLPRI); + + if (cinergyt2->pending_fe_events != 0) + mask |= (POLLIN | POLLRDNORM | POLLPRI); + + mutex_unlock(&cinergyt2->sem); + + return mask; } @@ -564,10 +598,15 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file, (__u16 __user *) arg); case FE_READ_UNCORRECTED_BLOCKS: - /* UNC are already converted to host byte order... */ - return put_user(stat->uncorrected_block_count, - (__u32 __user *) arg); + { + uint32_t unc_count; + unc_count = stat->uncorrected_block_count; + stat->uncorrected_block_count = 0; + + /* UNC are already converted to host byte order... */ + return put_user(unc_count,(__u32 __user *) arg); + } case FE_SET_FRONTEND: { struct dvbt_set_parameters_msg *param = &cinergyt2->param; @@ -580,7 +619,7 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file, if (copy_from_user(&p, (void __user*) arg, sizeof(p))) return -EFAULT; - if (down_interruptible(&cinergyt2->sem)) + if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) return -ERESTARTSYS; param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; @@ -596,7 +635,7 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file, (char *) param, sizeof(*param), NULL, 0); - up(&cinergyt2->sem); + mutex_unlock(&cinergyt2->sem); return (err < 0) ? err : 0; } @@ -683,68 +722,151 @@ static struct dvb_device cinergyt2_fe_template = { }; #ifdef ENABLE_RC -static void cinergyt2_query_rc (void *data) + +static void cinergyt2_query_rc (struct work_struct *work) { - struct cinergyt2 *cinergyt2 = (struct cinergyt2 *) data; - char buf [1] = { CINERGYT2_EP1_GET_RC_EVENTS }; + struct cinergyt2 *cinergyt2 = + container_of(work, struct cinergyt2, rc_query_work.work); + char buf[1] = { CINERGYT2_EP1_GET_RC_EVENTS }; struct cinergyt2_rc_event rc_events[12]; - int n, len; + int n, len, i; - if (down_interruptible(&cinergyt2->sem)) + if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) return; len = cinergyt2_command(cinergyt2, buf, sizeof(buf), - (char *) rc_events, sizeof(rc_events)); + (char *) rc_events, sizeof(rc_events)); + if (len < 0) + goto out; + if (len == 0) { + if (time_after(jiffies, cinergyt2->last_event_jiffies + + msecs_to_jiffies(150))) { + /* stop key repeat */ + if (cinergyt2->rc_input_event != KEY_MAX) { + dprintk(1, "rc_input_event=%d Up\n", cinergyt2->rc_input_event); + input_report_key(cinergyt2->rc_input_dev, + cinergyt2->rc_input_event, 0); + input_sync(cinergyt2->rc_input_dev); + cinergyt2->rc_input_event = KEY_MAX; + } + cinergyt2->rc_last_code = ~0; + } + goto out; + } + cinergyt2->last_event_jiffies = jiffies; - for (n=0; len>0 && n<(len/sizeof(rc_events[0])); n++) { - int i; + for (n = 0; n < (len / sizeof(rc_events[0])); n++) { + dprintk(1, "rc_events[%d].value = %x, type=%x\n", + n, le32_to_cpu(rc_events[n].value), rc_events[n].type); if (rc_events[n].type == CINERGYT2_RC_EVENT_TYPE_NEC && - rc_events[n].value == ~0) - { - /** - * keyrepeat bit. If we would handle this properly - * we would need to emit down events as long the - * keyrepeat goes, a up event if no further - * repeat bits occur. Would need a timer to implement - * and no other driver does this, so we simply - * emit the last key up/down sequence again. - */ + rc_events[n].value == ~0) { + /* keyrepeat bit -> just repeat last rc_input_event */ } else { cinergyt2->rc_input_event = KEY_MAX; - for (i=0; irc_input_event = rc_keys[i+2]; + for (i = 0; i < ARRAY_SIZE(rc_keys); i += 3) { + if (rc_keys[i + 0] == rc_events[n].type && + rc_keys[i + 1] == le32_to_cpu(rc_events[n].value)) { + cinergyt2->rc_input_event = rc_keys[i + 2]; break; } } } if (cinergyt2->rc_input_event != KEY_MAX) { - input_report_key(&cinergyt2->rc_input_dev, cinergyt2->rc_input_event, 1); - input_report_key(&cinergyt2->rc_input_dev, cinergyt2->rc_input_event, 0); - input_sync(&cinergyt2->rc_input_dev); + if (rc_events[n].value == cinergyt2->rc_last_code && + cinergyt2->rc_last_code != ~0) { + /* emit a key-up so the double event is recognized */ + dprintk(1, "rc_input_event=%d UP\n", cinergyt2->rc_input_event); + input_report_key(cinergyt2->rc_input_dev, + cinergyt2->rc_input_event, 0); + } + dprintk(1, "rc_input_event=%d\n", cinergyt2->rc_input_event); + input_report_key(cinergyt2->rc_input_dev, + cinergyt2->rc_input_event, 1); + input_sync(cinergyt2->rc_input_dev); + cinergyt2->rc_last_code = rc_events[n].value; } } +out: schedule_delayed_work(&cinergyt2->rc_query_work, msecs_to_jiffies(RC_QUERY_INTERVAL)); - up(&cinergyt2->sem); + mutex_unlock(&cinergyt2->sem); } -#endif -static void cinergyt2_query (void *data) +static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) { - struct cinergyt2 *cinergyt2 = (struct cinergyt2 *) data; + struct input_dev *input_dev; + int i; + int err; + + input_dev = input_allocate_device(); + if (!input_dev) + return -ENOMEM; + + usb_make_path(cinergyt2->udev, cinergyt2->phys, sizeof(cinergyt2->phys)); + strlcat(cinergyt2->phys, "/input0", sizeof(cinergyt2->phys)); + cinergyt2->rc_input_event = KEY_MAX; + cinergyt2->rc_last_code = ~0; + INIT_DELAYED_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc); + + input_dev->name = DRIVER_NAME " remote control"; + input_dev->phys = cinergyt2->phys; + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + for (i = 0; i < ARRAY_SIZE(rc_keys); i += 3) + set_bit(rc_keys[i + 2], input_dev->keybit); + input_dev->keycodesize = 0; + input_dev->keycodemax = 0; + + err = input_register_device(input_dev); + if (err) { + input_free_device(input_dev); + return err; + } + + cinergyt2->rc_input_dev = input_dev; + schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2); + + return 0; +} + +static void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2) +{ + cancel_delayed_work(&cinergyt2->rc_query_work); + input_unregister_device(cinergyt2->rc_input_dev); +} + +static inline void cinergyt2_suspend_rc(struct cinergyt2 *cinergyt2) +{ + cancel_delayed_work(&cinergyt2->rc_query_work); +} + +static inline void cinergyt2_resume_rc(struct cinergyt2 *cinergyt2) +{ + schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2); +} + +#else + +static inline int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) { return 0; } +static inline void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2) { } +static inline void cinergyt2_suspend_rc(struct cinergyt2 *cinergyt2) { } +static inline void cinergyt2_resume_rc(struct cinergyt2 *cinergyt2) { } + +#endif /* ENABLE_RC */ + +static void cinergyt2_query (struct work_struct *work) +{ + struct cinergyt2 *cinergyt2 = + container_of(work, struct cinergyt2, query_work.work); char cmd [] = { CINERGYT2_EP1_GET_TUNER_STATUS }; struct dvbt_get_status_msg *s = &cinergyt2->status; uint8_t lock_bits; uint32_t unc; - if (down_interruptible(&cinergyt2->sem)) + if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) return; unc = s->uncorrected_block_count; @@ -763,14 +885,14 @@ static void cinergyt2_query (void *data) schedule_delayed_work(&cinergyt2->query_work, msecs_to_jiffies(QUERY_INTERVAL)); - up(&cinergyt2->sem); + mutex_unlock(&cinergyt2->sem); } static int cinergyt2_probe (struct usb_interface *intf, const struct usb_device_id *id) { struct cinergyt2 *cinergyt2; - int i, err; + int err; if (!(cinergyt2 = kmalloc (sizeof(struct cinergyt2), GFP_KERNEL))) { dprintk(1, "out of memory?!?\n"); @@ -780,9 +902,9 @@ static int cinergyt2_probe (struct usb_interface *intf, memset (cinergyt2, 0, sizeof (struct cinergyt2)); usb_set_intfdata (intf, (void *) cinergyt2); - init_MUTEX(&cinergyt2->sem); + mutex_init(&cinergyt2->sem); init_waitqueue_head (&cinergyt2->poll_wq); - INIT_WORK(&cinergyt2->query_work, cinergyt2_query, cinergyt2); + INIT_DELAYED_WORK(&cinergyt2->query_work, cinergyt2_query); cinergyt2->udev = interface_to_usbdev(intf); cinergyt2->param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; @@ -793,7 +915,10 @@ static int cinergyt2_probe (struct usb_interface *intf, return -ENOMEM; } - dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, THIS_MODULE); + if ((err = dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, THIS_MODULE, &cinergyt2->udev->dev)) < 0) { + kfree(cinergyt2); + return err; + } cinergyt2->demux.priv = cinergyt2; cinergyt2->demux.filternum = 256; @@ -825,31 +950,18 @@ static int cinergyt2_probe (struct usb_interface *intf, &cinergyt2_fe_template, cinergyt2, DVB_DEVICE_FRONTEND); -#ifdef ENABLE_RC - init_input_dev(&cinergyt2->rc_input_dev); - - cinergyt2->rc_input_dev.evbit[0] = BIT(EV_KEY); - cinergyt2->rc_input_dev.keycodesize = sizeof(unsigned char); - cinergyt2->rc_input_dev.keycodemax = KEY_MAX; - cinergyt2->rc_input_dev.name = DRIVER_NAME " remote control"; - - for (i=0; irc_input_dev.keybit); - - input_register_device(&cinergyt2->rc_input_dev); - - cinergyt2->rc_input_event = KEY_MAX; + err = cinergyt2_register_rc(cinergyt2); + if (err) + goto bailout; - INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2); - schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2); -#endif return 0; bailout: + dvb_net_release(&cinergyt2->dvbnet); dvb_dmxdev_release(&cinergyt2->dmxdev); dvb_dmx_release(&cinergyt2->demux); - dvb_unregister_adapter (&cinergyt2->adapter); - cinergyt2_free_stream_urbs (cinergyt2); + dvb_unregister_adapter(&cinergyt2->adapter); + cinergyt2_free_stream_urbs(cinergyt2); kfree(cinergyt2); return -ENOMEM; } @@ -858,39 +970,31 @@ static void cinergyt2_disconnect (struct usb_interface *intf) { struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); - if (down_interruptible(&cinergyt2->sem)) - return; - -#ifdef ENABLE_RC - cancel_delayed_work(&cinergyt2->rc_query_work); flush_scheduled_work(); - input_unregister_device(&cinergyt2->rc_input_dev); -#endif + + cinergyt2_unregister_rc(cinergyt2); + + cancel_delayed_work(&cinergyt2->query_work); + wake_up_interruptible(&cinergyt2->poll_wq); cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx); - dvb_net_release(&cinergyt2->dvbnet); - dvb_dmxdev_release(&cinergyt2->dmxdev); - dvb_dmx_release(&cinergyt2->demux); - dvb_unregister_device(cinergyt2->fedev); - dvb_unregister_adapter(&cinergyt2->adapter); + cinergyt2->disconnect_pending = 1; - cinergyt2_free_stream_urbs(cinergyt2); - up(&cinergyt2->sem); - kfree(cinergyt2); + if (!atomic_read(&cinergyt2->inuse)) + cinergyt2_unregister(cinergyt2); } static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state) { struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); - if (down_interruptible(&cinergyt2->sem)) + if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) return -ERESTARTSYS; - if (state > 0) { /* state 0 seems to mean DEVICE_PM_ON */ + if (1) { struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); -#ifdef ENABLE_RC - cancel_delayed_work(&cinergyt2->rc_query_work); -#endif + + cinergyt2_suspend_rc(cinergyt2); cancel_delayed_work(&cinergyt2->query_work); if (cinergyt2->streaming) cinergyt2_stop_stream_xfer(cinergyt2); @@ -898,7 +1002,7 @@ static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state) cinergyt2_sleep(cinergyt2, 1); } - up(&cinergyt2->sem); + mutex_unlock(&cinergyt2->sem); return 0; } @@ -907,7 +1011,7 @@ static int cinergyt2_resume (struct usb_interface *intf) struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); struct dvbt_set_parameters_msg *param = &cinergyt2->param; - if (down_interruptible(&cinergyt2->sem)) + if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) return -ERESTARTSYS; if (!cinergyt2->sleeping) { @@ -918,10 +1022,9 @@ static int cinergyt2_resume (struct usb_interface *intf) schedule_delayed_work(&cinergyt2->query_work, HZ/2); } -#ifdef ENABLE_RC - schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2); -#endif - up(&cinergyt2->sem); + cinergyt2_resume_rc(cinergyt2); + + mutex_unlock(&cinergyt2->sem); return 0; } @@ -933,7 +1036,6 @@ static const struct usb_device_id cinergyt2_table [] __devinitdata = { MODULE_DEVICE_TABLE(usb, cinergyt2_table); static struct usb_driver cinergyt2_driver = { - .owner = THIS_MODULE, .name = "cinergyT2", .probe = cinergyt2_probe, .disconnect = cinergyt2_disconnect, @@ -962,4 +1064,3 @@ module_exit (cinergyt2_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Holger Waechtler, Daniel Mack"); -