1,318
社区成员
发帖
与我相关
我的任务
分享
/*
仅做参考:原是一个SPI口扩展了两路mcp2515,一个驱动注册两个设备,mcp251x_count=2
*/
static int __init mcp251x_init(void)
{
int ret,i;
struct mcp251x *chip=NULL;
DEBUGMSG(DRIVER_NAME" init\n");
mcp251x_dev = kmalloc(sizeof(struct mcp251x)*mcp251x_count,GFP_KERNEL);
if (!mcp251x_dev) {
printk(KERN_WARNING "mcp251x_CAN: cannot allocate memmory for mcp251x_dev");
ret = -1;
goto err_kmalloc_mcp251x_dev;
}
alloc_chrdev_region(&mcp251x_dev_major,0, mcp251x_count, DRIVER_NAME);
cclass = class_create(THIS_MODULE, DRIVER_NAME);
for (i=0; i< mcp251x_count; i++) {
chip = &mcp251x_dev[i];
chip->dev = i;//minor device number
chip->f_osc = CANFOSC;
cdev_init(&chip->cdev, &mcp251x_fops);
chip->cdev.owner = THIS_MODULE;
chip->cdev.ops = &mcp251x_fops;
ret = cdev_add (&chip->cdev, MKDEV(MAJOR(mcp251x_dev_major), i), 1);
if (ret)
printk (KERN_NOTICE "Error %d adding can_lpc2xxx\n", ret);
sprintf(chip->name, DRIVER_NAME"%d", i+1);
if (device_create(cclass, NULL, MKDEV(MAJOR(mcp251x_dev_major), i),
chip, DRIVER_NAME"%d",i+1) == NULL) {
printk(KERN_WARNING "fail to create device %s %d \n",__FILE__,__LINE__);
}
chip->can_available = (atomic_t)ATOMIC_INIT(1);
chip->spi_transfer_buf = kmalloc(SPI_TRANSFER_BUF_LEN, GFP_KERNEL);
if (!chip->spi_transfer_buf) {
ret = -ENOMEM;
goto error_buf;
}
/*init receive FIFO*/
//chip->RxFIFO.fadd = 0;
//chip->RxFIFO.fremove = 0;
(chip->RxFIFO).count = 0;
(chip->RxFIFO).wp = 0;
(chip->RxFIFO).rp = 0;
(chip->RxFIFO).buf = kmalloc(sizeof(struct canmsg_t)*CAN_CIRBUF_SIZE,GFP_KERNEL);
spin_lock_init(&chip->RxFIFO.flock);
if ( !(chip->RxFIFO).buf) {
printk(KERN_WARNING "mcp251x_CAN: cannot allocate memmory for receive FIFO buffer");
ret = -1;
goto err_kmalloc_buf;
}
/*init Transimit FIFO*/
//chip->TxFIFO.fadd = 0;
//chip->TxFIFO.fremove = 0;
(chip->TxFIFO).count = 0;
(chip->TxFIFO).wp = 0;
(chip->TxFIFO).rp = 0;
(chip->TxFIFO).buf = kmalloc(sizeof(struct canmsg_t)*CAN_TXDBUF_SIZE,GFP_KERNEL);
spin_lock_init(&chip->lock);
spin_lock_init(&chip->TxFIFO.flock);
if ( !(chip->TxFIFO).buf) {
printk(KERN_WARNING "mcp251x_CAN: cannot allocate memmory for transimit FIFO buffer");
ret = -1;
goto err_kmalloc_buf;
}
if (i == 0) {
set_irq_type(IRQ0_GPIO_NAME, IRQ_TYPE_EDGE_FALLING);
__raw_writel(PIO_DIR_GPIO(IRQ0_GPIO), GPIO_P2_DIR_CLR(GPIO_IOBASE));//GPIO_00 as input
chip->irq=IRQ0_GPIO_NAME;
ret = request_irq(chip->irq, mcp251x_can1_irq, IRQF_DISABLED|IRQF_TRIGGER_FALLING,DRIVER_NAME, NULL);
if (ret < 0) {
dev_err(&chip->sdev, "request irq %d failed (ret = %d)\n", chip->irq, ret);
goto error_irq;
}
} else if (i == 1) {
set_irq_type(IRQ1_GPIO_NAME, IRQ_TYPE_EDGE_FALLING);
__raw_writel(PIO_DIR_GPIO(IRQ1_GPIO), GPIO_P2_DIR_CLR(GPIO_IOBASE));//GPIO_01 as input
chip->irq=IRQ1_GPIO_NAME;
ret = request_irq(chip->irq, mcp251x_can2_irq, IRQF_DISABLED|IRQF_TRIGGER_FALLING,DRIVER_NAME, NULL);
if (ret < 0) {
dev_err(&chip->sdev, "request irq %d failed (ret = %d)\n", chip->irq, ret);
goto error_irq;
}
} else {
goto error_irq;
}
lpc32xx_gpio_irq_set(i,Disable);
}
mcp251x_hw_init();
for (i=0; i<mcp251x_count; i++) {
mcp251x_set_bit_rate(i, 20000);
}
DEBUGMSG("%s init sucess", DRIVER_NAME);
return 0;
error_irq:
DEBUGMSG("error_irq");
error_buf:
DEBUGMSG("error_buf");
err_kmalloc_buf:
DEBUGMSG("err_kmalloc_buf");
while (i > 0) {
i--;
kfree((mcp251x_dev[i].RxFIFO).buf);
kfree((mcp251x_dev[i].TxFIFO).buf);
}
kfree(mcp251x_dev);
err_kmalloc_mcp251x_dev:
DEBUGMSG("err_kmalloc_mcp251x_dev");
printk(KERN_WARNING "mcp251x_can init FAILURE\n");
return ret;
}