Commit 50978df3 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'media/v5.5-3' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media fixes from Mauro Carvalho Chehab:

 - some fixes at CEC core to comply with HDMI 2.0 specs and fix some
   border cases

 - a fix at the transmission logic of the pulse8-cec driver

 - one alignment fix on a data struct at ipu3 when built with 32 bits

* tag 'media/v5.5-3' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media:
  media: intel-ipu3: Align struct ipu3_uapi_awb_fr_config_s to 32 bytes
  media: pulse8-cec: fix lost cec_transmit_attempt_done() call
  media: cec: check 'transmit_in_progress', not 'transmitting'
  media: cec: avoid decrementing transmit_queue_sz if it is 0
  media: cec: CEC 2.0-only bcast messages were ignored
parents 3a562aee ce644cf3
...@@ -380,7 +380,8 @@ static void cec_data_cancel(struct cec_data *data, u8 tx_status) ...@@ -380,7 +380,8 @@ static void cec_data_cancel(struct cec_data *data, u8 tx_status)
} else { } else {
list_del_init(&data->list); list_del_init(&data->list);
if (!(data->msg.tx_status & CEC_TX_STATUS_OK)) if (!(data->msg.tx_status & CEC_TX_STATUS_OK))
data->adap->transmit_queue_sz--; if (!WARN_ON(!data->adap->transmit_queue_sz))
data->adap->transmit_queue_sz--;
} }
if (data->msg.tx_status & CEC_TX_STATUS_OK) { if (data->msg.tx_status & CEC_TX_STATUS_OK) {
...@@ -432,6 +433,14 @@ static void cec_flush(struct cec_adapter *adap) ...@@ -432,6 +433,14 @@ static void cec_flush(struct cec_adapter *adap)
* need to do anything special in that case. * need to do anything special in that case.
*/ */
} }
/*
* If something went wrong and this counter isn't what it should
* be, then this will reset it back to 0. Warn if it is not 0,
* since it indicates a bug, either in this framework or in a
* CEC driver.
*/
if (WARN_ON(adap->transmit_queue_sz))
adap->transmit_queue_sz = 0;
} }
/* /*
...@@ -456,7 +465,7 @@ int cec_thread_func(void *_adap) ...@@ -456,7 +465,7 @@ int cec_thread_func(void *_adap)
bool timeout = false; bool timeout = false;
u8 attempts; u8 attempts;
if (adap->transmitting) { if (adap->transmit_in_progress) {
int err; int err;
/* /*
...@@ -491,7 +500,7 @@ int cec_thread_func(void *_adap) ...@@ -491,7 +500,7 @@ int cec_thread_func(void *_adap)
goto unlock; goto unlock;
} }
if (adap->transmitting && timeout) { if (adap->transmit_in_progress && timeout) {
/* /*
* If we timeout, then log that. Normally this does * If we timeout, then log that. Normally this does
* not happen and it is an indication of a faulty CEC * not happen and it is an indication of a faulty CEC
...@@ -500,14 +509,18 @@ int cec_thread_func(void *_adap) ...@@ -500,14 +509,18 @@ int cec_thread_func(void *_adap)
* so much traffic on the bus that the adapter was * so much traffic on the bus that the adapter was
* unable to transmit for CEC_XFER_TIMEOUT_MS (2.1s). * unable to transmit for CEC_XFER_TIMEOUT_MS (2.1s).
*/ */
pr_warn("cec-%s: message %*ph timed out\n", adap->name, if (adap->transmitting) {
adap->transmitting->msg.len, pr_warn("cec-%s: message %*ph timed out\n", adap->name,
adap->transmitting->msg.msg); adap->transmitting->msg.len,
adap->transmitting->msg.msg);
/* Just give up on this. */
cec_data_cancel(adap->transmitting,
CEC_TX_STATUS_TIMEOUT);
} else {
pr_warn("cec-%s: transmit timed out\n", adap->name);
}
adap->transmit_in_progress = false; adap->transmit_in_progress = false;
adap->tx_timeouts++; adap->tx_timeouts++;
/* Just give up on this. */
cec_data_cancel(adap->transmitting,
CEC_TX_STATUS_TIMEOUT);
goto unlock; goto unlock;
} }
...@@ -522,7 +535,8 @@ int cec_thread_func(void *_adap) ...@@ -522,7 +535,8 @@ int cec_thread_func(void *_adap)
data = list_first_entry(&adap->transmit_queue, data = list_first_entry(&adap->transmit_queue,
struct cec_data, list); struct cec_data, list);
list_del_init(&data->list); list_del_init(&data->list);
adap->transmit_queue_sz--; if (!WARN_ON(!data->adap->transmit_queue_sz))
adap->transmit_queue_sz--;
/* Make this the current transmitting message */ /* Make this the current transmitting message */
adap->transmitting = data; adap->transmitting = data;
...@@ -1085,11 +1099,11 @@ void cec_received_msg_ts(struct cec_adapter *adap, ...@@ -1085,11 +1099,11 @@ void cec_received_msg_ts(struct cec_adapter *adap,
valid_la = false; valid_la = false;
else if (!cec_msg_is_broadcast(msg) && !(dir_fl & DIRECTED)) else if (!cec_msg_is_broadcast(msg) && !(dir_fl & DIRECTED))
valid_la = false; valid_la = false;
else if (cec_msg_is_broadcast(msg) && !(dir_fl & BCAST1_4)) else if (cec_msg_is_broadcast(msg) && !(dir_fl & BCAST))
valid_la = false; valid_la = false;
else if (cec_msg_is_broadcast(msg) && else if (cec_msg_is_broadcast(msg) &&
adap->log_addrs.cec_version >= CEC_OP_CEC_VERSION_2_0 && adap->log_addrs.cec_version < CEC_OP_CEC_VERSION_2_0 &&
!(dir_fl & BCAST2_0)) !(dir_fl & BCAST1_4))
valid_la = false; valid_la = false;
} }
if (valid_la && min_len) { if (valid_la && min_len) {
......
...@@ -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:
......
...@@ -449,7 +449,7 @@ struct ipu3_uapi_awb_fr_config_s { ...@@ -449,7 +449,7 @@ struct ipu3_uapi_awb_fr_config_s {
__u16 reserved1; __u16 reserved1;
__u32 bayer_sign; __u32 bayer_sign;
__u8 bayer_nf; __u8 bayer_nf;
__u8 reserved2[3]; __u8 reserved2[7];
} __attribute__((aligned(32))) __packed; } __attribute__((aligned(32))) __packed;
/** /**
......
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