dp: Guard interrupts against uninitialized callbacks.
If an interrupt occurs without a user defined callback, don't invoke the function. Otherwise, unexpected behavior will be seen due to running code from 0x0 (NULL). Prior to this, it was the responsibility of the user to ensure all callbacks for interrupts were set. Signed-off-by: Andrei-Liviu Simion <andrei.simion@xilinx.com> Reviewed-by: Hyun Kwon <hyun.kwon@xilinx.com>
This commit is contained in:
parent
83cfd59989
commit
0e5f54a853
1 changed files with 54 additions and 27 deletions
|
@ -45,6 +45,7 @@
|
|||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.0 als 01/20/15 Initial release. TX code merged from the dptx driver.
|
||||
* 2.0 als 06/08/15 Added MST interrupt handlers for RX.
|
||||
* Guard against uninitialized callbacks.
|
||||
* Added HDCP interrupts.
|
||||
* Added unplug interrupt.
|
||||
* </pre>
|
||||
|
@ -991,11 +992,12 @@ static void XDp_TxInterruptHandler(XDp *InstancePtr)
|
|||
HpdPulseDetected = IntrStatus &
|
||||
XDP_TX_INTERRUPT_STATUS_HPD_PULSE_DETECTED_MASK;
|
||||
|
||||
if (HpdEventDetected) {
|
||||
if (HpdEventDetected && InstancePtr->TxInstance.HpdEventHandler) {
|
||||
InstancePtr->TxInstance.HpdEventHandler(
|
||||
InstancePtr->TxInstance.HpdEventCallbackRef);
|
||||
}
|
||||
else if (HpdPulseDetected && XDp_TxIsConnected(InstancePtr)) {
|
||||
else if (HpdPulseDetected && XDp_TxIsConnected(InstancePtr) &&
|
||||
InstancePtr->TxInstance.HpdPulseHandler) {
|
||||
/* The source device must debounce the incoming HPD signal by
|
||||
* sampling the value at an interval greater than 0.500 ms. An
|
||||
* HPD pulse should be of width 0.5 ms - 1.0 ms. */
|
||||
|
@ -1037,27 +1039,32 @@ static void XDp_RxInterruptHandler(XDp *InstancePtr)
|
|||
XDP_RX_INTERRUPT_MASK);
|
||||
|
||||
/* Training pattern 1 has started. */
|
||||
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_TP1_MASK) {
|
||||
if ((IntrStatus & XDP_RX_INTERRUPT_CAUSE_TP1_MASK) &&
|
||||
InstancePtr->RxInstance.IntrTp1Handler) {
|
||||
InstancePtr->RxInstance.IntrTp1Handler(
|
||||
InstancePtr->RxInstance.IntrTp1CallbackRef);
|
||||
}
|
||||
/* Training pattern 2 has started. */
|
||||
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_TP2_MASK) {
|
||||
if ((IntrStatus & XDP_RX_INTERRUPT_CAUSE_TP2_MASK) &&
|
||||
InstancePtr->RxInstance.IntrTp2Handler) {
|
||||
InstancePtr->RxInstance.IntrTp2Handler(
|
||||
InstancePtr->RxInstance.IntrTp2CallbackRef);
|
||||
}
|
||||
/* Training pattern 3 has started. */
|
||||
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_TP3_MASK) {
|
||||
if ((IntrStatus & XDP_RX_INTERRUPT_CAUSE_TP3_MASK) &&
|
||||
InstancePtr->RxInstance.IntrTp3Handler) {
|
||||
InstancePtr->RxInstance.IntrTp3Handler(
|
||||
InstancePtr->RxInstance.IntrTp3CallbackRef);
|
||||
}
|
||||
/* Training lost - the link has been lost. */
|
||||
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_TRAINING_LOST_MASK) {
|
||||
if ((IntrStatus & XDP_RX_INTERRUPT_CAUSE_TRAINING_LOST_MASK) &&
|
||||
InstancePtr->RxInstance.IntrTrainingLostHandler) {
|
||||
InstancePtr->RxInstance.IntrTrainingLostHandler(
|
||||
InstancePtr->RxInstance.IntrTrainingLostCallbackRef);
|
||||
}
|
||||
/* The link has been trained. */
|
||||
else if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_TRAINING_DONE_MASK) {
|
||||
else if ((IntrStatus & XDP_RX_INTERRUPT_CAUSE_TRAINING_DONE_MASK) &&
|
||||
InstancePtr->RxInstance.IntrTrainingDoneHandler) {
|
||||
InstancePtr->RxInstance.IntrTrainingDoneHandler(
|
||||
InstancePtr->RxInstance.IntrTrainingDoneCallbackRef);
|
||||
}
|
||||
|
@ -1066,72 +1073,84 @@ static void XDp_RxInterruptHandler(XDp *InstancePtr)
|
|||
* link as indicated by the main stream attributes (MSA) fields. The
|
||||
* horizontal and vertical resolution parameters are monitored for
|
||||
* changes. */
|
||||
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_VM_CHANGE_MASK) {
|
||||
if ((IntrStatus & XDP_RX_INTERRUPT_CAUSE_VM_CHANGE_MASK) &&
|
||||
InstancePtr->RxInstance.IntrVmChangeHandler) {
|
||||
InstancePtr->RxInstance.IntrVmChangeHandler(
|
||||
InstancePtr->RxInstance.IntrVmChangeCallbackRef);
|
||||
}
|
||||
/* The VerticalBlanking_Flag in the VB-ID field of the received stream
|
||||
* indicates the start of the vertical blanking interval. */
|
||||
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_VBLANK_MASK) {
|
||||
if ((IntrStatus & XDP_RX_INTERRUPT_CAUSE_VBLANK_MASK) &&
|
||||
InstancePtr->RxInstance.IntrVBlankHandler) {
|
||||
InstancePtr->RxInstance.IntrVBlankHandler(
|
||||
InstancePtr->RxInstance.IntrVBlankCallbackRef);
|
||||
}
|
||||
/* The receiver has detected the no-video flags in the VB-ID field after
|
||||
* active video has been received. */
|
||||
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_NO_VIDEO_MASK) {
|
||||
if ((IntrStatus & XDP_RX_INTERRUPT_CAUSE_NO_VIDEO_MASK) &&
|
||||
InstancePtr->RxInstance.IntrNoVideoHandler) {
|
||||
InstancePtr->RxInstance.IntrNoVideoHandler(
|
||||
InstancePtr->RxInstance.IntrNoVideoCallbackRef);
|
||||
}
|
||||
/* A valid video frame is detected on the main link. */
|
||||
else if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_VIDEO_MASK) {
|
||||
else if ((IntrStatus & XDP_RX_INTERRUPT_CAUSE_VIDEO_MASK) &&
|
||||
InstancePtr->RxInstance.IntrVideoHandler) {
|
||||
InstancePtr->RxInstance.IntrVideoHandler(
|
||||
InstancePtr->RxInstance.IntrVideoCallbackRef);
|
||||
}
|
||||
|
||||
/* The transmitter has requested a change in the current power state of
|
||||
* the receiver core. */
|
||||
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_POWER_STATE_MASK) {
|
||||
if ((IntrStatus & XDP_RX_INTERRUPT_CAUSE_POWER_STATE_MASK) &&
|
||||
InstancePtr->RxInstance.IntrPowerStateHandler) {
|
||||
InstancePtr->RxInstance.IntrPowerStateHandler(
|
||||
InstancePtr->RxInstance.IntrPowerStateCallbackRef);
|
||||
}
|
||||
/* A change in the bandwidth has been detected. */
|
||||
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_BW_CHANGE_MASK) {
|
||||
if ((IntrStatus & XDP_RX_INTERRUPT_CAUSE_BW_CHANGE_MASK) &&
|
||||
InstancePtr->RxInstance.IntrBwChangeHandler) {
|
||||
InstancePtr->RxInstance.IntrBwChangeHandler(
|
||||
InstancePtr->RxInstance.IntrBwChangeCallbackRef);
|
||||
}
|
||||
|
||||
/* An audio info packet has been received. */
|
||||
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_INFO_PKT_MASK) {
|
||||
if ((IntrStatus & XDP_RX_INTERRUPT_CAUSE_INFO_PKT_MASK) &&
|
||||
InstancePtr->RxInstance.IntrInfoPktHandler) {
|
||||
InstancePtr->RxInstance.IntrInfoPktHandler(
|
||||
InstancePtr->RxInstance.IntrInfoPktCallbackRef);
|
||||
}
|
||||
/* An audio extension packet has been received. */
|
||||
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_EXT_PKT_MASK) {
|
||||
if ((IntrStatus & XDP_RX_INTERRUPT_CAUSE_EXT_PKT_MASK) &&
|
||||
InstancePtr->RxInstance.IntrExtPktHandler) {
|
||||
InstancePtr->RxInstance.IntrExtPktHandler(
|
||||
InstancePtr->RxInstance.IntrExtPktCallbackRef);
|
||||
}
|
||||
|
||||
/* The TX has issued a down request; a sideband message is ready. */
|
||||
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_DOWN_REQUEST_MASK) {
|
||||
if ((IntrStatus & XDP_RX_INTERRUPT_CAUSE_DOWN_REQUEST_MASK) &&
|
||||
InstancePtr->RxInstance.IntrDownReqHandler) {
|
||||
InstancePtr->RxInstance.IntrDownReqHandler(
|
||||
InstancePtr->RxInstance.IntrDownReqCallbackRef);
|
||||
}
|
||||
|
||||
/* The RX has issued a down reply. */
|
||||
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_DOWN_REPLY_MASK) {
|
||||
if ((IntrStatus & XDP_RX_INTERRUPT_CAUSE_DOWN_REPLY_MASK) &&
|
||||
InstancePtr->RxInstance.IntrDownReplyHandler) {
|
||||
InstancePtr->RxInstance.IntrDownReplyHandler(
|
||||
InstancePtr->RxInstance.IntrDownReplyCallbackRef);
|
||||
}
|
||||
|
||||
/* An audio packet overflow has occurred. */
|
||||
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_AUDIO_OVER_MASK) {
|
||||
if ((IntrStatus & XDP_RX_INTERRUPT_CAUSE_AUDIO_OVER_MASK) &&
|
||||
InstancePtr->RxInstance.IntrAudioOverHandler) {
|
||||
InstancePtr->RxInstance.IntrAudioOverHandler(
|
||||
InstancePtr->RxInstance.IntrAudioOverCallbackRef);
|
||||
}
|
||||
|
||||
/* The RX's DPCD payload allocation registers have been written for
|
||||
* allocation, de-allocation, or partial deletion. */
|
||||
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_PAYLOAD_ALLOC_MASK) {
|
||||
if ((IntrStatus & XDP_RX_INTERRUPT_CAUSE_PAYLOAD_ALLOC_MASK) &&
|
||||
InstancePtr->RxInstance.IntrPayloadAllocHandler) {
|
||||
RegVal = XDp_ReadReg(InstancePtr->Config.BaseAddr,
|
||||
XDP_RX_MST_CAP);
|
||||
RegVal |= XDP_RX_MST_CAP_VCP_UPDATE_MASK;
|
||||
|
@ -1143,44 +1162,52 @@ static void XDp_RxInterruptHandler(XDp *InstancePtr)
|
|||
}
|
||||
|
||||
/* The ACT sequence has been received. */
|
||||
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_ACT_RX_MASK) {
|
||||
if ((IntrStatus & XDP_RX_INTERRUPT_CAUSE_ACT_RX_MASK) &&
|
||||
InstancePtr->RxInstance.IntrActRxHandler) {
|
||||
InstancePtr->RxInstance.IntrActRxHandler(
|
||||
InstancePtr->RxInstance.IntrActRxCallbackRef);
|
||||
}
|
||||
|
||||
/* The CRC test has started. */
|
||||
if (IntrStatus & XDP_RX_INTERRUPT_CAUSE_CRC_TEST_MASK) {
|
||||
if ((IntrStatus & XDP_RX_INTERRUPT_CAUSE_CRC_TEST_MASK) &&
|
||||
InstancePtr->RxInstance.IntrCrcTestHandler) {
|
||||
InstancePtr->RxInstance.IntrCrcTestHandler(
|
||||
InstancePtr->RxInstance.IntrCrcTestCallbackRef);
|
||||
}
|
||||
|
||||
/* A write to one of the HDCP debug registers has been performed. */
|
||||
if (IntrStatus & XDP_RX_INTERRUPT_MASK_HDCP_DEBUG_WRITE_MASK) {
|
||||
if ((IntrStatus & XDP_RX_INTERRUPT_MASK_HDCP_DEBUG_WRITE_MASK) &&
|
||||
InstancePtr->RxInstance.IntrHdcpDbgWrHandler) {
|
||||
InstancePtr->RxInstance.IntrHdcpDbgWrHandler(
|
||||
InstancePtr->RxInstance.IntrHdcpDbgWrCallbackRef);
|
||||
}
|
||||
/* A write to the HDCP Aksv MSB register has been performed. */
|
||||
if (IntrStatus & XDP_RX_INTERRUPT_MASK_HDCP_AKSV_WRITE_MASK) {
|
||||
if ((IntrStatus & XDP_RX_INTERRUPT_MASK_HDCP_AKSV_WRITE_MASK) &&
|
||||
InstancePtr->RxInstance.IntrHdcpAksvWrHandler) {
|
||||
InstancePtr->RxInstance.IntrHdcpAksvWrHandler(
|
||||
InstancePtr->RxInstance.IntrHdcpAksvWrCallbackRef);
|
||||
}
|
||||
/* A write to the HDCP An MSB register has been performed. */
|
||||
if (IntrStatus & XDP_RX_INTERRUPT_MASK_HDCP_AN_WRITE_MASK) {
|
||||
if ((IntrStatus & XDP_RX_INTERRUPT_MASK_HDCP_AN_WRITE_MASK) &&
|
||||
InstancePtr->RxInstance.IntrHdcpAnWrHandler) {
|
||||
InstancePtr->RxInstance.IntrHdcpAnWrHandler(
|
||||
InstancePtr->RxInstance.IntrHdcpAnWrCallbackRef);
|
||||
}
|
||||
/* A write to the HDCP Ainfo MSB register has been performed. */
|
||||
if (IntrStatus & XDP_RX_INTERRUPT_MASK_HDCP_AINFO_WRITE_MASK) {
|
||||
if ((IntrStatus & XDP_RX_INTERRUPT_MASK_HDCP_AINFO_WRITE_MASK) &&
|
||||
InstancePtr->RxInstance.IntrHdcpAinfoWrHandler) {
|
||||
InstancePtr->RxInstance.IntrHdcpAinfoWrHandler(
|
||||
InstancePtr->RxInstance.IntrHdcpAinfoWrCallbackRef);
|
||||
}
|
||||
/* A read of the HDCP Ro register has been performed. */
|
||||
if (IntrStatus & XDP_RX_INTERRUPT_MASK_HDCP_RO_READ_MASK) {
|
||||
if ((IntrStatus & XDP_RX_INTERRUPT_MASK_HDCP_RO_READ_MASK) &&
|
||||
InstancePtr->RxInstance.IntrHdcpRoRdHandler) {
|
||||
InstancePtr->RxInstance.IntrHdcpRoRdHandler(
|
||||
InstancePtr->RxInstance.IntrHdcpRoRdCallbackRef);
|
||||
}
|
||||
/* A read of the HDCP Binfo register has been performed. */
|
||||
if (IntrStatus & XDP_RX_INTERRUPT_MASK_HDCP_BINFO_READ_MASK) {
|
||||
if ((IntrStatus & XDP_RX_INTERRUPT_MASK_HDCP_BINFO_READ_MASK) &&
|
||||
InstancePtr->RxInstance.IntrHdcpBinfoRdHandler) {
|
||||
InstancePtr->RxInstance.IntrHdcpBinfoRdHandler(
|
||||
InstancePtr->RxInstance.IntrHdcpBinfoRdCallbackRef);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue