diff -Nur linux-3.14.45.orig/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c linux-3.14.45/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c --- linux-3.14.45.orig/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c 2015-07-16 01:45:57.033999867 -0500 +++ linux-3.14.45/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c 2015-07-16 01:44:12.826000821 -0500 @@ -67,7 +67,6 @@ u8 msg_len; int tx_answer; u16 latest_cec_stat; - u8 link_status; spinlock_t irq_lock; struct delayed_work hdmi_cec_work; struct mutex lock; @@ -83,8 +82,6 @@ static LIST_HEAD(head); -static int hdmi_cec_ready = 0; -static int hdmi_cec_started; static int hdmi_cec_major; static struct class *hdmi_cec_class; static struct hdmi_cec_priv hdmi_cec_data; @@ -98,7 +95,6 @@ struct hdmi_cec_priv *hdmi_cec = data; u16 cec_stat = 0; unsigned long flags; - u8 phy_stat0; irqreturn_t ret = IRQ_HANDLED; spin_lock_irqsave(&hdmi_cec->irq_lock, flags); @@ -107,7 +103,6 @@ cec_stat = hdmi_readb(HDMI_IH_CEC_STAT0); hdmi_writeb(cec_stat, HDMI_IH_CEC_STAT0); - phy_stat0 = hdmi_readb(HDMI_PHY_STAT0) & 0x02; if ((cec_stat & (HDMI_IH_CEC_STAT0_ERROR_INIT | \ HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | \ @@ -115,14 +110,7 @@ ret = IRQ_NONE; cec_stat = 0; } - if (hdmi_cec->link_status ^ phy_stat0) { - /* HPD value changed */ - hdmi_cec->link_status = phy_stat0; - if (hdmi_cec->link_status) - cec_stat |= 0x80; /* Connected */ - else - cec_stat |= 0x100; /* Disconnected */ - } + pr_debug("HDMI CEC interrupt received\n"); hdmi_cec->latest_cec_stat = cec_stat ; @@ -315,7 +303,7 @@ mutex_unlock(&hdmi_cec_data.lock); return -EACCES; } - /* Ensure that there is only one writer who is the only listener of tx_cec_queue */ + /* Ensure that there is only one writer who is the unique listener of tx_cec_queue */ if (hdmi_cec_data.tx_answer != CEC_TX_AVAIL) { mutex_unlock(&hdmi_cec_data.lock); return -EBUSY; @@ -363,9 +351,6 @@ { u8 val; - if (!hdmi_cec_ready || hdmi_cec_started) - return; - val = hdmi_readb(HDMI_MC_CLKDIS); val &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE; hdmi_writeb(val, HDMI_MC_CLKDIS); @@ -377,12 +362,7 @@ val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL | HDMI_IH_CEC_STAT0_ARB_LOST; hdmi_writeb(val, HDMI_CEC_MASK); hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0); - hdmi_cec_data.link_status = hdmi_readb(HDMI_PHY_STAT0) & 0x02; - mutex_lock(&hdmi_cec_data.lock); hdmi_cec_data.cec_state = true; - mutex_unlock(&hdmi_cec_data.lock); - - hdmi_cec_started = 1; } EXPORT_SYMBOL(hdmi_cec_start_device); @@ -390,9 +370,6 @@ { u8 val; - if (!hdmi_cec_ready || !hdmi_cec_started) - return; - hdmi_writeb(0x10, HDMI_CEC_CTRL); val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL | HDMI_IH_CEC_STAT0_ERROR_INIT | HDMI_IH_CEC_STAT0_ARB_LOST | \ HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | HDMI_IH_CEC_STAT0_DONE; @@ -402,11 +379,7 @@ val = hdmi_readb(HDMI_MC_CLKDIS); val |= HDMI_MC_CLKDIS_CECCLK_DISABLE; hdmi_writeb(val, HDMI_MC_CLKDIS); - mutex_lock(&hdmi_cec_data.lock); hdmi_cec_data.cec_state = false; - mutex_unlock(&hdmi_cec_data.lock); - - hdmi_cec_started = 0; } EXPORT_SYMBOL(hdmi_cec_stop_device); @@ -481,11 +454,18 @@ */ static int hdmi_cec_release(struct inode *inode, struct file *filp) { + struct hdmi_cec_event *event, *tmp_event; mutex_lock(&hdmi_cec_data.lock); if (open_count) { open_count = 0; hdmi_cec_data.cec_state = false; hdmi_cec_data.Logical_address = 15; + + /* Flush eventual events which have not been read by user space */ + list_for_each_entry_safe(event, tmp_event, &head, list) { + list_del(&event->list); + vfree(event); + } } mutex_unlock(&hdmi_cec_data.lock); @@ -580,7 +560,6 @@ INIT_DELAYED_WORK(&hdmi_cec_data.hdmi_cec_work, mxc_hdmi_cec_worker); dev_info(&pdev->dev, "HDMI CEC initialized\n"); - hdmi_cec_ready = 1; goto out; err_out_class: