diff mbox

[1/2] drm/i915: Take forcewake once for the entire GMBUS transaction

Message ID 20160819164503.17845-1-chris@chris-wilson.co.uk (mailing list archive)
State New, archived
Headers show

Commit Message

Chris Wilson Aug. 19, 2016, 4:45 p.m. UTC
As we do many register reads within a very short period of time, hold
the GMBUS powerwell from start to finish.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: David Weinehall <david.weinehall@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_i2c.c | 131 +++++++++++++++++++--------------------
 1 file changed, 63 insertions(+), 68 deletions(-)

Comments

David Weinehall Aug. 22, 2016, 4:42 p.m. UTC | #1
On Fri, Aug 19, 2016 at 05:45:02PM +0100, Chris Wilson wrote:
> As we do many register reads within a very short period of time, hold
> the GMBUS powerwell from start to finish.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: David Weinehall <david.weinehall@linux.intel.com>

Looks good, works well.

Reviewed-by: David Weinehall <david.weinehall@linux.intel.com>

> ---
>  drivers/gpu/drm/i915/intel_i2c.c | 131 +++++++++++++++++++--------------------
>  1 file changed, 63 insertions(+), 68 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
> index 1f266d7df2ec..6841c41281a3 100644
> --- a/drivers/gpu/drm/i915/intel_i2c.c
> +++ b/drivers/gpu/drm/i915/intel_i2c.c
> @@ -255,67 +255,59 @@ intel_gpio_setup(struct intel_gmbus *bus, unsigned int pin)
>  	algo->data = bus;
>  }
>  
> -static int
> -gmbus_wait_hw_status(struct drm_i915_private *dev_priv,
> -		     u32 gmbus2_status,
> -		     u32 gmbus4_irq_en)
> +static int gmbus_wait(struct drm_i915_private *dev_priv, u32 status, u32 irq_en)
>  {
> -	int i;
> -	u32 gmbus2 = 0;
>  	DEFINE_WAIT(wait);
> -
> -	if (!HAS_GMBUS_IRQ(dev_priv))
> -		gmbus4_irq_en = 0;
> +	u32 gmbus2;
> +	int ret;
>  
>  	/* Important: The hw handles only the first bit, so set only one! Since
>  	 * we also need to check for NAKs besides the hw ready/idle signal, we
> -	 * need to wake up periodically and check that ourselves. */
> -	I915_WRITE(GMBUS4, gmbus4_irq_en);
> -
> -	for (i = 0; i < msecs_to_jiffies_timeout(50); i++) {
> -		prepare_to_wait(&dev_priv->gmbus_wait_queue, &wait,
> -				TASK_UNINTERRUPTIBLE);
> +	 * need to wake up periodically and check that ourselves.
> +	 */
> +	if (!HAS_GMBUS_IRQ(dev_priv))
> +		irq_en = 0;
>  
> -		gmbus2 = I915_READ_NOTRACE(GMBUS2);
> -		if (gmbus2 & (GMBUS_SATOER | gmbus2_status))
> -			break;
> +	add_wait_queue(&dev_priv->gmbus_wait_queue, &wait);
> +	I915_WRITE_FW(GMBUS4, irq_en);
>  
> -		schedule_timeout(1);
> -	}
> -	finish_wait(&dev_priv->gmbus_wait_queue, &wait);
> +	status |= GMBUS_SATOER;
> +	ret = wait_for_us((gmbus2 = I915_READ_FW(GMBUS2)) & status, 2);
> +	if (ret)
> +		ret = wait_for((gmbus2 = I915_READ_FW(GMBUS2)) & status, 50);
>  
> -	I915_WRITE(GMBUS4, 0);
> +	I915_WRITE_FW(GMBUS4, 0);
> +	remove_wait_queue(&dev_priv->gmbus_wait_queue, &wait);
>  
>  	if (gmbus2 & GMBUS_SATOER)
>  		return -ENXIO;
> -	if (gmbus2 & gmbus2_status)
> -		return 0;
> -	return -ETIMEDOUT;
> +
> +	return ret;
>  }
>  
>  static int
>  gmbus_wait_idle(struct drm_i915_private *dev_priv)
>  {
> +	DEFINE_WAIT(wait);
> +	u32 irq_enable;
>  	int ret;
>  
> -	if (!HAS_GMBUS_IRQ(dev_priv))
> -		return intel_wait_for_register(dev_priv,
> -					       GMBUS2, GMBUS_ACTIVE, 0,
> -					       10);
> -
>  	/* Important: The hw handles only the first bit, so set only one! */
> -	I915_WRITE(GMBUS4, GMBUS_IDLE_EN);
> +	irq_enable = 0;
> +	if (HAS_GMBUS_IRQ(dev_priv))
> +		irq_enable = GMBUS_IDLE_EN;
>  
> -	ret = wait_event_timeout(dev_priv->gmbus_wait_queue,
> -				 (I915_READ_NOTRACE(GMBUS2) & GMBUS_ACTIVE) == 0,
> -				 msecs_to_jiffies_timeout(10));
> +	add_wait_queue(&dev_priv->gmbus_wait_queue, &wait);
> +	I915_WRITE_FW(GMBUS4, irq_enable);
>  
> -	I915_WRITE(GMBUS4, 0);
> +	ret = intel_wait_for_register_fw(dev_priv,
> +					 GMBUS2, GMBUS_ACTIVE, 0,
> +					 10);
>  
> -	if (ret)
> -		return 0;
> -	else
> -		return -ETIMEDOUT;
> +	I915_WRITE_FW(GMBUS4, 0);
> +	remove_wait_queue(&dev_priv->gmbus_wait_queue, &wait);
> +
> +	return ret;
>  }
>  
>  static int
> @@ -323,22 +315,21 @@ gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv,
>  		      unsigned short addr, u8 *buf, unsigned int len,
>  		      u32 gmbus1_index)
>  {
> -	I915_WRITE(GMBUS1,
> -		   gmbus1_index |
> -		   GMBUS_CYCLE_WAIT |
> -		   (len << GMBUS_BYTE_COUNT_SHIFT) |
> -		   (addr << GMBUS_SLAVE_ADDR_SHIFT) |
> -		   GMBUS_SLAVE_READ | GMBUS_SW_RDY);
> +	I915_WRITE_FW(GMBUS1,
> +		      gmbus1_index |
> +		      GMBUS_CYCLE_WAIT |
> +		      (len << GMBUS_BYTE_COUNT_SHIFT) |
> +		      (addr << GMBUS_SLAVE_ADDR_SHIFT) |
> +		      GMBUS_SLAVE_READ | GMBUS_SW_RDY);
>  	while (len) {
>  		int ret;
>  		u32 val, loop = 0;
>  
> -		ret = gmbus_wait_hw_status(dev_priv, GMBUS_HW_RDY,
> -					   GMBUS_HW_RDY_EN);
> +		ret = gmbus_wait(dev_priv, GMBUS_HW_RDY, GMBUS_HW_RDY_EN);
>  		if (ret)
>  			return ret;
>  
> -		val = I915_READ(GMBUS3);
> +		val = I915_READ_FW(GMBUS3);
>  		do {
>  			*buf++ = val & 0xff;
>  			val >>= 8;
> @@ -385,12 +376,12 @@ gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv,
>  		len -= 1;
>  	}
>  
> -	I915_WRITE(GMBUS3, val);
> -	I915_WRITE(GMBUS1,
> -		   GMBUS_CYCLE_WAIT |
> -		   (chunk_size << GMBUS_BYTE_COUNT_SHIFT) |
> -		   (addr << GMBUS_SLAVE_ADDR_SHIFT) |
> -		   GMBUS_SLAVE_WRITE | GMBUS_SW_RDY);
> +	I915_WRITE_FW(GMBUS3, val);
> +	I915_WRITE_FW(GMBUS1,
> +		      GMBUS_CYCLE_WAIT |
> +		      (chunk_size << GMBUS_BYTE_COUNT_SHIFT) |
> +		      (addr << GMBUS_SLAVE_ADDR_SHIFT) |
> +		      GMBUS_SLAVE_WRITE | GMBUS_SW_RDY);
>  	while (len) {
>  		int ret;
>  
> @@ -399,10 +390,9 @@ gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv,
>  			val |= *buf++ << (8 * loop);
>  		} while (--len && ++loop < 4);
>  
> -		I915_WRITE(GMBUS3, val);
> +		I915_WRITE_FW(GMBUS3, val);
>  
> -		ret = gmbus_wait_hw_status(dev_priv, GMBUS_HW_RDY,
> -					   GMBUS_HW_RDY_EN);
> +		ret = gmbus_wait(dev_priv, GMBUS_HW_RDY, GMBUS_HW_RDY_EN);
>  		if (ret)
>  			return ret;
>  	}
> @@ -460,13 +450,13 @@ gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
>  
>  	/* GMBUS5 holds 16-bit index */
>  	if (gmbus5)
> -		I915_WRITE(GMBUS5, gmbus5);
> +		I915_WRITE_FW(GMBUS5, gmbus5);
>  
>  	ret = gmbus_xfer_read(dev_priv, &msgs[1], gmbus1_index);
>  
>  	/* Clear GMBUS5 after each index transfer */
>  	if (gmbus5)
> -		I915_WRITE(GMBUS5, 0);
> +		I915_WRITE_FW(GMBUS5, 0);
>  
>  	return ret;
>  }
> @@ -478,11 +468,15 @@ do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
>  					       struct intel_gmbus,
>  					       adapter);
>  	struct drm_i915_private *dev_priv = bus->dev_priv;
> +	const unsigned int fw =
> +		intel_uncore_forcewake_for_reg(dev_priv, GMBUS0,
> +					       FW_REG_READ | FW_REG_WRITE);
>  	int i = 0, inc, try = 0;
>  	int ret = 0;
>  
> +	intel_uncore_forcewake_get(dev_priv, fw);
>  retry:
> -	I915_WRITE(GMBUS0, bus->reg0);
> +	I915_WRITE_FW(GMBUS0, bus->reg0);
>  
>  	for (; i < num; i += inc) {
>  		inc = 1;
> @@ -496,8 +490,8 @@ retry:
>  		}
>  
>  		if (!ret)
> -			ret = gmbus_wait_hw_status(dev_priv, GMBUS_HW_WAIT_PHASE,
> -						   GMBUS_HW_WAIT_EN);
> +			ret = gmbus_wait(dev_priv,
> +					 GMBUS_HW_WAIT_PHASE, GMBUS_HW_WAIT_EN);
>  		if (ret == -ETIMEDOUT)
>  			goto timeout;
>  		else if (ret)
> @@ -508,7 +502,7 @@ retry:
>  	 * a STOP on the very first cycle. To simplify the code we
>  	 * unconditionally generate the STOP condition with an additional gmbus
>  	 * cycle. */
> -	I915_WRITE(GMBUS1, GMBUS_CYCLE_STOP | GMBUS_SW_RDY);
> +	I915_WRITE_FW(GMBUS1, GMBUS_CYCLE_STOP | GMBUS_SW_RDY);
>  
>  	/* Mark the GMBUS interface as disabled after waiting for idle.
>  	 * We will re-enable it at the start of the next xfer,
> @@ -519,7 +513,7 @@ retry:
>  			 adapter->name);
>  		ret = -ETIMEDOUT;
>  	}
> -	I915_WRITE(GMBUS0, 0);
> +	I915_WRITE_FW(GMBUS0, 0);
>  	ret = ret ?: i;
>  	goto out;
>  
> @@ -548,9 +542,9 @@ clear_err:
>  	 * of resetting the GMBUS controller and so clearing the
>  	 * BUS_ERROR raised by the slave's NAK.
>  	 */
> -	I915_WRITE(GMBUS1, GMBUS_SW_CLR_INT);
> -	I915_WRITE(GMBUS1, 0);
> -	I915_WRITE(GMBUS0, 0);
> +	I915_WRITE_FW(GMBUS1, GMBUS_SW_CLR_INT);
> +	I915_WRITE_FW(GMBUS1, 0);
> +	I915_WRITE_FW(GMBUS0, 0);
>  
>  	DRM_DEBUG_KMS("GMBUS [%s] NAK for addr: %04x %c(%d)\n",
>  			 adapter->name, msgs[i].addr,
> @@ -573,7 +567,7 @@ clear_err:
>  timeout:
>  	DRM_DEBUG_KMS("GMBUS [%s] timed out, falling back to bit banging on pin %d\n",
>  		      bus->adapter.name, bus->reg0 & 0xff);
> -	I915_WRITE(GMBUS0, 0);
> +	I915_WRITE_FW(GMBUS0, 0);
>  
>  	/*
>  	 * Hardware may not support GMBUS over these pins? Try GPIO bitbanging
> @@ -582,6 +576,7 @@ timeout:
>  	ret = -EAGAIN;
>  
>  out:
> +	intel_uncore_forcewake_put(dev_priv, fw);
>  	return ret;
>  }
>  
> -- 
> 2.9.3
>
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index 1f266d7df2ec..6841c41281a3 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -255,67 +255,59 @@  intel_gpio_setup(struct intel_gmbus *bus, unsigned int pin)
 	algo->data = bus;
 }
 
-static int
-gmbus_wait_hw_status(struct drm_i915_private *dev_priv,
-		     u32 gmbus2_status,
-		     u32 gmbus4_irq_en)
+static int gmbus_wait(struct drm_i915_private *dev_priv, u32 status, u32 irq_en)
 {
-	int i;
-	u32 gmbus2 = 0;
 	DEFINE_WAIT(wait);
-
-	if (!HAS_GMBUS_IRQ(dev_priv))
-		gmbus4_irq_en = 0;
+	u32 gmbus2;
+	int ret;
 
 	/* Important: The hw handles only the first bit, so set only one! Since
 	 * we also need to check for NAKs besides the hw ready/idle signal, we
-	 * need to wake up periodically and check that ourselves. */
-	I915_WRITE(GMBUS4, gmbus4_irq_en);
-
-	for (i = 0; i < msecs_to_jiffies_timeout(50); i++) {
-		prepare_to_wait(&dev_priv->gmbus_wait_queue, &wait,
-				TASK_UNINTERRUPTIBLE);
+	 * need to wake up periodically and check that ourselves.
+	 */
+	if (!HAS_GMBUS_IRQ(dev_priv))
+		irq_en = 0;
 
-		gmbus2 = I915_READ_NOTRACE(GMBUS2);
-		if (gmbus2 & (GMBUS_SATOER | gmbus2_status))
-			break;
+	add_wait_queue(&dev_priv->gmbus_wait_queue, &wait);
+	I915_WRITE_FW(GMBUS4, irq_en);
 
-		schedule_timeout(1);
-	}
-	finish_wait(&dev_priv->gmbus_wait_queue, &wait);
+	status |= GMBUS_SATOER;
+	ret = wait_for_us((gmbus2 = I915_READ_FW(GMBUS2)) & status, 2);
+	if (ret)
+		ret = wait_for((gmbus2 = I915_READ_FW(GMBUS2)) & status, 50);
 
-	I915_WRITE(GMBUS4, 0);
+	I915_WRITE_FW(GMBUS4, 0);
+	remove_wait_queue(&dev_priv->gmbus_wait_queue, &wait);
 
 	if (gmbus2 & GMBUS_SATOER)
 		return -ENXIO;
-	if (gmbus2 & gmbus2_status)
-		return 0;
-	return -ETIMEDOUT;
+
+	return ret;
 }
 
 static int
 gmbus_wait_idle(struct drm_i915_private *dev_priv)
 {
+	DEFINE_WAIT(wait);
+	u32 irq_enable;
 	int ret;
 
-	if (!HAS_GMBUS_IRQ(dev_priv))
-		return intel_wait_for_register(dev_priv,
-					       GMBUS2, GMBUS_ACTIVE, 0,
-					       10);
-
 	/* Important: The hw handles only the first bit, so set only one! */
-	I915_WRITE(GMBUS4, GMBUS_IDLE_EN);
+	irq_enable = 0;
+	if (HAS_GMBUS_IRQ(dev_priv))
+		irq_enable = GMBUS_IDLE_EN;
 
-	ret = wait_event_timeout(dev_priv->gmbus_wait_queue,
-				 (I915_READ_NOTRACE(GMBUS2) & GMBUS_ACTIVE) == 0,
-				 msecs_to_jiffies_timeout(10));
+	add_wait_queue(&dev_priv->gmbus_wait_queue, &wait);
+	I915_WRITE_FW(GMBUS4, irq_enable);
 
-	I915_WRITE(GMBUS4, 0);
+	ret = intel_wait_for_register_fw(dev_priv,
+					 GMBUS2, GMBUS_ACTIVE, 0,
+					 10);
 
-	if (ret)
-		return 0;
-	else
-		return -ETIMEDOUT;
+	I915_WRITE_FW(GMBUS4, 0);
+	remove_wait_queue(&dev_priv->gmbus_wait_queue, &wait);
+
+	return ret;
 }
 
 static int
@@ -323,22 +315,21 @@  gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv,
 		      unsigned short addr, u8 *buf, unsigned int len,
 		      u32 gmbus1_index)
 {
-	I915_WRITE(GMBUS1,
-		   gmbus1_index |
-		   GMBUS_CYCLE_WAIT |
-		   (len << GMBUS_BYTE_COUNT_SHIFT) |
-		   (addr << GMBUS_SLAVE_ADDR_SHIFT) |
-		   GMBUS_SLAVE_READ | GMBUS_SW_RDY);
+	I915_WRITE_FW(GMBUS1,
+		      gmbus1_index |
+		      GMBUS_CYCLE_WAIT |
+		      (len << GMBUS_BYTE_COUNT_SHIFT) |
+		      (addr << GMBUS_SLAVE_ADDR_SHIFT) |
+		      GMBUS_SLAVE_READ | GMBUS_SW_RDY);
 	while (len) {
 		int ret;
 		u32 val, loop = 0;
 
-		ret = gmbus_wait_hw_status(dev_priv, GMBUS_HW_RDY,
-					   GMBUS_HW_RDY_EN);
+		ret = gmbus_wait(dev_priv, GMBUS_HW_RDY, GMBUS_HW_RDY_EN);
 		if (ret)
 			return ret;
 
-		val = I915_READ(GMBUS3);
+		val = I915_READ_FW(GMBUS3);
 		do {
 			*buf++ = val & 0xff;
 			val >>= 8;
@@ -385,12 +376,12 @@  gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv,
 		len -= 1;
 	}
 
-	I915_WRITE(GMBUS3, val);
-	I915_WRITE(GMBUS1,
-		   GMBUS_CYCLE_WAIT |
-		   (chunk_size << GMBUS_BYTE_COUNT_SHIFT) |
-		   (addr << GMBUS_SLAVE_ADDR_SHIFT) |
-		   GMBUS_SLAVE_WRITE | GMBUS_SW_RDY);
+	I915_WRITE_FW(GMBUS3, val);
+	I915_WRITE_FW(GMBUS1,
+		      GMBUS_CYCLE_WAIT |
+		      (chunk_size << GMBUS_BYTE_COUNT_SHIFT) |
+		      (addr << GMBUS_SLAVE_ADDR_SHIFT) |
+		      GMBUS_SLAVE_WRITE | GMBUS_SW_RDY);
 	while (len) {
 		int ret;
 
@@ -399,10 +390,9 @@  gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv,
 			val |= *buf++ << (8 * loop);
 		} while (--len && ++loop < 4);
 
-		I915_WRITE(GMBUS3, val);
+		I915_WRITE_FW(GMBUS3, val);
 
-		ret = gmbus_wait_hw_status(dev_priv, GMBUS_HW_RDY,
-					   GMBUS_HW_RDY_EN);
+		ret = gmbus_wait(dev_priv, GMBUS_HW_RDY, GMBUS_HW_RDY_EN);
 		if (ret)
 			return ret;
 	}
@@ -460,13 +450,13 @@  gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
 
 	/* GMBUS5 holds 16-bit index */
 	if (gmbus5)
-		I915_WRITE(GMBUS5, gmbus5);
+		I915_WRITE_FW(GMBUS5, gmbus5);
 
 	ret = gmbus_xfer_read(dev_priv, &msgs[1], gmbus1_index);
 
 	/* Clear GMBUS5 after each index transfer */
 	if (gmbus5)
-		I915_WRITE(GMBUS5, 0);
+		I915_WRITE_FW(GMBUS5, 0);
 
 	return ret;
 }
@@ -478,11 +468,15 @@  do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
 					       struct intel_gmbus,
 					       adapter);
 	struct drm_i915_private *dev_priv = bus->dev_priv;
+	const unsigned int fw =
+		intel_uncore_forcewake_for_reg(dev_priv, GMBUS0,
+					       FW_REG_READ | FW_REG_WRITE);
 	int i = 0, inc, try = 0;
 	int ret = 0;
 
+	intel_uncore_forcewake_get(dev_priv, fw);
 retry:
-	I915_WRITE(GMBUS0, bus->reg0);
+	I915_WRITE_FW(GMBUS0, bus->reg0);
 
 	for (; i < num; i += inc) {
 		inc = 1;
@@ -496,8 +490,8 @@  retry:
 		}
 
 		if (!ret)
-			ret = gmbus_wait_hw_status(dev_priv, GMBUS_HW_WAIT_PHASE,
-						   GMBUS_HW_WAIT_EN);
+			ret = gmbus_wait(dev_priv,
+					 GMBUS_HW_WAIT_PHASE, GMBUS_HW_WAIT_EN);
 		if (ret == -ETIMEDOUT)
 			goto timeout;
 		else if (ret)
@@ -508,7 +502,7 @@  retry:
 	 * a STOP on the very first cycle. To simplify the code we
 	 * unconditionally generate the STOP condition with an additional gmbus
 	 * cycle. */
-	I915_WRITE(GMBUS1, GMBUS_CYCLE_STOP | GMBUS_SW_RDY);
+	I915_WRITE_FW(GMBUS1, GMBUS_CYCLE_STOP | GMBUS_SW_RDY);
 
 	/* Mark the GMBUS interface as disabled after waiting for idle.
 	 * We will re-enable it at the start of the next xfer,
@@ -519,7 +513,7 @@  retry:
 			 adapter->name);
 		ret = -ETIMEDOUT;
 	}
-	I915_WRITE(GMBUS0, 0);
+	I915_WRITE_FW(GMBUS0, 0);
 	ret = ret ?: i;
 	goto out;
 
@@ -548,9 +542,9 @@  clear_err:
 	 * of resetting the GMBUS controller and so clearing the
 	 * BUS_ERROR raised by the slave's NAK.
 	 */
-	I915_WRITE(GMBUS1, GMBUS_SW_CLR_INT);
-	I915_WRITE(GMBUS1, 0);
-	I915_WRITE(GMBUS0, 0);
+	I915_WRITE_FW(GMBUS1, GMBUS_SW_CLR_INT);
+	I915_WRITE_FW(GMBUS1, 0);
+	I915_WRITE_FW(GMBUS0, 0);
 
 	DRM_DEBUG_KMS("GMBUS [%s] NAK for addr: %04x %c(%d)\n",
 			 adapter->name, msgs[i].addr,
@@ -573,7 +567,7 @@  clear_err:
 timeout:
 	DRM_DEBUG_KMS("GMBUS [%s] timed out, falling back to bit banging on pin %d\n",
 		      bus->adapter.name, bus->reg0 & 0xff);
-	I915_WRITE(GMBUS0, 0);
+	I915_WRITE_FW(GMBUS0, 0);
 
 	/*
 	 * Hardware may not support GMBUS over these pins? Try GPIO bitbanging
@@ -582,6 +576,7 @@  timeout:
 	ret = -EAGAIN;
 
 out:
+	intel_uncore_forcewake_put(dev_priv, fw);
 	return ret;
 }