From patchwork Tue Jun 11 19:59:09 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 2705581 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.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id CCD999F3DD for ; Tue, 11 Jun 2013 20:00:05 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8D92220231 for ; Tue, 11 Jun 2013 20:00:04 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1F2EA20225 for ; Tue, 11 Jun 2013 20:00:03 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UmUjS-000540-2z; Tue, 11 Jun 2013 19:59:54 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UmUjP-0004hD-9d; Tue, 11 Jun 2013 19:59:51 +0000 Received: from eu1sys200aog113.obsmtp.com ([207.126.144.135]) by merlin.infradead.org with smtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UmUjL-0004gW-Df for linux-arm-kernel@lists.infradead.org; Tue, 11 Jun 2013 19:59:48 +0000 Received: from beta.dmz-eu.st.com ([164.129.1.35]) (using TLSv1) by eu1sys200aob113.postini.com ([207.126.147.11]) with SMTP ID DSNKUbeBlsf00KHsoGBNPCkLAqnADAI+L+ER@postini.com; Tue, 11 Jun 2013 19:59:47 UTC Received: from zeta.dmz-eu.st.com (zeta.dmz-eu.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 650EE168; Tue, 11 Jun 2013 19:59:16 +0000 (GMT) Received: from relay1.stm.gmessaging.net (unknown [10.230.100.17]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 4D32559C2; Tue, 11 Jun 2013 19:58:56 +0000 (GMT) Received: from exdcvycastm022.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm022", Issuer "exdcvycastm022" (not verified)) by relay1.stm.gmessaging.net (Postfix) with ESMTPS id 5AEFC24C07C; Tue, 11 Jun 2013 21:59:05 +0200 (CEST) Received: from steludxu4075.lud.stericsson.com (10.230.100.153) by smtp.stericsson.com (10.230.100.30) with Microsoft SMTP Server (TLS) id 8.3.279.5; Tue, 11 Jun 2013 21:59:15 +0200 From: Linus Walleij To: Stephen Warren , Kevin Hilman , Tony Lindgren Subject: [PATCH] pinctrl: document the pinctrl PM states Date: Tue, 11 Jun 2013 21:59:09 +0200 Message-ID: <1370980749-15383-1-git-send-email-linus.walleij@stericsson.com> X-Mailer: git-send-email 1.7.11.3 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130611_155947_781909_EEE2834B X-CRM114-Status: GOOD ( 19.08 ) X-Spam-Score: -4.2 (----) Cc: Ulf Hansson , Linus Walleij , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , 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.4 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, 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 From: Linus Walleij This document snippet tries to be helpful and define the pin PM states and helpers, and how they should be used to create some kind of common ontology around this. Cc: Ulf Hansson Cc: Kevin Hilman Cc: Tony Lindgren Signed-off-by: Linus Walleij Acked-by: Tony Lindgren --- Documentation/pinctrl.txt | 118 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index f6e664b..a34ea92 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -1196,6 +1196,124 @@ registered. Thus make sure that the error path in your driver gracefully cleans up and is ready to retry the probing later in the startup process. +Default and power management related states +=========================================== + +As mentioned earlier the device core will automatically try to obtain a +pinctrl handle and activate the "default" state on all drivers. + +However, for power management and power saving, it is sometimes necessary +to switch pin states at runtime. Electrically speaking this involves +for example reconfigure some pins to be grounded or pulled-down when the +system as a whole goes to sleep, or a pull-up could be turned off when pins +are idle, reducing leak current. + +To help out with this, if CONFIG_PM is selected in the Kconfig, three +additional states will also be obtained by the driver core and cached +there: + +"active" this is indended as an explicit active state, if the "default" + state is not synonymous with the active one. + +"idle" this is a state that is relaxing the pins when the system as a + whole is up and running, but these particular pins are unused. + +"sleep" this is a state that is used when the whole system goes to + suspend, becomes uninteractive, unresponsive to anything but + specific wake-up events. + +These correspond to the definitions found in +where the same strings are encoded. + +When CONFIG_PM is set, the following functions will simultaneously be made +available to switch between these power-related states: + +#include + +int pinctrl_pm_select_default_state(struct device *dev); +int pinctrl_pm_select_active_state(struct device *dev); +int pinctrl_pm_select_sleep_state(struct device *dev); +int pinctrl_pm_select_idle_state(struct device *dev); + +As the corresponding pinctrl handle and states are cached in the driver +core, nothing apart from these calls is needed to move the pins between +these states. + +For a typical runtime PM enabled (see Documentation/power/runtime_pm.txt) +driver the following outline could be followed: + +probe(): + pinctrl_pm_select_default_state() + +runtime_suspend(): + pinctrl_pm_select_idle_state() + +runtime_resume(): + pinctrl_pm_select_default_state() + +suspend: + pinctrl_pm_select_sleep_state() + +resume: + pinctrl_pm_select_idle_state() + +Some of the state selectors could be skipped if the driver is for a +certain system where e.g. the "active" state is not defined, instead +relying on the "default" state to make the pins active at all times. +For a driver only supporting suspend and resume, the "idle" state also +loose its meaning. + +A state-chart diagram would look like this: + + +---------+ +----------+ + probe() -> | default | -> runtime_suspend() -> | idle | + | | <- runtime_resume() <- | | + +---------+ +----------+ + | ^ + | | + suspend() resume() + | | + V | + +---------+ + | sleep | + +---------+ + +This reflects the runtime PM concept that we are always runtime +suspended when we go to suspend. + +A more complex example is a driver written for many different +hardware configurations, some which have only the default state, +some which have the default state and the sleep state, some that +have no idle state but indeed a default state and so on. Since +all states are basically optional (the core will not complain if +they are not found) we can write our state transitions like +this: + +probe(): + pinctrl_pm_select_default_state() + +runtime_suspend(): + pinctrl_pm_select_idle_state() + +runtime_resume(): + pinctrl_pm_select_default_state() + pinctrl_pm_select_active_state() + +suspend: + pinctrl_pm_select_sleep_state() + +resume: + pinctrl_pm_select_default_state() + pinctrl_pm_select_idle_state() + +Here runtime_resume() and resume() passes through the "default" +state to the "active" and "idle" states respectively since everything +but "default" is optional. For example it is OK to only supply the +"default" and "sleep" state pair with this code, and it will +transition the pins from "default" to "sleep" and leaving the rest +as no-ops. + + Drivers needing both pin control and GPIOs ==========================================