0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/kernel.h>
0010 #include <linux/cpuidle.h>
0011 #include <linux/sysfs.h>
0012 #include <linux/slab.h>
0013 #include <linux/cpu.h>
0014 #include <linux/completion.h>
0015 #include <linux/capability.h>
0016 #include <linux/device.h>
0017 #include <linux/kobject.h>
0018
0019 #include "cpuidle.h"
0020
0021 static ssize_t show_available_governors(struct device *dev,
0022 struct device_attribute *attr,
0023 char *buf)
0024 {
0025 ssize_t i = 0;
0026 struct cpuidle_governor *tmp;
0027
0028 mutex_lock(&cpuidle_lock);
0029 list_for_each_entry(tmp, &cpuidle_governors, governor_list) {
0030 if (i >= (ssize_t) (PAGE_SIZE - (CPUIDLE_NAME_LEN + 2)))
0031 goto out;
0032
0033 i += scnprintf(&buf[i], CPUIDLE_NAME_LEN + 1, "%s ", tmp->name);
0034 }
0035
0036 out:
0037 i+= sprintf(&buf[i], "\n");
0038 mutex_unlock(&cpuidle_lock);
0039 return i;
0040 }
0041
0042 static ssize_t show_current_driver(struct device *dev,
0043 struct device_attribute *attr,
0044 char *buf)
0045 {
0046 ssize_t ret;
0047 struct cpuidle_driver *drv;
0048
0049 spin_lock(&cpuidle_driver_lock);
0050 drv = cpuidle_get_driver();
0051 if (drv)
0052 ret = sprintf(buf, "%s\n", drv->name);
0053 else
0054 ret = sprintf(buf, "none\n");
0055 spin_unlock(&cpuidle_driver_lock);
0056
0057 return ret;
0058 }
0059
0060 static ssize_t show_current_governor(struct device *dev,
0061 struct device_attribute *attr,
0062 char *buf)
0063 {
0064 ssize_t ret;
0065
0066 mutex_lock(&cpuidle_lock);
0067 if (cpuidle_curr_governor)
0068 ret = sprintf(buf, "%s\n", cpuidle_curr_governor->name);
0069 else
0070 ret = sprintf(buf, "none\n");
0071 mutex_unlock(&cpuidle_lock);
0072
0073 return ret;
0074 }
0075
0076 static ssize_t store_current_governor(struct device *dev,
0077 struct device_attribute *attr,
0078 const char *buf, size_t count)
0079 {
0080 char gov_name[CPUIDLE_NAME_LEN + 1];
0081 int ret;
0082 struct cpuidle_governor *gov;
0083
0084 ret = sscanf(buf, "%" __stringify(CPUIDLE_NAME_LEN) "s", gov_name);
0085 if (ret != 1)
0086 return -EINVAL;
0087
0088 mutex_lock(&cpuidle_lock);
0089 ret = -EINVAL;
0090 list_for_each_entry(gov, &cpuidle_governors, governor_list) {
0091 if (!strncmp(gov->name, gov_name, CPUIDLE_NAME_LEN)) {
0092 ret = cpuidle_switch_governor(gov);
0093 break;
0094 }
0095 }
0096 mutex_unlock(&cpuidle_lock);
0097
0098 return ret ? ret : count;
0099 }
0100
0101 static DEVICE_ATTR(available_governors, 0444, show_available_governors, NULL);
0102 static DEVICE_ATTR(current_driver, 0444, show_current_driver, NULL);
0103 static DEVICE_ATTR(current_governor, 0644, show_current_governor,
0104 store_current_governor);
0105 static DEVICE_ATTR(current_governor_ro, 0444, show_current_governor, NULL);
0106
0107 static struct attribute *cpuidle_attrs[] = {
0108 &dev_attr_available_governors.attr,
0109 &dev_attr_current_driver.attr,
0110 &dev_attr_current_governor.attr,
0111 &dev_attr_current_governor_ro.attr,
0112 NULL
0113 };
0114
0115 static struct attribute_group cpuidle_attr_group = {
0116 .attrs = cpuidle_attrs,
0117 .name = "cpuidle",
0118 };
0119
0120
0121
0122
0123
0124 int cpuidle_add_interface(struct device *dev)
0125 {
0126 return sysfs_create_group(&dev->kobj, &cpuidle_attr_group);
0127 }
0128
0129
0130
0131
0132
0133 void cpuidle_remove_interface(struct device *dev)
0134 {
0135 sysfs_remove_group(&dev->kobj, &cpuidle_attr_group);
0136 }
0137
0138 struct cpuidle_attr {
0139 struct attribute attr;
0140 ssize_t (*show)(struct cpuidle_device *, char *);
0141 ssize_t (*store)(struct cpuidle_device *, const char *, size_t count);
0142 };
0143
0144 #define attr_to_cpuidleattr(a) container_of(a, struct cpuidle_attr, attr)
0145
0146 struct cpuidle_device_kobj {
0147 struct cpuidle_device *dev;
0148 struct completion kobj_unregister;
0149 struct kobject kobj;
0150 };
0151
0152 static inline struct cpuidle_device *to_cpuidle_device(struct kobject *kobj)
0153 {
0154 struct cpuidle_device_kobj *kdev =
0155 container_of(kobj, struct cpuidle_device_kobj, kobj);
0156
0157 return kdev->dev;
0158 }
0159
0160 static ssize_t cpuidle_show(struct kobject *kobj, struct attribute *attr,
0161 char *buf)
0162 {
0163 int ret = -EIO;
0164 struct cpuidle_device *dev = to_cpuidle_device(kobj);
0165 struct cpuidle_attr *cattr = attr_to_cpuidleattr(attr);
0166
0167 if (cattr->show) {
0168 mutex_lock(&cpuidle_lock);
0169 ret = cattr->show(dev, buf);
0170 mutex_unlock(&cpuidle_lock);
0171 }
0172 return ret;
0173 }
0174
0175 static ssize_t cpuidle_store(struct kobject *kobj, struct attribute *attr,
0176 const char *buf, size_t count)
0177 {
0178 int ret = -EIO;
0179 struct cpuidle_device *dev = to_cpuidle_device(kobj);
0180 struct cpuidle_attr *cattr = attr_to_cpuidleattr(attr);
0181
0182 if (cattr->store) {
0183 mutex_lock(&cpuidle_lock);
0184 ret = cattr->store(dev, buf, count);
0185 mutex_unlock(&cpuidle_lock);
0186 }
0187 return ret;
0188 }
0189
0190 static const struct sysfs_ops cpuidle_sysfs_ops = {
0191 .show = cpuidle_show,
0192 .store = cpuidle_store,
0193 };
0194
0195 static void cpuidle_sysfs_release(struct kobject *kobj)
0196 {
0197 struct cpuidle_device_kobj *kdev =
0198 container_of(kobj, struct cpuidle_device_kobj, kobj);
0199
0200 complete(&kdev->kobj_unregister);
0201 }
0202
0203 static struct kobj_type ktype_cpuidle = {
0204 .sysfs_ops = &cpuidle_sysfs_ops,
0205 .release = cpuidle_sysfs_release,
0206 };
0207
0208 struct cpuidle_state_attr {
0209 struct attribute attr;
0210 ssize_t (*show)(struct cpuidle_state *, \
0211 struct cpuidle_state_usage *, char *);
0212 ssize_t (*store)(struct cpuidle_state *, \
0213 struct cpuidle_state_usage *, const char *, size_t);
0214 };
0215
0216 #define define_one_state_ro(_name, show) \
0217 static struct cpuidle_state_attr attr_##_name = __ATTR(_name, 0444, show, NULL)
0218
0219 #define define_one_state_rw(_name, show, store) \
0220 static struct cpuidle_state_attr attr_##_name = __ATTR(_name, 0644, show, store)
0221
0222 #define define_show_state_function(_name) \
0223 static ssize_t show_state_##_name(struct cpuidle_state *state, \
0224 struct cpuidle_state_usage *state_usage, char *buf) \
0225 { \
0226 return sprintf(buf, "%u\n", state->_name);\
0227 }
0228
0229 #define define_show_state_ull_function(_name) \
0230 static ssize_t show_state_##_name(struct cpuidle_state *state, \
0231 struct cpuidle_state_usage *state_usage, \
0232 char *buf) \
0233 { \
0234 return sprintf(buf, "%llu\n", state_usage->_name);\
0235 }
0236
0237 #define define_show_state_str_function(_name) \
0238 static ssize_t show_state_##_name(struct cpuidle_state *state, \
0239 struct cpuidle_state_usage *state_usage, \
0240 char *buf) \
0241 { \
0242 if (state->_name[0] == '\0')\
0243 return sprintf(buf, "<null>\n");\
0244 return sprintf(buf, "%s\n", state->_name);\
0245 }
0246
0247 #define define_show_state_time_function(_name) \
0248 static ssize_t show_state_##_name(struct cpuidle_state *state, \
0249 struct cpuidle_state_usage *state_usage, \
0250 char *buf) \
0251 { \
0252 return sprintf(buf, "%llu\n", ktime_to_us(state->_name##_ns)); \
0253 }
0254
0255 define_show_state_time_function(exit_latency)
0256 define_show_state_time_function(target_residency)
0257 define_show_state_function(power_usage)
0258 define_show_state_ull_function(usage)
0259 define_show_state_ull_function(rejected)
0260 define_show_state_str_function(name)
0261 define_show_state_str_function(desc)
0262 define_show_state_ull_function(above)
0263 define_show_state_ull_function(below)
0264
0265 static ssize_t show_state_time(struct cpuidle_state *state,
0266 struct cpuidle_state_usage *state_usage,
0267 char *buf)
0268 {
0269 return sprintf(buf, "%llu\n", ktime_to_us(state_usage->time_ns));
0270 }
0271
0272 static ssize_t show_state_disable(struct cpuidle_state *state,
0273 struct cpuidle_state_usage *state_usage,
0274 char *buf)
0275 {
0276 return sprintf(buf, "%llu\n",
0277 state_usage->disable & CPUIDLE_STATE_DISABLED_BY_USER);
0278 }
0279
0280 static ssize_t store_state_disable(struct cpuidle_state *state,
0281 struct cpuidle_state_usage *state_usage,
0282 const char *buf, size_t size)
0283 {
0284 unsigned int value;
0285 int err;
0286
0287 if (!capable(CAP_SYS_ADMIN))
0288 return -EPERM;
0289
0290 err = kstrtouint(buf, 0, &value);
0291 if (err)
0292 return err;
0293
0294 if (value)
0295 state_usage->disable |= CPUIDLE_STATE_DISABLED_BY_USER;
0296 else
0297 state_usage->disable &= ~CPUIDLE_STATE_DISABLED_BY_USER;
0298
0299 return size;
0300 }
0301
0302 static ssize_t show_state_default_status(struct cpuidle_state *state,
0303 struct cpuidle_state_usage *state_usage,
0304 char *buf)
0305 {
0306 return sprintf(buf, "%s\n",
0307 state->flags & CPUIDLE_FLAG_OFF ? "disabled" : "enabled");
0308 }
0309
0310 define_one_state_ro(name, show_state_name);
0311 define_one_state_ro(desc, show_state_desc);
0312 define_one_state_ro(latency, show_state_exit_latency);
0313 define_one_state_ro(residency, show_state_target_residency);
0314 define_one_state_ro(power, show_state_power_usage);
0315 define_one_state_ro(usage, show_state_usage);
0316 define_one_state_ro(rejected, show_state_rejected);
0317 define_one_state_ro(time, show_state_time);
0318 define_one_state_rw(disable, show_state_disable, store_state_disable);
0319 define_one_state_ro(above, show_state_above);
0320 define_one_state_ro(below, show_state_below);
0321 define_one_state_ro(default_status, show_state_default_status);
0322
0323 static struct attribute *cpuidle_state_default_attrs[] = {
0324 &attr_name.attr,
0325 &attr_desc.attr,
0326 &attr_latency.attr,
0327 &attr_residency.attr,
0328 &attr_power.attr,
0329 &attr_usage.attr,
0330 &attr_rejected.attr,
0331 &attr_time.attr,
0332 &attr_disable.attr,
0333 &attr_above.attr,
0334 &attr_below.attr,
0335 &attr_default_status.attr,
0336 NULL
0337 };
0338 ATTRIBUTE_GROUPS(cpuidle_state_default);
0339
0340 struct cpuidle_state_kobj {
0341 struct cpuidle_state *state;
0342 struct cpuidle_state_usage *state_usage;
0343 struct completion kobj_unregister;
0344 struct kobject kobj;
0345 struct cpuidle_device *device;
0346 };
0347
0348 #ifdef CONFIG_SUSPEND
0349 #define define_show_state_s2idle_ull_function(_name) \
0350 static ssize_t show_state_s2idle_##_name(struct cpuidle_state *state, \
0351 struct cpuidle_state_usage *state_usage, \
0352 char *buf) \
0353 { \
0354 return sprintf(buf, "%llu\n", state_usage->s2idle_##_name);\
0355 }
0356
0357 define_show_state_s2idle_ull_function(usage);
0358 define_show_state_s2idle_ull_function(time);
0359
0360 #define define_one_state_s2idle_ro(_name, show) \
0361 static struct cpuidle_state_attr attr_s2idle_##_name = \
0362 __ATTR(_name, 0444, show, NULL)
0363
0364 define_one_state_s2idle_ro(usage, show_state_s2idle_usage);
0365 define_one_state_s2idle_ro(time, show_state_s2idle_time);
0366
0367 static struct attribute *cpuidle_state_s2idle_attrs[] = {
0368 &attr_s2idle_usage.attr,
0369 &attr_s2idle_time.attr,
0370 NULL
0371 };
0372
0373 static const struct attribute_group cpuidle_state_s2idle_group = {
0374 .name = "s2idle",
0375 .attrs = cpuidle_state_s2idle_attrs,
0376 };
0377
0378 static void cpuidle_add_s2idle_attr_group(struct cpuidle_state_kobj *kobj)
0379 {
0380 int ret;
0381
0382 if (!kobj->state->enter_s2idle)
0383 return;
0384
0385 ret = sysfs_create_group(&kobj->kobj, &cpuidle_state_s2idle_group);
0386 if (ret)
0387 pr_debug("%s: sysfs attribute group not created\n", __func__);
0388 }
0389
0390 static void cpuidle_remove_s2idle_attr_group(struct cpuidle_state_kobj *kobj)
0391 {
0392 if (kobj->state->enter_s2idle)
0393 sysfs_remove_group(&kobj->kobj, &cpuidle_state_s2idle_group);
0394 }
0395 #else
0396 static inline void cpuidle_add_s2idle_attr_group(struct cpuidle_state_kobj *kobj) { }
0397 static inline void cpuidle_remove_s2idle_attr_group(struct cpuidle_state_kobj *kobj) { }
0398 #endif
0399
0400 #define kobj_to_state_obj(k) container_of(k, struct cpuidle_state_kobj, kobj)
0401 #define kobj_to_state(k) (kobj_to_state_obj(k)->state)
0402 #define kobj_to_state_usage(k) (kobj_to_state_obj(k)->state_usage)
0403 #define kobj_to_device(k) (kobj_to_state_obj(k)->device)
0404 #define attr_to_stateattr(a) container_of(a, struct cpuidle_state_attr, attr)
0405
0406 static ssize_t cpuidle_state_show(struct kobject *kobj, struct attribute *attr,
0407 char *buf)
0408 {
0409 int ret = -EIO;
0410 struct cpuidle_state *state = kobj_to_state(kobj);
0411 struct cpuidle_state_usage *state_usage = kobj_to_state_usage(kobj);
0412 struct cpuidle_state_attr *cattr = attr_to_stateattr(attr);
0413
0414 if (cattr->show)
0415 ret = cattr->show(state, state_usage, buf);
0416
0417 return ret;
0418 }
0419
0420 static ssize_t cpuidle_state_store(struct kobject *kobj, struct attribute *attr,
0421 const char *buf, size_t size)
0422 {
0423 int ret = -EIO;
0424 struct cpuidle_state *state = kobj_to_state(kobj);
0425 struct cpuidle_state_usage *state_usage = kobj_to_state_usage(kobj);
0426 struct cpuidle_state_attr *cattr = attr_to_stateattr(attr);
0427 struct cpuidle_device *dev = kobj_to_device(kobj);
0428
0429 if (cattr->store)
0430 ret = cattr->store(state, state_usage, buf, size);
0431
0432
0433 dev->poll_limit_ns = 0;
0434
0435 return ret;
0436 }
0437
0438 static const struct sysfs_ops cpuidle_state_sysfs_ops = {
0439 .show = cpuidle_state_show,
0440 .store = cpuidle_state_store,
0441 };
0442
0443 static void cpuidle_state_sysfs_release(struct kobject *kobj)
0444 {
0445 struct cpuidle_state_kobj *state_obj = kobj_to_state_obj(kobj);
0446
0447 complete(&state_obj->kobj_unregister);
0448 }
0449
0450 static struct kobj_type ktype_state_cpuidle = {
0451 .sysfs_ops = &cpuidle_state_sysfs_ops,
0452 .default_groups = cpuidle_state_default_groups,
0453 .release = cpuidle_state_sysfs_release,
0454 };
0455
0456 static inline void cpuidle_free_state_kobj(struct cpuidle_device *device, int i)
0457 {
0458 cpuidle_remove_s2idle_attr_group(device->kobjs[i]);
0459 kobject_put(&device->kobjs[i]->kobj);
0460 wait_for_completion(&device->kobjs[i]->kobj_unregister);
0461 kfree(device->kobjs[i]);
0462 device->kobjs[i] = NULL;
0463 }
0464
0465
0466
0467
0468
0469 static int cpuidle_add_state_sysfs(struct cpuidle_device *device)
0470 {
0471 int i, ret = -ENOMEM;
0472 struct cpuidle_state_kobj *kobj;
0473 struct cpuidle_device_kobj *kdev = device->kobj_dev;
0474 struct cpuidle_driver *drv = cpuidle_get_cpu_driver(device);
0475
0476
0477 for (i = 0; i < drv->state_count; i++) {
0478 kobj = kzalloc(sizeof(struct cpuidle_state_kobj), GFP_KERNEL);
0479 if (!kobj) {
0480 ret = -ENOMEM;
0481 goto error_state;
0482 }
0483 kobj->state = &drv->states[i];
0484 kobj->state_usage = &device->states_usage[i];
0485 kobj->device = device;
0486 init_completion(&kobj->kobj_unregister);
0487
0488 ret = kobject_init_and_add(&kobj->kobj, &ktype_state_cpuidle,
0489 &kdev->kobj, "state%d", i);
0490 if (ret) {
0491 kobject_put(&kobj->kobj);
0492 kfree(kobj);
0493 goto error_state;
0494 }
0495 cpuidle_add_s2idle_attr_group(kobj);
0496 kobject_uevent(&kobj->kobj, KOBJ_ADD);
0497 device->kobjs[i] = kobj;
0498 }
0499
0500 return 0;
0501
0502 error_state:
0503 for (i = i - 1; i >= 0; i--)
0504 cpuidle_free_state_kobj(device, i);
0505 return ret;
0506 }
0507
0508
0509
0510
0511
0512 static void cpuidle_remove_state_sysfs(struct cpuidle_device *device)
0513 {
0514 struct cpuidle_driver *drv = cpuidle_get_cpu_driver(device);
0515 int i;
0516
0517 for (i = 0; i < drv->state_count; i++)
0518 cpuidle_free_state_kobj(device, i);
0519 }
0520
0521 #ifdef CONFIG_CPU_IDLE_MULTIPLE_DRIVERS
0522 #define kobj_to_driver_kobj(k) container_of(k, struct cpuidle_driver_kobj, kobj)
0523 #define attr_to_driver_attr(a) container_of(a, struct cpuidle_driver_attr, attr)
0524
0525 #define define_one_driver_ro(_name, show) \
0526 static struct cpuidle_driver_attr attr_driver_##_name = \
0527 __ATTR(_name, 0444, show, NULL)
0528
0529 struct cpuidle_driver_kobj {
0530 struct cpuidle_driver *drv;
0531 struct completion kobj_unregister;
0532 struct kobject kobj;
0533 };
0534
0535 struct cpuidle_driver_attr {
0536 struct attribute attr;
0537 ssize_t (*show)(struct cpuidle_driver *, char *);
0538 ssize_t (*store)(struct cpuidle_driver *, const char *, size_t);
0539 };
0540
0541 static ssize_t show_driver_name(struct cpuidle_driver *drv, char *buf)
0542 {
0543 ssize_t ret;
0544
0545 spin_lock(&cpuidle_driver_lock);
0546 ret = sprintf(buf, "%s\n", drv ? drv->name : "none");
0547 spin_unlock(&cpuidle_driver_lock);
0548
0549 return ret;
0550 }
0551
0552 static void cpuidle_driver_sysfs_release(struct kobject *kobj)
0553 {
0554 struct cpuidle_driver_kobj *driver_kobj = kobj_to_driver_kobj(kobj);
0555 complete(&driver_kobj->kobj_unregister);
0556 }
0557
0558 static ssize_t cpuidle_driver_show(struct kobject *kobj, struct attribute *attr,
0559 char *buf)
0560 {
0561 int ret = -EIO;
0562 struct cpuidle_driver_kobj *driver_kobj = kobj_to_driver_kobj(kobj);
0563 struct cpuidle_driver_attr *dattr = attr_to_driver_attr(attr);
0564
0565 if (dattr->show)
0566 ret = dattr->show(driver_kobj->drv, buf);
0567
0568 return ret;
0569 }
0570
0571 static ssize_t cpuidle_driver_store(struct kobject *kobj, struct attribute *attr,
0572 const char *buf, size_t size)
0573 {
0574 int ret = -EIO;
0575 struct cpuidle_driver_kobj *driver_kobj = kobj_to_driver_kobj(kobj);
0576 struct cpuidle_driver_attr *dattr = attr_to_driver_attr(attr);
0577
0578 if (dattr->store)
0579 ret = dattr->store(driver_kobj->drv, buf, size);
0580
0581 return ret;
0582 }
0583
0584 define_one_driver_ro(name, show_driver_name);
0585
0586 static const struct sysfs_ops cpuidle_driver_sysfs_ops = {
0587 .show = cpuidle_driver_show,
0588 .store = cpuidle_driver_store,
0589 };
0590
0591 static struct attribute *cpuidle_driver_default_attrs[] = {
0592 &attr_driver_name.attr,
0593 NULL
0594 };
0595 ATTRIBUTE_GROUPS(cpuidle_driver_default);
0596
0597 static struct kobj_type ktype_driver_cpuidle = {
0598 .sysfs_ops = &cpuidle_driver_sysfs_ops,
0599 .default_groups = cpuidle_driver_default_groups,
0600 .release = cpuidle_driver_sysfs_release,
0601 };
0602
0603
0604
0605
0606
0607 static int cpuidle_add_driver_sysfs(struct cpuidle_device *dev)
0608 {
0609 struct cpuidle_driver_kobj *kdrv;
0610 struct cpuidle_device_kobj *kdev = dev->kobj_dev;
0611 struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
0612 int ret;
0613
0614 kdrv = kzalloc(sizeof(*kdrv), GFP_KERNEL);
0615 if (!kdrv)
0616 return -ENOMEM;
0617
0618 kdrv->drv = drv;
0619 init_completion(&kdrv->kobj_unregister);
0620
0621 ret = kobject_init_and_add(&kdrv->kobj, &ktype_driver_cpuidle,
0622 &kdev->kobj, "driver");
0623 if (ret) {
0624 kobject_put(&kdrv->kobj);
0625 kfree(kdrv);
0626 return ret;
0627 }
0628
0629 kobject_uevent(&kdrv->kobj, KOBJ_ADD);
0630 dev->kobj_driver = kdrv;
0631
0632 return ret;
0633 }
0634
0635
0636
0637
0638
0639 static void cpuidle_remove_driver_sysfs(struct cpuidle_device *dev)
0640 {
0641 struct cpuidle_driver_kobj *kdrv = dev->kobj_driver;
0642 kobject_put(&kdrv->kobj);
0643 wait_for_completion(&kdrv->kobj_unregister);
0644 kfree(kdrv);
0645 }
0646 #else
0647 static inline int cpuidle_add_driver_sysfs(struct cpuidle_device *dev)
0648 {
0649 return 0;
0650 }
0651
0652 static inline void cpuidle_remove_driver_sysfs(struct cpuidle_device *dev)
0653 {
0654 ;
0655 }
0656 #endif
0657
0658
0659
0660
0661
0662 int cpuidle_add_device_sysfs(struct cpuidle_device *device)
0663 {
0664 int ret;
0665
0666 ret = cpuidle_add_state_sysfs(device);
0667 if (ret)
0668 return ret;
0669
0670 ret = cpuidle_add_driver_sysfs(device);
0671 if (ret)
0672 cpuidle_remove_state_sysfs(device);
0673 return ret;
0674 }
0675
0676
0677
0678
0679
0680 void cpuidle_remove_device_sysfs(struct cpuidle_device *device)
0681 {
0682 cpuidle_remove_driver_sysfs(device);
0683 cpuidle_remove_state_sysfs(device);
0684 }
0685
0686
0687
0688
0689
0690 int cpuidle_add_sysfs(struct cpuidle_device *dev)
0691 {
0692 struct cpuidle_device_kobj *kdev;
0693 struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu);
0694 int error;
0695
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705 if (!cpu_dev)
0706 return -ENODEV;
0707
0708 kdev = kzalloc(sizeof(*kdev), GFP_KERNEL);
0709 if (!kdev)
0710 return -ENOMEM;
0711 kdev->dev = dev;
0712
0713 init_completion(&kdev->kobj_unregister);
0714
0715 error = kobject_init_and_add(&kdev->kobj, &ktype_cpuidle, &cpu_dev->kobj,
0716 "cpuidle");
0717 if (error) {
0718 kobject_put(&kdev->kobj);
0719 kfree(kdev);
0720 return error;
0721 }
0722
0723 dev->kobj_dev = kdev;
0724 kobject_uevent(&kdev->kobj, KOBJ_ADD);
0725
0726 return 0;
0727 }
0728
0729
0730
0731
0732
0733 void cpuidle_remove_sysfs(struct cpuidle_device *dev)
0734 {
0735 struct cpuidle_device_kobj *kdev = dev->kobj_dev;
0736
0737 kobject_put(&kdev->kobj);
0738 wait_for_completion(&kdev->kobj_unregister);
0739 kfree(kdev);
0740 }