Skip to contentSkip to conversation

soc: qcom: Introduce subsystem sleep stats driver

PATCH Superseded Maulik Shah 3 participants 4 messages Nov 6, 2019 – Feb 21, 2020

Subsystems (2)

v3 of 12 Superseded Latest is v12 →

lore
Share & tools
lore
#0 lore raw

PATCH v3 1/1 soc: qcom: Introduce subsystem sleep stats driver

Multiple subsystems like modem, spss, adsp, cdsp present on Qualcomm Technologies Inc's (QTI) SoCs maintains low power mode statistics in shared memory (SMEM). Lets add a driver to read and display this information using sysfs.

---
Changes in v3:
- Addressed comments from v2.

Changes in v2:
- Correct Makefile to use QCOM_SS_SLEEP_STATS config

---
 Documentation/ABI/testing/sysfs-power    |  10 +++
 drivers/soc/qcom/Kconfig                 |   9 ++
 drivers/soc/qcom/Makefile                |   1 +
 drivers/soc/qcom/subsystem_sleep_stats.c | 143 +++++++++++++++++++++++++++++++
 4 files changed, 163 insertions(+)
 create mode 100644 drivers/soc/qcom/subsystem_sleep_stats.c
Documentation/ABI/testing/sysfs-power +10 -0
index 6f87b9d..e095eae 100644
@@ -288,6 +288,16 @@ Description:
 		writing a "0" (default) to it disables them.  Reads from
 		this file return the current value.
 
+What:		/sys/power/subsystem_sleep/stats
+Date:		December 2017
+Contact:	Maulik Shah <[email protected]>
+Description:
+		The /sys/power/subsystem_sleep/stats file prints the subsystem
+		sleep information on Qualcomm Technologies, Inc. (QTI) SoCs.
+
+		Reading from this file will display subsystem level low power
+		mode statistics.
+
 What:		/sys/power/resume_offset
 Date:		April 2018
 Contact:	Mario Limonciello <[email protected]>
drivers/soc/qcom/Kconfig +9 -0
index 79d8265..bed0704 100644
@@ -185,6 +185,15 @@ config QCOM_SOCINFO
 	 Say yes here to support the Qualcomm socinfo driver, providing
 	 information about the SoC to user space.
 
+config QCOM_SS_SLEEP_STATS
+	tristate "Qualcomm Technologies Inc. Subsystem Sleep Stats driver"
+	depends on QCOM_SMEM
+	help
+	  Say y here to enable support for the Qualcomm Technologies Inc (QTI)
+	  SS sleep stats driver to read the sleep stats of various subsystems
+	  from SMEM. The stats are exported to sysfs. The driver also maintains
+	  application processor sleep stats.
+
 config QCOM_WCNSS_CTRL
 	tristate "Qualcomm WCNSS control driver"
 	depends on ARCH_QCOM || COMPILE_TEST
drivers/soc/qcom/Makefile +1 -0
index 9fb35c8..f3a2fb0 100644
@@ -20,6 +20,7 @@ obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o
 obj-$(CONFIG_QCOM_SMP2P)	+= smp2p.o
 obj-$(CONFIG_QCOM_SMSM)	+= smsm.o
 obj-$(CONFIG_QCOM_SOCINFO)	+= socinfo.o
+obj-$(CONFIG_QCOM_SS_SLEEP_STATS)	+= subsystem_sleep_stats.o
 obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o
 obj-$(CONFIG_QCOM_APR) += apr.o
 obj-$(CONFIG_QCOM_LLCC) += llcc-qcom.o
drivers/soc/qcom/subsystem_sleep_stats.c new file +143 -0

143 lines not on this page · raw message

Signature · 2 lines
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
#1 lore raw

Quoting Maulik Shah (2019-11-06 03:19:25)

Quoted 7 lines
Documentation/ABI/testing/sysfs-power +0 -0
index 6f87b9d..e095eae 100644
@@ -288,6 +288,16 @@ Description:
                writing a "0" (default) to it disables them.  Reads from
                this file return the current value.

Documentation/ABI/testing/sysfs-power Description: · line 299

Quoted 10 lines
Documentation/ABI/testing/sysfs-power +9 -0
 
+What:          /sys/power/subsystem_sleep/stats
+Date:          December 2017
+Contact:       Maulik Shah <[email protected]>
+Description:
+               The /sys/power/subsystem_sleep/stats file prints the subsystem
+               sleep information on Qualcomm Technologies, Inc. (QTI) SoCs.
+
+               Reading from this file will display subsystem level low power
+               mode statistics.

I still don't understand what this has to do with the kernel's power management support.

Quoted 9 lines
Documentation/ABI/testing/sysfs-power +1 -0
+
 What:          /sys/power/resume_offset
 Date:          April 2018
 Contact:       Mario Limonciello <[email protected]>
drivers/soc/qcom/Kconfig +0 -0
index 79d8265..bed0704 100644

drivers/soc/qcom/Kconfig config QCOM_SOCINFO · line 192

Quoted 8 lines
drivers/soc/qcom/Kconfig +5 -0
@@ -185,6 +185,15 @@ config QCOM_SOCINFO
         Say yes here to support the Qualcomm socinfo driver, providing
         information about the SoC to user space.
 
+config QCOM_SS_SLEEP_STATS
+       tristate "Qualcomm Technologies Inc. Subsystem Sleep Stats driver"
+       depends on QCOM_SMEM
+       help
+         Say y here to enable support for the Qualcomm Technologies Inc (QTI)

This 'Inc' is missing the full stop like in the summary above. Please be consistent.

drivers/soc/qcom/Kconfig config QCOM_SOCINFO · line 193

Quoted 1 line
drivers/soc/qcom/Kconfig +1 -0
+         SS sleep stats driver to read the sleep stats of various subsystems

what is 'SS'?

Quoted 14 lines
drivers/soc/qcom/Kconfig +3 -0
+         from SMEM. The stats are exported to sysfs. The driver also maintains
+         application processor sleep stats.
+
 config QCOM_WCNSS_CTRL
        tristate "Qualcomm WCNSS control driver"
        depends on ARCH_QCOM || COMPILE_TEST
drivers/soc/qcom/subsystem_sleep_stats.c new file +2 -0
new file mode 100644
index 00000000..724b213
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0-only
+

drivers/soc/qcom/subsystem_sleep_stats.c line 12

Quoted 10 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +10 -0
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, KBUILD_MODNAME
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/types.h>

I think we need to include linux/kernel.h for scnprintf() too.

Quoted 11 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +11 -0
+
+#include <linux/soc/qcom/smem.h>
+
+enum subsystem_item_id {
+       MODEM = 605,
+       ADSP,
+       CDSP,
+       SLPI,
+       GPU,
+       DISPLAY,
+};

drivers/soc/qcom/subsystem_sleep_stats.c line 33

Quoted 10 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +10 -0
+
+enum subsystem_pid {
+       PID_APSS = 0,
+       PID_MODEM = 1,
+       PID_ADSP = 2,
+       PID_SLPI = 3,
+       PID_CDSP = 5,
+       PID_GPU = PID_APSS,
+       PID_DISPLAY = PID_APSS,
+};

Can these just be defines? There seems to be no value in enum because we're not testing these in switch statements and they're randomly assigned values.

Quoted 12 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +12 -0
+
+struct subsystem_data {
+       char *name;
+       enum subsystem_item_id item_id;
+       enum subsystem_pid pid;
+};
+
+static const struct subsystem_data subsystems[] = {
+       { "MODEM", MODEM, PID_MODEM },
+       { "ADSP", ADSP, PID_ADSP },
+       { "CDSP", CDSP, PID_CDSP },
+       { "SLPI", SLPI, PID_SLPI },

drivers/soc/qcom/subsystem_sleep_stats.c line 55

Quoted 10 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +10 -0
+       { "GPU", GPU, PID_GPU },
+       { "DISPLAY", DISPLAY, PID_DISPLAY },
+};
+
+struct subsystem_stats {
+       uint32_t version_id;
+       uint32_t count;
+       uint64_t last_entered;
+       uint64_t last_exited;
+       uint64_t accumulated_duration;

We use u32 and u64 in kernel code. Also, is this the value in shared memory? Probably it's little endian so needs to be __le32 an __le64.

Quoted 11 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +11 -0
+};
+
+struct subsystem_stats_prv_data {
+       struct kobj_attribute ka;
+       struct kobject *kobj;
+};
+
+static struct subsystem_stats_prv_data *prvdata;
+
+static inline ssize_t subsystem_stats_print(char *prvbuf, ssize_t length,
+                                           struct subsystem_stats *record,

drivers/soc/qcom/subsystem_sleep_stats.c line 76

Quoted 10 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +10 -0
+                                           const char *name)
+{
+       return scnprintf(prvbuf, length, "%s\n\tVersion:0x%x\n"
+                       "\tSleep Count:0x%x\n"
+                       "\tSleep Last Entered At:0x%llx\n"
+                       "\tSleep Last Exited At:0x%llx\n"
+                       "\tSleep Accumulated Duration:0x%llx\n\n",
+                       name, record->version_id, record->count,
+                       record->last_entered, record->last_exited,
+                       record->accumulated_duration);

This isn't one value per file as per sysfs rules. Why can't this go to debugfs? Otherwise, it would be better to split it up into multiple files.

And it still looks like something that should be plumbed into the remote proc subsystem so we can see from userspace what remote processors are
1) present in the system and 2) how long they've been in a sleep state.

drivers/soc/qcom/subsystem_sleep_stats.c line 83

Quoted 7 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +7 -0
+}
+
+static ssize_t subsystem_stats_show(struct kobject *kobj,
+                                   struct kobj_attribute *attr, char *buf)
+{
+       ssize_t length = 0;
+       int i = 0;

Drop assignment to i here.

drivers/soc/qcom/subsystem_sleep_stats.c line 84

Quoted 1 line
drivers/soc/qcom/subsystem_sleep_stats.c new file +1 -0
+       size_t size = 0;

Why assign size to 0? It looks unused in this function besides to store the size in qcom_smem_get(). It looks like we can pass NULL for that argument if we don't care to actually look at the size of what is returned.

drivers/soc/qcom/subsystem_sleep_stats.c line 85

Quoted 1 line
drivers/soc/qcom/subsystem_sleep_stats.c new file +1 -0
+       struct subsystem_stats *record = NULL;

Please don't assign to NULL and then overwrite it without testing in between.

drivers/soc/qcom/subsystem_sleep_stats.c line 89

Quoted 4 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +4 -0
+
+       /* Read SMEM data written by other subsystems */
+       for (i = 0; i < ARRAY_SIZE(subsystems); i++) {
+               record = (struct subsystem_stats *) qcom_smem_get(

The cast is unnecessary, it returns a void * already.

Quoted 13 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +13 -0
+                         subsystems[i].pid, subsystems[i].item_id, &size);
+
+               if (!IS_ERR(record) && (PAGE_SIZE - length > 0))
+                       length += subsystem_stats_print(buf + length,
+                                                       PAGE_SIZE - length,
+                                                       record,
+                                                       subsystems[i].name);
+       }
+
+       return length;
+}
+
+static int __init subsystem_sleep_stats_init(void)

drivers/soc/qcom/subsystem_sleep_stats.c line 112

Quoted 10 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +10 -0
+{
+       struct kobject *ss_stats_kobj;
+       int ret;
+
+       prvdata = kzalloc(sizeof(*prvdata), GFP_KERNEL);
+       if (!prvdata)
+               return -ENOMEM;
+
+       ss_stats_kobj = kobject_create_and_add("subsystem_sleep",
+                                              power_kobj);

If this module is loaded on non-qcom platforms we'll create subsystem_sleep directory still. Please don't do that. If this was connected to remote proc it would be easier to avoid this problem.

Quoted 19 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +19 -0
+       if (!ss_stats_kobj)
+               return -ENOMEM;
+
+       prvdata->kobj = ss_stats_kobj;
+
+       sysfs_attr_init(&prvdata->ka.attr);
+       prvdata->ka.attr.mode = 0444;
+       prvdata->ka.attr.name = "stats";
+       prvdata->ka.show = subsystem_stats_show;
+
+       ret = sysfs_create_file(prvdata->kobj, &prvdata->ka.attr);
+       if (ret) {
+               kobject_put(prvdata->kobj);
+               kfree(prvdata);
+       }
+
+       return ret;
+}
+
#2 lore raw
Quoted 9 lines · Stephen Boyd

Quoting Maulik Shah (2019-11-06 03:19:25)

Quoted 8 lines
Documentation/ABI/testing/sysfs-power +0 -0
index 6f87b9d..e095eae 100644
@@ -288,6 +288,16 @@ Description:
                 writing a "0" (default) to it disables them.  Reads from
                 this file return the current value.
 
Quoted 11 lines

Documentation/ABI/testing/sysfs-power Description: · line 299

Quoted 9 lines
Documentation/ABI/testing/sysfs-power +9 -0
+What:          /sys/power/subsystem_sleep/stats
+Date:          December 2017
+Contact:       Maulik Shah <[email protected]>
+Description:
+               The /sys/power/subsystem_sleep/stats file prints the subsystem
+               sleep information on Qualcomm Technologies, Inc. (QTI) SoCs.
+
+               Reading from this file will display subsystem level low power
+               mode statistics.

I still don't understand what this has to do with the kernel's power management support.

Using debugfs in v2 in single stats driver.

https://lore.kernel.org/patchwork/project/lkml/list/?series=430622

Quoted 13 lines
Quoted 13 lines
Documentation/ABI/testing/sysfs-power +1 -0
+
  What:          /sys/power/resume_offset
  Date:          April 2018
  Contact:       Mario Limonciello <[email protected]>
drivers/soc/qcom/Kconfig +0 -0
index 79d8265..bed0704 100644
@@ -185,6 +185,15 @@ config QCOM_SOCINFO
          Say yes here to support the Qualcomm socinfo driver, providing
          information about the SoC to user space.
 
Quoted 7 lines

drivers/soc/qcom/Kconfig config QCOM_SOCINFO · line 192

Quoted 5 lines
drivers/soc/qcom/Kconfig +5 -0
+config QCOM_SS_SLEEP_STATS
+       tristate "Qualcomm Technologies Inc. Subsystem Sleep Stats driver"
+       depends on QCOM_SMEM
+       help
+         Say y here to enable support for the Qualcomm Technologies Inc (QTI)

This 'Inc' is missing the full stop like in the summary above. Please be consistent.

corrected.

Quoted 3 lines

drivers/soc/qcom/Kconfig config QCOM_SOCINFO · line 193

Quoted 2 lines
drivers/soc/qcom/Kconfig +1 -0
+         SS sleep stats driver to read the sleep stats of various subsystems

what is 'SS'?

corrected.

Quoted 18 lines
Quoted 18 lines
drivers/soc/qcom/Kconfig +3 -0
+         from SMEM. The stats are exported to sysfs. The driver also maintains
+         application processor sleep stats.
+
  config QCOM_WCNSS_CTRL
         tristate "Qualcomm WCNSS control driver"
         depends on ARCH_QCOM || COMPILE_TEST
drivers/soc/qcom/subsystem_sleep_stats.c new file +5 -0
new file mode 100644
index 00000000..724b213
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ */
Quoted 8 lines

drivers/soc/qcom/subsystem_sleep_stats.c line 12

Quoted 7 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +7 -0
+
+#define pr_fmt(fmt) "%s: " fmt, KBUILD_MODNAME
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/types.h>

I think we need to include linux/kernel.h for scnprintf() too.

done.

Quoted 16 lines
Quoted 16 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +16 -0
+
+#include <linux/soc/qcom/smem.h>
+
+enum subsystem_item_id {
+       MODEM = 605,
+       ADSP,
+       CDSP,
+       SLPI,
+       GPU,
+       DISPLAY,
+};
+
+enum subsystem_pid {
+       PID_APSS = 0,
+       PID_MODEM = 1,
+       PID_ADSP = 2,
Quoted 8 lines

drivers/soc/qcom/subsystem_sleep_stats.c line 33

Quoted 5 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +5 -0
+       PID_SLPI = 3,
+       PID_CDSP = 5,
+       PID_GPU = PID_APSS,
+       PID_DISPLAY = PID_APSS,
+};

Can these just be defines? There seems to be no value in enum because we're not testing these in switch statements and they're randomly assigned values.

this is inline with subsystem_item_id enum which uses 605 to 610 item ids in enum.

keeping it same for better readbility.

Quoted 17 lines
Quoted 17 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +16 -0
+
+struct subsystem_data {
+       char *name;
+       enum subsystem_item_id item_id;
+       enum subsystem_pid pid;
+};
+
+static const struct subsystem_data subsystems[] = {
+       { "MODEM", MODEM, PID_MODEM },
+       { "ADSP", ADSP, PID_ADSP },
+       { "CDSP", CDSP, PID_CDSP },
+       { "SLPI", SLPI, PID_SLPI },
+       { "GPU", GPU, PID_GPU },
+       { "DISPLAY", DISPLAY, PID_DISPLAY },
+};
+
Quoted 8 lines

drivers/soc/qcom/subsystem_sleep_stats.c line 55

Quoted 6 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +6 -0
+struct subsystem_stats {
+       uint32_t version_id;
+       uint32_t count;
+       uint64_t last_entered;
+       uint64_t last_exited;
+       uint64_t accumulated_duration;

We use u32 and u64 in kernel code. Also, is this the value in shared memory? Probably it's little endian so needs to be __le32 an __le64.

corrected.

Quoted 25 lines
Quoted 11 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +11 -0
+};
+
+struct subsystem_stats_prv_data {
+       struct kobj_attribute ka;
+       struct kobject *kobj;
+};
+
+static struct subsystem_stats_prv_data *prvdata;
+
+static inline ssize_t subsystem_stats_print(char *prvbuf, ssize_t length,
+                                           struct subsystem_stats *record,

drivers/soc/qcom/subsystem_sleep_stats.c line 76

Quoted 10 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +10 -0
+                                           const char *name)
+{
+       return scnprintf(prvbuf, length, "%s\n\tVersion:0x%x\n"
+                       "\tSleep Count:0x%x\n"
+                       "\tSleep Last Entered At:0x%llx\n"
+                       "\tSleep Last Exited At:0x%llx\n"
+                       "\tSleep Accumulated Duration:0x%llx\n\n",
+                       name, record->version_id, record->count,
+                       record->last_entered, record->last_exited,
+                       record->accumulated_duration);

This isn't one value per file as per sysfs rules. Why can't this go to debugfs? Otherwise, it would be better to split it up into multiple files.

Quoted 3 lines

And it still looks like something that should be plumbed into the remote proc subsystem so we can see from userspace what remote processors are
1) present in the system and 2) how long they've been in a sleep state.

Using debugfs.

Quoted 9 lines

drivers/soc/qcom/subsystem_sleep_stats.c line 83

Quoted 8 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +7 -0
+}
+
+static ssize_t subsystem_stats_show(struct kobject *kobj,
+                                   struct kobj_attribute *attr, char *buf)
+{
+       ssize_t length = 0;
+       int i = 0;

Drop assignment to i here.

done.

Quoted 6 lines

drivers/soc/qcom/subsystem_sleep_stats.c line 84

Quoted 2 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +1 -0
+       size_t size = 0;

Why assign size to 0? It looks unused in this function besides to store the size in qcom_smem_get(). It looks like we can pass NULL for that argument if we don't care to actually look at the size of what is returned.

done.

Quoted 3 lines

drivers/soc/qcom/subsystem_sleep_stats.c line 85

Quoted 1 line
drivers/soc/qcom/subsystem_sleep_stats.c new file +1 -0
+       struct subsystem_stats *record = NULL;

Please don't assign to NULL and then overwrite it without testing in between.

done.

Quoted 6 lines

drivers/soc/qcom/subsystem_sleep_stats.c line 89

Quoted 5 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +4 -0
+
+       /* Read SMEM data written by other subsystems */
+       for (i = 0; i < ARRAY_SIZE(subsystems); i++) {
+               record = (struct subsystem_stats *) qcom_smem_get(

The cast is unnecessary, it returns a void * already.

done.

Quoted 18 lines
Quoted 18 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +18 -0
+                         subsystems[i].pid, subsystems[i].item_id, &size);
+
+               if (!IS_ERR(record) && (PAGE_SIZE - length > 0))
+                       length += subsystem_stats_print(buf + length,
+                                                       PAGE_SIZE - length,
+                                                       record,
+                                                       subsystems[i].name);
+       }
+
+       return length;
+}
+
+static int __init subsystem_sleep_stats_init(void)
+{
+       struct kobject *ss_stats_kobj;
+       int ret;
+
+       prvdata = kzalloc(sizeof(*prvdata), GFP_KERNEL);
Quoted 8 lines

drivers/soc/qcom/subsystem_sleep_stats.c line 112

Quoted 5 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +5 -0
+       if (!prvdata)
+               return -ENOMEM;
+
+       ss_stats_kobj = kobject_create_and_add("subsystem_sleep",
+                                              power_kobj);

If this module is loaded on non-qcom platforms we'll create subsystem_sleep directory still. Please don't do that. If this was connected to remote proc it would be easier to avoid this problem.

This is clubbed in single stats driver for both sleep stats in v2 link pasted above.

Quoted 20 lines
Quoted 20 lines
drivers/soc/qcom/subsystem_sleep_stats.c new file +19 -0
+       if (!ss_stats_kobj)
+               return -ENOMEM;
+
+       prvdata->kobj = ss_stats_kobj;
+
+       sysfs_attr_init(&prvdata->ka.attr);
+       prvdata->ka.attr.mode = 0444;
+       prvdata->ka.attr.name = "stats";
+       prvdata->ka.show = subsystem_stats_show;
+
+       ret = sysfs_create_file(prvdata->kobj, &prvdata->ka.attr);
+       if (ret) {
+               kobject_put(prvdata->kobj);
+               kfree(prvdata);
+       }
+
+       return ret;
+}
+
Signature · 1 line
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
#3 lore raw
In reply to Maulik Shah
Quoted 7 lines · Maulik Shah
Documentation/ABI/testing/sysfs-power +0 -0
index 6f87b9d..e095eae 100644
@@ -288,6 +288,16 @@ Description:
 		writing a "0" (default) to it disables them.  Reads from
 		this file return the current value.

Documentation/ABI/testing/sysfs-power Description: · line 299

Quoted 10 lines
Documentation/ABI/testing/sysfs-power +9 -0
 
+What:		/sys/power/subsystem_sleep/stats
+Date:		December 2017
+Contact:	Maulik Shah <[email protected]>
+Description:
+		The /sys/power/subsystem_sleep/stats file prints the subsystem
+		sleep information on Qualcomm Technologies, Inc. (QTI) SoCs.
+
+		Reading from this file will display subsystem level low power
+		mode statistics.

sysfs files must follow the design of "one file, one value" and it must be well defined. "sleep information" does not have a defined structure.

And as Stephen has pointed out several times, /sys/power/subsystem_sleep is hardly the right place for a Qualcomm-specific entry.

[..]

Quoted 1 line
drivers/soc/qcom/subsystem_sleep_stats.c +0 -0

[..]

Quoted 29 lines
drivers/soc/qcom/subsystem_sleep_stats.c +29 -0
+static int __init subsystem_sleep_stats_init(void)
+{
+	struct kobject *ss_stats_kobj;
+	int ret;
+
+	prvdata = kzalloc(sizeof(*prvdata), GFP_KERNEL);
+	if (!prvdata)
+		return -ENOMEM;
+
+	ss_stats_kobj = kobject_create_and_add("subsystem_sleep",
+					       power_kobj);
+	if (!ss_stats_kobj)
+		return -ENOMEM;
+
+	prvdata->kobj = ss_stats_kobj;
+
+	sysfs_attr_init(&prvdata->ka.attr);
+	prvdata->ka.attr.mode = 0444;
+	prvdata->ka.attr.name = "stats";
+	prvdata->ka.show = subsystem_stats_show;
+
+	ret = sysfs_create_file(prvdata->kobj, &prvdata->ka.attr);
+	if (ret) {
+		kobject_put(prvdata->kobj);
+		kfree(prvdata);
+	}
+
+	return ret;
+}

drivers/soc/qcom/subsystem_sleep_stats.c line 140

Quoted 10 lines
drivers/soc/qcom/subsystem_sleep_stats.c +10 -0
+
+static void __exit subsystem_sleep_stats_exit(void)
+{
+	sysfs_remove_file(prvdata->kobj, &prvdata->ka.attr);
+	kobject_put(prvdata->kobj);
+	kfree(prvdata);
+}
+
+module_init(subsystem_sleep_stats_init);
+module_exit(subsystem_sleep_stats_exit);

In the event that this is compiled as a kernel module, this driver won't be automatically loaded - there's no references from other drivers nor devicetree.

But equally big of an issue is that there's a single arm64 defconfig, so this driver will be available on non-Qualcomm installations as well, so you will be creating /sys/power/subsystem_sleep/stats regardless if it ever will be possible to get any data out of this.

Regards,
Bjorn