[PATCH] backlight: corgi_lcd: Use gpio_set_value_cansleep() for akita machines to avoid WARN_ON trigger

Andrew Morton akpm at linux-foundation.org
Thu Nov 29 20:36:46 EST 2012


On Fri, 30 Nov 2012 02:06:17 +0100
dromede at gmail.com wrote:

> From: Marko Katic <dromede.gmail.com>
> 
> Changing backlight intensity on an Akita (Sharp Zaurus C-1000)
> will always trigger a WARN_ON:
> 
> WARNING: at drivers/gpio/gpiolib.c:1672 __gpio_set_value+0x38/0xa4()
> 
> ...
>
> Akita machines have backlight controls hooked to a gpio expander chip, max7310.
> The driver that controls the max7310 sets the cansleep flag and the corgi_lcd
> driver only uses plain gpio_set_value calls for changing backlight controls.
> This triggers the WARN_ON on akita machines.
> 
> Akita is the only exception in this case since other users of corgi_bl access
> backlight gpio controls through a different gpio expander which does not set the cansleep flag.

Let's be nice and specific, please.  You're referring to
pca953x_gpio_set_value(), yes?  And it uses i2c transfers which can
sleep?

> Fix this by conditionally using gpio_set_value_cansleep() when changing backlight intensity on
> akita machines.

I don't get this.  There is no difference between
gpio_set_value_cansleep() and __gpio_set_value() apart from the
generation of debug warnings.  What's going on here?

> index c781768..f33e26f 100644
> --- a/drivers/video/backlight/corgi_lcd.c
> +++ b/drivers/video/backlight/corgi_lcd.c
> @@ -26,7 +26,7 @@
>  #include <linux/spi/corgi_lcd.h>
>  #include <linux/slab.h>
>  #include <asm/mach/sharpsl_param.h>
> -
> +#include <asm/mach-types.h>
>  #define POWER_IS_ON(pwr)	((pwr) <= FB_BLANK_NORMAL)
>  
>  /* Register Addresses */
> @@ -408,11 +408,19 @@ static int corgi_bl_set_intensity(struct corgi_lcd *lcd, int intensity)
>  	/* Bit 5 via GPIO_BACKLIGHT_CONT */
>  	cont = !!(intensity & 0x20) ^ lcd->gpio_backlight_cont_inverted;
>  
> -	if (gpio_is_valid(lcd->gpio_backlight_cont))
> -		gpio_set_value(lcd->gpio_backlight_cont, cont);
> +	if (gpio_is_valid(lcd->gpio_backlight_cont)) {
> +		if (machine_is_akita())
> +			gpio_set_value_cansleep(lcd->gpio_backlight_cont, cont);
> +		else
> +			gpio_set_value(lcd->gpio_backlight_cont, cont);
> +	}

See, here you could do

	if (__gpio_cansleep(lcd->gpio_backlight_cont))
		gpio_set_value_cansleep(...);
	else
		gpio_set_value(...);

and solve the problem forever, without having to hackily add
hardware-specific exceptions.

But such a change simply demonstrates the silliness of
this gpio_set_value_cansleep-vs-gpio_set_value thing.

Confused.




More information about the linux-arm-kernel mailing list