summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2018-02-21 10:15:11 +0000
committerArd Biesheuvel <ard.biesheuvel@linaro.org>2018-02-21 12:08:19 +0000
commit33d1b85bae277a8a78f2ab15ab6a0d9f0c9e5d79 (patch)
treea55d16fa57924e36b85950b6306fd1d091aceacd
parent8eec3bc33ed5b1e5bd35d62fd9780f3ed4bcb5e1 (diff)
downloadedk2-platforms-33d1b85bae277a8a78f2ab15ab6a0d9f0c9e5d79.tar.xz
Silicon/Socionext/SynQuacerI2cDxe: fix TPL handling bug
Currently, SynQuacerI2cStartRequest() increases the TPL to TPL_HIGH_LEVEL while accessing the I2C controller hardware, but fails to restore the TPL to the original level if the call to SynQuacerI2cMasterStart() fails, and returns right away. Given the TPL_HIGH_LEVEL implies that interrupts are disabled, this results in a complete system hang. So instead, break out of the loop, so that the TPL restore will occur before leaving the function. Note that this will result in the bus control bits to be de-asserted in case of a failure to send the START condition, which is an appropriate cleanup action to take after SynQuacerI2cMasterStart() fails. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
-rw-r--r--Silicon/Socionext/SynQuacer/Drivers/SynQuacerI2cDxe/SynQuacerI2cDxe.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/Silicon/Socionext/SynQuacer/Drivers/SynQuacerI2cDxe/SynQuacerI2cDxe.c b/Silicon/Socionext/SynQuacer/Drivers/SynQuacerI2cDxe/SynQuacerI2cDxe.c
index 46c512a201..5e70f9d921 100644
--- a/Silicon/Socionext/SynQuacer/Drivers/SynQuacerI2cDxe/SynQuacerI2cDxe.c
+++ b/Silicon/Socionext/SynQuacer/Drivers/SynQuacerI2cDxe/SynQuacerI2cDxe.c
@@ -324,7 +324,7 @@ SynQuacerI2cStartRequest (
Status = SynQuacerI2cMasterStart (I2c, SlaveAddress, Op);
if (EFI_ERROR (Status)) {
- return Status;
+ break;
}
Status = WaitForInterrupt (I2c);
@@ -397,7 +397,7 @@ SynQuacerI2cStartRequest (
} while (BufIdx < Op->LengthInBytes);
}
- // Stop the transfer
+ // Force bus state to idle, terminating any ongoing transfer
MmioWrite8 (I2c->MmioBase + F_I2C_REG_BCR, 0);
if (!AtRuntime) {