From: Chao Xie <chao.xie@marvell.com>
To: haojian.zhuang@gmail.com, mturquette@linaro.org,
chao.xie@marvell.com, xiechao_mail@163.com,
linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH 07/12] clk: mmp: add clock type composite for mix
Date: Tue, 10 Jun 2014 09:27:43 +0800 [thread overview]
Message-ID: <1402363668-25806-8-git-send-email-chao.xie@marvell.com> (raw)
In-Reply-To: <1402363668-25806-1-git-send-email-chao.xie@marvell.com>
From: Chao Xie <chao.xie@marvell.com>
The general composite clock supports div/mux/gate.
marvell SOCes have many clocks that need change
div and mux together. So it need the composite
clock that supports mix/gate.
Signed-off-by: Chao Xie <chao.xie@marvell.com>
---
drivers/clk/mmp/Makefile | 3 +-
drivers/clk/mmp/clk-mix-composite.c | 195 ++++++++++++++++++++++++++++++++++++
drivers/clk/mmp/clk.h | 20 ++++
3 files changed, 217 insertions(+), 1 deletion(-)
create mode 100644 drivers/clk/mmp/clk-mix-composite.c
diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 2855f7b..2cd7d94 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -2,7 +2,8 @@
# Makefile for mmp specific clk
#
-obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o
+obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o \
+ clk-mix-composite.o
obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk-mix-composite.c b/drivers/clk/mmp/clk-mix-composite.c
new file mode 100644
index 0000000..79d5286
--- /dev/null
+++ b/drivers/clk/mmp/clk-mix-composite.c
@@ -0,0 +1,195 @@
+/*
+ * mmp mix(div and mux) clock operation source file
+ *
+ * Copyright (C) 2014 Marvell
+ * Chao Xie <chao.xie@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+#include "clk.h"
+
+#define to_clk_composite(_hw) container_of(_hw, struct mmp_clk_composite, hw)
+
+static u8 mmp_clk_composite_get_parent(struct clk_hw *hw)
+{
+ struct mmp_clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *mix_ops = composite->mix_ops;
+ struct clk_hw *mix_hw = composite->mix_hw;
+
+ mix_hw->clk = hw->clk;
+
+ return mix_ops->get_parent(mix_hw);
+}
+
+static int mmp_clk_composite_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct mmp_clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *mix_ops = composite->mix_ops;
+ struct clk_hw *mix_hw = composite->mix_hw;
+
+ mix_hw->clk = hw->clk;
+
+ return mix_ops->set_parent(mix_hw, index);
+}
+
+static int mmp_clk_composite_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct mmp_clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *mix_ops = composite->mix_ops;
+ struct clk_hw *mix_hw = composite->mix_hw;
+
+ mix_hw->clk = hw->clk;
+
+ return mix_ops->set_rate(mix_hw, rate, parent_rate);
+}
+
+static unsigned long mmp_clk_composite_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct mmp_clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *mix_ops = composite->mix_ops;
+ struct clk_hw *mix_hw = composite->mix_hw;
+
+ mix_hw->clk = hw->clk;
+
+ return mix_ops->recalc_rate(mix_hw, parent_rate);
+}
+
+static long mmp_clk_composite_determine_rate(struct clk_hw *hw,
+ unsigned long rate,
+ unsigned long *best_parent_rate,
+ struct clk **best_parent_p)
+{
+ struct mmp_clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *mix_ops = composite->mix_ops;
+ struct clk_hw *mix_hw = composite->mix_hw;
+
+ mix_hw->clk = hw->clk;
+
+ return mix_ops->determine_rate(mix_hw, rate, best_parent_rate,
+ best_parent_p);
+}
+
+static int mmp_clk_composite_set_rate_and_parent(struct clk_hw *hw,
+ unsigned long rate,
+ unsigned long parent_rate, u8 index)
+
+{
+ struct mmp_clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *mix_ops = composite->mix_ops;
+ struct clk_hw *mix_hw = composite->mix_hw;
+
+ mix_hw->clk = hw->clk;
+
+ return mix_ops->set_rate_and_parent(mix_hw, rate, parent_rate, index);
+}
+
+static int mmp_clk_composite_is_enabled(struct clk_hw *hw)
+{
+ struct mmp_clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *gate_ops = composite->gate_ops;
+ struct clk_hw *gate_hw = composite->gate_hw;
+
+ gate_hw->clk = hw->clk;
+
+ return gate_ops->is_enabled(gate_hw);
+}
+
+static int mmp_clk_composite_enable(struct clk_hw *hw)
+{
+ struct mmp_clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *gate_ops = composite->gate_ops;
+ struct clk_hw *gate_hw = composite->gate_hw;
+
+ gate_hw->clk = hw->clk;
+
+ return gate_ops->enable(gate_hw);
+}
+
+static void mmp_clk_composite_disable(struct clk_hw *hw)
+{
+ struct mmp_clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *gate_ops = composite->gate_ops;
+ struct clk_hw *gate_hw = composite->gate_hw;
+
+ gate_hw->clk = hw->clk;
+
+ gate_ops->disable(gate_hw);
+}
+
+static void mmp_clk_composite_init(struct clk_hw *hw)
+{
+ struct mmp_clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *gate_ops = composite->gate_ops;
+ struct clk_hw *gate_hw = composite->gate_hw;
+ const struct clk_ops *mix_ops = composite->mix_ops;
+ struct clk_hw *mix_hw = composite->mix_hw;
+
+ mix_hw->clk = hw->clk;
+ gate_hw->clk = hw->clk;
+
+ if (mix_ops->init)
+ mix_ops->init(mix_hw);
+ if (gate_ops->init)
+ gate_ops->init(gate_hw);
+}
+
+static struct clk_ops mmp_clk_composite_ops = {
+ .enable = mmp_clk_composite_enable,
+ .disable = mmp_clk_composite_disable,
+ .is_enabled = mmp_clk_composite_is_enabled,
+ .determine_rate = mmp_clk_composite_determine_rate,
+ .set_rate_and_parent = mmp_clk_composite_set_rate_and_parent,
+ .set_rate = mmp_clk_composite_set_rate,
+ .recalc_rate = mmp_clk_composite_recalc_rate,
+ .get_parent = mmp_clk_composite_get_parent,
+ .set_parent = mmp_clk_composite_set_parent,
+ .init = mmp_clk_composite_init,
+};
+
+struct clk *mmp_clk_register_composite(struct device *dev, const char *name,
+ const char **parent_names, int num_parents,
+ struct clk_hw *mix_hw, const struct clk_ops *mix_ops,
+ struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
+ unsigned long flags)
+{
+ struct clk *clk;
+ struct clk_init_data init;
+ struct mmp_clk_composite *composite;
+
+ if (!mix_hw || !gate_hw)
+ return ERR_PTR(-EINVAL);
+
+ composite = kzalloc(sizeof(*composite), GFP_KERNEL);
+ if (!composite) {
+ pr_err("%s: could not allocate mmp composite clk\n", __func__);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ init.name = name;
+ init.flags = flags;
+ init.parent_names = parent_names;
+ init.num_parents = num_parents;
+ init.ops = &mmp_clk_composite_ops;
+
+ composite->mix_hw = mix_hw;
+ composite->mix_ops = mix_ops;
+ composite->gate_hw = gate_hw;
+ composite->gate_ops = gate_ops;
+ composite->hw.init = &init;
+
+ clk = clk_register(dev, &composite->hw);
+ if (IS_ERR(clk))
+ kfree(composite);
+
+ return clk;
+}
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h
index 9096f0a..9827a4f 100644
--- a/drivers/clk/mmp/clk.h
+++ b/drivers/clk/mmp/clk.h
@@ -120,6 +120,26 @@ extern struct clk *mmp_clk_register_gate(struct device *dev, const char *name,
spinlock_t *lock);
+/* Clock type "composite" for mix clock */
+struct mmp_clk_composite {
+ struct clk_hw hw;
+ struct clk_ops ops;
+
+ struct clk_hw *mix_hw;
+ struct clk_hw *gate_hw;
+
+ const struct clk_ops *mix_ops;
+ const struct clk_ops *gate_ops;
+};
+
+extern struct clk *mmp_clk_register_composite(struct device *dev,
+ const char *name,
+ const char **parent_names, int num_parents,
+ struct clk_hw *mix_hw, const struct clk_ops *mix_ops,
+ struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
+ unsigned long flags);
+
+
extern struct clk *mmp_clk_register_pll2(const char *name,
const char *parent_name, unsigned long flags);
extern struct clk *mmp_clk_register_apbc(const char *name,
--
1.8.3.2
next prev parent reply other threads:[~2014-06-10 1:27 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-10 1:27 [PATCH 00/12] clk: mmp: clock device tree support Chao Xie
2014-06-10 1:27 ` [PATCH 01/12] clk: mmp: add prefix "mmp" for structures defined for clk-frac Chao Xie
2014-06-10 1:27 ` [PATCH 02/12] clk: mmp: add spin lock " Chao Xie
[not found] ` <1402363668-25806-1-git-send-email-chao.xie-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
2014-06-10 1:27 ` [PATCH 03/12] clk: mmp: add init callback " Chao Xie
2014-06-10 1:27 ` [PATCH 04/12] clk: mmp: move definiton of mmp_clk_frac to clk.h Chao Xie
2014-06-10 1:27 ` [PATCH 05/12] clk: mmp: add clock type mix Chao Xie
2014-06-10 1:27 ` [PATCH 06/12] clk: mmp: add mmp private gate clock Chao Xie
2014-06-10 1:27 ` Chao Xie [this message]
2014-06-10 1:27 ` [PATCH 08/12] clk: mmp: add clock type master Chao Xie
2014-06-10 1:27 ` [PATCH 09/12] clk: mmp: add spin lock automatic detection from device tree Chao Xie
2014-06-10 1:27 ` [PATCH 10/12] clk: mmp: add device tree support for composite type clock Chao Xie
2014-06-10 1:27 ` [PATCH 11/12] clk: mmp: add device tree support for clocks Chao Xie
2014-06-10 1:27 ` [PATCH 12/12] arm: mmp: support clock device tree for mmp platforms Chao Xie
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=1402363668-25806-8-git-send-email-chao.xie@marvell.com \
--to=chao.xie@marvell.com \
--cc=devicetree@vger.kernel.org \
--cc=haojian.zhuang@gmail.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mturquette@linaro.org \
--cc=xiechao_mail@163.com \
/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).