diff options
| author | Doug Anderson <dianders@chromium.org> | 2013-01-11 12:03:50 -0500 |
|---|---|---|
| committer | Chris Ball <cjb@laptop.org> | 2013-02-24 14:36:52 -0500 |
| commit | a70aaa64da2205d32d1c9362d8f5d4be619cd58f (patch) | |
| tree | a1744e9c87a2437863c707bb9ec043b5a4cebe5a | |
| parent | c148e9ff4bd45f26d3f0253c20efc497672c3c84 (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.txt | 12 | ||||
| -rw-r--r-- | drivers/mmc/host/dw_mmc.c | 41 | ||||
| -rw-r--r-- | include/linux/mmc/dw_mmc.h | 9 |
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 | ||
| 32 | Optional properties: | 40 | Optional 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 | ||
| 1797 | static 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 | |||
| 1807 | static 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 */ |
| 1789 | static u32 dw_mci_of_get_bus_wd(struct device *dev, u8 slot) | 1822 | static 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 */ |
| 1836 | static int dw_mci_of_get_slot_quirks(struct device *dev, u8 slot) | ||
| 1837 | { | ||
| 1838 | return 0; | ||
| 1839 | } | ||
| 1803 | static u32 dw_mci_of_get_bus_wd(struct device *dev, u8 slot) | 1840 | static 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 | |||
| 215 | struct dma_pdata; | 224 | struct dma_pdata; |
| 216 | 225 | ||
| 217 | struct block_settings { | 226 | struct block_settings { |
