root/drivers/cpuidle/sysfs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cpuidle_sysfs_setup
  2. show_available_governors
  3. show_current_driver
  4. show_current_governor
  5. store_current_governor
  6. cpuidle_add_interface
  7. cpuidle_remove_interface
  8. to_cpuidle_device
  9. cpuidle_show
  10. cpuidle_store
  11. cpuidle_sysfs_release
  12. cpuidle_add_s2idle_attr_group
  13. cpuidle_remove_s2idle_attr_group
  14. cpuidle_add_s2idle_attr_group
  15. cpuidle_remove_s2idle_attr_group
  16. cpuidle_state_show
  17. cpuidle_state_store
  18. cpuidle_state_sysfs_release
  19. cpuidle_free_state_kobj
  20. cpuidle_add_state_sysfs
  21. cpuidle_remove_state_sysfs
  22. show_driver_name
  23. cpuidle_driver_sysfs_release
  24. cpuidle_driver_show
  25. cpuidle_driver_store
  26. cpuidle_add_driver_sysfs
  27. cpuidle_remove_driver_sysfs
  28. cpuidle_add_driver_sysfs
  29. cpuidle_remove_driver_sysfs
  30. cpuidle_add_device_sysfs
  31. cpuidle_remove_device_sysfs
  32. cpuidle_add_sysfs
  33. cpuidle_remove_sysfs

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

/* [<][>][^][v][top][bottom][index][help] */