xref: /rk3399_ARM-atf/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c (revision 1dcc28cfbac5dae3992ad9581f9ea68f6cb339c1)
1 /*
2  * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /*
8  * ZynqMP system level PM-API functions for ioctl.
9  */
10 
11 #include <arch_helpers.h>
12 #include <delay_timer.h>
13 #include <mmio.h>
14 #include <platform.h>
15 #include "pm_api_clock.h"
16 #include "pm_api_ioctl.h"
17 #include "pm_api_sys.h"
18 #include "pm_client.h"
19 #include "pm_common.h"
20 #include "pm_ipi.h"
21 #include "../zynqmp_def.h"
22 
23 /**
24  * pm_ioctl_get_rpu_oper_mode () - Get current RPU operation mode
25  * @mode	Buffer to store value of oper mode(Split/Lock-step)
26  *
27  * This function provides current configured RPU operational mode.
28  *
29  * @return	Returns status, either success or error+reason
30  */
31 static enum pm_ret_status pm_ioctl_get_rpu_oper_mode(unsigned int *mode)
32 {
33 	unsigned int val;
34 
35 	val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
36 	val &= ZYNQMP_SLSPLIT_MASK;
37 	if (val == 0)
38 		*mode = PM_RPU_MODE_LOCKSTEP;
39 	else
40 		*mode = PM_RPU_MODE_SPLIT;
41 
42 	return PM_RET_SUCCESS;
43 }
44 
45 /**
46  * pm_ioctl_set_rpu_oper_mode () - Configure RPU operation mode
47  * @mode	Value to set for oper mode(Split/Lock-step)
48  *
49  * This function configures RPU operational mode(Split/Lock-step).
50  * It also sets TCM combined mode in RPU lock-step and TCM non-combined
51  * mode for RPU split mode. In case of Lock step mode, RPU1's output is
52  * clamped.
53  *
54  * @return	Returns status, either success or error+reason
55  */
56 static enum pm_ret_status pm_ioctl_set_rpu_oper_mode(unsigned int mode)
57 {
58 	unsigned int val;
59 
60 	if (mmio_read_32(CRL_APB_RST_LPD_TOP) && CRL_APB_RPU_AMBA_RESET)
61 		return PM_RET_ERROR_ACCESS;
62 
63 	val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
64 
65 	if (mode == PM_RPU_MODE_SPLIT) {
66 		val |= ZYNQMP_SLSPLIT_MASK;
67 		val &= ~ZYNQMP_TCM_COMB_MASK;
68 		val &= ~ZYNQMP_SLCLAMP_MASK;
69 	} else if (mode == PM_RPU_MODE_LOCKSTEP) {
70 		val &= ~ZYNQMP_SLSPLIT_MASK;
71 		val |= ZYNQMP_TCM_COMB_MASK;
72 		val |= ZYNQMP_SLCLAMP_MASK;
73 	} else {
74 		return PM_RET_ERROR_ARGS;
75 	}
76 
77 	mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
78 
79 	return PM_RET_SUCCESS;
80 }
81 
82 /**
83  * pm_ioctl_config_boot_addr() - Configure RPU boot address
84  * @nid		Node ID of RPU
85  * @value	Value to set for boot address (TCM/OCM)
86  *
87  * This function configures RPU boot address(memory).
88  *
89  * @return	Returns status, either success or error+reason
90  */
91 static enum pm_ret_status pm_ioctl_config_boot_addr(enum pm_node_id nid,
92 						    unsigned int value)
93 {
94 	unsigned int rpu_cfg_addr, val;
95 
96 	if (nid == NODE_RPU_0)
97 		rpu_cfg_addr = ZYNQMP_RPU0_CFG;
98 	else if (nid == NODE_RPU_1)
99 		rpu_cfg_addr = ZYNQMP_RPU1_CFG;
100 	else
101 		return PM_RET_ERROR_ARGS;
102 
103 	val = mmio_read_32(rpu_cfg_addr);
104 
105 	if (value == PM_RPU_BOOTMEM_LOVEC)
106 		val &= ~ZYNQMP_VINITHI_MASK;
107 	else if (value == PM_RPU_BOOTMEM_HIVEC)
108 		val |= ZYNQMP_VINITHI_MASK;
109 	else
110 		return PM_RET_ERROR_ARGS;
111 
112 	mmio_write_32(rpu_cfg_addr, val);
113 
114 	return PM_RET_SUCCESS;
115 }
116 
117 /**
118  * pm_ioctl_config_tcm_comb() - Configure TCM combined mode
119  * @value	Value to set (Split/Combined)
120  *
121  * This function configures TCM to be in split mode or combined
122  * mode.
123  *
124  * @return	Returns status, either success or error+reason
125  */
126 static enum pm_ret_status pm_ioctl_config_tcm_comb(unsigned int value)
127 {
128 	unsigned int val;
129 
130 	val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
131 
132 	if (value == PM_RPU_TCM_SPLIT)
133 		val &= ~ZYNQMP_TCM_COMB_MASK;
134 	else if (value == PM_RPU_TCM_COMB)
135 		val |= ZYNQMP_TCM_COMB_MASK;
136 	else
137 		return PM_RET_ERROR_ARGS;
138 
139 	mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
140 
141 	return PM_RET_SUCCESS;
142 }
143 
144 /**
145  * pm_ioctl_set_tapdelay_bypass() -  Enable/Disable tap delay bypass
146  * @type	Type of tap delay to enable/disable (e.g. QSPI)
147  * @value	Enable/Disable
148  *
149  * This function enable/disable tap delay bypass.
150  *
151  * @return	Returns status, either success or error+reason
152  */
153 static enum pm_ret_status pm_ioctl_set_tapdelay_bypass(unsigned int type,
154 						       unsigned int value)
155 {
156 	if ((value != PM_TAPDELAY_BYPASS_ENABLE &&
157 	     value != PM_TAPDELAY_BYPASS_DISABLE) || type >= PM_TAPDELAY_MAX)
158 		return PM_RET_ERROR_ARGS;
159 
160 	return pm_mmio_write(IOU_TAPDLY_BYPASS, TAP_DELAY_MASK, value << type);
161 }
162 
163 /**
164  * pm_ioctl_set_sgmii_mode() -  Set SGMII mode for the GEM device
165  * @nid		Node ID of the device
166  * @value	Enable/Disable
167  *
168  * This function enable/disable SGMII mode for the GEM device.
169  * While enabling SGMII mode, it also ties the GEM PCS Signal
170  * Detect to 1 and selects EMIO for RX clock generation.
171  *
172  * @return	Returns status, either success or error+reason
173  */
174 static enum pm_ret_status pm_ioctl_set_sgmii_mode(enum pm_node_id nid,
175 						  unsigned int value)
176 {
177 	unsigned int val, mask, shift;
178 	enum pm_ret_status ret;
179 
180 	if (value != PM_SGMII_DISABLE && value != PM_SGMII_ENABLE)
181 		return PM_RET_ERROR_ARGS;
182 
183 	switch (nid) {
184 	case NODE_ETH_0:
185 		shift = 0;
186 		break;
187 	case NODE_ETH_1:
188 		shift = 1;
189 		break;
190 	case NODE_ETH_2:
191 		shift = 2;
192 		break;
193 	case NODE_ETH_3:
194 		shift = 3;
195 		break;
196 	default:
197 		return PM_RET_ERROR_ARGS;
198 	}
199 
200 	if (value == PM_SGMII_DISABLE) {
201 		mask = GEM_SGMII_MASK << GEM_CLK_CTRL_OFFSET * shift;
202 		ret = pm_mmio_write(IOU_GEM_CLK_CTRL, mask, 0U);
203 	} else {
204 		/* Tie the GEM PCS Signal Detect to 1 */
205 		mask = SGMII_SD_MASK << SGMII_SD_OFFSET * shift;
206 		val = SGMII_PCS_SD_1 << SGMII_SD_OFFSET * shift;
207 		ret = pm_mmio_write(IOU_GEM_CTRL, mask, val);
208 		if (ret != PM_RET_SUCCESS)
209 			return ret;
210 
211 		/* Set the GEM to SGMII mode */
212 		mask = GEM_CLK_CTRL_MASK << GEM_CLK_CTRL_OFFSET * shift;
213 		val = GEM_RX_SRC_SEL_GTR | GEM_SGMII_MODE;
214 		val <<= GEM_CLK_CTRL_OFFSET * shift;
215 		ret =  pm_mmio_write(IOU_GEM_CLK_CTRL, mask, val);
216 	}
217 
218 	return ret;
219 }
220 
221 /**
222  * pm_ioctl_sd_dll_reset() -  Reset DLL logic
223  * @nid		Node ID of the device
224  * @type	Reset type
225  *
226  * This function resets DLL logic for the SD device.
227  *
228  * @return	Returns status, either success or error+reason
229  */
230 static enum pm_ret_status pm_ioctl_sd_dll_reset(enum pm_node_id nid,
231 						unsigned int type)
232 {
233 	unsigned int mask, val;
234 	enum pm_ret_status ret;
235 
236 	if (nid == NODE_SD_0) {
237 		mask = ZYNQMP_SD0_DLL_RST_MASK;
238 		val = ZYNQMP_SD0_DLL_RST;
239 	} else if (nid == NODE_SD_1) {
240 		mask = ZYNQMP_SD1_DLL_RST_MASK;
241 		val = ZYNQMP_SD1_DLL_RST;
242 	} else {
243 		return PM_RET_ERROR_ARGS;
244 	}
245 
246 	switch (type) {
247 	case PM_DLL_RESET_ASSERT:
248 	case PM_DLL_RESET_PULSE:
249 		ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, val);
250 		if (ret != PM_RET_SUCCESS)
251 			return ret;
252 
253 		if (type == PM_DLL_RESET_ASSERT)
254 			break;
255 		mdelay(1);
256 	case PM_DLL_RESET_RELEASE:
257 		ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, 0);
258 		break;
259 	default:
260 		ret = PM_RET_ERROR_ARGS;
261 		break;
262 	}
263 
264 	return ret;
265 }
266 
267 /**
268  * pm_ioctl_sd_set_tapdelay() -  Set tap delay for the SD device
269  * @nid		Node ID of the device
270  * @type	Type of tap delay to set (input/output)
271  * @value	Value to set fot the tap delay
272  *
273  * This function sets input/output tap delay for the SD device.
274  *
275  * @return	Returns status, either success or error+reason
276  */
277 static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid,
278 						   enum tap_delay_type type,
279 						   unsigned int value)
280 {
281 	unsigned int shift;
282 	enum pm_ret_status ret;
283 
284 	if (nid == NODE_SD_0)
285 		shift = 0;
286 	else if (nid == NODE_SD_1)
287 		shift = ZYNQMP_SD_TAP_OFFSET;
288 	else
289 		return PM_RET_ERROR_ARGS;
290 
291 	ret = pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_ASSERT);
292 	if (ret != PM_RET_SUCCESS)
293 		return ret;
294 
295 	if (type == PM_TAPDELAY_INPUT) {
296 		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
297 				    (ZYNQMP_SD_ITAPCHGWIN_MASK << shift),
298 				    (ZYNQMP_SD_ITAPCHGWIN << shift));
299 		if (ret != PM_RET_SUCCESS)
300 			goto reset_release;
301 		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
302 				    (ZYNQMP_SD_ITAPDLYENA_MASK << shift),
303 				    (ZYNQMP_SD_ITAPDLYENA << shift));
304 		if (ret != PM_RET_SUCCESS)
305 			goto reset_release;
306 		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
307 				    (ZYNQMP_SD_ITAPDLYSEL_MASK << shift),
308 				    (value << shift));
309 		if (ret != PM_RET_SUCCESS)
310 			goto reset_release;
311 		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
312 				    (ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 0);
313 	} else if (type == PM_TAPDELAY_OUTPUT) {
314 		ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
315 				    (ZYNQMP_SD_OTAPDLYENA_MASK << shift),
316 				    (ZYNQMP_SD_OTAPDLYENA << shift));
317 		if (ret != PM_RET_SUCCESS)
318 			goto reset_release;
319 		ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
320 				    (ZYNQMP_SD_OTAPDLYSEL_MASK << shift),
321 				    (value << shift));
322 	} else {
323 		ret = PM_RET_ERROR_ARGS;
324 	}
325 
326 reset_release:
327 	pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_RELEASE);
328 	return ret;
329 }
330 
331 /**
332  * pm_ioctl_set_pll_frac_mode() -  Ioctl function for
333  *				   setting pll mode
334  * @pll     PLL id
335  * @mode    Mode fraction/integar
336  *
337  * This function sets PLL mode
338  *
339  * @return      Returns status, either success or error+reason
340  */
341 static enum pm_ret_status pm_ioctl_set_pll_frac_mode
342 			(unsigned int pll, unsigned int mode)
343 {
344 	return pm_api_clk_set_pll_mode(pll, mode);
345 }
346 
347 /**
348  * pm_ioctl_get_pll_frac_mode() -  Ioctl function for
349  *				   getting pll mode
350  * @pll     PLL id
351  * @mode    Mode fraction/integar
352  *
353  * This function return current PLL mode
354  *
355  * @return      Returns status, either success or error+reason
356  */
357 static enum pm_ret_status pm_ioctl_get_pll_frac_mode
358 			(unsigned int pll, unsigned int *mode)
359 {
360 	return pm_api_clk_get_pll_mode(pll, mode);
361 }
362 
363 /**
364  * pm_ioctl_set_pll_frac_data() -  Ioctl function for
365  *				   setting pll fraction data
366  * @pll     PLL id
367  * @data    fraction data
368  *
369  * This function sets fraction data.
370  * It is valid for fraction mode only.
371  *
372  * @return      Returns status, either success or error+reason
373  */
374 static enum pm_ret_status pm_ioctl_set_pll_frac_data
375 			(unsigned int pll, unsigned int data)
376 {
377 	return pm_api_clk_set_pll_frac_data(pll, data);
378 }
379 
380 /**
381  * pm_ioctl_get_pll_frac_data() -  Ioctl function for
382  *				   getting pll fraction data
383  * @pll     PLL id
384  * @data    fraction data
385  *
386  * This function returns fraction data value.
387  *
388  * @return      Returns status, either success or error+reason
389  */
390 static enum pm_ret_status pm_ioctl_get_pll_frac_data
391 			(unsigned int pll, unsigned int *data)
392 {
393 	return pm_api_clk_get_pll_frac_data(pll, data);
394 }
395 
396 /**
397  * pm_ioctl_write_ggs() - Ioctl function for writing
398  *			  global general storage (ggs)
399  * @index	GGS register index
400  * @value	Register value to be written
401  *
402  * This function writes value to GGS register.
403  *
404  * @return      Returns status, either success or error+reason
405  */
406 static enum pm_ret_status pm_ioctl_write_ggs(unsigned int index,
407 					     unsigned int value)
408 {
409 	if (index >= GGS_NUM_REGS)
410 		return PM_RET_ERROR_ARGS;
411 
412 	return pm_mmio_write(GGS_BASEADDR + (index << 2),
413 			     0xFFFFFFFFU, value);
414 }
415 
416 /**
417  * pm_ioctl_read_ggs() - Ioctl function for reading
418  *			 global general storage (ggs)
419  * @index	GGS register index
420  * @value	Register value
421  *
422  * This function returns GGS register value.
423  *
424  * @return      Returns status, either success or error+reason
425  */
426 static enum pm_ret_status pm_ioctl_read_ggs(unsigned int index,
427 					    unsigned int *value)
428 {
429 	if (index >= GGS_NUM_REGS)
430 		return PM_RET_ERROR_ARGS;
431 
432 	return pm_mmio_read(GGS_BASEADDR + (index << 2), value);
433 }
434 
435 /**
436  * pm_ioctl_write_pggs() - Ioctl function for writing persistent
437  *			   global general storage (pggs)
438  * @index	PGGS register index
439  * @value	Register value to be written
440  *
441  * This function writes value to PGGS register.
442  *
443  * @return      Returns status, either success or error+reason
444  */
445 static enum pm_ret_status pm_ioctl_write_pggs(unsigned int index,
446 					      unsigned int value)
447 {
448 	if (index >= PGGS_NUM_REGS)
449 		return PM_RET_ERROR_ARGS;
450 
451 	return pm_mmio_write(PGGS_BASEADDR + (index << 2),
452 			     0xFFFFFFFFU, value);
453 }
454 
455 /**
456  * pm_ioctl_afi() - Ioctl function for writing afi values
457  *
458  * @index 	AFI register index
459  * @value	Register value to be written
460  *
461  *
462  * @return      Returns status, either success or error+reason
463  */
464 static enum pm_ret_status pm_ioctl_afi(unsigned int index,
465 					      unsigned int value)
466 {
467 	unsigned int mask;
468 	unsigned int regarr[] = {0xFD360000,
469 				0xFD360014,
470 				0xFD370000,
471 				0xFD370014,
472 				0xFD380000,
473 				0xFD380014,
474 				0xFD390000,
475 				0xFD390014,
476 				0xFD3a0000,
477 				0xFD3a0014,
478 				0xFD3b0000,
479 				0xFD3b0014,
480 				0xFF9b0000,
481 				0xFF9b0014,
482 				0xFD615000,
483 				0xFF419000,
484 				};
485 
486 	if (index >= ARRAY_SIZE(regarr))
487 		return PM_RET_ERROR_ARGS;
488 
489 	if (index < AFIFM6_WRCTRL)
490 		mask = FABRIC_WIDTH;
491 	else
492 		mask = 0xf00;
493 
494 	return pm_mmio_write(regarr[index], mask, value);
495 }
496 
497 /**
498  * pm_ioctl_read_pggs() - Ioctl function for reading persistent
499  *			  global general storage (pggs)
500  * @index	PGGS register index
501  * @value	Register value
502  *
503  * This function returns PGGS register value.
504  *
505  * @return      Returns status, either success or error+reason
506  */
507 static enum pm_ret_status pm_ioctl_read_pggs(unsigned int index,
508 					     unsigned int *value)
509 {
510 	if (index >= PGGS_NUM_REGS)
511 		return PM_RET_ERROR_ARGS;
512 
513 	return pm_mmio_read(PGGS_BASEADDR + (index << 2), value);
514 }
515 
516 /**
517  * pm_ioctl_ulpi_reset() - Ioctl function for performing ULPI reset
518  *
519  * This function peerforms the ULPI reset sequence for resetting
520  * the ULPI transceiver.
521  *
522  * @return      Returns status, either success or error+reason
523  */
524 static enum pm_ret_status pm_ioctl_ulpi_reset(void)
525 {
526 	enum pm_ret_status ret;
527 
528 	ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
529 			    ZYNQMP_ULPI_RESET_VAL_HIGH);
530 	if (ret != PM_RET_SUCCESS)
531 		return ret;
532 
533 	/* Drive ULPI assert for atleast 1ms */
534 	mdelay(1);
535 
536 	ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
537 			    ZYNQMP_ULPI_RESET_VAL_LOW);
538 	if (ret != PM_RET_SUCCESS)
539 		return ret;
540 
541 	/* Drive ULPI de-assert for atleast 1ms */
542 	mdelay(1);
543 
544 	ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
545 			    ZYNQMP_ULPI_RESET_VAL_HIGH);
546 
547 	return ret;
548 }
549 
550 /**
551  * pm_ioctl_set_boot_health_status() - Ioctl for setting healthy boot status
552  *
553  * This function sets healthy bit value to indicate boot health status
554  * to firmware.
555  *
556  * @return      Returns status, either success or error+reason
557  */
558 static enum pm_ret_status pm_ioctl_set_boot_health_status(unsigned int value)
559 {
560 	return pm_mmio_write(PM_BOOT_HEALTH_STATUS_REG,
561 			     PM_BOOT_HEALTH_STATUS_MASK, value);
562 }
563 
564 /**
565  * pm_api_ioctl() -  PM IOCTL API for device control and configs
566  * @node_id	Node ID of the device
567  * @ioctl_id	ID of the requested IOCTL
568  * @arg1	Argument 1 to requested IOCTL call
569  * @arg2	Argument 2 to requested IOCTL call
570  * @value	Returned output value
571  *
572  * This function calls IOCTL to firmware for device control and configuration.
573  *
574  * @return	Returns status, either success or error+reason
575  */
576 enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
577 				unsigned int ioctl_id,
578 				unsigned int arg1,
579 				unsigned int arg2,
580 				unsigned int *value)
581 {
582 	enum pm_ret_status ret;
583 
584 	switch (ioctl_id) {
585 	case IOCTL_GET_RPU_OPER_MODE:
586 		ret = pm_ioctl_get_rpu_oper_mode(value);
587 		break;
588 	case IOCTL_SET_RPU_OPER_MODE:
589 		ret = pm_ioctl_set_rpu_oper_mode(arg1);
590 		break;
591 	case IOCTL_RPU_BOOT_ADDR_CONFIG:
592 		ret = pm_ioctl_config_boot_addr(nid, arg1);
593 		break;
594 	case IOCTL_TCM_COMB_CONFIG:
595 		ret = pm_ioctl_config_tcm_comb(arg1);
596 		break;
597 	case IOCTL_SET_TAPDELAY_BYPASS:
598 		ret = pm_ioctl_set_tapdelay_bypass(arg1, arg2);
599 		break;
600 	case IOCTL_SET_SGMII_MODE:
601 		ret = pm_ioctl_set_sgmii_mode(nid, arg1);
602 		break;
603 	case IOCTL_SD_DLL_RESET:
604 		ret = pm_ioctl_sd_dll_reset(nid, arg1);
605 		break;
606 	case IOCTL_SET_SD_TAPDELAY:
607 		ret = pm_ioctl_sd_set_tapdelay(nid, arg1, arg2);
608 		break;
609 	case IOCTL_SET_PLL_FRAC_MODE:
610 		ret = pm_ioctl_set_pll_frac_mode(arg1, arg2);
611 		break;
612 	case IOCTL_GET_PLL_FRAC_MODE:
613 		ret = pm_ioctl_get_pll_frac_mode(arg1, value);
614 		break;
615 	case IOCTL_SET_PLL_FRAC_DATA:
616 		ret = pm_ioctl_set_pll_frac_data(arg1, arg2);
617 		break;
618 	case IOCTL_GET_PLL_FRAC_DATA:
619 		ret = pm_ioctl_get_pll_frac_data(arg1, value);
620 		break;
621 	case IOCTL_WRITE_GGS:
622 		ret = pm_ioctl_write_ggs(arg1, arg2);
623 		break;
624 	case IOCTL_READ_GGS:
625 		ret = pm_ioctl_read_ggs(arg1, value);
626 		break;
627 	case IOCTL_WRITE_PGGS:
628 		ret = pm_ioctl_write_pggs(arg1, arg2);
629 		break;
630 	case IOCTL_READ_PGGS:
631 		ret = pm_ioctl_read_pggs(arg1, value);
632 		break;
633 	case IOCTL_ULPI_RESET:
634 		ret = pm_ioctl_ulpi_reset();
635 		break;
636 	case IOCTL_SET_BOOT_HEALTH_STATUS:
637 		ret = pm_ioctl_set_boot_health_status(arg1);
638 		break;
639 	case IOCTL_AFI:
640 		ret = pm_ioctl_afi(arg1, arg2);
641 		break;
642 	default:
643 		ret = PM_RET_ERROR_NOTSUPPORTED;
644 		break;
645 	}
646 
647 	return ret;
648 }
649