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 2ed72013c2e..59043589484 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -90,6 +90,8 @@  #define IGNORE_WAKEUP_LAT		1 +#define OMAP_DEVICE_MAGIC 0xf00dcafe +  /* Private functions */  /** @@ -138,10 +140,22 @@ static int _omap_device_activate(struct omap_device *od, u8 ignore_lat)  			 "%llu nsec\n", od->pdev.name, od->pm_lat_level,  			 act_lat); -		WARN(act_lat > odpl->activate_lat, "omap_device: %s.%d: " -		     "activate step %d took longer than expected (%llu > %d)\n", -		     od->pdev.name, od->pdev.id, od->pm_lat_level, -		     act_lat, odpl->activate_lat); +		if (act_lat > odpl->activate_lat) { +			odpl->activate_lat_worst = act_lat; +			if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) { +				odpl->activate_lat = act_lat; +				pr_warning("omap_device: %s.%d: new worst case " +					   "activate latency %d: %llu\n", +					   od->pdev.name, od->pdev.id, +					   od->pm_lat_level, act_lat); +			} else +				pr_warning("omap_device: %s.%d: activate " +					   "latency %d higher than exptected. " +					   "(%llu > %d)\n", +					   od->pdev.name, od->pdev.id, +					   od->pm_lat_level, act_lat, +					   odpl->activate_lat); +		}  		od->dev_wakeup_lat -= odpl->activate_lat;  	} @@ -194,10 +208,23 @@ static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat)  			 "%llu nsec\n", od->pdev.name, od->pm_lat_level,  			 deact_lat); -		WARN(deact_lat > odpl->deactivate_lat, "omap_device: %s.%d: " -		     "deactivate step %d took longer than expected " -		     "(%llu > %d)\n", od->pdev.name, od->pdev.id, -		     od->pm_lat_level, deact_lat, odpl->deactivate_lat); +		if (deact_lat > odpl->deactivate_lat) { +			odpl->deactivate_lat_worst = deact_lat; +			if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) { +				odpl->deactivate_lat = deact_lat; +				pr_warning("omap_device: %s.%d: new worst case " +					   "deactivate latency %d: %llu\n", +					   od->pdev.name, od->pdev.id, +					   od->pm_lat_level, deact_lat); +			} else +				pr_warning("omap_device: %s.%d: deactivate " +					   "latency %d higher than exptected. " +					   "(%llu > %d)\n", +					   od->pdev.name, od->pdev.id, +					   od->pm_lat_level, deact_lat, +					   odpl->deactivate_lat); +		} +  		od->dev_wakeup_lat += odpl->activate_lat; @@ -280,6 +307,7 @@ int omap_device_fill_resources(struct omap_device *od, struct resource *res)   * @pdata_len: amount of memory pointed to by @pdata   * @pm_lats: pointer to a omap_device_pm_latency array for this device   * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats + * @is_early_device: should the device be registered as an early device or not   *   * Convenience function for building and registering a single   * 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,  				      struct omap_hwmod *oh, void *pdata,  				      int pdata_len,  				      struct omap_device_pm_latency *pm_lats, -				      int pm_lats_cnt) +				      int pm_lats_cnt, int is_early_device)  {  	struct omap_hwmod *ohs[] = { oh }; @@ -299,7 +327,8 @@ struct omap_device *omap_device_build(const char *pdev_name, int pdev_id,  		return ERR_PTR(-EINVAL);  	return omap_device_build_ss(pdev_name, pdev_id, ohs, 1, pdata, -				    pdata_len, pm_lats, pm_lats_cnt); +				    pdata_len, pm_lats, pm_lats_cnt, +				    is_early_device);  }  /** @@ -311,6 +340,7 @@ struct omap_device *omap_device_build(const char *pdev_name, int pdev_id,   * @pdata_len: amount of memory pointed to by @pdata   * @pm_lats: pointer to a omap_device_pm_latency array for this device   * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats + * @is_early_device: should the device be registered as an early device or not   *   * Convenience function for building and registering an omap_device   * 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,  					 struct omap_hwmod **ohs, int oh_cnt,  					 void *pdata, int pdata_len,  					 struct omap_device_pm_latency *pm_lats, -					 int pm_lats_cnt) +					 int pm_lats_cnt, int is_early_device)  {  	int ret = -ENOMEM;  	struct omap_device *od; @@ -378,7 +408,13 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,  	od->pm_lats = pm_lats;  	od->pm_lats_cnt = pm_lats_cnt; -	ret = omap_device_register(od); +	od->magic = OMAP_DEVICE_MAGIC; + +	if (is_early_device) +		ret = omap_early_device_register(od); +	else +		ret = omap_device_register(od); +  	if (ret)  		goto odbs_exit4; @@ -399,6 +435,24 @@ odbs_exit1:  }  /** + * omap_early_device_register - register an omap_device as an early platform + * device. + * @od: struct omap_device * to register + * + * Register the omap_device structure.  This currently just calls + * platform_early_add_device() on the underlying platform_device. + * Returns 0 by default. + */ +int omap_early_device_register(struct omap_device *od) +{ +	struct platform_device *devices[1]; + +	devices[0] = &(od->pdev); +	early_platform_add_devices(devices, 1); +	return 0; +} + +/**   * omap_device_register - register an omap_device with one omap_hwmod   * @od: struct omap_device * to register   * @@ -437,8 +491,8 @@ int omap_device_enable(struct platform_device *pdev)  	od = _find_by_pdev(pdev);  	if (od->_state == OMAP_DEVICE_STATE_ENABLED) { -		WARN(1, "omap_device: %s.%d: omap_device_enable() called from " -		     "invalid state\n", od->pdev.name, od->pdev.id); +		WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n", +		     od->pdev.name, od->pdev.id, __func__, od->_state);  		return -EINVAL;  	} @@ -476,8 +530,8 @@ int omap_device_idle(struct platform_device *pdev)  	od = _find_by_pdev(pdev);  	if (od->_state != OMAP_DEVICE_STATE_ENABLED) { -		WARN(1, "omap_device: %s.%d: omap_device_idle() called from " -		     "invalid state\n", od->pdev.name, od->pdev.id); +		WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n", +		     od->pdev.name, od->pdev.id, __func__, od->_state);  		return -EINVAL;  	} @@ -509,8 +563,8 @@ int omap_device_shutdown(struct platform_device *pdev)  	if (od->_state != OMAP_DEVICE_STATE_ENABLED &&  	    od->_state != OMAP_DEVICE_STATE_IDLE) { -		WARN(1, "omap_device: %s.%d: omap_device_shutdown() called " -		     "from invalid state\n", od->pdev.name, od->pdev.id); +		WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n", +		     od->pdev.name, od->pdev.id, __func__, od->_state);  		return -EINVAL;  	} @@ -564,6 +618,18 @@ int omap_device_align_pm_lat(struct platform_device *pdev,  }  /** + * omap_device_is_valid - Check if pointer is a valid omap_device + * @od: struct omap_device * + * + * Return whether struct omap_device pointer @od points to a valid + * omap_device. + */ +bool omap_device_is_valid(struct omap_device *od) +{ +	return (od && od->magic == OMAP_DEVICE_MAGIC); +} + +/**   * omap_device_get_pwrdm - return the powerdomain * associated with @od   * @od: struct omap_device *   *  |