diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/intel_i2c.c | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index f02e52aca746..9707868881ec 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c | |||
@@ -324,26 +324,47 @@ gmbus_xfer(struct i2c_adapter *adapter, | |||
324 | goto clear_err; | 324 | goto clear_err; |
325 | } | 325 | } |
326 | 326 | ||
327 | goto done; | 327 | /* Mark the GMBUS interface as disabled after waiting for idle. |
328 | * We will re-enable it at the start of the next xfer, | ||
329 | * till then let it sleep. | ||
330 | */ | ||
331 | if (wait_for((I915_READ(GMBUS2 + reg_offset) & GMBUS_ACTIVE) == 0, 10)) | ||
332 | DRM_INFO("GMBUS [%s] timed out waiting for idle\n", | ||
333 | adapter->name); | ||
334 | I915_WRITE(GMBUS0 + reg_offset, 0); | ||
335 | ret = i; | ||
336 | goto out; | ||
328 | 337 | ||
329 | clear_err: | 338 | clear_err: |
339 | /* | ||
340 | * Wait for bus to IDLE before clearing NAK. | ||
341 | * If we clear the NAK while bus is still active, then it will stay | ||
342 | * active and the next transaction may fail. | ||
343 | */ | ||
344 | if (wait_for((I915_READ(GMBUS2 + reg_offset) & GMBUS_ACTIVE) == 0, | ||
345 | 10)) | ||
346 | DRM_INFO("GMBUS [%s] timed out after NAK\n", adapter->name); | ||
347 | |||
330 | /* Toggle the Software Clear Interrupt bit. This has the effect | 348 | /* Toggle the Software Clear Interrupt bit. This has the effect |
331 | * of resetting the GMBUS controller and so clearing the | 349 | * of resetting the GMBUS controller and so clearing the |
332 | * BUS_ERROR raised by the slave's NAK. | 350 | * BUS_ERROR raised by the slave's NAK. |
333 | */ | 351 | */ |
334 | I915_WRITE(GMBUS1 + reg_offset, GMBUS_SW_CLR_INT); | 352 | I915_WRITE(GMBUS1 + reg_offset, GMBUS_SW_CLR_INT); |
335 | I915_WRITE(GMBUS1 + reg_offset, 0); | 353 | I915_WRITE(GMBUS1 + reg_offset, 0); |
354 | I915_WRITE(GMBUS0 + reg_offset, 0); | ||
336 | 355 | ||
337 | done: | 356 | DRM_DEBUG_DRIVER("GMBUS [%s] NAK for addr: %04x %c(%d)\n", |
338 | /* Mark the GMBUS interface as disabled after waiting for idle. | 357 | adapter->name, msgs[i].addr, |
339 | * We will re-enable it at the start of the next xfer, | 358 | (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len); |
340 | * till then let it sleep. | 359 | |
360 | /* | ||
361 | * If no ACK is received during the address phase of a transaction, | ||
362 | * the adapter must report -ENXIO. | ||
363 | * It is not clear what to return if no ACK is received at other times. | ||
364 | * So, we always return -ENXIO in all NAK cases, to ensure we send | ||
365 | * it at least during the one case that is specified. | ||
341 | */ | 366 | */ |
342 | if (wait_for((I915_READ(GMBUS2 + reg_offset) & GMBUS_ACTIVE) == 0, 10)) | 367 | ret = -ENXIO; |
343 | DRM_INFO("GMBUS [%s] timed out waiting for idle\n", | ||
344 | bus->adapter.name); | ||
345 | I915_WRITE(GMBUS0 + reg_offset, 0); | ||
346 | ret = i; | ||
347 | goto out; | 368 | goto out; |
348 | 369 | ||
349 | timeout: | 370 | timeout: |