leon, grcan: redesigned bus-off and AHB error handling
When bus-off condition is detected by the ISR, it sets the started flag to
STATE_BUSOFF. This is monitored by the user functions grcan_read() and
grcan_write() each time they want to enable DMA or update interrupt mask. If
they detect that ISR has detected bus-off then they will return either with an
error or with the number of CAN messages processed. Future calls to functions
which require STARTED mode will be rejected and grcan_isstarted() will return
- The next call to grcan_stop() will do the transition from BUSOFF->STOPPED
and the device can then be started again with grcan_start().
Similar to a bus-off condition, the AHB error condition detected by the ISR
will trigger the same shut-down logic of the driver. The difference is that
the state entered is STATE_AHBERR and the routines will return a different
value to indicate AHB error state.
This commit also fixes an issue where ISR was not always unregistered on close.
User functions can cause these transitions:
STATE_STOPPED -> STATE_STARTED (grcan_start)
STATE_STARTED -> STATE_STOPPED (grcan_stop)
STATE_BUSOFF -> STATE_STOPPED (grcan_stop, grcan_close)
STATE_AHBERR -> STATE_STOPPED (grcan_stop, grcan_close)
ISR can cause these transition
STATE_STARTED -> STATE_BUSOFF (grcan_interrupt)
STATE_STARTED -> STATE_AHBERR (grcan_interrupt)
STATE_BUSOFF/AHBERR is entered from ISR on bus-off condition. At transition
the ISR disables DMA, masks all interrupts and flushes semaphores.
Other related updates:
- Statistics are updated from the ISR. Update is now spin-locked to ensure a
consistent user view.
- The debug output has been updated to include state changes.
- For read/write/flush, return error (-4) if driver aborted the operation
due to bus-off. Likewise if abourted due to AHB error -5 is returned.
- Collect bus-off statistics
Related to the new BUSOFF and AHBERR states the API has been updated to
reflect the current SW driver state. The isstarted() function has been
replaced with get_state().