Skip to content

Commit 90a18c5

Browse files
AntonioBorneoLinus Walleij
authored andcommitted
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>
1 parent 4a6cc96 commit 90a18c5

2 files changed

Lines changed: 50 additions & 18 deletions

File tree

drivers/pinctrl/pinconf-generic.c

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,12 @@ static void pinconf_generic_dump_one(struct pinctrl_dev *pctldev,
6565
int i;
6666

6767
for (i = 0; i < nitems; i++) {
68+
const struct pin_config_item *item = &items[i];
6869
unsigned long config;
6970
int ret;
7071

7172
/* 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);
7374
if (gname)
7475
ret = pin_config_group_get(dev_name(pctldev->dev),
7576
gname, &config);
@@ -86,15 +87,22 @@ static void pinconf_generic_dump_one(struct pinctrl_dev *pctldev,
8687
if (*print_sep)
8788
seq_puts(s, ", ");
8889
*print_sep = 1;
89-
seq_puts(s, items[i].display);
90+
seq_puts(s, item->display);
9091
/* Print unit if available */
91-
if (items[i].has_arg) {
92+
if (item->has_arg) {
9293
u32 val = pinconf_to_config_argument(config);
9394

94-
if (items[i].format)
95-
seq_printf(s, " (%u %s)", val, items[i].format);
95+
if (item->format)
96+
seq_printf(s, " (%u %s)", val, item->format);
9697
else
9798
seq_printf(s, " (0x%x)", val);
99+
100+
if (item->values && item->num_values) {
101+
if (val < item->num_values)
102+
seq_printf(s, " \"%s\"", item->values[val]);
103+
else
104+
seq_puts(s, " \"(unknown)\"");
105+
}
98106
}
99107
}
100108
}
@@ -205,10 +213,10 @@ static const struct pinconf_generic_params dt_params[] = {
205213
* @ncfg. @ncfg is updated to reflect the number of entries after parsing. @cfg
206214
* needs to have enough memory allocated to hold all possible entries.
207215
*/
208-
static void 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)
216+
static int 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)
212220
{
213221
int i;
214222

@@ -217,7 +225,19 @@ static void parse_dt_cfg(struct device_node *np,
217225
int ret;
218226
const struct pinconf_generic_params *par = &params[i];
219227

220-
ret = of_property_read_u32(np, par->property, &val);
228+
if (par->values && par->num_values) {
229+
ret = fwnode_property_match_property_string(of_fwnode_handle(np),
230+
par->property,
231+
par->values, par->num_values);
232+
if (ret == -ENOENT)
233+
return ret;
234+
if (ret >= 0) {
235+
val = ret;
236+
ret = 0;
237+
}
238+
} else {
239+
ret = of_property_read_u32(np, par->property, &val);
240+
}
221241

222242
/* property not found */
223243
if (ret == -EINVAL)
@@ -231,6 +251,8 @@ static void parse_dt_cfg(struct device_node *np,
231251
cfg[*ncfg] = pinconf_to_config_packed(par->param, val);
232252
(*ncfg)++;
233253
}
254+
255+
return 0;
234256
}
235257

236258
/**
@@ -323,13 +345,16 @@ int pinconf_generic_parse_dt_config(struct device_node *np,
323345
if (!cfg)
324346
return -ENOMEM;
325347

326-
parse_dt_cfg(np, dt_params, ARRAY_SIZE(dt_params), cfg, &ncfg);
348+
ret = parse_dt_cfg(np, dt_params, ARRAY_SIZE(dt_params), cfg, &ncfg);
349+
if (ret)
350+
return ret;
327351
if (pctldev && pctldev->desc->num_custom_params &&
328-
pctldev->desc->custom_params)
329-
parse_dt_cfg(np, pctldev->desc->custom_params,
330-
pctldev->desc->num_custom_params, cfg, &ncfg);
331-
332-
ret = 0;
352+
pctldev->desc->custom_params) {
353+
ret = parse_dt_cfg(np, pctldev->desc->custom_params,
354+
pctldev->desc->num_custom_params, cfg, &ncfg);
355+
if (ret)
356+
return ret;
357+
}
333358

334359
/* no configs found at all */
335360
if (ncfg == 0) {

include/linux/pinctrl/pinconf-generic.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,21 +181,28 @@ static inline unsigned long pinconf_to_config_packed(enum pin_config_param param
181181
return PIN_CONF_PACKED(param, argument);
182182
}
183183

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 \
186187
}
187188

189+
#define PCONFDUMP(a, b, c, d) PCONFDUMP_WITH_VALUES(a, b, c, d, NULL, 0)
190+
188191
struct pin_config_item {
189192
const enum pin_config_param param;
190193
const char * const display;
191194
const char * const format;
192195
bool has_arg;
196+
const char * const *values;
197+
size_t num_values;
193198
};
194199

195200
struct pinconf_generic_params {
196201
const char * const property;
197202
enum pin_config_param param;
198203
u32 default_value;
204+
const char * const *values;
205+
size_t num_values;
199206
};
200207

201208
int pinconf_generic_dt_subnode_to_map(struct pinctrl_dev *pctldev,

0 commit comments

Comments
 (0)