Skip to content

Commit 2b32842

Browse files
committed
Merge tag 'devfreq-next-for-5.5' of git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/linux
Pull devfreq updates for v5.5 from Chanwoo Choi: "1. Update devfreq core - Check NULL governor in available_governors_show sysfs in order to prevent showing wrong governor information. - Fix race condition between devfreq_update_status() and trans_stat_show() - Add new 'interrupt-driven' flag for devfreq goveroris. Each devfreq driver can add their own interrupt-driven governor (NIVIDIA Tegra30 ACTMON governor). It needs to use the following sysfs interface to get the new polling interval in order to change the NVIDIA Tegra30 hardware's polling interval. : /sys/class/devfreq/devfreqX/polling_interval So, if 'interrupt-driven' flag of devfreq governor is 1, the devfreq governor is able to use the 'polling_interval' sysfs interface to get the new polling interval value. But, the devfreq core doesn't schedule out the polling work for this governor like NVIDIA Tegra30 ACTMON governor. 2. Update devfreq drivers - For exynos-bus.c, remove unused property from dt-binding documentation - For tegra30-devfreq.c, update the internal behavior like fixing the overflow integer issue and clean-up code. 3. Update devfreq-event driver - For exynos-ppmu.c, add exynos_ppmu.h dt-binding file for 'event-data-type' filed. and update dt-binging documentation. Also, Fix minor coding style." * tag 'devfreq-next-for-5.5' of git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/linux: (25 commits) PM / devfreq: tegra30: Tune up MCCPU boost-down coefficient PM / devfreq: tegra30: Support variable polling interval PM / devfreq: Add new interrupt_driven flag for governors PM / devfreq: tegra30: Use kHz units for dependency threshold PM / devfreq: tegra30: Disable consecutive interrupts when appropriate PM / devfreq: tegra30: Don't enable already enabled consecutive interrupts PM / devfreq: tegra30: Include appropriate header PM / devfreq: tegra30: Constify structs PM / devfreq: tegra30: Don't enable consecutive-down interrupt on startup PM / devfreq: tegra30: Reset boosting on startup PM / devfreq: tegra30: Move clk-notifier's registration to governor's start PM / devfreq: tegra30: Use CPUFreq notifier PM / devfreq: tegra30: Use kHz units uniformly in the code PM / devfreq: tegra30: Fix integer overflow on CPU's freq max out PM / devfreq: tegra30: Drop write-barrier PM / devfreq: tegra30: Handle possible round-rate error PM / devfreq: tegra30: Keep interrupt disabled while governor is stopped PM / devfreq: tegra30: Change irq type to unsigned int PM / devfreq: exynos-ppmu: remove useless assignment PM / devfreq: Lock devfreq in trans_stat_show ...
2 parents c389ec6 + fee2285 commit 2b32842

File tree

8 files changed

+386
-122
lines changed

8 files changed

+386
-122
lines changed

Documentation/devicetree/bindings/devfreq/event/exynos-ppmu.txt

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,23 @@ The Exynos PPMU driver uses the devfreq-event class to provide event data
1010
to various devfreq devices. The devfreq devices would use the event data when
1111
derterming the current state of each IP.
1212

13-
Required properties:
13+
Required properties for PPMU device:
1414
- compatible: Should be "samsung,exynos-ppmu" or "samsung,exynos-ppmu-v2.
1515
- reg: physical base address of each PPMU and length of memory mapped region.
1616

17-
Optional properties:
17+
Optional properties for PPMU device:
1818
- clock-names : the name of clock used by the PPMU, "ppmu"
1919
- clocks : phandles for clock specified in "clock-names" property
2020

21+
Required properties for 'events' child node of PPMU device:
22+
- event-name : the unique event name among PPMU device
23+
Optional properties for 'events' child node of PPMU device:
24+
- event-data-type : Define the type of data which shell be counted
25+
by the counter. You can check include/dt-bindings/pmu/exynos_ppmu.h for
26+
all possible type, i.e. count read requests, count write data in bytes,
27+
etc. This field is optional and when it is missing, the driver code
28+
will use default data type.
29+
2130
Example1 : PPMUv1 nodes in exynos3250.dtsi are listed below.
2231

2332
ppmu_dmc0: ppmu_dmc0@106a0000 {
@@ -145,3 +154,16 @@ Example3 : PPMUv2 nodes in exynos5433.dtsi are listed below.
145154
reg = <0x104d0000 0x2000>;
146155
status = "disabled";
147156
};
157+
158+
Example4 : 'event-data-type' in exynos4412-ppmu-common.dtsi are listed below.
159+
160+
&ppmu_dmc0 {
161+
status = "okay";
162+
events {
163+
ppmu_dmc0_3: ppmu-event3-dmc0 {
164+
event-name = "ppmu-event3-dmc0";
165+
event-data-type = <(PPMU_RO_DATA_CNT |
166+
PPMU_WO_DATA_CNT)>;
167+
};
168+
};
169+
};

Documentation/devicetree/bindings/devfreq/exynos-bus.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@ Required properties only for passive bus device:
5050
Optional properties only for parent bus device:
5151
- exynos,saturation-ratio: the percentage value which is used to calibrate
5252
the performance count against total cycle count.
53-
- exynos,voltage-tolerance: the percentage value for bus voltage tolerance
54-
which is used to calculate the max voltage.
5553

5654
Detailed correlation between sub-blocks and power line according to Exynos SoC:
5755
- In case of Exynos3250, there are two power line as following:

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4778,6 +4778,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/linux.git
47784778
S: Supported
47794779
F: drivers/devfreq/event/
47804780
F: drivers/devfreq/devfreq-event.c
4781+
F: include/dt-bindings/pmu/exynos_ppmu.h
47814782
F: include/linux/devfreq-event.h
47824783
F: Documentation/devicetree/bindings/devfreq/event/
47834784

drivers/devfreq/devfreq.c

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ int devfreq_update_status(struct devfreq *devfreq, unsigned long freq)
160160
int lev, prev_lev, ret = 0;
161161
unsigned long cur_time;
162162

163+
lockdep_assert_held(&devfreq->lock);
163164
cur_time = jiffies;
164165

165166
/* Immediately exit if previous_freq is not initialized yet. */
@@ -409,6 +410,9 @@ static void devfreq_monitor(struct work_struct *work)
409410
*/
410411
void devfreq_monitor_start(struct devfreq *devfreq)
411412
{
413+
if (devfreq->governor->interrupt_driven)
414+
return;
415+
412416
INIT_DEFERRABLE_WORK(&devfreq->work, devfreq_monitor);
413417
if (devfreq->profile->polling_ms)
414418
queue_delayed_work(devfreq_wq, &devfreq->work,
@@ -426,6 +430,9 @@ EXPORT_SYMBOL(devfreq_monitor_start);
426430
*/
427431
void devfreq_monitor_stop(struct devfreq *devfreq)
428432
{
433+
if (devfreq->governor->interrupt_driven)
434+
return;
435+
429436
cancel_delayed_work_sync(&devfreq->work);
430437
}
431438
EXPORT_SYMBOL(devfreq_monitor_stop);
@@ -453,6 +460,10 @@ void devfreq_monitor_suspend(struct devfreq *devfreq)
453460
devfreq_update_status(devfreq, devfreq->previous_freq);
454461
devfreq->stop_polling = true;
455462
mutex_unlock(&devfreq->lock);
463+
464+
if (devfreq->governor->interrupt_driven)
465+
return;
466+
456467
cancel_delayed_work_sync(&devfreq->work);
457468
}
458469
EXPORT_SYMBOL(devfreq_monitor_suspend);
@@ -473,11 +484,15 @@ void devfreq_monitor_resume(struct devfreq *devfreq)
473484
if (!devfreq->stop_polling)
474485
goto out;
475486

487+
if (devfreq->governor->interrupt_driven)
488+
goto out_update;
489+
476490
if (!delayed_work_pending(&devfreq->work) &&
477491
devfreq->profile->polling_ms)
478492
queue_delayed_work(devfreq_wq, &devfreq->work,
479493
msecs_to_jiffies(devfreq->profile->polling_ms));
480494

495+
out_update:
481496
devfreq->last_stat_updated = jiffies;
482497
devfreq->stop_polling = false;
483498

@@ -509,6 +524,9 @@ void devfreq_interval_update(struct devfreq *devfreq, unsigned int *delay)
509524
if (devfreq->stop_polling)
510525
goto out;
511526

527+
if (devfreq->governor->interrupt_driven)
528+
goto out;
529+
512530
/* if new delay is zero, stop polling */
513531
if (!new_delay) {
514532
mutex_unlock(&devfreq->lock);
@@ -625,7 +643,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
625643
devfreq = find_device_devfreq(dev);
626644
mutex_unlock(&devfreq_list_lock);
627645
if (!IS_ERR(devfreq)) {
628-
dev_err(dev, "%s: Unable to create devfreq for the device.\n",
646+
dev_err(dev, "%s: devfreq device already exists!\n",
629647
__func__);
630648
err = -EINVAL;
631649
goto err_out;
@@ -1195,7 +1213,7 @@ static ssize_t available_governors_show(struct device *d,
11951213
* The devfreq with immutable governor (e.g., passive) shows
11961214
* only own governor.
11971215
*/
1198-
if (df->governor->immutable) {
1216+
if (df->governor && df->governor->immutable) {
11991217
count = scnprintf(&buf[count], DEVFREQ_NAME_LEN,
12001218
"%s ", df->governor_name);
12011219
/*
@@ -1397,12 +1415,17 @@ static ssize_t trans_stat_show(struct device *dev,
13971415
int i, j;
13981416
unsigned int max_state = devfreq->profile->max_state;
13991417

1400-
if (!devfreq->stop_polling &&
1401-
devfreq_update_status(devfreq, devfreq->previous_freq))
1402-
return 0;
14031418
if (max_state == 0)
14041419
return sprintf(buf, "Not Supported.\n");
14051420

1421+
mutex_lock(&devfreq->lock);
1422+
if (!devfreq->stop_polling &&
1423+
devfreq_update_status(devfreq, devfreq->previous_freq)) {
1424+
mutex_unlock(&devfreq->lock);
1425+
return 0;
1426+
}
1427+
mutex_unlock(&devfreq->lock);
1428+
14061429
len = sprintf(buf, " From : To\n");
14071430
len += sprintf(buf + len, " :");
14081431
for (i = 0; i < max_state; i++)

drivers/devfreq/event/exynos-ppmu.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,6 @@ static int exynos_ppmu_probe(struct platform_device *pdev)
673673
for (i = 0; i < info->num_events; i++) {
674674
edev[i] = devm_devfreq_event_add_edev(&pdev->dev, &desc[i]);
675675
if (IS_ERR(edev[i])) {
676-
ret = PTR_ERR(edev[i]);
677676
dev_err(&pdev->dev,
678677
"failed to add devfreq-event device\n");
679678
return PTR_ERR(edev[i]);

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)