Allow soc specific clk drivers to specify a custom reset operation. We
will use this in an upcoming patch to allow gpucc driver to specify a
differet reset operation for cx_gdsc.

Signed-off-by: Akhil P Oommen <quic_akhi...@quicinc.com>
---

Changes in v3:
- Use pointer to const for "struct qcom_reset_ops" in qcom_reset_map (Krzysztof)

Changes in v2:
- Return error when a particular custom reset op is not implemented. (Dmitry)

 drivers/clk/qcom/reset.c | 27 +++++++++++++++++++++++++++
 drivers/clk/qcom/reset.h |  8 ++++++++
 2 files changed, 35 insertions(+)

diff --git a/drivers/clk/qcom/reset.c b/drivers/clk/qcom/reset.c
index 819d194..b7ae4a3 100644
--- a/drivers/clk/qcom/reset.c
+++ b/drivers/clk/qcom/reset.c
@@ -13,6 +13,21 @@
 
 static int qcom_reset(struct reset_controller_dev *rcdev, unsigned long id)
 {
+       struct qcom_reset_controller *rst;
+       const struct qcom_reset_map *map;
+
+       rst = to_qcom_reset_controller(rcdev);
+       map = &rst->reset_map[id];
+
+       if (map->ops && map->ops->reset)
+               return map->ops->reset(map->priv);
+       /*
+        * If custom ops is implemented but just not this callback, return
+        * error
+        */
+       else if (map->ops)
+               return -EOPNOTSUPP;
+
        rcdev->ops->assert(rcdev, id);
        udelay(1);
        rcdev->ops->deassert(rcdev, id);
@@ -28,6 +43,12 @@ qcom_reset_assert(struct reset_controller_dev *rcdev, 
unsigned long id)
 
        rst = to_qcom_reset_controller(rcdev);
        map = &rst->reset_map[id];
+
+       if (map->ops && map->ops->assert)
+               return map->ops->assert(map->priv);
+       else if (map->ops)
+               return -EOPNOTSUPP;
+
        mask = BIT(map->bit);
 
        return regmap_update_bits(rst->regmap, map->reg, mask, mask);
@@ -42,6 +63,12 @@ qcom_reset_deassert(struct reset_controller_dev *rcdev, 
unsigned long id)
 
        rst = to_qcom_reset_controller(rcdev);
        map = &rst->reset_map[id];
+
+       if (map->ops && map->ops->deassert)
+               return map->ops->deassert(map->priv);
+       else if (map->ops)
+               return -EOPNOTSUPP;
+
        mask = BIT(map->bit);
 
        return regmap_update_bits(rst->regmap, map->reg, mask, 0);
diff --git a/drivers/clk/qcom/reset.h b/drivers/clk/qcom/reset.h
index 2a08b5e..f3147eb 100644
--- a/drivers/clk/qcom/reset.h
+++ b/drivers/clk/qcom/reset.h
@@ -8,9 +8,17 @@
 
 #include <linux/reset-controller.h>
 
+struct qcom_reset_ops {
+       int (*reset)(void *priv);
+       int (*assert)(void *priv);
+       int (*deassert)(void *priv);
+};
+
 struct qcom_reset_map {
        unsigned int reg;
        u8 bit;
+       const struct qcom_reset_ops *ops;
+       void *priv;
 };
 
 struct regmap;
-- 
2.7.4

Reply via email to