1f6cc69f1SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
275d2364eSSrinivas Pandruvada /*
375d2364eSSrinivas Pandruvada * powercap.h: Data types and headers for sysfs power capping interface
475d2364eSSrinivas Pandruvada * Copyright (c) 2013, Intel Corporation.
575d2364eSSrinivas Pandruvada */
675d2364eSSrinivas Pandruvada
775d2364eSSrinivas Pandruvada #ifndef __POWERCAP_H__
875d2364eSSrinivas Pandruvada #define __POWERCAP_H__
975d2364eSSrinivas Pandruvada
1075d2364eSSrinivas Pandruvada #include <linux/device.h>
1175d2364eSSrinivas Pandruvada #include <linux/idr.h>
1275d2364eSSrinivas Pandruvada
1375d2364eSSrinivas Pandruvada /*
1475d2364eSSrinivas Pandruvada * A power cap class device can contain multiple powercap control_types.
1575d2364eSSrinivas Pandruvada * Each control_type can have multiple power zones, which can be independently
1675d2364eSSrinivas Pandruvada * controlled. Each power zone can have one or more constraints.
1775d2364eSSrinivas Pandruvada */
1875d2364eSSrinivas Pandruvada
1975d2364eSSrinivas Pandruvada struct powercap_control_type;
2075d2364eSSrinivas Pandruvada struct powercap_zone;
2175d2364eSSrinivas Pandruvada struct powercap_zone_constraint;
2275d2364eSSrinivas Pandruvada
2375d2364eSSrinivas Pandruvada /**
2475d2364eSSrinivas Pandruvada * struct powercap_control_type_ops - Define control type callbacks
2575d2364eSSrinivas Pandruvada * @set_enable: Enable/Disable whole control type.
2675d2364eSSrinivas Pandruvada * Default is enabled. But this callback allows all zones
2775d2364eSSrinivas Pandruvada * to be in disable state and remove any applied power
2875d2364eSSrinivas Pandruvada * limits. If disabled power zone can only be monitored
2975d2364eSSrinivas Pandruvada * not controlled.
3075d2364eSSrinivas Pandruvada * @get_enable: get Enable/Disable status.
3175d2364eSSrinivas Pandruvada * @release: Callback to inform that last reference to this
3275d2364eSSrinivas Pandruvada * control type is closed. So it is safe to free data
3375d2364eSSrinivas Pandruvada * structure associated with this control type.
3475d2364eSSrinivas Pandruvada * This callback is mandatory if the client own memory
3575d2364eSSrinivas Pandruvada * for the control type.
3675d2364eSSrinivas Pandruvada *
3775d2364eSSrinivas Pandruvada * This structure defines control type callbacks to be implemented by client
3875d2364eSSrinivas Pandruvada * drivers
3975d2364eSSrinivas Pandruvada */
4075d2364eSSrinivas Pandruvada struct powercap_control_type_ops {
4175d2364eSSrinivas Pandruvada int (*set_enable) (struct powercap_control_type *, bool mode);
4275d2364eSSrinivas Pandruvada int (*get_enable) (struct powercap_control_type *, bool *mode);
4375d2364eSSrinivas Pandruvada int (*release) (struct powercap_control_type *);
4475d2364eSSrinivas Pandruvada };
4575d2364eSSrinivas Pandruvada
4675d2364eSSrinivas Pandruvada /**
4775d2364eSSrinivas Pandruvada * struct powercap_control_type - Defines a powercap control_type
4875d2364eSSrinivas Pandruvada * @dev: device for this control_type
4975d2364eSSrinivas Pandruvada * @idr: idr to have unique id for its child
50cc88b78cSAmit Kucheria * @nr_zones: counter for number of zones of this type
5175d2364eSSrinivas Pandruvada * @ops: Pointer to callback struct
52cc88b78cSAmit Kucheria * @lock: mutex for control type
5375d2364eSSrinivas Pandruvada * @allocated: This is possible that client owns the memory
5475d2364eSSrinivas Pandruvada * used by this structure. In this case
5575d2364eSSrinivas Pandruvada * this flag is set to false by framework to
5675d2364eSSrinivas Pandruvada * prevent deallocation during release process.
5775d2364eSSrinivas Pandruvada * Otherwise this flag is set to true.
58cc88b78cSAmit Kucheria * @node: linked-list node
5975d2364eSSrinivas Pandruvada *
6075d2364eSSrinivas Pandruvada * Defines powercap control_type. This acts as a container for power
6175d2364eSSrinivas Pandruvada * zones, which use same method to control power. E.g. RAPL, RAPL-PCI etc.
6275d2364eSSrinivas Pandruvada * All fields are private and should not be used by client drivers.
6375d2364eSSrinivas Pandruvada */
6475d2364eSSrinivas Pandruvada struct powercap_control_type {
6575d2364eSSrinivas Pandruvada struct device dev;
6675d2364eSSrinivas Pandruvada struct idr idr;
6775d2364eSSrinivas Pandruvada int nr_zones;
6875d2364eSSrinivas Pandruvada const struct powercap_control_type_ops *ops;
6975d2364eSSrinivas Pandruvada struct mutex lock;
7075d2364eSSrinivas Pandruvada bool allocated;
7175d2364eSSrinivas Pandruvada struct list_head node;
7275d2364eSSrinivas Pandruvada };
7375d2364eSSrinivas Pandruvada
7475d2364eSSrinivas Pandruvada /**
7575d2364eSSrinivas Pandruvada * struct powercap_zone_ops - Define power zone callbacks
7675d2364eSSrinivas Pandruvada * @get_max_energy_range_uj: Get maximum range of energy counter in
7775d2364eSSrinivas Pandruvada * micro-joules.
7875d2364eSSrinivas Pandruvada * @get_energy_uj: Get current energy counter in micro-joules.
7975d2364eSSrinivas Pandruvada * @reset_energy_uj: Reset micro-joules energy counter.
8075d2364eSSrinivas Pandruvada * @get_max_power_range_uw: Get maximum range of power counter in
8175d2364eSSrinivas Pandruvada * micro-watts.
8275d2364eSSrinivas Pandruvada * @get_power_uw: Get current power counter in micro-watts.
8375d2364eSSrinivas Pandruvada * @set_enable: Enable/Disable power zone controls.
8475d2364eSSrinivas Pandruvada * Default is enabled.
8575d2364eSSrinivas Pandruvada * @get_enable: get Enable/Disable status.
8675d2364eSSrinivas Pandruvada * @release: Callback to inform that last reference to this
8775d2364eSSrinivas Pandruvada * control type is closed. So it is safe to free
8875d2364eSSrinivas Pandruvada * data structure associated with this
8975d2364eSSrinivas Pandruvada * control type. Mandatory, if client driver owns
9075d2364eSSrinivas Pandruvada * the power_zone memory.
9175d2364eSSrinivas Pandruvada *
9275d2364eSSrinivas Pandruvada * This structure defines zone callbacks to be implemented by client drivers.
9375d2364eSSrinivas Pandruvada * Client drives can define both energy and power related callbacks. But at
9475d2364eSSrinivas Pandruvada * the least one type (either power or energy) is mandatory. Client drivers
9575d2364eSSrinivas Pandruvada * should handle mutual exclusion, if required in callbacks.
9675d2364eSSrinivas Pandruvada */
9775d2364eSSrinivas Pandruvada struct powercap_zone_ops {
9875d2364eSSrinivas Pandruvada int (*get_max_energy_range_uj) (struct powercap_zone *, u64 *);
9975d2364eSSrinivas Pandruvada int (*get_energy_uj) (struct powercap_zone *, u64 *);
10075d2364eSSrinivas Pandruvada int (*reset_energy_uj) (struct powercap_zone *);
10175d2364eSSrinivas Pandruvada int (*get_max_power_range_uw) (struct powercap_zone *, u64 *);
10275d2364eSSrinivas Pandruvada int (*get_power_uw) (struct powercap_zone *, u64 *);
10375d2364eSSrinivas Pandruvada int (*set_enable) (struct powercap_zone *, bool mode);
10475d2364eSSrinivas Pandruvada int (*get_enable) (struct powercap_zone *, bool *mode);
10575d2364eSSrinivas Pandruvada int (*release) (struct powercap_zone *);
10675d2364eSSrinivas Pandruvada };
10775d2364eSSrinivas Pandruvada
10875d2364eSSrinivas Pandruvada #define POWERCAP_ZONE_MAX_ATTRS 6
10975d2364eSSrinivas Pandruvada #define POWERCAP_CONSTRAINTS_ATTRS 8
11075d2364eSSrinivas Pandruvada #define MAX_CONSTRAINTS_PER_ZONE 10
11175d2364eSSrinivas Pandruvada /**
11275d2364eSSrinivas Pandruvada * struct powercap_zone- Defines instance of a power cap zone
11375d2364eSSrinivas Pandruvada * @id: Unique id
11475d2364eSSrinivas Pandruvada * @name: Power zone name.
11575d2364eSSrinivas Pandruvada * @control_type_inst: Control type instance for this zone.
11675d2364eSSrinivas Pandruvada * @ops: Pointer to the zone operation structure.
11775d2364eSSrinivas Pandruvada * @dev: Instance of a device.
11875d2364eSSrinivas Pandruvada * @const_id_cnt: Number of constraint defined.
11975d2364eSSrinivas Pandruvada * @idr: Instance to an idr entry for children zones.
12075d2364eSSrinivas Pandruvada * @parent_idr: To remove reference from the parent idr.
12175d2364eSSrinivas Pandruvada * @private_data: Private data pointer if any for this zone.
12275d2364eSSrinivas Pandruvada * @zone_dev_attrs: Attributes associated with this device.
12375d2364eSSrinivas Pandruvada * @zone_attr_count: Attribute count.
12475d2364eSSrinivas Pandruvada * @dev_zone_attr_group: Attribute group for attributes.
12575d2364eSSrinivas Pandruvada * @dev_attr_groups: Attribute group store to register with device.
12675d2364eSSrinivas Pandruvada * @allocated: This is possible that client owns the memory
12775d2364eSSrinivas Pandruvada * used by this structure. In this case
12875d2364eSSrinivas Pandruvada * this flag is set to false by framework to
12975d2364eSSrinivas Pandruvada * prevent deallocation during release process.
13075d2364eSSrinivas Pandruvada * Otherwise this flag is set to true.
131cc88b78cSAmit Kucheria * @constraints: List of constraints for this zone.
13275d2364eSSrinivas Pandruvada *
13375d2364eSSrinivas Pandruvada * This defines a power zone instance. The fields of this structure are
13475d2364eSSrinivas Pandruvada * private, and should not be used by client drivers.
13575d2364eSSrinivas Pandruvada */
13675d2364eSSrinivas Pandruvada struct powercap_zone {
13775d2364eSSrinivas Pandruvada int id;
13875d2364eSSrinivas Pandruvada char *name;
13975d2364eSSrinivas Pandruvada void *control_type_inst;
14075d2364eSSrinivas Pandruvada const struct powercap_zone_ops *ops;
14175d2364eSSrinivas Pandruvada struct device dev;
14275d2364eSSrinivas Pandruvada int const_id_cnt;
14375d2364eSSrinivas Pandruvada struct idr idr;
14475d2364eSSrinivas Pandruvada struct idr *parent_idr;
14575d2364eSSrinivas Pandruvada void *private_data;
14675d2364eSSrinivas Pandruvada struct attribute **zone_dev_attrs;
14775d2364eSSrinivas Pandruvada int zone_attr_count;
14875d2364eSSrinivas Pandruvada struct attribute_group dev_zone_attr_group;
14975d2364eSSrinivas Pandruvada const struct attribute_group *dev_attr_groups[2]; /* 1 group + NULL */
15075d2364eSSrinivas Pandruvada bool allocated;
15175d2364eSSrinivas Pandruvada struct powercap_zone_constraint *constraints;
15275d2364eSSrinivas Pandruvada };
15375d2364eSSrinivas Pandruvada
15475d2364eSSrinivas Pandruvada /**
15575d2364eSSrinivas Pandruvada * struct powercap_zone_constraint_ops - Define constraint callbacks
15675d2364eSSrinivas Pandruvada * @set_power_limit_uw: Set power limit in micro-watts.
15775d2364eSSrinivas Pandruvada * @get_power_limit_uw: Get power limit in micro-watts.
15875d2364eSSrinivas Pandruvada * @set_time_window_us: Set time window in micro-seconds.
15975d2364eSSrinivas Pandruvada * @get_time_window_us: Get time window in micro-seconds.
16075d2364eSSrinivas Pandruvada * @get_max_power_uw: Get max power allowed in micro-watts.
16175d2364eSSrinivas Pandruvada * @get_min_power_uw: Get min power allowed in micro-watts.
16275d2364eSSrinivas Pandruvada * @get_max_time_window_us: Get max time window allowed in micro-seconds.
16375d2364eSSrinivas Pandruvada * @get_min_time_window_us: Get min time window allowed in micro-seconds.
16475d2364eSSrinivas Pandruvada * @get_name: Get the name of constraint
16575d2364eSSrinivas Pandruvada *
16675d2364eSSrinivas Pandruvada * This structure is used to define the constraint callbacks for the client
16775d2364eSSrinivas Pandruvada * drivers. The following callbacks are mandatory and can't be NULL:
16875d2364eSSrinivas Pandruvada * set_power_limit_uw
16975d2364eSSrinivas Pandruvada * get_power_limit_uw
17075d2364eSSrinivas Pandruvada * set_time_window_us
17175d2364eSSrinivas Pandruvada * get_time_window_us
17275d2364eSSrinivas Pandruvada * get_name
17375d2364eSSrinivas Pandruvada * Client drivers should handle mutual exclusion, if required in callbacks.
17475d2364eSSrinivas Pandruvada */
17575d2364eSSrinivas Pandruvada struct powercap_zone_constraint_ops {
17675d2364eSSrinivas Pandruvada int (*set_power_limit_uw) (struct powercap_zone *, int, u64);
17775d2364eSSrinivas Pandruvada int (*get_power_limit_uw) (struct powercap_zone *, int, u64 *);
17875d2364eSSrinivas Pandruvada int (*set_time_window_us) (struct powercap_zone *, int, u64);
17975d2364eSSrinivas Pandruvada int (*get_time_window_us) (struct powercap_zone *, int, u64 *);
18075d2364eSSrinivas Pandruvada int (*get_max_power_uw) (struct powercap_zone *, int, u64 *);
18175d2364eSSrinivas Pandruvada int (*get_min_power_uw) (struct powercap_zone *, int, u64 *);
18275d2364eSSrinivas Pandruvada int (*get_max_time_window_us) (struct powercap_zone *, int, u64 *);
18375d2364eSSrinivas Pandruvada int (*get_min_time_window_us) (struct powercap_zone *, int, u64 *);
18475d2364eSSrinivas Pandruvada const char *(*get_name) (struct powercap_zone *, int);
18575d2364eSSrinivas Pandruvada };
18675d2364eSSrinivas Pandruvada
18775d2364eSSrinivas Pandruvada /**
18875d2364eSSrinivas Pandruvada * struct powercap_zone_constraint- Defines instance of a constraint
18975d2364eSSrinivas Pandruvada * @id: Instance Id of this constraint.
19075d2364eSSrinivas Pandruvada * @power_zone: Pointer to the power zone for this constraint.
19175d2364eSSrinivas Pandruvada * @ops: Pointer to the constraint callbacks.
19275d2364eSSrinivas Pandruvada *
19375d2364eSSrinivas Pandruvada * This defines a constraint instance.
19475d2364eSSrinivas Pandruvada */
19575d2364eSSrinivas Pandruvada struct powercap_zone_constraint {
19675d2364eSSrinivas Pandruvada int id;
19775d2364eSSrinivas Pandruvada struct powercap_zone *power_zone;
198600c395bSJulia Lawall const struct powercap_zone_constraint_ops *ops;
19975d2364eSSrinivas Pandruvada };
20075d2364eSSrinivas Pandruvada
20175d2364eSSrinivas Pandruvada
20275d2364eSSrinivas Pandruvada /* For clients to get their device pointer, may be used for dev_dbgs */
20375d2364eSSrinivas Pandruvada #define POWERCAP_GET_DEV(power_zone) (&power_zone->dev)
20475d2364eSSrinivas Pandruvada
20575d2364eSSrinivas Pandruvada /**
20675d2364eSSrinivas Pandruvada * powercap_set_zone_data() - Set private data for a zone
20775d2364eSSrinivas Pandruvada * @power_zone: A pointer to the valid zone instance.
20875d2364eSSrinivas Pandruvada * @pdata: A pointer to the user private data.
20975d2364eSSrinivas Pandruvada *
21075d2364eSSrinivas Pandruvada * Allows client drivers to associate some private data to zone instance.
21175d2364eSSrinivas Pandruvada */
powercap_set_zone_data(struct powercap_zone * power_zone,void * pdata)21275d2364eSSrinivas Pandruvada static inline void powercap_set_zone_data(struct powercap_zone *power_zone,
21375d2364eSSrinivas Pandruvada void *pdata)
21475d2364eSSrinivas Pandruvada {
21575d2364eSSrinivas Pandruvada if (power_zone)
21675d2364eSSrinivas Pandruvada power_zone->private_data = pdata;
21775d2364eSSrinivas Pandruvada }
21875d2364eSSrinivas Pandruvada
21975d2364eSSrinivas Pandruvada /**
22075d2364eSSrinivas Pandruvada * powercap_get_zone_data() - Get private data for a zone
22175d2364eSSrinivas Pandruvada * @power_zone: A pointer to the valid zone instance.
22275d2364eSSrinivas Pandruvada *
22375d2364eSSrinivas Pandruvada * Allows client drivers to get private data associate with a zone,
22475d2364eSSrinivas Pandruvada * using call to powercap_set_zone_data.
22575d2364eSSrinivas Pandruvada */
powercap_get_zone_data(struct powercap_zone * power_zone)22675d2364eSSrinivas Pandruvada static inline void *powercap_get_zone_data(struct powercap_zone *power_zone)
22775d2364eSSrinivas Pandruvada {
22875d2364eSSrinivas Pandruvada if (power_zone)
22975d2364eSSrinivas Pandruvada return power_zone->private_data;
23075d2364eSSrinivas Pandruvada return NULL;
23175d2364eSSrinivas Pandruvada }
23275d2364eSSrinivas Pandruvada
23375d2364eSSrinivas Pandruvada /**
23475d2364eSSrinivas Pandruvada * powercap_register_control_type() - Register a control_type with framework
23575d2364eSSrinivas Pandruvada * @control_type: Pointer to client allocated memory for the control type
23675d2364eSSrinivas Pandruvada * structure storage. If this is NULL, powercap framework
23775d2364eSSrinivas Pandruvada * will allocate memory and own it.
23875d2364eSSrinivas Pandruvada * Advantage of this parameter is that client can embed
23975d2364eSSrinivas Pandruvada * this data in its data structures and allocate in a
24075d2364eSSrinivas Pandruvada * single call, preventing multiple allocations.
24175d2364eSSrinivas Pandruvada * @control_type_name: The Name of this control_type, which will be shown
24275d2364eSSrinivas Pandruvada * in the sysfs Interface.
24375d2364eSSrinivas Pandruvada * @ops: Callbacks for control type. This parameter is optional.
24475d2364eSSrinivas Pandruvada *
24575d2364eSSrinivas Pandruvada * Used to create a control_type with the power capping class. Here control_type
24675d2364eSSrinivas Pandruvada * can represent a type of technology, which can control a range of power zones.
24775d2364eSSrinivas Pandruvada * For example a control_type can be RAPL (Running Average Power Limit)
24875d2364eSSrinivas Pandruvada * Intel® 64 and IA-32 Processor Architectures. The name can be any string
24975d2364eSSrinivas Pandruvada * which must be unique, otherwise this function returns NULL.
25075d2364eSSrinivas Pandruvada * A pointer to the control_type instance is returned on success.
25175d2364eSSrinivas Pandruvada */
25275d2364eSSrinivas Pandruvada struct powercap_control_type *powercap_register_control_type(
25375d2364eSSrinivas Pandruvada struct powercap_control_type *control_type,
25475d2364eSSrinivas Pandruvada const char *name,
25575d2364eSSrinivas Pandruvada const struct powercap_control_type_ops *ops);
25675d2364eSSrinivas Pandruvada
25775d2364eSSrinivas Pandruvada /**
25875d2364eSSrinivas Pandruvada * powercap_unregister_control_type() - Unregister a control_type from framework
25975d2364eSSrinivas Pandruvada * @instance: A pointer to the valid control_type instance.
26075d2364eSSrinivas Pandruvada *
26175d2364eSSrinivas Pandruvada * Used to unregister a control_type with the power capping class.
26275d2364eSSrinivas Pandruvada * All power zones registered under this control type have to be unregistered
26375d2364eSSrinivas Pandruvada * before calling this function, or it will fail with an error code.
26475d2364eSSrinivas Pandruvada */
26575d2364eSSrinivas Pandruvada int powercap_unregister_control_type(struct powercap_control_type *instance);
26675d2364eSSrinivas Pandruvada
26775d2364eSSrinivas Pandruvada /* Zone register/unregister API */
26875d2364eSSrinivas Pandruvada
26975d2364eSSrinivas Pandruvada /**
27075d2364eSSrinivas Pandruvada * powercap_register_zone() - Register a power zone
27175d2364eSSrinivas Pandruvada * @power_zone: Pointer to client allocated memory for the power zone structure
27275d2364eSSrinivas Pandruvada * storage. If this is NULL, powercap framework will allocate
27375d2364eSSrinivas Pandruvada * memory and own it. Advantage of this parameter is that client
27475d2364eSSrinivas Pandruvada * can embed this data in its data structures and allocate in a
27575d2364eSSrinivas Pandruvada * single call, preventing multiple allocations.
27675d2364eSSrinivas Pandruvada * @control_type: A control_type instance under which this zone operates.
27775d2364eSSrinivas Pandruvada * @name: A name for this zone.
27875d2364eSSrinivas Pandruvada * @parent: A pointer to the parent power zone instance if any or NULL
27975d2364eSSrinivas Pandruvada * @ops: Pointer to zone operation callback structure.
28075d2364eSSrinivas Pandruvada * @no_constraints: Number of constraints for this zone
28175d2364eSSrinivas Pandruvada * @const_ops: Pointer to constraint callback structure
28275d2364eSSrinivas Pandruvada *
28375d2364eSSrinivas Pandruvada * Register a power zone under a given control type. A power zone must register
28475d2364eSSrinivas Pandruvada * a pointer to a structure representing zone callbacks.
28575d2364eSSrinivas Pandruvada * A power zone can be located under a parent power zone, in which case @parent
28675d2364eSSrinivas Pandruvada * should point to it. Otherwise, if @parent is NULL, the new power zone will
28775d2364eSSrinivas Pandruvada * be located directly under the given control type
28875d2364eSSrinivas Pandruvada * For each power zone there may be a number of constraints that appear in the
28975d2364eSSrinivas Pandruvada * sysfs under that zone as attributes with unique numeric IDs.
29075d2364eSSrinivas Pandruvada * Returns pointer to the power_zone on success.
29175d2364eSSrinivas Pandruvada */
29275d2364eSSrinivas Pandruvada struct powercap_zone *powercap_register_zone(
29375d2364eSSrinivas Pandruvada struct powercap_zone *power_zone,
29475d2364eSSrinivas Pandruvada struct powercap_control_type *control_type,
29575d2364eSSrinivas Pandruvada const char *name,
29675d2364eSSrinivas Pandruvada struct powercap_zone *parent,
29775d2364eSSrinivas Pandruvada const struct powercap_zone_ops *ops,
29875d2364eSSrinivas Pandruvada int nr_constraints,
299600c395bSJulia Lawall const struct powercap_zone_constraint_ops *const_ops);
30075d2364eSSrinivas Pandruvada
30175d2364eSSrinivas Pandruvada /**
30275d2364eSSrinivas Pandruvada * powercap_unregister_zone() - Unregister a zone device
30375d2364eSSrinivas Pandruvada * @control_type: A pointer to the valid instance of a control_type.
30475d2364eSSrinivas Pandruvada * @power_zone: A pointer to the valid zone instance for a control_type
30575d2364eSSrinivas Pandruvada *
30675d2364eSSrinivas Pandruvada * Used to unregister a zone device for a control_type. Caller should
30775d2364eSSrinivas Pandruvada * make sure that children for this zone are unregistered first.
30875d2364eSSrinivas Pandruvada */
30975d2364eSSrinivas Pandruvada int powercap_unregister_zone(struct powercap_control_type *control_type,
31075d2364eSSrinivas Pandruvada struct powercap_zone *power_zone);
31175d2364eSSrinivas Pandruvada
31275d2364eSSrinivas Pandruvada #endif
313