@@ -685,6 +685,8 @@ void thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev,
685685{
686686 struct cooling_dev_stats * stats = cdev -> stats ;
687687
688+ lockdep_assert_held (& cdev -> lock );
689+
688690 if (!stats )
689691 return ;
690692
@@ -706,13 +708,22 @@ static ssize_t total_trans_show(struct device *dev,
706708 struct device_attribute * attr , char * buf )
707709{
708710 struct thermal_cooling_device * cdev = to_cooling_device (dev );
709- struct cooling_dev_stats * stats = cdev -> stats ;
710- int ret ;
711+ struct cooling_dev_stats * stats ;
712+ int ret = 0 ;
713+
714+ mutex_lock (& cdev -> lock );
715+
716+ stats = cdev -> stats ;
717+ if (!stats )
718+ goto unlock ;
711719
712720 spin_lock (& stats -> lock );
713721 ret = sprintf (buf , "%u\n" , stats -> total_trans );
714722 spin_unlock (& stats -> lock );
715723
724+ unlock :
725+ mutex_unlock (& cdev -> lock );
726+
716727 return ret ;
717728}
718729
@@ -721,11 +732,18 @@ time_in_state_ms_show(struct device *dev, struct device_attribute *attr,
721732 char * buf )
722733{
723734 struct thermal_cooling_device * cdev = to_cooling_device (dev );
724- struct cooling_dev_stats * stats = cdev -> stats ;
735+ struct cooling_dev_stats * stats ;
725736 ssize_t len = 0 ;
726737 int i ;
727738
739+ mutex_lock (& cdev -> lock );
740+
741+ stats = cdev -> stats ;
742+ if (!stats )
743+ goto unlock ;
744+
728745 spin_lock (& stats -> lock );
746+
729747 update_time_in_state (stats );
730748
731749 for (i = 0 ; i <= cdev -> max_state ; i ++ ) {
@@ -734,6 +752,9 @@ time_in_state_ms_show(struct device *dev, struct device_attribute *attr,
734752 }
735753 spin_unlock (& stats -> lock );
736754
755+ unlock :
756+ mutex_unlock (& cdev -> lock );
757+
737758 return len ;
738759}
739760
@@ -742,8 +763,16 @@ reset_store(struct device *dev, struct device_attribute *attr, const char *buf,
742763 size_t count )
743764{
744765 struct thermal_cooling_device * cdev = to_cooling_device (dev );
745- struct cooling_dev_stats * stats = cdev -> stats ;
746- int i , states = cdev -> max_state + 1 ;
766+ struct cooling_dev_stats * stats ;
767+ int i , states ;
768+
769+ mutex_lock (& cdev -> lock );
770+
771+ stats = cdev -> stats ;
772+ if (!stats )
773+ goto unlock ;
774+
775+ states = cdev -> max_state + 1 ;
747776
748777 spin_lock (& stats -> lock );
749778
@@ -757,26 +786,39 @@ reset_store(struct device *dev, struct device_attribute *attr, const char *buf,
757786
758787 spin_unlock (& stats -> lock );
759788
789+ unlock :
790+ mutex_unlock (& cdev -> lock );
791+
760792 return count ;
761793}
762794
763795static ssize_t trans_table_show (struct device * dev ,
764796 struct device_attribute * attr , char * buf )
765797{
766798 struct thermal_cooling_device * cdev = to_cooling_device (dev );
767- struct cooling_dev_stats * stats = cdev -> stats ;
799+ struct cooling_dev_stats * stats ;
768800 ssize_t len = 0 ;
769801 int i , j ;
770802
803+ mutex_lock (& cdev -> lock );
804+
805+ stats = cdev -> stats ;
806+ if (!stats ) {
807+ len = - ENODATA ;
808+ goto unlock ;
809+ }
810+
771811 len += snprintf (buf + len , PAGE_SIZE - len , " From : To\n" );
772812 len += snprintf (buf + len , PAGE_SIZE - len , " : " );
773813 for (i = 0 ; i <= cdev -> max_state ; i ++ ) {
774814 if (len >= PAGE_SIZE )
775815 break ;
776816 len += snprintf (buf + len , PAGE_SIZE - len , "state%2u " , i );
777817 }
778- if (len >= PAGE_SIZE )
779- return PAGE_SIZE ;
818+ if (len >= PAGE_SIZE ) {
819+ len = PAGE_SIZE ;
820+ goto unlock ;
821+ }
780822
781823 len += snprintf (buf + len , PAGE_SIZE - len , "\n" );
782824
@@ -799,8 +841,12 @@ static ssize_t trans_table_show(struct device *dev,
799841
800842 if (len >= PAGE_SIZE ) {
801843 pr_warn_once ("Thermal transition table exceeds PAGE_SIZE. Disabling\n" );
802- return - EFBIG ;
844+ len = - EFBIG ;
803845 }
846+
847+ unlock :
848+ mutex_unlock (& cdev -> lock );
849+
804850 return len ;
805851}
806852
@@ -830,6 +876,8 @@ static void cooling_device_stats_setup(struct thermal_cooling_device *cdev)
830876 unsigned long states = cdev -> max_state + 1 ;
831877 int var ;
832878
879+ lockdep_assert_held (& cdev -> lock );
880+
833881 var = sizeof (* stats );
834882 var += sizeof (* stats -> time_in_state ) * states ;
835883 var += sizeof (* stats -> trans_table ) * states * states ;
@@ -855,6 +903,8 @@ static void cooling_device_stats_setup(struct thermal_cooling_device *cdev)
855903
856904static void cooling_device_stats_destroy (struct thermal_cooling_device * cdev )
857905{
906+ lockdep_assert_held (& cdev -> lock );
907+
858908 kfree (cdev -> stats );
859909 cdev -> stats = NULL ;
860910}
@@ -879,6 +929,12 @@ void thermal_cooling_device_destroy_sysfs(struct thermal_cooling_device *cdev)
879929 cooling_device_stats_destroy (cdev );
880930}
881931
932+ void thermal_cooling_device_stats_reinit (struct thermal_cooling_device * cdev )
933+ {
934+ cooling_device_stats_destroy (cdev );
935+ cooling_device_stats_setup (cdev );
936+ }
937+
882938/* these helper will be used only at the time of bindig */
883939ssize_t
884940trip_point_show (struct device * dev , struct device_attribute * attr , char * buf )
0 commit comments