diff options
author | Andrey Smirnov <andrew.smirnov@gmail.com> | 2019-02-19 23:29:26 -0800 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2019-02-22 08:11:18 +0100 |
commit | 7817ca90abcc7807152cb4339065cfd8db565d68 (patch) | |
tree | 459b28aadba1b556d968298d91d41c17fffcdfe9 /include/linux | |
parent | 2916bfffbdee5f1ba1a74d65b548635c4fe5e174 (diff) | |
download | barebox-7817ca90abcc7807152cb4339065cfd8db565d68.tar.gz barebox-7817ca90abcc7807152cb4339065cfd8db565d68.tar.xz |
clk: Import a subset of clk_bulk API from Linux
Import a subset of clk_bulk API from Linux to support porting kernel
code that uses it.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/clk.h | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/include/linux/clk.h b/include/linux/clk.h index 38c86e0b47..961fc89ba7 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -25,6 +25,22 @@ struct device_d; */ struct clk; +/** + * 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_HAVE_CLK /** @@ -45,6 +61,29 @@ struct clk; struct clk *clk_get(struct device_d *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_d *dev, int num_clks, + struct clk_bulk_data *clks); + +/** * clk_enable - inform the system when the clock source should be running. * @clk: clock source * @@ -55,6 +94,18 @@ struct clk *clk_get(struct device_d *dev, const char *id); 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 * @@ -69,12 +120,43 @@ 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. * @clk: clock source */ unsigned long clk_get_rate(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); + /* * The remaining APIs are optional for machine class support. */ @@ -153,15 +235,31 @@ static inline struct clk *clk_get(struct device_d *dev, const char *id) return NULL; } +static inline int __must_check clk_bulk_get(struct device_d *dev, int num_clks, + struct clk_bulk_data *clks) +{ + return 0; +} + +static inline void clk_bulk_put(int num_clks, struct clk_bulk_data *clks) {} + static inline int clk_enable(struct clk *clk) { return 0; } +static inline int __must_check 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; |