1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * devfreq-event: a framework to provide raw data and events of devfreq devices
4  *
5  * Copyright (C) 2014 Samsung Electronics
6  * Author: Chanwoo Choi <cw00.choi@samsung.com>
7  */
8 
9 #ifndef __LINUX_DEVFREQ_EVENT_H__
10 #define __LINUX_DEVFREQ_EVENT_H__
11 
12 #include <linux/device.h>
13 
14 /**
15  * struct devfreq_event_dev - the devfreq-event device
16  *
17  * @node	: Contain the devfreq-event device that have been registered.
18  * @dev		: the device registered by devfreq-event class. dev.parent is
19  *		  the device using devfreq-event.
20  * @lock	: a mutex to protect accessing devfreq-event.
21  * @enable_count: the number of enable function have been called.
22  * @desc	: the description for devfreq-event device.
23  *
24  * This structure contains devfreq-event device information.
25  */
26 struct devfreq_event_dev {
27 	struct list_head node;
28 
29 	struct device dev;
30 	struct mutex lock;
31 	u32 enable_count;
32 
33 	const struct devfreq_event_desc *desc;
34 };
35 
36 /**
37  * struct devfreq_event_data - the devfreq-event data
38  *
39  * @load_count	: load count of devfreq-event device for the given period.
40  * @total_count	: total count of devfreq-event device for the given period.
41  *		  each count may represent a clock cycle, a time unit
42  *		  (ns/us/...), or anything the device driver wants.
43  *		  Generally, utilization is load_count / total_count.
44  *
45  * This structure contains the data of devfreq-event device for polling period.
46  */
47 struct devfreq_event_data {
48 	unsigned long load_count;
49 	unsigned long total_count;
50 };
51 
52 /**
53  * struct devfreq_event_ops - the operations of devfreq-event device
54  *
55  * @enable	: Enable the devfreq-event device.
56  * @disable	: Disable the devfreq-event device.
57  * @reset	: Reset all setting of the devfreq-event device.
58  * @set_event	: Set the specific event type for the devfreq-event device.
59  * @get_event	: Get the result of the devfreq-event devie with specific
60  *		  event type.
61  *
62  * This structure contains devfreq-event device operations which can be
63  * implemented by devfreq-event device drivers.
64  */
65 struct devfreq_event_ops {
66 	/* Optional functions */
67 	int (*enable)(struct devfreq_event_dev *edev);
68 	int (*disable)(struct devfreq_event_dev *edev);
69 	int (*reset)(struct devfreq_event_dev *edev);
70 
71 	/* Mandatory functions */
72 	int (*set_event)(struct devfreq_event_dev *edev);
73 	int (*get_event)(struct devfreq_event_dev *edev,
74 			 struct devfreq_event_data *edata);
75 };
76 
77 /**
78  * struct devfreq_event_desc - the descriptor of devfreq-event device
79  *
80  * @name	: the name of devfreq-event device.
81  * @event_type	: the type of the event determined and used by driver
82  * @driver_data	: the private data for devfreq-event driver.
83  * @ops		: the operation to control devfreq-event device.
84  *
85  * Each devfreq-event device is described with a this structure.
86  * This structure contains the various data for devfreq-event device.
87  * The event_type describes what is going to be counted in the register.
88  * It might choose to count e.g. read requests, write data in bytes, etc.
89  * The full supported list of types is present in specyfic header in:
90  * include/dt-bindings/pmu/.
91  */
92 struct devfreq_event_desc {
93 	const char *name;
94 	u32 event_type;
95 	void *driver_data;
96 
97 	const struct devfreq_event_ops *ops;
98 };
99 
100 #if defined(CONFIG_PM_DEVFREQ_EVENT)
101 extern int devfreq_event_enable_edev(struct devfreq_event_dev *edev);
102 extern int devfreq_event_disable_edev(struct devfreq_event_dev *edev);
103 extern bool devfreq_event_is_enabled(struct devfreq_event_dev *edev);
104 extern int devfreq_event_set_event(struct devfreq_event_dev *edev);
105 extern int devfreq_event_get_event(struct devfreq_event_dev *edev,
106 				struct devfreq_event_data *edata);
107 extern int devfreq_event_reset_event(struct devfreq_event_dev *edev);
108 extern struct devfreq_event_dev *devfreq_event_get_edev_by_phandle(
109 				struct device *dev,
110 				const char *phandle_name,
111 				int index);
112 extern int devfreq_event_get_edev_count(struct device *dev,
113 				const char *phandle_name);
114 extern struct devfreq_event_dev *devfreq_event_add_edev(struct device *dev,
115 				struct devfreq_event_desc *desc);
116 extern int devfreq_event_remove_edev(struct devfreq_event_dev *edev);
117 extern struct devfreq_event_dev *devm_devfreq_event_add_edev(struct device *dev,
118 				struct devfreq_event_desc *desc);
119 extern void devm_devfreq_event_remove_edev(struct device *dev,
120 				struct devfreq_event_dev *edev);
devfreq_event_get_drvdata(struct devfreq_event_dev * edev)121 static inline void *devfreq_event_get_drvdata(struct devfreq_event_dev *edev)
122 {
123 	return edev->desc->driver_data;
124 }
125 #else
devfreq_event_enable_edev(struct devfreq_event_dev * edev)126 static inline int devfreq_event_enable_edev(struct devfreq_event_dev *edev)
127 {
128 	return -EINVAL;
129 }
130 
devfreq_event_disable_edev(struct devfreq_event_dev * edev)131 static inline int devfreq_event_disable_edev(struct devfreq_event_dev *edev)
132 {
133 	return -EINVAL;
134 }
135 
devfreq_event_is_enabled(struct devfreq_event_dev * edev)136 static inline bool devfreq_event_is_enabled(struct devfreq_event_dev *edev)
137 {
138 	return false;
139 }
140 
devfreq_event_set_event(struct devfreq_event_dev * edev)141 static inline int devfreq_event_set_event(struct devfreq_event_dev *edev)
142 {
143 	return -EINVAL;
144 }
145 
devfreq_event_get_event(struct devfreq_event_dev * edev,struct devfreq_event_data * edata)146 static inline int devfreq_event_get_event(struct devfreq_event_dev *edev,
147 					struct devfreq_event_data *edata)
148 {
149 	return -EINVAL;
150 }
151 
devfreq_event_reset_event(struct devfreq_event_dev * edev)152 static inline int devfreq_event_reset_event(struct devfreq_event_dev *edev)
153 {
154 	return -EINVAL;
155 }
156 
devfreq_event_get_edev_by_phandle(struct device * dev,const char * phandle_name,int index)157 static inline struct devfreq_event_dev *devfreq_event_get_edev_by_phandle(
158 					struct device *dev,
159 					const char *phandle_name,
160 					int index)
161 {
162 	return ERR_PTR(-EINVAL);
163 }
164 
devfreq_event_get_edev_count(struct device * dev,const char * phandle_name)165 static inline int devfreq_event_get_edev_count(struct device *dev,
166 					const char *phandle_name)
167 {
168 	return -EINVAL;
169 }
170 
devfreq_event_add_edev(struct device * dev,struct devfreq_event_desc * desc)171 static inline struct devfreq_event_dev *devfreq_event_add_edev(struct device *dev,
172 					struct devfreq_event_desc *desc)
173 {
174 	return ERR_PTR(-EINVAL);
175 }
176 
devfreq_event_remove_edev(struct devfreq_event_dev * edev)177 static inline int devfreq_event_remove_edev(struct devfreq_event_dev *edev)
178 {
179 	return -EINVAL;
180 }
181 
devm_devfreq_event_add_edev(struct device * dev,struct devfreq_event_desc * desc)182 static inline struct devfreq_event_dev *devm_devfreq_event_add_edev(
183 					struct device *dev,
184 					struct devfreq_event_desc *desc)
185 {
186 	return ERR_PTR(-EINVAL);
187 }
188 
devm_devfreq_event_remove_edev(struct device * dev,struct devfreq_event_dev * edev)189 static inline void devm_devfreq_event_remove_edev(struct device *dev,
190 					struct devfreq_event_dev *edev)
191 {
192 }
193 
devfreq_event_get_drvdata(struct devfreq_event_dev * edev)194 static inline void *devfreq_event_get_drvdata(struct devfreq_event_dev *edev)
195 {
196 	return NULL;
197 }
198 #endif /* CONFIG_PM_DEVFREQ_EVENT */
199 
200 #endif /* __LINUX_DEVFREQ_EVENT_H__ */
201