You need to sign in or sign up before continuing.
提交 bc3322bc 编写于 作者: F Fabio Estevam 提交者: Linus Walleij

pinctrl: devicetree: Fix pctldev pointer overwrite

Commit b89405b6 ("pinctrl: devicetree: Fix dt_to_map_one_config
handling of hogs") causes the pinctrl hog pins to not get initialized
on i.MX platforms leaving them with the IOMUX settings untouched.

This causes several regressions on i.MX such as:

- OV5640 camera driver can not be probed anymore on imx6qdl-sabresd
because the camera clock pin is in a pinctrl_hog group and since
its pinctrl initialization is skipped, the camera clock is kept
in GPIO functionality instead of CLK_CKO function.

- Audio stopped working on imx6qdl-wandboard and imx53-qsb for
the same reason.

Richard Fitzgerald explains the problem:

"I see the bug. If the hog node isn't a 1st level child of the pinctrl
parent node it will go around the for(;;) loop again but on the first
pass I overwrite pctldev with the result of
get_pinctrl_dev_from_of_node() so it doesn't point to the pinctrl driver
any more."

Fix the issue by stashing the original pctldev so it doesn't
get overwritten.

Fixes:  b89405b6 ("pinctrl: devicetree: Fix dt_to_map_one_config handling of hogs")
Cc: <stable@vger.kernel.org>
Reported-by: NMika Penttilä <mika.penttila@nextfour.com>
Reported-by: NSteve Longerbeam <slongerbeam@gmail.com>
Suggested-by: NRichard Fitzgerald <rf@opensource.cirrus.com>
Signed-off-by: NFabio Estevam <fabio.estevam@nxp.com>
Reviewed-by: NDong Aisheng <aisheng.dong@nxp.com>
Reviewed-by: NRichard Fitzgerald <rf@opensource.cirrus.com>
Signed-off-by: NLinus Walleij <linus.walleij@linaro.org>
上级 fb7298e1
......@@ -101,10 +101,11 @@ struct pinctrl_dev *of_pinctrl_get(struct device_node *np)
}
static int dt_to_map_one_config(struct pinctrl *p,
struct pinctrl_dev *pctldev,
struct pinctrl_dev *hog_pctldev,
const char *statename,
struct device_node *np_config)
{
struct pinctrl_dev *pctldev = NULL;
struct device_node *np_pctldev;
const struct pinctrl_ops *ops;
int ret;
......@@ -123,8 +124,10 @@ static int dt_to_map_one_config(struct pinctrl *p,
return -EPROBE_DEFER;
}
/* If we're creating a hog we can use the passed pctldev */
if (pctldev && (np_pctldev == p->dev->of_node))
if (hog_pctldev && (np_pctldev == p->dev->of_node)) {
pctldev = hog_pctldev;
break;
}
pctldev = get_pinctrl_dev_from_of_node(np_pctldev);
if (pctldev)
break;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册