研发干货丨关于RK3399 开发板休眠、关机功能简析

文章目录

Power按键

~短按休眠和长按关机

关机命令

~poweroff命令关机


OK3399-C平台采用RK3399 主CPU芯片设计,支持底板Power按键休眠唤醒以及关机功能,Linux命令行也可以通过命令进行关机,下面对这两种方式进行简单的解析。

Power按键

Power按键的休眠唤醒功能一般是与PMIC芯片和CPU相关的,硬件上该按键会连接到PMIC的PWRON引脚和CPU对应的引脚上。

先来看power按键在PMIC侧的响应机制,POWER键按下以后,经过TdbPWRONF时间以后,INT引脚变为低电平,触发中断。内核驱动响应中断,执行休眠程序。

如果PWRON继续保持低电平超过TdPWRONLP,PMIC就会响应,RK3399板卡将进行关机。

短按休眠和长按关机

Log信息:

[   10.250531] PM: Syncing filesystems ... done.[   10.255148] test message.            //加入的测试信息[   10.256842] Freezing user space processes ... (elapsed 0.003 seconds) done.[   10.260770] Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done. [   10.263308] Suspending console(s) (use no_console_suspend to debug)INFO:    sleep mode config[0xde]:INFO:           AP_PWROFFINFO:           SLP_ARMPD INFO:           SLP_PLLPDINFO:           DDR_RETINFO:           SLP_CENTER_PDINFO:    wakeup source config[0x804]:INFO:           GPIO interrupt can wakeup systemINFO:           PWM interrupt can wakeup systemINFO:    PWM CONFIG[0x4]:INFO:           PWM: PWM2D_REGULATOR_ENINFO:    APIOS info[0x0]:INFO:           not configINFO:    GPIO POWER INFO:INFO:           GPIO1_C1INFO:           GPIO1_B6INFO:    PMU_MODE_CONG: 0x1477bf51

涉及驱动文件

kernel/kernel/power/suspend.c
/** * enter_state - Do common work needed to enter system sleep state. * @state: System sleep state to enter. * * Make sure that no one else is trying to put the system into a sleep state. * Fail if that's not the case.  Otherwise, prepare for system suspend, make the * system enter the given sleep state and clean up after wakeup. */static int enter_state(suspend_state_t state){        int error;        trace_suspend_resume(TPS("suspend_enter"), state, true);        if (state == PM_SUSPEND_FREEZE) {#ifdef CONFIG_PM_DEBUG                if (pm_test_level != TEST_NONE && pm_test_level <= TEST_CPUS) {                        pr_warning("PM: Unsupported test mode for suspend to idle,"                                   "please choose none/freezer/devices/platform.\n");                        return -EAGAIN;                }#endif        } else if (!valid_state(state)) {                return -EINVAL;        }        if (!mutex_trylock(&pm_mutex))                return -EBUSY;        if (state == PM_SUSPEND_FREEZE)                freeze_begin();#ifndef CONFIG_SUSPEND_SKIP_SYNC        trace_suspend_resume(TPS("sync_filesystems"), 0, true);        printk(KERN_INFO "PM: Syncing filesystems ... ");        sys_sync();        printk("done.\n");        trace_suspend_resume(TPS("sync_filesystems"), 0, false);#endif        pr_debug("PM: Preparing system for sleep (%s)\n", pm_states[state]);        pm_suspend_clear_flags();        error = suspend_prepare(state);        if (error)                goto Unlock;        if (suspend_test(TEST_FREEZER))                goto Finish;        trace_suspend_resume(TPS("suspend_enter"), state, false);        pr_debug("PM: Suspending system (%s)\n", pm_states[state]);        pm_restrict_gfp_mask();        error = suspend_devices_and_enter(state);        pm_restore_gfp_mask(); Finish:        pr_debug("PM: Finishing wakeup.\n");        suspend_finish(); Unlock:        mutex_unlock(&pm_mutex);        return error;}

通过代码可知,Power按键触发的休眠和关机会执行sys_sync函数,进行系统数据的保存,这与突然掉电导致的异常关机是有很大区别的。

关机命令

RK3399 平台Linux下的关机命令有shutdown、halt、poweroff命令等.

Poweroff命令关机

Log信息:

[root@rk3399:/]# poweroff[root@rk3399:/]# stop finishedStopping input-event-daemon: donestop auto-reboot finishedStopping dnsmasq: OKStopping vsftpd: stopped vsftpd (pid 1072)OK[   20.099392] [BT_RFKILL]: bt shut off power[   20.132245] configfs-gadget gadget: unbind function 'Function FS Gadget'/ffffffc07b025a38Stopping sshd: OKStopping lighttpd: OKGracefully shutting down php-fpm . doneStopping dhcpcd...stopped /sbin/dhcpcd (pid 924)killall: rkisp_3A_server: no process killedStopping network: OKstop finishedStopping system message bus: doneSaving random seed... done.Stopping logging: OKumount: can't remount adb read-onlyumount: devtmpfs busy - remounted read-only[   21.589884] EXT4-fs (mmcblk2p8): re-mounted. Opts: (null)The system is going down NOW! Sent SIGTERM to all processesSent SIGKILL to all processesRequesting system poweroff[   23.597578] cpu cpu4: min=816000, max=816000[   23.598572] cpu cpu0: min=816000, max=816000[   23.669985] I : [File] : drivers/gpu/arm/midgard_for_linux/platform/rk/mali_kbase_config_rk.c; [Line] : 274; [Func] : kbase_platform_rk_shutdown(); to make vdd_gpu enabled for turning off pd_gpu in pm_framework.[   23.671701] rk-vcodec ff660000.rkvdec: shutdown[   23.672132] rk-vcodec ff650000.vpu_service: shutdown[   23.673046] rk808 0-001b: System power off[   23.673419] rk808 0-001b: test message        //加入的测试信息
[root@rk3399:/]# poweroff --helpBusyBox v1.27.2 (2020-03-19 09:39:13 UTC) multi-call binary.Usage: poweroff [-d DELAY] [-n] [-f]Halt and shut off power        -d SEC  Delay interval        -n      Do not sync        -f      Force (don't go through init)

Poweroff命令做的事可以从打印信息上看出来,其实可以分为两部分,一是配置系统,停止当前的服务,进行数据保存。二是调用电源管理驱动对应的接口,完成电源配置,RK3399 主板进行关机。

涉及驱动文件

kernel/drivers/mfd/rk808.c
static void rk808_syscore_shutdown(void){        int ret;        struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);        if (!rk808) {                dev_warn(&rk808_i2c_client->dev,                         "have no rk808, so do nothing here\n");                return;        }        /* close rtc int when power off */        regmap_update_bits(rk808->regmap,                           RK808_INT_STS_MSK_REG1,                           (0x3 << 5), (0x3 << 5));        regmap_update_bits(rk808->regmap,                           RK808_RTC_INT_REG,                           (0x3 << 2), (0x0 << 2));        /*         * For PMIC that power off supplies by write register via i2c bus,         * it's better to do power off at syscore shutdown here.         *         * Because when run to kernel's "pm_power_off" call, i2c may has         * been stopped or PMIC may not be able to get i2c transfer while         * there are too many devices are competiting.         */         if (system_state == SYSTEM_POWER_OFF) {                /* power off supplies ! */                if (pm_shutdown) {                        dev_info(&rk808_i2c_client->dev, "System power off\n");                        ret = pm_shutdown(rk808->regmap);                        if (ret)                                dev_err(&rk808_i2c_client->dev,                                        "System power off error!\n");                        mdelay(10);                        dev_info(&rk808_i2c_client->dev,                                 "Cpu should never reach here, stop!\n");                        while (1)                                ;                }        }}
#define DEV_OFF_RST     BIT(3)static int rk808_shutdown(struct regmap *regmap){        int ret;        ret = regmap_update_bits(regmap,                                 RK808_DEVCTRL_REG,                                 DEV_OFF_RST, DEV_OFF_RST);        return ret;}

最终调用的的rk808shutdown接口函数,对RK808DEVCTRLREG寄存器写入DEVOFF_RST,触发RK3399主板关机。

点击此处进入飞凌嵌入式官网>>,了解关于OK3399-C开发板的更多信息。

(0)

相关推荐