From patchwork Mon Sep 18 10:05:32 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabrice Gasnier X-Patchwork-Id: 9956247 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 66999601E9 for ; Mon, 18 Sep 2017 10:06:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5592D22B39 for ; Mon, 18 Sep 2017 10:06:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4A09A28C59; Mon, 18 Sep 2017 10:06:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 64F4E22B39 for ; Mon, 18 Sep 2017 10:06:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=d2mLgaT3ET2V7htQAM0kONASwNelZTqwTpUkPoQdgBM=; b=V93QC2fxAV0EQi wkpRUThPqpWsMWVz1zlARExIpMyqDe3SgSOJkGo5qM+BpxbzNfJAwvoIUflAGNCtVWNLxX1upDxbr WqTfVcWbSdRGleK5p5M7lxOv0s7+aWdXdbuZ3XyxmjLpeIzo3DlU4Zf6gM2cqh0iroryZX7lAZdlp NJ7i4ystdl8+71H9+j8Gqg4WXTVIPpeuxbZBgRlJMO4Mw8Dno2hJvImL+5s9Rr7wfAFHXcD4D+6BM cGiEJ3g2bKiPFTOqFr1VnJAn586LrcqicI/n8LLsKAcfSqfoEk7YBzsaoSaCcDDhDxyHiCspuKOC6 WLFQB6uY6P7wQFa0yNMQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dtswk-0003Kd-9h; Mon, 18 Sep 2017 10:06:34 +0000 Received: from mx07-00178001.pphosted.com ([62.209.51.94]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dtswf-0003Es-2C for linux-arm-kernel@lists.infradead.org; Mon, 18 Sep 2017 10:06:31 +0000 Received: from pps.filterd (m0046668.ppops.net [127.0.0.1]) by mx07-.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id v8IA4AnA000865; Mon, 18 Sep 2017 12:06:04 +0200 Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com with ESMTP id 2d20x02qev-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT); Mon, 18 Sep 2017 12:06:04 +0200 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 694A431; Mon, 18 Sep 2017 10:06:03 +0000 (GMT) Received: from Webmail-eu.st.com (sfhdag5node3.st.com [10.75.127.15]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 38C7516B7; Mon, 18 Sep 2017 10:06:03 +0000 (GMT) Received: from localhost (10.75.127.45) by SFHDAG5NODE3.st.com (10.75.127.15) with Microsoft SMTP Server (TLS) id 15.0.1178.4; Mon, 18 Sep 2017 12:06:02 +0200 From: Fabrice Gasnier To: Subject: [PATCH 3/3] iio: trigger: stm32-timer: enable clock when in master mode Date: Mon, 18 Sep 2017 12:05:32 +0200 Message-ID: <1505729132-1369-4-git-send-email-fabrice.gasnier@st.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1505729132-1369-1-git-send-email-fabrice.gasnier@st.com> References: <1505729132-1369-1-git-send-email-fabrice.gasnier@st.com> MIME-Version: 1.0 X-Originating-IP: [10.75.127.45] X-ClientProxiedBy: SFHDAG1NODE3.st.com (10.75.127.3) To SFHDAG5NODE3.st.com (10.75.127.15) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-09-18_02:, , signatures=0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170918_030629_465485_C612FCDF X-CRM114-Status: GOOD ( 15.87 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: benjamin.gaignard@linaro.org, lars@metafoo.de, benjamin.gaignard@st.com, linux-iio@vger.kernel.org, pmeerw@pmeerw.net, linux-kernel@vger.kernel.org, mcoquelin.stm32@gmail.com, knaack.h@gmx.de, fabrice.gasnier@st.com, linux-arm-kernel@lists.infradead.org, alexandre.torgue@st.com Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Clock should be enabled as soon as using master mode, even before enabling timer. Or, this may provoke bad behavior on the other end (slave timer). Then, introduce 'clk_enabled' flag, instead of relying on CR1 EN bit, to keep track of clock being enabled. Propagate this anywhere else in the driver. Also add 'remove' routine to stop timer and disable clock in case it has been left enabled. Signed-off-by: Fabrice Gasnier --- drivers/iio/trigger/stm32-timer-trigger.c | 60 +++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/drivers/iio/trigger/stm32-timer-trigger.c b/drivers/iio/trigger/stm32-timer-trigger.c index eb212f8c..5a6509c 100644 --- a/drivers/iio/trigger/stm32-timer-trigger.c +++ b/drivers/iio/trigger/stm32-timer-trigger.c @@ -79,6 +79,7 @@ struct stm32_timer_trigger { struct device *dev; struct regmap *regmap; struct clk *clk; + bool clk_enabled; u32 max_arr; const void *triggers; const void *valids; @@ -106,7 +107,7 @@ static int stm32_timer_start(struct stm32_timer_trigger *priv, { unsigned long long prd, div; int prescaler = 0; - u32 ccer, cr1; + u32 ccer; /* Period and prescaler values depends of clock rate */ div = (unsigned long long)clk_get_rate(priv->clk); @@ -136,9 +137,10 @@ static int stm32_timer_start(struct stm32_timer_trigger *priv, if (ccer & TIM_CCER_CCXE) return -EBUSY; - regmap_read(priv->regmap, TIM_CR1, &cr1); - if (!(cr1 & TIM_CR1_CEN)) + if (!priv->clk_enabled) { + priv->clk_enabled = true; clk_enable(priv->clk); + } regmap_write(priv->regmap, TIM_PSC, prescaler); regmap_write(priv->regmap, TIM_ARR, prd - 1); @@ -163,16 +165,12 @@ static int stm32_timer_start(struct stm32_timer_trigger *priv, static void stm32_timer_stop(struct stm32_timer_trigger *priv) { - u32 ccer, cr1; + u32 ccer; regmap_read(priv->regmap, TIM_CCER, &ccer); if (ccer & TIM_CCER_CCXE) return; - regmap_read(priv->regmap, TIM_CR1, &cr1); - if (cr1 & TIM_CR1_CEN) - clk_disable(priv->clk); - /* Stop timer */ regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0); regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0); @@ -181,6 +179,11 @@ static void stm32_timer_stop(struct stm32_timer_trigger *priv) /* Make sure that registers are updated */ regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG); + + if (priv->clk_enabled) { + priv->clk_enabled = false; + clk_disable(priv->clk); + } } static ssize_t stm32_tt_store_frequency(struct device *dev, @@ -295,6 +298,11 @@ static ssize_t stm32_tt_store_master_mode(struct device *dev, for (i = 0; i <= master_mode_max; i++) { if (!strncmp(master_mode_table[i], buf, strlen(master_mode_table[i]))) { + if (!priv->clk_enabled) { + /* Clock should be enabled first */ + priv->clk_enabled = true; + clk_enable(priv->clk); + } regmap_update_bits(priv->regmap, TIM_CR2, mask, i << shift); /* Make sure that registers are updated */ @@ -438,7 +446,6 @@ static int stm32_counter_write_raw(struct iio_dev *indio_dev, int val, int val2, long mask) { struct stm32_timer_trigger *priv = iio_priv(indio_dev); - u32 dat; switch (mask) { case IIO_CHAN_INFO_RAW: @@ -450,17 +457,19 @@ static int stm32_counter_write_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_ENABLE: if (val) { - regmap_read(priv->regmap, TIM_CR1, &dat); - if (!(dat & TIM_CR1_CEN)) + if (!priv->clk_enabled) { + priv->clk_enabled = true; clk_enable(priv->clk); + } regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, TIM_CR1_CEN); } else { - regmap_read(priv->regmap, TIM_CR1, &dat); regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0); - if (dat & TIM_CR1_CEN) + if (priv->clk_enabled) { + priv->clk_enabled = false; clk_disable(priv->clk); + } } return 0; } @@ -558,7 +567,6 @@ static int stm32_set_enable_mode(struct iio_dev *indio_dev, { struct stm32_timer_trigger *priv = iio_priv(indio_dev); int sms = stm32_enable_mode2sms(mode); - u32 val; if (sms < 0) return sms; @@ -566,10 +574,9 @@ static int stm32_set_enable_mode(struct iio_dev *indio_dev, * Triggered mode sets CEN bit automatically by hardware. So, first * enable counter clock, so it can use it. Keeps it in sync with CEN. */ - if (sms == 6) { - regmap_read(priv->regmap, TIM_CR1, &val); - if (!(val & TIM_CR1_CEN)) - clk_enable(priv->clk); + if (sms == 6 && !priv->clk_enabled) { + clk_enable(priv->clk); + priv->clk_enabled = true; } regmap_update_bits(priv->regmap, TIM_SMCR, TIM_SMCR_SMS, sms); @@ -848,6 +855,22 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev) return 0; } +static int stm32_timer_trigger_remove(struct platform_device *pdev) +{ + struct stm32_timer_trigger *priv = platform_get_drvdata(pdev); + u32 val; + + /* Check if nobody else use the timer, then disable it */ + regmap_read(priv->regmap, TIM_CCER, &val); + if (!(val & TIM_CCER_CCXE)) + regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0); + + if (priv->clk_enabled) + clk_disable(priv->clk); + + return 0; +} + static const struct stm32_timer_trigger_cfg stm32_timer_trg_cfg = { .valids_table = valids_table, .num_valids_table = ARRAY_SIZE(valids_table), @@ -872,6 +895,7 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev) static struct platform_driver stm32_timer_trigger_driver = { .probe = stm32_timer_trigger_probe, + .remove = stm32_timer_trigger_remove, .driver = { .name = "stm32-timer-trigger", .of_match_table = stm32_trig_of_match,