1 // SPDX-License-Identifier: GPL-2.0-only
4 * Copyright (c) 2013, Intel Corporation.
7 #include <linux/module.h>
8 #include <linux/device.h>
10 #include <linux/slab.h>
11 #include <linux/powercap.h>
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)
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,\
24 ssize_t len = -EINVAL; \
25 struct powercap_zone *power_zone = to_powercap_zone(dev); \
27 if (power_zone->ops->get_##_attr) { \
28 if (!power_zone->ops->get_##_attr(power_zone, &value)) \
29 len = sprintf(buf, "%lld\n", value); \
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) \
42 struct powercap_zone *power_zone = to_powercap_zone(dev); \
45 err = kstrtoull(buf, 10, &value); \
50 if (power_zone->ops->reset_##_attr) { \
51 if (!power_zone->ops->reset_##_attr(power_zone)) \
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,\
65 ssize_t len = -ENODATA; \
66 struct powercap_zone *power_zone = to_powercap_zone(dev); \
68 struct powercap_zone_constraint *pconst;\
70 if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \
72 if (id >= power_zone->const_id_cnt) \
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); \
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) \
91 struct powercap_zone *power_zone = to_powercap_zone(dev); \
93 struct powercap_zone_constraint *pconst;\
95 if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \
97 if (id >= power_zone->const_id_cnt) \
99 pconst = &power_zone->constraints[id]; \
100 err = kstrtoull(buf, 10, &value); \
103 if (pconst && pconst->ops && pconst->ops->set_##_attr) { \
104 if (!pconst->ops->set_##_attr(power_zone, id, value)) \
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
);
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
);
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
);
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
;
145 static struct powercap_constraint_attr
146 constraint_attrs
[MAX_CONSTRAINTS_PER_ZONE
];
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
);
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
,
159 struct powercap_zone
*power_zone
= to_powercap_zone(dev
);
161 ssize_t len
= -ENODATA
;
162 struct powercap_zone_constraint
*pconst
;
164 if (!sscanf(dev_attr
->attr
.name
, "constraint_%d_", &id
))
166 if (id
>= power_zone
->const_id_cnt
)
168 pconst
= &power_zone
->constraints
[id
];
170 if (pconst
&& pconst
->ops
&& pconst
->ops
->get_name
) {
171 name
= pconst
->ops
->get_name(power_zone
, id
);
173 snprintf(buf
, POWERCAP_CONSTRAINT_NAME_LEN
,
175 buf
[POWERCAP_CONSTRAINT_NAME_LEN
] = '\0';
183 static int create_constraint_attribute(int id
, const char *name
,
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)
194 dev_attr
->attr
.name
= kasprintf(GFP_KERNEL
, "constraint_%d_%s",
196 if (!dev_attr
->attr
.name
)
198 dev_attr
->attr
.mode
= mode
;
199 dev_attr
->show
= show
;
200 dev_attr
->store
= store
;
205 static void free_constraint_attributes(void)
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
);
220 static int seed_constraint_attributes(void)
225 for (i
= 0; i
< MAX_CONSTRAINTS_PER_ZONE
; ++i
) {
226 ret
= create_constraint_attribute(i
, "power_limit_uw",
228 &constraint_attrs
[i
].power_limit_attr
,
229 show_constraint_power_limit_uw
,
230 store_constraint_power_limit_uw
);
233 ret
= create_constraint_attribute(i
, "time_window_us",
235 &constraint_attrs
[i
].time_window_attr
,
236 show_constraint_time_window_us
,
237 store_constraint_time_window_us
);
240 ret
= create_constraint_attribute(i
, "name", S_IRUGO
,
241 &constraint_attrs
[i
].name_attr
,
242 show_constraint_name
,
246 ret
= create_constraint_attribute(i
, "max_power_uw", S_IRUGO
,
247 &constraint_attrs
[i
].max_power_attr
,
248 show_constraint_max_power_uw
,
252 ret
= create_constraint_attribute(i
, "min_power_uw", S_IRUGO
,
253 &constraint_attrs
[i
].min_power_attr
,
254 show_constraint_min_power_uw
,
258 ret
= create_constraint_attribute(i
, "max_time_window_us",
260 &constraint_attrs
[i
].max_time_window_attr
,
261 show_constraint_max_time_window_us
,
265 ret
= create_constraint_attribute(i
, "min_time_window_us",
267 &constraint_attrs
[i
].min_time_window_attr
,
268 show_constraint_min_time_window_us
,
278 free_constraint_attributes();
283 static int create_constraints(struct powercap_zone
*power_zone
,
285 const struct powercap_zone_constraint_ops
*const_ops
)
290 struct powercap_zone_constraint
*pconst
;
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
)
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
;
324 power_zone
->zone_attr_count
= count
;
329 static bool control_type_valid(void *control_type
)
331 struct powercap_control_type
*pos
= NULL
;
334 mutex_lock(&powercap_cntrl_list_lock
);
336 list_for_each_entry(pos
, &powercap_cntrl_list
, node
) {
337 if (pos
== control_type
) {
342 mutex_unlock(&powercap_cntrl_list_lock
);
347 static ssize_t
name_show(struct device
*dev
,
348 struct device_attribute
*attr
,
351 struct powercap_zone
*power_zone
= to_powercap_zone(dev
);
353 return sprintf(buf
, "%s\n", power_zone
->name
);
356 static DEVICE_ATTR_RO(name
);
358 /* Create zone and attributes in sysfs */
359 static void create_power_zone_common_attributes(
360 struct powercap_zone
*power_zone
)
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
;
372 dev_attr_energy_uj
.attr
.mode
= S_IRUGO
;
373 power_zone
->zone_dev_attrs
[count
++] =
374 &dev_attr_energy_uj
.attr
;
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
;
386 static void powercap_release(struct device
*dev
)
391 struct powercap_zone
*power_zone
= to_powercap_zone(dev
);
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
);
407 struct powercap_control_type
*control_type
=
408 to_powercap_control_type(dev
);
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
);
421 static ssize_t
enabled_show(struct device
*dev
,
422 struct device_attribute
*attr
,
427 /* Default is enabled */
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
))
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
))
441 return sprintf(buf
, "%d\n", mode
);
444 static ssize_t
enabled_store(struct device
*dev
,
445 struct device_attribute
*attr
,
446 const char *buf
, size_t len
)
450 if (strtobool(buf
, &mode
))
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
))
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
))
468 static DEVICE_ATTR_RW(enabled
);
470 static struct attribute
*powercap_attrs
[] = {
471 &dev_attr_enabled
.attr
,
474 ATTRIBUTE_GROUPS(powercap
);
476 static struct class powercap_class
= {
478 .dev_release
= powercap_release
,
479 .dev_groups
= powercap_groups
,
482 struct powercap_zone
*powercap_register_zone(
483 struct powercap_zone
*power_zone
,
484 struct powercap_control_type
*control_type
,
486 struct powercap_zone
*parent
,
487 const struct powercap_zone_ops
*ops
,
489 const struct powercap_zone_constraint_ops
*const_ops
)
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
);
502 return ERR_PTR(-EINVAL
);
503 memset(power_zone
, 0, sizeof(*power_zone
));
505 power_zone
= kzalloc(sizeof(*power_zone
), GFP_KERNEL
);
507 return ERR_PTR(-ENOMEM
);
508 power_zone
->allocated
= true;
510 power_zone
->ops
= ops
;
511 power_zone
->control_type_inst
= control_type
;
513 power_zone
->dev
.parent
= &control_type
->dev
;
514 power_zone
->parent_idr
= &control_type
->idr
;
516 power_zone
->dev
.parent
= &parent
->dev
;
517 power_zone
->parent_idr
= &parent
->idr
;
519 power_zone
->dev
.class = &powercap_class
;
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
);
527 power_zone
->id
= result
;
528 idr_init(&power_zone
->idr
);
530 power_zone
->name
= kstrdup(name
, GFP_KERNEL
);
531 if (!power_zone
->name
)
533 dev_set_name(&power_zone
->dev
, "%s:%x",
534 dev_name(power_zone
->dev
.parent
),
536 power_zone
->constraints
= kcalloc(nr_constraints
,
537 sizeof(*power_zone
->constraints
),
539 if (!power_zone
->constraints
)
540 goto err_const_alloc
;
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 *),
546 if (!power_zone
->zone_dev_attrs
)
548 create_power_zone_common_attributes(power_zone
);
549 result
= create_constraints(power_zone
, nr_constraints
, const_ops
);
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
);
562 control_type
->nr_zones
++;
563 mutex_unlock(&control_type
->lock
);
568 kfree(power_zone
->zone_dev_attrs
);
570 kfree(power_zone
->constraints
);
572 kfree(power_zone
->name
);
574 idr_remove(power_zone
->parent_idr
, power_zone
->id
);
576 if (power_zone
->allocated
)
578 mutex_unlock(&control_type
->lock
);
580 return ERR_PTR(result
);
582 EXPORT_SYMBOL_GPL(powercap_register_zone
);
584 int powercap_unregister_zone(struct powercap_control_type
*control_type
,
585 struct powercap_zone
*power_zone
)
587 if (!power_zone
|| !control_type
)
590 mutex_lock(&control_type
->lock
);
591 control_type
->nr_zones
--;
592 mutex_unlock(&control_type
->lock
);
594 device_unregister(&power_zone
->dev
);
598 EXPORT_SYMBOL_GPL(powercap_unregister_zone
);
600 struct powercap_control_type
*powercap_register_control_type(
601 struct powercap_control_type
*control_type
,
603 const struct powercap_control_type_ops
*ops
)
608 return ERR_PTR(-EINVAL
);
610 if (!ops
|| !ops
->release
)
611 return ERR_PTR(-EINVAL
);
612 memset(control_type
, 0, sizeof(*control_type
));
614 control_type
= kzalloc(sizeof(*control_type
), GFP_KERNEL
);
616 return ERR_PTR(-ENOMEM
);
617 control_type
->allocated
= true;
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
);
626 if (control_type
->allocated
)
628 return ERR_PTR(result
);
630 idr_init(&control_type
->idr
);
632 mutex_lock(&powercap_cntrl_list_lock
);
633 list_add_tail(&control_type
->node
, &powercap_cntrl_list
);
634 mutex_unlock(&powercap_cntrl_list_lock
);
638 EXPORT_SYMBOL_GPL(powercap_register_control_type
);
640 int powercap_unregister_control_type(struct powercap_control_type
*control_type
)
642 struct powercap_control_type
*pos
= NULL
;
644 if (control_type
->nr_zones
) {
645 dev_err(&control_type
->dev
, "Zones of this type still not freed\n");
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
);
657 mutex_unlock(&powercap_cntrl_list_lock
);
661 EXPORT_SYMBOL_GPL(powercap_unregister_control_type
);
663 static int __init
powercap_init(void)
667 result
= seed_constraint_attributes();
671 return class_register(&powercap_class
);
674 fs_initcall(powercap_init
);
676 MODULE_DESCRIPTION("PowerCap sysfs Driver");
677 MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
678 MODULE_LICENSE("GPL v2");