* [PATCH 1/4] clk: clk-gpio: Turn into driver
2023-03-22 8:32 [PATCH 0/4] Allow to probe clks added in overlays Sascha Hauer
@ 2023-03-22 8:32 ` Sascha Hauer
2023-03-22 8:32 ` [PATCH 2/4] clk: of: drop arguments from of_clk_init() Sascha Hauer
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2023-03-22 8:32 UTC (permalink / raw)
To: Barebox List
A comment states OF_CLK_DECLARE can't be used for the clk-gpio driver
as it needs to be registered after the GPIO controllers. If that's the
case there is no point in calling of_clk_init() directly from an
initcall. We can better register it as a regular driver which also
makes deep probe work.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/clk/clk-gpio.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c
index 6ac2e820fa..8cc0c5fc97 100644
--- a/drivers/clk/clk-gpio.c
+++ b/drivers/clk/clk-gpio.c
@@ -50,8 +50,9 @@ static struct clk_ops clk_gpio_ops = {
.is_enabled = clk_gpio_is_enabled,
};
-static int of_gpio_clk_setup(struct device_node *node)
+static int of_gpio_clk_probe(struct device *dev)
{
+ struct device_node *node = dev->device_node;
struct clk_gpio *clk_gpio;
enum of_gpio_flags of_flags;
unsigned long flags;
@@ -105,16 +106,15 @@ no_parent:
return ret;
}
-/* Can't use OF_CLK_DECLARE due to need to run after GPIOcontrollers have
- * registrered */
-
static const struct of_device_id clk_gpio_device_id[] = {
- { .compatible = "gpio-gate-clock", .data = of_gpio_clk_setup, },
+ { .compatible = "gpio-gate-clock", },
{}
};
-static int clk_gpio_init(void)
-{
- return of_clk_init(NULL, clk_gpio_device_id);
-}
-coredevice_initcall(clk_gpio_init);
+static struct driver gpio_gate_clock_driver = {
+ .probe = of_gpio_clk_probe,
+ .name = "gpio-gate-clock",
+ .of_compatible = DRV_OF_COMPAT(clk_gpio_device_id),
+};
+
+core_platform_driver(gpio_gate_clock_driver);
--
2.30.2
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/4] clk: of: drop arguments from of_clk_init()
2023-03-22 8:32 [PATCH 0/4] Allow to probe clks added in overlays Sascha Hauer
2023-03-22 8:32 ` [PATCH 1/4] clk: clk-gpio: Turn into driver Sascha Hauer
@ 2023-03-22 8:32 ` Sascha Hauer
2023-03-22 8:32 ` [PATCH 3/4] clk: of: make of_clk_init() safe for being called multiple times Sascha Hauer
2023-03-22 8:32 ` [PATCH 4/4] commands: of_overlay: Allow to register clocks from overlay Sascha Hauer
3 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2023-03-22 8:32 UTC (permalink / raw)
To: Barebox List
of_clk_init() should be used to register clock drivers declared with
CLK_OF_DECLARE and nothing else, so there shouldn't be a need to call
it with a non NULL "matches" argument.
Also there is no point in calling this function with another device tree
than the barebox live tree.
Drop both arguments.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/clk/clk.c | 10 +++-------
drivers/of/base.c | 2 +-
include/linux/clk.h | 5 ++---
3 files changed, 6 insertions(+), 11 deletions(-)
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 30fe43032b..c7ee6878c2 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -849,28 +849,24 @@ static int parent_ready(struct device_node *np)
/**
* of_clk_init() - Scan and init clock providers from the DT
- * @root: parent of the first level to probe or NULL for the root of the tree
- * @matches: array of compatible values and init functions for providers.
*
* This function scans the device tree for matching clock providers and
* calls their initialization functions
*
* Returns 0 on success, < 0 on failure.
*/
-int of_clk_init(struct device_node *root, const struct of_device_id *matches)
+int of_clk_init(void)
{
+ struct device_node *root = of_get_root_node();
+ const struct of_device_id *matches = __clk_of_table_start;
struct clock_provider *clk_provider, *next;
bool is_init_done;
bool force = false;
LIST_HEAD(clk_provider_list);
const struct of_device_id *match;
- if (!root)
- root = of_find_node_by_path("/");
if (!root)
return -EINVAL;
- if (!matches)
- matches = __clk_of_table_start;
/* First prepare the list of the clocks providers */
for_each_matching_node_and_match(root, matches, &match) {
diff --git a/drivers/of/base.c b/drivers/of/base.c
index ea4be9c512..acebba29a1 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1757,7 +1757,7 @@ int barebox_register_of(struct device_node *root)
of_fix_tree(root);
if (IS_ENABLED(CONFIG_OFDEVICE)) {
- of_clk_init(root, NULL);
+ of_clk_init();
if (!deep_probe_is_supported())
return of_probe();
}
diff --git a/include/linux/clk.h b/include/linux/clk.h
index bffed2bdcf..29c697a00b 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -686,7 +686,7 @@ struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec);
unsigned int of_clk_get_parent_count(struct device_node *np);
int of_clk_parent_fill(struct device_node *np, const char **parents,
unsigned int size);
-int of_clk_init(struct device_node *root, const struct of_device_id *matches);
+int of_clk_init(void);
int of_clk_add_provider(struct device_node *np,
struct clk *(*clk_src_get)(struct of_phandle_args *args,
void *data),
@@ -742,8 +742,7 @@ static inline unsigned int of_clk_get_parent_count(struct device_node *np)
{
return 0;
}
-static inline int of_clk_init(struct device_node *root,
- const struct of_device_id *matches)
+static inline int of_clk_init(void)
{
return 0;
}
--
2.30.2
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 3/4] clk: of: make of_clk_init() safe for being called multiple times
2023-03-22 8:32 [PATCH 0/4] Allow to probe clks added in overlays Sascha Hauer
2023-03-22 8:32 ` [PATCH 1/4] clk: clk-gpio: Turn into driver Sascha Hauer
2023-03-22 8:32 ` [PATCH 2/4] clk: of: drop arguments from of_clk_init() Sascha Hauer
@ 2023-03-22 8:32 ` Sascha Hauer
2023-03-22 8:32 ` [PATCH 4/4] commands: of_overlay: Allow to register clocks from overlay Sascha Hauer
3 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2023-03-22 8:32 UTC (permalink / raw)
To: Barebox List
Applying device tree overlays to the barebox live tree currently works
for devices handled by regular drivers, but not for clocks which do
not have a regular driver, but instead are declared with CLK_OF_DECLARE.
To support adding such clocks with a device tree overlay we have to
call of_clk_init() again. This patch makes of_clk_init() safe for being
called multiple times. For this we have to make sure we do not register
clocks for nodes which already have a clock.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/clk/clk.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index c7ee6878c2..7406dba260 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -847,6 +847,18 @@ static int parent_ready(struct device_node *np)
}
}
+static LIST_HEAD(probed_clks);
+
+static bool of_clk_probed(struct device_node *np)
+{
+ struct clock_provider *clk_provider;
+
+ list_for_each_entry(clk_provider, &probed_clks, node)
+ if (clk_provider->np == np)
+ return true;
+ return false;
+}
+
/**
* of_clk_init() - Scan and init clock providers from the DT
*
@@ -875,6 +887,11 @@ int of_clk_init(void)
if (!of_device_is_available(root))
continue;
+ if (of_clk_probed(root)) {
+ pr_debug("%s: already probed: %pOF\n", __func__, root);
+ continue;
+ }
+
parent = xzalloc(sizeof(*parent));
parent->clk_init_cb = match->data;
@@ -894,8 +911,7 @@ int of_clk_init(void)
clk_provider->clk_init_cb(np);
of_clk_set_defaults(np, true);
- list_del(&clk_provider->node);
- free(clk_provider);
+ list_move_tail(&clk_provider->node, &probed_clks);
is_init_done = true;
}
}
--
2.30.2
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 4/4] commands: of_overlay: Allow to register clocks from overlay
2023-03-22 8:32 [PATCH 0/4] Allow to probe clks added in overlays Sascha Hauer
` (2 preceding siblings ...)
2023-03-22 8:32 ` [PATCH 3/4] clk: of: make of_clk_init() safe for being called multiple times Sascha Hauer
@ 2023-03-22 8:32 ` Sascha Hauer
2023-03-22 9:25 ` Sascha Hauer
3 siblings, 1 reply; 6+ messages in thread
From: Sascha Hauer @ 2023-03-22 8:32 UTC (permalink / raw)
To: Barebox List
When clocks are added from an overlay calling of_probe() is enough
for devices handled by regular drivers, but not for clocks declared
with CLK_OF_DECLARE(). Additionally call of_clk_init() to support
these as well.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
commands/of_overlay.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/commands/of_overlay.c b/commands/of_overlay.c
index 37d29b88e5..1bd54a7b10 100644
--- a/commands/of_overlay.c
+++ b/commands/of_overlay.c
@@ -10,6 +10,7 @@
#include <getopt.h>
#include <libfile.h>
#include <of.h>
+#include <linux/clk.h>
static int do_of_overlay(int argc, char *argv[])
{
@@ -49,8 +50,11 @@ static int do_of_overlay(int argc, char *argv[])
if (live_tree) {
ret = of_overlay_apply_tree(of_get_root_node(), overlay);
- if (!ret)
- ret = of_probe();
+ if (ret)
+ goto err;
+
+ of_probe();
+ of_clk_init();
} else {
ret = of_register_overlay(overlay);
}
--
2.30.2
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 4/4] commands: of_overlay: Allow to register clocks from overlay
2023-03-22 8:32 ` [PATCH 4/4] commands: of_overlay: Allow to register clocks from overlay Sascha Hauer
@ 2023-03-22 9:25 ` Sascha Hauer
0 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2023-03-22 9:25 UTC (permalink / raw)
To: Barebox List
On Wed, Mar 22, 2023 at 09:32:45AM +0100, Sascha Hauer wrote:
> When clocks are added from an overlay calling of_probe() is enough
> for devices handled by regular drivers, but not for clocks declared
> with CLK_OF_DECLARE(). Additionally call of_clk_init() to support
> these as well.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> commands/of_overlay.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/commands/of_overlay.c b/commands/of_overlay.c
> index 37d29b88e5..1bd54a7b10 100644
> --- a/commands/of_overlay.c
> +++ b/commands/of_overlay.c
> @@ -10,6 +10,7 @@
> #include <getopt.h>
> #include <libfile.h>
> #include <of.h>
> +#include <linux/clk.h>
>
> static int do_of_overlay(int argc, char *argv[])
> {
> @@ -49,8 +50,11 @@ static int do_of_overlay(int argc, char *argv[])
>
> if (live_tree) {
> ret = of_overlay_apply_tree(of_get_root_node(), overlay);
> - if (!ret)
> - ret = of_probe();
> + if (ret)
> + goto err;
> +
> + of_probe();
> + of_clk_init();
Just realized we better call of_clk_init() first in case the just added
clock is really used by the devices added in the overlay.
Sascha
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 6+ messages in thread