]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge branches 'clk-debugfs-danger', 'clk-basic-hw', 'clk-renesas', 'clk-amlogic...
authorStephen Boyd <sboyd@kernel.org>
Fri, 31 Jan 2020 21:12:14 +0000 (13:12 -0800)
committerStephen Boyd <sboyd@kernel.org>
Fri, 31 Jan 2020 21:12:14 +0000 (13:12 -0800)
 - Support dangerous debugfs actions on clks with dead code
 - Convert gpio, fixed-factor, mux, gate, divider basic clks to hw based APIs

* clk-debugfs-danger:
  clk: Add support for setting clk_rate via debugfs

* clk-basic-hw:
  clk: divider: Add support for specifying parents via DT/pointers
  clk: gate: Add support for specifying parents via DT/pointers
  clk: mux: Add support for specifying parents via DT/pointers
  clk: asm9260: Use parent accuracy in fixed rate clk
  clk: fixed-rate: Document that accuracy isn't a rate
  clk: fixed-rate: Add clk flags for parent accuracy
  clk: fixed-rate: Add support for specifying parents via DT/pointers
  clk: fixed-rate: Document accuracy member
  clk: fixed-rate: Move to_clk_fixed_rate() to C file
  clk: fixed-rate: Remove clk_register_fixed_rate_with_accuracy()
  clk: fixed-rate: Convert to clk_hw based APIs
  clk: gpio: Use DT way of specifying parents

* clk-renesas:
  clk: renesas: Prepare for split of R-Car H3 config symbol
  dt-bindings: clock: renesas: cpg-mssr: Fix r8a774b1 typo
  clk: renesas: r7s9210: Add SPIBSC clock
  clk: renesas: rcar-gen3: Allow changing the RPC[D2] clocks
  clk: renesas: Remove use of ARCH_R8A7796
  clk: renesas: rcar-gen2: Change multipliers and dividers to u8

* clk-amlogic:
  clk: clarify that clk_set_rate() does updates from top to bottom
  clk: meson: meson8b: make the CCF use the glitch-free mali mux
  clk: meson: pll: Fix by 0 division in __pll_params_to_rate()
  clk: meson: g12a: fix missing uart2 in regmap table
  clk: meson: meson8b: use of_clk_hw_register to register the clocks
  clk: meson: meson8b: don't register the XTAL clock when provided via OF
  clk: meson: meson8b: change references to the XTAL clock to use [fw_]name
  clk: meson: meson8b: use clk_hw_set_parent in the CPU clock notifier
  clk: meson: add a driver for the Meson8/8b/8m2 DDR clock controller
  dt-bindings: clock: meson8b: add the clock inputs
  dt-bindings: clock: add the Amlogic Meson8 DDR clock controller binding

* clk-allwinner:
  clk: sunxi: a23/a33: Export the MIPI PLL
  clk: sunxi: a31: Export the MIPI PLL
  clk: sunxi-ng: a64: export CLK_CPUX clock for DVFS
  clk: sunxi-ng: add mux and pll notifiers for A64 CPU clock
  clk: sunxi-ng: r40: Export MBUS clock
  clk: sunxi: use of_device_get_match_data

60 files changed:
Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt
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-asm9260.c
drivers/clk/clk-bm1880.c
drivers/clk/clk-divider.c
drivers/clk/clk-fixed-rate.c
drivers/clk/clk-gate.c
drivers/clk/clk-gpio.c
drivers/clk/clk-mux.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/renesas/Kconfig
drivers/clk/renesas/r7s9210-cpg-mssr.c
drivers/clk/renesas/rcar-gen2-cpg.h
drivers/clk/renesas/rcar-gen3-cpg.c
drivers/clk/rockchip/clk-pll.c
drivers/clk/samsung/clk-exynos5420.c
drivers/clk/sunxi-ng/ccu-sun50i-a64.c
drivers/clk/sunxi-ng/ccu-sun50i-a64.h
drivers/clk/sunxi-ng/ccu-sun6i-a31.h
drivers/clk/sunxi-ng/ccu-sun8i-a23-a33.h
drivers/clk/sunxi-ng/ccu-sun8i-r40.h
drivers/clk/sunxi/clk-sun6i-apb0-gates.c
drivers/clk/tegra/clk.c
drivers/clk/ti/clock.h
drivers/clk/ti/clockdomain.c
drivers/clk/uniphier/clk-uniphier-peri.c
drivers/clk/ux500/u8500_of_clk.c
drivers/clk/versatile/Kconfig
drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c
drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c
drivers/net/phy/mdio-mux-meson-g12a.c
include/dt-bindings/clock/sun50i-a64-ccu.h
include/dt-bindings/clock/sun6i-a31-ccu.h
include/dt-bindings/clock/sun8i-a23-a33-ccu.h
include/dt-bindings/clock/sun8i-r40-ccu.h
include/linux/clk-provider.h

index c7674d0267a36fbd25f356482ea7b74e8f5fa27a..f4d153f24a0ff80369cd6768b22c7b3ea48d5d72 100644 (file)
@@ -19,7 +19,7 @@ Required Properties:
       - "renesas,r8a7745-cpg-mssr" for the r8a7745 SoC (RZ/G1E)
       - "renesas,r8a77470-cpg-mssr" for the r8a77470 SoC (RZ/G1C)
       - "renesas,r8a774a1-cpg-mssr" for the r8a774a1 SoC (RZ/G2M)
-      - "renesas,r8a774b1-cpg-mssr" for the r8a774a1 SoC (RZ/G2N)
+      - "renesas,r8a774b1-cpg-mssr" for the r8a774b1 SoC (RZ/G2N)
       - "renesas,r8a774c0-cpg-mssr" for the r8a774c0 SoC (RZ/G2E)
       - "renesas,r8a7790-cpg-mssr" for the r8a7790 SoC (R-Car H2)
       - "renesas,r8a7791-cpg-mssr" for the r8a7791 SoC (R-Car M2-W)
index 45653a0e6ecda1ebe53ecd174bc45ed1d8097394..a48e326f4ef738bf48ace433a76da2331f52e14b 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 0aabe49aed09449b153de865adc739dc8e22eacf..a9d4234758d7d42258a6686866bb20ba7aa0f847 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 0ac34cdaa106932fb797c534dae04273d26b8aad..77fe83a73bf480815e3aca23678231fee960235d 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 0855f3a80cc79ea8ea6933192964e02c0a2ef079..086cf0b4955c2ec5591e740785abe658452853fb 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 34b817825b22f62af23a1204f64b7b27171c1af3..dfb354a5ff1866e8da2eb5161df13c0919fab786 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 0b03cfae3a9ddcae4c7906edc77c82ac40d30c6c..b71515acdec1f0eaebdf865fb184cdbed40d27b8 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 86238d5ecb4da948add6b2b3b203cda5cdd7bc21..77398aefeb6db45396f23db2ecdf16c13c6f0769 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 0de1108737db9326de1507dc8bb7b6e48b5df1c9..ff7e3f727082e261a5990d332b16bcec6750ee3d 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 25b156d4e645f6daf4edea37f16cede5ac3ce4b9..a6dee4a3b6e48eade40a187be4b195cf0c7b17fe 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 dd0f90c9dd0e3b35558d1cf10aa0dc7d77a6912f..536b59aabd2cba18dab1656e66590628b08b1f6e 100644 (file)
@@ -260,7 +260,6 @@ static void __init asm9260_acc_init(struct device_node *np)
        const char *ref_clk, *pll_clk = "pll";
        u32 rate;
        int n;
-       u32 accuracy = 0;
 
        clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL);
        if (!clk_data)
@@ -275,10 +274,11 @@ static void __init asm9260_acc_init(struct device_node *np)
        /* register pll */
        rate = (ioread32(base + HW_SYSPLLCTRL) & 0xffff) * 1000000;
 
+       /* TODO: Convert to DT parent scheme */
        ref_clk = of_clk_get_parent_name(np, 0);
-       accuracy = clk_get_accuracy(__clk_lookup(ref_clk));
-       hw = clk_hw_register_fixed_rate_with_accuracy(NULL, pll_clk,
-                       ref_clk, 0, rate, accuracy);
+       hw = __clk_hw_register_fixed_rate_with_accuracy(NULL, NULL, pll_clk,
+                       ref_clk, NULL, NULL, 0, rate, 0,
+                       CLK_FIXED_RATE_PARENT_ACCURACY);
 
        if (IS_ERR(hw))
                panic("%pOFn: can't register REFCLK. Check DT!", np);
index 4cd175afce9b108e36e8f6febc1fc0057edda21b..e6d6599d310a1da8b2011151c81d13efb8d42cb7 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 098b2b01f0afc623658388c9f8c9c4417b0cb368..8de12cb0c43d895fc51608edb50a05ab52a5d5bf 100644 (file)
@@ -463,11 +463,12 @@ const struct clk_ops clk_divider_ro_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_divider_ro_ops);
 
-static struct clk_hw *_register_divider(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags,
-               void __iomem *reg, u8 shift, u8 width,
-               u8 clk_divider_flags, const struct clk_div_table *table,
-               spinlock_t *lock)
+struct clk_hw *__clk_hw_register_divider(struct device *dev,
+               struct device_node *np, const char *name,
+               const char *parent_name, const struct clk_hw *parent_hw,
+               const struct clk_parent_data *parent_data, unsigned long flags,
+               void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags,
+               const struct clk_div_table *table, spinlock_t *lock)
 {
        struct clk_divider *div;
        struct clk_hw *hw;
@@ -514,55 +515,7 @@ static struct clk_hw *_register_divider(struct device *dev, const char *name,
 
        return hw;
 }
-
-/**
- * clk_register_divider - register a divider clock with the clock framework
- * @dev: device registering this clock
- * @name: name of this clock
- * @parent_name: name of clock's parent
- * @flags: framework-specific flags
- * @reg: register address to adjust divider
- * @shift: number of bits to shift the bitfield
- * @width: width of the bitfield
- * @clk_divider_flags: divider-specific flags for this clock
- * @lock: shared register lock for this clock
- */
-struct clk *clk_register_divider(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags,
-               void __iomem *reg, u8 shift, u8 width,
-               u8 clk_divider_flags, spinlock_t *lock)
-{
-       struct clk_hw *hw;
-
-       hw =  _register_divider(dev, name, parent_name, flags, reg, shift,
-                       width, clk_divider_flags, NULL, lock);
-       if (IS_ERR(hw))
-               return ERR_CAST(hw);
-       return hw->clk;
-}
-EXPORT_SYMBOL_GPL(clk_register_divider);
-
-/**
- * clk_hw_register_divider - register a divider clock with the clock framework
- * @dev: device registering this clock
- * @name: name of this clock
- * @parent_name: name of clock's parent
- * @flags: framework-specific flags
- * @reg: register address to adjust divider
- * @shift: number of bits to shift the bitfield
- * @width: width of the bitfield
- * @clk_divider_flags: divider-specific flags for this clock
- * @lock: shared register lock for this clock
- */
-struct clk_hw *clk_hw_register_divider(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags,
-               void __iomem *reg, u8 shift, u8 width,
-               u8 clk_divider_flags, spinlock_t *lock)
-{
-       return _register_divider(dev, name, parent_name, flags, reg, shift,
-                       width, clk_divider_flags, NULL, lock);
-}
-EXPORT_SYMBOL_GPL(clk_hw_register_divider);
+EXPORT_SYMBOL_GPL(__clk_hw_register_divider);
 
 /**
  * clk_register_divider_table - register a table based divider clock with
@@ -586,39 +539,15 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,
 {
        struct clk_hw *hw;
 
-       hw =  _register_divider(dev, name, parent_name, flags, reg, shift,
-                       width, clk_divider_flags, table, lock);
+       hw =  __clk_hw_register_divider(dev, NULL, name, parent_name, NULL,
+                       NULL, flags, reg, shift, width, clk_divider_flags,
+                       table, lock);
        if (IS_ERR(hw))
                return ERR_CAST(hw);
        return hw->clk;
 }
 EXPORT_SYMBOL_GPL(clk_register_divider_table);
 
-/**
- * clk_hw_register_divider_table - register a table based divider clock with
- * the clock framework
- * @dev: device registering this clock
- * @name: name of this clock
- * @parent_name: name of clock's parent
- * @flags: framework-specific flags
- * @reg: register address to adjust divider
- * @shift: number of bits to shift the bitfield
- * @width: width of the bitfield
- * @clk_divider_flags: divider-specific flags for this clock
- * @table: array of divider/value pairs ending with a div set to 0
- * @lock: shared register lock for this clock
- */
-struct clk_hw *clk_hw_register_divider_table(struct device *dev,
-               const char *name, const char *parent_name, unsigned long flags,
-               void __iomem *reg, u8 shift, u8 width,
-               u8 clk_divider_flags, const struct clk_div_table *table,
-               spinlock_t *lock)
-{
-       return _register_divider(dev, name, parent_name, flags, reg, shift,
-                       width, clk_divider_flags, table, lock);
-}
-EXPORT_SYMBOL_GPL(clk_hw_register_divider_table);
-
 void clk_unregister_divider(struct clk *clk)
 {
        struct clk_divider *div;
index 2c4486c09040e192e35859b20a7c8471983c5bf2..77499a27c8fbfeb87e0393c9a135dca538c401bc 100644 (file)
@@ -24,6 +24,8 @@
  * parent - fixed parent.  No clk_set_parent support
  */
 
+#define to_clk_fixed_rate(_hw) container_of(_hw, struct clk_fixed_rate, hw)
+
 static unsigned long clk_fixed_rate_recalc_rate(struct clk_hw *hw,
                unsigned long parent_rate)
 {
@@ -33,7 +35,12 @@ static unsigned long clk_fixed_rate_recalc_rate(struct clk_hw *hw,
 static unsigned long clk_fixed_rate_recalc_accuracy(struct clk_hw *hw,
                unsigned long parent_accuracy)
 {
-       return to_clk_fixed_rate(hw)->fixed_accuracy;
+       struct clk_fixed_rate *fixed = to_clk_fixed_rate(hw);
+
+       if (fixed->flags & CLK_FIXED_RATE_PARENT_ACCURACY)
+               return parent_accuracy;
+
+       return fixed->fixed_accuracy;
 }
 
 const struct clk_ops clk_fixed_rate_ops = {
@@ -42,24 +49,17 @@ const struct clk_ops clk_fixed_rate_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_fixed_rate_ops);
 
-/**
- * clk_hw_register_fixed_rate_with_accuracy - register fixed-rate clock with
- * the clock framework
- * @dev: device that is registering this clock
- * @name: name of this clock
- * @parent_name: name of clock's parent
- * @flags: framework-specific flags
- * @fixed_rate: non-adjustable clock rate
- * @fixed_accuracy: non-adjustable clock rate
- */
-struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev,
-               const char *name, const char *parent_name, unsigned long flags,
-               unsigned long fixed_rate, unsigned long fixed_accuracy)
+struct clk_hw *__clk_hw_register_fixed_rate(struct device *dev,
+               struct device_node *np, const char *name,
+               const char *parent_name, const struct clk_hw *parent_hw,
+               const struct clk_parent_data *parent_data, unsigned long flags,
+               unsigned long fixed_rate, unsigned long fixed_accuracy,
+               unsigned long clk_fixed_flags)
 {
        struct clk_fixed_rate *fixed;
        struct clk_hw *hw;
        struct clk_init_data init = {};
-       int ret;
+       int ret = -EINVAL;
 
        /* allocate fixed-rate clock */
        fixed = kzalloc(sizeof(*fixed), GFP_KERNEL);
@@ -69,17 +69,26 @@ struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev,
        init.name = name;
        init.ops = &clk_fixed_rate_ops;
        init.flags = flags;
-       init.parent_names = (parent_name ? &parent_name: NULL);
-       init.num_parents = (parent_name ? 1 : 0);
+       init.parent_names = parent_name ? &parent_name : NULL;
+       init.parent_hws = parent_hw ? &parent_hw : NULL;
+       init.parent_data = parent_data;
+       if (parent_name || parent_hw || parent_data)
+               init.num_parents = 1;
+       else
+               init.num_parents = 0;
 
        /* struct clk_fixed_rate assignments */
+       fixed->flags = clk_fixed_flags;
        fixed->fixed_rate = fixed_rate;
        fixed->fixed_accuracy = fixed_accuracy;
        fixed->hw.init = &init;
 
        /* register the clock */
        hw = &fixed->hw;
-       ret = clk_hw_register(dev, hw);
+       if (dev || !np)
+               ret = clk_hw_register(dev, hw);
+       else if (np)
+               ret = of_clk_hw_register(np, hw);
        if (ret) {
                kfree(fixed);
                hw = ERR_PTR(ret);
@@ -87,47 +96,20 @@ struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev,
 
        return hw;
 }
-EXPORT_SYMBOL_GPL(clk_hw_register_fixed_rate_with_accuracy);
+EXPORT_SYMBOL_GPL(__clk_hw_register_fixed_rate);
 
-struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev,
-               const char *name, const char *parent_name, unsigned long flags,
-               unsigned long fixed_rate, unsigned long fixed_accuracy)
+struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags,
+               unsigned long fixed_rate)
 {
        struct clk_hw *hw;
 
        hw = clk_hw_register_fixed_rate_with_accuracy(dev, name, parent_name,
-                       flags, fixed_rate, fixed_accuracy);
+                                                     flags, fixed_rate, 0);
        if (IS_ERR(hw))
                return ERR_CAST(hw);
        return hw->clk;
 }
-EXPORT_SYMBOL_GPL(clk_register_fixed_rate_with_accuracy);
-
-/**
- * clk_hw_register_fixed_rate - register fixed-rate clock with the clock
- * framework
- * @dev: device that is registering this clock
- * @name: name of this clock
- * @parent_name: name of clock's parent
- * @flags: framework-specific flags
- * @fixed_rate: non-adjustable clock rate
- */
-struct clk_hw *clk_hw_register_fixed_rate(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags,
-               unsigned long fixed_rate)
-{
-       return clk_hw_register_fixed_rate_with_accuracy(dev, name, parent_name,
-                                                    flags, fixed_rate, 0);
-}
-EXPORT_SYMBOL_GPL(clk_hw_register_fixed_rate);
-
-struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags,
-               unsigned long fixed_rate)
-{
-       return clk_register_fixed_rate_with_accuracy(dev, name, parent_name,
-                                                    flags, fixed_rate, 0);
-}
 EXPORT_SYMBOL_GPL(clk_register_fixed_rate);
 
 void clk_unregister_fixed_rate(struct clk *clk)
@@ -155,9 +137,9 @@ void clk_hw_unregister_fixed_rate(struct clk_hw *hw)
 EXPORT_SYMBOL_GPL(clk_hw_unregister_fixed_rate);
 
 #ifdef CONFIG_OF
-static struct clk *_of_fixed_clk_setup(struct device_node *node)
+static struct clk_hw *_of_fixed_clk_setup(struct device_node *node)
 {
-       struct clk *clk;
+       struct clk_hw *hw;
        const char *clk_name = node->name;
        u32 rate;
        u32 accuracy = 0;
@@ -170,18 +152,18 @@ static struct clk *_of_fixed_clk_setup(struct device_node *node)
 
        of_property_read_string(node, "clock-output-names", &clk_name);
 
-       clk = clk_register_fixed_rate_with_accuracy(NULL, clk_name, NULL,
+       hw = clk_hw_register_fixed_rate_with_accuracy(NULL, clk_name, NULL,
                                                    0, rate, accuracy);
-       if (IS_ERR(clk))
-               return clk;
+       if (IS_ERR(hw))
+               return hw;
 
-       ret = of_clk_add_provider(node, of_clk_src_simple_get, clk);
+       ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw);
        if (ret) {
-               clk_unregister(clk);
+               clk_hw_unregister_fixed_rate(hw);
                return ERR_PTR(ret);
        }
 
-       return clk;
+       return hw;
 }
 
 /**
@@ -195,27 +177,27 @@ CLK_OF_DECLARE(fixed_clk, "fixed-clock", of_fixed_clk_setup);
 
 static int of_fixed_clk_remove(struct platform_device *pdev)
 {
-       struct clk *clk = platform_get_drvdata(pdev);
+       struct clk_hw *hw = platform_get_drvdata(pdev);
 
        of_clk_del_provider(pdev->dev.of_node);
-       clk_unregister_fixed_rate(clk);
+       clk_hw_unregister_fixed_rate(hw);
 
        return 0;
 }
 
 static int of_fixed_clk_probe(struct platform_device *pdev)
 {
-       struct clk *clk;
+       struct clk_hw *hw;
 
        /*
         * This function is not executed when of_fixed_clk_setup
         * succeeded.
         */
-       clk = _of_fixed_clk_setup(pdev->dev.of_node);
-       if (IS_ERR(clk))
-               return PTR_ERR(clk);
+       hw = _of_fixed_clk_setup(pdev->dev.of_node);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
 
-       platform_set_drvdata(pdev, clk);
+       platform_set_drvdata(pdev, hw);
 
        return 0;
 }
@@ -224,7 +206,6 @@ static const struct of_device_id of_fixed_clk_ids[] = {
        { .compatible = "fixed-clock" },
        { }
 };
-MODULE_DEVICE_TABLE(of, of_fixed_clk_ids);
 
 static struct platform_driver of_fixed_clk_driver = {
        .driver = {
index 670053c58c1a16dfb065341c30e7ac3e71f5a3a3..2ca1f2ac38a6d66c7f950eaaad6d2c8786c1966e 100644 (file)
@@ -123,26 +123,18 @@ const struct clk_ops clk_gate_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_gate_ops);
 
-/**
- * clk_hw_register_gate - register a gate clock with the clock framework
- * @dev: device that is registering this clock
- * @name: name of this clock
- * @parent_name: name of this clock's parent
- * @flags: framework-specific flags for this clock
- * @reg: register address to control gating of this clock
- * @bit_idx: which bit in the register controls gating of this clock
- * @clk_gate_flags: gate-specific flags for this clock
- * @lock: shared register lock for this clock
- */
-struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags,
+struct clk_hw *__clk_hw_register_gate(struct device *dev,
+               struct device_node *np, const char *name,
+               const char *parent_name, const struct clk_hw *parent_hw,
+               const struct clk_parent_data *parent_data,
+               unsigned long flags,
                void __iomem *reg, u8 bit_idx,
                u8 clk_gate_flags, spinlock_t *lock)
 {
        struct clk_gate *gate;
        struct clk_hw *hw;
        struct clk_init_data init = {};
-       int ret;
+       int ret = -EINVAL;
 
        if (clk_gate_flags & CLK_GATE_HIWORD_MASK) {
                if (bit_idx > 15) {
@@ -160,7 +152,12 @@ struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name,
        init.ops = &clk_gate_ops;
        init.flags = flags;
        init.parent_names = parent_name ? &parent_name : NULL;
-       init.num_parents = parent_name ? 1 : 0;
+       init.parent_hws = parent_hw ? &parent_hw : NULL;
+       init.parent_data = parent_data;
+       if (parent_name || parent_hw || parent_data)
+               init.num_parents = 1;
+       else
+               init.num_parents = 0;
 
        /* struct clk_gate assignments */
        gate->reg = reg;
@@ -170,15 +167,19 @@ struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name,
        gate->hw.init = &init;
 
        hw = &gate->hw;
-       ret = clk_hw_register(dev, hw);
+       if (dev || !np)
+               ret = clk_hw_register(dev, hw);
+       else if (np)
+               ret = of_clk_hw_register(np, hw);
        if (ret) {
                kfree(gate);
                hw = ERR_PTR(ret);
        }
 
        return hw;
+
 }
-EXPORT_SYMBOL_GPL(clk_hw_register_gate);
+EXPORT_SYMBOL_GPL(__clk_hw_register_gate);
 
 struct clk *clk_register_gate(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
index 13304cf5f2a8faf0320d7343448d33f13baf25ea..70397b4b5ffea84b945b197a69d5a328590560b3 100644 (file)
  * parent - fixed parent.  No clk_set_parent support
  */
 
+/**
+ * struct clk_gpio - gpio gated clock
+ *
+ * @hw:                handle between common and hardware-specific interfaces
+ * @gpiod:     gpio descriptor
+ *
+ * Clock with a gpio control for enabling and disabling the parent clock
+ * or switching between two parents by asserting or deasserting the gpio.
+ *
+ * Implements .enable, .disable and .is_enabled or
+ * .get_parent, .set_parent and .determine_rate depending on which clk_ops
+ * is used.
+ */
+struct clk_gpio {
+       struct clk_hw   hw;
+       struct gpio_desc *gpiod;
+};
+
+#define to_clk_gpio(_hw) container_of(_hw, struct clk_gpio, hw)
+
 static int clk_gpio_gate_enable(struct clk_hw *hw)
 {
        struct clk_gpio *clk = to_clk_gpio(hw);
@@ -51,12 +71,11 @@ static int clk_gpio_gate_is_enabled(struct clk_hw *hw)
        return gpiod_get_value(clk->gpiod);
 }
 
-const struct clk_ops clk_gpio_gate_ops = {
+static const struct clk_ops clk_gpio_gate_ops = {
        .enable = clk_gpio_gate_enable,
        .disable = clk_gpio_gate_disable,
        .is_enabled = clk_gpio_gate_is_enabled,
 };
-EXPORT_SYMBOL_GPL(clk_gpio_gate_ops);
 
 static int clk_sleeping_gpio_gate_prepare(struct clk_hw *hw)
 {
@@ -111,67 +130,49 @@ static int clk_gpio_mux_set_parent(struct clk_hw *hw, u8 index)
        return 0;
 }
 
-const struct clk_ops clk_gpio_mux_ops = {
+static const struct clk_ops clk_gpio_mux_ops = {
        .get_parent = clk_gpio_mux_get_parent,
        .set_parent = clk_gpio_mux_set_parent,
        .determine_rate = __clk_mux_determine_rate,
 };
-EXPORT_SYMBOL_GPL(clk_gpio_mux_ops);
 
-static struct clk_hw *clk_register_gpio(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod,
-               unsigned long flags, const struct clk_ops *clk_gpio_ops)
+static struct clk_hw *clk_register_gpio(struct device *dev, u8 num_parents,
+                                       struct gpio_desc *gpiod,
+                                       const struct clk_ops *clk_gpio_ops)
 {
        struct clk_gpio *clk_gpio;
        struct clk_hw *hw;
        struct clk_init_data init = {};
        int err;
+       const struct clk_parent_data gpio_parent_data[] = {
+               { .index = 0 },
+               { .index = 1 },
+       };
 
-       if (dev)
-               clk_gpio = devm_kzalloc(dev, sizeof(*clk_gpio), GFP_KERNEL);
-       else
-               clk_gpio = kzalloc(sizeof(*clk_gpio), GFP_KERNEL);
-
+       clk_gpio = devm_kzalloc(dev, sizeof(*clk_gpio), GFP_KERNEL);
        if (!clk_gpio)
                return ERR_PTR(-ENOMEM);
 
-       init.name = name;
+       init.name = dev->of_node->name;
        init.ops = clk_gpio_ops;
-       init.flags = flags;
-       init.parent_names = parent_names;
+       init.parent_data = gpio_parent_data;
        init.num_parents = num_parents;
+       init.flags = CLK_SET_RATE_PARENT;
 
        clk_gpio->gpiod = gpiod;
        clk_gpio->hw.init = &init;
 
        hw = &clk_gpio->hw;
-       if (dev)
-               err = devm_clk_hw_register(dev, hw);
-       else
-               err = clk_hw_register(NULL, hw);
-
-       if (!err)
-               return hw;
-
-       if (!dev) {
-               kfree(clk_gpio);
-       }
+       err = devm_clk_hw_register(dev, hw);
+       if (err)
+               return ERR_PTR(err);
 
-       return ERR_PTR(err);
+       return hw;
 }
 
-/**
- * clk_hw_register_gpio_gate - register a gpio clock gate with the clock
- * framework
- * @dev: device that is registering this clock
- * @name: name of this clock
- * @parent_name: name of this clock's parent
- * @gpiod: gpio descriptor to gate this clock
- * @flags: clock flags
- */
-struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name,
-               const char *parent_name, struct gpio_desc *gpiod,
-               unsigned long flags)
+static struct clk_hw *clk_hw_register_gpio_gate(struct device *dev,
+                                               int num_parents,
+                                               struct gpio_desc *gpiod)
 {
        const struct clk_ops *ops;
 
@@ -180,88 +181,36 @@ struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name,
        else
                ops = &clk_gpio_gate_ops;
 
-       return clk_register_gpio(dev, name,
-                       (parent_name ? &parent_name : NULL),
-                       (parent_name ? 1 : 0), gpiod, flags, ops);
+       return clk_register_gpio(dev, num_parents, gpiod, ops);
 }
-EXPORT_SYMBOL_GPL(clk_hw_register_gpio_gate);
 
-struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
-               const char *parent_name, struct gpio_desc *gpiod,
-               unsigned long flags)
+static struct clk_hw *clk_hw_register_gpio_mux(struct device *dev,
+                                              struct gpio_desc *gpiod)
 {
-       struct clk_hw *hw;
-
-       hw = clk_hw_register_gpio_gate(dev, name, parent_name, gpiod, flags);
-       if (IS_ERR(hw))
-               return ERR_CAST(hw);
-       return hw->clk;
+       return clk_register_gpio(dev, 2, gpiod, &clk_gpio_mux_ops);
 }
-EXPORT_SYMBOL_GPL(clk_register_gpio_gate);
-
-/**
- * clk_hw_register_gpio_mux - register a gpio clock mux with the clock framework
- * @dev: device that is registering this clock
- * @name: name of this clock
- * @parent_names: names of this clock's parents
- * @num_parents: number of parents listed in @parent_names
- * @gpiod: gpio descriptor to gate this clock
- * @flags: clock flags
- */
-struct clk_hw *clk_hw_register_gpio_mux(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod,
-               unsigned long flags)
-{
-       if (num_parents != 2) {
-               pr_err("mux-clock %s must have 2 parents\n", name);
-               return ERR_PTR(-EINVAL);
-       }
-
-       return clk_register_gpio(dev, name, parent_names, num_parents,
-                       gpiod, flags, &clk_gpio_mux_ops);
-}
-EXPORT_SYMBOL_GPL(clk_hw_register_gpio_mux);
-
-struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod,
-               unsigned long flags)
-{
-       struct clk_hw *hw;
-
-       hw = clk_hw_register_gpio_mux(dev, name, parent_names, num_parents,
-                       gpiod, flags);
-       if (IS_ERR(hw))
-               return ERR_CAST(hw);
-       return hw->clk;
-}
-EXPORT_SYMBOL_GPL(clk_register_gpio_mux);
 
 static int gpio_clk_driver_probe(struct platform_device *pdev)
 {
-       struct device_node *node = pdev->dev.of_node;
-       const char **parent_names, *gpio_name;
+       struct device *dev = &pdev->dev;
+       struct device_node *node = dev->of_node;
+       const char *gpio_name;
        unsigned int num_parents;
        struct gpio_desc *gpiod;
-       struct clk *clk;
+       struct clk_hw *hw;
        bool is_mux;
        int ret;
 
+       is_mux = of_device_is_compatible(node, "gpio-mux-clock");
+
        num_parents = of_clk_get_parent_count(node);
-       if (num_parents) {
-               parent_names = devm_kcalloc(&pdev->dev, num_parents,
-                                           sizeof(char *), GFP_KERNEL);
-               if (!parent_names)
-                       return -ENOMEM;
-
-               of_clk_parent_fill(node, parent_names, num_parents);
-       } else {
-               parent_names = NULL;
+       if (is_mux && num_parents != 2) {
+               dev_err(dev, "mux-clock must have 2 parents\n");
+               return -EINVAL;
        }
 
-       is_mux = of_device_is_compatible(node, "gpio-mux-clock");
-
        gpio_name = is_mux ? "select" : "enable";
-       gpiod = devm_gpiod_get(&pdev->dev, gpio_name, GPIOD_OUT_LOW);
+       gpiod = devm_gpiod_get(dev, gpio_name, GPIOD_OUT_LOW);
        if (IS_ERR(gpiod)) {
                ret = PTR_ERR(gpiod);
                if (ret == -EPROBE_DEFER)
@@ -275,16 +224,13 @@ static int gpio_clk_driver_probe(struct platform_device *pdev)
        }
 
        if (is_mux)
-               clk = clk_register_gpio_mux(&pdev->dev, node->name,
-                               parent_names, num_parents, gpiod, 0);
+               hw = clk_hw_register_gpio_mux(dev, gpiod);
        else
-               clk = clk_register_gpio_gate(&pdev->dev, node->name,
-                               parent_names ?  parent_names[0] : NULL, gpiod,
-                               CLK_SET_RATE_PARENT);
-       if (IS_ERR(clk))
-               return PTR_ERR(clk);
+               hw = clk_hw_register_gpio_gate(dev, num_parents, gpiod);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
 
-       return of_clk_add_provider(node, of_clk_src_simple_get, clk);
+       return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw);
 }
 
 static const struct of_device_id gpio_clk_match_table[] = {
index 570b6e5b603bcadc7b5b52e2f5fce2f3a80ac578..e54e79714818f931b8b6a4456b57d4154f114530 100644 (file)
@@ -145,17 +145,19 @@ const struct clk_ops clk_mux_ro_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_mux_ro_ops);
 
-struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents,
-               unsigned long flags,
-               void __iomem *reg, u8 shift, u32 mask,
+struct clk_hw *__clk_hw_register_mux(struct device *dev, struct device_node *np,
+               const char *name, u8 num_parents,
+               const char * const *parent_names,
+               const struct clk_hw **parent_hws,
+               const struct clk_parent_data *parent_data,
+               unsigned long flags, void __iomem *reg, u8 shift, u32 mask,
                u8 clk_mux_flags, u32 *table, spinlock_t *lock)
 {
        struct clk_mux *mux;
        struct clk_hw *hw;
        struct clk_init_data init = {};
        u8 width = 0;
-       int ret;
+       int ret = -EINVAL;
 
        if (clk_mux_flags & CLK_MUX_HIWORD_MASK) {
                width = fls(mask) - ffs(mask) + 1;
@@ -177,6 +179,8 @@ struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
                init.ops = &clk_mux_ops;
        init.flags = flags;
        init.parent_names = parent_names;
+       init.parent_data = parent_data;
+       init.parent_hws = parent_hws;
        init.num_parents = num_parents;
 
        /* struct clk_mux assignments */
@@ -189,7 +193,10 @@ struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
        mux->hw.init = &init;
 
        hw = &mux->hw;
-       ret = clk_hw_register(dev, hw);
+       if (dev || !np)
+               ret = clk_hw_register(dev, hw);
+       else if (np)
+               ret = of_clk_hw_register(np, hw);
        if (ret) {
                kfree(mux);
                hw = ERR_PTR(ret);
@@ -197,53 +204,24 @@ struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
 
        return hw;
 }
-EXPORT_SYMBOL_GPL(clk_hw_register_mux_table);
+EXPORT_SYMBOL_GPL(__clk_hw_register_mux);
 
 struct clk *clk_register_mux_table(struct device *dev, const char *name,
                const char * const *parent_names, u8 num_parents,
-               unsigned long flags,
-               void __iomem *reg, u8 shift, u32 mask,
+               unsigned long flags, void __iomem *reg, u8 shift, u32 mask,
                u8 clk_mux_flags, u32 *table, spinlock_t *lock)
 {
        struct clk_hw *hw;
 
-       hw = clk_hw_register_mux_table(dev, name, parent_names, num_parents,
-                                      flags, reg, shift, mask, clk_mux_flags,
-                                      table, lock);
+       hw = clk_hw_register_mux_table(dev, name, parent_names,
+                                      num_parents, flags, reg, shift, mask,
+                                      clk_mux_flags, table, lock);
        if (IS_ERR(hw))
                return ERR_CAST(hw);
        return hw->clk;
 }
 EXPORT_SYMBOL_GPL(clk_register_mux_table);
 
-struct clk *clk_register_mux(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents,
-               unsigned long flags,
-               void __iomem *reg, u8 shift, u8 width,
-               u8 clk_mux_flags, spinlock_t *lock)
-{
-       u32 mask = BIT(width) - 1;
-
-       return clk_register_mux_table(dev, name, parent_names, num_parents,
-                                     flags, reg, shift, mask, clk_mux_flags,
-                                     NULL, lock);
-}
-EXPORT_SYMBOL_GPL(clk_register_mux);
-
-struct clk_hw *clk_hw_register_mux(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents,
-               unsigned long flags,
-               void __iomem *reg, u8 shift, u8 width,
-               u8 clk_mux_flags, spinlock_t *lock)
-{
-       u32 mask = BIT(width) - 1;
-
-       return clk_hw_register_mux_table(dev, name, parent_names, num_parents,
-                                     flags, reg, shift, mask, clk_mux_flags,
-                                     NULL, lock);
-}
-EXPORT_SYMBOL_GPL(clk_hw_register_mux);
-
 void clk_unregister_mux(struct clk *clk)
 {
        struct clk_mux *mux;
index b68e200829f202d78f49af69cd20c291f0d92022..d529ad67805c38c5a8184e99690111bb8a6a5ed1 100644 (file)
@@ -2996,6 +2996,41 @@ static int clk_dump_show(struct seq_file *s, void *data)
 }
 DEFINE_SHOW_ATTRIBUTE(clk_dump);
 
+#undef CLOCK_ALLOW_WRITE_DEBUGFS
+#ifdef CLOCK_ALLOW_WRITE_DEBUGFS
+/*
+ * This can be dangerous, therefore don't provide any real compile time
+ * configuration option for this feature.
+ * People who want to use this will need to modify the source code directly.
+ */
+static int clk_rate_set(void *data, u64 val)
+{
+       struct clk_core *core = data;
+       int ret;
+
+       clk_prepare_lock();
+       ret = clk_core_set_rate_nolock(core, val);
+       clk_prepare_unlock();
+
+       return ret;
+}
+
+#define clk_rate_mode  0644
+#else
+#define clk_rate_set   NULL
+#define clk_rate_mode  0444
+#endif
+
+static int clk_rate_get(void *data, u64 *val)
+{
+       struct clk_core *core = data;
+
+       *val = core->rate;
+       return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(clk_rate_fops, clk_rate_get, clk_rate_set, "%llu\n");
+
 static const struct {
        unsigned long flag;
        const char *name;
@@ -3145,7 +3180,8 @@ static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
        root = debugfs_create_dir(core->name, pdentry);
        core->dentry = root;
 
-       debugfs_create_ulong("clk_rate", 0444, root, &core->rate);
+       debugfs_create_file("clk_rate", clk_rate_mode, root, core,
+                           &clk_rate_fops);
        debugfs_create_file("clk_min_rate", 0444, root, core, &clk_min_rate_fops);
        debugfs_create_file("clk_max_rate", 0444, root, core, &clk_max_rate_fops);
        debugfs_create_ulong("clk_accuracy", 0444, root, &core->accuracy);
@@ -3249,6 +3285,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 +3323,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 +3374,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);
 
        /*
@@ -3336,17 +3418,6 @@ static int __clk_core_init(struct clk_core *core)
                core->orphan = true;
        }
 
-       /*
-        * 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
@@ -3400,34 +3471,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:
@@ -3719,6 +3782,28 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
        return ERR_PTR(ret);
 }
 
+/**
+ * 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
@@ -3734,7 +3819,7 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
  */
 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 +3835,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 +3939,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 +3948,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 +3962,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 +4270,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 +4372,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 +4409,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 388bdb94f841da0a153cb024346832d282e853b8..d3486ee79ab54ebf186e94deb7b37d759a553f76 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 3fdf3d494f0afc305c0212fb57914f1abbbf498c..281191b55b3af5b59a43384bb2d1949d7393e98d 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 5c458199060a6e9557bb36b02fb488bb0b76a1bc..3636c8035c7d95e12012a2e9ff0bb40dc659c50b 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 7efc3617bbd55396aa342e3d5f3203f20b1663a7..ea3c70d1307ecfe39f644ca3ab05d7b3dfbc37ab 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 2d39a8bc367c37c1d17867cebefbda181ae58694..fc9df486087218bd3bd94e1049b5c6fbdf3b196f 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 80c3ada193a43f8d6598a6f2b5d03116810c1a3c..fe22e171121a7f0f50b454f0f556e723eb4f1ae6 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 3a5853ca98c6c008eeaedaf88652310dc08b65c4..b17a13e9337c40eb0fe677d6b283f91178ce01f9 100644 (file)
@@ -286,7 +286,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);
@@ -297,6 +297,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 3acf037802215cd7972543991853fe2ce279f381..76d31c0a33426651a84983e4e14c553ded609a79 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 567755d6f8446a4c036ab4913fb183f67ac7746f..1b4f023cdc8be44c4a57f0d2924c280b5c70d674 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 90bf181f191afaa386b31ae63bf3cfeade8db741..fabc09aca6c4649f3bffdaac250434bf862af59c 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 90814b2613c0c2c4e01a1b39b186ee06d1efbcc1..d2cd36c54474f635f7273ec43f7ccd60a66fbf65 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 415e6906a113f949089d133bf391029113dffcf8..ded07b0bd0d5e6ea2615d8728687295577e44faa 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 3b33ef129274aa26ef08ff86d63dd050f678ae03..f37f3cd615f2ed6c9b272bfd4e649a653804958e 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 3c04805f2a55af0d9889e5e5546b95b5fcd0fbfa..e847d586a73aef9ee29b1c50a12a42f0e818b987 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 38424e63bcae2e5f03494e58ba0d24f4d17b8765..7f59fb8da0337c64bb04cabd00c2de8efe2c05b1 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 e5e2492b20c5e840cb999142c70bb4360edc2035..9b3923af02a142dcf7c821114adee5522a3c542f 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 4cd846bc98cc2ec039916a0c10b7f9d8d6eae38c..250d8165167aa013da6c95a090e3e653bd931de7 100644 (file)
@@ -20,8 +20,8 @@ config CLK_RENESAS
        select CLK_R8A7791 if ARCH_R8A7791 || ARCH_R8A7793
        select CLK_R8A7792 if ARCH_R8A7792
        select CLK_R8A7794 if ARCH_R8A7794
-       select CLK_R8A7795 if ARCH_R8A7795
-       select CLK_R8A77960 if ARCH_R8A77960 || ARCH_R8A7796
+       select CLK_R8A7795 if ARCH_R8A77950 || ARCH_R8A77951 || ARCH_R8A7795
+       select CLK_R8A77960 if ARCH_R8A77960
        select CLK_R8A77961 if ARCH_R8A77961
        select CLK_R8A77965 if ARCH_R8A77965
        select CLK_R8A77970 if ARCH_R8A77970
index cf65d4e0e116664760ba415205126bc58b2ec4c0..443bff08df4c807227616511bd114a8d1364e5bb 100644 (file)
@@ -93,6 +93,7 @@ static const struct mssr_mod_clk r7s9210_mod_clks[] __initconst = {
        DEF_MOD_STB("ether1",    64,    R7S9210_CLK_B),
        DEF_MOD_STB("ether0",    65,    R7S9210_CLK_B),
 
+       DEF_MOD_STB("spibsc",    83,    R7S9210_CLK_P1),
        DEF_MOD_STB("i2c3",      84,    R7S9210_CLK_P1),
        DEF_MOD_STB("i2c2",      85,    R7S9210_CLK_P1),
        DEF_MOD_STB("i2c1",      86,    R7S9210_CLK_P1),
index db2f57ef2f9984e4a5ff55a6a42906890f285361..bdcd4a38d48d01bd4a344448746c80eb05d92268 100644 (file)
@@ -24,10 +24,10 @@ enum rcar_gen2_clk_types {
 };
 
 struct rcar_gen2_cpg_pll_config {
-       unsigned int extal_div;
-       unsigned int pll1_mult;
-       unsigned int pll3_mult;
-       unsigned int pll0_mult;         /* leave as zero if PLL0CR exists */
+       u8 extal_div;
+       u8 pll1_mult;
+       u8 pll3_mult;
+       u8 pll0_mult;           /* leave as zero if PLL0CR exists */
 };
 
 struct clk *rcar_gen2_cpg_clk_register(struct device *dev,
index c97b647db9b68f181dbb83362edbe910ffa48adb..488f8b3980c55072009b1f4642efc6e31186b560 100644 (file)
@@ -470,7 +470,8 @@ static struct clk * __init cpg_rpc_clk_register(const char *name,
 
        clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL,
                                     &rpc->div.hw,  &clk_divider_ops,
-                                    &rpc->gate.hw, &clk_gate_ops, 0);
+                                    &rpc->gate.hw, &clk_gate_ops,
+                                    CLK_SET_RATE_PARENT);
        if (IS_ERR(clk)) {
                kfree(rpc);
                return clk;
@@ -506,7 +507,8 @@ static struct clk * __init cpg_rpcd2_clk_register(const char *name,
 
        clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL,
                                     &rpcd2->fixed.hw, &clk_fixed_factor_ops,
-                                    &rpcd2->gate.hw, &clk_gate_ops, 0);
+                                    &rpcd2->gate.hw, &clk_gate_ops,
+                                    CLK_SET_RATE_PARENT);
        if (IS_ERR(clk))
                kfree(rpcd2);
 
index 198417d5630062eeaa220f1f8ed3df3eb17c29a1..10560d963baf6217a4d403d48f44abd6f844e427 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 3a991ca1ee3605af87831a603914db9ee3fe5deb..c9e5a1fb66539eed0f078d01849aa947752c2d5b 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 49bd7a4c015c46d4763d941f8d75ea3bec178ee9..5f66bf879772391f20406ff126bda3ebd615c0ba 100644 (file)
@@ -921,11 +921,26 @@ static const struct sunxi_ccu_desc sun50i_a64_ccu_desc = {
        .num_resets     = ARRAY_SIZE(sun50i_a64_ccu_resets),
 };
 
+static struct ccu_pll_nb sun50i_a64_pll_cpu_nb = {
+       .common = &pll_cpux_clk.common,
+       /* copy from pll_cpux_clk */
+       .enable = BIT(31),
+       .lock   = BIT(28),
+};
+
+static struct ccu_mux_nb sun50i_a64_cpu_nb = {
+       .common         = &cpux_clk.common,
+       .cm             = &cpux_clk.mux,
+       .delay_us       = 1, /* > 8 clock cycles at 24 MHz */
+       .bypass_index   = 1, /* index of 24 MHz oscillator */
+};
+
 static int sun50i_a64_ccu_probe(struct platform_device *pdev)
 {
        struct resource *res;
        void __iomem *reg;
        u32 val;
+       int ret;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        reg = devm_ioremap_resource(&pdev->dev, res);
@@ -939,7 +954,18 @@ static int sun50i_a64_ccu_probe(struct platform_device *pdev)
 
        writel(0x515, reg + SUN50I_A64_PLL_MIPI_REG);
 
-       return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a64_ccu_desc);
+       ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a64_ccu_desc);
+       if (ret)
+               return ret;
+
+       /* Gate then ungate PLL CPU after any rate changes */
+       ccu_pll_notifier_register(&sun50i_a64_pll_cpu_nb);
+
+       /* Reparent CPU during PLL CPU rate changes */
+       ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
+                                 &sun50i_a64_cpu_nb);
+
+       return 0;
 }
 
 static const struct of_device_id sun50i_a64_ccu_ids[] = {
index 9799292767092090f385bcb07dabfbb056ca15f0..116e6f826d0423680c940405b0630cc96d16b732 100644 (file)
@@ -36,7 +36,6 @@
 #define CLK_PLL_HSIC                   18
 #define CLK_PLL_DE                     19
 #define CLK_PLL_DDR1                   20
-#define CLK_CPUX                       21
 #define CLK_AXI                                22
 #define CLK_APB                                23
 #define CLK_AHB1                       24
index a361388b4670778244b93b44602386ced1b7e9af..3ed2a59b0dc6ef53825d80044ac5c2ec51576512 100644 (file)
@@ -32,7 +32,9 @@
 /* The PLL_VIDEO1_2X clock is exported */
 
 #define CLK_PLL_GPU            14
-#define CLK_PLL_MIPI           15
+
+/* The PLL_VIDEO1_2X clock is exported */
+
 #define CLK_PLL9               16
 #define CLK_PLL10              17
 
index 72df69291cc6bb050df5009a1c9d65072ec58ce5..5bf5c4d13b4cdfea29c17ed1d0c913a408e2fc59 100644 (file)
@@ -24,7 +24,9 @@
 #define CLK_PLL_PERIPH         10
 #define CLK_PLL_PERIPH_2X      11
 #define CLK_PLL_GPU            12
-#define CLK_PLL_MIPI           13
+
+/* The PLL MIPI clock is exported */
+
 #define CLK_PLL_HSIC           14
 #define CLK_PLL_DE             15
 #define CLK_PLL_DDR1           16
index a69637b6b0c1fa047855ed57044777748ffed380..6f7071df8e1cd95ef7716b14871ac1d0dd881831 100644 (file)
 
 /* Some more module clocks are exported */
 
-#define CLK_MBUS               155
-
-/* Another bunch of module clocks are exported */
-
 #define CLK_NUMBER             (CLK_OUTB + 1)
 
 #endif /* _CCU_SUN8I_R40_H_ */
index a165e7172346a0c8afb4da1df4467760a2a2543d..4c75b0770c74bfbbc4262fb6fded369c42b783d7 100644 (file)
@@ -37,7 +37,6 @@ static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
        struct clk_onecell_data *clk_data;
-       const struct of_device_id *device;
        const struct gates_data *data;
        const char *clk_parent;
        const char *clk_name;
@@ -50,10 +49,9 @@ static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev)
        if (!np)
                return -ENODEV;
 
-       device = of_match_device(sun6i_a31_apb0_gates_clk_dt_ids, &pdev->dev);
-       if (!device)
+       data = of_device_get_match_data(&pdev->dev);
+       if (!data)
                return -ENODEV;
-       data = device->data;
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        reg = devm_ioremap_resource(&pdev->dev, r);
index e6bd6d1ea0128525f76fb4b07f12e7a31054f133..f6cdce441cf7ac4e45eb9bb26576187c47d546e1 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 e6995c04001ece8955cf8414968bc3e31b391d9d..f1dd62de2bfcb64e7367b6c8252cee43cbdb81c8 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 423a99b9f10c762cc0cc275a2cf935bc81e6ef4c..ee56306f79d5fad7e0563d5ebec9c400c1e35a5e 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 9caa52944b1c5743c0afea5e3756bcac07892a75..3e32db9dad8151a39d2fbefa40f7268557b6ed70 100644 (file)
@@ -18,8 +18,8 @@
 #define UNIPHIER_PERI_CLK_FI2C(idx, ch)                                        \
        UNIPHIER_CLK_GATE("i2c" #ch, (idx), "i2c", 0x24, 24 + (ch))
 
-#define UNIPHIER_PERI_CLK_SCSSI(idx)                                   \
-       UNIPHIER_CLK_GATE("scssi", (idx), "spi", 0x20, 17)
+#define UNIPHIER_PERI_CLK_SCSSI(idx, ch)                               \
+       UNIPHIER_CLK_GATE("scssi" #ch, (idx), "spi", 0x20, 17 + (ch))
 
 #define UNIPHIER_PERI_CLK_MCSSI(idx)                                   \
        UNIPHIER_CLK_GATE("mcssi", (idx), "spi", 0x24, 14)
@@ -35,7 +35,7 @@ const struct uniphier_clk_data uniphier_ld4_peri_clk_data[] = {
        UNIPHIER_PERI_CLK_I2C(6, 2),
        UNIPHIER_PERI_CLK_I2C(7, 3),
        UNIPHIER_PERI_CLK_I2C(8, 4),
-       UNIPHIER_PERI_CLK_SCSSI(11),
+       UNIPHIER_PERI_CLK_SCSSI(11, 0),
        { /* sentinel */ }
 };
 
@@ -51,7 +51,10 @@ const struct uniphier_clk_data uniphier_pro4_peri_clk_data[] = {
        UNIPHIER_PERI_CLK_FI2C(8, 4),
        UNIPHIER_PERI_CLK_FI2C(9, 5),
        UNIPHIER_PERI_CLK_FI2C(10, 6),
-       UNIPHIER_PERI_CLK_SCSSI(11),
-       UNIPHIER_PERI_CLK_MCSSI(12),
+       UNIPHIER_PERI_CLK_SCSSI(11, 0),
+       UNIPHIER_PERI_CLK_SCSSI(12, 1),
+       UNIPHIER_PERI_CLK_SCSSI(13, 2),
+       UNIPHIER_PERI_CLK_SCSSI(14, 3),
+       UNIPHIER_PERI_CLK_MCSSI(15),
        { /* sentinel */ }
 };
index 72ed97c6662ab3ba7528de7bc0429bbbb08e0547..0aedd42fad52447413f1db3fdd99571774164521 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 ac766855ba160b1929e049aee996bc5bd3c579a1..c2618f1477a2284d545f8e4ba1b2d731ba5baf29 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 8f6100db90ed498ef730bc852b8b6185c3fddbd4..1c894548dd725c8365bc4eae9b98446ea36739e1 100644 (file)
@@ -751,9 +751,9 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm)
        snprintf(parent4, 32, "dsi%d_pll_post_out_div_clk", pll_10nm->id);
 
        hw = clk_hw_register_mux(dev, clk_name,
-                                (const char *[]){
+                                ((const char *[]){
                                 parent, parent2, parent3, parent4
-                                }, 4, 0, pll_10nm->phy_cmn_mmio +
+                                }), 4, 0, pll_10nm->phy_cmn_mmio +
                                 REG_DSI_10nm_PHY_CMN_CLK_CFG1,
                                 0, 2, 0, NULL);
        if (IS_ERR(hw)) {
index 8c99e01ae332553c719f49eea273deacd43f1abc..6dffd7f4a99b847b578ae358bde10742b29297f6 100644 (file)
@@ -554,9 +554,9 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm)
        snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id);
        snprintf(parent2, 32, "dsi%dindirect_path_div2_clk", pll_28nm->id);
        clks[num++] = clk_register_mux(dev, clk_name,
-                       (const char *[]){
+                       ((const char *[]){
                                parent1, parent2
-                       }, 2, CLK_SET_RATE_PARENT, pll_28nm->mmio +
+                       }), 2, CLK_SET_RATE_PARENT, pll_28nm->mmio +
                        REG_DSI_28nm_PHY_PLL_VREG_CFG, 1, 1, 0, NULL);
 
        snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->id);
index 7a9ad54582e191517a04f82c3ae8a477471f771c..bf86c9c7a288366fe6ff5849764626cc0e6c5ea9 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 a8ac4cfcdcbc3e912bf2549d8b30da45b61bf86a..e512a1c9b0fc18cbf1f3adc9a5ace1043b3f1b7a 100644 (file)
@@ -46,6 +46,7 @@
 #define CLK_PLL_VIDEO0         7
 #define CLK_PLL_PERIPH0                11
 
+#define CLK_CPUX               21
 #define CLK_BUS_MIPI_DSI       28
 #define CLK_BUS_CE             29
 #define CLK_BUS_DMA            30
index c5d13340184aada0817376a662f7ae247648aeb5..39878d9dce9f7b64a8716856cba0debdd6f6f5c9 100644 (file)
@@ -49,6 +49,8 @@
 
 #define CLK_PLL_VIDEO1_2X      13
 
+#define CLK_PLL_MIPI           15
+
 #define CLK_CPU                        18
 
 #define CLK_AHB1_MIPIDSI       23
index f8222b6b2cc31b83fceb05596eed826186054ceb..eb524d0bbd0131796ac4d9226691684dfa324adb 100644 (file)
@@ -43,6 +43,8 @@
 #ifndef _DT_BINDINGS_CLK_SUN8I_A23_A33_H_
 #define _DT_BINDINGS_CLK_SUN8I_A23_A33_H_
 
+#define CLK_PLL_MIPI           13
+
 #define CLK_CPUX               18
 
 #define CLK_BUS_MIPI_DSI       23
index f9e15a235626521726e88b65096943b1a3868c02..d7337b55a4ef05d3b39d6c675e1fd9e1e75a6bc4 100644 (file)
 #define CLK_AVS                        152
 #define CLK_HDMI               153
 #define CLK_HDMI_SLOW          154
-
+#define CLK_MBUS               155
 #define CLK_DSI_DPHY           156
 #define CLK_TVE0               157
 #define CLK_TVE1               158
index caf4b9df16ebe09ee91eee9fac753422025241b2..3f66b5e440e7ec7cb581db9a540325ae0436bcbd 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);
 };
 
@@ -321,29 +328,119 @@ struct clk_hw {
  * struct clk_fixed_rate - fixed-rate clock
  * @hw:                handle between common and hardware-specific interfaces
  * @fixed_rate:        constant frequency of clock
+ * @fixed_accuracy: constant accuracy of clock in ppb (parts per billion)
+ * @flags:     hardware specific flags
+ *
+ * Flags:
+ * * CLK_FIXED_RATE_PARENT_ACCURACY - Use the accuracy of the parent clk
+ *                                    instead of what's set in @fixed_accuracy.
  */
 struct clk_fixed_rate {
        struct          clk_hw hw;
        unsigned long   fixed_rate;
        unsigned long   fixed_accuracy;
+       unsigned long   flags;
 };
 
-#define to_clk_fixed_rate(_hw) container_of(_hw, struct clk_fixed_rate, hw)
+#define CLK_FIXED_RATE_PARENT_ACCURACY         BIT(0)
 
 extern const struct clk_ops clk_fixed_rate_ops;
+struct clk_hw *__clk_hw_register_fixed_rate(struct device *dev,
+               struct device_node *np, const char *name,
+               const char *parent_name, const struct clk_hw *parent_hw,
+               const struct clk_parent_data *parent_data, unsigned long flags,
+               unsigned long fixed_rate, unsigned long fixed_accuracy,
+               unsigned long clk_fixed_flags);
 struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
                unsigned long fixed_rate);
-struct clk_hw *clk_hw_register_fixed_rate(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags,
-               unsigned long fixed_rate);
-struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev,
-               const char *name, const char *parent_name, unsigned long flags,
-               unsigned long fixed_rate, unsigned long fixed_accuracy);
+/**
+ * clk_hw_register_fixed_rate - register fixed-rate clock with the clock
+ * framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @fixed_rate: non-adjustable clock rate
+ */
+#define clk_hw_register_fixed_rate(dev, name, parent_name, flags, fixed_rate)  \
+       __clk_hw_register_fixed_rate((dev), NULL, (name), (parent_name), NULL, \
+                                    NULL, (flags), (fixed_rate), 0, 0)
+/**
+ * clk_hw_register_fixed_rate_parent_hw - register fixed-rate clock with
+ * the clock framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_hw: pointer to parent clk
+ * @flags: framework-specific flags
+ * @fixed_rate: non-adjustable clock rate
+ */
+#define clk_hw_register_fixed_rate_parent_hw(dev, name, parent_hw, flags,     \
+                                            fixed_rate)                      \
+       __clk_hw_register_fixed_rate((dev), NULL, (name), NULL, (parent_hw),  \
+                                    NULL, (flags), (fixed_rate), 0, 0)
+/**
+ * clk_hw_register_fixed_rate_parent_data - register fixed-rate clock with
+ * the clock framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_data: parent clk data
+ * @flags: framework-specific flags
+ * @fixed_rate: non-adjustable clock rate
+ */
+#define clk_hw_register_fixed_rate_parent_data(dev, name, parent_hw, flags,   \
+                                            fixed_rate)                      \
+       __clk_hw_register_fixed_rate((dev), NULL, (name), NULL, NULL,         \
+                                    (parent_data), (flags), (fixed_rate), 0, \
+                                    0)
+/**
+ * clk_hw_register_fixed_rate_with_accuracy - register fixed-rate clock with
+ * the clock framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @fixed_rate: non-adjustable clock rate
+ * @fixed_accuracy: non-adjustable clock accuracy
+ */
+#define clk_hw_register_fixed_rate_with_accuracy(dev, name, parent_name,      \
+                                                flags, fixed_rate,           \
+                                                fixed_accuracy)              \
+       __clk_hw_register_fixed_rate((dev), NULL, (name), (parent_name),      \
+                                    NULL, NULL, (flags), (fixed_rate),       \
+                                    (fixed_accuracy), 0)
+/**
+ * clk_hw_register_fixed_rate_with_accuracy_parent_hw - register fixed-rate
+ * clock with the clock framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_hw: pointer to parent clk
+ * @flags: framework-specific flags
+ * @fixed_rate: non-adjustable clock rate
+ * @fixed_accuracy: non-adjustable clock accuracy
+ */
+#define clk_hw_register_fixed_rate_with_accuracy_parent_hw(dev, name,        \
+               parent_hw, flags, fixed_rate, fixed_accuracy)                 \
+       __clk_hw_register_fixed_rate((dev), NULL, (name), NULL, (parent_hw)   \
+                                    NULL, NULL, (flags), (fixed_rate),       \
+                                    (fixed_accuracy), 0)
+/**
+ * clk_hw_register_fixed_rate_with_accuracy_parent_data - register fixed-rate
+ * clock with the clock framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @fixed_rate: non-adjustable clock rate
+ * @fixed_accuracy: non-adjustable clock accuracy
+ */
+#define clk_hw_register_fixed_rate_with_accuracy_parent_data(dev, name,              \
+               parent_data, flags, fixed_rate, fixed_accuracy)               \
+       __clk_hw_register_fixed_rate((dev), NULL, (name), NULL, NULL,         \
+                                    (parent_data), NULL, (flags),            \
+                                    (fixed_rate), (fixed_accuracy), 0)
+
 void clk_unregister_fixed_rate(struct clk *clk);
-struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev,
-               const char *name, const char *parent_name, unsigned long flags,
-               unsigned long fixed_rate, unsigned long fixed_accuracy);
 void clk_hw_unregister_fixed_rate(struct clk_hw *hw);
 
 void of_fixed_clk_setup(struct device_node *np);
@@ -386,14 +483,67 @@ struct clk_gate {
 #define CLK_GATE_BIG_ENDIAN            BIT(2)
 
 extern const struct clk_ops clk_gate_ops;
-struct clk *clk_register_gate(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags,
+struct clk_hw *__clk_hw_register_gate(struct device *dev,
+               struct device_node *np, const char *name,
+               const char *parent_name, const struct clk_hw *parent_hw,
+               const struct clk_parent_data *parent_data,
+               unsigned long flags,
                void __iomem *reg, u8 bit_idx,
                u8 clk_gate_flags, spinlock_t *lock);
-struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name,
+struct clk *clk_register_gate(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
                void __iomem *reg, u8 bit_idx,
                u8 clk_gate_flags, spinlock_t *lock);
+/**
+ * clk_hw_register_gate - register a gate clock with the clock framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_name: name of this clock's parent
+ * @flags: framework-specific flags for this clock
+ * @reg: register address to control gating of this clock
+ * @bit_idx: which bit in the register controls gating of this clock
+ * @clk_gate_flags: gate-specific flags for this clock
+ * @lock: shared register lock for this clock
+ */
+#define clk_hw_register_gate(dev, name, parent_name, flags, reg, bit_idx,     \
+                            clk_gate_flags, lock)                            \
+       __clk_hw_register_gate((dev), NULL, (name), (parent_name), NULL,      \
+                              NULL, (flags), (reg), (bit_idx),               \
+                              (clk_gate_flags), (lock))
+/**
+ * clk_hw_register_gate_parent_hw - register a gate clock with the clock
+ * framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_hw: pointer to parent clk
+ * @flags: framework-specific flags for this clock
+ * @reg: register address to control gating of this clock
+ * @bit_idx: which bit in the register controls gating of this clock
+ * @clk_gate_flags: gate-specific flags for this clock
+ * @lock: shared register lock for this clock
+ */
+#define clk_hw_register_gate_parent_hw(dev, name, parent_name, flags, reg,    \
+                                      bit_idx, clk_gate_flags, lock)         \
+       __clk_hw_register_gate((dev), NULL, (name), (parent_name), NULL,      \
+                              NULL, (flags), (reg), (bit_idx),               \
+                              (clk_gate_flags), (lock))
+/**
+ * clk_hw_register_gate_parent_data - register a gate clock with the clock
+ * framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_data: parent clk data
+ * @flags: framework-specific flags for this clock
+ * @reg: register address to control gating of this clock
+ * @bit_idx: which bit in the register controls gating of this clock
+ * @clk_gate_flags: gate-specific flags for this clock
+ * @lock: shared register lock for this clock
+ */
+#define clk_hw_register_gate_parent_data(dev, name, parent_name, flags, reg,  \
+                                      bit_idx, clk_gate_flags, lock)         \
+       __clk_hw_register_gate((dev), NULL, (name), (parent_name), NULL,      \
+                              NULL, (flags), (reg), (bit_idx),               \
+                              (clk_gate_flags), (lock))
 void clk_unregister_gate(struct clk *clk);
 void clk_hw_unregister_gate(struct clk_hw *hw);
 int clk_gate_is_enabled(struct clk_hw *hw);
@@ -483,24 +633,153 @@ int divider_get_val(unsigned long rate, unsigned long parent_rate,
                const struct clk_div_table *table, u8 width,
                unsigned long flags);
 
-struct clk *clk_register_divider(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags,
-               void __iomem *reg, u8 shift, u8 width,
-               u8 clk_divider_flags, spinlock_t *lock);
-struct clk_hw *clk_hw_register_divider(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags,
-               void __iomem *reg, u8 shift, u8 width,
-               u8 clk_divider_flags, spinlock_t *lock);
+struct clk_hw *__clk_hw_register_divider(struct device *dev,
+               struct device_node *np, const char *name,
+               const char *parent_name, const struct clk_hw *parent_hw,
+               const struct clk_parent_data *parent_data, unsigned long flags,
+               void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags,
+               const struct clk_div_table *table, spinlock_t *lock);
 struct clk *clk_register_divider_table(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
                void __iomem *reg, u8 shift, u8 width,
                u8 clk_divider_flags, const struct clk_div_table *table,
                spinlock_t *lock);
-struct clk_hw *clk_hw_register_divider_table(struct device *dev,
-               const char *name, const char *parent_name, unsigned long flags,
-               void __iomem *reg, u8 shift, u8 width,
-               u8 clk_divider_flags, const struct clk_div_table *table,
-               spinlock_t *lock);
+/**
+ * clk_register_divider - register a divider clock with the clock framework
+ * @dev: device registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @reg: register address to adjust divider
+ * @shift: number of bits to shift the bitfield
+ * @width: width of the bitfield
+ * @clk_divider_flags: divider-specific flags for this clock
+ * @lock: shared register lock for this clock
+ */
+#define clk_register_divider(dev, name, parent_name, flags, reg, shift, width, \
+                            clk_divider_flags, lock)                          \
+       clk_register_divider_table((dev), (name), (parent_name), (flags),      \
+                                  (reg), (shift), (width),                    \
+                                  (clk_divider_flags), NULL, (lock))
+/**
+ * clk_hw_register_divider - register a divider clock with the clock framework
+ * @dev: device registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @reg: register address to adjust divider
+ * @shift: number of bits to shift the bitfield
+ * @width: width of the bitfield
+ * @clk_divider_flags: divider-specific flags for this clock
+ * @lock: shared register lock for this clock
+ */
+#define clk_hw_register_divider(dev, name, parent_name, flags, reg, shift,    \
+                               width, clk_divider_flags, lock)               \
+       __clk_hw_register_divider((dev), NULL, (name), (parent_name), NULL,   \
+                                 NULL, (flags), (reg), (shift), (width),     \
+                                 (clk_divider_flags), NULL, (lock))
+/**
+ * clk_hw_register_divider_parent_hw - register a divider clock with the clock
+ * framework
+ * @dev: device registering this clock
+ * @name: name of this clock
+ * @parent_hw: pointer to parent clk
+ * @flags: framework-specific flags
+ * @reg: register address to adjust divider
+ * @shift: number of bits to shift the bitfield
+ * @width: width of the bitfield
+ * @clk_divider_flags: divider-specific flags for this clock
+ * @lock: shared register lock for this clock
+ */
+#define clk_hw_register_divider_parent_hw(dev, name, parent_hw, flags, reg,   \
+                                         shift, width, clk_divider_flags,    \
+                                         lock)                               \
+       __clk_hw_register_divider((dev), NULL, (name), NULL, (parent_hw),     \
+                                 NULL, (flags), (reg), (shift), (width),     \
+                                 (clk_divider_flags), NULL, (lock))
+/**
+ * clk_hw_register_divider_parent_data - register a divider clock with the clock
+ * framework
+ * @dev: device registering this clock
+ * @name: name of this clock
+ * @parent_data: parent clk data
+ * @flags: framework-specific flags
+ * @reg: register address to adjust divider
+ * @shift: number of bits to shift the bitfield
+ * @width: width of the bitfield
+ * @clk_divider_flags: divider-specific flags for this clock
+ * @lock: shared register lock for this clock
+ */
+#define clk_hw_register_divider_parent_data(dev, name, parent_data, flags,    \
+                                           reg, shift, width,                \
+                                           clk_divider_flags, lock)          \
+       __clk_hw_register_divider((dev), NULL, (name), NULL, NULL,            \
+                                 (parent_data), (flags), (reg), (shift),     \
+                                 (width), (clk_divider_flags), NULL, (lock))
+/**
+ * clk_hw_register_divider_table - register a table based divider clock with
+ * the clock framework
+ * @dev: device registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @reg: register address to adjust divider
+ * @shift: number of bits to shift the bitfield
+ * @width: width of the bitfield
+ * @clk_divider_flags: divider-specific flags for this clock
+ * @table: array of divider/value pairs ending with a div set to 0
+ * @lock: shared register lock for this clock
+ */
+#define clk_hw_register_divider_table(dev, name, parent_name, flags, reg,     \
+                                     shift, width, clk_divider_flags, table, \
+                                     lock)                                   \
+       __clk_hw_register_divider((dev), NULL, (name), (parent_name), NULL,   \
+                                 NULL, (flags), (reg), (shift), (width),     \
+                                 (clk_divider_flags), (table), (lock))
+/**
+ * clk_hw_register_divider_table_parent_hw - register a table based divider
+ * clock with the clock framework
+ * @dev: device registering this clock
+ * @name: name of this clock
+ * @parent_hw: pointer to parent clk
+ * @flags: framework-specific flags
+ * @reg: register address to adjust divider
+ * @shift: number of bits to shift the bitfield
+ * @width: width of the bitfield
+ * @clk_divider_flags: divider-specific flags for this clock
+ * @table: array of divider/value pairs ending with a div set to 0
+ * @lock: shared register lock for this clock
+ */
+#define clk_hw_register_divider_table_parent_hw(dev, name, parent_hw, flags,  \
+                                               reg, shift, width,            \
+                                               clk_divider_flags, table,     \
+                                               lock)                         \
+       __clk_hw_register_divider((dev), NULL, (name), NULL, (parent_hw),     \
+                                 NULL, (flags), (reg), (shift), (width),     \
+                                 (clk_divider_flags), (table), (lock))
+/**
+ * clk_hw_register_divider_table_parent_data - register a table based divider
+ * clock with the clock framework
+ * @dev: device registering this clock
+ * @name: name of this clock
+ * @parent_data: parent clk data
+ * @flags: framework-specific flags
+ * @reg: register address to adjust divider
+ * @shift: number of bits to shift the bitfield
+ * @width: width of the bitfield
+ * @clk_divider_flags: divider-specific flags for this clock
+ * @table: array of divider/value pairs ending with a div set to 0
+ * @lock: shared register lock for this clock
+ */
+#define clk_hw_register_divider_table_parent_data(dev, name, parent_data,     \
+                                                 flags, reg, shift, width,   \
+                                                 clk_divider_flags, table,   \
+                                                 lock)                       \
+       __clk_hw_register_divider((dev), NULL, (name), NULL, NULL,            \
+                                 (parent_data), (flags), (reg), (shift),     \
+                                 (width), (clk_divider_flags), (table),      \
+                                 (lock))
+
 void clk_unregister_divider(struct clk *clk);
 void clk_hw_unregister_divider(struct clk_hw *hw);
 
@@ -555,28 +834,48 @@ struct clk_mux {
 extern const struct clk_ops clk_mux_ops;
 extern const struct clk_ops clk_mux_ro_ops;
 
-struct clk *clk_register_mux(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents,
-               unsigned long flags,
-               void __iomem *reg, u8 shift, u8 width,
-               u8 clk_mux_flags, spinlock_t *lock);
-struct clk_hw *clk_hw_register_mux(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents,
-               unsigned long flags,
-               void __iomem *reg, u8 shift, u8 width,
-               u8 clk_mux_flags, spinlock_t *lock);
-
-struct clk *clk_register_mux_table(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents,
-               unsigned long flags,
-               void __iomem *reg, u8 shift, u32 mask,
+struct clk_hw *__clk_hw_register_mux(struct device *dev, struct device_node *np,
+               const char *name, u8 num_parents,
+               const char * const *parent_names,
+               const struct clk_hw **parent_hws,
+               const struct clk_parent_data *parent_data,
+               unsigned long flags, void __iomem *reg, u8 shift, u32 mask,
                u8 clk_mux_flags, u32 *table, spinlock_t *lock);
-struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
+struct clk *clk_register_mux_table(struct device *dev, const char *name,
                const char * const *parent_names, u8 num_parents,
-               unsigned long flags,
-               void __iomem *reg, u8 shift, u32 mask,
+               unsigned long flags, void __iomem *reg, u8 shift, u32 mask,
                u8 clk_mux_flags, u32 *table, spinlock_t *lock);
 
+#define clk_register_mux(dev, name, parent_names, num_parents, flags, reg,    \
+                        shift, width, clk_mux_flags, lock)                   \
+       clk_register_mux_table((dev), (name), (parent_names), (num_parents),  \
+                              (flags), (reg), (shift), BIT((width)) - 1,     \
+                              (clk_mux_flags), NULL, (lock))
+#define clk_hw_register_mux_table(dev, name, parent_names, num_parents,              \
+                                 flags, reg, shift, mask, clk_mux_flags,     \
+                                 table, lock)                                \
+       __clk_hw_register_mux((dev), NULL, (name), (num_parents),             \
+                             (parent_names), NULL, NULL, (flags), (reg),     \
+                             (shift), (mask), (clk_mux_flags), (table),      \
+                             (lock))
+#define clk_hw_register_mux(dev, name, parent_names, num_parents, flags, reg, \
+                           shift, width, clk_mux_flags, lock)                \
+       __clk_hw_register_mux((dev), NULL, (name), (num_parents),             \
+                             (parent_names), NULL, NULL, (flags), (reg),     \
+                             (shift), BIT((width)) - 1, (clk_mux_flags),     \
+                             NULL, (lock))
+#define clk_hw_register_mux_hws(dev, name, parent_hws, num_parents, flags,    \
+                               reg, shift, width, clk_mux_flags, lock)       \
+       __clk_hw_register_mux((dev), NULL, (name), (num_parents), NULL,       \
+                             (parent_hws), NULL, (flags), (reg), (shift),    \
+                             BIT((width)) - 1, (clk_mux_flags), NULL, (lock))
+#define clk_hw_register_mux_parent_data(dev, name, parent_data, num_parents,  \
+                                       flags, reg, shift, width,             \
+                                       clk_mux_flags, lock)                  \
+       __clk_hw_register_mux((dev), NULL, (name), (num_parents), NULL, NULL, \
+                             (parent_data), (flags), (reg), (shift),         \
+                             BIT((width)) - 1, (clk_mux_flags), NULL, (lock))
+
 int clk_mux_val_to_index(struct clk_hw *hw, u32 *table, unsigned int flags,
                         unsigned int val);
 unsigned int clk_mux_index_to_val(u32 *table, unsigned int flags, u8 index);
@@ -752,44 +1051,6 @@ struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name,
                unsigned long flags);
 void clk_hw_unregister_composite(struct clk_hw *hw);
 
-/**
- * struct clk_gpio - gpio gated clock
- *
- * @hw:                handle between common and hardware-specific interfaces
- * @gpiod:     gpio descriptor
- *
- * Clock with a gpio control for enabling and disabling the parent clock
- * or switching between two parents by asserting or deasserting the gpio.
- *
- * Implements .enable, .disable and .is_enabled or
- * .get_parent, .set_parent and .determine_rate depending on which clk_ops
- * is used.
- */
-struct clk_gpio {
-       struct clk_hw   hw;
-       struct gpio_desc *gpiod;
-};
-
-#define to_clk_gpio(_hw) container_of(_hw, struct clk_gpio, hw)
-
-extern const struct clk_ops clk_gpio_gate_ops;
-struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
-               const char *parent_name, struct gpio_desc *gpiod,
-               unsigned long flags);
-struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name,
-               const char *parent_name, struct gpio_desc *gpiod,
-               unsigned long flags);
-void clk_hw_unregister_gpio_gate(struct clk_hw *hw);
-
-extern const struct clk_ops clk_gpio_mux_ops;
-struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod,
-               unsigned long flags);
-struct clk_hw *clk_hw_register_gpio_mux(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod,
-               unsigned long flags);
-void clk_hw_unregister_gpio_mux(struct clk_hw *hw);
-
 struct clk *clk_register(struct device *dev, struct clk_hw *hw);
 struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw);