diff options
author | Hans Verkuil | 2022-05-10 13:59:48 +0200 |
---|---|---|
committer | Mauro Carvalho Chehab | 2022-05-13 11:27:47 +0200 |
commit | 5f4eb16750511125aa1a874dd8cf1682a9d6a8a7 (patch) | |
tree | e71e3acf0c948f6a9105b69d5df6c7b5eae96d6b /drivers/media | |
parent | 60965c6a1960988bcb5ad3b530ccd133af5cc85d (diff) |
media: cec-pin.c: don't zero work_pin_num_events in adap_enable
It's OK to keep the pending pin events when disabling or
enabling the 'adapter'. Zeroing this can cause a race condition
if this happens when the pin kthread is handling a pin event
and calls atomic_dec later, causing work_pin_num_events to become
negative.
Just leave pending events in the queue, they'll be read eventually.
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/cec/core/cec-pin.c | 5 |
1 files changed, 1 insertions, 4 deletions
diff --git a/drivers/media/cec/core/cec-pin.c b/drivers/media/cec/core/cec-pin.c index 4bd7be4e2edf..68353c5dc501 100644 --- a/drivers/media/cec/core/cec-pin.c +++ b/drivers/media/cec/core/cec-pin.c @@ -1123,9 +1123,6 @@ static int cec_pin_adap_enable(struct cec_adapter *adap, bool enable) struct cec_pin *pin = adap->pin; if (enable) { - atomic_set(&pin->work_pin_num_events, 0); - pin->work_pin_events_rd = pin->work_pin_events_wr = 0; - pin->work_pin_events_dropped = false; cec_pin_read(pin); cec_pin_to_idle(pin); pin->tx_msg.len = 0; @@ -1150,7 +1147,6 @@ static int cec_pin_adap_enable(struct cec_adapter *adap, bool enable) cec_pin_to_idle(pin); pin->state = CEC_ST_OFF; pin->work_tx_status = 0; - atomic_set(&pin->work_pin_num_events, 0); atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_DISABLE); wake_up_interruptible(&pin->kthread_waitq); } @@ -1338,6 +1334,7 @@ struct cec_adapter *cec_pin_allocate_adapter(const struct cec_pin_ops *pin_ops, return ERR_PTR(-ENOMEM); pin->ops = pin_ops; hrtimer_init(&pin->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + atomic_set(&pin->work_pin_num_events, 0); pin->timer.function = cec_pin_timer; init_waitqueue_head(&pin->kthread_waitq); pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT; |