From patchwork Wed Jun 20 07:53:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ludovic BARRE X-Patchwork-Id: 10476173 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 7FB51600F6 for ; Wed, 20 Jun 2018 07:56:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 702A928CD7 for ; Wed, 20 Jun 2018 07:56:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 646D128CE2; Wed, 20 Jun 2018 07:56:23 +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=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.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 B035C28CDA for ; Wed, 20 Jun 2018 07:56:22 +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=Yzrgf9xgXXUdCfbgrHXwCYp8voYewO1BvRYUIZteGgo=; b=JgB4klcmFHRPhX TE1NZp8fB60RO61LYfbX7JcBtDYysyyk6BUnfe8uN1ewvzxXW5Q7t0khlS524GZ9M9ZQ6hY2L4Z5M BBOAniO11RA8PHcg7KP0oUfFWvlDxj4V4RzE10ezgrdyVdYS+knsxOPjBnPhTJc+zzZqORQC4x6sD MPJELwtR7osx6Y3zD7IJV917MQSr1YzS+OMSCllJjhZcOWdzbGpGcbTxeLAQ8z/fgPEAJGa23QE8S S+lC36eQBxE++KjUzT4PbXib0zjTjGL23uPq88HPatfM7wN+ywZGhwZpplszydnWEscPQNtEex0kJ PCyuHiilKSvdYBb1lQ5w==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fVXyQ-0000BK-M1; Wed, 20 Jun 2018 07:56:14 +0000 Received: from mx07-00178001.pphosted.com ([62.209.51.94]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fVXx5-0006dX-Ms for linux-arm-kernel@lists.infradead.org; Wed, 20 Jun 2018 07:55:02 +0000 Received: from pps.filterd (m0046037.ppops.net [127.0.0.1]) by mx07-.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id w5K7sZxR028244; Wed, 20 Jun 2018 09:54:35 +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 2jpma37es9-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT); Wed, 20 Jun 2018 09:54:35 +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 7962E48; Wed, 20 Jun 2018 07:54:33 +0000 (GMT) Received: from Webmail-eu.st.com (Safex1hubcas23.st.com [10.75.90.46]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 3C40715DF; Wed, 20 Jun 2018 07:54:33 +0000 (GMT) Received: from SAFEX1HUBCAS24.st.com (10.75.90.94) by SAFEX1HUBCAS23.st.com (10.75.90.46) with Microsoft SMTP Server (TLS) id 14.3.361.1; Wed, 20 Jun 2018 09:54:33 +0200 Received: from lmecxl0923.lme.st.com (10.48.0.237) by webmail-ga.st.com (10.75.90.48) with Microsoft SMTP Server (TLS) id 14.3.361.1; Wed, 20 Jun 2018 09:54:32 +0200 From: Ludovic Barre To: Wim Van Sebroeck , Guenter Roeck , Rob Herring Subject: [PATCH V2 1/3] watchdog: stm32: add pclk feature for stm32mp1 Date: Wed, 20 Jun 2018 09:53:56 +0200 Message-ID: <1529481238-15277-2-git-send-email-ludovic.Barre@st.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1529481238-15277-1-git-send-email-ludovic.Barre@st.com> References: <1529481238-15277-1-git-send-email-ludovic.Barre@st.com> MIME-Version: 1.0 X-Originating-IP: [10.48.0.237] X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-06-20_04:, , signatures=0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180620_005452_094023_8D60D57B X-CRM114-Status: GOOD ( 20.95 ) 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: devicetree@vger.kernel.org, Alexandre Torgue , linux-kernel@vger.kernel.org, Ludovic Barre , Maxime Coquelin , linux-arm-kernel@lists.infradead.org, linux-watchdog@vger.kernel.org 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 From: Ludovic Barre This patch adds config data to manage specific properties by compatible. Adds stm32mp1 config which requires pclk clock. Signed-off-by: Ludovic Barre --- .../devicetree/bindings/watchdog/st,stm32-iwdg.txt | 21 +++- drivers/watchdog/stm32_iwdg.c | 132 ++++++++++++++------- 2 files changed, 104 insertions(+), 49 deletions(-) diff --git a/Documentation/devicetree/bindings/watchdog/st,stm32-iwdg.txt b/Documentation/devicetree/bindings/watchdog/st,stm32-iwdg.txt index cc13b10a..f07f6d89 100644 --- a/Documentation/devicetree/bindings/watchdog/st,stm32-iwdg.txt +++ b/Documentation/devicetree/bindings/watchdog/st,stm32-iwdg.txt @@ -2,18 +2,31 @@ STM32 Independent WatchDoG (IWDG) --------------------------------- Required properties: -- compatible: "st,stm32-iwdg" -- reg: physical base address and length of the registers set for the device -- clocks: must contain a single entry describing the clock input +- compatible: Should be either "st,stm32-iwdg" or "st,stm32mp1-iwdg" +- reg: Physical base address and length of the registers set for the device +- clocks: Reference to the clock entry lsi. Additional pclk clock entry + is required only for st,stm32mp1-iwdg. +- clock-names: Name of the clocks used. + "lsi" for st,stm32-iwdg + "pclk", "lsi" for st,stm32mp1-iwdg Optional Properties: - timeout-sec: Watchdog timeout value in seconds. -Example: +Examples: iwdg: watchdog@40003000 { compatible = "st,stm32-iwdg"; reg = <0x40003000 0x400>; clocks = <&clk_lsi>; + clock-names = "lsi"; + timeout-sec = <32>; +}; + +iwdg: iwdg@5a002000 { + compatible = "st,stm32mp1-iwdg"; + reg = <0x5a002000 0x400>; + clocks = <&rcc IWDG2>, <&clk_lsi>; + clock-names = "pclk", "lsi"; timeout-sec = <32>; }; diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c index c97ad56..fc96670 100644 --- a/drivers/watchdog/stm32_iwdg.c +++ b/drivers/watchdog/stm32_iwdg.c @@ -11,12 +11,13 @@ #include #include -#include -#include #include #include #include +#include +#include #include +#include #include #include @@ -54,11 +55,17 @@ #define TIMEOUT_US 100000 #define SLEEP_US 1000 +struct stm32_iwdg_config { + bool has_pclk; +}; + struct stm32_iwdg { - struct watchdog_device wdd; - void __iomem *regs; - struct clk *clk; - unsigned int rate; + struct watchdog_device wdd; + void __iomem *regs; + struct stm32_iwdg_config *config; + struct clk *clk_lsi; + struct clk *clk_pclk; + unsigned int rate; }; static inline u32 reg_read(void __iomem *base, u32 reg) @@ -133,6 +140,44 @@ static int stm32_iwdg_set_timeout(struct watchdog_device *wdd, return 0; } +static int stm32_iwdg_clk_init(struct platform_device *pdev, + struct stm32_iwdg *wdt) +{ + u32 ret; + + wdt->clk_lsi = devm_clk_get(&pdev->dev, "lsi"); + if (IS_ERR(wdt->clk_lsi)) { + dev_err(&pdev->dev, "Unable to get lsi clock\n"); + return PTR_ERR(wdt->clk_lsi); + } + + /* optional peripheral clock */ + if (wdt->config->has_pclk) { + wdt->clk_pclk = devm_clk_get(&pdev->dev, "pclk"); + if (IS_ERR(wdt->clk_pclk)) { + dev_err(&pdev->dev, "Unable to get pclk clock\n"); + return PTR_ERR(wdt->clk_pclk); + } + + ret = clk_prepare_enable(wdt->clk_pclk); + if (ret) { + dev_err(&pdev->dev, "Unable to prepare pclk clock\n"); + return ret; + } + } + + ret = clk_prepare_enable(wdt->clk_lsi); + if (ret) { + dev_err(&pdev->dev, "Unable to prepare lsi clock\n"); + clk_disable_unprepare(wdt->clk_pclk); + return ret; + } + + wdt->rate = clk_get_rate(wdt->clk_lsi); + + return 0; +} + static const struct watchdog_info stm32_iwdg_info = { .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | @@ -147,49 +192,50 @@ static const struct watchdog_ops stm32_iwdg_ops = { .set_timeout = stm32_iwdg_set_timeout, }; +static const struct stm32_iwdg_config stm32_iwdg_cfg = { + .has_pclk = false, +}; + +static const struct stm32_iwdg_config stm32mp1_iwdg_cfg = { + .has_pclk = true, +}; + +static const struct of_device_id stm32_iwdg_of_match[] = { + { .compatible = "st,stm32-iwdg", .data = &stm32_iwdg_cfg }, + { .compatible = "st,stm32mp1-iwdg", .data = &stm32mp1_iwdg_cfg }, + { /* end node */ } +}; +MODULE_DEVICE_TABLE(of, stm32_iwdg_of_match); + static int stm32_iwdg_probe(struct platform_device *pdev) { struct watchdog_device *wdd; + const struct of_device_id *match; struct stm32_iwdg *wdt; struct resource *res; - void __iomem *regs; - struct clk *clk; int ret; + match = of_match_device(stm32_iwdg_of_match, &pdev->dev); + if (!match || !match->data) + return -ENODEV; + + wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); + if (!wdt) + return -ENOMEM; + + wdt->config = (struct stm32_iwdg_config *)match->data; + /* This is the timer base. */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - regs = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(regs)) { + wdt->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(wdt->regs)) { dev_err(&pdev->dev, "Could not get resource\n"); - return PTR_ERR(regs); + return PTR_ERR(wdt->regs); } - clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(clk)) { - dev_err(&pdev->dev, "Unable to get clock\n"); - return PTR_ERR(clk); - } - - ret = clk_prepare_enable(clk); - if (ret) { - dev_err(&pdev->dev, "Unable to prepare clock %p\n", clk); + ret = stm32_iwdg_clk_init(pdev, wdt); + if (ret) return ret; - } - - /* - * Allocate our watchdog driver data, which has the - * struct watchdog_device nested within it. - */ - wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); - if (!wdt) { - ret = -ENOMEM; - goto err; - } - - /* Initialize struct stm32_iwdg. */ - wdt->regs = regs; - wdt->clk = clk; - wdt->rate = clk_get_rate(clk); /* Initialize struct watchdog_device. */ wdd = &wdt->wdd; @@ -217,7 +263,8 @@ static int stm32_iwdg_probe(struct platform_device *pdev) return 0; err: - clk_disable_unprepare(clk); + clk_disable_unprepare(wdt->clk_lsi); + clk_disable_unprepare(wdt->clk_pclk); return ret; } @@ -227,23 +274,18 @@ static int stm32_iwdg_remove(struct platform_device *pdev) struct stm32_iwdg *wdt = platform_get_drvdata(pdev); watchdog_unregister_device(&wdt->wdd); - clk_disable_unprepare(wdt->clk); + clk_disable_unprepare(wdt->clk_lsi); + clk_disable_unprepare(wdt->clk_pclk); return 0; } -static const struct of_device_id stm32_iwdg_of_match[] = { - { .compatible = "st,stm32-iwdg" }, - { /* end node */ } -}; -MODULE_DEVICE_TABLE(of, stm32_iwdg_of_match); - static struct platform_driver stm32_iwdg_driver = { .probe = stm32_iwdg_probe, .remove = stm32_iwdg_remove, .driver = { .name = "iwdg", - .of_match_table = stm32_iwdg_of_match, + .of_match_table = of_match_ptr(stm32_iwdg_of_match), }, }; module_platform_driver(stm32_iwdg_driver);