-
Ben Avison authored
The SDIO specification allows IO cards to request servicing by driver software on the host by repurposing the DAT1 pin when it is not being used to transfer data blocks, i.e. during the "interrupt period". SD controllers typically take care of sampling DAT1 appropriately, and proxy the interrupt to the CPU by piggybacking on the SD host controller's interrupt. Thus SDIODriver needs to be involved in disambiguating card interrupts from other host controller interrupts. However, the servicing action required on a card interrupt varies from card to card, so SDIODriver needs to delegate this to individual card drivers. To achieve this, implement SWIs SDIO_ClaimDeviceVector and SDIO_ReleaseDeviceVector as previously specified. Note that these are function-specific, so for example a combined WiFi/Bluetooth card would have separate handlers for its WiFi and Bluetooth functions, potentially in separate driver modules. The fact that DAT1 interrupts are level-sensitive, and that servicing any interrupt by issuing further operations over the same SD bus - a lengthy process that requires the use of other SD controller interrupts - means that the card interrupt must be masked until servicing is complete. The card driver therefore needs some way to signal to SDIODriver that servicing is complete and DAT1 interrupts can be unmasked again. This is achieved using new SWI SDIOControl 7. To accelerate interrupt dispatch, SDIODriver has two optimisations: * If only one function has an installed handler for a given card, it skips polling the "Int Pending" register in the card, and immediately dispatches to the one handler. * SDIODriver now snoops the results of operations for each slot to keep track of which RCA (if any) is selected. This means if multiple functions have installed handlers, it only needs to issue CMD7 if the card is not selected. This facility appears to be beneficial more generally for driver code ported from other OSes, and so it is exposed via new SWI SDIO_Status 0. At the low level, any standard SDHCI controller is automatically supported, providing SDIODriver trusts its interrupt device number (i.e. minor version 2 or above). Soft controllers are supported via two additional functions: EnableCardInterrupt() and CardInterruptStatus(). These are assumed to be defined for all type-2 soft controllers (since these are being added at the same version of SDIOController as type-2 soft controllers were introduced, there's no need to test for their presence at runtime). Type-1 soft controllers are superseded by type-2 soft controllers, so there's no need to add equivalent functions to them. This commit also adds a test module which was used in development for testing card interrupt dispatch in a way that doesn't rely on having a genuine SDIO card interrupt working (which would require a card driver to be in a more advanced state than they are at the current time). This relies on a backdoor SWI in SDIODriver - SDIO_Control &100. Support for this is wrapped in #if conditionals, and may be disabled in future, once the system has been proved in real-world usage.
3d84c6d3