mmc: dw_mmc: Add "disable-wp" device tree property

The "disable-wp" property is used to specify that a given SD card slot
doesn't have a concept of write protect.  This eliminates the need for
special case code for SD slots that should never be write protected
(like a micro SD slot or a dev board).

The dw_mmc driver is special in needing to specify "disable-wp"
because the lack of a "wp-gpios" property means to use the special
purpose write protect line.  On some other mmc devices the lack of
"wp-gpios" means that write protect should be disabled.

Signed-off-by: Doug Anderson <dianders@chromium.org>
Acked-by: Seungwon Jeon <tgih.jun@samsung.com>
Acked-by: Will Newton <will.newton@imgtec.com>
Acked-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Chris Ball <cjb@laptop.org>
This commit is contained in:
Doug Anderson 2013-01-11 17:03:50 +00:00 committed by Chris Ball
parent c148e9ff4b
commit a70aaa64da
3 changed files with 59 additions and 3 deletions

View File

@ -26,8 +26,16 @@ Required Properties:
* bus-width: as documented in mmc core bindings.
* wp-gpios: specifies the write protect gpio line. The format of the
gpio specifier depends on the gpio controller. If the write-protect
line is not available, this property is optional.
gpio specifier depends on the gpio controller. If a GPIO is not used
for write-protect, this property is optional.
* disable-wp: If the wp-gpios property isn't present then (by default)
we'd assume that the write protect is hooked up directly to the
controller's special purpose write protect line (accessible via
the WRTPRT register). However, it's possible that we simply don't
want write protect. In that case specify 'disable-wp'.
NOTE: This property is not required for slots known to always
connect to eMMC or SDIO cards.
Optional properties:

View File

@ -74,6 +74,7 @@ struct idmac_desc {
* struct dw_mci_slot - MMC slot state
* @mmc: The mmc_host representing this slot.
* @host: The MMC controller this slot is using.
* @quirks: Slot-level quirks (DW_MCI_SLOT_QUIRK_XXX)
* @ctype: Card type for this slot.
* @mrq: mmc_request currently being processed or waiting to be
* processed, or NULL when the slot is idle.
@ -88,6 +89,8 @@ struct dw_mci_slot {
struct mmc_host *mmc;
struct dw_mci *host;
int quirks;
u32 ctype;
struct mmc_request *mrq;
@ -825,7 +828,13 @@ static int dw_mci_get_ro(struct mmc_host *mmc)
struct dw_mci_board *brd = slot->host->pdata;
/* Use platform get_ro function, else try on board write protect */
if (brd->quirks & DW_MCI_QUIRK_NO_WRITE_PROTECT)
/*
* NOTE: DW_MCI_QUIRK_NO_WRITE_PROTECT will be removed in a future
* patch in the series once reference to it is removed.
*/
if ((brd->quirks & DW_MCI_QUIRK_NO_WRITE_PROTECT) ||
(slot->quirks & DW_MCI_SLOT_QUIRK_NO_WRITE_PROTECT))
read_only = 0;
else if (brd->get_ro)
read_only = brd->get_ro(slot->id);
@ -1785,6 +1794,30 @@ static struct device_node *dw_mci_of_find_slot_node(struct device *dev, u8 slot)
return NULL;
}
static struct dw_mci_of_slot_quirks {
char *quirk;
int id;
} of_slot_quirks[] = {
{
.quirk = "disable-wp",
.id = DW_MCI_SLOT_QUIRK_NO_WRITE_PROTECT,
},
};
static int dw_mci_of_get_slot_quirks(struct device *dev, u8 slot)
{
struct device_node *np = dw_mci_of_find_slot_node(dev, slot);
int quirks = 0;
int idx;
/* get quirks */
for (idx = 0; idx < ARRAY_SIZE(of_slot_quirks); idx++)
if (of_get_property(np, of_slot_quirks[idx].quirk, NULL))
quirks |= of_slot_quirks[idx].id;
return quirks;
}
/* find out bus-width for a given slot */
static u32 dw_mci_of_get_bus_wd(struct device *dev, u8 slot)
{
@ -1800,6 +1833,10 @@ static u32 dw_mci_of_get_bus_wd(struct device *dev, u8 slot)
return bus_wd;
}
#else /* CONFIG_OF */
static int dw_mci_of_get_slot_quirks(struct device *dev, u8 slot)
{
return 0;
}
static u32 dw_mci_of_get_bus_wd(struct device *dev, u8 slot)
{
return 1;
@ -1828,6 +1865,8 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
slot->host = host;
host->slot[id] = slot;
slot->quirks = dw_mci_of_get_slot_quirks(host->dev, slot->id);
mmc->ops = &dw_mci_ops;
mmc->f_min = DIV_ROUND_UP(host->bus_hz, 510);
mmc->f_max = host->bus_hz;

View File

@ -209,9 +209,18 @@ struct dw_mci_dma_ops {
#define DW_MCI_QUIRK_HIGHSPEED BIT(2)
/* Unreliable card detection */
#define DW_MCI_QUIRK_BROKEN_CARD_DETECTION BIT(3)
/* Write Protect detection not available */
/*
* NOTE: DW_MCI_QUIRK_NO_WRITE_PROTECT will be removed in a future
* patch in the series once reference to it is removed.
*/
#define DW_MCI_QUIRK_NO_WRITE_PROTECT BIT(4)
/* Slot level quirks */
/* This slot has no write protect */
#define DW_MCI_SLOT_QUIRK_NO_WRITE_PROTECT BIT(0)
struct dma_pdata;
struct block_settings {