Skip to contentSkip to conversation

SPEAr: Move to common clock framework

PATCH Superseded Viresh Kumar 5 participants 42 messages Apr 24, 2012 – May 3, 2012

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

v3 cover SPEAr: Move to common clock framework

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
Signature · 1 line
1.7.9
#1 lore raw

PATCH v3 1/8 CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk *

From: Russell King <[email protected]>

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.

---
 drivers/clk/clkdev.c   |   64 +++++++++++++++++++++++++++++++++++++++++++----
 include/linux/clkdev.h |    3 ++
 2 files changed, 61 insertions(+), 6 deletions(-)
drivers/clk/clkdev.c +58 -6
index d4a5993..e39d96f 100644
@@ -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);
include/linux/clkdev.h +3 -0
index d9a4fd0..01d8ff6 100644
@@ -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
Signature · 1 line
1.7.9
#2 lore raw

PATCH v3 1/8 CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk *

Quoted 9 lines · Viresh Kumar

From: Russell King <[email protected]>

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.

#3 lore raw

PATCH v3 1/8 CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk *

Quoted 7 lines · Russell King - ARM Linux

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 <[email protected]>
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.

---
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(-)
drivers/clk/clkdev.c +65 -10
index d4a5993..c890214 100644
@@ -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);
include/linux/clkdev.h +3 -0
index d9a4fd0..01d8ff6 100644
@@ -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
Signature · 6 lines
1.7.9



-- 
viresh
#4 lore raw

PATCH v3 1/8 CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk *

Quoted 11 lines · Viresh Kumar

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

From: Russell King <[email protected]>
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.

Quoted 7 lines

This patch introduces helper routines to:

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

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

drivers/clk/clkdev.c +78 -6
index 6db161f..f5db067 100644
@@ -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);
include/linux/clkdev.h +3 -0
index d9a4fd0..a6a6f60 100644
@@ -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
#5 lore raw

PATCH v3 1/8 CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk *

Quoted 13 lines · Russell King - ARM Linux
drivers/clk/clkdev.c +13 -0
+
+/**
+ * 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

drivers/clk/clkdev.c void clkdev_drop(struct clk_lookup *cl) · line 208

Quoted 10 lines
drivers/clk/clkdev.c +10 -0
+ * 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

Signature · 4 lines
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 |
#6 lore raw

PATCH v3 1/8 CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk *

Quoted 18 lines · Sascha Hauer
Quoted 17 lines · Russell King - ARM Linux
(quoted diff) +17 -0
+
+/**
+ * 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, ...)
Quoted 8 lines

Review

Quoted 6 lines
(quoted diff) +6 -0
+{
+	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.

drivers/clk/clkdev.c +78 -6
index 6db161f..2000c6b 100644
@@ -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);
include/linux/clkdev.h +3 -0
index d9a4fd0..a6a6f60 100644
@@ -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
#7 lore raw

PATCH v3 1/8 CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk *

Quoted 117 lines · Russell King - ARM Linux
drivers/clk/clkdev.c +78 -6
index 6db161f..2000c6b 100644
@@ -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);
include/linux/clkdev.h +0 -0
index d9a4fd0..a6a6f60 100644

include/linux/clkdev.h void clkdev_drop(struct clk_lookup *cl); · line 46

Quoted 7 lines
include/linux/clkdev.h +3 -0
@@ -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
Signature · 1 line
viresh
#8 lore raw

PATCH v3 1/8 CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk *

In reply to Russell King - ARM Linux
Quoted 95 lines · Russell King - ARM Linux
drivers/clk/clkdev.c +61 -6
index 6db161f..2000c6b 100644
@@ -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

drivers/clk/clkdev.c void clkdev_drop(struct clk_lookup *cl) · line 240

Quoted 10 lines
drivers/clk/clkdev.c +10 -0
+ * 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++) {

Regards,
Shawn

Quoted 25 lines
drivers/clk/clkdev.c +7 -0
+		cl->clk = clk;
+		clkdev_add(cl);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(clk_register_clkdevs);
include/linux/clkdev.h +3 -0
index d9a4fd0..a6a6f60 100644
@@ -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

#9 lore raw

PATCH v3 1/8 CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk *

Quoted 8 lines · Shawn Guo

drivers/clk/clkdev.c void clkdev_drop(struct clk_lookup *cl) · line 240

Quoted 1 line
drivers/clk/clkdev.c +1 -0
+	for (i = 0; i < num; i++) {

With above line changed to:

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

Thanks, fixed that and committed.

#10 lore raw

PATCH v3 1/8 CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk *

Quoted 11 lines · Russell King - ARM Linux
Quoted 8 lines · Shawn Guo

drivers/clk/clkdev.c void clkdev_drop(struct clk_lookup *cl) · line 240

Quoted 1 line
drivers/clk/clkdev.c +1 -0
+	for (i = 0; i < num; i++) {

With above line changed to:

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

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?

Signature · 2 lines
Regards,
Shawn
#11 lore raw

PATCH v3 1/8 CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk *

Quoted 9 lines · Shawn Guo
Quoted 8 lines · Russell King - ARM Linux
Quoted 7 lines · Shawn Guo

drivers/clk/clkdev.c void clkdev_drop(struct clk_lookup *cl) · line 240

Quoted 1 line
drivers/clk/clkdev.c +1 -0
+	for (i = 0; i < num; i++) {

With above line changed to:

	for (i = 0; i < num; i++, cl++) {
Quoted 6 lines
Quoted 3 lines
Quoted 1 line

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

#12 lore raw

PATCH v3 1/8 CLKDEV: Add helper routines to allocate and add clkdevs for given struct clk *

In reply to Russell King - ARM Linux
Quoted 2 lines · Russell King - ARM Linux

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.

Quoted 8 lines

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

Quoted 3 lines

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.

Signature · 1 line
viresh
#13 lore raw

PATCH v3 2/8 clk: add a fixed factor clock

In reply to Viresh Kumar

From: Sascha Hauer <[email protected]>

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.

---
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
drivers/clk/Makefile +1 -1
index 1f736bc..24aa714 100644
@@ -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
drivers/clk/clk-fixed-factor.c new file +94 -0

94 lines not on this page · raw message

include/linux/clk-private.h +20 -0
index eeae7a3..1e0fa93 100644
@@ -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
include/linux/clk-provider.h +23 -0
index 8e85a9d..067b04d 100644
@@ -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
Signature · 1 line
1.7.9
#14 lore raw

PATCH v3 2/8 clk: add a fixed factor clock

Quoted 7 lines · Viresh KUMAR

From: Sascha Hauer <[email protected]>

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.

fixup! clk: add a fixed factor clock

---
 drivers/clk/clk-fixed-factor.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
drivers/clk/clk-fixed-factor.c +2 -1
index 7453efe..9afbdc4 100644
@@ -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;
 }
Signature · 1 line
viresh
#15 lore raw

PATCH v3 2/8 clk: add a fixed factor clock

In reply to Viresh Kumar
Quoted 77 lines · Viresh Kumar

From: Sascha Hauer <[email protected]>

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.

---
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
drivers/clk/Makefile +1 -1
index 1f736bc..24aa714 100644
@@ -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
drivers/clk/clk-fixed-factor.c new file +40 -0
new file mode 100644
index 0000000..7453efe
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2011 Sascha Hauer, Pengutronix <[email protected]>
+ *
+ * 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) {

drivers/clk/clk-fixed-factor.c line 50

Quoted 10 lines
drivers/clk/clk-fixed-factor.c new file +10 -0
+		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

Signature · 4 lines
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 |
#16 lore raw

PATCH v3 2/8 clk: add a fixed factor clock

Quoted 5 lines · Sascha Hauer

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.

Signature · 1 line
viresh
#17 lore raw

PATCH v3 2/8 clk: add a fixed factor clock

Quoted 7 lines · Viresh Kumar
Quoted 5 lines · Sascha Hauer

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

Quoted 7 lines

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

#18 lore raw

PATCH v3 2/8 clk: add a fixed factor clock

Quoted 14 lines · Mike Turquette
Quoted 13 lines · Viresh Kumar
Quoted 5 lines · Sascha Hauer

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.

Quoted 6 lines
Quoted 1 line

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

Quoted 6 lines

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

Thanks,
Mike

#19 lore raw

PATCH v3 2/8 clk: add a fixed factor clock

Quoted 17 lines · Mike Turquette
Quoted 16 lines · Mike Turquette
Quoted 14 lines · Viresh Kumar
Quoted 5 lines · Sascha Hauer

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.

Quoted 8 lines
Quoted 4 lines

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

#20 lore raw

PATCH v3 2/8 clk: add a fixed factor clock

In reply to Mike Turquette
Quoted 4 lines · Mike Turquette

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.

Quoted 2 lines

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(-)
drivers/clk/clk-fixed-factor.c +4 -5
index 9afbdc4..8d25c2e 100644
@@ -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,
Signature · 1 line
viresh
#21 lore raw

PATCH v3 2/8 clk: add a fixed factor clock

Quoted 35 lines · Viresh Kumar
Quoted 4 lines · Mike Turquette

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.

Quoted 2 lines

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(-)
drivers/clk/clk-fixed-factor.c +2 -1
index 9afbdc4..8d25c2e 100644
@@ -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;

drivers/clk/clk-fixed-factor.c static long clk_factor_round_rate(struct clk_hw *hw, unsigned long rate, · line 49

Quoted 10 lines
drivers/clk/clk-fixed-factor.c +2 -4
                *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

Signature · 4 lines
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 |
#22 lore raw

PATCH v3 2/8 clk: add a fixed factor clock

Quoted 1 line · Sascha Hauer

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(-)
drivers/clk/clk-fixed-factor.c +9 -6
index 8d25c2e..0e8782b 100644
@@ -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;
Signature · 1 line
viresh
#23 lore raw

PATCH v3 3/8 SPEAr: clk: Add VCO-PLL Synthesizer clock

In reply to Viresh Kumar

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.

---
 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
drivers/clk/Makefile +3 -0
index 24aa714..0f5e03d 100644
@@ -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/
drivers/clk/spear/Makefile new file +5 -0
new file mode 100644
index 0000000..3fc2a30
@@ -0,0 +1,5 @@
+#
+# SPEAr Clock specific Makefile
+#
+
+obj-y	+= clk.o clk-vco-pll.o
drivers/clk/spear/clk-vco-pll.c new file +346 -0

346 lines not on this page · raw message

drivers/clk/spear/clk.c new file +36 -0
new file mode 100644
index 0000000..74f6acc
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <[email protected]>
+ *
+ * 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;
+}
drivers/clk/spear/clk.h new file +57 -0

57 lines not on this page · raw message

Signature · 1 line
1.7.9
#24 lore raw

PATCH v3 3/8 SPEAr: clk: Add VCO-PLL Synthesizer clock

Quoted 8 lines · Viresh KUMAR

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)

Quoted 7 lines

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(-)
drivers/clk/spear/clk-vco-pll.c +9 -5
index 9efa30d..e661273 100644
@@ -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);
drivers/clk/spear/clk.c +2 -2
index 74f6acc..376d4e5 100644
@@ -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;
drivers/clk/spear/clk.h +2 -1
index ee17994..3321c46 100644
@@ -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 */
Signature · 1 line
viresh
#25 lore raw

PATCH v3 3/8 SPEAr: clk: Add VCO-PLL Synthesizer clock

In reply to Viresh Kumar
Quoted 10 lines · Viresh KUMAR

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

Quoted 7 lines

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.

Another fixup:

---
 drivers/clk/spear/clk-vco-pll.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)
drivers/clk/spear/clk-vco-pll.c +1 -2
index e661273..318b04e 100644
@@ -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);
 }
 
Signature · 1 line
viresh
#26 lore raw

PATCH v3 3/8 SPEAr: clk: Add VCO-PLL Synthesizer clock

In reply to Viresh Kumar
Quoted 10 lines · Viresh KUMAR

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

Quoted 8 lines

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.

---

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(-)
drivers/clk/spear/clk-vco-pll.c +15 -3
index 318b04e..dcd4bdf 100644
@@ -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

#27 lore raw

PATCH v3 4/8 SPEAr: clk: Add Auxiliary Synthesizer clock

In reply to Viresh Kumar

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.

---
 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
drivers/clk/spear/Makefile +1 -1
index 3fc2a30..e36d8c6 100644
@@ -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
drivers/clk/spear/clk-aux-synth.c new file +189 -0

189 lines not on this page · raw message

drivers/clk/spear/clk.h +43 -0

55 lines not on this page · raw message

Signature · 1 line
1.7.9
#28 lore raw

PATCH v3 4/8 SPEAr: clk: Add Auxiliary Synthesizer clock

Quoted 10 lines · Viresh KUMAR

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.

fixup! SPEAr: clk: Add Auxiliary Synthesizer clock

---
 drivers/clk/spear/clk-aux-synth.c |   11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)
drivers/clk/spear/clk-aux-synth.c +7 -4
index e01a350..c199e78 100644
@@ -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);
Signature · 1 line
viresh
#29 lore raw

PATCH v3 4/8 SPEAr: clk: Add Auxiliary Synthesizer clock

In reply to Viresh Kumar
Quoted 10 lines · Viresh KUMAR

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.

Another fixup:

---
 drivers/clk/spear/clk-aux-synth.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)
drivers/clk/spear/clk-aux-synth.c +1 -2
index c199e78..abb1747 100644
@@ -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);
 }
 
Signature · 1 line
viresh
#30 lore raw

PATCH v3 4/8 SPEAr: clk: Add Auxiliary Synthesizer clock

In reply to Viresh Kumar
Quoted 10 lines · Viresh KUMAR

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.

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(-)
drivers/clk/spear/clk-aux-synth.c +9 -2
index abb1747..af34074 100644
@@ -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;
 
Signature · 1 line
viresh
#31 lore raw

PATCH v3 5/8 SPEAr: clk: Add Fractional Synthesizer clock

In reply to Viresh Kumar

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.

---
 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
drivers/clk/spear/Makefile +1 -1
index e36d8c6..1827036 100644
@@ -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
drivers/clk/spear/clk-frac-synth.c new file +156 -0

156 lines not on this page · raw message

drivers/clk/spear/clk.h +16 -0
index ae3dc44..c7dbc84 100644
@@ -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
Signature · 1 line
1.7.9
#32 lore raw

PATCH v3 5/8 SPEAr: clk: Add Fractional Synthesizer clock

Quoted 14 lines · Viresh KUMAR

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
Quoted 5 lines

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

This patch adds in support for this type of clock.

fixup! SPEAr: clk: Add Fractional Synthesizer clock

---
 drivers/clk/spear/clk-frac-synth.c |   11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)
drivers/clk/spear/clk-frac-synth.c +7 -4
index c6ccdab..b2090f8 100644
@@ -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);
Signature · 1 line
viresh
#33 lore raw

PATCH v3 5/8 SPEAr: clk: Add Fractional Synthesizer clock

In reply to Viresh Kumar
Quoted 14 lines · Viresh KUMAR

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
Quoted 5 lines

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

This patch adds in support for this type of clock.

Another fixup:

---
 drivers/clk/spear/clk-frac-synth.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)
drivers/clk/spear/clk-frac-synth.c +1 -2
index b2090f8..9915dbc 100644
@@ -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);
 }
 
Signature · 1 line
viresh
#34 lore raw

PATCH v3 5/8 SPEAr: clk: Add Fractional Synthesizer clock

In reply to Viresh Kumar
Quoted 14 lines · Viresh KUMAR

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
Quoted 6 lines

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

This patch adds in support for this type of clock.

---

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(-)
drivers/clk/spear/clk-frac-synth.c +9 -2
index 9915dbc..4dbdb3f 100644
@@ -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;
 
Signature · 1 line
viresh
#35 lore raw

PATCH v3 6/8 SPEAr: clk: Add General Purpose Timer Synthesizer clock

In reply to Viresh Kumar

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.

---
 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
drivers/clk/spear/Makefile +1 -1
index 1827036..9e64824 100644
@@ -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
drivers/clk/spear/clk-gpt-synth.c new file +145 -0

145 lines not on this page · raw message

drivers/clk/spear/clk.h +17 -0
index c7dbc84..ee17994 100644
@@ -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
Signature · 1 line
1.7.9
#36 lore raw

PATCH v3 6/8 SPEAr: clk: Add General Purpose Timer Synthesizer clock

Quoted 6 lines · Viresh KUMAR

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(-)
drivers/clk/spear/clk-gpt-synth.c +7 -4
index 514539c..f3b252a 100644
@@ -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);
Signature · 1 line
viresh
#37 lore raw

PATCH v3 6/8 SPEAr: clk: Add General Purpose Timer Synthesizer clock

In reply to Viresh Kumar
Quoted 8 lines · Viresh KUMAR

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.

Another Fixup:

---
 drivers/clk/spear/clk-gpt-synth.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)
drivers/clk/spear/clk-gpt-synth.c +1 -2
index f3b252a..688cbf4 100644
@@ -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);
 }
 
Signature · 1 line
viresh
#38 lore raw

PATCH v3 6/8 SPEAr: clk: Add General Purpose Timer Synthesizer clock

In reply to Viresh Kumar
Quoted 8 lines · Viresh KUMAR

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.

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(-)
drivers/clk/spear/clk-gpt-synth.c +9 -2
index 688cbf4..b471c97 100644
@@ -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;
 
Signature · 1 line
viresh
#39 lore raw

PATCH v3 7/8 SPEAr: Call clk_prepare() before calling clk_enable

In reply to Viresh Kumar

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

---
 arch/arm/plat-spear/time.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)
arch/arm/plat-spear/time.c +4 -4
index a3164d1..4f05d26 100644
@@ -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);
Signature · 1 line
1.7.9
#40 lore raw

v3 cover SPEAr: Move to common clock framework

In reply to Viresh Kumar
Quoted 4 lines · Viresh KUMAR

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 <[email protected]>
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.

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

Signature · 1 line
viresh
#41 lore raw

v3 cover SPEAr: Move to common clock framework

Quoted 21 lines · Viresh Kumar
Quoted 4 lines · Viresh KUMAR

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 <[email protected]>
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.

Quoted 7 lines

? ?It also updates the kernel doc for .set_rate ops.

? ?Signed-off-by: Shawn Guo <[email protected]> ? ?Signed-off-by: Mike Turquette <[email protected]>

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

Quoted 2 lines

--
viresh