[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux-omap
Subject:    Patch: Init/shutdown correctness fixes for drivers/cbus/retu*
From:       Andrew de Quincey <adq () lidskialf ! net>
Date:       2009-05-25 23:18:56
Message-ID: 20090526001856.117145k514vqy2kg () lidskialf ! net
[Download RAW message or body]

This message is in MIME format.


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.



["retu-correctness.patch" (text/x-patch)]

commit 59e589227131abbe5e07576f542cc35a8821c9d3
Author: Andrew de Quincey <adq@lidskialf.net>
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ölä
+ * 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ölä");
+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@elektrobit.com>
  *
- * Contact Juha Yrjölä <juha.yrjola@nokia.com>
+ * Contact Juha Yrj�l� <juha.yrjola@nokia.com>
  *
  * 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
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic