3434#include <linux/of.h>
3535#include <linux/of_platform.h>
3636#include <linux/of_gpio.h>
37+ #include <linux/thermal.h>
3738
3839struct gpio_fan_data {
3940 struct platform_device * pdev ;
4041 struct device * hwmon_dev ;
42+ /* Cooling device if any */
43+ struct thermal_cooling_device * cdev ;
4144 struct mutex lock ; /* lock GPIOs operations. */
4245 int num_ctrl ;
4346 unsigned * ctrl ;
@@ -387,6 +390,53 @@ static int fan_ctrl_init(struct gpio_fan_data *fan_data,
387390 return 0 ;
388391}
389392
393+ static int gpio_fan_get_max_state (struct thermal_cooling_device * cdev ,
394+ unsigned long * state )
395+ {
396+ struct gpio_fan_data * fan_data = cdev -> devdata ;
397+
398+ if (!fan_data )
399+ return - EINVAL ;
400+
401+ * state = fan_data -> num_speed - 1 ;
402+ return 0 ;
403+ }
404+
405+ static int gpio_fan_get_cur_state (struct thermal_cooling_device * cdev ,
406+ unsigned long * state )
407+ {
408+ struct gpio_fan_data * fan_data = cdev -> devdata ;
409+ int r ;
410+
411+ if (!fan_data )
412+ return - EINVAL ;
413+
414+ r = get_fan_speed_index (fan_data );
415+ if (r < 0 )
416+ return r ;
417+
418+ * state = r ;
419+ return 0 ;
420+ }
421+
422+ static int gpio_fan_set_cur_state (struct thermal_cooling_device * cdev ,
423+ unsigned long state )
424+ {
425+ struct gpio_fan_data * fan_data = cdev -> devdata ;
426+
427+ if (!fan_data )
428+ return - EINVAL ;
429+
430+ set_fan_speed (fan_data , state );
431+ return 0 ;
432+ }
433+
434+ static const struct thermal_cooling_device_ops gpio_fan_cool_ops = {
435+ .get_max_state = gpio_fan_get_max_state ,
436+ .get_cur_state = gpio_fan_get_cur_state ,
437+ .set_cur_state = gpio_fan_set_cur_state ,
438+ };
439+
390440#ifdef CONFIG_OF_GPIO
391441/*
392442 * Translate OpenFirmware node properties into platform_data
@@ -497,6 +547,11 @@ static int gpio_fan_probe(struct platform_device *pdev)
497547 struct gpio_fan_data * fan_data ;
498548 struct gpio_fan_platform_data * pdata = dev_get_platdata (& pdev -> dev );
499549
550+ fan_data = devm_kzalloc (& pdev -> dev , sizeof (struct gpio_fan_data ),
551+ GFP_KERNEL );
552+ if (!fan_data )
553+ return - ENOMEM ;
554+
500555#ifdef CONFIG_OF_GPIO
501556 if (!pdata ) {
502557 pdata = devm_kzalloc (& pdev -> dev ,
@@ -508,17 +563,20 @@ static int gpio_fan_probe(struct platform_device *pdev)
508563 err = gpio_fan_get_of_pdata (& pdev -> dev , pdata );
509564 if (err )
510565 return err ;
566+ /* Optional cooling device register for Device tree platforms */
567+ fan_data -> cdev =
568+ thermal_of_cooling_device_register (pdev -> dev .of_node ,
569+ "gpio-fan" , fan_data ,
570+ & gpio_fan_cool_ops );
511571 }
512572#else /* CONFIG_OF_GPIO */
513573 if (!pdata )
514574 return - EINVAL ;
575+ /* Optional cooling device register for non Device tree platforms */
576+ fan_data -> cdev = thermal_cooling_device_register ("gpio-fan" , fan_data ,
577+ & gpio_fan_cool_ops );
515578#endif /* CONFIG_OF_GPIO */
516579
517- fan_data = devm_kzalloc (& pdev -> dev , sizeof (struct gpio_fan_data ),
518- GFP_KERNEL );
519- if (!fan_data )
520- return - ENOMEM ;
521-
522580 fan_data -> pdev = pdev ;
523581 platform_set_drvdata (pdev , fan_data );
524582 mutex_init (& fan_data -> lock );
@@ -552,12 +610,22 @@ static int gpio_fan_probe(struct platform_device *pdev)
552610 return 0 ;
553611}
554612
555- static void gpio_fan_shutdown (struct platform_device * pdev )
613+ static int gpio_fan_remove (struct platform_device * pdev )
556614{
557- struct gpio_fan_data * fan_data = dev_get_drvdata (& pdev -> dev );
615+ struct gpio_fan_data * fan_data = platform_get_drvdata (pdev );
616+
617+ if (!IS_ERR (fan_data -> cdev ))
618+ thermal_cooling_device_unregister (fan_data -> cdev );
558619
559620 if (fan_data -> ctrl )
560621 set_fan_speed (fan_data , 0 );
622+
623+ return 0 ;
624+ }
625+
626+ static void gpio_fan_shutdown (struct platform_device * pdev )
627+ {
628+ gpio_fan_remove (pdev );
561629}
562630
563631#ifdef CONFIG_PM_SLEEP
@@ -591,6 +659,7 @@ static SIMPLE_DEV_PM_OPS(gpio_fan_pm, gpio_fan_suspend, gpio_fan_resume);
591659
592660static struct platform_driver gpio_fan_driver = {
593661 .probe = gpio_fan_probe ,
662+ .remove = gpio_fan_remove ,
594663 .shutdown = gpio_fan_shutdown ,
595664 .driver = {
596665 .name = "gpio-fan" ,
0 commit comments