Commit 5f4eb167 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

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: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent 60965c6a
...@@ -1123,9 +1123,6 @@ static int cec_pin_adap_enable(struct cec_adapter *adap, bool enable) ...@@ -1123,9 +1123,6 @@ static int cec_pin_adap_enable(struct cec_adapter *adap, bool enable)
struct cec_pin *pin = adap->pin; struct cec_pin *pin = adap->pin;
if (enable) { 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_read(pin);
cec_pin_to_idle(pin); cec_pin_to_idle(pin);
pin->tx_msg.len = 0; pin->tx_msg.len = 0;
...@@ -1150,7 +1147,6 @@ static int cec_pin_adap_enable(struct cec_adapter *adap, bool enable) ...@@ -1150,7 +1147,6 @@ static int cec_pin_adap_enable(struct cec_adapter *adap, bool enable)
cec_pin_to_idle(pin); cec_pin_to_idle(pin);
pin->state = CEC_ST_OFF; pin->state = CEC_ST_OFF;
pin->work_tx_status = 0; pin->work_tx_status = 0;
atomic_set(&pin->work_pin_num_events, 0);
atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_DISABLE); atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_DISABLE);
wake_up_interruptible(&pin->kthread_waitq); wake_up_interruptible(&pin->kthread_waitq);
} }
...@@ -1338,6 +1334,7 @@ struct cec_adapter *cec_pin_allocate_adapter(const struct cec_pin_ops *pin_ops, ...@@ -1338,6 +1334,7 @@ struct cec_adapter *cec_pin_allocate_adapter(const struct cec_pin_ops *pin_ops,
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
pin->ops = pin_ops; pin->ops = pin_ops;
hrtimer_init(&pin->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); hrtimer_init(&pin->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
atomic_set(&pin->work_pin_num_events, 0);
pin->timer.function = cec_pin_timer; pin->timer.function = cec_pin_timer;
init_waitqueue_head(&pin->kthread_waitq); init_waitqueue_head(&pin->kthread_waitq);
pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT; pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment