diff options
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/card/block.c | 83 | ||||
-rw-r--r-- | drivers/mmc/card/queue.c | 2 | ||||
-rw-r--r-- | drivers/mmc/core/bus.c | 41 | ||||
-rw-r--r-- | drivers/mmc/core/cd-gpio.c | 1 | ||||
-rw-r--r-- | drivers/mmc/core/core.c | 74 | ||||
-rw-r--r-- | drivers/mmc/core/mmc.c | 30 | ||||
-rw-r--r-- | drivers/mmc/core/sdio_bus.c | 12 | ||||
-rw-r--r-- | drivers/mmc/host/atmel-mci-regs.h | 1 | ||||
-rw-r--r-- | drivers/mmc/host/atmel-mci.c | 55 | ||||
-rw-r--r-- | drivers/mmc/host/dw_mmc.c | 7 | ||||
-rw-r--r-- | drivers/mmc/host/mxs-mmc.c | 3 | ||||
-rw-r--r-- | drivers/mmc/host/omap_hsmmc.c | 189 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-dove.c | 1 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-esdhc-imx.c | 5 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-pci.c | 6 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-pltfm.c | 8 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-s3c.c | 159 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-tegra.c | 24 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.c | 7 | ||||
-rw-r--r-- | drivers/mmc/host/sh_mmcif.c | 13 |
20 files changed, 400 insertions, 321 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index eed213a5c8cb..dabec556ebb8 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -873,7 +873,7 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, | |||
873 | { | 873 | { |
874 | struct mmc_blk_data *md = mq->data; | 874 | struct mmc_blk_data *md = mq->data; |
875 | struct mmc_card *card = md->queue.card; | 875 | struct mmc_card *card = md->queue.card; |
876 | unsigned int from, nr, arg; | 876 | unsigned int from, nr, arg, trim_arg, erase_arg; |
877 | int err = 0, type = MMC_BLK_SECDISCARD; | 877 | int err = 0, type = MMC_BLK_SECDISCARD; |
878 | 878 | ||
879 | if (!(mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))) { | 879 | if (!(mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))) { |
@@ -881,20 +881,26 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, | |||
881 | goto out; | 881 | goto out; |
882 | } | 882 | } |
883 | 883 | ||
884 | from = blk_rq_pos(req); | ||
885 | nr = blk_rq_sectors(req); | ||
886 | |||
884 | /* The sanitize operation is supported at v4.5 only */ | 887 | /* The sanitize operation is supported at v4.5 only */ |
885 | if (mmc_can_sanitize(card)) { | 888 | if (mmc_can_sanitize(card)) { |
886 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 889 | erase_arg = MMC_ERASE_ARG; |
887 | EXT_CSD_SANITIZE_START, 1, 0); | 890 | trim_arg = MMC_TRIM_ARG; |
888 | goto out; | 891 | } else { |
892 | erase_arg = MMC_SECURE_ERASE_ARG; | ||
893 | trim_arg = MMC_SECURE_TRIM1_ARG; | ||
889 | } | 894 | } |
890 | 895 | ||
891 | from = blk_rq_pos(req); | 896 | if (mmc_erase_group_aligned(card, from, nr)) |
892 | nr = blk_rq_sectors(req); | 897 | arg = erase_arg; |
893 | 898 | else if (mmc_can_trim(card)) | |
894 | if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr)) | 899 | arg = trim_arg; |
895 | arg = MMC_SECURE_TRIM1_ARG; | 900 | else { |
896 | else | 901 | err = -EINVAL; |
897 | arg = MMC_SECURE_ERASE_ARG; | 902 | goto out; |
903 | } | ||
898 | retry: | 904 | retry: |
899 | if (card->quirks & MMC_QUIRK_INAND_CMD38) { | 905 | if (card->quirks & MMC_QUIRK_INAND_CMD38) { |
900 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 906 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
@@ -904,25 +910,41 @@ retry: | |||
904 | INAND_CMD38_ARG_SECERASE, | 910 | INAND_CMD38_ARG_SECERASE, |
905 | 0); | 911 | 0); |
906 | if (err) | 912 | if (err) |
907 | goto out; | 913 | goto out_retry; |
908 | } | 914 | } |
915 | |||
909 | err = mmc_erase(card, from, nr, arg); | 916 | err = mmc_erase(card, from, nr, arg); |
910 | if (!err && arg == MMC_SECURE_TRIM1_ARG) { | 917 | if (err == -EIO) |
918 | goto out_retry; | ||
919 | if (err) | ||
920 | goto out; | ||
921 | |||
922 | if (arg == MMC_SECURE_TRIM1_ARG) { | ||
911 | if (card->quirks & MMC_QUIRK_INAND_CMD38) { | 923 | if (card->quirks & MMC_QUIRK_INAND_CMD38) { |
912 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 924 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
913 | INAND_CMD38_ARG_EXT_CSD, | 925 | INAND_CMD38_ARG_EXT_CSD, |
914 | INAND_CMD38_ARG_SECTRIM2, | 926 | INAND_CMD38_ARG_SECTRIM2, |
915 | 0); | 927 | 0); |
916 | if (err) | 928 | if (err) |
917 | goto out; | 929 | goto out_retry; |
918 | } | 930 | } |
931 | |||
919 | err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG); | 932 | err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG); |
933 | if (err == -EIO) | ||
934 | goto out_retry; | ||
935 | if (err) | ||
936 | goto out; | ||
920 | } | 937 | } |
921 | out: | 938 | |
922 | if (err == -EIO && !mmc_blk_reset(md, card->host, type)) | 939 | if (mmc_can_sanitize(card)) |
940 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | ||
941 | EXT_CSD_SANITIZE_START, 1, 0); | ||
942 | out_retry: | ||
943 | if (err && !mmc_blk_reset(md, card->host, type)) | ||
923 | goto retry; | 944 | goto retry; |
924 | if (!err) | 945 | if (!err) |
925 | mmc_blk_reset_success(md, type); | 946 | mmc_blk_reset_success(md, type); |
947 | out: | ||
926 | spin_lock_irq(&md->lock); | 948 | spin_lock_irq(&md->lock); |
927 | __blk_end_request(req, err, blk_rq_bytes(req)); | 949 | __blk_end_request(req, err, blk_rq_bytes(req)); |
928 | spin_unlock_irq(&md->lock); | 950 | spin_unlock_irq(&md->lock); |
@@ -1623,24 +1645,6 @@ static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md) | |||
1623 | return ret; | 1645 | return ret; |
1624 | } | 1646 | } |
1625 | 1647 | ||
1626 | static int | ||
1627 | mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card) | ||
1628 | { | ||
1629 | int err; | ||
1630 | |||
1631 | mmc_claim_host(card->host); | ||
1632 | err = mmc_set_blocklen(card, 512); | ||
1633 | mmc_release_host(card->host); | ||
1634 | |||
1635 | if (err) { | ||
1636 | pr_err("%s: unable to set block size to 512: %d\n", | ||
1637 | md->disk->disk_name, err); | ||
1638 | return -EINVAL; | ||
1639 | } | ||
1640 | |||
1641 | return 0; | ||
1642 | } | ||
1643 | |||
1644 | static void mmc_blk_remove_req(struct mmc_blk_data *md) | 1648 | static void mmc_blk_remove_req(struct mmc_blk_data *md) |
1645 | { | 1649 | { |
1646 | struct mmc_card *card; | 1650 | struct mmc_card *card; |
@@ -1768,7 +1772,6 @@ static const struct mmc_fixup blk_fixups[] = | |||
1768 | static int mmc_blk_probe(struct mmc_card *card) | 1772 | static int mmc_blk_probe(struct mmc_card *card) |
1769 | { | 1773 | { |
1770 | struct mmc_blk_data *md, *part_md; | 1774 | struct mmc_blk_data *md, *part_md; |
1771 | int err; | ||
1772 | char cap_str[10]; | 1775 | char cap_str[10]; |
1773 | 1776 | ||
1774 | /* | 1777 | /* |
@@ -1781,10 +1784,6 @@ static int mmc_blk_probe(struct mmc_card *card) | |||
1781 | if (IS_ERR(md)) | 1784 | if (IS_ERR(md)) |
1782 | return PTR_ERR(md); | 1785 | return PTR_ERR(md); |
1783 | 1786 | ||
1784 | err = mmc_blk_set_blksize(md, card); | ||
1785 | if (err) | ||
1786 | goto out; | ||
1787 | |||
1788 | string_get_size((u64)get_capacity(md->disk) << 9, STRING_UNITS_2, | 1787 | string_get_size((u64)get_capacity(md->disk) << 9, STRING_UNITS_2, |
1789 | cap_str, sizeof(cap_str)); | 1788 | cap_str, sizeof(cap_str)); |
1790 | pr_info("%s: %s %s %s %s\n", | 1789 | pr_info("%s: %s %s %s %s\n", |
@@ -1809,7 +1808,7 @@ static int mmc_blk_probe(struct mmc_card *card) | |||
1809 | out: | 1808 | out: |
1810 | mmc_blk_remove_parts(card, md); | 1809 | mmc_blk_remove_parts(card, md); |
1811 | mmc_blk_remove_req(md); | 1810 | mmc_blk_remove_req(md); |
1812 | return err; | 1811 | return 0; |
1813 | } | 1812 | } |
1814 | 1813 | ||
1815 | static void mmc_blk_remove(struct mmc_card *card) | 1814 | static void mmc_blk_remove(struct mmc_card *card) |
@@ -1825,7 +1824,7 @@ static void mmc_blk_remove(struct mmc_card *card) | |||
1825 | } | 1824 | } |
1826 | 1825 | ||
1827 | #ifdef CONFIG_PM | 1826 | #ifdef CONFIG_PM |
1828 | static int mmc_blk_suspend(struct mmc_card *card, pm_message_t state) | 1827 | static int mmc_blk_suspend(struct mmc_card *card) |
1829 | { | 1828 | { |
1830 | struct mmc_blk_data *part_md; | 1829 | struct mmc_blk_data *part_md; |
1831 | struct mmc_blk_data *md = mmc_get_drvdata(card); | 1830 | struct mmc_blk_data *md = mmc_get_drvdata(card); |
@@ -1845,8 +1844,6 @@ static int mmc_blk_resume(struct mmc_card *card) | |||
1845 | struct mmc_blk_data *md = mmc_get_drvdata(card); | 1844 | struct mmc_blk_data *md = mmc_get_drvdata(card); |
1846 | 1845 | ||
1847 | if (md) { | 1846 | if (md) { |
1848 | mmc_blk_set_blksize(md, card); | ||
1849 | |||
1850 | /* | 1847 | /* |
1851 | * Resume involves the card going into idle state, | 1848 | * Resume involves the card going into idle state, |
1852 | * so current partition is always the main one. | 1849 | * so current partition is always the main one. |
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 2517547b4366..996f8e36e23d 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c | |||
@@ -139,7 +139,7 @@ static void mmc_queue_setup_discard(struct request_queue *q, | |||
139 | 139 | ||
140 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); | 140 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); |
141 | q->limits.max_discard_sectors = max_discard; | 141 | q->limits.max_discard_sectors = max_discard; |
142 | if (card->erased_byte == 0) | 142 | if (card->erased_byte == 0 && !mmc_can_discard(card)) |
143 | q->limits.discard_zeroes_data = 1; | 143 | q->limits.discard_zeroes_data = 1; |
144 | q->limits.discard_granularity = card->pref_erase << 9; | 144 | q->limits.discard_granularity = card->pref_erase << 9; |
145 | /* granularity must not be greater than max. discard */ | 145 | /* granularity must not be greater than max. discard */ |
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 5d011a39dfff..c60cee92a2b2 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c | |||
@@ -122,14 +122,14 @@ static int mmc_bus_remove(struct device *dev) | |||
122 | return 0; | 122 | return 0; |
123 | } | 123 | } |
124 | 124 | ||
125 | static int mmc_bus_suspend(struct device *dev, pm_message_t state) | 125 | static int mmc_bus_suspend(struct device *dev) |
126 | { | 126 | { |
127 | struct mmc_driver *drv = to_mmc_driver(dev->driver); | 127 | struct mmc_driver *drv = to_mmc_driver(dev->driver); |
128 | struct mmc_card *card = mmc_dev_to_card(dev); | 128 | struct mmc_card *card = mmc_dev_to_card(dev); |
129 | int ret = 0; | 129 | int ret = 0; |
130 | 130 | ||
131 | if (dev->driver && drv->suspend) | 131 | if (dev->driver && drv->suspend) |
132 | ret = drv->suspend(card, state); | 132 | ret = drv->suspend(card); |
133 | return ret; | 133 | return ret; |
134 | } | 134 | } |
135 | 135 | ||
@@ -165,20 +165,14 @@ static int mmc_runtime_idle(struct device *dev) | |||
165 | return pm_runtime_suspend(dev); | 165 | return pm_runtime_suspend(dev); |
166 | } | 166 | } |
167 | 167 | ||
168 | #endif /* !CONFIG_PM_RUNTIME */ | ||
169 | |||
168 | static const struct dev_pm_ops mmc_bus_pm_ops = { | 170 | static const struct dev_pm_ops mmc_bus_pm_ops = { |
169 | .runtime_suspend = mmc_runtime_suspend, | 171 | SET_RUNTIME_PM_OPS(mmc_runtime_suspend, mmc_runtime_resume, |
170 | .runtime_resume = mmc_runtime_resume, | 172 | mmc_runtime_idle) |
171 | .runtime_idle = mmc_runtime_idle, | 173 | SET_SYSTEM_SLEEP_PM_OPS(mmc_bus_suspend, mmc_bus_resume) |
172 | }; | 174 | }; |
173 | 175 | ||
174 | #define MMC_PM_OPS_PTR (&mmc_bus_pm_ops) | ||
175 | |||
176 | #else /* !CONFIG_PM_RUNTIME */ | ||
177 | |||
178 | #define MMC_PM_OPS_PTR NULL | ||
179 | |||
180 | #endif /* !CONFIG_PM_RUNTIME */ | ||
181 | |||
182 | static struct bus_type mmc_bus_type = { | 176 | static struct bus_type mmc_bus_type = { |
183 | .name = "mmc", | 177 | .name = "mmc", |
184 | .dev_attrs = mmc_dev_attrs, | 178 | .dev_attrs = mmc_dev_attrs, |
@@ -186,9 +180,7 @@ static struct bus_type mmc_bus_type = { | |||
186 | .uevent = mmc_bus_uevent, | 180 | .uevent = mmc_bus_uevent, |
187 | .probe = mmc_bus_probe, | 181 | .probe = mmc_bus_probe, |
188 | .remove = mmc_bus_remove, | 182 | .remove = mmc_bus_remove, |
189 | .suspend = mmc_bus_suspend, | 183 | .pm = &mmc_bus_pm_ops, |
190 | .resume = mmc_bus_resume, | ||
191 | .pm = MMC_PM_OPS_PTR, | ||
192 | }; | 184 | }; |
193 | 185 | ||
194 | int mmc_register_bus(void) | 186 | int mmc_register_bus(void) |
@@ -267,6 +259,15 @@ int mmc_add_card(struct mmc_card *card) | |||
267 | { | 259 | { |
268 | int ret; | 260 | int ret; |
269 | const char *type; | 261 | const char *type; |
262 | const char *uhs_bus_speed_mode = ""; | ||
263 | static const char *const uhs_speeds[] = { | ||
264 | [UHS_SDR12_BUS_SPEED] = "SDR12 ", | ||
265 | [UHS_SDR25_BUS_SPEED] = "SDR25 ", | ||
266 | [UHS_SDR50_BUS_SPEED] = "SDR50 ", | ||
267 | [UHS_SDR104_BUS_SPEED] = "SDR104 ", | ||
268 | [UHS_DDR50_BUS_SPEED] = "DDR50 ", | ||
269 | }; | ||
270 | |||
270 | 271 | ||
271 | dev_set_name(&card->dev, "%s:%04x", mmc_hostname(card->host), card->rca); | 272 | dev_set_name(&card->dev, "%s:%04x", mmc_hostname(card->host), card->rca); |
272 | 273 | ||
@@ -296,6 +297,10 @@ int mmc_add_card(struct mmc_card *card) | |||
296 | break; | 297 | break; |
297 | } | 298 | } |
298 | 299 | ||
300 | if (mmc_sd_card_uhs(card) && | ||
301 | (card->sd_bus_speed < ARRAY_SIZE(uhs_speeds))) | ||
302 | uhs_bus_speed_mode = uhs_speeds[card->sd_bus_speed]; | ||
303 | |||
299 | if (mmc_host_is_spi(card->host)) { | 304 | if (mmc_host_is_spi(card->host)) { |
300 | pr_info("%s: new %s%s%s card on SPI\n", | 305 | pr_info("%s: new %s%s%s card on SPI\n", |
301 | mmc_hostname(card->host), | 306 | mmc_hostname(card->host), |
@@ -303,13 +308,13 @@ int mmc_add_card(struct mmc_card *card) | |||
303 | mmc_card_ddr_mode(card) ? "DDR " : "", | 308 | mmc_card_ddr_mode(card) ? "DDR " : "", |
304 | type); | 309 | type); |
305 | } else { | 310 | } else { |
306 | pr_info("%s: new %s%s%s%s card at address %04x\n", | 311 | pr_info("%s: new %s%s%s%s%s card at address %04x\n", |
307 | mmc_hostname(card->host), | 312 | mmc_hostname(card->host), |
308 | mmc_card_uhs(card) ? "ultra high speed " : | 313 | mmc_card_uhs(card) ? "ultra high speed " : |
309 | (mmc_card_highspeed(card) ? "high speed " : ""), | 314 | (mmc_card_highspeed(card) ? "high speed " : ""), |
310 | (mmc_card_hs200(card) ? "HS200 " : ""), | 315 | (mmc_card_hs200(card) ? "HS200 " : ""), |
311 | mmc_card_ddr_mode(card) ? "DDR " : "", | 316 | mmc_card_ddr_mode(card) ? "DDR " : "", |
312 | type, card->rca); | 317 | uhs_bus_speed_mode, type, card->rca); |
313 | } | 318 | } |
314 | 319 | ||
315 | #ifdef CONFIG_DEBUG_FS | 320 | #ifdef CONFIG_DEBUG_FS |
diff --git a/drivers/mmc/core/cd-gpio.c b/drivers/mmc/core/cd-gpio.c index 29de31e260dd..2c14be73254c 100644 --- a/drivers/mmc/core/cd-gpio.c +++ b/drivers/mmc/core/cd-gpio.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/gpio.h> | 12 | #include <linux/gpio.h> |
13 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
14 | #include <linux/jiffies.h> | 14 | #include <linux/jiffies.h> |
15 | #include <linux/mmc/cd-gpio.h> | ||
15 | #include <linux/mmc/host.h> | 16 | #include <linux/mmc/host.h> |
16 | #include <linux/module.h> | 17 | #include <linux/module.h> |
17 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 14f262e9246d..ba821fe70bca 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -527,10 +527,14 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card) | |||
527 | 527 | ||
528 | if (data->flags & MMC_DATA_WRITE) | 528 | if (data->flags & MMC_DATA_WRITE) |
529 | /* | 529 | /* |
530 | * The limit is really 250 ms, but that is | 530 | * The MMC spec "It is strongly recommended |
531 | * insufficient for some crappy cards. | 531 | * for hosts to implement more than 500ms |
532 | * timeout value even if the card indicates | ||
533 | * the 250ms maximum busy length." Even the | ||
534 | * previous value of 300ms is known to be | ||
535 | * insufficient for some cards. | ||
532 | */ | 536 | */ |
533 | limit_us = 300000; | 537 | limit_us = 3000000; |
534 | else | 538 | else |
535 | limit_us = 100000; | 539 | limit_us = 100000; |
536 | 540 | ||
@@ -1405,7 +1409,10 @@ static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card, | |||
1405 | { | 1409 | { |
1406 | unsigned int erase_timeout; | 1410 | unsigned int erase_timeout; |
1407 | 1411 | ||
1408 | if (card->ext_csd.erase_group_def & 1) { | 1412 | if (arg == MMC_DISCARD_ARG || |
1413 | (arg == MMC_TRIM_ARG && card->ext_csd.rev >= 6)) { | ||
1414 | erase_timeout = card->ext_csd.trim_timeout; | ||
1415 | } else if (card->ext_csd.erase_group_def & 1) { | ||
1409 | /* High Capacity Erase Group Size uses HC timeouts */ | 1416 | /* High Capacity Erase Group Size uses HC timeouts */ |
1410 | if (arg == MMC_TRIM_ARG) | 1417 | if (arg == MMC_TRIM_ARG) |
1411 | erase_timeout = card->ext_csd.trim_timeout; | 1418 | erase_timeout = card->ext_csd.trim_timeout; |
@@ -1677,8 +1684,6 @@ int mmc_can_trim(struct mmc_card *card) | |||
1677 | { | 1684 | { |
1678 | if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN) | 1685 | if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN) |
1679 | return 1; | 1686 | return 1; |
1680 | if (mmc_can_discard(card)) | ||
1681 | return 1; | ||
1682 | return 0; | 1687 | return 0; |
1683 | } | 1688 | } |
1684 | EXPORT_SYMBOL(mmc_can_trim); | 1689 | EXPORT_SYMBOL(mmc_can_trim); |
@@ -1697,6 +1702,8 @@ EXPORT_SYMBOL(mmc_can_discard); | |||
1697 | 1702 | ||
1698 | int mmc_can_sanitize(struct mmc_card *card) | 1703 | int mmc_can_sanitize(struct mmc_card *card) |
1699 | { | 1704 | { |
1705 | if (!mmc_can_trim(card) && !mmc_can_erase(card)) | ||
1706 | return 0; | ||
1700 | if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE) | 1707 | if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE) |
1701 | return 1; | 1708 | return 1; |
1702 | return 0; | 1709 | return 0; |
@@ -2231,6 +2238,7 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable) | |||
2231 | mmc_card_is_removable(host)) | 2238 | mmc_card_is_removable(host)) |
2232 | return err; | 2239 | return err; |
2233 | 2240 | ||
2241 | mmc_claim_host(host); | ||
2234 | if (card && mmc_card_mmc(card) && | 2242 | if (card && mmc_card_mmc(card) && |
2235 | (card->ext_csd.cache_size > 0)) { | 2243 | (card->ext_csd.cache_size > 0)) { |
2236 | enable = !!enable; | 2244 | enable = !!enable; |
@@ -2248,6 +2256,7 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable) | |||
2248 | card->ext_csd.cache_ctrl = enable; | 2256 | card->ext_csd.cache_ctrl = enable; |
2249 | } | 2257 | } |
2250 | } | 2258 | } |
2259 | mmc_release_host(host); | ||
2251 | 2260 | ||
2252 | return err; | 2261 | return err; |
2253 | } | 2262 | } |
@@ -2265,49 +2274,32 @@ int mmc_suspend_host(struct mmc_host *host) | |||
2265 | 2274 | ||
2266 | cancel_delayed_work(&host->detect); | 2275 | cancel_delayed_work(&host->detect); |
2267 | mmc_flush_scheduled_work(); | 2276 | mmc_flush_scheduled_work(); |
2268 | if (mmc_try_claim_host(host)) { | ||
2269 | err = mmc_cache_ctrl(host, 0); | ||
2270 | mmc_release_host(host); | ||
2271 | } else { | ||
2272 | err = -EBUSY; | ||
2273 | } | ||
2274 | 2277 | ||
2278 | err = mmc_cache_ctrl(host, 0); | ||
2275 | if (err) | 2279 | if (err) |
2276 | goto out; | 2280 | goto out; |
2277 | 2281 | ||
2278 | mmc_bus_get(host); | 2282 | mmc_bus_get(host); |
2279 | if (host->bus_ops && !host->bus_dead) { | 2283 | if (host->bus_ops && !host->bus_dead) { |
2280 | 2284 | ||
2281 | /* | 2285 | if (host->bus_ops->suspend) |
2282 | * A long response time is not acceptable for device drivers | 2286 | err = host->bus_ops->suspend(host); |
2283 | * when doing suspend. Prevent mmc_claim_host in the suspend | ||
2284 | * sequence, to potentially wait "forever" by trying to | ||
2285 | * pre-claim the host. | ||
2286 | */ | ||
2287 | if (mmc_try_claim_host(host)) { | ||
2288 | if (host->bus_ops->suspend) { | ||
2289 | err = host->bus_ops->suspend(host); | ||
2290 | } | ||
2291 | mmc_release_host(host); | ||
2292 | 2287 | ||
2293 | if (err == -ENOSYS || !host->bus_ops->resume) { | 2288 | if (err == -ENOSYS || !host->bus_ops->resume) { |
2294 | /* | 2289 | /* |
2295 | * We simply "remove" the card in this case. | 2290 | * We simply "remove" the card in this case. |
2296 | * It will be redetected on resume. (Calling | 2291 | * It will be redetected on resume. (Calling |
2297 | * bus_ops->remove() with a claimed host can | 2292 | * bus_ops->remove() with a claimed host can |
2298 | * deadlock.) | 2293 | * deadlock.) |
2299 | */ | 2294 | */ |
2300 | if (host->bus_ops->remove) | 2295 | if (host->bus_ops->remove) |
2301 | host->bus_ops->remove(host); | 2296 | host->bus_ops->remove(host); |
2302 | mmc_claim_host(host); | 2297 | mmc_claim_host(host); |
2303 | mmc_detach_bus(host); | 2298 | mmc_detach_bus(host); |
2304 | mmc_power_off(host); | 2299 | mmc_power_off(host); |
2305 | mmc_release_host(host); | 2300 | mmc_release_host(host); |
2306 | host->pm_flags = 0; | 2301 | host->pm_flags = 0; |
2307 | err = 0; | 2302 | err = 0; |
2308 | } | ||
2309 | } else { | ||
2310 | err = -EBUSY; | ||
2311 | } | 2303 | } |
2312 | } | 2304 | } |
2313 | mmc_bus_put(host); | 2305 | mmc_bus_put(host); |
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 02914d609a91..54df5adc0413 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -695,6 +695,11 @@ static int mmc_select_powerclass(struct mmc_card *card, | |||
695 | else if (host->ios.clock <= 200000000) | 695 | else if (host->ios.clock <= 200000000) |
696 | index = EXT_CSD_PWR_CL_200_195; | 696 | index = EXT_CSD_PWR_CL_200_195; |
697 | break; | 697 | break; |
698 | case MMC_VDD_27_28: | ||
699 | case MMC_VDD_28_29: | ||
700 | case MMC_VDD_29_30: | ||
701 | case MMC_VDD_30_31: | ||
702 | case MMC_VDD_31_32: | ||
698 | case MMC_VDD_32_33: | 703 | case MMC_VDD_32_33: |
699 | case MMC_VDD_33_34: | 704 | case MMC_VDD_33_34: |
700 | case MMC_VDD_34_35: | 705 | case MMC_VDD_34_35: |
@@ -1111,11 +1116,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
1111 | ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ? | 1116 | ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ? |
1112 | EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4; | 1117 | EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4; |
1113 | err = mmc_select_powerclass(card, ext_csd_bits, ext_csd); | 1118 | err = mmc_select_powerclass(card, ext_csd_bits, ext_csd); |
1114 | if (err) { | 1119 | if (err) |
1115 | pr_err("%s: power class selection to bus width %d failed\n", | 1120 | pr_warning("%s: power class selection to bus width %d" |
1116 | mmc_hostname(card->host), 1 << bus_width); | 1121 | " failed\n", mmc_hostname(card->host), |
1117 | goto err; | 1122 | 1 << bus_width); |
1118 | } | ||
1119 | } | 1123 | } |
1120 | 1124 | ||
1121 | /* | 1125 | /* |
@@ -1147,10 +1151,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
1147 | err = mmc_select_powerclass(card, ext_csd_bits[idx][0], | 1151 | err = mmc_select_powerclass(card, ext_csd_bits[idx][0], |
1148 | ext_csd); | 1152 | ext_csd); |
1149 | if (err) | 1153 | if (err) |
1150 | pr_err("%s: power class selection to " | 1154 | pr_warning("%s: power class selection to " |
1151 | "bus width %d failed\n", | 1155 | "bus width %d failed\n", |
1152 | mmc_hostname(card->host), | 1156 | mmc_hostname(card->host), |
1153 | 1 << bus_width); | 1157 | 1 << bus_width); |
1154 | 1158 | ||
1155 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 1159 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
1156 | EXT_CSD_BUS_WIDTH, | 1160 | EXT_CSD_BUS_WIDTH, |
@@ -1178,10 +1182,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
1178 | err = mmc_select_powerclass(card, ext_csd_bits[idx][1], | 1182 | err = mmc_select_powerclass(card, ext_csd_bits[idx][1], |
1179 | ext_csd); | 1183 | ext_csd); |
1180 | if (err) | 1184 | if (err) |
1181 | pr_err("%s: power class selection to " | 1185 | pr_warning("%s: power class selection to " |
1182 | "bus width %d ddr %d failed\n", | 1186 | "bus width %d ddr %d failed\n", |
1183 | mmc_hostname(card->host), | 1187 | mmc_hostname(card->host), |
1184 | 1 << bus_width, ddr); | 1188 | 1 << bus_width, ddr); |
1185 | 1189 | ||
1186 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 1190 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
1187 | EXT_CSD_BUS_WIDTH, | 1191 | EXT_CSD_BUS_WIDTH, |
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 40989e6bb53a..236842ec955a 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c | |||
@@ -192,9 +192,15 @@ static int sdio_bus_remove(struct device *dev) | |||
192 | return ret; | 192 | return ret; |
193 | } | 193 | } |
194 | 194 | ||
195 | #ifdef CONFIG_PM_RUNTIME | 195 | #ifdef CONFIG_PM |
196 | |||
197 | static int pm_no_operation(struct device *dev) | ||
198 | { | ||
199 | return 0; | ||
200 | } | ||
196 | 201 | ||
197 | static const struct dev_pm_ops sdio_bus_pm_ops = { | 202 | static const struct dev_pm_ops sdio_bus_pm_ops = { |
203 | SET_SYSTEM_SLEEP_PM_OPS(pm_no_operation, pm_no_operation) | ||
198 | SET_RUNTIME_PM_OPS( | 204 | SET_RUNTIME_PM_OPS( |
199 | pm_generic_runtime_suspend, | 205 | pm_generic_runtime_suspend, |
200 | pm_generic_runtime_resume, | 206 | pm_generic_runtime_resume, |
@@ -204,11 +210,11 @@ static const struct dev_pm_ops sdio_bus_pm_ops = { | |||
204 | 210 | ||
205 | #define SDIO_PM_OPS_PTR (&sdio_bus_pm_ops) | 211 | #define SDIO_PM_OPS_PTR (&sdio_bus_pm_ops) |
206 | 212 | ||
207 | #else /* !CONFIG_PM_RUNTIME */ | 213 | #else /* !CONFIG_PM */ |
208 | 214 | ||
209 | #define SDIO_PM_OPS_PTR NULL | 215 | #define SDIO_PM_OPS_PTR NULL |
210 | 216 | ||
211 | #endif /* !CONFIG_PM_RUNTIME */ | 217 | #endif /* !CONFIG_PM */ |
212 | 218 | ||
213 | static struct bus_type sdio_bus_type = { | 219 | static struct bus_type sdio_bus_type = { |
214 | .name = "sdio", | 220 | .name = "sdio", |
diff --git a/drivers/mmc/host/atmel-mci-regs.h b/drivers/mmc/host/atmel-mci-regs.h index 000b3ad0f5ca..787aba1682bb 100644 --- a/drivers/mmc/host/atmel-mci-regs.h +++ b/drivers/mmc/host/atmel-mci-regs.h | |||
@@ -31,6 +31,7 @@ | |||
31 | # define ATMCI_MR_PDCFBYTE ( 1 << 13) /* Force Byte Transfer */ | 31 | # define ATMCI_MR_PDCFBYTE ( 1 << 13) /* Force Byte Transfer */ |
32 | # define ATMCI_MR_PDCPADV ( 1 << 14) /* Padding Value */ | 32 | # define ATMCI_MR_PDCPADV ( 1 << 14) /* Padding Value */ |
33 | # define ATMCI_MR_PDCMODE ( 1 << 15) /* PDC-oriented Mode */ | 33 | # define ATMCI_MR_PDCMODE ( 1 << 15) /* PDC-oriented Mode */ |
34 | # define ATMCI_MR_CLKODD(x) ((x) << 16) /* LSB of Clock Divider */ | ||
34 | #define ATMCI_DTOR 0x0008 /* Data Timeout */ | 35 | #define ATMCI_DTOR 0x0008 /* Data Timeout */ |
35 | # define ATMCI_DTOCYC(x) ((x) << 0) /* Data Timeout Cycles */ | 36 | # define ATMCI_DTOCYC(x) ((x) << 0) /* Data Timeout Cycles */ |
36 | # define ATMCI_DTOMUL(x) ((x) << 4) /* Data Timeout Multiplier */ | 37 | # define ATMCI_DTOMUL(x) ((x) << 4) /* Data Timeout Multiplier */ |
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 9819dc09ce08..e94476beca18 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c | |||
@@ -77,6 +77,7 @@ struct atmel_mci_caps { | |||
77 | bool has_cstor_reg; | 77 | bool has_cstor_reg; |
78 | bool has_highspeed; | 78 | bool has_highspeed; |
79 | bool has_rwproof; | 79 | bool has_rwproof; |
80 | bool has_odd_clk_div; | ||
80 | }; | 81 | }; |
81 | 82 | ||
82 | struct atmel_mci_dma { | 83 | struct atmel_mci_dma { |
@@ -482,7 +483,14 @@ err: | |||
482 | static inline unsigned int atmci_ns_to_clocks(struct atmel_mci *host, | 483 | static inline unsigned int atmci_ns_to_clocks(struct atmel_mci *host, |
483 | unsigned int ns) | 484 | unsigned int ns) |
484 | { | 485 | { |
485 | return (ns * (host->bus_hz / 1000000) + 999) / 1000; | 486 | /* |
487 | * It is easier here to use us instead of ns for the timeout, | ||
488 | * it prevents from overflows during calculation. | ||
489 | */ | ||
490 | unsigned int us = DIV_ROUND_UP(ns, 1000); | ||
491 | |||
492 | /* Maximum clock frequency is host->bus_hz/2 */ | ||
493 | return us * (DIV_ROUND_UP(host->bus_hz, 2000000)); | ||
486 | } | 494 | } |
487 | 495 | ||
488 | static void atmci_set_timeout(struct atmel_mci *host, | 496 | static void atmci_set_timeout(struct atmel_mci *host, |
@@ -1127,16 +1135,27 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1127 | } | 1135 | } |
1128 | 1136 | ||
1129 | /* Calculate clock divider */ | 1137 | /* Calculate clock divider */ |
1130 | clkdiv = DIV_ROUND_UP(host->bus_hz, 2 * clock_min) - 1; | 1138 | if (host->caps.has_odd_clk_div) { |
1131 | if (clkdiv > 255) { | 1139 | clkdiv = DIV_ROUND_UP(host->bus_hz, clock_min) - 2; |
1132 | dev_warn(&mmc->class_dev, | 1140 | if (clkdiv > 511) { |
1133 | "clock %u too slow; using %lu\n", | 1141 | dev_warn(&mmc->class_dev, |
1134 | clock_min, host->bus_hz / (2 * 256)); | 1142 | "clock %u too slow; using %lu\n", |
1135 | clkdiv = 255; | 1143 | clock_min, host->bus_hz / (511 + 2)); |
1144 | clkdiv = 511; | ||
1145 | } | ||
1146 | host->mode_reg = ATMCI_MR_CLKDIV(clkdiv >> 1) | ||
1147 | | ATMCI_MR_CLKODD(clkdiv & 1); | ||
1148 | } else { | ||
1149 | clkdiv = DIV_ROUND_UP(host->bus_hz, 2 * clock_min) - 1; | ||
1150 | if (clkdiv > 255) { | ||
1151 | dev_warn(&mmc->class_dev, | ||
1152 | "clock %u too slow; using %lu\n", | ||
1153 | clock_min, host->bus_hz / (2 * 256)); | ||
1154 | clkdiv = 255; | ||
1155 | } | ||
1156 | host->mode_reg = ATMCI_MR_CLKDIV(clkdiv); | ||
1136 | } | 1157 | } |
1137 | 1158 | ||
1138 | host->mode_reg = ATMCI_MR_CLKDIV(clkdiv); | ||
1139 | |||
1140 | /* | 1159 | /* |
1141 | * WRPROOF and RDPROOF prevent overruns/underruns by | 1160 | * WRPROOF and RDPROOF prevent overruns/underruns by |
1142 | * stopping the clock when the FIFO is full/empty. | 1161 | * stopping the clock when the FIFO is full/empty. |
@@ -2007,35 +2026,35 @@ static void __init atmci_get_cap(struct atmel_mci *host) | |||
2007 | "version: 0x%x\n", version); | 2026 | "version: 0x%x\n", version); |
2008 | 2027 | ||
2009 | host->caps.has_dma = 0; | 2028 | host->caps.has_dma = 0; |
2010 | host->caps.has_pdc = 0; | 2029 | host->caps.has_pdc = 1; |
2011 | host->caps.has_cfg_reg = 0; | 2030 | host->caps.has_cfg_reg = 0; |
2012 | host->caps.has_cstor_reg = 0; | 2031 | host->caps.has_cstor_reg = 0; |
2013 | host->caps.has_highspeed = 0; | 2032 | host->caps.has_highspeed = 0; |
2014 | host->caps.has_rwproof = 0; | 2033 | host->caps.has_rwproof = 0; |
2034 | host->caps.has_odd_clk_div = 0; | ||
2015 | 2035 | ||
2016 | /* keep only major version number */ | 2036 | /* keep only major version number */ |
2017 | switch (version & 0xf00) { | 2037 | switch (version & 0xf00) { |
2018 | case 0x100: | ||
2019 | case 0x200: | ||
2020 | host->caps.has_pdc = 1; | ||
2021 | host->caps.has_rwproof = 1; | ||
2022 | break; | ||
2023 | case 0x300: | ||
2024 | case 0x400: | ||
2025 | case 0x500: | 2038 | case 0x500: |
2039 | host->caps.has_odd_clk_div = 1; | ||
2040 | case 0x400: | ||
2041 | case 0x300: | ||
2026 | #ifdef CONFIG_AT_HDMAC | 2042 | #ifdef CONFIG_AT_HDMAC |
2027 | host->caps.has_dma = 1; | 2043 | host->caps.has_dma = 1; |
2028 | #else | 2044 | #else |
2029 | host->caps.has_dma = 0; | ||
2030 | dev_info(&host->pdev->dev, | 2045 | dev_info(&host->pdev->dev, |
2031 | "has dma capability but dma engine is not selected, then use pio\n"); | 2046 | "has dma capability but dma engine is not selected, then use pio\n"); |
2032 | #endif | 2047 | #endif |
2048 | host->caps.has_pdc = 0; | ||
2033 | host->caps.has_cfg_reg = 1; | 2049 | host->caps.has_cfg_reg = 1; |
2034 | host->caps.has_cstor_reg = 1; | 2050 | host->caps.has_cstor_reg = 1; |
2035 | host->caps.has_highspeed = 1; | 2051 | host->caps.has_highspeed = 1; |
2052 | case 0x200: | ||
2036 | host->caps.has_rwproof = 1; | 2053 | host->caps.has_rwproof = 1; |
2054 | case 0x100: | ||
2037 | break; | 2055 | break; |
2038 | default: | 2056 | default: |
2057 | host->caps.has_pdc = 0; | ||
2039 | dev_warn(&host->pdev->dev, | 2058 | dev_warn(&host->pdev->dev, |
2040 | "Unmanaged mci version, set minimum capabilities\n"); | 2059 | "Unmanaged mci version, set minimum capabilities\n"); |
2041 | break; | 2060 | break; |
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index bf3c9b456aaf..ab3fc4617107 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c | |||
@@ -526,8 +526,10 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data) | |||
526 | return -ENODEV; | 526 | return -ENODEV; |
527 | 527 | ||
528 | sg_len = dw_mci_pre_dma_transfer(host, data, 0); | 528 | sg_len = dw_mci_pre_dma_transfer(host, data, 0); |
529 | if (sg_len < 0) | 529 | if (sg_len < 0) { |
530 | host->dma_ops->stop(host); | ||
530 | return sg_len; | 531 | return sg_len; |
532 | } | ||
531 | 533 | ||
532 | host->using_dma = 1; | 534 | host->using_dma = 1; |
533 | 535 | ||
@@ -1879,7 +1881,8 @@ static void dw_mci_init_dma(struct dw_mci *host) | |||
1879 | if (!host->dma_ops) | 1881 | if (!host->dma_ops) |
1880 | goto no_dma; | 1882 | goto no_dma; |
1881 | 1883 | ||
1882 | if (host->dma_ops->init) { | 1884 | if (host->dma_ops->init && host->dma_ops->start && |
1885 | host->dma_ops->stop && host->dma_ops->cleanup) { | ||
1883 | if (host->dma_ops->init(host)) { | 1886 | if (host->dma_ops->init(host)) { |
1884 | dev_err(&host->dev, "%s: Unable to initialize " | 1887 | dev_err(&host->dev, "%s: Unable to initialize " |
1885 | "DMA Controller.\n", __func__); | 1888 | "DMA Controller.\n", __func__); |
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index b0f2ef988188..e3f5af96ab87 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c | |||
@@ -363,6 +363,7 @@ static void mxs_mmc_bc(struct mxs_mmc_host *host) | |||
363 | goto out; | 363 | goto out; |
364 | 364 | ||
365 | dmaengine_submit(desc); | 365 | dmaengine_submit(desc); |
366 | dma_async_issue_pending(host->dmach); | ||
366 | return; | 367 | return; |
367 | 368 | ||
368 | out: | 369 | out: |
@@ -403,6 +404,7 @@ static void mxs_mmc_ac(struct mxs_mmc_host *host) | |||
403 | goto out; | 404 | goto out; |
404 | 405 | ||
405 | dmaengine_submit(desc); | 406 | dmaengine_submit(desc); |
407 | dma_async_issue_pending(host->dmach); | ||
406 | return; | 408 | return; |
407 | 409 | ||
408 | out: | 410 | out: |
@@ -531,6 +533,7 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host) | |||
531 | goto out; | 533 | goto out; |
532 | 534 | ||
533 | dmaengine_submit(desc); | 535 | dmaengine_submit(desc); |
536 | dma_async_issue_pending(host->dmach); | ||
534 | return; | 537 | return; |
535 | out: | 538 | out: |
536 | dev_warn(mmc_dev(host->mmc), | 539 | dev_warn(mmc_dev(host->mmc), |
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 47adb161d3ad..33e81c24e140 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
@@ -249,7 +249,7 @@ static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on, | |||
249 | * the pbias cell programming support is still missing when | 249 | * the pbias cell programming support is still missing when |
250 | * booting with Device tree | 250 | * booting with Device tree |
251 | */ | 251 | */ |
252 | if (of_have_populated_dt() && !vdd) | 252 | if (dev->of_node && !vdd) |
253 | return 0; | 253 | return 0; |
254 | 254 | ||
255 | if (mmc_slot(host).before_set_reg) | 255 | if (mmc_slot(host).before_set_reg) |
@@ -1549,7 +1549,7 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1549 | * can't be allowed when booting with device | 1549 | * can't be allowed when booting with device |
1550 | * tree. | 1550 | * tree. |
1551 | */ | 1551 | */ |
1552 | (!of_have_populated_dt())) { | 1552 | !host->dev->of_node) { |
1553 | /* | 1553 | /* |
1554 | * The mmc_select_voltage fn of the core does | 1554 | * The mmc_select_voltage fn of the core does |
1555 | * not seem to set the power_mode to | 1555 | * not seem to set the power_mode to |
@@ -1741,7 +1741,7 @@ static const struct of_device_id omap_mmc_of_match[] = { | |||
1741 | .data = &omap4_reg_offset, | 1741 | .data = &omap4_reg_offset, |
1742 | }, | 1742 | }, |
1743 | {}, | 1743 | {}, |
1744 | } | 1744 | }; |
1745 | MODULE_DEVICE_TABLE(of, omap_mmc_of_match); | 1745 | MODULE_DEVICE_TABLE(of, omap_mmc_of_match); |
1746 | 1746 | ||
1747 | static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev) | 1747 | static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev) |
@@ -1766,7 +1766,7 @@ static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev) | |||
1766 | pdata->slots[0].nonremovable = true; | 1766 | pdata->slots[0].nonremovable = true; |
1767 | pdata->slots[0].no_regulator_off_init = true; | 1767 | pdata->slots[0].no_regulator_off_init = true; |
1768 | } | 1768 | } |
1769 | of_property_read_u32(np, "ti,bus-width", &bus_width); | 1769 | of_property_read_u32(np, "bus-width", &bus_width); |
1770 | if (bus_width == 4) | 1770 | if (bus_width == 4) |
1771 | pdata->slots[0].caps |= MMC_CAP_4_BIT_DATA; | 1771 | pdata->slots[0].caps |= MMC_CAP_4_BIT_DATA; |
1772 | else if (bus_width == 8) | 1772 | else if (bus_width == 8) |
@@ -1785,7 +1785,7 @@ static inline struct omap_mmc_platform_data | |||
1785 | } | 1785 | } |
1786 | #endif | 1786 | #endif |
1787 | 1787 | ||
1788 | static int __init omap_hsmmc_probe(struct platform_device *pdev) | 1788 | static int __devinit omap_hsmmc_probe(struct platform_device *pdev) |
1789 | { | 1789 | { |
1790 | struct omap_mmc_platform_data *pdata = pdev->dev.platform_data; | 1790 | struct omap_mmc_platform_data *pdata = pdev->dev.platform_data; |
1791 | struct mmc_host *mmc; | 1791 | struct mmc_host *mmc; |
@@ -1818,8 +1818,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
1818 | if (res == NULL || irq < 0) | 1818 | if (res == NULL || irq < 0) |
1819 | return -ENXIO; | 1819 | return -ENXIO; |
1820 | 1820 | ||
1821 | res->start += pdata->reg_offset; | ||
1822 | res->end += pdata->reg_offset; | ||
1823 | res = request_mem_region(res->start, resource_size(res), pdev->name); | 1821 | res = request_mem_region(res->start, resource_size(res), pdev->name); |
1824 | if (res == NULL) | 1822 | if (res == NULL) |
1825 | return -EBUSY; | 1823 | return -EBUSY; |
@@ -1843,7 +1841,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
1843 | host->dma_ch = -1; | 1841 | host->dma_ch = -1; |
1844 | host->irq = irq; | 1842 | host->irq = irq; |
1845 | host->slot_id = 0; | 1843 | host->slot_id = 0; |
1846 | host->mapbase = res->start; | 1844 | host->mapbase = res->start + pdata->reg_offset; |
1847 | host->base = ioremap(host->mapbase, SZ_4K); | 1845 | host->base = ioremap(host->mapbase, SZ_4K); |
1848 | host->power_mode = MMC_POWER_OFF; | 1846 | host->power_mode = MMC_POWER_OFF; |
1849 | host->next_data.cookie = 1; | 1847 | host->next_data.cookie = 1; |
@@ -1875,8 +1873,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
1875 | goto err1; | 1873 | goto err1; |
1876 | } | 1874 | } |
1877 | 1875 | ||
1878 | omap_hsmmc_context_save(host); | ||
1879 | |||
1880 | if (host->pdata->controller_flags & OMAP_HSMMC_BROKEN_MULTIBLOCK_READ) { | 1876 | if (host->pdata->controller_flags & OMAP_HSMMC_BROKEN_MULTIBLOCK_READ) { |
1881 | dev_info(&pdev->dev, "multiblock reads disabled due to 35xx erratum 2.1.1.128; MMC read performance may suffer\n"); | 1877 | dev_info(&pdev->dev, "multiblock reads disabled due to 35xx erratum 2.1.1.128; MMC read performance may suffer\n"); |
1882 | mmc->caps2 |= MMC_CAP2_NO_MULTI_READ; | 1878 | mmc->caps2 |= MMC_CAP2_NO_MULTI_READ; |
@@ -1887,6 +1883,8 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
1887 | pm_runtime_set_autosuspend_delay(host->dev, MMC_AUTOSUSPEND_DELAY); | 1883 | pm_runtime_set_autosuspend_delay(host->dev, MMC_AUTOSUSPEND_DELAY); |
1888 | pm_runtime_use_autosuspend(host->dev); | 1884 | pm_runtime_use_autosuspend(host->dev); |
1889 | 1885 | ||
1886 | omap_hsmmc_context_save(host); | ||
1887 | |||
1890 | if (cpu_is_omap2430()) { | 1888 | if (cpu_is_omap2430()) { |
1891 | host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck"); | 1889 | host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck"); |
1892 | /* | 1890 | /* |
@@ -2018,8 +2016,7 @@ err_reg: | |||
2018 | err_irq_cd_init: | 2016 | err_irq_cd_init: |
2019 | free_irq(host->irq, host); | 2017 | free_irq(host->irq, host); |
2020 | err_irq: | 2018 | err_irq: |
2021 | pm_runtime_mark_last_busy(host->dev); | 2019 | pm_runtime_put_sync(host->dev); |
2022 | pm_runtime_put_autosuspend(host->dev); | ||
2023 | pm_runtime_disable(host->dev); | 2020 | pm_runtime_disable(host->dev); |
2024 | clk_put(host->fclk); | 2021 | clk_put(host->fclk); |
2025 | if (host->got_dbclk) { | 2022 | if (host->got_dbclk) { |
@@ -2037,35 +2034,33 @@ err: | |||
2037 | return ret; | 2034 | return ret; |
2038 | } | 2035 | } |
2039 | 2036 | ||
2040 | static int omap_hsmmc_remove(struct platform_device *pdev) | 2037 | static int __devexit omap_hsmmc_remove(struct platform_device *pdev) |
2041 | { | 2038 | { |
2042 | struct omap_hsmmc_host *host = platform_get_drvdata(pdev); | 2039 | struct omap_hsmmc_host *host = platform_get_drvdata(pdev); |
2043 | struct resource *res; | 2040 | struct resource *res; |
2044 | 2041 | ||
2045 | if (host) { | 2042 | pm_runtime_get_sync(host->dev); |
2046 | pm_runtime_get_sync(host->dev); | 2043 | mmc_remove_host(host->mmc); |
2047 | mmc_remove_host(host->mmc); | 2044 | if (host->use_reg) |
2048 | if (host->use_reg) | 2045 | omap_hsmmc_reg_put(host); |
2049 | omap_hsmmc_reg_put(host); | 2046 | if (host->pdata->cleanup) |
2050 | if (host->pdata->cleanup) | 2047 | host->pdata->cleanup(&pdev->dev); |
2051 | host->pdata->cleanup(&pdev->dev); | 2048 | free_irq(host->irq, host); |
2052 | free_irq(host->irq, host); | 2049 | if (mmc_slot(host).card_detect_irq) |
2053 | if (mmc_slot(host).card_detect_irq) | 2050 | free_irq(mmc_slot(host).card_detect_irq, host); |
2054 | free_irq(mmc_slot(host).card_detect_irq, host); | ||
2055 | |||
2056 | pm_runtime_put_sync(host->dev); | ||
2057 | pm_runtime_disable(host->dev); | ||
2058 | clk_put(host->fclk); | ||
2059 | if (host->got_dbclk) { | ||
2060 | clk_disable(host->dbclk); | ||
2061 | clk_put(host->dbclk); | ||
2062 | } | ||
2063 | 2051 | ||
2064 | mmc_free_host(host->mmc); | 2052 | pm_runtime_put_sync(host->dev); |
2065 | iounmap(host->base); | 2053 | pm_runtime_disable(host->dev); |
2066 | omap_hsmmc_gpio_free(pdev->dev.platform_data); | 2054 | clk_put(host->fclk); |
2055 | if (host->got_dbclk) { | ||
2056 | clk_disable(host->dbclk); | ||
2057 | clk_put(host->dbclk); | ||
2067 | } | 2058 | } |
2068 | 2059 | ||
2060 | mmc_free_host(host->mmc); | ||
2061 | iounmap(host->base); | ||
2062 | omap_hsmmc_gpio_free(pdev->dev.platform_data); | ||
2063 | |||
2069 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2064 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2070 | if (res) | 2065 | if (res) |
2071 | release_mem_region(res->start, resource_size(res)); | 2066 | release_mem_region(res->start, resource_size(res)); |
@@ -2078,49 +2073,45 @@ static int omap_hsmmc_remove(struct platform_device *pdev) | |||
2078 | static int omap_hsmmc_suspend(struct device *dev) | 2073 | static int omap_hsmmc_suspend(struct device *dev) |
2079 | { | 2074 | { |
2080 | int ret = 0; | 2075 | int ret = 0; |
2081 | struct platform_device *pdev = to_platform_device(dev); | 2076 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); |
2082 | struct omap_hsmmc_host *host = platform_get_drvdata(pdev); | ||
2083 | 2077 | ||
2084 | if (host && host->suspended) | 2078 | if (!host) |
2085 | return 0; | 2079 | return 0; |
2086 | 2080 | ||
2087 | if (host) { | 2081 | if (host && host->suspended) |
2088 | pm_runtime_get_sync(host->dev); | 2082 | return 0; |
2089 | host->suspended = 1; | ||
2090 | if (host->pdata->suspend) { | ||
2091 | ret = host->pdata->suspend(&pdev->dev, | ||
2092 | host->slot_id); | ||
2093 | if (ret) { | ||
2094 | dev_dbg(mmc_dev(host->mmc), | ||
2095 | "Unable to handle MMC board" | ||
2096 | " level suspend\n"); | ||
2097 | host->suspended = 0; | ||
2098 | return ret; | ||
2099 | } | ||
2100 | } | ||
2101 | ret = mmc_suspend_host(host->mmc); | ||
2102 | 2083 | ||
2084 | pm_runtime_get_sync(host->dev); | ||
2085 | host->suspended = 1; | ||
2086 | if (host->pdata->suspend) { | ||
2087 | ret = host->pdata->suspend(dev, host->slot_id); | ||
2103 | if (ret) { | 2088 | if (ret) { |
2089 | dev_dbg(dev, "Unable to handle MMC board" | ||
2090 | " level suspend\n"); | ||
2104 | host->suspended = 0; | 2091 | host->suspended = 0; |
2105 | if (host->pdata->resume) { | 2092 | return ret; |
2106 | ret = host->pdata->resume(&pdev->dev, | ||
2107 | host->slot_id); | ||
2108 | if (ret) | ||
2109 | dev_dbg(mmc_dev(host->mmc), | ||
2110 | "Unmask interrupt failed\n"); | ||
2111 | } | ||
2112 | goto err; | ||
2113 | } | 2093 | } |
2094 | } | ||
2095 | ret = mmc_suspend_host(host->mmc); | ||
2114 | 2096 | ||
2115 | if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) { | 2097 | if (ret) { |
2116 | omap_hsmmc_disable_irq(host); | 2098 | host->suspended = 0; |
2117 | OMAP_HSMMC_WRITE(host->base, HCTL, | 2099 | if (host->pdata->resume) { |
2118 | OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP); | 2100 | ret = host->pdata->resume(dev, host->slot_id); |
2101 | if (ret) | ||
2102 | dev_dbg(dev, "Unmask interrupt failed\n"); | ||
2119 | } | 2103 | } |
2120 | if (host->got_dbclk) | 2104 | goto err; |
2121 | clk_disable(host->dbclk); | 2105 | } |
2122 | 2106 | ||
2107 | if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) { | ||
2108 | omap_hsmmc_disable_irq(host); | ||
2109 | OMAP_HSMMC_WRITE(host->base, HCTL, | ||
2110 | OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP); | ||
2123 | } | 2111 | } |
2112 | |||
2113 | if (host->got_dbclk) | ||
2114 | clk_disable(host->dbclk); | ||
2124 | err: | 2115 | err: |
2125 | pm_runtime_put_sync(host->dev); | 2116 | pm_runtime_put_sync(host->dev); |
2126 | return ret; | 2117 | return ret; |
@@ -2130,38 +2121,37 @@ err: | |||
2130 | static int omap_hsmmc_resume(struct device *dev) | 2121 | static int omap_hsmmc_resume(struct device *dev) |
2131 | { | 2122 | { |
2132 | int ret = 0; | 2123 | int ret = 0; |
2133 | struct platform_device *pdev = to_platform_device(dev); | 2124 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); |
2134 | struct omap_hsmmc_host *host = platform_get_drvdata(pdev); | 2125 | |
2126 | if (!host) | ||
2127 | return 0; | ||
2135 | 2128 | ||
2136 | if (host && !host->suspended) | 2129 | if (host && !host->suspended) |
2137 | return 0; | 2130 | return 0; |
2138 | 2131 | ||
2139 | if (host) { | 2132 | pm_runtime_get_sync(host->dev); |
2140 | pm_runtime_get_sync(host->dev); | ||
2141 | 2133 | ||
2142 | if (host->got_dbclk) | 2134 | if (host->got_dbclk) |
2143 | clk_enable(host->dbclk); | 2135 | clk_enable(host->dbclk); |
2144 | 2136 | ||
2145 | if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) | 2137 | if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) |
2146 | omap_hsmmc_conf_bus_power(host); | 2138 | omap_hsmmc_conf_bus_power(host); |
2147 | 2139 | ||
2148 | if (host->pdata->resume) { | 2140 | if (host->pdata->resume) { |
2149 | ret = host->pdata->resume(&pdev->dev, host->slot_id); | 2141 | ret = host->pdata->resume(dev, host->slot_id); |
2150 | if (ret) | 2142 | if (ret) |
2151 | dev_dbg(mmc_dev(host->mmc), | 2143 | dev_dbg(dev, "Unmask interrupt failed\n"); |
2152 | "Unmask interrupt failed\n"); | 2144 | } |
2153 | } | ||
2154 | 2145 | ||
2155 | omap_hsmmc_protect_card(host); | 2146 | omap_hsmmc_protect_card(host); |
2156 | 2147 | ||
2157 | /* Notify the core to resume the host */ | 2148 | /* Notify the core to resume the host */ |
2158 | ret = mmc_resume_host(host->mmc); | 2149 | ret = mmc_resume_host(host->mmc); |
2159 | if (ret == 0) | 2150 | if (ret == 0) |
2160 | host->suspended = 0; | 2151 | host->suspended = 0; |
2161 | 2152 | ||
2162 | pm_runtime_mark_last_busy(host->dev); | 2153 | pm_runtime_mark_last_busy(host->dev); |
2163 | pm_runtime_put_autosuspend(host->dev); | 2154 | pm_runtime_put_autosuspend(host->dev); |
2164 | } | ||
2165 | 2155 | ||
2166 | return ret; | 2156 | return ret; |
2167 | 2157 | ||
@@ -2178,7 +2168,7 @@ static int omap_hsmmc_runtime_suspend(struct device *dev) | |||
2178 | 2168 | ||
2179 | host = platform_get_drvdata(to_platform_device(dev)); | 2169 | host = platform_get_drvdata(to_platform_device(dev)); |
2180 | omap_hsmmc_context_save(host); | 2170 | omap_hsmmc_context_save(host); |
2181 | dev_dbg(mmc_dev(host->mmc), "disabled\n"); | 2171 | dev_dbg(dev, "disabled\n"); |
2182 | 2172 | ||
2183 | return 0; | 2173 | return 0; |
2184 | } | 2174 | } |
@@ -2189,7 +2179,7 @@ static int omap_hsmmc_runtime_resume(struct device *dev) | |||
2189 | 2179 | ||
2190 | host = platform_get_drvdata(to_platform_device(dev)); | 2180 | host = platform_get_drvdata(to_platform_device(dev)); |
2191 | omap_hsmmc_context_restore(host); | 2181 | omap_hsmmc_context_restore(host); |
2192 | dev_dbg(mmc_dev(host->mmc), "enabled\n"); | 2182 | dev_dbg(dev, "enabled\n"); |
2193 | 2183 | ||
2194 | return 0; | 2184 | return 0; |
2195 | } | 2185 | } |
@@ -2202,7 +2192,8 @@ static struct dev_pm_ops omap_hsmmc_dev_pm_ops = { | |||
2202 | }; | 2192 | }; |
2203 | 2193 | ||
2204 | static struct platform_driver omap_hsmmc_driver = { | 2194 | static struct platform_driver omap_hsmmc_driver = { |
2205 | .remove = omap_hsmmc_remove, | 2195 | .probe = omap_hsmmc_probe, |
2196 | .remove = __devexit_p(omap_hsmmc_remove), | ||
2206 | .driver = { | 2197 | .driver = { |
2207 | .name = DRIVER_NAME, | 2198 | .name = DRIVER_NAME, |
2208 | .owner = THIS_MODULE, | 2199 | .owner = THIS_MODULE, |
@@ -2211,21 +2202,7 @@ static struct platform_driver omap_hsmmc_driver = { | |||
2211 | }, | 2202 | }, |
2212 | }; | 2203 | }; |
2213 | 2204 | ||
2214 | static int __init omap_hsmmc_init(void) | 2205 | module_platform_driver(omap_hsmmc_driver); |
2215 | { | ||
2216 | /* Register the MMC driver */ | ||
2217 | return platform_driver_probe(&omap_hsmmc_driver, omap_hsmmc_probe); | ||
2218 | } | ||
2219 | |||
2220 | static void __exit omap_hsmmc_cleanup(void) | ||
2221 | { | ||
2222 | /* Unregister MMC driver */ | ||
2223 | platform_driver_unregister(&omap_hsmmc_driver); | ||
2224 | } | ||
2225 | |||
2226 | module_init(omap_hsmmc_init); | ||
2227 | module_exit(omap_hsmmc_cleanup); | ||
2228 | |||
2229 | MODULE_DESCRIPTION("OMAP High Speed Multimedia Card driver"); | 2206 | MODULE_DESCRIPTION("OMAP High Speed Multimedia Card driver"); |
2230 | MODULE_LICENSE("GPL"); | 2207 | MODULE_LICENSE("GPL"); |
2231 | MODULE_ALIAS("platform:" DRIVER_NAME); | 2208 | MODULE_ALIAS("platform:" DRIVER_NAME); |
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c index 46fd1fd1b605..177f697b5835 100644 --- a/drivers/mmc/host/sdhci-dove.c +++ b/drivers/mmc/host/sdhci-dove.c | |||
@@ -20,6 +20,7 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/module.h> | ||
23 | #include <linux/mmc/host.h> | 24 | #include <linux/mmc/host.h> |
24 | 25 | ||
25 | #include "sdhci-pltfm.h" | 26 | #include "sdhci-pltfm.h" |
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 6193a0d7bde5..0d2b082f2246 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c | |||
@@ -402,7 +402,7 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev, | |||
402 | if (!np) | 402 | if (!np) |
403 | return -ENODEV; | 403 | return -ENODEV; |
404 | 404 | ||
405 | if (of_get_property(np, "fsl,card-wired", NULL)) | 405 | if (of_get_property(np, "non-removable", NULL)) |
406 | boarddata->cd_type = ESDHC_CD_PERMANENT; | 406 | boarddata->cd_type = ESDHC_CD_PERMANENT; |
407 | 407 | ||
408 | if (of_get_property(np, "fsl,cd-controller", NULL)) | 408 | if (of_get_property(np, "fsl,cd-controller", NULL)) |
@@ -467,8 +467,7 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev) | |||
467 | clk_prepare_enable(clk); | 467 | clk_prepare_enable(clk); |
468 | pltfm_host->clk = clk; | 468 | pltfm_host->clk = clk; |
469 | 469 | ||
470 | if (!is_imx25_esdhc(imx_data)) | 470 | host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; |
471 | host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; | ||
472 | 471 | ||
473 | if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data)) | 472 | if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data)) |
474 | /* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */ | 473 | /* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */ |
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index fbbebe251e01..69ef0beae104 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
@@ -1418,8 +1418,6 @@ static int __devinit sdhci_pci_probe(struct pci_dev *pdev, | |||
1418 | 1418 | ||
1419 | slots = chip->num_slots; /* Quirk may have changed this */ | 1419 | slots = chip->num_slots; /* Quirk may have changed this */ |
1420 | 1420 | ||
1421 | pci_enable_msi(pdev); | ||
1422 | |||
1423 | for (i = 0; i < slots; i++) { | 1421 | for (i = 0; i < slots; i++) { |
1424 | slot = sdhci_pci_probe_slot(pdev, chip, first_bar, i); | 1422 | slot = sdhci_pci_probe_slot(pdev, chip, first_bar, i); |
1425 | if (IS_ERR(slot)) { | 1423 | if (IS_ERR(slot)) { |
@@ -1438,8 +1436,6 @@ static int __devinit sdhci_pci_probe(struct pci_dev *pdev, | |||
1438 | return 0; | 1436 | return 0; |
1439 | 1437 | ||
1440 | free: | 1438 | free: |
1441 | pci_disable_msi(pdev); | ||
1442 | |||
1443 | pci_set_drvdata(pdev, NULL); | 1439 | pci_set_drvdata(pdev, NULL); |
1444 | kfree(chip); | 1440 | kfree(chip); |
1445 | 1441 | ||
@@ -1462,8 +1458,6 @@ static void __devexit sdhci_pci_remove(struct pci_dev *pdev) | |||
1462 | for (i = 0; i < chip->num_slots; i++) | 1458 | for (i = 0; i < chip->num_slots; i++) |
1463 | sdhci_pci_remove_slot(chip->slots[i]); | 1459 | sdhci_pci_remove_slot(chip->slots[i]); |
1464 | 1460 | ||
1465 | pci_disable_msi(pdev); | ||
1466 | |||
1467 | pci_set_drvdata(pdev, NULL); | 1461 | pci_set_drvdata(pdev, NULL); |
1468 | kfree(chip); | 1462 | kfree(chip); |
1469 | } | 1463 | } |
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c index c5c2a48bdd94..d9a4ef4f1ed0 100644 --- a/drivers/mmc/host/sdhci-pltfm.c +++ b/drivers/mmc/host/sdhci-pltfm.c | |||
@@ -42,7 +42,8 @@ static struct sdhci_ops sdhci_pltfm_ops = { | |||
42 | #ifdef CONFIG_OF | 42 | #ifdef CONFIG_OF |
43 | static bool sdhci_of_wp_inverted(struct device_node *np) | 43 | static bool sdhci_of_wp_inverted(struct device_node *np) |
44 | { | 44 | { |
45 | if (of_get_property(np, "sdhci,wp-inverted", NULL)) | 45 | if (of_get_property(np, "sdhci,wp-inverted", NULL) || |
46 | of_get_property(np, "wp-inverted", NULL)) | ||
46 | return true; | 47 | return true; |
47 | 48 | ||
48 | /* Old device trees don't have the wp-inverted property. */ | 49 | /* Old device trees don't have the wp-inverted property. */ |
@@ -59,13 +60,16 @@ void sdhci_get_of_property(struct platform_device *pdev) | |||
59 | struct sdhci_host *host = platform_get_drvdata(pdev); | 60 | struct sdhci_host *host = platform_get_drvdata(pdev); |
60 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 61 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
61 | const __be32 *clk; | 62 | const __be32 *clk; |
63 | u32 bus_width; | ||
62 | int size; | 64 | int size; |
63 | 65 | ||
64 | if (of_device_is_available(np)) { | 66 | if (of_device_is_available(np)) { |
65 | if (of_get_property(np, "sdhci,auto-cmd12", NULL)) | 67 | if (of_get_property(np, "sdhci,auto-cmd12", NULL)) |
66 | host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12; | 68 | host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12; |
67 | 69 | ||
68 | if (of_get_property(np, "sdhci,1-bit-only", NULL)) | 70 | if (of_get_property(np, "sdhci,1-bit-only", NULL) || |
71 | (of_property_read_u32(np, "bus-width", &bus_width) == 0 && | ||
72 | bus_width == 1)) | ||
69 | host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA; | 73 | host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA; |
70 | 74 | ||
71 | if (sdhci_of_wp_inverted(np)) | 75 | if (sdhci_of_wp_inverted(np)) |
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index b19e7d435f8d..55a164fcaa15 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
@@ -20,6 +20,10 @@ | |||
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/gpio.h> | 21 | #include <linux/gpio.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/of.h> | ||
24 | #include <linux/of_gpio.h> | ||
25 | #include <linux/pm.h> | ||
26 | #include <linux/pm_runtime.h> | ||
23 | 27 | ||
24 | #include <linux/mmc/host.h> | 28 | #include <linux/mmc/host.h> |
25 | 29 | ||
@@ -53,6 +57,18 @@ struct sdhci_s3c { | |||
53 | struct clk *clk_bus[MAX_BUS_CLK]; | 57 | struct clk *clk_bus[MAX_BUS_CLK]; |
54 | }; | 58 | }; |
55 | 59 | ||
60 | /** | ||
61 | * struct sdhci_s3c_driver_data - S3C SDHCI platform specific driver data | ||
62 | * @sdhci_quirks: sdhci host specific quirks. | ||
63 | * | ||
64 | * Specifies platform specific configuration of sdhci controller. | ||
65 | * Note: A structure for driver specific platform data is used for future | ||
66 | * expansion of its usage. | ||
67 | */ | ||
68 | struct sdhci_s3c_drv_data { | ||
69 | unsigned int sdhci_quirks; | ||
70 | }; | ||
71 | |||
56 | static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host) | 72 | static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host) |
57 | { | 73 | { |
58 | return sdhci_priv(host); | 74 | return sdhci_priv(host); |
@@ -132,10 +148,10 @@ static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost, | |||
132 | return UINT_MAX; | 148 | return UINT_MAX; |
133 | 149 | ||
134 | /* | 150 | /* |
135 | * Clock divider's step is different as 1 from that of host controller | 151 | * If controller uses a non-standard clock division, find the best clock |
136 | * when 'clk_type' is S3C_SDHCI_CLK_DIV_EXTERNAL. | 152 | * speed possible with selected clock source and skip the division. |
137 | */ | 153 | */ |
138 | if (ourhost->pdata->clk_type) { | 154 | if (ourhost->host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) { |
139 | rate = clk_round_rate(clksrc, wanted); | 155 | rate = clk_round_rate(clksrc, wanted); |
140 | return wanted - rate; | 156 | return wanted - rate; |
141 | } | 157 | } |
@@ -272,6 +288,8 @@ static unsigned int sdhci_cmu_get_min_clock(struct sdhci_host *host) | |||
272 | static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock) | 288 | static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock) |
273 | { | 289 | { |
274 | struct sdhci_s3c *ourhost = to_s3c(host); | 290 | struct sdhci_s3c *ourhost = to_s3c(host); |
291 | unsigned long timeout; | ||
292 | u16 clk = 0; | ||
275 | 293 | ||
276 | /* don't bother if the clock is going off */ | 294 | /* don't bother if the clock is going off */ |
277 | if (clock == 0) | 295 | if (clock == 0) |
@@ -282,6 +300,25 @@ static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock) | |||
282 | clk_set_rate(ourhost->clk_bus[ourhost->cur_clk], clock); | 300 | clk_set_rate(ourhost->clk_bus[ourhost->cur_clk], clock); |
283 | 301 | ||
284 | host->clock = clock; | 302 | host->clock = clock; |
303 | |||
304 | clk = SDHCI_CLOCK_INT_EN; | ||
305 | sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); | ||
306 | |||
307 | /* Wait max 20 ms */ | ||
308 | timeout = 20; | ||
309 | while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL)) | ||
310 | & SDHCI_CLOCK_INT_STABLE)) { | ||
311 | if (timeout == 0) { | ||
312 | printk(KERN_ERR "%s: Internal clock never " | ||
313 | "stabilised.\n", mmc_hostname(host->mmc)); | ||
314 | return; | ||
315 | } | ||
316 | timeout--; | ||
317 | mdelay(1); | ||
318 | } | ||
319 | |||
320 | clk |= SDHCI_CLOCK_CARD_EN; | ||
321 | sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); | ||
285 | } | 322 | } |
286 | 323 | ||
287 | /** | 324 | /** |
@@ -382,16 +419,24 @@ static void sdhci_s3c_setup_card_detect_gpio(struct sdhci_s3c *sc) | |||
382 | } | 419 | } |
383 | } | 420 | } |
384 | 421 | ||
422 | static inline struct sdhci_s3c_drv_data *sdhci_s3c_get_driver_data( | ||
423 | struct platform_device *pdev) | ||
424 | { | ||
425 | return (struct sdhci_s3c_drv_data *) | ||
426 | platform_get_device_id(pdev)->driver_data; | ||
427 | } | ||
428 | |||
385 | static int __devinit sdhci_s3c_probe(struct platform_device *pdev) | 429 | static int __devinit sdhci_s3c_probe(struct platform_device *pdev) |
386 | { | 430 | { |
387 | struct s3c_sdhci_platdata *pdata = pdev->dev.platform_data; | 431 | struct s3c_sdhci_platdata *pdata; |
432 | struct sdhci_s3c_drv_data *drv_data; | ||
388 | struct device *dev = &pdev->dev; | 433 | struct device *dev = &pdev->dev; |
389 | struct sdhci_host *host; | 434 | struct sdhci_host *host; |
390 | struct sdhci_s3c *sc; | 435 | struct sdhci_s3c *sc; |
391 | struct resource *res; | 436 | struct resource *res; |
392 | int ret, irq, ptr, clks; | 437 | int ret, irq, ptr, clks; |
393 | 438 | ||
394 | if (!pdata) { | 439 | if (!pdev->dev.platform_data) { |
395 | dev_err(dev, "no device data specified\n"); | 440 | dev_err(dev, "no device data specified\n"); |
396 | return -ENOENT; | 441 | return -ENOENT; |
397 | } | 442 | } |
@@ -402,18 +447,20 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) | |||
402 | return irq; | 447 | return irq; |
403 | } | 448 | } |
404 | 449 | ||
405 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
406 | if (!res) { | ||
407 | dev_err(dev, "no memory specified\n"); | ||
408 | return -ENOENT; | ||
409 | } | ||
410 | |||
411 | host = sdhci_alloc_host(dev, sizeof(struct sdhci_s3c)); | 450 | host = sdhci_alloc_host(dev, sizeof(struct sdhci_s3c)); |
412 | if (IS_ERR(host)) { | 451 | if (IS_ERR(host)) { |
413 | dev_err(dev, "sdhci_alloc_host() failed\n"); | 452 | dev_err(dev, "sdhci_alloc_host() failed\n"); |
414 | return PTR_ERR(host); | 453 | return PTR_ERR(host); |
415 | } | 454 | } |
416 | 455 | ||
456 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
457 | if (!pdata) { | ||
458 | ret = -ENOMEM; | ||
459 | goto err_io_clk; | ||
460 | } | ||
461 | memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata)); | ||
462 | |||
463 | drv_data = sdhci_s3c_get_driver_data(pdev); | ||
417 | sc = sdhci_priv(host); | 464 | sc = sdhci_priv(host); |
418 | 465 | ||
419 | sc->host = host; | 466 | sc->host = host; |
@@ -464,15 +511,8 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) | |||
464 | goto err_no_busclks; | 511 | goto err_no_busclks; |
465 | } | 512 | } |
466 | 513 | ||
467 | sc->ioarea = request_mem_region(res->start, resource_size(res), | 514 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
468 | mmc_hostname(host->mmc)); | 515 | host->ioaddr = devm_request_and_ioremap(&pdev->dev, res); |
469 | if (!sc->ioarea) { | ||
470 | dev_err(dev, "failed to reserve register area\n"); | ||
471 | ret = -ENXIO; | ||
472 | goto err_req_regs; | ||
473 | } | ||
474 | |||
475 | host->ioaddr = ioremap_nocache(res->start, resource_size(res)); | ||
476 | if (!host->ioaddr) { | 516 | if (!host->ioaddr) { |
477 | dev_err(dev, "failed to map registers\n"); | 517 | dev_err(dev, "failed to map registers\n"); |
478 | ret = -ENXIO; | 518 | ret = -ENXIO; |
@@ -491,6 +531,8 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) | |||
491 | /* Setup quirks for the controller */ | 531 | /* Setup quirks for the controller */ |
492 | host->quirks |= SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC; | 532 | host->quirks |= SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC; |
493 | host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT; | 533 | host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT; |
534 | if (drv_data) | ||
535 | host->quirks |= drv_data->sdhci_quirks; | ||
494 | 536 | ||
495 | #ifndef CONFIG_MMC_SDHCI_S3C_DMA | 537 | #ifndef CONFIG_MMC_SDHCI_S3C_DMA |
496 | 538 | ||
@@ -518,6 +560,14 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) | |||
518 | if (pdata->cd_type == S3C_SDHCI_CD_PERMANENT) | 560 | if (pdata->cd_type == S3C_SDHCI_CD_PERMANENT) |
519 | host->mmc->caps = MMC_CAP_NONREMOVABLE; | 561 | host->mmc->caps = MMC_CAP_NONREMOVABLE; |
520 | 562 | ||
563 | switch (pdata->max_width) { | ||
564 | case 8: | ||
565 | host->mmc->caps |= MMC_CAP_8_BIT_DATA; | ||
566 | case 4: | ||
567 | host->mmc->caps |= MMC_CAP_4_BIT_DATA; | ||
568 | break; | ||
569 | } | ||
570 | |||
521 | if (pdata->pm_caps) | 571 | if (pdata->pm_caps) |
522 | host->mmc->pm_caps |= pdata->pm_caps; | 572 | host->mmc->pm_caps |= pdata->pm_caps; |
523 | 573 | ||
@@ -531,7 +581,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) | |||
531 | * If controller does not have internal clock divider, | 581 | * If controller does not have internal clock divider, |
532 | * we can use overriding functions instead of default. | 582 | * we can use overriding functions instead of default. |
533 | */ | 583 | */ |
534 | if (pdata->clk_type) { | 584 | if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) { |
535 | sdhci_s3c_ops.set_clock = sdhci_cmu_set_clock; | 585 | sdhci_s3c_ops.set_clock = sdhci_cmu_set_clock; |
536 | sdhci_s3c_ops.get_min_clock = sdhci_cmu_get_min_clock; | 586 | sdhci_s3c_ops.get_min_clock = sdhci_cmu_get_min_clock; |
537 | sdhci_s3c_ops.get_max_clock = sdhci_cmu_get_max_clock; | 587 | sdhci_s3c_ops.get_max_clock = sdhci_cmu_get_max_clock; |
@@ -544,10 +594,17 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) | |||
544 | if (pdata->host_caps2) | 594 | if (pdata->host_caps2) |
545 | host->mmc->caps2 |= pdata->host_caps2; | 595 | host->mmc->caps2 |= pdata->host_caps2; |
546 | 596 | ||
597 | pm_runtime_enable(&pdev->dev); | ||
598 | pm_runtime_set_autosuspend_delay(&pdev->dev, 50); | ||
599 | pm_runtime_use_autosuspend(&pdev->dev); | ||
600 | pm_suspend_ignore_children(&pdev->dev, 1); | ||
601 | |||
547 | ret = sdhci_add_host(host); | 602 | ret = sdhci_add_host(host); |
548 | if (ret) { | 603 | if (ret) { |
549 | dev_err(dev, "sdhci_add_host() failed\n"); | 604 | dev_err(dev, "sdhci_add_host() failed\n"); |
550 | goto err_add_host; | 605 | pm_runtime_forbid(&pdev->dev); |
606 | pm_runtime_get_noresume(&pdev->dev); | ||
607 | goto err_req_regs; | ||
551 | } | 608 | } |
552 | 609 | ||
553 | /* The following two methods of card detection might call | 610 | /* The following two methods of card detection might call |
@@ -561,10 +618,6 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) | |||
561 | 618 | ||
562 | return 0; | 619 | return 0; |
563 | 620 | ||
564 | err_add_host: | ||
565 | release_resource(sc->ioarea); | ||
566 | kfree(sc->ioarea); | ||
567 | |||
568 | err_req_regs: | 621 | err_req_regs: |
569 | for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { | 622 | for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { |
570 | if (sc->clk_bus[ptr]) { | 623 | if (sc->clk_bus[ptr]) { |
@@ -601,6 +654,8 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) | |||
601 | 654 | ||
602 | sdhci_remove_host(host, 1); | 655 | sdhci_remove_host(host, 1); |
603 | 656 | ||
657 | pm_runtime_disable(&pdev->dev); | ||
658 | |||
604 | for (ptr = 0; ptr < 3; ptr++) { | 659 | for (ptr = 0; ptr < 3; ptr++) { |
605 | if (sc->clk_bus[ptr]) { | 660 | if (sc->clk_bus[ptr]) { |
606 | clk_disable(sc->clk_bus[ptr]); | 661 | clk_disable(sc->clk_bus[ptr]); |
@@ -610,18 +665,13 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) | |||
610 | clk_disable(sc->clk_io); | 665 | clk_disable(sc->clk_io); |
611 | clk_put(sc->clk_io); | 666 | clk_put(sc->clk_io); |
612 | 667 | ||
613 | iounmap(host->ioaddr); | ||
614 | release_resource(sc->ioarea); | ||
615 | kfree(sc->ioarea); | ||
616 | |||
617 | sdhci_free_host(host); | 668 | sdhci_free_host(host); |
618 | platform_set_drvdata(pdev, NULL); | 669 | platform_set_drvdata(pdev, NULL); |
619 | 670 | ||
620 | return 0; | 671 | return 0; |
621 | } | 672 | } |
622 | 673 | ||
623 | #ifdef CONFIG_PM | 674 | #ifdef CONFIG_PM_SLEEP |
624 | |||
625 | static int sdhci_s3c_suspend(struct device *dev) | 675 | static int sdhci_s3c_suspend(struct device *dev) |
626 | { | 676 | { |
627 | struct sdhci_host *host = dev_get_drvdata(dev); | 677 | struct sdhci_host *host = dev_get_drvdata(dev); |
@@ -635,10 +685,29 @@ static int sdhci_s3c_resume(struct device *dev) | |||
635 | 685 | ||
636 | return sdhci_resume_host(host); | 686 | return sdhci_resume_host(host); |
637 | } | 687 | } |
688 | #endif | ||
689 | |||
690 | #ifdef CONFIG_PM_RUNTIME | ||
691 | static int sdhci_s3c_runtime_suspend(struct device *dev) | ||
692 | { | ||
693 | struct sdhci_host *host = dev_get_drvdata(dev); | ||
694 | |||
695 | return sdhci_runtime_suspend_host(host); | ||
696 | } | ||
638 | 697 | ||
698 | static int sdhci_s3c_runtime_resume(struct device *dev) | ||
699 | { | ||
700 | struct sdhci_host *host = dev_get_drvdata(dev); | ||
701 | |||
702 | return sdhci_runtime_resume_host(host); | ||
703 | } | ||
704 | #endif | ||
705 | |||
706 | #ifdef CONFIG_PM | ||
639 | static const struct dev_pm_ops sdhci_s3c_pmops = { | 707 | static const struct dev_pm_ops sdhci_s3c_pmops = { |
640 | .suspend = sdhci_s3c_suspend, | 708 | SET_SYSTEM_SLEEP_PM_OPS(sdhci_s3c_suspend, sdhci_s3c_resume) |
641 | .resume = sdhci_s3c_resume, | 709 | SET_RUNTIME_PM_OPS(sdhci_s3c_runtime_suspend, sdhci_s3c_runtime_resume, |
710 | NULL) | ||
642 | }; | 711 | }; |
643 | 712 | ||
644 | #define SDHCI_S3C_PMOPS (&sdhci_s3c_pmops) | 713 | #define SDHCI_S3C_PMOPS (&sdhci_s3c_pmops) |
@@ -647,9 +716,31 @@ static const struct dev_pm_ops sdhci_s3c_pmops = { | |||
647 | #define SDHCI_S3C_PMOPS NULL | 716 | #define SDHCI_S3C_PMOPS NULL |
648 | #endif | 717 | #endif |
649 | 718 | ||
719 | #if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS4212) | ||
720 | static struct sdhci_s3c_drv_data exynos4_sdhci_drv_data = { | ||
721 | .sdhci_quirks = SDHCI_QUIRK_NONSTANDARD_CLOCK, | ||
722 | }; | ||
723 | #define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)&exynos4_sdhci_drv_data) | ||
724 | #else | ||
725 | #define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)NULL) | ||
726 | #endif | ||
727 | |||
728 | static struct platform_device_id sdhci_s3c_driver_ids[] = { | ||
729 | { | ||
730 | .name = "s3c-sdhci", | ||
731 | .driver_data = (kernel_ulong_t)NULL, | ||
732 | }, { | ||
733 | .name = "exynos4-sdhci", | ||
734 | .driver_data = EXYNOS4_SDHCI_DRV_DATA, | ||
735 | }, | ||
736 | { } | ||
737 | }; | ||
738 | MODULE_DEVICE_TABLE(platform, sdhci_s3c_driver_ids); | ||
739 | |||
650 | static struct platform_driver sdhci_s3c_driver = { | 740 | static struct platform_driver sdhci_s3c_driver = { |
651 | .probe = sdhci_s3c_probe, | 741 | .probe = sdhci_s3c_probe, |
652 | .remove = __devexit_p(sdhci_s3c_remove), | 742 | .remove = __devexit_p(sdhci_s3c_remove), |
743 | .id_table = sdhci_s3c_driver_ids, | ||
653 | .driver = { | 744 | .driver = { |
654 | .owner = THIS_MODULE, | 745 | .owner = THIS_MODULE, |
655 | .name = "s3c-sdhci", | 746 | .name = "s3c-sdhci", |
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 53b26502f6e2..ff5a16991939 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c | |||
@@ -269,7 +269,6 @@ static int __devinit sdhci_tegra_probe(struct platform_device *pdev) | |||
269 | "failed to allocate power gpio\n"); | 269 | "failed to allocate power gpio\n"); |
270 | goto err_power_req; | 270 | goto err_power_req; |
271 | } | 271 | } |
272 | tegra_gpio_enable(plat->power_gpio); | ||
273 | gpio_direction_output(plat->power_gpio, 1); | 272 | gpio_direction_output(plat->power_gpio, 1); |
274 | } | 273 | } |
275 | 274 | ||
@@ -280,7 +279,6 @@ static int __devinit sdhci_tegra_probe(struct platform_device *pdev) | |||
280 | "failed to allocate cd gpio\n"); | 279 | "failed to allocate cd gpio\n"); |
281 | goto err_cd_req; | 280 | goto err_cd_req; |
282 | } | 281 | } |
283 | tegra_gpio_enable(plat->cd_gpio); | ||
284 | gpio_direction_input(plat->cd_gpio); | 282 | gpio_direction_input(plat->cd_gpio); |
285 | 283 | ||
286 | rc = request_irq(gpio_to_irq(plat->cd_gpio), carddetect_irq, | 284 | rc = request_irq(gpio_to_irq(plat->cd_gpio), carddetect_irq, |
@@ -301,7 +299,6 @@ static int __devinit sdhci_tegra_probe(struct platform_device *pdev) | |||
301 | "failed to allocate wp gpio\n"); | 299 | "failed to allocate wp gpio\n"); |
302 | goto err_wp_req; | 300 | goto err_wp_req; |
303 | } | 301 | } |
304 | tegra_gpio_enable(plat->wp_gpio); | ||
305 | gpio_direction_input(plat->wp_gpio); | 302 | gpio_direction_input(plat->wp_gpio); |
306 | } | 303 | } |
307 | 304 | ||
@@ -329,23 +326,17 @@ err_add_host: | |||
329 | clk_disable(pltfm_host->clk); | 326 | clk_disable(pltfm_host->clk); |
330 | clk_put(pltfm_host->clk); | 327 | clk_put(pltfm_host->clk); |
331 | err_clk_get: | 328 | err_clk_get: |
332 | if (gpio_is_valid(plat->wp_gpio)) { | 329 | if (gpio_is_valid(plat->wp_gpio)) |
333 | tegra_gpio_disable(plat->wp_gpio); | ||
334 | gpio_free(plat->wp_gpio); | 330 | gpio_free(plat->wp_gpio); |
335 | } | ||
336 | err_wp_req: | 331 | err_wp_req: |
337 | if (gpio_is_valid(plat->cd_gpio)) | 332 | if (gpio_is_valid(plat->cd_gpio)) |
338 | free_irq(gpio_to_irq(plat->cd_gpio), host); | 333 | free_irq(gpio_to_irq(plat->cd_gpio), host); |
339 | err_cd_irq_req: | 334 | err_cd_irq_req: |
340 | if (gpio_is_valid(plat->cd_gpio)) { | 335 | if (gpio_is_valid(plat->cd_gpio)) |
341 | tegra_gpio_disable(plat->cd_gpio); | ||
342 | gpio_free(plat->cd_gpio); | 336 | gpio_free(plat->cd_gpio); |
343 | } | ||
344 | err_cd_req: | 337 | err_cd_req: |
345 | if (gpio_is_valid(plat->power_gpio)) { | 338 | if (gpio_is_valid(plat->power_gpio)) |
346 | tegra_gpio_disable(plat->power_gpio); | ||
347 | gpio_free(plat->power_gpio); | 339 | gpio_free(plat->power_gpio); |
348 | } | ||
349 | err_power_req: | 340 | err_power_req: |
350 | err_no_plat: | 341 | err_no_plat: |
351 | sdhci_pltfm_free(pdev); | 342 | sdhci_pltfm_free(pdev); |
@@ -362,21 +353,16 @@ static int __devexit sdhci_tegra_remove(struct platform_device *pdev) | |||
362 | 353 | ||
363 | sdhci_remove_host(host, dead); | 354 | sdhci_remove_host(host, dead); |
364 | 355 | ||
365 | if (gpio_is_valid(plat->wp_gpio)) { | 356 | if (gpio_is_valid(plat->wp_gpio)) |
366 | tegra_gpio_disable(plat->wp_gpio); | ||
367 | gpio_free(plat->wp_gpio); | 357 | gpio_free(plat->wp_gpio); |
368 | } | ||
369 | 358 | ||
370 | if (gpio_is_valid(plat->cd_gpio)) { | 359 | if (gpio_is_valid(plat->cd_gpio)) { |
371 | free_irq(gpio_to_irq(plat->cd_gpio), host); | 360 | free_irq(gpio_to_irq(plat->cd_gpio), host); |
372 | tegra_gpio_disable(plat->cd_gpio); | ||
373 | gpio_free(plat->cd_gpio); | 361 | gpio_free(plat->cd_gpio); |
374 | } | 362 | } |
375 | 363 | ||
376 | if (gpio_is_valid(plat->power_gpio)) { | 364 | if (gpio_is_valid(plat->power_gpio)) |
377 | tegra_gpio_disable(plat->power_gpio); | ||
378 | gpio_free(plat->power_gpio); | 365 | gpio_free(plat->power_gpio); |
379 | } | ||
380 | 366 | ||
381 | clk_disable(pltfm_host->clk); | 367 | clk_disable(pltfm_host->clk); |
382 | clk_put(pltfm_host->clk); | 368 | clk_put(pltfm_host->clk); |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 8262cadfdab7..ccefdebeff14 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -147,7 +147,7 @@ static void sdhci_set_card_detection(struct sdhci_host *host, bool enable) | |||
147 | u32 present, irqs; | 147 | u32 present, irqs; |
148 | 148 | ||
149 | if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) || | 149 | if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) || |
150 | !mmc_card_is_removable(host->mmc)) | 150 | (host->mmc->caps & MMC_CAP_NONREMOVABLE)) |
151 | return; | 151 | return; |
152 | 152 | ||
153 | present = sdhci_readl(host, SDHCI_PRESENT_STATE) & | 153 | present = sdhci_readl(host, SDHCI_PRESENT_STATE) & |
@@ -2782,8 +2782,9 @@ int sdhci_add_host(struct sdhci_host *host) | |||
2782 | mmc_card_is_removable(mmc)) | 2782 | mmc_card_is_removable(mmc)) |
2783 | mmc->caps |= MMC_CAP_NEEDS_POLL; | 2783 | mmc->caps |= MMC_CAP_NEEDS_POLL; |
2784 | 2784 | ||
2785 | /* UHS-I mode(s) supported by the host controller. */ | 2785 | /* Any UHS-I mode in caps implies SDR12 and SDR25 support. */ |
2786 | if (host->version >= SDHCI_SPEC_300) | 2786 | if (caps[1] & (SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 | |
2787 | SDHCI_SUPPORT_DDR50)) | ||
2787 | mmc->caps |= MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25; | 2788 | mmc->caps |= MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25; |
2788 | 2789 | ||
2789 | /* SDR104 supports also implies SDR50 support */ | 2790 | /* SDR104 supports also implies SDR50 support */ |
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c index aafaf0b6eb1c..724b35e85a26 100644 --- a/drivers/mmc/host/sh_mmcif.c +++ b/drivers/mmc/host/sh_mmcif.c | |||
@@ -454,7 +454,8 @@ static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk) | |||
454 | sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_SUP_PCLK); | 454 | sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_SUP_PCLK); |
455 | else | 455 | else |
456 | sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR & | 456 | sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR & |
457 | ((fls(host->clk / clk) - 1) << 16)); | 457 | ((fls(DIV_ROUND_UP(host->clk, |
458 | clk) - 1) - 1) << 16)); | ||
458 | 459 | ||
459 | sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_ENABLE); | 460 | sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_ENABLE); |
460 | } | 461 | } |
@@ -1297,14 +1298,8 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev) | |||
1297 | spin_lock_init(&host->lock); | 1298 | spin_lock_init(&host->lock); |
1298 | 1299 | ||
1299 | mmc->ops = &sh_mmcif_ops; | 1300 | mmc->ops = &sh_mmcif_ops; |
1300 | mmc->f_max = host->clk; | 1301 | mmc->f_max = host->clk / 2; |
1301 | /* close to 400KHz */ | 1302 | mmc->f_min = host->clk / 512; |
1302 | if (mmc->f_max < 51200000) | ||
1303 | mmc->f_min = mmc->f_max / 128; | ||
1304 | else if (mmc->f_max < 102400000) | ||
1305 | mmc->f_min = mmc->f_max / 256; | ||
1306 | else | ||
1307 | mmc->f_min = mmc->f_max / 512; | ||
1308 | if (pd->ocr) | 1303 | if (pd->ocr) |
1309 | mmc->ocr_avail = pd->ocr; | 1304 | mmc->ocr_avail = pd->ocr; |
1310 | mmc->caps = MMC_CAP_MMC_HIGHSPEED; | 1305 | mmc->caps = MMC_CAP_MMC_HIGHSPEED; |