| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524 |
- #ifdef pr_fmt
- #undef pr_fmt
- #endif
- #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
- #include <asm/uaccess.h>
- #include <linux/version.h>
- #include <linux/kernel.h>
- #include <linux/printk.h>
- #include <linux/module.h>
- #include <linux/dmi.h>
- #include <linux/acpi.h>
- #include <linux/thermal.h>
- #include <linux/platform_device.h>
- #include <linux/types.h>
- #include <linux/delay.h>
- #include <linux/proc_fs.h>
- #include <linux/err.h>
- #include <linux/syscalls.h>
- #include <linux/time.h>
- #include <linux/string.h>
- #include <linux/mutex.h>
- #include <linux/bug.h>
- #include <linux/workqueue.h>
- #include <linux/slab.h>
- #include <mt-plat/mtk_thermal_monitor.h>
- #include <mt-plat/mtk_thermal_platform.h>
- #include <linux/uidgid.h>
- /*#ifdef CONFIG_MD32_SUPPORT
- #define CONFIG_MTK_THERMAL_EXT_CONTROL
- #endif*/
- /* ************************************ */
- /* Definition */
- /* ************************************ */
- /**
- * \def MTK_THERMAL_MONITOR_MEASURE_GET_TEMP_OVERHEAD
- * 1 to enable
- * 0 to disable
- */
- #define MTK_THERMAL_MONITOR_MEASURE_GET_TEMP_OVERHEAD (0)
- #define MTK_THERMAL_MONITOR_COOLER_MAX_EXTRA_CONDITIONS (3)
- #define MTK_THERMAL_MONITOR_CONDITIONAL_COOLING (1)
- /**
- * \def MTK_MAX_STEP_SMA_LEN
- * If not defined as 1, multi-step temperature SMA len is supported.
- * For example, MTK_MAX_STEP_SMA_LEN is defined as 4.
- * Users can set 4 different SMA len for a thermal zone and assign a high threshold for each.
- * SMA len in the next step is applied if temp of the TZ reaches high threshold.
- * Represent this in a simple figure as below:
- * -infinite HT(0)|<- sma_len(0) ->|HT(1)|<- sma_len(1) ->|HT(2)|<- sma_len(2)
- * ->|HT(3)|<- sma_len(3)-> |+infinite HT(4)
- * In temp range between HT(i) and HT(i+1), sma_len(i) is applied.
- * HT(i) < HT(i+1), eq is not allowed since meaningless
- * sma_len(i) in [1, 60]
- */
- #define MAX_STEP_MA_LEN (4)
- #define MSMA_MAX_HT (1000000)
- #define MSMA_MIN_HT (-275000)
- struct mtk_thermal_cooler_data {
- struct thermal_zone_device *tz;
- struct thermal_cooling_device_ops *ops;
- void *devdata;
- int trip;
- char conditions[MTK_THERMAL_MONITOR_COOLER_MAX_EXTRA_CONDITIONS][THERMAL_NAME_LENGTH];
- int *condition_last_value[MTK_THERMAL_MONITOR_COOLER_MAX_EXTRA_CONDITIONS];
- int threshold[MTK_THERMAL_MONITOR_COOLER_MAX_EXTRA_CONDITIONS];
- int exit_threshold;
- int id;
- };
- struct mtk_thermal_tz_data {
- struct thermal_zone_device_ops *ops;
- unsigned int ma_len; /* max 60 */
- unsigned int ma_counter;
- long ma[60];
- #if (MAX_STEP_MA_LEN > 1)
- unsigned int curr_idx_ma_len;
- unsigned int ma_lens[MAX_STEP_MA_LEN];
- long msma_ht[MAX_STEP_MA_LEN];
- /**< multi-step moving avg. high threshold array. */
- #endif
- long fake_temp;
- /* to store the Tfake, range from -275000 to MAX positive of int...
- -275000 is a special number to turn off Tfake */
- struct mutex ma_lock; /* protect moving avg. vars... */
- };
- struct proc_dir_entry *mtk_thermal_get_proc_drv_therm_dir_entry(void);
- static DEFINE_MUTEX(MTM_GET_TEMP_LOCK);
- static int *tz_last_values[MTK_THERMAL_SENSOR_COUNT] = { NULL };
- /* ************************************ */
- /* Global Variable */
- /* ************************************ */
- struct thermal_zone_device_ops *g_SysinfoAttachOps;
- static bool enable_ThermalMonitor;
- static bool enable_ThermalMonitorXlog;
- static int g_nStartRealTime;
- static struct proc_dir_entry *proc_cooler_dir_entry; /* lock by MTM_COOLER_PROC_DIR_LOCK */
- static struct proc_dir_entry *proc_tz_dir_entry; /* lock by MTK_TZ_PROC_DIR_LOCK */
- static struct proc_dir_entry *proc_drv_therm_dir_entry;
- /**
- * write to nBattCurrentCnsmpt, nCPU0_usage, and nCPU1_usage are locked by MTM_SYSINFO_LOCK
- */
- static int nBattCurrentCnsmpt;
- static int nCPU_loading_sum;
- /* 64bit */
- static unsigned long long g_check_cpu_info_flag = 0x0;
- static unsigned long long g_check_batt_info_flag = 0x0;
- static unsigned long long g_check_wifi_info_flag = 0x0;
- static unsigned long long g_check_mobile_info_flag = 0x0;
- static int nWifi_throughput;
- static int nMobile_throughput;
- /* static int nModem_TxPower = -127; ///< Indicate invalid value */
- /* For enabling time based thermal protection under phone call+AP suspend scenario. */
- static int g_mtm_phone_call_ongoing;
- static DEFINE_MUTEX(MTM_COOLER_LOCK);
- static DEFINE_MUTEX(MTM_SYSINFO_LOCK);
- static DEFINE_MUTEX(MTM_COOLER_PROC_DIR_LOCK);
- static DEFINE_MUTEX(MTM_TZ_PROC_DIR_LOCK);
- static DEFINE_MUTEX(MTM_DRV_THERM_PROC_DIR_LOCK);
- static struct delayed_work _mtm_sysinfo_poll_queue;
- static kuid_t uid = KUIDT_INIT(0);
- static kgid_t gid = KGIDT_INIT(1000);
- /* ************************************ */
- /* Macro */
- /* ************************************ */
- #ifdef CONFIG_MTK_MT_LOGGER
- #define THRML_STORAGE_LOG(msg_id, func_name, ...) \
- do { \
- if (unlikely(is_dump_mthermal()) && enable_ThermalMonitor) { \
- AddThrmlTrace(msg_id, func_name, __VA_ARGS__); \
- } \
- } while (0)
- #else
- #define THRML_STORAGE_LOG(msg_id, func_name, ...)
- #endif
- #define THRML_LOG(fmt, args...) \
- do { \
- if (unlikely(enable_ThermalMonitorXlog)) { \
- pr_debug("THERMAL/MONITOR " fmt, ##args); \
- } \
- } while (0)
- #define THRML_ERROR_LOG(fmt, args...) pr_debug("THERMAL/MONITOR " fmt, ##args)
- /* ************************************ */
- /* Define */
- /* ************************************ */
- /* thermal_zone_device * sysinfo_monitor_register(int nPollingTime); */
- /* int sysinfo_monitor_unregister(void); */
- #define SYSINFO_ATTACH_DEV_NAME "mtktscpu"
- /* ************************************ */
- /* Thermal Monitor API */
- /* ************************************ */
- #if defined(CONFIG_MTK_THERMAL_TIME_BASE_PROTECTION)
- #include <mach/mt_gpt.h>
- #include <mach/mt_sleep.h>
- #include <linux/wakelock.h>
- /* extern int force_get_tbat(void); */
- static struct wake_lock mtm_wake_lock;
- static unsigned int gpt_remaining_cnt;
- static int last_batt_raw_temp;
- static int mtk_thermal_monitor_get_battery_timeout_time(void)
- {
- if (NULL != tz_last_values[MTK_THERMAL_SENSOR_BATTERY]) {
- int batt_temp = last_batt_raw_temp; /* *tz_last_values[MTK_THERMAL_SENSOR_BATTERY]; */
- if (batt_temp <= 25000)
- return 330; /* max 330 */
- else if (batt_temp <= 35000 && batt_temp > 25000)
- return 300;
- else if (batt_temp <= 45000 && batt_temp > 35000)
- return 150; /* 2.5 min */
- else if (batt_temp <= 50000 && batt_temp > 45000)
- return 60; /* 1 min */
- else
- return 30; /* 0.5 min */
- } else {
- return -1; /* no battery temperature, what to protect? */
- }
- }
- static int mtk_thermal_monitor_suspend(struct platform_device *dev, pm_message_t state)
- {
- /* check if phone call on going... */
- if (g_mtm_phone_call_ongoing) {
- /* if yes, based on battery temperature to setup a GPT timer */
- int timeout = mtk_thermal_monitor_get_battery_timeout_time();
- if (timeout > 0) {
- /* restart a one-shot GPT timer // max 5.5 min */
- if (gpt_remaining_cnt > 0 && gpt_remaining_cnt <= (timeout * 13000000))
- gpt_set_cmp(GPT5, gpt_remaining_cnt);
- else
- gpt_set_cmp(GPT5, timeout * 13000000); /* compare unit is (1/13M) s */
- start_gpt(GPT5);
- THRML_ERROR_LOG("%s timeout: %d, gpt_remaining_cnt: %u\n", __func__,
- timeout, gpt_remaining_cnt);
- }
- /* make GPT able to wake up AP */
- slp_set_wakesrc(WAKE_SRC_CFG_KEY | WAKE_SRC_GPT, true, false);
- } else {
- THRML_LOG("%s disable GPT wakes AP.\n", __func__);
- /* make GPT unable to wake up AP */
- slp_set_wakesrc(WAKE_SRC_CFG_KEY | WAKE_SRC_GPT, false, false);
- }
- return 0;
- }
- static int mtk_thermal_monitor_resume(struct platform_device *dev)
- {
- /* take wake lock */
- if (NULL != tz_last_values[MTK_THERMAL_SENSOR_BATTERY]) {
- /* check if phone call on going...if yes,
- we need to confirm battery temp. if not, we don't need this. */
- if (g_mtm_phone_call_ongoing) {
- unsigned int GPT5_cmp;
- unsigned int GPT5_cnt;
- int gpt_counting;
- gpt_counting = gpt_is_counting(GPT5);
- gpt_get_cmp(GPT5, &GPT5_cmp);
- gpt_get_cnt(GPT5, &GPT5_cnt);
- gpt_remaining_cnt = GPT5_cmp - GPT5_cnt;
- /* If no wake lock taken and gpt does timeout! */
- if (!wake_lock_active(&mtm_wake_lock) && !gpt_counting) {
- THRML_ERROR_LOG("%s wake_lock() counting=%d, cmp=%u, cnt=%u",
- __func__, gpt_counting, GPT5_cmp, GPT5_cnt);
- wake_lock(&mtm_wake_lock);
- }
- }
- }
- /* cancel my own GPT timer, ok to do it w/o pairing */
- stop_gpt(GPT5);
- /* release wake lock until no problem... */
- return 0;
- }
- static struct platform_driver mtk_thermal_monitor_driver = {
- .remove = NULL,
- .shutdown = NULL,
- .probe = NULL,
- .suspend = mtk_thermal_monitor_suspend,
- .resume = mtk_thermal_monitor_resume,
- .driver = {
- .name = "mtk-therm-mon",
- },
- };
- #endif
- #if MTK_THERMAL_MONITOR_MEASURE_GET_TEMP_OVERHEAD
- static long int _get_current_time_us(void)
- {
- struct timeval t;
- do_gettimeofday(&t);
- return (t.tv_sec & 0xFFF) * 1000000 + t.tv_usec;
- }
- #endif
- #ifdef CONFIG_MTK_THERMAL_EXT_CONTROL
- #include "md32_ipi.h"
- #include "md32_helper.h"
- #include <mach/mtk_thermal_ext_control.h>
- #define MTK_THERMAL_DEFAULT_MAX_TEMPERATURE 300000
- #define MTK_THERMAL_MAX_TRIP_NUM 20
- enum mtk_thermal_control_state {
- MTK_THERMAL_CONTROL_STATE_NONE = 0,
- MTK_THERMAL_CONTROL_STATE_POLLING,
- MTK_THERMAL_CONTROL_STATE_SWITCHING,
- MTK_THERMAL_CONTROL_STATE_INTERRUPT,
- };
- struct mtk_thermal_ext_tz_data {
- long high_trip_point;
- long low_trip_point;
- int polling_delay;
- int last_temperature;
- int trips;
- struct mtk_thermal_tz_data *tzdata;
- struct thermal_zone_device *tz;
- bool set;
- };
- static int g_controlState;
- static DEFINE_MUTEX(mtk_thermal_ext_control_lock);
- static struct mtk_thermal_ext_tz_data mtk_thermal_ext_tz_values[MTK_THERMAL_EXT_SENSOR_COUNT];
- static int mtk_thermal_ext_get_threshold(struct mtk_thermal_ext_tz_data *tzdata,
- struct thermal_zone_device *thermal, struct thermal_zone_device_ops *ops, int trips) {
- unsigned long temperature;
- int i, j, ret, trip_num;
- long trip_point[MTK_THERMAL_MAX_TRIP_NUM] = { 0 };
- long temp;
- if (!tzdata || !thermal || !ops) {
- THRML_ERROR_LOG("%s invalid parameter\n", __func__);
- return -1;
- }
- trip_num = (trips < MTK_THERMAL_MAX_TRIP_NUM) ? trips : MTK_THERMAL_MAX_TRIP_NUM;
- if (ops->get_trip_temp) {
- for (i = 0; i < trip_num; i++) {
- ret = ops->get_trip_temp(thermal, i, &temperature);
- trip_point[i] = (long)temperature;
- }
- if (trip_num > 1) {
- /* Sort trip point */
- for (i = (trip_num - 1); i > 0; i--) {
- for (j = 0; j < i; j++) {
- if (trip_point[j] > trip_point[j + 1]) {
- temp = trip_point[j];
- trip_point[j] = trip_point[j + 1];
- trip_point[j + 1] = temp;
- }
- }
- }
- /*
- * Get trip points
- * Condition 1. temperature < low_trip_point < high_trip_point
- * Condition 2. low_trip_point <= temperature < high_trip_point
- */
- for (i = 0; i < trip_num; i++) {
- if (tzdata->last_temperature < trip_point[i]) {
- if (i == 0) {
- tzdata->low_trip_point = trip_point[0];
- tzdata->high_trip_point = trip_point[1];
- } else {
- tzdata->low_trip_point = trip_point[i - 1];
- tzdata->high_trip_point = trip_point[i];
- }
- break;
- } else if (i == (trip_num - 1)) {
- tzdata->low_trip_point = trip_point[i];
- tzdata->high_trip_point =
- MTK_THERMAL_DEFAULT_MAX_TEMPERATURE;
- }
- }
- } else if (trip_num == 1) {
- tzdata->low_trip_point = trip_point[0];
- tzdata->high_trip_point = MTK_THERMAL_DEFAULT_MAX_TEMPERATURE;
- } else {
- tzdata->low_trip_point = 0;
- tzdata->high_trip_point = 0;
- }
- } else {
- return -1;
- }
- return 0;
- }
- static int mtk_thermal_ext_get_temp(struct thermal_zone_device *tz, int *temp)
- {
- int i;
- mutex_lock(&mtk_thermal_ext_control_lock);
- if (g_controlState == MTK_THERMAL_CONTROL_STATE_INTERRUPT) {
- for (i = 0; i < MTK_THERMAL_EXT_SENSOR_COUNT; i++) {
- if (mtk_thermal_ext_tz_values[i].set
- && mtk_thermal_ext_tz_values[i].tz == tz) {
- *temp = mtk_thermal_ext_tz_values[i].last_temperature;
- THRML_LOG("%s tz %s, return temp %d\n", __func__, tz->type, *temp);
- mutex_unlock(&mtk_thermal_ext_control_lock);
- return 0;
- }
- }
- }
- mutex_unlock(&mtk_thermal_ext_control_lock);
- return -1;
- }
- static bool mtk_thermal_ext_ipi_msg_send(thermal_ipi_msg_id id, thermal_zone_data *tzdata,
- uint wait)
- {
- thermal_ipi_msg msg;
- ipi_status status;
- THRML_LOG("%s msg id %x\n", __func__, (unsigned int)id);
- memset(&msg, 0, sizeof(thermal_ipi_msg));
- msg.id = id;
- if (tzdata != NULL) {
- msg.data.tz.id = tzdata->id;
- msg.data.tz.high_trip_point = tzdata->high_trip_point;
- msg.data.tz.low_trip_point = tzdata->low_trip_point;
- msg.data.tz.polling_delay = tzdata->polling_delay;
- }
- status = md32_ipi_send(IPI_THERMAL, (void *)&msg, sizeof(thermal_ipi_msg), wait);
- if (status != DONE) {
- THRML_ERROR_LOG("%s send fail, ret %d\n", __func__, status);
- return false;
- }
- return true;
- }
- static void mtk_thermal_ext_set_tz_threshold(struct mtk_thermal_ext_tz_data *tzdata, int idx)
- {
- thermal_zone_data tz_threshold;
- tz_threshold.id = idx;
- tz_threshold.high_trip_point = tzdata->high_trip_point;
- tz_threshold.low_trip_point = tzdata->low_trip_point;
- if (tzdata->trips > 0)
- tz_threshold.polling_delay = tzdata->polling_delay;
- else
- tz_threshold.polling_delay = 0;
- THRML_LOG("%s id: %d, polling delay: %d, low trip: %d, high trip: %d\n", __func__,
- idx,
- tz_threshold.polling_delay,
- tz_threshold.low_trip_point, tz_threshold.high_trip_point);
- mtk_thermal_ext_ipi_msg_send(THERMAL_AP_IPI_MSG_SET_TZ_THRESHOLD, &tz_threshold, true);
- }
- static void mtk_thermal_ext_update_tz_threshold(int tzidx, int temperature)
- {
- int result;
- mutex_lock(&mtk_thermal_ext_control_lock);
- mtk_thermal_ext_tz_values[tzidx].last_temperature = temperature;
- result = mtk_thermal_ext_get_threshold(&mtk_thermal_ext_tz_values[tzidx],
- mtk_thermal_ext_tz_values[tzidx].tz,
- mtk_thermal_ext_tz_values[tzidx].tzdata->ops,
- mtk_thermal_ext_tz_values[tzidx].trips);
- if (result < 0) {
- mtk_thermal_ext_tz_values[tzidx].high_trip_point =
- MTK_THERMAL_DEFAULT_MAX_TEMPERATURE;
- mtk_thermal_ext_tz_values[tzidx].low_trip_point =
- MTK_THERMAL_DEFAULT_MAX_TEMPERATURE;
- }
- mutex_unlock(&mtk_thermal_ext_control_lock);
- mtk_thermal_ext_set_tz_threshold(&mtk_thermal_ext_tz_values[tzidx], tzidx);
- }
- static void mtk_thermal_ext_switch_control_back(void)
- {
- int i;
- /* Switch state from interrupt mode to polling mode */
- mutex_lock(&mtk_thermal_ext_control_lock);
- if (g_controlState == MTK_THERMAL_CONTROL_STATE_INTERRUPT) {
- for (i = 0; i < MTK_THERMAL_EXT_SENSOR_COUNT; i++) {
- if (mtk_thermal_ext_tz_values[i].set
- && mtk_thermal_ext_tz_values[i].polling_delay > 0) {
- schedule_delayed_work(&
- (mtk_thermal_ext_tz_values[i].tz->poll_queue),
- 0);
- }
- }
- g_controlState = MTK_THERMAL_CONTROL_STATE_POLLING;
- }
- mutex_unlock(&mtk_thermal_ext_control_lock);
- }
- static void mtk_thermal_ext_switch_control_out(void)
- {
- int i;
- /* [Warning] Not lock here because md32_ipi_send() also lock and
- * it will result in kernel warning (LockProve Warning) */
- /* mutex_lock(&mtk_thermal_ext_control_lock); */
- if (g_controlState == MTK_THERMAL_CONTROL_STATE_POLLING) {
- for (i = 0; i < MTK_THERMAL_EXT_SENSOR_COUNT; i++) {
- if (mtk_thermal_ext_tz_values[i].set)
- mtk_thermal_ext_update_tz_threshold(i, *tz_last_values[i]);
- }
- g_controlState = MTK_THERMAL_CONTROL_STATE_SWITCHING;
- }
- /* mutex_unlock(&mtk_thermal_ext_control_lock); */
- mtk_thermal_ext_ipi_msg_send(THERMAL_AP_IPI_MSG_MD32_START, NULL, false);
- }
- static void mtk_thermal_ext_ipi_msg_handler(int id, void *data, uint len)
- {
- thermal_ipi_msg *msg = (thermal_ipi_msg *) data;
- int i;
- THRML_LOG("%s id %d, msg id %x, len %d\n", __func__, id, msg->id, len);
- switch (msg->id) {
- case THERMAL_MD32_IPI_MSG_READY:
- {
- mtk_thermal_ext_switch_control_out();
- break;
- }
- case THERMAL_MD32_IPI_MSG_MD32_START_ACK:
- {
- mutex_lock(&mtk_thermal_ext_control_lock);
- if (g_controlState != MTK_THERMAL_CONTROL_STATE_SWITCHING)
- break;
- for (i = 0; i < MTK_THERMAL_EXT_SENSOR_COUNT; i++) {
- if (mtk_thermal_ext_tz_values[i].set) {
- /* [Warning] Can not use cancel_delayed_work_sync() here
- * because it will cause kernel warning (LockProve Warning) */
- if (cancel_delayed_work(&(mtk_thermal_ext_tz_values[i].tz->poll_queue)) == 0)
- THRML_ERROR_LOG("%s work (tz %d) is running\n", __func__, i);
- }
- }
- g_controlState = MTK_THERMAL_CONTROL_STATE_INTERRUPT;
- mutex_unlock(&mtk_thermal_ext_control_lock);
- break;
- }
- case THERMAL_MD32_IPI_MSG_REACH_THRESHOLD:
- {
- int tzidx = msg->data.tz_status.id;
- struct thermal_zone_device *tz = NULL;
- /* [Warning] Not lock here because md32_ipi_send() also lock and
- * it will result in kernel warning (LockProve Warning) */
- /* mutex_lock(&mtk_thermal_ext_control_lock); */
- if (g_controlState == MTK_THERMAL_CONTROL_STATE_INTERRUPT) {
- if (mtk_thermal_ext_tz_values[tzidx].set) {
- tz = mtk_thermal_ext_tz_values[tzidx].tz;
- mtk_thermal_ext_update_tz_threshold(tzidx,
- (int)msg->
- data.tz_status.
- temperature);
- }
- }
- /* mutex_unlock(&mtk_thermal_ext_control_lock); */
- if (tz != NULL) {
- thermal_zone_device_update(tz);
- /* [Warning] Can not use cancel_delayed_work_sync() here
- because it will cause kernel warning (LockProve Warning) */
- if (cancel_delayed_work(&(tz->poll_queue)) == 0) {
- THRML_ERROR_LOG("%s work (tz %d) is running\n", __func__,
- tzidx);
- }
- }
- break;
- }
- }
- }
- static int mtk_thermal_ext_proc_show(struct seq_file *m, void *v)
- {
- int i;
- mutex_lock(&mtk_thermal_ext_control_lock);
- seq_puts(m, "\r\n[EXT Thermal Control Debug]\r\n");
- seq_puts(m, "=========================================\r\n");
- seq_printf(m, "ap thermal state = %d\r\n", g_controlState);
- for (i = 0; i < MTK_THERMAL_EXT_SENSOR_COUNT; i++) {
- seq_printf(m,
- "tz %s, id: %d, set: %d, temp: %d, polling delay: %d, low trip: %d, high trip: %d\r\n",
- mtk_thermal_ext_tz_values[i].tz->type, i,
- mtk_thermal_ext_tz_values[i].set,
- mtk_thermal_ext_tz_values[i].last_temperature,
- mtk_thermal_ext_tz_values[i].polling_delay,
- mtk_thermal_ext_tz_values[i].low_trip_point,
- mtk_thermal_ext_tz_values[i].high_trip_point);
- }
- mutex_unlock(&mtk_thermal_ext_control_lock);
- return 0;
- }
- static int mtk_thermal_ext_proc_open(struct inode *inode, struct file *file)
- {
- return single_open(file, mtk_thermal_ext_proc_show, NULL);
- }
- static const struct file_operations mtk_thermal_ext_proc_fops = {
- .owner = THIS_MODULE,
- .open = mtk_thermal_ext_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- };
- static int mtk_thermal_ext_get_tz_idx(char *type)
- {
- if (0 == strncmp(type, "mtktsabb", 8))
- return MTK_THERMAL_EXT_SENSOR_ABB;
- else if (0 == strncmp(type, "mtktspmic", 9))
- return MTK_THERMAL_EXT_SENSOR_PMIC;
- else if (0 == strncmp(type, "mtktsbattery2", 13))
- return -1;
- else if (0 == strncmp(type, "mtktsbattery", 12))
- return MTK_THERMAL_EXT_SENSOR_BATTERY;
- return -1;
- }
- static int mtk_thermal_ext_notify(struct notifier_block *self, unsigned long action, void *dev)
- {
- #ifdef DYNAMIC_TCM_SWAP
- MD32_REQUEST_SWAP *request_swap = (MD32_REQUEST_SWAP *) dev;
- THRML_LOG("%s action: %d, current group: %d, start group: %d\n", __func__,
- action, request_swap->current_group, request_swap->group_start);
- switch (action) {
- case APP_TRIGGER_TCM_SWAP_START:
- {
- if (request_swap->prepare_result < 0) {
- /* MD32 dynamic swap prepare failed */
- break;
- }
- if (request_swap->current_group == GROUP_BASIC
- && request_swap->group_start == GROUP_A) {
- mtk_thermal_ext_switch_control_back();
- }
- break;
- }
- case APP_TRIGGER_TCM_SWAP_DONE:
- {
- if (request_swap->current_group == GROUP_A
- && request_swap->group_start == GROUP_BASIC) {
- mtk_thermal_ext_switch_control_out();
- }
- break;
- }
- case APP_TRIGGER_TCM_SWAP_FAIL:
- {
- if (request_swap->current_group == GROUP_BASIC
- && request_swap->group_start == GROUP_A) {
- mtk_thermal_ext_switch_control_out();
- }
- break;
- }
- case APP_TRIGGER_APP_FINISHED:
- break;
- default:
- break;
- }
- #endif
- return NOTIFY_OK;
- }
- static struct notifier_block mtk_thermal_ext_nb = {
- .notifier_call = mtk_thermal_ext_notify,
- };
- #endif /* CONFIG_MTK_THERMAL_EXT_CONTROL */
- static int mtk_thermal_get_tz_idx(char *type)
- {
- if (0 == strncmp(type, "mtktscpu", 8))
- return MTK_THERMAL_SENSOR_CPU;
- else if (0 == strncmp(type, "mtktsabb", 8))
- return MTK_THERMAL_SENSOR_ABB;
- else if (0 == strncmp(type, "mtktspmic", 9))
- return MTK_THERMAL_SENSOR_PMIC;
- else if (0 == strncmp(type, "mtktsbattery2", 13))
- return MTK_THERMAL_SENSOR_BATTERY2;
- else if (0 == strncmp(type, "mtktsbattery", 12))
- return MTK_THERMAL_SENSOR_BATTERY;
- else if (0 == strncmp(type, "mtktspa", 7))
- return MTK_THERMAL_SENSOR_MD1;
- else if (0 == strncmp(type, "mtktstdpa", 9))
- return MTK_THERMAL_SENSOR_MD2;
- else if (0 == strncmp(type, "mtktswmt", 8))
- return MTK_THERMAL_SENSOR_WIFI;
- else if (0 == strncmp(type, "mtktsbuck", 9))
- return MTK_THERMAL_SENSOR_BUCK;
- else if (0 == strncmp(type, "mtktsAP", 7))
- return MTK_THERMAL_SENSOR_AP;
- else if (0 == strncmp(type, "mtktspcb1", 9))
- return MTK_THERMAL_SENSOR_PCB1;
- else if (0 == strncmp(type, "mtktspcb2", 9))
- return MTK_THERMAL_SENSOR_PCB2;
- else if (0 == strncmp(type, "mtktsskin", 9))
- return MTK_THERMAL_SENSOR_SKIN;
- else if (0 == strncmp(type, "mtktsxtal", 9))
- return MTK_THERMAL_SENSOR_XTAL;
- return -1;
- }
- static struct proc_dir_entry *_get_proc_cooler_dir_entry(void)
- {
- mutex_lock(&MTM_COOLER_PROC_DIR_LOCK);
- if (NULL == proc_cooler_dir_entry) {
- proc_cooler_dir_entry = proc_mkdir("mtkcooler", NULL);
- mb();
- if (NULL == proc_cooler_dir_entry)
- THRML_ERROR_LOG("%s mkdir /proc/mtkcooler failed\n", __func__);
- }
- mutex_unlock(&MTM_COOLER_PROC_DIR_LOCK);
- return proc_cooler_dir_entry;
- }
- static struct proc_dir_entry *_get_proc_tz_dir_entry(void)
- {
- mutex_lock(&MTM_TZ_PROC_DIR_LOCK);
- if (NULL == proc_tz_dir_entry) {
- proc_tz_dir_entry = proc_mkdir("mtktz", NULL);
- mb();
- if (NULL == proc_tz_dir_entry)
- THRML_ERROR_LOG("%s mkdir /proc/mtktz failed\n", __func__);
- }
- mutex_unlock(&MTM_TZ_PROC_DIR_LOCK);
- return proc_tz_dir_entry;
- }
- static struct thermal_cooling_device_ops *recoveryClientCooler
- (struct thermal_cooling_device *cdev, struct mtk_thermal_cooler_data **mcdata) {
- *mcdata = cdev->devdata;
- cdev->devdata = (*mcdata)->devdata;
- return (*mcdata)->ops;
- }
- /* Lookup List to get Client's Thermal Zone OPS */
- static struct thermal_zone_device_ops *getClientZoneOps(struct thermal_zone_device *zdev)
- {
- struct thermal_zone_device_ops *ret = NULL;
- struct mtk_thermal_tz_data *tzdata;
- if ((NULL == zdev) || (NULL == zdev->devdata)) {
- BUG();
- return NULL;
- }
- tzdata = zdev->devdata;
- mutex_lock(&tzdata->ma_lock);
- ret = tzdata->ops;
- mutex_unlock(&tzdata->ma_lock);
- return ret;
- }
- #define CPU_USAGE_CURRENT_FIELD (0)
- #define CPU_USAGE_SAVE_FIELD (1)
- #define CPU_USAGE_FRAME_FIELD (2)
- struct cpu_index_st {
- unsigned long u[3];
- unsigned long s[3];
- unsigned long n[3];
- unsigned long i[3];
- unsigned long w[3];
- unsigned long q[3];
- unsigned long sq[3];
- unsigned long tot_frme;
- unsigned long tz;
- int usage;
- int freq;
- };
- struct gpu_index_st {
- int usage;
- int freq;
- };
- static struct cpu_index_st cpu_index_list[8]; /* /< 8-Core is maximum */
- static struct gpu_index_st gpu_index;
- #define SEEK_BUFF(x, c) \
- do { \
- while (*x != c)\
- x++; \
- x++; \
- } while (0)
- #define TRIMz_ex(tz, x) ((tz = (unsigned long long)(x)) < 0 ? 0 : tz)
- enum {
- THERMAL_SYS_INFO_CPU = 0x1,
- THERMAL_SYS_INFO_GPU = 0x2,
- THERMAL_SYS_INFO_BATT = 0x4,
- THERMAL_SYS_INFO_WIFI = 0x8,
- THERMAL_SYS_INFO_MD = 0x10,
- THERMAL_SYS_INFO_ALL = 0xFFFFFFF
- };
- static int mtk_sysinfo_get_info(unsigned int mask)
- {
- int nBattVol, nBattTemp;
- int i;
- int nocpucores = 0, *cpufreqs, *cpuloadings;
- int nogpucores = 0, *gpufreqs, *gpuloadings;
- int noextraattr = 0, *attrvalues;
- char **attrnames, **attrunits;
- if (mask == 0x0)
- return 0;
- mutex_lock(&MTM_SYSINFO_LOCK);
- /* ****************** */
- /* Battery */
- /* ****************** */
- if (mask & THERMAL_SYS_INFO_BATT) {
- if (mtk_thermal_get_batt_info(&nBattVol, &nBattCurrentCnsmpt, &nBattTemp))
- ; /* TODO: print error log */
- }
- /* ****************** */
- /* CPU Usage */
- /* ****************** */
- /* ****************** */
- /* CPU Frequency */
- /* ****************** */
- if (mask & THERMAL_SYS_INFO_CPU) {
- if (mtk_thermal_get_cpu_info(&nocpucores, &cpufreqs, &cpuloadings))
- ; /* TODO: print error log */
- else {
- for (i = 0; i < nocpucores; i++) {
- cpu_index_list[i].freq = cpufreqs[i];
- cpu_index_list[i].usage = cpuloadings[i];
- }
- }
- /* CPU loading average */
- nCPU_loading_sum = 0;
- for (i = 0; i < nocpucores; i++)
- nCPU_loading_sum += cpuloadings[i];
- }
- /* ****************** */
- /* GPU Index */
- /* ****************** */
- if (mask & THERMAL_SYS_INFO_GPU) {
- if (mtk_thermal_get_gpu_info(&nogpucores, &gpufreqs, &gpuloadings))
- ; /* TODO: print error log */
- else {
- gpu_index.freq = gpufreqs[0];
- gpu_index.usage = gpuloadings[0];
- }
- }
- /* ****************** */
- /* Modem Index */
- /* ****************** */
- /* ****************** */
- /* Wifi Index */
- /* ****************** */
- if (mask & (THERMAL_SYS_INFO_WIFI | THERMAL_SYS_INFO_MD)) {
- if (mtk_thermal_get_extra_info(&noextraattr, &attrnames, &attrvalues, &attrunits))
- /* TODO: print error log */;
- else {
- /* THRML_LOG("%s %d, %d, %d, %d, %d, %d, %d, %d\n",
- __func__,*(attrvalues +0), *(attrvalues +1), *(attrvalues +2),
- *(attrvalues +3), *(attrvalues +4), *(attrvalues +5),
- *(attrvalues +6), *(attrvalues +7)); */
- nMobile_throughput = *(attrvalues + 7);
- THRML_LOG("%s Mobile_throughput=%d\n", __func__, nMobile_throughput);
- }
- }
- mutex_unlock(&MTM_SYSINFO_LOCK);
- /* print extra info */
- for (i = 0; i < noextraattr; i++) {
- THRML_STORAGE_LOG(THRML_LOGGER_MSG_MISC_EX_INFO, get_misc_ex_info, attrnames[i],
- attrvalues[i], attrunits[i]);
- }
- /* print batt info */
- if (mask & THERMAL_SYS_INFO_BATT) {
- THRML_LOG("%s nBattCurrentCnsmpt=%d nBattVol=%d nBattTemp=%d\n", __func__,
- nBattCurrentCnsmpt, nBattVol, nBattTemp);
- }
- THRML_STORAGE_LOG(THRML_LOGGER_MSG_BATTERY_INFO, get_battery_info, nBattCurrentCnsmpt,
- nBattVol, nBattTemp);
- /* CPU and GPU to storage logger */
- THRML_STORAGE_LOG(THRML_LOGGER_MSG_CPU_INFO_EX, get_cpu_info_ex,
- cpu_index_list[0].usage, cpu_index_list[1].usage,
- cpu_index_list[2].usage, cpu_index_list[3].usage,
- cpu_index_list[0].freq, cpu_index_list[1].freq,
- cpu_index_list[2].freq, cpu_index_list[3].freq,
- gpu_index.usage, gpu_index.freq);
- if (mask & THERMAL_SYS_INFO_CPU) {
- THRML_LOG("%s CPU U C0=%d C1=%d C2=%d C3=%d\n", __func__,
- cpu_index_list[0].usage, cpu_index_list[1].usage,
- cpu_index_list[2].usage, cpu_index_list[3].usage);
- THRML_LOG("%s CPU Freq C0=%d C1=%d C2=%d C3=%d\n", __func__,
- cpu_index_list[0].freq, cpu_index_list[1].freq,
- cpu_index_list[2].freq, cpu_index_list[3].freq);
- }
- return 0;
- }
- static int _mtm_interval;
- static void _mtm_update_sysinfo(struct work_struct *work)
- {
- if (true == enable_ThermalMonitor)
- mtk_sysinfo_get_info(THERMAL_SYS_INFO_ALL);
- else {
- unsigned int mask = 0;
- mask |= (g_check_cpu_info_flag == 0ULL) ? 0 : THERMAL_SYS_INFO_CPU;
- mask |= (g_check_batt_info_flag == 0ULL) ? 0 : THERMAL_SYS_INFO_BATT;
- mask |= (g_check_wifi_info_flag == 0ULL) ? 0 : THERMAL_SYS_INFO_WIFI;
- mask |= (g_check_mobile_info_flag == 0ULL) ? 0 : THERMAL_SYS_INFO_MD;
- mtk_sysinfo_get_info(mask);
- }
- cancel_delayed_work(&_mtm_sysinfo_poll_queue);
- if (_mtm_interval != 0)
- queue_delayed_work(system_freezable_wq, &_mtm_sysinfo_poll_queue,
- msecs_to_jiffies(_mtm_interval));
- }
- static void _mtm_decide_new_delay(void)
- {
- int new_interval = 0;
- if (true == enable_ThermalMonitor) {
- new_interval = 1000;
- } else {
- unsigned int mask = 0;
- mask |= (g_check_cpu_info_flag == 0ULL) ? 0 : THERMAL_SYS_INFO_CPU;
- mask |= (g_check_batt_info_flag == 0ULL) ? 0 : THERMAL_SYS_INFO_BATT;
- mask |= (g_check_wifi_info_flag == 0ULL) ? 0 : THERMAL_SYS_INFO_WIFI;
- mask |= (g_check_mobile_info_flag == 0ULL) ? 0 : THERMAL_SYS_INFO_MD;
- if (mask != 0x0)
- new_interval = 1000;
- }
- if (_mtm_interval == 0 && new_interval != 0) {
- _mtm_interval = new_interval;
- _mtm_update_sysinfo(NULL);
- } else {
- _mtm_interval = new_interval;
- }
- }
- /* ************************************ */
- /* Thermal Host Driver Interface */
- /* ************************************ */
- /* Read */
- static int mtkthermal_read(struct seq_file *m, void *v)
- {
- seq_puts(m, "\r\n[Thermal Monitor debug flag]\r\n");
- seq_puts(m, "=========================================\r\n");
- seq_printf(m, "enable_ThermalMonitor = %d\r\n", enable_ThermalMonitor);
- seq_printf(m, "enable_ThermalMonitorXlog = %d\r\n", enable_ThermalMonitorXlog);
- seq_printf(m, "g_nStartRealTime = %d\r\n", g_nStartRealTime);
- THRML_LOG("%s enable_ThermalMonitor:%d\n", __func__, enable_ThermalMonitor);
- return 0;
- }
- /* Write */
- static ssize_t mtkthermal_write(struct file *file, const char __user *buffer, size_t count,
- loff_t *data)
- {
- int len = 0, nCtrlCmd = 0, nReadTime = 0;
- char desc[32];
- len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
- if (copy_from_user(desc, buffer, len))
- return 0;
- desc[len] = '\0';
- if (sscanf(desc, "%d %d", &nCtrlCmd, &nReadTime) == 2) {
- /* Bit 0; Enable Thermal Monitor. */
- if ((nCtrlCmd >> 0) & 0x01) {
- /* Reset Global CPU Info Variable */
- memset(&cpu_index_list, 0x00, sizeof(cpu_index_list));
- enable_ThermalMonitor = true;
- } else {
- enable_ThermalMonitor = false;
- }
- _mtm_decide_new_delay();
- /* Bit 1: Enable Thermal Monitor xlog */
- enable_ThermalMonitorXlog = ((nCtrlCmd >> 1) & 0x01) ? true : false;
- /*
- * Get Real Time from user input
- * Format: hhmmss 113901=> 11:39:01
- */
- g_nStartRealTime = nReadTime;
- THRML_STORAGE_LOG(THRML_LOGGER_MSG_DEC_NUM, get_real_time, "[realtime]",
- g_nStartRealTime);
- THRML_ERROR_LOG("%s nCtrlCmd=%d enable_ThermalMonitor=%d g_nStartRealTime=%d\n",
- __func__, nCtrlCmd, (int)enable_ThermalMonitor, g_nStartRealTime);
- return count;
- }
- if (kstrtoint(desc, 10, &nCtrlCmd) == 0) {
- /* Bit 0; Enable Thermal Monitor. */
- if ((nCtrlCmd >> 0) & 0x01) {
- /* Reset Global CPU Info Variable */
- memset(&cpu_index_list, 0x00, sizeof(cpu_index_list));
- enable_ThermalMonitor = true;
- } else {
- enable_ThermalMonitor = false;
- }
- _mtm_decide_new_delay();
- /* Bit 1: Enable Thermal Monitor xlog */
- enable_ThermalMonitorXlog = ((nCtrlCmd >> 1) & 0x01) ? true : false;
- THRML_ERROR_LOG("%s nCtrlCmd=%d enable_ThermalMonitor=%d\n", __func__, nCtrlCmd,
- (int)enable_ThermalMonitor);
- return count;
- }
- THRML_LOG("%s bad arg\n", __func__);
- return -EINVAL;
- }
- static int mtkthermal_open(struct inode *inode, struct file *file)
- {
- return single_open(file, mtkthermal_read, NULL);
- }
- static const struct file_operations mtkthermal_fops = {
- .owner = THIS_MODULE,
- .open = mtkthermal_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .write = mtkthermal_write,
- .release = single_release,
- };
- static int _mtkthermal_check_cooler_conditions(struct mtk_thermal_cooler_data *cldata)
- {
- int ret = 0;
- if (NULL != cldata) {
- int i = 0;
- for (; i < MTK_THERMAL_MONITOR_COOLER_MAX_EXTRA_CONDITIONS; i++) {
- if (NULL == cldata->condition_last_value[i]) {
- ret++;
- } else {
- #if 1 /* [FIX ME] Special case for "condifion of MOBILE" */
- if (0 == strncmp(cldata->conditions[i], "MOBILE", 5)) {
- if (*cldata->condition_last_value[i] < cldata->threshold[i]) {
- THRML_LOG("%s MOBILE Condition=%s, last_value=%d, threshold=%d\n",
- __func__, cldata->conditions[i],
- (*cldata->condition_last_value[i]), cldata->threshold[i]);
- ret++;
- }
- } else if (*cldata->condition_last_value[i] > cldata->threshold[i])
- ret++;
- #else
- if (*cldata->condition_last_value[i] > cldata->threshold[i])
- ret++;
- #endif
- }
- }
- mb();
- }
- return ret;
- }
- static void _mtkthermal_clear_cooler_conditions(struct mtk_thermal_cooler_data *cldata)
- {
- int i = 0;
- cldata->exit_threshold = 0;
- for (; i < MTK_THERMAL_MONITOR_COOLER_MAX_EXTRA_CONDITIONS; i++) {
- cldata->conditions[i][0] = 0x0;
- cldata->condition_last_value[i] = NULL;
- cldata->threshold[i] = 0;
- }
- g_check_cpu_info_flag &= (~(1ULL << cldata->id));
- g_check_batt_info_flag &= (~(1ULL << cldata->id));
- g_check_wifi_info_flag &= (~(1ULL << cldata->id));
- g_check_mobile_info_flag &= (~(1ULL << cldata->id));
- _mtm_decide_new_delay();
- }
- static int _mtkthermal_cooler_read(struct seq_file *m, void *v)
- {
- struct mtk_thermal_cooler_data *mcdata;
- /**
- * The format to print out
- * <condition_name_1> <condition_value_1> <thershold_1> <state_1>
- * ..
- * <condition_name_n> <condition_value_n> <thershold_n> <state_n>
- * PS: n is MTK_THERMAL_MONITOR_COOLER_MAX_EXTRA_CONDITIONS
- */
- if (NULL == m->private) {
- THRML_ERROR_LOG("%s null data\n", __func__);
- } else {
- int i = 0;
- /* TODO: we may not need to lock here... */
- mutex_lock(&MTM_COOLER_LOCK);
- mcdata = (struct mtk_thermal_cooler_data *)m->private;
- mutex_unlock(&MTM_COOLER_LOCK);
- for (; i < MTK_THERMAL_MONITOR_COOLER_MAX_EXTRA_CONDITIONS; i++) {
- if (0x0 == mcdata->conditions[i][0])
- continue; /* no condition */
- /* TODO: consider the case that tz is unregistered... */
- seq_printf(m, "%s val=%d threshold=%d %s",
- mcdata->conditions[i],
- (NULL ==
- mcdata->
- condition_last_value[i]) ? 0 :
- *(mcdata->condition_last_value[i]), mcdata->threshold[i],
- (NULL == mcdata->condition_last_value[i]) ? "error\n" : "\n");
- }
- }
- return 0;
- }
- static ssize_t _mtkthermal_cooler_write(struct file *file, const char __user *buffer, size_t count, loff_t *data)
- {
- int len = 0;
- char desc[128];
- struct mtk_thermal_cooler_data *mcdata;
- len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
- if (copy_from_user(desc, buffer, len))
- return 0;
- desc[len] = '\0';
- /**
- * sscanf format <condition_1> <threshold_1> ... <condition_n> <threshold_n>
- * <condition_i> is string format
- * <threshold_i> is integer format
- * n is MTK_THERMAL_MONITOR_COOLER_MAX_EXTRA_CONDITIONS
- */
- /* TODO: we may not need to lock here... */
- mutex_lock(&MTM_COOLER_LOCK);
- mcdata = (struct mtk_thermal_cooler_data *)PDE_DATA(file_inode(file));
- mutex_unlock(&MTM_COOLER_LOCK);
- if (NULL == mcdata) {
- THRML_ERROR_LOG("%s null data\n", __func__);
- return -EINVAL;
- }
- /* WARNING: Modify here if MTK_THERMAL_MONITOR_COOLER_MAX_EXTRA_CONDITIONS is changed to other than 3 */
- #if (3 == MTK_THERMAL_MONITOR_COOLER_MAX_EXTRA_CONDITIONS)
- _mtkthermal_clear_cooler_conditions(mcdata);
- if (2 <= sscanf(desc, "%s %d %s %d %s %d",
- &mcdata->conditions[0][0], &mcdata->threshold[0],
- &mcdata->conditions[1][0], &mcdata->threshold[1],
- &mcdata->conditions[2][0], &mcdata->threshold[2])) {
- int i = 0;
- for (; i < MTK_THERMAL_MONITOR_COOLER_MAX_EXTRA_CONDITIONS; i++) {
- if (0 == strncmp(mcdata->conditions[i], "EXIT", 4)) {
- mcdata->exit_threshold = mcdata->threshold[i];
- } else if (0 == strncmp(mcdata->conditions[i], "CPU0", 4)) {
- mcdata->condition_last_value[i] = &nCPU_loading_sum;
- g_check_cpu_info_flag |= (1ULL << mcdata->id);
- THRML_LOG("%s cpu flag: %016llx, id=%d\n", __func__,
- g_check_cpu_info_flag, mcdata->id);
- } else if (0 == strncmp(mcdata->conditions[i], "BATCC", 5)) {
- mcdata->condition_last_value[i] = &nBattCurrentCnsmpt;
- g_check_batt_info_flag |= (1ULL << mcdata->id);
- THRML_LOG("%s batt flag: %016llx, id=%d\n", __func__,
- g_check_batt_info_flag, mcdata->id);
- } else if (0 == strncmp(mcdata->conditions[i], "WIFI", 4)) {
- mcdata->condition_last_value[i] = &nWifi_throughput;
- g_check_wifi_info_flag |= (1ULL << mcdata->id);
- THRML_LOG("%s wifi flag: %016llx, id=%d\n", __func__,
- g_check_wifi_info_flag, mcdata->id);
- } else if (0 == strncmp(mcdata->conditions[i], "MOBILE", 5)) {
- mcdata->condition_last_value[i] = &nMobile_throughput;
- g_check_mobile_info_flag |= (1ULL << mcdata->id);
- THRML_LOG("%s mobile flag: %016llx, id=%d\n", __func__,
- g_check_mobile_info_flag, mcdata->id);
- } else {
- /* normal thermal zones */
- mcdata->condition_last_value[i] = NULL;
- }
- THRML_LOG("%s %d: %s %d %p %d.\n", __func__,
- i, &mcdata->conditions[i][0], mcdata->conditions[i][0],
- mcdata->condition_last_value[i], mcdata->threshold[0]);
- }
- _mtm_decide_new_delay();
- return count;
- }
- #else
- #error "Change correspondent part when changing MTK_THERMAL_MONITOR_COOLER_MAX_EXTRA_CONDITIONS!"
- #endif
- THRML_ERROR_LOG("%s bad arg\n", __func__);
- return -EINVAL;
- }
- static int _mtkthermal_cooler_open(struct inode *inode, struct file *file)
- {
- return single_open(file, _mtkthermal_cooler_read, PDE_DATA(inode));
- }
- static const struct file_operations _mtkthermal_cooler_fops = {
- .owner = THIS_MODULE,
- .open = _mtkthermal_cooler_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .write = _mtkthermal_cooler_write,
- .release = single_release,
- };
- static int _mtkthermal_tz_read(struct seq_file *m, void *v)
- {
- struct thermal_zone_device *tz = NULL;
- if (NULL == m->private) {
- THRML_ERROR_LOG("%s null data\n", __func__);
- } else {
- tz = (struct thermal_zone_device *)m->private;
- /* TODO: consider the case that tz is unregistered... */
- seq_printf(m, "%d\n", tz->temperature);
- {
- struct mtk_thermal_tz_data *tzdata = NULL;
- int ma_len = 0;
- int fake_temp = 0;
- tzdata = tz->devdata;
- if (!tzdata)
- BUG();
- #if (MAX_STEP_MA_LEN > 1)
- mutex_lock(&tzdata->ma_lock);
- ma_len = tzdata->ma_len;
- fake_temp = tzdata->fake_temp;
- seq_printf(m, "ma_len=%d\n", ma_len);
- seq_printf(m, "%d ", tzdata->ma_lens[0]);
- {
- int i = 1;
- for (; i < MAX_STEP_MA_LEN; i++)
- seq_printf(m, "(%ld,%d) ", tzdata->msma_ht[i - 1],
- tzdata->ma_lens[i]);
- }
- mutex_unlock(&tzdata->ma_lock);
- seq_puts(m, "\n");
- #else
- mutex_lock(&tzdata->ma_lock);
- ma_len = tzdata->ma_len;
- fake_temp = tzdata->fake_temp;
- mutex_unlock(&tzdata->ma_lock);
- seq_printf(m, "ma_len=%d\n", ma_len);
- #endif
- if (-275000 < fake_temp) {
- /* print Tfake only when fake_temp > -275000 */
- seq_printf(m, "Tfake=%d\n", fake_temp);
- }
- }
- }
- return 0;
- }
- static ssize_t _mtkthermal_tz_write(struct file *file, const char __user *buffer, size_t count,
- loff_t *data)
- {
- int len = 0;
- char desc[128];
- char trailing[128] = { 0 };
- int check = 0;
- struct thermal_zone_device *tz;
- char arg_name[32] = { 0 };
- int arg_val = 0;
- len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
- if (copy_from_user(desc, buffer, len))
- return 0;
- desc[len] = '\0';
- tz = (struct thermal_zone_device *)PDE_DATA(file_inode(file));
- if (NULL == tz) {
- THRML_ERROR_LOG("%s null data\n", __func__);
- return -EINVAL;
- }
- if (2 <= sscanf(desc, "%s %d %s", arg_name, &arg_val, trailing)) {
- if ((0 == strncmp(arg_name, "ma_len", 6)) && (arg_val >= 1) && (arg_val <= 60)) {
- struct mtk_thermal_tz_data *tzdata = NULL;
- tzdata = tz->devdata;
- if (!tzdata)
- BUG();
- THRML_ERROR_LOG("%s trailing=%s\n", __func__, trailing);
- /**
- * reset MA len and lock
- */
- #if (MAX_STEP_MA_LEN > 1)
- mutex_lock(&tzdata->ma_lock);
- tzdata->ma_len = arg_val;
- tzdata->ma_counter = 0;
- tzdata->curr_idx_ma_len = 0;
- tzdata->ma_lens[0] = arg_val;
- tzdata->msma_ht[0] = MSMA_MAX_HT;
- THRML_ERROR_LOG("%s %s ma_len=%d.\n", __func__, tz->type, tzdata->ma_len);
- #if (MAX_STEP_MA_LEN == 4)
- /* reset */
- tzdata->msma_ht[1] = tzdata->msma_ht[2] = tzdata->msma_ht[3] = MSMA_MAX_HT;
- tzdata->ma_lens[1] = tzdata->ma_lens[2] = tzdata->ma_lens[3] = 1;
- check = sscanf(trailing, "%ld,%d;%ld,%d;%ld,%d;", &tzdata->msma_ht[0], &tzdata->ma_lens[1],
- &tzdata->msma_ht[1], &tzdata->ma_lens[2],
- &tzdata->msma_ht[2], &tzdata->ma_lens[3]);
- THRML_ERROR_LOG("%s %s (%ld, %d), (%ld, %d), (%ld, %d)\n", __func__,
- tz->type, tzdata->msma_ht[0], tzdata->ma_lens[1],
- tzdata->msma_ht[1], tzdata->ma_lens[2],
- tzdata->msma_ht[2], tzdata->ma_lens[3]);
- #else
- #error
- #endif
- mutex_unlock(&tzdata->ma_lock);
- #else
- mutex_lock(&tzdata->ma_lock);
- tzdata->ma_len = arg_val;
- tzdata->ma_counter = 0;
- mutex_unlock(&tzdata->ma_lock);
- THRML_ERROR_LOG("%s %s ma_len=%d.\n", __func__, tz->type, tzdata->ma_len);
- #endif
- } else if ((0 == strncmp(arg_name, "Tfake", 5)) && (arg_val >= -275000)) {
- /* only accept for [-275000, max positive value of int] */
- struct mtk_thermal_tz_data *tzdata = NULL;
- tzdata = tz->devdata;
- if (!tzdata)
- BUG();
- mutex_lock(&tzdata->ma_lock);
- tzdata->fake_temp = (long)arg_val;
- mutex_unlock(&tzdata->ma_lock);
- THRML_ERROR_LOG("%s %s Tfake=%ld.\n", __func__, tz->type, tzdata->fake_temp);
- }
- return count;
- } else {
- return -EINVAL;
- }
- }
- static int _mtkthermal_tz_open(struct inode *inode, struct file *file)
- {
- return single_open(file, _mtkthermal_tz_read, PDE_DATA(inode));
- }
- static const struct file_operations _mtkthermal_tz_fops = {
- .owner = THIS_MODULE,
- .open = _mtkthermal_tz_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .write = _mtkthermal_tz_write,
- .release = single_release,
- };
- #define MIN(_a_, _b_) ((_a_) < (_b_) ? (_a_) : (_b_))
- /* No parameter check in this internal function */
- static long _mtkthermal_update_and_get_sma(struct mtk_thermal_tz_data *tzdata, long latest_val)
- {
- long ret = 0;
- if (NULL == tzdata) {
- BUG();
- return latest_val;
- }
- mutex_lock(&tzdata->ma_lock);
- /* Use Tfake if set... */
- latest_val = (-275000 < tzdata->fake_temp) ? tzdata->fake_temp : latest_val;
- if (1 == tzdata->ma_len) {
- ret = latest_val;
- } else if (1 < tzdata->ma_len) {
- int i = 0;
- tzdata->ma[(tzdata->ma_counter) % (tzdata->ma_len)] = latest_val;
- tzdata->ma_counter++;
- for (i = 0; i < MIN(tzdata->ma_counter, tzdata->ma_len); i++)
- ret += tzdata->ma[i];
- ret = ret / ((long)MIN(tzdata->ma_counter, tzdata->ma_len));
- }
- #if (MAX_STEP_MA_LEN > 1)
- /*
- * 2. Move to correct region if ma_counter == 1
- * a. For (i=0;SMA >= high_threshold[i];i++) ;
- * b. if (curr_idx_sma_len != i) {ma_counter = 0; ma_len = sma_len[curr_idx_sma_len = i]; }
- * 3. Check if need to change region if ma_counter > 1
- * a. if SMA >= high_threshold[curr_idx_sma_len]
- * { Move upward: ma_counter = 0; ma_len = sma_len[++curr_idx_sma_len]; }
- * b. else if curr_idx_sma_len >0 && SMA < high_threshold[curr_idx_sma_len-1]
- * { Move downward: ma_counter =0; ma_len = sma_len[--curr_idx_sma_len]; }
- */
- if (1 == tzdata->ma_counter) {
- int i = 0;
- for (; ret >= tzdata->msma_ht[i]; i++)
- ;
- if (tzdata->curr_idx_ma_len != i) {
- tzdata->ma_counter = 0;
- tzdata->ma_len = tzdata->ma_lens[tzdata->curr_idx_ma_len = i];
- THRML_LOG("%s 2b ma_len: %d curr_idx_ma_len: %d\n", __func__,
- tzdata->ma_len, tzdata->curr_idx_ma_len);
- }
- } else {
- if (ret >= tzdata->msma_ht[tzdata->curr_idx_ma_len]) {
- tzdata->ma_counter = 0;
- tzdata->ma_len = tzdata->ma_lens[++(tzdata->curr_idx_ma_len)];
- THRML_LOG("%s 3a ma_len: %d curr_idx_ma_len: %d\n", __func__,
- tzdata->ma_len, tzdata->curr_idx_ma_len);
- } else if (tzdata->curr_idx_ma_len > 0
- && ret < tzdata->msma_ht[tzdata->curr_idx_ma_len - 1]) {
- tzdata->ma_counter = 0;
- tzdata->ma_len = tzdata->ma_lens[--(tzdata->curr_idx_ma_len)];
- THRML_LOG("%s 3b ma_len: %d curr_idx_ma_len: %d\n", __func__,
- tzdata->ma_len, tzdata->curr_idx_ma_len);
- }
- }
- #endif
- mutex_unlock(&tzdata->ma_lock);
- return ret;
- }
- /**
- * 0: means please do not show thermal limit in "Show CPU Usage" panel.
- * 1: means show thermal limit and CPU temp only
- * 2: means show all all tz temp besides thermal limit and CPU temp
- */
- static unsigned int g_thermal_indicator_mode;
- /**
- * delay in milliseconds.
- */
- static unsigned int g_thermal_indicator_delay;
- /* Read */
- static int _mtkthermal_indicator_read(struct seq_file *m, void *v)
- {
- seq_printf(m, "%d\n%d\n", g_thermal_indicator_mode, g_thermal_indicator_delay);
- return 0;
- }
- /* Write */
- static ssize_t _mtkthermal_indicator_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *data)
- {
- int len = 0, thermal_indicator_mode = 0, thermal_indicator_delay = 0;
- char desc[32];
- len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
- if (copy_from_user(desc, buffer, len))
- return 0;
- desc[len] = '\0';
- if (sscanf(desc, "%d %d", &thermal_indicator_mode, &thermal_indicator_delay) == 2) {
- if ((thermal_indicator_mode >= 0) && (thermal_indicator_mode <= 3))
- g_thermal_indicator_mode = thermal_indicator_mode;
- g_thermal_indicator_delay = thermal_indicator_delay;
- return count;
- } else {
- return 0;
- }
- }
- static int _mtkthermal_indicator_open(struct inode *inode, struct file *file)
- {
- return single_open(file, _mtkthermal_indicator_read, NULL);
- }
- static const struct file_operations _mtkthermal_indicator_fops = {
- .owner = THIS_MODULE,
- .open = _mtkthermal_indicator_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .write = _mtkthermal_indicator_write,
- .release = single_release,
- };
- /* Read */
- static int _mtm_scen_call_read(struct seq_file *m, void *v)
- {
- seq_printf(m, "%d\n", g_mtm_phone_call_ongoing);
- return 0;
- }
- /* Write */
- static ssize_t _mtm_scen_call_write(struct file *file, const char __user *buffer, size_t count,
- loff_t *data)
- {
- int len = 0, mtm_phone_call_ongoing = 0;
- char desc[32];
- len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
- if (copy_from_user(desc, buffer, len))
- return 0;
- desc[len] = '\0';
- if (kstrtoint(desc, 10, &mtm_phone_call_ongoing) == 0) {
- if ((mtm_phone_call_ongoing == 0) || (mtm_phone_call_ongoing == 1)) {
- g_mtm_phone_call_ongoing = mtm_phone_call_ongoing;
- if (1 == mtm_phone_call_ongoing)
- mtk_thermal_set_user_scenarios(MTK_THERMAL_SCEN_CALL);
- else if (0 == mtm_phone_call_ongoing)
- mtk_thermal_clear_user_scenarios(MTK_THERMAL_SCEN_CALL);
- }
- return count;
- }
- return 0;
- }
- static int _mtm_scen_call_open(struct inode *inode, struct file *file)
- {
- return single_open(file, _mtm_scen_call_read, NULL);
- }
- static const struct file_operations _mtm_scen_call_fops = {
- .owner = THIS_MODULE,
- .open = _mtm_scen_call_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .write = _mtm_scen_call_write,
- .release = single_release,
- };
- /* Init */
- static int __init mtkthermal_init(void)
- {
- int err = 0;
- struct proc_dir_entry *entry;
- struct proc_dir_entry *dir_entry = mtk_thermal_get_proc_drv_therm_dir_entry();
- THRML_LOG("%s\n", __func__);
- entry = proc_create("mtm_monitor", S_IRUGO | S_IWUSR | S_IWGRP, dir_entry, &mtkthermal_fops);
- if (!entry)
- THRML_ERROR_LOG("%s Can not create mtm_monitor\n", __func__);
- else
- proc_set_user(entry, uid, gid);
- entry = proc_create("mtm_indicator", S_IRUGO | S_IWUSR, dir_entry, &_mtkthermal_indicator_fops);
- if (!entry)
- THRML_ERROR_LOG("%s Can not create mtm_indicator\n", __func__);
- entry = proc_create("mtm_scen_call", S_IRUGO | S_IWUSR | S_IWGRP, dir_entry, &_mtm_scen_call_fops);
- if (!entry)
- THRML_ERROR_LOG("%s Can not create mtm_scen_call\n", __func__);
- else
- proc_set_user(entry, uid, gid);
- /* create /proc/cooler folder */
- /* WARNING! This is not gauranteed to be invoked before mtk_ts_cpu's functions... */
- proc_cooler_dir_entry =
- (NULL == proc_cooler_dir_entry) ? proc_mkdir("mtkcooler", NULL) : proc_cooler_dir_entry;
- if (NULL == proc_cooler_dir_entry)
- THRML_ERROR_LOG("%s mkdir /proc/mtkcooler failed\n", __func__);
- /* create /proc/tz folder */
- /* WARNING! This is not gauranteed to be invoked before mtk_ts_cpu's functions... */
- proc_tz_dir_entry =
- (NULL == proc_tz_dir_entry) ? proc_mkdir("mtktz", NULL) : proc_tz_dir_entry;
- if (NULL == proc_tz_dir_entry)
- THRML_ERROR_LOG("%s mkdir /proc/mtktz failed\n", __func__);
- #if defined(CONFIG_MTK_THERMAL_TIME_BASE_PROTECTION)
- wake_lock_init(&mtm_wake_lock, WAKE_LOCK_SUSPEND, "alarm");
- #endif
- #ifdef CONFIG_MTK_THERMAL_EXT_CONTROL
- g_controlState = MTK_THERMAL_CONTROL_STATE_POLLING;
- memset(&mtk_thermal_ext_tz_values, 0,
- sizeof(struct mtk_thermal_ext_tz_data) * MTK_THERMAL_EXT_SENSOR_COUNT);
- entry =
- proc_create("mtm_extctrl", S_IRUGO | S_IWUSR, dir_entry, &mtk_thermal_ext_proc_fops);
- if (!entry)
- THRML_ERROR_LOG("%s Can not create mtm_extctrl\n", __func__);
- /* Register AP side IPI handler */
- THRML_LOG("%s Register AP side IPI handler\n", __func__);
- md32_ipi_registration(IPI_THERMAL, mtk_thermal_ext_ipi_msg_handler, "Thermal");
- md32_register_notify(&mtk_thermal_ext_nb);
- #endif
- INIT_DELAYED_WORK(&_mtm_sysinfo_poll_queue, _mtm_update_sysinfo);
- _mtm_update_sysinfo(NULL);
- return err;
- }
- /* Exit */
- static void __exit mtkthermal_exit(void)
- {
- THRML_LOG("%s\n", __func__);
- #if defined(CONFIG_MTK_THERMAL_TIME_BASE_PROTECTION)
- wake_lock_destroy(&mtm_wake_lock);
- #endif
- #ifdef CONFIG_MTK_THERMAL_EXT_CONTROL
- mutex_destroy(&mtk_thermal_ext_control_lock);
- #endif
- }
- #if defined(CONFIG_MTK_THERMAL_TIME_BASE_PROTECTION)
- static int __init mtkthermal_late_init(void)
- {
- THRML_LOG("%s\n", __func__);
- return platform_driver_register(&mtk_thermal_monitor_driver);
- }
- #endif
- /* ************************************ */
- /* thermal_zone_device_ops Wrapper */
- /* ************************************ */
- /*
- * .bind wrapper: bind the thermal zone device with a thermal cooling device.
- */
- static int mtk_thermal_wrapper_bind(struct thermal_zone_device *thermal, struct thermal_cooling_device *cdev)
- {
- int ret = 0;
- struct thermal_zone_device_ops *ops;
- /* WARNING! bind will invoke mtk_thermal_zone_bind_cooling_device_wrapper(),
- so don't rollback cooler's devdata in this bind... */
- #if MTK_THERMAL_MONITOR_CONDITIONAL_COOLING
- {
- int i = 0;
- struct mtk_thermal_cooler_data *cldata = NULL;
- mutex_lock(&MTM_COOLER_LOCK);
- cldata = cdev->devdata;
- mutex_unlock(&MTM_COOLER_LOCK);
- for (; i < MTK_THERMAL_MONITOR_COOLER_MAX_EXTRA_CONDITIONS; i++) {
- if ((0x0 != cldata->conditions[i][0]) &&
- (NULL == cldata->condition_last_value[i])) {
- if (0 == strncmp(cldata->conditions[i], thermal->type, 20)) {
- cldata->condition_last_value[i] = &(thermal->temperature);
- THRML_LOG
- ("[.bind]condition+ tz: %s cdev: %s condition: %s\n",
- thermal->type, cdev->type, cldata->conditions[i]);
- }
- }
- }
- }
- #endif
- /* Bind Relationship to StoreLogger */
- THRML_LOG("[.bind]+ tz: %s cdev: %s tz_data:%p cl_data:%p\n", thermal->type, cdev->type,
- thermal->devdata, cdev->devdata);
- ops = getClientZoneOps(thermal);
- if (!ops) {
- THRML_ERROR_LOG("[.bind]E tz: %s unregistered.\n", thermal->type);
- return 1;
- }
- if (ops->bind)
- ops->bind(thermal, cdev);
- /* Bind Relationship to StoreLogger */
- THRML_LOG("[.bind]- tz: %s cdev: %s tz_data:%p cl_data:%p\n", thermal->type, cdev->type,
- thermal->devdata, cdev->devdata);
- /* Log in mtk_thermal_zone_bind_cooling_device_wrapper() */
- /* THRML_STORAGE_LOG(THRML_LOGGER_MSG_BIND, bind, thermal->type, cdev->type); */
- return ret;
- }
- /*
- *.unbind wrapper: unbind the thermal zone device with a thermal cooling device.
- */
- static int mtk_thermal_wrapper_unbind
- (struct thermal_zone_device *thermal, struct thermal_cooling_device *cdev) {
- int ret = 0;
- struct thermal_zone_device_ops *ops;
- #if MTK_THERMAL_MONITOR_CONDITIONAL_COOLING
- {
- int i = 0;
- struct mtk_thermal_cooler_data *cldata = NULL;
- mutex_lock(&MTM_COOLER_LOCK);
- cldata = cdev->devdata;
- mutex_unlock(&MTM_COOLER_LOCK);
- /* Clear cldata->tz */
- if (thermal == cldata->tz) {
- /* clear the state of cooler bounded first... */
- if (cdev->ops)
- cdev->ops->set_cur_state(cdev, 0);
- cldata->tz = NULL;
- cldata->trip = 0;
- }
- for (; i < MTK_THERMAL_MONITOR_COOLER_MAX_EXTRA_CONDITIONS; i++) {
- if ((NULL != cldata->condition_last_value[i]) &&
- (&(thermal->temperature) == cldata->condition_last_value[i])) {
- cldata->condition_last_value[i] = NULL;
- THRML_LOG("[.unbind]condition- tz: %s cdev: %s condition: %s\n",
- thermal->type, cdev->type, cldata->conditions[i]);
- }
- }
- }
- #endif
- THRML_LOG("[.unbind]+ tz: %s cdev: %s\n", thermal->type, cdev->type);
- ops = getClientZoneOps(thermal);
- if (!ops) {
- THRML_ERROR_LOG("[.unbind]E tz: %s unregistered.\n", thermal->type);
- return 1;
- }
- if (ops->unbind)
- ret = ops->unbind(thermal, cdev);
- THRML_LOG("[.unbind]- tz: %s cdev: %s\n", thermal->type, cdev->type);
- return ret;
- }
- /*
- * .get_temp wrapper: get the current temperature of the thermal zone.
- */
- static int mtk_thermal_wrapper_get_temp
- (struct thermal_zone_device *thermal, unsigned long *temperature) {
- int ret = 0;
- struct thermal_zone_device_ops *ops;
- int nTemperature;
- unsigned long raw_temp = 0;
- #if MTK_THERMAL_MONITOR_MEASURE_GET_TEMP_OVERHEAD
- long int t = _get_current_time_us();
- long int dur = 0;
- #endif
- ops = getClientZoneOps(thermal);
- if (!ops) {
- THRML_ERROR_LOG("[.get_temp] tz: %s unregistered.\n", thermal->type);
- return 1;
- }
- #ifndef CONFIG_MTK_THERMAL_EXT_CONTROL
- if (ops->get_temp)
- ret = ops->get_temp(thermal, &raw_temp);
- #else
- if (mtk_thermal_ext_get_temp(thermal, &raw_temp) < 0) {
- if (ops->get_temp)
- ret = ops->get_temp(thermal, &raw_temp);
- }
- #endif
- nTemperature = (int)raw_temp; /* /< Long cast to INT. */
- #if defined(CONFIG_MTK_THERMAL_TIME_BASE_PROTECTION)
- /* if batt temp raw data < 60C, release wake lock */
- if ((tz_last_values[MTK_THERMAL_SENSOR_BATTERY] != NULL) && /* batt TZ is registered */
- (&(thermal->temperature) == tz_last_values[MTK_THERMAL_SENSOR_BATTERY])) { /* get batt temp this time */
- if (wake_lock_active(&mtm_wake_lock)) {
- nTemperature = mtk_thermal_force_get_batt_temp() * 1000;
- raw_temp = nTemperature;
- THRML_ERROR_LOG("[.get_temp] tz: %s wake_lock_active() batt temp=%d\n",
- thermal->type, nTemperature);
- }
- if (nTemperature < 59000 && wake_lock_active(&mtm_wake_lock)) {
- /* unlock when only batt temp below 60C */
- THRML_ERROR_LOG("[.get_temp] tz: %s wake_unlock()\n", thermal->type);
- wake_unlock(&mtm_wake_lock);
- }
- last_batt_raw_temp = nTemperature;
- }
- #endif
- if (0 == ret) {
- *temperature = _mtkthermal_update_and_get_sma(thermal->devdata, raw_temp);
- /* No strong type cast... */
- } else {
- THRML_ERROR_LOG("[.get_temp] tz: %s invalid temp\n", thermal->type);
- *temperature = nTemperature;
- }
- /* Monitor Temperature to StoreLogger */
- THRML_STORAGE_LOG(THRML_LOGGER_MSG_ZONE_TEMP, get_temp, thermal->type, (int)*temperature);
- THRML_LOG("[.get_temp] tz: %s raw: %d sma: %ld\n", thermal->type, nTemperature,
- (long)*temperature);
- #if MTK_THERMAL_MONITOR_MEASURE_GET_TEMP_OVERHEAD
- dur = _get_current_time_us() - t;
- if (dur > 10000) /* over 10msec, log it */
- THRML_ERROR_LOG("[.get_temp] tz: %s dur: %ld\n", thermal->type, dur);
- #endif
- return ret;
- }
- /*
- * .get_mode wrapper: get the current mode (user/kernel) of the thermal zone.
- * - "kernel" means thermal management is done in kernel.
- * - "user" will prevent kernel thermal driver actions upon trip points
- */
- static int mtk_thermal_wrapper_get_mode
- (struct thermal_zone_device *thermal, enum thermal_device_mode *mode) {
- int ret = 0;
- struct thermal_zone_device_ops *ops;
- THRML_LOG("[.get_mode] tz: %s mode: %d\n", thermal->type, *mode);
- ops = getClientZoneOps(thermal);
- if (!ops) {
- THRML_ERROR_LOG("[.get_mode] tz: %s unregistered.\n", thermal->type);
- return 1;
- }
- if (ops->get_mode)
- ret = ops->get_mode(thermal, mode);
- return ret;
- }
- /*
- * .set_mode wrapper: set the mode (user/kernel) of the thermal zone.
- */
- static int mtk_thermal_wrapper_set_mode
- (struct thermal_zone_device *thermal, enum thermal_device_mode mode) {
- int ret = 0;
- struct thermal_zone_device_ops *ops;
- THRML_LOG("[.set_mode] tz: %s mode: %d\n", thermal->type, mode);
- ops = getClientZoneOps(thermal);
- if (!ops) {
- THRML_ERROR_LOG("[.set_mode] tz: %s unregistered.\n", thermal->type);
- return 1;
- }
- if (ops->set_mode)
- ret = ops->set_mode(thermal, mode);
- return ret;
- }
- /*
- * .get_trip_type wrapper: get the type of certain trip point.
- */
- static int mtk_thermal_wrapper_get_trip_type
- (struct thermal_zone_device *thermal, int trip, enum thermal_trip_type *type) {
- int ret = 0;
- struct thermal_zone_device_ops *ops;
- ops = getClientZoneOps(thermal);
- if (!ops) {
- THRML_ERROR_LOG("[.get_trip_type] tz: %s unregistered.\n", thermal->type);
- return 1;
- }
- if (ops->get_trip_type)
- ret = ops->get_trip_type(thermal, trip, type);
- THRML_LOG("[.get_trip_type] tz: %s trip: %d type: %d\n", thermal->type, trip, *type);
- return ret;
- }
- /*
- * .get_trip_temp wrapper: get the temperature above which the certain trip point
- * will be fired.
- */
- static int mtk_thermal_wrapper_get_trip_temp
- (struct thermal_zone_device *thermal, int trip, unsigned long *temperature) {
- int ret = 0;
- struct thermal_zone_device_ops *ops;
- ops = getClientZoneOps(thermal);
- if (!ops) {
- THRML_ERROR_LOG("[.get_trip_temp] tz: %s unregistered.\n", thermal->type);
- return 1;
- }
- if (ops->get_trip_temp)
- ret = ops->get_trip_temp(thermal, trip, temperature);
- THRML_LOG("[.get_trip_temp] tz: %s trip: %d temp: %ld\n", thermal->type, trip,
- (long)*temperature);
- THRML_STORAGE_LOG(THRML_LOGGER_MSG_TRIP_POINT, get_trip_temp, thermal->type, trip,
- *temperature);
- return ret;
- }
- /*
- * .get_crit_temp wrapper:
- */
- static int mtk_thermal_wrapper_get_crit_temp
- (struct thermal_zone_device *thermal, unsigned long *temperature) {
- int ret = 0;
- struct thermal_zone_device_ops *ops;
- ops = getClientZoneOps(thermal);
- if (!ops) {
- THRML_ERROR_LOG("[.get_crit_temp] tz: %s unregistered.\n", thermal->type);
- return 1;
- }
- if (ops->get_crit_temp)
- ret = ops->get_crit_temp(thermal, temperature);
- THRML_LOG("[.get_crit_temp] tz: %s temp: %ld\n", thermal->type, (long)*temperature);
- return ret;
- }
- static int mtk_thermal_wrapper_notify
- (struct thermal_zone_device *thermal, int trip, enum thermal_trip_type type) {
- int ret = 0;
- struct thermal_zone_device_ops *ops;
- ops = getClientZoneOps(thermal);
- if (!ops) {
- THRML_ERROR_LOG("[.notify] tz: %s unregistered.\n", thermal->type);
- return 1;
- }
- if (ops->notify)
- ret = ops->notify(thermal, trip, type);
- return ret;
- }
- /* *************************************** */
- /* MTK thermal zone register/unregister */
- /* *************************************** */
- /* Wrapper callback OPS */
- static struct thermal_zone_device_ops mtk_thermal_wrapper_dev_ops = {
- .bind = mtk_thermal_wrapper_bind,
- .unbind = mtk_thermal_wrapper_unbind,
- .get_temp = mtk_thermal_wrapper_get_temp,
- .get_mode = mtk_thermal_wrapper_get_mode,
- .set_mode = mtk_thermal_wrapper_set_mode,
- .get_trip_type = mtk_thermal_wrapper_get_trip_type,
- .get_trip_temp = mtk_thermal_wrapper_get_trip_temp,
- .get_crit_temp = mtk_thermal_wrapper_get_crit_temp,
- .notify = mtk_thermal_wrapper_notify,
- };
- /*mtk thermal zone register function */
- struct thermal_zone_device *mtk_thermal_zone_device_register_wrapper
- (char *type, int trips, void *devdata, const struct thermal_zone_device_ops *ops,
- int tc1, int tc2, int passive_delay, int polling_delay) {
- struct thermal_zone_device *tz = NULL;
- struct mtk_thermal_tz_data *tzdata = NULL;
- int tzidx;
- THRML_LOG("%s tz: %s trips: %d passive_delay: %d polling_delay: %d\n", __func__, type,
- trips, passive_delay, polling_delay);
- if (strcmp(SYSINFO_ATTACH_DEV_NAME, type) == 0)
- g_SysinfoAttachOps = (struct thermal_zone_device_ops *)ops;
- tzdata = kzalloc(sizeof(struct mtk_thermal_tz_data), GFP_KERNEL);
- if (!tzdata) {
- THRML_ERROR_LOG("%s tzdata kzalloc fail.\n", __func__);
- return ERR_PTR(-ENOMEM);
- }
- mutex_init(&tzdata->ma_lock);
- mutex_lock(&tzdata->ma_lock);
- tzdata->ops = (struct thermal_zone_device_ops *)ops;
- tzdata->ma_len = 1;
- tzdata->ma_counter = 0;
- tzdata->fake_temp = -275000; /* init to -275000 */
- #if (MAX_STEP_MA_LEN > 1)
- tzdata->curr_idx_ma_len = 0;
- tzdata->ma_lens[0] = 1;
- tzdata->msma_ht[0] = MSMA_MAX_HT;
- #endif
- mb();
- mutex_unlock(&tzdata->ma_lock);
- tz = thermal_zone_device_register(type, trips, /* /< total number of trip points */
- 0, /* /< mask */
- /* (void*)ops, ///< invoker's ops pass to devdata */
- (void *)tzdata, &mtk_thermal_wrapper_dev_ops, /* /< use wrapper ops. */
- NULL, /* /< tzp */
- passive_delay, polling_delay);
- tzidx = mtk_thermal_get_tz_idx(type);
- /* registered the last_temperature to local arra */
- mutex_lock(&MTM_GET_TEMP_LOCK);
- {
- if (tzidx >= 0 && tzidx < MTK_THERMAL_SENSOR_COUNT)
- tz_last_values[tzidx] = &(tz->temperature);
- }
- mutex_unlock(&MTM_GET_TEMP_LOCK);
- #ifdef CONFIG_MTK_THERMAL_EXT_CONTROL
- tzidx = mtk_thermal_ext_get_tz_idx(type);
- if (tzidx >= 0 && tzidx < MTK_THERMAL_EXT_SENSOR_COUNT) {
- mutex_lock(&mtk_thermal_ext_control_lock);
- mtk_thermal_ext_tz_values[tzidx].tz = tz;
- mtk_thermal_ext_tz_values[tzidx].tzdata = tzdata;
- mtk_thermal_ext_tz_values[tzidx].trips = trips;
- mtk_thermal_ext_tz_values[tzidx].last_temperature = *tz_last_values[tzidx];
- mtk_thermal_ext_tz_values[tzidx].polling_delay = polling_delay;
- if (mtk_thermal_ext_get_threshold(&mtk_thermal_ext_tz_values[tzidx], tz, ops, trips)
- < 0) {
- mtk_thermal_ext_tz_values[tzidx].high_trip_point =
- MTK_THERMAL_DEFAULT_MAX_TEMPERATURE;
- mtk_thermal_ext_tz_values[tzidx].low_trip_point =
- MTK_THERMAL_DEFAULT_MAX_TEMPERATURE;
- }
- mtk_thermal_ext_tz_values[tzidx].set = true;
- THRML_LOG
- ("%s %s, id: %d, temp: %d, polling delay: %d, low trip: %d, high trip: %d\n",
- __func__, type, tzidx, mtk_thermal_ext_tz_values[tzidx].last_temperature,
- mtk_thermal_ext_tz_values[tzidx].polling_delay,
- mtk_thermal_ext_tz_values[tzidx].low_trip_point,
- mtk_thermal_ext_tz_values[tzidx].high_trip_point);
- if (g_controlState == MTK_THERMAL_CONTROL_STATE_INTERRUPT ||
- g_controlState == MTK_THERMAL_CONTROL_STATE_SWITCHING) {
- /* Set TZ high/low threshold to MD32 */
- mtk_thermal_ext_set_tz_threshold(&mtk_thermal_ext_tz_values[tzidx], tzidx);
- /* [Warning] Can not use cancel_delayed_work_sync() here
- because it will cause kernel warning (LockProve Warning) */
- if (g_controlState == MTK_THERMAL_CONTROL_STATE_INTERRUPT &&
- cancel_delayed_work(&(tz->poll_queue)) == 0) {
- THRML_ERROR_LOG("%s cancel tz %d work, work is running\n", __func__,
- type);
- }
- }
- mutex_unlock(&mtk_thermal_ext_control_lock);
- }
- #endif /* CONFIG_MTK_THERMAL_EXT_CONTROL */
- /* create a proc for this tz... */
- if (NULL != _get_proc_tz_dir_entry()) {
- struct proc_dir_entry *entry;
- entry =
- proc_create_data((const char *)type, S_IRUGO | S_IWUSR | S_IWGRP,
- proc_tz_dir_entry, &_mtkthermal_tz_fops, tz);
- if (!entry) {
- THRML_ERROR_LOG("%s proc file not created: %p\n", __func__, tz);
- } else {
- proc_set_user(entry, uid, gid);
- THRML_LOG("%s proc file created: %p\n", __func__, tz);
- }
- }
- /* This interface function adds a new thermal zone device */
- return tz;
- }
- EXPORT_SYMBOL(mtk_thermal_zone_device_register_wrapper);
- /*mtk thermal zone unregister function */
- void mtk_thermal_zone_device_unregister_wrapper(struct thermal_zone_device *tz)
- {
- char type[32] = { 0 };
- struct mtk_thermal_tz_data *tzdata = NULL;
- int tzidx;
- strncpy(type, tz->type, 20);
- tzdata = (struct mtk_thermal_tz_data *)tz->devdata;
- /* delete the proc file entry from proc */
- if (NULL != proc_tz_dir_entry)
- remove_proc_entry((const char *)type, proc_tz_dir_entry);
- #ifdef CONFIG_MTK_THERMAL_EXT_CONTROL
- tzidx = mtk_thermal_ext_get_tz_idx(tz->type);
- mutex_lock(&mtk_thermal_ext_control_lock);
- if (tzidx >= 0 && tzidx < MTK_THERMAL_EXT_SENSOR_COUNT) {
- bool set = mtk_thermal_ext_tz_values[tzidx].set;
- /* Unset MD32 TZ high/low threshold and polling delay */
- memset(&mtk_thermal_ext_tz_values[tzidx], 0,
- sizeof(struct mtk_thermal_ext_tz_data));
- if (set)
- mtk_thermal_ext_set_tz_threshold(&mtk_thermal_ext_tz_values[tzidx], tzidx);
- }
- mutex_unlock(&mtk_thermal_ext_control_lock);
- #endif
- tzidx = mtk_thermal_get_tz_idx(tz->type);
- /* unregistered the last_temperature from local array */
- mutex_lock(&MTM_GET_TEMP_LOCK);
- {
- if (tzidx >= 0 && tzidx < MTK_THERMAL_SENSOR_COUNT)
- tz_last_values[tzidx] = NULL;
- }
- mutex_unlock(&MTM_GET_TEMP_LOCK);
- THRML_LOG("%s+ tz : %s\n", __func__, type);
- thermal_zone_device_unregister(tz);
- THRML_LOG("%s- tz: %s\n", __func__, type);
- /* free memory */
- if (NULL != tzdata) {
- mutex_lock(&tzdata->ma_lock);
- tzdata->ops = NULL;
- mutex_unlock(&tzdata->ma_lock);
- mutex_destroy(&tzdata->ma_lock);
- kfree(tzdata);
- }
- }
- EXPORT_SYMBOL(mtk_thermal_zone_device_unregister_wrapper);
- int mtk_thermal_zone_bind_cooling_device_wrapper(struct thermal_zone_device *thermal,
- int trip, struct thermal_cooling_device *cdev) {
- struct mtk_thermal_cooler_data *mcdata;
- int ret = 0;
- THRML_LOG("%s thermal_type:%s trip:%d cdev_type:%s ret:%d\n", __func__,
- thermal->type, trip, cdev->type, ret);
- ret =
- thermal_zone_bind_cooling_device(thermal, trip, cdev, THERMAL_NO_LIMIT,
- THERMAL_NO_LIMIT);
- if (ret) {
- THRML_ERROR_LOG("thermal_zone_bind_cooling_device Fail. Code(%d)\n", ret);
- } else {
- /* TODO: think of a way don't do this here...Or cannot rollback devdata in bind ops... */
- /* Init mtk Cooler Data */
- mcdata = cdev->devdata;
- mcdata->trip = trip;
- mcdata->tz = thermal;
- }
- THRML_LOG("%s thermal_type:%s trip:%d cdev_type:%s ret:%d\n", __func__,
- thermal->type, trip, cdev->type, ret);
- THRML_STORAGE_LOG(THRML_LOGGER_MSG_BIND, bind, thermal->type, trip, cdev->type);
- return ret;
- }
- EXPORT_SYMBOL(mtk_thermal_zone_bind_cooling_device_wrapper);
- /* ********************************************* */
- /* MTK cooling dev register/unregister */
- /* ********************************************* */
- /* .get_max_state */
- static int mtk_cooling_wrapper_get_max_state
- (struct thermal_cooling_device *cdev, unsigned long *state) {
- int ret = 0;
- struct thermal_cooling_device_ops *ops;
- struct mtk_thermal_cooler_data *mcdata;
- mutex_lock(&MTM_COOLER_LOCK);
- /* Recovery client's devdata */
- ops = recoveryClientCooler(cdev, &mcdata);
- if (ops->get_max_state)
- ret = ops->get_max_state(cdev, state);
- THRML_LOG("[.get_max_state] cdev_type:%s state:%lu\n", cdev->type, *state);
- cdev->devdata = mcdata;
- mutex_unlock(&MTM_COOLER_LOCK);
- return ret;
- }
- /* .get_cur_state */
- static int mtk_cooling_wrapper_get_cur_state
- (struct thermal_cooling_device *cdev, unsigned long *state) {
- int ret = 0;
- struct thermal_cooling_device_ops *ops;
- struct mtk_thermal_cooler_data *mcdata;
- mutex_lock(&MTM_COOLER_LOCK);
- /* Recovery client's devdata */
- ops = recoveryClientCooler(cdev, &mcdata);
- if (ops->get_cur_state)
- ret = ops->get_cur_state(cdev, state);
- THRML_LOG("[.get_cur_state] cdev_type:%s state:%lu\n", cdev->type, *state);
- /* reset devdata to mcdata */
- cdev->devdata = mcdata;
- mutex_unlock(&MTM_COOLER_LOCK);
- return ret;
- }
- /* set_cur_state */
- static int mtk_cooling_wrapper_set_cur_state
- (struct thermal_cooling_device *cdev, unsigned long state) {
- struct thermal_cooling_device_ops *ops;
- struct mtk_thermal_cooler_data *mcdata;
- int ret = 0;
- unsigned long cur_state = 0;
- mutex_lock(&MTM_COOLER_LOCK);
- /* Recovery client's devdata */
- ops = recoveryClientCooler(cdev, &mcdata);
- if (ops == NULL) {
- THRML_ERROR_LOG("[.set_cur_state]E no cdev ops.\n");
- mutex_unlock(&MTM_COOLER_LOCK);
- return -1;
- }
- if (ops->get_cur_state)
- ret = ops->get_cur_state(cdev, &cur_state);
- /* check conditions */
- #if MTK_THERMAL_MONITOR_CONDITIONAL_COOLING
- if (0 != state) {
- /* here check conditions for setting the cooler... */
- if (MTK_THERMAL_MONITOR_COOLER_MAX_EXTRA_CONDITIONS ==
- _mtkthermal_check_cooler_conditions(mcdata)) {
- /* pass */
- } else {
- THRML_LOG
- ("[.set_cur_state]condition check failed tz_type:%s cdev_type:%s trip:%d state:%lu\n",
- mcdata->tz->type, cdev->type, mcdata->trip, state);
- state = 0;
- }
- }
- if (0 == state) {
- int last_temp = 0;
- unsigned long trip_temp = 0;
- struct thermal_zone_device_ops *tz_ops;
- if ((0 < mcdata->exit_threshold) && (mcdata->tz != NULL)) {
- /* if exit point is set and if this cooler is still bound... */
- THRML_LOG("[.set_cur_state] cur_state:%lu\n", cur_state);
- if (0 < cur_state) {
- THRML_LOG("[.set_cur_state] tz:%p devdata:%p\n", mcdata->tz,
- mcdata->tz->devdata);
- if (mcdata->tz)
- last_temp = mcdata->tz->temperature;
- THRML_LOG("[.set_cur_state] last_temp:%d\n", last_temp);
- tz_ops = getClientZoneOps(mcdata->tz);
- if (!ops) {
- THRML_ERROR_LOG("[.set_cur_state]E tz unregistered.\n");
- /* BUG(); */
- trip_temp = 120000;
- } else {
- if (tz_ops->get_trip_temp) {
- tz_ops->get_trip_temp(mcdata->tz, mcdata->trip, &trip_temp);
- THRML_LOG("[.set_cur_state] trip_temp:%ld\n", (long)trip_temp);
- } else {
- BUG();
- }
- }
- if ((last_temp >= (int)trip_temp)
- || (((int)trip_temp - last_temp) < mcdata->exit_threshold)) {
- THRML_LOG
- ("[.set_cur_state]not exit yet tz_type:%s cdev_type:%s trip:%d state:%lu\n",
- mcdata->tz->type, cdev->type, mcdata->trip, state);
- state = cur_state;
- }
- }
- }
- }
- #endif
- THRML_LOG("[.set_cur_state] tz_type:%s cdev_type:%s trip:%d state:%lu\n", mcdata->tz->type,
- cdev->type, mcdata->trip, state);
- THRML_STORAGE_LOG(THRML_LOGGER_MSG_COOL_STAE, set_cur_state, mcdata->tz->type, mcdata->trip,
- cdev->type, state);
- if (ops->set_cur_state)
- ret = ops->set_cur_state(cdev, state);
- /* reset devdata to mcdata */
- cdev->devdata = mcdata;
- mutex_unlock(&MTM_COOLER_LOCK);
- return ret;
- }
- /* Cooling callbacks OPS */
- static struct thermal_cooling_device_ops mtk_cooling_wrapper_dev_ops = {
- .get_max_state = mtk_cooling_wrapper_get_max_state,
- .get_cur_state = mtk_cooling_wrapper_get_cur_state,
- .set_cur_state = mtk_cooling_wrapper_set_cur_state,
- };
- /*
- * MTK Cooling Register
- */
- struct thermal_cooling_device *mtk_thermal_cooling_device_register_wrapper
- (char *type, void *devdata, const struct thermal_cooling_device_ops *ops) {
- struct mtk_thermal_cooler_data *mcdata = NULL;
- struct thermal_cooling_device *ret = NULL;
- int i = 0;
- THRML_LOG("%s type:%s\n", __func__, type);
- mcdata = kzalloc(sizeof(struct mtk_thermal_cooler_data), GFP_KERNEL);
- if (!mcdata) {
- THRML_ERROR_LOG("%s mcdata kzalloc fail.\n", __func__);
- return ERR_PTR(-ENOMEM);
- }
- mcdata->ops = (struct thermal_cooling_device_ops *)ops;
- mcdata->devdata = devdata;
- mcdata->exit_threshold = 0;
- for (; i < MTK_THERMAL_MONITOR_COOLER_MAX_EXTRA_CONDITIONS; i++) {
- mcdata->conditions[i][0] = 0x0;
- mcdata->condition_last_value[i] = NULL;
- mcdata->threshold[i] = 0;
- }
- mb();
- /* create a proc for this cooler... */
- if (NULL != _get_proc_cooler_dir_entry()) {
- struct proc_dir_entry *entry;
- entry =
- proc_create_data((const char *)type, S_IRUGO | S_IWUSR | S_IWGRP,
- proc_cooler_dir_entry, &_mtkthermal_cooler_fops, mcdata);
- if (!entry) {
- THRML_ERROR_LOG("%s proc file not created: %p\n", __func__, mcdata);
- } else {
- proc_set_user(entry, uid, gid);
- THRML_LOG("%s proc file created: %p\n", __func__, mcdata);
- }
- }
- ret = thermal_cooling_device_register(type, mcdata, &mtk_cooling_wrapper_dev_ops);
- mcdata->id = ret->id; /* Used for CPU usage flag... */
- return ret;
- }
- EXPORT_SYMBOL(mtk_thermal_cooling_device_register_wrapper);
- /*
- * MTK Cooling Unregister
- */
- void mtk_thermal_cooling_device_unregister_wrapper(struct thermal_cooling_device *cdev)
- {
- struct mtk_thermal_cooler_data *mcdata;
- char type[32] = { 0 };
- strncpy(type, cdev->type, 20);
- THRML_LOG("%s+ cdev:%p devdata:%p cdev:%s\n", __func__, cdev, cdev->devdata, type);
- /* delete the proc file entry from proc */
- if (NULL != proc_cooler_dir_entry)
- remove_proc_entry((const char *)type, proc_cooler_dir_entry);
- /* TODO: consider error handling... */
- mutex_lock(&MTM_COOLER_LOCK);
- /* free mtk cooler data */
- mcdata = cdev->devdata;
- mutex_unlock(&MTM_COOLER_LOCK);
- THRML_LOG("%s- mcdata:%p\n", __func__, mcdata);
- thermal_cooling_device_unregister(cdev);
- /* free mtk cooler data */
- kfree(mcdata);
- THRML_LOG("%s- cdev: %s\n", __func__, type);
- }
- EXPORT_SYMBOL(mtk_thermal_cooling_device_unregister_wrapper);
- int mtk_thermal_zone_bind_trigger_trip(struct thermal_zone_device *tz, int trip, int mode)
- {
- THRML_LOG("%s trip %d\n", __func__, trip);
- schedule_delayed_work(&(tz->poll_queue), 0);
- return 0;
- }
- EXPORT_SYMBOL(mtk_thermal_zone_bind_trigger_trip);
- int mtk_thermal_get_temp(MTK_THERMAL_SENSOR_ID id)
- {
- int ret = 0;
- if (id < 0 || id >= MTK_THERMAL_SENSOR_COUNT)
- return -127000;
- mutex_lock(&MTM_GET_TEMP_LOCK);
- if (tz_last_values[id] == NULL) {
- mutex_unlock(&MTM_GET_TEMP_LOCK);
- return -127000;
- }
- ret = *tz_last_values[id];
- mutex_unlock(&MTM_GET_TEMP_LOCK);
- return ret;
- }
- EXPORT_SYMBOL(mtk_thermal_get_temp);
- struct proc_dir_entry *mtk_thermal_get_proc_drv_therm_dir_entry(void)
- {
- mutex_lock(&MTM_DRV_THERM_PROC_DIR_LOCK);
- if (NULL == proc_drv_therm_dir_entry) {
- proc_drv_therm_dir_entry = proc_mkdir("driver/thermal", NULL);
- if (NULL == proc_drv_therm_dir_entry)
- THRML_ERROR_LOG("[%s]: mkdir /proc/driver/thermal failed\n", __func__);
- }
- mutex_unlock(&MTM_DRV_THERM_PROC_DIR_LOCK);
- return proc_drv_therm_dir_entry;
- }
- EXPORT_SYMBOL(mtk_thermal_get_proc_drv_therm_dir_entry);
- module_init(mtkthermal_init);
- module_exit(mtkthermal_exit);
- #if defined(CONFIG_MTK_THERMAL_TIME_BASE_PROTECTION)
- late_initcall(mtkthermal_late_init);
- #endif
|