Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 336478
b: refs/heads/master
c: 46c8773
h: refs/heads/master
v: v3
  • Loading branch information
Stephen Boyd authored and Mike Turquette committed Oct 29, 2012
1 parent 82b08c5 commit 4efeeb7
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 22 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 980f58a45e04b248e9dd01b0eba510a3384160db
refs/heads/master: 46c8773a58010d31f228e148b8b774d94cc9810d
111 changes: 90 additions & 21 deletions trunk/drivers/clk/clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/device.h>

static DEFINE_SPINLOCK(enable_lock);
static DEFINE_MUTEX(prepare_lock);
Expand Down Expand Up @@ -1361,28 +1362,9 @@ struct clk *__clk_register(struct device *dev, struct clk_hw *hw)
}
EXPORT_SYMBOL_GPL(__clk_register);

/**
* clk_register - allocate a new clock, register it and return an opaque cookie
* @dev: device that is registering this clock
* @hw: link to hardware-specific clock data
*
* clk_register is the primary interface for populating the clock tree with new
* clock nodes. It returns a pointer to the newly allocated struct clk which
* cannot be dereferenced by driver code but may be used in conjuction with the
* rest of the clock API. In the event of an error clk_register will return an
* error code; drivers must test for an error code after calling clk_register.
*/
struct clk *clk_register(struct device *dev, struct clk_hw *hw)
static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk)
{
int i, ret;
struct clk *clk;

clk = kzalloc(sizeof(*clk), GFP_KERNEL);
if (!clk) {
pr_err("%s: could not allocate clk\n", __func__);
ret = -ENOMEM;
goto fail_out;
}

clk->name = kstrdup(hw->init->name, GFP_KERNEL);
if (!clk->name) {
Expand Down Expand Up @@ -1420,7 +1402,7 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)

ret = __clk_init(dev, clk);
if (!ret)
return clk;
return 0;

fail_parent_names_copy:
while (--i >= 0)
Expand All @@ -1429,6 +1411,36 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
fail_parent_names:
kfree(clk->name);
fail_name:
return ret;
}

/**
* clk_register - allocate a new clock, register it and return an opaque cookie
* @dev: device that is registering this clock
* @hw: link to hardware-specific clock data
*
* clk_register is the primary interface for populating the clock tree with new
* clock nodes. It returns a pointer to the newly allocated struct clk which
* cannot be dereferenced by driver code but may be used in conjuction with the
* rest of the clock API. In the event of an error clk_register will return an
* error code; drivers must test for an error code after calling clk_register.
*/
struct clk *clk_register(struct device *dev, struct clk_hw *hw)
{
int ret;
struct clk *clk;

clk = kzalloc(sizeof(*clk), GFP_KERNEL);
if (!clk) {
pr_err("%s: could not allocate clk\n", __func__);
ret = -ENOMEM;
goto fail_out;
}

ret = _clk_register(dev, hw, clk);
if (!ret)
return clk;

kfree(clk);
fail_out:
return ERR_PTR(ret);
Expand All @@ -1444,6 +1456,63 @@ EXPORT_SYMBOL_GPL(clk_register);
void clk_unregister(struct clk *clk) {}
EXPORT_SYMBOL_GPL(clk_unregister);

static void devm_clk_release(struct device *dev, void *res)
{
clk_unregister(res);
}

/**
* devm_clk_register - resource managed clk_register()
* @dev: device that is registering this clock
* @hw: link to hardware-specific clock data
*
* Managed clk_register(). Clocks returned from this function are
* automatically clk_unregister()ed on driver detach. See clk_register() for
* more information.
*/
struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw)
{
struct clk *clk;
int ret;

clk = devres_alloc(devm_clk_release, sizeof(*clk), GFP_KERNEL);
if (!clk)
return ERR_PTR(-ENOMEM);

ret = _clk_register(dev, hw, clk);
if (!ret) {
devres_add(dev, clk);
} else {
devres_free(clk);
clk = ERR_PTR(ret);
}

return clk;
}
EXPORT_SYMBOL_GPL(devm_clk_register);

static int devm_clk_match(struct device *dev, void *res, void *data)
{
struct clk *c = res;
if (WARN_ON(!c))
return 0;
return c == data;
}

/**
* devm_clk_unregister - resource managed clk_unregister()
* @clk: clock to unregister
*
* Deallocate a clock allocated with devm_clk_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_unregister(struct device *dev, struct clk *clk)
{
WARN_ON(devres_release(dev, devm_clk_release, devm_clk_match, clk));
}
EXPORT_SYMBOL_GPL(devm_clk_unregister);

/*** clk rate change notifiers ***/

/**
Expand Down
2 changes: 2 additions & 0 deletions trunk/include/linux/clk-provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,8 +331,10 @@ struct clk *clk_register_fixed_factor(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 *devm_clk_register(struct device *dev, struct clk_hw *hw);

void clk_unregister(struct clk *clk);
void devm_clk_unregister(struct device *dev, struct clk *clk);

/* helper functions */
const char *__clk_get_name(struct clk *clk);
Expand Down

0 comments on commit 4efeeb7

Please sign in to comment.