aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorBen Hutchings <ben@decadent.org.uk>2011-11-15 23:49:41 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-11-24 15:16:40 -0500
commit9105b8b200410383d0854bbe237ee385d7d33ba6 (patch)
treef03d48ed0f0f84204e319bdd13c3707238485601 /drivers/staging
parent37e22142891773fb883bbef435f2ebbb5670c0b0 (diff)
[media] staging: lirc_serial: Fix init/exit order
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>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/media/lirc/lirc_serial.c56
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 8a060a8a7224..86376311506b 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)
836 return 0; 836 return 0;
837} 837}
838 838
839static int init_port(void) 839static int __devinit lirc_serial_probe(struct platform_device *dev)
840{ 840{
841 int i, nlow, nhigh, result; 841 int i, nlow, nhigh, result;
842 842
@@ -913,6 +913,18 @@ static int init_port(void)
913 return 0; 913 return 0;
914} 914}
915 915
916static int __devexit lirc_serial_remove(struct platform_device *dev)
917{
918 free_irq(irq, (void *)&hardware);
919
920 if (iommap != 0)
921 release_mem_region(iommap, 8 << ioshift);
922 else
923 release_region(io, 8);
924
925 return 0;
926}
927
916static int set_use_inc(void *data) 928static int set_use_inc(void *data)
917{ 929{
918 unsigned long flags; 930 unsigned long flags;
@@ -1076,16 +1088,6 @@ static struct lirc_driver driver = {
1076 1088
1077static struct platform_device *lirc_serial_dev; 1089static struct platform_device *lirc_serial_dev;
1078 1090
1079static int __devinit lirc_serial_probe(struct platform_device *dev)
1080{
1081 return 0;
1082}
1083
1084static int __devexit lirc_serial_remove(struct platform_device *dev)
1085{
1086 return 0;
1087}
1088
1089static int lirc_serial_suspend(struct platform_device *dev, 1091static int lirc_serial_suspend(struct platform_device *dev,
1090 pm_message_t state) 1092 pm_message_t state)
1091{ 1093{
@@ -1188,10 +1190,6 @@ static int __init lirc_serial_init_module(void)
1188{ 1190{
1189 int result; 1191 int result;
1190 1192
1191 result = lirc_serial_init();
1192 if (result)
1193 return result;
1194
1195 switch (type) { 1193 switch (type) {
1196 case LIRC_HOMEBREW: 1194 case LIRC_HOMEBREW:
1197 case LIRC_IRDEO: 1195 case LIRC_IRDEO:
@@ -1211,8 +1209,7 @@ static int __init lirc_serial_init_module(void)
1211 break; 1209 break;
1212#endif 1210#endif
1213 default: 1211 default:
1214 result = -EINVAL; 1212 return -EINVAL;
1215 goto exit_serial_exit;
1216 } 1213 }
1217 if (!softcarrier) { 1214 if (!softcarrier) {
1218 switch (type) { 1215 switch (type) {
@@ -1228,37 +1225,26 @@ static int __init lirc_serial_init_module(void)
1228 } 1225 }
1229 } 1226 }
1230 1227
1231 result = init_port(); 1228 result = lirc_serial_init();
1232 if (result < 0) 1229 if (result)
1233 goto exit_serial_exit; 1230 return result;
1231
1234 driver.features = hardware[type].features; 1232 driver.features = hardware[type].features;
1235 driver.dev = &lirc_serial_dev->dev; 1233 driver.dev = &lirc_serial_dev->dev;
1236 driver.minor = lirc_register_driver(&driver); 1234 driver.minor = lirc_register_driver(&driver);
1237 if (driver.minor < 0) { 1235 if (driver.minor < 0) {
1238 printk(KERN_ERR LIRC_DRIVER_NAME 1236 printk(KERN_ERR LIRC_DRIVER_NAME
1239 ": register_chrdev failed!\n"); 1237 ": register_chrdev failed!\n");
1240 result = -EIO; 1238 lirc_serial_exit();
1241 goto exit_release; 1239 return -EIO;
1242 } 1240 }
1243 return 0; 1241 return 0;
1244exit_release:
1245 release_region(io, 8);
1246exit_serial_exit:
1247 lirc_serial_exit();
1248 return result;
1249} 1242}
1250 1243
1251static void __exit lirc_serial_exit_module(void) 1244static void __exit lirc_serial_exit_module(void)
1252{ 1245{
1253 lirc_serial_exit();
1254
1255 free_irq(irq, (void *)&hardware);
1256
1257 if (iommap != 0)
1258 release_mem_region(iommap, 8 << ioshift);
1259 else
1260 release_region(io, 8);
1261 lirc_unregister_driver(driver.minor); 1246 lirc_unregister_driver(driver.minor);
1247 lirc_serial_exit();
1262 dprintk("cleaned up module\n"); 1248 dprintk("cleaned up module\n");
1263} 1249}
1264 1250