pinctrl: mediatek: common-v2: Fix bias-disable for PULL_PU_PD_RSEL_TYPE
authorAngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Fri, 4 Nov 2022 10:56:05 +0000 (11:56 +0100)
committerLinus Walleij <linus.walleij@linaro.org>
Wed, 9 Nov 2022 08:34:38 +0000 (09:34 +0100)
In pinctrl-paris we're calling the .bias_set_combo() callback when we
are asked to set the pin bias to either pull up/down or pull disable.

On newer platforms, this callback is mtk_pinconf_bias_set_combo(),
located in pinctrl-mtk-common-v2.c: this will check the "pull type"
assigned to the requested pin and in case said pin's pull type is
MTK_PULL_PU_PD_RSEL_TYPE, this function will set RSEL first, PUPD
last, which is fine.

The issue comes when we're requesting PIN_CONFIG_BIAS_DISABLE, as
this does *not* require setting RSEL but only PU_PD: in this case,
the arg is MTK_DISABLE (zero), which is not a supported RSEL, due
to which function mtk_pinconf_bias_set_rsel() returns a failure;
because of that, mtk_pinconf_bias_set_pu_pd() is never called,
hence the pin bias is never set to DISABLE.

To fix this issue, add a check to mtk_pinconf_bias_set_rsel(): if
we are entering that function with no pullup requested and at the
same time the arg is MTK_DISABLE, this means that we're trying to
disable pin bias, hence it's safe to return cleanly without ever
setting any RSEL register.
This makes mtk_pinconf_bias_set_combo() happy, going on with setting
the PU_PD registers, which is the only action to actually take to
disable bias on a pin/pingroup.

Fixes: fb34a9ae383a ("pinctrl: mediatek: support rsel feature")
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://lore.kernel.org/r/20221104105605.33720-1-angelogioacchino.delregno@collabora.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c

index e1ae3beb9f72b07ab9977259f4fd78979242e140..b7921b59eb7b15f720fbfe65837cf6bfc876ee9c 100644 (file)
@@ -709,6 +709,9 @@ static int mtk_pinconf_bias_set_rsel(struct mtk_pinctrl *hw,
 {
        int err, rsel_val;
 
+       if (!pullup && arg == MTK_DISABLE)
+               return 0;
+
        if (hw->rsel_si_unit) {
                /* find pin rsel_index from pin_rsel array*/
                err = mtk_hw_pin_rsel_lookup(hw, desc, pullup, arg, &rsel_val);