b69e6f6af918dd1f2801c7d5eebbc006f11e35d8
[openembedded.git] /
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
5
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.
12
13 Signed-off-by: Thara Gopinath <thara@ti.com>
14 ---
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(-)
19
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 {
25         u32 volt;
26  };
27  
28 +struct omap_vdd_dev_list {
29 +       struct device *dev;
30 +       struct list_head node;
31 +};
32 +
33  /**
34   * omap_vdd_info - Per Voltage Domain info
35   *
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 {
45         spinlock_t user_lock;
46         struct plist_head user_list;
47         struct mutex scaling_mutex;
48 +       struct list_head dev_list;
49         u32 curr_volt;
50         u16 ocp_mod;
51         u8 prm_irqst_reg;
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);
58  
59         /* VC parameters */
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,
62         return 0;
63  }
64  
65 +int omap_voltage_add_dev(struct voltagedomain *voltdm, struct device *dev)
66 +{
67 +       struct omap_vdd_info *vdd;
68 +       struct omap_vdd_dev_list *temp_dev;
69 +
70 +       if (!voltdm || IS_ERR(voltdm)) {
71 +               pr_warning("%s: VDD specified does not exist!\n", __func__);
72 +               return -EINVAL;
73 +       }
74 +
75 +       vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
76 +
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);
81 +                       return -EINVAL;
82 +               }
83 +       }
84 +
85 +       temp_dev = kzalloc(sizeof(struct omap_vdd_dev_list), GFP_KERNEL);
86 +       if (!temp_dev) {
87 +               dev_err(dev, "%s: Unable to creat a new device for vdd_%s\n",
88 +                       __func__, voltdm->name);
89 +               return -ENOMEM;
90 +       }
91 +
92 +       temp_dev->dev = dev;
93 +
94 +       list_add(&temp_dev->node, &vdd->dev_list);
95 +
96 +       return 0;
97 +}
98 +
99  /**
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)
103   */
104  static int __init omap_voltage_early_init(void)
105  {
106 +       int i;
107 +
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;
113         } else {
114                 pr_warning("%s: voltage driver support not added\n", __func__);
115 +               return -EINVAL;
116         }
117  
118 +       /* Init the device list */
119 +       for (i = 0; i < nr_scalable_vdd; i++)
120 +               INIT_LIST_HEAD(&(vdd_info[i].dev_list));
121 +
122         return 0;
123  }
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);
133 -
134 +int omap_voltage_add_dev(struct voltagedomain *voltdm, struct device *dev);
135  #else
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,
139  {
140         return -EINVAL;
141  }
142 +static inline int omap_voltage_add_dev(struct voltagedomain *voltdm,
143 +               struct device *dev)
144 +{
145 +       return -EINVAL;
146 +}
147  #endif
148  
149  #endif
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
154 @@ -86,6 +86,7 @@
155  
156  #include <plat/omap_device.h>
157  #include <plat/omap_hwmod.h>
158 +#include <plat/voltage.h>
159  
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++) {
164                 hwmods[i]->od = od;
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;
169 +
170 +                       if (is_early_device)
171 +                               continue;
172 +
173 +                       voltdm = omap_voltage_domain_lookup(oh->vdd_name);
174 +                       if (!omap_voltage_add_dev(voltdm, &od->pdev.dev))
175 +                               oh->voltdm = voltdm;
176 +               }
177         }
178  
179         if (ret)
180 -- 
181 1.6.6.1
182