Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * powercap.h: Data types and headers for sysfs power capping interface
0004  * Copyright (c) 2013, Intel Corporation.
0005  */
0006 
0007 #ifndef __POWERCAP_H__
0008 #define __POWERCAP_H__
0009 
0010 #include <linux/device.h>
0011 #include <linux/idr.h>
0012 
0013 /*
0014  * A power cap class device can contain multiple powercap control_types.
0015  * Each control_type can have multiple power zones, which can be independently
0016  * controlled. Each power zone can have one or more constraints.
0017  */
0018 
0019 struct powercap_control_type;
0020 struct powercap_zone;
0021 struct powercap_zone_constraint;
0022 
0023 /**
0024  * struct powercap_control_type_ops - Define control type callbacks
0025  * @set_enable:     Enable/Disable whole control type.
0026  *          Default is enabled. But this callback allows all zones
0027  *          to be in disable state and remove any applied power
0028  *          limits. If disabled power zone can only be monitored
0029  *          not controlled.
0030  * @get_enable:     get Enable/Disable status.
0031  * @release:        Callback to inform that last reference to this
0032  *          control type is closed. So it is safe to free data
0033  *          structure associated with this control type.
0034  *          This callback is mandatory if the client own memory
0035  *          for the control type.
0036  *
0037  * This structure defines control type callbacks to be implemented by client
0038  * drivers
0039  */
0040 struct powercap_control_type_ops {
0041     int (*set_enable) (struct powercap_control_type *, bool mode);
0042     int (*get_enable) (struct powercap_control_type *, bool *mode);
0043     int (*release) (struct powercap_control_type *);
0044 };
0045 
0046 /**
0047  * struct powercap_control_type - Defines a powercap control_type
0048  * @dev:        device for this control_type
0049  * @idr:        idr to have unique id for its child
0050  * @nr_zones:       counter for number of zones of this type
0051  * @ops:        Pointer to callback struct
0052  * @lock:       mutex for control type
0053  * @allocated:      This is possible that client owns the memory
0054  *          used by this structure. In this case
0055  *          this flag is set to false by framework to
0056  *          prevent deallocation during release process.
0057  *          Otherwise this flag is set to true.
0058  * @node:       linked-list node
0059  *
0060  * Defines powercap control_type. This acts as a container for power
0061  * zones, which use same method to control power. E.g. RAPL, RAPL-PCI etc.
0062  * All fields are private and should not be used by client drivers.
0063  */
0064 struct powercap_control_type {
0065     struct device dev;
0066     struct idr idr;
0067     int nr_zones;
0068     const struct powercap_control_type_ops *ops;
0069     struct mutex lock;
0070     bool allocated;
0071     struct list_head node;
0072 };
0073 
0074 /**
0075  * struct powercap_zone_ops - Define power zone callbacks
0076  * @get_max_energy_range_uj:    Get maximum range of energy counter in
0077  *              micro-joules.
0078  * @get_energy_uj:      Get current energy counter in micro-joules.
0079  * @reset_energy_uj:        Reset micro-joules energy counter.
0080  * @get_max_power_range_uw: Get maximum range of power counter in
0081  *              micro-watts.
0082  * @get_power_uw:       Get current power counter in micro-watts.
0083  * @set_enable:         Enable/Disable power zone controls.
0084  *              Default is enabled.
0085  * @get_enable:         get Enable/Disable status.
0086  * @release:            Callback to inform that last reference to this
0087  *              control type is closed. So it is safe to free
0088  *              data structure associated with this
0089  *              control type. Mandatory, if client driver owns
0090  *              the power_zone memory.
0091  *
0092  * This structure defines zone callbacks to be implemented by client drivers.
0093  * Client drives can define both energy and power related callbacks. But at
0094  * the least one type (either power or energy) is mandatory. Client drivers
0095  * should handle mutual exclusion, if required in callbacks.
0096  */
0097 struct powercap_zone_ops {
0098     int (*get_max_energy_range_uj) (struct powercap_zone *, u64 *);
0099     int (*get_energy_uj) (struct powercap_zone *, u64 *);
0100     int (*reset_energy_uj) (struct powercap_zone *);
0101     int (*get_max_power_range_uw) (struct powercap_zone *, u64 *);
0102     int (*get_power_uw) (struct powercap_zone *, u64 *);
0103     int (*set_enable) (struct powercap_zone *, bool mode);
0104     int (*get_enable) (struct powercap_zone *, bool *mode);
0105     int (*release) (struct powercap_zone *);
0106 };
0107 
0108 #define POWERCAP_ZONE_MAX_ATTRS     6
0109 #define POWERCAP_CONSTRAINTS_ATTRS  8
0110 #define MAX_CONSTRAINTS_PER_ZONE    10
0111 /**
0112  * struct powercap_zone- Defines instance of a power cap zone
0113  * @id:         Unique id
0114  * @name:       Power zone name.
0115  * @control_type_inst:  Control type instance for this zone.
0116  * @ops:        Pointer to the zone operation structure.
0117  * @dev:        Instance of a device.
0118  * @const_id_cnt:   Number of constraint defined.
0119  * @idr:        Instance to an idr entry for children zones.
0120  * @parent_idr:     To remove reference from the parent idr.
0121  * @private_data:   Private data pointer if any for this zone.
0122  * @zone_dev_attrs: Attributes associated with this device.
0123  * @zone_attr_count:    Attribute count.
0124  * @dev_zone_attr_group: Attribute group for attributes.
0125  * @dev_attr_groups:    Attribute group store to register with device.
0126  * @allocated:      This is possible that client owns the memory
0127  *          used by this structure. In this case
0128  *          this flag is set to false by framework to
0129  *          prevent deallocation during release process.
0130  *          Otherwise this flag is set to true.
0131  * @constraints:    List of constraints for this zone.
0132  *
0133  * This defines a power zone instance. The fields of this structure are
0134  * private, and should not be used by client drivers.
0135  */
0136 struct powercap_zone {
0137     int id;
0138     char *name;
0139     void *control_type_inst;
0140     const struct powercap_zone_ops *ops;
0141     struct device dev;
0142     int const_id_cnt;
0143     struct idr idr;
0144     struct idr *parent_idr;
0145     void *private_data;
0146     struct attribute **zone_dev_attrs;
0147     int zone_attr_count;
0148     struct attribute_group dev_zone_attr_group;
0149     const struct attribute_group *dev_attr_groups[2]; /* 1 group + NULL */
0150     bool allocated;
0151     struct powercap_zone_constraint *constraints;
0152 };
0153 
0154 /**
0155  * struct powercap_zone_constraint_ops - Define constraint callbacks
0156  * @set_power_limit_uw:     Set power limit in micro-watts.
0157  * @get_power_limit_uw:     Get power limit in micro-watts.
0158  * @set_time_window_us:     Set time window in micro-seconds.
0159  * @get_time_window_us:     Get time window in micro-seconds.
0160  * @get_max_power_uw:       Get max power allowed in micro-watts.
0161  * @get_min_power_uw:       Get min power allowed in micro-watts.
0162  * @get_max_time_window_us: Get max time window allowed in micro-seconds.
0163  * @get_min_time_window_us: Get min time window allowed in micro-seconds.
0164  * @get_name:           Get the name of constraint
0165  *
0166  * This structure is used to define the constraint callbacks for the client
0167  * drivers. The following callbacks are mandatory and can't be NULL:
0168  *  set_power_limit_uw
0169  *  get_power_limit_uw
0170  *  set_time_window_us
0171  *  get_time_window_us
0172  *  get_name
0173  *  Client drivers should handle mutual exclusion, if required in callbacks.
0174  */
0175 struct powercap_zone_constraint_ops {
0176     int (*set_power_limit_uw) (struct powercap_zone *, int, u64);
0177     int (*get_power_limit_uw) (struct powercap_zone *, int, u64 *);
0178     int (*set_time_window_us) (struct powercap_zone *, int, u64);
0179     int (*get_time_window_us) (struct powercap_zone *, int, u64 *);
0180     int (*get_max_power_uw) (struct powercap_zone *, int, u64 *);
0181     int (*get_min_power_uw) (struct powercap_zone *, int, u64 *);
0182     int (*get_max_time_window_us) (struct powercap_zone *, int, u64 *);
0183     int (*get_min_time_window_us) (struct powercap_zone *, int, u64 *);
0184     const char *(*get_name) (struct powercap_zone *, int);
0185 };
0186 
0187 /**
0188  * struct powercap_zone_constraint- Defines instance of a constraint
0189  * @id:         Instance Id of this constraint.
0190  * @power_zone:     Pointer to the power zone for this constraint.
0191  * @ops:        Pointer to the constraint callbacks.
0192  *
0193  * This defines a constraint instance.
0194  */
0195 struct powercap_zone_constraint {
0196     int id;
0197     struct powercap_zone *power_zone;
0198     const struct powercap_zone_constraint_ops *ops;
0199 };
0200 
0201 
0202 /* For clients to get their device pointer, may be used for dev_dbgs */
0203 #define POWERCAP_GET_DEV(power_zone)    (&power_zone->dev)
0204 
0205 /**
0206 * powercap_set_zone_data() - Set private data for a zone
0207 * @power_zone:  A pointer to the valid zone instance.
0208 * @pdata:   A pointer to the user private data.
0209 *
0210 * Allows client drivers to associate some private data to zone instance.
0211 */
0212 static inline void powercap_set_zone_data(struct powercap_zone *power_zone,
0213                         void *pdata)
0214 {
0215     if (power_zone)
0216         power_zone->private_data = pdata;
0217 }
0218 
0219 /**
0220 * powercap_get_zone_data() - Get private data for a zone
0221 * @power_zone:  A pointer to the valid zone instance.
0222 *
0223 * Allows client drivers to get private data associate with a zone,
0224 * using call to powercap_set_zone_data.
0225 */
0226 static inline void *powercap_get_zone_data(struct powercap_zone *power_zone)
0227 {
0228     if (power_zone)
0229         return power_zone->private_data;
0230     return NULL;
0231 }
0232 
0233 /**
0234 * powercap_register_control_type() - Register a control_type with framework
0235 * @control_type:    Pointer to client allocated memory for the control type
0236 *           structure storage. If this is NULL, powercap framework
0237 *           will allocate memory and own it.
0238 *           Advantage of this parameter is that client can embed
0239 *           this data in its data structures and allocate in a
0240 *           single call, preventing multiple allocations.
0241 * @control_type_name:   The Name of this control_type, which will be shown
0242 *           in the sysfs Interface.
0243 * @ops:         Callbacks for control type. This parameter is optional.
0244 *
0245 * Used to create a control_type with the power capping class. Here control_type
0246 * can represent a type of technology, which can control a range of power zones.
0247 * For example a control_type can be RAPL (Running Average Power Limit)
0248 * IntelĀ® 64 and IA-32 Processor Architectures. The name can be any string
0249 * which must be unique, otherwise this function returns NULL.
0250 * A pointer to the control_type instance is returned on success.
0251 */
0252 struct powercap_control_type *powercap_register_control_type(
0253                 struct powercap_control_type *control_type,
0254                 const char *name,
0255                 const struct powercap_control_type_ops *ops);
0256 
0257 /**
0258 * powercap_unregister_control_type() - Unregister a control_type from framework
0259 * @instance:    A pointer to the valid control_type instance.
0260 *
0261 * Used to unregister a control_type with the power capping class.
0262 * All power zones registered under this control type have to be unregistered
0263 * before calling this function, or it will fail with an error code.
0264 */
0265 int powercap_unregister_control_type(struct powercap_control_type *instance);
0266 
0267 /* Zone register/unregister API */
0268 
0269 /**
0270 * powercap_register_zone() - Register a power zone
0271 * @power_zone:  Pointer to client allocated memory for the power zone structure
0272 *       storage. If this is NULL, powercap framework will allocate
0273 *       memory and own it. Advantage of this parameter is that client
0274 *       can embed this data in its data structures and allocate in a
0275 *       single call, preventing multiple allocations.
0276 * @control_type: A control_type instance under which this zone operates.
0277 * @name:    A name for this zone.
0278 * @parent:  A pointer to the parent power zone instance if any or NULL
0279 * @ops:     Pointer to zone operation callback structure.
0280 * @no_constraints: Number of constraints for this zone
0281 * @const_ops:   Pointer to constraint callback structure
0282 *
0283 * Register a power zone under a given control type. A power zone must register
0284 * a pointer to a structure representing zone callbacks.
0285 * A power zone can be located under a parent power zone, in which case @parent
0286 * should point to it.  Otherwise, if @parent is NULL, the new power zone will
0287 * be located directly under the given control type
0288 * For each power zone there may be a number of constraints that appear in the
0289 * sysfs under that zone as attributes with unique numeric IDs.
0290 * Returns pointer to the power_zone on success.
0291 */
0292 struct powercap_zone *powercap_register_zone(
0293             struct powercap_zone *power_zone,
0294             struct powercap_control_type *control_type,
0295             const char *name,
0296             struct powercap_zone *parent,
0297             const struct powercap_zone_ops *ops,
0298             int nr_constraints,
0299             const struct powercap_zone_constraint_ops *const_ops);
0300 
0301 /**
0302 * powercap_unregister_zone() - Unregister a zone device
0303 * @control_type:    A pointer to the valid instance of a control_type.
0304 * @power_zone:  A pointer to the valid zone instance for a control_type
0305 *
0306 * Used to unregister a zone device for a control_type.  Caller should
0307 * make sure that children for this zone are unregistered first.
0308 */
0309 int powercap_unregister_zone(struct powercap_control_type *control_type,
0310                 struct powercap_zone *power_zone);
0311 
0312 #endif