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