From 0fc9f263641fc144d52e4a47ef9feed3247e285f Mon Sep 17 00:00:00 2001 From: Alexandru M Stan Date: Mon, 27 Apr 2015 16:50:04 -0700 Subject: [PATCH] stm32: spi: Fix race condition with the enabled boolean Sometimes the chipset task is slow enough that we might get messages from the AP before chipset_in_state(CHIPSET_STATE_ON) is true. This causes us to leave the spi off after our usual reset after every transaction (see chrome-os-partner:31390). This would put an end to any EC communications. Instead of relying on CHIPSET_STATE_ON we could just save the value of "enabled" before we turn it off, then use that as a condition instead. There shouldn't be a race condition on "enabled" because the only other place it gets modified is in the hooks, which can't preempt spi_init (which usually happens in the host command task). The only problem is that in case of a sysjump enabled will be 0, so CHIPSET_STATE_ON was left as a backup to handle that case. This fixup was squashed from Ied3788f83fef548dff3b01bec93d0e40101ba0f7 TEST=Resume minnie from "echo mem>/sys/power/state" a few times, note ec still works BUG=chrome-os-partner:39564, chrome-os-partner:39576 BRANCH=veyron Change-Id: I7c33243faebfd74dc33451024c1d75080babee03 Signed-off-by: Alexandru M Stan Reviewed-on: https://chromium-review.googlesource.com/267593 Reviewed-by: Douglas Anderson Reviewed-by: Randall Spangler --- chip/stm32/spi.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/chip/stm32/spi.c b/chip/stm32/spi.c index 21984618be..abb86940a4 100644 --- a/chip/stm32/spi.c +++ b/chip/stm32/spi.c @@ -617,6 +617,7 @@ DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, spi_chipset_shutdown, HOOK_PRIO_DEFAULT); static void spi_init(void) { stm32_spi_regs_t *spi = STM32_SPI1_REGS; + uint8_t was_enabled = enabled; /* Reset the SPI Peripheral to clear any existing weird states. */ /* Fix for bug chrome-os-partner:31390 */ @@ -646,8 +647,11 @@ static void spi_init(void) gpio_enable_interrupt(GPIO_SPI1_NSS); - /* If chipset is already on, prepare for transactions */ - if (chipset_in_state(CHIPSET_STATE_ON)) + /* + * If we were already enabled or chipset is already on, + * prepare for transaction + */ + if (was_enabled || chipset_in_state(CHIPSET_STATE_ON)) spi_chipset_startup(); } DECLARE_HOOK(HOOK_INIT, spi_init, HOOK_PRIO_DEFAULT);