From patchwork Wed Nov 19 23:15:29 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: James Hogan X-Patchwork-Id: 41215 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ee0-f71.google.com (mail-ee0-f71.google.com [74.125.83.71]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 761ED20CBB for ; Wed, 19 Nov 2014 23:16:22 +0000 (UTC) Received: by mail-ee0-f71.google.com with SMTP id c13sf1325494eek.10 for ; Wed, 19 Nov 2014 15:16:21 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe:content-type :content-transfer-encoding; bh=eEh9IlRfSnNXnmx+avwNxqfA9agi7KjI4IniZCRl2IA=; b=fvuPp7zcwOxuC1ynX0CGWZQ0jSFnEVqy+pfFtVupus2MqSW7n1ZW6BtkzoSm2sCbSE k3hCEOd0KcFhpE8HsgHjbgWi78Lj6GIBPttA9D5N0Wrg20ZhwR/wyBm8DhiOvwVdWlJk tsOQzL+vL1yAXpdzADlpuiKJ+0cmrMhE6g05m6G8xXQ931SE05iYfy9qZzfGPVXkPXub pdMxdA9xBFqtX0PzEFHx/ykFIHcEebKJ7ixDw96S/lhIR0+NKlJ2QpBoAOzpW685NUtl Xqu5lH3bBWeCzyOVrq8DdSKM+3c9Sg0tPRUBznav3PFmTO6lz2+aUNeLo+qVIgX7Bo/N nJRA== X-Gm-Message-State: ALoCoQmeL27FgFRiR63PA8YsUMFob9AmVy/bu7m+AWm1EhFJFHH8M9oP7sqeWqr/Eq12mX5Wkt1Y X-Received: by 10.181.13.80 with SMTP id ew16mr1552096wid.4.1416438981705; Wed, 19 Nov 2014 15:16:21 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.207.9 with SMTP id ls9ls1425688lac.44.gmail; Wed, 19 Nov 2014 15:16:21 -0800 (PST) X-Received: by 10.152.10.67 with SMTP id g3mr8047853lab.59.1416438981498; Wed, 19 Nov 2014 15:16:21 -0800 (PST) Received: from mail-la0-f47.google.com (mail-la0-f47.google.com. [209.85.215.47]) by mx.google.com with ESMTPS id p10si456539lap.125.2014.11.19.15.16.21 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 19 Nov 2014 15:16:21 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.47 as permitted sender) client-ip=209.85.215.47; Received: by mail-la0-f47.google.com with SMTP id hz20so1407959lab.6 for ; Wed, 19 Nov 2014 15:16:21 -0800 (PST) X-Received: by 10.112.135.229 with SMTP id pv5mr7901030lbb.52.1416438981379; Wed, 19 Nov 2014 15:16:21 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.184.201 with SMTP id ew9csp179173lbc; Wed, 19 Nov 2014 15:16:20 -0800 (PST) X-Received: by 10.68.239.71 with SMTP id vq7mr23829495pbc.155.1416438979628; Wed, 19 Nov 2014 15:16:19 -0800 (PST) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id yg1si550448pbc.115.2014.11.19.15.16.18 for ; Wed, 19 Nov 2014 15:16:19 -0800 (PST) Received-SPF: none (google.com: linux-kernel-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757057AbaKSXQJ (ORCPT + 26 others); Wed, 19 Nov 2014 18:16:09 -0500 Received: from mail-wi0-f182.google.com ([209.85.212.182]:39404 "EHLO mail-wi0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755822AbaKSXQB (ORCPT ); Wed, 19 Nov 2014 18:16:01 -0500 Received: by mail-wi0-f182.google.com with SMTP id h11so3521358wiw.3 for ; Wed, 19 Nov 2014 15:15:57 -0800 (PST) X-Received: by 10.180.19.164 with SMTP id g4mr17675971wie.51.1416438957728; Wed, 19 Nov 2014 15:15:57 -0800 (PST) Received: from radagast.localdomain (jahogan.plus.com. [212.159.75.221]) by mx.google.com with ESMTPSA id gi5sm797884wjd.26.2014.11.19.15.15.55 for (version=TLSv1.2 cipher=AES128-GCM-SHA256 bits=128/128); Wed, 19 Nov 2014 15:15:56 -0800 (PST) From: James Hogan To: Mike Turquette , linux-metag@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Cc: James Hogan , =?UTF-8?q?Emilio=20L=C3=B3pez?= , Sascha Hauer , Shawn Guo , Tero Kristo , linux-omap@vger.kernel.org, linux-rockchip@lists.infradead.org Subject: [PATCH 01/15] clk: divider: replace bitfield width with mask Date: Wed, 19 Nov 2014 23:15:29 +0000 Message-Id: <1416438943-11429-2-git-send-email-james.hogan@imgtec.com> X-Mailer: git-send-email 2.0.4 In-Reply-To: <1416438943-11429-1-git-send-email-james.hogan@imgtec.com> References: <1416438943-11429-1-git-send-email-james.hogan@imgtec.com> MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: james.hogan@imgtec.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.47 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , From: Mike Turquette The forthcoming Device Tree binding for the divider clock type will use a bitfield mask instead of bitfield width, which is what the current basic divider implementation uses. This patch replaces the u8 width in struct clk_divider with a u32 mask. The divider code is updated to use the bit mask internally but the two registration functions still accept the width to maintain compatibility with existing users. Also updated in this patch is the clk-private.h divider macro and various clock divider implementations that are based on struct clk_divider. Signed-off-by: Mike Turquette [james.hogan@imgtec.com: forward port, fix new uses of width] Signed-off-by: James Hogan Tested-by: Shawn Guo Tested-by: Heiko Stuebner Reviewed-by: Heiko Stuebner Cc: "Emilio López" Cc: Sascha Hauer Cc: Shawn Guo Cc: Tero Kristo Cc: linux-omap@vger.kernel.org Cc: linux-rockchip@lists.infradead.org --- Changes since original: - Forward ported - Adjust new div_mask from recent patch "clk-divider: Fix READ_ONLY when divider > 1" - Updated assignment of clk_divider::width in imx, rockchip, st, sunxi, ti clock components to use mask instead (not tested), using the following semantic patch: virtual context virtual patch @depends on context@ struct clk_divider clk; expression e; @@ *clk.width = e @depends on patch@ struct clk_divider clk; expression e; @@ -clk.width = fls(e) +clk.mask = e @depends on patch@ struct clk_divider *clk; expression e; @@ -clk->width = fls(e) +clk->mask = e @depends on patch@ struct clk_divider clk; expression e; @@ -clk.width = e +clk.mask = BIT(e) - 1 @depends on patch@ struct clk_divider *clk; expression e; @@ -clk->width = e +clk->mask = BIT(e) - 1 --- arch/arm/mach-imx/clk-busy.c | 2 +- arch/arm/mach-imx/clk-fixup-div.c | 2 +- drivers/clk/clk-divider.c | 33 ++++++++++++++++----------------- drivers/clk/mxs/clk-div.c | 2 +- drivers/clk/rockchip/clk.c | 2 +- drivers/clk/st/clk-flexgen.c | 4 ++-- drivers/clk/st/clkgen-mux.c | 4 ++-- drivers/clk/st/clkgen-pll.c | 2 +- drivers/clk/sunxi/clk-sunxi.c | 2 +- drivers/clk/ti/divider.c | 2 +- include/linux/clk-private.h | 2 +- include/linux/clk-provider.h | 2 +- 12 files changed, 29 insertions(+), 30 deletions(-) diff --git a/arch/arm/mach-imx/clk-busy.c b/arch/arm/mach-imx/clk-busy.c index 4bb1bc4..bc88e38 100644 --- a/arch/arm/mach-imx/clk-busy.c +++ b/arch/arm/mach-imx/clk-busy.c @@ -95,7 +95,7 @@ struct clk *imx_clk_busy_divider(const char *name, const char *parent_name, busy->div.reg = reg; busy->div.shift = shift; - busy->div.width = width; + busy->div.mask = BIT(width) - 1; busy->div.lock = &imx_ccm_lock; busy->div_ops = &clk_divider_ops; diff --git a/arch/arm/mach-imx/clk-fixup-div.c b/arch/arm/mach-imx/clk-fixup-div.c index 21db020..af33b7a 100644 --- a/arch/arm/mach-imx/clk-fixup-div.c +++ b/arch/arm/mach-imx/clk-fixup-div.c @@ -115,7 +115,7 @@ struct clk *imx_clk_fixup_divider(const char *name, const char *parent, fixup_div->divider.reg = reg; fixup_div->divider.shift = shift; - fixup_div->divider.width = width; + fixup_div->divider.mask = BIT(width) - 1; fixup_div->divider.lock = &imx_ccm_lock; fixup_div->divider.hw.init = &init; fixup_div->ops = &clk_divider_ops; diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index c0a842b..a432cf8 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -30,8 +30,6 @@ #define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw) -#define div_mask(d) ((1 << ((d)->width)) - 1) - static unsigned int _get_table_maxdiv(const struct clk_div_table *table) { unsigned int maxdiv = 0; @@ -57,12 +55,12 @@ static unsigned int _get_table_mindiv(const struct clk_div_table *table) static unsigned int _get_maxdiv(struct clk_divider *divider) { if (divider->flags & CLK_DIVIDER_ONE_BASED) - return div_mask(divider); + return divider->mask; if (divider->flags & CLK_DIVIDER_POWER_OF_TWO) - return 1 << div_mask(divider); + return 1 << divider->mask; if (divider->table) return _get_table_maxdiv(divider->table); - return div_mask(divider) + 1; + return divider->mask + 1; } static unsigned int _get_table_div(const struct clk_div_table *table, @@ -116,7 +114,7 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw, unsigned int div, val; val = clk_readl(divider->reg) >> divider->shift; - val &= div_mask(divider); + val &= divider->mask; div = _get_div(divider, val); if (!div) { @@ -266,7 +264,7 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, /* if read only, just return current value */ if (divider->flags & CLK_DIVIDER_READ_ONLY) { bestdiv = readl(divider->reg) >> divider->shift; - bestdiv &= div_mask(divider); + bestdiv &= divider->mask; bestdiv = _get_div(divider, bestdiv); return bestdiv; } @@ -341,17 +339,17 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, value = _get_val(divider, div); - if (value > div_mask(divider)) - value = div_mask(divider); + if (value > divider->mask) + value = divider->mask; if (divider->lock) spin_lock_irqsave(divider->lock, flags); if (divider->flags & CLK_DIVIDER_HIWORD_MASK) { - val = div_mask(divider) << (divider->shift + 16); + val = divider->mask << (divider->shift + 16); } else { val = clk_readl(divider->reg); - val &= ~(div_mask(divider) << divider->shift); + val &= ~(divider->mask << divider->shift); } val |= value << divider->shift; clk_writel(val, divider->reg); @@ -371,7 +369,7 @@ EXPORT_SYMBOL_GPL(clk_divider_ops); static struct clk *_register_divider(struct device *dev, const char *name, const char *parent_name, unsigned long flags, - void __iomem *reg, u8 shift, u8 width, + void __iomem *reg, u8 shift, u32 mask, u8 clk_divider_flags, const struct clk_div_table *table, spinlock_t *lock) { @@ -380,8 +378,9 @@ static struct clk *_register_divider(struct device *dev, const char *name, struct clk_init_data init; if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) { - if (width + shift > 16) { - pr_warn("divider value exceeds LOWORD field\n"); + if ((mask << shift) & 0xffff0000) { + pr_warn("%s: divider value exceeds LOWORD field\n", + __func__); return ERR_PTR(-EINVAL); } } @@ -402,7 +401,7 @@ static struct clk *_register_divider(struct device *dev, const char *name, /* struct clk_divider assignments */ div->reg = reg; div->shift = shift; - div->width = width; + div->mask = mask; div->flags = clk_divider_flags; div->lock = lock; div->hw.init = &init; @@ -435,7 +434,7 @@ struct clk *clk_register_divider(struct device *dev, const char *name, u8 clk_divider_flags, spinlock_t *lock) { return _register_divider(dev, name, parent_name, flags, reg, shift, - width, clk_divider_flags, NULL, lock); + ((1 << width) - 1), clk_divider_flags, NULL, lock); } EXPORT_SYMBOL_GPL(clk_register_divider); @@ -460,6 +459,6 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name, spinlock_t *lock) { return _register_divider(dev, name, parent_name, flags, reg, shift, - width, clk_divider_flags, table, lock); + ((1 << width) - 1), clk_divider_flags, table, lock); } EXPORT_SYMBOL_GPL(clk_register_divider_table); diff --git a/drivers/clk/mxs/clk-div.c b/drivers/clk/mxs/clk-div.c index 90e1da9..af2428e 100644 --- a/drivers/clk/mxs/clk-div.c +++ b/drivers/clk/mxs/clk-div.c @@ -96,7 +96,7 @@ struct clk *mxs_clk_div(const char *name, const char *parent_name, div->divider.reg = reg; div->divider.shift = shift; - div->divider.width = width; + div->divider.mask = BIT(width) - 1; div->divider.flags = CLK_DIVIDER_ONE_BASED; div->divider.lock = &mxs_lock; div->divider.hw.init = &init; diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index 880a266..9024a0e 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -87,7 +87,7 @@ static struct clk *rockchip_clk_register_branch(const char *name, div->flags = div_flags; div->reg = base + muxdiv_offset; div->shift = div_shift; - div->width = div_width; + div->mask = BIT(div_width) - 1; div->lock = lock; div->table = div_table; div_ops = &clk_divider_ops; diff --git a/drivers/clk/st/clk-flexgen.c b/drivers/clk/st/clk-flexgen.c index 2282cef..603d5d6 100644 --- a/drivers/clk/st/clk-flexgen.c +++ b/drivers/clk/st/clk-flexgen.c @@ -203,7 +203,7 @@ struct clk *clk_register_flexgen(const char *name, /* Pre-divider config */ fgxbar->pdiv.lock = lock; fgxbar->pdiv.reg = reg + 0x58 + idx * 4; - fgxbar->pdiv.width = 10; + fgxbar->pdiv.mask = BIT(10) - 1; /* Final divider's gate config */ fgxbar->fgate.lock = lock; @@ -213,7 +213,7 @@ struct clk *clk_register_flexgen(const char *name, /* Final divider config */ fgxbar->fdiv.lock = lock; fgxbar->fdiv.reg = fdiv_reg; - fgxbar->fdiv.width = 6; + fgxbar->fdiv.mask = BIT(6) - 1; fgxbar->hw.init = &init; diff --git a/drivers/clk/st/clkgen-mux.c b/drivers/clk/st/clkgen-mux.c index 79dc40b..85a1165 100644 --- a/drivers/clk/st/clkgen-mux.c +++ b/drivers/clk/st/clkgen-mux.c @@ -260,7 +260,7 @@ struct clk *clk_register_genamux(const char *name, * Divider config for each input */ void __iomem *divbase = reg + muxdata->div_offsets[i]; - genamux->div[i].width = divider_width; + genamux->div[i].mask = BIT(divider_width) - 1; genamux->div[i].reg = divbase + (idx * sizeof(u32)); /* @@ -773,7 +773,7 @@ void __init st_of_clkgen_vcc_setup(struct device_node *np) div->reg = reg + VCC_DIV_OFFSET; div->shift = 2 * i; - div->width = 2; + div->mask = BIT(2) - 1; div->flags = CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_ROUND_CLOSEST; diff --git a/drivers/clk/st/clkgen-pll.c b/drivers/clk/st/clkgen-pll.c index 29769d7..0d76278 100644 --- a/drivers/clk/st/clkgen-pll.c +++ b/drivers/clk/st/clkgen-pll.c @@ -575,7 +575,7 @@ static struct clk * __init clkgen_odf_register(const char *parent_name, div->flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO; div->reg = reg + pll_data->odf[odf].offset; div->shift = pll_data->odf[odf].shift; - div->width = fls(pll_data->odf[odf].mask); + div->mask = pll_data->odf[odf].mask; div->lock = odf_lock; clk = clk_register_composite(NULL, odf_name, &parent_name, 1, diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index d5dc951..a23d393 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -1015,7 +1015,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node, divider->reg = reg; divider->shift = data->div[i].shift; - divider->width = SUNXI_DIVISOR_WIDTH; + divider->mask = BIT(SUNXI_DIVISOR_WIDTH) - 1; divider->flags = flags; divider->lock = &clk_lock; divider->table = data->div[i].table; diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c index bff2b5b..c27e01e 100644 --- a/drivers/clk/ti/divider.c +++ b/drivers/clk/ti/divider.c @@ -285,7 +285,7 @@ static struct clk *_register_divider(struct device *dev, const char *name, /* struct clk_divider assignments */ div->reg = reg; div->shift = shift; - div->width = width; + div->mask = BIT(width) - 1; div->flags = clk_divider_flags; div->lock = lock; div->hw.init = &init; diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h index 0ca5f60..40bc1b2 100644 --- a/include/linux/clk-private.h +++ b/include/linux/clk-private.h @@ -130,7 +130,7 @@ struct clk { }, \ .reg = _reg, \ .shift = _shift, \ - .width = _width, \ + .mask = ((1 << _width) - 1), \ .flags = _divider_flags, \ .table = _table, \ .lock = _lock, \ diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 2839c63..2c00215 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -338,7 +338,7 @@ struct clk_divider { struct clk_hw hw; void __iomem *reg; u8 shift; - u8 width; + u32 mask; u8 flags; const struct clk_div_table *table; spinlock_t *lock;