141 lines
3.4 KiB
Diff
141 lines
3.4 KiB
Diff
From: Ben Hutchings <ben@decadent.org.uk>
|
|
Date: Wed, 16 Nov 2011 01:49:41 -0300
|
|
Subject: [PATCH 1/5] [media] staging: lirc_serial: Fix init/exit order
|
|
|
|
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>
|
|
---
|
|
drivers/staging/media/lirc/lirc_serial.c | 56 +++++++++++------------------
|
|
1 files changed, 21 insertions(+), 35 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c
|
|
index 8a060a8..8637631 100644
|
|
--- 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_module(void)
|
|
{
|
|
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_module(void)
|
|
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_module(void)
|
|
}
|
|
}
|
|
|
|
- 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");
|
|
}
|
|
|
|
--
|
|
1.7.7.3
|
|
|