Merge branch 'acpica'
[cascardo/linux.git] / drivers / acpi / button.c
index db35594..6d5d183 100644 (file)
@@ -79,11 +79,13 @@ static int acpi_button_remove(struct acpi_device *device);
 static void acpi_button_notify(struct acpi_device *device, u32 event);
 
 #ifdef CONFIG_PM_SLEEP
+static int acpi_button_suspend(struct device *dev);
 static int acpi_button_resume(struct device *dev);
 #else
+#define acpi_button_suspend NULL
 #define acpi_button_resume NULL
 #endif
-static SIMPLE_DEV_PM_OPS(acpi_button_pm, NULL, acpi_button_resume);
+static SIMPLE_DEV_PM_OPS(acpi_button_pm, acpi_button_suspend, acpi_button_resume);
 
 static struct acpi_driver acpi_button_driver = {
        .name = "button",
@@ -102,6 +104,7 @@ struct acpi_button {
        struct input_dev *input;
        char phys[32];                  /* for input device */
        unsigned long pushed;
+       bool suspended;
 };
 
 static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier);
@@ -293,15 +296,19 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
                if (button->type == ACPI_BUTTON_TYPE_LID) {
                        acpi_lid_send_state(device);
                } else {
-                       int keycode = test_bit(KEY_SLEEP, input->keybit) ?
-                                               KEY_SLEEP : KEY_POWER;
+                       int keycode;
+
+                       pm_wakeup_event(&device->dev, 0);
+                       if (button->suspended)
+                               break;
 
+                       keycode = test_bit(KEY_SLEEP, input->keybit) ?
+                                               KEY_SLEEP : KEY_POWER;
                        input_report_key(input, keycode, 1);
                        input_sync(input);
                        input_report_key(input, keycode, 0);
                        input_sync(input);
 
-                       pm_wakeup_event(&device->dev, 0);
                        acpi_bus_generate_netlink_event(
                                        device->pnp.device_class,
                                        dev_name(&device->dev),
@@ -316,11 +323,21 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
 }
 
 #ifdef CONFIG_PM_SLEEP
+static int acpi_button_suspend(struct device *dev)
+{
+       struct acpi_device *device = to_acpi_device(dev);
+       struct acpi_button *button = acpi_driver_data(device);
+
+       button->suspended = true;
+       return 0;
+}
+
 static int acpi_button_resume(struct device *dev)
 {
        struct acpi_device *device = to_acpi_device(dev);
        struct acpi_button *button = acpi_driver_data(device);
 
+       button->suspended = false;
        if (button->type == ACPI_BUTTON_TYPE_LID)
                return acpi_lid_send_state(device);
        return 0;