summaryrefslogtreecommitdiffstats
path: root/extras/recipes-kernel/linux/linux-omap/dvfs/0006-OMAP-Introduce-a-user-list-for-each-voltage-domain-i.patch
diff options
context:
space:
mode:
Diffstat (limited to 'extras/recipes-kernel/linux/linux-omap/dvfs/0006-OMAP-Introduce-a-user-list-for-each-voltage-domain-i.patch')
-rw-r--r--extras/recipes-kernel/linux/linux-omap/dvfs/0006-OMAP-Introduce-a-user-list-for-each-voltage-domain-i.patch199
1 files changed, 199 insertions, 0 deletions
diff --git a/extras/recipes-kernel/linux/linux-omap/dvfs/0006-OMAP-Introduce-a-user-list-for-each-voltage-domain-i.patch b/extras/recipes-kernel/linux/linux-omap/dvfs/0006-OMAP-Introduce-a-user-list-for-each-voltage-domain-i.patch
new file mode 100644
index 00000000..516c7cb0
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap/dvfs/0006-OMAP-Introduce-a-user-list-for-each-voltage-domain-i.patch
@@ -0,0 +1,199 @@
1From a4107498616e8dafa2a0155a6d45a990766b161b Mon Sep 17 00:00:00 2001
2From: Thara Gopinath <thara@ti.com>
3Date: Fri, 29 Oct 2010 20:43:07 +0530
4Subject: [PATCH 06/20] OMAP: Introduce a user list for each voltage domain instance in the voltage driver.
5
6This patch introduces a user list of devices associated with each
7voltage domain instance. The user list is implemented using plist
8structure with priority node populated with the voltage values.
9This patch also adds an API which will take in a device and
10requested voltage as parameters, adds the info to the user list
11and returns back the maximum voltage requested by all the user
12devices. This can be used anytime to get the voltage that the
13voltage domain instance can be transitioned into.
14
15Signed-off-by: Thara Gopinath <thara@ti.com>
16---
17 arch/arm/mach-omap2/voltage.c | 97 +++++++++++++++++++++++++++++
18 arch/arm/plat-omap/include/plat/voltage.h | 8 +++
19 2 files changed, 105 insertions(+), 0 deletions(-)
20
21diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
22index ed6079c..76c98c6 100644
23--- a/arch/arm/mach-omap2/voltage.c
24+++ b/arch/arm/mach-omap2/voltage.c
25@@ -24,6 +24,9 @@
26 #include <linux/err.h>
27 #include <linux/debugfs.h>
28 #include <linux/slab.h>
29+#include <linux/spinlock.h>
30+#include <linux/plist.h>
31+#include <linux/slab.h>
32
33 #include <plat/common.h>
34 #include <plat/voltage.h>
35@@ -118,6 +121,20 @@ struct vc_reg_info {
36 };
37
38 /**
39+ * struct omap_vdd_user_list - The per vdd user list
40+ *
41+ * @dev: The device asking for the vdd to be set at a particular
42+ * voltage
43+ * @node: The list head entry
44+ * @volt: The voltage requested by the device <dev>
45+ */
46+struct omap_vdd_user_list {
47+ struct device *dev;
48+ struct plist_node node;
49+ u32 volt;
50+};
51+
52+/**
53 * omap_vdd_info - Per Voltage Domain info
54 *
55 * @volt_data : voltage table having the distinct voltages supported
56@@ -132,6 +149,10 @@ struct vc_reg_info {
57 * shifts, masks etc.
58 * @voltdm : pointer to the voltage domain structure
59 * @debug_dir : debug directory for this voltage domain.
60+ * @user_lock : the lock to be used by the plist user_list
61+ * @user_list : the list head maintaining the various users.
62+ * @scaling_mutex : the dvfs muutex.
63+ * of this vdd with the voltage requested by each user.
64 * @curr_volt : current voltage for this vdd.
65 * @ocp_mod : The prm module for accessing the prm irqstatus reg.
66 * @prm_irqst_reg : prm irqstatus register.
67@@ -146,6 +167,9 @@ struct omap_vdd_info {
68 struct vc_reg_info vc_reg;
69 struct voltagedomain voltdm;
70 struct dentry *debug_dir;
71+ spinlock_t user_lock;
72+ struct plist_head user_list;
73+ struct mutex scaling_mutex;
74 u32 curr_volt;
75 u16 ocp_mod;
76 u8 prm_irqst_reg;
77@@ -869,6 +893,11 @@ static int __init omap3_vdd_data_configure(struct omap_vdd_info *vdd)
78 vdd->write_reg = omap3_voltage_write_reg;
79 vdd->volt_scale = vp_forceupdate_scale_voltage;
80 vdd->vp_enabled = false;
81+ /* Init the plist */
82+ spin_lock_init(&vdd->user_lock);
83+ plist_head_init(&vdd->user_list, &vdd->user_lock);
84+ /* Init the DVFS mutex */
85+ mutex_init(&vdd->scaling_mutex);
86
87 /* VC parameters */
88 vdd->vc_reg.prm_mod = OMAP3430_GR_MOD;
89@@ -1059,6 +1088,11 @@ static int __init omap4_vdd_data_configure(struct omap_vdd_info *vdd)
90 vdd->write_reg = omap4_voltage_write_reg;
91 vdd->volt_scale = vp_forceupdate_scale_voltage;
92 vdd->vp_enabled = false;
93+ /* Init the plist */
94+ spin_lock_init(&vdd->user_lock);
95+ plist_head_init(&vdd->user_list, &vdd->user_lock);
96+ /* Init the DVFS mutex */
97+ mutex_init(&vdd->scaling_mutex);
98
99 /* VC parameters */
100 vdd->vc_reg.prm_mod = OMAP4430_PRM_DEVICE_INST;
101@@ -1171,6 +1205,69 @@ unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm)
102
103 return vdd->pmic_info->vsel_to_uv(curr_vsel);
104 }
105+/**
106+ * omap_voltage_add_request() - API to keep track of various requests to
107+ * scale the VDD and returns the best possible
108+ * voltage the VDD can be put to.
109+ * @volt_domain: pointer to the voltage domain.
110+ * @dev: the device pointer.
111+ * @volt: the voltage which is requested by the device.
112+ *
113+ * This API is to be called before the actual voltage scaling is
114+ * done to determine what is the best possible voltage the VDD can
115+ * be put to. This API adds the device <dev> in the user list of the
116+ * vdd <volt_domain> with <volt> as the requested voltage. The user list
117+ * is a plist with the priority element absolute voltage values.
118+ * The API then finds the maximum of all the requested voltages for
119+ * the VDD and returns it back through <volt> pointer itself.
120+ * Returns error value in case of any errors.
121+ */
122+int omap_voltage_add_request(struct voltagedomain *voltdm, struct device *dev,
123+ unsigned long *volt)
124+{
125+ struct omap_vdd_info *vdd;
126+ struct omap_vdd_user_list *user;
127+ struct plist_node *node;
128+ int found = 0;
129+
130+ if (!voltdm || IS_ERR(voltdm)) {
131+ pr_warning("%s: VDD specified does not exist!\n", __func__);
132+ return -EINVAL;
133+ }
134+
135+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
136+
137+ mutex_lock(&vdd->scaling_mutex);
138+
139+ plist_for_each_entry(user, &vdd->user_list, node) {
140+ if (user->dev == dev) {
141+ found = 1;
142+ break;
143+ }
144+ }
145+
146+ if (!found) {
147+ user = kzalloc(sizeof(struct omap_vdd_user_list), GFP_KERNEL);
148+ if (!user) {
149+ pr_err("%s: Unable to creat a new user for vdd_%s\n",
150+ __func__, voltdm->name);
151+ mutex_unlock(&vdd->scaling_mutex);
152+ return -ENOMEM;
153+ }
154+ user->dev = dev;
155+ } else {
156+ plist_del(&user->node, &vdd->user_list);
157+ }
158+
159+ plist_node_init(&user->node, *volt);
160+ plist_add(&user->node, &vdd->user_list);
161+ node = plist_last(&vdd->user_list);
162+ *volt = user->volt = node->prio;
163+
164+ mutex_unlock(&vdd->scaling_mutex);
165+
166+ return 0;
167+}
168
169 /**
170 * omap_vp_enable() - API to enable a particular VP
171diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
172index 0ff1233..bd07eca 100644
173--- a/arch/arm/plat-omap/include/plat/voltage.h
174+++ b/arch/arm/plat-omap/include/plat/voltage.h
175@@ -132,6 +132,9 @@ int omap_voltage_register_pmic(struct voltagedomain *voltdm,
176 void omap_change_voltscale_method(struct voltagedomain *voltdm,
177 int voltscale_method);
178 int omap_voltage_late_init(void);
179+int omap_voltage_add_request(struct voltagedomain *voltdm, struct device *dev,
180+ unsigned long *volt);
181+
182 #else
183 static inline int omap_voltage_register_pmic(struct voltagedomain *voltdm,
184 struct omap_volt_pmic_info *pmic_info) {}
185@@ -141,6 +144,11 @@ static inline int omap_voltage_late_init(void)
186 {
187 return -EINVAL;
188 }
189+static inline int omap_voltage_add_request(struct voltagedomain *voltdm,
190+ struct device *dev, unsigned long *volt)
191+{
192+ return -EINVAL;
193+}
194 #endif
195
196 #endif
197--
1981.6.6.1
199