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

media: pulse8-cec: fix lost cec_transmit_attempt_done() call

The periodic PING command could interfere with the result of
a CEC transmit, causing a lost cec_transmit_attempt_done()
call.
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Cc: <stable@vger.kernel.org>      # for v4.10 and up
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent ac479b51
...@@ -116,6 +116,7 @@ struct pulse8 { ...@@ -116,6 +116,7 @@ struct pulse8 {
unsigned int vers; unsigned int vers;
struct completion cmd_done; struct completion cmd_done;
struct work_struct work; struct work_struct work;
u8 work_result;
struct delayed_work ping_eeprom_work; struct delayed_work ping_eeprom_work;
struct cec_msg rx_msg; struct cec_msg rx_msg;
u8 data[DATA_SIZE]; u8 data[DATA_SIZE];
...@@ -137,8 +138,10 @@ static void pulse8_irq_work_handler(struct work_struct *work) ...@@ -137,8 +138,10 @@ static void pulse8_irq_work_handler(struct work_struct *work)
{ {
struct pulse8 *pulse8 = struct pulse8 *pulse8 =
container_of(work, struct pulse8, work); container_of(work, struct pulse8, work);
u8 result = pulse8->work_result;
switch (pulse8->data[0] & 0x3f) { pulse8->work_result = 0;
switch (result & 0x3f) {
case MSGCODE_FRAME_DATA: case MSGCODE_FRAME_DATA:
cec_received_msg(pulse8->adap, &pulse8->rx_msg); cec_received_msg(pulse8->adap, &pulse8->rx_msg);
break; break;
...@@ -172,12 +175,12 @@ static irqreturn_t pulse8_interrupt(struct serio *serio, unsigned char data, ...@@ -172,12 +175,12 @@ static irqreturn_t pulse8_interrupt(struct serio *serio, unsigned char data,
pulse8->escape = false; pulse8->escape = false;
} else if (data == MSGEND) { } else if (data == MSGEND) {
struct cec_msg *msg = &pulse8->rx_msg; struct cec_msg *msg = &pulse8->rx_msg;
u8 msgcode = pulse8->buf[0];
if (debug) if (debug)
dev_info(pulse8->dev, "received: %*ph\n", dev_info(pulse8->dev, "received: %*ph\n",
pulse8->idx, pulse8->buf); pulse8->idx, pulse8->buf);
pulse8->data[0] = pulse8->buf[0]; switch (msgcode & 0x3f) {
switch (pulse8->buf[0] & 0x3f) {
case MSGCODE_FRAME_START: case MSGCODE_FRAME_START:
msg->len = 1; msg->len = 1;
msg->msg[0] = pulse8->buf[1]; msg->msg[0] = pulse8->buf[1];
...@@ -186,14 +189,20 @@ static irqreturn_t pulse8_interrupt(struct serio *serio, unsigned char data, ...@@ -186,14 +189,20 @@ static irqreturn_t pulse8_interrupt(struct serio *serio, unsigned char data,
if (msg->len == CEC_MAX_MSG_SIZE) if (msg->len == CEC_MAX_MSG_SIZE)
break; break;
msg->msg[msg->len++] = pulse8->buf[1]; msg->msg[msg->len++] = pulse8->buf[1];
if (pulse8->buf[0] & MSGCODE_FRAME_EOM) if (msgcode & MSGCODE_FRAME_EOM) {
WARN_ON(pulse8->work_result);
pulse8->work_result = msgcode;
schedule_work(&pulse8->work); schedule_work(&pulse8->work);
break; break;
}
break;
case MSGCODE_TRANSMIT_SUCCEEDED: case MSGCODE_TRANSMIT_SUCCEEDED:
case MSGCODE_TRANSMIT_FAILED_LINE: case MSGCODE_TRANSMIT_FAILED_LINE:
case MSGCODE_TRANSMIT_FAILED_ACK: case MSGCODE_TRANSMIT_FAILED_ACK:
case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA: case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA:
case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE: case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE:
WARN_ON(pulse8->work_result);
pulse8->work_result = msgcode;
schedule_work(&pulse8->work); schedule_work(&pulse8->work);
break; break;
case MSGCODE_HIGH_ERROR: case MSGCODE_HIGH_ERROR:
......
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