|
@@ -37,23 +37,49 @@
|
|
#include "clk.h"
|
|
#include "clk.h"
|
|
|
|
|
|
static DEFINE_SPINLOCK(hisi_clk_lock);
|
|
static DEFINE_SPINLOCK(hisi_clk_lock);
|
|
-static struct clk **clk_table;
|
|
|
|
-static struct clk_onecell_data clk_data;
|
|
|
|
|
|
|
|
-void __init hisi_clk_init(struct device_node *np, int nr_clks)
|
|
|
|
|
|
+struct hisi_clock_data __init *hisi_clk_init(struct device_node *np,
|
|
|
|
+ int nr_clks)
|
|
{
|
|
{
|
|
|
|
+ struct hisi_clock_data *clk_data;
|
|
|
|
+ struct clk **clk_table;
|
|
|
|
+ void __iomem *base;
|
|
|
|
+
|
|
|
|
+ if (np) {
|
|
|
|
+ base = of_iomap(np, 0);
|
|
|
|
+ if (!base) {
|
|
|
|
+ pr_err("failed to map Hisilicon clock registers\n");
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ pr_err("failed to find Hisilicon clock node in DTS\n");
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
|
|
|
|
+ if (!clk_data) {
|
|
|
|
+ pr_err("%s: could not allocate clock data\n", __func__);
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+ clk_data->base = base;
|
|
|
|
+
|
|
clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL);
|
|
clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL);
|
|
if (!clk_table) {
|
|
if (!clk_table) {
|
|
pr_err("%s: could not allocate clock lookup table\n", __func__);
|
|
pr_err("%s: could not allocate clock lookup table\n", __func__);
|
|
- return;
|
|
|
|
|
|
+ goto err_data;
|
|
}
|
|
}
|
|
- clk_data.clks = clk_table;
|
|
|
|
- clk_data.clk_num = nr_clks;
|
|
|
|
- of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
|
|
|
|
|
|
+ clk_data->clk_data.clks = clk_table;
|
|
|
|
+ clk_data->clk_data.clk_num = nr_clks;
|
|
|
|
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data->clk_data);
|
|
|
|
+ return clk_data;
|
|
|
|
+err_data:
|
|
|
|
+ kfree(clk_data);
|
|
|
|
+err:
|
|
|
|
+ return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
void __init hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *clks,
|
|
void __init hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *clks,
|
|
- int nums, void __iomem *base)
|
|
|
|
|
|
+ int nums, struct hisi_clock_data *data)
|
|
{
|
|
{
|
|
struct clk *clk;
|
|
struct clk *clk;
|
|
int i;
|
|
int i;
|
|
@@ -68,12 +94,13 @@ void __init hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *clks,
|
|
__func__, clks[i].name);
|
|
__func__, clks[i].name);
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
- clk_table[clks[i].id] = clk;
|
|
|
|
|
|
+ data->clk_data.clks[clks[i].id] = clk;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void __init hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *clks,
|
|
void __init hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *clks,
|
|
- int nums, void __iomem *base)
|
|
|
|
|
|
+ int nums,
|
|
|
|
+ struct hisi_clock_data *data)
|
|
{
|
|
{
|
|
struct clk *clk;
|
|
struct clk *clk;
|
|
int i;
|
|
int i;
|
|
@@ -88,14 +115,15 @@ void __init hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *clks,
|
|
__func__, clks[i].name);
|
|
__func__, clks[i].name);
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
- clk_table[clks[i].id] = clk;
|
|
|
|
|
|
+ data->clk_data.clks[clks[i].id] = clk;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void __init hisi_clk_register_mux(struct hisi_mux_clock *clks,
|
|
void __init hisi_clk_register_mux(struct hisi_mux_clock *clks,
|
|
- int nums, void __iomem *base)
|
|
|
|
|
|
+ int nums, struct hisi_clock_data *data)
|
|
{
|
|
{
|
|
struct clk *clk;
|
|
struct clk *clk;
|
|
|
|
+ void __iomem *base = data->base;
|
|
int i;
|
|
int i;
|
|
|
|
|
|
for (i = 0; i < nums; i++) {
|
|
for (i = 0; i < nums; i++) {
|
|
@@ -113,14 +141,15 @@ void __init hisi_clk_register_mux(struct hisi_mux_clock *clks,
|
|
if (clks[i].alias)
|
|
if (clks[i].alias)
|
|
clk_register_clkdev(clk, clks[i].alias, NULL);
|
|
clk_register_clkdev(clk, clks[i].alias, NULL);
|
|
|
|
|
|
- clk_table[clks[i].id] = clk;
|
|
|
|
|
|
+ data->clk_data.clks[clks[i].id] = clk;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void __init hisi_clk_register_divider(struct hisi_divider_clock *clks,
|
|
void __init hisi_clk_register_divider(struct hisi_divider_clock *clks,
|
|
- int nums, void __iomem *base)
|
|
|
|
|
|
+ int nums, struct hisi_clock_data *data)
|
|
{
|
|
{
|
|
struct clk *clk;
|
|
struct clk *clk;
|
|
|
|
+ void __iomem *base = data->base;
|
|
int i;
|
|
int i;
|
|
|
|
|
|
for (i = 0; i < nums; i++) {
|
|
for (i = 0; i < nums; i++) {
|
|
@@ -141,14 +170,15 @@ void __init hisi_clk_register_divider(struct hisi_divider_clock *clks,
|
|
if (clks[i].alias)
|
|
if (clks[i].alias)
|
|
clk_register_clkdev(clk, clks[i].alias, NULL);
|
|
clk_register_clkdev(clk, clks[i].alias, NULL);
|
|
|
|
|
|
- clk_table[clks[i].id] = clk;
|
|
|
|
|
|
+ data->clk_data.clks[clks[i].id] = clk;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *clks,
|
|
void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *clks,
|
|
- int nums, void __iomem *base)
|
|
|
|
|
|
+ int nums, struct hisi_clock_data *data)
|
|
{
|
|
{
|
|
struct clk *clk;
|
|
struct clk *clk;
|
|
|
|
+ void __iomem *base = data->base;
|
|
int i;
|
|
int i;
|
|
|
|
|
|
for (i = 0; i < nums; i++) {
|
|
for (i = 0; i < nums; i++) {
|
|
@@ -168,6 +198,6 @@ void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *clks,
|
|
if (clks[i].alias)
|
|
if (clks[i].alias)
|
|
clk_register_clkdev(clk, clks[i].alias, NULL);
|
|
clk_register_clkdev(clk, clks[i].alias, NULL);
|
|
|
|
|
|
- clk_table[clks[i].id] = clk;
|
|
|
|
|
|
+ data->clk_data.clks[clks[i].id] = clk;
|
|
}
|
|
}
|
|
}
|
|
}
|