diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2014-04-06 18:20:08 -0400 |
---|---|---|
committer | Bryan Wu <cooloney@gmail.com> | 2014-05-08 02:28:07 -0400 |
commit | 5f7b03dc2ab5f4ca16e5d6bc3e6dcd2953c6fede (patch) | |
tree | b60d1bab4279494cce35d711300c6f0b5ffd3c5e /drivers/leds | |
parent | 2ce112f1e788a695630e2c275f47d57a801673d3 (diff) |
leds: leds-pwm: provide a common function to setup a single led-pwm device
Provide a common function to setup a single led-pwm device, replacing
the platform data initialisation path with this function. This allows
us to have a common method of creating these devices in a consistent
manner, which then allows us to place the probe failure cleanup in one
place.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Bryan Wu <cooloney@gmail.com>
Diffstat (limited to 'drivers/leds')
-rw-r--r-- | drivers/leds/leds-pwm.c | 85 |
1 files changed, 46 insertions, 39 deletions
diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c index 7d0aaed1e23a..203e332967b2 100644 --- a/drivers/leds/leds-pwm.c +++ b/drivers/leds/leds-pwm.c | |||
@@ -92,6 +92,44 @@ static void led_pwm_cleanup(struct led_pwm_priv *priv) | |||
92 | } | 92 | } |
93 | } | 93 | } |
94 | 94 | ||
95 | static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv, | ||
96 | struct led_pwm *led) | ||
97 | { | ||
98 | struct led_pwm_data *led_data = &priv->leds[priv->num_leds]; | ||
99 | int ret; | ||
100 | |||
101 | led_data->active_low = led->active_low; | ||
102 | led_data->period = led->pwm_period_ns; | ||
103 | led_data->cdev.name = led->name; | ||
104 | led_data->cdev.default_trigger = led->default_trigger; | ||
105 | led_data->cdev.brightness_set = led_pwm_set; | ||
106 | led_data->cdev.brightness = LED_OFF; | ||
107 | led_data->cdev.max_brightness = led->max_brightness; | ||
108 | led_data->cdev.flags = LED_CORE_SUSPENDRESUME; | ||
109 | |||
110 | led_data->pwm = devm_pwm_get(dev, led->name); | ||
111 | if (IS_ERR(led_data->pwm)) { | ||
112 | ret = PTR_ERR(led_data->pwm); | ||
113 | dev_err(dev, "unable to request PWM for %s: %d\n", | ||
114 | led->name, ret); | ||
115 | return ret; | ||
116 | } | ||
117 | |||
118 | led_data->can_sleep = pwm_can_sleep(led_data->pwm); | ||
119 | if (led_data->can_sleep) | ||
120 | INIT_WORK(&led_data->work, led_pwm_work); | ||
121 | |||
122 | ret = led_classdev_register(dev, &led_data->cdev); | ||
123 | if (ret == 0) { | ||
124 | priv->num_leds++; | ||
125 | } else { | ||
126 | dev_err(dev, "failed to register PWM led for %s: %d\n", | ||
127 | led->name, ret); | ||
128 | } | ||
129 | |||
130 | return ret; | ||
131 | } | ||
132 | |||
95 | static int led_pwm_create_of(struct platform_device *pdev, | 133 | static int led_pwm_create_of(struct platform_device *pdev, |
96 | struct led_pwm_priv *priv) | 134 | struct led_pwm_priv *priv) |
97 | { | 135 | { |
@@ -139,8 +177,6 @@ static int led_pwm_create_of(struct platform_device *pdev, | |||
139 | 177 | ||
140 | return 0; | 178 | return 0; |
141 | err: | 179 | err: |
142 | led_pwm_cleanup(priv); | ||
143 | |||
144 | return ret; | 180 | return ret; |
145 | } | 181 | } |
146 | 182 | ||
@@ -166,51 +202,22 @@ static int led_pwm_probe(struct platform_device *pdev) | |||
166 | 202 | ||
167 | if (pdata) { | 203 | if (pdata) { |
168 | for (i = 0; i < count; i++) { | 204 | for (i = 0; i < count; i++) { |
169 | struct led_pwm *cur_led = &pdata->leds[i]; | 205 | ret = led_pwm_add(&pdev->dev, priv, &pdata->leds[i]); |
170 | struct led_pwm_data *led_dat = &priv->leds[i]; | 206 | if (ret) |
171 | 207 | break; | |
172 | led_dat->pwm = devm_pwm_get(&pdev->dev, cur_led->name); | ||
173 | if (IS_ERR(led_dat->pwm)) { | ||
174 | ret = PTR_ERR(led_dat->pwm); | ||
175 | dev_err(&pdev->dev, | ||
176 | "unable to request PWM for %s\n", | ||
177 | cur_led->name); | ||
178 | goto err; | ||
179 | } | ||
180 | |||
181 | led_dat->cdev.name = cur_led->name; | ||
182 | led_dat->cdev.default_trigger = cur_led->default_trigger; | ||
183 | led_dat->active_low = cur_led->active_low; | ||
184 | led_dat->period = cur_led->pwm_period_ns; | ||
185 | led_dat->cdev.brightness_set = led_pwm_set; | ||
186 | led_dat->cdev.brightness = LED_OFF; | ||
187 | led_dat->cdev.max_brightness = cur_led->max_brightness; | ||
188 | led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; | ||
189 | |||
190 | led_dat->can_sleep = pwm_can_sleep(led_dat->pwm); | ||
191 | if (led_dat->can_sleep) | ||
192 | INIT_WORK(&led_dat->work, led_pwm_work); | ||
193 | |||
194 | ret = led_classdev_register(&pdev->dev, &led_dat->cdev); | ||
195 | if (ret < 0) | ||
196 | goto err; | ||
197 | } | 208 | } |
198 | priv->num_leds = count; | ||
199 | } else { | 209 | } else { |
200 | ret = led_pwm_create_of(pdev, priv); | 210 | ret = led_pwm_create_of(pdev, priv); |
201 | if (ret) | 211 | } |
202 | return ret; | 212 | |
213 | if (ret) { | ||
214 | led_pwm_cleanup(priv); | ||
215 | return ret; | ||
203 | } | 216 | } |
204 | 217 | ||
205 | platform_set_drvdata(pdev, priv); | 218 | platform_set_drvdata(pdev, priv); |
206 | 219 | ||
207 | return 0; | 220 | return 0; |
208 | |||
209 | err: | ||
210 | priv->num_leds = i; | ||
211 | led_pwm_cleanup(priv); | ||
212 | |||
213 | return ret; | ||
214 | } | 221 | } |
215 | 222 | ||
216 | static int led_pwm_remove(struct platform_device *pdev) | 223 | static int led_pwm_remove(struct platform_device *pdev) |