diff mbox

[GIT,PULL] for testing: OMAP hwmod driver conversions: watchdog, UART, i2c

Message ID alpine.DEB.2.00.1010042359170.13816@utopia.booyaka.com (mailing list archive)
State New, archived
Delegated to: Paul Walmsley
Headers show

Commit Message

Paul Walmsley Oct. 5, 2010, 6:01 a.m. UTC
None
diff mbox

Patch

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 955861a..fbcfe14 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1204,6 +1204,9 @@  int _omap_hwmod_enable(struct omap_hwmod *oh)
 
 	r = _wait_target_ready(oh);
 	if (!r) {
+		if (oh->enable_delay)
+			udelay(oh->enable_delay);
+
 		oh->_state = _HWMOD_STATE_ENABLED;
 
 		/* Access the sysconfig only if the target is ready */
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index c1835af..5a1e058 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -434,6 +434,7 @@  struct omap_hwmod_class {
  * @main_clk: main clock: OMAP clock name
  * @_clk: pointer to the main struct clk (filled in at runtime)
  * @opt_clks: other device clocks that drivers can request (0..*)
+ * @enable_delay: number of microseconds to wait after IdleReq is deasserted
  * @masters: ptr to array of OCP ifs that this hwmod can initiate on
  * @slaves: ptr to array of OCP ifs that this hwmod can respond on
  * @dev_attr: arbitrary device attributes that can be passed to the driver
@@ -460,8 +461,35 @@  struct omap_hwmod_class {
  * accesses to complete."  Modules may not have a main clock if the
  * interface clock also serves as a main clock.
  *
- * Parameter names beginning with an underscore are managed internally by
- * the omap_hwmod code and should not be set during initialization.
+ * On OMAP SoCs prior to OMAP4, some hwmods may require a non-zero
+ * @enable_delay value.  A hwmod needs a non-zero @enable_delay if an
+ * imprecise external abort occurs while the hwmod is being enabled.
+ * This can happen if the hwmod takes a significant time to become
+ * ready for OCP transactions after the PRCM deasserts IdleAck to the
+ * module.  @enable_delay specifies the number of microseconds for the
+ * hwmod code to udelay() between the time that the PRCM deasserts the
+ * IdleAck, and the time when the module is ready to handle register
+ * reads/writes.  Most hwmods shouldn't need anything here and can
+ * leave @enable_delay blank.  For hwmods that do need a value here,
+ * to estimate the required value, the best thing to do is to set the
+ * IP block to run at the slowest interface and functional clock rates
+ * and the lowest voltages.  First, try out a small value, say, 10
+ * microseconds, and keep increasing it until the kernel no longer
+ * crashes.  Then add a safety margin to the value that you arrived at
+ * -- say, 50% -- and specify the value in the structure record
+ * initializer for @enable_delay as (value + safety_margin).  Try not
+ * to overestimate this number; if @enable_delay is too large, then
+ * energy will be wasted and the CPU will spin for an unnecessarily
+ * long time while enabling the device.  If @enable_delay is too
+ * small, the device will trigger an abort.  More information is
+ * available here:
+ * http://www.mail-archive.com/linux-omap@vger.kernel.org/msg36300.html
+ * XXX @enable_value will need to be taken into consideration by the
+ * omap_device code to determine whether the device's current wakeup
+ * latency constraint can be satisfied if the module is placed into idle.
+ *
+ * Parameter names beginning with an underscore are managed internally
+ * by the omap_hwmod code and should not be set during initialization.
  */
 struct omap_hwmod {
 	const char			*name;
@@ -484,6 +512,7 @@  struct omap_hwmod {
 	void __iomem			*_mpu_rt_va;
 	struct mutex			_mutex;
 	struct list_head		node;
+	u16				enable_delay;
 	u16				flags;
 	u8				_mpu_port_index;
 	u8				msuspendmux_reg_id;