diff options
Diffstat (limited to 'arch/arm/plat-omap/omap_device.c')
-rw-r--r-- | arch/arm/plat-omap/omap_device.c | 102 |
1 files changed, 84 insertions, 18 deletions
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index 2ed72013c2e2..590435894848 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c | |||
@@ -90,6 +90,8 @@ | |||
90 | #define IGNORE_WAKEUP_LAT 1 | 90 | #define IGNORE_WAKEUP_LAT 1 |
91 | 91 | ||
92 | 92 | ||
93 | #define OMAP_DEVICE_MAGIC 0xf00dcafe | ||
94 | |||
93 | /* Private functions */ | 95 | /* Private functions */ |
94 | 96 | ||
95 | /** | 97 | /** |
@@ -138,10 +140,22 @@ static int _omap_device_activate(struct omap_device *od, u8 ignore_lat) | |||
138 | "%llu nsec\n", od->pdev.name, od->pm_lat_level, | 140 | "%llu nsec\n", od->pdev.name, od->pm_lat_level, |
139 | act_lat); | 141 | act_lat); |
140 | 142 | ||
141 | WARN(act_lat > odpl->activate_lat, "omap_device: %s.%d: " | 143 | if (act_lat > odpl->activate_lat) { |
142 | "activate step %d took longer than expected (%llu > %d)\n", | 144 | odpl->activate_lat_worst = act_lat; |
143 | od->pdev.name, od->pdev.id, od->pm_lat_level, | 145 | if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) { |
144 | act_lat, odpl->activate_lat); | 146 | odpl->activate_lat = act_lat; |
147 | pr_warning("omap_device: %s.%d: new worst case " | ||
148 | "activate latency %d: %llu\n", | ||
149 | od->pdev.name, od->pdev.id, | ||
150 | od->pm_lat_level, act_lat); | ||
151 | } else | ||
152 | pr_warning("omap_device: %s.%d: activate " | ||
153 | "latency %d higher than exptected. " | ||
154 | "(%llu > %d)\n", | ||
155 | od->pdev.name, od->pdev.id, | ||
156 | od->pm_lat_level, act_lat, | ||
157 | odpl->activate_lat); | ||
158 | } | ||
145 | 159 | ||
146 | od->dev_wakeup_lat -= odpl->activate_lat; | 160 | od->dev_wakeup_lat -= odpl->activate_lat; |
147 | } | 161 | } |
@@ -194,10 +208,23 @@ static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat) | |||
194 | "%llu nsec\n", od->pdev.name, od->pm_lat_level, | 208 | "%llu nsec\n", od->pdev.name, od->pm_lat_level, |
195 | deact_lat); | 209 | deact_lat); |
196 | 210 | ||
197 | WARN(deact_lat > odpl->deactivate_lat, "omap_device: %s.%d: " | 211 | if (deact_lat > odpl->deactivate_lat) { |
198 | "deactivate step %d took longer than expected " | 212 | odpl->deactivate_lat_worst = deact_lat; |
199 | "(%llu > %d)\n", od->pdev.name, od->pdev.id, | 213 | if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) { |
200 | od->pm_lat_level, deact_lat, odpl->deactivate_lat); | 214 | odpl->deactivate_lat = deact_lat; |
215 | pr_warning("omap_device: %s.%d: new worst case " | ||
216 | "deactivate latency %d: %llu\n", | ||
217 | od->pdev.name, od->pdev.id, | ||
218 | od->pm_lat_level, deact_lat); | ||
219 | } else | ||
220 | pr_warning("omap_device: %s.%d: deactivate " | ||
221 | "latency %d higher than exptected. " | ||
222 | "(%llu > %d)\n", | ||
223 | od->pdev.name, od->pdev.id, | ||
224 | od->pm_lat_level, deact_lat, | ||
225 | odpl->deactivate_lat); | ||
226 | } | ||
227 | |||
201 | 228 | ||
202 | od->dev_wakeup_lat += odpl->activate_lat; | 229 | od->dev_wakeup_lat += odpl->activate_lat; |
203 | 230 | ||
@@ -280,6 +307,7 @@ int omap_device_fill_resources(struct omap_device *od, struct resource *res) | |||
280 | * @pdata_len: amount of memory pointed to by @pdata | 307 | * @pdata_len: amount of memory pointed to by @pdata |
281 | * @pm_lats: pointer to a omap_device_pm_latency array for this device | 308 | * @pm_lats: pointer to a omap_device_pm_latency array for this device |
282 | * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats | 309 | * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats |
310 | * @is_early_device: should the device be registered as an early device or not | ||
283 | * | 311 | * |
284 | * Convenience function for building and registering a single | 312 | * Convenience function for building and registering a single |
285 | * omap_device record, which in turn builds and registers a | 313 | * omap_device record, which in turn builds and registers a |
@@ -291,7 +319,7 @@ struct omap_device *omap_device_build(const char *pdev_name, int pdev_id, | |||
291 | struct omap_hwmod *oh, void *pdata, | 319 | struct omap_hwmod *oh, void *pdata, |
292 | int pdata_len, | 320 | int pdata_len, |
293 | struct omap_device_pm_latency *pm_lats, | 321 | struct omap_device_pm_latency *pm_lats, |
294 | int pm_lats_cnt) | 322 | int pm_lats_cnt, int is_early_device) |
295 | { | 323 | { |
296 | struct omap_hwmod *ohs[] = { oh }; | 324 | struct omap_hwmod *ohs[] = { oh }; |
297 | 325 | ||
@@ -299,7 +327,8 @@ struct omap_device *omap_device_build(const char *pdev_name, int pdev_id, | |||
299 | return ERR_PTR(-EINVAL); | 327 | return ERR_PTR(-EINVAL); |
300 | 328 | ||
301 | return omap_device_build_ss(pdev_name, pdev_id, ohs, 1, pdata, | 329 | return omap_device_build_ss(pdev_name, pdev_id, ohs, 1, pdata, |
302 | pdata_len, pm_lats, pm_lats_cnt); | 330 | pdata_len, pm_lats, pm_lats_cnt, |
331 | is_early_device); | ||
303 | } | 332 | } |
304 | 333 | ||
305 | /** | 334 | /** |
@@ -311,6 +340,7 @@ struct omap_device *omap_device_build(const char *pdev_name, int pdev_id, | |||
311 | * @pdata_len: amount of memory pointed to by @pdata | 340 | * @pdata_len: amount of memory pointed to by @pdata |
312 | * @pm_lats: pointer to a omap_device_pm_latency array for this device | 341 | * @pm_lats: pointer to a omap_device_pm_latency array for this device |
313 | * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats | 342 | * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats |
343 | * @is_early_device: should the device be registered as an early device or not | ||
314 | * | 344 | * |
315 | * Convenience function for building and registering an omap_device | 345 | * Convenience function for building and registering an omap_device |
316 | * subsystem record. Subsystem records consist of multiple | 346 | * subsystem record. Subsystem records consist of multiple |
@@ -322,7 +352,7 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id, | |||
322 | struct omap_hwmod **ohs, int oh_cnt, | 352 | struct omap_hwmod **ohs, int oh_cnt, |
323 | void *pdata, int pdata_len, | 353 | void *pdata, int pdata_len, |
324 | struct omap_device_pm_latency *pm_lats, | 354 | struct omap_device_pm_latency *pm_lats, |
325 | int pm_lats_cnt) | 355 | int pm_lats_cnt, int is_early_device) |
326 | { | 356 | { |
327 | int ret = -ENOMEM; | 357 | int ret = -ENOMEM; |
328 | struct omap_device *od; | 358 | struct omap_device *od; |
@@ -378,7 +408,13 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id, | |||
378 | od->pm_lats = pm_lats; | 408 | od->pm_lats = pm_lats; |
379 | od->pm_lats_cnt = pm_lats_cnt; | 409 | od->pm_lats_cnt = pm_lats_cnt; |
380 | 410 | ||
381 | ret = omap_device_register(od); | 411 | od->magic = OMAP_DEVICE_MAGIC; |
412 | |||
413 | if (is_early_device) | ||
414 | ret = omap_early_device_register(od); | ||
415 | else | ||
416 | ret = omap_device_register(od); | ||
417 | |||
382 | if (ret) | 418 | if (ret) |
383 | goto odbs_exit4; | 419 | goto odbs_exit4; |
384 | 420 | ||
@@ -399,6 +435,24 @@ odbs_exit1: | |||
399 | } | 435 | } |
400 | 436 | ||
401 | /** | 437 | /** |
438 | * omap_early_device_register - register an omap_device as an early platform | ||
439 | * device. | ||
440 | * @od: struct omap_device * to register | ||
441 | * | ||
442 | * Register the omap_device structure. This currently just calls | ||
443 | * platform_early_add_device() on the underlying platform_device. | ||
444 | * Returns 0 by default. | ||
445 | */ | ||
446 | int omap_early_device_register(struct omap_device *od) | ||
447 | { | ||
448 | struct platform_device *devices[1]; | ||
449 | |||
450 | devices[0] = &(od->pdev); | ||
451 | early_platform_add_devices(devices, 1); | ||
452 | return 0; | ||
453 | } | ||
454 | |||
455 | /** | ||
402 | * omap_device_register - register an omap_device with one omap_hwmod | 456 | * omap_device_register - register an omap_device with one omap_hwmod |
403 | * @od: struct omap_device * to register | 457 | * @od: struct omap_device * to register |
404 | * | 458 | * |
@@ -437,8 +491,8 @@ int omap_device_enable(struct platform_device *pdev) | |||
437 | od = _find_by_pdev(pdev); | 491 | od = _find_by_pdev(pdev); |
438 | 492 | ||
439 | if (od->_state == OMAP_DEVICE_STATE_ENABLED) { | 493 | if (od->_state == OMAP_DEVICE_STATE_ENABLED) { |
440 | WARN(1, "omap_device: %s.%d: omap_device_enable() called from " | 494 | WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n", |
441 | "invalid state\n", od->pdev.name, od->pdev.id); | 495 | od->pdev.name, od->pdev.id, __func__, od->_state); |
442 | return -EINVAL; | 496 | return -EINVAL; |
443 | } | 497 | } |
444 | 498 | ||
@@ -476,8 +530,8 @@ int omap_device_idle(struct platform_device *pdev) | |||
476 | od = _find_by_pdev(pdev); | 530 | od = _find_by_pdev(pdev); |
477 | 531 | ||
478 | if (od->_state != OMAP_DEVICE_STATE_ENABLED) { | 532 | if (od->_state != OMAP_DEVICE_STATE_ENABLED) { |
479 | WARN(1, "omap_device: %s.%d: omap_device_idle() called from " | 533 | WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n", |
480 | "invalid state\n", od->pdev.name, od->pdev.id); | 534 | od->pdev.name, od->pdev.id, __func__, od->_state); |
481 | return -EINVAL; | 535 | return -EINVAL; |
482 | } | 536 | } |
483 | 537 | ||
@@ -509,8 +563,8 @@ int omap_device_shutdown(struct platform_device *pdev) | |||
509 | 563 | ||
510 | if (od->_state != OMAP_DEVICE_STATE_ENABLED && | 564 | if (od->_state != OMAP_DEVICE_STATE_ENABLED && |
511 | od->_state != OMAP_DEVICE_STATE_IDLE) { | 565 | od->_state != OMAP_DEVICE_STATE_IDLE) { |
512 | WARN(1, "omap_device: %s.%d: omap_device_shutdown() called " | 566 | WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n", |
513 | "from invalid state\n", od->pdev.name, od->pdev.id); | 567 | od->pdev.name, od->pdev.id, __func__, od->_state); |
514 | return -EINVAL; | 568 | return -EINVAL; |
515 | } | 569 | } |
516 | 570 | ||
@@ -564,6 +618,18 @@ int omap_device_align_pm_lat(struct platform_device *pdev, | |||
564 | } | 618 | } |
565 | 619 | ||
566 | /** | 620 | /** |
621 | * omap_device_is_valid - Check if pointer is a valid omap_device | ||
622 | * @od: struct omap_device * | ||
623 | * | ||
624 | * Return whether struct omap_device pointer @od points to a valid | ||
625 | * omap_device. | ||
626 | */ | ||
627 | bool omap_device_is_valid(struct omap_device *od) | ||
628 | { | ||
629 | return (od && od->magic == OMAP_DEVICE_MAGIC); | ||
630 | } | ||
631 | |||
632 | /** | ||
567 | * omap_device_get_pwrdm - return the powerdomain * associated with @od | 633 | * omap_device_get_pwrdm - return the powerdomain * associated with @od |
568 | * @od: struct omap_device * | 634 | * @od: struct omap_device * |
569 | * | 635 | * |