diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-03-23 20:10:36 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-03-23 20:10:36 -0400 |
commit | bba1594d348b59d6172e02bf74fba837c8273989 (patch) | |
tree | 223e67a4ad043d4ec9361e89c59592ea60e7ddff | |
parent | 9e5ed094c89e55fbf11d2e81d60be98eb12346c0 (diff) | |
parent | 7437cfa532842ce75189826742bddf1ba137f58e (diff) |
Merge branch 'mmci' into amba
-rw-r--r-- | arch/arm/mach-ux500/board-mop500-sdi.c | 21 | ||||
-rw-r--r-- | drivers/mmc/host/mmci.c | 166 | ||||
-rw-r--r-- | drivers/mmc/host/mmci.h | 15 | ||||
-rw-r--r-- | include/linux/amba/mmci.h | 22 |
4 files changed, 151 insertions, 73 deletions
diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c index 23be34b3bb6e..4049bd7f061f 100644 --- a/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/arch/arm/mach-ux500/board-mop500-sdi.c | |||
@@ -31,21 +31,13 @@ | |||
31 | * SDI 0 (MicroSD slot) | 31 | * SDI 0 (MicroSD slot) |
32 | */ | 32 | */ |
33 | 33 | ||
34 | /* MMCIPOWER bits */ | ||
35 | #define MCI_DATA2DIREN (1 << 2) | ||
36 | #define MCI_CMDDIREN (1 << 3) | ||
37 | #define MCI_DATA0DIREN (1 << 4) | ||
38 | #define MCI_DATA31DIREN (1 << 5) | ||
39 | #define MCI_FBCLKEN (1 << 7) | ||
40 | |||
41 | /* GPIO pins used by the sdi0 level shifter */ | 34 | /* GPIO pins used by the sdi0 level shifter */ |
42 | static int sdi0_en = -1; | 35 | static int sdi0_en = -1; |
43 | static int sdi0_vsel = -1; | 36 | static int sdi0_vsel = -1; |
44 | 37 | ||
45 | static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd, | 38 | static int mop500_sdi0_ios_handler(struct device *dev, struct mmc_ios *ios) |
46 | unsigned char power_mode) | ||
47 | { | 39 | { |
48 | switch (power_mode) { | 40 | switch (ios->power_mode) { |
49 | case MMC_POWER_UP: | 41 | case MMC_POWER_UP: |
50 | case MMC_POWER_ON: | 42 | case MMC_POWER_ON: |
51 | /* | 43 | /* |
@@ -65,8 +57,7 @@ static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd, | |||
65 | break; | 57 | break; |
66 | } | 58 | } |
67 | 59 | ||
68 | return MCI_FBCLKEN | MCI_CMDDIREN | MCI_DATA0DIREN | | 60 | return 0; |
69 | MCI_DATA2DIREN | MCI_DATA31DIREN; | ||
70 | } | 61 | } |
71 | 62 | ||
72 | #ifdef CONFIG_STE_DMA40 | 63 | #ifdef CONFIG_STE_DMA40 |
@@ -90,13 +81,17 @@ static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = { | |||
90 | #endif | 81 | #endif |
91 | 82 | ||
92 | static struct mmci_platform_data mop500_sdi0_data = { | 83 | static struct mmci_platform_data mop500_sdi0_data = { |
93 | .vdd_handler = mop500_sdi0_vdd_handler, | 84 | .ios_handler = mop500_sdi0_ios_handler, |
94 | .ocr_mask = MMC_VDD_29_30, | 85 | .ocr_mask = MMC_VDD_29_30, |
95 | .f_max = 50000000, | 86 | .f_max = 50000000, |
96 | .capabilities = MMC_CAP_4_BIT_DATA | | 87 | .capabilities = MMC_CAP_4_BIT_DATA | |
97 | MMC_CAP_SD_HIGHSPEED | | 88 | MMC_CAP_SD_HIGHSPEED | |
98 | MMC_CAP_MMC_HIGHSPEED, | 89 | MMC_CAP_MMC_HIGHSPEED, |
99 | .gpio_wp = -1, | 90 | .gpio_wp = -1, |
91 | .sigdir = MCI_ST_FBCLKEN | | ||
92 | MCI_ST_CMDDIREN | | ||
93 | MCI_ST_DATA0DIREN | | ||
94 | MCI_ST_DATA2DIREN, | ||
100 | #ifdef CONFIG_STE_DMA40 | 95 | #ifdef CONFIG_STE_DMA40 |
101 | .dma_filter = stedma40_filter, | 96 | .dma_filter = stedma40_filter, |
102 | .dma_rx_param = &mop500_sdi0_dma_cfg_rx, | 97 | .dma_rx_param = &mop500_sdi0_dma_cfg_rx, |
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 6692392c05dd..deb73e2b7460 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -53,6 +53,8 @@ static unsigned int fmax = 515633; | |||
53 | * @sdio: variant supports SDIO | 53 | * @sdio: variant supports SDIO |
54 | * @st_clkdiv: true if using a ST-specific clock divider algorithm | 54 | * @st_clkdiv: true if using a ST-specific clock divider algorithm |
55 | * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register | 55 | * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register |
56 | * @pwrreg_powerup: power up value for MMCIPOWER register | ||
57 | * @signal_direction: input/out direction of bus signals can be indicated | ||
56 | */ | 58 | */ |
57 | struct variant_data { | 59 | struct variant_data { |
58 | unsigned int clkreg; | 60 | unsigned int clkreg; |
@@ -63,18 +65,22 @@ struct variant_data { | |||
63 | bool sdio; | 65 | bool sdio; |
64 | bool st_clkdiv; | 66 | bool st_clkdiv; |
65 | bool blksz_datactrl16; | 67 | bool blksz_datactrl16; |
68 | u32 pwrreg_powerup; | ||
69 | bool signal_direction; | ||
66 | }; | 70 | }; |
67 | 71 | ||
68 | static struct variant_data variant_arm = { | 72 | static struct variant_data variant_arm = { |
69 | .fifosize = 16 * 4, | 73 | .fifosize = 16 * 4, |
70 | .fifohalfsize = 8 * 4, | 74 | .fifohalfsize = 8 * 4, |
71 | .datalength_bits = 16, | 75 | .datalength_bits = 16, |
76 | .pwrreg_powerup = MCI_PWR_UP, | ||
72 | }; | 77 | }; |
73 | 78 | ||
74 | static struct variant_data variant_arm_extended_fifo = { | 79 | static struct variant_data variant_arm_extended_fifo = { |
75 | .fifosize = 128 * 4, | 80 | .fifosize = 128 * 4, |
76 | .fifohalfsize = 64 * 4, | 81 | .fifohalfsize = 64 * 4, |
77 | .datalength_bits = 16, | 82 | .datalength_bits = 16, |
83 | .pwrreg_powerup = MCI_PWR_UP, | ||
78 | }; | 84 | }; |
79 | 85 | ||
80 | static struct variant_data variant_u300 = { | 86 | static struct variant_data variant_u300 = { |
@@ -83,6 +89,8 @@ static struct variant_data variant_u300 = { | |||
83 | .clkreg_enable = MCI_ST_U300_HWFCEN, | 89 | .clkreg_enable = MCI_ST_U300_HWFCEN, |
84 | .datalength_bits = 16, | 90 | .datalength_bits = 16, |
85 | .sdio = true, | 91 | .sdio = true, |
92 | .pwrreg_powerup = MCI_PWR_ON, | ||
93 | .signal_direction = true, | ||
86 | }; | 94 | }; |
87 | 95 | ||
88 | static struct variant_data variant_ux500 = { | 96 | static struct variant_data variant_ux500 = { |
@@ -93,6 +101,8 @@ static struct variant_data variant_ux500 = { | |||
93 | .datalength_bits = 24, | 101 | .datalength_bits = 24, |
94 | .sdio = true, | 102 | .sdio = true, |
95 | .st_clkdiv = true, | 103 | .st_clkdiv = true, |
104 | .pwrreg_powerup = MCI_PWR_ON, | ||
105 | .signal_direction = true, | ||
96 | }; | 106 | }; |
97 | 107 | ||
98 | static struct variant_data variant_ux500v2 = { | 108 | static struct variant_data variant_ux500v2 = { |
@@ -104,11 +114,35 @@ static struct variant_data variant_ux500v2 = { | |||
104 | .sdio = true, | 114 | .sdio = true, |
105 | .st_clkdiv = true, | 115 | .st_clkdiv = true, |
106 | .blksz_datactrl16 = true, | 116 | .blksz_datactrl16 = true, |
117 | .pwrreg_powerup = MCI_PWR_ON, | ||
118 | .signal_direction = true, | ||
107 | }; | 119 | }; |
108 | 120 | ||
109 | /* | 121 | /* |
110 | * This must be called with host->lock held | 122 | * This must be called with host->lock held |
111 | */ | 123 | */ |
124 | static void mmci_write_clkreg(struct mmci_host *host, u32 clk) | ||
125 | { | ||
126 | if (host->clk_reg != clk) { | ||
127 | host->clk_reg = clk; | ||
128 | writel(clk, host->base + MMCICLOCK); | ||
129 | } | ||
130 | } | ||
131 | |||
132 | /* | ||
133 | * This must be called with host->lock held | ||
134 | */ | ||
135 | static void mmci_write_pwrreg(struct mmci_host *host, u32 pwr) | ||
136 | { | ||
137 | if (host->pwr_reg != pwr) { | ||
138 | host->pwr_reg = pwr; | ||
139 | writel(pwr, host->base + MMCIPOWER); | ||
140 | } | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * This must be called with host->lock held | ||
145 | */ | ||
112 | static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) | 146 | static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) |
113 | { | 147 | { |
114 | struct variant_data *variant = host->variant; | 148 | struct variant_data *variant = host->variant; |
@@ -153,7 +187,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) | |||
153 | if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8) | 187 | if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8) |
154 | clk |= MCI_ST_8BIT_BUS; | 188 | clk |= MCI_ST_8BIT_BUS; |
155 | 189 | ||
156 | writel(clk, host->base + MMCICLOCK); | 190 | mmci_write_clkreg(host, clk); |
157 | } | 191 | } |
158 | 192 | ||
159 | static void | 193 | static void |
@@ -166,14 +200,10 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) | |||
166 | host->mrq = NULL; | 200 | host->mrq = NULL; |
167 | host->cmd = NULL; | 201 | host->cmd = NULL; |
168 | 202 | ||
169 | /* | ||
170 | * Need to drop the host lock here; mmc_request_done may call | ||
171 | * back into the driver... | ||
172 | */ | ||
173 | spin_unlock(&host->lock); | ||
174 | pm_runtime_put(mmc_dev(host->mmc)); | ||
175 | mmc_request_done(host->mmc, mrq); | 203 | mmc_request_done(host->mmc, mrq); |
176 | spin_lock(&host->lock); | 204 | |
205 | pm_runtime_mark_last_busy(mmc_dev(host->mmc)); | ||
206 | pm_runtime_put_autosuspend(mmc_dev(host->mmc)); | ||
177 | } | 207 | } |
178 | 208 | ||
179 | static void mmci_set_mask1(struct mmci_host *host, unsigned int mask) | 209 | static void mmci_set_mask1(struct mmci_host *host, unsigned int mask) |
@@ -607,6 +637,11 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) | |||
607 | if (data->flags & MMC_DATA_READ) | 637 | if (data->flags & MMC_DATA_READ) |
608 | datactrl |= MCI_DPSM_DIRECTION; | 638 | datactrl |= MCI_DPSM_DIRECTION; |
609 | 639 | ||
640 | /* The ST Micro variants has a special bit to enable SDIO */ | ||
641 | if (variant->sdio && host->mmc->card) | ||
642 | if (mmc_card_sdio(host->mmc->card)) | ||
643 | datactrl |= MCI_ST_DPSM_SDIOEN; | ||
644 | |||
610 | /* | 645 | /* |
611 | * Attempt to use DMA operation mode, if this | 646 | * Attempt to use DMA operation mode, if this |
612 | * should fail, fall back to PIO mode | 647 | * should fail, fall back to PIO mode |
@@ -635,11 +670,6 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) | |||
635 | irqmask = MCI_TXFIFOHALFEMPTYMASK; | 670 | irqmask = MCI_TXFIFOHALFEMPTYMASK; |
636 | } | 671 | } |
637 | 672 | ||
638 | /* The ST Micro variants has a special bit to enable SDIO */ | ||
639 | if (variant->sdio && host->mmc->card) | ||
640 | if (mmc_card_sdio(host->mmc->card)) | ||
641 | datactrl |= MCI_ST_DPSM_SDIOEN; | ||
642 | |||
643 | writel(datactrl, base + MMCIDATACTRL); | 673 | writel(datactrl, base + MMCIDATACTRL); |
644 | writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0); | 674 | writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0); |
645 | mmci_set_mask1(host, irqmask); | 675 | mmci_set_mask1(host, irqmask); |
@@ -786,7 +816,24 @@ static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int rema | |||
786 | if (count <= 0) | 816 | if (count <= 0) |
787 | break; | 817 | break; |
788 | 818 | ||
789 | readsl(base + MMCIFIFO, ptr, count >> 2); | 819 | /* |
820 | * SDIO especially may want to send something that is | ||
821 | * not divisible by 4 (as opposed to card sectors | ||
822 | * etc). Therefore make sure to always read the last bytes | ||
823 | * while only doing full 32-bit reads towards the FIFO. | ||
824 | */ | ||
825 | if (unlikely(count & 0x3)) { | ||
826 | if (count < 4) { | ||
827 | unsigned char buf[4]; | ||
828 | readsl(base + MMCIFIFO, buf, 1); | ||
829 | memcpy(ptr, buf, count); | ||
830 | } else { | ||
831 | readsl(base + MMCIFIFO, ptr, count >> 2); | ||
832 | count &= ~0x3; | ||
833 | } | ||
834 | } else { | ||
835 | readsl(base + MMCIFIFO, ptr, count >> 2); | ||
836 | } | ||
790 | 837 | ||
791 | ptr += count; | 838 | ptr += count; |
792 | remain -= count; | 839 | remain -= count; |
@@ -821,14 +868,13 @@ static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int rem | |||
821 | */ | 868 | */ |
822 | if (variant->sdio && | 869 | if (variant->sdio && |
823 | mmc_card_sdio(host->mmc->card)) { | 870 | mmc_card_sdio(host->mmc->card)) { |
871 | u32 clk; | ||
824 | if (count < 8) | 872 | if (count < 8) |
825 | writel(readl(host->base + MMCICLOCK) & | 873 | clk = host->clk_reg & ~variant->clkreg_enable; |
826 | ~variant->clkreg_enable, | ||
827 | host->base + MMCICLOCK); | ||
828 | else | 874 | else |
829 | writel(readl(host->base + MMCICLOCK) | | 875 | clk = host->clk_reg | variant->clkreg_enable; |
830 | variant->clkreg_enable, | 876 | |
831 | host->base + MMCICLOCK); | 877 | mmci_write_clkreg(host, clk); |
832 | } | 878 | } |
833 | 879 | ||
834 | /* | 880 | /* |
@@ -1015,10 +1061,17 @@ static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
1015 | static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 1061 | static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
1016 | { | 1062 | { |
1017 | struct mmci_host *host = mmc_priv(mmc); | 1063 | struct mmci_host *host = mmc_priv(mmc); |
1064 | struct variant_data *variant = host->variant; | ||
1018 | u32 pwr = 0; | 1065 | u32 pwr = 0; |
1019 | unsigned long flags; | 1066 | unsigned long flags; |
1020 | int ret; | 1067 | int ret; |
1021 | 1068 | ||
1069 | pm_runtime_get_sync(mmc_dev(mmc)); | ||
1070 | |||
1071 | if (host->plat->ios_handler && | ||
1072 | host->plat->ios_handler(mmc_dev(mmc), ios)) | ||
1073 | dev_err(mmc_dev(mmc), "platform ios_handler failed\n"); | ||
1074 | |||
1022 | switch (ios->power_mode) { | 1075 | switch (ios->power_mode) { |
1023 | case MMC_POWER_OFF: | 1076 | case MMC_POWER_OFF: |
1024 | if (host->vcc) | 1077 | if (host->vcc) |
@@ -1035,22 +1088,38 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1035 | * power should be rare so we print an error | 1088 | * power should be rare so we print an error |
1036 | * and return here. | 1089 | * and return here. |
1037 | */ | 1090 | */ |
1038 | return; | 1091 | goto out; |
1039 | } | 1092 | } |
1040 | } | 1093 | } |
1041 | if (host->plat->vdd_handler) | 1094 | /* |
1042 | pwr |= host->plat->vdd_handler(mmc_dev(mmc), ios->vdd, | 1095 | * The ST Micro variant doesn't have the PL180s MCI_PWR_UP |
1043 | ios->power_mode); | 1096 | * and instead uses MCI_PWR_ON so apply whatever value is |
1044 | /* The ST version does not have this, fall through to POWER_ON */ | 1097 | * configured in the variant data. |
1045 | if (host->hw_designer != AMBA_VENDOR_ST) { | 1098 | */ |
1046 | pwr |= MCI_PWR_UP; | 1099 | pwr |= variant->pwrreg_powerup; |
1047 | break; | 1100 | |
1048 | } | 1101 | break; |
1049 | case MMC_POWER_ON: | 1102 | case MMC_POWER_ON: |
1050 | pwr |= MCI_PWR_ON; | 1103 | pwr |= MCI_PWR_ON; |
1051 | break; | 1104 | break; |
1052 | } | 1105 | } |
1053 | 1106 | ||
1107 | if (variant->signal_direction && ios->power_mode != MMC_POWER_OFF) { | ||
1108 | /* | ||
1109 | * The ST Micro variant has some additional bits | ||
1110 | * indicating signal direction for the signals in | ||
1111 | * the SD/MMC bus and feedback-clock usage. | ||
1112 | */ | ||
1113 | pwr |= host->plat->sigdir; | ||
1114 | |||
1115 | if (ios->bus_width == MMC_BUS_WIDTH_4) | ||
1116 | pwr &= ~MCI_ST_DATA74DIREN; | ||
1117 | else if (ios->bus_width == MMC_BUS_WIDTH_1) | ||
1118 | pwr &= (~MCI_ST_DATA74DIREN & | ||
1119 | ~MCI_ST_DATA31DIREN & | ||
1120 | ~MCI_ST_DATA2DIREN); | ||
1121 | } | ||
1122 | |||
1054 | if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) { | 1123 | if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) { |
1055 | if (host->hw_designer != AMBA_VENDOR_ST) | 1124 | if (host->hw_designer != AMBA_VENDOR_ST) |
1056 | pwr |= MCI_ROD; | 1125 | pwr |= MCI_ROD; |
@@ -1066,13 +1135,13 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1066 | spin_lock_irqsave(&host->lock, flags); | 1135 | spin_lock_irqsave(&host->lock, flags); |
1067 | 1136 | ||
1068 | mmci_set_clkreg(host, ios->clock); | 1137 | mmci_set_clkreg(host, ios->clock); |
1069 | 1138 | mmci_write_pwrreg(host, pwr); | |
1070 | if (host->pwr != pwr) { | ||
1071 | host->pwr = pwr; | ||
1072 | writel(pwr, host->base + MMCIPOWER); | ||
1073 | } | ||
1074 | 1139 | ||
1075 | spin_unlock_irqrestore(&host->lock, flags); | 1140 | spin_unlock_irqrestore(&host->lock, flags); |
1141 | |||
1142 | out: | ||
1143 | pm_runtime_mark_last_busy(mmc_dev(mmc)); | ||
1144 | pm_runtime_put_autosuspend(mmc_dev(mmc)); | ||
1076 | } | 1145 | } |
1077 | 1146 | ||
1078 | static int mmci_get_ro(struct mmc_host *mmc) | 1147 | static int mmci_get_ro(struct mmc_host *mmc) |
@@ -1345,6 +1414,8 @@ static int __devinit mmci_probe(struct amba_device *dev, | |||
1345 | 1414 | ||
1346 | mmci_dma_setup(host); | 1415 | mmci_dma_setup(host); |
1347 | 1416 | ||
1417 | pm_runtime_set_autosuspend_delay(&dev->dev, 50); | ||
1418 | pm_runtime_use_autosuspend(&dev->dev); | ||
1348 | pm_runtime_put(&dev->dev); | 1419 | pm_runtime_put(&dev->dev); |
1349 | 1420 | ||
1350 | mmc_add_host(mmc); | 1421 | mmc_add_host(mmc); |
@@ -1429,43 +1500,49 @@ static int __devexit mmci_remove(struct amba_device *dev) | |||
1429 | return 0; | 1500 | return 0; |
1430 | } | 1501 | } |
1431 | 1502 | ||
1432 | #ifdef CONFIG_PM | 1503 | #ifdef CONFIG_SUSPEND |
1433 | static int mmci_suspend(struct amba_device *dev, pm_message_t state) | 1504 | static int mmci_suspend(struct device *dev) |
1434 | { | 1505 | { |
1435 | struct mmc_host *mmc = amba_get_drvdata(dev); | 1506 | struct amba_device *adev = to_amba_device(dev); |
1507 | struct mmc_host *mmc = amba_get_drvdata(adev); | ||
1436 | int ret = 0; | 1508 | int ret = 0; |
1437 | 1509 | ||
1438 | if (mmc) { | 1510 | if (mmc) { |
1439 | struct mmci_host *host = mmc_priv(mmc); | 1511 | struct mmci_host *host = mmc_priv(mmc); |
1440 | 1512 | ||
1441 | ret = mmc_suspend_host(mmc); | 1513 | ret = mmc_suspend_host(mmc); |
1442 | if (ret == 0) | 1514 | if (ret == 0) { |
1515 | pm_runtime_get_sync(dev); | ||
1443 | writel(0, host->base + MMCIMASK0); | 1516 | writel(0, host->base + MMCIMASK0); |
1517 | } | ||
1444 | } | 1518 | } |
1445 | 1519 | ||
1446 | return ret; | 1520 | return ret; |
1447 | } | 1521 | } |
1448 | 1522 | ||
1449 | static int mmci_resume(struct amba_device *dev) | 1523 | static int mmci_resume(struct device *dev) |
1450 | { | 1524 | { |
1451 | struct mmc_host *mmc = amba_get_drvdata(dev); | 1525 | struct amba_device *adev = to_amba_device(dev); |
1526 | struct mmc_host *mmc = amba_get_drvdata(adev); | ||
1452 | int ret = 0; | 1527 | int ret = 0; |
1453 | 1528 | ||
1454 | if (mmc) { | 1529 | if (mmc) { |
1455 | struct mmci_host *host = mmc_priv(mmc); | 1530 | struct mmci_host *host = mmc_priv(mmc); |
1456 | 1531 | ||
1457 | writel(MCI_IRQENABLE, host->base + MMCIMASK0); | 1532 | writel(MCI_IRQENABLE, host->base + MMCIMASK0); |
1533 | pm_runtime_put(dev); | ||
1458 | 1534 | ||
1459 | ret = mmc_resume_host(mmc); | 1535 | ret = mmc_resume_host(mmc); |
1460 | } | 1536 | } |
1461 | 1537 | ||
1462 | return ret; | 1538 | return ret; |
1463 | } | 1539 | } |
1464 | #else | ||
1465 | #define mmci_suspend NULL | ||
1466 | #define mmci_resume NULL | ||
1467 | #endif | 1540 | #endif |
1468 | 1541 | ||
1542 | static const struct dev_pm_ops mmci_dev_pm_ops = { | ||
1543 | SET_SYSTEM_SLEEP_PM_OPS(mmci_suspend, mmci_resume) | ||
1544 | }; | ||
1545 | |||
1469 | static struct amba_id mmci_ids[] = { | 1546 | static struct amba_id mmci_ids[] = { |
1470 | { | 1547 | { |
1471 | .id = 0x00041180, | 1548 | .id = 0x00041180, |
@@ -1511,11 +1588,10 @@ MODULE_DEVICE_TABLE(amba, mmci_ids); | |||
1511 | static struct amba_driver mmci_driver = { | 1588 | static struct amba_driver mmci_driver = { |
1512 | .drv = { | 1589 | .drv = { |
1513 | .name = DRIVER_NAME, | 1590 | .name = DRIVER_NAME, |
1591 | .pm = &mmci_dev_pm_ops, | ||
1514 | }, | 1592 | }, |
1515 | .probe = mmci_probe, | 1593 | .probe = mmci_probe, |
1516 | .remove = __devexit_p(mmci_remove), | 1594 | .remove = __devexit_p(mmci_remove), |
1517 | .suspend = mmci_suspend, | ||
1518 | .resume = mmci_resume, | ||
1519 | .id_table = mmci_ids, | 1595 | .id_table = mmci_ids, |
1520 | }; | 1596 | }; |
1521 | 1597 | ||
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 79e4143ab9df..d437ccf62d6b 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h | |||
@@ -13,16 +13,6 @@ | |||
13 | #define MCI_PWR_ON 0x03 | 13 | #define MCI_PWR_ON 0x03 |
14 | #define MCI_OD (1 << 6) | 14 | #define MCI_OD (1 << 6) |
15 | #define MCI_ROD (1 << 7) | 15 | #define MCI_ROD (1 << 7) |
16 | /* | ||
17 | * The ST Micro version does not have ROD and reuse the voltage registers | ||
18 | * for direction settings | ||
19 | */ | ||
20 | #define MCI_ST_DATA2DIREN (1 << 2) | ||
21 | #define MCI_ST_CMDDIREN (1 << 3) | ||
22 | #define MCI_ST_DATA0DIREN (1 << 4) | ||
23 | #define MCI_ST_DATA31DIREN (1 << 5) | ||
24 | #define MCI_ST_FBCLKEN (1 << 7) | ||
25 | #define MCI_ST_DATA74DIREN (1 << 8) | ||
26 | 16 | ||
27 | #define MMCICLOCK 0x004 | 17 | #define MMCICLOCK 0x004 |
28 | #define MCI_CLK_ENABLE (1 << 8) | 18 | #define MCI_CLK_ENABLE (1 << 8) |
@@ -160,7 +150,7 @@ | |||
160 | (MCI_RXFIFOHALFFULLMASK | MCI_RXDATAAVLBLMASK | \ | 150 | (MCI_RXFIFOHALFFULLMASK | MCI_RXDATAAVLBLMASK | \ |
161 | MCI_TXFIFOHALFEMPTYMASK) | 151 | MCI_TXFIFOHALFEMPTYMASK) |
162 | 152 | ||
163 | #define NR_SG 16 | 153 | #define NR_SG 128 |
164 | 154 | ||
165 | struct clk; | 155 | struct clk; |
166 | struct variant_data; | 156 | struct variant_data; |
@@ -189,7 +179,8 @@ struct mmci_host { | |||
189 | 179 | ||
190 | unsigned int mclk; | 180 | unsigned int mclk; |
191 | unsigned int cclk; | 181 | unsigned int cclk; |
192 | u32 pwr; | 182 | u32 pwr_reg; |
183 | u32 clk_reg; | ||
193 | struct mmci_platform_data *plat; | 184 | struct mmci_platform_data *plat; |
194 | struct variant_data *variant; | 185 | struct variant_data *variant; |
195 | 186 | ||
diff --git a/include/linux/amba/mmci.h b/include/linux/amba/mmci.h index 0101e9c17fa1..32a89cf5ec45 100644 --- a/include/linux/amba/mmci.h +++ b/include/linux/amba/mmci.h | |||
@@ -6,6 +6,19 @@ | |||
6 | 6 | ||
7 | #include <linux/mmc/host.h> | 7 | #include <linux/mmc/host.h> |
8 | 8 | ||
9 | |||
10 | /* | ||
11 | * These defines is places here due to access is needed from machine | ||
12 | * configuration files. The ST Micro version does not have ROD and | ||
13 | * reuse the voltage registers for direction settings. | ||
14 | */ | ||
15 | #define MCI_ST_DATA2DIREN (1 << 2) | ||
16 | #define MCI_ST_CMDDIREN (1 << 3) | ||
17 | #define MCI_ST_DATA0DIREN (1 << 4) | ||
18 | #define MCI_ST_DATA31DIREN (1 << 5) | ||
19 | #define MCI_ST_FBCLKEN (1 << 7) | ||
20 | #define MCI_ST_DATA74DIREN (1 << 8) | ||
21 | |||
9 | /* Just some dummy forwarding */ | 22 | /* Just some dummy forwarding */ |
10 | struct dma_chan; | 23 | struct dma_chan; |
11 | 24 | ||
@@ -18,7 +31,8 @@ struct dma_chan; | |||
18 | * @ocr_mask: available voltages on the 4 pins from the block, this | 31 | * @ocr_mask: available voltages on the 4 pins from the block, this |
19 | * is ignored if a regulator is used, see the MMC_VDD_* masks in | 32 | * is ignored if a regulator is used, see the MMC_VDD_* masks in |
20 | * mmc/host.h | 33 | * mmc/host.h |
21 | * @vdd_handler: a callback function to translate a MMC_VDD_* | 34 | * @ios_handler: a callback function to act on specfic ios changes, |
35 | * used for example to control a levelshifter | ||
22 | * mask into a value to be binary (or set some other custom bits | 36 | * mask into a value to be binary (or set some other custom bits |
23 | * in MMCIPWR) or:ed and written into the MMCIPWR register of the | 37 | * in MMCIPWR) or:ed and written into the MMCIPWR register of the |
24 | * block. May also control external power based on the power_mode. | 38 | * block. May also control external power based on the power_mode. |
@@ -31,6 +45,8 @@ struct dma_chan; | |||
31 | * @capabilities: the capabilities of the block as implemented in | 45 | * @capabilities: the capabilities of the block as implemented in |
32 | * this platform, signify anything MMC_CAP_* from mmc/host.h | 46 | * this platform, signify anything MMC_CAP_* from mmc/host.h |
33 | * @capabilities2: more capabilities, MMC_CAP2_* from mmc/host.h | 47 | * @capabilities2: more capabilities, MMC_CAP2_* from mmc/host.h |
48 | * @sigdir: a bit field indicating for what bits in the MMC bus the host | ||
49 | * should enable signal direction indication. | ||
34 | * @dma_filter: function used to select an appropriate RX and TX | 50 | * @dma_filter: function used to select an appropriate RX and TX |
35 | * DMA channel to be used for DMA, if and only if you're deploying the | 51 | * DMA channel to be used for DMA, if and only if you're deploying the |
36 | * generic DMA engine | 52 | * generic DMA engine |
@@ -46,14 +62,14 @@ struct dma_chan; | |||
46 | struct mmci_platform_data { | 62 | struct mmci_platform_data { |
47 | unsigned int f_max; | 63 | unsigned int f_max; |
48 | unsigned int ocr_mask; | 64 | unsigned int ocr_mask; |
49 | u32 (*vdd_handler)(struct device *, unsigned int vdd, | 65 | int (*ios_handler)(struct device *, struct mmc_ios *); |
50 | unsigned char power_mode); | ||
51 | unsigned int (*status)(struct device *); | 66 | unsigned int (*status)(struct device *); |
52 | int gpio_wp; | 67 | int gpio_wp; |
53 | int gpio_cd; | 68 | int gpio_cd; |
54 | bool cd_invert; | 69 | bool cd_invert; |
55 | unsigned long capabilities; | 70 | unsigned long capabilities; |
56 | unsigned long capabilities2; | 71 | unsigned long capabilities2; |
72 | u32 sigdir; | ||
57 | bool (*dma_filter)(struct dma_chan *chan, void *filter_param); | 73 | bool (*dma_filter)(struct dma_chan *chan, void *filter_param); |
58 | void *dma_rx_param; | 74 | void *dma_rx_param; |
59 | void *dma_tx_param; | 75 | void *dma_tx_param; |