From ae133611810121ee572e8adb61fbe665ff2d5e4f Mon Sep 17 00:00:00 2001 From: Jonas Bonn Date: Wed, 19 Nov 2008 17:10:57 +0000 Subject: GTA01: replace mutex with spinlock in neo1973_vib_vib_set This function (set_brightness) may be called in interrupt context and therefore should not sleep; use a spin_lock instead of a mutex to ensure this. This should take care of the following BUG: [21474678.340000] BUG: sleeping function called from invalid context at kernel/mutex.c:207 [21474678.340000] in_atomic():1, irqs_disabled():0 [21474678.340000] no locks held by python/1255. [21474678.340000] [] (dump_stack+0x0/0x18) from [] (__might_sleep+0xdc/0xf8) [21474678.340000] [] (__might_sleep+0x0/0xf8) from [] (mutex_lock_nested+0x2c/0x264) [21474678.340000] r5:c03ed754 r4:c03ed6dc [21474678.340000] [] (mutex_lock_nested+0x0/0x264) from [] (neo1973_vib_vib_set+0x2c/0x6c) [21474678.340000] [] (neo1973_vib_vib_set+0x0/0x6c) from [] (led_timer_function+0x8c/0xb4) [21474678.340000] r6:c041a1a0 r5:c7f34820 r4:0000012c [21474678.340000] [] (led_timer_function+0x0/0xb4) from [] (run_timer_softirq+0x180/0x20c) [21474678.340000] r5:c7f3482c r4:00000102 [21474678.340000] [] (run_timer_softirq+0x0/0x20c) from [] (__do_softirq+0x64/0xd8) [21474678.340000] r8:00000000 r7:00000001 r6:0000000a r5:c0419ff8 r4:00000041 [21474678.340000] [] (__do_softirq+0x0/0xd8) from [] (irq_exit+0x48/0x5c) [21474678.340000] r6:00000000 r5:c03d128c r4:0000001e [21474678.340000] [] (irq_exit+0x0/0x5c) from [] (__exception_text_start+0x50/0x68) [21474678.340000] [] (__exception_text_start+0x0/0x68) from [] (__irq_usr+0x4c/0xe0) [21474678.340000] Exception stack(0xc7d7bfb0 to 0xc7d7bff8) [21474678.340000] bfa0: 0055bb3a 0000004a 00000000 0055baf0 [21474678.340000] bfc0: 0000004a 0052ae30 00000025 005168e0 00000073 00000025 401281ec 00000000 [21474678.340000] bfe0: 0000006f be9b8470 006e0069 400a8844 60000010 ffffffff [21474678.340000] r6:00004000 r5:f4000000 r4:ffffffff Signed-off-by: Jonas Bonn --- drivers/leds/leds-neo1973-vibrator.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers/leds') diff --git a/drivers/leds/leds-neo1973-vibrator.c b/drivers/leds/leds-neo1973-vibrator.c index 1c4db5dfbc6..494fb83af4e 100644 --- a/drivers/leds/leds-neo1973-vibrator.c +++ b/drivers/leds/leds-neo1973-vibrator.c @@ -33,7 +33,7 @@ struct neo1973_vib_priv { struct led_classdev cdev; unsigned int gpio; - struct mutex mutex; + spinlock_t lock; unsigned int has_pwm; struct s3c2410_pwm pwm; }; @@ -41,6 +41,7 @@ struct neo1973_vib_priv { static void neo1973_vib_vib_set(struct led_classdev *led_cdev, enum led_brightness value) { + unsigned long flags; struct neo1973_vib_priv *vp = container_of(led_cdev, struct neo1973_vib_priv, cdev); @@ -56,7 +57,7 @@ static void neo1973_vib_vib_set(struct led_classdev *led_cdev, * value == 128 -> 50% duty cycle (medium power) * value == 0 -> 0% duty cycle (zero power) */ - mutex_lock(&vp->mutex); + spin_lock_irqsave(&vp->lock, flags); if (vp->has_pwm) s3c2410_pwm_duty_cycle(value / 4, &vp->pwm); else { @@ -65,8 +66,7 @@ static void neo1973_vib_vib_set(struct led_classdev *led_cdev, else neo1973_gpb_setpin(vp->gpio, 0); } - - mutex_unlock(&vp->mutex); + spin_unlock_irqrestore(&vp->lock, flags); } static struct neo1973_vib_priv neo1973_vib_led = { @@ -159,7 +159,7 @@ static int __init neo1973_vib_probe(struct platform_device *pdev) #ifdef CONFIG_MACH_NEO1973_GTA02 configured: #endif - mutex_init(&neo1973_vib_led.mutex); + spin_lock_init(&neo1973_vib_led.lock); return led_classdev_register(&pdev->dev, &neo1973_vib_led.cdev); } @@ -177,8 +177,6 @@ static int neo1973_vib_remove(struct platform_device *pdev) led_classdev_unregister(&neo1973_vib_led.cdev); - mutex_destroy(&neo1973_vib_led.mutex); - return 0; } -- cgit v1.2.3