1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Power capping class 4 * Copyright (c) 2013, Intel Corporation. 5 */ 6 7 #include <linux/module.h> 8 #include <linux/device.h> 9 #include <linux/err.h> 10 #include <linux/slab.h> 11 #include <linux/powercap.h> 12 13 #define to_powercap_zone(n) container_of(n, struct powercap_zone, dev) 14 #define to_powercap_control_type(n) \ 15 container_of(n, struct powercap_control_type, dev) 16 17 /* Power zone show function */ 18 #define define_power_zone_show(_attr) \ 19 static ssize_t _attr##_show(struct device *dev, \ 20 struct device_attribute *dev_attr,\ 21 char *buf) \ 22 { \ 23 u64 value; \ 24 ssize_t len = -EINVAL; \ 25 struct powercap_zone *power_zone = to_powercap_zone(dev); \ 26 \ 27 if (power_zone->ops->get_##_attr) { \ 28 if (!power_zone->ops->get_##_attr(power_zone, &value)) \ 29 len = sprintf(buf, "%lld\n", value); \ 30 } \ 31 \ 32 return len; \ 33 } 34 35 /* The only meaningful input is 0 (reset), others are silently ignored */ 36 #define define_power_zone_store(_attr) \ 37 static ssize_t _attr##_store(struct device *dev,\ 38 struct device_attribute *dev_attr, \ 39 const char *buf, size_t count) \ 40 { \ 41 int err; \ 42 struct powercap_zone *power_zone = to_powercap_zone(dev); \ 43 u64 value; \ 44 \ 45 err = kstrtoull(buf, 10, &value); \ 46 if (err) \ 47 return -EINVAL; \ 48 if (value) \ 49 return count; \ 50 if (power_zone->ops->reset_##_attr) { \ 51 if (!power_zone->ops->reset_##_attr(power_zone)) \ 52 return count; \ 53 } \ 54 \ 55 return -EINVAL; \ 56 } 57 58 /* Power zone constraint show function */ 59 #define define_power_zone_constraint_show(_attr) \ 60 static ssize_t show_constraint_##_attr(struct device *dev, \ 61 struct device_attribute *dev_attr,\ 62 char *buf) \ 63 { \ 64 u64 value; \ 65 ssize_t len = -ENODATA; \ 66 struct powercap_zone *power_zone = to_powercap_zone(dev); \ 67 int id; \ 68 struct powercap_zone_constraint *pconst;\ 69 \ 70 if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \ 71 return -EINVAL; \ 72 if (id >= power_zone->const_id_cnt) \ 73 return -EINVAL; \ 74 pconst = &power_zone->constraints[id]; \ 75 if (pconst && pconst->ops && pconst->ops->get_##_attr) { \ 76 if (!pconst->ops->get_##_attr(power_zone, id, &value)) \ 77 len = sprintf(buf, "%lld\n", value); \ 78 } \ 79 \ 80 return len; \ 81 } 82 83 /* Power zone constraint store function */ 84 #define define_power_zone_constraint_store(_attr) \ 85 static ssize_t store_constraint_##_attr(struct device *dev,\ 86 struct device_attribute *dev_attr, \ 87 const char *buf, size_t count) \ 88 { \ 89 int err; \ 90 u64 value; \ 91 struct powercap_zone *power_zone = to_powercap_zone(dev); \ 92 int id; \ 93 struct powercap_zone_constraint *pconst;\ 94 \ 95 if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \ 96 return -EINVAL; \ 97 if (id >= power_zone->const_id_cnt) \ 98 return -EINVAL; \ 99 pconst = &power_zone->constraints[id]; \ 100 err = kstrtoull(buf, 10, &value); \ 101 if (err) \ 102 return -EINVAL; \ 103 if (pconst && pconst->ops && pconst->ops->set_##_attr) { \ 104 if (!pconst->ops->set_##_attr(power_zone, id, value)) \ 105 return count; \ 106 } \ 107 \ 108 return -ENODATA; \ 109 } 110 111 /* Power zone information callbacks */ 112 define_power_zone_show(power_uw); 113 define_power_zone_show(max_power_range_uw); 114 define_power_zone_show(energy_uj); 115 define_power_zone_store(energy_uj); 116 define_power_zone_show(max_energy_range_uj); 117 118 /* Power zone attributes */ 119 static DEVICE_ATTR_RO(max_power_range_uw); 120 static DEVICE_ATTR_RO(power_uw); 121 static DEVICE_ATTR_RO(max_energy_range_uj); 122 static DEVICE_ATTR_RW(energy_uj); 123 124 /* Power zone constraint attributes callbacks */ 125 define_power_zone_constraint_show(power_limit_uw); 126 define_power_zone_constraint_store(power_limit_uw); 127 define_power_zone_constraint_show(time_window_us); 128 define_power_zone_constraint_store(time_window_us); 129 define_power_zone_constraint_show(max_power_uw); 130 define_power_zone_constraint_show(min_power_uw); 131 define_power_zone_constraint_show(max_time_window_us); 132 define_power_zone_constraint_show(min_time_window_us); 133 134 /* For one time seeding of constraint device attributes */ 135 struct powercap_constraint_attr { 136 struct device_attribute power_limit_attr; 137 struct device_attribute time_window_attr; 138 struct device_attribute max_power_attr; 139 struct device_attribute min_power_attr; 140 struct device_attribute max_time_window_attr; 141 struct device_attribute min_time_window_attr; 142 struct device_attribute name_attr; 143 }; 144 145 static struct powercap_constraint_attr 146 constraint_attrs[MAX_CONSTRAINTS_PER_ZONE]; 147 148 /* A list of powercap control_types */ 149 static LIST_HEAD(powercap_cntrl_list); 150 /* Mutex to protect list of powercap control_types */ 151 static DEFINE_MUTEX(powercap_cntrl_list_lock); 152 153 #define POWERCAP_CONSTRAINT_NAME_LEN 30 /* Some limit to avoid overflow */ 154 static ssize_t show_constraint_name(struct device *dev, 155 struct device_attribute *dev_attr, 156 char *buf) 157 { 158 const char *name; 159 struct powercap_zone *power_zone = to_powercap_zone(dev); 160 int id; 161 ssize_t len = -ENODATA; 162 struct powercap_zone_constraint *pconst; 163 164 if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) 165 return -EINVAL; 166 if (id >= power_zone->const_id_cnt) 167 return -EINVAL; 168 pconst = &power_zone->constraints[id]; 169 170 if (pconst && pconst->ops && pconst->ops->get_name) { 171 name = pconst->ops->get_name(power_zone, id); 172 if (name) { 173 snprintf(buf, POWERCAP_CONSTRAINT_NAME_LEN, 174 "%s\n", name); 175 buf[POWERCAP_CONSTRAINT_NAME_LEN] = '\0'; 176 len = strlen(buf); 177 } 178 } 179 180 return len; 181 } 182 183 static int create_constraint_attribute(int id, const char *name, 184 int mode, 185 struct device_attribute *dev_attr, 186 ssize_t (*show)(struct device *, 187 struct device_attribute *, char *), 188 ssize_t (*store)(struct device *, 189 struct device_attribute *, 190 const char *, size_t) 191 ) 192 { 193 194 dev_attr->attr.name = kasprintf(GFP_KERNEL, "constraint_%d_%s", 195 id, name); 196 if (!dev_attr->attr.name) 197 return -ENOMEM; 198 dev_attr->attr.mode = mode; 199 dev_attr->show = show; 200 dev_attr->store = store; 201 202 return 0; 203 } 204 205 static void free_constraint_attributes(void) 206 { 207 int i; 208 209 for (i = 0; i < MAX_CONSTRAINTS_PER_ZONE; ++i) { 210 kfree(constraint_attrs[i].power_limit_attr.attr.name); 211 kfree(constraint_attrs[i].time_window_attr.attr.name); 212 kfree(constraint_attrs[i].name_attr.attr.name); 213 kfree(constraint_attrs[i].max_power_attr.attr.name); 214 kfree(constraint_attrs[i].min_power_attr.attr.name); 215 kfree(constraint_attrs[i].max_time_window_attr.attr.name); 216 kfree(constraint_attrs[i].min_time_window_attr.attr.name); 217 } 218 } 219 220 static int seed_constraint_attributes(void) 221 { 222 int i; 223 int ret; 224 225 for (i = 0; i < MAX_CONSTRAINTS_PER_ZONE; ++i) { 226 ret = create_constraint_attribute(i, "power_limit_uw", 227 S_IWUSR | S_IRUGO, 228 &constraint_attrs[i].power_limit_attr, 229 show_constraint_power_limit_uw, 230 store_constraint_power_limit_uw); 231 if (ret) 232 goto err_alloc; 233 ret = create_constraint_attribute(i, "time_window_us", 234 S_IWUSR | S_IRUGO, 235 &constraint_attrs[i].time_window_attr, 236 show_constraint_time_window_us, 237 store_constraint_time_window_us); 238 if (ret) 239 goto err_alloc; 240 ret = create_constraint_attribute(i, "name", S_IRUGO, 241 &constraint_attrs[i].name_attr, 242 show_constraint_name, 243 NULL); 244 if (ret) 245 goto err_alloc; 246 ret = create_constraint_attribute(i, "max_power_uw", S_IRUGO, 247 &constraint_attrs[i].max_power_attr, 248 show_constraint_max_power_uw, 249 NULL); 250 if (ret) 251 goto err_alloc; 252 ret = create_constraint_attribute(i, "min_power_uw", S_IRUGO, 253 &constraint_attrs[i].min_power_attr, 254 show_constraint_min_power_uw, 255 NULL); 256 if (ret) 257 goto err_alloc; 258 ret = create_constraint_attribute(i, "max_time_window_us", 259 S_IRUGO, 260 &constraint_attrs[i].max_time_window_attr, 261 show_constraint_max_time_window_us, 262 NULL); 263 if (ret) 264 goto err_alloc; 265 ret = create_constraint_attribute(i, "min_time_window_us", 266 S_IRUGO, 267 &constraint_attrs[i].min_time_window_attr, 268 show_constraint_min_time_window_us, 269 NULL); 270 if (ret) 271 goto err_alloc; 272 273 } 274 275 return 0; 276 277 err_alloc: 278 free_constraint_attributes(); 279 280 return ret; 281 } 282 283 static int create_constraints(struct powercap_zone *power_zone, 284 int nr_constraints, 285 const struct powercap_zone_constraint_ops *const_ops) 286 { 287 int i; 288 int ret = 0; 289 int count; 290 struct powercap_zone_constraint *pconst; 291 292 if (!power_zone || !const_ops || !const_ops->get_power_limit_uw || 293 !const_ops->set_power_limit_uw || 294 !const_ops->get_time_window_us || 295 !const_ops->set_time_window_us) 296 return -EINVAL; 297 298 count = power_zone->zone_attr_count; 299 for (i = 0; i < nr_constraints; ++i) { 300 pconst = &power_zone->constraints[i]; 301 pconst->ops = const_ops; 302 pconst->id = power_zone->const_id_cnt; 303 power_zone->const_id_cnt++; 304 power_zone->zone_dev_attrs[count++] = 305 &constraint_attrs[i].power_limit_attr.attr; 306 power_zone->zone_dev_attrs[count++] = 307 &constraint_attrs[i].time_window_attr.attr; 308 if (pconst->ops->get_name) 309 power_zone->zone_dev_attrs[count++] = 310 &constraint_attrs[i].name_attr.attr; 311 if (pconst->ops->get_max_power_uw) 312 power_zone->zone_dev_attrs[count++] = 313 &constraint_attrs[i].max_power_attr.attr; 314 if (pconst->ops->get_min_power_uw) 315 power_zone->zone_dev_attrs[count++] = 316 &constraint_attrs[i].min_power_attr.attr; 317 if (pconst->ops->get_max_time_window_us) 318 power_zone->zone_dev_attrs[count++] = 319 &constraint_attrs[i].max_time_window_attr.attr; 320 if (pconst->ops->get_min_time_window_us) 321 power_zone->zone_dev_attrs[count++] = 322 &constraint_attrs[i].min_time_window_attr.attr; 323 } 324 power_zone->zone_attr_count = count; 325 326 return ret; 327 } 328 329 static bool control_type_valid(void *control_type) 330 { 331 struct powercap_control_type *pos = NULL; 332 bool found = false; 333 334 mutex_lock(&powercap_cntrl_list_lock); 335 336 list_for_each_entry(pos, &powercap_cntrl_list, node) { 337 if (pos == control_type) { 338 found = true; 339 break; 340 } 341 } 342 mutex_unlock(&powercap_cntrl_list_lock); 343 344 return found; 345 } 346 347 static ssize_t name_show(struct device *dev, 348 struct device_attribute *attr, 349 char *buf) 350 { 351 struct powercap_zone *power_zone = to_powercap_zone(dev); 352 353 return sprintf(buf, "%s\n", power_zone->name); 354 } 355 356 static DEVICE_ATTR_RO(name); 357 358 /* Create zone and attributes in sysfs */ 359 static void create_power_zone_common_attributes( 360 struct powercap_zone *power_zone) 361 { 362 int count = 0; 363 364 power_zone->zone_dev_attrs[count++] = &dev_attr_name.attr; 365 if (power_zone->ops->get_max_energy_range_uj) 366 power_zone->zone_dev_attrs[count++] = 367 &dev_attr_max_energy_range_uj.attr; 368 if (power_zone->ops->get_energy_uj) { 369 if (power_zone->ops->reset_energy_uj) 370 dev_attr_energy_uj.attr.mode = S_IWUSR | S_IRUGO; 371 else 372 dev_attr_energy_uj.attr.mode = S_IRUGO; 373 power_zone->zone_dev_attrs[count++] = 374 &dev_attr_energy_uj.attr; 375 } 376 if (power_zone->ops->get_power_uw) 377 power_zone->zone_dev_attrs[count++] = 378 &dev_attr_power_uw.attr; 379 if (power_zone->ops->get_max_power_range_uw) 380 power_zone->zone_dev_attrs[count++] = 381 &dev_attr_max_power_range_uw.attr; 382 power_zone->zone_dev_attrs[count] = NULL; 383 power_zone->zone_attr_count = count; 384 } 385 386 static void powercap_release(struct device *dev) 387 { 388 bool allocated; 389 390 if (dev->parent) { 391 struct powercap_zone *power_zone = to_powercap_zone(dev); 392 393 /* Store flag as the release() may free memory */ 394 allocated = power_zone->allocated; 395 /* Remove id from parent idr struct */ 396 idr_remove(power_zone->parent_idr, power_zone->id); 397 /* Destroy idrs allocated for this zone */ 398 idr_destroy(&power_zone->idr); 399 kfree(power_zone->name); 400 kfree(power_zone->zone_dev_attrs); 401 kfree(power_zone->constraints); 402 if (power_zone->ops->release) 403 power_zone->ops->release(power_zone); 404 if (allocated) 405 kfree(power_zone); 406 } else { 407 struct powercap_control_type *control_type = 408 to_powercap_control_type(dev); 409 410 /* Store flag as the release() may free memory */ 411 allocated = control_type->allocated; 412 idr_destroy(&control_type->idr); 413 mutex_destroy(&control_type->lock); 414 if (control_type->ops && control_type->ops->release) 415 control_type->ops->release(control_type); 416 if (allocated) 417 kfree(control_type); 418 } 419 } 420 421 static ssize_t enabled_show(struct device *dev, 422 struct device_attribute *attr, 423 char *buf) 424 { 425 bool mode = true; 426 427 /* Default is enabled */ 428 if (dev->parent) { 429 struct powercap_zone *power_zone = to_powercap_zone(dev); 430 if (power_zone->ops->get_enable) 431 if (power_zone->ops->get_enable(power_zone, &mode)) 432 mode = false; 433 } else { 434 struct powercap_control_type *control_type = 435 to_powercap_control_type(dev); 436 if (control_type->ops && control_type->ops->get_enable) 437 if (control_type->ops->get_enable(control_type, &mode)) 438 mode = false; 439 } 440 441 return sprintf(buf, "%d\n", mode); 442 } 443 444 static ssize_t enabled_store(struct device *dev, 445 struct device_attribute *attr, 446 const char *buf, size_t len) 447 { 448 bool mode; 449 450 if (strtobool(buf, &mode)) 451 return -EINVAL; 452 if (dev->parent) { 453 struct powercap_zone *power_zone = to_powercap_zone(dev); 454 if (power_zone->ops->set_enable) 455 if (!power_zone->ops->set_enable(power_zone, mode)) 456 return len; 457 } else { 458 struct powercap_control_type *control_type = 459 to_powercap_control_type(dev); 460 if (control_type->ops && control_type->ops->set_enable) 461 if (!control_type->ops->set_enable(control_type, mode)) 462 return len; 463 } 464 465 return -ENOSYS; 466 } 467 468 static DEVICE_ATTR_RW(enabled); 469 470 static struct attribute *powercap_attrs[] = { 471 &dev_attr_enabled.attr, 472 NULL, 473 }; 474 ATTRIBUTE_GROUPS(powercap); 475 476 static struct class powercap_class = { 477 .name = "powercap", 478 .dev_release = powercap_release, 479 .dev_groups = powercap_groups, 480 }; 481 482 struct powercap_zone *powercap_register_zone( 483 struct powercap_zone *power_zone, 484 struct powercap_control_type *control_type, 485 const char *name, 486 struct powercap_zone *parent, 487 const struct powercap_zone_ops *ops, 488 int nr_constraints, 489 const struct powercap_zone_constraint_ops *const_ops) 490 { 491 int result; 492 int nr_attrs; 493 494 if (!name || !control_type || !ops || 495 nr_constraints > MAX_CONSTRAINTS_PER_ZONE || 496 (!ops->get_energy_uj && !ops->get_power_uw) || 497 !control_type_valid(control_type)) 498 return ERR_PTR(-EINVAL); 499 500 if (power_zone) { 501 if (!ops->release) 502 return ERR_PTR(-EINVAL); 503 memset(power_zone, 0, sizeof(*power_zone)); 504 } else { 505 power_zone = kzalloc(sizeof(*power_zone), GFP_KERNEL); 506 if (!power_zone) 507 return ERR_PTR(-ENOMEM); 508 power_zone->allocated = true; 509 } 510 power_zone->ops = ops; 511 power_zone->control_type_inst = control_type; 512 if (!parent) { 513 power_zone->dev.parent = &control_type->dev; 514 power_zone->parent_idr = &control_type->idr; 515 } else { 516 power_zone->dev.parent = &parent->dev; 517 power_zone->parent_idr = &parent->idr; 518 } 519 power_zone->dev.class = &powercap_class; 520 521 mutex_lock(&control_type->lock); 522 /* Using idr to get the unique id */ 523 result = idr_alloc(power_zone->parent_idr, NULL, 0, 0, GFP_KERNEL); 524 if (result < 0) 525 goto err_idr_alloc; 526 527 power_zone->id = result; 528 idr_init(&power_zone->idr); 529 result = -ENOMEM; 530 power_zone->name = kstrdup(name, GFP_KERNEL); 531 if (!power_zone->name) 532 goto err_name_alloc; 533 dev_set_name(&power_zone->dev, "%s:%x", 534 dev_name(power_zone->dev.parent), 535 power_zone->id); 536 power_zone->constraints = kcalloc(nr_constraints, 537 sizeof(*power_zone->constraints), 538 GFP_KERNEL); 539 if (!power_zone->constraints) 540 goto err_const_alloc; 541 542 nr_attrs = nr_constraints * POWERCAP_CONSTRAINTS_ATTRS + 543 POWERCAP_ZONE_MAX_ATTRS + 1; 544 power_zone->zone_dev_attrs = kcalloc(nr_attrs, sizeof(void *), 545 GFP_KERNEL); 546 if (!power_zone->zone_dev_attrs) 547 goto err_attr_alloc; 548 create_power_zone_common_attributes(power_zone); 549 result = create_constraints(power_zone, nr_constraints, const_ops); 550 if (result) 551 goto err_dev_ret; 552 553 power_zone->zone_dev_attrs[power_zone->zone_attr_count] = NULL; 554 power_zone->dev_zone_attr_group.attrs = power_zone->zone_dev_attrs; 555 power_zone->dev_attr_groups[0] = &power_zone->dev_zone_attr_group; 556 power_zone->dev_attr_groups[1] = NULL; 557 power_zone->dev.groups = power_zone->dev_attr_groups; 558 result = device_register(&power_zone->dev); 559 if (result) 560 goto err_dev_ret; 561 562 control_type->nr_zones++; 563 mutex_unlock(&control_type->lock); 564 565 return power_zone; 566 567 err_dev_ret: 568 kfree(power_zone->zone_dev_attrs); 569 err_attr_alloc: 570 kfree(power_zone->constraints); 571 err_const_alloc: 572 kfree(power_zone->name); 573 err_name_alloc: 574 idr_remove(power_zone->parent_idr, power_zone->id); 575 err_idr_alloc: 576 if (power_zone->allocated) 577 kfree(power_zone); 578 mutex_unlock(&control_type->lock); 579 580 return ERR_PTR(result); 581 } 582 EXPORT_SYMBOL_GPL(powercap_register_zone); 583 584 int powercap_unregister_zone(struct powercap_control_type *control_type, 585 struct powercap_zone *power_zone) 586 { 587 if (!power_zone || !control_type) 588 return -EINVAL; 589 590 mutex_lock(&control_type->lock); 591 control_type->nr_zones--; 592 mutex_unlock(&control_type->lock); 593 594 device_unregister(&power_zone->dev); 595 596 return 0; 597 } 598 EXPORT_SYMBOL_GPL(powercap_unregister_zone); 599 600 struct powercap_control_type *powercap_register_control_type( 601 struct powercap_control_type *control_type, 602 const char *name, 603 const struct powercap_control_type_ops *ops) 604 { 605 int result; 606 607 if (!name) 608 return ERR_PTR(-EINVAL); 609 if (control_type) { 610 if (!ops || !ops->release) 611 return ERR_PTR(-EINVAL); 612 memset(control_type, 0, sizeof(*control_type)); 613 } else { 614 control_type = kzalloc(sizeof(*control_type), GFP_KERNEL); 615 if (!control_type) 616 return ERR_PTR(-ENOMEM); 617 control_type->allocated = true; 618 } 619 mutex_init(&control_type->lock); 620 control_type->ops = ops; 621 INIT_LIST_HEAD(&control_type->node); 622 control_type->dev.class = &powercap_class; 623 dev_set_name(&control_type->dev, "%s", name); 624 result = device_register(&control_type->dev); 625 if (result) { 626 if (control_type->allocated) 627 kfree(control_type); 628 return ERR_PTR(result); 629 } 630 idr_init(&control_type->idr); 631 632 mutex_lock(&powercap_cntrl_list_lock); 633 list_add_tail(&control_type->node, &powercap_cntrl_list); 634 mutex_unlock(&powercap_cntrl_list_lock); 635 636 return control_type; 637 } 638 EXPORT_SYMBOL_GPL(powercap_register_control_type); 639 640 int powercap_unregister_control_type(struct powercap_control_type *control_type) 641 { 642 struct powercap_control_type *pos = NULL; 643 644 if (control_type->nr_zones) { 645 dev_err(&control_type->dev, "Zones of this type still not freed\n"); 646 return -EINVAL; 647 } 648 mutex_lock(&powercap_cntrl_list_lock); 649 list_for_each_entry(pos, &powercap_cntrl_list, node) { 650 if (pos == control_type) { 651 list_del(&control_type->node); 652 mutex_unlock(&powercap_cntrl_list_lock); 653 device_unregister(&control_type->dev); 654 return 0; 655 } 656 } 657 mutex_unlock(&powercap_cntrl_list_lock); 658 659 return -ENODEV; 660 } 661 EXPORT_SYMBOL_GPL(powercap_unregister_control_type); 662 663 static int __init powercap_init(void) 664 { 665 int result; 666 667 result = seed_constraint_attributes(); 668 if (result) 669 return result; 670 671 return class_register(&powercap_class); 672 } 673 674 fs_initcall(powercap_init); 675 676 MODULE_DESCRIPTION("PowerCap sysfs Driver"); 677 MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>"); 678 MODULE_LICENSE("GPL v2"); 679