1 From be5bdabb6206f106f0dcf91b0e90474d23773416 Mon Sep 17 00:00:00 2001
2 From: Thara Gopinath <thara@ti.com>
3 Date: Fri, 29 Oct 2010 20:43:24 +0530
4 Subject: [PATCH 08/19] OMAP: Introduce API to register a device with a voltagedomain
6 This patch adds an API in the voltage layer that
7 can be used during omap_device_build to register the built
8 device with the voltage domain. This API is to be typically called
9 only once per device during the device registeration. This approach
10 makes it easy during dvfs to scale all the devices associated with
11 a voltage domain and then scale the voltage domain.
13 Signed-off-by: Thara Gopinath <thara@ti.com>
15 arch/arm/mach-omap2/voltage.c | 50 +++++++++++++++++++++++++++++
16 arch/arm/plat-omap/include/plat/voltage.h | 7 +++-
17 arch/arm/plat-omap/omap_device.c | 12 +++++++
18 3 files changed, 68 insertions(+), 1 deletions(-)
20 diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
21 index 76c98c6..7381fa6 100644
22 --- a/arch/arm/mach-omap2/voltage.c
23 +++ b/arch/arm/mach-omap2/voltage.c
24 @@ -134,6 +134,11 @@ struct omap_vdd_user_list {
28 +struct omap_vdd_dev_list {
30 + struct list_head node;
34 * omap_vdd_info - Per Voltage Domain info
36 @@ -153,6 +158,7 @@ struct omap_vdd_user_list {
37 * @user_list : the list head maintaining the various users.
38 * @scaling_mutex : the dvfs muutex.
39 * of this vdd with the voltage requested by each user.
40 + * @dev_list : list of devices bwlonging to this voltage domain.
41 * @curr_volt : current voltage for this vdd.
42 * @ocp_mod : The prm module for accessing the prm irqstatus reg.
43 * @prm_irqst_reg : prm irqstatus register.
44 @@ -170,6 +176,7 @@ struct omap_vdd_info {
46 struct plist_head user_list;
47 struct mutex scaling_mutex;
48 + struct list_head dev_list;
52 @@ -1093,6 +1100,8 @@ static int __init omap4_vdd_data_configure(struct omap_vdd_info *vdd)
53 plist_head_init(&vdd->user_list, &vdd->user_lock);
54 /* Init the DVFS mutex */
55 mutex_init(&vdd->scaling_mutex);
56 + /* Init the device list */
57 + INIT_LIST_HEAD(&vdd->dev_list);
60 vdd->vc_reg.prm_mod = OMAP4430_PRM_DEVICE_INST;
61 @@ -1269,6 +1278,40 @@ int omap_voltage_add_request(struct voltagedomain *voltdm, struct device *dev,
65 +int omap_voltage_add_dev(struct voltagedomain *voltdm, struct device *dev)
67 + struct omap_vdd_info *vdd;
68 + struct omap_vdd_dev_list *temp_dev;
70 + if (!voltdm || IS_ERR(voltdm)) {
71 + pr_warning("%s: VDD specified does not exist!\n", __func__);
75 + vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
77 + list_for_each_entry(temp_dev, &vdd->dev_list, node) {
78 + if (temp_dev->dev == dev) {
79 + dev_warn(dev, "%s: Device already added to vdee_%s\n",
80 + __func__, voltdm->name);
85 + temp_dev = kzalloc(sizeof(struct omap_vdd_dev_list), GFP_KERNEL);
87 + dev_err(dev, "%s: Unable to creat a new device for vdd_%s\n",
88 + __func__, voltdm->name);
92 + temp_dev->dev = dev;
94 + list_add(&temp_dev->node, &vdd->dev_list);
100 * omap_vp_enable() - API to enable a particular VP
101 * @voltdm: pointer to the VDD whose VP is to be enabled.
102 @@ -1649,6 +1692,8 @@ int __init omap_voltage_late_init(void)
104 static int __init omap_voltage_early_init(void)
108 if (cpu_is_omap34xx()) {
109 vdd_info = omap3_vdd_info;
110 nr_scalable_vdd = OMAP3_NR_SCALABLE_VDD;
111 @@ -1661,8 +1706,13 @@ static int __init omap_voltage_early_init(void)
112 vdd_data_configure = omap4_vdd_data_configure;
114 pr_warning("%s: voltage driver support not added\n", __func__);
118 + /* Init the device list */
119 + for (i = 0; i < nr_scalable_vdd; i++)
120 + INIT_LIST_HEAD(&(vdd_info[i].dev_list));
124 core_initcall(omap_voltage_early_init);
125 diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
126 index bd07eca..adbc6af 100644
127 --- a/arch/arm/plat-omap/include/plat/voltage.h
128 +++ b/arch/arm/plat-omap/include/plat/voltage.h
129 @@ -134,7 +134,7 @@ void omap_change_voltscale_method(struct voltagedomain *voltdm,
130 int omap_voltage_late_init(void);
131 int omap_voltage_add_request(struct voltagedomain *voltdm, struct device *dev,
132 unsigned long *volt);
134 +int omap_voltage_add_dev(struct voltagedomain *voltdm, struct device *dev);
136 static inline int omap_voltage_register_pmic(struct voltagedomain *voltdm,
137 struct omap_volt_pmic_info *pmic_info) {}
138 @@ -149,6 +149,11 @@ static inline int omap_voltage_add_request(struct voltagedomain *voltdm,
142 +static inline int omap_voltage_add_dev(struct voltagedomain *voltdm,
143 + struct device *dev)
150 diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
151 index 57adb27..2c95e61 100644
152 --- a/arch/arm/plat-omap/omap_device.c
153 +++ b/arch/arm/plat-omap/omap_device.c
156 #include <plat/omap_device.h>
157 #include <plat/omap_hwmod.h>
158 +#include <plat/voltage.h>
160 /* These parameters are passed to _omap_device_{de,}activate() */
161 #define USE_WAKEUP_LAT 0
162 @@ -481,6 +482,17 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
163 for (i = 0; i < oh_cnt; i++) {
165 _add_optional_clock_alias(od, hwmods[i]);
166 + if (hwmods[i]->vdd_name) {
167 + struct omap_hwmod *oh = hwmods[i];
168 + struct voltagedomain *voltdm;
170 + if (is_early_device)
173 + voltdm = omap_voltage_domain_lookup(oh->vdd_name);
174 + if (!omap_voltage_add_dev(voltdm, &od->pdev.dev))
175 + oh->voltdm = voltdm;