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