Common struct clk implementation, v10
cover Common struct clk implementation, v10
Hi all,
These patches are an attempt to allow platforms to share clock code. At present, the definitions of 'struct clk' are local to platform code, which makes allocating and initialising cross-platform clock sources difficult, and makes it impossible to compile a single image containing support for two ARM platforms with different struct clks.
The two patches are for the architecture-independent kernel code, introducing the common clk infrastructure. The changelog for the first patch includes details about the new clock definitions.
As requested by rmk, I've put together a small series of patches illustrating the usage of the common struct clock on the ARM imx51 platform. These are available in my git tree:
git://kernel.ubuntu.com/jk/dt/linux-2.6
in the clk-common-mx51 branch (clk-common..clk-common-mx51). There is also a port for versatile (clk-common-versatile) in this tree too.
The approach I've taken with the imx51 port is to temporarly duplicate the platform-common clock code (ie, for all mxc-based boards) to enable usage of the common struct clk on one machine (imx51), while leaving the others as-is. For a proper platform-wide usage of the common struct clk, we'd be better off doing the whole platform at once. However, mx51 is the only mxc-based HW I have, hence the duplicated example port.
In the example port, the first change simply converts the mxc's struct clk to a struct clk_mxc, using the new API. The subsequent patches move certain clocks to more specific data structures (eg clk_fixed and clk_pll) where possible.
Also, Yong Shen has contributed a patch to export a tree of clock data (currently the clock rate and enable_count) through debugfs; this is in the clk-common-debug branch.
Ben Herrenschmidt is looking at using common struct clk code for powerpc too, hence the kernel-wide approach.
Many thanks to the following for their input:
* Ben Dooks <[email protected]>
* Baruch Siach <[email protected]>
* Russell King <[email protected]>
* Uwe Kleine-K?nig <[email protected]>
* Lorenzo Pieralisi <[email protected]>
* Vincent Guittot <[email protected]>
* Sascha Hauer <[email protected]>
Russell - now that we've had a few platforms ported to the common clk infrastructure, I believe it's ready to merge. If so, do you want this in the patch tracker? Otherwise, let me know what needs changing.
Cheers,
Jeremy
--
v10:
* comment fixups, from Uwe's review
* added DEFINE_CLK_FIXED
v9:
* comment improvements
* kerneldoc fixups
* add WARN_ON to clk_disable
v8:
* add atomic clocks, and locking wrappers
* expand comments on clk and clk_ops
v7:
* change CLK_INIT to initialise clk->mutex statically
v6:
* fixed up references to 'clk_operations' in the changelog
v5:
* uninline main API, and share definitions with !USE_COMMON_STRUCT_CLK
* add __clk_get
* delay mutex init
* kerneldoc for struct clk
v4:
* use mutex for enable/disable locking
* DEFINE_CLK -> INIT_CLK, and pass the clk name for mutex init
* struct clk_operations -> struct clk_ops
v3:
* do clock usage refcounting in common code
* provide sample port
v2:
* no longer ARM-specific
* use clk_operations
---
Jeremy Kerr (2):
Add a common struct clk
clk: Generic support for fixed-rate clocks
PATCH 1/2 Add a common struct clk
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 <[email protected]>.
--- arch/Kconfig | 3 include/linux/clk.h | 164 +++++++++++++++++++++++++++++++++++++++++--- kernel/Makefile | 1 kernel/clk.c | 102 +++++++++++++++++++++++++++ 4 files changed, 261 insertions(+), 9 deletions(-)
arch/Kconfig +3 -0
@@ -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
include/linux/clk.h +155 -9
191 lines not on this page · raw message
kernel/Makefile +1 -0
@@ -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 <[email protected]>, the -fno-omit-frame-pointer is
kernel/clk.c new file +102 -0
102 lines not on this page · raw message
Re: [PATCH 1/2] Add a common struct clk
Quoted 11 lines · Jeremy Kerr
+ * 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; ifCLK_ATOMICis
+ * set, then the core clock code will use a spinlock, otherwise a mutex. This
+ * lock will be acquired duringclk_enableandclk_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, useCLK_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.
...
include/linux/clk.h line 67
Quoted 9 lines
include/linux/clk.h +9
-0+struct clk { +const struct clk_ops *ops; +unsigned int enable_count; +int flags; +union { +struct mutex mutex; +spinlock_t spinlock; + } lock; +};
Here you have a "polymorphic" lock, where the clock instance knows which type it is supposed to be. I got flak from David Miller and others trying to do the same thing with the mdio_bus:
http://kerneltrap.org/mailarchive/linux-netdev/2010/7/6/6280618
The criticism, applied to your case, is that the clk_enable() caller cannot know whether it is safe to make the call or not. I was told, "there has got to be a better way."
Richard
Re: [PATCH 1/2] Add a common struct clk
Quoted 30 lines · Richard Cochran
Quoted 11 lines · Jeremy Kerr
+ * 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; ifCLK_ATOMICis
+ * set, then the core clock code will use a spinlock, otherwise a mutex. This
+ * lock will be acquired duringclk_enableandclk_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, useCLK_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....
include/linux/clk.h line 67
Quoted 9 lines
include/linux/clk.h +9
-0+struct clk { +const struct clk_ops *ops; +unsigned int enable_count; +int flags; +union { +struct mutex mutex; +spinlock_t spinlock; + } lock; +};Here you have a "polymorphic" lock, where the clock instance knows which type it is supposed to be. I got flak from David Miller and others trying to do the same thing with the
mdio_bus:
Quoted 5 lines
http://kerneltrap.org/mailarchive/linux-netdev/2010/7/6/6280618The criticism, applied to your case, is that the
clk_enable()caller cannot know whether it is safe to make the call or not. I was told, "there has got to be a better way."
Note that this is not "new". Currently there is no convention available if clk_enable sleeps or not. See e.g.
http://thread.gmane.org/gmane.linux.ports.arm.kernel/100744
So if there is no consent and you want to introduce common code there is no choice.
I don't like it, too. IMHO clk_enable should be allowed to sleep, but I see the concerns of the other camp, too. If you know the better way that has to exists, please tell us.
(Hmm, the way the gpio api does it comes to mind:
clk_enable_atomic
clk_enable_cansleep
(where one of these can be named clk_enable).)
Best regards
Uwe
Signature · 2 lines
Pengutronix e.K. | Uwe Kleine-K?nig | Industrial Linux Solutions | http://www.pengutronix.de/ |
Re: [PATCH 1/2] Add a common struct clk
Hi Richard,
Quoted 16 lines
Quoted 16 lines
include/linux/clk.h line 67
Quoted 9 lines
include/linux/clk.h +9
-0+struct clk { +const struct clk_ops *ops; +unsigned int enable_count; +int flags; +union { +struct mutex mutex; +spinlock_t spinlock; + } lock; +};Here you have a "polymorphic" lock, where the clock instance knows which type it is supposed to be. I got flak from David Miller and
others trying to do the same thing with the
mdio_bus:http://kerneltrap.org/mailarchive/linux-netdev/2010/7/6/6280618
Quoted 7 lines
Quoted 3 lines
The criticism, applied to your case, is that the
clk_enable()caller cannot know whether it is safe to make the call or not. I was told, "there has got to be a better way."Note that this is not "new". Currently there is no convention available if
clk_enablesleeps or not. See e.g.
http://thread.gmane.org/gmane.linux.ports.arm.kernel/100744
As Uwe says, the common clock does not change these semantics; I would prefer to keep the driver API changes at a minimum with these patches.
But yes, it would be a good idea to:
* introduce clk_enable_atomic, which requires clk->flags & CLK_ATOMIC
* add might_sleep to clk_enable(), encouraging clk uses in atomic contexts to switch to clk_enable_atomic.
We'd still be able to handle CLK_ATOMIC clocks in clk_enable(), so the enforcement only needs to be one-way.
However, I think these would be better as separate changes.
Cheers,
Jeremy
Re: [PATCH 1/2] Add a common struct clk
Quoted 31 lines · Jeremy Kerr
Hi Richard,
Quoted 16 lines
Quoted 16 lines
include/linux/clk.h line 67
Quoted 9 lines
include/linux/clk.h +9
-0+struct clk { +const struct clk_ops *ops; +unsigned int enable_count; +int flags; +union { +struct mutex mutex; +spinlock_t spinlock; + } lock; +};Here you have a "polymorphic" lock, where the clock instance knows which type it is supposed to be. I got flak from David Miller and
others trying to do the same thing with the
mdio_bus:http://kerneltrap.org/mailarchive/linux-netdev/2010/7/6/6280618Quoted 7 lines
Quoted 3 lines
The criticism, applied to your case, is that the
clk_enable()caller cannot know whether it is safe to make the call or not. I was told, "there has got to be a better way."Note that this is not "new". Currently there is no convention available if
clk_enablesleeps or not. See e.g.
http://thread.gmane.org/gmane.linux.ports.arm.kernel/100744As Uwe says, the common clock does not change these semantics; I would prefer to keep the driver API changes at a minimum with these patches.
But yes, it would be a good idea to:
Quoted 7 lines
* introduce
clk_enable_atomic, which requiresclk->flags&CLK_ATOMIC* add
might_sleeptoclk_enable(), encouraging clk uses in atomic contexts to switch toclk_enable_atomic.We'd still be able to handle
CLK_ATOMICclocks inclk_enable(), so the enforcement only needs to be one-way.
I think the atomic stuff should be the norm through and through - otherwise we're going to end up with problems in drivers where they use the _atomic() stuff, but the clocks behind are coded to sleep.
I hate the GPIO APIs for doing this _cansleep crap as the decision of whether to use the _cansleep or normal APIs normally can't be made at the time when the API is used, but sometime later. Many people just use the non-_cansleep versions irrespective of the context they're in - which is unnecessarily restrictive - consider what happens if you then have that driver use a GPIO on an I2C peripheral...
By inventing two interfaces, you're asking for the same thing to happen with clocks.
Re: [PATCH 1/2] Add a common struct clk
Hello Russell,
Quoted 44 lines · Russell King - ARM Linux
Quoted 31 lines · Jeremy Kerr
Hi Richard,
Quoted 16 lines
Quoted 16 lines
include/linux/clk.h line 67
Quoted 9 lines
include/linux/clk.h +9
-0+struct clk { +const struct clk_ops *ops; +unsigned int enable_count; +int flags; +union { +struct mutex mutex; +spinlock_t spinlock; + } lock; +};Here you have a "polymorphic" lock, where the clock instance knows which type it is supposed to be. I got flak from David Miller and
others trying to do the same thing with the
mdio_bus:http://kerneltrap.org/mailarchive/linux-netdev/2010/7/6/6280618Quoted 7 lines
Quoted 3 lines
The criticism, applied to your case, is that the
clk_enable()caller cannot know whether it is safe to make the call or not. I was told, "there has got to be a better way."Note that this is not "new". Currently there is no convention available if
clk_enablesleeps or not. See e.g.
http://thread.gmane.org/gmane.linux.ports.arm.kernel/100744As Uwe says, the common clock does not change these semantics; I would prefer to keep the driver API changes at a minimum with these patches.
But yes, it would be a good idea to:
Quoted 7 lines
* introduce
clk_enable_atomic, which requiresclk->flags&CLK_ATOMIC* add
might_sleeptoclk_enable(), encouraging clk uses in atomic contexts to switch toclk_enable_atomic.We'd still be able to handle
CLK_ATOMICclocks inclk_enable(), so the enforcement only needs to be one-way.I think the atomic stuff should be the norm through and through - otherwise we're going to end up with problems in drivers where they use the
_atomic()stuff, but the clocks behind are coded to sleep.
Quoted 6 lines
I hate the GPIO APIs for doing this
_cansleepcrap as the decision of whether to use the_cansleepor normal APIs normally can't be made at the time when the API is used, but sometime later. Many people just use the non-_cansleep versions irrespective of the context they're in - which is unnecessarily restrictive - consider what happens if you then have that driver use a GPIO on an I2C peripheral...
I'd prefer it the other way around, too. (That is an atomic gpio_set_value_atomic and a sleeping gpio_set_value.) So if someone uses the wrong one it's more likely that (s)he notices it. Other than that I agree that not having to do this would be preferable.
When applying the clk_enable_atomic stuff to the amba-pl011 driver (see link above), I would just get a different error (clk_enable_atomic would return -ESOMETHING instead of a backtrace about sleeping in atomic context). Hmm, not very useful.
On the other hand fixing the clk API to the sleeping or non-sleeping approach has disadvantages, too:
- sleeping
doesn't allow enabling a clk in atomic context which (e.g. in the case of amba-pl011) provides maximal power saving.
- atomic
some clocks need long to become enabled, so long critical sections are introduced
Having a maxtracer for the clk_enable/disable functions would be great to get some numbers. I volunteer to try to add something like that to the common clk thing when it is merged. (Yes, I still think that merging Jeremy's patches for .38 is good.)
Best regards
Uwe
Signature · 2 lines
Pengutronix e.K. | Uwe Kleine-K?nig | Industrial Linux Solutions | http://www.pengutronix.de/ |
Re: [PATCH 1/2] Add a common struct clk
In reply to Jeremy KerrHi Jeremy,
Quoted 21 lines · Jeremy Kerr
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:
Quoted 9 lines
struct clk {
const struct clk_ops *ops;
unsigned int enable_count;
int flags;
union {
struct mutex mutex;
spinlock_t spinlock;
} lock;
};I'm currently thinking about how to get the locking right with this approach. In the current i.MX implementation we have a global lock which protects the clock enable counter and also the register accesses in the clock code. With the common struct clock we have a lock per clock which only protects the enable counter, so we have to introduce a second lock to protect the register accesses.
The problem comes with nested calls to for example clk_enable which happens when the parent clock gets enabled. currently we do this with clk->enable(clk->parent) which results in an unlocked clk_enable of the parent. With common struct clk we would have to call clk_enable(clk_get_parent(clk) which results in taking the lock a second time.
Any ideas how to solve this?
Sascha
Signature · 4 lines
Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
Re: [PATCH 1/2] Add a common struct clk
Hi Sascha,
Quoted 6 lines
I'm currently thinking about how to get the locking right with this approach. In the current i.MX implementation we have a global lock which protects the clock enable counter and also the register accesses in the clock code. With the common struct clock we have a lock per clock which only protects the enable counter, so we have to introduce a second lock to protect the register accesses.
Are the registers shared between clocks? If not, you can just use the existing per-clk lock. Otherwise it'd be reasonable to add a global register lock, protecting accesses to the shared register set (and *only* protecting these registers).
Quoted 7 lines
The problem comes with nested calls to for example
clk_enablewhich happens when the parent clock gets enabled. currently we do this withclk->enable(clk->parent)which results in an unlockedclk_enableof the parent. With common struct clk we would have to call clk_enable(clk_get_parent(clk) which results in taking the lock a second time.
Any ideas how to solve this?
With the shared register lock, you just need to make sure that you don't recurse to the parent while holding the lock.
For clocks with a shared register set, the general pattern would be something like:
struct clk_foo {
struct clk clk;
u32 enable_reg;
u32 enable_mask;
struct clk *parent;
};static DEFINE_SPINLOCK(clk_foo_register_lock);
/* called with _clk->lock held */
static int clk_foo_enable(struct clk *_clk)
{
struct clk_foo *clk = to_clk_foo(_clk);
int reg, rc;
/* enable parent - will acquire and release the parent's per-clk lock */
rc = clk_enable(clk->parent);
if (rc)
return rc;
/* do register update, under global register lock */
spin_lock(&clk_foo_register_lock);
reg = __raw_readl(clk->reg);
__raw_writel(clk->reg, reg | clk->enable_mask);
spin_unlock(&clk_foo_register_lock);
return 0;
}struct clk_foo_ops = {
.enable = clk_foo_enable;
[...]
};However, because clk_mxc introduces its own set of abstractions, there may be some merging to do here. For my work on mx51, I've done a very basic port:
* changed plat-mxc's struct clk to struct clk_mxc
* embedded struct clk into struct clk_mxc (ie, making it use the common API)
* separated some of the simpler clocks to separate types (eg clk_fixed, clk_pll, clk_ccgr).
The goal here is to separate all of the clocks into their most basic types, leaving no clk_mxc clocks remaining, then the locking should be much simpler.
Cheers,
Jeremy
Re: [PATCH 1/2] Add a common struct clk
Quoted 9 lines · Jeremy Kerr
Hi Sascha,
Quoted 6 lines
I'm currently thinking about how to get the locking right with this approach. In the current i.MX implementation we have a global lock which protects the clock enable counter and also the register accesses in the clock code. With the common struct clock we have a lock per clock which only protects the enable counter, so we have to introduce a second lock to protect the register accesses.
Quoted 4 lines
Are the registers shared between clocks? If not, you can just use the existing per-clk lock. Otherwise it'd be reasonable to add a global register lock, protecting accesses to the shared register set (and *only* protecting these registers).
Yes, the registers are shared between clocks.
Quoted 46 lines
Quoted 8 lines
The problem comes with nested calls to for example
clk_enablewhich happens when the parent clock gets enabled. currently we do this withclk->enable(clk->parent)which results in an unlockedclk_enableof the parent. With common struct clk we would have to call clk_enable(clk_get_parent(clk) which results in taking the lock a second time.
Any ideas how to solve this?With the shared register lock, you just need to make sure that you don't recurse to the parent while holding the lock.
For clocks with a shared register set, the general pattern would be something like:
struct clk_foo { struct clk clk; u32 enable_reg; u32 enable_mask; struct clk *parent; };static
DEFINE_SPINLOCK(clk_foo_register_lock);/* called with
_clk->lockheld */
static intclk_foo_enable(struct clk *_clk){ struct clk_foo *clk = to_clk_foo(_clk); int reg, rc; /* enable parent - will acquire and release the parent's per-clk lock */ rc = clk_enable(clk->parent); if (rc) return rc; /* do register update, under global register lock */ spin_lock(&clk_foo_register_lock); reg = __raw_readl(clk->reg); __raw_writel(clk->reg, reg | clk->enable_mask); spin_unlock(&clk_foo_register_lock); return 0; }
Quoted 4 lines
struct clk_foo_ops = {
.enable = clk_foo_enable;
[...]
};Ok, that should do it. Unfortunately this requires pushing the lock down to the individual functions instead of taking it in some global place.
Quoted 11 lines
However, because
clk_mxcintroduces its own set of abstractions, there may be some merging to do here. For my work on mx51, I've done a very basic port:* changed plat-mxc's struct clk to struct
clk_mxc
* embedded struct clk into structclk_mxc(ie, making it use the common API)
* separated some of the simpler clocks to separate types (egclk_fixed,clk_pll,clk_ccgr).The goal here is to separate all of the clocks into their most basic types, leaving no
clk_mxcclocks remaining, then the locking should be much simpler.
I am aware of your work. In fact, I already did some work upon this. See
git://git.pengutronix.de/git/imx/linux-2.6.git clk-common
and
git://git.pengutronix.de/git/imx/linux-2.6.git clk-common-wip
The first branch converts the whole i.MX architecture to clk-common. The second branch converts i.MX51 into the basic building blocks. See how i.MX51 clock support looks like after the conversion:
The following shows the basic building blocks I used:
This branch must be reworked because the correct locking is missing, but the first branch should be ready for merging once your clk-common patches are merged. I'll post the patches for review soon. I hope it's clear soon that your clk-common patches get merged.
Sascha
Signature · 4 lines
Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
Re: [PATCH 1/2] Add a common struct clk
Quoted 4 lines · Sascha Hauer
This branch must be reworked because the correct locking is missing, but the first branch should be ready for merging once your clk-common patches are merged. I'll post the patches for review soon. I hope it's clear soon that your clk-common patches get merged.
Unless the locking problems can be resolved, the patches aren't ready.
Re: [PATCH 1/2] Add a common struct clk
Hi Russell,
Quoted 4 lines
Unless the locking problems can be resolved, the patches aren't ready.
From what I've seen there's still quite a problem with what kind of lock to use in the clock - mutex or spinlock.
Yes, the clock driver may either use a spinlock or mutex.
However, this exactly the same as the current clock code, my patches do not alter what we currently have.
I do agree that we should define some specific semantics for the clock API with regards to sleeping, and I'll start a new thread about that. But we should definitely separate that issue from the problem of having multiple definitions for struct clk, which is what these patches address.
Cheers,
Jeremy
Re: [PATCH 1/2] Add a common struct clk
Quoted 9 lines · Jeremy Kerr
Hi Russell,
Quoted 4 lines
Unless the locking problems can be resolved, the patches aren't ready.
From what I've seen there's still quite a problem with what kind of lock to use in the clock - mutex or spinlock.
Yes, the clock driver may either use a spinlock or mutex.
Quoted 7 lines
However, this exactly the same as the current clock code, my patches do not alter what we currently have.
I do agree that we should define some specific semantics for the clock API with regards to sleeping, and I'll start a new thread about that. But we should definitely separate that issue from the problem of having multiple definitions for struct clk, which is what these patches address.
Given that each current struct clk implementation makes it's own decisions about how to handle locking, would it not make sense to omit locking entirely? At least as a first step? Let the clock ops implement their own locking. Make enable count management their responsibility too. That's all that the lock protects anyway. The clk_* apis can fall directly through to the ops hooks with no manipulation or locking. The way v3 of the patch worked.
Just having a common struct clk definition (without the locking) is valuable on its own to get closer to supporting multiple platforms with a single kernel on ARM. It certainly shouldn't be worse that the current state. Locking consolidation can be implemented in follow-on patches.
g.
Re: [PATCH 1/2] Add a common struct clk
Quoted 18 lines · Grant Likely
Quoted 9 lines · Jeremy Kerr
Hi Russell,
Quoted 4 lines
Unless the locking problems can be resolved, the patches aren't ready.
From what I've seen there's still quite a problem with what kind of lock to use in the clock - mutex or spinlock.
Yes, the clock driver may either use a spinlock or mutex.
Quoted 7 lines
However, this exactly the same as the current clock code, my patches do not alter what we currently have.
I do agree that we should define some specific semantics for the clock API with regards to sleeping, and I'll start a new thread about that. But we should definitely separate that issue from the problem of having multiple definitions for struct clk, which is what these patches address.
Quoted 7 lines
Given that each current struct clk implementation makes it's own decisions about how to handle locking, would it not make sense to omit locking entirely? At least as a first step? Let the clock ops implement their own locking. Make enable count management their responsibility too. That's all that the lock protects anyway. The clk_* apis can fall directly through to the ops hooks with no manipulation or locking. The way v3 of the patch worked.
This doesn't really work in a generic API because the call sites need to know whether it safe to call clk_enable/disable, etc from a non-sleepable context. This has essentially the same problems as using a union with both a mutex and a spinlock.
That said, although we are aiming for a generic clock API, it's usage typically isn't. Most of the users of the clock API are machine/platform specific drivers and so they can make assumptions about the implementation of the clock API calls. We currently do have a generic set of clock calls which do not define rules about calling from atomic context. We have a number of drivers, for several platforms, using the clk_enable/disable calls. Some platforms are using sleeping clocks and others are using atomic clocks, but because the _usage_ of the API is largely platform specific it all hangs together.
This is a bit ugly in practice. It's hardly desirable to have an API which looks generic, but in reality is platform/machine specific. I'm guessing that a large benefit of having a unified API and well defined rules about whether clock API calls may sleep or not allows the usage of the clock API to become more generic.
I agree with Russell that the best short term approach is to create two clock APIs, one for clocks which are atomic and the other for clocks which need to sleep. If nothing else this at least allows the rules about calling context to nailed down.
~Ryan
Signature · 7 lines
Bluewater Systems Ltd - ARM Technology Solution Centre Ryan Mallon 5 Amuri Park, 404 Barbadoes St [email protected] 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
Re: [PATCH 1/2] Add a common struct clk
Quoted 27 lines · Ryan Mallon
Quoted 18 lines · Grant Likely
Quoted 9 lines · Jeremy Kerr
Hi Russell,
Quoted 4 lines
Unless the locking problems can be resolved, the patches aren't ready.
From what I've seen there's still quite a problem with what kind of lock to use in the clock - mutex or spinlock.
Yes, the clock driver may either use a spinlock or mutex.
Quoted 7 lines
However, this exactly the same as the current clock code, my patches do not alter what we currently have.
I do agree that we should define some specific semantics for the clock API with regards to sleeping, and I'll start a new thread about that. But we should definitely separate that issue from the problem of having multiple definitions for struct clk, which is what these patches address.
Quoted 7 lines
Given that each current struct clk implementation makes it's own decisions about how to handle locking, would it not make sense to omit locking entirely? At least as a first step? Let the clock ops implement their own locking. Make enable count management their responsibility too. That's all that the lock protects anyway. The clk_* apis can fall directly through to the ops hooks with no manipulation or locking. The way v3 of the patch worked.
Quoted 4 lines
This doesn't really work in a generic API because the call sites need to know whether it safe to call clk_enable/disable, etc from a non-sleepable context. This has essentially the same problems as using a union with both a mutex and a spinlock.
Note that this is the current status quo, too. clk_enable on imx sleeps, clk_enable on at91 doesn't. I think we all agree we don't want to change that during the unifying step. So the common struct clk might not solve all problems, but it's not worse than the state now.
Quoted 16 lines
That said, although we are aiming for a generic clock API, it's usage typically isn't. Most of the users of the clock API are machine/platform specific drivers and so they can make assumptions about the implementation of the clock API calls. We currently do have a generic set of clock calls which do not define rules about calling from atomic context. We have a number of drivers, for several platforms, using the clk_enable/disable calls. Some platforms are using sleeping clocks and others are using atomic clocks, but because the _usage_ of the API is largely platform specific it all hangs together.
This is a bit ugly in practice. It's hardly desirable to have an API which looks generic, but in reality is platform/machine specific. I'm guessing that a large benefit of having a unified API and well defined rules about whether clock API calls may sleep or not allows the usage of the clock API to become more generic.
Quoted 4 lines
I agree with Russell that the best short term approach is to create two clock APIs, one for clocks which are atomic and the other for clocks which need to sleep. If nothing else this at least allows the rules about calling context to nailed down.
For me this sounds like code duplication if everything is identical only spinlocks are substituted by mutexes. What do you think about my suggestion to use a Kconfig symbol that is selected by platforms (e.g. COMMON_CLK_SLEEPING) and then use:
#ifdef CONFIG_COMMON_CLK_SLEEPING ... mutex stuff ... #else ... spinlock stuff ... #endif
?
Best regards
Uwe
Signature · 2 lines
Pengutronix e.K. | Uwe Kleine-K?nig | Industrial Linux Solutions | http://www.pengutronix.de/ |
Re: [PATCH 1/2] Add a common struct clk
Quoted 28 lines · Uwe Kleine-König
Quoted 27 lines · Ryan Mallon
Quoted 25 lines · Grant Likely
Quoted 9 lines · Jeremy Kerr
Hi Russell,
Quoted 4 lines
Unless the locking problems can be resolved, the patches aren't ready.
From what I've seen there's still quite a problem with what kind of lock to use in the clock - mutex or spinlock.
Yes, the clock driver may either use a spinlock or mutex.
Quoted 7 lines
However, this exactly the same as the current clock code, my patches do not alter what we currently have.
I do agree that we should define some specific semantics for the clock API with regards to sleeping, and I'll start a new thread about that. But we should definitely separate that issue from the problem of having multiple definitions for struct clk, which is what these patches address.
Given that each current struct clk implementation makes it's own decisions about how to handle locking, would it not make sense to omit locking entirely? At least as a first step? Let the clock ops implement their own locking. Make enable count management their responsibility too. That's all that the lock protects anyway. The clk_* apis can fall directly through to the ops hooks with no manipulation or locking. The way v3 of the patch worked.
Quoted 8 lines
Quoted 4 lines
This doesn't really work in a generic API because the call sites need to know whether it safe to call clk_enable/disable, etc from a non-sleepable context. This has essentially the same problems as using a union with both a mutex and a spinlock.
Note that this is the current status quo, too.
clk_enableon imx sleeps,clk_enableon at91 doesn't. I think we all agree we don't want to change that during the unifying step. So the common struct clk might not solve all problems, but it's not worse than the state now.
Yes, I pointed this out. I think we have ended up in this ugly situation because the clock API calls never defined rules about calling context and so some platforms have ended up needing to sleep in the calls, while drivers for other platforms assume that the clock API calls can be safely called from atomic context.
My point, and I think Russell's point, is that if you are going to have a truly generic, unified API we don't want this sort of mix and match. The clock API functions should have clearly defined rules about what context they can be called from and each platform/machine implementation of the API should obey those rules.
Partly this is about code clarity. At the moment, to determine if a clk_enable call might sleep I need to go and look at the implementation for the platform I am on. There are drivers, such as the amba-pl010 serial driver, which can be used on multiple platforms. To verify that the clock API call sites are correct you need to check each platform that the driver runs on. By having an explicit separation of the clock implementations which are atomic and those which may need to sleep these problems disappear.
For the current patch series, the documentation for clk_enable would need include this.
"This function may or may not be safe to call from atomic context
depending on the platform you are on."
I don't think we have too many other generic APIs in the kernel which have this kind of loose documentation.
Quoted 25 lines
Quoted 16 lines
That said, although we are aiming for a generic clock API, it's usage typically isn't. Most of the users of the clock API are machine/platform specific drivers and so they can make assumptions about the implementation of the clock API calls. We currently do have a generic set of clock calls which do not define rules about calling from atomic context. We have a number of drivers, for several platforms, using the clk_enable/disable calls. Some platforms are using sleeping clocks and others are using atomic clocks, but because the _usage_ of the API is largely platform specific it all hangs together.
This is a bit ugly in practice. It's hardly desirable to have an API which looks generic, but in reality is platform/machine specific. I'm guessing that a large benefit of having a unified API and well defined rules about whether clock API calls may sleep or not allows the usage of the clock API to become more generic.
Quoted 4 lines
I agree with Russell that the best short term approach is to create two clock APIs, one for clocks which are atomic and the other for clocks which need to sleep. If nothing else this at least allows the rules about calling context to nailed down.
For me this sounds like code duplication if everything is identical only spinlocks are substituted by mutexes. What do you think about my suggestion to use a
Kconfigsymbol that is selected by platforms (e.g.COMMON_CLK_SLEEPING) and then use:
Quoted 5 lines
#ifdef CONFIG_COMMON_CLK_SLEEPING ... mutex stuff ... #else ... spinlock stuff ... #endif
You still have the problem that cannot make any assumptions about calling context for calls to the clock API. The point is that the semantics about calling context for a generic clock API are currently too loose. Part of consolidating the clock implementations should be to fix that. Russell's suggestion to reduce to two implementations (from the 30+ we have now) will have a net reduction in code, but will also clarify which platforms/drivers are using sleeping clocks.
~Ryan
Signature · 7 lines
Bluewater Systems Ltd - ARM Technology Solution Centre Ryan Mallon 5 Amuri Park, 404 Barbadoes St [email protected] 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
Re: [PATCH 1/2] Add a common struct clk
In reply to Jeremy KerrQuoted 19 lines · Jeremy Kerr
kernel/clk.c new file +13
-0@@ -0,0 +1,102 @@ +/* +* Copyright (C) 2010 Canonical Ltd <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +* Standard functionality for the common clock API. +*/ + +#include <linux/clk.h> +#include <linux/module.h> +
...
kernel/clk.c line 94
Quoted 8 lines
kernel/clk.c new file +8
-0+ +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);
The i.MX clk implementation disables the old parent if clk is enabled and enables the new parent if clk is enabled (modulo bugs). Shouldn't we do this here aswell? Otherwise at least the enable_count of both the old and the new parent will be wrong after calling clk_set_parent for an enabled clk.
I thought about returning -EBUSY if clk_set_parent is called for an enabled clk, but this way we could never reparent the cpu clock which I think is done in the Freescale BSP for power saving.
Sascha
Signature · 4 lines
Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
Re: [PATCH 1/2] Add a common struct clk
Hi Sascha,
Quoted 3 lines
The i.MX clk implementation disables the old parent if clk is enabled and enables the new parent if clk is enabled (modulo bugs). Shouldn't we do this here aswell?
Sounds reasonable, yes.
Quoted 3 lines
I thought about returning
-EBUSYifclk_set_parentis called for an enabled clk, but this way we could never reparent the cpu clock which I think is done in the Freescale BSP for power saving.
I think that the possibility for changing the parent really depends on the implementation; in some cases we may want to disallow it, in others it might be fine.
Related: do we really need globally-accessible clk_{get,set}_parent in the clk API? For cases where we need to set the parent, we probably need details about the platform clock configuration (eg, which clocks are possible parents). In this case, we could just call into the clock driver directly.
Cheers,
Jeremy
Re: [PATCH 1/2] Add a common struct clk
Quoted 12 lines · Jeremy Kerr
Hi Sascha,
Quoted 3 lines
The i.MX clk implementation disables the old parent if clk is enabled and enables the new parent if clk is enabled (modulo bugs). Shouldn't we do this here aswell?
Sounds reasonable, yes.
Quoted 3 lines
I thought about returning
-EBUSYifclk_set_parentis called for an enabled clk, but this way we could never reparent the cpu clock which I think is done in the Freescale BSP for power saving.
Quoted 8 lines
I think that the possibility for changing the parent really depends on the implementation; in some cases we may want to disallow it, in others it might be fine.
Related: do we really need globally-accessible clk_{get,set}_parent in the clk API? For cases where we need to set the parent, we probably need details about the platform clock configuration (eg, which clocks are possible parents). In this case, we could just call into the clock driver directly.
I agree that drivers have no business calling clk_{get,set}_parent, this is purely platform specific.
Sascha
Signature · 4 lines
Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
Re: [PATCH 1/2] Add a common struct clk
Quoted 17 lines · Sascha Hauer
Quoted 16 lines · Jeremy Kerr
Hi Sascha,
Quoted 3 lines
The i.MX clk implementation disables the old parent if clk is enabled and enables the new parent if clk is enabled (modulo bugs). Shouldn't we do this here aswell?
Sounds reasonable, yes.
Quoted 3 lines
I thought about returning
-EBUSYifclk_set_parentis called for an enabled clk, but this way we could never reparent the cpu clock which I think is done in the Freescale BSP for power saving.I think that the possibility for changing the parent really depends on the implementation; in some cases we may want to disallow it, in others it might be fine.
Quoted 8 lines
Quoted 4 lines
Related: do we really need globally-accessible clk_{get,set}_parent in the clk API? For cases where we need to set the parent, we probably need details about the platform clock configuration (eg, which clocks are possible parents). In this case, we could just call into the clock driver directly.
I agree that drivers have no business calling clk_{get,set}_parent, this is purely platform specific.
Do you guys even bother to grep the kernel for users of the API before coming up with arbitrary policy?
There are plenty of cases where clocks are allocated dynamically by driver code that in turn can be set up as a parent for other dynamically allocated clocks. This has not a damn thing to do with platform code and everything to do with the clock circuitry of the device or IP block in question.
If you actually want this API unification thing to not be completely stillborn, I recommend focusing on how people are actually using the API today (especially the parts that are used by the majority of users, not the one you happened to base your implementation off of), and then trying to push your interpretation or roadmap for the API at a later stage. This way the former has a chance of getting upstream without the latter completely derailing it.
Re: [PATCH 1/2] Add a common struct clk
Quoted 23 lines · Paul Mundt
Quoted 22 lines · Sascha Hauer
Quoted 20 lines · Jeremy Kerr
Hi Sascha,
Quoted 3 lines
The i.MX clk implementation disables the old parent if clk is enabled and enables the new parent if clk is enabled (modulo bugs). Shouldn't we do this here aswell?
Sounds reasonable, yes.
Quoted 3 lines
I thought about returning
-EBUSYifclk_set_parentis called for an enabled clk, but this way we could never reparent the cpu clock which I think is done in the Freescale BSP for power saving.I think that the possibility for changing the parent really depends on the implementation; in some cases we may want to disallow it, in others it might be fine.
Related: do we really need globally-accessible clk_{get,set}_parent in the clk API? For cases where we need to set the parent, we probably need details about the platform clock configuration (eg, which clocks are possible parents). In this case, we could just call into the clock driver directly.
Quoted 5 lines
Quoted 3 lines
I agree that drivers have no business calling clk_{get,set}_parent, this is purely platform specific.
Do you guys even bother to grep the kernel for users of the API before coming up with arbitrary policy?
Actually I did bother to grep the kernel and I came up with these results:
drivers/video/omap2/dss/dss.c:219: dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));drivers/video/omap2/dss/dss.c:312: prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
drivers/video/omap2/dss/dss.c:325: prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); drivers/video/omap2/dss/dss.c:344: prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); drivers/video/omap2/dss/dss.c:359: return clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
drivers/video/sh_mobile_hdmi.c:716: else if (clk_get_parent(hdmi->hdmi_clk))drivers/video/sh_mobile_hdmi.c:717: *parent_rate = clk_get_rate(clk_get_parent(hdmi->hdmi_clk));drivers/video/sh_mobile_hdmi.c:1089: if (parent_rate && clk_get_parent(hdmi->hdmi_clk)) {drivers/video/sh_mobile_hdmi.c:1090: ret = clk_set_rate(clk_get_parent(hdmi->hdmi_clk), parent_rate);drivers/usb/host/ehci-omap.c:405: ret = clk_set_parent(omap->utmi_p1_fck,drivers/usb/host/ehci-omap.c:435: ret = clk_set_parent(omap->utmi_p2_fck,
In case of the omap2 dss driver the parent rate seems to be used for calculating valid clock frequencies based on the knowledge that between the parent clock and the device clock is a divider with some fixed values. It's arguable whether this is a valid use of the clock API.
In the sh mobile hdmi driver both the device clock and the parent clock seem to be adjustable and the driver tries to get the best possible rate by adjusting both clocks. I think this could better be abstracted in the clock framework.
The omap ehci driver is the only one I found which uses clk_set_parent, but it uses detailed platform knowledge to do so. Is it really necessary to put this into a driver?
Quoted 7 lines
There are plenty of cases where clocks are allocated dynamically by driver code that in turn can be set up as a parent for other dynamically allocated clocks. This has not a damn thing to do with platform code and everything to do with the clock circuitry of the device or IP block in question.
Quoted 7 lines
If you actually want this API unification thing to not be completely stillborn, I recommend focusing on how people are actually using the API today (especially the parts that are used by the majority of users, not the one you happened to base your implementation off of), and then trying to push your interpretation or roadmap for the API at a later stage. This way the former has a chance of getting upstream without the latter completely derailing it.
The majority of users do not use clk_{get,set}_parent at all. And it's really questionable whether drivers should know anything about the layout of the clock tree. I'm pretty sure that these are the code pieces where there will be a if_soc_rev(x) around it once the next incarnation of a SoC comes out.
Saascha
Signature · 4 lines
Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
Re: [PATCH 1/2] Add a common struct clk
Quoted 12 lines · Sascha Hauer
Quoted 2 lines · Paul Mundt
Do you guys even bother to grep the kernel for users of the API before coming up with arbitrary policy?
Actually I did bother to grep the kernel and I came up with these results:
drivers/video/omap2/dss/dss.c:219:dpll4_ck_rate= clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));drivers/video/omap2/dss/dss.c:312: prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));drivers/video/omap2/dss/dss.c:325: prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); drivers/video/omap2/dss/dss.c:344: prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); drivers/video/omap2/dss/dss.c:359: return clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
Quoted 7 lines
drivers/video/sh_mobile_hdmi.c:716: else if (clk_get_parent(hdmi->hdmi_clk))drivers/video/sh_mobile_hdmi.c:717:*parent_rate= clk_get_rate(clk_get_parent(hdmi->hdmi_clk));drivers/video/sh_mobile_hdmi.c:1089: if (parent_rate&&clk_get_parent(hdmi->hdmi_clk)) {drivers/video/sh_mobile_hdmi.c:1090: ret =clk_set_rate(clk_get_parent(hdmi->hdmi_clk), parent_rate);drivers/usb/host/ehci-omap.c:405: ret = clk_set_parent(omap->utmi_p1_fck,drivers/usb/host/ehci-omap.c:435: ret = clk_set_parent(omap->utmi_p2_fck,
Then I recommend you grep harder. There are more drivers than the ones that simply live in drivers/.
Quoted 6 lines
Quoted 5 lines
There are plenty of cases where clocks are allocated dynamically by driver code that in turn can be set up as a parent for other dynamically allocated clocks. This has not a damn thing to do with platform code and everything to do with the clock circuitry of the device or IP block in question.
Quoted 6 lines
The majority of users do not use clk_{get,set}_parent at all. And it's really questionable whether drivers should know anything about the layout of the clock tree. I'm pretty sure that these are the code pieces where there will be a
if_soc_rev(x)around it once the next incarnation of a SoC comes out.
It's not questionable in the least, you're simply dealing with cases where you personally haven't had a need to do so and are attempting to project that as a policy. I'm getting pretty tired of this.
We have many IP blocks that can use external clocks or drive their own clock circuitry, in which case the internal clocks are parented by a parent clock that is likewise also dynamically created. Your lack of imagination is really not my concern, and again, this has nothing to do with the SoC.
Re: [PATCH 1/2] Add a common struct clk
In reply to Jeremy KerrQuoted 6 lines · Jeremy Kerr
--- arch/Kconfig | 3 include/linux/clk.h | 164 +++++++++++++++++++++++++++++++++++++++++--- kernel/Makefile | 1 kernel/clk.c | 102 +++++++++++++++++++++++++++ 4 files changed, 261 insertions(+), 9 deletions(-)
As we already have drivers/clk/, does it really make sense to spread this far and wide around the kernel tree by putting it in kernel/ ?
PATCH 2/2 clk: Generic support for fixed-rate clocks
In reply to Jeremy KerrSince most platforms will need a fixed-rate clock, add one. This will also serve as a basic example of an implementation of struct clk.
--- include/linux/clk.h | 16 ++++++++++++++++ kernel/clk.c | 14 ++++++++++++++ 2 files changed, 30 insertions(+)
include/linux/clk.h +16 -0
@@ -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 */ /*
kernel/clk.c +14 -0
@@ -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);
cover Common struct clk implementation, v10
In reply to Jeremy KerrSorry about the repost, folks - lkml bounced my badly-encoded headers.
Cheers,
Jeremy
cover Common struct clk implementation, v10
In reply to Jeremy KerrQuoted 7 lines · Jeremy Kerr
Hi all,
These patches are an attempt to allow platforms to share clock code. At present, the definitions of 'struct clk' are local to platform code, which makes allocating and initialising cross-platform clock sources difficult, and makes it impossible to compile a single image containing support for two ARM platforms with different struct clks.
no, it doesn't actually. you could do run-time link and select the right arch support.
cover Common struct clk implementation, v10
Hi Ben,
Quoted 11 lines · Ben Dooks
Quoted 7 lines · Jeremy Kerr
Hi all,
These patches are an attempt to allow platforms to share clock code. At present, the definitions of 'struct clk' are local to platform code, which makes allocating and initialising cross-platform clock sources difficult, and makes it impossible to compile a single image containing support for two ARM platforms with different struct clks.
no, it doesn't actually. you could do run-time link and select the right arch support.
does that mean you're against the patch set?
Best regards
Uwe
Signature · 2 lines
Pengutronix e.K. | Uwe Kleine-K?nig | Industrial Linux Solutions | http://www.pengutronix.de/ |