From: wentasah Date: Tue, 27 Apr 2004 16:28:59 +0000 (+0000) Subject: VME support is in a separate file X-Git-Tag: CLT_COMM_CAN-lincan-0_2_2~12 X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/commitdiff_plain/fc56df3494e65117cdb707f07f9d992a85d10023?ds=sidebyside VME support is in a separate file --- diff --git a/lincan/src/unican_vme.c b/lincan/src/unican_vme.c new file mode 100644 index 0000000..5075a01 --- /dev/null +++ b/lincan/src/unican_vme.c @@ -0,0 +1,117 @@ +/* unican_vme.c + * Linux CAN-bus device driver. + * Written for new CAN driver version by Pavel Pisa - OCERA team member + * email:pisa@cmp.felk.cvut.cz + * This software is released under the GPL-License. + * Version lincan-0.2 9 Jul 2003 + */ + +/* This file is included in unican.c when CAN_ENABLE_VME_SUPPORT is + * set. */ + +#include "ca91c042.h" + +#define UNICAN_VME_IRQ 1 + +/* Used to pass chip pointer to irq handler. This sould be done in VME + * bridge driver */ +#define VME_CHIPS_SIZE 8 +struct chip_t *vme_chips[VME_CHIPS_SIZE]; + +can_irqreturn_t unican_vme_irq_handler(int vmeirq, int vector, void *dev_id, struct pt_regs *regs) +{ +/* struct chip_t *chip = vme_chips[vector < VME_CHIPS_SIZE && vector >= 0 ? vector : 0]; */ + struct chip_t *chip = vme_chips[0]; + + DEBUGMSG("unican_vme_irq_handler: vmeirq=0x%08x vector=0x%08x\n", vmeirq, vector); + return unican_irq_handler(vmeirq, chip, regs); +} + +int unican_vme_request_io(struct candevice_t *candev) +{ + struct chip_t *chip = candev->chip[0]; + + unican_request_io(candev); + + if (chip->chip_irq < 0 || chip->chip_irq >= VME_CHIPS_SIZE) { + CANMSG("Bad irq parameter. Maximum is %d.\n", VME_CHIPS_SIZE-1); + return -EINVAL; + } + +/* vme_chips[chip->chip_irq] = chip; */ + vme_chips[0] = chip; + + request_vmeirq(UNICAN_VME_IRQ, unican_vme_irq_handler); + enable_vmeirq(UNICAN_VME_IRQ); + + return 0; +} + +/** + * unican_vme_release_io - free reserved io memory range + * @candev: pointer to candevice/board which releases io + * + * Return Value: The function always returns zero + * File: src/unican.c + */ +int unican_vme_release_io(struct candevice_t *candev) +{ + unican_release_io(candev); + + free_vmeirq(UNICAN_VME_IRQ); + disable_vmeirq(UNICAN_VME_IRQ); + return 0; +} + +/** + * unican_vme_init_hw_data - Initialize hardware cards + * @candev: Pointer to candevice/board structure + * + * Return Value: The function always returns zero + * File: src/unican.c + */ +int unican_vme_reset(struct candevice_t *candev) +{ + int ret; + struct chip_t *chip = candev->chip[0]; + + ret = unican_reset(candev); + + /* Setup VME interrupt vector */ + if (ret == 0) + unican_writew(0x1234/* chip->chip_irq */,chip->chip_base_addr+CL2_VME_INT_VECTOR); + + + return ret; +} + +/** + * unican_vme_init_chip_data - Initialize chips + * @candev: Pointer to candevice/board structure + * @chipnr: Number of the CAN chip on the hardware card + * + * Return Value: The function always returns zero + * File: src/unican.c + */ +int unican_vme_init_chip_data(struct candevice_t *candev, int chipnr) +{ + struct chip_t *chip = candev->chip[chipnr]; + + unican_init_chip_data(candev, chipnr); + + chip->flags |= CHIP_IRQ_VME; + chip->chipspecops->irq_handler=unican_vme_irq_handler; + return 0; +} + + +int unican_vme_register(struct hwspecops_t *hwspecops) +{ + unican_register(hwspecops); + + hwspecops->request_io = unican_vme_request_io; + hwspecops->release_io = unican_vme_release_io; + hwspecops->reset = unican_vme_reset; + hwspecops->init_chip_data = unican_vme_init_chip_data; + return 0; +}