int tegra_dvfs_core_cap_level_apply(int level) { int ret = 0; mutex_lock(&core_cap_lock); if (level) { if (kdvfs_core_cap.refcnt) { pr_err("%s: core cap is already set\n", __func__); ret = -EPERM; } else { kdvfs_core_cap.level = level; kdvfs_core_cap.refcnt = 1; ret = core_cap_enable(true); if (ret) { kdvfs_core_cap.refcnt = 0; core_cap_enable(false); } } } else if (kdvfs_core_cap.refcnt) { kdvfs_core_cap.refcnt = 0; core_cap_enable(false); } mutex_unlock(&core_cap_lock); return ret; }
void tegra_dvfs_core_cap_enable(bool enable) { mutex_lock(&core_cap_lock); if (enable) { kdvfs_core_cap.refcnt++; if (kdvfs_core_cap.refcnt == 1) core_cap_enable(true); } else if (kdvfs_core_cap.refcnt) { kdvfs_core_cap.refcnt--; if (kdvfs_core_cap.refcnt == 0) core_cap_enable(false); } mutex_unlock(&core_cap_lock); }
static ssize_t core_cap_state_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { int state; if (sscanf(buf, "%d", &state) != 1) return -1; mutex_lock(&core_cap_lock); if (state) { user_core_cap.refcnt++; if (user_core_cap.refcnt == 1) core_cap_enable(true); } else if (user_core_cap.refcnt) { user_core_cap.refcnt--; if (user_core_cap.refcnt == 0) core_cap_enable(false); } mutex_unlock(&core_cap_lock); return count; }