* Fix OMAP4 HDMI CEC interrupt handling and a possible buffer overflow
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJaS3sIAAoJEPo9qoy8lh71O0cP/RvA2BQeBwWXsNIdH5rkCTxg
 UHDbPlexBYPnXN5CakP1x038aFC1fUJrikAaStjGsrCpkdaKfCT4F3p0fVYo0Qfh
 FNENQOngNJLoFf2M1t9vQIH72BZaYVTb+pKSOHcp6fCX3cABmAVyBos3wjky9YIr
 fe8L813dwswHUIAHqmS46yR/7FHRdQ0FrN0CTThXSkzL7+pv3rrL9QwUF7osQX9O
 ubEehhYd4vj7XxsPylPoP6xhjw01IXghA38v5nEMAdk+XFJl/1wsGZ8r07YuDsJO
 J8t28j05g3krcTV4XCLMFwkJblGwVIEstaM7j8XxiEcuwdVizvTQXkeaFmMAUQM9
 IWTJrLCfH9Aet8LylpfPirdIfkliGlNFfdh0EyUH48lU4hRjIYgoYmknWDOTQNbz
 jthF9+vRXJPxKUUKwWzYqDsidKA8DI/Ura+ljjSRxNqLMoCBqKg4SPL0QgzC+EtX
 odPeovdgYUC8P0Bm8YLyvme+ROcB+TYQwBuzCw7eZH0buDxhMDHYVH6Kpasl+DGc
 ieNuUeluB0zAfzXnq8KCvdyr4ZnJGcaW4Zw1HJRDGmtzS3YTI/c2HQOEUAAOG+hr
 klGhbRUPcQlNH334vHd6qPppDLZgBOfDDTzjvt2OiUs50HKr2NAY9JsdI4E0fumH
 g98cNJ3JujFTXJEH2+cr
 =DI2v
 -----END PGP SIGNATURE-----

Merge tag 'omapdrm-4.15-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux into drm-fixes

omapdrm fixes for 4.15

* Fix OMAP4 HDMI CEC interrupt handling and a possible buffer overflow

* tag 'omapdrm-4.15-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux:
  omapdrm/dss/hdmi4_cec: fix interrupt handling
This commit is contained in:
Dave Airlie 2018-01-05 09:23:35 +10:00
Родитель 30a7acd573 df29c9db8a
Коммит 041ea47833
1 изменённых файлов: 9 добавлений и 37 удалений

Просмотреть файл

@ -78,6 +78,8 @@ static void hdmi_cec_received_msg(struct hdmi_core_data *core)
/* then read the message */
msg.len = cnt & 0xf;
if (msg.len > CEC_MAX_MSG_SIZE - 2)
msg.len = CEC_MAX_MSG_SIZE - 2;
msg.msg[0] = hdmi_read_reg(core->base,
HDMI_CEC_RX_CMD_HEADER);
msg.msg[1] = hdmi_read_reg(core->base,
@ -104,26 +106,6 @@ static void hdmi_cec_received_msg(struct hdmi_core_data *core)
}
}
static void hdmi_cec_transmit_fifo_empty(struct hdmi_core_data *core, u32 stat1)
{
if (stat1 & 2) {
u32 dbg3 = hdmi_read_reg(core->base, HDMI_CEC_DBG_3);
cec_transmit_done(core->adap,
CEC_TX_STATUS_NACK |
CEC_TX_STATUS_MAX_RETRIES,
0, (dbg3 >> 4) & 7, 0, 0);
} else if (stat1 & 1) {
cec_transmit_done(core->adap,
CEC_TX_STATUS_ARB_LOST |
CEC_TX_STATUS_MAX_RETRIES,
0, 0, 0, 0);
} else if (stat1 == 0) {
cec_transmit_done(core->adap, CEC_TX_STATUS_OK,
0, 0, 0, 0);
}
}
void hdmi4_cec_irq(struct hdmi_core_data *core)
{
u32 stat0 = hdmi_read_reg(core->base, HDMI_CEC_INT_STATUS_0);
@ -132,27 +114,21 @@ void hdmi4_cec_irq(struct hdmi_core_data *core)
hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_0, stat0);
hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_1, stat1);
if (stat0 & 0x40)
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 (stat0 & 0x24)
hdmi_cec_transmit_fifo_empty(core, stat1);
if (stat1 & 2) {
} else if (stat1 & 0x02) {
u32 dbg3 = hdmi_read_reg(core->base, HDMI_CEC_DBG_3);
cec_transmit_done(core->adap,
CEC_TX_STATUS_NACK |
CEC_TX_STATUS_MAX_RETRIES,
0, (dbg3 >> 4) & 7, 0, 0);
} else if (stat1 & 1) {
cec_transmit_done(core->adap,
CEC_TX_STATUS_ARB_LOST |
CEC_TX_STATUS_MAX_RETRIES,
0, 0, 0, 0);
REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, 0x1, 7, 7);
}
if (stat0 & 0x02)
hdmi_cec_received_msg(core);
if (stat1 & 0x3)
REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, 0x1, 7, 7);
}
static bool hdmi_cec_clear_tx_fifo(struct cec_adapter *adap)
@ -231,18 +207,14 @@ static int hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable)
/*
* Enable CEC interrupts:
* Transmit Buffer Full/Empty Change event
* Transmitter FIFO Empty event
* Receiver FIFO Not Empty event
*/
hdmi_write_reg(core->base, HDMI_CEC_INT_ENABLE_0, 0x26);
hdmi_write_reg(core->base, HDMI_CEC_INT_ENABLE_0, 0x22);
/*
* Enable CEC interrupts:
* RX FIFO Overrun Error event
* Short Pulse Detected event
* Frame Retransmit Count Exceeded event
* Start Bit Irregularity event
*/
hdmi_write_reg(core->base, HDMI_CEC_INT_ENABLE_1, 0x0f);
hdmi_write_reg(core->base, HDMI_CEC_INT_ENABLE_1, 0x02);
/* cec calibration enable (self clearing) */
hdmi_write_reg(core->base, HDMI_CEC_SETUP, 0x03);