diff options
author | Azael Avalos <coproscefalo@gmail.com> | 2014-08-04 17:21:01 +0200 |
---|---|---|
committer | Matthew Garrett <matthew.garrett@nebula.com> | 2014-08-16 10:23:54 +0200 |
commit | f6aac652290b31f120fc07c61331e9e0d4b4afb9 (patch) | |
tree | 32b430149d6da304e69ec9b1094f0e5f7ed4e783 /drivers/platform | |
parent | Fix log message about future removal of interface (diff) | |
download | linux-f6aac652290b31f120fc07c61331e9e0d4b4afb9.tar.xz linux-f6aac652290b31f120fc07c61331e9e0d4b4afb9.zip |
toshiba_acpi: Add extra check to backlight code
Some Toshiba models (most notably Qosmios) come with an
incomplete backlight method where the AML code doesn't
check for write or read commands and always returns
HCI_SUCCESS and the actual brightness (and in some
cases the max brightness), thus allowing the backlight
interface to be registered without write support.
This patch changes the set_lcd_brightness function,
checking the returned values for values greater than
zero to avoid registering a broken backlight interface.
Signed-off-by: Azael Avalos <coproscefalo@gmail.com>
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
Diffstat (limited to 'drivers/platform')
-rw-r--r-- | drivers/platform/x86/toshiba_acpi.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index dfd2243451ba..fa65cec42971 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -872,7 +872,9 @@ static int lcd_proc_open(struct inode *inode, struct file *file) static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value) { - u32 hci_result; + u32 in[HCI_WORDS] = { HCI_SET, HCI_LCD_BRIGHTNESS, 0, 0, 0, 0 }; + u32 out[HCI_WORDS]; + acpi_status status; if (dev->tr_backlight_supported) { bool enable = !value; @@ -883,9 +885,20 @@ static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value) value--; } - value = value << HCI_LCD_BRIGHTNESS_SHIFT; - hci_write1(dev, HCI_LCD_BRIGHTNESS, value, &hci_result); - return hci_result == HCI_SUCCESS ? 0 : -EIO; + in[2] = value << HCI_LCD_BRIGHTNESS_SHIFT; + status = hci_raw(dev, in, out); + if (ACPI_FAILURE(status) || out[0] == HCI_FAILURE) { + pr_err("ACPI call to set brightness failed"); + return -EIO; + } + /* Extra check for "incomplete" backlight method, where the AML code + * doesn't check for HCI_SET or HCI_GET and returns HCI_SUCCESS, + * the actual brightness, and in some cases the max brightness. + */ + if (out[2] > 0 || out[3] == 0xE000) + return -ENODEV; + + return out[0] == HCI_SUCCESS ? 0 : -EIO; } static int set_lcd_status(struct backlight_device *bd) |