Browse Source

[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 <mchehab@redhat.com>
Mauro Carvalho Chehab 13 years ago
parent
commit
90bf3aab42
2 changed files with 18 additions and 5 deletions
  1. 5 1
      drivers/media/video/cx231xx/cx231xx-input.c
  2. 13 4
      drivers/media/video/ir-kbd-i2c.c

+ 5 - 1
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

+ 13 - 4
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);