1 /* c_can_irq.c - Hynix HMS30c7202 ARM IRQ handling code
2 * Linux CAN-bus device driver.
3 * Written by Sebastian Stolzenberg email:stolzi@sebastian-stolzenberg.de
4 * Based on code from Arnaud Westenberg email:arnaud@wanadoo.nl
5 * and Ake Hedman, eurosource, akhe@eurosource.se
6 * Rewritten for new CAN queues by Pavel Pisa - OCERA team member
7 * email:pisa@cmp.felk.cvut.cz
8 * This software is released under the GPL-License.
9 * Version lincan-0.3 17 Jun 2004
12 #include "../include/can.h"
13 #include "../include/can_sysdep.h"
14 #include "../include/main.h"
15 #include "../include/c_can.h"
19 unsigned short wdata[4];
20 unsigned char bdata[8];
26 inline void c_can_irq_read_handler( struct chip_t *pchip, int idxobj, u32 msgid );
28 inline void c_can_irq_write_handler( struct chip_t *pchip, int idxobj);
30 void c_can_irq_rtr_handler( struct chip_t *pchip, int idxobj, u32 msgid );
32 u16 readMaskCM = IFXCM_ARB | IFXCM_CNTRL | IFXCM_CLRINTPND
33 | IFXCM_TRND | IFXCM_DA | IFXCM_DB;
35 u16 msgLstReadMaskCM = IFXCM_CNTRL;
36 u16 msgLstWriteMaskCM = IFXCM_CNTRL | IFXCM_WRRD;
38 ///////////////////////////////////////////////////////////////////////////////
39 // c_can_irq_write_handler
41 // Send a message from the output fifo ( if any ).
44 inline void c_can_irq_write_handler( struct chip_t *pchip, int idxobj)
47 struct msgobj_t *pmsgobj = pchip->msgobj[idxobj];
49 DEBUGMSG("(c%dm%d)calling c_can_irq_write_handler(...)\n",
50 pchip->chip_idx, pmsgobj->object);
53 /* Do local transmitted message distribution if enabled */
55 /* fill CAN message timestamp */
56 can_filltimestamp(&pmsgobj->tx_slot->msg.timestamp);
58 pmsgobj->tx_slot->msg.flags |= MSG_LOCAL;
59 canque_filter_msg2edges(pmsgobj->qends, &pmsgobj->tx_slot->msg);
61 /* Free transmitted slot */
62 canque_free_outslot(pmsgobj->qends, pmsgobj->tx_qedge, pmsgobj->tx_slot);
63 pmsgobj->tx_slot=NULL;
66 // Get ready to send next message
67 spin_lock( &c_can_spwlock );
69 cmd=canque_test_outslot(pmsgobj->qends, &pmsgobj->tx_qedge, &pmsgobj->tx_slot);
71 DEBUGMSG("(c%dm%d)Nothin to write\n",
72 pchip->chip_idx, pmsgobj->object);
73 spin_unlock( &c_can_spwlock );
78 if ( pchip->chipspecops->send_msg( pchip, pmsgobj,&pmsgobj->tx_slot->msg) ) {
80 canque_notify_inends(pmsgobj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_SEND);
81 canque_free_outslot(pmsgobj->qends, pmsgobj->tx_qedge, pmsgobj->tx_slot);
82 pmsgobj->tx_slot=NULL;
83 spin_unlock( &c_can_spwlock );
84 DEBUGMSG("(c%dm%d)c_can_irq_handler: Unable to send message\n",
85 pchip->chip_idx, pmsgobj->object );
88 // Another message sent
89 #ifdef CAN_WITH_STATISTICS
90 pchip->stat.cntTxPkt++;
91 pchip->stat.cntTxData += pmsgobj->tx_slot->length;
92 #endif /*CAN_WITH_STATISTICS*/
94 spin_unlock( &c_can_spwlock );
96 // Wake up any waiting writer
100 ///////////////////////////////////////////////////////////////////////////////
101 // c_can_irq_read_handler
103 // Message received form the line. Write it in the input fifo->
106 inline void c_can_irq_read_handler( struct chip_t *pchip,
107 int idxobj, u32 msgid )
112 union c_can_data readData;
113 struct msgobj_t *pmsgobj = pchip->msgobj[idxobj];
115 DEBUGMSG("(c%dm%d)calling c_can_irq_read_handler(...)\n",
116 pchip->chip_idx, pmsgobj->object);
118 while ( bDataAvail ) {
120 #ifdef CAN_WITH_STATISTICS
121 pchip->stat.cntRxFifoOvr++;
122 #endif /*CAN_WITH_STATISTICS*/
124 msgCntlReg = c_can_read_reg_w( pchip, CCIF1DMC );
126 pmsgobj->rx_msg.length = msgCntlReg & 0x000F;
129 pmsgobj->rx_msg.id = (u32)msgid;
131 // Fetch message bytes
132 if (pmsgobj->rx_msg.length > 0)
133 readData.wdata[0] = c_can_read_reg_w(pchip, CCIF1DA1);
134 if (pmsgobj->rx_msg.length > 2)
135 readData.wdata[1] = c_can_read_reg_w(pchip, CCIF1DA2);
136 if (pmsgobj->rx_msg.length > 4)
137 readData.wdata[2] = c_can_read_reg_w(pchip, CCIF1DB1);
138 if (pmsgobj->rx_msg.length > 6)
139 readData.wdata[3] = c_can_read_reg_w(pchip, CCIF1DB2);
141 for ( i=0; i < pmsgobj->rx_msg.length; i++ ) {
142 pmsgobj->rx_msg.data[ i ] = readData.bdata[i];
144 DEBUGMSG("(c%dm%d)Received Message:\n",
145 pchip->chip_idx, pmsgobj->object);
146 DEBUGMSG(" id = %ld\n",
148 DEBUGMSG(" length = %d\n",
149 pmsgobj->rx_msg.length);
150 for ( i=0; i < pmsgobj->rx_msg.length; i++ )
151 DEBUGMSG(" data[%d] = 0x%.2x\n", i, pmsgobj->rx_msg.data[i]);
153 /* fill CAN message timestamp */
154 can_filltimestamp(&pmsgobj->rx_msg.timestamp);
156 canque_filter_msg2edges(pmsgobj->qends, &pmsgobj->rx_msg);
158 #ifdef CAN_WITH_STATISTICS
159 // Another received packet
160 pchip->stat.cntRxPkt++;
162 // Add databytes read to statistics block
163 pchip->stat.cntRxData += pmsgobj->rx_msg.length;
164 #endif /*CAN_WITH_STATISTICS*/
166 spin_unlock( &c_can_sprlock );
168 // Check if new data arrived
169 if (c_can_if1_busycheck(pchip)) ;
170 c_can_write_reg_w(pchip, readMaskCM, CCIF1CM);
171 c_can_write_reg_w(pchip, idxobj+1, CCIF1CR);
172 if (c_can_if1_busycheck(pchip)) ;
173 if ( !( ( bDataAvail = c_can_read_reg_w( pchip, CCIF1DMC ) ) &
178 if ( bDataAvail & IFXMC_MSGLST ) {
179 CANMSG("(c%dm%d)c-can fifo full: Message lost!\n",
180 pchip->chip_idx, pmsgobj->object);
187 void c_can_irq_sync_activities(struct chip_t *chip, struct msgobj_t *obj)
189 while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)) {
191 /*if(can_msgobj_test_and_clear_fl(obj,TX_REQUEST)) {
192 if(canobj_read_reg(chip,obj,iMSGCTL1)&TXRQ_RES)
193 i82527_irq_write_handler(chip, obj);
197 if(can_msgobj_test_and_clear_fl(obj,FILTCH_REQUEST)) {
198 i82527_irq_update_filter(chip, obj);
201 /* FIXME: these functionality has to be implemented to start TX */
203 can_msgobj_clear_fl(obj,TX_LOCK);
204 if(can_msgobj_test_fl(obj,TX_REQUEST))
206 if(can_msgobj_test_fl(obj,FILTCH_REQUEST) && !obj->tx_slot)
213 ///////////////////////////////////////////////////////////////////////////////
217 can_irqreturn_t c_can_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
219 struct rtr_id *rtr_search = hardware_p->rtr_queue;
220 struct chip_t *pchip = (struct chip_t *)dev_id;
228 // u32 intCntrVAddr = 0;
230 //unsigned short flags = 0;
232 //if (pchip->ntype != CAN_CHIPTYPE_C_CAN) {
233 // DEBUGMSG("\n(c%d)IRQ not for c_can_irq_handler(...)\n", pchip->chip_idx);
237 irqreg = c_can_read_reg_w( pchip, CCINTR );
240 DEBUGMSG( "\n(c%d)IRQ handler: addr=%.8lx spurious interrupt\n",
242 (long)( pchip->/*v*/chip_base_addr/* + CCSR*/));
246 DEBUGMSG( "\n(c%d)IRQ handler: addr=%.8lx irqreg=0x%.4x\n",
248 (long)( pchip->/*v*/chip_base_addr/* + CCSR*/),
254 c_can_registerdump(pchip);
259 if ( (!( intCntrVAddr = (u32)ioremap( 0x80024000, 0xCD ) ))) {
260 DEBUGMSG("Failed to map Interrupt Controller IO-memory\n");
264 DEBUGMSG( "Mapped Interrupt Controller IO-memory: 0x%lx - 0x%lx to 0x%lx\n",
265 (unsigned long)0X80024000,
266 (unsigned long)0X800240CC,
267 (unsigned long)intCntrVAddr);
270 DEBUGMSG("Current Interrupt Status Register (ISR): 0x%4.4lx\n",
271 (long)readl(intCntrVAddr + 4));
272 DEBUGMSG("Current Interrupt ID: %d\n",
273 (int)(readl(intCntrVAddr + 0x90) & 0xF));
274 iounmap( (void*)intCntrVAddr);
275 DEBUGMSG( "Unmapped Interrupt Controller IO-memory: 0x%lx\n",
276 (unsigned long)intCntrVAddr);
280 // Handle change in status register
282 if ( irqreg == INT_STAT ) {
283 chip_status = c_can_read_reg_w( pchip, CCSR );
284 DEBUGMSG( "(c%d)Status register: 0x%x\n",
285 pchip->chip_idx, chip_status );
287 if ( chip_status & SR_EWARN ) {
288 // There is an abnormal # of errors
289 #ifdef CAN_WITH_STATISTICS
290 pchip->stat.cntWarnings++;
291 #endif /*CAN_WITH_STATISTICS*/
292 errcount = c_can_read_reg_w( pchip, CCEC);
293 DEBUGMSG("(c%d)stat: c_can_irq_handler: Abnormal number of Errors Warning\n"
294 " txErr=%d, rxErr=%d\n",
295 pchip->chip_idx, (errcount&0x00ff), ((errcount&0x7f00)>>8));
298 // this code deactivates the chip if the transmiterrorcounter grew above 127
299 if ((pchip->stat.cntWarnings > 100) && ((errcount&0x00ff) > 127))
301 CANMSG("(c%d)to much Errornumber warnings (>100), deactivating chip",
303 pchip->config_irqs(pchip, 0);
304 pchip->enable_configuration(pchip);
305 pchip->clear_objects(pchip);
306 pchip->flags &= ~CHANNEL_CONFIGURED;
311 if ( chip_status & SR_EPASS ) {
312 // There is an abnormal # of errors
313 #ifdef CAN_WITH_STATISTICS
314 pchip->stat.cntErrPassive++;
315 #endif /*CAN_WITH_STATISTICS*/
316 DEBUGMSG("(c%d)stat: c_can_irq_handler: Chip entering Error Passive Mode\n",
320 if ( chip_status & SR_BOFF ) {
321 // We have a bus off condition
322 #ifdef CAN_WITH_STATISTICS
323 pchip->stat.cntBusOff++;
324 #endif /*CAN_WITH_STATISTICS*/
325 //pchip->fifo->tx_in_progress = 0;
327 CANMSG("(c%d)stat: c_can_irq_handler: Bus Off\n",
329 /*if (pchip->stat.cntBusOff > 100)
331 CANMSG("(c%d)to much busoff warnings (>100), deactivating chip",
333 pchip->config_irqs(pchip, 0);
334 pchip->enable_configuration(pchip);
335 pchip->clear_objects(pchip);
336 pchip->flags &= ~CHANNEL_CONFIGURED;
340 CANMSG("(c%d)try to reconnect",
342 pchip->chipspecops->disable_configuration(pchip);
345 if (chip_status & SR_TXOK) {
346 DEBUGMSG("(c%d)stat: Transmitted a Message successfully\n",
348 c_can_write_reg_w(pchip, chip_status & ~SR_TXOK, CCSR);
351 if (chip_status & SR_RXOK) {
352 DEBUGMSG("(c%d)stat: Received a Message successfully\n",
354 c_can_write_reg_w(pchip, chip_status & ~SR_RXOK, CCSR);
357 #ifdef CAN_WITH_STATISTICS
358 // Errors to statistics
359 switch( chip_status & 0x07 )
361 case SRLEC_NE: // No error
363 case SRLEC_SE: // Stuff error
364 pchip->stat.cntStuffErr++;
366 case SRLEC_FE: // Form error
367 pchip->stat.cntFormErr++;
369 case SRLEC_AE: // Ack error
370 pchip->stat.cntAckErr++;
372 case SRLEC_B1: // Bit 1 error
373 pchip->stat.cntBit1Err++;
375 case SRLEC_B0: // Bit 0 error
376 pchip->stat.cntBit0Err++;
378 case SRLEC_CR: // CRC error
379 pchip->stat.cntCrcErr++;
384 #endif /*CAN_WITH_STATISTICS*/
385 //return; // continue?
387 if (irqreg >0 && irqreg <33) {
388 struct msgobj_t *pmsgobj;
393 pmsgobj=pchip->msgobj[idxobj];
395 //DEBUGMSG( "Interrupt handler: addr=%lx devid=%lx irqreq=%x status=0x%x\n",
396 // (unsigned long)pchip->vbase_addr + iIRQ,
397 // (unsigned long)dev_id,
401 spin_lock( &c_can_if1lock );
404 if (c_can_if1_busycheck(pchip)) ; /*??????????*/
405 c_can_write_reg_w(pchip, msgLstReadMaskCM, CCIF1CM);
406 c_can_write_reg_w(pchip, idxobj+1, CCIF1CR);
408 if (c_can_if1_busycheck(pchip)) ; /*??????????*/
409 tempCntlReg = c_can_read_reg_w( pchip, CCIF1DMC );
411 if (tempCntlReg & IFXMC_MSGLST) {
412 CANMSG("(c%dm%d)Chip lost a message\n",
413 pchip->chip_idx, pmsgobj->object);
414 #ifdef CAN_WITH_STATISTICS
415 pchip->stat.cntMsgLst++;
416 #endif /*CAN_WITH_STATISTICS*/
418 //Reset Message Lost Bit
419 tempCntlReg = tempCntlReg & (~IFXMC_MSGLST);
420 c_can_write_reg_w(pchip, tempCntlReg, CCIF1DMC);
421 c_can_write_reg_w(pchip, msgLstWriteMaskCM, CCIF1CM);
422 c_can_write_reg_w(pchip, idxobj+1, CCIF1CR);
425 //transfer Message Object to IF1 Buffer
426 if (c_can_if1_busycheck(pchip)) ;
427 c_can_write_reg_w(pchip, readMaskCM, CCIF1CM);
428 c_can_write_reg_w(pchip, idxobj+1, CCIF1CR);
430 if (c_can_if1_busycheck(pchip)) ;
431 if (c_can_read_reg_w(pchip, CCIF1A2) & IFXARB2_DIR) {
432 spin_unlock( &c_can_if1lock );
433 c_can_irq_write_handler(pchip,idxobj);
435 if (can_msgobj_test_fl(pmsgobj,RX_MODE_EXT)) {
436 id0=c_can_read_reg_w(pchip, CCIF1A1);
437 id1=(c_can_read_reg_w(pchip, CCIF1A2)&0x1FFF)<<16;
440 msgid=((c_can_read_reg_w(pchip, CCIF1A2)&0x1FFC)>>2)&0x7FF;
442 spin_unlock( &c_can_if1lock );
444 spin_lock(&hardware_p->rtr_lock);
445 while ( rtr_search != NULL )
447 if ( rtr_search->id == msgid ) {
450 rtr_search = rtr_search->next;
452 spin_unlock(&hardware_p->rtr_lock);
454 spin_lock( &c_can_if1lock );
456 //transfer Message Object to IF1 Buffer
457 if (c_can_if1_busycheck(pchip)) ;
458 c_can_write_reg_w(pchip, readMaskCM, CCIF1CM);
459 c_can_write_reg_w(pchip, idxobj+1, CCIF1CR);
461 if (c_can_if1_busycheck(pchip)) ;
463 if ( ( rtr_search != NULL ) && (rtr_search->id == msgid ) ) {
464 c_can_irq_rtr_handler( pchip, idxobj, msgid );
466 c_can_irq_read_handler( pchip, idxobj, msgid );
468 spin_unlock( &c_can_if1lock );
476 // Get irq status again
477 irqreg = c_can_read_reg_w( pchip, CCINTR );
479 return CAN_IRQ_HANDLED;
482 ///////////////////////////////////////////////////////////////////////////////
483 // c_can_irq_rtr_handler
486 void c_can_irq_rtr_handler( struct chip_t *pchip, int idxobj, u32 msgid )
489 struct rtr_id *prtr_search = hardware_p->rtr_queue;
490 union c_can_data rtrData;
492 spin_lock( &hardware_p->rtr_lock );
494 prtr_search->rtr_message->id = msgid;
495 prtr_search->rtr_message->length =
496 ( c_can_read_reg_w( pchip, CCIF1DMC ) & 0x000f);
498 // Fetch message bytes
499 if (prtr_search->rtr_message->length > 0)
500 rtrData.wdata[0] = c_can_read_reg_w(pchip, CCIF1DA1);
501 if (prtr_search->rtr_message->length > 2)
502 rtrData.wdata[1] = c_can_read_reg_w(pchip, CCIF1DA2);
503 if (prtr_search->rtr_message->length > 4)
504 rtrData.wdata[2] = c_can_read_reg_w(pchip, CCIF1DB1);
505 if (prtr_search->rtr_message->length > 6)
506 rtrData.wdata[3] = c_can_read_reg_w(pchip, CCIF1DB2);
508 for ( i=0; i<prtr_search->rtr_message->length; i++ ) {
509 prtr_search->rtr_message->data[ i ] = rtrData.bdata[i];
512 spin_unlock( &hardware_p->rtr_lock );
513 wake_up_interruptible( &prtr_search->rtr_wq );