Commit 7f274d54 authored by Stephen Boyd's avatar Stephen Boyd

Merge tag 'clk-v4.13-samsung' of...

Merge tag 'clk-v4.13-samsung' of git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk into clk-next

Pull samsung clk driver updates from Sylwester Nawrocki

 - conversion to the clk_hw API
 - definitions and fixes of exynos5420 SoC audio subsystem
   related clocks

* tag 'clk-v4.13-samsung' of git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk:
  clk: samsung: exynos542x: Add EPLL rate table
  clk: samsung: Add missing exynos5420 audio related clocks
  clk: samsung: Add enable/disable operation for PLL36XX clocks
  clk: samsung: s5pv210-audss: Convert to the new clk_hw API
  clk: samsung: exynos-clkout: Convert to the new clk_hw API
  clk: samsung: exynos-audss: Convert to the new clk_hw API
  clk: samsung: Convert common drivers to the new clk_hw API
  clk: samsung: Add local variable to match its purpose
  clk: samsung: Remove dead code
parents c96da4dd 9842452a
...@@ -410,7 +410,7 @@ int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx, ...@@ -410,7 +410,7 @@ int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
{ {
struct exynos_cpuclk *cpuclk; struct exynos_cpuclk *cpuclk;
struct clk_init_data init; struct clk_init_data init;
struct clk *clk; struct clk *parent_clk;
int ret = 0; int ret = 0;
cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL); cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL);
...@@ -440,15 +440,15 @@ int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx, ...@@ -440,15 +440,15 @@ int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
goto free_cpuclk; goto free_cpuclk;
} }
clk = __clk_lookup(parent); parent_clk = __clk_lookup(parent);
if (!clk) { if (!parent_clk) {
pr_err("%s: could not lookup parent clock %s\n", pr_err("%s: could not lookup parent clock %s\n",
__func__, parent); __func__, parent);
ret = -EINVAL; ret = -EINVAL;
goto free_cpuclk; goto free_cpuclk;
} }
ret = clk_notifier_register(clk, &cpuclk->clk_nb); ret = clk_notifier_register(parent_clk, &cpuclk->clk_nb);
if (ret) { if (ret) {
pr_err("%s: failed to register clock notifier for %s\n", pr_err("%s: failed to register clock notifier for %s\n",
__func__, name); __func__, name);
...@@ -463,20 +463,19 @@ int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx, ...@@ -463,20 +463,19 @@ int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
goto unregister_clk_nb; goto unregister_clk_nb;
} }
clk = clk_register(NULL, &cpuclk->hw); ret = clk_hw_register(NULL, &cpuclk->hw);
if (IS_ERR(clk)) { if (ret) {
pr_err("%s: could not register cpuclk %s\n", __func__, name); pr_err("%s: could not register cpuclk %s\n", __func__, name);
ret = PTR_ERR(clk);
goto free_cpuclk_data; goto free_cpuclk_data;
} }
samsung_clk_add_lookup(ctx, clk, lookup_id); samsung_clk_add_lookup(ctx, &cpuclk->hw, lookup_id);
return 0; return 0;
free_cpuclk_data: free_cpuclk_data:
kfree(cpuclk->cfg); kfree(cpuclk->cfg);
unregister_clk_nb: unregister_clk_nb:
clk_notifier_unregister(__clk_lookup(parent), &cpuclk->clk_nb); clk_notifier_unregister(parent_clk, &cpuclk->clk_nb);
free_cpuclk: free_cpuclk:
kfree(cpuclk); kfree(cpuclk);
return ret; return ret;
......
...@@ -22,9 +22,8 @@ ...@@ -22,9 +22,8 @@
#include <dt-bindings/clock/exynos-audss-clk.h> #include <dt-bindings/clock/exynos-audss-clk.h>
static DEFINE_SPINLOCK(lock); static DEFINE_SPINLOCK(lock);
static struct clk **clk_table;
static void __iomem *reg_base; static void __iomem *reg_base;
static struct clk_onecell_data clk_data; static struct clk_hw_onecell_data *clk_data;
/* /*
* On Exynos5420 this will be a clock which has to be enabled before any * On Exynos5420 this will be a clock which has to be enabled before any
* access to audss registers. Typically a child of EPLL. * access to audss registers. Typically a child of EPLL.
...@@ -110,18 +109,18 @@ static void exynos_audss_clk_teardown(void) ...@@ -110,18 +109,18 @@ static void exynos_audss_clk_teardown(void)
int i; int i;
for (i = EXYNOS_MOUT_AUDSS; i < EXYNOS_DOUT_SRP; i++) { for (i = EXYNOS_MOUT_AUDSS; i < EXYNOS_DOUT_SRP; i++) {
if (!IS_ERR(clk_table[i])) if (!IS_ERR(clk_data->hws[i]))
clk_unregister_mux(clk_table[i]); clk_hw_unregister_mux(clk_data->hws[i]);
} }
for (; i < EXYNOS_SRP_CLK; i++) { for (; i < EXYNOS_SRP_CLK; i++) {
if (!IS_ERR(clk_table[i])) if (!IS_ERR(clk_data->hws[i]))
clk_unregister_divider(clk_table[i]); clk_hw_unregister_divider(clk_data->hws[i]);
} }
for (; i < clk_data.clk_num; i++) { for (; i < clk_data->num; i++) {
if (!IS_ERR(clk_table[i])) if (!IS_ERR(clk_data->hws[i]))
clk_unregister_gate(clk_table[i]); clk_hw_unregister_gate(clk_data->hws[i]);
} }
} }
...@@ -133,6 +132,7 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) ...@@ -133,6 +132,7 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
const char *sclk_pcm_p = "sclk_pcm0"; const char *sclk_pcm_p = "sclk_pcm0";
struct clk *pll_ref, *pll_in, *cdclk, *sclk_audio, *sclk_pcm_in; struct clk *pll_ref, *pll_in, *cdclk, *sclk_audio, *sclk_pcm_in;
const struct exynos_audss_clk_drvdata *variant; const struct exynos_audss_clk_drvdata *variant;
struct clk_hw **clk_table;
struct resource *res; struct resource *res;
int i, ret = 0; int i, ret = 0;
...@@ -149,14 +149,15 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) ...@@ -149,14 +149,15 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
epll = ERR_PTR(-ENODEV); epll = ERR_PTR(-ENODEV);
clk_table = devm_kzalloc(&pdev->dev, clk_data = devm_kzalloc(&pdev->dev,
sizeof(struct clk *) * EXYNOS_AUDSS_MAX_CLKS, sizeof(*clk_data) +
sizeof(*clk_data->hws) * EXYNOS_AUDSS_MAX_CLKS,
GFP_KERNEL); GFP_KERNEL);
if (!clk_table) if (!clk_data)
return -ENOMEM; return -ENOMEM;
clk_data.clks = clk_table; clk_data->num = variant->num_clks;
clk_data.clk_num = variant->num_clks; clk_table = clk_data->hws;
pll_ref = devm_clk_get(&pdev->dev, "pll_ref"); pll_ref = devm_clk_get(&pdev->dev, "pll_ref");
pll_in = devm_clk_get(&pdev->dev, "pll_in"); pll_in = devm_clk_get(&pdev->dev, "pll_in");
...@@ -176,7 +177,7 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) ...@@ -176,7 +177,7 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
} }
} }
} }
clk_table[EXYNOS_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss", clk_table[EXYNOS_MOUT_AUDSS] = clk_hw_register_mux(NULL, "mout_audss",
mout_audss_p, ARRAY_SIZE(mout_audss_p), mout_audss_p, ARRAY_SIZE(mout_audss_p),
CLK_SET_RATE_NO_REPARENT, CLK_SET_RATE_NO_REPARENT,
reg_base + ASS_CLK_SRC, 0, 1, 0, &lock); reg_base + ASS_CLK_SRC, 0, 1, 0, &lock);
...@@ -187,53 +188,53 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) ...@@ -187,53 +188,53 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
mout_i2s_p[1] = __clk_get_name(cdclk); mout_i2s_p[1] = __clk_get_name(cdclk);
if (!IS_ERR(sclk_audio)) if (!IS_ERR(sclk_audio))
mout_i2s_p[2] = __clk_get_name(sclk_audio); mout_i2s_p[2] = __clk_get_name(sclk_audio);
clk_table[EXYNOS_MOUT_I2S] = clk_register_mux(NULL, "mout_i2s", clk_table[EXYNOS_MOUT_I2S] = clk_hw_register_mux(NULL, "mout_i2s",
mout_i2s_p, ARRAY_SIZE(mout_i2s_p), mout_i2s_p, ARRAY_SIZE(mout_i2s_p),
CLK_SET_RATE_NO_REPARENT, CLK_SET_RATE_NO_REPARENT,
reg_base + ASS_CLK_SRC, 2, 2, 0, &lock); reg_base + ASS_CLK_SRC, 2, 2, 0, &lock);
clk_table[EXYNOS_DOUT_SRP] = clk_register_divider(NULL, "dout_srp", clk_table[EXYNOS_DOUT_SRP] = clk_hw_register_divider(NULL, "dout_srp",
"mout_audss", 0, reg_base + ASS_CLK_DIV, 0, 4, "mout_audss", 0, reg_base + ASS_CLK_DIV, 0, 4,
0, &lock); 0, &lock);
clk_table[EXYNOS_DOUT_AUD_BUS] = clk_register_divider(NULL, clk_table[EXYNOS_DOUT_AUD_BUS] = clk_hw_register_divider(NULL,
"dout_aud_bus", "dout_srp", 0, "dout_aud_bus", "dout_srp", 0,
reg_base + ASS_CLK_DIV, 4, 4, 0, &lock); reg_base + ASS_CLK_DIV, 4, 4, 0, &lock);
clk_table[EXYNOS_DOUT_I2S] = clk_register_divider(NULL, "dout_i2s", clk_table[EXYNOS_DOUT_I2S] = clk_hw_register_divider(NULL, "dout_i2s",
"mout_i2s", 0, reg_base + ASS_CLK_DIV, 8, 4, 0, "mout_i2s", 0, reg_base + ASS_CLK_DIV, 8, 4, 0,
&lock); &lock);
clk_table[EXYNOS_SRP_CLK] = clk_register_gate(NULL, "srp_clk", clk_table[EXYNOS_SRP_CLK] = clk_hw_register_gate(NULL, "srp_clk",
"dout_srp", CLK_SET_RATE_PARENT, "dout_srp", CLK_SET_RATE_PARENT,
reg_base + ASS_CLK_GATE, 0, 0, &lock); reg_base + ASS_CLK_GATE, 0, 0, &lock);
clk_table[EXYNOS_I2S_BUS] = clk_register_gate(NULL, "i2s_bus", clk_table[EXYNOS_I2S_BUS] = clk_hw_register_gate(NULL, "i2s_bus",
"dout_aud_bus", CLK_SET_RATE_PARENT, "dout_aud_bus", CLK_SET_RATE_PARENT,
reg_base + ASS_CLK_GATE, 2, 0, &lock); reg_base + ASS_CLK_GATE, 2, 0, &lock);
clk_table[EXYNOS_SCLK_I2S] = clk_register_gate(NULL, "sclk_i2s", clk_table[EXYNOS_SCLK_I2S] = clk_hw_register_gate(NULL, "sclk_i2s",
"dout_i2s", CLK_SET_RATE_PARENT, "dout_i2s", CLK_SET_RATE_PARENT,
reg_base + ASS_CLK_GATE, 3, 0, &lock); reg_base + ASS_CLK_GATE, 3, 0, &lock);
clk_table[EXYNOS_PCM_BUS] = clk_register_gate(NULL, "pcm_bus", clk_table[EXYNOS_PCM_BUS] = clk_hw_register_gate(NULL, "pcm_bus",
"sclk_pcm", CLK_SET_RATE_PARENT, "sclk_pcm", CLK_SET_RATE_PARENT,
reg_base + ASS_CLK_GATE, 4, 0, &lock); reg_base + ASS_CLK_GATE, 4, 0, &lock);
sclk_pcm_in = devm_clk_get(&pdev->dev, "sclk_pcm_in"); sclk_pcm_in = devm_clk_get(&pdev->dev, "sclk_pcm_in");
if (!IS_ERR(sclk_pcm_in)) if (!IS_ERR(sclk_pcm_in))
sclk_pcm_p = __clk_get_name(sclk_pcm_in); sclk_pcm_p = __clk_get_name(sclk_pcm_in);
clk_table[EXYNOS_SCLK_PCM] = clk_register_gate(NULL, "sclk_pcm", clk_table[EXYNOS_SCLK_PCM] = clk_hw_register_gate(NULL, "sclk_pcm",
sclk_pcm_p, CLK_SET_RATE_PARENT, sclk_pcm_p, CLK_SET_RATE_PARENT,
reg_base + ASS_CLK_GATE, 5, 0, &lock); reg_base + ASS_CLK_GATE, 5, 0, &lock);
if (variant->has_adma_clk) { if (variant->has_adma_clk) {
clk_table[EXYNOS_ADMA] = clk_register_gate(NULL, "adma", clk_table[EXYNOS_ADMA] = clk_hw_register_gate(NULL, "adma",
"dout_srp", CLK_SET_RATE_PARENT, "dout_srp", CLK_SET_RATE_PARENT,
reg_base + ASS_CLK_GATE, 9, 0, &lock); reg_base + ASS_CLK_GATE, 9, 0, &lock);
} }
for (i = 0; i < clk_data.clk_num; i++) { for (i = 0; i < clk_data->num; i++) {
if (IS_ERR(clk_table[i])) { if (IS_ERR(clk_table[i])) {
dev_err(&pdev->dev, "failed to register clock %d\n", i); dev_err(&pdev->dev, "failed to register clock %d\n", i);
ret = PTR_ERR(clk_table[i]); ret = PTR_ERR(clk_table[i]);
...@@ -241,8 +242,8 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) ...@@ -241,8 +242,8 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
} }
} }
ret = of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get, ret = of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get,
&clk_data); clk_data);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to add clock provider\n"); dev_err(&pdev->dev, "failed to add clock provider\n");
goto unregister; goto unregister;
......
...@@ -29,10 +29,9 @@ struct exynos_clkout { ...@@ -29,10 +29,9 @@ struct exynos_clkout {
struct clk_gate gate; struct clk_gate gate;
struct clk_mux mux; struct clk_mux mux;
spinlock_t slock; spinlock_t slock;
struct clk_onecell_data data;
struct clk *clk_table[EXYNOS_CLKOUT_NR_CLKS];
void __iomem *reg; void __iomem *reg;
u32 pmu_debug_save; u32 pmu_debug_save;
struct clk_hw_onecell_data data;
}; };
static struct exynos_clkout *clkout; static struct exynos_clkout *clkout;
...@@ -62,7 +61,9 @@ static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask) ...@@ -62,7 +61,9 @@ static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask)
int ret; int ret;
int i; int i;
clkout = kzalloc(sizeof(*clkout), GFP_KERNEL); clkout = kzalloc(sizeof(*clkout) +
sizeof(*clkout->data.hws) * EXYNOS_CLKOUT_NR_CLKS,
GFP_KERNEL);
if (!clkout) if (!clkout)
return; return;
...@@ -100,17 +101,16 @@ static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask) ...@@ -100,17 +101,16 @@ static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask)
clkout->mux.shift = EXYNOS_CLKOUT_MUX_SHIFT; clkout->mux.shift = EXYNOS_CLKOUT_MUX_SHIFT;
clkout->mux.lock = &clkout->slock; clkout->mux.lock = &clkout->slock;
clkout->clk_table[0] = clk_register_composite(NULL, "clkout", clkout->data.hws[0] = clk_hw_register_composite(NULL, "clkout",
parent_names, parent_count, &clkout->mux.hw, parent_names, parent_count, &clkout->mux.hw,
&clk_mux_ops, NULL, NULL, &clkout->gate.hw, &clk_mux_ops, NULL, NULL, &clkout->gate.hw,
&clk_gate_ops, CLK_SET_RATE_PARENT &clk_gate_ops, CLK_SET_RATE_PARENT
| CLK_SET_RATE_NO_REPARENT); | CLK_SET_RATE_NO_REPARENT);
if (IS_ERR(clkout->clk_table[0])) if (IS_ERR(clkout->data.hws[0]))
goto err_unmap; goto err_unmap;
clkout->data.clks = clkout->clk_table; clkout->data.num = EXYNOS_CLKOUT_NR_CLKS;
clkout->data.clk_num = EXYNOS_CLKOUT_NR_CLKS; ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, &clkout->data);
ret = of_clk_add_provider(node, of_clk_src_onecell_get, &clkout->data);
if (ret) if (ret)
goto err_clk_unreg; goto err_clk_unreg;
...@@ -119,7 +119,7 @@ static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask) ...@@ -119,7 +119,7 @@ static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask)
return; return;
err_clk_unreg: err_clk_unreg:
clk_unregister(clkout->clk_table[0]); clk_hw_unregister(clkout->data.hws[0]);
err_unmap: err_unmap:
iounmap(clkout->reg); iounmap(clkout->reg);
clks_put: clks_put:
......
...@@ -487,6 +487,7 @@ PNAME(mout_group12_5800_p) = { "dout_aclkfl1_550_cam", "dout_sclk_sw" }; ...@@ -487,6 +487,7 @@ PNAME(mout_group12_5800_p) = { "dout_aclkfl1_550_cam", "dout_sclk_sw" };
PNAME(mout_group13_5800_p) = { "dout_osc_div", "mout_sw_aclkfl1_550_cam" }; PNAME(mout_group13_5800_p) = { "dout_osc_div", "mout_sw_aclkfl1_550_cam" };
PNAME(mout_group14_5800_p) = { "dout_aclk550_cam", "dout_sclk_sw" }; PNAME(mout_group14_5800_p) = { "dout_aclk550_cam", "dout_sclk_sw" };
PNAME(mout_group15_5800_p) = { "dout_osc_div", "mout_sw_aclk550_cam" }; PNAME(mout_group15_5800_p) = { "dout_osc_div", "mout_sw_aclk550_cam" };
PNAME(mout_group16_5800_p) = { "dout_osc_div", "mout_mau_epll_clk" };
/* fixed rate clocks generated outside the soc */ /* fixed rate clocks generated outside the soc */
static struct samsung_fixed_rate_clock static struct samsung_fixed_rate_clock
...@@ -536,8 +537,8 @@ static const struct samsung_mux_clock exynos5800_mux_clks[] __initconst = { ...@@ -536,8 +537,8 @@ static const struct samsung_mux_clock exynos5800_mux_clks[] __initconst = {
MUX(CLK_MOUT_MX_MSPLL_CCORE, "mout_mx_mspll_ccore", MUX(CLK_MOUT_MX_MSPLL_CCORE, "mout_mx_mspll_ccore",
mout_mx_mspll_ccore_p, SRC_TOP7, 16, 2), mout_mx_mspll_ccore_p, SRC_TOP7, 16, 2),
MUX(0, "mout_mau_epll_clk", mout_mau_epll_clk_5800_p, SRC_TOP7, MUX(CLK_MOUT_MAU_EPLL, "mout_mau_epll_clk", mout_mau_epll_clk_5800_p,
20, 2), SRC_TOP7, 20, 2),
MUX(0, "sclk_bpll", mout_bpll_p, SRC_TOP7, 24, 1), MUX(0, "sclk_bpll", mout_bpll_p, SRC_TOP7, 24, 1),
MUX(0, "mout_epll2", mout_epll2_5800_p, SRC_TOP7, 28, 1), MUX(0, "mout_epll2", mout_epll2_5800_p, SRC_TOP7, 28, 1),
...@@ -546,6 +547,8 @@ static const struct samsung_mux_clock exynos5800_mux_clks[] __initconst = { ...@@ -546,6 +547,8 @@ static const struct samsung_mux_clock exynos5800_mux_clks[] __initconst = {
MUX(0, "mout_aclk432_cam", mout_group6_5800_p, SRC_TOP8, 24, 2), MUX(0, "mout_aclk432_cam", mout_group6_5800_p, SRC_TOP8, 24, 2),
MUX(0, "mout_aclk432_scaler", mout_group6_5800_p, SRC_TOP8, 28, 2), MUX(0, "mout_aclk432_scaler", mout_group6_5800_p, SRC_TOP8, 28, 2),
MUX(CLK_MOUT_USER_MAU_EPLL, "mout_user_mau_epll", mout_group16_5800_p,
SRC_TOP9, 8, 1),
MUX(0, "mout_user_aclk550_cam", mout_group15_5800_p, MUX(0, "mout_user_aclk550_cam", mout_group15_5800_p,
SRC_TOP9, 16, 1), SRC_TOP9, 16, 1),
MUX(0, "mout_user_aclkfl1_550_cam", mout_group13_5800_p, MUX(0, "mout_user_aclkfl1_550_cam", mout_group13_5800_p,
...@@ -703,7 +706,7 @@ static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = { ...@@ -703,7 +706,7 @@ static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = {
MUX(0, "mout_sclk_spll", mout_spll_p, SRC_TOP6, 8, 1), MUX(0, "mout_sclk_spll", mout_spll_p, SRC_TOP6, 8, 1),
MUX(0, "mout_sclk_ipll", mout_ipll_p, SRC_TOP6, 12, 1), MUX(0, "mout_sclk_ipll", mout_ipll_p, SRC_TOP6, 12, 1),
MUX(0, "mout_sclk_rpll", mout_rpll_p, SRC_TOP6, 16, 1), MUX(0, "mout_sclk_rpll", mout_rpll_p, SRC_TOP6, 16, 1),
MUX(0, "mout_sclk_epll", mout_epll_p, SRC_TOP6, 20, 1), MUX(CLK_MOUT_EPLL, "mout_sclk_epll", mout_epll_p, SRC_TOP6, 20, 1),
MUX(0, "mout_sclk_dpll", mout_dpll_p, SRC_TOP6, 24, 1), MUX(0, "mout_sclk_dpll", mout_dpll_p, SRC_TOP6, 24, 1),
MUX(0, "mout_sclk_cpll", mout_cpll_p, SRC_TOP6, 28, 1), MUX(0, "mout_sclk_cpll", mout_cpll_p, SRC_TOP6, 28, 1),
...@@ -1277,6 +1280,21 @@ static const struct samsung_pll_rate_table exynos5420_pll2550x_24mhz_tbl[] __ini ...@@ -1277,6 +1280,21 @@ static const struct samsung_pll_rate_table exynos5420_pll2550x_24mhz_tbl[] __ini
PLL_35XX_RATE(200000000, 200, 3, 3), PLL_35XX_RATE(200000000, 200, 3, 3),
}; };
static const struct samsung_pll_rate_table exynos5420_epll_24mhz_tbl[] = {
PLL_36XX_RATE(600000000U, 100, 2, 1, 0),
PLL_36XX_RATE(400000000U, 200, 3, 2, 0),
PLL_36XX_RATE(393216000U, 197, 3, 2, 25690),
PLL_36XX_RATE(361267200U, 301, 5, 2, 3671),
PLL_36XX_RATE(200000000U, 200, 3, 3, 0),
PLL_36XX_RATE(196608000U, 197, 3, 3, -25690),
PLL_36XX_RATE(180633600U, 301, 5, 3, 3671),
PLL_36XX_RATE(131072000U, 131, 3, 3, 4719),
PLL_36XX_RATE(100000000U, 200, 3, 4, 0),
PLL_36XX_RATE(65536000U, 131, 3, 4, 4719),
PLL_36XX_RATE(49152000U, 197, 3, 5, 25690),
PLL_36XX_RATE(32768000U, 131, 3, 5, 4719),
};
static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = { static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = {
[apll] = PLL(pll_2550, CLK_FOUT_APLL, "fout_apll", "fin_pll", APLL_LOCK, [apll] = PLL(pll_2550, CLK_FOUT_APLL, "fout_apll", "fin_pll", APLL_LOCK,
APLL_CON0, NULL), APLL_CON0, NULL),
...@@ -1284,7 +1302,7 @@ static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = { ...@@ -1284,7 +1302,7 @@ static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = {
CPLL_CON0, NULL), CPLL_CON0, NULL),
[dpll] = PLL(pll_2550, CLK_FOUT_DPLL, "fout_dpll", "fin_pll", DPLL_LOCK, [dpll] = PLL(pll_2550, CLK_FOUT_DPLL, "fout_dpll", "fin_pll", DPLL_LOCK,
DPLL_CON0, NULL), DPLL_CON0, NULL),
[epll] = PLL(pll_2650, CLK_FOUT_EPLL, "fout_epll", "fin_pll", EPLL_LOCK, [epll] = PLL(pll_36xx, CLK_FOUT_EPLL, "fout_epll", "fin_pll", EPLL_LOCK,
EPLL_CON0, NULL), EPLL_CON0, NULL),
[rpll] = PLL(pll_2650, CLK_FOUT_RPLL, "fout_rpll", "fin_pll", RPLL_LOCK, [rpll] = PLL(pll_2650, CLK_FOUT_RPLL, "fout_rpll", "fin_pll", RPLL_LOCK,
RPLL_CON0, NULL), RPLL_CON0, NULL),
...@@ -1399,6 +1417,7 @@ static void __init exynos5x_clk_init(struct device_node *np, ...@@ -1399,6 +1417,7 @@ static void __init exynos5x_clk_init(struct device_node *np,
if (_get_rate("fin_pll") == 24 * MHZ) { if (_get_rate("fin_pll") == 24 * MHZ) {
exynos5x_plls[apll].rate_table = exynos5420_pll2550x_24mhz_tbl; exynos5x_plls[apll].rate_table = exynos5420_pll2550x_24mhz_tbl;
exynos5x_plls[epll].rate_table = exynos5420_epll_24mhz_tbl;
exynos5x_plls[kpll].rate_table = exynos5420_pll2550x_24mhz_tbl; exynos5x_plls[kpll].rate_table = exynos5420_pll2550x_24mhz_tbl;
exynos5x_plls[bpll].rate_table = exynos5420_pll2550x_24mhz_tbl; exynos5x_plls[bpll].rate_table = exynos5420_pll2550x_24mhz_tbl;
} }
......
...@@ -23,6 +23,10 @@ struct samsung_clk_pll { ...@@ -23,6 +23,10 @@ struct samsung_clk_pll {
struct clk_hw hw; struct clk_hw hw;
void __iomem *lock_reg; void __iomem *lock_reg;
void __iomem *con_reg; void __iomem *con_reg;
/* PLL enable control bit offset in @con_reg register */
unsigned short enable_offs;
/* PLL lock status bit offset in @con_reg register */
unsigned short lock_offs;
enum samsung_pll_type type; enum samsung_pll_type type;
unsigned int rate_count; unsigned int rate_count;
const struct samsung_pll_rate_table *rate_table; const struct samsung_pll_rate_table *rate_table;
...@@ -61,6 +65,34 @@ static long samsung_pll_round_rate(struct clk_hw *hw, ...@@ -61,6 +65,34 @@ static long samsung_pll_round_rate(struct clk_hw *hw,
return rate_table[i - 1].rate; return rate_table[i - 1].rate;
} }
static int samsung_pll3xxx_enable(struct clk_hw *hw)
{
struct samsung_clk_pll *pll = to_clk_pll(hw);
u32 tmp;
tmp = readl_relaxed(pll->con_reg);
tmp |= BIT(pll->enable_offs);
writel_relaxed(tmp, pll->con_reg);
/* wait lock time */
do {
cpu_relax();
tmp = readl_relaxed(pll->con_reg);
} while (!(tmp & BIT(pll->lock_offs)));
return 0;
}
static void samsung_pll3xxx_disable(struct clk_hw *hw)
{
struct samsung_clk_pll *pll = to_clk_pll(hw);
u32 tmp;
tmp = readl_relaxed(pll->con_reg);
tmp &= ~BIT(pll->enable_offs);
writel_relaxed(tmp, pll->con_reg);
}
/* /*
* PLL2126 Clock Type * PLL2126 Clock Type
*/ */
...@@ -142,34 +174,6 @@ static const struct clk_ops samsung_pll3000_clk_ops = { ...@@ -142,34 +174,6 @@ static const struct clk_ops samsung_pll3000_clk_ops = {
#define PLL35XX_LOCK_STAT_SHIFT (29) #define PLL35XX_LOCK_STAT_SHIFT (29)
#define PLL35XX_ENABLE_SHIFT (31) #define PLL35XX_ENABLE_SHIFT (31)
static int samsung_pll35xx_enable(struct clk_hw *hw)
{
struct samsung_clk_pll *pll = to_clk_pll(hw);
u32 tmp;
tmp = readl_relaxed(pll->con_reg);
tmp |= BIT(PLL35XX_ENABLE_SHIFT);
writel_relaxed(tmp, pll->con_reg);
/* wait_lock_time */
do {
cpu_relax();
tmp = readl_relaxed(pll->con_reg);
} while (!(tmp & BIT(PLL35XX_LOCK_STAT_SHIFT)));
return 0;
}
static void samsung_pll35xx_disable(struct clk_hw *hw)
{
struct samsung_clk_pll *pll = to_clk_pll(hw);
u32 tmp;
tmp = readl_relaxed(pll->con_reg);
tmp &= ~BIT(PLL35XX_ENABLE_SHIFT);
writel_relaxed(tmp, pll->con_reg);
}
static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw, static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate) unsigned long parent_rate)
{ {
...@@ -238,12 +242,12 @@ static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate, ...@@ -238,12 +242,12 @@ static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
(rate->sdiv << PLL35XX_SDIV_SHIFT); (rate->sdiv << PLL35XX_SDIV_SHIFT);
writel_relaxed(tmp, pll->con_reg); writel_relaxed(tmp, pll->con_reg);
/* wait_lock_time if enabled */ /* Wait until the PLL is locked if it is enabled. */
if (tmp & BIT(PLL35XX_ENABLE_SHIFT)) { if (tmp & BIT(pll->enable_offs)) {
do { do {
cpu_relax(); cpu_relax();
tmp = readl_relaxed(pll->con_reg); tmp = readl_relaxed(pll->con_reg);
} while (!(tmp & BIT(PLL35XX_LOCK_STAT_SHIFT))); } while (!(tmp & BIT(pll->lock_offs)));
} }
return 0; return 0;
} }
...@@ -252,8 +256,8 @@ static const struct clk_ops samsung_pll35xx_clk_ops = { ...@@ -252,8 +256,8 @@ static const struct clk_ops samsung_pll35xx_clk_ops = {
.recalc_rate = samsung_pll35xx_recalc_rate, .recalc_rate = samsung_pll35xx_recalc_rate,
.round_rate = samsung_pll_round_rate, .round_rate = samsung_pll_round_rate,
.set_rate = samsung_pll35xx_set_rate, .set_rate = samsung_pll35xx_set_rate,
.enable = samsung_pll35xx_enable, .enable = samsung_pll3xxx_enable,
.disable = samsung_pll35xx_disable, .disable = samsung_pll3xxx_disable,
}; };
static const struct clk_ops samsung_pll35xx_clk_min_ops = { static const struct clk_ops samsung_pll35xx_clk_min_ops = {
...@@ -275,6 +279,7 @@ static const struct clk_ops samsung_pll35xx_clk_min_ops = { ...@@ -275,6 +279,7 @@ static const struct clk_ops samsung_pll35xx_clk_min_ops = {
#define PLL36XX_SDIV_SHIFT (0) #define PLL36XX_SDIV_SHIFT (0)
#define PLL36XX_KDIV_SHIFT (0) #define PLL36XX_KDIV_SHIFT (0)
#define PLL36XX_LOCK_STAT_SHIFT (29) #define PLL36XX_LOCK_STAT_SHIFT (29)
#define PLL36XX_ENABLE_SHIFT (31)
static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw, static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate) unsigned long parent_rate)
...@@ -354,10 +359,12 @@ static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate, ...@@ -354,10 +359,12 @@ static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
writel_relaxed(pll_con1, pll->con_reg + 4); writel_relaxed(pll_con1, pll->con_reg + 4);
/* wait_lock_time */ /* wait_lock_time */
do { if (pll_con0 & BIT(pll->enable_offs)) {
cpu_relax(); do {
tmp = readl_relaxed(pll->con_reg); cpu_relax();
} while (!(tmp & (1 << PLL36XX_LOCK_STAT_SHIFT))); tmp = readl_relaxed(pll->con_reg);
} while (!(tmp & BIT(pll->lock_offs)));
}
return 0; return 0;
} }
...@@ -366,6 +373,8 @@ static const struct clk_ops samsung_pll36xx_clk_ops = { ...@@ -366,6 +373,8 @@ static const struct clk_ops samsung_pll36xx_clk_ops = {
.recalc_rate = samsung_pll36xx_recalc_rate, .recalc_rate = samsung_pll36xx_recalc_rate,
.set_rate = samsung_pll36xx_set_rate, .set_rate = samsung_pll36xx_set_rate,
.round_rate = samsung_pll_round_rate, .round_rate = samsung_pll_round_rate,
.enable = samsung_pll3xxx_enable,
.disable = samsung_pll3xxx_disable,
}; };
static const struct clk_ops samsung_pll36xx_clk_min_ops = { static const struct clk_ops samsung_pll36xx_clk_min_ops = {
...@@ -1244,7 +1253,6 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, ...@@ -1244,7 +1253,6 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
void __iomem *base) void __iomem *base)
{ {
struct samsung_clk_pll *pll; struct samsung_clk_pll *pll;
struct clk *clk;
struct clk_init_data init; struct clk_init_data init;
int ret, len; int ret, len;
...@@ -1288,6 +1296,8 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, ...@@ -1288,6 +1296,8 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
case pll_1450x: case pll_1450x:
case pll_1451x: case pll_1451x:
case pll_1452x: case pll_1452x:
pll->enable_offs = PLL35XX_ENABLE_SHIFT;
pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT;
if (!pll->rate_table) if (!pll->rate_table)
init.ops = &samsung_pll35xx_clk_min_ops; init.ops = &samsung_pll35xx_clk_min_ops;
else else
...@@ -1306,6 +1316,8 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, ...@@ -1306,6 +1316,8 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
/* clk_ops for 36xx and 2650 are similar */ /* clk_ops for 36xx and 2650 are similar */
case pll_36xx: case pll_36xx:
case pll_2650: case pll_2650:
pll->enable_offs = PLL36XX_ENABLE_SHIFT;
pll->lock_offs = PLL36XX_LOCK_STAT_SHIFT;
if (!pll->rate_table) if (!pll->rate_table)
init.ops = &samsung_pll36xx_clk_min_ops; init.ops = &samsung_pll36xx_clk_min_ops;
else else
...@@ -1376,20 +1388,21 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, ...@@ -1376,20 +1388,21 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
pll->lock_reg = base + pll_clk->lock_offset; pll->lock_reg = base + pll_clk->lock_offset;
pll->con_reg = base + pll_clk->con_offset; pll->con_reg = base + pll_clk->con_offset;
clk = clk_register(NULL, &pll->hw); ret = clk_hw_register(NULL, &pll->hw);
if (IS_ERR(clk)) { if (ret) {
pr_err("%s: failed to register pll clock %s : %ld\n", pr_err("%s: failed to register pll clock %s : %d\n",
__func__, pll_clk->name, PTR_ERR(clk)); __func__, pll_clk->name, ret);
kfree(pll); kfree(pll);
return; return;
} }
samsung_clk_add_lookup(ctx, clk, pll_clk->id); samsung_clk_add_lookup(ctx, &pll->hw, pll_clk->id);
if (!pll_clk->alias) if (!pll_clk->alias)
return; return;
ret = clk_register_clkdev(clk, pll_clk->alias, pll_clk->dev_name); ret = clk_hw_register_clkdev(&pll->hw, pll_clk->alias,
pll_clk->dev_name);
if (ret) if (ret)
pr_err("%s: failed to register lookup for %s : %d", pr_err("%s: failed to register lookup for %s : %d",
__func__, pll_clk->name, ret); __func__, pll_clk->name, ret);
......
...@@ -103,8 +103,4 @@ struct samsung_pll_rate_table { ...@@ -103,8 +103,4 @@ struct samsung_pll_rate_table {
unsigned int vsel; unsigned int vsel;
}; };
extern struct clk * __init samsung_clk_register_pll2550x(const char *name,
const char *pname, const void __iomem *reg_base,
const unsigned long offset);
#endif /* __SAMSUNG_CLK_PLL_H */ #endif /* __SAMSUNG_CLK_PLL_H */
...@@ -90,13 +90,13 @@ static const struct clk_ops s3c24xx_clkout_ops = { ...@@ -90,13 +90,13 @@ static const struct clk_ops s3c24xx_clkout_ops = {
.determine_rate = __clk_mux_determine_rate, .determine_rate = __clk_mux_determine_rate,
}; };
static struct clk *s3c24xx_register_clkout(struct device *dev, const char *name, static struct clk_hw *s3c24xx_register_clkout(struct device *dev,
const char **parent_names, u8 num_parents, const char *name, const char **parent_names, u8 num_parents,
u8 shift, u32 mask) u8 shift, u32 mask)
{ {
struct s3c24xx_clkout *clkout; struct s3c24xx_clkout *clkout;
struct clk *clk;
struct clk_init_data init; struct clk_init_data init;
int ret;
/* allocate the clkout */ /* allocate the clkout */
clkout = kzalloc(sizeof(*clkout), GFP_KERNEL); clkout = kzalloc(sizeof(*clkout), GFP_KERNEL);
...@@ -113,9 +113,11 @@ static struct clk *s3c24xx_register_clkout(struct device *dev, const char *name, ...@@ -113,9 +113,11 @@ static struct clk *s3c24xx_register_clkout(struct device *dev, const char *name,
clkout->mask = mask; clkout->mask = mask;
clkout->hw.init = &init; clkout->hw.init = &init;
clk = clk_register(dev, &clkout->hw); ret = clk_hw_register(dev, &clkout->hw);
if (ret)
return ERR_PTR(ret);
return clk; return &clkout->hw;
} }
/* /*
...@@ -125,11 +127,12 @@ static struct clk *s3c24xx_register_clkout(struct device *dev, const char *name, ...@@ -125,11 +127,12 @@ static struct clk *s3c24xx_register_clkout(struct device *dev, const char *name,
struct s3c24xx_dclk { struct s3c24xx_dclk {
struct device *dev; struct device *dev;
void __iomem *base; void __iomem *base;
struct clk_onecell_data clk_data;
struct notifier_block dclk0_div_change_nb; struct notifier_block dclk0_div_change_nb;
struct notifier_block dclk1_div_change_nb; struct notifier_block dclk1_div_change_nb;
spinlock_t dclk_lock; spinlock_t dclk_lock;
unsigned long reg_save; unsigned long reg_save;
/* clk_data must be the last entry in the structure */
struct clk_hw_onecell_data clk_data;
}; };
#define to_s3c24xx_dclk0(x) \ #define to_s3c24xx_dclk0(x) \
...@@ -240,28 +243,23 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev) ...@@ -240,28 +243,23 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev)
{ {
struct s3c24xx_dclk *s3c24xx_dclk; struct s3c24xx_dclk *s3c24xx_dclk;
struct resource *mem; struct resource *mem;
struct clk **clk_table;
struct s3c24xx_dclk_drv_data *dclk_variant; struct s3c24xx_dclk_drv_data *dclk_variant;
struct clk_hw **clk_table;
int ret, i; int ret, i;
s3c24xx_dclk = devm_kzalloc(&pdev->dev, sizeof(*s3c24xx_dclk), s3c24xx_dclk = devm_kzalloc(&pdev->dev, sizeof(*s3c24xx_dclk) +
GFP_KERNEL); sizeof(*s3c24xx_dclk->clk_data.hws) * DCLK_MAX_CLKS,
GFP_KERNEL);
if (!s3c24xx_dclk) if (!s3c24xx_dclk)
return -ENOMEM; return -ENOMEM;
clk_table = s3c24xx_dclk->clk_data.hws;
s3c24xx_dclk->dev = &pdev->dev; s3c24xx_dclk->dev = &pdev->dev;
s3c24xx_dclk->clk_data.num = DCLK_MAX_CLKS;
platform_set_drvdata(pdev, s3c24xx_dclk); platform_set_drvdata(pdev, s3c24xx_dclk);
spin_lock_init(&s3c24xx_dclk->dclk_lock); spin_lock_init(&s3c24xx_dclk->dclk_lock);
clk_table = devm_kzalloc(&pdev->dev,
sizeof(struct clk *) * DCLK_MAX_CLKS,
GFP_KERNEL);
if (!clk_table)
return -ENOMEM;
s3c24xx_dclk->clk_data.clks = clk_table;
s3c24xx_dclk->clk_data.clk_num = DCLK_MAX_CLKS;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
s3c24xx_dclk->base = devm_ioremap_resource(&pdev->dev, mem); s3c24xx_dclk->base = devm_ioremap_resource(&pdev->dev, mem);
if (IS_ERR(s3c24xx_dclk->base)) if (IS_ERR(s3c24xx_dclk->base))
...@@ -271,29 +269,29 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev) ...@@ -271,29 +269,29 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev)
platform_get_device_id(pdev)->driver_data; platform_get_device_id(pdev)->driver_data;
clk_table[MUX_DCLK0] = clk_register_mux(&pdev->dev, "mux_dclk0", clk_table[MUX_DCLK0] = clk_hw_register_mux(&pdev->dev, "mux_dclk0",
dclk_variant->mux_parent_names, dclk_variant->mux_parent_names,
dclk_variant->mux_num_parents, 0, dclk_variant->mux_num_parents, 0,
s3c24xx_dclk->base, 1, 1, 0, s3c24xx_dclk->base, 1, 1, 0,
&s3c24xx_dclk->dclk_lock); &s3c24xx_dclk->dclk_lock);
clk_table[MUX_DCLK1] = clk_register_mux(&pdev->dev, "mux_dclk1", clk_table[MUX_DCLK1] = clk_hw_register_mux(&pdev->dev, "mux_dclk1",
dclk_variant->mux_parent_names, dclk_variant->mux_parent_names,
dclk_variant->mux_num_parents, 0, dclk_variant->mux_num_parents, 0,
s3c24xx_dclk->base, 17, 1, 0, s3c24xx_dclk->base, 17, 1, 0,
&s3c24xx_dclk->dclk_lock); &s3c24xx_dclk->dclk_lock);
clk_table[DIV_DCLK0] = clk_register_divider(&pdev->dev, "div_dclk0", clk_table[DIV_DCLK0] = clk_hw_register_divider(&pdev->dev, "div_dclk0",
"mux_dclk0", 0, s3c24xx_dclk->base, "mux_dclk0", 0, s3c24xx_dclk->base,
4, 4, 0, &s3c24xx_dclk->dclk_lock); 4, 4, 0, &s3c24xx_dclk->dclk_lock);
clk_table[DIV_DCLK1] = clk_register_divider(&pdev->dev, "div_dclk1", clk_table[DIV_DCLK1] = clk_hw_register_divider(&pdev->dev, "div_dclk1",
"mux_dclk1", 0, s3c24xx_dclk->base, "mux_dclk1", 0, s3c24xx_dclk->base,
20, 4, 0, &s3c24xx_dclk->dclk_lock); 20, 4, 0, &s3c24xx_dclk->dclk_lock);
clk_table[GATE_DCLK0] = clk_register_gate(&pdev->dev, "gate_dclk0", clk_table[GATE_DCLK0] = clk_hw_register_gate(&pdev->dev, "gate_dclk0",
"div_dclk0", CLK_SET_RATE_PARENT, "div_dclk0", CLK_SET_RATE_PARENT,
s3c24xx_dclk->base, 0, 0, s3c24xx_dclk->base, 0, 0,
&s3c24xx_dclk->dclk_lock); &s3c24xx_dclk->dclk_lock);
clk_table[GATE_DCLK1] = clk_register_gate(&pdev->dev, "gate_dclk1", clk_table[GATE_DCLK1] = clk_hw_register_gate(&pdev->dev, "gate_dclk1",
"div_dclk1", CLK_SET_RATE_PARENT, "div_dclk1", CLK_SET_RATE_PARENT,
s3c24xx_dclk->base, 16, 0, s3c24xx_dclk->base, 16, 0,
&s3c24xx_dclk->dclk_lock); &s3c24xx_dclk->dclk_lock);
...@@ -312,15 +310,16 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev) ...@@ -312,15 +310,16 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev)
goto err_clk_register; goto err_clk_register;
} }
ret = clk_register_clkdev(clk_table[MUX_DCLK0], "dclk0", NULL); ret = clk_hw_register_clkdev(clk_table[MUX_DCLK0], "dclk0", NULL);
if (!ret) if (!ret)
ret = clk_register_clkdev(clk_table[MUX_DCLK1], "dclk1", NULL); ret = clk_hw_register_clkdev(clk_table[MUX_DCLK1], "dclk1",
NULL);
if (!ret) if (!ret)
ret = clk_register_clkdev(clk_table[MUX_CLKOUT0], ret = clk_hw_register_clkdev(clk_table[MUX_CLKOUT0],
"clkout0", NULL); "clkout0", NULL);
if (!ret) if (!ret)
ret = clk_register_clkdev(clk_table[MUX_CLKOUT1], ret = clk_hw_register_clkdev(clk_table[MUX_CLKOUT1],
"clkout1", NULL); "clkout1", NULL);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to register aliases, %d\n", ret); dev_err(&pdev->dev, "failed to register aliases, %d\n", ret);
goto err_clk_register; goto err_clk_register;
...@@ -332,12 +331,12 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev) ...@@ -332,12 +331,12 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev)
s3c24xx_dclk->dclk1_div_change_nb.notifier_call = s3c24xx_dclk->dclk1_div_change_nb.notifier_call =
s3c24xx_dclk1_div_notify; s3c24xx_dclk1_div_notify;
ret = clk_notifier_register(clk_table[DIV_DCLK0], ret = clk_notifier_register(clk_table[DIV_DCLK0]->clk,
&s3c24xx_dclk->dclk0_div_change_nb); &s3c24xx_dclk->dclk0_div_change_nb);
if (ret) if (ret)
goto err_clk_register; goto err_clk_register;
ret = clk_notifier_register(clk_table[DIV_DCLK1], ret = clk_notifier_register(clk_table[DIV_DCLK1]->clk,
&s3c24xx_dclk->dclk1_div_change_nb); &s3c24xx_dclk->dclk1_div_change_nb);
if (ret) if (ret)
goto err_dclk_notify; goto err_dclk_notify;
...@@ -345,12 +344,12 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev) ...@@ -345,12 +344,12 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev)
return 0; return 0;
err_dclk_notify: err_dclk_notify:
clk_notifier_unregister(clk_table[DIV_DCLK0], clk_notifier_unregister(clk_table[DIV_DCLK0]->clk,
&s3c24xx_dclk->dclk0_div_change_nb); &s3c24xx_dclk->dclk0_div_change_nb);
err_clk_register: err_clk_register:
for (i = 0; i < DCLK_MAX_CLKS; i++) for (i = 0; i < DCLK_MAX_CLKS; i++)
if (clk_table[i] && !IS_ERR(clk_table[i])) if (clk_table[i] && !IS_ERR(clk_table[i]))
clk_unregister(clk_table[i]); clk_hw_unregister(clk_table[i]);
return ret; return ret;
} }
...@@ -358,16 +357,16 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev) ...@@ -358,16 +357,16 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev)
static int s3c24xx_dclk_remove(struct platform_device *pdev) static int s3c24xx_dclk_remove(struct platform_device *pdev)
{ {
struct s3c24xx_dclk *s3c24xx_dclk = platform_get_drvdata(pdev); struct s3c24xx_dclk *s3c24xx_dclk = platform_get_drvdata(pdev);
struct clk **clk_table = s3c24xx_dclk->clk_data.clks; struct clk_hw **clk_table = s3c24xx_dclk->clk_data.hws;
int i; int i;
clk_notifier_unregister(clk_table[DIV_DCLK1], clk_notifier_unregister(clk_table[DIV_DCLK1]->clk,
&s3c24xx_dclk->dclk1_div_change_nb); &s3c24xx_dclk->dclk1_div_change_nb);
clk_notifier_unregister(clk_table[DIV_DCLK0], clk_notifier_unregister(clk_table[DIV_DCLK0]->clk,
&s3c24xx_dclk->dclk0_div_change_nb); &s3c24xx_dclk->dclk0_div_change_nb);
for (i = 0; i < DCLK_MAX_CLKS; i++) for (i = 0; i < DCLK_MAX_CLKS; i++)
clk_unregister(clk_table[i]); clk_hw_unregister(clk_table[i]);
return 0; return 0;
} }
......
...@@ -24,9 +24,8 @@ ...@@ -24,9 +24,8 @@
#include <dt-bindings/clock/s5pv210-audss.h> #include <dt-bindings/clock/s5pv210-audss.h>
static DEFINE_SPINLOCK(lock); static DEFINE_SPINLOCK(lock);
static struct clk **clk_table;
static void __iomem *reg_base; static void __iomem *reg_base;
static struct clk_onecell_data clk_data; static struct clk_hw_onecell_data *clk_data;
#define ASS_CLK_SRC 0x0 #define ASS_CLK_SRC 0x0
#define ASS_CLK_DIV 0x4 #define ASS_CLK_DIV 0x4
...@@ -71,6 +70,7 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev) ...@@ -71,6 +70,7 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev)
const char *mout_audss_p[2]; const char *mout_audss_p[2];
const char *mout_i2s_p[3]; const char *mout_i2s_p[3];
const char *hclk_p; const char *hclk_p;
struct clk_hw **clk_table;
struct clk *hclk, *pll_ref, *pll_in, *cdclk, *sclk_audio; struct clk *hclk, *pll_ref, *pll_in, *cdclk, *sclk_audio;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
...@@ -80,14 +80,16 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev) ...@@ -80,14 +80,16 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev)
return PTR_ERR(reg_base); return PTR_ERR(reg_base);
} }
clk_table = devm_kzalloc(&pdev->dev, clk_data = devm_kzalloc(&pdev->dev,
sizeof(struct clk *) * AUDSS_MAX_CLKS, sizeof(*clk_data) +
sizeof(*clk_data->hws) * AUDSS_MAX_CLKS,
GFP_KERNEL); GFP_KERNEL);
if (!clk_table)
if (!clk_data)
return -ENOMEM; return -ENOMEM;
clk_data.clks = clk_table; clk_data->num = AUDSS_MAX_CLKS;
clk_data.clk_num = AUDSS_MAX_CLKS; clk_table = clk_data->hws;
hclk = devm_clk_get(&pdev->dev, "hclk"); hclk = devm_clk_get(&pdev->dev, "hclk");
if (IS_ERR(hclk)) { if (IS_ERR(hclk)) {
...@@ -116,7 +118,7 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev) ...@@ -116,7 +118,7 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev)
else else
mout_audss_p[0] = "xxti"; mout_audss_p[0] = "xxti";
mout_audss_p[1] = __clk_get_name(pll_in); mout_audss_p[1] = __clk_get_name(pll_in);
clk_table[CLK_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss", clk_table[CLK_MOUT_AUDSS] = clk_hw_register_mux(NULL, "mout_audss",
mout_audss_p, ARRAY_SIZE(mout_audss_p), mout_audss_p, ARRAY_SIZE(mout_audss_p),
CLK_SET_RATE_NO_REPARENT, CLK_SET_RATE_NO_REPARENT,
reg_base + ASS_CLK_SRC, 0, 1, 0, &lock); reg_base + ASS_CLK_SRC, 0, 1, 0, &lock);
...@@ -127,44 +129,44 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev) ...@@ -127,44 +129,44 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev)
else else
mout_i2s_p[1] = "iiscdclk0"; mout_i2s_p[1] = "iiscdclk0";
mout_i2s_p[2] = __clk_get_name(sclk_audio); mout_i2s_p[2] = __clk_get_name(sclk_audio);
clk_table[CLK_MOUT_I2S_A] = clk_register_mux(NULL, "mout_i2s_audss", clk_table[CLK_MOUT_I2S_A] = clk_hw_register_mux(NULL, "mout_i2s_audss",
mout_i2s_p, ARRAY_SIZE(mout_i2s_p), mout_i2s_p, ARRAY_SIZE(mout_i2s_p),
CLK_SET_RATE_NO_REPARENT, CLK_SET_RATE_NO_REPARENT,
reg_base + ASS_CLK_SRC, 2, 2, 0, &lock); reg_base + ASS_CLK_SRC, 2, 2, 0, &lock);
clk_table[CLK_DOUT_AUD_BUS] = clk_register_divider(NULL, clk_table[CLK_DOUT_AUD_BUS] = clk_hw_register_divider(NULL,
"dout_aud_bus", "mout_audss", 0, "dout_aud_bus", "mout_audss", 0,
reg_base + ASS_CLK_DIV, 0, 4, 0, &lock); reg_base + ASS_CLK_DIV, 0, 4, 0, &lock);
clk_table[CLK_DOUT_I2S_A] = clk_register_divider(NULL, "dout_i2s_audss", clk_table[CLK_DOUT_I2S_A] = clk_hw_register_divider(NULL,
"mout_i2s_audss", 0, reg_base + ASS_CLK_DIV, "dout_i2s_audss", "mout_i2s_audss", 0,
4, 4, 0, &lock); reg_base + ASS_CLK_DIV, 4, 4, 0, &lock);
clk_table[CLK_I2S] = clk_register_gate(NULL, "i2s_audss", clk_table[CLK_I2S] = clk_hw_register_gate(NULL, "i2s_audss",
"dout_i2s_audss", CLK_SET_RATE_PARENT, "dout_i2s_audss", CLK_SET_RATE_PARENT,
reg_base + ASS_CLK_GATE, 6, 0, &lock); reg_base + ASS_CLK_GATE, 6, 0, &lock);
hclk_p = __clk_get_name(hclk); hclk_p = __clk_get_name(hclk);
clk_table[CLK_HCLK_I2S] = clk_register_gate(NULL, "hclk_i2s_audss", clk_table[CLK_HCLK_I2S] = clk_hw_register_gate(NULL, "hclk_i2s_audss",
hclk_p, CLK_IGNORE_UNUSED, hclk_p, CLK_IGNORE_UNUSED,
reg_base + ASS_CLK_GATE, 5, 0, &lock); reg_base + ASS_CLK_GATE, 5, 0, &lock);
clk_table[CLK_HCLK_UART] = clk_register_gate(NULL, "hclk_uart_audss", clk_table[CLK_HCLK_UART] = clk_hw_register_gate(NULL, "hclk_uart_audss",
hclk_p, CLK_IGNORE_UNUSED, hclk_p, CLK_IGNORE_UNUSED,
reg_base + ASS_CLK_GATE, 4, 0, &lock); reg_base + ASS_CLK_GATE, 4, 0, &lock);
clk_table[CLK_HCLK_HWA] = clk_register_gate(NULL, "hclk_hwa_audss", clk_table[CLK_HCLK_HWA] = clk_hw_register_gate(NULL, "hclk_hwa_audss",
hclk_p, CLK_IGNORE_UNUSED, hclk_p, CLK_IGNORE_UNUSED,
reg_base + ASS_CLK_GATE, 3, 0, &lock); reg_base + ASS_CLK_GATE, 3, 0, &lock);
clk_table[CLK_HCLK_DMA] = clk_register_gate(NULL, "hclk_dma_audss", clk_table[CLK_HCLK_DMA] = clk_hw_register_gate(NULL, "hclk_dma_audss",
hclk_p, CLK_IGNORE_UNUSED, hclk_p, CLK_IGNORE_UNUSED,
reg_base + ASS_CLK_GATE, 2, 0, &lock); reg_base + ASS_CLK_GATE, 2, 0, &lock);
clk_table[CLK_HCLK_BUF] = clk_register_gate(NULL, "hclk_buf_audss", clk_table[CLK_HCLK_BUF] = clk_hw_register_gate(NULL, "hclk_buf_audss",
hclk_p, CLK_IGNORE_UNUSED, hclk_p, CLK_IGNORE_UNUSED,
reg_base + ASS_CLK_GATE, 1, 0, &lock); reg_base + ASS_CLK_GATE, 1, 0, &lock);
clk_table[CLK_HCLK_RP] = clk_register_gate(NULL, "hclk_rp_audss", clk_table[CLK_HCLK_RP] = clk_hw_register_gate(NULL, "hclk_rp_audss",
hclk_p, CLK_IGNORE_UNUSED, hclk_p, CLK_IGNORE_UNUSED,
reg_base + ASS_CLK_GATE, 0, 0, &lock); reg_base + ASS_CLK_GATE, 0, 0, &lock);
for (i = 0; i < clk_data.clk_num; i++) { for (i = 0; i < clk_data->num; i++) {
if (IS_ERR(clk_table[i])) { if (IS_ERR(clk_table[i])) {
dev_err(&pdev->dev, "failed to register clock %d\n", i); dev_err(&pdev->dev, "failed to register clock %d\n", i);
ret = PTR_ERR(clk_table[i]); ret = PTR_ERR(clk_table[i]);
...@@ -172,8 +174,8 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev) ...@@ -172,8 +174,8 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev)
} }
} }
ret = of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get, ret = of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get,
&clk_data); clk_data);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to add clock provider\n"); dev_err(&pdev->dev, "failed to add clock provider\n");
goto unregister; goto unregister;
...@@ -186,9 +188,9 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev) ...@@ -186,9 +188,9 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev)
return 0; return 0;
unregister: unregister:
for (i = 0; i < clk_data.clk_num; i++) { for (i = 0; i < clk_data->num; i++) {
if (!IS_ERR(clk_table[i])) if (!IS_ERR(clk_table[i]))
clk_unregister(clk_table[i]); clk_hw_unregister(clk_table[i]);
} }
return ret; return ret;
......
...@@ -60,23 +60,18 @@ struct samsung_clk_provider *__init samsung_clk_init(struct device_node *np, ...@@ -60,23 +60,18 @@ struct samsung_clk_provider *__init samsung_clk_init(struct device_node *np,
void __iomem *base, unsigned long nr_clks) void __iomem *base, unsigned long nr_clks)
{ {
struct samsung_clk_provider *ctx; struct samsung_clk_provider *ctx;
struct clk **clk_table;
int i; int i;
ctx = kzalloc(sizeof(struct samsung_clk_provider), GFP_KERNEL); ctx = kzalloc(sizeof(struct samsung_clk_provider) +
sizeof(*ctx->clk_data.hws) * nr_clks, GFP_KERNEL);
if (!ctx) if (!ctx)
panic("could not allocate clock provider context.\n"); panic("could not allocate clock provider context.\n");
clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL);
if (!clk_table)
panic("could not allocate clock lookup table\n");
for (i = 0; i < nr_clks; ++i) for (i = 0; i < nr_clks; ++i)
clk_table[i] = ERR_PTR(-ENOENT); ctx->clk_data.hws[i] = ERR_PTR(-ENOENT);
ctx->reg_base = base; ctx->reg_base = base;
ctx->clk_data.clks = clk_table; ctx->clk_data.num = nr_clks;
ctx->clk_data.clk_num = nr_clks;
spin_lock_init(&ctx->lock); spin_lock_init(&ctx->lock);
return ctx; return ctx;
...@@ -86,18 +81,18 @@ void __init samsung_clk_of_add_provider(struct device_node *np, ...@@ -86,18 +81,18 @@ void __init samsung_clk_of_add_provider(struct device_node *np,
struct samsung_clk_provider *ctx) struct samsung_clk_provider *ctx)
{ {
if (np) { if (np) {
if (of_clk_add_provider(np, of_clk_src_onecell_get, if (of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
&ctx->clk_data)) &ctx->clk_data))
panic("could not register clk provider\n"); panic("could not register clk provider\n");
} }
} }
/* add a clock instance to the clock lookup table used for dt based lookup */ /* add a clock instance to the clock lookup table used for dt based lookup */
void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, struct clk *clk, void samsung_clk_add_lookup(struct samsung_clk_provider *ctx,
unsigned int id) struct clk_hw *clk_hw, unsigned int id)
{ {
if (ctx->clk_data.clks && id) if (id)
ctx->clk_data.clks[id] = clk; ctx->clk_data.hws[id] = clk_hw;
} }
/* register a list of aliases */ /* register a list of aliases */
...@@ -105,14 +100,9 @@ void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx, ...@@ -105,14 +100,9 @@ void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx,
const struct samsung_clock_alias *list, const struct samsung_clock_alias *list,
unsigned int nr_clk) unsigned int nr_clk)
{ {
struct clk *clk; struct clk_hw *clk_hw;
unsigned int idx, ret; unsigned int idx, ret;
if (!ctx->clk_data.clks) {
pr_err("%s: clock table missing\n", __func__);
return;
}
for (idx = 0; idx < nr_clk; idx++, list++) { for (idx = 0; idx < nr_clk; idx++, list++) {
if (!list->id) { if (!list->id) {
pr_err("%s: clock id missing for index %d\n", __func__, pr_err("%s: clock id missing for index %d\n", __func__,
...@@ -120,14 +110,15 @@ void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx, ...@@ -120,14 +110,15 @@ void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx,
continue; continue;
} }
clk = ctx->clk_data.clks[list->id]; clk_hw = ctx->clk_data.hws[list->id];
if (!clk) { if (!clk_hw) {
pr_err("%s: failed to find clock %d\n", __func__, pr_err("%s: failed to find clock %d\n", __func__,
list->id); list->id);
continue; continue;
} }
ret = clk_register_clkdev(clk, list->alias, list->dev_name); ret = clk_hw_register_clkdev(clk_hw, list->alias,
list->dev_name);
if (ret) if (ret)
pr_err("%s: failed to register lookup %s\n", pr_err("%s: failed to register lookup %s\n",
__func__, list->alias); __func__, list->alias);
...@@ -139,25 +130,25 @@ void __init samsung_clk_register_fixed_rate(struct samsung_clk_provider *ctx, ...@@ -139,25 +130,25 @@ void __init samsung_clk_register_fixed_rate(struct samsung_clk_provider *ctx,
const struct samsung_fixed_rate_clock *list, const struct samsung_fixed_rate_clock *list,
unsigned int nr_clk) unsigned int nr_clk)
{ {
struct clk *clk; struct clk_hw *clk_hw;
unsigned int idx, ret; unsigned int idx, ret;
for (idx = 0; idx < nr_clk; idx++, list++) { for (idx = 0; idx < nr_clk; idx++, list++) {
clk = clk_register_fixed_rate(NULL, list->name, clk_hw = clk_hw_register_fixed_rate(NULL, list->name,
list->parent_name, list->flags, list->fixed_rate); list->parent_name, list->flags, list->fixed_rate);
if (IS_ERR(clk)) { if (IS_ERR(clk_hw)) {
pr_err("%s: failed to register clock %s\n", __func__, pr_err("%s: failed to register clock %s\n", __func__,
list->name); list->name);
continue; continue;
} }
samsung_clk_add_lookup(ctx, clk, list->id); samsung_clk_add_lookup(ctx, clk_hw, list->id);
/* /*
* Unconditionally add a clock lookup for the fixed rate clocks. * Unconditionally add a clock lookup for the fixed rate clocks.
* There are not many of these on any of Samsung platforms. * There are not many of these on any of Samsung platforms.
*/ */
ret = clk_register_clkdev(clk, list->name, NULL); ret = clk_hw_register_clkdev(clk_hw, list->name, NULL);
if (ret) if (ret)
pr_err("%s: failed to register clock lookup for %s", pr_err("%s: failed to register clock lookup for %s",
__func__, list->name); __func__, list->name);
...@@ -168,19 +159,19 @@ void __init samsung_clk_register_fixed_rate(struct samsung_clk_provider *ctx, ...@@ -168,19 +159,19 @@ void __init samsung_clk_register_fixed_rate(struct samsung_clk_provider *ctx,
void __init samsung_clk_register_fixed_factor(struct samsung_clk_provider *ctx, void __init samsung_clk_register_fixed_factor(struct samsung_clk_provider *ctx,
const struct samsung_fixed_factor_clock *list, unsigned int nr_clk) const struct samsung_fixed_factor_clock *list, unsigned int nr_clk)
{ {
struct clk *clk; struct clk_hw *clk_hw;
unsigned int idx; unsigned int idx;
for (idx = 0; idx < nr_clk; idx++, list++) { for (idx = 0; idx < nr_clk; idx++, list++) {
clk = clk_register_fixed_factor(NULL, list->name, clk_hw = clk_hw_register_fixed_factor(NULL, list->name,
list->parent_name, list->flags, list->mult, list->div); list->parent_name, list->flags, list->mult, list->div);
if (IS_ERR(clk)) { if (IS_ERR(clk_hw)) {
pr_err("%s: failed to register clock %s\n", __func__, pr_err("%s: failed to register clock %s\n", __func__,
list->name); list->name);
continue; continue;
} }
samsung_clk_add_lookup(ctx, clk, list->id); samsung_clk_add_lookup(ctx, clk_hw, list->id);
} }
} }
...@@ -189,25 +180,25 @@ void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx, ...@@ -189,25 +180,25 @@ void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx,
const struct samsung_mux_clock *list, const struct samsung_mux_clock *list,
unsigned int nr_clk) unsigned int nr_clk)
{ {
struct clk *clk; struct clk_hw *clk_hw;
unsigned int idx, ret; unsigned int idx, ret;
for (idx = 0; idx < nr_clk; idx++, list++) { for (idx = 0; idx < nr_clk; idx++, list++) {
clk = clk_register_mux(NULL, list->name, list->parent_names, clk_hw = clk_hw_register_mux(NULL, list->name,
list->num_parents, list->flags, list->parent_names, list->num_parents, list->flags,
ctx->reg_base + list->offset, ctx->reg_base + list->offset,
list->shift, list->width, list->mux_flags, &ctx->lock); list->shift, list->width, list->mux_flags, &ctx->lock);
if (IS_ERR(clk)) { if (IS_ERR(clk_hw)) {
pr_err("%s: failed to register clock %s\n", __func__, pr_err("%s: failed to register clock %s\n", __func__,
list->name); list->name);
continue; continue;
} }
samsung_clk_add_lookup(ctx, clk, list->id); samsung_clk_add_lookup(ctx, clk_hw, list->id);
/* register a clock lookup only if a clock alias is specified */ /* register a clock lookup only if a clock alias is specified */
if (list->alias) { if (list->alias) {
ret = clk_register_clkdev(clk, list->alias, ret = clk_hw_register_clkdev(clk_hw, list->alias,
list->dev_name); list->dev_name);
if (ret) if (ret)
pr_err("%s: failed to register lookup %s\n", pr_err("%s: failed to register lookup %s\n",
...@@ -221,32 +212,32 @@ void __init samsung_clk_register_div(struct samsung_clk_provider *ctx, ...@@ -221,32 +212,32 @@ void __init samsung_clk_register_div(struct samsung_clk_provider *ctx,
const struct samsung_div_clock *list, const struct samsung_div_clock *list,
unsigned int nr_clk) unsigned int nr_clk)
{ {
struct clk *clk; struct clk_hw *clk_hw;
unsigned int idx, ret; unsigned int idx, ret;
for (idx = 0; idx < nr_clk; idx++, list++) { for (idx = 0; idx < nr_clk; idx++, list++) {
if (list->table) if (list->table)
clk = clk_register_divider_table(NULL, list->name, clk_hw = clk_hw_register_divider_table(NULL,
list->parent_name, list->flags, list->name, list->parent_name, list->flags,
ctx->reg_base + list->offset, ctx->reg_base + list->offset,
list->shift, list->width, list->div_flags, list->shift, list->width, list->div_flags,
list->table, &ctx->lock); list->table, &ctx->lock);
else else
clk = clk_register_divider(NULL, list->name, clk_hw = clk_hw_register_divider(NULL, list->name,
list->parent_name, list->flags, list->parent_name, list->flags,
ctx->reg_base + list->offset, list->shift, ctx->reg_base + list->offset, list->shift,
list->width, list->div_flags, &ctx->lock); list->width, list->div_flags, &ctx->lock);
if (IS_ERR(clk)) { if (IS_ERR(clk_hw)) {
pr_err("%s: failed to register clock %s\n", __func__, pr_err("%s: failed to register clock %s\n", __func__,
list->name); list->name);
continue; continue;
} }
samsung_clk_add_lookup(ctx, clk, list->id); samsung_clk_add_lookup(ctx, clk_hw, list->id);
/* register a clock lookup only if a clock alias is specified */ /* register a clock lookup only if a clock alias is specified */
if (list->alias) { if (list->alias) {
ret = clk_register_clkdev(clk, list->alias, ret = clk_hw_register_clkdev(clk_hw, list->alias,
list->dev_name); list->dev_name);
if (ret) if (ret)
pr_err("%s: failed to register lookup %s\n", pr_err("%s: failed to register lookup %s\n",
...@@ -260,14 +251,14 @@ void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx, ...@@ -260,14 +251,14 @@ void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
const struct samsung_gate_clock *list, const struct samsung_gate_clock *list,
unsigned int nr_clk) unsigned int nr_clk)
{ {
struct clk *clk; struct clk_hw *clk_hw;
unsigned int idx, ret; unsigned int idx, ret;
for (idx = 0; idx < nr_clk; idx++, list++) { for (idx = 0; idx < nr_clk; idx++, list++) {
clk = clk_register_gate(NULL, list->name, list->parent_name, clk_hw = clk_hw_register_gate(NULL, list->name, list->parent_name,
list->flags, ctx->reg_base + list->offset, list->flags, ctx->reg_base + list->offset,
list->bit_idx, list->gate_flags, &ctx->lock); list->bit_idx, list->gate_flags, &ctx->lock);
if (IS_ERR(clk)) { if (IS_ERR(clk_hw)) {
pr_err("%s: failed to register clock %s\n", __func__, pr_err("%s: failed to register clock %s\n", __func__,
list->name); list->name);
continue; continue;
...@@ -275,14 +266,14 @@ void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx, ...@@ -275,14 +266,14 @@ void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
/* register a clock lookup only if a clock alias is specified */ /* register a clock lookup only if a clock alias is specified */
if (list->alias) { if (list->alias) {
ret = clk_register_clkdev(clk, list->alias, ret = clk_hw_register_clkdev(clk_hw, list->alias,
list->dev_name); list->dev_name);
if (ret) if (ret)
pr_err("%s: failed to register lookup %s\n", pr_err("%s: failed to register lookup %s\n",
__func__, list->alias); __func__, list->alias);
} }
samsung_clk_add_lookup(ctx, clk, list->id); samsung_clk_add_lookup(ctx, clk_hw, list->id);
} }
} }
......
...@@ -16,18 +16,17 @@ ...@@ -16,18 +16,17 @@
#include <linux/clk-provider.h> #include <linux/clk-provider.h>
#include "clk-pll.h" #include "clk-pll.h"
struct clk;
/** /**
* struct samsung_clk_provider: information about clock provider * struct samsung_clk_provider: information about clock provider
* @reg_base: virtual address for the register base. * @reg_base: virtual address for the register base.
* @clk_data: holds clock related data like clk* and number of clocks.
* @lock: maintains exclusion between callbacks for a given clock-provider. * @lock: maintains exclusion between callbacks for a given clock-provider.
* @clk_data: holds clock related data like clk_hw* and number of clocks.
*/ */
struct samsung_clk_provider { struct samsung_clk_provider {
void __iomem *reg_base; void __iomem *reg_base;
struct clk_onecell_data clk_data;
spinlock_t lock; spinlock_t lock;
/* clk_data must be the last entry due to variable lenght 'hws' array */
struct clk_hw_onecell_data clk_data;
}; };
/** /**
...@@ -367,7 +366,7 @@ extern void __init samsung_clk_of_register_fixed_ext( ...@@ -367,7 +366,7 @@ extern void __init samsung_clk_of_register_fixed_ext(
const struct of_device_id *clk_matches); const struct of_device_id *clk_matches);
extern void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, extern void samsung_clk_add_lookup(struct samsung_clk_provider *ctx,
struct clk *clk, unsigned int id); struct clk_hw *clk_hw, unsigned int id);
extern void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx, extern void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx,
const struct samsung_clock_alias *list, const struct samsung_clock_alias *list,
......
...@@ -217,6 +217,9 @@ ...@@ -217,6 +217,9 @@
#define CLK_MOUT_MCLK_CDREX 654 #define CLK_MOUT_MCLK_CDREX 654
#define CLK_MOUT_BPLL 655 #define CLK_MOUT_BPLL 655
#define CLK_MOUT_MX_MSPLL_CCORE 656 #define CLK_MOUT_MX_MSPLL_CCORE 656
#define CLK_MOUT_EPLL 657
#define CLK_MOUT_MAU_EPLL 658
#define CLK_MOUT_USER_MAU_EPLL 659
/* divider clocks */ /* divider clocks */
#define CLK_DOUT_PIXEL 768 #define CLK_DOUT_PIXEL 768
......
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