From d8e63b8fd9ef90ec936b944d46d90a4fb843d109 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Mon, 25 Mar 2013 15:47:22 +0100 Subject: [PATCH] --- yaml --- r: 362989 b: refs/heads/master c: 3102a76cfbf9ac4ae0cf54c7452f7ba4292a4760 h: refs/heads/master i: 362987: e54269c741784a1802514b125bea1eec6a01ebd4 v: v3 --- [refs] | 2 +- trunk/drivers/pinctrl/core.c | 28 +++++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index 859fe5acb625..0461006b9bc1 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: d3cee8305b48316ea416a73c763be3cb04bbc82b +refs/heads/master: 3102a76cfbf9ac4ae0cf54c7452f7ba4292a4760 diff --git a/trunk/drivers/pinctrl/core.c b/trunk/drivers/pinctrl/core.c index 971234599d72..09f79f251800 100644 --- a/trunk/drivers/pinctrl/core.c +++ b/trunk/drivers/pinctrl/core.c @@ -930,7 +930,7 @@ static int pinctrl_select_state_locked(struct pinctrl *p, } } - p->state = state; + p->state = NULL; /* Apply all the settings for the new state */ list_for_each_entry(setting, &state->settings, node) { @@ -946,13 +946,35 @@ static int pinctrl_select_state_locked(struct pinctrl *p, ret = -EINVAL; break; } + if (ret < 0) { - /* FIXME: Difficult to return to prev state */ - return ret; + goto unapply_new_state; } } + p->state = state; + return 0; + +unapply_new_state: + pr_info("Error applying setting, reverse things back\n"); + + /* + * If the loop stopped on the 1st entry, nothing has been enabled, + * so jump directly to the 2nd phase + */ + if (list_entry(&setting->node, typeof(*setting), node) == + list_first_entry(&state->settings, typeof(*setting), node)) + goto reapply_old_state; + + list_for_each_entry(setting2, &state->settings, node) { + if (&setting2->node == &setting->node) + break; + pinctrl_free_setting(true, setting2); + } +reapply_old_state: + /* FIXME: re-enable old setting */ + return ret; } /**