| .. | .. |
|---|
| 17 | 17 | #include <linux/pm.h> |
|---|
| 18 | 18 | #include <linux/regulator/driver.h> |
|---|
| 19 | 19 | #include <linux/regulator/machine.h> |
|---|
| 20 | +#include <linux/rockchip/rockchip_pm_config.h> |
|---|
| 20 | 21 | #include <linux/rockchip/rockchip_sip.h> |
|---|
| 21 | 22 | #include <linux/suspend.h> |
|---|
| 22 | 23 | #include <dt-bindings/input/input.h> |
|---|
| .. | .. |
|---|
| 51 | 52 | } on_off_regs_list[RK_PM_STATE_MAX]; |
|---|
| 52 | 53 | #endif |
|---|
| 53 | 54 | |
|---|
| 54 | | -static struct rk_sleep_config { |
|---|
| 55 | | - u32 mode_config; |
|---|
| 56 | | - u32 wakeup_config; |
|---|
| 57 | | -} sleep_config[RK_PM_STATE_MAX]; |
|---|
| 58 | | - |
|---|
| 59 | 55 | /* rk_tag related defines */ |
|---|
| 60 | 56 | #define sleep_tag_next(t) \ |
|---|
| 61 | 57 | ((struct rk_sleep_tag *)((__u32 *)(t) + (t)->hdr.size)) |
|---|
| .. | .. |
|---|
| 81 | 77 | struct rk_sleep_tag slp_tags; |
|---|
| 82 | 78 | }; |
|---|
| 83 | 79 | |
|---|
| 80 | +struct rk_sleep_config *sleep_config; |
|---|
| 81 | + |
|---|
| 84 | 82 | static const struct of_device_id pm_match_table[] = { |
|---|
| 83 | + { .compatible = "rockchip,pm-config",}, |
|---|
| 85 | 84 | { .compatible = "rockchip,pm-px30",}, |
|---|
| 86 | 85 | { .compatible = "rockchip,pm-rk1808",}, |
|---|
| 87 | 86 | { .compatible = "rockchip,pm-rk322x",}, |
|---|
| .. | .. |
|---|
| 253 | 252 | |
|---|
| 254 | 253 | return 0; |
|---|
| 255 | 254 | } |
|---|
| 255 | + |
|---|
| 256 | +const struct rk_sleep_config *rockchip_get_cur_sleep_config(void) |
|---|
| 257 | +{ |
|---|
| 258 | + suspend_state_t suspend_state = mem_sleep_current; |
|---|
| 259 | + enum rk_pm_state state = suspend_state - PM_SUSPEND_MEM; |
|---|
| 260 | + |
|---|
| 261 | + if (state >= RK_PM_STATE_MAX) |
|---|
| 262 | + return NULL; |
|---|
| 263 | + |
|---|
| 264 | + return &sleep_config[state]; |
|---|
| 265 | +} |
|---|
| 266 | +EXPORT_SYMBOL_GPL(rockchip_get_cur_sleep_config); |
|---|
| 256 | 267 | #endif |
|---|
| 257 | 268 | |
|---|
| 258 | 269 | static int parse_mcu_sleep_config(struct device_node *node) |
|---|
| .. | .. |
|---|
| 364 | 375 | return ret; |
|---|
| 365 | 376 | } |
|---|
| 366 | 377 | |
|---|
| 378 | +static int parse_io_config(struct device *dev) |
|---|
| 379 | +{ |
|---|
| 380 | + int ret = 0, cnt; |
|---|
| 381 | + struct device_node *node = dev->of_node; |
|---|
| 382 | + struct rk_sleep_config *config = &sleep_config[RK_PM_MEM]; |
|---|
| 383 | + |
|---|
| 384 | + cnt = of_property_count_u32_elems(node, "rockchip,sleep-io-config"); |
|---|
| 385 | + if (cnt > 0) { |
|---|
| 386 | + /* 0 as the last element of virtual_pwroff_irqs */ |
|---|
| 387 | + config->sleep_io_config = |
|---|
| 388 | + devm_kmalloc_array(dev, cnt, sizeof(u32), GFP_KERNEL); |
|---|
| 389 | + if (!config->sleep_io_config) { |
|---|
| 390 | + ret = -ENOMEM; |
|---|
| 391 | + goto out; |
|---|
| 392 | + } |
|---|
| 393 | + |
|---|
| 394 | + ret = of_property_read_u32_array(node, "rockchip,sleep-io-config", |
|---|
| 395 | + config->sleep_io_config, cnt); |
|---|
| 396 | + if (ret) { |
|---|
| 397 | + dev_err(dev, "get rockchip,sleep-io-config error\n"); |
|---|
| 398 | + goto out; |
|---|
| 399 | + } |
|---|
| 400 | + |
|---|
| 401 | + config->sleep_io_config_cnt = cnt; |
|---|
| 402 | + } else { |
|---|
| 403 | + dev_dbg(dev, "not set sleep-pin-config\n"); |
|---|
| 404 | + } |
|---|
| 405 | + |
|---|
| 406 | +out: |
|---|
| 407 | + return ret; |
|---|
| 408 | +} |
|---|
| 409 | + |
|---|
| 367 | 410 | static int pm_config_probe(struct platform_device *pdev) |
|---|
| 368 | 411 | { |
|---|
| 369 | 412 | const struct of_device_id *match_id; |
|---|
| 370 | 413 | struct device_node *node; |
|---|
| 371 | | - struct rk_sleep_config *config = &sleep_config[RK_PM_MEM]; |
|---|
| 372 | | - u32 pwm_regulator_config = 0; |
|---|
| 373 | | - int gpio_temp[10]; |
|---|
| 374 | | - u32 sleep_debug_en = 0; |
|---|
| 375 | | - u32 apios_suspend = 0; |
|---|
| 376 | | - u32 io_ret_config = 0; |
|---|
| 377 | | - u32 sleep_pin_config[2] = {0}; |
|---|
| 414 | + struct rk_sleep_config *config; |
|---|
| 378 | 415 | |
|---|
| 379 | 416 | enum of_gpio_flags flags; |
|---|
| 380 | 417 | int i = 0; |
|---|
| .. | .. |
|---|
| 392 | 429 | return -ENODEV; |
|---|
| 393 | 430 | } |
|---|
| 394 | 431 | |
|---|
| 432 | + sleep_config = |
|---|
| 433 | + devm_kmalloc_array(&pdev->dev, RK_PM_STATE_MAX, |
|---|
| 434 | + sizeof(*sleep_config), GFP_KERNEL); |
|---|
| 435 | + if (!sleep_config) |
|---|
| 436 | + return -ENOMEM; |
|---|
| 437 | + |
|---|
| 438 | + config = &sleep_config[RK_PM_MEM]; |
|---|
| 439 | + |
|---|
| 395 | 440 | if (of_property_read_u32_array(node, |
|---|
| 396 | 441 | "rockchip,sleep-mode-config", |
|---|
| 397 | 442 | &config->mode_config, 1)) |
|---|
| .. | .. |
|---|
| 408 | 453 | |
|---|
| 409 | 454 | if (of_property_read_u32_array(node, |
|---|
| 410 | 455 | "rockchip,pwm-regulator-config", |
|---|
| 411 | | - &pwm_regulator_config, 1)) |
|---|
| 456 | + &config->pwm_regulator_config, 1)) |
|---|
| 412 | 457 | dev_warn(&pdev->dev, "not set pwm-regulator-config\n"); |
|---|
| 413 | 458 | else |
|---|
| 414 | 459 | sip_smc_set_suspend_mode(PWM_REGULATOR_CONFIG, |
|---|
| 415 | | - pwm_regulator_config, |
|---|
| 460 | + config->pwm_regulator_config, |
|---|
| 416 | 461 | 0); |
|---|
| 417 | 462 | |
|---|
| 418 | 463 | length = of_gpio_named_count(node, "rockchip,power-ctrl"); |
|---|
| 419 | 464 | |
|---|
| 420 | 465 | if (length > 0 && length < 10) { |
|---|
| 466 | + config->power_ctrl_config_cnt = length; |
|---|
| 467 | + config->power_ctrl_config = |
|---|
| 468 | + devm_kmalloc_array(&pdev->dev, length, |
|---|
| 469 | + sizeof(u32), GFP_KERNEL); |
|---|
| 470 | + if (!config->power_ctrl_config) |
|---|
| 471 | + return -ENOMEM; |
|---|
| 472 | + |
|---|
| 421 | 473 | for (i = 0; i < length; i++) { |
|---|
| 422 | | - gpio_temp[i] = of_get_named_gpio_flags(node, |
|---|
| 423 | | - "rockchip,power-ctrl", |
|---|
| 424 | | - i, |
|---|
| 425 | | - &flags); |
|---|
| 426 | | - if (!gpio_is_valid(gpio_temp[i])) |
|---|
| 474 | + config->power_ctrl_config[i] = |
|---|
| 475 | + of_get_named_gpio_flags(node, |
|---|
| 476 | + "rockchip,power-ctrl", |
|---|
| 477 | + i, |
|---|
| 478 | + &flags); |
|---|
| 479 | + if (!gpio_is_valid(config->power_ctrl_config[i])) |
|---|
| 427 | 480 | break; |
|---|
| 428 | 481 | sip_smc_set_suspend_mode(GPIO_POWER_CONFIG, |
|---|
| 429 | 482 | i, |
|---|
| 430 | | - gpio_temp[i]); |
|---|
| 483 | + config->power_ctrl_config[i]); |
|---|
| 431 | 484 | } |
|---|
| 432 | 485 | } |
|---|
| 433 | 486 | sip_smc_set_suspend_mode(GPIO_POWER_CONFIG, i, PM_INVALID_GPIO); |
|---|
| 434 | 487 | |
|---|
| 435 | 488 | if (!of_property_read_u32_array(node, |
|---|
| 436 | 489 | "rockchip,sleep-debug-en", |
|---|
| 437 | | - &sleep_debug_en, 1)) |
|---|
| 490 | + &config->sleep_debug_en, 1)) |
|---|
| 438 | 491 | sip_smc_set_suspend_mode(SUSPEND_DEBUG_ENABLE, |
|---|
| 439 | | - sleep_debug_en, |
|---|
| 492 | + config->sleep_debug_en, |
|---|
| 440 | 493 | 0); |
|---|
| 441 | 494 | |
|---|
| 442 | 495 | if (!of_property_read_u32_array(node, |
|---|
| 443 | 496 | "rockchip,apios-suspend", |
|---|
| 444 | | - &apios_suspend, 1)) |
|---|
| 497 | + &config->apios_suspend, 1)) |
|---|
| 445 | 498 | sip_smc_set_suspend_mode(APIOS_SUSPEND_CONFIG, |
|---|
| 446 | | - apios_suspend, |
|---|
| 499 | + config->apios_suspend, |
|---|
| 447 | 500 | 0); |
|---|
| 448 | 501 | |
|---|
| 449 | 502 | if (!of_property_read_u32_array(node, |
|---|
| 450 | 503 | "rockchip,sleep-io-ret-config", |
|---|
| 451 | | - &io_ret_config, 1)) { |
|---|
| 452 | | - ret = sip_smc_set_suspend_mode(SUSPEND_IO_RET_CONFIG, io_ret_config, 0); |
|---|
| 504 | + &config->io_ret_config, 1)) { |
|---|
| 505 | + ret = sip_smc_set_suspend_mode(SUSPEND_IO_RET_CONFIG, config->io_ret_config, 0); |
|---|
| 453 | 506 | if (ret) |
|---|
| 454 | 507 | dev_warn(&pdev->dev, |
|---|
| 455 | 508 | "sleep-io-ret-config failed (%d), check parameters or update trust\n", |
|---|
| .. | .. |
|---|
| 458 | 511 | |
|---|
| 459 | 512 | if (!of_property_read_u32_array(node, |
|---|
| 460 | 513 | "rockchip,sleep-pin-config", |
|---|
| 461 | | - sleep_pin_config, 2)) { |
|---|
| 462 | | - ret = sip_smc_set_suspend_mode(SLEEP_PIN_CONFIG, sleep_pin_config[0], sleep_pin_config[1]); |
|---|
| 514 | + config->sleep_pin_config, 2)) { |
|---|
| 515 | + ret = sip_smc_set_suspend_mode(SLEEP_PIN_CONFIG, |
|---|
| 516 | + config->sleep_pin_config[0], |
|---|
| 517 | + config->sleep_pin_config[1]); |
|---|
| 463 | 518 | if (ret) |
|---|
| 464 | 519 | dev_warn(&pdev->dev, |
|---|
| 465 | 520 | "sleep-pin-config failed (%d), check parameters or update trust\n", |
|---|
| 466 | 521 | ret); |
|---|
| 467 | 522 | } |
|---|
| 468 | 523 | |
|---|
| 524 | + parse_io_config(&pdev->dev); |
|---|
| 469 | 525 | parse_mcu_sleep_config(node); |
|---|
| 470 | 526 | |
|---|
| 471 | 527 | #ifndef MODULE |
|---|