Power management and ACPI updates for 3.10-rc1
- ARM big.LITTLE cpufreq driver from Viresh Kumar.
- exynos5440 cpufreq driver from Amit Daniel Kachhap.
- cpufreq core cleanup and code consolidation from Viresh Kumar and
Stratos Karafotis.
- cpufreq scalability improvement from Nathan Zimmer.
- AMD "frequency sensitivity feedback" powersave bias for the ondemand
cpufreq governor from Jacob Shin.
- cpuidle code consolidation and cleanups from Daniel Lezcano.
- ARM OMAP cpuidle fixes from Santosh Shilimkar and Daniel Lezcano.
- ACPICA fixes and other improvements from Bob Moore, Jung-uk Kim,
Lv Zheng, Yinghai Lu, Tang Chen, Colin Ian King, and Linn Crosetto.
- ACPI core updates related to hotplug from Toshi Kani, Paul Bolle,
Yasuaki Ishimatsu, and Rafael J. Wysocki.
- Intel Lynxpoint LPSS (Low-Power Subsystem) support improvements
from Rafael J. Wysocki and Andy Shevchenko.
/
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (GNU/Linux)
iQIcBAABAgAGBQJRf8M8AAoJEKhOf7ml8uNsud4P/3cabXP5lDipzibRrpOiONse
puuvIdhtNdMRMc3t1oSDjNH/w/JA51Gc+ICGFAORiyVmqxBc85mpT6J5ibqV7hNd
pCqbKJceoB5PajHZSx22e4wG9O7YN1k3r80p38IfFzA+Ct0KNSuE0ixMEfHKYjiq
p5pXswk6TY3gtBReH9agrafHqDtXw4IMTE0asMuJ+BorPW7vQeiNlrkuA+0qmDuu
26O0Pm2TVkx1ryfTjdM9zSZ9X2G4JuM8rm1/VFZWQJTExwlv3bA2Za1nvQNJlJ99
6JZ0JXfAehcEW2Ye0sqsZ8HSEabDVHM29QvvOszJ5RpBXERiOCHOkhvFleCoTpn0
Xq0rtXPrLMH1G28Ej+cxmsAjfzOLV2Byg30CAoI/GCLuQ+xh+VMCpuNYQuld25CG
9rtYd0fWESeYsAebhDcX0E3xyzJtbrHtOb9PyGwNkbAJ8YQfhVSMCOPi2SX2wa+Q
qXLXi2VaHvjBSUKcAv5BmM+Ya57Be+88D0LxbgXbUeOnYefUK1ljldKDDshkMjgG
P4LPdm4JpoB5ncXSOO1Dz9w9QnNcFexSUySd/TtKLNMha1vEHV8ISzNPYY+9IdXf
XN0VZbFnUDzdj+Fwna7zyFb1cGihDYJKAtpXvRd8Y6RGUxKx9uGLAFJZw/xZB/cR
KZKuML5O8MgJuef37F38
=H/se
-----END PGP SIGNATURE-----
Merge tag 'pm+acpi-3.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management and ACPI updates from Rafael J Wysocki:
- ARM big.LITTLE cpufreq driver from Viresh Kumar.
- exynos5440 cpufreq driver from Amit Daniel Kachhap.
- cpufreq core cleanup and code consolidation from Viresh Kumar and
Stratos Karafotis.
- cpufreq scalability improvement from Nathan Zimmer.
- AMD "frequency sensitivity feedback" powersave bias for the ondemand
cpufreq governor from Jacob Shin.
- cpuidle code consolidation and cleanups from Daniel Lezcano.
- ARM OMAP cpuidle fixes from Santosh Shilimkar and Daniel Lezcano.
- ACPICA fixes and other improvements from Bob Moore, Jung-uk Kim, Lv
Zheng, Yinghai Lu, Tang Chen, Colin Ian King, and Linn Crosetto.
- ACPI core updates related to hotplug from Toshi Kani, Paul Bolle,
Yasuaki Ishimatsu, and Rafael J Wysocki.
- Intel Lynxpoint LPSS (Low-Power Subsystem) support improvements from
Rafael J Wysocki and Andy Shevchenko.
* tag 'pm+acpi-3.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (192 commits)
cpufreq: Revert incorrect commit 5800043
cpufreq: MAINTAINERS: Add co-maintainer
cpuidle: add maintainer entry
ACPI / thermal: do not always return THERMAL_TREND_RAISING for active trip points
ARM: s3c64xx: cpuidle: use init/exit common routine
cpufreq: pxa2xx: initialize variables
ACPI: video: correct acpi_video_bus_add error processing
SH: cpuidle: use init/exit common routine
ARM: S5pv210: compiling issue, ARM_S5PV210_CPUFREQ needs CONFIG_CPU_FREQ_TABLE=y
ACPI: Fix wrong parameter passed to memblock_reserve
cpuidle: fix comment format
pnp: use %*phC to dump small buffers
isapnp: remove debug leftovers
ARM: imx: cpuidle: use init/exit common routine
ARM: davinci: cpuidle: use init/exit common routine
ARM: kirkwood: cpuidle: use init/exit common routine
ARM: calxeda: cpuidle: use init/exit common routine
ARM: tegra: cpuidle: use init/exit common routine for tegra3
ARM: tegra: cpuidle: use init/exit common routine for tegra2
ARM: OMAP4: cpuidle: use init/exit common routine
...
This commit is contained in:
commit
3ed1c478ef
253 changed files with 6885 additions and 4092 deletions
44
Documentation/ABI/testing/sysfs-devices-lpss_ltr
Normal file
44
Documentation/ABI/testing/sysfs-devices-lpss_ltr
Normal file
|
@ -0,0 +1,44 @@
|
|||
What: /sys/devices/.../lpss_ltr/
|
||||
Date: March 2013
|
||||
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
Description:
|
||||
The /sys/devices/.../lpss_ltr/ directory is only present for
|
||||
devices included into the Intel Lynxpoint Low Power Subsystem
|
||||
(LPSS). If present, it contains attributes containing the LTR
|
||||
mode and the values of LTR registers of the device.
|
||||
|
||||
What: /sys/devices/.../lpss_ltr/ltr_mode
|
||||
Date: March 2013
|
||||
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
Description:
|
||||
The /sys/devices/.../lpss_ltr/ltr_mode attribute contains an
|
||||
integer number (0 or 1) indicating whether or not the devices'
|
||||
LTR functionality is working in the software mode (1).
|
||||
|
||||
This attribute is read-only. If the device's runtime PM status
|
||||
is not "active", attempts to read from this attribute cause
|
||||
-EAGAIN to be returned.
|
||||
|
||||
What: /sys/devices/.../lpss_ltr/auto_ltr
|
||||
Date: March 2013
|
||||
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
Description:
|
||||
The /sys/devices/.../lpss_ltr/auto_ltr attribute contains the
|
||||
current value of the device's AUTO_LTR register (raw)
|
||||
represented as an 8-digit hexadecimal number.
|
||||
|
||||
This attribute is read-only. If the device's runtime PM status
|
||||
is not "active", attempts to read from this attribute cause
|
||||
-EAGAIN to be returned.
|
||||
|
||||
What: /sys/devices/.../lpss_ltr/sw_ltr
|
||||
Date: March 2013
|
||||
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
Description:
|
||||
The /sys/devices/.../lpss_ltr/auto_ltr attribute contains the
|
||||
current value of the device's SW_LTR register (raw) represented
|
||||
as an 8-digit hexadecimal number.
|
||||
|
||||
This attribute is read-only. If the device's runtime PM status
|
||||
is not "active", attempts to read from this attribute cause
|
||||
-EAGAIN to be returned.
|
|
@ -0,0 +1,13 @@
|
|||
What: /sys/devices/.../power_resources_wakeup/
|
||||
Date: April 2013
|
||||
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
Description:
|
||||
The /sys/devices/.../power_resources_wakeup/ directory is only
|
||||
present for device objects representing ACPI device nodes that
|
||||
require ACPI power resources for wakeup signaling.
|
||||
|
||||
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 able to signal wakeup. The names of
|
||||
the links are the same as the names of the directories they
|
||||
point to.
|
|
@ -18,6 +18,32 @@ Description:
|
|||
yoffset: The number of pixels between the top of the screen
|
||||
and the top edge of the image.
|
||||
|
||||
What: /sys/firmware/acpi/hotplug/
|
||||
Date: February 2013
|
||||
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
Description:
|
||||
There are separate hotplug profiles for different classes of
|
||||
devices supported by ACPI, such as containers, memory modules,
|
||||
processors, PCI root bridges etc. A hotplug profile for a given
|
||||
class of devices is a collection of settings defining the way
|
||||
that class of devices will be handled by the ACPI core hotplug
|
||||
code. Those profiles are represented in sysfs as subdirectories
|
||||
of /sys/firmware/acpi/hotplug/.
|
||||
|
||||
The following setting is available to user space for each
|
||||
hotplug profile:
|
||||
|
||||
enabled: If set, the ACPI core will handle notifications of
|
||||
hotplug events associated with the given class of
|
||||
devices and will allow those devices to be ejected with
|
||||
the help of the _EJ0 control method. Unsetting it
|
||||
effectively disables hotplug for the correspoinding
|
||||
class of devices.
|
||||
|
||||
The value of the above attribute is an integer number: 1 (set)
|
||||
or 0 (unset). Attempts to write any other values to it will
|
||||
cause -EINVAL to be returned.
|
||||
|
||||
What: /sys/firmware/acpi/interrupts/
|
||||
Date: February 2008
|
||||
Contact: Len Brown <lenb@kernel.org>
|
||||
|
|
|
@ -108,8 +108,9 @@ policy->governor must contain the "default policy" for
|
|||
cpufreq_driver.target is called with
|
||||
these values.
|
||||
|
||||
For setting some of these values, the frequency table helpers might be
|
||||
helpful. See the section 2 for more information on them.
|
||||
For setting some of these values (cpuinfo.min[max]_freq, policy->min[max]), 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()
|
||||
|
@ -184,10 +185,10 @@ the reference implementation in drivers/cpufreq/longrun.c
|
|||
As most cpufreq processors only allow for being set to a few specific
|
||||
frequencies, a "frequency table" with some functions might assist in
|
||||
some work of the processor driver. Such a "frequency table" consists
|
||||
of an array of struct cpufreq_freq_table entries, with any value in
|
||||
of an array of struct cpufreq_frequency_table entries, with any value in
|
||||
"index" you want to use, and the corresponding frequency in
|
||||
"frequency". At the end of the table, you need to add a
|
||||
cpufreq_freq_table entry with frequency set to CPUFREQ_TABLE_END. And
|
||||
cpufreq_frequency_table entry with frequency set to CPUFREQ_TABLE_END. And
|
||||
if you want to skip one entry in the table, set the frequency to
|
||||
CPUFREQ_ENTRY_INVALID. The entries don't need to be in ascending
|
||||
order.
|
||||
|
|
|
@ -167,6 +167,27 @@ of load evaluation and helping the CPU stay at its top speed when truly
|
|||
busy, rather than shifting back and forth in speed. This tunable has no
|
||||
effect on behavior at lower speeds/lower CPU loads.
|
||||
|
||||
powersave_bias: this parameter takes a value between 0 to 1000. It
|
||||
defines the percentage (times 10) value of the target frequency that
|
||||
will be shaved off of the target. For example, when set to 100 -- 10%,
|
||||
when ondemand governor would have targeted 1000 MHz, it will target
|
||||
1000 MHz - (10% of 1000 MHz) = 900 MHz instead. This is set to 0
|
||||
(disabled) by default.
|
||||
When AMD frequency sensitivity powersave bias driver --
|
||||
drivers/cpufreq/amd_freq_sensitivity.c is loaded, this parameter
|
||||
defines the workload frequency sensitivity threshold in which a lower
|
||||
frequency is chosen instead of ondemand governor's original target.
|
||||
The frequency sensitivity is a hardware reported (on AMD Family 16h
|
||||
Processors and above) value between 0 to 100% that tells software how
|
||||
the performance of the workload running on a CPU will change when
|
||||
frequency changes. A workload with sensitivity of 0% (memory/IO-bound)
|
||||
will not perform any better on higher core frequency, whereas a
|
||||
workload with sensitivity of 100% (CPU-bound) will perform better
|
||||
higher the frequency. When the driver is loaded, this is set to 400
|
||||
by default -- for CPUs running workloads with sensitivity value below
|
||||
40%, a lower frequency is chosen. Unloading the driver or writing 0
|
||||
will disable this feature.
|
||||
|
||||
|
||||
2.5 Conservative
|
||||
----------------
|
||||
|
@ -191,6 +212,12 @@ governor but for the opposite direction. For example when set to its
|
|||
default value of '20' it means that if the CPU usage needs to be below
|
||||
20% between samples to have the frequency decreased.
|
||||
|
||||
sampling_down_factor: similar functionality as in "ondemand" governor.
|
||||
But in "conservative", it controls the rate at which the kernel makes
|
||||
a decision on when to decrease the frequency while running in any
|
||||
speed. Load for frequency increase is still evaluated every
|
||||
sampling rate.
|
||||
|
||||
3. The Governor Interface in the CPUfreq Core
|
||||
=============================================
|
||||
|
||||
|
|
|
@ -15,11 +15,17 @@ has mechanisms in place to support actual entry-exit into CPU idle states.
|
|||
cpuidle driver initializes the cpuidle_device structure for each CPU device
|
||||
and registers with cpuidle using cpuidle_register_device.
|
||||
|
||||
If all the idle states are the same, the wrapper function cpuidle_register
|
||||
could be used instead.
|
||||
|
||||
It can also support the dynamic changes (like battery <-> AC), by using
|
||||
cpuidle_pause_and_lock, cpuidle_disable_device and cpuidle_enable_device,
|
||||
cpuidle_resume_and_unlock.
|
||||
|
||||
Interfaces:
|
||||
extern int cpuidle_register(struct cpuidle_driver *drv,
|
||||
const struct cpumask *const coupled_cpus);
|
||||
extern int cpuidle_unregister(struct cpuidle_driver *drv);
|
||||
extern int cpuidle_register_driver(struct cpuidle_driver *drv);
|
||||
extern void cpuidle_unregister_driver(struct cpuidle_driver *drv);
|
||||
extern int cpuidle_register_device(struct cpuidle_device *dev);
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
Generic ARM big LITTLE cpufreq driver's DT glue
|
||||
-----------------------------------------------
|
||||
|
||||
This is DT specific glue layer for generic cpufreq driver for big LITTLE
|
||||
systems.
|
||||
|
||||
Both required and optional properties listed below must be defined
|
||||
under node /cpus/cpu@x. Where x is the first cpu inside a cluster.
|
||||
|
||||
FIXME: Cpus should boot in the order specified in DT and all cpus for a cluster
|
||||
must be present contiguously. Generic DT driver will check only node 'x' for
|
||||
cpu:x.
|
||||
|
||||
Required properties:
|
||||
- operating-points: Refer to Documentation/devicetree/bindings/power/opp.txt
|
||||
for details
|
||||
|
||||
Optional properties:
|
||||
- clock-latency: Specify the possible maximum transition latency for clock,
|
||||
in unit of nanoseconds.
|
||||
|
||||
Examples:
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu@0 {
|
||||
compatible = "arm,cortex-a15";
|
||||
reg = <0>;
|
||||
next-level-cache = <&L2>;
|
||||
operating-points = <
|
||||
/* kHz uV */
|
||||
792000 1100000
|
||||
396000 950000
|
||||
198000 850000
|
||||
>;
|
||||
clock-latency = <61036>; /* two CLK32 periods */
|
||||
};
|
||||
|
||||
cpu@1 {
|
||||
compatible = "arm,cortex-a15";
|
||||
reg = <1>;
|
||||
next-level-cache = <&L2>;
|
||||
};
|
||||
|
||||
cpu@100 {
|
||||
compatible = "arm,cortex-a7";
|
||||
reg = <100>;
|
||||
next-level-cache = <&L2>;
|
||||
operating-points = <
|
||||
/* kHz uV */
|
||||
792000 950000
|
||||
396000 750000
|
||||
198000 450000
|
||||
>;
|
||||
clock-latency = <61036>; /* two CLK32 periods */
|
||||
};
|
||||
|
||||
cpu@101 {
|
||||
compatible = "arm,cortex-a7";
|
||||
reg = <101>;
|
||||
next-level-cache = <&L2>;
|
||||
};
|
||||
};
|
|
@ -32,7 +32,7 @@ cpus {
|
|||
396000 950000
|
||||
198000 850000
|
||||
>;
|
||||
transition-latency = <61036>; /* two CLK32 periods */
|
||||
clock-latency = <61036>; /* two CLK32 periods */
|
||||
};
|
||||
|
||||
cpu@1 {
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
Exynos5440 cpufreq driver
|
||||
-------------------
|
||||
|
||||
Exynos5440 SoC cpufreq driver for CPU frequency scaling.
|
||||
|
||||
Required properties:
|
||||
- interrupts: Interrupt to know the completion of cpu frequency change.
|
||||
- operating-points: Table of frequencies and voltage CPU could be transitioned into,
|
||||
in the decreasing order. Frequency should be in KHz units and voltage
|
||||
should be in microvolts.
|
||||
|
||||
Optional properties:
|
||||
- clock-latency: Clock monitor latency in microsecond.
|
||||
|
||||
All the required listed above must be defined under node cpufreq.
|
||||
|
||||
Example:
|
||||
--------
|
||||
cpufreq@160000 {
|
||||
compatible = "samsung,exynos5440-cpufreq";
|
||||
reg = <0x160000 0x1000>;
|
||||
interrupts = <0 57 0>;
|
||||
operating-points = <
|
||||
1000000 975000
|
||||
800000 925000>;
|
||||
clock-latency = <100000>;
|
||||
};
|
22
MAINTAINERS
22
MAINTAINERS
|
@ -2203,12 +2203,34 @@ F: drivers/net/ethernet/ti/cpmac.c
|
|||
|
||||
CPU FREQUENCY DRIVERS
|
||||
M: Rafael J. Wysocki <rjw@sisk.pl>
|
||||
M: Viresh Kumar <viresh.kumar@linaro.org>
|
||||
L: cpufreq@vger.kernel.org
|
||||
L: linux-pm@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git
|
||||
F: drivers/cpufreq/
|
||||
F: include/linux/cpufreq.h
|
||||
|
||||
CPU FREQUENCY DRIVERS - ARM BIG LITTLE
|
||||
M: Viresh Kumar <viresh.kumar@linaro.org>
|
||||
M: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>
|
||||
L: cpufreq@vger.kernel.org
|
||||
L: linux-pm@vger.kernel.org
|
||||
W: http://www.arm.com/products/processors/technologies/biglittleprocessing.php
|
||||
S: Maintained
|
||||
F: drivers/cpufreq/arm_big_little.h
|
||||
F: drivers/cpufreq/arm_big_little.c
|
||||
F: drivers/cpufreq/arm_big_little_dt.c
|
||||
|
||||
CPUIDLE DRIVERS
|
||||
M: Rafael J. Wysocki <rjw@sisk.pl>
|
||||
M: Daniel Lezcano <daniel.lezcano@linaro.org>
|
||||
L: linux-pm@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git
|
||||
F: drivers/cpuidle/*
|
||||
F: include/linux/cpuidle.h
|
||||
|
||||
CPUID/MSR DRIVER
|
||||
M: "H. Peter Anvin" <hpa@zytor.com>
|
||||
S: Maintained
|
||||
|
|
|
@ -2163,7 +2163,6 @@ endmenu
|
|||
menu "CPU Power Management"
|
||||
|
||||
if ARCH_HAS_CPUFREQ
|
||||
|
||||
source "drivers/cpufreq/Kconfig"
|
||||
|
||||
config CPU_FREQ_IMX
|
||||
|
@ -2173,30 +2172,6 @@ config CPU_FREQ_IMX
|
|||
help
|
||||
This enables the CPUfreq driver for i.MX CPUs.
|
||||
|
||||
config CPU_FREQ_SA1100
|
||||
bool
|
||||
|
||||
config CPU_FREQ_SA1110
|
||||
bool
|
||||
|
||||
config CPU_FREQ_INTEGRATOR
|
||||
tristate "CPUfreq driver for ARM Integrator CPUs"
|
||||
depends on ARCH_INTEGRATOR && CPU_FREQ
|
||||
default y
|
||||
help
|
||||
This enables the CPUfreq driver for ARM Integrator CPUs.
|
||||
|
||||
For details, take a look at <file:Documentation/cpu-freq>.
|
||||
|
||||
If in doubt, say Y.
|
||||
|
||||
config CPU_FREQ_PXA
|
||||
bool
|
||||
depends on CPU_FREQ && ARCH_PXA && PXA25x
|
||||
default y
|
||||
select CPU_FREQ_DEFAULT_GOV_USERSPACE
|
||||
select CPU_FREQ_TABLE
|
||||
|
||||
config CPU_FREQ_S3C
|
||||
bool
|
||||
help
|
||||
|
|
|
@ -56,7 +56,6 @@ CONFIG_AEABI=y
|
|||
CONFIG_ZBOOT_ROM_TEXT=0x0
|
||||
CONFIG_ZBOOT_ROM_BSS=0x0
|
||||
CONFIG_CPU_IDLE=y
|
||||
CONFIG_CPU_IDLE_KIRKWOOD=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
|
||||
#define AT91_MAX_STATES 2
|
||||
|
||||
static DEFINE_PER_CPU(struct cpuidle_device, at91_cpuidle_device);
|
||||
|
||||
/* Actual code that puts the SoC in different idle states */
|
||||
static int at91_enter_idle(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
|
@ -47,7 +45,6 @@ static int at91_enter_idle(struct cpuidle_device *dev,
|
|||
static struct cpuidle_driver at91_idle_driver = {
|
||||
.name = "at91_idle",
|
||||
.owner = THIS_MODULE,
|
||||
.en_core_tk_irqen = 1,
|
||||
.states[0] = ARM_CPUIDLE_WFI_STATE,
|
||||
.states[1] = {
|
||||
.enter = at91_enter_idle,
|
||||
|
@ -61,20 +58,9 @@ static struct cpuidle_driver at91_idle_driver = {
|
|||
};
|
||||
|
||||
/* Initialize CPU idle by registering the idle states */
|
||||
static int at91_init_cpuidle(void)
|
||||
static int __init at91_init_cpuidle(void)
|
||||
{
|
||||
struct cpuidle_device *device;
|
||||
|
||||
device = &per_cpu(at91_cpuidle_device, smp_processor_id());
|
||||
device->state_count = AT91_MAX_STATES;
|
||||
|
||||
cpuidle_register_driver(&at91_idle_driver);
|
||||
|
||||
if (cpuidle_register_device(device)) {
|
||||
printk(KERN_ERR "at91_init_cpuidle: Failed registering\n");
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
return cpuidle_register(&at91_idle_driver, NULL);
|
||||
}
|
||||
|
||||
device_initcall(at91_init_cpuidle);
|
||||
|
|
|
@ -37,7 +37,6 @@ obj-$(CONFIG_MACH_MITYOMAPL138) += board-mityomapl138.o
|
|||
obj-$(CONFIG_MACH_OMAPL138_HAWKBOARD) += board-omapl138-hawk.o
|
||||
|
||||
# Power Management
|
||||
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
|
||||
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
|
||||
obj-$(CONFIG_SUSPEND) += pm.o sleep.o
|
||||
obj-$(CONFIG_HAVE_CLK) += pm_domain.o
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
#define DAVINCI_CPUIDLE_MAX_STATES 2
|
||||
|
||||
static DEFINE_PER_CPU(struct cpuidle_device, davinci_cpuidle_device);
|
||||
static void __iomem *ddr2_reg_base;
|
||||
static bool ddr2_pdown;
|
||||
|
||||
|
@ -50,14 +49,10 @@ static void davinci_save_ddr_power(int enter, bool pdown)
|
|||
|
||||
/* 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_driver *drv, int index)
|
||||
{
|
||||
davinci_save_ddr_power(1, ddr2_pdown);
|
||||
|
||||
index = cpuidle_wrap_enter(dev, drv, index,
|
||||
arm_cpuidle_simple_enter);
|
||||
|
||||
cpu_do_idle();
|
||||
davinci_save_ddr_power(0, ddr2_pdown);
|
||||
|
||||
return index;
|
||||
|
@ -66,7 +61,6 @@ static int davinci_enter_idle(struct cpuidle_device *dev,
|
|||
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,
|
||||
|
@ -81,12 +75,8 @@ static struct cpuidle_driver davinci_idle_driver = {
|
|||
|
||||
static int __init davinci_cpuidle_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
struct cpuidle_device *device;
|
||||
struct davinci_cpuidle_config *pdata = pdev->dev.platform_data;
|
||||
|
||||
device = &per_cpu(davinci_cpuidle_device, smp_processor_id());
|
||||
|
||||
if (!pdata) {
|
||||
dev_err(&pdev->dev, "cannot get platform data\n");
|
||||
return -ENOENT;
|
||||
|
@ -96,20 +86,7 @@ static int __init davinci_cpuidle_probe(struct platform_device *pdev)
|
|||
|
||||
ddr2_pdown = pdata->ddr2_pdown;
|
||||
|
||||
ret = cpuidle_register_driver(&davinci_idle_driver);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register driver\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = cpuidle_register_device(device);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register device\n");
|
||||
cpuidle_unregister_driver(&davinci_idle_driver);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return cpuidle_register(&davinci_idle_driver, NULL);
|
||||
}
|
||||
|
||||
static struct platform_driver davinci_cpuidle_driver = {
|
||||
|
|
|
@ -72,10 +72,12 @@ config SOC_EXYNOS5440
|
|||
bool "SAMSUNG EXYNOS5440"
|
||||
default y
|
||||
depends on ARCH_EXYNOS5
|
||||
select ARCH_HAS_OPP
|
||||
select ARM_ARCH_TIMER
|
||||
select AUTO_ZRELADDR
|
||||
select PINCTRL
|
||||
select PINCTRL_EXYNOS5440
|
||||
select PM_OPP
|
||||
help
|
||||
Enable EXYNOS5440 SoC support
|
||||
|
||||
|
|
|
@ -58,7 +58,6 @@ static DEFINE_PER_CPU(struct cpuidle_device, exynos4_cpuidle_device);
|
|||
static struct cpuidle_driver exynos4_idle_driver = {
|
||||
.name = "exynos4_idle",
|
||||
.owner = THIS_MODULE,
|
||||
.en_core_tk_irqen = 1,
|
||||
};
|
||||
|
||||
/* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
|
||||
|
|
|
@ -30,7 +30,7 @@ obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
|
|||
obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o
|
||||
|
||||
ifeq ($(CONFIG_CPU_IDLE),y)
|
||||
obj-y += cpuidle.o
|
||||
obj-$(CONFIG_SOC_IMX5) += cpuidle-imx5.o
|
||||
obj-$(CONFIG_SOC_IMX6Q) += cpuidle-imx6q.o
|
||||
endif
|
||||
|
||||
|
|
|
@ -87,13 +87,12 @@ static int mxc_set_target(struct cpufreq_policy *policy,
|
|||
|
||||
freqs.old = clk_get_rate(cpu_clk) / 1000;
|
||||
freqs.new = freq_Hz / 1000;
|
||||
freqs.cpu = 0;
|
||||
freqs.flags = 0;
|
||||
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
|
||||
cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
|
||||
|
||||
ret = set_cpu_freq(freq_Hz);
|
||||
|
||||
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
|
||||
cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -145,14 +144,11 @@ static int mxc_cpufreq_init(struct cpufreq_policy *policy)
|
|||
imx_freq_table[i].frequency = CPUFREQ_TABLE_END;
|
||||
|
||||
policy->cur = clk_get_rate(cpu_clk) / 1000;
|
||||
policy->min = policy->cpuinfo.min_freq = cpu_freq_khz_min;
|
||||
policy->max = policy->cpuinfo.max_freq = cpu_freq_khz_max;
|
||||
|
||||
/* Manual states, that PLL stabilizes in two CLK32 periods */
|
||||
policy->cpuinfo.transition_latency = 2 * NANOSECOND / CLK32_FREQ;
|
||||
|
||||
ret = cpufreq_frequency_table_cpuinfo(policy, imx_freq_table);
|
||||
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "%s: failed to register i.MXC CPUfreq with error code %d\n",
|
||||
__func__, ret);
|
||||
|
|
37
arch/arm/mach-imx/cpuidle-imx5.c
Normal file
37
arch/arm/mach-imx/cpuidle-imx5.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (C) 2012 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/system_misc.h>
|
||||
|
||||
static int imx5_cpuidle_enter(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv, int index)
|
||||
{
|
||||
arm_pm_idle();
|
||||
return index;
|
||||
}
|
||||
|
||||
static struct cpuidle_driver imx5_cpuidle_driver = {
|
||||
.name = "imx5_cpuidle",
|
||||
.owner = THIS_MODULE,
|
||||
.states[0] = {
|
||||
.enter = imx5_cpuidle_enter,
|
||||
.exit_latency = 2,
|
||||
.target_residency = 1,
|
||||
.flags = CPUIDLE_FLAG_TIME_VALID,
|
||||
.name = "IMX5 SRPG",
|
||||
.desc = "CPU state retained,powered off",
|
||||
},
|
||||
.state_count = 1,
|
||||
};
|
||||
|
||||
int __init imx5_cpuidle_init(void)
|
||||
{
|
||||
return cpuidle_register(&imx5_cpuidle_driver, NULL);
|
||||
}
|
|
@ -6,7 +6,6 @@
|
|||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/cpuidle.h>
|
||||
|
@ -21,10 +20,6 @@ static DEFINE_SPINLOCK(master_lock);
|
|||
static int imx6q_enter_wait(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv, int index)
|
||||
{
|
||||
int cpu = dev->cpu;
|
||||
|
||||
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
|
||||
|
||||
if (atomic_inc_return(&master) == num_online_cpus()) {
|
||||
/*
|
||||
* With this lock, we prevent other cpu to exit and enter
|
||||
|
@ -43,26 +38,13 @@ static int imx6q_enter_wait(struct cpuidle_device *dev,
|
|||
cpu_do_idle();
|
||||
done:
|
||||
atomic_dec(&master);
|
||||
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
/*
|
||||
* For each cpu, setup the broadcast timer because local timer
|
||||
* stops for the states other than WFI.
|
||||
*/
|
||||
static void imx6q_setup_broadcast_timer(void *arg)
|
||||
{
|
||||
int cpu = smp_processor_id();
|
||||
|
||||
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu);
|
||||
}
|
||||
|
||||
static struct cpuidle_driver imx6q_cpuidle_driver = {
|
||||
.name = "imx6q_cpuidle",
|
||||
.owner = THIS_MODULE,
|
||||
.en_core_tk_irqen = 1,
|
||||
.states = {
|
||||
/* WFI */
|
||||
ARM_CPUIDLE_WFI_STATE,
|
||||
|
@ -70,7 +52,8 @@ static struct cpuidle_driver imx6q_cpuidle_driver = {
|
|||
{
|
||||
.exit_latency = 50,
|
||||
.target_residency = 75,
|
||||
.flags = CPUIDLE_FLAG_TIME_VALID,
|
||||
.flags = CPUIDLE_FLAG_TIME_VALID |
|
||||
CPUIDLE_FLAG_TIMER_STOP,
|
||||
.enter = imx6q_enter_wait,
|
||||
.name = "WAIT",
|
||||
.desc = "Clock off",
|
||||
|
@ -88,8 +71,5 @@ int __init imx6q_cpuidle_init(void)
|
|||
/* Set chicken bit to get a reliable WAIT mode support */
|
||||
imx6q_set_chicken_bit();
|
||||
|
||||
/* Configure the broadcast timer on each cpu */
|
||||
on_each_cpu(imx6q_setup_broadcast_timer, NULL, 1);
|
||||
|
||||
return imx_cpuidle_init(&imx6q_cpuidle_driver);
|
||||
return cpuidle_register(&imx6q_cpuidle_driver, NULL);
|
||||
}
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||
* Copyright 2012 Linaro Ltd.
|
||||
*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
static struct cpuidle_device __percpu * imx_cpuidle_devices;
|
||||
|
||||
static void __init imx_cpuidle_devices_uninit(void)
|
||||
{
|
||||
int cpu_id;
|
||||
struct cpuidle_device *dev;
|
||||
|
||||
for_each_possible_cpu(cpu_id) {
|
||||
dev = per_cpu_ptr(imx_cpuidle_devices, cpu_id);
|
||||
cpuidle_unregister_device(dev);
|
||||
}
|
||||
|
||||
free_percpu(imx_cpuidle_devices);
|
||||
}
|
||||
|
||||
int __init imx_cpuidle_init(struct cpuidle_driver *drv)
|
||||
{
|
||||
struct cpuidle_device *dev;
|
||||
int cpu_id, ret;
|
||||
|
||||
if (drv->state_count > CPUIDLE_STATE_MAX) {
|
||||
pr_err("%s: state_count exceeds maximum\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = cpuidle_register_driver(drv);
|
||||
if (ret) {
|
||||
pr_err("%s: Failed to register cpuidle driver with error: %d\n",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
imx_cpuidle_devices = alloc_percpu(struct cpuidle_device);
|
||||
if (imx_cpuidle_devices == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto unregister_drv;
|
||||
}
|
||||
|
||||
/* initialize state data for each cpuidle_device */
|
||||
for_each_possible_cpu(cpu_id) {
|
||||
dev = per_cpu_ptr(imx_cpuidle_devices, cpu_id);
|
||||
dev->cpu = cpu_id;
|
||||
dev->state_count = drv->state_count;
|
||||
|
||||
ret = cpuidle_register_device(dev);
|
||||
if (ret) {
|
||||
pr_err("%s: Failed to register cpu %u, error: %d\n",
|
||||
__func__, cpu_id, ret);
|
||||
goto uninit;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
uninit:
|
||||
imx_cpuidle_devices_uninit();
|
||||
|
||||
unregister_drv:
|
||||
cpuidle_unregister_driver(drv);
|
||||
return ret;
|
||||
}
|
|
@ -10,18 +10,16 @@
|
|||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
#include <linux/cpuidle.h>
|
||||
|
||||
#ifdef CONFIG_CPU_IDLE
|
||||
extern int imx_cpuidle_init(struct cpuidle_driver *drv);
|
||||
extern int imx5_cpuidle_init(void);
|
||||
extern int imx6q_cpuidle_init(void);
|
||||
#else
|
||||
static inline int imx_cpuidle_init(struct cpuidle_driver *drv)
|
||||
static inline int imx5_cpuidle_init(void)
|
||||
{
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
static inline int imx6q_cpuidle_init(void)
|
||||
{
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -149,33 +149,6 @@ static void imx5_pm_idle(void)
|
|||
imx5_cpu_do_idle();
|
||||
}
|
||||
|
||||
static int imx5_cpuidle_enter(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv, int idx)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = imx5_cpu_do_idle();
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
static struct cpuidle_driver imx5_cpuidle_driver = {
|
||||
.name = "imx5_cpuidle",
|
||||
.owner = THIS_MODULE,
|
||||
.en_core_tk_irqen = 1,
|
||||
.states[0] = {
|
||||
.enter = imx5_cpuidle_enter,
|
||||
.exit_latency = 2,
|
||||
.target_residency = 1,
|
||||
.flags = CPUIDLE_FLAG_TIME_VALID,
|
||||
.name = "IMX5 SRPG",
|
||||
.desc = "CPU state retained,powered off",
|
||||
},
|
||||
.state_count = 1,
|
||||
};
|
||||
|
||||
static int __init imx5_pm_common_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
@ -193,8 +166,7 @@ static int __init imx5_pm_common_init(void)
|
|||
/* Set the registers to the default cpu idle state. */
|
||||
mx5_cpu_lp_set(IMX5_DEFAULT_CPU_IDLE_STATE);
|
||||
|
||||
imx_cpuidle_init(&imx5_cpuidle_driver);
|
||||
return 0;
|
||||
return imx5_cpuidle_init();
|
||||
}
|
||||
|
||||
void __init imx51_pm_init(void)
|
||||
|
|
|
@ -9,5 +9,4 @@ obj-$(CONFIG_ARCH_INTEGRATOR_AP) += integrator_ap.o
|
|||
obj-$(CONFIG_ARCH_INTEGRATOR_CP) += integrator_cp.o
|
||||
|
||||
obj-$(CONFIG_PCI) += pci_v3.o pci.o
|
||||
obj-$(CONFIG_CPU_FREQ_INTEGRATOR) += cpu.o
|
||||
obj-$(CONFIG_INTEGRATOR_IMPD1) += impd1.o
|
||||
|
|
|
@ -249,7 +249,6 @@ extern int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state);
|
|||
extern int omap4_finish_suspend(unsigned long cpu_state);
|
||||
extern void omap4_cpu_resume(void);
|
||||
extern int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state);
|
||||
extern u32 omap4_mpuss_read_prev_context_state(void);
|
||||
#else
|
||||
static inline int omap4_enter_lowpower(unsigned int cpu,
|
||||
unsigned int power_state)
|
||||
|
@ -277,10 +276,6 @@ static inline int omap4_finish_suspend(unsigned long cpu_state)
|
|||
static inline void omap4_cpu_resume(void)
|
||||
{}
|
||||
|
||||
static inline u32 omap4_mpuss_read_prev_context_state(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct omap_sdrc_params;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <linux/cpuidle.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/cpu_pm.h>
|
||||
#include <asm/cpuidle.h>
|
||||
|
||||
#include "powerdomain.h"
|
||||
#include "clockdomain.h"
|
||||
|
@ -99,11 +100,15 @@ static struct omap3_idle_statedata omap3_idle_data[] = {
|
|||
},
|
||||
};
|
||||
|
||||
/* Private functions */
|
||||
|
||||
static int __omap3_enter_idle(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index)
|
||||
/**
|
||||
* omap3_enter_idle - Programs OMAP3 to enter the specified state
|
||||
* @dev: cpuidle device
|
||||
* @drv: cpuidle driver
|
||||
* @index: the index of state to be entered
|
||||
*/
|
||||
static int omap3_enter_idle(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index)
|
||||
{
|
||||
struct omap3_idle_statedata *cx = &omap3_idle_data[index];
|
||||
|
||||
|
@ -148,22 +153,6 @@ static int __omap3_enter_idle(struct cpuidle_device *dev,
|
|||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap3_enter_idle - Programs OMAP3 to enter the specified state
|
||||
* @dev: cpuidle device
|
||||
* @drv: cpuidle driver
|
||||
* @index: the index of state to be entered
|
||||
*
|
||||
* Called from the CPUidle framework to program the device to the
|
||||
* specified target state selected by the governor.
|
||||
*/
|
||||
static inline int omap3_enter_idle(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index)
|
||||
{
|
||||
return cpuidle_wrap_enter(dev, drv, index, __omap3_enter_idle);
|
||||
}
|
||||
|
||||
/**
|
||||
* next_valid_state - Find next valid C-state
|
||||
* @dev: cpuidle device
|
||||
|
@ -271,11 +260,9 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
|
||||
|
||||
static struct cpuidle_driver omap3_idle_driver = {
|
||||
.name = "omap3_idle",
|
||||
.owner = THIS_MODULE,
|
||||
.name = "omap3_idle",
|
||||
.owner = THIS_MODULE,
|
||||
.states = {
|
||||
{
|
||||
.enter = omap3_enter_idle_bm,
|
||||
|
@ -348,8 +335,6 @@ static struct cpuidle_driver omap3_idle_driver = {
|
|||
*/
|
||||
int __init omap3_idle_init(void)
|
||||
{
|
||||
struct cpuidle_device *dev;
|
||||
|
||||
mpu_pd = pwrdm_lookup("mpu_pwrdm");
|
||||
core_pd = pwrdm_lookup("core_pwrdm");
|
||||
per_pd = pwrdm_lookup("per_pwrdm");
|
||||
|
@ -358,16 +343,5 @@ int __init omap3_idle_init(void)
|
|||
if (!mpu_pd || !core_pd || !per_pd || !cam_pd)
|
||||
return -ENODEV;
|
||||
|
||||
cpuidle_register_driver(&omap3_idle_driver);
|
||||
|
||||
dev = &per_cpu(omap3_idle_dev, smp_processor_id());
|
||||
dev->cpu = 0;
|
||||
|
||||
if (cpuidle_register_device(dev)) {
|
||||
printk(KERN_ERR "%s: CPUidle register device failed\n",
|
||||
__func__);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return cpuidle_register(&omap3_idle_driver, NULL);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* OMAP4 CPU idle Routines
|
||||
* OMAP4+ CPU idle Routines
|
||||
*
|
||||
* Copyright (C) 2011 Texas Instruments, Inc.
|
||||
* Copyright (C) 2011-2013 Texas Instruments, Inc.
|
||||
* Santosh Shilimkar <santosh.shilimkar@ti.com>
|
||||
* Rajendra Nayak <rnayak@ti.com>
|
||||
*
|
||||
|
@ -14,8 +14,8 @@
|
|||
#include <linux/cpuidle.h>
|
||||
#include <linux/cpu_pm.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/clockchips.h>
|
||||
|
||||
#include <asm/cpuidle.h>
|
||||
#include <asm/proc-fns.h>
|
||||
|
||||
#include "common.h"
|
||||
|
@ -24,13 +24,13 @@
|
|||
#include "clockdomain.h"
|
||||
|
||||
/* Machine specific information */
|
||||
struct omap4_idle_statedata {
|
||||
struct idle_statedata {
|
||||
u32 cpu_state;
|
||||
u32 mpu_logic_state;
|
||||
u32 mpu_state;
|
||||
};
|
||||
|
||||
static struct omap4_idle_statedata omap4_idle_data[] = {
|
||||
static struct idle_statedata omap4_idle_data[] = {
|
||||
{
|
||||
.cpu_state = PWRDM_POWER_ON,
|
||||
.mpu_state = PWRDM_POWER_ON,
|
||||
|
@ -53,11 +53,12 @@ static struct clockdomain *cpu_clkdm[NR_CPUS];
|
|||
|
||||
static atomic_t abort_barrier;
|
||||
static bool cpu_done[NR_CPUS];
|
||||
static struct idle_statedata *state_ptr = &omap4_idle_data[0];
|
||||
|
||||
/* Private functions */
|
||||
|
||||
/**
|
||||
* omap4_enter_idle_coupled_[simple/coupled] - OMAP4 cpuidle entry functions
|
||||
* omap_enter_idle_[simple/coupled] - OMAP4PLUS cpuidle entry functions
|
||||
* @dev: cpuidle device
|
||||
* @drv: cpuidle driver
|
||||
* @index: the index of state to be entered
|
||||
|
@ -66,7 +67,7 @@ static bool cpu_done[NR_CPUS];
|
|||
* specified low power state selected by the governor.
|
||||
* Returns the amount of time spent in the low power state.
|
||||
*/
|
||||
static int omap4_enter_idle_simple(struct cpuidle_device *dev,
|
||||
static int omap_enter_idle_simple(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index)
|
||||
{
|
||||
|
@ -77,12 +78,11 @@ static int omap4_enter_idle_simple(struct cpuidle_device *dev,
|
|||
return index;
|
||||
}
|
||||
|
||||
static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
|
||||
static int omap_enter_idle_coupled(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index)
|
||||
{
|
||||
struct omap4_idle_statedata *cx = &omap4_idle_data[index];
|
||||
int cpu_id = smp_processor_id();
|
||||
struct idle_statedata *cx = state_ptr + index;
|
||||
|
||||
local_fiq_disable();
|
||||
|
||||
|
@ -109,8 +109,6 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
|
|||
}
|
||||
}
|
||||
|
||||
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id);
|
||||
|
||||
/*
|
||||
* Call idle CPU PM enter notifier chain so that
|
||||
* VFP and per CPU interrupt context is saved.
|
||||
|
@ -149,11 +147,10 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
|
|||
* Call idle CPU cluster PM exit notifier chain
|
||||
* to restore GIC and wakeupgen context.
|
||||
*/
|
||||
if (omap4_mpuss_read_prev_context_state())
|
||||
if ((cx->mpu_state == PWRDM_POWER_RET) &&
|
||||
(cx->mpu_logic_state == PWRDM_POWER_OFF))
|
||||
cpu_cluster_pm_exit();
|
||||
|
||||
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id);
|
||||
|
||||
fail:
|
||||
cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
|
||||
cpu_done[dev->cpu] = false;
|
||||
|
@ -163,49 +160,38 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
|
|||
return index;
|
||||
}
|
||||
|
||||
/*
|
||||
* For each cpu, setup the broadcast timer because local timers
|
||||
* stops for the states above C1.
|
||||
*/
|
||||
static void omap_setup_broadcast_timer(void *arg)
|
||||
{
|
||||
int cpu = smp_processor_id();
|
||||
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu);
|
||||
}
|
||||
|
||||
static DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev);
|
||||
|
||||
static struct cpuidle_driver omap4_idle_driver = {
|
||||
.name = "omap4_idle",
|
||||
.owner = THIS_MODULE,
|
||||
.en_core_tk_irqen = 1,
|
||||
.states = {
|
||||
{
|
||||
/* C1 - CPU0 ON + CPU1 ON + MPU ON */
|
||||
.exit_latency = 2 + 2,
|
||||
.target_residency = 5,
|
||||
.flags = CPUIDLE_FLAG_TIME_VALID,
|
||||
.enter = omap4_enter_idle_simple,
|
||||
.enter = omap_enter_idle_simple,
|
||||
.name = "C1",
|
||||
.desc = "MPUSS ON"
|
||||
.desc = "CPUx ON, MPUSS ON"
|
||||
},
|
||||
{
|
||||
/* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */
|
||||
.exit_latency = 328 + 440,
|
||||
.target_residency = 960,
|
||||
.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED,
|
||||
.enter = omap4_enter_idle_coupled,
|
||||
.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED |
|
||||
CPUIDLE_FLAG_TIMER_STOP,
|
||||
.enter = omap_enter_idle_coupled,
|
||||
.name = "C2",
|
||||
.desc = "MPUSS CSWR",
|
||||
.desc = "CPUx OFF, MPUSS CSWR",
|
||||
},
|
||||
{
|
||||
/* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */
|
||||
.exit_latency = 460 + 518,
|
||||
.target_residency = 1100,
|
||||
.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED,
|
||||
.enter = omap4_enter_idle_coupled,
|
||||
.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED |
|
||||
CPUIDLE_FLAG_TIMER_STOP,
|
||||
.enter = omap_enter_idle_coupled,
|
||||
.name = "C3",
|
||||
.desc = "MPUSS OSWR",
|
||||
.desc = "CPUx OFF, MPUSS OSWR",
|
||||
},
|
||||
},
|
||||
.state_count = ARRAY_SIZE(omap4_idle_data),
|
||||
|
@ -215,16 +201,13 @@ static struct cpuidle_driver omap4_idle_driver = {
|
|||
/* Public functions */
|
||||
|
||||
/**
|
||||
* omap4_idle_init - Init routine for OMAP4 idle
|
||||
* omap4_idle_init - Init routine for OMAP4+ idle
|
||||
*
|
||||
* Registers the OMAP4 specific cpuidle driver to the cpuidle
|
||||
* Registers the OMAP4+ specific cpuidle driver to the cpuidle
|
||||
* framework with the valid set of states.
|
||||
*/
|
||||
int __init omap4_idle_init(void)
|
||||
{
|
||||
struct cpuidle_device *dev;
|
||||
unsigned int cpu_id = 0;
|
||||
|
||||
mpu_pd = pwrdm_lookup("mpu_pwrdm");
|
||||
cpu_pd[0] = pwrdm_lookup("cpu0_pwrdm");
|
||||
cpu_pd[1] = pwrdm_lookup("cpu1_pwrdm");
|
||||
|
@ -236,22 +219,5 @@ int __init omap4_idle_init(void)
|
|||
if (!cpu_clkdm[0] || !cpu_clkdm[1])
|
||||
return -ENODEV;
|
||||
|
||||
/* Configure the broadcast timer on each cpu */
|
||||
on_each_cpu(omap_setup_broadcast_timer, NULL, 1);
|
||||
|
||||
for_each_cpu(cpu_id, cpu_online_mask) {
|
||||
dev = &per_cpu(omap4_idle_dev, cpu_id);
|
||||
dev->cpu = cpu_id;
|
||||
#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
|
||||
dev->coupled_cpus = *cpu_online_mask;
|
||||
#endif
|
||||
cpuidle_register_driver(&omap4_idle_driver);
|
||||
|
||||
if (cpuidle_register_device(dev)) {
|
||||
pr_err("%s: CPUidle register failed\n", __func__);
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return cpuidle_register(&omap4_idle_driver, cpu_online_mask);
|
||||
}
|
||||
|
|
|
@ -139,20 +139,6 @@ static inline void cpu_clear_prev_logic_pwrst(unsigned int cpu_id)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* omap4_mpuss_read_prev_context_state:
|
||||
* Function returns the MPUSS previous context state
|
||||
*/
|
||||
u32 omap4_mpuss_read_prev_context_state(void)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
|
||||
OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET);
|
||||
reg &= OMAP4430_LOSTCONTEXT_DFF_MASK;
|
||||
return reg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Store the CPU cluster state for L2X0 low power operations.
|
||||
*/
|
||||
|
|
|
@ -264,6 +264,12 @@ static void __init omap4_init_voltages(void)
|
|||
omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", "iva");
|
||||
}
|
||||
|
||||
static inline void omap_init_cpufreq(void)
|
||||
{
|
||||
struct platform_device_info devinfo = { .name = "omap-cpufreq", };
|
||||
platform_device_register_full(&devinfo);
|
||||
}
|
||||
|
||||
static int __init omap2_common_pm_init(void)
|
||||
{
|
||||
if (!of_have_populated_dt())
|
||||
|
@ -293,6 +299,9 @@ int __init omap2_common_pm_late_init(void)
|
|||
|
||||
/* Smartreflex device init */
|
||||
omap_devinit_smartreflex();
|
||||
|
||||
/* cpufreq dummy device instantiation */
|
||||
omap_init_cpufreq();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SUSPEND
|
||||
|
|
|
@ -7,12 +7,6 @@ obj-y += clock.o devices.o generic.o irq.o \
|
|||
time.o reset.o
|
||||
obj-$(CONFIG_PM) += pm.o sleep.o standby.o
|
||||
|
||||
ifeq ($(CONFIG_CPU_FREQ),y)
|
||||
obj-$(CONFIG_PXA25x) += cpufreq-pxa2xx.o
|
||||
obj-$(CONFIG_PXA27x) += cpufreq-pxa2xx.o
|
||||
obj-$(CONFIG_PXA3xx) += cpufreq-pxa3xx.o
|
||||
endif
|
||||
|
||||
# Generic drivers that other drivers may depend upon
|
||||
|
||||
# SoC-specific code
|
||||
|
|
1
arch/arm/mach-pxa/include/mach/generic.h
Normal file
1
arch/arm/mach-pxa/include/mach/generic.h
Normal file
|
@ -0,0 +1 @@
|
|||
#include "../../generic.h"
|
|
@ -204,7 +204,6 @@ static int s3c_cpufreq_settarget(struct cpufreq_policy *policy,
|
|||
freqs.old = cpu_cur.freq;
|
||||
freqs.new = cpu_new.freq;
|
||||
|
||||
freqs.freqs.cpu = 0;
|
||||
freqs.freqs.old = cpu_cur.freq.armclk / 1000;
|
||||
freqs.freqs.new = cpu_new.freq.armclk / 1000;
|
||||
|
||||
|
@ -218,9 +217,7 @@ static int s3c_cpufreq_settarget(struct cpufreq_policy *policy,
|
|||
s3c_cpufreq_updateclk(clk_pclk, cpu_new.freq.pclk);
|
||||
|
||||
/* start the frequency change */
|
||||
|
||||
if (policy)
|
||||
cpufreq_notify_transition(&freqs.freqs, CPUFREQ_PRECHANGE);
|
||||
cpufreq_notify_transition(policy, &freqs.freqs, CPUFREQ_PRECHANGE);
|
||||
|
||||
/* If hclk is staying the same, then we do not need to
|
||||
* re-write the IO or the refresh timings whilst we are changing
|
||||
|
@ -264,8 +261,7 @@ static int s3c_cpufreq_settarget(struct cpufreq_policy *policy,
|
|||
local_irq_restore(flags);
|
||||
|
||||
/* notify everyone we've done this */
|
||||
if (policy)
|
||||
cpufreq_notify_transition(&freqs.freqs, CPUFREQ_POSTCHANGE);
|
||||
cpufreq_notify_transition(policy, &freqs.freqs, CPUFREQ_POSTCHANGE);
|
||||
|
||||
s3c_freq_dbg("%s: finished\n", __func__);
|
||||
return 0;
|
||||
|
|
|
@ -40,12 +40,9 @@ static int s3c64xx_enter_idle(struct cpuidle_device *dev,
|
|||
return index;
|
||||
}
|
||||
|
||||
static DEFINE_PER_CPU(struct cpuidle_device, s3c64xx_cpuidle_device);
|
||||
|
||||
static struct cpuidle_driver s3c64xx_cpuidle_driver = {
|
||||
.name = "s3c64xx_cpuidle",
|
||||
.owner = THIS_MODULE,
|
||||
.en_core_tk_irqen = 1,
|
||||
.states = {
|
||||
{
|
||||
.enter = s3c64xx_enter_idle,
|
||||
|
@ -61,16 +58,6 @@ static struct cpuidle_driver s3c64xx_cpuidle_driver = {
|
|||
|
||||
static int __init s3c64xx_init_cpuidle(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
cpuidle_register_driver(&s3c64xx_cpuidle_driver);
|
||||
|
||||
ret = cpuidle_register_device(&s3c64xx_cpuidle_device);
|
||||
if (ret) {
|
||||
pr_err("Failed to register cpuidle device: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return cpuidle_register(&s3c64xx_cpuidle_driver, NULL);
|
||||
}
|
||||
device_initcall(s3c64xx_init_cpuidle);
|
||||
|
|
|
@ -4,7 +4,7 @@ menu "SA11x0 Implementations"
|
|||
|
||||
config SA1100_ASSABET
|
||||
bool "Assabet"
|
||||
select CPU_FREQ_SA1110
|
||||
select ARM_SA1110_CPUFREQ
|
||||
help
|
||||
Say Y here if you are using the Intel(R) StrongARM(R) SA-1110
|
||||
Microprocessor Development Board (also known as the Assabet).
|
||||
|
@ -20,7 +20,7 @@ config ASSABET_NEPONSET
|
|||
|
||||
config SA1100_CERF
|
||||
bool "CerfBoard"
|
||||
select CPU_FREQ_SA1110
|
||||
select ARM_SA1110_CPUFREQ
|
||||
help
|
||||
The Intrinsyc CerfBoard is based on the StrongARM 1110 (Discontinued).
|
||||
More information is available at:
|
||||
|
@ -47,7 +47,7 @@ endchoice
|
|||
|
||||
config SA1100_COLLIE
|
||||
bool "Sharp Zaurus SL5500"
|
||||
# FIXME: select CPU_FREQ_SA11x0
|
||||
# FIXME: select ARM_SA11x0_CPUFREQ
|
||||
select SHARP_LOCOMO
|
||||
select SHARP_PARAM
|
||||
select SHARP_SCOOP
|
||||
|
@ -56,7 +56,7 @@ config SA1100_COLLIE
|
|||
|
||||
config SA1100_H3100
|
||||
bool "Compaq iPAQ H3100"
|
||||
select CPU_FREQ_SA1110
|
||||
select ARM_SA1110_CPUFREQ
|
||||
select HTC_EGPIO
|
||||
help
|
||||
Say Y here if you intend to run this kernel on the Compaq iPAQ
|
||||
|
@ -67,7 +67,7 @@ config SA1100_H3100
|
|||
|
||||
config SA1100_H3600
|
||||
bool "Compaq iPAQ H3600/H3700"
|
||||
select CPU_FREQ_SA1110
|
||||
select ARM_SA1110_CPUFREQ
|
||||
select HTC_EGPIO
|
||||
help
|
||||
Say Y here if you intend to run this kernel on the Compaq iPAQ
|
||||
|
@ -78,7 +78,7 @@ config SA1100_H3600
|
|||
|
||||
config SA1100_BADGE4
|
||||
bool "HP Labs BadgePAD 4"
|
||||
select CPU_FREQ_SA1100
|
||||
select ARM_SA1100_CPUFREQ
|
||||
select SA1111
|
||||
help
|
||||
Say Y here if you want to build a kernel for the HP Laboratories
|
||||
|
@ -86,7 +86,7 @@ config SA1100_BADGE4
|
|||
|
||||
config SA1100_JORNADA720
|
||||
bool "HP Jornada 720"
|
||||
# FIXME: select CPU_FREQ_SA11x0
|
||||
# FIXME: select ARM_SA11x0_CPUFREQ
|
||||
select SA1111
|
||||
help
|
||||
Say Y here if you want to build a kernel for the HP Jornada 720
|
||||
|
@ -105,14 +105,14 @@ config SA1100_JORNADA720_SSP
|
|||
|
||||
config SA1100_HACKKIT
|
||||
bool "HackKit Core CPU Board"
|
||||
select CPU_FREQ_SA1100
|
||||
select ARM_SA1100_CPUFREQ
|
||||
help
|
||||
Say Y here to support the HackKit Core CPU Board
|
||||
<http://hackkit.eletztrick.de>;
|
||||
|
||||
config SA1100_LART
|
||||
bool "LART"
|
||||
select CPU_FREQ_SA1100
|
||||
select ARM_SA1100_CPUFREQ
|
||||
help
|
||||
Say Y here if you are using the Linux Advanced Radio Terminal
|
||||
(also known as the LART). See <http://www.lartmaker.nl/> for
|
||||
|
@ -120,7 +120,7 @@ config SA1100_LART
|
|||
|
||||
config SA1100_NANOENGINE
|
||||
bool "nanoEngine"
|
||||
select CPU_FREQ_SA1110
|
||||
select ARM_SA1110_CPUFREQ
|
||||
select PCI
|
||||
select PCI_NANOENGINE
|
||||
help
|
||||
|
@ -130,7 +130,7 @@ config SA1100_NANOENGINE
|
|||
|
||||
config SA1100_PLEB
|
||||
bool "PLEB"
|
||||
select CPU_FREQ_SA1100
|
||||
select ARM_SA1100_CPUFREQ
|
||||
help
|
||||
Say Y here if you are using version 1 of the Portable Linux
|
||||
Embedded Board (also known as PLEB).
|
||||
|
@ -139,7 +139,7 @@ config SA1100_PLEB
|
|||
|
||||
config SA1100_SHANNON
|
||||
bool "Shannon"
|
||||
select CPU_FREQ_SA1100
|
||||
select ARM_SA1100_CPUFREQ
|
||||
help
|
||||
The Shannon (also known as a Tuxscreen, and also as a IS2630) was a
|
||||
limited edition webphone produced by Philips. The Shannon is a SA1100
|
||||
|
@ -148,7 +148,7 @@ config SA1100_SHANNON
|
|||
|
||||
config SA1100_SIMPAD
|
||||
bool "Simpad"
|
||||
select CPU_FREQ_SA1110
|
||||
select ARM_SA1110_CPUFREQ
|
||||
help
|
||||
The SIEMENS webpad SIMpad is based on the StrongARM 1110. There
|
||||
are two different versions CL4 and SL4. CL4 has 32MB RAM and 16MB
|
||||
|
|
|
@ -8,9 +8,6 @@ obj-m :=
|
|||
obj-n :=
|
||||
obj- :=
|
||||
|
||||
obj-$(CONFIG_CPU_FREQ_SA1100) += cpu-sa1100.o
|
||||
obj-$(CONFIG_CPU_FREQ_SA1110) += cpu-sa1110.o
|
||||
|
||||
# Specific board support
|
||||
obj-$(CONFIG_SA1100_ASSABET) += assabet.o
|
||||
obj-$(CONFIG_ASSABET_NEPONSET) += neponset.o
|
||||
|
|
1
arch/arm/mach-sa1100/include/mach/generic.h
Normal file
1
arch/arm/mach-sa1100/include/mach/generic.h
Normal file
|
@ -0,0 +1 @@
|
|||
#include "../../generic.h"
|
|
@ -16,39 +16,22 @@
|
|||
#include <asm/cpuidle.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
int shmobile_enter_wfi(struct cpuidle_device *dev, struct cpuidle_driver *drv,
|
||||
int index)
|
||||
{
|
||||
cpu_do_idle();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpuidle_device shmobile_cpuidle_dev;
|
||||
static struct cpuidle_driver shmobile_cpuidle_default_driver = {
|
||||
.name = "shmobile_cpuidle",
|
||||
.owner = THIS_MODULE,
|
||||
.en_core_tk_irqen = 1,
|
||||
.states[0] = ARM_CPUIDLE_WFI_STATE,
|
||||
.states[0].enter = shmobile_enter_wfi,
|
||||
.safe_state_index = 0, /* C1 */
|
||||
.state_count = 1,
|
||||
};
|
||||
|
||||
static struct cpuidle_driver *cpuidle_drv = &shmobile_cpuidle_default_driver;
|
||||
|
||||
void shmobile_cpuidle_set_driver(struct cpuidle_driver *drv)
|
||||
void __init shmobile_cpuidle_set_driver(struct cpuidle_driver *drv)
|
||||
{
|
||||
cpuidle_drv = drv;
|
||||
}
|
||||
|
||||
int shmobile_cpuidle_init(void)
|
||||
int __init shmobile_cpuidle_init(void)
|
||||
{
|
||||
struct cpuidle_device *dev = &shmobile_cpuidle_dev;
|
||||
|
||||
cpuidle_register_driver(cpuidle_drv);
|
||||
|
||||
dev->state_count = cpuidle_drv->state_count;
|
||||
cpuidle_register_device(dev);
|
||||
|
||||
return 0;
|
||||
return cpuidle_register(cpuidle_drv, NULL);
|
||||
}
|
||||
|
|
|
@ -13,9 +13,6 @@ extern int shmobile_clk_init(void);
|
|||
extern void shmobile_handle_irq_intc(struct pt_regs *);
|
||||
extern struct platform_suspend_ops shmobile_suspend_ops;
|
||||
struct cpuidle_driver;
|
||||
struct cpuidle_device;
|
||||
extern int shmobile_enter_wfi(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv, int index);
|
||||
extern void shmobile_cpuidle_set_driver(struct cpuidle_driver *drv);
|
||||
|
||||
extern void sh7372_init_irq(void);
|
||||
|
|
|
@ -410,11 +410,9 @@ static int sh7372_enter_a4s(struct cpuidle_device *dev,
|
|||
static struct cpuidle_driver sh7372_cpuidle_driver = {
|
||||
.name = "sh7372_cpuidle",
|
||||
.owner = THIS_MODULE,
|
||||
.en_core_tk_irqen = 1,
|
||||
.state_count = 5,
|
||||
.safe_state_index = 0, /* C1 */
|
||||
.states[0] = ARM_CPUIDLE_WFI_STATE,
|
||||
.states[0].enter = shmobile_enter_wfi,
|
||||
.states[1] = {
|
||||
.name = "C2",
|
||||
.desc = "Core Standby Mode",
|
||||
|
@ -450,12 +448,12 @@ static struct cpuidle_driver sh7372_cpuidle_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
static void sh7372_cpuidle_init(void)
|
||||
static void __init sh7372_cpuidle_init(void)
|
||||
{
|
||||
shmobile_cpuidle_set_driver(&sh7372_cpuidle_driver);
|
||||
}
|
||||
#else
|
||||
static void sh7372_cpuidle_init(void) {}
|
||||
static void __init sh7372_cpuidle_init(void) {}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SUSPEND
|
||||
|
|
|
@ -24,7 +24,6 @@ obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += cpuidle-tegra30.o
|
|||
endif
|
||||
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
|
||||
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
|
||||
obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o
|
||||
obj-$(CONFIG_TEGRA_PCI) += pcie.o
|
||||
|
||||
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-dt-tegra20.o
|
||||
|
|
|
@ -23,39 +23,13 @@
|
|||
static struct cpuidle_driver tegra_idle_driver = {
|
||||
.name = "tegra_idle",
|
||||
.owner = THIS_MODULE,
|
||||
.en_core_tk_irqen = 1,
|
||||
.state_count = 1,
|
||||
.states = {
|
||||
[0] = ARM_CPUIDLE_WFI_STATE_PWR(600),
|
||||
},
|
||||
};
|
||||
|
||||
static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device);
|
||||
|
||||
int __init tegra114_cpuidle_init(void)
|
||||
{
|
||||
int ret;
|
||||
unsigned int cpu;
|
||||
struct cpuidle_device *dev;
|
||||
struct cpuidle_driver *drv = &tegra_idle_driver;
|
||||
|
||||
ret = cpuidle_register_driver(&tegra_idle_driver);
|
||||
if (ret) {
|
||||
pr_err("CPUidle driver registration failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
dev = &per_cpu(tegra_idle_device, cpu);
|
||||
dev->cpu = cpu;
|
||||
|
||||
dev->state_count = drv->state_count;
|
||||
ret = cpuidle_register_device(dev);
|
||||
if (ret) {
|
||||
pr_err("CPU%u: CPUidle device registration failed\n",
|
||||
cpu);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return cpuidle_register(&tegra_idle_driver, NULL);
|
||||
}
|
||||
|
|
|
@ -43,32 +43,33 @@ static atomic_t abort_barrier;
|
|||
static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index);
|
||||
#define TEGRA20_MAX_STATES 2
|
||||
#else
|
||||
#define TEGRA20_MAX_STATES 1
|
||||
#endif
|
||||
|
||||
static struct cpuidle_state tegra_idle_states[] = {
|
||||
[0] = ARM_CPUIDLE_WFI_STATE_PWR(600),
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
[1] = {
|
||||
.enter = tegra20_idle_lp2_coupled,
|
||||
.exit_latency = 5000,
|
||||
.target_residency = 10000,
|
||||
.power_usage = 0,
|
||||
.flags = CPUIDLE_FLAG_TIME_VALID |
|
||||
CPUIDLE_FLAG_COUPLED,
|
||||
.name = "powered-down",
|
||||
.desc = "CPU power gated",
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct cpuidle_driver tegra_idle_driver = {
|
||||
.name = "tegra_idle",
|
||||
.owner = THIS_MODULE,
|
||||
.en_core_tk_irqen = 1,
|
||||
.states = {
|
||||
ARM_CPUIDLE_WFI_STATE_PWR(600),
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
{
|
||||
.enter = tegra20_idle_lp2_coupled,
|
||||
.exit_latency = 5000,
|
||||
.target_residency = 10000,
|
||||
.power_usage = 0,
|
||||
.flags = CPUIDLE_FLAG_TIME_VALID |
|
||||
CPUIDLE_FLAG_COUPLED,
|
||||
.name = "powered-down",
|
||||
.desc = "CPU power gated",
|
||||
},
|
||||
#endif
|
||||
},
|
||||
.state_count = TEGRA20_MAX_STATES,
|
||||
.safe_state_index = 0,
|
||||
};
|
||||
|
||||
static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device);
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
#ifdef CONFIG_SMP
|
||||
static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
|
||||
|
@ -217,39 +218,8 @@ static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev,
|
|||
|
||||
int __init tegra20_cpuidle_init(void)
|
||||
{
|
||||
int ret;
|
||||
unsigned int cpu;
|
||||
struct cpuidle_device *dev;
|
||||
struct cpuidle_driver *drv = &tegra_idle_driver;
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
tegra_tear_down_cpu = tegra20_tear_down_cpu;
|
||||
#endif
|
||||
|
||||
drv->state_count = ARRAY_SIZE(tegra_idle_states);
|
||||
memcpy(drv->states, tegra_idle_states,
|
||||
drv->state_count * sizeof(drv->states[0]));
|
||||
|
||||
ret = cpuidle_register_driver(&tegra_idle_driver);
|
||||
if (ret) {
|
||||
pr_err("CPUidle driver registration failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
dev = &per_cpu(tegra_idle_device, cpu);
|
||||
dev->cpu = cpu;
|
||||
#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
|
||||
dev->coupled_cpus = *cpu_possible_mask;
|
||||
#endif
|
||||
|
||||
dev->state_count = drv->state_count;
|
||||
ret = cpuidle_register_device(dev);
|
||||
if (ret) {
|
||||
pr_err("CPU%u: CPUidle device registration failed\n",
|
||||
cpu);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return cpuidle_register(&tegra_idle_driver, cpu_possible_mask);
|
||||
}
|
||||
|
|
|
@ -43,7 +43,6 @@ static int tegra30_idle_lp2(struct cpuidle_device *dev,
|
|||
static struct cpuidle_driver tegra_idle_driver = {
|
||||
.name = "tegra_idle",
|
||||
.owner = THIS_MODULE,
|
||||
.en_core_tk_irqen = 1,
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
.state_count = 2,
|
||||
#else
|
||||
|
@ -65,8 +64,6 @@ static struct cpuidle_driver tegra_idle_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device);
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static bool tegra30_cpu_cluster_power_down(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
|
@ -157,32 +154,8 @@ static int tegra30_idle_lp2(struct cpuidle_device *dev,
|
|||
|
||||
int __init tegra30_cpuidle_init(void)
|
||||
{
|
||||
int ret;
|
||||
unsigned int cpu;
|
||||
struct cpuidle_device *dev;
|
||||
struct cpuidle_driver *drv = &tegra_idle_driver;
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
tegra_tear_down_cpu = tegra30_tear_down_cpu;
|
||||
#endif
|
||||
|
||||
ret = cpuidle_register_driver(&tegra_idle_driver);
|
||||
if (ret) {
|
||||
pr_err("CPUidle driver registration failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
dev = &per_cpu(tegra_idle_device, cpu);
|
||||
dev->cpu = cpu;
|
||||
|
||||
dev->state_count = drv->state_count;
|
||||
ret = cpuidle_register_device(dev);
|
||||
if (ret) {
|
||||
pr_err("CPU%u: CPUidle device registration failed\n",
|
||||
cpu);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return cpuidle_register(&tegra_idle_driver, NULL);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
|
||||
#include <linux/module.h>
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/smp.h>
|
||||
|
@ -22,7 +21,6 @@
|
|||
|
||||
static atomic_t master = ATOMIC_INIT(0);
|
||||
static DEFINE_SPINLOCK(master_lock);
|
||||
static DEFINE_PER_CPU(struct cpuidle_device, ux500_cpuidle_device);
|
||||
|
||||
static inline int ux500_enter_idle(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv, int index)
|
||||
|
@ -30,8 +28,6 @@ static inline int ux500_enter_idle(struct cpuidle_device *dev,
|
|||
int this_cpu = smp_processor_id();
|
||||
bool recouple = false;
|
||||
|
||||
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &this_cpu);
|
||||
|
||||
if (atomic_inc_return(&master) == num_online_cpus()) {
|
||||
|
||||
/* With this lock, we prevent the other cpu to exit and enter
|
||||
|
@ -91,22 +87,20 @@ static inline int ux500_enter_idle(struct cpuidle_device *dev,
|
|||
spin_unlock(&master_lock);
|
||||
}
|
||||
|
||||
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &this_cpu);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static struct cpuidle_driver ux500_idle_driver = {
|
||||
.name = "ux500_idle",
|
||||
.owner = THIS_MODULE,
|
||||
.en_core_tk_irqen = 1,
|
||||
.states = {
|
||||
ARM_CPUIDLE_WFI_STATE,
|
||||
{
|
||||
.enter = ux500_enter_idle,
|
||||
.exit_latency = 70,
|
||||
.target_residency = 260,
|
||||
.flags = CPUIDLE_FLAG_TIME_VALID,
|
||||
.flags = CPUIDLE_FLAG_TIME_VALID |
|
||||
CPUIDLE_FLAG_TIMER_STOP,
|
||||
.name = "ApIdle",
|
||||
.desc = "ARM Retention",
|
||||
},
|
||||
|
@ -115,59 +109,13 @@ static struct cpuidle_driver ux500_idle_driver = {
|
|||
.state_count = 2,
|
||||
};
|
||||
|
||||
/*
|
||||
* For each cpu, setup the broadcast timer because we will
|
||||
* need to migrate the timers for the states >= ApIdle.
|
||||
*/
|
||||
static void ux500_setup_broadcast_timer(void *arg)
|
||||
{
|
||||
int cpu = smp_processor_id();
|
||||
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu);
|
||||
}
|
||||
|
||||
int __init ux500_idle_init(void)
|
||||
{
|
||||
int ret, cpu;
|
||||
struct cpuidle_device *device;
|
||||
|
||||
/* Configure wake up reasons */
|
||||
prcmu_enable_wakeups(PRCMU_WAKEUP(ARM) | PRCMU_WAKEUP(RTC) |
|
||||
PRCMU_WAKEUP(ABB));
|
||||
|
||||
/*
|
||||
* Configure the timer broadcast for each cpu, that must
|
||||
* be done from the cpu context, so we use a smp cross
|
||||
* call with 'on_each_cpu'.
|
||||
*/
|
||||
on_each_cpu(ux500_setup_broadcast_timer, NULL, 1);
|
||||
|
||||
ret = cpuidle_register_driver(&ux500_idle_driver);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "failed to register ux500 idle driver\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
for_each_online_cpu(cpu) {
|
||||
device = &per_cpu(ux500_cpuidle_device, cpu);
|
||||
device->cpu = cpu;
|
||||
ret = cpuidle_register_device(device);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "Failed to register cpuidle "
|
||||
"device for cpu%d\n", cpu);
|
||||
goto out_unregister;
|
||||
}
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
|
||||
out_unregister:
|
||||
for_each_online_cpu(cpu) {
|
||||
device = &per_cpu(ux500_cpuidle_device, cpu);
|
||||
cpuidle_unregister_device(device);
|
||||
}
|
||||
|
||||
cpuidle_unregister_driver(&ux500_idle_driver);
|
||||
goto out;
|
||||
return cpuidle_register(&ux500_idle_driver, NULL);
|
||||
}
|
||||
|
||||
device_initcall(ux500_idle_init);
|
||||
|
|
|
@ -250,20 +250,7 @@ config ARCH_SUSPEND_POSSIBLE
|
|||
def_bool y
|
||||
|
||||
menu "CPU Frequency scaling"
|
||||
|
||||
source "drivers/cpufreq/Kconfig"
|
||||
|
||||
config CPU_FREQ_AT32AP
|
||||
bool "CPU frequency driver for AT32AP"
|
||||
depends on CPU_FREQ && PLATFORM_AT32AP
|
||||
default n
|
||||
help
|
||||
This enables the CPU frequency driver for AT32AP processors.
|
||||
|
||||
For details, take a look in <file:Documentation/cpu-freq>.
|
||||
|
||||
If in doubt, say N.
|
||||
|
||||
endmenu
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -26,7 +26,7 @@ CONFIG_CPU_FREQ=y
|
|||
# CONFIG_CPU_FREQ_STAT is not set
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_AT32AP=y
|
||||
CONFIG_AVR32_AT32AP_CPUFREQ=y
|
||||
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
|
|
|
@ -28,7 +28,7 @@ CONFIG_CPU_FREQ=y
|
|||
# CONFIG_CPU_FREQ_STAT is not set
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_AT32AP=y
|
||||
CONFIG_AVR32_AT32AP_CPUFREQ=y
|
||||
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
|
|
|
@ -27,7 +27,7 @@ CONFIG_CPU_FREQ=y
|
|||
# CONFIG_CPU_FREQ_STAT is not set
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_AT32AP=y
|
||||
CONFIG_AVR32_AT32AP_CPUFREQ=y
|
||||
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
|
|
|
@ -23,7 +23,7 @@ CONFIG_CPU_FREQ=y
|
|||
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_AT32AP=y
|
||||
CONFIG_AVR32_AT32AP_CPUFREQ=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
|
|
|
@ -26,7 +26,7 @@ CONFIG_CPU_FREQ=y
|
|||
# CONFIG_CPU_FREQ_STAT is not set
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_AT32AP=y
|
||||
CONFIG_AVR32_AT32AP_CPUFREQ=y
|
||||
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
|
|
|
@ -29,7 +29,7 @@ CONFIG_CPU_FREQ=y
|
|||
# CONFIG_CPU_FREQ_STAT is not set
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_AT32AP=y
|
||||
CONFIG_AVR32_AT32AP_CPUFREQ=y
|
||||
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
|
|
|
@ -28,7 +28,7 @@ CONFIG_CPU_FREQ=y
|
|||
# CONFIG_CPU_FREQ_STAT is not set
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_AT32AP=y
|
||||
CONFIG_AVR32_AT32AP_CPUFREQ=y
|
||||
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
|
|
|
@ -25,7 +25,7 @@ CONFIG_CPU_FREQ=y
|
|||
# CONFIG_CPU_FREQ_STAT is not set
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_AT32AP=y
|
||||
CONFIG_AVR32_AT32AP_CPUFREQ=y
|
||||
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
|
|
|
@ -26,7 +26,7 @@ CONFIG_CPU_FREQ=y
|
|||
# CONFIG_CPU_FREQ_STAT is not set
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_AT32AP=y
|
||||
CONFIG_AVR32_AT32AP_CPUFREQ=y
|
||||
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
|
|
|
@ -26,7 +26,7 @@ CONFIG_CPU_FREQ=y
|
|||
# CONFIG_CPU_FREQ_STAT is not set
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_AT32AP=y
|
||||
CONFIG_AVR32_AT32AP_CPUFREQ=y
|
||||
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
|
|
|
@ -26,7 +26,7 @@ CONFIG_CPU_FREQ=y
|
|||
# CONFIG_CPU_FREQ_STAT is not set
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_AT32AP=y
|
||||
CONFIG_AVR32_AT32AP_CPUFREQ=y
|
||||
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
|
|
|
@ -27,7 +27,7 @@ CONFIG_CPU_FREQ=y
|
|||
# CONFIG_CPU_FREQ_STAT is not set
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_AT32AP=y
|
||||
CONFIG_AVR32_AT32AP_CPUFREQ=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
|
|
|
@ -31,7 +31,7 @@ CONFIG_CPU_FREQ=y
|
|||
# CONFIG_CPU_FREQ_STAT is not set
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_AT32AP=y
|
||||
CONFIG_AVR32_AT32AP_CPUFREQ=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
|
|
|
@ -24,7 +24,7 @@ CONFIG_CPU_FREQ=y
|
|||
# CONFIG_CPU_FREQ_STAT is not set
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_AT32AP=y
|
||||
CONFIG_AVR32_AT32AP_CPUFREQ=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
obj-y += pdc.o clock.o intc.o extint.o pio.o hsmc.o
|
||||
obj-y += hmatrix.o
|
||||
obj-$(CONFIG_CPU_AT32AP700X) += at32ap700x.o pm-at32ap700x.o
|
||||
obj-$(CONFIG_CPU_FREQ_AT32AP) += cpufreq.o
|
||||
obj-$(CONFIG_PM) += pm.o
|
||||
|
||||
ifeq ($(CONFIG_PM_DEBUG),y)
|
||||
|
|
|
@ -10,7 +10,6 @@ obj-$(CONFIG_PM) += pm.o
|
|||
ifneq ($(CONFIG_BF60x),y)
|
||||
obj-$(CONFIG_PM) += dpmc_modes.o
|
||||
endif
|
||||
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
|
||||
obj-$(CONFIG_CPU_VOLTAGE) += dpmc.o
|
||||
obj-$(CONFIG_SMP) += smp.o
|
||||
obj-$(CONFIG_BFIN_KERNEL_CLOCK) += clocks-init.o
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#
|
||||
|
||||
obj-y := dma.o pinmux.o io.o arbiter.o
|
||||
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
|
||||
|
||||
clean:
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#
|
||||
|
||||
obj-y := dma.o pinmux.o io.o arbiter.o
|
||||
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
|
||||
|
||||
clean:
|
||||
|
||||
|
|
|
@ -591,9 +591,9 @@ source "kernel/power/Kconfig"
|
|||
source "drivers/acpi/Kconfig"
|
||||
|
||||
if PM
|
||||
|
||||
source "arch/ia64/kernel/cpufreq/Kconfig"
|
||||
|
||||
menu "CPU Frequency scaling"
|
||||
source "drivers/cpufreq/Kconfig"
|
||||
endmenu
|
||||
endif
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -23,7 +23,6 @@ obj-$(CONFIG_SMP) += smp.o smpboot.o
|
|||
obj-$(CONFIG_NUMA) += numa.o
|
||||
obj-$(CONFIG_PERFMON) += perfmon_default_smpl.o
|
||||
obj-$(CONFIG_IA64_CYCLONE) += cyclone.o
|
||||
obj-$(CONFIG_CPU_FREQ) += cpufreq/
|
||||
obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o
|
||||
obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o
|
||||
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
|
||||
#
|
||||
# CPU Frequency scaling
|
||||
#
|
||||
|
||||
menu "CPU Frequency scaling"
|
||||
|
||||
source "drivers/cpufreq/Kconfig"
|
||||
|
||||
if CPU_FREQ
|
||||
|
||||
comment "CPUFreq processor drivers"
|
||||
|
||||
config IA64_ACPI_CPUFREQ
|
||||
tristate "ACPI Processor P-States driver"
|
||||
select CPU_FREQ_TABLE
|
||||
depends on ACPI_PROCESSOR
|
||||
help
|
||||
This driver adds a CPUFreq driver which utilizes the ACPI
|
||||
Processor Performance States.
|
||||
|
||||
For details, take a look at <file:Documentation/cpu-freq/>.
|
||||
|
||||
If in doubt, say N.
|
||||
|
||||
endif # CPU_FREQ
|
||||
|
||||
endmenu
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
obj-$(CONFIG_IA64_ACPI_CPUFREQ) += acpi-cpufreq.o
|
||||
|
|
@ -2541,7 +2541,14 @@ source "kernel/power/Kconfig"
|
|||
|
||||
endmenu
|
||||
|
||||
source "arch/mips/kernel/cpufreq/Kconfig"
|
||||
config MIPS_EXTERNAL_TIMER
|
||||
bool
|
||||
|
||||
if CPU_SUPPORTS_CPUFREQ && MIPS_EXTERNAL_TIMER
|
||||
menu "CPU Power Management"
|
||||
source "drivers/cpufreq/Kconfig"
|
||||
endmenu
|
||||
endif
|
||||
|
||||
source "net/Kconfig"
|
||||
|
||||
|
|
|
@ -92,8 +92,6 @@ CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(KBUILD_CFLAGS) -Wa,-mdaddi -c -o /dev/n
|
|||
|
||||
obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT) += 8250-platform.o
|
||||
|
||||
obj-$(CONFIG_MIPS_CPUFREQ) += cpufreq/
|
||||
|
||||
obj-$(CONFIG_PERF_EVENTS) += perf_event.o
|
||||
obj-$(CONFIG_HW_PERF_EVENTS) += perf_event_mipsxx.o
|
||||
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
#
|
||||
# CPU Frequency scaling
|
||||
#
|
||||
|
||||
config MIPS_EXTERNAL_TIMER
|
||||
bool
|
||||
|
||||
config MIPS_CPUFREQ
|
||||
bool
|
||||
default y
|
||||
depends on CPU_SUPPORTS_CPUFREQ && MIPS_EXTERNAL_TIMER
|
||||
|
||||
if MIPS_CPUFREQ
|
||||
|
||||
menu "CPU Frequency scaling"
|
||||
|
||||
source "drivers/cpufreq/Kconfig"
|
||||
|
||||
if CPU_FREQ
|
||||
|
||||
comment "CPUFreq processor drivers"
|
||||
|
||||
config LOONGSON2_CPUFREQ
|
||||
tristate "Loongson2 CPUFreq Driver"
|
||||
select CPU_FREQ_TABLE
|
||||
depends on MIPS_CPUFREQ
|
||||
help
|
||||
This option adds a CPUFreq driver for loongson processors which
|
||||
support software configurable cpu frequency.
|
||||
|
||||
Loongson2F and it's successors support this feature.
|
||||
|
||||
For details, take a look at <file:Documentation/cpu-freq/>.
|
||||
|
||||
If in doubt, say N.
|
||||
|
||||
endif # CPU_FREQ
|
||||
|
||||
endmenu
|
||||
|
||||
endif # MIPS_CPUFREQ
|
|
@ -1,5 +0,0 @@
|
|||
#
|
||||
# Makefile for the Linux/MIPS cpufreq.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_LOONGSON2_CPUFREQ) += loongson2_cpufreq.o
|
|
@ -113,34 +113,10 @@ config CBE_THERM
|
|||
default m
|
||||
depends on CBE_RAS && SPU_BASE
|
||||
|
||||
config CBE_CPUFREQ
|
||||
tristate "CBE frequency scaling"
|
||||
depends on CBE_RAS && CPU_FREQ
|
||||
default m
|
||||
help
|
||||
This adds the cpufreq driver for Cell BE processors.
|
||||
For details, take a look at <file:Documentation/cpu-freq/>.
|
||||
If you don't have such processor, say N
|
||||
|
||||
config CBE_CPUFREQ_PMI_ENABLE
|
||||
bool "CBE frequency scaling using PMI interface"
|
||||
depends on CBE_CPUFREQ
|
||||
default n
|
||||
help
|
||||
Select this, if you want to use the PMI interface
|
||||
to switch frequencies. Using PMI, the
|
||||
processor will not only be able to run at lower speed,
|
||||
but also at lower core voltage.
|
||||
|
||||
config CBE_CPUFREQ_PMI
|
||||
tristate
|
||||
depends on CBE_CPUFREQ_PMI_ENABLE
|
||||
default CBE_CPUFREQ
|
||||
|
||||
config PPC_PMI
|
||||
tristate
|
||||
default y
|
||||
depends on CBE_CPUFREQ_PMI || PPC_IBM_CELL_POWERBUTTON
|
||||
depends on CPU_FREQ_CBE_PMI || PPC_IBM_CELL_POWERBUTTON
|
||||
help
|
||||
PMI (Platform Management Interrupt) is a way to
|
||||
communicate with the BMC (Baseboard Management Controller).
|
||||
|
|
|
@ -5,9 +5,6 @@ obj-$(CONFIG_PPC_CELL_NATIVE) += iommu.o setup.o spider-pic.o \
|
|||
obj-$(CONFIG_CBE_RAS) += ras.o
|
||||
|
||||
obj-$(CONFIG_CBE_THERM) += cbe_thermal.o
|
||||
obj-$(CONFIG_CBE_CPUFREQ_PMI) += cbe_cpufreq_pmi.o
|
||||
obj-$(CONFIG_CBE_CPUFREQ) += cbe-cpufreq.o
|
||||
cbe-cpufreq-y += cbe_cpufreq_pervasive.o cbe_cpufreq.o
|
||||
obj-$(CONFIG_CBE_CPUFREQ_SPU_GOVERNOR) += cpufreq_spudemand.o
|
||||
|
||||
obj-$(CONFIG_PPC_IBM_CELL_POWERBUTTON) += cbe_powerbutton.o
|
||||
|
|
|
@ -273,10 +273,9 @@ static int pas_cpufreq_target(struct cpufreq_policy *policy,
|
|||
|
||||
freqs.old = policy->cur;
|
||||
freqs.new = pas_freqs[pas_astate_new].frequency;
|
||||
freqs.cpu = policy->cpu;
|
||||
|
||||
mutex_lock(&pas_switch_mutex);
|
||||
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
|
||||
cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
|
||||
|
||||
pr_debug("setting frequency for cpu %d to %d kHz, 1/%d of max frequency\n",
|
||||
policy->cpu,
|
||||
|
@ -288,7 +287,7 @@ static int pas_cpufreq_target(struct cpufreq_policy *policy,
|
|||
for_each_online_cpu(i)
|
||||
set_astate(i, pas_astate_new);
|
||||
|
||||
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
|
||||
cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
|
||||
mutex_unlock(&pas_switch_mutex);
|
||||
|
||||
ppc_proc_freq = freqs.new * 1000ul;
|
||||
|
|
|
@ -335,7 +335,8 @@ static int pmu_set_cpu_speed(int low_speed)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int do_set_cpu_speed(int speed_mode, int notify)
|
||||
static int do_set_cpu_speed(struct cpufreq_policy *policy, int speed_mode,
|
||||
int notify)
|
||||
{
|
||||
struct cpufreq_freqs freqs;
|
||||
unsigned long l3cr;
|
||||
|
@ -343,13 +344,12 @@ static int do_set_cpu_speed(int speed_mode, int notify)
|
|||
|
||||
freqs.old = cur_freq;
|
||||
freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
|
||||
freqs.cpu = smp_processor_id();
|
||||
|
||||
if (freqs.old == freqs.new)
|
||||
return 0;
|
||||
|
||||
if (notify)
|
||||
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
|
||||
cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
|
||||
if (speed_mode == CPUFREQ_LOW &&
|
||||
cpu_has_feature(CPU_FTR_L3CR)) {
|
||||
l3cr = _get_L3CR();
|
||||
|
@ -366,7 +366,7 @@ static int do_set_cpu_speed(int speed_mode, int notify)
|
|||
_set_L3CR(prev_l3cr);
|
||||
}
|
||||
if (notify)
|
||||
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
|
||||
cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
|
||||
cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
|
||||
|
||||
return 0;
|
||||
|
@ -393,7 +393,7 @@ static int pmac_cpufreq_target( struct cpufreq_policy *policy,
|
|||
target_freq, relation, &newstate))
|
||||
return -EINVAL;
|
||||
|
||||
rc = do_set_cpu_speed(newstate, 1);
|
||||
rc = do_set_cpu_speed(policy, newstate, 1);
|
||||
|
||||
ppc_proc_freq = cur_freq * 1000ul;
|
||||
return rc;
|
||||
|
@ -442,7 +442,7 @@ static int pmac_cpufreq_suspend(struct cpufreq_policy *policy)
|
|||
no_schedule = 1;
|
||||
sleep_freq = cur_freq;
|
||||
if (cur_freq == low_freq && !is_pmu_based)
|
||||
do_set_cpu_speed(CPUFREQ_HIGH, 0);
|
||||
do_set_cpu_speed(policy, CPUFREQ_HIGH, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -458,7 +458,7 @@ static int pmac_cpufreq_resume(struct cpufreq_policy *policy)
|
|||
* is that we force a switch to whatever it was, which is
|
||||
* probably high speed due to our suspend() routine
|
||||
*/
|
||||
do_set_cpu_speed(sleep_freq == low_freq ?
|
||||
do_set_cpu_speed(policy, sleep_freq == low_freq ?
|
||||
CPUFREQ_LOW : CPUFREQ_HIGH, 0);
|
||||
|
||||
ppc_proc_freq = cur_freq * 1000ul;
|
||||
|
|
|
@ -339,11 +339,10 @@ static int g5_cpufreq_target(struct cpufreq_policy *policy,
|
|||
|
||||
freqs.old = g5_cpu_freqs[g5_pmode_cur].frequency;
|
||||
freqs.new = g5_cpu_freqs[newstate].frequency;
|
||||
freqs.cpu = 0;
|
||||
|
||||
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
|
||||
cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
|
||||
rc = g5_switch_freq(newstate);
|
||||
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
|
||||
cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
|
||||
|
||||
mutex_unlock(&g5_switch_mutex);
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
#include "pseries.h"
|
||||
|
||||
struct cpuidle_driver pseries_idle_driver = {
|
||||
.name = "pseries_idle",
|
||||
.owner = THIS_MODULE,
|
||||
.name = "pseries_idle",
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
#define MAX_IDLE_STATE_COUNT 2
|
||||
|
@ -33,10 +33,8 @@ static int max_idle_state = MAX_IDLE_STATE_COUNT - 1;
|
|||
static struct cpuidle_device __percpu *pseries_cpuidle_devices;
|
||||
static struct cpuidle_state *cpuidle_state_table;
|
||||
|
||||
static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before)
|
||||
static inline void idle_loop_prolog(unsigned long *in_purr)
|
||||
{
|
||||
|
||||
*kt_before = ktime_get();
|
||||
*in_purr = mfspr(SPRN_PURR);
|
||||
/*
|
||||
* Indicate to the HV that we are idle. Now would be
|
||||
|
@ -45,12 +43,10 @@ static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before)
|
|||
get_lppaca()->idle = 1;
|
||||
}
|
||||
|
||||
static inline s64 idle_loop_epilog(unsigned long in_purr, ktime_t kt_before)
|
||||
static inline void idle_loop_epilog(unsigned long in_purr)
|
||||
{
|
||||
get_lppaca()->wait_state_cycles += mfspr(SPRN_PURR) - in_purr;
|
||||
get_lppaca()->idle = 0;
|
||||
|
||||
return ktime_to_us(ktime_sub(ktime_get(), kt_before));
|
||||
}
|
||||
|
||||
static int snooze_loop(struct cpuidle_device *dev,
|
||||
|
@ -58,10 +54,9 @@ static int snooze_loop(struct cpuidle_device *dev,
|
|||
int index)
|
||||
{
|
||||
unsigned long in_purr;
|
||||
ktime_t kt_before;
|
||||
int cpu = dev->cpu;
|
||||
|
||||
idle_loop_prolog(&in_purr, &kt_before);
|
||||
idle_loop_prolog(&in_purr);
|
||||
local_irq_enable();
|
||||
set_thread_flag(TIF_POLLING_NRFLAG);
|
||||
|
||||
|
@ -75,8 +70,8 @@ static int snooze_loop(struct cpuidle_device *dev,
|
|||
clear_thread_flag(TIF_POLLING_NRFLAG);
|
||||
smp_mb();
|
||||
|
||||
dev->last_residency =
|
||||
(int)idle_loop_epilog(in_purr, kt_before);
|
||||
idle_loop_epilog(in_purr);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
|
@ -102,9 +97,8 @@ static int dedicated_cede_loop(struct cpuidle_device *dev,
|
|||
int index)
|
||||
{
|
||||
unsigned long in_purr;
|
||||
ktime_t kt_before;
|
||||
|
||||
idle_loop_prolog(&in_purr, &kt_before);
|
||||
idle_loop_prolog(&in_purr);
|
||||
get_lppaca()->donate_dedicated_cpu = 1;
|
||||
|
||||
ppc64_runlatch_off();
|
||||
|
@ -112,8 +106,9 @@ static int dedicated_cede_loop(struct cpuidle_device *dev,
|
|||
check_and_cede_processor();
|
||||
|
||||
get_lppaca()->donate_dedicated_cpu = 0;
|
||||
dev->last_residency =
|
||||
(int)idle_loop_epilog(in_purr, kt_before);
|
||||
|
||||
idle_loop_epilog(in_purr);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
|
@ -122,9 +117,8 @@ static int shared_cede_loop(struct cpuidle_device *dev,
|
|||
int index)
|
||||
{
|
||||
unsigned long in_purr;
|
||||
ktime_t kt_before;
|
||||
|
||||
idle_loop_prolog(&in_purr, &kt_before);
|
||||
idle_loop_prolog(&in_purr);
|
||||
|
||||
/*
|
||||
* Yield the processor to the hypervisor. We return if
|
||||
|
@ -135,8 +129,8 @@ static int shared_cede_loop(struct cpuidle_device *dev,
|
|||
*/
|
||||
check_and_cede_processor();
|
||||
|
||||
dev->last_residency =
|
||||
(int)idle_loop_epilog(in_purr, kt_before);
|
||||
idle_loop_epilog(in_purr);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
|
|
|
@ -622,25 +622,7 @@ config SH_CLK_CPG_LEGACY
|
|||
endmenu
|
||||
|
||||
menu "CPU Frequency scaling"
|
||||
|
||||
source "drivers/cpufreq/Kconfig"
|
||||
|
||||
config SH_CPU_FREQ
|
||||
tristate "SuperH CPU Frequency driver"
|
||||
depends on CPU_FREQ
|
||||
select CPU_FREQ_TABLE
|
||||
help
|
||||
This adds the cpufreq driver for SuperH. Any CPU that supports
|
||||
clock rate rounding through the clock framework can use this
|
||||
driver. While it will make the kernel slightly larger, this is
|
||||
harmless for CPUs that don't support rate rounding. The driver
|
||||
will also generate a notice in the boot log before disabling
|
||||
itself if the CPU in question is not capable of rate rounding.
|
||||
|
||||
For details, take a look at <file:Documentation/cpu-freq>.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
endmenu
|
||||
|
||||
source "arch/sh/drivers/Kconfig"
|
||||
|
|
|
@ -14,9 +14,9 @@ struct swsusp_arch_regs {
|
|||
void sh_mobile_call_standby(unsigned long mode);
|
||||
|
||||
#ifdef CONFIG_CPU_IDLE
|
||||
void sh_mobile_setup_cpuidle(void);
|
||||
int sh_mobile_setup_cpuidle(void);
|
||||
#else
|
||||
static inline void sh_mobile_setup_cpuidle(void) {}
|
||||
static inline int sh_mobile_setup_cpuidle(void) { return 0; }
|
||||
#endif
|
||||
|
||||
/* notifier chains for pre/post sleep hooks */
|
||||
|
|
|
@ -31,7 +31,6 @@ obj-$(CONFIG_VSYSCALL) += vsyscall/
|
|||
obj-$(CONFIG_SMP) += smp.o
|
||||
obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
|
||||
obj-$(CONFIG_KGDB) += kgdb.o
|
||||
obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o
|
||||
obj-$(CONFIG_MODULES) += sh_ksyms_$(BITS).o module.o
|
||||
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
|
||||
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
|
||||
|
|
|
@ -51,70 +51,53 @@ static int cpuidle_sleep_enter(struct cpuidle_device *dev,
|
|||
return k;
|
||||
}
|
||||
|
||||
static struct cpuidle_device cpuidle_dev;
|
||||
static struct cpuidle_driver cpuidle_driver = {
|
||||
.name = "sh_idle",
|
||||
.owner = THIS_MODULE,
|
||||
.en_core_tk_irqen = 1,
|
||||
.name = "sh_idle",
|
||||
.owner = THIS_MODULE,
|
||||
.states = {
|
||||
{
|
||||
.exit_latency = 1,
|
||||
.target_residency = 1 * 2,
|
||||
.power_usage = 3,
|
||||
.flags = CPUIDLE_FLAG_TIME_VALID,
|
||||
.enter = cpuidle_sleep_enter,
|
||||
.name = "C1",
|
||||
.desc = "SuperH Sleep Mode",
|
||||
},
|
||||
{
|
||||
.exit_latency = 100,
|
||||
.target_residency = 1 * 2,
|
||||
.power_usage = 1,
|
||||
.flags = CPUIDLE_FLAG_TIME_VALID,
|
||||
.enter = cpuidle_sleep_enter,
|
||||
.name = "C2",
|
||||
.desc = "SuperH Sleep Mode [SF]",
|
||||
.disabled = true,
|
||||
},
|
||||
{
|
||||
.exit_latency = 2300,
|
||||
.target_residency = 1 * 2,
|
||||
.power_usage = 1,
|
||||
.flags = CPUIDLE_FLAG_TIME_VALID,
|
||||
.enter = cpuidle_sleep_enter,
|
||||
.name = "C3",
|
||||
.desc = "SuperH Mobile Standby Mode [SF]",
|
||||
.disabled = true,
|
||||
},
|
||||
},
|
||||
.safe_state_index = 0,
|
||||
.state_count = 3,
|
||||
};
|
||||
|
||||
void sh_mobile_setup_cpuidle(void)
|
||||
int __init sh_mobile_setup_cpuidle(void)
|
||||
{
|
||||
struct cpuidle_device *dev = &cpuidle_dev;
|
||||
struct cpuidle_driver *drv = &cpuidle_driver;
|
||||
struct cpuidle_state *state;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
if (sh_mobile_sleep_supported & SUSP_SH_SF)
|
||||
cpuidle_driver.states[1].disabled = false;
|
||||
|
||||
for (i = 0; i < CPUIDLE_STATE_MAX; i++) {
|
||||
drv->states[i].name[0] = '\0';
|
||||
drv->states[i].desc[0] = '\0';
|
||||
}
|
||||
if (sh_mobile_sleep_supported & SUSP_SH_STANDBY)
|
||||
cpuidle_driver.states[2].disabled = false;
|
||||
|
||||
i = CPUIDLE_DRIVER_STATE_START;
|
||||
|
||||
state = &drv->states[i++];
|
||||
snprintf(state->name, CPUIDLE_NAME_LEN, "C1");
|
||||
strncpy(state->desc, "SuperH Sleep Mode", CPUIDLE_DESC_LEN);
|
||||
state->exit_latency = 1;
|
||||
state->target_residency = 1 * 2;
|
||||
state->power_usage = 3;
|
||||
state->flags = 0;
|
||||
state->flags |= CPUIDLE_FLAG_TIME_VALID;
|
||||
state->enter = cpuidle_sleep_enter;
|
||||
|
||||
drv->safe_state_index = i-1;
|
||||
|
||||
if (sh_mobile_sleep_supported & SUSP_SH_SF) {
|
||||
state = &drv->states[i++];
|
||||
snprintf(state->name, CPUIDLE_NAME_LEN, "C2");
|
||||
strncpy(state->desc, "SuperH Sleep Mode [SF]",
|
||||
CPUIDLE_DESC_LEN);
|
||||
state->exit_latency = 100;
|
||||
state->target_residency = 1 * 2;
|
||||
state->power_usage = 1;
|
||||
state->flags = 0;
|
||||
state->flags |= CPUIDLE_FLAG_TIME_VALID;
|
||||
state->enter = cpuidle_sleep_enter;
|
||||
}
|
||||
|
||||
if (sh_mobile_sleep_supported & SUSP_SH_STANDBY) {
|
||||
state = &drv->states[i++];
|
||||
snprintf(state->name, CPUIDLE_NAME_LEN, "C3");
|
||||
strncpy(state->desc, "SuperH Mobile Standby Mode [SF]",
|
||||
CPUIDLE_DESC_LEN);
|
||||
state->exit_latency = 2300;
|
||||
state->target_residency = 1 * 2;
|
||||
state->power_usage = 1;
|
||||
state->flags = 0;
|
||||
state->flags |= CPUIDLE_FLAG_TIME_VALID;
|
||||
state->enter = cpuidle_sleep_enter;
|
||||
}
|
||||
|
||||
drv->state_count = i;
|
||||
dev->state_count = i;
|
||||
|
||||
cpuidle_register_driver(&cpuidle_driver);
|
||||
|
||||
cpuidle_register_device(dev);
|
||||
return cpuidle_register(&cpuidle_driver);
|
||||
}
|
||||
|
|
|
@ -150,8 +150,7 @@ static const struct platform_suspend_ops sh_pm_ops = {
|
|||
static int __init sh_pm_init(void)
|
||||
{
|
||||
suspend_set_ops(&sh_pm_ops);
|
||||
sh_mobile_setup_cpuidle();
|
||||
return 0;
|
||||
return sh_mobile_setup_cpuidle();
|
||||
}
|
||||
|
||||
late_initcall(sh_pm_init);
|
||||
|
|
|
@ -254,29 +254,6 @@ config HOTPLUG_CPU
|
|||
|
||||
if SPARC64
|
||||
source "drivers/cpufreq/Kconfig"
|
||||
|
||||
config US3_FREQ
|
||||
tristate "UltraSPARC-III CPU Frequency driver"
|
||||
depends on CPU_FREQ
|
||||
select CPU_FREQ_TABLE
|
||||
help
|
||||
This adds the CPUFreq driver for UltraSPARC-III processors.
|
||||
|
||||
For details, take a look at <file:Documentation/cpu-freq>.
|
||||
|
||||
If in doubt, say N.
|
||||
|
||||
config US2E_FREQ
|
||||
tristate "UltraSPARC-IIe CPU Frequency driver"
|
||||
depends on CPU_FREQ
|
||||
select CPU_FREQ_TABLE
|
||||
help
|
||||
This adds the CPUFreq driver for UltraSPARC-IIe processors.
|
||||
|
||||
For details, take a look at <file:Documentation/cpu-freq>.
|
||||
|
||||
If in doubt, say N.
|
||||
|
||||
endif
|
||||
|
||||
config US3_MC
|
||||
|
|
|
@ -102,9 +102,6 @@ obj-$(CONFIG_PCI_MSI) += pci_msi.o
|
|||
|
||||
obj-$(CONFIG_COMPAT) += sys32.o sys_sparc32.o signal32.o
|
||||
|
||||
# sparc64 cpufreq
|
||||
obj-$(CONFIG_US3_FREQ) += us3_cpufreq.o
|
||||
obj-$(CONFIG_US2E_FREQ) += us2e_cpufreq.o
|
||||
obj-$(CONFIG_US3_MC) += chmc.o
|
||||
|
||||
obj-$(CONFIG_KPROBES) += kprobes.o
|
||||
|
|
|
@ -9,7 +9,6 @@ obj-y += setup.o signal.o sys.o stacktrace.o traps.o
|
|||
obj-$(CONFIG_MODULES) += ksyms.o module.o
|
||||
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
|
||||
|
||||
obj-$(CONFIG_CPU_FREQ) += cpu-ucv2.o
|
||||
obj-$(CONFIG_UNICORE_FPU_F64) += fpu-ucf64.o
|
||||
|
||||
# obj-y for architecture PKUnity v3
|
||||
|
|
|
@ -185,6 +185,7 @@
|
|||
#define X86_FEATURE_PTS (7*32+ 6) /* Intel Package Thermal Status */
|
||||
#define X86_FEATURE_DTHERM (7*32+ 7) /* Digital Thermal Sensor */
|
||||
#define X86_FEATURE_HW_PSTATE (7*32+ 8) /* AMD HW-PState */
|
||||
#define X86_FEATURE_PROC_FEEDBACK (7*32+ 9) /* AMD ProcFeedbackInterface */
|
||||
|
||||
/* Virtualization flags: Linux defined, word 8 */
|
||||
#define X86_FEATURE_TPR_SHADOW (8*32+ 0) /* Intel TPR Shadow */
|
||||
|
|
|
@ -373,7 +373,6 @@ static int apm_cpu_idle(struct cpuidle_device *dev,
|
|||
static struct cpuidle_driver apm_idle_driver = {
|
||||
.name = "apm_idle",
|
||||
.owner = THIS_MODULE,
|
||||
.en_core_tk_irqen = 1,
|
||||
.states = {
|
||||
{ /* entry 0 is for polling */ },
|
||||
{ /* entry 1 is for APM idle */
|
||||
|
|
|
@ -39,8 +39,9 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
|
|||
{ X86_FEATURE_APERFMPERF, CR_ECX, 0, 0x00000006, 0 },
|
||||
{ X86_FEATURE_EPB, CR_ECX, 3, 0x00000006, 0 },
|
||||
{ X86_FEATURE_XSAVEOPT, CR_EAX, 0, 0x0000000d, 1 },
|
||||
{ X86_FEATURE_CPB, CR_EDX, 9, 0x80000007, 0 },
|
||||
{ X86_FEATURE_HW_PSTATE, CR_EDX, 7, 0x80000007, 0 },
|
||||
{ X86_FEATURE_CPB, CR_EDX, 9, 0x80000007, 0 },
|
||||
{ X86_FEATURE_PROC_FEEDBACK, CR_EDX,11, 0x80000007, 0 },
|
||||
{ X86_FEATURE_NPT, CR_EDX, 0, 0x8000000a, 0 },
|
||||
{ X86_FEATURE_LBRV, CR_EDX, 1, 0x8000000a, 0 },
|
||||
{ X86_FEATURE_SVML, CR_EDX, 2, 0x8000000a, 0 },
|
||||
|
|
|
@ -298,14 +298,6 @@ config ACPI_DEBUG
|
|||
Documentation/kernel-parameters.txt to control the type and
|
||||
amount of debug output.
|
||||
|
||||
config ACPI_DEBUG_FUNC_TRACE
|
||||
bool "Additionally enable ACPI function tracing"
|
||||
default n
|
||||
depends on ACPI_DEBUG
|
||||
help
|
||||
ACPI Debug Statements slow down ACPI processing. Function trace
|
||||
is about half of the penalty and is rarely useful.
|
||||
|
||||
config ACPI_PCI_SLOT
|
||||
bool "PCI slot detection driver"
|
||||
depends on SYSFS
|
||||
|
@ -334,7 +326,7 @@ config X86_PM_TIMER
|
|||
|
||||
config ACPI_CONTAINER
|
||||
bool "Container and Module Devices"
|
||||
default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU || ACPI_HOTPLUG_IO)
|
||||
default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU)
|
||||
help
|
||||
This driver supports ACPI Container and Module devices (IDs
|
||||
ACPI0004, PNP0A05, and PNP0A06).
|
||||
|
@ -345,9 +337,8 @@ config ACPI_CONTAINER
|
|||
the module will be called container.
|
||||
|
||||
config ACPI_HOTPLUG_MEMORY
|
||||
tristate "Memory Hotplug"
|
||||
bool "Memory Hotplug"
|
||||
depends on MEMORY_HOTPLUG
|
||||
default n
|
||||
help
|
||||
This driver supports ACPI memory hotplug. The driver
|
||||
fields notifications on ACPI memory devices (PNP0C80),
|
||||
|
|
|
@ -39,6 +39,7 @@ acpi-y += ec.o
|
|||
acpi-$(CONFIG_ACPI_DOCK) += dock.o
|
||||
acpi-y += pci_root.o pci_link.o pci_irq.o
|
||||
acpi-y += csrt.o
|
||||
acpi-$(CONFIG_X86_INTEL_LPSS) += acpi_lpss.o
|
||||
acpi-y += acpi_platform.o
|
||||
acpi-y += power.o
|
||||
acpi-y += event.o
|
||||
|
|
292
drivers/acpi/acpi_lpss.c
Normal file
292
drivers/acpi/acpi_lpss.c
Normal file
|
@ -0,0 +1,292 @@
|
|||
/*
|
||||
* ACPI support for Intel Lynxpoint LPSS.
|
||||
*
|
||||
* Copyright (C) 2013, Intel Corporation
|
||||
* Authors: Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
* Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/platform_data/clk-lpss.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
ACPI_MODULE_NAME("acpi_lpss");
|
||||
|
||||
#define LPSS_CLK_SIZE 0x04
|
||||
#define LPSS_LTR_SIZE 0x18
|
||||
|
||||
/* Offsets relative to LPSS_PRIVATE_OFFSET */
|
||||
#define LPSS_GENERAL 0x08
|
||||
#define LPSS_GENERAL_LTR_MODE_SW BIT(2)
|
||||
#define LPSS_SW_LTR 0x10
|
||||
#define LPSS_AUTO_LTR 0x14
|
||||
|
||||
struct lpss_device_desc {
|
||||
bool clk_required;
|
||||
const char *clk_parent;
|
||||
bool ltr_required;
|
||||
unsigned int prv_offset;
|
||||
};
|
||||
|
||||
struct lpss_private_data {
|
||||
void __iomem *mmio_base;
|
||||
resource_size_t mmio_size;
|
||||
struct clk *clk;
|
||||
const struct lpss_device_desc *dev_desc;
|
||||
};
|
||||
|
||||
static struct lpss_device_desc lpt_dev_desc = {
|
||||
.clk_required = true,
|
||||
.clk_parent = "lpss_clk",
|
||||
.prv_offset = 0x800,
|
||||
.ltr_required = true,
|
||||
};
|
||||
|
||||
static struct lpss_device_desc lpt_sdio_dev_desc = {
|
||||
.prv_offset = 0x1000,
|
||||
.ltr_required = true,
|
||||
};
|
||||
|
||||
static const struct acpi_device_id acpi_lpss_device_ids[] = {
|
||||
/* Lynxpoint LPSS devices */
|
||||
{ "INT33C0", (unsigned long)&lpt_dev_desc },
|
||||
{ "INT33C1", (unsigned long)&lpt_dev_desc },
|
||||
{ "INT33C2", (unsigned long)&lpt_dev_desc },
|
||||
{ "INT33C3", (unsigned long)&lpt_dev_desc },
|
||||
{ "INT33C4", (unsigned long)&lpt_dev_desc },
|
||||
{ "INT33C5", (unsigned long)&lpt_dev_desc },
|
||||
{ "INT33C6", (unsigned long)&lpt_sdio_dev_desc },
|
||||
{ "INT33C7", },
|
||||
|
||||
{ }
|
||||
};
|
||||
|
||||
static int is_memory(struct acpi_resource *res, void *not_used)
|
||||
{
|
||||
struct resource r;
|
||||
return !acpi_dev_resource_memory(res, &r);
|
||||
}
|
||||
|
||||
/* LPSS main clock device. */
|
||||
static struct platform_device *lpss_clk_dev;
|
||||
|
||||
static inline void lpt_register_clock_device(void)
|
||||
{
|
||||
lpss_clk_dev = platform_device_register_simple("clk-lpt", -1, NULL, 0);
|
||||
}
|
||||
|
||||
static int register_device_clock(struct acpi_device *adev,
|
||||
struct lpss_private_data *pdata)
|
||||
{
|
||||
const struct lpss_device_desc *dev_desc = pdata->dev_desc;
|
||||
|
||||
if (!lpss_clk_dev)
|
||||
lpt_register_clock_device();
|
||||
|
||||
if (!dev_desc->clk_parent || !pdata->mmio_base
|
||||
|| pdata->mmio_size < dev_desc->prv_offset + LPSS_CLK_SIZE)
|
||||
return -ENODATA;
|
||||
|
||||
pdata->clk = clk_register_gate(NULL, dev_name(&adev->dev),
|
||||
dev_desc->clk_parent, 0,
|
||||
pdata->mmio_base + dev_desc->prv_offset,
|
||||
0, 0, NULL);
|
||||
if (IS_ERR(pdata->clk))
|
||||
return PTR_ERR(pdata->clk);
|
||||
|
||||
clk_register_clkdev(pdata->clk, NULL, dev_name(&adev->dev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_lpss_create_device(struct acpi_device *adev,
|
||||
const struct acpi_device_id *id)
|
||||
{
|
||||
struct lpss_device_desc *dev_desc;
|
||||
struct lpss_private_data *pdata;
|
||||
struct resource_list_entry *rentry;
|
||||
struct list_head resource_list;
|
||||
int ret;
|
||||
|
||||
dev_desc = (struct lpss_device_desc *)id->driver_data;
|
||||
if (!dev_desc)
|
||||
return acpi_create_platform_device(adev, id);
|
||||
|
||||
pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
|
||||
if (!pdata)
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_LIST_HEAD(&resource_list);
|
||||
ret = acpi_dev_get_resources(adev, &resource_list, is_memory, NULL);
|
||||
if (ret < 0)
|
||||
goto err_out;
|
||||
|
||||
list_for_each_entry(rentry, &resource_list, node)
|
||||
if (resource_type(&rentry->res) == IORESOURCE_MEM) {
|
||||
pdata->mmio_size = resource_size(&rentry->res);
|
||||
pdata->mmio_base = ioremap(rentry->res.start,
|
||||
pdata->mmio_size);
|
||||
pdata->dev_desc = dev_desc;
|
||||
break;
|
||||
}
|
||||
|
||||
acpi_dev_free_resource_list(&resource_list);
|
||||
|
||||
if (dev_desc->clk_required) {
|
||||
ret = register_device_clock(adev, pdata);
|
||||
if (ret) {
|
||||
/*
|
||||
* Skip the device, but don't terminate the namespace
|
||||
* scan.
|
||||
*/
|
||||
kfree(pdata);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
adev->driver_data = pdata;
|
||||
ret = acpi_create_platform_device(adev, id);
|
||||
if (ret > 0)
|
||||
return ret;
|
||||
|
||||
adev->driver_data = NULL;
|
||||
|
||||
err_out:
|
||||
kfree(pdata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lpss_reg_read(struct device *dev, unsigned int reg, u32 *val)
|
||||
{
|
||||
struct acpi_device *adev;
|
||||
struct lpss_private_data *pdata;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
ret = acpi_bus_get_device(ACPI_HANDLE(dev), &adev);
|
||||
if (WARN_ON(ret))
|
||||
return ret;
|
||||
|
||||
spin_lock_irqsave(&dev->power.lock, flags);
|
||||
if (pm_runtime_suspended(dev)) {
|
||||
ret = -EAGAIN;
|
||||
goto out;
|
||||
}
|
||||
pdata = acpi_driver_data(adev);
|
||||
if (WARN_ON(!pdata || !pdata->mmio_base)) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
*val = readl(pdata->mmio_base + pdata->dev_desc->prv_offset + reg);
|
||||
|
||||
out:
|
||||
spin_unlock_irqrestore(&dev->power.lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t lpss_ltr_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
u32 ltr_value = 0;
|
||||
unsigned int reg;
|
||||
int ret;
|
||||
|
||||
reg = strcmp(attr->attr.name, "auto_ltr") ? LPSS_SW_LTR : LPSS_AUTO_LTR;
|
||||
ret = lpss_reg_read(dev, reg, <r_value);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%08x\n", ltr_value);
|
||||
}
|
||||
|
||||
static ssize_t lpss_ltr_mode_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
u32 ltr_mode = 0;
|
||||
char *outstr;
|
||||
int ret;
|
||||
|
||||
ret = lpss_reg_read(dev, LPSS_GENERAL, <r_mode);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
outstr = (ltr_mode & LPSS_GENERAL_LTR_MODE_SW) ? "sw" : "auto";
|
||||
return sprintf(buf, "%s\n", outstr);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(auto_ltr, S_IRUSR, lpss_ltr_show, NULL);
|
||||
static DEVICE_ATTR(sw_ltr, S_IRUSR, lpss_ltr_show, NULL);
|
||||
static DEVICE_ATTR(ltr_mode, S_IRUSR, lpss_ltr_mode_show, NULL);
|
||||
|
||||
static struct attribute *lpss_attrs[] = {
|
||||
&dev_attr_auto_ltr.attr,
|
||||
&dev_attr_sw_ltr.attr,
|
||||
&dev_attr_ltr_mode.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group lpss_attr_group = {
|
||||
.attrs = lpss_attrs,
|
||||
.name = "lpss_ltr",
|
||||
};
|
||||
|
||||
static int acpi_lpss_platform_notify(struct notifier_block *nb,
|
||||
unsigned long action, void *data)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(data);
|
||||
struct lpss_private_data *pdata;
|
||||
struct acpi_device *adev;
|
||||
const struct acpi_device_id *id;
|
||||
int ret = 0;
|
||||
|
||||
id = acpi_match_device(acpi_lpss_device_ids, &pdev->dev);
|
||||
if (!id || !id->driver_data)
|
||||
return 0;
|
||||
|
||||
if (acpi_bus_get_device(ACPI_HANDLE(&pdev->dev), &adev))
|
||||
return 0;
|
||||
|
||||
pdata = acpi_driver_data(adev);
|
||||
if (!pdata || !pdata->mmio_base || !pdata->dev_desc->ltr_required)
|
||||
return 0;
|
||||
|
||||
if (pdata->mmio_size < pdata->dev_desc->prv_offset + LPSS_LTR_SIZE) {
|
||||
dev_err(&pdev->dev, "MMIO size insufficient to access LTR\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (action == BUS_NOTIFY_ADD_DEVICE)
|
||||
ret = sysfs_create_group(&pdev->dev.kobj, &lpss_attr_group);
|
||||
else if (action == BUS_NOTIFY_DEL_DEVICE)
|
||||
sysfs_remove_group(&pdev->dev.kobj, &lpss_attr_group);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct notifier_block acpi_lpss_nb = {
|
||||
.notifier_call = acpi_lpss_platform_notify,
|
||||
};
|
||||
|
||||
static struct acpi_scan_handler lpss_handler = {
|
||||
.ids = acpi_lpss_device_ids,
|
||||
.attach = acpi_lpss_create_device,
|
||||
};
|
||||
|
||||
void __init acpi_lpss_init(void)
|
||||
{
|
||||
if (!lpt_clk_init()) {
|
||||
bus_register_notifier(&platform_bus_type, &acpi_lpss_nb);
|
||||
acpi_scan_add_handler(&lpss_handler);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
/*
|
||||
* Copyright (C) 2004 Intel Corporation <naveen.b.s@intel.com>
|
||||
* Copyright (C) 2004, 2013 Intel Corporation
|
||||
* Author: Naveen B S <naveen.b.s@intel.com>
|
||||
* Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
|
@ -25,14 +27,10 @@
|
|||
* ranges.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/memory_hotplug.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <acpi/acpi_drivers.h>
|
||||
#include <linux/memory_hotplug.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#define ACPI_MEMORY_DEVICE_CLASS "memory"
|
||||
#define ACPI_MEMORY_DEVICE_HID "PNP0C80"
|
||||
|
@ -44,32 +42,28 @@
|
|||
#define PREFIX "ACPI:memory_hp:"
|
||||
|
||||
ACPI_MODULE_NAME("acpi_memhotplug");
|
||||
MODULE_AUTHOR("Naveen B S <naveen.b.s@intel.com>");
|
||||
MODULE_DESCRIPTION("Hotplug Mem Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
/* Memory Device States */
|
||||
#define MEMORY_INVALID_STATE 0
|
||||
#define MEMORY_POWER_ON_STATE 1
|
||||
#define MEMORY_POWER_OFF_STATE 2
|
||||
|
||||
static int acpi_memory_device_add(struct acpi_device *device);
|
||||
static int acpi_memory_device_remove(struct acpi_device *device);
|
||||
static int acpi_memory_device_add(struct acpi_device *device,
|
||||
const struct acpi_device_id *not_used);
|
||||
static void acpi_memory_device_remove(struct acpi_device *device);
|
||||
|
||||
static const struct acpi_device_id memory_device_ids[] = {
|
||||
{ACPI_MEMORY_DEVICE_HID, 0},
|
||||
{"", 0},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, memory_device_ids);
|
||||
|
||||
static struct acpi_driver acpi_memory_device_driver = {
|
||||
.name = "acpi_memhotplug",
|
||||
.class = ACPI_MEMORY_DEVICE_CLASS,
|
||||
static struct acpi_scan_handler memory_device_handler = {
|
||||
.ids = memory_device_ids,
|
||||
.ops = {
|
||||
.add = acpi_memory_device_add,
|
||||
.remove = acpi_memory_device_remove,
|
||||
},
|
||||
.attach = acpi_memory_device_add,
|
||||
.detach = acpi_memory_device_remove,
|
||||
.hotplug = {
|
||||
.enabled = true,
|
||||
},
|
||||
};
|
||||
|
||||
struct acpi_memory_info {
|
||||
|
@ -79,7 +73,6 @@ struct acpi_memory_info {
|
|||
unsigned short caching; /* memory cache attribute */
|
||||
unsigned short write_protect; /* memory read/write attribute */
|
||||
unsigned int enabled:1;
|
||||
unsigned int failed:1;
|
||||
};
|
||||
|
||||
struct acpi_memory_device {
|
||||
|
@ -153,48 +146,6 @@ acpi_memory_get_device_resources(struct acpi_memory_device *mem_device)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_memory_get_device(acpi_handle handle,
|
||||
struct acpi_memory_device **mem_device)
|
||||
{
|
||||
struct acpi_device *device = NULL;
|
||||
int result = 0;
|
||||
|
||||
acpi_scan_lock_acquire();
|
||||
|
||||
acpi_bus_get_device(handle, &device);
|
||||
if (device)
|
||||
goto end;
|
||||
|
||||
/*
|
||||
* Now add the notified device. This creates the acpi_device
|
||||
* and invokes .add function
|
||||
*/
|
||||
result = acpi_bus_scan(handle);
|
||||
if (result) {
|
||||
acpi_handle_warn(handle, "ACPI namespace scan failed\n");
|
||||
result = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
result = acpi_bus_get_device(handle, &device);
|
||||
if (result) {
|
||||
acpi_handle_warn(handle, "Missing device object\n");
|
||||
result = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
end:
|
||||
*mem_device = acpi_driver_data(device);
|
||||
if (!(*mem_device)) {
|
||||
dev_err(&device->dev, "driver data not found\n");
|
||||
result = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
acpi_scan_lock_release();
|
||||
return result;
|
||||
}
|
||||
|
||||
static int acpi_memory_check_device(struct acpi_memory_device *mem_device)
|
||||
{
|
||||
unsigned long long current_status;
|
||||
|
@ -249,13 +200,11 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)
|
|||
* returns -EEXIST. If add_memory() returns the other error, it
|
||||
* means that this memory block is not used by the kernel.
|
||||
*/
|
||||
if (result && result != -EEXIST) {
|
||||
info->failed = 1;
|
||||
if (result && result != -EEXIST)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!result)
|
||||
info->enabled = 1;
|
||||
info->enabled = 1;
|
||||
|
||||
/*
|
||||
* Add num_enable even if add_memory() returns -EEXIST, so the
|
||||
* device is bound to this driver.
|
||||
|
@ -286,16 +235,8 @@ static int acpi_memory_remove_memory(struct acpi_memory_device *mem_device)
|
|||
nid = acpi_get_node(mem_device->device->handle);
|
||||
|
||||
list_for_each_entry_safe(info, n, &mem_device->res_list, list) {
|
||||
if (info->failed)
|
||||
/* The kernel does not use this memory block */
|
||||
continue;
|
||||
|
||||
if (!info->enabled)
|
||||
/*
|
||||
* The kernel uses this memory block, but it may be not
|
||||
* managed by us.
|
||||
*/
|
||||
return -EBUSY;
|
||||
continue;
|
||||
|
||||
if (nid < 0)
|
||||
nid = memory_add_physaddr_to_nid(info->start_addr);
|
||||
|
@ -310,95 +251,21 @@ static int acpi_memory_remove_memory(struct acpi_memory_device *mem_device)
|
|||
return result;
|
||||
}
|
||||
|
||||
static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
|
||||
{
|
||||
struct acpi_memory_device *mem_device;
|
||||
struct acpi_device *device;
|
||||
struct acpi_eject_event *ej_event = NULL;
|
||||
u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
|
||||
acpi_status status;
|
||||
|
||||
switch (event) {
|
||||
case ACPI_NOTIFY_BUS_CHECK:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"\nReceived BUS CHECK notification for device\n"));
|
||||
/* Fall Through */
|
||||
case ACPI_NOTIFY_DEVICE_CHECK:
|
||||
if (event == ACPI_NOTIFY_DEVICE_CHECK)
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"\nReceived DEVICE CHECK notification for device\n"));
|
||||
if (acpi_memory_get_device(handle, &mem_device)) {
|
||||
acpi_handle_err(handle, "Cannot find driver data\n");
|
||||
break;
|
||||
}
|
||||
|
||||
ost_code = ACPI_OST_SC_SUCCESS;
|
||||
break;
|
||||
|
||||
case ACPI_NOTIFY_EJECT_REQUEST:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"\nReceived EJECT REQUEST notification for device\n"));
|
||||
|
||||
status = AE_ERROR;
|
||||
acpi_scan_lock_acquire();
|
||||
|
||||
if (acpi_bus_get_device(handle, &device)) {
|
||||
acpi_handle_err(handle, "Device doesn't exist\n");
|
||||
goto unlock;
|
||||
}
|
||||
mem_device = acpi_driver_data(device);
|
||||
if (!mem_device) {
|
||||
acpi_handle_err(handle, "Driver Data is NULL\n");
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
|
||||
if (!ej_event) {
|
||||
pr_err(PREFIX "No memory, dropping EJECT\n");
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
get_device(&device->dev);
|
||||
ej_event->device = device;
|
||||
ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
|
||||
/* The eject is carried out asynchronously. */
|
||||
status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
|
||||
ej_event);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
put_device(&device->dev);
|
||||
kfree(ej_event);
|
||||
}
|
||||
|
||||
unlock:
|
||||
acpi_scan_lock_release();
|
||||
if (ACPI_SUCCESS(status))
|
||||
return;
|
||||
default:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Unsupported event [0x%x]\n", event));
|
||||
|
||||
/* non-hotplug event; possibly handled by other handler */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Inform firmware that the hotplug operation has completed */
|
||||
(void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL);
|
||||
}
|
||||
|
||||
static void acpi_memory_device_free(struct acpi_memory_device *mem_device)
|
||||
{
|
||||
if (!mem_device)
|
||||
return;
|
||||
|
||||
acpi_memory_free_device_resources(mem_device);
|
||||
mem_device->device->driver_data = NULL;
|
||||
kfree(mem_device);
|
||||
}
|
||||
|
||||
static int acpi_memory_device_add(struct acpi_device *device)
|
||||
static int acpi_memory_device_add(struct acpi_device *device,
|
||||
const struct acpi_device_id *not_used)
|
||||
{
|
||||
struct acpi_memory_device *mem_device;
|
||||
int result;
|
||||
struct acpi_memory_device *mem_device = NULL;
|
||||
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
@ -423,147 +290,36 @@ static int acpi_memory_device_add(struct acpi_device *device)
|
|||
/* Set the device state */
|
||||
mem_device->state = MEMORY_POWER_ON_STATE;
|
||||
|
||||
pr_debug("%s\n", acpi_device_name(device));
|
||||
|
||||
if (!acpi_memory_check_device(mem_device)) {
|
||||
/* call add_memory func */
|
||||
result = acpi_memory_enable_device(mem_device);
|
||||
if (result) {
|
||||
dev_err(&device->dev,
|
||||
"Error in acpi_memory_enable_device\n");
|
||||
acpi_memory_device_free(mem_device);
|
||||
}
|
||||
result = acpi_memory_check_device(mem_device);
|
||||
if (result) {
|
||||
acpi_memory_device_free(mem_device);
|
||||
return 0;
|
||||
}
|
||||
return result;
|
||||
|
||||
result = acpi_memory_enable_device(mem_device);
|
||||
if (result) {
|
||||
dev_err(&device->dev, "acpi_memory_enable_device() error\n");
|
||||
acpi_memory_device_free(mem_device);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dev_dbg(&device->dev, "Memory device configured by ACPI\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int acpi_memory_device_remove(struct acpi_device *device)
|
||||
static void acpi_memory_device_remove(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_memory_device *mem_device = NULL;
|
||||
int result;
|
||||
struct acpi_memory_device *mem_device;
|
||||
|
||||
if (!device || !acpi_driver_data(device))
|
||||
return -EINVAL;
|
||||
return;
|
||||
|
||||
mem_device = acpi_driver_data(device);
|
||||
|
||||
result = acpi_memory_remove_memory(mem_device);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
acpi_memory_remove_memory(mem_device);
|
||||
acpi_memory_device_free(mem_device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to check for memory device
|
||||
*/
|
||||
static acpi_status is_memory_device(acpi_handle handle)
|
||||
void __init acpi_memory_hotplug_init(void)
|
||||
{
|
||||
char *hardware_id;
|
||||
acpi_status status;
|
||||
struct acpi_device_info *info;
|
||||
|
||||
status = acpi_get_object_info(handle, &info);
|
||||
if (ACPI_FAILURE(status))
|
||||
return status;
|
||||
|
||||
if (!(info->valid & ACPI_VALID_HID)) {
|
||||
kfree(info);
|
||||
return AE_ERROR;
|
||||
}
|
||||
|
||||
hardware_id = info->hardware_id.string;
|
||||
if ((hardware_id == NULL) ||
|
||||
(strcmp(hardware_id, ACPI_MEMORY_DEVICE_HID)))
|
||||
status = AE_ERROR;
|
||||
|
||||
kfree(info);
|
||||
return status;
|
||||
acpi_scan_add_handler_with_hotplug(&memory_device_handler, "memory");
|
||||
}
|
||||
|
||||
static acpi_status
|
||||
acpi_memory_register_notify_handler(acpi_handle handle,
|
||||
u32 level, void *ctxt, void **retv)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
|
||||
status = is_memory_device(handle);
|
||||
if (ACPI_FAILURE(status))
|
||||
return AE_OK; /* continue */
|
||||
|
||||
status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
|
||||
acpi_memory_device_notify, NULL);
|
||||
/* continue */
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static acpi_status
|
||||
acpi_memory_deregister_notify_handler(acpi_handle handle,
|
||||
u32 level, void *ctxt, void **retv)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
|
||||
status = is_memory_device(handle);
|
||||
if (ACPI_FAILURE(status))
|
||||
return AE_OK; /* continue */
|
||||
|
||||
status = acpi_remove_notify_handler(handle,
|
||||
ACPI_SYSTEM_NOTIFY,
|
||||
acpi_memory_device_notify);
|
||||
|
||||
return AE_OK; /* continue */
|
||||
}
|
||||
|
||||
static int __init acpi_memory_device_init(void)
|
||||
{
|
||||
int result;
|
||||
acpi_status status;
|
||||
|
||||
|
||||
result = acpi_bus_register_driver(&acpi_memory_device_driver);
|
||||
|
||||
if (result < 0)
|
||||
return -ENODEV;
|
||||
|
||||
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
|
||||
ACPI_UINT32_MAX,
|
||||
acpi_memory_register_notify_handler, NULL,
|
||||
NULL, NULL);
|
||||
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status, "walk_namespace failed"));
|
||||
acpi_bus_unregister_driver(&acpi_memory_device_driver);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit acpi_memory_device_exit(void)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
|
||||
/*
|
||||
* Adding this to un-install notification handlers for all the device
|
||||
* handles.
|
||||
*/
|
||||
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
|
||||
ACPI_UINT32_MAX,
|
||||
acpi_memory_deregister_notify_handler, NULL,
|
||||
NULL, NULL);
|
||||
|
||||
if (ACPI_FAILURE(status))
|
||||
ACPI_EXCEPTION((AE_INFO, status, "walk_namespace failed"));
|
||||
|
||||
acpi_bus_unregister_driver(&acpi_memory_device_driver);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
module_init(acpi_memory_device_init);
|
||||
module_exit(acpi_memory_device_exit);
|
||||
|
|
|
@ -236,7 +236,7 @@ static int create_power_saving_task(void)
|
|||
ps_tsks[ps_tsk_num] = kthread_run(power_saving_thread,
|
||||
(void *)(unsigned long)ps_tsk_num,
|
||||
"acpi_pad/%d", ps_tsk_num);
|
||||
rc = IS_ERR(ps_tsks[ps_tsk_num]) ? PTR_ERR(ps_tsks[ps_tsk_num]) : 0;
|
||||
rc = PTR_RET(ps_tsks[ps_tsk_num]);
|
||||
if (!rc)
|
||||
ps_tsk_num++;
|
||||
else
|
||||
|
|
|
@ -22,9 +22,6 @@
|
|||
|
||||
ACPI_MODULE_NAME("platform");
|
||||
|
||||
/* Flags for acpi_create_platform_device */
|
||||
#define ACPI_PLATFORM_CLK BIT(0)
|
||||
|
||||
/*
|
||||
* The following ACPI IDs are known to be suitable for representing as
|
||||
* platform devices.
|
||||
|
@ -33,33 +30,9 @@ static const struct acpi_device_id acpi_platform_device_ids[] = {
|
|||
|
||||
{ "PNP0D40" },
|
||||
|
||||
/* Haswell LPSS devices */
|
||||
{ "INT33C0", ACPI_PLATFORM_CLK },
|
||||
{ "INT33C1", ACPI_PLATFORM_CLK },
|
||||
{ "INT33C2", ACPI_PLATFORM_CLK },
|
||||
{ "INT33C3", ACPI_PLATFORM_CLK },
|
||||
{ "INT33C4", ACPI_PLATFORM_CLK },
|
||||
{ "INT33C5", ACPI_PLATFORM_CLK },
|
||||
{ "INT33C6", ACPI_PLATFORM_CLK },
|
||||
{ "INT33C7", ACPI_PLATFORM_CLK },
|
||||
|
||||
{ }
|
||||
};
|
||||
|
||||
static int acpi_create_platform_clks(struct acpi_device *adev)
|
||||
{
|
||||
static struct platform_device *pdev;
|
||||
|
||||
/* Create Lynxpoint LPSS clocks */
|
||||
if (!pdev && !strncmp(acpi_device_hid(adev), "INT33C", 6)) {
|
||||
pdev = platform_device_register_simple("clk-lpt", -1, NULL, 0);
|
||||
if (IS_ERR(pdev))
|
||||
return PTR_ERR(pdev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* acpi_create_platform_device - Create platform device for ACPI device node
|
||||
* @adev: ACPI device node to create a platform device for.
|
||||
|
@ -71,10 +44,9 @@ static int acpi_create_platform_clks(struct acpi_device *adev)
|
|||
*
|
||||
* Name of the platform device will be the same as @adev's.
|
||||
*/
|
||||
static int acpi_create_platform_device(struct acpi_device *adev,
|
||||
const struct acpi_device_id *id)
|
||||
int acpi_create_platform_device(struct acpi_device *adev,
|
||||
const struct acpi_device_id *id)
|
||||
{
|
||||
unsigned long flags = id->driver_data;
|
||||
struct platform_device *pdev = NULL;
|
||||
struct acpi_device *acpi_parent;
|
||||
struct platform_device_info pdevinfo;
|
||||
|
@ -83,14 +55,6 @@ static int acpi_create_platform_device(struct acpi_device *adev,
|
|||
struct resource *resources;
|
||||
int count;
|
||||
|
||||
if (flags & ACPI_PLATFORM_CLK) {
|
||||
int ret = acpi_create_platform_clks(adev);
|
||||
if (ret) {
|
||||
dev_err(&adev->dev, "failed to create clocks\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the ACPI node already has a physical device attached, skip it. */
|
||||
if (adev->physical_node_count)
|
||||
return 0;
|
||||
|
|
|
@ -83,6 +83,7 @@ acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o
|
|||
acpi-y += \
|
||||
nsaccess.o \
|
||||
nsalloc.o \
|
||||
nsconvert.o \
|
||||
nsdump.o \
|
||||
nseval.o \
|
||||
nsinit.o \
|
||||
|
@ -160,6 +161,7 @@ acpi-y += \
|
|||
utobject.o \
|
||||
utosi.o \
|
||||
utownerid.o \
|
||||
utpredef.o \
|
||||
utresrc.o \
|
||||
utstate.o \
|
||||
utstring.o \
|
||||
|
|
|
@ -224,6 +224,7 @@ ACPI_EXTERN u8 acpi_gbl_global_lock_pending;
|
|||
*/
|
||||
ACPI_EXTERN acpi_spinlock acpi_gbl_gpe_lock; /* For GPE data structs and registers */
|
||||
ACPI_EXTERN acpi_spinlock acpi_gbl_hardware_lock; /* For ACPI H/W except GPE registers */
|
||||
ACPI_EXTERN acpi_spinlock acpi_gbl_reference_count_lock;
|
||||
|
||||
/* Mutex for _OSI support */
|
||||
|
||||
|
@ -413,10 +414,12 @@ ACPI_EXTERN u8 acpi_gbl_db_output_flags;
|
|||
|
||||
#ifdef ACPI_DISASSEMBLER
|
||||
|
||||
u8 ACPI_INIT_GLOBAL(acpi_gbl_ignore_noop_operator, FALSE);
|
||||
ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_ignore_noop_operator, FALSE);
|
||||
|
||||
ACPI_EXTERN u8 acpi_gbl_db_opt_disasm;
|
||||
ACPI_EXTERN u8 acpi_gbl_db_opt_verbose;
|
||||
ACPI_EXTERN u8 acpi_gbl_num_external_methods;
|
||||
ACPI_EXTERN u32 acpi_gbl_resolved_external_methods;
|
||||
ACPI_EXTERN struct acpi_external_list *acpi_gbl_external_list;
|
||||
ACPI_EXTERN struct acpi_external_file *acpi_gbl_external_file_list;
|
||||
#endif
|
||||
|
|
|
@ -294,6 +294,8 @@ acpi_status(*acpi_internal_method) (struct acpi_walk_state * walk_state);
|
|||
#define ACPI_BTYPE_OBJECTS_AND_REFS 0x0001FFFF /* ARG or LOCAL */
|
||||
#define ACPI_BTYPE_ALL_OBJECTS 0x0000FFFF
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
/*
|
||||
* Information structure for ACPI predefined names.
|
||||
* Each entry in the table contains the following items:
|
||||
|
@ -304,7 +306,7 @@ acpi_status(*acpi_internal_method) (struct acpi_walk_state * walk_state);
|
|||
*/
|
||||
struct acpi_name_info {
|
||||
char name[ACPI_NAME_SIZE];
|
||||
u8 param_count;
|
||||
u16 argument_list;
|
||||
u8 expected_btypes;
|
||||
};
|
||||
|
||||
|
@ -327,7 +329,7 @@ struct acpi_package_info {
|
|||
u8 count1;
|
||||
u8 object_type2;
|
||||
u8 count2;
|
||||
u8 reserved;
|
||||
u16 reserved;
|
||||
};
|
||||
|
||||
/* Used for ACPI_PTYPE2_FIXED */
|
||||
|
@ -336,6 +338,7 @@ struct acpi_package_info2 {
|
|||
u8 type;
|
||||
u8 count;
|
||||
u8 object_type[4];
|
||||
u8 reserved;
|
||||
};
|
||||
|
||||
/* Used for ACPI_PTYPE1_OPTION */
|
||||
|
@ -345,7 +348,7 @@ struct acpi_package_info3 {
|
|||
u8 count;
|
||||
u8 object_type[2];
|
||||
u8 tail_object_type;
|
||||
u8 reserved;
|
||||
u16 reserved;
|
||||
};
|
||||
|
||||
union acpi_predefined_info {
|
||||
|
@ -355,6 +358,10 @@ union acpi_predefined_info {
|
|||
struct acpi_package_info3 ret_info3;
|
||||
};
|
||||
|
||||
/* Reset to default packing */
|
||||
|
||||
#pragma pack()
|
||||
|
||||
/* Data block used during object validation */
|
||||
|
||||
struct acpi_predefined_data {
|
||||
|
@ -363,6 +370,7 @@ struct acpi_predefined_data {
|
|||
union acpi_operand_object *parent_package;
|
||||
struct acpi_namespace_node *node;
|
||||
u32 flags;
|
||||
u32 return_btype;
|
||||
u8 node_flags;
|
||||
};
|
||||
|
||||
|
@ -371,6 +379,20 @@ struct acpi_predefined_data {
|
|||
#define ACPI_OBJECT_REPAIRED 1
|
||||
#define ACPI_OBJECT_WRAPPED 2
|
||||
|
||||
/* Return object auto-repair info */
|
||||
|
||||
typedef acpi_status(*acpi_object_converter) (union acpi_operand_object
|
||||
*original_object,
|
||||
union acpi_operand_object
|
||||
**converted_object);
|
||||
|
||||
struct acpi_simple_repair_info {
|
||||
char name[ACPI_NAME_SIZE];
|
||||
u32 unexpected_btypes;
|
||||
u32 package_index;
|
||||
acpi_object_converter object_converter;
|
||||
};
|
||||
|
||||
/*
|
||||
* Bitmapped return value types
|
||||
* Note: the actual data types must be contiguous, a loop in nspredef.c
|
||||
|
@ -1037,6 +1059,7 @@ struct acpi_external_list {
|
|||
u16 length;
|
||||
u8 type;
|
||||
u8 flags;
|
||||
u8 resolved;
|
||||
};
|
||||
|
||||
/* Values for Flags field above */
|
||||
|
|
|
@ -322,10 +322,12 @@
|
|||
* where a pointer to an object of type union acpi_operand_object can also
|
||||
* appear. This macro is used to distinguish them.
|
||||
*
|
||||
* The "Descriptor" field is the first field in both structures.
|
||||
* The "DescriptorType" field is the second field in both structures.
|
||||
*/
|
||||
#define ACPI_GET_DESCRIPTOR_PTR(d) (((union acpi_descriptor *)(void *)(d))->common.common_pointer)
|
||||
#define ACPI_SET_DESCRIPTOR_PTR(d, p) (((union acpi_descriptor *)(void *)(d))->common.common_pointer = (p))
|
||||
#define ACPI_GET_DESCRIPTOR_TYPE(d) (((union acpi_descriptor *)(void *)(d))->common.descriptor_type)
|
||||
#define ACPI_SET_DESCRIPTOR_TYPE(d, t) (((union acpi_descriptor *)(void *)(d))->common.descriptor_type = t)
|
||||
#define ACPI_SET_DESCRIPTOR_TYPE(d, t) (((union acpi_descriptor *)(void *)(d))->common.descriptor_type = (t))
|
||||
|
||||
/*
|
||||
* Macros for the master AML opcode table
|
||||
|
|
|
@ -166,6 +166,29 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent);
|
|||
|
||||
int acpi_ns_compare_names(char *name1, char *name2);
|
||||
|
||||
/*
|
||||
* nsconvert - Dynamic object conversion routines
|
||||
*/
|
||||
acpi_status
|
||||
acpi_ns_convert_to_integer(union acpi_operand_object *original_object,
|
||||
union acpi_operand_object **return_object);
|
||||
|
||||
acpi_status
|
||||
acpi_ns_convert_to_string(union acpi_operand_object *original_object,
|
||||
union acpi_operand_object **return_object);
|
||||
|
||||
acpi_status
|
||||
acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
|
||||
union acpi_operand_object **return_object);
|
||||
|
||||
acpi_status
|
||||
acpi_ns_convert_to_unicode(union acpi_operand_object *original_object,
|
||||
union acpi_operand_object **return_object);
|
||||
|
||||
acpi_status
|
||||
acpi_ns_convert_to_resource(union acpi_operand_object *original_object,
|
||||
union acpi_operand_object **return_object);
|
||||
|
||||
/*
|
||||
* nsdump - Namespace dump/print utilities
|
||||
*/
|
||||
|
@ -208,10 +231,6 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
|
|||
acpi_status return_status,
|
||||
union acpi_operand_object **return_object);
|
||||
|
||||
const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct
|
||||
acpi_namespace_node
|
||||
*node);
|
||||
|
||||
void
|
||||
acpi_ns_check_parameter_count(char *pathname,
|
||||
struct acpi_namespace_node *node,
|
||||
|
@ -289,7 +308,7 @@ acpi_ns_get_attached_data(struct acpi_namespace_node *node,
|
|||
* predefined methods/objects
|
||||
*/
|
||||
acpi_status
|
||||
acpi_ns_repair_object(struct acpi_predefined_data *data,
|
||||
acpi_ns_simple_repair(struct acpi_predefined_data *data,
|
||||
u32 expected_btypes,
|
||||
u32 package_index,
|
||||
union acpi_operand_object **return_object_ptr);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue