Received: by 2002:a25:c205:0:0:0:0:0 with SMTP id s5csp3188419ybf; Tue, 3 Mar 2020 01:04:09 -0800 (PST) X-Google-Smtp-Source: ADFU+vvt558XRoYY3cLYVxkrdEnE9VUGqph7j8jdO7K7FUOydsUr7MQKL3OWUOjsAzaxY6G41UBE X-Received: by 2002:aca:ea46:: with SMTP id i67mr1697005oih.149.1583226249336; Tue, 03 Mar 2020 01:04:09 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1583226249; cv=none; d=google.com; s=arc-20160816; b=e6B/t8khSyPVN0hlmDxCilGqaC0226Wfgzi36o7BrHFs1RTJHTbN5tPMTpPd2Qd5q9 7uhvxjzsZ0uB+wzzdPtmCYLx+DU/mItE8wHRAieuBEVqiCTYNAXUXK/wDMmyURNZpOxw ONiDFevlvYQ1ybgoXryByEgnP+g1UqSMH652aGqpwnCOVP+oDudO9kqjTBoRerlobsze aml2p188D/kEbSU8jB7jwXuZrLFBUM9hfkEdDHq3OLY4Nj3lA8JYuzal6v/eVUeDg0/l jRb8BLo0OQfU/16MypRzyKw1vJ9AHR5K/f6iNpiouwfVGmqJeZfc8dGOP7VjXPyhX6f9 LwXg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=oXjX0mg/Y4i1iyPi7ezEnl06yPgIsmSFX20iT1ohpqI=; b=G6nzBgshzLauyLsK9LtblbWu7DvMsBhrs7qB5TplWOHSr0Fo5xL3wmSG95+DtSWElN YiYBU2hinnr61/pDHfsEF+MyiYG/xHN3jzEUusDdUtlnsoHkfBKxW1QqhusxjIXmCBGi S42DzMm8NtC+GA0S/2JbWnkBMY+ISDKxs7L6lYOMHPIkwZaVZYwzX8lIvLAepHY/84q5 TND+JXOTpfYzfgkO9e1RZ2nMIrmlZ5Bm9h6uJkA1w/qnNfysl2uk4yYIcvOV3jNiUBYe OXZSSrZySg/+h09FXcmaP2UmfLQWgjyCbCUnHBU0b/ff2yIb6LgvDzFCu/5wa5SQ+VQq Pq9w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=nxp.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q64si4786775oic.155.2020.03.03.01.03.57; Tue, 03 Mar 2020 01:04:09 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=nxp.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728037AbgCCJDo (ORCPT + 99 others); Tue, 3 Mar 2020 04:03:44 -0500 Received: from inva020.nxp.com ([92.121.34.13]:36518 "EHLO inva020.nxp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727992AbgCCJDn (ORCPT ); Tue, 3 Mar 2020 04:03:43 -0500 Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id CA6871A1469; Tue, 3 Mar 2020 10:03:40 +0100 (CET) Received: from inva024.eu-rdc02.nxp.com (inva024.eu-rdc02.nxp.com [134.27.226.22]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id BD7231A1465; Tue, 3 Mar 2020 10:03:40 +0100 (CET) Received: from fsr-ub1664-175.ea.freescale.net (fsr-ub1664-175.ea.freescale.net [10.171.82.40]) by inva024.eu-rdc02.nxp.com (Postfix) with ESMTP id C3DD920414; Tue, 3 Mar 2020 10:03:39 +0100 (CET) From: Abel Vesa To: Rob Herring , Shawn Guo , Sascha Hauer , Fabio Estevam , Mike Turquette , Stephen Boyd , Lee Jones , Anson Huang , Leonard Crestez , Peng Fan , Jacky Bai Cc: NXP Linux Team , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Linux Kernel Mailing List , linux-clk@vger.kernel.org, Abel Vesa Subject: [RFC 04/11] clk: imx: Add gate shared for i.MX8MP audiomix Date: Tue, 3 Mar 2020 11:03:19 +0200 Message-Id: <1583226206-19758-5-git-send-email-abel.vesa@nxp.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1583226206-19758-1-git-send-email-abel.vesa@nxp.com> References: <1583226206-19758-1-git-send-email-abel.vesa@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The newer i.MX platform use some gates that have a shared control bit between them. Signed-off-by: Abel Vesa --- drivers/clk/imx/Makefile | 2 +- drivers/clk/imx/clk-gate-shared.c | 111 ++++++++++++++++++++++++++++++++++++++ drivers/clk/imx/clk.h | 4 ++ 3 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/imx/clk-gate-shared.c diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index 928f874c..799a8ef 100644 --- a/drivers/clk/imx/Makefile +++ b/drivers/clk/imx/Makefile @@ -27,7 +27,7 @@ obj-$(CONFIG_MXC_CLK_SCU) += \ obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o -obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o +obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o clk-gate-shared.o obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o obj-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o diff --git a/drivers/clk/imx/clk-gate-shared.c b/drivers/clk/imx/clk-gate-shared.c new file mode 100644 index 00000000..961a0e3 --- /dev/null +++ b/drivers/clk/imx/clk-gate-shared.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019 NXP. + */ + +#include +#include +#include +#include +#include "clk.h" + +/** + * struct clk_gate_shared - i.MX specific gate clock having the gate flag + * shared with other gate clocks + */ +struct clk_gate_shared { + struct clk_gate gate; + spinlock_t *lock; + unsigned int *share_count; +}; + +static int clk_gate_shared_enable(struct clk_hw *hw) +{ + struct clk_gate *gate = to_clk_gate(hw); + struct clk_gate_shared *shgate = container_of(gate, + struct clk_gate_shared, gate); + unsigned long flags = 0; + int ret = 0; + + spin_lock_irqsave(shgate->lock, flags); + + if (shgate->share_count && (*shgate->share_count)++ > 0) + goto out; + + ret = clk_gate_ops.enable(hw); +out: + spin_unlock_irqrestore(shgate->lock, flags); + + return ret; +} + +static void clk_gate_shared_disable(struct clk_hw *hw) +{ + struct clk_gate *gate = to_clk_gate(hw); + struct clk_gate_shared *shgate = container_of(gate, + struct clk_gate_shared, gate); + unsigned long flags = 0; + + spin_lock_irqsave(shgate->lock, flags); + + if (shgate->share_count) { + if (WARN_ON(*shgate->share_count == 0)) + goto out; + else if (--(*shgate->share_count) > 0) + goto out; + } + + clk_gate_ops.disable(hw); +out: + spin_unlock_irqrestore(shgate->lock, flags); +} + +static int clk_gate_shared_is_enabled(struct clk_hw *hw) +{ + return clk_gate_ops.is_enabled(hw); +} + +static const struct clk_ops clk_gate_shared_ops = { + .enable = clk_gate_shared_enable, + .disable = clk_gate_shared_disable, + .is_enabled = clk_gate_shared_is_enabled, +}; + +struct clk_hw *imx_dev_clk_hw_gate_shared(struct device *dev, const char *name, + const char *parent, void __iomem *reg, + u8 shift, unsigned int *share_count) +{ + struct clk_gate_shared *shgate; + struct clk_gate *gate; + struct clk_hw *hw; + struct clk_init_data init; + int ret; + + shgate = kzalloc(sizeof(*shgate), GFP_KERNEL); + if (!shgate) + return ERR_PTR(-ENOMEM); + gate = &shgate->gate; + + init.name = name; + init.ops = &clk_gate_shared_ops; + init.flags = CLK_OPS_PARENT_ENABLE; + init.parent_names = parent ? &parent : NULL; + init.num_parents = parent ? 1 : 0; + + gate->reg = reg; + gate->bit_idx = shift; + gate->lock = NULL; + gate->hw.init = &init; + shgate->lock = &imx_ccm_lock; + shgate->share_count = share_count; + + hw = &gate->hw; + + ret = clk_hw_register(NULL, hw); + if (ret) { + kfree(shgate); + return ERR_PTR(ret); + } + + return hw; +} diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index f074dd8..51d6c26 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -151,6 +151,10 @@ struct clk_hw *imx_clk_hw_sscg_pll(const char *name, void __iomem *base, unsigned long flags); +struct clk_hw *imx_dev_clk_hw_gate_shared(struct device *dev, const char *name, + const char *parent, void __iomem *reg, + u8 shift, unsigned int *share_count); + enum imx_pllv3_type { IMX_PLLV3_GENERIC, IMX_PLLV3_SYS, -- 2.7.4