Re: [PATCH] ACPI: disable the ACPI backlight control on laptops with buggy _BCL methods

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 2009-01-08 at 10:58 +0800, Zhang, Rui wrote:
> From: Zhang Rui <rui.zhang@xxxxxxxxx>
> Subject: disable the ACPI backlight control on laptops with buggy _BCL methods
> 
> Some users used to control the backlight via the platform interface.
> But commit c3d6de698c84efdbdd3781b7058bcc339ab43da8 disables the platform
> backlight control if ACPI video backlight control is available.
> 
> This breaks the laptops with buggy _BCL/_BCM/_BQC methods. i.e. only ACPI
> backlight I/F are available on these laptops but they don't work.
> 
> With this patch applied, the ACPI backlight control are disabled instead
> on these laptops.
> 
> http://bugzilla.kernel.org/show_bug.cgi?id=12037
> http://bugzilla.kernel.org/show_bug.cgi?id=12235
> http://bugzilla.kernel.org/show_bug.cgi?id=12249
> http://bugzilla.kernel.org/show_bug.cgi?id=12302
> https://bugs.launchpad.net/ubuntu/+source/linux/+bug/311716
> https://bugs.launchpad.net/ubuntu/+source/linux/+bug/301524
> 
> CC: Thomas Renninger <trenn@xxxxxxx>
> Signed-off-by: Zhang Rui <rui.zhang@xxxxxxxxx>
tested-by: Andy Whitcroft <apw@xxxxxxxxxxxxx>

> ---
>  drivers/acpi/video_detect.c |   83 ++++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 77 insertions(+), 6 deletions(-)
> 
> Index: linux-2.6/drivers/acpi/video_detect.c
> ===================================================================
> --- linux-2.6.orig/drivers/acpi/video_detect.c
> +++ linux-2.6/drivers/acpi/video_detect.c
> @@ -44,17 +44,88 @@ static long acpi_video_support;
>  static bool acpi_video_caps_checked;
>  
>  static acpi_status
> +acpi_backlight_validate_bcl(acpi_handle handle)
> +{
> +	union acpi_object *obj, *obj2;
> +	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
> +	int level_ac = 0, level_battery = 0;
> +	int i, count;
> +	int *levels;
> +	acpi_status status;
> +
> +
> +	status = acpi_evaluate_object(handle, "_BCL", NULL, &buffer);
> +	if (!ACPI_SUCCESS(status))
> +		return status;
> +	obj = (union acpi_object *)buffer.pointer;
> +	if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
> +		printk(KERN_ERR PREFIX "Invalid _BCL data\n");
> +		status = AE_BAD_DATA;
> +		goto out;
> +	}
> +
> +	if (obj->package.count < 2) {
> +		status = AE_BAD_DATA;
> +		goto out;
> +	}
> +
> +        levels = kzalloc(obj->package.count * sizeof(*levels), GFP_KERNEL);
> +	if (!levels) {
> +		status = AE_NO_MEMORY;
> +		goto out;
> +	}
> +
> +	for (i = 0, count = 0; i < obj->package.count; i++) {
> +		obj2 = (union acpi_object *)&obj->package.elements[i];
> +		if (obj2->type != ACPI_TYPE_INTEGER) {
> +			printk(KERN_ERR PREFIX "Invalid data\n");
> +			continue;
> +		}
> +		levels[i] = (u32) obj2->integer.value;
> +		count ++;
> +        }
> +
> +        if (count < 2) {
> +		status = AE_BAD_DATA;
> +		goto out_free_levels;
> +	}
> +
> +	for (i = 2, level_ac = levels[0], level_battery = levels[1]; i < count; i ++) {
> +		if (levels[0] == levels[i])
> +			level_ac = 1;
> +		if (levels[1] == levels[i])
> +			level_battery = 1;
> +	}
> +
> +	if (!level_ac || !level_battery) {
> +		printk(KERN_ERR PREFIX "Invalid _BCL package\n");
> +		status = AE_BAD_DATA;
> +		goto out_free_levels;
> +	}
> +
> +        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count));
> +
> +out_free_levels:
> +	kfree(levels);
> +out:
> +        kfree(obj);
> +        return status;
> +}
> +
> +static acpi_status
>  acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context,
>  			  void **retyurn_value)
>  {
>  	long *cap = context;
> -	acpi_handle h_dummy;
> +	acpi_handle h_dummy1, h_dummy2;
>  
> -	if (ACPI_SUCCESS(acpi_get_handle(handle, "_BCM", &h_dummy)) &&
> -	    ACPI_SUCCESS(acpi_get_handle(handle, "_BCL", &h_dummy))) {
> -		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight "
> -				  "support\n"));
> -		*cap |= ACPI_VIDEO_BACKLIGHT;
> +	if (ACPI_SUCCESS(acpi_get_handle(handle, "_BCM", &h_dummy1)) &&
> +	    ACPI_SUCCESS(acpi_get_handle(handle, "_BCL", &h_dummy2))) {
> +		if (ACPI_SUCCESS(acpi_backlight_validate_bcl(h_dummy2))) {
> +			ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight "
> +					  "support\n"));
> +			*cap |= ACPI_VIDEO_BACKLIGHT;
> +		}
>  		/* We have backlight support, no need to scan further */
>  		return AE_CTRL_TERMINATE;
>  	}
> 
> email message attachment
> > -------- Forwarded Message --------
> > From: Zhang, Rui <rui.zhang@xxxxxxxxx>
> > Subject: don't use buggy _BCL/_BCM/_BQC for backlight control
> > Date: Thu, 8 Jan 2009 10:56:50 +0800
> > 
> > Some users used to control the backlight via the platform interface.
> > But commit c3d6de698c84efdbdd3781b7058bcc339ab43da8 disables the platform
> > backlight control if ACPI video backlight control is available.
> > 
> > This breaks the laptops with buggy _BCL/_BCM/_BQC methods. i.e. only ACPI
> > backlight I/F are available on these laptops but they don't work.
> > 
> > With this patch applied, the ACPI backlight control are disabled instead
> > on these laptops.
> > 
> > http://bugzilla.kernel.org/show_bug.cgi?id=12037
> > http://bugzilla.kernel.org/show_bug.cgi?id=12235
> > http://bugzilla.kernel.org/show_bug.cgi?id=12249
> > http://bugzilla.kernel.org/show_bug.cgi?id=12302
> > https://bugs.launchpad.net/ubuntu/+source/linux/+bug/311716
> > https://bugs.launchpad.net/ubuntu/+source/linux/+bug/301524
> > 
> > CC: Thomas Renninger <trenn@xxxxxxx>
> > Signed-off-by: Zhang Rui <rui.zhang@xxxxxxxxx>
> > ---
> >  drivers/acpi/video_detect.c |   83 ++++++++++++++++++++++++++++++++++++++++----
> >  1 file changed, 77 insertions(+), 6 deletions(-)
> > 
> > Index: linux-2.6/drivers/acpi/video_detect.c
> > ===================================================================
> > --- linux-2.6.orig/drivers/acpi/video_detect.c
> > +++ linux-2.6/drivers/acpi/video_detect.c
> > @@ -44,17 +44,88 @@ static long acpi_video_support;
> >  static bool acpi_video_caps_checked;
> >  
> >  static acpi_status
> > +acpi_backlight_validate_bcl(acpi_handle handle)
> > +{
> > +	union acpi_object *obj, *obj2;
> > +	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
> > +	int level_ac = 0, level_battery = 0;
> > +	int i, count;
> > +	int *levels;
> > +	acpi_status status;
> > +
> > +
> > +	status = acpi_evaluate_object(handle, "_BCL", NULL, &buffer);
> > +	if (!ACPI_SUCCESS(status))
> > +		return status;
> > +	obj = (union acpi_object *)buffer.pointer;
> > +	if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
> > +		printk(KERN_ERR PREFIX "Invalid _BCL data\n");
> > +		status = AE_BAD_DATA;
> > +		goto out;
> > +	}
> > +
> > +	if (obj->package.count < 2) {
> > +		status = AE_BAD_DATA;
> > +		goto out;
> > +	}
> > +
> > +        levels = kzalloc(obj->package.count * sizeof(*levels), GFP_KERNEL);
> > +	if (!levels) {
> > +		status = AE_NO_MEMORY;
> > +		goto out;
> > +	}
> > +
> > +	for (i = 0, count = 0; i < obj->package.count; i++) {
> > +		obj2 = (union acpi_object *)&obj->package.elements[i];
> > +		if (obj2->type != ACPI_TYPE_INTEGER) {
> > +			printk(KERN_ERR PREFIX "Invalid data\n");
> > +			continue;
> > +		}
> > +		levels[i] = (u32) obj2->integer.value;
> > +		count ++;
> > +        }
> > +
> > +        if (count < 2) {
> > +		status = AE_BAD_DATA;
> > +		goto out_free_levels;
> > +	}
> > +
> > +	for (i = 2, level_ac = levels[0], level_battery = levels[1]; i < count; i ++) {
> > +		if (levels[0] == levels[i])
> > +			level_ac = 1;
> > +		if (levels[1] == levels[i])
> > +			level_battery = 1;
> > +	}
> > +
> > +	if (!level_ac || !level_battery) {
> > +		printk(KERN_ERR PREFIX "Invalid _BCL package\n");
> > +		status = AE_BAD_DATA;
> > +		goto out_free_levels;
> > +	}
> > +
> > +        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count));
> > +
> > +out_free_levels:
> > +	kfree(levels);
> > +out:
> > +        kfree(obj);
> > +        return status;
> > +}
> > +
> > +static acpi_status
> >  acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context,
> >  			  void **retyurn_value)
> >  {
> >  	long *cap = context;
> > -	acpi_handle h_dummy;
> > +	acpi_handle h_dummy1, h_dummy2;
> >  
> > -	if (ACPI_SUCCESS(acpi_get_handle(handle, "_BCM", &h_dummy)) &&
> > -	    ACPI_SUCCESS(acpi_get_handle(handle, "_BCL", &h_dummy))) {
> > -		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight "
> > -				  "support\n"));
> > -		*cap |= ACPI_VIDEO_BACKLIGHT;
> > +	if (ACPI_SUCCESS(acpi_get_handle(handle, "_BCM", &h_dummy1)) &&
> > +	    ACPI_SUCCESS(acpi_get_handle(handle, "_BCL", &h_dummy2))) {
> > +		if (ACPI_SUCCESS(acpi_backlight_validate_bcl(h_dummy2))) {
> > +			ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight "
> > +					  "support\n"));
> > +			*cap |= ACPI_VIDEO_BACKLIGHT;
> > +		}
> >  		/* We have backlight support, no need to scan further */
> >  		return AE_CTRL_TERMINATE;
> >  	}

--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux