static irqreturn_t s5p_cec_irq_handler(int irq, void *dev_id) { u32 status = 0; status = s5p_cec_get_status(); if (status & CEC_STATUS_TX_DONE) { if (status & CEC_STATUS_TX_ERROR) { tvout_dbg(" CEC_STATUS_TX_ERROR!\n"); s5p_cec_set_tx_state(STATE_ERROR); } else { tvout_dbg(" CEC_STATUS_TX_DONE!\n"); s5p_cec_set_tx_state(STATE_DONE); } s5p_clr_pending_tx(); wake_up_interruptible(&cec_tx_struct.waitq); } if (status & CEC_STATUS_RX_DONE) { if (status & CEC_STATUS_RX_ERROR) { tvout_dbg(" CEC_STATUS_RX_ERROR!\n"); s5p_cec_rx_reset(); } else { u32 size; tvout_dbg(" CEC_STATUS_RX_DONE!\n"); /* copy data from internal buffer */ size = status >> 24; spin_lock(&cec_rx_struct.lock); s5p_cec_get_rx_buf(size, cec_rx_struct.buffer); cec_rx_struct.size = size; s5p_cec_set_rx_state(STATE_DONE); spin_unlock(&cec_rx_struct.lock); s5p_cec_enable_rx(); } /* clear interrupt pending bit */ s5p_clr_pending_rx(); wake_up_interruptible(&cec_rx_struct.waitq); } return IRQ_HANDLED; }
static irqreturn_t s5p_cec_irq_handler(int irq, void *priv) { struct s5p_cec_dev *cec = priv; u32 status = 0; status = s5p_cec_get_status(cec); dev_dbg(cec->dev, "irq received\n"); if (status & CEC_STATUS_TX_DONE) { if (status & CEC_STATUS_TX_ERROR) { dev_dbg(cec->dev, "CEC_STATUS_TX_ERROR set\n"); cec->tx = STATE_ERROR; } else { dev_dbg(cec->dev, "CEC_STATUS_TX_DONE\n"); cec->tx = STATE_DONE; } s5p_clr_pending_tx(cec); } if (status & CEC_STATUS_RX_DONE) { if (status & CEC_STATUS_RX_ERROR) { dev_dbg(cec->dev, "CEC_STATUS_RX_ERROR set\n"); s5p_cec_rx_reset(cec); s5p_cec_enable_rx(cec); } else { dev_dbg(cec->dev, "CEC_STATUS_RX_DONE set\n"); if (cec->rx != STATE_IDLE) dev_dbg(cec->dev, "Buffer overrun (worker did not process previous message)\n"); cec->rx = STATE_BUSY; cec->msg.len = status >> 24; cec->msg.rx_status = CEC_RX_STATUS_OK; s5p_cec_get_rx_buf(cec, cec->msg.len, cec->msg.msg); cec->rx = STATE_DONE; s5p_cec_enable_rx(cec); } /* Clear interrupt pending bit */ s5p_clr_pending_rx(cec); } return IRQ_WAKE_THREAD; }