cpufreq_governor_attr_set.c 2.1 KB

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