From 428c9de583921c4b699622272c04af4e362c474c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 28 Apr 2017 15:08:53 +0200 Subject: clk: Provide dummy of_clk_get_from_provider() for compile-testing When CONFIG_ON=n, dummies are provided for of_clk_get() and of_clk_get_by_name(), but not for of_clk_get_from_provider(). Provide a dummy for the latter, to improve the ability to do compile-testing. This requires removing the existing dummy in the Lantiq clock code. Fixes: 766e6a4ec602d0c1 ("clk: add DT clock binding support") Signed-off-by: Geert Uytterhoeven Acked-by: Thomas Langer Signed-off-by: Stephen Boyd --- include/linux/clk.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/clk.h b/include/linux/clk.h index 024cd07870d0..e790d19b8ffb 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -539,6 +539,10 @@ static inline struct clk *of_clk_get_by_name(struct device_node *np, { return ERR_PTR(-ENOENT); } +static inline struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec) +{ + return ERR_PTR(-ENOENT); +} #endif #endif -- cgit v1.2.3 From 266e4e9d9150e98141b85c7400f8aa3cd57a7f9b Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Fri, 19 May 2017 21:49:04 +0800 Subject: clk: add clk_bulk_get accessories These helper function allows drivers to get several clk consumers in one operation. If any of the clk cannot be acquired then any clks that were got will be put before returning to the caller. This can relieve the driver owners' life who needs to handle many clocks, as well as each clock error reporting. Cc: Michael Turquette Cc: Stephen Boyd Cc: Russell King Cc: Geert Uytterhoeven Cc: "Rafael J. Wysocki" Cc: Viresh Kumar Cc: Mark Brown Cc: Shawn Guo Cc: Fabio Estevam Cc: Sascha Hauer Cc: Anson Huang Cc: Robin Gong Cc: Bai Ping Cc: Leonard Crestez Cc: Octavian Purdila Signed-off-by: Dong Aisheng Signed-off-by: Stephen Boyd --- include/linux/clk.h | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) (limited to 'include/linux') diff --git a/include/linux/clk.h b/include/linux/clk.h index 024cd07870d0..72b0cfce9165 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -77,6 +77,21 @@ struct clk_notifier_data { unsigned long new_rate; }; +/** + * struct clk_bulk_data - Data used for bulk clk operations. + * + * @id: clock consumer ID + * @clk: struct clk * to store the associated clock + * + * The CLK APIs provide a series of clk_bulk_() API calls as + * a convenience to consumers which require multiple clks. This + * structure is used to manage data for these calls. + */ +struct clk_bulk_data { + const char *id; + struct clk *clk; +}; + #ifdef CONFIG_COMMON_CLK /** @@ -185,12 +200,20 @@ static inline bool clk_is_match(const struct clk *p, const struct clk *q) */ #ifdef CONFIG_HAVE_CLK_PREPARE int clk_prepare(struct clk *clk); +int __must_check clk_bulk_prepare(int num_clks, + const struct clk_bulk_data *clks); #else static inline int clk_prepare(struct clk *clk) { might_sleep(); return 0; } + +static inline int clk_bulk_prepare(int num_clks, struct clk_bulk_data *clks) +{ + might_sleep(); + return 0; +} #endif /** @@ -204,11 +227,16 @@ static inline int clk_prepare(struct clk *clk) */ #ifdef CONFIG_HAVE_CLK_PREPARE void clk_unprepare(struct clk *clk); +void clk_bulk_unprepare(int num_clks, const struct clk_bulk_data *clks); #else static inline void clk_unprepare(struct clk *clk) { might_sleep(); } +static inline void clk_bulk_unprepare(int num_clks, struct clk_bulk_data *clks) +{ + might_sleep(); +} #endif #ifdef CONFIG_HAVE_CLK @@ -229,6 +257,29 @@ static inline void clk_unprepare(struct clk *clk) */ struct clk *clk_get(struct device *dev, const char *id); +/** + * clk_bulk_get - lookup and obtain a number of references to clock producer. + * @dev: device for clock "consumer" + * @num_clks: the number of clk_bulk_data + * @clks: the clk_bulk_data table of consumer + * + * This helper function allows drivers to get several clk consumers in one + * operation. If any of the clk cannot be acquired then any clks + * that were obtained will be freed before returning to the caller. + * + * Returns 0 if all clocks specified in clk_bulk_data table are obtained + * successfully, or valid IS_ERR() condition containing errno. + * The implementation uses @dev and @clk_bulk_data.id to determine the + * clock consumer, and thereby the clock producer. + * The clock returned is stored in each @clk_bulk_data.clk field. + * + * Drivers must assume that the clock source is not enabled. + * + * clk_bulk_get should not be called from within interrupt context. + */ +int __must_check clk_bulk_get(struct device *dev, int num_clks, + struct clk_bulk_data *clks); + /** * devm_clk_get - lookup and obtain a managed reference to a clock producer. * @dev: device for clock "consumer" @@ -278,6 +329,18 @@ struct clk *devm_get_clk_from_child(struct device *dev, */ int clk_enable(struct clk *clk); +/** + * clk_bulk_enable - inform the system when the set of clks should be running. + * @num_clks: the number of clk_bulk_data + * @clks: the clk_bulk_data table of consumer + * + * May be called from atomic contexts. + * + * Returns success (0) or negative errno. + */ +int __must_check clk_bulk_enable(int num_clks, + const struct clk_bulk_data *clks); + /** * clk_disable - inform the system when the clock source is no longer required. * @clk: clock source @@ -294,6 +357,24 @@ int clk_enable(struct clk *clk); */ void clk_disable(struct clk *clk); +/** + * clk_bulk_disable - inform the system when the set of clks is no + * longer required. + * @num_clks: the number of clk_bulk_data + * @clks: the clk_bulk_data table of consumer + * + * Inform the system that a set of clks is no longer required by + * a driver and may be shut down. + * + * May be called from atomic contexts. + * + * Implementation detail: if the set of clks is shared between + * multiple drivers, clk_bulk_enable() calls must be balanced by the + * same number of clk_bulk_disable() calls for the clock source to be + * disabled. + */ +void clk_bulk_disable(int num_clks, const struct clk_bulk_data *clks); + /** * clk_get_rate - obtain the current clock rate (in Hz) for a clock source. * This is only valid once the clock source has been enabled. @@ -313,6 +394,19 @@ unsigned long clk_get_rate(struct clk *clk); */ void clk_put(struct clk *clk); +/** + * clk_bulk_put - "free" the clock source + * @num_clks: the number of clk_bulk_data + * @clks: the clk_bulk_data table of consumer + * + * Note: drivers must ensure that all clk_bulk_enable calls made on this + * clock source are balanced by clk_bulk_disable calls prior to calling + * this function. + * + * clk_bulk_put should not be called from within interrupt context. + */ +void clk_bulk_put(int num_clks, struct clk_bulk_data *clks); + /** * devm_clk_put - "free" a managed clock source * @dev: device used to acquire the clock @@ -445,6 +539,12 @@ static inline struct clk *clk_get(struct device *dev, const char *id) return NULL; } +static inline int clk_bulk_get(struct device *dev, int num_clks, + struct clk_bulk_data *clks) +{ + return 0; +} + static inline struct clk *devm_clk_get(struct device *dev, const char *id) { return NULL; @@ -458,6 +558,8 @@ static inline struct clk *devm_get_clk_from_child(struct device *dev, static inline void clk_put(struct clk *clk) {} +static inline void clk_bulk_put(int num_clks, struct clk_bulk_data *clks) {} + static inline void devm_clk_put(struct device *dev, struct clk *clk) {} static inline int clk_enable(struct clk *clk) @@ -465,8 +567,17 @@ static inline int clk_enable(struct clk *clk) return 0; } +static inline int clk_bulk_enable(int num_clks, struct clk_bulk_data *clks) +{ + return 0; +} + static inline void clk_disable(struct clk *clk) {} + +static inline void clk_bulk_disable(int num_clks, + struct clk_bulk_data *clks) {} + static inline unsigned long clk_get_rate(struct clk *clk) { return 0; -- cgit v1.2.3 From 618aee02e2f57042f4cdeab228caf631e524b281 Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Fri, 19 May 2017 21:49:05 +0800 Subject: clk: add managed version of clk_bulk_get This patch introduces the managed version of clk_bulk_get. Cc: Michael Turquette Cc: Stephen Boyd Cc: Russell King Cc: Geert Uytterhoeven Cc: "Rafael J. Wysocki" Cc: Viresh Kumar Cc: Mark Brown Cc: Shawn Guo Cc: Fabio Estevam Cc: Sascha Hauer Cc: Anson Huang Cc: Robin Gong Cc: Bai Ping Cc: Leonard Crestez Cc: Octavian Purdila Signed-off-by: Dong Aisheng Signed-off-by: Stephen Boyd --- include/linux/clk.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'include/linux') diff --git a/include/linux/clk.h b/include/linux/clk.h index 72b0cfce9165..c673f0b91751 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -280,6 +280,21 @@ struct clk *clk_get(struct device *dev, const char *id); int __must_check clk_bulk_get(struct device *dev, int num_clks, struct clk_bulk_data *clks); +/** + * devm_clk_bulk_get - managed get multiple clk consumers + * @dev: device for clock "consumer" + * @num_clks: the number of clk_bulk_data + * @clks: the clk_bulk_data table of consumer + * + * Return 0 on success, an errno on failure. + * + * This helper function allows drivers to get several clk + * consumers in one operation with management, the clks will + * automatically be freed when the device is unbound. + */ +int __must_check devm_clk_bulk_get(struct device *dev, int num_clks, + struct clk_bulk_data *clks); + /** * devm_clk_get - lookup and obtain a managed reference to a clock producer. * @dev: device for clock "consumer" @@ -550,6 +565,12 @@ static inline struct clk *devm_clk_get(struct device *dev, const char *id) return NULL; } +static inline int devm_clk_bulk_get(struct device *dev, int num_clks, + struct clk_bulk_data *clks) +{ + return 0; +} + static inline struct clk *devm_get_clk_from_child(struct device *dev, struct device_node *np, const char *con_id) { -- cgit v1.2.3 From cfe76a28e37112f471d4bcb8d5f336e3416299b7 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 12 May 2017 09:40:49 +0200 Subject: clk: versatile: delete old RealView clock implementation The old RealView clock implementation is not used anymore (nothing in the kernel calls realview_clk_init()) as we have moved all clocks over to device tree. Delete it. Signed-off-by: Linus Walleij Signed-off-by: Stephen Boyd --- include/linux/platform_data/clk-realview.h | 1 - 1 file changed, 1 deletion(-) delete mode 100644 include/linux/platform_data/clk-realview.h (limited to 'include/linux') diff --git a/include/linux/platform_data/clk-realview.h b/include/linux/platform_data/clk-realview.h deleted file mode 100644 index 2e426a7dbc51..000000000000 --- a/include/linux/platform_data/clk-realview.h +++ /dev/null @@ -1 +0,0 @@ -void realview_clk_init(void __iomem *sysbase, bool is_pb1176); -- cgit v1.2.3 From 22833a9165a1c72a54ddc696a3765bd6f87fbb92 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Wed, 17 May 2017 09:40:30 +0200 Subject: clk: divider: Make divider_round_rate take the parent clock So far, divider_round_rate only considers the parent clock returned by clk_hw_get_parent. This works fine on clocks that have a single parents, this doesn't work on muxes, since we will only consider the first parent, while other parents may totally be able to provide a better combination. Clocks in that case cannot use divider_round_rate, so would have to come up with a very similar logic to work around it. Instead of having to do something like this, and duplicate that logic everywhere, create a divider_round_rate parent to allow caller to give an additional parameter for the parent clock to consider. Reviewed-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard Acked-by: Stephen Boyd Signed-off-by: Chen-Yu Tsai --- include/linux/clk-provider.h | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index a428aec36ace..c59c62571e4f 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -412,9 +412,10 @@ extern const struct clk_ops clk_divider_ro_ops; unsigned long divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate, unsigned int val, const struct clk_div_table *table, unsigned long flags); -long divider_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate, const struct clk_div_table *table, - u8 width, unsigned long flags); +long divider_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent, + unsigned long rate, unsigned long *prate, + const struct clk_div_table *table, + u8 width, unsigned long flags); int divider_get_val(unsigned long rate, unsigned long parent_rate, const struct clk_div_table *table, u8 width, unsigned long flags); @@ -757,6 +758,15 @@ static inline void __clk_hw_set_clk(struct clk_hw *dst, struct clk_hw *src) dst->core = src->core; } +static inline long divider_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate, + const struct clk_div_table *table, + u8 width, unsigned long flags) +{ + return divider_round_rate_parent(hw, clk_hw_get_parent(hw), + rate, prate, table, width, flags); +} + /* * FIXME clock api without lock protection */ -- cgit v1.2.3