| From 5f05e996d70edb7fdc8510680d7f287c44654511 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 21 May 2021 13:21:01 +0200 |
| Subject: leds: ktd2692: Fix an error handling path |
| |
| From: Christophe JAILLET <christophe.jaillet@wanadoo.fr> |
| |
| [ Upstream commit ee78b9360e14c276f5ceaa4a0d06f790f04ccdad ] |
| |
| In 'ktd2692_parse_dt()', if an error occurs after a successful |
| 'regulator_enable()' call, we should call 'regulator_enable()'. |
| |
| This is the same in 'ktd2692_probe()', if an error occurs after a |
| successful 'ktd2692_parse_dt()' call. |
| |
| Instead of adding 'regulator_enable()' in several places, implement a |
| resource managed solution and simplify the remove function accordingly. |
| |
| Fixes: b7da8c5c725c ("leds: Add ktd2692 flash LED driver") |
| Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr> |
| Signed-off-by: Pavel Machek <pavel@ucw.cz> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/leds/leds-ktd2692.c | 27 ++++++++++++++++++--------- |
| 1 file changed, 18 insertions(+), 9 deletions(-) |
| |
| diff --git a/drivers/leds/leds-ktd2692.c b/drivers/leds/leds-ktd2692.c |
| index 632f10db4b3f..f341da1503a4 100644 |
| --- a/drivers/leds/leds-ktd2692.c |
| +++ b/drivers/leds/leds-ktd2692.c |
| @@ -256,6 +256,17 @@ static void ktd2692_setup(struct ktd2692_context *led) |
| | KTD2692_REG_FLASH_CURRENT_BASE); |
| } |
| |
| +static void regulator_disable_action(void *_data) |
| +{ |
| + struct device *dev = _data; |
| + struct ktd2692_context *led = dev_get_drvdata(dev); |
| + int ret; |
| + |
| + ret = regulator_disable(led->regulator); |
| + if (ret) |
| + dev_err(dev, "Failed to disable supply: %d\n", ret); |
| +} |
| + |
| static int ktd2692_parse_dt(struct ktd2692_context *led, struct device *dev, |
| struct ktd2692_led_config_data *cfg) |
| { |
| @@ -286,8 +297,14 @@ static int ktd2692_parse_dt(struct ktd2692_context *led, struct device *dev, |
| |
| if (led->regulator) { |
| ret = regulator_enable(led->regulator); |
| - if (ret) |
| + if (ret) { |
| dev_err(dev, "Failed to enable supply: %d\n", ret); |
| + } else { |
| + ret = devm_add_action_or_reset(dev, |
| + regulator_disable_action, dev); |
| + if (ret) |
| + return ret; |
| + } |
| } |
| |
| child_node = of_get_next_available_child(np, NULL); |
| @@ -377,17 +394,9 @@ static int ktd2692_probe(struct platform_device *pdev) |
| static int ktd2692_remove(struct platform_device *pdev) |
| { |
| struct ktd2692_context *led = platform_get_drvdata(pdev); |
| - int ret; |
| |
| led_classdev_flash_unregister(&led->fled_cdev); |
| |
| - if (led->regulator) { |
| - ret = regulator_disable(led->regulator); |
| - if (ret) |
| - dev_err(&pdev->dev, |
| - "Failed to disable supply: %d\n", ret); |
| - } |
| - |
| mutex_destroy(&led->lock); |
| |
| return 0; |
| -- |
| 2.30.2 |
| |