motion_sense: Skip IRQ init if no sensors

If we dynamically set the motion_sensor_count to 0, skip initializing
the interrupts.

BUG=b:410646711
TEST=flash uldrenite and uldrenite-ish, check that sensors are working

Change-Id: I7e4974d98e97bad7340bdc98f6aee7a74b186601

Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/6503813
Reviewed-by: Gwendal Grignou <gwendal@chromium.org>
Commit-Queue: Yuval Peress <peress@google.com>
Tested-by: Yuval Peress <peress@google.com>
Code-Coverage: Zoss <zoss-cl-coverage@prod.google.com>
diff --git a/zephyr/shim/src/motionsense_sensors.c b/zephyr/shim/src/motionsense_sensors.c
index c85da6f..7efbfc8 100644
--- a/zephyr/shim/src/motionsense_sensors.c
+++ b/zephyr/shim/src/motionsense_sensors.c
@@ -397,10 +397,23 @@
 #define SENSOR_GPIO_ENABLE_INTERRUPT(i, id) \
 	gpio_enable_dt_interrupt(           \
 		GPIO_INT_FROM_NODE(DT_PHANDLE_BY_IDX(id, sensor_irqs, i)));
-static void sensor_enable_irqs(void){
+static void sensor_enable_irqs(void)
+{
+	if (motion_sensor_count == 0) {
+		/* Don't enable interrupts if there are no sensors. This is not
+		 * an optimal solution, it's possible that some sensors will be
+		 * disabled while others aren't. For now, we will use this
+		 * all-or-nothing approach which will be replaced eventually by
+		 * the Zephyr upstream drivers.
+		 */
+		return;
+	}
+	__ASSERT_NO_MSG(DT_PROP_LEN(SENSOR_INFO_NODE, sensor_irqs) <=
+			motion_sensor_count);
 	LISTIFY(DT_PROP_LEN(SENSOR_INFO_NODE, sensor_irqs),
 		SENSOR_GPIO_ENABLE_INTERRUPT, (), SENSOR_INFO_NODE)
-} DECLARE_HOOK(HOOK_INIT, sensor_enable_irqs, HOOK_PRIO_DEFAULT);
+}
+DECLARE_HOOK(HOOK_INIT, sensor_enable_irqs, HOOK_PRIO_DEFAULT);
 #endif
 
 /* Handle the alternative motion sensors */
diff --git a/zephyr/test/geralt/geralt.ciri.overlay b/zephyr/test/geralt/geralt.ciri.overlay
index c572d56..a21448f 100644
--- a/zephyr/test/geralt/geralt.ciri.overlay
+++ b/zephyr/test/geralt/geralt.ciri.overlay
@@ -57,6 +57,7 @@
 			active-mask = "SENSOR_ACTIVE_S0";
 			location = "MOTIONSENSE_LOC_LID";
 			drv-data = <&bmi323_data>;
+			port = <&i2c_sensor>;
 		};
 
 		lid_gyro: lid-gyro {
@@ -66,6 +67,7 @@
 			active-mask = "SENSOR_ACTIVE_S0";
 			location = "MOTIONSENSE_LOC_LID";
 			drv-data = <&bmi323_data>;
+			port = <&i2c_sensor>;
 		};
 	};
 
@@ -76,6 +78,9 @@
 
 			active-mask = "SENSOR_ACTIVE_S0";
 			location = "MOTIONSENSE_LOC_LID";
+			drv-data = <&lsm6dsm_data_accel>;
+			port = <&i2c_sensor>;
+			alternate-for = <&lid_accel>;
 		};
 
 		alt_lid_gyro: alt-lid-gyro {
@@ -84,6 +89,9 @@
 
 			active-mask = "SENSOR_ACTIVE_S0";
 			location = "MOTIONSENSE_LOC_LID";
+			drv-data = <&lsm6dsm_data_gyro>;
+			port = <&i2c_sensor>;
+			alternate-for = <&lid_gyro>;
 		};
 	};
 
diff --git a/zephyr/test/geralt/testcase.yaml b/zephyr/test/geralt/testcase.yaml
index e0f2bf3..f8638ab 100644
--- a/zephyr/test/geralt/testcase.yaml
+++ b/zephyr/test/geralt/testcase.yaml
@@ -11,5 +11,8 @@
   geralt.ciri:
     extra_configs:
     - CONFIG_TEST_CIRI=y
+    - CONFIG_PLATFORM_EC_ACCELGYRO_LSM6DSM=y
+    - CONFIG_PLATFORM_EC_ACCELGYRO_BMI3XX=y
+    - CONFIG_PLATFORM_EC_ACCELGYRO_BMI_COMM_I2C=y
     extra_dtc_overlay_files:
     - geralt.ciri.overlay
diff --git a/zephyr/test/kingler/common.dtsi b/zephyr/test/kingler/common.dtsi
index 10ab46d..f90e1b2 100644
--- a/zephyr/test/kingler/common.dtsi
+++ b/zephyr/test/kingler/common.dtsi
@@ -97,6 +97,7 @@
 
 			active-mask = "SENSOR_ACTIVE_S0_S3_S5";
 			location = "MOTIONSENSE_LOC_BASE";
+			port = <&i2c_sensor>;
 			drv-data = <&bmi160_data>;
 			default-range = <4>;
 			i2c-spi-addr-flags = "BMI160_ADDR0_FLAGS";
@@ -107,6 +108,7 @@
 
 			active-mask = "SENSOR_ACTIVE_S0_S3_S5";
 			location = "MOTIONSENSE_LOC_BASE";
+			port = <&i2c_sensor>;
 			drv-data = <&bmi160_data>;
 			default-range = <4>;
 			i2c-spi-addr-flags = "BMI160_ADDR0_FLAGS";
diff --git a/zephyr/test/kingler/kingler.ponyta.overlay b/zephyr/test/kingler/kingler.ponyta.overlay
index 3f1e054..f7002dc 100644
--- a/zephyr/test/kingler/kingler.ponyta.overlay
+++ b/zephyr/test/kingler/kingler.ponyta.overlay
@@ -17,5 +17,77 @@
 		 * its own <>_INT_EVENT.
 		 */
 		lsm6dsm-int = &base_accel;
+		bmi3xx-int = &base_accel;
+	};
+
+	motionsense-mutex {
+		compatible = "cros-ec,motionsense-mutex";
+		base_mutex: lid-mutex {
+		};
+
+		alt_base_mutex: alt-lid-mutex {
+		};
+	};
+
+	motionsense-sensor-data {
+		bmi323_data: bmi323-drv-data {
+			compatible = "cros-ec,drvdata-bmi3xx";
+			status = "okay";
+		};
+		lsm6dsm_data: lsm6dsm-drv-data {
+			compatible = "cros-ec,drvdata-lsm6dsm";
+			status = "okay";
+		};
+	};
+
+	motionsense-sensor {
+		/delete-node/ ms-bmi160-accel;
+		base_accel: base-accel {
+			compatible = "cros-ec,bmi3xx-accel";
+			status = "okay";
+
+			active-mask = "SENSOR_ACTIVE_S0_S3";
+			location = "MOTIONSENSE_LOC_LID";
+			mutex = <&base_mutex>;
+			drv-data = <&bmi323_data>;
+			port = <&i2c_sensor>;
+		};
+
+		base_gyro: base-gyro {
+			compatible = "cros-ec,bmi3xx-gyro";
+			status = "okay";
+
+			active-mask = "SENSOR_ACTIVE_S0_S3";
+			location = "MOTIONSENSE_LOC_LID";
+			mutex = <&base_mutex>;
+			drv-data = <&bmi323_data>;
+			port = <&i2c_sensor>;
+		};
+	};
+
+	motionsense-sensor-alt {
+		alt_base_accel: alt-base-accel {
+			compatible = "cros-ec,lsm6dsm-accel";
+			status = "okay";
+
+			active-mask = "SENSOR_ACTIVE_S0_S3";
+			location = "MOTIONSENSE_LOC_BASE";
+			mutex = <&alt_base_mutex>;
+			drv-data = <&lsm6dsm_data>;
+			port = <&i2c_sensor>;
+			alternate-for = <&base_accel>;
+		};
+
+		alt_base_gyro: alt-base-gyro {
+			compatible = "cros-ec,lsm6dsm-gyro";
+			status = "okay";
+
+			active-mask = "SENSOR_ACTIVE_S0_S3";
+			location = "MOTIONSENSE_LOC_BASE";
+			mutex = <&alt_base_mutex>;
+			drv-data = <&lsm6dsm_data>;
+			port = <&i2c_sensor>;
+			alternate-for = <&base_gyro>;
+		};
 	};
 };
diff --git a/zephyr/test/kingler/kingler.steelix.overlay b/zephyr/test/kingler/kingler.steelix.overlay
index 10af983..46c42f3 100644
--- a/zephyr/test/kingler/kingler.steelix.overlay
+++ b/zephyr/test/kingler/kingler.steelix.overlay
@@ -19,6 +19,7 @@
 		 * its own <>_INT_EVENT.
 		 */
 		lsm6dsm-int = &base_accel;
+		bmi3xx-int = &base_accel;
 	};
 
 	/* LEDs need to exist for testing, but aren't actually used. */
@@ -57,4 +58,75 @@
 			pwms = <&pwm4 0 PWM_HZ(100) PWM_POLARITY_INVERTED>;
 		};
 	};
+
+	motionsense-mutex {
+		compatible = "cros-ec,motionsense-mutex";
+		base_mutex: lid-mutex {
+		};
+
+		alt_base_mutex: alt-lid-mutex {
+		};
+	};
+
+	motionsense-sensor-data {
+		bmi323_data: bmi323-drv-data {
+			compatible = "cros-ec,drvdata-bmi3xx";
+			status = "okay";
+		};
+		lsm6dsm_data: lsm6dsm-drv-data {
+			compatible = "cros-ec,drvdata-lsm6dsm";
+			status = "okay";
+		};
+	};
+
+	motionsense-sensor {
+		/delete-node/ ms-bmi160-accel;
+		base_accel: base-accel {
+			compatible = "cros-ec,bmi3xx-accel";
+			status = "okay";
+
+			active-mask = "SENSOR_ACTIVE_S0_S3";
+			location = "MOTIONSENSE_LOC_LID";
+			mutex = <&base_mutex>;
+			drv-data = <&bmi323_data>;
+			port = <&i2c_sensor>;
+		};
+
+		base_gyro: base-gyro {
+			compatible = "cros-ec,bmi3xx-gyro";
+			status = "okay";
+
+			active-mask = "SENSOR_ACTIVE_S0_S3";
+			location = "MOTIONSENSE_LOC_LID";
+			mutex = <&base_mutex>;
+			drv-data = <&bmi323_data>;
+			port = <&i2c_sensor>;
+		};
+	};
+
+	motionsense-sensor-alt {
+		alt_base_accel: alt-base-accel {
+			compatible = "cros-ec,lsm6dsm-accel";
+			status = "okay";
+
+			active-mask = "SENSOR_ACTIVE_S0_S3";
+			location = "MOTIONSENSE_LOC_BASE";
+			mutex = <&alt_base_mutex>;
+			drv-data = <&lsm6dsm_data>;
+			port = <&i2c_sensor>;
+			alternate-for = <&base_accel>;
+		};
+
+		alt_base_gyro: alt-base-gyro {
+			compatible = "cros-ec,lsm6dsm-gyro";
+			status = "okay";
+
+			active-mask = "SENSOR_ACTIVE_S0_S3";
+			location = "MOTIONSENSE_LOC_BASE";
+			mutex = <&alt_base_mutex>;
+			drv-data = <&lsm6dsm_data>;
+			port = <&i2c_sensor>;
+			alternate-for = <&base_gyro>;
+		};
+	};
 };
diff --git a/zephyr/test/kingler/src/fakes.c b/zephyr/test/kingler/src/fakes.c
index 7b02435..154b369 100644
--- a/zephyr/test/kingler/src/fakes.c
+++ b/zephyr/test/kingler/src/fakes.c
@@ -38,8 +38,9 @@
      defined(CONFIG_TEST_SQUIRTLE))
 #ifndef CONFIG_TEST_SQUIRTLE
 FAKE_VOID_FUNC(x_ec_interrupt, enum gpio_signal);
-#endif
+#else
 FAKE_VOID_FUNC(motion_sensors_check_ssfc);
+#endif
 #else
 FAKE_VOID_FUNC(motion_interrupt, enum gpio_signal);
 #endif
diff --git a/zephyr/test/kingler/src/ponyta_board.c b/zephyr/test/kingler/src/ponyta_board.c
index f213316..a0d1e1c 100644
--- a/zephyr/test/kingler/src/ponyta_board.c
+++ b/zephyr/test/kingler/src/ponyta_board.c
@@ -9,6 +9,7 @@
 #include "hooks.h"
 #include "keyboard_config.h"
 #include "keyboard_scan.h"
+#include "motion_sense.h"
 #include "tablet_mode.h"
 #include "zephyr/kernel.h"
 
@@ -44,6 +45,12 @@
 
 static void reset(void)
 {
+	/* zephyr/program/corsola/ponyta/src/board.c will set the sensor count
+	 * to 0 if the CBI fw config is set to CLAMSHELL, but there's no way to
+	 * recover the previous sensor count. Before calling hook_notify, we
+	 * should reset the sensor count manually.
+	 */
+	motion_sensor_count = DT_CHILD_NUM_STATUS_OKAY(SENSOR_NODE);
 	/* Re-initialize CBI */
 	cros_cbi_ec_init();
 
diff --git a/zephyr/test/kingler/testcase.yaml b/zephyr/test/kingler/testcase.yaml
index cfc23c95..ddff516 100644
--- a/zephyr/test/kingler/testcase.yaml
+++ b/zephyr/test/kingler/testcase.yaml
@@ -44,6 +44,8 @@
     extra_configs:
     - CONFIG_TEST_STEELIX_RUSTY=y
     - CONFIG_TEST_FORM_FACTOR_CONVERTIBLE=y
+    - CONFIG_PLATFORM_EC_ACCELGYRO_BMI3XX=y
+    - CONFIG_PLATFORM_EC_ACCELGYRO_BMI_COMM_I2C=y
     - CONFIG_PLATFORM_EC_ACCELGYRO_LSM6DSM=y
     extra_dtc_overlay_files:
     - kingler.steelix.overlay
@@ -88,6 +90,9 @@
     extra_configs:
     - CONFIG_TEST_STEELIX_RUSTY=y
     - CONFIG_TEST_ALT_SENSOR_PROBE=y
+    - CONFIG_PLATFORM_EC_ACCELGYRO_BMI3XX=y
+    - CONFIG_PLATFORM_EC_ACCELGYRO_BMI_COMM_I2C=y
+    - CONFIG_PLATFORM_EC_ACCELGYRO_LSM6DSM=y
     extra_dtc_overlay_files:
     - kingler.steelix.overlay
   kingler.voltorb:
@@ -111,12 +116,18 @@
     - CONFIG_TEST_PONYTA=y
     - CONFIG_PLATFORM_EC_KEYBOARD_PROTOCOL_MKBP=y
     - CONFIG_PLATFORM_EC_MKBP_EVENT=y
+    - CONFIG_PLATFORM_EC_ACCELGYRO_BMI3XX=y
+    - CONFIG_PLATFORM_EC_ACCELGYRO_BMI160=y
+    - CONFIG_PLATFORM_EC_ACCELGYRO_BMI_COMM_I2C=y
+    - CONFIG_PLATFORM_EC_ACCELGYRO_LSM6DSM=y
     extra_dtc_overlay_files:
     - kingler.ponyta.overlay
     - boards/ponyta.dtsi
   kingler.kyogre_sensor:
     extra_configs:
     - CONFIG_TEST_KYOGRE_SENSOR_PROBE=y
+    - CONFIG_PLATFORM_EC_ACCELGYRO_BMI160=y
+    - CONFIG_PLATFORM_EC_ACCELGYRO_BMI_COMM_I2C=y
     extra_dtc_overlay_files:
     - kingler.kyogre.overlay
   kingler.kyogre_battery_detection:
diff --git a/zephyr/test/krabby/krabby.wugtrio.overlay b/zephyr/test/krabby/krabby.wugtrio.overlay
index aef0eaf..0452634 100644
--- a/zephyr/test/krabby/krabby.wugtrio.overlay
+++ b/zephyr/test/krabby/krabby.wugtrio.overlay
@@ -36,6 +36,14 @@
 	};
 
 	/delete-node/ unused-pins;
+	named-i2c-ports {
+		compatible = "named-i2c-ports";
+
+		i2c_sensor: i2c-sensor {
+			i2c-port = <&i2c0>;
+			enum-names = "I2C_PORT_SENSOR";
+		};
+	};
 
 	named-gpios {
 		/delete-node/ tablet_mode_l;
@@ -122,6 +130,15 @@
 		};
 	};
 
+	motionsense-mutex {
+		compatible = "cros-ec,motionsense-mutex";
+		lid_mutex: lid-mutex {
+		};
+
+		alt_lid_mutex: alt-lid-mutex {
+		};
+	};
+
 	motionsense-sensor {
 		/delete-node/ base-accel;
 		/delete-node/ base-gyro;
@@ -132,6 +149,9 @@
 
 			active-mask = "SENSOR_ACTIVE_S0_S3";
 			location = "MOTIONSENSE_LOC_LID";
+			mutex = <&lid_mutex>;
+			drv-data = <&bmi323_data>;
+			port = <&i2c_sensor>;
 		};
 
 		lid_gyro: lid-gyro {
@@ -140,6 +160,9 @@
 
 			active-mask = "SENSOR_ACTIVE_S0_S3";
 			location = "MOTIONSENSE_LOC_LID";
+			mutex = <&lid_mutex>;
+			drv-data = <&bmi323_data>;
+			port = <&i2c_sensor>;
 		};
 	};
 
@@ -150,6 +173,10 @@
 
 			active-mask = "SENSOR_ACTIVE_S0_S3";
 			location = "MOTIONSENSE_LOC_BASE";
+			mutex = <&alt_lid_mutex>;
+			drv-data = <&lsm6dsm_data>;
+			port = <&i2c_sensor>;
+			alternate-for = <&lid_accel>;
 		};
 
 		alt_lid_gyro: alt-lid-gyro {
@@ -158,6 +185,10 @@
 
 			active-mask = "SENSOR_ACTIVE_S0_S3";
 			location = "MOTIONSENSE_LOC_BASE";
+			mutex = <&alt_lid_mutex>;
+			drv-data = <&lsm6dsm_data>;
+			port = <&i2c_sensor>;
+			alternate-for = <&lid_gyro>;
 		};
 	};
 
diff --git a/zephyr/test/krabby/src/fwconfig_tentacruel.c b/zephyr/test/krabby/src/fwconfig_tentacruel.c
index 99221fb..b161c20 100644
--- a/zephyr/test/krabby/src/fwconfig_tentacruel.c
+++ b/zephyr/test/krabby/src/fwconfig_tentacruel.c
@@ -7,6 +7,7 @@
 #include "cros_cbi.h"
 #include "gpio_signal.h"
 #include "hooks.h"
+#include "motion_sense.h"
 #include "tablet_mode.h"
 #include "zephyr/kernel.h"
 
@@ -120,6 +121,13 @@
 	fake_base_sensor = BASE_ICM42607;
 	fake_lid_sensor = LID_LIS2DWLTR;
 
+	/* zephyr/program/corsola/tentacruel/src/sensor.c will set the sensor
+	 * count to 0 if the CBI fw config is set to CLAMSHELL, but there's no
+	 * way to recover the previous sensor count. Before calling hook_notify,
+	 * we should reset the sensor count manually.
+	 */
+	motion_sensor_count = DT_CHILD_NUM_STATUS_OKAY(SENSOR_NODE);
+
 	/* Run init hooks to initialize cbi. */
 	hook_notify(HOOK_INIT);
 
diff --git a/zephyr/test/krabby/src/fwconfig_woobat.c b/zephyr/test/krabby/src/fwconfig_woobat.c
index f664538..a285eee 100644
--- a/zephyr/test/krabby/src/fwconfig_woobat.c
+++ b/zephyr/test/krabby/src/fwconfig_woobat.c
@@ -7,6 +7,7 @@
 #include "cros_cbi.h"
 #include "gpio_signal.h"
 #include "hooks.h"
+#include "motion_sense.h"
 #include "tablet_mode.h"
 #include "zephyr/kernel.h"
 
@@ -120,6 +121,13 @@
 	fake_base_sensor = BASE_ICM42607;
 	fake_lid_sensor = LID_LIS2DWLTR;
 
+	/* zephyr/program/corsola/woobat/src/sensor.c will set the sensor count
+	 * to 0 if the CBI fw config is set to CLAMSHELL, but there's no way to
+	 * recover the previous sensor count. Before calling hook_notify, we
+	 * should reset the sensor count manually.
+	 */
+	motion_sensor_count = DT_CHILD_NUM_STATUS_OKAY(SENSOR_NODE);
+
 	/* Run init hooks to initialize cbi. */
 	hook_notify(HOOK_INIT);
 
diff --git a/zephyr/test/krabby/src/motionsense_wugtrio.c b/zephyr/test/krabby/src/motionsense_wugtrio.c
index d3e307f..0081bf9 100644
--- a/zephyr/test/krabby/src/motionsense_wugtrio.c
+++ b/zephyr/test/krabby/src/motionsense_wugtrio.c
@@ -7,6 +7,7 @@
 #include "cros_cbi.h"
 #include "gpio_signal.h"
 #include "hooks.h"
+#include "motion_sense.h"
 #include "tablet_mode.h"
 #include "zephyr/kernel.h"
 
@@ -107,6 +108,7 @@
 	const gpio_port_pins_t base_imu_pin =
 		DT_GPIO_PIN(DT_NODELABEL(base_imu_int_l), gpios);
 
+	printk("motion_sensor_count: %d\n", motion_sensor_count);
 	zassert_ok(gpio_emul_input_set(base_imu_gpio, base_imu_pin, 1), NULL);
 	k_sleep(K_MSEC(100));
 	zassert_ok(gpio_emul_input_set(base_imu_gpio, base_imu_pin, 0), NULL);
diff --git a/zephyr/test/krabby/testcase.yaml b/zephyr/test/krabby/testcase.yaml
index 2f3fcec..29e2fef 100644
--- a/zephyr/test/krabby/testcase.yaml
+++ b/zephyr/test/krabby/testcase.yaml
@@ -118,6 +118,9 @@
     - CONFIG_PLATFORM_EC_POWERSEQ=y
     - CONFIG_PLATFORM_EC_POWERSEQ_PP5000_CONTROL=n
     - CONFIG_PLATFORM_EC_TABLET_MODE=y
+    - CONFIG_PLATFORM_EC_ACCELGYRO_BMI3XX=y
+    - CONFIG_PLATFORM_EC_ACCELGYRO_BMI_COMM_I2C=y
+    - CONFIG_PLATFORM_EC_ACCELGYRO_LSM6DSM=y
     - CONFIG_SHIMMED_TASKS=y
     extra_dtc_overlay_files:
     - krabby.wugtrio.overlay
diff --git a/zephyr/test/skyrim/testcase.yaml b/zephyr/test/skyrim/testcase.yaml
index 6c6dcc7..b689273 100644
--- a/zephyr/test/skyrim/testcase.yaml
+++ b/zephyr/test/skyrim/testcase.yaml
@@ -73,6 +73,8 @@
     extra_configs:
     - CONFIG_TEST_BOARD_CRYSTALDRIFT=y
     - CONFIG_TEST_BOARD_FORM_FACTOR=y
+    - CONFIG_PLATFORM_EC_ACCELGYRO_BMI3XX=y
+    - CONFIG_PLATFORM_EC_ACCELGYRO_BMI_COMM_I2C=y
     extra_dtc_overlay_files:
     - ./boards/skyrim/skyrim.dtsi
 
@@ -134,6 +136,8 @@
     extra_configs:
     - CONFIG_TEST_BOARD_SKYRIM=y
     - CONFIG_TEST_BOARD_FORM_FACTOR=y
+    - CONFIG_PLATFORM_EC_ACCELGYRO_BMI3XX=y
+    - CONFIG_PLATFORM_EC_ACCELGYRO_BMI_COMM_I2C=y
     extra_dtc_overlay_files:
     - ./boards/skyrim/skyrim.dtsi