summaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/clk-provider.h103
-rw-r--r--include/linux/clk.h47
-rw-r--r--include/linux/soc/ti/ti_sci_protocol.h28
3 files changed, 157 insertions, 21 deletions
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index bb6118f79784..2ae7604783dd 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -9,8 +9,6 @@
#include <linux/of.h>
#include <linux/of_clk.h>
-#ifdef CONFIG_COMMON_CLK
-
/*
* flags used across common struct clk. these flags should only affect the
* top-level framework. custom flags for dealing with hardware specifics
@@ -807,7 +805,14 @@ void devm_clk_hw_unregister(struct device *dev, struct clk_hw *hw);
/* helper functions */
const char *__clk_get_name(const struct clk *clk);
const char *clk_hw_get_name(const struct clk_hw *hw);
+#ifdef CONFIG_COMMON_CLK
struct clk_hw *__clk_get_hw(struct clk *clk);
+#else
+static inline struct clk_hw *__clk_get_hw(struct clk *clk)
+{
+ return (struct clk_hw *)clk;
+}
+#endif
unsigned int clk_hw_get_num_parents(const struct clk_hw *hw);
struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw);
struct clk_hw *clk_hw_get_parent_by_index(const struct clk_hw *hw,
@@ -867,8 +872,6 @@ static inline long divider_ro_round_rate(struct clk_hw *hw, unsigned long rate,
*/
unsigned long clk_hw_round_rate(struct clk_hw *hw, unsigned long rate);
-struct of_device_id;
-
struct clk_onecell_data {
struct clk **clks;
unsigned int clk_num;
@@ -879,8 +882,6 @@ struct clk_hw_onecell_data {
struct clk_hw *hws[];
};
-extern struct of_device_id __clk_of_table;
-
#define CLK_OF_DECLARE(name, compat, fn) OF_DECLARE_1(clk, name, compat, fn)
/*
@@ -904,6 +905,40 @@ extern struct of_device_id __clk_of_table;
.ops = _ops, \
})
+#define CLK_HW_INIT_HW(_name, _parent, _ops, _flags) \
+ (&(struct clk_init_data) { \
+ .flags = _flags, \
+ .name = _name, \
+ .parent_hws = (const struct clk_hw*[]) { _parent }, \
+ .num_parents = 1, \
+ .ops = _ops, \
+ })
+
+/*
+ * This macro is intended for drivers to be able to share the otherwise
+ * individual struct clk_hw[] compound literals created by the compiler
+ * when using CLK_HW_INIT_HW. It does NOT support multiple parents.
+ */
+#define CLK_HW_INIT_HWS(_name, _parent, _ops, _flags) \
+ (&(struct clk_init_data) { \
+ .flags = _flags, \
+ .name = _name, \
+ .parent_hws = _parent, \
+ .num_parents = 1, \
+ .ops = _ops, \
+ })
+
+#define CLK_HW_INIT_FW_NAME(_name, _parent, _ops, _flags) \
+ (&(struct clk_init_data) { \
+ .flags = _flags, \
+ .name = _name, \
+ .parent_data = (const struct clk_parent_data[]) { \
+ { .fw_name = _parent }, \
+ }, \
+ .num_parents = 1, \
+ .ops = _ops, \
+ })
+
#define CLK_HW_INIT_PARENTS(_name, _parents, _ops, _flags) \
(&(struct clk_init_data) { \
.flags = _flags, \
@@ -913,6 +948,24 @@ extern struct of_device_id __clk_of_table;
.ops = _ops, \
})
+#define CLK_HW_INIT_PARENTS_HW(_name, _parents, _ops, _flags) \
+ (&(struct clk_init_data) { \
+ .flags = _flags, \
+ .name = _name, \
+ .parent_hws = _parents, \
+ .num_parents = ARRAY_SIZE(_parents), \
+ .ops = _ops, \
+ })
+
+#define CLK_HW_INIT_PARENTS_DATA(_name, _parents, _ops, _flags) \
+ (&(struct clk_init_data) { \
+ .flags = _flags, \
+ .name = _name, \
+ .parent_data = _parents, \
+ .num_parents = ARRAY_SIZE(_parents), \
+ .ops = _ops, \
+ })
+
#define CLK_HW_INIT_NO_PARENT(_name, _ops, _flags) \
(&(struct clk_init_data) { \
.flags = _flags, \
@@ -933,6 +986,43 @@ extern struct of_device_id __clk_of_table;
_flags), \
}
+#define CLK_FIXED_FACTOR_HW(_struct, _name, _parent, \
+ _div, _mult, _flags) \
+ struct clk_fixed_factor _struct = { \
+ .div = _div, \
+ .mult = _mult, \
+ .hw.init = CLK_HW_INIT_HW(_name, \
+ _parent, \
+ &clk_fixed_factor_ops, \
+ _flags), \
+ }
+
+/*
+ * This macro allows the driver to reuse the _parent array for multiple
+ * fixed factor clk declarations.
+ */
+#define CLK_FIXED_FACTOR_HWS(_struct, _name, _parent, \
+ _div, _mult, _flags) \
+ struct clk_fixed_factor _struct = { \
+ .div = _div, \
+ .mult = _mult, \
+ .hw.init = CLK_HW_INIT_HWS(_name, \
+ _parent, \
+ &clk_fixed_factor_ops, \
+ _flags), \
+ }
+
+#define CLK_FIXED_FACTOR_FW_NAME(_struct, _name, _parent, \
+ _div, _mult, _flags) \
+ struct clk_fixed_factor _struct = { \
+ .div = _div, \
+ .mult = _mult, \
+ .hw.init = CLK_HW_INIT_FW_NAME(_name, \
+ _parent, \
+ &clk_fixed_factor_ops, \
+ _flags), \
+ }
+
#ifdef CONFIG_OF
int of_clk_add_provider(struct device_node *np,
struct clk *(*clk_src_get)(struct of_phandle_args *args,
@@ -1019,5 +1109,4 @@ static inline int of_clk_detect_critical(struct device_node *np, int index,
void clk_gate_restore_context(struct clk_hw *hw);
-#endif /* CONFIG_COMMON_CLK */
#endif /* CLK_PROVIDER_H */
diff --git a/include/linux/clk.h b/include/linux/clk.h
index c8e3325868bd..3c096c7a51dc 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -329,6 +329,19 @@ int __must_check clk_bulk_get(struct device *dev, int num_clks,
*/
int __must_check clk_bulk_get_all(struct device *dev,
struct clk_bulk_data **clks);
+
+/**
+ * clk_bulk_get_optional - 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
+ *
+ * Behaves the same as clk_bulk_get() except where there is no clock producer.
+ * In this case, instead of returning -ENOENT, the function returns 0 and
+ * NULL for a clk for which a clock producer could not be determined.
+ */
+int __must_check clk_bulk_get_optional(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"
@@ -344,6 +357,28 @@ int __must_check clk_bulk_get_all(struct device *dev,
int __must_check devm_clk_bulk_get(struct device *dev, int num_clks,
struct clk_bulk_data *clks);
/**
+ * devm_clk_bulk_get_optional - managed get multiple optional consumer clocks
+ * @dev: device for clock "consumer"
+ * @clks: pointer to the clk_bulk_data table of consumer
+ *
+ * Behaves the same as devm_clk_bulk_get() except where there is no clock
+ * producer. In this case, instead of returning -ENOENT, the function returns
+ * NULL for given clk. It is assumed all clocks in clk_bulk_data are optional.
+ *
+ * Returns 0 if all clocks specified in clk_bulk_data table are obtained
+ * successfully or for any clk there was no clk provider available, otherwise
+ * returns 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 devm_clk_bulk_get_optional(struct device *dev, int num_clks,
+ struct clk_bulk_data *clks);
+/**
* devm_clk_bulk_get_all - managed get multiple clk consumers
* @dev: device for clock "consumer"
* @clks: pointer to the clk_bulk_data table of consumer
@@ -715,6 +750,12 @@ static inline int __must_check clk_bulk_get(struct device *dev, int num_clks,
return 0;
}
+static inline int __must_check clk_bulk_get_optional(struct device *dev,
+ int num_clks, struct clk_bulk_data *clks)
+{
+ return 0;
+}
+
static inline int __must_check clk_bulk_get_all(struct device *dev,
struct clk_bulk_data **clks)
{
@@ -738,6 +779,12 @@ static inline int __must_check devm_clk_bulk_get(struct device *dev, int num_clk
return 0;
}
+static inline int __must_check devm_clk_bulk_get_optional(struct device *dev,
+ int num_clks, struct clk_bulk_data *clks)
+{
+ return 0;
+}
+
static inline int __must_check devm_clk_bulk_get_all(struct device *dev,
struct clk_bulk_data **clks)
{
diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h
index 568722a041bf..406e6717d252 100644
--- a/include/linux/soc/ti/ti_sci_protocol.h
+++ b/include/linux/soc/ti/ti_sci_protocol.h
@@ -166,29 +166,29 @@ struct ti_sci_dev_ops {
* managed by driver for that purpose.
*/
struct ti_sci_clk_ops {
- int (*get_clock)(const struct ti_sci_handle *handle, u32 did, u8 cid,
+ int (*get_clock)(const struct ti_sci_handle *handle, u32 did, u32 cid,
bool needs_ssc, bool can_change_freq,
bool enable_input_term);
- int (*idle_clock)(const struct ti_sci_handle *handle, u32 did, u8 cid);
- int (*put_clock)(const struct ti_sci_handle *handle, u32 did, u8 cid);
- int (*is_auto)(const struct ti_sci_handle *handle, u32 did, u8 cid,
+ int (*idle_clock)(const struct ti_sci_handle *handle, u32 did, u32 cid);
+ int (*put_clock)(const struct ti_sci_handle *handle, u32 did, u32 cid);
+ int (*is_auto)(const struct ti_sci_handle *handle, u32 did, u32 cid,
bool *req_state);
- int (*is_on)(const struct ti_sci_handle *handle, u32 did, u8 cid,
+ int (*is_on)(const struct ti_sci_handle *handle, u32 did, u32 cid,
bool *req_state, bool *current_state);
- int (*is_off)(const struct ti_sci_handle *handle, u32 did, u8 cid,
+ int (*is_off)(const struct ti_sci_handle *handle, u32 did, u32 cid,
bool *req_state, bool *current_state);
- int (*set_parent)(const struct ti_sci_handle *handle, u32 did, u8 cid,
- u8 parent_id);
- int (*get_parent)(const struct ti_sci_handle *handle, u32 did, u8 cid,
- u8 *parent_id);
+ int (*set_parent)(const struct ti_sci_handle *handle, u32 did, u32 cid,
+ u32 parent_id);
+ int (*get_parent)(const struct ti_sci_handle *handle, u32 did, u32 cid,
+ u32 *parent_id);
int (*get_num_parents)(const struct ti_sci_handle *handle, u32 did,
- u8 cid, u8 *num_parents);
+ u32 cid, u32 *num_parents);
int (*get_best_match_freq)(const struct ti_sci_handle *handle, u32 did,
- u8 cid, u64 min_freq, u64 target_freq,
+ u32 cid, u64 min_freq, u64 target_freq,
u64 max_freq, u64 *match_freq);
- int (*set_freq)(const struct ti_sci_handle *handle, u32 did, u8 cid,
+ int (*set_freq)(const struct ti_sci_handle *handle, u32 did, u32 cid,
u64 min_freq, u64 target_freq, u64 max_freq);
- int (*get_freq)(const struct ti_sci_handle *handle, u32 did, u8 cid,
+ int (*get_freq)(const struct ti_sci_handle *handle, u32 did, u32 cid,
u64 *current_freq);
};
OpenPOWER on IntegriCloud