void cec_queue_event_fh(struct cec_fh *fh,
                        const struct cec_event *new_ev, u64 ts)
 {
-       static const u8 max_events[CEC_NUM_EVENTS] = {
-               1, 1, 64, 64, 8, 8,
+       static const u16 max_events[CEC_NUM_EVENTS] = {
+               1, 1, 800, 800, 8, 8,
        };
        struct cec_event_entry *entry;
        unsigned int ev_idx = new_ev->event - 1;
 }
 
 /* Notify userspace that the CEC pin changed state at the given time. */
-void cec_queue_pin_cec_event(struct cec_adapter *adap, bool is_high, ktime_t ts)
+void cec_queue_pin_cec_event(struct cec_adapter *adap, bool is_high,
+                            bool dropped_events, ktime_t ts)
 {
        struct cec_event ev = {
                .event = is_high ? CEC_EVENT_PIN_CEC_HIGH :
                                   CEC_EVENT_PIN_CEC_LOW,
+               .flags = dropped_events ? CEC_EVENT_FL_DROPPED_EVENTS : 0,
        };
        struct cec_fh *fh;
 
 
 /* The default for the low/high time of the custom pulse */
 #define CEC_TIM_CUSTOM_DEFAULT                         1000
 
-#define CEC_NUM_PIN_EVENTS 128
+#define CEC_NUM_PIN_EVENTS                             128
+#define CEC_PIN_EVENT_FL_IS_HIGH                       (1 << 0)
+#define CEC_PIN_EVENT_FL_DROPPED                       (1 << 1)
 
 #define CEC_PIN_IRQ_UNCHANGED  0
 #define CEC_PIN_IRQ_DISABLE    1
        u8                              work_tx_status;
        ktime_t                         work_tx_ts;
        atomic_t                        work_irq_change;
-       atomic_t                        work_pin_events;
+       atomic_t                        work_pin_num_events;
        unsigned int                    work_pin_events_wr;
        unsigned int                    work_pin_events_rd;
        ktime_t                         work_pin_ts[CEC_NUM_PIN_EVENTS];
-       bool                            work_pin_is_high[CEC_NUM_PIN_EVENTS];
+       u8                              work_pin_events[CEC_NUM_PIN_EVENTS];
+       bool                            work_pin_events_dropped;
+       u32                             work_pin_events_dropped_cnt;
        ktime_t                         timer_ts;
        u32                             timer_cnt;
        u32                             timer_100ms_overruns;
 
                return;
 
        pin->adap->cec_pin_is_high = v;
-       if (atomic_read(&pin->work_pin_events) < CEC_NUM_PIN_EVENTS) {
-               pin->work_pin_is_high[pin->work_pin_events_wr] = v;
+       if (atomic_read(&pin->work_pin_num_events) < CEC_NUM_PIN_EVENTS) {
+               u8 ev = v;
+
+               if (pin->work_pin_events_dropped) {
+                       pin->work_pin_events_dropped = false;
+                       v |= CEC_PIN_EVENT_FL_DROPPED;
+               }
+               pin->work_pin_events[pin->work_pin_events_wr] = ev;
                pin->work_pin_ts[pin->work_pin_events_wr] = ktime_get();
                pin->work_pin_events_wr =
                        (pin->work_pin_events_wr + 1) % CEC_NUM_PIN_EVENTS;
-               atomic_inc(&pin->work_pin_events);
+               atomic_inc(&pin->work_pin_num_events);
+       } else {
+               pin->work_pin_events_dropped = true;
+               pin->work_pin_events_dropped_cnt++;
        }
        wake_up_interruptible(&pin->kthread_waitq);
 }
                        pin->work_rx_msg.len ||
                        pin->work_tx_status ||
                        atomic_read(&pin->work_irq_change) ||
-                       atomic_read(&pin->work_pin_events));
+                       atomic_read(&pin->work_pin_num_events));
 
                if (pin->work_rx_msg.len) {
                        struct cec_msg *msg = &pin->work_rx_msg;
                                                     pin->work_tx_ts);
                }
 
-               while (atomic_read(&pin->work_pin_events)) {
+               while (atomic_read(&pin->work_pin_num_events)) {
                        unsigned int idx = pin->work_pin_events_rd;
+                       u8 v = pin->work_pin_events[idx];
 
                        cec_queue_pin_cec_event(adap,
-                                               pin->work_pin_is_high[idx],
+                                               v & CEC_PIN_EVENT_FL_IS_HIGH,
+                                               v & CEC_PIN_EVENT_FL_DROPPED,
                                                pin->work_pin_ts[idx]);
                        pin->work_pin_events_rd = (idx + 1) % CEC_NUM_PIN_EVENTS;
-                       atomic_dec(&pin->work_pin_events);
+                       atomic_dec(&pin->work_pin_num_events);
                }
 
                switch (atomic_xchg(&pin->work_irq_change,
 
        pin->enabled = enable;
        if (enable) {
-               atomic_set(&pin->work_pin_events, 0);
+               atomic_set(&pin->work_pin_num_events, 0);
                pin->work_pin_events_rd = pin->work_pin_events_wr = 0;
+               pin->work_pin_events_dropped = false;
                cec_pin_read(pin);
                cec_pin_to_idle(pin);
                pin->tx_msg.len = 0;
        seq_printf(file, "tx_bit: %d\n", pin->tx_bit);
        seq_printf(file, "rx_bit: %d\n", pin->rx_bit);
        seq_printf(file, "cec pin: %d\n", pin->ops->read(adap));
+       seq_printf(file, "cec pin events dropped: %u\n",
+                  pin->work_pin_events_dropped_cnt);
        seq_printf(file, "irq failed: %d\n", pin->enable_irq_failed);
        if (pin->timer_100ms_overruns) {
                seq_printf(file, "timer overruns > 100ms: %u of %u\n",
                           pin->rx_data_bit_too_long_cnt);
        seq_printf(file, "rx initiated low drive: %u\n", pin->rx_low_drive_cnt);
        seq_printf(file, "tx detected low drive: %u\n", pin->tx_low_drive_cnt);
+       pin->work_pin_events_dropped_cnt = 0;
        pin->timer_cnt = 0;
        pin->timer_100ms_overruns = 0;
        pin->timer_300ms_overruns = 0;
 
         */
        ts = ktime_sub_us(ts, CEC_TIM_START_BIT_TOTAL +
                               10ULL * len * CEC_TIM_DATA_BIT_TOTAL);
-       cec_queue_pin_cec_event(adap, false, ts);
+       cec_queue_pin_cec_event(adap, false, false, ts);
        ts = ktime_add_us(ts, CEC_TIM_START_BIT_LOW);
-       cec_queue_pin_cec_event(adap, true, ts);
+       cec_queue_pin_cec_event(adap, true, false, ts);
        ts = ktime_add_us(ts, CEC_TIM_START_BIT_HIGH);
 
        for (i = 0; i < 10 * len; i++) {
                        bit = cec_msg_is_broadcast(msg) ^ nacked;
                        break;
                }
-               cec_queue_pin_cec_event(adap, false, ts);
+               cec_queue_pin_cec_event(adap, false, false, ts);
                if (bit)
                        ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_1_LOW);
                else
                        ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_0_LOW);
-               cec_queue_pin_cec_event(adap, true, ts);
+               cec_queue_pin_cec_event(adap, true, false, ts);
                if (bit)
                        ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_1_HIGH);
                else
 
        wait_queue_head_t       wait;
        struct mutex            lock;
        struct list_head        events[CEC_NUM_EVENTS]; /* queued events */
-       u8                      queued_events[CEC_NUM_EVENTS];
+       u16                     queued_events[CEC_NUM_EVENTS];
        unsigned int            total_queued_events;
        struct cec_event_entry  core_events[CEC_NUM_CORE_EVENTS];
        struct list_head        msgs; /* queued messages */
  *
  * @adap:      pointer to the cec adapter
  * @is_high:   when true the CEC pin is high, otherwise it is low
+ * @dropped_events: when true some events were dropped
  * @ts:                the timestamp for this event
  *
  */
-void cec_queue_pin_cec_event(struct cec_adapter *adap,
-                            bool is_high, ktime_t ts);
+void cec_queue_pin_cec_event(struct cec_adapter *adap, bool is_high,
+                            bool dropped_events, ktime_t ts);
 
 /**
  * cec_queue_pin_hpd_event() - queue a pin event with a given timestamp.