diff options
-rw-r--r-- | chip/it83xx/i2c.c | 3 | ||||
-rw-r--r-- | chip/it83xx/system.c | 1 | ||||
-rw-r--r-- | core/nds32/task.c | 32 |
3 files changed, 32 insertions, 4 deletions
diff --git a/chip/it83xx/i2c.c b/chip/it83xx/i2c.c index bc10a5970f..fe516bb41f 100644 --- a/chip/it83xx/i2c.c +++ b/chip/it83xx/i2c.c @@ -410,7 +410,8 @@ int chip_i2c_xfer(int port, int slave_addr, const uint8_t *out, int out_size, } /* Start transaction */ i2c_transaction(port); - events = task_wait_event(pd->timeout_us); + /* Wait for transfer complete or timeout */ + events = task_wait_event_mask(TASK_EVENT_I2C_IDLE, pd->timeout_us); /* disable i2c interrupt */ task_disable_irq(i2c_ctrl_regs[port].irq); pd->task_waiting = TASK_ID_INVALID; diff --git a/chip/it83xx/system.c b/chip/it83xx/system.c index 6019c5f41b..90e234ce86 100644 --- a/chip/it83xx/system.c +++ b/chip/it83xx/system.c @@ -9,6 +9,7 @@ #include "cpu.h" #include "ec2i_chip.h" #include "flash.h" +#include "host_command.h" #include "registers.h" #include "system.h" #include "task.h" diff --git a/core/nds32/task.c b/core/nds32/task.c index b34e9e9f50..4be65ac913 100644 --- a/core/nds32/task.c +++ b/core/nds32/task.c @@ -450,6 +450,34 @@ uint32_t task_wait_event(int timeout_us) return __wait_evt(timeout_us, TASK_ID_IDLE); } +uint32_t task_wait_event_mask(uint32_t event_mask, int timeout_us) +{ + uint64_t deadline = get_time().val + timeout_us; + uint32_t events = 0; + int time_remaining_us = timeout_us; + + /* Add the timer event to the mask so we can indicate a timeout */ + event_mask |= TASK_EVENT_TIMER; + + while (!(events & event_mask)) { + /* Collect events to re-post later */ + events |= __wait_evt(time_remaining_us, TASK_ID_IDLE); + + time_remaining_us = deadline - get_time().val; + if (timeout_us > 0 && time_remaining_us <= 0) { + /* Ensure we return a TIMER event if we timeout */ + events |= TASK_EVENT_TIMER; + break; + } + } + + /* Re-post any other events collected */ + if (events & ~event_mask) + atomic_or(¤t_task->events, events & ~event_mask); + + return events & event_mask; +} + uint32_t get_int_mask(void) { uint32_t ret; @@ -577,9 +605,7 @@ void mutex_lock(struct mutex *mtx) /* end of critical section : re-enable interrupts */ interrupt_enable(); /* Sleep waiting for our turn */ - /* TODO(crbug.com/435612, crbug.com/435611) - * This discards any pending events! */ - task_wait_event(0); + task_wait_event_mask(TASK_EVENT_MUTEX, 0); /* re-enter critical section */ interrupt_disable(); } |