From patchwork Wed Oct 31 03:06:55 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 1675671 Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 7692C3FD2B for ; Wed, 31 Oct 2012 03:06:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757994Ab2JaDG4 (ORCPT ); Tue, 30 Oct 2012 23:06:56 -0400 Received: from mail-pa0-f46.google.com ([209.85.220.46]:43417 "EHLO mail-pa0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755804Ab2JaDG4 (ORCPT ); Tue, 30 Oct 2012 23:06:56 -0400 Received: by mail-pa0-f46.google.com with SMTP id hz1so627185pad.19 for ; Tue, 30 Oct 2012 20:06:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:sender:message-id:to:cc:in-reply-to:references:from:subject :mime-version:content-type; bh=PprIxQRyoBF4s9zZ/GRBnSt69Sy42Y6yF0FizPU6AXc=; b=ezKwMPtEKZ36QWJagTsqsjXYJm/H7lLy5fjZzOdEMlie6eDQvI5Ym048dp5FFM7KL4 tfA9sapa3MwmLn5qxwJK5FDxDKchVSi/0/58/XoADwEOAutHakOoI8D+4yMQwPp79DFh GxcKAFdxrKeOmbNKfEYvgRFJx4mCGX/BQi2LD1B7/IoHfRfVwVuGDv3QP4wTE/iUALv4 U9A0VuhMWTdO5oVsRilY/DpYf7wr5VEJp9oPEVycpqKEq3N3t0K8SYIVz9nfa6tbtdS+ mi1U5Z2ZdJUC2ZvBON/ZTDsuJNuzFJuwtidJOxWncXEIo5Q3a6KoUcdqaUECaSh6Ne9g HOJg== Received: by 10.66.77.74 with SMTP id q10mr97907284paw.81.1351652815743; Tue, 30 Oct 2012 20:06:55 -0700 (PDT) Received: from morimoto-Dell-XPS420.gmail.com (49.14.32.202.bf.2iij.net. [202.32.14.49]) by mx.google.com with ESMTPS id sa2sm1528893pbc.4.2012.10.30.20.06.53 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 30 Oct 2012 20:06:55 -0700 (PDT) Date: Tue, 30 Oct 2012 20:06:55 -0700 (PDT) Message-ID: <87hapbmjar.wl%kuninori.morimoto.gx@renesas.com> To: Paul , Simon Cc: Magnus , linux-sh@vger.kernel.org, Kuninori Morimoto In-Reply-To: <87ip9rmjcb.wl%kuninori.morimoto.gx@renesas.com> References: <87ip9rmjcb.wl%kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto Subject: [PATCH 1/3] sh: clkfwk: add sh_clk_fsidiv_register() MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org This patch adds sh_clk_fsidiv_register() to share FSI-DIV clock code Signed-off-by: Kuninori Morimoto --- drivers/sh/clk/cpg.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/sh_clk.h | 9 +++++ 2 files changed, 95 insertions(+) diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c index fe6dbef..b05e543 100644 --- a/drivers/sh/clk/cpg.c +++ b/drivers/sh/clk/cpg.c @@ -368,3 +368,89 @@ int __init sh_clk_div4_reparent_register(struct clk *clks, int nr, return sh_clk_div_register_ops(clks, nr, table, &sh_clk_div4_reparent_clk_ops); } + +/* FSI-DIV */ +static unsigned long fsidiv_recalc(struct clk *clk) +{ + u32 value; + + value = __raw_readl(clk->mapping->base); + + value >>= 16; + if (value < 2) + return clk->parent->rate; + + return clk->parent->rate / value; +} + +static long fsidiv_round_rate(struct clk *clk, unsigned long rate) +{ + return clk_rate_div_range_round(clk, 1, 0xffff, rate); +} + +static void fsidiv_disable(struct clk *clk) +{ + __raw_writel(0, clk->mapping->base); +} + +static int fsidiv_enable(struct clk *clk) +{ + u32 value; + + value = __raw_readl(clk->mapping->base) >> 16; + if (value < 2) + return 0; + + __raw_writel((value << 16) | 0x3, clk->mapping->base); + + return 0; +} + +static int fsidiv_set_rate(struct clk *clk, unsigned long rate) +{ + u32 val; + int idx; + + idx = (clk->parent->rate / rate) & 0xffff; + if (idx < 2) + __raw_writel(0, clk->mapping->base); + else + __raw_writel(idx << 16, clk->mapping->base); + + return 0; +} + +static struct sh_clk_ops fsidiv_clk_ops = { + .recalc = fsidiv_recalc, + .round_rate = fsidiv_round_rate, + .set_rate = fsidiv_set_rate, + .enable = fsidiv_enable, + .disable = fsidiv_disable, +}; + +int __init sh_clk_fsidiv_register(struct clk *clks, int nr) +{ + struct clk_mapping *map; + int i; + + for (i = 0; i < nr; i++) { + + map = kzalloc(sizeof(struct clk_mapping), GFP_KERNEL); + if (!map) { + pr_err("%s: unable to alloc memory\n", __func__); + return -ENOMEM; + } + + /* clks[i].enable_reg came from SH_CLK_FSIDIV() */ + map->phys = (phys_addr_t)clks[i].enable_reg; + map->len = 8; + + clks[i].enable_reg = 0; /* remove .enable_reg */ + clks[i].ops = &fsidiv_clk_ops; + clks[i].mapping = map; + + clk_register(&clks[i]); + } + + return 0; +} diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h index 5091091..60c7239 100644 --- a/include/linux/sh_clk.h +++ b/include/linux/sh_clk.h @@ -199,4 +199,13 @@ int sh_clk_div6_reparent_register(struct clk *clks, int nr); #define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk } #define CLKDEV_ICK_ID(_cid, _did, _clk) { .con_id = _cid, .dev_id = _did, .clk = _clk } +/* .enable_reg will be updated to .mapping on sh_clk_fsidiv_register() */ +#define SH_CLK_FSIDIV(_reg, _parent) \ +{ \ + .enable_reg = (void __iomem *)_reg, \ + .parent = _parent, \ +} + +int sh_clk_fsidiv_register(struct clk *clks, int nr); + #endif /* __SH_CLOCK_H */