99#include <linux/platform_device.h>
1010#include <linux/reset-controller.h>
1111#include <linux/firmware/xlnx-zynqmp.h>
12+ #include <linux/of_device.h>
1213
1314#define ZYNQMP_NR_RESETS (ZYNQMP_PM_RESET_END - ZYNQMP_PM_RESET_START)
1415#define ZYNQMP_RESET_ID ZYNQMP_PM_RESET_START
16+ #define VERSAL_NR_RESETS 95
17+
18+ struct zynqmp_reset_soc_data {
19+ u32 reset_id ;
20+ u32 num_resets ;
21+ };
1522
1623struct zynqmp_reset_data {
1724 struct reset_controller_dev rcdev ;
25+ const struct zynqmp_reset_soc_data * data ;
1826};
1927
2028static inline struct zynqmp_reset_data *
@@ -26,23 +34,28 @@ to_zynqmp_reset_data(struct reset_controller_dev *rcdev)
2634static int zynqmp_reset_assert (struct reset_controller_dev * rcdev ,
2735 unsigned long id )
2836{
29- return zynqmp_pm_reset_assert (ZYNQMP_RESET_ID + id ,
37+ struct zynqmp_reset_data * priv = to_zynqmp_reset_data (rcdev );
38+
39+ return zynqmp_pm_reset_assert (priv -> data -> reset_id + id ,
3040 PM_RESET_ACTION_ASSERT );
3141}
3242
3343static int zynqmp_reset_deassert (struct reset_controller_dev * rcdev ,
3444 unsigned long id )
3545{
36- return zynqmp_pm_reset_assert (ZYNQMP_RESET_ID + id ,
46+ struct zynqmp_reset_data * priv = to_zynqmp_reset_data (rcdev );
47+
48+ return zynqmp_pm_reset_assert (priv -> data -> reset_id + id ,
3749 PM_RESET_ACTION_RELEASE );
3850}
3951
4052static int zynqmp_reset_status (struct reset_controller_dev * rcdev ,
4153 unsigned long id )
4254{
55+ struct zynqmp_reset_data * priv = to_zynqmp_reset_data (rcdev );
4356 int val , err ;
4457
45- err = zynqmp_pm_reset_get_status (ZYNQMP_RESET_ID + id , & val );
58+ err = zynqmp_pm_reset_get_status (priv -> data -> reset_id + id , & val );
4659 if (err )
4760 return err ;
4861
@@ -52,10 +65,28 @@ static int zynqmp_reset_status(struct reset_controller_dev *rcdev,
5265static int zynqmp_reset_reset (struct reset_controller_dev * rcdev ,
5366 unsigned long id )
5467{
55- return zynqmp_pm_reset_assert (ZYNQMP_RESET_ID + id ,
68+ struct zynqmp_reset_data * priv = to_zynqmp_reset_data (rcdev );
69+
70+ return zynqmp_pm_reset_assert (priv -> data -> reset_id + id ,
5671 PM_RESET_ACTION_PULSE );
5772}
5873
74+ static int zynqmp_reset_of_xlate (struct reset_controller_dev * rcdev ,
75+ const struct of_phandle_args * reset_spec )
76+ {
77+ return reset_spec -> args [0 ];
78+ }
79+
80+ static const struct zynqmp_reset_soc_data zynqmp_reset_data = {
81+ .reset_id = ZYNQMP_RESET_ID ,
82+ .num_resets = ZYNQMP_NR_RESETS ,
83+ };
84+
85+ static const struct zynqmp_reset_soc_data versal_reset_data = {
86+ .reset_id = 0 ,
87+ .num_resets = VERSAL_NR_RESETS ,
88+ };
89+
5990static const struct reset_control_ops zynqmp_reset_ops = {
6091 .reset = zynqmp_reset_reset ,
6192 .assert = zynqmp_reset_assert ,
@@ -71,18 +102,25 @@ static int zynqmp_reset_probe(struct platform_device *pdev)
71102 if (!priv )
72103 return - ENOMEM ;
73104
105+ priv -> data = of_device_get_match_data (& pdev -> dev );
106+ if (!priv -> data )
107+ return - EINVAL ;
108+
74109 platform_set_drvdata (pdev , priv );
75110
76111 priv -> rcdev .ops = & zynqmp_reset_ops ;
77112 priv -> rcdev .owner = THIS_MODULE ;
78113 priv -> rcdev .of_node = pdev -> dev .of_node ;
79- priv -> rcdev .nr_resets = ZYNQMP_NR_RESETS ;
114+ priv -> rcdev .nr_resets = priv -> data -> num_resets ;
115+ priv -> rcdev .of_reset_n_cells = 1 ;
116+ priv -> rcdev .of_xlate = zynqmp_reset_of_xlate ;
80117
81118 return devm_reset_controller_register (& pdev -> dev , & priv -> rcdev );
82119}
83120
84121static const struct of_device_id zynqmp_reset_dt_ids [] = {
85- { .compatible = "xlnx,zynqmp-reset" , },
122+ { .compatible = "xlnx,zynqmp-reset" , .data = & zynqmp_reset_data , },
123+ { .compatible = "xlnx,versal-reset" , .data = & versal_reset_data , },
86124 { /* sentinel */ },
87125};
88126
0 commit comments