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