OSDN Git Service

Merge branches 'clk-uniphier', 'clk-warn-critical', 'clk-ux500', 'clk-kconfig' and...
authorStephen Boyd <sboyd@kernel.org>
Fri, 31 Jan 2020 21:12:00 +0000 (13:12 -0800)
committerStephen Boyd <sboyd@kernel.org>
Fri, 31 Jan 2020 21:12:00 +0000 (13:12 -0800)
 - Warn about critical clks that fail to enable or prepare
 - Detect more PRMCU variants in ux500 driver

* clk-uniphier:
  clk: uniphier: Add SCSSI clock gate for each channel

* clk-warn-critical:
  clk: Warn about critical clks that fail to enable
  clk: Don't try to enable critical clocks if prepare failed
  clk: tegra: Fix double-free in tegra_clk_init()
  clk: samsung: exynos5420: Keep top G3D clocks enabled
  clk: qcom: Avoid SMMU/cx gdsc corner cases
  clk: qcom: gcc-sc7180: Fix setting flag for votable GDSCs
  clk: Move clk_core_reparent_orphans() under CONFIG_OF
  clk: at91: fix possible deadlock
  clk: walk orphan list on clock provider registration
  clk: imx: pll14xx: fix clk_pll14xx_wait_lock
  clk: imx: clk-imx7ulp: Add missing sentinel of ulp_div_table
  clk: imx: clk-composite-8m: add lock to gate/mux

* clk-ux500:
  clk: ux500: Fix up the SGA clock for some variants

* clk-kconfig:
  clk: Fix Kconfig indentation

* clk-at91:
  clk: at91: sam9x60: fix programmable clock prescaler
  clk: at91: sam9x60-pll: adapt PMC_PLL_ACR default value

36 files changed:
drivers/clk/Kconfig
drivers/clk/at91/at91sam9260.c
drivers/clk/at91/at91sam9rl.c
drivers/clk/at91/at91sam9x5.c
drivers/clk/at91/clk-sam9x60-pll.c
drivers/clk/at91/pmc.c
drivers/clk/at91/sam9x60.c
drivers/clk/at91/sama5d2.c
drivers/clk/at91/sama5d4.c
drivers/clk/clk-bm1880.c
drivers/clk/clk.c
drivers/clk/imx/clk-composite-8m.c
drivers/clk/imx/clk-imx7ulp.c
drivers/clk/imx/clk-pll14xx.c
drivers/clk/mediatek/Kconfig
drivers/clk/meson/clk-mpll.c
drivers/clk/meson/clk-phase.c
drivers/clk/meson/clk-pll.c
drivers/clk/meson/sclk-div.c
drivers/clk/microchip/clk-core.c
drivers/clk/mmp/clk-frac.c
drivers/clk/mmp/clk-mix.c
drivers/clk/mvebu/Kconfig
drivers/clk/qcom/Kconfig
drivers/clk/qcom/clk-hfpll.c
drivers/clk/qcom/gcc-sc7180.c
drivers/clk/qcom/gpucc-msm8998.c
drivers/clk/rockchip/clk-pll.c
drivers/clk/samsung/clk-exynos5420.c
drivers/clk/tegra/clk.c
drivers/clk/ti/clock.h
drivers/clk/ti/clockdomain.c
drivers/clk/ux500/u8500_of_clk.c
drivers/clk/versatile/Kconfig
drivers/net/phy/mdio-mux-meson-g12a.c
include/linux/clk-provider.h

index 45653a0..a48e326 100644 (file)
@@ -27,7 +27,7 @@ config COMMON_CLK_WM831X
        tristate "Clock driver for WM831x/2x PMICs"
        depends on MFD_WM831X
        ---help---
-          Supports the clocking subsystem of the WM831x/2x series of
+         Supports the clocking subsystem of the WM831x/2x series of
          PMICs from Wolfson Microelectronics.
 
 source "drivers/clk/versatile/Kconfig"
index 0aabe49..a9d4234 100644 (file)
@@ -348,7 +348,7 @@ static void __init at91sam926x_pmc_setup(struct device_node *np,
                return;
        mainxtal_name = of_clk_get_parent_name(np, i);
 
-       regmap = syscon_node_to_regmap(np);
+       regmap = device_node_to_regmap(np);
        if (IS_ERR(regmap))
                return;
 
index 0ac34cd..77fe83a 100644 (file)
@@ -83,7 +83,7 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np)
                return;
        mainxtal_name = of_clk_get_parent_name(np, i);
 
-       regmap = syscon_node_to_regmap(np);
+       regmap = device_node_to_regmap(np);
        if (IS_ERR(regmap))
                return;
 
index 0855f3a..086cf0b 100644 (file)
@@ -146,7 +146,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np,
                return;
        mainxtal_name = of_clk_get_parent_name(np, i);
 
-       regmap = syscon_node_to_regmap(np);
+       regmap = device_node_to_regmap(np);
        if (IS_ERR(regmap))
                return;
 
index 34b8178..dfb354a 100644 (file)
@@ -25,7 +25,8 @@
 #define                PMC_PLL_CTRL1_MUL_MSK           GENMASK(30, 24)
 
 #define PMC_PLL_ACR    0x18
-#define                PMC_PLL_ACR_DEFAULT             0x1b040010UL
+#define                PMC_PLL_ACR_DEFAULT_UPLL        0x12020010UL
+#define                PMC_PLL_ACR_DEFAULT_PLLA        0x00020010UL
 #define                PMC_PLL_ACR_UTMIVR              BIT(12)
 #define                PMC_PLL_ACR_UTMIBG              BIT(13)
 #define                PMC_PLL_ACR_LOOP_FILTER_MSK     GENMASK(31, 24)
@@ -88,7 +89,10 @@ static int sam9x60_pll_prepare(struct clk_hw *hw)
        }
 
        /* Recommended value for PMC_PLL_ACR */
-       val = PMC_PLL_ACR_DEFAULT;
+       if (pll->characteristics->upll)
+               val = PMC_PLL_ACR_DEFAULT_UPLL;
+       else
+               val = PMC_PLL_ACR_DEFAULT_PLLA;
        regmap_write(regmap, PMC_PLL_ACR, val);
 
        regmap_write(regmap, PMC_PLL_CTRL1,
index 0b03cfa..b71515a 100644 (file)
@@ -275,7 +275,7 @@ static int __init pmc_register_ops(void)
 
        np = of_find_matching_node(NULL, sama5d2_pmc_dt_ids);
 
-       pmcreg = syscon_node_to_regmap(np);
+       pmcreg = device_node_to_regmap(np);
        if (IS_ERR(pmcreg))
                return PTR_ERR(pmcreg);
 
index 86238d5..77398ae 100644 (file)
@@ -47,6 +47,7 @@ static const struct clk_programmable_layout sam9x60_programmable_layout = {
        .pres_shift = 8,
        .css_mask = 0x1f,
        .have_slck_mck = 0,
+       .is_pres_direct = 1,
 };
 
 static const struct clk_pcr_layout sam9x60_pcr_layout = {
index 0de1108..ff7e3f7 100644 (file)
@@ -162,7 +162,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
                return;
        mainxtal_name = of_clk_get_parent_name(np, i);
 
-       regmap = syscon_node_to_regmap(np);
+       regmap = device_node_to_regmap(np);
        if (IS_ERR(regmap))
                return;
 
index 25b156d..a6dee4a 100644 (file)
@@ -136,7 +136,7 @@ static void __init sama5d4_pmc_setup(struct device_node *np)
                return;
        mainxtal_name = of_clk_get_parent_name(np, i);
 
-       regmap = syscon_node_to_regmap(np);
+       regmap = device_node_to_regmap(np);
        if (IS_ERR(regmap))
                return;
 
index 4cd175a..e6d6599 100644 (file)
@@ -474,11 +474,10 @@ static struct bm1880_composite_clock bm1880_composite_clks[] = {
 static unsigned long bm1880_pll_rate_calc(u32 regval, unsigned long parent_rate)
 {
        u64 numerator;
-       u32 fbdiv, fref, refdiv;
+       u32 fbdiv, refdiv;
        u32 postdiv1, postdiv2, denominator;
 
        fbdiv = (regval >> 16) & 0xfff;
-       fref = parent_rate;
        refdiv = regval & 0x1f;
        postdiv1 = (regval >> 8) & 0x7;
        postdiv2 = (regval >> 12) & 0x7;
index b68e200..fa99d0b 100644 (file)
@@ -3249,6 +3249,34 @@ static inline void clk_debug_unregister(struct clk_core *core)
 }
 #endif
 
+static void clk_core_reparent_orphans_nolock(void)
+{
+       struct clk_core *orphan;
+       struct hlist_node *tmp2;
+
+       /*
+        * walk the list of orphan clocks and reparent any that newly finds a
+        * parent.
+        */
+       hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) {
+               struct clk_core *parent = __clk_init_parent(orphan);
+
+               /*
+                * We need to use __clk_set_parent_before() and _after() to
+                * to properly migrate any prepare/enable count of the orphan
+                * clock. This is important for CLK_IS_CRITICAL clocks, which
+                * are enabled during init but might not have a parent yet.
+                */
+               if (parent) {
+                       /* update the clk tree topology */
+                       __clk_set_parent_before(orphan, parent);
+                       __clk_set_parent_after(orphan, parent, NULL);
+                       __clk_recalc_accuracies(orphan);
+                       __clk_recalc_rates(orphan, 0);
+               }
+       }
+}
+
 /**
  * __clk_core_init - initialize the data structures in a struct clk_core
  * @core:      clk_core being initialized
@@ -3259,8 +3287,6 @@ static inline void clk_debug_unregister(struct clk_core *core)
 static int __clk_core_init(struct clk_core *core)
 {
        int ret;
-       struct clk_core *orphan;
-       struct hlist_node *tmp2;
        unsigned long rate;
 
        if (!core)
@@ -3312,6 +3338,26 @@ static int __clk_core_init(struct clk_core *core)
                goto out;
        }
 
+       /*
+        * optional platform-specific magic
+        *
+        * The .init callback is not used by any of the basic clock types, but
+        * exists for weird hardware that must perform initialization magic for
+        * CCF to get an accurate view of clock for any other callbacks. It may
+        * also be used needs to perform dynamic allocations. Such allocation
+        * must be freed in the terminate() callback.
+        * This callback shall not be used to initialize the parameters state,
+        * such as rate, parent, etc ...
+        *
+        * If it exist, this callback should called before any other callback of
+        * the clock
+        */
+       if (core->ops->init) {
+               ret = core->ops->init(core->hw);
+               if (ret)
+                       goto out;
+       }
+
        core->parent = __clk_init_parent(core);
 
        /*
@@ -3337,17 +3383,6 @@ static int __clk_core_init(struct clk_core *core)
        }
 
        /*
-        * optional platform-specific magic
-        *
-        * The .init callback is not used by any of the basic clock types, but
-        * exists for weird hardware that must perform initialization magic.
-        * Please consider other ways of solving initialization problems before
-        * using this callback, as its use is discouraged.
-        */
-       if (core->ops->init)
-               core->ops->init(core->hw);
-
-       /*
         * Set clk's accuracy.  The preferred method is to use
         * .recalc_accuracy. For simple clocks and lazy developers the default
         * fallback is to use the parent's accuracy.  If a clock doesn't have a
@@ -3400,34 +3435,26 @@ static int __clk_core_init(struct clk_core *core)
        if (core->flags & CLK_IS_CRITICAL) {
                unsigned long flags;
 
-               clk_core_prepare(core);
+               ret = clk_core_prepare(core);
+               if (ret) {
+                       pr_warn("%s: critical clk '%s' failed to prepare\n",
+                              __func__, core->name);
+                       goto out;
+               }
 
                flags = clk_enable_lock();
-               clk_core_enable(core);
+               ret = clk_core_enable(core);
                clk_enable_unlock(flags);
+               if (ret) {
+                       pr_warn("%s: critical clk '%s' failed to enable\n",
+                              __func__, core->name);
+                       clk_core_unprepare(core);
+                       goto out;
+               }
        }
 
-       /*
-        * walk the list of orphan clocks and reparent any that newly finds a
-        * parent.
-        */
-       hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) {
-               struct clk_core *parent = __clk_init_parent(orphan);
+       clk_core_reparent_orphans_nolock();
 
-               /*
-                * We need to use __clk_set_parent_before() and _after() to
-                * to properly migrate any prepare/enable count of the orphan
-                * clock. This is important for CLK_IS_CRITICAL clocks, which
-                * are enabled during init but might not have a parent yet.
-                */
-               if (parent) {
-                       /* update the clk tree topology */
-                       __clk_set_parent_before(orphan, parent);
-                       __clk_set_parent_after(orphan, parent, NULL);
-                       __clk_recalc_accuracies(orphan);
-                       __clk_recalc_rates(orphan, 0);
-               }
-       }
 
        kref_init(&core->ref);
 out:
@@ -3720,6 +3747,28 @@ fail_out:
 }
 
 /**
+ * dev_or_parent_of_node() - Get device node of @dev or @dev's parent
+ * @dev: Device to get device node of
+ *
+ * Return: device node pointer of @dev, or the device node pointer of
+ * @dev->parent if dev doesn't have a device node, or NULL if neither
+ * @dev or @dev->parent have a device node.
+ */
+static struct device_node *dev_or_parent_of_node(struct device *dev)
+{
+       struct device_node *np;
+
+       if (!dev)
+               return NULL;
+
+       np = dev_of_node(dev);
+       if (!np)
+               np = dev_of_node(dev->parent);
+
+       return np;
+}
+
+/**
  * clk_register - allocate a new clock, register it and return an opaque cookie
  * @dev: device that is registering this clock
  * @hw: link to hardware-specific clock data
@@ -3734,7 +3783,7 @@ fail_out:
  */
 struct clk *clk_register(struct device *dev, struct clk_hw *hw)
 {
-       return __clk_register(dev, dev_of_node(dev), hw);
+       return __clk_register(dev, dev_or_parent_of_node(dev), hw);
 }
 EXPORT_SYMBOL_GPL(clk_register);
 
@@ -3750,7 +3799,8 @@ EXPORT_SYMBOL_GPL(clk_register);
  */
 int clk_hw_register(struct device *dev, struct clk_hw *hw)
 {
-       return PTR_ERR_OR_ZERO(__clk_register(dev, dev_of_node(dev), hw));
+       return PTR_ERR_OR_ZERO(__clk_register(dev, dev_or_parent_of_node(dev),
+                              hw));
 }
 EXPORT_SYMBOL_GPL(clk_hw_register);
 
@@ -3853,6 +3903,7 @@ static void clk_core_evict_parent_cache(struct clk_core *core)
 void clk_unregister(struct clk *clk)
 {
        unsigned long flags;
+       const struct clk_ops *ops;
 
        if (!clk || WARN_ON_ONCE(IS_ERR(clk)))
                return;
@@ -3861,7 +3912,8 @@ void clk_unregister(struct clk *clk)
 
        clk_prepare_lock();
 
-       if (clk->core->ops == &clk_nodrv_ops) {
+       ops = clk->core->ops;
+       if (ops == &clk_nodrv_ops) {
                pr_err("%s: unregistered clock: %s\n", __func__,
                       clk->core->name);
                goto unlock;
@@ -3874,6 +3926,9 @@ void clk_unregister(struct clk *clk)
        clk->core->ops = &clk_nodrv_ops;
        clk_enable_unlock(flags);
 
+       if (ops->terminate)
+               ops->terminate(clk->core->hw);
+
        if (!hlist_empty(&clk->core->children)) {
                struct clk_core *child;
                struct hlist_node *t;
@@ -4179,6 +4234,13 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb)
 EXPORT_SYMBOL_GPL(clk_notifier_unregister);
 
 #ifdef CONFIG_OF
+static void clk_core_reparent_orphans(void)
+{
+       clk_prepare_lock();
+       clk_core_reparent_orphans_nolock();
+       clk_prepare_unlock();
+}
+
 /**
  * struct of_clk_provider - Clock provider registration structure
  * @link: Entry in global list of clock providers
@@ -4274,6 +4336,8 @@ int of_clk_add_provider(struct device_node *np,
        mutex_unlock(&of_clk_mutex);
        pr_debug("Added clock from %pOF\n", np);
 
+       clk_core_reparent_orphans();
+
        ret = of_clk_set_defaults(np, true);
        if (ret < 0)
                of_clk_del_provider(np);
@@ -4309,6 +4373,8 @@ int of_clk_add_hw_provider(struct device_node *np,
        mutex_unlock(&of_clk_mutex);
        pr_debug("Added clk_hw provider from %pOF\n", np);
 
+       clk_core_reparent_orphans();
+
        ret = of_clk_set_defaults(np, true);
        if (ret < 0)
                of_clk_del_provider(np);
index 388bdb9..d3486ee 100644 (file)
@@ -142,6 +142,7 @@ struct clk *imx8m_clk_composite_flags(const char *name,
        mux->reg = reg;
        mux->shift = PCG_PCS_SHIFT;
        mux->mask = PCG_PCS_MASK;
+       mux->lock = &imx_ccm_lock;
 
        div = kzalloc(sizeof(*div), GFP_KERNEL);
        if (!div)
@@ -161,6 +162,7 @@ struct clk *imx8m_clk_composite_flags(const char *name,
        gate_hw = &gate->hw;
        gate->reg = reg;
        gate->bit_idx = PCG_CGC_SHIFT;
+       gate->lock = &imx_ccm_lock;
 
        hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
                        mux_hw, &clk_mux_ops, div_hw,
index 3fdf3d4..281191b 100644 (file)
@@ -40,6 +40,7 @@ static const struct clk_div_table ulp_div_table[] = {
        { .val = 5, .div = 16, },
        { .val = 6, .div = 32, },
        { .val = 7, .div = 64, },
+       { /* sentinel */ },
 };
 
 static const int pcc2_uart_clk_ids[] __initconst = {
index 5c45819..3636c80 100644 (file)
@@ -159,7 +159,7 @@ static int clk_pll14xx_wait_lock(struct clk_pll14xx *pll)
 {
        u32 val;
 
-       return readl_poll_timeout(pll->base, val, val & LOCK_TIMEOUT_US, 0,
+       return readl_poll_timeout(pll->base, val, val & LOCK_STATUS, 0,
                        LOCK_TIMEOUT_US);
 }
 
index 7efc361..ea3c70d 100644 (file)
@@ -174,36 +174,36 @@ config COMMON_CLK_MT6779_AUDSYS
          This driver supports Mediatek MT6779 audsys clocks.
 
 config COMMON_CLK_MT6797
-       bool "Clock driver for MediaTek MT6797"
-       depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
-       select COMMON_CLK_MEDIATEK
-       default ARCH_MEDIATEK && ARM64
-       ---help---
-         This driver supports MediaTek MT6797 basic clocks.
+       bool "Clock driver for MediaTek MT6797"
+       depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
+       select COMMON_CLK_MEDIATEK
+       default ARCH_MEDIATEK && ARM64
+       ---help---
+         This driver supports MediaTek MT6797 basic clocks.
 
 config COMMON_CLK_MT6797_MMSYS
-       bool "Clock driver for MediaTek MT6797 mmsys"
-       depends on COMMON_CLK_MT6797
-       ---help---
-         This driver supports MediaTek MT6797 mmsys clocks.
+       bool "Clock driver for MediaTek MT6797 mmsys"
+       depends on COMMON_CLK_MT6797
+       ---help---
+         This driver supports MediaTek MT6797 mmsys clocks.
 
 config COMMON_CLK_MT6797_IMGSYS
-       bool "Clock driver for MediaTek MT6797 imgsys"
-       depends on COMMON_CLK_MT6797
-       ---help---
-         This driver supports MediaTek MT6797 imgsys clocks.
+       bool "Clock driver for MediaTek MT6797 imgsys"
+       depends on COMMON_CLK_MT6797
+       ---help---
+         This driver supports MediaTek MT6797 imgsys clocks.
 
 config COMMON_CLK_MT6797_VDECSYS
-       bool "Clock driver for MediaTek MT6797 vdecsys"
-       depends on COMMON_CLK_MT6797
-       ---help---
-         This driver supports MediaTek MT6797 vdecsys clocks.
+       bool "Clock driver for MediaTek MT6797 vdecsys"
+       depends on COMMON_CLK_MT6797
+       ---help---
+         This driver supports MediaTek MT6797 vdecsys clocks.
 
 config COMMON_CLK_MT6797_VENCSYS
-       bool "Clock driver for MediaTek MT6797 vencsys"
-       depends on COMMON_CLK_MT6797
-       ---help---
-         This driver supports MediaTek MT6797 vencsys clocks.
+       bool "Clock driver for MediaTek MT6797 vencsys"
+       depends on COMMON_CLK_MT6797
+       ---help---
+         This driver supports MediaTek MT6797 vencsys clocks.
 
 config COMMON_CLK_MT7622
        bool "Clock driver for MediaTek MT7622"
index 2d39a8b..fc9df48 100644 (file)
@@ -129,7 +129,7 @@ static int mpll_set_rate(struct clk_hw *hw,
        return 0;
 }
 
-static void mpll_init(struct clk_hw *hw)
+static int mpll_init(struct clk_hw *hw)
 {
        struct clk_regmap *clk = to_clk_regmap(hw);
        struct meson_clk_mpll_data *mpll = meson_clk_mpll_data(clk);
@@ -151,6 +151,8 @@ static void mpll_init(struct clk_hw *hw)
        /* Set the magic misc bit if required */
        if (MESON_PARM_APPLICABLE(&mpll->misc))
                meson_parm_write(clk->map, &mpll->misc, 1);
+
+       return 0;
 }
 
 const struct clk_ops meson_clk_mpll_ro_ops = {
index 80c3ada..fe22e17 100644 (file)
@@ -78,7 +78,7 @@ meson_clk_triphase_data(struct clk_regmap *clk)
        return (struct meson_clk_triphase_data *)clk->data;
 }
 
-static void meson_clk_triphase_sync(struct clk_hw *hw)
+static int meson_clk_triphase_sync(struct clk_hw *hw)
 {
        struct clk_regmap *clk = to_clk_regmap(hw);
        struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk);
@@ -88,6 +88,8 @@ static void meson_clk_triphase_sync(struct clk_hw *hw)
        val = meson_parm_read(clk->map, &tph->ph0);
        meson_parm_write(clk->map, &tph->ph1, val);
        meson_parm_write(clk->map, &tph->ph2, val);
+
+       return 0;
 }
 
 static int meson_clk_triphase_get_phase(struct clk_hw *hw)
index ddb1e56..489092d 100644 (file)
@@ -277,7 +277,7 @@ static int meson_clk_pll_wait_lock(struct clk_hw *hw)
        return -ETIMEDOUT;
 }
 
-static void meson_clk_pll_init(struct clk_hw *hw)
+static int meson_clk_pll_init(struct clk_hw *hw)
 {
        struct clk_regmap *clk = to_clk_regmap(hw);
        struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
@@ -288,6 +288,8 @@ static void meson_clk_pll_init(struct clk_hw *hw)
                                       pll->init_count);
                meson_parm_write(clk->map, &pll->rst, 0);
        }
+
+       return 0;
 }
 
 static int meson_clk_pll_is_enabled(struct clk_hw *hw)
index 3acf037..76d31c0 100644 (file)
@@ -216,7 +216,7 @@ static int sclk_div_is_enabled(struct clk_hw *hw)
        return 0;
 }
 
-static void sclk_div_init(struct clk_hw *hw)
+static int sclk_div_init(struct clk_hw *hw)
 {
        struct clk_regmap *clk = to_clk_regmap(hw);
        struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk);
@@ -231,6 +231,8 @@ static void sclk_div_init(struct clk_hw *hw)
                sclk->cached_div = val + 1;
 
        sclk_div_get_duty_cycle(hw, &sclk->cached_duty);
+
+       return 0;
 }
 
 const struct clk_ops meson_sclk_div_ops = {
index 567755d..1b4f023 100644 (file)
@@ -266,10 +266,12 @@ static void roclk_disable(struct clk_hw *hw)
        writel(REFO_ON | REFO_OE, PIC32_CLR(refo->ctrl_reg));
 }
 
-static void roclk_init(struct clk_hw *hw)
+static int roclk_init(struct clk_hw *hw)
 {
        /* initialize clock in disabled state */
        roclk_disable(hw);
+
+       return 0;
 }
 
 static u8 roclk_get_parent(struct clk_hw *hw)
@@ -880,7 +882,7 @@ static int sclk_set_parent(struct clk_hw *hw, u8 index)
        return err;
 }
 
-static void sclk_init(struct clk_hw *hw)
+static int sclk_init(struct clk_hw *hw)
 {
        struct pic32_sys_clk *sclk = clkhw_to_sys_clk(hw);
        unsigned long flags;
@@ -899,6 +901,8 @@ static void sclk_init(struct clk_hw *hw)
                writel(v, sclk->slew_reg);
                spin_unlock_irqrestore(&sclk->core->reg_lock, flags);
        }
+
+       return 0;
 }
 
 /* sclk with post-divider */
index 90bf181..fabc09a 100644 (file)
@@ -109,7 +109,7 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate,
        return 0;
 }
 
-static void clk_factor_init(struct clk_hw *hw)
+static int clk_factor_init(struct clk_hw *hw)
 {
        struct mmp_clk_factor *factor = to_clk_factor(hw);
        struct mmp_clk_factor_masks *masks = factor->masks;
@@ -146,6 +146,8 @@ static void clk_factor_init(struct clk_hw *hw)
 
        if (factor->lock)
                spin_unlock_irqrestore(factor->lock, flags);
+
+       return 0;
 }
 
 static const struct clk_ops clk_factor_ops = {
index 90814b2..d2cd36c 100644 (file)
@@ -419,12 +419,14 @@ static int mmp_clk_set_rate(struct clk_hw *hw, unsigned long rate,
        }
 }
 
-static void mmp_clk_mix_init(struct clk_hw *hw)
+static int mmp_clk_mix_init(struct clk_hw *hw)
 {
        struct mmp_clk_mix *mix = to_clk_mix(hw);
 
        if (mix->table)
                _filter_clk_table(mix, mix->table, mix->table_size);
+
+       return 0;
 }
 
 const struct clk_ops mmp_clk_mix_ops = {
index 415e690..ded07b0 100644 (file)
@@ -29,7 +29,7 @@ config ARMADA_39X_CLK
        select MVEBU_CLK_COMMON
 
 config ARMADA_37XX_CLK
-       bool
+       bool
 
 config ARMADA_XP_CLK
        bool
index 3b33ef1..f37f3cd 100644 (file)
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config KRAIT_CLOCKS
-       bool
-       select KRAIT_L2_ACCESSORS
+       bool
+       select KRAIT_L2_ACCESSORS
 
 config QCOM_GDSC
        bool
index 3c04805..e847d58 100644 (file)
@@ -196,7 +196,7 @@ static unsigned long clk_hfpll_recalc_rate(struct clk_hw *hw,
        return l_val * parent_rate;
 }
 
-static void clk_hfpll_init(struct clk_hw *hw)
+static int clk_hfpll_init(struct clk_hw *hw)
 {
        struct clk_hfpll *h = to_clk_hfpll(hw);
        struct hfpll_data const *hd = h->d;
@@ -206,7 +206,7 @@ static void clk_hfpll_init(struct clk_hw *hw)
        regmap_read(regmap, hd->mode_reg, &mode);
        if (mode != (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL)) {
                __clk_hfpll_init_once(hw);
-               return;
+               return 0;
        }
 
        if (hd->status_reg) {
@@ -218,6 +218,8 @@ static void clk_hfpll_init(struct clk_hw *hw)
                        __clk_hfpll_init_once(hw);
                }
        }
+
+       return 0;
 }
 
 static int hfpll_is_enabled(struct clk_hw *hw)
index 38424e6..7f59fb8 100644 (file)
@@ -2186,7 +2186,8 @@ static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc = {
        .pd = {
                .name = "hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc",
        },
-       .pwrsts = PWRSTS_OFF_ON | VOTABLE,
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
 };
 
 static struct gdsc hlos1_vote_mmnoc_mmu_tbu_sf_gdsc = {
@@ -2194,7 +2195,8 @@ static struct gdsc hlos1_vote_mmnoc_mmu_tbu_sf_gdsc = {
        .pd = {
                .name = "hlos1_vote_mmnoc_mmu_tbu_sf_gdsc",
        },
-       .pwrsts = PWRSTS_OFF_ON | VOTABLE,
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
 };
 
 static struct gdsc *gcc_sc7180_gdscs[] = {
index e5e2492..9b3923a 100644 (file)
@@ -242,10 +242,12 @@ static struct clk_branch gfx3d_isense_clk = {
 
 static struct gdsc gpu_cx_gdsc = {
        .gdscr = 0x1004,
+       .gds_hw_ctrl = 0x1008,
        .pd = {
                .name = "gpu_cx",
        },
        .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
 };
 
 static struct gdsc gpu_gx_gdsc = {
index 198417d..10560d9 100644 (file)
@@ -282,7 +282,7 @@ static int rockchip_rk3036_pll_is_enabled(struct clk_hw *hw)
        return !(pllcon & RK3036_PLLCON1_PWRDOWN);
 }
 
-static void rockchip_rk3036_pll_init(struct clk_hw *hw)
+static int rockchip_rk3036_pll_init(struct clk_hw *hw)
 {
        struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
        const struct rockchip_pll_rate_table *rate;
@@ -290,14 +290,14 @@ static void rockchip_rk3036_pll_init(struct clk_hw *hw)
        unsigned long drate;
 
        if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
-               return;
+               return 0;
 
        drate = clk_hw_get_rate(hw);
        rate = rockchip_get_pll_settings(pll, drate);
 
        /* when no rate setting for the current rate, rely on clk_set_rate */
        if (!rate)
-               return;
+               return 0;
 
        rockchip_rk3036_pll_get_params(pll, &cur);
 
@@ -319,13 +319,15 @@ static void rockchip_rk3036_pll_init(struct clk_hw *hw)
                if (!parent) {
                        pr_warn("%s: parent of %s not available\n",
                                __func__, __clk_get_name(hw->clk));
-                       return;
+                       return 0;
                }
 
                pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
                         __func__, __clk_get_name(hw->clk));
                rockchip_rk3036_pll_set_params(pll, rate);
        }
+
+       return 0;
 }
 
 static const struct clk_ops rockchip_rk3036_pll_clk_norate_ops = {
@@ -515,7 +517,7 @@ static int rockchip_rk3066_pll_is_enabled(struct clk_hw *hw)
        return !(pllcon & RK3066_PLLCON3_PWRDOWN);
 }
 
-static void rockchip_rk3066_pll_init(struct clk_hw *hw)
+static int rockchip_rk3066_pll_init(struct clk_hw *hw)
 {
        struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
        const struct rockchip_pll_rate_table *rate;
@@ -523,14 +525,14 @@ static void rockchip_rk3066_pll_init(struct clk_hw *hw)
        unsigned long drate;
 
        if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
-               return;
+               return 0;
 
        drate = clk_hw_get_rate(hw);
        rate = rockchip_get_pll_settings(pll, drate);
 
        /* when no rate setting for the current rate, rely on clk_set_rate */
        if (!rate)
-               return;
+               return 0;
 
        rockchip_rk3066_pll_get_params(pll, &cur);
 
@@ -543,6 +545,8 @@ static void rockchip_rk3066_pll_init(struct clk_hw *hw)
                         __func__, clk_hw_get_name(hw));
                rockchip_rk3066_pll_set_params(pll, rate);
        }
+
+       return 0;
 }
 
 static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = {
@@ -761,7 +765,7 @@ static int rockchip_rk3399_pll_is_enabled(struct clk_hw *hw)
        return !(pllcon & RK3399_PLLCON3_PWRDOWN);
 }
 
-static void rockchip_rk3399_pll_init(struct clk_hw *hw)
+static int rockchip_rk3399_pll_init(struct clk_hw *hw)
 {
        struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
        const struct rockchip_pll_rate_table *rate;
@@ -769,14 +773,14 @@ static void rockchip_rk3399_pll_init(struct clk_hw *hw)
        unsigned long drate;
 
        if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
-               return;
+               return 0;
 
        drate = clk_hw_get_rate(hw);
        rate = rockchip_get_pll_settings(pll, drate);
 
        /* when no rate setting for the current rate, rely on clk_set_rate */
        if (!rate)
-               return;
+               return 0;
 
        rockchip_rk3399_pll_get_params(pll, &cur);
 
@@ -798,13 +802,15 @@ static void rockchip_rk3399_pll_init(struct clk_hw *hw)
                if (!parent) {
                        pr_warn("%s: parent of %s not available\n",
                                __func__, __clk_get_name(hw->clk));
-                       return;
+                       return 0;
                }
 
                pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
                         __func__, __clk_get_name(hw->clk));
                rockchip_rk3399_pll_set_params(pll, rate);
        }
+
+       return 0;
 }
 
 static const struct clk_ops rockchip_rk3399_pll_clk_norate_ops = {
index 3a991ca..c9e5a1f 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/clk.h>
 
 #include "clk.h"
 #include "clk-cpu.h"
@@ -1646,6 +1647,13 @@ static void __init exynos5x_clk_init(struct device_node *np,
                                     exynos5x_subcmus);
        }
 
+       /*
+        * Keep top part of G3D clock path enabled permanently to ensure
+        * that the internal busses get their clock regardless of the
+        * main G3D clock enablement status.
+        */
+       clk_prepare_enable(__clk_lookup("mout_sw_aclk_g3d"));
+
        samsung_clk_of_add_provider(np, ctx);
 }
 
index e6bd6d1..f6cdce4 100644 (file)
@@ -231,8 +231,10 @@ struct clk ** __init tegra_clk_init(void __iomem *regs, int num, int banks)
        periph_banks = banks;
 
        clks = kcalloc(num, sizeof(struct clk *), GFP_KERNEL);
-       if (!clks)
+       if (!clks) {
                kfree(periph_clk_enb_refcnt);
+               return NULL;
+       }
 
        clk_num = num;
 
index e6995c0..f1dd62d 100644 (file)
@@ -253,7 +253,7 @@ extern const struct clk_ops omap_gate_clk_ops;
 
 extern struct ti_clk_features ti_clk_features;
 
-void omap2_init_clk_clkdm(struct clk_hw *hw);
+int omap2_init_clk_clkdm(struct clk_hw *hw);
 int omap2_clkops_enable_clkdm(struct clk_hw *hw);
 void omap2_clkops_disable_clkdm(struct clk_hw *hw);
 
index 423a99b..ee56306 100644 (file)
@@ -101,16 +101,16 @@ void omap2_clkops_disable_clkdm(struct clk_hw *hw)
  *
  * Convert a clockdomain name stored in a struct clk 'clk' into a
  * clockdomain pointer, and save it into the struct clk.  Intended to be
- * called during clk_register().  No return value.
+ * called during clk_register(). Returns 0 on success, -EERROR otherwise.
  */
-void omap2_init_clk_clkdm(struct clk_hw *hw)
+int omap2_init_clk_clkdm(struct clk_hw *hw)
 {
        struct clk_hw_omap *clk = to_clk_hw_omap(hw);
        struct clockdomain *clkdm;
        const char *clk_name;
 
        if (!clk->clkdm_name)
-               return;
+               return 0;
 
        clk_name = __clk_get_name(hw->clk);
 
@@ -123,6 +123,8 @@ void omap2_init_clk_clkdm(struct clk_hw *hw)
                pr_debug("clock: could not associate clk %s to clkdm %s\n",
                         clk_name, clk->clkdm_name);
        }
+
+       return 0;
 }
 
 static void __init of_ti_clockdomain_setup(struct device_node *node)
index 72ed97c..0aedd42 100644 (file)
@@ -99,8 +99,10 @@ static void u8500_clk_init(struct device_node *np)
        if (fw_version != NULL) {
                switch (fw_version->project) {
                case PRCMU_FW_PROJECT_U8500_C2:
+               case PRCMU_FW_PROJECT_U8500_MBL:
                case PRCMU_FW_PROJECT_U8520:
                case PRCMU_FW_PROJECT_U8420:
+               case PRCMU_FW_PROJECT_U8420_SYSCLK:
                        sgaclk_parent = "soc0_pll";
                        break;
                default:
index ac76685..c2618f1 100644 (file)
@@ -9,7 +9,7 @@ config COMMON_CLK_VERSATILE
                COMPILE_TEST
        select REGMAP_MMIO
        ---help---
-          Supports clocking on ARM Reference designs:
+         Supports clocking on ARM Reference designs:
          - Integrator/AP and Integrator/CP
          - RealView PB1176, EB, PB11MP and PBX
          - Versatile Express
index 7a9ad54..bf86c9c 100644 (file)
@@ -123,7 +123,7 @@ static int g12a_ephy_pll_is_enabled(struct clk_hw *hw)
        return (val & PLL_CTL0_LOCK_DIG) ? 1 : 0;
 }
 
-static void g12a_ephy_pll_init(struct clk_hw *hw)
+static int g12a_ephy_pll_init(struct clk_hw *hw)
 {
        struct g12a_ephy_pll *pll = g12a_ephy_pll_to_dev(hw);
 
@@ -136,6 +136,8 @@ static void g12a_ephy_pll_init(struct clk_hw *hw)
        writel(0x20200000, pll->base + ETH_PLL_CTL5);
        writel(0x0000c002, pll->base + ETH_PLL_CTL6);
        writel(0x00000023, pll->base + ETH_PLL_CTL7);
+
+       return 0;
 }
 
 static const struct clk_ops g12a_ephy_pll_ops = {
index caf4b9d..013dc66 100644 (file)
@@ -190,8 +190,14 @@ struct clk_duty {
  *
  * @init:      Perform platform-specific initialization magic.
  *             This is not not used by any of the basic clock types.
- *             Please consider other ways of solving initialization problems
- *             before using this callback, as its use is discouraged.
+ *             This callback exist for HW which needs to perform some
+ *             initialisation magic for CCF to get an accurate view of the
+ *             clock. It may also be used dynamic resource allocation is
+ *             required. It shall not used to deal with clock parameters,
+ *             such as rate or parents.
+ *             Returns 0 on success, -EERROR otherwise.
+ *
+ * @terminate:  Free any resource allocated by init.
  *
  * @debug_init:        Set up type-specific debugfs entries for this clock.  This
  *             is called once, after the debugfs directory entry for this
@@ -243,7 +249,8 @@ struct clk_ops {
                                          struct clk_duty *duty);
        int             (*set_duty_cycle)(struct clk_hw *hw,
                                          struct clk_duty *duty);
-       void            (*init)(struct clk_hw *hw);
+       int             (*init)(struct clk_hw *hw);
+       void            (*terminate)(struct clk_hw *hw);
        void            (*debug_init)(struct clk_hw *hw, struct dentry *dentry);
 };