diff options
| author | Lijo Lazar <lijo.lazar@amd.com> | 2026-05-19 19:29:20 +0530 |
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2026-07-01 11:08:33 -0400 |
| commit | b68f1654927fe841e71816933d0b50efb4f0196d (patch) | |
| tree | 9d3a9f23b061e2fe66693cf1f3fdced0e67a8d6b | |
| parent | d077a0d57c6d151866c4914e7890b6117d255c61 (diff) | |
| download | linux-stable-b68f1654927fe841e71816933d0b50efb4f0196d.tar.gz linux-stable-b68f1654927fe841e71816933d0b50efb4f0196d.zip | |
drm/amd/pm: Add helper for parameter parsing
Add a helper function to extract long values passed in a string. The
string may have values of multiple parameters separated by space char.
Signed-off-by: Lijo Lazar <lijo.lazar@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
| -rw-r--r-- | drivers/gpu/drm/amd/pm/amdgpu_pm.c | 116 |
1 files changed, 48 insertions, 68 deletions
diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c index f43d09769320..538b6736e9f8 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -98,6 +98,37 @@ const char * const amdgpu_pp_profile_name[] = { "UNCAPPED", }; +static int amdgpu_pm_parse_long_params(char *str, long *params, + uint32_t max_params, + uint32_t *num_params) +{ + const char delimiter[] = { ' ', '\n', '\0' }; + uint32_t count = 0; + char *sub_str; + int ret; + + if (!params || !num_params) + return -EINVAL; + + while ((sub_str = strsep(&str, delimiter)) != NULL) { + if (strlen(sub_str) == 0) + continue; + if (count >= max_params) + return -EINVAL; + ret = kstrtol(sub_str, 0, ¶ms[count]); + if (ret) + return -EINVAL; + count++; + if (!str) + break; + while (isspace(*str)) + str++; + } + *num_params = count; + + return 0; +} + /** * amdgpu_pm_dev_state_check - Check if device can be accessed. * @adev: Target device. @@ -767,8 +798,6 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev, long parameter[64]; char buf_cpy[128]; char *tmp_str; - char *sub_str; - const char delimiter[3] = {' ', '\n', '\0'}; uint32_t type; if (count > 127 || count == 0) @@ -803,22 +832,10 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev, tmp_str++; while (isspace(*++tmp_str)); - while ((sub_str = strsep(&tmp_str, delimiter)) != NULL) { - if (strlen(sub_str) == 0) - continue; - if (parameter_size >= ARRAY_SIZE(parameter)) - return -EINVAL; - ret = kstrtol(sub_str, 0, ¶meter[parameter_size]); - if (ret) - return -EINVAL; - parameter_size++; - - if (!tmp_str) - break; - - while (isspace(*tmp_str)) - tmp_str++; - } + ret = amdgpu_pm_parse_long_params( + tmp_str, parameter, ARRAY_SIZE(parameter), ¶meter_size); + if (ret) + return ret; ret = amdgpu_pm_get_access(adev); if (ret < 0) @@ -1391,11 +1408,9 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev, struct amdgpu_device *adev = drm_to_adev(ddev); uint32_t parameter_size = 0; long parameter[64]; - char *sub_str, buf_cpy[128]; - char *tmp_str; + char buf_cpy[128]; char tmp[2]; long int profile_mode = 0; - const char delimiter[3] = {' ', '\n', '\0'}; /* Reject empty/whitespace strings - fuzzing found this is not validated */ if (count == 0 || sysfs_streq(buf, "")) @@ -1413,19 +1428,11 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev, while (isspace(*buf)) buf++; strscpy(buf_cpy, buf, sizeof(buf_cpy)); - tmp_str = buf_cpy; - while ((sub_str = strsep(&tmp_str, delimiter)) != NULL) { - if (strlen(sub_str) == 0) - continue; - ret = kstrtol(sub_str, 0, ¶meter[parameter_size]); - if (ret) - return -EINVAL; - parameter_size++; - if (!tmp_str) - break; - while (isspace(*tmp_str)) - tmp_str++; - } + ret = amdgpu_pm_parse_long_params(buf_cpy, parameter, + ARRAY_SIZE(parameter) - 1, + ¶meter_size); + if (ret) + return ret; } parameter[parameter_size] = profile_mode; @@ -3954,18 +3961,14 @@ out_pm_put: return size; } -static int parse_input_od_command_lines(const char *buf, - size_t count, - u32 *type, - long *params, - size_t params_max, +static int parse_input_od_command_lines(const char *buf, size_t count, + u32 *type, long *params, + uint32_t max_params, uint32_t *num_of_params) { - const char delimiter[3] = {' ', '\n', '\0'}; uint32_t parameter_size = 0; char buf_cpy[128] = {0}; - char *tmp_str, *sub_str; - int ret; + char *tmp_str; if (count > sizeof(buf_cpy) - 1) return -EINVAL; @@ -3990,28 +3993,8 @@ static int parse_input_od_command_lines(const char *buf, break; } - while ((sub_str = strsep(&tmp_str, delimiter)) != NULL) { - if (strlen(sub_str) == 0) - continue; - - if (parameter_size >= params_max) - return -EINVAL; - - ret = kstrtol(sub_str, 0, ¶ms[parameter_size]); - if (ret) - return -EINVAL; - parameter_size++; - - if (!tmp_str) - break; - - while (isspace(*tmp_str)) - tmp_str++; - } - - *num_of_params = parameter_size; - - return 0; + return amdgpu_pm_parse_long_params(tmp_str, params, max_params, + num_of_params); } static int @@ -4024,10 +4007,7 @@ amdgpu_distribute_custom_od_settings(struct amdgpu_device *adev, long parameter[64]; int ret; - ret = parse_input_od_command_lines(in_buf, - count, - &cmd_type, - parameter, + ret = parse_input_od_command_lines(in_buf, count, &cmd_type, parameter, ARRAY_SIZE(parameter), ¶meter_size); if (ret) |
