aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/backlight/pwm_bl.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index 9637f5e08cb6..8346dfc01cf6 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -23,6 +23,7 @@
23struct pwm_bl_data { 23struct pwm_bl_data {
24 struct pwm_device *pwm; 24 struct pwm_device *pwm;
25 unsigned int period; 25 unsigned int period;
26 int (*notify)(int brightness);
26}; 27};
27 28
28static int pwm_backlight_update_status(struct backlight_device *bl) 29static int pwm_backlight_update_status(struct backlight_device *bl)
@@ -37,6 +38,9 @@ static int pwm_backlight_update_status(struct backlight_device *bl)
37 if (bl->props.fb_blank != FB_BLANK_UNBLANK) 38 if (bl->props.fb_blank != FB_BLANK_UNBLANK)
38 brightness = 0; 39 brightness = 0;
39 40
41 if (pb->notify)
42 brightness = pb->notify(brightness);
43
40 if (brightness == 0) { 44 if (brightness == 0) {
41 pwm_config(pb->pwm, 0, pb->period); 45 pwm_config(pb->pwm, 0, pb->period);
42 pwm_disable(pb->pwm); 46 pwm_disable(pb->pwm);
@@ -62,30 +66,39 @@ static int pwm_backlight_probe(struct platform_device *pdev)
62 struct platform_pwm_backlight_data *data = pdev->dev.platform_data; 66 struct platform_pwm_backlight_data *data = pdev->dev.platform_data;
63 struct backlight_device *bl; 67 struct backlight_device *bl;
64 struct pwm_bl_data *pb; 68 struct pwm_bl_data *pb;
69 int ret;
65 70
66 if (!data) 71 if (!data)
67 return -EINVAL; 72 return -EINVAL;
68 73
74 if (data->init) {
75 ret = data->init(&pdev->dev);
76 if (ret < 0)
77 return ret;
78 }
79
69 pb = kzalloc(sizeof(*pb), GFP_KERNEL); 80 pb = kzalloc(sizeof(*pb), GFP_KERNEL);
70 if (!pb) 81 if (!pb) {
71 return -ENOMEM; 82 ret = -ENOMEM;
83 goto err_alloc;
84 }
72 85
73 pb->period = data->pwm_period_ns; 86 pb->period = data->pwm_period_ns;
87 pb->notify = data->notify;
74 88
75 pb->pwm = pwm_request(data->pwm_id, "backlight"); 89 pb->pwm = pwm_request(data->pwm_id, "backlight");
76 if (pb->pwm == NULL) { 90 if (pb->pwm == NULL) {
77 dev_err(&pdev->dev, "unable to request PWM for backlight\n"); 91 dev_err(&pdev->dev, "unable to request PWM for backlight\n");
78 kfree(pb); 92 ret = -EBUSY;
79 return -EBUSY; 93 goto err_pwm;
80 } 94 }
81 95
82 bl = backlight_device_register(pdev->name, &pdev->dev, 96 bl = backlight_device_register(pdev->name, &pdev->dev,
83 pb, &pwm_backlight_ops); 97 pb, &pwm_backlight_ops);
84 if (IS_ERR(bl)) { 98 if (IS_ERR(bl)) {
85 dev_err(&pdev->dev, "failed to register backlight\n"); 99 dev_err(&pdev->dev, "failed to register backlight\n");
86 pwm_free(pb->pwm); 100 ret = PTR_ERR(bl);
87 kfree(pb); 101 goto err_bl;
88 return PTR_ERR(bl);
89 } 102 }
90 103
91 bl->props.max_brightness = data->max_brightness; 104 bl->props.max_brightness = data->max_brightness;
@@ -94,10 +107,20 @@ static int pwm_backlight_probe(struct platform_device *pdev)
94 107
95 platform_set_drvdata(pdev, bl); 108 platform_set_drvdata(pdev, bl);
96 return 0; 109 return 0;
110
111err_bl:
112 pwm_free(pb->pwm);
113err_pwm:
114 kfree(pb);
115err_alloc:
116 if (data->exit)
117 data->exit(&pdev->dev);
118 return ret;
97} 119}
98 120
99static int pwm_backlight_remove(struct platform_device *pdev) 121static int pwm_backlight_remove(struct platform_device *pdev)
100{ 122{
123 struct platform_pwm_backlight_data *data = pdev->dev.platform_data;
101 struct backlight_device *bl = platform_get_drvdata(pdev); 124 struct backlight_device *bl = platform_get_drvdata(pdev);
102 struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); 125 struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev);
103 126
@@ -106,6 +129,8 @@ static int pwm_backlight_remove(struct platform_device *pdev)
106 pwm_disable(pb->pwm); 129 pwm_disable(pb->pwm);
107 pwm_free(pb->pwm); 130 pwm_free(pb->pwm);
108 kfree(pb); 131 kfree(pb);
132 if (data->exit)
133 data->exit(&pdev->dev);
109 return 0; 134 return 0;
110} 135}
111 136