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 gov_attr_set *to_gov_attr_set(struct kobject *kobj) 12 { 13 return container_of(kobj, struct gov_attr_set, kobj); 14 } 15 16 static inline struct governor_attr *to_gov_attr(struct attribute *attr) 17 { 18 return container_of(attr, struct governor_attr, attr); 19 } 20 21 static ssize_t governor_show(struct kobject *kobj, struct attribute *attr, 22 char *buf) 23 { 24 struct governor_attr *gattr = to_gov_attr(attr); 25 26 return gattr->show(to_gov_attr_set(kobj), buf); 27 } 28 29 static ssize_t governor_store(struct kobject *kobj, struct attribute *attr, 30 const char *buf, size_t count) 31 { 32 struct gov_attr_set *attr_set = to_gov_attr_set(kobj); 33 struct governor_attr *gattr = to_gov_attr(attr); 34 int ret; 35 36 mutex_lock(&attr_set->update_lock); 37 ret = attr_set->usage_count ? gattr->store(attr_set, buf, count) : -EBUSY; 38 mutex_unlock(&attr_set->update_lock); 39 return ret; 40 } 41 42 const struct sysfs_ops governor_sysfs_ops = { 43 .show = governor_show, 44 .store = governor_store, 45 }; 46 EXPORT_SYMBOL_GPL(governor_sysfs_ops); 47 48 void gov_attr_set_init(struct gov_attr_set *attr_set, struct list_head *list_node) 49 { 50 INIT_LIST_HEAD(&attr_set->policy_list); 51 mutex_init(&attr_set->update_lock); 52 attr_set->usage_count = 1; 53 list_add(list_node, &attr_set->policy_list); 54 } 55 EXPORT_SYMBOL_GPL(gov_attr_set_init); 56 57 void gov_attr_set_get(struct gov_attr_set *attr_set, struct list_head *list_node) 58 { 59 mutex_lock(&attr_set->update_lock); 60 attr_set->usage_count++; 61 list_add(list_node, &attr_set->policy_list); 62 mutex_unlock(&attr_set->update_lock); 63 } 64 EXPORT_SYMBOL_GPL(gov_attr_set_get); 65 66 unsigned int gov_attr_set_put(struct gov_attr_set *attr_set, struct list_head *list_node) 67 { 68 unsigned int count; 69 70 mutex_lock(&attr_set->update_lock); 71 list_del(list_node); 72 count = --attr_set->usage_count; 73 mutex_unlock(&attr_set->update_lock); 74 if (count) 75 return count; 76 77 mutex_destroy(&attr_set->update_lock); 78 kobject_put(&attr_set->kobj); 79 return 0; 80 } 81 EXPORT_SYMBOL_GPL(gov_attr_set_put); 82