// SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* * Copyright (C) 2014-2022 Amlogic, Inc. All rights reserved. * * All information contained herein is Amlogic confidential. * * This software is provided to you pursuant to Software License Agreement * (SLA) with Amlogic Inc ("Amlogic"). This software may be used * only in accordance with the terms of this agreement. * * Redistribution and use in source and binary forms, with or without * modification is strictly prohibited without prior written permission from * Amlogic. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include //#include #include #include #define PM_SUSPEND_ON (0) #define PM_SUSPEND_TO_IDLE (1) #define PM_RESUME (2) #define PM_SUSPEND_MEM (3) #define PM_SUSPEND_MIN PM_SUSPEND_TO_IDLE #define PM_SUSPEND_MAX (4) #define PM_DEBUG static struct list_head devices; #ifdef PM_DEBUG static int test_pm_suspend(void *dev_info) { printf("%s\n", __func__); return 0; } static int test_pm_resume(void *dev_info) { printf("%s\n", __func__); return 0; } static int test_pm_poweroff(void *dev_info) { printf("%s\n", __func__); return 0; } #endif #ifdef PM_DEBUG struct dev_pm_ops *dev_register_pm(char *name, FUNC_PTR suspend, FUNC_PTR resume, FUNC_PTR poweroff); char name[] = "test_pm_name"; #endif void pm_initialize(void) { INIT_LIST_HEAD(&devices); #ifdef PM_DEBUG dev_register_pm(name, test_pm_suspend, test_pm_resume, test_pm_poweroff); #endif } extern int cpu_suspend(unsigned long arg); void pm_suspend(void) { struct list_head *dentry; struct dev_pm_ops *pm_ops; debug("suspend entry\n"); list_for_each(dentry, &devices) { pm_ops = list_entry(dentry, struct dev_pm_ops, link); if (pm_ops->suspend) { pm_ops->suspend((void *)pm_ops); debug("%s suspend done\n", pm_ops->name); } else { printf("suspend is not illeage!\n"); } } printf("uboot str suspend done!\n"); cpu_suspend(0); list_for_each_prev(dentry, &devices) { pm_ops = list_entry(dentry, struct dev_pm_ops, link); if (pm_ops->resume) { pm_ops->resume((void *)pm_ops); debug("%s resume done\n", pm_ops->name); } else { printf("suspend is not illeage!\n"); } } printf("uboot str resume done!\n"); } void pm_poweroff(void) { struct list_head *dentry; struct dev_pm_ops *pm_ops; debug("poweroff entry\n"); list_for_each(dentry, &devices) { pm_ops = list_entry(dentry, struct dev_pm_ops, link); if (pm_ops->poweroff) { pm_ops->poweroff((void *)pm_ops); debug("%s poweroff done\n", pm_ops->name); } else { printf("poweroff is not illeage!\n"); } } printf("uboot poweroff done!\n"); aml_system_off(); } struct dev_pm_ops *dev_register_pm(char *name, FUNC_PTR suspend, FUNC_PTR resume, FUNC_PTR poweroff) { struct dev_pm_ops *ops; if (!name || !suspend || !resume || !poweroff) { printf("Invalid pass parameters\n"); return NULL; } ops = (struct dev_pm_ops *)malloc((size_t)sizeof(struct dev_pm_ops)); if (!ops) { printf("Wakeup source malloc fail!!\n"); return NULL; } ops->name = name; ops->suspend = suspend; ops->resume = resume; ops->poweroff = poweroff; list_add_tail(&ops->link, &devices); return ops; } int dev_unregister_pm(struct dev_pm_ops *arg) { struct dev_pm_ops *ops = arg; if (!ops) { printf("Invalid parameters\n"); return -1; } list_del(&ops->link); free(ops); ops = NULL; return 0; }