Skip to content

Commit

Permalink
Merge branch 'pm-cpuidle'
Browse files Browse the repository at this point in the history
* pm-cpuidle: (51 commits)
  cpuidle: add maintainer entry
  ARM: s3c64xx: cpuidle: use init/exit common routine
  SH: cpuidle: use init/exit common routine
  cpuidle: fix comment format
  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
  ARM: shmobile: cpuidle: use init/exit common routine
  ARM: tegra: cpuidle: use init/exit common routine
  ARM: OMAP3: cpuidle: use init/exit common routine
  ARM: at91: cpuidle: use init/exit common routine
  ARM: ux500: cpuidle: use init/exit common routine
  cpuidle: make a single register function for all
  ARM: ux500: cpuidle: replace for_each_online_cpu by for_each_possible_cpu
  cpuidle: remove en_core_tk_irqen flag
  ARM: OMAP3: remove cpuidle_wrap_enter
  ...
  • Loading branch information
Rafael J. Wysocki committed Apr 27, 2013
2 parents ae62083 + a8e39c3 commit e4f5a3a
Show file tree
Hide file tree
Showing 39 changed files with 362 additions and 757 deletions.
6 changes: 6 additions & 0 deletions Documentation/cpuidle/driver.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
9 changes: 9 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -2206,6 +2206,15 @@ S: Maintained
F: drivers/cpufreq/
F: include/linux/cpufreq.h

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
Expand Down
1 change: 0 additions & 1 deletion arch/arm/configs/kirkwood_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 2 additions & 16 deletions arch/arm/mach-at91/cpuidle.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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);
29 changes: 3 additions & 26 deletions arch/arm/mach-davinci/cpuidle.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand All @@ -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,
Expand All @@ -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;
Expand All @@ -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 = {
Expand Down
1 change: 0 additions & 1 deletion arch/arm/mach-exynos/cpuidle.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/mach-imx/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
37 changes: 37 additions & 0 deletions arch/arm/mach-imx/cpuidle-imx5.c
Original file line number Diff line number Diff line change
@@ -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);
}
26 changes: 3 additions & 23 deletions arch/arm/mach-imx/cpuidle-imx6q.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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
Expand All @@ -43,34 +38,22 @@ 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,
/* WAIT */
{
.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",
Expand All @@ -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);
}
80 changes: 0 additions & 80 deletions arch/arm/mach-imx/cpuidle.c

This file was deleted.

10 changes: 4 additions & 6 deletions arch/arm/mach-imx/cpuidle.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading

0 comments on commit e4f5a3a

Please sign in to comment.