aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2019-04-18 15:58:20 -0400
committerEduardo Valentin <edubezval@gmail.com>2019-05-14 10:00:47 -0400
commit37bcec5d9f71bd13142a97d2196b293c9ac23823 (patch)
tree0350c5a1d8edcee93c0e48b8d204d361d7547300
parent0b2a785db8797db08181f71395a412c8eedbc614 (diff)
hwmon: (pwm-fan) Use devm_thermal_of_cooling_device_register
Use devm_thermal_of_cooling_device_register() to register the cooling device. Also use devm_add_action_or_reset() to stop the fan on device removal, and to disable the pwm. Introduce a local 'dev' variable in the probe function to make the code easier to read. As a side effect, this fixes a bug seen if pwm_fan_of_get_cooling_data() returned an error. In that situation, the pwm was not disabled, and the fan was not stopped. Using devm functions also ensures that the pwm is disabled and that the fan is stopped only after the hwmon device has been unregistered. Cc: Lukasz Majewski <l.majewski@samsung.com> Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
-rw-r--r--drivers/hwmon/pwm-fan.c73
1 files changed, 29 insertions, 44 deletions
diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c
index 167221c7628a..0243ba70107e 100644
--- a/drivers/hwmon/pwm-fan.c
+++ b/drivers/hwmon/pwm-fan.c
@@ -207,33 +207,44 @@ static int pwm_fan_of_get_cooling_data(struct device *dev,
207 return 0; 207 return 0;
208} 208}
209 209
210static void pwm_fan_regulator_disable(void *data)
211{
212 regulator_disable(data);
213}
214
215static void pwm_fan_pwm_disable(void *data)
216{
217 pwm_disable(data);
218}
219
210static int pwm_fan_probe(struct platform_device *pdev) 220static int pwm_fan_probe(struct platform_device *pdev)
211{ 221{
212 struct thermal_cooling_device *cdev; 222 struct thermal_cooling_device *cdev;
223 struct device *dev = &pdev->dev;
213 struct pwm_fan_ctx *ctx; 224 struct pwm_fan_ctx *ctx;
214 struct device *hwmon; 225 struct device *hwmon;
215 int ret; 226 int ret;
216 struct pwm_state state = { }; 227 struct pwm_state state = { };
217 228
218 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); 229 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
219 if (!ctx) 230 if (!ctx)
220 return -ENOMEM; 231 return -ENOMEM;
221 232
222 mutex_init(&ctx->lock); 233 mutex_init(&ctx->lock);
223 234
224 ctx->pwm = devm_of_pwm_get(&pdev->dev, pdev->dev.of_node, NULL); 235 ctx->pwm = devm_of_pwm_get(dev, dev->of_node, NULL);
225 if (IS_ERR(ctx->pwm)) { 236 if (IS_ERR(ctx->pwm)) {
226 ret = PTR_ERR(ctx->pwm); 237 ret = PTR_ERR(ctx->pwm);
227 238
228 if (ret != -EPROBE_DEFER) 239 if (ret != -EPROBE_DEFER)
229 dev_err(&pdev->dev, "Could not get PWM: %d\n", ret); 240 dev_err(dev, "Could not get PWM: %d\n", ret);
230 241
231 return ret; 242 return ret;
232 } 243 }
233 244
234 platform_set_drvdata(pdev, ctx); 245 platform_set_drvdata(pdev, ctx);
235 246
236 ctx->reg_en = devm_regulator_get_optional(&pdev->dev, "fan"); 247 ctx->reg_en = devm_regulator_get_optional(dev, "fan");
237 if (IS_ERR(ctx->reg_en)) { 248 if (IS_ERR(ctx->reg_en)) {
238 if (PTR_ERR(ctx->reg_en) != -ENODEV) 249 if (PTR_ERR(ctx->reg_en) != -ENODEV)
239 return PTR_ERR(ctx->reg_en); 250 return PTR_ERR(ctx->reg_en);
@@ -242,10 +253,11 @@ static int pwm_fan_probe(struct platform_device *pdev)
242 } else { 253 } else {
243 ret = regulator_enable(ctx->reg_en); 254 ret = regulator_enable(ctx->reg_en);
244 if (ret) { 255 if (ret) {
245 dev_err(&pdev->dev, 256 dev_err(dev, "Failed to enable fan supply: %d\n", ret);
246 "Failed to enable fan supply: %d\n", ret);
247 return ret; 257 return ret;
248 } 258 }
259 devm_add_action_or_reset(dev, pwm_fan_regulator_disable,
260 ctx->reg_en);
249 } 261 }
250 262
251 ctx->pwm_value = MAX_PWM; 263 ctx->pwm_value = MAX_PWM;
@@ -257,62 +269,36 @@ static int pwm_fan_probe(struct platform_device *pdev)
257 269
258 ret = pwm_apply_state(ctx->pwm, &state); 270 ret = pwm_apply_state(ctx->pwm, &state);
259 if (ret) { 271 if (ret) {
260 dev_err(&pdev->dev, "Failed to configure PWM\n"); 272 dev_err(dev, "Failed to configure PWM\n");
261 goto err_reg_disable; 273 return ret;
262 } 274 }
275 devm_add_action_or_reset(dev, pwm_fan_pwm_disable, ctx->pwm);
263 276
264 hwmon = devm_hwmon_device_register_with_groups(&pdev->dev, "pwmfan", 277 hwmon = devm_hwmon_device_register_with_groups(dev, "pwmfan",
265 ctx, pwm_fan_groups); 278 ctx, pwm_fan_groups);
266 if (IS_ERR(hwmon)) { 279 if (IS_ERR(hwmon)) {
267 dev_err(&pdev->dev, "Failed to register hwmon device\n"); 280 dev_err(dev, "Failed to register hwmon device\n");
268 ret = PTR_ERR(hwmon); 281 return PTR_ERR(hwmon);
269 goto err_pwm_disable;
270 } 282 }
271 283
272 ret = pwm_fan_of_get_cooling_data(&pdev->dev, ctx); 284 ret = pwm_fan_of_get_cooling_data(dev, ctx);
273 if (ret) 285 if (ret)
274 return ret; 286 return ret;
275 287
276 ctx->pwm_fan_state = ctx->pwm_fan_max_state; 288 ctx->pwm_fan_state = ctx->pwm_fan_max_state;
277 if (IS_ENABLED(CONFIG_THERMAL)) { 289 if (IS_ENABLED(CONFIG_THERMAL)) {
278 cdev = thermal_of_cooling_device_register(pdev->dev.of_node, 290 cdev = devm_thermal_of_cooling_device_register(dev,
279 "pwm-fan", ctx, 291 dev->of_node, "pwm-fan", ctx, &pwm_fan_cooling_ops);
280 &pwm_fan_cooling_ops);
281 if (IS_ERR(cdev)) { 292 if (IS_ERR(cdev)) {
282 dev_err(&pdev->dev, 293 dev_err(dev,
283 "Failed to register pwm-fan as cooling device"); 294 "Failed to register pwm-fan as cooling device");
284 ret = PTR_ERR(cdev); 295 return PTR_ERR(cdev);
285 goto err_pwm_disable;
286 } 296 }
287 ctx->cdev = cdev; 297 ctx->cdev = cdev;
288 thermal_cdev_update(cdev); 298 thermal_cdev_update(cdev);
289 } 299 }
290 300
291 return 0; 301 return 0;
292
293err_pwm_disable:
294 state.enabled = false;
295 pwm_apply_state(ctx->pwm, &state);
296
297err_reg_disable:
298 if (ctx->reg_en)
299 regulator_disable(ctx->reg_en);
300
301 return ret;
302}
303
304static int pwm_fan_remove(struct platform_device *pdev)
305{
306 struct pwm_fan_ctx *ctx = platform_get_drvdata(pdev);
307
308 thermal_cooling_device_unregister(ctx->cdev);
309 if (ctx->pwm_value)
310 pwm_disable(ctx->pwm);
311
312 if (ctx->reg_en)
313 regulator_disable(ctx->reg_en);
314
315 return 0;
316} 302}
317 303
318#ifdef CONFIG_PM_SLEEP 304#ifdef CONFIG_PM_SLEEP
@@ -380,7 +366,6 @@ MODULE_DEVICE_TABLE(of, of_pwm_fan_match);
380 366
381static struct platform_driver pwm_fan_driver = { 367static struct platform_driver pwm_fan_driver = {
382 .probe = pwm_fan_probe, 368 .probe = pwm_fan_probe,
383 .remove = pwm_fan_remove,
384 .driver = { 369 .driver = {
385 .name = "pwm-fan", 370 .name = "pwm-fan",
386 .pm = &pwm_fan_pm, 371 .pm = &pwm_fan_pm,