diff options
| author | Hans Verkuil <hverkuil+cisco@kernel.org> | 2026-07-10 13:07:31 +0200 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab+huawei@kernel.org> | 2026-07-17 10:14:03 +0200 |
| commit | 67d95987201591a91067a3e49ebef265fd968df6 (patch) | |
| tree | 98c549139d85f03450d1c505d4ba999c36ee6e45 | |
| parent | 0c138a5d5045f06618ff581f7a65f3149c033902 (diff) | |
| download | linux-67d95987201591a91067a3e49ebef265fd968df6.tar.gz linux-67d95987201591a91067a3e49ebef265fd968df6.zip | |
media: cec/core: handle core events like normal events
Currently there is a distinction between core events
(CEC_EVENT_STATE_CHANGE and CEC_EVENT_LOST_MSGS) and other
events. The core events do not require memory allocations,
so are a bit faster, but they are also limited to just a
single event: if a new event comes in, then that replaces
the old one.
It's all overly complicated, and with only one state change
event it is easy to miss state changes.
So just drop that optimization, and allow for up to 3
state change events.
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.c | 34 | ||||
| -rw-r--r-- | drivers/media/cec/core/cec-api.c | 5 | ||||
| -rw-r--r-- | include/media/cec.h | 2 |
3 files changed, 18 insertions, 23 deletions
diff --git a/drivers/media/cec/core/cec-adap.c b/drivers/media/cec/core/cec-adap.c index 0c2f4660a7bd..bbd5395fa67d 100644 --- a/drivers/media/cec/core/cec-adap.c +++ b/drivers/media/cec/core/cec-adap.c @@ -80,9 +80,9 @@ void cec_queue_event_fh(struct cec_fh *fh, const struct cec_event *new_ev, u64 ts) { static const u16 max_events[CEC_NUM_EVENTS] = { - 1, 1, 800, 800, 8, 8, 8, 8 + 3, 1, 800, 800, 8, 8, 8, 8 }; - struct cec_event_entry *entry; + struct cec_event_entry *new_entry, *entry; unsigned int ev_idx = new_ev->event - 1; if (WARN_ON(ev_idx >= ARRAY_SIZE(fh->events))) @@ -92,36 +92,34 @@ void cec_queue_event_fh(struct cec_fh *fh, ts = ktime_get_ns(); mutex_lock(&fh->lock); - if (ev_idx < CEC_NUM_CORE_EVENTS) - entry = &fh->core_events[ev_idx]; - else - entry = kmalloc_obj(*entry); - if (entry) { + new_entry = kmalloc_obj(*new_entry); + if (new_entry) { if (new_ev->event == CEC_EVENT_LOST_MSGS && fh->queued_events[ev_idx]) { + entry = list_first_entry(&fh->events[ev_idx], + struct cec_event_entry, list); entry->ev.lost_msgs.lost_msgs += new_ev->lost_msgs.lost_msgs; + kfree(new_entry); goto unlock; } - entry->ev = *new_ev; - entry->ev.ts = ts; + new_entry->ev = *new_ev; + new_entry->ev.ts = ts; if (fh->queued_events[ev_idx] < max_events[ev_idx]) { /* Add new msg at the end of the queue */ - list_add_tail(&entry->list, &fh->events[ev_idx]); + list_add_tail(&new_entry->list, &fh->events[ev_idx]); fh->queued_events[ev_idx]++; fh->total_queued_events++; goto unlock; } - if (ev_idx >= CEC_NUM_CORE_EVENTS) { - list_add_tail(&entry->list, &fh->events[ev_idx]); - /* drop the oldest event */ - entry = list_first_entry(&fh->events[ev_idx], - struct cec_event_entry, list); - list_del(&entry->list); - kfree(entry); - } + list_add_tail(&new_entry->list, &fh->events[ev_idx]); + /* drop the oldest event */ + entry = list_first_entry(&fh->events[ev_idx], + struct cec_event_entry, list); + list_del(&entry->list); + kfree(entry); } /* Mark that events were lost */ entry = list_first_entry_or_null(&fh->events[ev_idx], diff --git a/drivers/media/cec/core/cec-api.c b/drivers/media/cec/core/cec-api.c index 103ded79526f..a491d7fc8a71 100644 --- a/drivers/media/cec/core/cec-api.c +++ b/drivers/media/cec/core/cec-api.c @@ -345,8 +345,7 @@ static long cec_dqevent(struct cec_adapter *adap, struct cec_fh *fh, if (copy_to_user(parg, &ev->ev, sizeof(ev->ev))) err = -EFAULT; - if (ev_idx >= CEC_NUM_CORE_EVENTS) - kfree(ev); + kfree(ev); fh->queued_events[ev_idx]--; fh->total_queued_events--; @@ -673,7 +672,7 @@ static int cec_release(struct inode *inode, struct file *filp) list_del(&entry->list); kfree(entry); } - for (i = CEC_NUM_CORE_EVENTS; i < CEC_NUM_EVENTS; i++) { + for (i = 0; i < CEC_NUM_EVENTS; i++) { while (!list_empty(&fh->events[i])) { struct cec_event_entry *entry = list_first_entry(&fh->events[i], diff --git a/include/media/cec.h b/include/media/cec.h index 0c8e86115b6f..5aff399e69e6 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -85,7 +85,6 @@ struct cec_event_entry { struct cec_event ev; }; -#define CEC_NUM_CORE_EVENTS 2 #define CEC_NUM_EVENTS CEC_EVENT_PIN_5V_HIGH struct cec_fh { @@ -101,7 +100,6 @@ struct cec_fh { struct list_head events[CEC_NUM_EVENTS]; /* queued events */ u16 queued_events[CEC_NUM_EVENTS]; unsigned int total_queued_events; - struct cec_event_entry core_events[CEC_NUM_CORE_EVENTS]; struct list_head msgs; /* queued messages */ unsigned int queued_msgs; }; |
