Commit eb7d264f authored by Stephen Boyd's avatar Stephen Boyd

clk: divider: Add hw based registration APIs

Add registration APIs in the clk divider code to return struct
clk_hw pointers instead of struct clk pointers. This way we hide
the struct clk pointer from providers unless they need to use
consumer facing APIs.
Signed-off-by: default avatarStephen Boyd <sboyd@codeaurora.org>
parent e4f1b49b
...@@ -426,15 +426,16 @@ const struct clk_ops clk_divider_ro_ops = { ...@@ -426,15 +426,16 @@ const struct clk_ops clk_divider_ro_ops = {
}; };
EXPORT_SYMBOL_GPL(clk_divider_ro_ops); EXPORT_SYMBOL_GPL(clk_divider_ro_ops);
static struct clk *_register_divider(struct device *dev, const char *name, static struct clk_hw *_register_divider(struct device *dev, const char *name,
const char *parent_name, unsigned long flags, const char *parent_name, unsigned long flags,
void __iomem *reg, u8 shift, u8 width, void __iomem *reg, u8 shift, u8 width,
u8 clk_divider_flags, const struct clk_div_table *table, u8 clk_divider_flags, const struct clk_div_table *table,
spinlock_t *lock) spinlock_t *lock)
{ {
struct clk_divider *div; struct clk_divider *div;
struct clk *clk; struct clk_hw *hw;
struct clk_init_data init; struct clk_init_data init;
int ret;
if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) { if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) {
if (width + shift > 16) { if (width + shift > 16) {
...@@ -467,12 +468,14 @@ static struct clk *_register_divider(struct device *dev, const char *name, ...@@ -467,12 +468,14 @@ static struct clk *_register_divider(struct device *dev, const char *name,
div->table = table; div->table = table;
/* register the clock */ /* register the clock */
clk = clk_register(dev, &div->hw); hw = &div->hw;
ret = clk_hw_register(dev, hw);
if (IS_ERR(clk)) if (ret) {
kfree(div); kfree(div);
hw = ERR_PTR(ret);
}
return clk; return hw;
} }
/** /**
...@@ -492,11 +495,38 @@ struct clk *clk_register_divider(struct device *dev, const char *name, ...@@ -492,11 +495,38 @@ struct clk *clk_register_divider(struct device *dev, const char *name,
void __iomem *reg, u8 shift, u8 width, void __iomem *reg, u8 shift, u8 width,
u8 clk_divider_flags, spinlock_t *lock) u8 clk_divider_flags, spinlock_t *lock)
{ {
return _register_divider(dev, name, parent_name, flags, reg, shift, struct clk_hw *hw;
hw = _register_divider(dev, name, parent_name, flags, reg, shift,
width, clk_divider_flags, NULL, lock); width, clk_divider_flags, NULL, lock);
if (IS_ERR(hw))
return ERR_CAST(hw);
return hw->clk;
} }
EXPORT_SYMBOL_GPL(clk_register_divider); EXPORT_SYMBOL_GPL(clk_register_divider);
/**
* clk_hw_register_divider - register a divider clock with the clock framework
* @dev: device registering this clock
* @name: name of this clock
* @parent_name: name of clock's parent
* @flags: framework-specific flags
* @reg: register address to adjust divider
* @shift: number of bits to shift the bitfield
* @width: width of the bitfield
* @clk_divider_flags: divider-specific flags for this clock
* @lock: shared register lock for this clock
*/
struct clk_hw *clk_hw_register_divider(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
void __iomem *reg, u8 shift, u8 width,
u8 clk_divider_flags, spinlock_t *lock)
{
return _register_divider(dev, name, parent_name, flags, reg, shift,
width, clk_divider_flags, NULL, lock);
}
EXPORT_SYMBOL_GPL(clk_hw_register_divider);
/** /**
* clk_register_divider_table - register a table based divider clock with * clk_register_divider_table - register a table based divider clock with
* the clock framework * the clock framework
...@@ -517,11 +547,41 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name, ...@@ -517,11 +547,41 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,
u8 clk_divider_flags, const struct clk_div_table *table, u8 clk_divider_flags, const struct clk_div_table *table,
spinlock_t *lock) spinlock_t *lock)
{ {
return _register_divider(dev, name, parent_name, flags, reg, shift, struct clk_hw *hw;
hw = _register_divider(dev, name, parent_name, flags, reg, shift,
width, clk_divider_flags, table, lock); width, clk_divider_flags, table, lock);
if (IS_ERR(hw))
return ERR_CAST(hw);
return hw->clk;
} }
EXPORT_SYMBOL_GPL(clk_register_divider_table); EXPORT_SYMBOL_GPL(clk_register_divider_table);
/**
* clk_hw_register_divider_table - register a table based divider clock with
* the clock framework
* @dev: device registering this clock
* @name: name of this clock
* @parent_name: name of clock's parent
* @flags: framework-specific flags
* @reg: register address to adjust divider
* @shift: number of bits to shift the bitfield
* @width: width of the bitfield
* @clk_divider_flags: divider-specific flags for this clock
* @table: array of divider/value pairs ending with a div set to 0
* @lock: shared register lock for this clock
*/
struct clk_hw *clk_hw_register_divider_table(struct device *dev,
const char *name, const char *parent_name, unsigned long flags,
void __iomem *reg, u8 shift, u8 width,
u8 clk_divider_flags, const struct clk_div_table *table,
spinlock_t *lock)
{
return _register_divider(dev, name, parent_name, flags, reg, shift,
width, clk_divider_flags, table, lock);
}
EXPORT_SYMBOL_GPL(clk_hw_register_divider_table);
void clk_unregister_divider(struct clk *clk) void clk_unregister_divider(struct clk *clk)
{ {
struct clk_divider *div; struct clk_divider *div;
...@@ -537,3 +597,18 @@ void clk_unregister_divider(struct clk *clk) ...@@ -537,3 +597,18 @@ void clk_unregister_divider(struct clk *clk)
kfree(div); kfree(div);
} }
EXPORT_SYMBOL_GPL(clk_unregister_divider); EXPORT_SYMBOL_GPL(clk_unregister_divider);
/**
* clk_hw_unregister_divider - unregister a clk divider
* @hw: hardware-specific clock data to unregister
*/
void clk_hw_unregister_divider(struct clk_hw *hw)
{
struct clk_divider *div;
div = to_clk_divider(hw);
clk_hw_unregister(hw);
kfree(div);
}
EXPORT_SYMBOL_GPL(clk_hw_unregister_divider);
...@@ -407,12 +407,22 @@ struct clk *clk_register_divider(struct device *dev, const char *name, ...@@ -407,12 +407,22 @@ struct clk *clk_register_divider(struct device *dev, const char *name,
const char *parent_name, unsigned long flags, const char *parent_name, unsigned long flags,
void __iomem *reg, u8 shift, u8 width, void __iomem *reg, u8 shift, u8 width,
u8 clk_divider_flags, spinlock_t *lock); u8 clk_divider_flags, spinlock_t *lock);
struct clk_hw *clk_hw_register_divider(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
void __iomem *reg, u8 shift, u8 width,
u8 clk_divider_flags, spinlock_t *lock);
struct clk *clk_register_divider_table(struct device *dev, const char *name, struct clk *clk_register_divider_table(struct device *dev, const char *name,
const char *parent_name, unsigned long flags, const char *parent_name, unsigned long flags,
void __iomem *reg, u8 shift, u8 width, void __iomem *reg, u8 shift, u8 width,
u8 clk_divider_flags, const struct clk_div_table *table, u8 clk_divider_flags, const struct clk_div_table *table,
spinlock_t *lock); spinlock_t *lock);
struct clk_hw *clk_hw_register_divider_table(struct device *dev,
const char *name, const char *parent_name, unsigned long flags,
void __iomem *reg, u8 shift, u8 width,
u8 clk_divider_flags, const struct clk_div_table *table,
spinlock_t *lock);
void clk_unregister_divider(struct clk *clk); void clk_unregister_divider(struct clk *clk);
void clk_hw_unregister_divider(struct clk_hw *hw);
/** /**
* struct clk_mux - multiplexer clock * struct clk_mux - multiplexer clock
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment