ARM: TI SoC clock DT conversion
Subsystems (8)
v12 cover ARM: TI SoC clock DT conversion
Hi,
Hopefully final post of this series. At least this is going to be the last post this year as I will be going to x-mas vacation and won't be back before Jan 2nd. This time I just sent the patches that have changes in them, the missing ones are exactly the same as in v11.
Changes done:
- most of the patches:
* Some cosmetic documentation fixes
- patch 06:
* Changed register pointer types from 'u32 __iomem *' to 'void __iomem *'
- patch 07,08,09:
* Added check for clk->ll_ops being NULL (happens with statically built clock data), fixes the boot time crash issue noticed by Tony
- patch 11:
* Moved __clk_of_table extern declaration to clk-provider.h header file... Got flamed about this enough times now. :)
* Type for the declaration changed also from array to single entry, and address for this used in code. This prevents compile time error:
"array type has incomplete element type". Can't use pointer here either as this messes the address of the table.
* ti_clk_retry_init() now has int return type, and checks for kzalloc failure
- patch 12, 14, 23:
* Added cleanup in case ti_clk_retry_init() fails
- patch 17:
* Fixed potential memory leak in failed init detected by sparse
- patch 18:
* Modified commit message to add some details about clockdomains
- patch 43:
* Changed register pointer types from 'u32 *' to 'void __iomem *'
Testing done:
- omap3-beagle: boot, suspend/resume (ret), suspend/resume (off)
- omap4-panda-es: boot, suspend/resume (ret)
- omap5-uevm: boot
- am335x-bone: boot
- dra7-evm: boot
Branches available at https://github.com/t-kristo/linux-pm.git:
- branch: 3.13-rc4-dt-clks-v12 : contains everything, shall me merged last
- branch: 3.13-rc4-dt-clks-v12-for-mike : drivers/clk changes
- branch: 3.13-rc4-dt-clks-v11-for-benoit : DT data only (from v11, no changes)
-Tero
PATCH v12 1/49 clk: add support for registering clocks from description
From: Mike Turquette <[email protected]>
clk_register_desc is the primary interface for populating the clock tree with new clock nodes. In time, this will replace the various hardware-specific registration functions (e.g. clk_register_gate).
--- drivers/clk/clk.c | 71 ++++++++++++++++++++++++++++++++++++++++++ include/linux/clk-provider.h | 22 +++++++++++++ 2 files changed, 93 insertions(+)
drivers/clk/clk.c +71 -0
@@ -1905,6 +1905,77 @@ fail_out:EXPORT_SYMBOL_GPL (clk_register);/** +* clk_register_desc - register a new clock from its description +* @dev: device that is registering this clock +* @desc: description of the clock, may be __initdata or otherwise discarded +* +* clk_register_desc is the primary interface for populating the clock tree +* with new clock nodes. In time it will replace the various hardware-specific +* registration functions (e.g. clk_register_gate). clk_register_desc returns a +* pointer to the newly allocated struct clk which is an opaque cookie. Drivers +* must not dereference it except to check with IS_ERR. +*/ +struct clk *clk_register_desc (struct device *dev,struct clk_desc *desc) +{ +int ret, i; +struct clk *clk; + + clk =kzalloc (sizeof (*clk),GFP_KERNEL ); + +if (!clk) +return ERR_PTR (-ENOMEM ); + + clk->hw = desc->register_func (dev, desc); + clk->hw->clk = clk; + +/* _clk_register */ + clk->name =kstrdup (desc->name,GFP_KERNEL ); +if (!clk->name) { + ret = -ENOMEM ; + goto fail_name; + } + + clk->ops = desc->ops; + clk->flags = desc->flags; + clk->num_parents = desc->num_parents; + +/* allocate local copy in case parent_names is __initdata */ + clk->parent_names =kcalloc (clk->num_parents,sizeof (char *), +GFP_KERNEL ); + +if (!clk->parent_names) { + ret = -ENOMEM ; + goto fail_parent_names; + } + +/* copy each string name in case parent_names is __initdata */ +for (i =0 ; i < clk->num_parents; i++) { + clk->parent_names[i] =kstrdup (desc->parent_names[i], +GFP_KERNEL ); + +if (!clk->parent_names[i]) { + ret = -ENOMEM ; + goto fail_parent_names_copy; + } + } + + ret =__clk_init (dev, clk); + +if (!ret) +return clk; + +fail_parent_names_copy: +while (--i >=0 ) +kfree (clk->parent_names[i]); +kfree (clk->parent_names); +fail_parent_names: +kfree (clk->name); +fail_name: +kfree (clk); +return ERR_PTR (ret); +} + +/** * clk_unregister - unregister a currently registered clock * @clk: clock to unregister *
include/linux/clk-provider.h +22 -0
@@ -161,6 +161,27 @@ struct clk_init_data { };/** +* struct clk_desc - clock init descriptor for providing init time parameters +* for a clock. +* @name: clock name +* @ops: clock ops +* @parent_names: array of string names for all possible parents +* @num_parents: number of possible parents +* @flags: framework-level hints and quirks +* @register_func: function for parsing the clock descriptor and providing +* ready-to-register clk_hw +*/ +struct clk_desc { +const char *name; +const struct clk_ops *ops; +const char **parent_names; +u8 num_parents; +unsigned long flags; +struct clk_hw *(*register_func)(struct device *dev, +struct clk_desc *desc); +}; + +/** * struct clk_hw - handle for traversing from a struct clk to its corresponding * hardware-specific structure. struct clk_hw should be declared within struct * clk_foo and then referenced by the struct clk instance that uses struct
@@ -419,6 +440,7 @@ struct clk *clk_register_composite(struct device *dev, const char *name,* error code; drivers must test for an error code after calling clk_register. */ struct clk *clk_register (struct device *dev,struct clk_hw *hw); +struct clk *clk_register_desc (struct device *dev,struct clk_desc *desc);struct clk *devm_clk_register (struct device *dev,struct clk_hw *hw);void clk_unregister (struct clk *clk);
Signature · 1 line
1.7.9.5
PATCH v12 3/49 clk: divider: add support for registering divider clock from descriptor
In reply to Tero KristoNew clk_register_desc() call can be used to register this clock type now.
--- drivers/clk/clk-divider.c | 34 ++++++++++++++++++++++++++++++++++ include/linux/clk-provider.h | 22 ++++++++++++++++++++++ 2 files changed, 56 insertions(+)
drivers/clk/clk-divider.c +34 -0
@@ -28,8 +28,12 @@* parent - fixed parent. No clk_set_parent support */ +/* resolve struct clk_divider from inner struct clk_hw member */ #define to_clk_divider (_hw) container_of(_hw, struct clk_divider, hw) +/* resolve struct clk_divider_desc from inner struct clk_desc member */ +#define to_hw_desc (_desc) container_of(_desc, struct clk_divider_desc, desc) +#define div_mask (d) ((1 << ((d)->width)) - 1)static unsigned int _get_table_maxdiv (const struct clk_div_table *table)
@@ -343,3 +347,33 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name, width, clk_divider_flags, table, lock); }EXPORT_SYMBOL_GPL (clk_register_divider_table); + +struct clk_hw *clk_register_divider_desc (struct device *dev, +struct clk_desc *desc) +{ +struct clk_divider *divider; +struct clk_divider_desc *hw_desc; + + hw_desc =to_hw_desc (desc); + +/* allocate divider clock */ + divider =kzalloc (sizeof (*divider),GFP_KERNEL ); +if (!divider) +return ERR_PTR (-ENOMEM ); + +/* populate struct clk_divider assignments */ + divider->reg = hw_desc->reg; + divider->shift = hw_desc->shift; + divider->width = hw_desc->width; + divider->flags = hw_desc->flags; + divider->table = hw_desc->table; + divider->lock = hw_desc->lock; + +if (!desc->ops) + desc->ops = &clk_divider_ops; + + desc->flags |=CLK_IS_BASIC ; + +return ÷r->hw; +} +EXPORT_SYMBOL_GPL (clk_register_divider_desc);
include/linux/clk-provider.h +22 -0
@@ -322,11 +322,33 @@ struct clk_divider {spinlock_t *lock; }; +/** +* struct clk_divider_desc - init descriptor for divider clock +* @desc: handle between common and hardware-specific interfaces +* @reg: register containing the divider +* @shift: shift to the divider bit field +* @width: width of the divider bit field +* @table: array of value/divider pairs, last entry should have div = 0 +* @lock: register lock +*/ +struct clk_divider_desc { +struct clk_desc desc; +void __iomem *reg; +u8 shift; +u8 width; +u8 flags; +const struct clk_div_table *table; +spinlock_t *lock; +}; +#define CLK_DIVIDER_ONE_BASED BIT(0)#define CLK_DIVIDER_POWER_OF_TWO BIT(1)#define CLK_DIVIDER_ALLOW_ZERO BIT(2)#define CLK_DIVIDER_HIWORD_MASK BIT(3) +struct clk_hw *clk_register_divider_desc (struct device *dev, +struct clk_desc *desc); +extern const struct clk_ops clk_divider_ops; struct clk *clk_register_divider(struct device *dev, const char *name, const char *parent_name, unsigned long flags,
Signature · 1 line
1.7.9.5
PATCH v12 4/49 clk: mux: add support for registering mux clock from descriptor
In reply to Tero KristoNew clk_register_desc() call can be used to register this clock type now.
--- drivers/clk/clk-mux.c | 37 +++++++++++++++++++++++++++++++++++++ include/linux/clk-provider.h | 20 ++++++++++++++++++++ 2 files changed, 57 insertions(+)
drivers/clk/clk-mux.c +37 -0
@@ -27,8 +27,12 @@* parent - parent is adjustable through clk_set_parent */ +/* resolve struct clk_mux from inner struct clk_hw member */ #define to_clk_mux (_hw) container_of(_hw, struct clk_mux, hw) +/* resolve struct clk_mux_desc from inner struct clk_desc member */ +#define to_hw_desc (_desc) container_of(_desc, struct clk_mux_desc, desc) +static u8 clk_mux_get_parent (struct clk_hw *hw) {struct clk_mux *mux =to_clk_mux (hw);
@@ -177,3 +181,36 @@ struct clk *clk_register_mux(struct device *dev, const char *name, NULL, lock); }EXPORT_SYMBOL_GPL (clk_register_mux); + +struct clk_hw *clk_register_mux_desc (struct device *dev,struct clk_desc *desc) +{ +struct clk_mux *mux; +struct clk_mux_desc *hw_desc; + + hw_desc =to_hw_desc (desc); + +/* allocate mux clock */ + mux =kzalloc (sizeof (*mux),GFP_KERNEL ); +if (!mux) +return ERR_PTR (-ENOMEM ); + +/* populate struct clk_mux assignments */ + mux->reg = hw_desc->reg; + mux->table = hw_desc->table; + mux->mask = hw_desc->mask; + mux->shift = hw_desc->shift; + mux->flags = hw_desc->flags; + mux->lock = hw_desc->lock; + +if (!desc->ops) { +if (mux->flags &CLK_MUX_READ_ONLY ) + desc->ops = &clk_mux_ro_ops; +else + desc->ops = &clk_mux_ops; + } + + desc->flags |=CLK_IS_BASIC ; + +return &mux->hw; +} +EXPORT_SYMBOL_GPL (clk_register_mux_desc);
include/linux/clk-provider.h +20 -0
@@ -391,6 +391,25 @@ struct clk_mux {spinlock_t *lock; }; +/** +* struct clk_mux_desc - init descriptor for multiplexer clock +* @desc: handle between common and hardware-specific interfaces +* @reg: register controlling multiplexer +* @shift: shift to multiplexer bit field +* @width: width of multiplexer bit field +* @flags: hardware-specific flags +* @lock: register lock +*/ +struct clk_mux_desc { +struct clk_desc desc; +void __iomem *reg; +u32 *table; +u32 mask; +u8 shift; +u8 flags; +spinlock_t *lock; +}; +#define CLK_MUX_INDEX_ONE BIT(0)#define CLK_MUX_INDEX_BIT BIT(1)#define CLK_MUX_HIWORD_MASK BIT(2)
@@ -399,6 +418,7 @@ struct clk_mux {extern const struct clk_ops clk_mux_ops;extern const struct clk_ops clk_mux_ro_ops; +struct clk_hw *clk_register_mux_desc (struct device *dev,struct clk_desc *desc); struct clk *clk_register_mux(struct device *dev, const char *name, const char **parent_names, u8 num_parents, unsigned long flags, void __iomem *reg, u8 shift, u8 width,
Signature · 1 line
1.7.9.5
PATCH v12 5/49 clk: gate: add support for registering gate clock from descriptor
In reply to Tero KristoNew clk_register_desc() call can be used to register this clock type now.
--- drivers/clk/clk-gate.c | 31 +++++++++++++++++++++++++++++++ include/linux/clk-provider.h | 18 ++++++++++++++++++ 2 files changed, 49 insertions(+)
drivers/clk/clk-gate.c +31 -0
@@ -26,8 +26,12 @@* parent - fixed parent. No clk_set_parent support */ +/* resolve struct clk_gate from inner struct clk_hw member */ #define to_clk_gate (_hw) container_of(_hw, struct clk_gate, hw) +/* resolve struct clk_gate_desc from inner struct clk_desc member */ +#define to_hw_desc (_desc) container_of(_desc, struct clk_gate_desc, desc) +/* * It works on following logic: *
@@ -162,3 +166,30 @@ struct clk *clk_register_gate(struct device *dev, const char *name,return clk; }EXPORT_SYMBOL_GPL (clk_register_gate); + +struct clk_hw *clk_register_gate_desc (struct device *dev,struct clk_desc *desc) +{ +struct clk_gate *gate; +struct clk_gate_desc *hw_desc; + + hw_desc =to_hw_desc (desc); + +/* allocate mux clock */ + gate =kzalloc (sizeof (*gate),GFP_KERNEL ); +if (!gate) +return ERR_PTR (-ENOMEM ); + +/* populate struct clk_gate assignments */ + gate->reg = hw_desc->reg; + gate->bit_idx = hw_desc->bit_idx; + gate->flags = hw_desc->flags; + gate->lock = hw_desc->lock; + +if (!desc->ops) + desc->ops = &clk_gate_ops; + + desc->flags |=CLK_IS_BASIC ; + +return &gate->hw; +} +EXPORT_SYMBOL_GPL (clk_register_gate_desc);
include/linux/clk-provider.h +18 -0
@@ -268,10 +268,28 @@ struct clk_gate {spinlock_t *lock; }; +/** +* struct clk_gate_desc - init descriptor for gating clock +* @desc: handle between common and hardware-specific interfaces +* @reg: register controlling gate +* @bit_idx: single bit controlling gate +* @flags: hardware-specific flags +* @lock: register lock +*/ +struct clk_gate_desc { +struct clk_desc desc; +void __iomem *reg; +u8 bit_idx; +u8 flags; +spinlock_t *lock; +}; +#define CLK_GATE_SET_TO_DISABLE BIT(0)#define CLK_GATE_HIWORD_MASK BIT(1)extern const struct clk_ops clk_gate_ops; +struct clk_hw *clk_register_gate_desc (struct device *dev, +struct clk_desc *desc); struct clk *clk_register_gate(struct device *dev, const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u8 bit_idx,
Signature · 1 line
1.7.9.5
PATCH v12 6/49 clk: add support for low level register ops
In reply to Tero KristoLow level register ops are needed for providing SoC or IP block specific access routines to clock registers. Subsequent patches add support for the low level ops for the individual clock drivers.
--- drivers/clk/clk.c | 28 ++++++++++++++++++++++++++++ include/linux/clk-provider.h | 17 +++++++++++++++++ 2 files changed, 45 insertions(+)
drivers/clk/clk.c +28 -0
@@ -34,6 +34,34 @@ static HLIST_HEAD(clk_root_list);static HLIST_HEAD (clk_orphan_list);static LIST_HEAD (clk_notifier_list); +/** +* clk_readl_default - default clock register read support function +* @reg: register to read +* +* Default implementation for reading a clock register. +*/ +static u32 clk_readl_default (void __iomem *reg) +{ +return readl (reg); +} + +/** +* clk_writel_default - default clock register write support function +* @val: value to write +* @reg: register to write to +* +* Default implementation for writing a clock register. +*/ +static void clk_writel_default (u32 val,void __iomem *reg) +{ +writel (val, reg); +} + +struct clk_ll_ops clk_ll_ops_default = { + .clk_readl = clk_readl_default, + .clk_writel = clk_writel_default +}; +/*** locking ***/ static void clk_prepare_lock (void ) {
include/linux/clk-provider.h +17 -0
@@ -198,6 +198,23 @@ struct clk_hw {const struct clk_init_data *init; }; +/** +* struct clk_ll_ops - low-level register access ops for a clock +* @clk_readl: pointer to register read function +* @clk_writel: pointer to register write function +* +* Low-level register access ops are generally used by the basic clock types +* (clk-gate, clk-mux, clk-divider etc.) to provide support for various +* low-level hardware interfaces (direct MMIO, regmap etc.), but can also be +* used by other hardware-specific clock drivers if needed. +*/ +struct clk_ll_ops { +u32 (*clk_readl)(void __iomem *reg); +void (*clk_writel)(u32 val,void __iomem *reg); +}; + +extern struct clk_ll_ops clk_ll_ops_default; +/* * DOC: Basic clock implementations common to many platforms *
Signature · 1 line
1.7.9.5
PATCH v12 6/49 clk: add support for low level register ops
[ added agust@ for mpc5xxx, dropped devicetree ]
Quoted 40 lines · Tero Kristo
Low level register ops are needed for providing SoC or IP block specific access routines to clock registers. Subsequent patches add support for the low level ops for the individual clock drivers.
Signed-off-by Tero Kristo <[email protected]>--- drivers/clk/clk.c | 28 ++++++++++++++++++++++++++++ include/linux/clk-provider.h | 17 +++++++++++++++++ 2 files changed, 45 insertions(+)drivers/clk/clk.c +21
-0@@ -34,6 +34,34 @@ static HLIST_HEAD(clk_root_list);static HLIST_HEAD (clk_orphan_list);static LIST_HEAD (clk_notifier_list); +/** +* clk_readl_default - default clock register read support function +* @reg: register to read +* +* Default implementation for reading a clock register. +*/ +static u32 clk_readl_default (void __iomem *reg) +{ +return readl (reg); +} + +/** +* clk_writel_default - default clock register write support function +* @val: value to write +* @reg: register to write to +* +* Default implementation for writing a clock register. +*/ +static void clk_writel_default (u32 val,void __iomem *reg) +{ +writel (val, reg);
drivers/clk/clk.c static HLIST_HEAD(clk_root_list); · line 67
Quoted 10 lines
drivers/clk/clk.c +7
-0+} + +struct clk_ll_ops clk_ll_ops_default = { + .clk_readl = clk_readl_default, + .clk_writel = clk_writel_default +}; +/*** locking ***/ static void clk_prepare_lock (void ) {
Mike, Anatolij, this is a HEADS UP for the clock and mpc5xxx
maintainers: This patch will break the recently introduced CCF support for MPC512x (currently sitting in -next, to get merged for 3.14), and requires some adjustment.
Either the clk_{read,write}l_default() routines' bodies need to depend on the architecture, or the clk_ll_ops_default structure needs to get preset differently depending on the architecture.
For least intrusive changes in future use, adding a routine which allows to register a different ll_ops structure could be most appropriate. That would allow to pre-set the ll_ops structure with the readl()/writel() implementation (current state of mainline code, working for the ARM architecture and maybe other little endian peripherals), and allows to register the ioread32be()/iowrite32be() routines for PowerPC, or whatever other platforms or architectures will require.
Expecting each individual clock item registration to specify a differing set of ll_ops if readl()/writel() are not appropriate would look weird to me.
Further I'd suggest to split this register access aspect out of the TI clock series, and to prepare it already for regmap style access to the hardware registers. See the next comment below.
Quoted 15 lines
include/linux/clk-provider.h +7
-0@@ -198,6 +198,23 @@ struct clk_hw {const struct clk_init_data *init; }; +/** +* struct clk_ll_ops - low-level register access ops for a clock +* @clk_readl: pointer to register read function +* @clk_writel: pointer to register write function +* +* Low-level register access ops are generally used by the basic clock types +* (clk-gate, clk-mux, clk-divider etc.) to provide support for various
include/linux/clk-provider.h struct clk_hw { · line 217
Quoted 10 lines
include/linux/clk-provider.h +10
-0+* low-level hardware interfaces (direct MMIO, regmap etc.), but can also be +* used by other hardware-specific clock drivers if needed. +*/ +struct clk_ll_ops { +u32 (*clk_readl)(void __iomem *reg); +void (*clk_writel)(u32 val,void __iomem *reg); +}; + +extern struct clk_ll_ops clk_ll_ops_default; +
I'd suggest to add a "strct clk_ll_ops" pointer to the routines' list of arguments, and to add some "user data" pointer to the struct.
This would provide more than the "reg" pointer to the routine, e.g. to determine an offset within a register set, and/or to hold a regmap handle.
Not adding this extension now would lead to our queueing several patches which will result in potential conflicts, or requiring more cycles than necessary to achieve a working state for currently pending changes.
There is another issue with this series: It introduces "alternative" _default() routines (which are verbatim copies of the static inlines from the header), then adjusts the basic clock types (div, gate, mux), but does not remove the then obsolete static inlines from the header.
Tero, can you please verify whether the clk_readl() and clk_writel() routines from <linux/clock-provider.h> become obsolete with your patch, or whether any unchanged users remain?
Are other parts of v12 still stuck? I only saw 15 of 49 patches.
virtually yours
Gerhard Sittig
Signature · 3 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr. 5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office at denx.de
PATCH v12 6/49 clk: add support for low level register ops
Quoted 72 lines · Gerhard Sittig
[ added agust@ for mpc5xxx, dropped devicetree ]
Quoted 40 lines · Tero Kristo
Low level register ops are needed for providing SoC or IP block specific access routines to clock registers. Subsequent patches add support for the low level ops for the individual clock drivers.
Signed-off-by Tero Kristo <[email protected]>--- drivers/clk/clk.c | 28 ++++++++++++++++++++++++++++ include/linux/clk-provider.h | 17 +++++++++++++++++ 2 files changed, 45 insertions(+)drivers/clk/clk.c +21
-0@@ -34,6 +34,34 @@ static HLIST_HEAD(clk_root_list);static HLIST_HEAD (clk_orphan_list);static LIST_HEAD (clk_notifier_list); +/** +* clk_readl_default - default clock register read support function +* @reg: register to read +* +* Default implementation for reading a clock register. +*/ +static u32 clk_readl_default (void __iomem *reg) +{ +return readl (reg); +} + +/** +* clk_writel_default - default clock register write support function +* @val: value to write +* @reg: register to write to +* +* Default implementation for writing a clock register. +*/ +static void clk_writel_default (u32 val,void __iomem *reg) +{ +writel (val, reg);drivers/clk/clk.c static HLIST_HEAD(clk_root_list); · line 67
Quoted 10 lines
drivers/clk/clk.c +7
-0+} + +struct clk_ll_ops clk_ll_ops_default = { + .clk_readl = clk_readl_default, + .clk_writel = clk_writel_default +}; +/*** locking ***/ static void clk_prepare_lock (void ) {Mike, Anatolij, this is a HEADS UP for the clock and mpc5xxx
maintainers: This patch will break the recently introduced CCF support for MPC512x (currently sitting in -next, to get merged for 3.14), and requires some adjustment.Either the clk_{read,write}l_default() routines' bodies need to depend on the architecture, or the
clk_ll_ops_defaultstructure needs to get preset differently depending on the architecture.For least intrusive changes in future use, adding a routine which allows to register a different
ll_opsstructure could be most appropriate. That would allow to pre-set thell_opsstructure with the readl()/writel() implementation (current state of mainline code, working for the ARM architecture and maybe other little endian peripherals), and allows to register the ioread32be()/iowrite32be() routines for PowerPC, or whatever other platforms or architectures will require.
Quoted 8 lines
Expecting each individual clock item registration to specify a differing set of
ll_opsif readl()/writel() are not appropriate would look weird to me.Further I'd suggest to split this register access aspect out of the TI clock series, and to prepare it already for regmap style access to the hardware registers. See the next comment below.
This sounds like a good idea to me, seeing it is blocking lots of other things.
Quoted 30 lines
Quoted 15 lines
include/linux/clk-provider.h +7
-0@@ -198,6 +198,23 @@ struct clk_hw {const struct clk_init_data *init; }; +/** +* struct clk_ll_ops - low-level register access ops for a clock +* @clk_readl: pointer to register read function +* @clk_writel: pointer to register write function +* +* Low-level register access ops are generally used by the basic clock types +* (clk-gate, clk-mux, clk-divider etc.) to provide support for various include/linux/clk-provider.h struct clk_hw { · line 217
Quoted 10 lines
include/linux/clk-provider.h +10
-0+* low-level hardware interfaces (direct MMIO, regmap etc.), but can also be +* used by other hardware-specific clock drivers if needed. +*/ +struct clk_ll_ops { +u32 (*clk_readl)(void __iomem *reg); +void (*clk_writel)(u32 val,void __iomem *reg); +}; + +extern struct clk_ll_ops clk_ll_ops_default; +I'd suggest to add a "strct
clk_ll_ops" pointer to the routines' list of arguments, and to add some "user data" pointer to the struct.
Quoted 8 lines
This would provide more than the "reg" pointer to the routine, e.g. to determine an offset within a register set, and/or to hold a regmap handle.
Not adding this extension now would lead to our queueing several patches which will result in potential conflicts, or requiring more cycles than necessary to achieve a working state for currently pending changes.
Yea I think this sounds like a good idea.
Quoted 11 lines
There is another issue with this series: It introduces "alternative"
_default()routines (which are verbatim copies of the static inlines from the header), then adjusts the basic clock types (div, gate, mux), but does not remove the then obsolete static inlines from the header.Tero, can you please verify whether the
clk_readl()andclk_writel()routines from <linux/clock-provider.h> become obsolete with your patch, or whether any unchanged users remain?
Just did a quick grep and it seems you are right, the routines become obsolete and could be removed (or alternatively just rename the clk_readl/writel_default to clk_readl/writel.)
Quoted 3 lines
Are other parts of v12 still stuck? I only saw 15 of 49 patches.
Rest of v12 was identical copy of v11, so I didn't repost them.
-Tero
PATCH v12 6/49 clk: add support for low level register ops
Quoted 9 lines · Tero Kristo
Quoted 5 lines · Gerhard Sittig
Further I'd suggest to split this register access aspect out of the TI clock series, and to prepare it already for regmap style access to the hardware registers. See the next comment below.
This sounds like a good idea to me, seeing it is blocking lots of other things.
This ll_ops struct looks like a simplified regmap. Have you seen my series that adds regmap support to the common clock framework[1]? Is there any reason why you can't use those patches and layer some patches on top to add support for regmap to the basic clock types?
[1] https://lkml.org/lkml/2013/12/23/461
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH v12 6/49 clk: add support for low level register ops
Quoted 11 lines · Stephen Boyd
Quoted 9 lines · Tero Kristo
Quoted 5 lines · Gerhard Sittig
Further I'd suggest to split this register access aspect out of the TI clock series, and to prepare it already for regmap style access to the hardware registers. See the next comment below.
This sounds like a good idea to me, seeing it is blocking lots of other things.
Quoted 6 lines
This
ll_opsstruct looks like a simplified regmap. Have you seen my series that adds regmap support to the common clock framework[1]? Is there any reason why you can't use those patches and layer some patches on top to add support for regmap to the basic clock types?
Yea I've seen that. I also used regmap myself on some earlier rev, but it is rather an overkill solution to my purposes, and it also adds additional latencies to the register access.
-Tero
PATCH v12 7/49 clk: divider: add support for low level ops
In reply to Tero KristoDivider clock can now be registered to use low level register access ops. Preferred initialization method is via clock description.
--- drivers/clk/clk-divider.c | 22 +++++++++++++++++++--- include/linux/clk-provider.h | 4 ++++ 2 files changed, 23 insertions(+), 3 deletions(-)
drivers/clk/clk-divider.c +19 -3
@@ -108,7 +108,12 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,struct clk_divider *divider =to_clk_divider (hw);unsigned int div, val; - val =clk_readl (divider->reg) >> divider->shift; +if (divider->ll_ops) + val = divider->ll_ops->clk_readl (divider->reg); +else + val =clk_readl (divider->reg); + + val >>= divider->shift; val &=div_mask (divider); div =_get_div (divider, val);
@@ -234,11 +239,17 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,if (divider->flags &CLK_DIVIDER_HIWORD_MASK ) { val =div_mask (divider) << (divider->shift +16 ); }else { - val =clk_readl (divider->reg); +if (divider->ll_ops) + val = divider->ll_ops->clk_readl (divider->reg); +else + val =clk_readl (divider->reg); val &= ~(div_mask (divider) << divider->shift); } val |= value << divider->shift; -clk_writel (val, divider->reg); +if (divider->ll_ops) + divider->ll_ops->clk_writel (val, divider->reg); +else +clk_writel (val, divider->reg);if (divider->lock)spin_unlock_irqrestore (divider->lock, flags);
@@ -291,6 +302,7 @@ static struct clk *_register_divider(struct device *dev, const char *name, div->lock = lock; div->hw.init = &init; div->table = table; + div->ll_ops = &clk_ll_ops_default;/* register the clock */ clk =clk_register (dev, &div->hw);
@@ -368,6 +380,10 @@ struct clk_hw *clk_register_divider_desc(struct device *dev, divider->flags = hw_desc->flags; divider->table = hw_desc->table; divider->lock = hw_desc->lock; + divider->ll_ops = hw_desc->ll_ops; + +if (!divider->ll_ops) + divider->ll_ops = &clk_ll_ops_default;if (!desc->ops) desc->ops = &clk_divider_ops;
include/linux/clk-provider.h +4 -0
@@ -322,6 +322,7 @@ struct clk_div_table {* * @hw: handle between common and hardware-specific interfaces * @reg: register containing the divider +* @ll_ops: low-level ops for accessing the register * @shift: shift to the divider bit field * @width: width of the divider bit field * @table: array of value/divider pairs, last entry should have div = 0
@@ -350,6 +351,7 @@ struct clk_div_table {struct clk_divider {struct clk_hw hw;void __iomem *reg; +struct clk_ll_ops *ll_ops;u8 shift;u8 width;u8 flags;
@@ -361,6 +363,7 @@ struct clk_divider {* struct clk_divider_desc - init descriptor for divider clock * @desc: handle between common and hardware-specific interfaces * @reg: register containing the divider +* @ll_ops: low-level ops for accessing the register * @shift: shift to the divider bit field * @width: width of the divider bit field * @table: array of value/divider pairs, last entry should have div = 0
@@ -369,6 +372,7 @@ struct clk_divider {struct clk_divider_desc {struct clk_desc desc;void __iomem *reg; +struct clk_ll_ops *ll_ops;u8 shift;u8 width;u8 flags;
Signature · 1 line
1.7.9.5
PATCH v12 7/49 clk: divider: add support for low level ops
[ dropped devicetree, we're clock specific here ]
Quoted 15 lines · Tero Kristo
Divider clock can now be registered to use low level register access ops. Preferred initialization method is via clock description.
Signed-off-by Tero Kristo <[email protected]>--- drivers/clk/clk-divider.c | 22 +++++++++++++++++++--- include/linux/clk-provider.h | 4 ++++ 2 files changed, 23 insertions(+), 3 deletions(-)drivers/clk/clk-divider.c +0
-0
drivers/clk/clk-divider.c static unsigned long clk_divider_recalc_rate(struct clk_hw *hw, · line 114
Quoted 8 lines
drivers/clk/clk-divider.c +4
-1@@ -108,7 +108,12 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,struct clk_divider *divider =to_clk_divider (hw);unsigned int div, val; - val =clk_readl (divider->reg) >> divider->shift; +if (divider->ll_ops) + val = divider->ll_ops->clk_readl (divider->reg); +else + val =clk_readl (divider->reg);
Should this not better always use an ll_ops structure, which either is individual to the clock item, or is "global" for a platform, yet can get re-registered at runtime (see the comment on 06/49)? And why are you referencing clk_readl() instead of clk_readl_default() which you specifically have introduced in the previous patch? Adding a copy of the routine and using both the copy and the original doesn't look right.
virtually yours
Gerhard Sittig
Signature · 3 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr. 5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office at denx.de
PATCH v12 7/49 clk: divider: add support for low level ops
Quoted 21 lines · Gerhard Sittig
[ dropped devicetree, we're clock specific here ]
Quoted 18 lines · Tero Kristo
Divider clock can now be registered to use low level register access ops. Preferred initialization method is via clock description.
Signed-off-by Tero Kristo <[email protected]>--- drivers/clk/clk-divider.c | 22 +++++++++++++++++++--- include/linux/clk-provider.h | 4 ++++ 2 files changed, 23 insertions(+), 3 deletions(-)drivers/clk/clk-divider.c +0
-0@@ -108,7 +108,12 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,struct clk_divider *divider =to_clk_divider (hw);unsigned int div, val;
Quoted 13 lines
drivers/clk/clk-divider.c static unsigned long clk_divider_recalc_rate(struct clk_hw *hw, · line 114
Quoted 5 lines
drivers/clk/clk-divider.c +4
-1- val =clk_readl (divider->reg) >> divider->shift; +if (divider->ll_ops) + val = divider->ll_ops->clk_readl (divider->reg); +else + val =clk_readl (divider->reg);Should this not better always use an
ll_opsstructure, which either is individual to the clock item, or is "global" for a platform, yet can get re-registered at runtime (see the comment on 06/49)? And why are you referencingclk_readl()instead ofclk_readl_default()which you specifically have introduced in the previous patch? Adding a copy of the routine and using both the copy and the original doesn't look right.
In some cases, the clock data is defined statically during compile time and here, ll_ops can be (and for OMAP cases at least is) NULL. I had kind of a global ll_ops definition in some of the earlier versions of this series, but it was frowned upon by some of the maintainers thus I dropped it.
-Tero
PATCH v12 7/49 clk: divider: add support for low level ops
Quoted 37 lines · Tero Kristo
Quoted 21 lines · Gerhard Sittig
[ dropped devicetree, we're clock specific here ]
Quoted 18 lines · Tero Kristo
Divider clock can now be registered to use low level register access ops. Preferred initialization method is via clock description.
Signed-off-by Tero Kristo <[email protected]>--- drivers/clk/clk-divider.c | 22 +++++++++++++++++++--- include/linux/clk-provider.h | 4 ++++ 2 files changed, 23 insertions(+), 3 deletions(-)drivers/clk/clk-divider.c +0
-0@@ -108,7 +108,12 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,struct clk_divider *divider =to_clk_divider (hw);unsigned int div, val;Quoted 13 lines
drivers/clk/clk-divider.c static unsigned long clk_divider_recalc_rate(struct clk_hw *hw, · line 114
Quoted 5 lines
drivers/clk/clk-divider.c +4
-1- val =clk_readl (divider->reg) >> divider->shift; +if (divider->ll_ops) + val = divider->ll_ops->clk_readl (divider->reg); +else + val =clk_readl (divider->reg);Should this not better always use an
ll_opsstructure, which either is individual to the clock item, or is "global" for a platform, yet can get re-registered at runtime (see the comment on 06/49)? And why are you referencingclk_readl()instead ofclk_readl_default()which you specifically have introduced in the previous patch? Adding a copy of the routine and using both the copy and the original doesn't look right.
Quoted 5 lines
In some cases, the clock data is defined statically during compile time and here,
ll_opscan be (and for OMAP cases at least is) NULL. I had kind of a globalll_opsdefinition in some of the earlier versions of this series, but it was frowned upon by some of the maintainers thus I dropped it.
Well, admittedly v11 was the first version that I have seen/noticed. But the static declaration you talk about and the ll_ops potentially being NULL was discussed there. My response was about replacing the above clk_readl() call with some ll_ops dereference while the ll_ops to use gets determined before, as 'divider' need not have one.
Consider something like this
- have default routines which do readl() and writel(), and have a default ll_ops struct which references the default routines
- have a default ll_ops struct _pointer_ that by default references the default readl/writel struct, yet can get changed to something else for a whole platform or architecture
- never use routines directly upon hardware access, but instead always dereference an ll_ops struct that gets determined so:
- start with the clock item's ll_ops reference
- use the global ll_ops pointer if the above is NULL
- use the pointer to the default ll_ops struct if still NULL (this protects against NULL platform specs, which should not happen yet are possible, and the test is cheap)
In pseudo code, this would then be
init:
default_struct = { default_read, default_write, NULL, };
default_ops = &default_struct;setup:
/* allow platforms to optionally change default_ops */
/* allow clk items to have individual clk->ll_ops */ use:
ops = divider->ll_ops;
if (!ops)
ops = default_ops;
if (!ops)
ops = &default_struct;
val = ops->clk_readl(ops, ...);This way
- you always end up with an ll_ops reference which leads to routines (and potential additional data that can be specific to a clock item, like regmap data), for both "dynamically" registered clock items as well as "static" declarations
- one initialization step can apply different accessors for a whole platform, while the default behaviour equals the current implementation
- individual clock items can specify their accessor routine and data, or may go with the builtin or the preset defaults
The biggest change in cost here is the indirect routine call in contrast to the static inline of the current implementation, while this additional cost of calling a real wrapper routine can't get avoided in the first place. Comparing pointers and falling back in the absence of individual overrides should not outweight the above additional cost of calling the routine. The always identical logic to determine which routine to call can get implemented in a static inline and then won't clutter the actual clock handling logic.
If regmap access is rather popular a method, and requires only little additional information, it might receive more explicit support such that users need not hand-roll the same logic over and over again, yet not too much waste occurs to non-regmap items. But available information suggests that currently there is only one user for regmap style access to clock related hardware (Steven's). This could change in the future.
virtually yours
Gerhard Sittig
Signature · 3 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr. 5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office at denx.de
PATCH v12 8/49 clk: gate: add support for low level ops
In reply to Tero KristoGate clock can now be registered to use low level register access ops. Preferred initialization method is via clock description.
--- drivers/clk/clk-gate.c | 20 +++++++++++++++++--- include/linux/clk-provider.h | 4 ++++ 2 files changed, 21 insertions(+), 3 deletions(-)
drivers/clk/clk-gate.c +17 -3
@@ -62,7 +62,10 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable)if (set) reg |=BIT (gate->bit_idx); }else { - reg =clk_readl (gate->reg); +if (gate->ll_ops) + reg = gate->ll_ops->clk_readl (gate->reg); +else + reg =clk_readl (gate->reg);if (set) reg |=BIT (gate->bit_idx);
@@ -70,7 +73,10 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable) reg &= ~BIT (gate->bit_idx); } -clk_writel (reg, gate->reg); +if (gate->ll_ops) + gate->ll_ops->clk_writel (reg, gate->reg); +else +clk_writel (reg, gate->reg);if (gate->lock)spin_unlock_irqrestore (gate->lock, flags);
@@ -93,7 +99,10 @@ static int clk_gate_is_enabled(struct clk_hw *hw)u32 reg;struct clk_gate *gate =to_clk_gate (hw); - reg =clk_readl (gate->reg); +if (gate->ll_ops) + reg = gate->ll_ops->clk_readl (gate->reg); +else + reg =clk_readl (gate->reg);/* if a set bit disables this clk, flip it before masking */ if (gate->flags &CLK_GATE_SET_TO_DISABLE )
@@ -157,6 +166,7 @@ struct clk *clk_register_gate(struct device *dev, const char *name, gate->flags = clk_gate_flags; gate->lock = lock; gate->hw.init = &init; + gate->ll_ops = &clk_ll_ops_default; clk =clk_register (dev, &gate->hw);
@@ -184,6 +194,10 @@ struct clk_hw *clk_register_gate_desc(struct device *dev, struct clk_desc *desc) gate->bit_idx = hw_desc->bit_idx; gate->flags = hw_desc->flags; gate->lock = hw_desc->lock; + gate->ll_ops = hw_desc->ll_ops; + +if (!gate->ll_ops) + gate->ll_ops = &clk_ll_ops_default;if (!desc->ops) desc->ops = &clk_gate_ops;
include/linux/clk-provider.h +4 -0
@@ -262,6 +262,7 @@ void of_fixed_clk_setup(struct device_node *np);* * @hw: handle between common and hardware-specific interfaces * @reg: register controlling gate +* @ll_ops: low-level ops for accessing the register * @bit_idx: single bit controlling gate * @flags: hardware-specific flags * @lock: register lock
@@ -280,6 +281,7 @@ void of_fixed_clk_setup(struct device_node *np);struct clk_gate {struct clk_hw hw;void __iomem *reg; +struct clk_ll_ops *ll_ops;u8 bit_idx;u8 flags;spinlock_t *lock;
@@ -289,6 +291,7 @@ struct clk_gate {* struct clk_gate_desc - init descriptor for gating clock * @desc: handle between common and hardware-specific interfaces * @reg: register controlling gate +* @ll_ops: low-level ops for accessing the register * @bit_idx: single bit controlling gate * @flags: hardware-specific flags * @lock: register lock
@@ -296,6 +299,7 @@ struct clk_gate {struct clk_gate_desc {struct clk_desc desc;void __iomem *reg; +struct clk_ll_ops *ll_ops;u8 bit_idx;u8 flags;spinlock_t *lock;
Signature · 1 line
1.7.9.5
PATCH v12 9/49 clk: mux: add support for low level ops
In reply to Tero KristoMultiplexer clock can now be registered to use low level register access ops. Preferred initialization method is via clock description.
--- drivers/clk/clk-mux.c | 24 +++++++++++++++++++++--- include/linux/clk-provider.h | 4 ++++ 2 files changed, 25 insertions(+), 3 deletions(-)
drivers/clk/clk-mux.c +21 -3
@@ -46,7 +46,12 @@ static u8 clk_mux_get_parent(struct clk_hw *hw)* OTOH, pmd_trace_clk_mux_ck uses a separate bit for each clock, so * val = 0x4 really means "bit 2, index starts at bit 0" */ - val =clk_readl (mux->reg) >> mux->shift; +if (mux->ll_ops) + val = mux->ll_ops->clk_readl (mux->reg); +else + val =clk_readl (mux->reg); + + val >>= mux->shift; val &= mux->mask;if (mux->table) {
@@ -93,11 +98,19 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index)if (mux->flags &CLK_MUX_HIWORD_MASK ) { val = mux->mask << (mux->shift +16 ); }else { - val =clk_readl (mux->reg); +if (mux->ll_ops) + val = mux->ll_ops->clk_readl (mux->reg); +else + val =clk_readl (mux->reg); + val &= ~(mux->mask << mux->shift); } val |= index << mux->shift; -clk_writel (val, mux->reg); + +if (mux->ll_ops) + mux->ll_ops->clk_writel (val, mux->reg); +else +clk_writel (val, mux->reg);if (mux->lock)spin_unlock_irqrestore (mux->lock, flags);
@@ -159,6 +172,7 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name, mux->lock = lock; mux->table = table; mux->hw.init = &init; + mux->ll_ops = &clk_ll_ops_default; clk =clk_register (dev, &mux->hw);
@@ -201,6 +215,10 @@ struct clk_hw *clk_register_mux_desc(struct device *dev, struct clk_desc *desc) mux->shift = hw_desc->shift; mux->flags = hw_desc->flags; mux->lock = hw_desc->lock; + mux->ll_ops = hw_desc->ll_ops; + +if (!mux->ll_ops) + mux->ll_ops = &clk_ll_ops_default;if (!desc->ops) {if (mux->flags &CLK_MUX_READ_ONLY )
include/linux/clk-provider.h +4 -0
@@ -408,6 +408,7 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,* * @hw: handle between common and hardware-specific interfaces * @reg: register controlling multiplexer +* @ll_ops: low-level ops for accessing the register * @shift: shift to multiplexer bit field * @width: width of mutliplexer bit field * @flags: hardware-specific flags
@@ -427,6 +428,7 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,struct clk_mux {struct clk_hw hw;void __iomem *reg; +struct clk_ll_ops *ll_ops;u32 *table;u32 mask;u8 shift;
@@ -438,6 +440,7 @@ struct clk_mux {* struct clk_mux_desc - init descriptor for multiplexer clock * @desc: handle between common and hardware-specific interfaces * @reg: register controlling multiplexer +* @ll_ops: low-level ops for accesing the register * @shift: shift to multiplexer bit field * @width: width of multiplexer bit field * @flags: hardware-specific flags
@@ -446,6 +449,7 @@ struct clk_mux {struct clk_mux_desc {struct clk_desc desc;void __iomem *reg; +struct clk_ll_ops *ll_ops;u32 *table;u32 mask;u8 shift;
Signature · 1 line
1.7.9.5
PATCH v12 11/49 CLK: ti: add init support for clock IP blocks
In reply to Tero Kristoti_dt_clk_init_provider() can now be used to initialize the contents of a single clock IP block. This parses all the clocks under the IP block and calls the corresponding init function for them.
This patch also introduces a helper function for the TI clock drivers to get register info from DT and append the master IP info to this.
--- drivers/clk/clk.c | 4 +- drivers/clk/ti/clk.c | 112 ++++++++++++++++++++++++++++++++++++++++++ include/linux/clk-provider.h | 2 + include/linux/clk/ti.h | 20 ++++++++ 4 files changed, 135 insertions(+), 3 deletions(-)
drivers/clk/clk.c +1 -3
@@ -2203,8 +2203,6 @@ struct of_clk_provider {void *data; }; -extern struct of_device_id __clk_of_table[]; - static const struct of_device_id __clk_of_table_sentinel__used __section (__clk_of_table_end);
@@ -2344,7 +2342,7 @@ void __init of_clk_init(const struct of_device_id *matches)struct device_node *np;if (!matches) - matches = __clk_of_table; + matches = &__clk_of_table;for_each_matching_node_and_match (np, matches, &match) {of_clk_init_cb_t clk_init_cb = match->data;
drivers/clk/ti/clk.c +112 -0
125 lines not on this page · raw message
include/linux/clk-provider.h +2 -0
@@ -584,6 +584,8 @@ struct clk_onecell_data {unsigned int clk_num; }; +extern struct of_device_id __clk_of_table; +#define CLK_OF_DECLARE (name, compat, fn) \ static const struct of_device_id __clk_of_table_##name \ __used __section(__clk_of_table) \
include/linux/clk/ti.h +20 -0
@@ -36,7 +36,27 @@ struct ti_dt_clk { .node_name = name, \ } +/* Maximum number of clock memmaps */ +#define CLK_MAX_MEMMAPS 4 +typedef void (*ti_of_clk_init_cb_t )(struct clk_hw *,struct device_node *); + +/** +* struct clk_omap_reg - OMAP register declaration +* @offset: offset from the master IP module base address +* @index: index of the master IP module +*/ +struct clk_omap_reg { +u16 offset; +u16 index; +}; + +extern struct clk_ll_ops *ti_clk_ll_ops; + +void __iomem *ti_clk_get_reg_addr (struct device_node *node,int index);void ti_dt_clocks_register (struct ti_dt_clk *oclks); +void ti_dt_clk_init_provider (struct device_node *np,int index); +int ti_clk_retry_init (struct device_node *node,struct clk_hw *hw, +ti_of_clk_init_cb_t func);#endif
Signature · 1 line
1.7.9.5
PATCH v12 12/49 CLK: TI: Add DPLL clock support
In reply to Tero KristoThe OMAP clock driver now supports DPLL clock type. This patch also adds support for DT DPLL nodes.
--- .../devicetree/bindings/clock/ti/dpll.txt | 75 +++ arch/arm/mach-omap2/clock.h | 164 +----- arch/arm/mach-omap2/clock3xxx.h | 2 - drivers/clk/ti/Makefile | 2 +- drivers/clk/ti/dpll.c | 558 ++++++++++++++++++++ include/linux/clk/ti.h | 172 ++++++ 6 files changed, 807 insertions(+), 166 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/ti/dpll.txt create mode 100644 drivers/clk/ti/dpll.c
Documentation/devicetree/bindings/clock/ti/dpll.txt new file +75 -0
@@ -0,0 +1,75 @@ +Binding for Texas Instruments DPLL clock. + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. It assumes a +register-mapped DPLL with usually two selectable input clocks +(reference clock and bypass clock), with digital phase locked +loop logic for multiplying the input clock to a desired output +clock. This clock also typically supports different operation +modes (locked, low power stop etc.) This binding has several +sub-types, which effectively result in slightly different setup +for the actual DPLL clock. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt + +Required properties: +- compatible : shall be one of: + "ti,omap3-dpll-clock", + "ti,omap3-dpll-core-clock", + "ti,omap3-dpll-per-clock", + "ti,omap3-dpll-per-j-type-clock", + "ti,omap4-dpll-clock", + "ti,omap4-dpll-x2-clock", + "ti,omap4-dpll-core-clock", + "ti,omap4-dpll-m4xen-clock", + "ti,omap4-dpll-j-type-clock", + "ti,am3-dpll-no-gate-clock", + "ti,am3-dpll-j-type-clock", + "ti,am3-dpll-no-gate-j-type-clock", + "ti,am3-dpll-clock", + "ti,am3-dpll-core-clock", + "ti,am3-dpll-x2-clock", + +- #clock-cells : from common clock binding; shall be set to 0. +- clocks : link phandles of parent clocks, first entry lists reference clock + and second entry bypass clock +- reg : offsets for the register set for controlling the DPLL. + Registers are listed in following order: + "control" - contains the control register base address + "idlest" - contains the idle status register base address + "mult-div1" - contains the multiplier / divider register base address + "autoidle" - contains the autoidle register base address (optional) + ti,am3-* dpll types do not have autoidle register + +Optional properties: +- DPLL mode setting - defining any one or more of the following overrides + default setting. + - ti,low-power-stop : DPLL supports low power stop mode, gating output + - ti,low-power-bypass : DPLL output matches rate of parent bypass clock + - ti,lock : DPLL locks in programmed rate + +Examples: + dpll_core_ck: dpll_core_ck at 44e00490 { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-core-clock"; + clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; + reg = <0x490>, <0x45c>, <0x488>, <0x468>; + }; + + dpll2_ck: dpll2_ck at 48004004 { + #clock-cells = <0>; + compatible = "ti,omap3-dpll-clock"; + clocks = <&sys_ck>, <&dpll2_fck>; + ti,low-power-stop; + ti,low-power-bypass; + ti,lock; + reg = <0x4>, <0x24>, <0x34>, <0x40>; + }; + + dpll_core_ck: dpll_core_ck at 44e00490 { + #clock-cells = <0>; + compatible = "ti,am3-dpll-core-clock"; + clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; + reg = <0x90>, <0x5c>, <0x68>; + };
arch/arm/mach-omap2/clock.h +1 -163
215 lines not on this page · raw message
arch/arm/mach-omap2/clock3xxx.h +0 -2
@@ -9,8 +9,6 @@#define __ARCH_ARM_MACH_OMAP2_CLOCK3XXX_Hint omap3xxx_clk_init (void ); -int omap3_dpll4_set_rate (struct clk_hw *clk,unsigned long rate, -unsigned long parent_rate);int omap3_core_dpll_m2_set_rate (struct clk_hw *clk,unsigned long rate,unsigned long parent_rate);void omap3_clk_lock_dpll5 (void );
drivers/clk/ti/Makefile +1 -1
@@ -1,3 +1,3 @@ ifneq ($(CONFIG_OF),) -obj-y += clk.o +obj-y += clk.o dpll.o endif
drivers/clk/ti/dpll.c new file +558 -0
558 lines not on this page · raw message
include/linux/clk/ti.h +172 -0
188 lines not on this page · raw message
Signature · 1 line
1.7.9.5
PATCH v12 14/49 clk: ti: add composite clock support
In reply to Tero KristoThis is a multipurpose clock node, which contains support for multiple sub-clocks. Uses basic composite clock type to implement the actual functionality, and TI specific gate, mux and divider clocks.
--- .../devicetree/bindings/clock/ti/composite.txt | 54 ++++ arch/arm/mach-omap2/clock.h | 3 - drivers/clk/ti/Makefile | 2 +- drivers/clk/ti/composite.c | 269 ++++++++++++++++++++ include/linux/clk/ti.h | 12 + 5 files changed, 336 insertions(+), 4 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/ti/composite.txt create mode 100644 drivers/clk/ti/composite.c
Documentation/devicetree/bindings/clock/ti/composite.txt new file +54 -0
@@ -0,0 +1,54 @@ +Binding for TI composite clock. + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. It assumes a +register-mapped composite clock with multiple different sub-types; + +a multiplexer clock with multiple input clock signals or parents, one +of which can be selected as output, this behaves exactly as [2] + +an adjustable clock rate divider, this behaves exactly as [3] + +a gating function which can be used to enable and disable the output +clock, this behaves exactly as [4] + +The binding must provide a list of the component clocks that shall be +merged to this clock. The component clocks shall be of one of the +"ti,*composite*-clock" types. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Documentation/devicetree/bindings/clock/ti/mux.txt +[3] Documentation/devicetree/bindings/clock/ti/divider.txt +[4] Documentation/devicetree/bindings/clock/ti/gate.txt + +Required properties: +- compatible : shall be: "ti,composite-clock" +- clocks : link phandles of component clocks +- #clock-cells : from common clock binding; shall be set to 0. + +Examples: + +usb_l4_gate_ick: usb_l4_gate_ick { + #clock-cells = <0>; + compatible = "ti,composite-interface-clock"; + clocks = <&l4_ick>; + ti,bit-shift = <5>; + reg = <0x0a10>; +}; + +usb_l4_div_ick: usb_l4_div_ick { + #clock-cells = <0>; + compatible = "ti,composite-divider-clock"; + clocks = <&l4_ick>; + ti,bit-shift = <4>; + ti,max-div = <1>; + reg = <0x0a40>; + ti,index-starts-at-one; +}; + +usb_l4_ick: usb_l4_ick { + #clock-cells = <0>; + compatible = "ti,composite-clock"; + clocks = <&usb_l4_gate_ick>, <&usb_l4_div_ick>; +};
arch/arm/mach-omap2/clock.h +0 -3
@@ -240,9 +240,6 @@ extern void omap2_clkt_iclk_deny_idle(struct clk_hw_omap *clk);unsigned long omap2_get_dpll_rate (struct clk_hw_omap *clk); -int omap2_dflt_clk_enable (struct clk_hw *hw); -void omap2_dflt_clk_disable (struct clk_hw *hw); -int omap2_dflt_clk_is_enabled (struct clk_hw *hw);void omap2_clk_dflt_find_companion (struct clk_hw_omap *clk,void __iomem **other_reg,u8 *other_bit);
drivers/clk/ti/Makefile +1 -1
@@ -1,3 +1,3 @@ ifneq ($(CONFIG_OF),) -obj-y += clk.o dpll.o autoidle.o +obj-y += clk.o dpll.o autoidle.o composite.o endif
drivers/clk/ti/composite.c new file +269 -0
269 lines not on this page · raw message
include/linux/clk/ti.h +12 -0
@@ -164,6 +164,14 @@ struct clk_hw_omap {/* DPLL Type and DCO Selection Flags */ #define DPLL_J_TYPE 0x1 +/* Composite clock component types */ +enum { +CLK_COMPONENT_TYPE_GATE =0 , +CLK_COMPONENT_TYPE_DIVIDER , +CLK_COMPONENT_TYPE_MUX , +CLK_COMPONENT_TYPE_MAX , +}; +/** * struct ti_dt_clk - OMAP DT clock alias declarations * @lk: clock lookup definition
@@ -221,6 +229,9 @@ unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw, unsigned long parent_rate);int omap3_dpll4_set_rate (struct clk_hw *clk,unsigned long rate,unsigned long parent_rate); +int omap2_dflt_clk_enable (struct clk_hw *hw); +void omap2_dflt_clk_disable (struct clk_hw *hw); +int omap2_dflt_clk_is_enabled (struct clk_hw *hw);void __iomem *ti_clk_get_reg_addr (struct device_node *node,int index);void ti_dt_clocks_register (struct ti_dt_clk *oclks);
@@ -228,6 +239,7 @@ void ti_dt_clk_init_provider(struct device_node *np, int index);int ti_clk_retry_init (struct device_node *node,struct clk_hw *hw,ti_of_clk_init_cb_t func);int of_ti_clk_autoidle_setup (struct device_node *node); +int ti_clk_add_component (struct device_node *node,struct clk_hw *hw,int type);#ifdef CONFIG_OF void of_ti_clk_allow_autoidle_all (void );
Signature · 1 line
1.7.9.5
PATCH v12 17/49 CLK: TI: add support for gate clock
In reply to Tero KristoThis patch adds support for TI specific gate clocks. These behave as basic gate-clock, but have different ops / hw-ops for controlling the actual gate, for example waiting until the clock is ready. Several sub-types are supported:
- ti,gate-clock: basic gate clock with default ops/hwops
- ti,clkdm-gate-clock: clockdomain level gate control
- ti,dss-gate-clock: gate clock with DSS specific hardware handling
- ti,am35xx-gate-clock: gate clock with AM35xx specific hardware handling
- ti,hsdiv-gate-clock: gate clock with OMAP36xx hardware errata handling
--- .../devicetree/bindings/clock/ti/gate.txt | 85 +++++++ drivers/clk/ti/Makefile | 2 +- drivers/clk/ti/gate.c | 247 ++++++++++++++++++++ include/linux/clk/ti.h | 6 + 4 files changed, 339 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/clock/ti/gate.txt create mode 100644 drivers/clk/ti/gate.c
Documentation/devicetree/bindings/clock/ti/gate.txt new file +85 -0
@@ -0,0 +1,85 @@ +Binding for Texas Instruments gate clock. + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. This clock is +quite much similar to the basic gate-clock [2], however, +it supports a number of additional features. If no register +is provided for this clock, the code assumes that a clockdomain +will be controlled instead and the corresponding hw-ops for +that is used. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Documentation/devicetree/bindings/clock/gate-clock.txt +[3] Documentation/devicetree/bindings/clock/ti/clockdomain.txt + +Required properties: +- compatible : shall be one of: + "ti,gate-clock" - basic gate clock + "ti,wait-gate-clock" - gate clock which waits until clock is active before + returning from clk_enable() + "ti,dss-gate-clock" - gate clock with DSS specific hardware handling + "ti,am35xx-gate-clock" - gate clock with AM35xx specific hardware handling + "ti,clkdm-gate-clock" - clockdomain gate clock, which derives its functional + clock directly from a clockdomain, see [3] how + to map clockdomains properly + "ti,hsdiv-gate-clock" - gate clock with OMAP36xx specific hardware handling, + required for a hardware errata +- #clock-cells : from common clock binding; shall be set to 0 +- clocks : link to phandle of parent clock +- reg : offset for register controlling adjustable gate, not needed for + ti,clkdm-gate-clock type + +Optional properties: +- ti,bit-shift : bit shift for programming the clock gate, invalid for + ti,clkdm-gate-clock type +- ti,set-bit-to-disable : inverts default gate programming. Setting the bit + gates the clock and clearing the bit ungates the clock. + +Examples: + mmchs2_fck: mmchs2_fck at 48004a00 { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&core_96m_fck>; + reg = <0x48004a00 0x4>; + ti,bit-shift = <25>; + }; + + uart4_fck_am35xx: uart4_fck_am35xx { + #clock-cells = <0>; + compatible = "ti,wait-gate-clock"; + clocks = <&core_48m_fck>; + reg = <0x0a00>; + ti,bit-shift = <23>; + }; + + dss1_alwon_fck_3430es2: dss1_alwon_fck_3430es2 at 48004e00 { + #clock-cells = <0>; + compatible = "ti,dss-gate-clock"; + clocks = <&dpll4_m4x2_ck>; + reg = <0x48004e00 0x4>; + ti,bit-shift = <0>; + }; + + emac_ick: emac_ick at 4800259c { + #clock-cells = <0>; + compatible = "ti,am35xx-gate-clock"; + clocks = <&ipss_ick>; + reg = <0x4800259c 0x4>; + ti,bit-shift = <1>; + }; + + emu_src_ck: emu_src_ck { + #clock-cells = <0>; + compatible = "ti,clkdm-gate-clock"; + clocks = <&emu_src_mux_ck>; + }; + + dpll4_m2x2_ck: dpll4_m2x2_ck at 48004d00 { + #clock-cells = <0>; + compatible = "ti,hsdiv-gate-clock"; + clocks = <&dpll4_m2x2_mul_ck>; + ti,bit-shift = <0x1b>; + reg = <0x48004d00 0x4>; + ti,set-bit-to-disable; + };
drivers/clk/ti/Makefile +1 -1
@@ -1,4 +1,4 @@ ifneq ($(CONFIG_OF),) obj-y += clk.o dpll.o autoidle.o divider.o \ - fixed-factor.o composite.o + fixed-factor.o gate.o composite.o endif
drivers/clk/ti/gate.c new file +247 -0
247 lines not on this page · raw message
include/linux/clk/ti.h +6 -0
@@ -227,6 +227,8 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,void omap2_init_clk_clkdm (struct clk_hw *clk);unsigned long omap3_clkoutx2_recalc (struct clk_hw *hw,unsigned long parent_rate); +int omap2_clkops_enable_clkdm (struct clk_hw *hw); +void omap2_clkops_disable_clkdm (struct clk_hw *hw);int omap3_dpll4_set_rate (struct clk_hw *clk,unsigned long rate,unsigned long parent_rate);int omap2_dflt_clk_enable (struct clk_hw *hw);
@@ -251,5 +253,9 @@ static inline void of_ti_clk_deny_autoidle_all(void) { }extern const struct clk_hw_omap_ops clkhwops_omap3_dpll;extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx; +extern const struct clk_hw_omap_ops clkhwops_wait; +extern const struct clk_hw_omap_ops clkhwops_omap3430es2_dss_usbhost_wait; +extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait; +extern const struct clk_hw_omap_ops clkhwops_iclk_wait;#endif
Signature · 1 line
1.7.9.5
PATCH v12 18/49 CLK: TI: add support for clockdomain binding
In reply to Tero KristoSome OMAP clocks require knowledge about their parent clockdomain for book keeping purposes. This patch creates a new DT binding for TI clockdomains, which act as a collection of device clocks. Clockdomain itself is rather misleading name for the hardware functionality, as at least on OMAP4 / OMAP5 / DRA7 the clockdomains can be collections of either clocks and/or IP blocks, thus idle-domain or such might be more appropriate. For most cases on these SoCs, the kernel doesn't even need the information and the mappings can be ignored.
--- .../devicetree/bindings/clock/ti/clockdomain.txt | 24 +++++++ drivers/clk/ti/Makefile | 3 +- drivers/clk/ti/clockdomain.c | 70 ++++++++++++++++++++ include/linux/clk/ti.h | 1 + 4 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/clock/ti/clockdomain.txt create mode 100644 drivers/clk/ti/clockdomain.c
Documentation/devicetree/bindings/clock/ti/clockdomain.txt new file +24 -0
@@ -0,0 +1,24 @@ +Binding for Texas Instruments clockdomain. + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1] in consumer role. +Every clock on TI SoC belongs to one clockdomain, but software +only needs this information for specific clocks which require +their parent clockdomain to be controlled when the clock is +enabled/disabled. This binding doesn't define a new clock +binding type, it is used to group existing clock nodes under +hardware hierarchy. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt + +Required properties: +- compatible : shall be "ti,clockdomain" +- #clock-cells : from common clock binding; shall be set to 0. +- clocks : link phandles of clocks within this domain + +Examples: + dss_clkdm: dss_clkdm { + compatible = "ti,clockdomain"; + clocks = <&dss1_alwon_fck_3430es2>, <&dss_ick_3430es2>; + };
drivers/clk/ti/Makefile +2 -1
@@ -1,4 +1,5 @@ ifneq ($(CONFIG_OF),) obj-y += clk.o dpll.o autoidle.o divider.o \ - fixed-factor.o gate.o composite.o + fixed-factor.o gate.o clockdomain.o \ + composite.o endif
drivers/clk/ti/clockdomain.c new file +70 -0
70 lines not on this page · raw message
include/linux/clk/ti.h +1 -0
@@ -238,6 +238,7 @@ int omap2_dflt_clk_is_enabled(struct clk_hw *hw);void __iomem *ti_clk_get_reg_addr (struct device_node *node,int index);void ti_dt_clocks_register (struct ti_dt_clk *oclks);void ti_dt_clk_init_provider (struct device_node *np,int index); +void ti_dt_clockdomains_setup (void );int ti_clk_retry_init (struct device_node *node,struct clk_hw *hw,ti_of_clk_init_cb_t func);int of_ti_clk_autoidle_setup (struct device_node *node);
Signature · 1 line
1.7.9.5
PATCH v12 23/49 CLK: TI: DRA7: Add APLL support
In reply to Tero KristoFrom: J Keerthy <[email protected]>
The patch adds support for DRA7 PCIe APLL. The APLL sources the optional functional clocks for PCIe module.
APLL stands for Analog PLL. This is different when comapred with DPLL meaning Digital PLL, the phase detection is done using an analog circuit.
--- .../devicetree/bindings/clock/ti/apll.txt | 31 +++ drivers/clk/ti/Makefile | 2 +- drivers/clk/ti/apll.c | 221 ++++++++++++++++++++ 3 files changed, 253 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/clock/ti/apll.txt create mode 100644 drivers/clk/ti/apll.c
Documentation/devicetree/bindings/clock/ti/apll.txt new file +31 -0
@@ -0,0 +1,31 @@ +Binding for Texas Instruments APLL clock. + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. It assumes a +register-mapped APLL with usually two selectable input clocks +(reference clock and bypass clock), with analog phase locked +loop logic for multiplying the input clock to a desired output +clock. This clock also typically supports different operation +modes (locked, low power stop etc.) APLL mostly behaves like +a subtype of a DPLL [2], although a simplified one at that. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Documentation/devicetree/bindings/clock/ti/dpll.txt + +Required properties: +- compatible : shall be "ti,dra7-apll-clock" +- #clock-cells : from common clock binding; shall be set to 0. +- clocks : link phandles of parent clocks (clk-ref and clk-bypass) +- reg : address and length of the register set for controlling the APLL. + It contains the information of registers in the following order: + "control" - contains the control register base address + "idlest" - contains the idlest register base address + +Examples: + apll_pcie_ck: apll_pcie_ck at 4a008200 { + #clock-cells = <0>; + clocks = <&apll_pcie_in_clk_mux>, <&dpll_pcie_ref_ck>; + reg = <0x4a00821c 0x4>, <0x4a008220 0x4>; + compatible = "ti,dra7-apll-clock"; + };
drivers/clk/ti/Makefile +1 -1
@@ -1,7 +1,7 @@ ifneq ($(CONFIG_OF),) obj-y += clk.o dpll.o autoidle.o divider.o \ fixed-factor.o gate.o clockdomain.o \ - composite.o mux.o + composite.o mux.o apll.o obj-$(CONFIG_ARCH_OMAP4) += clk-44xx.o obj-$(CONFIG_SOC_OMAP5) += clk-54xx.o endif
drivers/clk/ti/apll.c new file +221 -0
221 lines not on this page · raw message
Signature · 1 line
1.7.9.5
PATCH v12 43/49 ARM: OMAP2+: PRM: add support for initializing PRCM clock modules from DT
In reply to Tero KristoThis patch provides top level functionality for the DT clock initialization. Clock tree is initialized hierarchically starting from IP modules (CM/PRM/PRCM) going down towards individual clock nodes, and finally initializing clockdomains once all the clocks are ready.
--- arch/arm/mach-omap2/prm.h | 1 + arch/arm/mach-omap2/prm_common.c | 66 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+)
arch/arm/mach-omap2/prm.h +1 -0
@@ -18,6 +18,7 @@# ifndef __ASSEMBLER__extern void __iomem *prm_base;extern void omap2_set_globals_prm (void __iomem *prm); +int of_prcm_init (void );# endif
arch/arm/mach-omap2/prm_common.c +66 -0
81 lines not on this page · raw message
Signature · 1 line
1.7.9.5
Tony Lindgren
maintainerv12 cover ARM: TI SoC clock DT conversion
In reply to Tero KristoQuoted 40 lines · Tero Kristo
Hi,
Hopefully final post of this series. At least this is going to be the last post this year as I will be going to x-mas vacation and won't be back before Jan 2nd. This time I just sent the patches that have changes in them, the missing ones are exactly the same as in v11.
Changes done:
- most of the patches:
* Some cosmetic documentation fixes
- patch 06:
* Changed register pointer types from 'u32__iomem*' to 'void__iomem*'
- patch 07,08,09:
* Added check forclk->ll_opsbeing NULL (happens with statically built clock data), fixes the boot time crash issue noticed by Tony
- patch 11:
* Moved__clk_of_tableextern declaration toclk-provider.hheader file... Got flamed about this enough times now. :)
* Type for the declaration changed also from array to single entry, and address for this used in code. This prevents compile time error:
"array type has incomplete element type". Can't use pointer here either as this messes the address of the table.
*ti_clk_retry_init()now has int return type, and checks for kzalloc failure
- patch 12, 14, 23:
* Added cleanup in caseti_clk_retry_init()fails
- patch 17:
* Fixed potential memory leak in failed init detected by sparse
- patch 18:
* Modified commit message to add some details about clockdomains
- patch 43:
* Changed register pointer types from 'u32 *' to 'void__iomem*'Testing done:
- omap3-beagle: boot, suspend/resume (ret), suspend/resume (off)
- omap4-panda-es: boot, suspend/resume (ret)
- omap5-uevm: boot
- am335x-bone: boot
- dra7-evm: boot
Quoted 4 lines
Branches available at https://github.com/t-kristo/linux-pm.git:
- branch: 3.13-rc4-dt-clks-v12 : contains everything, shall me merged last
- branch: 3.13-rc4-dt-clks-v12-for-mike :drivers/clkchanges
- branch: 3.13-rc4-dt-clks-v11-for-benoit : DT data only (from v11, no changes)
Boots now for me on omap2/3/4, and off-idle works on omap3. So as far as I'm concerned, please feel free to add my ack to the new and updated patches still missing it:
v12 cover ARM: TI SoC clock DT conversion
In reply to Tero KristoQuoted 40 lines · Tero Kristo
Hi,
Hopefully final post of this series. At least this is going to be the last post this year as I will be going to x-mas vacation and won't be back before Jan 2nd. This time I just sent the patches that have changes in them, the missing ones are exactly the same as in v11.
Changes done:
- most of the patches:
* Some cosmetic documentation fixes
- patch 06:
* Changed register pointer types from 'u32__iomem*' to 'void__iomem*'
- patch 07,08,09:
* Added check forclk->ll_opsbeing NULL (happens with statically built clock data), fixes the boot time crash issue noticed by Tony
- patch 11:
* Moved__clk_of_tableextern declaration toclk-provider.hheader file... Got flamed about this enough times now. :)
* Type for the declaration changed also from array to single entry, and address for this used in code. This prevents compile time error:
"array type has incomplete element type". Can't use pointer here either as this messes the address of the table.
*ti_clk_retry_init()now has int return type, and checks for kzalloc failure
- patch 12, 14, 23:
* Added cleanup in caseti_clk_retry_init()fails
- patch 17:
* Fixed potential memory leak in failed init detected by sparse
- patch 18:
* Modified commit message to add some details about clockdomains
- patch 43:
* Changed register pointer types from 'u32 *' to 'void__iomem*'Testing done:
- omap3-beagle: boot, suspend/resume (ret), suspend/resume (off)
- omap4-panda-es: boot, suspend/resume (ret)
- omap5-uevm: boot
- am335x-bone: boot
- dra7-evm: boot
Quoted 4 lines
Branches available at https://github.com/t-kristo/linux-pm.git:
- branch: 3.13-rc4-dt-clks-v12 : contains everything, shall me merged last
- branch: 3.13-rc4-dt-clks-v12-for-mike :drivers/clkchanges
- branch: 3.13-rc4-dt-clks-v11-for-benoit : DT data only (from v11, no changes)
Still fails to build OMAP5-only defconfig:
drivers/built-in.o: In function `of_ti_composite_interface_clk_setup':drivers/clk/ti/gate.c:190: undefined reference to `clkhwops_iclk_wait'
make: *** [vmlinux] Error 1
Signature · 8 lines
balbi -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20131220/54f1fc8a/attachment-0001.sig>
v12 cover ARM: TI SoC clock DT conversion
In reply to Tero KristoQuoted 11 lines · Tero Kristo
Hopefully final post of this series. At least this is going to be the last post this year as I will be going to x-mas vacation and won't be back before Jan 2nd. This time I just sent the patches that have changes in them, the missing ones are exactly the same as in v11.
Testing done:
- omap3-beagle: boot, suspend/resume (ret), suspend/resume (off)
- omap4-panda-es: boot, suspend/resume (ret)
- omap5-uevm: boot
- am335x-bone: boot
- dra7-evm: boot
Booting the 3.13-rc4-dt-clks-v12 branch on my Nokia N900 works:
-- Sebastian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20131220/95750d5b/attachment.sig>
v12 cover ARM: TI SoC clock DT conversion
In reply to Tero KristoHi Tero,
Quoted 5 lines · Tero Kristo
Hopefully final post of this series. At least this is going to be the last post this year as I will be going to x-mas vacation and won't be back before Jan 2nd. This time I just sent the patches that have changes in them, the missing ones are exactly the same as in v11.
There are still a few issues that I see
[...]
Quoted 4 lines
Branches available at https://github.com/t-kristo/linux-pm.git:
- branch: 3.13-rc4-dt-clks-v12 : contains everything, shall me merged last
- branch: 3.13-rc4-dt-clks-v12-for-mike :drivers/clkchanges
- branch: 3.13-rc4-dt-clks-v11-for-benoit : DT data only (from v11, no changes)
For easy maintainer merging, you may want to make this as three branches:
1. for-mike based ongit://git.linaro.org/people/mturquette/linux.git clk-next
2. for-benoit based ongit://git.kernel.org/pub/scm/linux/kernel/git/bcousson/linux-omap-dt.git
for_3.14/dts
3. for-tony based ongit://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap.git
omap-for-v3.14/board-removal or on a clean k.org tag
4. A testing branch for the rest of us which consolidates all of these together.
Testing with a rebase of 3.13-rc4-dt-clks-v12 to v3.13-rc7:
Here is my test platforms and logs (boot only - omap2plus_defconfig + common_clk_debug - all boots to sd card based filesystem):
AM335x Family:
AM335x-EVMSK:
http://pastebin.mozilla.org/3955459 AM335x-EVM: http://pastebin.mozilla.org/3955460 AM335x-BeagleBone Black: http://pastebin.mozilla.org/3955476
OMAP3 family:
OMAP3430: SDP3430:
http://pastebin.mozilla.org/3955475 AM3517-evm: (requires a bootargs fix - remote board - no regressions seen) http://pastebin.mozilla.org/3955461 AM3517-CraneBoard: http://pastebin.mozilla.org/3955477 OMAP3630/DM3730 BeagleBoard-XM: http://pastebin.mozilla.org/3955474 AM37xx-evm: http://pastebin.mozilla.org/3955472
OMAP4 Family:
OMAP4460: PandaBoard-ES:
http://pastebin.mozilla.org/3955478
NOTE: trace_clk_div_ck seems orphan clock here?
OMAP5 Family:
OMAP5432: OMAP5uEVM:
http://pastebin.mozilla.org/3955479
DRA7 Family:
DRA7: DRA7-evm:
http://pastebin.mozilla.org/3955480
Patch autoverification report: http://pastebin.mozilla.org/3955695
The following issues need fixes I suppose:
* CHECK: spinlock_t definition without comment
[PATCH 03/49] clk: divider: add support for registering divider [PATCH 04/49] clk: mux: add support for registering mux clock from [PATCH 05/49] clk: gate: add support for registering gate clock from
* [PATCH 23/49] CLK: TI: DRA7: Add APLL support
"parent_names = kzalloc(sizeof(char *) * init->num_parents, GFP_KERNEL);"
* kzalloc without check for NULL
* will also be good to add some kerneldoc documentation (same withinterface.c)
* WARNING: static const char * array should probably be static const char * const
[PATCH 25/49] CLK: TI: add am33xx clock init file
[PATCH 27/49] CLK: TI: add omap3 clock init file
* [PATCH 40/49] ARM: OMAP2+: clock: use driver API instead of direct adds a new kernel doc warning "Warning(arch/arm/mach-omap2/clock.c:
No description found for parameter 'clk'"
* [PATCH 44/49] ARM: OMAP2+: io: use new clock init API
introduces warning for
"arch/arm/mach-omap2/io.c: warning: symbol 'omap_clk_soc_init' was
not declared. Should it be static?"
which seems squashed with "[PATCH 45/49] ARM: OMAP4: remove old clock
data and link in new"
will be good to have it not appear in patch 44 itself.
Also pending is OMAP5 only build failure that Felipe reported and does not seem fixed in V12 as well:
http://marc.info/?l=linux-arm-kernel&m=138757010619274&w=2
and
http://marc.info/?l=linux-arm-kernel&m=138755595914796&w=2
Signature · 2 lines
Regards, Nishanth Menon
v12 cover ARM: TI SoC clock DT conversion
Quoted 63 lines · Nishanth Menon
Hi Tero,
Quoted 5 lines · Tero Kristo
Hopefully final post of this series. At least this is going to be the last post this year as I will be going to x-mas vacation and won't be back before Jan 2nd. This time I just sent the patches that have changes in them, the missing ones are exactly the same as in v11.
There are still a few issues that I see
[...]Quoted 4 lines
Branches available at https://github.com/t-kristo/linux-pm.git:
- branch: 3.13-rc4-dt-clks-v12 : contains everything, shall me merged last
- branch: 3.13-rc4-dt-clks-v12-for-mike :drivers/clkchanges
- branch: 3.13-rc4-dt-clks-v11-for-benoit : DT data only (from v11, no changes)For easy maintainer merging, you may want to make this as three branches:
1. for-mike based on
git://git.linaro.org/people/mturquette/linux.gitclk-next2. for-benoit based on
git://git.kernel.org/pub/scm/linux/kernel/git/bcousson/linux-omap-dt.git
for_3.14/dts3. for-tony based on
git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap.git
omap-for-v3.14/board-removal or on a clean k.org tag4. A testing branch for the rest of us which consolidates all of these together.
Testing with a rebase of 3.13-rc4-dt-clks-v12 to v3.13-rc7:
Here is my test platforms and logs (boot only -
omap2plus_defconfig+common_clk_debug- all boots to sd card based filesystem):AM335x Family:
AM335x-EVMSK:
http://pastebin.mozilla.org/3955459 AM335x-EVM: http://pastebin.mozilla.org/3955460 AM335x-BeagleBone Black: http://pastebin.mozilla.org/3955476OMAP3 family:
OMAP3430: SDP3430:http://pastebin.mozilla.org/3955475 AM3517-evm: (requires a bootargs fix - remote board - no regressions seen) http://pastebin.mozilla.org/3955461 AM3517-CraneBoard: http://pastebin.mozilla.org/3955477 OMAP3630/DM3730 BeagleBoard-XM: http://pastebin.mozilla.org/3955474 AM37xx-evm: http://pastebin.mozilla.org/3955472OMAP4 Family:
OMAP4460: PandaBoard-ES:
http://pastebin.mozilla.org/3955478
NOTE:trace_clk_div_ckseems orphan clock here?
Quoted 8 lines
OMAP5 Family:
OMAP5432: OMAP5uEVM:http://pastebin.mozilla.org/3955479DRA7 Family:
DRA7: DRA7-evm:
http://pastebin.mozilla.org/3955480
one more missing test platform:
AM43xx-epos platform: (needed a few out of tree patches to test on TI internal engineering samples):
http://pastebin.mozilla.org/3960056
Quoted 37 lines
Patch autoverification report: http://pastebin.mozilla.org/3955695
The following issues need fixes I suppose:
* CHECK:spinlock_tdefinition without comment
[PATCH 03/49] clk: divider: add support for registering divider [PATCH 04/49] clk: mux: add support for registering mux clock from [PATCH 05/49] clk: gate: add support for registering gate clock from* [PATCH 23/49] CLK: TI: DRA7: Add APLL support
"parent_names=kzalloc(sizeof(char *) * init->num_parents, GFP_KERNEL);"
* kzalloc without check for NULL
* will also be good to add some kerneldoc documentation (same withinterface.c)
* WARNING: static const char * array should probably be static const char * const
[PATCH 25/49] CLK: TI: add am33xx clock init file
[PATCH 27/49] CLK: TI: add omap3 clock init file
* [PATCH 40/49] ARM: OMAP2+: clock: use driver API instead of direct adds a new kernel doc warning "Warning(arch/arm/mach-omap2/clock.c:
No description found for parameter 'clk'"
* [PATCH 44/49] ARM: OMAP2+: io: use new clock init API
introduces warning for
"arch/arm/mach-omap2/io.c: warning: symbol 'omap_clk_soc_init' was
not declared. Should it be static?"
which seems squashed with "[PATCH 45/49] ARM: OMAP4: remove old clock
data and link in new"
will be good to have it not appear in patch 44 itself.Also pending is OMAP5 only build failure that Felipe reported and does not seem fixed in V12 as well:
http://marc.info/?l=linux-arm-kernel&m=138757010619274&w=2
and
http://marc.info/?l=linux-arm-kernel&m=138755595914796&w=2
Signature · 2 lines
Regards, Nishanth Menon