aboutsummaryrefslogtreecommitdiff
path: root/drivers/clk/mediatek/reset.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/mediatek/reset.c')
-rw-r--r--drivers/clk/mediatek/reset.c63
1 files changed, 57 insertions, 6 deletions
diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c
index d8376b92349e..bcec4b89f449 100644
--- a/drivers/clk/mediatek/reset.c
+++ b/drivers/clk/mediatek/reset.c
@@ -19,6 +19,24 @@ struct mtk_reset {
struct reset_controller_dev rcdev;
};
+static int mtk_reset_assert_set_clr(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
+ unsigned int reg = data->regofs + ((id / 32) << 4);
+
+ return regmap_write(data->regmap, reg, 1);
+}
+
+static int mtk_reset_deassert_set_clr(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
+ unsigned int reg = data->regofs + ((id / 32) << 4) + 0x4;
+
+ return regmap_write(data->regmap, reg, 1);
+}
+
static int mtk_reset_assert(struct reset_controller_dev *rcdev,
unsigned long id)
{
@@ -49,23 +67,40 @@ static int mtk_reset(struct reset_controller_dev *rcdev,
return mtk_reset_deassert(rcdev, id);
}
+static int mtk_reset_set_clr(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ int ret;
+
+ ret = mtk_reset_assert_set_clr(rcdev, id);
+ if (ret)
+ return ret;
+ return mtk_reset_deassert_set_clr(rcdev, id);
+}
+
static const struct reset_control_ops mtk_reset_ops = {
.assert = mtk_reset_assert,
.deassert = mtk_reset_deassert,
.reset = mtk_reset,
};
-void mtk_register_reset_controller(struct device_node *np,
- unsigned int num_regs, int regofs)
+static const struct reset_control_ops mtk_reset_ops_set_clr = {
+ .assert = mtk_reset_assert_set_clr,
+ .deassert = mtk_reset_deassert_set_clr,
+ .reset = mtk_reset_set_clr,
+};
+
+static void mtk_register_reset_controller_common(struct device_node *np,
+ unsigned int num_regs, int regofs,
+ const struct reset_control_ops *reset_ops)
{
struct mtk_reset *data;
int ret;
struct regmap *regmap;
- regmap = syscon_node_to_regmap(np);
+ regmap = device_node_to_regmap(np);
if (IS_ERR(regmap)) {
- pr_err("Cannot find regmap for %pOF: %ld\n", np,
- PTR_ERR(regmap));
+ pr_err("Cannot find regmap for %pOF: %pe\n", np, regmap);
return;
}
@@ -77,7 +112,7 @@ void mtk_register_reset_controller(struct device_node *np,
data->regofs = regofs;
data->rcdev.owner = THIS_MODULE;
data->rcdev.nr_resets = num_regs * 32;
- data->rcdev.ops = &mtk_reset_ops;
+ data->rcdev.ops = reset_ops;
data->rcdev.of_node = np;
ret = reset_controller_register(&data->rcdev);
@@ -87,3 +122,19 @@ void mtk_register_reset_controller(struct device_node *np,
return;
}
}
+
+void mtk_register_reset_controller(struct device_node *np,
+ unsigned int num_regs, int regofs)
+{
+ mtk_register_reset_controller_common(np, num_regs, regofs,
+ &mtk_reset_ops);
+}
+
+void mtk_register_reset_controller_set_clr(struct device_node *np,
+ unsigned int num_regs, int regofs)
+{
+ mtk_register_reset_controller_common(np, num_regs, regofs,
+ &mtk_reset_ops_set_clr);
+}
+
+MODULE_LICENSE("GPL");