thinkpad-acpi: document backlight level writeback at driver init
[pandora-kernel.git] / drivers / platform / x86 / thinkpad_acpi.c
index da3a70b..4bdb137 100644 (file)
@@ -516,9 +516,9 @@ static acpi_handle ec_handle;
 
 #define TPACPI_HANDLE(object, parent, paths...)                        \
        static acpi_handle  object##_handle;                    \
-       static acpi_handle *object##_parent = &parent##_handle; \
-       static char        *object##_path;                      \
-       static char        *object##_paths[] = { paths }
+       static const acpi_handle *object##_parent __initdata =  \
+                                               &parent##_handle; \
+       static char *object##_paths[] __initdata = { paths }
 
 TPACPI_HANDLE(ecrd, ec, "ECRD");       /* 570 */
 TPACPI_HANDLE(ecwr, ec, "ECWR");       /* 570 */
@@ -673,11 +673,11 @@ static int issue_thinkpad_cmos_command(int cmos_cmd)
 
 #define TPACPI_ACPIHANDLE_INIT(object) \
        drv_acpi_handle_init(#object, &object##_handle, *object##_parent, \
-               object##_paths, ARRAY_SIZE(object##_paths), &object##_path)
+               object##_paths, ARRAY_SIZE(object##_paths))
 
-static void drv_acpi_handle_init(char *name,
-                          acpi_handle *handle, acpi_handle parent,
-                          char **paths, int num_paths, char **path)
+static void __init drv_acpi_handle_init(const char *name,
+                          acpi_handle *handle, const acpi_handle parent,
+                          char **paths, const int num_paths)
 {
        int i;
        acpi_status status;
@@ -688,10 +688,9 @@ static void drv_acpi_handle_init(char *name,
        for (i = 0; i < num_paths; i++) {
                status = acpi_get_handle(parent, paths[i], handle);
                if (ACPI_SUCCESS(status)) {
-                       *path = paths[i];
                        dbg_printk(TPACPI_DBG_INIT,
                                   "Found ACPI handle %s for %s\n",
-                                  *path, name);
+                                  paths[i], name);
                        return;
                }
        }
@@ -785,8 +784,8 @@ static int __init setup_acpi_notify(struct ibm_struct *ibm)
                               "handling %s events\n", ibm->name);
                } else {
                        printk(TPACPI_ERR
-                              "acpi_install_notify_handler(%s) failed: %d\n",
-                              ibm->name, status);
+                              "acpi_install_notify_handler(%s) failed: %s\n",
+                              ibm->name, acpi_format_exception(status));
                }
                return -ENODEV;
        }
@@ -5009,11 +5008,7 @@ enum {   /* For TPACPI_LED_OLD */
 
 static enum led_access_mode led_supported;
 
-TPACPI_HANDLE(led, ec, "SLED", /* 570 */
-          "SYSL",              /* 600e/x, 770e, 770x, A21e, A2xm/p, */
-                               /* T20-22, X20-21 */
-          "LED",               /* all others */
-          );                   /* R30, R31 */
+static acpi_handle led_handle;
 
 #define TPACPI_LED_NUMLEDS 16
 static struct tpacpi_led_classdev *tpacpi_leds;
@@ -5273,6 +5268,32 @@ static const struct tpacpi_quirk led_useful_qtable[] __initconst = {
 #undef TPACPI_LEDQ_IBM
 #undef TPACPI_LEDQ_LNV
 
+static enum led_access_mode __init led_init_detect_mode(void)
+{
+       acpi_status status;
+
+       if (tpacpi_is_ibm()) {
+               /* 570 */
+               status = acpi_get_handle(ec_handle, "SLED", &led_handle);
+               if (ACPI_SUCCESS(status))
+                       return TPACPI_LED_570;
+
+               /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
+               status = acpi_get_handle(ec_handle, "SYSL", &led_handle);
+               if (ACPI_SUCCESS(status))
+                       return TPACPI_LED_OLD;
+       }
+
+       /* most others */
+       status = acpi_get_handle(ec_handle, "LED", &led_handle);
+       if (ACPI_SUCCESS(status))
+               return TPACPI_LED_NEW;
+
+       /* R30, R31, and unknown firmwares */
+       led_handle = NULL;
+       return TPACPI_LED_NONE;
+}
+
 static int __init led_init(struct ibm_init_struct *iibm)
 {
        unsigned int i;
@@ -5281,20 +5302,7 @@ static int __init led_init(struct ibm_init_struct *iibm)
 
        vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n");
 
-       TPACPI_ACPIHANDLE_INIT(led);
-
-       if (!led_handle)
-               /* led not supported on R30, R31 */
-               led_supported = TPACPI_LED_NONE;
-       else if (tpacpi_is_ibm() && strlencmp(led_path, "SLED") == 0)
-               /* 570 */
-               led_supported = TPACPI_LED_570;
-       else if (tpacpi_is_ibm() && strlencmp(led_path, "SYSL") == 0)
-               /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
-               led_supported = TPACPI_LED_OLD;
-       else
-               /* all others */
-               led_supported = TPACPI_LED_NEW;
+       led_supported = led_init_detect_mode();
 
        vdbg_printk(TPACPI_DBG_INIT, "LED commands are %s, mode %d\n",
                str_supported(led_supported), led_supported);
@@ -6389,6 +6397,10 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
                        "or not on your ThinkPad\n", TPACPI_MAIL);
        }
 
+       /* Added by mistake in early 2007.  Probably useless, but it could
+        * be working around some unknown firmware problem where the value
+        * read at startup doesn't match the real hardware state... so leave
+        * it in place just in case */
        backlight_update_status(ibm_backlight_device);
 
        vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,