From: ppisa Date: Thu, 2 Jun 2005 04:06:13 +0000 (+0000) Subject: Added attach_to_chip() and release_chip() functions for each chip. X-Git-Tag: CLT_COMM_CAN-lincan-0_3_1~10 X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/commitdiff_plain/5282a3d5b5624f59a4a11b061368e523934fe5f0 Added attach_to_chip() and release_chip() functions for each chip. This enables correct stopping and IRQ disable before driver unload. This is required to get rid of problematic handling of shut down for C_CAN ARM in ns_dev_release_io(). --- diff --git a/lincan/include/constants.h b/lincan/include/constants.h index 2643d0d..e838a9e 100644 --- a/lincan/include/constants.h +++ b/lincan/include/constants.h @@ -73,13 +73,14 @@ /* These flags can be used for the canchip_t structure flags data entry */ -#define CHIP_CONFIGURED (1<<0) /* chip is configured and prepared for communication */ -#define CHIP_SEGMENTED (1<<1) /* segmented access, ex: i82527 with 16 byte window*/ -#define CHIP_IRQ_SETUP (1<<2) /* IRQ handler has been set */ -#define CHIP_IRQ_PCI (1<<3) /* chip is on PCI board and uses PCI interrupt */ -#define CHIP_IRQ_VME (1<<4) /* interrupt is VME bus and requires VME bridge */ -#define CHIP_IRQ_CUSTOM (1<<5) /* custom interrupt provided by board or chip code */ -#define CHIP_IRQ_FAST (1<<6) /* interrupt handler only schedules postponed processing */ +#define CHIP_ATTACHED (1<<0) /* chip is attached to HW, release_chip() has to be called */ +#define CHIP_CONFIGURED (1<<1) /* chip is configured and prepared for communication */ +#define CHIP_SEGMENTED (1<<2) /* segmented access, ex: i82527 with 16 byte window*/ +#define CHIP_IRQ_SETUP (1<<3) /* IRQ handler has been set */ +#define CHIP_IRQ_PCI (1<<4) /* chip is on PCI board and uses PCI interrupt */ +#define CHIP_IRQ_VME (1<<5) /* interrupt is VME bus and requires VME bridge */ +#define CHIP_IRQ_CUSTOM (1<<6) /* custom interrupt provided by board or chip code */ +#define CHIP_IRQ_FAST (1<<7) /* interrupt handler only schedules postponed processing */ #define CHIP_MAX_IRQLOOP 1000 diff --git a/lincan/include/main.h b/lincan/include/main.h index e05e774..f7afa85 100644 --- a/lincan/include/main.h +++ b/lincan/include/main.h @@ -320,6 +320,8 @@ struct hwspecops_t { * @enable_configuration: enable chip configuration mode * @disable_configuration: disable chip configuration mode * @set_btregs: configures bitrate registers + * @attach_to_chip: attaches to the chip, setups registers and possibly state informations + * @release_chip: called before chip structure removal if %CHIP_ATTACHED is set * @start_chip: starts chip message processing * @stop_chip: stops chip message processing * @irq_handler: interrupt service routine @@ -350,6 +352,8 @@ struct chipspecops_t { int (*disable_configuration)(struct canchip_t *chip); int (*set_btregs)(struct canchip_t *chip, unsigned short btr0, unsigned short btr1); + int (*attach_to_chip)(struct canchip_t *chip); + int (*release_chip)(struct canchip_t *chip); int (*start_chip)(struct canchip_t *chip); int (*stop_chip)(struct canchip_t *chip); int (*irq_handler)(int irq, struct canchip_t *chip); diff --git a/lincan/src/c_can.c b/lincan/src/c_can.c index a0503b4..4c052c3 100644 --- a/lincan/src/c_can.c +++ b/lincan/src/c_can.c @@ -750,6 +750,29 @@ int c_can_stop_chip(struct canchip_t *pchip) return 0; } +int c_can_attach_to_chip(struct canchip_t *chip) +{ + return 0; +} + +int c_can_release_chip(struct canchip_t *chip) +{ + int temp; + + temp = c_can_read_reg_w(chip, CCCR); + + /* Disable IRQ generation */ + c_can_config_irqs(chip, 0); + + temp = c_can_read_reg_w(chip, CCCR); + + /* Power-down C_CAN, except this does nothing in the version 1.2 */ + c_can_stop_chip(chip); + + + return 0; +} + /////////////////////////////////////////////////////////////////////// /* *Check the TxOK bit of the Status Register and resets it afterwards. @@ -946,6 +969,8 @@ int c_can_register(struct chipspecops_t *chipspecops) chipspecops->remote_request=c_can_remote_request; chipspecops->enable_configuration=c_can_enable_configuration; chipspecops->disable_configuration=c_can_disable_configuration; + chipspecops->attach_to_chip=c_can_attach_to_chip; + chipspecops->release_chip=c_can_release_chip; chipspecops->set_btregs=c_can_set_btregs; chipspecops->start_chip=c_can_start_chip; chipspecops->stop_chip=c_can_stop_chip; diff --git a/lincan/src/finish.c b/lincan/src/finish.c index 0641048..f10f309 100644 --- a/lincan/src/finish.c +++ b/lincan/src/finish.c @@ -66,6 +66,9 @@ void canchip_done(struct canchip_t *chip) int i; struct msgobj_t *obj; + if(chip->flags & CHIP_ATTACHED) + chip->chipspecops->release_chip(chip); + if((chip->hostdevice) && (chip->chip_idx>=0)) { if(chip->hostdevice->chip[chip->chip_idx] == chip) chip->hostdevice->chip[chip->chip_idx] = NULL; diff --git a/lincan/src/i82527.c b/lincan/src/i82527.c index 7834c1b..d5c7b24 100644 --- a/lincan/src/i82527.c +++ b/lincan/src/i82527.c @@ -416,6 +416,19 @@ int i82527_stop_chip(struct canchip_t *chip) return 0; } +int i82527_attach_to_chip(struct canchip_t *chip) +{ + return 0; +} + +int i82527_release_chip(struct canchip_t *chip) +{ + i82527_stop_chip(chip); + can_write_reg(chip, (iCTL_CCE|iCTL_INI), iCTL); + + return 0; +} + static inline void i82527_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj) { @@ -752,6 +765,8 @@ int i82527_register(struct chipspecops_t *chipspecops) chipspecops->enable_configuration = i82527_enable_configuration; chipspecops->disable_configuration = i82527_disable_configuration; chipspecops->set_btregs = i82527_set_btregs; + chipspecops->attach_to_chip = i82527_attach_to_chip; + chipspecops->release_chip = i82527_release_chip; chipspecops->start_chip = i82527_start_chip; chipspecops->stop_chip = i82527_stop_chip; chipspecops->irq_handler = i82527_irq_handler; diff --git a/lincan/src/main.c b/lincan/src/main.c index 60eb6e6..dac9620 100644 --- a/lincan/src/main.c +++ b/lincan/src/main.c @@ -229,15 +229,25 @@ int init_module(void) for(j=0; jnr_all_chips; j++) { if((chip=candev->chip[j])==NULL) continue; + + if(chip->chipspecops->attach_to_chip(chip)<0) { + CANMSG("Initial attach to the chip HW failed\n"); + goto interrupt_error; + } + + chip->flags |= CHIP_ATTACHED; + if(can_chip_setup_irq(chip)<0) { - CANMSG("IRQ setup failed\n"); + CANMSG("Error to setup chip IRQ\n"); goto interrupt_error; } } - + if (candev->flags & CANDEV_PROGRAMMABLE_IRQ) - if (candev->hwspecops->program_irq(candev)) + if (candev->hwspecops->program_irq(candev)){ + CANMSG("Error to program board interrupt\n"); goto interrupt_error; + } } #ifdef CONFIG_PROC_FS @@ -275,7 +285,6 @@ int init_module(void) #endif interrupt_error: ; - CANMSG("Error registering interrupt line.\n"); goto memory_error; reset_error: ; diff --git a/lincan/src/sja1000.c b/lincan/src/sja1000.c index d43de2f..71c7095 100644 --- a/lincan/src/sja1000.c +++ b/lincan/src/sja1000.c @@ -305,6 +305,19 @@ int sja1000_stop_chip(struct canchip_t *chip) return 0; } +int sja1000_attach_to_chip(struct canchip_t *chip) +{ + return 0; +} + +int sja1000_release_chip(struct canchip_t *chip) +{ + sja1000_stop_chip(chip); + can_write_reg(chip,sjaCR_RR,SJACR); + + return 0; +} + int sja1000_remote_request(struct canchip_t *chip, struct msgobj_t *obj) { CANMSG("sja1000_remote_request not implemented\n"); @@ -497,6 +510,8 @@ int sja1000_register(struct chipspecops_t *chipspecops) chipspecops->enable_configuration = sja1000_enable_configuration; chipspecops->disable_configuration = sja1000_disable_configuration; chipspecops->set_btregs = sja1000_set_btregs; + chipspecops->attach_to_chip=sja1000_attach_to_chip; + chipspecops->release_chip=sja1000_release_chip; chipspecops->start_chip = sja1000_start_chip; chipspecops->stop_chip = sja1000_stop_chip; chipspecops->irq_handler = sja1000_irq_handler; diff --git a/lincan/src/sja1000p.c b/lincan/src/sja1000p.c index 70a99c4..216a9b9 100644 --- a/lincan/src/sja1000p.c +++ b/lincan/src/sja1000p.c @@ -486,6 +486,32 @@ int sja1000p_stop_chip(struct canchip_t *chip) return 0; } +/** + * sja1000p_attach_to_chip: - attaches to the chip, setups registers and state + * @chip: pointer to chip state structure + * + * Return Value: negative value reports error. + * File: src/sja1000p.c + */ +int sja1000p_attach_to_chip(struct canchip_t *chip) +{ + return 0; +} + +/** + * sja1000p_release_chip: - called before chip structure removal if %CHIP_ATTACHED is set + * @chip: pointer to chip state structure + * + * Return Value: negative value reports error. + * File: src/sja1000p.c + */ +int sja1000p_release_chip(struct canchip_t *chip) +{ + sja1000p_stop_chip(chip); + can_write_reg(chip, sjaDISABLE_INTERRUPTS, SJAIER); + + return 0; +} /** * sja1000p_remote_request: - configures message object and asks for RTR message @@ -746,6 +772,8 @@ int sja1000p_register(struct chipspecops_t *chipspecops) chipspecops->remote_request=sja1000p_remote_request; chipspecops->enable_configuration=sja1000p_enable_configuration; chipspecops->disable_configuration=sja1000p_disable_configuration; + chipspecops->attach_to_chip=sja1000p_attach_to_chip; + chipspecops->release_chip=sja1000p_release_chip; chipspecops->set_btregs=sja1000p_set_btregs; chipspecops->start_chip=sja1000p_start_chip; chipspecops->stop_chip=sja1000p_stop_chip; diff --git a/lincan/src/unican.c b/lincan/src/unican.c index df556d6..55cfbd5 100644 --- a/lincan/src/unican.c +++ b/lincan/src/unican.c @@ -347,6 +347,34 @@ int unican_stop_chip(struct canchip_t *chip) return 0; } +/** + * unican_attach_to_chip: - attaches to the chip, setups registers and state + * @chip: pointer to chip state structure + * + * Return Value: negative value reports error. + * File: src/sja1000p.c + */ +int unican_attach_to_chip(struct canchip_t *chip) +{ + return 0; +} + +/** + * unican_release_chip: - called before chip structure removal if %CHIP_ATTACHED is set + * @chip: pointer to chip state structure + * + * Return Value: negative value reports error. + * File: src/sja1000p.c + */ +int unican_release_chip(struct canchip_t *chip) +{ + sCAN_CARD *chipext = (sCAN_CARD *)chip->chip_data; + + unican_stop_chip(chip); + cl2_clear_interrupt(chipext); + + return 0; +} /** * unican_remote_request: - configures message object and asks for RTR message @@ -803,6 +831,8 @@ int unican_init_chip_data(struct candevice_t *candev, int chipnr) chip->chipspecops->enable_configuration=unican_enable_configuration; chip->chipspecops->disable_configuration=unican_disable_configuration; chip->chipspecops->set_btregs=unican_set_btregs; + chip->chipspecops->attach_to_chip=unican_attach_to_chip; + chip->chipspecops->release_chip=unican_release_chip; chip->chipspecops->start_chip=unican_start_chip; chip->chipspecops->stop_chip=unican_stop_chip; chip->chipspecops->irq_handler=unican_irq_handler;