lkml.org 
[lkml]   [2014]   [Sep]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH v1] clk: qcom: Add support for regmap clock dividers
Date
This patch expands the regmap support to allow registration of clock
dividers. It just prepares for the introduction of a clkdiv driver,
that will be in a separate patch.
Such dividers are found in the Qualcomm PMIC chips such as PM8941,
PMA8084 and others.

Signed-off-by: Georgi Djakov <gdjakov@mm-sol.com>
---
drivers/clk/qcom/clk-regmap.c | 68 +++++++++++++++++++++++++++++++++++++++++
drivers/clk/qcom/clk-regmap.h | 24 +++++++++++++++
2 files changed, 92 insertions(+)

diff --git a/drivers/clk/qcom/clk-regmap.c b/drivers/clk/qcom/clk-regmap.c
index a58ba39..d63b8ca 100644
--- a/drivers/clk/qcom/clk-regmap.c
+++ b/drivers/clk/qcom/clk-regmap.c
@@ -112,3 +112,71 @@ struct clk *devm_clk_register_regmap(struct device *dev,
return devm_clk_register(dev, &rclk->hw);
}
EXPORT_SYMBOL_GPL(devm_clk_register_regmap);
+
+/**
+ * clkdiv_recalc_rate_regmap - Calculate clock divider output rate
+ */
+unsigned long clkdiv_recalc_rate_regmap(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_regmap *rclk = to_clk_regmap(hw);
+ struct clkdiv_regmap *clkdiv = to_clkdiv_regmap(rclk);
+ unsigned int div, val;
+
+ regmap_read(rclk->regmap, clkdiv->reg, &val);
+ if (!val)
+ return parent_rate;
+
+ div = (val >> clkdiv->shift) & ((1 << clkdiv->width)-1);
+
+ return parent_rate / div;
+}
+EXPORT_SYMBOL_GPL(clkdiv_recalc_rate_regmap);
+
+static const struct clk_ops clkdiv_ops = {
+ .enable = clk_enable_regmap,
+ .disable = clk_disable_regmap,
+ .is_enabled = clk_is_enabled_regmap,
+ .recalc_rate = clkdiv_recalc_rate_regmap,
+};
+EXPORT_SYMBOL_GPL(clkdiv_ops);
+
+/**
+ * devm_clkdiv_register_regmap - register a clk_regmap clock divider
+ *
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @clkdiv: clock divider to operate on
+ *
+ * Clocks that use regmap for their register I/O should register their
+ * clk_regmap struct via this function so that the regmap is initialized
+ * and so that the clock is registered with the common clock framework.
+ */
+struct clk *devm_clkdiv_register_regmap(struct device *dev, const char *name,
+ const char *parent_name,
+ unsigned long flags,
+ struct clkdiv_regmap *clkdiv)
+{
+ struct clk_init_data init;
+
+ if (!clkdiv)
+ return ERR_PTR(-ENODEV);
+
+ clkdiv->rclk.regmap = dev_get_regmap(dev->parent, NULL);
+
+ if (!clkdiv->rclk.regmap)
+ return ERR_PTR(-ENXIO);
+
+ init.name = name;
+ init.parent_names = (parent_name ? &parent_name : NULL);
+ init.num_parents = (parent_name ? 1 : 0);
+ init.flags = flags;
+ init.ops = &clkdiv_ops;
+
+ clkdiv->rclk.hw.init = &init;
+
+ return devm_clk_register(dev, &clkdiv->rclk.hw);
+}
+EXPORT_SYMBOL_GPL(devm_clkdiv_register_regmap);
diff --git a/drivers/clk/qcom/clk-regmap.h b/drivers/clk/qcom/clk-regmap.h
index 491a63d..02582cf 100644
--- a/drivers/clk/qcom/clk-regmap.h
+++ b/drivers/clk/qcom/clk-regmap.h
@@ -42,4 +42,28 @@ void clk_disable_regmap(struct clk_hw *hw);
struct clk *
devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk);

+/**
+ * struct clkdiv_regmap - regmap supporting clock divider
+ * @rclk: regmap supporting clock struct
+ * @reg: offset into regmap for the control register
+ * @shift: bit position for divider value
+ * @width: number of bits used for divider value
+ * @table: pointer to table containing an array of divider/value pairs
+ */
+struct clkdiv_regmap {
+ struct clk_regmap rclk;
+ unsigned int reg;
+ unsigned int shift;
+ unsigned int width;
+ struct clk_div_table *table;
+};
+
+#define to_clkdiv_regmap(_rclk) container_of(_rclk, struct clkdiv_regmap, rclk)
+
+unsigned long
+clkdiv_recalc_rate_regmap(struct clk_hw *hw, unsigned long parent_rate);
+struct clk *
+devm_clkdiv_register_regmap(struct device *dev, const char *name,
+ const char *parent_name, unsigned long flags,
+ struct clkdiv_regmap *clkdiv);
#endif
--
1.7.9.5


\
 
 \ /
  Last update: 2014-09-30 19:41    [W:0.060 / U:1.712 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site