* [PATCH] acpi: video: enhance the quirk detect logic of _BQC
@ 2013-04-07 1:56 Aaron Lu
2013-04-17 14:54 ` Zhang Rui
0 siblings, 1 reply; 3+ messages in thread
From: Aaron Lu @ 2013-04-07 1:56 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Artem Savkov, Cheppes, Luis Medinas, ACPI Devel Mailing List, Zhang Rui
Currently we decide if the _BQC is using index by first setting the
level to maximum, and then check if _BQC returned maximum; if not, we
say it is using index.
This is not true for some buggy systems, where the _BQC method will
always return a constant value(e.g. 0 or 100 for the two broken system)
and thus break the current logic. So this patch tries to enhance the
quirk detect logic for _BQC: we do this by picking a test_level, it can
be the maximum level or the mininum one based on some condition. And we
don't make the assumption that if _BQC returned a value that is not what
we just set, it must be using an index. Instead, we will compare the
value returned from _BQC and if it doesn't match, see if the returned
value is an index. And if still no, clear the capability of _BQC.
Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=42861
Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=56011
Reported-and-tested-by: Artem Savkov <artem.savkov@gmail.com>
Reported-by: Luis Medinas <lmedinas@gmail.com>
Reported-by: Cheppes <cheppes@mailinator.com>
Signed-off-by: Aaron Lu <aaron.lu@intel.com>
---
Thanks Cheppes <cheppes@mailinator.com> for the suggestion of choosing
different levels to test, and also for the help of in code comment
correction.
drivers/acpi/video.c | 67 ++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 57 insertions(+), 10 deletions(-)
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 3cdd047..306ea2a 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -632,6 +632,56 @@ acpi_video_cmp_level(const void *a, const void *b)
}
/*
+ * Decides if _BQC/_BCQ for this system is usable
+ *
+ * We do this by changing the level first and then read out the current
+ * brightness level, if the value does not match, find out if it is using
+ * index. If not, clear the _BQC/_BCQ capability.
+ */
+static int acpi_video_bqc_quirk(struct acpi_video_device *device,
+ int max_level, int current_level)
+{
+ struct acpi_video_device_brightness *br = device->brightness;
+ int result;
+ unsigned long long level;
+ int test_level;
+
+ /* don't mess with existing known broken systems */
+ if (bqc_offset_aml_bug_workaround)
+ return 0;
+
+ /*
+ * Some systems always report current brightness level as maximum
+ * through _BQC, we need to test another value for them.
+ */
+ test_level = current_level == max_level ? br->levels[2] : max_level;
+
+ result = acpi_video_device_lcd_set_level(device, test_level);
+ if (result)
+ return result;
+
+ result = acpi_video_device_lcd_get_level_current(device, &level, true);
+ if (result)
+ return result;
+
+ if (level != test_level) {
+ /* buggy _BQC found, need to find out if it uses index */
+ if (level < br->count) {
+ if (br->flags._BCL_reversed)
+ level = br->count - 3 - level;
+ if (br->levels[level + 2] == test_level)
+ br->flags._BQC_use_index = 1;
+ }
+
+ if (!br->flags._BQC_use_index)
+ device->cap._BQC = device->cap._BCQ = 0;
+ }
+
+ return 0;
+}
+
+
+/*
* Arg:
* device : video output device (LCD, CRT, ..)
*
@@ -742,18 +792,15 @@ acpi_video_init_brightness(struct acpi_video_device *device)
if (result)
goto out_free_levels;
- /*
- * Set the level to maximum and check if _BQC uses indexed value
- */
- result = acpi_video_device_lcd_set_level(device, max_level);
- if (result)
- goto out_free_levels;
-
- result = acpi_video_device_lcd_get_level_current(device, &level, true);
+ result = acpi_video_bqc_quirk(device, max_level, level_old);
if (result)
goto out_free_levels;
-
- br->flags._BQC_use_index = (level == max_level ? 0 : 1);
+ /*
+ * cap._BQC may get cleared due to _BQC is found to be broken
+ * in acpi_video_bqc_quirk, so check again here.
+ */
+ if (!device->cap._BQC)
+ goto set_level;
if (use_bios_initial_backlight) {
level = acpi_video_bqc_value_to_level(device, level_old);
--
1.8.1.4
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] acpi: video: enhance the quirk detect logic of _BQC
2013-04-07 1:56 [PATCH] acpi: video: enhance the quirk detect logic of _BQC Aaron Lu
@ 2013-04-17 14:54 ` Zhang Rui
2013-04-22 12:19 ` Rafael J. Wysocki
0 siblings, 1 reply; 3+ messages in thread
From: Zhang Rui @ 2013-04-17 14:54 UTC (permalink / raw)
To: Aaron Lu
Cc: Rafael J. Wysocki, Artem Savkov, Cheppes, Luis Medinas,
ACPI Devel Mailing List
On Sun, 2013-04-07 at 09:56 +0800, Aaron Lu wrote:
> Currently we decide if the _BQC is using index by first setting the
> level to maximum, and then check if _BQC returned maximum; if not, we
> say it is using index.
>
> This is not true for some buggy systems, where the _BQC method will
> always return a constant value(e.g. 0 or 100 for the two broken system)
> and thus break the current logic. So this patch tries to enhance the
> quirk detect logic for _BQC: we do this by picking a test_level, it can
> be the maximum level or the mininum one based on some condition. And we
> don't make the assumption that if _BQC returned a value that is not what
> we just set, it must be using an index. Instead, we will compare the
> value returned from _BQC and if it doesn't match, see if the returned
> value is an index. And if still no, clear the capability of _BQC.
>
> Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=42861
> Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=56011
> Reported-and-tested-by: Artem Savkov <artem.savkov@gmail.com>
> Reported-by: Luis Medinas <lmedinas@gmail.com>
> Reported-by: Cheppes <cheppes@mailinator.com>
> Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Acked-by: Zhang Rui <rui.zhang@intel.com>
thanks,
rui
> ---
> Thanks Cheppes <cheppes@mailinator.com> for the suggestion of choosing
> different levels to test, and also for the help of in code comment
> correction.
>
> drivers/acpi/video.c | 67 ++++++++++++++++++++++++++++++++++++++++++++--------
> 1 file changed, 57 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
> index 3cdd047..306ea2a 100644
> --- a/drivers/acpi/video.c
> +++ b/drivers/acpi/video.c
> @@ -632,6 +632,56 @@ acpi_video_cmp_level(const void *a, const void *b)
> }
>
> /*
> + * Decides if _BQC/_BCQ for this system is usable
> + *
> + * We do this by changing the level first and then read out the current
> + * brightness level, if the value does not match, find out if it is using
> + * index. If not, clear the _BQC/_BCQ capability.
> + */
> +static int acpi_video_bqc_quirk(struct acpi_video_device *device,
> + int max_level, int current_level)
> +{
> + struct acpi_video_device_brightness *br = device->brightness;
> + int result;
> + unsigned long long level;
> + int test_level;
> +
> + /* don't mess with existing known broken systems */
> + if (bqc_offset_aml_bug_workaround)
> + return 0;
> +
> + /*
> + * Some systems always report current brightness level as maximum
> + * through _BQC, we need to test another value for them.
> + */
> + test_level = current_level == max_level ? br->levels[2] : max_level;
> +
> + result = acpi_video_device_lcd_set_level(device, test_level);
> + if (result)
> + return result;
> +
> + result = acpi_video_device_lcd_get_level_current(device, &level, true);
> + if (result)
> + return result;
> +
> + if (level != test_level) {
> + /* buggy _BQC found, need to find out if it uses index */
> + if (level < br->count) {
> + if (br->flags._BCL_reversed)
> + level = br->count - 3 - level;
> + if (br->levels[level + 2] == test_level)
> + br->flags._BQC_use_index = 1;
> + }
> +
> + if (!br->flags._BQC_use_index)
> + device->cap._BQC = device->cap._BCQ = 0;
> + }
> +
> + return 0;
> +}
> +
> +
> +/*
> * Arg:
> * device : video output device (LCD, CRT, ..)
> *
> @@ -742,18 +792,15 @@ acpi_video_init_brightness(struct acpi_video_device *device)
> if (result)
> goto out_free_levels;
>
> - /*
> - * Set the level to maximum and check if _BQC uses indexed value
> - */
> - result = acpi_video_device_lcd_set_level(device, max_level);
> - if (result)
> - goto out_free_levels;
> -
> - result = acpi_video_device_lcd_get_level_current(device, &level, true);
> + result = acpi_video_bqc_quirk(device, max_level, level_old);
> if (result)
> goto out_free_levels;
> -
> - br->flags._BQC_use_index = (level == max_level ? 0 : 1);
> + /*
> + * cap._BQC may get cleared due to _BQC is found to be broken
> + * in acpi_video_bqc_quirk, so check again here.
> + */
> + if (!device->cap._BQC)
> + goto set_level;
>
> if (use_bios_initial_backlight) {
> level = acpi_video_bqc_value_to_level(device, level_old);
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] acpi: video: enhance the quirk detect logic of _BQC
2013-04-17 14:54 ` Zhang Rui
@ 2013-04-22 12:19 ` Rafael J. Wysocki
0 siblings, 0 replies; 3+ messages in thread
From: Rafael J. Wysocki @ 2013-04-22 12:19 UTC (permalink / raw)
To: Zhang Rui
Cc: Aaron Lu, Artem Savkov, Cheppes, Luis Medinas, ACPI Devel Mailing List
On Wednesday, April 17, 2013 10:54:50 PM Zhang Rui wrote:
> On Sun, 2013-04-07 at 09:56 +0800, Aaron Lu wrote:
> > Currently we decide if the _BQC is using index by first setting the
> > level to maximum, and then check if _BQC returned maximum; if not, we
> > say it is using index.
> >
> > This is not true for some buggy systems, where the _BQC method will
> > always return a constant value(e.g. 0 or 100 for the two broken system)
> > and thus break the current logic. So this patch tries to enhance the
> > quirk detect logic for _BQC: we do this by picking a test_level, it can
> > be the maximum level or the mininum one based on some condition. And we
> > don't make the assumption that if _BQC returned a value that is not what
> > we just set, it must be using an index. Instead, we will compare the
> > value returned from _BQC and if it doesn't match, see if the returned
> > value is an index. And if still no, clear the capability of _BQC.
> >
> > Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=42861
> > Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=56011
> > Reported-and-tested-by: Artem Savkov <artem.savkov@gmail.com>
> > Reported-by: Luis Medinas <lmedinas@gmail.com>
> > Reported-by: Cheppes <cheppes@mailinator.com>
> > Signed-off-by: Aaron Lu <aaron.lu@intel.com>
>
> Acked-by: Zhang Rui <rui.zhang@intel.com>
Applied.
Thanks,
Rafael
> > ---
> > Thanks Cheppes <cheppes@mailinator.com> for the suggestion of choosing
> > different levels to test, and also for the help of in code comment
> > correction.
> >
> > drivers/acpi/video.c | 67 ++++++++++++++++++++++++++++++++++++++++++++--------
> > 1 file changed, 57 insertions(+), 10 deletions(-)
> >
> > diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
> > index 3cdd047..306ea2a 100644
> > --- a/drivers/acpi/video.c
> > +++ b/drivers/acpi/video.c
> > @@ -632,6 +632,56 @@ acpi_video_cmp_level(const void *a, const void *b)
> > }
> >
> > /*
> > + * Decides if _BQC/_BCQ for this system is usable
> > + *
> > + * We do this by changing the level first and then read out the current
> > + * brightness level, if the value does not match, find out if it is using
> > + * index. If not, clear the _BQC/_BCQ capability.
> > + */
> > +static int acpi_video_bqc_quirk(struct acpi_video_device *device,
> > + int max_level, int current_level)
> > +{
> > + struct acpi_video_device_brightness *br = device->brightness;
> > + int result;
> > + unsigned long long level;
> > + int test_level;
> > +
> > + /* don't mess with existing known broken systems */
> > + if (bqc_offset_aml_bug_workaround)
> > + return 0;
> > +
> > + /*
> > + * Some systems always report current brightness level as maximum
> > + * through _BQC, we need to test another value for them.
> > + */
> > + test_level = current_level == max_level ? br->levels[2] : max_level;
> > +
> > + result = acpi_video_device_lcd_set_level(device, test_level);
> > + if (result)
> > + return result;
> > +
> > + result = acpi_video_device_lcd_get_level_current(device, &level, true);
> > + if (result)
> > + return result;
> > +
> > + if (level != test_level) {
> > + /* buggy _BQC found, need to find out if it uses index */
> > + if (level < br->count) {
> > + if (br->flags._BCL_reversed)
> > + level = br->count - 3 - level;
> > + if (br->levels[level + 2] == test_level)
> > + br->flags._BQC_use_index = 1;
> > + }
> > +
> > + if (!br->flags._BQC_use_index)
> > + device->cap._BQC = device->cap._BCQ = 0;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +
> > +/*
> > * Arg:
> > * device : video output device (LCD, CRT, ..)
> > *
> > @@ -742,18 +792,15 @@ acpi_video_init_brightness(struct acpi_video_device *device)
> > if (result)
> > goto out_free_levels;
> >
> > - /*
> > - * Set the level to maximum and check if _BQC uses indexed value
> > - */
> > - result = acpi_video_device_lcd_set_level(device, max_level);
> > - if (result)
> > - goto out_free_levels;
> > -
> > - result = acpi_video_device_lcd_get_level_current(device, &level, true);
> > + result = acpi_video_bqc_quirk(device, max_level, level_old);
> > if (result)
> > goto out_free_levels;
> > -
> > - br->flags._BQC_use_index = (level == max_level ? 0 : 1);
> > + /*
> > + * cap._BQC may get cleared due to _BQC is found to be broken
> > + * in acpi_video_bqc_quirk, so check again here.
> > + */
> > + if (!device->cap._BQC)
> > + goto set_level;
> >
> > if (use_bios_initial_backlight) {
> > level = acpi_video_bqc_value_to_level(device, level_old);
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2013-04-22 12:11 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-04-07 1:56 [PATCH] acpi: video: enhance the quirk detect logic of _BQC Aaron Lu
2013-04-17 14:54 ` Zhang Rui
2013-04-22 12:19 ` Rafael J. Wysocki
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.