Commit 965ebf33 authored by Haavard Skinnemoen's avatar Haavard Skinnemoen

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: default avatarHaavard Skinnemoen <haavard.skinnemoen@atmel.com>
parent 6b918657
#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 @@ ...@@ -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 { ...@@ -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 */
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment