File Index
Files and directories
Sign in
FILE

hwmon.c

File preview with syntax highlighting.

linux-6.19.14/drivers/platform/x86/amd/hsmp/hwmon.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * AMD HSMP hwmon support
  4 * Copyright (c) 2025, AMD.
  5 * All Rights Reserved.
  6 *
  7 * This file provides hwmon implementation for HSMP interface.
  8 */
  9
 10#include <asm/amd/hsmp.h>
 11
 12#include <linux/device.h>
 13#include <linux/err.h>
 14#include <linux/hwmon.h>
 15#include <linux/types.h>
 16#include <linux/units.h>
 17
 18#include "hsmp.h"
 19
 20#define HSMP_HWMON_NAME		"amd_hsmp_hwmon"
 21
 22static int hsmp_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
 23			    u32 attr, int channel, long val)
 24{
 25	u16 sock_ind = (uintptr_t)dev_get_drvdata(dev);
 26	struct hsmp_message msg = {};
 27
 28	if (type != hwmon_power)
 29		return -EOPNOTSUPP;
 30
 31	if (attr != hwmon_power_cap)
 32		return -EOPNOTSUPP;
 33
 34	msg.num_args = 1;
 35	msg.args[0] = val / MICROWATT_PER_MILLIWATT;
 36	msg.msg_id = HSMP_SET_SOCKET_POWER_LIMIT;
 37	msg.sock_ind = sock_ind;
 38	return hsmp_send_message(&msg);
 39}
 40
 41static int hsmp_hwmon_read(struct device *dev,
 42			   enum hwmon_sensor_types type,
 43			   u32 attr, int channel, long *val)
 44{
 45	u16 sock_ind = (uintptr_t)dev_get_drvdata(dev);
 46	struct hsmp_message msg = {};
 47	int ret;
 48
 49	if (type != hwmon_power)
 50		return -EOPNOTSUPP;
 51
 52	msg.sock_ind = sock_ind;
 53	msg.response_sz = 1;
 54
 55	switch (attr) {
 56	case hwmon_power_input:
 57		msg.msg_id = HSMP_GET_SOCKET_POWER;
 58		break;
 59	case hwmon_power_cap:
 60		msg.msg_id = HSMP_GET_SOCKET_POWER_LIMIT;
 61		break;
 62	case hwmon_power_cap_max:
 63		msg.msg_id = HSMP_GET_SOCKET_POWER_LIMIT_MAX;
 64		break;
 65	default:
 66		return -EOPNOTSUPP;
 67	}
 68
 69	ret = hsmp_send_message(&msg);
 70	if (!ret)
 71		*val = msg.args[0] * MICROWATT_PER_MILLIWATT;
 72
 73	return ret;
 74}
 75
 76static umode_t hsmp_hwmon_is_visble(const void *data,
 77				    enum hwmon_sensor_types type,
 78				    u32 attr, int channel)
 79{
 80	if (type != hwmon_power)
 81		return 0;
 82
 83	switch (attr) {
 84	case hwmon_power_input:
 85		return 0444;
 86	case hwmon_power_cap:
 87		return 0644;
 88	case hwmon_power_cap_max:
 89		return 0444;
 90	default:
 91		return 0;
 92	}
 93}
 94
 95static const struct hwmon_ops hsmp_hwmon_ops = {
 96	.read = hsmp_hwmon_read,
 97	.is_visible = hsmp_hwmon_is_visble,
 98	.write	= hsmp_hwmon_write,
 99};
100
101static const struct hwmon_channel_info * const hsmp_info[] = {
102	HWMON_CHANNEL_INFO(power, HWMON_P_INPUT | HWMON_P_CAP | HWMON_P_CAP_MAX),
103	NULL
104};
105
106static const struct hwmon_chip_info hsmp_chip_info = {
107	.ops = &hsmp_hwmon_ops,
108	.info = hsmp_info,
109};
110
111int hsmp_create_sensor(struct device *dev, u16 sock_ind)
112{
113	struct device *hwmon_dev;
114
115	hwmon_dev = devm_hwmon_device_register_with_info(dev, HSMP_HWMON_NAME,
116							 (void *)(uintptr_t)sock_ind,
117							 &hsmp_chip_info,
118							 NULL);
119	return PTR_ERR_OR_ZERO(hwmon_dev);
120}
121EXPORT_SYMBOL_NS(hsmp_create_sensor, "AMD_HSMP");
~/ Read-only file preview.