static void hdcp_work_queue(struct work_struct *work) { struct hdcp_worker_data *d = container_of(work, typeof(*d), dwork.work); int state = atomic_read(&d->state); int ret = 0; HDCP_DBG("hdcp_work_queue() start\n"); switch (state) { case HDCP_STATE_STEP1: ret = hdcp_wq_start_authentication(); break; case HDCP_STATE_STEP2: ret = hdcp_step2_authenticate_repeater(HDCP_EVENT_STEP2); break; } if (ret) HDCP_ERR("authentication failed"); HDCP_DBG("hdcp_work_queue() - END\n"); }
/*----------------------------------------------------------------------------- * 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); hdcp_request_dss(); DBG("hdcp_work_queue() - START - %u hdmi=%d hdcp=%d auth=%d evt= %x %d" " hdcp_ctrl=%02x", jiffies_to_msecs(jiffies), hdcp.hdmi_state, hdcp.hdcp_state, hdcp.auth_state, (event & 0xFF00) >> 8, event & 0xFF, RD_REG_32(hdcp.hdmi_wp_base_addr + HDMI_IP_CORE_SYSTEM, HDMI_IP_CORE_SYSTEM__HDCP_CTRL)); /* Clear pending_wq_event * In case a delayed work is scheduled from the state machine * "pending_wq_event" is used to memorize pointer on the event to be * able to cancel any pending work in case HDCP is disabled */ 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) { /* State */ /*********/ case HDCP_DISABLED: /* HDCP enable control or re-authentication event */ if (event == HDCP_ENABLE_CTL) { if (hdcp.en_ctrl->nb_retry == 0) hdcp.retry_cnt = HDCP_INFINITE_REAUTH; else hdcp.retry_cnt = hdcp.en_ctrl->nb_retry; if (hdcp.hdmi_state == HDMI_STARTED) hdcp_wq_start_authentication(); else hdcp.hdcp_state = HDCP_ENABLE_PENDING; } break; /* State */ /*********/ case HDCP_ENABLE_PENDING: /* HDMI start frame event */ if (event == HDCP_START_FRAME_EVENT) hdcp_wq_start_authentication(); break; /* State */ /*********/ case HDCP_AUTHENTICATION_START: /* Re-authentication */ if (event == HDCP_AUTH_REATT_EVENT) hdcp_wq_start_authentication(); break; /* State */ /*********/ case HDCP_WAIT_R0_DELAY: /* R0 timer elapsed */ if (event == HDCP_R0_EXP_EVENT) hdcp_wq_check_r0(); break; /* State */ /*********/ case HDCP_WAIT_KSV_LIST: /* Ri failure */ if (event == HDCP_RI_FAIL_EVENT) { printk(KERN_INFO "HDCP: Ri check failure\n"); hdcp_wq_authentication_failure(); } /* KSV list ready event */ else if (event == HDCP_KSV_LIST_RDY_EVENT) hdcp_wq_step2_authentication(); /* Timeout */ else if (event == HDCP_KSV_TIMEOUT_EVENT) { printk(KERN_INFO "HDCP: BCAPS polling timeout\n"); hdcp_wq_authentication_failure(); } break; /* State */ /*********/ case HDCP_LINK_INTEGRITY_CHECK: /* Ri failure */ if (event == HDCP_RI_FAIL_EVENT) { printk(KERN_INFO "HDCP: Ri check failure\n"); hdcp_wq_authentication_failure(); } break; default: printk(KERN_WARNING "HDCP: error - unknow HDCP state\n"); break; } kfree(hdcp_w); hdcp_w = 0; if (event == HDCP_START_FRAME_EVENT) hdcp.pending_start = 0; if (event == HDCP_KSV_LIST_RDY_EVENT || event == HDCP_R0_EXP_EVENT) { hdcp.pending_wq_event = 0; } DBG("hdcp_work_queue() - END - %u hdmi=%d hdcp=%d auth=%d evt=%x %d ", jiffies_to_msecs(jiffies), hdcp.hdmi_state, hdcp.hdcp_state, hdcp.auth_state, (event & 0xFF00) >> 8, event & 0xFF); hdcp_release_dss(); mutex_unlock(&hdcp.lock); }
/*----------------------------------------------------------------------------- * 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); }