@@ -58,10 +58,47 @@ struct rcar_thermal_common {
58
58
spinlock_t lock ;
59
59
};
60
60
61
+ struct rcar_thermal_chip {
62
+ unsigned int use_of_thermal : 1 ;
63
+ unsigned int has_filonoff : 1 ;
64
+ unsigned int irq_per_ch : 1 ;
65
+ unsigned int needs_suspend_resume : 1 ;
66
+ unsigned int nirqs ;
67
+ };
68
+
69
+ static const struct rcar_thermal_chip rcar_thermal = {
70
+ .use_of_thermal = 0 ,
71
+ .has_filonoff = 1 ,
72
+ .irq_per_ch = 0 ,
73
+ .needs_suspend_resume = 0 ,
74
+ .nirqs = 1 ,
75
+ };
76
+
77
+ static const struct rcar_thermal_chip rcar_gen2_thermal = {
78
+ .use_of_thermal = 1 ,
79
+ .has_filonoff = 1 ,
80
+ .irq_per_ch = 0 ,
81
+ .needs_suspend_resume = 0 ,
82
+ .nirqs = 1 ,
83
+ };
84
+
85
+ static const struct rcar_thermal_chip rcar_gen3_thermal = {
86
+ .use_of_thermal = 1 ,
87
+ .has_filonoff = 0 ,
88
+ .irq_per_ch = 1 ,
89
+ .needs_suspend_resume = 1 ,
90
+ /*
91
+ * The Gen3 chip has 3 interrupts, but this driver uses only 2
92
+ * interrupts to detect a temperature change, rise or fall.
93
+ */
94
+ .nirqs = 2 ,
95
+ };
96
+
61
97
struct rcar_thermal_priv {
62
98
void __iomem * base ;
63
99
struct rcar_thermal_common * common ;
64
100
struct thermal_zone_device * zone ;
101
+ const struct rcar_thermal_chip * chip ;
65
102
struct delayed_work work ;
66
103
struct mutex lock ;
67
104
struct list_head list ;
@@ -77,13 +114,20 @@ struct rcar_thermal_priv {
77
114
#define rcar_priv_to_dev (priv ) ((priv)->common->dev)
78
115
#define rcar_has_irq_support (priv ) ((priv)->common->base)
79
116
#define rcar_id_to_shift (priv ) ((priv)->id * 8)
80
- #define rcar_of_data (dev ) ((unsigned long)of_device_get_match_data(dev))
81
- #define rcar_use_of_thermal (dev ) (rcar_of_data(dev) == USE_OF_THERMAL)
82
117
83
- #define USE_OF_THERMAL 1
84
118
static const struct of_device_id rcar_thermal_dt_ids [] = {
85
- { .compatible = "renesas,rcar-thermal" , },
86
- { .compatible = "renesas,rcar-gen2-thermal" , .data = (void * )USE_OF_THERMAL },
119
+ {
120
+ .compatible = "renesas,rcar-thermal" ,
121
+ .data = & rcar_thermal ,
122
+ },
123
+ {
124
+ .compatible = "renesas,rcar-gen2-thermal" ,
125
+ .data = & rcar_gen2_thermal ,
126
+ },
127
+ {
128
+ .compatible = "renesas,thermal-r8a77995" ,
129
+ .data = & rcar_gen3_thermal ,
130
+ },
87
131
{},
88
132
};
89
133
MODULE_DEVICE_TABLE (of , rcar_thermal_dt_ids );
@@ -190,7 +234,8 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv)
190
234
* enable IRQ
191
235
*/
192
236
if (rcar_has_irq_support (priv )) {
193
- rcar_thermal_write (priv , FILONOFF , 0 );
237
+ if (priv -> chip -> has_filonoff )
238
+ rcar_thermal_write (priv , FILONOFF , 0 );
194
239
195
240
/* enable Rising/Falling edge interrupt */
196
241
rcar_thermal_write (priv , POSNEG , 0x1 );
@@ -420,7 +465,7 @@ static int rcar_thermal_remove(struct platform_device *pdev)
420
465
421
466
rcar_thermal_for_each_priv (priv , common ) {
422
467
rcar_thermal_irq_disable (priv );
423
- if (rcar_use_of_thermal ( dev ) )
468
+ if (priv -> chip -> use_of_thermal )
424
469
thermal_remove_hwmon_sysfs (priv -> zone );
425
470
else
426
471
thermal_zone_device_unregister (priv -> zone );
@@ -438,6 +483,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)
438
483
struct rcar_thermal_priv * priv ;
439
484
struct device * dev = & pdev -> dev ;
440
485
struct resource * res , * irq ;
486
+ const struct rcar_thermal_chip * chip = of_device_get_match_data (dev );
441
487
int mres = 0 ;
442
488
int i ;
443
489
int ret = - ENODEV ;
@@ -457,19 +503,35 @@ static int rcar_thermal_probe(struct platform_device *pdev)
457
503
pm_runtime_enable (dev );
458
504
pm_runtime_get_sync (dev );
459
505
460
- irq = platform_get_resource (pdev , IORESOURCE_IRQ , 0 );
461
- if (irq ) {
462
- /*
463
- * platform has IRQ support.
464
- * Then, driver uses common registers
465
- * rcar_has_irq_support() will be enabled
466
- */
467
- res = platform_get_resource (pdev , IORESOURCE_MEM , mres ++ );
468
- common -> base = devm_ioremap_resource (dev , res );
469
- if (IS_ERR (common -> base ))
470
- return PTR_ERR (common -> base );
506
+ for (i = 0 ; i < chip -> nirqs ; i ++ ) {
507
+ irq = platform_get_resource (pdev , IORESOURCE_IRQ , 0 );
508
+ if (!irq )
509
+ continue ;
510
+ if (!common -> base ) {
511
+ /*
512
+ * platform has IRQ support.
513
+ * Then, driver uses common registers
514
+ * rcar_has_irq_support() will be enabled
515
+ */
516
+ res = platform_get_resource (pdev , IORESOURCE_MEM ,
517
+ mres ++ );
518
+ common -> base = devm_ioremap_resource (dev , res );
519
+ if (IS_ERR (common -> base ))
520
+ return PTR_ERR (common -> base );
521
+
522
+ idle = 0 ; /* polling delay is not needed */
523
+ }
471
524
472
- idle = 0 ; /* polling delay is not needed */
525
+ ret = devm_request_irq (dev , irq -> start , rcar_thermal_irq ,
526
+ IRQF_SHARED , dev_name (dev ), common );
527
+ if (ret ) {
528
+ dev_err (dev , "irq request failed\n " );
529
+ goto error_unregister ;
530
+ }
531
+
532
+ /* update ENR bits */
533
+ if (chip -> irq_per_ch )
534
+ enr_bits |= 1 << i ;
473
535
}
474
536
475
537
for (i = 0 ;; i ++ ) {
@@ -491,14 +553,15 @@ static int rcar_thermal_probe(struct platform_device *pdev)
491
553
492
554
priv -> common = common ;
493
555
priv -> id = i ;
556
+ priv -> chip = chip ;
494
557
mutex_init (& priv -> lock );
495
558
INIT_LIST_HEAD (& priv -> list );
496
559
INIT_DELAYED_WORK (& priv -> work , rcar_thermal_work );
497
560
ret = rcar_thermal_update_temp (priv );
498
561
if (ret < 0 )
499
562
goto error_unregister ;
500
563
501
- if (rcar_use_of_thermal ( dev ) )
564
+ if (chip -> use_of_thermal )
502
565
priv -> zone = devm_thermal_zone_of_sensor_register (
503
566
dev , i , priv ,
504
567
& rcar_thermal_zone_of_ops );
@@ -515,7 +578,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)
515
578
goto error_unregister ;
516
579
}
517
580
518
- if (rcar_use_of_thermal ( dev ) ) {
581
+ if (chip -> use_of_thermal ) {
519
582
/*
520
583
* thermal_zone doesn't enable hwmon as default,
521
584
* but, enable it here to keep compatible
@@ -531,20 +594,12 @@ static int rcar_thermal_probe(struct platform_device *pdev)
531
594
list_move_tail (& priv -> list , & common -> head );
532
595
533
596
/* update ENR bits */
534
- enr_bits |= 3 << (i * 8 );
597
+ if (!chip -> irq_per_ch )
598
+ enr_bits |= 3 << (i * 8 );
535
599
}
536
600
537
- /* enable temperature comparation */
538
- if (irq ) {
539
- ret = devm_request_irq (dev , irq -> start , rcar_thermal_irq , 0 ,
540
- dev_name (dev ), common );
541
- if (ret ) {
542
- dev_err (dev , "irq request failed\n " );
543
- goto error_unregister ;
544
- }
545
-
601
+ if (enr_bits )
546
602
rcar_thermal_common_write (common , ENR , enr_bits );
547
- }
548
603
549
604
dev_info (dev , "%d sensor probed\n" , i );
550
605
@@ -556,9 +611,48 @@ static int rcar_thermal_probe(struct platform_device *pdev)
556
611
return ret ;
557
612
}
558
613
614
+ #ifdef CONFIG_PM_SLEEP
615
+ static int rcar_thermal_suspend (struct device * dev )
616
+ {
617
+ struct rcar_thermal_common * common = dev_get_drvdata (dev );
618
+ struct rcar_thermal_priv * priv = list_first_entry (& common -> head ,
619
+ typeof (* priv ), list );
620
+
621
+ if (priv -> chip -> needs_suspend_resume ) {
622
+ rcar_thermal_common_write (common , ENR , 0 );
623
+ rcar_thermal_irq_disable (priv );
624
+ rcar_thermal_bset (priv , THSCR , CPCTL , 0 );
625
+ }
626
+
627
+ return 0 ;
628
+ }
629
+
630
+ static int rcar_thermal_resume (struct device * dev )
631
+ {
632
+ struct rcar_thermal_common * common = dev_get_drvdata (dev );
633
+ struct rcar_thermal_priv * priv = list_first_entry (& common -> head ,
634
+ typeof (* priv ), list );
635
+ int ret ;
636
+
637
+ if (priv -> chip -> needs_suspend_resume ) {
638
+ ret = rcar_thermal_update_temp (priv );
639
+ if (ret < 0 )
640
+ return ret ;
641
+ rcar_thermal_irq_enable (priv );
642
+ rcar_thermal_common_write (common , ENR , 0x03 );
643
+ }
644
+
645
+ return 0 ;
646
+ }
647
+ #endif
648
+
649
+ static SIMPLE_DEV_PM_OPS (rcar_thermal_pm_ops , rcar_thermal_suspend ,
650
+ rcar_thermal_resume ) ;
651
+
559
652
static struct platform_driver rcar_thermal_driver = {
560
653
.driver = {
561
654
.name = "rcar_thermal" ,
655
+ .pm = & rcar_thermal_pm_ops ,
562
656
.of_match_table = rcar_thermal_dt_ids ,
563
657
},
564
658
.probe = rcar_thermal_probe ,
0 commit comments