diff options
author | Magnus Damm <damm@opensource.se> | 2011-10-31 17:12:06 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-31 17:30:55 -0700 |
commit | 02c3294174e170a47cfd58956a739901160381a8 (patch) | |
tree | e0531a64436f9604990585d7ac3a77ae22a4ea46 /drivers/leds | |
parent | 3edc5804b7d27ec48975d7d7acbc0b3e1c62c064 (diff) |
drivers/leds/leds-renesas-tpu.c: update driver to use workqueue
Use a workqueue in the Renesas TPU LED driver to allow the Runtime PM code
to sleep.
Signed-off-by: Magnus Damm <damm@opensource.se>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Richard Purdie <rpurdie@rpsys.net>
Cc: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/leds')
-rw-r--r-- | drivers/leds/leds-renesas-tpu.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/drivers/leds/leds-renesas-tpu.c b/drivers/leds/leds-renesas-tpu.c index d9a7d72a7569..45dbdf58f5ee 100644 --- a/drivers/leds/leds-renesas-tpu.c +++ b/drivers/leds/leds-renesas-tpu.c @@ -31,6 +31,7 @@ #include <linux/err.h> #include <linux/slab.h> #include <linux/pm_runtime.h> +#include <linux/workqueue.h> enum r_tpu_pin { R_TPU_PIN_UNUSED, R_TPU_PIN_GPIO, R_TPU_PIN_GPIO_FN }; enum r_tpu_timer { R_TPU_TIMER_UNUSED, R_TPU_TIMER_ON }; @@ -44,6 +45,8 @@ struct r_tpu_priv { enum r_tpu_timer timer_state; unsigned long min_rate; unsigned int refresh_rate; + struct work_struct work; + enum led_brightness new_brightness; }; static DEFINE_SPINLOCK(r_tpu_lock); @@ -211,15 +214,15 @@ static void r_tpu_set_pin(struct r_tpu_priv *p, enum r_tpu_pin new_state, p->pin_state = new_state; } -static void r_tpu_set_brightness(struct led_classdev *ldev, - enum led_brightness brightness) +static void r_tpu_work(struct work_struct *work) { - struct r_tpu_priv *p = container_of(ldev, struct r_tpu_priv, ldev); + struct r_tpu_priv *p = container_of(work, struct r_tpu_priv, work); + enum led_brightness brightness = p->new_brightness; r_tpu_disable(p); /* off and maximum are handled as GPIO pins, in between PWM */ - if ((brightness == 0) || (brightness == ldev->max_brightness)) + if ((brightness == 0) || (brightness == p->ldev.max_brightness)) r_tpu_set_pin(p, R_TPU_PIN_GPIO, brightness); else { r_tpu_set_pin(p, R_TPU_PIN_GPIO_FN, 0); @@ -227,6 +230,14 @@ static void r_tpu_set_brightness(struct led_classdev *ldev, } } +static void r_tpu_set_brightness(struct led_classdev *ldev, + enum led_brightness brightness) +{ + struct r_tpu_priv *p = container_of(ldev, struct r_tpu_priv, ldev); + p->new_brightness = brightness; + schedule_work(&p->work); +} + static int __devinit r_tpu_probe(struct platform_device *pdev) { struct led_renesas_tpu_config *cfg = pdev->dev.platform_data; @@ -274,6 +285,7 @@ static int __devinit r_tpu_probe(struct platform_device *pdev) r_tpu_set_pin(p, R_TPU_PIN_GPIO, LED_OFF); platform_set_drvdata(pdev, p); + INIT_WORK(&p->work, r_tpu_work); p->ldev.name = cfg->name; p->ldev.brightness = LED_OFF; @@ -307,6 +319,7 @@ static int __devexit r_tpu_remove(struct platform_device *pdev) r_tpu_set_brightness(&p->ldev, LED_OFF); led_classdev_unregister(&p->ldev); + cancel_work_sync(&p->work); r_tpu_disable(p); r_tpu_set_pin(p, R_TPU_PIN_UNUSED, LED_OFF); |