@@ -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
@@ -481,7 +525,9 @@ static void armada_set_sane_name(struct platform_device *pdev,
481
525
482
526
static int armada_thermal_probe (struct platform_device * pdev )
483
527
{
484
- struct thermal_zone_device * thermal ;
528
+ struct thermal_zone_device * tz ;
529
+ struct armada_thermal_sensor * sensors ;
530
+ struct armada_drvdata * drvdata ;
485
531
const struct of_device_id * match ;
486
532
struct armada_thermal_priv * priv ;
487
533
int ret ;
@@ -494,10 +540,12 @@ static int armada_thermal_probe(struct platform_device *pdev)
494
540
if (!priv )
495
541
return - ENOMEM ;
496
542
497
- priv -> data = (struct armada_thermal_data * )match -> data ;
543
+ drvdata = devm_kzalloc (& pdev -> dev , sizeof (* drvdata ), GFP_KERNEL );
544
+ if (!priv )
545
+ return - ENOMEM ;
498
546
499
- /* Ensure device name is correct for the thermal core */
500
- armada_set_sane_name ( pdev , priv ) ;
547
+ priv -> dev = & pdev -> dev ;
548
+ priv -> data = ( struct armada_thermal_data * ) match -> data ;
501
549
502
550
/*
503
551
* Legacy DT bindings only described "control1" register (also referred
@@ -511,35 +559,65 @@ static int armada_thermal_probe(struct platform_device *pdev)
511
559
* is to define an overall system controller and put the thermal node
512
560
* into it, which requires the use of regmaps across all the driver.
513
561
*/
514
- if (IS_ERR (syscon_node_to_regmap (pdev -> dev .parent -> of_node )))
562
+ if (IS_ERR (syscon_node_to_regmap (pdev -> dev .parent -> of_node ))) {
563
+ /* Ensure device name is correct for the thermal core */
564
+ armada_set_sane_name (pdev , priv );
565
+
515
566
ret = armada_thermal_probe_legacy (pdev , priv );
516
- else
517
- ret = armada_thermal_probe_syscon ( pdev , priv ) ;
567
+ if ( ret )
568
+ return ret ;
518
569
570
+ priv -> data -> init (pdev , priv );
571
+
572
+ tz = thermal_zone_device_register (priv -> zone_name , 0 , 0 , priv ,
573
+ & legacy_ops , NULL , 0 , 0 );
574
+ if (IS_ERR (tz )) {
575
+ dev_err (& pdev -> dev ,
576
+ "Failed to register thermal zone device\n" );
577
+ return PTR_ERR (tz );
578
+ }
579
+
580
+ drvdata -> type = LEGACY ;
581
+ drvdata -> data .tz = tz ;
582
+ platform_set_drvdata (pdev , drvdata );
583
+
584
+ return 0 ;
585
+ }
586
+
587
+ ret = armada_thermal_probe_syscon (pdev , priv );
519
588
if (ret )
520
589
return ret ;
521
590
522
591
priv -> data -> init (pdev , priv );
592
+ drvdata -> type = SYSCON ;
593
+ drvdata -> data .priv = priv ;
594
+ platform_set_drvdata (pdev , drvdata );
523
595
524
- thermal = thermal_zone_device_register (priv -> zone_name , 0 , 0 , priv ,
525
- & ops , NULL , 0 , 0 );
526
- if (IS_ERR (thermal )) {
596
+ sensors = devm_kzalloc (& pdev -> dev , sizeof (struct armada_thermal_sensor ),
597
+ GFP_KERNEL );
598
+ if (!sensors )
599
+ return - ENOMEM ;
600
+
601
+ sensors -> priv = priv ;
602
+
603
+ tz = devm_thermal_zone_of_sensor_register (& pdev -> dev , 0 , sensors ,
604
+ & of_ops );
605
+ if (IS_ERR (tz )) {
527
606
dev_err (& pdev -> dev ,
528
- "Failed to register thermal zone device\n" );
529
- return PTR_ERR (thermal );
607
+ "Failed to register thermal sensor (err: %ld)\n" ,
608
+ PTR_ERR (tz ));
609
+ return PTR_ERR (tz );
530
610
}
531
611
532
- platform_set_drvdata (pdev , thermal );
533
-
534
612
return 0 ;
535
613
}
536
614
537
615
static int armada_thermal_exit (struct platform_device * pdev )
538
616
{
539
- struct thermal_zone_device * armada_thermal =
540
- platform_get_drvdata (pdev );
617
+ struct armada_drvdata * drvdata = platform_get_drvdata (pdev );
541
618
542
- thermal_zone_device_unregister (armada_thermal );
619
+ if (drvdata -> type == LEGACY )
620
+ thermal_zone_device_unregister (drvdata -> data .tz );
543
621
544
622
return 0 ;
545
623
}
0 commit comments