Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/olpc/xo1/sci: Produce wakeup events for buttons and switches

Produce wakeup events for the XO-1's power button, lid switch
and ebook switch, taking care to only produce events when the
states have changed.

Signed-off-by: Daniel Drake <dsd@laptop.org>
Cc: dilinger@queued.net
Cc: pgf@laptop.org
Link: http://lkml.kernel.org/r/20120412171824.D14C49D401E@zog.reactivated.net
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Daniel Drake and committed by
Ingo Molnar
d2aa3741 83125a3a

+21 -5
+21 -5
arch/x86/platform/olpc/olpc-xo1-sci.c
··· 18 18 #include <linux/interrupt.h> 19 19 #include <linux/platform_device.h> 20 20 #include <linux/pm.h> 21 + #include <linux/pm_wakeup.h> 21 22 #include <linux/mfd/core.h> 22 23 #include <linux/power_supply.h> 23 24 #include <linux/suspend.h> ··· 84 83 return; 85 84 } 86 85 86 + if (!!test_bit(SW_TABLET_MODE, ebook_switch_idev->sw) == state) 87 + return; /* Nothing new to report. */ 88 + 87 89 input_report_switch(ebook_switch_idev, SW_TABLET_MODE, state); 88 90 input_sync(ebook_switch_idev); 91 + pm_wakeup_event(&ebook_switch_idev->dev, 0); 89 92 } 90 93 91 94 static void flip_lid_inverter(void) ··· 128 123 /* Report current lid switch state through input layer */ 129 124 static void send_lid_state(void) 130 125 { 126 + if (!!test_bit(SW_LID, lid_switch_idev->sw) == !lid_open) 127 + return; /* Nothing new to report. */ 128 + 131 129 input_report_switch(lid_switch_idev, SW_LID, !lid_open); 132 130 input_sync(lid_switch_idev); 131 + pm_wakeup_event(&lid_switch_idev->dev, 0); 133 132 } 134 133 135 134 static ssize_t lid_wake_mode_show(struct device *dev, ··· 222 213 223 214 dev_dbg(&pdev->dev, "sts %x gpe %x\n", sts, gpe); 224 215 225 - if (sts & CS5536_PWRBTN_FLAG && !(sts & CS5536_WAK_FLAG)) { 226 - input_report_key(power_button_idev, KEY_POWER, 1); 227 - input_sync(power_button_idev); 228 - input_report_key(power_button_idev, KEY_POWER, 0); 229 - input_sync(power_button_idev); 216 + if (sts & CS5536_PWRBTN_FLAG) { 217 + if (!(sts & CS5536_WAK_FLAG)) { 218 + /* Only report power button input when it was pressed 219 + * during regular operation (as opposed to when it 220 + * was used to wake the system). */ 221 + input_report_key(power_button_idev, KEY_POWER, 1); 222 + input_sync(power_button_idev); 223 + input_report_key(power_button_idev, KEY_POWER, 0); 224 + input_sync(power_button_idev); 225 + } 226 + /* Report the wakeup event in all cases. */ 227 + pm_wakeup_event(&power_button_idev->dev, 0); 230 228 } 231 229 232 230 if (gpe & CS5536_GPIOM7_PME_FLAG) { /* EC GPIO */