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/kstrtox.h> 11 #include <linux/slab.h> 12 #include <linux/powercap.h> 13 14 #define to_powercap_zone(n) container_of(n, struct powercap_zone, dev) 15 #define to_powercap_control_type(n) \ 16 container_of(n, struct powercap_control_type, dev) 17 18 /* Power zone show function */ 19 #define define_power_zone_show(_attr) \ 20 static ssize_t _attr##_show(struct device *dev, \ 21 struct device_attribute *dev_attr,\ 22 char *buf) \ 23 { \ 24 u64 value; \ 25 ssize_t len = -EINVAL; \ 26 struct powercap_zone *power_zone = to_powercap_zone(dev); \ 27 \ 28 if (power_zone->ops->get_##_attr) { \ 29 if (!power_zone->ops->get_##_attr(power_zone, &value)) \ 30 len = sprintf(buf, "%lld\n", value); \ 31 } \ 32 \ 33 return len; \ 34 } 35 36 /* The only meaningful input is 0 (reset), others are silently ignored */ 37 #define define_power_zone_store(_attr) \ 38 static ssize_t _attr##_store(struct device *dev,\ 39 struct device_attribute *dev_attr, \ 40 const char *buf, size_t count) \ 41 { \ 42 int err; \ 43 struct powercap_zone *power_zone = to_powercap_zone(dev); \ 44 u64 value; \ 45 \ 46 err = kstrtoull(buf, 10, &value); \ 47 if (err) \ 48 return -EINVAL; \ 49 if (value) \ 50 return count; \ 51 if (power_zone->ops->reset_##_attr) { \ 52 if (!power_zone->ops->reset_##_attr(power_zone)) \ 53 return count; \ 54 } \ 55 \ 56 return -EINVAL; \ 57 } 58 59 /* Power zone constraint show function */ 60 #define define_power_zone_constraint_show(_attr) \ 61 static ssize_t show_constraint_##_attr(struct device *dev, \ 62 struct device_attribute *dev_attr,\ 63 char *buf) \ 64 { \ 65 u64 value; \ 66 ssize_t len = -ENODATA; \ 67 struct powercap_zone *power_zone = to_powercap_zone(dev); \ 68 int id; \ 69 struct powercap_zone_constraint *pconst;\ 70 \ 71 if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \ 72 return -EINVAL; \ 73 if (id >= power_zone->const_id_cnt) \ 74 return -EINVAL; \ 75 pconst = &power_zone->constraints[id]; \ 76 if (pconst && pconst->ops && pconst->ops->get_##_attr) { \ 77 if (!pconst->ops->get_##_attr(power_zone, id, &value)) \ 78 len = sprintf(buf, "%lld\n", value); \ 79 } \ 80 \ 81 return len; \ 82 } 83 84 /* Power zone constraint store function */ 85 #define define_power_zone_constraint_store(_attr) \ 86 static ssize_t store_constraint_##_attr(struct device *dev,\ 87 struct device_attribute *dev_attr, \ 88 const char *buf, size_t count) \ 89 { \ 90 int err; \ 91 u64 value; \ 92 struct powercap_zone *power_zone = to_powercap_zone(dev); \ 93 int id; \ 94 struct powercap_zone_constraint *pconst;\ 95 \ 96 if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \ 97 return -EINVAL; \ 98 if (id >= power_zone->const_id_cnt) \ 99 return -EINVAL; \ 100 pconst = &power_zone->constraints[id]; \ 101 err = kstrtoull(buf, 10, &value); \ 102 if (err) \ 103 return -EINVAL; \ 104 if (pconst && pconst->ops && pconst->ops->set_##_attr) { \ 105 if (!pconst->ops->set_##_attr(power_zone, id, value)) \ 106 return count; \ 107 } \ 108 \ 109 return -ENODATA; \ 110 } 111 112 /* Power zone information callbacks */ 113 define_power_zone_show(power_uw); 114 define_power_zone_show(max_power_range_uw); 115 define_power_zone_show(energy_uj); 116 define_power_zone_store(energy_uj); 117 define_power_zone_show(max_energy_range_uj); 118 119 /* Power zone attributes */ 120 static DEVICE_ATTR_RO(max_power_range_uw); 121 static DEVICE_ATTR_RO(power_uw); 122 static DEVICE_ATTR_RO(max_energy_range_uj); 123 static DEVICE_ATTR_RW(energy_uj); 124 125 /* Power zone constraint attributes callbacks */ 126 define_power_zone_constraint_show(power_limit_uw); 127 define_power_zone_constraint_store(power_limit_uw); 128 define_power_zone_constraint_show(time_window_us); 129 define_power_zone_constraint_store(time_window_us); 130 define_power_zone_constraint_show(max_power_uw); 131 define_power_zone_constraint_show(min_power_uw); 132 define_power_zone_constraint_show(max_time_window_us); 133 define_power_zone_constraint_show(min_time_window_us); 134 135 /* For one time seeding of constraint device attributes */ 136 struct powercap_constraint_attr { 137 struct device_attribute power_limit_attr; 138 struct device_attribute time_window_attr; 139 struct device_attribute max_power_attr; 140 struct device_attribute min_power_attr; 141 struct device_attribute max_time_window_attr; 142 struct device_attribute min_time_window_attr; 143 struct device_attribute name_attr; 144 }; 145 146 static struct powercap_constraint_attr 147 constraint_attrs[MAX_CONSTRAINTS_PER_ZONE]; 148 149 /* A list of powercap control_types */ 150 static LIST_HEAD(powercap_cntrl_list); 151 /* Mutex to protect list of powercap control_types */ 152 static DEFINE_MUTEX(powercap_cntrl_list_lock); 153 154 #define POWERCAP_CONSTRAINT_NAME_LEN 30 /* Some limit to avoid overflow */ 155 static ssize_t show_constraint_name(struct device *dev, 156 struct device_attribute *dev_attr, 157 char *buf) 158 { 159 const char *name; 160 struct powercap_zone *power_zone = to_powercap_zone(dev); 161 int id; 162 ssize_t len = -ENODATA; 163 struct powercap_zone_constraint *pconst; 164 165 if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) 166 return -EINVAL; 167 if (id >= power_zone->const_id_cnt) 168 return -EINVAL; 169 pconst = &power_zone->constraints[id]; 170 171 if (pconst && pconst->ops && pconst->ops->get_name) { 172 name = pconst->ops->get_name(power_zone, id); 173 if (name) { 174 sprintf(buf, "%.*s\n", POWERCAP_CONSTRAINT_NAME_LEN - 1, 175 name); 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_IRUSR; 371 else 372 dev_attr_energy_uj.attr.mode = S_IRUSR; 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 (kstrtobool(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 power_zone->constraints = kcalloc(nr_constraints, 534 sizeof(*power_zone->constraints), 535 GFP_KERNEL); 536 if (!power_zone->constraints) 537 goto err_const_alloc; 538 539 nr_attrs = nr_constraints * POWERCAP_CONSTRAINTS_ATTRS + 540 POWERCAP_ZONE_MAX_ATTRS + 1; 541 power_zone->zone_dev_attrs = kcalloc(nr_attrs, sizeof(void *), 542 GFP_KERNEL); 543 if (!power_zone->zone_dev_attrs) 544 goto err_attr_alloc; 545 create_power_zone_common_attributes(power_zone); 546 result = create_constraints(power_zone, nr_constraints, const_ops); 547 if (result) 548 goto err_dev_ret; 549 550 power_zone->zone_dev_attrs[power_zone->zone_attr_count] = NULL; 551 power_zone->dev_zone_attr_group.attrs = power_zone->zone_dev_attrs; 552 power_zone->dev_attr_groups[0] = &power_zone->dev_zone_attr_group; 553 power_zone->dev_attr_groups[1] = NULL; 554 power_zone->dev.groups = power_zone->dev_attr_groups; 555 dev_set_name(&power_zone->dev, "%s:%x", 556 dev_name(power_zone->dev.parent), 557 power_zone->id); 558 result = device_register(&power_zone->dev); 559 if (result) { 560 put_device(&power_zone->dev); 561 mutex_unlock(&control_type->lock); 562 563 return ERR_PTR(result); 564 } 565 566 control_type->nr_zones++; 567 mutex_unlock(&control_type->lock); 568 569 return power_zone; 570 571 err_dev_ret: 572 kfree(power_zone->zone_dev_attrs); 573 err_attr_alloc: 574 kfree(power_zone->constraints); 575 err_const_alloc: 576 kfree(power_zone->name); 577 err_name_alloc: 578 idr_remove(power_zone->parent_idr, power_zone->id); 579 err_idr_alloc: 580 if (power_zone->allocated) 581 kfree(power_zone); 582 mutex_unlock(&control_type->lock); 583 584 return ERR_PTR(result); 585 } 586 EXPORT_SYMBOL_GPL(powercap_register_zone); 587 588 int powercap_unregister_zone(struct powercap_control_type *control_type, 589 struct powercap_zone *power_zone) 590 { 591 if (!power_zone || !control_type) 592 return -EINVAL; 593 594 mutex_lock(&control_type->lock); 595 control_type->nr_zones--; 596 mutex_unlock(&control_type->lock); 597 598 device_unregister(&power_zone->dev); 599 600 return 0; 601 } 602 EXPORT_SYMBOL_GPL(powercap_unregister_zone); 603 604 struct powercap_control_type *powercap_register_control_type( 605 struct powercap_control_type *control_type, 606 const char *name, 607 const struct powercap_control_type_ops *ops) 608 { 609 int result; 610 611 if (!name) 612 return ERR_PTR(-EINVAL); 613 if (control_type) { 614 if (!ops || !ops->release) 615 return ERR_PTR(-EINVAL); 616 memset(control_type, 0, sizeof(*control_type)); 617 } else { 618 control_type = kzalloc(sizeof(*control_type), GFP_KERNEL); 619 if (!control_type) 620 return ERR_PTR(-ENOMEM); 621 control_type->allocated = true; 622 } 623 mutex_init(&control_type->lock); 624 control_type->ops = ops; 625 INIT_LIST_HEAD(&control_type->node); 626 control_type->dev.class = &powercap_class; 627 dev_set_name(&control_type->dev, "%s", name); 628 result = device_register(&control_type->dev); 629 if (result) { 630 if (control_type->allocated) 631 kfree(control_type); 632 return ERR_PTR(result); 633 } 634 idr_init(&control_type->idr); 635 636 mutex_lock(&powercap_cntrl_list_lock); 637 list_add_tail(&control_type->node, &powercap_cntrl_list); 638 mutex_unlock(&powercap_cntrl_list_lock); 639 640 return control_type; 641 } 642 EXPORT_SYMBOL_GPL(powercap_register_control_type); 643 644 int powercap_unregister_control_type(struct powercap_control_type *control_type) 645 { 646 struct powercap_control_type *pos = NULL; 647 648 if (control_type->nr_zones) { 649 dev_err(&control_type->dev, "Zones of this type still not freed\n"); 650 return -EINVAL; 651 } 652 mutex_lock(&powercap_cntrl_list_lock); 653 list_for_each_entry(pos, &powercap_cntrl_list, node) { 654 if (pos == control_type) { 655 list_del(&control_type->node); 656 mutex_unlock(&powercap_cntrl_list_lock); 657 device_unregister(&control_type->dev); 658 return 0; 659 } 660 } 661 mutex_unlock(&powercap_cntrl_list_lock); 662 663 return -ENODEV; 664 } 665 EXPORT_SYMBOL_GPL(powercap_unregister_control_type); 666 667 static int __init powercap_init(void) 668 { 669 int result; 670 671 result = seed_constraint_attributes(); 672 if (result) 673 return result; 674 675 return class_register(&powercap_class); 676 } 677 678 fs_initcall(powercap_init); 679 680 MODULE_DESCRIPTION("PowerCap sysfs Driver"); 681 MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>"); 682