cpufreq_governor_attr_set.c 2.0 KB

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