Skip to content

Commit 001d7ef

Browse files
mukeshojha-linuxLinus Walleij
authored andcommitted
pinctrl: Fix the clean up on pinconf_apply_setting failure
When some client does devm_pinctrl_get() followed by pinctrl_select_state() that does pinmux first successfully and later during config setting it sets the wrong drive strenght to the pin due to which pinconf_apply_setting fails. Currently, on failure during config setting is implemented as if pinmux has failed for one of the pin but that does not seem right and need to undo the pinmux for all the pin if config setting fails. Current commit does a bit refactor to reuse the code and tries to clean up mux setting on config setting failure. Signed-off-by: Mukesh Ojha <[email protected]> Link: https://lore.kernel.org/[email protected] Signed-off-by: Linus Walleij <[email protected]>
1 parent e4ee0ac commit 001d7ef

File tree

1 file changed

+30
-20
lines changed

1 file changed

+30
-20
lines changed

drivers/pinctrl/core.c

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,14 +1256,28 @@ static void pinctrl_link_add(struct pinctrl_dev *pctldev,
12561256
DL_FLAG_AUTOREMOVE_CONSUMER);
12571257
}
12581258

1259+
static void pinctrl_cond_disable_mux_setting(struct pinctrl_state *state,
1260+
struct pinctrl_setting *target_setting)
1261+
{
1262+
struct pinctrl_setting *setting;
1263+
1264+
list_for_each_entry(setting, &state->settings, node) {
1265+
if (target_setting && (&setting->node == &target_setting->node))
1266+
break;
1267+
1268+
if (setting->type == PIN_MAP_TYPE_MUX_GROUP)
1269+
pinmux_disable_setting(setting);
1270+
}
1271+
}
1272+
12591273
/**
12601274
* pinctrl_commit_state() - select/activate/program a pinctrl state to HW
12611275
* @p: the pinctrl handle for the device that requests configuration
12621276
* @state: the state handle to select/activate/program
12631277
*/
12641278
static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
12651279
{
1266-
struct pinctrl_setting *setting, *setting2;
1280+
struct pinctrl_setting *setting;
12671281
struct pinctrl_state *old_state = READ_ONCE(p->state);
12681282
int ret;
12691283

@@ -1274,11 +1288,7 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
12741288
* still owned by the new state will be re-acquired by the call
12751289
* to pinmux_enable_setting() in the loop below.
12761290
*/
1277-
list_for_each_entry(setting, &old_state->settings, node) {
1278-
if (setting->type != PIN_MAP_TYPE_MUX_GROUP)
1279-
continue;
1280-
pinmux_disable_setting(setting);
1281-
}
1291+
pinctrl_cond_disable_mux_setting(old_state, NULL);
12821292
}
12831293

12841294
p->state = NULL;
@@ -1322,7 +1332,7 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
13221332
}
13231333

13241334
if (ret < 0) {
1325-
goto unapply_new_state;
1335+
goto unapply_mux_setting;
13261336
}
13271337

13281338
/* Do not link hogs (circular dependency) */
@@ -1334,23 +1344,23 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
13341344

13351345
return 0;
13361346

1347+
unapply_mux_setting:
1348+
pinctrl_cond_disable_mux_setting(state, NULL);
1349+
goto restore_old_state;
1350+
13371351
unapply_new_state:
13381352
dev_err(p->dev, "Error applying setting, reverse things back\n");
13391353

1340-
list_for_each_entry(setting2, &state->settings, node) {
1341-
if (&setting2->node == &setting->node)
1342-
break;
1343-
/*
1344-
* All we can do here is pinmux_disable_setting.
1345-
* That means that some pins are muxed differently now
1346-
* than they were before applying the setting (We can't
1347-
* "unmux a pin"!), but it's not a big deal since the pins
1348-
* are free to be muxed by another apply_setting.
1349-
*/
1350-
if (setting2->type == PIN_MAP_TYPE_MUX_GROUP)
1351-
pinmux_disable_setting(setting2);
1352-
}
1354+
/*
1355+
* All we can do here is pinmux_disable_setting.
1356+
* That means that some pins are muxed differently now
1357+
* than they were before applying the setting (We can't
1358+
* "unmux a pin"!), but it's not a big deal since the pins
1359+
* are free to be muxed by another apply_setting.
1360+
*/
1361+
pinctrl_cond_disable_mux_setting(state, setting);
13531362

1363+
restore_old_state:
13541364
/* There's no infinite recursive loop here because p->state is NULL */
13551365
if (old_state)
13561366
pinctrl_select_state(p, old_state);

0 commit comments

Comments
 (0)