]> Git Repo - J-linux.git/commitdiff
Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
authorLinus Torvalds <[email protected]>
Fri, 20 Sep 2019 22:45:07 +0000 (15:45 -0700)
committerLinus Torvalds <[email protected]>
Fri, 20 Sep 2019 22:45:07 +0000 (15:45 -0700)
Pull clk updates from Stephen Boyd:
 "We have a small collection of core framework updates this time, mostly
  around clk registration by clk providers and debugfs "nice to haves"
  for rate constraints. I'll highlight that we're now setting the
  clk_init_data pointer inside struct clk_hw to NULL during
  clk_register(), which may break some drivers that thought they could
  use that pointer during normal operations. That change has been
  sitting in next for a while now but maybe something is still broken.
  We'l see. Other than that the core framework changes aren't invasive
  and they're fixing bugs, simplifying, and making things better.

  On the clk driver side we got the usual addition of new SoC support,
  new features for existing drivers, and bug fixes scattered throughout.
  The biggest diffstat is the Amlogic driver that gained CPU clk support
  in addition to migrating to the new way of specifying clk parents.
  After that the Qualcomm, i.MX, Mediatek, and Rockchip clk drivers got
  support for various new SoCs and clock controllers from those vendors.

  Core:
   - Drop NULL checks in clk debugfs
   - Add min/max rates to clk debugfs
   - Set clk_init_data pointer inside clk_hw to NULL after registration
   - Make clk_bulk_get_all() return an 'id' corresponding to clock-names
   - Evict parents from parent cache when they're unregistered

  New Drivers:
   - Add clock driver for i.MX8MN SoCs
   - Support aspeed AST2600 SoCs
   - Support for Mediatek MT6779 SoCs
   - Support qcom SM8150 GCC and RPMh clks
   - Support qcom QCS404 WCSS clks
   - Add CPU clock support for Armada 7K/8K (specifically AP806 and AP807)
   - Addition of clock driver for Rockchip rk3308 SoCs

  Updates:
   - Add regulator support to the cdce925 clk driver
   - Add support for Raspberry Pi 4 bcm2711 SoCs
   - Add SDIO gate support to aspeed driver
   - Add missing of_node_put() calls in various clk drivers
   - Migrate Amlogic driver to new clock parent description method
   - Add DVFS support to Amlogic Meson g12
   - Add Amlogic Meson g12a reset support to the axg audio clock controller
   - Add sm1 support to the Amlogic Meson g12a clock controller
   - Switch i.MX8MM clock driver to platform driver
   - Add Hifi4 DSP related clocks for i.MX8QXP SoC
   - Fix Audio PLL setting and parent clock for USB
   - Misc i.MX8 clock driver improvements and corrections
   - Set floor ops for Qualcomm SD clks so that rounding works
   - Fix "always-on" Clock Domains on Renesas R-Car M1A, RZ/A1, RZ/A2, and RZ/N1
   - Enable the Allwinner V3 SoC and fix the i2s clock for H6"

* tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (137 commits)
  clk: Drop !clk checks in debugfs dumping
  clk: imx: imx8mn: fix pll mux bit
  clk: imx: imx8mm: fix pll mux bit
  clk: imx: clk-pll14xx: unbypass PLL by default
  clk: imx: pll14xx: avoid glitch when set rate
  clk: mvebu: ap80x: add AP807 clock support
  clk: mvebu: ap806: Prepare the introduction of AP807 clock support
  clk: mvebu: ap806: add AP-DCLK (hclk) to system controller driver
  clk: mvebu: ap806: be more explicit on what SaR is
  clk: mvebu: ap80x-cpu: add AP807 CPU clock support
  clk: mvebu: ap806-cpu: prepare mapping of AP807 CPU clock
  dt-bindings: ap806: Document AP807 clock compatible
  dt-bindings: ap80x: Document AP807 CPU clock compatible
  clk: sprd: add missing kfree
  clk: at91: allow 24 Mhz clock as input for PLL
  clk: Make clk_bulk_get_all() return a valid "id"
  clk: actions: Fix factor clk struct member access
  clk: qcom: rcg: Return failure for RCG update
  clk: remove extra ---help--- tags in Kconfig
  clk: add include guard to clk-conf.h
  ...

1  2 
Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml
drivers/clk/clk.c
drivers/clk/mediatek/clk-mt8183.c
drivers/clk/qcom/clk-rpmh.c
drivers/clk/renesas/renesas-cpg-mssr.c
drivers/phy/ti/phy-am654-serdes.c
include/linux/clk.h

index fa4d143a73de2e16d5c7d841c4dacd69cdd9817c,1bde87fc94c55a8ff47d2712f64744be81524aa2..64938fdaea554973d960bd1c3b4f01e130747167
@@@ -1,7 -1,7 +1,7 @@@
  # SPDX-License-Identifier: GPL-2.0
  %YAML 1.2
  ---
 -$id: http://devicetree.org/schemas/phy/allwinner,sun4i-a10-ccu.yaml#
 +$id: http://devicetree.org/schemas/clock/allwinner,sun4i-a10-ccu.yaml#
  $schema: http://devicetree.org/meta-schemas/core.yaml#
  
  title: Allwinner Clock Control Unit Device Tree Bindings
@@@ -31,6 -31,7 +31,7 @@@ properties
        - allwinner,sun8i-h3-ccu
        - allwinner,sun8i-h3-r-ccu
        - allwinner,sun8i-r40-ccu
+       - allwinner,sun8i-v3-ccu
        - allwinner,sun8i-v3s-ccu
        - allwinner,sun9i-a80-ccu
        - allwinner,sun50i-a64-ccu
diff --combined drivers/clk/clk.c
index ca99e9db657587995dcd83efb49b194b91fa3be7,498cae518147d83a1aee9fb64f3f292911df933d..1c677d7f7f530739ef2dd91428697d308dee3349
@@@ -37,6 -37,12 +37,12 @@@ static HLIST_HEAD(clk_root_list)
  static HLIST_HEAD(clk_orphan_list);
  static LIST_HEAD(clk_notifier_list);
  
+ static struct hlist_head *all_lists[] = {
+       &clk_root_list,
+       &clk_orphan_list,
+       NULL,
+ };
  /***    private data structures    ***/
  
  struct clk_parent_map {
@@@ -324,25 -330,6 +330,25 @@@ static struct clk_core *clk_core_lookup
        return NULL;
  }
  
 +#ifdef CONFIG_OF
 +static int of_parse_clkspec(const struct device_node *np, int index,
 +                          const char *name, struct of_phandle_args *out_args);
 +static struct clk_hw *
 +of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec);
 +#else
 +static inline int of_parse_clkspec(const struct device_node *np, int index,
 +                                 const char *name,
 +                                 struct of_phandle_args *out_args)
 +{
 +      return -ENOENT;
 +}
 +static inline struct clk_hw *
 +of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec)
 +{
 +      return ERR_PTR(-ENOENT);
 +}
 +#endif
 +
  /**
   * clk_core_get - Find the clk_core parent of a clk
   * @core: clk to find parent of
   *      };
   *
   * Returns: -ENOENT when the provider can't be found or the clk doesn't
 - * exist in the provider. -EINVAL when the name can't be found. NULL when the
 - * provider knows about the clk but it isn't provided on this system.
 + * exist in the provider or the name can't be found in the DT node or
 + * in a clkdev lookup. NULL when the provider knows about the clk but it
 + * isn't provided on this system.
   * A valid clk_core pointer when the clk can be found in the provider.
   */
  static struct clk_core *clk_core_get(struct clk_core *core, u8 p_index)
        struct device *dev = core->dev;
        const char *dev_id = dev ? dev_name(dev) : NULL;
        struct device_node *np = core->of_node;
 +      struct of_phandle_args clkspec;
  
 -      if (np && (name || index >= 0))
 -              hw = of_clk_get_hw(np, index, name);
 -
 -      /*
 -       * If the DT search above couldn't find the provider or the provider
 -       * didn't know about this clk, fallback to looking up via clkdev based
 -       * clk_lookups
 -       */
 -      if (PTR_ERR(hw) == -ENOENT && name)
 +      if (np && (name || index >= 0) &&
 +          !of_parse_clkspec(np, index, name, &clkspec)) {
 +              hw = of_clk_get_hw_from_clkspec(&clkspec);
 +              of_node_put(clkspec.np);
 +      } else if (name) {
 +              /*
 +               * If the DT search above couldn't find the provider fallback to
 +               * looking up via clkdev based clk_lookups.
 +               */
                hw = clk_find_hw(dev_id, name);
 +      }
  
        if (IS_ERR(hw))
                return ERR_CAST(hw);
@@@ -423,7 -407,7 +429,7 @@@ static void clk_core_fill_parent_index(
                        parent = ERR_PTR(-EPROBE_DEFER);
        } else {
                parent = clk_core_get(core, index);
 -              if (IS_ERR(parent) && PTR_ERR(parent) == -ENOENT)
 +              if (IS_ERR(parent) && PTR_ERR(parent) == -ENOENT && entry->name)
                        parent = clk_core_lookup(entry->name);
        }
  
@@@ -615,6 -599,8 +621,8 @@@ static void clk_core_get_boundaries(str
  {
        struct clk *clk_user;
  
+       lockdep_assert_held(&prepare_lock);
        *min_rate = core->min_rate;
        *max_rate = core->max_rate;
  
@@@ -1654,8 -1640,7 +1662,8 @@@ static int clk_fetch_parent_index(struc
                        break;
  
                /* Fallback to comparing globally unique names */
 -              if (!strcmp(parent->name, core->parents[i].name))
 +              if (core->parents[i].name &&
 +                  !strcmp(parent->name, core->parents[i].name))
                        break;
        }
  
@@@ -2460,7 -2445,7 +2468,7 @@@ static int clk_core_set_parent_nolock(s
        if (core->parent == parent)
                return 0;
  
-       /* verify ops for for multi-parent clks */
+       /* verify ops for multi-parent clks */
        if (core->num_parents > 1 && !core->ops->set_parent)
                return -EPERM;
  
@@@ -2862,12 -2847,6 +2870,6 @@@ static int inited = 0
  static DEFINE_MUTEX(clk_debug_lock);
  static HLIST_HEAD(clk_debug_list);
  
- static struct hlist_head *all_lists[] = {
-       &clk_root_list,
-       &clk_orphan_list,
-       NULL,
- };
  static struct hlist_head *orphan_list[] = {
        &clk_orphan_list,
        NULL,
  static void clk_summary_show_one(struct seq_file *s, struct clk_core *c,
                                 int level)
  {
-       if (!c)
-               return;
        seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu %5d %6d\n",
                   level * 3 + 1, "",
                   30 - level * 3, c->name,
@@@ -2893,9 -2869,6 +2892,6 @@@ static void clk_summary_show_subtree(st
  {
        struct clk_core *child;
  
-       if (!c)
-               return;
        clk_summary_show_one(s, c, level);
  
        hlist_for_each_entry(child, &c->children, child_node)
@@@ -2925,8 -2898,9 +2921,9 @@@ DEFINE_SHOW_ATTRIBUTE(clk_summary)
  
  static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)
  {
-       if (!c)
-               return;
+       unsigned long min_rate, max_rate;
+       clk_core_get_boundaries(c, &min_rate, &max_rate);
  
        /* This should be JSON format, i.e. elements separated with a comma */
        seq_printf(s, "\"%s\": { ", c->name);
        seq_printf(s, "\"prepare_count\": %d,", c->prepare_count);
        seq_printf(s, "\"protect_count\": %d,", c->protect_count);
        seq_printf(s, "\"rate\": %lu,", clk_core_get_rate(c));
+       seq_printf(s, "\"min_rate\": %lu,", min_rate);
+       seq_printf(s, "\"max_rate\": %lu,", max_rate);
        seq_printf(s, "\"accuracy\": %lu,", clk_core_get_accuracy(c));
        seq_printf(s, "\"phase\": %d,", clk_core_get_phase(c));
        seq_printf(s, "\"duty_cycle\": %u",
@@@ -2944,9 -2920,6 +2943,6 @@@ static void clk_dump_subtree(struct seq
  {
        struct clk_core *child;
  
-       if (!c)
-               return;
        clk_dump_one(s, c, level);
  
        hlist_for_each_entry(child, &c->children, child_node) {
@@@ -3042,15 -3015,15 +3038,15 @@@ static void possible_parent_show(struc
         */
        parent = clk_core_get_parent_by_index(core, i);
        if (parent)
-               seq_printf(s, "%s", parent->name);
+               seq_puts(s, parent->name);
        else if (core->parents[i].name)
-               seq_printf(s, "%s", core->parents[i].name);
+               seq_puts(s, core->parents[i].name);
        else if (core->parents[i].fw_name)
                seq_printf(s, "<%s>(fw)", core->parents[i].fw_name);
        else if (core->parents[i].index >= 0)
-               seq_printf(s, "%s",
-                          of_clk_get_parent_name(core->of_node,
-                                                 core->parents[i].index));
+               seq_puts(s,
+                        of_clk_get_parent_name(core->of_node,
+                                               core->parents[i].index));
        else
                seq_puts(s, "(missing)");
  
@@@ -3093,6 -3066,34 +3089,34 @@@ static int clk_duty_cycle_show(struct s
  }
  DEFINE_SHOW_ATTRIBUTE(clk_duty_cycle);
  
+ static int clk_min_rate_show(struct seq_file *s, void *data)
+ {
+       struct clk_core *core = s->private;
+       unsigned long min_rate, max_rate;
+       clk_prepare_lock();
+       clk_core_get_boundaries(core, &min_rate, &max_rate);
+       clk_prepare_unlock();
+       seq_printf(s, "%lu\n", min_rate);
+       return 0;
+ }
+ DEFINE_SHOW_ATTRIBUTE(clk_min_rate);
+ static int clk_max_rate_show(struct seq_file *s, void *data)
+ {
+       struct clk_core *core = s->private;
+       unsigned long min_rate, max_rate;
+       clk_prepare_lock();
+       clk_core_get_boundaries(core, &min_rate, &max_rate);
+       clk_prepare_unlock();
+       seq_printf(s, "%lu\n", max_rate);
+       return 0;
+ }
+ DEFINE_SHOW_ATTRIBUTE(clk_max_rate);
  static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
  {
        struct dentry *root;
        core->dentry = root;
  
        debugfs_create_ulong("clk_rate", 0444, root, &core->rate);
+       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);
        debugfs_create_u32("clk_phase", 0444, root, &core->phase);
        debugfs_create_file("clk_flags", 0444, root, core, &clk_flags_fops);
@@@ -3513,9 -3516,9 +3539,9 @@@ static int clk_cpy_name(const char **ds
        return 0;
  }
  
- static int clk_core_populate_parent_map(struct clk_core *core)
+ static int clk_core_populate_parent_map(struct clk_core *core,
+                                       const struct clk_init_data *init)
  {
-       const struct clk_init_data *init = core->hw->init;
        u8 num_parents = init->num_parents;
        const char * const *parent_names = init->parent_names;
        const struct clk_hw **parent_hws = init->parent_hws;
@@@ -3595,6 -3598,14 +3621,14 @@@ __clk_register(struct device *dev, stru
  {
        int ret;
        struct clk_core *core;
+       const struct clk_init_data *init = hw->init;
+       /*
+        * The init data is not supposed to be used outside of registration path.
+        * Set it to NULL so that provider drivers can't use it either and so that
+        * we catch use of hw->init early on in the core.
+        */
+       hw->init = NULL;
  
        core = kzalloc(sizeof(*core), GFP_KERNEL);
        if (!core) {
                goto fail_out;
        }
  
-       core->name = kstrdup_const(hw->init->name, GFP_KERNEL);
+       core->name = kstrdup_const(init->name, GFP_KERNEL);
        if (!core->name) {
                ret = -ENOMEM;
                goto fail_name;
        }
  
-       if (WARN_ON(!hw->init->ops)) {
+       if (WARN_ON(!init->ops)) {
                ret = -EINVAL;
                goto fail_ops;
        }
-       core->ops = hw->init->ops;
+       core->ops = init->ops;
  
        if (dev && pm_runtime_enabled(dev))
                core->rpm_enabled = true;
        if (dev && dev->driver)
                core->owner = dev->driver->owner;
        core->hw = hw;
-       core->flags = hw->init->flags;
-       core->num_parents = hw->init->num_parents;
+       core->flags = init->flags;
+       core->num_parents = init->num_parents;
        core->min_rate = 0;
        core->max_rate = ULONG_MAX;
        hw->core = core;
  
-       ret = clk_core_populate_parent_map(core);
+       ret = clk_core_populate_parent_map(core, init);
        if (ret)
                goto fail_parents;
  
@@@ -3766,6 -3777,34 +3800,34 @@@ static const struct clk_ops clk_nodrv_o
        .set_parent     = clk_nodrv_set_parent,
  };
  
+ static void clk_core_evict_parent_cache_subtree(struct clk_core *root,
+                                               struct clk_core *target)
+ {
+       int i;
+       struct clk_core *child;
+       for (i = 0; i < root->num_parents; i++)
+               if (root->parents[i].core == target)
+                       root->parents[i].core = NULL;
+       hlist_for_each_entry(child, &root->children, child_node)
+               clk_core_evict_parent_cache_subtree(child, target);
+ }
+ /* Remove this clk from all parent caches */
+ static void clk_core_evict_parent_cache(struct clk_core *core)
+ {
+       struct hlist_head **lists;
+       struct clk_core *root;
+       lockdep_assert_held(&prepare_lock);
+       for (lists = all_lists; *lists; lists++)
+               hlist_for_each_entry(root, *lists, child_node)
+                       clk_core_evict_parent_cache_subtree(root, core);
+ }
  /**
   * clk_unregister - unregister a currently registered clock
   * @clk: clock to unregister
@@@ -3804,6 -3843,8 +3866,8 @@@ void clk_unregister(struct clk *clk
                        clk_core_set_parent_nolock(child, NULL);
        }
  
+       clk_core_evict_parent_cache(clk->core);
        hlist_del_init(&clk->core->child_node);
  
        if (clk->core->prepare_count)
@@@ -4345,12 -4386,43 +4409,43 @@@ void devm_of_clk_del_provider(struct de
  }
  EXPORT_SYMBOL(devm_of_clk_del_provider);
  
- /*
-  * Beware the return values when np is valid, but no clock provider is found.
-  * If name == NULL, the function returns -ENOENT.
-  * If name != NULL, the function returns -EINVAL. This is because
-  * of_parse_phandle_with_args() is called even if of_property_match_string()
-  * returns an error.
+ /**
+  * of_parse_clkspec() - Parse a DT clock specifier for a given device node
+  * @np: device node to parse clock specifier from
+  * @index: index of phandle to parse clock out of. If index < 0, @name is used
+  * @name: clock name to find and parse. If name is NULL, the index is used
+  * @out_args: Result of parsing the clock specifier
+  *
+  * Parses a device node's "clocks" and "clock-names" properties to find the
+  * phandle and cells for the index or name that is desired. The resulting clock
+  * specifier is placed into @out_args, or an errno is returned when there's a
+  * parsing error. The @index argument is ignored if @name is non-NULL.
+  *
+  * Example:
+  *
+  * phandle1: clock-controller@1 {
+  *    #clock-cells = <2>;
+  * }
+  *
+  * phandle2: clock-controller@2 {
+  *    #clock-cells = <1>;
+  * }
+  *
+  * clock-consumer@3 {
+  *    clocks = <&phandle1 1 2 &phandle2 3>;
+  *    clock-names = "name1", "name2";
+  * }
+  *
+  * To get a device_node for `clock-controller@2' node you may call this
+  * function a few different ways:
+  *
+  *   of_parse_clkspec(clock-consumer@3, -1, "name2", &args);
+  *   of_parse_clkspec(clock-consumer@3, 1, NULL, &args);
+  *   of_parse_clkspec(clock-consumer@3, 1, "name2", &args);
+  *
+  * Return: 0 upon successfully parsing the clock specifier. Otherwise, -ENOENT
+  * if @name is NULL or -EINVAL if @name is non-NULL and it can't be found in
+  * the "clock-names" property of @np.
   */
  static int of_parse_clkspec(const struct device_node *np, int index,
                            const char *name, struct of_phandle_args *out_args)
index 73b7e238eee75e020373b98e3727277676920c21,7e7452e5669422d3bc2fe1d5e4c5e767ae8408f9..51c8d5c9a030fd103f72510d2ace9296983a81d6
@@@ -17,6 -17,9 +17,9 @@@
  
  #include <dt-bindings/clock/mt8183-clk.h>
  
+ /* Infra global controller reset set register */
+ #define INFRA_RST0_SET_OFFSET         0x120
  static DEFINE_SPINLOCK(mt8183_clk_lock);
  
  static const struct mtk_fixed_clk top_fixed_clks[] = {
        FIXED_CLK(CLK_TOP_UNIVP_192M, "univpll_192m", "univpll", 192000000),
  };
  
 +static const struct mtk_fixed_factor top_early_divs[] = {
 +      FACTOR(CLK_TOP_CLK13M, "clk13m", "clk26m", 1, 2),
 +};
 +
  static const struct mtk_fixed_factor top_divs[] = {
 -      FACTOR(CLK_TOP_CLK13M, "clk13m", "clk26m", 1,
 -              2),
        FACTOR(CLK_TOP_F26M_CK_D2, "csw_f26m_ck_d2", "clk26m", 1,
                2),
        FACTOR(CLK_TOP_SYSPLL_CK, "syspll_ck", "mainpll", 1,
@@@ -1001,6 -1002,20 +1004,20 @@@ static const struct mtk_gate infra_clks
                "msdc50_0_sel", 24),
  };
  
+ static const struct mtk_gate_regs peri_cg_regs = {
+       .set_ofs = 0x20c,
+       .clr_ofs = 0x20c,
+       .sta_ofs = 0x20c,
+ };
+ #define GATE_PERI(_id, _name, _parent, _shift)                        \
+       GATE_MTK(_id, _name, _parent, &peri_cg_regs, _shift,    \
+               &mtk_clk_gate_ops_no_setclr_inv)
+ static const struct mtk_gate peri_clks[] = {
+       GATE_PERI(CLK_PERI_AXI, "peri_axi", "axi_sel", 31),
+ };
  static const struct mtk_gate_regs apmixed_cg_regs = {
        .set_ofs = 0x20,
        .clr_ofs = 0x20,
@@@ -1150,69 -1165,73 +1167,93 @@@ static int clk_mt8183_apmixed_probe(str
        return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
  }
  
 +static struct clk_onecell_data *top_clk_data;
 +
 +static void clk_mt8183_top_init_early(struct device_node *node)
 +{
 +      int i;
 +
 +      top_clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
 +
 +      for (i = 0; i < CLK_TOP_NR_CLK; i++)
 +              top_clk_data->clks[i] = ERR_PTR(-EPROBE_DEFER);
 +
 +      mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs),
 +                      top_clk_data);
 +
 +      of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data);
 +}
 +
 +CLK_OF_DECLARE_DRIVER(mt8183_topckgen, "mediatek,mt8183-topckgen",
 +                      clk_mt8183_top_init_early);
 +
  static int clk_mt8183_top_probe(struct platform_device *pdev)
  {
        struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        void __iomem *base;
 -      struct clk_onecell_data *clk_data;
        struct device_node *node = pdev->dev.of_node;
  
        base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(base))
                return PTR_ERR(base);
  
 -      clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
 -
        mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
 -              clk_data);
 +              top_clk_data);
 +
 +      mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs),
 +              top_clk_data);
  
 -      mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
 +      mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data);
  
        mtk_clk_register_muxes(top_muxes, ARRAY_SIZE(top_muxes),
 -              node, &mt8183_clk_lock, clk_data);
 +              node, &mt8183_clk_lock, top_clk_data);
  
        mtk_clk_register_composites(top_aud_muxes, ARRAY_SIZE(top_aud_muxes),
 -              base, &mt8183_clk_lock, clk_data);
 +              base, &mt8183_clk_lock, top_clk_data);
  
        mtk_clk_register_composites(top_aud_divs, ARRAY_SIZE(top_aud_divs),
 -              base, &mt8183_clk_lock, clk_data);
 +              base, &mt8183_clk_lock, top_clk_data);
  
        mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
 -              clk_data);
 +              top_clk_data);
  
 -      return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
 +      return of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data);
  }
  
  static int clk_mt8183_infra_probe(struct platform_device *pdev)
  {
        struct clk_onecell_data *clk_data;
        struct device_node *node = pdev->dev.of_node;
+       int r;
  
        clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
  
        mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
                clk_data);
  
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+       if (r) {
+               dev_err(&pdev->dev,
+                       "%s(): could not register clock provider: %d\n",
+                       __func__, r);
+               return r;
+       }
+       mtk_register_reset_controller_set_clr(node, 4, INFRA_RST0_SET_OFFSET);
+       return r;
+ }
+ static int clk_mt8183_peri_probe(struct platform_device *pdev)
+ {
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+       clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK);
+       mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
+                              clk_data);
        return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
  }
  
@@@ -1245,6 -1264,9 +1286,9 @@@ static const struct of_device_id of_mat
        }, {
                .compatible = "mediatek,mt8183-infracfg",
                .data = clk_mt8183_infra_probe,
+       }, {
+               .compatible = "mediatek,mt8183-pericfg",
+               .data = clk_mt8183_peri_probe,
        }, {
                .compatible = "mediatek,mt8183-mcucfg",
                .data = clk_mt8183_mcu_probe,
index a32bfaeb7e613af452aaac836189c623109c09e8,5b72689c3939d391da557f64944c6bc74d1fcaab..96a36f6ff667d6bee37df3b323c415712ba38c5f
@@@ -1,6 -1,6 +1,6 @@@
  // SPDX-License-Identifier: GPL-2.0
  /*
 - * Copyright (c) 2018, The Linux Foundation. All rights reserved.
 + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
   */
  
  #include <linux/clk-provider.h>
  #include <linux/platform_device.h>
  #include <soc/qcom/cmd-db.h>
  #include <soc/qcom/rpmh.h>
 +#include <soc/qcom/tcs.h>
  
  #include <dt-bindings/clock/qcom,rpmh.h>
  
  #define CLK_RPMH_ARC_EN_OFFSET                0
  #define CLK_RPMH_VRM_EN_OFFSET                4
  
 -#define BCM_TCS_CMD_COMMIT_MASK               0x40000000
 -#define BCM_TCS_CMD_VALID_SHIFT               29
 -#define BCM_TCS_CMD_VOTE_MASK         0x3fff
 -#define BCM_TCS_CMD_VOTE_SHIFT                0
 -
 -#define BCM_TCS_CMD(valid, vote)                              \
 -      (BCM_TCS_CMD_COMMIT_MASK |                              \
 -      ((valid) << BCM_TCS_CMD_VALID_SHIFT) |                  \
 -      ((vote & BCM_TCS_CMD_VOTE_MASK)                         \
 -      << BCM_TCS_CMD_VOTE_SHIFT))
 -
  /**
   * struct bcm_db - Auxiliary data pertaining to each Bus Clock Manager(BCM)
   * @unit: divisor used to convert Hz value to an RPMh msg
@@@ -85,7 -95,10 +85,10 @@@ static DEFINE_MUTEX(rpmh_clk_lock)
                .hw.init = &(struct clk_init_data){                     \
                        .ops = &clk_rpmh_ops,                           \
                        .name = #_name,                                 \
-                       .parent_names = (const char *[]){ "xo_board" }, \
+                       .parent_data =  &(const struct clk_parent_data){ \
+                                       .fw_name = "xo",                \
+                                       .name = "xo_board",             \
+                       },                                              \
                        .num_parents = 1,                               \
                },                                                      \
        };                                                              \
                .hw.init = &(struct clk_init_data){                     \
                        .ops = &clk_rpmh_ops,                           \
                        .name = #_name_active,                          \
-                       .parent_names = (const char *[]){ "xo_board" }, \
+                       .parent_data =  &(const struct clk_parent_data){ \
+                                       .fw_name = "xo",                \
+                                       .name = "xo_board",             \
+                       },                                              \
                        .num_parents = 1,                               \
                },                                                      \
        }
@@@ -259,7 -275,7 +265,7 @@@ static int clk_rpmh_bcm_send_cmd(struc
        }
  
        cmd.addr = c->res_addr;
 -      cmd.data = BCM_TCS_CMD(enable, cmd_state);
 +      cmd.data = BCM_TCS_CMD(1, enable, 0, cmd_state);
  
        ret = rpmh_write_async(c->dev, RPMH_ACTIVE_ONLY_STATE, &cmd, 1);
        if (ret) {
@@@ -358,6 -374,33 +364,33 @@@ static const struct clk_rpmh_desc clk_r
        .num_clks = ARRAY_SIZE(sdm845_rpmh_clocks),
  };
  
+ DEFINE_CLK_RPMH_ARC(sm8150, bi_tcxo, bi_tcxo_ao, "xo.lvl", 0x3, 2);
+ DEFINE_CLK_RPMH_VRM(sm8150, ln_bb_clk2, ln_bb_clk2_ao, "lnbclka2", 2);
+ DEFINE_CLK_RPMH_VRM(sm8150, ln_bb_clk3, ln_bb_clk3_ao, "lnbclka3", 2);
+ DEFINE_CLK_RPMH_VRM(sm8150, rf_clk1, rf_clk1_ao, "rfclka1", 1);
+ DEFINE_CLK_RPMH_VRM(sm8150, rf_clk2, rf_clk2_ao, "rfclka2", 1);
+ DEFINE_CLK_RPMH_VRM(sm8150, rf_clk3, rf_clk3_ao, "rfclka3", 1);
+ static struct clk_hw *sm8150_rpmh_clocks[] = {
+       [RPMH_CXO_CLK]          = &sm8150_bi_tcxo.hw,
+       [RPMH_CXO_CLK_A]        = &sm8150_bi_tcxo_ao.hw,
+       [RPMH_LN_BB_CLK2]       = &sm8150_ln_bb_clk2.hw,
+       [RPMH_LN_BB_CLK2_A]     = &sm8150_ln_bb_clk2_ao.hw,
+       [RPMH_LN_BB_CLK3]       = &sm8150_ln_bb_clk3.hw,
+       [RPMH_LN_BB_CLK3_A]     = &sm8150_ln_bb_clk3_ao.hw,
+       [RPMH_RF_CLK1]          = &sm8150_rf_clk1.hw,
+       [RPMH_RF_CLK1_A]        = &sm8150_rf_clk1_ao.hw,
+       [RPMH_RF_CLK2]          = &sm8150_rf_clk2.hw,
+       [RPMH_RF_CLK2_A]        = &sm8150_rf_clk2_ao.hw,
+       [RPMH_RF_CLK3]          = &sm8150_rf_clk3.hw,
+       [RPMH_RF_CLK3_A]        = &sm8150_rf_clk3_ao.hw,
+ };
+ static const struct clk_rpmh_desc clk_rpmh_sm8150 = {
+       .clks = sm8150_rpmh_clocks,
+       .num_clks = ARRAY_SIZE(sm8150_rpmh_clocks),
+ };
  static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec,
                                         void *data)
  {
@@@ -386,6 -429,7 +419,7 @@@ static int clk_rpmh_probe(struct platfo
        hw_clks = desc->clks;
  
        for (i = 0; i < desc->num_clks; i++) {
+               const char *name = hw_clks[i]->init->name;
                u32 res_addr;
                size_t aux_data_len;
                const struct bcm_db *data;
  
                ret = devm_clk_hw_register(&pdev->dev, hw_clks[i]);
                if (ret) {
-                       dev_err(&pdev->dev, "failed to register %s\n",
-                               hw_clks[i]->init->name);
+                       dev_err(&pdev->dev, "failed to register %s\n", name);
                        return ret;
                }
        }
  
  static const struct of_device_id clk_rpmh_match_table[] = {
        { .compatible = "qcom,sdm845-rpmh-clk", .data = &clk_rpmh_sdm845},
+       { .compatible = "qcom,sm8150-rpmh-clk", .data = &clk_rpmh_sm8150},
        { }
  };
  MODULE_DEVICE_TABLE(of, clk_rpmh_match_table);
index d4075b13067429cded1088e6423b77bb78b5309b,cc39c8fff8a1a7d99387a39f39e0a707397e45cb..132cc96895e3a97845b7d086ea83053e8299b799
@@@ -551,7 -551,8 +551,8 @@@ static int __init cpg_mssr_add_clk_doma
  
        genpd = &pd->genpd;
        genpd->name = np->name;
-       genpd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ACTIVE_WAKEUP;
+       genpd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ALWAYS_ON |
+                      GENPD_FLAG_ACTIVE_WAKEUP;
        genpd->attach_dev = cpg_mssr_attach_dev;
        genpd->detach_dev = cpg_mssr_detach_dev;
        pm_genpd_init(genpd, &pm_domain_always_on_gov, false);
@@@ -572,11 -573,17 +573,11 @@@ static int cpg_mssr_reset(struct reset_
        unsigned int reg = id / 32;
        unsigned int bit = id % 32;
        u32 bitmask = BIT(bit);
 -      unsigned long flags;
 -      u32 value;
  
        dev_dbg(priv->dev, "reset %u%02u\n", reg, bit);
  
        /* Reset module */
 -      spin_lock_irqsave(&priv->rmw_lock, flags);
 -      value = readl(priv->base + SRCR(reg));
 -      value |= bitmask;
 -      writel(value, priv->base + SRCR(reg));
 -      spin_unlock_irqrestore(&priv->rmw_lock, flags);
 +      writel(bitmask, priv->base + SRCR(reg));
  
        /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */
        udelay(35);
@@@ -593,10 -600,16 +594,10 @@@ static int cpg_mssr_assert(struct reset
        unsigned int reg = id / 32;
        unsigned int bit = id % 32;
        u32 bitmask = BIT(bit);
 -      unsigned long flags;
 -      u32 value;
  
        dev_dbg(priv->dev, "assert %u%02u\n", reg, bit);
  
 -      spin_lock_irqsave(&priv->rmw_lock, flags);
 -      value = readl(priv->base + SRCR(reg));
 -      value |= bitmask;
 -      writel(value, priv->base + SRCR(reg));
 -      spin_unlock_irqrestore(&priv->rmw_lock, flags);
 +      writel(bitmask, priv->base + SRCR(reg));
        return 0;
  }
  
index f14f1f053a75b8bd63be17655be59a4e864a89c3,398a8c9b675a94b37e5cb1765ce6b83ace95be33..88a047b9fa6fa4e79ca3f9fd18decafcdf568327
@@@ -335,6 -335,7 +335,7 @@@ static int serdes_am654_clk_mux_set_par
  {
        struct serdes_am654_clk_mux *mux = to_serdes_am654_clk_mux(hw);
        struct regmap *regmap = mux->regmap;
+       const char *name = clk_hw_get_name(hw);
        unsigned int reg = mux->reg;
        int clk_id = mux->clk_id;
        int parents[SERDES_NUM_CLOCKS];
                 * This can never happen, unless we missed
                 * a valid combination in serdes_am654_mux_table.
                 */
-               WARN(1, "Failed to find the parent of %s clock\n",
-                    hw->init->name);
+               WARN(1, "Failed to find the parent of %s clock\n", name);
                return -EINVAL;
        }
  
@@@ -405,7 -405,6 +405,7 @@@ static int serdes_am654_clk_register(st
        const __be32 *addr;
        unsigned int reg;
        struct clk *clk;
 +      int ret = 0;
  
        mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
        if (!mux)
        init = &mux->clk_data;
  
        regmap_node = of_parse_phandle(node, "ti,serdes-clk", 0);
 -      of_node_put(regmap_node);
        if (!regmap_node) {
                dev_err(dev, "Fail to get serdes-clk node\n");
 -              return -ENODEV;
 +              ret = -ENODEV;
 +              goto out_put_node;
        }
  
        regmap = syscon_node_to_regmap(regmap_node->parent);
        if (IS_ERR(regmap)) {
                dev_err(dev, "Fail to get Syscon regmap\n");
 -              return PTR_ERR(regmap);
 +              ret = PTR_ERR(regmap);
 +              goto out_put_node;
        }
  
        num_parents = of_clk_get_parent_count(node);
        if (num_parents < 2) {
                dev_err(dev, "SERDES clock must have parents\n");
 -              return -EINVAL;
 +              ret = -EINVAL;
 +              goto out_put_node;
        }
  
        parent_names = devm_kzalloc(dev, (sizeof(char *) * num_parents),
                                    GFP_KERNEL);
 -      if (!parent_names)
 -              return -ENOMEM;
 +      if (!parent_names) {
 +              ret = -ENOMEM;
 +              goto out_put_node;
 +      }
  
        of_clk_parent_fill(node, parent_names, num_parents);
  
        addr = of_get_address(regmap_node, 0, NULL, NULL);
 -      if (!addr)
 -              return -EINVAL;
 +      if (!addr) {
 +              ret = -EINVAL;
 +              goto out_put_node;
 +      }
  
        reg = be32_to_cpu(*addr);
  
        mux->hw.init = init;
  
        clk = devm_clk_register(dev, &mux->hw);
 -      if (IS_ERR(clk))
 -              return PTR_ERR(clk);
 +      if (IS_ERR(clk)) {
 +              ret = PTR_ERR(clk);
 +              goto out_put_node;
 +      }
  
        am654_phy->clks[clock_num] = clk;
  
 -      return 0;
 +out_put_node:
 +      of_node_put(regmap_node);
 +      return ret;
  }
  
  static const struct of_device_id serdes_am654_id_table[] = {
diff --combined include/linux/clk.h
index 853a8f1813947c4e745e0bc4b5c05a9d2197a650,7a795fd6d141188f92e88c4aa32402663cd9615a..18b7b95a8253c775c58920884e2a151df1e670f9
@@@ -239,7 -239,8 +239,8 @@@ static inline int clk_prepare(struct cl
        return 0;
  }
  
- static inline int __must_check clk_bulk_prepare(int num_clks, struct clk_bulk_data *clks)
+ static inline int __must_check
+ clk_bulk_prepare(int num_clks, const struct clk_bulk_data *clks)
  {
        might_sleep();
        return 0;
@@@ -263,7 -264,8 +264,8 @@@ static inline void clk_unprepare(struc
  {
        might_sleep();
  }
- static inline void clk_bulk_unprepare(int num_clks, struct clk_bulk_data *clks)
+ static inline void clk_bulk_unprepare(int num_clks,
+                                     const struct clk_bulk_data *clks)
  {
        might_sleep();
  }
@@@ -359,7 -361,6 +361,7 @@@ int __must_check devm_clk_bulk_get(stru
  /**
   * devm_clk_bulk_get_optional - managed get multiple optional consumer clocks
   * @dev: device for clock "consumer"
 + * @num_clks: the number of clk_bulk_data
   * @clks: pointer to the clk_bulk_data table of consumer
   *
   * Behaves the same as devm_clk_bulk_get() except where there is no clock
@@@ -820,7 -821,8 +822,8 @@@ static inline int clk_enable(struct cl
        return 0;
  }
  
- static inline int __must_check clk_bulk_enable(int num_clks, struct clk_bulk_data *clks)
+ static inline int __must_check clk_bulk_enable(int num_clks,
+                                              const struct clk_bulk_data *clks)
  {
        return 0;
  }
@@@ -829,7 -831,7 +832,7 @@@ static inline void clk_disable(struct c
  
  
  static inline void clk_bulk_disable(int num_clks,
-                                   struct clk_bulk_data *clks) {}
+                                   const struct clk_bulk_data *clks) {}
  
  static inline unsigned long clk_get_rate(struct clk *clk)
  {
@@@ -918,8 -920,8 +921,8 @@@ static inline void clk_disable_unprepar
        clk_unprepare(clk);
  }
  
- static inline int __must_check clk_bulk_prepare_enable(int num_clks,
                                      struct clk_bulk_data *clks)
+ static inline int __must_check
clk_bulk_prepare_enable(int num_clks, const struct clk_bulk_data *clks)
  {
        int ret;
  
  }
  
  static inline void clk_bulk_disable_unprepare(int num_clks,
-                                             struct clk_bulk_data *clks)
+                                             const struct clk_bulk_data *clks)
  {
        clk_bulk_disable(num_clks, clks);
        clk_bulk_unprepare(num_clks, clks);
This page took 0.131848 seconds and 4 git commands to generate.