From 1881fbeab95a6dc6dfb235b9e5963bef402c8cd1 Mon Sep 17 00:00:00 2001 From: Tarun Saxena Date: Mon, 2 Sep 2024 17:04:32 +0530 Subject: [PATCH] qcom_stats: Add the function to get the subsystem status This change adds the function to get the subsystem status from any other Module at any point of time. Change-Id: Idb4b14d0d9d634ffb5badbeab422b8774f6e9491 Signed-off-by: Tarun Saxena --- drivers/soc/qcom/qcom_stats.c | 73 +++++++++++++++++++++++++++++++++-- include/soc/qcom/qcom_stats.h | 5 ++- 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/drivers/soc/qcom/qcom_stats.c b/drivers/soc/qcom/qcom_stats.c index 4b9bb3141f95..a0e47f4787e8 100644 --- a/drivers/soc/qcom/qcom_stats.c +++ b/drivers/soc/qcom/qcom_stats.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2011-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -93,6 +93,21 @@ #define DDR_STATS_IOCTL _IOR(SUBSYSTEM_STATS_MAGIC_NUM, 13, \ struct sleep_stats *) +enum subsystem_smem_id { + AOSD = 0, + CXSD = 1, + DDR = 2, + DDR_STATS = 3, + MPSS = 605, + ADSP, + CDSP, + SLPI, + GPU, + DISPLAY, + SLPI_ISLAND = 613, + APSS = 631, +}; + struct subsystem_data { const char *name; u32 smem_item; @@ -179,11 +194,33 @@ static bool subsystem_stats_debug_on; /* Subsystem stats before and after suspend */ static struct sleep_stats *b_subsystem_stats; static struct sleep_stats *a_subsystem_stats; +static struct sleep_stats *c_subsystem_stats; /* System sleep stats before and after suspend */ static struct sleep_stats *b_system_stats; static struct sleep_stats *a_system_stats; static DEFINE_MUTEX(sleep_stats_mutex); +static int subsystem_sleep_stats(struct sleep_stats *stats, + unsigned int pid, unsigned int idx, unsigned int index) +{ + struct sleep_stats *subsystems_data; + + if (pid == SUBSYSTEM_STATS_OTHERS_NUM) + memcpy_fromio(stats, drv->d[index].base, sizeof(*stats)); + else { + subsystems_data = qcom_smem_get(pid, idx, NULL); + if (IS_ERR(subsystems_data)) + return -ENODEV; + + stats->count = subsystems_data->count; + stats->last_entered_at = subsystems_data->last_entered_at; + stats->last_exited_at = subsystems_data->last_exited_at; + stats->accumulated = subsystems_data->accumulated; + } + + return 0; +} + static inline void get_sleep_stat_name(u32 type, char *stat_type) { int i; @@ -211,7 +248,7 @@ bool has_system_slept(void) return sleep_flag; } -EXPORT_SYMBOL(has_system_slept); +EXPORT_SYMBOL_GPL(has_system_slept); bool has_subsystem_slept(void) { @@ -232,13 +269,34 @@ bool has_subsystem_slept(void) return sleep_flag; } -EXPORT_SYMBOL(has_subsystem_slept); +EXPORT_SYMBOL_GPL(has_subsystem_slept); + +bool current_subsystem_sleep(void) +{ + int i, ret; + bool sleep_flag = true; + + for (i = 0; i < ARRAY_SIZE(subsystems); i++) { + ret = subsystem_sleep_stats(c_subsystem_stats + i, + subsystems[i].pid, subsystems[i].smem_item, i); + if (ret != -ENODEV && subsystems[i].smem_item != APSS) { + if (c_subsystem_stats[i].last_exited_at > + c_subsystem_stats[i].last_entered_at) { + pr_warn("Subsystem %s not in sleep\n", subsystems[i].name); + sleep_flag = false; + break; + } + } + } + return sleep_flag; +} +EXPORT_SYMBOL_GPL(current_subsystem_sleep); void subsystem_sleep_debug_enable(bool enable) { subsystem_stats_debug_on = enable; } -EXPORT_SYMBOL(subsystem_sleep_debug_enable); +EXPORT_SYMBOL_GPL(subsystem_sleep_debug_enable); static inline int qcom_stats_copy_to_user(unsigned long arg, struct sleep_stats *stats, unsigned long size) @@ -1075,6 +1133,13 @@ static int qcom_stats_probe(struct platform_device *pdev) goto fail; } + c_subsystem_stats = devm_kcalloc(&pdev->dev, ARRAY_SIZE(subsystems), + sizeof(struct sleep_stats), GFP_KERNEL); + if (!c_subsystem_stats) { + ret = -ENOMEM; + goto fail; + } + b_system_stats = devm_kcalloc(&pdev->dev, drv->config->num_records, sizeof(struct sleep_stats), GFP_KERNEL); if (!b_system_stats) { diff --git a/include/soc/qcom/qcom_stats.h b/include/soc/qcom/qcom_stats.h index 567ad6cbb289..cab94df4571b 100644 --- a/include/soc/qcom/qcom_stats.h +++ b/include/soc/qcom/qcom_stats.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef __QCOM_STATS_H__ @@ -33,6 +33,7 @@ int ddr_stats_get_residency(int freq_count, struct ddr_freq_residency *data); bool has_system_slept(void); bool has_subsystem_slept(void); +bool current_subsystem_sleep(void); void subsystem_sleep_debug_enable(bool enable); int cx_stats_get_ss_vote_info(int ss_count, @@ -57,6 +58,8 @@ bool has_system_slept(void) { return false; } bool has_subsystem_slept(void) { return false; } +bool current_subsystem_sleep(void) +{ return false; } void subsystem_sleep_debug_enable(bool enable) { return; }