From: mturquette@linaro.org (Mike Turquette)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 5/5] clk: add a fixed factor clock
Date: Sun, 6 May 2012 22:08:30 -0700 [thread overview]
Message-ID: <1336367310-5140-6-git-send-email-mturquette@linaro.org> (raw)
In-Reply-To: <1336367310-5140-1-git-send-email-mturquette@linaro.org>
From: Sascha Hauer <s.hauer@pengutronix.de>
Having fixed factors/dividers in hardware is a common pattern, so
add a basic clock type doing this. It basically describes a fixed
factor clock using a nominator and a denominator.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Viresh Kumar <viresh.kumar@st.com>
[mturquette at linaro.org: constify parent_names in static init macro]
[mturquette at linaro.org: copy/paste bug from mux in static init macro]
[mturquette at linaro.org: fix error handling in clk_register_fixed_factor]
Signed-off-by: Mike Turquette <mturquette@linaro.org>
---
drivers/clk/Makefile | 2 +-
drivers/clk/clk-fixed-factor.c | 95 ++++++++++++++++++++++++++++++++++++++++
include/linux/clk-private.h | 20 ++++++++
include/linux/clk-provider.h | 23 ++++++++++
4 files changed, 139 insertions(+), 1 deletions(-)
create mode 100644 drivers/clk/clk-fixed-factor.c
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 1f736bc..24aa714 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -1,4 +1,4 @@
obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o
obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed-rate.o clk-gate.o \
- clk-mux.o clk-divider.o
+ clk-mux.o clk-divider.o clk-fixed-factor.o
diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
new file mode 100644
index 0000000..1f2da01
--- /dev/null
+++ b/drivers/clk/clk-fixed-factor.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ *
+ * 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.
+ *
+ * Standard functionality for the common clock API.
+ */
+#include <linux/module.h>
+#include <linux/clk-provider.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+
+/*
+ * DOC: basic fixed multiplier and divider clock that cannot gate
+ *
+ * Traits of this clock:
+ * prepare - clk_prepare only ensures that parents are prepared
+ * enable - clk_enable only ensures that parents are enabled
+ * rate - rate is fixed. clk->rate = parent->rate / div * mult
+ * parent - fixed parent. No clk_set_parent support
+ */
+
+#define to_clk_fixed_factor(_hw) container_of(_hw, struct clk_fixed_factor, hw)
+
+static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_fixed_factor *fix = to_clk_fixed_factor(hw);
+
+ return (parent_rate / fix->div) * fix->mult;
+}
+
+static long clk_factor_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ struct clk_fixed_factor *fix = to_clk_fixed_factor(hw);
+
+ if (__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT) {
+ unsigned long best_parent;
+
+ best_parent = (rate / fix->mult) * fix->div;
+ *prate = __clk_round_rate(__clk_get_parent(hw->clk),
+ best_parent);
+ }
+
+ return (*prate / fix->div) * fix->mult;
+}
+
+static int clk_factor_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ return 0;
+}
+
+struct clk_ops clk_fixed_factor_ops = {
+ .round_rate = clk_factor_round_rate,
+ .set_rate = clk_factor_set_rate,
+ .recalc_rate = clk_factor_recalc_rate,
+};
+EXPORT_SYMBOL_GPL(clk_fixed_factor_ops);
+
+struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
+ const char *parent_name, unsigned long flags,
+ unsigned int mult, unsigned int div)
+{
+ struct clk_fixed_factor *fix;
+ struct clk_init_data init;
+ struct clk *clk;
+
+ fix = kmalloc(sizeof(*fix), GFP_KERNEL);
+ if (!fix) {
+ pr_err("%s: could not allocate fixed factor clk\n", __func__);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ /* struct clk_fixed_factor assignments */
+ fix->mult = mult;
+ fix->div = div;
+ fix->hw.init = &init;
+
+ init.name = name;
+ init.ops = &clk_fixed_factor_ops;
+ init.flags = flags;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ clk = clk_register(dev, &fix->hw);
+
+ if (IS_ERR(clk))
+ kfree(fix);
+
+ return clk;
+}
diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h
index b258532..eb3f84b 100644
--- a/include/linux/clk-private.h
+++ b/include/linux/clk-private.h
@@ -143,6 +143,26 @@ struct clk {
DEFINE_CLK(_name, clk_mux_ops, _flags, _parent_names, \
_parents);
+#define DEFINE_CLK_FIXED_FACTOR(_name, _parent_name, \
+ _parent_ptr, _flags, \
+ _mult, _div) \
+ static struct clk _name; \
+ static const char *_name##_parent_names[] = { \
+ _parent_name, \
+ }; \
+ static struct clk *_name##_parents[] = { \
+ _parent_ptr, \
+ }; \
+ static struct clk_fixed_factor _name##_hw = { \
+ .hw = { \
+ .clk = &_name, \
+ }, \
+ .mult = _mult, \
+ .div = _div, \
+ }; \
+ DEFINE_CLK(_name, clk_fixed_factor_ops, _flags, \
+ _name##_parent_names, _name##_parents);
+
/**
* __clk_init - initialize the data structures in a struct clk
* @dev: device initializing this clk, placeholder for now
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 5db3412..c1c23b9 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -277,6 +277,29 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
u8 clk_mux_flags, spinlock_t *lock);
/**
+ * struct clk_fixed_factor - fixed multiplier and divider clock
+ *
+ * @hw: handle between common and hardware-specific interfaces
+ * @mult: multiplier
+ * @div: divider
+ *
+ * Clock with a fixed multiplier and divider. The output frequency is the
+ * parent clock rate divided by div and multiplied by mult.
+ * Implements .recalc_rate, .set_rate and .round_rate
+ */
+
+struct clk_fixed_factor {
+ struct clk_hw hw;
+ unsigned int mult;
+ unsigned int div;
+};
+
+extern struct clk_ops clk_fixed_factor_ops;
+struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
+ const char *parent_name, unsigned long flags,
+ unsigned int mult, unsigned int div);
+
+/**
* clk_register - allocate a new clock, register it and return an opaque cookie
* @dev: device that is registering this clock
* @hw: link to hardware-specific clock data
--
1.7.5.4
next prev parent reply other threads:[~2012-05-07 5:08 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-05-07 5:08 [PATCH 0/5] more clk-next fixes Mike Turquette
2012-05-07 5:08 ` [PATCH 1/5] MAINTAINERS: add entry for common clk framework Mike Turquette
2012-05-07 5:08 ` [PATCH 2/5] clk: prevent spurious parent rate propagation Mike Turquette
2012-05-07 7:58 ` Sascha Hauer
2012-05-07 17:34 ` Turquette, Mike
2012-05-07 5:08 ` [PATCH 3/5] clk: remove COMMON_CLK_DISABLE_UNUSED Mike Turquette
2012-05-07 19:31 ` Saravana Kannan
2012-05-07 5:08 ` [PATCH 4/5] clk: mux: assign init data Mike Turquette
2012-05-07 5:08 ` Mike Turquette [this message]
2012-05-07 19:54 ` [PATCH 5/5] clk: add a fixed factor clock Saravana Kannan
2012-05-07 20:14 ` Turquette, Mike
2012-05-07 20:26 ` Saravana Kannan
2012-05-08 7:20 ` [PATCH 0/5] more clk-next fixes Andrew Lunn
2012-05-08 16:12 ` Shawn Guo
2012-05-08 17:33 ` Turquette, Mike
2012-05-08 21:35 ` Turquette, Mike
2012-05-11 14:39 ` Arnd Bergmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1336367310-5140-6-git-send-email-mturquette@linaro.org \
--to=mturquette@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).