diff options
| author | Karthik Poosa <karthik.poosa@intel.com> | 2026-10-15 12:44:34 +0530 |
|---|---|---|
| committer | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2026-10-15 10:22:25 -0400 |
| commit | 4289dded4329bc2bf16fbc1bcfed22c198e2f147 (patch) | |
| tree | e15099e9ff3a919538da4af7f919bd13d282062a | |
| parent | a3d7376b9d6711ad45060f73b951130399a1ff9b (diff) | |
| download | linux-next-4289dded4329bc2bf16fbc1bcfed22c198e2f147.tar.gz linux-next-4289dded4329bc2bf16fbc1bcfed22c198e2f147.zip | |
drm/xe/hwmon: Propagate all hardware read errors
Propagate all failures from pcode and mailbox accesses and fix missed
return-value checks found by Sashiko in
https://patchwork.freedesktop.org/patch/758843/?series=174898&rev=6.
Fixes: 7596d839f622 ("drm/xe/hwmon: Add support to manage power limits though mailbox")
Fixes: 0c5405d3aa4ad ("drm/xe/hwmon: Read energy status from PMT")
Fixes: 25e963a09e059 ("drm/xe/hwmon: Move card reactive critical power under channel card")
Signed-off-by: Karthik Poosa <karthik.poosa@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patch.msgid.link/20261015071434.1063785-17-karthik.poosa@intel.com
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
| -rw-r--r-- | drivers/gpu/drm/xe/xe_hwmon.c | 47 |
1 files changed, 29 insertions, 18 deletions
diff --git a/drivers/gpu/drm/xe/xe_hwmon.c b/drivers/gpu/drm/xe/xe_hwmon.c index 221d7a3bd7dc..42acfeb8818c 100644 --- a/drivers/gpu/drm/xe/xe_hwmon.c +++ b/drivers/gpu/drm/xe/xe_hwmon.c @@ -411,17 +411,20 @@ static struct xe_reg xe_hwmon_get_reg(struct xe_hwmon *hwmon, enum xe_hwmon_reg * same pattern for sysfs, allow arbitrary PL1 limits to be set but display * clamped values when read. */ -static void xe_hwmon_power_max_read(struct xe_hwmon *hwmon, u32 attr, int channel, long *value) +static int xe_hwmon_power_max_read(struct xe_hwmon *hwmon, u32 attr, int channel, long *value) { u32 reg_val = 0; struct xe_device *xe = hwmon->xe; struct xe_reg rapl_limit, pkg_power_sku; struct xe_mmio *mmio = xe_root_tile_mmio(xe); + int ret = 0; mutex_lock(&hwmon->hwmon_lock); if (hwmon->xe->info.has_mbx_power_limits) { - xe_hwmon_pcode_read_power_limit(hwmon, attr, channel, ®_val); + ret = xe_hwmon_pcode_read_power_limit(hwmon, attr, channel, ®_val); + if (ret) + goto unlock; } else { rapl_limit = xe_hwmon_get_reg(hwmon, REG_PKG_RAPL_LIMIT, channel); pkg_power_sku = xe_hwmon_get_reg(hwmon, REG_PKG_POWER_SKU, channel); @@ -453,6 +456,7 @@ static void xe_hwmon_power_max_read(struct xe_hwmon *hwmon, u32 attr, int channe } unlock: mutex_unlock(&hwmon->hwmon_lock); + return ret; } static int xe_hwmon_power_max_write(struct xe_hwmon *hwmon, u32 attr, int channel, long value) @@ -475,7 +479,9 @@ static int xe_hwmon_power_max_write(struct xe_hwmon *hwmon, u32 attr, int channe ret = xe_hwmon_pcode_rmw_power_limit(hwmon, attr, channel, PWR_LIM_EN, 0); if (ret) goto unlock; - xe_hwmon_pcode_read_power_limit(hwmon, attr, channel, ®_val); + ret = xe_hwmon_pcode_read_power_limit(hwmon, attr, channel, ®_val); + if (ret) + goto unlock; } else { reg_val = xe_mmio_rmw32(mmio, rapl_limit, PWR_LIM_EN, 0); reg_val = xe_mmio_read32(mmio, rapl_limit); @@ -532,15 +538,18 @@ unlock: return ret; } -static void xe_hwmon_power_rated_max_read(struct xe_hwmon *hwmon, u32 attr, int channel, - long *value) +static int xe_hwmon_power_rated_max_read(struct xe_hwmon *hwmon, u32 attr, int channel, + long *value) { struct xe_mmio *mmio = xe_root_tile_mmio(hwmon->xe); u32 reg_val; + int ret = 0; if (hwmon->xe->info.has_mbx_power_limits) { /* PL1 is rated max if supported. */ - xe_hwmon_pcode_read_power_limit(hwmon, PL1_HWMON_ATTR, channel, ®_val); + ret = xe_hwmon_pcode_read_power_limit(hwmon, PL1_HWMON_ATTR, channel, ®_val); + if (ret) + return ret; } else { /* * This sysfs file won't be visible if REG_PKG_POWER_SKU is invalid, so valid check @@ -554,6 +563,7 @@ static void xe_hwmon_power_rated_max_read(struct xe_hwmon *hwmon, u32 attr, int reg_val = REG_FIELD_GET(PKG_TDP, reg_val); *value = mul_u64_u32_shr(reg_val, SF_POWER, hwmon->scl_shift_power); + return ret; } /* @@ -576,7 +586,7 @@ static void xe_hwmon_power_rated_max_read(struct xe_hwmon *hwmon, u32 attr, int * hwmon->scl_shift_energy of 14 bits we have 57 (63 - 20 + 14) bits before * energyN_input overflows. This at 1000 W is an overflow duration of 278 years. */ -static void +static int xe_hwmon_energy_get(struct xe_hwmon *hwmon, int channel, long *energy) { struct xe_mmio *mmio = xe_root_tile_mmio(hwmon->xe); @@ -587,7 +597,7 @@ xe_hwmon_energy_get(struct xe_hwmon *hwmon, int channel, long *energy) /* Energy is supported only for card and pkg */ if (channel > CHANNEL_PKG) { *energy = 0; - return; + return 0; } if (hwmon->xe->info.platform == XE_BATTLEMAGE) { @@ -599,7 +609,7 @@ xe_hwmon_energy_get(struct xe_hwmon *hwmon, int channel, long *energy) if (ret != sizeof(pmt_val)) { drm_warn(&hwmon->xe->drm, "energy read from pmt failed, ret %d\n", ret); *energy = 0; - return; + return ret < 0 ? ret : -EIO; } if (channel == CHANNEL_PKG) @@ -616,6 +626,7 @@ xe_hwmon_energy_get(struct xe_hwmon *hwmon, int channel, long *energy) *energy = mul_u64_u32_shr(ei->accum_energy, SF_ENERGY, hwmon->scl_shift_energy); + return 0; } static ssize_t @@ -641,7 +652,8 @@ xe_hwmon_power_max_interval_show(struct device *dev, struct device_attribute *at xe_log_err(hwmon->xe, HWMON, ret, "Power interval read fail, ch %d, attr %d, val 0x%08x\n", channel, power_attr, reg_val); - reg_val = 0; + mutex_unlock(&hwmon->hwmon_lock); + return ret; } } else { reg_val = xe_mmio_read32(mmio, xe_hwmon_get_reg(hwmon, REG_PKG_RAPL_LIMIT, @@ -1438,7 +1450,8 @@ xe_hwmon_power_is_visible(struct xe_hwmon *hwmon, u32 attr, int channel) } case hwmon_power_crit: if (channel == CHANNEL_CARD) { - xe_hwmon_pcode_read_i1(hwmon, &uval); + if (xe_hwmon_pcode_read_i1(hwmon, &uval)) + return 0; return (uval & POWER_SETUP_I1_WATTS) ? 0644 : 0; } break; @@ -1457,7 +1470,8 @@ xe_hwmon_power_is_visible(struct xe_hwmon *hwmon, u32 attr, int channel) } } if ((!(uval & PWR_LIM_EN)) && channel == CHANNEL_CARD) { - xe_hwmon_pcode_read_i1(hwmon, &uval); + if (xe_hwmon_pcode_read_i1(hwmon, &uval)) + return 0; return (uval & POWER_SETUP_I1_WATTS) ? 0444 : 0; } return (uval) ? 0444 : 0; @@ -1473,11 +1487,9 @@ xe_hwmon_power_read(struct xe_hwmon *hwmon, u32 attr, int channel, long *val) switch (attr) { case hwmon_power_max: case hwmon_power_cap: - xe_hwmon_power_max_read(hwmon, attr, channel, val); - return 0; + return xe_hwmon_power_max_read(hwmon, attr, channel, val); case hwmon_power_rated_max: - xe_hwmon_power_rated_max_read(hwmon, attr, channel, val); - return 0; + return xe_hwmon_power_rated_max_read(hwmon, attr, channel, val); case hwmon_power_crit: return xe_hwmon_power_curr_crit_read(hwmon, channel, val, SF_POWER); default: @@ -1594,8 +1606,7 @@ xe_hwmon_energy_read(struct xe_hwmon *hwmon, u32 attr, int channel, long *val) { switch (attr) { case hwmon_energy_input: - xe_hwmon_energy_get(hwmon, channel, val); - return 0; + return xe_hwmon_energy_get(hwmon, channel, val); default: return -EOPNOTSUPP; } |
