mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
pinctrl: mediatek: use devm_gpiochip_add_data() for GPIO chip
The gpio_chip is allocated with device-managed memory but registered with the non-managed gpiochip_add_data(). This was harmless while the drivers were built-in, but once they can be built as modules and unbound/rmmod'd, devm frees the gpio_chip's memory while it is still registered, causing a use-after-free. Register it with devm_gpiochip_add_data() so it shares the same device-managed lifecycle, which also lets the manual gpiochip_remove() error paths go away. Fixes:a6df410d42("pinctrl: mediatek: Add Pinctrl/GPIO driver for mt8135.") Fixes:805250982b("pinctrl: mediatek: add pinctrl-paris that implements the vendor dt-bindings") Fixes:e78d57b2f8("pinctrl: mediatek: add pinctrl-moore that implements the generic pinctrl dt-bindings") Signed-off-by: Justin Yeh <justin.yeh@mediatek.com> Reviewed-by: Chen-Yu Tsai <wenst@chromium.org> Signed-off-by: Linus Walleij <linusw@kernel.org>
This commit is contained in:
parent
a2fd5a9f09
commit
9c650317ba
|
|
@ -594,7 +594,7 @@ static int mtk_build_gpiochip(struct mtk_pinctrl *hw)
|
|||
chip->base = -1;
|
||||
chip->ngpio = hw->soc->npins;
|
||||
|
||||
ret = gpiochip_add_data(chip, hw);
|
||||
ret = devm_gpiochip_add_data(hw->dev, chip, hw);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
@ -608,10 +608,8 @@ static int mtk_build_gpiochip(struct mtk_pinctrl *hw)
|
|||
if (!of_property_present(hw->dev->of_node, "gpio-ranges")) {
|
||||
ret = gpiochip_add_pin_range(chip, dev_name(hw->dev), 0, 0,
|
||||
chip->ngpio);
|
||||
if (ret < 0) {
|
||||
gpiochip_remove(chip);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1130,30 +1130,24 @@ int mtk_pctrl_init(struct platform_device *pdev,
|
|||
pctl->chip->parent = &pdev->dev;
|
||||
pctl->chip->base = -1;
|
||||
|
||||
ret = gpiochip_add_data(pctl->chip, pctl);
|
||||
ret = devm_gpiochip_add_data(&pdev->dev, pctl->chip, pctl);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
/* Register the GPIO to pin mappings. */
|
||||
ret = gpiochip_add_pin_range(pctl->chip, dev_name(&pdev->dev),
|
||||
0, 0, pctl->devdata->npins);
|
||||
if (ret) {
|
||||
ret = -EINVAL;
|
||||
goto chip_error;
|
||||
}
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
/* Only initialize EINT if we have EINT pins */
|
||||
if (data->eint_hw.ap_num > 0) {
|
||||
ret = mtk_eint_init(pctl, pdev);
|
||||
if (ret)
|
||||
goto chip_error;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
chip_error:
|
||||
gpiochip_remove(pctl->chip);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mtk_pctrl_common_probe(struct platform_device *pdev)
|
||||
|
|
|
|||
|
|
@ -957,7 +957,7 @@ static int mtk_build_gpiochip(struct mtk_pinctrl *hw)
|
|||
chip->base = -1;
|
||||
chip->ngpio = hw->soc->npins;
|
||||
|
||||
ret = gpiochip_add_data(chip, hw);
|
||||
ret = devm_gpiochip_add_data(hw->dev, chip, hw);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user