mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
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>
This commit is contained in:
parent
0c138a5d50
commit
67d9598720
|
|
@ -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],
|
||||
|
|
|
|||
|
|
@ -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],
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user