From patchwork Mon Jul 14 14:33:31 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lee Jones X-Patchwork-Id: 369648 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 4CA0C140097 for ; Tue, 15 Jul 2014 00:34:55 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755914AbaGNOex (ORCPT ); Mon, 14 Jul 2014 10:34:53 -0400 Received: from mail-ie0-f170.google.com ([209.85.223.170]:52997 "EHLO mail-ie0-f170.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755867AbaGNOeK (ORCPT ); Mon, 14 Jul 2014 10:34:10 -0400 Received: by mail-ie0-f170.google.com with SMTP id rl12so2017794iec.1 for ; Mon, 14 Jul 2014 07:34:09 -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=4Qn2ebFUBVfsIQZtLiYL96ooRAVTrimAlie3H52VvcA=; b=VCpRnjI9ZG5p6AStF61f3vpcMa0AzLCo6o2cx0WZA5GBqZHZv1znsFBpNPRzpQowYm DBMt6MXMGfnd5KbPcfJspRCXF805eDN6po8zV+m5JwvkO+AtXKUgh9S7GhqN/2tdZoJh jq46cK+tXWLhY70n9TxliwTPv4gc+cknkYgi7CCMr8U8HMC+H/7CNo2VlMLX8u5wKjGS /StsrJoxganbYCxJExT/MA2qv9F9aP6dNm1BXFh8XprXGTeHvr0SNywR+YZrcEpp8B4K AbvtzMPCy1SLJyVggLX6jRYVe4QTGosrM5ISaXYjMWN6nsNKHRLRWDS1HfyY40aiYRAa YXXA== X-Gm-Message-State: ALoCoQnnJyH897CDh+ZCjZ/APDcIVL2v5YJiNJTQR7DNOd90ICkEIrl3HpUEDxD7MSW7GTFpHdqE X-Received: by 10.50.138.66 with SMTP id qo2mr12787805igb.12.1405348449804; Mon, 14 Jul 2014 07:34:09 -0700 (PDT) Received: from localhost.localdomain (host109-148-237-85.range109-148.btcentralplus.com. [109.148.237.85]) by mx.google.com with ESMTPSA id q11sm25317390igr.7.2014.07.14.07.34.07 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 14 Jul 2014 07:34:09 -0700 (PDT) From: Lee Jones To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: lee.jones@linaro.org, kernel@stlinux.com, thierry.reding@gmail.com, linux-pwm@vger.kernel.org, devicetree@vger.kernel.org, ajitpal.singh@st.com Subject: [PATCH v2 10/11] pwm: sti: Sync between enable/disable calls Date: Mon, 14 Jul 2014 15:33:31 +0100 Message-Id: <1405348412-7352-11-git-send-email-lee.jones@linaro.org> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1405348412-7352-1-git-send-email-lee.jones@linaro.org> References: <1405348412-7352-1-git-send-email-lee.jones@linaro.org> Sender: linux-pwm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pwm@vger.kernel.org From: Ajit Pal Singh ST PWM IP has a common enable/disable control for all the PWM channels on a PWM cell. Disables PWM output on the PWM HW only when disable is called for the last channel. Signed-off-by: Ajit Pal Singh Signed-off-by: Lee Jones --- drivers/pwm/pwm-sti.c | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/drivers/pwm/pwm-sti.c b/drivers/pwm/pwm-sti.c index 0fdf4b4..1aa901d 100644 --- a/drivers/pwm/pwm-sti.c +++ b/drivers/pwm/pwm-sti.c @@ -59,6 +59,8 @@ struct sti_pwm_chip { unsigned long *pwm_periods; struct pwm_chip chip; struct pwm_device *cur; + unsigned int en_count; + struct mutex sti_pwm_lock; /* To sync between enable/disable calls */ void __iomem *mmio; }; @@ -236,32 +238,44 @@ static int sti_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) { struct sti_pwm_chip *pc = to_sti_pwmchip(chip); struct device *dev = pc->dev; - int ret; - - ret = clk_enable(pc->clk); - if (ret) - return ret; + int ret = 0; - ret = regmap_field_write(pc->pwm_en, 1); - if (ret) - dev_err(dev, "%s,pwm_en write failed\n", __func__); + /* + * Since we have a common enable for all PWM channels, + * do not enable if already enabled. + */ + mutex_lock(&pc->sti_pwm_lock); + if (!pc->en_count) { + ret = clk_enable(pc->clk); + if (ret) + goto out; + ret = regmap_field_write(pc->pwm_en, 1); + if (ret) { + dev_err(dev, "failed to enable PWM device:%d\n", + pwm->hwpwm); + goto out; + } + } + pc->en_count++; +out: + mutex_unlock(&pc->sti_pwm_lock); return ret; } static void sti_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) { struct sti_pwm_chip *pc = to_sti_pwmchip(chip); - struct device *dev = pc->dev; - unsigned int val; + mutex_lock(&pc->sti_pwm_lock); + if (--pc->en_count) { + mutex_unlock(&pc->sti_pwm_lock); + return; + } regmap_field_write(pc->pwm_en, 0); - regmap_read(pc->regmap, STI_CNT, &val); - - dev_dbg(dev, "pwm counter :%u\n", val); - clk_disable(pc->clk); + mutex_unlock(&pc->sti_pwm_lock); } static const struct pwm_ops sti_pwm_ops = { @@ -352,6 +366,8 @@ static int sti_pwm_probe(struct platform_device *pdev) pc->cdata = cdata; pc->dev = dev; + pc->en_count = 0; + mutex_init(&pc->sti_pwm_lock); ret = sti_pwm_probe_dt(pc); if (ret)