summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
diff options
context:
space:
mode:
authorNĂ­colas F. R. A. Prado <nfraprado@collabora.com>2024-08-09 01:27:09 +0200
committerLinus Walleij <linus.walleij@linaro.org>2024-08-23 18:07:14 +0200
commit166bf8af91225576f85208a31eaedbadd182d1ea (patch)
treeea533fb281e7ab35798b323e2f3c7f4819aeee30 /drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
parentpinctrl: single: fix potential NULL dereference in pcs_get_function() (diff)
downloadlinux-166bf8af91225576f85208a31eaedbadd182d1ea.tar.xz
linux-166bf8af91225576f85208a31eaedbadd182d1ea.zip
pinctrl: mediatek: common-v2: Fix broken bias-disable for PULL_PU_PD_RSEL_TYPE
Despite its name, commit fed74d75277d ("pinctrl: mediatek: common-v2: Fix bias-disable for PULL_PU_PD_RSEL_TYPE") actually broke bias-disable for PULL_PU_PD_RSEL_TYPE. mtk_pinconf_bias_set_combo() tries every bias method supported by the pin until one succeeds. For PULL_PU_PD_RSEL_TYPE pins, before the breaking commit, mtk_pinconf_bias_set_rsel() would be called first to try and set the RSEL value (as well as PU and PD), and if that failed, the only other valid option was that bias-disable was specified, which would then be handled by calling mtk_pinconf_bias_set_pu_pd() and disabling both PU and PD. The breaking commit misunderstood this logic and added an early "return 0" in mtk_pinconf_bias_set_rsel(). The result was that in the bias-disable case, the bias was left unchanged, since by returning success, mtk_pinconf_bias_set_combo() no longer tried calling mtk_pinconf_bias_set_pu_pd() to disable the bias. Since the logic for configuring bias-disable on PULL_PU_PD_RSEL_TYPE pins required mtk_pinconf_bias_set_rsel() to fail first, in that case, an error was printed to the log, eg: mt8195-pinctrl 10005000.pinctrl: Not support rsel value 0 Ohm for pin = 29 (GPIO29) This is what the breaking commit actually got rid of, and likely part of the reason why that commit was thought to be fixing functionality, while in reality it was breaking it. Instead of simply reverting that commit, restore the functionality but in a way that avoids the error from being printed and makes the code less confusing: * Return 0 explicitly if a bias method was successful * Introduce an extra function mtk_pinconf_bias_set_pu_pd_rsel() that calls both mtk_pinconf_bias_set_rsel() (only if needed) and mtk_pinconf_bias_set_pu_pd() * And analogously for the corresponding getters Fixes: fed74d75277d ("pinctrl: mediatek: common-v2: Fix bias-disable for PULL_PU_PD_RSEL_TYPE") Signed-off-by: NĂ­colas F. R. A. Prado <nfraprado@collabora.com> Link: https://lore.kernel.org/20240808-mtk-rsel-bias-disable-fix-v1-1-1b4e85bf596c@collabora.com Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c')
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c55
1 files changed, 29 insertions, 26 deletions
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index b7921b59eb7b..54301fbba524 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -709,32 +709,35 @@ 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);
if (err)
- goto out;
+ return err;
} else {
- if (arg < MTK_PULL_SET_RSEL_000 ||
- arg > MTK_PULL_SET_RSEL_111) {
- err = -EINVAL;
- goto out;
- }
+ if (arg < MTK_PULL_SET_RSEL_000 || arg > MTK_PULL_SET_RSEL_111)
+ return -EINVAL;
rsel_val = arg - MTK_PULL_SET_RSEL_000;
}
- err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_RSEL, rsel_val);
- if (err)
- goto out;
+ return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_RSEL, rsel_val);
+}
- err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, MTK_ENABLE);
+static int mtk_pinconf_bias_set_pu_pd_rsel(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ u32 pullup, u32 arg)
+{
+ u32 enable = arg == MTK_DISABLE ? MTK_DISABLE : MTK_ENABLE;
+ int err;
-out:
- return err;
+ if (arg != MTK_DISABLE) {
+ err = mtk_pinconf_bias_set_rsel(hw, desc, pullup, arg);
+ if (err)
+ return err;
+ }
+
+ return mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, enable);
}
int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
@@ -750,22 +753,22 @@ int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
try_all_type = MTK_PULL_TYPE_MASK;
if (try_all_type & MTK_PULL_RSEL_TYPE) {
- err = mtk_pinconf_bias_set_rsel(hw, desc, pullup, arg);
+ err = mtk_pinconf_bias_set_pu_pd_rsel(hw, desc, pullup, arg);
if (!err)
- return err;
+ return 0;
}
if (try_all_type & MTK_PULL_PU_PD_TYPE) {
err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
if (!err)
- return err;
+ return 0;
}
if (try_all_type & MTK_PULL_PULLSEL_TYPE) {
err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc,
pullup, arg);
if (!err)
- return err;
+ return 0;
}
if (try_all_type & MTK_PULL_PUPD_R1R0_TYPE)
@@ -803,9 +806,9 @@ static int mtk_rsel_get_si_unit(struct mtk_pinctrl *hw,
return 0;
}
-static int mtk_pinconf_bias_get_rsel(struct mtk_pinctrl *hw,
- const struct mtk_pin_desc *desc,
- u32 *pullup, u32 *enable)
+static int mtk_pinconf_bias_get_pu_pd_rsel(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ u32 *pullup, u32 *enable)
{
int pu, pd, rsel, err;
@@ -939,22 +942,22 @@ int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
try_all_type = MTK_PULL_TYPE_MASK;
if (try_all_type & MTK_PULL_RSEL_TYPE) {
- err = mtk_pinconf_bias_get_rsel(hw, desc, pullup, enable);
+ err = mtk_pinconf_bias_get_pu_pd_rsel(hw, desc, pullup, enable);
if (!err)
- return err;
+ return 0;
}
if (try_all_type & MTK_PULL_PU_PD_TYPE) {
err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
if (!err)
- return err;
+ return 0;
}
if (try_all_type & MTK_PULL_PULLSEL_TYPE) {
err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc,
pullup, enable);
if (!err)
- return err;
+ return 0;
}
if (try_all_type & MTK_PULL_PUPD_R1R0_TYPE)