Commit 4f6be565 authored by Tero Kristo's avatar Tero Kristo

clk: ti: divider: add driver internal API for parsing divider data

This can be used from the divider itself, and also from the clkctrl
clocks once this is introduced.
Signed-off-by: default avatarTero Kristo <t-kristo@ti.com>
Acked-by: default avatarTony Lindgren <tony@atomide.com>
parent 6dbde947
...@@ -220,6 +220,10 @@ struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup); ...@@ -220,6 +220,10 @@ struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup);
struct clk_hw *ti_clk_build_component_gate(struct ti_clk_gate *setup); struct clk_hw *ti_clk_build_component_gate(struct ti_clk_gate *setup);
struct clk_hw *ti_clk_build_component_mux(struct ti_clk_mux *setup); struct clk_hw *ti_clk_build_component_mux(struct ti_clk_mux *setup);
int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div,
u8 flags, u8 *width,
const struct clk_div_table **table);
void ti_clk_patch_legacy_clks(struct ti_clk **patch); void ti_clk_patch_legacy_clks(struct ti_clk **patch);
struct clk *ti_clk_register_clk(struct ti_clk *setup); struct clk *ti_clk_register_clk(struct ti_clk *setup);
int ti_clk_register_legacy_clks(struct ti_clk_alias *clks); int ti_clk_register_legacy_clks(struct ti_clk_alias *clks);
......
...@@ -319,20 +319,17 @@ static struct clk *_register_divider(struct device *dev, const char *name, ...@@ -319,20 +319,17 @@ static struct clk *_register_divider(struct device *dev, const char *name,
return clk; return clk;
} }
static struct clk_div_table * int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div,
_get_div_table_from_setup(struct ti_clk_divider *setup, u8 *width) u8 flags, u8 *width,
const struct clk_div_table **table)
{ {
int valid_div = 0; int valid_div = 0;
struct clk_div_table *table;
int i;
int div;
u32 val; u32 val;
u8 flags; int div;
int i;
if (!setup->num_dividers) { struct clk_div_table *tmp;
/* Clk divider table not provided, determine min/max divs */
flags = setup->flags;
if (!div_table) {
if (flags & CLKF_INDEX_STARTS_AT_ONE) if (flags & CLKF_INDEX_STARTS_AT_ONE)
val = 1; val = 1;
else else
...@@ -340,7 +337,7 @@ _get_div_table_from_setup(struct ti_clk_divider *setup, u8 *width) ...@@ -340,7 +337,7 @@ _get_div_table_from_setup(struct ti_clk_divider *setup, u8 *width)
div = 1; div = 1;
while (div < setup->max_div) { while (div < max_div) {
if (flags & CLKF_INDEX_POWER_OF_TWO) if (flags & CLKF_INDEX_POWER_OF_TWO)
div <<= 1; div <<= 1;
else else
...@@ -349,30 +346,52 @@ _get_div_table_from_setup(struct ti_clk_divider *setup, u8 *width) ...@@ -349,30 +346,52 @@ _get_div_table_from_setup(struct ti_clk_divider *setup, u8 *width)
} }
*width = fls(val); *width = fls(val);
*table = NULL;
return NULL; return 0;
} }
for (i = 0; i < setup->num_dividers; i++) i = 0;
if (setup->dividers[i])
while (!num_dividers || i < num_dividers) {
if (div_table[i] == -1)
break;
if (div_table[i])
valid_div++; valid_div++;
i++;
}
table = kzalloc(sizeof(*table) * (valid_div + 1), GFP_KERNEL); num_dividers = i;
if (!table)
return ERR_PTR(-ENOMEM); tmp = kzalloc(sizeof(*tmp) * (valid_div + 1), GFP_KERNEL);
if (!tmp)
return -ENOMEM;
valid_div = 0; valid_div = 0;
*width = 0; *width = 0;
for (i = 0; i < setup->num_dividers; i++) for (i = 0; i < num_dividers; i++)
if (setup->dividers[i]) { if (div_table[i] > 0) {
table[valid_div].div = setup->dividers[i]; tmp[valid_div].div = div_table[i];
table[valid_div].val = i; tmp[valid_div].val = i;
valid_div++; valid_div++;
*width = i; *width = i;
} }
*width = fls(*width); *width = fls(*width);
*table = tmp;
return 0;
}
static const struct clk_div_table *
_get_div_table_from_setup(struct ti_clk_divider *setup, u8 *width)
{
const struct clk_div_table *table = NULL;
ti_clk_parse_divider_data(setup->dividers, setup->num_dividers,
setup->max_div, setup->flags, width,
&table);
return table; return table;
} }
...@@ -414,7 +433,7 @@ struct clk *ti_clk_register_divider(struct ti_clk *setup) ...@@ -414,7 +433,7 @@ struct clk *ti_clk_register_divider(struct ti_clk *setup)
u8 width; u8 width;
u32 flags = 0; u32 flags = 0;
u8 div_flags = 0; u8 div_flags = 0;
struct clk_div_table *table; const struct clk_div_table *table;
struct clk *clk; struct clk *clk;
div = setup->data; div = setup->data;
......
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