diff options
Diffstat (limited to 'drivers/hwmon/gpio-fan.c')
-rw-r--r-- | drivers/hwmon/gpio-fan.c | 77 |
1 files changed, 26 insertions, 51 deletions
diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c index 2ce8c44a0e07..2f4b01bda87c 100644 --- a/drivers/hwmon/gpio-fan.c +++ b/drivers/hwmon/gpio-fan.c | |||
@@ -41,7 +41,7 @@ struct gpio_fan_data { | |||
41 | int num_speed; | 41 | int num_speed; |
42 | struct gpio_fan_speed *speed; | 42 | struct gpio_fan_speed *speed; |
43 | int speed_index; | 43 | int speed_index; |
44 | #ifdef CONFIG_PM | 44 | #ifdef CONFIG_PM_SLEEP |
45 | int resume_speed; | 45 | int resume_speed; |
46 | #endif | 46 | #endif |
47 | bool pwm_enable; | 47 | bool pwm_enable; |
@@ -95,17 +95,17 @@ static int fan_alarm_init(struct gpio_fan_data *fan_data, | |||
95 | 95 | ||
96 | fan_data->alarm = alarm; | 96 | fan_data->alarm = alarm; |
97 | 97 | ||
98 | err = gpio_request(alarm->gpio, "GPIO fan alarm"); | 98 | err = devm_gpio_request(&pdev->dev, alarm->gpio, "GPIO fan alarm"); |
99 | if (err) | 99 | if (err) |
100 | return err; | 100 | return err; |
101 | 101 | ||
102 | err = gpio_direction_input(alarm->gpio); | 102 | err = gpio_direction_input(alarm->gpio); |
103 | if (err) | 103 | if (err) |
104 | goto err_free_gpio; | 104 | return err; |
105 | 105 | ||
106 | err = device_create_file(&pdev->dev, &dev_attr_fan1_alarm); | 106 | err = device_create_file(&pdev->dev, &dev_attr_fan1_alarm); |
107 | if (err) | 107 | if (err) |
108 | goto err_free_gpio; | 108 | return err; |
109 | 109 | ||
110 | /* | 110 | /* |
111 | * If the alarm GPIO don't support interrupts, just leave | 111 | * If the alarm GPIO don't support interrupts, just leave |
@@ -117,8 +117,8 @@ static int fan_alarm_init(struct gpio_fan_data *fan_data, | |||
117 | 117 | ||
118 | INIT_WORK(&fan_data->alarm_work, fan_alarm_notify); | 118 | INIT_WORK(&fan_data->alarm_work, fan_alarm_notify); |
119 | irq_set_irq_type(alarm_irq, IRQ_TYPE_EDGE_BOTH); | 119 | irq_set_irq_type(alarm_irq, IRQ_TYPE_EDGE_BOTH); |
120 | err = request_irq(alarm_irq, fan_alarm_irq_handler, IRQF_SHARED, | 120 | err = devm_request_irq(&pdev->dev, alarm_irq, fan_alarm_irq_handler, |
121 | "GPIO fan alarm", fan_data); | 121 | IRQF_SHARED, "GPIO fan alarm", fan_data); |
122 | if (err) | 122 | if (err) |
123 | goto err_free_sysfs; | 123 | goto err_free_sysfs; |
124 | 124 | ||
@@ -126,21 +126,14 @@ static int fan_alarm_init(struct gpio_fan_data *fan_data, | |||
126 | 126 | ||
127 | err_free_sysfs: | 127 | err_free_sysfs: |
128 | device_remove_file(&pdev->dev, &dev_attr_fan1_alarm); | 128 | device_remove_file(&pdev->dev, &dev_attr_fan1_alarm); |
129 | err_free_gpio: | ||
130 | gpio_free(alarm->gpio); | ||
131 | |||
132 | return err; | 129 | return err; |
133 | } | 130 | } |
134 | 131 | ||
135 | static void fan_alarm_free(struct gpio_fan_data *fan_data) | 132 | static void fan_alarm_free(struct gpio_fan_data *fan_data) |
136 | { | 133 | { |
137 | struct platform_device *pdev = fan_data->pdev; | 134 | struct platform_device *pdev = fan_data->pdev; |
138 | int alarm_irq = gpio_to_irq(fan_data->alarm->gpio); | ||
139 | 135 | ||
140 | if (alarm_irq >= 0) | ||
141 | free_irq(alarm_irq, fan_data); | ||
142 | device_remove_file(&pdev->dev, &dev_attr_fan1_alarm); | 136 | device_remove_file(&pdev->dev, &dev_attr_fan1_alarm); |
143 | gpio_free(fan_data->alarm->gpio); | ||
144 | } | 137 | } |
145 | 138 | ||
146 | /* | 139 | /* |
@@ -365,15 +358,14 @@ static int fan_ctrl_init(struct gpio_fan_data *fan_data, | |||
365 | int i, err; | 358 | int i, err; |
366 | 359 | ||
367 | for (i = 0; i < num_ctrl; i++) { | 360 | for (i = 0; i < num_ctrl; i++) { |
368 | err = gpio_request(ctrl[i], "GPIO fan control"); | 361 | err = devm_gpio_request(&pdev->dev, ctrl[i], |
362 | "GPIO fan control"); | ||
369 | if (err) | 363 | if (err) |
370 | goto err_free_gpio; | 364 | return err; |
371 | 365 | ||
372 | err = gpio_direction_output(ctrl[i], gpio_get_value(ctrl[i])); | 366 | err = gpio_direction_output(ctrl[i], gpio_get_value(ctrl[i])); |
373 | if (err) { | 367 | if (err) |
374 | gpio_free(ctrl[i]); | 368 | return err; |
375 | goto err_free_gpio; | ||
376 | } | ||
377 | } | 369 | } |
378 | 370 | ||
379 | fan_data->num_ctrl = num_ctrl; | 371 | fan_data->num_ctrl = num_ctrl; |
@@ -382,32 +374,18 @@ static int fan_ctrl_init(struct gpio_fan_data *fan_data, | |||
382 | fan_data->speed = pdata->speed; | 374 | fan_data->speed = pdata->speed; |
383 | fan_data->pwm_enable = true; /* Enable manual fan speed control. */ | 375 | fan_data->pwm_enable = true; /* Enable manual fan speed control. */ |
384 | fan_data->speed_index = get_fan_speed_index(fan_data); | 376 | fan_data->speed_index = get_fan_speed_index(fan_data); |
385 | if (fan_data->speed_index < 0) { | 377 | if (fan_data->speed_index < 0) |
386 | err = -ENODEV; | 378 | return -ENODEV; |
387 | goto err_free_gpio; | ||
388 | } | ||
389 | 379 | ||
390 | err = sysfs_create_group(&pdev->dev.kobj, &gpio_fan_ctrl_group); | 380 | err = sysfs_create_group(&pdev->dev.kobj, &gpio_fan_ctrl_group); |
391 | if (err) | ||
392 | goto err_free_gpio; | ||
393 | |||
394 | return 0; | ||
395 | |||
396 | err_free_gpio: | ||
397 | for (i = i - 1; i >= 0; i--) | ||
398 | gpio_free(ctrl[i]); | ||
399 | |||
400 | return err; | 381 | return err; |
401 | } | 382 | } |
402 | 383 | ||
403 | static void fan_ctrl_free(struct gpio_fan_data *fan_data) | 384 | static void fan_ctrl_free(struct gpio_fan_data *fan_data) |
404 | { | 385 | { |
405 | struct platform_device *pdev = fan_data->pdev; | 386 | struct platform_device *pdev = fan_data->pdev; |
406 | int i; | ||
407 | 387 | ||
408 | sysfs_remove_group(&pdev->dev.kobj, &gpio_fan_ctrl_group); | 388 | sysfs_remove_group(&pdev->dev.kobj, &gpio_fan_ctrl_group); |
409 | for (i = 0; i < fan_data->num_ctrl; i++) | ||
410 | gpio_free(fan_data->ctrl[i]); | ||
411 | } | 389 | } |
412 | 390 | ||
413 | /* | 391 | /* |
@@ -431,7 +409,8 @@ static int __devinit gpio_fan_probe(struct platform_device *pdev) | |||
431 | if (!pdata) | 409 | if (!pdata) |
432 | return -EINVAL; | 410 | return -EINVAL; |
433 | 411 | ||
434 | fan_data = kzalloc(sizeof(struct gpio_fan_data), GFP_KERNEL); | 412 | fan_data = devm_kzalloc(&pdev->dev, sizeof(struct gpio_fan_data), |
413 | GFP_KERNEL); | ||
435 | if (!fan_data) | 414 | if (!fan_data) |
436 | return -ENOMEM; | 415 | return -ENOMEM; |
437 | 416 | ||
@@ -443,7 +422,7 @@ static int __devinit gpio_fan_probe(struct platform_device *pdev) | |||
443 | if (pdata->alarm) { | 422 | if (pdata->alarm) { |
444 | err = fan_alarm_init(fan_data, pdata->alarm); | 423 | err = fan_alarm_init(fan_data, pdata->alarm); |
445 | if (err) | 424 | if (err) |
446 | goto err_free_data; | 425 | return err; |
447 | } | 426 | } |
448 | 427 | ||
449 | /* Configure control GPIOs if available. */ | 428 | /* Configure control GPIOs if available. */ |
@@ -480,10 +459,6 @@ err_free_ctrl: | |||
480 | err_free_alarm: | 459 | err_free_alarm: |
481 | if (fan_data->alarm) | 460 | if (fan_data->alarm) |
482 | fan_alarm_free(fan_data); | 461 | fan_alarm_free(fan_data); |
483 | err_free_data: | ||
484 | platform_set_drvdata(pdev, NULL); | ||
485 | kfree(fan_data); | ||
486 | |||
487 | return err; | 462 | return err; |
488 | } | 463 | } |
489 | 464 | ||
@@ -497,15 +472,14 @@ static int __devexit gpio_fan_remove(struct platform_device *pdev) | |||
497 | fan_alarm_free(fan_data); | 472 | fan_alarm_free(fan_data); |
498 | if (fan_data->ctrl) | 473 | if (fan_data->ctrl) |
499 | fan_ctrl_free(fan_data); | 474 | fan_ctrl_free(fan_data); |
500 | kfree(fan_data); | ||
501 | 475 | ||
502 | return 0; | 476 | return 0; |
503 | } | 477 | } |
504 | 478 | ||
505 | #ifdef CONFIG_PM | 479 | #ifdef CONFIG_PM_SLEEP |
506 | static int gpio_fan_suspend(struct platform_device *pdev, pm_message_t state) | 480 | static int gpio_fan_suspend(struct device *dev) |
507 | { | 481 | { |
508 | struct gpio_fan_data *fan_data = platform_get_drvdata(pdev); | 482 | struct gpio_fan_data *fan_data = dev_get_drvdata(dev); |
509 | 483 | ||
510 | if (fan_data->ctrl) { | 484 | if (fan_data->ctrl) { |
511 | fan_data->resume_speed = fan_data->speed_index; | 485 | fan_data->resume_speed = fan_data->speed_index; |
@@ -515,27 +489,28 @@ static int gpio_fan_suspend(struct platform_device *pdev, pm_message_t state) | |||
515 | return 0; | 489 | return 0; |
516 | } | 490 | } |
517 | 491 | ||
518 | static int gpio_fan_resume(struct platform_device *pdev) | 492 | static int gpio_fan_resume(struct device *dev) |
519 | { | 493 | { |
520 | struct gpio_fan_data *fan_data = platform_get_drvdata(pdev); | 494 | struct gpio_fan_data *fan_data = dev_get_drvdata(dev); |
521 | 495 | ||
522 | if (fan_data->ctrl) | 496 | if (fan_data->ctrl) |
523 | set_fan_speed(fan_data, fan_data->resume_speed); | 497 | set_fan_speed(fan_data, fan_data->resume_speed); |
524 | 498 | ||
525 | return 0; | 499 | return 0; |
526 | } | 500 | } |
501 | |||
502 | static SIMPLE_DEV_PM_OPS(gpio_fan_pm, gpio_fan_suspend, gpio_fan_resume); | ||
503 | #define GPIO_FAN_PM &gpio_fan_pm | ||
527 | #else | 504 | #else |
528 | #define gpio_fan_suspend NULL | 505 | #define GPIO_FAN_PM NULL |
529 | #define gpio_fan_resume NULL | ||
530 | #endif | 506 | #endif |
531 | 507 | ||
532 | static struct platform_driver gpio_fan_driver = { | 508 | static struct platform_driver gpio_fan_driver = { |
533 | .probe = gpio_fan_probe, | 509 | .probe = gpio_fan_probe, |
534 | .remove = __devexit_p(gpio_fan_remove), | 510 | .remove = __devexit_p(gpio_fan_remove), |
535 | .suspend = gpio_fan_suspend, | ||
536 | .resume = gpio_fan_resume, | ||
537 | .driver = { | 511 | .driver = { |
538 | .name = "gpio-fan", | 512 | .name = "gpio-fan", |
513 | .pm = GPIO_FAN_PM, | ||
539 | }, | 514 | }, |
540 | }; | 515 | }; |
541 | 516 | ||