Skip to content

Commit 041ea47

Browse files
committed
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
2 parents 30a7acd + df29c9d commit 041ea47

File tree

1 file changed

+9
-37
lines changed

1 file changed

+9
-37
lines changed

drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c

Lines changed: 9 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ static void hdmi_cec_received_msg(struct hdmi_core_data *core)
7878

7979
/* then read the message */
8080
msg.len = cnt & 0xf;
81+
if (msg.len > CEC_MAX_MSG_SIZE - 2)
82+
msg.len = CEC_MAX_MSG_SIZE - 2;
8183
msg.msg[0] = hdmi_read_reg(core->base,
8284
HDMI_CEC_RX_CMD_HEADER);
8385
msg.msg[1] = hdmi_read_reg(core->base,
@@ -104,26 +106,6 @@ static void hdmi_cec_received_msg(struct hdmi_core_data *core)
104106
}
105107
}
106108

107-
static void hdmi_cec_transmit_fifo_empty(struct hdmi_core_data *core, u32 stat1)
108-
{
109-
if (stat1 & 2) {
110-
u32 dbg3 = hdmi_read_reg(core->base, HDMI_CEC_DBG_3);
111-
112-
cec_transmit_done(core->adap,
113-
CEC_TX_STATUS_NACK |
114-
CEC_TX_STATUS_MAX_RETRIES,
115-
0, (dbg3 >> 4) & 7, 0, 0);
116-
} else if (stat1 & 1) {
117-
cec_transmit_done(core->adap,
118-
CEC_TX_STATUS_ARB_LOST |
119-
CEC_TX_STATUS_MAX_RETRIES,
120-
0, 0, 0, 0);
121-
} else if (stat1 == 0) {
122-
cec_transmit_done(core->adap, CEC_TX_STATUS_OK,
123-
0, 0, 0, 0);
124-
}
125-
}
126-
127109
void hdmi4_cec_irq(struct hdmi_core_data *core)
128110
{
129111
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)
132114
hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_0, stat0);
133115
hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_1, stat1);
134116

135-
if (stat0 & 0x40)
117+
if (stat0 & 0x20) {
118+
cec_transmit_done(core->adap, CEC_TX_STATUS_OK,
119+
0, 0, 0, 0);
136120
REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, 0x1, 7, 7);
137-
else if (stat0 & 0x24)
138-
hdmi_cec_transmit_fifo_empty(core, stat1);
139-
if (stat1 & 2) {
121+
} else if (stat1 & 0x02) {
140122
u32 dbg3 = hdmi_read_reg(core->base, HDMI_CEC_DBG_3);
141123

142124
cec_transmit_done(core->adap,
143125
CEC_TX_STATUS_NACK |
144126
CEC_TX_STATUS_MAX_RETRIES,
145127
0, (dbg3 >> 4) & 7, 0, 0);
146-
} else if (stat1 & 1) {
147-
cec_transmit_done(core->adap,
148-
CEC_TX_STATUS_ARB_LOST |
149-
CEC_TX_STATUS_MAX_RETRIES,
150-
0, 0, 0, 0);
128+
REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, 0x1, 7, 7);
151129
}
152130
if (stat0 & 0x02)
153131
hdmi_cec_received_msg(core);
154-
if (stat1 & 0x3)
155-
REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, 0x1, 7, 7);
156132
}
157133

158134
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)
231207
/*
232208
* Enable CEC interrupts:
233209
* Transmit Buffer Full/Empty Change event
234-
* Transmitter FIFO Empty event
235210
* Receiver FIFO Not Empty event
236211
*/
237-
hdmi_write_reg(core->base, HDMI_CEC_INT_ENABLE_0, 0x26);
212+
hdmi_write_reg(core->base, HDMI_CEC_INT_ENABLE_0, 0x22);
238213
/*
239214
* Enable CEC interrupts:
240-
* RX FIFO Overrun Error event
241-
* Short Pulse Detected event
242215
* Frame Retransmit Count Exceeded event
243-
* Start Bit Irregularity event
244216
*/
245-
hdmi_write_reg(core->base, HDMI_CEC_INT_ENABLE_1, 0x0f);
217+
hdmi_write_reg(core->base, HDMI_CEC_INT_ENABLE_1, 0x02);
246218

247219
/* cec calibration enable (self clearing) */
248220
hdmi_write_reg(core->base, HDMI_CEC_SETUP, 0x03);

0 commit comments

Comments
 (0)