1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/slab.h>
5 #include <linux/of_address.h>
6 #include <linux/reset-controller.h>
10 #define rcdev_to_unit(rcdev) container_of(rcdev, struct mmp_clk_reset_unit, rcdev)
12 static int mmp_of_reset_xlate(struct reset_controller_dev
*rcdev
,
13 const struct of_phandle_args
*reset_spec
)
15 struct mmp_clk_reset_unit
*unit
= rcdev_to_unit(rcdev
);
16 struct mmp_clk_reset_cell
*cell
;
19 if (WARN_ON(reset_spec
->args_count
!= rcdev
->of_reset_n_cells
))
22 for (i
= 0; i
< rcdev
->nr_resets
; i
++) {
23 cell
= &unit
->cells
[i
];
24 if (cell
->clk_id
== reset_spec
->args
[0])
28 if (i
== rcdev
->nr_resets
)
34 static int mmp_clk_reset_assert(struct reset_controller_dev
*rcdev
,
37 struct mmp_clk_reset_unit
*unit
= rcdev_to_unit(rcdev
);
38 struct mmp_clk_reset_cell
*cell
;
39 unsigned long flags
= 0;
42 cell
= &unit
->cells
[id
];
44 spin_lock_irqsave(cell
->lock
, flags
);
46 val
= readl(cell
->reg
);
48 writel(val
, cell
->reg
);
51 spin_unlock_irqrestore(cell
->lock
, flags
);
56 static int mmp_clk_reset_deassert(struct reset_controller_dev
*rcdev
,
59 struct mmp_clk_reset_unit
*unit
= rcdev_to_unit(rcdev
);
60 struct mmp_clk_reset_cell
*cell
;
61 unsigned long flags
= 0;
64 cell
= &unit
->cells
[id
];
66 spin_lock_irqsave(cell
->lock
, flags
);
68 val
= readl(cell
->reg
);
70 writel(val
, cell
->reg
);
73 spin_unlock_irqrestore(cell
->lock
, flags
);
78 static const struct reset_control_ops mmp_clk_reset_ops
= {
79 .assert = mmp_clk_reset_assert
,
80 .deassert
= mmp_clk_reset_deassert
,
83 void mmp_clk_reset_register(struct device_node
*np
,
84 struct mmp_clk_reset_cell
*cells
, int nr_resets
)
86 struct mmp_clk_reset_unit
*unit
;
88 unit
= kzalloc(sizeof(*unit
), GFP_KERNEL
);
93 unit
->rcdev
.of_reset_n_cells
= 1;
94 unit
->rcdev
.nr_resets
= nr_resets
;
95 unit
->rcdev
.ops
= &mmp_clk_reset_ops
;
96 unit
->rcdev
.of_node
= np
;
97 unit
->rcdev
.of_xlate
= mmp_of_reset_xlate
;
99 reset_controller_register(&unit
->rcdev
);