@@ -64,6 +64,7 @@ struct armada_thermal_data;
64
64
65
65
/* Marvell EBU Thermal Sensor Dev Structure */
66
66
struct armada_thermal_priv {
67
+ struct device * dev ;
67
68
struct regmap * syscon ;
68
69
char zone_name [THERMAL_NAME_LENGTH ];
69
70
struct armada_thermal_data * data ;
@@ -95,6 +96,26 @@ struct armada_thermal_data {
95
96
unsigned int syscon_status_off ;
96
97
};
97
98
99
+ struct armada_drvdata {
100
+ enum drvtype {
101
+ LEGACY ,
102
+ SYSCON
103
+ } type ;
104
+ union {
105
+ struct armada_thermal_priv * priv ;
106
+ struct thermal_zone_device * tz ;
107
+ } data ;
108
+ };
109
+
110
+ /*
111
+ * struct armada_thermal_sensor - hold the information of one thermal sensor
112
+ * @thermal: pointer to the local private structure
113
+ * @tzd: pointer to the thermal zone device
114
+ */
115
+ struct armada_thermal_sensor {
116
+ struct armada_thermal_priv * priv ;
117
+ };
118
+
98
119
static void armadaxp_init (struct platform_device * pdev ,
99
120
struct armada_thermal_priv * priv )
100
121
{
@@ -243,16 +264,14 @@ static bool armada_is_valid(struct armada_thermal_priv *priv)
243
264
return reg & priv -> data -> is_valid_bit ;
244
265
}
245
266
246
- static int armada_get_temp (struct thermal_zone_device * thermal ,
247
- int * temp )
267
+ static int armada_read_sensor (struct armada_thermal_priv * priv , int * temp )
248
268
{
249
- struct armada_thermal_priv * priv = thermal -> devdata ;
250
269
u32 reg , div ;
251
270
s64 sample , b , m ;
252
271
253
272
/* Valid check */
254
273
if (priv -> data -> is_valid && !priv -> data -> is_valid (priv )) {
255
- dev_err (& thermal -> device ,
274
+ dev_err (priv -> dev ,
256
275
"Temperature sensor reading not valid\n" );
257
276
return - EIO ;
258
277
}
@@ -278,7 +297,32 @@ static int armada_get_temp(struct thermal_zone_device *thermal,
278
297
return 0 ;
279
298
}
280
299
281
- static struct thermal_zone_device_ops ops = {
300
+ static int armada_get_temp_legacy (struct thermal_zone_device * thermal ,
301
+ int * temp )
302
+ {
303
+ struct armada_thermal_priv * priv = thermal -> devdata ;
304
+ int ret ;
305
+
306
+ /* Do the actual reading */
307
+ ret = armada_read_sensor (priv , temp );
308
+
309
+ return ret ;
310
+ }
311
+
312
+ static struct thermal_zone_device_ops legacy_ops = {
313
+ .get_temp = armada_get_temp_legacy ,
314
+ };
315
+
316
+ static int armada_get_temp (void * _sensor , int * temp )
317
+ {
318
+ struct armada_thermal_sensor * sensor = _sensor ;
319
+ struct armada_thermal_priv * priv = sensor -> priv ;
320
+
321
+ /* Do the actual reading */
322
+ return armada_read_sensor (priv , temp );
323
+ }
324
+
325
+ static struct thermal_zone_of_device_ops of_ops = {
282
326
.get_temp = armada_get_temp ,
283
327
};
284
328
@@ -480,7 +524,9 @@ static void armada_set_sane_name(struct platform_device *pdev,
480
524
481
525
static int armada_thermal_probe (struct platform_device * pdev )
482
526
{
483
- struct thermal_zone_device * thermal ;
527
+ struct thermal_zone_device * tz ;
528
+ struct armada_thermal_sensor * sensors ;
529
+ struct armada_drvdata * drvdata ;
484
530
const struct of_device_id * match ;
485
531
struct armada_thermal_priv * priv ;
486
532
int ret ;
@@ -493,10 +539,12 @@ static int armada_thermal_probe(struct platform_device *pdev)
493
539
if (!priv )
494
540
return - ENOMEM ;
495
541
496
- priv -> data = (struct armada_thermal_data * )match -> data ;
542
+ drvdata = devm_kzalloc (& pdev -> dev , sizeof (* drvdata ), GFP_KERNEL );
543
+ if (!priv )
544
+ return - ENOMEM ;
497
545
498
- /* Ensure device name is correct for the thermal core */
499
- armada_set_sane_name ( pdev , priv ) ;
546
+ priv -> dev = & pdev -> dev ;
547
+ priv -> data = ( struct armada_thermal_data * ) match -> data ;
500
548
501
549
/*
502
550
* Legacy DT bindings only described "control1" register (also referred
@@ -510,35 +558,65 @@ static int armada_thermal_probe(struct platform_device *pdev)
510
558
* is to define an overall system controller and put the thermal node
511
559
* into it, which requires the use of regmaps across all the driver.
512
560
*/
513
- if (IS_ERR (syscon_node_to_regmap (pdev -> dev .parent -> of_node )))
561
+ if (IS_ERR (syscon_node_to_regmap (pdev -> dev .parent -> of_node ))) {
562
+ /* Ensure device name is correct for the thermal core */
563
+ armada_set_sane_name (pdev , priv );
564
+
514
565
ret = armada_thermal_probe_legacy (pdev , priv );
515
- else
516
- ret = armada_thermal_probe_syscon ( pdev , priv ) ;
566
+ if ( ret )
567
+ return ret ;
517
568
569
+ priv -> data -> init (pdev , priv );
570
+
571
+ tz = thermal_zone_device_register (priv -> zone_name , 0 , 0 , priv ,
572
+ & legacy_ops , NULL , 0 , 0 );
573
+ if (IS_ERR (tz )) {
574
+ dev_err (& pdev -> dev ,
575
+ "Failed to register thermal zone device\n" );
576
+ return PTR_ERR (tz );
577
+ }
578
+
579
+ drvdata -> type = LEGACY ;
580
+ drvdata -> data .tz = tz ;
581
+ platform_set_drvdata (pdev , drvdata );
582
+
583
+ return 0 ;
584
+ }
585
+
586
+ ret = armada_thermal_probe_syscon (pdev , priv );
518
587
if (ret )
519
588
return ret ;
520
589
521
590
priv -> data -> init (pdev , priv );
591
+ drvdata -> type = SYSCON ;
592
+ drvdata -> data .priv = priv ;
593
+ platform_set_drvdata (pdev , drvdata );
522
594
523
- thermal = thermal_zone_device_register (priv -> zone_name , 0 , 0 , priv ,
524
- & ops , NULL , 0 , 0 );
525
- if (IS_ERR (thermal )) {
595
+ sensors = devm_kzalloc (& pdev -> dev , sizeof (struct armada_thermal_sensor ),
596
+ GFP_KERNEL );
597
+ if (!sensors )
598
+ return - ENOMEM ;
599
+
600
+ sensors -> priv = priv ;
601
+
602
+ tz = devm_thermal_zone_of_sensor_register (& pdev -> dev , 0 , sensors ,
603
+ & of_ops );
604
+ if (IS_ERR (tz )) {
526
605
dev_err (& pdev -> dev ,
527
- "Failed to register thermal zone device\n" );
528
- return PTR_ERR (thermal );
606
+ "Failed to register thermal sensor (err: %ld)\n" ,
607
+ PTR_ERR (tz ));
608
+ return PTR_ERR (tz );
529
609
}
530
610
531
- platform_set_drvdata (pdev , thermal );
532
-
533
611
return 0 ;
534
612
}
535
613
536
614
static int armada_thermal_exit (struct platform_device * pdev )
537
615
{
538
- struct thermal_zone_device * armada_thermal =
539
- platform_get_drvdata (pdev );
616
+ struct armada_drvdata * drvdata = platform_get_drvdata (pdev );
540
617
541
- thermal_zone_device_unregister (armada_thermal );
618
+ if (drvdata -> type == LEGACY )
619
+ thermal_zone_device_unregister (drvdata -> data .tz );
542
620
543
621
return 0 ;
544
622
}
0 commit comments