static int tvme200_request_irq(struct ipack_device *dev, irqreturn_t (*handler)(void *), void *arg) { int res = 0; struct slot_irq *slot_irq; struct tvme200_board *tvme200; void *irq_reg; tvme200 = check_slot(dev); if (tvme200 == NULL) return -EINVAL; if (mutex_lock_interruptible(&tvme200->mutex)) return -ERESTARTSYS; if (tvme200->slots[dev->slot].irq != NULL) { dev_err(&dev->dev, "Slot [%d:%d] IRQ already registered !\n", dev->bus->bus_nr, dev->slot); res = -EINVAL; goto out_unlock; } slot_irq = kzalloc(sizeof(struct slot_irq), GFP_KERNEL); if (slot_irq == NULL) { dev_err(&dev->dev, "Slot [%d:%d] unable to allocate memory for IRQ !\n", dev->bus->bus_nr, dev->slot); res = -ENOMEM; goto out_unlock; } /* * WARNING: Setup Interrupt Vector in the IndustryPack device * before an IRQ request. * Read the User Manual of your IndustryPack device to know * where to write the vector in memory. */ slot_irq->vector = irq[(4 * tvme200->number) + dev->slot]; slot_irq->handler = (int (*)(void *))(handler); /* FIXME: ugly casting, its ok? */ slot_irq->arg = arg; slot_irq->holder = dev; sprintf(slot_irq->name, "ipackdev_%d_%d", tvme200->lun, dev->slot); rcu_assign_pointer(tvme200->slots[dev->slot].irq, slot_irq); irq_reg = ioremap_nocache(tvme200->mod_mem[IPACK_INT_SPACE] + TVME200_INT_SPACE_INTERVAL * dev->slot, TVME200_ID_SPACE_SIZE); iowrite8(slot_irq->vector, irq_reg); res = vme_request_irq(slot_irq->vector, slot_irq->handler, slot_irq->arg, slot_irq->name); out_unlock: mutex_unlock(&tvme200->mutex); return res; }
int register_isr(struct vmeio_device *dev, unsigned vector, unsigned level) { int err; err = vme_request_irq(vector, (int (*)(void *)) vmeio_irq, dev, DRIVER_NAME); dev->isrfl = !(err < 0); printk(PFX "ISR:Level:0x%X Vector:0x%X:%s\n", level, vector, (err < 0) ? "ERROR:NotRegistered" : "OK:Registered"); return err; }
/** * @brief User entry point in driver/simulator installation routine. * * @param proceed -- if standard code execution should be proceed * @param info -- driver info table * @param sptr -- statics table * * It's up to user to set kernel-level errno (by means of @e pseterr call). * @e proceed parameter denotes if further standard actions should be proceed * after function returns. @b FALSE - means that user-desired operation done * all that user wants and there is no further necessaty to perfom any standard * operations that follow function call. @b TRUE - means that code that follows * function call will be executed. * * @return return value is the same as in entry point function.\n * pointer to a statics data structure - if succeed.\n * SYSERR - in case of failure. */ char* GfaschannelUserInst(int *proceed, register DevInfo_t *info, register GFASCHANNELStatics_t *sptr) { GFASCHANNELUserStatics_t *usp; /* user statistics table */ int iVec = 0; /* interrupt vector */ usp = sptr->usrst; iVec = info->iVector; /* set up interrupt vector */ /* Uncomment the following code to register ISR */ #if 0 if (iVec > 0) { int cc = 0; /* completion code */ kkprintf("ISR ( vector number [%d] ) installation - ", iVec); #ifdef __Lynx__ #ifdef __powerpc__ /* in this case we are using CES BSP */ cc = vme_intset(iVec, (int (*)())GfaschannelISR, (char*)sptr, 0); #else /* use standard system call otherwise */ cc = iointset(iVec, (int (*)())GfaschannelISR, (char*)sptr); #endif #else /* __linux__ */ cc = vme_request_irq(iVec, (int (*)(void *))GfaschannelISR, (char *)sptr, "GfaschannelD"); #endif /* __Lynx__ */ if (cc < 0) { kkprintf("Failed.\n"); pseterr(EFAULT); /* TODO. what error to set? */ return (char*)SYSERR; /* -1 */ } kkprintf("interrupt vector managed.\n"); } #endif if (proceed) *proceed = TRUE; /* continue standard code execution */ return (char *)sptr; /* succeed */ }
int ctrirq_init(void) { int rc; if ((rc = vme_find_mapping(&ctr_desc, 1)) != 0) { printk(KERN_ERR PFX "Failed to map CTR_n"); return rc; } vmeaddr = ctr_desc.kernel_va; mmap = (CtrDrvrMemoryMap *) vmeaddr; ResetCtr(); EnableCtrModule(); if ((rc = vme_request_irq(CTR_IRQ_VECTOR, IntrHandler, &ctr_desc, "ctrirq")) != 0) { printk(KERN_ERR PFX "Failed to register interrupt handler\n"); goto out_unmap; } EnableCtrInterrupt(); show_ctr_info(); return 0; out_unmap: DisableCtrModule(); if (vme_release_mapping(&ctr_desc, 1) != 0) printk(KERN_WARNING PFX "Failed to release mapping on error\n"); return rc; }
/** * @brief User entry point in driver/simulator installation routine. * * @param proceed -- if standard code execution should be proceed * @param info -- driver info table * @param sptr -- statics table * * It's up to user to set kernel-level errno (by means of @e pseterr call). * @e proceed parameter denotes if further standard actions should be proceed * after function returns. @b FALSE - means that user-desired operation done * all that user wants and there is no further necessaty to perfom any standard * operations that follow function call. @b TRUE - means that code that follows * function call will be executed. * * @return return value is the same as in entry point function.\n * pointer to a statics data structure - if succeed.\n * SYSERR - in case of failure. */ char* CvorbUserInst(int *proceed, register DevInfo_t *info, register CVORBStatics_t *sptr) { CVORBUserStatics_t *usp = sptr->usrst; /* user statistics table */ int iVec = 0; /* interrupt vector */ int m, c; iVec = info->iVector; /* set up interrupt vector */ /* map submodule address pointers */ usp->md = (struct cvorb_module *)sysbrk(sizeof(_m)); usp->md[0].md = (mod *)sptr->card->block00; usp->md[1].md = (mod *)((long)sptr->card->block00 + 0x200); if (!firmware_ok(usp, info->mlun)) { sysfree((char *)usp->md, sizeof(_m)); return (char *)SYSERR; } for (m = 0; m < SMAM; m++) { /* reset subModules */ _wr(m, SOFT_PULSE, SPR_FGR); /* initialize iolock mutex */ cdcm_mutex_init(&usp->md[m].iol); /* set submodule channels addresses */ for (c = 0; c < CHAM; c++) usp->md[m].cd[c] = (chd *) ((long)usp->md[m].md + _ch_offset[c]); } /* init on-board DAC */ ad9516o_init(usp); /* disable on-board clock generator */ _wr(0, CLK_GEN_CNTL, AD9516_OFF); /* set normal mode operation, enable all channels and set recurrent cycles to 1 (i.e. play function once) */ enable_modules(usp); /* Uncomment the following code to register ISR */ #if 0 if (iVec > 0) { int cc = 0; /* completion code */ kkprintf("ISR ( vector number [%d] ) installation - ", iVec); #ifdef __Lynx__ #ifdef __powerpc__ /* in this case we are using CES BSP */ cc = vme_intset(iVec, (int (*)())CvorbISR, (char*)sptr, 0); #else /* use standard system call otherwise */ cc = iointset(iVec, (int (*)())CvorbISR, (char*)sptr); #endif #else /* __linux__ */ cc = vme_request_irq(iVec, (int (*)(void *))CvorbISR, (char *)sptr, "CvorbD"); #endif /* __Lynx__ */ if (cc < 0) { kkprintf("Failed.\n"); pseterr(EFAULT); /* TODO. what error to set? */ return (char*)SYSERR; /* -1 */ } kkprintf("interrupt vector managed.\n"); } #endif if (proceed) *proceed = TRUE; /* continue standard code execution */ return (char *)sptr; /* succeed */ }