Skip to content

Commit f4dc640

Browse files
akky16gregkh
authored andcommitted
misc: amd-sbi: Move hwmon device sensor as separate entity
- Move hwmon device sensor to misc as only power is reported through hwmon sensor. Reviewed-by: Naveen Krishna Chatradhi <[email protected]> Signed-off-by: Akshay Gupta <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 4347059 commit f4dc640

File tree

5 files changed

+142
-104
lines changed

5 files changed

+142
-104
lines changed

drivers/misc/amd-sbi/Kconfig

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,17 @@
22
config AMD_SBRMI_I2C
33
tristate "AMD side band RMI support"
44
depends on I2C
5-
depends on HWMON
65
help
76
Side band RMI over I2C support for AMD out of band management.
87

98
This driver can also be built as a module. If so, the module will
109
be called sbrmi-i2c.
10+
11+
config AMD_SBRMI_HWMON
12+
bool "SBRMI hardware monitoring"
13+
depends on AMD_SBRMI_I2C && HWMON
14+
depends on !(AMD_SBRMI_I2C=y && HWMON=m)
15+
help
16+
This provides support for RMI device hardware monitoring. If enabled,
17+
a hardware monitoring device will be created for each socket in
18+
the system.

drivers/misc/amd-sbi/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# SPDX-License-Identifier: GPL-2.0-only
2-
sbrmi-i2c-objs := rmi-i2c.o rmi-core.o
2+
sbrmi-i2c-objs += rmi-i2c.o rmi-core.o
3+
sbrmi-i2c-$(CONFIG_AMD_SBRMI_HWMON) += rmi-hwmon.o
34
obj-$(CONFIG_AMD_SBRMI_I2C) += sbrmi-i2c.o

drivers/misc/amd-sbi/rmi-core.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,12 @@ struct sbrmi_mailbox_msg {
6060
};
6161

6262
int rmi_mailbox_xfer(struct sbrmi_data *data, struct sbrmi_mailbox_msg *msg);
63+
#ifdef CONFIG_AMD_SBRMI_HWMON
64+
int create_hwmon_sensor_device(struct device *dev, struct sbrmi_data *data);
65+
#else
66+
static inline int create_hwmon_sensor_device(struct device *dev, struct sbrmi_data *data)
67+
{
68+
return 0;
69+
}
70+
#endif
6371
#endif /*_SBRMI_CORE_H_*/

drivers/misc/amd-sbi/rmi-hwmon.c

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
/*
3+
* rmi-hwmon.c - hwmon sensor support for side band RMI
4+
*
5+
* Copyright (C) 2025 Advanced Micro Devices, Inc.
6+
*/
7+
#include <linux/err.h>
8+
#include <linux/hwmon.h>
9+
#include "rmi-core.h"
10+
11+
/* Do not allow setting negative power limit */
12+
#define SBRMI_PWR_MIN 0
13+
14+
static int sbrmi_read(struct device *dev, enum hwmon_sensor_types type,
15+
u32 attr, int channel, long *val)
16+
{
17+
struct sbrmi_data *data = dev_get_drvdata(dev);
18+
struct sbrmi_mailbox_msg msg = { 0 };
19+
int ret;
20+
21+
if (!data)
22+
return -ENODEV;
23+
24+
if (type != hwmon_power)
25+
return -EINVAL;
26+
27+
msg.read = true;
28+
switch (attr) {
29+
case hwmon_power_input:
30+
msg.cmd = SBRMI_READ_PKG_PWR_CONSUMPTION;
31+
ret = rmi_mailbox_xfer(data, &msg);
32+
break;
33+
case hwmon_power_cap:
34+
msg.cmd = SBRMI_READ_PKG_PWR_LIMIT;
35+
ret = rmi_mailbox_xfer(data, &msg);
36+
break;
37+
case hwmon_power_cap_max:
38+
msg.data_out = data->pwr_limit_max;
39+
ret = 0;
40+
break;
41+
default:
42+
return -EINVAL;
43+
}
44+
if (ret < 0)
45+
return ret;
46+
/* hwmon power attributes are in microWatt */
47+
*val = (long)msg.data_out * 1000;
48+
return ret;
49+
}
50+
51+
static int sbrmi_write(struct device *dev, enum hwmon_sensor_types type,
52+
u32 attr, int channel, long val)
53+
{
54+
struct sbrmi_data *data = dev_get_drvdata(dev);
55+
struct sbrmi_mailbox_msg msg = { 0 };
56+
57+
if (!data)
58+
return -ENODEV;
59+
60+
if (type != hwmon_power && attr != hwmon_power_cap)
61+
return -EINVAL;
62+
/*
63+
* hwmon power attributes are in microWatt
64+
* mailbox read/write is in mWatt
65+
*/
66+
val /= 1000;
67+
68+
val = clamp_val(val, SBRMI_PWR_MIN, data->pwr_limit_max);
69+
70+
msg.cmd = SBRMI_WRITE_PKG_PWR_LIMIT;
71+
msg.data_in = val;
72+
msg.read = false;
73+
74+
return rmi_mailbox_xfer(data, &msg);
75+
}
76+
77+
static umode_t sbrmi_is_visible(const void *data,
78+
enum hwmon_sensor_types type,
79+
u32 attr, int channel)
80+
{
81+
switch (type) {
82+
case hwmon_power:
83+
switch (attr) {
84+
case hwmon_power_input:
85+
case hwmon_power_cap_max:
86+
return 0444;
87+
case hwmon_power_cap:
88+
return 0644;
89+
}
90+
break;
91+
default:
92+
break;
93+
}
94+
return 0;
95+
}
96+
97+
static const struct hwmon_channel_info * const sbrmi_info[] = {
98+
HWMON_CHANNEL_INFO(power,
99+
HWMON_P_INPUT | HWMON_P_CAP | HWMON_P_CAP_MAX),
100+
NULL
101+
};
102+
103+
static const struct hwmon_ops sbrmi_hwmon_ops = {
104+
.is_visible = sbrmi_is_visible,
105+
.read = sbrmi_read,
106+
.write = sbrmi_write,
107+
};
108+
109+
static const struct hwmon_chip_info sbrmi_chip_info = {
110+
.ops = &sbrmi_hwmon_ops,
111+
.info = sbrmi_info,
112+
};
113+
114+
int create_hwmon_sensor_device(struct device *dev, struct sbrmi_data *data)
115+
{
116+
struct device *hwmon_dev;
117+
118+
hwmon_dev = devm_hwmon_device_register_with_info(dev, "sbrmi", data,
119+
&sbrmi_chip_info, NULL);
120+
return PTR_ERR_OR_ZERO(hwmon_dev);
121+
}

drivers/misc/amd-sbi/rmi-i2c.c

Lines changed: 2 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,13 @@
88

99
#include <linux/delay.h>
1010
#include <linux/err.h>
11-
#include <linux/hwmon.h>
1211
#include <linux/i2c.h>
1312
#include <linux/init.h>
1413
#include <linux/module.h>
1514
#include <linux/mutex.h>
1615
#include <linux/of.h>
1716
#include "rmi-core.h"
1817

19-
/* Do not allow setting negative power limit */
20-
#define SBRMI_PWR_MIN 0
21-
2218
static int sbrmi_enable_alert(struct i2c_client *client)
2319
{
2420
int ctrl;
@@ -40,100 +36,6 @@ static int sbrmi_enable_alert(struct i2c_client *client)
4036
return 0;
4137
}
4238

43-
static int sbrmi_read(struct device *dev, enum hwmon_sensor_types type,
44-
u32 attr, int channel, long *val)
45-
{
46-
struct sbrmi_data *data = dev_get_drvdata(dev);
47-
struct sbrmi_mailbox_msg msg = { 0 };
48-
int ret;
49-
50-
if (type != hwmon_power)
51-
return -EINVAL;
52-
53-
msg.read = true;
54-
switch (attr) {
55-
case hwmon_power_input:
56-
msg.cmd = SBRMI_READ_PKG_PWR_CONSUMPTION;
57-
ret = rmi_mailbox_xfer(data, &msg);
58-
break;
59-
case hwmon_power_cap:
60-
msg.cmd = SBRMI_READ_PKG_PWR_LIMIT;
61-
ret = rmi_mailbox_xfer(data, &msg);
62-
break;
63-
case hwmon_power_cap_max:
64-
msg.data_out = data->pwr_limit_max;
65-
ret = 0;
66-
break;
67-
default:
68-
return -EINVAL;
69-
}
70-
if (ret < 0)
71-
return ret;
72-
/* hwmon power attributes are in microWatt */
73-
*val = (long)msg.data_out * 1000;
74-
return ret;
75-
}
76-
77-
static int sbrmi_write(struct device *dev, enum hwmon_sensor_types type,
78-
u32 attr, int channel, long val)
79-
{
80-
struct sbrmi_data *data = dev_get_drvdata(dev);
81-
struct sbrmi_mailbox_msg msg = { 0 };
82-
83-
if (type != hwmon_power && attr != hwmon_power_cap)
84-
return -EINVAL;
85-
/*
86-
* hwmon power attributes are in microWatt
87-
* mailbox read/write is in mWatt
88-
*/
89-
val /= 1000;
90-
91-
val = clamp_val(val, SBRMI_PWR_MIN, data->pwr_limit_max);
92-
93-
msg.cmd = SBRMI_WRITE_PKG_PWR_LIMIT;
94-
msg.data_in = val;
95-
msg.read = false;
96-
97-
return rmi_mailbox_xfer(data, &msg);
98-
}
99-
100-
static umode_t sbrmi_is_visible(const void *data,
101-
enum hwmon_sensor_types type,
102-
u32 attr, int channel)
103-
{
104-
switch (type) {
105-
case hwmon_power:
106-
switch (attr) {
107-
case hwmon_power_input:
108-
case hwmon_power_cap_max:
109-
return 0444;
110-
case hwmon_power_cap:
111-
return 0644;
112-
}
113-
break;
114-
default:
115-
break;
116-
}
117-
return 0;
118-
}
119-
120-
static const struct hwmon_channel_info * const sbrmi_info[] = {
121-
HWMON_CHANNEL_INFO(power,
122-
HWMON_P_INPUT | HWMON_P_CAP | HWMON_P_CAP_MAX),
123-
NULL
124-
};
125-
126-
static const struct hwmon_ops sbrmi_hwmon_ops = {
127-
.is_visible = sbrmi_is_visible,
128-
.read = sbrmi_read,
129-
.write = sbrmi_write,
130-
};
131-
132-
static const struct hwmon_chip_info sbrmi_chip_info = {
133-
.ops = &sbrmi_hwmon_ops,
134-
.info = sbrmi_info,
135-
};
136-
13739
static int sbrmi_get_max_pwr_limit(struct sbrmi_data *data)
13840
{
13941
struct sbrmi_mailbox_msg msg = { 0 };
@@ -152,7 +54,6 @@ static int sbrmi_get_max_pwr_limit(struct sbrmi_data *data)
15254
static int sbrmi_i2c_probe(struct i2c_client *client)
15355
{
15456
struct device *dev = &client->dev;
155-
struct device *hwmon_dev;
15657
struct sbrmi_data *data;
15758
int ret;
15859

@@ -173,9 +74,8 @@ static int sbrmi_i2c_probe(struct i2c_client *client)
17374
if (ret < 0)
17475
return ret;
17576

176-
hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, data,
177-
&sbrmi_chip_info, NULL);
178-
return PTR_ERR_OR_ZERO(hwmon_dev);
77+
dev_set_drvdata(dev, data);
78+
return create_hwmon_sensor_device(dev, data);
17979
}
18080

18181
static const struct i2c_device_id sbrmi_id[] = {

0 commit comments

Comments
 (0)