Merge git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile
[pandora-kernel.git] / drivers / acpi / button.c
index 714e957..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,23 @@ 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),
+                                       event, ++button->pushed);
                }
                break;
        default:
@@ -312,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;