sysfs.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747
  1. /*
  2. * sysfs.c - sysfs support
  3. *
  4. * (C) 2006-2007 Shaohua Li <shaohua.li@intel.com>
  5. *
  6. * This code is licenced under the GPL.
  7. */
  8. #include <linux/kernel.h>
  9. #include <linux/cpuidle.h>
  10. #include <linux/sysfs.h>
  11. #include <linux/slab.h>
  12. #include <linux/cpu.h>
  13. #include <linux/completion.h>
  14. #include <linux/capability.h>
  15. #include <linux/device.h>
  16. #include <linux/kobject.h>
  17. #include "cpuidle.h"
  18. static ssize_t show_available_governors(struct device *dev,
  19. struct device_attribute *attr,
  20. char *buf)
  21. {
  22. ssize_t i = 0;
  23. struct cpuidle_governor *tmp;
  24. mutex_lock(&cpuidle_lock);
  25. list_for_each_entry(tmp, &cpuidle_governors, governor_list) {
  26. if (i >= (ssize_t)(PAGE_SIZE - (CPUIDLE_NAME_LEN + 2)))
  27. goto out;
  28. i += sysfs_emit_at(buf, i, "%.*s ", CPUIDLE_NAME_LEN, tmp->name);
  29. }
  30. out:
  31. i += sysfs_emit_at(buf, i, "\n");
  32. mutex_unlock(&cpuidle_lock);
  33. return i;
  34. }
  35. static ssize_t show_current_driver(struct device *dev,
  36. struct device_attribute *attr,
  37. char *buf)
  38. {
  39. ssize_t ret;
  40. struct cpuidle_driver *drv;
  41. spin_lock(&cpuidle_driver_lock);
  42. drv = cpuidle_get_driver();
  43. if (drv)
  44. ret = sysfs_emit(buf, "%s\n", drv->name);
  45. else
  46. ret = sysfs_emit(buf, "none\n");
  47. spin_unlock(&cpuidle_driver_lock);
  48. return ret;
  49. }
  50. static ssize_t show_current_governor(struct device *dev,
  51. struct device_attribute *attr,
  52. char *buf)
  53. {
  54. ssize_t ret;
  55. mutex_lock(&cpuidle_lock);
  56. if (cpuidle_curr_governor)
  57. ret = sysfs_emit(buf, "%s\n", cpuidle_curr_governor->name);
  58. else
  59. ret = sysfs_emit(buf, "none\n");
  60. mutex_unlock(&cpuidle_lock);
  61. return ret;
  62. }
  63. static ssize_t store_current_governor(struct device *dev,
  64. struct device_attribute *attr,
  65. const char *buf, size_t count)
  66. {
  67. char gov_name[CPUIDLE_NAME_LEN + 1];
  68. int ret;
  69. struct cpuidle_governor *gov;
  70. ret = sscanf(buf, "%" __stringify(CPUIDLE_NAME_LEN) "s", gov_name);
  71. if (ret != 1)
  72. return -EINVAL;
  73. mutex_lock(&cpuidle_lock);
  74. ret = -EINVAL;
  75. list_for_each_entry(gov, &cpuidle_governors, governor_list) {
  76. if (!strncmp(gov->name, gov_name, CPUIDLE_NAME_LEN)) {
  77. ret = cpuidle_switch_governor(gov);
  78. break;
  79. }
  80. }
  81. mutex_unlock(&cpuidle_lock);
  82. return ret ? ret : count;
  83. }
  84. static DEVICE_ATTR(available_governors, 0444, show_available_governors, NULL);
  85. static DEVICE_ATTR(current_driver, 0444, show_current_driver, NULL);
  86. static DEVICE_ATTR(current_governor, 0644, show_current_governor,
  87. store_current_governor);
  88. static DEVICE_ATTR(current_governor_ro, 0444, show_current_governor, NULL);
  89. static struct attribute *cpuidle_attrs[] = {
  90. &dev_attr_available_governors.attr,
  91. &dev_attr_current_driver.attr,
  92. &dev_attr_current_governor.attr,
  93. &dev_attr_current_governor_ro.attr,
  94. NULL
  95. };
  96. static struct attribute_group cpuidle_attr_group = {
  97. .attrs = cpuidle_attrs,
  98. .name = "cpuidle",
  99. };
  100. /**
  101. * cpuidle_add_interface - add CPU global sysfs attributes
  102. */
  103. int cpuidle_add_interface(void)
  104. {
  105. struct device *dev_root = bus_get_dev_root(&cpu_subsys);
  106. int retval;
  107. if (!dev_root)
  108. return -EINVAL;
  109. retval = sysfs_create_group(&dev_root->kobj, &cpuidle_attr_group);
  110. put_device(dev_root);
  111. return retval;
  112. }
  113. /**
  114. * cpuidle_remove_interface - remove CPU global sysfs attributes
  115. * @dev: the target device
  116. */
  117. void cpuidle_remove_interface(struct device *dev)
  118. {
  119. sysfs_remove_group(&dev->kobj, &cpuidle_attr_group);
  120. }
  121. struct cpuidle_attr {
  122. struct attribute attr;
  123. ssize_t (*show)(struct cpuidle_device *, char *);
  124. ssize_t (*store)(struct cpuidle_device *, const char *, size_t count);
  125. };
  126. #define attr_to_cpuidleattr(a) container_of(a, struct cpuidle_attr, attr)
  127. struct cpuidle_device_kobj {
  128. struct cpuidle_device *dev;
  129. struct completion kobj_unregister;
  130. struct kobject kobj;
  131. };
  132. static inline struct cpuidle_device *to_cpuidle_device(struct kobject *kobj)
  133. {
  134. struct cpuidle_device_kobj *kdev =
  135. container_of(kobj, struct cpuidle_device_kobj, kobj);
  136. return kdev->dev;
  137. }
  138. static ssize_t cpuidle_show(struct kobject *kobj, struct attribute *attr,
  139. char *buf)
  140. {
  141. int ret = -EIO;
  142. struct cpuidle_device *dev = to_cpuidle_device(kobj);
  143. struct cpuidle_attr *cattr = attr_to_cpuidleattr(attr);
  144. if (cattr->show) {
  145. mutex_lock(&cpuidle_lock);
  146. ret = cattr->show(dev, buf);
  147. mutex_unlock(&cpuidle_lock);
  148. }
  149. return ret;
  150. }
  151. static ssize_t cpuidle_store(struct kobject *kobj, struct attribute *attr,
  152. const char *buf, size_t count)
  153. {
  154. int ret = -EIO;
  155. struct cpuidle_device *dev = to_cpuidle_device(kobj);
  156. struct cpuidle_attr *cattr = attr_to_cpuidleattr(attr);
  157. if (cattr->store) {
  158. mutex_lock(&cpuidle_lock);
  159. ret = cattr->store(dev, buf, count);
  160. mutex_unlock(&cpuidle_lock);
  161. }
  162. return ret;
  163. }
  164. static const struct sysfs_ops cpuidle_sysfs_ops = {
  165. .show = cpuidle_show,
  166. .store = cpuidle_store,
  167. };
  168. static void cpuidle_sysfs_release(struct kobject *kobj)
  169. {
  170. struct cpuidle_device_kobj *kdev =
  171. container_of(kobj, struct cpuidle_device_kobj, kobj);
  172. complete(&kdev->kobj_unregister);
  173. }
  174. static const struct kobj_type ktype_cpuidle = {
  175. .sysfs_ops = &cpuidle_sysfs_ops,
  176. .release = cpuidle_sysfs_release,
  177. };
  178. struct cpuidle_state_attr {
  179. struct attribute attr;
  180. ssize_t (*show)(struct cpuidle_state *, \
  181. struct cpuidle_state_usage *, char *);
  182. ssize_t (*store)(struct cpuidle_state *, \
  183. struct cpuidle_state_usage *, const char *, size_t);
  184. };
  185. #define define_one_state_ro(_name, show) \
  186. static struct cpuidle_state_attr attr_##_name = __ATTR(_name, 0444, show, NULL)
  187. #define define_one_state_rw(_name, show, store) \
  188. static struct cpuidle_state_attr attr_##_name = __ATTR(_name, 0644, show, store)
  189. #define define_show_state_function(_name) \
  190. static ssize_t show_state_##_name(struct cpuidle_state *state, \
  191. struct cpuidle_state_usage *state_usage, char *buf) \
  192. { \
  193. return sysfs_emit(buf, "%u\n", state->_name);\
  194. }
  195. #define define_show_state_ull_function(_name) \
  196. static ssize_t show_state_##_name(struct cpuidle_state *state, \
  197. struct cpuidle_state_usage *state_usage, \
  198. char *buf) \
  199. { \
  200. return sysfs_emit(buf, "%llu\n", state_usage->_name);\
  201. }
  202. #define define_show_state_str_function(_name) \
  203. static ssize_t show_state_##_name(struct cpuidle_state *state, \
  204. struct cpuidle_state_usage *state_usage, \
  205. char *buf) \
  206. { \
  207. if (state->_name[0] == '\0')\
  208. return sysfs_emit(buf, "<null>\n");\
  209. return sysfs_emit(buf, "%s\n", state->_name);\
  210. }
  211. #define define_show_state_time_function(_name) \
  212. static ssize_t show_state_##_name(struct cpuidle_state *state, \
  213. struct cpuidle_state_usage *state_usage, \
  214. char *buf) \
  215. { \
  216. return sysfs_emit(buf, "%llu\n", ktime_to_us(state->_name##_ns)); \
  217. }
  218. define_show_state_time_function(exit_latency)
  219. define_show_state_time_function(target_residency)
  220. define_show_state_function(power_usage)
  221. define_show_state_ull_function(usage)
  222. define_show_state_ull_function(rejected)
  223. define_show_state_str_function(name)
  224. define_show_state_str_function(desc)
  225. define_show_state_ull_function(above)
  226. define_show_state_ull_function(below)
  227. static ssize_t show_state_time(struct cpuidle_state *state,
  228. struct cpuidle_state_usage *state_usage,
  229. char *buf)
  230. {
  231. return sysfs_emit(buf, "%llu\n", ktime_to_us(state_usage->time_ns));
  232. }
  233. static ssize_t show_state_disable(struct cpuidle_state *state,
  234. struct cpuidle_state_usage *state_usage,
  235. char *buf)
  236. {
  237. return sysfs_emit(buf, "%llu\n",
  238. state_usage->disable & CPUIDLE_STATE_DISABLED_BY_USER);
  239. }
  240. static ssize_t store_state_disable(struct cpuidle_state *state,
  241. struct cpuidle_state_usage *state_usage,
  242. const char *buf, size_t size)
  243. {
  244. unsigned int value;
  245. int err;
  246. if (!capable(CAP_SYS_ADMIN))
  247. return -EPERM;
  248. err = kstrtouint(buf, 0, &value);
  249. if (err)
  250. return err;
  251. if (value)
  252. state_usage->disable |= CPUIDLE_STATE_DISABLED_BY_USER;
  253. else
  254. state_usage->disable &= ~CPUIDLE_STATE_DISABLED_BY_USER;
  255. return size;
  256. }
  257. static ssize_t show_state_default_status(struct cpuidle_state *state,
  258. struct cpuidle_state_usage *state_usage,
  259. char *buf)
  260. {
  261. return sysfs_emit(buf, "%s\n",
  262. state->flags & CPUIDLE_FLAG_OFF ? "disabled" : "enabled");
  263. }
  264. define_one_state_ro(name, show_state_name);
  265. define_one_state_ro(desc, show_state_desc);
  266. define_one_state_ro(latency, show_state_exit_latency);
  267. define_one_state_ro(residency, show_state_target_residency);
  268. define_one_state_ro(power, show_state_power_usage);
  269. define_one_state_ro(usage, show_state_usage);
  270. define_one_state_ro(rejected, show_state_rejected);
  271. define_one_state_ro(time, show_state_time);
  272. define_one_state_rw(disable, show_state_disable, store_state_disable);
  273. define_one_state_ro(above, show_state_above);
  274. define_one_state_ro(below, show_state_below);
  275. define_one_state_ro(default_status, show_state_default_status);
  276. static struct attribute *cpuidle_state_default_attrs[] = {
  277. &attr_name.attr,
  278. &attr_desc.attr,
  279. &attr_latency.attr,
  280. &attr_residency.attr,
  281. &attr_power.attr,
  282. &attr_usage.attr,
  283. &attr_rejected.attr,
  284. &attr_time.attr,
  285. &attr_disable.attr,
  286. &attr_above.attr,
  287. &attr_below.attr,
  288. &attr_default_status.attr,
  289. NULL
  290. };
  291. ATTRIBUTE_GROUPS(cpuidle_state_default);
  292. struct cpuidle_state_kobj {
  293. struct cpuidle_state *state;
  294. struct cpuidle_state_usage *state_usage;
  295. struct completion kobj_unregister;
  296. struct kobject kobj;
  297. struct cpuidle_device *device;
  298. };
  299. #ifdef CONFIG_SUSPEND
  300. #define define_show_state_s2idle_ull_function(_name) \
  301. static ssize_t show_state_s2idle_##_name(struct cpuidle_state *state, \
  302. struct cpuidle_state_usage *state_usage, \
  303. char *buf) \
  304. { \
  305. return sysfs_emit(buf, "%llu\n", state_usage->s2idle_##_name);\
  306. }
  307. define_show_state_s2idle_ull_function(usage);
  308. define_show_state_s2idle_ull_function(time);
  309. #define define_one_state_s2idle_ro(_name, show) \
  310. static struct cpuidle_state_attr attr_s2idle_##_name = \
  311. __ATTR(_name, 0444, show, NULL)
  312. define_one_state_s2idle_ro(usage, show_state_s2idle_usage);
  313. define_one_state_s2idle_ro(time, show_state_s2idle_time);
  314. static struct attribute *cpuidle_state_s2idle_attrs[] = {
  315. &attr_s2idle_usage.attr,
  316. &attr_s2idle_time.attr,
  317. NULL
  318. };
  319. static const struct attribute_group cpuidle_state_s2idle_group = {
  320. .name = "s2idle",
  321. .attrs = cpuidle_state_s2idle_attrs,
  322. };
  323. static void cpuidle_add_s2idle_attr_group(struct cpuidle_state_kobj *kobj)
  324. {
  325. int ret;
  326. if (!kobj->state->enter_s2idle)
  327. return;
  328. ret = sysfs_create_group(&kobj->kobj, &cpuidle_state_s2idle_group);
  329. if (ret)
  330. pr_debug("%s: sysfs attribute group not created\n", __func__);
  331. }
  332. static void cpuidle_remove_s2idle_attr_group(struct cpuidle_state_kobj *kobj)
  333. {
  334. if (kobj->state->enter_s2idle)
  335. sysfs_remove_group(&kobj->kobj, &cpuidle_state_s2idle_group);
  336. }
  337. #else
  338. static inline void cpuidle_add_s2idle_attr_group(struct cpuidle_state_kobj *kobj) { }
  339. static inline void cpuidle_remove_s2idle_attr_group(struct cpuidle_state_kobj *kobj) { }
  340. #endif /* CONFIG_SUSPEND */
  341. #define kobj_to_state_obj(k) container_of(k, struct cpuidle_state_kobj, kobj)
  342. #define kobj_to_state(k) (kobj_to_state_obj(k)->state)
  343. #define kobj_to_state_usage(k) (kobj_to_state_obj(k)->state_usage)
  344. #define kobj_to_device(k) (kobj_to_state_obj(k)->device)
  345. #define attr_to_stateattr(a) container_of(a, struct cpuidle_state_attr, attr)
  346. static ssize_t cpuidle_state_show(struct kobject *kobj, struct attribute *attr,
  347. char *buf)
  348. {
  349. int ret = -EIO;
  350. struct cpuidle_state *state = kobj_to_state(kobj);
  351. struct cpuidle_state_usage *state_usage = kobj_to_state_usage(kobj);
  352. struct cpuidle_state_attr *cattr = attr_to_stateattr(attr);
  353. if (cattr->show)
  354. ret = cattr->show(state, state_usage, buf);
  355. return ret;
  356. }
  357. static ssize_t cpuidle_state_store(struct kobject *kobj, struct attribute *attr,
  358. const char *buf, size_t size)
  359. {
  360. int ret = -EIO;
  361. struct cpuidle_state *state = kobj_to_state(kobj);
  362. struct cpuidle_state_usage *state_usage = kobj_to_state_usage(kobj);
  363. struct cpuidle_state_attr *cattr = attr_to_stateattr(attr);
  364. struct cpuidle_device *dev = kobj_to_device(kobj);
  365. if (cattr->store)
  366. ret = cattr->store(state, state_usage, buf, size);
  367. /* reset poll time cache */
  368. dev->poll_limit_ns = 0;
  369. return ret;
  370. }
  371. static const struct sysfs_ops cpuidle_state_sysfs_ops = {
  372. .show = cpuidle_state_show,
  373. .store = cpuidle_state_store,
  374. };
  375. static void cpuidle_state_sysfs_release(struct kobject *kobj)
  376. {
  377. struct cpuidle_state_kobj *state_obj = kobj_to_state_obj(kobj);
  378. complete(&state_obj->kobj_unregister);
  379. }
  380. static const struct kobj_type ktype_state_cpuidle = {
  381. .sysfs_ops = &cpuidle_state_sysfs_ops,
  382. .default_groups = cpuidle_state_default_groups,
  383. .release = cpuidle_state_sysfs_release,
  384. };
  385. static inline void cpuidle_free_state_kobj(struct cpuidle_device *device, int i)
  386. {
  387. cpuidle_remove_s2idle_attr_group(device->kobjs[i]);
  388. kobject_put(&device->kobjs[i]->kobj);
  389. wait_for_completion(&device->kobjs[i]->kobj_unregister);
  390. kfree(device->kobjs[i]);
  391. device->kobjs[i] = NULL;
  392. }
  393. /**
  394. * cpuidle_add_state_sysfs - adds cpuidle states sysfs attributes
  395. * @device: the target device
  396. */
  397. static int cpuidle_add_state_sysfs(struct cpuidle_device *device)
  398. {
  399. int i, ret = -ENOMEM;
  400. struct cpuidle_state_kobj *kobj;
  401. struct cpuidle_device_kobj *kdev = device->kobj_dev;
  402. struct cpuidle_driver *drv = cpuidle_get_cpu_driver(device);
  403. /* state statistics */
  404. for (i = 0; i < drv->state_count; i++) {
  405. kobj = kzalloc_obj(struct cpuidle_state_kobj);
  406. if (!kobj) {
  407. ret = -ENOMEM;
  408. goto error_state;
  409. }
  410. kobj->state = &drv->states[i];
  411. kobj->state_usage = &device->states_usage[i];
  412. kobj->device = device;
  413. init_completion(&kobj->kobj_unregister);
  414. ret = kobject_init_and_add(&kobj->kobj, &ktype_state_cpuidle,
  415. &kdev->kobj, "state%d", i);
  416. if (ret) {
  417. kobject_put(&kobj->kobj);
  418. kfree(kobj);
  419. goto error_state;
  420. }
  421. cpuidle_add_s2idle_attr_group(kobj);
  422. kobject_uevent(&kobj->kobj, KOBJ_ADD);
  423. device->kobjs[i] = kobj;
  424. }
  425. return 0;
  426. error_state:
  427. for (i = i - 1; i >= 0; i--)
  428. cpuidle_free_state_kobj(device, i);
  429. return ret;
  430. }
  431. /**
  432. * cpuidle_remove_state_sysfs - removes the cpuidle states sysfs attributes
  433. * @device: the target device
  434. */
  435. static void cpuidle_remove_state_sysfs(struct cpuidle_device *device)
  436. {
  437. struct cpuidle_driver *drv = cpuidle_get_cpu_driver(device);
  438. int i;
  439. for (i = 0; i < drv->state_count; i++)
  440. cpuidle_free_state_kobj(device, i);
  441. }
  442. #ifdef CONFIG_CPU_IDLE_MULTIPLE_DRIVERS
  443. #define kobj_to_driver_kobj(k) container_of(k, struct cpuidle_driver_kobj, kobj)
  444. #define attr_to_driver_attr(a) container_of(a, struct cpuidle_driver_attr, attr)
  445. #define define_one_driver_ro(_name, show) \
  446. static struct cpuidle_driver_attr attr_driver_##_name = \
  447. __ATTR(_name, 0444, show, NULL)
  448. struct cpuidle_driver_kobj {
  449. struct cpuidle_driver *drv;
  450. struct completion kobj_unregister;
  451. struct kobject kobj;
  452. };
  453. struct cpuidle_driver_attr {
  454. struct attribute attr;
  455. ssize_t (*show)(struct cpuidle_driver *, char *);
  456. ssize_t (*store)(struct cpuidle_driver *, const char *, size_t);
  457. };
  458. static ssize_t show_driver_name(struct cpuidle_driver *drv, char *buf)
  459. {
  460. ssize_t ret;
  461. spin_lock(&cpuidle_driver_lock);
  462. ret = sysfs_emit(buf, "%s\n", drv ? drv->name : "none");
  463. spin_unlock(&cpuidle_driver_lock);
  464. return ret;
  465. }
  466. static void cpuidle_driver_sysfs_release(struct kobject *kobj)
  467. {
  468. struct cpuidle_driver_kobj *driver_kobj = kobj_to_driver_kobj(kobj);
  469. complete(&driver_kobj->kobj_unregister);
  470. }
  471. static ssize_t cpuidle_driver_show(struct kobject *kobj, struct attribute *attr,
  472. char *buf)
  473. {
  474. int ret = -EIO;
  475. struct cpuidle_driver_kobj *driver_kobj = kobj_to_driver_kobj(kobj);
  476. struct cpuidle_driver_attr *dattr = attr_to_driver_attr(attr);
  477. if (dattr->show)
  478. ret = dattr->show(driver_kobj->drv, buf);
  479. return ret;
  480. }
  481. static ssize_t cpuidle_driver_store(struct kobject *kobj, struct attribute *attr,
  482. const char *buf, size_t size)
  483. {
  484. int ret = -EIO;
  485. struct cpuidle_driver_kobj *driver_kobj = kobj_to_driver_kobj(kobj);
  486. struct cpuidle_driver_attr *dattr = attr_to_driver_attr(attr);
  487. if (dattr->store)
  488. ret = dattr->store(driver_kobj->drv, buf, size);
  489. return ret;
  490. }
  491. define_one_driver_ro(name, show_driver_name);
  492. static const struct sysfs_ops cpuidle_driver_sysfs_ops = {
  493. .show = cpuidle_driver_show,
  494. .store = cpuidle_driver_store,
  495. };
  496. static struct attribute *cpuidle_driver_default_attrs[] = {
  497. &attr_driver_name.attr,
  498. NULL
  499. };
  500. ATTRIBUTE_GROUPS(cpuidle_driver_default);
  501. static const struct kobj_type ktype_driver_cpuidle = {
  502. .sysfs_ops = &cpuidle_driver_sysfs_ops,
  503. .default_groups = cpuidle_driver_default_groups,
  504. .release = cpuidle_driver_sysfs_release,
  505. };
  506. /**
  507. * cpuidle_add_driver_sysfs - adds the driver name sysfs attribute
  508. * @dev: the target device
  509. */
  510. static int cpuidle_add_driver_sysfs(struct cpuidle_device *dev)
  511. {
  512. struct cpuidle_driver_kobj *kdrv;
  513. struct cpuidle_device_kobj *kdev = dev->kobj_dev;
  514. struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
  515. int ret;
  516. kdrv = kzalloc_obj(*kdrv);
  517. if (!kdrv)
  518. return -ENOMEM;
  519. kdrv->drv = drv;
  520. init_completion(&kdrv->kobj_unregister);
  521. ret = kobject_init_and_add(&kdrv->kobj, &ktype_driver_cpuidle,
  522. &kdev->kobj, "driver");
  523. if (ret) {
  524. kobject_put(&kdrv->kobj);
  525. kfree(kdrv);
  526. return ret;
  527. }
  528. kobject_uevent(&kdrv->kobj, KOBJ_ADD);
  529. dev->kobj_driver = kdrv;
  530. return ret;
  531. }
  532. /**
  533. * cpuidle_remove_driver_sysfs - removes the driver name sysfs attribute
  534. * @dev: the target device
  535. */
  536. static void cpuidle_remove_driver_sysfs(struct cpuidle_device *dev)
  537. {
  538. struct cpuidle_driver_kobj *kdrv = dev->kobj_driver;
  539. kobject_put(&kdrv->kobj);
  540. wait_for_completion(&kdrv->kobj_unregister);
  541. kfree(kdrv);
  542. }
  543. #else
  544. static inline int cpuidle_add_driver_sysfs(struct cpuidle_device *dev)
  545. {
  546. return 0;
  547. }
  548. static inline void cpuidle_remove_driver_sysfs(struct cpuidle_device *dev)
  549. {
  550. ;
  551. }
  552. #endif
  553. /**
  554. * cpuidle_add_device_sysfs - adds device specific sysfs attributes
  555. * @device: the target device
  556. */
  557. int cpuidle_add_device_sysfs(struct cpuidle_device *device)
  558. {
  559. int ret;
  560. ret = cpuidle_add_state_sysfs(device);
  561. if (ret)
  562. return ret;
  563. ret = cpuidle_add_driver_sysfs(device);
  564. if (ret)
  565. cpuidle_remove_state_sysfs(device);
  566. return ret;
  567. }
  568. /**
  569. * cpuidle_remove_device_sysfs : removes device specific sysfs attributes
  570. * @device : the target device
  571. */
  572. void cpuidle_remove_device_sysfs(struct cpuidle_device *device)
  573. {
  574. cpuidle_remove_driver_sysfs(device);
  575. cpuidle_remove_state_sysfs(device);
  576. }
  577. /**
  578. * cpuidle_add_sysfs - creates a sysfs instance for the target device
  579. * @dev: the target device
  580. */
  581. int cpuidle_add_sysfs(struct cpuidle_device *dev)
  582. {
  583. struct cpuidle_device_kobj *kdev;
  584. struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu);
  585. int error;
  586. /*
  587. * Return if cpu_device is not setup for this CPU.
  588. *
  589. * This could happen if the arch did not set up cpu_device
  590. * since this CPU is not in cpu_present mask and the
  591. * driver did not send a correct CPU mask during registration.
  592. * Without this check we would end up passing bogus
  593. * value for &cpu_dev->kobj in kobject_init_and_add()
  594. */
  595. if (!cpu_dev)
  596. return -ENODEV;
  597. kdev = kzalloc_obj(*kdev);
  598. if (!kdev)
  599. return -ENOMEM;
  600. kdev->dev = dev;
  601. init_completion(&kdev->kobj_unregister);
  602. error = kobject_init_and_add(&kdev->kobj, &ktype_cpuidle, &cpu_dev->kobj,
  603. "cpuidle");
  604. if (error) {
  605. kobject_put(&kdev->kobj);
  606. kfree(kdev);
  607. return error;
  608. }
  609. dev->kobj_dev = kdev;
  610. kobject_uevent(&kdev->kobj, KOBJ_ADD);
  611. return 0;
  612. }
  613. /**
  614. * cpuidle_remove_sysfs - deletes a sysfs instance on the target device
  615. * @dev: the target device
  616. */
  617. void cpuidle_remove_sysfs(struct cpuidle_device *dev)
  618. {
  619. struct cpuidle_device_kobj *kdev = dev->kobj_dev;
  620. kobject_put(&kdev->kobj);
  621. wait_for_completion(&kdev->kobj_unregister);
  622. kfree(kdev);
  623. }