From patchwork Mon Sep 23 23:17:45 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Pitre X-Patchwork-Id: 20536 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qe0-f70.google.com (mail-qe0-f70.google.com [209.85.128.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 94CDB28EB2 for ; Mon, 23 Sep 2013 23:18:03 +0000 (UTC) Received: by mail-qe0-f70.google.com with SMTP id b4sf3928442qen.9 for ; Mon, 23 Sep 2013 16:18:03 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe :content-transfer-encoding; bh=xfLbDTijygWKKz+khufGhyFR2TofhvB0pFgX9ybiyWE=; b=AyaZukWwGzDJJl6n9Veqbpt/ywUiDDx/WjOdov/6TT3CkESbDEuvkCNmcACN/aKFlB qddsSLRCXYt5g3N9BqjK09kms+jG1M0DPSUMqGNKxKAbl6lFYBsnmjBg1LAGosdze1zn LPfZtyVzWWapjgjstXZASCmgDorC/V1y66AmPQtFuTbj3Qbh3YSJvme55FlKiz/sPtnf xQHtM4bcuIKV3o1Dz26Tq2MtnWEC5rKGhrnnUhikmAzUFqmEXqBrmNLKHCs0j7E1e8Uh wo/SI6kIioz53eyCZIBT1qM1WNiQesFRLah0vT5K3HN5P0rK9i/vTYHUMZsnEd8O7nTP 2JfA== X-Gm-Message-State: ALoCoQnwyQCCwKIwMmh0hK5Dwqda8Dbz3KH8RGgyclWktOXH+5GY2UY1oxI2R+KsA8H6JzBk+UnZ X-Received: by 10.236.186.101 with SMTP id v65mr7981732yhm.12.1379978283237; Mon, 23 Sep 2013 16:18:03 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.35.244 with SMTP id l20ls1401030qej.98.gmail; Mon, 23 Sep 2013 16:18:03 -0700 (PDT) X-Received: by 10.221.51.206 with SMTP id vj14mr24447868vcb.17.1379978283122; Mon, 23 Sep 2013 16:18:03 -0700 (PDT) Received: from mail-ve0-f170.google.com (mail-ve0-f170.google.com [209.85.128.170]) by mx.google.com with ESMTPS id cz7si7548150veb.109.1969.12.31.16.00.00 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 23 Sep 2013 16:18:03 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.128.170 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.128.170; Received: by mail-ve0-f170.google.com with SMTP id c14so2976513vea.15 for ; Mon, 23 Sep 2013 16:18:03 -0700 (PDT) X-Received: by 10.58.55.138 with SMTP id s10mr1179281vep.45.1379978282967; Mon, 23 Sep 2013 16:18:02 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.174.196 with SMTP id u4csp208737vcz; Mon, 23 Sep 2013 16:18:02 -0700 (PDT) X-Received: by 10.58.219.227 with SMTP id pr3mr1196332vec.49.1379978281922; Mon, 23 Sep 2013 16:18:01 -0700 (PDT) Received: from relais.videotron.ca (relais.videotron.ca. [24.201.245.36]) by mx.google.com with ESMTP id d7si13390068qeo.8.1969.12.31.16.00.00; Mon, 23 Sep 2013 16:18:01 -0700 (PDT) Received-SPF: neutral (google.com: 24.201.245.36 is neither permitted nor denied by best guess record for domain of nicolas.pitre@linaro.org) client-ip=24.201.245.36; Received: from yoda.home ([70.83.209.44]) by VL-VM-MR005.ip.videotron.ca (Oracle Communications Messaging Exchange Server 7u4-22.01 64bit (built Apr 21 2011)) with ESMTP id <0MTL003B2Q21N190@VL-VM-MR005.ip.videotron.ca> for patches@linaro.org; Mon, 23 Sep 2013 19:18:01 -0400 (EDT) Received: from xanadu.home (xanadu.home [192.168.2.2]) by yoda.home (Postfix) with ESMTP id 20C452DA0667; Mon, 23 Sep 2013 19:18:01 -0400 (EDT) From: Nicolas Pitre To: linux-arm-kernel@lists.infradead.org Cc: dave.martin@arm.com, linaro-kernel@lists.linaro.org, patches@linaro.org Subject: [PATCH 02/13] ARM: bL_switcher: Add runtime control notifier Date: Mon, 23 Sep 2013 19:17:45 -0400 Message-id: <1379978276-31241-3-git-send-email-nicolas.pitre@linaro.org> X-Mailer: git-send-email 1.8.4.98.gb022869 In-reply-to: <1379978276-31241-1-git-send-email-nicolas.pitre@linaro.org> References: <1379978276-31241-1-git-send-email-nicolas.pitre@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: nicolas.pitre@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.128.170 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Content-transfer-encoding: 7BIT From: Dave Martin Some subsystems will need to respond synchronously to runtime enabling and disabling of the switcher. This patch adds a dedicated notifier interface to support such subsystems. Pre- and post- enable/disable notifications are sent to registered callbacks, allowing safe transition of non-b.L- transparent subsystems across these control transitions. Notifier callbacks may veto switcher (de)activation on pre notifications only. Post notifications won't revert the action. If enabling or disabling of the switcher fails after the pre-change notification has been sent, subsystems which have registered notifiers can be left in an inappropriate state. This patch sends a suitable post-change notification on failure, indicating that the old state has been reestablished. For example, a failed initialisation will result in the following sequence: BL_NOTIFY_PRE_ENABLE /* switcher initialisation fails */ BL_NOTIFY_POST_DISABLE It is the responsibility of notified subsystems to respond in an appropriate way. Signed-off-by: Dave Martin Signed-off-by: Nicolas Pitre --- arch/arm/common/bL_switcher.c | 60 +++++++++++++++++++++++++++++++------- arch/arm/include/asm/bL_switcher.h | 44 ++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 10 deletions(-) diff --git a/arch/arm/common/bL_switcher.c b/arch/arm/common/bL_switcher.c index 7d98629aa4..016488730c 100644 --- a/arch/arm/common/bL_switcher.c +++ b/arch/arm/common/bL_switcher.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -304,10 +305,34 @@ EXPORT_SYMBOL_GPL(bL_switch_request); */ static DEFINE_MUTEX(bL_switcher_activation_lock); +static BLOCKING_NOTIFIER_HEAD(bL_activation_notifier); static unsigned int bL_switcher_active; static unsigned int bL_switcher_cpu_original_cluster[NR_CPUS]; static cpumask_t bL_switcher_removed_logical_cpus; +int bL_switcher_register_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&bL_activation_notifier, nb); +} +EXPORT_SYMBOL_GPL(bL_switcher_register_notifier); + +int bL_switcher_unregister_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&bL_activation_notifier, nb); +} +EXPORT_SYMBOL_GPL(bL_switcher_unregister_notifier); + +static int bL_activation_notify(unsigned long val) +{ + int ret; + + ret = blocking_notifier_call_chain(&bL_activation_notifier, val, NULL); + if (ret & NOTIFY_STOP_MASK) + pr_err("%s: notifier chain failed with status 0x%x\n", + __func__, ret); + return notifier_to_errno(ret); +} + static void bL_switcher_restore_cpus(void) { int i; @@ -425,12 +450,13 @@ static int bL_switcher_enable(void) pr_info("big.LITTLE switcher initializing\n"); + ret = bL_activation_notify(BL_NOTIFY_PRE_ENABLE); + if (ret) + goto error; + ret = bL_switcher_halve_cpus(); - if (ret) { - cpu_hotplug_driver_unlock(); - mutex_unlock(&bL_switcher_activation_lock); - return ret; - } + if (ret) + goto error; for_each_online_cpu(cpu) { struct bL_thread *t = &bL_threads[cpu]; @@ -441,11 +467,18 @@ static int bL_switcher_enable(void) } bL_switcher_active = 1; + bL_activation_notify(BL_NOTIFY_POST_ENABLE); pr_info("big.LITTLE switcher initialized\n"); + goto out; + +error: + pr_warn("big.LITTLE switcher initialization failed\n"); + bL_activation_notify(BL_NOTIFY_POST_DISABLE); +out: cpu_hotplug_driver_unlock(); mutex_unlock(&bL_switcher_activation_lock); - return 0; + return ret; } #ifdef CONFIG_SYSFS @@ -458,11 +491,15 @@ static void bL_switcher_disable(void) mutex_lock(&bL_switcher_activation_lock); cpu_hotplug_driver_lock(); - if (!bL_switcher_active) { - cpu_hotplug_driver_unlock(); - mutex_unlock(&bL_switcher_activation_lock); - return; + + if (!bL_switcher_active) + goto out; + + if (bL_activation_notify(BL_NOTIFY_PRE_DISABLE) != 0) { + bL_activation_notify(BL_NOTIFY_POST_ENABLE); + goto out; } + bL_switcher_active = 0; /* @@ -504,6 +541,9 @@ static void bL_switcher_disable(void) } bL_switcher_restore_cpus(); + bL_activation_notify(BL_NOTIFY_POST_DISABLE); + +out: cpu_hotplug_driver_unlock(); mutex_unlock(&bL_switcher_activation_lock); } diff --git a/arch/arm/include/asm/bL_switcher.h b/arch/arm/include/asm/bL_switcher.h index 05d7c4cb94..b243ca93e8 100644 --- a/arch/arm/include/asm/bL_switcher.h +++ b/arch/arm/include/asm/bL_switcher.h @@ -12,9 +12,53 @@ #ifndef ASM_BL_SWITCHER_H #define ASM_BL_SWITCHER_H +#include +#include + int bL_switch_request(unsigned int cpu, unsigned int new_cluster_id); +/* + * Register here to be notified about runtime enabling/disabling of + * the switcher. + * + * The notifier chain is called with the switcher activation lock held: + * the switcher will not be enabled or disabled during callbacks. + * Callbacks must not call bL_switcher_{get,put}_enabled(). + */ +#define BL_NOTIFY_PRE_ENABLE 0 +#define BL_NOTIFY_POST_ENABLE 1 +#define BL_NOTIFY_PRE_DISABLE 2 +#define BL_NOTIFY_POST_DISABLE 3 + +#ifdef CONFIG_BL_SWITCHER + +int bL_switcher_register_notifier(struct notifier_block *nb); +int bL_switcher_unregister_notifier(struct notifier_block *nb); + +/* + * Use these functions to temporarily prevent enabling/disabling of + * the switcher. + * bL_switcher_get_enabled() returns true if the switcher is currently + * enabled. Each call to bL_switcher_get_enabled() must be followed + * by a call to bL_switcher_put_enabled(). These functions are not + * recursive. + */ bool bL_switcher_get_enabled(void); void bL_switcher_put_enabled(void); +#else +static inline int bL_switcher_register_notifier(struct notifier_block *nb) +{ + return 0; +} + +static inline int bL_switcher_unregister_notifier(struct notifier_block *nb) +{ + return 0; +} + +static inline bool bL_switcher_get_enabled(void) { return false; } +static inline void bL_switcher_put_enabled(void) { } +#endif /* CONFIG_BL_SWITCHER */ + #endif