aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap/omap_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-omap/omap_device.c')
-rw-r--r--arch/arm/plat-omap/omap_device.c102
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 */
446int 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 */
627bool 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 *