diff options
| author | Hans Verkuil <hverkuil+cisco@kernel.org> | 2026-07-10 13:07:35 +0200 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab+huawei@kernel.org> | 2026-07-17 10:14:16 +0200 |
| commit | cefce07c6ca56c826e046feaa70b82a0d708bc71 (patch) | |
| tree | 93a1ac84232f758d1d3dbaecdddd7c98a66af280 | |
| parent | cba172820898140dc1fd4c2223ddf3ded978d2b2 (diff) | |
media: cec/core: cec-pin: toggle rx_toggle when arb lost
If we inject an Arbitration Lost error, then manually toggle rx_toggle
instead of waiting for cec_pin_to_idle(). When handling the Arbitration
Lost error injection we are switching to TX mode, and as a result when
cec_pin_to_idle() is called when the transmit ends it would never toggle
rx_toggle since it is no longer in RX mode.
Without this change the 'any,toggle rx-arb-lost' error injection
would, once it is on, always stay on.
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-pin.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/media/cec/core/cec-pin.c b/drivers/media/cec/core/cec-pin.c index 085fc12067af..6a0ee32e8401 100644 --- a/drivers/media/cec/core/cec-pin.c +++ b/drivers/media/cec/core/cec-pin.c @@ -692,7 +692,6 @@ static void cec_pin_rx_states(struct cec_pin *pin, ktime_t ts) v = cec_pin_read(pin); if (!v) break; - pin->state = CEC_ST_RX_START_BIT_HIGH; delta = ktime_us_delta(ts, pin->ts); /* Start bit low is too short, go back to idle */ if (delta < CEC_TIM_START_BIT_LOW_MIN - CEC_TIM_IDLE_SAMPLE) { @@ -703,7 +702,16 @@ static void cec_pin_rx_states(struct cec_pin *pin, ktime_t ts) cec_pin_to_idle(pin); break; } + pin->state = CEC_ST_RX_START_BIT_HIGH; if (rx_arb_lost(pin, &poll)) { + /* + * Normally rx_toggle is toggled in cec_pin_to_idle() + * when we're in an RX state, but here we switch to TX + * mode, so cec_pin_to_idle() sees a TX mode and never + * toggles rx_toggle. So toggle it here as a special + * corner case. + */ + pin->rx_toggle ^= 1; cec_msg_init(&pin->tx_msg, poll >> 4, poll & 0xf); pin->tx_generated_poll = true; pin->tx_extra_bytes = 0; |
