mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: Barebox List <barebox@lists.infradead.org>
Subject: [PATCH 6/9] clk: Add support for shared gates
Date: Mon,  6 Feb 2017 07:50:54 +0100	[thread overview]
Message-ID: <20170206065057.19483-7-s.hauer@pengutronix.de> (raw)
In-Reply-To: <20170206065057.19483-1-s.hauer@pengutronix.de>

Sometimes a single software control knob controls multiple gates
in hardware. This patch adds support for shared gates which help
coping this situation. The first gate is registered with the hardware
gate as usual, the others are registered as shared gates which does
not have hardware control itself, but only switches the real hardware
gate.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/Makefile          |   3 +-
 drivers/clk/clk-gate-shared.c | 123 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/clk.h           |   3 ++
 3 files changed, 128 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/clk-gate-shared.c

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index a4e4ed024..5811d28b8 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -1,6 +1,7 @@
 obj-$(CONFIG_COMMON_CLK)	+= clk.o clk-fixed.o clk-divider.o clk-fixed-factor.o \
 				clk-mux.o clk-gate.o clk-composite.o \
-				clk-fractional-divider.o clk-conf.o
+				clk-fractional-divider.o clk-conf.o \
+				clk-gate-shared.o
 obj-$(CONFIG_CLKDEV_LOOKUP)	+= clkdev.o
 
 obj-$(CONFIG_ARCH_MVEBU)	+= mvebu/
diff --git a/drivers/clk/clk-gate-shared.c b/drivers/clk/clk-gate-shared.c
new file mode 100644
index 000000000..a95f940dd
--- /dev/null
+++ b/drivers/clk/clk-gate-shared.c
@@ -0,0 +1,123 @@
+/*
+ * clk-gate-shared.c - generic barebox clock support. Based on Linux clk support
+ *
+ * Copyright (c) 2017 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <common.h>
+#include <io.h>
+#include <malloc.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+struct clk_gate_shared {
+	struct clk clk;
+	const char *parent;
+	const char *companion_gate;
+	struct clk *companion_clk;
+};
+
+#define to_clk_gate_shared(_clk) container_of(_clk, struct clk_gate_shared, clk)
+
+static struct clk *lookup_companion(struct clk_gate_shared *g)
+{
+	if (IS_ERR(g->companion_clk))
+		g->companion_clk = clk_lookup(g->companion_gate);
+
+	if (IS_ERR(g->companion_clk))
+		return NULL;
+
+	return g->companion_clk;
+}
+
+static int clk_gate_shared_enable(struct clk *clk)
+{
+	struct clk_gate_shared *g = to_clk_gate_shared(clk);
+
+	return clk_enable(lookup_companion(g));
+}
+
+static void clk_gate_shared_disable(struct clk *clk)
+{
+	struct clk_gate_shared *g = to_clk_gate_shared(clk);
+
+	clk_disable(lookup_companion(g));
+}
+
+static int clk_gate_shared_is_enabled(struct clk *clk)
+{
+	struct clk_gate_shared *g = to_clk_gate_shared(clk);
+
+	return clk_is_enabled(lookup_companion(g));
+}
+
+static struct clk_ops clk_gate_shared_ops = {
+	.set_rate = clk_parent_set_rate,
+	.round_rate = clk_parent_round_rate,
+	.enable = clk_gate_shared_enable,
+	.disable = clk_gate_shared_disable,
+	.is_enabled = clk_gate_shared_is_enabled,
+};
+
+struct clk *clk_gate_shared_alloc(const char *name, const char *parent, const char *companion,
+			   unsigned flags)
+{
+	struct clk_gate_shared *g = xzalloc(sizeof(*g));
+
+	g->parent = parent;
+	g->companion_gate = companion;
+	g->companion_clk = ERR_PTR(-EINVAL);
+	g->clk.ops = &clk_gate_shared_ops;
+	g->clk.name = name;
+	g->clk.flags = flags;
+	g->clk.parent_names = &g->parent;
+	g->clk.num_parents = 1;
+
+	return &g->clk;
+}
+
+void clk_gate_shared_free(struct clk *clk)
+{
+	struct clk_gate_shared *g = to_clk_gate_shared(clk);
+
+	free(g);
+}
+
+/*
+ * clk_gate_shared - register a gate controlled by another gate
+ * @name: The name of the new clock gate
+ * @parent: The parent name of the new clock
+ * companion: The hardware gate this clock is controlled by
+ * @flags: common CLK_* flags
+ *
+ * This gate clock is used when a single software control knob controls multiple
+ * gates in hardware. The first gate is then registered as the real hardware gate,
+ * the others are registered with this function. This gate has no hardware control
+ * itself, but only enables/disabled its companion hardware gate.
+ */
+struct clk *clk_gate_shared(const char *name, const char *parent, const char *companion,
+			    unsigned flags)
+{
+	struct clk *clk;
+	int ret;
+
+	clk = clk_gate_shared_alloc(name , parent, companion, flags);
+
+	ret = clk_register(clk);
+	if (ret) {
+		clk_gate_shared_free(clk);
+		return ERR_PTR(ret);
+	}
+
+	return clk;
+}
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 697ab4ff4..7dd52388c 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -296,6 +296,9 @@ struct clk *clk_gate(const char *name, const char *parent, void __iomem *reg,
 		u8 shift, unsigned flags, u8 clk_gate_flags);
 struct clk *clk_gate_inverted(const char *name, const char *parent, void __iomem *reg,
 		u8 shift, unsigned flags);
+struct clk *clk_gate_shared(const char *name, const char *parent, const char *shared,
+			    unsigned flags);
+
 int clk_is_enabled(struct clk *clk);
 
 int clk_is_enabled_always(struct clk *clk);
-- 
2.11.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

  parent reply	other threads:[~2017-02-06  6:53 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-06  6:50 i.MX7 Ethernet clock fixes Sascha Hauer
2017-02-06  6:50 ` [PATCH 1/9] clk: Keep enable count consistent over reparent Sascha Hauer
2017-02-06  6:50 ` [PATCH 2/9] clk: implement CLK_OPS_PARENT_ENABLE Sascha Hauer
2017-02-06  6:50 ` [PATCH 3/9] clk: i.MX: clk-gate2: Allow to pass flags Sascha Hauer
2017-02-06  6:50 ` [PATCH 4/9] clk: i.MX: Pass CLK_OPS_PARENT_ENABLE where necessary Sascha Hauer
2017-02-06  6:50 ` [PATCH 5/9] clk: i.MX7: do clock reparenting when all clocks are initialized Sascha Hauer
2017-02-06  6:50 ` Sascha Hauer [this message]
2017-02-06  6:50 ` [PATCH 7/9] clk: i.MX7: Fix ethernet clocks Sascha Hauer
2017-02-06  6:50 ` [PATCH 8/9] clk: i.MX7: do not register PLL bypass clocks as separate clocks Sascha Hauer
2017-02-06  6:50 ` [PATCH 9/9] clk: i.MX7: setup ethernet clocks Sascha Hauer

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=20170206065057.19483-7-s.hauer@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@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