From patchwork Tue Sep 23 23:17:26 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 392696 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 2B1F8140081 for ; Wed, 24 Sep 2014 09:17:36 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756095AbaIWXRf (ORCPT ); Tue, 23 Sep 2014 19:17:35 -0400 Received: from mail-pd0-f173.google.com ([209.85.192.173]:55692 "EHLO mail-pd0-f173.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755339AbaIWXRe (ORCPT ); Tue, 23 Sep 2014 19:17:34 -0400 Received: by mail-pd0-f173.google.com with SMTP id y10so7369888pdj.18 for ; Tue, 23 Sep 2014 16:17:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id; bh=tVnEYfBw3U1fATol4fiKDubIrW40mWIC6Eci0g2pOXI=; b=NinwDmf+nOdKlZyl1cL0tf19WtRQy258WXJ/FmFCKNpo3wUx3NZlJMr2iqBNbgwBmW FPJqs66Yvqr35W8rzYYX0JbbXlplsyxnXJ+Bnqqw4Jfmftx6/dwOcryWcTF2CDATakqU 4rI37CtryEdGHEDv7/ME/Sn3UwtUiZGUmCH6o= 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; bh=tVnEYfBw3U1fATol4fiKDubIrW40mWIC6Eci0g2pOXI=; b=QZxw1JV0VwBDCHBK/0Mh4wGop/qXDV2R5+astUpvQbGJRJYCJj8QWyrhBui4HODO0Q ej4ECAkj3MHfeWTcwyGahGRGtQRMPLNT5NI62nqCF5K1zl45LHtLoi1CDfnnOfcOd/XJ 4moRLRvOzrip5SNsN+pwLj//qX4Lakt3POShiFgt9fgb+jnjV2/kcKOK9md4c+FG02st 79Flgd37V6sUDhqv3FOhAOAerh+UAHI4WfsVbCOBV1thc4n8gpjZICmNdj8tnB81prh9 FEw4N/OvjWEzgmQsRtMhH/ddgEZKLPQ91jWvijJYXCWSbM78XtKt7HPqvfg4Sq2Sonl1 8yhQ== X-Gm-Message-State: ALoCoQkwgR0y1WR2Q0pmuMpNT0HErjR/dHnEFWFERbsjR+iniryLWBxVD9jDEBQPYV40lY3bVqQx X-Received: by 10.66.66.101 with SMTP id e5mr3929034pat.100.1411514253666; Tue, 23 Sep 2014 16:17:33 -0700 (PDT) Received: from tictac.mtv.corp.google.com (tictac.mtv.corp.google.com [172.22.162.15]) by mx.google.com with ESMTPSA id dw2sm13129178pab.8.2014.09.23.16.17.32 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 23 Sep 2014 16:17:32 -0700 (PDT) From: Doug Anderson To: thierry.reding@gmail.com, Linus Walleij , Mark Brown , Lee Jones Cc: Chris Zhong , Heiko Stuebner , Sonny Rao , Doug Anderson , linux-pwm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH] pwm: Add the concept of an "active" pinctrl Date: Tue, 23 Sep 2014 16:17:26 -0700 Message-Id: <1411514246-6163-1-git-send-email-dianders@chromium.org> X-Mailer: git-send-email 2.1.0.rc2.206.gedb03e5 Sender: linux-pwm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pwm@vger.kernel.org There are cases where you really don't want a PWM's pinctrl to take effect until you know that the PWM is driving at the proper rate. A good example of this is a PWM-controlled regulator, where the boot state of the pin (maybe a pulled down input) could cause a vastly different voltage to take effect than having the pin setup as a PWM but not having the PWM enabled yet. Let's add a feature where you can define an "active" pinctrl state. This state (if it exists) will be applied after the PWM has actually been enabled. If the PWM is ever disabled we'll go back to "default" state. Signed-off-by: Doug Anderson --- I'm sure Linus W or Thierry or Mark will tell me this is an idiotic idea (or totally the wrong way to do it), but I figured I'd float it out there and maybe someone can tell me something better to do. ;) drivers/pwm/core.c | 34 +++++++++++++++++++++++++++++++--- include/linux/pwm.h | 8 ++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 966497d..12f86e0 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -245,6 +245,14 @@ int pwmchip_add(struct pwm_chip *chip) if (ret < 0) goto out; + chip->pinctrl = devm_pinctrl_get(chip->dev); + if (!IS_ERR_OR_NULL(chip->pinctrl)) { + chip->state_default = pinctrl_lookup_state(chip->pinctrl, + "default"); + chip->state_active = pinctrl_lookup_state(chip->pinctrl, + "active"); + } + chip->pwms = kzalloc(chip->npwm * sizeof(*pwm), GFP_KERNEL); if (!chip->pwms) { ret = -ENOMEM; @@ -457,8 +465,17 @@ EXPORT_SYMBOL_GPL(pwm_set_polarity); */ int pwm_enable(struct pwm_device *pwm) { - if (pwm && !test_and_set_bit(PWMF_ENABLED, &pwm->flags)) - return pwm->chip->ops->enable(pwm->chip, pwm); + int ret; + + if (pwm && !test_and_set_bit(PWMF_ENABLED, &pwm->flags)) { + ret = pwm->chip->ops->enable(pwm->chip, pwm); + + if (!ret && !IS_ERR_OR_NULL(pwm->chip->state_active)) + ret = pinctrl_select_state(pwm->chip->pinctrl, + pwm->chip->state_active); + + return ret; + } return pwm ? 0 : -EINVAL; } @@ -470,8 +487,19 @@ EXPORT_SYMBOL_GPL(pwm_enable); */ void pwm_disable(struct pwm_device *pwm) { - if (pwm && test_and_clear_bit(PWMF_ENABLED, &pwm->flags)) + int ret; + + if (pwm && test_and_clear_bit(PWMF_ENABLED, &pwm->flags)) { + if (!IS_ERR_OR_NULL(pwm->chip->state_default)) { + ret = pinctrl_select_state(pwm->chip->pinctrl, + pwm->chip->state_default); + if (ret) + dev_warn(pwm->chip->dev, + "Couldn't set def state: %d\n", ret); + } + pwm->chip->ops->disable(pwm->chip, pwm); + } } EXPORT_SYMBOL_GPL(pwm_disable); diff --git a/include/linux/pwm.h b/include/linux/pwm.h index e90628c..039c898 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h @@ -162,6 +162,10 @@ struct pwm_ops { * @pwms: array of PWM devices allocated by the framework * @can_sleep: must be true if the .config(), .enable() or .disable() * operations may sleep + * + * @pinctrl: Pointer to the a pinctrl for the dev + * @state_default: We'll apply this when a PWM is disabled + * @state_active: We'll apply this when a PWM is enabled */ struct pwm_chip { struct device *dev; @@ -176,6 +180,10 @@ struct pwm_chip { const struct of_phandle_args *args); unsigned int of_pwm_n_cells; bool can_sleep; + + struct pinctrl *pinctrl; + struct pinctrl_state *state_default; + struct pinctrl_state *state_active; }; #if IS_ENABLED(CONFIG_PWM)