diff options
Diffstat (limited to 'drivers/media/rc')
34 files changed, 373 insertions, 205 deletions
diff --git a/drivers/media/rc/ati_remote.c b/drivers/media/rc/ati_remote.c index a733914a2574..51d85de24fae 100644 --- a/drivers/media/rc/ati_remote.c +++ b/drivers/media/rc/ati_remote.c @@ -839,7 +839,7 @@ static int ati_remote_probe(struct usb_interface *interface, return -ENODEV; } - ati_remote = kzalloc(sizeof (struct ati_remote), GFP_KERNEL); + ati_remote = kzalloc_obj(struct ati_remote); rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE); if (!ati_remote || !rc_dev) goto exit_free_dev_rdev; @@ -921,7 +921,6 @@ static int ati_remote_probe(struct usb_interface *interface, input_free_device(input_dev); exit_unregister_device: rc_unregister_device(rc_dev); - rc_dev = NULL; exit_kill_urbs: usb_kill_urb(ati_remote->irq_urb); usb_kill_urb(ati_remote->out_urb); @@ -941,18 +940,19 @@ static void ati_remote_disconnect(struct usb_interface *interface) struct ati_remote *ati_remote; ati_remote = usb_get_intfdata(interface); - usb_set_intfdata(interface, NULL); if (!ati_remote) { dev_warn(&interface->dev, "%s - null device?\n", __func__); return; } + rc_unregister_device(ati_remote->rdev); + usb_set_intfdata(interface, NULL); usb_kill_urb(ati_remote->irq_urb); usb_kill_urb(ati_remote->out_urb); if (ati_remote->idev) input_unregister_device(ati_remote->idev); - rc_unregister_device(ati_remote->rdev); ati_remote_free_buffers(ati_remote); + rc_free_device(ati_remote->rdev); kfree(ati_remote); } diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c index 67722e2e47ff..6f7dccc965e7 100644 --- a/drivers/media/rc/ene_ir.c +++ b/drivers/media/rc/ene_ir.c @@ -659,7 +659,7 @@ exit: /* timer to simulate tx done interrupt */ static void ene_tx_irqsim(struct timer_list *t) { - struct ene_device *dev = from_timer(dev, t, tx_sim_timer); + struct ene_device *dev = timer_container_of(dev, t, tx_sim_timer); unsigned long flags; spin_lock_irqsave(&dev->hw_lock, flags); @@ -993,7 +993,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) struct ene_device *dev; /* allocate memory */ - dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL); + dev = kzalloc_obj(struct ene_device); rdev = rc_allocate_device(RC_DRIVER_IR_RAW); if (!dev || !rdev) goto exit_free_dev_rdev; @@ -1090,7 +1090,6 @@ exit_release_hw_io: release_region(dev->hw_io, ENE_IO_SIZE); exit_unregister_device: rc_unregister_device(rdev); - rdev = NULL; exit_free_dev_rdev: rc_free_device(rdev); kfree(dev); @@ -1104,12 +1103,13 @@ static void ene_remove(struct pnp_dev *pnp_dev) unsigned long flags; rc_unregister_device(dev->rdev); - del_timer_sync(&dev->tx_sim_timer); + timer_delete_sync(&dev->tx_sim_timer); spin_lock_irqsave(&dev->hw_lock, flags); ene_rx_disable(dev); ene_rx_restore_hw_buffer(dev); spin_unlock_irqrestore(&dev->hw_lock, flags); + rc_free_device(dev->rdev); free_irq(dev->irq, dev); release_region(dev->hw_io, ENE_IO_SIZE); kfree(dev); diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c index 3fb0968efd57..5055dfc3f465 100644 --- a/drivers/media/rc/fintek-cir.c +++ b/drivers/media/rc/fintek-cir.c @@ -465,7 +465,7 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id struct rc_dev *rdev; int ret = -ENOMEM; - fintek = kzalloc(sizeof(struct fintek_dev), GFP_KERNEL); + fintek = kzalloc_obj(struct fintek_dev); if (!fintek) return ret; @@ -568,6 +568,7 @@ static void fintek_remove(struct pnp_dev *pdev) struct fintek_dev *fintek = pnp_get_drvdata(pdev); unsigned long flags; + rc_unregister_device(fintek->rdev); spin_lock_irqsave(&fintek->fintek_lock, flags); /* disable CIR */ fintek_disable_cir(fintek); @@ -580,7 +581,7 @@ static void fintek_remove(struct pnp_dev *pdev) free_irq(fintek->cir_irq, fintek); release_region(fintek->cir_addr, fintek->cir_port_len); - rc_unregister_device(fintek->rdev); + rc_free_device(fintek->rdev); kfree(fintek); } diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c index bf6d8fa983bf..a6418ef782bc 100644 --- a/drivers/media/rc/gpio-ir-recv.c +++ b/drivers/media/rc/gpio-ir-recv.c @@ -48,10 +48,8 @@ static irqreturn_t gpio_ir_recv_irq(int irq, void *dev_id) if (val >= 0) ir_raw_event_store_edge(gpio_dev->rcdev, val == 1); - if (pmdev) { - pm_runtime_mark_last_busy(pmdev); + if (pmdev) pm_runtime_put_autosuspend(pmdev); - } return IRQ_HANDLED; } diff --git a/drivers/media/rc/gpio-ir-tx.c b/drivers/media/rc/gpio-ir-tx.c index e185ead40464..d15fb17fa0fa 100644 --- a/drivers/media/rc/gpio-ir-tx.c +++ b/drivers/media/rc/gpio-ir-tx.c @@ -51,7 +51,7 @@ static int gpio_ir_tx_set_carrier(struct rc_dev *dev, u32 carrier) static void delay_until(ktime_t until) { /* - * delta should never exceed 0.5 seconds (IR_MAX_DURATION) and on + * delta should never exceed 1 second (IR_MAX_DURATION) and on * m68k ndelay(s64) does not compile; so use s32 rather than s64. */ s32 delta; @@ -95,7 +95,7 @@ static void gpio_ir_tx_modulated(struct gpio_ir *gpio_ir, uint *txbuf, { ktime_t edge; /* - * delta should never exceed 0.5 seconds (IR_MAX_DURATION) and on + * delta should never exceed 1 second (IR_MAX_DURATION) and on * m68k ndelay(s64) does not compile; so use s32 rather than s64. */ s32 delta; diff --git a/drivers/media/rc/igorplugusb.c b/drivers/media/rc/igorplugusb.c index 1464ef9c55bc..3e10f6fe89f8 100644 --- a/drivers/media/rc/igorplugusb.c +++ b/drivers/media/rc/igorplugusb.c @@ -34,7 +34,7 @@ struct igorplugusb { struct device *dev; struct urb *urb; - struct usb_ctrlrequest request; + struct usb_ctrlrequest *request; struct timer_list timer; @@ -122,7 +122,7 @@ static void igorplugusb_cmd(struct igorplugusb *ir, int cmd) { int ret; - ir->request.bRequest = cmd; + ir->request->bRequest = cmd; ir->urb->transfer_flags = 0; ret = usb_submit_urb(ir->urb, GFP_ATOMIC); if (ret && ret != -EPERM) @@ -131,7 +131,7 @@ static void igorplugusb_cmd(struct igorplugusb *ir, int cmd) static void igorplugusb_timer(struct timer_list *t) { - struct igorplugusb *ir = from_timer(ir, t, timer); + struct igorplugusb *ir = timer_container_of(ir, t, timer); igorplugusb_cmd(ir, GET_INFRACODE); } @@ -164,13 +164,17 @@ static int igorplugusb_probe(struct usb_interface *intf, if (!ir) return -ENOMEM; + ir->request = kzalloc_obj(*ir->request, GFP_KERNEL); + if (!ir->request) + goto fail; + ir->dev = &intf->dev; timer_setup(&ir->timer, igorplugusb_timer, 0); - ir->request.bRequest = GET_INFRACODE; - ir->request.bRequestType = USB_TYPE_VENDOR | USB_DIR_IN; - ir->request.wLength = cpu_to_le16(MAX_PACKET); + ir->request->bRequest = GET_INFRACODE; + ir->request->bRequestType = USB_TYPE_VENDOR | USB_DIR_IN; + ir->request->wLength = cpu_to_le16(MAX_PACKET); ir->urb = usb_alloc_urb(0, GFP_KERNEL); if (!ir->urb) @@ -223,11 +227,12 @@ static int igorplugusb_probe(struct usb_interface *intf, return 0; fail: usb_poison_urb(ir->urb); - del_timer(&ir->timer); + timer_delete(&ir->timer); usb_unpoison_urb(ir->urb); usb_free_urb(ir->urb); rc_free_device(ir->rc); kfree(ir->buf_in); + kfree(ir->request); return ret; } @@ -238,11 +243,13 @@ static void igorplugusb_disconnect(struct usb_interface *intf) rc_unregister_device(ir->rc); usb_poison_urb(ir->urb); - del_timer_sync(&ir->timer); + timer_delete_sync(&ir->timer); usb_set_intfdata(intf, NULL); usb_unpoison_urb(ir->urb); usb_free_urb(ir->urb); + rc_free_device(ir->rc); kfree(ir->buf_in); + kfree(ir->request); } static const struct usb_device_id igorplugusb_table[] = { diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c index 8af94246e591..0c5b8befb0af 100644 --- a/drivers/media/rc/iguanair.c +++ b/drivers/media/rc/iguanair.c @@ -392,7 +392,7 @@ static int iguanair_probe(struct usb_interface *intf, if (idesc->desc.bNumEndpoints < 2) return -ENODEV; - ir = kzalloc(sizeof(*ir), GFP_KERNEL); + ir = kzalloc_obj(*ir); rc = rc_allocate_device(RC_DRIVER_IR_RAW); if (!ir || !rc) { ret = -ENOMEM; @@ -500,6 +500,7 @@ static void iguanair_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); usb_kill_urb(ir->urb_in); usb_kill_urb(ir->urb_out); + rc_free_device(ir->rc); usb_free_urb(ir->urb_in); usb_free_urb(ir->urb_out); usb_free_coherent(ir->udev, MAX_IN_PACKET, ir->buf_in, ir->dma_in); diff --git a/drivers/media/rc/img-ir/img-ir-hw.c b/drivers/media/rc/img-ir/img-ir-hw.c index 5da7479c1793..f30adf4d8444 100644 --- a/drivers/media/rc/img-ir/img-ir-hw.c +++ b/drivers/media/rc/img-ir/img-ir-hw.c @@ -556,8 +556,8 @@ static void img_ir_set_decoder(struct img_ir_priv *priv, * acquires the lock and we don't want to deadlock waiting for it. */ spin_unlock_irq(&priv->lock); - del_timer_sync(&hw->end_timer); - del_timer_sync(&hw->suspend_timer); + timer_delete_sync(&hw->end_timer); + timer_delete_sync(&hw->suspend_timer); spin_lock_irq(&priv->lock); hw->stopping = false; @@ -865,7 +865,7 @@ static void img_ir_handle_data(struct img_ir_priv *priv, u32 len, u64 raw) /* timer function to end waiting for repeat. */ static void img_ir_end_timer(struct timer_list *t) { - struct img_ir_priv *priv = from_timer(priv, t, hw.end_timer); + struct img_ir_priv *priv = timer_container_of(priv, t, hw.end_timer); spin_lock_irq(&priv->lock); img_ir_end_repeat(priv); @@ -879,7 +879,8 @@ static void img_ir_end_timer(struct timer_list *t) */ static void img_ir_suspend_timer(struct timer_list *t) { - struct img_ir_priv *priv = from_timer(priv, t, hw.suspend_timer); + struct img_ir_priv *priv = timer_container_of(priv, t, + hw.suspend_timer); spin_lock_irq(&priv->lock); /* @@ -1117,9 +1118,10 @@ void img_ir_remove_hw(struct img_ir_priv *priv) struct rc_dev *rdev = hw->rdev; if (!rdev) return; + rc_unregister_device(rdev); img_ir_set_decoder(priv, NULL, 0); hw->rdev = NULL; - rc_unregister_device(rdev); + rc_free_device(rdev); #ifdef CONFIG_COMMON_CLK if (!IS_ERR(priv->clk)) clk_notifier_unregister(priv->clk, &hw->clk_nb); diff --git a/drivers/media/rc/img-ir/img-ir-raw.c b/drivers/media/rc/img-ir/img-ir-raw.c index 8b0bdd9603b3..f1460d4acf3e 100644 --- a/drivers/media/rc/img-ir/img-ir-raw.c +++ b/drivers/media/rc/img-ir/img-ir-raw.c @@ -65,7 +65,7 @@ void img_ir_isr_raw(struct img_ir_priv *priv, u32 irq_status) */ static void img_ir_echo_timer(struct timer_list *t) { - struct img_ir_priv *priv = from_timer(priv, t, raw.timer); + struct img_ir_priv *priv = timer_container_of(priv, t, raw.timer); spin_lock_irq(&priv->lock); @@ -136,6 +136,7 @@ void img_ir_remove_raw(struct img_ir_priv *priv) if (!rdev) return; + rc_unregister_device(rdev); /* switch off and disable raw (edge) interrupts */ spin_lock_irq(&priv->lock); raw->rdev = NULL; @@ -145,7 +146,7 @@ void img_ir_remove_raw(struct img_ir_priv *priv) img_ir_write(priv, IMG_IR_IRQ_CLEAR, IMG_IR_IRQ_EDGE); spin_unlock_irq(&priv->lock); - rc_unregister_device(rdev); + rc_free_device(rdev); - del_timer_sync(&raw->timer); + timer_delete_sync(&raw->timer); } diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index 8f1361bcce3a..9bb27ba8240f 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -39,11 +39,6 @@ #define DISPLAY_MINOR_BASE 144 #define DEVICE_NAME "lcd%d" -#define BUF_CHUNK_SIZE 8 -#define BUF_SIZE 128 - -#define BIT_DURATION 250 /* each bit received is 250us */ - #define IMON_CLOCK_ENABLE_PACKETS 2 /*** P R O T O T Y P E S ***/ @@ -536,7 +531,9 @@ static int display_open(struct inode *inode, struct file *file) mutex_lock(&ictx->lock); - if (!ictx->display_supported) { + if (ictx->disconnected) { + retval = -ENODEV; + } else if (!ictx->display_supported) { pr_err("display not supported by device\n"); retval = -ENODEV; } else if (ictx->display_isopen) { @@ -598,6 +595,11 @@ static int send_packet(struct imon_context *ictx) int retval = 0; struct usb_ctrlrequest *control_req = NULL; + lockdep_assert_held(&ictx->lock); + + if (ictx->disconnected) + return -ENODEV; + /* Check if we need to use control or interrupt urb */ if (!ictx->tx_control) { pipe = usb_sndintpipe(ictx->usbdev_intf0, @@ -612,7 +614,7 @@ static int send_packet(struct imon_context *ictx) ictx->tx_urb->actual_length = 0; } else { /* fill request into kmalloc'ed space: */ - control_req = kmalloc(sizeof(*control_req), GFP_KERNEL); + control_req = kmalloc_obj(*control_req); if (control_req == NULL) return -ENOMEM; @@ -645,12 +647,15 @@ static int send_packet(struct imon_context *ictx) smp_rmb(); /* ensure later readers know we're not busy */ pr_err_ratelimited("error submitting urb(%d)\n", retval); } else { - /* Wait for transmission to complete (or abort) */ - retval = wait_for_completion_interruptible( - &ictx->tx.finished); - if (retval) { + /* Wait for transmission to complete (or abort or timeout) */ + retval = wait_for_completion_interruptible_timeout(&ictx->tx.finished, 10 * HZ); + if (retval <= 0) { usb_kill_urb(ictx->tx_urb); pr_err_ratelimited("task interrupted\n"); + if (retval < 0) + ictx->tx.status = retval; + else + ictx->tx.status = -ETIMEDOUT; } ictx->tx.busy = false; @@ -949,12 +954,14 @@ static ssize_t vfd_write(struct file *file, const char __user *buf, static const unsigned char vfd_packet6[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF }; - if (ictx->disconnected) - return -ENODEV; - if (mutex_lock_interruptible(&ictx->lock)) return -ERESTARTSYS; + if (ictx->disconnected) { + retval = -ENODEV; + goto exit; + } + if (!ictx->dev_present_intf0) { pr_err_ratelimited("no iMON device present\n"); retval = -ENODEV; @@ -1029,11 +1036,13 @@ static ssize_t lcd_write(struct file *file, const char __user *buf, int retval = 0; struct imon_context *ictx = file->private_data; - if (ictx->disconnected) - return -ENODEV; - mutex_lock(&ictx->lock); + if (ictx->disconnected) { + retval = -ENODEV; + goto exit; + } + if (!ictx->display_supported) { pr_err_ratelimited("no iMON display present\n"); retval = -ENODEV; @@ -1091,7 +1100,7 @@ static void usb_tx_callback(struct urb *urb) */ static void imon_touch_display_timeout(struct timer_list *t) { - struct imon_context *ictx = from_timer(ictx, t, ttimer); + struct imon_context *ictx = timer_container_of(ictx, t, ttimer); if (ictx->display_type != IMON_DISPLAY_TYPE_VGA) return; @@ -1121,7 +1130,7 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_proto) int retval; struct imon_context *ictx = rc->priv; struct device *dev = ictx->dev; - bool unlock = false; + const bool unlock = mutex_trylock(&ictx->lock); unsigned char ir_proto_packet[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 }; @@ -1148,8 +1157,6 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_proto) memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet)); - unlock = mutex_trylock(&ictx->lock); - retval = send_packet(ictx); if (retval) goto out; @@ -1745,14 +1752,6 @@ static void usb_rx_callback_intf0(struct urb *urb) if (!ictx) return; - /* - * if we get a callback before we're done configuring the hardware, we - * can't yet process the data, as there's nowhere to send it, but we - * still need to submit a new rx URB to avoid wedging the hardware - */ - if (!ictx->dev_present_intf0) - goto out; - switch (urb->status) { case -ENOENT: /* usbcore unlink successful! */ return; @@ -1761,16 +1760,29 @@ static void usb_rx_callback_intf0(struct urb *urb) break; case 0: - imon_incoming_packet(ictx, urb, intfnum); + /* + * if we get a callback before we're done configuring the hardware, we + * can't yet process the data, as there's nowhere to send it, but we + * still need to submit a new rx URB to avoid wedging the hardware + */ + if (ictx->dev_present_intf0) + imon_incoming_packet(ictx, urb, intfnum); break; + case -ECONNRESET: + case -EILSEQ: + case -EPROTO: + case -EPIPE: + dev_warn(ictx->dev, "imon %s: status(%d)\n", + __func__, urb->status); + return; + default: dev_warn(ictx->dev, "imon %s: status(%d): ignored\n", __func__, urb->status); break; } -out: usb_submit_urb(ictx->rx_urb_intf0, GFP_ATOMIC); } @@ -1786,14 +1798,6 @@ static void usb_rx_callback_intf1(struct urb *urb) if (!ictx) return; - /* - * if we get a callback before we're done configuring the hardware, we - * can't yet process the data, as there's nowhere to send it, but we - * still need to submit a new rx URB to avoid wedging the hardware - */ - if (!ictx->dev_present_intf1) - goto out; - switch (urb->status) { case -ENOENT: /* usbcore unlink successful! */ return; @@ -1802,16 +1806,29 @@ static void usb_rx_callback_intf1(struct urb *urb) break; case 0: - imon_incoming_packet(ictx, urb, intfnum); + /* + * if we get a callback before we're done configuring the hardware, we + * can't yet process the data, as there's nowhere to send it, but we + * still need to submit a new rx URB to avoid wedging the hardware + */ + if (ictx->dev_present_intf1) + imon_incoming_packet(ictx, urb, intfnum); break; + case -ECONNRESET: + case -EILSEQ: + case -EPROTO: + case -EPIPE: + dev_warn(ictx->dev, "imon %s: status(%d)\n", + __func__, urb->status); + return; + default: dev_warn(ictx->dev, "imon %s: status(%d): ignored\n", __func__, urb->status); break; } -out: usb_submit_urb(ictx->rx_urb_intf1, GFP_ATOMIC); } @@ -2216,7 +2233,7 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf, struct usb_host_interface *iface_desc; int ret = -ENOMEM; - ictx = kzalloc(sizeof(*ictx), GFP_KERNEL); + ictx = kzalloc_obj(*ictx); if (!ictx) goto exit; @@ -2233,7 +2250,7 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf, mutex_lock(&ictx->lock); ictx->dev = dev; - ictx->usbdev_intf0 = usb_get_dev(interface_to_usbdev(intf)); + ictx->usbdev_intf0 = interface_to_usbdev(intf); ictx->rx_urb_intf0 = rx_urb; ictx->tx_urb = tx_urb; ictx->rf_device = false; @@ -2291,7 +2308,6 @@ idev_setup_failed: usb_kill_urb(ictx->rx_urb_intf0); urb_submit_failed: find_endpoint_failed: - usb_put_dev(ictx->usbdev_intf0); mutex_unlock(&ictx->lock); usb_free_urb(tx_urb); tx_urb_alloc_failed: @@ -2321,7 +2337,7 @@ static struct imon_context *imon_init_intf1(struct usb_interface *intf, timer_setup(&ictx->ttimer, imon_touch_display_timeout, 0); } - ictx->usbdev_intf1 = usb_get_dev(interface_to_usbdev(intf)); + ictx->usbdev_intf1 = interface_to_usbdev(intf); ictx->rx_urb_intf1 = rx_urb; ret = -ENODEV; @@ -2360,7 +2376,6 @@ urb_submit_failed: input_unregister_device(ictx->touch); touch_setup_failed: find_endpoint_failed: - usb_put_dev(ictx->usbdev_intf1); ictx->usbdev_intf1 = NULL; mutex_unlock(&ictx->lock); usb_free_urb(rx_urb); @@ -2409,7 +2424,7 @@ static int imon_probe(struct usb_interface *interface, struct imon_context *ictx = NULL; u16 vendor, product; - usbdev = usb_get_dev(interface_to_usbdev(interface)); + usbdev = interface_to_usbdev(interface); iface_desc = interface->cur_altsetting; ifnum = iface_desc->desc.bInterfaceNumber; vendor = le16_to_cpu(usbdev->descriptor.idVendor); @@ -2478,12 +2493,9 @@ static int imon_probe(struct usb_interface *interface, vendor, product, ifnum, usbdev->bus->busnum, usbdev->devnum); - usb_put_dev(usbdev); - return 0; fail: - usb_put_dev(usbdev); dev_err(dev, "unable to register, err %d\n", ret); return ret; @@ -2499,7 +2511,11 @@ static void imon_disconnect(struct usb_interface *interface) int ifnum; ictx = usb_get_intfdata(interface); + + mutex_lock(&ictx->lock); ictx->disconnected = true; + mutex_unlock(&ictx->lock); + dev = ictx->dev; ifnum = interface->cur_altsetting->desc.bInterfaceNumber; @@ -2520,24 +2536,23 @@ static void imon_disconnect(struct usb_interface *interface) if (ifnum == 0) { ictx->dev_present_intf0 = false; + rc_unregister_device(ictx->rdev); usb_kill_urb(ictx->rx_urb_intf0); input_unregister_device(ictx->idev); - rc_unregister_device(ictx->rdev); + rc_free_device(ictx->rdev); if (ictx->display_supported) { if (ictx->display_type == IMON_DISPLAY_TYPE_LCD) usb_deregister_dev(interface, &imon_lcd_class); else if (ictx->display_type == IMON_DISPLAY_TYPE_VFD) usb_deregister_dev(interface, &imon_vfd_class); } - usb_put_dev(ictx->usbdev_intf0); } else { ictx->dev_present_intf1 = false; usb_kill_urb(ictx->rx_urb_intf1); if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) { - del_timer_sync(&ictx->ttimer); + timer_delete_sync(&ictx->ttimer); input_unregister_device(ictx->touch); } - usb_put_dev(ictx->usbdev_intf1); } if (refcount_dec_and_test(&ictx->users)) diff --git a/drivers/media/rc/ir-hix5hd2.c b/drivers/media/rc/ir-hix5hd2.c index afd80d2350c6..1b061e4a3dcf 100644 --- a/drivers/media/rc/ir-hix5hd2.c +++ b/drivers/media/rc/ir-hix5hd2.c @@ -331,7 +331,6 @@ static int hix5hd2_ir_probe(struct platform_device *pdev) regerr: rc_unregister_device(rdev); - rdev = NULL; clkerr: clk_disable_unprepare(priv->clock); err: @@ -346,6 +345,7 @@ static void hix5hd2_ir_remove(struct platform_device *pdev) clk_disable_unprepare(priv->clock); rc_unregister_device(priv->rdev); + rc_free_device(priv->rdev); } #ifdef CONFIG_PM_SLEEP @@ -402,4 +402,3 @@ module_platform_driver(hix5hd2_ir_driver); MODULE_DESCRIPTION("IR controller driver for hix5hd2 platforms"); MODULE_AUTHOR("Guoxiong Yan <yanguoxiong@huawei.com>"); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:hix5hd2-ir"); diff --git a/drivers/media/rc/ir-mce_kbd-decoder.c b/drivers/media/rc/ir-mce_kbd-decoder.c index 66e8feb9a569..bb2d7c37c263 100644 --- a/drivers/media/rc/ir-mce_kbd-decoder.c +++ b/drivers/media/rc/ir-mce_kbd-decoder.c @@ -109,7 +109,8 @@ static unsigned char kbd_keycodes[256] = { static void mce_kbd_rx_timeout(struct timer_list *t) { - struct ir_raw_event_ctrl *raw = from_timer(raw, t, mce_kbd.rx_timeout); + struct ir_raw_event_ctrl *raw = timer_container_of(raw, t, + mce_kbd.rx_timeout); unsigned char maskcode; unsigned long flags; int i; @@ -324,7 +325,7 @@ again: msecs_to_jiffies(100); mod_timer(&data->rx_timeout, jiffies + delay); } else { - del_timer(&data->rx_timeout); + timer_delete(&data->rx_timeout); } /* Pass data to keyboard buffer parser */ ir_mce_kbd_process_keyboard_data(dev, scancode); @@ -372,7 +373,7 @@ static int ir_mce_kbd_unregister(struct rc_dev *dev) { struct mce_kbd_dec *mce_kbd = &dev->raw->mce_kbd; - del_timer_sync(&mce_kbd->rx_timeout); + timer_delete_sync(&mce_kbd->rx_timeout); return 0; } diff --git a/drivers/media/rc/ir-spi.c b/drivers/media/rc/ir-spi.c index 8fc8e496e6aa..392441e0c116 100644 --- a/drivers/media/rc/ir-spi.c +++ b/drivers/media/rc/ir-spi.c @@ -21,13 +21,12 @@ #define IR_SPI_DRIVER_NAME "ir-spi" #define IR_SPI_DEFAULT_FREQUENCY 38000 -#define IR_SPI_MAX_BUFSIZE 4096 +#define IR_SPI_BITS_PER_PULSE 16 struct ir_spi_data { u32 freq; bool negated; - u16 tx_buf[IR_SPI_MAX_BUFSIZE]; u16 pulse; u16 space; @@ -43,17 +42,23 @@ static int ir_spi_tx(struct rc_dev *dev, unsigned int *buffer, unsigned int coun unsigned int len = 0; struct ir_spi_data *idata = dev->priv; struct spi_transfer xfer; + u16 *tx_buf; /* convert the pulse/space signal to raw binary signal */ for (i = 0; i < count; i++) { - unsigned int periods; - int j; - u16 val; + buffer[i] = DIV_ROUND_CLOSEST_ULL((u64)buffer[i] * idata->freq, + 1000000); + len += buffer[i]; + } - periods = DIV_ROUND_CLOSEST(buffer[i] * idata->freq, 1000000); + tx_buf = kmalloc_array(len, sizeof(*tx_buf), GFP_KERNEL); + if (!tx_buf) + return -ENOMEM; - if (len + periods >= IR_SPI_MAX_BUFSIZE) - return -EINVAL; + len = 0; + for (i = 0; i < count; i++) { + int j; + u16 val; /* * The first value in buffer is a pulse, so that 0, 2, 4, ... @@ -61,19 +66,19 @@ static int ir_spi_tx(struct rc_dev *dev, unsigned int *buffer, unsigned int coun * contain a space duration. */ val = (i % 2) ? idata->space : idata->pulse; - for (j = 0; j < periods; j++) - idata->tx_buf[len++] = val; + for (j = 0; j < buffer[i]; j++) + tx_buf[len++] = val; } memset(&xfer, 0, sizeof(xfer)); - xfer.speed_hz = idata->freq * 16; - xfer.len = len * sizeof(*idata->tx_buf); - xfer.tx_buf = idata->tx_buf; + xfer.speed_hz = idata->freq * IR_SPI_BITS_PER_PULSE; + xfer.len = len * sizeof(*tx_buf); + xfer.tx_buf = tx_buf; ret = regulator_enable(idata->regulator); if (ret) - return ret; + goto err_free_tx_buf; ret = spi_sync_transfer(idata->spi, &xfer, 1); if (ret) @@ -81,6 +86,10 @@ static int ir_spi_tx(struct rc_dev *dev, unsigned int *buffer, unsigned int coun regulator_disable(idata->regulator); +err_free_tx_buf: + + kfree(tx_buf); + return ret ? ret : count; } @@ -91,6 +100,9 @@ static int ir_spi_set_tx_carrier(struct rc_dev *dev, u32 carrier) if (!carrier) return -EINVAL; + if (carrier > idata->spi->max_speed_hz / IR_SPI_BITS_PER_PULSE) + return -EINVAL; + idata->freq = carrier; return 0; diff --git a/drivers/media/rc/ir_toy.c b/drivers/media/rc/ir_toy.c index 533faa117517..089833e41178 100644 --- a/drivers/media/rc/ir_toy.c +++ b/drivers/media/rc/ir_toy.c @@ -418,7 +418,7 @@ static int irtoy_probe(struct usb_interface *intf, return -ENODEV; } - irtoy = kzalloc(sizeof(*irtoy), GFP_KERNEL); + irtoy = kzalloc_obj(*irtoy); if (!irtoy) return -ENOMEM; @@ -536,6 +536,7 @@ static void irtoy_disconnect(struct usb_interface *intf) usb_free_urb(ir->urb_out); usb_kill_urb(ir->urb_in); usb_free_urb(ir->urb_in); + rc_free_device(ir->rc); kfree(ir->in); kfree(ir->out); kfree(ir); diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c index 2bacecb02262..bde2a7051231 100644 --- a/drivers/media/rc/ite-cir.c +++ b/drivers/media/rc/ite-cir.c @@ -1304,7 +1304,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id int model_no; int io_rsrc_no; - itdev = kzalloc(sizeof(struct ite_dev), GFP_KERNEL); + itdev = kzalloc_obj(struct ite_dev); if (!itdev) return ret; @@ -1414,7 +1414,6 @@ exit_release_cir_addr: release_region(itdev->cir_addr, itdev->params->io_region_size); exit_unregister_device: rc_unregister_device(rdev); - rdev = NULL; exit_free_dev_rdev: rc_free_device(rdev); kfree(itdev); @@ -1439,6 +1438,7 @@ static void ite_remove(struct pnp_dev *pdev) release_region(dev->cir_addr, dev->params->io_region_size); rc_unregister_device(dev->rdev); + rc_free_device(dev->rdev); kfree(dev); } diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile index 7fdf0d9edbfd..d04572627cdd 100644 --- a/drivers/media/rc/keymaps/Makefile +++ b/drivers/media/rc/keymaps/Makefile @@ -106,6 +106,7 @@ obj-$(CONFIG_RC_MAP) += \ rc-rc6-mce.o \ rc-real-audio-220-32-keys.o \ rc-reddo.o \ + rc-siemens-gigaset-rc20.o \ rc-snapstream-firefly.o \ rc-streamzap.o \ rc-su3000.o \ diff --git a/drivers/media/rc/keymaps/rc-hauppauge.c b/drivers/media/rc/keymaps/rc-hauppauge.c index d7156774aa0e..9e64c0b2d18e 100644 --- a/drivers/media/rc/keymaps/rc-hauppauge.c +++ b/drivers/media/rc/keymaps/rc-hauppauge.c @@ -261,6 +261,48 @@ static struct rc_map_table rc5_hauppauge_new[] = { { 0x001e, KEY_RED }, /* Reserved */ { 0x0000, KEY_NUMERIC_0 }, { 0x0026, KEY_SLEEP }, /* Minimize */ + + /* + * Keycodes for the black Credit Card Remote Control shipped with, for + * example, the WinTV-dualHD tuner. + * Keycodes start with address = 0x19 + */ + { 0x190a, KEY_LAST }, /* <- */ + { 0x192f, KEY_MENU }, /* List */ + { 0x1910, KEY_CHANNELUP }, + { 0x192e, KEY_CHANNELDOWN }, + { 0x192c, KEY_OK }, + + { 0x1911, KEY_TV }, + { 0x190c, KEY_POWER }, + + { 0x1900, KEY_NUMERIC_0 }, + { 0x1938, KEY_NUMERIC_1 }, + { 0x1920, KEY_NUMERIC_2 }, + { 0x1901, KEY_NUMERIC_3 }, + { 0x1902, KEY_NUMERIC_4 }, + { 0x1904, KEY_NUMERIC_5 }, + { 0x1905, KEY_NUMERIC_6 }, + { 0x1907, KEY_NUMERIC_7 }, + { 0x1908, KEY_NUMERIC_8 }, + { 0x190f, KEY_NUMERIC_9 }, + + { 0x1921, KEY_VOLUMEUP }, + { 0x1903, KEY_VOLUMEDOWN }, + { 0x1906, KEY_MUTE }, + + { 0x1909, KEY_CAMERA }, /* Snap */ + { 0x1922, KEY_SUBTITLE }, /* CC */ + { 0x192b, KEY_INFO }, + + { 0x1929, KEY_END }, /* Skip to live TV */ + { 0x190d, KEY_PLAYPAUSE }, + { 0x1926, KEY_STOP }, + { 0x192a, KEY_RECORD }, + { 0x193a, KEY_PREVIOUS }, /* |< */ + { 0x193b, KEY_REWIND }, /* << */ + { 0x193c, KEY_FASTFORWARD }, /* >> */ + { 0x193d, KEY_NEXT }, /* >| */ }; static struct rc_map_list rc5_hauppauge_new_map = { diff --git a/drivers/media/rc/keymaps/rc-siemens-gigaset-rc20.c b/drivers/media/rc/keymaps/rc-siemens-gigaset-rc20.c new file mode 100644 index 000000000000..defc77932e10 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-siemens-gigaset-rc20.c @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* rc-siemens-gigaset-rc20.c - Keytable for the Siemens Gigaset RC 20 remote + * + * Copyright (c) 2025 by Michael Klein + */ + +#include <media/rc-map.h> +#include <linux/module.h> + +static struct rc_map_table siemens_gigaset_rc20[] = { + { 0x1501, KEY_POWER }, + { 0x1502, KEY_MUTE }, + { 0x1503, KEY_NUMERIC_1 }, + { 0x1504, KEY_NUMERIC_2 }, + { 0x1505, KEY_NUMERIC_3 }, + { 0x1506, KEY_NUMERIC_4 }, + { 0x1507, KEY_NUMERIC_5 }, + { 0x1508, KEY_NUMERIC_6 }, + { 0x1509, KEY_NUMERIC_7 }, + { 0x150a, KEY_NUMERIC_8 }, + { 0x150b, KEY_NUMERIC_9 }, + { 0x150c, KEY_NUMERIC_0 }, + { 0x150d, KEY_UP }, + { 0x150e, KEY_LEFT }, + { 0x150f, KEY_OK }, + { 0x1510, KEY_RIGHT }, + { 0x1511, KEY_DOWN }, + { 0x1512, KEY_SHUFFLE }, /* double-arrow */ + { 0x1513, KEY_EXIT }, + { 0x1514, KEY_RED }, + { 0x1515, KEY_GREEN }, + { 0x1516, KEY_YELLOW }, /* OPT */ + { 0x1517, KEY_BLUE }, + { 0x1518, KEY_MENU }, + { 0x1519, KEY_TEXT }, + { 0x151a, KEY_MODE }, /* TV/Radio */ + + { 0x1521, KEY_EPG }, + { 0x1522, KEY_FAVORITES }, + { 0x1523, KEY_CHANNELUP }, + { 0x1524, KEY_CHANNELDOWN }, + { 0x1525, KEY_VOLUMEUP }, + { 0x1526, KEY_VOLUMEDOWN }, + { 0x1527, KEY_INFO }, +}; + +static struct rc_map_list siemens_gigaset_rc20_map = { + .map = { + .scan = siemens_gigaset_rc20, + .size = ARRAY_SIZE(siemens_gigaset_rc20), + .rc_proto = RC_PROTO_RC5, + .name = RC_MAP_SIEMENS_GIGASET_RC20, + } +}; + +static int __init init_rc_map_siemens_gigaset_rc20(void) +{ + return rc_map_register(&siemens_gigaset_rc20_map); +} + +static void __exit exit_rc_map_siemens_gigaset_rc20(void) +{ + rc_map_unregister(&siemens_gigaset_rc20_map); +} + +module_init(init_rc_map_siemens_gigaset_rc20) +module_exit(exit_rc_map_siemens_gigaset_rc20) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Michael Klein"); +MODULE_DESCRIPTION("Siemens Gigaset RC20 remote keytable"); diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index a2257dc2f25d..183f1939b941 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -128,7 +128,7 @@ static int lirc_open(struct inode *inode, struct file *file) { struct rc_dev *dev = container_of(inode->i_cdev, struct rc_dev, lirc_cdev); - struct lirc_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL); + struct lirc_fh *fh = kzalloc_obj(*fh); unsigned long flags; int retval; @@ -267,7 +267,7 @@ static ssize_t lirc_transmit(struct file *file, const char __user *buf, goto out_unlock; } - raw = kmalloc_array(LIRCBUF_SIZE, sizeof(*raw), GFP_KERNEL); + raw = kmalloc_objs(*raw, LIRCBUF_SIZE); if (!raw) { ret = -ENOMEM; goto out_unlock; @@ -736,11 +736,11 @@ int lirc_register(struct rc_dev *dev) cdev_init(&dev->lirc_cdev, &lirc_fops); + get_device(&dev->dev); + err = cdev_device_add(&dev->lirc_cdev, &dev->lirc_dev); if (err) - goto out_ida; - - get_device(&dev->dev); + goto out_put_device; switch (dev->driver_type) { case RC_DRIVER_SCANCODE: @@ -764,7 +764,8 @@ int lirc_register(struct rc_dev *dev) return 0; -out_ida: +out_put_device: + put_device(&dev->lirc_dev); ida_free(&lirc_ida, minor); return err; } diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index 044767eb3a38..6a9e4382a224 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -1715,7 +1715,7 @@ static int mceusb_dev_probe(struct usb_interface *intf, pipe = usb_rcvbulkpipe(dev, ep_in->bEndpointAddress); maxp = usb_maxpacket(dev, pipe); - ir = kzalloc(sizeof(struct mceusb_dev), GFP_KERNEL); + ir = kzalloc_obj(struct mceusb_dev); if (!ir) goto mem_alloc_fail; @@ -1729,7 +1729,7 @@ static int mceusb_dev_probe(struct usb_interface *intf, goto urb_in_alloc_fail; ir->usbintf = intf; - ir->usbdev = usb_get_dev(dev); + ir->usbdev = dev; ir->dev = &intf->dev; ir->len_in = maxp; ir->flags.microsoft_gen1 = is_microsoft_gen1; @@ -1817,7 +1817,6 @@ static int mceusb_dev_probe(struct usb_interface *intf, /* Error-handling path */ rc_dev_fail: cancel_work_sync(&ir->kevent); - usb_put_dev(ir->usbdev); usb_kill_urb(ir->urb_in); usb_free_urb(ir->urb_in); urb_in_alloc_fail: @@ -1849,7 +1848,7 @@ static void mceusb_dev_disconnect(struct usb_interface *intf) usb_kill_urb(ir->urb_in); usb_free_urb(ir->urb_in); usb_free_coherent(dev, ir->len_in, ir->buf_in, ir->dma_in); - usb_put_dev(dev); + rc_free_device(ir->rc); kfree(ir); } diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index 2214d41ef579..4e5a0c8dc9a0 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -639,7 +639,7 @@ static int nvt_ir_raw_set_wakeup_filter(struct rc_dev *dev, if (!sc_filter->mask) return 0; - raw = kmalloc_array(WAKEUP_MAX_SIZE, sizeof(*raw), GFP_KERNEL); + raw = kmalloc_objs(*raw, WAKEUP_MAX_SIZE); if (!raw) return -ENOMEM; diff --git a/drivers/media/rc/pwm-ir-tx.c b/drivers/media/rc/pwm-ir-tx.c index fe368aebbc13..047472dc9244 100644 --- a/drivers/media/rc/pwm-ir-tx.c +++ b/drivers/media/rc/pwm-ir-tx.c @@ -117,7 +117,6 @@ static int pwm_ir_tx_atomic(struct rc_dev *dev, unsigned int *txbuf, static enum hrtimer_restart pwm_ir_timer(struct hrtimer *timer) { struct pwm_ir *pwm_ir = container_of(timer, struct pwm_ir, timer); - ktime_t now; /* * If we happen to hit an odd latency spike, loop through the @@ -139,9 +138,7 @@ static enum hrtimer_restart pwm_ir_timer(struct hrtimer *timer) hrtimer_add_expires_ns(timer, ns); pwm_ir->txbuf_index++; - - now = timer->base->get_time(); - } while (hrtimer_get_expires_tv64(timer) < now); + } while (hrtimer_expires_remaining(timer) > 0); return HRTIMER_RESTART; } @@ -172,8 +169,7 @@ static int pwm_ir_probe(struct platform_device *pdev) rcdev->tx_ir = pwm_ir_tx_sleep; } else { init_completion(&pwm_ir->tx_done); - hrtimer_init(&pwm_ir->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - pwm_ir->timer.function = pwm_ir_timer; + hrtimer_setup(&pwm_ir->timer, pwm_ir_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); rcdev->tx_ir = pwm_ir_tx_atomic; } diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index 7df949fc65e2..4967d87ec4b7 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -85,8 +85,8 @@ struct ir_raw_event_ctrl { struct rc6_dec { int state; u8 header; - u32 body; bool toggle; + u32 body; unsigned count; unsigned wanted_bits; } rc6; @@ -127,8 +127,8 @@ struct ir_raw_event_ctrl { struct mce_kbd_dec { /* locks key up timer */ spinlock_t keylock; - struct timer_list rx_timeout; int state; + struct timer_list rx_timeout; u8 header; u32 body; unsigned count; diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index 16e33d7eaaa2..ba24c2f22d39 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -552,7 +552,8 @@ EXPORT_SYMBOL(ir_raw_encode_scancode); */ static void ir_raw_edge_handle(struct timer_list *t) { - struct ir_raw_event_ctrl *raw = from_timer(raw, t, edge_handle); + struct ir_raw_event_ctrl *raw = timer_container_of(raw, t, + edge_handle); struct rc_dev *dev = raw->dev; unsigned long flags; ktime_t interval; @@ -614,7 +615,7 @@ int ir_raw_event_prepare(struct rc_dev *dev) if (!dev) return -EINVAL; - dev->raw = kzalloc(sizeof(*dev->raw), GFP_KERNEL); + dev->raw = kzalloc_obj(*dev->raw); if (!dev->raw) return -ENOMEM; @@ -647,9 +648,6 @@ int ir_raw_event_register(struct rc_dev *dev) void ir_raw_event_free(struct rc_dev *dev) { - if (!dev) - return; - kfree(dev->raw); dev->raw = NULL; } @@ -662,7 +660,7 @@ void ir_raw_event_unregister(struct rc_dev *dev) return; kthread_stop(dev->raw->thread); - del_timer_sync(&dev->raw->edge_handle); + timer_delete_sync(&dev->raw->edge_handle); mutex_lock(&ir_raw_handler_lock); list_del(&dev->raw->list); @@ -673,8 +671,6 @@ void ir_raw_event_unregister(struct rc_dev *dev) lirc_bpf_free(dev); - ir_raw_event_free(dev); - /* * A user can be calling bpf(BPF_PROG_{QUERY|ATTACH|DETACH}), so * ensure that the raw member is null on unlock; this is how diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c index 8288366f891f..53d0540717b3 100644 --- a/drivers/media/rc/rc-loopback.c +++ b/drivers/media/rc/rc-loopback.c @@ -185,7 +185,7 @@ static int loop_set_wakeup_filter(struct rc_dev *dev, return 0; /* encode the specified filter and loop it back */ - raw = kmalloc_array(max, sizeof(*raw), GFP_KERNEL); + raw = kmalloc_objs(*raw, max); if (!raw) return -ENOMEM; @@ -263,6 +263,7 @@ static int __init loop_init(void) static void __exit loop_exit(void) { rc_unregister_device(loopdev.dev); + rc_free_device(loopdev.dev); } module_init(loop_init); diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index a4c539b17cf3..dda3479ea3ad 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -639,7 +639,7 @@ static void ir_do_keyup(struct rc_dev *dev, bool sync) return; dev_dbg(&dev->dev, "keyup key 0x%04x\n", dev->last_keycode); - del_timer(&dev->timer_repeat); + timer_delete(&dev->timer_repeat); input_report_key(dev->input_dev, dev->last_keycode, 0); led_trigger_event(led_feedback, LED_OFF); if (sync) @@ -674,7 +674,7 @@ EXPORT_SYMBOL_GPL(rc_keyup); */ static void ir_timer_keyup(struct timer_list *t) { - struct rc_dev *dev = from_timer(dev, t, timer_keyup); + struct rc_dev *dev = timer_container_of(dev, t, timer_keyup); unsigned long flags; /* @@ -703,7 +703,7 @@ static void ir_timer_keyup(struct timer_list *t) */ static void ir_timer_repeat(struct timer_list *t) { - struct rc_dev *dev = from_timer(dev, t, timer_repeat); + struct rc_dev *dev = timer_container_of(dev, t, timer_repeat); struct input_dev *input = dev->input_dev; unsigned long flags; @@ -1611,6 +1611,7 @@ static void rc_dev_release(struct device *device) { struct rc_dev *dev = to_rc_dev(device); + ir_raw_event_free(dev); kfree(dev); } @@ -1701,7 +1702,7 @@ struct rc_dev *rc_allocate_device(enum rc_driver_type type) { struct rc_dev *dev; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return NULL; @@ -1773,7 +1774,6 @@ struct rc_dev *devm_rc_allocate_device(struct device *dev, } rc->dev.parent = dev; - rc->managed_alloc = true; *dr = rc; devres_add(dev, dr); @@ -2021,8 +2021,8 @@ void rc_unregister_device(struct rc_dev *dev) if (dev->driver_type == RC_DRIVER_IR_RAW) ir_raw_event_unregister(dev); - del_timer_sync(&dev->timer_keyup); - del_timer_sync(&dev->timer_repeat); + timer_delete_sync(&dev->timer_keyup); + timer_delete_sync(&dev->timer_repeat); mutex_lock(&dev->lock); if (dev->users && dev->close) @@ -2042,11 +2042,7 @@ void rc_unregister_device(struct rc_dev *dev) device_del(&dev->dev); ida_free(&rc_ida, dev->minor); - - if (!dev->managed_alloc) - rc_free_device(dev); } - EXPORT_SYMBOL_GPL(rc_unregister_device); /* diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index d89a4cfe3c89..3f828a564e19 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -422,7 +422,7 @@ static int redrat3_send_cmd(int cmd, struct redrat3_dev *rr3) static int redrat3_enable_detector(struct redrat3_dev *rr3) { struct device *dev = rr3->dev; - u8 ret; + int ret; ret = redrat3_send_cmd(RR3_RC_DET_ENABLE, rr3); if (ret != 0) @@ -502,7 +502,7 @@ static int redrat3_set_timeout(struct rc_dev *rc_dev, unsigned int timeoutus) __be32 *timeout; int ret; - timeout = kmalloc(sizeof(*timeout), GFP_KERNEL); + timeout = kmalloc_obj(*timeout); if (!timeout) return -ENOMEM; @@ -768,13 +768,11 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf, /* rr3 will disable rc detector on transmit */ rr3->transmitting = true; - sample_lens = kcalloc(RR3_DRIVER_MAXLENS, - sizeof(*sample_lens), - GFP_KERNEL); + sample_lens = kzalloc_objs(*sample_lens, RR3_DRIVER_MAXLENS); if (!sample_lens) return -ENOMEM; - irdata = kzalloc(sizeof(*irdata), GFP_KERNEL); + irdata = kzalloc_obj(*irdata); if (!irdata) { ret = -ENOMEM; goto out; @@ -1022,7 +1020,7 @@ static int redrat3_dev_probe(struct usb_interface *intf, } /* allocate memory for our device state and initialize it */ - rr3 = kzalloc(sizeof(*rr3), GFP_KERNEL); + rr3 = kzalloc_obj(*rr3); if (!rr3) goto no_endpoints; @@ -1133,11 +1131,13 @@ static void redrat3_dev_disconnect(struct usb_interface *intf) { struct usb_device *udev = interface_to_usbdev(intf); struct redrat3_dev *rr3 = usb_get_intfdata(intf); + struct rc_dev *rc = rr3->rc; usb_set_intfdata(intf, NULL); - rc_unregister_device(rr3->rc); + rc_unregister_device(rc); led_classdev_unregister(&rr3->led); redrat3_delete(rr3, udev); + rc_free_device(rc); } static int redrat3_dev_suspend(struct usb_interface *intf, pm_message_t message) diff --git a/drivers/media/rc/serial_ir.c b/drivers/media/rc/serial_ir.c index fc5fd3927177..992fff82b524 100644 --- a/drivers/media/rc/serial_ir.c +++ b/drivers/media/rc/serial_ir.c @@ -798,7 +798,7 @@ static int __init serial_ir_init_module(void) static void __exit serial_ir_exit_module(void) { - del_timer_sync(&serial_ir.timeout_timer); + timer_delete_sync(&serial_ir.timeout_timer); serial_ir_exit(); } diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c index 6539fa0a6e79..0ba06bfc9e14 100644 --- a/drivers/media/rc/st_rc.c +++ b/drivers/media/rc/st_rc.c @@ -203,6 +203,7 @@ static void st_rc_remove(struct platform_device *pdev) device_init_wakeup(&pdev->dev, false); clk_disable_unprepare(rc_dev->sys_clock); rc_unregister_device(rc_dev->rdev); + rc_free_device(rc_dev->rdev); } static int st_rc_open(struct rc_dev *rdev) @@ -284,7 +285,7 @@ static int st_rc_probe(struct platform_device *pdev) else rc_dev->rx_base = rc_dev->base; - rc_dev->rstc = reset_control_get_optional_exclusive(dev, NULL); + rc_dev->rstc = devm_reset_control_get_optional_exclusive(dev, NULL); if (IS_ERR(rc_dev->rstc)) { ret = PTR_ERR(rc_dev->rstc); goto err; @@ -334,7 +335,6 @@ static int st_rc_probe(struct platform_device *pdev) return ret; rcerr: rc_unregister_device(rdev); - rdev = NULL; clkerr: clk_disable_unprepare(rc_dev->sys_clock); err: diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c index 9b209e687f25..307985d74fe8 100644 --- a/drivers/media/rc/streamzap.c +++ b/drivers/media/rc/streamzap.c @@ -138,39 +138,10 @@ static void sz_push_half_space(struct streamzap_ir *sz, sz_push_full_space(sz, value & SZ_SPACE_MASK); } -/* - * streamzap_callback - usb IRQ handler callback - * - * This procedure is invoked on reception of data from - * the usb remote. - */ -static void streamzap_callback(struct urb *urb) +static void sz_process_ir_data(struct streamzap_ir *sz, int len) { - struct streamzap_ir *sz; unsigned int i; - int len; - if (!urb) - return; - - sz = urb->context; - len = urb->actual_length; - - switch (urb->status) { - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* - * this urb is terminated, clean up. - * sz might already be invalid at this point - */ - dev_err(sz->dev, "urb terminated, status: %d\n", urb->status); - return; - default: - break; - } - - dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len); for (i = 0; i < len; i++) { dev_dbg(sz->dev, "sz->buf_in[%d]: %x\n", i, (unsigned char)sz->buf_in[i]); @@ -219,6 +190,42 @@ static void streamzap_callback(struct urb *urb) } ir_raw_event_handle(sz->rdev); +} + +/* + * streamzap_callback - usb IRQ handler callback + * + * This procedure is invoked on reception of data from + * the usb remote. + */ +static void streamzap_callback(struct urb *urb) +{ + struct streamzap_ir *sz; + int len; + + if (!urb) + return; + + sz = urb->context; + len = urb->actual_length; + + switch (urb->status) { + case 0: + dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len); + sz_process_ir_data(sz, len); + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* + * this urb is terminated, clean up. + */ + dev_dbg(sz->dev, "urb terminated, status: %d\n", urb->status); + return; + default: + break; + } + usb_submit_urb(urb, GFP_ATOMIC); } @@ -277,7 +284,7 @@ static int streamzap_probe(struct usb_interface *intf, int pipe, maxp; /* Allocate space for device driver specific data */ - sz = kzalloc(sizeof(struct streamzap_ir), GFP_KERNEL); + sz = kzalloc_obj(struct streamzap_ir); if (!sz) return -ENOMEM; @@ -350,11 +357,16 @@ static int streamzap_probe(struct usb_interface *intf, usb_set_intfdata(intf, sz); - if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) + retval = usb_submit_urb(sz->urb_in, GFP_ATOMIC); + if (retval < 0) { dev_err(sz->dev, "urb submit failed\n"); + goto rc_submit_fail; + } return 0; - +rc_submit_fail: + rc_free_device(sz->rdev); + usb_set_intfdata(intf, NULL); rc_dev_fail: usb_free_urb(sz->urb_in); free_buf_in: @@ -380,15 +392,16 @@ static void streamzap_disconnect(struct usb_interface *interface) struct streamzap_ir *sz = usb_get_intfdata(interface); struct usb_device *usbdev = interface_to_usbdev(interface); - usb_set_intfdata(interface, NULL); - if (!sz) return; rc_unregister_device(sz->rdev); + usb_set_intfdata(interface, NULL); + usb_kill_urb(sz->urb_in); usb_free_urb(sz->urb_in); usb_free_coherent(usbdev, sz->buf_in_len, sz->buf_in, sz->dma_in); + rc_free_device(sz->rdev); kfree(sz); } diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c index 92ef4e7c6f69..cb4c56bf0752 100644 --- a/drivers/media/rc/sunxi-cir.c +++ b/drivers/media/rc/sunxi-cir.c @@ -371,6 +371,7 @@ static void sunxi_ir_remove(struct platform_device *pdev) struct sunxi_ir *ir = platform_get_drvdata(pdev); rc_unregister_device(ir->rc); + rc_free_device(ir->rc); sunxi_ir_hw_exit(&pdev->dev); } diff --git a/drivers/media/rc/ttusbir.c b/drivers/media/rc/ttusbir.c index 560a26f3965c..db2f6698a6c0 100644 --- a/drivers/media/rc/ttusbir.c +++ b/drivers/media/rc/ttusbir.c @@ -32,7 +32,7 @@ struct ttusbir { struct led_classdev led; struct urb *bulk_urb; - uint8_t bulk_buffer[5]; + u8 *bulk_buffer; int bulk_out_endp, iso_in_endp; bool led_on, is_led_on; atomic_t led_complete; @@ -186,13 +186,16 @@ static int ttusbir_probe(struct usb_interface *intf, struct rc_dev *rc; int i, j, ret; int altsetting = -1; + u8 *buffer; - tt = kzalloc(sizeof(*tt), GFP_KERNEL); + tt = kzalloc_obj(*tt); + buffer = kzalloc(5, GFP_KERNEL); rc = rc_allocate_device(RC_DRIVER_IR_RAW); - if (!tt || !rc) { + if (!tt || !rc || !buffer) { ret = -ENOMEM; goto out; } + tt->bulk_buffer = buffer; /* find the correct alt setting */ for (i = 0; i < intf->num_altsetting && altsetting == -1; i++) { @@ -281,8 +284,8 @@ static int ttusbir_probe(struct usb_interface *intf, tt->bulk_buffer[3] = 0x01; usb_fill_bulk_urb(tt->bulk_urb, tt->udev, usb_sndbulkpipe(tt->udev, - tt->bulk_out_endp), tt->bulk_buffer, sizeof(tt->bulk_buffer), - ttusbir_bulk_complete, tt); + tt->bulk_out_endp), tt->bulk_buffer, 5, + ttusbir_bulk_complete, tt); tt->led.name = "ttusbir:green:power"; tt->led.default_trigger = "rc-feedback"; @@ -333,7 +336,6 @@ static int ttusbir_probe(struct usb_interface *intf, return 0; out3: rc_unregister_device(rc); - rc = NULL; out2: led_classdev_unregister(&tt->led); out: @@ -351,6 +353,7 @@ out: kfree(tt); } rc_free_device(rc); + kfree(buffer); return ret; } @@ -373,6 +376,8 @@ static void ttusbir_disconnect(struct usb_interface *intf) } usb_kill_urb(tt->bulk_urb); usb_free_urb(tt->bulk_urb); + rc_free_device(tt->rc); + kfree(tt->bulk_buffer); usb_set_intfdata(intf, NULL); kfree(tt); } diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index 25884a79985c..8e804661a621 100644 --- a/drivers/media/rc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c @@ -1017,7 +1017,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) return -ENODEV; } - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) { err = -ENOMEM; goto exit; @@ -1132,7 +1132,6 @@ exit_release_wbase: release_region(data->wbase, WAKEUP_IOMEM_LEN); exit_unregister_device: rc_unregister_device(data->dev); - data->dev = NULL; exit_free_rc: rc_free_device(data->dev); exit_unregister_led: @@ -1163,6 +1162,7 @@ wbcir_remove(struct pnp_dev *device) wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07); rc_unregister_device(data->dev); + rc_free_device(data->dev); led_classdev_unregister(&data->led); diff --git a/drivers/media/rc/xbox_remote.c b/drivers/media/rc/xbox_remote.c index a1572381d097..d2cb88b8f1ca 100644 --- a/drivers/media/rc/xbox_remote.c +++ b/drivers/media/rc/xbox_remote.c @@ -55,7 +55,7 @@ struct xbox_remote { struct usb_interface *interface; struct urb *irq_urb; - unsigned char inbuf[DATA_BUFSIZE] __aligned(sizeof(u16)); + u8 *inbuf; char rc_name[NAME_BUFSIZE]; char rc_phys[NAME_BUFSIZE]; @@ -213,11 +213,15 @@ static int xbox_remote_probe(struct usb_interface *interface, return -ENODEV; } - xbox_remote = kzalloc(sizeof(*xbox_remote), GFP_KERNEL); + xbox_remote = kzalloc_obj(*xbox_remote); rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE); if (!xbox_remote || !rc_dev) goto exit_free_dev_rdev; + xbox_remote->inbuf = kzalloc(DATA_BUFSIZE, GFP_KERNEL); + if (!xbox_remote->inbuf) + goto exit_free_inbuf; + /* Allocate URB buffer */ xbox_remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL); if (!xbox_remote->irq_urb) @@ -262,6 +266,8 @@ exit_kill_urbs: usb_kill_urb(xbox_remote->irq_urb); exit_free_buffers: usb_free_urb(xbox_remote->irq_urb); +exit_free_inbuf: + kfree(xbox_remote->inbuf); exit_free_dev_rdev: rc_free_device(rc_dev); kfree(xbox_remote); @@ -277,15 +283,17 @@ static void xbox_remote_disconnect(struct usb_interface *interface) struct xbox_remote *xbox_remote; xbox_remote = usb_get_intfdata(interface); - usb_set_intfdata(interface, NULL); if (!xbox_remote) { dev_warn(&interface->dev, "%s - null device?\n", __func__); return; } - usb_kill_urb(xbox_remote->irq_urb); rc_unregister_device(xbox_remote->rdev); + usb_set_intfdata(interface, NULL); + usb_kill_urb(xbox_remote->irq_urb); + rc_free_device(xbox_remote->rdev); usb_free_urb(xbox_remote->irq_urb); + kfree(xbox_remote->inbuf); kfree(xbox_remote); } |
