From patchwork Mon Mar 23 16:50:24 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 6074431 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 23D1D9F2A9 for ; Mon, 23 Mar 2015 16:52:44 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 50CBB2024C for ; Mon, 23 Mar 2015 16:52:43 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 72AB7201FA for ; Mon, 23 Mar 2015 16:52:42 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Ya5Yz-0007Dj-JZ; Mon, 23 Mar 2015 16:50:53 +0000 Received: from mail-wg0-f42.google.com ([74.125.82.42]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Ya5Yv-00079Z-8f for linux-arm-kernel@lists.infradead.org; Mon, 23 Mar 2015 16:50:49 +0000 Received: by wgs2 with SMTP id 2so43901748wgs.1 for ; Mon, 23 Mar 2015 09:50:27 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=TqNKciWAkS/+lrOmfWHbBSCL2FuyZ/WkQxQg5tCRZBg=; b=bgMzsILylLo+9PG3JmNh/+fGrxwUj6UdEJx7/Scd9Nw7Y9nMeNDykilj0Pvx712VSb WQU2E5mCNsASovq6MedpgeWlDY6TpMjIh7fbcFqV+wXOn19QCvklI3H3MytDW2EaDTN5 rsiCcOwJiyBiWczuPi9s05DvPvVq/zsrDMp5ueco/2zAA8mJMbM10dsfmqXTsUH+rKIf R4rhkT0wtU0tuJmC9C27RnPrqxSZc1gCWkK61aauSHUHU9aRgrIIwg0b+eJwt+Ph2fIP Eb8kMWzFANjpwVgt1WnhqanS9mrIeWvyt9hRgRorJ2U3+EtItza0Svms/h0VBTHK02ft ozGQ== X-Gm-Message-State: ALoCoQm/OGb6UytzOpRjUS6BDYlhwSQZbvaYtJpPKXswZ78McDw/hIW1oq0nS3fXR6fsaL5p2Xr2 X-Received: by 10.194.77.230 with SMTP id v6mr190306195wjw.25.1427129427167; Mon, 23 Mar 2015 09:50:27 -0700 (PDT) Received: from mai.lan (135-224-190-109.dsl.ovh.fr. [109.190.224.135]) by mx.google.com with ESMTPSA id fo8sm11920180wib.14.2015.03.23.09.50.25 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 23 Mar 2015 09:50:26 -0700 (PDT) From: Daniel Lezcano To: lorenzo.pieralisi@arm.com Subject: [PATCH V4] ARM: cpuidle: Register per cpuidle device Date: Mon, 23 Mar 2015 17:50:24 +0100 Message-Id: <1427129424-17175-1-git-send-email-daniel.lezcano@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <20150323162514.GE18904@red-moon> References: <20150323162514.GE18904@red-moon> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150323_095049_457870_1D67B6EA X-CRM114-Status: GOOD ( 17.15 ) X-Spam-Score: -0.7 (/) Cc: devicetree@vger.kernel.org, arnd@arndb.de, linux-pm@vger.kernel.org, Catalin.Marinas@arm.com, rjw@rjwysocki.net, linux-kernel@vger.kernel.org, lina.iyer@linaro.org, sboyd@codeaurora.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On some platforms, the low level PM code may not be initialized correctly for a specific cpu. In this case, the EXNIO tells the cpuidle driver to not initialize the cpuidle device as the associated low level PM is not operational. That prevents the system to crash and allows to handle the error gracefully. For example, on Qcom's platform, each core has a SPM. The device associated with this SPM is initialized before the cpuidle framework. If there is an error in the initialization (eg. error in the DT), the system continues to boot but in degraded mode as some SPM may not be correctly initialized. Signed-off-by: Daniel Lezcano Acked-by: Lorenzo Pieralisi --- drivers/cpuidle/cpuidle-arm.c | 46 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c index 1c94b88..a7a01ce 100644 --- a/drivers/cpuidle/cpuidle-arm.c +++ b/drivers/cpuidle/cpuidle-arm.c @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -94,6 +95,7 @@ static int __init arm_idle_init(void) { int cpu, ret; struct cpuidle_driver *drv = &arm_idle_driver; + struct cpuidle_device *dev; /* * Initialize idle states data, starting at index 1. @@ -105,18 +107,58 @@ static int __init arm_idle_init(void) if (ret <= 0) return ret ? : -ENODEV; + ret = cpuidle_register_driver(drv); + if (ret) { + pr_err("Failed to register cpuidle driver\n"); + return ret; + } + /* * Call arch CPU operations in order to initialize * idle states suspend back-end specific data */ for_each_possible_cpu(cpu) { ret = arm_cpuidle_init(cpu); + + /* + * Do not register the cpuidle device. This situation could + * happen when the low level PM was not able to initialize + * for any reaon. + */ + if (ret == -ENXIO) + continue; + if (ret) { pr_err("CPU %d failed to init idle CPU ops\n", cpu); - return ret; + goto out_fail; + } + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) { + pr_err("Failed to allocate cpuidle device\n"); + goto out_fail; + } + dev->cpu = cpu; + + ret = cpuidle_register_device(dev); + if (ret) { + pr_err("Failed to register cpuidle device for CPU %d\n", + cpu); + kfree(dev); + goto out_fail; } } - return cpuidle_register(drv, NULL); + return 0; +out_fail: + while (--cpu >= 0) { + dev = per_cpu(cpuidle_devices, cpu); + cpuidle_unregister_device(dev); + kfree(dev); + } + + cpuidle_unregister_driver(drv); + + return ret; } device_initcall(arm_idle_init);