This is an automatic generated email to let you know that the following patch 
were queued at the 
http://git.linuxtv.org/media_tree.git tree:

Subject: [media] rc-main: Fix device de-registration logic
Author:  Mauro Carvalho Chehab <[email protected]>
Date:    Fri Jul 29 02:23:20 2011 -0300

rc unregister logic were deadly broken, preventing some drivers to
be removed. Among the broken things, rc_dev_uevent() is being called
during device_del(), causing a data filling on an area that it is
not ready anymore.

Also, some drivers have a stop callback defined, that needs to be called
before data removal, as it stops data polling.

Signed-off-by: Mauro Carvalho Chehab <[email protected]>

 drivers/media/rc/rc-main.c |   29 +++++++++++++++++++----------
 1 files changed, 19 insertions(+), 10 deletions(-)

---

http://git.linuxtv.org/media_tree.git?a=commitdiff;h=d2fea3477b6527f29b946f6aa5842398d72c3a1e

diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 51a23f4..666d4bb 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -928,10 +928,6 @@ out:
 
 static void rc_dev_release(struct device *device)
 {
-       struct rc_dev *dev = to_rc_dev(device);
-
-       kfree(dev);
-       module_put(THIS_MODULE);
 }
 
 #define ADD_HOTPLUG_VAR(fmt, val...)                                   \
@@ -945,6 +941,9 @@ static int rc_dev_uevent(struct device *device, struct 
kobj_uevent_env *env)
 {
        struct rc_dev *dev = to_rc_dev(device);
 
+       if (!dev || !dev->input_dev)
+               return -ENODEV;
+
        if (dev->rc_map.name)
                ADD_HOTPLUG_VAR("NAME=%s", dev->rc_map.name);
        if (dev->driver_name)
@@ -1013,10 +1012,16 @@ EXPORT_SYMBOL_GPL(rc_allocate_device);
 
 void rc_free_device(struct rc_dev *dev)
 {
-       if (dev) {
+       if (!dev)
+               return;
+
+       if (dev->input_dev)
                input_free_device(dev->input_dev);
-               put_device(&dev->dev);
-       }
+
+       put_device(&dev->dev);
+
+       kfree(dev);
+       module_put(THIS_MODULE);
 }
 EXPORT_SYMBOL_GPL(rc_free_device);
 
@@ -1143,14 +1148,18 @@ void rc_unregister_device(struct rc_dev *dev)
        if (dev->driver_type == RC_DRIVER_IR_RAW)
                ir_raw_event_unregister(dev);
 
+       /* Freeing the table should also call the stop callback */
+       ir_free_table(&dev->rc_map);
+       IR_dprintk(1, "Freed keycode table\n");
+
        input_unregister_device(dev->input_dev);
        dev->input_dev = NULL;
 
-       ir_free_table(&dev->rc_map);
-       IR_dprintk(1, "Freed keycode table\n");
+       device_del(&dev->dev);
 
-       device_unregister(&dev->dev);
+       rc_free_device(dev);
 }
+
 EXPORT_SYMBOL_GPL(rc_unregister_device);
 
 /*

_______________________________________________
linuxtv-commits mailing list
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to