From patchwork Wed Dec 10 09:51:42 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anson Huang X-Patchwork-Id: 5467731 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id C4C559F1D4 for ; Wed, 10 Dec 2014 09:59:10 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id DCF7420121 for ; Wed, 10 Dec 2014 09:59:09 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B1CC92010C for ; Wed, 10 Dec 2014 09:59:08 +0000 (UTC) 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 1Xye0G-0006Iy-TK; Wed, 10 Dec 2014 09:56:16 +0000 Received: from mail-by2on0730.outbound.protection.outlook.com ([2a01:111:f400:fc0c::730] helo=na01-by2-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Xye0C-0006F9-PX for linux-arm-kernel@lists.infradead.org; Wed, 10 Dec 2014 09:56:13 +0000 Received: from BN3PR0301CA0036.namprd03.prod.outlook.com (25.160.180.174) by CY1PR0301MB0633.namprd03.prod.outlook.com (25.160.158.139) with Microsoft SMTP Server (TLS) id 15.1.31.17; Wed, 10 Dec 2014 09:55:48 +0000 Received: from BN1BFFO11FD035.protection.gbl (2a01:111:f400:7c10::1:139) by BN3PR0301CA0036.outlook.office365.com (2a01:111:e400:4000::46) with Microsoft SMTP Server (TLS) id 15.1.31.17 via Frontend Transport; Wed, 10 Dec 2014 09:55:48 +0000 Received: from tx30smr01.am.freescale.net (192.88.168.50) by BN1BFFO11FD035.mail.protection.outlook.com (10.58.144.98) with Microsoft SMTP Server (TLS) id 15.1.26.17 via Frontend Transport; Wed, 10 Dec 2014 09:55:47 +0000 Received: from ubuntu.ap.freescale.net (ubuntu-010192242118.ap.freescale.net [10.192.242.118]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id sBA9tiGt016850; Wed, 10 Dec 2014 02:55:45 -0700 From: Anson Huang To: , , , , Subject: [PATCH V3] arm: imx: correct the hardware clock gate setting for shared nodes Date: Wed, 10 Dec 2014 17:51:42 +0800 Message-ID: <1418205102-14598-1-git-send-email-b20788@freescale.com> X-Mailer: git-send-email 1.7.9.5 X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CIP:192.88.168.50; CTRY:US; IPV:NLI; EFV:NLI; SFV:NSPM; SFS:(10019020)(6009001)(199003)(189002)(50986999)(46102003)(4396001)(50226001)(31966008)(97736003)(48376002)(120916001)(50466002)(99396003)(47776003)(64706001)(20776003)(105606002)(21056001)(33646002)(104016003)(89996001)(62966003)(77156002)(68736005)(77096005)(6806004)(19580395003)(87936001)(92566001)(19580405001)(107046002)(106466001)(2201001)(229853001)(84676001)(36756003)(42262002); DIR:OUT; SFP:1102; SCL:1; SRVR:CY1PR0301MB0633; H:tx30smr01.am.freescale.net; FPR:; SPF:Fail; MLV:sfv; PTR:InfoDomainNonexistent; A:1; MX:1; LANG:en; MIME-Version: 1.0 X-Microsoft-Antispam: UriScan:; X-Microsoft-Antispam: BCL:0;PCL:0;RULEID:;SRVR:CY1PR0301MB0633; X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(602002); SRVR:CY1PR0301MB0633; X-Forefront-PRVS: 0421BF7135 Received-SPF: Fail (protection.outlook.com: domain of freescale.com does not designate 192.88.168.50 as permitted sender) receiver=protection.outlook.com; client-ip=192.88.168.50; helo=tx30smr01.am.freescale.net; Authentication-Results: spf=fail (sender IP is 192.88.168.50) smtp.mailfrom=Anson.Huang@freescale.com; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:; SRVR:CY1PR0301MB0633; X-OriginatorOrg: freescale.com X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20141210_015612_868302_82A30FC8 X-CRM114-Status: GOOD ( 11.51 ) X-Spam-Score: -0.0 (/) Cc: linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP For those clk gates which hold share count, since its is_enabled callback is only checking the share count rather than reading the hardware register setting, in the late phase of kernel bootup, the clk_disable_unused action will NOT handle the scenario of share_count is 0 but the hardware setting is enabled, actually, U-Boot normally enables all clk gates, then those shared clk gates will be always enabled until they are used by some modules. So the problem would be: when kernel boot up, the usecount cat from clk tree is 0, but the clk gates actually is enabled in hardware register, it will confuse user and bring unnecessary power consumption. This patch adds .disable_unused callback and using hardware register check for .is_enabled callback of shared nodes to handle such scenario in late phase of kernel boot up, then the hardware status will match the clk tree info. Signed-off-by: Anson Huang --- changes from V2: 1. uboot -> U-Boot; 2. add .is_enabled change into commit log; 3. improve the condition check code. arch/arm/mach-imx/clk-gate2.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c index 5a75cdc..8935bff 100644 --- a/arch/arm/mach-imx/clk-gate2.c +++ b/arch/arm/mach-imx/clk-gate2.c @@ -96,15 +96,30 @@ static int clk_gate2_is_enabled(struct clk_hw *hw) { struct clk_gate2 *gate = to_clk_gate2(hw); - if (gate->share_count) - return !!__clk_get_enable_count(hw->clk); - else - return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx); + return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx); +} + +static void clk_gate2_disable_unused(struct clk_hw *hw) +{ + struct clk_gate2 *gate = to_clk_gate2(hw); + unsigned long flags = 0; + u32 reg; + + spin_lock_irqsave(gate->lock, flags); + + if (!gate->share_count || *gate->share_count == 0) { + reg = readl(gate->reg); + reg &= ~(3 << gate->bit_idx); + writel(reg, gate->reg); + } + + spin_unlock_irqrestore(gate->lock, flags); } static struct clk_ops clk_gate2_ops = { .enable = clk_gate2_enable, .disable = clk_gate2_disable, + .disable_unused = clk_gate2_disable_unused, .is_enabled = clk_gate2_is_enabled, };