/* int init_module(void) */ int can_init(void) { int i; #if LDDK_USE_BLKREQUEST extern int Can_request (); #endif DBGin("init_module"); printk("Init can\n"); //while(1); #ifdef LDDK_USE_REGISTER if( register_chrdev(Can_major, "Can", &can_fops) ) { printk("can't get Major %d\n", Can_major); return(-EIO); } #endif { printk("CAN Driver for Open Cores CAN MAC (c) " __DATE__ " " __TIME__ "\n"); //printk(__CAN_TYPE__ "CAN Driver " VERSION " (c) " __DATE__ " " __TIME__ "\n"); printk(" H. Obereder (gleichmann)\n"); /* printk(" H.J. Oertel ([email protected])\n");*/ /* printk(" C.Schroeter ([email protected]), H.D. Stich\n"); */ } /* initialize the variables layed down in /proc/sys/Can */ for (i = 0; i < MAX_CHANNELS; i++) { IOModel[i] = IO_MODEL; Baud[i] = 500; AccCode[i] = AccMask[i] = STD_MASK; Timeout[i] = 100; Outc[i] = CAN_OUTC_VAL; IRQ_requested[i] = 0; Can_minors[i] = i; /* used as IRQ dev_id */ /*Byte access for LEON3 Sparc */ /*changed by hobe */ #define LEON3 1 #ifdef LEON3 Base[i] = (0xFFFC0000); IRQ[i] = 13; #endif #if defined(MCF5282) /* we have a really fixed address here */ Base[i] = (MCF_MBAR + 0x1c0000); /* Because the MCF FlexCAN is using more then 1 Interrupt vector, * what should be specified here ? * For information purpose let's only specify the first used here */ IRQ[i] = 136; #endif #if defined(CCPC104) pc104_irqsetup(); IRQ[i] = 67; /* The only possible vector on CTRLink's 5282 CPU */ Base[i] = 0x40000280; #endif } /* after initializing channel based parameters * finisch some entries * and do drivers specific initialization */ IOModel[i] = '\0'; /* CAN_register_dump(); */ #if CAN4LINUX_PCI /* make some sysctl entries read only * IRQ number * Base address * and access mode * are fixed and provided by the PCI BIOS */ Can_sysctl_table[SYSCTL_IRQ - 1].mode = 0444; Can_sysctl_table[SYSCTL_BASE - 1].mode = 0444; /* printk("CAN pci test loaded\n"); */ /* dbgMask = 0; */ pcimod_scan(); #endif #if defined(CCPC104) /* The only possible interrupt could be IRQ4 on the PC104 Board */ Can_sysctl_table[SYSCTL_IRQ - 1].mode = 0444; #endif #if defined(MCF5282) Can_sysctl_table[SYSCTL_BASE - 1].mode = 0444; #endif /* #if LDDK_USE_PROCINFO */ /* #error procinfo */ /* register_procinfo(); */ /* #endif */ /* #if LDDK_USE_SYSCTL */ register_systables(); /* #endif */ #if LDDK_USE_BLKREQUEST blk_dev[Can_major].request_fn = Can_request ; #endif DBGout(); return 0; }
int Can_RequestIrq(int minor, int irq, irqservice_t handler) { int err=0; DBGin("Can_RequestIrq"); /* int request_irq(unsigned int irq, // interrupt number void (*handler)(int, void *, struct pt_regs *), // pointer to ISR irq, dev_id, registers on stack unsigned long irqflags, const char *devname, void *dev_id); dev_id - The device ID of this handler (see below). This parameter is usually set to NULL, but should be non-null if you wish to do IRQ sharing. This doesn't matter when hooking the interrupt, but is required so that, when free_irq() is called, the correct driver is unhooked. Since this is a void *, it can point to anything (such as a device-spe cific structure, or even empty space), but make sure you pass the same pointer to free_irq(). */ #if defined(CONFIG_PPC) /* LINUX_PPC */ err = request_8xxirq( irq, handler, 0, "Can", NULL ); #elif defined(MCF5282) { int i; /* 19 Int vectors are used on Interrupt Controller 1 */ for( i = 136; i < 155; i++) { err = request_irq( i, handler, SA_SHIRQ, "Can", &Can_minors[minor]); if(err) { DBGout();return err; } } } #else err = request_irq( irq, handler, SA_SHIRQ, "Can", &Can_minors[minor]); #endif if( !err ){ /* printk("Requested IRQ[%d]: %d @ 0x%x", minor, irq, handler); */ /* Now the kernel has assigned a service to the Interruptvector, time to enable the hardware to genearte an ISR. here should be used a generic function e.g. can_irqsetup(minor) and do whatever needed for the app. hardware to reduce #ifdef clutter */ #if defined(CCPC104) pc104_irqsetup(); #endif #if defined(MCF5282) mcf_irqsetup(); #endif irq2minormap[irq] = minor; irq2pidmap[irq] = current->pid; DBGprint(DBG_BRANCH,("Requested IRQ: %d @ 0x%lx", irq, (unsigned long)handler)); IRQ_requested[minor] = 1; } DBGout();return err; }
/* int init_module(void) */ static int __init can_init(void) { int i; #if LDDK_USE_BLKREQUEST extern int Can_request (); #endif DBGin("init_module"); #ifdef CONFIG_DEVFS_FS devfs_mk_cdev (MKDEV(Can_MAJOR, 0), S_IRUSR | S_IWUSR | S_IFCHR, "can0", 0); #endif #if LDDK_USE_REGISTER if( register_chrdev(Can_major, "can", &can_fops) ) { printk("can't get Major %d\n", Can_major); return(-EIO); } #endif { printk(__CAN_TYPE__ "CAN Driver " VERSION " (c) " __DATE__ " " __TIME__ "\n"); } /* initialize the variables layed down in /proc/sys/Can */ for (i = 0; i < MAX_CHANNELS; i++) { IOModel[i] = IO_MODEL; Baud[i] = 125; AccCode[i] = AccMask[i] = STD_MASK; Timeout[i] = 100; Outc[i] = CAN_OUTC_VAL; IRQ_requested[i] = 0; Can_minors[i] = i; /* used as IRQ dev_id */ #if defined(CONFIG_FIRE_ENGINE) /* we have a really fixed address here */ Base[i] = (MCF_MBAR + 0xa000 + CAN_MODULE*(0x0800)); /* Because the MCF FlexCAN is using more then 1 Interrupt vector, * what should be specified here ? * For information purpose let's only specify the first used here */ IRQ[i] = 64 + ISC_CANn_MBOR(CAN_MODULE); #endif #if defined(CONFIG_M528x) Base[i] = (MCF_MBAR + 0x1c0000); IRQ[i] = 136; #endif #if defined(CONFIG_M532x) /* we have a really fixed address here */ Base[i] = MCF_FLEXCAN_BASEADDR(CAN_MODULE); /* Because the MCF FlexCAN is using more then 1 Interrupt vector, * what should be specified here ? * For information purpose let's only specify the first used here */ IRQ[i] = 128; /* Enable GPIO pins for CANTX, CANRX */ #if defined(CONFIG_M5329EVB) /* On Freescale 5329 EVB CAN pins are muxed with I2C pins */ MCF_GPIO_PAR_FECI2C &= 0xF0; MCF_GPIO_PAR_FECI2C |= MCF_GPIO_PAR_FECI2C_PAR_SDA(0x2) | MCF_GPIO_PAR_FECI2C_PAR_SCL(0x2); #elif defined(CONFIG_UC532X) || defined(CONFIG_UC53281EVM) #ifdef CONFIG_PAR_LCDDATA_FOR_CAN /* we may use these pins for CAN signal */ MCF_GPIO_PAR_LCDDATA &= 0x0F; MCF_GPIO_PAR_LCDDATA |= MCF_GPIO_PAR_LCDDATA_PAR_LD17(0x2) | MCF_GPIO_PAR_LCDDATA_PAR_LD16(0x2); #else MCF_GPIO_PAR_FECI2C &= 0xF0; MCF_GPIO_PAR_FECI2C |= MCF_GPIO_PAR_FECI2C_PAR_SDA(0x2) | MCF_GPIO_PAR_FECI2C_PAR_SCL(0x2); #endif #else /* Could be changed for other boards. Depends on board design */ MCF_GPIO_PDDR_SSI = 0; MCF_GPIO_PAR_SSI = MCF_GPIO_PAR_SSI_PAR_RXD(0x1) | MCF_GPIO_PAR_SSI_PAR_TXD(0x1); #endif #endif #if defined(CONFIG_M5253EVB) /* we have a really fixed address here */ Base[i] = MCF_FLEXCAN_BASEADDR(i); /* Because the MCF FlexCAN is using more then 1 Interrupt vector, * what should be specified here ? * For information purpose let's only specify the first used here */ IRQ[i] = 128 + i; #endif #if defined(CCPC104) pc104_irqsetup(); IRQ[i] = 67; /* The only possible vector on CTRLink's 5282 CPU */ Base[i] = 0x40000280; #endif } /* after initializing channel based parameters * finisch some entries * and do drivers specific initialization */ IOModel[i] = '\0'; /* CAN_register_dump(); */ #if CAN4LINUX_PCI /* make some sysctl entries read only * IRQ number * Base address * and access mode * are fixed and provided by the PCI BIOS */ Can_sysctl_table[SYSCTL_IRQ - 1].mode = 0444; Can_sysctl_table[SYSCTL_BASE - 1].mode = 0444; /* printk("CAN pci test loaded\n"); */ /* dbgMask = 0; */ pcimod_scan(); #endif #if defined(CCPC104) /* The only possible interrupt could be IRQ4 on the PC104 Board */ Can_sysctl_table[SYSCTL_IRQ - 1].mode = 0444; #endif #if defined(CONFIG_FIRE_ENGINE) Can_sysctl_table[SYSCTL_BASE - 1].mode = 0444; #endif #if defined(CONFIG_M532x) || defined(CONFIG_M5253) || defined(CONFIG_M528x) Can_sysctl_table[SYSCTL_BASE - 1].mode = 0444; #endif #if LDDK_USE_PROCINFO /* #error procinfo */ register_procinfo(); #endif #if LDDK_USE_SYSCTL register_systables(); #endif #if LDDK_USE_BLKREQUEST blk_dev[Can_major].request_fn = Can_request; #endif DBGout(); return 0; }