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 11static 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 16static inline struct governor_attr *to_gov_attr(struct attribute *attr) 17{ 18 return container_of(attr, struct governor_attr, attr); 19} 20 21static 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 29static 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 42const struct sysfs_ops governor_sysfs_ops = { 43 .show = governor_show, 44 .store = governor_store, 45}; 46EXPORT_SYMBOL_GPL(governor_sysfs_ops); 47 48void 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} 55EXPORT_SYMBOL_GPL(gov_attr_set_init); 56 57void 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} 64EXPORT_SYMBOL_GPL(gov_attr_set_get); 65 66unsigned 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} 81EXPORT_SYMBOL_GPL(gov_attr_set_put); 82