backlight: corgi_lcd: Use gpio_set_value_cansleep() to avoid WARN_ON
authorMarko Katic <dromede@gmail.com>
Tue, 18 Dec 2012 00:01:14 +0000 (16:01 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 18 Dec 2012 01:15:17 +0000 (17:15 -0800)
Changing backlight intensity on an Akita (Sharp Zaurus C-1000) triggers
WARN_ON message:

  WARNING: at drivers/gpio/gpiolib.c:1672 __gpio_set_value+0x38/0xa4()
  Modules linked in:
  Backtrace:
    corgi_bl_set_intensity+0x0/0x74
    corgi_bl_update_status+0x0/0x64
    corgi_lcd_probe+0x0/0x258
    spi_drv_probe+0x0/0x24
    driver_probe_device+0x0/0x208
    __driver_attach+0x0/0x94
    bus_for_each_dev+0x0/0x90
    driver_attach+0x0/0x28
    bus_add_driver+0x0/0x22c
    driver_register+0x0/0x134
    spi_register_driver+0x0/0x60
    corgi_lcd_driver_init+0x0/0x1c
    do_one_initcall+0x0/0x174
    kernel_init+0x0/0x2a8

Akita machines have backlight controls hooked to a gpio expander chip,
max7310 using i2c transfers which can sleep.  In this case,
pca953x_gpio_set_value() can be called to control gpio, and
pca953x_setup_gpio() sets can_sleep flag.  Therefore,
gpio_set_value_cansleep() should be used in order to avoid WARN_ON on
akita machines.

Akita is the only exception in this case since other users of corgi_lcd
access backlight gpio controls through a different gpio expander which
does not set the can_sleep flag.

Signed-off-by: Marko Katic <dromede@gmail.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Cc: Richard Purdie <rpurdie@rpsys.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/video/backlight/corgi_lcd.c

index e2e1b62..e323fcb 100644 (file)
@@ -409,10 +409,10 @@ static int corgi_bl_set_intensity(struct corgi_lcd *lcd, int intensity)
        cont = !!(intensity & 0x20) ^ lcd->gpio_backlight_cont_inverted;
 
        if (gpio_is_valid(lcd->gpio_backlight_cont))
-               gpio_set_value(lcd->gpio_backlight_cont, cont);
+               gpio_set_value_cansleep(lcd->gpio_backlight_cont, cont);
 
        if (gpio_is_valid(lcd->gpio_backlight_on))
-               gpio_set_value(lcd->gpio_backlight_on, intensity);
+               gpio_set_value_cansleep(lcd->gpio_backlight_on, intensity);
 
        if (lcd->kick_battery)
                lcd->kick_battery();