All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/2] clk: Generic support for fixed-rate clocks
  2010-12-08  2:05 ` Jeremy Kerr
@ 2010-12-08  2:05   ` Jeremy Kerr
  -1 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2010-12-08  2:05 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: linux-kernel

Since most platforms will need a fixed-rate clock, add one. This will
also serve as a basic example of an implementation of struct clk.

Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>

---
 include/linux/clk.h |   13 +++++++++++++
 kernel/clk.c        |   14 ++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/include/linux/clk.h b/include/linux/clk.h
index e09e40e..ae7e4ed 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -158,6 +158,19 @@ static inline void clk_common_init(struct clk *clk)
 		mutex_init(&clk->lock.mutex);
 }
 
+/* Simple fixed-rate clock */
+struct clk_fixed {
+	struct clk	clk;
+	unsigned long	rate;
+};
+
+extern struct clk_ops clk_fixed_ops;
+
+#define INIT_CLK_FIXED(name, r) { \
+	.clk = INIT_CLK(name.clk, clk_fixed_ops), \
+	.rate = (r) \
+}
+
 #else /* !CONFIG_USE_COMMON_STRUCT_CLK */
 
 /*
diff --git a/kernel/clk.c b/kernel/clk.c
index 1545e69..2779abb 100644
--- a/kernel/clk.c
+++ b/kernel/clk.c
@@ -98,3 +98,17 @@ struct clk *clk_get_parent(struct clk *clk)
 	return ERR_PTR(-ENOSYS);
 }
 EXPORT_SYMBOL_GPL(clk_get_parent);
+
+/* clk_fixed support */
+
+#define to_clk_fixed(clk) (container_of(clk, struct clk_fixed, clk))
+
+static unsigned long clk_fixed_get_rate(struct clk *clk)
+{
+	return to_clk_fixed(clk)->rate;
+}
+
+struct clk_ops clk_fixed_ops = {
+	.get_rate = clk_fixed_get_rate,
+};
+EXPORT_SYMBOL_GPL(clk_fixed_ops);

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

* [PATCH 1/2] Add a common struct clk
@ 2010-12-08  2:05 ` Jeremy Kerr
  0 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2010-12-08  2:05 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: linux-kernel

We currently have ~21 definitions of struct clk in the ARM architecture,
each defined on a per-platform basis. This makes it difficult to define
platform- (or architecture-) independent clock sources without making
assumptions about struct clk, and impossible to compile two
platforms with different struct clks into a single image.

This change is an effort to unify struct clk where possible, by defining
a common struct clk, containing a set of clock operations. Different
clock implementations can set their own operations, and have a standard
interface for generic code. The callback interface is exposed to the
kernel proper, while the clock implementations only need to be seen by
the platform internals.

This allows us to share clock code among platforms, and makes it
possible to dynamically create clock devices in platform-independent
code.

Platforms can enable the generic struct clock through
CONFIG_USE_COMMON_STRUCT_CLK. In this case, the clock infrastructure
consists of a common struct clk:

struct clk {
	const struct clk_ops	*ops;
	unsigned int		enable_count;
	int			flags;
	union {
		struct mutex	mutex;
		spinlock_t	spinlock;
	} lock;
};

And a set of clock operations (defined per type of clock):

struct clk_ops {
	int             (*enable)(struct clk *);
	void            (*disable)(struct clk *);
	unsigned long   (*get_rate)(struct clk *);
	[...]
};

To define a hardware-specific clock, machine code can "subclass" the
struct clock into a new struct (adding any device-specific data), and
provide a set of operations:

struct clk_foo {
	struct clk	clk;
	void __iomem	*some_register;
};

struct clk_ops clk_foo_ops = {
	.get_rate = clk_foo_get_rate,
};

The common clock definitions are based on a development patch from Ben
Herrenschmidt <benh@kernel.crashing.org>.

Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
Acked-by: Paulius Zaleckas <paulius.zaleckas@gmail.com>

---
 arch/Kconfig        |    3 
 include/linux/clk.h |  158 +++++++++++++++++++++++++++++++++++++++++---
 kernel/Makefile     |    1 
 kernel/clk.c        |  100 +++++++++++++++++++++++++++
 4 files changed, 253 insertions(+), 9 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 8bf0fa6..212bd3c 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -165,6 +165,9 @@ config HAVE_MIXED_BREAKPOINTS_REGS
 config HAVE_USER_RETURN_NOTIFIER
 	bool
 
+config USE_COMMON_STRUCT_CLK
+	bool
+
 config HAVE_PERF_EVENTS_NMI
 	bool
 	help
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 1d37f42..e09e40e 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -3,6 +3,7 @@
  *
  *  Copyright (C) 2004 ARM Limited.
  *  Written by Deep Blue Solutions Limited.
+ *  Copyright (c) 2010 Jeremy Kerr <jeremy.kerr@canonical.com>
  *
  * 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
@@ -11,18 +12,163 @@
 #ifndef __LINUX_CLK_H
 #define __LINUX_CLK_H
 
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+
 struct device;
 
-/*
- * The base API.
+#ifdef CONFIG_USE_COMMON_STRUCT_CLK
+
+#define CLK_ATOMIC	0x1
+
+/* If we're using the common struct clk, we define the base clk object here */
+
+/**
+ * struct clk - hardware independent clock structure
+ * @clk_ops:		implementation-specific ops for this clock
+ * @enable_count:	count of clk_enable() calls active on this clock
+ * @flags:		platform-independent flags
+ * @lock:		lock for enable/disable or other HW-specific ops
+ *
+ * The base clock object, used by drivers for hardware-independent manipulation
+ * of clock lines. This will be 'subclassed' by device-specific implementations,
+ * which add device-specific data to struct clk. For example:
+ *
+ *  struct clk_foo {
+ *      struct clk;
+ *      [device specific fields]
+ *  };
+ *
+ * The clock driver code will manage the device-specific data, and pass
+ * clk_foo.clk to the common clock code. The clock driver will be called
+ * through the @ops callbacks.
+ *
+ * The @lock member provides either a spinlock or a mutex to protect (at least)
+ * @enable_count. The type of lock used will depend on @flags; if CLK_ATOMIC is
+ * set, then the core clock code will use a spinlock, otherwise a mutex. This
+ * lock will be acquired during clk_enable and clk_disable, so for atomic
+ * clocks, these ops callbacks must not sleep.
+ *
+ * The choice of atomic or non-atomic clock depends on how the clock is enabled.
+ * Typically, you'll want to use a non-atomic clock. For clocks that need to be
+ * enabled/disabled in interrupt context, use CLK_ATOMIC. Note that atomic
+ * clocks with parents will typically cascade enable/disable operations to
+ * their parent, so the parent of an atomic clock *must* be atomic too.
+ */
+struct clk {
+	const struct clk_ops	*ops;
+	unsigned int		enable_count;
+	int			flags;
+	union {
+		struct mutex	mutex;
+		spinlock_t	spinlock;
+	} lock;
+};
+
+/* static initialiser for non-atomic clocks */
+#define INIT_CLK(name, o) {						\
+	.ops		= &o,						\
+	.enable_count	= 0,						\
+	.flags		= 0,						\
+	.lock.mutex	= __MUTEX_INITIALIZER(name.lock.mutex),		\
+}
+
+/* static initialiser for atomic clocks */
+#define INIT_CLK_ATOMIC(name, o) {					\
+	.ops		= &o,						\
+	.enable_count	= 0,						\
+	.flags		= CLK_ATOMIC,					\
+	.lock.spinlock	= __SPIN_LOCK_UNLOCKED(name.lock.spinlock),	\
+}
+
+/**
+ * clk_ops: Callback operations for clocks; these are to be provided by the
+ * clock implementation, and will be called by drivers through the clk_* API.
+ *
+ * @enable:	Enable the clock. This must not return until the clock is
+ *		generating a valid clock signal, usable by consumer devices.
+ *		Called with clk->lock held.
+ *
+ * @disable:	Disable the clock. Called with clk->lock held.
+ *
+ * @get	/ @put:	Called by the core clock code to notify the driver about
+ *		refounts as clk is passed to drivers. Optional.
+ *
+ * For other callbacks, see the corresponding clk_* functions. Parameters and
+ * return values are passed directly from/to these API functions directly, or
+ * -ENOSYS is returned if the callback is NULL, see kernel/clk.c for
+ * implementation details. All are optional.
  */
+struct clk_ops {
+       int		(*enable)(struct clk *);
+       void		(*disable)(struct clk *);
+       int		(*get)(struct clk *);
+       void		(*put)(struct clk *);
+       unsigned long	(*get_rate)(struct clk *);
+       long		(*round_rate)(struct clk *, unsigned long);
+       int		(*set_rate)(struct clk *, unsigned long);
+       int		(*set_parent)(struct clk *, struct clk *);
+       struct clk *	(*get_parent)(struct clk *);
+};
 
+static inline void __clk_lock(struct clk *clk)
+{
+	if (clk->flags & CLK_ATOMIC)
+		spin_lock(&clk->lock.spinlock);
+	else
+		mutex_lock(&clk->lock.mutex);
+}
+
+static inline void __clk_unlock(struct clk *clk)
+{
+	if (clk->flags & CLK_ATOMIC)
+		spin_unlock(&clk->lock.spinlock);
+	else
+		mutex_unlock(&clk->lock.mutex);
+}
+
+/**
+ * __clk_get - update clock-specific refcounter
+ *
+ * @clk: The clock to refcount
+ *
+ * Before a clock is returned from clk_get, this function should be called
+ * to update any clock-specific refcounting.
+ *
+ * Returns non-zero on success, zero on failure.
+ *
+ * Drivers should not need this function; it is only needed by the
+ * arch-specific clk_get() implementations.
+ */
+int __clk_get(struct clk *clk);
+
+/**
+ * clk_common_init - initialise a clock for driver usage
+ *
+ * Used for runtime intialization of clocks; you don't need to call this
+ * if your clock has been (statically) initialized with INIT_CLK.
+ */
+static inline void clk_common_init(struct clk *clk)
+{
+	clk->enable_count = 0;
+	if (clk->flags & CLK_ATOMIC)
+		spin_lock_init(&clk->lock.spinlock);
+	else
+		mutex_init(&clk->lock.mutex);
+}
+
+#else /* !CONFIG_USE_COMMON_STRUCT_CLK */
 
 /*
- * struct clk - an machine class defined object / cookie.
+ * Global clock object, actual structure is declared per-machine
  */
 struct clk;
 
+static inline void clk_common_init(struct clk *clk) { }
+
+#endif /* !CONFIG_USE_COMMON_STRUCT_CLK */
+
 /**
  * clk_get - lookup and obtain a reference to a clock producer.
  * @dev: device for clock "consumer"
@@ -83,12 +229,6 @@ unsigned long clk_get_rate(struct clk *clk);
  */
 void clk_put(struct clk *clk);
 
-
-/*
- * The remaining APIs are optional for machine class support.
- */
-
-
 /**
  * clk_round_rate - adjust a rate to the exact rate a clock can provide
  * @clk: clock source
diff --git a/kernel/Makefile b/kernel/Makefile
index 0b5ff08..01383a0 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -106,6 +106,7 @@ obj-$(CONFIG_PERF_EVENTS) += perf_event.o
 obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
 obj-$(CONFIG_USER_RETURN_NOTIFIER) += user-return-notifier.o
 obj-$(CONFIG_PADATA) += padata.o
+obj-$(CONFIG_USE_COMMON_STRUCT_CLK) += clk.o
 
 ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y)
 # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
diff --git a/kernel/clk.c b/kernel/clk.c
new file mode 100644
index 0000000..1545e69
--- /dev/null
+++ b/kernel/clk.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2010 Canonical Ltd <jeremy.kerr@canonical.com>
+ *
+ * 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/clk.h>
+#include <linux/module.h>
+
+int clk_enable(struct clk *clk)
+{
+	int ret = 0;
+
+	if (!clk->ops->enable)
+		return 0;
+
+	__clk_lock(clk);
+	if (!clk->enable_count)
+		ret = clk->ops->enable(clk);
+
+	if (!ret)
+		clk->enable_count++;
+	__clk_unlock(clk);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+	if (!clk->ops->disable)
+		return;
+
+	__clk_lock(clk);
+
+	if (!--clk->enable_count)
+		clk->ops->disable(clk);
+
+	__clk_unlock(clk);
+}
+EXPORT_SYMBOL_GPL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	if (clk->ops->get_rate)
+		return clk->ops->get_rate(clk);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(clk_get_rate);
+
+int __clk_get(struct clk *clk)
+{
+	if (clk->ops->get)
+		return clk->ops->get(clk);
+	return 1;
+}
+EXPORT_SYMBOL_GPL(__clk_get);
+
+void clk_put(struct clk *clk)
+{
+	if (clk->ops->put)
+		clk->ops->put(clk);
+}
+EXPORT_SYMBOL_GPL(clk_put);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	if (clk->ops->round_rate)
+		return clk->ops->round_rate(clk, rate);
+	return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	if (clk->ops->set_rate)
+		return clk->ops->set_rate(clk, rate);
+	return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(clk_set_rate);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	if (clk->ops->set_parent)
+		return clk->ops->set_parent(clk, parent);
+	return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(clk_set_parent);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+	if (clk->ops->get_parent)
+		return clk->ops->get_parent(clk);
+	return ERR_PTR(-ENOSYS);
+}
+EXPORT_SYMBOL_GPL(clk_get_parent);

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

* [PATCH 2/2] clk: Generic support for fixed-rate clocks
@ 2010-12-08  2:05   ` Jeremy Kerr
  0 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2010-12-08  2:05 UTC (permalink / raw)
  To: linux-arm-kernel

Since most platforms will need a fixed-rate clock, add one. This will
also serve as a basic example of an implementation of struct clk.

Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>

---
 include/linux/clk.h |   13 +++++++++++++
 kernel/clk.c        |   14 ++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/include/linux/clk.h b/include/linux/clk.h
index e09e40e..ae7e4ed 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -158,6 +158,19 @@ static inline void clk_common_init(struct clk *clk)
 		mutex_init(&clk->lock.mutex);
 }
 
+/* Simple fixed-rate clock */
+struct clk_fixed {
+	struct clk	clk;
+	unsigned long	rate;
+};
+
+extern struct clk_ops clk_fixed_ops;
+
+#define INIT_CLK_FIXED(name, r) { \
+	.clk = INIT_CLK(name.clk, clk_fixed_ops), \
+	.rate = (r) \
+}
+
 #else /* !CONFIG_USE_COMMON_STRUCT_CLK */
 
 /*
diff --git a/kernel/clk.c b/kernel/clk.c
index 1545e69..2779abb 100644
--- a/kernel/clk.c
+++ b/kernel/clk.c
@@ -98,3 +98,17 @@ struct clk *clk_get_parent(struct clk *clk)
 	return ERR_PTR(-ENOSYS);
 }
 EXPORT_SYMBOL_GPL(clk_get_parent);
+
+/* clk_fixed support */
+
+#define to_clk_fixed(clk) (container_of(clk, struct clk_fixed, clk))
+
+static unsigned long clk_fixed_get_rate(struct clk *clk)
+{
+	return to_clk_fixed(clk)->rate;
+}
+
+struct clk_ops clk_fixed_ops = {
+	.get_rate = clk_fixed_get_rate,
+};
+EXPORT_SYMBOL_GPL(clk_fixed_ops);

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

* [PATCH 1/2] Add a common struct clk
@ 2010-12-08  2:05 ` Jeremy Kerr
  0 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2010-12-08  2:05 UTC (permalink / raw)
  To: linux-arm-kernel

We currently have ~21 definitions of struct clk in the ARM architecture,
each defined on a per-platform basis. This makes it difficult to define
platform- (or architecture-) independent clock sources without making
assumptions about struct clk, and impossible to compile two
platforms with different struct clks into a single image.

This change is an effort to unify struct clk where possible, by defining
a common struct clk, containing a set of clock operations. Different
clock implementations can set their own operations, and have a standard
interface for generic code. The callback interface is exposed to the
kernel proper, while the clock implementations only need to be seen by
the platform internals.

This allows us to share clock code among platforms, and makes it
possible to dynamically create clock devices in platform-independent
code.

Platforms can enable the generic struct clock through
CONFIG_USE_COMMON_STRUCT_CLK. In this case, the clock infrastructure
consists of a common struct clk:

struct clk {
	const struct clk_ops	*ops;
	unsigned int		enable_count;
	int			flags;
	union {
		struct mutex	mutex;
		spinlock_t	spinlock;
	} lock;
};

And a set of clock operations (defined per type of clock):

struct clk_ops {
	int             (*enable)(struct clk *);
	void            (*disable)(struct clk *);
	unsigned long   (*get_rate)(struct clk *);
	[...]
};

To define a hardware-specific clock, machine code can "subclass" the
struct clock into a new struct (adding any device-specific data), and
provide a set of operations:

struct clk_foo {
	struct clk	clk;
	void __iomem	*some_register;
};

struct clk_ops clk_foo_ops = {
	.get_rate = clk_foo_get_rate,
};

The common clock definitions are based on a development patch from Ben
Herrenschmidt <benh@kernel.crashing.org>.

Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
Acked-by: Paulius Zaleckas <paulius.zaleckas@gmail.com>

---
 arch/Kconfig        |    3 
 include/linux/clk.h |  158 +++++++++++++++++++++++++++++++++++++++++---
 kernel/Makefile     |    1 
 kernel/clk.c        |  100 +++++++++++++++++++++++++++
 4 files changed, 253 insertions(+), 9 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 8bf0fa6..212bd3c 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -165,6 +165,9 @@ config HAVE_MIXED_BREAKPOINTS_REGS
 config HAVE_USER_RETURN_NOTIFIER
 	bool
 
+config USE_COMMON_STRUCT_CLK
+	bool
+
 config HAVE_PERF_EVENTS_NMI
 	bool
 	help
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 1d37f42..e09e40e 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -3,6 +3,7 @@
  *
  *  Copyright (C) 2004 ARM Limited.
  *  Written by Deep Blue Solutions Limited.
+ *  Copyright (c) 2010 Jeremy Kerr <jeremy.kerr@canonical.com>
  *
  * 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
@@ -11,18 +12,163 @@
 #ifndef __LINUX_CLK_H
 #define __LINUX_CLK_H
 
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+
 struct device;
 
-/*
- * The base API.
+#ifdef CONFIG_USE_COMMON_STRUCT_CLK
+
+#define CLK_ATOMIC	0x1
+
+/* If we're using the common struct clk, we define the base clk object here */
+
+/**
+ * struct clk - hardware independent clock structure
+ * @clk_ops:		implementation-specific ops for this clock
+ * @enable_count:	count of clk_enable() calls active on this clock
+ * @flags:		platform-independent flags
+ * @lock:		lock for enable/disable or other HW-specific ops
+ *
+ * The base clock object, used by drivers for hardware-independent manipulation
+ * of clock lines. This will be 'subclassed' by device-specific implementations,
+ * which add device-specific data to struct clk. For example:
+ *
+ *  struct clk_foo {
+ *      struct clk;
+ *      [device specific fields]
+ *  };
+ *
+ * The clock driver code will manage the device-specific data, and pass
+ * clk_foo.clk to the common clock code. The clock driver will be called
+ * through the @ops callbacks.
+ *
+ * The @lock member provides either a spinlock or a mutex to protect (at least)
+ * @enable_count. The type of lock used will depend on @flags; if CLK_ATOMIC is
+ * set, then the core clock code will use a spinlock, otherwise a mutex. This
+ * lock will be acquired during clk_enable and clk_disable, so for atomic
+ * clocks, these ops callbacks must not sleep.
+ *
+ * The choice of atomic or non-atomic clock depends on how the clock is enabled.
+ * Typically, you'll want to use a non-atomic clock. For clocks that need to be
+ * enabled/disabled in interrupt context, use CLK_ATOMIC. Note that atomic
+ * clocks with parents will typically cascade enable/disable operations to
+ * their parent, so the parent of an atomic clock *must* be atomic too.
+ */
+struct clk {
+	const struct clk_ops	*ops;
+	unsigned int		enable_count;
+	int			flags;
+	union {
+		struct mutex	mutex;
+		spinlock_t	spinlock;
+	} lock;
+};
+
+/* static initialiser for non-atomic clocks */
+#define INIT_CLK(name, o) {						\
+	.ops		= &o,						\
+	.enable_count	= 0,						\
+	.flags		= 0,						\
+	.lock.mutex	= __MUTEX_INITIALIZER(name.lock.mutex),		\
+}
+
+/* static initialiser for atomic clocks */
+#define INIT_CLK_ATOMIC(name, o) {					\
+	.ops		= &o,						\
+	.enable_count	= 0,						\
+	.flags		= CLK_ATOMIC,					\
+	.lock.spinlock	= __SPIN_LOCK_UNLOCKED(name.lock.spinlock),	\
+}
+
+/**
+ * clk_ops: Callback operations for clocks; these are to be provided by the
+ * clock implementation, and will be called by drivers through the clk_* API.
+ *
+ * @enable:	Enable the clock. This must not return until the clock is
+ *		generating a valid clock signal, usable by consumer devices.
+ *		Called with clk->lock held.
+ *
+ * @disable:	Disable the clock. Called with clk->lock held.
+ *
+ * @get	/ @put:	Called by the core clock code to notify the driver about
+ *		refounts as clk is passed to drivers. Optional.
+ *
+ * For other callbacks, see the corresponding clk_* functions. Parameters and
+ * return values are passed directly from/to these API functions directly, or
+ * -ENOSYS is returned if the callback is NULL, see kernel/clk.c for
+ * implementation details. All are optional.
  */
+struct clk_ops {
+       int		(*enable)(struct clk *);
+       void		(*disable)(struct clk *);
+       int		(*get)(struct clk *);
+       void		(*put)(struct clk *);
+       unsigned long	(*get_rate)(struct clk *);
+       long		(*round_rate)(struct clk *, unsigned long);
+       int		(*set_rate)(struct clk *, unsigned long);
+       int		(*set_parent)(struct clk *, struct clk *);
+       struct clk *	(*get_parent)(struct clk *);
+};
 
+static inline void __clk_lock(struct clk *clk)
+{
+	if (clk->flags & CLK_ATOMIC)
+		spin_lock(&clk->lock.spinlock);
+	else
+		mutex_lock(&clk->lock.mutex);
+}
+
+static inline void __clk_unlock(struct clk *clk)
+{
+	if (clk->flags & CLK_ATOMIC)
+		spin_unlock(&clk->lock.spinlock);
+	else
+		mutex_unlock(&clk->lock.mutex);
+}
+
+/**
+ * __clk_get - update clock-specific refcounter
+ *
+ * @clk: The clock to refcount
+ *
+ * Before a clock is returned from clk_get, this function should be called
+ * to update any clock-specific refcounting.
+ *
+ * Returns non-zero on success, zero on failure.
+ *
+ * Drivers should not need this function; it is only needed by the
+ * arch-specific clk_get() implementations.
+ */
+int __clk_get(struct clk *clk);
+
+/**
+ * clk_common_init - initialise a clock for driver usage
+ *
+ * Used for runtime intialization of clocks; you don't need to call this
+ * if your clock has been (statically) initialized with INIT_CLK.
+ */
+static inline void clk_common_init(struct clk *clk)
+{
+	clk->enable_count = 0;
+	if (clk->flags & CLK_ATOMIC)
+		spin_lock_init(&clk->lock.spinlock);
+	else
+		mutex_init(&clk->lock.mutex);
+}
+
+#else /* !CONFIG_USE_COMMON_STRUCT_CLK */
 
 /*
- * struct clk - an machine class defined object / cookie.
+ * Global clock object, actual structure is declared per-machine
  */
 struct clk;
 
+static inline void clk_common_init(struct clk *clk) { }
+
+#endif /* !CONFIG_USE_COMMON_STRUCT_CLK */
+
 /**
  * clk_get - lookup and obtain a reference to a clock producer.
  * @dev: device for clock "consumer"
@@ -83,12 +229,6 @@ unsigned long clk_get_rate(struct clk *clk);
  */
 void clk_put(struct clk *clk);
 
-
-/*
- * The remaining APIs are optional for machine class support.
- */
-
-
 /**
  * clk_round_rate - adjust a rate to the exact rate a clock can provide
  * @clk: clock source
diff --git a/kernel/Makefile b/kernel/Makefile
index 0b5ff08..01383a0 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -106,6 +106,7 @@ obj-$(CONFIG_PERF_EVENTS) += perf_event.o
 obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
 obj-$(CONFIG_USER_RETURN_NOTIFIER) += user-return-notifier.o
 obj-$(CONFIG_PADATA) += padata.o
+obj-$(CONFIG_USE_COMMON_STRUCT_CLK) += clk.o
 
 ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y)
 # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
diff --git a/kernel/clk.c b/kernel/clk.c
new file mode 100644
index 0000000..1545e69
--- /dev/null
+++ b/kernel/clk.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2010 Canonical Ltd <jeremy.kerr@canonical.com>
+ *
+ * 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/clk.h>
+#include <linux/module.h>
+
+int clk_enable(struct clk *clk)
+{
+	int ret = 0;
+
+	if (!clk->ops->enable)
+		return 0;
+
+	__clk_lock(clk);
+	if (!clk->enable_count)
+		ret = clk->ops->enable(clk);
+
+	if (!ret)
+		clk->enable_count++;
+	__clk_unlock(clk);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+	if (!clk->ops->disable)
+		return;
+
+	__clk_lock(clk);
+
+	if (!--clk->enable_count)
+		clk->ops->disable(clk);
+
+	__clk_unlock(clk);
+}
+EXPORT_SYMBOL_GPL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	if (clk->ops->get_rate)
+		return clk->ops->get_rate(clk);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(clk_get_rate);
+
+int __clk_get(struct clk *clk)
+{
+	if (clk->ops->get)
+		return clk->ops->get(clk);
+	return 1;
+}
+EXPORT_SYMBOL_GPL(__clk_get);
+
+void clk_put(struct clk *clk)
+{
+	if (clk->ops->put)
+		clk->ops->put(clk);
+}
+EXPORT_SYMBOL_GPL(clk_put);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	if (clk->ops->round_rate)
+		return clk->ops->round_rate(clk, rate);
+	return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	if (clk->ops->set_rate)
+		return clk->ops->set_rate(clk, rate);
+	return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(clk_set_rate);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	if (clk->ops->set_parent)
+		return clk->ops->set_parent(clk, parent);
+	return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(clk_set_parent);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+	if (clk->ops->get_parent)
+		return clk->ops->get_parent(clk);
+	return ERR_PTR(-ENOSYS);
+}
+EXPORT_SYMBOL_GPL(clk_get_parent);

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

* Re: [PATCH 1/2] Add a common struct clk
  2010-12-08  2:05 ` Jeremy Kerr
@ 2010-12-08 10:21   ` Uwe Kleine-König
  -1 siblings, 0 replies; 40+ messages in thread
From: Uwe Kleine-König @ 2010-12-08 10:21 UTC (permalink / raw)
  To: Jeremy Kerr; +Cc: linux-arm-kernel, linux-kernel

Hi Jeremy,

On Wed, Dec 08, 2010 at 10:05:32AM +0800, Jeremy Kerr wrote:
> We currently have ~21 definitions of struct clk in the ARM architecture,
> each defined on a per-platform basis. This makes it difficult to define
> platform- (or architecture-) independent clock sources without making
> assumptions about struct clk, and impossible to compile two
> platforms with different struct clks into a single image.
> 
> This change is an effort to unify struct clk where possible, by defining
> a common struct clk, containing a set of clock operations. Different
> clock implementations can set their own operations, and have a standard
> interface for generic code. The callback interface is exposed to the
> kernel proper, while the clock implementations only need to be seen by
> the platform internals.
> 
> This allows us to share clock code among platforms, and makes it
> possible to dynamically create clock devices in platform-independent
> code.
> 
> Platforms can enable the generic struct clock through
> CONFIG_USE_COMMON_STRUCT_CLK. In this case, the clock infrastructure
> consists of a common struct clk:
> 
> struct clk {
> 	const struct clk_ops	*ops;
> 	unsigned int		enable_count;
> 	int			flags;
> 	union {
> 		struct mutex	mutex;
> 		spinlock_t	spinlock;
> 	} lock;
> };
> 
> And a set of clock operations (defined per type of clock):
> 
> struct clk_ops {
> 	int             (*enable)(struct clk *);
> 	void            (*disable)(struct clk *);
> 	unsigned long   (*get_rate)(struct clk *);
> 	[...]
> };
> 
> To define a hardware-specific clock, machine code can "subclass" the
> struct clock into a new struct (adding any device-specific data), and
> provide a set of operations:
> 
> struct clk_foo {
> 	struct clk	clk;
> 	void __iomem	*some_register;
> };
> 
> struct clk_ops clk_foo_ops = {
> 	.get_rate = clk_foo_get_rate,
> };
> 
> The common clock definitions are based on a development patch from Ben
> Herrenschmidt <benh@kernel.crashing.org>.
> 
> Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
> Acked-by: Paulius Zaleckas <paulius.zaleckas@gmail.com>
> 
> ---
>  arch/Kconfig        |    3 
>  include/linux/clk.h |  158 +++++++++++++++++++++++++++++++++++++++++---
>  kernel/Makefile     |    1 
>  kernel/clk.c        |  100 +++++++++++++++++++++++++++
>  4 files changed, 253 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/Kconfig b/arch/Kconfig
> index 8bf0fa6..212bd3c 100644
> --- a/arch/Kconfig
> +++ b/arch/Kconfig
> @@ -165,6 +165,9 @@ config HAVE_MIXED_BREAKPOINTS_REGS
>  config HAVE_USER_RETURN_NOTIFIER
>  	bool
>  
> +config USE_COMMON_STRUCT_CLK
> +	bool
> +
>  config HAVE_PERF_EVENTS_NMI
>  	bool
>  	help
> diff --git a/include/linux/clk.h b/include/linux/clk.h
> index 1d37f42..e09e40e 100644
> --- a/include/linux/clk.h
> +++ b/include/linux/clk.h
> @@ -3,6 +3,7 @@
>   *
>   *  Copyright (C) 2004 ARM Limited.
>   *  Written by Deep Blue Solutions Limited.
> + *  Copyright (c) 2010 Jeremy Kerr <jeremy.kerr@canonical.com>
>   *
>   * 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
> @@ -11,18 +12,163 @@
>  #ifndef __LINUX_CLK_H
>  #define __LINUX_CLK_H
>  
> +#include <linux/err.h>
> +#include <linux/mutex.h>
> +#include <linux/spinlock.h>
> +
>  struct device;
>  
> -/*
> - * The base API.
> +#ifdef CONFIG_USE_COMMON_STRUCT_CLK
> +
> +#define CLK_ATOMIC	0x1
> +
> +/* If we're using the common struct clk, we define the base clk object here */
> +
> +/**
> + * struct clk - hardware independent clock structure
> + * @clk_ops:		implementation-specific ops for this clock
> + * @enable_count:	count of clk_enable() calls active on this clock
> + * @flags:		platform-independent flags
> + * @lock:		lock for enable/disable or other HW-specific ops
> + *
> + * The base clock object, used by drivers for hardware-independent manipulation
> + * of clock lines. This will be 'subclassed' by device-specific implementations,
> + * which add device-specific data to struct clk. For example:
> + *
> + *  struct clk_foo {
> + *      struct clk;
> + *      [device specific fields]
> + *  };
> + *
> + * The clock driver code will manage the device-specific data, and pass
> + * clk_foo.clk to the common clock code. The clock driver will be called
> + * through the @ops callbacks.
> + *
> + * The @lock member provides either a spinlock or a mutex to protect (at least)
> + * @enable_count. The type of lock used will depend on @flags; if CLK_ATOMIC is
> + * set, then the core clock code will use a spinlock, otherwise a mutex. This
> + * lock will be acquired during clk_enable and clk_disable, so for atomic
> + * clocks, these ops callbacks must not sleep.
> + *
> + * The choice of atomic or non-atomic clock depends on how the clock is enabled.
> + * Typically, you'll want to use a non-atomic clock. For clocks that need to be
> + * enabled/disabled in interrupt context, use CLK_ATOMIC. Note that atomic
> + * clocks with parents will typically cascade enable/disable operations to
> + * their parent, so the parent of an atomic clock *must* be atomic too.
> + */
> +struct clk {
> +	const struct clk_ops	*ops;
> +	unsigned int		enable_count;
> +	int			flags;
> +	union {
> +		struct mutex	mutex;
> +		spinlock_t	spinlock;
> +	} lock;
> +};
> +
> +/* static initialiser for non-atomic clocks */
> +#define INIT_CLK(name, o) {						\
> +	.ops		= &o,						\
> +	.enable_count	= 0,						\
> +	.flags		= 0,						\
> +	.lock.mutex	= __MUTEX_INITIALIZER(name.lock.mutex),		\
> +}
> +
> +/* static initialiser for atomic clocks */
> +#define INIT_CLK_ATOMIC(name, o) {					\
> +	.ops		= &o,						\
> +	.enable_count	= 0,						\
> +	.flags		= CLK_ATOMIC,					\
> +	.lock.spinlock	= __SPIN_LOCK_UNLOCKED(name.lock.spinlock),	\
> +}
> +
> +/**
> + * clk_ops: Callback operations for clocks; these are to be provided by the
> + * clock implementation, and will be called by drivers through the clk_* API.
> + *
> + * @enable:	Enable the clock. This must not return until the clock is
> + *		generating a valid clock signal, usable by consumer devices.
> + *		Called with clk->lock held.
> + *
> + * @disable:	Disable the clock. Called with clk->lock held.
> + *
> + * @get	/ @put:	Called by the core clock code to notify the driver about
I wonder if this is valid kerneldoc.  The tab before / looks (IMHO)
ugly.  Maybe specify "driver" a bit more to distinguish from "drivers"
above.  "clk_ops driver"?

> + *		refounts as clk is passed to drivers. Optional.
> + *
> + * For other callbacks, see the corresponding clk_* functions. Parameters and
> + * return values are passed directly from/to these API functions directly, or
duplicated "directly"
> + * -ENOSYS is returned if the callback is NULL, see kernel/clk.c for
> + * implementation details. All are optional.
>   */
> +struct clk_ops {
> +       int		(*enable)(struct clk *);
> +       void		(*disable)(struct clk *);
> +       int		(*get)(struct clk *);
> +       void		(*put)(struct clk *);
> +       unsigned long	(*get_rate)(struct clk *);
> +       long		(*round_rate)(struct clk *, unsigned long);
> +       int		(*set_rate)(struct clk *, unsigned long);
> +       int		(*set_parent)(struct clk *, struct clk *);
> +       struct clk *	(*get_parent)(struct clk *);
> +};
>  
> +static inline void __clk_lock(struct clk *clk)
> +{
> +	if (clk->flags & CLK_ATOMIC)
> +		spin_lock(&clk->lock.spinlock);
> +	else
> +		mutex_lock(&clk->lock.mutex);
> +}
> +
> +static inline void __clk_unlock(struct clk *clk)
> +{
> +	if (clk->flags & CLK_ATOMIC)
> +		spin_unlock(&clk->lock.spinlock);
> +	else
> +		mutex_unlock(&clk->lock.mutex);
> +}
> +
> +/**
> + * __clk_get - update clock-specific refcounter
> + *
> + * @clk: The clock to refcount
"The clock to update the refcount for"?

> + *
> + * Before a clock is returned from clk_get, this function should be called
> + * to update any clock-specific refcounting.
> + *
> + * Returns non-zero on success, zero on failure.
> + *
> + * Drivers should not need this function; it is only needed by the
> + * arch-specific clk_get() implementations.
> + */
> +int __clk_get(struct clk *clk);
> +
> +/**
> + * clk_common_init - initialise a clock for driver usage
> + *
> + * Used for runtime intialization of clocks; you don't need to call this
> + * if your clock has been (statically) initialized with INIT_CLK.
> + */
> +static inline void clk_common_init(struct clk *clk)
> +{
> +	clk->enable_count = 0;
> +	if (clk->flags & CLK_ATOMIC)
> +		spin_lock_init(&clk->lock.spinlock);
> +	else
> +		mutex_init(&clk->lock.mutex);
> +}
> +
> +#else /* !CONFIG_USE_COMMON_STRUCT_CLK */
>  
>  /*
> - * struct clk - an machine class defined object / cookie.
> + * Global clock object, actual structure is declared per-machine
>   */
>  struct clk;
>  
> +static inline void clk_common_init(struct clk *clk) { }
> +
> +#endif /* !CONFIG_USE_COMMON_STRUCT_CLK */
> +
>  /**
>   * clk_get - lookup and obtain a reference to a clock producer.
>   * @dev: device for clock "consumer"
> @@ -83,12 +229,6 @@ unsigned long clk_get_rate(struct clk *clk);
>   */
>  void clk_put(struct clk *clk);
>  
> -
> -/*
> - * The remaining APIs are optional for machine class support.
> - */
> -
> -
>  /**
>   * clk_round_rate - adjust a rate to the exact rate a clock can provide
>   * @clk: clock source
> diff --git a/kernel/Makefile b/kernel/Makefile
> index 0b5ff08..01383a0 100644
> --- a/kernel/Makefile
> +++ b/kernel/Makefile
> @@ -106,6 +106,7 @@ obj-$(CONFIG_PERF_EVENTS) += perf_event.o
>  obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
>  obj-$(CONFIG_USER_RETURN_NOTIFIER) += user-return-notifier.o
>  obj-$(CONFIG_PADATA) += padata.o
> +obj-$(CONFIG_USE_COMMON_STRUCT_CLK) += clk.o
>  
>  ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y)
>  # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
> diff --git a/kernel/clk.c b/kernel/clk.c
> new file mode 100644
> index 0000000..1545e69
> --- /dev/null
> +++ b/kernel/clk.c
> @@ -0,0 +1,100 @@
> +/*
> + * Copyright (C) 2010 Canonical Ltd <jeremy.kerr@canonical.com>
> + *
> + * 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/clk.h>
> +#include <linux/module.h>
> +
> +int clk_enable(struct clk *clk)
> +{
> +	int ret = 0;
> +
> +	if (!clk->ops->enable)
> +		return 0;
> +
> +	__clk_lock(clk);
> +	if (!clk->enable_count)
> +		ret = clk->ops->enable(clk);
I wonder if it's worth to handle parents here, e.g.

	if (!clk->enable_count) {
		struct clk *parent = clk_get_parent(clk);
		if (parent) {
			ret = clk_enable(parent);
			if (ret)
				return ret;
		}

		ret = clk->ops->enable(clk);
		if (likely(!ret))
			clk->enable_count++;
		else if (parent)
			clk_disable(parent);
	}

as they are quite common.

And I wonder further if it makes the code a bit more efficient to use:

	if (!clk->enable_count++) {
		... enable clock (and maybe parent)
		if (unlikely(ret))
			clk->enable_count--
		...


> +
> +	if (!ret)
> +		clk->enable_count++;
> +	__clk_unlock(clk);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(clk_enable);
> +
> +void clk_disable(struct clk *clk)
> +{
> +	if (!clk->ops->disable)
> +		return;

	WARN_ON(!clk->enable_count) ?
> +
> +	__clk_lock(clk);
> +
> +	if (!--clk->enable_count)
> +		clk->ops->disable(clk);
> +
> +	__clk_unlock(clk);
> +}
> +EXPORT_SYMBOL_GPL(clk_disable);
> +
> +unsigned long clk_get_rate(struct clk *clk)
> +{
> +	if (clk->ops->get_rate)
> +		return clk->ops->get_rate(clk);
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(clk_get_rate);
> +
> +int __clk_get(struct clk *clk)
> +{
> +	if (clk->ops->get)
> +		return clk->ops->get(clk);
> +	return 1;
> +}
> +EXPORT_SYMBOL_GPL(__clk_get);
> +
> +void clk_put(struct clk *clk)
> +{
> +	if (clk->ops->put)
> +		clk->ops->put(clk);
> +}
> +EXPORT_SYMBOL_GPL(clk_put);
> +
> +long clk_round_rate(struct clk *clk, unsigned long rate)
> +{
> +	if (clk->ops->round_rate)
> +		return clk->ops->round_rate(clk, rate);
> +	return -ENOSYS;
> +}
> +EXPORT_SYMBOL_GPL(clk_round_rate);
> +
> +int clk_set_rate(struct clk *clk, unsigned long rate)
> +{
> +	if (clk->ops->set_rate)
> +		return clk->ops->set_rate(clk, rate);
> +	return -ENOSYS;
> +}
> +EXPORT_SYMBOL_GPL(clk_set_rate);
> +
> +int clk_set_parent(struct clk *clk, struct clk *parent)
> +{
> +	if (clk->ops->set_parent)
> +		return clk->ops->set_parent(clk, parent);
> +	return -ENOSYS;
> +}
> +EXPORT_SYMBOL_GPL(clk_set_parent);
> +
> +struct clk *clk_get_parent(struct clk *clk)
> +{
> +	if (clk->ops->get_parent)
> +		return clk->ops->get_parent(clk);
> +	return ERR_PTR(-ENOSYS);
> +}
> +EXPORT_SYMBOL_GPL(clk_get_parent);
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH 1/2] Add a common struct clk
@ 2010-12-08 10:21   ` Uwe Kleine-König
  0 siblings, 0 replies; 40+ messages in thread
From: Uwe Kleine-König @ 2010-12-08 10:21 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Jeremy,

On Wed, Dec 08, 2010 at 10:05:32AM +0800, Jeremy Kerr wrote:
> We currently have ~21 definitions of struct clk in the ARM architecture,
> each defined on a per-platform basis. This makes it difficult to define
> platform- (or architecture-) independent clock sources without making
> assumptions about struct clk, and impossible to compile two
> platforms with different struct clks into a single image.
> 
> This change is an effort to unify struct clk where possible, by defining
> a common struct clk, containing a set of clock operations. Different
> clock implementations can set their own operations, and have a standard
> interface for generic code. The callback interface is exposed to the
> kernel proper, while the clock implementations only need to be seen by
> the platform internals.
> 
> This allows us to share clock code among platforms, and makes it
> possible to dynamically create clock devices in platform-independent
> code.
> 
> Platforms can enable the generic struct clock through
> CONFIG_USE_COMMON_STRUCT_CLK. In this case, the clock infrastructure
> consists of a common struct clk:
> 
> struct clk {
> 	const struct clk_ops	*ops;
> 	unsigned int		enable_count;
> 	int			flags;
> 	union {
> 		struct mutex	mutex;
> 		spinlock_t	spinlock;
> 	} lock;
> };
> 
> And a set of clock operations (defined per type of clock):
> 
> struct clk_ops {
> 	int             (*enable)(struct clk *);
> 	void            (*disable)(struct clk *);
> 	unsigned long   (*get_rate)(struct clk *);
> 	[...]
> };
> 
> To define a hardware-specific clock, machine code can "subclass" the
> struct clock into a new struct (adding any device-specific data), and
> provide a set of operations:
> 
> struct clk_foo {
> 	struct clk	clk;
> 	void __iomem	*some_register;
> };
> 
> struct clk_ops clk_foo_ops = {
> 	.get_rate = clk_foo_get_rate,
> };
> 
> The common clock definitions are based on a development patch from Ben
> Herrenschmidt <benh@kernel.crashing.org>.
> 
> Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
> Acked-by: Paulius Zaleckas <paulius.zaleckas@gmail.com>
> 
> ---
>  arch/Kconfig        |    3 
>  include/linux/clk.h |  158 +++++++++++++++++++++++++++++++++++++++++---
>  kernel/Makefile     |    1 
>  kernel/clk.c        |  100 +++++++++++++++++++++++++++
>  4 files changed, 253 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/Kconfig b/arch/Kconfig
> index 8bf0fa6..212bd3c 100644
> --- a/arch/Kconfig
> +++ b/arch/Kconfig
> @@ -165,6 +165,9 @@ config HAVE_MIXED_BREAKPOINTS_REGS
>  config HAVE_USER_RETURN_NOTIFIER
>  	bool
>  
> +config USE_COMMON_STRUCT_CLK
> +	bool
> +
>  config HAVE_PERF_EVENTS_NMI
>  	bool
>  	help
> diff --git a/include/linux/clk.h b/include/linux/clk.h
> index 1d37f42..e09e40e 100644
> --- a/include/linux/clk.h
> +++ b/include/linux/clk.h
> @@ -3,6 +3,7 @@
>   *
>   *  Copyright (C) 2004 ARM Limited.
>   *  Written by Deep Blue Solutions Limited.
> + *  Copyright (c) 2010 Jeremy Kerr <jeremy.kerr@canonical.com>
>   *
>   * 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
> @@ -11,18 +12,163 @@
>  #ifndef __LINUX_CLK_H
>  #define __LINUX_CLK_H
>  
> +#include <linux/err.h>
> +#include <linux/mutex.h>
> +#include <linux/spinlock.h>
> +
>  struct device;
>  
> -/*
> - * The base API.
> +#ifdef CONFIG_USE_COMMON_STRUCT_CLK
> +
> +#define CLK_ATOMIC	0x1
> +
> +/* If we're using the common struct clk, we define the base clk object here */
> +
> +/**
> + * struct clk - hardware independent clock structure
> + * @clk_ops:		implementation-specific ops for this clock
> + * @enable_count:	count of clk_enable() calls active on this clock
> + * @flags:		platform-independent flags
> + * @lock:		lock for enable/disable or other HW-specific ops
> + *
> + * The base clock object, used by drivers for hardware-independent manipulation
> + * of clock lines. This will be 'subclassed' by device-specific implementations,
> + * which add device-specific data to struct clk. For example:
> + *
> + *  struct clk_foo {
> + *      struct clk;
> + *      [device specific fields]
> + *  };
> + *
> + * The clock driver code will manage the device-specific data, and pass
> + * clk_foo.clk to the common clock code. The clock driver will be called
> + * through the @ops callbacks.
> + *
> + * The @lock member provides either a spinlock or a mutex to protect (at least)
> + * @enable_count. The type of lock used will depend on @flags; if CLK_ATOMIC is
> + * set, then the core clock code will use a spinlock, otherwise a mutex. This
> + * lock will be acquired during clk_enable and clk_disable, so for atomic
> + * clocks, these ops callbacks must not sleep.
> + *
> + * The choice of atomic or non-atomic clock depends on how the clock is enabled.
> + * Typically, you'll want to use a non-atomic clock. For clocks that need to be
> + * enabled/disabled in interrupt context, use CLK_ATOMIC. Note that atomic
> + * clocks with parents will typically cascade enable/disable operations to
> + * their parent, so the parent of an atomic clock *must* be atomic too.
> + */
> +struct clk {
> +	const struct clk_ops	*ops;
> +	unsigned int		enable_count;
> +	int			flags;
> +	union {
> +		struct mutex	mutex;
> +		spinlock_t	spinlock;
> +	} lock;
> +};
> +
> +/* static initialiser for non-atomic clocks */
> +#define INIT_CLK(name, o) {						\
> +	.ops		= &o,						\
> +	.enable_count	= 0,						\
> +	.flags		= 0,						\
> +	.lock.mutex	= __MUTEX_INITIALIZER(name.lock.mutex),		\
> +}
> +
> +/* static initialiser for atomic clocks */
> +#define INIT_CLK_ATOMIC(name, o) {					\
> +	.ops		= &o,						\
> +	.enable_count	= 0,						\
> +	.flags		= CLK_ATOMIC,					\
> +	.lock.spinlock	= __SPIN_LOCK_UNLOCKED(name.lock.spinlock),	\
> +}
> +
> +/**
> + * clk_ops: Callback operations for clocks; these are to be provided by the
> + * clock implementation, and will be called by drivers through the clk_* API.
> + *
> + * @enable:	Enable the clock. This must not return until the clock is
> + *		generating a valid clock signal, usable by consumer devices.
> + *		Called with clk->lock held.
> + *
> + * @disable:	Disable the clock. Called with clk->lock held.
> + *
> + * @get	/ @put:	Called by the core clock code to notify the driver about
I wonder if this is valid kerneldoc.  The tab before / looks (IMHO)
ugly.  Maybe specify "driver" a bit more to distinguish from "drivers"
above.  "clk_ops driver"?

> + *		refounts as clk is passed to drivers. Optional.
> + *
> + * For other callbacks, see the corresponding clk_* functions. Parameters and
> + * return values are passed directly from/to these API functions directly, or
duplicated "directly"
> + * -ENOSYS is returned if the callback is NULL, see kernel/clk.c for
> + * implementation details. All are optional.
>   */
> +struct clk_ops {
> +       int		(*enable)(struct clk *);
> +       void		(*disable)(struct clk *);
> +       int		(*get)(struct clk *);
> +       void		(*put)(struct clk *);
> +       unsigned long	(*get_rate)(struct clk *);
> +       long		(*round_rate)(struct clk *, unsigned long);
> +       int		(*set_rate)(struct clk *, unsigned long);
> +       int		(*set_parent)(struct clk *, struct clk *);
> +       struct clk *	(*get_parent)(struct clk *);
> +};
>  
> +static inline void __clk_lock(struct clk *clk)
> +{
> +	if (clk->flags & CLK_ATOMIC)
> +		spin_lock(&clk->lock.spinlock);
> +	else
> +		mutex_lock(&clk->lock.mutex);
> +}
> +
> +static inline void __clk_unlock(struct clk *clk)
> +{
> +	if (clk->flags & CLK_ATOMIC)
> +		spin_unlock(&clk->lock.spinlock);
> +	else
> +		mutex_unlock(&clk->lock.mutex);
> +}
> +
> +/**
> + * __clk_get - update clock-specific refcounter
> + *
> + * @clk: The clock to refcount
"The clock to update the refcount for"?

> + *
> + * Before a clock is returned from clk_get, this function should be called
> + * to update any clock-specific refcounting.
> + *
> + * Returns non-zero on success, zero on failure.
> + *
> + * Drivers should not need this function; it is only needed by the
> + * arch-specific clk_get() implementations.
> + */
> +int __clk_get(struct clk *clk);
> +
> +/**
> + * clk_common_init - initialise a clock for driver usage
> + *
> + * Used for runtime intialization of clocks; you don't need to call this
> + * if your clock has been (statically) initialized with INIT_CLK.
> + */
> +static inline void clk_common_init(struct clk *clk)
> +{
> +	clk->enable_count = 0;
> +	if (clk->flags & CLK_ATOMIC)
> +		spin_lock_init(&clk->lock.spinlock);
> +	else
> +		mutex_init(&clk->lock.mutex);
> +}
> +
> +#else /* !CONFIG_USE_COMMON_STRUCT_CLK */
>  
>  /*
> - * struct clk - an machine class defined object / cookie.
> + * Global clock object, actual structure is declared per-machine
>   */
>  struct clk;
>  
> +static inline void clk_common_init(struct clk *clk) { }
> +
> +#endif /* !CONFIG_USE_COMMON_STRUCT_CLK */
> +
>  /**
>   * clk_get - lookup and obtain a reference to a clock producer.
>   * @dev: device for clock "consumer"
> @@ -83,12 +229,6 @@ unsigned long clk_get_rate(struct clk *clk);
>   */
>  void clk_put(struct clk *clk);
>  
> -
> -/*
> - * The remaining APIs are optional for machine class support.
> - */
> -
> -
>  /**
>   * clk_round_rate - adjust a rate to the exact rate a clock can provide
>   * @clk: clock source
> diff --git a/kernel/Makefile b/kernel/Makefile
> index 0b5ff08..01383a0 100644
> --- a/kernel/Makefile
> +++ b/kernel/Makefile
> @@ -106,6 +106,7 @@ obj-$(CONFIG_PERF_EVENTS) += perf_event.o
>  obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
>  obj-$(CONFIG_USER_RETURN_NOTIFIER) += user-return-notifier.o
>  obj-$(CONFIG_PADATA) += padata.o
> +obj-$(CONFIG_USE_COMMON_STRUCT_CLK) += clk.o
>  
>  ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y)
>  # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
> diff --git a/kernel/clk.c b/kernel/clk.c
> new file mode 100644
> index 0000000..1545e69
> --- /dev/null
> +++ b/kernel/clk.c
> @@ -0,0 +1,100 @@
> +/*
> + * Copyright (C) 2010 Canonical Ltd <jeremy.kerr@canonical.com>
> + *
> + * 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/clk.h>
> +#include <linux/module.h>
> +
> +int clk_enable(struct clk *clk)
> +{
> +	int ret = 0;
> +
> +	if (!clk->ops->enable)
> +		return 0;
> +
> +	__clk_lock(clk);
> +	if (!clk->enable_count)
> +		ret = clk->ops->enable(clk);
I wonder if it's worth to handle parents here, e.g.

	if (!clk->enable_count) {
		struct clk *parent = clk_get_parent(clk);
		if (parent) {
			ret = clk_enable(parent);
			if (ret)
				return ret;
		}

		ret = clk->ops->enable(clk);
		if (likely(!ret))
			clk->enable_count++;
		else if (parent)
			clk_disable(parent);
	}

as they are quite common.

And I wonder further if it makes the code a bit more efficient to use:

	if (!clk->enable_count++) {
		... enable clock (and maybe parent)
		if (unlikely(ret))
			clk->enable_count--
		...


> +
> +	if (!ret)
> +		clk->enable_count++;
> +	__clk_unlock(clk);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(clk_enable);
> +
> +void clk_disable(struct clk *clk)
> +{
> +	if (!clk->ops->disable)
> +		return;

	WARN_ON(!clk->enable_count) ?
> +
> +	__clk_lock(clk);
> +
> +	if (!--clk->enable_count)
> +		clk->ops->disable(clk);
> +
> +	__clk_unlock(clk);
> +}
> +EXPORT_SYMBOL_GPL(clk_disable);
> +
> +unsigned long clk_get_rate(struct clk *clk)
> +{
> +	if (clk->ops->get_rate)
> +		return clk->ops->get_rate(clk);
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(clk_get_rate);
> +
> +int __clk_get(struct clk *clk)
> +{
> +	if (clk->ops->get)
> +		return clk->ops->get(clk);
> +	return 1;
> +}
> +EXPORT_SYMBOL_GPL(__clk_get);
> +
> +void clk_put(struct clk *clk)
> +{
> +	if (clk->ops->put)
> +		clk->ops->put(clk);
> +}
> +EXPORT_SYMBOL_GPL(clk_put);
> +
> +long clk_round_rate(struct clk *clk, unsigned long rate)
> +{
> +	if (clk->ops->round_rate)
> +		return clk->ops->round_rate(clk, rate);
> +	return -ENOSYS;
> +}
> +EXPORT_SYMBOL_GPL(clk_round_rate);
> +
> +int clk_set_rate(struct clk *clk, unsigned long rate)
> +{
> +	if (clk->ops->set_rate)
> +		return clk->ops->set_rate(clk, rate);
> +	return -ENOSYS;
> +}
> +EXPORT_SYMBOL_GPL(clk_set_rate);
> +
> +int clk_set_parent(struct clk *clk, struct clk *parent)
> +{
> +	if (clk->ops->set_parent)
> +		return clk->ops->set_parent(clk, parent);
> +	return -ENOSYS;
> +}
> +EXPORT_SYMBOL_GPL(clk_set_parent);
> +
> +struct clk *clk_get_parent(struct clk *clk)
> +{
> +	if (clk->ops->get_parent)
> +		return clk->ops->get_parent(clk);
> +	return ERR_PTR(-ENOSYS);
> +}
> +EXPORT_SYMBOL_GPL(clk_get_parent);
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* Re: [PATCH 1/2] Add a common struct clk
  2010-12-08 10:21   ` Uwe Kleine-König
@ 2010-12-10  1:58     ` Jeremy Kerr
  -1 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2010-12-10  1:58 UTC (permalink / raw)
  To: Uwe Kleine-König; +Cc: linux-arm-kernel, linux-kernel

Hi Uwe

> > +/**
> > + * clk_ops: Callback operations for clocks; these are to be provided by
> > the + * clock implementation, and will be called by drivers through the
> > clk_* API. + *
> > + * @enable:	Enable the clock. This must not return until the clock is
> > + *		generating a valid clock signal, usable by consumer devices.
> > + *		Called with clk->lock held.
> > + *
> > + * @disable:	Disable the clock. Called with clk->lock held.
> > + *
> > + * @get	/ @put:	Called by the core clock code to notify the driver 
about
> 
> I wonder if this is valid kerneldoc.  The tab before / looks (IMHO)
> ugly.

Not valid kernel doc, so I'll fix that up. The tab was unintentional.

> Maybe specify "driver" a bit more to distinguish from "drivers"
> above.  "clk_ops driver"?

This is actually for refcounting for uses by device drivers (ie, not the clock 
provider), I've updated the comment:

/**
 * struct clk_ops -  Callback operations for clocks; these are to be provided
 * by the clock implementation, and will be called by drivers through the
 * clk_* API.
 *
 * @enable:	Enable the clock. This must not return until the clock is
 *		generating a valid clock signal, usable by consumer devices.
 *		Called with clk->lock held.
 *
 * @disable:	Disable the clock. Called with clk->lock held.
 *
 * @get:	     Called by the core clock code to increment the clock's
 *		     refount as clk is passed to device drivers. Optional.
 *
 * @put:	     Called by the core clock code to decrement the clocks's
 *		     refounts as clk is released from device drivers. Optional.
 *
 * For other callbacks, see the corresponding clk_* functions. Parameters and
 * return values are passed directly from/to these API functions, or
 * -ENOSYS is returned if the callback is NULL, see kernel/clk.c for
 * implementation details. All are optional.
 */

> > +/**
> > + * __clk_get - update clock-specific refcounter
> > + *
> > + * @clk: The clock to refcount
> 
> "The clock to update the refcount for"?

I'm using refcount as a verb here; if this isn't clear I can come up with 
something else. Your solution splits the 'clock' and the 'for' which may be 
difficult to parse too. Let me know if you have any other suggestions :)

> I wonder if it's worth to handle parents here, e.g.
> 
> 	if (!clk->enable_count) {
> 		struct clk *parent = clk_get_parent(clk);
> 		if (parent) {
> 			ret = clk_enable(parent);
> 			if (ret)
> 				return ret;
> 		}
> 
> 		ret = clk->ops->enable(clk);
> 		if (likely(!ret))
> 			clk->enable_count++;
> 		else if (parent)
> 			clk_disable(parent);
> 	}
> 
> as they are quite common.

I'm not convinced we should do the parent handling in the core clock code. 
It's fairly easy to do the parent enable/disable in platform code, which 
should have explicit knowledge about whether or not the clock has a parent, 
and the semantics of how the parent/child clocks interact.

However, happy to discuss this further if needs be.

> > +void clk_disable(struct clk *clk)
> > +{
> > +	if (!clk->ops->disable)
> > +		return;
> 
> 	WARN_ON(!clk->enable_count) ?

Yep, good idea. I'll do this check with the lock acquired.

Thanks for the comments, I've updated my tree accordingly (along with some 
other kerneldoc fixups). I'll wait to see if there is any other feedback and 
re-post next week.

Cheers,


Jeremy

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

* [PATCH 1/2] Add a common struct clk
@ 2010-12-10  1:58     ` Jeremy Kerr
  0 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2010-12-10  1:58 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe

> > +/**
> > + * clk_ops: Callback operations for clocks; these are to be provided by
> > the + * clock implementation, and will be called by drivers through the
> > clk_* API. + *
> > + * @enable:	Enable the clock. This must not return until the clock is
> > + *		generating a valid clock signal, usable by consumer devices.
> > + *		Called with clk->lock held.
> > + *
> > + * @disable:	Disable the clock. Called with clk->lock held.
> > + *
> > + * @get	/ @put:	Called by the core clock code to notify the driver 
about
> 
> I wonder if this is valid kerneldoc.  The tab before / looks (IMHO)
> ugly.

Not valid kernel doc, so I'll fix that up. The tab was unintentional.

> Maybe specify "driver" a bit more to distinguish from "drivers"
> above.  "clk_ops driver"?

This is actually for refcounting for uses by device drivers (ie, not the clock 
provider), I've updated the comment:

/**
 * struct clk_ops -  Callback operations for clocks; these are to be provided
 * by the clock implementation, and will be called by drivers through the
 * clk_* API.
 *
 * @enable:	Enable the clock. This must not return until the clock is
 *		generating a valid clock signal, usable by consumer devices.
 *		Called with clk->lock held.
 *
 * @disable:	Disable the clock. Called with clk->lock held.
 *
 * @get:	     Called by the core clock code to increment the clock's
 *		     refount as clk is passed to device drivers. Optional.
 *
 * @put:	     Called by the core clock code to decrement the clocks's
 *		     refounts as clk is released from device drivers. Optional.
 *
 * For other callbacks, see the corresponding clk_* functions. Parameters and
 * return values are passed directly from/to these API functions, or
 * -ENOSYS is returned if the callback is NULL, see kernel/clk.c for
 * implementation details. All are optional.
 */

> > +/**
> > + * __clk_get - update clock-specific refcounter
> > + *
> > + * @clk: The clock to refcount
> 
> "The clock to update the refcount for"?

I'm using refcount as a verb here; if this isn't clear I can come up with 
something else. Your solution splits the 'clock' and the 'for' which may be 
difficult to parse too. Let me know if you have any other suggestions :)

> I wonder if it's worth to handle parents here, e.g.
> 
> 	if (!clk->enable_count) {
> 		struct clk *parent = clk_get_parent(clk);
> 		if (parent) {
> 			ret = clk_enable(parent);
> 			if (ret)
> 				return ret;
> 		}
> 
> 		ret = clk->ops->enable(clk);
> 		if (likely(!ret))
> 			clk->enable_count++;
> 		else if (parent)
> 			clk_disable(parent);
> 	}
> 
> as they are quite common.

I'm not convinced we should do the parent handling in the core clock code. 
It's fairly easy to do the parent enable/disable in platform code, which 
should have explicit knowledge about whether or not the clock has a parent, 
and the semantics of how the parent/child clocks interact.

However, happy to discuss this further if needs be.

> > +void clk_disable(struct clk *clk)
> > +{
> > +	if (!clk->ops->disable)
> > +		return;
> 
> 	WARN_ON(!clk->enable_count) ?

Yep, good idea. I'll do this check with the lock acquired.

Thanks for the comments, I've updated my tree accordingly (along with some 
other kerneldoc fixups). I'll wait to see if there is any other feedback and 
re-post next week.

Cheers,


Jeremy

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

* [PATCH 1/2] Add a common struct clk
  2010-12-10  1:58     ` Jeremy Kerr
  (?)
@ 2010-12-10  9:21     ` Uwe Kleine-König
  -1 siblings, 0 replies; 40+ messages in thread
From: Uwe Kleine-König @ 2010-12-10  9:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Dec 10, 2010 at 09:58:31AM +0800, Jeremy Kerr wrote:
> Hi Uwe
> 
> > > +/**
> > > + * clk_ops: Callback operations for clocks; these are to be provided by
> > > the + * clock implementation, and will be called by drivers through the
> > > clk_* API. + *
> > > + * @enable:	Enable the clock. This must not return until the clock is
> > > + *		generating a valid clock signal, usable by consumer devices.
> > > + *		Called with clk->lock held.
> > > + *
> > > + * @disable:	Disable the clock. Called with clk->lock held.
> > > + *
> > > + * @get	/ @put:	Called by the core clock code to notify the driver 
> about
> > 
> > I wonder if this is valid kerneldoc.  The tab before / looks (IMHO)
> > ugly.
> 
> Not valid kernel doc, so I'll fix that up. The tab was unintentional.
> 
> > Maybe specify "driver" a bit more to distinguish from "drivers"
> > above.  "clk_ops driver"?
> 
> This is actually for refcounting for uses by device drivers (ie, not the clock 
> provider), I've updated the comment:
> 
> /**
>  * struct clk_ops -  Callback operations for clocks; these are to be provided
>  * by the clock implementation, and will be called by drivers through the
>  * clk_* API.
>  *
>  * @enable:	Enable the clock. This must not return until the clock is
>  *		generating a valid clock signal, usable by consumer devices.
>  *		Called with clk->lock held.
>  *
>  * @disable:	Disable the clock. Called with clk->lock held.
>  *
>  * @get:	     Called by the core clock code to increment the clock's
>  *		     refount as clk is passed to device drivers. Optional.
s/refount/refcount/ (once more below)
>  *
>  * @put:	     Called by the core clock code to decrement the clocks's
>  *		     refounts as clk is released from device drivers. Optional.
again inconsistent tabbing.

IMHO the wording above is better.  This makes me unsure if the callback
has to fiddle with the refcount.

>  *
>  * For other callbacks, see the corresponding clk_* functions. Parameters and
>  * return values are passed directly from/to these API functions, or
>  * -ENOSYS is returned if the callback is NULL, see kernel/clk.c for
This is not true for clk_get_rate.  This returns 0 if the callback isn't
set.

>  * implementation details. All are optional.
>  */
> 
> > > +/**
> > > + * __clk_get - update clock-specific refcounter
> > > + *
> > > + * @clk: The clock to refcount
> > 
> > "The clock to update the refcount for"?
> 
> I'm using refcount as a verb here; if this isn't clear I can come up with 
> something else. Your solution splits the 'clock' and the 'for' which may be 
> difficult to parse too. Let me know if you have any other suggestions :)
hmm, don't know.  Keeping it as is is OK for me, too, if you don't
consider my suggestion to be better.
 
> > I wonder if it's worth to handle parents here, e.g.
> > 
> > 	if (!clk->enable_count) {
> > 		struct clk *parent = clk_get_parent(clk);
> > 		if (parent) {
> > 			ret = clk_enable(parent);
> > 			if (ret)
> > 				return ret;
> > 		}
> > 
> > 		ret = clk->ops->enable(clk);
> > 		if (likely(!ret))
> > 			clk->enable_count++;
> > 		else if (parent)
> > 			clk_disable(parent);
> > 	}
> > 
> > as they are quite common.
> 
> I'm not convinced we should do the parent handling in the core clock code. 
> It's fairly easy to do the parent enable/disable in platform code, which 
> should have explicit knowledge about whether or not the clock has a parent, 
> and the semantics of how the parent/child clocks interact.
> 
> However, happy to discuss this further if needs be.
As already said in #armlinux, in the meantime I agree.

> > > +void clk_disable(struct clk *clk)
> > > +{
> > > +	if (!clk->ops->disable)
> > > +		return;
> > 
> > 	WARN_ON(!clk->enable_count) ?
> 
> Yep, good idea. I'll do this check with the lock acquired.
fine.

> Thanks for the comments, I've updated my tree accordingly (along with some 
> other kerneldoc fixups). I'll wait to see if there is any other feedback and 
> re-post next week.
fine, too.

Thanks for your efforts
Uwe

PS: I don't know who looks at your git tree, but you might want to
update the arch branches to base on your current work.

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH 2/2] clk: Generic support for fixed-rate clocks
  2011-03-03  6:40     ` [PATCH 0/2] Common struct clk implementation, v14 Jeremy Kerr
  2011-03-03  6:40         ` Jeremy Kerr
@ 2011-03-03  6:40         ` Jeremy Kerr
  0 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2011-03-03  6:40 UTC (permalink / raw)
  To: linux-arm-kernel

Since most platforms will need a fixed-rate clock, add one. This will
also serve as a basic example of an implementation of struct clk.

Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>

---
 drivers/clk/clk.c   |   14 ++++++++++++++
 include/linux/clk.h |   16 ++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 0bc9c6f..0da0bb9 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -130,3 +130,17 @@ void __clk_put(struct clk *clk)
 	if (clk->ops->put)
 		clk->ops->put(clk);
 }
+
+/* clk_fixed support */
+
+#define to_clk_fixed(clk) (container_of(clk, struct clk_fixed, clk))
+
+static unsigned long clk_fixed_get_rate(struct clk *clk)
+{
+	return to_clk_fixed(clk)->rate;
+}
+
+struct clk_ops clk_fixed_ops = {
+	.get_rate = clk_fixed_get_rate,
+};
+EXPORT_SYMBOL_GPL(clk_fixed_ops);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 7b406bd..d2f0db0 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -155,6 +155,22 @@ static inline void clk_common_init(struct clk *clk)
 	mutex_init(&clk->prepare_lock);
 }
 
+/* Simple fixed-rate clock */
+struct clk_fixed {
+	struct clk	clk;
+	unsigned long	rate;
+};
+
+extern struct clk_ops clk_fixed_ops;
+
+#define INIT_CLK_FIXED(name, r) { \
+	.clk = INIT_CLK(name.clk, clk_fixed_ops), \
+	.rate = (r) \
+}
+
+#define DEFINE_CLK_FIXED(name, r) \
+	struct clk_fixed name = INIT_CLK_FIXED(name, r)
+
 #else /* !CONFIG_USE_COMMON_STRUCT_CLK */
 
 /*

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

* [PATCH 2/2] clk: Generic support for fixed-rate clocks
@ 2011-03-03  6:40         ` Jeremy Kerr
  0 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2011-03-03  6:40 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel
  Cc: Nicolas Pitre, Dima Zavin, Lorenzo Pieralisi, Vincent Guittot,
	linux-sh, Ben Herrenschmidt, Uwe Kleine-König, Sascha Hauer,
	Paul Mundt, Saravana Kannan, Ben Dooks, Jeremy Kerr,
	Russell King

Since most platforms will need a fixed-rate clock, add one. This will
also serve as a basic example of an implementation of struct clk.

Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>

---
 drivers/clk/clk.c   |   14 ++++++++++++++
 include/linux/clk.h |   16 ++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 0bc9c6f..0da0bb9 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -130,3 +130,17 @@ void __clk_put(struct clk *clk)
 	if (clk->ops->put)
 		clk->ops->put(clk);
 }
+
+/* clk_fixed support */
+
+#define to_clk_fixed(clk) (container_of(clk, struct clk_fixed, clk))
+
+static unsigned long clk_fixed_get_rate(struct clk *clk)
+{
+	return to_clk_fixed(clk)->rate;
+}
+
+struct clk_ops clk_fixed_ops = {
+	.get_rate = clk_fixed_get_rate,
+};
+EXPORT_SYMBOL_GPL(clk_fixed_ops);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 7b406bd..d2f0db0 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -155,6 +155,22 @@ static inline void clk_common_init(struct clk *clk)
 	mutex_init(&clk->prepare_lock);
 }
 
+/* Simple fixed-rate clock */
+struct clk_fixed {
+	struct clk	clk;
+	unsigned long	rate;
+};
+
+extern struct clk_ops clk_fixed_ops;
+
+#define INIT_CLK_FIXED(name, r) { \
+	.clk = INIT_CLK(name.clk, clk_fixed_ops), \
+	.rate = (r) \
+}
+
+#define DEFINE_CLK_FIXED(name, r) \
+	struct clk_fixed name = INIT_CLK_FIXED(name, r)
+
 #else /* !CONFIG_USE_COMMON_STRUCT_CLK */
 
 /*

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

* [PATCH 2/2] clk: Generic support for fixed-rate clocks
@ 2011-03-03  6:40         ` Jeremy Kerr
  0 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2011-03-03  6:40 UTC (permalink / raw)
  To: linux-arm-kernel

Since most platforms will need a fixed-rate clock, add one. This will
also serve as a basic example of an implementation of struct clk.

Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>

---
 drivers/clk/clk.c   |   14 ++++++++++++++
 include/linux/clk.h |   16 ++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 0bc9c6f..0da0bb9 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -130,3 +130,17 @@ void __clk_put(struct clk *clk)
 	if (clk->ops->put)
 		clk->ops->put(clk);
 }
+
+/* clk_fixed support */
+
+#define to_clk_fixed(clk) (container_of(clk, struct clk_fixed, clk))
+
+static unsigned long clk_fixed_get_rate(struct clk *clk)
+{
+	return to_clk_fixed(clk)->rate;
+}
+
+struct clk_ops clk_fixed_ops = {
+	.get_rate = clk_fixed_get_rate,
+};
+EXPORT_SYMBOL_GPL(clk_fixed_ops);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 7b406bd..d2f0db0 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -155,6 +155,22 @@ static inline void clk_common_init(struct clk *clk)
 	mutex_init(&clk->prepare_lock);
 }
 
+/* Simple fixed-rate clock */
+struct clk_fixed {
+	struct clk	clk;
+	unsigned long	rate;
+};
+
+extern struct clk_ops clk_fixed_ops;
+
+#define INIT_CLK_FIXED(name, r) { \
+	.clk = INIT_CLK(name.clk, clk_fixed_ops), \
+	.rate = (r) \
+}
+
+#define DEFINE_CLK_FIXED(name, r) \
+	struct clk_fixed name = INIT_CLK_FIXED(name, r)
+
 #else /* !CONFIG_USE_COMMON_STRUCT_CLK */
 
 /*

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

* Re: [PATCH 2/2] clk: Generic support for fixed-rate clocks
  2011-02-21 19:51     ` Ryan Mallon
  (?)
@ 2011-02-21 23:29       ` Jeremy Kerr
  -1 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2011-02-21 23:29 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Ryan,

> If we never need to dynamically create fixed clocks (which seems
> unlikely) then rate can be const.

There's been a few cases where I've needed to set the rate of a fixed clock 
during boot - for example when a clock rate varies between boards, it may be 
defined in a platform-wide file, but have the rate modified early (ie, 
clk_foo.rate = 32678) in a board file.

Also, if we're parsing clocks from the device tree (or any other discovery 
mechanism), we'll need to modify rate.

Cheers,


Jeremy

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

* Re: [PATCH 2/2] clk: Generic support for fixed-rate clocks
@ 2011-02-21 23:29       ` Jeremy Kerr
  0 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2011-02-21 23:29 UTC (permalink / raw)
  To: Ryan Mallon
  Cc: linux-kernel, linux-arm-kernel, Nicolas Pitre, Dima Zavin,
	Lorenzo Pieralisi, Vincent Guittot, linux-sh, Ben Herrenchmidt,
	Uwe Kleine-König, Sascha Hauer, Paul Mundt, Saravana Kannan,
	Ben Dooks, Russell King

Hi Ryan,

> If we never need to dynamically create fixed clocks (which seems
> unlikely) then rate can be const.

There's been a few cases where I've needed to set the rate of a fixed clock 
during boot - for example when a clock rate varies between boards, it may be 
defined in a platform-wide file, but have the rate modified early (ie, 
clk_foo.rate = 32678) in a board file.

Also, if we're parsing clocks from the device tree (or any other discovery 
mechanism), we'll need to modify rate.

Cheers,


Jeremy

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

* [PATCH 2/2] clk: Generic support for fixed-rate clocks
@ 2011-02-21 23:29       ` Jeremy Kerr
  0 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2011-02-21 23:29 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Ryan,

> If we never need to dynamically create fixed clocks (which seems
> unlikely) then rate can be const.

There's been a few cases where I've needed to set the rate of a fixed clock 
during boot - for example when a clock rate varies between boards, it may be 
defined in a platform-wide file, but have the rate modified early (ie, 
clk_foo.rate = 32678) in a board file.

Also, if we're parsing clocks from the device tree (or any other discovery 
mechanism), we'll need to modify rate.

Cheers,


Jeremy

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

* Re: [PATCH 2/2] clk: Generic support for fixed-rate clocks
  2011-02-21  2:50   ` Jeremy Kerr
  (?)
@ 2011-02-21 19:51     ` Ryan Mallon
  -1 siblings, 0 replies; 40+ messages in thread
From: Ryan Mallon @ 2011-02-21 19:51 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/21/2011 03:50 PM, Jeremy Kerr wrote:
> Since most platforms will need a fixed-rate clock, add one. This will
> also serve as a basic example of an implementation of struct clk.
> 
> Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
> 
> ---
>  drivers/clk/clk.c   |   14 ++++++++++++++
>  include/linux/clk.h |   16 ++++++++++++++++
>  2 files changed, 30 insertions(+)
> 
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index 0bc9c6f..0da0bb9 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -130,3 +130,17 @@ void __clk_put(struct clk *clk)
>  	if (clk->ops->put)
>  		clk->ops->put(clk);
>  }
> +
> +/* clk_fixed support */
> +
> +#define to_clk_fixed(clk) (container_of(clk, struct clk_fixed, clk))
> +
> +static unsigned long clk_fixed_get_rate(struct clk *clk)
> +{
> +	return to_clk_fixed(clk)->rate;
> +}
> +
> +struct clk_ops clk_fixed_ops = {
> +	.get_rate = clk_fixed_get_rate,
> +};
> +EXPORT_SYMBOL_GPL(clk_fixed_ops);
> diff --git a/include/linux/clk.h b/include/linux/clk.h
> index 604be74..7c0808c 100644
> --- a/include/linux/clk.h
> +++ b/include/linux/clk.h
> @@ -155,6 +155,22 @@ static inline void clk_common_init(struct clk *clk)
>  	mutex_init(&clk->prepare_lock);
>  }
>  
> +/* Simple fixed-rate clock */
> +struct clk_fixed {
> +	struct clk	clk;
> +	unsigned long	rate;

If we never need to dynamically create fixed clocks (which seems
unlikely) then rate can be const.

~Ryan

-- 
Bluewater Systems Ltd - ARM Technology Solution Centre

Ryan Mallon         		5 Amuri Park, 404 Barbadoes St
ryan@bluewatersys.com         	PO Box 13 889, Christchurch 8013
http://www.bluewatersys.com	New Zealand
Phone: +64 3 3779127		Freecall: Australia 1800 148 751
Fax:   +64 3 3779135			  USA 1800 261 2934

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

* Re: [PATCH 2/2] clk: Generic support for fixed-rate clocks
@ 2011-02-21 19:51     ` Ryan Mallon
  0 siblings, 0 replies; 40+ messages in thread
From: Ryan Mallon @ 2011-02-21 19:51 UTC (permalink / raw)
  To: Jeremy Kerr
  Cc: linux-kernel, linux-arm-kernel, Nicolas Pitre, Dima Zavin,
	Lorenzo Pieralisi, Vincent Guittot, linux-sh, Ben Herrenchmidt,
	Uwe Kleine-König, Sascha Hauer, Paul Mundt, Saravana Kannan,
	Ben Dooks, Russell King

On 02/21/2011 03:50 PM, Jeremy Kerr wrote:
> Since most platforms will need a fixed-rate clock, add one. This will
> also serve as a basic example of an implementation of struct clk.
> 
> Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
> 
> ---
>  drivers/clk/clk.c   |   14 ++++++++++++++
>  include/linux/clk.h |   16 ++++++++++++++++
>  2 files changed, 30 insertions(+)
> 
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index 0bc9c6f..0da0bb9 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -130,3 +130,17 @@ void __clk_put(struct clk *clk)
>  	if (clk->ops->put)
>  		clk->ops->put(clk);
>  }
> +
> +/* clk_fixed support */
> +
> +#define to_clk_fixed(clk) (container_of(clk, struct clk_fixed, clk))
> +
> +static unsigned long clk_fixed_get_rate(struct clk *clk)
> +{
> +	return to_clk_fixed(clk)->rate;
> +}
> +
> +struct clk_ops clk_fixed_ops = {
> +	.get_rate = clk_fixed_get_rate,
> +};
> +EXPORT_SYMBOL_GPL(clk_fixed_ops);
> diff --git a/include/linux/clk.h b/include/linux/clk.h
> index 604be74..7c0808c 100644
> --- a/include/linux/clk.h
> +++ b/include/linux/clk.h
> @@ -155,6 +155,22 @@ static inline void clk_common_init(struct clk *clk)
>  	mutex_init(&clk->prepare_lock);
>  }
>  
> +/* Simple fixed-rate clock */
> +struct clk_fixed {
> +	struct clk	clk;
> +	unsigned long	rate;

If we never need to dynamically create fixed clocks (which seems
unlikely) then rate can be const.

~Ryan

-- 
Bluewater Systems Ltd - ARM Technology Solution Centre

Ryan Mallon         		5 Amuri Park, 404 Barbadoes St
ryan@bluewatersys.com         	PO Box 13 889, Christchurch 8013
http://www.bluewatersys.com	New Zealand
Phone: +64 3 3779127		Freecall: Australia 1800 148 751
Fax:   +64 3 3779135			  USA 1800 261 2934

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

* [PATCH 2/2] clk: Generic support for fixed-rate clocks
@ 2011-02-21 19:51     ` Ryan Mallon
  0 siblings, 0 replies; 40+ messages in thread
From: Ryan Mallon @ 2011-02-21 19:51 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/21/2011 03:50 PM, Jeremy Kerr wrote:
> Since most platforms will need a fixed-rate clock, add one. This will
> also serve as a basic example of an implementation of struct clk.
> 
> Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
> 
> ---
>  drivers/clk/clk.c   |   14 ++++++++++++++
>  include/linux/clk.h |   16 ++++++++++++++++
>  2 files changed, 30 insertions(+)
> 
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index 0bc9c6f..0da0bb9 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -130,3 +130,17 @@ void __clk_put(struct clk *clk)
>  	if (clk->ops->put)
>  		clk->ops->put(clk);
>  }
> +
> +/* clk_fixed support */
> +
> +#define to_clk_fixed(clk) (container_of(clk, struct clk_fixed, clk))
> +
> +static unsigned long clk_fixed_get_rate(struct clk *clk)
> +{
> +	return to_clk_fixed(clk)->rate;
> +}
> +
> +struct clk_ops clk_fixed_ops = {
> +	.get_rate = clk_fixed_get_rate,
> +};
> +EXPORT_SYMBOL_GPL(clk_fixed_ops);
> diff --git a/include/linux/clk.h b/include/linux/clk.h
> index 604be74..7c0808c 100644
> --- a/include/linux/clk.h
> +++ b/include/linux/clk.h
> @@ -155,6 +155,22 @@ static inline void clk_common_init(struct clk *clk)
>  	mutex_init(&clk->prepare_lock);
>  }
>  
> +/* Simple fixed-rate clock */
> +struct clk_fixed {
> +	struct clk	clk;
> +	unsigned long	rate;

If we never need to dynamically create fixed clocks (which seems
unlikely) then rate can be const.

~Ryan

-- 
Bluewater Systems Ltd - ARM Technology Solution Centre

Ryan Mallon         		5 Amuri Park, 404 Barbadoes St
ryan at bluewatersys.com         	PO Box 13 889, Christchurch 8013
http://www.bluewatersys.com	New Zealand
Phone: +64 3 3779127		Freecall: Australia 1800 148 751
Fax:   +64 3 3779135			  USA 1800 261 2934

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

* [PATCH 2/2] clk: Generic support for fixed-rate clocks
  2011-02-21  2:50 [PATCH 0/2] Common struct clk implementation, v13 Jeremy Kerr
  2011-02-21  2:50   ` Jeremy Kerr
@ 2011-02-21  2:50   ` Jeremy Kerr
  0 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2011-02-21  2:50 UTC (permalink / raw)
  To: linux-arm-kernel

Since most platforms will need a fixed-rate clock, add one. This will
also serve as a basic example of an implementation of struct clk.

Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>

---
 drivers/clk/clk.c   |   14 ++++++++++++++
 include/linux/clk.h |   16 ++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 0bc9c6f..0da0bb9 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -130,3 +130,17 @@ void __clk_put(struct clk *clk)
 	if (clk->ops->put)
 		clk->ops->put(clk);
 }
+
+/* clk_fixed support */
+
+#define to_clk_fixed(clk) (container_of(clk, struct clk_fixed, clk))
+
+static unsigned long clk_fixed_get_rate(struct clk *clk)
+{
+	return to_clk_fixed(clk)->rate;
+}
+
+struct clk_ops clk_fixed_ops = {
+	.get_rate = clk_fixed_get_rate,
+};
+EXPORT_SYMBOL_GPL(clk_fixed_ops);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 604be74..7c0808c 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -155,6 +155,22 @@ static inline void clk_common_init(struct clk *clk)
 	mutex_init(&clk->prepare_lock);
 }
 
+/* Simple fixed-rate clock */
+struct clk_fixed {
+	struct clk	clk;
+	unsigned long	rate;
+};
+
+extern struct clk_ops clk_fixed_ops;
+
+#define INIT_CLK_FIXED(name, r) { \
+	.clk = INIT_CLK(name.clk, clk_fixed_ops), \
+	.rate = (r) \
+}
+
+#define DEFINE_CLK_FIXED(name, r) \
+	struct clk_fixed name = INIT_CLK_FIXED(name, r)
+
 #else /* !CONFIG_USE_COMMON_STRUCT_CLK */
 
 /*

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

* [PATCH 2/2] clk: Generic support for fixed-rate clocks
@ 2011-02-21  2:50   ` Jeremy Kerr
  0 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2011-02-21  2:50 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel
  Cc: Nicolas Pitre, Dima Zavin, Lorenzo Pieralisi, Vincent Guittot,
	linux-sh, Ben Herrenchmidt, Uwe Kleine-König, Sascha Hauer,
	Paul Mundt, Saravana Kannan, Ben Dooks, Jeremy Kerr,
	Russell King

Since most platforms will need a fixed-rate clock, add one. This will
also serve as a basic example of an implementation of struct clk.

Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>

---
 drivers/clk/clk.c   |   14 ++++++++++++++
 include/linux/clk.h |   16 ++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 0bc9c6f..0da0bb9 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -130,3 +130,17 @@ void __clk_put(struct clk *clk)
 	if (clk->ops->put)
 		clk->ops->put(clk);
 }
+
+/* clk_fixed support */
+
+#define to_clk_fixed(clk) (container_of(clk, struct clk_fixed, clk))
+
+static unsigned long clk_fixed_get_rate(struct clk *clk)
+{
+	return to_clk_fixed(clk)->rate;
+}
+
+struct clk_ops clk_fixed_ops = {
+	.get_rate = clk_fixed_get_rate,
+};
+EXPORT_SYMBOL_GPL(clk_fixed_ops);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 604be74..7c0808c 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -155,6 +155,22 @@ static inline void clk_common_init(struct clk *clk)
 	mutex_init(&clk->prepare_lock);
 }
 
+/* Simple fixed-rate clock */
+struct clk_fixed {
+	struct clk	clk;
+	unsigned long	rate;
+};
+
+extern struct clk_ops clk_fixed_ops;
+
+#define INIT_CLK_FIXED(name, r) { \
+	.clk = INIT_CLK(name.clk, clk_fixed_ops), \
+	.rate = (r) \
+}
+
+#define DEFINE_CLK_FIXED(name, r) \
+	struct clk_fixed name = INIT_CLK_FIXED(name, r)
+
 #else /* !CONFIG_USE_COMMON_STRUCT_CLK */
 
 /*

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

* [PATCH 2/2] clk: Generic support for fixed-rate clocks
@ 2011-02-21  2:50   ` Jeremy Kerr
  0 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2011-02-21  2:50 UTC (permalink / raw)
  To: linux-arm-kernel

Since most platforms will need a fixed-rate clock, add one. This will
also serve as a basic example of an implementation of struct clk.

Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>

---
 drivers/clk/clk.c   |   14 ++++++++++++++
 include/linux/clk.h |   16 ++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 0bc9c6f..0da0bb9 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -130,3 +130,17 @@ void __clk_put(struct clk *clk)
 	if (clk->ops->put)
 		clk->ops->put(clk);
 }
+
+/* clk_fixed support */
+
+#define to_clk_fixed(clk) (container_of(clk, struct clk_fixed, clk))
+
+static unsigned long clk_fixed_get_rate(struct clk *clk)
+{
+	return to_clk_fixed(clk)->rate;
+}
+
+struct clk_ops clk_fixed_ops = {
+	.get_rate = clk_fixed_get_rate,
+};
+EXPORT_SYMBOL_GPL(clk_fixed_ops);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 604be74..7c0808c 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -155,6 +155,22 @@ static inline void clk_common_init(struct clk *clk)
 	mutex_init(&clk->prepare_lock);
 }
 
+/* Simple fixed-rate clock */
+struct clk_fixed {
+	struct clk	clk;
+	unsigned long	rate;
+};
+
+extern struct clk_ops clk_fixed_ops;
+
+#define INIT_CLK_FIXED(name, r) { \
+	.clk = INIT_CLK(name.clk, clk_fixed_ops), \
+	.rate = (r) \
+}
+
+#define DEFINE_CLK_FIXED(name, r) \
+	struct clk_fixed name = INIT_CLK_FIXED(name, r)
+
 #else /* !CONFIG_USE_COMMON_STRUCT_CLK */
 
 /*

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

* [PATCH 2/2] clk: Generic support for fixed-rate clocks
  2011-01-05  3:51 [PATCH 0/2] Common struct clk implementation, v10 Jeremy Kerr
@ 2011-01-05  3:51   ` Jeremy Kerr
  0 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2011-01-05  3:51 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel; +Cc: Ben Herrenchmidt, Uwe Kleine-König

Since most platforms will need a fixed-rate clock, add one. This will
also serve as a basic example of an implementation of struct clk.

Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>

---
 include/linux/clk.h |   16 ++++++++++++++++
 kernel/clk.c        |   14 ++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/include/linux/clk.h b/include/linux/clk.h
index 95c49b1..6cef9fe 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -164,6 +164,22 @@ static inline void clk_common_init(struct clk *clk)
 		mutex_init(&clk->lock.mutex);
 }
 
+/* Simple fixed-rate clock */
+struct clk_fixed {
+	struct clk	clk;
+	unsigned long	rate;
+};
+
+extern struct clk_ops clk_fixed_ops;
+
+#define INIT_CLK_FIXED(name, r) { \
+	.clk = INIT_CLK(name.clk, clk_fixed_ops), \
+	.rate = (r) \
+}
+
+#define DEFINE_CLK_FIXED(name, r) \
+	struct clk_fixed name = INIT_CLK_FIXED(name, r)
+
 #else /* !CONFIG_USE_COMMON_STRUCT_CLK */
 
 /*
diff --git a/kernel/clk.c b/kernel/clk.c
index 8de8fe3..6c38cc0 100644
--- a/kernel/clk.c
+++ b/kernel/clk.c
@@ -100,3 +100,17 @@ struct clk *clk_get_parent(struct clk *clk)
 	return ERR_PTR(-ENOSYS);
 }
 EXPORT_SYMBOL_GPL(clk_get_parent);
+
+/* clk_fixed support */
+
+#define to_clk_fixed(clk) (container_of(clk, struct clk_fixed, clk))
+
+static unsigned long clk_fixed_get_rate(struct clk *clk)
+{
+	return to_clk_fixed(clk)->rate;
+}
+
+struct clk_ops clk_fixed_ops = {
+	.get_rate = clk_fixed_get_rate,
+};
+EXPORT_SYMBOL_GPL(clk_fixed_ops);

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

* [PATCH 2/2] clk: Generic support for fixed-rate clocks
@ 2011-01-05  3:51   ` Jeremy Kerr
  0 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2011-01-05  3:51 UTC (permalink / raw)
  To: linux-arm-kernel

Since most platforms will need a fixed-rate clock, add one. This will
also serve as a basic example of an implementation of struct clk.

Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>

---
 include/linux/clk.h |   16 ++++++++++++++++
 kernel/clk.c        |   14 ++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/include/linux/clk.h b/include/linux/clk.h
index 95c49b1..6cef9fe 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -164,6 +164,22 @@ static inline void clk_common_init(struct clk *clk)
 		mutex_init(&clk->lock.mutex);
 }
 
+/* Simple fixed-rate clock */
+struct clk_fixed {
+	struct clk	clk;
+	unsigned long	rate;
+};
+
+extern struct clk_ops clk_fixed_ops;
+
+#define INIT_CLK_FIXED(name, r) { \
+	.clk = INIT_CLK(name.clk, clk_fixed_ops), \
+	.rate = (r) \
+}
+
+#define DEFINE_CLK_FIXED(name, r) \
+	struct clk_fixed name = INIT_CLK_FIXED(name, r)
+
 #else /* !CONFIG_USE_COMMON_STRUCT_CLK */
 
 /*
diff --git a/kernel/clk.c b/kernel/clk.c
index 8de8fe3..6c38cc0 100644
--- a/kernel/clk.c
+++ b/kernel/clk.c
@@ -100,3 +100,17 @@ struct clk *clk_get_parent(struct clk *clk)
 	return ERR_PTR(-ENOSYS);
 }
 EXPORT_SYMBOL_GPL(clk_get_parent);
+
+/* clk_fixed support */
+
+#define to_clk_fixed(clk) (container_of(clk, struct clk_fixed, clk))
+
+static unsigned long clk_fixed_get_rate(struct clk *clk)
+{
+	return to_clk_fixed(clk)->rate;
+}
+
+struct clk_ops clk_fixed_ops = {
+	.get_rate = clk_fixed_get_rate,
+};
+EXPORT_SYMBOL_GPL(clk_fixed_ops);

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

* [PATCH 2/2] clk: Generic support for fixed-rate clocks
  2011-01-05  3:18 [PATCH 0/2] Common struct clk implementation, v10 Jeremy Kerr
@ 2011-01-05  3:18 ` Jeremy Kerr
  0 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2011-01-05  3:18 UTC (permalink / raw)
  To: linux-arm-kernel

Since most platforms will need a fixed-rate clock, add one. This will
also serve as a basic example of an implementation of struct clk.

Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>

---
 include/linux/clk.h |   16 ++++++++++++++++
 kernel/clk.c        |   14 ++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/include/linux/clk.h b/include/linux/clk.h
index 95c49b1..6cef9fe 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -164,6 +164,22 @@ static inline void clk_common_init(struct clk *clk)
 		mutex_init(&clk->lock.mutex);
 }
 
+/* Simple fixed-rate clock */
+struct clk_fixed {
+	struct clk	clk;
+	unsigned long	rate;
+};
+
+extern struct clk_ops clk_fixed_ops;
+
+#define INIT_CLK_FIXED(name, r) { \
+	.clk = INIT_CLK(name.clk, clk_fixed_ops), \
+	.rate = (r) \
+}
+
+#define DEFINE_CLK_FIXED(name, r) \
+	struct clk_fixed name = INIT_CLK_FIXED(name, r)
+
 #else /* !CONFIG_USE_COMMON_STRUCT_CLK */
 
 /*
diff --git a/kernel/clk.c b/kernel/clk.c
index 8de8fe3..6c38cc0 100644
--- a/kernel/clk.c
+++ b/kernel/clk.c
@@ -100,3 +100,17 @@ struct clk *clk_get_parent(struct clk *clk)
 	return ERR_PTR(-ENOSYS);
 }
 EXPORT_SYMBOL_GPL(clk_get_parent);
+
+/* clk_fixed support */
+
+#define to_clk_fixed(clk) (container_of(clk, struct clk_fixed, clk))
+
+static unsigned long clk_fixed_get_rate(struct clk *clk)
+{
+	return to_clk_fixed(clk)->rate;
+}
+
+struct clk_ops clk_fixed_ops = {
+	.get_rate = clk_fixed_get_rate,
+};
+EXPORT_SYMBOL_GPL(clk_fixed_ops);

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

* Re: [PATCH 2/2] clk: Generic support for fixed-rate clocks
  2010-12-13 12:35       ` Jeremy Kerr
@ 2010-12-13 12:42         ` Sascha Hauer
  -1 siblings, 0 replies; 40+ messages in thread
From: Sascha Hauer @ 2010-12-13 12:42 UTC (permalink / raw)
  To: Jeremy Kerr; +Cc: linux-arm-kernel, linux-kernel

On Mon, Dec 13, 2010 at 08:35:37PM +0800, Jeremy Kerr wrote:
> Hi Sascha,
> 
> > > +extern struct clk_ops clk_fixed_ops;
> > > +
> > > +#define INIT_CLK_FIXED(name, r) { \
> > > +	.clk = INIT_CLK(name.clk, clk_fixed_ops), \
> > > +	.rate = (r) \
> > > +}
> > 
> > Is there any other valid usecase for this other than
> > 
> > struct clk_fixed bla = INIT_CLK_FIXED(bla, rate);
> > 
> > Otherwise I suggest to convert the macro to:
> > 
> > #define INIT_CLK_FIXED(name, r) \
> > 	struct clk_fixed name = { \
> > 		.clk = INIT_CLK(name.clk, clk_fixed_ops), \
> > 		.rate = (r) \
> > 	}
> > 
> > This way we do not have to specify the same name twice (and it has
> > to be exactly the same name, otherwise it won't compile).
> 
> For the system-wide INIT_CLK* macros, I've intentionally made them initalisers 
> rather than declarators, so that we can use them in other declarators (ie, the 
> usage of INIT_CLK() above). This would be relevant if someone is using 
> clk_fixed in their struct - probably not likely, but good to be consistent.
> 
> But yes, it would be good to avoid having to specify the name twice - how 
> about adding a:
> 
> #define DEFINE_CLK_FIXED(name, r) \
> 	struct clk_fixed name = INIT_CLK_FIXED(name, r)
> 
> - just like DEFINE_MUTEX and MUTEX_INITIALIZER.

Jup, sounds 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] 40+ messages in thread

* [PATCH 2/2] clk: Generic support for fixed-rate clocks
@ 2010-12-13 12:42         ` Sascha Hauer
  0 siblings, 0 replies; 40+ messages in thread
From: Sascha Hauer @ 2010-12-13 12:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Dec 13, 2010 at 08:35:37PM +0800, Jeremy Kerr wrote:
> Hi Sascha,
> 
> > > +extern struct clk_ops clk_fixed_ops;
> > > +
> > > +#define INIT_CLK_FIXED(name, r) { \
> > > +	.clk = INIT_CLK(name.clk, clk_fixed_ops), \
> > > +	.rate = (r) \
> > > +}
> > 
> > Is there any other valid usecase for this other than
> > 
> > struct clk_fixed bla = INIT_CLK_FIXED(bla, rate);
> > 
> > Otherwise I suggest to convert the macro to:
> > 
> > #define INIT_CLK_FIXED(name, r) \
> > 	struct clk_fixed name = { \
> > 		.clk = INIT_CLK(name.clk, clk_fixed_ops), \
> > 		.rate = (r) \
> > 	}
> > 
> > This way we do not have to specify the same name twice (and it has
> > to be exactly the same name, otherwise it won't compile).
> 
> For the system-wide INIT_CLK* macros, I've intentionally made them initalisers 
> rather than declarators, so that we can use them in other declarators (ie, the 
> usage of INIT_CLK() above). This would be relevant if someone is using 
> clk_fixed in their struct - probably not likely, but good to be consistent.
> 
> But yes, it would be good to avoid having to specify the name twice - how 
> about adding a:
> 
> #define DEFINE_CLK_FIXED(name, r) \
> 	struct clk_fixed name = INIT_CLK_FIXED(name, r)
> 
> - just like DEFINE_MUTEX and MUTEX_INITIALIZER.

Jup, sounds 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] 40+ messages in thread

* Re: [PATCH 2/2] clk: Generic support for fixed-rate clocks
  2010-12-13 12:14     ` Sascha Hauer
@ 2010-12-13 12:35       ` Jeremy Kerr
  -1 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2010-12-13 12:35 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: linux-arm-kernel, linux-kernel

Hi Sascha,

> > +extern struct clk_ops clk_fixed_ops;
> > +
> > +#define INIT_CLK_FIXED(name, r) { \
> > +	.clk = INIT_CLK(name.clk, clk_fixed_ops), \
> > +	.rate = (r) \
> > +}
> 
> Is there any other valid usecase for this other than
> 
> struct clk_fixed bla = INIT_CLK_FIXED(bla, rate);
> 
> Otherwise I suggest to convert the macro to:
> 
> #define INIT_CLK_FIXED(name, r) \
> 	struct clk_fixed name = { \
> 		.clk = INIT_CLK(name.clk, clk_fixed_ops), \
> 		.rate = (r) \
> 	}
> 
> This way we do not have to specify the same name twice (and it has
> to be exactly the same name, otherwise it won't compile).

For the system-wide INIT_CLK* macros, I've intentionally made them initalisers 
rather than declarators, so that we can use them in other declarators (ie, the 
usage of INIT_CLK() above). This would be relevant if someone is using 
clk_fixed in their struct - probably not likely, but good to be consistent.

But yes, it would be good to avoid having to specify the name twice - how 
about adding a:

#define DEFINE_CLK_FIXED(name, r) \
	struct clk_fixed name = INIT_CLK_FIXED(name, r)

- just like DEFINE_MUTEX and MUTEX_INITIALIZER.

Cheers,


Jeremy

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

* [PATCH 2/2] clk: Generic support for fixed-rate clocks
@ 2010-12-13 12:35       ` Jeremy Kerr
  0 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2010-12-13 12:35 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Sascha,

> > +extern struct clk_ops clk_fixed_ops;
> > +
> > +#define INIT_CLK_FIXED(name, r) { \
> > +	.clk = INIT_CLK(name.clk, clk_fixed_ops), \
> > +	.rate = (r) \
> > +}
> 
> Is there any other valid usecase for this other than
> 
> struct clk_fixed bla = INIT_CLK_FIXED(bla, rate);
> 
> Otherwise I suggest to convert the macro to:
> 
> #define INIT_CLK_FIXED(name, r) \
> 	struct clk_fixed name = { \
> 		.clk = INIT_CLK(name.clk, clk_fixed_ops), \
> 		.rate = (r) \
> 	}
> 
> This way we do not have to specify the same name twice (and it has
> to be exactly the same name, otherwise it won't compile).

For the system-wide INIT_CLK* macros, I've intentionally made them initalisers 
rather than declarators, so that we can use them in other declarators (ie, the 
usage of INIT_CLK() above). This would be relevant if someone is using 
clk_fixed in their struct - probably not likely, but good to be consistent.

But yes, it would be good to avoid having to specify the name twice - how 
about adding a:

#define DEFINE_CLK_FIXED(name, r) \
	struct clk_fixed name = INIT_CLK_FIXED(name, r)

- just like DEFINE_MUTEX and MUTEX_INITIALIZER.

Cheers,


Jeremy

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

* Re: [PATCH 2/2] clk: Generic support for fixed-rate clocks
  2010-12-08  2:08   ` Jeremy Kerr
@ 2010-12-13 12:14     ` Sascha Hauer
  -1 siblings, 0 replies; 40+ messages in thread
From: Sascha Hauer @ 2010-12-13 12:14 UTC (permalink / raw)
  To: Jeremy Kerr; +Cc: linux-arm-kernel, linux-kernel

Hi Jeremy,

On Wed, Dec 08, 2010 at 10:08:14AM +0800, Jeremy Kerr wrote:
> Since most platforms will need a fixed-rate clock, add one. This will
> also serve as a basic example of an implementation of struct clk.
> 
> Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
> 
> ---
>  include/linux/clk.h |   13 +++++++++++++
>  kernel/clk.c        |   14 ++++++++++++++
>  2 files changed, 27 insertions(+)
> 
> diff --git a/include/linux/clk.h b/include/linux/clk.h
> index e09e40e..ae7e4ed 100644
> --- a/include/linux/clk.h
> +++ b/include/linux/clk.h
> @@ -158,6 +158,19 @@ static inline void clk_common_init(struct clk *clk)
>  		mutex_init(&clk->lock.mutex);
>  }
>  
> +/* Simple fixed-rate clock */
> +struct clk_fixed {
> +	struct clk	clk;
> +	unsigned long	rate;
> +};
> +
> +extern struct clk_ops clk_fixed_ops;
> +
> +#define INIT_CLK_FIXED(name, r) { \
> +	.clk = INIT_CLK(name.clk, clk_fixed_ops), \
> +	.rate = (r) \
> +}

Is there any other valid usecase for this other than

struct clk_fixed bla = INIT_CLK_FIXED(bla, rate);

Otherwise I suggest to convert the macro to:

#define INIT_CLK_FIXED(name, r) \
	struct clk_fixed name = { \
		.clk = INIT_CLK(name.clk, clk_fixed_ops), \
		.rate = (r) \
	}

This way we do not have to specify the same name twice (and it has
to be exactly the same name, otherwise it won't compile).

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] 40+ messages in thread

* [PATCH 2/2] clk: Generic support for fixed-rate clocks
@ 2010-12-13 12:14     ` Sascha Hauer
  0 siblings, 0 replies; 40+ messages in thread
From: Sascha Hauer @ 2010-12-13 12:14 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Jeremy,

On Wed, Dec 08, 2010 at 10:08:14AM +0800, Jeremy Kerr wrote:
> Since most platforms will need a fixed-rate clock, add one. This will
> also serve as a basic example of an implementation of struct clk.
> 
> Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
> 
> ---
>  include/linux/clk.h |   13 +++++++++++++
>  kernel/clk.c        |   14 ++++++++++++++
>  2 files changed, 27 insertions(+)
> 
> diff --git a/include/linux/clk.h b/include/linux/clk.h
> index e09e40e..ae7e4ed 100644
> --- a/include/linux/clk.h
> +++ b/include/linux/clk.h
> @@ -158,6 +158,19 @@ static inline void clk_common_init(struct clk *clk)
>  		mutex_init(&clk->lock.mutex);
>  }
>  
> +/* Simple fixed-rate clock */
> +struct clk_fixed {
> +	struct clk	clk;
> +	unsigned long	rate;
> +};
> +
> +extern struct clk_ops clk_fixed_ops;
> +
> +#define INIT_CLK_FIXED(name, r) { \
> +	.clk = INIT_CLK(name.clk, clk_fixed_ops), \
> +	.rate = (r) \
> +}

Is there any other valid usecase for this other than

struct clk_fixed bla = INIT_CLK_FIXED(bla, rate);

Otherwise I suggest to convert the macro to:

#define INIT_CLK_FIXED(name, r) \
	struct clk_fixed name = { \
		.clk = INIT_CLK(name.clk, clk_fixed_ops), \
		.rate = (r) \
	}

This way we do not have to specify the same name twice (and it has
to be exactly the same name, otherwise it won't compile).

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] 40+ messages in thread

* [PATCH 2/2] clk: Generic support for fixed-rate clocks
  2010-12-08  2:08 [PATCH 0/2] Common struct clk implementation, v8 Jeremy Kerr
@ 2010-12-08  2:08   ` Jeremy Kerr
  0 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2010-12-08  2:08 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: linux-kernel

Since most platforms will need a fixed-rate clock, add one. This will
also serve as a basic example of an implementation of struct clk.

Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>

---
 include/linux/clk.h |   13 +++++++++++++
 kernel/clk.c        |   14 ++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/include/linux/clk.h b/include/linux/clk.h
index e09e40e..ae7e4ed 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -158,6 +158,19 @@ static inline void clk_common_init(struct clk *clk)
 		mutex_init(&clk->lock.mutex);
 }
 
+/* Simple fixed-rate clock */
+struct clk_fixed {
+	struct clk	clk;
+	unsigned long	rate;
+};
+
+extern struct clk_ops clk_fixed_ops;
+
+#define INIT_CLK_FIXED(name, r) { \
+	.clk = INIT_CLK(name.clk, clk_fixed_ops), \
+	.rate = (r) \
+}
+
 #else /* !CONFIG_USE_COMMON_STRUCT_CLK */
 
 /*
diff --git a/kernel/clk.c b/kernel/clk.c
index 1545e69..2779abb 100644
--- a/kernel/clk.c
+++ b/kernel/clk.c
@@ -98,3 +98,17 @@ struct clk *clk_get_parent(struct clk *clk)
 	return ERR_PTR(-ENOSYS);
 }
 EXPORT_SYMBOL_GPL(clk_get_parent);
+
+/* clk_fixed support */
+
+#define to_clk_fixed(clk) (container_of(clk, struct clk_fixed, clk))
+
+static unsigned long clk_fixed_get_rate(struct clk *clk)
+{
+	return to_clk_fixed(clk)->rate;
+}
+
+struct clk_ops clk_fixed_ops = {
+	.get_rate = clk_fixed_get_rate,
+};
+EXPORT_SYMBOL_GPL(clk_fixed_ops);

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

* [PATCH 2/2] clk: Generic support for fixed-rate clocks
@ 2010-12-08  2:08   ` Jeremy Kerr
  0 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2010-12-08  2:08 UTC (permalink / raw)
  To: linux-arm-kernel

Since most platforms will need a fixed-rate clock, add one. This will
also serve as a basic example of an implementation of struct clk.

Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>

---
 include/linux/clk.h |   13 +++++++++++++
 kernel/clk.c        |   14 ++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/include/linux/clk.h b/include/linux/clk.h
index e09e40e..ae7e4ed 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -158,6 +158,19 @@ static inline void clk_common_init(struct clk *clk)
 		mutex_init(&clk->lock.mutex);
 }
 
+/* Simple fixed-rate clock */
+struct clk_fixed {
+	struct clk	clk;
+	unsigned long	rate;
+};
+
+extern struct clk_ops clk_fixed_ops;
+
+#define INIT_CLK_FIXED(name, r) { \
+	.clk = INIT_CLK(name.clk, clk_fixed_ops), \
+	.rate = (r) \
+}
+
 #else /* !CONFIG_USE_COMMON_STRUCT_CLK */
 
 /*
diff --git a/kernel/clk.c b/kernel/clk.c
index 1545e69..2779abb 100644
--- a/kernel/clk.c
+++ b/kernel/clk.c
@@ -98,3 +98,17 @@ struct clk *clk_get_parent(struct clk *clk)
 	return ERR_PTR(-ENOSYS);
 }
 EXPORT_SYMBOL_GPL(clk_get_parent);
+
+/* clk_fixed support */
+
+#define to_clk_fixed(clk) (container_of(clk, struct clk_fixed, clk))
+
+static unsigned long clk_fixed_get_rate(struct clk *clk)
+{
+	return to_clk_fixed(clk)->rate;
+}
+
+struct clk_ops clk_fixed_ops = {
+	.get_rate = clk_fixed_get_rate,
+};
+EXPORT_SYMBOL_GPL(clk_fixed_ops);

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

* [PATCH 2/2] clk: Generic support for fixed-rate clocks
  2010-07-12  2:37 [PATCH 0/2] Common struct clk implementation, v6 Jeremy Kerr
@ 2010-07-12  2:37   ` Jeremy Kerr
  0 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2010-07-12  2:37 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: linux-kernel, Ben Herrenchmidt

Since most platforms will need a fixed-rate clock, add one. This will
also serve as a basic example of an implementation of struct clk.

Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>

---
 include/linux/clk.h |   13 +++++++++++++
 kernel/clk.c        |   14 ++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/include/linux/clk.h b/include/linux/clk.h
index a95cc82..85e1d44 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -90,6 +90,19 @@ static inline void clk_common_init(struct clk *clk)
 	clk->enable_count = 0;
 }
 
+/* Simple fixed-rate clock */
+struct clk_fixed {
+	struct clk	clk;
+	unsigned long	rate;
+};
+
+extern struct clk_ops clk_fixed_ops;
+
+#define INIT_CLK_FIXED(r) { \
+	.clk = INIT_CLK(clk_fixed_ops), \
+	.rate = (r) \
+}
+
 #else /* !CONFIG_USE_COMMON_STRUCT_CLK */
 
 /*
diff --git a/kernel/clk.c b/kernel/clk.c
index cdea25f..32f25ef 100644
--- a/kernel/clk.c
+++ b/kernel/clk.c
@@ -99,3 +99,17 @@ struct clk *clk_get_parent(struct clk *clk)
 	return ERR_PTR(-ENOSYS);
 }
 EXPORT_SYMBOL_GPL(clk_get_parent);
+
+/* clk_fixed support */
+
+#define to_clk_fixed(clk) (container_of(clk, struct clk_fixed, clk))
+
+static unsigned long clk_fixed_get_rate(struct clk *clk)
+{
+	return to_clk_fixed(clk)->rate;
+}
+
+struct clk_ops clk_fixed_ops = {
+	.get_rate = clk_fixed_get_rate,
+};
+EXPORT_SYMBOL_GPL(clk_fixed_ops);

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

* [PATCH 2/2] clk: Generic support for fixed-rate clocks
@ 2010-07-12  2:37   ` Jeremy Kerr
  0 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2010-07-12  2:37 UTC (permalink / raw)
  To: linux-arm-kernel

Since most platforms will need a fixed-rate clock, add one. This will
also serve as a basic example of an implementation of struct clk.

Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>

---
 include/linux/clk.h |   13 +++++++++++++
 kernel/clk.c        |   14 ++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/include/linux/clk.h b/include/linux/clk.h
index a95cc82..85e1d44 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -90,6 +90,19 @@ static inline void clk_common_init(struct clk *clk)
 	clk->enable_count = 0;
 }
 
+/* Simple fixed-rate clock */
+struct clk_fixed {
+	struct clk	clk;
+	unsigned long	rate;
+};
+
+extern struct clk_ops clk_fixed_ops;
+
+#define INIT_CLK_FIXED(r) { \
+	.clk = INIT_CLK(clk_fixed_ops), \
+	.rate = (r) \
+}
+
 #else /* !CONFIG_USE_COMMON_STRUCT_CLK */
 
 /*
diff --git a/kernel/clk.c b/kernel/clk.c
index cdea25f..32f25ef 100644
--- a/kernel/clk.c
+++ b/kernel/clk.c
@@ -99,3 +99,17 @@ struct clk *clk_get_parent(struct clk *clk)
 	return ERR_PTR(-ENOSYS);
 }
 EXPORT_SYMBOL_GPL(clk_get_parent);
+
+/* clk_fixed support */
+
+#define to_clk_fixed(clk) (container_of(clk, struct clk_fixed, clk))
+
+static unsigned long clk_fixed_get_rate(struct clk *clk)
+{
+	return to_clk_fixed(clk)->rate;
+}
+
+struct clk_ops clk_fixed_ops = {
+	.get_rate = clk_fixed_get_rate,
+};
+EXPORT_SYMBOL_GPL(clk_fixed_ops);

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

* Re: [PATCH 2/2] clk: Generic support for fixed-rate clocks
  2010-06-21 20:43     ` Ryan Mallon
@ 2010-06-22  1:05       ` Jeremy Kerr
  -1 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2010-06-22  1:05 UTC (permalink / raw)
  To: Ryan Mallon; +Cc: linux-kernel, Ben Herrenchmidt, linux-arm-kernel

Hi Ryan,

> Not sure if this has been discussed already, but shouldn't rate be const
> for a fixed clock?

No, we may need to set the rate at some point - eg, when setting up the 
clocks, or parsing from the device tree.

Cheers,


Jeremy

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

* [PATCH 2/2] clk: Generic support for fixed-rate clocks
@ 2010-06-22  1:05       ` Jeremy Kerr
  0 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2010-06-22  1:05 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Ryan,

> Not sure if this has been discussed already, but shouldn't rate be const
> for a fixed clock?

No, we may need to set the rate at some point - eg, when setting up the 
clocks, or parsing from the device tree.

Cheers,


Jeremy

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

* Re: [PATCH 2/2] clk: Generic support for fixed-rate clocks
  2010-06-21  5:35   ` Jeremy Kerr
@ 2010-06-21 20:43     ` Ryan Mallon
  -1 siblings, 0 replies; 40+ messages in thread
From: Ryan Mallon @ 2010-06-21 20:43 UTC (permalink / raw)
  To: Jeremy Kerr; +Cc: linux-kernel, Ben Herrenchmidt, linux-arm-kernel

On 06/21/2010 05:35 PM, Jeremy Kerr wrote:
> Since most platforms will need a fixed-rate clock, add one. This will
> also serve as a basic example of an implementation of struct clk.
> 
> Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
> 
> ---
>  include/linux/clk.h |   13 +++++++++++++
>  kernel/clk.c        |   14 ++++++++++++++
>  2 files changed, 27 insertions(+)
> 
> diff --git a/include/linux/clk.h b/include/linux/clk.h
> index 5c1098b..1dce473 100644
> --- a/include/linux/clk.h
> +++ b/include/linux/clk.h
> @@ -79,6 +79,19 @@ struct clk_ops {
>   */
>  int __clk_get(struct clk *clk);
>  
> +/* Simple fixed-rate clock */
> +struct clk_fixed {
> +	struct clk	clk;
> +	unsigned long	rate;
> +};

Not sure if this has been discussed already, but shouldn't rate be const
for a fixed clock?

~Ryan

-- 
Bluewater Systems Ltd - ARM Technology Solution Centre

Ryan Mallon         		5 Amuri Park, 404 Barbadoes St
ryan@bluewatersys.com         	PO Box 13 889, Christchurch 8013
http://www.bluewatersys.com	New Zealand
Phone: +64 3 3779127		Freecall: Australia 1800 148 751
Fax:   +64 3 3779135			  USA 1800 261 2934

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

* [PATCH 2/2] clk: Generic support for fixed-rate clocks
@ 2010-06-21 20:43     ` Ryan Mallon
  0 siblings, 0 replies; 40+ messages in thread
From: Ryan Mallon @ 2010-06-21 20:43 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/21/2010 05:35 PM, Jeremy Kerr wrote:
> Since most platforms will need a fixed-rate clock, add one. This will
> also serve as a basic example of an implementation of struct clk.
> 
> Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
> 
> ---
>  include/linux/clk.h |   13 +++++++++++++
>  kernel/clk.c        |   14 ++++++++++++++
>  2 files changed, 27 insertions(+)
> 
> diff --git a/include/linux/clk.h b/include/linux/clk.h
> index 5c1098b..1dce473 100644
> --- a/include/linux/clk.h
> +++ b/include/linux/clk.h
> @@ -79,6 +79,19 @@ struct clk_ops {
>   */
>  int __clk_get(struct clk *clk);
>  
> +/* Simple fixed-rate clock */
> +struct clk_fixed {
> +	struct clk	clk;
> +	unsigned long	rate;
> +};

Not sure if this has been discussed already, but shouldn't rate be const
for a fixed clock?

~Ryan

-- 
Bluewater Systems Ltd - ARM Technology Solution Centre

Ryan Mallon         		5 Amuri Park, 404 Barbadoes St
ryan at bluewatersys.com         	PO Box 13 889, Christchurch 8013
http://www.bluewatersys.com	New Zealand
Phone: +64 3 3779127		Freecall: Australia 1800 148 751
Fax:   +64 3 3779135			  USA 1800 261 2934

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

* [PATCH 2/2] clk: Generic support for fixed-rate clocks
  2010-06-21  5:35 [PATCH 0/2] Common struct clk implementation, v5 Jeremy Kerr
@ 2010-06-21  5:35   ` Jeremy Kerr
  0 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2010-06-21  5:35 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-arm-kernel, Ben Herrenchmidt

Since most platforms will need a fixed-rate clock, add one. This will
also serve as a basic example of an implementation of struct clk.

Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>

---
 include/linux/clk.h |   13 +++++++++++++
 kernel/clk.c        |   14 ++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/include/linux/clk.h b/include/linux/clk.h
index 5c1098b..1dce473 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -79,6 +79,19 @@ struct clk_ops {
  */
 int __clk_get(struct clk *clk);
 
+/* Simple fixed-rate clock */
+struct clk_fixed {
+	struct clk	clk;
+	unsigned long	rate;
+};
+
+extern struct clk_ops clk_fixed_ops;
+
+#define INIT_CLK_FIXED(r) { \
+	.clk = INIT_CLK(clk_fixed_ops), \
+	.rate = (r) \
+}
+
 #else /* !CONFIG_USE_COMMON_STRUCT_CLK */
 
 /*
diff --git a/kernel/clk.c b/kernel/clk.c
index cdea25f..32f25ef 100644
--- a/kernel/clk.c
+++ b/kernel/clk.c
@@ -99,3 +99,17 @@ struct clk *clk_get_parent(struct clk *clk)
 	return ERR_PTR(-ENOSYS);
 }
 EXPORT_SYMBOL_GPL(clk_get_parent);
+
+/* clk_fixed support */
+
+#define to_clk_fixed(clk) (container_of(clk, struct clk_fixed, clk))
+
+static unsigned long clk_fixed_get_rate(struct clk *clk)
+{
+	return to_clk_fixed(clk)->rate;
+}
+
+struct clk_ops clk_fixed_ops = {
+	.get_rate = clk_fixed_get_rate,
+};
+EXPORT_SYMBOL_GPL(clk_fixed_ops);

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

* [PATCH 2/2] clk: Generic support for fixed-rate clocks
@ 2010-06-21  5:35   ` Jeremy Kerr
  0 siblings, 0 replies; 40+ messages in thread
From: Jeremy Kerr @ 2010-06-21  5:35 UTC (permalink / raw)
  To: linux-arm-kernel

Since most platforms will need a fixed-rate clock, add one. This will
also serve as a basic example of an implementation of struct clk.

Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>

---
 include/linux/clk.h |   13 +++++++++++++
 kernel/clk.c        |   14 ++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/include/linux/clk.h b/include/linux/clk.h
index 5c1098b..1dce473 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -79,6 +79,19 @@ struct clk_ops {
  */
 int __clk_get(struct clk *clk);
 
+/* Simple fixed-rate clock */
+struct clk_fixed {
+	struct clk	clk;
+	unsigned long	rate;
+};
+
+extern struct clk_ops clk_fixed_ops;
+
+#define INIT_CLK_FIXED(r) { \
+	.clk = INIT_CLK(clk_fixed_ops), \
+	.rate = (r) \
+}
+
 #else /* !CONFIG_USE_COMMON_STRUCT_CLK */
 
 /*
diff --git a/kernel/clk.c b/kernel/clk.c
index cdea25f..32f25ef 100644
--- a/kernel/clk.c
+++ b/kernel/clk.c
@@ -99,3 +99,17 @@ struct clk *clk_get_parent(struct clk *clk)
 	return ERR_PTR(-ENOSYS);
 }
 EXPORT_SYMBOL_GPL(clk_get_parent);
+
+/* clk_fixed support */
+
+#define to_clk_fixed(clk) (container_of(clk, struct clk_fixed, clk))
+
+static unsigned long clk_fixed_get_rate(struct clk *clk)
+{
+	return to_clk_fixed(clk)->rate;
+}
+
+struct clk_ops clk_fixed_ops = {
+	.get_rate = clk_fixed_get_rate,
+};
+EXPORT_SYMBOL_GPL(clk_fixed_ops);

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

end of thread, other threads:[~2011-03-03  6:40 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-08  2:05 [PATCH 1/2] Add a common struct clk Jeremy Kerr
2010-12-08  2:05 ` Jeremy Kerr
2010-12-08  2:05 ` [PATCH 2/2] clk: Generic support for fixed-rate clocks Jeremy Kerr
2010-12-08  2:05   ` Jeremy Kerr
2010-12-08 10:21 ` [PATCH 1/2] Add a common struct clk Uwe Kleine-König
2010-12-08 10:21   ` Uwe Kleine-König
2010-12-10  1:58   ` Jeremy Kerr
2010-12-10  1:58     ` Jeremy Kerr
2010-12-10  9:21     ` Uwe Kleine-König
  -- strict thread matches above, loose matches on Subject: below --
2011-02-21  2:50 [PATCH 0/2] Common struct clk implementation, v13 Jeremy Kerr
2011-02-21  2:50 ` [PATCH 2/2] clk: Generic support for fixed-rate clocks Jeremy Kerr
2011-02-21  2:50   ` Jeremy Kerr
2011-02-21  2:50   ` Jeremy Kerr
2011-02-21 19:51   ` Ryan Mallon
2011-02-21 19:51     ` Ryan Mallon
2011-02-21 19:51     ` Ryan Mallon
2011-02-21 23:29     ` Jeremy Kerr
2011-02-21 23:29       ` Jeremy Kerr
2011-02-21 23:29       ` Jeremy Kerr
2011-03-03  6:40     ` [PATCH 0/2] Common struct clk implementation, v14 Jeremy Kerr
2011-03-03  6:40       ` [PATCH 2/2] clk: Generic support for fixed-rate clocks Jeremy Kerr
2011-03-03  6:40         ` Jeremy Kerr
2011-03-03  6:40         ` Jeremy Kerr
2011-01-05  3:51 [PATCH 0/2] Common struct clk implementation, v10 Jeremy Kerr
2011-01-05  3:51 ` [PATCH 2/2] clk: Generic support for fixed-rate clocks Jeremy Kerr
2011-01-05  3:51   ` Jeremy Kerr
2011-01-05  3:18 [PATCH 0/2] Common struct clk implementation, v10 Jeremy Kerr
2011-01-05  3:18 ` [PATCH 2/2] clk: Generic support for fixed-rate clocks Jeremy Kerr
2010-12-08  2:08 [PATCH 0/2] Common struct clk implementation, v8 Jeremy Kerr
2010-12-08  2:08 ` [PATCH 2/2] clk: Generic support for fixed-rate clocks Jeremy Kerr
2010-12-08  2:08   ` Jeremy Kerr
2010-12-13 12:14   ` Sascha Hauer
2010-12-13 12:14     ` Sascha Hauer
2010-12-13 12:35     ` Jeremy Kerr
2010-12-13 12:35       ` Jeremy Kerr
2010-12-13 12:42       ` Sascha Hauer
2010-12-13 12:42         ` Sascha Hauer
2010-07-12  2:37 [PATCH 0/2] Common struct clk implementation, v6 Jeremy Kerr
2010-07-12  2:37 ` [PATCH 2/2] clk: Generic support for fixed-rate clocks Jeremy Kerr
2010-07-12  2:37   ` Jeremy Kerr
2010-06-21  5:35 [PATCH 0/2] Common struct clk implementation, v5 Jeremy Kerr
2010-06-21  5:35 ` [PATCH 2/2] clk: Generic support for fixed-rate clocks Jeremy Kerr
2010-06-21  5:35   ` Jeremy Kerr
2010-06-21 20:43   ` Ryan Mallon
2010-06-21 20:43     ` Ryan Mallon
2010-06-22  1:05     ` Jeremy Kerr
2010-06-22  1:05       ` Jeremy Kerr

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.