/******************************************************************* * vflash_isr: the interrupt handler for dqm messages ******************************************************************/ static irqreturn_t vflash_isr(int irq, void *unused) { MsgStruct rxMsg; while (hostDqmGetMessage(&rxMsg, dqmchannel.dqmRxHandle)) { ItcRpcMsg *rpcMsg = (ItcRpcMsg *)&rxMsg.msgData[0]; RpcMsgQueue *msg = extract_from_msg_queue(rpcMsg->xid); if (msg) { #if DEBUG_DQM_IO if (irq == -1) printk("%s: extracted %08x\n", __func__, rpcMsg->xid); #endif memcpy(msg->response, rpcMsg, sizeof(ItcRpcMsg)); up(msg->sema); } else { printk("%s: unable to find message id %08x\n", __func__, (unsigned int)rpcMsg->xid); dump_msg_queue(); } } hostDqmEnableDqmQInt(dqmchannel.dqmRxHandle); enable_brcm_irq(INTERRUPT_ID_VFLASH); return IRQ_HANDLED; }
static unsigned int startup_brcm_irq(unsigned int irq) { enable_brcm_irq(irq); return 0; /* never anything pending */ }
/* Control functions for linux IRQ8 and above */ static INLINE void enable_brcm_irq2(unsigned int irq) { ASSERT(irq2en >= 0); if (irq2en++) return; enable_brcm_irq(2); }
int do_rpc_io(ItcRpcMsg *req) { static DEFINE_SPINLOCK(io_lock); unsigned long flags; MsgStruct msgBuf; ItcRpcMsg response; RpcMsgQueue msgQueueItem; int timeout_cnt = 0; DECLARE_MUTEX(sema); // Construct a message memset((void *)&msgBuf, 0, sizeof(MsgStruct)); msgBuf.msgLen = sizeof(ItcRpcMsg)/4; memcpy((void *)&msgBuf.msgData[0], (void *)req, sizeof(ItcRpcMsg)); #if DEBUG_DQM_IO printk(">>>> %s %08lx %08lx %08lx %08lx\n", __func__, msgBuf.msgData[0], msgBuf.msgData[1], msgBuf.msgData[2], msgBuf.msgData[3]); #endif memset(&response, 0, sizeof(response)); msgQueueItem.xid = req->xid; msgQueueItem.response = &response; msgQueueItem.sema = &sema; msgQueueItem.next = NULL; add_to_msg_queue(&msgQueueItem); down(&sema); spin_lock_irqsave(&io_lock, flags); if(hostDqmSendMessage(&msgBuf, dqmchannel.dqmTxHandle)) { printk("%s:%d - Can not send rpc message!\n", __func__, __LINE__); spin_unlock_irqrestore(&io_lock, flags); return -1; } hostDqmEnableDqmQInt(dqmchannel.dqmRxHandle); spin_unlock_irqrestore(&io_lock, flags); enable_brcm_irq(INTERRUPT_ID_VFLASH); while (down_timeout(&sema, rpc_io_timeout)) { timeout_cnt++; vflash_isr(-1, NULL); if (timeout_cnt >= 60) { dump_msg_queue(); extract_from_msg_queue(msgQueueItem.xid); return -ETIMEDOUT; } else if ((timeout_cnt >= RPC_TIMEOUT_RESEND_CNT) && (timeout_cnt % RPC_TIMEOUT_RESEND_CNT == 0)) { printk("%s: TIMEOUT resending %08lx\n", __func__, msgQueueItem.xid); spin_lock_irqsave(&io_lock, flags); if(hostDqmSendMessage(&msgBuf, dqmchannel.dqmTxHandle)) { printk("%s:%d - Can not send rpc message!\n", __func__, __LINE__); spin_unlock_irqrestore(&io_lock, flags); return -1; } spin_unlock_irqrestore(&io_lock, flags); } } #if DEBUG_DQM_IO if (timeout_cnt) { printk("%s: %d timeouts but I got a reply for msg %08lx\n", __func__, timeout_cnt, msgQueueItem.xid); } #endif return response.u0; }
static void end_brcm_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) enable_brcm_irq(irq); }