--- /dev/null
+From affc9a0d59ac49bd304e2137bd5e4ffdd6fdfa52 Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Wed, 16 Nov 2011 01:54:04 -0300
+Subject: media: staging: lirc_serial: Do not assume error codes returned by request_irq()
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+commit affc9a0d59ac49bd304e2137bd5e4ffdd6fdfa52 upstream.
+
+lirc_serial_probe() must fail if request_irq() returns an error, even if
+it isn't EBUSY or EINVAL,
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/media/lirc/lirc_serial.c | 21 +++++++++------------
+ 1 file changed, 9 insertions(+), 12 deletions(-)
+
+--- a/drivers/staging/media/lirc/lirc_serial.c
++++ b/drivers/staging/media/lirc/lirc_serial.c
+@@ -843,18 +843,15 @@ static int __devinit lirc_serial_probe(s
+ result = request_irq(irq, irq_handler,
+ (share_irq ? IRQF_SHARED : 0),
+ LIRC_DRIVER_NAME, (void *)&hardware);
+-
+- switch (result) {
+- case -EBUSY:
+- printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", irq);
+- return -EBUSY;
+- case -EINVAL:
+- printk(KERN_ERR LIRC_DRIVER_NAME
+- ": Bad irq number or handler\n");
+- return -EINVAL;
+- default:
+- break;
+- };
++ if (result < 0) {
++ if (result == -EBUSY)
++ printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n",
++ irq);
++ else if (result == -EINVAL)
++ printk(KERN_ERR LIRC_DRIVER_NAME
++ ": Bad irq number or handler\n");
++ return result;
++ }
+
+ /* Reserve io region. */
+ /*
--- /dev/null
+From 1ff1d88e862948ae5bfe490248c023ff8ac2855d Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Wed, 16 Nov 2011 01:53:25 -0300
+Subject: media: staging: lirc_serial: Fix deadlock on resume failure
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+commit 1ff1d88e862948ae5bfe490248c023ff8ac2855d upstream.
+
+A resume function cannot remove the device it is resuming!
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ drivers/staging/media/lirc/lirc_serial.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/drivers/staging/media/lirc/lirc_serial.c
++++ b/drivers/staging/media/lirc/lirc_serial.c
+@@ -1127,10 +1127,8 @@ static int lirc_serial_resume(struct pla
+ {
+ unsigned long flags;
+
+- if (hardware_init_port() < 0) {
+- lirc_serial_exit();
++ if (hardware_init_port() < 0)
+ return -EINVAL;
+- }
+
+ spin_lock_irqsave(&hardware[type].lock, flags);
+ /* Enable Interrupt */
--- /dev/null
+From 9105b8b200410383d0854bbe237ee385d7d33ba6 Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Wed, 16 Nov 2011 01:49:41 -0300
+Subject: media: staging: lirc_serial: Fix init/exit order
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+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 <ben@decadent.org.uk>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/media/lirc/lirc_serial.c | 56 +++++++++++--------------------
+ 1 file changed, 21 insertions(+), 35 deletions(-)
+
+--- a/drivers/staging/media/lirc/lirc_serial.c
++++ b/drivers/staging/media/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");
+ }
+
--- /dev/null
+From c8e57e1b766c2321aa76ee5e6878c69bd2313d62 Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Wed, 16 Nov 2011 01:52:11 -0300
+Subject: media: staging: lirc_serial: Free resources on failure paths of lirc_serial_probe()
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+commit c8e57e1b766c2321aa76ee5e6878c69bd2313d62 upstream.
+
+Failure to allocate the I/O region leaves the IRQ allocated.
+A later failure leaves them both allocated.
+
+Reported-by: Torsten Crass <torsten.crass@eBiology.de>
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/media/lirc/lirc_serial.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+--- a/drivers/staging/media/lirc/lirc_serial.c
++++ b/drivers/staging/media/lirc/lirc_serial.c
+@@ -875,11 +875,14 @@ static int __devinit lirc_serial_probe(s
+ ": or compile the serial port driver as module and\n");
+ printk(KERN_WARNING LIRC_DRIVER_NAME
+ ": make sure this module is loaded first\n");
+- return -EBUSY;
++ result = -EBUSY;
++ goto exit_free_irq;
+ }
+
+- if (hardware_init_port() < 0)
+- return -EINVAL;
++ if (hardware_init_port() < 0) {
++ result = -EINVAL;
++ goto exit_release_region;
++ }
+
+ /* Initialize pulse/space widths */
+ init_timing_params(duty_cycle, freq);
+@@ -911,6 +914,16 @@ static int __devinit lirc_serial_probe(s
+
+ dprintk("Interrupt %d, port %04x obtained\n", irq, io);
+ return 0;
++
++exit_release_region:
++ if (iommap != 0)
++ release_mem_region(iommap, 8 << ioshift);
++ else
++ release_region(io, 8);
++exit_free_irq:
++ free_irq(irq, (void *)&hardware);
++
++ return result;
+ }
+
+ static int __devexit lirc_serial_remove(struct platform_device *dev)
arm-7355-1-perf-clear-overflow-flag-when-disabling-counter-on-armv7-pmu.patch
arm-7356-1-perf-check-that-we-have-an-event-in-the-pmu-irq-handlers.patch
arm-7357-1-perf-fix-overflow-handling-for-xscale2-pmus.patch
+media-staging-lirc_serial-fix-init-exit-order.patch
+media-staging-lirc_serial-free-resources-on-failure-paths-of-lirc_serial_probe.patch
+media-staging-lirc_serial-fix-deadlock-on-resume-failure.patch
+media-staging-lirc_serial-do-not-assume-error-codes-returned-by-request_irq.patch