Merge branch 'clk-parent-rewrite-1' into clk-next
authorStephen Boyd <sboyd@kernel.org>
Tue, 7 May 2019 18:46:13 +0000 (11:46 -0700)
committerStephen Boyd <sboyd@kernel.org>
Tue, 7 May 2019 18:46:13 +0000 (11:46 -0700)
 - Rewrite how clk parents can be specified to be DT/clkdev based instead
   of just string based

* clk-parent-rewrite-1:
  clk: Cache core in clk_fetch_parent_index() without names
  clk: fixed-factor: Initialize clk_init_data on stack
  clk: fixed-factor: Let clk framework find parent
  clk: Allow parents to be specified via clkspec index
  clk: Look for parents with clkdev based clk_lookups
  clk: Allow parents to be specified without string names
  clk: Add of_clk_hw_register() API for early clk drivers
  driver core: Let dev_of_node() accept a NULL dev
  clk: Prepare for clk registration API that uses DT nodes
  clkdev: Move clk creation outside of 'clocks_mutex'

1  2 
drivers/clk/clk-fixed-factor.c
drivers/clk/clk.c
include/linux/clk-provider.h
include/linux/device.h

index 8aac2d1b6feac260f962b8cfab4bbcbdf022d00f,2d988a7585d50c5358c97e976cdf7a23f31db22d..8b343e59dc616e959a78463941868500c7b9da53
@@@ -64,12 -64,14 +64,14 @@@ const struct clk_ops clk_fixed_factor_o
  };
  EXPORT_SYMBOL_GPL(clk_fixed_factor_ops);
  
- struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
-               const char *name, const char *parent_name, unsigned long flags,
-               unsigned int mult, unsigned int div)
+ static struct clk_hw *
+ __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np,
+               const char *name, const char *parent_name, int index,
+               unsigned long flags, unsigned int mult, unsigned int div)
  {
        struct clk_fixed_factor *fix;
-       struct clk_init_data init;
+       struct clk_init_data init = { };
+       struct clk_parent_data pdata = { .index = index };
        struct clk_hw *hw;
        int ret;
  
  
        init.name = name;
        init.ops = &clk_fixed_factor_ops;
 -      init.flags = flags | CLK_IS_BASIC;
 +      init.flags = flags;
-       init.parent_names = &parent_name;
+       if (parent_name)
+               init.parent_names = &parent_name;
+       else
+               init.parent_data = &pdata;
        init.num_parents = 1;
  
        hw = &fix->hw;
-       ret = clk_hw_register(dev, hw);
+       if (dev)
+               ret = clk_hw_register(dev, hw);
+       else
+               ret = of_clk_hw_register(np, hw);
        if (ret) {
                kfree(fix);
                hw = ERR_PTR(ret);
  
        return hw;
  }
+ struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
+               const char *name, const char *parent_name, unsigned long flags,
+               unsigned int mult, unsigned int div)
+ {
+       return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, -1,
+                                             flags, mult, div);
+ }
  EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor);
  
  struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
@@@ -143,11 -159,10 +159,10 @@@ static const struct of_device_id set_ra
        { /* Sentinel */ },
  };
  
- static struct clk *_of_fixed_factor_clk_setup(struct device_node *node)
+ static struct clk_hw *_of_fixed_factor_clk_setup(struct device_node *node)
  {
-       struct clk *clk;
+       struct clk_hw *hw;
        const char *clk_name = node->name;
-       const char *parent_name;
        unsigned long flags = 0;
        u32 div, mult;
        int ret;
        }
  
        of_property_read_string(node, "clock-output-names", &clk_name);
-       parent_name = of_clk_get_parent_name(node, 0);
  
        if (of_match_node(set_rate_parent_matches, node))
                flags |= CLK_SET_RATE_PARENT;
  
-       clk = clk_register_fixed_factor(NULL, clk_name, parent_name, flags,
-                                       mult, div);
-       if (IS_ERR(clk)) {
+       hw = __clk_hw_register_fixed_factor(NULL, node, clk_name, NULL, 0,
+                                           flags, mult, div);
+       if (IS_ERR(hw)) {
                /*
-                * If parent clock is not registered, registration would fail.
                 * Clear OF_POPULATED flag so that clock registration can be
                 * attempted again from probe function.
                 */
                of_node_clear_flag(node, OF_POPULATED);
-               return clk;
+               return ERR_CAST(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_factor(hw);
                return ERR_PTR(ret);
        }
  
-       return clk;
+       return hw;
  }
  
  /**
@@@ -203,17 -216,17 +216,17 @@@ CLK_OF_DECLARE(fixed_factor_clk, "fixed
  
  static int of_fixed_factor_clk_remove(struct platform_device *pdev)
  {
-       struct clk *clk = platform_get_drvdata(pdev);
+       struct clk_hw *clk = platform_get_drvdata(pdev);
  
        of_clk_del_provider(pdev->dev.of_node);
-       clk_unregister_fixed_factor(clk);
+       clk_hw_unregister_fixed_factor(clk);
  
        return 0;
  }
  
  static int of_fixed_factor_clk_probe(struct platform_device *pdev)
  {
-       struct clk *clk;
+       struct clk_hw *clk;
  
        /*
         * This function is not executed when of_fixed_factor_clk_setup
diff --combined drivers/clk/clk.c
index 3e1708747cd2821573175d0dd0dae1955a744dce,dcb7e1cddd2de4b92555e456fe9c4a352db80f8a..aa51756fd4d695b359ee5c6117e7c9d00fddf183
@@@ -39,15 -39,23 +39,23 @@@ static LIST_HEAD(clk_notifier_list)
  
  /***    private data structures    ***/
  
+ struct clk_parent_map {
+       const struct clk_hw     *hw;
+       struct clk_core         *core;
+       const char              *fw_name;
+       const char              *name;
+       int                     index;
+ };
  struct clk_core {
        const char              *name;
        const struct clk_ops    *ops;
        struct clk_hw           *hw;
        struct module           *owner;
        struct device           *dev;
+       struct device_node      *of_node;
        struct clk_core         *parent;
-       const char              **parent_names;
-       struct clk_core         **parents;
+       struct clk_parent_map   *parents;
        u8                      num_parents;
        u8                      new_parent_index;
        unsigned long           rate;
@@@ -316,17 -324,102 +324,102 @@@ static struct clk_core *clk_core_lookup
        return NULL;
  }
  
+ /**
+  * clk_core_get - Find the clk_core parent of a clk
+  * @core: clk to find parent of
+  * @p_index: parent index to search for
+  *
+  * This is the preferred method for clk providers to find the parent of a
+  * clk when that parent is external to the clk controller. The parent_names
+  * array is indexed and treated as a local name matching a string in the device
+  * node's 'clock-names' property or as the 'con_id' matching the device's
+  * dev_name() in a clk_lookup. This allows clk providers to use their own
+  * namespace instead of looking for a globally unique parent string.
+  *
+  * For example the following DT snippet would allow a clock registered by the
+  * clock-controller@c001 that has a clk_init_data::parent_data array
+  * with 'xtal' in the 'name' member to find the clock provided by the
+  * clock-controller@f00abcd without needing to get the globally unique name of
+  * the xtal clk.
+  *
+  *      parent: clock-controller@f00abcd {
+  *              reg = <0xf00abcd 0xabcd>;
+  *              #clock-cells = <0>;
+  *      };
+  *
+  *      clock-controller@c001 {
+  *              reg = <0xc001 0xf00d>;
+  *              clocks = <&parent>;
+  *              clock-names = "xtal";
+  *              #clock-cells = <1>;
+  *      };
+  *
+  * 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.
+  * 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)
+ {
+       const char *name = core->parents[p_index].fw_name;
+       int index = core->parents[p_index].index;
+       struct clk_hw *hw = ERR_PTR(-ENOENT);
+       struct device *dev = core->dev;
+       const char *dev_id = dev ? dev_name(dev) : NULL;
+       struct device_node *np = core->of_node;
+       if (np && 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)
+               hw = clk_find_hw(dev_id, name);
+       if (IS_ERR(hw))
+               return ERR_CAST(hw);
+       return hw->core;
+ }
+ static void clk_core_fill_parent_index(struct clk_core *core, u8 index)
+ {
+       struct clk_parent_map *entry = &core->parents[index];
+       struct clk_core *parent = ERR_PTR(-ENOENT);
+       if (entry->hw) {
+               parent = entry->hw->core;
+               /*
+                * We have a direct reference but it isn't registered yet?
+                * Orphan it and let clk_reparent() update the orphan status
+                * when the parent is registered.
+                */
+               if (!parent)
+                       parent = ERR_PTR(-EPROBE_DEFER);
+       } else {
+               parent = clk_core_get(core, index);
+               if (IS_ERR(parent) && PTR_ERR(parent) == -ENOENT)
+                       parent = clk_core_lookup(entry->name);
+       }
+       /* Only cache it if it's not an error */
+       if (!IS_ERR(parent))
+               entry->core = parent;
+ }
  static struct clk_core *clk_core_get_parent_by_index(struct clk_core *core,
                                                         u8 index)
  {
-       if (!core || index >= core->num_parents)
+       if (!core || index >= core->num_parents || !core->parents)
                return NULL;
  
-       if (!core->parents[index])
-               core->parents[index] =
-                               clk_core_lookup(core->parent_names[index]);
+       if (!core->parents[index].core)
+               clk_core_fill_parent_index(core, index);
  
-       return core->parents[index];
+       return core->parents[index].core;
  }
  
  struct clk_hw *
@@@ -347,18 -440,23 +440,18 @@@ unsigned int __clk_get_enable_count(str
  
  static unsigned long clk_core_get_rate_nolock(struct clk_core *core)
  {
 -      unsigned long ret;
 -
 -      if (!core) {
 -              ret = 0;
 -              goto out;
 -      }
 -
 -      ret = core->rate;
 -
 -      if (!core->num_parents)
 -              goto out;
 +      if (!core)
 +              return 0;
  
 -      if (!core->parent)
 -              ret = 0;
 +      if (!core->num_parents || core->parent)
 +              return core->rate;
  
 -out:
 -      return ret;
 +      /*
 +       * Clk must have a parent because num_parents > 0 but the parent isn't
 +       * known yet. Best to return 0 as the rate of this clk until we can
 +       * properly recalc the rate based on the parent's rate.
 +       */
 +      return 0;
  }
  
  unsigned long clk_hw_get_rate(const struct clk_hw *hw)
@@@ -519,15 -617,9 +612,15 @@@ void clk_hw_set_rate_range(struct clk_h
  EXPORT_SYMBOL_GPL(clk_hw_set_rate_range);
  
  /*
 + * __clk_mux_determine_rate - clk_ops::determine_rate implementation for a mux type clk
 + * @hw: mux type clk to determine rate on
 + * @req: rate request, also used to return preferred parent and frequencies
 + *
   * Helper for finding best parent to provide a given frequency. This can be used
   * directly as a determine_rate callback (e.g. for a mux), or from a more
   * complex clock that may combine a mux with other operations.
 + *
 + * Returns: 0 on success, -EERROR value on error
   */
  int __clk_mux_determine_rate(struct clk_hw *hw,
                             struct clk_rate_request *req)
@@@ -1520,20 -1612,37 +1613,37 @@@ static int clk_fetch_parent_index(struc
                return -EINVAL;
  
        for (i = 0; i < core->num_parents; i++) {
-               if (core->parents[i] == parent)
+               /* Found it first try! */
+               if (core->parents[i].core == parent)
                        return i;
  
-               if (core->parents[i])
+               /* Something else is here, so keep looking */
+               if (core->parents[i].core)
                        continue;
  
-               /* Fallback to comparing globally unique names */
-               if (!strcmp(parent->name, core->parent_names[i])) {
-                       core->parents[i] = parent;
-                       return i;
+               /* Maybe core hasn't been cached but the hw is all we know? */
+               if (core->parents[i].hw) {
+                       if (core->parents[i].hw == parent->hw)
+                               break;
+                       /* Didn't match, but we're expecting a clk_hw */
+                       continue;
                }
+               /* Maybe it hasn't been cached (clk_set_parent() path) */
+               if (parent == clk_core_get(core, i))
+                       break;
+               /* Fallback to comparing globally unique names */
+               if (!strcmp(parent->name, core->parents[i].name))
+                       break;
        }
  
-       return -EINVAL;
+       if (i == core->num_parents)
+               return -EINVAL;
+       core->parents[i].core = parent;
+       return i;
  }
  
  /*
@@@ -2294,6 -2403,7 +2404,7 @@@ void clk_hw_reparent(struct clk_hw *hw
  bool clk_has_parent(struct clk *clk, struct clk *parent)
  {
        struct clk_core *core, *parent_core;
+       int i;
  
        /* NULL clocks should be nops, so return success if either is NULL. */
        if (!clk || !parent)
        if (core->parent == parent_core)
                return true;
  
-       return match_string(core->parent_names, core->num_parents,
-                           parent_core->name) >= 0;
+       for (i = 0; i < core->num_parents; i++)
+               if (!strcmp(core->parents[i].name, parent_core->name))
+                       return true;
+       return false;
  }
  EXPORT_SYMBOL_GPL(clk_has_parent);
  
@@@ -2851,6 -2964,7 +2965,6 @@@ static const struct 
        ENTRY(CLK_SET_PARENT_GATE),
        ENTRY(CLK_SET_RATE_PARENT),
        ENTRY(CLK_IGNORE_UNUSED),
 -      ENTRY(CLK_IS_BASIC),
        ENTRY(CLK_GET_RATE_NOCACHE),
        ENTRY(CLK_SET_RATE_NO_REPARENT),
        ENTRY(CLK_GET_ACCURACY_NOCACHE),
@@@ -2889,9 -3003,9 +3003,9 @@@ static int possible_parents_show(struc
        int i;
  
        for (i = 0; i < core->num_parents - 1; i++)
-               seq_printf(s, "%s ", core->parent_names[i]);
+               seq_printf(s, "%s ", core->parents[i].name);
  
-       seq_printf(s, "%s\n", core->parent_names[i]);
+       seq_printf(s, "%s\n", core->parents[i].name);
  
        return 0;
  }
@@@ -3025,7 -3139,7 +3139,7 @@@ static inline void clk_debug_unregister
   */
  static int __clk_core_init(struct clk_core *core)
  {
-       int i, ret;
+       int ret;
        struct clk_core *orphan;
        struct hlist_node *tmp2;
        unsigned long rate;
                goto out;
        }
  
-       /* throw a WARN if any entries in parent_names are NULL */
-       for (i = 0; i < core->num_parents; i++)
-               WARN(!core->parent_names[i],
-                               "%s: invalid NULL in %s's .parent_names\n",
-                               __func__, core->name);
        core->parent = __clk_init_parent(core);
  
        /*
@@@ -3313,22 -3421,104 +3421,104 @@@ struct clk *clk_hw_create_clk(struct de
        return clk;
  }
  
- /**
-  * clk_register - allocate a new clock, register it and return an opaque cookie
-  * @dev: device that is registering this clock
-  * @hw: link to hardware-specific clock data
-  *
-  * clk_register is the *deprecated* interface for populating the clock tree with
-  * new clock nodes. Use clk_hw_register() instead.
-  *
-  * Returns: a pointer to the newly allocated struct clk which
-  * cannot be dereferenced by driver code but may be used in conjunction with the
-  * rest of the clock API.  In the event of an error clk_register will return an
-  * error code; drivers must test for an error code after calling clk_register.
-  */
- struct clk *clk_register(struct device *dev, struct clk_hw *hw)
+ static int clk_cpy_name(const char **dst_p, const char *src, bool must_exist)
  {
-       int i, ret;
+       const char *dst;
+       if (!src) {
+               if (must_exist)
+                       return -EINVAL;
+               return 0;
+       }
+       *dst_p = dst = kstrdup_const(src, GFP_KERNEL);
+       if (!dst)
+               return -ENOMEM;
+       return 0;
+ }
+ static int clk_core_populate_parent_map(struct clk_core *core)
+ {
+       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;
+       const struct clk_parent_data *parent_data = init->parent_data;
+       int i, ret = 0;
+       struct clk_parent_map *parents, *parent;
+       if (!num_parents)
+               return 0;
+       /*
+        * Avoid unnecessary string look-ups of clk_core's possible parents by
+        * having a cache of names/clk_hw pointers to clk_core pointers.
+        */
+       parents = kcalloc(num_parents, sizeof(*parents), GFP_KERNEL);
+       core->parents = parents;
+       if (!parents)
+               return -ENOMEM;
+       /* Copy everything over because it might be __initdata */
+       for (i = 0, parent = parents; i < num_parents; i++, parent++) {
+               parent->index = -1;
+               if (parent_names) {
+                       /* throw a WARN if any entries are NULL */
+                       WARN(!parent_names[i],
+                               "%s: invalid NULL in %s's .parent_names\n",
+                               __func__, core->name);
+                       ret = clk_cpy_name(&parent->name, parent_names[i],
+                                          true);
+               } else if (parent_data) {
+                       parent->hw = parent_data[i].hw;
+                       parent->index = parent_data[i].index;
+                       ret = clk_cpy_name(&parent->fw_name,
+                                          parent_data[i].fw_name, false);
+                       if (!ret)
+                               ret = clk_cpy_name(&parent->name,
+                                                  parent_data[i].name,
+                                                  false);
+               } else if (parent_hws) {
+                       parent->hw = parent_hws[i];
+               } else {
+                       ret = -EINVAL;
+                       WARN(1, "Must specify parents if num_parents > 0\n");
+               }
+               if (ret) {
+                       do {
+                               kfree_const(parents[i].name);
+                               kfree_const(parents[i].fw_name);
+                       } while (--i >= 0);
+                       kfree(parents);
+                       return ret;
+               }
+       }
+       return 0;
+ }
+ static void clk_core_free_parent_map(struct clk_core *core)
+ {
+       int i = core->num_parents;
+       if (!core->num_parents)
+               return;
+       while (--i >= 0) {
+               kfree_const(core->parents[i].name);
+               kfree_const(core->parents[i].fw_name);
+       }
+       kfree(core->parents);
+ }
+ static struct clk *
+ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
+ {
+       int ret;
        struct clk_core *core;
  
        core = kzalloc(sizeof(*core), GFP_KERNEL);
        if (dev && pm_runtime_enabled(dev))
                core->rpm_enabled = true;
        core->dev = dev;
+       core->of_node = np;
        if (dev && dev->driver)
                core->owner = dev->driver->owner;
        core->hw = hw;
        core->max_rate = ULONG_MAX;
        hw->core = core;
  
-       /* allocate local copy in case parent_names is __initdata */
-       core->parent_names = kcalloc(core->num_parents, sizeof(char *),
-                                       GFP_KERNEL);
-       if (!core->parent_names) {
-               ret = -ENOMEM;
-               goto fail_parent_names;
-       }
-       /* copy each string name in case parent_names is __initdata */
-       for (i = 0; i < core->num_parents; i++) {
-               core->parent_names[i] = kstrdup_const(hw->init->parent_names[i],
-                                               GFP_KERNEL);
-               if (!core->parent_names[i]) {
-                       ret = -ENOMEM;
-                       goto fail_parent_names_copy;
-               }
-       }
-       /* avoid unnecessary string look-ups of clk_core's possible parents. */
-       core->parents = kcalloc(core->num_parents, sizeof(*core->parents),
-                               GFP_KERNEL);
-       if (!core->parents) {
-               ret = -ENOMEM;
+       ret = clk_core_populate_parent_map(core);
+       if (ret)
                goto fail_parents;
-       };
  
        INIT_HLIST_HEAD(&core->clks);
  
        hw->clk = alloc_clk(core, NULL, NULL);
        if (IS_ERR(hw->clk)) {
                ret = PTR_ERR(hw->clk);
-               goto fail_parents;
+               goto fail_create_clk;
        }
  
        clk_core_link_consumer(hw->core, hw->clk);
        free_clk(hw->clk);
        hw->clk = NULL;
  
+ fail_create_clk:
+       clk_core_free_parent_map(core);
  fail_parents:
-       kfree(core->parents);
- fail_parent_names_copy:
-       while (--i >= 0)
-               kfree_const(core->parent_names[i]);
-       kfree(core->parent_names);
- fail_parent_names:
  fail_ops:
        kfree_const(core->name);
  fail_name:
  fail_out:
        return ERR_PTR(ret);
  }
 - * clk_register is the primary interface for populating the clock tree with new
 - * clock nodes.  It returns a pointer to the newly allocated struct clk which
+ /**
+  * clk_register - allocate a new clock, register it and return an opaque cookie
+  * @dev: device that is registering this clock
+  * @hw: link to hardware-specific clock data
+  *
++ * clk_register is the *deprecated* interface for populating the clock tree with
++ * new clock nodes. Use clk_hw_register() instead.
++ *
++ * Returns: a pointer to the newly allocated struct clk which
+  * cannot be dereferenced by driver code but may be used in conjunction with the
+  * rest of the clock API.  In the event of an error clk_register will return an
+  * error code; drivers must test for an error code after calling clk_register.
+  */
+ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
+ {
+       return __clk_register(dev, dev_of_node(dev), hw);
+ }
  EXPORT_SYMBOL_GPL(clk_register);
  
  /**
   */
  int clk_hw_register(struct device *dev, struct clk_hw *hw)
  {
-       return PTR_ERR_OR_ZERO(clk_register(dev, hw));
+       return PTR_ERR_OR_ZERO(__clk_register(dev, dev_of_node(dev), hw));
  }
  EXPORT_SYMBOL_GPL(clk_hw_register);
  
+ /*
+  * of_clk_hw_register - register a clk_hw and return an error code
+  * @node: device_node of device that is registering this clock
+  * @hw: link to hardware-specific clock data
+  *
+  * of_clk_hw_register() is the primary interface for populating the clock tree
+  * with new clock nodes when a struct device is not available, but a struct
+  * device_node is. It returns an integer equal to zero indicating success or
+  * less than zero indicating failure. Drivers must test for an error code after
+  * calling of_clk_hw_register().
+  */
+ int of_clk_hw_register(struct device_node *node, struct clk_hw *hw)
+ {
+       return PTR_ERR_OR_ZERO(__clk_register(NULL, node, hw));
+ }
+ EXPORT_SYMBOL_GPL(of_clk_hw_register);
  /* Free memory allocated for a clock. */
  static void __clk_release(struct kref *ref)
  {
        struct clk_core *core = container_of(ref, struct clk_core, ref);
-       int i = core->num_parents;
  
        lockdep_assert_held(&prepare_lock);
  
-       kfree(core->parents);
-       while (--i >= 0)
-               kfree_const(core->parent_names[i]);
-       kfree(core->parent_names);
+       clk_core_free_parent_map(core);
        kfree_const(core->name);
        kfree(core);
  }
@@@ -3577,10 -3768,9 +3770,10 @@@ static void devm_clk_hw_release(struct 
   * @dev: device that is registering this clock
   * @hw: link to hardware-specific clock data
   *
 - * Managed clk_register(). Clocks returned from this function are
 - * automatically clk_unregister()ed on driver detach. See clk_register() for
 - * more information.
 + * Managed clk_register(). This function is *deprecated*, use devm_clk_hw_register() instead.
 + *
 + * Clocks returned from this function are automatically clk_unregister()ed on
 + * driver detach. See clk_register() for more information.
   */
  struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw)
  {
@@@ -3898,8 -4088,6 +4091,8 @@@ EXPORT_SYMBOL_GPL(of_clk_hw_onecell_get
   * @np: Device node pointer associated with clock provider
   * @clk_src_get: callback for decoding clock
   * @data: context pointer for @clk_src_get callback.
 + *
 + * This function is *deprecated*. Use of_clk_add_hw_provider() instead.
   */
  int of_clk_add_provider(struct device_node *np,
                        struct clk *(*clk_src_get)(struct of_phandle_args *clkspec,
index 8fa494aaa34dee5be721d2dd066a63f67f5f653e,27d8f96dd28348b8c365782beff890ffb479b60a..491d992d045d4fded2cf11397de471efcbb51cc9
@@@ -24,7 -24,7 +24,7 @@@
  #define CLK_SET_RATE_PARENT   BIT(2) /* propagate rate change up one level */
  #define CLK_IGNORE_UNUSED     BIT(3) /* do not gate even if unused */
                                /* unused */
 -#define CLK_IS_BASIC          BIT(5) /* Basic clk, can't do a to_clk_foo() */
 +                              /* unused */
  #define CLK_GET_RATE_NOCACHE  BIT(6) /* do not use the cached clk rate */
  #define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */
  #define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */
@@@ -250,6 -250,20 +250,20 @@@ struct clk_ops 
        void            (*debug_init)(struct clk_hw *hw, struct dentry *dentry);
  };
  
+ /**
+  * struct clk_parent_data - clk parent information
+  * @hw: parent clk_hw pointer (used for clk providers with internal clks)
+  * @fw_name: parent name local to provider registering clk
+  * @name: globally unique parent name (used as a fallback)
+  * @index: parent index local to provider registering clk (if @fw_name absent)
+  */
+ struct clk_parent_data {
+       const struct clk_hw     *hw;
+       const char              *fw_name;
+       const char              *name;
+       int                     index;
+ };
  /**
   * struct clk_init_data - holds init data that's common to all clocks and is
   * shared between the clock provider and the common clock framework.
   * @name: clock name
   * @ops: operations this clock supports
   * @parent_names: array of string names for all possible parents
+  * @parent_data: array of parent data for all possible parents (when some
+  *               parents are external to the clk controller)
+  * @parent_hws: array of pointers to all possible parents (when all parents
+  *              are internal to the clk controller)
   * @num_parents: number of possible parents
   * @flags: framework-level hints and quirks
   */
  struct clk_init_data {
        const char              *name;
        const struct clk_ops    *ops;
+       /* Only one of the following three should be assigned */
        const char              * const *parent_names;
+       const struct clk_parent_data    *parent_data;
+       const struct clk_hw             **parent_hws;
        u8                      num_parents;
        unsigned long           flags;
  };
@@@ -307,6 -328,7 +328,6 @@@ struct clk_fixed_rate 
        struct          clk_hw hw;
        unsigned long   fixed_rate;
        unsigned long   fixed_accuracy;
 -      u8              flags;
  };
  
  #define to_clk_fixed_rate(_hw) container_of(_hw, struct clk_fixed_rate, hw)
@@@ -348,9 -370,6 +369,9 @@@ void of_fixed_clk_setup(struct device_n
   *    of this register, and mask of gate bits are in higher 16-bit of this
   *    register.  While setting the gate bits, higher 16-bit should also be
   *    updated to indicate changing gate bits.
 + * CLK_GATE_BIG_ENDIAN - by default little endian register accesses are used for
 + *    the gate register.  Setting this flag makes the register accesses big
 + *    endian.
   */
  struct clk_gate {
        struct clk_hw hw;
  
  #define CLK_GATE_SET_TO_DISABLE               BIT(0)
  #define CLK_GATE_HIWORD_MASK          BIT(1)
 +#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,
@@@ -420,9 -438,6 +441,9 @@@ struct clk_div_table 
   * CLK_DIVIDER_MAX_AT_ZERO - For dividers which are like CLK_DIVIDER_ONE_BASED
   *    except when the value read from the register is zero, the divisor is
   *    2^width of the field.
 + * CLK_DIVIDER_BIG_ENDIAN - By default little endian register accesses are used
 + *    for the divider register.  Setting this flag makes the register accesses
 + *    big endian.
   */
  struct clk_divider {
        struct clk_hw   hw;
  #define CLK_DIVIDER_ROUND_CLOSEST     BIT(4)
  #define CLK_DIVIDER_READ_ONLY         BIT(5)
  #define CLK_DIVIDER_MAX_AT_ZERO               BIT(6)
 +#define CLK_DIVIDER_BIG_ENDIAN                BIT(7)
  
  extern const struct clk_ops clk_divider_ops;
  extern const struct clk_ops clk_divider_ro_ops;
@@@ -506,13 -520,8 +527,13 @@@ void clk_hw_unregister_divider(struct c
   *    register, and mask of mux bits are in higher 16-bit of this register.
   *    While setting the mux bits, higher 16-bit should also be updated to
   *    indicate changing mux bits.
 + * CLK_MUX_READ_ONLY - The mux registers can't be written, only read in the
 + *    .get_parent clk_op.
   * CLK_MUX_ROUND_CLOSEST - Use the parent rate that is closest to the desired
   *    frequency.
 + * CLK_MUX_BIG_ENDIAN - By default little endian register accesses are used for
 + *    the mux register.  Setting this flag makes the register accesses big
 + *    endian.
   */
  struct clk_mux {
        struct clk_hw   hw;
  #define CLK_MUX_HIWORD_MASK           BIT(2)
  #define CLK_MUX_READ_ONLY             BIT(3) /* mux can't be changed */
  #define CLK_MUX_ROUND_CLOSEST         BIT(4)
 +#define CLK_MUX_BIG_ENDIAN            BIT(5)
  
  extern const struct clk_ops clk_mux_ops;
  extern const struct clk_ops clk_mux_ro_ops;
@@@ -615,9 -623,6 +636,9 @@@ void clk_hw_unregister_fixed_factor(str
   *    is the value read from the register. If CLK_FRAC_DIVIDER_ZERO_BASED
   *    is set then the numerator and denominator are both the value read
   *    plus one.
 + * CLK_FRAC_DIVIDER_BIG_ENDIAN - By default little endian register accesses are
 + *    used for the divider register.  Setting this flag makes the register
 + *    accesses big endian.
   */
  struct clk_fractional_divider {
        struct clk_hw   hw;
  #define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw)
  
  #define CLK_FRAC_DIVIDER_ZERO_BASED           BIT(0)
 +#define CLK_FRAC_DIVIDER_BIG_ENDIAN           BIT(1)
  
  extern const struct clk_ops clk_fractional_divider_ops;
  struct clk *clk_register_fractional_divider(struct device *dev,
@@@ -671,9 -675,6 +692,9 @@@ void clk_hw_unregister_fractional_divid
   *    leaving the parent rate unmodified.
   * CLK_MULTIPLIER_ROUND_CLOSEST - Makes the best calculated divider to be
   *    rounded to the closest integer instead of the down one.
 + * CLK_MULTIPLIER_BIG_ENDIAN - By default little endian register accesses are
 + *    used for the multiplier register.  Setting this flag makes the register
 + *    accesses big endian.
   */
  struct clk_multiplier {
        struct clk_hw   hw;
  
  #define CLK_MULTIPLIER_ZERO_BYPASS            BIT(0)
  #define CLK_MULTIPLIER_ROUND_CLOSEST  BIT(1)
 +#define CLK_MULTIPLIER_BIG_ENDIAN             BIT(2)
  
  extern const struct clk_ops clk_multiplier_ops;
  
@@@ -733,19 -733,16 +754,19 @@@ struct clk_hw *clk_hw_register_composit
                unsigned long flags);
  void clk_hw_unregister_composite(struct clk_hw *hw);
  
 -/***
 - * struct clk_gpio_gate - gpio gated clock
 +/**
 + * 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.
 - * Implements .enable, .disable and .is_enabled
 + * 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;
@@@ -762,6 -759,16 +783,6 @@@ struct clk_hw *clk_hw_register_gpio_gat
                unsigned long flags);
  void clk_hw_unregister_gpio_gate(struct clk_hw *hw);
  
 -/**
 - * struct clk_gpio_mux - gpio controlled clock multiplexer
 - *
 - * @hw:               see struct clk_gpio
 - * @gpiod:    gpio descriptor to select the parent of this clock multiplexer
 - *
 - * Clock with a gpio control for selecting the parent clock.
 - * Implements .get_parent, .set_parent and .determine_rate
 - */
 -
  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,
@@@ -771,11 -778,23 +792,12 @@@ struct clk_hw *clk_hw_register_gpio_mux
                unsigned long flags);
  void clk_hw_unregister_gpio_mux(struct clk_hw *hw);
  
 -/**
 - * clk_register - allocate a new clock, register it and return an opaque cookie
 - * @dev: device that is registering this clock
 - * @hw: link to hardware-specific clock data
 - *
 - * clk_register is the primary interface for populating the clock tree with new
 - * clock nodes.  It returns a pointer to the newly allocated struct clk which
 - * cannot be dereferenced by driver code but may be used in conjuction with the
 - * rest of the clock API.  In the event of an error clk_register will return an
 - * error code; drivers must test for an error code after calling clk_register.
 - */
  struct clk *clk_register(struct device *dev, struct clk_hw *hw);
  struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw);
  
  int __must_check clk_hw_register(struct device *dev, struct clk_hw *hw);
  int __must_check devm_clk_hw_register(struct device *dev, struct clk_hw *hw);
+ int __must_check of_clk_hw_register(struct device_node *node, struct clk_hw *hw);
  
  void clk_unregister(struct clk *clk);
  void devm_clk_unregister(struct device *dev, struct clk *clk);
@@@ -996,6 -1015,37 +1018,6 @@@ static inline int of_clk_detect_critica
  }
  #endif /* CONFIG_OF */
  
 -/*
 - * wrap access to peripherals in accessor routines
 - * for improved portability across platforms
 - */
 -
 -#if IS_ENABLED(CONFIG_PPC)
 -
 -static inline u32 clk_readl(u32 __iomem *reg)
 -{
 -      return ioread32be(reg);
 -}
 -
 -static inline void clk_writel(u32 val, u32 __iomem *reg)
 -{
 -      iowrite32be(val, reg);
 -}
 -
 -#else /* platform dependent I/O accessors */
 -
 -static inline u32 clk_readl(u32 __iomem *reg)
 -{
 -      return readl(reg);
 -}
 -
 -static inline void clk_writel(u32 val, u32 __iomem *reg)
 -{
 -      writel(val, reg);
 -}
 -
 -#endif        /* platform dependent I/O accessors */
 -
  void clk_gate_restore_context(struct clk_hw *hw);
  
  #endif /* CONFIG_COMMON_CLK */
diff --combined include/linux/device.h
index 4e6987e11f688bc12001cc4d030e8a3a99faa514,0370dd0b3ae7dbdd4b7e79ac154721d45cdd3468..ad626df2e12e2607f6c7a97b687191a73aa0f995
@@@ -49,6 -49,8 +49,6 @@@ struct bus_attribute 
        ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count);
  };
  
 -#define BUS_ATTR(_name, _mode, _show, _store) \
 -      struct bus_attribute bus_attr_##_name = __ATTR(_name, _mode, _show, _store)
  #define BUS_ATTR_RW(_name) \
        struct bus_attribute bus_attr_##_name = __ATTR_RW(_name)
  #define BUS_ATTR_RO(_name) \
@@@ -1229,7 -1231,7 +1229,7 @@@ static inline void device_lock_assert(s
  
  static inline struct device_node *dev_of_node(struct device *dev)
  {
-       if (!IS_ENABLED(CONFIG_OF))
+       if (!IS_ENABLED(CONFIG_OF) || !dev)
                return NULL;
        return dev->of_node;
  }