summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Bettis <jbettis@google.com>2022-10-17 16:24:27 -0600
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-10-19 18:06:31 +0000
commite4ddf85bfc97a859913482fd6183640d69315cc6 (patch)
tree7a0e37d7f8f7a9f32f7ff07b88038bbae7566aff
parent730e8ac2ad096fc55078670fe559213524886a8d (diff)
downloadchrome-ec-e4ddf85bfc97a859913482fd6183640d69315cc6.tar.gz
zephyr: Add more qcom tests
Add new cases for booting from power button where power good times out and when the battery is too low to boot. Add new case for the suspend timing out. Add case for resume from suspend. Allow mocking system_can_boot_ap() because the alternative is to add 10 emulators to get an emulated battery level. Exclude 4 lines that are an impossible error case. BRANCH=None BUG=None TEST=twister Signed-off-by: Jeremy Bettis <jbettis@google.com> Change-Id: Icbc7ac579c8f6d2b7e5535a63eb2eca705b9bd06 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3962308 Tested-by: Jeremy Bettis <jbettis@chromium.org> Commit-Queue: Jeremy Bettis <jbettis@chromium.org> Reviewed-by: Simon Glass <sjg@chromium.org> Code-Coverage: Zoss <zoss-cl-coverage@prod.google.com>
-rw-r--r--common/system.c2
-rw-r--r--zephyr/test/qcom_power/boards/native_posix.overlay5
-rw-r--r--zephyr/test/qcom_power/prj.conf2
-rw-r--r--zephyr/test/qcom_power/src/main.c193
4 files changed, 195 insertions, 7 deletions
diff --git a/common/system.c b/common/system.c
index 047b96e799..c3a0f8ac58 100644
--- a/common/system.c
+++ b/common/system.c
@@ -1739,7 +1739,7 @@ static enum ec_status host_command_reboot(struct host_cmd_handler_args *args)
}
DECLARE_HOST_COMMAND(EC_CMD_REBOOT_EC, host_command_reboot, EC_VER_MASK(0));
-int system_can_boot_ap(void)
+test_mockable int system_can_boot_ap(void)
{
int soc = -1;
int pow = -1;
diff --git a/zephyr/test/qcom_power/boards/native_posix.overlay b/zephyr/test/qcom_power/boards/native_posix.overlay
index cda68b4b4c..820db360b7 100644
--- a/zephyr/test/qcom_power/boards/native_posix.overlay
+++ b/zephyr/test/qcom_power/boards/native_posix.overlay
@@ -113,6 +113,11 @@
flags = <GPIO_INT_EDGE_BOTH>;
handler = "power_signal_interrupt";
};
+ int_power_button: power_button {
+ irq-pin = <&gpio_ec_pwr_btn_odl>;
+ flags = <GPIO_INT_EDGE_BOTH>;
+ handler = "power_button_interrupt";
+ };
};
gpio1: gpio@101 {
diff --git a/zephyr/test/qcom_power/prj.conf b/zephyr/test/qcom_power/prj.conf
index 476a1760d2..d741784117 100644
--- a/zephyr/test/qcom_power/prj.conf
+++ b/zephyr/test/qcom_power/prj.conf
@@ -28,6 +28,7 @@ CONFIG_SHIMMED_TASKS=y
# QCom power sequencing
CONFIG_AP_ARM_QUALCOMM_SC7280=y
+CONFIG_PLATFORM_EC_CHIPSET_RESUME_INIT_HOOK=y
CONFIG_PLATFORM_EC_EXTPOWER=y
CONFIG_PLATFORM_EC_EXTPOWER_GPIO=y
CONFIG_PLATFORM_EC_HOSTCMD=y
@@ -36,4 +37,5 @@ CONFIG_PLATFORM_EC_POWERSEQ=y
CONFIG_PLATFORM_EC_POWERSEQ_HOST_SLEEP=y
CONFIG_PLATFORM_EC_POWERSEQ_SC7280=y
CONFIG_PLATFORM_EC_POWER_BUTTON=y
+CONFIG_PLATFORM_EC_POWER_SLEEP_FAILURE_DETECTION=y
CONFIG_PLATFORM_EC_SWITCHCAP_GPIO=y
diff --git a/zephyr/test/qcom_power/src/main.c b/zephyr/test/qcom_power/src/main.c
index 6f299119ff..92bbe851c9 100644
--- a/zephyr/test/qcom_power/src/main.c
+++ b/zephyr/test/qcom_power/src/main.c
@@ -10,6 +10,9 @@
#include <zephyr/drivers/gpio/gpio_emul.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/shell/shell_dummy.h>
+#include <zephyr/fff.h>
+
+#include <setjmp.h>
#include "gpio_signal.h"
#include "power/qcom.h"
@@ -19,12 +22,14 @@
#include "console.h"
#include "task.h"
#include "hooks.h"
+#include "host_command.h"
#define AP_RST_L_NODE DT_PATH(named_gpios, ap_rst_l)
#define POWER_GOOD_NODE DT_PATH(named_gpios, mb_power_good)
#define AP_SUSPEND_NODE DT_PATH(named_gpios, ap_suspend)
#define SWITCHCAP_PG_NODE DT_PATH(named_gpios, switchcap_pg_int_l)
#define PMIC_RESIN_L_NODE DT_PATH(named_gpios, pmic_resin_l)
+#define EC_PWR_BTN_ODL_NODE DT_PATH(named_gpios, ec_pwr_btn_odl)
static int chipset_reset_count;
@@ -34,6 +39,11 @@ static void do_chipset_reset(void)
}
DECLARE_HOOK(HOOK_CHIPSET_RESET, do_chipset_reset, HOOK_PRIO_DEFAULT);
+DEFINE_FFF_GLOBALS;
+
+FAKE_VALUE_FUNC(int, system_can_boot_ap);
+FAKE_VALUE_FUNC(int, battery_wait_for_stable);
+
/* Tests the chipset_ap_rst_interrupt() handler when in S3.
*
* When the system is in S3, and ap_rst_l is pulsed 1-3 times then
@@ -240,6 +250,179 @@ ZTEST(qcom_power, test_chipset_reset_success)
zassert_equal(power_get_state(), POWER_S0);
}
+/* Sent the host command, set the gpio, wait for transition to S3. */
+ZTEST(qcom_power, test_request_sleep)
+{
+ static const struct device *ap_suspend_dev =
+ DEVICE_DT_GET(DT_GPIO_CTLR(AP_SUSPEND_NODE, gpios));
+ struct ec_params_host_sleep_event params = {
+ .sleep_event = HOST_SLEEP_EVENT_S3_SUSPEND,
+ };
+ struct host_cmd_handler_args args = BUILD_HOST_COMMAND_PARAMS(
+ EC_CMD_HOST_SLEEP_EVENT, UINT8_C(0), params);
+
+ zassert_ok(host_command_process(&args));
+ zassert_ok(gpio_emul_input_set(ap_suspend_dev,
+ DT_GPIO_PIN(AP_SUSPEND_NODE, gpios), 1));
+ k_sleep(K_SECONDS(16));
+ zassert_equal(power_get_state(), POWER_S3);
+ zassert_false(host_is_event_set(EC_HOST_EVENT_HANG_DETECT));
+}
+
+/* Sent the host command, don't set the gpio, look for host event. */
+ZTEST(qcom_power, test_request_sleep_timeout)
+{
+ const char *buffer;
+ size_t buffer_size;
+ struct ec_params_host_sleep_event params = {
+ .sleep_event = HOST_SLEEP_EVENT_S3_SUSPEND,
+ };
+ struct host_cmd_handler_args args = BUILD_HOST_COMMAND_PARAMS(
+ EC_CMD_HOST_SLEEP_EVENT, UINT8_C(0), params);
+
+ shell_backend_dummy_clear_output(get_ec_shell());
+ zassert_ok(host_command_process(&args));
+ k_sleep(K_SECONDS(16));
+ zassert_equal(power_get_state(), POWER_S0);
+ buffer = shell_backend_dummy_get_output(get_ec_shell(), &buffer_size);
+ zassert_true(strstr(buffer, "Detected sleep hang!") != NULL,
+ "Invalid console output %s", buffer);
+ zassert_true(host_is_event_set(EC_HOST_EVENT_HANG_DETECT));
+}
+
+ZTEST(qcom_power, test_chipset_force_shutdown)
+{
+ chipset_force_shutdown(CHIPSET_SHUTDOWN_G3);
+ k_sleep(K_SECONDS(11));
+ zassert_equal(power_get_state(), POWER_G3);
+}
+
+ZTEST(qcom_power, test_power_button)
+{
+ static const struct device *ec_pwr_btn_odl_dev =
+ DEVICE_DT_GET(DT_GPIO_CTLR(EC_PWR_BTN_ODL_NODE, gpios));
+
+ power_set_state(POWER_G3);
+ k_sleep(K_MSEC(10));
+ zassert_equal(power_get_state(), POWER_G3);
+
+ zassert_ok(gpio_emul_input_set(ec_pwr_btn_odl_dev,
+ DT_GPIO_PIN(EC_PWR_BTN_ODL_NODE, gpios),
+ 0));
+ k_sleep(K_MSEC(100));
+ zassert_ok(gpio_emul_input_set(ec_pwr_btn_odl_dev,
+ DT_GPIO_PIN(EC_PWR_BTN_ODL_NODE, gpios),
+ 1));
+ k_sleep(K_MSEC(500));
+ zassert_equal(power_get_state(), POWER_S0);
+}
+
+ZTEST(qcom_power, test_power_button_no_power_good)
+{
+ static const struct device *ec_pwr_btn_odl_dev =
+ DEVICE_DT_GET(DT_GPIO_CTLR(EC_PWR_BTN_ODL_NODE, gpios));
+ static const struct device *power_good_dev =
+ DEVICE_DT_GET(DT_GPIO_CTLR(POWER_GOOD_NODE, gpios));
+
+ zassert_ok(gpio_emul_input_set(power_good_dev,
+ DT_GPIO_PIN(POWER_GOOD_NODE, gpios), 0));
+ power_set_state(POWER_G3);
+ k_sleep(K_MSEC(10));
+ zassert_equal(power_get_state(), POWER_G3);
+
+ zassert_ok(gpio_emul_input_set(ec_pwr_btn_odl_dev,
+ DT_GPIO_PIN(EC_PWR_BTN_ODL_NODE, gpios),
+ 0));
+ k_sleep(K_MSEC(100));
+ zassert_ok(gpio_emul_input_set(ec_pwr_btn_odl_dev,
+ DT_GPIO_PIN(EC_PWR_BTN_ODL_NODE, gpios),
+ 1));
+ k_sleep(K_MSEC(900));
+ zassert_equal(power_get_state(), POWER_S5, "power_state=%d",
+ power_get_state());
+}
+
+ZTEST(qcom_power, test_power_button_battery_low)
+{
+ static const struct device *ec_pwr_btn_odl_dev =
+ DEVICE_DT_GET(DT_GPIO_CTLR(EC_PWR_BTN_ODL_NODE, gpios));
+
+ RESET_FAKE(system_can_boot_ap);
+ system_can_boot_ap_fake.return_val = 0;
+
+ power_set_state(POWER_G3);
+ k_sleep(K_MSEC(10));
+ zassert_equal(power_get_state(), POWER_G3);
+
+ zassert_ok(gpio_emul_input_set(ec_pwr_btn_odl_dev,
+ DT_GPIO_PIN(EC_PWR_BTN_ODL_NODE, gpios),
+ 0));
+ k_sleep(K_MSEC(100));
+ zassert_ok(gpio_emul_input_set(ec_pwr_btn_odl_dev,
+ DT_GPIO_PIN(EC_PWR_BTN_ODL_NODE, gpios),
+ 1));
+ /* > CAN_BOOT_AP_CHECK_TIMEOUT + CAN_BOOT_AP_CHECK_WAIT */
+ k_sleep(K_MSEC(1800));
+ zassert_equal(power_get_state(), POWER_S5);
+}
+
+ZTEST(qcom_power, test_host_sleep_event_resume)
+{
+ static const struct device *ap_suspend_dev =
+ DEVICE_DT_GET(DT_GPIO_CTLR(AP_SUSPEND_NODE, gpios));
+ struct ec_params_host_sleep_event params = {
+ .sleep_event = HOST_SLEEP_EVENT_S3_RESUME,
+ };
+ struct host_cmd_handler_args args = BUILD_HOST_COMMAND_PARAMS(
+ EC_CMD_HOST_SLEEP_EVENT, UINT8_C(0), params);
+
+ /* Get into S3 first */
+ power_signal_enable_interrupt(GPIO_AP_SUSPEND);
+ zassert_ok(gpio_emul_input_set(ap_suspend_dev,
+ DT_GPIO_PIN(AP_SUSPEND_NODE, gpios), 1));
+ power_set_state(POWER_S3);
+ task_wake(TASK_ID_CHIPSET);
+ k_sleep(K_MSEC(10));
+ zassert_equal(power_get_state(), POWER_S3);
+
+ /* Exit suspend via gpio. */
+ zassert_ok(gpio_emul_input_set(ap_suspend_dev,
+ DT_GPIO_PIN(AP_SUSPEND_NODE, gpios), 0));
+ k_sleep(K_MSEC(100));
+ zassert_equal(power_get_state(), POWER_S0, "power_state=%d",
+ power_get_state());
+
+ /* Call host command to notify ec resume is done. */
+ zassert_ok(host_command_process(&args));
+ k_sleep(K_MSEC(10));
+ zassert_equal(power_get_state(), POWER_S0, "power_state=%d",
+ power_get_state());
+
+ /* Check that AP_SUSPEND interrupts are disabled & we are in S0. */
+ zassert_ok(gpio_emul_input_set(ap_suspend_dev,
+ DT_GPIO_PIN(AP_SUSPEND_NODE, gpios), 1));
+ k_sleep(K_MSEC(100));
+ zassert_equal(power_get_state(), POWER_S0);
+}
+
+static jmp_buf assert_jumpdata;
+static int num_asserts;
+
+void assert_post_action(const char *file, unsigned int line)
+{
+ ++num_asserts;
+ longjmp(assert_jumpdata, 1);
+}
+
+ZTEST(qcom_power, test_invalid_power_state)
+{
+ if (setjmp(assert_jumpdata) == 0) {
+ power_handle_state(POWER_S4);
+ zassert_unreachable();
+ }
+ zassert_equal(num_asserts, 1);
+}
+
void start_in_s0(void *fixture)
{
static const struct device *ap_rst_dev =
@@ -253,6 +436,9 @@ void start_in_s0(void *fixture)
static const struct device *pmic_resin_l_dev =
DEVICE_DT_GET(DT_GPIO_CTLR(PMIC_RESIN_L_NODE, gpios));
+ RESET_FAKE(system_can_boot_ap);
+ system_can_boot_ap_fake.return_val = 1;
+
power_signal_disable_interrupt(GPIO_AP_SUSPEND);
power_signal_enable_interrupt(GPIO_AP_RST_L);
zassert_ok(gpio_emul_input_set(power_good_dev,
@@ -283,16 +469,11 @@ void qcom_cleanup(void *fixture)
gpio_remove_callback(pmic_resin_l_dev, &gpio_callback);
gpio_callback.handler = NULL;
}
+ host_clear_events(EC_HOST_EVENT_MASK(EC_HOST_EVENT_HANG_DETECT));
}
ZTEST_SUITE(qcom_power, NULL, NULL, start_in_s0, qcom_cleanup, NULL);
-/* Wait until battery is totally stable */
-int battery_wait_for_stable(void)
-{
- return EC_SUCCESS;
-}
-
void test_main(void)
{
ec_app_main();