Received: by 10.223.164.202 with SMTP id h10csp1417338wrb; Wed, 15 Nov 2017 20:13:01 -0800 (PST) X-Google-Smtp-Source: AGs4zMY73YCpKhc9jqlBEaXgOSuh0J+m+nLYODVK9a/3zMTWE8YMkrSoVvZqteS8WpCMTOzqS9cj X-Received: by 10.84.193.3 with SMTP id e3mr382070pld.300.1510805581314; Wed, 15 Nov 2017 20:13:01 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1510805581; cv=none; d=google.com; s=arc-20160816; b=J+3FpslLBOk/yOfhftSFSITEqkrOKnpQiLvtPfg2jbxHisrZnrbWqIwOzYcAU9aBbj 5Mbt96U//eucLzB+wNgg4K+1JzLN/CdpGMXxj5xvub6AJRBXHLM4usaMQ2a3YjPLmoNZ H5BPs//rVJ9x5EfJkdwodS+CrSAikCbi5x2zQt/NWWG/zrMGPlx+JSndrtI9++EJBuYd tHUrvNlGPfI6AJh0J8Spy8yhorI1Be2A1/y66r3ZoFzVAwdLQXCRNbCmyVBvZiGQwY5I UUsEjNBzLI9vRSXcGE1LqeaCR0Vf0Vb0VkRxZcM9q/f0ebxc3If9UyChuczsdkLdXSJa 1S7A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:dkim-signature:arc-authentication-results; bh=TDT/CrvsIflvBVB+JI5ajmg4h5S1qqh10AIiZVSpjDQ=; b=xlsz6r20tmYtqovc3tDuHxoPo+2uPpsqJk1lybiij1FIFDf2VNhMMmJEJlOxEu7nyX OWjTyeXR26T0WqWkBp3aDPQVScQA8JJxPw3gourWIh2ego43YEyeJC1JOOcCrsySKz3i FKn7hQyE677FS4rNnAFoxQIpigHDQmrKKlepi6auPsxXDrf6SRQysZeObTIKovt4slxK wRIdEspgOyq9h9h03Vnvl0LlmSXTmf+FiY+Vy9cb3Ll0zuVUqwF3Ds9RbpyF6Y5Pjgwb Ln1tB/vRqNUqCUVj/qA5dRUu5cAYYZoaGZAL4+lfW7W0VMKQ4OvVaWmQS8I4FJ4gBeCb TomQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=YUdVMCH4; 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=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m26si183542pgc.86.2017.11.15.20.12.36; Wed, 15 Nov 2017 20:13:01 -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; dkim=pass header.i=@linaro.org header.s=google header.b=YUdVMCH4; 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=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933749AbdKPCb7 (ORCPT + 90 others); Wed, 15 Nov 2017 21:31:59 -0500 Received: from mail-pf0-f194.google.com ([209.85.192.194]:48193 "EHLO mail-pf0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755702AbdKPCb4 (ORCPT ); Wed, 15 Nov 2017 21:31:56 -0500 Received: by mail-pf0-f194.google.com with SMTP id r62so5908409pfd.5 for ; Wed, 15 Nov 2017 18:31:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=TDT/CrvsIflvBVB+JI5ajmg4h5S1qqh10AIiZVSpjDQ=; b=YUdVMCH4qCuCiMQvi5mN4dM3vUl/MJizhl9HNIhkcUDscaY76XbhMjTgGjgNpGDWTH sZPmbYSP90hM/j8Ue1Jzq4ExbsPAVNFxDw3xYMoUGwSS41aPKzldF+ficaOg12jrTSAm JPa3rcmk2ttoVyY+QTEuAEEyrGIunpTQZzyGU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=TDT/CrvsIflvBVB+JI5ajmg4h5S1qqh10AIiZVSpjDQ=; b=DLiXK7t8VqmAPACfDlvJb6map5gc4V21WU4sfZPoq2XDixFeI8uEjzAkm44YMTjeFT WRoc/Jmh9dBuUfZJB/htePGXATvMvuMUuPJ2YRfQEE2Xx4LUvP7EIs4VHOdw2HR0tb+0 Nv4D2baq7V2l+4G5O3RY25fJbH0f6qh085ZqWBiZa0i9r8itUe2JQWJTXL0KIkjI7g+m 1PLOF5yrANB9k1EolpGyeyldSCCunZjW9pr6jmetTd9lZ19muWgHRidzBTR3//X091Y3 Q8RGEVpnZFyhWmbntiv0BcQPYJIMR4lD6WZ80HgKXWckbywqmysljXonWyyHNYS+JeE7 viSA== X-Gm-Message-State: AJaThX5mRfvrIHwTbMA/JLuA6F4Y7L5CfJ5PCu4dLxi9zVgd2R3zd8z8 eFEJYfppMGmiVi9vCvGByn5dww== X-Received: by 10.159.204.147 with SMTP id t19mr163922plo.222.1510799516188; Wed, 15 Nov 2017 18:31:56 -0800 (PST) Received: from dragon ([104.237.91.117]) by smtp.gmail.com with ESMTPSA id e70sm77418pgc.15.2017.11.15.18.31.53 (version=TLS1_2 cipher=AES128-SHA bits=128/128); Wed, 15 Nov 2017 18:31:55 -0800 (PST) Date: Thu, 16 Nov 2017 10:31:34 +0800 From: Shawn Guo To: Jiancheng Xue Cc: sboyd@codeaurora.org, mturquette@baylibre.com, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, hermit.wangheming@hisilicon.com, project-aspen-dev@linaro.org, tianshuliang Subject: Re: [PATCH 1/3] clk: hisilicon: add hisi phase clock support Message-ID: <20171116023131.GI11163@dragon> References: <1508324429-6012-1-git-send-email-xuejiancheng@hisilicon.com> <1508324429-6012-2-git-send-email-xuejiancheng@hisilicon.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1508324429-6012-2-git-send-email-xuejiancheng@hisilicon.com> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Oct 18, 2017 at 07:00:27AM -0400, Jiancheng Xue wrote: > From: tianshuliang > > Add a phase clock type for HiSilicon SoCs,which supports > clk_set_phase operation. As the pair of phase operation, I don't see why clk_get_phase operation is missing. > > Signed-off-by: tianshuliang > Signed-off-by: Jiancheng Xue > --- > drivers/clk/hisilicon/Makefile | 2 +- > drivers/clk/hisilicon/clk-hisi-phase.c | 117 +++++++++++++++++++++++++++++++++ > drivers/clk/hisilicon/clk.c | 45 +++++++++++++ > drivers/clk/hisilicon/clk.h | 22 +++++++ > 4 files changed, 185 insertions(+), 1 deletion(-) > create mode 100644 drivers/clk/hisilicon/clk-hisi-phase.c > > diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile > index 1e4c3dd..7189f07 100644 > --- a/drivers/clk/hisilicon/Makefile > +++ b/drivers/clk/hisilicon/Makefile > @@ -2,7 +2,7 @@ > # Hisilicon Clock specific Makefile > # > > -obj-y += clk.o clkgate-separated.o clkdivider-hi6220.o > +obj-y += clk.o clkgate-separated.o clkdivider-hi6220.o clk-hisi-phase.o > > obj-$(CONFIG_ARCH_HI3xxx) += clk-hi3620.o > obj-$(CONFIG_ARCH_HIP04) += clk-hip04.o > diff --git a/drivers/clk/hisilicon/clk-hisi-phase.c b/drivers/clk/hisilicon/clk-hisi-phase.c > new file mode 100644 > index 0000000..436f0a1 > --- /dev/null > +++ b/drivers/clk/hisilicon/clk-hisi-phase.c > @@ -0,0 +1,117 @@ > +/* > + * Copyright (c) 2017 HiSilicon Technologies Co., Ltd. > + * > + * 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. > + * > + * Simple HiSilicon phase clock implementation. > + */ > +#include > +#include > +#include > +#include > +#include > +#include "clk.h" > + > +struct clk_hisi_phase { > + struct clk_hw hw; > + void __iomem *reg; > + u32 *phase_values; > + u32 *phase_regs; > + u8 phase_num; I do not think this value-reg table is necessary, as the register value maps to phase degree in a way that is easy for programming, i.e. degree increases 45 with register value increases one. > + u32 mask; > + u8 shift; > + u8 flags; > + spinlock_t *lock; > +}; Have a newline here. > +#define to_clk_hisi_phase(_hw) container_of(_hw, struct clk_hisi_phase, hw) > + > +static u32 hisi_clk_get_phase_reg(struct clk_hisi_phase *phase, int degrees) > +{ > + int i; > + > + for (i = 0; i < phase->phase_num; i++) > + if (phase->phase_values[i] == degrees) > + return phase->phase_regs[i]; > + > + return -EINVAL; > +} > + > +static int hisi_clk_set_phase(struct clk_hw *hw, int degrees) > +{ > + struct clk_hisi_phase *phase = to_clk_hisi_phase(hw); > + u32 val, phase_reg; > + unsigned long flags = 0; > + > + phase_reg = hisi_clk_get_phase_reg(phase, degrees); > + if (phase_reg < 0) > + return phase_reg; > + > + if (phase->lock) > + spin_lock_irqsave(phase->lock, flags); > + else > + __acquire(phase->lock); > + > + val = clk_readl(phase->reg); > + val &= ~(phase->mask << phase->shift); > + val |= phase_reg << phase->shift; > + clk_writel(val, phase->reg); > + > + if (phase->lock) > + spin_unlock_irqrestore(phase->lock, flags); > + else > + __release(phase->lock); > + > + return 0; > +} > + > +const struct clk_ops clk_phase_ops = { > + .set_phase = hisi_clk_set_phase, > +}; > + > +void clk_unregister_hisi_phase(struct clk *clk) > +{ > + struct clk_hisi_phase *phase; > + struct clk_hw *hw; > + > + hw = __clk_get_hw(clk); > + if (!hw) > + return; > + > + phase = to_clk_hisi_phase(hw); > + clk_unregister(clk); > +} > +EXPORT_SYMBOL_GPL(clk_unregister_hisi_phase); If there no reason that this unregister function need to be before register function, I would suggest you put it after register function, so that you are consistent with other register/unregister function pair like hisi_clk_register[unregister]_phase() etc. Shawn > + > +struct clk *clk_register_hisi_phase(struct device *dev, > + const struct hisi_phase_clock *clks, > + void __iomem *base, spinlock_t *lock) > +{ > + struct clk_hisi_phase *phase; > + struct clk *clk; > + struct clk_init_data init; > + > + phase = devm_kzalloc(dev, sizeof(struct clk_hisi_phase), GFP_KERNEL); > + if (!phase) > + return ERR_PTR(-ENOMEM); > + > + init.name = clks->name; > + init.ops = &clk_phase_ops; > + init.flags = clks->flags | CLK_IS_BASIC; > + init.parent_names = clks->parent_names ? &clks->parent_names : NULL; > + init.num_parents = clks->parent_names ? 1 : 0; > + > + phase->reg = base + clks->offset; > + phase->shift = clks->shift; > + phase->mask = BIT(clks->width) - 1; > + phase->lock = lock; > + phase->phase_values = clks->phase_values; > + phase->phase_regs = clks->phase_regs; > + phase->phase_num = clks->phase_num; > + phase->hw.init = &init; > + > + clk = clk_register(NULL, &phase->hw); > + return clk; > +} > +EXPORT_SYMBOL_GPL(clk_register_hisi_phase); > diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c > index b73c1df..e3adfad 100644 > --- a/drivers/clk/hisilicon/clk.c > +++ b/drivers/clk/hisilicon/clk.c > @@ -197,6 +197,51 @@ int hisi_clk_register_mux(const struct hisi_mux_clock *clks, > } > EXPORT_SYMBOL_GPL(hisi_clk_register_mux); > > +int hisi_clk_register_phase(struct device *dev, > + const struct hisi_phase_clock *clks, > + int nums, struct hisi_clock_data *data) > +{ > + int i; > + struct clk *clk; > + void __iomem *base = data->base; > + > + for (i = 0; i < nums; i++) { > + clk = clk_register_hisi_phase(dev, > + &clks[i], base, &hisi_clk_lock); > + > + if (IS_ERR(clk)) { > + pr_err("%s: failed to register clock %s\n", > + __func__, clks[i].name); > + goto err; > + } > + > + data->clk_data.clks[clks[i].id] = clk; > + } > + return 0; > + > +err: > + while (i--) > + clk_unregister_hisi_phase(data->clk_data.clks[clks[i].id]); > + > + return PTR_ERR(clk); > +} > +EXPORT_SYMBOL_GPL(hisi_clk_register_phase); > + > +void hisi_clk_unregister_phase(const struct hisi_phase_clock *clks, > + int nums, struct hisi_clock_data *data) > +{ > + struct clk **clocks = data->clk_data.clks; > + int i, id; > + > + for (i = 0; i < nums; i++) { > + id = clks[i].id; > + > + if (clocks[id]) > + clk_unregister_hisi_phase(clocks[id]); > + } > +} > +EXPORT_SYMBOL_GPL(hisi_clk_unregister_phase); > + > int hisi_clk_register_divider(const struct hisi_divider_clock *clks, > int nums, struct hisi_clock_data *data) > { > diff --git a/drivers/clk/hisilicon/clk.h b/drivers/clk/hisilicon/clk.h > index 4e1d1af..bc18730 100644 > --- a/drivers/clk/hisilicon/clk.h > +++ b/drivers/clk/hisilicon/clk.h > @@ -68,6 +68,19 @@ struct hisi_mux_clock { > const char *alias; > }; > > +struct hisi_phase_clock { > + unsigned int id; > + const char *name; > + const char *parent_names; > + unsigned long flags; > + unsigned long offset; > + u8 shift; > + u8 width; > + u32 *phase_values; > + u32 *phase_regs; > + u8 phase_num; > +}; > + > struct hisi_divider_clock { > unsigned int id; > const char *name; > @@ -120,6 +133,15 @@ int hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *, > int, struct hisi_clock_data *); > int hisi_clk_register_mux(const struct hisi_mux_clock *, int, > struct hisi_clock_data *); > +struct clk *clk_register_hisi_phase(struct device *dev, > + const struct hisi_phase_clock *clks, > + void __iomem *base, spinlock_t *lock); > +void clk_unregister_hisi_phase(struct clk *clk); > +int hisi_clk_register_phase(struct device *dev, > + const struct hisi_phase_clock *clks, > + int nums, struct hisi_clock_data *data); > +void hisi_clk_unregister_phase(const struct hisi_phase_clock *clks, > + int nums, struct hisi_clock_data *data); > int hisi_clk_register_divider(const struct hisi_divider_clock *, > int, struct hisi_clock_data *); > int hisi_clk_register_gate(const struct hisi_gate_clock *, > -- > 2.7.4 > From 1581601566268227643@xxx Wed Oct 18 13:19:52 +0000 2017 X-GM-THRID: 1581601566268227643 X-Gmail-Labels: Inbox,Category Forums