From: Mattia Dongili <malattia@linux.it>
Date: Tue, 29 Oct 2013 23:07:36 +0000 (+0900)
Subject: sony-laptop: warn on multiple KBD backlight handles
X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=1d885f4257165563342acc6bc473b67d9b36a742;p=GitHub%2Fmoto-9609%2Fandroid_kernel_motorola_exynos9610.git

sony-laptop: warn on multiple KBD backlight handles

Some BIOS versions/Vaio models apparently ship with two nearly identical
functions to handle backlight related controls.
The only difference seems to be:
        If (LEqual (BUF1, 0x40))
        {
            Store (0x40, P80H)
            Store (BUF2, Local0)
-           And (Local0, One, Local0)
+           And (Local0, 0x03, Local0)
            Store (Local0, ^^H_EC.KLPC)
        }

Avoid erroring out on initialization and messing things up on cleanup
for now since we never call into these methods with anything different
than 1 or 0.
This issue was found on a Sony VPCSE1V9E/BIOS R2087H4.

Cc: Marco Krüger <krgsch@gmail.com>
Signed-off-by: Mattia Dongili <malattia@linux.it>
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
---

diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index 47caab0ea7a1..03f02cc476e5 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -145,7 +145,8 @@ static void sony_nc_thermal_resume(void);
 #endif
 static int sony_nc_kbd_backlight_setup(struct platform_device *pd,
 		unsigned int handle);
-static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd);
+static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd,
+		unsigned int handle);
 
 static int sony_nc_battery_care_setup(struct platform_device *pd,
 		unsigned int handle);
@@ -1444,7 +1445,7 @@ static void sony_nc_function_cleanup(struct platform_device *pd)
 		case 0x014b:
 		case 0x014c:
 		case 0x0163:
-			sony_nc_kbd_backlight_cleanup(pd);
+			sony_nc_kbd_backlight_cleanup(pd, handle);
 			break;
 		default:
 			continue;
@@ -1822,6 +1823,12 @@ static int sony_nc_kbd_backlight_setup(struct platform_device *pd,
 	int result;
 	int ret = 0;
 
+	if (kbdbl_ctl) {
+		pr_warn("handle 0x%.4x: keyboard backlight setup already done for 0x%.4x\n",
+				handle, kbdbl_ctl->handle);
+		return -EBUSY;
+	}
+
 	/* verify the kbd backlight presence, these handles are not used for
 	 * keyboard backlight only
 	 */
@@ -1881,9 +1888,10 @@ outkzalloc:
 	return ret;
 }
 
-static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd)
+static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd,
+		unsigned int handle)
 {
-	if (kbdbl_ctl) {
+	if (kbdbl_ctl && handle == kbdbl_ctl->handle) {
 		device_remove_file(&pd->dev, &kbdbl_ctl->mode_attr);
 		device_remove_file(&pd->dev, &kbdbl_ctl->timeout_attr);
 		kfree(kbdbl_ctl);