]> rtime.felk.cvut.cz Git - lincan.git/commitdiff
Added attach_to_chip() and release_chip() functions for each chip.
authorppisa <ppisa>
Thu, 2 Jun 2005 04:06:13 +0000 (04:06 +0000)
committerppisa <ppisa>
Thu, 2 Jun 2005 04:06:13 +0000 (04:06 +0000)
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().

lincan/include/constants.h
lincan/include/main.h
lincan/src/c_can.c
lincan/src/finish.c
lincan/src/i82527.c
lincan/src/main.c
lincan/src/sja1000.c
lincan/src/sja1000p.c
lincan/src/unican.c

index 2643d0d84180cc16173c6b07a7a77d08bffabb6a..e838a9eee321e4f67b979cce718621dc3168f2e9 100644 (file)
 
 
 /* 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
 
index e05e774fb6a3bfb94d69dcde35be1ca61b9fcb19..f7afa85a46fc0eab7f04204115207f68288f8322 100644 (file)
@@ -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);
index a0503b49be2e6fb75f2b6c30647abe84454b2d8c..4c052c312603d2b0bef68cb518564fe444cde143 100644 (file)
@@ -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;
index 0641048b914b522296d5057ac672cf390b6531b6..f10f309789d03d699a8f03e963aaf0ed7b74ff27 100644 (file)
@@ -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;
index 7834c1bc8b35ad7cb40dcf52ee8138b7b7987064..d5c7b24e528fb05201c357fe2a27fe8a042d4804 100644 (file)
@@ -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;
index 60eb6e6799c429a652dc0dcf73df9ea1167ed681..dac96200c05c5d6402763279ce9a32152a877df9 100644 (file)
@@ -229,15 +229,25 @@ int init_module(void)
                for(j=0; j<candev->nr_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: ;
index d43de2f176622cccb03281359f0d9840925803f6..71c7095adad847292cfa9f37cd14865eaa20061e 100644 (file)
@@ -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;
index 70a99c4094e5fb5fc6c1db5d6a900fc84fb4e342..216a9b904b8f755c8a5c4a91795c1489c3f1629d 100644 (file)
@@ -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;
index df556d611b7fbafaca8cfdbf934dbcbd2d19e644..55cfbd5374a5f9525dedd8d4ebc7325408b688ae 100644 (file)
@@ -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;