atmel-mci: support multiple mmc slots
The Atmel MCI controller can drive multiple cards through separate sets of pins, but only one at a time. This patch adds support for multiplexing access to the controller so that multiple card slots can be used as if they were hooked up to separate mmc controllers. The atmel-mci driver registers each slot as a separate mmc_host. Both access the same common controller state, but they also have some state on their own for card detection/write protect handling, and separate shadows of the MR and SDCR registers. When one of the slots receives a request from the mmc core, the common controller state is checked. If it's idle, the request is submitted immediately. If not, the request is added to a queue. When a request is done, the queue is checked and if there is a queued request, it is submitted before the completion callback is called. This patch also includes a few cleanups and fixes, including a locking overhaul. I had to change the locking extensively in any case, so I might as well try to get it right. The driver no longer takes any irq-safe locks, which may or may not improve the overall system performance. This patch also adds a bit of documentation of the internal data structures. Signed-off-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com>
This commit is contained in:
parent
6b918657b7
commit
965ebf33ea
|
@ -1,6 +1,8 @@
|
||||||
#ifndef __ASM_AVR32_ATMEL_MCI_H
|
#ifndef __ASM_AVR32_ATMEL_MCI_H
|
||||||
#define __ASM_AVR32_ATMEL_MCI_H
|
#define __ASM_AVR32_ATMEL_MCI_H
|
||||||
|
|
||||||
|
#define ATMEL_MCI_MAX_NR_SLOTS 2
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct mci_slot_pdata - board-specific per-slot configuration
|
* struct mci_slot_pdata - board-specific per-slot configuration
|
||||||
* @bus_width: Number of data lines wired up the slot
|
* @bus_width: Number of data lines wired up the slot
|
||||||
|
@ -11,6 +13,10 @@
|
||||||
* set to 0. The other fields are ignored in this case.
|
* set to 0. The other fields are ignored in this case.
|
||||||
*
|
*
|
||||||
* Any pins that aren't available should be set to a negative value.
|
* Any pins that aren't available should be set to a negative value.
|
||||||
|
*
|
||||||
|
* Note that support for multiple slots is experimental -- some cards
|
||||||
|
* might get upset if we don't get the clock management exactly right.
|
||||||
|
* But in most cases, it should work just fine.
|
||||||
*/
|
*/
|
||||||
struct mci_slot_pdata {
|
struct mci_slot_pdata {
|
||||||
unsigned int bus_width;
|
unsigned int bus_width;
|
||||||
|
@ -23,7 +29,7 @@ struct mci_slot_pdata {
|
||||||
* @slot: Per-slot configuration data.
|
* @slot: Per-slot configuration data.
|
||||||
*/
|
*/
|
||||||
struct mci_platform_data {
|
struct mci_platform_data {
|
||||||
struct mci_slot_pdata slot[2];
|
struct mci_slot_pdata slot[ATMEL_MCI_MAX_NR_SLOTS];
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __ASM_AVR32_ATMEL_MCI_H */
|
#endif /* __ASM_AVR32_ATMEL_MCI_H */
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue