diff options
author | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2018-02-21 10:15:11 +0000 |
---|---|---|
committer | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2018-02-21 12:08:19 +0000 |
commit | 33d1b85bae277a8a78f2ab15ab6a0d9f0c9e5d79 (patch) | |
tree | a55d16fa57924e36b85950b6306fd1d091aceacd | |
parent | 8eec3bc33ed5b1e5bd35d62fd9780f3ed4bcb5e1 (diff) | |
download | edk2-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.c | 4 |
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) { |