list_del_init(&data->list);
 
        /* Mark it as an error */
-       data->msg.ts = ktime_get_ns();
+       data->msg.tx_ts = ktime_get_ns();
        data->msg.tx_status = CEC_TX_STATUS_ERROR |
                              CEC_TX_STATUS_MAX_RETRIES;
        data->attempts = 0;
 {
        struct cec_data *data;
        struct cec_msg *msg;
+       u64 ts = ktime_get_ns();
 
        dprintk(2, "cec_transmit_done %02x\n", status);
        mutex_lock(&adap->lock);
 
        /* Drivers must fill in the status! */
        WARN_ON(status == 0);
-       msg->ts = ktime_get_ns();
+       msg->tx_ts = ts;
        msg->tx_status |= status;
        msg->tx_arb_lost_cnt += arb_lost_cnt;
        msg->tx_nack_cnt += nack_cnt;
 
        /* Mark the message as timed out */
        list_del_init(&data->list);
-       data->msg.ts = ktime_get_ns();
+       data->msg.rx_ts = ktime_get_ns();
        data->msg.rx_status = CEC_RX_STATUS_TIMEOUT;
        cec_data_completed(data);
 unlock:
        if (WARN_ON(!msg->len || msg->len > CEC_MAX_MSG_SIZE))
                return;
 
-       mutex_lock(&adap->lock);
-       msg->ts = ktime_get_ns();
+       msg->rx_ts = ktime_get_ns();
        msg->rx_status = CEC_RX_STATUS_OK;
-       msg->tx_status = 0;
        msg->sequence = msg->reply = msg->timeout = 0;
+       msg->tx_status = 0;
+       msg->tx_ts = 0;
        msg->flags = 0;
 
+       mutex_lock(&adap->lock);
        dprintk(2, "cec_received_msg: %*ph\n", msg->len, msg->msg);
 
        /* Check if this message was for us (directed or broadcast). */
                 */
                list_for_each_entry(data, &adap->wait_queue, list) {
                        struct cec_msg *dst = &data->msg;
-                       u8 dst_reply;
 
                        /* Does the command match? */
                        if ((abort && cmd != dst->msg[1]) ||
                                continue;
 
                        /* We got a reply */
-                       msg->sequence = dst->sequence;
-                       msg->tx_status = dst->tx_status;
-                       dst_reply = dst->reply;
-                       *dst = *msg;
-                       dst->reply = dst_reply;
+                       memcpy(dst->msg, msg->msg, msg->len);
+                       dst->len = msg->len;
+                       dst->rx_ts = msg->rx_ts;
+                       dst->rx_status = msg->rx_status;
                        if (abort) {
                                dst->reply = 0;
                                dst->rx_status |= CEC_RX_STATUS_FEATURE_ABORT;
 
 
 /**
  * struct cec_msg - CEC message structure.
- * @ts:                Timestamp in nanoseconds using CLOCK_MONOTONIC. Set by the
- *             driver. It is set when the message transmission has finished
- *             and it is set when a message was received.
+ * @tx_ts:     Timestamp in nanoseconds using CLOCK_MONOTONIC. Set by the
+ *             driver when the message transmission has finished.
+ * @rx_ts:     Timestamp in nanoseconds using CLOCK_MONOTONIC. Set by the
+ *             driver when the message was received.
  * @len:       Length in bytes of the message.
  * @timeout:   The timeout (in ms) that is used to timeout CEC_RECEIVE.
  *             Set to 0 if you want to wait forever. This timeout can also be
  *             sent. This can be used to track replies to previously sent
  *             messages.
  * @flags:     Set to 0.
- * @rx_status: The message receive status bits. Set by the driver.
- * @tx_status: The message transmit status bits. Set by the driver.
  * @msg:       The message payload.
  * @reply:     This field is ignored with CEC_RECEIVE and is only used by
  *             CEC_TRANSMIT. If non-zero, then wait for a reply with this
  *             broadcast, then -EINVAL is returned.
  *             if reply is non-zero, then timeout is set to 1000 (the required
  *             maximum response time).
+ * @rx_status: The message receive status bits. Set by the driver.
+ * @tx_status: The message transmit status bits. Set by the driver.
  * @tx_arb_lost_cnt: The number of 'Arbitration Lost' events. Set by the driver.
  * @tx_nack_cnt: The number of 'Not Acknowledged' events. Set by the driver.
  * @tx_low_drive_cnt: The number of 'Low Drive Detected' events. Set by the
  * @tx_error_cnt: The number of 'Error' events. Set by the driver.
  */
 struct cec_msg {
-       __u64 ts;
+       __u64 tx_ts;
+       __u64 rx_ts;
        __u32 len;
        __u32 timeout;
        __u32 sequence;
        __u32 flags;
-       __u8 rx_status;
-       __u8 tx_status;
        __u8 msg[CEC_MAX_MSG_SIZE];
        __u8 reply;
+       __u8 rx_status;
+       __u8 tx_status;
        __u8 tx_arb_lost_cnt;
        __u8 tx_nack_cnt;
        __u8 tx_low_drive_cnt;