aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorChanwoo Choi <cw00.choi@samsung.com>2015-01-25 23:16:27 -0500
committerMyungJoo Ham <myungjoo.ham@samsung.com>2015-01-30 03:56:40 -0500
commitf262f28c147051e7aa6daaf4fb5996833ffadff4 (patch)
treed12bfa2a472245c2ac39a9a734f6cc2c0541fc3c /include/linux
parent6234f38016ad56321ad0e4bfb57a10a3d940380a (diff)
PM / devfreq: event: Add devfreq_event class
This patch adds a new class in devfreq, devfreq_event, which provides raw data (e.g., memory bus utilization, GPU utilization) for devfreq governors. - devfreq_event device : Provides raw data for a governor of a devfreq device - devfreq device : Monitors device state and changes frequency/voltage of the device using the raw data from its devfreq_event device. A devfreq device dertermines performance states (normally the frequency and the voltage vlues) based on the results its designtated devfreq governor: e.g., ondemand, performance, powersave. In order to give such results required by a devfreq device, the devfreq governor requires data that indicates the performance requirement given to the devfreq device. The conventional (previous) implementatino of devfreq subsystem requires a devfreq device driver to implement its own mechanism to acquire performance requirement for its governor. However, there had been issues with such requirements: 1. Although performance requirement of such devices is usually acquired from common devices (PMU/PPMU), we do not have any abstract structure to represent them properly. 2. Such performance requirement devices (PMU/PPMU) are actual hardware pieces that may be represented by Device Tree directly while devfreq device itself is a virtual entity that are not considered to be represented by Device Tree according to Device Tree folks. In order to address such issues, a devferq_event device (represented by this patch) provides a template for device drivers representing performance monitoring unit, which gives the basic or raw data for preformance requirement, which in turn, is required by devfreq governors. The following description explains the feature of two kind of devfreq class: - devfreq class (existing) : devfreq consumer device use raw data from devfreq_event device for determining proper current system state and change voltage/frequency dynamically using various governors. - devfreq_event class (new) : Provide measured raw data to devfreq device for governor Cc: MyungJoo Ham <myungjoo.ham@samsung.com> Cc: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> [Commit message rewritten & conflict resolved by MyungJoo] Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/devfreq-event.h196
1 files changed, 196 insertions, 0 deletions
diff --git a/include/linux/devfreq-event.h b/include/linux/devfreq-event.h
new file mode 100644
index 000000000000..602fbbfcfeed
--- /dev/null
+++ b/include/linux/devfreq-event.h
@@ -0,0 +1,196 @@
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 */
29struct 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 */
50struct 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 */
68struct 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 */
90struct devfreq_event_desc {
91 const char *name;
92 void *driver_data;
93
94 struct devfreq_event_ops *ops;
95};
96
97#if defined(CONFIG_PM_DEVFREQ_EVENT)
98extern int devfreq_event_enable_edev(struct devfreq_event_dev *edev);
99extern int devfreq_event_disable_edev(struct devfreq_event_dev *edev);
100extern bool devfreq_event_is_enabled(struct devfreq_event_dev *edev);
101extern int devfreq_event_set_event(struct devfreq_event_dev *edev);
102extern int devfreq_event_get_event(struct devfreq_event_dev *edev,
103 struct devfreq_event_data *edata);
104extern int devfreq_event_reset_event(struct devfreq_event_dev *edev);
105extern struct devfreq_event_dev *devfreq_event_get_edev_by_phandle(
106 struct device *dev, int index);
107extern int devfreq_event_get_edev_count(struct device *dev);
108extern struct devfreq_event_dev *devfreq_event_add_edev(struct device *dev,
109 struct devfreq_event_desc *desc);
110extern int devfreq_event_remove_edev(struct devfreq_event_dev *edev);
111extern struct devfreq_event_dev *devm_devfreq_event_add_edev(struct device *dev,
112 struct devfreq_event_desc *desc);
113extern void devm_devfreq_event_remove_edev(struct device *dev,
114 struct devfreq_event_dev *edev);
115static inline void *devfreq_event_get_drvdata(struct devfreq_event_dev *edev)
116{
117 return edev->desc->driver_data;
118}
119#else
120static inline int devfreq_event_enable_edev(struct devfreq_event_dev *edev)
121{
122 return -EINVAL;
123}
124
125static inline int devfreq_event_disable_edev(struct devfreq_event_dev *edev)
126{
127 return -EINVAL;
128}
129
130static inline bool devfreq_event_is_enabled(struct devfreq_event_dev *edev)
131{
132 return false;
133}
134
135static inline int devfreq_event_set_event(struct devfreq_event_dev *edev)
136{
137 return -EINVAL;
138}
139
140static inline int devfreq_event_get_event(struct devfreq_event_dev *edev,
141 struct devfreq_event_data *edata)
142{
143 return -EINVAL;
144}
145
146static inline int devfreq_event_reset_event(struct devfreq_event_dev *edev)
147{
148 return -EINVAL;
149}
150
151static inline void *devfreq_event_get_drvdata(struct devfreq_event_dev *edev)
152{
153 return ERR_PTR(-EINVAL);
154}
155
156static inline struct devfreq_event_dev *devfreq_event_get_edev_by_phandle(
157 struct device *dev, int index)
158{
159 return ERR_PTR(-EINVAL);
160}
161
162static inline int devfreq_event_get_edev_count(struct device *dev)
163{
164 return -EINVAL;
165}
166
167static inline struct devfreq_event_dev *devfreq_event_add_edev(struct device *dev,
168 struct devfreq_event_desc *desc)
169{
170 return ERR_PTR(-EINVAL);
171}
172
173static inline int devfreq_event_remove_edev(struct devfreq_event_dev *edev)
174{
175 return -EINVAL;
176}
177
178static inline struct devfreq_event_dev *devm_devfreq_event_add_edev(
179 struct device *dev,
180 struct devfreq_event_desc *desc)
181{
182 return ERR_PTR(-EINVAL);
183}
184
185static inline void devm_devfreq_event_remove_edev(struct device *dev,
186 struct devfreq_event_dev *edev)
187{
188}
189
190static inline void *devfreq_event_get_drvdata(struct devfreq_event_dev *edev)
191{
192 return NULL;
193}
194#endif /* CONFIG_PM_DEVFREQ_EVENT */
195
196#endif /* __LINUX_DEVFREQ_EVENT_H__ */