linux-clk.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] Introduce Quantum Clock handling
@ 2016-04-01 11:37 Neil Armstrong
  2016-04-01 11:37 ` [PATCH 1/5] clk: Switch clk handling to signed long and introduce Quantum State Neil Armstrong
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Neil Armstrong @ 2016-04-01 11:37 UTC (permalink / raw)
  To: linux-clk, mturquette, sjan, ahaslam, abailon; +Cc: Neil Armstrong

As today, handling of future but close Quantum physics as
part of our modern computing model is clearly and really not
ready. Introduce a simple, clear and clean but straightforward
implementation of a Quantum concept in the clk framework
looking for a great future for experimental physics handling.

For handling the new quantum physics, add a Quantum clock
or Schrodingers clock in reference of the great experiment,
organize a new implementation that describes a simple but
Logical quantum clock.

Researched-by: Just Another Kernel Experiment Research <joker@baylibre.com>
Tested-by: Brotherhood After The Most Andvanced Number <batman@baylibre.com>

Neil Armstrong (5):
  clk: Switch clk handling to signed long and introduce Quantum State
  clk: Introduce clk-schrodinger as Quantum clock implementation
  clk: Add build support for schrodinger clock
  dt-bindings: clock: add schrodinger clock bindings
  MAINTAINERS: Add Neil Armstrong as maintainers of schrodinger clock

 .../devicetree/bindings/clock/schrodinger.txt      |  18 ++++
 MAINTAINERS                                        |   6 ++
 drivers/clk/Makefile                               |   1 +
 drivers/clk/clk-schrodinger.c                      | 110 +++++++++++++++++++++
 drivers/clk/clk.c                                  | 104 ++++++++++---------
 include/linux/clk-provider.h                       |  29 +++++-
 include/linux/clk.h                                |  22 ++---
 7 files changed, 226 insertions(+), 64 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/schrodinger.txt
 create mode 100644 drivers/clk/clk-schrodinger.c

-- 
1.9.1

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/5] clk: Switch clk handling to signed long and introduce Quantum State
  2016-04-01 11:37 [PATCH 0/5] Introduce Quantum Clock handling Neil Armstrong
@ 2016-04-01 11:37 ` Neil Armstrong
  2016-04-01 16:13   ` Michael Turquette
  2016-04-04  9:10   ` Geert Uytterhoeven
  2016-04-01 11:37 ` [PATCH 2/5] clk: Introduce clk-schrodinger as Quantum clock implementation Neil Armstrong
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 10+ messages in thread
From: Neil Armstrong @ 2016-04-01 11:37 UTC (permalink / raw)
  To: linux-clk, mturquette, sjan, ahaslam, abailon; +Cc: Neil Armstrong

In order to handle the quantum clock state for rate, accuracy and phase,
switch all core functions to signed long.

Also add QUATUM state flag and QUANTUM return value.

Set QUANTUM default state in clk_core_init.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 drivers/clk/clk.c            | 104 +++++++++++++++++++++++--------------------
 include/linux/clk-provider.h |  12 +++--
 include/linux/clk.h          |  22 ++++-----
 3 files changed, 74 insertions(+), 64 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index fb74dc1..db7eced 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -51,9 +51,9 @@ struct clk_core {
 	struct clk_core		**parents;
 	u8			num_parents;
 	u8			new_parent_index;
-	unsigned long		rate;
-	unsigned long		req_rate;
-	unsigned long		new_rate;
+	long			rate;
+	long			req_rate;
+	long			new_rate;
 	struct clk_core		*new_parent;
 	struct clk_core		*new_child;
 	unsigned long		flags;
@@ -62,7 +62,7 @@ struct clk_core {
 	unsigned int		prepare_count;
 	unsigned long		min_rate;
 	unsigned long		max_rate;
-	unsigned long		accuracy;
+	long			accuracy;
 	int			phase;
 	struct hlist_head	children;
 	struct hlist_node	child_node;
@@ -82,8 +82,8 @@ struct clk {
 	struct clk_core	*core;
 	const char *dev_id;
 	const char *con_id;
-	unsigned long min_rate;
-	unsigned long max_rate;
+	long min_rate;
+	long max_rate;
 	struct hlist_node clks_node;
 };
 
@@ -374,9 +374,9 @@ unsigned int __clk_get_enable_count(struct clk *clk)
 	return !clk ? 0 : clk->core->enable_count;
 }
 
-static unsigned long clk_core_get_rate_nolock(struct clk_core *core)
+static long clk_core_get_rate_nolock(struct clk_core *core)
 {
-	unsigned long ret;
+	long ret;
 
 	if (!core) {
 		ret = 0;
@@ -395,13 +395,13 @@ out:
 	return ret;
 }
 
-unsigned long clk_hw_get_rate(const struct clk_hw *hw)
+long clk_hw_get_rate(const struct clk_hw *hw)
 {
 	return clk_core_get_rate_nolock(hw->core);
 }
 EXPORT_SYMBOL_GPL(clk_hw_get_rate);
 
-static unsigned long __clk_get_accuracy(struct clk_core *core)
+static long __clk_get_accuracy(struct clk_core *core)
 {
 	if (!core)
 		return 0;
@@ -440,8 +440,8 @@ bool __clk_is_enabled(struct clk *clk)
 }
 EXPORT_SYMBOL_GPL(__clk_is_enabled);
 
-static bool mux_is_better_rate(unsigned long rate, unsigned long now,
-			   unsigned long best, unsigned long flags)
+static bool mux_is_better_rate(long rate, long now,
+			   long best, unsigned long flags)
 {
 	if (flags & CLK_MUX_ROUND_CLOSEST)
 		return abs(now - rate) < abs(best - rate);
@@ -455,7 +455,7 @@ clk_mux_determine_rate_flags(struct clk_hw *hw, struct clk_rate_request *req,
 {
 	struct clk_core *core = hw->core, *parent, *best_parent = NULL;
 	int i, num_parents, ret;
-	unsigned long best = 0;
+	long best = 0;
 	struct clk_rate_request parent_req = *req;
 
 	/* if NO_REPARENT flag set, pass through to current parent */
@@ -520,8 +520,8 @@ struct clk *__clk_lookup(const char *name)
 }
 
 static void clk_core_get_boundaries(struct clk_core *core,
-				    unsigned long *min_rate,
-				    unsigned long *max_rate)
+				    long *min_rate,
+				    long *max_rate)
 {
 	struct clk *clk_user;
 
@@ -535,8 +535,8 @@ static void clk_core_get_boundaries(struct clk_core *core,
 		*max_rate = min(*max_rate, clk_user->max_rate);
 }
 
-void clk_hw_set_rate_range(struct clk_hw *hw, unsigned long min_rate,
-			   unsigned long max_rate)
+void clk_hw_set_rate_range(struct clk_hw *hw, long min_rate,
+			   long max_rate)
 {
 	hw->core->min_rate = min_rate;
 	hw->core->max_rate = max_rate;
@@ -839,7 +839,7 @@ int __clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
 }
 EXPORT_SYMBOL_GPL(__clk_determine_rate);
 
-unsigned long clk_hw_round_rate(struct clk_hw *hw, unsigned long rate)
+long clk_hw_round_rate(struct clk_hw *hw, long rate)
 {
 	int ret;
 	struct clk_rate_request req;
@@ -864,7 +864,7 @@ EXPORT_SYMBOL_GPL(clk_hw_round_rate);
  * use which is then returned.  If clk doesn't support round_rate operation
  * then the parent rate is returned.
  */
-long clk_round_rate(struct clk *clk, unsigned long rate)
+long clk_round_rate(struct clk *clk, long rate)
 {
 	struct clk_rate_request req;
 	int ret;
@@ -902,7 +902,7 @@ EXPORT_SYMBOL_GPL(clk_round_rate);
  * a driver returns that.
  */
 static int __clk_notify(struct clk_core *core, unsigned long msg,
-		unsigned long old_rate, unsigned long new_rate)
+		long old_rate, long new_rate)
 {
 	struct clk_notifier *cn;
 	struct clk_notifier_data cnd;
@@ -933,7 +933,7 @@ static int __clk_notify(struct clk_core *core, unsigned long msg,
  */
 static void __clk_recalc_accuracies(struct clk_core *core)
 {
-	unsigned long parent_accuracy = 0;
+	long parent_accuracy = 0;
 	struct clk_core *child;
 
 	lockdep_assert_held(&prepare_lock);
@@ -953,7 +953,7 @@ static void __clk_recalc_accuracies(struct clk_core *core)
 
 static long clk_core_get_accuracy(struct clk_core *core)
 {
-	unsigned long accuracy;
+	long accuracy;
 
 	clk_prepare_lock();
 	if (core && (core->flags & CLK_GET_ACCURACY_NOCACHE))
@@ -983,8 +983,8 @@ long clk_get_accuracy(struct clk *clk)
 }
 EXPORT_SYMBOL_GPL(clk_get_accuracy);
 
-static unsigned long clk_recalc(struct clk_core *core,
-				unsigned long parent_rate)
+static long clk_recalc(struct clk_core *core,
+			long parent_rate)
 {
 	if (core->ops->recalc_rate)
 		return core->ops->recalc_rate(core->hw, parent_rate);
@@ -1005,8 +1005,8 @@ static unsigned long clk_recalc(struct clk_core *core,
  */
 static void __clk_recalc_rates(struct clk_core *core, unsigned long msg)
 {
-	unsigned long old_rate;
-	unsigned long parent_rate = 0;
+	long old_rate;
+	long parent_rate = 0;
 	struct clk_core *child;
 
 	lockdep_assert_held(&prepare_lock);
@@ -1029,9 +1029,9 @@ static void __clk_recalc_rates(struct clk_core *core, unsigned long msg)
 		__clk_recalc_rates(child, msg);
 }
 
-static unsigned long clk_core_get_rate(struct clk_core *core)
+static long clk_core_get_rate(struct clk_core *core)
 {
-	unsigned long rate;
+	long rate;
 
 	clk_prepare_lock();
 
@@ -1052,7 +1052,7 @@ static unsigned long clk_core_get_rate(struct clk_core *core)
  * is set, which means a recalc_rate will be issued.
  * If clk is NULL then returns 0.
  */
-unsigned long clk_get_rate(struct clk *clk)
+long clk_get_rate(struct clk *clk)
 {
 	if (!clk)
 		return 0;
@@ -1219,10 +1219,10 @@ static int __clk_set_parent(struct clk_core *core, struct clk_core *parent,
  * take on the rate of its parent.
  */
 static int __clk_speculate_rates(struct clk_core *core,
-				 unsigned long parent_rate)
+				 long parent_rate)
 {
 	struct clk_core *child;
-	unsigned long new_rate;
+	long new_rate;
 	int ret = NOTIFY_DONE;
 
 	lockdep_assert_held(&prepare_lock);
@@ -1249,7 +1249,7 @@ out:
 	return ret;
 }
 
-static void clk_calc_subtree(struct clk_core *core, unsigned long new_rate,
+static void clk_calc_subtree(struct clk_core *core, long new_rate,
 			     struct clk_core *new_parent, u8 p_index)
 {
 	struct clk_core *child;
@@ -1273,14 +1273,14 @@ static void clk_calc_subtree(struct clk_core *core, unsigned long new_rate,
  * changed.
  */
 static struct clk_core *clk_calc_new_rates(struct clk_core *core,
-					   unsigned long rate)
+					   long rate)
 {
 	struct clk_core *top = core;
 	struct clk_core *old_parent, *parent;
-	unsigned long best_parent_rate = 0;
-	unsigned long new_rate;
-	unsigned long min_rate;
-	unsigned long max_rate;
+	long best_parent_rate = 0;
+	long new_rate;
+	long min_rate;
+	long max_rate;
 	int p_index = 0;
 	long ret;
 
@@ -1412,8 +1412,8 @@ static void clk_change_rate(struct clk_core *core)
 {
 	struct clk_core *child;
 	struct hlist_node *tmp;
-	unsigned long old_rate;
-	unsigned long best_parent_rate = 0;
+	long old_rate;
+	long best_parent_rate = 0;
 	bool skip_set_rate = false;
 	struct clk_core *old_parent;
 
@@ -1491,10 +1491,10 @@ static void clk_change_rate(struct clk_core *core)
 }
 
 static int clk_core_set_rate_nolock(struct clk_core *core,
-				    unsigned long req_rate)
+				    long req_rate)
 {
 	struct clk_core *top, *fail_clk;
-	unsigned long rate = req_rate;
+	long rate = req_rate;
 	int ret = 0;
 
 	if (!core)
@@ -1550,7 +1550,7 @@ static int clk_core_set_rate_nolock(struct clk_core *core,
  *
  * Returns 0 on success, -EERROR otherwise.
  */
-int clk_set_rate(struct clk *clk, unsigned long rate)
+int clk_set_rate(struct clk *clk, long rate)
 {
 	int ret;
 
@@ -1576,7 +1576,7 @@ EXPORT_SYMBOL_GPL(clk_set_rate);
  *
  * Returns success (0) or negative errno.
  */
-int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max)
+int clk_set_rate_range(struct clk *clk, long min, long max)
 {
 	int ret = 0;
 
@@ -1611,7 +1611,7 @@ EXPORT_SYMBOL_GPL(clk_set_rate_range);
  *
  * Returns success (0) or negative errno.
  */
-int clk_set_min_rate(struct clk *clk, unsigned long rate)
+int clk_set_min_rate(struct clk *clk, long rate)
 {
 	if (!clk)
 		return 0;
@@ -1627,7 +1627,7 @@ EXPORT_SYMBOL_GPL(clk_set_min_rate);
  *
  * Returns success (0) or negative errno.
  */
-int clk_set_max_rate(struct clk *clk, unsigned long rate)
+int clk_set_max_rate(struct clk *clk, long rate)
 {
 	if (!clk)
 		return 0;
@@ -1722,7 +1722,7 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent)
 {
 	int ret = 0;
 	int p_index = 0;
-	unsigned long p_rate = 0;
+	long p_rate = 0;
 
 	if (!core)
 		return 0;
@@ -2258,7 +2258,7 @@ static int __clk_core_init(struct clk_core *core)
 	int i, ret = 0;
 	struct clk_core *orphan;
 	struct hlist_node *tmp2;
-	unsigned long rate;
+	long rate;
 
 	if (!core)
 		return -EINVAL;
@@ -2347,6 +2347,8 @@ static int __clk_core_init(struct clk_core *core)
 					__clk_get_accuracy(core->parent));
 	else if (core->parent)
 		core->accuracy = core->parent->accuracy;
+	else if ((core->flags & CLK_STATE_IS_QUANTUM))
+		core->accuracy = -EQUANTUM_STATE;
 	else
 		core->accuracy = 0;
 
@@ -2357,6 +2359,8 @@ static int __clk_core_init(struct clk_core *core)
 	 */
 	if (core->ops->get_phase)
 		core->phase = core->ops->get_phase(core->hw);
+	else if ((core->flags & CLK_STATE_IS_QUANTUM))
+		core->phase = -EQUANTUM_STATE;
 	else
 		core->phase = 0;
 
@@ -2371,6 +2375,8 @@ static int __clk_core_init(struct clk_core *core)
 				clk_core_get_rate_nolock(core->parent));
 	else if (core->parent)
 		rate = core->parent->rate;
+	else if ((core->flags & CLK_STATE_IS_QUANTUM))
+		rate = -EQUANTUM_STATE;
 	else
 		rate = 0;
 	core->rate = core->req_rate = rate;
@@ -2423,7 +2429,7 @@ struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id,
 	clk->core = hw->core;
 	clk->dev_id = dev_id;
 	clk->con_id = con_id;
-	clk->max_rate = ULONG_MAX;
+	clk->max_rate = LONG_MAX;
 
 	clk_prepare_lock();
 	hlist_add_head(&clk->clks_node, &hw->core->clks);
@@ -2475,7 +2481,7 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
 	core->flags = hw->init->flags;
 	core->num_parents = hw->init->num_parents;
 	core->min_rate = 0;
-	core->max_rate = ULONG_MAX;
+	core->max_rate = LONG_MAX;
 	hw->core = core;
 
 	/* allocate local copy in case parent_names is __initdata */
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index da95258..03f96db 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -32,6 +32,10 @@
 #define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */
 #define CLK_RECALC_NEW_RATES	BIT(9) /* recalc rates after notifications */
 #define CLK_SET_RATE_UNGATE	BIT(10) /* clock needs to run to set rate */
+#define CLK_STATE_IS_QUANTUM	BIT(11) /* Clock in a quantum state */
+
+/* Quantum State clock status report for rate, accuracy and phase */
+#define EQUANTUM_STATE		(LONG_MAX)
 
 struct clk;
 struct clk_hw;
@@ -667,7 +671,7 @@ struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw);
 struct clk_hw *clk_hw_get_parent_by_index(const struct clk_hw *hw,
 					  unsigned int index);
 unsigned int __clk_get_enable_count(struct clk *clk);
-unsigned long clk_hw_get_rate(const struct clk_hw *hw);
+long clk_hw_get_rate(const struct clk_hw *hw);
 unsigned long __clk_get_flags(struct clk *clk);
 unsigned long clk_hw_get_flags(const struct clk_hw *hw);
 bool clk_hw_is_prepared(const struct clk_hw *hw);
@@ -680,8 +684,8 @@ int __clk_determine_rate(struct clk_hw *core, struct clk_rate_request *req);
 int __clk_mux_determine_rate_closest(struct clk_hw *hw,
 				     struct clk_rate_request *req);
 void clk_hw_reparent(struct clk_hw *hw, struct clk_hw *new_parent);
-void clk_hw_set_rate_range(struct clk_hw *hw, unsigned long min_rate,
-			   unsigned long max_rate);
+void clk_hw_set_rate_range(struct clk_hw *hw, long min_rate,
+			   long max_rate);
 
 static inline void __clk_hw_set_clk(struct clk_hw *dst, struct clk_hw *src)
 {
@@ -692,7 +696,7 @@ static inline void __clk_hw_set_clk(struct clk_hw *dst, struct clk_hw *src)
 /*
  * FIXME clock api without lock protection
  */
-unsigned long clk_hw_round_rate(struct clk_hw *hw, unsigned long rate);
+long clk_hw_round_rate(struct clk_hw *hw, long rate);
 
 struct of_device_id;
 
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 0df4a51..1d3ee61 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -74,8 +74,8 @@ struct clk_notifier {
  */
 struct clk_notifier_data {
 	struct clk		*clk;
-	unsigned long		old_rate;
-	unsigned long		new_rate;
+	long		old_rate;
+	long		new_rate;
 };
 
 /**
@@ -269,7 +269,7 @@ void clk_disable(struct clk *clk);
  *		  This is only valid once the clock source has been enabled.
  * @clk: clock source
  */
-unsigned long clk_get_rate(struct clk *clk);
+long clk_get_rate(struct clk *clk);
 
 /**
  * clk_put	- "free" the clock source
@@ -322,7 +322,7 @@ void devm_clk_put(struct device *dev, struct clk *clk);
  *
  * Returns rounded clock rate in Hz, or negative errno.
  */
-long clk_round_rate(struct clk *clk, unsigned long rate);
+long clk_round_rate(struct clk *clk, long rate);
 
 /**
  * clk_set_rate - set the clock rate for a clock source
@@ -331,7 +331,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate);
  *
  * Returns success (0) or negative errno.
  */
-int clk_set_rate(struct clk *clk, unsigned long rate);
+int clk_set_rate(struct clk *clk, long rate);
 
 /**
  * clk_has_parent - check if a clock is a possible parent for another
@@ -353,7 +353,7 @@ bool clk_has_parent(struct clk *clk, struct clk *parent);
  *
  * Returns success (0) or negative errno.
  */
-int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max);
+int clk_set_rate_range(struct clk *clk, long min, long max);
 
 /**
  * clk_set_min_rate - set a minimum clock rate for a clock source
@@ -362,7 +362,7 @@ int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max);
  *
  * Returns success (0) or negative errno.
  */
-int clk_set_min_rate(struct clk *clk, unsigned long rate);
+int clk_set_min_rate(struct clk *clk, long rate);
 
 /**
  * clk_set_max_rate - set a maximum clock rate for a clock source
@@ -371,7 +371,7 @@ int clk_set_min_rate(struct clk *clk, unsigned long rate);
  *
  * Returns success (0) or negative errno.
  */
-int clk_set_max_rate(struct clk *clk, unsigned long rate);
+int clk_set_max_rate(struct clk *clk, long rate);
 
 /**
  * clk_set_parent - set the parent clock source for this clock
@@ -431,17 +431,17 @@ static inline int clk_enable(struct clk *clk)
 
 static inline void clk_disable(struct clk *clk) {}
 
-static inline unsigned long clk_get_rate(struct clk *clk)
+static inline long clk_get_rate(struct clk *clk)
 {
 	return 0;
 }
 
-static inline int clk_set_rate(struct clk *clk, unsigned long rate)
+static inline int clk_set_rate(struct clk *clk, long rate)
 {
 	return 0;
 }
 
-static inline long clk_round_rate(struct clk *clk, unsigned long rate)
+static inline long clk_round_rate(struct clk *clk, long rate)
 {
 	return 0;
 }
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/5] clk: Introduce clk-schrodinger as Quantum clock implementation
  2016-04-01 11:37 [PATCH 0/5] Introduce Quantum Clock handling Neil Armstrong
  2016-04-01 11:37 ` [PATCH 1/5] clk: Switch clk handling to signed long and introduce Quantum State Neil Armstrong
@ 2016-04-01 11:37 ` Neil Armstrong
  2016-04-01 11:37 ` [PATCH 3/5] clk: Add build support for schrodinger clock Neil Armstrong
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Neil Armstrong @ 2016-04-01 11:37 UTC (permalink / raw)
  To: linux-clk, mturquette, sjan, ahaslam, abailon; +Cc: Neil Armstrong

For handling the new quantum physics, add a Quantum clock
or Schrodingers clock in reference of the great experiment,
organize a new implementation that describes a simple but
Logical quantum clock.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 drivers/clk/clk-schrodinger.c | 110 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/clk-provider.h  |  17 +++++++
 2 files changed, 127 insertions(+)
 create mode 100644 drivers/clk/clk-schrodinger.c

diff --git a/drivers/clk/clk-schrodinger.c b/drivers/clk/clk-schrodinger.c
new file mode 100644
index 0000000..14dd329
--- /dev/null
+++ b/drivers/clk/clk-schrodinger.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
+ * Copyright (C) 2010-2011 Canonical Ltd <jeremy.kerr@canonical.com>
+ * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
+ *
+ * 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.
+ *
+ * Schrodinger's clock implementation
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/of.h>
+
+/*
+ * basic unknown-rate clock that cannot gate
+ *
+ * Traits of this clock:
+ * parent - fixed parent.  No clk_set_parent support
+ */
+
+const struct clk_ops clk_schrodinger_ops = {
+	/* This is the point, since this clock is is in a quantum state,
+	 * any action could lead to a physical degradation of the clock */
+};
+EXPORT_SYMBOL_GPL(clk_schrodinger_ops);
+
+/**
+ * clk_register_schrodinger - register schrodinger clock with the
+ *							   clock framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @fixed_accuracy: non-adjustable clock rate
+ */
+struct clk *clk_register_schrodinger_with_accuracy(struct device *dev,
+		const char *name, const char *parent_name, unsigned long flags)
+{
+	struct clk_schrodinger *schrodinger;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	/* allocate schrodinger clock */
+	fixed = kzalloc(sizeof(*fixed), GFP_KERNEL);
+	if (!fixed)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &clk_schrodinger_ops;
+	init.flags = flags | CLK_STATE_IS_QUANTUM;
+	init.parent_names = (parent_name ? &parent_name : NULL);
+	init.num_parents = (parent_name ? 1 : 0);
+
+	/* struct clk_schrodinger assignments */
+	fixed->hw.init = &init;
+
+	/* register the clock */
+	clk = clk_register(dev, &fixed->hw);
+	if (IS_ERR(clk))
+		kfree(schrodinger);
+
+	return clk;
+}
+EXPORT_SYMBOL_GPL(clk_register_schrodinger);
+
+void clk_unregister_schrodinger(struct clk *clk)
+{
+	struct clk_hw *hw;
+
+	hw = __clk_get_hw(clk);
+	if (!hw)
+		return;
+
+	clk_unregister(clk);
+	kfree(to_clk_schrodinger(hw));
+}
+EXPORT_SYMBOL_GPL(clk_unregister_schrodinger);
+
+#ifdef CONFIG_OF
+/**
+ * of_schrodinger_clk_setup() - Setup function for schrodinger clock
+ */
+void of_schrodinger_clk_setup(struct device_node *node)
+{
+	struct clk *clk;
+	const char *clk_name = node->name;
+	u32 rate;
+	u32 accuracy = 0;
+
+	if (of_property_read_u32(node, "clock-frequency", &rate))
+		return;
+
+	of_property_read_u32(node, "clock-accuracy", &accuracy);
+
+	of_property_read_string(node, "clock-output-names", &clk_name);
+
+	clk = clk_register_schrodinger_with_accuracy(NULL, clk_name, NULL,
+						    0, rate, accuracy);
+	if (!IS_ERR(clk))
+		of_clk_add_provider(node, of_clk_src_simple_get, clk);
+}
+EXPORT_SYMBOL_GPL(of_schrodinger_clk_setup);
+CLK_OF_DECLARE(schrodinger_clk, "schrodinger-clock", of_schrodinger_clk_setup);
+#endif
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 03f96db..4414476 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -269,6 +269,23 @@ struct clk_hw {
  */
 
 /**
+ * struct clk_schrodinger - schrodinger unknown rate clock
+ * @hw:		handle between common and hardware-specific interfaces
+ */
+struct clk_schrodinger {
+	struct		clk_hw hw;
+	u8		flags;
+};
+
+#define to_clk_schrodinger(_hw) container_of(_hw, struct clk_schrodinger, hw)
+
+extern const struct clk_ops clk_schrodinger_ops;
+struct clk *clk_register_schrodingere(struct device *dev, const char *name,
+		const char *parent_name, unsigned long flags);
+void clk_unregister_schrodinger(struct clk *clk);
+void of_schrodinger_clk_setup(struct device_node *np);
+
+/**
  * struct clk_fixed_rate - fixed-rate clock
  * @hw:		handle between common and hardware-specific interfaces
  * @fixed_rate:	constant frequency of clock
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/5] clk: Add build support for schrodinger clock
  2016-04-01 11:37 [PATCH 0/5] Introduce Quantum Clock handling Neil Armstrong
  2016-04-01 11:37 ` [PATCH 1/5] clk: Switch clk handling to signed long and introduce Quantum State Neil Armstrong
  2016-04-01 11:37 ` [PATCH 2/5] clk: Introduce clk-schrodinger as Quantum clock implementation Neil Armstrong
@ 2016-04-01 11:37 ` Neil Armstrong
  2016-04-01 11:37 ` [PATCH 4/5] dt-bindings: clock: add schrodinger clock bindings Neil Armstrong
  2016-04-01 11:37 ` [PATCH 5/5] MAINTAINERS: Add Neil Armstrong as maintainers of schrodinger clock Neil Armstrong
  4 siblings, 0 replies; 10+ messages in thread
From: Neil Armstrong @ 2016-04-01 11:37 UTC (permalink / raw)
  To: linux-clk, mturquette, sjan, ahaslam, abailon; +Cc: Neil Armstrong

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 drivers/clk/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 46869d6..4976efe 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_COMMON_CLK)	+= clk.o
 obj-$(CONFIG_COMMON_CLK)	+= clk-divider.o
 obj-$(CONFIG_COMMON_CLK)	+= clk-fixed-factor.o
 obj-$(CONFIG_COMMON_CLK)	+= clk-fixed-rate.o
+obj-$(CONFIG_COMMON_CLK)	+= clk-schrodinger.o
 obj-$(CONFIG_COMMON_CLK)	+= clk-gate.o
 obj-$(CONFIG_COMMON_CLK)	+= clk-multiplier.o
 obj-$(CONFIG_COMMON_CLK)	+= clk-mux.o
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/5] dt-bindings: clock: add schrodinger clock bindings
  2016-04-01 11:37 [PATCH 0/5] Introduce Quantum Clock handling Neil Armstrong
                   ` (2 preceding siblings ...)
  2016-04-01 11:37 ` [PATCH 3/5] clk: Add build support for schrodinger clock Neil Armstrong
@ 2016-04-01 11:37 ` Neil Armstrong
  2016-04-01 16:18   ` Michael Turquette
  2016-04-01 11:37 ` [PATCH 5/5] MAINTAINERS: Add Neil Armstrong as maintainers of schrodinger clock Neil Armstrong
  4 siblings, 1 reply; 10+ messages in thread
From: Neil Armstrong @ 2016-04-01 11:37 UTC (permalink / raw)
  To: linux-clk, mturquette, sjan, ahaslam, abailon; +Cc: Neil Armstrong

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 .../devicetree/bindings/clock/schrodinger.txt          | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/schrodinger.txt

diff --git a/Documentation/devicetree/bindings/clock/schrodinger.txt b/Documentation/devicetree/bindings/clock/schrodinger.txt
new file mode 100644
index 0000000..ecb1a51
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/schrodinger.txt
@@ -0,0 +1,18 @@
+Binding for schrodinger Quantum clock sources.
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible : shall be "schrodinger-clock".
+- #clock-cells : from common clock binding; shall be set to 0.
+
+Optional properties:
+- clock-output-names : From common clock binding.
+
+Example:
+	cat {
+		compatible = "schrodinger-clock";
+		#clock-cells = <0>;
+	};
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5/5] MAINTAINERS: Add Neil Armstrong as maintainers of schrodinger clock
  2016-04-01 11:37 [PATCH 0/5] Introduce Quantum Clock handling Neil Armstrong
                   ` (3 preceding siblings ...)
  2016-04-01 11:37 ` [PATCH 4/5] dt-bindings: clock: add schrodinger clock bindings Neil Armstrong
@ 2016-04-01 11:37 ` Neil Armstrong
  4 siblings, 0 replies; 10+ messages in thread
From: Neil Armstrong @ 2016-04-01 11:37 UTC (permalink / raw)
  To: linux-clk, mturquette, sjan, ahaslam, abailon; +Cc: Neil Armstrong

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 378ebff..598d85e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10183,6 +10183,12 @@ S:	Maintained
 F:	drivers/media/i2c/ov2659.c
 F:	include/media/i2c/ov2659.h
 
+SCHRODINGER CLOCK
+M:	Neil Armstrong <narmstrong@baylibre.com>
+L:	linux-clk@vger.kernel.org
+S:	Maintained
+F:	drivers/clk/clk-schrodinger.c
+
 SILICON MOTION SM712 FRAME BUFFER DRIVER
 M:	Sudip Mukherjee <sudipm.mukherjee@gmail.com>
 M:	Teddy Wang <teddy.wang@siliconmotion.com>
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/5] clk: Switch clk handling to signed long and introduce Quantum State
  2016-04-01 11:37 ` [PATCH 1/5] clk: Switch clk handling to signed long and introduce Quantum State Neil Armstrong
@ 2016-04-01 16:13   ` Michael Turquette
  2016-04-04  9:10   ` Geert Uytterhoeven
  1 sibling, 0 replies; 10+ messages in thread
From: Michael Turquette @ 2016-04-01 16:13 UTC (permalink / raw)
  To: Neil Armstrong, linux-clk, sjan, ahaslam, abailon; +Cc: Neil Armstrong

Quoting Neil Armstrong (2016-04-01 04:37:11)
> In order to handle the quantum clock state for rate, accuracy and phase,
> switch all core functions to signed long.
> =

> Also add QUATUM state flag and QUANTUM return value.

s/QUATUM/QUANTUM/

Otherwise looks good. I fixed up locally and applied. We should have
quantum clocks in linux-next some time this week.

Regards,
Mike

> =

> Set QUANTUM default state in clk_core_init.
> =

> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
>  drivers/clk/clk.c            | 104 +++++++++++++++++++++++--------------=
------
>  include/linux/clk-provider.h |  12 +++--
>  include/linux/clk.h          |  22 ++++-----
>  3 files changed, 74 insertions(+), 64 deletions(-)
> =

> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index fb74dc1..db7eced 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -51,9 +51,9 @@ struct clk_core {
>         struct clk_core         **parents;
>         u8                      num_parents;
>         u8                      new_parent_index;
> -       unsigned long           rate;
> -       unsigned long           req_rate;
> -       unsigned long           new_rate;
> +       long                    rate;
> +       long                    req_rate;
> +       long                    new_rate;
>         struct clk_core         *new_parent;
>         struct clk_core         *new_child;
>         unsigned long           flags;
> @@ -62,7 +62,7 @@ struct clk_core {
>         unsigned int            prepare_count;
>         unsigned long           min_rate;
>         unsigned long           max_rate;
> -       unsigned long           accuracy;
> +       long                    accuracy;
>         int                     phase;
>         struct hlist_head       children;
>         struct hlist_node       child_node;
> @@ -82,8 +82,8 @@ struct clk {
>         struct clk_core *core;
>         const char *dev_id;
>         const char *con_id;
> -       unsigned long min_rate;
> -       unsigned long max_rate;
> +       long min_rate;
> +       long max_rate;
>         struct hlist_node clks_node;
>  };
>  =

> @@ -374,9 +374,9 @@ unsigned int __clk_get_enable_count(struct clk *clk)
>         return !clk ? 0 : clk->core->enable_count;
>  }
>  =

> -static unsigned long clk_core_get_rate_nolock(struct clk_core *core)
> +static long clk_core_get_rate_nolock(struct clk_core *core)
>  {
> -       unsigned long ret;
> +       long ret;
>  =

>         if (!core) {
>                 ret =3D 0;
> @@ -395,13 +395,13 @@ out:
>         return ret;
>  }
>  =

> -unsigned long clk_hw_get_rate(const struct clk_hw *hw)
> +long clk_hw_get_rate(const struct clk_hw *hw)
>  {
>         return clk_core_get_rate_nolock(hw->core);
>  }
>  EXPORT_SYMBOL_GPL(clk_hw_get_rate);
>  =

> -static unsigned long __clk_get_accuracy(struct clk_core *core)
> +static long __clk_get_accuracy(struct clk_core *core)
>  {
>         if (!core)
>                 return 0;
> @@ -440,8 +440,8 @@ bool __clk_is_enabled(struct clk *clk)
>  }
>  EXPORT_SYMBOL_GPL(__clk_is_enabled);
>  =

> -static bool mux_is_better_rate(unsigned long rate, unsigned long now,
> -                          unsigned long best, unsigned long flags)
> +static bool mux_is_better_rate(long rate, long now,
> +                          long best, unsigned long flags)
>  {
>         if (flags & CLK_MUX_ROUND_CLOSEST)
>                 return abs(now - rate) < abs(best - rate);
> @@ -455,7 +455,7 @@ clk_mux_determine_rate_flags(struct clk_hw *hw, struc=
t clk_rate_request *req,
>  {
>         struct clk_core *core =3D hw->core, *parent, *best_parent =3D NUL=
L;
>         int i, num_parents, ret;
> -       unsigned long best =3D 0;
> +       long best =3D 0;
>         struct clk_rate_request parent_req =3D *req;
>  =

>         /* if NO_REPARENT flag set, pass through to current parent */
> @@ -520,8 +520,8 @@ struct clk *__clk_lookup(const char *name)
>  }
>  =

>  static void clk_core_get_boundaries(struct clk_core *core,
> -                                   unsigned long *min_rate,
> -                                   unsigned long *max_rate)
> +                                   long *min_rate,
> +                                   long *max_rate)
>  {
>         struct clk *clk_user;
>  =

> @@ -535,8 +535,8 @@ static void clk_core_get_boundaries(struct clk_core *=
core,
>                 *max_rate =3D min(*max_rate, clk_user->max_rate);
>  }
>  =

> -void clk_hw_set_rate_range(struct clk_hw *hw, unsigned long min_rate,
> -                          unsigned long max_rate)
> +void clk_hw_set_rate_range(struct clk_hw *hw, long min_rate,
> +                          long max_rate)
>  {
>         hw->core->min_rate =3D min_rate;
>         hw->core->max_rate =3D max_rate;
> @@ -839,7 +839,7 @@ int __clk_determine_rate(struct clk_hw *hw, struct cl=
k_rate_request *req)
>  }
>  EXPORT_SYMBOL_GPL(__clk_determine_rate);
>  =

> -unsigned long clk_hw_round_rate(struct clk_hw *hw, unsigned long rate)
> +long clk_hw_round_rate(struct clk_hw *hw, long rate)
>  {
>         int ret;
>         struct clk_rate_request req;
> @@ -864,7 +864,7 @@ EXPORT_SYMBOL_GPL(clk_hw_round_rate);
>   * use which is then returned.  If clk doesn't support round_rate operat=
ion
>   * then the parent rate is returned.
>   */
> -long clk_round_rate(struct clk *clk, unsigned long rate)
> +long clk_round_rate(struct clk *clk, long rate)
>  {
>         struct clk_rate_request req;
>         int ret;
> @@ -902,7 +902,7 @@ EXPORT_SYMBOL_GPL(clk_round_rate);
>   * a driver returns that.
>   */
>  static int __clk_notify(struct clk_core *core, unsigned long msg,
> -               unsigned long old_rate, unsigned long new_rate)
> +               long old_rate, long new_rate)
>  {
>         struct clk_notifier *cn;
>         struct clk_notifier_data cnd;
> @@ -933,7 +933,7 @@ static int __clk_notify(struct clk_core *core, unsign=
ed long msg,
>   */
>  static void __clk_recalc_accuracies(struct clk_core *core)
>  {
> -       unsigned long parent_accuracy =3D 0;
> +       long parent_accuracy =3D 0;
>         struct clk_core *child;
>  =

>         lockdep_assert_held(&prepare_lock);
> @@ -953,7 +953,7 @@ static void __clk_recalc_accuracies(struct clk_core *=
core)
>  =

>  static long clk_core_get_accuracy(struct clk_core *core)
>  {
> -       unsigned long accuracy;
> +       long accuracy;
>  =

>         clk_prepare_lock();
>         if (core && (core->flags & CLK_GET_ACCURACY_NOCACHE))
> @@ -983,8 +983,8 @@ long clk_get_accuracy(struct clk *clk)
>  }
>  EXPORT_SYMBOL_GPL(clk_get_accuracy);
>  =

> -static unsigned long clk_recalc(struct clk_core *core,
> -                               unsigned long parent_rate)
> +static long clk_recalc(struct clk_core *core,
> +                       long parent_rate)
>  {
>         if (core->ops->recalc_rate)
>                 return core->ops->recalc_rate(core->hw, parent_rate);
> @@ -1005,8 +1005,8 @@ static unsigned long clk_recalc(struct clk_core *co=
re,
>   */
>  static void __clk_recalc_rates(struct clk_core *core, unsigned long msg)
>  {
> -       unsigned long old_rate;
> -       unsigned long parent_rate =3D 0;
> +       long old_rate;
> +       long parent_rate =3D 0;
>         struct clk_core *child;
>  =

>         lockdep_assert_held(&prepare_lock);
> @@ -1029,9 +1029,9 @@ static void __clk_recalc_rates(struct clk_core *cor=
e, unsigned long msg)
>                 __clk_recalc_rates(child, msg);
>  }
>  =

> -static unsigned long clk_core_get_rate(struct clk_core *core)
> +static long clk_core_get_rate(struct clk_core *core)
>  {
> -       unsigned long rate;
> +       long rate;
>  =

>         clk_prepare_lock();
>  =

> @@ -1052,7 +1052,7 @@ static unsigned long clk_core_get_rate(struct clk_c=
ore *core)
>   * is set, which means a recalc_rate will be issued.
>   * If clk is NULL then returns 0.
>   */
> -unsigned long clk_get_rate(struct clk *clk)
> +long clk_get_rate(struct clk *clk)
>  {
>         if (!clk)
>                 return 0;
> @@ -1219,10 +1219,10 @@ static int __clk_set_parent(struct clk_core *core=
, struct clk_core *parent,
>   * take on the rate of its parent.
>   */
>  static int __clk_speculate_rates(struct clk_core *core,
> -                                unsigned long parent_rate)
> +                                long parent_rate)
>  {
>         struct clk_core *child;
> -       unsigned long new_rate;
> +       long new_rate;
>         int ret =3D NOTIFY_DONE;
>  =

>         lockdep_assert_held(&prepare_lock);
> @@ -1249,7 +1249,7 @@ out:
>         return ret;
>  }
>  =

> -static void clk_calc_subtree(struct clk_core *core, unsigned long new_ra=
te,
> +static void clk_calc_subtree(struct clk_core *core, long new_rate,
>                              struct clk_core *new_parent, u8 p_index)
>  {
>         struct clk_core *child;
> @@ -1273,14 +1273,14 @@ static void clk_calc_subtree(struct clk_core *cor=
e, unsigned long new_rate,
>   * changed.
>   */
>  static struct clk_core *clk_calc_new_rates(struct clk_core *core,
> -                                          unsigned long rate)
> +                                          long rate)
>  {
>         struct clk_core *top =3D core;
>         struct clk_core *old_parent, *parent;
> -       unsigned long best_parent_rate =3D 0;
> -       unsigned long new_rate;
> -       unsigned long min_rate;
> -       unsigned long max_rate;
> +       long best_parent_rate =3D 0;
> +       long new_rate;
> +       long min_rate;
> +       long max_rate;
>         int p_index =3D 0;
>         long ret;
>  =

> @@ -1412,8 +1412,8 @@ static void clk_change_rate(struct clk_core *core)
>  {
>         struct clk_core *child;
>         struct hlist_node *tmp;
> -       unsigned long old_rate;
> -       unsigned long best_parent_rate =3D 0;
> +       long old_rate;
> +       long best_parent_rate =3D 0;
>         bool skip_set_rate =3D false;
>         struct clk_core *old_parent;
>  =

> @@ -1491,10 +1491,10 @@ static void clk_change_rate(struct clk_core *core)
>  }
>  =

>  static int clk_core_set_rate_nolock(struct clk_core *core,
> -                                   unsigned long req_rate)
> +                                   long req_rate)
>  {
>         struct clk_core *top, *fail_clk;
> -       unsigned long rate =3D req_rate;
> +       long rate =3D req_rate;
>         int ret =3D 0;
>  =

>         if (!core)
> @@ -1550,7 +1550,7 @@ static int clk_core_set_rate_nolock(struct clk_core=
 *core,
>   *
>   * Returns 0 on success, -EERROR otherwise.
>   */
> -int clk_set_rate(struct clk *clk, unsigned long rate)
> +int clk_set_rate(struct clk *clk, long rate)
>  {
>         int ret;
>  =

> @@ -1576,7 +1576,7 @@ EXPORT_SYMBOL_GPL(clk_set_rate);
>   *
>   * Returns success (0) or negative errno.
>   */
> -int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long=
 max)
> +int clk_set_rate_range(struct clk *clk, long min, long max)
>  {
>         int ret =3D 0;
>  =

> @@ -1611,7 +1611,7 @@ EXPORT_SYMBOL_GPL(clk_set_rate_range);
>   *
>   * Returns success (0) or negative errno.
>   */
> -int clk_set_min_rate(struct clk *clk, unsigned long rate)
> +int clk_set_min_rate(struct clk *clk, long rate)
>  {
>         if (!clk)
>                 return 0;
> @@ -1627,7 +1627,7 @@ EXPORT_SYMBOL_GPL(clk_set_min_rate);
>   *
>   * Returns success (0) or negative errno.
>   */
> -int clk_set_max_rate(struct clk *clk, unsigned long rate)
> +int clk_set_max_rate(struct clk *clk, long rate)
>  {
>         if (!clk)
>                 return 0;
> @@ -1722,7 +1722,7 @@ static int clk_core_set_parent(struct clk_core *cor=
e, struct clk_core *parent)
>  {
>         int ret =3D 0;
>         int p_index =3D 0;
> -       unsigned long p_rate =3D 0;
> +       long p_rate =3D 0;
>  =

>         if (!core)
>                 return 0;
> @@ -2258,7 +2258,7 @@ static int __clk_core_init(struct clk_core *core)
>         int i, ret =3D 0;
>         struct clk_core *orphan;
>         struct hlist_node *tmp2;
> -       unsigned long rate;
> +       long rate;
>  =

>         if (!core)
>                 return -EINVAL;
> @@ -2347,6 +2347,8 @@ static int __clk_core_init(struct clk_core *core)
>                                         __clk_get_accuracy(core->parent));
>         else if (core->parent)
>                 core->accuracy =3D core->parent->accuracy;
> +       else if ((core->flags & CLK_STATE_IS_QUANTUM))
> +               core->accuracy =3D -EQUANTUM_STATE;
>         else
>                 core->accuracy =3D 0;
>  =

> @@ -2357,6 +2359,8 @@ static int __clk_core_init(struct clk_core *core)
>          */
>         if (core->ops->get_phase)
>                 core->phase =3D core->ops->get_phase(core->hw);
> +       else if ((core->flags & CLK_STATE_IS_QUANTUM))
> +               core->phase =3D -EQUANTUM_STATE;
>         else
>                 core->phase =3D 0;
>  =

> @@ -2371,6 +2375,8 @@ static int __clk_core_init(struct clk_core *core)
>                                 clk_core_get_rate_nolock(core->parent));
>         else if (core->parent)
>                 rate =3D core->parent->rate;
> +       else if ((core->flags & CLK_STATE_IS_QUANTUM))
> +               rate =3D -EQUANTUM_STATE;
>         else
>                 rate =3D 0;
>         core->rate =3D core->req_rate =3D rate;
> @@ -2423,7 +2429,7 @@ struct clk *__clk_create_clk(struct clk_hw *hw, con=
st char *dev_id,
>         clk->core =3D hw->core;
>         clk->dev_id =3D dev_id;
>         clk->con_id =3D con_id;
> -       clk->max_rate =3D ULONG_MAX;
> +       clk->max_rate =3D LONG_MAX;
>  =

>         clk_prepare_lock();
>         hlist_add_head(&clk->clks_node, &hw->core->clks);
> @@ -2475,7 +2481,7 @@ struct clk *clk_register(struct device *dev, struct=
 clk_hw *hw)
>         core->flags =3D hw->init->flags;
>         core->num_parents =3D hw->init->num_parents;
>         core->min_rate =3D 0;
> -       core->max_rate =3D ULONG_MAX;
> +       core->max_rate =3D LONG_MAX;
>         hw->core =3D core;
>  =

>         /* allocate local copy in case parent_names is __initdata */
> diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
> index da95258..03f96db 100644
> --- a/include/linux/clk-provider.h
> +++ b/include/linux/clk-provider.h
> @@ -32,6 +32,10 @@
>  #define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk acc=
uracy */
>  #define CLK_RECALC_NEW_RATES   BIT(9) /* recalc rates after notification=
s */
>  #define CLK_SET_RATE_UNGATE    BIT(10) /* clock needs to run to set rate=
 */
> +#define CLK_STATE_IS_QUANTUM   BIT(11) /* Clock in a quantum state */
> +
> +/* Quantum State clock status report for rate, accuracy and phase */
> +#define EQUANTUM_STATE         (LONG_MAX)
>  =

>  struct clk;
>  struct clk_hw;
> @@ -667,7 +671,7 @@ struct clk_hw *clk_hw_get_parent(const struct clk_hw =
*hw);
>  struct clk_hw *clk_hw_get_parent_by_index(const struct clk_hw *hw,
>                                           unsigned int index);
>  unsigned int __clk_get_enable_count(struct clk *clk);
> -unsigned long clk_hw_get_rate(const struct clk_hw *hw);
> +long clk_hw_get_rate(const struct clk_hw *hw);
>  unsigned long __clk_get_flags(struct clk *clk);
>  unsigned long clk_hw_get_flags(const struct clk_hw *hw);
>  bool clk_hw_is_prepared(const struct clk_hw *hw);
> @@ -680,8 +684,8 @@ int __clk_determine_rate(struct clk_hw *core, struct =
clk_rate_request *req);
>  int __clk_mux_determine_rate_closest(struct clk_hw *hw,
>                                      struct clk_rate_request *req);
>  void clk_hw_reparent(struct clk_hw *hw, struct clk_hw *new_parent);
> -void clk_hw_set_rate_range(struct clk_hw *hw, unsigned long min_rate,
> -                          unsigned long max_rate);
> +void clk_hw_set_rate_range(struct clk_hw *hw, long min_rate,
> +                          long max_rate);
>  =

>  static inline void __clk_hw_set_clk(struct clk_hw *dst, struct clk_hw *s=
rc)
>  {
> @@ -692,7 +696,7 @@ static inline void __clk_hw_set_clk(struct clk_hw *ds=
t, struct clk_hw *src)
>  /*
>   * FIXME clock api without lock protection
>   */
> -unsigned long clk_hw_round_rate(struct clk_hw *hw, unsigned long rate);
> +long clk_hw_round_rate(struct clk_hw *hw, long rate);
>  =

>  struct of_device_id;
>  =

> diff --git a/include/linux/clk.h b/include/linux/clk.h
> index 0df4a51..1d3ee61 100644
> --- a/include/linux/clk.h
> +++ b/include/linux/clk.h
> @@ -74,8 +74,8 @@ struct clk_notifier {
>   */
>  struct clk_notifier_data {
>         struct clk              *clk;
> -       unsigned long           old_rate;
> -       unsigned long           new_rate;
> +       long            old_rate;
> +       long            new_rate;
>  };
>  =

>  /**
> @@ -269,7 +269,7 @@ void clk_disable(struct clk *clk);
>   *               This is only valid once the clock source has been enabl=
ed.
>   * @clk: clock source
>   */
> -unsigned long clk_get_rate(struct clk *clk);
> +long clk_get_rate(struct clk *clk);
>  =

>  /**
>   * clk_put     - "free" the clock source
> @@ -322,7 +322,7 @@ void devm_clk_put(struct device *dev, struct clk *clk=
);
>   *
>   * Returns rounded clock rate in Hz, or negative errno.
>   */
> -long clk_round_rate(struct clk *clk, unsigned long rate);
> +long clk_round_rate(struct clk *clk, long rate);
>  =

>  /**
>   * clk_set_rate - set the clock rate for a clock source
> @@ -331,7 +331,7 @@ long clk_round_rate(struct clk *clk, unsigned long ra=
te);
>   *
>   * Returns success (0) or negative errno.
>   */
> -int clk_set_rate(struct clk *clk, unsigned long rate);
> +int clk_set_rate(struct clk *clk, long rate);
>  =

>  /**
>   * clk_has_parent - check if a clock is a possible parent for another
> @@ -353,7 +353,7 @@ bool clk_has_parent(struct clk *clk, struct clk *pare=
nt);
>   *
>   * Returns success (0) or negative errno.
>   */
> -int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long=
 max);
> +int clk_set_rate_range(struct clk *clk, long min, long max);
>  =

>  /**
>   * clk_set_min_rate - set a minimum clock rate for a clock source
> @@ -362,7 +362,7 @@ int clk_set_rate_range(struct clk *clk, unsigned long=
 min, unsigned long max);
>   *
>   * Returns success (0) or negative errno.
>   */
> -int clk_set_min_rate(struct clk *clk, unsigned long rate);
> +int clk_set_min_rate(struct clk *clk, long rate);
>  =

>  /**
>   * clk_set_max_rate - set a maximum clock rate for a clock source
> @@ -371,7 +371,7 @@ int clk_set_min_rate(struct clk *clk, unsigned long r=
ate);
>   *
>   * Returns success (0) or negative errno.
>   */
> -int clk_set_max_rate(struct clk *clk, unsigned long rate);
> +int clk_set_max_rate(struct clk *clk, long rate);
>  =

>  /**
>   * clk_set_parent - set the parent clock source for this clock
> @@ -431,17 +431,17 @@ static inline int clk_enable(struct clk *clk)
>  =

>  static inline void clk_disable(struct clk *clk) {}
>  =

> -static inline unsigned long clk_get_rate(struct clk *clk)
> +static inline long clk_get_rate(struct clk *clk)
>  {
>         return 0;
>  }
>  =

> -static inline int clk_set_rate(struct clk *clk, unsigned long rate)
> +static inline int clk_set_rate(struct clk *clk, long rate)
>  {
>         return 0;
>  }
>  =

> -static inline long clk_round_rate(struct clk *clk, unsigned long rate)
> +static inline long clk_round_rate(struct clk *clk, long rate)
>  {
>         return 0;
>  }
> -- =

> 1.9.1
>=20

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/5] dt-bindings: clock: add schrodinger clock bindings
  2016-04-01 11:37 ` [PATCH 4/5] dt-bindings: clock: add schrodinger clock bindings Neil Armstrong
@ 2016-04-01 16:18   ` Michael Turquette
  2016-04-01 18:27     ` Kevin Hilman
  0 siblings, 1 reply; 10+ messages in thread
From: Michael Turquette @ 2016-04-01 16:18 UTC (permalink / raw)
  To: Neil Armstrong, linux-clk, sjan, ahaslam, abailon; +Cc: Neil Armstrong

Quoting Neil Armstrong (2016-04-01 04:37:14)
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
>  .../devicetree/bindings/clock/schrodinger.txt          | 18 ++++++++++++=
++++++
>  1 file changed, 18 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/schrodinger.t=
xt
> =

> diff --git a/Documentation/devicetree/bindings/clock/schrodinger.txt b/Do=
cumentation/devicetree/bindings/clock/schrodinger.txt
> new file mode 100644
> index 0000000..ecb1a51
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/schrodinger.txt
> @@ -0,0 +1,18 @@
> +Binding for schrodinger Quantum clock sources.
> +
> +This binding uses the common clock binding[1].
> +
> +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
> +
> +Required properties:
> +- compatible : shall be "schrodinger-clock".
> +- #clock-cells : from common clock binding; shall be set to 0.
> +
> +Optional properties:
> +- clock-output-names : From common clock binding.
> +
> +Example:
> +       cat {
> +               compatible =3D "schrodinger-clock";
> +               #clock-cells =3D <0>;

I know it is out of scope for this series, but I wonder what would
constitute a valid status property for the cat node? Should we propose
adding "dead" and "alive" values to the status property in ePAPR?

Regards,
Mike

> +       };
> -- =

> 1.9.1
>=20

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/5] dt-bindings: clock: add schrodinger clock bindings
  2016-04-01 16:18   ` Michael Turquette
@ 2016-04-01 18:27     ` Kevin Hilman
  0 siblings, 0 replies; 10+ messages in thread
From: Kevin Hilman @ 2016-04-01 18:27 UTC (permalink / raw)
  To: Michael Turquette; +Cc: Neil Armstrong, linux-clk, sjan, ahaslam, abailon

Michael Turquette <mturquette@baylibre.com> writes:

> Quoting Neil Armstrong (2016-04-01 04:37:14)
>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>> ---
>>  .../devicetree/bindings/clock/schrodinger.txt          | 18 ++++++++++++++++++
>>  1 file changed, 18 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/clock/schrodinger.txt
>> 
>> diff --git a/Documentation/devicetree/bindings/clock/schrodinger.txt b/Documentation/devicetree/bindings/clock/schrodinger.txt
>> new file mode 100644
>> index 0000000..ecb1a51
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/schrodinger.txt
>> @@ -0,0 +1,18 @@
>> +Binding for schrodinger Quantum clock sources.
>> +
>> +This binding uses the common clock binding[1].
>> +
>> +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
>> +
>> +Required properties:
>> +- compatible : shall be "schrodinger-clock".
>> +- #clock-cells : from common clock binding; shall be set to 0.
>> +
>> +Optional properties:
>> +- clock-output-names : From common clock binding.
>> +
>> +Example:
>> +       cat {
>> +               compatible = "schrodinger-clock";
>> +               #clock-cells = <0>;
>
> I know it is out of scope for this series, but I wonder what would
> constitute a valid status property for the cat node? Should we propose
> adding "dead" and "alive" values to the status property in ePAPR?

IMO, "dead" and "alive" could probably be mapped onto "ok" and
"disabled" without too much confusion.

However, with this series, we will clearly need to add support for
status = "both".;

Kevin

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/5] clk: Switch clk handling to signed long and introduce Quantum State
  2016-04-01 11:37 ` [PATCH 1/5] clk: Switch clk handling to signed long and introduce Quantum State Neil Armstrong
  2016-04-01 16:13   ` Michael Turquette
@ 2016-04-04  9:10   ` Geert Uytterhoeven
  1 sibling, 0 replies; 10+ messages in thread
From: Geert Uytterhoeven @ 2016-04-04  9:10 UTC (permalink / raw)
  To: Neil Armstrong; +Cc: linux-clk, Michael Turquette, sjan, Axel Haslam, abailon

Hi Neil,

On Fri, Apr 1, 2016 at 1:37 PM, Neil Armstrong <narmstrong@baylibre.com> wrote:
> In order to handle the quantum clock state for rate, accuracy and phase,
> switch all core functions to signed long.
>
> Also add QUATUM state flag and QUANTUM return value.
>
> Set QUANTUM default state in clk_core_init.

Thanks for your patch!

> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
>  drivers/clk/clk.c            | 104 +++++++++++++++++++++++--------------------
>  include/linux/clk-provider.h |  12 +++--
>  include/linux/clk.h          |  22 ++++-----
>  3 files changed, 74 insertions(+), 64 deletions(-)
>
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index fb74dc1..db7eced 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -51,9 +51,9 @@ struct clk_core {
>         struct clk_core         **parents;
>         u8                      num_parents;
>         u8                      new_parent_index;
> -       unsigned long           rate;
> -       unsigned long           req_rate;
> -       unsigned long           new_rate;
> +       long                    rate;
> +       long                    req_rate;
> +       long                    new_rate;

To account for the imaginary part of the phase, I think this should be a
complex number, not just a long.

Apart from that, it's definitely a step in the right direction!

Sorry for the late comments, I was on holidays last Friday...

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2016-04-04  9:10 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-04-01 11:37 [PATCH 0/5] Introduce Quantum Clock handling Neil Armstrong
2016-04-01 11:37 ` [PATCH 1/5] clk: Switch clk handling to signed long and introduce Quantum State Neil Armstrong
2016-04-01 16:13   ` Michael Turquette
2016-04-04  9:10   ` Geert Uytterhoeven
2016-04-01 11:37 ` [PATCH 2/5] clk: Introduce clk-schrodinger as Quantum clock implementation Neil Armstrong
2016-04-01 11:37 ` [PATCH 3/5] clk: Add build support for schrodinger clock Neil Armstrong
2016-04-01 11:37 ` [PATCH 4/5] dt-bindings: clock: add schrodinger clock bindings Neil Armstrong
2016-04-01 16:18   ` Michael Turquette
2016-04-01 18:27     ` Kevin Hilman
2016-04-01 11:37 ` [PATCH 5/5] MAINTAINERS: Add Neil Armstrong as maintainers of schrodinger clock Neil Armstrong

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).