From a2c6016f927e4b9a23499005c63f3e46f48ff8a2 Mon Sep 17 00:00:00 2001 From: Ghennadi Procopciuc Date: Mon, 3 Jun 2024 09:16:41 +0300 Subject: [PATCH 1/2] feat(clk): add set_parent callback This callback will be used to set a clock's parent if the underlying clock driver supports this option. Change-Id: Ie8a77d17dd3cc867bd520217b481cd188317a9c9 Signed-off-by: Ghennadi Procopciuc --- drivers/clk/clk.c | 7 +++++++ include/drivers/clk.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 4cbc0f70f..4395c3c24 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -41,6 +41,13 @@ int clk_get_parent(unsigned long id) return ops->get_parent(id); } +int clk_set_parent(unsigned long id, unsigned long parent_id) +{ + assert((ops != NULL) && (ops->set_parent != NULL)); + + return ops->set_parent(id, parent_id); +} + bool clk_is_enabled(unsigned long id) { assert((ops != NULL) && (ops->is_enabled != NULL)); diff --git a/include/drivers/clk.h b/include/drivers/clk.h index a18f41ffc..d4cc90da0 100644 --- a/include/drivers/clk.h +++ b/include/drivers/clk.h @@ -14,6 +14,7 @@ struct clk_ops { void (*disable)(unsigned long id); unsigned long (*get_rate)(unsigned long id); int (*get_parent)(unsigned long id); + int (*set_parent)(unsigned long id, unsigned long parent_id); bool (*is_enabled)(unsigned long id); }; @@ -22,6 +23,7 @@ void clk_disable(unsigned long id); unsigned long clk_get_rate(unsigned long id); bool clk_is_enabled(unsigned long id); int clk_get_parent(unsigned long id); +int clk_set_parent(unsigned long id, unsigned long parent_id); void clk_register(const struct clk_ops *ops); From 19f9e2e657918d023c9836f8330a967e97a45d7e Mon Sep 17 00:00:00 2001 From: Ghennadi Procopciuc Date: Sat, 1 Jun 2024 00:04:31 +0300 Subject: [PATCH 2/2] feat(clk): add set_rate callback This callback will be used to set a clock's rate if the underlying clock driver supports this option. The function's last parameter is an output parameter, storing the actual frequency set by the clock driver, as it may not precisely match the requested rate in some cases. Change-Id: I6a399bf6f64407d5fbff36407561e4bf18104cf1 Signed-off-by: Ghennadi Procopciuc --- drivers/clk/clk.c | 14 ++++++++++++++ include/drivers/clk.h | 3 +++ 2 files changed, 17 insertions(+) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 4395c3c24..3e87efcb2 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -34,6 +34,20 @@ unsigned long clk_get_rate(unsigned long id) return ops->get_rate(id); } +int clk_set_rate(unsigned long id, unsigned long rate, unsigned long *orate) +{ + unsigned long lrate; + + assert((ops != NULL) && (ops->set_rate != NULL)); + + if (orate != NULL) { + return ops->set_rate(id, rate, orate); + } + + /* In case the caller is not interested in the output rate */ + return ops->set_rate(id, rate, &lrate); +} + int clk_get_parent(unsigned long id) { assert((ops != NULL) && (ops->get_parent != NULL)); diff --git a/include/drivers/clk.h b/include/drivers/clk.h index d4cc90da0..4db20f8ec 100644 --- a/include/drivers/clk.h +++ b/include/drivers/clk.h @@ -13,6 +13,8 @@ struct clk_ops { int (*enable)(unsigned long id); void (*disable)(unsigned long id); unsigned long (*get_rate)(unsigned long id); + int (*set_rate)(unsigned long id, unsigned long rate, + unsigned long *orate); int (*get_parent)(unsigned long id); int (*set_parent)(unsigned long id, unsigned long parent_id); bool (*is_enabled)(unsigned long id); @@ -21,6 +23,7 @@ struct clk_ops { int clk_enable(unsigned long id); void clk_disable(unsigned long id); unsigned long clk_get_rate(unsigned long id); +int clk_set_rate(unsigned long id, unsigned long rate, unsigned long *orate); bool clk_is_enabled(unsigned long id); int clk_get_parent(unsigned long id); int clk_set_parent(unsigned long id, unsigned long parent_id);