diff options
author | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2012-02-17 10:15:58 -0500 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2012-05-11 07:44:51 -0400 |
commit | 966eaed08c40b49de19273b2b1ad1af4bf014862 (patch) | |
tree | 4edc100a6e1106410066fd1de00f94fec625afee /arch/arm/mach-omap2/display.c | |
parent | 11436e1dd2aab1a33f81a3737ec8641788ec8543 (diff) |
OMAPDSS: create custom pdevs for DSS omap_devices
Instead of using omap_device_build() to create the omap_devices for DSS
hwmods, create them with a custom function. This will allow us to create
a parent-child hierarchy for the devices so that the omapdss_core device
is parent for the rest of the dss hwmod devices.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'arch/arm/mach-omap2/display.c')
-rw-r--r-- | arch/arm/mach-omap2/display.c | 101 |
1 files changed, 87 insertions, 14 deletions
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 07232fd7ab17..5369bf13652b 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c | |||
@@ -185,13 +185,71 @@ static int omap_dss_set_min_bus_tput(struct device *dev, unsigned long tput) | |||
185 | return omap_pm_set_min_bus_tput(dev, OCP_INITIATOR_AGENT, tput); | 185 | return omap_pm_set_min_bus_tput(dev, OCP_INITIATOR_AGENT, tput); |
186 | } | 186 | } |
187 | 187 | ||
188 | static struct platform_device *create_dss_pdev(const char *pdev_name, | ||
189 | int pdev_id, const char *oh_name, void *pdata, int pdata_len, | ||
190 | struct platform_device *parent) | ||
191 | { | ||
192 | struct platform_device *pdev; | ||
193 | struct omap_device *od; | ||
194 | struct omap_hwmod *ohs[1]; | ||
195 | struct omap_hwmod *oh; | ||
196 | int r; | ||
197 | |||
198 | oh = omap_hwmod_lookup(oh_name); | ||
199 | if (!oh) { | ||
200 | pr_err("Could not look up %s\n", oh_name); | ||
201 | r = -ENODEV; | ||
202 | goto err; | ||
203 | } | ||
204 | |||
205 | pdev = platform_device_alloc(pdev_name, pdev_id); | ||
206 | if (!pdev) { | ||
207 | pr_err("Could not create pdev for %s\n", pdev_name); | ||
208 | r = -ENOMEM; | ||
209 | goto err; | ||
210 | } | ||
211 | |||
212 | if (parent != NULL) | ||
213 | pdev->dev.parent = &parent->dev; | ||
214 | |||
215 | if (pdev->id != -1) | ||
216 | dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); | ||
217 | else | ||
218 | dev_set_name(&pdev->dev, "%s", pdev->name); | ||
219 | |||
220 | ohs[0] = oh; | ||
221 | od = omap_device_alloc(pdev, ohs, 1, NULL, 0); | ||
222 | if (!od) { | ||
223 | pr_err("Could not alloc omap_device for %s\n", pdev_name); | ||
224 | r = -ENOMEM; | ||
225 | goto err; | ||
226 | } | ||
227 | |||
228 | r = platform_device_add_data(pdev, pdata, pdata_len); | ||
229 | if (r) { | ||
230 | pr_err("Could not set pdata for %s\n", pdev_name); | ||
231 | goto err; | ||
232 | } | ||
233 | |||
234 | r = omap_device_register(pdev); | ||
235 | if (r) { | ||
236 | pr_err("Could not register omap_device for %s\n", pdev_name); | ||
237 | goto err; | ||
238 | } | ||
239 | |||
240 | return pdev; | ||
241 | |||
242 | err: | ||
243 | return ERR_PTR(r); | ||
244 | } | ||
245 | |||
188 | int __init omap_display_init(struct omap_dss_board_info *board_data) | 246 | int __init omap_display_init(struct omap_dss_board_info *board_data) |
189 | { | 247 | { |
190 | int r = 0; | 248 | int r = 0; |
191 | struct omap_hwmod *oh; | ||
192 | struct platform_device *pdev; | 249 | struct platform_device *pdev; |
193 | int i, oh_count; | 250 | int i, oh_count; |
194 | const struct omap_dss_hwmod_data *curr_dss_hwmod; | 251 | const struct omap_dss_hwmod_data *curr_dss_hwmod; |
252 | struct platform_device *dss_pdev; | ||
195 | 253 | ||
196 | /* create omapdss device */ | 254 | /* create omapdss device */ |
197 | 255 | ||
@@ -221,22 +279,37 @@ int __init omap_display_init(struct omap_dss_board_info *board_data) | |||
221 | oh_count = ARRAY_SIZE(omap4_dss_hwmod_data); | 279 | oh_count = ARRAY_SIZE(omap4_dss_hwmod_data); |
222 | } | 280 | } |
223 | 281 | ||
224 | for (i = 0; i < oh_count; i++) { | 282 | /* |
225 | oh = omap_hwmod_lookup(curr_dss_hwmod[i].oh_name); | 283 | * First create the pdev for dss_core, which is used as a parent device |
226 | if (!oh) { | 284 | * by the other dss pdevs. Note: dss_core has to be the first item in |
227 | pr_err("Could not look up %s\n", | 285 | * the hwmod list. |
228 | curr_dss_hwmod[i].oh_name); | 286 | */ |
229 | return -ENODEV; | 287 | dss_pdev = create_dss_pdev(curr_dss_hwmod[0].dev_name, |
230 | } | 288 | curr_dss_hwmod[0].id, |
289 | curr_dss_hwmod[0].oh_name, | ||
290 | NULL, 0, | ||
291 | NULL); | ||
231 | 292 | ||
232 | pdev = omap_device_build(curr_dss_hwmod[i].dev_name, | 293 | if (IS_ERR(dss_pdev)) { |
233 | curr_dss_hwmod[i].id, oh, | 294 | pr_err("Could not build omap_device for %s\n", |
295 | curr_dss_hwmod[0].oh_name); | ||
296 | |||
297 | return PTR_ERR(dss_pdev); | ||
298 | } | ||
299 | |||
300 | for (i = 1; i < oh_count; i++) { | ||
301 | pdev = create_dss_pdev(curr_dss_hwmod[i].dev_name, | ||
302 | curr_dss_hwmod[i].id, | ||
303 | curr_dss_hwmod[i].oh_name, | ||
234 | NULL, 0, | 304 | NULL, 0, |
235 | NULL, 0, 0); | 305 | dss_pdev); |
306 | |||
307 | if (IS_ERR(pdev)) { | ||
308 | pr_err("Could not build omap_device for %s\n", | ||
309 | curr_dss_hwmod[i].oh_name); | ||
236 | 310 | ||
237 | if (WARN((IS_ERR(pdev)), "Could not build omap_device for %s\n", | 311 | return PTR_ERR(pdev); |
238 | curr_dss_hwmod[i].oh_name)) | 312 | } |
239 | return -ENODEV; | ||
240 | } | 313 | } |
241 | 314 | ||
242 | return 0; | 315 | return 0; |