From: Hans Verkuil <hverkuil@xs4all.nl> To: linux-media@vger.kernel.org Cc: dri-devel@lists.freedesktop.org, Tomi Valkeinen <tomi.valkeinen@ti.com>, Hans Verkuil <hans.verkuil@cisco.com> Subject: [PATCH 4/5] omapdrm/dss/hdmi4_cec.c: clear TX FIFO before transmit_done Date: Thu, 4 Oct 2018 11:08:59 +0200 [thread overview] Message-ID: <20181004090900.32915-5-hverkuil@xs4all.nl> (raw) In-Reply-To: <20181004090900.32915-1-hverkuil@xs4all.nl> From: Hans Verkuil <hans.verkuil@cisco.com> The TX FIFO has to be cleared if the transmit failed due to e.g. a NACK condition, otherwise the hardware will keep trying to transmit the message. An attempt was made to do this, but it was done after the call to cec_transmit_done, which can cause a race condition since the call to cec_transmit_done can cause a new transmit to be issued, and then attempting to clear the TX FIFO will actually clear the new transmit instead of the old transmit and the new transmit simply never happens. By clearing the FIFO before transmit_done is called this race is fixed. Note that there is no reason to clear the FIFO if the transmit was successful, so the attempt to clear the FIFO in that case was dropped. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> --- drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c | 35 ++++++++++++------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c index 340383150fb9..dee66a5101b5 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c @@ -106,6 +106,22 @@ static void hdmi_cec_received_msg(struct hdmi_core_data *core) } } +static bool hdmi_cec_clear_tx_fifo(struct cec_adapter *adap) +{ + struct hdmi_core_data *core = cec_get_drvdata(adap); + int retry = HDMI_CORE_CEC_RETRY; + int temp; + + REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, 0x1, 7, 7); + while (retry) { + temp = hdmi_read_reg(core->base, HDMI_CEC_DBG_3); + if (FLD_GET(temp, 7, 7) == 0) + break; + retry--; + } + return retry != 0; +} + void hdmi4_cec_irq(struct hdmi_core_data *core) { u32 stat0 = hdmi_read_reg(core->base, HDMI_CEC_INT_STATUS_0); @@ -117,36 +133,19 @@ void hdmi4_cec_irq(struct hdmi_core_data *core) if (stat0 & 0x20) { cec_transmit_done(core->adap, CEC_TX_STATUS_OK, 0, 0, 0, 0); - REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, 0x1, 7, 7); } else if (stat1 & 0x02) { u32 dbg3 = hdmi_read_reg(core->base, HDMI_CEC_DBG_3); + hdmi_cec_clear_tx_fifo(core->adap); cec_transmit_done(core->adap, CEC_TX_STATUS_NACK | CEC_TX_STATUS_MAX_RETRIES, 0, (dbg3 >> 4) & 7, 0, 0); - REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, 0x1, 7, 7); } if (stat0 & 0x02) hdmi_cec_received_msg(core); } -static bool hdmi_cec_clear_tx_fifo(struct cec_adapter *adap) -{ - struct hdmi_core_data *core = cec_get_drvdata(adap); - int retry = HDMI_CORE_CEC_RETRY; - int temp; - - REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, 0x1, 7, 7); - while (retry) { - temp = hdmi_read_reg(core->base, HDMI_CEC_DBG_3); - if (FLD_GET(temp, 7, 7) == 0) - break; - retry--; - } - return retry != 0; -} - static bool hdmi_cec_clear_rx_fifo(struct cec_adapter *adap) { struct hdmi_core_data *core = cec_get_drvdata(adap); -- 2.18.0
WARNING: multiple messages have this Message-ID (diff)
From: Hans Verkuil <hverkuil@xs4all.nl> To: linux-media@vger.kernel.org Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>, Hans Verkuil <hans.verkuil@cisco.com>, dri-devel@lists.freedesktop.org Subject: [PATCH 4/5] omapdrm/dss/hdmi4_cec.c: clear TX FIFO before transmit_done Date: Thu, 4 Oct 2018 11:08:59 +0200 [thread overview] Message-ID: <20181004090900.32915-5-hverkuil@xs4all.nl> (raw) In-Reply-To: <20181004090900.32915-1-hverkuil@xs4all.nl> From: Hans Verkuil <hans.verkuil@cisco.com> The TX FIFO has to be cleared if the transmit failed due to e.g. a NACK condition, otherwise the hardware will keep trying to transmit the message. An attempt was made to do this, but it was done after the call to cec_transmit_done, which can cause a race condition since the call to cec_transmit_done can cause a new transmit to be issued, and then attempting to clear the TX FIFO will actually clear the new transmit instead of the old transmit and the new transmit simply never happens. By clearing the FIFO before transmit_done is called this race is fixed. Note that there is no reason to clear the FIFO if the transmit was successful, so the attempt to clear the FIFO in that case was dropped. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> --- drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c | 35 ++++++++++++------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c index 340383150fb9..dee66a5101b5 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c @@ -106,6 +106,22 @@ static void hdmi_cec_received_msg(struct hdmi_core_data *core) } } +static bool hdmi_cec_clear_tx_fifo(struct cec_adapter *adap) +{ + struct hdmi_core_data *core = cec_get_drvdata(adap); + int retry = HDMI_CORE_CEC_RETRY; + int temp; + + REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, 0x1, 7, 7); + while (retry) { + temp = hdmi_read_reg(core->base, HDMI_CEC_DBG_3); + if (FLD_GET(temp, 7, 7) == 0) + break; + retry--; + } + return retry != 0; +} + void hdmi4_cec_irq(struct hdmi_core_data *core) { u32 stat0 = hdmi_read_reg(core->base, HDMI_CEC_INT_STATUS_0); @@ -117,36 +133,19 @@ void hdmi4_cec_irq(struct hdmi_core_data *core) if (stat0 & 0x20) { cec_transmit_done(core->adap, CEC_TX_STATUS_OK, 0, 0, 0, 0); - REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, 0x1, 7, 7); } else if (stat1 & 0x02) { u32 dbg3 = hdmi_read_reg(core->base, HDMI_CEC_DBG_3); + hdmi_cec_clear_tx_fifo(core->adap); cec_transmit_done(core->adap, CEC_TX_STATUS_NACK | CEC_TX_STATUS_MAX_RETRIES, 0, (dbg3 >> 4) & 7, 0, 0); - REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, 0x1, 7, 7); } if (stat0 & 0x02) hdmi_cec_received_msg(core); } -static bool hdmi_cec_clear_tx_fifo(struct cec_adapter *adap) -{ - struct hdmi_core_data *core = cec_get_drvdata(adap); - int retry = HDMI_CORE_CEC_RETRY; - int temp; - - REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, 0x1, 7, 7); - while (retry) { - temp = hdmi_read_reg(core->base, HDMI_CEC_DBG_3); - if (FLD_GET(temp, 7, 7) == 0) - break; - retry--; - } - return retry != 0; -} - static bool hdmi_cec_clear_rx_fifo(struct cec_adapter *adap) { struct hdmi_core_data *core = cec_get_drvdata(adap); -- 2.18.0 _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
next prev parent reply other threads:[~2018-10-04 16:01 UTC|newest] Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-10-04 9:08 [PATCH 0/5] cec/adv/omap: fixes and new status flags Hans Verkuil 2018-10-04 9:08 ` Hans Verkuil 2018-10-04 9:08 ` [PATCH 1/5] cec: add new tx/rx status bits to detect aborts/timeouts Hans Verkuil 2018-10-04 9:08 ` Hans Verkuil 2018-10-04 9:08 ` [PATCH 2/5] adv7604: when the EDID is cleared, unconfigure CEC as well Hans Verkuil 2018-10-04 9:08 ` Hans Verkuil 2018-10-04 9:08 ` [PATCH 3/5] adv7842: " Hans Verkuil 2018-10-04 9:08 ` Hans Verkuil 2018-10-04 9:08 ` Hans Verkuil [this message] 2018-10-04 9:08 ` [PATCH 4/5] omapdrm/dss/hdmi4_cec.c: clear TX FIFO before transmit_done Hans Verkuil 2018-10-05 14:13 ` Hans Verkuil 2018-10-05 14:13 ` Hans Verkuil 2018-10-08 12:52 ` Tomi Valkeinen 2018-10-08 12:52 ` Tomi Valkeinen 2018-10-08 12:58 ` Hans Verkuil 2018-10-08 12:58 ` Hans Verkuil 2018-10-08 12:45 ` Tomi Valkeinen 2018-10-08 12:45 ` Tomi Valkeinen 2018-10-08 12:55 ` Hans Verkuil 2018-10-08 12:55 ` Hans Verkuil 2018-10-08 13:03 ` Tomi Valkeinen 2018-10-08 13:03 ` Tomi Valkeinen 2018-10-04 9:09 ` [PATCH 5/5] omapdrm/dss/hdmi4_cec.c: don't set the retransmit count Hans Verkuil 2018-10-04 9:09 ` Hans Verkuil 2018-10-08 12:47 ` Tomi Valkeinen 2018-10-08 12:47 ` Tomi Valkeinen 2018-10-08 13:01 ` Hans Verkuil 2018-10-08 13:01 ` Hans Verkuil
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20181004090900.32915-5-hverkuil@xs4all.nl \ --to=hverkuil@xs4all.nl \ --cc=dri-devel@lists.freedesktop.org \ --cc=hans.verkuil@cisco.com \ --cc=linux-media@vger.kernel.org \ --cc=tomi.valkeinen@ti.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.