Skip to content

Commit fa6a599

Browse files
committed
Merge branch 'pm-devfreq'
* pm-devfreq: (26 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 c48b90f + 2b32842 commit fa6a599

File tree

8 files changed

+390
-126
lines changed

8 files changed

+390
-126
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: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3532,7 +3532,7 @@ BUS FREQUENCY DRIVER FOR SAMSUNG EXYNOS
35323532
M: Chanwoo Choi <[email protected]>
35333533
35343534
3535-
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq.git
3535+
T: git git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/linux.git
35363536
S: Maintained
35373537
F: drivers/devfreq/exynos-bus.c
35383538
F: Documentation/devicetree/bindings/devfreq/exynos-bus.txt
@@ -4760,9 +4760,9 @@ F: include/linux/devcoredump.h
47604760
DEVICE FREQUENCY (DEVFREQ)
47614761
M: MyungJoo Ham <[email protected]>
47624762
M: Kyungmin Park <[email protected]>
4763-
R: Chanwoo Choi <[email protected]>
4763+
M: Chanwoo Choi <[email protected]>
47644764
4765-
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq.git
4765+
T: git git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/linux.git
47664766
S: Maintained
47674767
F: drivers/devfreq/
47684768
F: include/linux/devfreq.h
@@ -4772,10 +4772,11 @@ F: include/trace/events/devfreq.h
47724772
DEVICE FREQUENCY EVENT (DEVFREQ-EVENT)
47734773
M: Chanwoo Choi <[email protected]>
47744774
4775-
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq.git
4775+
T: git git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/linux.git
47764776
S: Supported
47774777
F: drivers/devfreq/event/
47784778
F: drivers/devfreq/devfreq-event.c
4779+
F: include/dt-bindings/pmu/exynos_ppmu.h
47794780
F: include/linux/devfreq-event.h
47804781
F: Documentation/devicetree/bindings/devfreq/event/
47814782

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)