replace common qcom sources with samsung ones
This commit is contained in:
77
qcom/opensource/thermal-hal/Android.bp
Normal file
77
qcom/opensource/thermal-hal/Android.bp
Normal file
@@ -0,0 +1,77 @@
|
||||
cc_binary {
|
||||
name: "android.hardware.thermal-service.qti",
|
||||
relative_install_path: "hw",
|
||||
init_rc: ["android.hardware.thermal-service.qti.rc"],
|
||||
vintf_fragments: ["android.hardware.thermal-service.qti.xml"],
|
||||
vendor: true,
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libbinder_ndk",
|
||||
"android.hardware.thermal-V2-ndk",
|
||||
"libcutils",
|
||||
"libutils",
|
||||
"liblog",
|
||||
"libnl",
|
||||
],
|
||||
srcs: [
|
||||
"service.cpp",
|
||||
"thermal.cpp",
|
||||
"thermalConfig.cpp",
|
||||
"thermalCommon.cpp",
|
||||
"thermalUtilsNetlink.cpp",
|
||||
"thermalMonitorNetlink.cpp",
|
||||
],
|
||||
header_libs: [
|
||||
"liblog_headers",
|
||||
"libcutils_headers",
|
||||
"qti_kernel_headers"
|
||||
],
|
||||
cflags: [
|
||||
"-Wno-unused-parameter",
|
||||
"-Wno-unused-variable",
|
||||
"-DENABLE_THERMAL_NETLINK",
|
||||
"-fexceptions",
|
||||
],
|
||||
}
|
||||
|
||||
cc_fuzz {
|
||||
name: "aidl_fuzzer_thermal",
|
||||
vendor: true,
|
||||
|
||||
shared_libs: [
|
||||
"liblog",
|
||||
"libbase",
|
||||
"libutils",
|
||||
"libcutils",
|
||||
"libbinder",
|
||||
"libbinder_ndk",
|
||||
"android.hardware.thermal-V2-ndk",
|
||||
"libnl",
|
||||
],
|
||||
|
||||
srcs: [
|
||||
"fuzzer.cpp",
|
||||
"thermal.cpp",
|
||||
"thermalConfig.cpp",
|
||||
"thermalCommon.cpp",
|
||||
"thermalUtilsNetlink.cpp",
|
||||
"thermalMonitorNetlink.cpp",
|
||||
],
|
||||
header_libs: [
|
||||
"liblog_headers",
|
||||
"libcutils_headers",
|
||||
"qti_kernel_headers"
|
||||
],
|
||||
|
||||
cflags: [
|
||||
"-Wno-unused-parameter",
|
||||
"-Wno-unused-variable",
|
||||
"-DENABLE_THERMAL_NETLINK",
|
||||
"-fexceptions",
|
||||
],
|
||||
|
||||
static_libs: [
|
||||
"libbinder_random_parcel",
|
||||
],
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
# Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
# Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
# * Neither the name of The Linux Foundation nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
# 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.
|
||||
|
||||
#Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
|
||||
#Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
#SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
|
||||
service vendor.thermal-hal /vendor/bin/hw/android.hardware.thermal-service.qti
|
||||
interface aidl android.hardware.thermal.IThermal/default
|
||||
class hal
|
||||
user root
|
||||
group root
|
||||
@@ -0,0 +1,43 @@
|
||||
<!--
|
||||
Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
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.
|
||||
-->
|
||||
|
||||
<!-- Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
|
||||
Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-3-Clause-Clear -->
|
||||
|
||||
<manifest version="2.0" type="device">
|
||||
<hal format="aidl">
|
||||
<name>android.hardware.thermal</name>
|
||||
<version>2</version>
|
||||
<fqname>IThermal/default</fqname>
|
||||
</hal>
|
||||
</manifest>
|
||||
|
||||
26
qcom/opensource/thermal-hal/fuzzer.cpp
Normal file
26
qcom/opensource/thermal-hal/fuzzer.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
#include <fuzzbinder/libbinder_ndk_driver.h>
|
||||
#include <fuzzer/FuzzedDataProvider.h>
|
||||
|
||||
#include "thermal.h"
|
||||
|
||||
using aidl::android::hardware::thermal::Thermal;
|
||||
|
||||
std::shared_ptr<Thermal> service;
|
||||
|
||||
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
|
||||
service = ndk::SharedRefBase::make<Thermal>();
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
if( service == nullptr ) return 0;
|
||||
|
||||
FuzzedDataProvider provider(data, size);
|
||||
android::fuzzService(service->asBinder().get(),std::move(provider));
|
||||
|
||||
return 0;
|
||||
}
|
||||
54
qcom/opensource/thermal-hal/service.cpp
Normal file
54
qcom/opensource/thermal-hal/service.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
* Not a contribution
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
|
||||
Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
|
||||
#define LOG_TAG "thermal_hal"
|
||||
|
||||
#include "thermal.h"
|
||||
#include <android-base/logging.h>
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_process.h>
|
||||
|
||||
using ::android::OK;
|
||||
using ::android::status_t;
|
||||
using aidl::android::hardware::thermal::Thermal;
|
||||
|
||||
int main() {
|
||||
|
||||
LOG(INFO) << "Thermal HAL Service AIDL starting...";
|
||||
|
||||
ABinderProcess_setThreadPoolMaxThreadCount(0);
|
||||
std::shared_ptr<Thermal> therm = ndk::SharedRefBase::make<Thermal>();
|
||||
|
||||
const std::string instance = std::string() + Thermal::descriptor + "/default";
|
||||
|
||||
if(therm){
|
||||
binder_status_t status =
|
||||
AServiceManager_addService(therm->asBinder().get(), instance.c_str());
|
||||
|
||||
CHECK(status == STATUS_OK);
|
||||
}
|
||||
|
||||
LOG(INFO) << "Thermal HAL Service AIDL started successfully.";
|
||||
ABinderProcess_joinThreadPool();
|
||||
return EXIT_FAILURE; // should not reach
|
||||
}
|
||||
359
qcom/opensource/thermal-hal/thermal.cpp
Normal file
359
qcom/opensource/thermal-hal/thermal.cpp
Normal file
@@ -0,0 +1,359 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
|
||||
Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <cerrno>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include "thermal.h"
|
||||
|
||||
namespace aidl::android::hardware::thermal{
|
||||
|
||||
using ndk::ScopedAStatus;
|
||||
|
||||
namespace {
|
||||
|
||||
bool interfacesEqual(const std::shared_ptr<::ndk::ICInterface>& left,
|
||||
const std::shared_ptr<::ndk::ICInterface>& right) {
|
||||
if (left == nullptr || right == nullptr || !left->isRemote() || !right->isRemote()) {
|
||||
return left == right;
|
||||
}
|
||||
return left->asBinder() == right->asBinder();
|
||||
}
|
||||
|
||||
}// namespace
|
||||
|
||||
static const Temperature dummy_temp_1_0 = {
|
||||
.type = TemperatureType::SKIN,
|
||||
.name = "test sensor",
|
||||
.value = 30,
|
||||
.throttlingStatus = ThrottlingSeverity::NONE,
|
||||
};
|
||||
|
||||
Thermal::Thermal():
|
||||
utils(std::bind(&Thermal::sendThrottlingChangeCB, this,
|
||||
std::placeholders::_1),
|
||||
std::bind(&Thermal::sendCoolingDeviceChangeCB, this,
|
||||
std::placeholders::_1))
|
||||
{ }
|
||||
|
||||
ScopedAStatus Thermal::getCoolingDevices(std::vector<CoolingDevice>* out_data) {
|
||||
|
||||
std::vector<CoolingDevice> cdev;
|
||||
|
||||
if (!utils.isCdevInitialized())
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
|
||||
"ThermalHAL not initialized properly.");
|
||||
else {
|
||||
if (utils.readCdevStates(cdev) <= 0)
|
||||
LOG(VERBOSE) << __func__ << "Failed to read thermal cooling devices.";
|
||||
}
|
||||
|
||||
if (out_data != nullptr)
|
||||
*out_data = std::move(cdev);
|
||||
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ScopedAStatus Thermal::getCoolingDevicesWithType(CoolingType in_type,
|
||||
std::vector<CoolingDevice>* out_data) {
|
||||
|
||||
std::vector<CoolingDevice> cdev;
|
||||
|
||||
if (!utils.isCdevInitialized())
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
|
||||
"ThermalHAL not initialized properly.");
|
||||
else {
|
||||
if (utils.readCdevStates(in_type, cdev) <= 0)
|
||||
LOG(VERBOSE) << __func__ << "Failed to read thermal cooling devices.";
|
||||
}
|
||||
|
||||
if (out_data != nullptr)
|
||||
*out_data = std::move(cdev);
|
||||
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ScopedAStatus Thermal::getTemperatures(std::vector<Temperature>* out_temp) {
|
||||
LOG(VERBOSE) << __func__;
|
||||
std::vector<Temperature> temperatures;
|
||||
|
||||
if (!utils.isSensorInitialized()) {
|
||||
std::vector<Temperature> _temp = {dummy_temp_1_0};
|
||||
LOG(VERBOSE) << __func__ << " Returning Dummy Value";
|
||||
|
||||
if (out_temp != nullptr)
|
||||
*out_temp = std::move(_temp);
|
||||
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
if (utils.readTemperatures(temperatures) <= 0)
|
||||
LOG(VERBOSE) << __func__ << "Sensor Temperature read failure.";
|
||||
|
||||
if (out_temp != nullptr)
|
||||
*out_temp = std::move(temperatures);
|
||||
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ScopedAStatus Thermal::getTemperaturesWithType(TemperatureType in_type,
|
||||
std::vector<Temperature>* out_temp) {
|
||||
|
||||
std::vector<Temperature> temperatures;
|
||||
|
||||
if (!utils.isSensorInitialized())
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
|
||||
"ThermalHAL not initialized properly.");
|
||||
else {
|
||||
if (utils.readTemperatures(in_type, temperatures) <= 0)
|
||||
LOG(VERBOSE) << __func__ << "Sensor Temperature read failure.";
|
||||
}
|
||||
|
||||
if (out_temp != nullptr)
|
||||
*out_temp = std::move(temperatures);
|
||||
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ScopedAStatus Thermal::getTemperatureThresholds(std::vector<TemperatureThreshold>* out_temp_thresh) {
|
||||
|
||||
std::vector<TemperatureThreshold> thresh;
|
||||
|
||||
if (!utils.isSensorInitialized())
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
|
||||
"ThermalHAL not initialized properly.");
|
||||
|
||||
if (utils.readTemperatureThreshold(thresh) <= 0)
|
||||
LOG(VERBOSE) << __func__ << "Sensor Threshold read failure or type not supported.";
|
||||
|
||||
if (out_temp_thresh != nullptr)
|
||||
*out_temp_thresh = std::move(thresh);
|
||||
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ScopedAStatus Thermal::getTemperatureThresholdsWithType(
|
||||
TemperatureType in_type,
|
||||
std::vector<TemperatureThreshold>* out_temp_thresh) {
|
||||
|
||||
std::vector<TemperatureThreshold> thresh;
|
||||
|
||||
if (!utils.isSensorInitialized())
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
|
||||
"ThermalHAL not initialized properly.");
|
||||
else{
|
||||
if (utils.readTemperatureThreshold(in_type, thresh) <= 0)
|
||||
LOG(VERBOSE) << __func__ << "Sensor Threshold read failure or type not supported.";
|
||||
}
|
||||
|
||||
if (out_temp_thresh != nullptr)
|
||||
*out_temp_thresh = std::move(thresh);
|
||||
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ScopedAStatus Thermal::registerThermalChangedCallback(
|
||||
const std::shared_ptr<IThermalChangedCallback>& in_callback) {
|
||||
|
||||
if (in_callback == nullptr) {
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
|
||||
"Invalid nullptr callback");
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
|
||||
TemperatureType in_type = TemperatureType::UNKNOWN;
|
||||
for (CallbackSetting _cb: cb) {
|
||||
if (interfacesEqual(_cb.callback, in_callback))
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
|
||||
"Callback already registered");
|
||||
}
|
||||
cb.emplace_back(in_callback, in_type);
|
||||
LOG(DEBUG) << "A callback has been registered to ThermalHAL ";
|
||||
}
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ScopedAStatus Thermal::registerThermalChangedCallbackWithType(
|
||||
const std::shared_ptr<IThermalChangedCallback>& in_callback, TemperatureType in_type) {
|
||||
LOG(VERBOSE) << __func__ << " IThermalChangedCallback: " << in_callback
|
||||
<< ", TemperatureType: " << static_cast<int32_t>(in_type);
|
||||
if (in_callback == nullptr) {
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
|
||||
"Invalid nullptr callback");
|
||||
}
|
||||
if (in_type == TemperatureType::BCL_VOLTAGE ||
|
||||
in_type == TemperatureType::BCL_CURRENT)
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
|
||||
"BCL current and voltage notification not supported");
|
||||
{
|
||||
std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
|
||||
for (CallbackSetting _cb: cb) {
|
||||
if (interfacesEqual(_cb.callback, in_callback))
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
|
||||
"Callback already registered");
|
||||
}
|
||||
cb.emplace_back(in_callback, in_type);
|
||||
LOG(DEBUG) << "A callback has been registered to ThermalHAL Type: " << android::hardware::thermal::toString(in_type);
|
||||
}
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ScopedAStatus Thermal::unregisterThermalChangedCallback(
|
||||
const std::shared_ptr<IThermalChangedCallback>& in_callback) {
|
||||
|
||||
if (in_callback == nullptr) {
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
|
||||
"Invalid nullptr callback");
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
|
||||
std::vector<CallbackSetting>::iterator it;
|
||||
bool removed = false;
|
||||
for (it = cb.begin(); it != cb.end(); it++) {
|
||||
if (interfacesEqual(it->callback, in_callback)) {
|
||||
cb.erase(it);
|
||||
LOG(DEBUG) << "callback unregistered. isFilter: ";
|
||||
removed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!removed) {
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
|
||||
"Callback wasn't registered");
|
||||
}
|
||||
LOG(DEBUG) << "A callback has been registered to ThermalHAL" ;
|
||||
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ScopedAStatus Thermal::registerCoolingDeviceChangedCallbackWithType(
|
||||
const std::shared_ptr<ICoolingDeviceChangedCallback> &in_callback, CoolingType in_type)
|
||||
{
|
||||
if (in_callback == nullptr)
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
|
||||
"Invalid nullptr callback");
|
||||
|
||||
std::lock_guard<std::mutex> _lock(cdev_callback_mutex_);
|
||||
for (CdevCallbackSetting _cb: cdev_cb) {
|
||||
if (interfacesEqual(_cb.callback, in_callback))
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
|
||||
"Callback already registered");
|
||||
}
|
||||
cdev_cb.emplace_back(CdevCallbackSetting(in_callback, in_type));
|
||||
LOG(DEBUG) << "CoolingDevice changed callback has been registered. Type: "<< android::hardware::thermal::toString(in_type);
|
||||
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ScopedAStatus Thermal::unregisterCoolingDeviceChangedCallback(
|
||||
const std::shared_ptr<ICoolingDeviceChangedCallback> &in_callback) {
|
||||
if (in_callback == nullptr)
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
|
||||
"Invalid nullptr callback");
|
||||
|
||||
std::lock_guard<std::mutex> _lock(cdev_callback_mutex_);
|
||||
std::vector<CdevCallbackSetting>::iterator it;
|
||||
bool removed = false;
|
||||
for (auto it = cdev_cb.begin(); it != cdev_cb.end(); it++) {
|
||||
if (interfacesEqual(it->callback, in_callback)) {
|
||||
cdev_cb.erase(it);
|
||||
removed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!removed) {
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
|
||||
"CoolingDevice changed callback wasn't registered");
|
||||
}
|
||||
LOG(DEBUG) << "A CoolingDevice changed callback has been unregistered to CDEV" ;
|
||||
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
void Thermal::sendCoolingDeviceChangeCB(const CoolingDevice &c)
|
||||
{
|
||||
std::lock_guard<std::mutex> _lock(cdev_callback_mutex_);
|
||||
std::vector<CdevCallbackSetting>::iterator it;
|
||||
|
||||
LOG(DEBUG) << "Cooling device Name: " << c.name <<
|
||||
" type: " << (int)c.type << " cur_level: " << c.value;
|
||||
it = cdev_cb.begin();
|
||||
while (it != cdev_cb.end()) {
|
||||
if (it->type == c.type) {
|
||||
::ndk::ScopedAStatus ret = it->callback->notifyCoolingDeviceChanged(c);
|
||||
if (!ret.isOk()) {
|
||||
LOG(ERROR) << "Notify CoolingDevice changed callback execution error. Removing"
|
||||
<<ret.getMessage();
|
||||
it = cdev_cb.erase(it);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
void Thermal::sendThrottlingChangeCB(const Temperature &t)
|
||||
{
|
||||
std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
|
||||
std::vector<CallbackSetting>::iterator it;
|
||||
|
||||
LOG(DEBUG) << "Throttle Severity change: " << " Type: " << (int)t.type
|
||||
<< " Name: " << t.name << " Value: " << t.value <<
|
||||
" ThrottlingStatus: " << (int)t.throttlingStatus;
|
||||
it = cb.begin();
|
||||
while (it != cb.end()) {
|
||||
if (it->type == t.type || it->type == TemperatureType::UNKNOWN) {
|
||||
::ndk::ScopedAStatus ret = it->callback->notifyThrottling(t);
|
||||
if (!ret.isOk()) {
|
||||
LOG(ERROR) << "Notify callback execution error. Removing"<<ret.getMessage();
|
||||
it = cb.erase(it);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace aidl::android::hardware::thermal
|
||||
130
qcom/opensource/thermal-hal/thermal.h
Normal file
130
qcom/opensource/thermal-hal/thermal.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
|
||||
Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
|
||||
#ifndef ANDROID_QTI_VENDOR_THERMAL_H
|
||||
#define ANDROID_QTI_VENDOR_THERMAL_H
|
||||
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <set>
|
||||
|
||||
#include <aidl/android/hardware/thermal/BnThermal.h>
|
||||
#include <aidl/android/hardware/thermal/IThermalChangedCallback.h>
|
||||
#include <aidl/android/hardware/thermal/ICoolingDeviceChangedCallback.h>
|
||||
|
||||
#ifdef ENABLE_THERMAL_NETLINK
|
||||
#include "thermalUtilsNetlink.h"
|
||||
#else
|
||||
#include "thermalUtils.h"
|
||||
#endif
|
||||
|
||||
#include "thermalData.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace thermal {
|
||||
|
||||
struct CallbackSetting {
|
||||
std::shared_ptr<IThermalChangedCallback> callback;
|
||||
TemperatureType type;
|
||||
|
||||
CallbackSetting(std::shared_ptr<IThermalChangedCallback> callback,
|
||||
TemperatureType type)
|
||||
: callback(callback), type(type) {}
|
||||
};
|
||||
|
||||
struct CdevCallbackSetting {
|
||||
std::shared_ptr<ICoolingDeviceChangedCallback> callback;
|
||||
CoolingType type;
|
||||
|
||||
CdevCallbackSetting(std::shared_ptr<ICoolingDeviceChangedCallback> callback,
|
||||
CoolingType type)
|
||||
: callback(callback), type(type) {}
|
||||
};
|
||||
|
||||
class Thermal : public BnThermal {
|
||||
public:
|
||||
Thermal();
|
||||
~Thermal() = default;
|
||||
|
||||
Thermal(const Thermal &) = delete;
|
||||
void operator=(const Thermal &) = delete;
|
||||
ndk::ScopedAStatus getCoolingDevices(std::vector<CoolingDevice>* out_devices) override;
|
||||
ndk::ScopedAStatus getCoolingDevicesWithType(CoolingType in_type,
|
||||
std::vector<CoolingDevice>* out_devices) override;
|
||||
|
||||
ndk::ScopedAStatus getTemperatures(std::vector<Temperature>* out_temperatures) override;
|
||||
ndk::ScopedAStatus getTemperaturesWithType(TemperatureType in_type,
|
||||
std::vector<Temperature>* out_temperatures) override;
|
||||
|
||||
ndk::ScopedAStatus getTemperatureThresholds(
|
||||
std::vector<TemperatureThreshold>* out_temperatureThresholds) override;
|
||||
|
||||
ndk::ScopedAStatus getTemperatureThresholdsWithType(
|
||||
TemperatureType in_type,
|
||||
std::vector<TemperatureThreshold>* out_temperatureThresholds) override;
|
||||
|
||||
ndk::ScopedAStatus registerThermalChangedCallback(
|
||||
const std::shared_ptr<IThermalChangedCallback>& in_callback) override;
|
||||
ndk::ScopedAStatus registerThermalChangedCallbackWithType(
|
||||
const std::shared_ptr<IThermalChangedCallback>& in_callback,
|
||||
TemperatureType in_type) override;
|
||||
ndk::ScopedAStatus registerCoolingDeviceChangedCallbackWithType(
|
||||
const std::shared_ptr<ICoolingDeviceChangedCallback> &in_callback,
|
||||
CoolingType in_type) override;
|
||||
|
||||
ndk::ScopedAStatus unregisterThermalChangedCallback(
|
||||
const std::shared_ptr<IThermalChangedCallback>& in_callback) override;
|
||||
ndk::ScopedAStatus unregisterCoolingDeviceChangedCallback(
|
||||
const std::shared_ptr<ICoolingDeviceChangedCallback> &in_callback) override;
|
||||
|
||||
void sendThrottlingChangeCB(const Temperature &t);
|
||||
void sendCoolingDeviceChangeCB(const CoolingDevice &c);
|
||||
|
||||
private:
|
||||
std::mutex thermal_callback_mutex_;
|
||||
std::mutex cdev_callback_mutex_;
|
||||
std::vector<CallbackSetting> cb;
|
||||
std::vector<CdevCallbackSetting> cdev_cb;
|
||||
ThermalUtils utils;
|
||||
};
|
||||
|
||||
} // namespace thermal
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // ANDROID_QTI_VENDOR_THERMAL_H
|
||||
642
qcom/opensource/thermal-hal/thermalCommon.cpp
Normal file
642
qcom/opensource/thermal-hal/thermalCommon.cpp
Normal file
@@ -0,0 +1,642 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
|
||||
Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
|
||||
#include <cstdio>
|
||||
#include <cinttypes>
|
||||
#include <string>
|
||||
#include <dirent.h>
|
||||
#include <unordered_map>
|
||||
#include <fstream>
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include "thermalCommon.h"
|
||||
|
||||
#define MAX_LENGTH 50
|
||||
#define MAX_PATH (256)
|
||||
#define DEFAULT_HYSTERESIS 5
|
||||
#define DEFAULT_SKIN_HYSTERESIS 2
|
||||
#define THERMAL_SYSFS "/sys/class/thermal/"
|
||||
#define TZ_DIR_NAME "thermal_zone"
|
||||
#define TZ_DIR_FMT "thermal_zone%d"
|
||||
#define TEMPERATURE_FILE_FORMAT "/sys/class/thermal/thermal_zone%d/temp"
|
||||
#define POLICY_FILE_FORMAT "/sys/class/thermal/thermal_zone%d/policy"
|
||||
#define TRIP_FILE_FORMAT "/sys/class/thermal/thermal_zone%d/trip_point_1_temp"
|
||||
#define HYST_FILE_FORMAT "/sys/class/thermal/thermal_zone%d/trip_point_1_hyst"
|
||||
#define TRIP_TYPE_FILE_FORMAT "/sys/class/thermal/thermal_zone%d/trip_point_%d_type"
|
||||
#define TRIP_N_FILE_FORMAT "/sys/class/thermal/thermal_zone%d/trip_point_%d_temp"
|
||||
#define USER_SPACE_POLICY "user_space"
|
||||
#define TZ_TYPE "type"
|
||||
#define CDEV_DIR_NAME "cooling_device"
|
||||
#define CDEV_DIR_FMT "cooling_device%d"
|
||||
#define CDEV_CUR_STATE_PATH "/sys/class/thermal/cooling_device%d/cur_state"
|
||||
#define CPU_USAGE_FILE "/proc/stat"
|
||||
#define CPU_ONLINE_FILE_FORMAT "/sys/devices/system/cpu/cpu%d/online"
|
||||
#define LIMIT_PROFILE_1_SD_TEMP 125000
|
||||
#define LIMIT_PROFILE_TRIP_TYPE "hot"
|
||||
#define LIMIT_PROFILE_SD_TZ "aoss-0"
|
||||
#define LIMIT_PROFILE_TRIP_MAX 11
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace thermal {
|
||||
|
||||
static std::unordered_map<std::string, cdevType> cdev_map = {
|
||||
{"thermal-cpufreq-0", cdevType::CPU},
|
||||
{"thermal-cpufreq-1", cdevType::CPU},
|
||||
{"thermal-cpufreq-2", cdevType::CPU},
|
||||
{"thermal-cpufreq-3", cdevType::CPU},
|
||||
{"thermal-cpufreq-4", cdevType::CPU},
|
||||
{"thermal-cpufreq-5", cdevType::CPU},
|
||||
{"thermal-cpufreq-6", cdevType::CPU},
|
||||
{"thermal-cpufreq-7", cdevType::CPU},
|
||||
{"cpufreq-cpu0", cdevType::CPU},
|
||||
{"cpufreq-cpu1", cdevType::CPU},
|
||||
{"cpufreq-cpu2", cdevType::CPU},
|
||||
{"cpufreq-cpu3", cdevType::CPU},
|
||||
{"cpufreq-cpu4", cdevType::CPU},
|
||||
{"cpufreq-cpu5", cdevType::CPU},
|
||||
{"cpufreq-cpu6", cdevType::CPU},
|
||||
{"cpufreq-cpu7", cdevType::CPU},
|
||||
{"thermal-cluster-4-7", cdevType::CPU},
|
||||
{"thermal-cluster-3-7", cdevType::CPU},
|
||||
{"cpu-isolate0", cdevType::CPU},
|
||||
{"cpu-isolate1", cdevType::CPU},
|
||||
{"cpu-isolate2", cdevType::CPU},
|
||||
{"cpu-isolate3", cdevType::CPU},
|
||||
{"cpu-isolate4", cdevType::CPU},
|
||||
{"cpu-isolate5", cdevType::CPU},
|
||||
{"cpu-isolate6", cdevType::CPU},
|
||||
{"cpu-isolate7", cdevType::CPU},
|
||||
{"thermal-pause-1", cdevType::CPU},
|
||||
{"thermal-pause-2", cdevType::CPU},
|
||||
{"thermal-pause-4", cdevType::CPU},
|
||||
{"thermal-pause-8", cdevType::CPU},
|
||||
{"thermal-pause-10", cdevType::CPU},
|
||||
{"thermal-pause-20", cdevType::CPU},
|
||||
{"thermal-pause-40", cdevType::CPU},
|
||||
{"thermal-pause-80", cdevType::CPU},
|
||||
{"thermal-devfreq-0", cdevType::GPU},
|
||||
{"devfreq-3d00000.qcom,kgsl-3d0", cdevType::GPU},
|
||||
{"gpu", cdevType::GPU},
|
||||
{"modem_tj", cdevType::MODEM},
|
||||
{"modem_lte_dsc", cdevType::MODEM},
|
||||
{"modem_nr_dsc", cdevType::MODEM},
|
||||
{"modem_nr_scg_dsc", cdevType::MODEM},
|
||||
{"cdsp", cdevType::NPU},
|
||||
{"cdsp_hw", cdevType::NPU},
|
||||
{"battery", cdevType::BATTERY},
|
||||
{"fan-max31760", cdevType::FAN},
|
||||
{"display-fps", cdevType::DISPLAY},
|
||||
};
|
||||
|
||||
ThermalCommon::ThermalCommon()
|
||||
{
|
||||
LOG(DEBUG) << "Entering " << __func__;
|
||||
ncpus = (int)sysconf(_SC_NPROCESSORS_CONF);
|
||||
if (ncpus < 1)
|
||||
LOG(ERROR) << "Error retrieving number of cores";
|
||||
}
|
||||
|
||||
static int writeToFile(std::string_view path, std::string data)
|
||||
{
|
||||
std::fstream outFile;
|
||||
|
||||
outFile.open(std::string(path).c_str(),
|
||||
std::fstream::binary | std::fstream::out);
|
||||
if (outFile.is_open()) {
|
||||
LOG(DEBUG) << "writing: "<< data << " in path:" << path
|
||||
<< std::endl;
|
||||
outFile << data;
|
||||
outFile.close();
|
||||
return data.length();
|
||||
}
|
||||
|
||||
LOG(ERROR) << "Error opening file: "<< path << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int readLineFromFile(std::string_view path, std::string& out)
|
||||
{
|
||||
char *fgets_ret;
|
||||
FILE *fd;
|
||||
int rv;
|
||||
char buf[MAX_LENGTH];
|
||||
|
||||
out.clear();
|
||||
|
||||
fd = fopen(std::string(path).c_str(), "r");
|
||||
if (fd == NULL) {
|
||||
LOG(ERROR) << "Path:" << std::string(path) << " file open error.err:"
|
||||
<< strerror(errno) << std::endl;
|
||||
return -errno;
|
||||
}
|
||||
|
||||
fgets_ret = fgets(buf, MAX_LENGTH, fd);
|
||||
if (NULL != fgets_ret) {
|
||||
rv = (int)strlen(buf);
|
||||
out.append(buf, rv);
|
||||
} else {
|
||||
rv = ferror(fd);
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
out.erase(std::remove(out.begin(), out.end(), '\n'), out.end());
|
||||
LOG(DEBUG) << "Path:" << std::string(path) << " Val:" << out << std::endl;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int ThermalCommon::readFromFile(std::string_view path, std::string& out)
|
||||
{
|
||||
return readLineFromFile(path, out);
|
||||
}
|
||||
|
||||
static int get_tzn(std::string sensor_name)
|
||||
{
|
||||
DIR *tdir = NULL;
|
||||
struct dirent *tdirent = NULL;
|
||||
int found = -1;
|
||||
int tzn = 0;
|
||||
char name[MAX_PATH] = {0};
|
||||
char cwd[MAX_PATH] = {0};
|
||||
int ret = 0;
|
||||
|
||||
if (!getcwd(cwd, sizeof(cwd)))
|
||||
return found;
|
||||
|
||||
/* Change dir to read the entries. Doesnt work otherwise */
|
||||
ret = chdir(THERMAL_SYSFS);
|
||||
if (ret) {
|
||||
LOG(ERROR) << "Unable to change to " << THERMAL_SYSFS << std::endl;
|
||||
return found;
|
||||
}
|
||||
tdir = opendir(THERMAL_SYSFS);
|
||||
if (!tdir) {
|
||||
LOG(ERROR) << "Unable to open " << THERMAL_SYSFS << std::endl;
|
||||
return found;
|
||||
}
|
||||
|
||||
while ((tdirent = readdir(tdir))) {
|
||||
std::string buf;
|
||||
|
||||
if (strncmp(tdirent->d_name, TZ_DIR_NAME,
|
||||
strlen(TZ_DIR_NAME)) != 0)
|
||||
continue;
|
||||
|
||||
snprintf(name, MAX_PATH, "%s%s/%s", THERMAL_SYSFS,
|
||||
tdirent->d_name, TZ_TYPE);
|
||||
ret = readLineFromFile(std::string_view(name), buf);
|
||||
if (ret <= 0) {
|
||||
LOG(ERROR) <<
|
||||
"get_tzn: sensor name read error for tz:" <<
|
||||
tdirent->d_name << std::endl;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(buf.c_str(), sensor_name.c_str(),
|
||||
sensor_name.length())) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found == 1) {
|
||||
sscanf(tdirent->d_name, TZ_DIR_FMT, &tzn);
|
||||
LOG(DEBUG) << "Sensor: " << sensor_name <<
|
||||
" found at tz: " << tzn << std::endl;
|
||||
found = tzn;
|
||||
}
|
||||
|
||||
closedir(tdir);
|
||||
/* Restore current working dir */
|
||||
ret = chdir(cwd);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
int ThermalCommon::initialize_sensor(struct target_therm_cfg& cfg, int sens_idx)
|
||||
{
|
||||
struct therm_sensor sensor;
|
||||
int idx = 0;
|
||||
|
||||
sensor.tzn = get_tzn(cfg.sensor_list[sens_idx]);
|
||||
if (sensor.tzn < 0) {
|
||||
LOG(ERROR) << "No thermal zone for sensor: " <<
|
||||
cfg.sensor_list[sens_idx] << ", ret:" <<
|
||||
sensor.tzn << std::endl;
|
||||
return -1;
|
||||
}
|
||||
if (cfg.type == TemperatureType::CPU)
|
||||
sensor.thresh.name = sensor.t.name =
|
||||
std::string("CPU") + std::to_string(sens_idx);
|
||||
else
|
||||
sensor.thresh.name = sensor.t.name = cfg.label;
|
||||
|
||||
if (cfg.type == TemperatureType::BCL_PERCENTAGE)
|
||||
sensor.mulFactor = 1;
|
||||
else
|
||||
sensor.mulFactor = 1000;
|
||||
|
||||
sensor.sensor_name = cfg.sensor_list[sens_idx];
|
||||
sensor.positiveThresh = cfg.positive_thresh_ramp;
|
||||
sensor.no_trip_set = cfg.no_trip_set;
|
||||
sensor.lastThrottleStatus = sensor.t.throttlingStatus =
|
||||
ThrottlingSeverity::NONE;
|
||||
sensor.thresh.type = sensor.t.type = cfg.type;
|
||||
for (idx = 0; idx <= (size_t)ThrottlingSeverity::SHUTDOWN; idx++) {
|
||||
sensor.thresh.hotThrottlingThresholds.push_back(UNKNOWN_TEMPERATURE);
|
||||
sensor.thresh.coldThrottlingThresholds.push_back(UNKNOWN_TEMPERATURE);
|
||||
}
|
||||
|
||||
for (idx = 0; idx <= (size_t)ThrottlingSeverity::SHUTDOWN; idx++) {
|
||||
if (cfg.thresh[idx] != 0 && cfg.positive_thresh_ramp)
|
||||
sensor.thresh.hotThrottlingThresholds[idx] =
|
||||
cfg.thresh[idx] / (float)sensor.mulFactor;
|
||||
else if (cfg.thresh[idx] != 0 && !cfg.positive_thresh_ramp)
|
||||
sensor.thresh.coldThrottlingThresholds[idx] =
|
||||
cfg.thresh[idx] / (float)sensor.mulFactor;
|
||||
}
|
||||
sens.push_back(sensor);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ThermalCommon::initializeCpuSensor(struct target_therm_cfg& cpu_cfg)
|
||||
{
|
||||
int cpu = 0;
|
||||
|
||||
for (;cpu < ncpus; cpu++) {
|
||||
if (initialize_sensor(cpu_cfg, cpu) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ThermalCommon::initThermalZones(std::vector<struct target_therm_cfg>& cfg)
|
||||
{
|
||||
std::vector<struct target_therm_cfg>::iterator it;
|
||||
|
||||
if (cfg.empty()) {
|
||||
LOG(ERROR) << std::string(__func__) +":Invalid input";
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (it = cfg.begin(); it != cfg.end(); it++)
|
||||
{
|
||||
if (it->type == TemperatureType::CPU) {
|
||||
if (initializeCpuSensor(*it) < 0)
|
||||
return -1;
|
||||
continue;
|
||||
}
|
||||
if (initialize_sensor(*it, 0) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return sens.size();
|
||||
}
|
||||
|
||||
int ThermalCommon::initCdev()
|
||||
{
|
||||
DIR *tdir = NULL;
|
||||
struct dirent *tdirent = NULL;
|
||||
int cdevn = 0;
|
||||
char name[MAX_PATH] = {0};
|
||||
char cwd[MAX_PATH] = {0};
|
||||
int ret = 0;
|
||||
|
||||
if (!getcwd(cwd, sizeof(cwd)))
|
||||
return 0;
|
||||
|
||||
/* Change dir to read the entries. Doesnt work otherwise */
|
||||
ret = chdir(THERMAL_SYSFS);
|
||||
if (ret) {
|
||||
LOG(ERROR) << "Unable to change to " << THERMAL_SYSFS << std::endl;
|
||||
return 0;
|
||||
}
|
||||
tdir = opendir(THERMAL_SYSFS);
|
||||
if (!tdir) {
|
||||
LOG(ERROR) << "Unable to open " << THERMAL_SYSFS << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while ((tdirent = readdir(tdir))) {
|
||||
std::string buf;
|
||||
struct dirent *tzdirent;
|
||||
std::unordered_map<std::string, cdevType>::iterator it;
|
||||
struct therm_cdev cdevInst;
|
||||
|
||||
if (strncmp(tdirent->d_name, CDEV_DIR_NAME,
|
||||
strlen(CDEV_DIR_NAME)) != 0)
|
||||
continue;
|
||||
|
||||
snprintf(name, MAX_PATH, "%s%s/%s", THERMAL_SYSFS,
|
||||
tdirent->d_name, TZ_TYPE);
|
||||
ret = readLineFromFile(std::string_view(name), buf);
|
||||
if (ret <= 0) {
|
||||
LOG(ERROR) <<
|
||||
"init_cdev: cdev type read error for cdev:" <<
|
||||
tdirent->d_name << std::endl;
|
||||
}
|
||||
it = cdev_map.find(buf);
|
||||
if (it == cdev_map.end())
|
||||
continue;
|
||||
sscanf(tdirent->d_name, CDEV_DIR_FMT, &cdevn);
|
||||
LOG(DEBUG) << "cdev: " << it->first <<
|
||||
" found at cdev number: " << cdevn << std::endl;
|
||||
cdevInst.c.name = it->first;
|
||||
cdevInst.c.type = it->second;
|
||||
cdevInst.cdevn = cdevn;
|
||||
read_cdev_state(cdevInst);
|
||||
cdev.push_back(cdevInst);
|
||||
}
|
||||
|
||||
closedir(tdir);
|
||||
/* Restore current working dir */
|
||||
ret = chdir(cwd);
|
||||
|
||||
return cdev.size();
|
||||
}
|
||||
|
||||
int ThermalCommon::read_cdev_state(struct therm_cdev& cdev)
|
||||
{
|
||||
char file_name[MAX_PATH];
|
||||
std::string buf;
|
||||
int ret = 0, ct = 0;
|
||||
bool read_ok = false;
|
||||
|
||||
snprintf(file_name, sizeof(file_name), CDEV_CUR_STATE_PATH,
|
||||
cdev.cdevn);
|
||||
do {
|
||||
ret = readLineFromFile(std::string(file_name), buf);
|
||||
if (ret <= 0) {
|
||||
LOG(ERROR) << "Cdev state read error:"<< ret <<
|
||||
" for cdev: " << cdev.c.name;
|
||||
return -1;
|
||||
}
|
||||
try {
|
||||
cdev.c.value = std::stoi(buf, nullptr, 0);
|
||||
read_ok = true;
|
||||
}
|
||||
catch (std::exception &err) {
|
||||
LOG(ERROR) << "Cdev read stoi error:" << err.what()
|
||||
<< " cdev:" << cdev.c.name << " ID:"
|
||||
<< cdev.cdevn << " buf:" << buf <<
|
||||
std::endl;
|
||||
}
|
||||
ct++;
|
||||
} while (!read_ok && ct < RETRY_CT);
|
||||
LOG(DEBUG) << "cdev Name:" << cdev.c.name << ". state:" <<
|
||||
cdev.c.value << std::endl;
|
||||
|
||||
return cdev.c.value;
|
||||
}
|
||||
|
||||
int ThermalCommon::estimateSeverity(struct therm_sensor& sensor)
|
||||
{
|
||||
int idx = 0;
|
||||
ThrottlingSeverity severity = ThrottlingSeverity::NONE;
|
||||
float temp = sensor.t.value;
|
||||
int hysteresis = (sensor.thresh.type == TemperatureType::SKIN) ?
|
||||
DEFAULT_SKIN_HYSTERESIS : DEFAULT_HYSTERESIS;
|
||||
|
||||
for (idx = (int)ThrottlingSeverity::SHUTDOWN; idx >= 0; idx--) {
|
||||
/* If a particular threshold is hit already, check if the
|
||||
* hysteresis is cleared before changing the severity */
|
||||
if (idx <= (int)sensor.t.throttlingStatus) {
|
||||
if ((sensor.positiveThresh &&
|
||||
!isnan(sensor.thresh.hotThrottlingThresholds[idx]) &&
|
||||
temp >=
|
||||
(sensor.thresh.hotThrottlingThresholds[idx] - hysteresis)) ||
|
||||
(!sensor.positiveThresh &&
|
||||
!isnan(sensor.thresh.coldThrottlingThresholds[idx]) &&
|
||||
temp <=
|
||||
(sensor.thresh.coldThrottlingThresholds[idx] + hysteresis)))
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if ((sensor.positiveThresh &&
|
||||
!isnan(sensor.thresh.hotThrottlingThresholds[idx]) &&
|
||||
temp >=
|
||||
sensor.thresh.hotThrottlingThresholds[idx]) ||
|
||||
(!sensor.positiveThresh &&
|
||||
!isnan(sensor.thresh.coldThrottlingThresholds[idx]) &&
|
||||
temp <=
|
||||
sensor.thresh.coldThrottlingThresholds[idx]))
|
||||
break;
|
||||
}
|
||||
if (idx >= 0)
|
||||
severity = (ThrottlingSeverity)(idx);
|
||||
LOG(DEBUG) << "Sensor Name:" << sensor.t.name << "temp: " <<
|
||||
temp << ". prev severity:" <<
|
||||
(int)sensor.lastThrottleStatus << ". cur severity:" <<
|
||||
(int)sensor.t.throttlingStatus << " New severity:" <<
|
||||
(int)severity << std::endl;
|
||||
if (severity == sensor.t.throttlingStatus)
|
||||
return -1;
|
||||
sensor.lastThrottleStatus = sensor.t.throttlingStatus;
|
||||
sensor.t.throttlingStatus = severity;
|
||||
|
||||
return (int)severity;
|
||||
}
|
||||
|
||||
int ThermalCommon::read_temperature(struct therm_sensor& sensor)
|
||||
{
|
||||
char file_name[MAX_PATH];
|
||||
float temp;
|
||||
std::string buf;
|
||||
int ret = 0, ct = 0;
|
||||
bool read_ok = false;
|
||||
|
||||
do {
|
||||
snprintf(file_name, sizeof(file_name), TEMPERATURE_FILE_FORMAT,
|
||||
sensor.tzn);
|
||||
ret = readLineFromFile(std::string(file_name), buf);
|
||||
if (ret <= 0) {
|
||||
LOG(ERROR) << "Temperature read error:"<< ret <<
|
||||
" for sensor " << sensor.t.name;
|
||||
return -1;
|
||||
}
|
||||
try {
|
||||
sensor.t.value = (float)std::stoi(buf, nullptr, 0) /
|
||||
(float)sensor.mulFactor;
|
||||
read_ok = true;
|
||||
}
|
||||
catch (std::exception &err) {
|
||||
LOG(ERROR) << "Temperature buf stoi error: "
|
||||
<< err.what()
|
||||
<< " buf:" << buf << " sensor:"
|
||||
<< sensor.t.name << " TZ:" <<
|
||||
sensor.tzn << std::endl;
|
||||
}
|
||||
ct++;
|
||||
} while (!read_ok && ct < RETRY_CT);
|
||||
LOG(DEBUG) << "Sensor Name:" << sensor.t.name << ". Temperature:" <<
|
||||
(float)sensor.t.value << std::endl;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ThermalCommon::initThreshold(struct therm_sensor& sensor)
|
||||
{
|
||||
char file_name[MAX_PATH] = "";
|
||||
std::string buf;
|
||||
int ret = 0, idx;
|
||||
ThrottlingSeverity severity = ThrottlingSeverity::NONE;
|
||||
int next_trip, curr_trip, hyst_temp = 0;
|
||||
int hysteresis = (sensor.thresh.type == TemperatureType::SKIN) ?
|
||||
DEFAULT_SKIN_HYSTERESIS : DEFAULT_HYSTERESIS;
|
||||
|
||||
LOG(DEBUG) << "Entering " <<__func__;
|
||||
if (!sensor.positiveThresh) {
|
||||
LOG(ERROR) << "negative temperature ramp for sensor:"<<
|
||||
sensor.t.name;
|
||||
return;
|
||||
}
|
||||
#ifndef ENABLE_THERMAL_NETLINK
|
||||
snprintf(file_name, sizeof(file_name), POLICY_FILE_FORMAT,
|
||||
sensor.tzn);
|
||||
ret = readLineFromFile(std::string(file_name), buf);
|
||||
if (ret <= 0) {
|
||||
LOG(ERROR) << "Policy read error:"<< ret <<
|
||||
" for sensor " << sensor.t.name;
|
||||
return;
|
||||
}
|
||||
if (buf != std::string(USER_SPACE_POLICY)) {
|
||||
LOG(ERROR) << "Policy error:"<< buf << " sensor:" <<
|
||||
sensor.t.name << std::endl;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
next_trip = UNKNOWN_TEMPERATURE;
|
||||
for (idx = 0;idx <= (int)ThrottlingSeverity::SHUTDOWN; idx++) {
|
||||
if (isnan(sensor.thresh.hotThrottlingThresholds[idx])
|
||||
|| idx <= (int)sensor.t.throttlingStatus)
|
||||
continue;
|
||||
|
||||
next_trip = sensor.thresh.hotThrottlingThresholds[idx] *
|
||||
sensor.mulFactor;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isnan(next_trip)) {
|
||||
LOG(DEBUG) << "Sensor: " << sensor.t.name << " high trip:"
|
||||
<< next_trip << std::endl;
|
||||
snprintf(file_name, sizeof(file_name), TRIP_FILE_FORMAT,
|
||||
sensor.tzn);
|
||||
writeToFile(std::string_view(file_name), std::to_string(next_trip));
|
||||
}
|
||||
if (sensor.t.throttlingStatus != ThrottlingSeverity::NONE) {
|
||||
curr_trip = sensor.thresh.hotThrottlingThresholds[
|
||||
(int)sensor.t.throttlingStatus]
|
||||
* sensor.mulFactor;
|
||||
if (!isnan(next_trip))
|
||||
hyst_temp = (next_trip - curr_trip) + (hysteresis *
|
||||
sensor.mulFactor);
|
||||
else
|
||||
hyst_temp = hysteresis * sensor.mulFactor;
|
||||
LOG(DEBUG) << "Sensor: " << sensor.t.name << " hysteresis:"
|
||||
<< hyst_temp << std::endl;
|
||||
snprintf(file_name, sizeof(file_name), HYST_FILE_FORMAT,
|
||||
sensor.tzn);
|
||||
writeToFile(std::string_view(file_name), std::to_string(hyst_temp));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int ThermalCommon::findLimitProfile(void)
|
||||
{
|
||||
char file_name[MAX_PATH];
|
||||
std::string buf;
|
||||
int trip = 1, lp = -1;
|
||||
int ct = 0, ret = 0;
|
||||
bool read_ok = false;
|
||||
int tzn = get_tzn(LIMIT_PROFILE_SD_TZ);
|
||||
if (tzn < 0) {
|
||||
LOG(ERROR) <<" Not able to get tz id for "
|
||||
<< LIMIT_PROFILE_SD_TZ << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
do {
|
||||
snprintf(file_name, sizeof(file_name), TRIP_TYPE_FILE_FORMAT,
|
||||
tzn, trip);
|
||||
ret = readFromFile(std::string_view(file_name), buf);
|
||||
if (ret <= 0) {
|
||||
LOG(ERROR) <<" Not able to read trip type trip: "
|
||||
<< trip << std::endl;
|
||||
return -1;
|
||||
}
|
||||
if (strncmp(buf.c_str(), LIMIT_PROFILE_TRIP_TYPE,
|
||||
strlen(LIMIT_PROFILE_TRIP_TYPE))) {
|
||||
trip++;
|
||||
if (trip > LIMIT_PROFILE_TRIP_MAX)
|
||||
return -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
snprintf(file_name, sizeof(file_name), TRIP_N_FILE_FORMAT,
|
||||
tzn, trip);
|
||||
do {
|
||||
ret = readFromFile(std::string_view(file_name), buf);
|
||||
if (ret <= 0) {
|
||||
LOG(ERROR) <<" Not able to read trip temp, id: "
|
||||
<< trip << std::endl;
|
||||
return -1;
|
||||
}
|
||||
try {
|
||||
lp = std::stoi(buf, nullptr, 0);
|
||||
read_ok = true;
|
||||
}
|
||||
catch (std::exception &err) {
|
||||
LOG(ERROR) <<"limits profile stoi err:"
|
||||
<< err.what() << " buf:" << buf;
|
||||
}
|
||||
ct++;
|
||||
} while (!read_ok && ct < RETRY_CT);
|
||||
|
||||
lp = lp == LIMIT_PROFILE_1_SD_TEMP ? 1 : 0;
|
||||
|
||||
break;
|
||||
} while (1);
|
||||
|
||||
return lp;
|
||||
}
|
||||
}// namespace thermal
|
||||
}// namespace hardware
|
||||
}// namespace android
|
||||
}// namespace aidl
|
||||
81
qcom/opensource/thermal-hal/thermalCommon.h
Normal file
81
qcom/opensource/thermal-hal/thermalCommon.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef THERMAL_THERMAL_COMMON_H__
|
||||
#define THERMAL_THERMAL_COMMON_H__
|
||||
|
||||
#include "thermalData.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace thermal {
|
||||
|
||||
#define RETRY_CT 3
|
||||
|
||||
class ThermalCommon {
|
||||
public:
|
||||
ThermalCommon();
|
||||
~ThermalCommon() = default;
|
||||
|
||||
int readFromFile(std::string_view path, std::string& out);
|
||||
int initThermalZones(std::vector<struct target_therm_cfg>& cfg);
|
||||
void initThreshold(struct therm_sensor& sens);
|
||||
int initCdev();
|
||||
|
||||
int read_cdev_state(struct therm_cdev& cdev);
|
||||
int read_temperature(struct therm_sensor& sensor);
|
||||
int estimateSeverity(struct therm_sensor& sensor);
|
||||
int findLimitProfile(void);
|
||||
std::vector<struct therm_sensor> fetch_sensor_list()
|
||||
{
|
||||
return sens;
|
||||
};
|
||||
std::vector<struct therm_cdev> fetch_cdev_list()
|
||||
{
|
||||
return cdev;
|
||||
};
|
||||
|
||||
private:
|
||||
int ncpus;
|
||||
std::vector<struct target_therm_cfg> cfg;
|
||||
std::vector<struct therm_sensor> sens;
|
||||
std::vector<struct therm_cdev> cdev;
|
||||
|
||||
int initializeCpuSensor(struct target_therm_cfg& cpu_cfg);
|
||||
int initialize_sensor(struct target_therm_cfg& cfg,
|
||||
int sens_idx);
|
||||
};
|
||||
|
||||
} // namespace thermal
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
#endif // THERMAL_THERMAL_COMMON_H__
|
||||
2404
qcom/opensource/thermal-hal/thermalConfig.cpp
Normal file
2404
qcom/opensource/thermal-hal/thermalConfig.cpp
Normal file
File diff suppressed because it is too large
Load Diff
72
qcom/opensource/thermal-hal/thermalConfig.h
Normal file
72
qcom/opensource/thermal-hal/thermalConfig.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
|
||||
Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
|
||||
#ifndef THERMAL_THERMAL_CONFIG_H__
|
||||
#define THERMAL_THERMAL_CONFIG_H__
|
||||
|
||||
#include <aidl/android/hardware/thermal/BnThermal.h>
|
||||
|
||||
#include "thermalData.h"
|
||||
#include "thermalCommon.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace thermal {
|
||||
|
||||
class ThermalConfig {
|
||||
public:
|
||||
ThermalConfig();
|
||||
~ThermalConfig() = default;
|
||||
|
||||
std::vector<struct target_therm_cfg> fetchConfig(void)
|
||||
{
|
||||
return thermalConfig;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<struct target_therm_cfg> thermalConfig;
|
||||
int soc_id;
|
||||
std::string hw_platform;
|
||||
int limitp;
|
||||
ThermalCommon cmnInst;
|
||||
};
|
||||
|
||||
} // namespace thermal
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // THERMAL_THERMAL_CONFIG_H__
|
||||
104
qcom/opensource/thermal-hal/thermalData.h
Normal file
104
qcom/opensource/thermal-hal/thermalData.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
|
||||
Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
|
||||
#ifndef THERMAL_THERMAL_DATA_H__
|
||||
#define THERMAL_THERMAL_DATA_H__
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include <cmath>
|
||||
#include <aidl/android/hardware/thermal/BnThermal.h>
|
||||
|
||||
#define UNKNOWN_TEMPERATURE (NAN)
|
||||
|
||||
namespace aidl{
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace thermal {
|
||||
|
||||
using CoolingDevice = ::aidl::android::hardware::thermal::CoolingDevice;
|
||||
using Temperature = ::aidl::android::hardware::thermal::Temperature;
|
||||
using TemperatureType = ::aidl::android::hardware::thermal::TemperatureType;
|
||||
|
||||
using cdevType = ::aidl::android::hardware::thermal::CoolingType;
|
||||
using CoolingDevice = ::aidl::android::hardware::thermal::CoolingDevice;
|
||||
using Temperature = ::aidl::android::hardware::thermal::Temperature;
|
||||
using TemperatureType = ::aidl::android::hardware::thermal::TemperatureType;
|
||||
using TemperatureThreshold =
|
||||
::aidl::android::hardware::thermal::TemperatureThreshold;
|
||||
using ::aidl::android::hardware::thermal::ThrottlingSeverity;
|
||||
|
||||
enum QthrottlingSeverity {
|
||||
NONE = (size_t)ThrottlingSeverity::NONE,
|
||||
LIGHT = (size_t)ThrottlingSeverity::LIGHT,
|
||||
MODERATE = (size_t)ThrottlingSeverity::MODERATE,
|
||||
SEVERE = (size_t)ThrottlingSeverity::SEVERE,
|
||||
CRITICAL = (size_t)ThrottlingSeverity::CRITICAL,
|
||||
EMERGENCY = (size_t)ThrottlingSeverity::EMERGENCY,
|
||||
SHUTDOWN = (size_t)ThrottlingSeverity::SHUTDOWN,
|
||||
};
|
||||
|
||||
struct target_therm_cfg {
|
||||
TemperatureType type;
|
||||
std::vector<std::string> sensor_list;
|
||||
std::string label;
|
||||
int thresh[SHUTDOWN + 1];
|
||||
bool positive_thresh_ramp;
|
||||
bool no_trip_set = false;
|
||||
};
|
||||
|
||||
struct therm_sensor {
|
||||
int tzn;
|
||||
int mulFactor;
|
||||
bool positiveThresh;
|
||||
std::string sensor_name;
|
||||
ThrottlingSeverity lastThrottleStatus;
|
||||
Temperature t;
|
||||
TemperatureThreshold thresh;
|
||||
bool no_trip_set;
|
||||
};
|
||||
|
||||
struct therm_cdev {
|
||||
int cdevn;
|
||||
CoolingDevice c;
|
||||
};
|
||||
|
||||
} // namespace thermal
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // THERMAL_THERMAL_DATA_H__
|
||||
195
qcom/opensource/thermal-hal/thermalMonitor.cpp
Normal file
195
qcom/opensource/thermal-hal/thermalMonitor.cpp
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright (c) 2020,2023, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
|
||||
Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
|
||||
#include <unistd.h>
|
||||
#include <poll.h>
|
||||
#include <sys/socket.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/properties.h>
|
||||
#include <android-base/stringprintf.h>
|
||||
|
||||
#include "thermalMonitor.h"
|
||||
|
||||
#define UEVENT_BUF 1024
|
||||
|
||||
#define HYST_FMT "change@/devices/virtual/thermal/thermal_zone%d\n\
|
||||
ACTION=change\n\
|
||||
DEVPATH=/devices/virtual/thermal/thermal_zone%d\n\
|
||||
SUBSYSTEM=thermal\n\
|
||||
NAME=%s\n\
|
||||
TEMP=%d\n\
|
||||
HYST=%d\n\
|
||||
EVENT=%d\n"\
|
||||
|
||||
#define TRIP_FMT "change@/devices/virtual/thermal/thermal_zone%d\n\
|
||||
ACTION=change\n\
|
||||
DEVPATH=/devices/virtual/thermal/thermal_zone%d\n\
|
||||
SUBSYSTEM=thermal\n\
|
||||
NAME=%s\n\
|
||||
TEMP=%d\n\
|
||||
TRIP=%d\n\
|
||||
EVENT=%d\n"\
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace thermal {
|
||||
|
||||
using parseCB = std::function<void(char *inp_buf, ssize_t len)>;
|
||||
using pollCB = std::function<bool()>;
|
||||
|
||||
void thermal_monitor_uevent(const parseCB &parse_cb, const pollCB &stopPollCB)
|
||||
{
|
||||
struct pollfd pfd;
|
||||
char buf[UEVENT_BUF] = {0};
|
||||
int sz = 64*1024;
|
||||
struct sockaddr_nl nls;
|
||||
|
||||
memset(&nls, 0, sizeof(nls));
|
||||
nls.nl_family = AF_NETLINK;
|
||||
nls.nl_pid = getpid();
|
||||
nls.nl_groups = 0xffffffff;
|
||||
|
||||
pfd.events = POLLIN;
|
||||
pfd.fd = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC,
|
||||
NETLINK_KOBJECT_UEVENT);
|
||||
if (pfd.fd < 0) {
|
||||
LOG(ERROR) << "socket creation error:" << errno << std::endl;
|
||||
return;
|
||||
}
|
||||
LOG(DEBUG) << "socket creation success" << std::endl;
|
||||
|
||||
setsockopt(pfd.fd, SOL_SOCKET, SO_RCVBUF, &sz, sizeof(sz));
|
||||
if (bind(pfd.fd, (struct sockaddr *)&nls, sizeof(nls)) < 0) {
|
||||
close(pfd.fd);
|
||||
LOG(ERROR) << "socket bind failed:" << errno << std::endl;
|
||||
return;
|
||||
}
|
||||
LOG(DEBUG) << "Listening for uevent" << std::endl;
|
||||
|
||||
while (!stopPollCB()) {
|
||||
ssize_t len;
|
||||
int err;
|
||||
|
||||
err = poll(&pfd, 1, -1);
|
||||
if (err == -1) {
|
||||
LOG(ERROR) << "Error in uevent poll.";
|
||||
break;
|
||||
}
|
||||
if (stopPollCB()) {
|
||||
LOG(INFO) << "Exiting uevent monitor" << std::endl;
|
||||
return;
|
||||
}
|
||||
len = recv(pfd.fd, buf, sizeof(buf) - 1, MSG_DONTWAIT);
|
||||
if (len == -1) {
|
||||
LOG(ERROR) << "uevent read failed:" << errno << std::endl;
|
||||
continue;
|
||||
}
|
||||
buf[len] = '\0';
|
||||
|
||||
parse_cb(buf, len);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ThermalMonitor::ThermalMonitor(const ueventMonitorCB &inp_cb):
|
||||
cb(inp_cb)
|
||||
{
|
||||
monitor_shutdown = false;
|
||||
}
|
||||
|
||||
ThermalMonitor::~ThermalMonitor()
|
||||
{
|
||||
monitor_shutdown = true;
|
||||
th.join();
|
||||
}
|
||||
|
||||
void ThermalMonitor::start()
|
||||
{
|
||||
th = std::thread(thermal_monitor_uevent,
|
||||
std::bind(&ThermalMonitor::parse_and_notify, this,
|
||||
std::placeholders::_1, std::placeholders::_2),
|
||||
std::bind(&ThermalMonitor::stopPolling, this));
|
||||
}
|
||||
|
||||
void ThermalMonitor::parse_and_notify(char *inp_buf, ssize_t len)
|
||||
{
|
||||
int zone_num, temp, trip, ret = 0, event;
|
||||
ssize_t i = 0;
|
||||
char sensor_name[30] = "", buf[UEVENT_BUF] = {0};
|
||||
|
||||
LOG(DEBUG) << "monitor received thermal uevent: " << inp_buf
|
||||
<< std::endl;
|
||||
|
||||
while (i < len) {
|
||||
if (i >= UEVENT_BUF)
|
||||
return;
|
||||
ret = snprintf(buf + i, UEVENT_BUF - i, "%s ", inp_buf + i);
|
||||
if (ret == (strlen(inp_buf + i) + 1))
|
||||
i += ret;
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strstr(buf, "SUBSYSTEM=thermal"))
|
||||
return;
|
||||
|
||||
if (strstr(buf, "TRIP=")) {
|
||||
ret = sscanf(buf, TRIP_FMT, &zone_num, &zone_num, sensor_name,
|
||||
&temp, &trip, &event);
|
||||
LOG(DEBUG) << "zone:" << zone_num << " sensor:" << sensor_name
|
||||
<<" temp:" << temp << " trip:" << trip << " event:" <<
|
||||
event << std::endl;
|
||||
} else {
|
||||
ret = sscanf(buf, HYST_FMT, &zone_num, &zone_num, sensor_name,
|
||||
&temp, &trip, &event);
|
||||
LOG(DEBUG) << "zone:" << zone_num << " sensor:" << sensor_name
|
||||
<<" temp:" << temp << " trip:" << trip << " event:" <<
|
||||
event << std::endl;
|
||||
}
|
||||
if (ret <= 0 || ret == EOF) {
|
||||
LOG(ERROR) << "read error:" << ret <<". buf:" << buf << std::endl;
|
||||
return;
|
||||
}
|
||||
cb(sensor_name, temp);
|
||||
}
|
||||
|
||||
} // namespace thermal
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
71
qcom/opensource/thermal-hal/thermalMonitor.h
Normal file
71
qcom/opensource/thermal-hal/thermalMonitor.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
|
||||
Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
|
||||
#ifndef THERMAL_THERMAL_MONITOR_H__
|
||||
#define THERMAL_THERMAL_MONITOR_H__
|
||||
|
||||
#include <thread>
|
||||
#include <aidl/android/hardware/thermal/BnThermal.h>
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace thermal {
|
||||
|
||||
using ueventMonitorCB = std::function<void(std::string sensor_name, int temp)>;
|
||||
|
||||
class ThermalMonitor {
|
||||
public:
|
||||
ThermalMonitor(const ueventMonitorCB &inp_cb);
|
||||
~ThermalMonitor();
|
||||
|
||||
void parse_and_notify(char *inp_buf, ssize_t len);
|
||||
bool stopPolling()
|
||||
{
|
||||
return monitor_shutdown;
|
||||
}
|
||||
void start();
|
||||
private:
|
||||
std::thread th;
|
||||
bool monitor_shutdown;
|
||||
ueventMonitorCB cb;
|
||||
};
|
||||
|
||||
} // namespace thermal
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // THERMAL_THERMAL_MONITOR_H__
|
||||
324
qcom/opensource/thermal-hal/thermalMonitorNetlink.cpp
Normal file
324
qcom/opensource/thermal-hal/thermalMonitorNetlink.cpp
Normal file
@@ -0,0 +1,324 @@
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
|
||||
Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
|
||||
#include <unistd.h>
|
||||
#include <linux/thermal.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/properties.h>
|
||||
#include <android-base/stringprintf.h>
|
||||
|
||||
#include "thermalMonitorNetlink.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace thermal {
|
||||
|
||||
using pollCB = std::function<bool()>;
|
||||
using familyCB = std::function<int(struct nl_msg *, void *)>;
|
||||
|
||||
void thermal_listen(struct nl_sock *soc, const pollCB &stopCB)
|
||||
{
|
||||
while (!stopCB())
|
||||
nl_recvmsgs_default(soc);
|
||||
|
||||
LOG(INFO) << "thermal_listen_event Exit" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
int thermal_event_cb(struct nl_msg *n, void *data)
|
||||
{
|
||||
ThermalMonitor *t = (ThermalMonitor *)data;
|
||||
return t->event_parse(n, NULL);
|
||||
}
|
||||
|
||||
int thermal_sample_cb(struct nl_msg *n, void *data)
|
||||
{
|
||||
ThermalMonitor *t = (ThermalMonitor *)data;
|
||||
return t->sample_parse(n, NULL);
|
||||
}
|
||||
|
||||
int thermal_family_cb(struct nl_msg *n, void *data)
|
||||
{
|
||||
ThermalMonitor *t = (ThermalMonitor *)data;
|
||||
return t->family_msg_cb(n, NULL);
|
||||
}
|
||||
|
||||
ThermalMonitor::ThermalMonitor(const eventMonitorCB &inp_event_cb,
|
||||
const eventMonitorCB &inp_sample_cb,
|
||||
const eventCreateMonitorCB &inp_event_create_cb,
|
||||
const eventMonitorCB &inp_event_cdev_cb):
|
||||
event_group(-1),
|
||||
sample_group(-1),
|
||||
event_cb(inp_event_cb),
|
||||
sample_cb(inp_sample_cb),
|
||||
event_create_cb(inp_event_create_cb),
|
||||
cdev_cb(inp_event_cdev_cb)
|
||||
{
|
||||
monitor_shutdown = false;
|
||||
}
|
||||
|
||||
ThermalMonitor::~ThermalMonitor()
|
||||
{
|
||||
monitor_shutdown = true;
|
||||
event_th.join();
|
||||
sample_th.join();
|
||||
if (sample_soc)
|
||||
nl_socket_free(sample_soc);
|
||||
if (event_soc)
|
||||
nl_socket_free(event_soc);
|
||||
}
|
||||
|
||||
int ThermalMonitor::event_parse(struct nl_msg *n, void *data)
|
||||
{
|
||||
struct nlmsghdr *nl_hdr = nlmsg_hdr(n);
|
||||
struct genlmsghdr *hdr = genlmsg_hdr(nl_hdr);
|
||||
struct nlattr *attrs[THERMAL_GENL_ATTR_MAX + 1];
|
||||
int tzn = -1, trip = -1, cdev_id = -1, curr_state = -1;
|
||||
const char *tz_name = "";
|
||||
|
||||
genlmsg_parse(nl_hdr, 0, attrs, THERMAL_GENL_ATTR_MAX, NULL);
|
||||
|
||||
switch (hdr->cmd) {
|
||||
case THERMAL_GENL_EVENT_TZ_TRIP_UP:
|
||||
case THERMAL_GENL_EVENT_TZ_TRIP_DOWN:
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_ID])
|
||||
tzn = nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
|
||||
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID])
|
||||
trip = nla_get_u32(
|
||||
attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID]);
|
||||
LOG(DEBUG) << "thermal_nl_event: TZ:" << tzn << " Trip:"
|
||||
<< trip << "event:" << (int)hdr->cmd << std::endl;
|
||||
event_cb(tzn, trip);
|
||||
break;
|
||||
case THERMAL_GENL_EVENT_TZ_CREATE:
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_ID])
|
||||
tzn = nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_NAME])
|
||||
tz_name = nla_get_string(attrs[THERMAL_GENL_ATTR_TZ_NAME]);
|
||||
LOG(DEBUG) << "thermal_nl_event: TZ_CREATE: TZ:" << tzn << " TZ_NAME:"
|
||||
<< tz_name << "event:" << (int)hdr->cmd << std::endl;
|
||||
event_create_cb(tzn, tz_name);
|
||||
break;
|
||||
case THERMAL_GENL_EVENT_CDEV_STATE_UPDATE:
|
||||
if (attrs[THERMAL_GENL_ATTR_CDEV_ID])
|
||||
cdev_id = nla_get_u32(attrs[THERMAL_GENL_ATTR_CDEV_ID]);
|
||||
if (attrs[THERMAL_GENL_ATTR_CDEV_CUR_STATE])
|
||||
curr_state = nla_get_u32(attrs[THERMAL_GENL_ATTR_CDEV_CUR_STATE]);
|
||||
LOG(DEBUG) << "thermal_nl_event: CDEV:" << cdev_id <<
|
||||
" curr_state :" << curr_state << " event:" << (int)hdr->cmd<< std::endl;
|
||||
cdev_cb(cdev_id, curr_state);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int ThermalMonitor::sample_parse(struct nl_msg *n, void *data)
|
||||
{
|
||||
struct nlmsghdr *nl_hdr = nlmsg_hdr(n);
|
||||
struct genlmsghdr *hdr = genlmsg_hdr(nl_hdr);
|
||||
struct nlattr *attrs[THERMAL_GENL_ATTR_MAX + 1];
|
||||
int tzn = -1, temp = -1;
|
||||
|
||||
genlmsg_parse(nl_hdr, 0, attrs, THERMAL_GENL_ATTR_MAX, NULL);
|
||||
|
||||
switch (hdr->cmd) {
|
||||
case THERMAL_GENL_SAMPLING_TEMP:
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_ID])
|
||||
tzn = nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
|
||||
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_TEMP])
|
||||
temp = nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TEMP]);
|
||||
|
||||
LOG(DEBUG) << "thermal_sample_event: TZ:" << tzn << " temp:"
|
||||
<< temp << std::endl;
|
||||
sample_cb(tzn, temp);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int ThermalMonitor::family_msg_cb(struct nl_msg *msg, void *data)
|
||||
{
|
||||
struct nlattr *tb[CTRL_ATTR_MAX + 1];
|
||||
struct genlmsghdr *gnlh = genlmsg_hdr(nlmsg_hdr(msg));
|
||||
struct nlattr *mc_group;
|
||||
int rem_mcgrp;
|
||||
|
||||
nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
|
||||
genlmsg_attrlen(gnlh, 0), NULL);
|
||||
|
||||
if (!tb[CTRL_ATTR_MCAST_GROUPS]) {
|
||||
LOG(ERROR) << "Multicast group not available\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
nla_for_each_nested(mc_group, tb[CTRL_ATTR_MCAST_GROUPS], rem_mcgrp) {
|
||||
|
||||
struct nlattr *nl_group[CTRL_ATTR_MCAST_GRP_MAX + 1];
|
||||
|
||||
nla_parse(nl_group, CTRL_ATTR_MCAST_GRP_MAX,
|
||||
(struct nlattr *)nla_data(mc_group),
|
||||
nla_len(mc_group), NULL);
|
||||
|
||||
if (!nl_group[CTRL_ATTR_MCAST_GRP_NAME] ||
|
||||
!nl_group[CTRL_ATTR_MCAST_GRP_ID])
|
||||
continue;
|
||||
std::string family((char *)nla_data(
|
||||
nl_group[CTRL_ATTR_MCAST_GRP_NAME]));
|
||||
LOG(DEBUG) << "Family:" << family << std::endl;
|
||||
if (family == THERMAL_GENL_EVENT_GROUP_NAME)
|
||||
event_group = nla_get_u32(
|
||||
nl_group[CTRL_ATTR_MCAST_GRP_ID]);
|
||||
|
||||
if (family == THERMAL_GENL_SAMPLING_GROUP_NAME)
|
||||
sample_group = nla_get_u32(
|
||||
nl_group[CTRL_ATTR_MCAST_GRP_ID]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ThermalMonitor::send_nl_msg(struct nl_msg *msg)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = nl_send_auto(event_soc, msg);
|
||||
if (ret < 0) {
|
||||
LOG(ERROR) << "Error sending NL message\n";
|
||||
return ret;
|
||||
}
|
||||
nl_socket_disable_seq_check(event_soc);
|
||||
nl_socket_modify_cb(event_soc, NL_CB_VALID, NL_CB_CUSTOM,
|
||||
thermal_family_cb, this);
|
||||
ret = nl_recvmsgs_default(event_soc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ThermalMonitor::fetch_group_id(void)
|
||||
{
|
||||
struct nl_msg *msg;
|
||||
int ctrlid, ret = 0;
|
||||
|
||||
msg = nlmsg_alloc();
|
||||
if (!msg)
|
||||
return -1;
|
||||
|
||||
ctrlid = genl_ctrl_resolve(event_soc, "nlctrl");
|
||||
genlmsg_put(msg, 0, 0, ctrlid, 0, 0, CTRL_CMD_GETFAMILY, 0);
|
||||
|
||||
nla_put_string(msg, CTRL_ATTR_FAMILY_NAME, THERMAL_GENL_FAMILY_NAME);
|
||||
send_nl_msg(msg);
|
||||
|
||||
nlmsg_free(msg);
|
||||
|
||||
if (event_group != -1 && sample_group != -1) {
|
||||
LOG(DEBUG) << "Netlink event: " << event_group <<
|
||||
" Sample:" << sample_group << std::endl;
|
||||
ret = nl_socket_add_membership(event_soc, event_group);
|
||||
if (ret) {
|
||||
LOG(ERROR) << "Netlink event Socket membership add error\n";
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = nl_socket_add_membership(sample_soc, sample_group);
|
||||
if (ret) {
|
||||
LOG(ERROR) << "Netlink sample Socket membership add error\n";
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ThermalMonitor::start()
|
||||
{
|
||||
struct nl_msg *msg;
|
||||
|
||||
event_soc = nl_socket_alloc();
|
||||
if (!event_soc) {
|
||||
LOG(ERROR) << "Netlink Event socket alloc failed\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if (genl_connect(event_soc)) {
|
||||
LOG(ERROR) << "Netlink Event socket connect failed\n";
|
||||
nl_socket_free(event_soc);
|
||||
event_soc = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
sample_soc = nl_socket_alloc();
|
||||
if (!sample_soc) {
|
||||
LOG(ERROR) << "Netlink Sample socket alloc failed\n";
|
||||
nl_socket_free(event_soc);
|
||||
event_soc = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (genl_connect(sample_soc)) {
|
||||
LOG(ERROR) << "Netlink Sample socket connect failed\n";
|
||||
nl_socket_free(sample_soc);
|
||||
nl_socket_free(event_soc);
|
||||
event_soc = nullptr;
|
||||
sample_soc = nullptr;
|
||||
return;
|
||||
}
|
||||
if (fetch_group_id())
|
||||
return;
|
||||
LOG(DEBUG) << "Netlink connection established.\n";
|
||||
nl_socket_disable_seq_check(sample_soc);
|
||||
nl_socket_modify_cb(sample_soc, NL_CB_VALID, NL_CB_CUSTOM,
|
||||
thermal_sample_cb, this);
|
||||
nl_socket_disable_seq_check(event_soc);
|
||||
nl_socket_modify_cb(event_soc, NL_CB_VALID, NL_CB_CUSTOM,
|
||||
thermal_event_cb, this);
|
||||
event_th = std::thread(thermal_listen, event_soc,
|
||||
std::bind(&ThermalMonitor::stopPolling, this));
|
||||
|
||||
sample_th = std::thread(thermal_listen, sample_soc,
|
||||
std::bind(&ThermalMonitor::stopPolling, this));
|
||||
}
|
||||
|
||||
} // namespace thermal
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
90
qcom/opensource/thermal-hal/thermalMonitorNetlink.h
Normal file
90
qcom/opensource/thermal-hal/thermalMonitorNetlink.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
|
||||
Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
|
||||
#ifndef THERMAL_THERMAL_MONITOR_NETLINK_H__
|
||||
#define THERMAL_THERMAL_MONITOR_NETLINK_H__
|
||||
|
||||
#include <thread>
|
||||
#include <netlink/genl/genl.h>
|
||||
#include <netlink/genl/mngt.h>
|
||||
#include <netlink/genl/ctrl.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <aidl/android/hardware/thermal/BnThermal.h>
|
||||
|
||||
namespace aidl{
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace thermal {
|
||||
|
||||
using eventMonitorCB = std::function<void(int, int)>;
|
||||
using eventCreateMonitorCB = std::function<void(int, const char *)>;
|
||||
|
||||
class ThermalMonitor {
|
||||
public:
|
||||
ThermalMonitor(const eventMonitorCB &inp_event_cb,
|
||||
const eventMonitorCB &inp_sample_cb,
|
||||
const eventCreateMonitorCB &inp_event_create_cb,
|
||||
const eventMonitorCB &inp_event_cdev_cb);
|
||||
~ThermalMonitor();
|
||||
|
||||
void parse_and_notify(char *inp_buf, ssize_t len);
|
||||
bool stopPolling()
|
||||
{
|
||||
return monitor_shutdown;
|
||||
}
|
||||
void start();
|
||||
int family_msg_cb(struct nl_msg *msg, void *data);
|
||||
int event_parse(struct nl_msg *n, void *data);
|
||||
int sample_parse(struct nl_msg *n, void *data);
|
||||
private:
|
||||
std::thread event_th, sample_th;
|
||||
struct nl_sock *event_soc, *sample_soc;
|
||||
int event_group, sample_group;
|
||||
bool monitor_shutdown;
|
||||
eventMonitorCB event_cb, sample_cb;
|
||||
eventCreateMonitorCB event_create_cb;
|
||||
eventMonitorCB cdev_cb;
|
||||
|
||||
int fetch_group_id();
|
||||
int send_nl_msg(struct nl_msg *msg);
|
||||
};
|
||||
|
||||
} // namespace thermal
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // THERMAL_THERMAL_MONITOR_NETLINK_H__
|
||||
232
qcom/opensource/thermal-hal/thermalUtils.cpp
Normal file
232
qcom/opensource/thermal-hal/thermalUtils.cpp
Normal file
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
|
||||
Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/properties.h>
|
||||
#include <android-base/stringprintf.h>
|
||||
#include <android-base/strings.h>
|
||||
|
||||
#include "thermalConfig.h"
|
||||
#include "thermalUtils.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace thermal {
|
||||
|
||||
ThermalUtils::ThermalUtils(const ueventCB &inp_cb):
|
||||
cfg(),
|
||||
cmnInst(),
|
||||
monitor(std::bind(&ThermalUtils::ueventParse, this,
|
||||
std::placeholders::_1,
|
||||
std::placeholders::_2)),
|
||||
cb(inp_cb)
|
||||
{
|
||||
int ret = 0;
|
||||
std::vector<struct therm_sensor> sensorList;
|
||||
std::vector<struct target_therm_cfg> therm_cfg = cfg.fetchConfig();
|
||||
|
||||
is_sensor_init = false;
|
||||
is_cdev_init = false;
|
||||
ret = cmnInst.initThermalZones(therm_cfg);
|
||||
if (ret > 0) {
|
||||
is_sensor_init = true;
|
||||
sensorList = cmnInst.fetch_sensor_list();
|
||||
std::lock_guard<std::mutex> _lock(sens_cb_mutex);
|
||||
for (struct therm_sensor sens: sensorList) {
|
||||
thermalConfig[sens.sensor_name] = sens;
|
||||
cmnInst.read_temperature(sens);
|
||||
cmnInst.estimateSeverity(sens);
|
||||
cmnInst.initThreshold(sens);
|
||||
}
|
||||
monitor.start();
|
||||
}
|
||||
ret = cmnInst.initCdev();
|
||||
if (ret > 0) {
|
||||
is_cdev_init = true;
|
||||
cdevList = cmnInst.fetch_cdev_list();
|
||||
}
|
||||
}
|
||||
|
||||
void ThermalUtils::Notify(struct therm_sensor& sens)
|
||||
{
|
||||
int severity = cmnInst.estimateSeverity(sens);
|
||||
if (severity != -1) {
|
||||
LOG(INFO) << "sensor: " << sens.sensor_name <<" temperature: "
|
||||
<< sens.t.value << " old: " <<
|
||||
(int)sens.lastThrottleStatus << " new: " <<
|
||||
(int)sens.t.throttlingStatus << std::endl;
|
||||
cb(sens.t);
|
||||
cmnInst.initThreshold(sens);
|
||||
}
|
||||
}
|
||||
|
||||
void ThermalUtils::ueventParse(std::string sensor_name, int temp)
|
||||
{
|
||||
LOG(DEBUG) << "uevent triggered for sensor: " << sensor_name
|
||||
<< std::endl;
|
||||
if (thermalConfig.find(sensor_name) == thermalConfig.end()) {
|
||||
LOG(DEBUG) << "sensor is not monitored:" << sensor_name
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
std::lock_guard<std::mutex> _lock(sens_cb_mutex);
|
||||
struct therm_sensor& sens = thermalConfig[sensor_name];
|
||||
sens.t.value = (float)temp / (float)sens.mulFactor;
|
||||
return Notify(sens);
|
||||
}
|
||||
|
||||
int ThermalUtils::readTemperatures(std::vector<Temperature>& temp)
|
||||
{
|
||||
std::unordered_map<std::string, struct therm_sensor>::iterator it;
|
||||
int ret = 0;
|
||||
std::vector<Temperature> _temp;
|
||||
|
||||
std::lock_guard<std::mutex> _lock(sens_cb_mutex);
|
||||
for (it = thermalConfig.begin(); it != thermalConfig.end(); it++) {
|
||||
struct therm_sensor& sens = it->second;
|
||||
|
||||
ret = cmnInst.read_temperature(sens);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
Notify(sens);
|
||||
_temp.push_back(sens.t);
|
||||
}
|
||||
|
||||
temp = _temp;
|
||||
return temp.size();
|
||||
}
|
||||
|
||||
int ThermalUtils::readTemperatures(TemperatureType type,
|
||||
std::vector<Temperature>& temp)
|
||||
{
|
||||
std::unordered_map<std::string, struct therm_sensor>::iterator it;
|
||||
int ret = 0;
|
||||
std::vector<Temperature> _temp;
|
||||
|
||||
std::lock_guard<std::mutex> _lock(sens_cb_mutex);
|
||||
for (it = thermalConfig.begin(); it != thermalConfig.end(); it++) {
|
||||
struct therm_sensor& sens = it->second;
|
||||
|
||||
if (sens.t.type != type)
|
||||
continue;
|
||||
ret = cmnInst.read_temperature(sens);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
Notify(sens);
|
||||
_temp.push_back(sens.t);
|
||||
}
|
||||
|
||||
temp = _temp;
|
||||
return temp.size();
|
||||
}
|
||||
|
||||
int ThermalUtils::readTemperatureThreshold(std::vector<TemperatureThreshold>& thresh)
|
||||
{
|
||||
std::unordered_map<std::string, struct therm_sensor>::iterator it;
|
||||
std::vector<TemperatureThreshold> _thresh;
|
||||
|
||||
for (it = thermalConfig.begin(); it != thermalConfig.end(); it++) {
|
||||
struct therm_sensor& sens = it->second;
|
||||
|
||||
_thresh.push_back(sens.thresh);
|
||||
}
|
||||
|
||||
thresh = _thresh;
|
||||
return thresh.size();
|
||||
}
|
||||
|
||||
int ThermalUtils::readTemperatureThreshold(TemperatureType type,
|
||||
std::vector<TemperatureThreshold>& thresh)
|
||||
{
|
||||
std::unordered_map<std::string, struct therm_sensor>::iterator it;
|
||||
std::vector<TemperatureThreshold> _thresh;
|
||||
|
||||
for (it = thermalConfig.begin(); it != thermalConfig.end(); it++) {
|
||||
struct therm_sensor& sens = it->second;
|
||||
|
||||
if (sens.t.type != type)
|
||||
continue;
|
||||
_thresh.push_back(sens.thresh);
|
||||
}
|
||||
|
||||
thresh = _thresh;
|
||||
return thresh.size();
|
||||
}
|
||||
|
||||
int ThermalUtils::readCdevStates(std::vector<CoolingDevice>& cdev_out)
|
||||
{
|
||||
int ret = 0;
|
||||
std::vector<CoolingDevice> _cdev;
|
||||
|
||||
for (struct therm_cdev cdev: cdevList) {
|
||||
|
||||
ret = cmnInst.read_cdev_state(cdev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
_cdev.push_back(cdev.c);
|
||||
}
|
||||
|
||||
cdev_out = _cdev;
|
||||
|
||||
return cdev_out.size();
|
||||
}
|
||||
|
||||
int ThermalUtils::readCdevStates(cdevType type,
|
||||
std::vector<CoolingDevice>& cdev_out)
|
||||
{
|
||||
int ret = 0;
|
||||
std::vector<CoolingDevice> _cdev;
|
||||
|
||||
for (struct therm_cdev cdev: cdevList) {
|
||||
|
||||
if (cdev.c.type != type)
|
||||
continue;
|
||||
ret = cmnInst.read_cdev_state(cdev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
_cdev.push_back(cdev.c);
|
||||
}
|
||||
|
||||
cdev_out = _cdev;
|
||||
|
||||
return cdev_out.size();
|
||||
}
|
||||
|
||||
} // namespace thermal
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
97
qcom/opensource/thermal-hal/thermalUtils.h
Normal file
97
qcom/opensource/thermal-hal/thermalUtils.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
|
||||
Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
|
||||
#ifndef THERMAL_THERMAL_UTILS_H__
|
||||
#define THERMAL_THERMAL_UTILS_H__
|
||||
|
||||
#include <unordered_map>
|
||||
#include <mutex>
|
||||
#include <aidl/android/hardware/thermal/BnThermal.h>
|
||||
|
||||
#include "thermalConfig.h"
|
||||
#include "thermalMonitor.h"
|
||||
#include "thermalCommon.h"
|
||||
#include "thermalData.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace thermal {
|
||||
|
||||
using ueventCB = std::function<void(Temperature &t)>;
|
||||
|
||||
class ThermalUtils {
|
||||
public:
|
||||
ThermalUtils(const ueventCB &inp_cb);
|
||||
~ThermalUtils() = default;
|
||||
bool isSensorInitialized()
|
||||
{
|
||||
return is_sensor_init;
|
||||
};
|
||||
bool isCdevInitialized()
|
||||
{
|
||||
return is_cdev_init;
|
||||
};
|
||||
int readTemperatures(std::vector<Temperature>& temp);
|
||||
int readTemperatures(TemperatureType type,
|
||||
std::vector<Temperature>& temperatures);
|
||||
int readTemperatureThreshold(std::vector<TemperatureThreshold>& thresh);
|
||||
int readTemperatureThreshold(TemperatureType type,
|
||||
std::vector<TemperatureThreshold>& thresh);
|
||||
int readCdevStates(std::vector<CoolingDevice>& cdev);
|
||||
int readCdevStates(cdevType type,
|
||||
std::vector<CoolingDevice>& cdev);
|
||||
private:
|
||||
bool is_sensor_init;
|
||||
bool is_cdev_init;
|
||||
ThermalConfig cfg;
|
||||
ThermalCommon cmnInst;
|
||||
ThermalMonitor monitor;
|
||||
std::unordered_map<std::string, struct therm_sensor>
|
||||
thermalConfig;
|
||||
std::vector<struct therm_cdev> cdevList;
|
||||
std::mutex sens_cb_mutex;
|
||||
ueventCB cb;
|
||||
|
||||
void ueventParse(std::string sensor_name, int temp);
|
||||
void Notify(struct therm_sensor& sens);
|
||||
};
|
||||
|
||||
} // namespace thermal
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // THERMAL_THERMAL_UTILS_H__
|
||||
326
qcom/opensource/thermal-hal/thermalUtilsNetlink.cpp
Normal file
326
qcom/opensource/thermal-hal/thermalUtilsNetlink.cpp
Normal file
@@ -0,0 +1,326 @@
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
|
||||
Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/properties.h>
|
||||
#include <android-base/stringprintf.h>
|
||||
#include <android-base/strings.h>
|
||||
|
||||
#include "thermalConfig.h"
|
||||
#include "thermalUtilsNetlink.h"
|
||||
#include "thermalCommon.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace thermal {
|
||||
|
||||
ThermalUtils::ThermalUtils(const ueventCB &inp_cb, const notifyCB &inp_cdev_cb):
|
||||
cfg(),
|
||||
cmnInst(),
|
||||
monitor(std::bind(&ThermalUtils::eventParse, this,
|
||||
std::placeholders::_1,
|
||||
std::placeholders::_2),
|
||||
std::bind(&ThermalUtils::sampleParse, this,
|
||||
std::placeholders::_1,
|
||||
std::placeholders::_2),
|
||||
std::bind(&ThermalUtils::eventCreateParse, this,
|
||||
std::placeholders::_1,
|
||||
std::placeholders::_2),
|
||||
std::bind(&ThermalUtils::cdevEventParse, this,
|
||||
std::placeholders::_1,
|
||||
std::placeholders::_2)),
|
||||
cb(inp_cb),
|
||||
notify(inp_cdev_cb)
|
||||
{
|
||||
int ret = 0;
|
||||
std::vector<struct therm_sensor> sensorList;
|
||||
std::vector<struct target_therm_cfg> therm_cfg = cfg.fetchConfig();
|
||||
|
||||
is_sensor_init = false;
|
||||
is_cdev_init = false;
|
||||
ret = cmnInst.initThermalZones(therm_cfg);
|
||||
if (ret > 0) {
|
||||
is_sensor_init = true;
|
||||
sensorList = cmnInst.fetch_sensor_list();
|
||||
std::lock_guard<std::mutex> _lock(sens_cb_mutex);
|
||||
for (struct therm_sensor sens: sensorList) {
|
||||
thermalConfig[sens.tzn] = sens;
|
||||
cmnInst.read_temperature(sens);
|
||||
cmnInst.estimateSeverity(sens);
|
||||
if (!sens.no_trip_set)
|
||||
cmnInst.initThreshold(sens);
|
||||
}
|
||||
}
|
||||
monitor.start();
|
||||
ret = cmnInst.initCdev();
|
||||
if (ret > 0) {
|
||||
is_cdev_init = true;
|
||||
cdevList = cmnInst.fetch_cdev_list();
|
||||
std::lock_guard<std::mutex> _lock(cdev_cb_mutex);
|
||||
for (struct therm_cdev cdevs: cdevList) {
|
||||
cmnInst.read_cdev_state(cdevs);
|
||||
cdev[cdevs.cdevn] = cdevs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ThermalUtils::Notify(struct therm_sensor& sens)
|
||||
{
|
||||
int severity = cmnInst.estimateSeverity(sens);
|
||||
if (severity != -1) {
|
||||
LOG(INFO) << "sensor: " << sens.sensor_name <<" temperature: "
|
||||
<< sens.t.value << " old: " <<
|
||||
(int)sens.lastThrottleStatus << " new: " <<
|
||||
(int)sens.t.throttlingStatus << std::endl;
|
||||
cb(sens.t);
|
||||
if (!sens.no_trip_set)
|
||||
cmnInst.initThreshold(sens);
|
||||
}
|
||||
}
|
||||
|
||||
void ThermalUtils::cdevNotify(struct therm_cdev& cdev, int state)
|
||||
{
|
||||
|
||||
if (state > -1) {
|
||||
cdev.c.value = state;
|
||||
|
||||
notify(cdev.c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ThermalUtils::cdevEventParse(int cdevn, int state)
|
||||
{
|
||||
if (cdev.find(cdevn) == cdev.end()) {
|
||||
LOG(DEBUG) << "cdev is not supported:" << cdevn
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
std::lock_guard<std::mutex> _lock(cdev_cb_mutex);
|
||||
struct therm_cdev& cdevs = cdev[cdevn];
|
||||
return cdevNotify(cdevs, state);
|
||||
}
|
||||
|
||||
void ThermalUtils::eventParse(int tzn, int trip)
|
||||
{
|
||||
if (trip != 1)
|
||||
return;
|
||||
if (thermalConfig.find(tzn) == thermalConfig.end()) {
|
||||
LOG(DEBUG) << "sensor is not monitored:" << tzn
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
std::lock_guard<std::mutex> _lock(sens_cb_mutex);
|
||||
struct therm_sensor& sens = thermalConfig[tzn];
|
||||
return Notify(sens);
|
||||
}
|
||||
|
||||
void ThermalUtils::sampleParse(int tzn, int temp)
|
||||
{
|
||||
if (thermalConfig.find(tzn) == thermalConfig.end()) {
|
||||
LOG(DEBUG) << "sensor is not monitored:" << tzn
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
std::lock_guard<std::mutex> _lock(sens_cb_mutex);
|
||||
struct therm_sensor& sens = thermalConfig[tzn];
|
||||
sens.t.value = (float)temp / (float)sens.mulFactor;
|
||||
return Notify(sens);
|
||||
}
|
||||
|
||||
void ThermalUtils::eventCreateParse(int tzn, const char *name)
|
||||
{
|
||||
int ret = 0;
|
||||
std::vector<struct therm_sensor> sensorList;
|
||||
std::vector<struct target_therm_cfg> therm_cfg = cfg.fetchConfig();
|
||||
std::vector<struct target_therm_cfg>::iterator it_vec;
|
||||
std::vector<std::string>::iterator it;
|
||||
|
||||
if (isSensorInitialized())
|
||||
return;
|
||||
for (it_vec = therm_cfg.begin();
|
||||
it_vec != therm_cfg.end(); it_vec++) {
|
||||
for (it = it_vec->sensor_list.begin();
|
||||
it != it_vec->sensor_list.end(); it++) {
|
||||
if (!it->compare(name))
|
||||
break;
|
||||
}
|
||||
if (it != it_vec->sensor_list.end())
|
||||
break;
|
||||
}
|
||||
if (it_vec == therm_cfg.end()) {
|
||||
LOG(DEBUG) << "sensor is not monitored:" << tzn
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
ret = cmnInst.initThermalZones(therm_cfg);
|
||||
if (ret > 0) {
|
||||
is_sensor_init = true;
|
||||
sensorList = cmnInst.fetch_sensor_list();
|
||||
std::lock_guard<std::mutex> _lock(sens_cb_mutex);
|
||||
for (struct therm_sensor sens: sensorList) {
|
||||
thermalConfig[sens.tzn] = sens;
|
||||
cmnInst.read_temperature(sens);
|
||||
cmnInst.estimateSeverity(sens);
|
||||
if (!sens.no_trip_set)
|
||||
cmnInst.initThreshold(sens);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ThermalUtils::readTemperatures(std::vector<Temperature>& temp)
|
||||
{
|
||||
std::unordered_map<int, struct therm_sensor>::iterator it;
|
||||
int ret = 0;
|
||||
std::vector<Temperature> _temp;
|
||||
|
||||
std::lock_guard<std::mutex> _lock(sens_cb_mutex);
|
||||
for (it = thermalConfig.begin(); it != thermalConfig.end(); it++) {
|
||||
struct therm_sensor& sens = it->second;
|
||||
|
||||
ret = cmnInst.read_temperature(sens);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
Notify(sens);
|
||||
_temp.push_back(sens.t);
|
||||
}
|
||||
|
||||
temp = _temp;
|
||||
return temp.size();
|
||||
}
|
||||
|
||||
int ThermalUtils::readTemperatures(TemperatureType type,
|
||||
std::vector<Temperature>& temp)
|
||||
{
|
||||
std::unordered_map<int, struct therm_sensor>::iterator it;
|
||||
int ret = 0;
|
||||
std::vector<Temperature> _temp;
|
||||
|
||||
std::lock_guard<std::mutex> _lock(sens_cb_mutex);
|
||||
for (it = thermalConfig.begin(); it != thermalConfig.end(); it++) {
|
||||
struct therm_sensor& sens = it->second;
|
||||
|
||||
if (sens.t.type != type)
|
||||
continue;
|
||||
ret = cmnInst.read_temperature(sens);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
Notify(sens);
|
||||
_temp.push_back(sens.t);
|
||||
}
|
||||
|
||||
temp = _temp;
|
||||
return temp.size();
|
||||
}
|
||||
|
||||
int ThermalUtils::readTemperatureThreshold(std::vector<TemperatureThreshold>& thresh)
|
||||
{
|
||||
std::unordered_map<int, struct therm_sensor>::iterator it;
|
||||
std::vector<TemperatureThreshold> _thresh;
|
||||
|
||||
for (it = thermalConfig.begin(); it != thermalConfig.end(); it++) {
|
||||
struct therm_sensor& sens = it->second;
|
||||
|
||||
_thresh.push_back(sens.thresh);
|
||||
}
|
||||
|
||||
thresh = _thresh;
|
||||
return thresh.size();
|
||||
}
|
||||
|
||||
int ThermalUtils::readTemperatureThreshold(TemperatureType type,
|
||||
std::vector<TemperatureThreshold>& thresh)
|
||||
{
|
||||
std::unordered_map<int, struct therm_sensor>::iterator it;
|
||||
std::vector<TemperatureThreshold> _thresh;
|
||||
|
||||
for (it = thermalConfig.begin(); it != thermalConfig.end(); it++) {
|
||||
struct therm_sensor& sens = it->second;
|
||||
|
||||
if (sens.t.type != type)
|
||||
continue;
|
||||
_thresh.push_back(sens.thresh);
|
||||
}
|
||||
|
||||
thresh = _thresh;
|
||||
return thresh.size();
|
||||
}
|
||||
|
||||
int ThermalUtils::readCdevStates(std::vector<CoolingDevice>& cdev_out)
|
||||
{
|
||||
int ret = 0;
|
||||
std::vector<CoolingDevice> _cdev;
|
||||
|
||||
for (struct therm_cdev cdev: cdevList) {
|
||||
|
||||
ret = cmnInst.read_cdev_state(cdev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
_cdev.push_back(cdev.c);
|
||||
}
|
||||
|
||||
cdev_out = _cdev;
|
||||
|
||||
return cdev_out.size();
|
||||
}
|
||||
|
||||
int ThermalUtils::readCdevStates(cdevType type,
|
||||
std::vector<CoolingDevice>& cdev_out)
|
||||
{
|
||||
int ret = 0;
|
||||
std::vector<CoolingDevice> _cdev;
|
||||
|
||||
for (struct therm_cdev cdev: cdevList) {
|
||||
|
||||
if (cdev.c.type != type)
|
||||
continue;
|
||||
ret = cmnInst.read_cdev_state(cdev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
_cdev.push_back(cdev.c);
|
||||
}
|
||||
|
||||
cdev_out = _cdev;
|
||||
|
||||
return cdev_out.size();
|
||||
}
|
||||
|
||||
} // namespace thermal
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
106
qcom/opensource/thermal-hal/thermalUtilsNetlink.h
Normal file
106
qcom/opensource/thermal-hal/thermalUtilsNetlink.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Changes from Qualcomm Innovation Center are provided under the following license:
|
||||
|
||||
Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
|
||||
#ifndef THERMAL_THERMAL_UTILS_H__
|
||||
#define THERMAL_THERMAL_UTILS_H__
|
||||
|
||||
#include <unordered_map>
|
||||
#include <mutex>
|
||||
#include <aidl/android/hardware/thermal/BnThermal.h>
|
||||
#include "thermalConfig.h"
|
||||
#include "thermalMonitorNetlink.h"
|
||||
#include "thermalCommon.h"
|
||||
#include "thermalData.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace thermal {
|
||||
|
||||
using ueventCB = std::function<void(Temperature &t)>;
|
||||
using notifyCB = std::function<void(CoolingDevice &c)>;
|
||||
|
||||
class ThermalUtils {
|
||||
public:
|
||||
ThermalUtils(const ueventCB &inp_cb, const notifyCB &inp_cdev_cb);
|
||||
~ThermalUtils() = default;
|
||||
bool isSensorInitialized()
|
||||
{
|
||||
return is_sensor_init;
|
||||
};
|
||||
bool isCdevInitialized()
|
||||
{
|
||||
return is_cdev_init;
|
||||
};
|
||||
int readTemperatures(std::vector<Temperature>& temp);
|
||||
int readTemperatures(TemperatureType type,
|
||||
std::vector<Temperature>& temperatures);
|
||||
int readTemperatureThreshold(std::vector<TemperatureThreshold>& thresh);
|
||||
int readTemperatureThreshold(TemperatureType type,
|
||||
std::vector<TemperatureThreshold>& thresh);
|
||||
int readCdevStates(std::vector<CoolingDevice>& cdev);
|
||||
int readCdevStates(cdevType type,
|
||||
std::vector<CoolingDevice>& cdev);
|
||||
private:
|
||||
bool is_sensor_init;
|
||||
bool is_cdev_init;
|
||||
ThermalConfig cfg;
|
||||
ThermalCommon cmnInst;
|
||||
ThermalMonitor monitor;
|
||||
std::unordered_map<int, struct therm_sensor>
|
||||
thermalConfig;
|
||||
std::unordered_map<int, struct therm_cdev>
|
||||
cdev;
|
||||
std::vector<struct therm_cdev> cdevList;
|
||||
std::mutex sens_cb_mutex;
|
||||
std::mutex cdev_cb_mutex;
|
||||
ueventCB cb;
|
||||
notifyCB notify;
|
||||
|
||||
void eventParse(int tzn, int trip);
|
||||
void sampleParse(int tzn, int temp);
|
||||
void eventCreateParse(int tzn, const char *name);
|
||||
void Notify(struct therm_sensor& sens);
|
||||
void cdevNotify(struct therm_cdev& cdev, int state);
|
||||
void cdevEventParse(int cdevn, int state);
|
||||
};
|
||||
|
||||
} // namespace thermal
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
||||
#endif // THERMAL_THERMAL_UTILS_H__
|
||||
Reference in New Issue
Block a user