Merge branches 'clk-cdce-regulator', 'clk-bcm', 'clk-evict-parent-cache' and 'clk...
authorStephen Boyd <sboyd@kernel.org>
Thu, 19 Sep 2019 22:31:46 +0000 (15:31 -0700)
committerStephen Boyd <sboyd@kernel.org>
Thu, 19 Sep 2019 22:31:46 +0000 (15:31 -0700)
 - Add regulator support to the cdce925 clk driver
 - Add support for Raspberry Pi 4 bcm2711 SoCs
 - Evict parents from parent cache when they're unregistered

* clk-cdce-regulator:
  clk: clk-cdce925: Add regulator support
  dt-bindings: clock: cdce925: Add regulator documentation

* clk-bcm:
  clk: bcm2835: Mark PLLD_PER as CRITICAL
  clk: bcm2835: Add BCM2711_CLOCK_EMMC2 support
  clk: bcm2835: Introduce SoC specific clock registration
  dt-bindings: bcm2835-cprman: Add bcm2711 support

* clk-evict-parent-cache:
  clk: Evict unregistered clks from parent caches

* clk-actions:
  clk: actions: Fix factor clk struct member access

1  2  3  4  5 
drivers/clk/clk.c

diff --combined drivers/clk/clk.c
index e7300e1094b978b89dd2b8fab832156b2db1b67d,c0990703ce5403c1092bda6d982c56dffd70e6a0,c0990703ce5403c1092bda6d982c56dffd70e6a0,f9076c74bf0d81684cfc2dbe2a83f7fca12caf48,c0990703ce5403c1092bda6d982c56dffd70e6a0..498cae518147d83a1aee9fb64f3f292911df933d
@@@@@@ -37,6 -37,6 -37,6 -37,12 -37,6 +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 {
@@@@@@ -593,8 -593,6 -593,6 -599,6 -593,6 +599,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;
     
@@@@@@ -2439,7 -2437,7 -2437,7 -2443,7 -2437,7 +2445,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;
     
@@@@@@ -2489,12 -2487,6 -2487,6 -2493,6 -2487,6 +2495,12 @@@@@@ runtime_put
        return ret;
     }
     
 ++++int clk_hw_set_parent(struct clk_hw *hw, struct clk_hw *parent)
 ++++{
 ++++   return clk_core_set_parent_nolock(hw->core, parent->core);
 ++++}
 ++++EXPORT_SYMBOL_GPL(clk_hw_set_parent);
 ++++
     /**
      * clk_set_parent - switch the parent of a mux clk
      * @clk: the mux clk whose input we are switching
@@@@@@ -2841,12 -2833,12 -2833,12 -2839,6 -2833,12 +2847,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,
@@@@@@ -2869,6 -2864,9 -2864,9 -2864,9 -2864,9 +2869,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)
@@@@@@ -2898,9 -2896,8 -2896,8 -2896,8 -2896,8 +2898,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",
@@@@@@ -2920,6 -2915,9 -2915,9 -2915,9 -2915,9 +2920,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) {
@@@@@@ -3015,15 -3013,15 -3013,15 -3013,15 -3013,15 +3015,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)");
     
@@@@@@ -3066,34 -3064,6 -3064,6 -3064,6 -3064,6 +3066,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);
@@@@@@ -3516,9 -3484,9 -3484,9 -3484,9 -3484,9 +3516,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;
@@@@@@ -3598,14 -3566,6 -3566,6 -3566,6 -3566,6 +3598,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;
     
@@@@@@ -3777,6 -3737,6 -3737,6 -3737,34 -3737,6 +3777,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
@@@@@@ -3815,6 -3775,6 -3775,6 -3803,8 -3775,6 +3843,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)
@@@@@@ -4356,43 -4316,12 -4316,12 -4346,12 -4316,12 +4386,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)