This is a note to let you know that I've just added the patch titled

    media: staging: lirc_serial: Fix init/exit order

to the 3.0-stable tree which can be found at:
    
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     media-staging-lirc_serial-fix-init-exit-order.patch
and it can be found in the queue-3.0 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <[email protected]> know about it.


>From 9105b8b200410383d0854bbe237ee385d7d33ba6 Mon Sep 17 00:00:00 2001
From: Ben Hutchings <[email protected]>
Date: Wed, 16 Nov 2011 01:49:41 -0300
Subject: media: staging: lirc_serial: Fix init/exit order

From: Ben Hutchings <[email protected]>

commit 9105b8b200410383d0854bbe237ee385d7d33ba6 upstream.

Currently the module init function registers a platform_device and
only then allocates its IRQ and I/O region.  This allows allocation to
race with the device's suspend() function.  Instead, allocate
resources in the platform driver's probe() function and free them in
the remove() function.

The module exit function removes the platform device before the
character device that provides access to it.  Change it to reverse the
order of initialisation.

Signed-off-by: Ben Hutchings <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Jonathan Nieder <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
 drivers/staging/lirc/lirc_serial.c |   56 +++++++++++++------------------------
 1 file changed, 21 insertions(+), 35 deletions(-)

--- a/drivers/staging/lirc/lirc_serial.c
+++ b/drivers/staging/lirc/lirc_serial.c
@@ -836,7 +836,7 @@ static int hardware_init_port(void)
        return 0;
 }
 
-static int init_port(void)
+static int __devinit lirc_serial_probe(struct platform_device *dev)
 {
        int i, nlow, nhigh, result;
 
@@ -913,6 +913,18 @@ static int init_port(void)
        return 0;
 }
 
+static int __devexit lirc_serial_remove(struct platform_device *dev)
+{
+       free_irq(irq, (void *)&hardware);
+
+       if (iommap != 0)
+               release_mem_region(iommap, 8 << ioshift);
+       else
+               release_region(io, 8);
+
+       return 0;
+}
+
 static int set_use_inc(void *data)
 {
        unsigned long flags;
@@ -1076,16 +1088,6 @@ static struct lirc_driver driver = {
 
 static struct platform_device *lirc_serial_dev;
 
-static int __devinit lirc_serial_probe(struct platform_device *dev)
-{
-       return 0;
-}
-
-static int __devexit lirc_serial_remove(struct platform_device *dev)
-{
-       return 0;
-}
-
 static int lirc_serial_suspend(struct platform_device *dev,
                               pm_message_t state)
 {
@@ -1188,10 +1190,6 @@ static int __init lirc_serial_init_modul
 {
        int result;
 
-       result = lirc_serial_init();
-       if (result)
-               return result;
-
        switch (type) {
        case LIRC_HOMEBREW:
        case LIRC_IRDEO:
@@ -1211,8 +1209,7 @@ static int __init lirc_serial_init_modul
                break;
 #endif
        default:
-               result = -EINVAL;
-               goto exit_serial_exit;
+               return -EINVAL;
        }
        if (!softcarrier) {
                switch (type) {
@@ -1228,37 +1225,26 @@ static int __init lirc_serial_init_modul
                }
        }
 
-       result = init_port();
-       if (result < 0)
-               goto exit_serial_exit;
+       result = lirc_serial_init();
+       if (result)
+               return result;
+
        driver.features = hardware[type].features;
        driver.dev = &lirc_serial_dev->dev;
        driver.minor = lirc_register_driver(&driver);
        if (driver.minor < 0) {
                printk(KERN_ERR  LIRC_DRIVER_NAME
                       ": register_chrdev failed!\n");
-               result = -EIO;
-               goto exit_release;
+               lirc_serial_exit();
+               return -EIO;
        }
        return 0;
-exit_release:
-       release_region(io, 8);
-exit_serial_exit:
-       lirc_serial_exit();
-       return result;
 }
 
 static void __exit lirc_serial_exit_module(void)
 {
-       lirc_serial_exit();
-
-       free_irq(irq, (void *)&hardware);
-
-       if (iommap != 0)
-               release_mem_region(iommap, 8 << ioshift);
-       else
-               release_region(io, 8);
        lirc_unregister_driver(driver.minor);
+       lirc_serial_exit();
        dprintk("cleaned up module\n");
 }
 


Patches currently in stable-queue which might be from [email protected] are

queue-3.0/media-staging-lirc_serial-do-not-assume-error-codes-returned-by-request_irq.patch
queue-3.0/media-staging-lirc_serial-fix-deadlock-on-resume-failure.patch
queue-3.0/media-staging-lirc_serial-free-resources-on-failure-paths-of-lirc_serial_probe.patch
queue-3.0/media-staging-lirc_serial-fix-init-exit-order.patch
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to