Skip to content

Commit

Permalink
Merge branch 'pm-cpuidle'
Browse files Browse the repository at this point in the history
* pm-cpuidle: (25 commits)
  cpuidle: Change struct menu_device field types
  cpuidle: Add a comment warning about possible overflow
  cpuidle: Fix variable domains in get_typical_interval()
  cpuidle: Fix menu_device->intervals type
  cpuidle: CodingStyle: Break up multiple assignments on single line
  cpuidle: Check called function parameter in get_typical_interval()
  cpuidle: Rearrange code and comments in get_typical_interval()
  cpuidle: Ignore interval prediction result when timer is shorter
  cpuidle-kirkwood.c: simplify use of devm_ioremap_resource()
  cpuidle: kirkwood: Make kirkwood_cpuidle_remove function static
  cpuidle: calxeda: Add missing __iomem annotation
  SH: cpuidle: Add missing parameter for cpuidle_register()
  ARM: ux500: cpuidle: Move ux500 cpuidle driver to drivers/cpuidle
  ARM: ux500: cpuidle: Remove pointless include
  ARM: ux500: cpuidle: Instantiate the driver from platform device
  ARM: davinci: cpuidle: Fix target residency
  cpuidle: Add Kconfig.arm and move calxeda, kirkwood and zynq
  cpuidle: Check if device is already registered
  cpuidle: Introduce __cpuidle_device_init()
  cpuidle: Introduce __cpuidle_unregister_device()
  ...
  • Loading branch information
Rafael J. Wysocki committed Aug 26, 2013
2 parents 95b6fcb + 51f245b commit c787881
Show file tree
Hide file tree
Showing 15 changed files with 256 additions and 163 deletions.
2 changes: 1 addition & 1 deletion arch/arm/mach-davinci/cpuidle.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ static struct cpuidle_driver davinci_idle_driver = {
.states[1] = {
.enter = davinci_enter_idle,
.exit_latency = 10,
.target_residency = 100000,
.target_residency = 10000,
.flags = CPUIDLE_FLAG_TIME_VALID,
.name = "DDR SR",
.desc = "WFI and DDR Self Refresh",
Expand Down
1 change: 0 additions & 1 deletion arch/arm/mach-ux500/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

obj-y := cpu.o devices.o devices-common.o \
id.o usb.o timer.o pm.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o
obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o
obj-$(CONFIG_MACH_MOP500) += board-mop500.o board-mop500-sdi.o \
Expand Down
4 changes: 1 addition & 3 deletions arch/sh/kernel/cpu/shmobile/cpuidle.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,11 @@ static struct cpuidle_driver cpuidle_driver = {

int __init sh_mobile_setup_cpuidle(void)
{
int ret;

if (sh_mobile_sleep_supported & SUSP_SH_SF)
cpuidle_driver.states[1].disabled = false;

if (sh_mobile_sleep_supported & SUSP_SH_STANDBY)
cpuidle_driver.states[2].disabled = false;

return cpuidle_register(&cpuidle_driver);
return cpuidle_register(&cpuidle_driver, NULL);
}
20 changes: 7 additions & 13 deletions drivers/cpuidle/Kconfig
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
menu "CPU Idle"

menuconfig CPU_IDLE
config CPU_IDLE
bool "CPU idle PM support"
default y if ACPI || PPC_PSERIES
select CPU_IDLE_GOV_LADDER if (!NO_HZ && !NO_HZ_IDLE)
Expand Down Expand Up @@ -29,20 +30,13 @@ config CPU_IDLE_GOV_MENU
bool "Menu governor (for tickless system)"
default y

config CPU_IDLE_CALXEDA
bool "CPU Idle Driver for Calxeda processors"
depends on ARCH_HIGHBANK
select ARM_CPU_SUSPEND
help
Select this to enable cpuidle on Calxeda processors.

config CPU_IDLE_ZYNQ
bool "CPU Idle Driver for Xilinx Zynq processors"
depends on ARCH_ZYNQ
help
Select this to enable cpuidle on Xilinx Zynq processors.
menu "ARM CPU Idle Drivers"
depends on ARM
source "drivers/cpuidle/Kconfig.arm"
endmenu

endif

config ARCH_NEEDS_CPU_IDLE_COUPLED
def_bool n
endmenu
29 changes: 29 additions & 0 deletions drivers/cpuidle/Kconfig.arm
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#
# ARM CPU Idle drivers
#

config ARM_HIGHBANK_CPUIDLE
bool "CPU Idle Driver for Calxeda processors"
depends on ARCH_HIGHBANK
select ARM_CPU_SUSPEND
help
Select this to enable cpuidle on Calxeda processors.

config ARM_KIRKWOOD_CPUIDLE
bool "CPU Idle Driver for Marvell Kirkwood SoCs"
depends on ARCH_KIRKWOOD
help
This adds the CPU Idle driver for Marvell Kirkwood SoCs.

config ARM_ZYNQ_CPUIDLE
bool "CPU Idle Driver for Xilinx Zynq processors"
depends on ARCH_ZYNQ
help
Select this to enable cpuidle on Xilinx Zynq processors.

config ARM_U8500_CPUIDLE
bool "Cpu Idle Driver for the ST-E u8500 processors"
depends on ARCH_U8500
help
Select this to enable cpuidle for ST-E u8500 processors

9 changes: 6 additions & 3 deletions drivers/cpuidle/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
obj-y += cpuidle.o driver.o governor.o sysfs.o governors/
obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o

obj-$(CONFIG_CPU_IDLE_CALXEDA) += cpuidle-calxeda.o
obj-$(CONFIG_ARCH_KIRKWOOD) += cpuidle-kirkwood.o
obj-$(CONFIG_CPU_IDLE_ZYNQ) += cpuidle-zynq.o
##################################################################################
# ARM SoC drivers
obj-$(CONFIG_ARM_HIGHBANK_CPUIDLE) += cpuidle-calxeda.o
obj-$(CONFIG_ARM_KIRKWOOD_CPUIDLE) += cpuidle-kirkwood.o
obj-$(CONFIG_ARM_ZYNQ_CPUIDLE) += cpuidle-zynq.o
obj-$(CONFIG_ARM_U8500_CPUIDLE) += cpuidle-ux500.o
2 changes: 1 addition & 1 deletion drivers/cpuidle/cpuidle-calxeda.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
#include <asm/cp15.h>

extern void highbank_set_cpu_jump(int cpu, void *jump_addr);
extern void *scu_base_addr;
extern void __iomem *scu_base_addr;

static noinline void calxeda_idle_restore(void)
{
Expand Down
5 changes: 1 addition & 4 deletions drivers/cpuidle/cpuidle-kirkwood.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,14 @@ static int kirkwood_cpuidle_probe(struct platform_device *pdev)
struct resource *res;

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL)
return -EINVAL;

ddr_operation_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(ddr_operation_base))
return PTR_ERR(ddr_operation_base);

return cpuidle_register(&kirkwood_idle_driver, NULL);
}

int kirkwood_cpuidle_remove(struct platform_device *pdev)
static int kirkwood_cpuidle_remove(struct platform_device *pdev)
{
cpuidle_unregister(&kirkwood_idle_driver);
return 0;
Expand Down
19 changes: 11 additions & 8 deletions arch/arm/mach-ux500/cpuidle.c → drivers/cpuidle/cpuidle-ux500.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,11 @@
#include <linux/smp.h>
#include <linux/mfd/dbx500-prcmu.h>
#include <linux/platform_data/arm-ux500-pm.h>
#include <linux/platform_device.h>

#include <asm/cpuidle.h>
#include <asm/proc-fns.h>

#include "db8500-regs.h"
#include "id.h"

static atomic_t master = ATOMIC_INIT(0);
static DEFINE_SPINLOCK(master_lock);

Expand Down Expand Up @@ -113,16 +111,21 @@ static struct cpuidle_driver ux500_idle_driver = {
.state_count = 2,
};

int __init ux500_idle_init(void)
static int __init dbx500_cpuidle_probe(struct platform_device *pdev)
{
if (!(cpu_is_u8500_family() || cpu_is_ux540_family()))
return -ENODEV;

/* Configure wake up reasons */
prcmu_enable_wakeups(PRCMU_WAKEUP(ARM) | PRCMU_WAKEUP(RTC) |
PRCMU_WAKEUP(ABB));

return cpuidle_register(&ux500_idle_driver, NULL);
}

device_initcall(ux500_idle_init);
static struct platform_driver dbx500_cpuidle_plat_driver = {
.driver = {
.name = "cpuidle-dbx500",
.owner = THIS_MODULE,
},
.probe = dbx500_cpuidle_probe,
};

module_platform_driver(dbx500_cpuidle_plat_driver);
94 changes: 53 additions & 41 deletions drivers/cpuidle/cpuidle.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ void disable_cpuidle(void)
off = 1;
}

static int __cpuidle_register_device(struct cpuidle_device *dev);

/**
* cpuidle_play_dead - cpu off-lining
*
Expand Down Expand Up @@ -278,7 +276,7 @@ static void poll_idle_init(struct cpuidle_driver *drv) {}
*/
int cpuidle_enable_device(struct cpuidle_device *dev)
{
int ret, i;
int ret;
struct cpuidle_driver *drv;

if (!dev)
Expand All @@ -292,15 +290,12 @@ int cpuidle_enable_device(struct cpuidle_device *dev)
if (!drv || !cpuidle_curr_governor)
return -EIO;

if (!dev->registered)
return -EINVAL;

if (!dev->state_count)
dev->state_count = drv->state_count;

if (dev->registered == 0) {
ret = __cpuidle_register_device(dev);
if (ret)
return ret;
}

poll_idle_init(drv);

ret = cpuidle_add_device_sysfs(dev);
Expand All @@ -311,12 +306,6 @@ int cpuidle_enable_device(struct cpuidle_device *dev)
(ret = cpuidle_curr_governor->enable(drv, dev)))
goto fail_sysfs;

for (i = 0; i < dev->state_count; i++) {
dev->states_usage[i].usage = 0;
dev->states_usage[i].time = 0;
}
dev->last_residency = 0;

smp_wmb();

dev->enabled = 1;
Expand Down Expand Up @@ -360,6 +349,23 @@ void cpuidle_disable_device(struct cpuidle_device *dev)

EXPORT_SYMBOL_GPL(cpuidle_disable_device);

static void __cpuidle_unregister_device(struct cpuidle_device *dev)
{
struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);

list_del(&dev->device_list);
per_cpu(cpuidle_devices, dev->cpu) = NULL;
module_put(drv->owner);
}

static int __cpuidle_device_init(struct cpuidle_device *dev)
{
memset(dev->states_usage, 0, sizeof(dev->states_usage));
dev->last_residency = 0;

return 0;
}

/**
* __cpuidle_register_device - internal register function called before register
* and enable routines
Expand All @@ -377,24 +383,15 @@ static int __cpuidle_register_device(struct cpuidle_device *dev)

per_cpu(cpuidle_devices, dev->cpu) = dev;
list_add(&dev->device_list, &cpuidle_detected_devices);
ret = cpuidle_add_sysfs(dev);
if (ret)
goto err_sysfs;

ret = cpuidle_coupled_register_device(dev);
if (ret)
goto err_coupled;
if (ret) {
__cpuidle_unregister_device(dev);
return ret;
}

dev->registered = 1;
return 0;

err_coupled:
cpuidle_remove_sysfs(dev);
err_sysfs:
list_del(&dev->device_list);
per_cpu(cpuidle_devices, dev->cpu) = NULL;
module_put(drv->owner);
return ret;
}

/**
Expand All @@ -403,25 +400,44 @@ static int __cpuidle_register_device(struct cpuidle_device *dev)
*/
int cpuidle_register_device(struct cpuidle_device *dev)
{
int ret;
int ret = -EBUSY;

if (!dev)
return -EINVAL;

mutex_lock(&cpuidle_lock);

if ((ret = __cpuidle_register_device(dev))) {
mutex_unlock(&cpuidle_lock);
return ret;
}
if (dev->registered)
goto out_unlock;

ret = __cpuidle_device_init(dev);
if (ret)
goto out_unlock;

ret = __cpuidle_register_device(dev);
if (ret)
goto out_unlock;

ret = cpuidle_add_sysfs(dev);
if (ret)
goto out_unregister;

ret = cpuidle_enable_device(dev);
if (ret)
goto out_sysfs;

cpuidle_enable_device(dev);
cpuidle_install_idle_handler();

out_unlock:
mutex_unlock(&cpuidle_lock);

return 0;
return ret;

out_sysfs:
cpuidle_remove_sysfs(dev);
out_unregister:
__cpuidle_unregister_device(dev);
goto out_unlock;
}

EXPORT_SYMBOL_GPL(cpuidle_register_device);
Expand All @@ -432,8 +448,6 @@ EXPORT_SYMBOL_GPL(cpuidle_register_device);
*/
void cpuidle_unregister_device(struct cpuidle_device *dev)
{
struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);

if (dev->registered == 0)
return;

Expand All @@ -442,14 +456,12 @@ void cpuidle_unregister_device(struct cpuidle_device *dev)
cpuidle_disable_device(dev);

cpuidle_remove_sysfs(dev);
list_del(&dev->device_list);
per_cpu(cpuidle_devices, dev->cpu) = NULL;

__cpuidle_unregister_device(dev);

cpuidle_coupled_unregister_device(dev);

cpuidle_resume_and_unlock();

module_put(drv->owner);
}

EXPORT_SYMBOL_GPL(cpuidle_unregister_device);
Expand Down
12 changes: 1 addition & 11 deletions drivers/cpuidle/governors/ladder.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,14 +192,4 @@ static int __init init_ladder(void)
return cpuidle_register_governor(&ladder_governor);
}

/**
* exit_ladder - exits the governor
*/
static void __exit exit_ladder(void)
{
cpuidle_unregister_governor(&ladder_governor);
}

MODULE_LICENSE("GPL");
module_init(init_ladder);
module_exit(exit_ladder);
postcore_initcall(init_ladder);
Loading

0 comments on commit c787881

Please sign in to comment.