Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * sysfs.c - sysfs support
0003  *
0004  * (C) 2006-2007 Shaohua Li <shaohua.li@intel.com>
0005  *
0006  * This code is licenced under the GPL.
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  * cpuidle_add_interface - add CPU global sysfs attributes
0122  * @dev: the target device
0123  */
0124 int cpuidle_add_interface(struct device *dev)
0125 {
0126     return sysfs_create_group(&dev->kobj, &cpuidle_attr_group);
0127 }
0128 
0129 /**
0130  * cpuidle_remove_interface - remove CPU global sysfs attributes
0131  * @dev: the target device
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 /* CONFIG_SUSPEND */
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     /* reset poll time cache */
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  * cpuidle_add_state_sysfs - adds cpuidle states sysfs attributes
0467  * @device: the target device
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     /* state statistics */
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  * cpuidle_remove_state_sysfs - removes the cpuidle states sysfs attributes
0510  * @device: the target device
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  * cpuidle_add_driver_sysfs - adds the driver name sysfs attribute
0605  * @dev: the target device
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  * cpuidle_remove_driver_sysfs - removes the driver name sysfs attribute
0637  * @dev: the target device
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  * cpuidle_add_device_sysfs - adds device specific sysfs attributes
0660  * @device: the target device
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  * cpuidle_remove_device_sysfs : removes device specific sysfs attributes
0678  * @device : the target device
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  * cpuidle_add_sysfs - creates a sysfs instance for the target device
0688  * @dev: the target device
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      * Return if cpu_device is not setup for this CPU.
0698      *
0699      * This could happen if the arch did not set up cpu_device
0700      * since this CPU is not in cpu_present mask and the
0701      * driver did not send a correct CPU mask during registration.
0702      * Without this check we would end up passing bogus
0703      * value for &cpu_dev->kobj in kobject_init_and_add()
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  * cpuidle_remove_sysfs - deletes a sysfs instance on the target device
0731  * @dev: the target device
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 }