aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDoug Anderson <dianders@chromium.org>2013-01-11 12:03:50 -0500
committerChris Ball <cjb@laptop.org>2013-02-24 14:36:52 -0500
commita70aaa64da2205d32d1c9362d8f5d4be619cd58f (patch)
treea1744e9c87a2437863c707bb9ec043b5a4cebe5a
parentc148e9ff4bd45f26d3f0253c20efc497672c3c84 (diff)
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>
-rw-r--r--Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt12
-rw-r--r--drivers/mmc/host/dw_mmc.c41
-rw-r--r--include/linux/mmc/dw_mmc.h9
3 files changed, 59 insertions, 3 deletions
diff --git a/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt
index 06cd32d08052..726fd2122a13 100644
--- a/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt
+++ b/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt
@@ -26,8 +26,16 @@ Required Properties:
26 * bus-width: as documented in mmc core bindings. 26 * bus-width: as documented in mmc core bindings.
27 27
28 * wp-gpios: specifies the write protect gpio line. The format of the 28 * wp-gpios: specifies the write protect gpio line. The format of the
29 gpio specifier depends on the gpio controller. If the write-protect 29 gpio specifier depends on the gpio controller. If a GPIO is not used
30 line is not available, this property is optional. 30 for write-protect, this property is optional.
31
32 * disable-wp: If the wp-gpios property isn't present then (by default)
33 we'd assume that the write protect is hooked up directly to the
34 controller's special purpose write protect line (accessible via
35 the WRTPRT register). However, it's possible that we simply don't
36 want write protect. In that case specify 'disable-wp'.
37 NOTE: This property is not required for slots known to always
38 connect to eMMC or SDIO cards.
31 39
32Optional properties: 40Optional properties:
33 41
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 323c5022c2ca..90f7d990551b 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -74,6 +74,7 @@ struct idmac_desc {
74 * struct dw_mci_slot - MMC slot state 74 * struct dw_mci_slot - MMC slot state
75 * @mmc: The mmc_host representing this slot. 75 * @mmc: The mmc_host representing this slot.
76 * @host: The MMC controller this slot is using. 76 * @host: The MMC controller this slot is using.
77 * @quirks: Slot-level quirks (DW_MCI_SLOT_QUIRK_XXX)
77 * @ctype: Card type for this slot. 78 * @ctype: Card type for this slot.
78 * @mrq: mmc_request currently being processed or waiting to be 79 * @mrq: mmc_request currently being processed or waiting to be
79 * processed, or NULL when the slot is idle. 80 * processed, or NULL when the slot is idle.
@@ -88,6 +89,8 @@ struct dw_mci_slot {
88 struct mmc_host *mmc; 89 struct mmc_host *mmc;
89 struct dw_mci *host; 90 struct dw_mci *host;
90 91
92 int quirks;
93
91 u32 ctype; 94 u32 ctype;
92 95
93 struct mmc_request *mrq; 96 struct mmc_request *mrq;
@@ -825,7 +828,13 @@ static int dw_mci_get_ro(struct mmc_host *mmc)
825 struct dw_mci_board *brd = slot->host->pdata; 828 struct dw_mci_board *brd = slot->host->pdata;
826 829
827 /* Use platform get_ro function, else try on board write protect */ 830 /* Use platform get_ro function, else try on board write protect */
828 if (brd->quirks & DW_MCI_QUIRK_NO_WRITE_PROTECT) 831
832 /*
833 * NOTE: DW_MCI_QUIRK_NO_WRITE_PROTECT will be removed in a future
834 * patch in the series once reference to it is removed.
835 */
836 if ((brd->quirks & DW_MCI_QUIRK_NO_WRITE_PROTECT) ||
837 (slot->quirks & DW_MCI_SLOT_QUIRK_NO_WRITE_PROTECT))
829 read_only = 0; 838 read_only = 0;
830 else if (brd->get_ro) 839 else if (brd->get_ro)
831 read_only = brd->get_ro(slot->id); 840 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)
1785 return NULL; 1794 return NULL;
1786} 1795}
1787 1796
1797static struct dw_mci_of_slot_quirks {
1798 char *quirk;
1799 int id;
1800} of_slot_quirks[] = {
1801 {
1802 .quirk = "disable-wp",
1803 .id = DW_MCI_SLOT_QUIRK_NO_WRITE_PROTECT,
1804 },
1805};
1806
1807static int dw_mci_of_get_slot_quirks(struct device *dev, u8 slot)
1808{
1809 struct device_node *np = dw_mci_of_find_slot_node(dev, slot);
1810 int quirks = 0;
1811 int idx;
1812
1813 /* get quirks */
1814 for (idx = 0; idx < ARRAY_SIZE(of_slot_quirks); idx++)
1815 if (of_get_property(np, of_slot_quirks[idx].quirk, NULL))
1816 quirks |= of_slot_quirks[idx].id;
1817
1818 return quirks;
1819}
1820
1788/* find out bus-width for a given slot */ 1821/* find out bus-width for a given slot */
1789static u32 dw_mci_of_get_bus_wd(struct device *dev, u8 slot) 1822static u32 dw_mci_of_get_bus_wd(struct device *dev, u8 slot)
1790{ 1823{
@@ -1800,6 +1833,10 @@ static u32 dw_mci_of_get_bus_wd(struct device *dev, u8 slot)
1800 return bus_wd; 1833 return bus_wd;
1801} 1834}
1802#else /* CONFIG_OF */ 1835#else /* CONFIG_OF */
1836static int dw_mci_of_get_slot_quirks(struct device *dev, u8 slot)
1837{
1838 return 0;
1839}
1803static u32 dw_mci_of_get_bus_wd(struct device *dev, u8 slot) 1840static u32 dw_mci_of_get_bus_wd(struct device *dev, u8 slot)
1804{ 1841{
1805 return 1; 1842 return 1;
@@ -1828,6 +1865,8 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
1828 slot->host = host; 1865 slot->host = host;
1829 host->slot[id] = slot; 1866 host->slot[id] = slot;
1830 1867
1868 slot->quirks = dw_mci_of_get_slot_quirks(host->dev, slot->id);
1869
1831 mmc->ops = &dw_mci_ops; 1870 mmc->ops = &dw_mci_ops;
1832 mmc->f_min = DIV_ROUND_UP(host->bus_hz, 510); 1871 mmc->f_min = DIV_ROUND_UP(host->bus_hz, 510);
1833 mmc->f_max = host->bus_hz; 1872 mmc->f_max = host->bus_hz;
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
index 34be4f47293c..de61de5608c9 100644
--- a/include/linux/mmc/dw_mmc.h
+++ b/include/linux/mmc/dw_mmc.h
@@ -209,9 +209,18 @@ struct dw_mci_dma_ops {
209#define DW_MCI_QUIRK_HIGHSPEED BIT(2) 209#define DW_MCI_QUIRK_HIGHSPEED BIT(2)
210/* Unreliable card detection */ 210/* Unreliable card detection */
211#define DW_MCI_QUIRK_BROKEN_CARD_DETECTION BIT(3) 211#define DW_MCI_QUIRK_BROKEN_CARD_DETECTION BIT(3)
212
212/* Write Protect detection not available */ 213/* Write Protect detection not available */
214/*
215 * NOTE: DW_MCI_QUIRK_NO_WRITE_PROTECT will be removed in a future
216 * patch in the series once reference to it is removed.
217 */
213#define DW_MCI_QUIRK_NO_WRITE_PROTECT BIT(4) 218#define DW_MCI_QUIRK_NO_WRITE_PROTECT BIT(4)
214 219
220/* Slot level quirks */
221/* This slot has no write protect */
222#define DW_MCI_SLOT_QUIRK_NO_WRITE_PROTECT BIT(0)
223
215struct dma_pdata; 224struct dma_pdata;
216 225
217struct block_settings { 226struct block_settings {