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>
Reviewed-by: Dmitry Baryshkov <dmitry.barysh...@linaro.org>
---

(no changes since v3)

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, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/qcom/reset.c b/drivers/clk/qcom/reset.c
index 2a16adb..10ef71b 100644
--- a/drivers/clk/qcom/reset.c
+++ b/drivers/clk/qcom/reset.c
@@ -13,7 +13,20 @@
 
 static int qcom_reset(struct reset_controller_dev *rcdev, unsigned long id)
 {
-       struct qcom_reset_controller *rst = to_qcom_reset_controller(rcdev);
+       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(rst->reset_map[id].udelay ?: 1); /* use 1 us as default */
@@ -30,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);
@@ -44,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 b8c1135..a4d767b 100644
--- a/drivers/clk/qcom/reset.h
+++ b/drivers/clk/qcom/reset.h
@@ -8,10 +8,18 @@
 
 #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;
        u8 udelay;
+       const struct qcom_reset_ops *ops;
+       void *priv;
 };
 
 struct regmap;
-- 
2.7.4

Reply via email to