@@ -461,10 +461,14 @@ static void devfreq_monitor(struct work_struct *work)
461461 if (err )
462462 dev_err (& devfreq -> dev , "dvfs failed with (%d) error\n" , err );
463463
464+ if (devfreq -> stop_polling )
465+ goto out ;
466+
464467 queue_delayed_work (devfreq_wq , & devfreq -> work ,
465468 msecs_to_jiffies (devfreq -> profile -> polling_ms ));
466- mutex_unlock (& devfreq -> lock );
467469
470+ out :
471+ mutex_unlock (& devfreq -> lock );
468472 trace_devfreq_monitor (devfreq );
469473}
470474
@@ -483,6 +487,10 @@ void devfreq_monitor_start(struct devfreq *devfreq)
483487 if (IS_SUPPORTED_FLAG (devfreq -> governor -> flags , IRQ_DRIVEN ))
484488 return ;
485489
490+ mutex_lock (& devfreq -> lock );
491+ if (delayed_work_pending (& devfreq -> work ))
492+ goto out ;
493+
486494 switch (devfreq -> profile -> timer ) {
487495 case DEVFREQ_TIMER_DEFERRABLE :
488496 INIT_DEFERRABLE_WORK (& devfreq -> work , devfreq_monitor );
@@ -491,12 +499,16 @@ void devfreq_monitor_start(struct devfreq *devfreq)
491499 INIT_DELAYED_WORK (& devfreq -> work , devfreq_monitor );
492500 break ;
493501 default :
494- return ;
502+ goto out ;
495503 }
496504
497505 if (devfreq -> profile -> polling_ms )
498506 queue_delayed_work (devfreq_wq , & devfreq -> work ,
499507 msecs_to_jiffies (devfreq -> profile -> polling_ms ));
508+
509+ out :
510+ devfreq -> stop_polling = false;
511+ mutex_unlock (& devfreq -> lock );
500512}
501513EXPORT_SYMBOL (devfreq_monitor_start );
502514
@@ -513,6 +525,14 @@ void devfreq_monitor_stop(struct devfreq *devfreq)
513525 if (IS_SUPPORTED_FLAG (devfreq -> governor -> flags , IRQ_DRIVEN ))
514526 return ;
515527
528+ mutex_lock (& devfreq -> lock );
529+ if (devfreq -> stop_polling ) {
530+ mutex_unlock (& devfreq -> lock );
531+ return ;
532+ }
533+
534+ devfreq -> stop_polling = true;
535+ mutex_unlock (& devfreq -> lock );
516536 cancel_delayed_work_sync (& devfreq -> work );
517537}
518538EXPORT_SYMBOL (devfreq_monitor_stop );
@@ -1688,7 +1708,7 @@ static ssize_t trans_stat_show(struct device *dev,
16881708 struct device_attribute * attr , char * buf )
16891709{
16901710 struct devfreq * df = to_devfreq (dev );
1691- ssize_t len ;
1711+ ssize_t len = 0 ;
16921712 int i , j ;
16931713 unsigned int max_state ;
16941714
@@ -1697,7 +1717,7 @@ static ssize_t trans_stat_show(struct device *dev,
16971717 max_state = df -> max_state ;
16981718
16991719 if (max_state == 0 )
1700- return sprintf (buf , "Not Supported.\n" );
1720+ return sysfs_emit (buf , "Not Supported.\n" );
17011721
17021722 mutex_lock (& df -> lock );
17031723 if (!df -> stop_polling &&
@@ -1707,31 +1727,49 @@ static ssize_t trans_stat_show(struct device *dev,
17071727 }
17081728 mutex_unlock (& df -> lock );
17091729
1710- len = sprintf (buf , " From : To\n" );
1711- len += sprintf (buf + len , " :" );
1712- for (i = 0 ; i < max_state ; i ++ )
1713- len += sprintf (buf + len , "%10lu" ,
1714- df -> freq_table [i ]);
1730+ len += sysfs_emit_at (buf , len , " From : To\n" );
1731+ len += sysfs_emit_at (buf , len , " :" );
1732+ for (i = 0 ; i < max_state ; i ++ ) {
1733+ if (len >= PAGE_SIZE - 1 )
1734+ break ;
1735+ len += sysfs_emit_at (buf , len , "%10lu" ,
1736+ df -> freq_table [i ]);
1737+ }
17151738
1716- len += sprintf (buf + len , " time(ms)\n" );
1739+ if (len >= PAGE_SIZE - 1 )
1740+ return PAGE_SIZE - 1 ;
1741+ len += sysfs_emit_at (buf , len , " time(ms)\n" );
17171742
17181743 for (i = 0 ; i < max_state ; i ++ ) {
1719- if (df -> freq_table [i ] == df -> previous_freq )
1720- len += sprintf (buf + len , "*" );
1744+ if (len >= PAGE_SIZE - 1 )
1745+ break ;
1746+ if (df -> freq_table [2 ] == df -> previous_freq )
1747+ len += sysfs_emit_at (buf , len , "*" );
17211748 else
1722- len += sprintf (buf + len , " " );
1723-
1724- len += sprintf (buf + len , "%10lu:" , df -> freq_table [i ]);
1725- for (j = 0 ; j < max_state ; j ++ )
1726- len += sprintf (buf + len , "%10u" ,
1749+ len += sysfs_emit_at (buf , len , " " );
1750+ if (len >= PAGE_SIZE - 1 )
1751+ break ;
1752+ len += sysfs_emit_at (buf , len , "%10lu:" , df -> freq_table [i ]);
1753+ for (j = 0 ; j < max_state ; j ++ ) {
1754+ if (len >= PAGE_SIZE - 1 )
1755+ break ;
1756+ len += sysfs_emit_at (buf , len , "%10u" ,
17271757 df -> stats .trans_table [(i * max_state ) + j ]);
1758+ }
1759+ if (len >= PAGE_SIZE - 1 )
1760+ break ;
1761+ len += sysfs_emit_at (buf , len , "%10llu\n" , (u64 )
1762+ jiffies64_to_msecs (df -> stats .time_in_state [i ]));
1763+ }
17281764
1729- len += sprintf (buf + len , "%10llu\n" , (u64 )
1730- jiffies64_to_msecs (df -> stats .time_in_state [i ]));
1765+ if (len < PAGE_SIZE - 1 )
1766+ len += sysfs_emit_at (buf , len , "Total transition : %u\n" ,
1767+ df -> stats .total_trans );
1768+ if (len >= PAGE_SIZE - 1 ) {
1769+ pr_warn_once ("devfreq transition table exceeds PAGE_SIZE. Disabling\n" );
1770+ return - EFBIG ;
17311771 }
17321772
1733- len += sprintf (buf + len , "Total transition : %u\n" ,
1734- df -> stats .total_trans );
17351773 return len ;
17361774}
17371775
0 commit comments