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.
-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)
while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)) {
if(can_msgobj_test_and_clear_fl(obj,TX_REQUEST)) {
while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)) {
if(can_msgobj_test_and_clear_fl(obj,TX_REQUEST)) {
mb();
can_msgobj_clear_fl(obj,TX_LOCK);
mb();
can_msgobj_clear_fl(obj,TX_LOCK);
}
int i82527_irq_handler(int irq, struct canchip_t *chip)
}
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 */
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);
+ }