All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V3 0/8] SPEAr: Move to common clock framework
@ 2012-04-24  6:50 Viresh Kumar
  2012-04-24  6:50 ` [PATCH V3 1/8] CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk * Viresh Kumar
                   ` (7 more replies)
  0 siblings, 8 replies; 42+ messages in thread
From: Viresh Kumar @ 2012-04-24  6:50 UTC (permalink / raw)
  To: linux-arm-kernel

Mike,

You can apply all these patches as they don't have any dependency left (leaving
the ones included here) and will now apply cleanly over linux-next.

SPEAr now supports common clock framework. This patchset contains changes
related to this.

V2->V3:
- Created spear/clk.c for common routines
- Fixed #ifndef,#ifdef,#endif name in spear/clk.h
- Included dependency patches, so that Mike can apply these patches

V1->V2:
- Removed first seven commits as they are directly picked by Mike into his next.
- Moved SPEAr clock support to drivers/clk/spear/ from arch/arm/
- Fixed error handling issues in spear clk drivers
- Rearranged patches to get git bisect working

Russell King (1):
  CLKDEV: Add helper routines to allocate and add clkdevs for given
    struct clk *

Sascha Hauer (1):
  clk: add a fixed factor clock

Viresh Kumar (6):
  SPEAr: clk: Add VCO-PLL Synthesizer clock
  SPEAr: clk: Add Auxiliary Synthesizer clock
  SPEAr: clk: Add Fractional Synthesizer clock
  SPEAr: clk: Add General Purpose Timer Synthesizer clock
  SPEAr: Call clk_prepare() before calling clk_enable
  SPEAr: Switch to common clock framework

 MAINTAINERS                                     |    4 +-
 arch/arm/Kconfig                                |    1 +
 arch/arm/mach-spear3xx/Makefile                 |    2 +-
 arch/arm/mach-spear3xx/clock.c                  |  892 --------------------
 arch/arm/mach-spear3xx/include/mach/generic.h   |    4 +-
 arch/arm/mach-spear3xx/include/mach/misc_regs.h |    2 +
 arch/arm/mach-spear3xx/include/mach/spear.h     |   13 +
 arch/arm/mach-spear3xx/spear300.c               |    1 -
 arch/arm/mach-spear3xx/spear310.c               |    1 -
 arch/arm/mach-spear3xx/spear320.c               |   12 +-
 arch/arm/mach-spear3xx/spear3xx.c               |    2 +
 arch/arm/mach-spear6xx/Makefile                 |    2 +-
 arch/arm/mach-spear6xx/clock.c                  |  789 ------------------
 arch/arm/mach-spear6xx/include/mach/misc_regs.h |    2 +
 arch/arm/mach-spear6xx/spear6xx.c               |    5 +-
 arch/arm/plat-spear/Makefile                    |    2 +-
 arch/arm/plat-spear/clock.c                     | 1005 -----------------------
 arch/arm/plat-spear/include/plat/clock.h        |  249 ------
 arch/arm/plat-spear/time.c                      |    8 +-
 drivers/clk/Makefile                            |    5 +-
 drivers/clk/clk-fixed-factor.c                  |   94 +++
 drivers/clk/clkdev.c                            |   64 ++-
 drivers/clk/spear/Makefile                      |    8 +
 drivers/clk/spear/clk-aux-synth.c               |  189 +++++
 drivers/clk/spear/clk-frac-synth.c              |  156 ++++
 drivers/clk/spear/clk-gpt-synth.c               |  145 ++++
 drivers/clk/spear/clk-vco-pll.c                 |  346 ++++++++
 drivers/clk/spear/clk.c                         |   36 +
 drivers/clk/spear/clk.h                         |  133 +++
 drivers/clk/spear/spear3xx_clock.c              |  612 ++++++++++++++
 drivers/clk/spear/spear6xx_clock.c              |  342 ++++++++
 include/linux/clk-private.h                     |   20 +
 include/linux/clk-provider.h                    |   23 +
 include/linux/clkdev.h                          |    3 +
 34 files changed, 2210 insertions(+), 2962 deletions(-)
 delete mode 100644 arch/arm/mach-spear3xx/clock.c
 delete mode 100644 arch/arm/mach-spear6xx/clock.c
 delete mode 100644 arch/arm/plat-spear/clock.c
 delete mode 100644 arch/arm/plat-spear/include/plat/clock.h
 create mode 100644 drivers/clk/clk-fixed-factor.c
 create mode 100644 drivers/clk/spear/Makefile
 create mode 100644 drivers/clk/spear/clk-aux-synth.c
 create mode 100644 drivers/clk/spear/clk-frac-synth.c
 create mode 100644 drivers/clk/spear/clk-gpt-synth.c
 create mode 100644 drivers/clk/spear/clk-vco-pll.c
 create mode 100644 drivers/clk/spear/clk.c
 create mode 100644 drivers/clk/spear/clk.h
 create mode 100644 drivers/clk/spear/spear3xx_clock.c
 create mode 100644 drivers/clk/spear/spear6xx_clock.c

-- 
1.7.9

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

* [PATCH V3 1/8] CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk *
  2012-04-24  6:50 [PATCH V3 0/8] SPEAr: Move to common clock framework Viresh Kumar
@ 2012-04-24  6:50 ` Viresh Kumar
  2012-04-26  7:47   ` Russell King - ARM Linux
  2012-04-24  6:50 ` [PATCH V3 2/8] clk: add a fixed factor clock Viresh Kumar
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 42+ messages in thread
From: Viresh Kumar @ 2012-04-24  6:50 UTC (permalink / raw)
  To: linux-arm-kernel

From: Russell King <rmk+kernel@arm.linux.org.uk>

With common clock framework, clks are allocated at runtime. Some of them require
clkdevs to be allocated and added in global clkdev list.

This patch introduces helper routines to:

 - allocate and add single clkdev for a single clk structure.
 - add multiple clkdevs for a single clk structure.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 drivers/clk/clkdev.c   |   64 +++++++++++++++++++++++++++++++++++++++++++----
 include/linux/clkdev.h |    3 ++
 2 files changed, 61 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index d4a5993..e39d96f 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -166,8 +166,9 @@ struct clk_lookup_alloc {
 	char	con_id[MAX_CON_ID];
 };
 
-struct clk_lookup * __init_refok
-clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
+static struct clk_lookup * __init_refok
+__clkdev_alloc_valist(struct clk *clk, const char *con_id, const char *dev_fmt,
+		va_list ap)
 {
 	struct clk_lookup_alloc *cla;
 
@@ -182,16 +183,35 @@ clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
 	}
 
 	if (dev_fmt) {
-		va_list ap;
-
-		va_start(ap, dev_fmt);
 		vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap);
 		cla->cl.dev_id = cla->dev_id;
-		va_end(ap);
 	}
 
 	return &cla->cl;
 }
+
+#define clkdev_alloc_valist(_cl, _clk, _con_id, _dev_fmt, _ap)		\
+	do {								\
+		if (_dev_fmt)						\
+			va_start(_ap, _dev_fmt);			\
+									\
+		_cl = __clkdev_alloc_valist(_clk, _con_id, _dev_fmt,	\
+				_ap);					\
+									\
+		if (_dev_fmt)						\
+			va_end(ap);					\
+	} while (0);
+
+struct clk_lookup * __init_refok
+clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
+{
+	struct clk_lookup *cl;
+	va_list ap;
+
+	clkdev_alloc_valist(cl, clk, con_id, dev_fmt, ap);
+
+	return cl;
+}
 EXPORT_SYMBOL(clkdev_alloc);
 
 int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
@@ -223,3 +243,35 @@ void clkdev_drop(struct clk_lookup *cl)
 	kfree(cl);
 }
 EXPORT_SYMBOL(clkdev_drop);
+
+int clk_register_clkdev(struct clk *clk, const char *con_id,
+		const char *dev_fmt, ...)
+{
+	struct clk_lookup *cl;
+	va_list ap;
+
+	clkdev_alloc_valist(cl, clk, con_id, dev_fmt, ap);
+
+	if (!cl)
+		return -ENOMEM;
+
+	clkdev_add(cl);
+	return 0;
+}
+EXPORT_SYMBOL(clk_register_clkdev);
+
+int clk_register_clkdevs(struct clk *clk, struct clk_lookup *cl, size_t num)
+{
+	unsigned i;
+
+	if (!clk)
+		return -ENOMEM;
+
+	for (i = 0; i < num; i++, cl++) {
+		cl->clk = clk;
+		clkdev_add(cl);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(clk_register_clkdevs);
diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h
index d9a4fd0..01d8ff6 100644
--- a/include/linux/clkdev.h
+++ b/include/linux/clkdev.h
@@ -39,5 +39,8 @@ void clkdev_drop(struct clk_lookup *cl);
 
 void clkdev_add_table(struct clk_lookup *, size_t);
 int clk_add_alias(const char *, const char *, char *, struct device *);
+int clk_register_clkdev(struct clk *clk, const char *con_id,
+		const char *dev_fmt, ...);
+int clk_register_clkdevs(struct clk *clk, struct clk_lookup *cl, size_t num);
 
 #endif
-- 
1.7.9

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

* [PATCH V3 2/8] clk: add a fixed factor clock
  2012-04-24  6:50 [PATCH V3 0/8] SPEAr: Move to common clock framework Viresh Kumar
  2012-04-24  6:50 ` [PATCH V3 1/8] CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk * Viresh Kumar
@ 2012-04-24  6:50 ` Viresh Kumar
  2012-04-27  4:43   ` Viresh Kumar
  2012-05-02  9:48   ` Sascha Hauer
  2012-04-24  6:50 ` [PATCH V3 3/8] SPEAr: clk: Add VCO-PLL Synthesizer clock Viresh Kumar
                   ` (5 subsequent siblings)
  7 siblings, 2 replies; 42+ messages in thread
From: Viresh Kumar @ 2012-04-24  6:50 UTC (permalink / raw)
  To: linux-arm-kernel

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>
---
Sascha,

I have this patch in my set, because i need this to get SPEAr stuff pushed by
Mike. I have updated your original patch, with all the review comments you got
on it. Please check see if i have corrupted something.

 drivers/clk/Makefile           |    2 +-
 drivers/clk/clk-fixed-factor.c |   94 ++++++++++++++++++++++++++++++++++++++++
 include/linux/clk-private.h    |   20 ++++++++
 include/linux/clk-provider.h   |   23 ++++++++++
 4 files changed, 138 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..7453efe
--- /dev/null
+++ b/drivers/clk/clk-fixed-factor.c
@@ -0,0 +1,94 @@
+/*
+ * 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 (prate) {
+		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;
+	} else {
+		return (__clk_get_rate(__clk_get_parent(hw->clk)) / fix->div) *
+			fix->mult;
+	}
+}
+
+static int clk_factor_set_rate(struct clk_hw *hw, unsigned long 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 *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;
+
+	clk = clk_register(dev, name,
+			&clk_fixed_factor_ops, &fix->hw,
+			&parent_name,
+			(parent_name ? 1 : 0),
+			flags);
+
+	if (clk)
+		return clk;
+
+	kfree(fix);
+
+	return NULL;
+}
diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h
index eeae7a3..1e0fa93 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 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, _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 8e85a9d..067b04d 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -260,6 +260,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
  * @name: clock name
-- 
1.7.9

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

* [PATCH V3 3/8] SPEAr: clk: Add VCO-PLL Synthesizer clock
  2012-04-24  6:50 [PATCH V3 0/8] SPEAr: Move to common clock framework Viresh Kumar
  2012-04-24  6:50 ` [PATCH V3 1/8] CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk * Viresh Kumar
  2012-04-24  6:50 ` [PATCH V3 2/8] clk: add a fixed factor clock Viresh Kumar
@ 2012-04-24  6:50 ` Viresh Kumar
  2012-04-27  4:44   ` Viresh Kumar
                     ` (2 more replies)
  2012-04-24  6:50 ` [PATCH V3 4/8] SPEAr: clk: Add Auxiliary " Viresh Kumar
                   ` (4 subsequent siblings)
  7 siblings, 3 replies; 42+ messages in thread
From: Viresh Kumar @ 2012-04-24  6:50 UTC (permalink / raw)
  To: linux-arm-kernel

All SPEAr SoC's contain PLLs. Their Fout is derived based on following equations

- In normal mode
  vco = (2 * M[15:8] * Fin)/N

- In Dithered mode
  vco = (2 * M[15:0] * Fin)/(256 * N)

pll_rate = vco/2^p

vco and pll are very closely bound to each other,
"vco needs to program: mode, m & n" and "pll needs to program p",
both share common enable/disable logic and registers.

This patch adds in support for this type of clock.

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 drivers/clk/Makefile            |    3 +
 drivers/clk/spear/Makefile      |    5 +
 drivers/clk/spear/clk-vco-pll.c |  346 +++++++++++++++++++++++++++++++++++++++
 drivers/clk/spear/clk.c         |   36 ++++
 drivers/clk/spear/clk.h         |   57 +++++++
 5 files changed, 447 insertions(+), 0 deletions(-)
 create mode 100644 drivers/clk/spear/Makefile
 create mode 100644 drivers/clk/spear/clk-vco-pll.c
 create mode 100644 drivers/clk/spear/clk.c
 create mode 100644 drivers/clk/spear/clk.h

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 24aa714..0f5e03d 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -2,3 +2,6 @@
 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-fixed-factor.o
+
+# SoCs specific
+obj-$(CONFIG_PLAT_SPEAR)	+= spear/
diff --git a/drivers/clk/spear/Makefile b/drivers/clk/spear/Makefile
new file mode 100644
index 0000000..3fc2a30
--- /dev/null
+++ b/drivers/clk/spear/Makefile
@@ -0,0 +1,5 @@
+#
+# SPEAr Clock specific Makefile
+#
+
+obj-y	+= clk.o clk-vco-pll.o
diff --git a/drivers/clk/spear/clk-vco-pll.c b/drivers/clk/spear/clk-vco-pll.c
new file mode 100644
index 0000000..9efa30d
--- /dev/null
+++ b/drivers/clk/spear/clk-vco-pll.c
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.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.
+ *
+ * VCO-PLL clock implementation
+ */
+
+#define pr_fmt(fmt) "clk-vco-pll: " fmt
+
+#include <linux/clk-provider.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include "clk.h"
+
+/*
+ * DOC: VCO-PLL clock
+ *
+ * VCO and PLL rate are derived from following equations:
+ *
+ * In normal mode
+ * vco = (2 * M[15:8] * Fin)/N
+ *
+ * In Dithered mode
+ * vco = (2 * M[15:0] * Fin)/(256 * N)
+ *
+ * pll_rate = pll/2^p
+ *
+ * vco and pll are very closely bound to each other, "vco needs to program:
+ * mode, m & n" and "pll needs to program p", both share common enable/disable
+ * logic.
+ *
+ * clk_register_vco_pll() registers instances of both vco & pll.
+ * CLK_SET_RATE_PARENT flag is forced for pll, as it will always pass its
+ * set_rate to vco. A single rate table exists for both the clocks, which
+ * configures m, n and p.
+ */
+
+/* PLL_CTR register masks */
+#define PLL_MODE_NORMAL		0
+#define PLL_MODE_FRACTION	1
+#define PLL_MODE_DITH_DSM	2
+#define PLL_MODE_DITH_SSM	3
+#define PLL_MODE_MASK		3
+#define PLL_MODE_SHIFT		3
+#define PLL_ENABLE		2
+
+#define PLL_LOCK_SHIFT		0
+#define PLL_LOCK_MASK		1
+
+/* PLL FRQ register masks */
+#define PLL_NORM_FDBK_M_MASK	0xFF
+#define PLL_NORM_FDBK_M_SHIFT	24
+#define PLL_DITH_FDBK_M_MASK	0xFFFF
+#define PLL_DITH_FDBK_M_SHIFT	16
+#define PLL_DIV_P_MASK		0x7
+#define PLL_DIV_P_SHIFT		8
+#define PLL_DIV_N_MASK		0xFF
+#define PLL_DIV_N_SHIFT		0
+
+#define to_clk_vco(_hw) container_of(_hw, struct clk_vco, hw)
+#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw)
+
+/* Calculates pll clk rate for specific value of mode, m, n and p */
+static unsigned long pll_calc_rate(struct pll_rate_tbl *rtbl,
+		unsigned long prate, int index, unsigned long *pll_rate)
+{
+	unsigned long rate = prate;
+	unsigned int mode;
+
+	mode = rtbl[index].mode ? 256 : 1;
+	rate = (((2 * rate / 10000) * rtbl[index].m) / (mode * rtbl[index].n));
+
+	if (pll_rate)
+		*pll_rate = (rate / (1 << rtbl[index].p)) * 10000;
+
+	return rate * 10000;
+}
+
+static long clk_pll_round_rate_index(struct clk_hw *hw, unsigned long drate,
+				unsigned long *prate, int *index)
+{
+	struct clk_pll *pll = to_clk_pll(hw);
+	unsigned long prev_rate, vco_prev_rate, rate = 0;
+	unsigned long vco_parent_rate =
+		__clk_get_rate(__clk_get_parent(__clk_get_parent(hw->clk)));
+
+	if (!prate) {
+		pr_err("%s: prate is must for pll clk\n", __func__);
+		return -EINVAL;
+	}
+
+	for (*index = 0; *index < pll->vco->rtbl_cnt; (*index)++) {
+		prev_rate = rate;
+		vco_prev_rate = *prate;
+		*prate = pll_calc_rate(pll->vco->rtbl, vco_parent_rate, *index,
+				&rate);
+		if (drate < rate) {
+			/* previous clock was best */
+			if (*index) {
+				rate = prev_rate;
+				*prate = vco_prev_rate;
+				(*index)--;
+			}
+			break;
+		}
+	}
+
+	return rate;
+}
+
+static long clk_pll_round_rate(struct clk_hw *hw, unsigned long drate,
+				unsigned long *prate)
+{
+	int unused;
+
+	return clk_pll_round_rate_index(hw, drate, prate, &unused);
+}
+
+static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, unsigned long
+		parent_rate)
+{
+	struct clk_pll *pll = to_clk_pll(hw);
+	unsigned long flags = 0;
+	unsigned int p;
+
+	if (pll->vco->lock)
+		spin_lock_irqsave(pll->vco->lock, flags);
+
+	p = readl_relaxed(pll->vco->cfg_reg);
+
+	if (pll->vco->lock)
+		spin_unlock_irqrestore(pll->vco->lock, flags);
+
+	p = (p >> PLL_DIV_P_SHIFT) & PLL_DIV_P_MASK;
+
+	return parent_rate / (1 << p);
+}
+
+static int clk_pll_set_rate(struct clk_hw *hw, unsigned long drate)
+{
+	struct clk_pll *pll = to_clk_pll(hw);
+	struct pll_rate_tbl *rtbl = pll->vco->rtbl;
+	unsigned long flags = 0, val;
+	int i;
+
+	clk_pll_round_rate_index(hw, drate, NULL, &i);
+
+	if (pll->vco->lock)
+		spin_lock_irqsave(pll->vco->lock, flags);
+
+	val = readl_relaxed(pll->vco->cfg_reg);
+	val &= ~(PLL_DIV_P_MASK << PLL_DIV_P_SHIFT);
+	val |= (rtbl[i].p & PLL_DIV_P_MASK) << PLL_DIV_P_SHIFT;
+	writel_relaxed(val, pll->vco->cfg_reg);
+
+	if (pll->vco->lock)
+		spin_unlock_irqrestore(pll->vco->lock, flags);
+
+	return 0;
+}
+
+static struct clk_ops clk_pll_ops = {
+	.recalc_rate = clk_pll_recalc_rate,
+	.round_rate = clk_pll_round_rate,
+	.set_rate = clk_pll_set_rate,
+};
+
+static inline unsigned long vco_calc_rate(struct clk_hw *hw,
+		unsigned long prate, int index)
+{
+	struct clk_vco *vco = to_clk_vco(hw);
+
+	return pll_calc_rate(vco->rtbl, prate, index, NULL);
+}
+
+static long clk_vco_round_rate(struct clk_hw *hw, unsigned long drate,
+		unsigned long *prate)
+{
+	struct clk_vco *vco = to_clk_vco(hw);
+	int unused;
+
+	return clk_round_rate_index(hw, drate, vco_calc_rate, vco->rtbl_cnt,
+			&unused);
+}
+
+static unsigned long clk_vco_recalc_rate(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	struct clk_vco *vco = to_clk_vco(hw);
+	unsigned long flags = 0;
+	unsigned int num = 2, den = 0, val, mode = 0;
+
+	if (vco->lock)
+		spin_lock_irqsave(vco->lock, flags);
+
+	mode = (readl_relaxed(vco->mode_reg) >> PLL_MODE_SHIFT) & PLL_MODE_MASK;
+
+	val = readl_relaxed(vco->cfg_reg);
+
+	if (vco->lock)
+		spin_unlock_irqrestore(vco->lock, flags);
+
+	den = (val >> PLL_DIV_N_SHIFT) & PLL_DIV_N_MASK;
+
+	/* calculate numerator & denominator */
+	if (!mode) {
+		/* Normal mode */
+		num *= (val >> PLL_NORM_FDBK_M_SHIFT) & PLL_NORM_FDBK_M_MASK;
+	} else {
+		/* Dithered mode */
+		num *= (val >> PLL_DITH_FDBK_M_SHIFT) & PLL_DITH_FDBK_M_MASK;
+		den *= 256;
+	}
+
+	if (!den) {
+		WARN(1, "%s: denominator can't be zero\n", __func__);
+		return 0;
+	}
+
+	return (((parent_rate / 10000) * num) / den) * 10000;
+}
+
+/* Configures new clock rate of vco */
+static int clk_vco_set_rate(struct clk_hw *hw, unsigned long drate)
+{
+	struct clk_vco *vco = to_clk_vco(hw);
+	struct pll_rate_tbl *rtbl = vco->rtbl;
+	unsigned long flags = 0, val;
+	int i;
+
+	clk_round_rate_index(hw, drate, vco_calc_rate, vco->rtbl_cnt, &i);
+
+	if (vco->lock)
+		spin_lock_irqsave(vco->lock, flags);
+
+	val = readl_relaxed(vco->mode_reg);
+	val &= ~(PLL_MODE_MASK << PLL_MODE_SHIFT);
+	val |= (rtbl[i].mode & PLL_MODE_MASK) << PLL_MODE_SHIFT;
+	writel_relaxed(val, vco->mode_reg);
+
+	val = readl_relaxed(vco->cfg_reg);
+	val &= ~(PLL_DIV_N_MASK << PLL_DIV_N_SHIFT);
+	val |= (rtbl[i].n & PLL_DIV_N_MASK) << PLL_DIV_N_SHIFT;
+
+	val &= ~(PLL_DITH_FDBK_M_MASK << PLL_DITH_FDBK_M_SHIFT);
+	if (rtbl[i].mode)
+		val |= (rtbl[i].m & PLL_DITH_FDBK_M_MASK) <<
+			PLL_DITH_FDBK_M_SHIFT;
+	else
+		val |= (rtbl[i].m & PLL_NORM_FDBK_M_MASK) <<
+			PLL_NORM_FDBK_M_SHIFT;
+
+	writel_relaxed(val, vco->cfg_reg);
+
+	if (vco->lock)
+		spin_unlock_irqrestore(vco->lock, flags);
+
+	return 0;
+}
+
+static struct clk_ops clk_vco_ops = {
+	.recalc_rate = clk_vco_recalc_rate,
+	.round_rate = clk_vco_round_rate,
+	.set_rate = clk_vco_set_rate,
+};
+
+struct clk *clk_register_vco_pll(const char *vco_name, const char *pll_name,
+		const char *vco_gate_name, const char *parent_name,
+		unsigned long flags, void __iomem *mode_reg, void __iomem
+		*cfg_reg, struct pll_rate_tbl *rtbl, u8 rtbl_cnt,
+		spinlock_t *lock, struct clk **pll_clk,
+		struct clk **vco_gate_clk)
+{
+	struct clk_vco *vco;
+	struct clk_pll *pll;
+	struct clk *vco_clk, *tpll_clk, *tvco_gate_clk;
+	const char **vco_parent_name;
+
+	if (!vco_name || !pll_name || !parent_name || !mode_reg || !cfg_reg ||
+			!rtbl || !rtbl_cnt) {
+		pr_err("Invalid arguments passed");
+		return ERR_PTR(-EINVAL);
+	}
+
+	vco = kzalloc(sizeof(*vco), GFP_KERNEL);
+	if (!vco) {
+		pr_err("could not allocate vco clk\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll) {
+		pr_err("could not allocate pll clk\n");
+		goto free_vco;
+	}
+
+	/* struct clk_vco assignments */
+	vco->mode_reg = mode_reg;
+	vco->cfg_reg = cfg_reg;
+	vco->rtbl = rtbl;
+	vco->rtbl_cnt = rtbl_cnt;
+	vco->lock = lock;
+	pll->vco = vco;
+
+	if (vco_gate_name) {
+		tvco_gate_clk = clk_register_gate(NULL, vco_gate_name,
+				parent_name, 0, mode_reg, PLL_ENABLE, 0, lock);
+		if (IS_ERR_OR_NULL(tvco_gate_clk))
+			goto free_pll;
+
+		if (vco_gate_clk)
+			*vco_gate_clk = tvco_gate_clk;
+		vco_parent_name = &vco_gate_name;
+	} else {
+		vco_parent_name = &parent_name;
+	}
+
+	vco_clk = clk_register(NULL, vco_name, &clk_vco_ops, &vco->hw,
+			vco_parent_name, 1, flags);
+	if (IS_ERR_OR_NULL(vco_clk))
+		goto free_pll;
+
+	tpll_clk = clk_register(NULL, pll_name, &clk_pll_ops, &pll->hw,
+			&vco_name, 1, CLK_SET_RATE_PARENT);
+	if (IS_ERR_OR_NULL(tpll_clk))
+		goto free_pll;
+
+	if (pll_clk)
+		*pll_clk = tpll_clk;
+
+	return vco_clk;
+
+free_pll:
+	kfree(pll);
+free_vco:
+	kfree(vco);
+
+	pr_err("Failed to register vco pll clock\n");
+
+	return ERR_PTR(-ENOMEM);
+}
diff --git a/drivers/clk/spear/clk.c b/drivers/clk/spear/clk.c
new file mode 100644
index 0000000..74f6acc
--- /dev/null
+++ b/drivers/clk/spear/clk.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.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.
+ *
+ * SPEAr clk - Common routines
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/types.h>
+#include "clk.h"
+
+long clk_round_rate_index(struct clk_hw *hw, unsigned long drate,
+		clk_calc_rate calc_rate, u8 rtbl_cnt, int *index)
+{
+	unsigned long prev_rate, rate = 0;
+	unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
+
+	for (*index = 0; *index < rtbl_cnt; (*index)++) {
+		prev_rate = rate;
+		rate = calc_rate(hw, parent_rate, *index);
+		if (drate < rate) {
+			/* previous clock was best */
+			if (*index) {
+				rate = prev_rate;
+				(*index)--;
+			}
+			break;
+		}
+	}
+
+	return rate;
+}
diff --git a/drivers/clk/spear/clk.h b/drivers/clk/spear/clk.h
new file mode 100644
index 0000000..18201bf
--- /dev/null
+++ b/drivers/clk/spear/clk.h
@@ -0,0 +1,57 @@
+/*
+ * Clock framework definitions for SPEAr platform
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.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.
+ */
+
+#ifndef __SPEAR_CLK_H
+#define __SPEAR_CLK_H
+
+#include <linux/clk-provider.h>
+#include <linux/spinlock_types.h>
+#include <linux/types.h>
+
+/* VCO-PLL clk */
+struct pll_rate_tbl {
+	u8 mode;
+	u16 m;
+	u8 n;
+	u8 p;
+};
+
+struct clk_vco {
+	struct			clk_hw hw;
+	void __iomem		*mode_reg;
+	void __iomem		*cfg_reg;
+	struct pll_rate_tbl	*rtbl;
+	u8			rtbl_cnt;
+	spinlock_t		*lock;
+};
+
+struct clk_pll {
+	struct			clk_hw hw;
+	struct clk_vco		*vco;
+	const char		*parent[1];
+	spinlock_t		*lock;
+};
+
+typedef unsigned long (*clk_calc_rate)(struct clk_hw *hw, unsigned long prate,
+		int index);
+
+/* clk register routines */
+struct clk *clk_register_vco_pll(const char *vco_name, const char *pll_name,
+		const char *vco_gate_name, const char *parent_name,
+		unsigned long flags, void __iomem *mode_reg, void __iomem
+		*cfg_reg, struct pll_rate_tbl *rtbl, u8 rtbl_cnt,
+		spinlock_t *lock, struct clk **pll_clk,
+		struct clk **vco_gate_clk);
+
+long clk_round_rate_index(struct clk_hw *hw, unsigned long drate,
+		clk_calc_rate calc_rate, u8 rtbl_cnt, int *index);
+
+#endif /* __SPEAR_CLK_H */
-- 
1.7.9

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

* [PATCH V3 4/8] SPEAr: clk: Add Auxiliary Synthesizer clock
  2012-04-24  6:50 [PATCH V3 0/8] SPEAr: Move to common clock framework Viresh Kumar
                   ` (2 preceding siblings ...)
  2012-04-24  6:50 ` [PATCH V3 3/8] SPEAr: clk: Add VCO-PLL Synthesizer clock Viresh Kumar
@ 2012-04-24  6:50 ` Viresh Kumar
  2012-04-27  4:45   ` Viresh Kumar
                     ` (2 more replies)
  2012-04-24  6:50 ` [PATCH V3 5/8] SPEAr: clk: Add Fractional " Viresh Kumar
                   ` (3 subsequent siblings)
  7 siblings, 3 replies; 42+ messages in thread
From: Viresh Kumar @ 2012-04-24  6:50 UTC (permalink / raw)
  To: linux-arm-kernel

All SPEAr SoC's contain Auxiliary Synthesizers. Their Fout is derived based on
values of eq, x and y.

Fout from synthesizer can be given from two equations:
Fout1 = (Fin * X/Y)/2		EQ1
Fout2 = Fin * X/Y		EQ2

This patch adds in support for this type of clock.

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 drivers/clk/spear/Makefile        |    2 +-
 drivers/clk/spear/clk-aux-synth.c |  189 +++++++++++++++++++++++++++++++++++++
 drivers/clk/spear/clk.h           |   43 +++++++++
 3 files changed, 233 insertions(+), 1 deletions(-)
 create mode 100644 drivers/clk/spear/clk-aux-synth.c

diff --git a/drivers/clk/spear/Makefile b/drivers/clk/spear/Makefile
index 3fc2a30..e36d8c6 100644
--- a/drivers/clk/spear/Makefile
+++ b/drivers/clk/spear/Makefile
@@ -2,4 +2,4 @@
 # SPEAr Clock specific Makefile
 #
 
-obj-y	+= clk.o clk-vco-pll.o
+obj-y	+= clk.o clk-aux-synth.o clk-vco-pll.o
diff --git a/drivers/clk/spear/clk-aux-synth.c b/drivers/clk/spear/clk-aux-synth.c
new file mode 100644
index 0000000..e01a350
--- /dev/null
+++ b/drivers/clk/spear/clk-aux-synth.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.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.
+ *
+ * Auxiliary Synthesizer clock implementation
+ */
+
+#define pr_fmt(fmt) "clk-aux-synth: " fmt
+
+#include <linux/clk-provider.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include "clk.h"
+
+/*
+ * DOC: Auxiliary Synthesizer clock
+ *
+ * Aux synth gives rate for different values of eq, x and y
+ *
+ * Fout from synthesizer can be given from two equations:
+ * Fout1 = (Fin * X/Y)/2		EQ1
+ * Fout2 = Fin * X/Y			EQ2
+ */
+
+#define to_clk_aux(_hw) container_of(_hw, struct clk_aux, hw)
+
+static struct aux_clk_masks default_aux_masks = {
+	.eq_sel_mask = AUX_EQ_SEL_MASK,
+	.eq_sel_shift = AUX_EQ_SEL_SHIFT,
+	.eq1_mask = AUX_EQ1_SEL,
+	.eq2_mask = AUX_EQ2_SEL,
+	.xscale_sel_mask = AUX_XSCALE_MASK,
+	.xscale_sel_shift = AUX_XSCALE_SHIFT,
+	.yscale_sel_mask = AUX_YSCALE_MASK,
+	.yscale_sel_shift = AUX_YSCALE_SHIFT,
+	.enable_bit = AUX_SYNT_ENB,
+};
+
+static unsigned long aux_calc_rate(struct clk_hw *hw, unsigned long prate,
+		int index)
+{
+	struct clk_aux *aux = to_clk_aux(hw);
+	struct aux_rate_tbl *rtbl = aux->rtbl;
+	u8 eq = rtbl[index].eq ? 1 : 2;
+
+	return (((prate / 10000) * rtbl[index].xscale) /
+			(rtbl[index].yscale * eq)) * 10000;
+}
+
+static long clk_aux_round_rate(struct clk_hw *hw, unsigned long drate,
+		unsigned long *prate)
+{
+	struct clk_aux *aux = to_clk_aux(hw);
+	int unused;
+
+	return clk_round_rate_index(hw, drate, aux_calc_rate, aux->rtbl_cnt,
+			&unused);
+}
+
+static unsigned long clk_aux_recalc_rate(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	struct clk_aux *aux = to_clk_aux(hw);
+	unsigned int num = 1, den = 1, val, eqn;
+	unsigned long flags = 0;
+
+	if (aux->lock)
+		spin_lock_irqsave(aux->lock, flags);
+
+	val = readl_relaxed(aux->reg);
+
+	if (aux->lock)
+		spin_unlock_irqrestore(aux->lock, flags);
+
+	eqn = (val >> aux->masks->eq_sel_shift) & aux->masks->eq_sel_mask;
+	if (eqn == aux->masks->eq1_mask)
+		den = 2;
+
+	/* calculate numerator */
+	num = (val >> aux->masks->xscale_sel_shift) &
+		aux->masks->xscale_sel_mask;
+
+	/* calculate denominator */
+	den *= (val >> aux->masks->yscale_sel_shift) &
+		aux->masks->yscale_sel_mask;
+
+	if (!den)
+		return 0;
+
+	return (((parent_rate / 10000) * num) / den) * 10000;
+}
+
+/* Configures new clock rate of aux */
+static int clk_aux_set_rate(struct clk_hw *hw, unsigned long drate)
+{
+	struct clk_aux *aux = to_clk_aux(hw);
+	struct aux_rate_tbl *rtbl = aux->rtbl;
+	unsigned long val, flags = 0;
+	int i;
+
+	clk_round_rate_index(hw, drate, aux_calc_rate, aux->rtbl_cnt, &i);
+
+	if (aux->lock)
+		spin_lock_irqsave(aux->lock, flags);
+
+	val = readl_relaxed(aux->reg) &
+		~(aux->masks->eq_sel_mask << aux->masks->eq_sel_shift);
+	val |= (rtbl[i].eq & aux->masks->eq_sel_mask) <<
+		aux->masks->eq_sel_shift;
+	val &= ~(aux->masks->xscale_sel_mask << aux->masks->xscale_sel_shift);
+	val |= (rtbl[i].xscale & aux->masks->xscale_sel_mask) <<
+		aux->masks->xscale_sel_shift;
+	val &= ~(aux->masks->yscale_sel_mask << aux->masks->yscale_sel_shift);
+	val |= (rtbl[i].yscale & aux->masks->yscale_sel_mask) <<
+		aux->masks->yscale_sel_shift;
+	writel_relaxed(val, aux->reg);
+
+	if (aux->lock)
+		spin_unlock_irqrestore(aux->lock, flags);
+
+	return 0;
+}
+
+static struct clk_ops clk_aux_ops = {
+	.recalc_rate = clk_aux_recalc_rate,
+	.round_rate = clk_aux_round_rate,
+	.set_rate = clk_aux_set_rate,
+};
+
+struct clk *clk_register_aux(const char *aux_name, const char *gate_name,
+		const char *parent_name, unsigned long flags, void __iomem *reg,
+		struct aux_clk_masks *masks, struct aux_rate_tbl *rtbl,
+		u8 rtbl_cnt, spinlock_t *lock, struct clk **gate_clk)
+{
+	struct clk_aux *aux;
+	struct clk *clk;
+
+	if (!aux_name || !parent_name || !reg || !rtbl || !rtbl_cnt) {
+		pr_err("Invalid arguments passed");
+		return ERR_PTR(-EINVAL);
+	}
+
+	aux = kzalloc(sizeof(*aux), GFP_KERNEL);
+	if (!aux) {
+		pr_err("could not allocate aux clk\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	/* struct clk_aux assignments */
+	if (!masks)
+		aux->masks = &default_aux_masks;
+	else
+		aux->masks = masks;
+
+	aux->reg = reg;
+	aux->rtbl = rtbl;
+	aux->rtbl_cnt = rtbl_cnt;
+	aux->lock = lock;
+
+	clk = clk_register(NULL, aux_name, &clk_aux_ops, &aux->hw, &parent_name,
+			1, flags);
+	if (IS_ERR_OR_NULL(clk))
+		goto free_aux;
+
+	if (gate_name) {
+		struct clk *tgate_clk;
+
+		tgate_clk = clk_register_gate(NULL, gate_name, aux_name, 0, reg,
+				aux->masks->enable_bit, 0, lock);
+		if (IS_ERR_OR_NULL(tgate_clk))
+			goto free_aux;
+
+		if (gate_clk)
+			*gate_clk = tgate_clk;
+	}
+
+	return clk;
+
+free_aux:
+	kfree(aux);
+	pr_err("clk register failed\n");
+
+	return NULL;
+}
diff --git a/drivers/clk/spear/clk.h b/drivers/clk/spear/clk.h
index 18201bf..ae3dc44 100644
--- a/drivers/clk/spear/clk.h
+++ b/drivers/clk/spear/clk.h
@@ -16,6 +16,45 @@
 #include <linux/spinlock_types.h>
 #include <linux/types.h>
 
+/* Auxiliary Synth clk */
+/* Default masks */
+#define AUX_EQ_SEL_SHIFT	30
+#define AUX_EQ_SEL_MASK		1
+#define AUX_EQ1_SEL		0
+#define AUX_EQ2_SEL		1
+#define AUX_XSCALE_SHIFT	16
+#define AUX_XSCALE_MASK		0xFFF
+#define AUX_YSCALE_SHIFT	0
+#define AUX_YSCALE_MASK		0xFFF
+#define AUX_SYNT_ENB		31
+
+struct aux_clk_masks {
+	u32 eq_sel_mask;
+	u32 eq_sel_shift;
+	u32 eq1_mask;
+	u32 eq2_mask;
+	u32 xscale_sel_mask;
+	u32 xscale_sel_shift;
+	u32 yscale_sel_mask;
+	u32 yscale_sel_shift;
+	u32 enable_bit;
+};
+
+struct aux_rate_tbl {
+	u16 xscale;
+	u16 yscale;
+	u8 eq;
+};
+
+struct clk_aux {
+	struct			clk_hw hw;
+	void __iomem		*reg;
+	struct aux_clk_masks	*masks;
+	struct aux_rate_tbl	*rtbl;
+	u8			rtbl_cnt;
+	spinlock_t		*lock;
+};
+
 /* VCO-PLL clk */
 struct pll_rate_tbl {
 	u8 mode;
@@ -44,6 +83,10 @@ typedef unsigned long (*clk_calc_rate)(struct clk_hw *hw, unsigned long prate,
 		int index);
 
 /* clk register routines */
+struct clk *clk_register_aux(const char *aux_name, const char *gate_name,
+		const char *parent_name, unsigned long flags, void __iomem *reg,
+		struct aux_clk_masks *masks, struct aux_rate_tbl *rtbl,
+		u8 rtbl_cnt, spinlock_t *lock, struct clk **gate_clk);
 struct clk *clk_register_vco_pll(const char *vco_name, const char *pll_name,
 		const char *vco_gate_name, const char *parent_name,
 		unsigned long flags, void __iomem *mode_reg, void __iomem
-- 
1.7.9

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

* [PATCH V3 5/8] SPEAr: clk: Add Fractional Synthesizer clock
  2012-04-24  6:50 [PATCH V3 0/8] SPEAr: Move to common clock framework Viresh Kumar
                   ` (3 preceding siblings ...)
  2012-04-24  6:50 ` [PATCH V3 4/8] SPEAr: clk: Add Auxiliary " Viresh Kumar
@ 2012-04-24  6:50 ` Viresh Kumar
  2012-04-27  4:45   ` Viresh Kumar
                     ` (2 more replies)
  2012-04-24  6:50 ` [PATCH V3 6/8] SPEAr: clk: Add General Purpose Timer " Viresh Kumar
                   ` (2 subsequent siblings)
  7 siblings, 3 replies; 42+ messages in thread
From: Viresh Kumar @ 2012-04-24  6:50 UTC (permalink / raw)
  To: linux-arm-kernel

All SPEAr SoC's contain Fractional Synthesizers. Their Fout is derived from
following equations:

Fout = Fin / (2 * div) (division factor)
div is 17 bits:-
     0-13 (fractional part)
     14-16 (integer part)
     div is (16-14 bits).(13-0 bits) (in binary)

     Fout = Fin/(2 * div)
     Fout = ((Fin / 10000)/(2 * div)) * 10000
     Fout = (2^14 * (Fin / 10000)/(2^14 * (2 * div))) * 10000
     Fout = (((Fin / 10000) << 14)/(2 * (div << 14))) * 10000

div << 14 is simply 17 bit value written at register.

This patch adds in support for this type of clock.

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 drivers/clk/spear/Makefile         |    2 +-
 drivers/clk/spear/clk-frac-synth.c |  156 ++++++++++++++++++++++++++++++++++++
 drivers/clk/spear/clk.h            |   16 ++++
 3 files changed, 173 insertions(+), 1 deletions(-)
 create mode 100644 drivers/clk/spear/clk-frac-synth.c

diff --git a/drivers/clk/spear/Makefile b/drivers/clk/spear/Makefile
index e36d8c6..1827036 100644
--- a/drivers/clk/spear/Makefile
+++ b/drivers/clk/spear/Makefile
@@ -2,4 +2,4 @@
 # SPEAr Clock specific Makefile
 #
 
-obj-y	+= clk.o clk-aux-synth.o clk-vco-pll.o
+obj-y	+= clk.o clk-aux-synth.o clk-frac-synth.o clk-vco-pll.o
diff --git a/drivers/clk/spear/clk-frac-synth.c b/drivers/clk/spear/clk-frac-synth.c
new file mode 100644
index 0000000..c6ccdab
--- /dev/null
+++ b/drivers/clk/spear/clk-frac-synth.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.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.
+ *
+ * Fractional Synthesizer clock implementation
+ */
+
+#define pr_fmt(fmt) "clk-frac-synth: " fmt
+
+#include <linux/clk-provider.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include "clk.h"
+
+#define DIV_FACTOR_MASK		0x1FFFF
+
+/*
+ * DOC: Fractional Synthesizer clock
+ *
+ * Fout from synthesizer can be given from below equation:
+ *
+ * Fout= Fin/2*div (division factor)
+ * div is 17 bits:-
+ *	0-13 (fractional part)
+ *	14-16 (integer part)
+ *	div is (16-14 bits).(13-0 bits) (in binary)
+ *
+ *	Fout = Fin/(2 * div)
+ *	Fout = ((Fin / 10000)/(2 * div)) * 10000
+ *	Fout = (2^14 * (Fin / 10000)/(2^14 * (2 * div))) * 10000
+ *	Fout = (((Fin / 10000) << 14)/(2 * (div << 14))) * 10000
+ *
+ * div << 14 simply 17 bit value written@register.
+ * Max error due to scaling down by 10000 is 10 KHz
+ */
+
+#define to_clk_frac(_hw) container_of(_hw, struct clk_frac, hw)
+
+static unsigned long frac_calc_rate(struct clk_hw *hw, unsigned long prate,
+		int index)
+{
+	struct clk_frac *frac = to_clk_frac(hw);
+	struct frac_rate_tbl *rtbl = frac->rtbl;
+
+	prate /= 10000;
+	prate <<= 14;
+	prate /= (2 * rtbl[index].div);
+	prate *= 10000;
+
+	return prate;
+}
+
+static long clk_frac_round_rate(struct clk_hw *hw, unsigned long drate,
+		unsigned long *prate)
+{
+	struct clk_frac *frac = to_clk_frac(hw);
+	int unused;
+
+	return clk_round_rate_index(hw, drate, frac_calc_rate, frac->rtbl_cnt,
+			&unused);
+}
+
+static unsigned long clk_frac_recalc_rate(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	struct clk_frac *frac = to_clk_frac(hw);
+	unsigned long flags = 0;
+	unsigned int div = 1, val;
+
+	if (frac->lock)
+		spin_lock_irqsave(frac->lock, flags);
+
+	val = readl_relaxed(frac->reg);
+
+	if (frac->lock)
+		spin_unlock_irqrestore(frac->lock, flags);
+
+	div = val & DIV_FACTOR_MASK;
+
+	if (!div)
+		return 0;
+
+	parent_rate = parent_rate / 10000;
+
+	parent_rate = (parent_rate << 14) / (2 * div);
+	return parent_rate * 10000;
+}
+
+/* Configures new clock rate of frac */
+static int clk_frac_set_rate(struct clk_hw *hw, unsigned long drate)
+{
+	struct clk_frac *frac = to_clk_frac(hw);
+	struct frac_rate_tbl *rtbl = frac->rtbl;
+	unsigned long flags = 0, val;
+	int i;
+
+	clk_round_rate_index(hw, drate, frac_calc_rate, frac->rtbl_cnt, &i);
+
+	if (frac->lock)
+		spin_lock_irqsave(frac->lock, flags);
+
+	val = readl_relaxed(frac->reg) & ~DIV_FACTOR_MASK;
+	val |= rtbl[i].div & DIV_FACTOR_MASK;
+	writel_relaxed(val, frac->reg);
+
+	if (frac->lock)
+		spin_unlock_irqrestore(frac->lock, flags);
+
+	return 0;
+}
+
+struct clk_ops clk_frac_ops = {
+	.recalc_rate = clk_frac_recalc_rate,
+	.round_rate = clk_frac_round_rate,
+	.set_rate = clk_frac_set_rate,
+};
+
+struct clk *clk_register_frac(const char *name, const char *parent_name,
+		unsigned long flags, void __iomem *reg,
+		struct frac_rate_tbl *rtbl, u8 rtbl_cnt, spinlock_t *lock)
+{
+	struct clk_frac *frac;
+	struct clk *clk;
+
+	if (!name || !parent_name || !reg || !rtbl || !rtbl_cnt) {
+		pr_err("Invalid arguments passed");
+		return ERR_PTR(-EINVAL);
+	}
+
+	frac = kzalloc(sizeof(*frac), GFP_KERNEL);
+	if (!frac) {
+		pr_err("could not allocate frac clk\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	/* struct clk_frac assignments */
+	frac->reg = reg;
+	frac->rtbl = rtbl;
+	frac->rtbl_cnt = rtbl_cnt;
+	frac->lock = lock;
+
+	clk = clk_register(NULL, name, &clk_frac_ops, &frac->hw, &parent_name,
+			1, flags);
+	if (!IS_ERR_OR_NULL(clk))
+		return clk;
+
+	pr_err("clk register failed\n");
+	kfree(frac);
+
+	return NULL;
+}
diff --git a/drivers/clk/spear/clk.h b/drivers/clk/spear/clk.h
index ae3dc44..c7dbc84 100644
--- a/drivers/clk/spear/clk.h
+++ b/drivers/clk/spear/clk.h
@@ -55,6 +55,19 @@ struct clk_aux {
 	spinlock_t		*lock;
 };
 
+/* Fractional Synth clk */
+struct frac_rate_tbl {
+	u32 div;
+};
+
+struct clk_frac {
+	struct			clk_hw hw;
+	void __iomem		*reg;
+	struct frac_rate_tbl	*rtbl;
+	u8			rtbl_cnt;
+	spinlock_t		*lock;
+};
+
 /* VCO-PLL clk */
 struct pll_rate_tbl {
 	u8 mode;
@@ -87,6 +100,9 @@ struct clk *clk_register_aux(const char *aux_name, const char *gate_name,
 		const char *parent_name, unsigned long flags, void __iomem *reg,
 		struct aux_clk_masks *masks, struct aux_rate_tbl *rtbl,
 		u8 rtbl_cnt, spinlock_t *lock, struct clk **gate_clk);
+struct clk *clk_register_frac(const char *name, const char *parent_name,
+		unsigned long flags, void __iomem *reg,
+		struct frac_rate_tbl *rtbl, u8 rtbl_cnt, spinlock_t *lock);
 struct clk *clk_register_vco_pll(const char *vco_name, const char *pll_name,
 		const char *vco_gate_name, const char *parent_name,
 		unsigned long flags, void __iomem *mode_reg, void __iomem
-- 
1.7.9

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

* [PATCH V3 6/8] SPEAr: clk: Add General Purpose Timer Synthesizer clock
  2012-04-24  6:50 [PATCH V3 0/8] SPEAr: Move to common clock framework Viresh Kumar
                   ` (4 preceding siblings ...)
  2012-04-24  6:50 ` [PATCH V3 5/8] SPEAr: clk: Add Fractional " Viresh Kumar
@ 2012-04-24  6:50 ` Viresh Kumar
  2012-04-27  4:46   ` Viresh Kumar
                     ` (2 more replies)
  2012-04-24  6:50 ` [PATCH V3 7/8] SPEAr: Call clk_prepare() before calling clk_enable Viresh Kumar
  2012-04-27  4:42 ` [PATCH V3 0/8] SPEAr: Move to common clock framework Viresh Kumar
  7 siblings, 3 replies; 42+ messages in thread
From: Viresh Kumar @ 2012-04-24  6:50 UTC (permalink / raw)
  To: linux-arm-kernel

All SPEAr SoC's contain GPT Synthesizers. Their Fout is derived from
following equations:

Fout= Fin/((2 ^ (N+1)) * (M+1))

This patch adds in support for this type of clock.

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 drivers/clk/spear/Makefile        |    2 +-
 drivers/clk/spear/clk-gpt-synth.c |  145 +++++++++++++++++++++++++++++++++++++
 drivers/clk/spear/clk.h           |   17 +++++
 3 files changed, 163 insertions(+), 1 deletions(-)
 create mode 100644 drivers/clk/spear/clk-gpt-synth.c

diff --git a/drivers/clk/spear/Makefile b/drivers/clk/spear/Makefile
index 1827036..9e64824 100644
--- a/drivers/clk/spear/Makefile
+++ b/drivers/clk/spear/Makefile
@@ -2,4 +2,4 @@
 # SPEAr Clock specific Makefile
 #
 
-obj-y	+= clk.o clk-aux-synth.o clk-frac-synth.o clk-vco-pll.o
+obj-y	+= clk.o clk-aux-synth.o clk-frac-synth.o clk-gpt-synth.o clk-vco-pll.o
diff --git a/drivers/clk/spear/clk-gpt-synth.c b/drivers/clk/spear/clk-gpt-synth.c
new file mode 100644
index 0000000..514539c
--- /dev/null
+++ b/drivers/clk/spear/clk-gpt-synth.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.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.
+ *
+ * General Purpose Timer Synthesizer clock implementation
+ */
+
+#define pr_fmt(fmt) "clk-gpt-synth: " fmt
+
+#include <linux/clk-provider.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include "clk.h"
+
+#define GPT_MSCALE_MASK		0xFFF
+#define GPT_NSCALE_SHIFT	12
+#define GPT_NSCALE_MASK		0xF
+
+/*
+ * DOC: General Purpose Timer Synthesizer clock
+ *
+ * Calculates gpt synth clk rate for different values of mscale and nscale
+ *
+ * Fout= Fin/((2 ^ (N+1)) * (M+1))
+ */
+
+#define to_clk_gpt(_hw) container_of(_hw, struct clk_gpt, hw)
+
+static unsigned long gpt_calc_rate(struct clk_hw *hw, unsigned long prate,
+		int index)
+{
+	struct clk_gpt *gpt = to_clk_gpt(hw);
+	struct gpt_rate_tbl *rtbl = gpt->rtbl;
+
+	prate /= ((1 << (rtbl[index].nscale + 1)) * (rtbl[index].mscale + 1));
+
+	return prate;
+}
+
+static long clk_gpt_round_rate(struct clk_hw *hw, unsigned long drate,
+		unsigned long *prate)
+{
+	struct clk_gpt *gpt = to_clk_gpt(hw);
+	int unused;
+
+	return clk_round_rate_index(hw, drate, gpt_calc_rate, gpt->rtbl_cnt,
+			&unused);
+}
+
+static unsigned long clk_gpt_recalc_rate(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	struct clk_gpt *gpt = to_clk_gpt(hw);
+	unsigned long flags = 0;
+	unsigned int div = 1, val;
+
+	if (gpt->lock)
+		spin_lock_irqsave(gpt->lock, flags);
+
+	val = readl_relaxed(gpt->reg);
+
+	if (gpt->lock)
+		spin_unlock_irqrestore(gpt->lock, flags);
+
+	div += val & GPT_MSCALE_MASK;
+	div *= 1 << (((val >> GPT_NSCALE_SHIFT) & GPT_NSCALE_MASK) + 1);
+
+	if (!div)
+		return 0;
+
+	return parent_rate / div;
+}
+
+/* Configures new clock rate of gpt */
+static int clk_gpt_set_rate(struct clk_hw *hw, unsigned long drate)
+{
+	struct clk_gpt *gpt = to_clk_gpt(hw);
+	struct gpt_rate_tbl *rtbl = gpt->rtbl;
+	unsigned long flags = 0, val;
+	int i;
+
+	clk_round_rate_index(hw, drate, gpt_calc_rate, gpt->rtbl_cnt, &i);
+
+	if (gpt->lock)
+		spin_lock_irqsave(gpt->lock, flags);
+
+	val = readl(gpt->reg) & ~GPT_MSCALE_MASK;
+	val &= ~(GPT_NSCALE_MASK << GPT_NSCALE_SHIFT);
+
+	val |= rtbl[i].mscale & GPT_MSCALE_MASK;
+	val |= (rtbl[i].nscale & GPT_NSCALE_MASK) << GPT_NSCALE_SHIFT;
+
+	writel_relaxed(val, gpt->reg);
+
+	if (gpt->lock)
+		spin_unlock_irqrestore(gpt->lock, flags);
+
+	return 0;
+}
+
+static struct clk_ops clk_gpt_ops = {
+	.recalc_rate = clk_gpt_recalc_rate,
+	.round_rate = clk_gpt_round_rate,
+	.set_rate = clk_gpt_set_rate,
+};
+
+struct clk *clk_register_gpt(const char *name, const char *parent_name, unsigned
+		long flags, void __iomem *reg, struct gpt_rate_tbl *rtbl, u8
+		rtbl_cnt, spinlock_t *lock)
+{
+	struct clk_gpt *gpt;
+	struct clk *clk;
+
+	if (!name || !parent_name || !reg || !rtbl || !rtbl_cnt) {
+		pr_err("Invalid arguments passed");
+		return ERR_PTR(-EINVAL);
+	}
+
+	gpt = kzalloc(sizeof(*gpt), GFP_KERNEL);
+	if (!gpt) {
+		pr_err("could not allocate gpt clk\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	/* struct clk_gpt assignments */
+	gpt->reg = reg;
+	gpt->rtbl = rtbl;
+	gpt->rtbl_cnt = rtbl_cnt;
+	gpt->lock = lock;
+
+	clk = clk_register(NULL, name, &clk_gpt_ops, &gpt->hw, &parent_name, 1,
+			flags);
+	if (!IS_ERR_OR_NULL(clk))
+		return clk;
+
+	pr_err("clk register failed\n");
+	kfree(gpt);
+
+	return NULL;
+}
diff --git a/drivers/clk/spear/clk.h b/drivers/clk/spear/clk.h
index c7dbc84..ee17994 100644
--- a/drivers/clk/spear/clk.h
+++ b/drivers/clk/spear/clk.h
@@ -68,6 +68,20 @@ struct clk_frac {
 	spinlock_t		*lock;
 };
 
+/* GPT clk */
+struct gpt_rate_tbl {
+	u16 mscale;
+	u16 nscale;
+};
+
+struct clk_gpt {
+	struct			clk_hw hw;
+	void __iomem		*reg;
+	struct gpt_rate_tbl	*rtbl;
+	u8			rtbl_cnt;
+	spinlock_t		*lock;
+};
+
 /* VCO-PLL clk */
 struct pll_rate_tbl {
 	u8 mode;
@@ -103,6 +117,9 @@ struct clk *clk_register_aux(const char *aux_name, const char *gate_name,
 struct clk *clk_register_frac(const char *name, const char *parent_name,
 		unsigned long flags, void __iomem *reg,
 		struct frac_rate_tbl *rtbl, u8 rtbl_cnt, spinlock_t *lock);
+struct clk *clk_register_gpt(const char *name, const char *parent_name, unsigned
+		long flags, void __iomem *reg, struct gpt_rate_tbl *rtbl, u8
+		rtbl_cnt, spinlock_t *lock);
 struct clk *clk_register_vco_pll(const char *vco_name, const char *pll_name,
 		const char *vco_gate_name, const char *parent_name,
 		unsigned long flags, void __iomem *mode_reg, void __iomem
-- 
1.7.9

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

* [PATCH V3 7/8] SPEAr: Call clk_prepare() before calling clk_enable
  2012-04-24  6:50 [PATCH V3 0/8] SPEAr: Move to common clock framework Viresh Kumar
                   ` (5 preceding siblings ...)
  2012-04-24  6:50 ` [PATCH V3 6/8] SPEAr: clk: Add General Purpose Timer " Viresh Kumar
@ 2012-04-24  6:50 ` Viresh Kumar
  2012-04-27  4:42 ` [PATCH V3 0/8] SPEAr: Move to common clock framework Viresh Kumar
  7 siblings, 0 replies; 42+ messages in thread
From: Viresh Kumar @ 2012-04-24  6:50 UTC (permalink / raw)
  To: linux-arm-kernel

With common clock framework, it is must to call clk_{un}prepare() before/after
clk_{dis}enable. This patch fixes this for SPEAr timer.

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
 arch/arm/plat-spear/time.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/plat-spear/time.c b/arch/arm/plat-spear/time.c
index a3164d1..4f05d26 100644
--- a/arch/arm/plat-spear/time.c
+++ b/arch/arm/plat-spear/time.c
@@ -218,10 +218,10 @@ void __init spear_setup_timer(resource_size_t base, int irq)
 		goto err_iomap;
 	}
 
-	ret = clk_enable(gpt_clk);
+	ret = clk_prepare_enable(gpt_clk);
 	if (ret < 0) {
-		pr_err("%s:couldn't enable gpt clock\n", __func__);
-		goto err_clk;
+		pr_err("%s:couldn't prepare-enable gpt clock\n", __func__);
+		goto err_prepare_enable_clk;
 	}
 
 	spear_clockevent_init(irq);
@@ -229,7 +229,7 @@ void __init spear_setup_timer(resource_size_t base, int irq)
 
 	return;
 
-err_clk:
+err_prepare_enable_clk:
 	clk_put(gpt_clk);
 err_iomap:
 	iounmap(gpt_base);
-- 
1.7.9

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

* [PATCH V3 1/8] CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk *
  2012-04-24  6:50 ` [PATCH V3 1/8] CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk * Viresh Kumar
@ 2012-04-26  7:47   ` Russell King - ARM Linux
  2012-04-26 10:28     ` Viresh Kumar
  0 siblings, 1 reply; 42+ messages in thread
From: Russell King - ARM Linux @ 2012-04-26  7:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Apr 24, 2012 at 12:20:29PM +0530, Viresh Kumar wrote:
> From: Russell King <rmk+kernel@arm.linux.org.uk>
> 
> With common clock framework, clks are allocated at runtime. Some of them require
> clkdevs to be allocated and added in global clkdev list.
> 
> This patch introduces helper routines to:
> 
>  - allocate and add single clkdev for a single clk structure.
>  - add multiple clkdevs for a single clk structure.

This still causes additional warnings.  Having managed to get the build
for various platforms down to zero warnings, we now have:

drivers/clk/clkdev.c: In function 'clkdev_alloc':
drivers/clk/clkdev.c:209: warning: 'ap' may be used uninitialized in this function
drivers/clk/clkdev.c: In function 'clk_register_clkdev':
drivers/clk/clkdev.c:251: warning: 'ap' may be used uninitialized in this function

for everything building clkdev.c

I'll be dropping the patch.  Please fix.

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

* [PATCH V3 1/8] CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk *
  2012-04-26  7:47   ` Russell King - ARM Linux
@ 2012-04-26 10:28     ` Viresh Kumar
  2012-04-28  9:52       ` Russell King - ARM Linux
  0 siblings, 1 reply; 42+ messages in thread
From: Viresh Kumar @ 2012-04-26 10:28 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/26/2012 1:17 PM, Russell King - ARM Linux wrote:
> This still causes additional warnings.  Having managed to get the build
> for various platforms down to zero warnings, we now have:
> 
> drivers/clk/clkdev.c: In function 'clkdev_alloc':
> drivers/clk/clkdev.c:209: warning: 'ap' may be used uninitialized in this function
> drivers/clk/clkdev.c: In function 'clk_register_clkdev':
> drivers/clk/clkdev.c:251: warning: 'ap' may be used uninitialized in this function

My compiler hasn't thrown any warnings :(
Please apply following patch. This should compile without errors.

From: Russell King <rmk+kernel@arm.linux.org.uk>
Date: Mon, 16 Apr 2012 10:43:17 +0530
Subject: [PATCH V4] CLKDEV: Add helper routines to allocate and add clkdevs for
 given struct clk *

With common clock framework, clks are allocated at runtime. Some of them require
clkdevs to be allocated and added in global clkdev list.

This patch introduces helper routines to:

 - allocate and add single clkdev for a single clk structure.
 - add multiple clkdevs for a single clk structure.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
---
V3->V4:
- Move code that filled dev_id to clkdev_alloc_valist macro.

 drivers/clk/clkdev.c   |   75 +++++++++++++++++++++++++++++++++++++++++------
 include/linux/clkdev.h |    3 ++
 2 files changed, 68 insertions(+), 10 deletions(-)

diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index d4a5993..c890214 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -166,8 +166,8 @@ struct clk_lookup_alloc {
 	char	con_id[MAX_CON_ID];
 };
 
-struct clk_lookup * __init_refok
-clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
+static struct clk_lookup_alloc * __init_refok
+__clkdev_alloc_set_conid(struct clk *clk, const char *con_id)
 {
 	struct clk_lookup_alloc *cla;
 
@@ -181,16 +181,40 @@ clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
 		cla->cl.con_id = cla->con_id;
 	}
 
-	if (dev_fmt) {
-		va_list ap;
+	return cla;
+}
 
-		va_start(ap, dev_fmt);
-		vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap);
-		cla->cl.dev_id = cla->dev_id;
-		va_end(ap);
-	}
+#define clkdev_alloc_valist(_cl, _clk, _con_id, _dev_fmt)		\
+	do {								\
+		struct clk_lookup_alloc *_cla;				\
+									\
+		_cla = __clkdev_alloc_set_conid(_clk, _con_id);		\
+		if (!_cla) {						\
+			_cl = NULL;					\
+			break;						\
+		}							\
+									\
+		_cl = &_cla->cl;					\
+									\
+		if (_dev_fmt) {						\
+			va_list _ap;					\
+									\
+			va_start(_ap, _dev_fmt);			\
+			vscnprintf(_cla->dev_id, sizeof(_cla->dev_id),	\
+					_dev_fmt, _ap);			\
+			_cl->dev_id = _cla->dev_id;			\
+			va_end(_ap);					\
+		}							\
+	} while (0);
+
+struct clk_lookup * __init_refok
+clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
+{
+	struct clk_lookup *cl;
 
-	return &cla->cl;
+	clkdev_alloc_valist(cl, clk, con_id, dev_fmt);
+
+	return cl;
 }
 EXPORT_SYMBOL(clkdev_alloc);
 
@@ -223,3 +247,34 @@ void clkdev_drop(struct clk_lookup *cl)
 	kfree(cl);
 }
 EXPORT_SYMBOL(clkdev_drop);
+
+int clk_register_clkdev(struct clk *clk, const char *con_id,
+		const char *dev_fmt, ...)
+{
+	struct clk_lookup *cl;
+
+	clkdev_alloc_valist(cl, clk, con_id, dev_fmt);
+
+	if (!cl)
+		return -ENOMEM;
+
+	clkdev_add(cl);
+	return 0;
+}
+EXPORT_SYMBOL(clk_register_clkdev);
+
+int clk_register_clkdevs(struct clk *clk, struct clk_lookup *cl, size_t num)
+{
+	unsigned i;
+
+	if (!clk)
+		return -ENOMEM;
+
+	for (i = 0; i < num; i++, cl++) {
+		cl->clk = clk;
+		clkdev_add(cl);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(clk_register_clkdevs);
diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h
index d9a4fd0..01d8ff6 100644
--- a/include/linux/clkdev.h
+++ b/include/linux/clkdev.h
@@ -39,5 +39,8 @@ void clkdev_drop(struct clk_lookup *cl);
 
 void clkdev_add_table(struct clk_lookup *, size_t);
 int clk_add_alias(const char *, const char *, char *, struct device *);
+int clk_register_clkdev(struct clk *clk, const char *con_id,
+		const char *dev_fmt, ...);
+int clk_register_clkdevs(struct clk *clk, struct clk_lookup *cl, size_t num);
 
 #endif
-- 
1.7.9



-- 
viresh

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

* [PATCH V3 0/8] SPEAr: Move to common clock framework
  2012-04-24  6:50 [PATCH V3 0/8] SPEAr: Move to common clock framework Viresh Kumar
                   ` (6 preceding siblings ...)
  2012-04-24  6:50 ` [PATCH V3 7/8] SPEAr: Call clk_prepare() before calling clk_enable Viresh Kumar
@ 2012-04-27  4:42 ` Viresh Kumar
  2012-04-27 17:50   ` Turquette, Mike
  7 siblings, 1 reply; 42+ messages in thread
From: Viresh Kumar @ 2012-04-27  4:42 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/24/2012 12:20 PM, Viresh KUMAR wrote:
> Mike,
> 
> You can apply all these patches as they don't have any dependency left (leaving
> the ones included here) and will now apply cleanly over linux-next.

Mike,

These patches give compilation errors over your clk-next branch.
This happened due to following patch.

commit 1c0035d710dd3bfa86d58f851b8737c7f11a9bbc
Author: Shawn Guo <shawn.guo@linaro.org>
Date:   Thu Apr 12 20:50:18 2012 +0800

    clk: pass parent_rate into .set_rate
    
    For most of .set_rate implementation, parent_rate will be used, so just
    like passing parent_rate into .recalc_rate, let's pass parent_rate into
    .set_rate too.
    
    It also updates the kernel doc for .set_rate ops.
    
    Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
    Signed-off-by: Mike Turquette <mturquette@linaro.org>

I will send fixups as reply on individual patches, and then send you pull request
with these changes squashed to parent commits.

-- 
viresh

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

* [PATCH V3 2/8] clk: add a fixed factor clock
  2012-04-24  6:50 ` [PATCH V3 2/8] clk: add a fixed factor clock Viresh Kumar
@ 2012-04-27  4:43   ` Viresh Kumar
  2012-05-02  9:48   ` Sascha Hauer
  1 sibling, 0 replies; 42+ messages in thread
From: Viresh Kumar @ 2012-04-27  4:43 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/24/2012 12:20 PM, Viresh KUMAR wrote:
> 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>

    fixup! clk: add a fixed factor clock
---
 drivers/clk/clk-fixed-factor.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index 7453efe..9afbdc4 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -49,7 +49,8 @@ static long clk_factor_round_rate(struct clk_hw *hw, unsigned long rate,
        }
 }
 
-static int clk_factor_set_rate(struct clk_hw *hw, unsigned long rate)
+static int clk_factor_set_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long parent_rate)
 {
        return 0;
 }

-- 
viresh

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

* [PATCH V3 3/8] SPEAr: clk: Add VCO-PLL Synthesizer clock
  2012-04-24  6:50 ` [PATCH V3 3/8] SPEAr: clk: Add VCO-PLL Synthesizer clock Viresh Kumar
@ 2012-04-27  4:44   ` Viresh Kumar
  2012-05-03  5:47   ` Viresh Kumar
  2012-05-03  9:49   ` Viresh Kumar
  2 siblings, 0 replies; 42+ messages in thread
From: Viresh Kumar @ 2012-04-27  4:44 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/24/2012 12:20 PM, Viresh KUMAR wrote:
> All SPEAr SoC's contain PLLs. Their Fout is derived based on following equations
> 
> - In normal mode
>   vco = (2 * M[15:8] * Fin)/N
> 
> - In Dithered mode
>   vco = (2 * M[15:0] * Fin)/(256 * N)
> 
> pll_rate = vco/2^p
> 
> vco and pll are very closely bound to each other,
> "vco needs to program: mode, m & n" and "pll needs to program p",
> both share common enable/disable logic and registers.
> 
> This patch adds in support for this type of clock.

    fixup! SPEAr: clk: Add VCO-PLL Synthesizer clock
---
 drivers/clk/spear/clk-vco-pll.c |   14 +++++++++-----
 drivers/clk/spear/clk.c         |    4 ++--
 drivers/clk/spear/clk.h         |    3 ++-
 3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/spear/clk-vco-pll.c b/drivers/clk/spear/clk-vco-pll.c
index 9efa30d..e661273 100644
--- a/drivers/clk/spear/clk-vco-pll.c
+++ b/drivers/clk/spear/clk-vco-pll.c
@@ -141,7 +141,8 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, unsigned long
        return parent_rate / (1 << p);
 }
 
-static int clk_pll_set_rate(struct clk_hw *hw, unsigned long drate)
+static int clk_pll_set_rate(struct clk_hw *hw, unsigned long drate,
+                               unsigned long prate)
 {
        struct clk_pll *pll = to_clk_pll(hw);
        struct pll_rate_tbl *rtbl = pll->vco->rtbl;
@@ -182,10 +183,11 @@ static long clk_vco_round_rate(struct clk_hw *hw, unsigned long drate,
                unsigned long *prate)
 {
        struct clk_vco *vco = to_clk_vco(hw);
+       unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
        int unused;
 
-       return clk_round_rate_index(hw, drate, vco_calc_rate, vco->rtbl_cnt,
-                       &unused);
+       return clk_round_rate_index(hw, drate, parent_rate, vco_calc_rate,
+                       vco->rtbl_cnt, &unused);
 }
 
 static unsigned long clk_vco_recalc_rate(struct clk_hw *hw,
@@ -226,14 +228,16 @@ static unsigned long clk_vco_recalc_rate(struct clk_hw *hw,
 }
 
 /* Configures new clock rate of vco */
-static int clk_vco_set_rate(struct clk_hw *hw, unsigned long drate)
+static int clk_vco_set_rate(struct clk_hw *hw, unsigned long drate,
+                               unsigned long prate)
 {
        struct clk_vco *vco = to_clk_vco(hw);
        struct pll_rate_tbl *rtbl = vco->rtbl;
        unsigned long flags = 0, val;
        int i;
 
-       clk_round_rate_index(hw, drate, vco_calc_rate, vco->rtbl_cnt, &i);
+       clk_round_rate_index(hw, drate, prate, vco_calc_rate, vco->rtbl_cnt,
+                       &i);
 
        if (vco->lock)
                spin_lock_irqsave(vco->lock, flags);
diff --git a/drivers/clk/spear/clk.c b/drivers/clk/spear/clk.c
index 74f6acc..376d4e5 100644
--- a/drivers/clk/spear/clk.c
+++ b/drivers/clk/spear/clk.c
@@ -14,10 +14,10 @@
 #include "clk.h"
 
 long clk_round_rate_index(struct clk_hw *hw, unsigned long drate,
-               clk_calc_rate calc_rate, u8 rtbl_cnt, int *index)
+               unsigned long parent_rate, clk_calc_rate calc_rate, u8 rtbl_cnt,
+               int *index)
 {
        unsigned long prev_rate, rate = 0;
-       unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
 
        for (*index = 0; *index < rtbl_cnt; (*index)++) {
                prev_rate = rate;
diff --git a/drivers/clk/spear/clk.h b/drivers/clk/spear/clk.h
index ee17994..3321c46 100644
--- a/drivers/clk/spear/clk.h
+++ b/drivers/clk/spear/clk.h
@@ -128,6 +128,7 @@ struct clk *clk_register_vco_pll(const char *vco_name, const char *pll_name,
                struct clk **vco_gate_clk);
 
 long clk_round_rate_index(struct clk_hw *hw, unsigned long drate,
-               clk_calc_rate calc_rate, u8 rtbl_cnt, int *index);
+               unsigned long parent_rate, clk_calc_rate calc_rate, u8 rtbl_cnt,
+               int *index);
 
 #endif /* __SPEAR_CLK_H */


-- 
viresh

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

* [PATCH V3 4/8] SPEAr: clk: Add Auxiliary Synthesizer clock
  2012-04-24  6:50 ` [PATCH V3 4/8] SPEAr: clk: Add Auxiliary " Viresh Kumar
@ 2012-04-27  4:45   ` Viresh Kumar
  2012-05-03  5:47   ` Viresh Kumar
  2012-05-03  9:50   ` Viresh Kumar
  2 siblings, 0 replies; 42+ messages in thread
From: Viresh Kumar @ 2012-04-27  4:45 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/24/2012 12:20 PM, Viresh KUMAR wrote:
> All SPEAr SoC's contain Auxiliary Synthesizers. Their Fout is derived based on
> values of eq, x and y.
> 
> Fout from synthesizer can be given from two equations:
> Fout1 = (Fin * X/Y)/2		EQ1
> Fout2 = Fin * X/Y		EQ2
> 
> This patch adds in support for this type of clock.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>

    fixup! SPEAr: clk: Add Auxiliary Synthesizer clock
---
 drivers/clk/spear/clk-aux-synth.c |   11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/spear/clk-aux-synth.c b/drivers/clk/spear/clk-aux-synth.c
index e01a350..c199e78 100644
--- a/drivers/clk/spear/clk-aux-synth.c
+++ b/drivers/clk/spear/clk-aux-synth.c
@@ -56,10 +56,11 @@ static long clk_aux_round_rate(struct clk_hw *hw, unsigned long drate,
                unsigned long *prate)
 {
        struct clk_aux *aux = to_clk_aux(hw);
+       unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
        int unused;
 
-       return clk_round_rate_index(hw, drate, aux_calc_rate, aux->rtbl_cnt,
-                       &unused);
+       return clk_round_rate_index(hw, drate, parent_rate, aux_calc_rate,
+                       aux->rtbl_cnt, &unused);
 }
 
 static unsigned long clk_aux_recalc_rate(struct clk_hw *hw,
@@ -96,14 +97,16 @@ static unsigned long clk_aux_recalc_rate(struct clk_hw *hw,
 }
 
 /* Configures new clock rate of aux */
-static int clk_aux_set_rate(struct clk_hw *hw, unsigned long drate)
+static int clk_aux_set_rate(struct clk_hw *hw, unsigned long drate,
+                               unsigned long prate)
 {
        struct clk_aux *aux = to_clk_aux(hw);
        struct aux_rate_tbl *rtbl = aux->rtbl;
        unsigned long val, flags = 0;
        int i;
 
-       clk_round_rate_index(hw, drate, aux_calc_rate, aux->rtbl_cnt, &i);
+       clk_round_rate_index(hw, drate, prate, aux_calc_rate, aux->rtbl_cnt,
+                       &i);
 
        if (aux->lock)
                spin_lock_irqsave(aux->lock, flags);

-- 
viresh

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

* [PATCH V3 5/8] SPEAr: clk: Add Fractional Synthesizer clock
  2012-04-24  6:50 ` [PATCH V3 5/8] SPEAr: clk: Add Fractional " Viresh Kumar
@ 2012-04-27  4:45   ` Viresh Kumar
  2012-05-03  5:46   ` Viresh Kumar
  2012-05-03  9:51   ` Viresh Kumar
  2 siblings, 0 replies; 42+ messages in thread
From: Viresh Kumar @ 2012-04-27  4:45 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/24/2012 12:20 PM, Viresh KUMAR wrote:
> All SPEAr SoC's contain Fractional Synthesizers. Their Fout is derived from
> following equations:
> 
> Fout = Fin / (2 * div) (division factor)
> div is 17 bits:-
>      0-13 (fractional part)
>      14-16 (integer part)
>      div is (16-14 bits).(13-0 bits) (in binary)
> 
>      Fout = Fin/(2 * div)
>      Fout = ((Fin / 10000)/(2 * div)) * 10000
>      Fout = (2^14 * (Fin / 10000)/(2^14 * (2 * div))) * 10000
>      Fout = (((Fin / 10000) << 14)/(2 * (div << 14))) * 10000
> 
> div << 14 is simply 17 bit value written@register.
> 
> This patch adds in support for this type of clock.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>

    fixup! SPEAr: clk: Add Fractional Synthesizer clock
---
 drivers/clk/spear/clk-frac-synth.c |   11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/spear/clk-frac-synth.c b/drivers/clk/spear/clk-frac-synth.c
index c6ccdab..b2090f8 100644
--- a/drivers/clk/spear/clk-frac-synth.c
+++ b/drivers/clk/spear/clk-frac-synth.c
@@ -59,10 +59,11 @@ static long clk_frac_round_rate(struct clk_hw *hw, unsigned long drate,
                unsigned long *prate)
 {
        struct clk_frac *frac = to_clk_frac(hw);
+       unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
        int unused;
 
-       return clk_round_rate_index(hw, drate, frac_calc_rate, frac->rtbl_cnt,
-                       &unused);
+       return clk_round_rate_index(hw, drate, parent_rate, frac_calc_rate,
+                       frac->rtbl_cnt, &unused);
 }
 
 static unsigned long clk_frac_recalc_rate(struct clk_hw *hw,
@@ -92,14 +93,16 @@ static unsigned long clk_frac_recalc_rate(struct clk_hw *hw,
 }
 
 /* Configures new clock rate of frac */
-static int clk_frac_set_rate(struct clk_hw *hw, unsigned long drate)
+static int clk_frac_set_rate(struct clk_hw *hw, unsigned long drate,
+                               unsigned long prate)
 {
        struct clk_frac *frac = to_clk_frac(hw);
        struct frac_rate_tbl *rtbl = frac->rtbl;
        unsigned long flags = 0, val;
        int i;
 
-       clk_round_rate_index(hw, drate, frac_calc_rate, frac->rtbl_cnt, &i);
+       clk_round_rate_index(hw, drate, prate, frac_calc_rate, frac->rtbl_cnt,
+                       &i);
 
        if (frac->lock)
                spin_lock_irqsave(frac->lock, flags);

-- 
viresh

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

* [PATCH V3 6/8] SPEAr: clk: Add General Purpose Timer Synthesizer clock
  2012-04-24  6:50 ` [PATCH V3 6/8] SPEAr: clk: Add General Purpose Timer " Viresh Kumar
@ 2012-04-27  4:46   ` Viresh Kumar
  2012-05-03  5:43   ` Viresh Kumar
  2012-05-03  9:51   ` Viresh Kumar
  2 siblings, 0 replies; 42+ messages in thread
From: Viresh Kumar @ 2012-04-27  4:46 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/24/2012 12:20 PM, Viresh KUMAR wrote:
> All SPEAr SoC's contain GPT Synthesizers. Their Fout is derived from
> following equations:
> 
> Fout= Fin/((2 ^ (N+1)) * (M+1))
> 
> This patch adds in support for this type of clock.

    fixup! SPEAr: clk: Add General Purpose Timer Synthesizer clock
---
 drivers/clk/spear/clk-gpt-synth.c |   11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/spear/clk-gpt-synth.c b/drivers/clk/spear/clk-gpt-synth.c
index 514539c..f3b252a 100644
--- a/drivers/clk/spear/clk-gpt-synth.c
+++ b/drivers/clk/spear/clk-gpt-synth.c
@@ -46,10 +46,11 @@ static long clk_gpt_round_rate(struct clk_hw *hw, unsigned long drate,
                unsigned long *prate)
 {
        struct clk_gpt *gpt = to_clk_gpt(hw);
+       unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
        int unused;
 
-       return clk_round_rate_index(hw, drate, gpt_calc_rate, gpt->rtbl_cnt,
-                       &unused);
+       return clk_round_rate_index(hw, drate, parent_rate, gpt_calc_rate,
+                       gpt->rtbl_cnt, &unused);
 }
 
 static unsigned long clk_gpt_recalc_rate(struct clk_hw *hw,
@@ -77,14 +78,16 @@ static unsigned long clk_gpt_recalc_rate(struct clk_hw *hw,
 }
 
 /* Configures new clock rate of gpt */
-static int clk_gpt_set_rate(struct clk_hw *hw, unsigned long drate)
+static int clk_gpt_set_rate(struct clk_hw *hw, unsigned long drate,
+                               unsigned long prate)
 {
        struct clk_gpt *gpt = to_clk_gpt(hw);
        struct gpt_rate_tbl *rtbl = gpt->rtbl;
        unsigned long flags = 0, val;
        int i;
 
-       clk_round_rate_index(hw, drate, gpt_calc_rate, gpt->rtbl_cnt, &i);
+       clk_round_rate_index(hw, drate, prate, gpt_calc_rate, gpt->rtbl_cnt,
+                       &i);
 
        if (gpt->lock)
                spin_lock_irqsave(gpt->lock, flags);

-- 
viresh

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

* [PATCH V3 0/8] SPEAr: Move to common clock framework
  2012-04-27  4:42 ` [PATCH V3 0/8] SPEAr: Move to common clock framework Viresh Kumar
@ 2012-04-27 17:50   ` Turquette, Mike
  0 siblings, 0 replies; 42+ messages in thread
From: Turquette, Mike @ 2012-04-27 17:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Apr 26, 2012 at 9:42 PM, Viresh Kumar <viresh.kumar@st.com> wrote:
> On 4/24/2012 12:20 PM, Viresh KUMAR wrote:
>> Mike,
>>
>> You can apply all these patches as they don't have any dependency left (leaving
>> the ones included here) and will now apply cleanly over linux-next.
>
> Mike,
>
> These patches give compilation errors over your clk-next branch.
> This happened due to following patch.
>
> commit 1c0035d710dd3bfa86d58f851b8737c7f11a9bbc
> Author: Shawn Guo <shawn.guo@linaro.org>
> Date: ? Thu Apr 12 20:50:18 2012 +0800
>
> ? ?clk: pass parent_rate into .set_rate
>
> ? ?For most of .set_rate implementation, parent_rate will be used, so just
> ? ?like passing parent_rate into .recalc_rate, let's pass parent_rate into
> ? ?.set_rate too.
>
> ? ?It also updates the kernel doc for .set_rate ops.
>
> ? ?Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> ? ?Signed-off-by: Mike Turquette <mturquette@linaro.org>
>
> I will send fixups as reply on individual patches, and then send you pull request
> with these changes squashed to parent commits.

Ok great.  A public branch for me to pull from would be great.

Thanks,
Mike

> --
> viresh

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

* [PATCH V3 1/8] CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk *
  2012-04-26 10:28     ` Viresh Kumar
@ 2012-04-28  9:52       ` Russell King - ARM Linux
  2012-04-28 11:01         ` Sascha Hauer
  2012-04-30  8:08         ` Viresh Kumar
  0 siblings, 2 replies; 42+ messages in thread
From: Russell King - ARM Linux @ 2012-04-28  9:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Apr 26, 2012 at 03:58:57PM +0530, Viresh Kumar wrote:
> My compiler hasn't thrown any warnings :(
> Please apply following patch. This should compile without errors.
> 
> From: Russell King <rmk+kernel@arm.linux.org.uk>
> Date: Mon, 16 Apr 2012 10:43:17 +0530
> Subject: [PATCH V4] CLKDEV: Add helper routines to allocate and add clkdevs for
>  given struct clk *
> 
> With common clock framework, clks are allocated at runtime. Some of them require
> clkdevs to be allocated and added in global clkdev list.
> 
> This patch introduces helper routines to:
> 
>  - allocate and add single clkdev for a single clk structure.
>  - add multiple clkdevs for a single clk structure.
> 
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>

I don't like that macro in there, I think it's unnecessary.  What about
the below, which I've built here and it builds fine.

As for va_start(ap, dev_fmt) when dev_fmt is NULL, that's perfectly fine
- the requirement for va_start() is that it is called with the argument
preceding the variable list of function arguments signified by '...'.
That's still true when dev_fmt is NULL (hint: the compiler doesn't know
at build time if dev_fmt was passed into this function as a NULL pointer
or a real pointer, so it's going to generate code which works for non-NULL
pointers.  If the pointer _is_ NULL, then we don't touch 'ap' other than
its initialization and finalization via the standard functions.)

Plus, I've added commentry to these two new functions because there's
an important point that needs to be conveyed (the fact that they do the
error handling for clk_register()).

diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 6db161f..f5db067 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -116,8 +116,9 @@ struct clk_lookup_alloc {
 	char	con_id[MAX_CON_ID];
 };
 
-struct clk_lookup * __init_refok
-clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
+static struct clk_lookup * __init_refok
+vclkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt,
+	va_list ap)
 {
 	struct clk_lookup_alloc *cla;
 
@@ -132,16 +133,25 @@ clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
 	}
 
 	if (dev_fmt) {
-		va_list ap;
-
-		va_start(ap, dev_fmt);
 		vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap);
 		cla->cl.dev_id = cla->dev_id;
-		va_end(ap);
 	}
 
 	return &cla->cl;
 }
+
+struct clk_lookup * __init_refok
+clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
+{
+	struct clk_lookup *cl;
+	va_list ap;
+
+	va_start(ap, dev_fmt);
+	cl = vclkdev_alloc(clk, con_id, dev_fmt, ap);
+	va_end(ap);
+
+	return cl;
+}
 EXPORT_SYMBOL(clkdev_alloc);
 
 int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
@@ -173,3 +183,65 @@ void clkdev_drop(struct clk_lookup *cl)
 	kfree(cl);
 }
 EXPORT_SYMBOL(clkdev_drop);
+
+/**
+ * clk_register_clkdev - register one clock lookup for a struct clk
+ * @clk: struct clk to associate with all clk_lookups
+ * @con_id: connection ID string on device
+ * @dev_id: format string describing device name
+ *
+ * con_id or dev_id may be NULL as a wildcard, just as in the rest of
+ * clkdev.
+ *
+ * To make things easier for mass registration, we detect the NULL clk
+ * from a previous clk_register() call, and generate an error code for
+ * that.  This is to permit this function to be called immediately after
+ * clk_register().
+ */
+int clk_register_clkdev(struct clk *clk, const char *con_id,
+	const char *dev_fmt, ...)
+{
+	struct clk_lookup *cl;
+	va_list ap;
+
+	if (!clk)
+		return -ENOMEM;
+
+	va_start(ap, dev_fmt);
+	cl = vclkdev_alloc(clk, con_id, dev_fmt, ap);
+	va_end(ap);
+
+	if (!cl)
+		return -ENOMEM;
+
+	clkdev_add(cl);
+
+	return 0;
+}
+
+/**
+ * clk_register_clkdevs - register a set of clk_lookup for a struct clk
+ * @clk: struct clk to associate with all clk_lookups
+ * @cl: array of clk_lookup structures with con_id and dev_id pre-initialized
+ * @num: number of clk_lookup structures to register
+ *
+ * To make things easier for mass registration, we detect the NULL clk
+ * from a previous clk_register() call, and generate an error code for
+ * that.  This is to permit this function to be called immediately after
+ * clk_register().
+ */
+int clk_register_clkdevs(struct clk *clk, struct clk_lookup *cl, size_t num)
+{
+	unsigned i;
+
+	if (!clk)
+		return -ENOMEM;
+
+	for (i = 0; i < num; i++) {
+		cl->clk = clk;
+		clkdev_add(cl);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(clk_register_clkdevs);
diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h
index d9a4fd0..a6a6f60 100644
--- a/include/linux/clkdev.h
+++ b/include/linux/clkdev.h
@@ -40,4 +40,7 @@ void clkdev_drop(struct clk_lookup *cl);
 void clkdev_add_table(struct clk_lookup *, size_t);
 int clk_add_alias(const char *, const char *, char *, struct device *);
 
+int clk_register_clkdev(struct clk *, const char *, const char *, ...);
+int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t);
+
 #endif

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

* [PATCH V3 1/8] CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk *
  2012-04-28  9:52       ` Russell King - ARM Linux
@ 2012-04-28 11:01         ` Sascha Hauer
  2012-04-28 11:06           ` Russell King - ARM Linux
  2012-04-30  8:08         ` Viresh Kumar
  1 sibling, 1 reply; 42+ messages in thread
From: Sascha Hauer @ 2012-04-28 11:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Apr 28, 2012 at 10:52:22AM +0100, Russell King - ARM Linux wrote:
> +
> +/**
> + * clk_register_clkdev - register one clock lookup for a struct clk
> + * @clk: struct clk to associate with all clk_lookups
> + * @con_id: connection ID string on device
> + * @dev_id: format string describing device name
> + *
> + * con_id or dev_id may be NULL as a wildcard, just as in the rest of
> + * clkdev.
> + *
> + * To make things easier for mass registration, we detect the NULL clk
> + * from a previous clk_register() call, and generate an error code for
> + * that.  This is to permit this function to be called immediately after
> + * clk_register().
> + */
> +int clk_register_clkdev(struct clk *clk, const char *con_id,
> +	const char *dev_fmt, ...)
> +{
> +	struct clk_lookup *cl;
> +	va_list ap;
> +
> +	if (!clk)
> +		return -ENOMEM;

clk_register was recently changed to return ERR_PTR in Mikes branch.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* [PATCH V3 1/8] CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk *
  2012-04-28 11:01         ` Sascha Hauer
@ 2012-04-28 11:06           ` Russell King - ARM Linux
  2012-05-01  8:45             ` Viresh Kumar
  2012-05-01 12:31             ` Shawn Guo
  0 siblings, 2 replies; 42+ messages in thread
From: Russell King - ARM Linux @ 2012-04-28 11:06 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Apr 28, 2012 at 01:01:08PM +0200, Sascha Hauer wrote:
> On Sat, Apr 28, 2012 at 10:52:22AM +0100, Russell King - ARM Linux wrote:
> > +
> > +/**
> > + * clk_register_clkdev - register one clock lookup for a struct clk
> > + * @clk: struct clk to associate with all clk_lookups
> > + * @con_id: connection ID string on device
> > + * @dev_id: format string describing device name
> > + *
> > + * con_id or dev_id may be NULL as a wildcard, just as in the rest of
> > + * clkdev.
> > + *
> > + * To make things easier for mass registration, we detect the NULL clk
> > + * from a previous clk_register() call, and generate an error code for
> > + * that.  This is to permit this function to be called immediately after
> > + * clk_register().
> > + */
> > +int clk_register_clkdev(struct clk *clk, const char *con_id,
> > +	const char *dev_fmt, ...)
> > +{
> > +	struct clk_lookup *cl;
> > +	va_list ap;
> > +
> > +	if (!clk)
> > +		return -ENOMEM;
> 
> clk_register was recently changed to return ERR_PTR in Mikes branch.

That's something I was thinking about suggesting, so that the rules for
passing in 'struct clk' are the same as that for clk_get(), which makes
everything nicely symetrical.

diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 6db161f..2000c6b 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -116,8 +116,9 @@ struct clk_lookup_alloc {
 	char	con_id[MAX_CON_ID];
 };
 
-struct clk_lookup * __init_refok
-clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
+static struct clk_lookup * __init_refok
+vclkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt,
+	va_list ap)
 {
 	struct clk_lookup_alloc *cla;
 
@@ -132,16 +133,25 @@ clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
 	}
 
 	if (dev_fmt) {
-		va_list ap;
-
-		va_start(ap, dev_fmt);
 		vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap);
 		cla->cl.dev_id = cla->dev_id;
-		va_end(ap);
 	}
 
 	return &cla->cl;
 }
+
+struct clk_lookup * __init_refok
+clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
+{
+	struct clk_lookup *cl;
+	va_list ap;
+
+	va_start(ap, dev_fmt);
+	cl = vclkdev_alloc(clk, con_id, dev_fmt, ap);
+	va_end(ap);
+
+	return cl;
+}
 EXPORT_SYMBOL(clkdev_alloc);
 
 int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
@@ -173,3 +183,65 @@ void clkdev_drop(struct clk_lookup *cl)
 	kfree(cl);
 }
 EXPORT_SYMBOL(clkdev_drop);
+
+/**
+ * clk_register_clkdev - register one clock lookup for a struct clk
+ * @clk: struct clk to associate with all clk_lookups
+ * @con_id: connection ID string on device
+ * @dev_id: format string describing device name
+ *
+ * con_id or dev_id may be NULL as a wildcard, just as in the rest of
+ * clkdev.
+ *
+ * To make things easier for mass registration, we detect error clks
+ * from a previous clk_register() call, and return the error code for
+ * those.  This is to permit this function to be called immediately after
+ * clk_register().
+ */
+int clk_register_clkdev(struct clk *clk, const char *con_id,
+	const char *dev_fmt, ...)
+{
+	struct clk_lookup *cl;
+	va_list ap;
+
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	va_start(ap, dev_fmt);
+	cl = vclkdev_alloc(clk, con_id, dev_fmt, ap);
+	va_end(ap);
+
+	if (!cl)
+		return -ENOMEM;
+
+	clkdev_add(cl);
+
+	return 0;
+}
+
+/**
+ * clk_register_clkdevs - register a set of clk_lookup for a struct clk
+ * @clk: struct clk to associate with all clk_lookups
+ * @cl: array of clk_lookup structures with con_id and dev_id pre-initialized
+ * @num: number of clk_lookup structures to register
+ *
+ * To make things easier for mass registration, we detect error clks
+ * from a previous clk_register() call, and return the error code for
+ * those.  This is to permit this function to be called immediately after
+ * clk_register().
+ */
+int clk_register_clkdevs(struct clk *clk, struct clk_lookup *cl, size_t num)
+{
+	unsigned i;
+
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	for (i = 0; i < num; i++) {
+		cl->clk = clk;
+		clkdev_add(cl);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(clk_register_clkdevs);
diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h
index d9a4fd0..a6a6f60 100644
--- a/include/linux/clkdev.h
+++ b/include/linux/clkdev.h
@@ -40,4 +40,7 @@ void clkdev_drop(struct clk_lookup *cl);
 void clkdev_add_table(struct clk_lookup *, size_t);
 int clk_add_alias(const char *, const char *, char *, struct device *);
 
+int clk_register_clkdev(struct clk *, const char *, const char *, ...);
+int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t);
+
 #endif

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

* [PATCH V3 1/8] CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk *
  2012-04-28  9:52       ` Russell King - ARM Linux
  2012-04-28 11:01         ` Sascha Hauer
@ 2012-04-30  8:08         ` Viresh Kumar
  1 sibling, 0 replies; 42+ messages in thread
From: Viresh Kumar @ 2012-04-30  8:08 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/28/2012 3:22 PM, Russell King - ARM Linux wrote:
> I don't like that macro in there, I think it's unnecessary.  What about
> the below, which I've built here and it builds fine.

Even i didn't liked it too.

> As for va_start(ap, dev_fmt) when dev_fmt is NULL, that's perfectly fine
> - the requirement for va_start() is that it is called with the argument
> preceding the variable list of function arguments signified by '...'.
> That's still true when dev_fmt is NULL (hint: the compiler doesn't know
> at build time if dev_fmt was passed into this function as a NULL pointer
> or a real pointer, so it's going to generate code which works for non-NULL
> pointers.  If the pointer _is_ NULL, then we don't touch 'ap' other than
> its initialization and finalization via the standard functions.)

And i did implement it, because i didn't knew this. :)

> Plus, I've added commentry to these two new functions because there's
> an important point that needs to be conveyed (the fact that they do the
> error handling for clk_register()).

That good.

When are you pushing this to linux-next? I need it urgently so that SPEAr
patches can be pushed by Arnd.

-- 
viresh

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

* [PATCH V3 1/8] CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk *
  2012-04-28 11:06           ` Russell King - ARM Linux
@ 2012-05-01  8:45             ` Viresh Kumar
  2012-05-01 12:31             ` Shawn Guo
  1 sibling, 0 replies; 42+ messages in thread
From: Viresh Kumar @ 2012-05-01  8:45 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/28/2012 4:36 PM, Russell King - ARM Linux wrote:
> diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
> index 6db161f..2000c6b 100644
> --- a/drivers/clk/clkdev.c
> +++ b/drivers/clk/clkdev.c
> @@ -116,8 +116,9 @@ struct clk_lookup_alloc {
>  	char	con_id[MAX_CON_ID];
>  };
>  
> -struct clk_lookup * __init_refok
> -clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
> +static struct clk_lookup * __init_refok
> +vclkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt,
> +	va_list ap)
>  {
>  	struct clk_lookup_alloc *cla;
>  
> @@ -132,16 +133,25 @@ clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
>  	}
>  
>  	if (dev_fmt) {
> -		va_list ap;
> -
> -		va_start(ap, dev_fmt);
>  		vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap);
>  		cla->cl.dev_id = cla->dev_id;
> -		va_end(ap);
>  	}
>  
>  	return &cla->cl;
>  }
> +
> +struct clk_lookup * __init_refok
> +clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
> +{
> +	struct clk_lookup *cl;
> +	va_list ap;
> +
> +	va_start(ap, dev_fmt);
> +	cl = vclkdev_alloc(clk, con_id, dev_fmt, ap);
> +	va_end(ap);
> +
> +	return cl;
> +}
>  EXPORT_SYMBOL(clkdev_alloc);
>  
>  int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
> @@ -173,3 +183,65 @@ void clkdev_drop(struct clk_lookup *cl)
>  	kfree(cl);
>  }
>  EXPORT_SYMBOL(clkdev_drop);
> +
> +/**
> + * clk_register_clkdev - register one clock lookup for a struct clk
> + * @clk: struct clk to associate with all clk_lookups
> + * @con_id: connection ID string on device
> + * @dev_id: format string describing device name
> + *
> + * con_id or dev_id may be NULL as a wildcard, just as in the rest of
> + * clkdev.
> + *
> + * To make things easier for mass registration, we detect error clks
> + * from a previous clk_register() call, and return the error code for
> + * those.  This is to permit this function to be called immediately after
> + * clk_register().
> + */
> +int clk_register_clkdev(struct clk *clk, const char *con_id,
> +	const char *dev_fmt, ...)
> +{
> +	struct clk_lookup *cl;
> +	va_list ap;
> +
> +	if (IS_ERR(clk))
> +		return PTR_ERR(clk);
> +
> +	va_start(ap, dev_fmt);
> +	cl = vclkdev_alloc(clk, con_id, dev_fmt, ap);
> +	va_end(ap);
> +
> +	if (!cl)
> +		return -ENOMEM;
> +
> +	clkdev_add(cl);
> +
> +	return 0;
> +}
> +
> +/**
> + * clk_register_clkdevs - register a set of clk_lookup for a struct clk
> + * @clk: struct clk to associate with all clk_lookups
> + * @cl: array of clk_lookup structures with con_id and dev_id pre-initialized
> + * @num: number of clk_lookup structures to register
> + *
> + * To make things easier for mass registration, we detect error clks
> + * from a previous clk_register() call, and return the error code for
> + * those.  This is to permit this function to be called immediately after
> + * clk_register().
> + */
> +int clk_register_clkdevs(struct clk *clk, struct clk_lookup *cl, size_t num)
> +{
> +	unsigned i;
> +
> +	if (IS_ERR(clk))
> +		return PTR_ERR(clk);
> +
> +	for (i = 0; i < num; i++) {
> +		cl->clk = clk;
> +		clkdev_add(cl);
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(clk_register_clkdevs);
> diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h
> index d9a4fd0..a6a6f60 100644
> --- a/include/linux/clkdev.h
> +++ b/include/linux/clkdev.h
> @@ -40,4 +40,7 @@ void clkdev_drop(struct clk_lookup *cl);
>  void clkdev_add_table(struct clk_lookup *, size_t);
>  int clk_add_alias(const char *, const char *, char *, struct device *);
>  
> +int clk_register_clkdev(struct clk *, const char *, const char *, ...);
> +int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t);
> +
>  #endif

Reviewed-by: Viresh Kumar <viresh.kumar@st.com>

-- 
viresh

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

* [PATCH V3 1/8] CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk *
  2012-04-28 11:06           ` Russell King - ARM Linux
  2012-05-01  8:45             ` Viresh Kumar
@ 2012-05-01 12:31             ` Shawn Guo
  2012-05-02  9:54               ` Russell King - ARM Linux
  1 sibling, 1 reply; 42+ messages in thread
From: Shawn Guo @ 2012-05-01 12:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Apr 28, 2012 at 12:06:35PM +0100, Russell King - ARM Linux wrote:
> diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
> index 6db161f..2000c6b 100644
> --- a/drivers/clk/clkdev.c
> +++ b/drivers/clk/clkdev.c
> @@ -116,8 +116,9 @@ struct clk_lookup_alloc {
>  	char	con_id[MAX_CON_ID];
>  };
>  
> -struct clk_lookup * __init_refok
> -clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
> +static struct clk_lookup * __init_refok
> +vclkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt,
> +	va_list ap)
>  {
>  	struct clk_lookup_alloc *cla;
>  
> @@ -132,16 +133,25 @@ clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
>  	}
>  
>  	if (dev_fmt) {
> -		va_list ap;
> -
> -		va_start(ap, dev_fmt);
>  		vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap);
>  		cla->cl.dev_id = cla->dev_id;
> -		va_end(ap);
>  	}
>  
>  	return &cla->cl;
>  }
> +
> +struct clk_lookup * __init_refok
> +clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
> +{
> +	struct clk_lookup *cl;
> +	va_list ap;
> +
> +	va_start(ap, dev_fmt);
> +	cl = vclkdev_alloc(clk, con_id, dev_fmt, ap);
> +	va_end(ap);
> +
> +	return cl;
> +}
>  EXPORT_SYMBOL(clkdev_alloc);
>  
>  int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
> @@ -173,3 +183,65 @@ void clkdev_drop(struct clk_lookup *cl)
>  	kfree(cl);
>  }
>  EXPORT_SYMBOL(clkdev_drop);
> +
> +/**
> + * clk_register_clkdev - register one clock lookup for a struct clk
> + * @clk: struct clk to associate with all clk_lookups
> + * @con_id: connection ID string on device
> + * @dev_id: format string describing device name
> + *
> + * con_id or dev_id may be NULL as a wildcard, just as in the rest of
> + * clkdev.
> + *
> + * To make things easier for mass registration, we detect error clks
> + * from a previous clk_register() call, and return the error code for
> + * those.  This is to permit this function to be called immediately after
> + * clk_register().
> + */
> +int clk_register_clkdev(struct clk *clk, const char *con_id,
> +	const char *dev_fmt, ...)
> +{
> +	struct clk_lookup *cl;
> +	va_list ap;
> +
> +	if (IS_ERR(clk))
> +		return PTR_ERR(clk);
> +
> +	va_start(ap, dev_fmt);
> +	cl = vclkdev_alloc(clk, con_id, dev_fmt, ap);
> +	va_end(ap);
> +
> +	if (!cl)
> +		return -ENOMEM;
> +
> +	clkdev_add(cl);
> +
> +	return 0;
> +}
> +
> +/**
> + * clk_register_clkdevs - register a set of clk_lookup for a struct clk
> + * @clk: struct clk to associate with all clk_lookups
> + * @cl: array of clk_lookup structures with con_id and dev_id pre-initialized
> + * @num: number of clk_lookup structures to register
> + *
> + * To make things easier for mass registration, we detect error clks
> + * from a previous clk_register() call, and return the error code for
> + * those.  This is to permit this function to be called immediately after
> + * clk_register().
> + */
> +int clk_register_clkdevs(struct clk *clk, struct clk_lookup *cl, size_t num)
> +{
> +	unsigned i;
> +
> +	if (IS_ERR(clk))
> +		return PTR_ERR(clk);
> +
> +	for (i = 0; i < num; i++) {

With above line changed to:

	for (i = 0; i < num; i++, cl++) {


Tested-by: Shawn Guo <shawn.guo@linaro.org>

Regards,
Shawn

> +		cl->clk = clk;
> +		clkdev_add(cl);
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(clk_register_clkdevs);
> diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h
> index d9a4fd0..a6a6f60 100644
> --- a/include/linux/clkdev.h
> +++ b/include/linux/clkdev.h
> @@ -40,4 +40,7 @@ void clkdev_drop(struct clk_lookup *cl);
>  void clkdev_add_table(struct clk_lookup *, size_t);
>  int clk_add_alias(const char *, const char *, char *, struct device *);
>  
> +int clk_register_clkdev(struct clk *, const char *, const char *, ...);
> +int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t);
> +
>  #endif
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V3 2/8] clk: add a fixed factor clock
  2012-04-24  6:50 ` [PATCH V3 2/8] clk: add a fixed factor clock Viresh Kumar
  2012-04-27  4:43   ` Viresh Kumar
@ 2012-05-02  9:48   ` Sascha Hauer
  2012-05-02 11:56     ` Viresh Kumar
  1 sibling, 1 reply; 42+ messages in thread
From: Sascha Hauer @ 2012-05-02  9:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Apr 24, 2012 at 12:20:30PM +0530, Viresh Kumar wrote:
> 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>
> ---
> Sascha,
> 
> I have this patch in my set, because i need this to get SPEAr stuff pushed by
> Mike. I have updated your original patch, with all the review comments you got
> on it. Please check see if i have corrupted something.
> 
>  drivers/clk/Makefile           |    2 +-
>  drivers/clk/clk-fixed-factor.c |   94 ++++++++++++++++++++++++++++++++++++++++
>  include/linux/clk-private.h    |   20 ++++++++
>  include/linux/clk-provider.h   |   23 ++++++++++
>  4 files changed, 138 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..7453efe
> --- /dev/null
> +++ b/drivers/clk/clk-fixed-factor.c
> @@ -0,0 +1,94 @@
> +/*
> + * 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 (prate) {
> +		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;
> +	} else {
> +		return (__clk_get_rate(__clk_get_parent(hw->clk)) / fix->div) *
> +			fix->mult;
> +	}
> +}

This needs a fixup. The clock framework used to pass in a NULL pointer
as prate when a clk is not allowed to change a parents clock. This
is no longer true, so we have to check for

__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT

instead.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* [PATCH V3 1/8] CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk *
  2012-05-01 12:31             ` Shawn Guo
@ 2012-05-02  9:54               ` Russell King - ARM Linux
  2012-05-02 13:59                 ` Shawn Guo
  0 siblings, 1 reply; 42+ messages in thread
From: Russell King - ARM Linux @ 2012-05-02  9:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, May 01, 2012 at 08:31:51PM +0800, Shawn Guo wrote:
> > +	for (i = 0; i < num; i++) {
> 
> With above line changed to:
> 
> 	for (i = 0; i < num; i++, cl++) {
> 
> 
> Tested-by: Shawn Guo <shawn.guo@linaro.org>

Thanks, fixed that and committed.

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

* [PATCH V3 2/8] clk: add a fixed factor clock
  2012-05-02  9:48   ` Sascha Hauer
@ 2012-05-02 11:56     ` Viresh Kumar
  2012-05-02 22:41       ` Mike Turquette
  0 siblings, 1 reply; 42+ messages in thread
From: Viresh Kumar @ 2012-05-02 11:56 UTC (permalink / raw)
  To: linux-arm-kernel

On 5/2/2012 3:18 PM, Sascha Hauer wrote:
> This needs a fixup. The clock framework used to pass in a NULL pointer
> as prate when a clk is not allowed to change a parents clock. This
> is no longer true, so we have to check for
> 
> __clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT

Sure. Will send fixup.

@Mike: When will you send your clk patches to Arnd?
I am asking this, because SPEAr patches are dependent on
them. Also, please include this patch too, in your patchset.

I will send a fixup.

-- 
viresh

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

* [PATCH V3 1/8] CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk *
  2012-05-02  9:54               ` Russell King - ARM Linux
@ 2012-05-02 13:59                 ` Shawn Guo
  2012-05-02 14:13                   ` Russell King - ARM Linux
  0 siblings, 1 reply; 42+ messages in thread
From: Shawn Guo @ 2012-05-02 13:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 02, 2012 at 10:54:04AM +0100, Russell King - ARM Linux wrote:
> On Tue, May 01, 2012 at 08:31:51PM +0800, Shawn Guo wrote:
> > > +	for (i = 0; i < num; i++) {
> > 
> > With above line changed to:
> > 
> > 	for (i = 0; i < num; i++, cl++) {
> > 
> > 
> > Tested-by: Shawn Guo <shawn.guo@linaro.org>
> 
> Thanks, fixed that and committed.

Can you please publish a branch for clkdev patches, so that we can ask
Arnd to pull it into arm-soc as a dependency of platform clock porting?

-- 
Regards,
Shawn

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

* [PATCH V3 1/8] CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk *
  2012-05-02 13:59                 ` Shawn Guo
@ 2012-05-02 14:13                   ` Russell King - ARM Linux
  0 siblings, 0 replies; 42+ messages in thread
From: Russell King - ARM Linux @ 2012-05-02 14:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 02, 2012 at 09:59:48PM +0800, Shawn Guo wrote:
> On Wed, May 02, 2012 at 10:54:04AM +0100, Russell King - ARM Linux wrote:
> > On Tue, May 01, 2012 at 08:31:51PM +0800, Shawn Guo wrote:
> > > > +	for (i = 0; i < num; i++) {
> > > 
> > > With above line changed to:
> > > 
> > > 	for (i = 0; i < num; i++, cl++) {
> > > 
> > > 
> > > Tested-by: Shawn Guo <shawn.guo@linaro.org>
> > 
> > Thanks, fixed that and committed.
> 
> Can you please publish a branch for clkdev patches, so that we can ask
> Arnd to pull it into arm-soc as a dependency of platform clock porting?

Let's wait for it to be in linux-next - and having it go through one
of my nightly build cycles first (which is where the problem with the
last version from Viresh was noticed.)

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

* [PATCH V3 2/8] clk: add a fixed factor clock
  2012-05-02 11:56     ` Viresh Kumar
@ 2012-05-02 22:41       ` Mike Turquette
  2012-05-02 22:44         ` Mike Turquette
  2012-05-03  5:32         ` Viresh Kumar
  0 siblings, 2 replies; 42+ messages in thread
From: Mike Turquette @ 2012-05-02 22:41 UTC (permalink / raw)
  To: linux-arm-kernel

On 20120502-17:26, Viresh Kumar wrote:
> On 5/2/2012 3:18 PM, Sascha Hauer wrote:
> > This needs a fixup. The clock framework used to pass in a NULL pointer
> > as prate when a clk is not allowed to change a parents clock. This
> > is no longer true, so we have to check for
> > 
> > __clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT
> 
> Sure. Will send fixup.
> 
> @Mike: When will you send your clk patches to Arnd?
> I am asking this, because SPEAr patches are dependent on
> them. Also, please include this patch too, in your patchset.
> 
> I will send a fixup.

I will take this patch in before sending my request to Arnd.  In your
patch 0/8 you ask me to take in the series, but it looks like not all of
the patches are going through me.  For instance patch 2/8 certainly
looks destined for Russell.

After fixing up this patch can you resend a clean series which is only
headed for clk-next?

Thanks,
Mike

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

* [PATCH V3 2/8] clk: add a fixed factor clock
  2012-05-02 22:41       ` Mike Turquette
@ 2012-05-02 22:44         ` Mike Turquette
  2012-05-02 23:31           ` Russell King - ARM Linux
  2012-05-03  5:32         ` Viresh Kumar
  1 sibling, 1 reply; 42+ messages in thread
From: Mike Turquette @ 2012-05-02 22:44 UTC (permalink / raw)
  To: linux-arm-kernel

On 20120502-15:41, Mike Turquette wrote:
> On 20120502-17:26, Viresh Kumar wrote:
> > On 5/2/2012 3:18 PM, Sascha Hauer wrote:
> > > This needs a fixup. The clock framework used to pass in a NULL pointer
> > > as prate when a clk is not allowed to change a parents clock. This
> > > is no longer true, so we have to check for
> > > 
> > > __clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT
> > 
> > Sure. Will send fixup.
> > 
> > @Mike: When will you send your clk patches to Arnd?
> > I am asking this, because SPEAr patches are dependent on
> > them. Also, please include this patch too, in your patchset.
> > 
> > I will send a fixup.
> 
> I will take this patch in before sending my request to Arnd.  In your
> patch 0/8 you ask me to take in the series, but it looks like not all of
> the patches are going through me.  For instance patch 2/8 certainly
> looks destined for Russell.

Typo above.

s/patch 2/patch 1/

Regards,
Mike

> 
> After fixing up this patch can you resend a clean series which is only
> headed for clk-next?
> 
> Thanks,
> Mike

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

* [PATCH V3 2/8] clk: add a fixed factor clock
  2012-05-02 22:44         ` Mike Turquette
@ 2012-05-02 23:31           ` Russell King - ARM Linux
  0 siblings, 0 replies; 42+ messages in thread
From: Russell King - ARM Linux @ 2012-05-02 23:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 02, 2012 at 03:44:03PM -0700, Mike Turquette wrote:
> On 20120502-15:41, Mike Turquette wrote:
> > On 20120502-17:26, Viresh Kumar wrote:
> > > On 5/2/2012 3:18 PM, Sascha Hauer wrote:
> > > > This needs a fixup. The clock framework used to pass in a NULL pointer
> > > > as prate when a clk is not allowed to change a parents clock. This
> > > > is no longer true, so we have to check for
> > > > 
> > > > __clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT
> > > 
> > > Sure. Will send fixup.
> > > 
> > > @Mike: When will you send your clk patches to Arnd?
> > > I am asking this, because SPEAr patches are dependent on
> > > them. Also, please include this patch too, in your patchset.
> > > 
> > > I will send a fixup.
> > 
> > I will take this patch in before sending my request to Arnd.  In your
> > patch 0/8 you ask me to take in the series, but it looks like not all of
> > the patches are going through me.  For instance patch 2/8 certainly
> > looks destined for Russell.
> 
> Typo above.
> 
> s/patch 2/patch 1/

I've just pushed the latest version out for linux-next, and pulled it
across into the nightly build system.  The results should be up in a
couple of hours (and an hour more for the boot tests, not that it should
affect those.)

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

* [PATCH V3 2/8] clk: add a fixed factor clock
  2012-05-02 22:41       ` Mike Turquette
  2012-05-02 22:44         ` Mike Turquette
@ 2012-05-03  5:32         ` Viresh Kumar
  2012-05-03  6:37           ` Sascha Hauer
  1 sibling, 1 reply; 42+ messages in thread
From: Viresh Kumar @ 2012-05-03  5:32 UTC (permalink / raw)
  To: linux-arm-kernel

On 5/3/2012 4:11 AM, Mike Turquette wrote:
> I will take this patch in before sending my request to Arnd.  In your
> patch 0/8 you ask me to take in the series, but it looks like not all of
> the patches are going through me.  For instance patch 2/8 certainly
> looks destined for Russell.

I think you only need to take this patch, i.e. 2/8.
Others will go through Arnd directly, keeping your branch as an dependency
branch for it.

> After fixing up this patch can you resend a clean series which is only
> headed for clk-next?

So, i would be sending this patch only after applying the last fixup
(hopefully :) ).

@Sascha: Please see if this patch is sufficient.

---
 drivers/clk/clk-fixed-factor.c |    9 ++++-----
 1 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index 9afbdc4..8d25c2e 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -37,16 +37,15 @@ static long clk_factor_round_rate(struct clk_hw *hw, unsigned long rate,
 {
        struct clk_fixed_factor *fix = to_clk_fixed_factor(hw);
 
-       if (prate) {
+       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;
-       } else {
-               return (__clk_get_rate(__clk_get_parent(hw->clk)) / fix->div) *
-                       fix->mult;
        }
+
+       return (*prate / fix->div) * fix->mult;
 }
 
 static int clk_factor_set_rate(struct clk_hw *hw, unsigned long rate,



-- 
viresh

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

* [PATCH V3 6/8] SPEAr: clk: Add General Purpose Timer Synthesizer clock
  2012-04-24  6:50 ` [PATCH V3 6/8] SPEAr: clk: Add General Purpose Timer " Viresh Kumar
  2012-04-27  4:46   ` Viresh Kumar
@ 2012-05-03  5:43   ` Viresh Kumar
  2012-05-03  9:51   ` Viresh Kumar
  2 siblings, 0 replies; 42+ messages in thread
From: Viresh Kumar @ 2012-05-03  5:43 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/24/2012 12:20 PM, Viresh KUMAR wrote:
> All SPEAr SoC's contain GPT Synthesizers. Their Fout is derived from
> following equations:
> 
> Fout= Fin/((2 ^ (N+1)) * (M+1))
> 
> This patch adds in support for this type of clock.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>

Another Fixup:

---
 drivers/clk/spear/clk-gpt-synth.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/spear/clk-gpt-synth.c b/drivers/clk/spear/clk-gpt-synth.c
index f3b252a..688cbf4 100644
--- a/drivers/clk/spear/clk-gpt-synth.c
+++ b/drivers/clk/spear/clk-gpt-synth.c
@@ -46,10 +46,9 @@ static long clk_gpt_round_rate(struct clk_hw *hw, unsigned long drate,
                unsigned long *prate)
 {
        struct clk_gpt *gpt = to_clk_gpt(hw);
-       unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
        int unused;
 
-       return clk_round_rate_index(hw, drate, parent_rate, gpt_calc_rate,
+       return clk_round_rate_index(hw, drate, *prate, gpt_calc_rate,
                        gpt->rtbl_cnt, &unused);
 }

-- 
viresh

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

* [PATCH V3 5/8] SPEAr: clk: Add Fractional Synthesizer clock
  2012-04-24  6:50 ` [PATCH V3 5/8] SPEAr: clk: Add Fractional " Viresh Kumar
  2012-04-27  4:45   ` Viresh Kumar
@ 2012-05-03  5:46   ` Viresh Kumar
  2012-05-03  9:51   ` Viresh Kumar
  2 siblings, 0 replies; 42+ messages in thread
From: Viresh Kumar @ 2012-05-03  5:46 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/24/2012 12:20 PM, Viresh KUMAR wrote:
> All SPEAr SoC's contain Fractional Synthesizers. Their Fout is derived from
> following equations:
> 
> Fout = Fin / (2 * div) (division factor)
> div is 17 bits:-
>      0-13 (fractional part)
>      14-16 (integer part)
>      div is (16-14 bits).(13-0 bits) (in binary)
> 
>      Fout = Fin/(2 * div)
>      Fout = ((Fin / 10000)/(2 * div)) * 10000
>      Fout = (2^14 * (Fin / 10000)/(2^14 * (2 * div))) * 10000
>      Fout = (((Fin / 10000) << 14)/(2 * (div << 14))) * 10000
> 
> div << 14 is simply 17 bit value written@register.
> 
> This patch adds in support for this type of clock.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>

Another fixup:

---
 drivers/clk/spear/clk-frac-synth.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/spear/clk-frac-synth.c b/drivers/clk/spear/clk-frac-synth.c
index b2090f8..9915dbc 100644
--- a/drivers/clk/spear/clk-frac-synth.c
+++ b/drivers/clk/spear/clk-frac-synth.c
@@ -59,10 +59,9 @@ static long clk_frac_round_rate(struct clk_hw *hw, unsigned long drate,
                unsigned long *prate)
 {
        struct clk_frac *frac = to_clk_frac(hw);
-       unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
        int unused;
 
-       return clk_round_rate_index(hw, drate, parent_rate, frac_calc_rate,
+       return clk_round_rate_index(hw, drate, *prate, frac_calc_rate,
                        frac->rtbl_cnt, &unused);
 }
 
-- 
viresh

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

* [PATCH V3 3/8] SPEAr: clk: Add VCO-PLL Synthesizer clock
  2012-04-24  6:50 ` [PATCH V3 3/8] SPEAr: clk: Add VCO-PLL Synthesizer clock Viresh Kumar
  2012-04-27  4:44   ` Viresh Kumar
@ 2012-05-03  5:47   ` Viresh Kumar
  2012-05-03  9:49   ` Viresh Kumar
  2 siblings, 0 replies; 42+ messages in thread
From: Viresh Kumar @ 2012-05-03  5:47 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/24/2012 12:20 PM, Viresh KUMAR wrote:
> All SPEAr SoC's contain PLLs. Their Fout is derived based on following equations
> 
> - In normal mode
>   vco = (2 * M[15:8] * Fin)/N
> 
> - In Dithered mode
>   vco = (2 * M[15:0] * Fin)/(256 * N)
> 
> pll_rate = vco/2^p
> 
> vco and pll are very closely bound to each other,
> "vco needs to program: mode, m & n" and "pll needs to program p",
> both share common enable/disable logic and registers.
> 
> This patch adds in support for this type of clock.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>

Another fixup:

---
 drivers/clk/spear/clk-vco-pll.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/spear/clk-vco-pll.c b/drivers/clk/spear/clk-vco-pll.c
index e661273..318b04e 100644
--- a/drivers/clk/spear/clk-vco-pll.c
+++ b/drivers/clk/spear/clk-vco-pll.c
@@ -183,10 +183,9 @@ static long clk_vco_round_rate(struct clk_hw *hw, unsigned long drate,
                unsigned long *prate)
 {
        struct clk_vco *vco = to_clk_vco(hw);
-       unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
        int unused;
 
-       return clk_round_rate_index(hw, drate, parent_rate, vco_calc_rate,
+       return clk_round_rate_index(hw, drate, *prate, vco_calc_rate,
                        vco->rtbl_cnt, &unused);
 }
 
-- 
viresh

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

* [PATCH V3 4/8] SPEAr: clk: Add Auxiliary Synthesizer clock
  2012-04-24  6:50 ` [PATCH V3 4/8] SPEAr: clk: Add Auxiliary " Viresh Kumar
  2012-04-27  4:45   ` Viresh Kumar
@ 2012-05-03  5:47   ` Viresh Kumar
  2012-05-03  9:50   ` Viresh Kumar
  2 siblings, 0 replies; 42+ messages in thread
From: Viresh Kumar @ 2012-05-03  5:47 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/24/2012 12:20 PM, Viresh KUMAR wrote:
> All SPEAr SoC's contain Auxiliary Synthesizers. Their Fout is derived based on
> values of eq, x and y.
> 
> Fout from synthesizer can be given from two equations:
> Fout1 = (Fin * X/Y)/2		EQ1
> Fout2 = Fin * X/Y		EQ2
> 
> This patch adds in support for this type of clock.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>

Another fixup:

---
 drivers/clk/spear/clk-aux-synth.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/spear/clk-aux-synth.c b/drivers/clk/spear/clk-aux-synth.c
index c199e78..abb1747 100644
--- a/drivers/clk/spear/clk-aux-synth.c
+++ b/drivers/clk/spear/clk-aux-synth.c
@@ -56,10 +56,9 @@ static long clk_aux_round_rate(struct clk_hw *hw, unsigned long drate,
                unsigned long *prate)
 {
        struct clk_aux *aux = to_clk_aux(hw);
-       unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
        int unused;
 
-       return clk_round_rate_index(hw, drate, parent_rate, aux_calc_rate,
+       return clk_round_rate_index(hw, drate, *prate, aux_calc_rate,
                        aux->rtbl_cnt, &unused);
 }
 
-- 
viresh

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

* [PATCH V3 2/8] clk: add a fixed factor clock
  2012-05-03  5:32         ` Viresh Kumar
@ 2012-05-03  6:37           ` Sascha Hauer
  2012-05-03  9:48             ` Viresh Kumar
  0 siblings, 1 reply; 42+ messages in thread
From: Sascha Hauer @ 2012-05-03  6:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, May 03, 2012 at 11:02:41AM +0530, Viresh Kumar wrote:
> On 5/3/2012 4:11 AM, Mike Turquette wrote:
> > I will take this patch in before sending my request to Arnd.  In your
> > patch 0/8 you ask me to take in the series, but it looks like not all of
> > the patches are going through me.  For instance patch 2/8 certainly
> > looks destined for Russell.
> 
> I think you only need to take this patch, i.e. 2/8.
> Others will go through Arnd directly, keeping your branch as an dependency
> branch for it.
> 
> > After fixing up this patch can you resend a clean series which is only
> > headed for clk-next?
> 
> So, i would be sending this patch only after applying the last fixup
> (hopefully :) ).
> 
> @Sascha: Please see if this patch is sufficient.
> 
> ---
>  drivers/clk/clk-fixed-factor.c |    9 ++++-----
>  1 files changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
> index 9afbdc4..8d25c2e 100644
> --- a/drivers/clk/clk-fixed-factor.c
> +++ b/drivers/clk/clk-fixed-factor.c
> @@ -37,16 +37,15 @@ static long clk_factor_round_rate(struct clk_hw *hw, unsigned long rate,
>  {
>         struct clk_fixed_factor *fix = to_clk_fixed_factor(hw);
>  
> -       if (prate) {
> +       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;
> -       } else {
> -               return (__clk_get_rate(__clk_get_parent(hw->clk)) / fix->div) *
> -                       fix->mult;
>         }
> +
> +       return (*prate / fix->div) * fix->mult;
>  }

Yes, looks good.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* [PATCH V3 2/8] clk: add a fixed factor clock
  2012-05-03  6:37           ` Sascha Hauer
@ 2012-05-03  9:48             ` Viresh Kumar
  0 siblings, 0 replies; 42+ messages in thread
From: Viresh Kumar @ 2012-05-03  9:48 UTC (permalink / raw)
  To: linux-arm-kernel

On 5/3/2012 12:07 PM, Sascha Hauer wrote:
> Yes, looks good.

Thanks. Here is one more to review, found after rebasing on latest
clk-next from Mike. I will send this a complete patch for fixed factor
clock separately, following is just for review.

This happened due to Saravana's patch:

---
 drivers/clk/clk-fixed-factor.c |   15 +++++++++------
 1 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index 8d25c2e..0e8782b 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -66,10 +66,10 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
                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);
@@ -78,12 +78,15 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
        /* 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, name,
-                       &clk_fixed_factor_ops, &fix->hw,
-                       &parent_name,
-                       (parent_name ? 1 : 0),
-                       flags);
+       clk = clk_register(dev, &fix->hw);
 
        if (clk)
                return clk;


-- 
viresh

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

* [PATCH V3 3/8] SPEAr: clk: Add VCO-PLL Synthesizer clock
  2012-04-24  6:50 ` [PATCH V3 3/8] SPEAr: clk: Add VCO-PLL Synthesizer clock Viresh Kumar
  2012-04-27  4:44   ` Viresh Kumar
  2012-05-03  5:47   ` Viresh Kumar
@ 2012-05-03  9:49   ` Viresh Kumar
  2 siblings, 0 replies; 42+ messages in thread
From: Viresh Kumar @ 2012-05-03  9:49 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/24/2012 12:20 PM, Viresh KUMAR wrote:
> All SPEAr SoC's contain PLLs. Their Fout is derived based on following equations
> 
> - In normal mode
>   vco = (2 * M[15:8] * Fin)/N
> 
> - In Dithered mode
>   vco = (2 * M[15:0] * Fin)/(256 * N)
> 
> pll_rate = vco/2^p
> 
> vco and pll are very closely bound to each other,
> "vco needs to program: mode, m & n" and "pll needs to program p",
> both share common enable/disable logic and registers.
> 
> This patch adds in support for this type of clock.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
> ---

Sorry for another fixup. Required due to Saravana's patch:

---
 drivers/clk/spear/clk-vco-pll.c |   22 ++++++++++++++++++----
 1 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/spear/clk-vco-pll.c b/drivers/clk/spear/clk-vco-pll.c
index 318b04e..dcd4bdf 100644
--- a/drivers/clk/spear/clk-vco-pll.c
+++ b/drivers/clk/spear/clk-vco-pll.c
@@ -282,6 +282,7 @@ struct clk *clk_register_vco_pll(const char *vco_name, const char *pll_name,
        struct clk_vco *vco;
        struct clk_pll *pll;
        struct clk *vco_clk, *tpll_clk, *tvco_gate_clk;
+       struct clk_init_data vco_init, pll_init;
        const char **vco_parent_name;
 
        if (!vco_name || !pll_name || !parent_name || !mode_reg || !cfg_reg ||
@@ -308,7 +309,10 @@ struct clk *clk_register_vco_pll(const char *vco_name, const char *pll_name,
        vco->rtbl = rtbl;
        vco->rtbl_cnt = rtbl_cnt;
        vco->lock = lock;
+       vco->hw.init = &vco_init;
+
        pll->vco = vco;
+       pll->hw.init = &pll_init;
 
        if (vco_gate_name) {
                tvco_gate_clk = clk_register_gate(NULL, vco_gate_name,
@@ -323,13 +327,23 @@ struct clk *clk_register_vco_pll(const char *vco_name, const char *pll_name,
                vco_parent_name = &parent_name;
        }
 
-       vco_clk = clk_register(NULL, vco_name, &clk_vco_ops, &vco->hw,
-                       vco_parent_name, 1, flags);
+       vco_init.name = vco_name;
+       vco_init.ops = &clk_vco_ops;
+       vco_init.flags = flags;
+       vco_init.parent_names = vco_parent_name;
+       vco_init.num_parents = 1;
+
+       pll_init.name = pll_name;
+       pll_init.ops = &clk_pll_ops;
+       pll_init.flags = CLK_SET_RATE_PARENT;
+       pll_init.parent_names = &vco_name;
+       pll_init.num_parents = 1;

-- 
viresh

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

* [PATCH V3 4/8] SPEAr: clk: Add Auxiliary Synthesizer clock
  2012-04-24  6:50 ` [PATCH V3 4/8] SPEAr: clk: Add Auxiliary " Viresh Kumar
  2012-04-27  4:45   ` Viresh Kumar
  2012-05-03  5:47   ` Viresh Kumar
@ 2012-05-03  9:50   ` Viresh Kumar
  2 siblings, 0 replies; 42+ messages in thread
From: Viresh Kumar @ 2012-05-03  9:50 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/24/2012 12:20 PM, Viresh KUMAR wrote:
> All SPEAr SoC's contain Auxiliary Synthesizers. Their Fout is derived based on
> values of eq, x and y.
> 
> Fout from synthesizer can be given from two equations:
> Fout1 = (Fin * X/Y)/2		EQ1
> Fout2 = Fin * X/Y		EQ2
> 
> This patch adds in support for this type of clock.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>

Sorry for another fixup. Required due to Saravana's patch:

---
 drivers/clk/spear/clk-aux-synth.c |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/spear/clk-aux-synth.c b/drivers/clk/spear/clk-aux-synth.c
index abb1747..af34074 100644
--- a/drivers/clk/spear/clk-aux-synth.c
+++ b/drivers/clk/spear/clk-aux-synth.c
@@ -140,6 +140,7 @@ struct clk *clk_register_aux(const char *aux_name, const char *gate_name,
                u8 rtbl_cnt, spinlock_t *lock, struct clk **gate_clk)
 {
        struct clk_aux *aux;
+       struct clk_init_data init;
        struct clk *clk;
 
        if (!aux_name || !parent_name || !reg || !rtbl || !rtbl_cnt) {
@@ -163,9 +164,15 @@ struct clk *clk_register_aux(const char *aux_name, const char *gate_name,
        aux->rtbl = rtbl;
        aux->rtbl_cnt = rtbl_cnt;
        aux->lock = lock;
+       aux->hw.init = &init;
 
-       clk = clk_register(NULL, aux_name, &clk_aux_ops, &aux->hw, &parent_name,
-                       1, flags);
+       init.name = aux_name;
+       init.ops = &clk_aux_ops;
+       init.flags = flags;
+       init.parent_names = &parent_name;
+       init.num_parents = 1;
+
+       clk = clk_register(NULL, &aux->hw);
        if (IS_ERR_OR_NULL(clk))
                goto free_aux;
 
-- 
viresh

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

* [PATCH V3 5/8] SPEAr: clk: Add Fractional Synthesizer clock
  2012-04-24  6:50 ` [PATCH V3 5/8] SPEAr: clk: Add Fractional " Viresh Kumar
  2012-04-27  4:45   ` Viresh Kumar
  2012-05-03  5:46   ` Viresh Kumar
@ 2012-05-03  9:51   ` Viresh Kumar
  2 siblings, 0 replies; 42+ messages in thread
From: Viresh Kumar @ 2012-05-03  9:51 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/24/2012 12:20 PM, Viresh KUMAR wrote:
> All SPEAr SoC's contain Fractional Synthesizers. Their Fout is derived from
> following equations:
> 
> Fout = Fin / (2 * div) (division factor)
> div is 17 bits:-
>      0-13 (fractional part)
>      14-16 (integer part)
>      div is (16-14 bits).(13-0 bits) (in binary)
> 
>      Fout = Fin/(2 * div)
>      Fout = ((Fin / 10000)/(2 * div)) * 10000
>      Fout = (2^14 * (Fin / 10000)/(2^14 * (2 * div))) * 10000
>      Fout = (((Fin / 10000) << 14)/(2 * (div << 14))) * 10000
> 
> div << 14 is simply 17 bit value written@register.
> 
> This patch adds in support for this type of clock.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
> ---

Sorry for another fixup. Required due to Saravana's patch:
---
 drivers/clk/spear/clk-frac-synth.c |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/spear/clk-frac-synth.c b/drivers/clk/spear/clk-frac-synth.c
index 9915dbc..4dbdb3f 100644
--- a/drivers/clk/spear/clk-frac-synth.c
+++ b/drivers/clk/spear/clk-frac-synth.c
@@ -126,6 +126,7 @@ struct clk *clk_register_frac(const char *name, const char *parent_name,
                unsigned long flags, void __iomem *reg,
                struct frac_rate_tbl *rtbl, u8 rtbl_cnt, spinlock_t *lock)
 {
+       struct clk_init_data init;
        struct clk_frac *frac;
        struct clk *clk;
 
@@ -145,9 +146,15 @@ struct clk *clk_register_frac(const char *name, const char *parent_name,
        frac->rtbl = rtbl;
        frac->rtbl_cnt = rtbl_cnt;
        frac->lock = lock;
+       frac->hw.init = &init;
 
-       clk = clk_register(NULL, name, &clk_frac_ops, &frac->hw, &parent_name,
-                       1, flags);
+       init.name = name;
+       init.ops = &clk_frac_ops;
+       init.flags = flags;
+       init.parent_names = &parent_name;
+       init.num_parents = 1;
+
+       clk = clk_register(NULL, &frac->hw);
        if (!IS_ERR_OR_NULL(clk))
                return clk;
 

-- 
viresh

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

* [PATCH V3 6/8] SPEAr: clk: Add General Purpose Timer Synthesizer clock
  2012-04-24  6:50 ` [PATCH V3 6/8] SPEAr: clk: Add General Purpose Timer " Viresh Kumar
  2012-04-27  4:46   ` Viresh Kumar
  2012-05-03  5:43   ` Viresh Kumar
@ 2012-05-03  9:51   ` Viresh Kumar
  2 siblings, 0 replies; 42+ messages in thread
From: Viresh Kumar @ 2012-05-03  9:51 UTC (permalink / raw)
  To: linux-arm-kernel

On 4/24/2012 12:20 PM, Viresh KUMAR wrote:
> All SPEAr SoC's contain GPT Synthesizers. Their Fout is derived from
> following equations:
> 
> Fout= Fin/((2 ^ (N+1)) * (M+1))
> 
> This patch adds in support for this type of clock.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>

Sorry for another fixup. Required due to Saravana's patch:

---
 drivers/clk/spear/clk-gpt-synth.c |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/spear/clk-gpt-synth.c b/drivers/clk/spear/clk-gpt-synth.c
index 688cbf4..b471c97 100644
--- a/drivers/clk/spear/clk-gpt-synth.c
+++ b/drivers/clk/spear/clk-gpt-synth.c
@@ -115,6 +115,7 @@ struct clk *clk_register_gpt(const char *name, const char *parent_name, unsigned
                long flags, void __iomem *reg, struct gpt_rate_tbl *rtbl, u8
                rtbl_cnt, spinlock_t *lock)
 {
+       struct clk_init_data init;
        struct clk_gpt *gpt;
        struct clk *clk;
 
@@ -134,9 +135,15 @@ struct clk *clk_register_gpt(const char *name, const char *parent_name, unsigned
        gpt->rtbl = rtbl;
        gpt->rtbl_cnt = rtbl_cnt;
        gpt->lock = lock;
+       gpt->hw.init = &init;
 
-       clk = clk_register(NULL, name, &clk_gpt_ops, &gpt->hw, &parent_name, 1,
-                       flags);
+       init.name = name;
+       init.ops = &clk_gpt_ops;
+       init.flags = flags;
+       init.parent_names = &parent_name;
+       init.num_parents = 1;
+
+       clk = clk_register(NULL, &gpt->hw);
        if (!IS_ERR_OR_NULL(clk))
                return clk;

-- 
viresh

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

end of thread, other threads:[~2012-05-03  9:51 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-24  6:50 [PATCH V3 0/8] SPEAr: Move to common clock framework Viresh Kumar
2012-04-24  6:50 ` [PATCH V3 1/8] CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk * Viresh Kumar
2012-04-26  7:47   ` Russell King - ARM Linux
2012-04-26 10:28     ` Viresh Kumar
2012-04-28  9:52       ` Russell King - ARM Linux
2012-04-28 11:01         ` Sascha Hauer
2012-04-28 11:06           ` Russell King - ARM Linux
2012-05-01  8:45             ` Viresh Kumar
2012-05-01 12:31             ` Shawn Guo
2012-05-02  9:54               ` Russell King - ARM Linux
2012-05-02 13:59                 ` Shawn Guo
2012-05-02 14:13                   ` Russell King - ARM Linux
2012-04-30  8:08         ` Viresh Kumar
2012-04-24  6:50 ` [PATCH V3 2/8] clk: add a fixed factor clock Viresh Kumar
2012-04-27  4:43   ` Viresh Kumar
2012-05-02  9:48   ` Sascha Hauer
2012-05-02 11:56     ` Viresh Kumar
2012-05-02 22:41       ` Mike Turquette
2012-05-02 22:44         ` Mike Turquette
2012-05-02 23:31           ` Russell King - ARM Linux
2012-05-03  5:32         ` Viresh Kumar
2012-05-03  6:37           ` Sascha Hauer
2012-05-03  9:48             ` Viresh Kumar
2012-04-24  6:50 ` [PATCH V3 3/8] SPEAr: clk: Add VCO-PLL Synthesizer clock Viresh Kumar
2012-04-27  4:44   ` Viresh Kumar
2012-05-03  5:47   ` Viresh Kumar
2012-05-03  9:49   ` Viresh Kumar
2012-04-24  6:50 ` [PATCH V3 4/8] SPEAr: clk: Add Auxiliary " Viresh Kumar
2012-04-27  4:45   ` Viresh Kumar
2012-05-03  5:47   ` Viresh Kumar
2012-05-03  9:50   ` Viresh Kumar
2012-04-24  6:50 ` [PATCH V3 5/8] SPEAr: clk: Add Fractional " Viresh Kumar
2012-04-27  4:45   ` Viresh Kumar
2012-05-03  5:46   ` Viresh Kumar
2012-05-03  9:51   ` Viresh Kumar
2012-04-24  6:50 ` [PATCH V3 6/8] SPEAr: clk: Add General Purpose Timer " Viresh Kumar
2012-04-27  4:46   ` Viresh Kumar
2012-05-03  5:43   ` Viresh Kumar
2012-05-03  9:51   ` Viresh Kumar
2012-04-24  6:50 ` [PATCH V3 7/8] SPEAr: Call clk_prepare() before calling clk_enable Viresh Kumar
2012-04-27  4:42 ` [PATCH V3 0/8] SPEAr: Move to common clock framework Viresh Kumar
2012-04-27 17:50   ` Turquette, Mike

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.