diff options
author | Nick Chung <nickchung@google.com> | 2023-02-21 15:48:12 +0800 |
---|---|---|
committer | Holmes Chou <holmeschou@google.com> | 2023-03-06 06:44:39 +0000 |
commit | 1542c4d7d38b46862dafbd99a9ab187b8b0d2149 (patch) | |
tree | b648c70a5b72f05a00415904bd23104284fe6de9 | |
parent | 10e32731ad6a4eb6f2022e976a328adfbd80ae88 (diff) | |
download | lwis-1542c4d7d38b46862dafbd99a9ab187b8b0d2149.tar.gz |
LWIS: Handle overflow interrupts
Overflow interrupts happens:
1. Trigger transaction that is associated with {Event X, N}
2. Emit {Event X, N} to userspace
3. Count to N+1;
4. Trigger transaction that is associated with {Event X, N+1}
5. Emit {Event X + overflow flag, N+1} to userspace
6. Count to N+2;
Bug: 265082306
Test: GCA, CTS
Change-Id: I9c045fe9c2e2881635310d953f6db21c42e0ec4d
Signed-off-by: Nick Chung <nickchung@google.com>
-rw-r--r-- | lwis_event.c | 12 | ||||
-rw-r--r-- | lwis_interrupt.c | 11 | ||||
-rw-r--r-- | lwis_transaction.c | 3 |
3 files changed, 11 insertions, 15 deletions
diff --git a/lwis_event.c b/lwis_event.c index 8b15b0c..baccbd9 100644 --- a/lwis_event.c +++ b/lwis_event.c @@ -844,16 +844,8 @@ static int lwis_device_event_emit_impl(struct lwis_device *lwis_dev, int64_t eve return -EINVAL; } - /* When the event is overflow, we increase the event counter +2 - * so that userspace driver should be aware that at least - * one interrupt was lost upon receiving an event with the overflow flag. - */ - if (event_id & LWIS_OVERFLOW_IRQ_EVENT_FLAG) { - device_event_state->event_counter += 2; - } else { - device_event_state->event_counter++; - } - + /* Increment the event counter */ + device_event_state->event_counter++; /* Save event counter to local variable */ event_counter = device_event_state->event_counter; /* Latch timestamp */ diff --git a/lwis_interrupt.c b/lwis_interrupt.c index e39a0d1..08bfc14 100644 --- a/lwis_interrupt.c +++ b/lwis_interrupt.c @@ -327,12 +327,13 @@ static void lwis_interrupt_emit_events(struct lwis_interrupt *irq, uint64_t sour /* Check if this event needs to be emitted */ if ((source_value >> event->int_reg_bit) & 0x1) { - int64_t event_id; + lwis_device_event_emit(irq->lwis_dev, event->event_id, NULL, 0); /* Check if this overflow event needs to combine event id + overflow flag */ - event_id = ((overflow_value >> event->int_reg_bit) & 0x1) ? - (event->event_id | LWIS_OVERFLOW_IRQ_EVENT_FLAG) : - event->event_id; - lwis_device_event_emit(irq->lwis_dev, event_id, NULL, 0); + if ((overflow_value >> event->int_reg_bit) & 0x1) { + lwis_device_event_emit( + irq->lwis_dev, + event->event_id | LWIS_OVERFLOW_IRQ_EVENT_FLAG, NULL, 0); + } /* Clear this interrupt */ reset_value |= (1ULL << event->int_reg_bit); diff --git a/lwis_transaction.c b/lwis_transaction.c index d32a5f0..6c73101 100644 --- a/lwis_transaction.c +++ b/lwis_transaction.c @@ -872,6 +872,9 @@ int lwis_transaction_event_trigger(struct lwis_client *client, int64_t event_id, /* Find event list that matches the trigger event ID. */ spin_lock_irqsave(&client->transaction_lock, flags); + if (event_id & LWIS_OVERFLOW_IRQ_EVENT_FLAG) { + event_id = event_id ^ LWIS_OVERFLOW_IRQ_EVENT_FLAG; + } event_list = event_list_find(client, event_id); /* No event found, just return. */ if (event_list == NULL || list_empty(&event_list->list)) { |