From patchwork Tue Aug 26 08:58:21 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shawn Guo X-Patchwork-Id: 4779131 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 1325BC0338 for ; Tue, 26 Aug 2014 09:01:13 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id BC44720154 for ; Tue, 26 Aug 2014 09:01:11 +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 2A82D2014A for ; Tue, 26 Aug 2014 09:01:10 +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 1XMCb3-0006XF-4i; Tue, 26 Aug 2014 08:59:21 +0000 Received: from mail-bl2lp0207.outbound.protection.outlook.com ([207.46.163.207] helo=na01-bl2-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1XMCat-0006HL-Io for linux-arm-kernel@lists.infradead.org; Tue, 26 Aug 2014 08:59:12 +0000 Received: from BN3PR0301CA0076.namprd03.prod.outlook.com (25.160.152.172) by DM2PR03MB334.namprd03.prod.outlook.com (10.141.54.19) with Microsoft SMTP Server (TLS) id 15.0.1015.9; Tue, 26 Aug 2014 08:58:41 +0000 Received: from BN1BFFO11FD016.protection.gbl (2a01:111:f400:7c10::1:105) by BN3PR0301CA0076.outlook.office365.com (2a01:111:e400:401e::44) with Microsoft SMTP Server (TLS) id 15.0.1015.19 via Frontend Transport; Tue, 26 Aug 2014 08:58:41 +0000 Received: from az84smr01.freescale.net (192.88.158.2) by BN1BFFO11FD016.mail.protection.outlook.com (10.58.144.79) with Microsoft SMTP Server (TLS) id 15.0.1010.11 via Frontend Transport; Tue, 26 Aug 2014 08:58:41 +0000 Received: from dragon.ap.freescale.net ([10.192.185.230]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id s7Q8wbre027155; Tue, 26 Aug 2014 01:58:38 -0700 From: Shawn Guo To: Subject: [PATCH 1/2] ARM: imx: add an exclusive gate clock type Date: Tue, 26 Aug 2014 16:58:21 +0800 Message-ID: <1409043502-29081-1-git-send-email-shawn.guo@freescale.com> X-Mailer: git-send-email 1.9.1 X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CIP:192.88.158.2; CTRY:US; IPV:CAL; IPV:NLI; EFV:NLI; SFV:NSPM; SFS:(6009001)(189002)(199003)(110136001)(21056001)(33646002)(2351001)(92726001)(76482001)(77156001)(83322001)(99396002)(26826002)(229853001)(74502001)(46102001)(81156004)(105606002)(31966008)(81542001)(20776003)(62966002)(47776003)(74662001)(87286001)(4396001)(77982001)(104016003)(36756003)(50986999)(97736001)(68736004)(92566001)(84676001)(85852003)(85306004)(69596002)(86362001)(93916002)(88136002)(107046002)(50466002)(48376002)(95666004)(19580395003)(44976005)(64706001)(50226001)(83072002)(102836001)(80022001)(6806004)(104166001)(79102001)(90102001)(81342001)(19580405001)(106466001)(89996001)(87936001)(2004002); DIR:OUT; SFP:; SCL:1; SRVR:DM2PR03MB334; H:az84smr01.freescale.net; FPR:; MLV:ovrnspm; PTR:InfoDomainNonexistent; MX:1; A:1; LANG:en; MIME-Version: 1.0 X-Microsoft-Antispam: BCL:0;PCL:0;RULEID:;UriScan:; X-Forefront-PRVS: 03152A99FF Received-SPF: Fail (protection.outlook.com: domain of freescale.com does not designate 192.88.158.2 as permitted sender) receiver=protection.outlook.com; client-ip=192.88.158.2; helo=az84smr01.freescale.net; Authentication-Results: spf=fail (sender IP is 192.88.158.2) smtp.mailfrom=Shawn.Guo@freescale.com; X-OriginatorOrg: freescale.com X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140826_015911_823291_5FCF18C6 X-CRM114-Status: GOOD ( 15.13 ) X-Spam-Score: -0.7 (/) Cc: Shengjiu Wang , Shawn Guo , kernel@pengutronix.de 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=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, 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 There are a couple of gate clocks are mutually exclusive on i.MX6, i.e. LVDSCLK1_IBEN and LVDSCLK1_OBEN. They cannot be enabled simultaneously. This patches adds an exclusive gate clock type specifically for such case. The clock driver will need to call imx_clk_gate_exclusive() to register a gate clock with parameter exclusive_mask indicating the mask of gate bits which are mutually exclusive to this gate clock. Right now, it only handles the exclusive gate clocks which are defined in a single hardware register, which is the case we're running into today. But it can be extended to handle exclusive gate clocks defined in different registers later if needed. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/Makefile | 3 +- arch/arm/mach-imx/clk-gate-exclusive.c | 94 ++++++++++++++++++++++++++++++++++ arch/arm/mach-imx/clk.h | 3 ++ 3 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-imx/clk-gate-exclusive.c diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 9f1c359566bb..3e6476b6a698 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -16,7 +16,8 @@ obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o clk-imx51-imx53.o $(imx5-pm-y) obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \ clk-pfd.o clk-busy.o clk.o \ - clk-fixup-div.o clk-fixup-mux.o + clk-fixup-div.o clk-fixup-mux.o \ + clk-gate-exclusive.o obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o diff --git a/arch/arm/mach-imx/clk-gate-exclusive.c b/arch/arm/mach-imx/clk-gate-exclusive.c new file mode 100644 index 000000000000..c12f5f2e04dc --- /dev/null +++ b/arch/arm/mach-imx/clk-gate-exclusive.c @@ -0,0 +1,94 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include "clk.h" + +/** + * struct clk_gate_exclusive - i.MX specific gate clock which is mutually + * exclusive with other gate clocks + * + * @gate: the parent class + * @exclusive_mask: mask of gate bits which are mutually exclusive to this + * gate clock + * + * The imx exclusive gate clock is a subclass of basic clk_gate + * with an addtional mask to indicate which other gate bits in the same + * register is mutually exclusive to this gate clock. + */ +struct clk_gate_exclusive { + struct clk_gate gate; + u32 exclusive_mask; +}; + +static int clk_gate_exclusive_enable(struct clk_hw *hw) +{ + struct clk_gate *gate = container_of(hw, struct clk_gate, hw); + struct clk_gate_exclusive *exgate = container_of(gate, + struct clk_gate_exclusive, gate); + u32 val = readl(gate->reg); + + if (val & exgate->exclusive_mask) + return -EBUSY; + + return clk_gate_ops.enable(hw); +} + +static void clk_gate_exclusive_disable(struct clk_hw *hw) +{ + clk_gate_ops.disable(hw); +} + +static int clk_gate_exclusive_is_enabled(struct clk_hw *hw) +{ + return clk_gate_ops.is_enabled(hw); +} + +static const struct clk_ops clk_gate_exclusive_ops = { + .enable = clk_gate_exclusive_enable, + .disable = clk_gate_exclusive_disable, + .is_enabled = clk_gate_exclusive_is_enabled, +}; + +struct clk *imx_clk_gate_exclusive(const char *name, const char *parent, + void __iomem *reg, u8 shift, u32 exclusive_mask) +{ + struct clk_gate_exclusive *exgate; + struct clk_gate *gate; + struct clk *clk; + struct clk_init_data init; + + if (exclusive_mask == 0) + return ERR_PTR(-EINVAL); + + exgate = kzalloc(sizeof(*exgate), GFP_KERNEL); + if (!exgate) + return ERR_PTR(-ENOMEM); + gate = &exgate->gate; + + init.name = name; + init.ops = &clk_gate_exclusive_ops; + init.flags = CLK_SET_RATE_PARENT; + init.parent_names = parent ? &parent : NULL; + init.num_parents = parent ? 1 : 0; + + gate->reg = reg; + gate->bit_idx = shift; + gate->lock = &imx_ccm_lock; + gate->hw.init = &init; + exgate->exclusive_mask = exclusive_mask; + + clk = clk_register(NULL, &gate->hw); + if (IS_ERR(clk)) + kfree(exgate); + + return clk; +} diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h index d5ba76fee115..4cdf8b6a74e8 100644 --- a/arch/arm/mach-imx/clk.h +++ b/arch/arm/mach-imx/clk.h @@ -36,6 +36,9 @@ struct clk *clk_register_gate2(struct device *dev, const char *name, struct clk * imx_obtain_fixed_clock( const char *name, unsigned long rate); +struct clk *imx_clk_gate_exclusive(const char *name, const char *parent, + void __iomem *reg, u8 shift, u32 exclusive_mask); + static inline struct clk *imx_clk_gate2(const char *name, const char *parent, void __iomem *reg, u8 shift) {