Merge branch 'pm-cpuidle-next' into linux-next
* pm-cpuidle-next: cpuidle: imx6: remove timer broadcast initialization cpuidle: OMAP4: remove timer broadcast initialization cpuidle: ux500: remove timer broadcast initialization cpuidle: initialize the broadcast timer framework timer: move enum definition out of ifdef section cpuidle: kirkwood: fix coccicheck warnings cpuidle / kirkwood: remove redundant Kconfig option cpuidle / ux500 : use CPUIDLE_FLAG_TIMER_STOP flag cpuidle / imx6 : use CPUIDLE_FLAG_TIMER_STOP flag cpuidle / omap4 : use CPUIDLE_FLAG_TIMER_STOP flag cpuidle : handle clockevent notify from the cpuidle framework
This commit is contained in:
commit
f69e44b205
|
@ -56,7 +56,6 @@ CONFIG_AEABI=y
|
||||||
CONFIG_ZBOOT_ROM_TEXT=0x0
|
CONFIG_ZBOOT_ROM_TEXT=0x0
|
||||||
CONFIG_ZBOOT_ROM_BSS=0x0
|
CONFIG_ZBOOT_ROM_BSS=0x0
|
||||||
CONFIG_CPU_IDLE=y
|
CONFIG_CPU_IDLE=y
|
||||||
CONFIG_CPU_IDLE_KIRKWOOD=y
|
|
||||||
CONFIG_NET=y
|
CONFIG_NET=y
|
||||||
CONFIG_PACKET=y
|
CONFIG_PACKET=y
|
||||||
CONFIG_UNIX=y
|
CONFIG_UNIX=y
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/clockchips.h>
|
|
||||||
#include <linux/cpuidle.h>
|
#include <linux/cpuidle.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <asm/cpuidle.h>
|
#include <asm/cpuidle.h>
|
||||||
|
@ -21,10 +20,6 @@ static DEFINE_SPINLOCK(master_lock);
|
||||||
static int imx6q_enter_wait(struct cpuidle_device *dev,
|
static int imx6q_enter_wait(struct cpuidle_device *dev,
|
||||||
struct cpuidle_driver *drv, int index)
|
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()) {
|
if (atomic_inc_return(&master) == num_online_cpus()) {
|
||||||
/*
|
/*
|
||||||
* With this lock, we prevent other cpu to exit and enter
|
* With this lock, we prevent other cpu to exit and enter
|
||||||
|
@ -43,22 +38,10 @@ idle:
|
||||||
cpu_do_idle();
|
cpu_do_idle();
|
||||||
done:
|
done:
|
||||||
atomic_dec(&master);
|
atomic_dec(&master);
|
||||||
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
|
|
||||||
|
|
||||||
return index;
|
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 = {
|
static struct cpuidle_driver imx6q_cpuidle_driver = {
|
||||||
.name = "imx6q_cpuidle",
|
.name = "imx6q_cpuidle",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
|
@ -70,7 +53,8 @@ static struct cpuidle_driver imx6q_cpuidle_driver = {
|
||||||
{
|
{
|
||||||
.exit_latency = 50,
|
.exit_latency = 50,
|
||||||
.target_residency = 75,
|
.target_residency = 75,
|
||||||
.flags = CPUIDLE_FLAG_TIME_VALID,
|
.flags = CPUIDLE_FLAG_TIME_VALID |
|
||||||
|
CPUIDLE_FLAG_TIMER_STOP,
|
||||||
.enter = imx6q_enter_wait,
|
.enter = imx6q_enter_wait,
|
||||||
.name = "WAIT",
|
.name = "WAIT",
|
||||||
.desc = "Clock off",
|
.desc = "Clock off",
|
||||||
|
@ -88,8 +72,5 @@ int __init imx6q_cpuidle_init(void)
|
||||||
/* Set chicken bit to get a reliable WAIT mode support */
|
/* Set chicken bit to get a reliable WAIT mode support */
|
||||||
imx6q_set_chicken_bit();
|
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 imx_cpuidle_init(&imx6q_cpuidle_driver);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include <linux/cpuidle.h>
|
#include <linux/cpuidle.h>
|
||||||
#include <linux/cpu_pm.h>
|
#include <linux/cpu_pm.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
#include <linux/clockchips.h>
|
|
||||||
|
|
||||||
#include <asm/proc-fns.h>
|
#include <asm/proc-fns.h>
|
||||||
|
|
||||||
|
@ -82,7 +81,6 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
|
||||||
int index)
|
int index)
|
||||||
{
|
{
|
||||||
struct omap4_idle_statedata *cx = &omap4_idle_data[index];
|
struct omap4_idle_statedata *cx = &omap4_idle_data[index];
|
||||||
int cpu_id = smp_processor_id();
|
|
||||||
|
|
||||||
local_fiq_disable();
|
local_fiq_disable();
|
||||||
|
|
||||||
|
@ -109,8 +107,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
|
* Call idle CPU PM enter notifier chain so that
|
||||||
* VFP and per CPU interrupt context is saved.
|
* VFP and per CPU interrupt context is saved.
|
||||||
|
@ -152,8 +148,6 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
|
||||||
if (omap4_mpuss_read_prev_context_state())
|
if (omap4_mpuss_read_prev_context_state())
|
||||||
cpu_cluster_pm_exit();
|
cpu_cluster_pm_exit();
|
||||||
|
|
||||||
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id);
|
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
|
cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
|
||||||
cpu_done[dev->cpu] = false;
|
cpu_done[dev->cpu] = false;
|
||||||
|
@ -163,16 +157,6 @@ fail:
|
||||||
return index;
|
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 DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev);
|
||||||
|
|
||||||
static struct cpuidle_driver omap4_idle_driver = {
|
static struct cpuidle_driver omap4_idle_driver = {
|
||||||
|
@ -193,7 +177,8 @@ static struct cpuidle_driver omap4_idle_driver = {
|
||||||
/* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */
|
/* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */
|
||||||
.exit_latency = 328 + 440,
|
.exit_latency = 328 + 440,
|
||||||
.target_residency = 960,
|
.target_residency = 960,
|
||||||
.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED,
|
.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED |
|
||||||
|
CPUIDLE_FLAG_TIMER_STOP,
|
||||||
.enter = omap4_enter_idle_coupled,
|
.enter = omap4_enter_idle_coupled,
|
||||||
.name = "C2",
|
.name = "C2",
|
||||||
.desc = "MPUSS CSWR",
|
.desc = "MPUSS CSWR",
|
||||||
|
@ -202,7 +187,8 @@ static struct cpuidle_driver omap4_idle_driver = {
|
||||||
/* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */
|
/* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */
|
||||||
.exit_latency = 460 + 518,
|
.exit_latency = 460 + 518,
|
||||||
.target_residency = 1100,
|
.target_residency = 1100,
|
||||||
.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED,
|
.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED |
|
||||||
|
CPUIDLE_FLAG_TIMER_STOP,
|
||||||
.enter = omap4_enter_idle_coupled,
|
.enter = omap4_enter_idle_coupled,
|
||||||
.name = "C3",
|
.name = "C3",
|
||||||
.desc = "MPUSS OSWR",
|
.desc = "MPUSS OSWR",
|
||||||
|
@ -236,9 +222,6 @@ int __init omap4_idle_init(void)
|
||||||
if (!cpu_clkdm[0] || !cpu_clkdm[1])
|
if (!cpu_clkdm[0] || !cpu_clkdm[1])
|
||||||
return -ENODEV;
|
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) {
|
for_each_cpu(cpu_id, cpu_online_mask) {
|
||||||
dev = &per_cpu(omap4_idle_dev, cpu_id);
|
dev = &per_cpu(omap4_idle_dev, cpu_id);
|
||||||
dev->cpu = cpu_id;
|
dev->cpu = cpu_id;
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/cpuidle.h>
|
#include <linux/cpuidle.h>
|
||||||
#include <linux/clockchips.h>
|
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/atomic.h>
|
#include <linux/atomic.h>
|
||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
|
@ -30,8 +29,6 @@ static inline int ux500_enter_idle(struct cpuidle_device *dev,
|
||||||
int this_cpu = smp_processor_id();
|
int this_cpu = smp_processor_id();
|
||||||
bool recouple = false;
|
bool recouple = false;
|
||||||
|
|
||||||
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &this_cpu);
|
|
||||||
|
|
||||||
if (atomic_inc_return(&master) == num_online_cpus()) {
|
if (atomic_inc_return(&master) == num_online_cpus()) {
|
||||||
|
|
||||||
/* With this lock, we prevent the other cpu to exit and enter
|
/* With this lock, we prevent the other cpu to exit and enter
|
||||||
|
@ -91,8 +88,6 @@ out:
|
||||||
spin_unlock(&master_lock);
|
spin_unlock(&master_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &this_cpu);
|
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +101,8 @@ static struct cpuidle_driver ux500_idle_driver = {
|
||||||
.enter = ux500_enter_idle,
|
.enter = ux500_enter_idle,
|
||||||
.exit_latency = 70,
|
.exit_latency = 70,
|
||||||
.target_residency = 260,
|
.target_residency = 260,
|
||||||
.flags = CPUIDLE_FLAG_TIME_VALID,
|
.flags = CPUIDLE_FLAG_TIME_VALID |
|
||||||
|
CPUIDLE_FLAG_TIMER_STOP,
|
||||||
.name = "ApIdle",
|
.name = "ApIdle",
|
||||||
.desc = "ARM Retention",
|
.desc = "ARM Retention",
|
||||||
},
|
},
|
||||||
|
@ -115,16 +111,6 @@ static struct cpuidle_driver ux500_idle_driver = {
|
||||||
.state_count = 2,
|
.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 __init ux500_idle_init(void)
|
||||||
{
|
{
|
||||||
int ret, cpu;
|
int ret, cpu;
|
||||||
|
@ -134,13 +120,6 @@ int __init ux500_idle_init(void)
|
||||||
prcmu_enable_wakeups(PRCMU_WAKEUP(ARM) | PRCMU_WAKEUP(RTC) |
|
prcmu_enable_wakeups(PRCMU_WAKEUP(ARM) | PRCMU_WAKEUP(RTC) |
|
||||||
PRCMU_WAKEUP(ABB));
|
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);
|
ret = cpuidle_register_driver(&ux500_idle_driver);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printk(KERN_ERR "failed to register ux500 idle driver\n");
|
printk(KERN_ERR "failed to register ux500 idle driver\n");
|
||||||
|
|
|
@ -39,10 +39,4 @@ config CPU_IDLE_CALXEDA
|
||||||
help
|
help
|
||||||
Select this to enable cpuidle on Calxeda processors.
|
Select this to enable cpuidle on Calxeda processors.
|
||||||
|
|
||||||
config CPU_IDLE_KIRKWOOD
|
|
||||||
bool "CPU Idle Driver for Kirkwood processors"
|
|
||||||
depends on ARCH_KIRKWOOD
|
|
||||||
help
|
|
||||||
Select this to enable cpuidle on Kirkwood processors.
|
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -6,4 +6,4 @@ obj-y += cpuidle.o driver.o governor.o sysfs.o governors/
|
||||||
obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
|
obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
|
||||||
|
|
||||||
obj-$(CONFIG_CPU_IDLE_CALXEDA) += cpuidle-calxeda.o
|
obj-$(CONFIG_CPU_IDLE_CALXEDA) += cpuidle-calxeda.o
|
||||||
obj-$(CONFIG_CPU_IDLE_KIRKWOOD) += cpuidle-kirkwood.o
|
obj-$(CONFIG_ARCH_KIRKWOOD) += cpuidle-kirkwood.o
|
||||||
|
|
|
@ -66,9 +66,9 @@ static int kirkwood_cpuidle_probe(struct platform_device *pdev)
|
||||||
if (res == NULL)
|
if (res == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
ddr_operation_base = devm_request_and_ioremap(&pdev->dev, res);
|
ddr_operation_base = devm_ioremap_resource(&pdev->dev, res);
|
||||||
if (!ddr_operation_base)
|
if (IS_ERR(ddr_operation_base))
|
||||||
return -EADDRNOTAVAIL;
|
return PTR_ERR(ddr_operation_base);
|
||||||
|
|
||||||
device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id());
|
device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id());
|
||||||
device->state_count = KIRKWOOD_MAX_STATES;
|
device->state_count = KIRKWOOD_MAX_STATES;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
* This code is licenced under the GPL.
|
* This code is licenced under the GPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/clockchips.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
@ -146,12 +147,20 @@ int cpuidle_idle_call(void)
|
||||||
|
|
||||||
trace_cpu_idle_rcuidle(next_state, dev->cpu);
|
trace_cpu_idle_rcuidle(next_state, dev->cpu);
|
||||||
|
|
||||||
|
if (drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP)
|
||||||
|
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
|
||||||
|
&dev->cpu);
|
||||||
|
|
||||||
if (cpuidle_state_is_coupled(dev, drv, next_state))
|
if (cpuidle_state_is_coupled(dev, drv, next_state))
|
||||||
entered_state = cpuidle_enter_state_coupled(dev, drv,
|
entered_state = cpuidle_enter_state_coupled(dev, drv,
|
||||||
next_state);
|
next_state);
|
||||||
else
|
else
|
||||||
entered_state = cpuidle_enter_state(dev, drv, next_state);
|
entered_state = cpuidle_enter_state(dev, drv, next_state);
|
||||||
|
|
||||||
|
if (drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP)
|
||||||
|
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
|
||||||
|
&dev->cpu);
|
||||||
|
|
||||||
trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);
|
trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);
|
||||||
|
|
||||||
/* give the governor an opportunity to reflect on the outcome */
|
/* give the governor an opportunity to reflect on the outcome */
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/cpuidle.h>
|
#include <linux/cpuidle.h>
|
||||||
|
#include <linux/cpumask.h>
|
||||||
|
#include <linux/clockchips.h>
|
||||||
|
|
||||||
#include "cpuidle.h"
|
#include "cpuidle.h"
|
||||||
|
|
||||||
|
@ -19,9 +21,28 @@ DEFINE_SPINLOCK(cpuidle_driver_lock);
|
||||||
static void __cpuidle_set_cpu_driver(struct cpuidle_driver *drv, int cpu);
|
static void __cpuidle_set_cpu_driver(struct cpuidle_driver *drv, int cpu);
|
||||||
static struct cpuidle_driver * __cpuidle_get_cpu_driver(int cpu);
|
static struct cpuidle_driver * __cpuidle_get_cpu_driver(int cpu);
|
||||||
|
|
||||||
static void __cpuidle_driver_init(struct cpuidle_driver *drv)
|
static void cpuidle_setup_broadcast_timer(void *arg)
|
||||||
{
|
{
|
||||||
|
int cpu = smp_processor_id();
|
||||||
|
clockevents_notify((long)(arg), &cpu);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __cpuidle_driver_init(struct cpuidle_driver *drv, int cpu)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
drv->refcnt = 0;
|
drv->refcnt = 0;
|
||||||
|
|
||||||
|
for (i = drv->state_count - 1; i >= 0 ; i--) {
|
||||||
|
|
||||||
|
if (!(drv->states[i].flags & CPUIDLE_FLAG_TIMER_STOP))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
drv->bctimer = 1;
|
||||||
|
on_each_cpu_mask(get_cpu_mask(cpu), cpuidle_setup_broadcast_timer,
|
||||||
|
(void *)CLOCK_EVT_NOTIFY_BROADCAST_ON, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __cpuidle_register_driver(struct cpuidle_driver *drv, int cpu)
|
static int __cpuidle_register_driver(struct cpuidle_driver *drv, int cpu)
|
||||||
|
@ -35,7 +56,7 @@ static int __cpuidle_register_driver(struct cpuidle_driver *drv, int cpu)
|
||||||
if (__cpuidle_get_cpu_driver(cpu))
|
if (__cpuidle_get_cpu_driver(cpu))
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
__cpuidle_driver_init(drv);
|
__cpuidle_driver_init(drv, cpu);
|
||||||
|
|
||||||
__cpuidle_set_cpu_driver(drv, cpu);
|
__cpuidle_set_cpu_driver(drv, cpu);
|
||||||
|
|
||||||
|
@ -49,6 +70,12 @@ static void __cpuidle_unregister_driver(struct cpuidle_driver *drv, int cpu)
|
||||||
|
|
||||||
if (!WARN_ON(drv->refcnt > 0))
|
if (!WARN_ON(drv->refcnt > 0))
|
||||||
__cpuidle_set_cpu_driver(NULL, cpu);
|
__cpuidle_set_cpu_driver(NULL, cpu);
|
||||||
|
|
||||||
|
if (drv->bctimer) {
|
||||||
|
drv->bctimer = 0;
|
||||||
|
on_each_cpu_mask(get_cpu_mask(cpu), cpuidle_setup_broadcast_timer,
|
||||||
|
(void *)CLOCK_EVT_NOTIFY_BROADCAST_OFF, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_IDLE_MULTIPLE_DRIVERS
|
#ifdef CONFIG_CPU_IDLE_MULTIPLE_DRIVERS
|
||||||
|
|
|
@ -8,6 +8,20 @@
|
||||||
#ifndef _LINUX_CLOCKCHIPS_H
|
#ifndef _LINUX_CLOCKCHIPS_H
|
||||||
#define _LINUX_CLOCKCHIPS_H
|
#define _LINUX_CLOCKCHIPS_H
|
||||||
|
|
||||||
|
/* Clock event notification values */
|
||||||
|
enum clock_event_nofitiers {
|
||||||
|
CLOCK_EVT_NOTIFY_ADD,
|
||||||
|
CLOCK_EVT_NOTIFY_BROADCAST_ON,
|
||||||
|
CLOCK_EVT_NOTIFY_BROADCAST_OFF,
|
||||||
|
CLOCK_EVT_NOTIFY_BROADCAST_FORCE,
|
||||||
|
CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
|
||||||
|
CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
|
||||||
|
CLOCK_EVT_NOTIFY_SUSPEND,
|
||||||
|
CLOCK_EVT_NOTIFY_RESUME,
|
||||||
|
CLOCK_EVT_NOTIFY_CPU_DYING,
|
||||||
|
CLOCK_EVT_NOTIFY_CPU_DEAD,
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_GENERIC_CLOCKEVENTS_BUILD
|
#ifdef CONFIG_GENERIC_CLOCKEVENTS_BUILD
|
||||||
|
|
||||||
#include <linux/clocksource.h>
|
#include <linux/clocksource.h>
|
||||||
|
@ -26,20 +40,6 @@ enum clock_event_mode {
|
||||||
CLOCK_EVT_MODE_RESUME,
|
CLOCK_EVT_MODE_RESUME,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Clock event notification values */
|
|
||||||
enum clock_event_nofitiers {
|
|
||||||
CLOCK_EVT_NOTIFY_ADD,
|
|
||||||
CLOCK_EVT_NOTIFY_BROADCAST_ON,
|
|
||||||
CLOCK_EVT_NOTIFY_BROADCAST_OFF,
|
|
||||||
CLOCK_EVT_NOTIFY_BROADCAST_FORCE,
|
|
||||||
CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
|
|
||||||
CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
|
|
||||||
CLOCK_EVT_NOTIFY_SUSPEND,
|
|
||||||
CLOCK_EVT_NOTIFY_RESUME,
|
|
||||||
CLOCK_EVT_NOTIFY_CPU_DYING,
|
|
||||||
CLOCK_EVT_NOTIFY_CPU_DEAD,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clock event features
|
* Clock event features
|
||||||
*/
|
*/
|
||||||
|
@ -173,7 +173,7 @@ extern int tick_receive_broadcast(void);
|
||||||
#ifdef CONFIG_GENERIC_CLOCKEVENTS
|
#ifdef CONFIG_GENERIC_CLOCKEVENTS
|
||||||
extern void clockevents_notify(unsigned long reason, void *arg);
|
extern void clockevents_notify(unsigned long reason, void *arg);
|
||||||
#else
|
#else
|
||||||
# define clockevents_notify(reason, arg) do { } while (0)
|
static inline void clockevents_notify(unsigned long reason, void *arg) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else /* CONFIG_GENERIC_CLOCKEVENTS_BUILD */
|
#else /* CONFIG_GENERIC_CLOCKEVENTS_BUILD */
|
||||||
|
@ -181,7 +181,7 @@ extern void clockevents_notify(unsigned long reason, void *arg);
|
||||||
static inline void clockevents_suspend(void) {}
|
static inline void clockevents_suspend(void) {}
|
||||||
static inline void clockevents_resume(void) {}
|
static inline void clockevents_resume(void) {}
|
||||||
|
|
||||||
#define clockevents_notify(reason, arg) do { } while (0)
|
static inline void clockevents_notify(unsigned long reason, void *arg) {}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ struct cpuidle_state {
|
||||||
/* Idle State Flags */
|
/* Idle State Flags */
|
||||||
#define CPUIDLE_FLAG_TIME_VALID (0x01) /* is residency time measurable? */
|
#define CPUIDLE_FLAG_TIME_VALID (0x01) /* is residency time measurable? */
|
||||||
#define CPUIDLE_FLAG_COUPLED (0x02) /* state applies to multiple cpus */
|
#define CPUIDLE_FLAG_COUPLED (0x02) /* state applies to multiple cpus */
|
||||||
|
#define CPUIDLE_FLAG_TIMER_STOP (0x04) /* timer is stopped on this state */
|
||||||
|
|
||||||
#define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000)
|
#define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000)
|
||||||
|
|
||||||
|
@ -106,6 +107,8 @@ struct cpuidle_driver {
|
||||||
|
|
||||||
/* set to 1 to use the core cpuidle time keeping (for all states). */
|
/* set to 1 to use the core cpuidle time keeping (for all states). */
|
||||||
unsigned int en_core_tk_irqen:1;
|
unsigned int en_core_tk_irqen:1;
|
||||||
|
/* used by the cpuidle framework to setup the broadcast timer */
|
||||||
|
unsigned int bctimer:1;
|
||||||
/* states array must be ordered in decreasing power consumption */
|
/* states array must be ordered in decreasing power consumption */
|
||||||
struct cpuidle_state states[CPUIDLE_STATE_MAX];
|
struct cpuidle_state states[CPUIDLE_STATE_MAX];
|
||||||
int state_count;
|
int state_count;
|
||||||
|
|
Loading…
Reference in a new issue