Patch: Init/shutdown correctness fixes for drivers/cbus/retu*

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I noticed there were a number of problems with the init and shutdown routines for the code in drivers/cbus/retu*. This patch (for review) attempts to fix them.


commit 59e589227131abbe5e07576f542cc35a8821c9d3
Author: Andrew de Quincey <adq@xxxxxxxxxxxxx>
Date:   Mon May 25 23:58:27 2009 +0100

    Correctness fixes for the retu drivers

diff --git a/drivers/cbus/retu-headset.c b/drivers/cbus/retu-headset.c
index e798bc2..fe8266f 100644
--- a/drivers/cbus/retu-headset.c
+++ b/drivers/cbus/retu-headset.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2006 Nokia Corporation
  *
- * Written by Juha Yrj�+ * Written by Juha Yrj�l�
  *
  * This file is subject to the terms and conditions of the GNU General
  * Public License. See the file "COPYING" in the main directory of this
@@ -265,6 +265,8 @@ static int __init retu_headset_probe(struct platform_device *pdev)
 	retu_disable_irq(RETU_INT_HOOK);
 	return 0;
 err6:
+	del_timer_sync(&hs->enable_timer);
+	del_timer_sync(&hs->detect_timer);
 	device_remove_file(&pdev->dev, &dev_attr_enable_det);
 err5:
 	device_remove_file(&pdev->dev, &dev_attr_enable);
@@ -291,6 +293,7 @@ static int retu_headset_remove(struct platform_device *pdev)
 	retu_free_irq(RETU_INT_HOOK);
 	input_unregister_device(hs->idev);
 	input_free_device(hs->idev);
+	kfree(hs);
 	return 0;
 }
 
@@ -352,4 +355,4 @@ module_exit(retu_headset_exit);
 
 MODULE_DESCRIPTION("Retu/Vilma headset detection");
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Juha Yrj�);
+MODULE_AUTHOR("Juha Yrj�l�");
diff --git a/drivers/cbus/retu-pwrbutton.c b/drivers/cbus/retu-pwrbutton.c
index 38d7aa4..cc47691 100644
--- a/drivers/cbus/retu-pwrbutton.c
+++ b/drivers/cbus/retu-pwrbutton.c
@@ -7,7 +7,7 @@
  *
  * Written by Ari Saastamoinen <ari.saastamoinen@xxxxxxxxxxxxxx>
  *
- * Contact Juha Yrj�<juha.yrjola@xxxxxxxxx>
+ * Contact Juha Yrj�l� <juha.yrjola@xxxxxxxxx>
  *
  * This file is subject to the terms and conditions of the GNU General
  * Public License. See the file "COPYING" in the main directory of this
@@ -75,29 +75,40 @@ static void retubutton_irq(unsigned long arg)
  */
 static int __init retubutton_init(void)
 {
-	int irq;
-
-	printk(KERN_INFO "Retu power button driver initialized\n");
-	irq = RETU_INT_PWR;
+	int ret;
 
 	init_timer(&pwrbtn_timer);
 	pwrbtn_timer.function = retubutton_timer_func;
 
-	if (retu_request_irq(irq, &retubutton_irq, 0, "PwrOnX") < 0) {
+	if (retu_request_irq(RETU_INT_PWR, &retubutton_irq, 0, "PwrOnX") < 0) {
+		del_timer_sync(&pwrbtn_timer);
 		printk(KERN_ERR "%s@%s: Cannot allocate irq\n",
 		       __FUNCTION__, __FILE__);
 		return -EBUSY;
 	}
 
 	pwrbtn_dev = input_allocate_device();
-	if (!pwrbtn_dev)
+	if (!pwrbtn_dev) {
+		retu_free_irq(RETU_INT_PWR);
+		del_timer_sync(&pwrbtn_timer);
 		return -ENOMEM;
+	}
 
 	pwrbtn_dev->evbit[0] = BIT_MASK(EV_KEY);
 	pwrbtn_dev->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER);
 	pwrbtn_dev->name = "retu-pwrbutton";
 
-	return input_register_device(pwrbtn_dev);
+	ret = input_register_device(pwrbtn_dev);
+	if (ret < 0) {
+		retu_free_irq(RETU_INT_PWR);
+		del_timer_sync(&pwrbtn_timer);
+		input_free_device(pwrbtn_dev);
+		return ret;
+	}
+
+	printk(KERN_INFO "Retu power button driver initialized\n");
+
+	return 0;
 }
 
 /**
@@ -108,6 +119,7 @@ static void __exit retubutton_exit(void)
 	retu_free_irq(RETU_INT_PWR);
 	del_timer_sync(&pwrbtn_timer);
 	input_unregister_device(pwrbtn_dev);
+	input_free_device(pwrbtn_dev);
 }
 
 module_init(retubutton_init);
diff --git a/drivers/cbus/retu-rtc.c b/drivers/cbus/retu-rtc.c
index 76343f9..5a6a816 100644
--- a/drivers/cbus/retu-rtc.c
+++ b/drivers/cbus/retu-rtc.c
@@ -381,7 +381,7 @@ static int __devinit retu_rtc_probe(struct platform_device *pdev)
 		retu_rtc_do_reset();
 
 	if ((r = device_create_file(&(pdev->dev), &dev_attr_time)) != 0)
-		return r;
+		goto err_free_irqs;
 	else if ((r = device_create_file(&(pdev->dev), &dev_attr_reset)) != 0)
 		goto err_unregister_time;
 	else if ((r = device_create_file(&(pdev->dev), &dev_attr_alarm)) != 0)
@@ -401,6 +401,9 @@ err_unregister_reset:
 	device_remove_file(&(pdev->dev), &dev_attr_reset);
 err_unregister_time:
 	device_remove_file(&(pdev->dev), &dev_attr_time);
+err_free_irqs:
+	retu_free_irq(RETU_INT_RTCS);
+	retu_free_irq(RETU_INT_RTCA);
 	return r;
 }
 
diff --git a/drivers/cbus/retu.c b/drivers/cbus/retu.c
index d9f28d5..8c0d7cb 100644
--- a/drivers/cbus/retu.c
+++ b/drivers/cbus/retu.c
@@ -331,6 +331,7 @@ static int __devinit retu_probe(struct platform_device *pdev)
 					 struct omap_em_asic_bb5_config);
 	if (em_asic_config == NULL) {
 		printk(KERN_ERR PFX "Unable to retrieve config data\n");
+		tasklet_kill(&retu_tasklet);
 		return -ENODATA;
 	}
 
@@ -338,6 +339,7 @@ static int __devinit retu_probe(struct platform_device *pdev)
 
 	if ((ret = gpio_request(retu_irq_pin, "RETU irq")) < 0) {
 		printk(KERN_ERR PFX "Unable to reserve IRQ GPIO\n");
+		tasklet_kill(&retu_tasklet);
 		return ret;
 	}
 
@@ -364,6 +366,7 @@ static int __devinit retu_probe(struct platform_device *pdev)
 	if (ret < 0) {
 		printk(KERN_ERR PFX "Unable to register IRQ handler\n");
 		gpio_free(retu_irq_pin);
+		tasklet_kill(&retu_tasklet);
 		return ret;
 	}
 	set_irq_wake(gpio_to_irq(retu_irq_pin), 1);
@@ -377,6 +380,7 @@ static int __devinit retu_probe(struct platform_device *pdev)
 		printk(KERN_ERR "Unable to initialize driver\n");
 		free_irq(gpio_to_irq(retu_irq_pin), 0);
 		gpio_free(retu_irq_pin);
+		tasklet_kill(&retu_tasklet);
 		return ret;
 	}
 #endif

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux