Commit 50978df3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
Loading
Loading
Loading
Loading
+27 −13
Original line number Diff line number Diff line
@@ -380,6 +380,7 @@ static void cec_data_cancel(struct cec_data *data, u8 tx_status)
	} else {
		list_del_init(&data->list);
		if (!(data->msg.tx_status & CEC_TX_STATUS_OK))
			if (!WARN_ON(!data->adap->transmit_queue_sz))
				data->adap->transmit_queue_sz--;
	}

@@ -432,6 +433,14 @@ static void cec_flush(struct cec_adapter *adap)
		 * 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)
		bool timeout = false;
		u8 attempts;

		if (adap->transmitting) {
		if (adap->transmit_in_progress) {
			int err;

			/*
@@ -491,7 +500,7 @@ int cec_thread_func(void *_adap)
			goto unlock;
		}

		if (adap->transmitting && timeout) {
		if (adap->transmit_in_progress && timeout) {
			/*
			 * If we timeout, then log that. Normally this does
			 * not happen and it is an indication of a faulty CEC
@@ -500,14 +509,18 @@ int cec_thread_func(void *_adap)
			 * so much traffic on the bus that the adapter was
			 * unable to transmit for CEC_XFER_TIMEOUT_MS (2.1s).
			 */
			if (adap->transmitting) {
				pr_warn("cec-%s: message %*ph timed out\n", adap->name,
					adap->transmitting->msg.len,
					adap->transmitting->msg.msg);
			adap->transmit_in_progress = false;
			adap->tx_timeouts++;
				/* 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->tx_timeouts++;
			goto unlock;
		}

@@ -522,6 +535,7 @@ int cec_thread_func(void *_adap)
		data = list_first_entry(&adap->transmit_queue,
					struct cec_data, list);
		list_del_init(&data->list);
		if (!WARN_ON(!data->adap->transmit_queue_sz))
			adap->transmit_queue_sz--;

		/* Make this the current transmitting message */
@@ -1085,11 +1099,11 @@ void cec_received_msg_ts(struct cec_adapter *adap,
			valid_la = false;
		else if (!cec_msg_is_broadcast(msg) && !(dir_fl & DIRECTED))
			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;
		else if (cec_msg_is_broadcast(msg) &&
			 adap->log_addrs.cec_version >= CEC_OP_CEC_VERSION_2_0 &&
			 !(dir_fl & BCAST2_0))
			 adap->log_addrs.cec_version < CEC_OP_CEC_VERSION_2_0 &&
			 !(dir_fl & BCAST1_4))
			valid_la = false;
	}
	if (valid_la && min_len) {
+13 −4
Original line number Diff line number Diff line
@@ -116,6 +116,7 @@ struct pulse8 {
	unsigned int vers;
	struct completion cmd_done;
	struct work_struct work;
	u8 work_result;
	struct delayed_work ping_eeprom_work;
	struct cec_msg rx_msg;
	u8 data[DATA_SIZE];
@@ -137,8 +138,10 @@ static void pulse8_irq_work_handler(struct work_struct *work)
{
	struct pulse8 *pulse8 =
		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:
		cec_received_msg(pulse8->adap, &pulse8->rx_msg);
		break;
@@ -172,12 +175,12 @@ static irqreturn_t pulse8_interrupt(struct serio *serio, unsigned char data,
		pulse8->escape = false;
	} else if (data == MSGEND) {
		struct cec_msg *msg = &pulse8->rx_msg;
		u8 msgcode = pulse8->buf[0];

		if (debug)
			dev_info(pulse8->dev, "received: %*ph\n",
				 pulse8->idx, pulse8->buf);
		pulse8->data[0] = pulse8->buf[0];
		switch (pulse8->buf[0] & 0x3f) {
		switch (msgcode & 0x3f) {
		case MSGCODE_FRAME_START:
			msg->len = 1;
			msg->msg[0] = pulse8->buf[1];
@@ -186,14 +189,20 @@ static irqreturn_t pulse8_interrupt(struct serio *serio, unsigned char data,
			if (msg->len == CEC_MAX_MSG_SIZE)
				break;
			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);
				break;
			}
			break;
		case MSGCODE_TRANSMIT_SUCCEEDED:
		case MSGCODE_TRANSMIT_FAILED_LINE:
		case MSGCODE_TRANSMIT_FAILED_ACK:
		case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA:
		case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE:
			WARN_ON(pulse8->work_result);
			pulse8->work_result = msgcode;
			schedule_work(&pulse8->work);
			break;
		case MSGCODE_HIGH_ERROR:
+1 −1
Original line number Diff line number Diff line
@@ -449,7 +449,7 @@ struct ipu3_uapi_awb_fr_config_s {
	__u16 reserved1;
	__u32 bayer_sign;
	__u8 bayer_nf;
	__u8 reserved2[3];
	__u8 reserved2[7];
} __attribute__((aligned(32))) __packed;

/**