diff options
Diffstat (limited to 'drivers/media/usb/ttusb-dec/ttusb_dec.c')
| -rw-r--r-- | drivers/media/usb/ttusb-dec/ttusb_dec.c | 81 |
1 files changed, 32 insertions, 49 deletions
diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c index 44ca66cb9b8f..b4575fe89c95 100644 --- a/drivers/media/usb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c @@ -1,19 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * TTUSB DEC Driver * * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org> * IR support by Peter Beutner <p.beutner@gmx.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <linux/list.h> @@ -29,6 +19,7 @@ #include <linux/input.h> #include <linux/mutex.h> +#include <linux/workqueue.h> #include <media/dmxdev.h> #include <media/dvb_demux.h> @@ -149,7 +140,7 @@ struct ttusb_dec { int v_pes_postbytes; struct list_head urb_frame_list; - struct tasklet_struct urb_tasklet; + struct work_struct urb_bh_work; spinlock_t urb_frame_list_lock; struct dvb_demux_filter *audio_filter; @@ -260,6 +251,7 @@ static void ttusb_dec_handle_irq( struct urb *urb) struct ttusb_dec *dec = urb->context; char *buffer = dec->irq_buffer; int retval; + int index = buffer[4]; switch(urb->status) { case 0: /*success*/ @@ -284,18 +276,18 @@ static void ttusb_dec_handle_irq( struct urb *urb) * * this is an fact a bit too simple implementation; * the box also reports a keyrepeat signal - * (with buffer[3] == 0x40) in an intervall of ~100ms. + * (with buffer[3] == 0x40) in an interval of ~100ms. * But to handle this correctly we had to imlemenent some * kind of timer which signals a 'key up' event if no * keyrepeat signal is received for lets say 200ms. * this should/could be added later ... * for now lets report each signal as a key down and up */ - if (buffer[4] - 1 < ARRAY_SIZE(rc_keys)) { - dprintk("%s:rc signal:%d\n", __func__, buffer[4]); - input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 1); + if (index - 1 < ARRAY_SIZE(rc_keys)) { + dprintk("%s:rc signal:%d\n", __func__, index); + input_report_key(dec->rc_input_dev, rc_keys[index - 1], 1); input_sync(dec->rc_input_dev); - input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 0); + input_report_key(dec->rc_input_dev, rc_keys[index - 1], 0); input_sync(dec->rc_input_dev); } } @@ -329,14 +321,14 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, dprintk("%s\n", __func__); - b = kmalloc(COMMAND_PACKET_SIZE + 4, GFP_KERNEL); + b = kzalloc(COMMAND_PACKET_SIZE + 4, GFP_KERNEL); if (!b) return -ENOMEM; - if ((result = mutex_lock_interruptible(&dec->usb_mutex))) { - kfree(b); + result = mutex_lock_interruptible(&dec->usb_mutex); + if (result) { printk("%s: Failed to lock usb mutex.\n", __func__); - return result; + goto err_free; } b[0] = 0xaa; @@ -358,9 +350,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, if (result) { printk("%s: command bulk message failed: error %d\n", __func__, result); - mutex_unlock(&dec->usb_mutex); - kfree(b); - return result; + goto err_mutex_unlock; } result = usb_bulk_msg(dec->udev, dec->result_pipe, b, @@ -369,9 +359,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, if (result) { printk("%s: result bulk message failed: error %d\n", __func__, result); - mutex_unlock(&dec->usb_mutex); - kfree(b); - return result; + goto err_mutex_unlock; } else { if (debug) { printk(KERN_DEBUG "%s: result: %*ph\n", @@ -382,12 +370,13 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, *result_length = b[3]; if (cmd_result && b[3] > 0) memcpy(cmd_result, &b[4], b[3]); - - mutex_unlock(&dec->usb_mutex); - - kfree(b); - return 0; } + +err_mutex_unlock: + mutex_unlock(&dec->usb_mutex); +err_free: + kfree(b); + return result; } static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode, @@ -778,9 +767,9 @@ static void ttusb_dec_process_urb_frame(struct ttusb_dec *dec, u8 *b, } } -static void ttusb_dec_process_urb_frame_list(unsigned long data) +static void ttusb_dec_process_urb_frame_list(struct work_struct *t) { - struct ttusb_dec *dec = (struct ttusb_dec *)data; + struct ttusb_dec *dec = from_work(dec, t, urb_bh_work); struct list_head *item; struct urb_frame *frame; unsigned long flags; @@ -834,7 +823,7 @@ static void ttusb_dec_process_urb(struct urb *urb) spin_unlock_irqrestore(&dec->urb_frame_list_lock, flags); - tasklet_schedule(&dec->urb_tasklet); + queue_work(system_bh_wq, &dec->urb_bh_work); } } } else { @@ -1111,11 +1100,9 @@ static int ttusb_dec_start_feed(struct dvb_demux_feed *dvbdmxfeed) case DMX_TYPE_TS: return ttusb_dec_start_ts_feed(dvbdmxfeed); - break; case DMX_TYPE_SEC: return ttusb_dec_start_sec_feed(dvbdmxfeed); - break; default: dprintk(" type: unknown (%d)\n", dvbdmxfeed->type); @@ -1142,7 +1129,7 @@ static int ttusb_dec_stop_sec_feed(struct dvb_demux_feed *dvbdmxfeed) { struct ttusb_dec *dec = dvbdmxfeed->demux->priv; u8 b0[] = { 0x00, 0x00 }; - struct filter_info *finfo = (struct filter_info *)dvbdmxfeed->priv; + struct filter_info *finfo = dvbdmxfeed->priv; unsigned long flags; b0[1] = finfo->stream_id; @@ -1166,11 +1153,9 @@ static int ttusb_dec_stop_feed(struct dvb_demux_feed *dvbdmxfeed) switch (dvbdmxfeed->type) { case DMX_TYPE_TS: return ttusb_dec_stop_ts_feed(dvbdmxfeed); - break; case DMX_TYPE_SEC: return ttusb_dec_stop_sec_feed(dvbdmxfeed); - break; } return 0; @@ -1214,12 +1199,11 @@ static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec) return 0; } -static void ttusb_dec_init_tasklet(struct ttusb_dec *dec) +static void ttusb_dec_init_bh_work(struct ttusb_dec *dec) { spin_lock_init(&dec->urb_frame_list_lock); INIT_LIST_HEAD(&dec->urb_frame_list); - tasklet_init(&dec->urb_tasklet, ttusb_dec_process_urb_frame_list, - (unsigned long)dec); + INIT_WORK(&dec->urb_bh_work, ttusb_dec_process_urb_frame_list); } static int ttusb_init_rc( struct ttusb_dec *dec) @@ -1561,8 +1545,7 @@ static void ttusb_dec_exit_dvb(struct ttusb_dec *dec) dvb_dmx_release(&dec->demux); if (dec->fe) { dvb_unregister_frontend(dec->fe); - if (dec->fe->ops.release) - dec->fe->ops.release(dec->fe); + dvb_frontend_detach(dec->fe); } dvb_unregister_adapter(&dec->adapter); } @@ -1606,12 +1589,12 @@ static void ttusb_dec_exit_usb(struct ttusb_dec *dec) ttusb_dec_free_iso_urbs(dec); } -static void ttusb_dec_exit_tasklet(struct ttusb_dec *dec) +static void ttusb_dec_exit_bh_work(struct ttusb_dec *dec) { struct list_head *item; struct urb_frame *frame; - tasklet_kill(&dec->urb_tasklet); + cancel_work_sync(&dec->urb_bh_work); while ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) { frame = list_entry(item, struct urb_frame, urb_frame_list); @@ -1721,7 +1704,7 @@ static int ttusb_dec_probe(struct usb_interface *intf, ttusb_dec_init_v_pes(dec); ttusb_dec_init_filters(dec); - ttusb_dec_init_tasklet(dec); + ttusb_dec_init_bh_work(dec); dec->active = 1; @@ -1747,7 +1730,7 @@ static void ttusb_dec_disconnect(struct usb_interface *intf) dprintk("%s\n", __func__); if (dec->active) { - ttusb_dec_exit_tasklet(dec); + ttusb_dec_exit_bh_work(dec); ttusb_dec_exit_filters(dec); if(enable_rc) ttusb_dec_exit_rc(dec); |
