1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Abstract code for CPUFreq governor tunable sysfs attributes. 4 * 5 * Copyright (C) 2016, Intel Corporation 6 * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com> 7 */ 8 9 #include "cpufreq_governor.h" 10 11 static inline struct governor_attr *to_gov_attr(struct attribute *attr) 12 { 13 return container_of(attr, struct governor_attr, attr); 14 } 15 16 static ssize_t governor_show(struct kobject *kobj, struct attribute *attr, 17 char *buf) 18 { 19 struct governor_attr *gattr = to_gov_attr(attr); 20 21 return gattr->show(to_gov_attr_set(kobj), buf); 22 } 23 24 static ssize_t governor_store(struct kobject *kobj, struct attribute *attr, 25 const char *buf, size_t count) 26 { 27 struct gov_attr_set *attr_set = to_gov_attr_set(kobj); 28 struct governor_attr *gattr = to_gov_attr(attr); 29 int ret; 30 31 mutex_lock(&attr_set->update_lock); 32 ret = attr_set->usage_count ? gattr->store(attr_set, buf, count) : -EBUSY; 33 mutex_unlock(&attr_set->update_lock); 34 return ret; 35 } 36 37 const struct sysfs_ops governor_sysfs_ops = { 38 .show = governor_show, 39 .store = governor_store, 40 }; 41 EXPORT_SYMBOL_GPL(governor_sysfs_ops); 42 43 void gov_attr_set_init(struct gov_attr_set *attr_set, struct list_head *list_node) 44 { 45 INIT_LIST_HEAD(&attr_set->policy_list); 46 mutex_init(&attr_set->update_lock); 47 attr_set->usage_count = 1; 48 list_add(list_node, &attr_set->policy_list); 49 } 50 EXPORT_SYMBOL_GPL(gov_attr_set_init); 51 52 void gov_attr_set_get(struct gov_attr_set *attr_set, struct list_head *list_node) 53 { 54 mutex_lock(&attr_set->update_lock); 55 attr_set->usage_count++; 56 list_add(list_node, &attr_set->policy_list); 57 mutex_unlock(&attr_set->update_lock); 58 } 59 EXPORT_SYMBOL_GPL(gov_attr_set_get); 60 61 unsigned int gov_attr_set_put(struct gov_attr_set *attr_set, struct list_head *list_node) 62 { 63 unsigned int count; 64 65 mutex_lock(&attr_set->update_lock); 66 list_del(list_node); 67 count = --attr_set->usage_count; 68 mutex_unlock(&attr_set->update_lock); 69 if (count) 70 return count; 71 72 mutex_destroy(&attr_set->update_lock); 73 kobject_put(&attr_set->kobj); 74 return 0; 75 } 76 EXPORT_SYMBOL_GPL(gov_attr_set_put); 77