aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil+cisco@kernel.org>2026-07-10 13:07:33 +0200
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>2026-07-17 10:14:10 +0200
commit350308a05f7dd5e03ab8d966dd672288749efb64 (patch)
tree403a8cf33bc214dce910117146db7543c5ff25e2
parentmedia: cec/core: drop cec_post_state_event call (diff)
media: cec/core: flush stale STATE_CHANGE events
If the physical address becomes invalid, then flush any old STATE_CHANGE events since those are no longer relevant. Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
-rw-r--r--drivers/media/cec/core/cec-adap.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/media/cec/core/cec-adap.c b/drivers/media/cec/core/cec-adap.c
index 5c7ede88c3df..4d14186bfef6 100644
--- a/drivers/media/cec/core/cec-adap.c
+++ b/drivers/media/cec/core/cec-adap.c
@@ -103,9 +103,32 @@ void cec_queue_event_fh(struct cec_fh *fh,
kfree(new_entry);
goto unlock;
}
+
new_entry->ev = *new_ev;
new_entry->ev.ts = ts;
+ /*
+ * If the physical address becomes invalid (HPD went low),
+ * then just flush all pending STATE_CHANGE events since
+ * those are all obsoleted.
+ *
+ * This ensures you will not see stale STATE_CHANGE events.
+ */
+ if (new_ev->event == CEC_EVENT_STATE_CHANGE &&
+ new_ev->state_change.phys_addr == CEC_PHYS_ADDR_INVALID &&
+ fh->queued_events[ev_idx]) {
+ /* drop all events */
+ while (!list_empty(&fh->events[ev_idx])) {
+ entry = list_first_entry(&fh->events[ev_idx],
+ struct cec_event_entry, list);
+ list_del(&entry->list);
+ kfree(entry);
+ fh->total_queued_events--;
+ fh->queued_events[ev_idx]--;
+ }
+ new_entry->ev.flags |= CEC_EVENT_FL_DROPPED_EVENTS;
+ }
+
if (fh->queued_events[ev_idx] < max_events[ev_idx]) {
/* Add new msg at the end of the queue */
list_add_tail(&new_entry->list, &fh->events[ev_idx]);