From patchwork Sat Apr 19 05:01:32 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shawn Guo X-Patchwork-Id: 340465 Return-Path: X-Original-To: incoming-imx@patchwork.ozlabs.org Delivered-To: patchwork-incoming-imx@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 9EBCD14009D for ; Sat, 19 Apr 2014 15:06:28 +1000 (EST) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WbNQM-0001t8-1I; Sat, 19 Apr 2014 05:02:46 +0000 Received: from va3ehsobe005.messaging.microsoft.com ([216.32.180.31] helo=va3outboundpool.messaging.microsoft.com) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WbNQ8-0001pt-Hx for linux-arm-kernel@lists.infradead.org; Sat, 19 Apr 2014 05:02:33 +0000 Received: from mail38-va3-R.bigfish.com (10.7.14.228) by VA3EHSOBE008.bigfish.com (10.7.40.28) with Microsoft SMTP Server id 14.1.225.22; Sat, 19 Apr 2014 05:01:17 +0000 Received: from mail38-va3 (localhost [127.0.0.1]) by mail38-va3-R.bigfish.com (Postfix) with ESMTP id 492DB3C0080; Sat, 19 Apr 2014 05:01:17 +0000 (UTC) X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPV:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-SpamScore: 0 X-BigFish: VS0(zzzz1f42h2148h1ee6h1de0h1fdah2073h2146h1202h1e76h2189h1d1ah1d2ah21bch1fc6h208chzz1de098h8275bh1de097h84d07hz2dh2a8h839hd24he5bhf0ah1288h12a5h12a9h12bdh12e5h137ah139eh13b6h1441h1504h1537h162dh1631h1758h1898h18e1h1946h19b5h1ad9h1b0ah1b2fh2222h224fh1fb3h1d0ch1d2eh1d3fh1dfeh1dffh1e23h1fe8h1ff5h2218h2216h226dh22d0h24afh2327h2336h2438h2461h2487h24d7h2516h2545h255eh25cch25f6h2605h268bh26d3h1155h) Received: from mail38-va3 (localhost.localdomain [127.0.0.1]) by mail38-va3 (MessageSwitch) id 1397883674930560_8647; Sat, 19 Apr 2014 05:01:14 +0000 (UTC) Received: from VA3EHSMHS006.bigfish.com (unknown [10.7.14.228]) by mail38-va3.bigfish.com (Postfix) with ESMTP id DCC9E46006B; Sat, 19 Apr 2014 05:01:14 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by VA3EHSMHS006.bigfish.com (10.7.99.16) with Microsoft SMTP Server (TLS) id 14.16.227.3; Sat, 19 Apr 2014 05:01:14 +0000 Received: from az84smr01.freescale.net (10.64.34.197) by 039-SN1MMR1-005.039d.mgd.msft.net (10.84.1.17) with Microsoft SMTP Server (TLS) id 14.3.174.2; Sat, 19 Apr 2014 05:02:02 +0000 Received: from dragon.ap.freescale.net ([10.192.185.87]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id s3J51h36021409; Fri, 18 Apr 2014 22:01:59 -0700 From: Shawn Guo To: Subject: [PATCH 3/4] ARM: imx: add shared gate clock support Date: Sat, 19 Apr 2014 13:01:32 +0800 Message-ID: <1397883693-26101-4-git-send-email-shawn.guo@freescale.com> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1397883693-26101-1-git-send-email-shawn.guo@freescale.com> References: <1397883693-26101-1-git-send-email-shawn.guo@freescale.com> MIME-Version: 1.0 X-OriginatorOrg: freescale.com X-FOPE-CONNECTOR: Id%0$Dn%*$RO%0$TLS%0$FQDN%$TlsDn% X-FOPE-CONNECTOR: Id%0$Dn%FREESCALE.MAIL.ONMICROSOFT.COM$RO%1$TLS%0$FQDN%$TlsDn% X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140418_220232_729316_3A85F53B X-CRM114-Status: GOOD ( 16.66 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.3.2 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [216.32.180.31 listed in list.dnswl.org] 0.7 UNRESOLVED_TEMPLATE Headers contain an unresolved template Cc: Gerhard Sittig , Mike Turquette , Shawn Guo , kernel@pengutronix.de, Nicolin Chen X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+incoming-imx=patchwork.ozlabs.org@lists.infradead.org List-Id: linux-imx-kernel.lists.patchwork.ozlabs.org It's quite common on i.MX that one gate bit controls the gating of multiple clocks, i.e. this is a shared gate. The patch adds the function imx_clk_gate2_shared() for such case. The clocks controlled by the same gate bits should call this function with a pointer to a single share count variable, so that the gate bits will only be operated on the first enabling and the last disabling of these shared gate clocks. Thanks to Gerhard Sittig for this idea. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-gate2.c | 13 ++++++++++++- arch/arm/mach-imx/clk.h | 13 +++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c index 0803df9..4ba587d 100644 --- a/arch/arm/mach-imx/clk-gate2.c +++ b/arch/arm/mach-imx/clk-gate2.c @@ -33,6 +33,7 @@ struct clk_gate2 { u8 bit_idx; u8 flags; spinlock_t *lock; + unsigned int *share_count; }; #define to_clk_gate2(_hw) container_of(_hw, struct clk_gate2, hw) @@ -45,10 +46,14 @@ static int clk_gate2_enable(struct clk_hw *hw) spin_lock_irqsave(gate->lock, flags); + if (gate->share_count && (*gate->share_count)++ > 0) + goto out; + reg = readl(gate->reg); reg |= 3 << gate->bit_idx; writel(reg, gate->reg); +out: spin_unlock_irqrestore(gate->lock, flags); return 0; @@ -62,10 +67,14 @@ static void clk_gate2_disable(struct clk_hw *hw) spin_lock_irqsave(gate->lock, flags); + if (gate->share_count && --(*gate->share_count) > 0) + goto out; + reg = readl(gate->reg); reg &= ~(3 << gate->bit_idx); writel(reg, gate->reg); +out: spin_unlock_irqrestore(gate->lock, flags); } @@ -91,7 +100,8 @@ static struct clk_ops clk_gate2_ops = { struct clk *clk_register_gate2(struct device *dev, const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u8 bit_idx, - u8 clk_gate2_flags, spinlock_t *lock) + u8 clk_gate2_flags, spinlock_t *lock, + unsigned int *share_count) { struct clk_gate2 *gate; struct clk *clk; @@ -106,6 +116,7 @@ struct clk *clk_register_gate2(struct device *dev, const char *name, gate->bit_idx = bit_idx; gate->flags = clk_gate2_flags; gate->lock = lock; + gate->share_count = share_count; init.name = name; init.ops = &clk_gate2_ops; diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h index 048c5ad8..e29f6eb 100644 --- a/arch/arm/mach-imx/clk.h +++ b/arch/arm/mach-imx/clk.h @@ -28,7 +28,8 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, struct clk *clk_register_gate2(struct device *dev, const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u8 bit_idx, - u8 clk_gate_flags, spinlock_t *lock); + u8 clk_gate_flags, spinlock_t *lock, + unsigned int *share_count); struct clk * imx_obtain_fixed_clock( const char *name, unsigned long rate); @@ -37,7 +38,15 @@ static inline struct clk *imx_clk_gate2(const char *name, const char *parent, void __iomem *reg, u8 shift) { return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, - shift, 0, &imx_ccm_lock); + shift, 0, &imx_ccm_lock, NULL); +} + +static inline struct clk *imx_clk_gate2_shared(const char *name, + const char *parent, void __iomem *reg, u8 shift, + unsigned int *share_count) +{ + return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, + shift, 0, &imx_ccm_lock, share_count); } struct clk *imx_clk_pfd(const char *name, const char *parent_name,