summaryrefslogtreecommitdiff
path: root/drivers/clk/starfive
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/starfive')
-rw-r--r--drivers/clk/starfive/clk-starfive-jh7100-audio.c14
-rw-r--r--drivers/clk/starfive/clk-starfive-jh7110-aon.c14
-rw-r--r--drivers/clk/starfive/clk-starfive-jh7110-isp.c16
-rw-r--r--drivers/clk/starfive/clk-starfive-jh7110-pll.c2
-rw-r--r--drivers/clk/starfive/clk-starfive-jh7110-stg.c14
-rw-r--r--drivers/clk/starfive/clk-starfive-jh7110-sys.c45
-rw-r--r--drivers/clk/starfive/clk-starfive-jh7110-vout.c18
-rw-r--r--drivers/clk/starfive/clk-starfive-jh71x0.c12
-rw-r--r--drivers/clk/starfive/clk-starfive-jh71x0.h6
9 files changed, 63 insertions, 78 deletions
diff --git a/drivers/clk/starfive/clk-starfive-jh7100-audio.c b/drivers/clk/starfive/clk-starfive-jh7100-audio.c
index 1fcf4e62f347..7de23f6749aa 100644
--- a/drivers/clk/starfive/clk-starfive-jh7100-audio.c
+++ b/drivers/clk/starfive/clk-starfive-jh7100-audio.c
@@ -84,17 +84,6 @@ static const struct jh71x0_clk_data jh7100_audclk_data[] = {
JH7100_AUDCLK_AUDIO_12288),
};
-static struct clk_hw *jh7100_audclk_get(struct of_phandle_args *clkspec, void *data)
-{
- struct jh71x0_clk_priv *priv = data;
- unsigned int idx = clkspec->args[0];
-
- if (idx < JH7100_AUDCLK_END)
- return &priv->reg[idx].hw;
-
- return ERR_PTR(-EINVAL);
-}
-
static int jh7100_audclk_probe(struct platform_device *pdev)
{
struct jh71x0_clk_priv *priv;
@@ -106,6 +95,7 @@ static int jh7100_audclk_probe(struct platform_device *pdev)
return -ENOMEM;
spin_lock_init(&priv->rmw_lock);
+ priv->num_reg = JH7100_AUDCLK_END;
priv->dev = &pdev->dev;
priv->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->base))
@@ -146,7 +136,7 @@ static int jh7100_audclk_probe(struct platform_device *pdev)
return ret;
}
- return devm_of_clk_add_hw_provider(priv->dev, jh7100_audclk_get, priv);
+ return devm_of_clk_add_hw_provider(priv->dev, jh71x0_clk_get, priv);
}
static const struct of_device_id jh7100_audclk_match[] = {
diff --git a/drivers/clk/starfive/clk-starfive-jh7110-aon.c b/drivers/clk/starfive/clk-starfive-jh7110-aon.c
index 418efdad719b..6f67587f4335 100644
--- a/drivers/clk/starfive/clk-starfive-jh7110-aon.c
+++ b/drivers/clk/starfive/clk-starfive-jh7110-aon.c
@@ -54,17 +54,6 @@ static const struct jh71x0_clk_data jh7110_aonclk_data[] = {
JH71X0_GATE(JH7110_AONCLK_RTC_CAL, "rtc_cal", 0, JH7110_AONCLK_OSC),
};
-static struct clk_hw *jh7110_aonclk_get(struct of_phandle_args *clkspec, void *data)
-{
- struct jh71x0_clk_priv *priv = data;
- unsigned int idx = clkspec->args[0];
-
- if (idx < JH7110_AONCLK_END)
- return &priv->reg[idx].hw;
-
- return ERR_PTR(-EINVAL);
-}
-
static int jh7110_aoncrg_probe(struct platform_device *pdev)
{
struct jh71x0_clk_priv *priv;
@@ -78,6 +67,7 @@ static int jh7110_aoncrg_probe(struct platform_device *pdev)
return -ENOMEM;
spin_lock_init(&priv->rmw_lock);
+ priv->num_reg = JH7110_AONCLK_END;
priv->dev = &pdev->dev;
priv->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->base))
@@ -127,7 +117,7 @@ static int jh7110_aoncrg_probe(struct platform_device *pdev)
return ret;
}
- ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_aonclk_get, priv);
+ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh71x0_clk_get, priv);
if (ret)
return ret;
diff --git a/drivers/clk/starfive/clk-starfive-jh7110-isp.c b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
index d3c85421f948..f3fa069db193 100644
--- a/drivers/clk/starfive/clk-starfive-jh7110-isp.c
+++ b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
@@ -75,17 +75,6 @@ static inline int jh7110_isp_top_rst_init(struct jh71x0_clk_priv *priv)
return reset_control_deassert(top_rsts);
}
-static struct clk_hw *jh7110_ispclk_get(struct of_phandle_args *clkspec, void *data)
-{
- struct jh71x0_clk_priv *priv = data;
- unsigned int idx = clkspec->args[0];
-
- if (idx < JH7110_ISPCLK_END)
- return &priv->reg[idx].hw;
-
- return ERR_PTR(-EINVAL);
-}
-
#ifdef CONFIG_PM
static int jh7110_ispcrg_suspend(struct device *dev)
{
@@ -126,6 +115,7 @@ static int jh7110_ispcrg_probe(struct platform_device *pdev)
return -ENOMEM;
spin_lock_init(&priv->rmw_lock);
+ priv->num_reg = JH7110_ISPCLK_END;
priv->dev = &pdev->dev;
priv->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->base))
@@ -186,7 +176,7 @@ static int jh7110_ispcrg_probe(struct platform_device *pdev)
goto err_exit;
}
- ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_ispclk_get, priv);
+ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh71x0_clk_get, priv);
if (ret)
goto err_exit;
@@ -216,7 +206,7 @@ MODULE_DEVICE_TABLE(of, jh7110_ispcrg_match);
static struct platform_driver jh7110_ispcrg_driver = {
.probe = jh7110_ispcrg_probe,
- .remove_new = jh7110_ispcrg_remove,
+ .remove = jh7110_ispcrg_remove,
.driver = {
.name = "clk-starfive-jh7110-isp",
.of_match_table = jh7110_ispcrg_match,
diff --git a/drivers/clk/starfive/clk-starfive-jh7110-pll.c b/drivers/clk/starfive/clk-starfive-jh7110-pll.c
index 3598390e8fd0..56dc58a04f8a 100644
--- a/drivers/clk/starfive/clk-starfive-jh7110-pll.c
+++ b/drivers/clk/starfive/clk-starfive-jh7110-pll.c
@@ -453,7 +453,7 @@ static struct clk_hw *jh7110_pll_get(struct of_phandle_args *clkspec, void *data
return ERR_PTR(-EINVAL);
}
-static int jh7110_pll_probe(struct platform_device *pdev)
+static int __init jh7110_pll_probe(struct platform_device *pdev)
{
struct jh7110_pll_priv *priv;
unsigned int idx;
diff --git a/drivers/clk/starfive/clk-starfive-jh7110-stg.c b/drivers/clk/starfive/clk-starfive-jh7110-stg.c
index dafcb7190592..2a5ad0e07d1d 100644
--- a/drivers/clk/starfive/clk-starfive-jh7110-stg.c
+++ b/drivers/clk/starfive/clk-starfive-jh7110-stg.c
@@ -75,17 +75,6 @@ static const struct jh71x0_clk_data jh7110_stgclk_data[] = {
JH71X0_GATE(JH7110_STGCLK_DMA1P_AHB, "dma1p_ahb", 0, JH7110_STGCLK_STG_AXIAHB),
};
-static struct clk_hw *jh7110_stgclk_get(struct of_phandle_args *clkspec, void *data)
-{
- struct jh71x0_clk_priv *priv = data;
- unsigned int idx = clkspec->args[0];
-
- if (idx < JH7110_STGCLK_END)
- return &priv->reg[idx].hw;
-
- return ERR_PTR(-EINVAL);
-}
-
static int jh7110_stgcrg_probe(struct platform_device *pdev)
{
struct jh71x0_clk_priv *priv;
@@ -98,6 +87,7 @@ static int jh7110_stgcrg_probe(struct platform_device *pdev)
return -ENOMEM;
spin_lock_init(&priv->rmw_lock);
+ priv->num_reg = JH7110_STGCLK_END;
priv->dev = &pdev->dev;
priv->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->base))
@@ -145,7 +135,7 @@ static int jh7110_stgcrg_probe(struct platform_device *pdev)
return ret;
}
- ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_stgclk_get, priv);
+ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh71x0_clk_get, priv);
if (ret)
return ret;
diff --git a/drivers/clk/starfive/clk-starfive-jh7110-sys.c b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
index 8f5e5abfa178..e9d8168d02b8 100644
--- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c
+++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
@@ -323,17 +323,6 @@ static const struct jh71x0_clk_data jh7110_sysclk_data[] __initconst = {
JH7110_SYSCLK_OSC),
};
-static struct clk_hw *jh7110_sysclk_get(struct of_phandle_args *clkspec, void *data)
-{
- struct jh71x0_clk_priv *priv = data;
- unsigned int idx = clkspec->args[0];
-
- if (idx < JH7110_SYSCLK_END)
- return &priv->reg[idx].hw;
-
- return ERR_PTR(-EINVAL);
-}
-
static void jh7110_reset_unregister_adev(void *_adev)
{
struct auxiliary_device *adev = _adev;
@@ -385,6 +374,32 @@ int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,
}
EXPORT_SYMBOL_GPL(jh7110_reset_controller_register);
+/*
+ * This clock notifier is called when the rate of PLL0 clock is to be changed.
+ * The cpu_root clock should save the curent parent clock and switch its parent
+ * clock to osc before PLL0 rate will be changed. Then switch its parent clock
+ * back after the PLL0 rate is completed.
+ */
+static int jh7110_pll0_clk_notifier_cb(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct jh71x0_clk_priv *priv = container_of(nb, struct jh71x0_clk_priv, pll_clk_nb);
+ struct clk *cpu_root = priv->reg[JH7110_SYSCLK_CPU_ROOT].hw.clk;
+ int ret = 0;
+
+ if (action == PRE_RATE_CHANGE) {
+ struct clk *osc = clk_get(priv->dev, "osc");
+
+ priv->original_clk = clk_get_parent(cpu_root);
+ ret = clk_set_parent(cpu_root, osc);
+ clk_put(osc);
+ } else if (action == POST_RATE_CHANGE) {
+ ret = clk_set_parent(cpu_root, priv->original_clk);
+ }
+
+ return notifier_from_errno(ret);
+}
+
static int __init jh7110_syscrg_probe(struct platform_device *pdev)
{
struct jh71x0_clk_priv *priv;
@@ -399,6 +414,7 @@ static int __init jh7110_syscrg_probe(struct platform_device *pdev)
return -ENOMEM;
spin_lock_init(&priv->rmw_lock);
+ priv->num_reg = JH7110_SYSCLK_END;
priv->dev = &pdev->dev;
priv->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->base))
@@ -413,7 +429,10 @@ static int __init jh7110_syscrg_probe(struct platform_device *pdev)
if (IS_ERR(priv->pll[0]))
return PTR_ERR(priv->pll[0]);
} else {
- clk_put(pllclk);
+ priv->pll_clk_nb.notifier_call = jh7110_pll0_clk_notifier_cb;
+ ret = clk_notifier_register(pllclk, &priv->pll_clk_nb);
+ if (ret)
+ return ret;
priv->pll[0] = NULL;
}
@@ -497,7 +516,7 @@ static int __init jh7110_syscrg_probe(struct platform_device *pdev)
return ret;
}
- ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_sysclk_get, priv);
+ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh71x0_clk_get, priv);
if (ret)
return ret;
diff --git a/drivers/clk/starfive/clk-starfive-jh7110-vout.c b/drivers/clk/starfive/clk-starfive-jh7110-vout.c
index 53f7af234cc2..bad20d5d794a 100644
--- a/drivers/clk/starfive/clk-starfive-jh7110-vout.c
+++ b/drivers/clk/starfive/clk-starfive-jh7110-vout.c
@@ -80,17 +80,6 @@ static int jh7110_vout_top_rst_init(struct jh71x0_clk_priv *priv)
return reset_control_deassert(top_rst);
}
-static struct clk_hw *jh7110_voutclk_get(struct of_phandle_args *clkspec, void *data)
-{
- struct jh71x0_clk_priv *priv = data;
- unsigned int idx = clkspec->args[0];
-
- if (idx < JH7110_VOUTCLK_END)
- return &priv->reg[idx].hw;
-
- return ERR_PTR(-EINVAL);
-}
-
#ifdef CONFIG_PM
static int jh7110_voutcrg_suspend(struct device *dev)
{
@@ -131,6 +120,7 @@ static int jh7110_voutcrg_probe(struct platform_device *pdev)
return -ENOMEM;
spin_lock_init(&priv->rmw_lock);
+ priv->num_reg = JH7110_VOUTCLK_END;
priv->dev = &pdev->dev;
priv->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->base))
@@ -145,7 +135,7 @@ static int jh7110_voutcrg_probe(struct platform_device *pdev)
/* enable power domain and clocks */
pm_runtime_enable(priv->dev);
- ret = pm_runtime_get_sync(priv->dev);
+ ret = pm_runtime_resume_and_get(priv->dev);
if (ret < 0)
return dev_err_probe(priv->dev, ret, "failed to turn on power\n");
@@ -193,7 +183,7 @@ static int jh7110_voutcrg_probe(struct platform_device *pdev)
goto err_exit;
}
- ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_voutclk_get, priv);
+ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh71x0_clk_get, priv);
if (ret)
goto err_exit;
@@ -223,7 +213,7 @@ MODULE_DEVICE_TABLE(of, jh7110_voutcrg_match);
static struct platform_driver jh7110_voutcrg_driver = {
.probe = jh7110_voutcrg_probe,
- .remove_new = jh7110_voutcrg_remove,
+ .remove = jh7110_voutcrg_remove,
.driver = {
.name = "clk-starfive-jh7110-vout",
.of_match_table = jh7110_voutcrg_match,
diff --git a/drivers/clk/starfive/clk-starfive-jh71x0.c b/drivers/clk/starfive/clk-starfive-jh71x0.c
index aebc99264a0b..80e9157347eb 100644
--- a/drivers/clk/starfive/clk-starfive-jh71x0.c
+++ b/drivers/clk/starfive/clk-starfive-jh71x0.c
@@ -325,3 +325,15 @@ const struct clk_ops *starfive_jh71x0_clk_ops(u32 max)
return &jh71x0_clk_inv_ops;
}
EXPORT_SYMBOL_GPL(starfive_jh71x0_clk_ops);
+
+struct clk_hw *jh71x0_clk_get(struct of_phandle_args *clkspec, void *data)
+{
+ struct jh71x0_clk_priv *priv = data;
+ unsigned int idx = clkspec->args[0];
+
+ if (idx < priv->num_reg)
+ return &priv->reg[idx].hw;
+
+ return ERR_PTR(-EINVAL);
+}
+EXPORT_SYMBOL_GPL(jh71x0_clk_get);
diff --git a/drivers/clk/starfive/clk-starfive-jh71x0.h b/drivers/clk/starfive/clk-starfive-jh71x0.h
index 23e052fc1549..9d5dec1d5cd1 100644
--- a/drivers/clk/starfive/clk-starfive-jh71x0.h
+++ b/drivers/clk/starfive/clk-starfive-jh71x0.h
@@ -114,10 +114,14 @@ struct jh71x0_clk_priv {
spinlock_t rmw_lock;
struct device *dev;
void __iomem *base;
+ struct clk *original_clk;
+ struct notifier_block pll_clk_nb;
struct clk_hw *pll[3];
- struct jh71x0_clk reg[];
+ unsigned int num_reg;
+ struct jh71x0_clk reg[] __counted_by(num_reg);
};
const struct clk_ops *starfive_jh71x0_clk_ops(u32 max);
+struct clk_hw *jh71x0_clk_get(struct of_phandle_args *clkspec, void *data);
#endif