diff options
author | Paul Mundt <lethal@linux-sh.org> | 2010-12-20 10:40:51 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-12-20 10:40:51 -0500 |
commit | 8bcee1832d23869c2cdb6886ae5210b0143256f0 (patch) | |
tree | 9fac190248ed9ed10fe4e6f7b1b4cda8eaef7ddd /drivers/mmc | |
parent | 5ce2a2ddb5d75d5e2371e58011fc21351bf278cb (diff) | |
parent | 1cf215a5b43950d1a304373037828158057ff9fc (diff) |
Merge branch 'rmobile/urgent' into rmobile-latest
Conflicts:
arch/arm/mach-shmobile/include/mach/entry-macro.S
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/core/core.c | 2 | ||||
-rw-r--r-- | drivers/mmc/core/mmc.c | 8 | ||||
-rw-r--r-- | drivers/mmc/core/sdio.c | 51 | ||||
-rw-r--r-- | drivers/mmc/core/sdio_bus.c | 33 | ||||
-rw-r--r-- | drivers/mmc/host/omap_hsmmc.c | 2 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-esdhc-imx.c | 12 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-pci.c | 31 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-pxa.c | 4 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.c | 54 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.h | 9 | ||||
-rw-r--r-- | drivers/mmc/host/ushc.c | 30 |
11 files changed, 174 insertions, 62 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 8f86d702e46e..31ae07a36576 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -1559,7 +1559,7 @@ void mmc_stop_host(struct mmc_host *host) | |||
1559 | 1559 | ||
1560 | if (host->caps & MMC_CAP_DISABLE) | 1560 | if (host->caps & MMC_CAP_DISABLE) |
1561 | cancel_delayed_work(&host->disable); | 1561 | cancel_delayed_work(&host->disable); |
1562 | cancel_delayed_work(&host->detect); | 1562 | cancel_delayed_work_sync(&host->detect); |
1563 | mmc_flush_scheduled_work(); | 1563 | mmc_flush_scheduled_work(); |
1564 | 1564 | ||
1565 | /* clear pm flags now and let card drivers set them as needed */ | 1565 | /* clear pm flags now and let card drivers set them as needed */ |
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 995261f7fd70..77f93c3b8808 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -375,7 +375,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
375 | struct mmc_card *oldcard) | 375 | struct mmc_card *oldcard) |
376 | { | 376 | { |
377 | struct mmc_card *card; | 377 | struct mmc_card *card; |
378 | int err, ddr = MMC_SDR_MODE; | 378 | int err, ddr = 0; |
379 | u32 cid[4]; | 379 | u32 cid[4]; |
380 | unsigned int max_dtr; | 380 | unsigned int max_dtr; |
381 | 381 | ||
@@ -562,7 +562,11 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
562 | 1 << bus_width, ddr); | 562 | 1 << bus_width, ddr); |
563 | err = 0; | 563 | err = 0; |
564 | } else { | 564 | } else { |
565 | mmc_card_set_ddr_mode(card); | 565 | if (ddr) |
566 | mmc_card_set_ddr_mode(card); | ||
567 | else | ||
568 | ddr = MMC_SDR_MODE; | ||
569 | |||
566 | mmc_set_bus_width_ddr(card->host, bus_width, ddr); | 570 | mmc_set_bus_width_ddr(card->host, bus_width, ddr); |
567 | } | 571 | } |
568 | } | 572 | } |
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index c3ad1058cd31..efef5f94ac42 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c | |||
@@ -547,9 +547,11 @@ static void mmc_sdio_detect(struct mmc_host *host) | |||
547 | BUG_ON(!host->card); | 547 | BUG_ON(!host->card); |
548 | 548 | ||
549 | /* Make sure card is powered before detecting it */ | 549 | /* Make sure card is powered before detecting it */ |
550 | err = pm_runtime_get_sync(&host->card->dev); | 550 | if (host->caps & MMC_CAP_POWER_OFF_CARD) { |
551 | if (err < 0) | 551 | err = pm_runtime_get_sync(&host->card->dev); |
552 | goto out; | 552 | if (err < 0) |
553 | goto out; | ||
554 | } | ||
553 | 555 | ||
554 | mmc_claim_host(host); | 556 | mmc_claim_host(host); |
555 | 557 | ||
@@ -560,6 +562,20 @@ static void mmc_sdio_detect(struct mmc_host *host) | |||
560 | 562 | ||
561 | mmc_release_host(host); | 563 | mmc_release_host(host); |
562 | 564 | ||
565 | /* | ||
566 | * Tell PM core it's OK to power off the card now. | ||
567 | * | ||
568 | * The _sync variant is used in order to ensure that the card | ||
569 | * is left powered off in case an error occurred, and the card | ||
570 | * is going to be removed. | ||
571 | * | ||
572 | * Since there is no specific reason to believe a new user | ||
573 | * is about to show up at this point, the _sync variant is | ||
574 | * desirable anyway. | ||
575 | */ | ||
576 | if (host->caps & MMC_CAP_POWER_OFF_CARD) | ||
577 | pm_runtime_put_sync(&host->card->dev); | ||
578 | |||
563 | out: | 579 | out: |
564 | if (err) { | 580 | if (err) { |
565 | mmc_sdio_remove(host); | 581 | mmc_sdio_remove(host); |
@@ -568,9 +584,6 @@ out: | |||
568 | mmc_detach_bus(host); | 584 | mmc_detach_bus(host); |
569 | mmc_release_host(host); | 585 | mmc_release_host(host); |
570 | } | 586 | } |
571 | |||
572 | /* Tell PM core that we're done */ | ||
573 | pm_runtime_put(&host->card->dev); | ||
574 | } | 587 | } |
575 | 588 | ||
576 | /* | 589 | /* |
@@ -718,16 +731,21 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) | |||
718 | card = host->card; | 731 | card = host->card; |
719 | 732 | ||
720 | /* | 733 | /* |
721 | * Let runtime PM core know our card is active | 734 | * Enable runtime PM only if supported by host+card+board |
722 | */ | 735 | */ |
723 | err = pm_runtime_set_active(&card->dev); | 736 | if (host->caps & MMC_CAP_POWER_OFF_CARD) { |
724 | if (err) | 737 | /* |
725 | goto remove; | 738 | * Let runtime PM core know our card is active |
739 | */ | ||
740 | err = pm_runtime_set_active(&card->dev); | ||
741 | if (err) | ||
742 | goto remove; | ||
726 | 743 | ||
727 | /* | 744 | /* |
728 | * Enable runtime PM for this card | 745 | * Enable runtime PM for this card |
729 | */ | 746 | */ |
730 | pm_runtime_enable(&card->dev); | 747 | pm_runtime_enable(&card->dev); |
748 | } | ||
731 | 749 | ||
732 | /* | 750 | /* |
733 | * The number of functions on the card is encoded inside | 751 | * The number of functions on the card is encoded inside |
@@ -745,9 +763,10 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) | |||
745 | goto remove; | 763 | goto remove; |
746 | 764 | ||
747 | /* | 765 | /* |
748 | * Enable Runtime PM for this func | 766 | * Enable Runtime PM for this func (if supported) |
749 | */ | 767 | */ |
750 | pm_runtime_enable(&card->sdio_func[i]->dev); | 768 | if (host->caps & MMC_CAP_POWER_OFF_CARD) |
769 | pm_runtime_enable(&card->sdio_func[i]->dev); | ||
751 | } | 770 | } |
752 | 771 | ||
753 | mmc_release_host(host); | 772 | mmc_release_host(host); |
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 2716c7ab6bbf..203da443e339 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/pm_runtime.h> | 17 | #include <linux/pm_runtime.h> |
18 | 18 | ||
19 | #include <linux/mmc/card.h> | 19 | #include <linux/mmc/card.h> |
20 | #include <linux/mmc/host.h> | ||
20 | #include <linux/mmc/sdio_func.h> | 21 | #include <linux/mmc/sdio_func.h> |
21 | 22 | ||
22 | #include "sdio_cis.h" | 23 | #include "sdio_cis.h" |
@@ -132,9 +133,11 @@ static int sdio_bus_probe(struct device *dev) | |||
132 | * it should call pm_runtime_put_noidle() in its probe routine and | 133 | * it should call pm_runtime_put_noidle() in its probe routine and |
133 | * pm_runtime_get_noresume() in its remove routine. | 134 | * pm_runtime_get_noresume() in its remove routine. |
134 | */ | 135 | */ |
135 | ret = pm_runtime_get_sync(dev); | 136 | if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) { |
136 | if (ret < 0) | 137 | ret = pm_runtime_get_sync(dev); |
137 | goto out; | 138 | if (ret < 0) |
139 | goto out; | ||
140 | } | ||
138 | 141 | ||
139 | /* Set the default block size so the driver is sure it's something | 142 | /* Set the default block size so the driver is sure it's something |
140 | * sensible. */ | 143 | * sensible. */ |
@@ -151,7 +154,8 @@ static int sdio_bus_probe(struct device *dev) | |||
151 | return 0; | 154 | return 0; |
152 | 155 | ||
153 | disable_runtimepm: | 156 | disable_runtimepm: |
154 | pm_runtime_put_noidle(dev); | 157 | if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) |
158 | pm_runtime_put_noidle(dev); | ||
155 | out: | 159 | out: |
156 | return ret; | 160 | return ret; |
157 | } | 161 | } |
@@ -160,12 +164,14 @@ static int sdio_bus_remove(struct device *dev) | |||
160 | { | 164 | { |
161 | struct sdio_driver *drv = to_sdio_driver(dev->driver); | 165 | struct sdio_driver *drv = to_sdio_driver(dev->driver); |
162 | struct sdio_func *func = dev_to_sdio_func(dev); | 166 | struct sdio_func *func = dev_to_sdio_func(dev); |
163 | int ret; | 167 | int ret = 0; |
164 | 168 | ||
165 | /* Make sure card is powered before invoking ->remove() */ | 169 | /* Make sure card is powered before invoking ->remove() */ |
166 | ret = pm_runtime_get_sync(dev); | 170 | if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) { |
167 | if (ret < 0) | 171 | ret = pm_runtime_get_sync(dev); |
168 | goto out; | 172 | if (ret < 0) |
173 | goto out; | ||
174 | } | ||
169 | 175 | ||
170 | drv->remove(func); | 176 | drv->remove(func); |
171 | 177 | ||
@@ -178,10 +184,12 @@ static int sdio_bus_remove(struct device *dev) | |||
178 | } | 184 | } |
179 | 185 | ||
180 | /* First, undo the increment made directly above */ | 186 | /* First, undo the increment made directly above */ |
181 | pm_runtime_put_noidle(dev); | 187 | if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) |
188 | pm_runtime_put_noidle(dev); | ||
182 | 189 | ||
183 | /* Then undo the runtime PM settings in sdio_bus_probe() */ | 190 | /* Then undo the runtime PM settings in sdio_bus_probe() */ |
184 | pm_runtime_put_noidle(dev); | 191 | if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) |
192 | pm_runtime_put_noidle(dev); | ||
185 | 193 | ||
186 | out: | 194 | out: |
187 | return ret; | 195 | return ret; |
@@ -191,6 +199,8 @@ out: | |||
191 | 199 | ||
192 | static int sdio_bus_pm_prepare(struct device *dev) | 200 | static int sdio_bus_pm_prepare(struct device *dev) |
193 | { | 201 | { |
202 | struct sdio_func *func = dev_to_sdio_func(dev); | ||
203 | |||
194 | /* | 204 | /* |
195 | * Resume an SDIO device which was suspended at run time at this | 205 | * Resume an SDIO device which was suspended at run time at this |
196 | * point, in order to allow standard SDIO suspend/resume paths | 206 | * point, in order to allow standard SDIO suspend/resume paths |
@@ -212,7 +222,8 @@ static int sdio_bus_pm_prepare(struct device *dev) | |||
212 | * since there is little point in failing system suspend if a | 222 | * since there is little point in failing system suspend if a |
213 | * device can't be resumed. | 223 | * device can't be resumed. |
214 | */ | 224 | */ |
215 | pm_runtime_resume(dev); | 225 | if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) |
226 | pm_runtime_resume(dev); | ||
216 | 227 | ||
217 | return 0; | 228 | return 0; |
218 | } | 229 | } |
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 82a1079bbdc7..5d46021cbb57 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
@@ -1002,7 +1002,7 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host, | |||
1002 | * Monitor a 0->1 transition first | 1002 | * Monitor a 0->1 transition first |
1003 | */ | 1003 | */ |
1004 | if (mmc_slot(host).features & HSMMC_HAS_UPDATED_RESET) { | 1004 | if (mmc_slot(host).features & HSMMC_HAS_UPDATED_RESET) { |
1005 | while ((!(OMAP_HSMMC_READ(host, SYSCTL) & bit)) | 1005 | while ((!(OMAP_HSMMC_READ(host->base, SYSCTL) & bit)) |
1006 | && (i++ < limit)) | 1006 | && (i++ < limit)) |
1007 | cpu_relax(); | 1007 | cpu_relax(); |
1008 | } | 1008 | } |
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 2e9cca19c90b..9b82910b9dbb 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
18 | #include <linux/mmc/host.h> | 18 | #include <linux/mmc/host.h> |
19 | #include <linux/mmc/sdhci-pltfm.h> | 19 | #include <linux/mmc/sdhci-pltfm.h> |
20 | #include <mach/hardware.h> | ||
20 | #include "sdhci.h" | 21 | #include "sdhci.h" |
21 | #include "sdhci-pltfm.h" | 22 | #include "sdhci-pltfm.h" |
22 | #include "sdhci-esdhc.h" | 23 | #include "sdhci-esdhc.h" |
@@ -112,6 +113,13 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd | |||
112 | clk_enable(clk); | 113 | clk_enable(clk); |
113 | pltfm_host->clk = clk; | 114 | pltfm_host->clk = clk; |
114 | 115 | ||
116 | if (cpu_is_mx35() || cpu_is_mx51()) | ||
117 | host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; | ||
118 | |||
119 | /* Fix errata ENGcm07207 which is present on i.MX25 and i.MX35 */ | ||
120 | if (cpu_is_mx25() || cpu_is_mx35()) | ||
121 | host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK; | ||
122 | |||
115 | return 0; | 123 | return 0; |
116 | } | 124 | } |
117 | 125 | ||
@@ -133,10 +141,8 @@ static struct sdhci_ops sdhci_esdhc_ops = { | |||
133 | }; | 141 | }; |
134 | 142 | ||
135 | struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = { | 143 | struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = { |
136 | .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_NO_MULTIBLOCK | 144 | .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_ADMA, |
137 | | SDHCI_QUIRK_BROKEN_ADMA, | ||
138 | /* ADMA has issues. Might be fixable */ | 145 | /* ADMA has issues. Might be fixable */ |
139 | /* NO_MULTIBLOCK might be MX35 only (Errata: ENGcm07207) */ | ||
140 | .ops = &sdhci_esdhc_ops, | 146 | .ops = &sdhci_esdhc_ops, |
141 | .init = esdhc_pltfm_init, | 147 | .init = esdhc_pltfm_init, |
142 | .exit = esdhc_pltfm_exit, | 148 | .exit = esdhc_pltfm_exit, |
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 55746bac2f44..3d9c2460d437 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
@@ -149,11 +149,11 @@ static const struct sdhci_pci_fixes sdhci_cafe = { | |||
149 | * ADMA operation is disabled for Moorestown platform due to | 149 | * ADMA operation is disabled for Moorestown platform due to |
150 | * hardware bugs. | 150 | * hardware bugs. |
151 | */ | 151 | */ |
152 | static int mrst_hc1_probe(struct sdhci_pci_chip *chip) | 152 | static int mrst_hc_probe(struct sdhci_pci_chip *chip) |
153 | { | 153 | { |
154 | /* | 154 | /* |
155 | * slots number is fixed here for MRST as SDIO3 is never used and has | 155 | * slots number is fixed here for MRST as SDIO3/5 are never used and |
156 | * hardware bugs. | 156 | * have hardware bugs. |
157 | */ | 157 | */ |
158 | chip->num_slots = 1; | 158 | chip->num_slots = 1; |
159 | return 0; | 159 | return 0; |
@@ -163,9 +163,9 @@ static const struct sdhci_pci_fixes sdhci_intel_mrst_hc0 = { | |||
163 | .quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT, | 163 | .quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT, |
164 | }; | 164 | }; |
165 | 165 | ||
166 | static const struct sdhci_pci_fixes sdhci_intel_mrst_hc1 = { | 166 | static const struct sdhci_pci_fixes sdhci_intel_mrst_hc1_hc2 = { |
167 | .quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT, | 167 | .quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT, |
168 | .probe = mrst_hc1_probe, | 168 | .probe = mrst_hc_probe, |
169 | }; | 169 | }; |
170 | 170 | ||
171 | static const struct sdhci_pci_fixes sdhci_intel_mfd_sd = { | 171 | static const struct sdhci_pci_fixes sdhci_intel_mfd_sd = { |
@@ -538,7 +538,15 @@ static const struct pci_device_id pci_ids[] __devinitdata = { | |||
538 | .device = PCI_DEVICE_ID_INTEL_MRST_SD1, | 538 | .device = PCI_DEVICE_ID_INTEL_MRST_SD1, |
539 | .subvendor = PCI_ANY_ID, | 539 | .subvendor = PCI_ANY_ID, |
540 | .subdevice = PCI_ANY_ID, | 540 | .subdevice = PCI_ANY_ID, |
541 | .driver_data = (kernel_ulong_t)&sdhci_intel_mrst_hc1, | 541 | .driver_data = (kernel_ulong_t)&sdhci_intel_mrst_hc1_hc2, |
542 | }, | ||
543 | |||
544 | { | ||
545 | .vendor = PCI_VENDOR_ID_INTEL, | ||
546 | .device = PCI_DEVICE_ID_INTEL_MRST_SD2, | ||
547 | .subvendor = PCI_ANY_ID, | ||
548 | .subdevice = PCI_ANY_ID, | ||
549 | .driver_data = (kernel_ulong_t)&sdhci_intel_mrst_hc1_hc2, | ||
542 | }, | 550 | }, |
543 | 551 | ||
544 | { | 552 | { |
@@ -637,6 +645,7 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) | |||
637 | { | 645 | { |
638 | struct sdhci_pci_chip *chip; | 646 | struct sdhci_pci_chip *chip; |
639 | struct sdhci_pci_slot *slot; | 647 | struct sdhci_pci_slot *slot; |
648 | mmc_pm_flag_t slot_pm_flags; | ||
640 | mmc_pm_flag_t pm_flags = 0; | 649 | mmc_pm_flag_t pm_flags = 0; |
641 | int i, ret; | 650 | int i, ret; |
642 | 651 | ||
@@ -657,7 +666,11 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) | |||
657 | return ret; | 666 | return ret; |
658 | } | 667 | } |
659 | 668 | ||
660 | pm_flags |= slot->host->mmc->pm_flags; | 669 | slot_pm_flags = slot->host->mmc->pm_flags; |
670 | if (slot_pm_flags & MMC_PM_WAKE_SDIO_IRQ) | ||
671 | sdhci_enable_irq_wakeups(slot->host); | ||
672 | |||
673 | pm_flags |= slot_pm_flags; | ||
661 | } | 674 | } |
662 | 675 | ||
663 | if (chip->fixes && chip->fixes->suspend) { | 676 | if (chip->fixes && chip->fixes->suspend) { |
@@ -671,8 +684,10 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) | |||
671 | 684 | ||
672 | pci_save_state(pdev); | 685 | pci_save_state(pdev); |
673 | if (pm_flags & MMC_PM_KEEP_POWER) { | 686 | if (pm_flags & MMC_PM_KEEP_POWER) { |
674 | if (pm_flags & MMC_PM_WAKE_SDIO_IRQ) | 687 | if (pm_flags & MMC_PM_WAKE_SDIO_IRQ) { |
688 | pci_pme_active(pdev, true); | ||
675 | pci_enable_wake(pdev, PCI_D3hot, 1); | 689 | pci_enable_wake(pdev, PCI_D3hot, 1); |
690 | } | ||
676 | pci_set_power_state(pdev, PCI_D3hot); | 691 | pci_set_power_state(pdev, PCI_D3hot); |
677 | } else { | 692 | } else { |
678 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); | 693 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); |
diff --git a/drivers/mmc/host/sdhci-pxa.c b/drivers/mmc/host/sdhci-pxa.c index fc406ac5d193..5a61208cbc66 100644 --- a/drivers/mmc/host/sdhci-pxa.c +++ b/drivers/mmc/host/sdhci-pxa.c | |||
@@ -141,6 +141,10 @@ static int __devinit sdhci_pxa_probe(struct platform_device *pdev) | |||
141 | if (pdata->quirks) | 141 | if (pdata->quirks) |
142 | host->quirks |= pdata->quirks; | 142 | host->quirks |= pdata->quirks; |
143 | 143 | ||
144 | /* If slot design supports 8 bit data, indicate this to MMC. */ | ||
145 | if (pdata->flags & PXA_FLAG_SD_8_BIT_CAPABLE_SLOT) | ||
146 | host->mmc->caps |= MMC_CAP_8_BIT_DATA; | ||
147 | |||
144 | ret = sdhci_add_host(host); | 148 | ret = sdhci_add_host(host); |
145 | if (ret) { | 149 | if (ret) { |
146 | dev_err(&pdev->dev, "failed to add host\n"); | 150 | dev_err(&pdev->dev, "failed to add host\n"); |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 782c0ee3c925..a25db426c910 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -1185,17 +1185,31 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1185 | if (host->ops->platform_send_init_74_clocks) | 1185 | if (host->ops->platform_send_init_74_clocks) |
1186 | host->ops->platform_send_init_74_clocks(host, ios->power_mode); | 1186 | host->ops->platform_send_init_74_clocks(host, ios->power_mode); |
1187 | 1187 | ||
1188 | ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); | 1188 | /* |
1189 | 1189 | * If your platform has 8-bit width support but is not a v3 controller, | |
1190 | if (ios->bus_width == MMC_BUS_WIDTH_8) | 1190 | * or if it requires special setup code, you should implement that in |
1191 | ctrl |= SDHCI_CTRL_8BITBUS; | 1191 | * platform_8bit_width(). |
1192 | else | 1192 | */ |
1193 | ctrl &= ~SDHCI_CTRL_8BITBUS; | 1193 | if (host->ops->platform_8bit_width) |
1194 | host->ops->platform_8bit_width(host, ios->bus_width); | ||
1195 | else { | ||
1196 | ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); | ||
1197 | if (ios->bus_width == MMC_BUS_WIDTH_8) { | ||
1198 | ctrl &= ~SDHCI_CTRL_4BITBUS; | ||
1199 | if (host->version >= SDHCI_SPEC_300) | ||
1200 | ctrl |= SDHCI_CTRL_8BITBUS; | ||
1201 | } else { | ||
1202 | if (host->version >= SDHCI_SPEC_300) | ||
1203 | ctrl &= ~SDHCI_CTRL_8BITBUS; | ||
1204 | if (ios->bus_width == MMC_BUS_WIDTH_4) | ||
1205 | ctrl |= SDHCI_CTRL_4BITBUS; | ||
1206 | else | ||
1207 | ctrl &= ~SDHCI_CTRL_4BITBUS; | ||
1208 | } | ||
1209 | sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); | ||
1210 | } | ||
1194 | 1211 | ||
1195 | if (ios->bus_width == MMC_BUS_WIDTH_4) | 1212 | ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); |
1196 | ctrl |= SDHCI_CTRL_4BITBUS; | ||
1197 | else | ||
1198 | ctrl &= ~SDHCI_CTRL_4BITBUS; | ||
1199 | 1213 | ||
1200 | if ((ios->timing == MMC_TIMING_SD_HS || | 1214 | if ((ios->timing == MMC_TIMING_SD_HS || |
1201 | ios->timing == MMC_TIMING_MMC_HS) | 1215 | ios->timing == MMC_TIMING_MMC_HS) |
@@ -1681,6 +1695,16 @@ int sdhci_resume_host(struct sdhci_host *host) | |||
1681 | 1695 | ||
1682 | EXPORT_SYMBOL_GPL(sdhci_resume_host); | 1696 | EXPORT_SYMBOL_GPL(sdhci_resume_host); |
1683 | 1697 | ||
1698 | void sdhci_enable_irq_wakeups(struct sdhci_host *host) | ||
1699 | { | ||
1700 | u8 val; | ||
1701 | val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL); | ||
1702 | val |= SDHCI_WAKE_ON_INT; | ||
1703 | sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL); | ||
1704 | } | ||
1705 | |||
1706 | EXPORT_SYMBOL_GPL(sdhci_enable_irq_wakeups); | ||
1707 | |||
1684 | #endif /* CONFIG_PM */ | 1708 | #endif /* CONFIG_PM */ |
1685 | 1709 | ||
1686 | /*****************************************************************************\ | 1710 | /*****************************************************************************\ |
@@ -1845,11 +1869,19 @@ int sdhci_add_host(struct sdhci_host *host) | |||
1845 | mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_300; | 1869 | mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_300; |
1846 | else | 1870 | else |
1847 | mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200; | 1871 | mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200; |
1872 | |||
1848 | mmc->f_max = host->max_clk; | 1873 | mmc->f_max = host->max_clk; |
1849 | mmc->caps |= MMC_CAP_SDIO_IRQ; | 1874 | mmc->caps |= MMC_CAP_SDIO_IRQ; |
1850 | 1875 | ||
1876 | /* | ||
1877 | * A controller may support 8-bit width, but the board itself | ||
1878 | * might not have the pins brought out. Boards that support | ||
1879 | * 8-bit width must set "mmc->caps |= MMC_CAP_8_BIT_DATA;" in | ||
1880 | * their platform code before calling sdhci_add_host(), and we | ||
1881 | * won't assume 8-bit width for hosts without that CAP. | ||
1882 | */ | ||
1851 | if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA)) | 1883 | if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA)) |
1852 | mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA; | 1884 | mmc->caps |= MMC_CAP_4_BIT_DATA; |
1853 | 1885 | ||
1854 | if (caps & SDHCI_CAN_DO_HISPD) | 1886 | if (caps & SDHCI_CAN_DO_HISPD) |
1855 | mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; | 1887 | mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index b7b8a3b28b01..e42d7f00c060 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -76,7 +76,7 @@ | |||
76 | #define SDHCI_CTRL_ADMA1 0x08 | 76 | #define SDHCI_CTRL_ADMA1 0x08 |
77 | #define SDHCI_CTRL_ADMA32 0x10 | 77 | #define SDHCI_CTRL_ADMA32 0x10 |
78 | #define SDHCI_CTRL_ADMA64 0x18 | 78 | #define SDHCI_CTRL_ADMA64 0x18 |
79 | #define SDHCI_CTRL_8BITBUS 0x20 | 79 | #define SDHCI_CTRL_8BITBUS 0x20 |
80 | 80 | ||
81 | #define SDHCI_POWER_CONTROL 0x29 | 81 | #define SDHCI_POWER_CONTROL 0x29 |
82 | #define SDHCI_POWER_ON 0x01 | 82 | #define SDHCI_POWER_ON 0x01 |
@@ -87,6 +87,9 @@ | |||
87 | #define SDHCI_BLOCK_GAP_CONTROL 0x2A | 87 | #define SDHCI_BLOCK_GAP_CONTROL 0x2A |
88 | 88 | ||
89 | #define SDHCI_WAKE_UP_CONTROL 0x2B | 89 | #define SDHCI_WAKE_UP_CONTROL 0x2B |
90 | #define SDHCI_WAKE_ON_INT 0x01 | ||
91 | #define SDHCI_WAKE_ON_INSERT 0x02 | ||
92 | #define SDHCI_WAKE_ON_REMOVE 0x04 | ||
90 | 93 | ||
91 | #define SDHCI_CLOCK_CONTROL 0x2C | 94 | #define SDHCI_CLOCK_CONTROL 0x2C |
92 | #define SDHCI_DIVIDER_SHIFT 8 | 95 | #define SDHCI_DIVIDER_SHIFT 8 |
@@ -152,6 +155,7 @@ | |||
152 | #define SDHCI_CLOCK_BASE_SHIFT 8 | 155 | #define SDHCI_CLOCK_BASE_SHIFT 8 |
153 | #define SDHCI_MAX_BLOCK_MASK 0x00030000 | 156 | #define SDHCI_MAX_BLOCK_MASK 0x00030000 |
154 | #define SDHCI_MAX_BLOCK_SHIFT 16 | 157 | #define SDHCI_MAX_BLOCK_SHIFT 16 |
158 | #define SDHCI_CAN_DO_8BIT 0x00040000 | ||
155 | #define SDHCI_CAN_DO_ADMA2 0x00080000 | 159 | #define SDHCI_CAN_DO_ADMA2 0x00080000 |
156 | #define SDHCI_CAN_DO_ADMA1 0x00100000 | 160 | #define SDHCI_CAN_DO_ADMA1 0x00100000 |
157 | #define SDHCI_CAN_DO_HISPD 0x00200000 | 161 | #define SDHCI_CAN_DO_HISPD 0x00200000 |
@@ -212,6 +216,8 @@ struct sdhci_ops { | |||
212 | unsigned int (*get_max_clock)(struct sdhci_host *host); | 216 | unsigned int (*get_max_clock)(struct sdhci_host *host); |
213 | unsigned int (*get_min_clock)(struct sdhci_host *host); | 217 | unsigned int (*get_min_clock)(struct sdhci_host *host); |
214 | unsigned int (*get_timeout_clock)(struct sdhci_host *host); | 218 | unsigned int (*get_timeout_clock)(struct sdhci_host *host); |
219 | int (*platform_8bit_width)(struct sdhci_host *host, | ||
220 | int width); | ||
215 | void (*platform_send_init_74_clocks)(struct sdhci_host *host, | 221 | void (*platform_send_init_74_clocks)(struct sdhci_host *host, |
216 | u8 power_mode); | 222 | u8 power_mode); |
217 | unsigned int (*get_ro)(struct sdhci_host *host); | 223 | unsigned int (*get_ro)(struct sdhci_host *host); |
@@ -317,6 +323,7 @@ extern void sdhci_remove_host(struct sdhci_host *host, int dead); | |||
317 | #ifdef CONFIG_PM | 323 | #ifdef CONFIG_PM |
318 | extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state); | 324 | extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state); |
319 | extern int sdhci_resume_host(struct sdhci_host *host); | 325 | extern int sdhci_resume_host(struct sdhci_host *host); |
326 | extern void sdhci_enable_irq_wakeups(struct sdhci_host *host); | ||
320 | #endif | 327 | #endif |
321 | 328 | ||
322 | #endif /* __SDHCI_HW_H */ | 329 | #endif /* __SDHCI_HW_H */ |
diff --git a/drivers/mmc/host/ushc.c b/drivers/mmc/host/ushc.c index b4ead4a13c98..f8f65df9b017 100644 --- a/drivers/mmc/host/ushc.c +++ b/drivers/mmc/host/ushc.c | |||
@@ -425,7 +425,7 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
425 | struct usb_device *usb_dev = interface_to_usbdev(intf); | 425 | struct usb_device *usb_dev = interface_to_usbdev(intf); |
426 | struct mmc_host *mmc; | 426 | struct mmc_host *mmc; |
427 | struct ushc_data *ushc; | 427 | struct ushc_data *ushc; |
428 | int ret = -ENOMEM; | 428 | int ret; |
429 | 429 | ||
430 | mmc = mmc_alloc_host(sizeof(struct ushc_data), &intf->dev); | 430 | mmc = mmc_alloc_host(sizeof(struct ushc_data), &intf->dev); |
431 | if (mmc == NULL) | 431 | if (mmc == NULL) |
@@ -462,11 +462,15 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
462 | mmc->max_blk_count = 511; | 462 | mmc->max_blk_count = 511; |
463 | 463 | ||
464 | ushc->int_urb = usb_alloc_urb(0, GFP_KERNEL); | 464 | ushc->int_urb = usb_alloc_urb(0, GFP_KERNEL); |
465 | if (ushc->int_urb == NULL) | 465 | if (ushc->int_urb == NULL) { |
466 | ret = -ENOMEM; | ||
466 | goto err; | 467 | goto err; |
468 | } | ||
467 | ushc->int_data = kzalloc(sizeof(struct ushc_int_data), GFP_KERNEL); | 469 | ushc->int_data = kzalloc(sizeof(struct ushc_int_data), GFP_KERNEL); |
468 | if (ushc->int_data == NULL) | 470 | if (ushc->int_data == NULL) { |
471 | ret = -ENOMEM; | ||
469 | goto err; | 472 | goto err; |
473 | } | ||
470 | usb_fill_int_urb(ushc->int_urb, ushc->usb_dev, | 474 | usb_fill_int_urb(ushc->int_urb, ushc->usb_dev, |
471 | usb_rcvintpipe(usb_dev, | 475 | usb_rcvintpipe(usb_dev, |
472 | intf->cur_altsetting->endpoint[0].desc.bEndpointAddress), | 476 | intf->cur_altsetting->endpoint[0].desc.bEndpointAddress), |
@@ -475,11 +479,15 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
475 | intf->cur_altsetting->endpoint[0].desc.bInterval); | 479 | intf->cur_altsetting->endpoint[0].desc.bInterval); |
476 | 480 | ||
477 | ushc->cbw_urb = usb_alloc_urb(0, GFP_KERNEL); | 481 | ushc->cbw_urb = usb_alloc_urb(0, GFP_KERNEL); |
478 | if (ushc->cbw_urb == NULL) | 482 | if (ushc->cbw_urb == NULL) { |
483 | ret = -ENOMEM; | ||
479 | goto err; | 484 | goto err; |
485 | } | ||
480 | ushc->cbw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL); | 486 | ushc->cbw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL); |
481 | if (ushc->cbw == NULL) | 487 | if (ushc->cbw == NULL) { |
488 | ret = -ENOMEM; | ||
482 | goto err; | 489 | goto err; |
490 | } | ||
483 | ushc->cbw->signature = USHC_CBW_SIGNATURE; | 491 | ushc->cbw->signature = USHC_CBW_SIGNATURE; |
484 | 492 | ||
485 | usb_fill_bulk_urb(ushc->cbw_urb, ushc->usb_dev, usb_sndbulkpipe(usb_dev, 2), | 493 | usb_fill_bulk_urb(ushc->cbw_urb, ushc->usb_dev, usb_sndbulkpipe(usb_dev, 2), |
@@ -487,15 +495,21 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
487 | cbw_callback, ushc); | 495 | cbw_callback, ushc); |
488 | 496 | ||
489 | ushc->data_urb = usb_alloc_urb(0, GFP_KERNEL); | 497 | ushc->data_urb = usb_alloc_urb(0, GFP_KERNEL); |
490 | if (ushc->data_urb == NULL) | 498 | if (ushc->data_urb == NULL) { |
499 | ret = -ENOMEM; | ||
491 | goto err; | 500 | goto err; |
501 | } | ||
492 | 502 | ||
493 | ushc->csw_urb = usb_alloc_urb(0, GFP_KERNEL); | 503 | ushc->csw_urb = usb_alloc_urb(0, GFP_KERNEL); |
494 | if (ushc->csw_urb == NULL) | 504 | if (ushc->csw_urb == NULL) { |
505 | ret = -ENOMEM; | ||
495 | goto err; | 506 | goto err; |
507 | } | ||
496 | ushc->csw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL); | 508 | ushc->csw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL); |
497 | if (ushc->csw == NULL) | 509 | if (ushc->csw == NULL) { |
510 | ret = -ENOMEM; | ||
498 | goto err; | 511 | goto err; |
512 | } | ||
499 | usb_fill_bulk_urb(ushc->csw_urb, ushc->usb_dev, usb_rcvbulkpipe(usb_dev, 6), | 513 | usb_fill_bulk_urb(ushc->csw_urb, ushc->usb_dev, usb_rcvbulkpipe(usb_dev, 6), |
500 | ushc->csw, sizeof(struct ushc_csw), | 514 | ushc->csw, sizeof(struct ushc_csw), |
501 | csw_callback, ushc); | 515 | csw_callback, ushc); |