summaryrefslogtreecommitdiff
path: root/include/linux/edp.h
blob: 5a7f1c041d3d4760f69d446b6e25e26692e5cd01 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
 * Copyright (c) 2012-2013, NVIDIA CORPORATION.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _LINUX_EDP_H
#define _LINUX_EDP_H

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/workqueue.h>
#include <linux/sysfs.h>

#define EDP_NAME_LEN	16
#define EDP_MIN_PRIO	19
#define EDP_MAX_PRIO	0

struct edp_manager {
	char name[EDP_NAME_LEN];
	unsigned int max;

	/* internal */
	struct list_head link;
	struct list_head clients;
	bool registered;
	unsigned int remaining;
	struct edp_governor *gov;
	struct work_struct work;
	unsigned int num_denied;
	struct kobject *kobj;

	/* governor internal */
	void *gov_data;

#ifdef CONFIG_DEBUG_FS
	/* public */
	struct dentry *dentry;
#endif
};

/*
 * @states: EDP state array holding the IMAX for each state.
 *	This must be sorted in descending order.
 * @num_states: length of the above array
 * @e0_index: index of the E0 state in the above array
 * @max_borrowers: maximum number of clients allowed to borrow from this
 * @priority: client priority - should be between EDP_MIN_PRIO & EDP_MAX_PRIO
 * @throttle: throttle callback function
 * @notify_loan_update: for receiving loan size change notifications
 *	(clients should return the amount of loan consumed)
 * @notify_loan_close: for receiving loan closure notification
 * Note that each EDP client is tied to a single EDP manager
 */
struct edp_client {
	char name[EDP_NAME_LEN];
	unsigned int *states;
	unsigned int num_states;
	unsigned int e0_index;
	unsigned int max_borrowers;
	int priority;
	void *private_data;
	struct edp_client_attribute *attrs;
	unsigned int notify_ui;

	void (*throttle)(unsigned int new_state, void *priv_data);
	void (*notify_promotion)(unsigned int new_state, void *priv_data);
	unsigned int (*notify_loan_update)(unsigned int new_size,
			struct edp_client *lender, void *priv_data);
	void (*notify_loan_close)(struct edp_client *lender, void *priv_data);

	/* internal */
	struct list_head link;
	struct list_head borrowers;
	struct edp_manager *manager;
	const unsigned int *req;
	const unsigned int *cur;
	unsigned int ithreshold;
	unsigned int num_borrowers;
	unsigned int num_loans;
	struct kobject *kobj;

	/* governor internal */
	unsigned int gwt;
	struct list_head glnk;

#ifdef CONFIG_DEBUG_FS
	/* public */
	struct dentry *dentry;
#endif
};

struct edp_client_attribute {
	struct attribute attr;
	ssize_t (*show)(struct edp_client *c,
			struct edp_client_attribute *attr, char *buf);
	ssize_t (*store)(struct edp_client *c,
			struct edp_client_attribute *attr,
			const char *buf, size_t count);
};

struct edp_governor {
	char name[EDP_NAME_LEN];
	struct module *owner;

	int (*start)(struct edp_manager *mgr);
	void (*stop)(struct edp_manager *mgr);
	void (*update_request)(struct edp_client *client,
			const unsigned int *req);
	void (*update_loans)(struct edp_client *client);
	void (*promote)(struct edp_manager *mgr);

	/* internal */
	struct list_head link;
	unsigned int refcnt;
};

static inline int edp_register_manager(struct edp_manager *mgr)
{ return -ENODEV; }
static inline int edp_unregister_manager(struct edp_manager *mgr)
{ return -ENODEV; }
static inline struct edp_manager *edp_get_manager(const char *name)
{ return NULL; }
static inline int edp_register_client(struct edp_manager *mgr,
		struct edp_client *client)
{ return -ENODEV; }
static inline int edp_unregister_client(struct edp_client *client)
{ return -ENODEV; }
static inline int edp_update_client_request(struct edp_client *client,
		unsigned int req, unsigned int *approved)
{ return -ENODEV; }
static inline struct edp_client *edp_get_client(const char *name)
{ return NULL; }
static inline int edp_register_loan(struct edp_client *lender,
		struct edp_client *borrower)
{ return -ENODEV; }
static inline int edp_unregister_loan(struct edp_client *lender,
		struct edp_client *borrower)
{ return -ENODEV; }
static inline int edp_update_loan_threshold(struct edp_client *lender,
		unsigned int threshold)
{ return -ENODEV; }
static inline int edp_register_governor(struct edp_governor *gov)
{ return -ENODEV; }
static inline int edp_unregister_governor(struct edp_governor *gov)
{ return -ENODEV; }
static inline struct edp_governor *edp_get_governor(const char *name)
{ return NULL; }
static inline int edp_set_governor(struct edp_manager *mgr,
		struct edp_governor *gov)
{ return -ENODEV; }

#endif