diff options
author | Jonas Bonn <jonas.bonn@gmail.com> | 2008-11-19 17:10:57 +0000 |
---|---|---|
committer | Andy Green <agreen@pads.home.warmcat.com> | 2008-11-19 17:10:57 +0000 |
commit | ae133611810121ee572e8adb61fbe665ff2d5e4f (patch) | |
tree | 74631a76274ad1056727cbe1047cdad3d57ed94b | |
parent | 91c639638bb2b7d0cc4d4235528aec653e2e4570 (diff) |
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] [<c002d928>] (dump_stack+0x0/0x18) from [<c003b08c>] (__might_sleep+0xdc/0xf8)
[21474678.340000] [<c003afb0>] (__might_sleep+0x0/0xf8) from [<c02efc08>] (mutex_lock_nested+0x2c/0x264)
[21474678.340000] r5:c03ed754 r4:c03ed6dc
[21474678.340000] [<c02efbdc>] (mutex_lock_nested+0x0/0x264) from [<c022e180>] (neo1973_vib_vib_set+0x2c/0x6c)
[21474678.340000] [<c022e154>] (neo1973_vib_vib_set+0x0/0x6c) from [<c022e6a4>] (led_timer_function+0x8c/0xb4)
[21474678.340000] r6:c041a1a0 r5:c7f34820 r4:0000012c
[21474678.340000] [<c022e618>] (led_timer_function+0x0/0xb4) from [<c004aeb4>] (run_timer_softirq+0x180/0x20c)
[21474678.340000] r5:c7f3482c r4:00000102
[21474678.340000] [<c004ad34>] (run_timer_softirq+0x0/0x20c) from [<c0046368>] (__do_softirq+0x64/0xd8)
[21474678.340000] r8:00000000 r7:00000001 r6:0000000a r5:c0419ff8 r4:00000041
[21474678.340000] [<c0046304>] (__do_softirq+0x0/0xd8) from [<c0046764>] (irq_exit+0x48/0x5c)
[21474678.340000] r6:00000000 r5:c03d128c r4:0000001e
[21474678.340000] [<c004671c>] (irq_exit+0x0/0x5c) from [<c0028050>] (__exception_text_start+0x50/0x68)
[21474678.340000] [<c0028000>] (__exception_text_start+0x0/0x68) from [<c0028a8c>] (__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 <jonas.bonn@gmail.com>
-rw-r--r-- | drivers/leds/leds-neo1973-vibrator.c | 12 |
1 files changed, 5 insertions, 7 deletions
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; } |