From 90bf3aab42937f760e5b645ab63df46d26b5e620 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 9 Jan 2012 22:28:13 -0200 Subject: [PATCH] [media] cx231xx-input: stop polling if the device got removed. If the device got removed, stops polling it. Also, un-registers it at input/evdev, as it won't work anymore. We can't free the IR structure yet, as the ir_remove method will be called later. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx231xx/cx231xx-input.c | 6 +++++- drivers/media/video/ir-kbd-i2c.c | 17 +++++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c index 45e14ca..8a75a90 100644 --- a/drivers/media/video/cx231xx/cx231xx-input.c +++ b/drivers/media/video/cx231xx/cx231xx-input.c @@ -27,12 +27,16 @@ static int get_key_isdbt(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) { + int rc; u8 cmd, scancode; dev_dbg(&ir->rc->input_dev->dev, "%s\n", __func__); /* poll IR chip */ - if (1 != i2c_master_recv(ir->c, &cmd, 1)) + rc = i2c_master_recv(ir->c, &cmd, 1); + if (rc < 0) + return rc; + if (rc != 1) return -EIO; /* it seems that 0xFE indicates that a button is still hold diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 3ab875d..37d0c20 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c @@ -244,7 +244,7 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir, /* ----------------------------------------------------------------------- */ -static void ir_key_poll(struct IR_i2c *ir) +static int ir_key_poll(struct IR_i2c *ir) { static u32 ir_key, ir_raw; int rc; @@ -253,20 +253,28 @@ static void ir_key_poll(struct IR_i2c *ir) rc = ir->get_key(ir, &ir_key, &ir_raw); if (rc < 0) { dprintk(2,"error\n"); - return; + return rc; } if (rc) { dprintk(1, "%s: keycode = 0x%04x\n", __func__, ir_key); rc_keydown(ir->rc, ir_key, 0); } + return 0; } static void ir_work(struct work_struct *work) { + int rc; struct IR_i2c *ir = container_of(work, struct IR_i2c, work.work); - ir_key_poll(ir); + rc = ir_key_poll(ir); + if (rc == -ENODEV) { + rc_unregister_device(ir->rc); + ir->rc = NULL; + return; + } + schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling_interval)); } @@ -446,7 +454,8 @@ static int ir_remove(struct i2c_client *client) cancel_delayed_work_sync(&ir->work); /* unregister device */ - rc_unregister_device(ir->rc); + if (ir->rc) + rc_unregister_device(ir->rc); /* free memory */ kfree(ir); -- 2.7.4