Skip to content

Commit 5c0f6c7

Browse files
digetxchanwoochoi
authored andcommitted
PM / devfreq: Add new interrupt_driven flag for governors
Currently interrupt-driven governors (like NVIDIA Tegra30 ACTMON governor) are used to set polling_ms=0 in order to avoid periodic polling of device status by devfreq core. This means that polling interval can't be changed by userspace for such governors. The new governor flag allows interrupt-driven governors to convey that devfreq core shouldn't perform polling of device status and thus generic devfreq polling interval could be supported by these governors now. Signed-off-by: Dmitry Osipenko <[email protected]> Reviewed-by: Chanwoo Choi <[email protected]> Signed-off-by: Chanwoo Choi <[email protected]>
1 parent 28615e3 commit 5c0f6c7

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

drivers/devfreq/devfreq.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,9 @@ static void devfreq_monitor(struct work_struct *work)
410410
*/
411411
void devfreq_monitor_start(struct devfreq *devfreq)
412412
{
413+
if (devfreq->governor->interrupt_driven)
414+
return;
415+
413416
INIT_DEFERRABLE_WORK(&devfreq->work, devfreq_monitor);
414417
if (devfreq->profile->polling_ms)
415418
queue_delayed_work(devfreq_wq, &devfreq->work,
@@ -427,6 +430,9 @@ EXPORT_SYMBOL(devfreq_monitor_start);
427430
*/
428431
void devfreq_monitor_stop(struct devfreq *devfreq)
429432
{
433+
if (devfreq->governor->interrupt_driven)
434+
return;
435+
430436
cancel_delayed_work_sync(&devfreq->work);
431437
}
432438
EXPORT_SYMBOL(devfreq_monitor_stop);
@@ -454,6 +460,10 @@ void devfreq_monitor_suspend(struct devfreq *devfreq)
454460
devfreq_update_status(devfreq, devfreq->previous_freq);
455461
devfreq->stop_polling = true;
456462
mutex_unlock(&devfreq->lock);
463+
464+
if (devfreq->governor->interrupt_driven)
465+
return;
466+
457467
cancel_delayed_work_sync(&devfreq->work);
458468
}
459469
EXPORT_SYMBOL(devfreq_monitor_suspend);
@@ -474,11 +484,15 @@ void devfreq_monitor_resume(struct devfreq *devfreq)
474484
if (!devfreq->stop_polling)
475485
goto out;
476486

487+
if (devfreq->governor->interrupt_driven)
488+
goto out_update;
489+
477490
if (!delayed_work_pending(&devfreq->work) &&
478491
devfreq->profile->polling_ms)
479492
queue_delayed_work(devfreq_wq, &devfreq->work,
480493
msecs_to_jiffies(devfreq->profile->polling_ms));
481494

495+
out_update:
482496
devfreq->last_stat_updated = jiffies;
483497
devfreq->stop_polling = false;
484498

@@ -510,6 +524,9 @@ void devfreq_interval_update(struct devfreq *devfreq, unsigned int *delay)
510524
if (devfreq->stop_polling)
511525
goto out;
512526

527+
if (devfreq->governor->interrupt_driven)
528+
goto out;
529+
513530
/* if new delay is zero, stop polling */
514531
if (!new_delay) {
515532
mutex_unlock(&devfreq->lock);

drivers/devfreq/governor.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
* @name: Governor's name
3232
* @immutable: Immutable flag for governor. If the value is 1,
3333
* this govenror is never changeable to other governor.
34+
* @interrupt_driven: Devfreq core won't schedule polling work for this
35+
* governor if value is set to 1.
3436
* @get_target_freq: Returns desired operating frequency for the device.
3537
* Basically, get_target_freq will run
3638
* devfreq_dev_profile.get_dev_status() to get the
@@ -49,6 +51,7 @@ struct devfreq_governor {
4951

5052
const char name[DEVFREQ_NAME_LEN];
5153
const unsigned int immutable;
54+
const unsigned int interrupt_driven;
5255
int (*get_target_freq)(struct devfreq *this, unsigned long *freq);
5356
int (*event_handler)(struct devfreq *devfreq,
5457
unsigned int event, void *data);

0 commit comments

Comments
 (0)