qca-thermald-10.4: drop legacy package

Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
John Crispin
2022-05-12 14:32:54 +02:00
parent c804333bc0
commit f162000749
62 changed files with 0 additions and 13431 deletions

View File

@@ -1,44 +0,0 @@
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=qca-thermald-10.4
PKG_RELEASE:=1
QCA_THERMALD_MAKE_OPTS:= \
CROSS=$(TARGET_CROSS) \
THERMALDIR=$(PKG_BUILD_DIR) \
include $(INCLUDE_DIR)/package.mk
define Package/qca-thermald-10.4
SECTION:=utils
CATEGORY:=Utilities
URL:=http://www.qca.qualcomm.com
MAINTAINER:=Qualcomm Atheros
DEPENDS:=+libpthread @TARGET_ipq807x
TITLE:=Thermal Mitigation daemon
endef
define Package/qca-thermald-10.4/description
This package is IPQ Thermal Mitigation daemon.
endef
define Build/Compile
LDFLAGS="$(TARGET_LDFLAGS)" \
$(MAKE) -C $(PKG_BUILD_DIR) $(strip $(QCA_THERMALD_MAKE_OPTS))
endef
define Package/qca-thermald-10.4/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/install/usr/sbin/thermald $(1)/usr/sbin
$(INSTALL_DIR) $(1)/etc/thermal
$(INSTALL_BIN) $(PKG_BUILD_DIR)/install/etc/thermal/ipq-thermald-8064.conf $(1)/etc/thermal
$(INSTALL_BIN) $(PKG_BUILD_DIR)/install/etc/thermal/ipq-thermald-8066.conf $(1)/etc/thermal
$(INSTALL_BIN) $(PKG_BUILD_DIR)/install/etc/thermal/ipq-thermald-8069.conf $(1)/etc/thermal
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/thermal.init $(1)/etc/init.d/thermal
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_BIN) ./files/thermal.config $(1)/etc/config/thermal
endef
$(eval $(call BuildPackage,qca-thermald-10.4))

View File

@@ -1,2 +0,0 @@
config thermal config
option Enabled '1'

View File

@@ -1,23 +0,0 @@
#!/bin/sh /etc/rc.common
START=98
SERVICE_WRITE_PID=1
SERVICE_DAEMONIZE=1
start() {
. /lib/functions.sh
local enabled
config_load 'thermal'
config_get_bool enabled config 'Enabled' '0'
[ "$enabled" -gt 0 ] || return 1
service_start /usr/sbin/thermald
}
stop() {
service_stop /usr/sbin/thermald
}

View File

@@ -1,236 +0,0 @@
BOARD_PLATFORM_LIST := msm7630_surf
BOARD_PLATFORM_LIST += msm7630_fusion
BOARD_PLATFORM_LIST += msm8660
BOARD_PLATFORM_LIST += msm8960
BOARD_PLATFORM_LIST += msm7627a
BOARD_PLATFORM_LIST += msm8974
ifeq ($(call is-board-platform-in-list,$(BOARD_PLATFORM_LIST)),true)
IS_MSM7630:=$(strip $(call is-chipset-in-board-platform,msm7630))
IS_MSM8660:=$(strip $(call is-board-platform,msm8660))
IS_MSM8960:=$(strip $(call is-board-platform,msm8960))
IS_MSM8625:=$(strip $(call is-board-platform,msm7627a))
IS_MSM8974:=$(strip $(call is-board-platform,msm8974))
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(QC_PROP_ROOT)/common/build/remote_api_makefiles/target_api_enables.mk
include $(QC_PROP_ROOT)/common/build/remote_api_makefiles/remote_api_defines.mk
LOCAL_C_INCLUDES := \
$(TARGET_OUT_HEADERS)/common/inc \
$(TARGET_OUT_HEADERS)/oncrpc/inc \
$(TARGET_OUT_HEADERS)/diag/include \
$(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include/
LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
LOCAL_SRC_FILES := \
thermal.c \
thermal_config.c \
thermal_monitor.c \
thermal_actions.c \
thermal_util.c \
thermal_server.c \
thermal_lib_common.c
LOCAL_SHARED_LIBRARIES := \
libcutils
LOCAL_CFLAGS := -DCONFIG_FILE_DEFAULT='"/system/etc/thermald.conf"'
LOCAL_CFLAGS += -include bionic/libc/kernel/arch-arm/asm/posix_types.h
ifneq ($(call is-platform-sdk-version-at-least,17),true)
# Override socket-related kernel headers with Bionic version before JB MR1
LOCAL_CFLAGS += -include bionic/libc/kernel/arch-arm/asm/byteorder.h
LOCAL_CFLAGS += -include bionic/libc/kernel/common/linux/posix_types.h
LOCAL_CFLAGS += -include bionic/libc/kernel/common/linux/types.h
LOCAL_CFLAGS += -include bionic/libc/kernel/common/linux/socket.h
LOCAL_CFLAGS += -include bionic/libc/kernel/common/linux/in.h
LOCAL_CFLAGS += -include bionic/libc/kernel/common/linux/netlink.h
LOCAL_CFLAGS += -include bionic/libc/kernel/common/linux/un.h
endif
ifneq ($(IS_MSM8625),)
LOCAL_SRC_FILES += sensors-8x25.c
LOCAL_CFLAGS += -DSENSORS_8625
ifeq ($(ADC_ENABLE),1)
LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/adc/inc
LOCAL_SHARED_LIBRARIES += libadc liboncrpc
endif
endif
ifneq ($(IS_MSM7630),)
LOCAL_SRC_FILES += sensors-7x30.c
LOCAL_CFLAGS += -DSENSORS_7630
THERMALD_CONF := thermald-7x30.conf
endif
ifneq ($(IS_MSM8660),)
LOCAL_SRC_FILES += tsens-sensor.c sensors-8660.c
LOCAL_CFLAGS += -DSENSORS_8660
LOCAL_CFLAGS += -DENABLE_TSENS_INTERRUPT
ENABLE_MODEM_MITIGATION_ONCRPC:=1
ENABLE_FUSION_MODEM:=1
THERMALD_CONF := thermald-8660.conf
endif
ifneq ($(IS_MSM8960),)
LOCAL_SRC_FILES += tsens-sensor.c adc-sensor.c sensors-8960.c gen-sensor.c bcl-sensor.c pm8821-sensor.c
LOCAL_CFLAGS += -DSENSORS_8960
LOCAL_CFLAGS += -DENABLE_TSENS_INTERRUPT
ENABLE_MODEM_MITIGATION_QMI:=1
ENABLE_MODEM_TS_QMI:=1
endif
ifneq ($(IS_MSM8974),)
LOCAL_SRC_FILES += tsens-sensor.c adc-sensor.c sensors-8974.c gen-sensor.c bcl-sensor.c
LOCAL_CFLAGS += -DSENSORS_8974
#ENABLE_MODEM_MITIGATION_QMI:=1
endif
ifneq ($(ENABLE_MODEM_MITIGATION_ONCRPC),)
LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/thermal_mitigation/inc
LOCAL_CFLAGS += -DENABLE_MODEM_MITIGATION
LOCAL_SRC_FILES += modem_mitigation_oncrpc.c
LOCAL_SHARED_LIBRARIES += liboncrpc
LOCAL_SHARED_LIBRARIES += libthermal_mitigation
ifneq ($(ENABLE_FUSION_MODEM),)
LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/thermal_mitigation_fusion/inc
LOCAL_CFLAGS += -DENABLE_FUSION_MODEM
LOCAL_SHARED_LIBRARIES += libthermal_mitigation_fusion
endif
endif
ifneq ($(ENABLE_MODEM_MITIGATION_QMI),)
LOCAL_CFLAGS += -DENABLE_MODEM_MITIGATION
LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qmi-framework/inc
LOCAL_SRC_FILES += modem_mitigation_qmi.c
LOCAL_SRC_FILES += thermal_mitigation_device_service_v01.c
LOCAL_SHARED_LIBRARIES += libqmi_cci libqmi_common_so
endif
ifneq ($(ENABLE_MODEM_TS_QMI),)
LOCAL_CFLAGS += -DENABLE_MODEM_TS
LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qmi-framework/inc
LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qmi/inc
LOCAL_SRC_FILES += modem_sensor_qmi.c qmi-ts-sensor.c
LOCAL_SRC_FILES += thermal_sensor_service_v01.c
LOCAL_SHARED_LIBRARIES += libqmi_cci libqmi_common_so
endif
LOCAL_CFLAGS += \
-DUSE_ANDROID_LOG \
LOCAL_MODULE := thermald
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)
#Install thermal client library
#include $(CLEAR_VARS)
#LOCAL_C_INCLUDES := \
$(TARGET_OUT_HEADERS)/common/inc \
$(TARGET_OUT_HEADERS)/diag/include
#LOCAL_SHARED_LIBRARIES := libcutils \
libdiag
#LOCAL_SRC_FILES:= thermal_client.c thermal_lib_common.c
#LOCAL_MODULE:= libthermalclient
#LOCAL_MODULE_TAGS := optional
#LOCAL_CFLAGS = \
-DUSE_ANDROID_LOG
#LOCAL_MODULE_OWNER := qcom
#LOCAL_PROPRIETARY_MODULE := true
#include $(BUILD_SHARED_LIBRARY)
# Install thermal configuration
ifneq ($(IS_MSM8974),)
include $(CLEAR_VARS)
LOCAL_MODULE := thermald-8974.conf
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_SRC_FILES := thermald-8974.conf
include $(BUILD_PREBUILT)
else ifneq ($(IS_MSM8960),)
include $(CLEAR_VARS)
LOCAL_MODULE := thermald-8960.conf
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_SRC_FILES := thermald-8960.conf
include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
LOCAL_MODULE := thermald-8064.conf
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_SRC_FILES := thermald-8064.conf
include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
LOCAL_MODULE := thermald-8930.conf
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_SRC_FILES := thermald-8930.conf
include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
LOCAL_MODULE := thermald-8960ab.conf
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_SRC_FILES := thermald-8960ab.conf
include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
LOCAL_MODULE := thermald-8064ab.conf
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_SRC_FILES := thermald-8064ab.conf
include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
LOCAL_MODULE := thermald-8930ab.conf
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_SRC_FILES := thermald-8930ab.conf
include $(BUILD_PREBUILT)
else ifneq ($(IS_MSM8625),)
include $(CLEAR_VARS)
LOCAL_MODULE := thermald-8x25-msm1-pmic_therm.conf
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_SRC_FILES := thermald-8x25-msm1-pmic_therm.conf
include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
LOCAL_MODULE := thermald-8x25-msm2-pmic_therm.conf
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_SRC_FILES := thermald-8x25-msm2-pmic_therm.conf
include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
LOCAL_MODULE := thermald-8x25-msm2-msm_therm.conf
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_SRC_FILES := thermald-8x25-msm2-msm_therm.conf
include $(BUILD_PREBUILT)
else
include $(CLEAR_VARS)
LOCAL_MODULE := thermald.conf
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_SRC_FILES := $(THERMALD_CONF)
include $(BUILD_PREBUILT)
endif
endif

View File

@@ -1,74 +0,0 @@
#****************************************************************************
#
# Copyright (c) 2014 Qualcomm Atheros, Inc.
# All Rights Reserved.
# Qualcomm Atheros Confidential and Proprietary.
#
#****************************************************************************/
ifneq ($(strip $(TOOLPREFIX)),)
export CROSS:=$(TOOLPREFIX)
endif
THERMALD_INSTALL_ROOT := $(THERMALDIR)/install
ifndef INSTALL_ROOT
INSTALL_ROOT=$(THERMALD_INSTALL_ROOT)
endif
export CC = $(CROSS)gcc
export CFLAGS += -O2 -Wall -DIPQ_806x -c
export STRIP = $(CROSS)strip
export SOURCES= \
thermal.c \
thermal_config.c \
thermal_util.c \
thermal_monitor.c \
thermal_actions.c \
sensors-ipq.c \
tsens-sensor.c
export OBJECTS=$(SOURCES:.c=.o)
export EXECUTABLE=thermald
LIBS += -lpthread -ldl
CFLAGS += -L$(INSTALL_ROOT)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) \
-fstack-protector-all -fpie
LDFLAGS += $(TARGET_LDFLAGS) -pie
# What we build by default:
ALL = $(EXECUTABLE)
# RULES ---------------------------------------------------------------
# Making default targets:
all: local install
@echo All done in `pwd`
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LIB_PATH) $(LIBS) $(LDFLAGS) $(OBJECTS) -o $@
@echo Build $@ successufully...
.c.o:
$(CC) $(INCLUDE) $(CFLAGS) $(LDFLAGS) $< -o $@
clean:
rm -rf *.o *.d $(EXECUTABLE)
local: $(SOURCES) $(EXECUTABLE)
@echo Build $@ successufully...
# Doing installation (see comments at top of this file)
install: local
mkdir -p $(INSTALL_ROOT)/usr/sbin/
cp -a -f $(ALL) $(INSTALL_ROOT)/usr/sbin/
mkdir -p $(INSTALL_ROOT)/etc/thermal
cp -a -f ipq-thermald-806?.conf $(INSTALL_ROOT)/etc/thermal/
@echo Installed outputs from `pwd`
# Remove all generated files
#clean: default_clean # from Makefile.rules
clean:
rm -rf install/usr/sbin/thermal
rm -rf ./$(ALL)
# END --------------------------------------------------------------------

View File

@@ -1,35 +0,0 @@
AM_CFLAGS = -Wall \
-Wundef \
-Wstrict-prototypes \
-Wno-trigraphs \
-Werror
AM_CPPFLAGS = -DENABLE_TSENS_INTERRUPT \
-DENABLE_MODEM_MITIGATION \
-DSENSORS_8960 \
-DCONFIG_FILE_DEFAULT='"/etc/thermald.conf"' \
$(QMIF_CFLAGS)
thermald_SOURCES = \
thermal.c \
thermal_config.c \
thermal_monitor.c \
thermal_actions.c \
thermal_util.c \
adc-sensor.c \
tsens-sensor.c \
sensors-8960.c \
modem_mitigation_qmi.c \
thermal_mitigation_device_service_v01.c
if USE_GLIB
thermald_CFLAGS = $(AM_CFLAGS) -DUSE_GLIB @GLIB_CFLAGS@
thermald_LDFLAGS = -lpthread -lrt @GLIB_LIBS@ $(QMIF_LIBS)
else
thermald_LDFLAGS = -lpthread -lrt $(QMIF_LIBS)
endif
bin_PROGRAMS = thermald
sysconf_DATA = thermald-9x15.conf
install-data-hook:
mv $(DESTDIR)$(sysconfdir)/$(sysconf_DATA) $(DESTDIR)$(sysconfdir)/thermald.conf

View File

@@ -1,119 +0,0 @@
/*===========================================================================
adc-sensor.c
DESCRIPTION
ADC sensor access functions.
INITIALIZATION AND SEQUENCING REQUIREMENTS
setup() function should be called before get_temperature().
shutdown() function should be called to clean up resources.
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <pthread.h>
#include <poll.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "thermal.h"
#define MSM_ADC_NODE_PM8921 "/sys/devices/platform/msm_ssbi.0/pm8921-core/pm8xxx-adc/%s"
#define MSM_ADC_NODE_PM8038 "/sys/devices/platform/msm_ssbi.0/pm8038-core/pm8xxx-adc/%s"
#define MSM_PM8921 "/sys/devices/platform/msm_ssbi.0/pm8921-core"
#define MSM_PM8038 "/sys/devices/platform/msm_ssbi.0/pm8038-core"
#define LVL_BUF_MAX (12)
static char *get_adc_sysfs()
{
struct stat filestat;
int msm_id = therm_get_msm_id();
switch (msm_id) {
case THERM_MSM_8960AB:
case THERM_MSM_8960:
case THERM_MSM_8064AB:
case THERM_MSM_8064:
return MSM_ADC_NODE_PM8921;
case THERM_MSM_8930AB:
case THERM_MSM_8930AA:
case THERM_MSM_8930:
if (stat(MSM_PM8038, &filestat) > -1)
return MSM_ADC_NODE_PM8038;
else if(stat(MSM_PM8921, &filestat) > -1)
return MSM_ADC_NODE_PM8921;
else
return NULL;
default:
dbgmsg("%s: ADC sensors unsupported on target %d",
__func__, msm_id);
return NULL;
}
}
int adc_sensors_setup(sensor_setting_t *setting, sensor_t *sensor)
{
int fd = -1;
int sensor_count = 0;
char name[MAX_PATH] = {0};
char *adc_sysfs = NULL;
/* We have nothing to do if there are no thresholds */
if (!setting->num_thresholds) {
dbgmsg("No thresholds for sensor %s\n", sensor->name);
return sensor_count;
}
adc_sysfs = get_adc_sysfs();
if (adc_sysfs == NULL) {
return sensor_count;
}
snprintf(name, MAX_PATH, adc_sysfs, sensor->name);
fd = open(name, O_RDONLY);
if (fd < 0) {
msg("%s: Error opening %s\n", __func__, name);
return sensor_count;
}
sensor_count++;
setting->disabled = 0;
setting->chan_idx = fd;
return sensor_count;
}
void adc_sensors_shutdown(sensor_setting_t *setting)
{
if (NULL == setting ||
NULL == setting->sensor) {
msg("%s: unexpected NULL", __func__);
return;
}
if (setting->chan_idx > 0)
close(setting->chan_idx);
}
int adc_sensor_get_temperature(sensor_setting_t *setting)
{
char buf[3*LVL_BUF_MAX] = {0};
int temp = 0;
if (NULL == setting) {
msg("%s: unexpected NULL", __func__);
return 0;
}
if (read(setting->chan_idx, buf, sizeof(buf) - 1) != -1) {
sscanf(buf, "Result:%d Raw:%*d\n", &temp);
}
lseek(setting->chan_idx, 0, SEEK_SET);
return CONV(temp);
}

View File

@@ -1,17 +0,0 @@
/*===========================================================================
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#ifndef __ADC_SENSOR_H__
#define __ADC_SENSOR_H__
#include "thermal.h"
int adc_sensors_setup(sensor_setting_t *settings, sensor_t * sensor);
void adc_sensors_shutdown(sensor_setting_t *setting);
int adc_sensor_get_temperature(sensor_setting_t *setting);
#endif /* __ADC_SENSOR_H__ */

View File

@@ -1,674 +0,0 @@
/*===========================================================================
bcl-sensor.c
DESCRIPTION
BCL sensor access functions.
INITIALIZATION AND SEQUENCING REQUIREMENTS
setup() function should be called before get_temperature().
shutdown() function should be called to clean up resources.
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <pthread.h>
#include <poll.h>
#include "bcl-sensor.h"
#include "thermal.h"
#define LVL_BUF_MAX (12)
#ifndef BCL_DUMP_FILE_DEFAULT
#define BCL_DUMP_FILE_DEFAULT "/data/bcl_dump.log"
#endif
/* BCL sysfs defines */
#define BCL_MODE "/sys/devices/platform/battery_current_limit/mode"
#define BCL_TYPE "/sys/devices/platform/battery_current_limit/type"
#define BCL_IBAT "/sys/devices/platform/battery_current_limit/ibat"
#define BCL_IMAX "/sys/devices/platform/battery_current_limit/imax"
#define BCL_VBAT "/sys/devices/platform/battery_current_limit/vbat"
#define BCL_RBAT "/sys/devices/platform/battery_current_limit/rbat"
#define BCL_OCV "/sys/devices/platform/battery_current_limit/ocv"
#define BCL_SOC "/sys/class/power_supply/battery/capacity"
#define BCL_POLL_INTERVAL "/sys/devices/platform/battery_current_limit/poll_interval"
#define BCL_IBAT_IMAX_LOW_THRESHOLD_MODE "/sys/devices/platform/battery_current_limit/ibat_imax_low_threshold_mode"
#define BCL_IBAT_IMAX_HIGH_THRESHOLD_MODE "/sys/devices/platform/battery_current_limit/ibat_imax_high_threshold_mode"
#define BCL_IBAT_IMAX_LOW_THRESHOLD_VALUE "/sys/devices/platform/battery_current_limit/ibat_imax_low_threshold_value"
#define BCL_IBAT_IMAX_HIGH_THRESHOLD_VALUE "/sys/devices/platform/battery_current_limit/ibat_imax_high_threshold_value"
typedef struct bcl_data {
pthread_t bcl_thread;
pthread_mutex_t bcl_mutex;
pthread_cond_t bcl_condition;
int threshold_reached;
int hi_threshold, lo_threshold;
int hi_idx, lo_idx;
int sensor_shutdown;
sensor_t *sensor;
FILE *dump_bcl_fd;
unsigned int ibat_idx;
unsigned int imax_idx;
unsigned int vbat_idx;
unsigned int rbat_idx;
unsigned int soc_idx;
unsigned int ocv_idx;
int ibat;
int imax;
} bcl_data;
static void *bcl_uevent(void *data)
{
int err = 0;
sensor_t *sensor = (sensor_t *)data;
struct pollfd fds;
int fd;
char uevent[MAX_PATH] = {0};
char buf[MAX_PATH] = {0};
bcl_data *bcl = NULL;
if (NULL == sensor ||
NULL == sensor->data) {
msg("%s: unexpected NULL", __func__);
return NULL;
}
bcl = (bcl_data *) sensor->data;
/* Looking for bcl uevent */
strlcpy(uevent, BCL_TYPE, MAX_PATH);
fd = open(uevent, O_RDONLY);
if (fd < 0) {
msg("Unable to open %s to receive notifications.\n", uevent);
return NULL;
};
while (!bcl->sensor_shutdown) {
fds.fd = fd;
fds.events = POLLERR|POLLPRI;
fds.revents = 0;
err = poll(&fds, 1, -1);
if (err == -1) {
msg("Error in uevent poll.\n");
break;
}
read(fd, buf, sizeof(buf));
lseek(fd, 0, SEEK_SET);
dbgmsg("BCL uevent :%s", buf);
/* notify the waiting threads */
pthread_mutex_lock(&(bcl->bcl_mutex));
bcl->threshold_reached = 1;
pthread_cond_broadcast(&(bcl->bcl_condition));
pthread_mutex_unlock(&(bcl->bcl_mutex));
}
if (fd > -1)
close(fd);
return NULL;
}
static void enable_bcl(bcl_data *bcl, int enabled)
{
int ret = 0;
char name[MAX_PATH] = {0};
if (NULL == bcl ||
NULL == bcl->sensor) {
msg("%s: unexpected NULL", __func__);
return;
}
strlcpy(name, BCL_MODE, MAX_PATH);
if (enabled)
ret = write_to_file(name, "enabled", strlen("enabled"));
else
ret = write_to_file(name, "disabled", strlen("disabled"));
if (ret <= 0) {
msg("BCL failed to set mode %d\n", enabled);
} else {
dbgmsg("BCL mode set to %d\n", enabled);
}
}
static void enable_bcl_threshold_high(bcl_data *bcl, int enabled)
{
int ret = 0;
char name[MAX_PATH] = {0};
if (NULL == bcl ||
NULL == bcl->sensor) {
msg("%s: unexpected NULL", __func__);
return;
}
strlcpy(name, BCL_IBAT_IMAX_HIGH_THRESHOLD_MODE, MAX_PATH);
if (enabled)
ret = write_to_file(name, "enabled", strlen("enabled"));
else
ret = write_to_file(name, "disabled", strlen("disabled"));
if (ret <= 0) {
msg("BCL high threshold failed to %d\n", enabled);
} else {
dbgmsg("BCL high threshold enabled: %d\n", enabled);
}
}
static void enable_bcl_threshold_low(bcl_data *bcl, int enabled)
{
int ret = 0;
char name[MAX_PATH] = {0};
if (NULL == bcl ||
NULL == bcl->sensor) {
msg("%s: unexpected NULL", __func__);
return;
}
strlcpy(name, BCL_IBAT_IMAX_LOW_THRESHOLD_MODE, MAX_PATH);
if (enabled)
ret = write_to_file(name, "enabled", strlen("enabled"));
else
ret = write_to_file(name, "disabled", strlen("disabled"));
if (ret <= 0) {
msg("BCL low threshold failed to %d\n", enabled);
} else {
dbgmsg("BCL low threshold enabled: %d\n", enabled);
}
}
static void set_bcl_thresholds(bcl_data *bcl, int lvl, int lvl_clr,
int hi_enable, int lo_enable)
{
char highname[MAX_PATH]= {0};
char lowname[MAX_PATH]= {0};
char buf[LVL_BUF_MAX] = {0};
int ret = 0;
int lowbcl = 0;
if (NULL == bcl) {
msg("%s: unexpected NULL", __func__);
return;
}
strlcpy(highname, BCL_IBAT_IMAX_HIGH_THRESHOLD_VALUE, MAX_PATH);
strlcpy(lowname, BCL_IBAT_IMAX_LOW_THRESHOLD_VALUE, MAX_PATH);
/* Set thresholds in legal order */
if (read_line_from_file(lowname, buf, sizeof(buf)) > 0) {
lowbcl = atoi(buf);
}
if (lvl <= lowbcl) {
/* set high threshold first */
dbgmsg("Setting up BCL thresholds high: %d\n", lvl);
enable_bcl_threshold_high(bcl, hi_enable);
snprintf(buf, LVL_BUF_MAX, "%d", lvl);
ret = write_to_file(highname, buf, strlen(buf));
if (ret <= 0)
msg("BCL threshold high failed to set %d\n", lvl);
dbgmsg("Setting up BCL thresholds low: %d\n", lvl_clr);
enable_bcl_threshold_low(bcl, lo_enable);
snprintf(buf, LVL_BUF_MAX, "%d", lvl_clr);
ret = write_to_file(lowname, buf, strlen(buf));
if (ret <= 0)
msg("BCL threshold low failed to set %d\n", lvl_clr);
} else {
dbgmsg("Setting up BCL thresholds low: %d\n", lvl_clr);
enable_bcl_threshold_low(bcl, lo_enable);
snprintf(buf, LVL_BUF_MAX, "%d", lvl_clr);
ret = write_to_file(lowname, buf, strlen(buf));
if (ret <= 0)
msg("BCL threshold low failed to set %d\n", lvl_clr);
dbgmsg("Setting up BCL thresholds high: %d\n", lvl);
enable_bcl_threshold_high(bcl, hi_enable);
snprintf(buf, LVL_BUF_MAX, "%d", lvl);
ret = write_to_file(highname, buf, strlen(buf));
if (ret <= 0)
msg("BCL threshold high failed to set %d\n", lvl);
}
bcl->hi_threshold = lvl;
bcl->lo_threshold = lvl_clr;
}
void bcl_enable_thresholds(sensor_setting_t *setting, int enabled)
{
if (NULL == setting ||
NULL == setting->sensor ||
NULL == setting->sensor->data) {
msg("bcl: unexpected NULL");
return;
}
enable_bcl_threshold_high(setting->sensor->data, enabled);
enable_bcl_threshold_low(setting->sensor->data, enabled);
}
void bcl_enable(sensor_setting_t *setting, int enabled)
{
if (NULL == setting ||
NULL == setting->sensor ||
NULL == setting->sensor->data) {
msg("bcl: unexpected NULL");
return;
}
enable_bcl(setting->sensor->data, enabled);
}
/* NOTE: bcl_setup() function does not enable the sensor
* or set thresholds. This should be done in the target-specific setup */
int bcl_setup(sensor_setting_t *setting, sensor_t *sensor)
{
int fd = -1;
int sensor_count = 0;
char name[MAX_PATH] = {0};
bcl_data *bcl = NULL;
char buf[LVL_BUF_MAX] = {0};
int ret = 0;
const char *dump_bcl_file = (dump_bcl_ibat_imax_file) ? dump_bcl_ibat_imax_file : BCL_DUMP_FILE_DEFAULT;
/* We have nothing to do if there are no thresholds */
if (!setting->num_thresholds) {
dbgmsg("No thresholds for sensor %s\n", sensor->name);
return sensor_count;
}
/* Allocate BCL data */
bcl = (bcl_data *) malloc(sizeof(bcl_data));
if (NULL == bcl) {
msg("%s: malloc failed", __func__);
return sensor_count;
}
memset(bcl, 0, sizeof(bcl_data));
sensor->data = (void *) bcl;
if (dump_bcl_ibat_imax) {
bcl->dump_bcl_fd = fopen(dump_bcl_file, "w");
if (bcl->dump_bcl_fd == NULL) {
msg("Failed to open BCL dump file %s\n", dump_bcl_file);
free(bcl);
return sensor_count;
}
fprintf(bcl->dump_bcl_fd, "ibat(mA) imax(mA) vbat(mV) ocv(uV) rbat(mOhms) soc\n");
fflush(bcl->dump_bcl_fd);
}
sensor->tzn = 0;
strlcpy(name, BCL_IBAT, MAX_PATH);
fd = open(name, O_RDONLY);
if (fd < 0) {
msg("%s: Error opening %s\n", __func__, name);
if (bcl->dump_bcl_fd != NULL)
fclose(bcl->dump_bcl_fd);
return sensor_count;
}
bcl->ibat_idx = fd;
strlcpy(name, BCL_IMAX, MAX_PATH);
fd = open(name, O_RDONLY);
if (fd < 0) {
msg("%s: Error opening %s\n", __func__, name);
close(bcl->ibat_idx);
if (bcl->dump_bcl_fd != NULL)
fclose(bcl->dump_bcl_fd);
return sensor_count;
}
bcl->imax_idx = fd;
strlcpy(name, BCL_VBAT, MAX_PATH);
fd = open(name, O_RDONLY);
if (fd < 0) {
msg("%s: Error opening %s\n", __func__, name);
close(bcl->ibat_idx);
close(bcl->imax_idx);
if (bcl->dump_bcl_fd != NULL)
fclose(bcl->dump_bcl_fd);
return sensor_count;
}
bcl->vbat_idx = fd;
strlcpy(name, BCL_RBAT, MAX_PATH);
fd = open(name, O_RDONLY);
if (fd < 0) {
msg("%s: Error opening %s\n", __func__, name);
close(bcl->ibat_idx);
close(bcl->imax_idx);
close(bcl->vbat_idx);
if (bcl->dump_bcl_fd != NULL)
fclose(bcl->dump_bcl_fd);
return sensor_count;
}
bcl->rbat_idx = fd;
strlcpy(name, BCL_SOC, MAX_PATH);
fd = open(name, O_RDONLY);
if (fd < 0) {
msg("%s: Error opening %s\n", __func__, name);
close(bcl->ibat_idx);
close(bcl->imax_idx);
close(bcl->vbat_idx);
close(bcl->rbat_idx);
if (bcl->dump_bcl_fd != NULL)
fclose(bcl->dump_bcl_fd);
return sensor_count;
}
bcl->soc_idx = fd;
strlcpy(name, BCL_OCV, MAX_PATH);
fd = open(name, O_RDONLY);
if (fd < 0) {
msg("%s: Error opening %s\n", __func__, name);
close(bcl->ibat_idx);
close(bcl->imax_idx);
close(bcl->vbat_idx);
close(bcl->rbat_idx);
close(bcl->soc_idx);
if (bcl->dump_bcl_fd != NULL)
fclose(bcl->dump_bcl_fd);
return sensor_count;
}
bcl->ocv_idx = fd;
sensor_count++;
pthread_mutex_init(&(bcl->bcl_mutex), NULL);
pthread_cond_init(&(bcl->bcl_condition), NULL);
bcl->sensor_shutdown = 0;
bcl->threshold_reached = 0;
bcl->sensor = sensor;
setting->disabled = 0;
if (sensor->interrupt_enable) {
pthread_create(&(bcl->bcl_thread), NULL,
bcl_uevent, sensor);
}
strlcpy(name, BCL_POLL_INTERVAL, MAX_PATH);
snprintf(buf, LVL_BUF_MAX, "%d", setting->sampling_period_us/1000);
ret = write_to_file(name, buf, strlen(buf));
if (ret <= 0)
msg("BCL poll interval failed to set %d\n", setting->sampling_period_us);
return sensor_count;
}
void bcl_shutdown(sensor_setting_t *setting)
{
bcl_data *bcl;
if (NULL == setting ||
NULL == setting->sensor ||
NULL == setting->sensor->data) {
msg("%s: unexpected NULL", __func__);
return;
}
bcl = (bcl_data *) setting->sensor->data;
bcl->sensor_shutdown = 1;
if (bcl->imax_idx > 0)
close(bcl->imax_idx);
if (bcl->ibat_idx > 0)
close(bcl->ibat_idx);
if (bcl->vbat_idx > 0)
close(bcl->vbat_idx);
if (bcl->rbat_idx > 0)
close(bcl->rbat_idx);
if (bcl->soc_idx > 0)
close(bcl->soc_idx);
if (bcl->ocv_idx > 0)
close(bcl->ocv_idx);
if (bcl->dump_bcl_fd)
fclose(bcl->dump_bcl_fd);
if (setting->sensor->interrupt_enable)
pthread_join(bcl->bcl_thread, NULL);
free(bcl);
}
int bcl_get_imax(sensor_setting_t *setting)
{
char buf[64];
int temp = 0;
bcl_data *bcl;
if (NULL == setting) {
msg("%s: unexpected NULL", __func__);
return 0;
}
memset(buf, 0, sizeof(buf));
bcl = (bcl_data *) setting->sensor->data;
if (read(bcl->imax_idx, buf, sizeof(buf) - 1) != -1)
temp = atoi(buf);
lseek(bcl->imax_idx, 0, SEEK_SET);
return (temp);
}
int bcl_get_vbat(sensor_setting_t *setting)
{
char buf[64];
int temp = 0;
bcl_data *bcl;
if (NULL == setting) {
msg("%s: unexpected NULL", __func__);
return 0;
}
memset(buf, 0, sizeof(buf));
bcl = (bcl_data *) setting->sensor->data;
if (read(bcl->vbat_idx, buf, sizeof(buf) - 1) != -1)
temp = atoi(buf);
lseek(bcl->vbat_idx, 0, SEEK_SET);
return (temp);
}
int bcl_get_rbat(sensor_setting_t *setting)
{
char buf[64];
int temp = 0;
bcl_data *bcl;
if (NULL == setting) {
msg("%s: unexpected NULL", __func__);
return 0;
}
memset(buf, 0, sizeof(buf));
bcl = (bcl_data *) setting->sensor->data;
if (read(bcl->rbat_idx, buf, sizeof(buf) - 1) != -1)
temp = atoi(buf);
lseek(bcl->rbat_idx, 0, SEEK_SET);
return (temp);
}
int bcl_get_soc(sensor_setting_t *setting)
{
char buf[64];
int temp = 0;
bcl_data *bcl;
if (NULL == setting) {
msg("%s: unexpected NULL", __func__);
return 0;
}
memset(buf, 0, sizeof(buf));
bcl = (bcl_data *) setting->sensor->data;
if (read(bcl->soc_idx, buf, sizeof(buf) - 1) != -1)
temp = atoi(buf);
lseek(bcl->soc_idx, 0, SEEK_SET);
return (temp);
}
int bcl_get_ocv(sensor_setting_t *setting)
{
char buf[64];
int temp = 0;
bcl_data *bcl;
if (NULL == setting) {
msg("%s: unexpected NULL", __func__);
return 0;
}
memset(buf, 0, sizeof(buf));
bcl = (bcl_data *) setting->sensor->data;
if (read(bcl->ocv_idx, buf, sizeof(buf) -1) != -1)
temp = atoi(buf);
lseek(bcl->ocv_idx, 0, SEEK_SET);
return (temp);
}
int bcl_get_ibat(sensor_setting_t *setting)
{
char buf[64];
int temp = 0;
bcl_data *bcl;
if (NULL == setting) {
msg("%s: unexpected NULL", __func__);
return 0;
}
memset(buf, 0, sizeof(buf));
bcl = (bcl_data *) setting->sensor->data;
if (read(bcl->ibat_idx, buf, sizeof(buf) - 1) != -1)
temp = atoi(buf);
lseek(bcl->ibat_idx, 0, SEEK_SET);
return (temp);
}
int bcl_get_diff_imax_ibat(sensor_setting_t *setting)
{
if (NULL == setting) {
msg("%s: unexpected NULL", __func__);
return 0;
}
return (bcl_get_imax(setting) - bcl_get_ibat(setting));
}
void bcl_interrupt_wait(sensor_setting_t *setting)
{
bcl_data *bcl;
if (NULL == setting ||
NULL == setting->sensor ||
NULL == setting->sensor->data) {
msg("%s: unexpected NULL", __func__);
return;
}
bcl = (bcl_data *) setting->sensor->data;
if (dump_bcl_ibat_imax == 1) {
usleep(setting->sampling_period_us);
/* Read all BCL related params for dumping to a file */
bcl->ibat = bcl_get_ibat(setting);
bcl->imax = bcl_get_imax(setting);
if (bcl->dump_bcl_fd) {
fprintf(bcl->dump_bcl_fd, "%d %d %d %d %d %d\n", bcl->ibat, bcl->imax, bcl_get_vbat(setting),
bcl_get_ocv(setting), bcl_get_rbat(setting), bcl_get_soc(setting));
fflush(bcl->dump_bcl_fd);
}
return;
}
if (setting->sensor->interrupt_enable) {
/* Wait for sensor threshold condition */
pthread_mutex_lock(&(bcl->bcl_mutex));
while (!bcl->threshold_reached) {
pthread_cond_wait(&(bcl->bcl_condition),
&(bcl->bcl_mutex));
}
bcl->threshold_reached = 0;
pthread_mutex_unlock(&(bcl->bcl_mutex));
/* Read all BCL related params after event is fired */
bcl->ibat = bcl_get_ibat(setting);
bcl->imax = bcl_get_imax(setting);
}
}
void bcl_update_thresholds(sensor_setting_t *setting,
int threshold_type, int level)
{
int hi, lo;
int hi_enable = 1;
int lo_enable = 1;
bcl_data *bcl;
if (NULL == setting ||
NULL == setting->sensor ||
NULL == setting->sensor->data) {
msg("%s: unexpected NULL", __func__);
return;
}
bcl = (bcl_data *) setting->sensor->data;
dbgmsg("%s: threshold_type %d, level %d", __func__,
threshold_type, level);
hi = setting->t[bcl->hi_idx].lvl_trig;
lo = setting->t[bcl->lo_idx].lvl_clr;
if (level >= setting->num_thresholds) {
/* handle corner high case */
hi = setting->t[setting->num_thresholds - 1].lvl_trig;
bcl->hi_idx = setting->num_thresholds - 1;
hi_enable = 0;
} else {
hi = setting->t[level].lvl_trig;
bcl->hi_idx = level;
}
if (level <= 0) {
/* handle corner low case */
lo = setting->t[0].lvl_clr;
bcl->lo_idx = 0;
lo_enable = 0;
} else {
lo = setting->t[level - 1].lvl_clr;
bcl->lo_idx = level - 1;
}
set_bcl_thresholds(bcl, hi, lo, hi_enable, lo_enable);
}

View File

@@ -1,21 +0,0 @@
/*===========================================================================
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#ifndef __BCL_SENSOR_H__
#define __BCL_SENSOR_H__
#include "thermal.h"
int bcl_setup(sensor_setting_t *settings, sensor_t * sensor);
void bcl_shutdown(sensor_setting_t *setting);
int bcl_get_imax(sensor_setting_t *setting);
int bcl_get_ibat(sensor_setting_t *setting);
int bcl_get_diff_imax_ibat(sensor_setting_t *setting);
void bcl_enable(sensor_setting_t *setting, int enabled);
void bcl_interrupt_wait(sensor_setting_t *setting);
void bcl_update_thresholds(sensor_setting_t *setting, int threshold_triggered, int level);
#endif /* __BCL_SENSOR_H__ */

View File

@@ -1,67 +0,0 @@
# -*- Autoconf -*-
# configure.ac -- Autoconf script for diag
#
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.61)
AC_INIT([thermal],
1.0.0)
AM_INIT_AUTOMAKE([foreign])
AM_MAINTAINER_MODE
AC_CONFIG_HEADER([config.h])
AC_CONFIG_MACRO_DIR([m4])
# Checks for programs.
AC_PROG_CC
AM_PROG_CC_C_O
AC_PROG_LIBTOOL
AC_PROG_AWK
AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
PKG_PROG_PKG_CONFIG
# Checks for libraries.
PKG_CHECK_MODULES([QMIF], [qmi-framework])
AC_SUBST([QMIF_CFLAGS])
AC_SUBST([QMIF_LIBS])
AC_ARG_WITH([kernel],
AC_HELP_STRING([--with-kernel=@<:@dir@:>@],
[Specify the location of the Linux kernel headers]),
[kerneldir=$withval],
with_kernel=no)
if test "x$with_kernel" != "xno"; then
CFLAGS="${CFLAGS} -I${kerneldir}/include -I${kerneldir}/arch/arm/include"
fi
AC_ARG_WITH([glib],
AC_HELP_STRING([--with-glib],
[enable glib, building HLOS systems which use glib]))
if (test "x${with_glib}" = "xyes"); then
AC_DEFINE(ENABLE_USEGLIB, 1, [Define if HLOS systems uses glib])
PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes,
AC_MSG_ERROR(GThread >= 2.16 is required))
PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes,
AC_MSG_ERROR(GLib >= 2.16 is required))
GLIB_CFLAGS="$GLIB_CFLAGS $GTHREAD_CFLAGS"
GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS"
AC_SUBST(GLIB_CFLAGS)
AC_SUBST(GLIB_LIBS)
fi
AM_CONDITIONAL(USE_GLIB, test "x${with_glib}" = "xyes")
AC_SUBST([CFLAGS])
AC_SUBST([CC])
AC_CONFIG_FILES([ \
Makefile \
])
AC_OUTPUT

View File

@@ -1,76 +0,0 @@
/*===========================================================================
gen-sensor.c
DESCRIPTION
Generic thermal zone sensor access functions.
INITIALIZATION AND SEQUENCING REQUIREMENTS
setup() function should be called before get_temperature().
shutdown() function should be called to clean up resources.
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include "thermal.h"
int gen_sensors_setup(sensor_setting_t *setting, sensor_t* s)
{
int fd = -1;
int sensor_count = 0;
char name[MAX_PATH] = {0};
int tzn = 0;
sensor_t *sensor = (sensor_t *)s;
tzn = get_tzn(sensor->name);
if (tzn < 0) {
msg("No thermal zone device found in the kernel for sensor %s\n", sensor->name);
return sensor_count;
}
/* We have nothing to do if there are no thresholds */
if (!setting->num_thresholds) {
dbgmsg("No thresholds for sensor %s\n", sensor->name);
return sensor_count;
}
sensor->tzn = tzn;
snprintf(name, MAX_PATH, TZ_TEMP, sensor->tzn);
fd = open(name, O_RDONLY);
if (fd > -1) {
setting->disabled = 0;
setting->chan_idx = fd;
sensor_count++;
} else {
msg("%s: Error opening %s\n", __func__, name);
}
return sensor_count;
}
void gen_sensors_shutdown(sensor_setting_t *setting)
{
if (NULL == setting ||
NULL == setting->sensor) {
msg("%s: unexpected NULL", __func__);
return;
}
if (setting->chan_idx > 0)
close(setting->chan_idx);
}
int gen_sensor_get_temperature(sensor_setting_t *setting)
{
char buf[10] = {0};
int temp = 0;
if (read(setting->chan_idx, buf, sizeof(buf) - 1) != -1)
temp = atoi(buf);
lseek(setting->chan_idx, 0, SEEK_SET);
return temp;
}

View File

@@ -1,17 +0,0 @@
/*===========================================================================
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#ifndef __GEN_SENSOR_H__
#define __GEN_SENSOR_H__
#include "thermal.h"
int gen_sensors_setup(sensor_setting_t *settings, sensor_t * sensor);
void gen_sensors_shutdown(sensor_setting_t *setting);
int gen_sensor_get_temperature(sensor_setting_t *setting);
#endif /* __GEN_SENSOR_H__ */

View File

@@ -1,77 +0,0 @@
sampling 5000
[tsens_tz_sensor0]
sampling 1000
thresholds 105 110 115 120 125
thresholds_clr 95 100 105 110 115
actions cpu cpu cpu cpu shutdown
action_info 1200000 1000000 800000 384000 1000
[tsens_tz_sensor1]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor2]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor3]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor4]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor5]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor6]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor7]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor8]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor9]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor10]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0

View File

@@ -1,77 +0,0 @@
sampling 5000
[tsens_tz_sensor0]
sampling 1000
thresholds 115 120 125
thresholds_clr 105 110 115
actions cpu cpu shutdown
action_info 800000 384000 1000
[tsens_tz_sensor1]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor2]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor3]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor4]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor5]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor6]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor7]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor8]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor9]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor10]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0

View File

@@ -1,77 +0,0 @@
sampling 5000
[tsens_tz_sensor0]
sampling 1000
thresholds 115 120 125
thresholds_clr 105 110 115
actions cpu cpu shutdown
action_info 1400000 800000 1000
[tsens_tz_sensor1]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor2]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor3]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor4]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor5]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor6]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor7]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor8]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor9]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0
[tsens_tz_sensor10]
sampling 1000
thresholds 105
thresholds_clr 100
actions none
action_info 0

View File

@@ -1,480 +0,0 @@
/*===========================================================================
modem_mitigation_oncrpc.c
DESCRIPTION
Modem mitigation action over ONCRPC.
INITIALIZATION AND SEQUENCING REQUIREMENTS
modem_communication_init() should be called before the modem_request().
Copyright (c) 2011 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#include <errno.h>
#include "thermal.h"
#include "oncrpc.h"
#include "thermal_mitigation.h"
#include "thermal_mitigation_rpc.h"
#ifdef ENABLE_FUSION_MODEM
#include "thermal_mitigation_fusion.h"
#include "thermal_mitigation_fusion_rpc.h"
#endif
/* Modem mitigative action */
#define MITIGATION_DEVICE "modem"
#define MAX_MODEM_MITIGATION_LEVEL (3)
#define MODEM_DEVICE 0
#define FUSION_DEVICE 1
static int modem_exists;
static int fusion_modem_exists;
static unsigned int modem_oncrpc_handle;
static unsigned int fusion_oncrpc_handle;
static int modem_req[SENSOR_IDX_MAX];
static int fusion_modem_req[SENSOR_IDX_MAX];
static pthread_mutex_t modem_mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t fusion_modem_mtx = PTHREAD_MUTEX_INITIALIZER;
static int modem_register(void);
static int fusion_modem_register(void);
/*===========================================================================
FUNCTION modem_thermal_state_cb
Callback function when modem does its own thermal mitigation.
Notifies the interested through the socket.
ARGUMENTS
None.
RETURN VALUE
None.
===========================================================================*/
static int modem_thermal_state_cb(const char *device, unsigned int state)
{
char tempBuf[60];
dbgmsg("Callback from modem (%s) with state %u", device, state);
snprintf(tempBuf, sizeof(tempBuf) -1, "%s\n%u", device, state);
write_to_local_socket(UI_LOCALSOCKET_NAME, tempBuf, strlen(tempBuf));
return 0;
}
/*===========================================================================
FUNCTION fusion_thermal_state_cb
Callback function when fusion modem does its own thermal mitigation.
Notifies the interested through the socket.
ARGUMENTS
None.
RETURN VALUE
None.
===========================================================================*/
static int fusion_thermal_state_cb(const char *device, unsigned int state)
{
char tempBuf[60];
dbgmsg("Callback from fusion (%s) with state %u", device, state);
snprintf(tempBuf, sizeof(tempBuf) -1, "%s\n%u", device, state);
write_to_local_socket(UI_LOCALSOCKET_NAME, tempBuf, strlen(tempBuf));
return 0;
}
/*===========================================================================
FUNCTION thermald_oncrpc_cleanup_cb
Callback function for ONCRPC clean up.
ARGUMENTS
handle : Passed from ONCRPC
data: Userdata passed during callback register.
RETURN VALUE
None.
===========================================================================*/
static void thermald_oncrpc_cleanup_cb(void *handle, void *data)
{
int type = (int)data;
switch (type) {
case MODEM_DEVICE:
info("Modem ONCRPC communication terminated.\n");
modem_exists = 0;
break;
#ifdef ENABLE_FUSION_MODEM
case FUSION_DEVICE:
info("Fusion modem ONCRPC communication terminated.\n");
fusion_modem_exists = 0;
break;
#endif
default:
msg("Unknown device in %s\n", __func__);
break;
}
oncrpc_cleanup_done(handle);
dbgmsg("ONCRPC clean up done for %d.\n", type);
}
/*===========================================================================
FUNCTION thermald_oncrpc_restart_cb
Callback for modem/fusion modem restart.
ARGUMENTS
handle : Passed from ONCRPC
data: Userdata passed during callback register.
RETURN VALUE
None.
===========================================================================*/
static void thermald_oncrpc_restart_cb(void *handle, void *data)
{
int type = (int)data;
switch (type) {
case MODEM_DEVICE:
info("Modem restart detected.\n");
modem_exists = modem_register();
break;
#ifdef ENABLE_FUSION_MODEM
case FUSION_DEVICE:
info("Fusion modem restart detected.\n");
fusion_modem_exists = fusion_modem_register();
break;
#endif
default:
msg("Unknown device in %s\n", __func__);
break;
}
dbgmsg("ONCRPC restart re-registered for %d.\n", type);
}
/*===========================================================================
FUNCTION modem_register
Register modem callbacks and server cleanup/restart callbacks
ARGUMENTS
None.
RETURN VALUE
Returns if the server is available.
1 if server is available, 0 if not.
===========================================================================*/
static int modem_register(void)
{
int ret = 0;
pthread_mutex_lock(&modem_mtx);
ret = thermal_mitigation_null();
if (ret) {
info("Modem thermal mitigation available.\n");
ret = thermal_mitigation_register_notify_cb(MITIGATION_DEVICE,
&modem_oncrpc_handle, modem_thermal_state_cb);
if (ret) {
msg("Modem callback not registered\n");
}
oncrpc_register_server_exit_notification_cb(
THERMAL_MITIGATIONPROG,
THERMAL_MITIGATIONVERS,
thermald_oncrpc_cleanup_cb, (void *)MODEM_DEVICE);
oncrpc_register_server_restart_notification_cb(
THERMAL_MITIGATIONPROG,
THERMAL_MITIGATIONVERS,
thermald_oncrpc_restart_cb, (void *)MODEM_DEVICE);
/* We are still ok to continue as only the callback failed */
dbgmsg("Modem thermal mitigation callbacks registered.\n");
ret = 1;
} else {
msg("Modem thermal mitigation not available.\n");
ret = 0;
}
pthread_mutex_unlock(&modem_mtx);
return ret;
}
/*===========================================================================
FUNCTION fusion_modem_register
Register fusion modem callbacks and server cleanup/restart callbacks
ARGUMENTS
None.
RETURN VALUE
Returns if the server is available.
1 if server is available, 0 if not.
===========================================================================*/
static int fusion_modem_register(void)
{
int ret = 0;
#ifdef ENABLE_FUSION_MODEM
pthread_mutex_lock(&fusion_modem_mtx);
ret = thermal_mitigation_fusion_null();
if (ret) {
info("Fusion modem thermal mitigation available.\n");
ret = thermal_mitigation_register_notify_cb_fusion(MITIGATION_DEVICE,
&fusion_oncrpc_handle, fusion_thermal_state_cb);
if (ret) {
msg("Fusion modem callback not registered\n");
}
oncrpc_register_server_exit_notification_cb(
THERMAL_MITIGATION_FUSIONPROG,
THERMAL_MITIGATION_FUSIONVERS,
thermald_oncrpc_cleanup_cb, (void *)FUSION_DEVICE);
oncrpc_register_server_restart_notification_cb(
THERMAL_MITIGATION_FUSIONPROG,
THERMAL_MITIGATION_FUSIONVERS,
thermald_oncrpc_restart_cb, (void *)FUSION_DEVICE);
/* We are still ok to continue as only the callback failed */
dbgmsg("Fusion modem thermal mitigation callbacks registered.\n");
ret = 1;
} else {
msg("Fusion modem thermal mitigation not available.\n");
ret = 0;
}
pthread_mutex_unlock(&fusion_modem_mtx);
#endif
return ret;
}
/*===========================================================================
FUNCTION modem_request
Action function to throttle modem functionality.
ARGUMENTS
requester - requesting sensor enum
temperature - temperature reached
level - 0-3 throttling level for modem mitigation
RETURN VALUE
0 on success, -1 on failure.
===========================================================================*/
int modem_request(int requester, int temperature, int level)
{
int ret = -1;
int i;
static int prev;
if (!modem_exists)
return ret;
/* Modem level: 0 - No action
* 1 - Mitigation level 1
* 2 - Mitigation level 2
* 3 - Emergency
*/
if (level < 0)
level = 0;
if (level > MAX_MODEM_MITIGATION_LEVEL)
level = MAX_MODEM_MITIGATION_LEVEL;
pthread_mutex_lock(&modem_mtx);
/* Aggregate modem mitigation level for all sensors */
modem_req[requester] = level;
for (i = 0; i < SENSOR_IDX_MAX; i++) {
if (modem_req[i] > level)
level = modem_req[i];
}
if (level != prev) {
ret = thermal_mitigation_set(MITIGATION_DEVICE, level);
if (ret) {
msg("Modem mitigation failed with %d for level %d\n", ret, level);
} else {
prev = level;
info("ACTION: MODEM - "
"Modem mitigation succeeded for level %d.\n", level);
}
} else {
dbgmsg("Modem already at mitigation state %d\n", level);
ret = 0;
}
pthread_mutex_unlock(&modem_mtx);
return ret;
}
/*===========================================================================
FUNCTION fusion_modem_request
Action function to throttle fusion modem functionality.
ARGUMENTS
requester - requesting sensor enum
temperature - temperature reached
level - 0-3 throttling level for modem mitigation
RETURN VALUE
0 on success, -1 on failure.
===========================================================================*/
int fusion_modem_request(int requester, int temperature, int level)
{
int ret = -1;
int i;
static int prev;
if (!fusion_modem_exists)
return ret;
/* Modem level: 0 - No action
* 1 - Mitigation level 1
* 2 - Mitigation level 2
* 3 - Emergency
*/
if (level < 0)
level = 0;
if (level > MAX_MODEM_MITIGATION_LEVEL)
level = MAX_MODEM_MITIGATION_LEVEL;
pthread_mutex_lock(&fusion_modem_mtx);
/* Aggregate modem mitigation level for all sensors */
fusion_modem_req[requester] = level;
for (i = 0; i < SENSOR_IDX_MAX; i++) {
if (fusion_modem_req[i] > level)
level = fusion_modem_req[i];
}
if (level != prev) {
#ifdef ENABLE_FUSION_MODEM
ret = thermal_mitigation_set_fusion(MITIGATION_DEVICE, level);
#endif
if (ret) {
msg("Fusion modem mitigation failed with %d for level %d\n", ret, level);
} else {
prev = level;
info("ACTION: FUSION - "
"Fusion modem mitigation succeeded for level %d.\n", level);
}
} else {
dbgmsg("Fusion modem already at mitigation state %d\n", level);
ret = 0;
}
pthread_mutex_unlock(&fusion_modem_mtx);
return ret;
}
/*===========================================================================
FUNCTION modem_communication_init
Initialization function for modem communication functionality.
Needs to be called before modem_request() or fusion_modem_request()
can be called.
ARGUMENTS
None.
RETURN VALUE
0 on success, -1 on failure.
===========================================================================*/
int modem_communication_init(void)
{
oncrpc_init();
oncrpc_task_start();
info("Establishing ONCRPC communication.\n");
thermal_mitigationcb_app_init();
modem_exists = modem_register();
#ifdef ENABLE_FUSION_MODEM
thermal_mitigation_fusioncb_app_init();
fusion_modem_exists = fusion_modem_register();
#endif
return 0;
}
/*===========================================================================
FUNCTION compare_fn
Comparator function for oncrpc
ARGUMENTS
d1, d2: void pointers for comparison
RETURN VALUE
1 if they are equal, 0 if they are not.
===========================================================================*/
static boolean compare_fn(void *d1, void *d2)
{
return (d1 == d2);
}
/*===========================================================================
FUNCTION modem_communication_release
Release function for modem communication to clean up resources.
Called after use of client handle is complete.
ARGUMENTS
None.
RETURN VALUE
0 on success, -1 on failure.
===========================================================================*/
int modem_communication_release(void)
{
int ret = 0;
int rc = 0;
if (modem_exists) {
ret = thermal_mitigation_deregister_notify_cb(modem_oncrpc_handle);
if (ret) {
msg("Unable to de-register modem cb handle (%d).\n", ret);
}
oncrpc_unregister_server_exit_notification_cb(
THERMAL_MITIGATIONPROG,
THERMAL_MITIGATIONVERS,
thermald_oncrpc_cleanup_cb, (void *)MODEM_DEVICE, compare_fn);
oncrpc_unregister_server_restart_notification_cb(
THERMAL_MITIGATIONPROG,
THERMAL_MITIGATIONVERS,
thermald_oncrpc_restart_cb, (void *)MODEM_DEVICE, compare_fn);
}
#ifdef ENABLE_FUSION_MODEM
if (fusion_modem_exists) {
rc = thermal_mitigation_deregister_notify_cb_fusion(fusion_oncrpc_handle);
if (rc) {
msg("Unable to de-register fusion cb handle (%d).\n", rc);
}
oncrpc_unregister_server_exit_notification_cb(
THERMAL_MITIGATION_FUSIONPROG,
THERMAL_MITIGATION_FUSIONVERS,
thermald_oncrpc_cleanup_cb, (void *)FUSION_DEVICE, compare_fn);
oncrpc_unregister_server_restart_notification_cb(
THERMAL_MITIGATION_FUSIONPROG,
THERMAL_MITIGATION_FUSIONVERS,
thermald_oncrpc_restart_cb, (void *)FUSION_DEVICE, compare_fn);
}
#endif
oncrpc_task_stop();
oncrpc_deinit();
info("ONCRPC communication terminated.\n");
return (ret || rc) ? -1 : 0;
}

View File

@@ -1,565 +0,0 @@
/*===========================================================================
modem_mitigation_qmi.c
DESCRIPTION
Modem mitigation action over QMI.
INITIALIZATION AND SEQUENCING REQUIREMENTS
modem_communication_init() should be called before the modem_request().
Copyright (c) 2011 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/time.h>
#include <errno.h>
#include "thermal.h"
#include "thermal_mitigation_device_service_v01.h"
#include "qmi_client.h"
#include "qmi_idl_lib.h"
#include "qmi_client_instance_defs.h"
#define QMI_MITIGATION_DEVICE_MODEM "pa"
#define MAX_MODEM_MITIGATION_LEVEL (3)
static void * modem_clnt;
static void * fusion_modem_clnt;
static int modem_req[SENSOR_IDX_MAX];
static int fusion_modem_req[SENSOR_IDX_MAX];
static int prev_modem;
static int prev_fusion;
static pthread_mutex_t modem_mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t fusion_modem_mtx = PTHREAD_MUTEX_INITIALIZER;
/*===========================================================================
LOCAL FUNCTION modem_verify_tmd_device
Helper function to verify QMI_MITIGATION_DEVICE_MODEM thermal mitigation
device on remote QMI TMD service.
ARGUMENTS
None.
RETURN VALUE
0 on success, -1 on failure.
===========================================================================*/
static int modem_verify_tmd_device(void *clnt)
{
int rc = -1;
int ret = -1;
unsigned int i;
tmd_get_mitigation_device_list_resp_msg_v01 data_resp;
if (clnt == NULL) {
return -1;
}
memset(&data_resp, 0, sizeof(data_resp));
rc = qmi_client_send_msg_sync(clnt,
QMI_TMD_GET_MITIGATION_DEVICE_LIST_REQ_V01,
NULL, 0,
&data_resp, sizeof(data_resp), 0);
if (rc == QMI_NO_ERR) {
for (i = 0; i < data_resp.mitigation_device_list_len; i++) {
if (0 == strncasecmp(QMI_MITIGATION_DEVICE_MODEM,
data_resp.mitigation_device_list[i].mitigation_dev_id.mitigation_dev_id,
strlen(QMI_MITIGATION_DEVICE_MODEM) + 1)) {
/* found matching device name */
ret = 0;
break;
}
}
} else {
msg("%s: QMI send_msg_sync failed with error %d", __func__, rc);
}
return (!rc && !ret) ? 0 : -1;
}
static qmi_idl_service_object_type tmd_service_object;
static pthread_t qmi_register_thread;
static pthread_t qmi_register_fusion_thread;
void modem_clnt_error_cb(qmi_client_type clnt,
qmi_client_error_type error,
void *error_cb_data);
/*===========================================================================
LOCAL FUNCTION modem_request_common_qmi
Common qmi modem request function.
ARGUMENTS
clnt - client on which to request throttling
mitigation_dev_id - name of mitigation_dev_id
level - 0-3 throttling level for modem mitigation
RETURN VALUE
0 on success, -1 on failure.
===========================================================================*/
static int modem_request_common_qmi(void *clnt, char *mitigation_dev_id,
int level)
{
int ret = -1;
tmd_set_mitigation_level_req_msg_v01 data_req;
tmd_set_mitigation_level_resp_msg_v01 data_resp;
if (!clnt || !mitigation_dev_id)
return ret;
strlcpy(data_req.mitigation_dev_id.mitigation_dev_id, mitigation_dev_id,
QMI_TMD_MITIGATION_DEV_ID_LENGTH_MAX_V01);
data_req.mitigation_level = level;
ret = qmi_client_send_msg_sync((qmi_client_type) clnt,
QMI_TMD_SET_MITIGATION_LEVEL_REQ_V01,
&data_req, sizeof(data_req),
&data_resp, sizeof(data_resp), 0);
return ret;
}
/*===========================================================================
FUNCTION qmi_register
Helper function to initialize qmi connection to modem service.
ARGUMENTS
None.
RETURN VALUE
0 on success, -1 on failure.
===========================================================================*/
static void *qmi_register(void *data)
{
int rc = -1;
int ret = 0;
int level = 0;
int i;
qmi_cci_os_signal_type os_params;
qmi_service_info info;
qmi_client_type notifier = NULL;
void * modem_clnt_local = NULL;
/* release any old handles for modem_clnt */
if (modem_clnt) {
qmi_client_release(modem_clnt);
modem_clnt = NULL;
}
rc = qmi_client_notifier_init(tmd_service_object, &os_params, &notifier);
if (rc != QMI_NO_ERR) {
msg("qmi: qmi_client_notifier_init failed.\n");
ret = -1;
goto handle_error;
}
/* TODO: Assuming modem index is 0, depends on QMI implementation */
while (1)
{
QMI_CCI_OS_SIGNAL_CLEAR(&os_params);
rc = qmi_client_get_service_instance(tmd_service_object, 0, &info);
if(rc == QMI_NO_ERR)
break;
/* wait for server to come up */
QMI_CCI_OS_SIGNAL_WAIT(&os_params, 0);
};
rc = qmi_client_init(&info, tmd_service_object, NULL, NULL, NULL, (qmi_client_type *) (&modem_clnt_local));
if (rc != QMI_NO_ERR) {
msg("Modem thermal mitigation not available.\n");
ret = -1;
goto handle_error;
}
/* Verify modem mitigation device present on modem */
rc = modem_verify_tmd_device(modem_clnt_local);
if (rc != 0) {
qmi_client_release(modem_clnt_local);
modem_clnt_local = NULL;
ret = -1;
goto handle_error;
}
/* best effort register for error */
qmi_client_register_error_cb(modem_clnt_local, modem_clnt_error_cb, NULL);
modem_clnt = modem_clnt_local;
info("Modem thermal mitigation available.\n");
/*Setting highest pending mitigation level if any */
pthread_mutex_lock(&modem_mtx);
/* Aggregate modem mitigation level for all sensors */
for (i = 0; i < SENSOR_IDX_MAX; i++) {
if (modem_req[i] > level)
level = modem_req[i];
}
if (level) {
ret = modem_request_common_qmi(modem_clnt,
QMI_MITIGATION_DEVICE_MODEM,
level);
if (ret) {
msg("Modem mitigation failed with %d for level %d\n",
ret, level);
} else {
prev_modem = level;
info("ACTION: MODEM - "
"Pending request:Modem mitigation succeeded for "
"level %d.\n", level);
}
} else {
dbgmsg("No pending request for Modem mitigation\n");
}
pthread_mutex_unlock(&modem_mtx);
handle_error:
if (notifier != NULL) {
qmi_client_release(notifier);
}
return NULL;
}
/*===========================================================================
FUNCTION qmi_register_fusion
Helper function to initialize qmi connection to fusion service.
ARGUMENTS
None.
RETURN VALUE
0 on success, -1 on failure.
===========================================================================*/
static void *qmi_register_fusion(void *data)
{
int rc = -1;
int ret = 0;
int level = 0;
int i;
qmi_cci_os_signal_type os_params;
qmi_service_info info;
qmi_client_type notifier = NULL;
void * fusion_clnt_local = NULL;
qmi_service_instance instance_id = QMI_CLIENT_QMUX_RMNET_USB_INSTANCE_0;
/* release any old handles for fusion_modem_clnt */
if (fusion_modem_clnt) {
qmi_client_release(fusion_modem_clnt);
fusion_modem_clnt = NULL;
}
rc = qmi_client_notifier_init(tmd_service_object, &os_params, &notifier);
if (rc != QMI_NO_ERR) {
msg("qmi: qmi_client_notifier_init failed.\n");
ret = -1;
goto handle_error_fusion;
}
info("qmi: Instance id %d for fusion TMD", instance_id);
while (1)
{
QMI_CCI_OS_SIGNAL_CLEAR(&os_params);
rc = qmi_client_get_service_instance(tmd_service_object,
instance_id, &info);
if(rc == QMI_NO_ERR)
break;
/* wait for server to come up */
QMI_CCI_OS_SIGNAL_WAIT(&os_params, 0);
};
rc = qmi_client_init(&info, tmd_service_object, NULL, NULL, NULL, (qmi_client_type *) (&fusion_clnt_local));
if (rc != QMI_NO_ERR) {
msg("Fusion modem thermal mitigation not available.\n");
ret = -1;
goto handle_error_fusion;
}
rc = modem_verify_tmd_device(fusion_clnt_local);
if (rc != 0) {
qmi_client_release(fusion_clnt_local);
fusion_clnt_local = NULL;
ret = -1;
goto handle_error_fusion;
}
/* best effort register for error */
qmi_client_register_error_cb(fusion_clnt_local, modem_clnt_error_cb, NULL);
fusion_modem_clnt = fusion_clnt_local;
info("Fusion modem thermal mitigation available.\n");
/*Setting highest pending mitigation level if any */
pthread_mutex_lock(&fusion_modem_mtx);
/* Aggregate modem mitigation level for all sensors */
for (i = 0; i < SENSOR_IDX_MAX; i++) {
if (fusion_modem_req[i] > level)
level = fusion_modem_req[i];
}
if (level) {
ret = modem_request_common_qmi(fusion_modem_clnt,
QMI_MITIGATION_DEVICE_MODEM,
level);
if (ret) {
msg("Fusion modem mitigation failed with %d for "
"level %d\n", ret, level);
} else {
prev_fusion = level;
info("ACTION: FUSION - "
"Pending request:Fusion modem mitigation succeeded "
"for level %d.\n", level);
}
} else {
dbgmsg("No pending request for Fusion modem mitigation\n");
}
pthread_mutex_unlock(&fusion_modem_mtx);
handle_error_fusion:
if (notifier != NULL) {
qmi_client_release(notifier);
}
return NULL;
}
/*===========================================================================
FUNCTION modem_clnt_error_cb
Callback function called by the QCCI infrastructure when it receives a
REMOVE SERVER message from the modem.
ARGUMENTS
None.
RETURN VALUE
0 on success, -1 on failure.
===========================================================================*/
void modem_clnt_error_cb(qmi_client_type clnt,
qmi_client_error_type error,
void *error_cb_data)
{
info("%s: with %d called for clnt %p\n", __func__, error, (void *)clnt);
if (clnt == NULL) {
return;
}
if (clnt == modem_clnt) {
pthread_join(qmi_register_thread, NULL);
pthread_create(&qmi_register_thread, NULL,
qmi_register, NULL);
} else if (clnt == fusion_modem_clnt) {
pthread_join(qmi_register_fusion_thread, NULL);
pthread_create(&qmi_register_fusion_thread, NULL,
qmi_register_fusion, NULL);
}
}
/*===========================================================================
FUNCTION modem_communication_init
Helper function to initialize qmi communication to modem.
ARGUMENTS
None.
RETURN VALUE
0 on success, -1 on failure.
===========================================================================*/
int modem_communication_init(void)
{
/* Get the service object for the tmd API */
tmd_service_object = tmd_get_service_object_v01();
if (!tmd_service_object) {
msg("qmi: tmd_get_service_object failed.\n");
return -1;
}
/* start thread to register with QMI services */
pthread_create(&qmi_register_thread, NULL,
qmi_register, NULL);
/* start thread to register with QMI services */
pthread_create(&qmi_register_fusion_thread, NULL,
qmi_register_fusion, NULL);
return 0;
}
/*===========================================================================
FUNCTION modem_request
Action function to throttle modem functionality.
ARGUMENTS
requester - requesting sensor enum
temperature - temperature reached
level - 0-3 throttling level for modem mitigation
RETURN VALUE
0 on success, -1 on failure.
===========================================================================*/
int modem_request(int requester, int temperature, int level)
{
int ret = -1;
int i;
/* Modem level: 0 - No action
* 1 - Mitigation level 1
* 2 - Mitigation level 2
* 3 - Emergency
*/
if (level < 0)
level = 0;
if (level > MAX_MODEM_MITIGATION_LEVEL)
level = MAX_MODEM_MITIGATION_LEVEL;
pthread_mutex_lock(&modem_mtx);
/* Aggregate modem mitigation level for all sensors */
modem_req[requester] = level;
for (i = 0; i < SENSOR_IDX_MAX; i++) {
if (modem_req[i] > level)
level = modem_req[i];
}
if (!modem_clnt) {
info("Modem: Requested level is recorded and waiting for"
"completing QMI registration");
ret = 0;
goto handle_return;
}
if (level != prev_modem) {
ret = modem_request_common_qmi(modem_clnt,
QMI_MITIGATION_DEVICE_MODEM,
level);
if (ret) {
msg("Modem mitigation failed with %d for level %d\n",
ret, level);
} else {
prev_modem = level;
info("ACTION: MODEM - "
"Modem mitigation succeeded for level %d.\n",
level);
}
} else {
dbgmsg("Modem already at mitigation state %d\n", level);
ret = 0;
}
handle_return:
pthread_mutex_unlock(&modem_mtx);
return ret;
}
/*===========================================================================
FUNCTION fusion_modem_request
Action function to throttle fusion modem functionality.
ARGUMENTS
requester - requesting sensor enum
temperature - temperature reached
level - 0-3 throttling level for modem mitigation
RETURN VALUE
0 on success, -1 on failure.
===========================================================================*/
int fusion_modem_request(int requester, int temperature, int level)
{
int ret = -1;
int i;
/* Modem level: 0 - No action
* 1 - Mitigation level 1
* 2 - Mitigation level 2
* 3 - Emergency
*/
if (level < 0)
level = 0;
if (level > MAX_MODEM_MITIGATION_LEVEL)
level = MAX_MODEM_MITIGATION_LEVEL;
pthread_mutex_lock(&fusion_modem_mtx);
/* Aggregate modem mitigation level for all sensors */
fusion_modem_req[requester] = level;
for (i = 0; i < SENSOR_IDX_MAX; i++) {
if (fusion_modem_req[i] > level)
level = fusion_modem_req[i];
}
if (!fusion_modem_clnt) {
info("Fusion: Requested level is recorded and waiting for"
"completing QMI registration");
ret = 0;
goto handle_return;
}
if (level != prev_fusion) {
ret = modem_request_common_qmi(fusion_modem_clnt,
QMI_MITIGATION_DEVICE_MODEM,
level);
if (ret) {
msg("Fusion modem mitigation failed with %d for "
"level %d\n", ret, level);
} else {
prev_fusion = level;
info("ACTION: FUSION - "
"Fusion modem mitigation succeeded for "
"level %d.\n", level);
}
} else {
dbgmsg("Fusion modem already at mitigation state %d\n", level);
ret = 0;
}
handle_return:
pthread_mutex_unlock(&fusion_modem_mtx);
return ret;
}
/*===========================================================================
FUNCTION modem_communication_release
Release function for modem communication to clean up resources.
Called after use of client handles is complete.
ARGUMENTS
None.
RETURN VALUE
0 on success, -1 on failure.
===========================================================================*/
int modem_communication_release(void)
{
int rc = 0;
pthread_join(qmi_register_thread, NULL);
pthread_join(qmi_register_fusion_thread, NULL);
if (modem_clnt) {
rc = qmi_client_release(modem_clnt);
if (rc)
msg("qmi: qmi_client_release modem clnt failed.\n");
modem_clnt = 0;
}
if (fusion_modem_clnt) {
rc = qmi_client_release(fusion_modem_clnt);
if (rc)
msg("qmi: qmi_client_release fusion clnt failed.\n");
fusion_modem_clnt = 0;
}
return rc;
}

View File

@@ -1,470 +0,0 @@
/*===========================================================================
modem_sensor_qmi.c
DESCRIPTION
Modem sensor action over QMI.
INITIALIZATION AND SEQUENCING REQUIREMENTS
modem_ts_qmi_init() should be called before the modem_ts_temp_request().
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include "thermal.h"
#include "qmi-ts-sensor.h"
#include "thermal_sensor_service_v01.h"
#include "qmi_client.h"
#include "qmi_idl_lib.h"
#include "qmi_client_instance_defs.h"
#define QMI_SENSOR_MODEM "pa"
static void *fusion_modem_clnt;
static pthread_mutex_t fusion_modem_mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t fusion_modem_cond = PTHREAD_COND_INITIALIZER;
static pthread_t fusion_qmi_register_thread;
static int fusion_modem_qmi_ts_ready;
static ts_temp_report_ind_msg_v01 ind_struct;
static qmi_idl_service_object_type ts_service_object;
static void modem_clnt_error_cb(qmi_client_type clnt,
qmi_client_error_type error,
void *error_cb_data);
static int modem_ts_reg_notify(void *clnt, const char *sensor_id,
int send_current_temp_report,
int high_valid,
int high_thresh,
int low_valid,
int low_thresh);
/*===========================================================================
LOCAL FUNCTION qmi_ts_ind_cb
Handle QMI TS indication callbacks.
ARGUMENTS
user_handle - QMI client user handle.
msg_id - Indication message id.
ind_buf - Indication encoded data.
ind_buf_len - Indication encoded data length.
ind_cb_data - TS provided callback data.
RETURN VALUE
None.
===========================================================================*/
static void qmi_ts_ind_cb(qmi_client_type user_handle,
unsigned int msg_id,
void *ind_buf,
unsigned int ind_buf_len,
void *ind_cb_data)
{
qmi_client_error_type rc = QMI_NO_ERR;
unsigned char *buf = ind_buf;
if (msg_id == QMI_TS_TEMP_REPORT_IND_V01) {
memset((void *)&ind_struct, 0,
sizeof(ts_temp_report_ind_msg_v01));
rc = qmi_client_message_decode(user_handle, QMI_IDL_INDICATION,
msg_id, ind_buf, ind_buf_len,
&ind_struct,
sizeof(ts_temp_report_ind_msg_v01));
if (rc != QMI_NO_ERR) {
msg("Error invalid indication message received.\n");
} else {
if (ind_struct.temp_valid) {
qmi_ts_update_temperature(ind_struct.sensor_id.sensor_id,
(int)ind_struct.temp);
} else {
msg("Error invalid temperature field.");
}
}
} else {
printf("\nWarning invalid indication message received.\n");
}
}
/*===========================================================================
LOCAL FUNCTION modem_verify_ts_device
Helper function to verify QMI_SENSOR_MODEM thermal sensor exits on remote QMI
TS service.
ARGUMENTS
None.
RETURN VALUE
0 on success, -(ERRNO) Code on failure.
===========================================================================*/
static int modem_verify_ts_device(void *clnt)
{
int rc;
int ret = -(EPERM);
unsigned int i;
static int func_exec_count;
ts_get_sensor_list_resp_msg_v01 *list_resp = NULL;
ts_register_notification_temp_req_msg_v01 *reg_notify_req = NULL;
ts_register_notification_temp_resp_msg_v01 *reg_notify_resp = NULL;
/* Large structs let's not put it on the stack. */
do {
if (clnt == NULL) {
ret = -(EINVAL);
break;
}
list_resp = malloc(sizeof(ts_get_sensor_list_resp_msg_v01));
if (list_resp == NULL) {
msg("%s: Malloc list_resp failure", __func__);
ret = -(ENOMEM);
break;
}
reg_notify_req = malloc(sizeof(ts_register_notification_temp_req_msg_v01));
if (reg_notify_req == NULL) {
msg("%s: Malloc reg_notify_req failure", __func__);
ret = -(ENOMEM);
break;
}
reg_notify_resp = malloc(sizeof(ts_register_notification_temp_resp_msg_v01));
if (reg_notify_resp == NULL) {
msg("%s: Malloc reg_notify_resp failure", __func__);
ret = -(ENOMEM);
break;
}
memset(list_resp, 0, sizeof(ts_get_sensor_list_resp_msg_v01));
rc = qmi_client_send_msg_sync(clnt,
QMI_TS_GET_SENSOR_LIST_REQ_V01,
NULL, 0,
list_resp, sizeof(ts_get_sensor_list_resp_msg_v01), 0);
if (rc == QMI_NO_ERR) {
for (i = 0; i < list_resp->sensor_list_len; i++) {
if (0 == strncasecmp(QMI_SENSOR_MODEM,
list_resp->sensor_list[i].sensor_id,
QMI_TS_SENSOR_ID_LENGTH_MAX_V01)) {
/* found matching device name */
ret = 0;
}
if (func_exec_count) {
/* Chances are the service reset, so send out
current temp notify request to get clients to configure
threshold triggers again.*/
modem_ts_reg_notify(clnt, list_resp->sensor_list[i].sensor_id,
1, 0, 0, 0, 0);
}
}
} else {
msg("%s: QMI send_msg_sync failed with error %d", __func__, rc);
ret = -(EFAULT);
}
} while (0);
if (list_resp != NULL)
free(list_resp);
if (reg_notify_req != NULL)
free(reg_notify_req);
if (reg_notify_resp != NULL)
free(reg_notify_resp);
func_exec_count++;
return ret;
}
/*===========================================================================
LOCAL FUNCTION fusion_qmi_register
Helper function to initialize QMI connection to modem service.
ARGUMENTS
None.
RETURN VALUE
NULL on exit
===========================================================================*/
static void *fusion_qmi_register(void *data)
{
int rc;
qmi_cci_os_signal_type os_params;
qmi_service_info info;
qmi_client_type notifier = NULL;
void *modem_clnt_local = NULL;
qmi_service_instance instance_id = QMI_CLIENT_QMUX_RMNET_USB_INSTANCE_0;
/* release any old handles for fusion_modem_clnt */
if (fusion_modem_clnt) {
qmi_client_release(fusion_modem_clnt);
fusion_modem_clnt = NULL;
}
do {
rc = qmi_client_notifier_init(ts_service_object, &os_params, &notifier);
if (rc != QMI_NO_ERR) {
msg("qmi: qmi_client_notifier_init failed.\n");
break;
}
info("qmi: Instance id %d for fusion TS", instance_id);
while (1) {
QMI_CCI_OS_SIGNAL_CLEAR(&os_params);
rc = qmi_client_get_service_instance(ts_service_object,
instance_id,
&info);
if (rc == QMI_NO_ERR)
break;
/* wait for server to come up */
QMI_CCI_OS_SIGNAL_WAIT(&os_params, 0);
};
rc = qmi_client_init(&info, ts_service_object, qmi_ts_ind_cb, NULL, NULL,
(qmi_client_type *) (&modem_clnt_local));
if (rc != QMI_NO_ERR) {
msg("Modem thermal sensor service not available.\n");
break;
}
/* Verify modem sensor service present on modem */
rc = modem_verify_ts_device(modem_clnt_local);
if (rc != 0) {
qmi_client_release(modem_clnt_local);
modem_clnt_local = NULL;
break;
}
/* best effort register for error */
qmi_client_register_error_cb(modem_clnt_local, modem_clnt_error_cb, NULL);
fusion_modem_clnt = modem_clnt_local;
/* notify waiting threads */
pthread_mutex_lock(&fusion_modem_mtx);
fusion_modem_qmi_ts_ready = 1;
pthread_cond_broadcast(&fusion_modem_cond);
pthread_mutex_unlock(&fusion_modem_mtx);
info("Modem thermal sensor service available.\n");
} while (0);
if (notifier != NULL)
qmi_client_release(notifier);
return NULL;
}
/*===========================================================================
LOCAL FUNCTION modem_clnt_error_cb
Callback function called by the QCCI infrastructure when it receives a
REMOVE SERVER message from the modem.
ARGUMENTS
None.
RETURN VALUE
None.
===========================================================================*/
static void modem_clnt_error_cb(qmi_client_type clnt,
qmi_client_error_type error,
void *error_cb_data)
{
info("%s: with %d called for clnt %p\n", __func__, error, (void *)clnt);
if (clnt == NULL)
return;
if (clnt == fusion_modem_clnt) {
pthread_mutex_lock(&fusion_modem_mtx);
fusion_modem_qmi_ts_ready = 0;
pthread_mutex_unlock(&fusion_modem_mtx);
pthread_join(fusion_qmi_register_thread, NULL);
pthread_create(&fusion_qmi_register_thread, NULL,
fusion_qmi_register, NULL);
}
}
/*===========================================================================
LOCAL FUNCTION modem_ts_reg_notify
Common TS qmi modem register notify function.
ARGUMENTS
clnt - client on which to request throttling
sensor_id - name of sensor_id
send_current_temp_report - 1 for trigger and immediate sensor reading,
0 for set threshold.
high_thresh
low_thresh
RETURN VALUE
0 on success, -(ERRNO) on failure.
===========================================================================*/
static int modem_ts_reg_notify(void *clnt, const char *sensor_id,
int send_current_temp_report,
int high_valid,
int high_thresh,
int low_valid,
int low_thresh)
{
int ret = -(EPERM);
qmi_client_error_type qmi_error = QMI_NO_ERR;
ts_register_notification_temp_req_msg_v01 data_req;
ts_register_notification_temp_resp_msg_v01 data_resp;
if (!clnt || !sensor_id)
return -(EINVAL);
memset(&data_req, 0x0, sizeof(data_req));
strlcpy(data_req.sensor_id.sensor_id, sensor_id,
QMI_TS_SENSOR_ID_LENGTH_MAX_V01);
if (send_current_temp_report) {
data_req.send_current_temp_report = 1;
} else {
data_req.temp_threshold_high_valid = high_valid;
data_req.temp_threshold_high = (float)high_thresh;
data_req.temp_threshold_low_valid = low_valid;
data_req.temp_threshold_low = (float)low_thresh;
}
qmi_error = qmi_client_send_msg_sync((qmi_client_type) clnt,
QMI_TS_REGISTER_NOTIFICATION_TEMP_REQ_V01,
&data_req, sizeof(data_req),
&data_resp, sizeof(data_resp), 0);
if (qmi_error == QMI_NO_ERR) {
ret = 0;
} else {
msg("qmi: qmi_client_send_msg_sync failed. Error %d\n", qmi_error);
}
return ret;
}
/*===========================================================================
FUNCTION modem_ts_qmi_init
Helper function to initialize TS qmi communication to modem.
ARGUMENTS
None.
RETURN VALUE
0 on success, -(ERRNO) on failure.
===========================================================================*/
int modem_ts_qmi_init(void)
{
/* Get the service object for the ts API */
ts_service_object = ts_get_service_object_v01();
if (!ts_service_object) {
msg("qmi: ts_get_service_object failed.\n");
return -(EPERM);
}
/* start thread to register with QMI services */
pthread_create(&fusion_qmi_register_thread, NULL, fusion_qmi_register, NULL);
return 0;
}
/*===========================================================================
FUNCTION modem_ts_temp_request
Function to request sensor read or notify threshold functionality.
ARGUMENTS
sensor_id - name of sensor_id
send_current_temp_report - 1 for trigger and immediate sensor reading, 0 for
set threshold.
high_valid
high_thresh
low_valid
low_thresh
RETURN VALUE
0 on success, -(ERRNO) on failure.
===========================================================================*/
int modem_ts_temp_request(const char *sensor_id,
int send_current_temp_report,
int high_valid,
int high_thresh,
int low_valid,
int low_thresh)
{
int ret = -(EPERM);
if ((send_current_temp_report == 0) && ((high_valid == 1) &&
(low_valid == 1)) &&
(high_thresh <= low_thresh)) {
msg("Invalid thresh level. High %d, Low %d", high_thresh,
low_thresh);
return -(EINVAL);
}
/* Make sure the QMI connection is established before proceeding. */
pthread_mutex_lock(&fusion_modem_mtx);
while (!fusion_modem_qmi_ts_ready)
pthread_cond_wait(&fusion_modem_cond, &fusion_modem_mtx);
pthread_mutex_unlock(&fusion_modem_mtx);
if (!fusion_modem_clnt) {
msg("Modem TS service failed - QMI registration incomplete");
return ret;
}
ret = modem_ts_reg_notify(fusion_modem_clnt, sensor_id, send_current_temp_report,
high_valid,
high_thresh,
low_valid,
low_thresh);
dbgmsg("%s %s, sensor %s, Get Immediate: %s, High valid: %s, High %d "
"Low valid: %s, Low %d\n",
__func__, (ret) ? ("Failed") : ("Success"), sensor_id,
(send_current_temp_report) ? ("YES") : ("NO"),
(high_valid) ? ("YES") : ("NO"), high_thresh,
(low_valid) ? ("YES") : ("NO"), low_thresh);
return ret;
}
/*===========================================================================
FUNCTION modem_qmi_ts_comm_release
Release function for modem communication to clean up resources.
Called after use of client handles is complete.
ARGUMENTS
None.
RETURN VALUE
0 on success, -(ERRNO) on failure.
===========================================================================*/
int modem_qmi_ts_comm_release(void)
{
int rc;
int ret = 0;
pthread_join(fusion_qmi_register_thread, NULL);
if (fusion_modem_clnt) {
rc = qmi_client_release(fusion_modem_clnt);
if (rc) {
msg("qmi: qmi_client_release modem clnt failed.\n");
ret = -(EPERM);
}
fusion_modem_clnt = 0;
}
return ret;
}

View File

@@ -1,242 +0,0 @@
/*===========================================================================
pm8821-sensor.c
DESCRIPTION
pm8821 temperature alarm access functions.
INITIALIZATION AND SEQUENCING REQUIREMENTS
setup() function should be called before get_temperature().
shutdown() function should be called to clean up resources.
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <pthread.h>
#include <poll.h>
#include "pm8821-sensor.h"
#include "thermal.h"
/* Stage 2 Alarm thresholds */
#define PM8821_STAGE_2_TEMP_TRIG 127
#define PM8821_STAGE_2_TEMP_CLR 123
struct pmic_data {
pthread_t pmic_thread;
pthread_mutex_t pmic_mutex;
pthread_cond_t pmic_condition;
int threshold_reached;
int temp_idx;
int sensor_shutdown;
sensor_t *sensor;
} pmic_data;
static void *pmic_uevent(void *data)
{
int err = 0;
sensor_t *sensor = (sensor_t *)data;
struct pollfd fds;
int fd;
char uevent[MAX_PATH] = {0};
char buf[MAX_PATH] = {0};
struct pmic_data *pmic = NULL;
if (NULL == sensor ||
NULL == sensor->data) {
msg("%s: unexpected NULL", __func__);
return NULL;
}
pmic = (struct pmic_data *) sensor->data;
/* Looking for pmic uevent */
snprintf(uevent, MAX_PATH, TZ_TYPE, pmic->sensor->tzn);
fd = open(uevent, O_RDONLY);
if (fd < 0) {
msg("Unable to open %s to receive notifications.\n", uevent);
return NULL;
};
while (!pmic->sensor_shutdown) {
fds.fd = fd;
fds.events = POLLERR|POLLPRI;
fds.revents = 0;
err = poll(&fds, 1, -1);
if (err == -1) {
msg("Error in uevent poll.\n");
break;
}
read(fd, buf, sizeof(buf));
lseek(fd, 0, SEEK_SET);
dbgmsg("pmic uevent :%s", buf);
/* notify the waiting threads */
pthread_mutex_lock(&(pmic->pmic_mutex));
pmic->threshold_reached = 1;
pthread_cond_broadcast(&(pmic->pmic_condition));
pthread_mutex_unlock(&(pmic->pmic_mutex));
}
close(fd);
return NULL;
}
void pm8821_interrupt_wait(sensor_setting_t *setting)
{
struct pmic_data *pmic;
if (NULL == setting ||
NULL == setting->sensor ||
NULL == setting->sensor->data) {
msg("%s: unexpected NULL", __func__);
return;
}
pmic = (struct pmic_data *) setting->sensor->data;
if (setting->sensor->interrupt_enable) {
/* Wait for sensor threshold condition */
pthread_mutex_lock(&(pmic->pmic_mutex));
while (!pmic->threshold_reached) {
pthread_cond_wait(&(pmic->pmic_condition),
&(pmic->pmic_mutex));
}
pmic->threshold_reached = 0;
pthread_mutex_unlock(&(pmic->pmic_mutex));
}
}
void pm8821_hotpug_threshold_override_default(sensor_setting_t *setting)
{
int j;
if (setting == NULL) {
msg("pm8821_tz:unexpected NULL");
return;
}
if (setting->desc == NULL)
setting->desc = sensor_names[setting->id];
for (j = 0; hotplug_map[j].sensor_name != NULL; j++) {
if (!strcmp(hotplug_map[j].sensor_name, setting->desc))
break;
}
if (hotplug_map[j].sensor_name == NULL) {
msg("Hotplug_map for pm8821_tz is not configured");
return;
}
setting->hotplug_lvl_trig = PM8821_STAGE_2_TEMP_TRIG;
setting->hotplug_lvl_clr = PM8821_STAGE_2_TEMP_CLR;
dbgmsg("pm8821_tz hotplug thresholds Override default");
if (!setting->num_thresholds) {
setting->num_thresholds = 1;
setting->t[0].lvl_trig = CONV(PM8821_STAGE_2_TEMP_TRIG);
setting->t[0].lvl_clr = CONV(PM8821_STAGE_2_TEMP_CLR);
}
}
/* pm8821_tz sensor specific set up */
int pm8821_setup(sensor_setting_t *setting, sensor_t *sensor)
{
int fd = -1;
int sensor_count = 0;
int tzn = 0;
char name[MAX_PATH] = {0};
struct pmic_data *pmic = NULL;
if (setting == NULL) {
msg("pm8821_tz:unexpected NULL");
return 0;
}
tzn = get_tzn(sensor->name);
if (tzn < 0) {
msg("No thermal zone device found in the kernel for sensor %s\n", sensor->name);
return sensor_count;
}
sensor->tzn = tzn;
/* Allocate pmic data */
pmic = (struct pmic_data *) malloc(sizeof(struct pmic_data));
if (NULL == pmic) {
msg("%s: malloc failed", __func__);
return sensor_count;
}
memset(pmic, 0, sizeof(pmic_data));
sensor->data = (void *) pmic;
pmic->sensor = sensor;
snprintf(name, MAX_PATH, TZ_TEMP, sensor->tzn);
fd = open(name, O_RDONLY);
if (fd < 0) {
msg("%s: Error opening %s\n", __func__, name);
free(pmic);
return sensor_count;
}
pmic->temp_idx = fd;
sensor_count++;
pthread_mutex_init(&(pmic->pmic_mutex), NULL);
pthread_cond_init(&(pmic->pmic_condition), NULL);
pmic->sensor_shutdown = 0;
pmic->threshold_reached = 0;
setting->disabled = 0;
/* Override default hotplug thresholds with pm8821 stage 2 alarm values */
pm8821_hotpug_threshold_override_default(setting);
if (sensor->interrupt_enable) {
pthread_create(&(pmic->pmic_thread), NULL,
pmic_uevent, sensor);
}
return sensor_count;
}
int pm8821_get_temperature(sensor_setting_t *setting)
{
struct pmic_data *pmic;
int temp = 0;
char buf[MAX_PATH] = {0};
if (NULL == setting) {
msg("%s: unexpected NULL", __func__);
return 0;
}
pmic = (struct pmic_data *) setting->sensor->data;
if (read(pmic->temp_idx, buf, sizeof(buf) - 1) != -1)
temp = atoi(buf);
lseek(pmic->temp_idx, 0, SEEK_SET);
temp /= 1000;
return CONV(temp);
}
void pm8821_shutdown(sensor_setting_t *setting)
{
struct pmic_data *pmic;
if (NULL == setting ||
NULL == setting->sensor ||
NULL == setting->sensor->data) {
msg("%s: unexpected NULL", __func__);
return;
}
pmic = (struct pmic_data *) setting->sensor->data;
pmic->sensor_shutdown = 1;
if (setting->sensor->interrupt_enable)
pthread_join(pmic->pmic_thread, NULL);
free(pmic);
}

View File

@@ -1,19 +0,0 @@
/*===========================================================================
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#ifndef __PM8821_SENSOR_H__
#define __PM8821_SENSOR_H__
#include "thermal.h"
int pm8821_setup(sensor_setting_t *setting, sensor_t *sensor);
void pm8821_shutdown(sensor_setting_t *setting);
int pm8821_get_temperature(sensor_setting_t *setting);
void pm8821_interrupt_wait(sensor_setting_t *setting);
extern hotplug_map_t *hotplug_map;
#endif /* __PM8821_SENSOR_H__ */

View File

@@ -1,372 +0,0 @@
/*===========================================================================
qmi-ts-sensor.c
DESCRIPTION
QMI TS sensor access functions.
INITIALIZATION AND SEQUENCING REQUIREMENTS
qmi_ts_setup() function should be called before qmi_ts_get_temperature().
qmi_ts_shutdown() function should be called to clean up resources.
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include "thermal.h"
#include "thermal_sensor_service_v01.h"
#include "qmi_client.h"
#include "qmi_idl_lib.h"
/* Specific qmi_ts sensor data */
typedef struct {
pthread_mutex_t mutex;
pthread_cond_t condition;
int init_thresh_set;
int threshold_reached;
int hi_idx, lo_idx;
sensor_t *sensor;
} qmi_ts_data;
/* Help track individual sensors for setup, shutdown, and updates. */
typedef struct {
const char *thermald_name;
const char *ts_qmi_name;
int last_read;
qmi_ts_data *data;
} qmi_ts_thermald_data;
/* Used to protect access of thermald_info */
static pthread_mutex_t qmi_ts_info_mtx = PTHREAD_MUTEX_INITIALIZER;
/* Add newly supported sensors here. */
static qmi_ts_thermald_data thermald_info[] = {
{"pa_therm0", "pa", 0, NULL},
{"pa_therm1", "pa_1", 0, NULL}
};
#define QMI_TS_MAX_STRING 16
void qmi_ts_update_thresholds(sensor_setting_t *setting,
int threshold_type, int level);
/*===========================================================================
LOCAL FUNCTION qmi_ts_get_thermald_info_idx
Helper function for finding thermald_info index of information based off of
thermald sensor name..
ARGUMENTS
sensor - Thermald version of sensor name.
RETURN VALUE
-1 on Failure, thermald_info array idx on Success.
===========================================================================*/
static int qmi_ts_get_thermald_info_idx(const char *sensor)
{
int idx = -1;
/* Find corresponding qmi_ts_thermald_data */
for (idx = 0; idx < ARRAY_SIZE(thermald_info); idx++) {
if (strncmp(thermald_info[idx].thermald_name, sensor,
QMI_TS_MAX_STRING) == 0) {
break;
}
}
if (idx == ARRAY_SIZE(thermald_info))
idx = -1;
return idx;
}
/*===========================================================================
FUNCTION qmi_ts_update_temperature
Updates the temperature for the thermald_info array.
ARGUMENTS
sensor - QMI TS version of sensor name.
RETURN VALUE
None
===========================================================================*/
void qmi_ts_update_temperature(const char *sensor, int temperature)
{
int idx = 0;
if (NULL == sensor) {
msg("%s: unexpected NULL", __func__);
return;
}
/* Find corresponding qmi_ts_data */
for (idx = 0; idx < ARRAY_SIZE(thermald_info); idx++) {
if (strncmp(thermald_info[idx].ts_qmi_name, sensor,
QMI_TS_MAX_STRING) == 0) {
break;
}
}
if (idx >= ARRAY_SIZE(thermald_info)) {
msg("%s: unknown sensor %s\n", __func__, sensor);
return;
}
thermald_info[idx].last_read = temperature;
pthread_mutex_lock(&qmi_ts_info_mtx);
if (thermald_info[idx].data != NULL) {
qmi_ts_data *qmi_ts = thermald_info[idx].data;
dbgmsg("Sensor update recieved :%s %d", sensor, temperature);
/* notify the waiting thread */
pthread_mutex_lock(&(qmi_ts->mutex));
qmi_ts->threshold_reached = 1;
pthread_cond_broadcast(&(qmi_ts->condition));
pthread_mutex_unlock(&(qmi_ts->mutex));
}
pthread_mutex_unlock(&qmi_ts_info_mtx);
}
/*===========================================================================
FUNCTION qmi_ts_setup
QMI TS setup sensor.
ARGUMENTS
setting - thermald sensor setting
sensor - thermald sensor data
RETURN VALUE
0 on Failure, 1 on Success
===========================================================================*/
int qmi_ts_setup(sensor_setting_t *setting, sensor_t *sensor)
{
qmi_ts_data *qmi_ts = NULL;
int idx;
/* We have nothing to do if there are no thresholds */
if (!setting->num_thresholds) {
dbgmsg("No thresholds for sensor %s\n", sensor->name);
return 0;
}
idx = qmi_ts_get_thermald_info_idx(sensor->name);
if (idx < 0) {
msg("%s: invalid sensor name %s", __func__, sensor->name);
return 0;
}
/* Allocate QMI TS data */
qmi_ts = (qmi_ts_data *) malloc(sizeof(qmi_ts_data));
if (NULL == qmi_ts) {
msg("%s: malloc failed", __func__);
return 0;
}
memset(qmi_ts, 0, sizeof(qmi_ts_data));
sensor->data = (void *) qmi_ts;
pthread_mutex_init(&(qmi_ts->mutex), NULL);
pthread_cond_init(&(qmi_ts->condition), NULL);
qmi_ts->threshold_reached = 0;
qmi_ts->init_thresh_set = 0;
qmi_ts->sensor = sensor;
setting->disabled = 0;
thermald_info[idx].data = qmi_ts;
return 1;
}
/*===========================================================================
FUNCTION qmi_ts_shutdown
QMI TS shutdown sensor.
ARGUMENTS
setting - thermald sensor setting
RETURN VALUE
None
===========================================================================*/
void qmi_ts_shutdown(sensor_setting_t *setting)
{
qmi_ts_data *qmi_ts;
int idx;
if (NULL == setting ||
NULL == setting->sensor ||
NULL == setting->sensor->name ||
NULL == setting->sensor->data) {
msg("%s: unexpected NULL", __func__);
return;
}
idx = qmi_ts_get_thermald_info_idx(setting->sensor->name);
if (idx < 0) {
msg("%s: invalid sensor name %s", __func__,
setting->sensor->name);
return;
}
pthread_mutex_lock(&qmi_ts_info_mtx);
/* Make sure an indication cannot be issued to a sensor being shutdown */
qmi_ts = thermald_info[idx].data;
thermald_info[idx].data = NULL;
setting->sensor->data = NULL;
pthread_mutex_unlock(&qmi_ts_info_mtx);
pthread_mutex_destroy(&qmi_ts->mutex);
pthread_cond_destroy(&qmi_ts->condition);
free(qmi_ts);
}
/*===========================================================================
FUNCTION qmi_ts_get_temperature
QMI TS get sensor temperature.
ARGUMENTS
setting - thermald sensor setting
RETURN VALUE
Current temperature, CONV(-273) on failure
===========================================================================*/
int qmi_ts_get_temperature(sensor_setting_t *setting)
{
int temp = -273;
int idx;
qmi_ts_data *qmi_ts;
if (NULL == setting ||
NULL == setting->sensor ||
NULL == setting->sensor->name ||
NULL == setting->sensor->data) {
msg("%s: unexpected NULL", __func__);
return CONV(temp);
}
idx = qmi_ts_get_thermald_info_idx(setting->sensor->name);
if (idx < 0) {
msg("%s: invalid sensor name %s", __func__,
setting->sensor->name);
return CONV(temp);
}
temp = thermald_info[idx].last_read;
return CONV(temp);
}
/*===========================================================================
FUNCTION qmi_ts_interrupt_wait
QMI TS sensor wait for interrupt.
ARGUMENTS
setting - thermald sensor setting
RETURN VALUE
None
===========================================================================*/
void qmi_ts_interrupt_wait(sensor_setting_t *setting)
{
qmi_ts_data *qmi_ts;
if (NULL == setting ||
NULL == setting->sensor ||
NULL == setting->sensor->data) {
msg("%s: unexpected NULL", __func__);
return;
}
if (setting->sensor->interrupt_enable) {
qmi_ts = (qmi_ts_data *) setting->sensor->data;
if (qmi_ts->init_thresh_set == 0) {
/* Set first threshold to trigger. */
qmi_ts_update_thresholds(setting, THRESHOLD_NOCHANGE, 0);
qmi_ts->init_thresh_set = 1;
}
/* Wait for sensor threshold condition */
pthread_mutex_lock(&(qmi_ts->mutex));
while (!qmi_ts->threshold_reached) {
pthread_cond_wait(&(qmi_ts->condition),
&(qmi_ts->mutex));
}
qmi_ts->threshold_reached = 0;
pthread_mutex_unlock(&(qmi_ts->mutex));
}
}
/*===========================================================================
FUNCTION qmi_ts_update_thresholds
QMI TS sensor update interrupt thresholds.
ARGUMENTS
setting - thermald sensor setting
threshold_type - type of threshold change that triggered update
level - current settings level
RETURN VALUE
None
===========================================================================*/
void qmi_ts_update_thresholds(sensor_setting_t *setting,
int threshold_type, int level)
{
int hi, lo;
int hi_enable = 1;
int lo_enable = 1;
int idx;
qmi_ts_data *qmi_ts;
if (NULL == setting ||
NULL == setting->sensor ||
NULL == setting->sensor->data ||
NULL == setting->sensor->name) {
msg("%s: unexpected NULL", __func__);
return;
}
qmi_ts = (qmi_ts_data *) setting->sensor->data;
idx = qmi_ts_get_thermald_info_idx(setting->sensor->name);
if (idx < 0) {
msg("%s: invalid sensor name %s", __func__, setting->sensor->name);
return;
}
dbgmsg("%s: threshold_type %d, level %d", __func__,
threshold_type, level);
hi = RCONV(setting->t[qmi_ts->hi_idx].lvl_trig);
lo = RCONV(setting->t[qmi_ts->lo_idx].lvl_clr);
if (level >= setting->num_thresholds) {
/* handle corner high case */
hi = RCONV(setting->t[setting->num_thresholds - 1].lvl_trig);
qmi_ts->hi_idx = setting->num_thresholds - 1;
hi_enable = 0;
} else {
hi = RCONV(setting->t[level].lvl_trig);
qmi_ts->hi_idx = level;
}
if (level <= 0) {
/* handle corner low case */
lo = RCONV(setting->t[0].lvl_clr);
qmi_ts->lo_idx = 0;
lo_enable = 0;
} else {
lo = RCONV(setting->t[level - 1].lvl_clr);
qmi_ts->lo_idx = level - 1;
}
modem_ts_temp_request(thermald_info[idx].ts_qmi_name, 0,
hi_enable, hi, lo_enable, lo);
}

View File

@@ -1,20 +0,0 @@
/*===========================================================================
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#ifndef __QMI_TS_SENSOR_H__
#define __QMI_TS_SENSOR_H__
#include "thermal.h"
int qmi_ts_setup(sensor_setting_t *settings, sensor_t * sensor);
void qmi_ts_shutdown(sensor_setting_t *setting);
int qmi_ts_get_temperature(sensor_setting_t *setting);
void qmi_ts_interrupt_wait(sensor_setting_t *setting);
void qmi_ts_update_thresholds(sensor_setting_t *setting, int threshold_type, int level);
void qmi_ts_update_temperature(const char *sensor, int temperature);
#endif /* __QMI_TS_SENSOR_H__ */

View File

@@ -1,173 +0,0 @@
/*===========================================================================
Copyright (c) 2011-2012 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
Thermal Daemon
~~~~~~~~~~~~~~
This daemon monitors thermal/temperature sensor data and performs
actions based on a configuration file (default is /etc/thermald.conf).
A sample configuration file is provided (thermald.conf_sample).
Configuration file format:
~~~~~~~~~~~~~~~~~~~~~~~~~~
{debug}
sampling <default sampling rate in ms>
[<temperature sensor section>]
sampling <sampling rate in ms>
thresholds <threshold values in degree Celsius> ...
thresholds_clr <temperature value to clear thresholds> ...
actions <action to perform at threshold;
multiple actions separated by '+'> ...
action_info <additional info for action;
multiple action_info separated by '+'> ...
* Optional 'debug' flag determines if debug logging is enabled.
* 'thresholds'/'thresholds_clr'/'actions'/'action_info' accepts a list of
space separated values for up to 8 thresholds.
'actions' field
---------------
* 'none' ;
- ACTION - Do nothing
- ACTION_INFO - ignored
* 'report'
- ACTION - Report threshold crossing to UI
- ACTION_INFO - ignored
- NOTES - The threshold crossing information is sent across an
abstract local socket "THERMALD_UI" in newline-separated
string format. Report action runs upon clearing or
triggering a level, slightly different from the other
actions which are run upon reaching the level, e.g.
clearing level n+1 or triggering level n.
Parameters are sent in the following order.
* sensorname - Name of sensor reporting
* temperature - Current temperature
* current_threshold_level - current threshold level triggered or cleared
* is_trigger - "true" on level trigger, "false" on level clearing
Example Android code to listen to this notification is
provided in the documentation folder.
* 'cpu'
- ACTION - CPU frequency scaling
- ACTION_INFO - Max CPU frequency in KHz
* 'lcd'
- ACTION - LCD brightness throttling
- ACTION_INFO - 0-255 value for max LCD brightness
* 'modem'
- ACTION - Request throttling of modem functionality
- ACTION_INFO - 0-3 throttling level for modem mitigation
* 'fusion'
- ACTION - Request throttling of fusion modem functionality
- ACTION_INFO - 0-3 throttling level for fusion modem mitigation
* 'battery'
- ACTION - Battery charging current throttling
- ACTION_INFO - 0-3 throttling level for battery charging current
* 'gpu'
- ACTION - GPU frequency scaling
- ACTION_INFO - Max GPU frequency in Hz
* 'wlan'
- ACTION - WLAN throttling
- ACTION_INFO - 0-4 throttling level for WLAN mitigation
* 'camera'
- ACTION - CAMERA throttling
- ACTION_INFO - 0-3 throttling level for CAMERA mitigation
* 'camcorder'
- ACTION - CAMCORDER throttling
- ACTION_INFO - 0-3 throttling level for CAMCORDER mitigation
* 'shutdown'
- ACTION - Shutdown target
- ACTION_INFO - Shutdown delay in ms
Example 1:
----------
sampling 1000
[PMIC_THERM]
sampling 5000
thresholds 40.2 45 50
thresholds_clr 38 43 48
actions cpu+report cpu cpu
action_info 1188000+0 368640 245760
Description:
1) Default sampling rate of 1 second.
For sensor 'PMIC_THERM', sample at 5 second rate (overrides default):
2) Threshold level 1 triggered at 40.2 deg C; clears if temperature drops
to/below 38 deg C. When triggered, adjust maximum allowed CPU to
1188000 KHz, which in this example is already the current maximum
frequency, and results in no action.
Also generate a report, action_info value 0 is ignored.
3) Threshold level 2 triggered at 45 deg C; clears if temperature drops
to/below 43 deg C. When triggered, adjust maximum allowed CPU to
368640 KHz.
4) When threshold level 2 cleared at 43 deg C; adjust CPU back to maximum
frequency 1188000 KHz.
5) When threshold level 1 cleared at 38 deg C; generate a report for level 1
clearing, all mitigation is reset.
Example 2:
----------
debug
sampling 2000
[PMIC_THERM]
sampling 5000
thresholds 40.2 45 50
thresholds_clr 38 43 48
actions cpu+report cpu report+shutdown
action_info 768000+0 368640 0+6000
Description:
1) Debug logging output is enabled.
2) Default sampling rate of 2 second.
For sensor 'PMIC_THERM', sample at 5 second rate (overrides default):
3) Threshold level 1 triggered at 40.2 deg C; clears if temperature drops
to/below 38 deg C. When triggered, adjust maximum allowed CPU to 768000 KHz,
and generate a report (action_info value 0 is ignored).
4) Threshold level 2 triggered at 45 deg C; clears if temperature drops
to/below 43 deg C. When triggered, adjust maximum allowed CPU to 368640 KHz.
5) Threshold level 3 triggered at 50 deg C; clears if temperature drops
to/below 48 deg C. When triggered, generate a report and shutdown the
target after a delay of 6 seconds.
Example 3:
----------
debug
sampling 2000
[bcl]
sampling 1000
thresholds 100 0
thresholds_clr 500 100
actions report report
action_info 0 0
Description:
1) Debug logging output is enabled.
2) Default sampling rate of 2 second.
For battery current limit 'bcl', sample at 1 second rate (overrides default):
3) Threshold level 1 triggered if ibat is at (imax - 100mA); clears if ibat drops
to/below (imax - 500mA). When triggered, generate a report (action_info value 0 is ignored).
4) Threshold level 2 triggered if ibat is at imax; clears if ibat drops
to/below (imax - 100mA). When triggered, generate a report (action_info value 0 is ignored).

View File

@@ -1,159 +0,0 @@
/*===========================================================================
Copyright (c) 2010-2011 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <pthread.h>
#include <linux/msm_adc.h>
#include "thermal.h"
#include "sensors-hw.h"
#define MSM_ADC_NODE "/dev/msm_adc"
#define POP_MEM_NODE "/sys/devices/virtual/thermal/thermal_zone0/temp"
char *sensor_names[] =
{
"PMIC_THERM",
"XO_THERM",
"XO_THERM_GPS",
"POP_MEM_TZ",
};
static int adc_fd = -1;
static int pop_mem_fd = 0;
int sensors_setup(thermal_setting_t *settings)
{
struct msm_adc_lookup lookup;
int i = 0;
int rc, numEnabled = 0;
adc_fd = open(MSM_ADC_NODE, O_RDWR);
if (adc_fd < 0) {
msg("Error opening %s\n", MSM_ADC_NODE);
i = POP_MEM_TZ;
}
for (; i < POP_MEM_TZ; i++) {
memset(&lookup, 0, sizeof(lookup));
strlcpy(lookup.name, sensor_names[i], MSM_ADC_MAX_CHAN_STR);
lookup.name[MSM_ADC_MAX_CHAN_STR-1] = '\0';
rc = ioctl(adc_fd, MSM_ADC_LOOKUP, &lookup);
if (rc < 0) {
msg("Error looking up '%s', skipping\n", sensor_names[i]);
settings->sensors[i].disabled = 1;
continue;
}
settings->sensors[i].chan_idx = lookup.chan_idx;
settings->sensors[i].disabled = 0;
numEnabled++;
dbgmsg("Sensor '%s' -> channel '%u'\n",
sensor_names[i], lookup.chan_idx);
}
pop_mem_fd = open(POP_MEM_NODE, O_RDONLY);
if (pop_mem_fd > 0) {
settings->sensors[i].chan_idx = pop_mem_fd;
settings->sensors[i].disabled = 0;
numEnabled++;
} else {
msg("Error(%d) opening %s\n", pop_mem_fd, POP_MEM_NODE);
settings->sensors[i].chan_idx = -1;
settings->sensors[i].disabled = 1;
}
return (numEnabled > 0) ? 1 : 0;
}
void sensors_shutdown()
{
if (adc_fd != -1)
close(adc_fd);
adc_fd = -1;
if (pop_mem_fd != -1)
close(pop_mem_fd);
pop_mem_fd = -1;
}
int sensor_threshold_trigger(int value, sensor_setting_t *sensor, int level)
{
if (value >= sensor->t[level].lvl_trig)
return 1;
else
return 0;
}
int sensor_threshold_clear(int value, sensor_setting_t *sensor, int level)
{
if (value <= sensor->t[level].lvl_clr)
return 1;
else
return 0;
}
int sensor_get_temperature(sensor_setting_t *sensor)
{
int rc = 0;
struct msm_adc_conversion conv;
if (sensor->id == POP_MEM_TZ) {
char buf[30] = {0};
int temp = 0;
lseek(sensor->chan_idx, 0, SEEK_SET);
read(sensor->chan_idx, buf, sizeof(buf) - 1);
temp = strtol(buf, NULL, 10);
return temp;
}
memset(&conv, 0, sizeof(conv));
conv.chan = sensor->chan_idx;
if (adc_fd <= 0) {
msg("Error opening sensor '%s'\n", sensor->desc);
return -1;
}
rc = ioctl(adc_fd, MSM_ADC_REQUEST, &conv);
if (rc) {
msg("Error getting sensor info '%s'\n", sensor->desc);
} else {
dbgmsg("Sensor '%s' - %2.1f*C (%u)\n",
sensor->desc, RCONV(conv.result), conv.result);
}
return conv.result;
}
void sensor_wait(sensor_setting_t *setting)
{
static int is_first_poll = 1;
if (setting == NULL) {
msg("%s: Unexpected NULL", __func__);
return;
}
if (!is_first_poll) {
usleep(setting->sampling_period_us);
} else {
is_first_poll = 0;
}
}
void sensor_update_thresholds(sensor_setting_t *setting,
int threshold_type, int level)
{
return;
}

View File

@@ -1,223 +0,0 @@
/*===========================================================================
Copyright (c) 2010-2011 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>
#include "tsens-sensor.h"
#include "thermal.h"
char *sensor_names[] =
{
"pm8058_tz",
"tsens_tz_sensor0",
};
int pmic_sensors_setup(sensor_setting_t *settings, sensor_t* sensor);
void pmic_sensors_shutdown(sensor_setting_t *setting);
int pmic_sensor_get_temperature(sensor_setting_t *setting);
static sensor_t g_sensors[] = {
{
.name = "pm8058_tz",
.setup = pmic_sensors_setup,
.shutdown = pmic_sensors_shutdown,
.get_temperature = pmic_sensor_get_temperature,
.interrupt_wait = NULL,
.update_thresholds = NULL,
.setting = NULL,
.tzn = 1,
.data = NULL,
.interrupt_enable = 0,
},
{
.name = "tsens_tz_sensor0",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.setting = NULL,
.tzn = 3,
.data = NULL,
#ifdef ENABLE_TSENS_INTERRUPT
.interrupt_enable = 1,
#else
.interrupt_enable = 0,
#endif
},
};
/* PMIC sensor */
int pmic_sensors_setup(sensor_setting_t *setting, sensor_t* s)
{
int adc_fd = -1;
int sensor_count = 0;
char name[MAX_PATH] = {0};
int tzn = 0;
sensor_t *sensor = (sensor_t *)s;
tzn = get_tzn(sensor->name);
if (tzn < 0) {
msg("No thermal zone device found in the kernel for sensor %s\n", sensor->name);
return sensor_count;
}
sensor->tzn = tzn;
snprintf(name, MAX_PATH, TZ_TEMP, sensor->tzn);
adc_fd = open(name, O_RDONLY);
if (adc_fd > 0) {
setting->disabled = 0;
setting->chan_idx = adc_fd;
sensor_count++;
} else {
msg("pmic: Error opening %s\n", name);
}
return sensor_count;
}
void pmic_sensors_shutdown(sensor_setting_t *setting)
{
if (setting->chan_idx > 0)
close(setting->chan_idx);
}
int pmic_sensor_get_temperature(sensor_setting_t *setting)
{
char buf[10] = {0};
int temp = 0;
if (read(setting->chan_idx, buf, sizeof(buf) - 1) != -1)
temp = atoi(buf);
lseek(setting->chan_idx, 0, SEEK_SET);
return temp;
}
int sensors_setup(thermal_setting_t *settings)
{
int i = 0;
int j = 0;
int sensor_count = 0;
int ret = 0;
if (!settings)
return sensor_count;
for (i = 0; i < ARRAY_SIZE(g_sensors); i++) {
for (j = 0; j < SENSOR_IDX_MAX; j++) {
if (settings->sensors[j].desc == NULL ||
0 != strcmp(settings->sensors[j].desc, g_sensors[i].name))
continue;
info("Sensor setup:[%s]\n", g_sensors[i].name);
g_sensors[i].setting = &settings->sensors[j];
settings->sensors[j].sensor = &g_sensors[i];
ret = g_sensors[i].setup(&settings->sensors[j],
(sensor_t *)&g_sensors[i]);
sensor_count += ret;
/* TSENS sensors need separate enabling and threshold set */
if (!ret ||
0 != strcmp(g_sensors[i].name, "tsens_tz_sensor0"))
break;
tsens_sensor_enable_sensor(g_sensors[i].setting, 1);
if (g_sensors[i].interrupt_enable) {
tsens_sensor_update_thresholds(g_sensors[i].setting,
THRESHOLD_NOCHANGE, 0);
}
break;
}
}
return sensor_count;
}
void sensors_shutdown()
{
int i = 0;
for (i = 0; i < ARRAY_SIZE(g_sensors); i++) {
info("Sensor shutdown:[%s] \n", g_sensors[i].name);
g_sensors[i].shutdown(g_sensors[i].setting);
}
}
int sensor_threshold_trigger(int value, sensor_setting_t *sensor, int level)
{
if (value >= sensor->t[level].lvl_trig)
return 1;
else
return 0;
}
int sensor_threshold_clear(int value, sensor_setting_t *sensor, int level)
{
if (value <= sensor->t[level].lvl_clr)
return 1;
else
return 0;
}
int sensor_get_temperature(sensor_setting_t *setting)
{
int temp = 0;
if (setting == NULL ||
setting->sensor == NULL ||
setting->sensor->get_temperature == NULL) {
return -EFAULT;
}
temp = setting->sensor->get_temperature(setting);
dbgmsg("Sensor[%s] Temperature : %2.1f\n", setting->desc, RCONV(temp));
return temp;
}
void sensor_wait(sensor_setting_t *setting)
{
static int is_first_poll = 1;
if (setting == NULL ||
setting->sensor == NULL) {
msg("%s: Unexpected NULL", __func__);
return;
}
if (setting->sensor->interrupt_enable &&
setting->sensor->interrupt_wait) {
setting->sensor->interrupt_wait(setting);
} else if (!is_first_poll) {
usleep(setting->sampling_period_us);
} else {
is_first_poll = 0;
}
}
void sensor_update_thresholds(sensor_setting_t *setting,
int threshold_type, int level)
{
if (setting == NULL ||
setting->sensor == NULL) {
msg("%s: Unexpected NULL", __func__);
return;
}
if (setting->sensor->interrupt_enable == 0 ||
setting->sensor->update_thresholds == NULL)
return;
setting->sensor->update_thresholds(setting, threshold_type, level);
}

View File

@@ -1,991 +0,0 @@
/*===========================================================================
Copyright (c) 2011-2012 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include "qmi-ts-sensor.h"
#include "tsens-sensor.h"
#include "bcl-sensor.h"
#include "adc-sensor.h"
#include "gen-sensor.h"
#include "pm8821-sensor.h"
#include "thermal.h"
#define NUM_TSENS_SENSORS (11)
#define HOTPLUG_HIGH_THRESHOLD_8960 (100)
#define HOTPLUG_LOW_THRESHOLD_8960 (HOTPLUG_HIGH_THRESHOLD_8960 - 20)
#define HOTPLUG_HIGH_THRESHOLD_8064 (115)
#define HOTPLUG_LOW_THRESHOLD_8064 (HOTPLUG_HIGH_THRESHOLD_8064 - 20)
#define HOTPLUG_HIGH_THRESHOLD_8930 (110)
#define HOTPLUG_LOW_THRESHOLD_8930 (HOTPLUG_HIGH_THRESHOLD_8930 - 20)
#define MPDECISION_SOCKET "/dev/socket/mpdecision"
char *sensor_names[] =
{
"pm8921_tz",
"pa_therm0",
"pa_therm1",
"tsens_tz_sensor0",
"tsens_tz_sensor1",
"tsens_tz_sensor2",
"tsens_tz_sensor3",
"tsens_tz_sensor4",
"tsens_tz_sensor5",
"tsens_tz_sensor6",
"tsens_tz_sensor7",
"tsens_tz_sensor8",
"tsens_tz_sensor9",
"tsens_tz_sensor10",
"bcl",
"pm8821_tz",
};
enum hybrid_state_t {
HYBRID_STATE_MAIN_INTERRUPT,
HYBRID_STATE_POLLING
};
enum sensor_type_8960_t {
SENSOR_TYPE_NON_HYBRID,
SENSOR_TYPE_HYBRID_MAIN,
SENSOR_TYPE_HYBRID_AUX,
SENSOR_TYPE_BCL,
};
/* variables controlling hybrid polling */
pthread_cond_t hybrid_condition;
pthread_mutex_t hybrid_mutex;
enum hybrid_state_t hybrid_state;
pthread_cond_t finish_poll_condition;
pthread_mutex_t poll_count_mutex;
int poll_count = 0;
static void hybrid_main_interrupt_wait(sensor_setting_t *setting);
static void hybrid_main_update_thresholds(sensor_setting_t *setting, int threshold_type, int level);
static void hybrid_aux_interrupt_wait(sensor_setting_t *setting);
static void hybrid_aux_update_thresholds(sensor_setting_t *setting, int threshold_type, int level);
static int pa_sensor_setup(sensor_setting_t *settings, sensor_t *sensor);
static sensor_t g_sensors[] = {
{
.name = "pm8921_tz",
.setup = gen_sensors_setup,
.shutdown = gen_sensors_shutdown,
.get_temperature = gen_sensor_get_temperature,
.interrupt_wait = NULL,
.update_thresholds = NULL,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 0,
},
{
.name = "pa_therm0",
.setup = pa_sensor_setup,
.shutdown = NULL,
.get_temperature = NULL,
.interrupt_wait = NULL,
.update_thresholds = NULL,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 0,
},
{
.name = "pa_therm1",
.setup = pa_sensor_setup,
.shutdown = NULL,
.get_temperature = NULL,
.interrupt_wait = NULL,
.update_thresholds = NULL,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 0,
},
{
.name = "tsens_tz_sensor0",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = hybrid_main_interrupt_wait,
.update_thresholds = hybrid_main_update_thresholds,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor1",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = hybrid_aux_interrupt_wait,
.update_thresholds = hybrid_aux_update_thresholds,
.setting = NULL,
.tzn = 1,
.data = NULL,
.interrupt_enable = 0,
},
{
.name = "tsens_tz_sensor2",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = hybrid_aux_interrupt_wait,
.update_thresholds = hybrid_aux_update_thresholds,
.setting = NULL,
.tzn = 2,
.data = NULL,
.interrupt_enable = 0,
},
{
.name = "tsens_tz_sensor3",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = hybrid_aux_interrupt_wait,
.update_thresholds = hybrid_aux_update_thresholds,
.setting = NULL,
.tzn = 3,
.data = NULL,
.interrupt_enable = 0,
},
{
.name = "tsens_tz_sensor4",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = hybrid_aux_interrupt_wait,
.update_thresholds = hybrid_aux_update_thresholds,
.setting = NULL,
.tzn = 4,
.data = NULL,
.interrupt_enable = 0,
},
{
.name = "tsens_tz_sensor5",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = hybrid_aux_interrupt_wait,
.update_thresholds = hybrid_aux_update_thresholds,
.setting = NULL,
.tzn = 5,
.data = NULL,
.interrupt_enable = 0,
},
{
.name = "tsens_tz_sensor6",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = hybrid_aux_interrupt_wait,
.update_thresholds = hybrid_aux_update_thresholds,
.setting = NULL,
.tzn = 6,
.data = NULL,
.interrupt_enable = 0,
},
{
.name = "tsens_tz_sensor7",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = hybrid_aux_interrupt_wait,
.update_thresholds = hybrid_aux_update_thresholds,
.setting = NULL,
.tzn = 7,
.data = NULL,
.interrupt_enable = 0,
},
{
.name = "tsens_tz_sensor8",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = hybrid_aux_interrupt_wait,
.update_thresholds = hybrid_aux_update_thresholds,
.setting = NULL,
.tzn = 8,
.data = NULL,
.interrupt_enable = 0,
},
{
.name = "tsens_tz_sensor9",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = hybrid_aux_interrupt_wait,
.update_thresholds = hybrid_aux_update_thresholds,
.setting = NULL,
.tzn = 9,
.data = NULL,
.interrupt_enable = 0,
},
{
.name = "tsens_tz_sensor10",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = hybrid_aux_interrupt_wait,
.update_thresholds = hybrid_aux_update_thresholds,
.setting = NULL,
.tzn = 10,
.data = NULL,
.interrupt_enable = 0,
},
{
.name = "bcl",
.setup = bcl_setup,
.shutdown = bcl_shutdown,
.get_temperature = bcl_get_diff_imax_ibat,
.interrupt_wait = bcl_interrupt_wait,
.update_thresholds = bcl_update_thresholds,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "pm8821_tz",
.setup = pm8821_setup,
.shutdown = pm8821_shutdown,
.get_temperature = pm8821_get_temperature,
.interrupt_wait = pm8821_interrupt_wait,
.update_thresholds = NULL,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
};
/* NOTE: number of indexes in sensor_type should match g_sensors */
static enum sensor_type_8960_t sensor_type[] = {
SENSOR_TYPE_NON_HYBRID,
SENSOR_TYPE_NON_HYBRID,
SENSOR_TYPE_NON_HYBRID,
SENSOR_TYPE_HYBRID_MAIN,
SENSOR_TYPE_HYBRID_AUX,
SENSOR_TYPE_HYBRID_AUX,
SENSOR_TYPE_HYBRID_AUX,
SENSOR_TYPE_HYBRID_AUX,
SENSOR_TYPE_HYBRID_AUX,
SENSOR_TYPE_HYBRID_AUX,
SENSOR_TYPE_HYBRID_AUX,
SENSOR_TYPE_HYBRID_AUX,
SENSOR_TYPE_HYBRID_AUX,
SENSOR_TYPE_HYBRID_AUX,
SENSOR_TYPE_BCL,
SENSOR_TYPE_NON_HYBRID,
};
/* status of main sensor's threshold interrupt, toggle 0 and 1 */
static int main_sensor_hi_threshold_enabled;
/* are all sensor thresholds cleared? true/false */
static int threshold_cleared[NUM_TSENS_SENSORS] = {1,1,1,1,1,1,1,1,1,1,1};
static hotplug_map_t hotplug_map_8960[] = {
{"tsens_tz_sensor2", 0x2, TSENS_TZ_SENSOR2},
{NULL, 0x0, 0},
};
static hotplug_map_t hotplug_map_8930[] = {
{"tsens_tz_sensor6", 0x2, TSENS_TZ_SENSOR6},
{NULL, 0x0, 0},
};
static hotplug_map_t hotplug_map_8064[] = {
{"tsens_tz_sensor8", 0x2, TSENS_TZ_SENSOR8},
{"tsens_tz_sensor9", 0x4, TSENS_TZ_SENSOR9},
{"tsens_tz_sensor10", 0x8, TSENS_TZ_SENSOR10},
{"pm8821_tz", 0xC, PM8821_TZ},
{NULL, 0x0, 0},
};
hotplug_map_t *hotplug_map;
static int hotplug_high_threshold;
static int hotplug_low_threshold;
/* returns gsensor idx matching the sensor name, or -1 if error */
static int get_gsensor_idx(char *name)
{
int i;
for (i = 0; i < ARRAY_SIZE(g_sensors); i++) {
if (0 == strncmp(name, g_sensors[i].name,
SENSOR_NAME_MAX))
break;
}
return (i >= ARRAY_SIZE(g_sensors)) ? -1 : i;
}
static int all_hybrid_thresholds_cleared(void)
{
int ret = 0;
int i;
for (i = 0; i < NUM_TSENS_SENSORS; i++) {
if (threshold_cleared[i] == 0)
break;
}
if (i == NUM_TSENS_SENSORS) {
dbgmsg("All hybrid_thresholds_cleared");
ret = 1;
}
return ret;
}
static int hybrid_sensor_id(sensor_setting_t *setting)
{
int sensor_id = 0;
if (NULL == setting ||
NULL == setting->desc) {
msg("%s: Unexpected NULL", __func__);
return -1;
}
if (!sscanf(setting->desc, "tsens_tz_sensor%d", &sensor_id)) {
return -1;
} else {
return sensor_id;
}
}
/* Manually disable sensors for unconfigured sensors */
static void disable_sensor_manual(char *sensor_name)
{
int tzn = 0;
char name[MAX_PATH] = {0};
tzn = get_tzn(sensor_name);
if (tzn != -1) {
snprintf(name, MAX_PATH, TZ_MODE, tzn);
write_to_file(name, "disabled", strlen("disabled"));
dbgmsg("Sensor '%s' not configured - set disabled\n",
sensor_name);
}
}
static int sensor_is_configured(sensor_t *sensor)
{
return (sensor->setting != NULL);
}
static void hybrid_enable_auxiliary_sensors(int enabled)
{
int i;
for (i = 0; i < ARRAY_SIZE(g_sensors); i++) {
if (sensor_type[i] != SENSOR_TYPE_HYBRID_AUX)
continue;
if (sensor_is_configured(&g_sensors[i]) &&
g_sensors[i].setting->disabled == 0) {
tsens_sensor_enable_sensor(g_sensors[i].setting,
enabled);
} else if (enabled == 0 &&
!sensor_is_configured(&g_sensors[i])) {
/* disable sensor manually if unconfigured */
disable_sensor_manual(g_sensors[i].name);
}
}
}
/* request hotplug manually via sysfs.
Fallback function for hotplugging CPUs
This function should only be called in one thread per hotplug core */
static int hotplug_request_manual(int cpu, int online)
{
char node_buf[MAX_PATH] = {0};
int i = 0;
int ret = 0;
static int prev[MAX_CPUS] = {1, 1, 1, 1};
if (online != prev[cpu]) {
/* Write to offline node if present */
snprintf(node_buf, MAX_PATH, CPU_SYSFS(HOTPLUG_NODE), cpu);
if (write_to_file(node_buf, online ? "1": "0", 2) > 0) {
info("ACTION: Hotplugged %s CPU[%d]\n",
online ? "ON" : "OFF", cpu);
prev[cpu] = online;
} else {
msg("Failed to hotplug CPU[%d] at path %s\n",
cpu, node_buf);
ret = -1;
}
} else {
dbgmsg("Hotplug request already at %d\n", online);
}
return ret;
}
/* Inform mpdecision to do hotplug, else hotplug cores manually */
void hotplug_request_critical(sensor_setting_t *setting, int temp, int cpu,
int requester, int set_offline)
{
static int hotplug_off_req[MAX_CPUS][SENSOR_IDX_MAX];
static int done_hotplug[MAX_CPUS];
char tempBuf[REPORT_MSG_MAX];
static pthread_mutex_t hotplug_cpu_mtx = PTHREAD_MUTEX_INITIALIZER;
int rc = 0;
int i;
if (setting == NULL) {
msg("%s: Unexpected NULL", __func__);
return;
}
pthread_mutex_lock(&hotplug_cpu_mtx);
/* Aggregate vote for hotplug request for all sensors */
/* While online core ensure all sensors threshold is cleared for that cpu */
hotplug_off_req[cpu][requester] = set_offline;
if (set_offline == 0) {
for (i = 0; hotplug_map[i].sensor_name != NULL; i++) {
if (hotplug_off_req[cpu][hotplug_map[i].sensor_idx] != 0) {
dbgmsg("Waiting for other sensors to clear hotplug "
"threshold for cpu[%d]", cpu);
goto handle_return;
}
}
}
if (set_offline != done_hotplug[cpu]) {
info("ACTION: HOTPLUG CPU[%d] critical failsafe %s - "
"Sensor %s - temperature %d", cpu, set_offline ? "triggered" : "cleared",
setting->desc, temp);
snprintf(tempBuf, REPORT_MSG_MAX, "hotplug %d %d", cpu, !set_offline);
if (write_to_local_file_socket(MPDECISION_SOCKET, tempBuf,
strlen(tempBuf)) != (int) strlen(tempBuf)) {
/* fallback to manual hotplug update */
rc = hotplug_request_manual(cpu, !set_offline);
}
if (rc == 0)
done_hotplug[cpu] = set_offline;
}
handle_return:
pthread_mutex_unlock(&hotplug_cpu_mtx);
}
void do_hotplug_critical(sensor_setting_t *setting, int cpu,
int temperature)
{
int cpu_mask;
if (setting == NULL) {
msg("%s: Unexpected NULL", __func__);
return;
}
for (cpu_mask = 0; cpu_mask < MAX_CPUS; cpu_mask++) {
if ((cpu & (1 << cpu_mask)) == 0)
continue;
if (temperature >= setting->hotplug_lvl_trig)
hotplug_request_critical(setting, temperature,
cpu_mask, setting->id, 1);
else if (temperature <= setting->hotplug_lvl_clr)
hotplug_request_critical(setting, temperature,
cpu_mask, setting->id, 0);
}
}
static void setup_hotplug_map(thermal_setting_t *settings)
{
int j = 0;
int msm_id = therm_get_msm_id();
switch (msm_id) {
case THERM_MSM_8064AB:
case THERM_MSM_8064:
hotplug_map = hotplug_map_8064;
hotplug_high_threshold = HOTPLUG_HIGH_THRESHOLD_8064;
hotplug_low_threshold = HOTPLUG_LOW_THRESHOLD_8064;
break;
case THERM_MSM_8930AB:
case THERM_MSM_8930AA:
case THERM_MSM_8930:
hotplug_map = hotplug_map_8930;
hotplug_high_threshold = HOTPLUG_HIGH_THRESHOLD_8930;
hotplug_low_threshold = HOTPLUG_LOW_THRESHOLD_8930;
break;
case THERM_MSM_8960AB:
case THERM_MSM_8960:
default:
/* default to 8960 hotplug map */
hotplug_map = hotplug_map_8960;
hotplug_high_threshold = HOTPLUG_HIGH_THRESHOLD_8960;
hotplug_low_threshold = HOTPLUG_LOW_THRESHOLD_8960;
}
/* Assign hotplug thresholds to hotplug_lvl_trg/clr of each sensor setting */
while (hotplug_map[j].sensor_name != NULL) {
if (hotplug_map[j].sensor_idx >= SENSOR_IDX_MAX) {
j++;
continue;
}
settings->sensors[hotplug_map[j].sensor_idx].hotplug_lvl_trig =
hotplug_high_threshold;
settings->sensors[hotplug_map[j].sensor_idx].hotplug_lvl_clr =
hotplug_low_threshold;
j++;
}
}
int sensors_setup(thermal_setting_t *settings)
{
int i = 0;
int j = 0;
int save_main_i = -1;
int sensor_count = 0;
int aux_sensor_count = 0;
int save_bcl_i = -1;
if (!settings)
return sensor_count;
pthread_mutex_init(&hybrid_mutex, NULL);
pthread_cond_init(&hybrid_condition, NULL);
pthread_cond_init(&finish_poll_condition, NULL);
pthread_mutex_init(&poll_count_mutex, NULL);
hybrid_state = HYBRID_STATE_MAIN_INTERRUPT;
setup_hotplug_map(settings);
/* override hotplug limit if requested on cmdline */
if (new_corelimit) {
hotplug_high_threshold = new_corelimit;
hotplug_low_threshold = new_corelimit - 20;
}
/* Set up sensors */
for (i = 0; i < ARRAY_SIZE(g_sensors); i++) {
for (j = 0; j < SENSOR_IDX_MAX; j++) {
if (settings->sensors[j].desc == NULL ||
0 != strcmp(settings->sensors[j].desc, g_sensors[i].name))
continue;
info("Sensor setup:[%s]\n", g_sensors[i].name);
g_sensors[i].setting = &settings->sensors[j];
settings->sensors[j].sensor = &g_sensors[i];
if (g_sensors[i].setup(&settings->sensors[j],
(sensor_t *)&g_sensors[i])) {
sensor_count++;
if (sensor_type[i] == SENSOR_TYPE_HYBRID_MAIN) {
save_main_i = i;
} else if (sensor_type[i] == SENSOR_TYPE_HYBRID_AUX) {
aux_sensor_count++;
} else if (sensor_type[i] == SENSOR_TYPE_BCL) {
save_bcl_i = i;
}
}
break;
}
}
/* set up hotplug sensors if not configured */
for (i = 0; i < SENSOR_IDX_MAX; i++) {
int g_idx;
if (settings->sensors[i].disabled == 0)
continue;
j = 0;
while (hotplug_map[j].sensor_name != NULL) {
if (i != hotplug_map[j].sensor_idx) {
j++;
continue;
}
settings->sensors[i].desc = sensor_names[i];
settings->sensors[i].num_thresholds = 1;
settings->sensors[i].disabled = 0;
settings->sensors[i].sampling_period_us = 1000000; /* 1 sec */
settings->sensors[i].t[0].lvl_trig = CONV(hotplug_high_threshold);
settings->sensors[i].t[0].lvl_clr = CONV(hotplug_low_threshold);
settings->sensors[i].t[0].actions[0].action = NONE;
settings->sensors[i].t[0].actions[0].info = 0;
g_idx = get_gsensor_idx(settings->sensors[i].desc);
if (g_idx == -1) {
msg("Invalid sensor name %s", settings->sensors[i].desc);
break;
}
g_sensors[g_idx].setting = &settings->sensors[i];
settings->sensors[i].sensor = &g_sensors[g_idx];
if (g_sensors[g_idx].setup(&settings->sensors[i],
(sensor_t *)&g_sensors[g_idx])) {
sensor_count++;
if (sensor_type[g_idx] == SENSOR_TYPE_HYBRID_MAIN) {
save_main_i = g_idx;
} else if (sensor_type[g_idx] == SENSOR_TYPE_HYBRID_AUX) {
aux_sensor_count++;
}
}
info("Sensor '%s' enabled for CPU%d "
"core-control failsafe", sensor_names[i],
hotplug_map[j].cpu);
break;
}
}
poll_count = aux_sensor_count;
/* Enable main sensors, disable auxiliary sensors, setup threshold */
if (save_main_i > -1 && save_main_i < ARRAY_SIZE(g_sensors)) {
tsens_sensor_enable_sensor(g_sensors[save_main_i].setting, 1);
hybrid_enable_auxiliary_sensors(0);
tsens_sensor_update_thresholds(g_sensors[save_main_i].setting,
THRESHOLD_NOCHANGE, 0);
/* mark threshold_enabled */
main_sensor_hi_threshold_enabled = 1;
} else {
info("Hybrid main sensor not configured, disabling any auxiliary sensors found");
for (i = 0; i < ARRAY_SIZE(g_sensors); i++) {
if (!sensor_is_configured(&g_sensors[i]) ||
g_sensors[i].setting->disabled != 0 ||
sensor_type[i] != SENSOR_TYPE_HYBRID_AUX)
continue;
info("Disabling auxiliary sensor:[%s]\n", g_sensors[i].name);
g_sensors[i].setting->disabled = 1;
j = 0;
while (hotplug_map[j].sensor_name != NULL) {
if (g_sensors[i].setting->id == hotplug_map[j].sensor_idx)
info("Core-control failsafe auxiliary sensor '%s' disabled, "
"failsafe for CPU%d will NOT work", g_sensors[i].name,
hotplug_map[j].cpu);
j++;
}
sensor_count--;
}
poll_count = 0;
}
/* TODO : if hotplug sensor is enabled, ensure that it will still be
polled at the HOTPLUG_LOW_THRESHOLD, ie. existing thresholds are not
t[0].lvl_clr > LOW_THRESHOLD || t[0].lvl_trig > HIGH_THRESHOLD
corner case where polling will stop and our hotplug failsafe won't
get executed since we're in interrupt mode */
// Enable and Setup Threshold for BCL
if (save_bcl_i > -1 && save_bcl_i < ARRAY_SIZE(g_sensors)) {
bcl_enable(g_sensors[save_bcl_i].setting, 1);
bcl_update_thresholds(g_sensors[save_bcl_i].setting, 0, 0);
}
return sensor_count;
}
void sensors_shutdown()
{
int i = 0;
for (i = 0; i < ARRAY_SIZE(g_sensors); i++) {
info("Sensor shutdown:[%s] \n", g_sensors[i].name);
g_sensors[i].shutdown(g_sensors[i].setting);
}
}
int sensor_threshold_trigger(int value, sensor_setting_t *sensor, int level)
{
if (sensor->id == BCL) {
if (value <= sensor->t[level].lvl_trig)
return 1;
else
return 0;
} else {
if (value >= sensor->t[level].lvl_trig)
return 1;
else
return 0;
}
}
int sensor_threshold_clear(int value, sensor_setting_t *sensor, int level)
{
if (sensor->id == BCL) {
if (value >= sensor->t[level].lvl_clr)
return 1;
else
return 0;
} else {
if (value <= sensor->t[level].lvl_clr)
return 1;
else
return 0;
}
}
int sensor_get_temperature(sensor_setting_t *setting)
{
int temp = 0;
int i = 0;
if (setting == NULL ||
setting->sensor == NULL ||
setting->sensor->get_temperature == NULL) {
return -EFAULT;
}
temp = setting->sensor->get_temperature(setting);
dbgmsg("Sensor[%s] Temperature : %2.1f\n", setting->desc, RCONV(temp));
i = 0;
while (hotplug_map[i].sensor_name != NULL) {
if (setting->id == hotplug_map[i].sensor_idx) {
do_hotplug_critical(setting, hotplug_map[i].cpu,
(int) RCONV(temp));
}
i++;
}
return temp;
}
static void hybrid_main_interrupt_wait(sensor_setting_t *setting)
{
int performed_wait = 0;
if (setting == NULL ||
setting->desc == NULL ||
setting->sensor == NULL) {
msg("%s: Unexpected NULL", __func__);
return;
}
/* If main sensor in interrupt mode */
if (hybrid_state == HYBRID_STATE_MAIN_INTERRUPT) {
if (main_sensor_hi_threshold_enabled == 0) {
/* wait for auxiliary sensors to finish polling */
pthread_mutex_lock(&poll_count_mutex);
while (poll_count > 0) {
pthread_cond_wait(&finish_poll_condition,
&poll_count_mutex);
}
pthread_mutex_unlock(&poll_count_mutex);
/* disable auxiliary sensors first, then
reenable main sensor hi threshold */
hybrid_enable_auxiliary_sensors(0);
tsens_sensor_enable_thresholds(setting, 1, 0);
main_sensor_hi_threshold_enabled = 1;
}
tsens_sensor_interrupt_wait(setting);
performed_wait = 1;
}
/* Don't sleep on first poll */
if (!performed_wait) {
usleep(setting->sampling_period_us);
}
}
static void hybrid_aux_interrupt_wait(sensor_setting_t *setting)
{
int performed_wait = 0;
if (setting == NULL ||
setting->desc == NULL ||
setting->sensor == NULL) {
msg("%s: Unexpected NULL", __func__);
return;
}
/* Auxiliary sensors should block on main sensor interrupt */
if (hybrid_state != HYBRID_STATE_POLLING) {
/* check that all auxiliary sensors are ready to wait before
completing polling */
pthread_mutex_lock(&poll_count_mutex);
poll_count--;
if (poll_count == 0) {
pthread_cond_broadcast(&finish_poll_condition);
}
pthread_mutex_unlock(&poll_count_mutex);
/* Wait for sensor threshold condition */
pthread_mutex_lock(&hybrid_mutex);
while (HYBRID_STATE_POLLING != hybrid_state) {
pthread_cond_wait(&hybrid_condition,
&hybrid_mutex);
}
pthread_mutex_unlock(&hybrid_mutex);
pthread_mutex_lock(&poll_count_mutex);
poll_count++;
pthread_mutex_unlock(&poll_count_mutex);
performed_wait = 1;
}
/* Don't sleep on first poll */
if (!performed_wait) {
usleep(setting->sampling_period_us);
}
}
void sensor_wait(sensor_setting_t *setting)
{
static int is_first_poll = 1;
if (setting == NULL ||
setting->sensor == NULL) {
msg("%s: Unexpected NULL", __func__);
return;
}
if (setting->sensor->interrupt_wait) {
setting->sensor->interrupt_wait(setting);
} else if (!is_first_poll) {
usleep(setting->sampling_period_us);
} else {
is_first_poll = 0;
}
}
static void hybrid_main_update_thresholds(sensor_setting_t *setting,
int threshold_type, int level)
{
if (setting == NULL ||
setting->sensor == NULL) {
msg("%s: Unexpected NULL", __func__);
return;
}
/* TSENS thresholds don't need updating for 8960
sensor_setup sets threshold 0 */
/* Update state for hybrid polling */
if (threshold_type == THRESHOLD_CROSS) {
threshold_cleared[0] = 0;
} else if (threshold_type == THRESHOLD_CLEAR && level == 0) {
threshold_cleared[0] = 1;
}
if (hybrid_state == HYBRID_STATE_MAIN_INTERRUPT &&
threshold_type == THRESHOLD_NOCHANGE) {
/* Rearm threshold if we didn't actually cross hi threshold */
tsens_sensor_enable_thresholds(setting, 1, 0);
} else if (hybrid_state == HYBRID_STATE_MAIN_INTERRUPT &&
threshold_type == THRESHOLD_CROSS) {
/* Enable auxiliary hybrid polling on threshold crossing */
dbgmsg("Hybrid state -> polling enabled");
/* transition to polling expected,
disable interrupts, enable aux sensors */
tsens_sensor_enable_thresholds(setting, 0, 0);
main_sensor_hi_threshold_enabled = 0;
hybrid_enable_auxiliary_sensors(1);
pthread_mutex_lock(&hybrid_mutex);
hybrid_state = HYBRID_STATE_POLLING;
pthread_cond_broadcast(&hybrid_condition);
pthread_mutex_unlock(&hybrid_mutex);
} else if (hybrid_state == HYBRID_STATE_POLLING &&
all_hybrid_thresholds_cleared()) {
/* disable polling on threshold clearing */
pthread_mutex_lock(&hybrid_mutex);
dbgmsg("Hybrid state -> interrupt");
hybrid_state = HYBRID_STATE_MAIN_INTERRUPT;
pthread_mutex_unlock(&hybrid_mutex);
}
}
static void hybrid_aux_update_thresholds(sensor_setting_t *setting,
int threshold_type, int level)
{
int hybrid_id = 0;
if (setting == NULL ||
setting->sensor == NULL) {
msg("%s: Unexpected NULL", __func__);
return;
}
hybrid_id = hybrid_sensor_id(setting);
if (hybrid_id <= 0 || hybrid_id >= NUM_TSENS_SENSORS) {
msg("%s: Bad hybrid sensor_id", __func__);
return;
}
/* Update state for hybrid polling */
if (threshold_type == THRESHOLD_CROSS) {
threshold_cleared[hybrid_id] = 0;
} else if (threshold_type == THRESHOLD_CLEAR && level == 0) {
threshold_cleared[hybrid_id] = 1;
}
/* disable polling on threshold clearing */
if (hybrid_state == HYBRID_STATE_POLLING &&
all_hybrid_thresholds_cleared()) {
pthread_mutex_lock(&hybrid_mutex);
dbgmsg("Hybrid state -> interrupt");
hybrid_state = HYBRID_STATE_MAIN_INTERRUPT;
pthread_mutex_unlock(&hybrid_mutex);
}
}
void sensor_update_thresholds(sensor_setting_t *setting,
int threshold_type, int level)
{
if (setting == NULL ||
setting->sensor == NULL) {
msg("%s: Unexpected NULL", __func__);
return;
}
if (setting->sensor->update_thresholds == NULL)
return;
setting->sensor->update_thresholds(setting, threshold_type, level);
}
static int pa_sensor_setup(sensor_setting_t *settings,
sensor_t *sensor)
{
int fd = -1;
int sensor_count = 0;
do {
/* We have nothing to do if there are no thresholds */
if (!settings->num_thresholds) {
dbgmsg("No thresholds for sensor %s\n", sensor->name);
break;
}
sensor_count = adc_sensors_setup(settings, sensor);
if (sensor_count) {
info("ADC sensor found for %s\n", sensor->name);
sensor->shutdown = adc_sensors_shutdown;
sensor->get_temperature = adc_sensor_get_temperature;
break;
}
sensor_count = qmi_ts_setup(settings, sensor);
if (sensor_count) {
info("QMI TS sensor found for %s\n", sensor->name);
sensor->update_thresholds = qmi_ts_update_thresholds;
sensor->get_temperature = qmi_ts_get_temperature;
sensor->interrupt_wait = qmi_ts_interrupt_wait;
sensor->shutdown = qmi_ts_shutdown;
sensor->interrupt_enable = 1;
break;
}
} while (0);
return sensor_count;
}

View File

@@ -1,322 +0,0 @@
/*===========================================================================
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>
#include "tsens-sensor.h"
#include "bcl-sensor.h"
#include "thermal.h"
char *sensor_names[] =
{
"tsens_tz_sensor0",
"tsens_tz_sensor1",
"tsens_tz_sensor2",
"tsens_tz_sensor3",
"tsens_tz_sensor4",
"tsens_tz_sensor5",
"tsens_tz_sensor6",
"tsens_tz_sensor7",
"tsens_tz_sensor8",
"tsens_tz_sensor9",
"tsens_tz_sensor10",
"bcl",
};
static sensor_t g_sensors[] = {
{
.name = "tsens_tz_sensor0",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor1",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor2",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor3",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor4",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor5",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor6",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor7",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor8",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor9",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor10",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "bcl",
.setup = bcl_setup,
.shutdown = bcl_shutdown,
.get_temperature = bcl_get_diff_imax_ibat,
.interrupt_wait = bcl_interrupt_wait,
.update_thresholds = bcl_update_thresholds,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
};
int sensors_setup(thermal_setting_t *settings)
{
int i = 0;
int j = 0;
int ret = 0;
int sensor_count = 0;
if (!settings)
return sensor_count;
for (i = 0; i < ARRAY_SIZE(g_sensors); i++) {
for (j = 0; j < SENSOR_IDX_MAX; j++) {
if (!settings->sensors[j].desc ||
strncmp(settings->sensors[j].desc, g_sensors[i].name,
SENSOR_NAME_MAX))
continue;
info("Sensor setup:[%s]\n", g_sensors[i].name);
g_sensors[i].setting = &settings->sensors[j];
settings->sensors[j].sensor = &g_sensors[i];
ret = g_sensors[i].setup(&settings->sensors[j],
(sensor_t *)&g_sensors[i]);
sensor_count += ret;
if (!ret)
break;
if (!g_sensors[i].interrupt_enable)
break;
/* TSENS sensor threshold setup */
if (strncmp(settings->sensors[j].desc,
g_sensors[i].name, strlen("tsens_tz_sensor")) == 0) {
tsens_sensor_update_thresholds(g_sensors[i].setting,
THRESHOLD_NOCHANGE, 0);
}
/* BCL sensor threshold setup */
if (strncmp(settings->sensors[j].desc,
g_sensors[i].name, strlen("bcl")) == 0) {
bcl_enable(g_sensors[i].setting, 1);
bcl_update_thresholds(g_sensors[i].setting, 0, 0);
}
break;
}
}
return sensor_count;
}
void sensors_shutdown()
{
int i = 0;
for (i = 0; i < ARRAY_SIZE(g_sensors); i++) {
info("Sensor shutdown:[%s] \n", g_sensors[i].name);
g_sensors[i].shutdown(g_sensors[i].setting);
}
}
int sensor_threshold_trigger(int value, sensor_setting_t *sensor, int level)
{
if (sensor->id == BCL) {
if (value <= sensor->t[level].lvl_trig)
return 1;
else
return 0;
} else {
if (value >= sensor->t[level].lvl_trig)
return 1;
else
return 0;
}
}
int sensor_threshold_clear(int value, sensor_setting_t *sensor, int level)
{
if (sensor->id == BCL) {
if (value >= sensor->t[level].lvl_clr)
return 1;
else
return 0;
} else {
if (value <= sensor->t[level].lvl_clr)
return 1;
else
return 0;
}
}
int sensor_get_temperature(sensor_setting_t *setting)
{
int temp = 0;
if (setting == NULL ||
setting->sensor == NULL ||
setting->sensor->get_temperature == NULL) {
return -EFAULT;
}
temp = setting->sensor->get_temperature(setting);
dbgmsg("Sensor[%s] Temperature : %2.1f\n", setting->desc, RCONV(temp));
return temp;
}
void sensor_wait(sensor_setting_t *setting)
{
static int is_first_poll = 1;
if (setting == NULL ||
setting->sensor == NULL) {
msg("%s: Unexpected NULL", __func__);
return;
}
if (setting->sensor->interrupt_enable &&
setting->sensor->interrupt_wait) {
setting->sensor->interrupt_wait(setting);
} else if (!is_first_poll) {
usleep(setting->sampling_period_us);
} else {
is_first_poll = 0;
}
}
void sensor_update_thresholds(sensor_setting_t *setting,
int threshold_type, int level)
{
if (setting == NULL ||
setting->sensor == NULL) {
msg("%s: Unexpected NULL", __func__);
return;
}
if (setting->sensor->interrupt_enable == 0 ||
setting->sensor->update_thresholds == NULL)
return;
setting->sensor->update_thresholds(setting, threshold_type, level);
}

View File

@@ -1,182 +0,0 @@
/*===========================================================================
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <pthread.h>
#include <linux/msm_adc.h>
#include "thermal.h"
#include "sensors-hw.h"
#include "oncrpc.h"
#include "adc.h"
#include "adc_rpc.h"
#define MSM_ADC_NODE "/dev/msm_adc"
#define EXTN_MSM_ONCRPC_CHANNEL (23)
#define EXTN_MSM_INVALID_TEMP (-555)
#define EXTN_MSM_MAX_TEMP (255)
char *sensor_names[] =
{
"PMIC_THERM",
"MSM_THERM",
};
static int adc_fd = -1;
int sensors_setup(thermal_setting_t *settings)
{
struct msm_adc_lookup lookup;
int rc, adc_value;
uint32_t convert_value;
oncrpc_init();
oncrpc_task_start();
/* 8x25 has two thermal mitigation solutions
a) pmic thermistor: uses dalrpc.
b) external thermistor: uses oncrpc.
both solutions are mutually exclusive.
Hence check oncrpc availability by issuing
adc_null. If the oncrpc is available, then check whether
msm thermistor rework is installed or not on the HW?
*/
if (adc_null()) {
dbgmsg("oncrpc is available\n");
/* look for msm thermistor rework if oncrpc is available
and check whether value is negative or not */
convert_value = adc_read(EXTN_MSM_ONCRPC_CHANNEL);
if (convert_value > EXTN_MSM_MAX_TEMP) {
convert_value |= 0xFFFF0000;
}
adc_value = convert_value;
if (adc_value == EXTN_MSM_INVALID_TEMP) {
settings->sensors[MSM_THERM].disabled = 1;
dbgmsg("Sensor '%s' is not present\n", sensor_names[MSM_THERM]);
oncrpc_task_stop();
oncrpc_deinit();
}
else {
dbgmsg("Sensor '%s' is present\n", sensor_names[MSM_THERM]);
settings->sensors[MSM_THERM].disabled = 0;
return 1;
}
} else {
dbgmsg("oncrpc is not available\n");
}
adc_fd = open(MSM_ADC_NODE, O_RDWR);
if (adc_fd < 0) {
msg("Error opening %s\n", MSM_ADC_NODE);
return 0;
}
memset(&lookup, 0, sizeof(lookup));
strlcpy(lookup.name, sensor_names[PMIC_THERM], MSM_ADC_MAX_CHAN_STR);
lookup.name[MSM_ADC_MAX_CHAN_STR-1] = '\0';
rc = ioctl(adc_fd, MSM_ADC_LOOKUP, &lookup);
if (rc < 0) {
msg("Error looking up '%s', skipping\n", sensor_names[PMIC_THERM]);
settings->sensors[PMIC_THERM].disabled = 1;
return 0;
}
settings->sensors[PMIC_THERM].chan_idx = lookup.chan_idx;
settings->sensors[PMIC_THERM].disabled = 0;
dbgmsg("Sensor '%s' -> channel '%u'\n",
sensor_names[PMIC_THERM], lookup.chan_idx);
return 1;
}
void sensors_shutdown()
{
if (adc_fd != -1)
close(adc_fd);
adc_fd = -1;
}
int sensor_threshold_trigger(int value, sensor_setting_t *sensor, int level)
{
if (value >= sensor->t[level].lvl_trig)
return 1;
else
return 0;
}
int sensor_threshold_clear(int value, sensor_setting_t *sensor, int level)
{
if (value <= sensor->t[level].lvl_clr)
return 1;
else
return 0;
}
int sensor_get_temperature(sensor_setting_t *sensor)
{
int rc = 0, adc_value;
uint32_t convert_value;
struct adc_chan_result conv;
if (sensor->id == MSM_THERM) {
convert_value = adc_read(EXTN_MSM_ONCRPC_CHANNEL);
if (convert_value > EXTN_MSM_MAX_TEMP) {
convert_value |= 0xFFFF0000;
}
adc_value = convert_value;
/* external msm thermistor returns the temparature in degress,
but thermal daemon expects the temparature in millie degrees.
Hence convert from degress to miiliedegrees.*/
dbgmsg("Sensor '%s' - %d*C (%d)\n",sensor->desc, adc_value, CONV(adc_value));
return CONV(adc_value);
}
memset(&conv, 0, sizeof(conv));
conv.chan = sensor->chan_idx;
if (adc_fd <= 0) {
msg("Error opening sensor '%s'\n", sensor->desc);
return -1;
}
rc = ioctl(adc_fd, MSM_ADC_REQUEST, &conv);
if (rc) {
msg("Error getting sensor info '%s'\n", sensor->desc);
} else {
dbgmsg("Sensor '%s' - %2.1f*C (%lld)\n",
sensor->desc, RCONV(conv.physical), conv.physical);
}
return conv.physical;
}
void sensor_wait(sensor_setting_t *setting)
{
static int is_first_poll = 1;
if (setting == NULL) {
msg("%s: Unexpected NULL", __func__);
return;
}
if (!is_first_poll) {
usleep(setting->sampling_period_us);
} else {
is_first_poll = 0;
}
}
void sensor_update_thresholds(sensor_setting_t *setting,
int threshold_triggered, int level)
{
return;
}

View File

@@ -1,95 +0,0 @@
/*===========================================================================
Copyright (c) 2011-2012 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#ifndef __SENSORS_HW_H__
#define __SENSORS_HW_H__
#define SENSOR_NAME_MAX (20)
#define SENSOR(x) (((x >= 0) && (x < SENSOR_IDX_MAX)) ? \
sensor_names[x] : "unknown")
enum sensor_list {
#ifdef SENSORS_7630
PMIC_THERM,
XO_THERM,
XO_THERM_GPS,
POP_MEM_TZ,
#endif /* SENSORS_7630 */
#ifdef SENSORS_8660
PMIC8058_TZ,
TSENS_TZ_SENSOR0,
#endif /* SENSORS_8660 */
#ifdef SENSORS_8960
PM8921_TZ,
PA_THERM0,
PA_THERM1,
TSENS_TZ_SENSOR0,
TSENS_TZ_SENSOR1,
TSENS_TZ_SENSOR2,
TSENS_TZ_SENSOR3,
TSENS_TZ_SENSOR4,
TSENS_TZ_SENSOR5,
TSENS_TZ_SENSOR6,
TSENS_TZ_SENSOR7,
TSENS_TZ_SENSOR8,
TSENS_TZ_SENSOR9,
TSENS_TZ_SENSOR10,
BCL,
PM8821_TZ,
#endif /* SENSORS_8960 */
#ifdef SENSORS_8974
TSENS_TZ_SENSOR0,
TSENS_TZ_SENSOR1,
TSENS_TZ_SENSOR2,
TSENS_TZ_SENSOR3,
TSENS_TZ_SENSOR4,
TSENS_TZ_SENSOR5,
TSENS_TZ_SENSOR6,
TSENS_TZ_SENSOR7,
TSENS_TZ_SENSOR8,
TSENS_TZ_SENSOR9,
TSENS_TZ_SENSOR10,
BCL,
#endif /* SENSORS_8974 */
#ifdef SENSORS_TEST
TEST0,
#endif /* SENSORS_TEST */
#ifdef SENSORS_8625
PMIC_THERM,
MSM_THERM,
#endif
#ifdef IPQ_806x
TSENS_TZ_SENSOR0,
TSENS_TZ_SENSOR1,
TSENS_TZ_SENSOR2,
TSENS_TZ_SENSOR3,
TSENS_TZ_SENSOR4,
TSENS_TZ_SENSOR5,
TSENS_TZ_SENSOR6,
TSENS_TZ_SENSOR7,
TSENS_TZ_SENSOR8,
TSENS_TZ_SENSOR9,
TSENS_TZ_SENSOR10,
TSENS_TZ_SENSOR11,
TSENS_TZ_SENSOR12,
TSENS_TZ_SENSOR13,
TSENS_TZ_SENSOR14,
TSENS_TZ_SENSOR15,
#endif /*IPQ_806x */
SENSOR_IDX_MAX
};
extern char *sensor_names[]; /* Sensor names are defined in sensors-*.c */
#endif /* __SENSORS_HW_H__ */

View File

@@ -1,417 +0,0 @@
/*===========================================================================
Copyright (c) 2014, 2017 Qualcomm Technologies, Inc.
All Rights Reserved.
Confidential and Proprietary - Qualcomm Technologies, Inc.
===========================================================================*/
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>
#include "tsens-sensor.h"
#include "thermal.h"
char *sensor_names[] =
{
"tsens_tz_sensor0",
"tsens_tz_sensor1",
"tsens_tz_sensor2",
"tsens_tz_sensor3",
"tsens_tz_sensor4",
"tsens_tz_sensor5",
"tsens_tz_sensor6",
"tsens_tz_sensor7",
"tsens_tz_sensor8",
"tsens_tz_sensor9",
"tsens_tz_sensor10",
"tsens_tz_sensor11",
"tsens_tz_sensor12",
"tsens_tz_sensor13",
"tsens_tz_sensor14",
"tsens_tz_sensor15",
};
static sensor_t g_sensors[] = {
{
.name = "tsens_tz_sensor0",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.enable_sensor = tsens_sensor_enable_sensor,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor1",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.enable_sensor = tsens_sensor_enable_sensor,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor2",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.enable_sensor = tsens_sensor_enable_sensor,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor3",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.enable_sensor = tsens_sensor_enable_sensor,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor4",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.enable_sensor = tsens_sensor_enable_sensor,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor5",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.enable_sensor = tsens_sensor_enable_sensor,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor6",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.enable_sensor = tsens_sensor_enable_sensor,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor7",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.enable_sensor = tsens_sensor_enable_sensor,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor8",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.enable_sensor = tsens_sensor_enable_sensor,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor9",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.enable_sensor = tsens_sensor_enable_sensor,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor10",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.enable_sensor = tsens_sensor_enable_sensor,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor11",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.enable_sensor = tsens_sensor_enable_sensor,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor12",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.enable_sensor = tsens_sensor_enable_sensor,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor13",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.enable_sensor = tsens_sensor_enable_sensor,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor14",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.enable_sensor = tsens_sensor_enable_sensor,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
{
.name = "tsens_tz_sensor15",
.setup = tsens_sensors_setup,
.shutdown = tsens_sensors_shutdown,
.get_temperature = tsens_sensor_get_temperature,
.interrupt_wait = tsens_sensor_interrupt_wait,
.update_thresholds = tsens_sensor_update_thresholds,
.enable_sensor = tsens_sensor_enable_sensor,
.setting = NULL,
.tzn = 0,
.data = NULL,
.interrupt_enable = 1,
},
};
int sensors_setup(thermal_setting_t *settings)
{
int i = 0;
int j = 0;
int ret = 0;
int sensor_count = 0;
#ifdef IPQ_806x
int act_cnt;
int thrs_cnt;
int valid_act_cnt;
int max_thr;
#endif
if (!settings)
return sensor_count;
for (i = 0; i < ARRAY_SIZE(g_sensors); i++) {
for (j = 0; j < SENSOR_IDX_MAX; j++) {
#ifdef IPQ_806x
/*
Some threshold actions are set to "none", so it
is therefore required to track only the valid
actions to avoid setting up that particular sensor.
*/
max_thr = settings->sensors[j].num_thresholds;
valid_act_cnt = 0;
for (thrs_cnt = max_thr - 1; thrs_cnt >= 0; thrs_cnt--) {
for( act_cnt = 0 ; act_cnt < settings->sensors[j].t[thrs_cnt].num_actions;act_cnt++ ){
if( NONE != settings->sensors[j].t[thrs_cnt].actions[act_cnt].action )
valid_act_cnt++;
}
}
#endif
/*
Do not setup sensors which are not being used.
This is required to reduce memory foot print as
each sensor requires about 1.5MB - 2 MB for setup.
*/
if (!settings->sensors[j].desc ||
valid_act_cnt == 0 ||
settings->sensors[j].num_thresholds < 1 ||
strncmp(settings->sensors[j].desc, g_sensors[i].name,
SENSOR_NAME_MAX))
continue;
info("Sensor setup:[%s]\n", g_sensors[i].name);
g_sensors[i].setting = &settings->sensors[j];
settings->sensors[j].sensor = &g_sensors[i];
ret = g_sensors[i].setup(&settings->sensors[j],
(sensor_t *)&g_sensors[i]);
sensor_count += ret;
if (!ret)
break;
if (!g_sensors[i].interrupt_enable)
break;
/* TSENS sensor threshold setup */
if (strncmp(settings->sensors[j].desc,
g_sensors[i].name, strlen("tsens_tz_sensor")) == 0) {
tsens_sensor_update_thresholds(g_sensors[i].setting,
THRESHOLD_NOCHANGE, 0);
}
break;
}
}
return sensor_count;
}
void sensors_shutdown()
{
int i = 0;
for (i = 0; i < ARRAY_SIZE(g_sensors); i++) {
info("Sensor shutdown:[%s] \n", g_sensors[i].name);
g_sensors[i].shutdown(g_sensors[i].setting);
}
}
int sensor_threshold_trigger(int value, sensor_setting_t *sensor, int level)
{
if (value >= sensor->t[level].lvl_trig)
return 1;
else
return 0;
}
int sensor_threshold_clear(int value, sensor_setting_t *sensor, int level)
{
if (value <= sensor->t[level].lvl_clr)
return 1;
else
return 0;
}
int sensor_get_temperature(sensor_setting_t *setting)
{
int temp = 0;
if (setting == NULL ||
setting->sensor == NULL ||
setting->sensor->get_temperature == NULL) {
return -EFAULT;
}
temp = setting->sensor->get_temperature(setting);
dbgmsg("Sensor[%s] Temperature : %2.1f\n", setting->desc, RCONV(temp));
return temp;
}
void sensor_wait(sensor_setting_t *setting)
{
static int is_first_poll = 1;
dbgmsg("Sensor_wait step in.\n");
if (setting == NULL ||
setting->sensor == NULL) {
msg("%s: Unexpected NULL", __func__);
return;
}
if (setting->sensor->interrupt_enable &&
setting->sensor->interrupt_wait) {
setting->sensor->interrupt_wait(setting);
} else if (!is_first_poll) {
dbgmsg("Sleeping for smapling period of %d us.\n" , setting->sampling_period_us );
usleep(setting->sampling_period_us);
} else {
is_first_poll = 0;
}
}
void sensor_update_thresholds(sensor_setting_t *setting,
int threshold_type, int level)
{
if (setting == NULL ||
setting->sensor == NULL) {
msg("%s: Unexpected NULL", __func__);
return;
}
dbgmsg("Interrupt Enable: %d \n" , setting->sensor->interrupt_enable );
if (setting->sensor->interrupt_enable == 0 ||
setting->sensor->update_thresholds == NULL)
{
dbgmsg("%s: return. interrupt disabled or updatethreshold is NULL \n", __func__ );
return;
}
setting->sensor->update_thresholds(setting, threshold_type, level);
}
void sensor_enable( sensor_setting_t *setting , int tzn , int enabled )
{
if ( setting && setting->sensor && setting->sensor->enable_sensor) {
dbgmsg("%s: sensor setting found for tzn%d\n" , __func__ , tzn );
setting->sensor->enable_sensor(tzn , enabled);
}
else{
dbgmsg("%s: sensor setting not found for tzn%d. Using defaults...\n" , __func__ , tzn );
tsens_sensor_enable_sensor(tzn , enabled);
}
}

View File

@@ -1,211 +0,0 @@
/*===========================================================================
Copyright (c) 2010-2012 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>
#include <pthread.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <signal.h>
#include "thermal.h"
#ifndef IPQ_806x
#include "thermal_server.h"
#endif
thermal_setting_t thermal_settings;
int num_cpus = 0;
int num_gpus = 0;
int exit_daemon = 0;
int debug_output = 0;
int enable_restore_brightness = 1;
int minimum_mode = 0;
int new_corelimit = 0;
int dump_bcl_ibat_imax = 0;
char *dump_bcl_ibat_imax_file = NULL;
static char *config_file = NULL;
void set_mitigation_level();
#ifdef IPQ_806x
void terminate_signal (int sig)
{
/* Do all uninitialization here */
/* Enabling NSS Auto scaling */
nssfreq_request( -1 );
/* Resetting the powerctl */
powerctl_restart(1);
/* Proceed with the termination */
exit(sig);
}
#endif
void print_help(void)
{
printf("\nTemperature sensor daemon\n");
printf("Optional arguments:\n");
printf(" --config-file/-c <file> config file\n");
printf(" --debug/-d debug output\n");
#ifndef IPQ_806x
printf(" --norestorebrightness/-r disable restore brightness functionality\n");
printf(" --overridecorelimit/-o <degC> override core limit temperature (test only)\n");
printf(" --dump-bcl/-i BCL ibat/imax file\n");
#endif
printf(" --help/-h this help screen\n");
}
int parse_commandline(int argc, char *const argv[])
{
int c;
struct option long_options[] = {
{"config-file", 1, 0, 'c'},
{"debug", 0, 0, 'd'},
#ifndef IPQ_806x
{"norestorebrightness", 0, 0, 'r'},
{"overridecorelimit", 1, 0, 'o'},
{"dump-bcl", 2, 0, 'i'},
#endif
{"help", 0, 0, 'h'},
{0, 0, 0, 0}
};
while ((c = getopt_long(argc, argv, "c:i::dro:h", long_options, NULL)) != EOF) {
switch (c) {
case 'c':
info("Using config file '%s'\n", optarg);
config_file = optarg;
break;
case 'd':
info("Debug output enabled\n");
debug_output = 1;
break;
#ifndef IPQ_806x
case 'i':
info("dump BCL ibat/imax to a file\n");
dump_bcl_ibat_imax = 1;
dump_bcl_ibat_imax_file = optarg;
break;
case 'r':
info("Restore brightness feature disabled\n");
enable_restore_brightness = 0;
break;
case 'o':
new_corelimit = atoi(optarg);
/* sanity check */
if (new_corelimit == 0) {
printf("Invalid argument %s for core limit, value should be an "
"integral value in degC\n", optarg);
return 0;
}
else if (new_corelimit < CORELIMIT_MIN ||
new_corelimit > CORELIMIT_MAX) {
printf("Core limit %d out of sanity check range, "
"should be between %d and %ddegC\n",
new_corelimit, CORELIMIT_MIN, CORELIMIT_MAX);
return 0;
}
info("Core limit override to %d\n", new_corelimit);
break;
#endif
case 'h':
default:
return 0;
}
}
/* Too many/unrecognized argument(s) */
if (optind < argc) {
msg("Too many arguments\n");
return 0;
}
return 1;
}
int main(int argc, char **argv)
{
#ifdef IPQ_806x
if (signal (SIGTERM, terminate_signal) == SIG_IGN)
signal (SIGTERM, SIG_IGN);
#endif
info("Thermal daemon started\n");
setpriority(PRIO_PROCESS, getpid(), -20);
if (!parse_commandline(argc, argv)) {
print_help();
return 0;
}
init_settings(&thermal_settings);
if (!load_config(&thermal_settings, config_file)) {
return 0;
}
#ifdef ANDROID
{
char buf[PROPERTY_VALUE_MAX];
/* Early stage of encrypted data partition;
* run without modem mitigation and framework socket
*/
if ((property_get("vold.decrypt", buf, "0") > 0)
&& (buf[0] == '1')) {
minimum_mode = 1;
info("Running in minimum mode\n");
}
}
#endif
set_mitigation_level();
cpufreq_init();
#ifndef IPQ_806x
gpufreq_init();
if (!minimum_mode) {
modem_communication_init();
modem_ts_qmi_init();
}
/* Initialize and setup a socket server for external
userspace apps interested in thermal mitigation. */
thermal_server_init();
#endif
/* Disable kernel thermal module and take over */
write_to_file("/sys/module/msm_thermal/parameters/enabled", "N" , strlen("N") + 1);
thermal_monitor(&thermal_settings);
#ifndef IPQ_806x
if (!minimum_mode) {
modem_communication_release();
modem_qmi_ts_comm_release();
}
thermal_server_release();
#endif
terminate_signal(0);
info("Thermal daemon exited\n");
return 0;
}

View File

@@ -1,391 +0,0 @@
/*===========================================================================
Copyright (c) 2010-2012 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#ifndef __THERMAL_H__
#define __THERMAL_H__
#include <math.h>
#include <pthread.h>
#include <stdio.h>
#include <errno.h>
#include "sensors-hw.h"
#ifdef ANDROID
# include "cutils/properties.h"
# ifdef USE_ANDROID_LOG
# define LOG_TAG "ThermalDaemon"
# include "cutils/log.h"
# endif
#endif
#ifndef IPQ_806x
#include "common_log.h" /* define after cutils/log.h */
#endif
#ifdef USE_GLIB
#include <glib/gprintf.h>
#define strlcat g_strlcat
#define strlcpy g_strlcpy
#endif /* USE_GLIB */
#ifndef FD_SETSIZE
#define FD_SETSIZE 1024
#endif
#ifndef CONFIG_FILE_DEFAULT
#define CONFIG_FILE_DEFAULT "/system/etc/thermald.conf"
#endif
#define MAX_CPUS (4) /* Supporting up to 4 core systems */
/* Abstract local socket name that report actions are sent on */
#define UI_LOCALSOCKET_NAME "THERMALD_UI"
#define SAMPLING_MS_DEFAULT (5000)
#ifdef SENSORS_8960
#define SAMPLING_MS_MINIMUM (100)
#else
#define SAMPLING_MS_MINIMUM (250)
#endif
#define THRESHOLDS_MAX (8)
#define ACTIONS_MAX (8)
#define MAX_PATH (256)
#define REPORT_MSG_MAX (60)
#define UINT_BUF_MAX (12)
/* core limit temperature sanity check values in degC */
#define CORELIMIT_MIN (50)
#define CORELIMIT_MAX (150)
/* Common thermal sysfs defines */
#define TZ_NODE "/sys/class/thermal/thermal_zone%d"
#define TZ_MODE "/sys/devices/virtual/thermal/thermal_zone%d/mode"
#define TZ_TEMP "/sys/devices/virtual/thermal/thermal_zone%d/temp"
#define TZ_TYPE "/sys/devices/virtual/thermal/thermal_zone%d/type"
/* CPU Frequency Scaling Action */
#define GOVERNOR_NODE "/cpufreq/scaling_governor"
#define FMAX_INFO_NODE "/cpufreq/cpuinfo_max_freq"
#define FMIN_INFO_NODE "/cpufreq/cpuinfo_min_freq"
#define FREQ_MAX_NODE "/cpufreq/scaling_max_freq"
#define FREQ_MIN_NODE "/cpufreq/scaling_min_freq"
#define FREQ_USR_NODE "/cpufreq/scaling_setspeed"
#define FREQ_RPT_NODE "/cpufreq/scaling_cur_freq"
#define HOTPLUG_NODE "/online"
#define CPU_SYSFS_DIR "/sys/devices/system/cpu"
#define CPU_SYSFS(NODE) (CPU_SYSFS_DIR "/cpu%d" NODE)
/*NSS Frequency Scaling Actions */
#define NSS_FREQ_MAX_NODE "/proc/sys/dev/nss/clock/freq_table"
#define NSS_FREQ_AUTO_SCALE "/proc/sys/dev/nss/clock/auto_scale"
#define NSS_CURR_FREQ "/proc/sys/dev/nss/clock/current_freq"
/* Fabric Frequency Scaling Actions */
#define AFAB_CLK "/sys/kernel/debug/clk/afab_a_clk/rate"
#define DFAB_CLK "/sys/kernel/debug/clk/dfab_a_clk/rate"
#define SFPB_CLK "/sys/kernel/debug/clk/sfpb_a_clk/rate"
#define CFPB_CLK "/sys/kernel/debug/clk/cfpb_a_clk/rate"
#define NSSFAB0_CLK "/sys/kernel/debug/clk/nssfab0_a_clk/rate"
#define NSSFAB1_CLK "/sys/kernel/debug/clk/nssfab1_a_clk/rate"
#define EBI1_CLK "/sys/kernel/debug/clk/ebi1_a_clk/rate"
/* Power Control Script */
#define POWER_CTL_PATH "/etc/init.d/powerctl"
/* GPU Frequency Scaling Action */
#define GPU_FREQ_MAX_NODE "/max_gpuclk"
#define GPU_FREQ_RPT_NODE "/gpuclk"
#define GPU_SYSFS_DIR "/sys/class/kgsl"
#define GPU_SYSFS(NODE) (GPU_SYSFS_DIR "/kgsl-3d%d" NODE)
enum therm_msm_id {
THERM_MSM_UNKNOWN = 0,
THERM_MSM_8X60,
THERM_MSM_8960,
THERM_MSM_8960AB,
THERM_MSM_8930,
THERM_MSM_8930AA,
THERM_MSM_8930AB,
THERM_MSM_8064,
THERM_MSM_8064AB,
THERM_MSM_8X25,
THERM_MSM_8974,
THERM_IPQ_8062,
THERM_IPQ_8064,
THERM_IPQ_8066,
THERM_IPQ_8068,
THERM_IPQ_8065,
THERM_IPQ_8069,
THERM_IPQ_8070,
THERM_IPQ_8070A,
THERM_IPQ_8071,
THERM_IPQ_8071A,
THERM_IPQ_8072,
THERM_IPQ_8072A,
THERM_IPQ_8074,
THERM_IPQ_8074A,
THERM_IPQ_8076,
THERM_IPQ_8076A,
THERM_IPQ_8078,
THERM_IPQ_8078A,
THERM_IPQ_8172,
THERM_IPQ_8173,
THERM_IPQ_8174,
THERM_IPQ_6018,
THERM_IPQ_6028,
THERM_IPQ_6000,
THERM_IPQ_6010
};
enum therm_msm_id therm_get_msm_id(void);
/* Utility macros */
#define ARRAY_SIZE(x) (int)(sizeof(x)/sizeof(x[0]))
/* Convert from Celcius to hardware unit (2^-10 *C); and back */
#define CONV(x) (int)((double)x / pow(2.0, -10))
#define RCONV(x) ((double)x * pow(2.0, -10))
enum {
NONE,
CPU_FREQ,
SHUTDOWN,
#ifdef IPQ_806x
POWERSAVE,
NSS_FREQ,
#else
REPORT,
LCD,
MODEM,
FUSION,
BATTERY,
GPU_FREQ,
WLAN,
CAMERA,
CAMCORDER,
#endif
ACTION_IDX_MAX
} action_type;
enum {
THRESHOLD_CLEAR = -1,
THRESHOLD_NOCHANGE = 0,
THRESHOLD_CROSS = 1
} threshold_trigger;
typedef struct _action_t {
int action;
int info;
} action_t;
typedef struct _threshold_t {
int lvl_trig;
int lvl_clr;
action_t actions[ACTIONS_MAX];
int num_actions;
} threshold_t;
struct _sensor_t;
typedef struct _sensor_setting_t {
char *desc;
int id;
unsigned int chan_idx;
int disabled;
pthread_t monitor;
int sampling_period_us;
int num_thresholds;
threshold_t t[THRESHOLDS_MAX];
int last_lvl;
struct _sensor_t *sensor;
unsigned int action_mask;
int hotplug_lvl_trig;
int hotplug_lvl_clr;
/* internal counters used during config parsing */
int _n_thresholds;
int _n_to_clear;
int _n_actions;
int _n_action_info;
} sensor_setting_t;
/* Common sensor struct */
typedef struct _sensor_t {
/* sensor name */
char *name;
/* setup function needs to be called before get_temperature */
int (*setup)(sensor_setting_t *settings, struct _sensor_t* sensor);
/* shutdown function for resource cleanup */
void (*shutdown)(sensor_setting_t *settings);
/* get_temperature function to query sensor reading */
int (*get_temperature)(sensor_setting_t *setting);
/* wait on threshold interrupt */
void (*interrupt_wait)(sensor_setting_t *setting);
/* update sensor thresholds */
void (*update_thresholds)(sensor_setting_t *setting,
int threshold_raised,
int threshold_level);
/* enable/disable sensor */
void (*enable_sensor)(int tzn, int enabled);
/* associated sensor settings */
sensor_setting_t *setting;
/* sysfs thermal zone number */
int tzn;
/* misc data */
void *data;
/* enable interrupt */
int interrupt_enable;
} sensor_t;
typedef struct _thermal_setting_t {
int sample_period_ms;
int soc_id;
int disable_unused_tsens;
sensor_setting_t sensors[SENSOR_IDX_MAX];
} thermal_setting_t;
typedef struct _def_sensor_setting_t {
int sensor_count;
sensor_setting_t *sensors;
}def_sensor_setting_t;
typedef struct {
char *sensor_name;
int cpu;
int sensor_idx;
} hotplug_map_t;
#ifdef USE_ANDROID_LOG
#define msg(format, ...) LOGE(format, ## __VA_ARGS__)
#define info(format, ...) LOGI(format, ## __VA_ARGS__)
#else
#define msg(format, ...) printf(format, ## __VA_ARGS__)
#define info(format, ...) printf(format, ## __VA_ARGS__)
#endif
#define dbgmsg(format, ...) \
do { \
if (debug_output) \
info(format, ## __VA_ARGS__); \
} while (0)
extern int exit_daemon;
extern int debug_output;
extern int enable_restore_brightness;
extern int num_cpus;
extern int num_gpus;
extern int minimum_mode;
extern int new_corelimit;
extern int dump_bcl_ibat_imax;
extern char *dump_bcl_ibat_imax_file;
void init_settings(thermal_setting_t *settings);
int load_config(thermal_setting_t *settings, const char *pFName);
int read_line_from_file(char *path, char *buf, size_t count);
int write_to_file(char *path, char *buf, size_t count);
int write_to_local_file_socket(char * socket_name, char *msg, size_t count);
int write_to_local_socket(char * socket_name, char *msg, size_t count);
int get_tzn(char *sensor_name);
int send_to_clients(char *buf);
void thermal_monitor(thermal_setting_t *settings);
int cpufreq_init(void);
void cpufreq_restore(void);
#ifndef IPQ_806x
int gpufreq_init(void);
int thermald_client_socket_init(void);
void thermald_client_socket_release(void);
#endif
int shutdown_action(int requester, int temperature, int delay);
int cpufreq_request(int cpu, int requester, int temperature, int frequency);
#ifdef IPQ_806x
int powersave_request( int enable );
int nssfreq_request( int frequency );
int powerctl_restart(int reset_max);
#else
int report_action(int requester, int temperature, int level, int is_trigger);
int lcd_brightness_request(int requester, int temperature, int value);
int battery_request(int requester, int temperature, int level);
int gpufreq_request(int gpu, int requester, int temperature, int level);
int wlan_request(int requester, int temperature, int level);
int camera_request(int requester, int temperature, int level);
int camcorder_request(int requester, int temperature, int level);
#endif
#ifndef IPQ_806x
#ifdef ENABLE_MODEM_MITIGATION
int modem_communication_init(void);
int modem_communication_release(void);
int modem_request(int requester, int temperature, int level);
int fusion_modem_request(int requester, int temperature, int level);
#else
static inline int modem_communication_init(void)
{
return -1;
}
static inline int modem_communication_release(void)
{
return -1;
}
static inline int modem_request(int requester, int temperature, int level)
{
return -1;
}
static inline int fusion_modem_request(int requester, int temperature, int level)
{
return -1;
}
#endif
#ifdef ENABLE_MODEM_TS
int modem_ts_qmi_init(void);
int modem_qmi_ts_comm_release(void);
int modem_ts_temp_request(const char *sensor_id, int send_current_temp_report,
int high_valid, int high_thresh, int low_valid,
int low_thresh);
#else
static int modem_ts_qmi_init(void)
{
return -(EPERM);
}
static int modem_qmi_ts_comm_release(void)
{
return -(EPERM);
}
static int modem_ts_temp_request(const char *sensor_id,
int send_current_temp_report,
int high_valid, int high_thresh,
int low_valid,
int low_thresh)
{
return -(EPERM);
}
#endif
#endif
int sensors_setup(thermal_setting_t *setting);
void sensors_shutdown(void);
int sensor_get_temperature(sensor_setting_t *sensor);
int sensor_threshold_trigger(int value, sensor_setting_t *sensor, int level);
int sensor_threshold_clear(int value, sensor_setting_t *sensor, int level);
void sensor_wait(sensor_setting_t *sensor);
void sensor_update_thresholds(sensor_setting_t *sensor, int threshold_type, int level);
#ifdef IPQ_806x
void sensor_enable( sensor_setting_t *setting, int tzn ,int enabled );
#endif
#endif /* __THERMAL_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -1,357 +0,0 @@
/*========================================================================================
thermal_client.c
GENERAL DESCRIPTION
Thermal client library for external userspace apps interested in thermal mitigation.
Copyright (c) 2013 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
==========================================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include <sys/socket.h>
#include <linux/un.h>
#include "thermal_lib_common.h"
#include "thermal_client.h"
#ifdef ANDROID
# include "cutils/properties.h"
# ifdef USE_ANDROID_LOG
# define LOG_TAG "Thermal-Lib"
# include "cutils/log.h"
# endif
#endif
#include "common_log.h" /* define after cutils/log.h */
#ifdef USE_ANDROID_LOG
#define msg(format, ...) LOGE(format, ## __VA_ARGS__)
#define info(format, ...) LOGI(format, ## __VA_ARGS__)
#else
#define msg(format, ...) printf(format, ## __VA_ARGS__)
#define info(format, ...) printf(format, ## __VA_ARGS__)
#endif
/* Utility macros */
#define ARRAY_SIZE(x) (int)(sizeof(x)/sizeof(x[0]))
static int sockfd_client_send = -1;
static int sockfd_client_recv = -1;
static pthread_t thermal_client_recv_thread;
static int thermal_client_shutdown = 0;
static int first_client = 1;
static struct thermal_msg_data client_msg;
struct thermal_cdata *list_head = NULL;
/* Supported Thermal clients */
static char *req_client_names[] =
{
"spkr",
"override",
};
static char *notify_client_names[] =
{
"camera",
"camcorder",
"spkr",
};
/*================================================================================================
FUNCTION do_request_to_thermal
Thermal client request sending thread.
This function will run in a separate thread. This thread is intented to
unblock parent client if connect() fails.
ARGUMENTS
data - data pointer which points to message to be sent
RETURN VALUE
void * - not used.
=================================================================================================*/
static void *do_request_to_thermal(void *data)
{
int rc = 0;
struct sockaddr_un client_addr_send;
while(1) {
sockfd_client_send = socket(AF_LOCAL, SOCK_STREAM, 0);
if (sockfd_client_send < 0) {
msg("Thermal-Lib-Client: %s: failed setup "
"client send sockfd", __func__);
sleep(5);
continue;
}
memset(&client_addr_send, 0, sizeof(struct sockaddr_un));
snprintf(client_addr_send.sun_path, UNIX_PATH_MAX, THERMAL_RECV_CLIENT_SOCKET);
client_addr_send.sun_family = AF_LOCAL;
rc = connect(sockfd_client_send, (struct sockaddr *)&client_addr_send,
sizeof(sa_family_t) + strlen(THERMAL_RECV_CLIENT_SOCKET));
if (rc != 0) {
close(sockfd_client_send);
sleep(5);
continue;
}
rc = send(sockfd_client_send, &client_msg, sizeof(struct thermal_msg_data), 0);
if (rc <= 0) {
msg("Thermal-Lib-Client: "
"Unable to send request data to fd %d", sockfd_client_send);
break;
}
info("Thermal-Lib-Client: Client request sent");
break;
}
close(sockfd_client_send);
return NULL;
}
/*================================================================================================
FUNCTION thermal_client_request
Thermal client request to thermal function.
The client which will send/notify request to thermal.
ARGUMENTS
client_name - client name
req_data - requested data to be sent
RETURN VALUE
0 on success, negative on failure.
=================================================================================================*/
int thermal_client_request(char *client_name, int req_data)
{
int rc = 0;
int ret = -EINVAL;
int i;
pthread_t thermal_client_request_thread;
if (NULL == client_name) {
msg("Thermal-Lib-Client:%s: unexpected NULL", __func__);
return ret;
}
/* Check for client is supported or not*/
for (i = 0; i < ARRAY_SIZE(req_client_names); i++) {
if (0 == strncmp(req_client_names[i], client_name, CLIENT_NAME_MAX))
break;
}
if (i >= ARRAY_SIZE(req_client_names)) {
msg("Thermal-Lib-Client:%s is not in supported "
"thermal client list", client_name);
return ret;
}
memset(&client_msg, 0, sizeof(struct thermal_msg_data));
strlcpy(client_msg.client_name, client_name, CLIENT_NAME_MAX);
client_msg.req_data = req_data;
rc = pthread_create(&thermal_client_request_thread, NULL, do_request_to_thermal, NULL);
if (rc != 0) {
msg("Thermal-Lib-Client: Unable to create pthread to "
"send client request from %s", client_name);
return ret;
}
ret = 0;
return ret;
}
/*============================================================================================
FUNCTION do_listen
Function to listen thermal socket.
This function will run in a separate thread.
ARGUMENTS
data - data pointer.
RETURN VALUE
void * - not used.
=============================================================================================*/
static void *do_listen(void *data)
{
int rc;
int i;
int count;
int (*callback)(int, void *, void *);
struct thermal_cdata *callback_node;
static struct sockaddr_un client_addr;
struct thermal_msg_data thermal_msg;
while (thermal_client_shutdown != 1) {
sockfd_client_recv = socket(AF_LOCAL, SOCK_STREAM, 0);
if (sockfd_client_recv < 0) {
sleep(5);
continue;
}
memset(&client_addr, 0, sizeof(struct sockaddr_un));
snprintf(client_addr.sun_path, UNIX_PATH_MAX, THERMAL_SEND_CLIENT_SOCKET);
client_addr.sun_family = AF_LOCAL;
rc = connect(sockfd_client_recv, (struct sockaddr *)&client_addr,
sizeof(sa_family_t) + strlen(THERMAL_SEND_CLIENT_SOCKET));
if (rc != 0) {
close(sockfd_client_recv);
sleep(5);
continue;
}
while (thermal_client_shutdown != 1) {
memset(&thermal_msg, 0, sizeof(struct thermal_msg_data));
rc = recv(sockfd_client_recv, &thermal_msg, sizeof(struct thermal_msg_data), 0);
if (rc <= 0) {
msg("Thermal-Lib-Client:%s: recv failed", __func__);
break;
}
if (rc != sizeof(struct thermal_msg_data))
continue;
for (i = 0; i < CLIENT_NAME_MAX; i++) {
if (thermal_msg.client_name[i] == '\0')
break;
}
if (i >= CLIENT_NAME_MAX)
thermal_msg.client_name[CLIENT_NAME_MAX - 1] = '\0';
info("Thermal-Lib-Client: Client received msg %s %d",
thermal_msg.client_name, thermal_msg.req_data);
/* Check for client is supported or not*/
for (i = 0; i < ARRAY_SIZE(notify_client_names); i++) {
if (0 == strncmp(notify_client_names[i], thermal_msg.client_name, CLIENT_NAME_MAX))
break;
}
if (i >= ARRAY_SIZE(notify_client_names)) {
msg("Thermal-Lib-Client:%s is not in supported "
"thermal client list", thermal_msg.client_name);
continue;
} else if (thermal_msg.req_data < 0 || thermal_msg.req_data > LEVEL_MAX) {
msg("Thermal-Lib-Client:%s: invalid level %d "
"unexpected", __func__, thermal_msg.req_data);
continue;
}
callback_node = list_head;
count = 0;
for (; callback_node != NULL; callback_node = callback_node->next) {
callback_node = get_callback_node_from_list(callback_node, thermal_msg.client_name);
if (callback_node) {
count++;
callback = callback_node->callback;
if (callback)
callback(thermal_msg.req_data, callback_node->user_data,
callback_node->data_reserved);
} else {
if (count == 0)
msg("Thermal-Lib-Client: No clients are "
"connected for %s", thermal_msg.client_name);
break;
}
}
}
close(sockfd_client_recv);
}
return NULL;
}
/*================================================================================================
FUNCTION thermal_client_register_callback
Thermal client registration function.
The client is registered with name and a callback funcion and keep on connecting
thermal local socket.Based on client name in the message from socket,corresponding
callback will be called.
ARGUMENTS
client_name - client name
callback - callback function pointer with level, user_data pointer and
reserved data as arguments
data - user data
RETURN VALUE
valid non zero client_cb_handle on success, zero on failure.
=================================================================================================*/
int thermal_client_register_callback(char *client_name, int (*callback)(int, void *, void *), void *data)
{
int rc = 0;
int ret = 0;
int i;
int client_cb_handle;
if (NULL == client_name ||
NULL == callback) {
msg("Thermal-Lib-Client:%s: unexpected NULL client registraion "
"failed ", __func__);
return ret;
}
/* Check for client is supported or not*/
for (i = 0; i < ARRAY_SIZE(notify_client_names); i++) {
if (0 == strncmp(notify_client_names[i], client_name, CLIENT_NAME_MAX))
break;
}
if (i >= ARRAY_SIZE(notify_client_names)) {
msg("Thermal-Lib-Client:%s is not in supported thermal client list", client_name);
return ret;
}
client_cb_handle = add_to_list(client_name, callback, data);
if (client_cb_handle == 0) {
msg("Thermal-Lib-Client: %s: Client Registration failed", __func__);
return ret;
}
if (first_client == 1) {
first_client = 0;
rc = pthread_create(&thermal_client_recv_thread, NULL, do_listen, NULL);
if (rc != 0) {
msg("Thermal-Lib-Client: Unable to create pthread to "
"listen thermal events for %s", client_name);
remove_from_list(client_cb_handle);
return ret;
}
}
info("Thermal-Lib-Client: Registraion successfully "
"finished for %s", client_name);
ret = client_cb_handle;
return ret;
}
/*===========================================================================
FUNCTION thermal_client_unregister_callback
Function to unregister client req_handler.
ARGUMENTS
client_cb_handle - client handle which retured on
succesful registeration
RETURN VALUE
void - return nothing.
===========================================================================*/
void thermal_client_unregister_callback(int client_cb_handle)
{
if (remove_from_list(client_cb_handle) < 0)
msg("Thermal-Lib-Client: thermal client unregister callback error");
if (list_head == NULL) {
if (thermal_client_shutdown != 1) {
thermal_client_shutdown = 1;
pthread_join(thermal_client_recv_thread, NULL);
close(sockfd_client_recv);
sockfd_client_recv = -1;
first_client = 1;
}
}
}

View File

@@ -1,22 +0,0 @@
/*===========================================================================
Copyright (c) 2013 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#ifndef __THERMAL_CLIENT_H__
#define __THERMAL_CLIENT_H__
#ifdef __cplusplus
extern "C" {
#endif
int thermal_client_register_callback(char *client_name, int (*callback)(int , void *, void *), void *data);
int thermal_client_request(char *client_name, int req_data);
void thermal_client_unregister_callback(int client_cb_handle);
#ifdef __cplusplus
}
#endif
#endif /* __THERMAL_CLIENT_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -1,146 +0,0 @@
/*========================================================================================
thermal_lib_common.c
GENERAL DESCRIPTION
Common utility functions for thermald and thermal client lib.
Copyright (c) 2013 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
==========================================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include "thermal_lib_common.h"
extern struct thermal_cdata *list_head;
static uint32_t client_cb_handle = 0;
#define CLIENT_HANDLE_COND(x) (client_cb_handle & (1 << (x)))
/*===========================================================================
FUNCTION get_callback_node_from_list
Function to get callback node from thermal client list.
ARGUMENTS
list - Node of list from which loop start to iterate
name - client name
RETURN VALUE
return valid thermal_cdata node if find a callback,
otherwise return NULL.
===========================================================================*/
struct thermal_cdata *get_callback_node_from_list(struct thermal_cdata *list, char *name)
{
for (; list != NULL; list = list->next) {
if (0 != strncmp(list->client_name, name, CLIENT_NAME_MAX))
continue;
else
return list;
}
return NULL;
}
/*===========================================================================
FUNCTION remove_from_list
Function to remove unregistered client and its data from thermal
client list based on client_cb_handle.
ARGUMENTS
handle - client_cb_handle,node of this to be removed
RETURN VALUE
return 0 on success, -negative on failure.
===========================================================================*/
int remove_from_list(int handle)
{
int ret = -EINVAL;
struct thermal_cdata *client = NULL,*prev_client = NULL;
if ( handle == 0 ||
handle >= CLIENT_HANDLE_MAX ||
0 == CLIENT_HANDLE_COND(handle))
return ret;
for (client = list_head; client != NULL; client = client->next) {
if (client->client_cb_handle != handle) {
prev_client = client;
continue;
}
if (client == list_head) {
list_head = list_head->next;
break;
} else {
prev_client->next = client->next;
break;
}
}
client_cb_handle &= ~(1 << handle);
if (client == NULL)
return ret;
free(client);
ret = 0;
return ret;
}
/*===========================================================================================
FUNCTION add_to_list
Function to add new client and its data to list while registering
with thermal.
ARGUMENTS
name - client name.
callback - callback function
data - client specific data
RETURN VALUE
return a unsigned non zero client handle on success, zero on failure.
=============================================================================================*/
int add_to_list(char *name, void *callback, void *data)
{
int ret = 0;
int i;
struct thermal_cdata *newclient = NULL;
if (NULL == name ||
NULL == callback)
return ret;
newclient = (struct thermal_cdata *) malloc(sizeof(struct thermal_cdata));
if (NULL == newclient) {
return ret;
}
memset(newclient, 0, sizeof(struct thermal_cdata));
for (i = 1; i < CLIENT_HANDLE_MAX; i++) {
if (!CLIENT_HANDLE_COND(i))
break;
}
if (i >= CLIENT_HANDLE_MAX)
return ret;
client_cb_handle |= (1<<i);
newclient->client_cb_handle = i;
newclient->client_name = name;
newclient->callback = callback;
newclient->user_data = data;
newclient->data_reserved = NULL;
newclient->next = NULL;
if (list_head == NULL) {
list_head = newclient;
} else {
newclient->next = list_head;
list_head = newclient;
}
ret = newclient->client_cb_handle;
return ret;
}

View File

@@ -1,38 +0,0 @@
/*===========================================================================
Copyright (c) 2013 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#ifndef __THERMAL_LIB_COMMON_H__
#define __THERMAL_LIB_COMMON_H__
#define THERMAL_SEND_CLIENT_SOCKET "/dev/socket/thermal-send-client"
#define THERMAL_RECV_CLIENT_SOCKET "/dev/socket/thermal-recv-client"
#define NUM_LISTEN_QUEUE (20)
#define LEVEL_MAX (3)
#define CLIENT_HANDLE_MAX (32)
#define CLIENT_NAME_MAX (12)
/* Thermal client data */
struct thermal_cdata {
int client_cb_handle;
char *client_name;
void *callback;
void *user_data;
void *data_reserved;
struct thermal_cdata *next;
};
/* Thermal socket message data type */
struct thermal_msg_data {
int msg_type;
char client_name[CLIENT_NAME_MAX];
int req_data;
};
int add_to_list(char *name, void *callback, void *data);
struct thermal_cdata *get_callback_node_from_list(struct thermal_cdata *list, char *name);
int remove_from_list(int handle);
#endif /* __THERMAL_LIB_COMMON_H__ */

View File

@@ -1,231 +0,0 @@
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
T H E R M A L _ M I T I G A T I O N _ D E V I C E _ S E R V I C E _ V 0 1 . C
GENERAL DESCRIPTION
This is the file which defines the tmd service Data structures.
Copyright (c) 2011 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
$Header: //source/qcom/qct/mpss/api/tmd/main/latest/src/thermal_mitigation_device_service_v01.c#1 $
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
*THIS IS AN AUTO GENERATED FILE. DO NOT ALTER IN ANY WAY
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
/* This file was generated with Tool version 2.7
It was generated on: Thu Sep 1 2011
From IDL File: thermal_mitigation_device_service_v01.idl */
#include "stdint.h"
#include "qmi_idl_lib_internal.h"
#include "thermal_mitigation_device_service_v01.h"
#include "common_v01.h"
/*Type Definitions*/
static const uint8_t tmd_mitigation_dev_id_type_data_v01[] = {
QMI_IDL_FLAGS_IS_ARRAY | QMI_IDL_FLAGS_IS_VARIABLE_LEN | QMI_IDL_STRING,
QMI_IDL_OFFSET8(tmd_mitigation_dev_id_type_v01, mitigation_dev_id),
QMI_TMD_MITIGATION_DEV_ID_LENGTH_MAX_V01,
QMI_IDL_FLAG_END_VALUE
};
static const uint8_t tmd_mitigation_dev_list_type_data_v01[] = {
QMI_IDL_AGGREGATE,
QMI_IDL_OFFSET8(tmd_mitigation_dev_list_type_v01, mitigation_dev_id),
0, 0,
QMI_IDL_GENERIC_1_BYTE,
QMI_IDL_OFFSET8(tmd_mitigation_dev_list_type_v01, max_mitigation_level),
QMI_IDL_FLAG_END_VALUE
};
/*Message Definitions*/
/*
* tmd_get_mitigation_device_list_req_msg is empty
* static const uint8_t tmd_get_mitigation_device_list_req_msg_data_v01[] = {
* };
*/
static const uint8_t tmd_get_mitigation_device_list_resp_msg_data_v01[] = {
0x02,
QMI_IDL_AGGREGATE,
QMI_IDL_OFFSET8(tmd_get_mitigation_device_list_resp_msg_v01, resp),
0, 1,
QMI_IDL_TLV_FLAGS_LAST_TLV | QMI_IDL_TLV_FLAGS_OPTIONAL | (QMI_IDL_OFFSET8(tmd_get_mitigation_device_list_resp_msg_v01, mitigation_device_list) - QMI_IDL_OFFSET8(tmd_get_mitigation_device_list_resp_msg_v01, mitigation_device_list_valid)),
0x10,
QMI_IDL_FLAGS_IS_ARRAY | QMI_IDL_FLAGS_IS_VARIABLE_LEN | QMI_IDL_AGGREGATE,
QMI_IDL_OFFSET8(tmd_get_mitigation_device_list_resp_msg_v01, mitigation_device_list),
QMI_TMD_MITIGATION_DEV_LIST_MAX_V01,
QMI_IDL_OFFSET8(tmd_get_mitigation_device_list_resp_msg_v01, mitigation_device_list) - QMI_IDL_OFFSET8(tmd_get_mitigation_device_list_resp_msg_v01, mitigation_device_list_len),
1, 0
};
static const uint8_t tmd_set_mitigation_level_req_msg_data_v01[] = {
0x01,
QMI_IDL_AGGREGATE,
QMI_IDL_OFFSET8(tmd_set_mitigation_level_req_msg_v01, mitigation_dev_id),
0, 0,
QMI_IDL_TLV_FLAGS_LAST_TLV | 0x02,
QMI_IDL_GENERIC_1_BYTE,
QMI_IDL_OFFSET8(tmd_set_mitigation_level_req_msg_v01, mitigation_level)
};
static const uint8_t tmd_set_mitigation_level_resp_msg_data_v01[] = {
QMI_IDL_TLV_FLAGS_LAST_TLV | 0x02,
QMI_IDL_AGGREGATE,
QMI_IDL_OFFSET8(tmd_set_mitigation_level_resp_msg_v01, resp),
0, 1
};
static const uint8_t tmd_get_mitigation_level_req_msg_data_v01[] = {
QMI_IDL_TLV_FLAGS_LAST_TLV | 0x01,
QMI_IDL_AGGREGATE,
QMI_IDL_OFFSET8(tmd_get_mitigation_level_req_msg_v01, mitigation_device),
0, 0
};
static const uint8_t tmd_get_mitigation_level_resp_msg_data_v01[] = {
0x02,
QMI_IDL_AGGREGATE,
QMI_IDL_OFFSET8(tmd_get_mitigation_level_resp_msg_v01, resp),
0, 1,
QMI_IDL_TLV_FLAGS_OPTIONAL | (QMI_IDL_OFFSET8(tmd_get_mitigation_level_resp_msg_v01, current_mitigation_level) - QMI_IDL_OFFSET8(tmd_get_mitigation_level_resp_msg_v01, current_mitigation_level_valid)),
0x10,
QMI_IDL_GENERIC_1_BYTE,
QMI_IDL_OFFSET8(tmd_get_mitigation_level_resp_msg_v01, current_mitigation_level),
QMI_IDL_TLV_FLAGS_LAST_TLV | QMI_IDL_TLV_FLAGS_OPTIONAL | (QMI_IDL_OFFSET8(tmd_get_mitigation_level_resp_msg_v01, requested_mitigation_level) - QMI_IDL_OFFSET8(tmd_get_mitigation_level_resp_msg_v01, requested_mitigation_level_valid)),
0x11,
QMI_IDL_GENERIC_1_BYTE,
QMI_IDL_OFFSET8(tmd_get_mitigation_level_resp_msg_v01, requested_mitigation_level)
};
static const uint8_t tmd_register_notification_mitigation_level_req_msg_data_v01[] = {
QMI_IDL_TLV_FLAGS_LAST_TLV | 0x01,
QMI_IDL_AGGREGATE,
QMI_IDL_OFFSET8(tmd_register_notification_mitigation_level_req_msg_v01, mitigation_device),
0, 0
};
static const uint8_t tmd_register_notification_mitigation_level_resp_msg_data_v01[] = {
QMI_IDL_TLV_FLAGS_LAST_TLV | 0x02,
QMI_IDL_AGGREGATE,
QMI_IDL_OFFSET8(tmd_register_notification_mitigation_level_resp_msg_v01, resp),
0, 1
};
static const uint8_t tmd_deregister_notification_mitigation_level_req_msg_data_v01[] = {
QMI_IDL_TLV_FLAGS_LAST_TLV | 0x01,
QMI_IDL_AGGREGATE,
QMI_IDL_OFFSET8(tmd_deregister_notification_mitigation_level_req_msg_v01, mitigation_device),
0, 0
};
static const uint8_t tmd_deregister_notification_mitigation_level_resp_msg_data_v01[] = {
QMI_IDL_TLV_FLAGS_LAST_TLV | 0x02,
QMI_IDL_AGGREGATE,
QMI_IDL_OFFSET8(tmd_deregister_notification_mitigation_level_resp_msg_v01, resp),
0, 1
};
static const uint8_t tmd_mitigation_level_report_ind_msg_data_v01[] = {
0x01,
QMI_IDL_AGGREGATE,
QMI_IDL_OFFSET8(tmd_mitigation_level_report_ind_msg_v01, mitigation_device),
0, 0,
QMI_IDL_TLV_FLAGS_LAST_TLV | 0x02,
QMI_IDL_GENERIC_1_BYTE,
QMI_IDL_OFFSET8(tmd_mitigation_level_report_ind_msg_v01, current_mitigation_level)
};
/* Type Table */
static const qmi_idl_type_table_entry tmd_type_table_v01[] = {
{sizeof(tmd_mitigation_dev_id_type_v01), tmd_mitigation_dev_id_type_data_v01},
{sizeof(tmd_mitigation_dev_list_type_v01), tmd_mitigation_dev_list_type_data_v01}
};
/* Message Table */
static const qmi_idl_message_table_entry tmd_message_table_v01[] = {
{0, 0},
{sizeof(tmd_get_mitigation_device_list_resp_msg_v01), tmd_get_mitigation_device_list_resp_msg_data_v01},
{sizeof(tmd_set_mitigation_level_req_msg_v01), tmd_set_mitigation_level_req_msg_data_v01},
{sizeof(tmd_set_mitigation_level_resp_msg_v01), tmd_set_mitigation_level_resp_msg_data_v01},
{sizeof(tmd_get_mitigation_level_req_msg_v01), tmd_get_mitigation_level_req_msg_data_v01},
{sizeof(tmd_get_mitigation_level_resp_msg_v01), tmd_get_mitigation_level_resp_msg_data_v01},
{sizeof(tmd_register_notification_mitigation_level_req_msg_v01), tmd_register_notification_mitigation_level_req_msg_data_v01},
{sizeof(tmd_register_notification_mitigation_level_resp_msg_v01), tmd_register_notification_mitigation_level_resp_msg_data_v01},
{sizeof(tmd_deregister_notification_mitigation_level_req_msg_v01), tmd_deregister_notification_mitigation_level_req_msg_data_v01},
{sizeof(tmd_deregister_notification_mitigation_level_resp_msg_v01), tmd_deregister_notification_mitigation_level_resp_msg_data_v01},
{sizeof(tmd_mitigation_level_report_ind_msg_v01), tmd_mitigation_level_report_ind_msg_data_v01}
};
/* Predefine the Type Table Object */
static const qmi_idl_type_table_object tmd_qmi_idl_type_table_object_v01;
/*Referenced Tables Array*/
static const qmi_idl_type_table_object *tmd_qmi_idl_type_table_object_referenced_tables_v01[] =
{&tmd_qmi_idl_type_table_object_v01, &common_qmi_idl_type_table_object_v01};
/*Type Table Object*/
static const qmi_idl_type_table_object tmd_qmi_idl_type_table_object_v01 = {
sizeof(tmd_type_table_v01)/sizeof(qmi_idl_type_table_entry ),
sizeof(tmd_message_table_v01)/sizeof(qmi_idl_message_table_entry),
1,
tmd_type_table_v01,
tmd_message_table_v01,
tmd_qmi_idl_type_table_object_referenced_tables_v01
};
/*Arrays of service_message_table_entries for commands, responses and indications*/
static const qmi_idl_service_message_table_entry tmd_service_command_messages_v01[] = {
{QMI_TMD_GET_MITIGATION_DEVICE_LIST_REQ_V01, TYPE16(0, 0), 0},
{QMI_TMD_SET_MITIGATION_LEVEL_REQ_V01, TYPE16(0, 2), 40},
{QMI_TMD_GET_MITIGATION_LEVEL_REQ_V01, TYPE16(0, 4), 36},
{QMI_TMD_REGISTER_NOTIFICATION_MITIGATION_LEVEL_REQ_V01, TYPE16(0, 6), 36},
{QMI_TMD_DEREGISTER_NOTIFICATION_MITIGATION_LEVEL_REQ_V01, TYPE16(0, 8), 36}
};
static const qmi_idl_service_message_table_entry tmd_service_response_messages_v01[] = {
{QMI_TMD_GET_MITIGATION_DEVICE_LIST_RESP_V01, TYPE16(0, 1), 1099},
{QMI_TMD_SET_MITIGATION_LEVEL_RESP_V01, TYPE16(0, 3), 7},
{QMI_TMD_GET_MITIGATION_LEVEL_RESP_V01, TYPE16(0, 5), 15},
{QMI_TMD_REGISTER_NOTIFICATION_MITIGATION_LEVEL_RESP_V01, TYPE16(0, 7), 7},
{QMI_TMD_DEREGISTER_NOTIFICATION_MITIGATION_LEVEL_RESP_V01, TYPE16(0, 9), 7}
};
static const qmi_idl_service_message_table_entry tmd_service_indication_messages_v01[] = {
{QMI_TMD_MITIGATION_LEVEL_REPORT_IND_V01, TYPE16(0, 10), 40}
};
/*Service Object*/
const struct qmi_idl_service_object tmd_qmi_idl_service_object_v01 = {
0x02,
0x01,
24,
1099,
{ sizeof(tmd_service_command_messages_v01)/sizeof(qmi_idl_service_message_table_entry),
sizeof(tmd_service_response_messages_v01)/sizeof(qmi_idl_service_message_table_entry),
sizeof(tmd_service_indication_messages_v01)/sizeof(qmi_idl_service_message_table_entry) },
{ tmd_service_command_messages_v01, tmd_service_response_messages_v01, tmd_service_indication_messages_v01},
&tmd_qmi_idl_type_table_object_v01
};
/* Service Object Accessor */
qmi_idl_service_object_type tmd_get_service_object_internal_v01
( int32_t idl_maj_version, int32_t idl_min_version, int32_t library_version ){
if ( TMD_V01_IDL_MAJOR_VERS != idl_maj_version || TMD_V01_IDL_MINOR_VERS != idl_min_version
|| TMD_V01_IDL_TOOL_VERS != library_version)
{
return NULL;
}
return (qmi_idl_service_object_type)&tmd_qmi_idl_service_object_v01;
}

View File

@@ -1,338 +0,0 @@
#ifndef TMD_SERVICE_H
#define TMD_SERVICE_H
/**
@file thermal_mitigation_device_service_v01.h
@brief This is the public header file which defines the tmd service Data structures.
This header file defines the types and structures that were defined in
tmd. It contains the constant values defined, enums, structures,
messages, and service message IDs (in that order) Structures that were
defined in the IDL as messages contain mandatory elements, optional
elements, a combination of mandatory and optional elements (mandatory
always come before optionals in the structure), or nothing (null message)
An optional element in a message is preceded by a uint8_t value that must be
set to true if the element is going to be included. When decoding a received
message, the uint8_t values will be set to true or false by the decode
routine, and should be checked before accessing the values that they
correspond to.
Variable sized arrays are defined as static sized arrays with an unsigned
integer (32 bit) preceding it that must be set to the number of elements
in the array that are valid. For Example:
uint32_t test_opaque_len;
uint8_t test_opaque[16];
If only 4 elements are added to test_opaque[] then test_opaque_len must be
set to 4 before sending the message. When decoding, the _len value is set
by the decode routine and should be checked so that the correct number of
elements in the array will be accessed.
*/
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
Copyright (c) 2011 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
$Header: //source/qcom/qct/mpss/api/tmd/main/latest/thermal_mitigation_device_service_v01.h#1 $
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
*THIS IS AN AUTO GENERATED FILE. DO NOT ALTER IN ANY WAY
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
/* This file was generated with Tool version 2.7
It was generated on: Thu Sep 1 2011
From IDL File: thermal_mitigation_device_service_v01.idl */
/** @defgroup tmd_qmi_consts Constant values defined in the IDL */
/** @defgroup tmd_qmi_msg_ids Constant values for QMI message IDs */
/** @defgroup tmd_qmi_enums Enumerated types used in QMI messages */
/** @defgroup tmd_qmi_messages Structures sent as QMI messages */
/** @defgroup tmd_qmi_aggregates Aggregate types used in QMI messages */
/** @defgroup tmd_qmi_accessor Accessor for QMI service object */
/** @defgroup tmd_qmi_version Constant values for versioning information */
#include <stdint.h>
#include "qmi_idl_lib.h"
#include "common_v01.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup tmd_qmi_version
@{
*/
/** Major Version Number of the IDL used to generate this file */
#define TMD_V01_IDL_MAJOR_VERS 0x01
/** Revision Number of the IDL used to generate this file */
#define TMD_V01_IDL_MINOR_VERS 0x00
/** Major Version Number of the qmi_idl_compiler used to generate this file */
#define TMD_V01_IDL_TOOL_VERS 0x02
/** Maximum Defined Message ID */
#define TMD_V01_MAX_MESSAGE_ID 0x0025;
/**
@}
*/
/** @addtogroup tmd_qmi_consts
@{
*/
#define QMI_TMD_MITIGATION_DEV_LIST_MAX_V01 32
#define QMI_TMD_MITIGATION_DEV_ID_LENGTH_MAX_V01 32
/**
@}
*/
/** @addtogroup tmd_qmi_aggregates
@{
*/
typedef struct {
char mitigation_dev_id[QMI_TMD_MITIGATION_DEV_ID_LENGTH_MAX_V01 + 1];
}tmd_mitigation_dev_id_type_v01; /* Type */
/**
@}
*/
/** @addtogroup tmd_qmi_aggregates
@{
*/
typedef struct {
tmd_mitigation_dev_id_type_v01 mitigation_dev_id;
/**< Mitigation device ID */
uint8_t max_mitigation_level;
/**< Maximum valid mitigation level; valid range from 0 - max_mitigation_level */
}tmd_mitigation_dev_list_type_v01; /* Type */
/**
@}
*/
/*
* tmd_get_mitigation_device_list_req_msg is empty
* typedef struct {
* }tmd_get_mitigation_device_list_req_msg_v01;
*/
/** @addtogroup tmd_qmi_messages
@{
*/
/** Response Message; This gets the list of mitigation devices from the remote endpoint. */
typedef struct {
/* Mandatory */
/* Result Code */
qmi_response_type_v01 resp;
/**< Standard response type. */
/* Optional */
uint8_t mitigation_device_list_valid; /**< Must be set to true if mitigation_device_list is being passed */
uint32_t mitigation_device_list_len; /**< Must be set to # of elements in mitigation_device_list */
tmd_mitigation_dev_list_type_v01 mitigation_device_list[QMI_TMD_MITIGATION_DEV_LIST_MAX_V01];
/**< List of mitigation devices on remote endpoint */
}tmd_get_mitigation_device_list_resp_msg_v01; /* Message */
/**
@}
*/
/** @addtogroup tmd_qmi_messages
@{
*/
/** Request Message; This sets thermal mitigation level for the specified mitigation
device. */
typedef struct {
/* Mandatory */
tmd_mitigation_dev_id_type_v01 mitigation_dev_id;
/**< Mitigation device ID */
/* Mandatory */
uint8_t mitigation_level;
/**< Thermal mitigation level to set, 0 defined as no mitigation,
with each level increment predefined to have increasing mitigative
effect. Per-device max valid level obtained from GET_MITIGATION_DEVICE_LIST. */
}tmd_set_mitigation_level_req_msg_v01; /* Message */
/**
@}
*/
/** @addtogroup tmd_qmi_messages
@{
*/
/** Response Message; This sets thermal mitigation level for the specified mitigation
device. */
typedef struct {
/* Mandatory */
/* Result Code */
qmi_response_type_v01 resp;
/**< Standard response type. */
}tmd_set_mitigation_level_resp_msg_v01; /* Message */
/**
@}
*/
/** @addtogroup tmd_qmi_messages
@{
*/
/** Request Message; This gets the thermal mitigation level for the mitigation device. */
typedef struct {
/* Mandatory */
tmd_mitigation_dev_id_type_v01 mitigation_device;
/**< Mitigation device */
}tmd_get_mitigation_level_req_msg_v01; /* Message */
/**
@}
*/
/** @addtogroup tmd_qmi_messages
@{
*/
/** Response Message; This gets the thermal mitigation level for the mitigation device. */
typedef struct {
/* Mandatory */
/* Result Code */
qmi_response_type_v01 resp;
/**< Standard response type. */
/* Optional */
uint8_t current_mitigation_level_valid; /**< Must be set to true if current_mitigation_level is being passed */
uint8_t current_mitigation_level;
/**< Current thermal mitigation level */
/* Optional */
uint8_t requested_mitigation_level_valid; /**< Must be set to true if requested_mitigation_level is being passed */
uint8_t requested_mitigation_level;
/**< Requested thermal mitigation level from client, defaults to 0 if
client has not previously set mitigation level */
}tmd_get_mitigation_level_resp_msg_v01; /* Message */
/**
@}
*/
/** @addtogroup tmd_qmi_messages
@{
*/
/** Request Message; Registers for notification of mitigation device level change. */
typedef struct {
/* Mandatory */
tmd_mitigation_dev_id_type_v01 mitigation_device;
/**< Mitigation device */
}tmd_register_notification_mitigation_level_req_msg_v01; /* Message */
/**
@}
*/
/** @addtogroup tmd_qmi_messages
@{
*/
/** Response Message; Registers for notification of mitigation device level change. */
typedef struct {
/* Mandatory */
/* Result Code */
qmi_response_type_v01 resp;
/**< Standard response type. */
}tmd_register_notification_mitigation_level_resp_msg_v01; /* Message */
/**
@}
*/
/** @addtogroup tmd_qmi_messages
@{
*/
/** Request Message; Deregisters notification for mitigation device level changes. */
typedef struct {
/* Mandatory */
tmd_mitigation_dev_id_type_v01 mitigation_device;
/**< Mitigation device */
}tmd_deregister_notification_mitigation_level_req_msg_v01; /* Message */
/**
@}
*/
/** @addtogroup tmd_qmi_messages
@{
*/
/** Response Message; Deregisters notification for mitigation device level changes. */
typedef struct {
/* Mandatory */
/* Result Code */
qmi_response_type_v01 resp;
/**< Standard response type. */
}tmd_deregister_notification_mitigation_level_resp_msg_v01; /* Message */
/**
@}
*/
/** @addtogroup tmd_qmi_messages
@{
*/
/** Indication Message; Indicates that a mitigation level report has been received */
typedef struct {
/* Mandatory */
tmd_mitigation_dev_id_type_v01 mitigation_device;
/**< Mitigation device */
/* Mandatory */
uint8_t current_mitigation_level;
/**< Current thermal mitigation level */
}tmd_mitigation_level_report_ind_msg_v01; /* Message */
/**
@}
*/
/*Service Message Definition*/
/** @addtogroup tmd_qmi_msg_ids
@{
*/
#define QMI_TMD_GET_MITIGATION_DEVICE_LIST_REQ_V01 0x0020
#define QMI_TMD_GET_MITIGATION_DEVICE_LIST_RESP_V01 0x0020
#define QMI_TMD_SET_MITIGATION_LEVEL_REQ_V01 0x0021
#define QMI_TMD_SET_MITIGATION_LEVEL_RESP_V01 0x0021
#define QMI_TMD_GET_MITIGATION_LEVEL_REQ_V01 0x0022
#define QMI_TMD_GET_MITIGATION_LEVEL_RESP_V01 0x0022
#define QMI_TMD_REGISTER_NOTIFICATION_MITIGATION_LEVEL_REQ_V01 0x0023
#define QMI_TMD_REGISTER_NOTIFICATION_MITIGATION_LEVEL_RESP_V01 0x0023
#define QMI_TMD_DEREGISTER_NOTIFICATION_MITIGATION_LEVEL_REQ_V01 0x0024
#define QMI_TMD_DEREGISTER_NOTIFICATION_MITIGATION_LEVEL_RESP_V01 0x0024
#define QMI_TMD_MITIGATION_LEVEL_REPORT_IND_V01 0x0025
/**
@}
*/
/* Service Object Accessor */
/** @addtogroup wms_qmi_accessor
@{
*/
/** This function is used internally by the autogenerated code. Clients should use the
macro tmd_get_service_object_v01( ) that takes in no arguments. */
qmi_idl_service_object_type tmd_get_service_object_internal_v01
( int32_t idl_maj_version, int32_t idl_min_version, int32_t library_version );
/** This macro should be used to get the service object */
#define tmd_get_service_object_v01( ) \
tmd_get_service_object_internal_v01( \
TMD_V01_IDL_MAJOR_VERS, TMD_V01_IDL_MINOR_VERS, \
TMD_V01_IDL_TOOL_VERS )
/**
@}
*/
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,318 +0,0 @@
/*===========================================================================
Copyright (c) 2010-2012 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/ioctl.h>
#include <pthread.h>
#include "thermal.h"
static void clear_all_alarms(sensor_setting_t *sensor, int sensor_temp)
{
int i, cpu;
#ifndef IPQ_806x
int gpu;
#endif
for (i = 0; i < ACTION_IDX_MAX; i++) {
/* check if action may have been set */
if ((sensor->action_mask & (1 << i)) == 0)
continue;
switch (i) {
case CPU_FREQ:
/* set CPU speed to highest */
for (cpu = 0; cpu < num_cpus; cpu++) {
cpufreq_request(cpu, sensor->id,
sensor_temp, -1);
}
break;
#ifndef IPQ_806x
case GPU_FREQ:
/* set GPU speed to highest */
for (gpu = 0; gpu < num_gpus; gpu++) {
gpufreq_request(gpu, sensor->id,
sensor_temp, -1);
}
break;
case LCD:
lcd_brightness_request(sensor->id, sensor_temp, -1);
break;
case MODEM:
modem_request(sensor->id, sensor_temp, 0);
break;
case FUSION:
fusion_modem_request(sensor->id, sensor_temp, 0);
break;
case BATTERY:
battery_request(sensor->id, sensor_temp, 0);
break;
case WLAN:
wlan_request(sensor->id, sensor_temp, 0);
break;
case CAMERA:
camera_request(sensor->id, sensor_temp, 0);
break;
case CAMCORDER:
camcorder_request(sensor->id, sensor_temp, 0);
break;
#endif
#ifdef IPQ_806x
case POWERSAVE:
powersave_request(0);
break;
case NSS_FREQ:
nssfreq_request(-1);
break;
#endif
}
}
sensor->action_mask = 0;
}
void *sensor_monitor(void *vsensor)
{
sensor_setting_t *sensor = (sensor_setting_t *)vsensor;
int i, j, cpu;
#ifndef IPQ_806x
int gpu;
#endif
int max_thr;
int lvl_alarm[THRESHOLDS_MAX];
int alarm_raised = 0, alarm_cleared = 0;
int sensor_temp = 0;
int lvl_max, lvl_min;
int threshold_type = THRESHOLD_NOCHANGE;
int threshold_level = 0;
if (!sensor || (sensor->num_thresholds < 1))
return NULL;
max_thr = sensor->num_thresholds;
for (i = 0; i < max_thr; i++) {
lvl_alarm[i] = 0;
}
while (exit_daemon != 1) {
sensor_wait(sensor);
sensor_temp = sensor_get_temperature(sensor);
lvl_max = -1;
lvl_min = INT_MAX;
for (i = max_thr - 1; i >= 0; i--) {
/* Scan for new alarm conditions */
if (sensor_threshold_trigger(sensor_temp, sensor, i)) {
if (lvl_alarm[i] == 0) {
info("Sensor '%s' - alarm raised %d at %2.1f degC\n",
sensor->desc, i + 1, RCONV(sensor_temp));
lvl_alarm[i] = 1;
alarm_raised = 1;
}
if (i > lvl_max)
lvl_max = i;
}
/* Scan for alarm clearing conditions */
if (sensor_threshold_clear(sensor_temp, sensor, i)) {
if (lvl_alarm[i] == 1) {
info("Sensor '%s' - alarm cleared %d at %2.1f degC\n",
sensor->desc, i + 1, RCONV(sensor_temp));
lvl_alarm[i] = 0;
alarm_cleared = 1;
}
if (i < lvl_min)
lvl_min = i;
}
}
/* Update temperature thresholds */
if (alarm_raised) {
threshold_type = THRESHOLD_CROSS;
threshold_level = lvl_max + 1;
} else if (alarm_cleared) {
threshold_type = THRESHOLD_CLEAR;
threshold_level = lvl_min;
} else {
threshold_type = THRESHOLD_NOCHANGE;
threshold_level = sensor->last_lvl;
}
sensor->last_lvl = threshold_level;
sensor_update_thresholds(sensor, threshold_type, threshold_level);
if (!alarm_raised && !alarm_cleared) {
continue;
}
/* Perform actions on highest level alarm */
for (i = max_thr - 1; i >= 0; i--) {
if (lvl_alarm[i] == 0)
continue;
for (j = 0; j < sensor->t[i].num_actions; j++) {
dbgmsg ("j=%d i=%d Sensor %s: action %d value %d\n",
j, i, sensor->desc,
sensor->t[i].actions[j].action,
sensor->t[i].actions[j].info);
sensor->action_mask |= (1 << sensor->t[i].actions[j].action);
switch(sensor->t[i].actions[j].action) {
case NONE:
break;
case CPU_FREQ:
for (cpu = 0; cpu < num_cpus; cpu++) {
cpufreq_request(cpu, sensor->id,
sensor_temp,
sensor->t[i].actions[j].info);
}
break;
case SHUTDOWN:
shutdown_action(sensor->id, sensor_temp, sensor->t[i].actions[j].info);
break;
#ifdef IPQ_806x
case POWERSAVE:
powersave_request(sensor->t[i].actions[j].info);
break;
case NSS_FREQ:
nssfreq_request(sensor->t[i].actions[j].info);
break;
#else
case REPORT:
if (alarm_raised)
report_action(sensor->id, sensor_temp, i, 1);
break;
case GPU_FREQ:
for (gpu = 0; gpu < num_gpus; gpu++) {
gpufreq_request(gpu, sensor->id,
sensor_temp,
sensor->t[i].actions[j].info);
}
break;
case LCD:
lcd_brightness_request(sensor->id,
sensor_temp,
sensor->t[i].actions[j].info);
break;
case MODEM:
modem_request(sensor->id, sensor_temp, sensor->t[i].actions[j].info);
break;
case FUSION:
fusion_modem_request(sensor->id, sensor_temp, sensor->t[i].actions[j].info);
break;
case BATTERY:
battery_request(sensor->id, sensor_temp, sensor->t[i].actions[j].info);
break;
case WLAN:
wlan_request(sensor->id, sensor_temp, sensor->t[i].actions[j].info);
break;
case CAMERA:
camera_request(sensor->id, sensor_temp, sensor->t[i].actions[j].info);
break;
case CAMCORDER:
camcorder_request(sensor->id, sensor_temp, sensor->t[i].actions[j].info);
break;
#endif
default:
msg("Unknown action %d\n", sensor->t[i].actions[j].action);
}
}
break;
}
if (alarm_cleared) {
/* Handle alarm clearing cases */
if (lvl_min == 0) {
dbgmsg("Clearing all alarms on sensor %s\n", sensor->desc);
clear_all_alarms(sensor, sensor_temp);
}
#ifndef IPQ_806x
/* report threshold clearing */
for (j = 0; j < sensor->t[lvl_min].num_actions; j++) {
if (REPORT == sensor->t[lvl_min].actions[j].action) {
report_action(sensor->id, sensor_temp, lvl_min, 0);
break;
}
}
#endif
}
alarm_raised = 0;
alarm_cleared = 0;
}
return NULL;
}
void thermal_monitor(thermal_setting_t *settings)
{
int i;
int act_cnt;
int thrs_cnt;
int valid_act_cnt;
int max_thr;
if (!sensors_setup(settings)) {
msg("Failed to setup at least one sensor for monitoring\n");
return;
}
if (settings->disable_unused_tsens) {
for (i = 0; i < SENSOR_IDX_MAX; i++){
dbgmsg("Disabling sensor %d\n", i);
sensor_enable(&settings->sensors[i], i, 0 );
}
}
for (i = 0; i < SENSOR_IDX_MAX; i++){
max_thr = settings->sensors[i].num_thresholds;
valid_act_cnt = 0;
for (thrs_cnt = max_thr - 1; thrs_cnt >= 0; thrs_cnt--) {
for( act_cnt = 0 ; act_cnt < settings->sensors[i].t[thrs_cnt].num_actions;act_cnt++ ){
if( NONE != settings->sensors[i].t[thrs_cnt].actions[act_cnt].action )
valid_act_cnt++;
}
}
dbgmsg("Sensor %d: No.of valid actions: %d\n" , i , valid_act_cnt );
if (valid_act_cnt) {
dbgmsg("%s - Enabling sensor: %d tzn: %d\n" , __func__ , i, settings->sensors[i].sensor->tzn);
sensor_enable(&settings->sensors[i], settings->sensors[i].sensor->tzn, 1 );
} else
continue;
dbgmsg("Spawn Monitor thread for sensor: %d\n" , i );
if (pthread_create(&settings->sensors[i].monitor,
NULL,
(void *)&sensor_monitor,
(void *)&settings->sensors[i]) != 0) {
msg("Error initializing monitor for sensor '%s'\n",
sensor_names[i]);
settings->sensors[i].disabled = 1;
}
}
for (i = 0; i < SENSOR_IDX_MAX; i++) {
if (!settings->sensors[i].disabled &&
(settings->sensors[i].num_thresholds > 0)) {
pthread_join(settings->sensors[i].monitor, NULL);
}
}
sensors_shutdown();
}

View File

@@ -1,179 +0,0 @@
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
T H E R M A L _ S E N S O R _ S E R V I C E _ V 0 1 . C
GENERAL DESCRIPTION
This is the file which defines the ts service Data structures.
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
*THIS IS AN AUTO GENERATED FILE. DO NOT ALTER IN ANY WAY
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
/* This file was generated with Tool version 4.2
It was generated on: Mon Dec 5 2011
From IDL File: thermal_sensor_service_v01.idl */
#include "stdint.h"
#include "qmi_idl_lib_internal.h"
#include "thermal_sensor_service_v01.h"
#include "common_v01.h"
/*Type Definitions*/
static const uint8_t ts_sensor_type_data_v01[] = {
QMI_IDL_FLAGS_IS_ARRAY | QMI_IDL_FLAGS_IS_VARIABLE_LEN | QMI_IDL_STRING,
QMI_IDL_OFFSET8(ts_sensor_type_v01, sensor_id),
QMI_TS_SENSOR_ID_LENGTH_MAX_V01,
QMI_IDL_FLAG_END_VALUE
};
/*Message Definitions*/
/*
* ts_get_sensor_list_req_msg is empty
* static const uint8_t ts_get_sensor_list_req_msg_data_v01[] = {
* };
*/
static const uint8_t ts_get_sensor_list_resp_msg_data_v01[] = {
0x02,
QMI_IDL_AGGREGATE,
QMI_IDL_OFFSET8(ts_get_sensor_list_resp_msg_v01, resp),
0, 1,
QMI_IDL_TLV_FLAGS_LAST_TLV | QMI_IDL_TLV_FLAGS_OPTIONAL | (QMI_IDL_OFFSET8(ts_get_sensor_list_resp_msg_v01, sensor_list) - QMI_IDL_OFFSET8(ts_get_sensor_list_resp_msg_v01, sensor_list_valid)),
0x10,
QMI_IDL_FLAGS_IS_ARRAY | QMI_IDL_FLAGS_IS_VARIABLE_LEN | QMI_IDL_AGGREGATE,
QMI_IDL_OFFSET8(ts_get_sensor_list_resp_msg_v01, sensor_list),
QMI_TS_SENSOR_LIST_MAX_V01,
QMI_IDL_OFFSET8(ts_get_sensor_list_resp_msg_v01, sensor_list) - QMI_IDL_OFFSET8(ts_get_sensor_list_resp_msg_v01, sensor_list_len),
0, 0
};
static const uint8_t ts_register_notification_temp_req_msg_data_v01[] = {
0x01,
QMI_IDL_AGGREGATE,
QMI_IDL_OFFSET8(ts_register_notification_temp_req_msg_v01, sensor_id),
0, 0,
0x02,
QMI_IDL_GENERIC_1_BYTE,
QMI_IDL_OFFSET8(ts_register_notification_temp_req_msg_v01, send_current_temp_report),
QMI_IDL_TLV_FLAGS_OPTIONAL | (QMI_IDL_OFFSET8(ts_register_notification_temp_req_msg_v01, temp_threshold_high) - QMI_IDL_OFFSET8(ts_register_notification_temp_req_msg_v01, temp_threshold_high_valid)),
0x10,
QMI_IDL_GENERIC_4_BYTE,
QMI_IDL_OFFSET8(ts_register_notification_temp_req_msg_v01, temp_threshold_high),
QMI_IDL_TLV_FLAGS_OPTIONAL | (QMI_IDL_OFFSET8(ts_register_notification_temp_req_msg_v01, temp_threshold_low) - QMI_IDL_OFFSET8(ts_register_notification_temp_req_msg_v01, temp_threshold_low_valid)),
0x11,
QMI_IDL_GENERIC_4_BYTE,
QMI_IDL_OFFSET8(ts_register_notification_temp_req_msg_v01, temp_threshold_low),
QMI_IDL_TLV_FLAGS_LAST_TLV | QMI_IDL_TLV_FLAGS_OPTIONAL | (QMI_IDL_OFFSET8(ts_register_notification_temp_req_msg_v01, seq_num) - QMI_IDL_OFFSET8(ts_register_notification_temp_req_msg_v01, seq_num_valid)),
0x12,
QMI_IDL_GENERIC_4_BYTE,
QMI_IDL_OFFSET8(ts_register_notification_temp_req_msg_v01, seq_num)
};
static const uint8_t ts_register_notification_temp_resp_msg_data_v01[] = {
QMI_IDL_TLV_FLAGS_LAST_TLV | 0x02,
QMI_IDL_AGGREGATE,
QMI_IDL_OFFSET8(ts_register_notification_temp_resp_msg_v01, resp),
0, 1
};
static const uint8_t ts_temp_report_ind_msg_data_v01[] = {
0x01,
QMI_IDL_AGGREGATE,
QMI_IDL_OFFSET8(ts_temp_report_ind_msg_v01, sensor_id),
0, 0,
0x02,
QMI_IDL_GENERIC_4_BYTE,
QMI_IDL_OFFSET8(ts_temp_report_ind_msg_v01, report_type),
QMI_IDL_TLV_FLAGS_OPTIONAL | (QMI_IDL_OFFSET8(ts_temp_report_ind_msg_v01, temp) - QMI_IDL_OFFSET8(ts_temp_report_ind_msg_v01, temp_valid)),
0x10,
QMI_IDL_GENERIC_4_BYTE,
QMI_IDL_OFFSET8(ts_temp_report_ind_msg_v01, temp),
QMI_IDL_TLV_FLAGS_LAST_TLV | QMI_IDL_TLV_FLAGS_OPTIONAL | (QMI_IDL_OFFSET8(ts_temp_report_ind_msg_v01, seq_num) - QMI_IDL_OFFSET8(ts_temp_report_ind_msg_v01, seq_num_valid)),
0x11,
QMI_IDL_GENERIC_4_BYTE,
QMI_IDL_OFFSET8(ts_temp_report_ind_msg_v01, seq_num)
};
/* Type Table */
static const qmi_idl_type_table_entry ts_type_table_v01[] = {
{sizeof(ts_sensor_type_v01), ts_sensor_type_data_v01}
};
/* Message Table */
static const qmi_idl_message_table_entry ts_message_table_v01[] = {
{0, 0},
{sizeof(ts_get_sensor_list_resp_msg_v01), ts_get_sensor_list_resp_msg_data_v01},
{sizeof(ts_register_notification_temp_req_msg_v01), ts_register_notification_temp_req_msg_data_v01},
{sizeof(ts_register_notification_temp_resp_msg_v01), ts_register_notification_temp_resp_msg_data_v01},
{sizeof(ts_temp_report_ind_msg_v01), ts_temp_report_ind_msg_data_v01}
};
/* Predefine the Type Table Object */
static const qmi_idl_type_table_object ts_qmi_idl_type_table_object_v01;
/*Referenced Tables Array*/
static const qmi_idl_type_table_object *ts_qmi_idl_type_table_object_referenced_tables_v01[] =
{&ts_qmi_idl_type_table_object_v01, &common_qmi_idl_type_table_object_v01};
/*Type Table Object*/
static const qmi_idl_type_table_object ts_qmi_idl_type_table_object_v01 = {
sizeof(ts_type_table_v01)/sizeof(qmi_idl_type_table_entry ),
sizeof(ts_message_table_v01)/sizeof(qmi_idl_message_table_entry),
1,
ts_type_table_v01,
ts_message_table_v01,
ts_qmi_idl_type_table_object_referenced_tables_v01
};
/*Arrays of service_message_table_entries for commands, responses and indications*/
static const qmi_idl_service_message_table_entry ts_service_command_messages_v01[] = {
{QMI_TS_GET_SENSOR_LIST_REQ_V01, TYPE16(0, 0), 0},
{QMI_TS_REGISTER_NOTIFICATION_TEMP_REQ_V01, TYPE16(0, 2), 61}
};
static const qmi_idl_service_message_table_entry ts_service_response_messages_v01[] = {
{QMI_TS_GET_SENSOR_LIST_RESP_V01, TYPE16(0, 1), 1067},
{QMI_TS_REGISTER_NOTIFICATION_TEMP_RESP_V01, TYPE16(0, 3), 7}
};
static const qmi_idl_service_message_table_entry ts_service_indication_messages_v01[] = {
{QMI_TS_TEMP_REPORT_IND_V01, TYPE16(0, 4), 57}
};
/*Service Object*/
const struct qmi_idl_service_object ts_qmi_idl_service_object_v01 = {
0x04,
0x01,
23,
1067,
{ sizeof(ts_service_command_messages_v01)/sizeof(qmi_idl_service_message_table_entry),
sizeof(ts_service_response_messages_v01)/sizeof(qmi_idl_service_message_table_entry),
sizeof(ts_service_indication_messages_v01)/sizeof(qmi_idl_service_message_table_entry) },
{ ts_service_command_messages_v01, ts_service_response_messages_v01, ts_service_indication_messages_v01},
&ts_qmi_idl_type_table_object_v01
};
/* Service Object Accessor */
qmi_idl_service_object_type ts_get_service_object_internal_v01
( int32_t idl_maj_version, int32_t idl_min_version, int32_t library_version ){
if ( TS_V01_IDL_MAJOR_VERS != idl_maj_version || TS_V01_IDL_MINOR_VERS != idl_min_version
|| TS_V01_IDL_TOOL_VERS != library_version)
{
return NULL;
}
return (qmi_idl_service_object_type)&ts_qmi_idl_service_object_v01;
}

View File

@@ -1,272 +0,0 @@
#ifndef TS_SERVICE_H
#define TS_SERVICE_H
/**
@file thermal_sensor_service_v01.h
@brief This is the public header file which defines the ts service Data structures.
This header file defines the types and structures that were defined in
ts. It contains the constant values defined, enums, structures,
messages, and service message IDs (in that order) Structures that were
defined in the IDL as messages contain mandatory elements, optional
elements, a combination of mandatory and optional elements (mandatory
always come before optionals in the structure), or nothing (null message)
An optional element in a message is preceded by a uint8_t value that must be
set to true if the element is going to be included. When decoding a received
message, the uint8_t values will be set to true or false by the decode
routine, and should be checked before accessing the values that they
correspond to.
Variable sized arrays are defined as static sized arrays with an unsigned
integer (32 bit) preceding it that must be set to the number of elements
in the array that are valid. For Example:
uint32_t test_opaque_len;
uint8_t test_opaque[16];
If only 4 elements are added to test_opaque[] then test_opaque_len must be
set to 4 before sending the message. When decoding, the _len value is set
by the decode routine and should be checked so that the correct number of
elements in the array will be accessed.
*/
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
Copyright (c) 2011 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
$Header: //source/qcom/qct/interfaces/qmi/ts/main/latest/api/thermal_sensor_service_v01.h#2 $
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
*THIS IS AN AUTO GENERATED FILE. DO NOT ALTER IN ANY WAY
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
/* This file was generated with Tool version 4.2
It was generated on: Mon Dec 5 2011
From IDL File: thermal_sensor_service_v01.idl */
/** @defgroup ts_qmi_consts Constant values defined in the IDL */
/** @defgroup ts_qmi_msg_ids Constant values for QMI message IDs */
/** @defgroup ts_qmi_enums Enumerated types used in QMI messages */
/** @defgroup ts_qmi_messages Structures sent as QMI messages */
/** @defgroup ts_qmi_aggregates Aggregate types used in QMI messages */
/** @defgroup ts_qmi_accessor Accessor for QMI service object */
/** @defgroup ts_qmi_version Constant values for versioning information */
#include <stdint.h>
#include "qmi_idl_lib.h"
#include "common_v01.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup ts_qmi_version
@{
*/
/** Major Version Number of the IDL used to generate this file */
#define TS_V01_IDL_MAJOR_VERS 0x01
/** Revision Number of the IDL used to generate this file */
#define TS_V01_IDL_MINOR_VERS 0x00
/** Major Version Number of the qmi_idl_compiler used to generate this file */
#define TS_V01_IDL_TOOL_VERS 0x04
/** Maximum Defined Message ID */
#define TS_V01_MAX_MESSAGE_ID 0x0022;
/**
@}
*/
/** @addtogroup ts_qmi_consts
@{
*/
#define QMI_TS_SENSOR_LIST_MAX_V01 32
#define QMI_TS_SENSOR_ID_LENGTH_MAX_V01 32
/**
@}
*/
/** @addtogroup ts_qmi_aggregates
@{
*/
typedef struct {
char sensor_id[QMI_TS_SENSOR_ID_LENGTH_MAX_V01 + 1];
/**< Sensor ID */
}ts_sensor_type_v01; /* Type */
/**
@}
*/
/*
* ts_get_sensor_list_req_msg is empty
* typedef struct {
* }ts_get_sensor_list_req_msg_v01;
*/
/** @addtogroup ts_qmi_messages
@{
*/
/** Response Message; Gets the list of sensors from the remote endpoint. */
typedef struct {
/* Mandatory */
/* Result Code */
qmi_response_type_v01 resp;
/**< Standard response type. */
/* Optional */
/* Sensor List */
uint8_t sensor_list_valid; /**< Must be set to true if sensor_list is being passed */
uint32_t sensor_list_len; /**< Must be set to # of elements in sensor_list */
ts_sensor_type_v01 sensor_list[QMI_TS_SENSOR_LIST_MAX_V01];
}ts_get_sensor_list_resp_msg_v01; /* Message */
/**
@}
*/
/** @addtogroup ts_qmi_messages
@{
*/
/** Request Message; Registers for notification of temperature sensor readings.
Indicates threshold temperatures for notification. */
typedef struct {
/* Mandatory */
/* Sensor ID */
ts_sensor_type_v01 sensor_id;
/* Mandatory */
/* Current Temperature Report */
uint8_t send_current_temp_report;
/**< Request for current temperature report indication.
*/
/* Optional */
/* High Threshold Temperature */
uint8_t temp_threshold_high_valid; /**< Must be set to true if temp_threshold_high is being passed */
float temp_threshold_high;
/**< High threshold temperature in degrees Celsius.
*/
/* Optional */
/* Low Threshold Temperature */
uint8_t temp_threshold_low_valid; /**< Must be set to true if temp_threshold_low is being passed */
float temp_threshold_low;
/**< Low threshold temperature in degrees Celsius.
*/
/* Optional */
/* Sequence Number */
uint8_t seq_num_valid; /**< Must be set to true if seq_num is being passed */
uint32_t seq_num;
/**< Optional sequence cookie to match the registration with the indication.
*/
}ts_register_notification_temp_req_msg_v01; /* Message */
/**
@}
*/
/** @addtogroup ts_qmi_messages
@{
*/
/** Response Message; Registers for notification of temperature sensor readings.
Indicates threshold temperatures for notification. */
typedef struct {
/* Mandatory */
/* Result Code */
qmi_response_type_v01 resp;
/**< Standard response type. */
}ts_register_notification_temp_resp_msg_v01; /* Message */
/**
@}
*/
/** @addtogroup ts_qmi_enums
@{
*/
typedef enum {
TS_TEMP_REPORT_TYPE_ENUM_MIN_ENUM_VAL_V01 = -2147483647, /**< To force a 32 bit signed enum. Do not change or use*/
QMI_TS_TEMP_REPORT_CURRENT_TEMP_V01 = 0,
QMI_TS_TEMP_REPORT_THRESHOLD_HIGH_V01 = 1,
QMI_TS_TEMP_REPORT_THRESHOLD_LOW_V01 = 2,
TS_TEMP_REPORT_TYPE_ENUM_MAX_ENUM_VAL_V01 = 2147483647 /**< To force a 32 bit signed enum. Do not change or use*/
}ts_temp_report_type_enum_v01;
/**
@}
*/
/** @addtogroup ts_qmi_messages
@{
*/
/** Indication Message; Indicates that a temperature report has been received. */
typedef struct {
/* Mandatory */
/* Sensor ID */
ts_sensor_type_v01 sensor_id;
/* Mandatory */
/* Sensor Reported */
ts_temp_report_type_enum_v01 report_type;
/**< Indicates temperature report type. If report_type is not recognized,
the client ignores the report.
*/
/* Optional */
/* Temperature */
uint8_t temp_valid; /**< Must be set to true if temp is being passed */
float temp;
/**< Temperature report in degrees Celsius. If this field is omitted,
the service cannot obtain the temperature value from the sensor.
*/
/* Optional */
/* Sequence Number */
uint8_t seq_num_valid; /**< Must be set to true if seq_num is being passed */
uint32_t seq_num;
/**< Optional sequence cookie to match the registration with the indication.
*/
}ts_temp_report_ind_msg_v01; /* Message */
/**
@}
*/
/*Service Message Definition*/
/** @addtogroup ts_qmi_msg_ids
@{
*/
#define QMI_TS_GET_SENSOR_LIST_REQ_V01 0x0020
#define QMI_TS_GET_SENSOR_LIST_RESP_V01 0x0020
#define QMI_TS_REGISTER_NOTIFICATION_TEMP_REQ_V01 0x0021
#define QMI_TS_REGISTER_NOTIFICATION_TEMP_RESP_V01 0x0021
#define QMI_TS_TEMP_REPORT_IND_V01 0x0022
/**
@}
*/
/* Service Object Accessor */
/** @addtogroup wms_qmi_accessor
@{
*/
/** This function is used internally by the autogenerated code. Clients should use the
macro ts_get_service_object_v01( ) that takes in no arguments. */
qmi_idl_service_object_type ts_get_service_object_internal_v01
( int32_t idl_maj_version, int32_t idl_min_version, int32_t library_version );
/** This macro should be used to get the service object */
#define ts_get_service_object_v01( ) \
ts_get_service_object_internal_v01( \
TS_V01_IDL_MAJOR_VERS, TS_V01_IDL_MINOR_VERS, \
TS_V01_IDL_TOOL_VERS )
/**
@}
*/
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,467 +0,0 @@
/*========================================================================================
thermal_server.c
GENERAL DESCRIPTION
Thermal socket server related code to communicate with thermal DLL.
Copyright (c) 2013 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
==========================================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include <linux/types.h>
#include <sys/socket.h>
#include <linux/un.h>
#include <sys/ioctl.h>
#include <private/android_filesystem_config.h>
#include "thermal.h"
#include "thermal_lib_common.h"
#include "thermal_server.h"
static int sockfd_server_send = -1;
static int sockfd_server_recv = -1;
static pthread_t listen_client_fd_thread;
static int server_socket_exit = 0;
static pthread_mutex_t soc_client_mutex;
static int thermal_send_fds[NUM_LISTEN_QUEUE];
struct thermal_cdata *list_head = NULL;
static char *req_client_names[] =
{
"spkr",
"override",
};
static char *notify_client_names[] =
{
"camera",
"camcorder",
"spkr",
};
/*========================================================================================
FUNCTION thermal_recv_data_from_client
Recieve requested data from client through socket and based on data
invoke appropriate thermal callback from list which already registered.
ARGUMENTS
client_fd - client fd for thermal recv socket
RETURN VALUE
0 on success, negative on failure.
========================================================================================*/
static int thermal_recv_data_from_client(int client_fd)
{
int rc;
int i;
int ret = -EINVAL;
int count = 0;
int (*callback)(int, void *, void *);
struct thermal_cdata *callback_node;
struct thermal_msg_data client_msg;
if (client_fd == -1)
return ret;
memset(&client_msg, 0, sizeof(struct thermal_msg_data));
rc = recv(client_fd, &client_msg, sizeof(struct thermal_msg_data), 0);
if (rc <= 0) {
msg("Thermal-Server: %s: recv failed", __func__);
return ret;
}
if (rc != sizeof(struct thermal_msg_data))
return ret;
for (i = 0; i < CLIENT_NAME_MAX; i++) {
if (client_msg.client_name[i] == '\0')
break;
}
if (i >= CLIENT_NAME_MAX)
client_msg.client_name[CLIENT_NAME_MAX - 1] = '\0';
info("Thermal-Server: Thermal received "
"msg %s %d", client_msg.client_name, client_msg.req_data);
/* Check for client is supported or not*/
for (i = 0; i < ARRAY_SIZE(req_client_names); i++) {
if (0 == strncmp(req_client_names[i], client_msg.client_name, CLIENT_NAME_MAX))
break;
}
if (i >= ARRAY_SIZE(req_client_names)) {
msg("Thermal-Server:%s is not in supported "
"thermal client list", client_msg.client_name);
return ret;
}
for (callback_node = list_head; callback_node != NULL; callback_node = callback_node->next) {
callback_node = get_callback_node_from_list(callback_node, client_msg.client_name);
if (callback_node) {
count++;
callback = callback_node->callback;
if (callback)
callback(client_msg.req_data, callback_node->user_data, callback_node->data_reserved);
} else {
if (count == 0)
msg("Thermal-Server: No clients are "
"connected for %s", client_msg.client_name);
break;
}
}
ret = 0;
return ret;
}
/*========================================================================================
FUNCTION do_listen_client_fd
Seperate thread function for monitoring thermal usersapce clients and recieving
client data from thermal recv socket once it is notified.
ARGUMENTS
data - data, not used
RETURN VALUE
void
========================================================================================*/
static void *do_listen_client_fd(void *data)
{
int fd;
int i;
int nread;
int result;
int client_len;
int client_fd = -1;
struct sockaddr_un client_addr;
fd_set t_readfds,testfds;
FD_ZERO(&t_readfds);
FD_SET(sockfd_server_send, &t_readfds);
FD_SET(sockfd_server_recv, &t_readfds);
for (i = 0; i < NUM_LISTEN_QUEUE; i++) {
thermal_send_fds[i] = -1;
}
while(server_socket_exit != 1) {
testfds = t_readfds;
result = select(FD_SETSIZE, &testfds, (fd_set *)0,
(fd_set *)0, (struct timeval *) 0);
if (result < 1) {
msg("Thermal-Server: %s select error", __func__);
break;
}
for (fd = 0; fd < FD_SETSIZE; fd++) {
if (FD_ISSET(fd,&testfds)) {
if (fd == sockfd_server_send) {
client_len = sizeof(struct sockaddr_un);
client_fd = accept(sockfd_server_send,
(struct sockaddr *)&client_addr,
&client_len);
if (client_fd < 0)
continue;
FD_SET(client_fd, &t_readfds);
info("Thermal-Server: Adding thermal event listener on fd %d\n", client_fd);
for (i = 0; i < NUM_LISTEN_QUEUE && thermal_send_fds[i] != -1; i++)
continue;
if (i < NUM_LISTEN_QUEUE)
thermal_send_fds[i] = client_fd;
} else if (fd == sockfd_server_recv) {
client_len = sizeof(struct sockaddr_un);
client_fd = accept(sockfd_server_recv,
(struct sockaddr *)&client_addr,
&client_len);
if (client_fd < 0)
continue;
thermal_recv_data_from_client(client_fd);
close(client_fd);
} else {
ioctl(fd, FIONREAD, &nread);
if (nread == 0) {
close(fd);
FD_CLR(fd, &t_readfds);
info("Thermal-Server: removing client on fd %d\n", fd);
for (i = 0; i < NUM_LISTEN_QUEUE && thermal_send_fds[i] != fd; i++)
continue;
if (i < NUM_LISTEN_QUEUE) {
thermal_send_fds[i] = -1;
}
}
}
}
}
}
for (i = 0; i < NUM_LISTEN_QUEUE; i++) {
if (thermal_send_fds[i] > -1)
close(thermal_send_fds[i]);
}
return NULL;
}
/*========================================================================================
FUNCTION thermal_server_init
Thermal socket initialization function for different clients
This function setup a server for both thermal sending socket and
thermal recieving socket.
ARGUMENTS
none
RETURN VALUE
0 on success, negative on failure.
=========================================================================================*/
int thermal_server_init(void)
{
int rc;
int ret = -EINVAL;
static struct sockaddr_un server_addr_send;
static struct sockaddr_un server_addr_recv;
if (sockfd_server_send != -1 || sockfd_server_recv != -1) {
sockfd_server_send = -1;
sockfd_server_recv = -1;
}
sockfd_server_send = socket(AF_LOCAL, SOCK_STREAM, 0);
if (sockfd_server_send < 0) {
goto error;
}
sockfd_server_recv = socket(AF_LOCAL, SOCK_STREAM, 0);
if (sockfd_server_recv < 0) {
goto error;
}
memset(&server_addr_send, 0, sizeof(struct sockaddr_un));
snprintf(server_addr_send.sun_path, UNIX_PATH_MAX, THERMAL_SEND_CLIENT_SOCKET);
server_addr_send.sun_family = AF_LOCAL;
memset(&server_addr_recv, 0, sizeof(struct sockaddr_un));
snprintf(server_addr_recv.sun_path, UNIX_PATH_MAX, THERMAL_RECV_CLIENT_SOCKET);
server_addr_recv.sun_family = AF_LOCAL;
/* Delete existing socket file if necessary */
unlink(server_addr_send.sun_path);
unlink(server_addr_recv.sun_path);
rc = bind(sockfd_server_send,(struct sockaddr const *)&server_addr_send, sizeof(struct sockaddr_un));
if (rc != 0) {
msg("Thermal-Server: Send socket: bind error - %s", strerror(errno));
goto error;
}
rc = bind(sockfd_server_recv,(struct sockaddr const *)&server_addr_recv, sizeof(struct sockaddr_un));
if (rc != 0) {
msg("Thermal-Server: Recv socket: bind error - %s", strerror(errno));
goto error;
}
/* Add Camera and media server group permission for sending
socket to socket and add media server group for recieving
socket untill having better security solution */
chown(server_addr_send.sun_path, AID_ROOT, AID_CAMERA);
chmod(server_addr_send.sun_path, 0660);
chmod(server_addr_recv.sun_path, 0660);
rc = listen(sockfd_server_send, NUM_LISTEN_QUEUE);
if (rc != 0) {
goto error;
}
rc = listen(sockfd_server_recv, NUM_LISTEN_QUEUE);
if (rc != 0) {
goto error;
}
rc = pthread_create(&listen_client_fd_thread, NULL, do_listen_client_fd, NULL);
if (rc != 0) {
msg("Thermal-Server: Unable to create pthread to "
"listen thermal clients fd");
goto error;
}
ret = 0;
return ret;
error:
msg("Thermal-Server: Unable to create socket server for thermal clients");
if (sockfd_server_send != -1) {
close(sockfd_server_send);
sockfd_server_send = -1;
}
if (sockfd_server_recv != -1) {
close(sockfd_server_recv);
sockfd_server_recv = -1;
}
return ret;
}
/*=======================================================================================
FUNCTION thermal_server_notify_clients
Function to send thermal event through socket to thermal clients.
ARGUMENTS
client_name - client_name
level - mitigation level
RETURN VALUE
return 0 on success and -EINVAL on failure.
========================================================================================*/
int thermal_server_notify_clients(char *client_name, int level)
{
int rc;
int i = 0;
int ret = -EINVAL;
int send_count = 0;
struct thermal_msg_data thermal_msg;
/* Check for client is supported or not*/
for (i = 0; i < ARRAY_SIZE(notify_client_names); i++) {
if (0 == strncmp(notify_client_names[i], client_name, CLIENT_NAME_MAX))
break;
}
if (i >= ARRAY_SIZE(notify_client_names)) {
msg("Thermal-Server: %s is not in supported "
"thermal client list", client_name);
return ret;
}
memset(&thermal_msg, 0, sizeof(struct thermal_msg_data));
strlcpy(thermal_msg.client_name, client_name, CLIENT_NAME_MAX);
thermal_msg.req_data = level;
pthread_mutex_lock(&soc_client_mutex);
if (sockfd_server_send == -1) {
msg("Thermal-Server: socket is not created, Trying to start server..");
thermal_server_release();
if ( thermal_server_init() || sockfd_server_send == -1) {
goto handle_error;
}
}
/* Send event to all connected clients */
for (i = 0; i < NUM_LISTEN_QUEUE; i++) {
if(thermal_send_fds[i] != -1) {
send_count++;
rc = send(thermal_send_fds[i], &thermal_msg,
sizeof(struct thermal_msg_data), 0);
if (rc <= 0) {
msg("Thermal-Server: Unable to send "
"event to fd %d", thermal_send_fds[i]);
}
}
}
if (send_count == 0) {
msg("Thermal-Server: No client connected to socket");
goto handle_error;
}
ret = 0;
handle_error:
pthread_mutex_unlock(&soc_client_mutex);
return ret;
}
/*================================================================================================
FUNCTION thermal_server_register_client_req_handler
Thermal register function to register callback
Whenever thermal wants to register a new callback for clients,
invoke this API.
ARGUMENTS
client_name - client name
callback - callback function pointer with req_data, user_data pointer and
reserved data as arguments
data - data
RETURN VALUE
valid non zero client_cb_handle on success, zero on failure.
=================================================================================================*/
int thermal_server_register_client_req_handler(char *client_name, int (*callback)(int, void *, void *), void *data)
{
int rc = 0;
int i;
int client_cb_handle;
if (NULL == client_name ||
NULL == callback) {
msg("Thermal-Server: %s: unexpected NULL client registraion failed ", __func__);
return 0;
}
/* Check for client is supported or not*/
for (i = 0; i < ARRAY_SIZE(req_client_names); i++) {
if (0 == strncmp(req_client_names[i], client_name, CLIENT_NAME_MAX))
break;
}
if (i >= ARRAY_SIZE(req_client_names)) {
msg("Thermal-Server: %s is not in supported thermal client list", client_name);
return 0;
}
client_cb_handle = add_to_list(client_name, callback, data);
if (client_cb_handle == 0) {
msg("Thermal-Server: %s: Client Registration failed", __func__);
return 0;
}
return client_cb_handle;
}
/*========================================================================================
FUNCTION thermal_server_unregister_client_req_handler
Function to unregister client req_handler.
ARGUMENTS
client_cb_handle - client handle which retured on succesful registeration
RETURN VALUE
void
========================================================================================*/
void thermal_server_unregister_client_req_handler(int client_cb_handle)
{
if (remove_from_list(client_cb_handle) < 0)
msg("Thermal-Server: thermal client unregister callback error");
}
/*========================================================================================
FUNCTION thermal_server_release
Function to release socket thread and fd
ARGUMENTS
none
RETURN VALUE
void
========================================================================================*/
void thermal_server_release(void)
{
int i;
server_socket_exit = 1;
pthread_join(listen_client_fd_thread, NULL);
close(sockfd_server_send);
close(sockfd_server_recv);
sockfd_server_send = -1;
sockfd_server_recv = -1;
for (i = 1; i < CLIENT_HANDLE_MAX && list_head != NULL; i++) {
if (remove_from_list(i) < 0)
msg("Thermal-Server: thermal client unregister callback error");
}
}

View File

@@ -1,25 +0,0 @@
/*===========================================================================
Copyright (c) 2013 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#ifndef __THERMAL_SERVER_H__
#define __THERMAL_SERVER_H__
#ifdef __cplusplus
extern "C" {
#endif
int thermal_server_init(void);
int thermal_server_notify_clients(char *client_name, int level);
int thermal_server_register_client_req_handler(char *, int (*callback)(int, void *, void *), void *data);
void thermal_server_unregister_client_req_handler(int client_cb_handle);
void thermal_server_release(void);
#ifdef __cplusplus
}
#endif
#endif /* __THERMAL_SERVER_H__ */

View File

@@ -1,492 +0,0 @@
/*===========================================================================
Copyright (c) 2010-2013 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <linux/un.h>
#include <string.h>
#include <dirent.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include "thermal.h"
#define THERMAL_SYSFS "/sys/devices/virtual/thermal"
/* Sys proc ID */
#define SYSFS_CPU_TYPE "/proc/device-tree/cpu_type"
#define SYSFS_PLATFORMID "/sys/devices/soc0/soc_id"
#define SYSFS_PLATFORMID_DEP "/sys/devices/system/soc/soc0/id"
typedef struct
{
enum therm_msm_id msm_id;
int soc_id;
} therm_msm_soc_type;
static therm_msm_soc_type msm_soc_table[] = {
{THERM_MSM_8X60, 70},
{THERM_MSM_8X60, 71},
{THERM_MSM_8X60, 86},
{THERM_MSM_8960, 87},
{THERM_MSM_8960, 122},
{THERM_MSM_8960, 123},
{THERM_MSM_8960, 124},
{THERM_MSM_8960AB, 138},
{THERM_MSM_8960AB, 139},
{THERM_MSM_8960AB, 140},
{THERM_MSM_8960AB, 141},
{THERM_MSM_8930, 116},
{THERM_MSM_8930, 117},
{THERM_MSM_8930, 118},
{THERM_MSM_8930, 119},
{THERM_MSM_8930, 120},
{THERM_MSM_8930, 121},
{THERM_MSM_8930AA, 142},
{THERM_MSM_8930AA, 143},
{THERM_MSM_8930AA, 144},
{THERM_MSM_8930AA, 160},
{THERM_MSM_8930AB, 154},
{THERM_MSM_8930AB, 155},
{THERM_MSM_8930AB, 156},
{THERM_MSM_8930AB, 157},
{THERM_MSM_8064, 109},
{THERM_MSM_8064, 130},
{THERM_MSM_8064AB, 153},
{THERM_MSM_8X25, 90},
{THERM_MSM_8X25, 91},
{THERM_MSM_8X25, 92},
{THERM_MSM_8X25, 97},
{THERM_MSM_8974, 126},
{THERM_IPQ_8062, 201},
{THERM_IPQ_8064, 202},
{THERM_IPQ_8066, 203},
{THERM_IPQ_8068, 204},
{THERM_IPQ_8065, 280},
{THERM_IPQ_8069, 281},
/* AC variants */
{THERM_IPQ_8070, 375},
{THERM_IPQ_8070A, 395},
{THERM_IPQ_8071, 376},
{THERM_IPQ_8071A, 396},
/* HK variants */
{THERM_IPQ_8072, 342},
{THERM_IPQ_8072A, 389},
{THERM_IPQ_8074, 323},
{THERM_IPQ_8074A, 390},
{THERM_IPQ_8076, 343},
{THERM_IPQ_8076A, 391},
{THERM_IPQ_8078, 344},
{THERM_IPQ_8078A, 392},
/* OAK variants */
{THERM_IPQ_8172, 397},
{THERM_IPQ_8173, 398},
{THERM_IPQ_8174, 399},
/* CP variants */
{THERM_IPQ_6018, 402},
{THERM_IPQ_6028, 403},
{THERM_IPQ_6000, 421},
{THERM_IPQ_6010, 422},
};
int read_id_from_binary_file(char *path, size_t size) {
FILE *fp;
int ret;
fp = fopen(path, "r");
if (fp == NULL)
return -1;
if(!fread(&ret, size, 1, fp)) {
ret = ferror(fp);
}
fclose(fp);
return ret;
}
/* returns platform id, or -errno if error */
static int get_platform_id(void)
{
int ret = -1;
char buf[UINT_BUF_MAX];
if (!access(SYSFS_CPU_TYPE, F_OK)) {
ret = read_id_from_binary_file(SYSFS_CPU_TYPE, sizeof(int));
if (ret >= 0)
return ret;
} else if (!access(SYSFS_PLATFORMID, F_OK)) {
ret = read_line_from_file(SYSFS_PLATFORMID, buf, UINT_BUF_MAX);
} else {
ret = read_line_from_file(SYSFS_PLATFORMID_DEP, buf, UINT_BUF_MAX);
}
if (ret < 0) {
msg("Error getting platform_id %d", ret);
} else {
ret = atoi(buf);
}
return ret;
}
enum therm_msm_id therm_get_msm_id(void)
{
enum therm_msm_id ret_val = THERM_MSM_UNKNOWN;
int idx;
int soc_id = get_platform_id();
for (idx = 0 ; idx < ARRAY_SIZE(msm_soc_table); idx++) {
if (soc_id == msm_soc_table[idx].soc_id) {
ret_val = msm_soc_table[idx].msm_id;
break;
}
}
return ret_val;
}
/*===========================================================================
FUNCTION open_file
Utility function to open file.
ARGUMENTS
path - pathname for file
flags - file open flags
RETURN VALUE
file descriptor on success,
-1 on failure.
===========================================================================*/
static int open_file(char *path, int flags)
{
int rv;
if (!path) return -EINVAL;
rv = open(path, flags);
if (rv < 0)
rv = -errno;
return rv;
}
/*===========================================================================
FUNCTION write_to_fd
Utility function to write to provided file descriptor.
ARGUMENTS
fd - file descriptor
buf - destination buffer to write to
count - number of bytes to write to fd
RETURN VALUE
number of bytes written on success, -errno on failure.
===========================================================================*/
static int write_to_fd(int fd, char *buf, size_t count)
{
ssize_t pos = 0;
ssize_t rv = 0;
do {
rv = write(fd, buf + pos, count - pos);
if (rv < 0)
return -errno;
pos += rv;
} while ((ssize_t)count > pos);
return count;
}
/*===========================================================================
FUNCTION read_line_from_file
Utility function to read characters from file and stores them in a string
until (count-1) characters are read or either a newline or EOF is reached.
ARGUMENTS
path - file path
buf - destination buffer to read from
count - max number of bytes to read from file
RETURN VALUE
number of bytes read on success, -errno on failure.
===========================================================================*/
int read_line_from_file(char *path, char *buf, size_t count)
{
char * fgets_ret;
FILE * fd;
int rv;
fd = fopen(path, "r");
if (fd == NULL)
return -1;
fgets_ret = fgets(buf, count, fd);
if (NULL != fgets_ret) {
rv = strlen(buf);
} else {
rv = ferror(fd);
}
fclose(fd);
return rv;
}
/*===========================================================================
FUNCTION write_to_file
Utility function to write to provided file path.
ARGUMENTS
path - file path
buf - destination buffer to write to
count - number of bytes to write to file
RETURN VALUE
number of bytes written on success, -errno on failure.
===========================================================================*/
int write_to_file(char *path, char *buf, size_t count)
{
int fd, rv;
fd = open_file(path, O_RDWR);
if (fd < 0)
return fd;
rv = write_to_fd(fd, buf, count);
close(fd);
return rv;
}
/*===========================================================================
FUNCTION connect_local_file_socket
Utility function to open and connect to local UNIX filesystem socket.
ARGUMENTS
socket_name - name of local UNIX filesystem socket to be connected
RETURN VALUE
Connected socket_fd on success,
-1 on failure.
===========================================================================*/
static int connect_local_file_socket(char *socket_name)
{
int socket_fd = 0;
struct sockaddr_un serv_addr;
socket_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
if (socket_fd < 0) {
dbgmsg("socket error - %s\n", strerror(errno));
return -1;
}
memset(&serv_addr, 0, sizeof(serv_addr));
snprintf(serv_addr.sun_path, UNIX_PATH_MAX, "%s", socket_name);
serv_addr.sun_family = AF_LOCAL;
if (connect(socket_fd, (struct sockaddr *) &serv_addr,
sizeof(sa_family_t) + strlen(socket_name) ) != 0) {
dbgmsg("connect error on %s - %s\n",
socket_name, strerror(errno));
close(socket_fd);
return -1;
}
return socket_fd;
}
/*===========================================================================
FUNCTION connect_local_socket
Utility function to open and connect to abstract local UNIX socket.
ARGUMENTS
socket_name - name of local UNIX socket to be connected in abstract
socket namespace.
RETURN VALUE
Connected socket_fd on success,
-1 on failure.
===========================================================================*/
static int connect_local_socket(char *socket_name)
{
int socket_fd = 0;
struct sockaddr_un serv_addr;
socket_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
if (socket_fd < 0) {
dbgmsg("socket error - %s\n", strerror(errno));
return -1;
}
memset(&serv_addr, 0, sizeof(serv_addr));
snprintf(serv_addr.sun_path, UNIX_PATH_MAX, " %s", socket_name);
serv_addr.sun_family = AF_LOCAL;
/* abstract namespace socket starts with NULL char */
serv_addr.sun_path[0] = '\0';
/* effective sockaddr_un size == sun_family + null-char + name len */
if (connect(socket_fd, (struct sockaddr *) &serv_addr,
sizeof(sa_family_t) + 1 + strlen(socket_name) ) != 0) {
dbgmsg("connect error on %s - %s\n",
socket_name, strerror(errno));
close(socket_fd);
return -1;
}
return socket_fd;
}
/*===========================================================================
FUNCTION write_to_local_file_socket
Utility function to write to local filesystem UNIX socket.
ARGUMENTS
socket_name - socket name to be written
msg - message to be written on socket
count - size of msg buffer to be written
RETURN VALUE
Number of bytes written on success,
-1 on failure.
===========================================================================*/
int write_to_local_file_socket(char *socket_name, char *msg, size_t count)
{
int socket_fd = 0;
int rv;
if (minimum_mode) {
return -1;
}
socket_fd = connect_local_file_socket(socket_name);
if (socket_fd < 0) {
return -1;
}
rv = write_to_fd(socket_fd, msg, count);
close(socket_fd);
return rv;
}
/*===========================================================================
FUNCTION write_to_local_socket
Utility function to write to abstract local UNIX socket.
ARGUMENTS
socket_name - socket name to be written
msg - message to be written on socket
count - size of msg buffer to be written
RETURN VALUE
Number of bytes written on success,
-1 on failure.
===========================================================================*/
int write_to_local_socket(char *socket_name, char *msg, size_t count)
{
int socket_fd = 0;
int rv;
if (minimum_mode) {
return -1;
}
socket_fd = connect_local_socket(socket_name);
if (socket_fd < 0) {
return -1;
}
rv = write_to_fd(socket_fd, msg, count);
close(socket_fd);
return rv;
}
/*===========================================================================
FUNCTION get_tzn
Utility function to match a sensor name with thermal zone id.
ARGUMENTS
sensor_name - name of sensor to match
RETURN VALUE
Thermal zone id on success,
-1 on failure.
===========================================================================*/
int get_tzn(char *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};
if (!getcwd(cwd, sizeof(cwd)))
return found;
/* Change dir to read the entries. Doesnt work otherwise */
if (chdir(THERMAL_SYSFS) != 0) {
msg("Change directory failed: %s\n", THERMAL_SYSFS);
return found;
}
tdir = opendir(THERMAL_SYSFS);
if (!tdir) {
msg("Unable to open %s\n", THERMAL_SYSFS);
return found;
}
while ((tdirent = readdir(tdir))) {
char buf[50];
struct dirent *tzdirent;
DIR *tzdir = NULL;
tzdir = opendir(tdirent->d_name);
if (!tzdir)
continue;
while ((tzdirent = readdir(tzdir))) {
if (strcmp(tzdirent->d_name, "type"))
continue;
snprintf(name, MAX_PATH, TZ_TYPE, tzn);
dbgmsg("Opening %s\n", name);
read_line_from_file(name, buf, sizeof(buf));
buf[strlen(sensor_name)] = '\0';
if (!strcmp(buf, sensor_name)) {
found = 1;
break;
}
tzn++;
}
closedir(tzdir);
if (found == 1)
break;
}
closedir(tdir);
if (chdir(cwd) != 0) { /* Restore current working dir */
msg("Restore directory failed: %s\n", cwd);
return -1;
}
if (found == 1) {
found = tzn;
dbgmsg("Sensor %s found at tz: %d\n", sensor_name, tzn);
}
return found;
}

View File

@@ -1,9 +0,0 @@
sampling 1000
[PMIC_THERM]
sampling 500000
thresholds 25 30 50
thresholds_clr 20 28 48
actions none none none
action_info 768000 368640 245760

View File

@@ -1,92 +0,0 @@
sampling 5000
[pa_therm0]
sampling 5000
thresholds 70
thresholds_clr 67
actions none
action_info 0
[tsens_tz_sensor0]
sampling 1000
thresholds 70
thresholds_clr 67
actions none
action_info 0
[tsens_tz_sensor1]
sampling 1000
thresholds 70
thresholds_clr 67
actions none
action_info 0
[tsens_tz_sensor2]
sampling 1000
thresholds 70
thresholds_clr 67
actions none
action_info 0
[tsens_tz_sensor3]
sampling 1000
thresholds 70
thresholds_clr 67
actions none
action_info 0
[tsens_tz_sensor4]
sampling 1000
thresholds 70
thresholds_clr 67
actions none
action_info 0
[tsens_tz_sensor5]
sampling 1000
thresholds 70
thresholds_clr 67
actions none
action_info 0
[tsens_tz_sensor6]
sampling 1000
thresholds 70
thresholds_clr 67
actions none
action_info 0
[tsens_tz_sensor7]
sampling 1000
thresholds 70 90 95 100 105 110 115 120
thresholds_clr 67 85 90 95 100 105 110 115
actions cpu+battery cpu+battery cpu+battery cpu+battery cpu+battery cpu+battery cpu+battery shutdown
action_info 1728000+0 1188000+0 810000+1 648000+1 540000+2 487000+2 384000+3 5000
[tsens_tz_sensor8]
sampling 1000
thresholds 70 90 95 100 105 110 115 120
thresholds_clr 67 85 90 95 100 105 110 115
actions cpu cpu cpu cpu cpu cpu cpu shutdown
action_info 1728000 1188000 810000 648000 540000 487000 384000 5000
[tsens_tz_sensor9]
sampling 1000
thresholds 70 90 95 100 105 110 115 120
thresholds_clr 67 85 90 95 100 105 110 115
actions cpu cpu cpu cpu cpu cpu cpu shutdown
action_info 1728000 1188000 810000 648000 540000 487000 384000 5000
[tsens_tz_sensor10]
sampling 1000
thresholds 70 90 95 100 105 110 115 120
thresholds_clr 67 85 90 95 100 105 110 115
actions cpu cpu cpu cpu cpu cpu cpu shutdown
action_info 1728000 1188000 810000 648000 540000 487000 384000 5000
[pm8821_tz]
thresholds 107
thresholds_clr 103
actions cpu
action_info 918000

View File

@@ -1,92 +0,0 @@
sampling 5000
[pa_therm0]
sampling 5000
thresholds 70
thresholds_clr 67
actions none
action_info 0
[tsens_tz_sensor0]
sampling 1000
thresholds 70
thresholds_clr 67
actions none
action_info 0
[tsens_tz_sensor1]
sampling 1000
thresholds 70
thresholds_clr 67
actions none
action_info 0
[tsens_tz_sensor2]
sampling 1000
thresholds 70
thresholds_clr 67
actions none
action_info 0
[tsens_tz_sensor3]
sampling 1000
thresholds 70
thresholds_clr 67
actions none
action_info 0
[tsens_tz_sensor4]
sampling 1000
thresholds 70
thresholds_clr 67
actions none
action_info 0
[tsens_tz_sensor5]
sampling 1000
thresholds 70
thresholds_clr 67
actions none
action_info 0
[tsens_tz_sensor6]
sampling 1000
thresholds 70
thresholds_clr 67
actions none
action_info 0
[tsens_tz_sensor7]
sampling 1000
thresholds 70 85 90 95 100 105 110 120
thresholds_clr 67 80 85 90 95 100 105 115
actions cpu+battery cpu+battery cpu+battery cpu+battery cpu+battery cpu+battery cpu+battery shutdown
action_info 1890000+0 1674000+0 1350000+1 1026000+1 810000+2 594000+2 384000+3 5000
[tsens_tz_sensor8]
sampling 1000
thresholds 70 85 90 95 100 105 110 120
thresholds_clr 67 80 85 90 95 100 105 115
actions cpu cpu cpu cpu cpu cpu cpu shutdown
action_info 1890000 1674000 1350000 1026000 810000 594000 384000 5000
[tsens_tz_sensor9]
sampling 1000
thresholds 70 85 90 95 100 105 110 120
thresholds_clr 67 80 85 90 95 100 105 115
actions cpu cpu cpu cpu cpu cpu cpu shutdown
action_info 1890000 1674000 1350000 1026000 810000 594000 384000 5000
[tsens_tz_sensor10]
sampling 1000
thresholds 70 85 90 95 100 105 110 120
thresholds_clr 67 80 85 90 95 100 105 115
actions cpu cpu cpu cpu cpu cpu cpu shutdown
action_info 1890000 1674000 1350000 1026000 810000 594000 384000 5000
[pm8821_tz]
thresholds 107
thresholds_clr 103
actions cpu
action_info 918000

View File

@@ -1,15 +0,0 @@
sampling 1000
[tsens_tz_sensor0]
sampling 500000
thresholds 25 30 50
thresholds_clr 20 28 48
actions none none none
action_info 768000 368640 245760
[pm8058_tz]
sampling 500000
thresholds 25 30 50
thresholds_clr 20 28 48
actions none none none
action_info 768000 368640 245760

View File

@@ -1,79 +0,0 @@
sampling 5000
[pa_therm0]
sampling 100000
thresholds 65 70 75 80 85 90
thresholds_clr 60 65 70 75 80 85
actions none none none none none none
action_info 0 0 0 0 0 0
[tsens_tz_sensor0]
sampling 1000
thresholds 60
thresholds_clr 57
actions none
action_info 0
[tsens_tz_sensor1]
sampling 1000
thresholds 60
thresholds_clr 57
actions none
action_info 0
[tsens_tz_sensor2]
sampling 1000
thresholds 60
thresholds_clr 57
actions none
action_info 0
[tsens_tz_sensor3]
sampling 1000
thresholds 60
thresholds_clr 57
actions none
action_info 0
[tsens_tz_sensor4]
sampling 1000
thresholds 60
thresholds_clr 57
actions none
action_info 0
[tsens_tz_sensor5]
sampling 1000
thresholds 60
thresholds_clr 57
actions none
action_info 0
[tsens_tz_sensor6]
sampling 1000
thresholds 60
thresholds_clr 57
actions none
action_info 0
[tsens_tz_sensor7]
sampling 1000
thresholds 60
thresholds_clr 57
actions none
action_info 0
[tsens_tz_sensor8]
sampling 1000
thresholds 60
thresholds_clr 57
actions none
action_info 0
[tsens_tz_sensor9]
sampling 1000
thresholds 60 90 95 100 105 110 115 120
thresholds_clr 57 85 90 95 100 105 110 115
actions cpu cpu cpu cpu cpu cpu cpu shutdown
action_info 1404000 1296000 1188000 918000 756000 648000 384000 5000

View File

@@ -1,79 +0,0 @@
sampling 5000
[pa_therm0]
sampling 100000
thresholds 65 70 75 80 85 90
thresholds_clr 60 65 70 75 80 85
actions none none none none none none
action_info 0 0 0 0 0 0
[tsens_tz_sensor0]
sampling 1000
thresholds 60
thresholds_clr 57
actions none
action_info 0
[tsens_tz_sensor1]
sampling 1000
thresholds 60
thresholds_clr 57
actions none
action_info 0
[tsens_tz_sensor2]
sampling 1000
thresholds 60
thresholds_clr 57
actions none
action_info 0
[tsens_tz_sensor3]
sampling 1000
thresholds 60
thresholds_clr 57
actions none
action_info 0
[tsens_tz_sensor4]
sampling 1000
thresholds 60
thresholds_clr 57
actions none
action_info 0
[tsens_tz_sensor5]
sampling 1000
thresholds 60
thresholds_clr 57
actions none
action_info 0
[tsens_tz_sensor6]
sampling 1000
thresholds 60
thresholds_clr 57
actions none
action_info 0
[tsens_tz_sensor7]
sampling 1000
thresholds 60
thresholds_clr 57
actions none
action_info 0
[tsens_tz_sensor8]
sampling 1000
thresholds 60
thresholds_clr 57
actions none
action_info 0
[tsens_tz_sensor9]
sampling 1000
thresholds 60 90 95 100 105 110 115 120
thresholds_clr 57 85 90 95 100 105 110 115
actions cpu cpu cpu cpu cpu cpu cpu shutdown
action_info 1728000 1404000 1296000 1188000 918000 756000 648000 5000

View File

@@ -1,44 +0,0 @@
sampling 5000
[pa_therm0]
sampling 100000
thresholds 65 70 75 80 85 90
thresholds_clr 60 65 70 75 80 85
actions none none none none none none
action_info 0 0 0 0 0 0
[tsens_tz_sensor0]
sampling 1000
thresholds 65 90 93 96 99 102 105
thresholds_clr 62 87 90 93 96 99 102
actions cpu cpu cpu cpu cpu cpu shutdown
action_info 1512000 1296000 1188000 918000 756000 648000 5000
[tsens_tz_sensor1]
sampling 1000
thresholds 75
thresholds_clr 72
actions none
action_info 0
[tsens_tz_sensor2]
sampling 1000
thresholds 75
thresholds_clr 72
actions none
action_info 0
[tsens_tz_sensor3]
sampling 1000
thresholds 75 78 81 84 87 90
thresholds_clr 72 75 78 81 84 87
actions cpu cpu cpu cpu cpu shutdown
action_info 1296000 1188000 918000 756000 648000 5000
[tsens_tz_sensor4]
sampling 1000
thresholds 75
thresholds_clr 72
actions none
action_info 0

View File

@@ -1,44 +0,0 @@
sampling 5000
[pa_therm0]
sampling 100000
thresholds 65 70 75 80 85 90
thresholds_clr 60 65 70 75 80 85
actions none none none none none none
action_info 0 0 0 0 0 0
[tsens_tz_sensor0]
sampling 1000
thresholds 65 87 90 93 96 99 102 105
thresholds_clr 62 84 87 90 93 96 99 102
actions cpu cpu cpu cpu cpu cpu cpu shutdown
action_info 1728000 1512000 1296000 1188000 918000 756000 648000 5000
[tsens_tz_sensor1]
sampling 1000
thresholds 75
thresholds_clr 72
actions none
action_info 0
[tsens_tz_sensor2]
sampling 1000
thresholds 75
thresholds_clr 72
actions none
action_info 0
[tsens_tz_sensor3]
sampling 1000
thresholds 75 78 81 84 87 90
thresholds_clr 72 75 78 81 84 87
actions cpu cpu cpu cpu cpu shutdown
action_info 1296000 1188000 918000 756000 648000 5000
[tsens_tz_sensor4]
sampling 1000
thresholds 75
thresholds_clr 72
actions none
action_info 0

View File

@@ -1,80 +0,0 @@
debug
sampling 5000
[tsens_tz_sensor0]
sampling 1000
thresholds 60 90 95 100 105 110 115 120
thresholds_clr 57 85 90 95 100 105 110 115
actions cpu cpu cpu cpu cpu cpu cpu shutdown
action_info 1512000 1188000 918000 756000 648000 540000 486000 5000
[tsens_tz_sensor1]
sampling 1000
thresholds 60 90 95 100 105 110 115 120
thresholds_clr 57 85 90 95 100 105 110 115
actions cpu cpu cpu cpu cpu cpu cpu shutdown
action_info 1512000 1188000 918000 756000 648000 540000 486000 5000
[tsens_tz_sensor2]
sampling 1000
thresholds 60 90 95 100 105 110 115 120
thresholds_clr 57 85 90 95 100 105 110 115
actions cpu cpu cpu cpu cpu cpu cpu shutdown
action_info 1512000 1188000 918000 756000 648000 540000 486000 5000
[tsens_tz_sensor3]
sampling 1000
thresholds 60 90 95 100 105 110 115 120
thresholds_clr 57 85 90 95 100 105 110 115
actions cpu cpu cpu cpu cpu cpu cpu shutdown
action_info 1512000 1188000 918000 756000 648000 540000 486000 5000
[tsens_tz_sensor4]
sampling 1000
thresholds 60 90 95 100 105 110 115 120
thresholds_clr 57 85 90 95 100 105 110 115
actions cpu cpu cpu cpu cpu cpu cpu shutdown
action_info 1512000 1188000 918000 756000 648000 540000 486000 5000
[tsens_tz_sensor5]
sampling 1000
thresholds 60 90 95 100 105 110 115 120
thresholds_clr 57 85 90 95 100 105 110 115
actions cpu cpu cpu cpu cpu cpu cpu shutdown
action_info 1512000 1188000 918000 756000 648000 540000 486000 5000
[tsens_tz_sensor6]
sampling 1000
thresholds 60 90 95 100 105 110 115 120
thresholds_clr 57 85 90 95 100 105 110 115
actions cpu cpu cpu cpu cpu cpu cpu shutdown
action_info 1512000 1188000 918000 756000 648000 540000 486000 5000
[tsens_tz_sensor7]
sampling 1000
thresholds 60 90 95 100 105 110 115 120
thresholds_clr 57 85 90 95 100 105 110 115
actions cpu cpu cpu cpu cpu cpu cpu shutdown
action_info 1512000 1188000 918000 756000 648000 540000 486000 5000
[tsens_tz_sensor8]
sampling 1000
thresholds 60 90 95 100 105 110 115 120
thresholds_clr 57 85 90 95 100 105 110 115
actions cpu cpu cpu cpu cpu cpu cpu shutdown
action_info 1512000 1188000 918000 756000 648000 540000 486000 5000
[tsens_tz_sensor9]
sampling 1000
thresholds 60 90 95 100 105 110 115 120
thresholds_clr 57 85 90 95 100 105 110 115
actions cpu cpu cpu cpu cpu cpu cpu shutdown
action_info 1512000 1188000 918000 756000 648000 540000 486000 5000
[tsens_tz_sensor10]
sampling 1000
thresholds 60 90 95 100 105 110 115 120
thresholds_clr 57 85 90 95 100 105 110 115
actions cpu cpu cpu cpu cpu cpu cpu shutdown
action_info 1512000 1188000 918000 756000 648000 540000 486000 5000

View File

@@ -1,10 +0,0 @@
debug
sampling 1000
[PMIC_THERM]
sampling 1000
thresholds 40 45 50 55 85
thresholds_clr 37 42 47 52 82
actions cpu cpu cpu cpu shutdown
action_info 1008000 600000 480000 245760 5000

View File

@@ -1,10 +0,0 @@
debug
sampling 1000
[MSM_THERM]
sampling 1000
thresholds 30 50 53 56 59 62 70
thresholds_clr 27 47 50 53 56 59 68
actions cpu cpu cpu cpu cpu cpu shutdown
action_info 1401600 1209600 1000800 700800 480000 320000 5

View File

@@ -1,10 +0,0 @@
debug
sampling 1000
[PMIC_THERM]
sampling 1000
thresholds 30 55 57 59 62 65 70
thresholds_clr 27 52 55 57 59 62 65
actions cpu cpu cpu cpu cpu cpu shutdown
action_info 1401600 1209600 1000800 700800 480000 320000 5

View File

@@ -1,22 +0,0 @@
sampling 1000
[PMIC_THERM]
sampling 5000
thresholds 40.2 45 50
thresholds_clr 38 43 48
actions report cpu cpu
action_info 768000 368640 245760
[XO_THERM]
sampling 5000
thresholds 40.1 45 90
thresholds_clr 38 43 88
actions cpu cpu shutdown
action_info 768000 368640 245760
[XO_THERM_GPS]
sampling 5000
thresholds 27.0 45 50
thresholds_clr 26.5 43 48
actions report cpu cpu
action_info 768000 368640 245760

View File

@@ -1,408 +0,0 @@
/*===========================================================================
tsens-sensor.c
DESCRIPTION
TSENS sensor access functions.
INITIALIZATION AND SEQUENCING REQUIREMENTS
setup() function should be called before get_temperature().
shutdown() function should be called to clean up resources.
Copyright (c) 2011 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <pthread.h>
#include <poll.h>
#include "tsens-sensor.h"
#include "thermal.h"
#define LVL_BUF_MAX (12)
#define TSENS_TZ_TRIP_TYPE "/sys/devices/virtual/thermal/thermal_zone%d/trip_point_%d_type"
#define TSENS_TZ_TRIP_TEMP "/sys/devices/virtual/thermal/thermal_zone%d/trip_point_%d_temp"
#ifdef SENSORS_8974
#define TRIP_MAX 0 /* Trip point 0 is the high temperature */
#define TRIP_MIN 1 /* Trip point 1 is the low temperature */
#else
#define TRIP_MAX 1 /* Trip point 1 is the high temperature */
#define TRIP_MIN 2 /* Trip point 2 is the low temperature */
#endif
typedef struct tsens_data {
pthread_t tsens_thread;
pthread_mutex_t tsens_mutex;
pthread_cond_t tsens_condition;
int threshold_reached;
int hi_threshold, lo_threshold;
int hi_idx, lo_idx;
int sensor_shutdown;
sensor_t *sensor;
} tsens_data;
static void *tsens_uevent(void *data)
{
int err = 0;
sensor_t *sensor = (sensor_t *)data;
struct pollfd fds;
int fd;
char uevent[MAX_PATH] = {0};
char buf[MAX_PATH] = {0};
tsens_data *tsens = NULL;
if (NULL == sensor ||
NULL == sensor->data) {
msg("%s: unexpected NULL", __func__);
return NULL;
}
tsens = (tsens_data *) sensor->data;
/* Looking for tsens uevent */
snprintf(uevent, MAX_PATH, TZ_TYPE, sensor->tzn);
fd = open(uevent, O_RDONLY);
if (fd < 0) {
msg("Unable to open %s to receive notifications.\n", uevent);
return NULL;
};
while (!tsens->sensor_shutdown) {
fds.fd = fd;
fds.events = POLLERR|POLLPRI;
fds.revents = 0;
err = poll(&fds, 1, -1);
if (err == -1) {
msg("Error in uevent poll.\n");
break;
}
if (read(fd, buf, sizeof(buf)) < 0) {
dbgmsg("TSENS uevent read failed\n");
close(fd);
return NULL;
}
lseek(fd, 0, SEEK_SET);
dbgmsg("TSENS uevent :%s", buf);
/* notify the waiting threads */
pthread_mutex_lock(&(tsens->tsens_mutex));
tsens->threshold_reached = 1;
pthread_cond_broadcast(&(tsens->tsens_condition));
pthread_mutex_unlock(&(tsens->tsens_mutex));
}
close(fd);
return NULL;
}
static void enable_sensor(int tzn , int enabled)
{
int ret = 0;
char name[MAX_PATH] = {0};
snprintf( name, MAX_PATH, TZ_MODE, tzn );
if (enabled)
ret = write_to_file(name, "enabled", strlen("enabled"));
else
ret = write_to_file(name, "disabled", strlen("disabled"));
if (ret <= 0) {
msg("TSENS tzn %d failed to set mode %d\n", tzn, enabled);
} else {
dbgmsg("TSENS tzn %d mode set to %d\n", tzn, enabled);
}
}
static void enable_threshold(tsens_data *tsens, int trip, int enabled)
{
int ret = 0;
char name[MAX_PATH] = {0};
if (NULL == tsens ||
NULL == tsens->sensor) {
msg("%s: unexpected NULL", __func__);
return;
}
snprintf(name, MAX_PATH, TSENS_TZ_TRIP_TYPE, tsens->sensor->tzn, trip);
if (enabled)
ret = write_to_file(name, "enabled", strlen("enabled"));
else
ret = write_to_file(name, "disabled", strlen("disabled"));
if (ret <= 0) {
msg("TSENS threshold at %d failed to %d\n", trip, enabled);
} else {
dbgmsg("TSENS threshold at %d enabled: %d\n", trip, enabled);
}
}
static void set_thresholds(tsens_data *tsens, int lvl, int lvl_clr,
int hi_enable, int lo_enable)
{
char minname[MAX_PATH]= {0};
char maxname[MAX_PATH]= {0};
char buf[LVL_BUF_MAX] = {0};
int ret = 0;
int mintemp = 0;
if (NULL == tsens) {
msg("%s: unexpected NULL", __func__);
return;
}
snprintf(minname, MAX_PATH, TSENS_TZ_TRIP_TEMP, tsens->sensor->tzn, TRIP_MIN);
snprintf(maxname, MAX_PATH, TSENS_TZ_TRIP_TEMP, tsens->sensor->tzn, TRIP_MAX);
/* Set thresholds in legal order */
if (read_line_from_file(minname, buf, sizeof(buf)) > 0) {
mintemp = atoi(buf);
}
if (lvl >= mintemp) {
/* set high threshold first */
dbgmsg("Setting up TSENS thresholds high: %d\n", lvl);
enable_threshold(tsens, TRIP_MAX, hi_enable);
snprintf(buf, LVL_BUF_MAX, "%d", lvl);
ret = write_to_file(maxname, buf, strlen(buf));
if (ret <= 0)
msg("TSENS threshold high failed to set %d\n", lvl);
dbgmsg("Setting up TSENS thresholds low: %d\n", lvl_clr);
enable_threshold(tsens, TRIP_MIN, lo_enable);
snprintf(buf, LVL_BUF_MAX, "%d", lvl_clr);
ret = write_to_file(minname, buf, strlen(buf));
if (ret <= 0)
msg("TSENS threshold low failed to set %d\n", lvl_clr);
} else {
dbgmsg("Setting up TSENS thresholds low: %d\n", lvl_clr);
enable_threshold(tsens, TRIP_MIN, lo_enable);
snprintf(buf, LVL_BUF_MAX, "%d", lvl_clr);
ret = write_to_file(minname, buf, strlen(buf));
if (ret <= 0)
msg("TSENS threshold low failed to set %d\n", lvl_clr);
dbgmsg("Setting up TSENS thresholds high: %d\n", lvl);
enable_threshold(tsens, TRIP_MAX, hi_enable);
snprintf(buf, LVL_BUF_MAX, "%d", lvl);
ret = write_to_file(maxname, buf, strlen(buf));
if (ret <= 0)
msg("TSENS threshold high failed to set %d\n", lvl);
}
tsens->hi_threshold = lvl;
tsens->lo_threshold = lvl_clr;
}
void tsens_sensor_enable_thresholds(sensor_setting_t *setting, int hi_enabled,
int lo_enabled)
{
#ifdef ENABLE_TSENS_INTERRUPT
if (NULL == setting ||
NULL == setting->sensor ||
NULL == setting->sensor->data) {
msg("tsens: unexpected NULL");
return;
}
enable_threshold(setting->sensor->data, TRIP_MAX, hi_enabled);
enable_threshold(setting->sensor->data, TRIP_MIN, lo_enabled);
#endif
}
#ifdef IPQ_806x
void tsens_sensor_enable_sensor(int tzn, int enabled)
{
if ( (0 >= tzn) && (SENSOR_IDX_MAX <= tzn) ){
msg("%s: Invalid sensor id = %d\n" , __func__ , tzn );
return;
}
enable_sensor(tzn, enabled);
}
#else
void tsens_sensor_enable_sensor(sensor_setting_t *setting, int enabled)
{
if (NULL == setting ||
NULL == setting->sensor ||
NULL == setting->sensor->data) {
msg("tsens: unexpected NULL");
return;
}
tsens_data *tsens = setting->sensor->data;
enable_sensor( tsens->sensor->tzn, enabled);
}
#endif
/* NOTE: tsens_sensors_setup() function does not enable the sensor
* or set thresholds. This should be done in the target-specific setup */
int tsens_sensors_setup(sensor_setting_t *setting, sensor_t *sensor)
{
int fd = -1;
int sensor_count = 0;
char name[MAX_PATH] = {0};
int tzn = 0;
tsens_data *tsens = NULL;
/* We have nothing to do if there are no thresholds */
if (!setting->num_thresholds) {
dbgmsg("No thresholds for sensor %s\n", sensor->name);
return sensor_count;
}
tzn = get_tzn(sensor->name);
if (tzn < 0) {
msg("No thermal zone device found in the kernel for sensor %s\n", sensor->name);
return sensor_count;
}
sensor->tzn = tzn;
snprintf(name, MAX_PATH, TZ_TEMP, sensor->tzn);
fd = open(name, O_RDONLY);
if (fd < 0) {
msg("%s: Error opening %s\n", __func__, TZ_TEMP);
return sensor_count;
}
/* Allocate TSENS data */
tsens = (tsens_data *) malloc(sizeof(tsens_data));
if (NULL == tsens) {
msg("%s: malloc failed", __func__);
close(fd);
return sensor_count;
}
memset(tsens, 0, sizeof(tsens_data));
sensor->data = (void *) tsens;
sensor_count++;
pthread_mutex_init(&(tsens->tsens_mutex), NULL);
pthread_cond_init(&(tsens->tsens_condition), NULL);
tsens->sensor_shutdown = 0;
tsens->threshold_reached = 0;
tsens->sensor = sensor;
setting->disabled = 0;
setting->chan_idx = fd;
if (sensor->interrupt_enable) {
pthread_create(&(tsens->tsens_thread), NULL,
tsens_uevent, sensor);
}
return sensor_count;
}
void tsens_sensors_shutdown(sensor_setting_t *setting)
{
tsens_data *tsens;
if (NULL == setting ||
NULL == setting->sensor ||
NULL == setting->sensor->data) {
msg("%s: unexpected NULL", __func__);
return;
}
tsens = (tsens_data *) setting->sensor->data;
tsens->sensor_shutdown = 1;
if (setting->chan_idx > 0)
close(setting->chan_idx);
if (setting->sensor->interrupt_enable)
pthread_join(tsens->tsens_thread, NULL);
free(tsens);
}
int tsens_sensor_get_temperature(sensor_setting_t *setting)
{
char buf[10] = {0};
int temp = 0;
if (NULL == setting) {
msg("%s: unexpected NULL", __func__);
return 0;
}
if (read(setting->chan_idx, buf, sizeof(buf) - 1) != -1)
temp = atoi(buf);
lseek(setting->chan_idx, 0, SEEK_SET);
return CONV(temp);
}
void tsens_sensor_interrupt_wait(sensor_setting_t *setting)
{
tsens_data *tsens;
if (NULL == setting ||
NULL == setting->sensor ||
NULL == setting->sensor->data) {
msg("%s: unexpected NULL", __func__);
return;
}
if (setting->sensor->interrupt_enable) {
tsens = (tsens_data *) setting->sensor->data;
/* Wait for sensor threshold condition */
pthread_mutex_lock(&(tsens->tsens_mutex));
while (!tsens->threshold_reached) {
pthread_cond_wait(&(tsens->tsens_condition),
&(tsens->tsens_mutex));
}
tsens->threshold_reached = 0;
pthread_mutex_unlock(&(tsens->tsens_mutex));
}
}
void tsens_sensor_update_thresholds(sensor_setting_t *setting,
int threshold_type, int level)
{
int hi, lo;
int hi_enable = 1;
int lo_enable = 1;
tsens_data *tsens;
if (NULL == setting ||
NULL == setting->sensor ||
NULL == setting->sensor->data) {
msg("%s: unexpected NULL", __func__);
return;
}
tsens = (tsens_data *) setting->sensor->data;
dbgmsg("%s: threshold_type %d, level %d", __func__,
threshold_type, level);
hi = RCONV(setting->t[tsens->hi_idx].lvl_trig);
lo = RCONV(setting->t[tsens->lo_idx].lvl_clr);
if (level >= setting->num_thresholds) {
/* handle corner high case */
hi = RCONV(setting->t[setting->num_thresholds - 1].lvl_trig);
tsens->hi_idx = setting->num_thresholds - 1;
hi_enable = 0;
} else {
hi = RCONV(setting->t[level].lvl_trig);
tsens->hi_idx = level;
}
if (level <= 0) {
/* handle corner low case */
lo = RCONV(setting->t[0].lvl_clr);
tsens->lo_idx = 0;
lo_enable = 0;
} else {
lo = RCONV(setting->t[level - 1].lvl_clr);
tsens->lo_idx = level - 1;
}
set_thresholds(tsens, hi, lo, hi_enable, lo_enable);
}

View File

@@ -1,25 +0,0 @@
/*===========================================================================
Copyright (c) 2012 Qualcomm Technologies, Inc. All Rights Reserved.
Qualcomm Technologies Proprietary and Confidential.
===========================================================================*/
#ifndef __TSENS_SENSOR_H__
#define __TSENS_SENSOR_H__
#include "thermal.h"
int tsens_sensors_setup(sensor_setting_t *settings, sensor_t * sensor);
void tsens_sensors_shutdown(sensor_setting_t *setting);
int tsens_sensor_get_temperature(sensor_setting_t *setting);
void tsens_sensor_interrupt_wait(sensor_setting_t *setting);
void tsens_sensor_update_thresholds(sensor_setting_t *setting, int threshold_type, int level);
void tsens_sensor_enable_thresholds(sensor_setting_t *setting, int hi_enabled, int lo_enabled);
#ifndef IPQ_806x
void tsens_sensor_enable_sensor(sensor_setting_t *setting, int enabled);
#else
void tsens_sensor_enable_sensor(int tzn, int enabled);
#endif
#endif /* __TSENS_SENSOR_H__ */