summaryrefslogtreecommitdiff
path: root/drivers/video/backlight/pwm_bl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/backlight/pwm_bl.c')
-rw-r--r--drivers/video/backlight/pwm_bl.c80
1 files changed, 46 insertions, 34 deletions
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index a51fbab96368..237d3d3f3bb1 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -11,7 +11,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/fb.h>
#include <linux/backlight.h>
#include <linux/err.h>
#include <linux/pwm.h>
@@ -34,7 +33,6 @@ struct pwm_bl_data {
int brightness);
void (*notify_after)(struct device *,
int brightness);
- int (*check_fb)(struct device *, struct fb_info *);
void (*exit)(struct device *);
};
@@ -103,7 +101,7 @@ static int pwm_backlight_update_status(struct backlight_device *bl)
pwm_get_state(pb->pwm, &state);
state.duty_cycle = compute_duty_cycle(pb, brightness, &state);
state.enabled = true;
- pwm_apply_state(pb->pwm, &state);
+ pwm_apply_might_sleep(pb->pwm, &state);
pwm_backlight_power_on(pb);
} else {
@@ -120,7 +118,7 @@ static int pwm_backlight_update_status(struct backlight_device *bl)
* inactive output.
*/
state.enabled = !pb->power_supply && !pb->enable_gpio;
- pwm_apply_state(pb->pwm, &state);
+ pwm_apply_might_sleep(pb->pwm, &state);
}
if (pb->notify_after)
@@ -129,17 +127,8 @@ static int pwm_backlight_update_status(struct backlight_device *bl)
return 0;
}
-static int pwm_backlight_check_fb(struct backlight_device *bl,
- struct fb_info *info)
-{
- struct pwm_bl_data *pb = bl_get_data(bl);
-
- return !pb->check_fb || pb->check_fb(pb->dev, info);
-}
-
static const struct backlight_ops pwm_backlight_ops = {
.update_status = pwm_backlight_update_status,
- .check_fb = pwm_backlight_check_fb,
};
#ifdef CONFIG_OF
@@ -437,7 +426,7 @@ static int pwm_backlight_initial_power_state(const struct pwm_bl_data *pb)
/* Not booted with device tree or no phandle link to the node */
if (!node || !node->phandle)
- return FB_BLANK_UNBLANK;
+ return BACKLIGHT_POWER_ON;
/*
* If the driver is probed from the device tree and there is a
@@ -445,7 +434,7 @@ static int pwm_backlight_initial_power_state(const struct pwm_bl_data *pb)
* assume that another driver will enable the backlight at the
* appropriate time. Therefore, if it is disabled, keep it so.
*/
- return active ? FB_BLANK_UNBLANK: FB_BLANK_POWERDOWN;
+ return active ? BACKLIGHT_POWER_ON : BACKLIGHT_POWER_OFF;
}
static int pwm_backlight_probe(struct platform_device *pdev)
@@ -461,10 +450,9 @@ static int pwm_backlight_probe(struct platform_device *pdev)
if (!data) {
ret = pwm_backlight_parse_dt(&pdev->dev, &defdata);
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to find platform data\n");
- return ret;
- }
+ if (ret < 0)
+ return dev_err_probe(&pdev->dev, ret,
+ "failed to find platform data\n");
data = &defdata;
}
@@ -483,7 +471,6 @@ static int pwm_backlight_probe(struct platform_device *pdev)
pb->notify = data->notify;
pb->notify_after = data->notify_after;
- pb->check_fb = data->check_fb;
pb->exit = data->exit;
pb->dev = &pdev->dev;
pb->enabled = false;
@@ -493,24 +480,27 @@ static int pwm_backlight_probe(struct platform_device *pdev)
pb->enable_gpio = devm_gpiod_get_optional(&pdev->dev, "enable",
GPIOD_ASIS);
if (IS_ERR(pb->enable_gpio)) {
- ret = PTR_ERR(pb->enable_gpio);
+ ret = dev_err_probe(&pdev->dev, PTR_ERR(pb->enable_gpio),
+ "failed to acquire enable GPIO\n");
goto err_alloc;
}
pb->power_supply = devm_regulator_get_optional(&pdev->dev, "power");
if (IS_ERR(pb->power_supply)) {
ret = PTR_ERR(pb->power_supply);
- if (ret == -ENODEV)
+ if (ret == -ENODEV) {
pb->power_supply = NULL;
- else
+ } else {
+ dev_err_probe(&pdev->dev, ret,
+ "failed to acquire power regulator\n");
goto err_alloc;
+ }
}
pb->pwm = devm_pwm_get(&pdev->dev, NULL);
if (IS_ERR(pb->pwm)) {
- ret = PTR_ERR(pb->pwm);
- if (ret != -EPROBE_DEFER)
- dev_err(&pdev->dev, "unable to request PWM\n");
+ ret = dev_err_probe(&pdev->dev, PTR_ERR(pb->pwm),
+ "unable to request PWM\n");
goto err_alloc;
}
@@ -528,10 +518,10 @@ static int pwm_backlight_probe(struct platform_device *pdev)
if (!state.period && (data->pwm_period_ns > 0))
state.period = data->pwm_period_ns;
- ret = pwm_apply_state(pb->pwm, &state);
+ ret = pwm_apply_might_sleep(pb->pwm, &state);
if (ret) {
- dev_err(&pdev->dev, "failed to apply initial PWM state: %d\n",
- ret);
+ dev_err_probe(&pdev->dev, ret,
+ "failed to apply initial PWM state");
goto err_alloc;
}
@@ -568,8 +558,8 @@ static int pwm_backlight_probe(struct platform_device *pdev)
ret = pwm_backlight_brightness_default(&pdev->dev, data,
state.period);
if (ret < 0) {
- dev_err(&pdev->dev,
- "failed to setup default brightness table\n");
+ dev_err_probe(&pdev->dev, ret,
+ "failed to setup default brightness table\n");
goto err_alloc;
}
@@ -597,8 +587,8 @@ static int pwm_backlight_probe(struct platform_device *pdev)
bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb,
&pwm_backlight_ops, &props);
if (IS_ERR(bl)) {
- dev_err(&pdev->dev, "failed to register backlight\n");
- ret = PTR_ERR(bl);
+ ret = dev_err_probe(&pdev->dev, PTR_ERR(bl),
+ "failed to register backlight\n");
goto err_alloc;
}
@@ -626,9 +616,14 @@ static void pwm_backlight_remove(struct platform_device *pdev)
{
struct backlight_device *bl = platform_get_drvdata(pdev);
struct pwm_bl_data *pb = bl_get_data(bl);
+ struct pwm_state state;
backlight_device_unregister(bl);
pwm_backlight_power_off(pb);
+ pwm_get_state(pb->pwm, &state);
+ state.duty_cycle = 0;
+ state.enabled = false;
+ pwm_apply_might_sleep(pb->pwm, &state);
if (pb->exit)
pb->exit(&pdev->dev);
@@ -638,8 +633,13 @@ static void pwm_backlight_shutdown(struct platform_device *pdev)
{
struct backlight_device *bl = platform_get_drvdata(pdev);
struct pwm_bl_data *pb = bl_get_data(bl);
+ struct pwm_state state;
pwm_backlight_power_off(pb);
+ pwm_get_state(pb->pwm, &state);
+ state.duty_cycle = 0;
+ state.enabled = false;
+ pwm_apply_might_sleep(pb->pwm, &state);
}
#ifdef CONFIG_PM_SLEEP
@@ -647,12 +647,24 @@ static int pwm_backlight_suspend(struct device *dev)
{
struct backlight_device *bl = dev_get_drvdata(dev);
struct pwm_bl_data *pb = bl_get_data(bl);
+ struct pwm_state state;
if (pb->notify)
pb->notify(pb->dev, 0);
pwm_backlight_power_off(pb);
+ /*
+ * Note that disabling the PWM doesn't guarantee that the output stays
+ * at its inactive state. However without the PWM disabled, the PWM
+ * driver refuses to suspend. So disable here even though this might
+ * enable the backlight on poorly designed boards.
+ */
+ pwm_get_state(pb->pwm, &state);
+ state.duty_cycle = 0;
+ state.enabled = false;
+ pwm_apply_might_sleep(pb->pwm, &state);
+
if (pb->notify_after)
pb->notify_after(pb->dev, 0);
@@ -685,7 +697,7 @@ static struct platform_driver pwm_backlight_driver = {
.of_match_table = of_match_ptr(pwm_backlight_of_match),
},
.probe = pwm_backlight_probe,
- .remove_new = pwm_backlight_remove,
+ .remove = pwm_backlight_remove,
.shutdown = pwm_backlight_shutdown,
};