Esempio n. 1
0
static void hdcp_wq_authentication_failure(void)
{
        if (hdcp.hdmi_state == HDMI_STOPPED) {
                hdcp.auth_state = HDCP_STATE_AUTH_FAILURE;
                return;
        }

        hdcp_lib_auto_ri_check(false);
        hdcp_lib_auto_bcaps_rdy_check(false);
        hdcp_lib_set_av_mute(AV_MUTE_SET);
        hdcp_lib_set_encryption(HDCP_ENC_OFF);

        hdcp_wq_disable();

        if (hdcp.retry_cnt && (hdcp.hdmi_state != HDMI_STOPPED)) {
                if (hdcp.retry_cnt < HDCP_INFINITE_REAUTH) {
                        hdcp.retry_cnt--;
                        printk(KERN_INFO "HDCP: authentication failed - "
                                         "retrying, attempts=%d\n",
                                                        hdcp.retry_cnt);
                } else
                        printk(KERN_INFO "HDCP: authentication failed - "
                                         "retrying\n");

                hdcp.hdcp_state = HDCP_AUTHENTICATION_START;
                hdcp.auth_state = HDCP_STATE_AUTH_FAIL_RESTARTING;

                hdcp.pending_wq_event = hdcp_submit_work(HDCP_AUTH_REATT_EVENT,
                                                         HDCP_REAUTH_DELAY);
        } else {
                printk(KERN_INFO "HDCP: authentication failed - "
                                 "HDCP disabled\n");
                hdcp.hdcp_state = HDCP_ENABLE_PENDING;
                hdcp.auth_state = HDCP_STATE_AUTH_FAILURE;
        }

}
Esempio n. 2
0
static void omap4_hdcp_irq_cb(int status)
{
        HDCP_DBG("hdcp_irq_cb() status=%x", status);

        if (!hdcp.hdcp_keys_loaded) {
                HDCP_DBG("%s: hdcp_keys not loaded = %d",
                    __func__, hdcp.hdcp_keys_loaded);
                return;
        }

        /* Disable auto Ri/BCAPS immediately */
        if (((status & HDMI_RI_ERR) ||
            (status & HDMI_BCAP) ||
            (status & HDMI_HPD_LOW)) &&
            (hdcp.hdcp_state != HDCP_ENABLE_PENDING)) {
                hdcp_lib_auto_ri_check(false);
                hdcp_lib_auto_bcaps_rdy_check(false);
        }

        /* Work queue execution not required if HDCP is disabled */
        /* TODO: ignore interrupts if they are masked (cannnot access UMASK
         * here so should use global variable
         */
        if ((hdcp.hdcp_state != HDCP_DISABLED) &&
            (hdcp.hdcp_state != HDCP_ENABLE_PENDING)) {
                if (status & HDMI_HPD_LOW) {
                        hdcp_lib_set_encryption(HDCP_ENC_OFF);
                        hdcp_ddc_abort();
                }

                if (status & HDMI_RI_ERR) {
                        hdcp_lib_set_av_mute(AV_MUTE_SET);
                        hdcp_lib_set_encryption(HDCP_ENC_OFF);
                        hdcp_submit_work(HDCP_RI_FAIL_EVENT, 0);
                }
                /* RI error takes precedence over BCAP */
                else if (status & HDMI_BCAP)
                        hdcp_submit_work(HDCP_KSV_LIST_RDY_EVENT, 0);
        }

        if (status & HDMI_HPD_LOW) {
                hdcp.pending_disable = 1;       /* Used to exit on-going HDCP
                                                 * work */
                hdcp.hpd_low = 0;               /* Used to cancel HDCP works */
                if (hdcp.pending_start) {
                        pr_err("cancelling work for pending start\n");
                        hdcp_cancel_work(&hdcp.pending_start);
                }
                hdcp_wq_disable();

                /* In case of HDCP_STOP_FRAME_EVENT, HDCP stop
                 * frame callback is blocked and waiting for
                 * HDCP driver to finish accessing the HW
                 * before returning
                 * Reason is to avoid HDMI driver to shutdown
                 * DSS/HDMI power before HDCP work is finished
                 */
                hdcp.hdmi_state = HDMI_STOPPED;
                hdcp.hdcp_state = HDCP_ENABLE_PENDING;
                hdcp.auth_state = HDCP_STATE_DISABLED;
        }
}
Esempio n. 3
0
/*-----------------------------------------------------------------------------
 * Function: hdcp_work_queue
 *-----------------------------------------------------------------------------
 */
static void hdcp_work_queue(struct work_struct *work)
{
	struct hdcp_delayed_work *hdcp_w =
		container_of(work, struct hdcp_delayed_work, work.work);
	int event = hdcp_w->event;

	mutex_lock(&hdcp->lock);
	
	DBG("hdcp_work_queue() - START - %u hdmi=%d hdcp=%d evt= %x %d",
		jiffies_to_msecs(jiffies),
		hdcp->hdmi_state,
		hdcp->hdcp_state,
		(event & 0xFF00) >> 8,
		event & 0xFF);
	
	if(event == HDCP_STOP_FRAME_EVENT) {
		hdcp->hdmi_state = HDMI_STOPPED;
	}
	
	if (event == HDCP_DISABLE_CTL || event == HDCP_STOP_FRAME_EVENT) {
		hdcp_wq_disable(event);
	}
	
	if (event & HDCP_WORKQUEUE_SRC)
		hdcp->pending_wq_event = 0;
	
	/* First handle HDMI state */
	if (event == HDCP_START_FRAME_EVENT) {
		hdcp->pending_start = 0;
		hdcp->hdmi_state = HDMI_STARTED;
	}
	
	/**********************/
	/* HDCP state machine */
	/**********************/
	switch (hdcp->hdcp_state) {
		case HDCP_DISABLED:
			/* HDCP enable control or re-authentication event */
			if (event == HDCP_ENABLE_CTL) {
				if(hdcp->retry_times == 0)
					hdcp->retry_cnt = HDCP_INFINITE_REAUTH;
				else
					hdcp->retry_cnt = hdcp->retry_times;
				if (hdcp->hdmi_state == HDMI_STARTED)
					hdcp_wq_start_authentication();
				else
					hdcp->hdcp_state = HDCP_ENABLE_PENDING;
			}
			break;
		
		case HDCP_ENABLE_PENDING:
			/* HDMI start frame event */
			if (event == HDCP_START_FRAME_EVENT)
				hdcp_wq_start_authentication();

			break;
		
		case HDCP_AUTHENTICATION_START:
			/* Re-authentication */
			if (event == HDCP_AUTH_REATT_EVENT)
				hdcp_wq_start_authentication();
	
			break;
		
		case HDCP_WAIT_KSV_LIST:
			/* KSV failure */
			if (event == HDCP_FAIL_EVENT) {
				printk(KERN_INFO "HDCP: KSV switch failure\n");
	
				hdcp_wq_authentication_failure();
			}
			/* KSV list ready event */
			else if (event == HDCP_KSV_LIST_RDY_EVENT)
				hdcp_wq_check_bksv();
			break;
		
		case HDCP_LINK_INTEGRITY_CHECK:
			/* Ri failure */
			if (event == HDCP_FAIL_EVENT) {
				printk(KERN_INFO "HDCP: Ri check failure\n");
				hdcp_wq_authentication_failure();
			}
			else if(event == HDCP_AUTH_PASS_EVENT)
				hdcp_wq_authentication_sucess();
			break;
	
		default:
			printk(KERN_WARNING "HDCP: error - unknow HDCP state\n");
			break;
	}
	
	kfree(hdcp_w);
	if(event == HDCP_STOP_FRAME_EVENT)
		complete(&hdcp->complete);
		
	mutex_unlock(&hdcp->lock);
}