Merge branch 'clk-hw-register' (early part) into clk-next

* 'clk-hw-register' (early part):
  clk: fixed-rate: Add hw based registration APIs
  clk: gpio: Add hw based registration APIs
  clk: composite: Add hw based registration APIs
  clk: fractional-divider: Add hw based registration APIs
  clk: fixed-factor: Add hw based registration APIs
  clk: mux: Add hw based registration APIs
  clk: gate: Add hw based registration APIs
  clk: divider: Add hw based registration APIs
  clkdev: Add clk_hw based registration APIs
  clk: Add clk_hw OF clk providers
  clk: Add {devm_}clk_hw_{register,unregister}() APIs
  clkdev: Remove clk_register_clkdevs()
This commit is contained in:
Stephen Boyd 2016-04-21 14:47:18 -07:00
commit 58657d189a
13 changed files with 673 additions and 88 deletions

View File

@ -236,6 +236,7 @@ certainly invest a bit more effort into libata core layer).
CLOCK
devm_clk_get()
devm_clk_put()
devm_clk_hw_register()
DMA
dmam_alloc_coherent()

View File

@ -211,17 +211,18 @@ static void clk_composite_disable(struct clk_hw *hw)
gate_ops->disable(gate_hw);
}
struct clk *clk_register_composite(struct device *dev, const char *name,
struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name,
const char * const *parent_names, int num_parents,
struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
unsigned long flags)
{
struct clk *clk;
struct clk_hw *hw;
struct clk_init_data init;
struct clk_composite *composite;
struct clk_ops *clk_composite_ops;
int ret;
composite = kzalloc(sizeof(*composite), GFP_KERNEL);
if (!composite)
@ -231,12 +232,13 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
init.flags = flags | CLK_IS_BASIC;
init.parent_names = parent_names;
init.num_parents = num_parents;
hw = &composite->hw;
clk_composite_ops = &composite->ops;
if (mux_hw && mux_ops) {
if (!mux_ops->get_parent) {
clk = ERR_PTR(-EINVAL);
hw = ERR_PTR(-EINVAL);
goto err;
}
@ -251,7 +253,7 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
if (rate_hw && rate_ops) {
if (!rate_ops->recalc_rate) {
clk = ERR_PTR(-EINVAL);
hw = ERR_PTR(-EINVAL);
goto err;
}
clk_composite_ops->recalc_rate = clk_composite_recalc_rate;
@ -286,7 +288,7 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
if (gate_hw && gate_ops) {
if (!gate_ops->is_enabled || !gate_ops->enable ||
!gate_ops->disable) {
clk = ERR_PTR(-EINVAL);
hw = ERR_PTR(-EINVAL);
goto err;
}
@ -300,24 +302,43 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
init.ops = clk_composite_ops;
composite->hw.init = &init;
clk = clk_register(dev, &composite->hw);
if (IS_ERR(clk))
ret = clk_hw_register(dev, hw);
if (ret) {
hw = ERR_PTR(ret);
goto err;
}
if (composite->mux_hw)
composite->mux_hw->clk = clk;
composite->mux_hw->clk = hw->clk;
if (composite->rate_hw)
composite->rate_hw->clk = clk;
composite->rate_hw->clk = hw->clk;
if (composite->gate_hw)
composite->gate_hw->clk = clk;
composite->gate_hw->clk = hw->clk;
return clk;
return hw;
err:
kfree(composite);
return clk;
return hw;
}
struct clk *clk_register_composite(struct device *dev, const char *name,
const char * const *parent_names, int num_parents,
struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
unsigned long flags)
{
struct clk_hw *hw;
hw = clk_hw_register_composite(dev, name, parent_names, num_parents,
mux_hw, mux_ops, rate_hw, rate_ops, gate_hw, gate_ops,
flags);
if (IS_ERR(hw))
return ERR_CAST(hw);
return hw->clk;
}
void clk_unregister_composite(struct clk *clk)

View File

@ -426,15 +426,16 @@ const struct clk_ops 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,
void __iomem *reg, u8 shift, u8 width,
u8 clk_divider_flags, const struct clk_div_table *table,
spinlock_t *lock)
{
struct clk_divider *div;
struct clk *clk;
struct clk_hw *hw;
struct clk_init_data init;
int ret;
if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) {
if (width + shift > 16) {
@ -467,12 +468,14 @@ static struct clk *_register_divider(struct device *dev, const char *name,
div->table = table;
/* register the clock */
clk = clk_register(dev, &div->hw);
if (IS_ERR(clk))
hw = &div->hw;
ret = clk_hw_register(dev, hw);
if (ret) {
kfree(div);
hw = ERR_PTR(ret);
}
return clk;
return hw;
}
/**
@ -491,11 +494,38 @@ struct clk *clk_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_hw *hw;
hw = _register_divider(dev, name, parent_name, flags, reg, shift,
width, clk_divider_flags, NULL, lock);
if (IS_ERR(hw))
return ERR_CAST(hw);
return hw->clk;
}
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_register_divider);
EXPORT_SYMBOL_GPL(clk_hw_register_divider);
/**
* clk_register_divider_table - register a table based divider clock with
@ -516,11 +546,41 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,
void __iomem *reg, u8 shift, u8 width,
u8 clk_divider_flags, const struct clk_div_table *table,
spinlock_t *lock)
{
struct clk_hw *hw;
hw = _register_divider(dev, name, parent_name, flags, reg, shift,
width, clk_divider_flags, table, lock);
if (IS_ERR(hw))
return ERR_CAST(hw);
return hw->clk;
}
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_register_divider_table);
EXPORT_SYMBOL_GPL(clk_hw_register_divider_table);
void clk_unregister_divider(struct clk *clk)
{
@ -537,3 +597,18 @@ void clk_unregister_divider(struct clk *clk)
kfree(div);
}
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);

View File

@ -68,13 +68,14 @@ const struct clk_ops clk_fixed_factor_ops = {
};
EXPORT_SYMBOL_GPL(clk_fixed_factor_ops);
struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
const char *name, const char *parent_name, unsigned long flags,
unsigned int mult, unsigned int div)
{
struct clk_fixed_factor *fix;
struct clk_init_data init;
struct clk *clk;
struct clk_hw *hw;
int ret;
fix = kmalloc(sizeof(*fix), GFP_KERNEL);
if (!fix)
@ -91,12 +92,28 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
init.parent_names = &parent_name;
init.num_parents = 1;
clk = clk_register(dev, &fix->hw);
if (IS_ERR(clk))
hw = &fix->hw;
ret = clk_hw_register(dev, hw);
if (ret) {
kfree(fix);
hw = ERR_PTR(ret);
}
return clk;
return hw;
}
EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor);
struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
unsigned int mult, unsigned int div)
{
struct clk_hw *hw;
hw = clk_hw_register_fixed_factor(dev, name, parent_name, flags, mult,
div);
if (IS_ERR(hw))
return ERR_CAST(hw);
return hw->clk;
}
EXPORT_SYMBOL_GPL(clk_register_fixed_factor);
@ -113,6 +130,17 @@ void clk_unregister_fixed_factor(struct clk *clk)
}
EXPORT_SYMBOL_GPL(clk_unregister_fixed_factor);
void clk_hw_unregister_fixed_factor(struct clk_hw *hw)
{
struct clk_fixed_factor *fix;
fix = to_clk_fixed_factor(hw);
clk_hw_unregister(hw);
kfree(fix);
}
EXPORT_SYMBOL_GPL(clk_hw_unregister_fixed_factor);
#ifdef CONFIG_OF
/**
* of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock

View File

@ -45,8 +45,8 @@ const struct clk_ops clk_fixed_rate_ops = {
EXPORT_SYMBOL_GPL(clk_fixed_rate_ops);
/**
* clk_register_fixed_rate_with_accuracy - register fixed-rate clock with the
* clock framework
* clk_hw_register_fixed_rate_with_accuracy - register fixed-rate clock with
* the clock framework
* @dev: device that is registering this clock
* @name: name of this clock
* @parent_name: name of clock's parent
@ -54,13 +54,14 @@ EXPORT_SYMBOL_GPL(clk_fixed_rate_ops);
* @fixed_rate: non-adjustable clock rate
* @fixed_accuracy: non-adjustable clock rate
*/
struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev,
struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev,
const char *name, const char *parent_name, unsigned long flags,
unsigned long fixed_rate, unsigned long fixed_accuracy)
{
struct clk_fixed_rate *fixed;
struct clk *clk;
struct clk_hw *hw;
struct clk_init_data init;
int ret;
/* allocate fixed-rate clock */
fixed = kzalloc(sizeof(*fixed), GFP_KERNEL);
@ -79,22 +80,49 @@ struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev,
fixed->hw.init = &init;
/* register the clock */
clk = clk_register(dev, &fixed->hw);
if (IS_ERR(clk))
hw = &fixed->hw;
ret = clk_hw_register(dev, hw);
if (ret) {
kfree(fixed);
hw = ERR_PTR(ret);
}
return clk;
return hw;
}
EXPORT_SYMBOL_GPL(clk_hw_register_fixed_rate_with_accuracy);
struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev,
const char *name, const char *parent_name, unsigned long flags,
unsigned long fixed_rate, unsigned long fixed_accuracy)
{
struct clk_hw *hw;
hw = clk_hw_register_fixed_rate_with_accuracy(dev, name, parent_name,
flags, fixed_rate, fixed_accuracy);
if (IS_ERR(hw))
return ERR_CAST(hw);
return hw->clk;
}
EXPORT_SYMBOL_GPL(clk_register_fixed_rate_with_accuracy);
/**
* clk_register_fixed_rate - register fixed-rate clock with the clock framework
* clk_hw_register_fixed_rate - register fixed-rate clock with the clock
* framework
* @dev: device that is registering this clock
* @name: name of this clock
* @parent_name: name of clock's parent
* @flags: framework-specific flags
* @fixed_rate: non-adjustable clock rate
*/
struct clk_hw *clk_hw_register_fixed_rate(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
unsigned long fixed_rate)
{
return clk_hw_register_fixed_rate_with_accuracy(dev, name, parent_name,
flags, fixed_rate, 0);
}
EXPORT_SYMBOL_GPL(clk_hw_register_fixed_rate);
struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
unsigned long fixed_rate)

View File

@ -116,14 +116,15 @@ const struct clk_ops clk_fractional_divider_ops = {
};
EXPORT_SYMBOL_GPL(clk_fractional_divider_ops);
struct clk *clk_register_fractional_divider(struct device *dev,
struct clk_hw *clk_hw_register_fractional_divider(struct device *dev,
const char *name, const char *parent_name, unsigned long flags,
void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth,
u8 clk_divider_flags, spinlock_t *lock)
{
struct clk_fractional_divider *fd;
struct clk_init_data init;
struct clk *clk;
struct clk_hw *hw;
int ret;
fd = kzalloc(sizeof(*fd), GFP_KERNEL);
if (!fd)
@ -146,10 +147,39 @@ struct clk *clk_register_fractional_divider(struct device *dev,
fd->lock = lock;
fd->hw.init = &init;
clk = clk_register(dev, &fd->hw);
if (IS_ERR(clk))
hw = &fd->hw;
ret = clk_hw_register(dev, hw);
if (ret) {
kfree(fd);
hw = ERR_PTR(ret);
}
return clk;
return hw;
}
EXPORT_SYMBOL_GPL(clk_hw_register_fractional_divider);
struct clk *clk_register_fractional_divider(struct device *dev,
const char *name, const char *parent_name, unsigned long flags,
void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth,
u8 clk_divider_flags, spinlock_t *lock)
{
struct clk_hw *hw;
hw = clk_hw_register_fractional_divider(dev, name, parent_name, flags,
reg, mshift, mwidth, nshift, nwidth, clk_divider_flags,
lock);
if (IS_ERR(hw))
return ERR_CAST(hw);
return hw->clk;
}
EXPORT_SYMBOL_GPL(clk_register_fractional_divider);
void clk_hw_unregister_fractional_divider(struct clk_hw *hw)
{
struct clk_fractional_divider *fd;
fd = to_clk_fd(hw);
clk_hw_unregister(hw);
kfree(fd);
}

View File

@ -110,7 +110,7 @@ const struct clk_ops clk_gate_ops = {
EXPORT_SYMBOL_GPL(clk_gate_ops);
/**
* clk_register_gate - register a gate clock with the clock framework
* clk_hw_register_gate - register a gate clock with the clock framework
* @dev: device that is registering this clock
* @name: name of this clock
* @parent_name: name of this clock's parent
@ -120,14 +120,15 @@ EXPORT_SYMBOL_GPL(clk_gate_ops);
* @clk_gate_flags: gate-specific flags for this clock
* @lock: shared register lock for this clock
*/
struct clk *clk_register_gate(struct device *dev, const char *name,
struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
void __iomem *reg, u8 bit_idx,
u8 clk_gate_flags, spinlock_t *lock)
{
struct clk_gate *gate;
struct clk *clk;
struct clk_hw *hw;
struct clk_init_data init;
int ret;
if (clk_gate_flags & CLK_GATE_HIWORD_MASK) {
if (bit_idx > 15) {
@ -154,12 +155,29 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
gate->lock = lock;
gate->hw.init = &init;
clk = clk_register(dev, &gate->hw);
if (IS_ERR(clk))
hw = &gate->hw;
ret = clk_hw_register(dev, hw);
if (ret) {
kfree(gate);
hw = ERR_PTR(ret);
}
return clk;
return hw;
}
EXPORT_SYMBOL_GPL(clk_hw_register_gate);
struct clk *clk_register_gate(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
void __iomem *reg, u8 bit_idx,
u8 clk_gate_flags, spinlock_t *lock)
{
struct clk_hw *hw;
hw = clk_hw_register_gate(dev, name, parent_name, flags, reg,
bit_idx, clk_gate_flags, lock);
if (IS_ERR(hw))
return ERR_CAST(hw);
return hw->clk;
}
EXPORT_SYMBOL_GPL(clk_register_gate);
@ -178,3 +196,14 @@ void clk_unregister_gate(struct clk *clk)
kfree(gate);
}
EXPORT_SYMBOL_GPL(clk_unregister_gate);
void clk_hw_unregister_gate(struct clk_hw *hw)
{
struct clk_gate *gate;
gate = to_clk_gate(hw);
clk_hw_unregister(hw);
kfree(gate);
}
EXPORT_SYMBOL_GPL(clk_hw_unregister_gate);

View File

@ -94,13 +94,13 @@ const struct clk_ops clk_gpio_mux_ops = {
};
EXPORT_SYMBOL_GPL(clk_gpio_mux_ops);
static struct clk *clk_register_gpio(struct device *dev, const char *name,
static struct clk_hw *clk_register_gpio(struct device *dev, const char *name,
const char * const *parent_names, u8 num_parents, unsigned gpio,
bool active_low, unsigned long flags,
const struct clk_ops *clk_gpio_ops)
{
struct clk_gpio *clk_gpio;
struct clk *clk;
struct clk_hw *hw;
struct clk_init_data init = {};
unsigned long gpio_flags;
int err;
@ -141,24 +141,26 @@ static struct clk *clk_register_gpio(struct device *dev, const char *name,
clk_gpio->gpiod = gpio_to_desc(gpio);
clk_gpio->hw.init = &init;
hw = &clk_gpio->hw;
if (dev)
clk = devm_clk_register(dev, &clk_gpio->hw);
err = devm_clk_hw_register(dev, hw);
else
clk = clk_register(NULL, &clk_gpio->hw);
err = clk_hw_register(NULL, hw);
if (!IS_ERR(clk))
return clk;
if (!err)
return hw;
if (!dev) {
gpiod_put(clk_gpio->gpiod);
kfree(clk_gpio);
}
return clk;
return ERR_PTR(err);
}
/**
* clk_register_gpio_gate - register a gpio clock gate with the clock framework
* clk_hw_register_gpio_gate - register a gpio clock gate with the clock
* framework
* @dev: device that is registering this clock
* @name: name of this clock
* @parent_name: name of this clock's parent
@ -166,7 +168,7 @@ static struct clk *clk_register_gpio(struct device *dev, const char *name,
* @active_low: true if gpio should be set to 0 to enable clock
* @flags: clock flags
*/
struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name,
const char *parent_name, unsigned gpio, bool active_low,
unsigned long flags)
{
@ -175,10 +177,24 @@ struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
(parent_name ? 1 : 0), gpio, active_low, flags,
&clk_gpio_gate_ops);
}
EXPORT_SYMBOL_GPL(clk_hw_register_gpio_gate);
struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
const char *parent_name, unsigned gpio, bool active_low,
unsigned long flags)
{
struct clk_hw *hw;
hw = clk_hw_register_gpio_gate(dev, name, parent_name, gpio, active_low,
flags);
if (IS_ERR(hw))
return ERR_CAST(hw);
return hw->clk;
}
EXPORT_SYMBOL_GPL(clk_register_gpio_gate);
/**
* clk_register_gpio_mux - register a gpio clock mux with the clock framework
* clk_hw_register_gpio_mux - register a gpio clock mux with the clock framework
* @dev: device that is registering this clock
* @name: name of this clock
* @parent_names: names of this clock's parents
@ -187,7 +203,7 @@ EXPORT_SYMBOL_GPL(clk_register_gpio_gate);
* @active_low: true if gpio should be set to 0 to enable clock
* @flags: clock flags
*/
struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
struct clk_hw *clk_hw_register_gpio_mux(struct device *dev, const char *name,
const char * const *parent_names, u8 num_parents, unsigned gpio,
bool active_low, unsigned long flags)
{
@ -199,6 +215,20 @@ struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
return clk_register_gpio(dev, name, parent_names, num_parents,
gpio, active_low, flags, &clk_gpio_mux_ops);
}
EXPORT_SYMBOL_GPL(clk_hw_register_gpio_mux);
struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
const char * const *parent_names, u8 num_parents, unsigned gpio,
bool active_low, unsigned long flags)
{
struct clk_hw *hw;
hw = clk_hw_register_gpio_mux(dev, name, parent_names, num_parents,
gpio, active_low, flags);
if (IS_ERR(hw))
return ERR_CAST(hw);
return hw->clk;
}
EXPORT_SYMBOL_GPL(clk_register_gpio_mux);
static int gpio_clk_driver_probe(struct platform_device *pdev)

View File

@ -113,16 +113,17 @@ const struct clk_ops clk_mux_ro_ops = {
};
EXPORT_SYMBOL_GPL(clk_mux_ro_ops);
struct clk *clk_register_mux_table(struct device *dev, const char *name,
struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
const char * const *parent_names, u8 num_parents,
unsigned long flags,
void __iomem *reg, u8 shift, u32 mask,
u8 clk_mux_flags, u32 *table, spinlock_t *lock)
{
struct clk_mux *mux;
struct clk *clk;
struct clk_hw *hw;
struct clk_init_data init;
u8 width = 0;
int ret;
if (clk_mux_flags & CLK_MUX_HIWORD_MASK) {
width = fls(mask) - ffs(mask) + 1;
@ -157,12 +158,31 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name,
mux->table = table;
mux->hw.init = &init;
clk = clk_register(dev, &mux->hw);
if (IS_ERR(clk))
hw = &mux->hw;
ret = clk_hw_register(dev, hw);
if (ret) {
kfree(mux);
hw = ERR_PTR(ret);
}
return clk;
return hw;
}
EXPORT_SYMBOL_GPL(clk_hw_register_mux_table);
struct clk *clk_register_mux_table(struct device *dev, const char *name,
const char * const *parent_names, u8 num_parents,
unsigned long flags,
void __iomem *reg, u8 shift, u32 mask,
u8 clk_mux_flags, u32 *table, spinlock_t *lock)
{
struct clk_hw *hw;
hw = clk_hw_register_mux_table(dev, name, parent_names, num_parents,
flags, reg, shift, mask, clk_mux_flags,
table, lock);
if (IS_ERR(hw))
return ERR_CAST(hw);
return hw->clk;
}
EXPORT_SYMBOL_GPL(clk_register_mux_table);
@ -180,6 +200,20 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
}
EXPORT_SYMBOL_GPL(clk_register_mux);
struct clk_hw *clk_hw_register_mux(struct device *dev, const char *name,
const char * const *parent_names, u8 num_parents,
unsigned long flags,
void __iomem *reg, u8 shift, u8 width,
u8 clk_mux_flags, spinlock_t *lock)
{
u32 mask = BIT(width) - 1;
return clk_hw_register_mux_table(dev, name, parent_names, num_parents,
flags, reg, shift, mask, clk_mux_flags,
NULL, lock);
}
EXPORT_SYMBOL_GPL(clk_hw_register_mux);
void clk_unregister_mux(struct clk *clk)
{
struct clk_mux *mux;
@ -195,3 +229,14 @@ void clk_unregister_mux(struct clk *clk)
kfree(mux);
}
EXPORT_SYMBOL_GPL(clk_unregister_mux);
void clk_hw_unregister_mux(struct clk_hw *hw)
{
struct clk_mux *mux;
mux = to_clk_mux(hw);
clk_hw_unregister(hw);
kfree(mux);
}
EXPORT_SYMBOL_GPL(clk_hw_unregister_mux);

View File

@ -2547,6 +2547,22 @@ fail_out:
}
EXPORT_SYMBOL_GPL(clk_register);
/**
* clk_hw_register - register a clk_hw and return an error code
* @dev: device that is registering this clock
* @hw: link to hardware-specific clock data
*
* clk_hw_register is the primary interface for populating the clock tree with
* new clock nodes. It returns an integer equal to zero indicating success or
* less than zero indicating failure. Drivers must test for an error code after
* calling clk_hw_register().
*/
int clk_hw_register(struct device *dev, struct clk_hw *hw)
{
return PTR_ERR_OR_ZERO(clk_register(dev, hw));
}
EXPORT_SYMBOL_GPL(clk_hw_register);
/* Free memory allocated for a clock. */
static void __clk_release(struct kref *ref)
{
@ -2648,11 +2664,26 @@ unlock:
}
EXPORT_SYMBOL_GPL(clk_unregister);
/**
* clk_hw_unregister - unregister a currently registered clk_hw
* @hw: hardware-specific clock data to unregister
*/
void clk_hw_unregister(struct clk_hw *hw)
{
clk_unregister(hw->clk);
}
EXPORT_SYMBOL_GPL(clk_hw_unregister);
static void devm_clk_release(struct device *dev, void *res)
{
clk_unregister(*(struct clk **)res);
}
static void devm_clk_hw_release(struct device *dev, void *res)
{
clk_hw_unregister(*(struct clk_hw **)res);
}
/**
* devm_clk_register - resource managed clk_register()
* @dev: device that is registering this clock
@ -2683,6 +2714,36 @@ struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw)
}
EXPORT_SYMBOL_GPL(devm_clk_register);
/**
* devm_clk_hw_register - resource managed clk_hw_register()
* @dev: device that is registering this clock
* @hw: link to hardware-specific clock data
*
* Managed clk_hw_register(). Clocks returned from this function are
* automatically clk_hw_unregister()ed on driver detach. See clk_hw_register()
* for more information.
*/
int devm_clk_hw_register(struct device *dev, struct clk_hw *hw)
{
struct clk_hw **hwp;
int ret;
hwp = devres_alloc(devm_clk_hw_release, sizeof(*hwp), GFP_KERNEL);
if (!hwp)
return -ENOMEM;
ret = clk_hw_register(dev, hw);
if (!ret) {
*hwp = hw;
devres_add(dev, hwp);
} else {
devres_free(hwp);
}
return ret;
}
EXPORT_SYMBOL_GPL(devm_clk_hw_register);
static int devm_clk_match(struct device *dev, void *res, void *data)
{
struct clk *c = res;
@ -2691,6 +2752,15 @@ static int devm_clk_match(struct device *dev, void *res, void *data)
return c == data;
}
static int devm_clk_hw_match(struct device *dev, void *res, void *data)
{
struct clk_hw *hw = res;
if (WARN_ON(!hw))
return 0;
return hw == data;
}
/**
* devm_clk_unregister - resource managed clk_unregister()
* @clk: clock to unregister
@ -2705,6 +2775,22 @@ void devm_clk_unregister(struct device *dev, struct clk *clk)
}
EXPORT_SYMBOL_GPL(devm_clk_unregister);
/**
* devm_clk_hw_unregister - resource managed clk_hw_unregister()
* @dev: device that is unregistering the hardware-specific clock data
* @hw: link to hardware-specific clock data
*
* Unregister a clk_hw registered with devm_clk_hw_register(). Normally
* this function will not need to be called and the resource management
* code will ensure that the resource is freed.
*/
void devm_clk_hw_unregister(struct device *dev, struct clk_hw *hw)
{
WARN_ON(devres_release(dev, devm_clk_hw_release, devm_clk_hw_match,
hw));
}
EXPORT_SYMBOL_GPL(devm_clk_hw_unregister);
/*
* clkdev helpers
*/
@ -2866,6 +2952,7 @@ struct of_clk_provider {
struct device_node *node;
struct clk *(*get)(struct of_phandle_args *clkspec, void *data);
struct clk_hw *(*get_hw)(struct of_phandle_args *clkspec, void *data);
void *data;
};
@ -2882,6 +2969,12 @@ struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
}
EXPORT_SYMBOL_GPL(of_clk_src_simple_get);
struct clk_hw *of_clk_hw_simple_get(struct of_phandle_args *clkspec, void *data)
{
return data;
}
EXPORT_SYMBOL_GPL(of_clk_hw_simple_get);
struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data)
{
struct clk_onecell_data *clk_data = data;
@ -2896,6 +2989,21 @@ struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data)
}
EXPORT_SYMBOL_GPL(of_clk_src_onecell_get);
struct clk_hw *
of_clk_hw_onecell_get(struct of_phandle_args *clkspec, void *data)
{
struct clk_hw_onecell_data *hw_data = data;
unsigned int idx = clkspec->args[0];
if (idx >= hw_data->num) {
pr_err("%s: invalid index %u\n", __func__, idx);
return ERR_PTR(-EINVAL);
}
return hw_data->hws[idx];
}
EXPORT_SYMBOL_GPL(of_clk_hw_onecell_get);
/**
* of_clk_add_provider() - Register a clock provider for a node
* @np: Device node pointer associated with clock provider
@ -2931,6 +3039,41 @@ int of_clk_add_provider(struct device_node *np,
}
EXPORT_SYMBOL_GPL(of_clk_add_provider);
/**
* of_clk_add_hw_provider() - Register a clock provider for a node
* @np: Device node pointer associated with clock provider
* @get: callback for decoding clk_hw
* @data: context pointer for @get callback.
*/
int of_clk_add_hw_provider(struct device_node *np,
struct clk_hw *(*get)(struct of_phandle_args *clkspec,
void *data),
void *data)
{
struct of_clk_provider *cp;
int ret;
cp = kzalloc(sizeof(*cp), GFP_KERNEL);
if (!cp)
return -ENOMEM;
cp->node = of_node_get(np);
cp->data = data;
cp->get_hw = get;
mutex_lock(&of_clk_mutex);
list_add(&cp->link, &of_clk_providers);
mutex_unlock(&of_clk_mutex);
pr_debug("Added clk_hw provider from %s\n", np->full_name);
ret = of_clk_set_defaults(np, true);
if (ret < 0)
of_clk_del_provider(np);
return ret;
}
EXPORT_SYMBOL_GPL(of_clk_add_hw_provider);
/**
* of_clk_del_provider() - Remove a previously registered clock provider
* @np: Device node pointer associated with clock provider
@ -2952,11 +3095,32 @@ void of_clk_del_provider(struct device_node *np)
}
EXPORT_SYMBOL_GPL(of_clk_del_provider);
static struct clk_hw *
__of_clk_get_hw_from_provider(struct of_clk_provider *provider,
struct of_phandle_args *clkspec)
{
struct clk *clk;
struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER);
if (provider->get_hw) {
hw = provider->get_hw(clkspec, provider->data);
} else if (provider->get) {
clk = provider->get(clkspec, provider->data);
if (!IS_ERR(clk))
hw = __clk_get_hw(clk);
else
hw = ERR_CAST(clk);
}
return hw;
}
struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
const char *dev_id, const char *con_id)
{
struct of_clk_provider *provider;
struct clk *clk = ERR_PTR(-EPROBE_DEFER);
struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER);
if (!clkspec)
return ERR_PTR(-EINVAL);
@ -2965,10 +3129,9 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
mutex_lock(&of_clk_mutex);
list_for_each_entry(provider, &of_clk_providers, link) {
if (provider->node == clkspec->np)
clk = provider->get(clkspec, provider->data);
if (!IS_ERR(clk)) {
clk = __clk_create_clk(__clk_get_hw(clk), dev_id,
con_id);
hw = __of_clk_get_hw_from_provider(provider, clkspec);
if (!IS_ERR(hw)) {
clk = __clk_create_clk(hw, dev_id, con_id);
if (!IS_ERR(clk) && !__clk_get(clk)) {
__clk_free_clk(clk);

View File

@ -301,6 +301,20 @@ clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
}
EXPORT_SYMBOL(clkdev_alloc);
struct clk_lookup *
clkdev_hw_alloc(struct clk_hw *hw, const char *con_id, const char *dev_fmt, ...)
{
struct clk_lookup *cl;
va_list ap;
va_start(ap, dev_fmt);
cl = vclkdev_alloc(hw, con_id, dev_fmt, ap);
va_end(ap);
return cl;
}
EXPORT_SYMBOL(clkdev_hw_alloc);
/**
* clkdev_create - allocate and add a clkdev lookup structure
* @clk: struct clk to associate with all clk_lookups
@ -324,6 +338,29 @@ struct clk_lookup *clkdev_create(struct clk *clk, const char *con_id,
}
EXPORT_SYMBOL_GPL(clkdev_create);
/**
* clkdev_hw_create - allocate and add a clkdev lookup structure
* @hw: struct clk_hw to associate with all clk_lookups
* @con_id: connection ID string on device
* @dev_fmt: format string describing device name
*
* Returns a clk_lookup structure, which can be later unregistered and
* freed.
*/
struct clk_lookup *clkdev_hw_create(struct clk_hw *hw, const char *con_id,
const char *dev_fmt, ...)
{
struct clk_lookup *cl;
va_list ap;
va_start(ap, dev_fmt);
cl = vclkdev_create(hw, con_id, dev_fmt, ap);
va_end(ap);
return cl;
}
EXPORT_SYMBOL_GPL(clkdev_hw_create);
int clk_add_alias(const char *alias, const char *alias_dev_name,
const char *con_id, struct device *dev)
{
@ -404,28 +441,28 @@ int clk_register_clkdev(struct clk *clk, const char *con_id,
EXPORT_SYMBOL(clk_register_clkdev);
/**
* clk_register_clkdevs - register a set of clk_lookup for a struct clk
* @clk: struct clk to associate with all clk_lookups
* @cl: array of clk_lookup structures with con_id and dev_id pre-initialized
* @num: number of clk_lookup structures to register
* clk_hw_register_clkdev - register one clock lookup for a struct clk_hw
* @hw: struct clk_hw to associate with all clk_lookups
* @con_id: connection ID string on device
* @dev_id: format string describing device name
*
* To make things easier for mass registration, we detect error clks
* from a previous clk_register() call, and return the error code for
* those. This is to permit this function to be called immediately
* after clk_register().
* con_id or dev_id may be NULL as a wildcard, just as in the rest of
* clkdev.
*/
int clk_register_clkdevs(struct clk *clk, struct clk_lookup *cl, size_t num)
int clk_hw_register_clkdev(struct clk_hw *hw, const char *con_id,
const char *dev_id)
{
unsigned i;
struct clk_lookup *cl;
if (IS_ERR(clk))
return PTR_ERR(clk);
/*
* Since dev_id can be NULL, and NULL is handled specially, we must
* pass it as either a NULL format string, or with "%s".
*/
if (dev_id)
cl = __clk_register_clkdev(hw, con_id, "%s", dev_id);
else
cl = __clk_register_clkdev(hw, con_id, NULL);
for (i = 0; i < num; i++, cl++) {
cl->clk_hw = __clk_get_hw(clk);
__clkdev_add(cl);
}
return 0;
return cl ? 0 : -ENOMEM;
}
EXPORT_SYMBOL(clk_register_clkdevs);
EXPORT_SYMBOL(clk_hw_register_clkdev);

View File

@ -283,10 +283,17 @@ extern const struct clk_ops clk_fixed_rate_ops;
struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
unsigned long fixed_rate);
struct clk_hw *clk_hw_register_fixed_rate(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
unsigned long fixed_rate);
struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev,
const char *name, const char *parent_name, unsigned long flags,
unsigned long fixed_rate, unsigned long fixed_accuracy);
void clk_unregister_fixed_rate(struct clk *clk);
struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev,
const char *name, const char *parent_name, unsigned long flags,
unsigned long fixed_rate, unsigned long fixed_accuracy);
void of_fixed_clk_setup(struct device_node *np);
/**
@ -327,7 +334,12 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
void __iomem *reg, u8 bit_idx,
u8 clk_gate_flags, spinlock_t *lock);
struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
void __iomem *reg, u8 bit_idx,
u8 clk_gate_flags, spinlock_t *lock);
void clk_unregister_gate(struct clk *clk);
void clk_hw_unregister_gate(struct clk_hw *hw);
struct clk_div_table {
unsigned int val;
@ -408,12 +420,22 @@ struct clk *clk_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_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,
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);
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_hw_unregister_divider(struct clk_hw *hw);
/**
* struct clk_mux - multiplexer clock
@ -464,14 +486,25 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
unsigned long flags,
void __iomem *reg, u8 shift, u8 width,
u8 clk_mux_flags, spinlock_t *lock);
struct clk_hw *clk_hw_register_mux(struct device *dev, const char *name,
const char * const *parent_names, u8 num_parents,
unsigned long flags,
void __iomem *reg, u8 shift, u8 width,
u8 clk_mux_flags, spinlock_t *lock);
struct clk *clk_register_mux_table(struct device *dev, const char *name,
const char * const *parent_names, u8 num_parents,
unsigned long flags,
void __iomem *reg, u8 shift, u32 mask,
u8 clk_mux_flags, u32 *table, spinlock_t *lock);
struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
const char * const *parent_names, u8 num_parents,
unsigned long flags,
void __iomem *reg, u8 shift, u32 mask,
u8 clk_mux_flags, u32 *table, spinlock_t *lock);
void clk_unregister_mux(struct clk *clk);
void clk_hw_unregister_mux(struct clk_hw *hw);
void of_fixed_factor_clk_setup(struct device_node *node);
@ -500,6 +533,10 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
unsigned int mult, unsigned int div);
void clk_unregister_fixed_factor(struct clk *clk);
struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
const char *name, const char *parent_name, unsigned long flags,
unsigned int mult, unsigned int div);
void clk_hw_unregister_fixed_factor(struct clk_hw *hw);
/**
* struct clk_fractional_divider - adjustable fractional divider clock
@ -534,6 +571,11 @@ struct clk *clk_register_fractional_divider(struct device *dev,
const char *name, const char *parent_name, unsigned long flags,
void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth,
u8 clk_divider_flags, spinlock_t *lock);
struct clk_hw *clk_hw_register_fractional_divider(struct device *dev,
const char *name, const char *parent_name, unsigned long flags,
void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth,
u8 clk_divider_flags, spinlock_t *lock);
void clk_hw_unregister_fractional_divider(struct clk_hw *hw);
/**
* struct clk_multiplier - adjustable multiplier clock
@ -605,6 +647,13 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
unsigned long flags);
void clk_unregister_composite(struct clk *clk);
struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name,
const char * const *parent_names, int num_parents,
struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
unsigned long flags);
void clk_hw_unregister_composite(struct clk_hw *hw);
/***
* struct clk_gpio_gate - gpio gated clock
@ -627,6 +676,10 @@ extern const struct clk_ops clk_gpio_gate_ops;
struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
const char *parent_name, unsigned gpio, bool active_low,
unsigned long flags);
struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name,
const char *parent_name, unsigned gpio, bool active_low,
unsigned long flags);
void clk_hw_unregister_gpio_gate(struct clk_hw *hw);
/**
* struct clk_gpio_mux - gpio controlled clock multiplexer
@ -642,6 +695,10 @@ extern const struct clk_ops clk_gpio_mux_ops;
struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
const char * const *parent_names, u8 num_parents, unsigned gpio,
bool active_low, unsigned long flags);
struct clk_hw *clk_hw_register_gpio_mux(struct device *dev, const char *name,
const char * const *parent_names, u8 num_parents, unsigned gpio,
bool active_low, unsigned long flags);
void clk_hw_unregister_gpio_mux(struct clk_hw *hw);
/**
* clk_register - allocate a new clock, register it and return an opaque cookie
@ -657,9 +714,15 @@ struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
struct clk *clk_register(struct device *dev, struct clk_hw *hw);
struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw);
int __must_check clk_hw_register(struct device *dev, struct clk_hw *hw);
int __must_check devm_clk_hw_register(struct device *dev, struct clk_hw *hw);
void clk_unregister(struct clk *clk);
void devm_clk_unregister(struct device *dev, struct clk *clk);
void clk_hw_unregister(struct clk_hw *hw);
void devm_clk_hw_unregister(struct device *dev, struct clk_hw *hw);
/* helper functions */
const char *__clk_get_name(const struct clk *clk);
const char *clk_hw_get_name(const struct clk_hw *hw);
@ -705,6 +768,11 @@ struct clk_onecell_data {
unsigned int clk_num;
};
struct clk_hw_onecell_data {
size_t num;
struct clk_hw *hws[];
};
extern struct of_device_id __clk_of_table;
#define CLK_OF_DECLARE(name, compat, fn) OF_DECLARE_1(clk, name, compat, fn)
@ -714,10 +782,18 @@ int of_clk_add_provider(struct device_node *np,
struct clk *(*clk_src_get)(struct of_phandle_args *args,
void *data),
void *data);
int of_clk_add_hw_provider(struct device_node *np,
struct clk_hw *(*get)(struct of_phandle_args *clkspec,
void *data),
void *data);
void of_clk_del_provider(struct device_node *np);
struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
void *data);
struct clk_hw *of_clk_hw_simple_get(struct of_phandle_args *clkspec,
void *data);
struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data);
struct clk_hw *of_clk_hw_onecell_get(struct of_phandle_args *clkspec,
void *data);
unsigned int of_clk_get_parent_count(struct device_node *np);
int of_clk_parent_fill(struct device_node *np, const char **parents,
unsigned int size);
@ -735,17 +811,34 @@ static inline int of_clk_add_provider(struct device_node *np,
{
return 0;
}
static inline int of_clk_add_hw_provider(struct device_node *np,
struct clk_hw *(*get)(struct of_phandle_args *clkspec,
void *data),
void *data)
{
return 0;
}
static inline void of_clk_del_provider(struct device_node *np) {}
static inline struct clk *of_clk_src_simple_get(
struct of_phandle_args *clkspec, void *data)
{
return ERR_PTR(-ENOENT);
}
static inline struct clk_hw *
of_clk_hw_simple_get(struct of_phandle_args *clkspec, void *data)
{
return ERR_PTR(-ENOENT);
}
static inline struct clk *of_clk_src_onecell_get(
struct of_phandle_args *clkspec, void *data)
{
return ERR_PTR(-ENOENT);
}
static inline struct clk_hw *
of_clk_hw_onecell_get(struct of_phandle_args *clkspec, void *data)
{
return ERR_PTR(-ENOENT);
}
static inline int of_clk_get_parent_count(struct device_node *np)
{
return 0;

View File

@ -15,6 +15,7 @@
#include <asm/clkdev.h>
struct clk;
struct clk_hw;
struct device;
struct clk_lookup {
@ -34,18 +35,22 @@ struct clk_lookup {
struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
const char *dev_fmt, ...) __printf(3, 4);
struct clk_lookup *clkdev_hw_alloc(struct clk_hw *hw, const char *con_id,
const char *dev_fmt, ...) __printf(3, 4);
void clkdev_add(struct clk_lookup *cl);
void clkdev_drop(struct clk_lookup *cl);
struct clk_lookup *clkdev_create(struct clk *clk, const char *con_id,
const char *dev_fmt, ...) __printf(3, 4);
struct clk_lookup *clkdev_hw_create(struct clk_hw *hw, const char *con_id,
const char *dev_fmt, ...) __printf(3, 4);
void clkdev_add_table(struct clk_lookup *, size_t);
int clk_add_alias(const char *, const char *, const char *, struct device *);
int clk_register_clkdev(struct clk *, const char *, const char *);
int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t);
int clk_hw_register_clkdev(struct clk_hw *, const char *, const char *);
#ifdef CONFIG_COMMON_CLK
int __clk_get(struct clk *clk);