]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
misc: amd-sbi: Move hwmon device sensor as separate entity
authorAkshay Gupta <akshay.gupta@amd.com>
Mon, 28 Apr 2025 06:30:27 +0000 (06:30 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 21 May 2025 12:44:40 +0000 (14:44 +0200)
- Move hwmon device sensor to misc as only power is reported through
  hwmon sensor.

Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
Signed-off-by: Akshay Gupta <akshay.gupta@amd.com>
Link: https://lore.kernel.org/r/20250428063034.2145566-4-akshay.gupta@amd.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/misc/amd-sbi/Kconfig
drivers/misc/amd-sbi/Makefile
drivers/misc/amd-sbi/rmi-core.h
drivers/misc/amd-sbi/rmi-hwmon.c [new file with mode: 0644]
drivers/misc/amd-sbi/rmi-i2c.c

index 0c8981f97f25bef6336971d8b192313f29e77892..4840831c84ca481a24f802874cf632280e682b44 100644 (file)
@@ -2,9 +2,17 @@
 config AMD_SBRMI_I2C
        tristate "AMD side band RMI support"
        depends on I2C
-       depends on HWMON
        help
          Side band RMI over I2C support for AMD out of band management.
 
          This driver can also be built as a module. If so, the module will
          be called sbrmi-i2c.
+
+config AMD_SBRMI_HWMON
+       bool "SBRMI hardware monitoring"
+       depends on AMD_SBRMI_I2C && HWMON
+       depends on !(AMD_SBRMI_I2C=y && HWMON=m)
+       help
+         This provides support for RMI device hardware monitoring. If enabled,
+         a hardware monitoring device will be created for each socket in
+         the system.
index 7cd8e0a1aa5df7a4c9d1be2f4343ece85cce4b64..38eaaa651fd99f6cc43e692098f481aeaaca1360 100644 (file)
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
-sbrmi-i2c-objs                 := rmi-i2c.o rmi-core.o
+sbrmi-i2c-objs                 += rmi-i2c.o rmi-core.o
+sbrmi-i2c-$(CONFIG_AMD_SBRMI_HWMON)    += rmi-hwmon.o
 obj-$(CONFIG_AMD_SBRMI_I2C)    += sbrmi-i2c.o
index 8e30a43ec714749479d67ba4336c193fda13f844..977ee05af6a69a3f3c63e1f7ffd451003f5af979 100644 (file)
@@ -60,4 +60,12 @@ struct sbrmi_mailbox_msg {
 };
 
 int rmi_mailbox_xfer(struct sbrmi_data *data, struct sbrmi_mailbox_msg *msg);
+#ifdef CONFIG_AMD_SBRMI_HWMON
+int create_hwmon_sensor_device(struct device *dev, struct sbrmi_data *data);
+#else
+static inline int create_hwmon_sensor_device(struct device *dev, struct sbrmi_data *data)
+{
+       return 0;
+}
+#endif
 #endif /*_SBRMI_CORE_H_*/
diff --git a/drivers/misc/amd-sbi/rmi-hwmon.c b/drivers/misc/amd-sbi/rmi-hwmon.c
new file mode 100644 (file)
index 0000000..720e800
--- /dev/null
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * rmi-hwmon.c - hwmon sensor support for side band RMI
+ *
+ * Copyright (C) 2025 Advanced Micro Devices, Inc.
+ */
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include "rmi-core.h"
+
+/* Do not allow setting negative power limit */
+#define SBRMI_PWR_MIN  0
+
+static int sbrmi_read(struct device *dev, enum hwmon_sensor_types type,
+                     u32 attr, int channel, long *val)
+{
+       struct sbrmi_data *data = dev_get_drvdata(dev);
+       struct sbrmi_mailbox_msg msg = { 0 };
+       int ret;
+
+       if (!data)
+               return -ENODEV;
+
+       if (type != hwmon_power)
+               return -EINVAL;
+
+       msg.read = true;
+       switch (attr) {
+       case hwmon_power_input:
+               msg.cmd = SBRMI_READ_PKG_PWR_CONSUMPTION;
+               ret = rmi_mailbox_xfer(data, &msg);
+               break;
+       case hwmon_power_cap:
+               msg.cmd = SBRMI_READ_PKG_PWR_LIMIT;
+               ret = rmi_mailbox_xfer(data, &msg);
+               break;
+       case hwmon_power_cap_max:
+               msg.data_out = data->pwr_limit_max;
+               ret = 0;
+               break;
+       default:
+               return -EINVAL;
+       }
+       if (ret < 0)
+               return ret;
+       /* hwmon power attributes are in microWatt */
+       *val = (long)msg.data_out * 1000;
+       return ret;
+}
+
+static int sbrmi_write(struct device *dev, enum hwmon_sensor_types type,
+                      u32 attr, int channel, long val)
+{
+       struct sbrmi_data *data = dev_get_drvdata(dev);
+       struct sbrmi_mailbox_msg msg = { 0 };
+
+       if (!data)
+               return -ENODEV;
+
+       if (type != hwmon_power && attr != hwmon_power_cap)
+               return -EINVAL;
+       /*
+        * hwmon power attributes are in microWatt
+        * mailbox read/write is in mWatt
+        */
+       val /= 1000;
+
+       val = clamp_val(val, SBRMI_PWR_MIN, data->pwr_limit_max);
+
+       msg.cmd = SBRMI_WRITE_PKG_PWR_LIMIT;
+       msg.data_in = val;
+       msg.read = false;
+
+       return rmi_mailbox_xfer(data, &msg);
+}
+
+static umode_t sbrmi_is_visible(const void *data,
+                               enum hwmon_sensor_types type,
+                               u32 attr, int channel)
+{
+       switch (type) {
+       case hwmon_power:
+               switch (attr) {
+               case hwmon_power_input:
+               case hwmon_power_cap_max:
+                       return 0444;
+               case hwmon_power_cap:
+                       return 0644;
+               }
+               break;
+       default:
+               break;
+       }
+       return 0;
+}
+
+static const struct hwmon_channel_info * const sbrmi_info[] = {
+       HWMON_CHANNEL_INFO(power,
+                          HWMON_P_INPUT | HWMON_P_CAP | HWMON_P_CAP_MAX),
+       NULL
+};
+
+static const struct hwmon_ops sbrmi_hwmon_ops = {
+       .is_visible = sbrmi_is_visible,
+       .read = sbrmi_read,
+       .write = sbrmi_write,
+};
+
+static const struct hwmon_chip_info sbrmi_chip_info = {
+       .ops = &sbrmi_hwmon_ops,
+       .info = sbrmi_info,
+};
+
+int create_hwmon_sensor_device(struct device *dev, struct sbrmi_data *data)
+{
+       struct device *hwmon_dev;
+
+       hwmon_dev = devm_hwmon_device_register_with_info(dev, "sbrmi", data,
+                                                        &sbrmi_chip_info, NULL);
+       return PTR_ERR_OR_ZERO(hwmon_dev);
+}
index 6412f00eb3810fad4ce451b37611e41e3ed21e60..9ad4c80933995123ab5f474f1234624ab36674f3 100644 (file)
@@ -8,7 +8,6 @@
 
 #include <linux/delay.h>
 #include <linux/err.h>
-#include <linux/hwmon.h>
 #include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -16,9 +15,6 @@
 #include <linux/of.h>
 #include "rmi-core.h"
 
-/* Do not allow setting negative power limit */
-#define SBRMI_PWR_MIN  0
-
 static int sbrmi_enable_alert(struct i2c_client *client)
 {
        int ctrl;
@@ -40,100 +36,6 @@ static int sbrmi_enable_alert(struct i2c_client *client)
        return 0;
 }
 
-static int sbrmi_read(struct device *dev, enum hwmon_sensor_types type,
-                     u32 attr, int channel, long *val)
-{
-       struct sbrmi_data *data = dev_get_drvdata(dev);
-       struct sbrmi_mailbox_msg msg = { 0 };
-       int ret;
-
-       if (type != hwmon_power)
-               return -EINVAL;
-
-       msg.read = true;
-       switch (attr) {
-       case hwmon_power_input:
-               msg.cmd = SBRMI_READ_PKG_PWR_CONSUMPTION;
-               ret = rmi_mailbox_xfer(data, &msg);
-               break;
-       case hwmon_power_cap:
-               msg.cmd = SBRMI_READ_PKG_PWR_LIMIT;
-               ret = rmi_mailbox_xfer(data, &msg);
-               break;
-       case hwmon_power_cap_max:
-               msg.data_out = data->pwr_limit_max;
-               ret = 0;
-               break;
-       default:
-               return -EINVAL;
-       }
-       if (ret < 0)
-               return ret;
-       /* hwmon power attributes are in microWatt */
-       *val = (long)msg.data_out * 1000;
-       return ret;
-}
-
-static int sbrmi_write(struct device *dev, enum hwmon_sensor_types type,
-                      u32 attr, int channel, long val)
-{
-       struct sbrmi_data *data = dev_get_drvdata(dev);
-       struct sbrmi_mailbox_msg msg = { 0 };
-
-       if (type != hwmon_power && attr != hwmon_power_cap)
-               return -EINVAL;
-       /*
-        * hwmon power attributes are in microWatt
-        * mailbox read/write is in mWatt
-        */
-       val /= 1000;
-
-       val = clamp_val(val, SBRMI_PWR_MIN, data->pwr_limit_max);
-
-       msg.cmd = SBRMI_WRITE_PKG_PWR_LIMIT;
-       msg.data_in = val;
-       msg.read = false;
-
-       return rmi_mailbox_xfer(data, &msg);
-}
-
-static umode_t sbrmi_is_visible(const void *data,
-                               enum hwmon_sensor_types type,
-                               u32 attr, int channel)
-{
-       switch (type) {
-       case hwmon_power:
-               switch (attr) {
-               case hwmon_power_input:
-               case hwmon_power_cap_max:
-                       return 0444;
-               case hwmon_power_cap:
-                       return 0644;
-               }
-               break;
-       default:
-               break;
-       }
-       return 0;
-}
-
-static const struct hwmon_channel_info * const sbrmi_info[] = {
-       HWMON_CHANNEL_INFO(power,
-                          HWMON_P_INPUT | HWMON_P_CAP | HWMON_P_CAP_MAX),
-       NULL
-};
-
-static const struct hwmon_ops sbrmi_hwmon_ops = {
-       .is_visible = sbrmi_is_visible,
-       .read = sbrmi_read,
-       .write = sbrmi_write,
-};
-
-static const struct hwmon_chip_info sbrmi_chip_info = {
-       .ops = &sbrmi_hwmon_ops,
-       .info = sbrmi_info,
-};
-
 static int sbrmi_get_max_pwr_limit(struct sbrmi_data *data)
 {
        struct sbrmi_mailbox_msg msg = { 0 };
@@ -152,7 +54,6 @@ static int sbrmi_get_max_pwr_limit(struct sbrmi_data *data)
 static int sbrmi_i2c_probe(struct i2c_client *client)
 {
        struct device *dev = &client->dev;
-       struct device *hwmon_dev;
        struct sbrmi_data *data;
        int ret;
 
@@ -173,9 +74,8 @@ static int sbrmi_i2c_probe(struct i2c_client *client)
        if (ret < 0)
                return ret;
 
-       hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, data,
-                                                        &sbrmi_chip_info, NULL);
-       return PTR_ERR_OR_ZERO(hwmon_dev);
+       dev_set_drvdata(dev, data);
+       return create_hwmon_sensor_device(dev, data);
 }
 
 static const struct i2c_device_id sbrmi_id[] = {