summaryrefslogtreecommitdiff
path: root/common/tablet_mode.c
diff options
context:
space:
mode:
authorWai-Hong Tam <waihong@google.com>2021-07-21 15:11:59 -0700
committerCommit Bot <commit-bot@chromium.org>2021-07-23 22:14:04 +0000
commite8f6467d65f086a16ec33cb3cfd724086595d2f1 (patch)
treee633d245112862427696f51e11d35a90a17e0442 /common/tablet_mode.c
parent6521a7aa8d69c494e98667d1ff05ec2c2d784287 (diff)
downloadchrome-ec-e8f6467d65f086a16ec33cb3cfd724086595d2f1.tar.gz
tablet_mode: Fix the race condition of setting the tablet mode
There are 2 tablet mode triggers: * Lid: when the lid angle close to 360 degree, either detected by a GMR sensor or by the angle computed by 2 motion sensors. * Base: when the detachable base is detached. These 2 triggers set the tablet mode status, which as a boolean, resulting a race condition. This CL fixes the race condition. Each trigger updates its own bit. The final tablet mode status is the OR of all bits. BRANCH=Trogdor BUG=b:193873098 TEST=Attached the base, checked tablet_mode enabled; detached the base, checked tablet_mode disabled; flip base to 360 degree, checked tablet_mode disabled; move the base out of the lid, checked tablet_mode disabled. Change-Id: Ia9d9d2d66c194796c1039cc8b746c8d1f28a4496 Signed-off-by: Wai-Hong Tam <waihong@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3044414 Reviewed-by: Ting Shen <phoenixshen@chromium.org>
Diffstat (limited to 'common/tablet_mode.c')
-rw-r--r--common/tablet_mode.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/common/tablet_mode.c b/common/tablet_mode.c
index 68d90ae772..3a5616ec3f 100644
--- a/common/tablet_mode.c
+++ b/common/tablet_mode.c
@@ -17,10 +17,10 @@
#define CPRINTF(format, args...) cprintf(CC_MOTION_LID, format, ## args)
/*
- * Other code modules assume that notebook mode (i.e. tablet_mode = false) at
+ * Other code modules assume that notebook mode (i.e. tablet_mode = 0) at
* startup
*/
-static bool tablet_mode;
+static uint32_t tablet_mode;
/*
* Console command can force the value of tablet_mode. If tablet_mode_force is
@@ -39,7 +39,7 @@ static bool disabled;
int tablet_get_mode(void)
{
- return tablet_mode;
+ return !!tablet_mode;
}
static inline void print_tablet_mode(void)
@@ -61,13 +61,21 @@ static void notify_tablet_mode_change(void)
}
-void tablet_set_mode(int mode)
+void tablet_set_mode(int mode, uint32_t trigger)
{
+ uint32_t old_mode = tablet_mode;
+
/* If tablet_mode is forced via a console command, ignore set. */
if (tablet_mode_forced)
return;
- if (tablet_mode == !!mode)
+ if (mode)
+ tablet_mode |= trigger;
+ else
+ tablet_mode &= ~trigger;
+
+ /* Boolean comparison */
+ if (!tablet_mode == !old_mode)
return;
if (disabled) {
@@ -81,14 +89,12 @@ void tablet_set_mode(int mode)
return;
}
- tablet_mode = !!mode;
-
notify_tablet_mode_change();
}
void tablet_disable(void)
{
- tablet_mode = false;
+ tablet_mode = 0;
disabled = true;
}
@@ -131,7 +137,7 @@ static void gmr_tablet_switch_interrupt_debounce(void)
*/
if (!IS_ENABLED(CONFIG_LID_ANGLE) || gmr_sensor_at_360)
- tablet_set_mode(gmr_sensor_at_360);
+ tablet_set_mode(gmr_sensor_at_360, TABLET_TRIGGER_LID);
if (IS_ENABLED(CONFIG_LID_ANGLE_UPDATE) && gmr_sensor_at_360)
lid_angle_peripheral_enable(0);
@@ -182,10 +188,10 @@ static int command_settabletmode(int argc, char **argv)
return EC_ERROR_PARAM_COUNT;
if (argv[1][0] == 'o' && argv[1][1] == 'n') {
- tablet_mode = true;
+ tablet_mode = TABLET_TRIGGER_LID;
tablet_mode_forced = true;
} else if (argv[1][0] == 'o' && argv[1][1] == 'f') {
- tablet_mode = false;
+ tablet_mode = 0;
tablet_mode_forced = true;
} else if (argv[1][0] == 'r') {
tablet_mode_forced = false;