platform/x86: intel-vbtn: Detect switch position before registering the input-device
[linux-2.6-microblaze.git] / drivers / platform / x86 / intel-vbtn.c
index 4921fc1..ef92c1c 100644 (file)
@@ -55,16 +55,35 @@ static const struct key_entry intel_vbtn_switchmap[] = {
 struct intel_vbtn_priv {
        struct key_entry keymap[KEYMAP_LEN];
        struct input_dev *input_dev;
+       bool has_buttons;
        bool has_switches;
        bool wakeup_mode;
 };
 
+static void detect_tablet_mode(struct platform_device *device)
+{
+       struct intel_vbtn_priv *priv = dev_get_drvdata(&device->dev);
+       acpi_handle handle = ACPI_HANDLE(&device->dev);
+       unsigned long long vgbs;
+       acpi_status status;
+       int m;
+
+       status = acpi_evaluate_integer(handle, "VGBS", NULL, &vgbs);
+       if (ACPI_FAILURE(status))
+               return;
+
+       m = !(vgbs & TABLET_MODE_FLAG);
+       input_report_switch(priv->input_dev, SW_TABLET_MODE, m);
+       m = (vgbs & DOCK_MODE_FLAG) ? 1 : 0;
+       input_report_switch(priv->input_dev, SW_DOCK, m);
+}
+
 static int intel_vbtn_input_setup(struct platform_device *device)
 {
        struct intel_vbtn_priv *priv = dev_get_drvdata(&device->dev);
        int ret, keymap_len = 0;
 
-       if (true) {
+       if (priv->has_buttons) {
                memcpy(&priv->keymap[keymap_len], intel_vbtn_keymap,
                       ARRAY_SIZE(intel_vbtn_keymap) *
                       sizeof(struct key_entry));
@@ -92,6 +111,9 @@ static int intel_vbtn_input_setup(struct platform_device *device)
        priv->input_dev->name = "Intel Virtual Button driver";
        priv->input_dev->id.bustype = BUS_HOST;
 
+       if (priv->has_switches)
+               detect_tablet_mode(device);
+
        return input_register_device(priv->input_dev);
 }
 
@@ -137,22 +159,12 @@ out_unknown:
        dev_dbg(&device->dev, "unknown event index 0x%x\n", event);
 }
 
-static void detect_tablet_mode(struct platform_device *device)
+static bool intel_vbtn_has_buttons(acpi_handle handle)
 {
-       struct intel_vbtn_priv *priv = dev_get_drvdata(&device->dev);
-       acpi_handle handle = ACPI_HANDLE(&device->dev);
-       unsigned long long vgbs;
        acpi_status status;
-       int m;
 
-       status = acpi_evaluate_integer(handle, "VGBS", NULL, &vgbs);
-       if (ACPI_FAILURE(status))
-               return;
-
-       m = !(vgbs & TABLET_MODE_FLAG);
-       input_report_switch(priv->input_dev, SW_TABLET_MODE, m);
-       m = (vgbs & DOCK_MODE_FLAG) ? 1 : 0;
-       input_report_switch(priv->input_dev, SW_DOCK, m);
+       status = acpi_evaluate_object(handle, "VBDL", NULL, NULL);
+       return ACPI_SUCCESS(status);
 }
 
 static bool intel_vbtn_has_switches(acpi_handle handle)
@@ -181,12 +193,15 @@ static bool intel_vbtn_has_switches(acpi_handle handle)
 static int intel_vbtn_probe(struct platform_device *device)
 {
        acpi_handle handle = ACPI_HANDLE(&device->dev);
+       bool has_buttons, has_switches;
        struct intel_vbtn_priv *priv;
        acpi_status status;
        int err;
 
-       status = acpi_evaluate_object(handle, "VBDL", NULL, NULL);
-       if (ACPI_FAILURE(status)) {
+       has_buttons = intel_vbtn_has_buttons(handle);
+       has_switches = intel_vbtn_has_switches(handle);
+
+       if (!has_buttons && !has_switches) {
                dev_warn(&device->dev, "failed to read Intel Virtual Button driver\n");
                return -ENODEV;
        }
@@ -196,7 +211,8 @@ static int intel_vbtn_probe(struct platform_device *device)
                return -ENOMEM;
        dev_set_drvdata(&device->dev, priv);
 
-       priv->has_switches = intel_vbtn_has_switches(handle);
+       priv->has_buttons = has_buttons;
+       priv->has_switches = has_switches;
 
        err = intel_vbtn_input_setup(device);
        if (err) {
@@ -204,9 +220,6 @@ static int intel_vbtn_probe(struct platform_device *device)
                return err;
        }
 
-       if (priv->has_switches)
-               detect_tablet_mode(device);
-
        status = acpi_install_notify_handler(handle,
                                             ACPI_DEVICE_NOTIFY,
                                             notify_handler,