From 871f20c5e18e4c1bea67050b34d5653dc2eda653 Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Tue, 19 Nov 2019 15:35:53 -0800 Subject: [PATCH] firmware: qcom_scm: Add calls for watchdog tests Add call to trigger secure watchdog and spin CPU. Change-Id: I792c366528f46c87c68e73a49e276b1cd9462eaf Signed-off-by: Elliot Berman --- drivers/firmware/qcom_scm-smc.c | 28 ++++++++++++++++++++++++++++ drivers/firmware/qcom_scm.c | 12 ++++++++++++ drivers/firmware/qcom_scm.h | 3 +++ include/linux/qcom_scm.h | 4 ++++ 4 files changed, 47 insertions(+) diff --git a/drivers/firmware/qcom_scm-smc.c b/drivers/firmware/qcom_scm-smc.c index d7e55267bf1e..77f4cb28a97f 100644 --- a/drivers/firmware/qcom_scm-smc.c +++ b/drivers/firmware/qcom_scm-smc.c @@ -696,6 +696,20 @@ int __qcom_scm_sec_wdog_deactivate(struct device *dev) return qcom_scm_call(dev, &desc); } +int __qcom_scm_sec_wdog_trigger(struct device *dev) +{ + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_BOOT, + .cmd = QCOM_SCM_BOOT_SEC_WDOG_TRIGGER, + .owner = ARM_SMCCC_OWNER_SIP, + }; + int ret; + + ret = qcom_scm_call(dev, &desc); + + return ret ? : desc.res[0]; +} + int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id) { struct qcom_scm_desc desc = { @@ -714,6 +728,20 @@ int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id) return ret ? : desc.res[0]; } +int __qcom_scm_spin_cpu(struct device *dev) +{ + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_BOOT, + .cmd = QCOM_SCM_BOOT_SPIN_CPU, + .owner = ARM_SMCCC_OWNER_SIP + }; + + desc.args[0] = 0; + desc.arginfo = QCOM_SCM_ARGS(1); + + return qcom_scm_call(dev, &desc); +} + int __qcom_scm_set_dload_mode(struct device *dev, bool enable) { struct qcom_scm_desc desc = { diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index ff74247fd546..3691cbba9f3c 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -124,12 +124,24 @@ int qcom_scm_sec_wdog_deactivate(void) } EXPORT_SYMBOL(qcom_scm_sec_wdog_deactivate); +int qcom_scm_sec_wdog_trigger(void) +{ + return __qcom_scm_sec_wdog_trigger(__scm->dev); +} +EXPORT_SYMBOL(qcom_scm_sec_wdog_trigger); + int qcom_scm_set_remote_state(u32 state, u32 id) { return __qcom_scm_set_remote_state(__scm->dev, state, id); } EXPORT_SYMBOL(qcom_scm_set_remote_state); +int qcom_scm_spin_cpu(void) +{ + return __qcom_scm_spin_cpu(__scm->dev); +} +EXPORT_SYMBOL(qcom_scm_spin_cpu); + static void qcom_scm_set_download_mode(bool enable) { bool avail; diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index da0e50ca4d91..87c5520f6f06 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -11,6 +11,7 @@ #define QCOM_SCM_BOOT_SEC_WDOG_DIS 0x07 #define QCOM_SCM_BOOT_SEC_WDOG_TRIGGER 0x08 #define QCOM_SCM_BOOT_SET_REMOTE_STATE 0x0a +#define QCOM_SCM_BOOT_SPIN_CPU 0x0d #define QCOM_SCM_BOOT_SWITCH_MODE 0x0f #define QCOM_SCM_BOOT_SET_DLOAD_MODE 0x10 #define QCOM_SCM_BOOT_CONFIG_CPU_ERRATA 0x12 @@ -20,7 +21,9 @@ extern int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry, const cpumask_t *cpus); extern void __qcom_scm_cpu_power_down(struct device *dev, u32 flags); extern int __qcom_scm_sec_wdog_deactivate(struct device *dev); +extern int __qcom_scm_sec_wdog_trigger(struct device *dev); extern int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id); +extern int __qcom_scm_spin_cpu(struct device *dev); extern int __qcom_scm_set_dload_mode(struct device *dev, bool enable); extern int __qcom_scm_config_cpu_errata(struct device *dev); #define QCOM_SCM_FLUSH_FLAG_MASK 0x3 diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index 5e4daba01b9e..f12ef1372167 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -76,7 +76,9 @@ extern int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus); extern int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus); extern void qcom_scm_cpu_power_down(u32 flags); extern int qcom_scm_sec_wdog_deactivate(void); +extern int qcom_scm_sec_wdog_trigger(void); extern int qcom_scm_set_remote_state(u32 state, u32 id); +extern int qcom_scm_spin_cpu(void); extern int qcom_scm_config_cpu_errata(void); extern bool qcom_scm_pas_supported(u32 peripheral); extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, @@ -188,8 +190,10 @@ int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus) { return -ENODEV; } static inline void qcom_scm_cpu_power_down(u32 flags) {} static inline int qcom_scm_sec_wdog_deactivate(void) { return -ENODEV; } +static inline int qcom_scm_sec_wdog_trigger(void) { return -ENODEV; } static inline u32 qcom_scm_set_remote_state(u32 state, u32 id) { return -ENODEV; } +static inline int qcom_scm_spin_cpu(void) { return -ENODEV; } static inline int qcom_scm_config_cpu_errata(void) { return -ENODEV; } static inline bool qcom_scm_pas_supported(u32 peripheral) { return false; }