commit 59e589227131abbe5e07576f542cc35a8821c9d3 Author: Andrew de Quincey <[email protected]> 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 <[email protected]> * - * Contact Juha Yrj�l� <[email protected]> + * Contact Juha Yrj�l� <[email protected]> * * 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: 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
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.
- Patch: Init/shutdown correctness fixes for drivers/cbus/... Andrew de Quincey
