With the addition of dynamically loadable buffer drivers, there needs
to be a way of knowing the currently available ones without having to
scan the list of loaded modules or trial and error.

Add a sysfs file that lists all the currently available "modes", listing
both the MSC hardware operating modes and loaded buffer drivers.

Signed-off-by: Alexander Shishkin <alexander.shish...@linux.intel.com>
---
 .../testing/sysfs-bus-intel_th-devices-msc    |  8 +++++++
 drivers/hwtracing/intel_th/msu.c              | 24 +++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-intel_th-devices-msc 
b/Documentation/ABI/testing/sysfs-bus-intel_th-devices-msc
index 7da00601afdc..a6dec69cf92e 100644
--- a/Documentation/ABI/testing/sysfs-bus-intel_th-devices-msc
+++ b/Documentation/ABI/testing/sysfs-bus-intel_th-devices-msc
@@ -40,3 +40,11 @@ Description: (RW) Trigger window switch for the MSC's 
buffer, in
                triggering a window switch for the buffer. Returns an error in 
any
                other operating mode or attempts to write something other than 
"1".
 
+What:          /sys/bus/intel_th/devices/<intel_th_id>-msc<msc-id>/modes
+Date:          May 2019
+KernelVersion: 5.2
+Contact:       Alexander Shishkin <alexander.shish...@linux.intel.com>
+Description:   (RO) Lists all possible modes, that is, values that can be
+               written to the "mode" file described above. This includes
+               the hardware operating modes ("single", "multi", etc) and
+               all the buffer drivers that are currently loaded.
diff --git a/drivers/hwtracing/intel_th/msu.c b/drivers/hwtracing/intel_th/msu.c
index 04bfe4dbf325..71529cd18d93 100644
--- a/drivers/hwtracing/intel_th/msu.c
+++ b/drivers/hwtracing/intel_th/msu.c
@@ -1866,6 +1866,29 @@ mode_store(struct device *dev, struct device_attribute 
*attr, const char *buf,
 
 static DEVICE_ATTR_RW(mode);
 
+static ssize_t
+modes_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct msu_buffer *mbuf;
+       ssize_t ret = 0;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(msc_mode); i++)
+               ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%s\n",
+                                msc_mode[i]);
+
+       mutex_lock(&msu_buffer_mutex);
+       list_for_each_entry(mbuf, &msu_buffer_list, entry) {
+               ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%s\n",
+                                mbuf->bdrv->name);
+       }
+       mutex_unlock(&msu_buffer_mutex);
+
+       return ret;
+}
+
+static DEVICE_ATTR_RO(modes);
+
 static ssize_t
 nr_pages_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -1999,6 +2022,7 @@ static DEVICE_ATTR_WO(win_switch);
 static struct attribute *msc_output_attrs[] = {
        &dev_attr_wrap.attr,
        &dev_attr_mode.attr,
+       &dev_attr_modes.attr,
        &dev_attr_nr_pages.attr,
        &dev_attr_win_switch.attr,
        NULL,
-- 
2.20.1

Reply via email to