From patchwork Fri May 31 10:13:07 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Hebbar, Gururaja" X-Patchwork-Id: 2641951 Return-Path: X-Original-To: patchwork-davinci@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from bear.ext.ti.com (bear.ext.ti.com [192.94.94.41]) by patchwork2.kernel.org (Postfix) with ESMTP id E694ADFB79 for ; Fri, 31 May 2013 10:14:34 +0000 (UTC) Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id r4VAD88P024104; Fri, 31 May 2013 05:13:08 -0500 Received: from DFLE72.ent.ti.com (dfle72.ent.ti.com [128.247.5.109]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id r4VAD786007843; Fri, 31 May 2013 05:13:08 -0500 Received: from dlelxv23.itg.ti.com (172.17.1.198) by DFLE72.ent.ti.com (128.247.5.109) with Microsoft SMTP Server id 14.2.342.3; Fri, 31 May 2013 05:13:07 -0500 Received: from linux.omap.com (dlelxs01.itg.ti.com [157.170.227.31]) by dlelxv23.itg.ti.com (8.13.8/8.13.8) with ESMTP id r4VAD7DW008532; Fri, 31 May 2013 05:13:07 -0500 Received: from linux.omap.com (localhost [127.0.0.1]) by linux.omap.com (Postfix) with ESMTP id E0B888062B; Fri, 31 May 2013 05:13:07 -0500 (CDT) X-Original-To: davinci-linux-open-source@linux.davincidsp.com Delivered-To: davinci-linux-open-source@linux.davincidsp.com Received: from dlelxv90.itg.ti.com (dlelxv90.itg.ti.com [172.17.2.17]) by linux.omap.com (Postfix) with ESMTP id 686CF8062F for ; Fri, 31 May 2013 05:11:20 -0500 (CDT) Received: from DFLE72.ent.ti.com (dfle72.ent.ti.com [128.247.5.109]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id r4VABK6T003564; Fri, 31 May 2013 05:11:20 -0500 Received: from dlelxv23.itg.ti.com (172.17.1.198) by DFLE72.ent.ti.com (128.247.5.109) with Microsoft SMTP Server id 14.2.342.3; Fri, 31 May 2013 05:11:19 -0500 Received: from ucmsshproxy.india.ext.ti.com (dbdp20.itg.ti.com [172.24.170.38]) by dlelxv23.itg.ti.com (8.13.8/8.13.8) with SMTP id r4VABF34005875; Fri, 31 May 2013 05:11:16 -0500 Received: from symphony.india.ext.ti.com (unknown [192.168.247.13]) by ucmsshproxy.india.ext.ti.com (Postfix) with ESMTP id 3A268158009; Fri, 31 May 2013 15:41:14 +0530 (IST) Received: from ubuntu-psp-linux.india.ext.ti.com (ubuntu-psp-linux [192.168.247.46]) by symphony.india.ext.ti.com (8.11.7p1+Sun/8.11.7) with ESMTP id r4VABDR05850; Fri, 31 May 2013 15:41:13 +0530 (IST) From: Hebbar Gururaja To: , , , Subject: [PATCH 07/11] pwm: pwm-tiehrpwm: enhance pinctrl support Date: Fri, 31 May 2013 15:43:07 +0530 Message-ID: <1369995191-20855-8-git-send-email-gururaja.hebbar@ti.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1369995191-20855-1-git-send-email-gururaja.hebbar@ti.com> References: <1369995191-20855-1-git-send-email-gururaja.hebbar@ti.com> MIME-Version: 1.0 CC: , , , Thierry Reding , , "Philip, Avinash" , X-BeenThere: davinci-linux-open-source@linux.davincidsp.com X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: Errors-To: davinci-linux-open-source-bounces@linux.davincidsp.com Amend the ti ehrpwm controller to optionally take a pin control handle and set the state of the pins to: - "default" on boot, resume - "sleep" on suspend() By optionally putting the pins into sleep state in the suspend callback we can accomplish two things. - One is to minimize current leakage from pins and thus save power, - second, we can prevent the IP from driving pins output in an uncontrolled manner, which may happen if the power domain drops the domain regulator. If any of the above pin states are missing in dt, a warning message about the missing state is displayed. If certain pin-states are not available, to remove this warning message pass respective state name with null phandler. Todo: - if an idle state is available for pins, add support for it. Signed-off-by: Hebbar Gururaja Cc: Thierry Reding Cc: Philip, Avinash --- :100644 100644 48a485c... ed55460ae. M drivers/pwm/pwm-tiehrpwm.c drivers/pwm/pwm-tiehrpwm.c | 49 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c index 48a485c..ed55460ae 100644 --- a/drivers/pwm/pwm-tiehrpwm.c +++ b/drivers/pwm/pwm-tiehrpwm.c @@ -132,6 +132,11 @@ struct ehrpwm_pwm_chip { enum pwm_polarity polarity[NUM_PWM_CHANNEL]; struct clk *tbclk; struct ehrpwm_context ctx; + + /* two pin states - default, sleep */ + struct pinctrl *pinctrl; + struct pinctrl_state *pins_default; + struct pinctrl_state *pins_sleep; }; static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip) @@ -439,11 +444,6 @@ static int ehrpwm_pwm_probe(struct platform_device *pdev) struct clk *clk; struct ehrpwm_pwm_chip *pc; u16 status; - struct pinctrl *pinctrl; - - pinctrl = devm_pinctrl_get_select_default(&pdev->dev); - if (IS_ERR(pinctrl)) - dev_warn(&pdev->dev, "unable to select pin group\n"); pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); if (!pc) { @@ -451,6 +451,34 @@ static int ehrpwm_pwm_probe(struct platform_device *pdev) return -ENOMEM; } + pc->pinctrl = devm_pinctrl_get(&pdev->dev); + if (!IS_ERR(pc->pinctrl)) { + pc->pins_default = pinctrl_lookup_state(pc->pinctrl, + PINCTRL_STATE_DEFAULT); + if (IS_ERR(pc->pins_default)) + dev_dbg(&pdev->dev, "could not get default pinstate\n"); + else + if (pinctrl_select_state(pc->pinctrl, pc->pins_default)) + dev_err(&pdev->dev, + "could not set default pinstate\n"); + + pc->pins_sleep = pinctrl_lookup_state(pc->pinctrl, + PINCTRL_STATE_SLEEP); + if (IS_ERR(pc->pins_sleep)) + dev_dbg(&pdev->dev, "could not get sleep pinstate\n"); + } else { + /* + * Since we continue even when pinctrl node is not found, + * Invalidate pins as not available. This is to make sure that + * IS_ERR(pins_xxx) results in failure when used. + */ + pc->pins_default = ERR_PTR(-ENODATA); + pc->pins_sleep = ERR_PTR(-ENODATA); + + dev_dbg(&pdev->dev, "did not get pins for i2c error: %li\n", + PTR_ERR(pc->pinctrl)); + } + clk = devm_clk_get(&pdev->dev, "fck"); if (IS_ERR(clk)) { dev_err(&pdev->dev, "failed to get clock\n"); @@ -570,6 +598,12 @@ static int ehrpwm_pwm_suspend(struct device *dev) /* Disable explicitly if PWM is running */ pm_runtime_put_sync(dev); } + + /* Optionally let pins go into sleep states */ + if (!IS_ERR(pc->pins_sleep)) + if (pinctrl_select_state(pc->pinctrl, pc->pins_sleep)) + dev_err(dev, "could not set pins to sleep state\n"); + return 0; } @@ -578,6 +612,11 @@ static int ehrpwm_pwm_resume(struct device *dev) struct ehrpwm_pwm_chip *pc = dev_get_drvdata(dev); int i; + /* Optionaly enable pins to be muxed in and configured */ + if (!IS_ERR(pc->pins_default)) + if (pinctrl_select_state(pc->pinctrl, pc->pins_default)) + dev_err(dev, "could not set default pins\n"); + for (i = 0; i < pc->chip.npwm; i++) { struct pwm_device *pwm = &pc->chip.pwms[i];