sysfs.c 19 KB

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