From: ppisa Date: Sun, 21 May 2006 22:50:24 +0000 (+0000) Subject: Correction of false i82527 IRQ stuck problem reported by Terence Soh. X-Git-Tag: CLT_COMM_CAN-lincan-0_3_3~1 X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/commitdiff_plain/33353b1cd90a21f7907e6d3151b2f1055396eba7 Correction of false i82527 IRQ stuck problem reported by Terence Soh. The interrupt pending flag has to be clean even, if we cannot process synchronous activities. The flags ensures, that they are processed later in such case. The change requires testing, I have not get to testing yet. --- diff --git a/lincan/src/i82527.c b/lincan/src/i82527.c index eb89220..58aa048 100644 --- a/lincan/src/i82527.c +++ b/lincan/src/i82527.c @@ -601,8 +601,10 @@ void i82527_irq_update_filter(struct canchip_t *chip, struct msgobj_t *obj) } -void i82527_irq_sync_activities(struct canchip_t *chip, struct msgobj_t *obj) +int i82527_irq_sync_activities(struct canchip_t *chip, struct msgobj_t *obj) { + int job_done=0; + while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)) { if(can_msgobj_test_and_clear_fl(obj,TX_REQUEST)) { @@ -616,6 +618,8 @@ void i82527_irq_sync_activities(struct canchip_t *chip, struct msgobj_t *obj) } } + job_done=1; + mb(); can_msgobj_clear_fl(obj,TX_LOCK); @@ -625,6 +629,8 @@ void i82527_irq_sync_activities(struct canchip_t *chip, struct msgobj_t *obj) continue; break; } + + return job_done; } int i82527_irq_handler(int irq, struct canchip_t *chip) @@ -679,7 +685,17 @@ int i82527_irq_handler(int irq, struct canchip_t *chip) can_msgobj_set_fl(obj,TX_REQUEST); /* calls i82527_irq_write_handler synchronized with other invocations */ - i82527_irq_sync_activities(chip, obj); + if(i82527_irq_sync_activities(chip, obj)<=0){ + /* The interrupt has to be cleared anyway */ + canobj_write_reg(chip,obj,(MVAL_UNC|TXIE_UNC|RXIE_UNC|INTPD_RES),iMSGCTL0); + + /* + * Rerun for case, that parallel activity on SMP or fully-preemptive + * kernel result in preparation and finished sending of message + * between above if and canobj_write_reg. + */ + i82527_irq_sync_activities(chip, obj); + } } else {