thermal: Import Xiaomi changes
From branch: redwood-s-oss mi_thermal_interface From branch: zijin-s-oss Change-Id: Ia224f2ac382abb409dd03e881779c51e478fa582
This commit is contained in:
parent
8fa6995f56
commit
0312ee81ad
@ -446,4 +446,12 @@ config SPRD_THERMAL
|
|||||||
help
|
help
|
||||||
Support for the Spreadtrum thermal sensor driver in the Linux thermal
|
Support for the Spreadtrum thermal sensor driver in the Linux thermal
|
||||||
framework.
|
framework.
|
||||||
|
|
||||||
|
config MI_THERMAL_INTERFACE
|
||||||
|
tristate "xiaomi thermal control interface"
|
||||||
|
depends on THERMAL && QGKI
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
This is xiaomi thermal control interface.
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
@ -60,3 +60,4 @@ obj-$(CONFIG_UNIPHIER_THERMAL) += uniphier_thermal.o
|
|||||||
obj-$(CONFIG_THERMAL_TSENS) += msm-tsens-driver.o
|
obj-$(CONFIG_THERMAL_TSENS) += msm-tsens-driver.o
|
||||||
msm-tsens-driver-objs := msm-tsens.o tsens2xxx.o tsens-dbg.o tsens-mtc.o tsens1xxx.o tsens-calib.o
|
msm-tsens-driver-objs := msm-tsens.o tsens2xxx.o tsens-dbg.o tsens-mtc.o tsens1xxx.o tsens-calib.o
|
||||||
obj-$(CONFIG_SPRD_THERMAL) += sprd_thermal.o
|
obj-$(CONFIG_SPRD_THERMAL) += sprd_thermal.o
|
||||||
|
obj-$(CONFIG_MI_THERMAL_INTERFACE) += mi_thermal_interface.o
|
||||||
|
@ -89,12 +89,40 @@ struct cpufreq_cooling_device {
|
|||||||
struct list_head node;
|
struct list_head node;
|
||||||
struct time_in_idle *idle_time;
|
struct time_in_idle *idle_time;
|
||||||
struct freq_qos_request qos_req;
|
struct freq_qos_request qos_req;
|
||||||
|
struct thermal_cooling_device *cdev;
|
||||||
};
|
};
|
||||||
|
|
||||||
static DEFINE_IDA(cpufreq_ida);
|
static DEFINE_IDA(cpufreq_ida);
|
||||||
static DEFINE_MUTEX(cooling_list_lock);
|
static DEFINE_MUTEX(cooling_list_lock);
|
||||||
static LIST_HEAD(cpufreq_cdev_list);
|
static LIST_HEAD(cpufreq_cdev_list);
|
||||||
|
|
||||||
|
|
||||||
|
void cpu_limits_set_level(unsigned int cpu, unsigned int max_freq)
|
||||||
|
{
|
||||||
|
struct cpufreq_cooling_device *cpufreq_cdev;
|
||||||
|
struct thermal_cooling_device *cdev;
|
||||||
|
unsigned int cdev_cpu;
|
||||||
|
unsigned int level;
|
||||||
|
|
||||||
|
list_for_each_entry(cpufreq_cdev, &cpufreq_cdev_list, node) {
|
||||||
|
sscanf(cpufreq_cdev->cdev->type, "thermal-cpufreq-%d", &cdev_cpu);
|
||||||
|
if (cdev_cpu == cpu) {
|
||||||
|
for (level = 0; level <= cpufreq_cdev->max_level; level++) {
|
||||||
|
int target_freq = cpufreq_cdev->freq_table[level].frequency;
|
||||||
|
if (max_freq >= target_freq) {
|
||||||
|
cdev = cpufreq_cdev->cdev;
|
||||||
|
if (cdev)
|
||||||
|
cdev->ops->set_cur_state(cdev, level);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Below code defines functions to be used for cpufreq as cooling device */
|
/* Below code defines functions to be used for cpufreq as cooling device */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -633,6 +661,8 @@ __cpufreq_cooling_register(struct device_node *np,
|
|||||||
if (IS_ERR(cdev))
|
if (IS_ERR(cdev))
|
||||||
goto remove_qos_req;
|
goto remove_qos_req;
|
||||||
|
|
||||||
|
cpufreq_cdev->cdev = cdev;
|
||||||
|
|
||||||
mutex_lock(&cooling_list_lock);
|
mutex_lock(&cooling_list_lock);
|
||||||
list_add(&cpufreq_cdev->node, &cpufreq_cdev_list);
|
list_add(&cpufreq_cdev->node, &cpufreq_cdev_list);
|
||||||
mutex_unlock(&cooling_list_lock);
|
mutex_unlock(&cooling_list_lock);
|
||||||
|
190
drivers/thermal/mi_thermal_interface.c
Normal file
190
drivers/thermal/mi_thermal_interface.c
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
#include <linux/cpu_cooling.h>
|
||||||
|
#include <linux/cpufreq.h>
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/idr.h>
|
||||||
|
#include <linux/kdev_t.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/pm_qos.h>
|
||||||
|
#include <linux/reboot.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <linux/suspend.h>
|
||||||
|
#include <linux/thermal.h>
|
||||||
|
#include <drm/mi_disp_notifier.h>
|
||||||
|
#include <net/netlink.h>
|
||||||
|
#include <net/genetlink.h>
|
||||||
|
#include <linux/power_supply.h>
|
||||||
|
|
||||||
|
#include "thermal_core.h"
|
||||||
|
|
||||||
|
struct mi_thermal_device {
|
||||||
|
struct device *dev;
|
||||||
|
struct class *class;
|
||||||
|
struct attribute_group attrs;
|
||||||
|
struct notifier_block psy_nb;
|
||||||
|
int usb_online;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct mi_thermal_device mi_thermal_dev;
|
||||||
|
|
||||||
|
struct screen_monitor {
|
||||||
|
struct notifier_block thermal_notifier;
|
||||||
|
int screen_state;
|
||||||
|
};
|
||||||
|
struct screen_monitor sm;
|
||||||
|
|
||||||
|
static ssize_t thermal_screen_state_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
return snprintf(buf, PAGE_SIZE, "%d\n", sm.screen_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(screen_state, 0664,
|
||||||
|
thermal_screen_state_show, NULL);
|
||||||
|
|
||||||
|
static ssize_t thermal_usb_online_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
return snprintf(buf, PAGE_SIZE, "%d\n", mi_thermal_dev.usb_online);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(usb_online, 0664,
|
||||||
|
thermal_usb_online_show, NULL);
|
||||||
|
|
||||||
|
static struct attribute *mi_thermal_dev_attr_group[] = {
|
||||||
|
&dev_attr_screen_state.attr,
|
||||||
|
&dev_attr_usb_online.attr,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *get_screen_state_name(int mode)
|
||||||
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case MI_DISP_DPMS_ON:
|
||||||
|
return "On";
|
||||||
|
case MI_DISP_DPMS_LP1:
|
||||||
|
return "Doze";
|
||||||
|
case MI_DISP_DPMS_LP2:
|
||||||
|
return "DozeSuspend";
|
||||||
|
case MI_DISP_DPMS_POWERDOWN:
|
||||||
|
return "Off";
|
||||||
|
default:
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int screen_state_for_thermal_callback(struct notifier_block *nb,
|
||||||
|
unsigned long val, void *data)
|
||||||
|
{
|
||||||
|
struct mi_disp_notifier *evdata = data;
|
||||||
|
unsigned int blank;
|
||||||
|
|
||||||
|
if (val != MI_DISP_DPMS_EVENT || !evdata || !evdata->data)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
blank = *(int *)(evdata->data);
|
||||||
|
switch (blank) {
|
||||||
|
case MI_DISP_DPMS_ON:
|
||||||
|
sm.screen_state = 1;
|
||||||
|
break;
|
||||||
|
case MI_DISP_DPMS_LP1:
|
||||||
|
case MI_DISP_DPMS_LP2:
|
||||||
|
case MI_DISP_DPMS_POWERDOWN:
|
||||||
|
sm.screen_state = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pr_warn("%s: %s, sm.screen_state = %d\n", __func__, get_screen_state_name(blank),
|
||||||
|
sm.screen_state);
|
||||||
|
sysfs_notify(&mi_thermal_dev.dev->kobj, NULL, "screen_state");
|
||||||
|
|
||||||
|
return NOTIFY_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int usb_online_callback(struct notifier_block *nb,
|
||||||
|
unsigned long val, void *data)
|
||||||
|
{
|
||||||
|
static struct power_supply *usb_psy;
|
||||||
|
struct power_supply *psy = data;
|
||||||
|
union power_supply_propval ret = {0,};
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (strcmp(psy->desc->name, "usb"))
|
||||||
|
return NOTIFY_OK;
|
||||||
|
|
||||||
|
if (!usb_psy)
|
||||||
|
usb_psy = power_supply_get_by_name("usb");
|
||||||
|
if (usb_psy) {
|
||||||
|
err = power_supply_get_property(usb_psy,
|
||||||
|
POWER_SUPPLY_PROP_ONLINE, &ret);
|
||||||
|
if (err) {
|
||||||
|
pr_err("usb online read error:%d\n",err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
mi_thermal_dev.usb_online = ret.intval;
|
||||||
|
sysfs_notify(&mi_thermal_dev.dev->kobj, NULL, "usb_online");
|
||||||
|
}
|
||||||
|
|
||||||
|
return NOTIFY_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int create_thermal_message_node(void)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
mi_thermal_dev.class = &thermal_class;
|
||||||
|
mi_thermal_dev.dev = &thermal_message_dev;
|
||||||
|
mi_thermal_dev.attrs.attrs = mi_thermal_dev_attr_group;
|
||||||
|
ret = sysfs_create_group(&mi_thermal_dev.dev->kobj, &mi_thermal_dev.attrs);
|
||||||
|
if (ret) {
|
||||||
|
pr_err("%s ERROR: Cannot create sysfs structure!:%d\n", __func__, ret);
|
||||||
|
ret = -ENODEV;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void destroy_thermal_message_node(void)
|
||||||
|
{
|
||||||
|
sysfs_remove_group(&mi_thermal_dev.dev->kobj, &mi_thermal_dev.attrs);
|
||||||
|
mi_thermal_dev.class = NULL;
|
||||||
|
mi_thermal_dev.dev = NULL;
|
||||||
|
mi_thermal_dev.attrs.attrs = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init mi_thermal_interface_init(void)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
if (create_thermal_message_node()){
|
||||||
|
pr_warn("Thermal: create screen state failed\n");
|
||||||
|
}
|
||||||
|
sm.thermal_notifier.notifier_call = screen_state_for_thermal_callback;
|
||||||
|
if (mi_disp_register_client(&sm.thermal_notifier) < 0) {
|
||||||
|
pr_warn("Thermal: register screen state callback failed\n");
|
||||||
|
}
|
||||||
|
mi_thermal_dev.psy_nb.notifier_call = usb_online_callback;
|
||||||
|
ret = power_supply_reg_notifier(&mi_thermal_dev.psy_nb);
|
||||||
|
if (ret < 0) {
|
||||||
|
pr_err("usb online notifier registration error. defer. err:%d\n",
|
||||||
|
ret);
|
||||||
|
ret = -EPROBE_DEFER;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit mi_thermal_interface_exit(void)
|
||||||
|
{
|
||||||
|
mi_disp_unregister_client(&sm.thermal_notifier);
|
||||||
|
destroy_thermal_message_node();
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(mi_thermal_interface_init);
|
||||||
|
module_exit(mi_thermal_interface_exit);
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Fankl");
|
||||||
|
MODULE_DESCRIPTION("Xiaomi thermal control interface");
|
||||||
|
MODULE_LICENSE("GPL v2");
|
||||||
|
|
@ -26,7 +26,10 @@
|
|||||||
|
|
||||||
#define BCL_DRIVER_NAME "bcl_pmic5"
|
#define BCL_DRIVER_NAME "bcl_pmic5"
|
||||||
#define BCL_MONITOR_EN 0x46
|
#define BCL_MONITOR_EN 0x46
|
||||||
|
#define BCL_MONITOR_EN_TEMP 0xDA
|
||||||
#define BCL_IRQ_STATUS 0x08
|
#define BCL_IRQ_STATUS 0x08
|
||||||
|
#define BCL_IADC_BF_DGL_CTL 0x59
|
||||||
|
#define BCL_IADC_BF_DGL_16MS 0x0E
|
||||||
|
|
||||||
#define BCL_IBAT_HIGH 0x4B
|
#define BCL_IBAT_HIGH 0x4B
|
||||||
#define BCL_IBAT_TOO_HIGH 0x4C
|
#define BCL_IBAT_TOO_HIGH 0x4C
|
||||||
@ -141,10 +144,6 @@ static int bcl_read_register(struct bcl_device *bcl_perph, int16_t reg_offset,
|
|||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (!bcl_perph) {
|
|
||||||
pr_err("BCL device not initialized\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
ret = regmap_read(bcl_perph->regmap,
|
ret = regmap_read(bcl_perph->regmap,
|
||||||
(bcl_perph->fg_bcl_addr + reg_offset),
|
(bcl_perph->fg_bcl_addr + reg_offset),
|
||||||
data);
|
data);
|
||||||
@ -752,9 +751,23 @@ static void bcl_probe_lvls(struct platform_device *pdev,
|
|||||||
bcl_lvl_init(pdev, BCL_LVL2, BCL_IRQ_L2, bcl_perph);
|
bcl_lvl_init(pdev, BCL_LVL2, BCL_IRQ_L2, bcl_perph);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void bcl_iadc_bf_degl_set(struct bcl_device *bcl_perph, int time)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int data = 0;
|
||||||
|
ret = bcl_read_register(bcl_perph, BCL_IADC_BF_DGL_CTL, &data);
|
||||||
|
if (ret)
|
||||||
|
return;
|
||||||
|
data = (data & 0xF0) | time;
|
||||||
|
ret = bcl_write_register(bcl_perph, BCL_IADC_BF_DGL_CTL, data);
|
||||||
|
if (ret)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static void bcl_configure_bcl_peripheral(struct bcl_device *bcl_perph)
|
static void bcl_configure_bcl_peripheral(struct bcl_device *bcl_perph)
|
||||||
{
|
{
|
||||||
bcl_write_register(bcl_perph, BCL_MONITOR_EN, BIT(7));
|
bcl_write_register(bcl_perph, BCL_MONITOR_EN, BIT(7));
|
||||||
|
bcl_iadc_bf_degl_set(bcl_perph, BCL_IADC_BF_DGL_16MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bcl_remove(struct platform_device *pdev)
|
static int bcl_remove(struct platform_device *pdev)
|
||||||
@ -822,6 +835,37 @@ static int bcl_probe(struct platform_device *pdev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void bcl_shutdown(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int data = 0;
|
||||||
|
struct bcl_device *bcl_perph =
|
||||||
|
(struct bcl_device *)dev_get_drvdata(&pdev->dev);
|
||||||
|
|
||||||
|
ret = bcl_read_register(bcl_perph, BCL_MONITOR_EN, &data);
|
||||||
|
printk(KERN_ERR "befor set data is %d", data);
|
||||||
|
if (ret)
|
||||||
|
return;
|
||||||
|
data = (data & 0x7F);
|
||||||
|
ret = bcl_write_register(bcl_perph, BCL_MONITOR_EN, data);
|
||||||
|
|
||||||
|
printk(KERN_ERR "after set data is %d", data);
|
||||||
|
if (ret)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ret = bcl_read_register(bcl_perph, BCL_MONITOR_EN_TEMP, &data);
|
||||||
|
printk(KERN_ERR "befor set temp_data is %d", data);
|
||||||
|
if (ret)
|
||||||
|
return;
|
||||||
|
data = (data & 0x00);
|
||||||
|
data = (data | 0x05);
|
||||||
|
ret = bcl_write_register(bcl_perph, BCL_MONITOR_EN_TEMP, data);
|
||||||
|
|
||||||
|
printk(KERN_ERR "after set temp_data is %d", data);
|
||||||
|
if (ret)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct of_device_id bcl_match[] = {
|
static const struct of_device_id bcl_match[] = {
|
||||||
{
|
{
|
||||||
.compatible = "qcom,bcl-v5",
|
.compatible = "qcom,bcl-v5",
|
||||||
@ -832,6 +876,7 @@ static const struct of_device_id bcl_match[] = {
|
|||||||
static struct platform_driver bcl_driver = {
|
static struct platform_driver bcl_driver = {
|
||||||
.probe = bcl_probe,
|
.probe = bcl_probe,
|
||||||
.remove = bcl_remove,
|
.remove = bcl_remove,
|
||||||
|
.shutdown = bcl_shutdown,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = BCL_DRIVER_NAME,
|
.name = BCL_DRIVER_NAME,
|
||||||
.of_match_table = bcl_match,
|
.of_match_table = bcl_match,
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
#include <net/netlink.h>
|
#include <net/netlink.h>
|
||||||
#include <net/genetlink.h>
|
#include <net/genetlink.h>
|
||||||
#include <linux/suspend.h>
|
#include <linux/suspend.h>
|
||||||
|
#include <linux/cpu_cooling.h>
|
||||||
|
#include <drm/mi_disp_notifier.h>
|
||||||
|
|
||||||
#define CREATE_TRACE_POINTS
|
#define CREATE_TRACE_POINTS
|
||||||
#include <trace/events/thermal.h>
|
#include <trace/events/thermal.h>
|
||||||
@ -34,6 +36,8 @@ MODULE_AUTHOR("Zhang Rui");
|
|||||||
MODULE_DESCRIPTION("Generic thermal management sysfs support");
|
MODULE_DESCRIPTION("Generic thermal management sysfs support");
|
||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL v2");
|
||||||
|
|
||||||
|
#define CPU_LIMITS_PARAM_NUM 2
|
||||||
|
|
||||||
static DEFINE_IDA(thermal_tz_ida);
|
static DEFINE_IDA(thermal_tz_ida);
|
||||||
static DEFINE_IDA(thermal_cdev_ida);
|
static DEFINE_IDA(thermal_cdev_ida);
|
||||||
|
|
||||||
@ -50,6 +54,24 @@ static bool power_off_triggered;
|
|||||||
|
|
||||||
static struct thermal_governor *def_governor;
|
static struct thermal_governor *def_governor;
|
||||||
|
|
||||||
|
#ifdef CONFIG_QTI_THERMAL
|
||||||
|
struct device thermal_message_dev;
|
||||||
|
EXPORT_SYMBOL_GPL(thermal_message_dev);
|
||||||
|
static atomic_t switch_mode = ATOMIC_INIT(-1);
|
||||||
|
static atomic_t balance_mode = ATOMIC_INIT(0);
|
||||||
|
static atomic_t temp_state = ATOMIC_INIT(0);
|
||||||
|
static atomic_t charger_mode = ATOMIC_INIT(-1);
|
||||||
|
static atomic_t modem_limit = ATOMIC_INIT(0);
|
||||||
|
static atomic_t market_download_limit = ATOMIC_INIT(0);
|
||||||
|
static atomic_t flash_state = ATOMIC_INIT(0);
|
||||||
|
static atomic_t wifi_limit = ATOMIC_INIT(0);
|
||||||
|
static atomic_t poor_modem_limit = ATOMIC_INIT(0);
|
||||||
|
static char boost_buf[128];
|
||||||
|
const char *board_sensor;
|
||||||
|
static char board_sensor_temp[128];
|
||||||
|
static char board_sensor_second_temp[128];
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Governor section: set of functions to handle thermal governors
|
* Governor section: set of functions to handle thermal governors
|
||||||
*
|
*
|
||||||
@ -1001,10 +1023,11 @@ static void thermal_release(struct device *dev)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct class thermal_class = {
|
struct class thermal_class = {
|
||||||
.name = "thermal",
|
.name = "thermal",
|
||||||
.dev_release = thermal_release,
|
.dev_release = thermal_release,
|
||||||
};
|
};
|
||||||
|
EXPORT_SYMBOL_GPL(thermal_class);
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
void print_bind_err_msg(struct thermal_zone_device *tz,
|
void print_bind_err_msg(struct thermal_zone_device *tz,
|
||||||
@ -1771,6 +1794,395 @@ static struct notifier_block thermal_pm_nb = {
|
|||||||
.notifier_call = thermal_pm_notify,
|
.notifier_call = thermal_pm_notify,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_QTI_THERMAL
|
||||||
|
static int of_parse_thermal_message(void)
|
||||||
|
{
|
||||||
|
struct device_node *np;
|
||||||
|
|
||||||
|
np = of_find_node_by_name(NULL, "thermal-message");
|
||||||
|
if (!np)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (of_property_read_string(np, "board-sensor", &board_sensor))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
pr_info("%s board sensor: %s\n", __func__, board_sensor);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
thermal_sconfig_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&switch_mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
thermal_sconfig_store(struct device *dev,
|
||||||
|
struct device_attribute *attr, const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
int val = -1;
|
||||||
|
|
||||||
|
val = simple_strtol(buf, NULL, 10);
|
||||||
|
|
||||||
|
atomic_set(&switch_mode, val);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(sconfig, 0664,
|
||||||
|
thermal_sconfig_show, thermal_sconfig_store);
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
thermal_charger_temp_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&charger_mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
thermal_charger_temp_store(struct device *dev,
|
||||||
|
struct device_attribute *attr, const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
int val = -1;
|
||||||
|
|
||||||
|
val = simple_strtol(buf, NULL, 10);
|
||||||
|
|
||||||
|
atomic_set(&charger_mode, val);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(charger_temp, 0664,
|
||||||
|
thermal_charger_temp_show, thermal_charger_temp_store);
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
thermal_balance_mode_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&balance_mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
thermal_balance_mode_store(struct device *dev,
|
||||||
|
struct device_attribute *attr, const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
int val = -1;
|
||||||
|
|
||||||
|
val = simple_strtol(buf, NULL, 10);
|
||||||
|
|
||||||
|
atomic_set(&balance_mode, val);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(balance_mode, 0664,
|
||||||
|
thermal_balance_mode_show, thermal_balance_mode_store);
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
thermal_boost_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
return snprintf(buf, PAGE_SIZE, boost_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
thermal_boost_store(struct device *dev,
|
||||||
|
struct device_attribute *attr, const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
ret = snprintf(boost_buf, PAGE_SIZE, buf);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(boost, 0644,
|
||||||
|
thermal_boost_show, thermal_boost_store);
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
thermal_temp_state_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&temp_state));
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
thermal_temp_state_store(struct device *dev,
|
||||||
|
struct device_attribute *attr, const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
int val = -1;
|
||||||
|
|
||||||
|
val = simple_strtol(buf, NULL, 10);
|
||||||
|
|
||||||
|
atomic_set(&temp_state, val);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(temp_state, 0664,
|
||||||
|
thermal_temp_state_show, thermal_temp_state_store);
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
cpu_limits_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
cpu_limits_store(struct device *dev,
|
||||||
|
struct device_attribute *attr, const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
unsigned int cpu;
|
||||||
|
unsigned int max;
|
||||||
|
|
||||||
|
if (sscanf(buf, "cpu%u %u", &cpu, &max) != CPU_LIMITS_PARAM_NUM) {
|
||||||
|
pr_err("input param error, can not prase param\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpu_limits_set_level(cpu, max);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(cpu_limits, 0664,
|
||||||
|
cpu_limits_show, cpu_limits_store);
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
thermal_board_sensor_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
if (!board_sensor)
|
||||||
|
board_sensor = "invalid";
|
||||||
|
|
||||||
|
return snprintf(buf, PAGE_SIZE, "%s", board_sensor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(board_sensor, 0664,
|
||||||
|
thermal_board_sensor_show, NULL);
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
thermal_board_sensor_temp_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
return snprintf(buf, PAGE_SIZE, board_sensor_temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
thermal_board_sensor_temp_store(struct device *dev,
|
||||||
|
struct device_attribute *attr, const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
snprintf(board_sensor_temp, PAGE_SIZE, buf);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(board_sensor_temp, 0664,
|
||||||
|
thermal_board_sensor_temp_show, thermal_board_sensor_temp_store);
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
thermal_board_sensor_second_temp_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
return snprintf(buf, PAGE_SIZE, board_sensor_second_temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
thermal_board_sensor_second_temp_store(struct device *dev,
|
||||||
|
struct device_attribute *attr, const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
snprintf(board_sensor_second_temp, PAGE_SIZE, buf);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(board_sensor_second_temp, 0664,
|
||||||
|
thermal_board_sensor_second_temp_show, thermal_board_sensor_second_temp_store);
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
thermal_modem_limit_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&modem_limit));
|
||||||
|
}
|
||||||
|
static ssize_t
|
||||||
|
thermal_modem_limit_store(struct device *dev,
|
||||||
|
struct device_attribute *attr, const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
int val = -1;
|
||||||
|
|
||||||
|
val = simple_strtol(buf, NULL, 10);
|
||||||
|
|
||||||
|
atomic_set(&modem_limit, val);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(modem_limit, 0664,
|
||||||
|
thermal_modem_limit_show, thermal_modem_limit_store);
|
||||||
|
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
thermal_market_download_limit_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&market_download_limit));
|
||||||
|
}
|
||||||
|
static ssize_t
|
||||||
|
thermal_market_download_limit_store(struct device *dev,
|
||||||
|
struct device_attribute *attr, const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
int val = -1;
|
||||||
|
|
||||||
|
val = simple_strtol(buf, NULL, 10);
|
||||||
|
|
||||||
|
atomic_set(&market_download_limit, val);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(market_download_limit, 0664,
|
||||||
|
thermal_market_download_limit_show, thermal_market_download_limit_store);
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
thermal_flash_state_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&flash_state));
|
||||||
|
}
|
||||||
|
static ssize_t
|
||||||
|
thermal_flash_state_store(struct device *dev,
|
||||||
|
struct device_attribute *attr, const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
int val = -1;
|
||||||
|
val = simple_strtol(buf, NULL, 10);
|
||||||
|
atomic_set(&flash_state, val);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(flash_state, 0664,
|
||||||
|
thermal_flash_state_show, thermal_flash_state_store);
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
thermal_wifi_limit_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&wifi_limit));
|
||||||
|
}
|
||||||
|
static ssize_t
|
||||||
|
thermal_wifi_limit_store(struct device *dev,
|
||||||
|
struct device_attribute *attr, const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
int val = -1;
|
||||||
|
val = simple_strtol(buf, NULL, 10);
|
||||||
|
atomic_set(&wifi_limit, val);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(wifi_limit, 0664,
|
||||||
|
thermal_wifi_limit_show, thermal_wifi_limit_store);
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
thermal_poor_modem_limit_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&poor_modem_limit));
|
||||||
|
}
|
||||||
|
static ssize_t
|
||||||
|
thermal_poor_modem_limit_store(struct device *dev,
|
||||||
|
struct device_attribute *attr, const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
int val = -1;
|
||||||
|
val = simple_strtol(buf, NULL, 10);
|
||||||
|
atomic_set(&poor_modem_limit, val);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(poor_modem_limit, 0664,
|
||||||
|
thermal_poor_modem_limit_show, thermal_poor_modem_limit_store);
|
||||||
|
|
||||||
|
int create_thermal_message_node(void)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
thermal_message_dev.class = &thermal_class;
|
||||||
|
|
||||||
|
dev_set_name(&thermal_message_dev, "thermal_message");
|
||||||
|
ret = device_register(&thermal_message_dev);
|
||||||
|
if (!ret) {
|
||||||
|
ret = sysfs_create_file(&thermal_message_dev.kobj, &dev_attr_sconfig.attr);
|
||||||
|
if (ret < 0)
|
||||||
|
pr_warn("Thermal: create sconfig node failed\n");
|
||||||
|
|
||||||
|
ret = sysfs_create_file(&thermal_message_dev.kobj, &dev_attr_balance_mode.attr);
|
||||||
|
if (ret < 0)
|
||||||
|
pr_warn("Thermal: create balance mode node failed\n");
|
||||||
|
|
||||||
|
ret = sysfs_create_file(&thermal_message_dev.kobj, &dev_attr_boost.attr);
|
||||||
|
if (ret < 0)
|
||||||
|
pr_warn("Thermal: create boost node failed\n");
|
||||||
|
|
||||||
|
ret = sysfs_create_file(&thermal_message_dev.kobj, &dev_attr_temp_state.attr);
|
||||||
|
if (ret < 0)
|
||||||
|
pr_warn("Thermal: create temp state node failed\n");
|
||||||
|
|
||||||
|
ret = sysfs_create_file(&thermal_message_dev.kobj, &dev_attr_cpu_limits.attr);
|
||||||
|
if (ret < 0)
|
||||||
|
pr_warn("Thermal: create cpu limits node failed\n");
|
||||||
|
|
||||||
|
ret = sysfs_create_file(&thermal_message_dev.kobj, &dev_attr_board_sensor.attr);
|
||||||
|
if (ret < 0)
|
||||||
|
pr_warn("Thermal: create board sensor node failed\n");
|
||||||
|
|
||||||
|
ret = sysfs_create_file(&thermal_message_dev.kobj, &dev_attr_board_sensor_temp.attr);
|
||||||
|
if (ret < 0)
|
||||||
|
pr_warn("Thermal: create board sensor temp node failed\n");
|
||||||
|
|
||||||
|
ret = sysfs_create_file(&thermal_message_dev.kobj, &dev_attr_board_sensor_second_temp.attr);
|
||||||
|
if (ret < 0)
|
||||||
|
pr_warn("Thermal: create board sensor second temp node failed\n");
|
||||||
|
|
||||||
|
ret = sysfs_create_file(&thermal_message_dev.kobj, &dev_attr_charger_temp.attr);
|
||||||
|
if (ret < 0)
|
||||||
|
pr_warn("Thermal: create charger temp node failed\n");
|
||||||
|
ret = sysfs_create_file(&thermal_message_dev.kobj, &dev_attr_modem_limit.attr);
|
||||||
|
if (ret < 0)
|
||||||
|
pr_warn("Thermal: create modem limit node failed\n");
|
||||||
|
ret = sysfs_create_file(&thermal_message_dev.kobj, &dev_attr_market_download_limit.attr);
|
||||||
|
if (ret < 0)
|
||||||
|
pr_warn("Thermal: create market download limit node failed\n");
|
||||||
|
ret = sysfs_create_file(&thermal_message_dev.kobj, &dev_attr_flash_state.attr);
|
||||||
|
if (ret < 0)
|
||||||
|
pr_warn("Thermal: create flash state node failed\n");
|
||||||
|
ret = sysfs_create_file(&thermal_message_dev.kobj, &dev_attr_wifi_limit.attr);
|
||||||
|
if (ret < 0)
|
||||||
|
pr_warn("Thermal: create wifi limit node failed\n");
|
||||||
|
ret = sysfs_create_file(&thermal_message_dev.kobj, &dev_attr_poor_modem_limit.attr);
|
||||||
|
if (ret < 0)
|
||||||
|
pr_warn("Thermal: create poor modem limit node failed\n");
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void destroy_thermal_message_node(void)
|
||||||
|
{
|
||||||
|
sysfs_remove_file(&thermal_message_dev.kobj, &dev_attr_poor_modem_limit.attr);
|
||||||
|
sysfs_remove_file(&thermal_message_dev.kobj, &dev_attr_wifi_limit.attr);
|
||||||
|
sysfs_remove_file(&thermal_message_dev.kobj, &dev_attr_flash_state.attr);
|
||||||
|
sysfs_remove_file(&thermal_message_dev.kobj, &dev_attr_market_download_limit.attr);
|
||||||
|
sysfs_remove_file(&thermal_message_dev.kobj, &dev_attr_charger_temp.attr);
|
||||||
|
sysfs_remove_file(&thermal_message_dev.kobj, &dev_attr_modem_limit.attr);
|
||||||
|
sysfs_remove_file(&thermal_message_dev.kobj, &dev_attr_board_sensor_temp.attr);
|
||||||
|
sysfs_remove_file(&thermal_message_dev.kobj, &dev_attr_board_sensor_second_temp.attr);
|
||||||
|
sysfs_remove_file(&thermal_message_dev.kobj, &dev_attr_board_sensor.attr);
|
||||||
|
sysfs_remove_file(&thermal_message_dev.kobj, &dev_attr_cpu_limits.attr);
|
||||||
|
sysfs_remove_file(&thermal_message_dev.kobj, &dev_attr_temp_state.attr);
|
||||||
|
sysfs_remove_file(&thermal_message_dev.kobj, &dev_attr_boost.attr);
|
||||||
|
sysfs_remove_file(&thermal_message_dev.kobj, &dev_attr_sconfig.attr);
|
||||||
|
sysfs_remove_file(&thermal_message_dev.kobj, &dev_attr_balance_mode.attr);
|
||||||
|
device_unregister(&thermal_message_dev);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_QTI_THERMAL
|
#ifdef CONFIG_QTI_THERMAL
|
||||||
static int __init thermal_init(void)
|
static int __init thermal_init(void)
|
||||||
{
|
{
|
||||||
@ -1804,6 +2216,17 @@ static int __init thermal_init(void)
|
|||||||
result);
|
result);
|
||||||
thermal_debug_init();
|
thermal_debug_init();
|
||||||
|
|
||||||
|
|
||||||
|
result = of_parse_thermal_message();
|
||||||
|
if (result)
|
||||||
|
pr_warn("Thermal: Can not parse thermal message node, return %d\n",
|
||||||
|
result);
|
||||||
|
|
||||||
|
result = create_thermal_message_node();
|
||||||
|
if (result)
|
||||||
|
pr_warn("Thermal: create thermal message node failed, return %d\n",
|
||||||
|
result);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unregister_class:
|
unregister_class:
|
||||||
@ -1827,6 +2250,7 @@ static void thermal_exit(void)
|
|||||||
of_thermal_destroy_zones();
|
of_thermal_destroy_zones();
|
||||||
destroy_workqueue(thermal_passive_wq);
|
destroy_workqueue(thermal_passive_wq);
|
||||||
genetlink_exit();
|
genetlink_exit();
|
||||||
|
destroy_thermal_message_node();
|
||||||
class_unregister(&thermal_class);
|
class_unregister(&thermal_class);
|
||||||
thermal_debug_exit();
|
thermal_debug_exit();
|
||||||
thermal_unregister_governors();
|
thermal_unregister_governors();
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
/* Init section thermal table */
|
/* Init section thermal table */
|
||||||
extern struct thermal_governor *__governor_thermal_table[];
|
extern struct thermal_governor *__governor_thermal_table[];
|
||||||
extern struct thermal_governor *__governor_thermal_table_end[];
|
extern struct thermal_governor *__governor_thermal_table_end[];
|
||||||
|
extern struct class thermal_class;
|
||||||
|
extern struct device thermal_message_dev;
|
||||||
|
|
||||||
#define THERMAL_TABLE_ENTRY(table, name) \
|
#define THERMAL_TABLE_ENTRY(table, name) \
|
||||||
static typeof(name) *__thermal_table_entry_##name \
|
static typeof(name) *__thermal_table_entry_##name \
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/jiffies.h>
|
#include <linux/jiffies.h>
|
||||||
|
#include <linux/vmalloc.h>
|
||||||
|
|
||||||
#include "thermal_core.h"
|
#include "thermal_core.h"
|
||||||
|
|
||||||
@ -1163,7 +1164,7 @@ static void cooling_device_stats_setup(struct thermal_cooling_device *cdev)
|
|||||||
var += sizeof(*stats->time_in_state) * states;
|
var += sizeof(*stats->time_in_state) * states;
|
||||||
var += sizeof(*stats->trans_table) * states * states;
|
var += sizeof(*stats->trans_table) * states * states;
|
||||||
|
|
||||||
stats = kzalloc(var, GFP_KERNEL);
|
stats = vzalloc(var);
|
||||||
if (!stats)
|
if (!stats)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -1185,7 +1186,7 @@ out:
|
|||||||
|
|
||||||
static void cooling_device_stats_destroy(struct thermal_cooling_device *cdev)
|
static void cooling_device_stats_destroy(struct thermal_cooling_device *cdev)
|
||||||
{
|
{
|
||||||
kfree(cdev->stats);
|
vfree(cdev->stats);
|
||||||
cdev->stats = NULL;
|
cdev->stats = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
struct cpufreq_policy;
|
struct cpufreq_policy;
|
||||||
|
|
||||||
|
void cpu_limits_set_level(unsigned int cpu, unsigned int max_freq);
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_THERMAL
|
#ifdef CONFIG_CPU_THERMAL
|
||||||
/**
|
/**
|
||||||
* cpufreq_cooling_register - function to create cpufreq cooling device.
|
* cpufreq_cooling_register - function to create cpufreq cooling device.
|
||||||
|
Loading…
Reference in New Issue
Block a user