From a8f4d358058bb5af9281a02a7ce0eeb7709d0b89 Mon Sep 17 00:00:00 2001
From: Rahix <rahix@rahix.de>
Date: Thu, 26 Dec 2019 11:37:24 +0100
Subject: [PATCH] fix(buttons): Fix an I2C transaction without bus lock

The call to MAX77650_getDebounceStatusnEN0() in epic_buttons_read()
performs transactions on the I2C bus but is not guarded by locking the
I2C hwlock.  This leads to strange issues like USB mode deadlocking when
writing large files.

Widen the hwlock I2C section to encompass the MAX77650_getDebounceStatusnEN0()
call as well.  This fixes card10/firmware#189.

Signed-off-by: Rahix <rahix@rahix.de>
---
 epicardium/modules/buttons.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/epicardium/modules/buttons.c b/epicardium/modules/buttons.c
index fd86bbad..0caa50c3 100644
--- a/epicardium/modules/buttons.c
+++ b/epicardium/modules/buttons.c
@@ -16,17 +16,15 @@ static const uint8_t pin_mask[] = {
 uint8_t epic_buttons_read(uint8_t mask)
 {
 	uint8_t ret = 0;
-	if (portexpander_detected() && (mask & 0x7)) {
-		hwlock_acquire(HWLOCK_I2C);
 
+	hwlock_acquire(HWLOCK_I2C);
+	if (portexpander_detected() && (mask & 0x7)) {
 		/*
 		 * Not using PB_Get() here as that performs one I2C transaction
 		 * per button.
 		 */
 		uint8_t pin_status = ~portexpander_in_get(0xFF);
 
-		hwlock_release(HWLOCK_I2C);
-
 		for (uint8_t m = 1; m < 0x8; m <<= 1) {
 			if (mask & m && pin_status & pin_mask[m]) {
 				ret |= m;
@@ -38,5 +36,6 @@ uint8_t epic_buttons_read(uint8_t mask)
 		ret |= BUTTON_RESET;
 	}
 
+	hwlock_release(HWLOCK_I2C);
 	return ret;
 }
-- 
GitLab