in cadence_master.c [865:947]
irqreturn_t sdw_cdns_irq(int irq, void *dev_id)
{
struct sdw_cdns *cdns = dev_id;
u32 int_status;
/* Check if the link is up */
if (!cdns->link_up)
return IRQ_NONE;
int_status = cdns_readl(cdns, CDNS_MCP_INTSTAT);
/* check for reserved values read as zero */
if (int_status & CDNS_MCP_INT_RESERVED)
return IRQ_NONE;
if (!(int_status & CDNS_MCP_INT_IRQ))
return IRQ_NONE;
if (int_status & CDNS_MCP_INT_RX_WL) {
cdns_read_response(cdns);
if (cdns->defer) {
cdns_fill_msg_resp(cdns, cdns->defer->msg,
cdns->defer->length, 0);
complete(&cdns->defer->complete);
cdns->defer = NULL;
} else {
complete(&cdns->tx_complete);
}
}
if (int_status & CDNS_MCP_INT_PARITY) {
/* Parity error detected by Master */
dev_err_ratelimited(cdns->dev, "Parity error\n");
}
if (int_status & CDNS_MCP_INT_CTRL_CLASH) {
/* Slave is driving bit slot during control word */
dev_err_ratelimited(cdns->dev, "Bus clash for control word\n");
}
if (int_status & CDNS_MCP_INT_DATA_CLASH) {
/*
* Multiple slaves trying to drive bit slot, or issue with
* ownership of data bits or Slave gone bonkers
*/
dev_err_ratelimited(cdns->dev, "Bus clash for data word\n");
}
if (cdns->bus.params.m_data_mode != SDW_PORT_DATA_MODE_NORMAL &&
int_status & CDNS_MCP_INT_DPINT) {
u32 port_intstat;
/* just log which ports report an error */
port_intstat = cdns_readl(cdns, CDNS_MCP_PORT_INTSTAT);
dev_err_ratelimited(cdns->dev, "DP interrupt: PortIntStat %8x\n",
port_intstat);
/* clear status w/ write1 */
cdns_writel(cdns, CDNS_MCP_PORT_INTSTAT, port_intstat);
}
if (int_status & CDNS_MCP_INT_SLAVE_MASK) {
/* Mask the Slave interrupt and wake thread */
cdns_updatel(cdns, CDNS_MCP_INTMASK,
CDNS_MCP_INT_SLAVE_MASK, 0);
int_status &= ~CDNS_MCP_INT_SLAVE_MASK;
/*
* Deal with possible race condition between interrupt
* handling and disabling interrupts on suspend.
*
* If the master is in the process of disabling
* interrupts, don't schedule a workqueue
*/
if (cdns->interrupt_enabled)
schedule_work(&cdns->work);
}
cdns_writel(cdns, CDNS_MCP_INTSTAT, int_status);
return IRQ_HANDLED;
}