You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'pm+acpi-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI and power management updates from Rafael Wysocki: - Rework of the ACPI namespace scanning code from Rafael J. Wysocki with contributions from Bjorn Helgaas, Jiang Liu, Mika Westerberg, Toshi Kani, and Yinghai Lu. - ACPI power resources handling and ACPI device PM update from Rafael J Wysocki. - ACPICA update to version 20130117 from Bob Moore and Lv Zheng with contributions from Aaron Lu, Chao Guan, Jesper Juhl, and Tim Gardner. - Support for Intel Lynxpoint LPSS from Mika Westerberg. - cpuidle update from Len Brown including Intel Haswell support, C1 state for intel_idle, removal of global pm_idle. - cpuidle fixes and cleanups from Daniel Lezcano. - cpufreq fixes and cleanups from Viresh Kumar and Fabio Baltieri with contributions from Stratos Karafotis and Rickard Andersson. - Intel P-states driver for Sandy Bridge processors from Dirk Brandewie. - cpufreq driver for Marvell Kirkwood SoCs from Andrew Lunn. - cpufreq fixes related to ordering issues between acpi-cpufreq and powernow-k8 from Borislav Petkov and Matthew Garrett. - cpufreq support for Calxeda Highbank processors from Mark Langsdorf and Rob Herring. - cpufreq driver for the Freescale i.MX6Q SoC and cpufreq-cpu0 update from Shawn Guo. - cpufreq Exynos fixes and cleanups from Jonghwan Choi, Sachin Kamat, and Inderpal Singh. - Support for "lightweight suspend" from Zhang Rui. - Removal of the deprecated power trace API from Paul Gortmaker. - Assorted updates from Andreas Fleig, Colin Ian King, Davidlohr Bueso, Joseph Salisbury, Kees Cook, Li Fei, Nishanth Menon, ShuoX Liu, Srinivas Pandruvada, Tejun Heo, Thomas Renninger, and Yasuaki Ishimatsu. * tag 'pm+acpi-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (267 commits) PM idle: remove global declaration of pm_idle unicore32 idle: delete stray pm_idle comment openrisc idle: delete pm_idle mn10300 idle: delete pm_idle microblaze idle: delete pm_idle m32r idle: delete pm_idle, and other dead idle code ia64 idle: delete pm_idle cris idle: delete idle and pm_idle ARM64 idle: delete pm_idle ARM idle: delete pm_idle blackfin idle: delete pm_idle sparc idle: rename pm_idle to sparc_idle sh idle: rename global pm_idle to static sh_idle x86 idle: rename global pm_idle to static x86_idle APM idle: register apm_cpu_idle via cpuidle cpufreq / intel_pstate: Add kernel command line option disable intel_pstate. cpufreq / intel_pstate: Change to disallow module build tools/power turbostat: display SMI count by default intel_idle: export both C1 and C1E ACPI / hotplug: Fix concurrency issues and memory leaks ...
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
What: /sys/devices/.../power_resources_D0/
|
||||
Date: January 2013
|
||||
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
Description:
|
||||
The /sys/devices/.../power_resources_D0/ directory is only
|
||||
present for device objects representing ACPI device nodes that
|
||||
use ACPI power resources for power management.
|
||||
|
||||
If present, it contains symbolic links to device directories
|
||||
representing ACPI power resources that need to be turned on for
|
||||
the given device node to be in ACPI power state D0. The names
|
||||
of the links are the same as the names of the directories they
|
||||
point to.
|
||||
@@ -0,0 +1,14 @@
|
||||
What: /sys/devices/.../power_resources_D1/
|
||||
Date: January 2013
|
||||
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
Description:
|
||||
The /sys/devices/.../power_resources_D1/ directory is only
|
||||
present for device objects representing ACPI device nodes that
|
||||
use ACPI power resources for power management and support ACPI
|
||||
power state D1.
|
||||
|
||||
If present, it contains symbolic links to device directories
|
||||
representing ACPI power resources that need to be turned on for
|
||||
the given device node to be in ACPI power state D1. The names
|
||||
of the links are the same as the names of the directories they
|
||||
point to.
|
||||
@@ -0,0 +1,14 @@
|
||||
What: /sys/devices/.../power_resources_D2/
|
||||
Date: January 2013
|
||||
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
Description:
|
||||
The /sys/devices/.../power_resources_D2/ directory is only
|
||||
present for device objects representing ACPI device nodes that
|
||||
use ACPI power resources for power management and support ACPI
|
||||
power state D2.
|
||||
|
||||
If present, it contains symbolic links to device directories
|
||||
representing ACPI power resources that need to be turned on for
|
||||
the given device node to be in ACPI power state D2. The names
|
||||
of the links are the same as the names of the directories they
|
||||
point to.
|
||||
@@ -0,0 +1,14 @@
|
||||
What: /sys/devices/.../power_resources_D3hot/
|
||||
Date: January 2013
|
||||
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
Description:
|
||||
The /sys/devices/.../power_resources_D3hot/ directory is only
|
||||
present for device objects representing ACPI device nodes that
|
||||
use ACPI power resources for power management and support ACPI
|
||||
power state D3hot.
|
||||
|
||||
If present, it contains symbolic links to device directories
|
||||
representing ACPI power resources that need to be turned on for
|
||||
the given device node to be in ACPI power state D3hot. The
|
||||
names of the links are the same as the names of the directories
|
||||
they point to.
|
||||
@@ -0,0 +1,20 @@
|
||||
What: /sys/devices/.../power_state
|
||||
Date: January 2013
|
||||
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
Description:
|
||||
The /sys/devices/.../power_state attribute is only present for
|
||||
device objects representing ACPI device nodes that provide power
|
||||
management methods.
|
||||
|
||||
If present, it contains a string representing the current ACPI
|
||||
power state of the given device node. Its possible values,
|
||||
"D0", "D1", "D2", "D3hot", and "D3cold", reflect the power state
|
||||
names defined by the ACPI specification (ACPI 4 and above).
|
||||
|
||||
If the device node uses shared ACPI power resources, this state
|
||||
determines a list of power resources required not to be turned
|
||||
off. However, some power resources needed by the device node in
|
||||
higher-power (lower-number) states may also be ON because of
|
||||
some other devices using them at the moment.
|
||||
|
||||
This attribute is read-only.
|
||||
@@ -0,0 +1,23 @@
|
||||
What: /sys/devices/.../real_power_state
|
||||
Date: January 2013
|
||||
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
Description:
|
||||
The /sys/devices/.../real_power_state attribute is only present
|
||||
for device objects representing ACPI device nodes that provide
|
||||
power management methods and use ACPI power resources for power
|
||||
management.
|
||||
|
||||
If present, it contains a string representing the real ACPI
|
||||
power state of the given device node as returned by the _PSC
|
||||
control method or inferred from the configuration of power
|
||||
resources. Its possible values, "D0", "D1", "D2", "D3hot", and
|
||||
"D3cold", reflect the power state names defined by the ACPI
|
||||
specification (ACPI 4 and above).
|
||||
|
||||
In some situations the value of this attribute may be different
|
||||
from the value of the /sys/devices/.../power_state attribute for
|
||||
the same device object. If that happens, some shared power
|
||||
resources used by the device node are only ON because of some
|
||||
other devices using them at the moment.
|
||||
|
||||
This attribute is read-only.
|
||||
@@ -0,0 +1,12 @@
|
||||
What: /sys/devices/.../resource_in_use
|
||||
Date: January 2013
|
||||
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
Description:
|
||||
The /sys/devices/.../resource_in_use attribute is only present
|
||||
for device objects representing ACPI power resources.
|
||||
|
||||
If present, it contains a number (0 or 1) representing the
|
||||
current status of the given power resource (0 means that the
|
||||
resource is not in use and therefore it has been turned off).
|
||||
|
||||
This attribute is read-only.
|
||||
@@ -63,8 +63,8 @@ from ACPI tables.
|
||||
Currently the kernel is not able to automatically determine from which ACPI
|
||||
device it should make the corresponding platform device so we need to add
|
||||
the ACPI device explicitly to acpi_platform_device_ids list defined in
|
||||
drivers/acpi/scan.c. This limitation is only for the platform devices, SPI
|
||||
and I2C devices are created automatically as described below.
|
||||
drivers/acpi/acpi_platform.c. This limitation is only for the platform
|
||||
devices, SPI and I2C devices are created automatically as described below.
|
||||
|
||||
SPI serial bus support
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
ACPI Scan Handlers
|
||||
|
||||
Copyright (C) 2012, Intel Corporation
|
||||
Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
|
||||
During system initialization and ACPI-based device hot-add, the ACPI namespace
|
||||
is scanned in search of device objects that generally represent various pieces
|
||||
of hardware. This causes a struct acpi_device object to be created and
|
||||
registered with the driver core for every device object in the ACPI namespace
|
||||
and the hierarchy of those struct acpi_device objects reflects the namespace
|
||||
layout (i.e. parent device objects in the namespace are represented by parent
|
||||
struct acpi_device objects and analogously for their children). Those struct
|
||||
acpi_device objects are referred to as "device nodes" in what follows, but they
|
||||
should not be confused with struct device_node objects used by the Device Trees
|
||||
parsing code (although their role is analogous to the role of those objects).
|
||||
|
||||
During ACPI-based device hot-remove device nodes representing pieces of hardware
|
||||
being removed are unregistered and deleted.
|
||||
|
||||
The core ACPI namespace scanning code in drivers/acpi/scan.c carries out basic
|
||||
initialization of device nodes, such as retrieving common configuration
|
||||
information from the device objects represented by them and populating them with
|
||||
appropriate data, but some of them require additional handling after they have
|
||||
been registered. For example, if the given device node represents a PCI host
|
||||
bridge, its registration should cause the PCI bus under that bridge to be
|
||||
enumerated and PCI devices on that bus to be registered with the driver core.
|
||||
Similarly, if the device node represents a PCI interrupt link, it is necessary
|
||||
to configure that link so that the kernel can use it.
|
||||
|
||||
Those additional configuration tasks usually depend on the type of the hardware
|
||||
component represented by the given device node which can be determined on the
|
||||
basis of the device node's hardware ID (HID). They are performed by objects
|
||||
called ACPI scan handlers represented by the following structure:
|
||||
|
||||
struct acpi_scan_handler {
|
||||
const struct acpi_device_id *ids;
|
||||
struct list_head list_node;
|
||||
int (*attach)(struct acpi_device *dev, const struct acpi_device_id *id);
|
||||
void (*detach)(struct acpi_device *dev);
|
||||
};
|
||||
|
||||
where ids is the list of IDs of device nodes the given handler is supposed to
|
||||
take care of, list_node is the hook to the global list of ACPI scan handlers
|
||||
maintained by the ACPI core and the .attach() and .detach() callbacks are
|
||||
executed, respectively, after registration of new device nodes and before
|
||||
unregistration of device nodes the handler attached to previously.
|
||||
|
||||
The namespace scanning function, acpi_bus_scan(), first registers all of the
|
||||
device nodes in the given namespace scope with the driver core. Then, it tries
|
||||
to match a scan handler against each of them using the ids arrays of the
|
||||
available scan handlers. If a matching scan handler is found, its .attach()
|
||||
callback is executed for the given device node. If that callback returns 1,
|
||||
that means that the handler has claimed the device node and is now responsible
|
||||
for carrying out any additional configuration tasks related to it. It also will
|
||||
be responsible for preparing the device node for unregistration in that case.
|
||||
The device node's handler field is then populated with the address of the scan
|
||||
handler that has claimed it.
|
||||
|
||||
If the .attach() callback returns 0, it means that the device node is not
|
||||
interesting to the given scan handler and may be matched against the next scan
|
||||
handler in the list. If it returns a (negative) error code, that means that
|
||||
the namespace scan should be terminated due to a serious error. The error code
|
||||
returned should then reflect the type of the error.
|
||||
|
||||
The namespace trimming function, acpi_bus_trim(), first executes .detach()
|
||||
callbacks from the scan handlers of all device nodes in the given namespace
|
||||
scope (if they have scan handlers). Next, it unregisters all of the device
|
||||
nodes in that scope.
|
||||
|
||||
ACPI scan handlers can be added to the list maintained by the ACPI core with the
|
||||
help of the acpi_scan_add_handler() function taking a pointer to the new scan
|
||||
handler as an argument. The order in which scan handlers are added to the list
|
||||
is the order in which they are matched against device nodes during namespace
|
||||
scans.
|
||||
|
||||
All scan handles must be added to the list before acpi_bus_scan() is run for the
|
||||
first time and they cannot be removed from it.
|
||||
@@ -111,6 +111,12 @@ policy->governor must contain the "default policy" for
|
||||
For setting some of these values, the frequency table helpers might be
|
||||
helpful. See the section 2 for more information on them.
|
||||
|
||||
SMP systems normally have same clock source for a group of cpus. For these the
|
||||
.init() would be called only once for the first online cpu. Here the .init()
|
||||
routine must initialize policy->cpus with mask of all possible cpus (Online +
|
||||
Offline) that share the clock. Then the core would copy this mask onto
|
||||
policy->related_cpus and will reset policy->cpus to carry only online cpus.
|
||||
|
||||
|
||||
1.3 verify
|
||||
------------
|
||||
|
||||
@@ -190,11 +190,11 @@ scaling_max_freq show the current "policy limits" (in
|
||||
first set scaling_max_freq, then
|
||||
scaling_min_freq.
|
||||
|
||||
affected_cpus : List of CPUs that require software coordination
|
||||
of frequency.
|
||||
affected_cpus : List of Online CPUs that require software
|
||||
coordination of frequency.
|
||||
|
||||
related_cpus : List of CPUs that need some sort of frequency
|
||||
coordination, whether software or hardware.
|
||||
related_cpus : List of Online + Offline CPUs that need software
|
||||
coordination of frequency.
|
||||
|
||||
scaling_driver : Hardware driver for cpufreq.
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
Marvell Kirkwood Platforms Device Tree Bindings
|
||||
-----------------------------------------------
|
||||
|
||||
Boards with a SoC of the Marvell Kirkwood
|
||||
shall have the following property:
|
||||
|
||||
Required root node property:
|
||||
|
||||
compatible: must contain "marvell,kirkwood";
|
||||
|
||||
In order to support the kirkwood cpufreq driver, there must be a node
|
||||
cpus/cpu@0 with three clocks, "cpu_clk", "ddrclk" and "powersave",
|
||||
where the "powersave" clock is a gating clock used to switch the CPU
|
||||
between the "cpu_clk" and the "ddrclk".
|
||||
|
||||
Example:
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "marvell,sheeva-88SV131";
|
||||
clocks = <&core_clk 1>, <&core_clk 3>, <&gate_clk 11>;
|
||||
clock-names = "cpu_clk", "ddrclk", "powersave";
|
||||
};
|
||||
@@ -1039,16 +1039,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
Claim all unknown PCI IDE storage controllers.
|
||||
|
||||
idle= [X86]
|
||||
Format: idle=poll, idle=mwait, idle=halt, idle=nomwait
|
||||
Format: idle=poll, idle=halt, idle=nomwait
|
||||
Poll forces a polling idle loop that can slightly
|
||||
improve the performance of waking up a idle CPU, but
|
||||
will use a lot of power and make the system run hot.
|
||||
Not recommended.
|
||||
idle=mwait: On systems which support MONITOR/MWAIT but
|
||||
the kernel chose to not use it because it doesn't save
|
||||
as much power as a normal idle loop, use the
|
||||
MONITOR/MWAIT idle loop anyways. Performance should be
|
||||
the same as idle=poll.
|
||||
idle=halt: Halt is forced to be used for CPU idle.
|
||||
In such case C2/C3 won't be used again.
|
||||
idle=nomwait: Disable mwait for CPU C-states
|
||||
@@ -1131,6 +1126,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
0 disables intel_idle and fall back on acpi_idle.
|
||||
1 to 6 specify maximum depth of C-state.
|
||||
|
||||
intel_pstate= [X86]
|
||||
disable
|
||||
Do not enable intel_pstate as the default
|
||||
scaling driver for the supported processors
|
||||
|
||||
intremap= [X86-64, Intel-IOMMU]
|
||||
on enable Interrupt Remapping (default)
|
||||
off disable Interrupt Remapping
|
||||
@@ -1886,10 +1886,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
wfi(ARM) instruction doesn't work correctly and not to
|
||||
use it. This is also useful when using JTAG debugger.
|
||||
|
||||
no-hlt [BUGS=X86-32] Tells the kernel that the hlt
|
||||
instruction doesn't work correctly and not to
|
||||
use it.
|
||||
|
||||
no_file_caps Tells the kernel not to honor file capabilities. The
|
||||
only way then for a file to be executed with privilege
|
||||
is to be setuid root or executed by root.
|
||||
|
||||
@@ -223,3 +223,8 @@ since they ask the freezer to skip freezing this task, since it is anyway
|
||||
only after the entire suspend/hibernation sequence is complete.
|
||||
So, to summarize, use [un]lock_system_sleep() instead of directly using
|
||||
mutex_[un]lock(&pm_mutex). That would prevent freezing failures.
|
||||
|
||||
V. Miscellaneous
|
||||
/sys/power/pm_freeze_timeout controls how long it will cost at most to freeze
|
||||
all user space processes or all freezable kernel threads, in unit of millisecond.
|
||||
The default value is 20000, with range of unsigned integer.
|
||||
|
||||
@@ -426,6 +426,10 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
|
||||
'power.runtime_error' is set or 'power.disable_depth' is greater than
|
||||
zero)
|
||||
|
||||
bool pm_runtime_active(struct device *dev);
|
||||
- return true if the device's runtime PM status is 'active' or its
|
||||
'power.disable_depth' field is not equal to zero, or false otherwise
|
||||
|
||||
bool pm_runtime_suspended(struct device *dev);
|
||||
- return true if the device's runtime PM status is 'suspended' and its
|
||||
'power.disable_depth' field is equal to zero, or false otherwise
|
||||
|
||||
@@ -17,7 +17,7 @@ Cf. include/trace/events/power.h for the events definitions.
|
||||
1. Power state switch events
|
||||
============================
|
||||
|
||||
1.1 New trace API
|
||||
1.1 Trace API
|
||||
-----------------
|
||||
|
||||
A 'cpu' event class gathers the CPU-related events: cpuidle and
|
||||
@@ -41,31 +41,6 @@ The event which has 'state=4294967295' in the trace is very important to the use
|
||||
space tools which are using it to detect the end of the current state, and so to
|
||||
correctly draw the states diagrams and to calculate accurate statistics etc.
|
||||
|
||||
1.2 DEPRECATED trace API
|
||||
------------------------
|
||||
|
||||
A new Kconfig option CONFIG_EVENT_POWER_TRACING_DEPRECATED with the default value of
|
||||
'y' has been created. This allows the legacy trace power API to be used conjointly
|
||||
with the new trace API.
|
||||
The Kconfig option, the old trace API (in include/trace/events/power.h) and the
|
||||
old trace points will disappear in a future release (namely 2.6.41).
|
||||
|
||||
power_start "type=%lu state=%lu cpu_id=%lu"
|
||||
power_frequency "type=%lu state=%lu cpu_id=%lu"
|
||||
power_end "cpu_id=%lu"
|
||||
|
||||
The 'type' parameter takes one of those macros:
|
||||
. POWER_NONE = 0,
|
||||
. POWER_CSTATE = 1, /* C-State */
|
||||
. POWER_PSTATE = 2, /* Frequency change or DVFS */
|
||||
|
||||
The 'state' parameter is set depending on the type:
|
||||
. Target C-state for type=POWER_CSTATE,
|
||||
. Target frequency for type=POWER_PSTATE,
|
||||
|
||||
power_end is used to indicate the exit of a state, corresponding to the latest
|
||||
power_start event.
|
||||
|
||||
2. Clocks events
|
||||
================
|
||||
The clock events are used for clock enable/disable and for
|
||||
|
||||
@@ -37,6 +37,16 @@
|
||||
next-level-cache = <&L2>;
|
||||
clocks = <&a9pll>;
|
||||
clock-names = "cpu";
|
||||
operating-points = <
|
||||
/* kHz ignored */
|
||||
1300000 1000000
|
||||
1200000 1000000
|
||||
1100000 1000000
|
||||
800000 1000000
|
||||
400000 1000000
|
||||
200000 1000000
|
||||
>;
|
||||
clock-latency = <100000>;
|
||||
};
|
||||
|
||||
cpu@901 {
|
||||
|
||||
@@ -172,14 +172,9 @@ static void default_idle(void)
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
void (*pm_idle)(void) = default_idle;
|
||||
EXPORT_SYMBOL(pm_idle);
|
||||
|
||||
/*
|
||||
* The idle thread, has rather strange semantics for calling pm_idle,
|
||||
* but this is what x86 does and we need to do the same, so that
|
||||
* things like cpuidle get called in the same way. The only difference
|
||||
* is that we always respect 'hlt_counter' to prevent low power idle.
|
||||
* The idle thread.
|
||||
* We always respect 'hlt_counter' to prevent low power idle.
|
||||
*/
|
||||
void cpu_idle(void)
|
||||
{
|
||||
@@ -210,10 +205,10 @@ void cpu_idle(void)
|
||||
} else if (!need_resched()) {
|
||||
stop_critical_timings();
|
||||
if (cpuidle_idle_call())
|
||||
pm_idle();
|
||||
default_idle();
|
||||
start_critical_timings();
|
||||
/*
|
||||
* pm_idle functions must always
|
||||
* default_idle functions must always
|
||||
* return with IRQs enabled.
|
||||
*/
|
||||
WARN_ON(irqs_disabled());
|
||||
|
||||
+19
-34
@@ -31,7 +31,6 @@ static void __iomem *twd_base;
|
||||
|
||||
static struct clk *twd_clk;
|
||||
static unsigned long twd_timer_rate;
|
||||
static bool common_setup_called;
|
||||
static DEFINE_PER_CPU(bool, percpu_setup_called);
|
||||
|
||||
static struct clock_event_device __percpu **twd_evt;
|
||||
@@ -239,25 +238,28 @@ static irqreturn_t twd_handler(int irq, void *dev_id)
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
static struct clk *twd_get_clock(void)
|
||||
static void twd_get_clock(struct device_node *np)
|
||||
{
|
||||
struct clk *clk;
|
||||
int err;
|
||||
|
||||
clk = clk_get_sys("smp_twd", NULL);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("smp_twd: clock not found: %d\n", (int)PTR_ERR(clk));
|
||||
return clk;
|
||||
if (np)
|
||||
twd_clk = of_clk_get(np, 0);
|
||||
else
|
||||
twd_clk = clk_get_sys("smp_twd", NULL);
|
||||
|
||||
if (IS_ERR(twd_clk)) {
|
||||
pr_err("smp_twd: clock not found %d\n", (int) PTR_ERR(twd_clk));
|
||||
return;
|
||||
}
|
||||
|
||||
err = clk_prepare_enable(clk);
|
||||
err = clk_prepare_enable(twd_clk);
|
||||
if (err) {
|
||||
pr_err("smp_twd: clock failed to prepare+enable: %d\n", err);
|
||||
clk_put(clk);
|
||||
return ERR_PTR(err);
|
||||
clk_put(twd_clk);
|
||||
return;
|
||||
}
|
||||
|
||||
return clk;
|
||||
twd_timer_rate = clk_get_rate(twd_clk);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -280,26 +282,7 @@ static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
|
||||
}
|
||||
per_cpu(percpu_setup_called, cpu) = true;
|
||||
|
||||
/*
|
||||
* This stuff only need to be done once for the entire TWD cluster
|
||||
* during the runtime of the system.
|
||||
*/
|
||||
if (!common_setup_called) {
|
||||
twd_clk = twd_get_clock();
|
||||
|
||||
/*
|
||||
* We use IS_ERR_OR_NULL() here, because if the clock stubs
|
||||
* are active we will get a valid clk reference which is
|
||||
* however NULL and will return the rate 0. In that case we
|
||||
* need to calibrate the rate instead.
|
||||
*/
|
||||
if (!IS_ERR_OR_NULL(twd_clk))
|
||||
twd_timer_rate = clk_get_rate(twd_clk);
|
||||
else
|
||||
twd_calibrate_rate();
|
||||
|
||||
common_setup_called = true;
|
||||
}
|
||||
twd_calibrate_rate();
|
||||
|
||||
/*
|
||||
* The following is done once per CPU the first time .setup() is
|
||||
@@ -330,7 +313,7 @@ static struct local_timer_ops twd_lt_ops __cpuinitdata = {
|
||||
.stop = twd_timer_stop,
|
||||
};
|
||||
|
||||
static int __init twd_local_timer_common_register(void)
|
||||
static int __init twd_local_timer_common_register(struct device_node *np)
|
||||
{
|
||||
int err;
|
||||
|
||||
@@ -350,6 +333,8 @@ static int __init twd_local_timer_common_register(void)
|
||||
if (err)
|
||||
goto out_irq;
|
||||
|
||||
twd_get_clock(np);
|
||||
|
||||
return 0;
|
||||
|
||||
out_irq:
|
||||
@@ -373,7 +358,7 @@ int __init twd_local_timer_register(struct twd_local_timer *tlt)
|
||||
if (!twd_base)
|
||||
return -ENOMEM;
|
||||
|
||||
return twd_local_timer_common_register();
|
||||
return twd_local_timer_common_register(NULL);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
@@ -405,7 +390,7 @@ void __init twd_local_timer_of_register(void)
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = twd_local_timer_common_register();
|
||||
err = twd_local_timer_common_register(np);
|
||||
|
||||
out:
|
||||
WARN(err, "twd_local_timer_of_register failed (%d)\n", err);
|
||||
|
||||
@@ -25,53 +25,9 @@
|
||||
|
||||
#define DAVINCI_CPUIDLE_MAX_STATES 2
|
||||
|
||||
struct davinci_ops {
|
||||
void (*enter) (u32 flags);
|
||||
void (*exit) (u32 flags);
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
/* Actual code that puts the SoC in different idle states */
|
||||
static int davinci_enter_idle(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index)
|
||||
{
|
||||
struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
|
||||
struct davinci_ops *ops = cpuidle_get_statedata(state_usage);
|
||||
|
||||
if (ops && ops->enter)
|
||||
ops->enter(ops->flags);
|
||||
|
||||
index = cpuidle_wrap_enter(dev, drv, index,
|
||||
arm_cpuidle_simple_enter);
|
||||
|
||||
if (ops && ops->exit)
|
||||
ops->exit(ops->flags);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
/* fields in davinci_ops.flags */
|
||||
#define DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN BIT(0)
|
||||
|
||||
static struct cpuidle_driver davinci_idle_driver = {
|
||||
.name = "cpuidle-davinci",
|
||||
.owner = THIS_MODULE,
|
||||
.en_core_tk_irqen = 1,
|
||||
.states[0] = ARM_CPUIDLE_WFI_STATE,
|
||||
.states[1] = {
|
||||
.enter = davinci_enter_idle,
|
||||
.exit_latency = 10,
|
||||
.target_residency = 100000,
|
||||
.flags = CPUIDLE_FLAG_TIME_VALID,
|
||||
.name = "DDR SR",
|
||||
.desc = "WFI and DDR Self Refresh",
|
||||
},
|
||||
.state_count = DAVINCI_CPUIDLE_MAX_STATES,
|
||||
};
|
||||
|
||||
static DEFINE_PER_CPU(struct cpuidle_device, davinci_cpuidle_device);
|
||||
static void __iomem *ddr2_reg_base;
|
||||
static bool ddr2_pdown;
|
||||
|
||||
static void davinci_save_ddr_power(int enter, bool pdown)
|
||||
{
|
||||
@@ -92,21 +48,35 @@ static void davinci_save_ddr_power(int enter, bool pdown)
|
||||
__raw_writel(val, ddr2_reg_base + DDR2_SDRCR_OFFSET);
|
||||
}
|
||||
|
||||
static void davinci_c2state_enter(u32 flags)
|
||||
/* Actual code that puts the SoC in different idle states */
|
||||
static int davinci_enter_idle(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index)
|
||||
{
|
||||
davinci_save_ddr_power(1, !!(flags & DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN));
|
||||
davinci_save_ddr_power(1, ddr2_pdown);
|
||||
|
||||
index = cpuidle_wrap_enter(dev, drv, index,
|
||||
arm_cpuidle_simple_enter);
|
||||
|
||||
davinci_save_ddr_power(0, ddr2_pdown);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static void davinci_c2state_exit(u32 flags)
|
||||
{
|
||||
davinci_save_ddr_power(0, !!(flags & DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN));
|
||||
}
|
||||
|
||||
static struct davinci_ops davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = {
|
||||
[1] = {
|
||||
.enter = davinci_c2state_enter,
|
||||
.exit = davinci_c2state_exit,
|
||||
static struct cpuidle_driver davinci_idle_driver = {
|
||||
.name = "cpuidle-davinci",
|
||||
.owner = THIS_MODULE,
|
||||
.en_core_tk_irqen = 1,
|
||||
.states[0] = ARM_CPUIDLE_WFI_STATE,
|
||||
.states[1] = {
|
||||
.enter = davinci_enter_idle,
|
||||
.exit_latency = 10,
|
||||
.target_residency = 100000,
|
||||
.flags = CPUIDLE_FLAG_TIME_VALID,
|
||||
.name = "DDR SR",
|
||||
.desc = "WFI and DDR Self Refresh",
|
||||
},
|
||||
.state_count = DAVINCI_CPUIDLE_MAX_STATES,
|
||||
};
|
||||
|
||||
static int __init davinci_cpuidle_probe(struct platform_device *pdev)
|
||||
@@ -124,11 +94,7 @@ static int __init davinci_cpuidle_probe(struct platform_device *pdev)
|
||||
|
||||
ddr2_reg_base = pdata->ddr2_ctlr_base;
|
||||
|
||||
if (pdata->ddr2_pdown)
|
||||
davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN;
|
||||
cpuidle_set_statedata(&device->states_usage[1], &davinci_states[1]);
|
||||
|
||||
device->state_count = DAVINCI_CPUIDLE_MAX_STATES;
|
||||
ddr2_pdown = pdata->ddr2_pdown;
|
||||
|
||||
ret = cpuidle_register_driver(&davinci_idle_driver);
|
||||
if (ret) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user