1818#include <linux/regmap.h>
1919#include <linux/slab.h>
2020#include <linux/thermal.h>
21+ #include "../thermal_hwmon.h"
2122#include "tsens.h"
2223
2324/**
@@ -417,7 +418,7 @@ static irqreturn_t tsens_critical_irq_thread(int irq, void *data)
417418 const struct tsens_sensor * s = & priv -> sensor [i ];
418419 u32 hw_id = s -> hw_id ;
419420
420- if (IS_ERR ( s -> tzd ) )
421+ if (! s -> tzd )
421422 continue ;
422423 if (!tsens_threshold_violated (priv , hw_id , & d ))
423424 continue ;
@@ -467,7 +468,7 @@ static irqreturn_t tsens_irq_thread(int irq, void *data)
467468 const struct tsens_sensor * s = & priv -> sensor [i ];
468469 u32 hw_id = s -> hw_id ;
469470
470- if (IS_ERR ( s -> tzd ) )
471+ if (! s -> tzd )
471472 continue ;
472473 if (!tsens_threshold_violated (priv , hw_id , & d ))
473474 continue ;
@@ -531,6 +532,27 @@ static irqreturn_t tsens_irq_thread(int irq, void *data)
531532 return IRQ_HANDLED ;
532533}
533534
535+ /**
536+ * tsens_combined_irq_thread() - Threaded interrupt handler for combined interrupts
537+ * @irq: irq number
538+ * @data: tsens controller private data
539+ *
540+ * Handle the combined interrupt as if it were 2 separate interrupts, so call the
541+ * critical handler first and then the up/low one.
542+ *
543+ * Return: IRQ_HANDLED
544+ */
545+ static irqreturn_t tsens_combined_irq_thread (int irq , void * data )
546+ {
547+ irqreturn_t ret ;
548+
549+ ret = tsens_critical_irq_thread (irq , data );
550+ if (ret != IRQ_HANDLED )
551+ return ret ;
552+
553+ return tsens_irq_thread (irq , data );
554+ }
555+
534556static int tsens_set_trips (void * _sensor , int low , int high )
535557{
536558 struct tsens_sensor * s = _sensor ;
@@ -551,8 +573,8 @@ static int tsens_set_trips(void *_sensor, int low, int high)
551573 dev_dbg (dev , "[%u] %s: proposed thresholds: (%d:%d)\n" ,
552574 hw_id , __func__ , low , high );
553575
554- cl_high = clamp_val (high , -40000 , 120000 );
555- cl_low = clamp_val (low , -40000 , 120000 );
576+ cl_high = clamp_val (high , priv -> feat -> trip_min_temp , priv -> feat -> trip_max_temp );
577+ cl_low = clamp_val (low , priv -> feat -> trip_min_temp , priv -> feat -> trip_max_temp );
556578
557579 high_val = tsens_mC_to_hw (s , cl_high );
558580 low_val = tsens_mC_to_hw (s , cl_low );
@@ -603,22 +625,21 @@ int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp)
603625 int ret ;
604626
605627 /* VER_0 doesn't have VALID bit */
606- if (tsens_version (priv ) >= VER_0_1 ) {
607- ret = regmap_field_read (priv -> rf [valid_idx ], & valid );
608- if (ret )
609- return ret ;
610- while (!valid ) {
611- /* Valid bit is 0 for 6 AHB clock cycles.
612- * At 19.2MHz, 1 AHB clock is ~60ns.
613- * We should enter this loop very, very rarely.
614- */
615- ndelay (400 );
616- ret = regmap_field_read (priv -> rf [valid_idx ], & valid );
617- if (ret )
618- return ret ;
619- }
620- }
628+ if (tsens_version (priv ) == VER_0 )
629+ goto get_temp ;
621630
631+ /* Valid bit is 0 for 6 AHB clock cycles.
632+ * At 19.2MHz, 1 AHB clock is ~60ns.
633+ * We should enter this loop very, very rarely.
634+ * Wait 1 us since it's the min of poll_timeout macro.
635+ * Old value was 400 ns.
636+ */
637+ ret = regmap_field_read_poll_timeout (priv -> rf [valid_idx ], valid ,
638+ valid , 1 , 20 * USEC_PER_MSEC );
639+ if (ret )
640+ return ret ;
641+
642+ get_temp :
622643 /* Valid bit is set, OK to read the temperature */
623644 * temp = tsens_hw_to_mC (s , temp_idx );
624645
@@ -692,7 +713,7 @@ static int dbg_version_show(struct seq_file *s, void *data)
692713 return ret ;
693714 seq_printf (s , "%d.%d.%d\n" , maj_ver , min_ver , step_ver );
694715 } else {
695- seq_puts (s , "0.1 .0\n" );
716+ seq_printf (s , "0.%d .0\n" , priv -> feat -> ver_major );
696717 }
697718
698719 return 0 ;
@@ -704,21 +725,14 @@ DEFINE_SHOW_ATTRIBUTE(dbg_sensors);
704725static void tsens_debug_init (struct platform_device * pdev )
705726{
706727 struct tsens_priv * priv = platform_get_drvdata (pdev );
707- struct dentry * root , * file ;
708728
709- root = debugfs_lookup ("tsens" , NULL );
710- if (!root )
729+ priv -> debug_root = debugfs_lookup ("tsens" , NULL );
730+ if (!priv -> debug_root )
711731 priv -> debug_root = debugfs_create_dir ("tsens" , NULL );
712- else
713- priv -> debug_root = root ;
714-
715- file = debugfs_lookup ("version" , priv -> debug_root );
716- if (!file )
717- debugfs_create_file ("version" , 0444 , priv -> debug_root ,
718- pdev , & dbg_version_fops );
719732
720733 /* A directory for each instance of the TSENS IP */
721734 priv -> debug = debugfs_create_dir (dev_name (& pdev -> dev ), priv -> debug_root );
735+ debugfs_create_file ("version" , 0444 , priv -> debug , pdev , & dbg_version_fops );
722736 debugfs_create_file ("sensors" , 0444 , priv -> debug , pdev , & dbg_sensors_fops );
723737}
724738#else
@@ -918,8 +932,6 @@ int __init init_common(struct tsens_priv *priv)
918932 if (tsens_version (priv ) >= VER_0_1 )
919933 tsens_enable_irq (priv );
920934
921- tsens_debug_init (op );
922-
923935err_put_device :
924936 put_device (& op -> dev );
925937 return ret ;
@@ -933,17 +945,6 @@ static int tsens_get_temp(void *data, int *temp)
933945 return priv -> ops -> get_temp (s , temp );
934946}
935947
936- static int tsens_get_trend (void * data , int trip , enum thermal_trend * trend )
937- {
938- struct tsens_sensor * s = data ;
939- struct tsens_priv * priv = s -> priv ;
940-
941- if (priv -> ops -> get_trend )
942- return priv -> ops -> get_trend (s , trend );
943-
944- return - ENOTSUPP ;
945- }
946-
947948static int __maybe_unused tsens_suspend (struct device * dev )
948949{
949950 struct tsens_priv * priv = dev_get_drvdata (dev );
@@ -1001,7 +1002,6 @@ MODULE_DEVICE_TABLE(of, tsens_table);
10011002
10021003static const struct thermal_zone_of_device_ops tsens_of_ops = {
10031004 .get_temp = tsens_get_temp ,
1004- .get_trend = tsens_get_trend ,
10051005 .set_trips = tsens_set_trips ,
10061006};
10071007
@@ -1061,6 +1061,10 @@ static int tsens_register(struct tsens_priv *priv)
10611061 priv -> sensor [i ].tzd = tzd ;
10621062 if (priv -> ops -> enable )
10631063 priv -> ops -> enable (priv , i );
1064+
1065+ if (devm_thermal_add_hwmon_sysfs (tzd ))
1066+ dev_warn (priv -> dev ,
1067+ "Failed to add hwmon sysfs attributes\n" );
10641068 }
10651069
10661070 /* VER_0 require to set MIN and MAX THRESH
@@ -1076,13 +1080,18 @@ static int tsens_register(struct tsens_priv *priv)
10761080 tsens_mC_to_hw (priv -> sensor , 0 ));
10771081 }
10781082
1079- ret = tsens_register_irq (priv , "uplow" , tsens_irq_thread );
1080- if (ret < 0 )
1081- return ret ;
1083+ if (priv -> feat -> combo_int ) {
1084+ ret = tsens_register_irq (priv , "combined" ,
1085+ tsens_combined_irq_thread );
1086+ } else {
1087+ ret = tsens_register_irq (priv , "uplow" , tsens_irq_thread );
1088+ if (ret < 0 )
1089+ return ret ;
10821090
1083- if (priv -> feat -> crit_int )
1084- ret = tsens_register_irq (priv , "critical" ,
1085- tsens_critical_irq_thread );
1091+ if (priv -> feat -> crit_int )
1092+ ret = tsens_register_irq (priv , "critical" ,
1093+ tsens_critical_irq_thread );
1094+ }
10861095
10871096 return ret ;
10881097}
@@ -1158,7 +1167,11 @@ static int tsens_probe(struct platform_device *pdev)
11581167 }
11591168 }
11601169
1161- return tsens_register (priv );
1170+ ret = tsens_register (priv );
1171+ if (!ret )
1172+ tsens_debug_init (pdev );
1173+
1174+ return ret ;
11621175}
11631176
11641177static int tsens_remove (struct platform_device * pdev )
0 commit comments