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/kstrtox.h>
11 #include <linux/slab.h>
12 #include <linux/powercap.h>
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)
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,\
25 ssize_t len = -EINVAL; \
26 struct powercap_zone *power_zone = to_powercap_zone(dev); \
28 if (power_zone->ops->get_##_attr) { \
29 if (!power_zone->ops->get_##_attr(power_zone, &value)) \
30 len = sprintf(buf, "%lld\n", value); \
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) \
43 struct powercap_zone *power_zone = to_powercap_zone(dev); \
46 err = kstrtoull(buf, 10, &value); \
51 if (power_zone->ops->reset_##_attr) { \
52 if (!power_zone->ops->reset_##_attr(power_zone)) \
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,\
66 ssize_t len = -ENODATA; \
67 struct powercap_zone *power_zone = to_powercap_zone(dev); \
69 struct powercap_zone_constraint *pconst;\
71 if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \
73 if (id >= power_zone->const_id_cnt) \
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); \
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) \
92 struct powercap_zone *power_zone = to_powercap_zone(dev); \
94 struct powercap_zone_constraint *pconst;\
96 if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \
98 if (id >= power_zone->const_id_cnt) \
100 pconst = &power_zone->constraints[id]; \
101 err = kstrtoull(buf, 10, &value); \
104 if (pconst && pconst->ops && pconst->ops->set_##_attr) { \
105 if (!pconst->ops->set_##_attr(power_zone, id, value)) \
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
);
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
);
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
);
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
;
146 static struct powercap_constraint_attr
147 constraint_attrs
[MAX_CONSTRAINTS_PER_ZONE
];
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
);
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
,
160 struct powercap_zone
*power_zone
= to_powercap_zone(dev
);
162 ssize_t len
= -ENODATA
;
163 struct powercap_zone_constraint
*pconst
;
165 if (!sscanf(dev_attr
->attr
.name
, "constraint_%d_", &id
))
167 if (id
>= power_zone
->const_id_cnt
)
169 pconst
= &power_zone
->constraints
[id
];
171 if (pconst
&& pconst
->ops
&& pconst
->ops
->get_name
) {
172 name
= pconst
->ops
->get_name(power_zone
, id
);
174 sprintf(buf
, "%.*s\n", POWERCAP_CONSTRAINT_NAME_LEN
- 1,
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_IRUSR
;
372 dev_attr_energy_uj
.attr
.mode
= S_IRUSR
;
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 (kstrtobool(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 power_zone
->constraints
= kcalloc(nr_constraints
,
534 sizeof(*power_zone
->constraints
),
536 if (!power_zone
->constraints
)
537 goto err_const_alloc
;
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 *),
543 if (!power_zone
->zone_dev_attrs
)
545 create_power_zone_common_attributes(power_zone
);
546 result
= create_constraints(power_zone
, nr_constraints
, const_ops
);
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
),
558 result
= device_register(&power_zone
->dev
);
560 put_device(&power_zone
->dev
);
561 mutex_unlock(&control_type
->lock
);
563 return ERR_PTR(result
);
566 control_type
->nr_zones
++;
567 mutex_unlock(&control_type
->lock
);
572 kfree(power_zone
->zone_dev_attrs
);
574 kfree(power_zone
->constraints
);
576 kfree(power_zone
->name
);
578 idr_remove(power_zone
->parent_idr
, power_zone
->id
);
580 if (power_zone
->allocated
)
582 mutex_unlock(&control_type
->lock
);
584 return ERR_PTR(result
);
586 EXPORT_SYMBOL_GPL(powercap_register_zone
);
588 int powercap_unregister_zone(struct powercap_control_type
*control_type
,
589 struct powercap_zone
*power_zone
)
591 if (!power_zone
|| !control_type
)
594 mutex_lock(&control_type
->lock
);
595 control_type
->nr_zones
--;
596 mutex_unlock(&control_type
->lock
);
598 device_unregister(&power_zone
->dev
);
602 EXPORT_SYMBOL_GPL(powercap_unregister_zone
);
604 struct powercap_control_type
*powercap_register_control_type(
605 struct powercap_control_type
*control_type
,
607 const struct powercap_control_type_ops
*ops
)
612 return ERR_PTR(-EINVAL
);
614 if (!ops
|| !ops
->release
)
615 return ERR_PTR(-EINVAL
);
616 memset(control_type
, 0, sizeof(*control_type
));
618 control_type
= kzalloc(sizeof(*control_type
), GFP_KERNEL
);
620 return ERR_PTR(-ENOMEM
);
621 control_type
->allocated
= true;
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
);
630 if (control_type
->allocated
)
632 return ERR_PTR(result
);
634 idr_init(&control_type
->idr
);
636 mutex_lock(&powercap_cntrl_list_lock
);
637 list_add_tail(&control_type
->node
, &powercap_cntrl_list
);
638 mutex_unlock(&powercap_cntrl_list_lock
);
642 EXPORT_SYMBOL_GPL(powercap_register_control_type
);
644 int powercap_unregister_control_type(struct powercap_control_type
*control_type
)
646 struct powercap_control_type
*pos
= NULL
;
648 if (control_type
->nr_zones
) {
649 dev_err(&control_type
->dev
, "Zones of this type still not freed\n");
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
);
661 mutex_unlock(&powercap_cntrl_list_lock
);
665 EXPORT_SYMBOL_GPL(powercap_unregister_control_type
);
667 static int __init
powercap_init(void)
671 result
= seed_constraint_attributes();
675 return class_register(&powercap_class
);
678 fs_initcall(powercap_init
);
680 MODULE_DESCRIPTION("PowerCap sysfs Driver");
681 MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");