Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

pinctrl: pinconf-generic: Handle string values for generic properties

Allow a generic pinconf property to specify its argument as one of
the strings in a match list.
Convert the matching string to an integer value using the index in
the list, then keep using this value in the generic pinconf code.

Signed-off-by: Antonio Borneo <antonio.borneo@foss.st.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Antonio Borneo and committed by
Linus Walleij
90a18c51 4a6cc965

+50 -18
+41 -16
drivers/pinctrl/pinconf-generic.c
··· 65 65 int i; 66 66 67 67 for (i = 0; i < nitems; i++) { 68 + const struct pin_config_item *item = &items[i]; 68 69 unsigned long config; 69 70 int ret; 70 71 71 72 /* We want to check out this parameter */ 72 - config = pinconf_to_config_packed(items[i].param, 0); 73 + config = pinconf_to_config_packed(item->param, 0); 73 74 if (gname) 74 75 ret = pin_config_group_get(dev_name(pctldev->dev), 75 76 gname, &config); ··· 87 86 if (*print_sep) 88 87 seq_puts(s, ", "); 89 88 *print_sep = 1; 90 - seq_puts(s, items[i].display); 89 + seq_puts(s, item->display); 91 90 /* Print unit if available */ 92 - if (items[i].has_arg) { 91 + if (item->has_arg) { 93 92 u32 val = pinconf_to_config_argument(config); 94 93 95 - if (items[i].format) 96 - seq_printf(s, " (%u %s)", val, items[i].format); 94 + if (item->format) 95 + seq_printf(s, " (%u %s)", val, item->format); 97 96 else 98 97 seq_printf(s, " (0x%x)", val); 98 + 99 + if (item->values && item->num_values) { 100 + if (val < item->num_values) 101 + seq_printf(s, " \"%s\"", item->values[val]); 102 + else 103 + seq_puts(s, " \"(unknown)\""); 104 + } 99 105 } 100 106 } 101 107 } ··· 213 205 * @ncfg. @ncfg is updated to reflect the number of entries after parsing. @cfg 214 206 * needs to have enough memory allocated to hold all possible entries. 215 207 */ 216 - static void parse_dt_cfg(struct device_node *np, 217 - const struct pinconf_generic_params *params, 218 - unsigned int count, unsigned long *cfg, 219 - unsigned int *ncfg) 208 + static int parse_dt_cfg(struct device_node *np, 209 + const struct pinconf_generic_params *params, 210 + unsigned int count, unsigned long *cfg, 211 + unsigned int *ncfg) 220 212 { 221 213 int i; 222 214 ··· 225 217 int ret; 226 218 const struct pinconf_generic_params *par = &params[i]; 227 219 228 - ret = of_property_read_u32(np, par->property, &val); 220 + if (par->values && par->num_values) { 221 + ret = fwnode_property_match_property_string(of_fwnode_handle(np), 222 + par->property, 223 + par->values, par->num_values); 224 + if (ret == -ENOENT) 225 + return ret; 226 + if (ret >= 0) { 227 + val = ret; 228 + ret = 0; 229 + } 230 + } else { 231 + ret = of_property_read_u32(np, par->property, &val); 232 + } 229 233 230 234 /* property not found */ 231 235 if (ret == -EINVAL) ··· 251 231 cfg[*ncfg] = pinconf_to_config_packed(par->param, val); 252 232 (*ncfg)++; 253 233 } 234 + 235 + return 0; 254 236 } 255 237 256 238 /** ··· 345 323 if (!cfg) 346 324 return -ENOMEM; 347 325 348 - parse_dt_cfg(np, dt_params, ARRAY_SIZE(dt_params), cfg, &ncfg); 326 + ret = parse_dt_cfg(np, dt_params, ARRAY_SIZE(dt_params), cfg, &ncfg); 327 + if (ret) 328 + return ret; 349 329 if (pctldev && pctldev->desc->num_custom_params && 350 - pctldev->desc->custom_params) 351 - parse_dt_cfg(np, pctldev->desc->custom_params, 352 - pctldev->desc->num_custom_params, cfg, &ncfg); 353 - 354 - ret = 0; 330 + pctldev->desc->custom_params) { 331 + ret = parse_dt_cfg(np, pctldev->desc->custom_params, 332 + pctldev->desc->num_custom_params, cfg, &ncfg); 333 + if (ret) 334 + return ret; 335 + } 355 336 356 337 /* no configs found at all */ 357 338 if (ncfg == 0) {
+9 -2
include/linux/pinctrl/pinconf-generic.h
··· 181 181 return PIN_CONF_PACKED(param, argument); 182 182 } 183 183 184 - #define PCONFDUMP(a, b, c, d) { \ 185 - .param = a, .display = b, .format = c, .has_arg = d \ 184 + #define PCONFDUMP_WITH_VALUES(a, b, c, d, e, f) { \ 185 + .param = a, .display = b, .format = c, .has_arg = d, \ 186 + .values = e, .num_values = f \ 186 187 } 188 + 189 + #define PCONFDUMP(a, b, c, d) PCONFDUMP_WITH_VALUES(a, b, c, d, NULL, 0) 187 190 188 191 struct pin_config_item { 189 192 const enum pin_config_param param; 190 193 const char * const display; 191 194 const char * const format; 192 195 bool has_arg; 196 + const char * const *values; 197 + size_t num_values; 193 198 }; 194 199 195 200 struct pinconf_generic_params { 196 201 const char * const property; 197 202 enum pin_config_param param; 198 203 u32 default_value; 204 + const char * const *values; 205 + size_t num_values; 199 206 }; 200 207 201 208 int pinconf_generic_dt_subnode_to_map(struct pinctrl_dev *pctldev,