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