1*b3b088e2SDale B Stimson // SPDX-License-Identifier: MIT 2*b3b088e2SDale B Stimson /* 3*b3b088e2SDale B Stimson * Copyright © 2022 Intel Corporation 4*b3b088e2SDale B Stimson */ 5*b3b088e2SDale B Stimson 6*b3b088e2SDale B Stimson #include <linux/hwmon.h> 7*b3b088e2SDale B Stimson #include <linux/hwmon-sysfs.h> 8*b3b088e2SDale B Stimson #include <linux/types.h> 9*b3b088e2SDale B Stimson 10*b3b088e2SDale B Stimson #include "i915_drv.h" 11*b3b088e2SDale B Stimson #include "i915_hwmon.h" 12*b3b088e2SDale B Stimson #include "i915_reg.h" 13*b3b088e2SDale B Stimson #include "intel_mchbar_regs.h" 14*b3b088e2SDale B Stimson 15*b3b088e2SDale B Stimson struct hwm_reg { 16*b3b088e2SDale B Stimson }; 17*b3b088e2SDale B Stimson 18*b3b088e2SDale B Stimson struct hwm_drvdata { 19*b3b088e2SDale B Stimson struct i915_hwmon *hwmon; 20*b3b088e2SDale B Stimson struct intel_uncore *uncore; 21*b3b088e2SDale B Stimson struct device *hwmon_dev; 22*b3b088e2SDale B Stimson char name[12]; 23*b3b088e2SDale B Stimson }; 24*b3b088e2SDale B Stimson 25*b3b088e2SDale B Stimson struct i915_hwmon { 26*b3b088e2SDale B Stimson struct hwm_drvdata ddat; 27*b3b088e2SDale B Stimson struct mutex hwmon_lock; /* counter overflow logic and rmw */ 28*b3b088e2SDale B Stimson struct hwm_reg rg; 29*b3b088e2SDale B Stimson }; 30*b3b088e2SDale B Stimson 31*b3b088e2SDale B Stimson static const struct hwmon_channel_info *hwm_info[] = { 32*b3b088e2SDale B Stimson NULL 33*b3b088e2SDale B Stimson }; 34*b3b088e2SDale B Stimson 35*b3b088e2SDale B Stimson static umode_t 36*b3b088e2SDale B Stimson hwm_is_visible(const void *drvdata, enum hwmon_sensor_types type, 37*b3b088e2SDale B Stimson u32 attr, int channel) 38*b3b088e2SDale B Stimson { 39*b3b088e2SDale B Stimson switch (type) { 40*b3b088e2SDale B Stimson default: 41*b3b088e2SDale B Stimson return 0; 42*b3b088e2SDale B Stimson } 43*b3b088e2SDale B Stimson } 44*b3b088e2SDale B Stimson 45*b3b088e2SDale B Stimson static int 46*b3b088e2SDale B Stimson hwm_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, 47*b3b088e2SDale B Stimson int channel, long *val) 48*b3b088e2SDale B Stimson { 49*b3b088e2SDale B Stimson switch (type) { 50*b3b088e2SDale B Stimson default: 51*b3b088e2SDale B Stimson return -EOPNOTSUPP; 52*b3b088e2SDale B Stimson } 53*b3b088e2SDale B Stimson } 54*b3b088e2SDale B Stimson 55*b3b088e2SDale B Stimson static int 56*b3b088e2SDale B Stimson hwm_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, 57*b3b088e2SDale B Stimson int channel, long val) 58*b3b088e2SDale B Stimson { 59*b3b088e2SDale B Stimson switch (type) { 60*b3b088e2SDale B Stimson default: 61*b3b088e2SDale B Stimson return -EOPNOTSUPP; 62*b3b088e2SDale B Stimson } 63*b3b088e2SDale B Stimson } 64*b3b088e2SDale B Stimson 65*b3b088e2SDale B Stimson static const struct hwmon_ops hwm_ops = { 66*b3b088e2SDale B Stimson .is_visible = hwm_is_visible, 67*b3b088e2SDale B Stimson .read = hwm_read, 68*b3b088e2SDale B Stimson .write = hwm_write, 69*b3b088e2SDale B Stimson }; 70*b3b088e2SDale B Stimson 71*b3b088e2SDale B Stimson static const struct hwmon_chip_info hwm_chip_info = { 72*b3b088e2SDale B Stimson .ops = &hwm_ops, 73*b3b088e2SDale B Stimson .info = hwm_info, 74*b3b088e2SDale B Stimson }; 75*b3b088e2SDale B Stimson 76*b3b088e2SDale B Stimson static void 77*b3b088e2SDale B Stimson hwm_get_preregistration_info(struct drm_i915_private *i915) 78*b3b088e2SDale B Stimson { 79*b3b088e2SDale B Stimson } 80*b3b088e2SDale B Stimson 81*b3b088e2SDale B Stimson void i915_hwmon_register(struct drm_i915_private *i915) 82*b3b088e2SDale B Stimson { 83*b3b088e2SDale B Stimson struct device *dev = i915->drm.dev; 84*b3b088e2SDale B Stimson struct i915_hwmon *hwmon; 85*b3b088e2SDale B Stimson struct device *hwmon_dev; 86*b3b088e2SDale B Stimson struct hwm_drvdata *ddat; 87*b3b088e2SDale B Stimson 88*b3b088e2SDale B Stimson /* hwmon is available only for dGfx */ 89*b3b088e2SDale B Stimson if (!IS_DGFX(i915)) 90*b3b088e2SDale B Stimson return; 91*b3b088e2SDale B Stimson 92*b3b088e2SDale B Stimson hwmon = devm_kzalloc(dev, sizeof(*hwmon), GFP_KERNEL); 93*b3b088e2SDale B Stimson if (!hwmon) 94*b3b088e2SDale B Stimson return; 95*b3b088e2SDale B Stimson 96*b3b088e2SDale B Stimson i915->hwmon = hwmon; 97*b3b088e2SDale B Stimson mutex_init(&hwmon->hwmon_lock); 98*b3b088e2SDale B Stimson ddat = &hwmon->ddat; 99*b3b088e2SDale B Stimson 100*b3b088e2SDale B Stimson ddat->hwmon = hwmon; 101*b3b088e2SDale B Stimson ddat->uncore = &i915->uncore; 102*b3b088e2SDale B Stimson snprintf(ddat->name, sizeof(ddat->name), "i915"); 103*b3b088e2SDale B Stimson 104*b3b088e2SDale B Stimson hwm_get_preregistration_info(i915); 105*b3b088e2SDale B Stimson 106*b3b088e2SDale B Stimson /* hwmon_dev points to device hwmon<i> */ 107*b3b088e2SDale B Stimson hwmon_dev = devm_hwmon_device_register_with_info(dev, ddat->name, 108*b3b088e2SDale B Stimson ddat, 109*b3b088e2SDale B Stimson &hwm_chip_info, 110*b3b088e2SDale B Stimson NULL); 111*b3b088e2SDale B Stimson if (IS_ERR(hwmon_dev)) { 112*b3b088e2SDale B Stimson i915->hwmon = NULL; 113*b3b088e2SDale B Stimson return; 114*b3b088e2SDale B Stimson } 115*b3b088e2SDale B Stimson 116*b3b088e2SDale B Stimson ddat->hwmon_dev = hwmon_dev; 117*b3b088e2SDale B Stimson } 118*b3b088e2SDale B Stimson 119*b3b088e2SDale B Stimson void i915_hwmon_unregister(struct drm_i915_private *i915) 120*b3b088e2SDale B Stimson { 121*b3b088e2SDale B Stimson fetch_and_zero(&i915->hwmon); 122*b3b088e2SDale B Stimson } 123