Merge "dt-bindings: thermal: qmi_sensor: Add new modem qmi sensors"
This commit is contained in:
commit
a5b00e08cf
7 changed files with 520 additions and 0 deletions
|
|
@ -192,10 +192,12 @@ CONFIG_QTI_BCL_PMIC5=m
|
|||
CONFIG_QTI_BCL_SOC_DRIVER=m
|
||||
CONFIG_QTI_CHARGER_ULOG_GLINK=m
|
||||
CONFIG_QTI_CPUCP_LOG=m
|
||||
CONFIG_QTI_CPUFREQ_CDEV=m
|
||||
CONFIG_QTI_CPU_HOTPLUG_COOLING_DEVICE=m
|
||||
CONFIG_QTI_CPU_PAUSE_COOLING_DEVICE=m
|
||||
CONFIG_QTI_CPU_VOLTAGE_COOLING_DEVICE=m
|
||||
CONFIG_QTI_DDR_COOLING_DEVICE=m
|
||||
CONFIG_QTI_DEVFREQ_CDEV=m
|
||||
CONFIG_QTI_HW_KEY_MANAGER=m
|
||||
CONFIG_QTI_IOMMU_SUPPORT=m
|
||||
CONFIG_QTI_PMIC_EUSB2_REPEATER=m
|
||||
|
|
|
|||
|
|
@ -103,6 +103,24 @@ config QTI_QMI_SENSOR_V2
|
|||
the remote sensor. These sensors can take thresholds and notify the
|
||||
thermal framework when the threshold is reached.
|
||||
|
||||
config QTI_CPUFREQ_CDEV
|
||||
tristate "QTI CPU frequency cooling device"
|
||||
depends on CPU_FREQ && THERMAL && PM_OPP
|
||||
help
|
||||
This enables the QTI cpufreq cooling device, which
|
||||
will help register the cpu freq devices with thermal
|
||||
framework and allow limiting the cpu frequency by
|
||||
userspace.
|
||||
|
||||
config QTI_DEVFREQ_CDEV
|
||||
tristate "QTI Devfreq cooling device"
|
||||
depends on PM_DEVFREQ && THERMAL && PM_OPP
|
||||
help
|
||||
This enables the QTI devfreq cooling device, which
|
||||
will help register the devfreq cooling devices with
|
||||
thermal framework and allow limiting the devfreq
|
||||
frequency.
|
||||
|
||||
config QTI_CPU_VOLTAGE_COOLING_DEVICE
|
||||
tristate "QTI CPU VOLTAGE cooling devices"
|
||||
depends on CPU_FREQ && THERMAL
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ qti_qmi_cdev-y += thermal_mitigation_device_service_v01.o qmi_cooling.o
|
|||
obj-$(CONFIG_QTI_QMI_SENSOR_V2) += qti_qmi_sensor_v2.o
|
||||
qti_qmi_sensor_v2-y += thermal_sensor_service_v02.o qmi_sensors_v2.o
|
||||
|
||||
obj-$(CONFIG_QTI_CPUFREQ_CDEV) += qti_cpufreq_cdev.o
|
||||
obj-$(CONFIG_QTI_DEVFREQ_CDEV) += qti_devfreq_cdev.o
|
||||
obj-$(CONFIG_QTI_CPU_VOLTAGE_COOLING_DEVICE) += cpu_voltage_cooling.o
|
||||
obj-$(CONFIG_QTI_CPU_HOTPLUG_COOLING_DEVICE) += cpu_hotplug.o
|
||||
obj-$(CONFIG_QTI_DDR_COOLING_DEVICE) += ddr_cdev.o
|
||||
|
|
|
|||
|
|
@ -84,6 +84,12 @@ enum qmi_ts_sensor {
|
|||
QMI_TS_EPM7,
|
||||
QMI_TS_SDR0_PA,
|
||||
QMI_TS_SDR1_PA,
|
||||
QMI_TS_SUB0_SDR0_PA,
|
||||
QMI_TS_SUB1_SDR0_PA,
|
||||
QMI_SYS_THERM3,
|
||||
QMI_SYS_THERM4,
|
||||
QMI_SYS_THERM5,
|
||||
QMI_SYS_THERM6,
|
||||
QMI_TS_MAX_NR
|
||||
};
|
||||
|
||||
|
|
@ -162,6 +168,12 @@ static char sensor_clients[QMI_TS_MAX_NR][QMI_CLIENT_NAME_LENGTH] = {
|
|||
{"epm7"},
|
||||
{"sdr0_pa"},
|
||||
{"sdr1_pa"},
|
||||
{"sub0_sdr0_pa"},
|
||||
{"sub1_sdr0_pa"},
|
||||
{"sys_therm3"},
|
||||
{"sys_therm4"},
|
||||
{"sys_therm5"},
|
||||
{"sys_therm6"},
|
||||
};
|
||||
|
||||
#endif /* __QMI_SENSORS_H__ */
|
||||
|
|
|
|||
269
drivers/thermal/qcom/qti_cpufreq_cdev.c
Normal file
269
drivers/thermal/qcom/qti_cpufreq_cdev.c
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "%s:%s " fmt, KBUILD_MODNAME, __func__
|
||||
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_qos.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/thermal.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#define CPUFREQ_CDEV_NAME "cpu%d"
|
||||
#define CPUFREQ_CDEV "qcom-cpufreq-cdev"
|
||||
|
||||
struct cpufreq_cdev_device {
|
||||
struct list_head node;
|
||||
struct thermal_cooling_device *cdev;
|
||||
int cpu;
|
||||
unsigned long cur_state;
|
||||
unsigned long max_state;
|
||||
unsigned int *freq_table;
|
||||
struct freq_qos_request qos_max_freq_req;
|
||||
char cdev_name[THERMAL_NAME_LENGTH];
|
||||
struct cpufreq_policy *policy;
|
||||
struct work_struct reg_work;
|
||||
};
|
||||
|
||||
static DEFINE_MUTEX(qti_cpufreq_cdev_lock);
|
||||
static LIST_HEAD(qti_cpufreq_cdev_list);
|
||||
static enum cpuhp_state cpu_hp_online;
|
||||
|
||||
static unsigned int state_to_cpufreq(struct cpufreq_cdev_device *cdev_data,
|
||||
unsigned long state)
|
||||
{
|
||||
return cdev_data->freq_table ?
|
||||
cdev_data->freq_table[state] : UINT_MAX;
|
||||
}
|
||||
|
||||
static int cpufreq_cdev_set_state(struct thermal_cooling_device *cdev,
|
||||
unsigned long state)
|
||||
{
|
||||
struct cpufreq_cdev_device *cdev_data = cdev->devdata;
|
||||
int ret = 0;
|
||||
unsigned int freq;
|
||||
|
||||
if (state > cdev_data->max_state)
|
||||
return -EINVAL;
|
||||
if (state == cdev_data->cur_state)
|
||||
return 0;
|
||||
|
||||
if (freq_qos_request_active(&cdev_data->qos_max_freq_req)) {
|
||||
freq = state_to_cpufreq(cdev_data, state);
|
||||
pr_debug("cdev:%s Limit:%u\n", cdev->type, freq);
|
||||
ret = freq_qos_update_request(&cdev_data->qos_max_freq_req,
|
||||
freq);
|
||||
if (ret < 0) {
|
||||
pr_err("Error placing qos request:%u. cdev:%s err:%d\n",
|
||||
freq, cdev->type, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
cdev_data->cur_state = state;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpufreq_cdev_get_state(struct thermal_cooling_device *cdev,
|
||||
unsigned long *state)
|
||||
{
|
||||
struct cpufreq_cdev_device *cdev_data = cdev->devdata;
|
||||
|
||||
*state = cdev_data->cur_state;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpufreq_cdev_get_max_state(struct thermal_cooling_device *cdev,
|
||||
unsigned long *state)
|
||||
{
|
||||
struct cpufreq_cdev_device *cdev_data = cdev->devdata;
|
||||
|
||||
*state = cdev_data->max_state;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct thermal_cooling_device_ops cpufreq_cdev_ops = {
|
||||
.set_cur_state = cpufreq_cdev_set_state,
|
||||
.get_cur_state = cpufreq_cdev_get_state,
|
||||
.get_max_state = cpufreq_cdev_get_max_state,
|
||||
};
|
||||
|
||||
static void cpufreq_cdev_register(struct work_struct *work)
|
||||
{
|
||||
struct cpufreq_cdev_device *cdev_data = container_of(work,
|
||||
struct cpufreq_cdev_device, reg_work);
|
||||
struct cpufreq_policy *policy = NULL;
|
||||
int freq_count = 0, i;
|
||||
|
||||
policy = cpufreq_cpu_get(cdev_data->cpu);
|
||||
if (!policy) {
|
||||
pr_err("No policy for CPU:%d\n", cdev_data->cpu);
|
||||
return;
|
||||
}
|
||||
freq_count = cpufreq_table_count_valid_entries(policy);
|
||||
if (!freq_count) {
|
||||
pr_debug("CPU%d freq policy table count error%d\n",
|
||||
cdev_data->cpu, freq_count);
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
cdev_data->freq_table = kmalloc_array(freq_count,
|
||||
sizeof(*cdev_data->freq_table),
|
||||
GFP_KERNEL);
|
||||
if (!cdev_data->freq_table)
|
||||
goto error_exit;
|
||||
|
||||
for (i = 0; i < freq_count; i++) {
|
||||
if (policy->freq_table_sorted ==
|
||||
CPUFREQ_TABLE_SORTED_ASCENDING)
|
||||
cdev_data->freq_table[i] =
|
||||
policy->freq_table[freq_count - i - 1].frequency;
|
||||
else
|
||||
cdev_data->freq_table[i] =
|
||||
policy->freq_table[i].frequency;
|
||||
}
|
||||
|
||||
freq_count--;
|
||||
cdev_data->policy = policy;
|
||||
cdev_data->max_state = freq_count;
|
||||
cdev_data->cur_state = 0;
|
||||
freq_qos_add_request(&policy->constraints,
|
||||
&cdev_data->qos_max_freq_req, FREQ_QOS_MAX,
|
||||
state_to_cpufreq(cdev_data, 0));
|
||||
cdev_data->cdev = thermal_cooling_device_register(cdev_data->cdev_name,
|
||||
cdev_data, &cpufreq_cdev_ops);
|
||||
if (IS_ERR(cdev_data->cdev)) {
|
||||
pr_err("Cdev register failed for %s, ret:%d\n",
|
||||
cdev_data->cdev_name, PTR_ERR(cdev_data->cdev));
|
||||
freq_qos_remove_request(&cdev_data->qos_max_freq_req);
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
pr_debug("Cdev %s registered\n", cdev_data->cdev_name);
|
||||
return;
|
||||
error_exit:
|
||||
if (policy)
|
||||
cpufreq_cpu_put(policy);
|
||||
if (cdev_data->cdev)
|
||||
cdev_data->cdev = NULL;
|
||||
kfree(cdev_data->freq_table);
|
||||
}
|
||||
|
||||
static int cpufreq_cdev_hp_online(unsigned int online_cpu)
|
||||
{
|
||||
|
||||
struct cpufreq_cdev_device *cdev_data;
|
||||
|
||||
mutex_lock(&qti_cpufreq_cdev_lock);
|
||||
list_for_each_entry(cdev_data, &qti_cpufreq_cdev_list, node) {
|
||||
if (cdev_data->cpu != online_cpu || cdev_data->cdev)
|
||||
continue;
|
||||
queue_work(system_highpri_wq, &cdev_data->reg_work);
|
||||
}
|
||||
mutex_unlock(&qti_cpufreq_cdev_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpufreq_cdev_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct cpufreq_cdev_device *cdev_data;
|
||||
struct device_node *np = pdev->dev.of_node, *cpu_phandle = NULL;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device *cpu_dev;
|
||||
int cpu = 0, ret = 0;
|
||||
struct of_phandle_iterator it;
|
||||
|
||||
mutex_lock(&qti_cpufreq_cdev_lock);
|
||||
of_phandle_iterator_init(&it, np, "qcom,cpus", NULL, 0);
|
||||
while (of_phandle_iterator_next(&it) == 0) {
|
||||
cdev_data = devm_kzalloc(dev, sizeof(*cdev_data), GFP_KERNEL);
|
||||
if (!cdev_data) {
|
||||
mutex_unlock(&qti_cpufreq_cdev_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
cpu_phandle = it.node;
|
||||
cdev_data->cpu = -1;
|
||||
for_each_possible_cpu(cpu) {
|
||||
cpu_dev = get_cpu_device(cpu);
|
||||
if (cpu_dev && cpu_dev->of_node == cpu_phandle) {
|
||||
cdev_data->cpu = cpu;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cdev_data->cpu == -1)
|
||||
continue;
|
||||
snprintf(cdev_data->cdev_name, THERMAL_NAME_LENGTH,
|
||||
CPUFREQ_CDEV_NAME, cpu);
|
||||
INIT_WORK(&cdev_data->reg_work,
|
||||
cpufreq_cdev_register);
|
||||
list_add(&cdev_data->node, &qti_cpufreq_cdev_list);
|
||||
}
|
||||
mutex_unlock(&qti_cpufreq_cdev_lock);
|
||||
|
||||
ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "thermal-cpu/cdev:online",
|
||||
cpufreq_cdev_hp_online, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
cpu_hp_online = ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpufreq_cdev_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct cpufreq_cdev_device *cdev_data;
|
||||
|
||||
mutex_lock(&qti_cpufreq_cdev_lock);
|
||||
if (cpu_hp_online) {
|
||||
cpuhp_remove_state_nocalls(cpu_hp_online);
|
||||
cpu_hp_online = 0;
|
||||
}
|
||||
list_for_each_entry(cdev_data, &qti_cpufreq_cdev_list, node) {
|
||||
if (!cdev_data->cdev)
|
||||
continue;
|
||||
thermal_cooling_device_unregister(cdev_data->cdev);
|
||||
if (freq_qos_request_active(&cdev_data->qos_max_freq_req))
|
||||
freq_qos_remove_request(&cdev_data->qos_max_freq_req);
|
||||
cdev_data->cdev = NULL;
|
||||
cpufreq_cpu_put(cdev_data->policy);
|
||||
kfree(cdev_data->freq_table);
|
||||
}
|
||||
mutex_unlock(&qti_cpufreq_cdev_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id cpufreq_cdev_match[] = {
|
||||
{.compatible = "qcom,cpufreq-cdev"},
|
||||
{}
|
||||
};
|
||||
|
||||
static struct platform_driver cpufreq_cdev_driver = {
|
||||
.probe = cpufreq_cdev_probe,
|
||||
.remove = cpufreq_cdev_remove,
|
||||
.driver = {
|
||||
.name = CPUFREQ_CDEV,
|
||||
.of_match_table = cpufreq_cdev_match,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init cpufreq_cdev_init(void)
|
||||
{
|
||||
return platform_driver_register(&cpufreq_cdev_driver);
|
||||
}
|
||||
module_init(cpufreq_cdev_init);
|
||||
|
||||
static void __exit cpufreq_cdev_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&cpufreq_cdev_driver);
|
||||
}
|
||||
module_exit(cpufreq_cdev_exit);
|
||||
|
||||
MODULE_DESCRIPTION("Qualcomm Technologies, Inc. cpufreq cooling driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
211
drivers/thermal/qcom/qti_devfreq_cdev.c
Normal file
211
drivers/thermal/qcom/qti_devfreq_cdev.c
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "%s:%s " fmt, KBUILD_MODNAME, __func__
|
||||
|
||||
#include <linux/devfreq.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_opp.h>
|
||||
#include <linux/pm_qos.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/thermal.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#define MAX_RETRY_CNT 20
|
||||
#define RETRY_DELAY msecs_to_jiffies(1000)
|
||||
#define DEVFREQ_CDEV_NAME "gpu"
|
||||
#define DEVFREQ_CDEV "qcom-devfreq-cdev"
|
||||
|
||||
struct devfreq_cdev_device {
|
||||
struct device_node *np;
|
||||
struct devfreq *devfreq;
|
||||
struct device *dev;
|
||||
unsigned long *freq_table;
|
||||
int cur_state;
|
||||
int max_state;
|
||||
int retry_cnt;
|
||||
struct dev_pm_qos_request qos_max_freq_req;
|
||||
struct delayed_work register_work;
|
||||
struct thermal_cooling_device *cdev;
|
||||
};
|
||||
|
||||
static struct devfreq_cdev_device *devfreq_cdev;
|
||||
|
||||
static int devfreq_cdev_set_state(struct thermal_cooling_device *cdev,
|
||||
unsigned long state)
|
||||
{
|
||||
struct devfreq_cdev_device *cdev_data = cdev->devdata;
|
||||
int ret = 0;
|
||||
unsigned long freq;
|
||||
|
||||
if (state > cdev_data->max_state)
|
||||
return -EINVAL;
|
||||
if (state == cdev_data->cur_state)
|
||||
return 0;
|
||||
freq = cdev_data->freq_table[state];
|
||||
pr_debug("cdev:%s Limit:%lu\n", cdev->type, freq);
|
||||
ret = dev_pm_qos_update_request(&cdev_data->qos_max_freq_req, freq);
|
||||
if (ret < 0) {
|
||||
pr_err("Error placing qos request:%u. cdev:%s err:%d\n",
|
||||
freq, cdev->type, ret);
|
||||
return ret;
|
||||
}
|
||||
cdev_data->cur_state = state;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int devfreq_cdev_get_state(struct thermal_cooling_device *cdev,
|
||||
unsigned long *state)
|
||||
{
|
||||
struct devfreq_cdev_device *cdev_data = cdev->devdata;
|
||||
|
||||
*state = cdev_data->cur_state;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int devfreq_cdev_get_max_state(struct thermal_cooling_device *cdev,
|
||||
unsigned long *state)
|
||||
{
|
||||
struct devfreq_cdev_device *cdev_data = cdev->devdata;
|
||||
|
||||
*state = cdev_data->max_state;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct thermal_cooling_device_ops devfreq_cdev_ops = {
|
||||
.set_cur_state = devfreq_cdev_set_state,
|
||||
.get_cur_state = devfreq_cdev_get_state,
|
||||
.get_max_state = devfreq_cdev_get_max_state,
|
||||
};
|
||||
|
||||
static void devfreq_cdev_work(struct work_struct *work)
|
||||
{
|
||||
struct devfreq *df = NULL;
|
||||
unsigned long freq = ULONG_MAX;
|
||||
unsigned long *freq_table;
|
||||
struct dev_pm_opp *opp;
|
||||
int ret = 0, freq_ct, i;
|
||||
struct devfreq_cdev_device *cdev_data = container_of(work,
|
||||
struct devfreq_cdev_device,
|
||||
register_work.work);
|
||||
|
||||
df = devfreq_get_devfreq_by_node(cdev_data->np);
|
||||
if (IS_ERR(df)) {
|
||||
ret = PTR_ERR(df);
|
||||
pr_debug("Devfreq not available:%d\n", ret);
|
||||
if (--cdev_data->retry_cnt)
|
||||
queue_delayed_work(system_highpri_wq,
|
||||
&cdev_data->register_work,
|
||||
RETRY_DELAY);
|
||||
return;
|
||||
}
|
||||
|
||||
cdev_data->dev = df->dev.parent;
|
||||
cdev_data->devfreq = df;
|
||||
freq_ct = dev_pm_opp_get_opp_count(cdev_data->dev);
|
||||
freq_table = kcalloc(freq_ct, sizeof(*freq_table), GFP_KERNEL);
|
||||
if (!freq_table) {
|
||||
ret = -ENOMEM;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0, freq = ULONG_MAX; i < freq_ct; i++, freq--) {
|
||||
|
||||
opp = dev_pm_opp_find_freq_floor(cdev_data->dev, &freq);
|
||||
if (IS_ERR(opp)) {
|
||||
ret = PTR_ERR(opp);
|
||||
goto qos_exit;
|
||||
}
|
||||
dev_pm_opp_put(opp);
|
||||
|
||||
freq_table[i] = DIV_ROUND_UP(freq, 1000); //hz to khz
|
||||
pr_debug("%d. freq table:%d\n", i, freq_table[i]);
|
||||
}
|
||||
cdev_data->max_state = freq_ct-1;
|
||||
cdev_data->freq_table = freq_table;
|
||||
ret = dev_pm_qos_add_request(cdev_data->dev,
|
||||
&cdev_data->qos_max_freq_req,
|
||||
DEV_PM_QOS_MAX_FREQUENCY,
|
||||
PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE);
|
||||
if (ret < 0)
|
||||
goto qos_exit;
|
||||
cdev_data->cdev = thermal_cooling_device_register(DEVFREQ_CDEV_NAME,
|
||||
cdev_data, &devfreq_cdev_ops);
|
||||
if (IS_ERR(cdev_data->cdev)) {
|
||||
pr_err("Cdev register failed for gpu, ret:%d\n",
|
||||
PTR_ERR(cdev_data->cdev));
|
||||
cdev_data->cdev = NULL;
|
||||
goto qos_exit;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
qos_exit:
|
||||
kfree(cdev_data->freq_table);
|
||||
dev_pm_qos_remove_request(&cdev_data->qos_max_freq_req);
|
||||
}
|
||||
|
||||
static int devfreq_cdev_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
|
||||
devfreq_cdev = devm_kzalloc(dev, sizeof(*devfreq_cdev), GFP_KERNEL);
|
||||
if (!devfreq_cdev)
|
||||
return -ENOMEM;
|
||||
|
||||
devfreq_cdev->np = of_parse_phandle(pdev->dev.of_node,
|
||||
"qcom,devfreq", 0);
|
||||
devfreq_cdev->retry_cnt = MAX_RETRY_CNT;
|
||||
|
||||
INIT_DEFERRABLE_WORK(&devfreq_cdev->register_work, devfreq_cdev_work);
|
||||
queue_delayed_work(system_highpri_wq, &devfreq_cdev->register_work, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int devfreq_cdev_remove(struct platform_device *pdev)
|
||||
{
|
||||
if (devfreq_cdev->cdev) {
|
||||
thermal_cooling_device_unregister(devfreq_cdev->cdev);
|
||||
dev_pm_qos_remove_request(&devfreq_cdev->qos_max_freq_req);
|
||||
kfree(devfreq_cdev->freq_table);
|
||||
devfreq_cdev->cdev = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id devfreq_cdev_match[] = {
|
||||
{.compatible = "qcom,devfreq-cdev"},
|
||||
{}
|
||||
};
|
||||
|
||||
static struct platform_driver devfreq_cdev_driver = {
|
||||
.probe = devfreq_cdev_probe,
|
||||
.remove = devfreq_cdev_remove,
|
||||
.driver = {
|
||||
.name = DEVFREQ_CDEV,
|
||||
.of_match_table = devfreq_cdev_match,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init devfreq_cdev_init(void)
|
||||
{
|
||||
return platform_driver_register(&devfreq_cdev_driver);
|
||||
}
|
||||
module_init(devfreq_cdev_init);
|
||||
|
||||
static void __exit devfreq_cdev_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&devfreq_cdev_driver);
|
||||
}
|
||||
module_exit(devfreq_cdev_exit);
|
||||
|
||||
MODULE_DESCRIPTION("Qualcomm Technologies, Inc. devfreq cooling device driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -88,6 +88,12 @@
|
|||
#define QMI_EPM7 71
|
||||
#define QMI_SDR0_PA 72
|
||||
#define QMI_SDR1_PA 73
|
||||
#define QMI_SUB0_SDR0_PA 74
|
||||
#define QMI_SUB1_SDR0_PA 75
|
||||
#define QMI_SYS_THERM_3 76
|
||||
#define QMI_SYS_THERM_4 77
|
||||
#define QMI_SYS_THERM_5 78
|
||||
#define QMI_SYS_THERM_6 79
|
||||
|
||||
#define QMI_MODEM_INST_ID 0x0
|
||||
#define QMI_ADSP_INST_ID 0x1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue