Loading drivers/thermal/msm_thermal-dev.c +100 −2 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ struct msm_thermal_ioctl_dev { static int msm_thermal_major; static struct class *thermal_class; static struct msm_thermal_ioctl_dev *msm_thermal_dev; static unsigned int freq_table_len[NR_CPUS], freq_table_set[NR_CPUS]; static unsigned int *freq_table_ptr[NR_CPUS]; static int msm_thermal_ioctl_open(struct inode *node, struct file *filep) { Loading Loading @@ -96,8 +98,6 @@ static long validate_and_copy(unsigned int *cmd, unsigned long *arg, } break; default: ret = -ENOTTY; goto validate_exit; break; } Loading @@ -105,6 +105,90 @@ validate_exit: return ret; } static long msm_thermal_process_freq_table_req(struct msm_thermal_ioctl *query, unsigned long *arg) { long ret = 0; uint32_t table_idx, idx = 0, cluster_id = query->clock_freq.cluster_num; struct clock_plan_arg *clock_freq = &(query->clock_freq); if (!freq_table_len[cluster_id]) { ret = msm_thermal_get_freq_plan_size(cluster_id, &freq_table_len[cluster_id]); if (ret) { pr_err("%s: Cluster%d freq table length get err:%ld\n", KBUILD_MODNAME, cluster_id, ret); goto process_freq_exit; } if (!freq_table_len[cluster_id]) { pr_err("%s: Cluster%d freq table empty\n", KBUILD_MODNAME, cluster_id); ret = -EAGAIN; goto process_freq_exit; } freq_table_set[cluster_id] = freq_table_len[cluster_id] / MSM_IOCTL_FREQ_SIZE; if (freq_table_len[cluster_id] % MSM_IOCTL_FREQ_SIZE) freq_table_set[cluster_id]++; if (!freq_table_ptr[cluster_id]) { freq_table_ptr[cluster_id] = kzalloc( sizeof(unsigned int) * freq_table_len[cluster_id], GFP_KERNEL); if (!freq_table_ptr[cluster_id]) { pr_err("%s: memory alloc failed\n", KBUILD_MODNAME); freq_table_len[cluster_id] = 0; ret = -ENOMEM; goto process_freq_exit; } } ret = msm_thermal_get_cluster_freq_plan(cluster_id, freq_table_ptr[cluster_id]); if (ret) { pr_err("%s: Error getting frequency table. err:%ld\n", KBUILD_MODNAME, ret); freq_table_len[cluster_id] = 0; freq_table_set[cluster_id] = 0; kfree(freq_table_ptr[cluster_id]); freq_table_ptr[cluster_id] = NULL; goto process_freq_exit; } } if (!clock_freq->freq_table_len) { clock_freq->freq_table_len = freq_table_len[cluster_id]; goto copy_and_return; } if (clock_freq->set_idx >= freq_table_set[cluster_id]) { pr_err("%s: Invalid freq table set%d for cluster%d\n", KBUILD_MODNAME, clock_freq->set_idx, cluster_id); ret = -EINVAL; goto process_freq_exit; } table_idx = MSM_IOCTL_FREQ_SIZE * clock_freq->set_idx; for (; table_idx < freq_table_len[cluster_id] && idx < MSM_IOCTL_FREQ_SIZE; idx++, table_idx++) { clock_freq->freq_table[idx] = freq_table_ptr[cluster_id][table_idx]; } clock_freq->freq_table_len = idx; copy_and_return: ret = copy_to_user((void __user *)(*arg), query, sizeof(struct msm_thermal_ioctl)); if (ret) { pr_err("%s: copy_to_user error:%ld.\n", KBUILD_MODNAME, ret); goto process_freq_exit; } process_freq_exit: return ret; } static long msm_thermal_ioctl_process(struct file *filep, unsigned int cmd, unsigned long arg) { Loading @@ -126,6 +210,17 @@ static long msm_thermal_ioctl_process(struct file *filep, unsigned int cmd, ret = msm_thermal_set_frequency(query.cpu_freq.cpu_num, query.cpu_freq.freq_req, false); break; case MSM_THERMAL_SET_CLUSTER_MAX_FREQUENCY: ret = msm_thermal_set_cluster_freq(query.cpu_freq.cpu_num, query.cpu_freq.freq_req, true); break; case MSM_THERMAL_SET_CLUSTER_MIN_FREQUENCY: ret = msm_thermal_set_cluster_freq(query.cpu_freq.cpu_num, query.cpu_freq.freq_req, false); break; case MSM_THERMAL_GET_CLUSTER_FREQUENCY_PLAN: ret = msm_thermal_process_freq_table_req(&query, &arg); break; default: ret = -ENOTTY; goto process_exit; Loading Loading @@ -218,6 +313,7 @@ ioctl_init_exit: void msm_thermal_ioctl_cleanup() { uint32_t idx = 0; dev_t thermal_dev = MKDEV(msm_thermal_major, 0); if (!msm_thermal_dev) { Loading @@ -226,6 +322,8 @@ void msm_thermal_ioctl_cleanup() return; } for (; idx < num_possible_cpus(); idx++) kfree(freq_table_ptr[idx]); device_destroy(thermal_class, thermal_dev); class_destroy(thermal_class); cdev_del(&msm_thermal_dev->char_dev); Loading drivers/thermal/msm_thermal.c +119 −0 Original line number Diff line number Diff line Loading @@ -2565,6 +2565,125 @@ init_freq_thread: } } int msm_thermal_get_freq_plan_size(uint32_t cluster, unsigned int *table_len) { uint32_t i = 0; struct cluster_info *cluster_ptr = NULL; if (!core_ptr) { pr_err("Topology ptr not initialized\n"); return -ENODEV; } if (!table_len) { pr_err("Invalid input\n"); return -EINVAL; } if (!freq_table_get) check_freq_table(); for (; i < core_ptr->entity_count; i++) { cluster_ptr = &core_ptr->child_entity_ptr[i]; if (cluster_ptr->cluster_id == cluster) { if (!cluster_ptr->freq_table) { pr_err("Cluster%d clock plan not initialized\n", cluster); return -EINVAL; } *table_len = cluster_ptr->freq_idx_high + 1; return 0; } } pr_err("Invalid cluster ID:%d\n", cluster); return -EINVAL; } int msm_thermal_get_cluster_freq_plan(uint32_t cluster, unsigned int *table_ptr) { uint32_t i = 0; struct cluster_info *cluster_ptr = NULL; if (!core_ptr) { pr_err("Topology ptr not initialized\n"); return -ENODEV; } if (!table_ptr) { pr_err("Invalid input\n"); return -EINVAL; } if (!freq_table_get) check_freq_table(); for (; i < core_ptr->entity_count; i++) { cluster_ptr = &core_ptr->child_entity_ptr[i]; if (cluster_ptr->cluster_id == cluster) break; } if (i == core_ptr->entity_count) { pr_err("Invalid cluster ID:%d\n", cluster); return -EINVAL; } if (!cluster_ptr->freq_table) { pr_err("Cluster%d clock plan not initialized\n", cluster); return -EINVAL; } for (i = 0; i <= cluster_ptr->freq_idx_high; i++) table_ptr[i] = cluster_ptr->freq_table[i].frequency; return 0; } int msm_thermal_set_cluster_freq(uint32_t cluster, uint32_t freq, bool is_max) { int ret = 0; uint32_t i = 0; struct cluster_info *cluster_ptr = NULL; bool notify = false; if (!core_ptr) { pr_err("Topology ptr not initialized\n"); return -ENODEV; } for (; i < core_ptr->entity_count; i++) { cluster_ptr = &core_ptr->child_entity_ptr[i]; if (cluster_ptr->cluster_id != cluster) continue; if (!cluster_ptr->sync_cluster) { pr_err("Cluster%d is not synchronous\n", cluster); return -EINVAL; } else { pr_debug("Update Cluster%d %s frequency to %d\n", cluster, (is_max) ? "max" : "min", freq); break; } } if (i == core_ptr->entity_count) { pr_err("Invalid cluster ID:%d\n", cluster); return -EINVAL; } for_each_cpu_mask(i, cluster_ptr->cluster_cores) { uint32_t *freq_ptr = (is_max) ? &cpus[i].user_max_freq : &cpus[i].user_min_freq; if (*freq_ptr == freq) continue; notify = true; *freq_ptr = freq; } if (freq_mitigation_task) { if (notify) complete(&freq_mitigation_complete); } else { pr_err("Frequency mitigation task is not initialized\n"); return -ESRCH; } return ret; } int msm_thermal_set_frequency(uint32_t cpu, uint32_t freq, bool is_max) { int ret = 0; Loading include/linux/msm_thermal.h +21 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,12 @@ extern int msm_thermal_init(struct msm_thermal_data *pdata); extern int msm_thermal_device_init(void); extern int msm_thermal_set_frequency(uint32_t cpu, uint32_t freq, bool is_max); extern int msm_thermal_set_cluster_freq(uint32_t cluster, uint32_t freq, bool is_max); extern int msm_thermal_get_freq_plan_size(uint32_t cluster, unsigned int *table_len); extern int msm_thermal_get_cluster_freq_plan(uint32_t cluster, unsigned int *table_ptr); #else static inline int msm_thermal_init(struct msm_thermal_data *pdata) { Loading @@ -74,6 +80,21 @@ static inline int msm_thermal_set_frequency(uint32_t cpu, uint32_t freq, { return -ENOSYS; } static inline int msm_thermal_set_cluster_freq(uint32_t cluster, uint32_t freq, bool is_max); { return -ENOSYS; } static inline int msm_thermal_get_freq_plan_size(uint32_t cluster, unsigned int *table_len); { return -ENOSYS; } static inline int msm_thermal_get_cluster_freq_plan(uint32_t cluster, unsigned int *table_ptr); { return -ENOSYS; } #endif #endif /*__MSM_THERMAL_H*/ include/uapi/linux/msm_thermal_ioctl.h +45 −0 Original line number Diff line number Diff line Loading @@ -4,16 +4,47 @@ #include <linux/ioctl.h> #define MSM_THERMAL_IOCTL_NAME "msm_thermal_query" #define MSM_IOCTL_FREQ_SIZE 16 struct __attribute__((__packed__)) cpu_freq_arg { uint32_t cpu_num; uint32_t freq_req; }; struct __attribute__((__packed__)) clock_plan_arg { uint32_t cluster_num; /* ** A value of zero for freq_table_len, will fetch the length of the ** cluster frequency table. A non-zero value will fetch the frequency ** table contents. */ uint32_t freq_table_len; /* ** For clusters with frequency table length greater than ** MSM_IOCTL_FREQ_SIZE, the frequency table is fetched from kernel ** in multiple sets or iterations. The set_idx variable, ** indicates, which set/part of frequency table the user is requesting. ** The set index value starts from zero. A set index value of 'Z', ** will fetch MSM_IOCTL_FREQ_SIZE or maximum available number of ** frequency values (if it is less than MSM_IOCTL_FREQ_SIZE) ** from the frequency table, starting from the index ** (Z * MSM_IOCTL_FREQ_SIZE). ** For example, in a device supporting 19 different frequencies, a set ** index value of 0 will fetch the first 16 (MSM_IOCTL_FREQ_SIZE) ** frequencies starting from the index 0 and a set value of 1 will fetch ** the remaining 3 frequencies starting from the index 16. ** A successful get, will populate the freq_table_len with the ** number of frequency table entries fetched. */ uint32_t set_idx; unsigned int freq_table[MSM_IOCTL_FREQ_SIZE]; }; struct __attribute__((__packed__)) msm_thermal_ioctl { uint32_t size; union { struct cpu_freq_arg cpu_freq; struct clock_plan_arg clock_freq; }; }; Loading @@ -21,6 +52,11 @@ enum { /*Set CPU Frequency*/ MSM_SET_CPU_MAX_FREQ = 0x00, MSM_SET_CPU_MIN_FREQ = 0x01, /*Set cluster frequency*/ MSM_SET_CLUSTER_MAX_FREQ = 0x02, MSM_SET_CLUSTER_MIN_FREQ = 0x03, /*Get cluster frequency plan*/ MSM_GET_CLUSTER_FREQ_PLAN = 0x04, MSM_CMD_MAX_NR, }; Loading @@ -33,6 +69,15 @@ enum { #define MSM_THERMAL_SET_CPU_MIN_FREQUENCY _IOW(MSM_THERMAL_MAGIC_NUM,\ MSM_SET_CPU_MIN_FREQ, struct msm_thermal_ioctl) #define MSM_THERMAL_SET_CLUSTER_MAX_FREQUENCY _IOW(MSM_THERMAL_MAGIC_NUM,\ MSM_SET_CLUSTER_MAX_FREQ, struct msm_thermal_ioctl) #define MSM_THERMAL_SET_CLUSTER_MIN_FREQUENCY _IOW(MSM_THERMAL_MAGIC_NUM,\ MSM_SET_CLUSTER_MIN_FREQ, struct msm_thermal_ioctl) #define MSM_THERMAL_GET_CLUSTER_FREQUENCY_PLAN _IOR(MSM_THERMAL_MAGIC_NUM,\ MSM_GET_CLUSTER_FREQ_PLAN, struct msm_thermal_ioctl) #ifdef __KERNEL__ extern int msm_thermal_ioctl_init(void); extern void msm_thermal_ioctl_cleanup(void); Loading Loading
drivers/thermal/msm_thermal-dev.c +100 −2 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ struct msm_thermal_ioctl_dev { static int msm_thermal_major; static struct class *thermal_class; static struct msm_thermal_ioctl_dev *msm_thermal_dev; static unsigned int freq_table_len[NR_CPUS], freq_table_set[NR_CPUS]; static unsigned int *freq_table_ptr[NR_CPUS]; static int msm_thermal_ioctl_open(struct inode *node, struct file *filep) { Loading Loading @@ -96,8 +98,6 @@ static long validate_and_copy(unsigned int *cmd, unsigned long *arg, } break; default: ret = -ENOTTY; goto validate_exit; break; } Loading @@ -105,6 +105,90 @@ validate_exit: return ret; } static long msm_thermal_process_freq_table_req(struct msm_thermal_ioctl *query, unsigned long *arg) { long ret = 0; uint32_t table_idx, idx = 0, cluster_id = query->clock_freq.cluster_num; struct clock_plan_arg *clock_freq = &(query->clock_freq); if (!freq_table_len[cluster_id]) { ret = msm_thermal_get_freq_plan_size(cluster_id, &freq_table_len[cluster_id]); if (ret) { pr_err("%s: Cluster%d freq table length get err:%ld\n", KBUILD_MODNAME, cluster_id, ret); goto process_freq_exit; } if (!freq_table_len[cluster_id]) { pr_err("%s: Cluster%d freq table empty\n", KBUILD_MODNAME, cluster_id); ret = -EAGAIN; goto process_freq_exit; } freq_table_set[cluster_id] = freq_table_len[cluster_id] / MSM_IOCTL_FREQ_SIZE; if (freq_table_len[cluster_id] % MSM_IOCTL_FREQ_SIZE) freq_table_set[cluster_id]++; if (!freq_table_ptr[cluster_id]) { freq_table_ptr[cluster_id] = kzalloc( sizeof(unsigned int) * freq_table_len[cluster_id], GFP_KERNEL); if (!freq_table_ptr[cluster_id]) { pr_err("%s: memory alloc failed\n", KBUILD_MODNAME); freq_table_len[cluster_id] = 0; ret = -ENOMEM; goto process_freq_exit; } } ret = msm_thermal_get_cluster_freq_plan(cluster_id, freq_table_ptr[cluster_id]); if (ret) { pr_err("%s: Error getting frequency table. err:%ld\n", KBUILD_MODNAME, ret); freq_table_len[cluster_id] = 0; freq_table_set[cluster_id] = 0; kfree(freq_table_ptr[cluster_id]); freq_table_ptr[cluster_id] = NULL; goto process_freq_exit; } } if (!clock_freq->freq_table_len) { clock_freq->freq_table_len = freq_table_len[cluster_id]; goto copy_and_return; } if (clock_freq->set_idx >= freq_table_set[cluster_id]) { pr_err("%s: Invalid freq table set%d for cluster%d\n", KBUILD_MODNAME, clock_freq->set_idx, cluster_id); ret = -EINVAL; goto process_freq_exit; } table_idx = MSM_IOCTL_FREQ_SIZE * clock_freq->set_idx; for (; table_idx < freq_table_len[cluster_id] && idx < MSM_IOCTL_FREQ_SIZE; idx++, table_idx++) { clock_freq->freq_table[idx] = freq_table_ptr[cluster_id][table_idx]; } clock_freq->freq_table_len = idx; copy_and_return: ret = copy_to_user((void __user *)(*arg), query, sizeof(struct msm_thermal_ioctl)); if (ret) { pr_err("%s: copy_to_user error:%ld.\n", KBUILD_MODNAME, ret); goto process_freq_exit; } process_freq_exit: return ret; } static long msm_thermal_ioctl_process(struct file *filep, unsigned int cmd, unsigned long arg) { Loading @@ -126,6 +210,17 @@ static long msm_thermal_ioctl_process(struct file *filep, unsigned int cmd, ret = msm_thermal_set_frequency(query.cpu_freq.cpu_num, query.cpu_freq.freq_req, false); break; case MSM_THERMAL_SET_CLUSTER_MAX_FREQUENCY: ret = msm_thermal_set_cluster_freq(query.cpu_freq.cpu_num, query.cpu_freq.freq_req, true); break; case MSM_THERMAL_SET_CLUSTER_MIN_FREQUENCY: ret = msm_thermal_set_cluster_freq(query.cpu_freq.cpu_num, query.cpu_freq.freq_req, false); break; case MSM_THERMAL_GET_CLUSTER_FREQUENCY_PLAN: ret = msm_thermal_process_freq_table_req(&query, &arg); break; default: ret = -ENOTTY; goto process_exit; Loading Loading @@ -218,6 +313,7 @@ ioctl_init_exit: void msm_thermal_ioctl_cleanup() { uint32_t idx = 0; dev_t thermal_dev = MKDEV(msm_thermal_major, 0); if (!msm_thermal_dev) { Loading @@ -226,6 +322,8 @@ void msm_thermal_ioctl_cleanup() return; } for (; idx < num_possible_cpus(); idx++) kfree(freq_table_ptr[idx]); device_destroy(thermal_class, thermal_dev); class_destroy(thermal_class); cdev_del(&msm_thermal_dev->char_dev); Loading
drivers/thermal/msm_thermal.c +119 −0 Original line number Diff line number Diff line Loading @@ -2565,6 +2565,125 @@ init_freq_thread: } } int msm_thermal_get_freq_plan_size(uint32_t cluster, unsigned int *table_len) { uint32_t i = 0; struct cluster_info *cluster_ptr = NULL; if (!core_ptr) { pr_err("Topology ptr not initialized\n"); return -ENODEV; } if (!table_len) { pr_err("Invalid input\n"); return -EINVAL; } if (!freq_table_get) check_freq_table(); for (; i < core_ptr->entity_count; i++) { cluster_ptr = &core_ptr->child_entity_ptr[i]; if (cluster_ptr->cluster_id == cluster) { if (!cluster_ptr->freq_table) { pr_err("Cluster%d clock plan not initialized\n", cluster); return -EINVAL; } *table_len = cluster_ptr->freq_idx_high + 1; return 0; } } pr_err("Invalid cluster ID:%d\n", cluster); return -EINVAL; } int msm_thermal_get_cluster_freq_plan(uint32_t cluster, unsigned int *table_ptr) { uint32_t i = 0; struct cluster_info *cluster_ptr = NULL; if (!core_ptr) { pr_err("Topology ptr not initialized\n"); return -ENODEV; } if (!table_ptr) { pr_err("Invalid input\n"); return -EINVAL; } if (!freq_table_get) check_freq_table(); for (; i < core_ptr->entity_count; i++) { cluster_ptr = &core_ptr->child_entity_ptr[i]; if (cluster_ptr->cluster_id == cluster) break; } if (i == core_ptr->entity_count) { pr_err("Invalid cluster ID:%d\n", cluster); return -EINVAL; } if (!cluster_ptr->freq_table) { pr_err("Cluster%d clock plan not initialized\n", cluster); return -EINVAL; } for (i = 0; i <= cluster_ptr->freq_idx_high; i++) table_ptr[i] = cluster_ptr->freq_table[i].frequency; return 0; } int msm_thermal_set_cluster_freq(uint32_t cluster, uint32_t freq, bool is_max) { int ret = 0; uint32_t i = 0; struct cluster_info *cluster_ptr = NULL; bool notify = false; if (!core_ptr) { pr_err("Topology ptr not initialized\n"); return -ENODEV; } for (; i < core_ptr->entity_count; i++) { cluster_ptr = &core_ptr->child_entity_ptr[i]; if (cluster_ptr->cluster_id != cluster) continue; if (!cluster_ptr->sync_cluster) { pr_err("Cluster%d is not synchronous\n", cluster); return -EINVAL; } else { pr_debug("Update Cluster%d %s frequency to %d\n", cluster, (is_max) ? "max" : "min", freq); break; } } if (i == core_ptr->entity_count) { pr_err("Invalid cluster ID:%d\n", cluster); return -EINVAL; } for_each_cpu_mask(i, cluster_ptr->cluster_cores) { uint32_t *freq_ptr = (is_max) ? &cpus[i].user_max_freq : &cpus[i].user_min_freq; if (*freq_ptr == freq) continue; notify = true; *freq_ptr = freq; } if (freq_mitigation_task) { if (notify) complete(&freq_mitigation_complete); } else { pr_err("Frequency mitigation task is not initialized\n"); return -ESRCH; } return ret; } int msm_thermal_set_frequency(uint32_t cpu, uint32_t freq, bool is_max) { int ret = 0; Loading
include/linux/msm_thermal.h +21 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,12 @@ extern int msm_thermal_init(struct msm_thermal_data *pdata); extern int msm_thermal_device_init(void); extern int msm_thermal_set_frequency(uint32_t cpu, uint32_t freq, bool is_max); extern int msm_thermal_set_cluster_freq(uint32_t cluster, uint32_t freq, bool is_max); extern int msm_thermal_get_freq_plan_size(uint32_t cluster, unsigned int *table_len); extern int msm_thermal_get_cluster_freq_plan(uint32_t cluster, unsigned int *table_ptr); #else static inline int msm_thermal_init(struct msm_thermal_data *pdata) { Loading @@ -74,6 +80,21 @@ static inline int msm_thermal_set_frequency(uint32_t cpu, uint32_t freq, { return -ENOSYS; } static inline int msm_thermal_set_cluster_freq(uint32_t cluster, uint32_t freq, bool is_max); { return -ENOSYS; } static inline int msm_thermal_get_freq_plan_size(uint32_t cluster, unsigned int *table_len); { return -ENOSYS; } static inline int msm_thermal_get_cluster_freq_plan(uint32_t cluster, unsigned int *table_ptr); { return -ENOSYS; } #endif #endif /*__MSM_THERMAL_H*/
include/uapi/linux/msm_thermal_ioctl.h +45 −0 Original line number Diff line number Diff line Loading @@ -4,16 +4,47 @@ #include <linux/ioctl.h> #define MSM_THERMAL_IOCTL_NAME "msm_thermal_query" #define MSM_IOCTL_FREQ_SIZE 16 struct __attribute__((__packed__)) cpu_freq_arg { uint32_t cpu_num; uint32_t freq_req; }; struct __attribute__((__packed__)) clock_plan_arg { uint32_t cluster_num; /* ** A value of zero for freq_table_len, will fetch the length of the ** cluster frequency table. A non-zero value will fetch the frequency ** table contents. */ uint32_t freq_table_len; /* ** For clusters with frequency table length greater than ** MSM_IOCTL_FREQ_SIZE, the frequency table is fetched from kernel ** in multiple sets or iterations. The set_idx variable, ** indicates, which set/part of frequency table the user is requesting. ** The set index value starts from zero. A set index value of 'Z', ** will fetch MSM_IOCTL_FREQ_SIZE or maximum available number of ** frequency values (if it is less than MSM_IOCTL_FREQ_SIZE) ** from the frequency table, starting from the index ** (Z * MSM_IOCTL_FREQ_SIZE). ** For example, in a device supporting 19 different frequencies, a set ** index value of 0 will fetch the first 16 (MSM_IOCTL_FREQ_SIZE) ** frequencies starting from the index 0 and a set value of 1 will fetch ** the remaining 3 frequencies starting from the index 16. ** A successful get, will populate the freq_table_len with the ** number of frequency table entries fetched. */ uint32_t set_idx; unsigned int freq_table[MSM_IOCTL_FREQ_SIZE]; }; struct __attribute__((__packed__)) msm_thermal_ioctl { uint32_t size; union { struct cpu_freq_arg cpu_freq; struct clock_plan_arg clock_freq; }; }; Loading @@ -21,6 +52,11 @@ enum { /*Set CPU Frequency*/ MSM_SET_CPU_MAX_FREQ = 0x00, MSM_SET_CPU_MIN_FREQ = 0x01, /*Set cluster frequency*/ MSM_SET_CLUSTER_MAX_FREQ = 0x02, MSM_SET_CLUSTER_MIN_FREQ = 0x03, /*Get cluster frequency plan*/ MSM_GET_CLUSTER_FREQ_PLAN = 0x04, MSM_CMD_MAX_NR, }; Loading @@ -33,6 +69,15 @@ enum { #define MSM_THERMAL_SET_CPU_MIN_FREQUENCY _IOW(MSM_THERMAL_MAGIC_NUM,\ MSM_SET_CPU_MIN_FREQ, struct msm_thermal_ioctl) #define MSM_THERMAL_SET_CLUSTER_MAX_FREQUENCY _IOW(MSM_THERMAL_MAGIC_NUM,\ MSM_SET_CLUSTER_MAX_FREQ, struct msm_thermal_ioctl) #define MSM_THERMAL_SET_CLUSTER_MIN_FREQUENCY _IOW(MSM_THERMAL_MAGIC_NUM,\ MSM_SET_CLUSTER_MIN_FREQ, struct msm_thermal_ioctl) #define MSM_THERMAL_GET_CLUSTER_FREQUENCY_PLAN _IOR(MSM_THERMAL_MAGIC_NUM,\ MSM_GET_CLUSTER_FREQ_PLAN, struct msm_thermal_ioctl) #ifdef __KERNEL__ extern int msm_thermal_ioctl_init(void); extern void msm_thermal_ioctl_cleanup(void); Loading