summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Chung <nickchung@google.com>2023-02-21 15:48:12 +0800
committerHolmes Chou <holmeschou@google.com>2023-03-06 06:44:39 +0000
commit1542c4d7d38b46862dafbd99a9ab187b8b0d2149 (patch)
treeb648c70a5b72f05a00415904bd23104284fe6de9
parent10e32731ad6a4eb6f2022e976a328adfbd80ae88 (diff)
downloadlwis-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.c12
-rw-r--r--lwis_interrupt.c11
-rw-r--r--lwis_transaction.c3
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)) {