1 #include <linux/slab.h>
4 #include <linux/of_address.h>
5 #include <linux/reset-controller.h>
9 #define rcdev_to_unit(rcdev) container_of(rcdev, struct mmp_clk_reset_unit, rcdev)
11 static int mmp_of_reset_xlate(struct reset_controller_dev
*rcdev
,
12 const struct of_phandle_args
*reset_spec
)
14 struct mmp_clk_reset_unit
*unit
= rcdev_to_unit(rcdev
);
15 struct mmp_clk_reset_cell
*cell
;
18 if (WARN_ON(reset_spec
->args_count
!= rcdev
->of_reset_n_cells
))
21 for (i
= 0; i
< rcdev
->nr_resets
; i
++) {
22 cell
= &unit
->cells
[i
];
23 if (cell
->clk_id
== reset_spec
->args
[0])
27 if (i
== rcdev
->nr_resets
)
33 static int mmp_clk_reset_assert(struct reset_controller_dev
*rcdev
,
36 struct mmp_clk_reset_unit
*unit
= rcdev_to_unit(rcdev
);
37 struct mmp_clk_reset_cell
*cell
;
38 unsigned long flags
= 0;
41 cell
= &unit
->cells
[id
];
43 spin_lock_irqsave(cell
->lock
, flags
);
45 val
= readl(cell
->reg
);
47 writel(val
, cell
->reg
);
50 spin_unlock_irqrestore(cell
->lock
, flags
);
55 static int mmp_clk_reset_deassert(struct reset_controller_dev
*rcdev
,
58 struct mmp_clk_reset_unit
*unit
= rcdev_to_unit(rcdev
);
59 struct mmp_clk_reset_cell
*cell
;
60 unsigned long flags
= 0;
63 cell
= &unit
->cells
[id
];
65 spin_lock_irqsave(cell
->lock
, flags
);
67 val
= readl(cell
->reg
);
69 writel(val
, cell
->reg
);
72 spin_unlock_irqrestore(cell
->lock
, flags
);
77 static struct reset_control_ops mmp_clk_reset_ops
= {
78 .assert = mmp_clk_reset_assert
,
79 .deassert
= mmp_clk_reset_deassert
,
82 void mmp_clk_reset_register(struct device_node
*np
,
83 struct mmp_clk_reset_cell
*cells
, int nr_resets
)
85 struct mmp_clk_reset_unit
*unit
;
87 unit
= kzalloc(sizeof(*unit
), GFP_KERNEL
);
92 unit
->rcdev
.of_reset_n_cells
= 1;
93 unit
->rcdev
.nr_resets
= nr_resets
;
94 unit
->rcdev
.ops
= &mmp_clk_reset_ops
;
95 unit
->rcdev
.of_node
= np
;
96 unit
->rcdev
.of_xlate
= mmp_of_reset_xlate
;
98 reset_controller_register(&unit
->rcdev
);