@@ -461,10 +461,14 @@ static void devfreq_monitor(struct work_struct *work)
461
461
if (err )
462
462
dev_err (& devfreq -> dev , "dvfs failed with (%d) error\n" , err );
463
463
464
+ if (devfreq -> stop_polling )
465
+ goto out ;
466
+
464
467
queue_delayed_work (devfreq_wq , & devfreq -> work ,
465
468
msecs_to_jiffies (devfreq -> profile -> polling_ms ));
466
- mutex_unlock (& devfreq -> lock );
467
469
470
+ out :
471
+ mutex_unlock (& devfreq -> lock );
468
472
trace_devfreq_monitor (devfreq );
469
473
}
470
474
@@ -483,6 +487,10 @@ void devfreq_monitor_start(struct devfreq *devfreq)
483
487
if (IS_SUPPORTED_FLAG (devfreq -> governor -> flags , IRQ_DRIVEN ))
484
488
return ;
485
489
490
+ mutex_lock (& devfreq -> lock );
491
+ if (delayed_work_pending (& devfreq -> work ))
492
+ goto out ;
493
+
486
494
switch (devfreq -> profile -> timer ) {
487
495
case DEVFREQ_TIMER_DEFERRABLE :
488
496
INIT_DEFERRABLE_WORK (& devfreq -> work , devfreq_monitor );
@@ -491,12 +499,16 @@ void devfreq_monitor_start(struct devfreq *devfreq)
491
499
INIT_DELAYED_WORK (& devfreq -> work , devfreq_monitor );
492
500
break ;
493
501
default :
494
- return ;
502
+ goto out ;
495
503
}
496
504
497
505
if (devfreq -> profile -> polling_ms )
498
506
queue_delayed_work (devfreq_wq , & devfreq -> work ,
499
507
msecs_to_jiffies (devfreq -> profile -> polling_ms ));
508
+
509
+ out :
510
+ devfreq -> stop_polling = false;
511
+ mutex_unlock (& devfreq -> lock );
500
512
}
501
513
EXPORT_SYMBOL (devfreq_monitor_start );
502
514
@@ -513,6 +525,14 @@ void devfreq_monitor_stop(struct devfreq *devfreq)
513
525
if (IS_SUPPORTED_FLAG (devfreq -> governor -> flags , IRQ_DRIVEN ))
514
526
return ;
515
527
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 );
516
536
cancel_delayed_work_sync (& devfreq -> work );
517
537
}
518
538
EXPORT_SYMBOL (devfreq_monitor_stop );
@@ -1688,7 +1708,7 @@ static ssize_t trans_stat_show(struct device *dev,
1688
1708
struct device_attribute * attr , char * buf )
1689
1709
{
1690
1710
struct devfreq * df = to_devfreq (dev );
1691
- ssize_t len ;
1711
+ ssize_t len = 0 ;
1692
1712
int i , j ;
1693
1713
unsigned int max_state ;
1694
1714
@@ -1697,7 +1717,7 @@ static ssize_t trans_stat_show(struct device *dev,
1697
1717
max_state = df -> max_state ;
1698
1718
1699
1719
if (max_state == 0 )
1700
- return sprintf (buf , "Not Supported.\n" );
1720
+ return sysfs_emit (buf , "Not Supported.\n" );
1701
1721
1702
1722
mutex_lock (& df -> lock );
1703
1723
if (!df -> stop_polling &&
@@ -1707,31 +1727,49 @@ static ssize_t trans_stat_show(struct device *dev,
1707
1727
}
1708
1728
mutex_unlock (& df -> lock );
1709
1729
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
+ }
1715
1738
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" );
1717
1742
1718
1743
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 , "*" );
1721
1748
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" ,
1727
1757
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
+ }
1728
1764
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 ;
1731
1771
}
1732
1772
1733
- len += sprintf (buf + len , "Total transition : %u\n" ,
1734
- df -> stats .total_trans );
1735
1773
return len ;
1736
1774
}
1737
1775
0 commit comments