Loading drivers/cpuidle/lpm-levels-of.c +233 −1 Original line number Diff line number Diff line Loading @@ -15,12 +15,245 @@ #include <linux/slab.h> #include <linux/of.h> #include <linux/err.h> #include <linux/sysfs.h> #include <linux/device.h> #include <linux/platform_device.h> #include <linux/moduleparam.h> #include "lpm-levels.h" enum lpm_type { IDLE = 0, SUSPEND, LPM_TYPE_NR }; struct lpm_type_str { enum lpm_type type; char *str; }; static const struct lpm_type_str lpm_types[] = { {IDLE, "idle_enabled"}, {SUSPEND, "suspend_enabled"}, }; static struct lpm_level_avail *cpu_level_available[NR_CPUS]; static struct platform_device *lpm_pdev; static void *get_avail_val(struct kobject *kobj, struct kobj_attribute *attr) { void *arg = NULL; struct lpm_level_avail *avail = NULL; if (!strcmp(attr->attr.name, lpm_types[IDLE].str)) { avail = container_of(attr, struct lpm_level_avail, idle_enabled_attr); arg = (void *) &avail->idle_enabled; } else if (!strcmp(attr->attr.name, lpm_types[SUSPEND].str)) { avail = container_of(attr, struct lpm_level_avail, suspend_enabled_attr); arg = (void *) &avail->suspend_enabled; } return arg; } ssize_t lpm_enable_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { int ret = 0; struct kernel_param kp; kp.arg = get_avail_val(kobj, attr); ret = param_get_bool(buf, &kp); if (ret > 0) { strlcat(buf, "\n", PAGE_SIZE); ret++; } return ret; } ssize_t lpm_enable_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t len) { int ret = 0; struct kernel_param kp; kp.arg = get_avail_val(kobj, attr); ret = param_set_bool(buf, &kp); return ret ? ret : len; } static int create_lvl_avail_nodes(const char *name, struct kobject *parent, struct lpm_level_avail *avail) { struct attribute_group *attr_group = NULL; struct attribute **attr = NULL; struct kobject *kobj = NULL; int ret = 0; kobj = kobject_create_and_add(name, parent); if (!kobj) return -ENOMEM; attr_group = devm_kzalloc(&lpm_pdev->dev, sizeof(*attr_group), GFP_KERNEL); if (!attr_group) { ret = -ENOMEM; goto failed; } attr = devm_kzalloc(&lpm_pdev->dev, sizeof(*attr) * (LPM_TYPE_NR + 1), GFP_KERNEL); if (!attr) { ret = -ENOMEM; goto failed; } avail->idle_enabled_attr.attr.name = lpm_types[IDLE].str; avail->idle_enabled_attr.attr.mode = 0644; avail->idle_enabled_attr.show = lpm_enable_show; avail->idle_enabled_attr.store = lpm_enable_store; avail->suspend_enabled_attr.attr.name = lpm_types[SUSPEND].str; avail->suspend_enabled_attr.attr.mode = 0644; avail->suspend_enabled_attr.show = lpm_enable_show; avail->suspend_enabled_attr.store = lpm_enable_store; attr[0] = &avail->idle_enabled_attr.attr; attr[1] = &avail->suspend_enabled_attr.attr; attr[2] = NULL; attr_group->attrs = attr; ret = sysfs_create_group(kobj, attr_group); if (ret) { ret = -ENOMEM; goto failed; } avail->idle_enabled = true; avail->suspend_enabled = true; avail->kobj = kobj; return ret; failed: kobject_put(kobj); return ret; } static int create_cpu_lvl_nodes(struct lpm_cluster *p, struct kobject *parent) { int cpu; int i, j; struct kobject **cpu_kobj = NULL; struct lpm_level_avail *level_list = NULL; char cpu_name[20] = {0}; int ret = 0; cpu_kobj = devm_kzalloc(&lpm_pdev->dev, sizeof(*cpu_kobj) * cpumask_weight(&p->child_cpus), GFP_KERNEL); if (!cpu_kobj) return -ENOMEM; for_each_cpu(cpu, &p->child_cpus) { snprintf(cpu_name, sizeof(cpu_name), "cpu%d", cpu); cpu_kobj[cpu] = kobject_create_and_add(cpu_name, parent); if (!cpu_kobj[cpu]) return -ENOMEM; level_list = devm_kzalloc(&lpm_pdev->dev, MSM_PM_SLEEP_MODE_NR * sizeof(*level_list), GFP_KERNEL); if (!level_list) return -ENOMEM; for (i = 0; i < MSM_PM_SLEEP_MODE_NR; i++) { for (j = 0; j < p->cpu->nlevels; j++) if (p->cpu->levels[j].mode == i) break; if (j == p->cpu->nlevels) { /* Level not defined in DT */ level_list[i].idle_enabled = false; level_list[i].suspend_enabled = false; continue; } ret = create_lvl_avail_nodes(p->cpu->levels[j].name, cpu_kobj[cpu], &level_list[i]); if (ret) return ret; } cpu_level_available[cpu] = level_list; } return 0; } int create_cluster_lvl_nodes(struct lpm_cluster *p, struct kobject *kobj) { int ret = 0; struct lpm_cluster *child = NULL; int i; struct kobject *cluster_kobj = NULL; if (!p) return -ENODEV; cluster_kobj = kobject_create_and_add(p->cluster_name, kobj); if (!cluster_kobj) return -ENOMEM; for (i = 0; i < p->nlevels; i++) { ret = create_lvl_avail_nodes(p->levels[i].level_name, cluster_kobj, &p->levels[i].available); if (ret) return ret; } list_for_each_entry(child, &p->child, list) { ret = create_cluster_lvl_nodes(child, cluster_kobj); if (ret) return ret; } if (p->cpu) { ret = create_cpu_lvl_nodes(p, cluster_kobj); if (ret) return ret; } return 0; } bool lpm_cpu_mode_allow(unsigned int cpu, unsigned int mode, bool from_idle) { struct lpm_level_avail *avail = cpu_level_available[cpu]; if (!lpm_pdev || !avail) return !from_idle; return !!(from_idle ? avail[mode].idle_enabled : avail[mode].suspend_enabled); } bool lpm_cluster_mode_allow(struct lpm_cluster *cluster, unsigned int mode, bool from_idle) { struct lpm_level_avail *avail = &cluster->levels[mode].available; if (!lpm_pdev || !avail) return false; return !!(from_idle ? avail->idle_enabled : avail->suspend_enabled); } static int parse_cluster_params(struct device_node *node, struct lpm_cluster *c) { int i; Loading Loading @@ -194,7 +427,6 @@ static int parse_cluster_level(struct device_node *node, cluster->min_child_level = level->min_child_level; } level->available = true; level->notify_rpm = of_property_read_bool(node, "qcom,notify-rpm"); level->last_core_only = of_property_read_bool(node, "qcom,last-core-only"); Loading drivers/cpuidle/lpm-levels.c +24 −6 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include <linux/msm_remote_spinlock.h> #include <linux/dma-mapping.h> #include <linux/coresight-cti.h> #include <linux/moduleparam.h> #include <soc/qcom/spm.h> #include <soc/qcom/pm.h> #include <soc/qcom/rpm-notifier.h> Loading Loading @@ -68,7 +69,8 @@ struct lpm_debug { uint32_t arg4; }; static struct lpm_cluster *lpm_root_node; struct lpm_cluster *lpm_root_node; static DEFINE_PER_CPU(struct lpm_cluster*, cpu_cluster); static bool suspend_in_progress; static struct hrtimer lpm_hrtimer; Loading Loading @@ -253,7 +255,7 @@ static int cpu_power_select(struct cpuidle_device *dev, enum msm_pm_sleep_mode mode = level->mode; bool allow; allow = msm_pm_sleep_mode_allow(dev->cpu, mode, true); allow = lpm_cpu_mode_allow(dev->cpu, mode, true); if (!allow) continue; Loading Loading @@ -374,7 +376,7 @@ static int cluster_select(struct lpm_cluster *cluster, bool from_idle) struct lpm_cluster_level *level = &cluster->levels[i]; struct power_params *pwr_params = &level->pwr; if (!level->available) if (!lpm_cluster_mode_allow(cluster, i, from_idle)) continue; if (level->last_core_only && Loading Loading @@ -801,7 +803,7 @@ static int lpm_suspend_enter(suspend_state_t state) for (idx = lpm_cpu->nlevels - 1; idx >= 0; idx--) { struct lpm_cpu_level *level = &lpm_cpu->levels[idx]; if (msm_pm_sleep_mode_allow(cpu, level->mode, false)) if (lpm_cpu_mode_allow(cpu, level->mode, false)) break; } if (idx < 0) { Loading Loading @@ -829,6 +831,7 @@ static int lpm_probe(struct platform_device *pdev) int size; struct lpm_cluster *p = NULL; int cpu; struct kobject *module_kobj = NULL; lpm_root_node = lpm_of_parse_cluster(pdev); Loading Loading @@ -884,6 +887,21 @@ static int lpm_probe(struct platform_device *pdev) goto failed; } module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME); if (!module_kobj) { pr_err("%s: cannot find kobject for module %s\n", __func__, KBUILD_MODNAME); ret = -ENOENT; goto failed; } ret = create_cluster_lvl_nodes(lpm_root_node, module_kobj); if (ret) { pr_err("%s(): Failed to create cluster level nodes\n", __func__); goto failed; } return 0; failed: free_cluster_node(lpm_root_node); Loading Loading @@ -972,10 +990,10 @@ void lpm_cpu_hotplug_enter(unsigned int cpu) int i; int idx = -1; if (msm_pm_sleep_mode_allow(cpu, MSM_PM_SLEEP_MODE_POWER_COLLAPSE, if (lpm_cpu_mode_allow(cpu, MSM_PM_SLEEP_MODE_POWER_COLLAPSE, false)) mode = MSM_PM_SLEEP_MODE_POWER_COLLAPSE; else if (msm_pm_sleep_mode_allow(cpu, else if (lpm_cpu_mode_allow(cpu, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE, false)) mode = MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE; else Loading drivers/cpuidle/lpm-levels.h +17 −1 Original line number Diff line number Diff line Loading @@ -40,6 +40,14 @@ struct lpm_cpu { struct lpm_cluster *parent; }; struct lpm_level_avail { bool idle_enabled; bool suspend_enabled; struct kobject *kobj; struct kobj_attribute idle_enabled_attr; struct kobj_attribute suspend_enabled_attr; }; struct lpm_cluster_level { const char *level_name; int *mode; /* SPM mode to enter */ Loading @@ -47,9 +55,9 @@ struct lpm_cluster_level { struct cpumask num_cpu_votes; struct power_params pwr; bool notify_rpm; bool available; bool sync_level; bool last_core_only; struct lpm_level_avail available; }; struct low_power_ops { Loading Loading @@ -87,3 +95,11 @@ int set_cci_mode(struct low_power_ops *ops, int mode, bool notify_rpm); struct lpm_cluster *lpm_of_parse_cluster(struct platform_device *pdev); void free_cluster_node(struct lpm_cluster *cluster); void cluster_dt_walkthrough(struct lpm_cluster *cluster); int create_cluster_lvl_nodes(struct lpm_cluster *p, struct kobject *kobj); bool lpm_cpu_mode_allow(unsigned int cpu, unsigned int mode, bool from_idle); bool lpm_cluster_mode_allow(struct lpm_cluster *cluster, unsigned int mode, bool from_idle); extern struct lpm_cluster *lpm_root_node; drivers/power/qcom/msm-pm.c +0 −1 Original line number Diff line number Diff line Loading @@ -839,7 +839,6 @@ static int msm_cpu_pm_probe(struct platform_device *pdev) } } msm_pm_mode_sysfs_add(KBUILD_MODNAME); if (pdev->dev.of_node) of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); Loading include/soc/qcom/pm.h +0 −2 Original line number Diff line number Diff line Loading @@ -61,8 +61,6 @@ struct msm_pm_sleep_status_data { uint32_t mask; }; int msm_pm_mode_sysfs_add(const char *); /** * lpm_cpu_pre_pc_cb(): API to get the L2 flag to pass to TZ * Loading Loading
drivers/cpuidle/lpm-levels-of.c +233 −1 Original line number Diff line number Diff line Loading @@ -15,12 +15,245 @@ #include <linux/slab.h> #include <linux/of.h> #include <linux/err.h> #include <linux/sysfs.h> #include <linux/device.h> #include <linux/platform_device.h> #include <linux/moduleparam.h> #include "lpm-levels.h" enum lpm_type { IDLE = 0, SUSPEND, LPM_TYPE_NR }; struct lpm_type_str { enum lpm_type type; char *str; }; static const struct lpm_type_str lpm_types[] = { {IDLE, "idle_enabled"}, {SUSPEND, "suspend_enabled"}, }; static struct lpm_level_avail *cpu_level_available[NR_CPUS]; static struct platform_device *lpm_pdev; static void *get_avail_val(struct kobject *kobj, struct kobj_attribute *attr) { void *arg = NULL; struct lpm_level_avail *avail = NULL; if (!strcmp(attr->attr.name, lpm_types[IDLE].str)) { avail = container_of(attr, struct lpm_level_avail, idle_enabled_attr); arg = (void *) &avail->idle_enabled; } else if (!strcmp(attr->attr.name, lpm_types[SUSPEND].str)) { avail = container_of(attr, struct lpm_level_avail, suspend_enabled_attr); arg = (void *) &avail->suspend_enabled; } return arg; } ssize_t lpm_enable_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { int ret = 0; struct kernel_param kp; kp.arg = get_avail_val(kobj, attr); ret = param_get_bool(buf, &kp); if (ret > 0) { strlcat(buf, "\n", PAGE_SIZE); ret++; } return ret; } ssize_t lpm_enable_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t len) { int ret = 0; struct kernel_param kp; kp.arg = get_avail_val(kobj, attr); ret = param_set_bool(buf, &kp); return ret ? ret : len; } static int create_lvl_avail_nodes(const char *name, struct kobject *parent, struct lpm_level_avail *avail) { struct attribute_group *attr_group = NULL; struct attribute **attr = NULL; struct kobject *kobj = NULL; int ret = 0; kobj = kobject_create_and_add(name, parent); if (!kobj) return -ENOMEM; attr_group = devm_kzalloc(&lpm_pdev->dev, sizeof(*attr_group), GFP_KERNEL); if (!attr_group) { ret = -ENOMEM; goto failed; } attr = devm_kzalloc(&lpm_pdev->dev, sizeof(*attr) * (LPM_TYPE_NR + 1), GFP_KERNEL); if (!attr) { ret = -ENOMEM; goto failed; } avail->idle_enabled_attr.attr.name = lpm_types[IDLE].str; avail->idle_enabled_attr.attr.mode = 0644; avail->idle_enabled_attr.show = lpm_enable_show; avail->idle_enabled_attr.store = lpm_enable_store; avail->suspend_enabled_attr.attr.name = lpm_types[SUSPEND].str; avail->suspend_enabled_attr.attr.mode = 0644; avail->suspend_enabled_attr.show = lpm_enable_show; avail->suspend_enabled_attr.store = lpm_enable_store; attr[0] = &avail->idle_enabled_attr.attr; attr[1] = &avail->suspend_enabled_attr.attr; attr[2] = NULL; attr_group->attrs = attr; ret = sysfs_create_group(kobj, attr_group); if (ret) { ret = -ENOMEM; goto failed; } avail->idle_enabled = true; avail->suspend_enabled = true; avail->kobj = kobj; return ret; failed: kobject_put(kobj); return ret; } static int create_cpu_lvl_nodes(struct lpm_cluster *p, struct kobject *parent) { int cpu; int i, j; struct kobject **cpu_kobj = NULL; struct lpm_level_avail *level_list = NULL; char cpu_name[20] = {0}; int ret = 0; cpu_kobj = devm_kzalloc(&lpm_pdev->dev, sizeof(*cpu_kobj) * cpumask_weight(&p->child_cpus), GFP_KERNEL); if (!cpu_kobj) return -ENOMEM; for_each_cpu(cpu, &p->child_cpus) { snprintf(cpu_name, sizeof(cpu_name), "cpu%d", cpu); cpu_kobj[cpu] = kobject_create_and_add(cpu_name, parent); if (!cpu_kobj[cpu]) return -ENOMEM; level_list = devm_kzalloc(&lpm_pdev->dev, MSM_PM_SLEEP_MODE_NR * sizeof(*level_list), GFP_KERNEL); if (!level_list) return -ENOMEM; for (i = 0; i < MSM_PM_SLEEP_MODE_NR; i++) { for (j = 0; j < p->cpu->nlevels; j++) if (p->cpu->levels[j].mode == i) break; if (j == p->cpu->nlevels) { /* Level not defined in DT */ level_list[i].idle_enabled = false; level_list[i].suspend_enabled = false; continue; } ret = create_lvl_avail_nodes(p->cpu->levels[j].name, cpu_kobj[cpu], &level_list[i]); if (ret) return ret; } cpu_level_available[cpu] = level_list; } return 0; } int create_cluster_lvl_nodes(struct lpm_cluster *p, struct kobject *kobj) { int ret = 0; struct lpm_cluster *child = NULL; int i; struct kobject *cluster_kobj = NULL; if (!p) return -ENODEV; cluster_kobj = kobject_create_and_add(p->cluster_name, kobj); if (!cluster_kobj) return -ENOMEM; for (i = 0; i < p->nlevels; i++) { ret = create_lvl_avail_nodes(p->levels[i].level_name, cluster_kobj, &p->levels[i].available); if (ret) return ret; } list_for_each_entry(child, &p->child, list) { ret = create_cluster_lvl_nodes(child, cluster_kobj); if (ret) return ret; } if (p->cpu) { ret = create_cpu_lvl_nodes(p, cluster_kobj); if (ret) return ret; } return 0; } bool lpm_cpu_mode_allow(unsigned int cpu, unsigned int mode, bool from_idle) { struct lpm_level_avail *avail = cpu_level_available[cpu]; if (!lpm_pdev || !avail) return !from_idle; return !!(from_idle ? avail[mode].idle_enabled : avail[mode].suspend_enabled); } bool lpm_cluster_mode_allow(struct lpm_cluster *cluster, unsigned int mode, bool from_idle) { struct lpm_level_avail *avail = &cluster->levels[mode].available; if (!lpm_pdev || !avail) return false; return !!(from_idle ? avail->idle_enabled : avail->suspend_enabled); } static int parse_cluster_params(struct device_node *node, struct lpm_cluster *c) { int i; Loading Loading @@ -194,7 +427,6 @@ static int parse_cluster_level(struct device_node *node, cluster->min_child_level = level->min_child_level; } level->available = true; level->notify_rpm = of_property_read_bool(node, "qcom,notify-rpm"); level->last_core_only = of_property_read_bool(node, "qcom,last-core-only"); Loading
drivers/cpuidle/lpm-levels.c +24 −6 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include <linux/msm_remote_spinlock.h> #include <linux/dma-mapping.h> #include <linux/coresight-cti.h> #include <linux/moduleparam.h> #include <soc/qcom/spm.h> #include <soc/qcom/pm.h> #include <soc/qcom/rpm-notifier.h> Loading Loading @@ -68,7 +69,8 @@ struct lpm_debug { uint32_t arg4; }; static struct lpm_cluster *lpm_root_node; struct lpm_cluster *lpm_root_node; static DEFINE_PER_CPU(struct lpm_cluster*, cpu_cluster); static bool suspend_in_progress; static struct hrtimer lpm_hrtimer; Loading Loading @@ -253,7 +255,7 @@ static int cpu_power_select(struct cpuidle_device *dev, enum msm_pm_sleep_mode mode = level->mode; bool allow; allow = msm_pm_sleep_mode_allow(dev->cpu, mode, true); allow = lpm_cpu_mode_allow(dev->cpu, mode, true); if (!allow) continue; Loading Loading @@ -374,7 +376,7 @@ static int cluster_select(struct lpm_cluster *cluster, bool from_idle) struct lpm_cluster_level *level = &cluster->levels[i]; struct power_params *pwr_params = &level->pwr; if (!level->available) if (!lpm_cluster_mode_allow(cluster, i, from_idle)) continue; if (level->last_core_only && Loading Loading @@ -801,7 +803,7 @@ static int lpm_suspend_enter(suspend_state_t state) for (idx = lpm_cpu->nlevels - 1; idx >= 0; idx--) { struct lpm_cpu_level *level = &lpm_cpu->levels[idx]; if (msm_pm_sleep_mode_allow(cpu, level->mode, false)) if (lpm_cpu_mode_allow(cpu, level->mode, false)) break; } if (idx < 0) { Loading Loading @@ -829,6 +831,7 @@ static int lpm_probe(struct platform_device *pdev) int size; struct lpm_cluster *p = NULL; int cpu; struct kobject *module_kobj = NULL; lpm_root_node = lpm_of_parse_cluster(pdev); Loading Loading @@ -884,6 +887,21 @@ static int lpm_probe(struct platform_device *pdev) goto failed; } module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME); if (!module_kobj) { pr_err("%s: cannot find kobject for module %s\n", __func__, KBUILD_MODNAME); ret = -ENOENT; goto failed; } ret = create_cluster_lvl_nodes(lpm_root_node, module_kobj); if (ret) { pr_err("%s(): Failed to create cluster level nodes\n", __func__); goto failed; } return 0; failed: free_cluster_node(lpm_root_node); Loading Loading @@ -972,10 +990,10 @@ void lpm_cpu_hotplug_enter(unsigned int cpu) int i; int idx = -1; if (msm_pm_sleep_mode_allow(cpu, MSM_PM_SLEEP_MODE_POWER_COLLAPSE, if (lpm_cpu_mode_allow(cpu, MSM_PM_SLEEP_MODE_POWER_COLLAPSE, false)) mode = MSM_PM_SLEEP_MODE_POWER_COLLAPSE; else if (msm_pm_sleep_mode_allow(cpu, else if (lpm_cpu_mode_allow(cpu, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE, false)) mode = MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE; else Loading
drivers/cpuidle/lpm-levels.h +17 −1 Original line number Diff line number Diff line Loading @@ -40,6 +40,14 @@ struct lpm_cpu { struct lpm_cluster *parent; }; struct lpm_level_avail { bool idle_enabled; bool suspend_enabled; struct kobject *kobj; struct kobj_attribute idle_enabled_attr; struct kobj_attribute suspend_enabled_attr; }; struct lpm_cluster_level { const char *level_name; int *mode; /* SPM mode to enter */ Loading @@ -47,9 +55,9 @@ struct lpm_cluster_level { struct cpumask num_cpu_votes; struct power_params pwr; bool notify_rpm; bool available; bool sync_level; bool last_core_only; struct lpm_level_avail available; }; struct low_power_ops { Loading Loading @@ -87,3 +95,11 @@ int set_cci_mode(struct low_power_ops *ops, int mode, bool notify_rpm); struct lpm_cluster *lpm_of_parse_cluster(struct platform_device *pdev); void free_cluster_node(struct lpm_cluster *cluster); void cluster_dt_walkthrough(struct lpm_cluster *cluster); int create_cluster_lvl_nodes(struct lpm_cluster *p, struct kobject *kobj); bool lpm_cpu_mode_allow(unsigned int cpu, unsigned int mode, bool from_idle); bool lpm_cluster_mode_allow(struct lpm_cluster *cluster, unsigned int mode, bool from_idle); extern struct lpm_cluster *lpm_root_node;
drivers/power/qcom/msm-pm.c +0 −1 Original line number Diff line number Diff line Loading @@ -839,7 +839,6 @@ static int msm_cpu_pm_probe(struct platform_device *pdev) } } msm_pm_mode_sysfs_add(KBUILD_MODNAME); if (pdev->dev.of_node) of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); Loading
include/soc/qcom/pm.h +0 −2 Original line number Diff line number Diff line Loading @@ -61,8 +61,6 @@ struct msm_pm_sleep_status_data { uint32_t mask; }; int msm_pm_mode_sysfs_add(const char *); /** * lpm_cpu_pre_pc_cb(): API to get the L2 flag to pass to TZ * Loading