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