diff options
author | Shawn Nematbakhsh <shawnn@chromium.org> | 2016-07-29 16:42:08 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-08-02 14:29:27 -0700 |
commit | 25f19f5bbd1f557d73c64079de9cd242b8e1f6ed (patch) | |
tree | 96b08d7d663aab42a77a2c85aee46db3b7be639c /chip | |
parent | c88b86852b1033e7623630554eb8ee0f4647b091 (diff) | |
download | chrome-ec-25f19f5bbd1f557d73c64079de9cd242b8e1f6ed.tar.gz |
shi: Enable SHI interrupt from CS interrupt
Enable the SHI interrupt only after we have received and begun
processing our host command. Disable the SHI interrupt once our
transaction is complete (with either success or error status). This will
prevent the SHI interrupt from being asserted at the same time as the CS
interrupt, which can lead to the SHI interrupt being serviced first.
Also, it avoids needless, non-useful SHI interrupts during error
transactions.
BUG=chrome-os-partner:55710,chrome-os-partner:55795
BRANCH=None
TEST=Manual on gru. Stress test flashrom w/ unpowered Donette attached
(for host command spam), verify no errors encountered after 100 minutes.
Change-Id: I0ab20b0202ebcfe15c04b272ec67001a6a358dad
Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/364698
Commit-Ready: Shawn N <shawnn@chromium.org>
Tested-by: Shawn N <shawnn@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Reviewed-by: Mulin Chao <mlchao@nuvoton.com>
Diffstat (limited to 'chip')
-rw-r--r-- | chip/npcx/shi.c | 47 |
1 files changed, 27 insertions, 20 deletions
diff --git a/chip/npcx/shi.c b/chip/npcx/shi.c index 416ebc3902..7e3f8486f2 100644 --- a/chip/npcx/shi.c +++ b/chip/npcx/shi.c @@ -195,13 +195,15 @@ static uint8_t shi_read_buf_pointer(void); */ static void shi_send_response_packet(struct host_packet *pkt) { + /* + * Disable interrupts. This routine is not called from interrupt + * context and buffer underrun will likely occur if it is + * preempted after writing its initial reply byte. Also, we must be + * sure our state doesn't unexpectedly change, in case we're expected + * to take RESP_NOT_RDY actions. + */ + interrupt_disable(); if (state == SHI_STATE_PROCESSING) { - /* - * Disable interrupts. This routine is not called from interrupt - * context and buffer underrun will likely occur if it is - * preempted after writing its initial reply byte. - */ - interrupt_disable(); /* Append our past-end byte, which we reserved space for. */ ((uint8_t *) pkt->response)[pkt->response_size + 0] = @@ -226,8 +228,6 @@ static void shi_send_response_packet(struct host_packet *pkt) #ifdef NPCX_SHI_BYPASS_OVER_256B } #endif - - interrupt_enable(); } /* * If we're not processing, then the AP has already terminated the @@ -239,6 +239,8 @@ static void shi_send_response_packet(struct host_packet *pkt) DEBUG_CPRINTF("END\n"); } else DEBUG_CPRINTS("Unexpected state %d in response handler", state); + + interrupt_enable(); } void shi_handle_host_package(void) @@ -293,9 +295,6 @@ void shi_handle_host_package(void) /* Parse header for version of spi-protocol */ static void shi_parse_header(void) { - /* Disable SHI interrupt until we're sure the size of request package.*/ - task_disable_irq(NPCX_IRQ_SHI); - /* We're now inside a transaction */ state = SHI_STATE_RECEIVING; DEBUG_CPRINTF("RV-"); @@ -330,9 +329,6 @@ static void shi_parse_header(void) /* Computing total bytes need to receive */ shi_params.sz_request = pkt_size; - /* Enable SHI interrupt & handle request package */ - task_enable_irq(NPCX_IRQ_SHI); - shi_handle_host_package(); } else { /* Invalid version number */ @@ -501,12 +497,6 @@ static void shi_bad_received_data(void) CPRINTF("%02x ", in_msg[i]); CPRINTF("]\n"); - /* - * Enable SHI interrupt again since we disable it - * at the begin of SHI_STATE_RECEIVING state - */ - task_enable_irq(NPCX_IRQ_SHI); - /* Reset shi's state machine for error recovery */ shi_reset_prepare(); @@ -559,6 +549,14 @@ void shi_int_handler(void) shi_fill_out_status(EC_SPI_NOT_READY); state = SHI_STATE_CNL_RESP_NOT_RDY; + + /* + * Disable SHI interrupt, it will remain disabled + * until shi_send_response_packet() is called and + * CS is asserted for a new transaction. + */ + task_disable_irq(NPCX_IRQ_SHI); + DEBUG_CPRINTF("CNL-"); return; /* Next transaction but we're not ready */ @@ -688,6 +686,12 @@ void shi_cs_event(enum gpio_signal signal) DEBUG_CPRINTF("CSL-"); + /* + * Enable SHI interrupt - we will either succeed to parse our host + * command or reset on failure from here. + */ + task_enable_irq(NPCX_IRQ_SHI); + /* Read first three bytes to parse which protocol is receiving */ shi_parse_header(); } @@ -703,6 +707,9 @@ static void shi_reset_prepare(void) { uint16_t i; + /* We no longer care about SHI interrupts, so disable them. */ + task_disable_irq(NPCX_IRQ_SHI); + /* Initialize parameters of next transaction */ shi_params.rx_msg = in_msg; shi_params.tx_msg = out_msg; |