aboutsummaryrefslogtreecommitdiff
path: root/drivers/leds
diff options
context:
space:
mode:
authorJonas Bonn <jonas.bonn@gmail.com>2008-11-19 17:10:57 +0000
committerAndy Green <agreen@pads.home.warmcat.com>2008-11-19 17:10:57 +0000
commitae133611810121ee572e8adb61fbe665ff2d5e4f (patch)
tree74631a76274ad1056727cbe1047cdad3d57ed94b /drivers/leds
parent91c639638bb2b7d0cc4d4235528aec653e2e4570 (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>
Diffstat (limited to 'drivers/leds')
-rw-r--r--drivers/leds/leds-neo1973-vibrator.c12
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;
}