summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWhi copybara merger <whitechapel-automerger@google.com>2021-10-27 13:42:05 +0530
committerNrithya Kanakasabapathy <nrithya@google.com>2021-11-09 20:23:26 +0000
commit31c9b0bdf1f54ca53b899c88d2de25108332a414 (patch)
tree3127356887f86fefe20ea3921a4783951e83f29c
parent1ac360cf5aca758039d87f67e87d8be451898509 (diff)
downloadjaneiro-31c9b0bdf1f54ca53b899c88d2de25108332a414.tar.gz
Merge branch 'pro' into android13-gs-pixel-5.10
edgetpu: code style fixups Bug: 204391548 edgetpu: Decrease pm_refcount when pm_runtime_get_sync fails Bug: 199111759 edgetpu: janeiro set default power state to UUD Bug: 203647578 edgetpu: Increase trace buffer size to 256 KB Bug: 202436856 edgetpu: Split EDGETPU_TELEMETRY_{LOG,TRACE}_BUFFER_SIZE Bug: 202436856 edgetpu: Calculate wrap bit by buffer size Bug: 202436856 edgetpu: thermal update call no longer available at 5.12 GitOrigin-RevId: 3d9db9216e2371c887b4164eee85b285dab25eb5 Change-Id: Ib8e4e687319a8bf60f9cacaf4697c01f4c71c59e
-rw-r--r--drivers/edgetpu/edgetpu-kci.c8
-rw-r--r--drivers/edgetpu/edgetpu-mobile-platform.c12
-rw-r--r--drivers/edgetpu/edgetpu-telemetry.c14
-rw-r--r--drivers/edgetpu/edgetpu-telemetry.h6
-rw-r--r--drivers/edgetpu/include/linux/gsa/gsa_tpu.h2
-rw-r--r--drivers/edgetpu/janeiro-pm.c8
-rw-r--r--drivers/edgetpu/mobile-firmware.c2
-rw-r--r--drivers/edgetpu/mobile-pm.c2
-rw-r--r--drivers/edgetpu/mobile-thermal.c121
9 files changed, 85 insertions, 90 deletions
diff --git a/drivers/edgetpu/edgetpu-kci.c b/drivers/edgetpu/edgetpu-kci.c
index 52521d1..bfa356f 100644
--- a/drivers/edgetpu/edgetpu-kci.c
+++ b/drivers/edgetpu/edgetpu-kci.c
@@ -1046,13 +1046,11 @@ int edgetpu_kci_notify_throttling(struct edgetpu_dev *etdev, u32 level)
.flags = level,
},
};
- int ret;
if (!etdev->kci)
return -ENODEV;
- ret = edgetpu_kci_send_cmd(etdev->kci, &cmd);
- return ret;
+ return edgetpu_kci_send_cmd(etdev->kci, &cmd);
}
@@ -1064,11 +1062,9 @@ int edgetpu_kci_block_bus_speed_control(struct edgetpu_dev *etdev, bool block)
.flags = (u32) block,
},
};
- int ret;
if (!etdev->kci)
return -ENODEV;
- ret = edgetpu_kci_send_cmd(etdev->kci, &cmd);
- return ret;
+ return edgetpu_kci_send_cmd(etdev->kci, &cmd);
}
diff --git a/drivers/edgetpu/edgetpu-mobile-platform.c b/drivers/edgetpu/edgetpu-mobile-platform.c
index fe1c67c..ffa8928 100644
--- a/drivers/edgetpu/edgetpu-mobile-platform.c
+++ b/drivers/edgetpu/edgetpu-mobile-platform.c
@@ -26,20 +26,24 @@
* Log and trace buffers at the beginning of the remapped region,
* pool memory afterwards.
*/
-#define EDGETPU_POOL_MEM_OFFSET (EDGETPU_TELEMETRY_BUFFER_SIZE * 2 * EDGETPU_NUM_CORES)
+#define EDGETPU_POOL_MEM_OFFSET \
+ ((EDGETPU_TELEMETRY_LOG_BUFFER_SIZE + EDGETPU_TELEMETRY_TRACE_BUFFER_SIZE) * \
+ EDGETPU_NUM_CORES)
static void get_telemetry_mem(struct edgetpu_mobile_platform_dev *etmdev,
enum edgetpu_telemetry_type type, struct edgetpu_coherent_mem *mem)
{
- int i, offset = type == EDGETPU_TELEMETRY_TRACE ? EDGETPU_TELEMETRY_BUFFER_SIZE : 0;
+ int i, offset = type == EDGETPU_TELEMETRY_TRACE ? EDGETPU_TELEMETRY_LOG_BUFFER_SIZE : 0;
+ const size_t size = type == EDGETPU_TELEMETRY_LOG ? EDGETPU_TELEMETRY_LOG_BUFFER_SIZE :
+ EDGETPU_TELEMETRY_TRACE_BUFFER_SIZE;
for (i = 0; i < etmdev->edgetpu_dev.num_cores; i++) {
mem[i].vaddr = etmdev->shared_mem_vaddr + offset;
mem[i].dma_addr = EDGETPU_REMAPPED_DATA_ADDR + offset;
mem[i].tpu_addr = EDGETPU_REMAPPED_DATA_ADDR + offset;
mem[i].host_addr = 0;
- mem[i].size = EDGETPU_TELEMETRY_BUFFER_SIZE;
- offset += EDGETPU_TELEMETRY_BUFFER_SIZE * 2;
+ mem[i].size = size;
+ offset += EDGETPU_TELEMETRY_LOG_BUFFER_SIZE + EDGETPU_TELEMETRY_TRACE_BUFFER_SIZE;
}
}
diff --git a/drivers/edgetpu/edgetpu-telemetry.c b/drivers/edgetpu/edgetpu-telemetry.c
index bad40ab..f18cef8 100644
--- a/drivers/edgetpu/edgetpu-telemetry.c
+++ b/drivers/edgetpu/edgetpu-telemetry.c
@@ -106,7 +106,7 @@ static void telemetry_unset_event(struct edgetpu_dev *etdev,
static void copy_with_wrap(struct edgetpu_telemetry_header *header, void *dest,
u32 length, u32 size, void *start)
{
- const u32 wrap_bit = EDGETPU_TELEMETRY_WRAP_BIT;
+ const u32 wrap_bit = size + sizeof(*header);
u32 remaining = 0;
u32 head = header->head & (wrap_bit - 1);
@@ -288,12 +288,10 @@ static int telemetry_mmap_buffer(struct edgetpu_dev *etdev,
return ret;
}
-static int telemetry_init(struct edgetpu_dev *etdev,
- struct edgetpu_telemetry *tel, const char *name,
- struct edgetpu_coherent_mem *mem,
+static int telemetry_init(struct edgetpu_dev *etdev, struct edgetpu_telemetry *tel,
+ const char *name, struct edgetpu_coherent_mem *mem, const size_t size,
void (*fallback)(struct edgetpu_telemetry *))
{
- const size_t size = EDGETPU_TELEMETRY_BUFFER_SIZE;
const u32 flags = EDGETPU_MMU_DIE | EDGETPU_MMU_32 | EDGETPU_MMU_HOST;
void *vaddr;
dma_addr_t dma_addr;
@@ -383,12 +381,14 @@ int edgetpu_telemetry_init(struct edgetpu_dev *etdev,
for (i = 0; i < etdev->num_cores; i++) {
ret = telemetry_init(etdev, &etdev->telemetry[i].log, "telemetry_log",
- log_mem ? &log_mem[i] : NULL, edgetpu_fw_log);
+ log_mem ? &log_mem[i] : NULL,
+ EDGETPU_TELEMETRY_LOG_BUFFER_SIZE, edgetpu_fw_log);
if (ret)
break;
#if IS_ENABLED(CONFIG_EDGETPU_TELEMETRY_TRACE)
ret = telemetry_init(etdev, &etdev->telemetry[i].trace, "telemetry_trace",
- trace_mem ? &trace_mem[i] : NULL, edgetpu_fw_trace);
+ trace_mem ? &trace_mem[i] : NULL,
+ EDGETPU_TELEMETRY_TRACE_BUFFER_SIZE, edgetpu_fw_trace);
if (ret)
break;
#endif
diff --git a/drivers/edgetpu/edgetpu-telemetry.h b/drivers/edgetpu/edgetpu-telemetry.h
index 6d7b3b1..2c89aff 100644
--- a/drivers/edgetpu/edgetpu-telemetry.h
+++ b/drivers/edgetpu/edgetpu-telemetry.h
@@ -27,9 +27,9 @@
#define EDGETPU_FW_DMESG_LOG_LEVEL (EDGETPU_FW_LOG_LEVEL_ERROR)
-#define EDGETPU_TELEMETRY_BUFFER_SIZE (16 * 4096)
-/* assumes buffer size is power of 2 */
-#define EDGETPU_TELEMETRY_WRAP_BIT EDGETPU_TELEMETRY_BUFFER_SIZE
+/* Buffer size must be a power of 2 */
+#define EDGETPU_TELEMETRY_LOG_BUFFER_SIZE (16 * 4096)
+#define EDGETPU_TELEMETRY_TRACE_BUFFER_SIZE (64 * 4096)
enum edgetpu_telemetry_state {
EDGETPU_TELEMETRY_DISABLED = 0,
diff --git a/drivers/edgetpu/include/linux/gsa/gsa_tpu.h b/drivers/edgetpu/include/linux/gsa/gsa_tpu.h
index 03dc951..2dc8a79 100644
--- a/drivers/edgetpu/include/linux/gsa/gsa_tpu.h
+++ b/drivers/edgetpu/include/linux/gsa/gsa_tpu.h
@@ -2,7 +2,7 @@
/*
* Fallback header for systems without GSA support.
*
- * Copyright (C) 2020 Google, Inc.
+ * Copyright (C) 2021 Google, Inc.
*/
#ifndef __LINUX_GSA_TPU_H
diff --git a/drivers/edgetpu/janeiro-pm.c b/drivers/edgetpu/janeiro-pm.c
index eec9340..3b56bb1 100644
--- a/drivers/edgetpu/janeiro-pm.c
+++ b/drivers/edgetpu/janeiro-pm.c
@@ -13,7 +13,7 @@
#include "edgetpu-mobile-platform.h"
#include "mobile-pm.h"
-#define TPU_DEFAULT_POWER_STATE TPU_ACTIVE_NOM
+#define TPU_DEFAULT_POWER_STATE TPU_ACTIVE_UUD
#include "mobile-pm.c"
@@ -49,17 +49,17 @@ static void janeiro_lpm_down(struct edgetpu_dev *etdev)
timeout_cnt++;
} while (timeout_cnt < SHUTDOWN_MAX_DELAY_COUNT);
if (timeout_cnt == SHUTDOWN_MAX_DELAY_COUNT) {
- // Log the issue then continue to perform the shutdown forcefully.
+ /* Log the issue then continue to perform the shutdown forcefully. */
etdev_err(etdev, "LPM shutdown failure, attempt to recover\n");
val = edgetpu_dev_read_32_sync(etdev, EDGETPU_PSM0_STATUS);
val1 = edgetpu_dev_read_32_sync(etdev, EDGETPU_PSM1_STATUS);
- etdev_err(etdev, "PSM0_STATUS: 0x%x, PSM1_STATUS: 0x%x\n", val, val1);
+ etdev_err(etdev, "PSM0_STATUS: %#x, PSM1_STATUS: %#x\n", val, val1);
edgetpu_dev_write_32_sync(etdev, EDGETPU_PSM0_GPOUT_WRT_LO,
EDGETPU_PSM0_RECOVER_VAL);
edgetpu_dev_write_32_sync(etdev, EDGETPU_PSM0_GPOUT_WRT_HI, 0);
val = edgetpu_dev_read_32_sync(etdev, EDGETPU_PSM0_DEBUGCFG);
- // Write then clear EDGETPU_PSM0_DEBUGCFG[1] to update the value.
+ /* Write then clear EDGETPU_PSM0_DEBUGCFG[1] to update the value. */
edgetpu_dev_write_32_sync(etdev, EDGETPU_PSM0_DEBUGCFG, 0x2 | val);
edgetpu_dev_write_32_sync(etdev, EDGETPU_PSM0_DEBUGCFG, 0x1 & val);
etdev_err(etdev, "Recovery attempt finish\n");
diff --git a/drivers/edgetpu/mobile-firmware.c b/drivers/edgetpu/mobile-firmware.c
index 40ac077..f021a32 100644
--- a/drivers/edgetpu/mobile-firmware.c
+++ b/drivers/edgetpu/mobile-firmware.c
@@ -60,7 +60,7 @@ static int mobile_firmware_setup_mappings(struct edgetpu_dev *etdev,
size = CONFIG_TO_SIZE(image_config->mappings[i].image_config_value);
phys_addr = image_config->mappings[i].image_config_value & ~(0xFFF);
- etdev_dbg(etdev, "Adding IOMMU mapping for firmware : %llu -> %08llX", tpu_addr,
+ etdev_dbg(etdev, "Adding IOMMU mapping for firmware : %#llx -> %#llx", tpu_addr,
phys_addr);
ret = edgetpu_mmu_add_translation(etdev, tpu_addr, phys_addr, size,
diff --git a/drivers/edgetpu/mobile-pm.c b/drivers/edgetpu/mobile-pm.c
index 186b425..b753231 100644
--- a/drivers/edgetpu/mobile-pm.c
+++ b/drivers/edgetpu/mobile-pm.c
@@ -63,6 +63,7 @@ static int mobile_pwr_state_init(struct device *dev)
if (curr_state > TPU_OFF) {
ret = pm_runtime_get_sync(dev);
if (ret) {
+ pm_runtime_put_noidle(dev);
dev_err(dev, "pm_runtime_get_sync returned %d\n", ret);
return ret;
}
@@ -235,6 +236,7 @@ static int mobile_pwr_state_set_locked(struct edgetpu_mobile_platform_dev *etmde
if (curr_state == TPU_OFF && val > TPU_OFF) {
ret = pm_runtime_get_sync(dev);
if (ret) {
+ pm_runtime_put_noidle(dev);
dev_err(dev, "pm_runtime_get_sync returned %d\n", ret);
return ret;
}
diff --git a/drivers/edgetpu/mobile-thermal.c b/drivers/edgetpu/mobile-thermal.c
index cf7dadf..c1b1f69 100644
--- a/drivers/edgetpu/mobile-thermal.c
+++ b/drivers/edgetpu/mobile-thermal.c
@@ -50,8 +50,7 @@ static int edgetpu_thermal_kci_if_powered(struct edgetpu_dev *etdev, enum edgetp
return ret;
}
-static int edgetpu_get_max_state(struct thermal_cooling_device *cdev,
- unsigned long *state)
+static int edgetpu_get_max_state(struct thermal_cooling_device *cdev, unsigned long *state)
{
struct edgetpu_thermal *thermal = cdev->devdata;
@@ -65,8 +64,7 @@ static int edgetpu_get_max_state(struct thermal_cooling_device *cdev,
/*
* Set cooling state.
*/
-static int edgetpu_set_cur_state(struct thermal_cooling_device *cdev,
- unsigned long state_original)
+static int edgetpu_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state_original)
{
int ret;
struct edgetpu_thermal *cooling = cdev->devdata;
@@ -74,8 +72,7 @@ static int edgetpu_set_cur_state(struct thermal_cooling_device *cdev,
unsigned long pwr_state;
if (state_original >= cooling->tpu_num_states) {
- dev_err(dev, "%s: invalid cooling state %lu\n", __func__,
- state_original);
+ dev_err(dev, "%s: invalid cooling state %lu\n", __func__, state_original);
return -EINVAL;
}
@@ -83,63 +80,61 @@ static int edgetpu_set_cur_state(struct thermal_cooling_device *cdev,
mutex_lock(&cooling->lock);
pwr_state = state_pwr_map[state_original].state;
- if (state_original != cooling->cooling_state) {
- /*
- * Set the thermal policy through ACPM to allow cooling by DVFS. Any states lower
- * than UUD should be handled by firmware when it gets the throttling notification
- * KCI
- */
- if (pwr_state < TPU_ACTIVE_UUD) {
- dev_warn_ratelimited(
- dev, "Setting lowest DVFS state, waiting for FW to shutdown TPU");
- ret = exynos_acpm_set_policy(TPU_ACPM_DOMAIN, TPU_ACTIVE_UUD);
- } else {
- ret = exynos_acpm_set_policy(TPU_ACPM_DOMAIN, pwr_state);
- }
+ if (state_original == cooling->cooling_state) {
+ ret = -EALREADY;
+ goto out;
+ }
- if (ret) {
- dev_err(dev, "error setting tpu policy: %d\n", ret);
- goto out;
- }
- cooling->cooling_state = state_original;
+ /*
+ * Set the thermal policy through ACPM to allow cooling by DVFS. Any states lower
+ * than UUD should be handled by firmware when it gets the throttling notification
+ * KCI
+ */
+ if (pwr_state < TPU_ACTIVE_UUD) {
+ dev_warn_ratelimited(dev,
+ "Setting lowest DVFS state, waiting for FW to shutdown TPU");
+ ret = exynos_acpm_set_policy(TPU_ACPM_DOMAIN, TPU_ACTIVE_UUD);
} else {
- ret = -EALREADY;
+ ret = exynos_acpm_set_policy(TPU_ACPM_DOMAIN, pwr_state);
}
+ if (ret) {
+ dev_err(dev, "error setting tpu policy: %d\n", ret);
+ goto out;
+ }
+ cooling->cooling_state = state_original;
out:
mutex_unlock(&cooling->lock);
return ret;
}
-static int edgetpu_get_cur_state(struct thermal_cooling_device *cdev,
- unsigned long *state)
+static int edgetpu_get_cur_state(struct thermal_cooling_device *cdev, unsigned long *state)
{
int ret = 0;
struct edgetpu_thermal *cooling = cdev->devdata;
*state = cooling->cooling_state;
- if (*state >= cooling->tpu_num_states) {
- dev_warn(cooling->dev,
- "Unknown cooling state: %lu, resetting\n", *state);
- mutex_lock(&cooling->lock);
+ if (*state < cooling->tpu_num_states)
+ return 0;
+
+ dev_warn(cooling->dev, "Unknown cooling state: %lu, resetting\n", *state);
+ mutex_lock(&cooling->lock);
#if IS_ENABLED(CONFIG_ABROLHOS)
- ret = exynos_acpm_set_policy(TPU_ACPM_DOMAIN, TPU_ACTIVE_OD);
+ ret = exynos_acpm_set_policy(TPU_ACPM_DOMAIN, TPU_ACTIVE_OD);
#else
- ret = exynos_acpm_set_policy(TPU_ACPM_DOMAIN, TPU_ACTIVE_NOM);
+ ret = exynos_acpm_set_policy(TPU_ACPM_DOMAIN, TPU_ACTIVE_NOM);
#endif /* IS_ENABLED(CONFIG_ABROLHOS) */
- if (ret) {
- dev_err(cooling->dev, "error setting tpu policy: %d\n",
- ret);
- mutex_unlock(&cooling->lock);
- return ret;
- }
-
- //setting back to "no cooling"
- cooling->cooling_state = 0;
+ if (ret) {
+ dev_err(cooling->dev, "error setting tpu policy: %d\n", ret);
mutex_unlock(&cooling->lock);
+ return ret;
}
+ /* setting back to "no cooling" */
+ cooling->cooling_state = 0;
+ mutex_unlock(&cooling->lock);
+
return 0;
}
@@ -169,8 +164,7 @@ static int edgetpu_get_requested_power(struct thermal_cooling_device *cdev,
struct edgetpu_thermal *cooling = cdev->devdata;
state_original = exynos_acpm_get_rate(TPU_ACPM_DOMAIN, 0);
- return edgetpu_state2power_internal(state_original, power,
- cooling);
+ return edgetpu_state2power_internal(state_original, power, cooling);
}
static int edgetpu_state2power(struct thermal_cooling_device *cdev,
@@ -182,13 +176,11 @@ static int edgetpu_state2power(struct thermal_cooling_device *cdev,
struct edgetpu_thermal *cooling = cdev->devdata;
if (state >= cooling->tpu_num_states) {
- dev_err(cooling->dev, "%s: invalid state: %lu\n", __func__,
- state);
+ dev_err(cooling->dev, "%s: invalid state: %lu\n", __func__, state);
return -EINVAL;
}
- return edgetpu_state2power_internal(state_pwr_map[state].state, power,
- cooling);
+ return edgetpu_state2power_internal(state_pwr_map[state].state, power, cooling);
}
static int edgetpu_power2state(struct thermal_cooling_device *cdev,
@@ -255,8 +247,8 @@ static int tpu_thermal_parse_dvfs_table(struct edgetpu_thermal *thermal)
int row_size, col_size, tbl_size, i;
int of_data_int_array[OF_DATA_NUM_MAX];
- if (of_property_read_u32_array(thermal->dev->of_node,
- "tpu_dvfs_table_size", of_data_int_array, 2))
+ if (of_property_read_u32_array(thermal->dev->of_node, "tpu_dvfs_table_size",
+ of_data_int_array, 2))
goto error;
row_size = of_data_int_array[0];
@@ -270,8 +262,8 @@ static int tpu_thermal_parse_dvfs_table(struct edgetpu_thermal *thermal)
if (tbl_size > OF_DATA_NUM_MAX)
goto error;
- if (of_property_read_u32_array(thermal->dev->of_node,
- "tpu_dvfs_table", of_data_int_array, tbl_size))
+ if (of_property_read_u32_array(thermal->dev->of_node, "tpu_dvfs_table", of_data_int_array,
+ tbl_size))
goto error;
thermal->tpu_num_states = row_size;
@@ -289,8 +281,7 @@ error:
return -EINVAL;
}
-static ssize_t
-user_vote_show(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t user_vote_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct thermal_cooling_device *cdev =
container_of(dev, struct thermal_cooling_device, device);
@@ -325,7 +316,12 @@ static ssize_t user_vote_store(struct device *dev, struct device_attribute *attr
cooling->sysfs_req = state;
cdev->updated = false;
mutex_unlock(&cdev->lock);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0)
thermal_cdev_update(cdev);
+#elif IS_ENABLED(CONFIG_THERMAL)
+ dev_err(dev, "Thermal update not implemented");
+#endif
return count;
}
@@ -347,8 +343,7 @@ static int tpu_pause_callback(enum thermal_pause_state action, void *dev)
return ret;
}
-static int
-tpu_thermal_cooling_register(struct edgetpu_thermal *thermal, char *type)
+static int tpu_thermal_cooling_register(struct edgetpu_thermal *thermal, char *type)
{
struct device_node *cooling_node = NULL;
int err = 0;
@@ -364,10 +359,10 @@ tpu_thermal_cooling_register(struct edgetpu_thermal *thermal, char *type)
cooling_node = of_find_node_by_name(NULL, "tpu-cooling");
if (!cooling_node)
dev_warn(thermal->dev, "failed to find cooling node\n");
- // Initialize the cooling state as 0, means "no cooling"
+ /* Initialize the cooling state as 0, means "no cooling" */
thermal->cooling_state = 0;
- thermal->cdev = thermal_of_cooling_device_register(
- cooling_node, type, thermal, &edgetpu_cooling_ops);
+ thermal->cdev = thermal_of_cooling_device_register(cooling_node, type, thermal,
+ &edgetpu_cooling_ops);
if (IS_ERR(thermal->cdev))
return PTR_ERR(thermal->cdev);
@@ -379,11 +374,11 @@ static int tpu_thermal_init(struct edgetpu_thermal *thermal, struct device *dev)
int err;
struct dentry *d;
+ thermal->dev = dev;
d = debugfs_create_dir("cooling", edgetpu_fs_debugfs_dir());
/* don't let debugfs creation failure abort the init procedure */
if (IS_ERR_OR_NULL(d))
dev_warn(dev, "failed to create debug fs for cooling");
- thermal->dev = dev;
thermal->cooling_root = d;
err = tpu_thermal_cooling_register(thermal, EDGETPU_COOLING_NAME);
@@ -398,14 +393,12 @@ static int tpu_thermal_init(struct edgetpu_thermal *thermal, struct device *dev)
return 0;
}
-struct edgetpu_thermal
-*devm_tpu_thermal_create(struct device *dev, struct edgetpu_dev *etdev)
+struct edgetpu_thermal *devm_tpu_thermal_create(struct device *dev, struct edgetpu_dev *etdev)
{
struct edgetpu_thermal *thermal;
int err;
- thermal = devres_alloc(devm_tpu_thermal_release, sizeof(*thermal),
- GFP_KERNEL);
+ thermal = devres_alloc(devm_tpu_thermal_release, sizeof(*thermal), GFP_KERNEL);
if (!thermal)
return ERR_PTR(-ENOMEM);