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