aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorDave Martin <Dave.Martin@arm.com>2013-06-18 14:37:02 +0100
committerNicolas Pitre <nicolas.pitre@linaro.org>2013-06-20 00:45:27 -0400
commit4725d41daea7e0cc79b3fb92af012b8cb18fccff (patch)
tree65dc3ec132d758a2d01b8b9cddf8d95654ffa233 /arch
parent0e95b2814e880cb031550d7c812c622df37f9154 (diff)
downloadvexpress-lsk-4725d41daea7e0cc79b3fb92af012b8cb18fccff.tar.gz
ARM: bL_switcher: Allow detachment of outstanding switch requests
In rare situations, it may be neecssary to prevent a completer registered using bL_switch_request_cb() from being called. For example, a cpufreq driver module needs to ensure that its completer won't get called if the module is about to be unloaded from the kernel. This patch provides a bL_switch_request_detach() function which detaches the completer from an outstanding request. The request continues in the background, as if it had been started using bL_switch_request(). If somebody else's completer is registered instead then the caller shouldn't care about it, so nothing is done in this case. Signed-off-by: Dave Martin <Dave.Martin@arm.com> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/common/bL_switcher.c32
-rw-r--r--arch/arm/include/asm/bL_switcher.h6
2 files changed, 38 insertions, 0 deletions
diff --git a/arch/arm/common/bL_switcher.c b/arch/arm/common/bL_switcher.c
index 6fbc73b8e02..b9ee01717a8 100644
--- a/arch/arm/common/bL_switcher.c
+++ b/arch/arm/common/bL_switcher.c
@@ -386,6 +386,38 @@ int bL_switch_request_cb(unsigned int cpu, unsigned int new_cluster_id,
EXPORT_SYMBOL_GPL(bL_switch_request_cb);
/*
+ * Detach an outstanding switch request.
+ *
+ * The switcher will continue with the switch request in the background,
+ * but the completer function will not be called.
+ *
+ * This may be necessary if the completer is in a kernel module which is
+ * about to be unloaded.
+ */
+void bL_switch_request_detach(unsigned int cpu,
+ bL_switch_completion_handler completer)
+{
+ struct bL_thread *t;
+
+ if (cpu >= ARRAY_SIZE(bL_threads)) {
+ pr_err("%s: cpu %d out of bounds\n", __func__, cpu);
+ return;
+ }
+
+ t = &bL_threads[cpu];
+
+ if (IS_ERR(t->task) || !t->task)
+ return;
+
+ spin_lock(&t->lock);
+ if (t->completer == completer)
+ t->completer = NULL;
+ spin_unlock(&t->lock);
+}
+
+EXPORT_SYMBOL_GPL(bL_switch_request_detach);
+
+/*
* Activation and configuration code.
*/
diff --git a/arch/arm/include/asm/bL_switcher.h b/arch/arm/include/asm/bL_switcher.h
index 98427597828..71d1b6a986b 100644
--- a/arch/arm/include/asm/bL_switcher.h
+++ b/arch/arm/include/asm/bL_switcher.h
@@ -40,6 +40,9 @@ static inline int bL_switch_request(unsigned int cpu, unsigned int new_cluster_i
#ifdef CONFIG_BL_SWITCHER
+void bL_switch_request_detach(unsigned int cpu,
+ bL_switch_completion_handler completer);
+
int bL_switcher_register_notifier(struct notifier_block *nb);
int bL_switcher_unregister_notifier(struct notifier_block *nb);
@@ -55,6 +58,9 @@ bool bL_switcher_get_enabled(void);
void bL_switcher_put_enabled(void);
#else
+static void bL_switch_request_detach(unsigned int cpu,
+ bL_switch_completion_handler completer) { }
+
static inline int bL_switcher_register_notifier(struct notifier_block *nb)
{
return 0;