summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLijo Lazar <lijo.lazar@amd.com>2026-05-19 19:29:20 +0530
committerAlex Deucher <alexander.deucher@amd.com>2026-07-01 11:08:33 -0400
commitb68f1654927fe841e71816933d0b50efb4f0196d (patch)
tree9d3a9f23b061e2fe66693cf1f3fdced0e67a8d6b
parentd077a0d57c6d151866c4914e7890b6117d255c61 (diff)
downloadlinux-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.c116
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, &params[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, &parameter[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), &parameter_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, &parameter[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,
+ &parameter_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, &params[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),
&parameter_size);
if (ret)