26
26
27
27
static const struct zynqmp_eemi_ops * eemi_ops_tbl ;
28
28
29
+ static bool feature_check_enabled ;
30
+ static u32 zynqmp_pm_features [PM_API_MAX ];
31
+
29
32
static const struct mfd_cell firmware_devs [] = {
30
33
{
31
34
.name = "zynqmp_power_controller" ,
@@ -44,6 +47,8 @@ static int zynqmp_pm_ret_code(u32 ret_status)
44
47
case XST_PM_SUCCESS :
45
48
case XST_PM_DOUBLE_REQ :
46
49
return 0 ;
50
+ case XST_PM_NO_FEATURE :
51
+ return - ENOTSUPP ;
47
52
case XST_PM_NO_ACCESS :
48
53
return - EACCES ;
49
54
case XST_PM_ABORT_SUSPEND :
@@ -126,6 +131,39 @@ static noinline int do_fw_call_hvc(u64 arg0, u64 arg1, u64 arg2,
126
131
return zynqmp_pm_ret_code ((enum pm_ret_status )res .a0 );
127
132
}
128
133
134
+ /**
135
+ * zynqmp_pm_feature() - Check weather given feature is supported or not
136
+ * @api_id: API ID to check
137
+ *
138
+ * Return: Returns status, either success or error+reason
139
+ */
140
+ static int zynqmp_pm_feature (u32 api_id )
141
+ {
142
+ int ret ;
143
+ u32 ret_payload [PAYLOAD_ARG_CNT ];
144
+ u64 smc_arg [2 ];
145
+
146
+ if (!feature_check_enabled )
147
+ return 0 ;
148
+
149
+ /* Return value if feature is already checked */
150
+ if (zynqmp_pm_features [api_id ] != PM_FEATURE_UNCHECKED )
151
+ return zynqmp_pm_features [api_id ];
152
+
153
+ smc_arg [0 ] = PM_SIP_SVC | PM_FEATURE_CHECK ;
154
+ smc_arg [1 ] = api_id ;
155
+
156
+ ret = do_fw_call (smc_arg [0 ], smc_arg [1 ], 0 , ret_payload );
157
+ if (ret ) {
158
+ zynqmp_pm_features [api_id ] = PM_FEATURE_INVALID ;
159
+ return PM_FEATURE_INVALID ;
160
+ }
161
+
162
+ zynqmp_pm_features [api_id ] = ret_payload [1 ];
163
+
164
+ return zynqmp_pm_features [api_id ];
165
+ }
166
+
129
167
/**
130
168
* zynqmp_pm_invoke_fn() - Invoke the system-level platform management layer
131
169
* caller function depending on the configuration
@@ -160,6 +198,9 @@ int zynqmp_pm_invoke_fn(u32 pm_api_id, u32 arg0, u32 arg1,
160
198
*/
161
199
u64 smc_arg [4 ];
162
200
201
+ if (zynqmp_pm_feature (pm_api_id ) == PM_FEATURE_INVALID )
202
+ return - ENOTSUPP ;
203
+
163
204
smc_arg [0 ] = PM_SIP_SVC | pm_api_id ;
164
205
smc_arg [1 ] = ((u64 )arg1 << 32 ) | arg0 ;
165
206
smc_arg [2 ] = ((u64 )arg3 << 32 ) | arg2 ;
@@ -715,6 +756,8 @@ static int zynqmp_firmware_probe(struct platform_device *pdev)
715
756
np = of_find_compatible_node (NULL , NULL , "xlnx,versal" );
716
757
if (!np )
717
758
return 0 ;
759
+
760
+ feature_check_enabled = true;
718
761
}
719
762
of_node_put (np );
720
763
0 commit comments