Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 308212
b: refs/heads/master
c: 0197b3e
h: refs/heads/master
v: v3
  • Loading branch information
Saravana Kannan authored and Mike Turquette committed May 2, 2012
1 parent 876caf0 commit 9529a81
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 75 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: e447c50e3af5dcad3075c80bd1bdc4e2024b8186
refs/heads/master: 0197b3ea0f66cd2a11417f58fe1812858ea77908
14 changes: 9 additions & 5 deletions trunk/drivers/clk/clk-divider.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ struct clk *clk_register_divider(struct device *dev, const char *name,
{
struct clk_divider *div;
struct clk *clk;
struct clk_init_data init;

/* allocate the divider */
div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL);
Expand All @@ -175,19 +176,22 @@ struct clk *clk_register_divider(struct device *dev, const char *name,
return ERR_PTR(-ENOMEM);
}

init.name = name;
init.ops = &clk_divider_ops;
init.flags = flags;
init.parent_names = (parent_name ? &parent_name: NULL);
init.num_parents = (parent_name ? 1 : 0);

/* struct clk_divider assignments */
div->reg = reg;
div->shift = shift;
div->width = width;
div->flags = clk_divider_flags;
div->lock = lock;
div->hw.init = &init;

/* register the clock */
clk = clk_register(dev, name,
&clk_divider_ops, &div->hw,
(parent_name ? &parent_name: NULL),
(parent_name ? 1 : 0),
flags);
clk = clk_register(dev, &div->hw);

if (IS_ERR(clk))
kfree(div);
Expand Down
14 changes: 9 additions & 5 deletions trunk/drivers/clk/clk-fixed-rate.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
{
struct clk_fixed_rate *fixed;
struct clk *clk;
struct clk_init_data init;

/* allocate fixed-rate clock */
fixed = kzalloc(sizeof(struct clk_fixed_rate), GFP_KERNEL);
Expand All @@ -60,15 +61,18 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
return ERR_PTR(-ENOMEM);
}

init.name = name;
init.ops = &clk_fixed_rate_ops;
init.flags = flags;
init.parent_names = (parent_name ? &parent_name: NULL);
init.num_parents = (parent_name ? 1 : 0);

/* struct clk_fixed_rate assignments */
fixed->fixed_rate = fixed_rate;
fixed->hw.init = &init;

/* register the clock */
clk = clk_register(dev, name,
&clk_fixed_rate_ops, &fixed->hw,
(parent_name ? &parent_name : NULL),
(parent_name ? 1 : 0),
flags);
clk = clk_register(dev, &fixed->hw);

if (IS_ERR(clk))
kfree(fixed);
Expand Down
15 changes: 9 additions & 6 deletions trunk/drivers/clk/clk-gate.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
{
struct clk_gate *gate;
struct clk *clk;
struct clk_init_data init;

/* allocate the gate */
gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
Expand All @@ -127,18 +128,20 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
return ERR_PTR(-ENOMEM);
}

init.name = name;
init.ops = &clk_gate_ops;
init.flags = flags;
init.parent_names = (parent_name ? &parent_name: NULL);
init.num_parents = (parent_name ? 1 : 0);

/* struct clk_gate assignments */
gate->reg = reg;
gate->bit_idx = bit_idx;
gate->flags = clk_gate_flags;
gate->lock = lock;
gate->hw.init = &init;

/* register the clock */
clk = clk_register(dev, name,
&clk_gate_ops, &gate->hw,
(parent_name ? &parent_name : NULL),
(parent_name ? 1 : 0),
flags);
clk = clk_register(dev, &gate->hw);

if (IS_ERR(clk))
kfree(gate);
Expand Down
10 changes: 8 additions & 2 deletions trunk/drivers/clk/clk-mux.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
{
struct clk_mux *mux;
struct clk *clk;
struct clk_init_data init;

/* allocate the mux */
mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
Expand All @@ -103,15 +104,20 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
return ERR_PTR(-ENOMEM);
}

init.name = name;
init.ops = &clk_mux_ops;
init.flags = flags;
init.parent_names = parent_names;
init.num_parents = num_parents;

/* struct clk_mux assignments */
mux->reg = reg;
mux->shift = shift;
mux->width = width;
mux->flags = clk_mux_flags;
mux->lock = lock;

clk = clk_register(dev, name, &clk_mux_ops, &mux->hw,
parent_names, num_parents, flags);
clk = clk_register(dev, &mux->hw);

if (IS_ERR(clk))
kfree(mux);
Expand Down
89 changes: 54 additions & 35 deletions trunk/drivers/clk/clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -1169,26 +1169,6 @@ EXPORT_SYMBOL_GPL(clk_set_parent);
*
* Initializes the lists in struct clk, queries the hardware for the
* parent and rate and sets them both.
*
* Any struct clk passed into __clk_init must have the following members
* populated:
* .name
* .ops
* .hw
* .parent_names
* .num_parents
* .flags
*
* Essentially, everything that would normally be passed into clk_register is
* assumed to be initialized already in __clk_init. The other members may be
* populated, but are optional.
*
* __clk_init is only exposed via clk-private.h and is intended for use with
* very large numbers of clocks that need to be statically initialized. It is
* a layering violation to include clk-private.h from any code which implements
* a clock's .ops; as such any statically initialized clock data MUST be in a
* separate C file from the logic that implements it's operations. Returns 0
* on success, otherwise an error code.
*/
int __clk_init(struct device *dev, struct clk *clk)
{
Expand Down Expand Up @@ -1320,25 +1300,56 @@ int __clk_init(struct device *dev, struct clk *clk)
return ret;
}

/**
* __clk_register - register a clock and return a cookie.
*
* Same as clk_register, except that the .clk field inside hw shall point to a
* preallocated (generally statically allocated) struct clk. None of the fields
* of the struct clk need to be initialized.
*
* The data pointed to by .init and .clk field shall NOT be marked as init
* data.
*
* __clk_register is only exposed via clk-private.h and is intended for use with
* very large numbers of clocks that need to be statically initialized. It is
* a layering violation to include clk-private.h from any code which implements
* a clock's .ops; as such any statically initialized clock data MUST be in a
* separate C file from the logic that implements it's operations. Returns 0
* on success, otherwise an error code.
*/
struct clk *__clk_register(struct device *dev, struct clk_hw *hw)
{
int ret;
struct clk *clk;

clk = hw->clk;
clk->name = hw->init->name;
clk->ops = hw->init->ops;
clk->hw = hw;
clk->flags = hw->init->flags;
clk->parent_names = hw->init->parent_names;
clk->num_parents = hw->init->num_parents;

ret = __clk_init(dev, clk);
if (ret)
return ERR_PTR(ret);

return clk;
}
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
* @name: clock name
* @ops: operations this clock supports
* @hw: link to hardware-specific clock data
* @parent_names: array of string names for all possible parents
* @num_parents: number of possible parents
* @flags: framework-level hints and quirks
*
* 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, const char *name,
const struct clk_ops *ops, struct clk_hw *hw,
const char **parent_names, u8 num_parents, unsigned long flags)
struct clk *clk_register(struct device *dev, struct clk_hw *hw)
{
int i, ret;
struct clk *clk;
Expand All @@ -1350,15 +1361,20 @@ struct clk *clk_register(struct device *dev, const char *name,
goto fail_out;
}

clk->name = name;
clk->ops = ops;
clk->name = kstrdup(hw->init->name, GFP_KERNEL);
if (!clk->name) {
pr_err("%s: could not allocate clk->name\n", __func__);
ret = -ENOMEM;
goto fail_name;
}
clk->ops = hw->init->ops;
clk->hw = hw;
clk->flags = flags;
clk->num_parents = num_parents;
clk->flags = hw->init->flags;
clk->num_parents = hw->init->num_parents;
hw->clk = clk;

/* allocate local copy in case parent_names is __initdata */
clk->parent_names = kzalloc((sizeof(char*) * num_parents),
clk->parent_names = kzalloc((sizeof(char*) * clk->num_parents),
GFP_KERNEL);

if (!clk->parent_names) {
Expand All @@ -1369,8 +1385,9 @@ struct clk *clk_register(struct device *dev, const char *name,


/* copy each string name in case parent_names is __initdata */
for (i = 0; i < num_parents; i++) {
clk->parent_names[i] = kstrdup(parent_names[i], GFP_KERNEL);
for (i = 0; i < clk->num_parents; i++) {
clk->parent_names[i] = kstrdup(hw->init->parent_names[i],
GFP_KERNEL);
if (!clk->parent_names[i]) {
pr_err("%s: could not copy parent_names\n", __func__);
ret = -ENOMEM;
Expand All @@ -1387,6 +1404,8 @@ struct clk *clk_register(struct device *dev, const char *name,
kfree(clk->parent_names[i]);
kfree(clk->parent_names);
fail_parent_names:
kfree(clk->name);
fail_name:
kfree(clk);
fail_out:
return ERR_PTR(ret);
Expand Down
2 changes: 2 additions & 0 deletions trunk/include/linux/clk-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,5 +167,7 @@ struct clk {
*/
int __clk_init(struct device *dev, struct clk *clk);

struct clk *__clk_register(struct device *dev, struct clk_hw *hw);

#endif /* CONFIG_COMMON_CLK */
#endif /* CLK_PRIVATE_H */
59 changes: 38 additions & 21 deletions trunk/include/linux/clk-provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,6 @@

#ifdef CONFIG_COMMON_CLK

/**
* 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
* clk_foo's clk_ops
*
* clk: pointer to the struct clk instance that points back to this struct
* clk_hw instance
*/
struct clk_hw {
struct clk *clk;
};

/*
* flags used across common struct clk. these flags should only affect the
* top-level framework. custom flags for dealing with hardware specifics
Expand All @@ -39,6 +26,8 @@ struct clk_hw {
#define CLK_IGNORE_UNUSED BIT(3) /* do not gate even if unused */
#define CLK_IS_ROOT BIT(4) /* root clk, has no parent */

struct clk_hw;

/**
* struct clk_ops - Callback operations for hardware clocks; these are to
* be provided by the clock implementation, and will be called by drivers
Expand Down Expand Up @@ -122,6 +111,41 @@ struct clk_ops {
void (*init)(struct clk_hw *hw);
};

/**
* struct clk_init_data - holds init data that's common to all clocks and is
* shared between the clock provider and the common clock framework.
*
* @name: clock name
* @ops: operations this clock supports
* @parent_names: array of string names for all possible parents
* @num_parents: number of possible parents
* @flags: framework-level hints and quirks
*/
struct clk_init_data {
const char *name;
const struct clk_ops *ops;
const char **parent_names;
u8 num_parents;
unsigned long flags;
};

/**
* 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
* clk_foo's clk_ops
*
* @clk: pointer to the struct clk instance that points back to this struct
* clk_hw instance
*
* @init: pointer to struct clk_init_data that contains the init data shared
* with the common clock framework.
*/
struct clk_hw {
struct clk *clk;
struct clk_init_data *init;
};

/*
* DOC: Basic clock implementations common to many platforms
*
Expand Down Expand Up @@ -255,22 +279,15 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
/**
* clk_register - allocate a new clock, register it and return an opaque cookie
* @dev: device that is registering this clock
* @name: clock name
* @ops: operations this clock supports
* @hw: link to hardware-specific clock data
* @parent_names: array of string names for all possible parents
* @num_parents: number of possible parents
* @flags: framework-level hints and quirks
*
* 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, const char *name,
const struct clk_ops *ops, struct clk_hw *hw,
const char **parent_names, u8 num_parents, unsigned long flags);
struct clk *clk_register(struct device *dev, struct clk_hw *hw);

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

0 comments on commit 9529a81

Please sign in to comment.