All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] hwmon: Add amd_energy driver to report energy counters
@ 2020-04-09 15:39 Naveen Krishna Chatradhi
  2020-04-09 15:39 ` [PATCH 2/2] hwmon: (amd_energy) Add documentation Naveen Krishna Chatradhi
  2020-04-10 15:57 ` [PATCH 1/2] hwmon: Add amd_energy driver to report energy counters Guenter Roeck
  0 siblings, 2 replies; 13+ messages in thread
From: Naveen Krishna Chatradhi @ 2020-04-09 15:39 UTC (permalink / raw)
  To: linux-hwmon; +Cc: naveenkrishna.ch, Naveen Krishna Chatradhi, Guenter Roeck

This patch adds hwmon based amd_energy driver support for
family 17h processors from AMD.

The driver provides following interface to the userspace
1. Reports the per core and per socket energy consumption
   via sysfs entries created per core and per socket respectively.
    * per core energy consumed via "core_energy%d_input"
    * package/socket energy consumed via "sock_energy%d_input".
2. Uses topology_max_packages() to get number of sockets.
3. Uses num_present_cpus() to get the number of CPUs.
4. Reports the energy units via energy_unit sysfs entry

Cc: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Naveen Krishna Chatradhi <nchatrad@amd.com>
---
 drivers/hwmon/Kconfig      |  10 ++
 drivers/hwmon/Makefile     |   1 +
 drivers/hwmon/amd_energy.c | 273 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 284 insertions(+)
 create mode 100644 drivers/hwmon/amd_energy.c

diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 05a30832c6ba..d83f1403b429 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -324,6 +324,16 @@ config SENSORS_FAM15H_POWER
 	  This driver can also be built as a module. If so, the module
 	  will be called fam15h_power.
 
+config SENSORS_AMD_ENERGY
+	tristate "AMD RAPL MSR based Energy driver"
+	depends on X86
+	help
+	  If you say yes here you get support for core and package energy
+	  sensors, based on RAPL MSR for AMD family 17h and above CPUs.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called as amd_energy.
+
 config SENSORS_APPLESMC
 	tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)"
 	depends on INPUT && X86
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index b0b9c8e57176..318f89dc7133 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_SENSORS_ADT7411)	+= adt7411.o
 obj-$(CONFIG_SENSORS_ADT7462)	+= adt7462.o
 obj-$(CONFIG_SENSORS_ADT7470)	+= adt7470.o
 obj-$(CONFIG_SENSORS_ADT7475)	+= adt7475.o
+obj-$(CONFIG_SENSORS_AMD_ENERGY) += amd_energy.o
 obj-$(CONFIG_SENSORS_APPLESMC)	+= applesmc.o
 obj-$(CONFIG_SENSORS_ARM_SCMI)	+= scmi-hwmon.o
 obj-$(CONFIG_SENSORS_ARM_SCPI)	+= scpi-hwmon.o
diff --git a/drivers/hwmon/amd_energy.c b/drivers/hwmon/amd_energy.c
new file mode 100644
index 000000000000..ddb7073ae39b
--- /dev/null
+++ b/drivers/hwmon/amd_energy.c
@@ -0,0 +1,273 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+/*
+ * Copyright (C) 2019 Advanced Micro Devices, Inc.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/sysfs.h>
+#include <linux/cpu.h>
+#include <linux/list.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/processor.h>
+#include <linux/platform_device.h>
+#include <linux/cpumask.h>
+
+#include <asm/cpu_device_id.h>
+
+#define DRVNAME	"amd_energy"
+
+#define ENERGY_PWR_UNIT_MSR	0xC0010299
+#define ENERGY_CORE_MSR	0xC001029A
+#define ENERGY_PCK_MSR		0xC001029B
+
+#define AMD_TIME_UNIT_MASK	0xF0000
+#define AMD_ENERGY_UNIT_MASK	0x01F00
+#define AMD_POWER_UNIT_MASK	0x0000F
+
+#define ENERGY_STATUS_MASK	0xffffffff
+
+#define AMD_FAM_17		0x17 /* ZP, SSP */
+
+/* Useful macros */
+#define AMD_CPU_FAM_ANY(_family, _model)	\
+{						\
+	.vendor		= X86_VENDOR_AMD,	\
+	.family		= _family,		\
+	.model		= _model,		\
+	.feature	= X86_FEATURE_ANY,	\
+}
+
+#define AMD_CPU_FAM(_model)			\
+	AMD_CPU_FAM_ANY(AMD_FAM_##_model, X86_MODEL_ANY)
+
+static struct device_attribute units_attr;
+
+struct sensor_data {
+	unsigned int scale;
+	union {
+		unsigned int cpu_nr;
+		unsigned int sock_nr;
+	};
+	struct device_attribute dev_attr_input;
+	char input[32];
+};
+
+struct amd_energy_sensors {
+	struct sensor_data *data;
+	struct attribute **attrs;
+	struct attribute_group group;
+	const struct attribute_group *groups[1];
+};
+
+static ssize_t amd_units_u64_show(struct device *dev,
+	struct device_attribute *dev_attr, char *buffer)
+{
+	uint64_t rapl_units;
+	uint64_t energy_unit;
+	int ret = 0;
+
+	ret = rdmsrl_safe(ENERGY_PWR_UNIT_MSR, &rapl_units);
+	if (ret)
+		return -EAGAIN;
+
+	energy_unit = (rapl_units & AMD_ENERGY_UNIT_MASK) >> 8;
+
+	return snprintf(buffer, 24, "%llu\n", energy_unit);
+}
+
+static ssize_t amd_core_u64_show(struct device *dev,
+		struct device_attribute *dev_attr, char *buffer)
+{
+	unsigned long long value;
+	struct sensor_data *sensor;
+	int ret = 0;
+
+	sensor = container_of(dev_attr, struct sensor_data, dev_attr_input);
+	ret = rdmsrl_safe_on_cpu(sensor->cpu_nr, ENERGY_CORE_MSR, &value);
+	if (ret)
+		return -EAGAIN;
+
+	return snprintf(buffer, 24, "%llu\n", value);
+}
+
+static ssize_t amd_sock_u64_show(struct device *dev,
+		struct device_attribute *dev_attr, char *buffer)
+{
+	unsigned long long value;
+	struct sensor_data *sensor;
+	int ret = 0;
+	int cpu, cpu_nr;
+
+	sensor = container_of(dev_attr, struct sensor_data, dev_attr_input);
+
+	for_each_possible_cpu(cpu) {
+		struct cpuinfo_x86 *c = &cpu_data(cpu);
+
+		if (c->initialized && c->logical_die_id == sensor->sock_nr) {
+			cpu_nr = cpu;
+			break;
+		}
+		cpu_nr = 0;
+	}
+
+	ret = rdmsrl_safe_on_cpu(cpu_nr, ENERGY_PCK_MSR, &value);
+	if (ret)
+		return -EAGAIN;
+
+	return snprintf(buffer, 24, "%llu\n", value);
+}
+
+static int amd_energy_probe(struct platform_device *pdev)
+{
+	struct amd_energy_sensors *amd_sensors;
+	struct device *hwdev, *dev = &pdev->dev;
+	int nr_cpus, nr_socks, idx = 0;
+
+	nr_cpus = num_present_cpus();
+	nr_socks = topology_max_packages();
+
+	amd_sensors = devm_kzalloc(dev, sizeof(*amd_sensors), GFP_KERNEL);
+	if (!amd_sensors)
+		return -ENOMEM;
+
+	amd_sensors->data = devm_kcalloc(dev, nr_cpus + nr_socks,
+				sizeof(*amd_sensors->data), GFP_KERNEL);
+	if (!amd_sensors->data)
+		return -ENOMEM;
+
+	amd_sensors->attrs = devm_kcalloc(dev, nr_cpus + nr_socks,
+				sizeof(*amd_sensors->attrs), GFP_KERNEL);
+	if (!amd_sensors->attrs)
+		return -ENOMEM;
+
+	/* populate attributes for number of cpus. */
+	for (idx = 0; idx < ; idx++) {
+		struct sensor_data *sensor = &amd_sensors->data[idx];
+
+		snprintf(sensor->input, sizeof(sensor->input),
+				"core_energy%d_input", idx);
+
+		sensor->dev_attr_input.attr.mode = 0444;
+		sensor->dev_attr_input.attr.name = sensor->input;
+		sensor->dev_attr_input.show = amd_core_u64_show;
+
+		sensor->cpu_nr = idx;
+		amd_sensors->attrs[idx] = &sensor->dev_attr_input.attr;
+
+		sysfs_attr_init(amd_sensors->attrs[idx]);
+	}
+
+	/* populate attributes for number of sockets. */
+	for (idx = 0; idx < nr_socks; idx++) {
+		struct sensor_data *sensor =
+			&amd_sensors->data[nr_cpus + idx];
+
+		snprintf(sensor->input,
+			sizeof(sensor->input), "sock_energy%d_input", idx);
+
+		sensor->dev_attr_input.attr.mode = 0444;
+		sensor->dev_attr_input.attr.name = sensor->input;
+		sensor->dev_attr_input.show = amd_sock_u64_show;
+
+		sensor->sock_nr = idx;
+		amd_sensors->attrs[nr_cpus + idx] =
+			&sensor->dev_attr_input.attr;
+
+		sysfs_attr_init(amd_sensors->attrs[nr_cpus + idx]);
+	}
+
+	amd_sensors->group.attrs = amd_sensors->attrs;
+	amd_sensors->groups[0] = &amd_sensors->group;
+
+	platform_set_drvdata(pdev, amd_sensors);
+
+	hwdev = devm_hwmon_device_register_with_groups(dev,
+			"amd_energy", amd_sensors, amd_sensors->groups);
+	if (!hwdev)
+		return PTR_ERR_OR_ZERO(hwdev);
+
+	/* populate attributes for energy units */
+	units_attr.attr.name = "energy_units";
+	units_attr.attr.mode = 0444;
+	units_attr.show = amd_units_u64_show;
+
+	return sysfs_create_file(&hwdev->kobj, &units_attr.attr);
+}
+
+static int amd_energy_remove(struct platform_device *pdev)
+{
+	sysfs_remove_file(&pdev->dev.kobj, &units_attr.attr);
+	return 0;
+}
+
+static const struct platform_device_id amd_energy_ids[] = {
+	{ .name = DRVNAME, },
+	{}
+};
+MODULE_DEVICE_TABLE(platform, amd_energy_ids);
+
+static struct platform_driver amd_energy_driver = {
+	.probe = amd_energy_probe,
+	.remove	= amd_energy_remove,
+	.id_table = amd_energy_ids,
+	.driver = {
+		.name = DRVNAME,
+	},
+};
+
+static struct platform_device *amd_energy_platdev;
+
+static const struct x86_cpu_id cpu_ids[] __initconst = {
+	AMD_CPU_FAM(17),
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, cpu_ids);
+
+static int __init amd_energy_init(void)
+{
+	const struct x86_cpu_id *id;
+	int ret;
+
+	id = x86_match_cpu(cpu_ids);
+	if (!id) {
+		pr_err("driver does not support CPU family %d model %d\n",
+			boot_cpu_data.x86, boot_cpu_data.x86_model);
+
+		return -ENODEV;
+	}
+
+	ret = platform_driver_register(&amd_energy_driver);
+	if (ret < 0)
+		return ret;
+
+	amd_energy_platdev = platform_device_alloc(DRVNAME, 0);
+	if (!amd_energy_platdev)
+		return -ENOMEM;
+
+	ret = platform_device_add(amd_energy_platdev);
+	if (ret) {
+		platform_device_unregister(amd_energy_platdev);
+		return ret;
+	}
+
+	return ret;
+}
+
+static void __exit amd_energy_exit(void)
+{
+	platform_device_unregister(amd_energy_platdev);
+	platform_driver_unregister(&amd_energy_driver);
+}
+
+module_init(amd_energy_init);
+module_exit(amd_energy_exit);
+
+MODULE_DESCRIPTION("Driver for AMD Energy reporting from RAPL MSR via HWMON interface");
+MODULE_AUTHOR("Naveen Krishna Chatradhi <nchatrad@amd.com>");
+MODULE_LICENSE("GPL");
-- 
2.16.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread
* [PATCH 1/2] hwmon: Add amd_energy driver to report energy counters
@ 2020-04-17 19:02 Naveen Krishna Chatradhi
  0 siblings, 0 replies; 13+ messages in thread
From: Naveen Krishna Chatradhi @ 2020-04-17 19:02 UTC (permalink / raw)
  To: linux-hwmon; +Cc: Naveen Krishna Chatradhi, Guenter Roeck

This patch adds hwmon based amd_energy driver support for
family 17h processors from AMD.

The driver provides following interface to the userspace
1. Reports the per core consumption
	* file: "energy%d_input", label: "Ecore%03d"
2. Reports per socket energy consumption
	* file: "energy%d_input", label: "Esocket%d"
3. Reports scaled energy value in Joules.

Cc: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Naveen Krishna Chatradhi <nchatrad@amd.com>
---
Changes in V2:
Addressed comments from Guenter. Major changes include 
1. Use chip_info instead of groups
2. Use standard file naming conventions
3. Report scaled values 

 drivers/hwmon/Kconfig      |  10 ++
 drivers/hwmon/Makefile     |   1 +
 drivers/hwmon/amd_energy.c | 251 +++++++++++++++++++++++++++++++++++++
 3 files changed, 262 insertions(+)
 create mode 100644 drivers/hwmon/amd_energy.c

diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 05a30832c6ba..d83f1403b429 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -324,6 +324,16 @@ config SENSORS_FAM15H_POWER
 	  This driver can also be built as a module. If so, the module
 	  will be called fam15h_power.
 
+config SENSORS_AMD_ENERGY
+	tristate "AMD RAPL MSR based Energy driver"
+	depends on X86
+	help
+	  If you say yes here you get support for core and package energy
+	  sensors, based on RAPL MSR for AMD family 17h and above CPUs.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called as amd_energy.
+
 config SENSORS_APPLESMC
 	tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)"
 	depends on INPUT && X86
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index b0b9c8e57176..318f89dc7133 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_SENSORS_ADT7411)	+= adt7411.o
 obj-$(CONFIG_SENSORS_ADT7462)	+= adt7462.o
 obj-$(CONFIG_SENSORS_ADT7470)	+= adt7470.o
 obj-$(CONFIG_SENSORS_ADT7475)	+= adt7475.o
+obj-$(CONFIG_SENSORS_AMD_ENERGY) += amd_energy.o
 obj-$(CONFIG_SENSORS_APPLESMC)	+= applesmc.o
 obj-$(CONFIG_SENSORS_ARM_SCMI)	+= scmi-hwmon.o
 obj-$(CONFIG_SENSORS_ARM_SCPI)	+= scpi-hwmon.o
diff --git a/drivers/hwmon/amd_energy.c b/drivers/hwmon/amd_energy.c
new file mode 100644
index 000000000000..7127f1f5f5ee
--- /dev/null
+++ b/drivers/hwmon/amd_energy.c
@@ -0,0 +1,251 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+/*
+ * Copyright (C) 2020 Advanced Micro Devices, Inc.
+ */
+
+#include <asm/cpu_device_id.h>
+
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+#include <linux/device.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/processor.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/types.h>
+
+#define DRVNAME			"amd_energy"
+
+#define ENERGY_PWR_UNIT_MSR	0xC0010299
+#define ENERGY_CORE_MSR		0xC001029A
+#define ENERGY_PKG_MSR		0xC001029B
+
+#define AMD_TIME_UNIT_MASK	0xF0000
+#define AMD_ENERGY_UNIT_MASK	0x01F00
+#define AMD_POWER_UNIT_MASK	0x0000F
+
+#define ENERGY_STATUS_MASK	0xffffffff
+
+#define AMD_FAM_17		0x17 /* ZP, SSP */
+
+/* Useful macros */
+#define AMD_CPU_FAM_ANY(_family, _model)	\
+{						\
+	.vendor		= X86_VENDOR_AMD,	\
+	.family		= _family,		\
+	.model		= _model,		\
+	.feature	= X86_FEATURE_ANY,	\
+}
+
+#define AMD_CPU_FAM(_model)			\
+	AMD_CPU_FAM_ANY(AMD_FAM_##_model, X86_MODEL_ANY)
+
+struct amd_energy_data {
+	struct hwmon_channel_info energy_info;
+	const struct hwmon_channel_info *info[2];
+	struct hwmon_chip_info chip;
+};
+
+static int nr_cpus, nr_socks;
+static uint64_t energy_units;
+
+static int amd_energy_read_labels(struct device *dev,
+			       enum hwmon_sensor_types type,
+			       u32 attr, int channel, const char **str)
+{
+	char *buf = devm_kcalloc(dev, 10, sizeof(char), GFP_KERNEL);
+
+	if (channel >= nr_cpus)
+		scnprintf(buf, 9, "Esocket%u", channel - nr_cpus);
+	else
+		scnprintf(buf, 9, "Ecore%03u", channel);
+
+	*str = buf;
+
+	return 0;
+}
+
+static int get_energy_units(void)
+{
+	uint64_t rapl_units;
+	int ret;
+
+	ret = rdmsrl_safe(ENERGY_PWR_UNIT_MSR, &rapl_units);
+	if (ret)
+		return -EAGAIN;
+
+	energy_units = (rapl_units & AMD_ENERGY_UNIT_MASK) >> 8;
+	return 0;
+}
+
+static int amd_energy_read(struct device *dev,
+			enum hwmon_sensor_types type,
+			u32 attr, int channel, long *val)
+{
+	uint64_t value;
+	int cpu = 0, ret;
+	u32 reg;
+
+	if (channel >= nr_cpus) {
+		reg = ENERGY_PKG_MSR;
+		cpu = cpumask_first_and(cpu_online_mask,
+				cpumask_of_node(channel - nr_cpus));
+	} else {
+		reg = ENERGY_CORE_MSR;
+		cpu = channel;
+	}
+
+	if (!cpu_online(cpu))
+		return -ENODEV;
+
+	ret = rdmsrl_safe_on_cpu(cpu, reg, &value);
+	if (ret)
+		return -EAGAIN;
+
+	if ((energy_units == 0) && get_energy_units())
+		return -EAGAIN;
+
+	/* Energy consumed = (1/(2^ESU) * RAW * 1000000UL) Joules */
+	*val = (long)value * div64_ul(1000000UL, (1 << energy_units));
+
+	return 0;
+}
+
+static umode_t amd_energy_is_visible(const void *_data,
+			enum hwmon_sensor_types type,
+			u32 attr, int channel)
+{
+	return 0444;
+}
+
+static const struct hwmon_ops amd_energy_ops = {
+	.is_visible = amd_energy_is_visible,
+	.read = amd_energy_read,
+	.read_string = amd_energy_read_labels,
+};
+
+static int amd_create_sensor(struct device *dev,
+			struct amd_energy_data *data,
+			u8 type, u32 config)
+{
+	int i;
+	u32 *s_config;
+	struct hwmon_channel_info *info = &data->energy_info;
+
+	nr_socks = num_online_nodes();
+	nr_cpus = num_online_cpus();
+
+	s_config = devm_kcalloc(dev, nr_cpus + nr_socks,
+				sizeof(u32), GFP_KERNEL);
+	if (!s_config)
+		return -ENOMEM;
+
+	info->type = type;
+	info->config = s_config;
+
+	for (i = 0; i < nr_cpus + nr_socks; i++)
+		s_config[i] = config;
+
+	return 0;
+}
+
+static int amd_energy_probe(struct platform_device *pdev)
+{
+	struct device *hwmon_dev;
+	struct amd_energy_data *data;
+	struct device *dev = &pdev->dev;
+	int ret;
+
+	ret = get_energy_units();
+
+	data = devm_kzalloc(dev, sizeof(struct amd_energy_data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->chip.ops = &amd_energy_ops;
+	data->chip.info = data->info;
+
+	/* Populate per-core energy reporting */
+	data->info[0] = &data->energy_info;
+	amd_create_sensor(dev, data,  hwmon_energy,
+				HWMON_E_INPUT | HWMON_E_LABEL);
+
+	data->info[1] = NULL;
+
+	hwmon_dev = devm_hwmon_device_register_with_info(dev, DRVNAME,
+							 data,
+							 &data->chip,
+							 NULL);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+static int amd_energy_remove(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static const struct platform_device_id amd_energy_ids[] = {
+	{ .name = DRVNAME, },
+	{}
+};
+MODULE_DEVICE_TABLE(platform, amd_energy_ids);
+
+static struct platform_driver amd_energy_driver = {
+	.probe = amd_energy_probe,
+	.remove	= amd_energy_remove,
+	.id_table = amd_energy_ids,
+	.driver = {
+		.name = DRVNAME,
+	},
+};
+
+static struct platform_device *amd_energy_platdev;
+
+static const struct x86_cpu_id cpu_ids[] __initconst = {
+	AMD_CPU_FAM(17),
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, cpu_ids);
+
+static int __init amd_energy_init(void)
+{
+	int ret;
+
+	if (!x86_match_cpu(cpu_ids))
+		return -ENODEV;
+
+	ret = platform_driver_register(&amd_energy_driver);
+	if (ret < 0)
+		return ret;
+
+	amd_energy_platdev = platform_device_alloc(DRVNAME, 0);
+	if (!amd_energy_platdev)
+		return -ENOMEM;
+
+	ret = platform_device_add(amd_energy_platdev);
+	if (ret) {
+		platform_device_unregister(amd_energy_platdev);
+		return ret;
+	}
+
+	return ret;
+}
+
+static void __exit amd_energy_exit(void)
+{
+	platform_device_unregister(amd_energy_platdev);
+	platform_driver_unregister(&amd_energy_driver);
+}
+
+module_init(amd_energy_init);
+module_exit(amd_energy_exit);
+
+MODULE_DESCRIPTION("Driver for AMD Energy reporting from RAPL MSR via HWMON interface");
+MODULE_AUTHOR("Naveen Krishna Chatradhi <nchatrad@amd.com>");
+MODULE_LICENSE("GPL");
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2020-04-20 10:51 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-09 15:39 [PATCH 1/2] hwmon: Add amd_energy driver to report energy counters Naveen Krishna Chatradhi
2020-04-09 15:39 ` [PATCH 2/2] hwmon: (amd_energy) Add documentation Naveen Krishna Chatradhi
2020-04-10 15:57 ` [PATCH 1/2] hwmon: Add amd_energy driver to report energy counters Guenter Roeck
2020-04-11  4:49   ` Naveen Krishna Ch
2020-04-11  5:16     ` Guenter Roeck
2020-04-11  5:43       ` Naveen Krishna Ch
2020-04-11 12:26   ` Naveen Krishna Ch
2020-04-11 15:48     ` Guenter Roeck
2020-04-11 17:07       ` Naveen Krishna Ch
2020-04-12 20:04         ` Naveen Krishna Ch
2020-04-12 22:27           ` Guenter Roeck
2020-04-20 10:51             ` Naveen Krishna Ch
2020-04-17 19:02 Naveen Krishna Chatradhi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.