summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-04-08 12:32:07 +0200
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-04-08 12:32:07 +0200
commitf69e44b2059f2238ac558b4a115ebcdefe20b9be (patch)
treebe2a95654d7c9cb38bbcbb7a83b862db359c79e1 /drivers
parentMerge branch 'acpi-assorted' into linux-next (diff)
parentcpuidle: imx6: remove timer broadcast initialization (diff)
downloadlinux-f69e44b2059f2238ac558b4a115ebcdefe20b9be.tar.xz
linux-f69e44b2059f2238ac558b4a115ebcdefe20b9be.zip
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
Diffstat (limited to 'drivers')
-rw-r--r--drivers/cpuidle/Kconfig6
-rw-r--r--drivers/cpuidle/Makefile2
-rw-r--r--drivers/cpuidle/cpuidle-kirkwood.c6
-rw-r--r--drivers/cpuidle/cpuidle.c9
-rw-r--r--drivers/cpuidle/driver.c31
5 files changed, 42 insertions, 12 deletions
diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
index 071e2c3eec4f..c4cc27e5c8a5 100644
--- a/drivers/cpuidle/Kconfig
+++ b/drivers/cpuidle/Kconfig
@@ -39,10 +39,4 @@ config CPU_IDLE_CALXEDA
help
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
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index 24c6e7d945ed..0d8bd55e776f 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -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_CPU_IDLE_CALXEDA) += cpuidle-calxeda.o
-obj-$(CONFIG_CPU_IDLE_KIRKWOOD) += cpuidle-kirkwood.o
+obj-$(CONFIG_ARCH_KIRKWOOD) += cpuidle-kirkwood.o
diff --git a/drivers/cpuidle/cpuidle-kirkwood.c b/drivers/cpuidle/cpuidle-kirkwood.c
index 670aa1e55cd6..53aad7324965 100644
--- a/drivers/cpuidle/cpuidle-kirkwood.c
+++ b/drivers/cpuidle/cpuidle-kirkwood.c
@@ -66,9 +66,9 @@ static int kirkwood_cpuidle_probe(struct platform_device *pdev)
if (res == NULL)
return -EINVAL;
- ddr_operation_base = devm_request_and_ioremap(&pdev->dev, res);
- if (!ddr_operation_base)
- return -EADDRNOTAVAIL;
+ ddr_operation_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(ddr_operation_base))
+ return PTR_ERR(ddr_operation_base);
device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id());
device->state_count = KIRKWOOD_MAX_STATES;
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index eba69290e074..c50037029184 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -8,6 +8,7 @@
* This code is licenced under the GPL.
*/
+#include <linux/clockchips.h>
#include <linux/kernel.h>
#include <linux/mutex.h>
#include <linux/sched.h>
@@ -146,12 +147,20 @@ int cpuidle_idle_call(void)
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))
entered_state = cpuidle_enter_state_coupled(dev, drv,
next_state);
else
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);
/* give the governor an opportunity to reflect on the outcome */
diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c
index 422c7b69ba7c..8dfaaae94444 100644
--- a/drivers/cpuidle/driver.c
+++ b/drivers/cpuidle/driver.c
@@ -11,6 +11,8 @@
#include <linux/mutex.h>
#include <linux/module.h>
#include <linux/cpuidle.h>
+#include <linux/cpumask.h>
+#include <linux/clockchips.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 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;
+
+ 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)
@@ -35,7 +56,7 @@ static int __cpuidle_register_driver(struct cpuidle_driver *drv, int cpu)
if (__cpuidle_get_cpu_driver(cpu))
return -EBUSY;
- __cpuidle_driver_init(drv);
+ __cpuidle_driver_init(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))
__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