From: Chanwoo Choi Date: Thu, 7 Jan 2021 13:21:59 +0000 (+0900) Subject: pass-hal: rpi: Update pass-hal-rpi by using hal-api-power interface X-Git-Tag: submit/tizen/20210201.020414~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1df988a87c93e41370561e65f82da856073516ab;p=platform%2Fadaptation%2Frpi%2Fpass-hal-rpi.git pass-hal: rpi: Update pass-hal-rpi by using hal-api-power interface Prior pass-hal-rpi depends on PASS HAL interface (hal.h) provided by pass-hal-devel pkg. In order to keep the new HAL API package on Tizen 6.5, change the pass-hal-rpi package. [Mandatory implementation for HAL backend] - Power HAL backend must define 'hal_backend_power_data' symbol including the implementation of Power HAL interface. - Include /hal/lib64/libhal-backend-power.so Change-Id: Ib705482d398b5d0d3b3249b896fb477e882f5da6 Signed-off-by: Chanwoo Choi --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 090d0a7..229820d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,27 +1,38 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) PROJECT(pass-hal-rpi C) +SET(LIBRARY_NAME "hal-backend-power") SET(CMAKE_VERBOSE_MAKEFILE ON) +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(HAL_LIBDIR ${CMAKE_HAL_LIBDIR_PREFIX}) +SET(HAL_LICENSEDIR ${CMAKE_HAL_LICENSEDIR_PREFIX}) -SET(PKG_MODULES - dlog) INCLUDE(FindPkgConfig) -pkg_check_modules(pkgs REQUIRED ${PKG_MODULES}) +pkg_check_modules(pkgs REQUIRED + dlog + hal-api-common + hal-api-power +) FOREACH(flag ${pkgs_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) +SET(CMAKE_C_FLAGS "${CMAKE_CFLAGS} ${EXTRA_CFLAGS}") -SET(PREFIX ${CMAKE_INSTALL_PREFIX}) -SET(DEST_DIR ${LIB_INSTALL_DIR}/pass) +INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include) + +SET(SRCS + ${PROJECT_SOURCE_DIR}/src/${LIBRARY_NAME}.c + ${PROJECT_SOURCE_DIR}/src/sysfs.c) -ADD_SUBDIRECTORY(src/cpu) -ADD_SUBDIRECTORY(src/memory) +ADD_LIBRARY(${LIBRARY_NAME} SHARED ${SRCS}) +TARGET_LINK_LIBRARIES(${LIBRARY_NAME} ${pkgs_LDFLAGS} -ldl) -SET(CONF_DIR /etc/pass) SET(CONF_FILES ${CMAKE_CURRENT_SOURCE_DIR}/scripts/pass.conf ${CMAKE_CURRENT_SOURCE_DIR}/scripts/pass-cpu0.conf ${CMAKE_CURRENT_SOURCE_DIR}/scripts/pass-memory.conf) -INSTALL(FILES ${CONF_FILES} DESTINATION ${CONF_DIR}) -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/scripts/pass-hal.conf DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/tmpfiles.d) +INSTALL(FILES ${CONF_FILES} DESTINATION /hal/etc/pass) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/scripts/pass-hal.conf DESTINATION /hal/lib/tmpfiles.d) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE DESTINATION ${HAL_LICENSEDIR}/${PROJECT_NAME}) +INSTALL(TARGETS ${LIBRARY_NAME} DESTINATION ${HAL_LIBDIR} COMPONENT RuntimeLibraries) diff --git a/packaging/pass-hal-rpi.spec b/packaging/pass-hal-rpi.spec index b781ec6..e7ddc69 100644 --- a/packaging/pass-hal-rpi.spec +++ b/packaging/pass-hal-rpi.spec @@ -2,7 +2,7 @@ %define release 1 Name: pass-hal-rpi -Summary: PASS hal for RPI4 +Summary: Power HAL for RPI4 Version: %{version} Release: %{release} Group: System/Hardware Adaptation @@ -16,21 +16,22 @@ Requires(post): /sbin/ldconfig Requires(post): /bin/systemctl Requires(postun): /sbin/ldconfig Requires(postun): /bin/systemctl -Requires: pass >= 1.1.0 BuildRequires: cmake BuildRequires: pkgconfig(dlog) -BuildRequires: pkgconfig(glib-2.0) -BuildRequires: pass-hal-devel >= 1.1.0 +BuildRequires: pkgconfig(hal-api-common) +BuildRequires: pkgconfig(hal-api-power) %description -PASS hal for RPI4 +Power HAL for RPI4 %prep %setup -q cp %{SOURCE1} . %build -%cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DHAL_VERSION=%{version}.%{release} +%cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} \ + -DCMAKE_HAL_LIBDIR_PREFIX=%{_hal_libdir} \ + -DCMAKE_HAL_LICENSEDIR_PREFIX=%{_hal_licensedir} \ make %{?jobs:-j%jobs} @@ -40,7 +41,7 @@ rm -rf %{buildroot} %make_install %post /sbin/ldconfig -systemd-tmpfiles %{_prefix}/lib/tmpfiles.d/pass-hal.conf --create +systemd-tmpfiles /hal/lib/tmpfiles.d/pass-hal.conf --create if [ -f %{_unitdir}/pass.service ]; then systemctl try-restart pass.service fi @@ -53,8 +54,9 @@ fi %files %manifest %{name}.manifest -%{_libdir}/pass/*.so -%{_prefix}/lib/tmpfiles.d/pass-hal.conf -%config %{_sysconfdir}/pass/pass.conf -%config %{_sysconfdir}/pass/pass-cpu0.conf -%config %{_sysconfdir}/pass/pass-memory.conf +%{_hal_licensedir}/%{name}/LICENSE +%{_hal_libdir}/*.so +/hal/lib/tmpfiles.d/pass-hal.conf +%config %{_hal_sysconfdir}/pass/pass.conf +%config %{_hal_sysconfdir}/pass/pass-cpu0.conf +%config %{_hal_sysconfdir}/pass/pass-memory.conf diff --git a/scripts/pass.conf b/scripts/pass.conf index e0fe5b5..3f52562 100644 --- a/scripts/pass.conf +++ b/scripts/pass.conf @@ -10,11 +10,11 @@ pass_num_resources=2 pass_res_type=cpu pass_res_name=cpu0 pass_res_thermal_name=thermal_zone0 -pass_path_conf_file=/etc/pass/pass-cpu0.conf +pass_path_conf_file=/hal/etc/pass/pass-cpu0.conf pass_first_cpu=0 pass_num_cpus=4 [PassResource1] pass_res_type=memory pass_res_name=memory -pass_path_conf_file=/etc/pass/pass-memory.conf +pass_path_conf_file=/hal/etc/pass/pass-memory.conf diff --git a/src/cpu/CMakeLists.txt b/src/cpu/CMakeLists.txt deleted file mode 100644 index 3cd62b8..0000000 --- a/src/cpu/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -PROJECT(cpu C) - -INCLUDE(FindPkgConfig) -pkg_check_modules(pkgs REQUIRED dlog glib-2.0) - -#HAL version -string(REPLACE "." ";" HAL_VERSION_LIST ${HAL_VERSION}) -list(GET HAL_VERSION_LIST 0 HAL_VERSION_MAJOR) -list(GET HAL_VERSION_LIST 1 HAL_VERSION_MINOR) -list(GET HAL_VERSION_LIST 2 HAL_VERSION_REVISION) -list(GET HAL_VERSION_LIST 3 HAL_VERSION_RELEASE) -add_definitions(-DVER_MAJOR=${HAL_VERSION_MAJOR} -DVER_MINOR=${HAL_VERSION_MINOR}) -add_definitions(-DVER_REVISION=${HAL_VERSION_REVISION} -DVER_RELEASE=${HAL_VERSION_RELEASE}) - -SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") - -SET(SRCS ${PROJECT_NAME}.c - ../shared/sysfs.c) - -ADD_LIBRARY(${PROJECT_NAME} MODULE ${SRCS}) -SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES PREFIX "") -INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${DEST_DIR} COMPONENT RuntimeLibraries) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c deleted file mode 100644 index 635f490..0000000 --- a/src/cpu/cpu.c +++ /dev/null @@ -1,440 +0,0 @@ -/* - * PASS (Power Aware System Service) - * - * Copyright (c) 2017 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include -#include -#include -#include -#include - -#include "../shared/sysfs.h" - -#define CPUFREQ_PATH_PREFIX "/sys/devices/system/cpu/" -#define CPUFREQ_CURR_GOVERNOR_PATH_SUFFIX "/cpufreq/scaling_governor" -#define CPUFREQ_AVAIL_GOVERNOR_PATH_SUFFIX "/cpufreq/scaling_available_governors" - -/* - * The cpuinfo_cur_freq indicates the actual operating CPU freqeuncy - * and scaling_cur_freq is the CPU frequency set by the CPUFREQ policy. - */ -#define CPUFREQ_CURR_FREQ_PATH_SUFFIX "/cpufreq/cpuinfo_cur_freq" -#define CPUFREQ_AVAILABLE_MIN_FREQ_PATH_SUFFIX "/cpufreq/cpuinfo_min_freq" -#define CPUFREQ_AVAILABLE_MAX_FREQ_PATH_SUFFIX "/cpufreq/cpuinfo_max_freq" -#define CPUFREQ_MIN_FREQ_PATH_SUFFIX "/cpufreq/scaling_min_freq" -#define CPUFREQ_MAX_FREQ_PATH_SUFFIX "/cpufreq/scaling_max_freq" -#define CPUFREQ_UP_THRESHOLD_PATH_SUFFIX "/cpufreq/ondemand/up_threshold" - -#define CPU_ONLINE_PATH_PREFIX "/sys/devices/system/cpu/cpu" -#define CPU_ONLINE_PATH_SUFFIX "/online" -#define CPU_ONLINE_STATE_ON 1 -#define CPU_ONLINE_STATE_OFF 0 - -#define TMU_PATH_PREFIX "/sys/class/thermal/" -#define TMU_TEMP_PATH_SUFFIX "/temp" -#define TMU_POLICY_PATH_SUFFIX "/policy" -#define TMU_TEMP_MASK 0xFFFFF - -static int standard_dvfs_get_curr_governor(char *res_name, char *governor) -{ - char path[PATH_MAX]; - int ret; - - if ((!res_name) || (!governor)) - return -EINVAL; - - snprintf(path, PATH_MAX, "%s%s%s", - CPUFREQ_PATH_PREFIX, - res_name, - CPUFREQ_CURR_GOVERNOR_PATH_SUFFIX); - - ret = sysfs_read_str(path, governor, BUFF_MAX); - if (ret < 0) - return ret; - - return 0; -} - -static int standard_dvfs_set_curr_governor(char *res_name, char *governor) -{ - char path[PATH_MAX]; - int ret; - - if ((!res_name) || (!governor)) - return -EINVAL; - - snprintf(path, PATH_MAX, "%s%s%s", - CPUFREQ_PATH_PREFIX, - res_name, - CPUFREQ_CURR_GOVERNOR_PATH_SUFFIX); - - ret = sysfs_write_str(path, governor); - if (ret < 0) - return ret; - - return 0; -} - -static int standard_dvfs_get_curr_freq(char *res_name) -{ - char path[PATH_MAX]; - int freq, ret; - - if (!res_name) - return -EINVAL; - - snprintf(path, PATH_MAX, "%s%s%s", - CPUFREQ_PATH_PREFIX, - res_name, - CPUFREQ_CURR_FREQ_PATH_SUFFIX); - - ret = sysfs_read_int(path, &freq); - if (ret < 0) - return ret; - - return freq; -} - -static int standard_dvfs_get_min_freq(char *res_name) -{ - char path[PATH_MAX]; - int freq, ret; - - if (!res_name) - return -EINVAL; - - snprintf(path, PATH_MAX, "%s%s%s", - CPUFREQ_PATH_PREFIX, - res_name, - CPUFREQ_MIN_FREQ_PATH_SUFFIX); - - ret = sysfs_read_int(path, &freq); - if (ret < 0) - return ret; - - return freq; -} - -static int standard_dvfs_set_min_freq(char *res_name, int freq) -{ - char path[PATH_MAX]; - int ret; - - if ((!res_name) || (freq < 0)) - return -EINVAL; - - snprintf(path, PATH_MAX, "%s%s%s", - CPUFREQ_PATH_PREFIX, - res_name, - CPUFREQ_MIN_FREQ_PATH_SUFFIX); - - ret = sysfs_write_int(path, freq); - if (ret < 0) - return ret; - - return 0; -} - -static int standard_dvfs_get_max_freq(char *res_name) -{ - char path[PATH_MAX]; - int freq, ret; - - if (!res_name) - return -EINVAL; - - snprintf(path, PATH_MAX, "%s%s%s", - CPUFREQ_PATH_PREFIX, - res_name, - CPUFREQ_MAX_FREQ_PATH_SUFFIX); - - ret = sysfs_read_int(path, &freq); - if (ret < 0) - return ret; - - return freq; -} - -static int standard_dvfs_set_max_freq(char *res_name, int freq) -{ - char path[PATH_MAX]; - int ret; - - if ((!res_name) || (freq < 0)) - return -EINVAL; - - snprintf(path, PATH_MAX, "%s%s%s", - CPUFREQ_PATH_PREFIX, - res_name, - CPUFREQ_MAX_FREQ_PATH_SUFFIX); - - ret = sysfs_write_int(path, freq); - if (ret < 0) - return ret; - return 0; -} - -static int standard_dvfs_get_available_min_freq(char *res_name) -{ - char path[PATH_MAX]; - int val, ret; - - if (!res_name) - return -EINVAL; - - snprintf(path, PATH_MAX, "%s%s%s", - CPUFREQ_PATH_PREFIX, - res_name, - CPUFREQ_AVAILABLE_MIN_FREQ_PATH_SUFFIX); - - ret = sysfs_read_int(path, &val); - if (ret < 0) - return ret; - - return val; -} - - -static int standard_dvfs_get_available_max_freq(char *res_name) -{ - char path[PATH_MAX]; - int val, ret; - - if (!res_name) - return -EINVAL; - - snprintf(path, PATH_MAX, "%s%s%s", - CPUFREQ_PATH_PREFIX, - res_name, - CPUFREQ_AVAILABLE_MAX_FREQ_PATH_SUFFIX); - - ret = sysfs_read_int(path, &val); - if (ret < 0) - return ret; - - return val; -} - -static int standard_dvfs_get_up_threshold(char *res_name) -{ - char path[PATH_MAX]; - int val, ret; - - if (!res_name) - return -EINVAL; - - snprintf(path, PATH_MAX, "%s%s%s", - CPUFREQ_PATH_PREFIX, - res_name, - CPUFREQ_UP_THRESHOLD_PATH_SUFFIX); - - ret = sysfs_read_int(path, &val); - if (ret < 0) - return ret; - - return val; -} - -static int standard_dvfs_set_up_threshold(char *res_name, int up_threshold) -{ - char path[PATH_MAX]; - int ret; - - if ((!res_name) || (up_threshold < 0)) - return -EINVAL; - - snprintf(path, PATH_MAX, "%s%s%s", - CPUFREQ_PATH_PREFIX, - res_name, - CPUFREQ_UP_THRESHOLD_PATH_SUFFIX); - - ret = sysfs_write_int(path, up_threshold); - if (ret < 0) - return ret; - - return 0; -} - -static struct pass_resource_dvfs_ops standard_cpu_dvfs_ops = { - .get_curr_governor = standard_dvfs_get_curr_governor, - .set_curr_governor = standard_dvfs_set_curr_governor, - .get_curr_freq = standard_dvfs_get_curr_freq, - .get_min_freq = standard_dvfs_get_min_freq, - .set_min_freq = standard_dvfs_set_min_freq, - .get_max_freq = standard_dvfs_get_max_freq, - .set_max_freq = standard_dvfs_set_max_freq, - .get_available_min_freq = standard_dvfs_get_available_min_freq, - .get_available_max_freq = standard_dvfs_get_available_max_freq, - .get_up_threshold = standard_dvfs_get_up_threshold, - .set_up_threshold = standard_dvfs_set_up_threshold, -}; - -static int standard_hotplug_get_online_state(char *res_name, int cpu) -{ - char path[PATH_MAX]; - int ret, online; - - if ((!res_name)) - return -EINVAL; - - snprintf(path, PATH_MAX, "%s%d%s", - CPU_ONLINE_PATH_PREFIX, - cpu, - CPU_ONLINE_PATH_SUFFIX); - - ret = sysfs_read_int(path, &online); - if (ret < 0) - return ret; - - return online; -} - -static int standard_hotplug_set_online_state(char *res_name, int cpu, int on) -{ - char path[PATH_MAX]; - int ret; - - if ((!res_name)) - return -EINVAL; - if ((on != CPU_ONLINE_STATE_ON) && (on != CPU_ONLINE_STATE_OFF)) - return -EINVAL; - - /* - * NOTE: Some ARM SoC series cannot turn off the CPU0 - * because of h/w design. To prevent the critical problem, - * if someone try to turn off the CPU0, just return without any - * opertaion. - */ - if (on == 0 && cpu == 0) { - _E("cannot turn off the CPU0"); - return 0; - } - - snprintf(path, PATH_MAX, "%s%d%s", - CPU_ONLINE_PATH_PREFIX, - cpu, - CPU_ONLINE_PATH_SUFFIX); - - ret = sysfs_write_int(path, on); - if (ret < 0) - return ret; - - return 0; -} - -static struct pass_resource_hotplug_ops standard_cpu_hotplus_ops = { - .get_online_state = standard_hotplug_get_online_state, - .set_online_state = standard_hotplug_set_online_state, - .get_online_min_num = NULL, - .set_online_min_num = NULL, - .get_online_max_num = NULL, - .set_online_max_num = NULL, -}; - -static int standard_tmu_get_temp(char *res_thermal_name) -{ - char path[PATH_MAX]; - int temp, ret; - - if (!res_thermal_name) - return -EINVAL; - - snprintf(path, PATH_MAX, "%s%s%s", - TMU_PATH_PREFIX, - res_thermal_name, - TMU_TEMP_PATH_SUFFIX); - - ret = sysfs_read_int(path, &temp); - if (ret < 0) - return ret; - - /* - * Thermal framework provides the current temperature - * as five digits interger like 54430 when temperature is 54.430 - * degrees centigrade. But, Thermal Monitor in Tizen usually - * use two digits interger without decimal point. - * So that round temperature value. It constraints the maximume - * temperature as 1049 degrees centigrade for preventing integer - * overflow. Usually, the embedded device never over 1000 degrees - * centigrade. - */ - return (((temp & TMU_TEMP_MASK) + 500) / 1000); -} - -static int standard_tmu_get_policy(char *res_thermal_name, char *policy) -{ - char path[PATH_MAX]; - int ret; - - if ((!res_thermal_name) || (!policy)) - return -EINVAL; - - snprintf(path, PATH_MAX, "%s%s%s", - TMU_PATH_PREFIX, - res_thermal_name, - TMU_POLICY_PATH_SUFFIX); - - ret = sysfs_read_str(path, policy, BUFF_MAX); - if (ret < 0) - return ret; - - return 0; -} - -static struct pass_resource_tmu_ops standard_cpu_tmu_ops = { - .get_temp = standard_tmu_get_temp, - .get_policy = standard_tmu_get_policy, -}; - -static int standard_cpu_open(char *res_name, struct pass_resource_info *info, - struct pass_resource_common **common) -{ - struct pass_resource_cpu *cpu_res; - - if (!info) - return -EINVAL; - - cpu_res = calloc(1, sizeof(struct pass_resource_cpu)); - if (!cpu_res) - return -ENOMEM; - - cpu_res->common.info = info; - cpu_res->dvfs = standard_cpu_dvfs_ops; - cpu_res->hotplug = standard_cpu_hotplus_ops; - cpu_res->tmu = standard_cpu_tmu_ops; - - *common = (struct pass_resource_common *) cpu_res; - - return 0; -} - -static int standard_cpu_close(char *res_name, struct pass_resource_common *common) -{ - if (!common) - return -EINVAL; - - free(common); - - return 0; -} - -HAL_MODULE_STRUCTURE = { - .magic = HAL_INFO_TAG, - .id = PASS_RESOURCE_CPU_ID, - .name = PASS_RESOURCE_CPU_NAME, - .open = standard_cpu_open, - .close = standard_cpu_close, -}; diff --git a/src/hal-backend-power.c b/src/hal-backend-power.c new file mode 100644 index 0000000..403f790 --- /dev/null +++ b/src/hal-backend-power.c @@ -0,0 +1,523 @@ +/* + * HAL backend for hal-api-power which is used for PASS daemon + * + * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include + +#include "sysfs.h" + +#define BUFF_MAX 255 + +/************************* + * H/W Resource Defintions + */ +#define CPUFREQ_PATH_PREFIX "/sys/devices/system/cpu/" +#define CPUFREQ_CURR_GOVERNOR_PATH_SUFFIX "/cpufreq/scaling_governor" +#define CPUFREQ_AVAIL_GOVERNOR_PATH_SUFFIX "/cpufreq/scaling_available_governors" + +/* + * The cpuinfo_cur_freq indicates the actual operating CPU freqeuncy + * and scaling_cur_freq is the CPU frequency set by the CPUFREQ policy. + */ +#define CPUFREQ_CURR_FREQ_PATH_SUFFIX "/cpufreq/cpuinfo_cur_freq" +#define CPUFREQ_AVAILABLE_MIN_FREQ_PATH_SUFFIX "/cpufreq/cpuinfo_min_freq" +#define CPUFREQ_AVAILABLE_MAX_FREQ_PATH_SUFFIX "/cpufreq/cpuinfo_max_freq" +#define CPUFREQ_MIN_FREQ_PATH_SUFFIX "/cpufreq/scaling_min_freq" +#define CPUFREQ_MAX_FREQ_PATH_SUFFIX "/cpufreq/scaling_max_freq" +#define CPUFREQ_UP_THRESHOLD_PATH_SUFFIX "/cpufreq/ondemand/up_threshold" + +#define CPU_ONLINE_PATH_PREFIX "/sys/devices/system/cpu/cpu" +#define CPU_ONLINE_PATH_SUFFIX "/online" +#define CPU_ONLINE_STATE_ON 1 +#define CPU_ONLINE_STATE_OFF 0 + +#define TMU_PATH_PREFIX "/sys/class/thermal/" +#define TMU_TEMP_PATH_SUFFIX "/temp" +#define TMU_POLICY_PATH_SUFFIX "/policy" +#define TMU_TEMP_MASK 0xFFFFF + +#define FAULT_AROUND_BYTES_PATH "/sys/kernel/debug/fault_around_bytes" + +/************************************************* + * HAL backend implementation for CPU H/W Resource + */ +static int cpu_dvfs_get_curr_governor(char *res_name, char *governor) +{ + char path[PATH_MAX]; + int ret; + + if ((!res_name) || (!governor)) + return -EINVAL; + + snprintf(path, PATH_MAX, "%s%s%s", + CPUFREQ_PATH_PREFIX, + res_name, + CPUFREQ_CURR_GOVERNOR_PATH_SUFFIX); + + ret = sysfs_read_str(path, governor, BUFF_MAX); + if (ret < 0) + return ret; + + return 0; +} + +static int cpu_dvfs_set_curr_governor(char *res_name, char *governor) +{ + char path[PATH_MAX]; + int ret; + + if ((!res_name) || (!governor)) + return -EINVAL; + + snprintf(path, PATH_MAX, "%s%s%s", + CPUFREQ_PATH_PREFIX, + res_name, + CPUFREQ_CURR_GOVERNOR_PATH_SUFFIX); + + ret = sysfs_write_str(path, governor); + if (ret < 0) + return ret; + + return 0; +} + +static int cpu_dvfs_get_curr_freq(char *res_name) +{ + char path[PATH_MAX]; + int freq, ret; + + if (!res_name) + return -EINVAL; + + snprintf(path, PATH_MAX, "%s%s%s", + CPUFREQ_PATH_PREFIX, + res_name, + CPUFREQ_CURR_FREQ_PATH_SUFFIX); + + ret = sysfs_read_int(path, &freq); + if (ret < 0) + return ret; + + return freq; +} + +static int cpu_dvfs_get_min_freq(char *res_name) +{ + char path[PATH_MAX]; + int freq, ret; + + if (!res_name) + return -EINVAL; + + snprintf(path, PATH_MAX, "%s%s%s", + CPUFREQ_PATH_PREFIX, + res_name, + CPUFREQ_MIN_FREQ_PATH_SUFFIX); + + ret = sysfs_read_int(path, &freq); + if (ret < 0) + return ret; + + return freq; +} + +static int cpu_dvfs_set_min_freq(char *res_name, int freq) +{ + char path[PATH_MAX]; + int ret; + + if ((!res_name) || (freq < 0)) + return -EINVAL; + + snprintf(path, PATH_MAX, "%s%s%s", + CPUFREQ_PATH_PREFIX, + res_name, + CPUFREQ_MIN_FREQ_PATH_SUFFIX); + + ret = sysfs_write_int(path, freq); + if (ret < 0) + return ret; + + return 0; +} + +static int cpu_dvfs_get_max_freq(char *res_name) +{ + char path[PATH_MAX]; + int freq, ret; + + if (!res_name) + return -EINVAL; + + snprintf(path, PATH_MAX, "%s%s%s", + CPUFREQ_PATH_PREFIX, + res_name, + CPUFREQ_MAX_FREQ_PATH_SUFFIX); + + ret = sysfs_read_int(path, &freq); + if (ret < 0) + return ret; + + return freq; +} + +static int cpu_dvfs_set_max_freq(char *res_name, int freq) +{ + char path[PATH_MAX]; + int ret; + + if ((!res_name) || (freq < 0)) + return -EINVAL; + + snprintf(path, PATH_MAX, "%s%s%s", + CPUFREQ_PATH_PREFIX, + res_name, + CPUFREQ_MAX_FREQ_PATH_SUFFIX); + + ret = sysfs_write_int(path, freq); + if (ret < 0) + return ret; + return 0; +} + +static int cpu_dvfs_get_available_min_freq(char *res_name) +{ + char path[PATH_MAX]; + int val, ret; + + if (!res_name) + return -EINVAL; + + snprintf(path, PATH_MAX, "%s%s%s", + CPUFREQ_PATH_PREFIX, + res_name, + CPUFREQ_AVAILABLE_MIN_FREQ_PATH_SUFFIX); + + ret = sysfs_read_int(path, &val); + if (ret < 0) + return ret; + + return val; +} + + +static int cpu_dvfs_get_available_max_freq(char *res_name) +{ + char path[PATH_MAX]; + int val, ret; + + if (!res_name) + return -EINVAL; + + snprintf(path, PATH_MAX, "%s%s%s", + CPUFREQ_PATH_PREFIX, + res_name, + CPUFREQ_AVAILABLE_MAX_FREQ_PATH_SUFFIX); + + ret = sysfs_read_int(path, &val); + if (ret < 0) + return ret; + + return val; +} + +static int cpu_dvfs_get_up_threshold(char *res_name) +{ + char path[PATH_MAX]; + int val, ret; + + if (!res_name) + return -EINVAL; + + snprintf(path, PATH_MAX, "%s%s%s", + CPUFREQ_PATH_PREFIX, + res_name, + CPUFREQ_UP_THRESHOLD_PATH_SUFFIX); + + ret = sysfs_read_int(path, &val); + if (ret < 0) + return ret; + + return val; +} + +static int cpu_dvfs_set_up_threshold(char *res_name, int up_threshold) +{ + char path[PATH_MAX]; + int ret; + + if ((!res_name) || (up_threshold < 0)) + return -EINVAL; + + snprintf(path, PATH_MAX, "%s%s%s", + CPUFREQ_PATH_PREFIX, + res_name, + CPUFREQ_UP_THRESHOLD_PATH_SUFFIX); + + ret = sysfs_write_int(path, up_threshold); + if (ret < 0) + return ret; + + return 0; +} + +static struct pass_resource_dvfs_ops cpu_dvfs_ops = { + .get_curr_governor = cpu_dvfs_get_curr_governor, + .set_curr_governor = cpu_dvfs_set_curr_governor, + .get_curr_freq = cpu_dvfs_get_curr_freq, + .get_min_freq = cpu_dvfs_get_min_freq, + .set_min_freq = cpu_dvfs_set_min_freq, + .get_max_freq = cpu_dvfs_get_max_freq, + .set_max_freq = cpu_dvfs_set_max_freq, + .get_available_min_freq = cpu_dvfs_get_available_min_freq, + .get_available_max_freq = cpu_dvfs_get_available_max_freq, + .get_up_threshold = cpu_dvfs_get_up_threshold, + .set_up_threshold = cpu_dvfs_set_up_threshold, +}; + +static int cpu_hotplug_get_online_state(char *res_name, int cpu) +{ + char path[PATH_MAX]; + int ret, online; + + if ((!res_name)) + return -EINVAL; + + snprintf(path, PATH_MAX, "%s%d%s", + CPU_ONLINE_PATH_PREFIX, + cpu, + CPU_ONLINE_PATH_SUFFIX); + + ret = sysfs_read_int(path, &online); + if (ret < 0) + return ret; + + return online; +} + +static int cpu_hotplug_set_online_state(char *res_name, int cpu, int on) +{ + char path[PATH_MAX]; + int ret; + + if ((!res_name)) + return -EINVAL; + if ((on != CPU_ONLINE_STATE_ON) && (on != CPU_ONLINE_STATE_OFF)) + return -EINVAL; + + /* + * NOTE: Some ARM SoC series cannot turn off the CPU0 + * because of h/w design. To prevent the critical problem, + * if someone try to turn off the CPU0, just return without any + * opertaion. + */ + if (on == 0 && cpu == 0) { + return 0; + } + + snprintf(path, PATH_MAX, "%s%d%s", + CPU_ONLINE_PATH_PREFIX, + cpu, + CPU_ONLINE_PATH_SUFFIX); + + ret = sysfs_write_int(path, on); + if (ret < 0) + return ret; + + return 0; +} + +static struct pass_resource_hotplug_ops cpu_hotplug_ops = { + .get_online_state = cpu_hotplug_get_online_state, + .set_online_state = cpu_hotplug_set_online_state, + .get_online_min_num = NULL, + .set_online_min_num = NULL, + .get_online_max_num = NULL, + .set_online_max_num = NULL, +}; + +static int cpu_tmu_get_temp(char *res_thermal_name) +{ + char path[PATH_MAX]; + int temp, ret; + + if (!res_thermal_name) + return -EINVAL; + + snprintf(path, PATH_MAX, "%s%s%s", + TMU_PATH_PREFIX, + res_thermal_name, + TMU_TEMP_PATH_SUFFIX); + + ret = sysfs_read_int(path, &temp); + if (ret < 0) + return ret; + + /* + * Thermal framework provides the current temperature + * as five digits interger like 54430 when temperature is 54.430 + * degrees centigrade. But, Thermal Monitor in Tizen usually + * use two digits interger without decimal point. + * So that round temperature value. It constraints the maximume + * temperature as 1049 degrees centigrade for preventing integer + * overflow. Usually, the embedded device never over 1000 degrees + * centigrade. + */ + return (((temp & TMU_TEMP_MASK) + 500) / 1000); +} + +static int cpu_tmu_get_policy(char *res_thermal_name, char *policy) +{ + char path[PATH_MAX]; + int ret; + + if ((!res_thermal_name) || (!policy)) + return -EINVAL; + + snprintf(path, PATH_MAX, "%s%s%s", + TMU_PATH_PREFIX, + res_thermal_name, + TMU_POLICY_PATH_SUFFIX); + + ret = sysfs_read_str(path, policy, BUFF_MAX); + if (ret < 0) + return ret; + + return 0; +} + +static struct pass_resource_tmu_ops cpu_tmu_ops = { + .get_temp = cpu_tmu_get_temp, + .get_policy = cpu_tmu_get_policy, +}; + +/**************************************************** + * HAL backend implementation for Memory H/W Resource + */ +static int memory_get_fault_around_bytes(char *res_name) +{ + int ret, fault_around_bytes; + + if (!res_name) + return -EINVAL; + + ret = sysfs_read_int(FAULT_AROUND_BYTES_PATH, &fault_around_bytes); + if (ret < 0) + return ret; + + return fault_around_bytes; +} + +static int memory_set_fault_around_bytes(char *res_name, + int fault_around_bytes) +{ + int ret; + + if ((!res_name) || (fault_around_bytes <= 0)) + return -EINVAL; + + ret = sysfs_write_int(FAULT_AROUND_BYTES_PATH, fault_around_bytes); + if (ret < 0) + return ret; + + return 0; +} + +/************************ + * HAL backend power data + */ +static int power_rpi4_init(void **data) +{ + hal_backend_power_funcs *power_funcs = NULL; + struct pass_resource_cpu *cpu = NULL; + struct pass_resource_memory *memory = NULL; + int ret; + + /* Allocate memory */ + power_funcs = calloc(1, sizeof(hal_backend_power_funcs)); + if (!power_funcs) + return -ENOMEM; + + cpu = calloc(1, sizeof(struct pass_resource_cpu)); + if (!cpu) { + return -ENOMEM; + goto err; + } + + memory = calloc(1, sizeof(struct pass_resource_memory)); + if (!memory) { + ret = -ENOMEM; + goto err; + } + + /* Initialize each h/w resource */ + cpu->dvfs = cpu_dvfs_ops; + cpu->hotplug = cpu_hotplug_ops; + cpu->tmu = cpu_tmu_ops; + + memory->get_fault_around_bytes = memory_get_fault_around_bytes; + memory->set_fault_around_bytes = memory_set_fault_around_bytes; + + /* Initialize hal_backend_power_funcs */ + power_funcs->cpu = cpu; + power_funcs->memory = memory; + + *data = (void *)power_funcs; + + return 0; +err: + if (memory) + free(memory); + if (cpu) + free(cpu); + + free(power_funcs); + + return ret; +} + +static int power_rpi4_exit(void *data) +{ + hal_backend_power_funcs *funcs; + + if (!data) + return -EINVAL; + + funcs = (hal_backend_power_funcs *)data; + + if (funcs->cpu) + free(funcs->cpu); + if (funcs->memory) + free(funcs->memory); + + free(funcs); + + return 0; +} + +hal_backend hal_backend_power_data = { + .name = "power-rpi4", + .vendor = "Rasberry Pi", + .abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .init = power_rpi4_init, + .exit = power_rpi4_exit, +}; diff --git a/src/memory/CMakeLists.txt b/src/memory/CMakeLists.txt deleted file mode 100644 index e7bd0a6..0000000 --- a/src/memory/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -PROJECT(memory C) - -INCLUDE(FindPkgConfig) -pkg_check_modules(pkgs REQUIRED dlog glib-2.0) - -#HAL version -string(REPLACE "." ";" HAL_VERSION_LIST ${HAL_VERSION}) -list(GET HAL_VERSION_LIST 0 HAL_VERSION_MAJOR) -list(GET HAL_VERSION_LIST 1 HAL_VERSION_MINOR) -list(GET HAL_VERSION_LIST 2 HAL_VERSION_REVISION) -list(GET HAL_VERSION_LIST 3 HAL_VERSION_RELEASE) -add_definitions(-DVER_MAJOR=${HAL_VERSION_MAJOR} -DVER_MINOR=${HAL_VERSION_MINOR}) -add_definitions(-DVER_REVISION=${HAL_VERSION_REVISION} -DVER_RELEASE=${HAL_VERSION_RELEASE}) - -SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") - -SET(SRCS ${PROJECT_NAME}.c - ../shared/sysfs.c) - -ADD_LIBRARY(${PROJECT_NAME} MODULE ${SRCS}) -SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES PREFIX "") -INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${DEST_DIR} COMPONENT RuntimeLibraries) diff --git a/src/memory/memory.c b/src/memory/memory.c deleted file mode 100644 index cd11a6e..0000000 --- a/src/memory/memory.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * PASS (Power Aware System Service) - * - * Copyright (c) 2020 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include -#include -#include -#include - -#include "../shared/sysfs.h" - -#define FAULT_AROUND_BYTES_PATH "/sys/kernel/debug/fault_around_bytes" - -static int rpi_memory_get_fault_around_bytes(char *res_name) -{ - int ret, fault_around_bytes; - - if (!res_name) - return -EINVAL; - - ret = sysfs_read_int(FAULT_AROUND_BYTES_PATH, &fault_around_bytes); - if (ret < 0) - return ret; - - return fault_around_bytes; -} - -static int rpi_memory_set_fault_around_bytes(char *res_name, - int fault_around_bytes) -{ - int ret; - - if ((!res_name) || (fault_around_bytes <= 0)) - return -EINVAL; - - ret = sysfs_write_int(FAULT_AROUND_BYTES_PATH, fault_around_bytes); - if (ret < 0) - return ret; - - return 0; -} - -static int rpi_memory_open(char *res_name, struct pass_resource_info *info, - struct pass_resource_common **common) -{ - struct pass_resource_memory *res; - - if (!info) - return -EINVAL; - - res = calloc(1, sizeof(struct pass_resource_memory)); - if (!res) - return -ENOMEM; - - res->common.info = info; - res->get_fault_around_bytes = rpi_memory_get_fault_around_bytes; - res->set_fault_around_bytes = rpi_memory_set_fault_around_bytes; - - *common = (struct pass_resource_common *)res; - - return 0; -} - -static int rpi_memory_close(char *res_name, struct pass_resource_common *common) -{ - if (!common) - return -EINVAL; - - free(common); - - return 0; -} - -HAL_MODULE_STRUCTURE = { - .magic = HAL_INFO_TAG, - .id = PASS_RESOURCE_MEMORY_ID, - .name = PASS_RESOURCE_MEMORY_NAME, - .open = rpi_memory_open, - .close = rpi_memory_close, -}; diff --git a/src/shared/sysfs.c b/src/shared/sysfs.c deleted file mode 100644 index 1256076..0000000 --- a/src/shared/sysfs.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * PASS (Power Aware System Service) - * - * Copyright (c) 2017 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include -#include -#include -#include -#include -#include - -#include "sysfs.h" - -static int sysfs_read_buf(char *path, char *buf, int len) -{ - int r, fd; - - if ((!path) || (!buf) || (len < 0)) - return -EINVAL; - - fd = open(path, O_RDONLY); - if (fd == -1) - return -ENOENT; - - r = read(fd, buf, len); - close(fd); - - if ((r < 0) || (r > len)) - return -EIO; - - buf[r] = '\0'; - - return 0; -} - -static int sysfs_write_buf(char *path, char *buf) -{ - int w, fd; - - if ((!path) || (!buf)) - return -EINVAL; - - fd = open(path, O_WRONLY); - if (fd == -1) - return -ENOENT; - - w = write(fd, buf, strlen(buf)); - close(fd); - - if (w < 0) - return -EIO; - - return 0; -} - -int sysfs_read_int(char *path, int *val) -{ - char buf[MAX_BUF_SIZE + 1]; - int r; - - if ((!path) || (!val)) - return -EINVAL; - - r = sysfs_read_buf(path, buf, MAX_BUF_SIZE); - if (r < 0) - return r; - - *val = atoi(buf); - return 0; -} - -int sysfs_read_str(char *path, char *str, int len) -{ - int r; - - if ((!path) || (!str) || (len <= 0)) - return -EINVAL; - - r = sysfs_read_buf(path, str, len); - if (r < 0) - return r; - - return 0; -} - -int sysfs_write_int(char *path, int val) -{ - char buf[MAX_BUF_SIZE + 1]; - int w; - - if (!path) - return -EINVAL; - - snprintf(buf, MAX_BUF_SIZE, "%d", val); - w = sysfs_write_buf(path, buf); - if (w < 0) - return w; - - return 0; -} - -int sysfs_write_str(char *path, char *str) -{ - int w; - - if ((!path) || (!str)) - return -EINVAL; - - w = sysfs_write_buf(path, str); - if (w < 0) - return w; - - return 0; -} diff --git a/src/shared/sysfs.h b/src/shared/sysfs.h deleted file mode 100644 index 5268738..0000000 --- a/src/shared/sysfs.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * PASS (Power Aware System Service) - * - * Copyright (c) 2020 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MAX_BUF_SIZE 255 - -int sysfs_read_int(char *path, int *val); -int sysfs_read_str(char *path, char *str, int len); -int sysfs_write_int(char *path, int val); -int sysfs_write_str(char *path, char *str); diff --git a/src/sysfs.c b/src/sysfs.c new file mode 100644 index 0000000..1256076 --- /dev/null +++ b/src/sysfs.c @@ -0,0 +1,127 @@ +/* + * PASS (Power Aware System Service) + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include +#include + +#include "sysfs.h" + +static int sysfs_read_buf(char *path, char *buf, int len) +{ + int r, fd; + + if ((!path) || (!buf) || (len < 0)) + return -EINVAL; + + fd = open(path, O_RDONLY); + if (fd == -1) + return -ENOENT; + + r = read(fd, buf, len); + close(fd); + + if ((r < 0) || (r > len)) + return -EIO; + + buf[r] = '\0'; + + return 0; +} + +static int sysfs_write_buf(char *path, char *buf) +{ + int w, fd; + + if ((!path) || (!buf)) + return -EINVAL; + + fd = open(path, O_WRONLY); + if (fd == -1) + return -ENOENT; + + w = write(fd, buf, strlen(buf)); + close(fd); + + if (w < 0) + return -EIO; + + return 0; +} + +int sysfs_read_int(char *path, int *val) +{ + char buf[MAX_BUF_SIZE + 1]; + int r; + + if ((!path) || (!val)) + return -EINVAL; + + r = sysfs_read_buf(path, buf, MAX_BUF_SIZE); + if (r < 0) + return r; + + *val = atoi(buf); + return 0; +} + +int sysfs_read_str(char *path, char *str, int len) +{ + int r; + + if ((!path) || (!str) || (len <= 0)) + return -EINVAL; + + r = sysfs_read_buf(path, str, len); + if (r < 0) + return r; + + return 0; +} + +int sysfs_write_int(char *path, int val) +{ + char buf[MAX_BUF_SIZE + 1]; + int w; + + if (!path) + return -EINVAL; + + snprintf(buf, MAX_BUF_SIZE, "%d", val); + w = sysfs_write_buf(path, buf); + if (w < 0) + return w; + + return 0; +} + +int sysfs_write_str(char *path, char *str) +{ + int w; + + if ((!path) || (!str)) + return -EINVAL; + + w = sysfs_write_buf(path, str); + if (w < 0) + return w; + + return 0; +} diff --git a/src/sysfs.h b/src/sysfs.h new file mode 100644 index 0000000..5268738 --- /dev/null +++ b/src/sysfs.h @@ -0,0 +1,24 @@ +/* + * PASS (Power Aware System Service) + * + * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MAX_BUF_SIZE 255 + +int sysfs_read_int(char *path, int *val); +int sysfs_read_str(char *path, char *str, int len); +int sysfs_write_int(char *path, int val); +int sysfs_write_str(char *path, char *str);