Skip to content

Commit

Permalink
Merge branch 'pm-devfreq' into pm-for-linus
Browse files Browse the repository at this point in the history
* pm-devfreq:
  PM / devfreq: Add basic governors
  PM / devfreq: Add common sysfs interfaces
  PM: Introduce devfreq: generic DVFS framework with device-specific OPPs
  PM / OPP: Add OPP availability change notifier.
  • Loading branch information
Rafael J. Wysocki committed Oct 7, 2011
2 parents 9696cc9 + ce26c5b commit 7811ac2
Show file tree
Hide file tree
Showing 14 changed files with 1,303 additions and 0 deletions.
52 changes: 52 additions & 0 deletions Documentation/ABI/testing/sysfs-class-devfreq
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
What: /sys/class/devfreq/.../
Date: September 2011
Contact: MyungJoo Ham <myungjoo.ham@samsung.com>
Description:
Provide a place in sysfs for the devfreq objects.
This allows accessing various devfreq specific variables.
The name of devfreq object denoted as ... is same as the
name of device using devfreq.

What: /sys/class/devfreq/.../governor
Date: September 2011
Contact: MyungJoo Ham <myungjoo.ham@samsung.com>
Description:
The /sys/class/devfreq/.../governor shows the name of the
governor used by the corresponding devfreq object.

What: /sys/class/devfreq/.../cur_freq
Date: September 2011
Contact: MyungJoo Ham <myungjoo.ham@samsung.com>
Description:
The /sys/class/devfreq/.../cur_freq shows the current
frequency of the corresponding devfreq object.

What: /sys/class/devfreq/.../central_polling
Date: September 2011
Contact: MyungJoo Ham <myungjoo.ham@samsung.com>
Description:
The /sys/class/devfreq/.../central_polling shows whether
the devfreq ojbect is using devfreq-provided central
polling mechanism or not.

What: /sys/class/devfreq/.../polling_interval
Date: September 2011
Contact: MyungJoo Ham <myungjoo.ham@samsung.com>
Description:
The /sys/class/devfreq/.../polling_interval shows and sets
the requested polling interval of the corresponding devfreq
object. The values are represented in ms. If the value is
less than 1 jiffy, it is considered to be 0, which means
no polling. This value is meaningless if the governor is
not polling; thus. If the governor is not using
devfreq-provided central polling
(/sys/class/devfreq/.../central_polling is 0), this value
may be useless.

What: /sys/class/devfreq/.../userspace/set_freq
Date: September 2011
Contact: MyungJoo Ham <myungjoo.ham@samsung.com>
Description:
The /sys/class/devfreq/.../userspace/set_freq shows and
sets the requested frequency for the devfreq object if
userspace governor is in effect.
2 changes: 2 additions & 0 deletions drivers/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,6 @@ source "drivers/iommu/Kconfig"

source "drivers/virt/Kconfig"

source "drivers/devfreq/Kconfig"

endmenu
2 changes: 2 additions & 0 deletions drivers/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,5 @@ obj-$(CONFIG_IOMMU_SUPPORT) += iommu/

# Virtualization drivers
obj-$(CONFIG_VIRT_DRIVERS) += virt/

obj-$(CONFIG_PM_DEVFREQ) += devfreq/
30 changes: 30 additions & 0 deletions drivers/base/power/opp.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ struct opp {
* RCU usage: nodes are not modified in the list of device_opp,
* however addition is possible and is secured by dev_opp_list_lock
* @dev: device pointer
* @head: notifier head to notify the OPP availability changes.
* @opp_list: list of opps
*
* This is an internal data structure maintaining the link to opps attached to
Expand All @@ -83,6 +84,7 @@ struct device_opp {
struct list_head node;

struct device *dev;
struct srcu_notifier_head head;
struct list_head opp_list;
};

Expand Down Expand Up @@ -404,6 +406,7 @@ int opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
}

dev_opp->dev = dev;
srcu_init_notifier_head(&dev_opp->head);
INIT_LIST_HEAD(&dev_opp->opp_list);

/* Secure the device list modification */
Expand All @@ -428,6 +431,11 @@ int opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
list_add_rcu(&new_opp->node, head);
mutex_unlock(&dev_opp_list_lock);

/*
* Notify the changes in the availability of the operable
* frequency/voltage list.
*/
srcu_notifier_call_chain(&dev_opp->head, OPP_EVENT_ADD, new_opp);
return 0;
}

Expand Down Expand Up @@ -504,6 +512,14 @@ static int opp_set_availability(struct device *dev, unsigned long freq,
mutex_unlock(&dev_opp_list_lock);
synchronize_rcu();

/* Notify the change of the OPP availability */
if (availability_req)
srcu_notifier_call_chain(&dev_opp->head, OPP_EVENT_ENABLE,
new_opp);
else
srcu_notifier_call_chain(&dev_opp->head, OPP_EVENT_DISABLE,
new_opp);

/* clean up old opp */
new_opp = opp;
goto out;
Expand Down Expand Up @@ -643,3 +659,17 @@ void opp_free_cpufreq_table(struct device *dev,
*table = NULL;
}
#endif /* CONFIG_CPU_FREQ */

/**
* opp_get_notifier() - find notifier_head of the device with opp
* @dev: device pointer used to lookup device OPPs.
*/
struct srcu_notifier_head *opp_get_notifier(struct device *dev)
{
struct device_opp *dev_opp = find_device_opp(dev);

if (IS_ERR(dev_opp))
return ERR_PTR(PTR_ERR(dev_opp)); /* matching type */

return &dev_opp->head;
}
75 changes: 75 additions & 0 deletions drivers/devfreq/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
config ARCH_HAS_DEVFREQ
bool
depends on ARCH_HAS_OPP
help
Denotes that the architecture supports DEVFREQ. If the architecture
supports multiple OPP entries per device and the frequency of the
devices with OPPs may be altered dynamically, the architecture
supports DEVFREQ.

menuconfig PM_DEVFREQ
bool "Generic Dynamic Voltage and Frequency Scaling (DVFS) support"
depends on PM_OPP && ARCH_HAS_DEVFREQ
help
With OPP support, a device may have a list of frequencies and
voltages available. DEVFREQ, a generic DVFS framework can be
registered for a device with OPP support in order to let the
governor provided to DEVFREQ choose an operating frequency
based on the OPP's list and the policy given with DEVFREQ.

Each device may have its own governor and policy. DEVFREQ can
reevaluate the device state periodically and/or based on the
OPP list changes (each frequency/voltage pair in OPP may be
disabled or enabled).

Like some CPUs with CPUFREQ, a device may have multiple clocks.
However, because the clock frequencies of a single device are
determined by the single device's state, an instance of DEVFREQ
is attached to a single device and returns a "representative"
clock frequency from the OPP of the device, which is also attached
to a device by 1-to-1. The device registering DEVFREQ takes the
responsiblity to "interpret" the frequency listed in OPP and
to set its every clock accordingly with the "target" callback
given to DEVFREQ.

if PM_DEVFREQ

comment "DEVFREQ Governors"

config DEVFREQ_GOV_SIMPLE_ONDEMAND
bool "Simple Ondemand"
help
Chooses frequency based on the recent load on the device. Works
similar as ONDEMAND governor of CPUFREQ does. A device with
Simple-Ondemand should be able to provide busy/total counter
values that imply the usage rate. A device may provide tuned
values to the governor with data field at devfreq_add_device().

config DEVFREQ_GOV_PERFORMANCE
bool "Performance"
help
Sets the frequency at the maximum available frequency.
This governor always returns UINT_MAX as frequency so that
the DEVFREQ framework returns the highest frequency available
at any time.

config DEVFREQ_GOV_POWERSAVE
bool "Powersave"
help
Sets the frequency at the minimum available frequency.
This governor always returns 0 as frequency so that
the DEVFREQ framework returns the lowest frequency available
at any time.

config DEVFREQ_GOV_USERSPACE
bool "Userspace"
help
Sets the frequency at the user specified one.
This governor returns the user configured frequency if there
has been an input to /sys/devices/.../power/devfreq_set_freq.
Otherwise, the governor does not change the frequnecy
given at the initialization.

comment "DEVFREQ Drivers"

endif # PM_DEVFREQ
5 changes: 5 additions & 0 deletions drivers/devfreq/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
obj-$(CONFIG_PM_DEVFREQ) += devfreq.o
obj-$(CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND) += governor_simpleondemand.o
obj-$(CONFIG_DEVFREQ_GOV_PERFORMANCE) += governor_performance.o
obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE) += governor_powersave.o
obj-$(CONFIG_DEVFREQ_GOV_USERSPACE) += governor_userspace.o
Loading

0 comments on commit 7811ac2

Please sign in to comment.