diff options
-rw-r--r-- | drivers/misc/tifm_7xx1.c | 332 | ||||
-rw-r--r-- | drivers/misc/tifm_core.c | 305 | ||||
-rw-r--r-- | drivers/mmc/Kconfig | 106 | ||||
-rw-r--r-- | drivers/mmc/Makefile | 33 | ||||
-rw-r--r-- | drivers/mmc/card/Kconfig | 17 | ||||
-rw-r--r-- | drivers/mmc/card/Makefile | 11 | ||||
-rw-r--r-- | drivers/mmc/card/block.c (renamed from drivers/mmc/mmc_block.c) | 55 | ||||
-rw-r--r-- | drivers/mmc/card/queue.c (renamed from drivers/mmc/mmc_queue.c) | 12 | ||||
-rw-r--r-- | drivers/mmc/card/queue.h (renamed from drivers/mmc/mmc_queue.h) | 0 | ||||
-rw-r--r-- | drivers/mmc/core/Kconfig | 17 | ||||
-rw-r--r-- | drivers/mmc/core/Makefile | 11 | ||||
-rw-r--r-- | drivers/mmc/core/core.c | 727 | ||||
-rw-r--r-- | drivers/mmc/core/core.h | 70 | ||||
-rw-r--r-- | drivers/mmc/core/mmc.c | 537 | ||||
-rw-r--r-- | drivers/mmc/core/mmc_ops.c | 276 | ||||
-rw-r--r-- | drivers/mmc/core/mmc_ops.h | 27 | ||||
-rw-r--r-- | drivers/mmc/core/sd.c | 587 | ||||
-rw-r--r-- | drivers/mmc/core/sd_ops.c | 316 | ||||
-rw-r--r-- | drivers/mmc/core/sd_ops.h | 25 | ||||
-rw-r--r-- | drivers/mmc/core/sysfs.c (renamed from drivers/mmc/mmc_sysfs.c) | 11 | ||||
-rw-r--r-- | drivers/mmc/core/sysfs.h (renamed from drivers/mmc/mmc.h) | 10 | ||||
-rw-r--r-- | drivers/mmc/host/Kconfig | 103 | ||||
-rw-r--r-- | drivers/mmc/host/Makefile | 18 | ||||
-rw-r--r-- | drivers/mmc/host/at91_mci.c (renamed from drivers/mmc/at91_mci.c) | 1 | ||||
-rw-r--r-- | drivers/mmc/host/au1xmmc.c (renamed from drivers/mmc/au1xmmc.c) | 1 | ||||
-rw-r--r-- | drivers/mmc/host/au1xmmc.h (renamed from drivers/mmc/au1xmmc.h) | 0 | ||||
-rw-r--r-- | drivers/mmc/host/imxmmc.c (renamed from drivers/mmc/imxmmc.c) | 1 | ||||
-rw-r--r-- | drivers/mmc/host/imxmmc.h (renamed from drivers/mmc/imxmmc.h) | 0 | ||||
-rw-r--r-- | drivers/mmc/host/mmci.c (renamed from drivers/mmc/mmci.c) | 1 | ||||
-rw-r--r-- | drivers/mmc/host/mmci.h (renamed from drivers/mmc/mmci.h) | 0 | ||||
-rw-r--r-- | drivers/mmc/host/omap.c (renamed from drivers/mmc/omap.c) | 56 | ||||
-rw-r--r-- | drivers/mmc/host/pxamci.c (renamed from drivers/mmc/pxamci.c) | 1 | ||||
-rw-r--r-- | drivers/mmc/host/pxamci.h (renamed from drivers/mmc/pxamci.h) | 0 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.c (renamed from drivers/mmc/sdhci.c) | 43 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.h (renamed from drivers/mmc/sdhci.h) | 4 | ||||
-rw-r--r-- | drivers/mmc/host/tifm_sd.c | 1102 | ||||
-rw-r--r-- | drivers/mmc/host/wbsd.c (renamed from drivers/mmc/wbsd.c) | 205 | ||||
-rw-r--r-- | drivers/mmc/host/wbsd.h (renamed from drivers/mmc/wbsd.h) | 9 | ||||
-rw-r--r-- | drivers/mmc/mmc.c | 1724 | ||||
-rw-r--r-- | drivers/mmc/tifm_sd.c | 987 | ||||
-rw-r--r-- | include/asm-arm/arch-imx/mmc.h | 2 | ||||
-rw-r--r-- | include/asm-arm/arch-pxa/mmc.h | 2 | ||||
-rw-r--r-- | include/asm-arm/mach/mmc.h | 2 | ||||
-rw-r--r-- | include/linux/mmc/card.h | 32 | ||||
-rw-r--r-- | include/linux/mmc/core.h | 112 | ||||
-rw-r--r-- | include/linux/mmc/host.h | 59 | ||||
-rw-r--r-- | include/linux/mmc/mmc.h | 322 | ||||
-rw-r--r-- | include/linux/mmc/protocol.h | 327 | ||||
-rw-r--r-- | include/linux/mmc/sd.h | 83 | ||||
-rw-r--r-- | include/linux/tifm.h | 117 |
50 files changed, 4858 insertions, 3941 deletions
diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c index bc60e2fc3c2c..1ba6c085419a 100644 --- a/drivers/misc/tifm_7xx1.c +++ b/drivers/misc/tifm_7xx1.c | |||
@@ -11,10 +11,20 @@ | |||
11 | 11 | ||
12 | #include <linux/tifm.h> | 12 | #include <linux/tifm.h> |
13 | #include <linux/dma-mapping.h> | 13 | #include <linux/dma-mapping.h> |
14 | #include <linux/freezer.h> | ||
15 | 14 | ||
16 | #define DRIVER_NAME "tifm_7xx1" | 15 | #define DRIVER_NAME "tifm_7xx1" |
17 | #define DRIVER_VERSION "0.7" | 16 | #define DRIVER_VERSION "0.8" |
17 | |||
18 | #define TIFM_IRQ_ENABLE 0x80000000 | ||
19 | #define TIFM_IRQ_SOCKMASK(x) (x) | ||
20 | #define TIFM_IRQ_CARDMASK(x) ((x) << 8) | ||
21 | #define TIFM_IRQ_FIFOMASK(x) ((x) << 16) | ||
22 | #define TIFM_IRQ_SETALL 0xffffffff | ||
23 | |||
24 | static void tifm_7xx1_dummy_eject(struct tifm_adapter *fm, | ||
25 | struct tifm_dev *sock) | ||
26 | { | ||
27 | } | ||
18 | 28 | ||
19 | static void tifm_7xx1_eject(struct tifm_adapter *fm, struct tifm_dev *sock) | 29 | static void tifm_7xx1_eject(struct tifm_adapter *fm, struct tifm_dev *sock) |
20 | { | 30 | { |
@@ -22,7 +32,7 @@ static void tifm_7xx1_eject(struct tifm_adapter *fm, struct tifm_dev *sock) | |||
22 | 32 | ||
23 | spin_lock_irqsave(&fm->lock, flags); | 33 | spin_lock_irqsave(&fm->lock, flags); |
24 | fm->socket_change_set |= 1 << sock->socket_id; | 34 | fm->socket_change_set |= 1 << sock->socket_id; |
25 | wake_up_all(&fm->change_set_notify); | 35 | tifm_queue_work(&fm->media_switcher); |
26 | spin_unlock_irqrestore(&fm->lock, flags); | 36 | spin_unlock_irqrestore(&fm->lock, flags); |
27 | } | 37 | } |
28 | 38 | ||
@@ -30,8 +40,7 @@ static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id) | |||
30 | { | 40 | { |
31 | struct tifm_adapter *fm = dev_id; | 41 | struct tifm_adapter *fm = dev_id; |
32 | struct tifm_dev *sock; | 42 | struct tifm_dev *sock; |
33 | unsigned int irq_status; | 43 | unsigned int irq_status, cnt; |
34 | unsigned int sock_irq_status, cnt; | ||
35 | 44 | ||
36 | spin_lock(&fm->lock); | 45 | spin_lock(&fm->lock); |
37 | irq_status = readl(fm->addr + FM_INTERRUPT_STATUS); | 46 | irq_status = readl(fm->addr + FM_INTERRUPT_STATUS); |
@@ -45,12 +54,12 @@ static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id) | |||
45 | 54 | ||
46 | for (cnt = 0; cnt < fm->num_sockets; cnt++) { | 55 | for (cnt = 0; cnt < fm->num_sockets; cnt++) { |
47 | sock = fm->sockets[cnt]; | 56 | sock = fm->sockets[cnt]; |
48 | sock_irq_status = (irq_status >> cnt) | 57 | if (sock) { |
49 | & (TIFM_IRQ_FIFOMASK(1) | 58 | if ((irq_status >> cnt) & TIFM_IRQ_FIFOMASK(1)) |
50 | | TIFM_IRQ_CARDMASK(1)); | 59 | sock->data_event(sock); |
51 | 60 | if ((irq_status >> cnt) & TIFM_IRQ_CARDMASK(1)) | |
52 | if (sock && sock_irq_status) | 61 | sock->card_event(sock); |
53 | sock->signal_irq(sock, sock_irq_status); | 62 | } |
54 | } | 63 | } |
55 | 64 | ||
56 | fm->socket_change_set |= irq_status | 65 | fm->socket_change_set |= irq_status |
@@ -58,57 +67,57 @@ static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id) | |||
58 | } | 67 | } |
59 | writel(irq_status, fm->addr + FM_INTERRUPT_STATUS); | 68 | writel(irq_status, fm->addr + FM_INTERRUPT_STATUS); |
60 | 69 | ||
61 | if (!fm->socket_change_set) | 70 | if (fm->finish_me) |
71 | complete_all(fm->finish_me); | ||
72 | else if (!fm->socket_change_set) | ||
62 | writel(TIFM_IRQ_ENABLE, fm->addr + FM_SET_INTERRUPT_ENABLE); | 73 | writel(TIFM_IRQ_ENABLE, fm->addr + FM_SET_INTERRUPT_ENABLE); |
63 | else | 74 | else |
64 | wake_up_all(&fm->change_set_notify); | 75 | tifm_queue_work(&fm->media_switcher); |
65 | 76 | ||
66 | spin_unlock(&fm->lock); | 77 | spin_unlock(&fm->lock); |
67 | return IRQ_HANDLED; | 78 | return IRQ_HANDLED; |
68 | } | 79 | } |
69 | 80 | ||
70 | static tifm_media_id tifm_7xx1_toggle_sock_power(char __iomem *sock_addr, | 81 | static unsigned char tifm_7xx1_toggle_sock_power(char __iomem *sock_addr) |
71 | int is_x2) | ||
72 | { | 82 | { |
73 | unsigned int s_state; | 83 | unsigned int s_state; |
74 | int cnt; | 84 | int cnt; |
75 | 85 | ||
76 | writel(0x0e00, sock_addr + SOCK_CONTROL); | 86 | writel(0x0e00, sock_addr + SOCK_CONTROL); |
77 | 87 | ||
78 | for (cnt = 0; cnt < 100; cnt++) { | 88 | for (cnt = 16; cnt <= 256; cnt <<= 1) { |
79 | if (!(TIFM_SOCK_STATE_POWERED | 89 | if (!(TIFM_SOCK_STATE_POWERED |
80 | & readl(sock_addr + SOCK_PRESENT_STATE))) | 90 | & readl(sock_addr + SOCK_PRESENT_STATE))) |
81 | break; | 91 | break; |
82 | msleep(10); | 92 | |
93 | msleep(cnt); | ||
83 | } | 94 | } |
84 | 95 | ||
85 | s_state = readl(sock_addr + SOCK_PRESENT_STATE); | 96 | s_state = readl(sock_addr + SOCK_PRESENT_STATE); |
86 | if (!(TIFM_SOCK_STATE_OCCUPIED & s_state)) | 97 | if (!(TIFM_SOCK_STATE_OCCUPIED & s_state)) |
87 | return FM_NULL; | 98 | return 0; |
88 | |||
89 | if (is_x2) { | ||
90 | writel((s_state & 7) | 0x0c00, sock_addr + SOCK_CONTROL); | ||
91 | } else { | ||
92 | // SmartMedia cards need extra 40 msec | ||
93 | if (((readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7) == 1) | ||
94 | msleep(40); | ||
95 | writel(readl(sock_addr + SOCK_CONTROL) | TIFM_CTRL_LED, | ||
96 | sock_addr + SOCK_CONTROL); | ||
97 | msleep(10); | ||
98 | writel((s_state & 0x7) | 0x0c00 | TIFM_CTRL_LED, | ||
99 | sock_addr + SOCK_CONTROL); | ||
100 | } | ||
101 | 99 | ||
102 | for (cnt = 0; cnt < 100; cnt++) { | 100 | writel(readl(sock_addr + SOCK_CONTROL) | TIFM_CTRL_LED, |
101 | sock_addr + SOCK_CONTROL); | ||
102 | |||
103 | /* xd needs some extra time before power on */ | ||
104 | if (((readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7) | ||
105 | == TIFM_TYPE_XD) | ||
106 | msleep(40); | ||
107 | |||
108 | writel((s_state & 7) | 0x0c00, sock_addr + SOCK_CONTROL); | ||
109 | /* wait for power to stabilize */ | ||
110 | msleep(20); | ||
111 | for (cnt = 16; cnt <= 256; cnt <<= 1) { | ||
103 | if ((TIFM_SOCK_STATE_POWERED | 112 | if ((TIFM_SOCK_STATE_POWERED |
104 | & readl(sock_addr + SOCK_PRESENT_STATE))) | 113 | & readl(sock_addr + SOCK_PRESENT_STATE))) |
105 | break; | 114 | break; |
106 | msleep(10); | 115 | |
116 | msleep(cnt); | ||
107 | } | 117 | } |
108 | 118 | ||
109 | if (!is_x2) | 119 | writel(readl(sock_addr + SOCK_CONTROL) & (~TIFM_CTRL_LED), |
110 | writel(readl(sock_addr + SOCK_CONTROL) & (~TIFM_CTRL_LED), | 120 | sock_addr + SOCK_CONTROL); |
111 | sock_addr + SOCK_CONTROL); | ||
112 | 121 | ||
113 | return (readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7; | 122 | return (readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7; |
114 | } | 123 | } |
@@ -119,127 +128,77 @@ tifm_7xx1_sock_addr(char __iomem *base_addr, unsigned int sock_num) | |||
119 | return base_addr + ((sock_num + 1) << 10); | 128 | return base_addr + ((sock_num + 1) << 10); |
120 | } | 129 | } |
121 | 130 | ||
122 | static int tifm_7xx1_switch_media(void *data) | 131 | static void tifm_7xx1_switch_media(struct work_struct *work) |
123 | { | 132 | { |
124 | struct tifm_adapter *fm = data; | 133 | struct tifm_adapter *fm = container_of(work, struct tifm_adapter, |
125 | unsigned long flags; | 134 | media_switcher); |
126 | tifm_media_id media_id; | ||
127 | char *card_name = "xx"; | ||
128 | int cnt, rc; | ||
129 | struct tifm_dev *sock; | 135 | struct tifm_dev *sock; |
130 | unsigned int socket_change_set; | 136 | unsigned long flags; |
131 | 137 | unsigned char media_id; | |
132 | while (1) { | 138 | unsigned int socket_change_set, cnt; |
133 | rc = wait_event_interruptible(fm->change_set_notify, | ||
134 | fm->socket_change_set); | ||
135 | if (rc == -ERESTARTSYS) | ||
136 | try_to_freeze(); | ||
137 | 139 | ||
138 | spin_lock_irqsave(&fm->lock, flags); | 140 | spin_lock_irqsave(&fm->lock, flags); |
139 | socket_change_set = fm->socket_change_set; | 141 | socket_change_set = fm->socket_change_set; |
140 | fm->socket_change_set = 0; | 142 | fm->socket_change_set = 0; |
141 | 143 | ||
142 | dev_dbg(fm->dev, "checking media set %x\n", | 144 | dev_dbg(fm->cdev.dev, "checking media set %x\n", |
143 | socket_change_set); | 145 | socket_change_set); |
144 | 146 | ||
145 | if (kthread_should_stop()) | 147 | if (!socket_change_set) { |
146 | socket_change_set = (1 << fm->num_sockets) - 1; | ||
147 | spin_unlock_irqrestore(&fm->lock, flags); | 148 | spin_unlock_irqrestore(&fm->lock, flags); |
149 | return; | ||
150 | } | ||
148 | 151 | ||
149 | if (!socket_change_set) | 152 | for (cnt = 0; cnt < fm->num_sockets; cnt++) { |
153 | if (!(socket_change_set & (1 << cnt))) | ||
150 | continue; | 154 | continue; |
151 | 155 | sock = fm->sockets[cnt]; | |
152 | spin_lock_irqsave(&fm->lock, flags); | 156 | if (sock) { |
153 | for (cnt = 0; cnt < fm->num_sockets; cnt++) { | 157 | printk(KERN_INFO |
154 | if (!(socket_change_set & (1 << cnt))) | 158 | "%s : demand removing card from socket %u:%u\n", |
155 | continue; | 159 | fm->cdev.class_id, fm->id, cnt); |
156 | sock = fm->sockets[cnt]; | 160 | fm->sockets[cnt] = NULL; |
157 | if (sock) { | ||
158 | printk(KERN_INFO DRIVER_NAME | ||
159 | ": demand removing card from socket %d\n", | ||
160 | cnt); | ||
161 | fm->sockets[cnt] = NULL; | ||
162 | spin_unlock_irqrestore(&fm->lock, flags); | ||
163 | device_unregister(&sock->dev); | ||
164 | spin_lock_irqsave(&fm->lock, flags); | ||
165 | writel(0x0e00, | ||
166 | tifm_7xx1_sock_addr(fm->addr, cnt) | ||
167 | + SOCK_CONTROL); | ||
168 | } | ||
169 | if (kthread_should_stop()) | ||
170 | continue; | ||
171 | |||
172 | spin_unlock_irqrestore(&fm->lock, flags); | 161 | spin_unlock_irqrestore(&fm->lock, flags); |
173 | media_id = tifm_7xx1_toggle_sock_power( | 162 | device_unregister(&sock->dev); |
174 | tifm_7xx1_sock_addr(fm->addr, cnt), | 163 | spin_lock_irqsave(&fm->lock, flags); |
175 | fm->num_sockets == 2); | 164 | writel(0x0e00, tifm_7xx1_sock_addr(fm->addr, cnt) |
176 | if (media_id) { | 165 | + SOCK_CONTROL); |
177 | sock = tifm_alloc_device(fm); | ||
178 | if (sock) { | ||
179 | sock->addr = tifm_7xx1_sock_addr(fm->addr, | ||
180 | cnt); | ||
181 | sock->media_id = media_id; | ||
182 | sock->socket_id = cnt; | ||
183 | switch (media_id) { | ||
184 | case 1: | ||
185 | card_name = "xd"; | ||
186 | break; | ||
187 | case 2: | ||
188 | card_name = "ms"; | ||
189 | break; | ||
190 | case 3: | ||
191 | card_name = "sd"; | ||
192 | break; | ||
193 | default: | ||
194 | tifm_free_device(&sock->dev); | ||
195 | spin_lock_irqsave(&fm->lock, flags); | ||
196 | continue; | ||
197 | } | ||
198 | snprintf(sock->dev.bus_id, BUS_ID_SIZE, | ||
199 | "tifm_%s%u:%u", card_name, | ||
200 | fm->id, cnt); | ||
201 | printk(KERN_INFO DRIVER_NAME | ||
202 | ": %s card detected in socket %d\n", | ||
203 | card_name, cnt); | ||
204 | if (!device_register(&sock->dev)) { | ||
205 | spin_lock_irqsave(&fm->lock, flags); | ||
206 | if (!fm->sockets[cnt]) { | ||
207 | fm->sockets[cnt] = sock; | ||
208 | sock = NULL; | ||
209 | } | ||
210 | spin_unlock_irqrestore(&fm->lock, flags); | ||
211 | } | ||
212 | if (sock) | ||
213 | tifm_free_device(&sock->dev); | ||
214 | } | ||
215 | spin_lock_irqsave(&fm->lock, flags); | ||
216 | } | ||
217 | } | 166 | } |
218 | 167 | ||
219 | if (!kthread_should_stop()) { | 168 | spin_unlock_irqrestore(&fm->lock, flags); |
220 | writel(TIFM_IRQ_FIFOMASK(socket_change_set) | 169 | |
221 | | TIFM_IRQ_CARDMASK(socket_change_set), | 170 | media_id = tifm_7xx1_toggle_sock_power( |
222 | fm->addr + FM_CLEAR_INTERRUPT_ENABLE); | 171 | tifm_7xx1_sock_addr(fm->addr, cnt)); |
223 | writel(TIFM_IRQ_FIFOMASK(socket_change_set) | 172 | |
224 | | TIFM_IRQ_CARDMASK(socket_change_set), | 173 | // tifm_alloc_device will check if media_id is valid |
225 | fm->addr + FM_SET_INTERRUPT_ENABLE); | 174 | sock = tifm_alloc_device(fm, cnt, media_id); |
226 | writel(TIFM_IRQ_ENABLE, | 175 | if (sock) { |
227 | fm->addr + FM_SET_INTERRUPT_ENABLE); | 176 | sock->addr = tifm_7xx1_sock_addr(fm->addr, cnt); |
228 | spin_unlock_irqrestore(&fm->lock, flags); | 177 | |
229 | } else { | 178 | if (!device_register(&sock->dev)) { |
230 | for (cnt = 0; cnt < fm->num_sockets; cnt++) { | 179 | spin_lock_irqsave(&fm->lock, flags); |
231 | if (fm->sockets[cnt]) | 180 | if (!fm->sockets[cnt]) { |
232 | fm->socket_change_set |= 1 << cnt; | 181 | fm->sockets[cnt] = sock; |
233 | } | 182 | sock = NULL; |
234 | if (!fm->socket_change_set) { | 183 | } |
235 | spin_unlock_irqrestore(&fm->lock, flags); | ||
236 | return 0; | ||
237 | } else { | ||
238 | spin_unlock_irqrestore(&fm->lock, flags); | 184 | spin_unlock_irqrestore(&fm->lock, flags); |
239 | } | 185 | } |
186 | if (sock) | ||
187 | tifm_free_device(&sock->dev); | ||
240 | } | 188 | } |
189 | spin_lock_irqsave(&fm->lock, flags); | ||
241 | } | 190 | } |
242 | return 0; | 191 | |
192 | writel(TIFM_IRQ_FIFOMASK(socket_change_set) | ||
193 | | TIFM_IRQ_CARDMASK(socket_change_set), | ||
194 | fm->addr + FM_CLEAR_INTERRUPT_ENABLE); | ||
195 | |||
196 | writel(TIFM_IRQ_FIFOMASK(socket_change_set) | ||
197 | | TIFM_IRQ_CARDMASK(socket_change_set), | ||
198 | fm->addr + FM_SET_INTERRUPT_ENABLE); | ||
199 | |||
200 | writel(TIFM_IRQ_ENABLE, fm->addr + FM_SET_INTERRUPT_ENABLE); | ||
201 | spin_unlock_irqrestore(&fm->lock, flags); | ||
243 | } | 202 | } |
244 | 203 | ||
245 | #ifdef CONFIG_PM | 204 | #ifdef CONFIG_PM |
@@ -258,9 +217,11 @@ static int tifm_7xx1_suspend(struct pci_dev *dev, pm_message_t state) | |||
258 | static int tifm_7xx1_resume(struct pci_dev *dev) | 217 | static int tifm_7xx1_resume(struct pci_dev *dev) |
259 | { | 218 | { |
260 | struct tifm_adapter *fm = pci_get_drvdata(dev); | 219 | struct tifm_adapter *fm = pci_get_drvdata(dev); |
261 | int cnt, rc; | 220 | int rc; |
221 | unsigned int good_sockets = 0, bad_sockets = 0; | ||
262 | unsigned long flags; | 222 | unsigned long flags; |
263 | tifm_media_id new_ids[fm->num_sockets]; | 223 | unsigned char new_ids[fm->num_sockets]; |
224 | DECLARE_COMPLETION_ONSTACK(finish_resume); | ||
264 | 225 | ||
265 | pci_set_power_state(dev, PCI_D0); | 226 | pci_set_power_state(dev, PCI_D0); |
266 | pci_restore_state(dev); | 227 | pci_restore_state(dev); |
@@ -271,45 +232,49 @@ static int tifm_7xx1_resume(struct pci_dev *dev) | |||
271 | 232 | ||
272 | dev_dbg(&dev->dev, "resuming host\n"); | 233 | dev_dbg(&dev->dev, "resuming host\n"); |
273 | 234 | ||
274 | for (cnt = 0; cnt < fm->num_sockets; cnt++) | 235 | for (rc = 0; rc < fm->num_sockets; rc++) |
275 | new_ids[cnt] = tifm_7xx1_toggle_sock_power( | 236 | new_ids[rc] = tifm_7xx1_toggle_sock_power( |
276 | tifm_7xx1_sock_addr(fm->addr, cnt), | 237 | tifm_7xx1_sock_addr(fm->addr, rc)); |
277 | fm->num_sockets == 2); | ||
278 | spin_lock_irqsave(&fm->lock, flags); | 238 | spin_lock_irqsave(&fm->lock, flags); |
279 | fm->socket_change_set = 0; | 239 | for (rc = 0; rc < fm->num_sockets; rc++) { |
280 | for (cnt = 0; cnt < fm->num_sockets; cnt++) { | 240 | if (fm->sockets[rc]) { |
281 | if (fm->sockets[cnt]) { | 241 | if (fm->sockets[rc]->type == new_ids[rc]) |
282 | if (fm->sockets[cnt]->media_id == new_ids[cnt]) | 242 | good_sockets |= 1 << rc; |
283 | fm->socket_change_set |= 1 << cnt; | 243 | else |
284 | 244 | bad_sockets |= 1 << rc; | |
285 | fm->sockets[cnt]->media_id = new_ids[cnt]; | ||
286 | } | 245 | } |
287 | } | 246 | } |
288 | 247 | ||
289 | writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SOCKMASK((1 << fm->num_sockets) - 1), | 248 | writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SOCKMASK((1 << fm->num_sockets) - 1), |
290 | fm->addr + FM_SET_INTERRUPT_ENABLE); | 249 | fm->addr + FM_SET_INTERRUPT_ENABLE); |
291 | if (!fm->socket_change_set) { | 250 | dev_dbg(&dev->dev, "change sets on resume: good %x, bad %x\n", |
292 | spin_unlock_irqrestore(&fm->lock, flags); | 251 | good_sockets, bad_sockets); |
293 | return 0; | 252 | |
294 | } else { | 253 | fm->socket_change_set = 0; |
295 | fm->socket_change_set = 0; | 254 | if (good_sockets) { |
255 | fm->finish_me = &finish_resume; | ||
296 | spin_unlock_irqrestore(&fm->lock, flags); | 256 | spin_unlock_irqrestore(&fm->lock, flags); |
257 | rc = wait_for_completion_timeout(&finish_resume, HZ); | ||
258 | dev_dbg(&dev->dev, "wait returned %d\n", rc); | ||
259 | writel(TIFM_IRQ_FIFOMASK(good_sockets) | ||
260 | | TIFM_IRQ_CARDMASK(good_sockets), | ||
261 | fm->addr + FM_CLEAR_INTERRUPT_ENABLE); | ||
262 | writel(TIFM_IRQ_FIFOMASK(good_sockets) | ||
263 | | TIFM_IRQ_CARDMASK(good_sockets), | ||
264 | fm->addr + FM_SET_INTERRUPT_ENABLE); | ||
265 | spin_lock_irqsave(&fm->lock, flags); | ||
266 | fm->finish_me = NULL; | ||
267 | fm->socket_change_set ^= good_sockets & fm->socket_change_set; | ||
297 | } | 268 | } |
298 | 269 | ||
299 | wait_event_timeout(fm->change_set_notify, fm->socket_change_set, HZ); | 270 | fm->socket_change_set |= bad_sockets; |
271 | if (fm->socket_change_set) | ||
272 | tifm_queue_work(&fm->media_switcher); | ||
300 | 273 | ||
301 | spin_lock_irqsave(&fm->lock, flags); | 274 | spin_unlock_irqrestore(&fm->lock, flags); |
302 | writel(TIFM_IRQ_FIFOMASK(fm->socket_change_set) | ||
303 | | TIFM_IRQ_CARDMASK(fm->socket_change_set), | ||
304 | fm->addr + FM_CLEAR_INTERRUPT_ENABLE); | ||
305 | writel(TIFM_IRQ_FIFOMASK(fm->socket_change_set) | ||
306 | | TIFM_IRQ_CARDMASK(fm->socket_change_set), | ||
307 | fm->addr + FM_SET_INTERRUPT_ENABLE); | ||
308 | writel(TIFM_IRQ_ENABLE, | 275 | writel(TIFM_IRQ_ENABLE, |
309 | fm->addr + FM_SET_INTERRUPT_ENABLE); | 276 | fm->addr + FM_SET_INTERRUPT_ENABLE); |
310 | fm->socket_change_set = 0; | ||
311 | 277 | ||
312 | spin_unlock_irqrestore(&fm->lock, flags); | ||
313 | return 0; | 278 | return 0; |
314 | } | 279 | } |
315 | 280 | ||
@@ -345,20 +310,14 @@ static int tifm_7xx1_probe(struct pci_dev *dev, | |||
345 | 310 | ||
346 | pci_intx(dev, 1); | 311 | pci_intx(dev, 1); |
347 | 312 | ||
348 | fm = tifm_alloc_adapter(); | 313 | fm = tifm_alloc_adapter(dev->device == PCI_DEVICE_ID_TI_XX21_XX11_FM |
314 | ? 4 : 2, &dev->dev); | ||
349 | if (!fm) { | 315 | if (!fm) { |
350 | rc = -ENOMEM; | 316 | rc = -ENOMEM; |
351 | goto err_out_int; | 317 | goto err_out_int; |
352 | } | 318 | } |
353 | 319 | ||
354 | fm->dev = &dev->dev; | 320 | INIT_WORK(&fm->media_switcher, tifm_7xx1_switch_media); |
355 | fm->num_sockets = (dev->device == PCI_DEVICE_ID_TI_XX21_XX11_FM) | ||
356 | ? 4 : 2; | ||
357 | fm->sockets = kzalloc(sizeof(struct tifm_dev*) * fm->num_sockets, | ||
358 | GFP_KERNEL); | ||
359 | if (!fm->sockets) | ||
360 | goto err_out_free; | ||
361 | |||
362 | fm->eject = tifm_7xx1_eject; | 321 | fm->eject = tifm_7xx1_eject; |
363 | pci_set_drvdata(dev, fm); | 322 | pci_set_drvdata(dev, fm); |
364 | 323 | ||
@@ -367,19 +326,16 @@ static int tifm_7xx1_probe(struct pci_dev *dev, | |||
367 | if (!fm->addr) | 326 | if (!fm->addr) |
368 | goto err_out_free; | 327 | goto err_out_free; |
369 | 328 | ||
370 | rc = request_irq(dev->irq, tifm_7xx1_isr, IRQF_SHARED, DRIVER_NAME, fm); | 329 | rc = request_irq(dev->irq, tifm_7xx1_isr, SA_SHIRQ, DRIVER_NAME, fm); |
371 | if (rc) | 330 | if (rc) |
372 | goto err_out_unmap; | 331 | goto err_out_unmap; |
373 | 332 | ||
374 | init_waitqueue_head(&fm->change_set_notify); | 333 | rc = tifm_add_adapter(fm); |
375 | rc = tifm_add_adapter(fm, tifm_7xx1_switch_media); | ||
376 | if (rc) | 334 | if (rc) |
377 | goto err_out_irq; | 335 | goto err_out_irq; |
378 | 336 | ||
379 | writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE); | ||
380 | writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SOCKMASK((1 << fm->num_sockets) - 1), | 337 | writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SOCKMASK((1 << fm->num_sockets) - 1), |
381 | fm->addr + FM_SET_INTERRUPT_ENABLE); | 338 | fm->addr + FM_SET_INTERRUPT_ENABLE); |
382 | wake_up_process(fm->media_switcher); | ||
383 | return 0; | 339 | return 0; |
384 | 340 | ||
385 | err_out_irq: | 341 | err_out_irq: |
@@ -401,18 +357,12 @@ err_out: | |||
401 | static void tifm_7xx1_remove(struct pci_dev *dev) | 357 | static void tifm_7xx1_remove(struct pci_dev *dev) |
402 | { | 358 | { |
403 | struct tifm_adapter *fm = pci_get_drvdata(dev); | 359 | struct tifm_adapter *fm = pci_get_drvdata(dev); |
404 | unsigned long flags; | ||
405 | 360 | ||
361 | fm->eject = tifm_7xx1_dummy_eject; | ||
406 | writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE); | 362 | writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE); |
407 | mmiowb(); | 363 | mmiowb(); |
408 | free_irq(dev->irq, fm); | 364 | free_irq(dev->irq, fm); |
409 | 365 | ||
410 | spin_lock_irqsave(&fm->lock, flags); | ||
411 | fm->socket_change_set = (1 << fm->num_sockets) - 1; | ||
412 | spin_unlock_irqrestore(&fm->lock, flags); | ||
413 | |||
414 | kthread_stop(fm->media_switcher); | ||
415 | |||
416 | tifm_remove_adapter(fm); | 366 | tifm_remove_adapter(fm); |
417 | 367 | ||
418 | pci_set_drvdata(dev, NULL); | 368 | pci_set_drvdata(dev, NULL); |
diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c index 6b10ebe9d936..d195fb088f4a 100644 --- a/drivers/misc/tifm_core.c +++ b/drivers/misc/tifm_core.c | |||
@@ -14,71 +14,124 @@ | |||
14 | #include <linux/idr.h> | 14 | #include <linux/idr.h> |
15 | 15 | ||
16 | #define DRIVER_NAME "tifm_core" | 16 | #define DRIVER_NAME "tifm_core" |
17 | #define DRIVER_VERSION "0.7" | 17 | #define DRIVER_VERSION "0.8" |
18 | 18 | ||
19 | static struct workqueue_struct *workqueue; | ||
19 | static DEFINE_IDR(tifm_adapter_idr); | 20 | static DEFINE_IDR(tifm_adapter_idr); |
20 | static DEFINE_SPINLOCK(tifm_adapter_lock); | 21 | static DEFINE_SPINLOCK(tifm_adapter_lock); |
21 | 22 | ||
22 | static tifm_media_id *tifm_device_match(tifm_media_id *ids, | 23 | static const char *tifm_media_type_name(unsigned char type, unsigned char nt) |
23 | struct tifm_dev *dev) | ||
24 | { | 24 | { |
25 | while (*ids) { | 25 | const char *card_type_name[3][3] = { |
26 | if (dev->media_id == *ids) | 26 | { "SmartMedia/xD", "MemoryStick", "MMC/SD" }, |
27 | return ids; | 27 | { "XD", "MS", "SD"}, |
28 | ids++; | 28 | { "xd", "ms", "sd"} |
29 | } | 29 | }; |
30 | return NULL; | 30 | |
31 | if (nt > 2 || type < 1 || type > 3) | ||
32 | return NULL; | ||
33 | return card_type_name[nt][type - 1]; | ||
31 | } | 34 | } |
32 | 35 | ||
33 | static int tifm_match(struct device *dev, struct device_driver *drv) | 36 | static int tifm_dev_match(struct tifm_dev *sock, struct tifm_device_id *id) |
34 | { | 37 | { |
35 | struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev); | 38 | if (sock->type == id->type) |
36 | struct tifm_driver *fm_drv; | ||
37 | |||
38 | fm_drv = container_of(drv, struct tifm_driver, driver); | ||
39 | if (!fm_drv->id_table) | ||
40 | return -EINVAL; | ||
41 | if (tifm_device_match(fm_drv->id_table, fm_dev)) | ||
42 | return 1; | 39 | return 1; |
43 | return -ENODEV; | 40 | return 0; |
41 | } | ||
42 | |||
43 | static int tifm_bus_match(struct device *dev, struct device_driver *drv) | ||
44 | { | ||
45 | struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev); | ||
46 | struct tifm_driver *fm_drv = container_of(drv, struct tifm_driver, | ||
47 | driver); | ||
48 | struct tifm_device_id *ids = fm_drv->id_table; | ||
49 | |||
50 | if (ids) { | ||
51 | while (ids->type) { | ||
52 | if (tifm_dev_match(sock, ids)) | ||
53 | return 1; | ||
54 | ++ids; | ||
55 | } | ||
56 | } | ||
57 | return 0; | ||
44 | } | 58 | } |
45 | 59 | ||
46 | static int tifm_uevent(struct device *dev, char **envp, int num_envp, | 60 | static int tifm_uevent(struct device *dev, char **envp, int num_envp, |
47 | char *buffer, int buffer_size) | 61 | char *buffer, int buffer_size) |
48 | { | 62 | { |
49 | struct tifm_dev *fm_dev; | 63 | struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev); |
50 | int i = 0; | 64 | int i = 0; |
51 | int length = 0; | 65 | int length = 0; |
52 | const char *card_type_name[] = {"INV", "SM", "MS", "SD"}; | ||
53 | 66 | ||
54 | if (!dev || !(fm_dev = container_of(dev, struct tifm_dev, dev))) | ||
55 | return -ENODEV; | ||
56 | if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, | 67 | if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, |
57 | "TIFM_CARD_TYPE=%s", card_type_name[fm_dev->media_id])) | 68 | "TIFM_CARD_TYPE=%s", |
69 | tifm_media_type_name(sock->type, 1))) | ||
58 | return -ENOMEM; | 70 | return -ENOMEM; |
59 | 71 | ||
60 | return 0; | 72 | return 0; |
61 | } | 73 | } |
62 | 74 | ||
75 | static int tifm_device_probe(struct device *dev) | ||
76 | { | ||
77 | struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev); | ||
78 | struct tifm_driver *drv = container_of(dev->driver, struct tifm_driver, | ||
79 | driver); | ||
80 | int rc = -ENODEV; | ||
81 | |||
82 | get_device(dev); | ||
83 | if (dev->driver && drv->probe) { | ||
84 | rc = drv->probe(sock); | ||
85 | if (!rc) | ||
86 | return 0; | ||
87 | } | ||
88 | put_device(dev); | ||
89 | return rc; | ||
90 | } | ||
91 | |||
92 | static void tifm_dummy_event(struct tifm_dev *sock) | ||
93 | { | ||
94 | return; | ||
95 | } | ||
96 | |||
97 | static int tifm_device_remove(struct device *dev) | ||
98 | { | ||
99 | struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev); | ||
100 | struct tifm_driver *drv = container_of(dev->driver, struct tifm_driver, | ||
101 | driver); | ||
102 | |||
103 | if (dev->driver && drv->remove) { | ||
104 | sock->card_event = tifm_dummy_event; | ||
105 | sock->data_event = tifm_dummy_event; | ||
106 | drv->remove(sock); | ||
107 | sock->dev.driver = NULL; | ||
108 | } | ||
109 | |||
110 | put_device(dev); | ||
111 | return 0; | ||
112 | } | ||
113 | |||
63 | #ifdef CONFIG_PM | 114 | #ifdef CONFIG_PM |
64 | 115 | ||
65 | static int tifm_device_suspend(struct device *dev, pm_message_t state) | 116 | static int tifm_device_suspend(struct device *dev, pm_message_t state) |
66 | { | 117 | { |
67 | struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev); | 118 | struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev); |
68 | struct tifm_driver *drv = fm_dev->drv; | 119 | struct tifm_driver *drv = container_of(dev->driver, struct tifm_driver, |
120 | driver); | ||
69 | 121 | ||
70 | if (drv && drv->suspend) | 122 | if (dev->driver && drv->suspend) |
71 | return drv->suspend(fm_dev, state); | 123 | return drv->suspend(sock, state); |
72 | return 0; | 124 | return 0; |
73 | } | 125 | } |
74 | 126 | ||
75 | static int tifm_device_resume(struct device *dev) | 127 | static int tifm_device_resume(struct device *dev) |
76 | { | 128 | { |
77 | struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev); | 129 | struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev); |
78 | struct tifm_driver *drv = fm_dev->drv; | 130 | struct tifm_driver *drv = container_of(dev->driver, struct tifm_driver, |
131 | driver); | ||
79 | 132 | ||
80 | if (drv && drv->resume) | 133 | if (dev->driver && drv->resume) |
81 | return drv->resume(fm_dev); | 134 | return drv->resume(sock); |
82 | return 0; | 135 | return 0; |
83 | } | 136 | } |
84 | 137 | ||
@@ -89,19 +142,33 @@ static int tifm_device_resume(struct device *dev) | |||
89 | 142 | ||
90 | #endif /* CONFIG_PM */ | 143 | #endif /* CONFIG_PM */ |
91 | 144 | ||
145 | static ssize_t type_show(struct device *dev, struct device_attribute *attr, | ||
146 | char *buf) | ||
147 | { | ||
148 | struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev); | ||
149 | return sprintf(buf, "%x", sock->type); | ||
150 | } | ||
151 | |||
152 | static struct device_attribute tifm_dev_attrs[] = { | ||
153 | __ATTR(type, S_IRUGO, type_show, NULL), | ||
154 | __ATTR_NULL | ||
155 | }; | ||
156 | |||
92 | static struct bus_type tifm_bus_type = { | 157 | static struct bus_type tifm_bus_type = { |
93 | .name = "tifm", | 158 | .name = "tifm", |
94 | .match = tifm_match, | 159 | .dev_attrs = tifm_dev_attrs, |
95 | .uevent = tifm_uevent, | 160 | .match = tifm_bus_match, |
96 | .suspend = tifm_device_suspend, | 161 | .uevent = tifm_uevent, |
97 | .resume = tifm_device_resume | 162 | .probe = tifm_device_probe, |
163 | .remove = tifm_device_remove, | ||
164 | .suspend = tifm_device_suspend, | ||
165 | .resume = tifm_device_resume | ||
98 | }; | 166 | }; |
99 | 167 | ||
100 | static void tifm_free(struct class_device *cdev) | 168 | static void tifm_free(struct class_device *cdev) |
101 | { | 169 | { |
102 | struct tifm_adapter *fm = container_of(cdev, struct tifm_adapter, cdev); | 170 | struct tifm_adapter *fm = container_of(cdev, struct tifm_adapter, cdev); |
103 | 171 | ||
104 | kfree(fm->sockets); | ||
105 | kfree(fm); | 172 | kfree(fm); |
106 | } | 173 | } |
107 | 174 | ||
@@ -110,28 +177,25 @@ static struct class tifm_adapter_class = { | |||
110 | .release = tifm_free | 177 | .release = tifm_free |
111 | }; | 178 | }; |
112 | 179 | ||
113 | struct tifm_adapter *tifm_alloc_adapter(void) | 180 | struct tifm_adapter *tifm_alloc_adapter(unsigned int num_sockets, |
181 | struct device *dev) | ||
114 | { | 182 | { |
115 | struct tifm_adapter *fm; | 183 | struct tifm_adapter *fm; |
116 | 184 | ||
117 | fm = kzalloc(sizeof(struct tifm_adapter), GFP_KERNEL); | 185 | fm = kzalloc(sizeof(struct tifm_adapter) |
186 | + sizeof(struct tifm_dev*) * num_sockets, GFP_KERNEL); | ||
118 | if (fm) { | 187 | if (fm) { |
119 | fm->cdev.class = &tifm_adapter_class; | 188 | fm->cdev.class = &tifm_adapter_class; |
120 | spin_lock_init(&fm->lock); | 189 | fm->cdev.dev = dev; |
121 | class_device_initialize(&fm->cdev); | 190 | class_device_initialize(&fm->cdev); |
191 | spin_lock_init(&fm->lock); | ||
192 | fm->num_sockets = num_sockets; | ||
122 | } | 193 | } |
123 | return fm; | 194 | return fm; |
124 | } | 195 | } |
125 | EXPORT_SYMBOL(tifm_alloc_adapter); | 196 | EXPORT_SYMBOL(tifm_alloc_adapter); |
126 | 197 | ||
127 | void tifm_free_adapter(struct tifm_adapter *fm) | 198 | int tifm_add_adapter(struct tifm_adapter *fm) |
128 | { | ||
129 | class_device_put(&fm->cdev); | ||
130 | } | ||
131 | EXPORT_SYMBOL(tifm_free_adapter); | ||
132 | |||
133 | int tifm_add_adapter(struct tifm_adapter *fm, | ||
134 | int (*mediathreadfn)(void *data)) | ||
135 | { | 199 | { |
136 | int rc; | 200 | int rc; |
137 | 201 | ||
@@ -141,59 +205,80 @@ int tifm_add_adapter(struct tifm_adapter *fm, | |||
141 | spin_lock(&tifm_adapter_lock); | 205 | spin_lock(&tifm_adapter_lock); |
142 | rc = idr_get_new(&tifm_adapter_idr, fm, &fm->id); | 206 | rc = idr_get_new(&tifm_adapter_idr, fm, &fm->id); |
143 | spin_unlock(&tifm_adapter_lock); | 207 | spin_unlock(&tifm_adapter_lock); |
144 | if (!rc) { | 208 | if (rc) |
145 | snprintf(fm->cdev.class_id, BUS_ID_SIZE, "tifm%u", fm->id); | 209 | return rc; |
146 | fm->media_switcher = kthread_create(mediathreadfn, | ||
147 | fm, "tifm/%u", fm->id); | ||
148 | |||
149 | if (!IS_ERR(fm->media_switcher)) | ||
150 | return class_device_add(&fm->cdev); | ||
151 | 210 | ||
211 | snprintf(fm->cdev.class_id, BUS_ID_SIZE, "tifm%u", fm->id); | ||
212 | rc = class_device_add(&fm->cdev); | ||
213 | if (rc) { | ||
152 | spin_lock(&tifm_adapter_lock); | 214 | spin_lock(&tifm_adapter_lock); |
153 | idr_remove(&tifm_adapter_idr, fm->id); | 215 | idr_remove(&tifm_adapter_idr, fm->id); |
154 | spin_unlock(&tifm_adapter_lock); | 216 | spin_unlock(&tifm_adapter_lock); |
155 | rc = -ENOMEM; | ||
156 | } | 217 | } |
218 | |||
157 | return rc; | 219 | return rc; |
158 | } | 220 | } |
159 | EXPORT_SYMBOL(tifm_add_adapter); | 221 | EXPORT_SYMBOL(tifm_add_adapter); |
160 | 222 | ||
161 | void tifm_remove_adapter(struct tifm_adapter *fm) | 223 | void tifm_remove_adapter(struct tifm_adapter *fm) |
162 | { | 224 | { |
163 | class_device_del(&fm->cdev); | 225 | unsigned int cnt; |
226 | |||
227 | flush_workqueue(workqueue); | ||
228 | for (cnt = 0; cnt < fm->num_sockets; ++cnt) { | ||
229 | if (fm->sockets[cnt]) | ||
230 | device_unregister(&fm->sockets[cnt]->dev); | ||
231 | } | ||
164 | 232 | ||
165 | spin_lock(&tifm_adapter_lock); | 233 | spin_lock(&tifm_adapter_lock); |
166 | idr_remove(&tifm_adapter_idr, fm->id); | 234 | idr_remove(&tifm_adapter_idr, fm->id); |
167 | spin_unlock(&tifm_adapter_lock); | 235 | spin_unlock(&tifm_adapter_lock); |
236 | class_device_del(&fm->cdev); | ||
168 | } | 237 | } |
169 | EXPORT_SYMBOL(tifm_remove_adapter); | 238 | EXPORT_SYMBOL(tifm_remove_adapter); |
170 | 239 | ||
171 | void tifm_free_device(struct device *dev) | 240 | void tifm_free_adapter(struct tifm_adapter *fm) |
172 | { | 241 | { |
173 | struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev); | 242 | class_device_put(&fm->cdev); |
174 | kfree(fm_dev); | ||
175 | } | 243 | } |
176 | EXPORT_SYMBOL(tifm_free_device); | 244 | EXPORT_SYMBOL(tifm_free_adapter); |
177 | 245 | ||
178 | static void tifm_dummy_signal_irq(struct tifm_dev *sock, | 246 | void tifm_free_device(struct device *dev) |
179 | unsigned int sock_irq_status) | ||
180 | { | 247 | { |
181 | return; | 248 | struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev); |
249 | kfree(sock); | ||
182 | } | 250 | } |
251 | EXPORT_SYMBOL(tifm_free_device); | ||
183 | 252 | ||
184 | struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm) | 253 | struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id, |
254 | unsigned char type) | ||
185 | { | 255 | { |
186 | struct tifm_dev *dev = kzalloc(sizeof(struct tifm_dev), GFP_KERNEL); | 256 | struct tifm_dev *sock = NULL; |
187 | 257 | ||
188 | if (dev) { | 258 | if (!tifm_media_type_name(type, 0)) |
189 | spin_lock_init(&dev->lock); | 259 | return sock; |
190 | 260 | ||
191 | dev->dev.parent = fm->dev; | 261 | sock = kzalloc(sizeof(struct tifm_dev), GFP_KERNEL); |
192 | dev->dev.bus = &tifm_bus_type; | 262 | if (sock) { |
193 | dev->dev.release = tifm_free_device; | 263 | spin_lock_init(&sock->lock); |
194 | dev->signal_irq = tifm_dummy_signal_irq; | 264 | sock->type = type; |
265 | sock->socket_id = id; | ||
266 | sock->card_event = tifm_dummy_event; | ||
267 | sock->data_event = tifm_dummy_event; | ||
268 | |||
269 | sock->dev.parent = fm->cdev.dev; | ||
270 | sock->dev.bus = &tifm_bus_type; | ||
271 | sock->dev.dma_mask = fm->cdev.dev->dma_mask; | ||
272 | sock->dev.release = tifm_free_device; | ||
273 | |||
274 | snprintf(sock->dev.bus_id, BUS_ID_SIZE, | ||
275 | "tifm_%s%u:%u", tifm_media_type_name(type, 2), | ||
276 | fm->id, id); | ||
277 | printk(KERN_INFO DRIVER_NAME | ||
278 | ": %s card detected in socket %u:%u\n", | ||
279 | tifm_media_type_name(type, 0), fm->id, id); | ||
195 | } | 280 | } |
196 | return dev; | 281 | return sock; |
197 | } | 282 | } |
198 | EXPORT_SYMBOL(tifm_alloc_device); | 283 | EXPORT_SYMBOL(tifm_alloc_device); |
199 | 284 | ||
@@ -218,54 +303,15 @@ void tifm_unmap_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents, | |||
218 | } | 303 | } |
219 | EXPORT_SYMBOL(tifm_unmap_sg); | 304 | EXPORT_SYMBOL(tifm_unmap_sg); |
220 | 305 | ||
221 | static int tifm_device_probe(struct device *dev) | 306 | void tifm_queue_work(struct work_struct *work) |
222 | { | ||
223 | struct tifm_driver *drv; | ||
224 | struct tifm_dev *fm_dev; | ||
225 | int rc = 0; | ||
226 | const tifm_media_id *id; | ||
227 | |||
228 | drv = container_of(dev->driver, struct tifm_driver, driver); | ||
229 | fm_dev = container_of(dev, struct tifm_dev, dev); | ||
230 | get_device(dev); | ||
231 | if (!fm_dev->drv && drv->probe && drv->id_table) { | ||
232 | rc = -ENODEV; | ||
233 | id = tifm_device_match(drv->id_table, fm_dev); | ||
234 | if (id) | ||
235 | rc = drv->probe(fm_dev); | ||
236 | if (rc >= 0) { | ||
237 | rc = 0; | ||
238 | fm_dev->drv = drv; | ||
239 | } | ||
240 | } | ||
241 | if (rc) | ||
242 | put_device(dev); | ||
243 | return rc; | ||
244 | } | ||
245 | |||
246 | static int tifm_device_remove(struct device *dev) | ||
247 | { | 307 | { |
248 | struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev); | 308 | queue_work(workqueue, work); |
249 | struct tifm_driver *drv = fm_dev->drv; | ||
250 | |||
251 | if (drv) { | ||
252 | fm_dev->signal_irq = tifm_dummy_signal_irq; | ||
253 | if (drv->remove) | ||
254 | drv->remove(fm_dev); | ||
255 | fm_dev->drv = NULL; | ||
256 | } | ||
257 | |||
258 | put_device(dev); | ||
259 | return 0; | ||
260 | } | 309 | } |
310 | EXPORT_SYMBOL(tifm_queue_work); | ||
261 | 311 | ||
262 | int tifm_register_driver(struct tifm_driver *drv) | 312 | int tifm_register_driver(struct tifm_driver *drv) |
263 | { | 313 | { |
264 | drv->driver.bus = &tifm_bus_type; | 314 | drv->driver.bus = &tifm_bus_type; |
265 | drv->driver.probe = tifm_device_probe; | ||
266 | drv->driver.remove = tifm_device_remove; | ||
267 | drv->driver.suspend = tifm_device_suspend; | ||
268 | drv->driver.resume = tifm_device_resume; | ||
269 | 315 | ||
270 | return driver_register(&drv->driver); | 316 | return driver_register(&drv->driver); |
271 | } | 317 | } |
@@ -279,13 +325,25 @@ EXPORT_SYMBOL(tifm_unregister_driver); | |||
279 | 325 | ||
280 | static int __init tifm_init(void) | 326 | static int __init tifm_init(void) |
281 | { | 327 | { |
282 | int rc = bus_register(&tifm_bus_type); | 328 | int rc; |
283 | 329 | ||
284 | if (!rc) { | 330 | workqueue = create_freezeable_workqueue("tifm"); |
285 | rc = class_register(&tifm_adapter_class); | 331 | if (!workqueue) |
286 | if (rc) | 332 | return -ENOMEM; |
287 | bus_unregister(&tifm_bus_type); | 333 | |
288 | } | 334 | rc = bus_register(&tifm_bus_type); |
335 | |||
336 | if (rc) | ||
337 | goto err_out_wq; | ||
338 | |||
339 | rc = class_register(&tifm_adapter_class); | ||
340 | if (!rc) | ||
341 | return 0; | ||
342 | |||
343 | bus_unregister(&tifm_bus_type); | ||
344 | |||
345 | err_out_wq: | ||
346 | destroy_workqueue(workqueue); | ||
289 | 347 | ||
290 | return rc; | 348 | return rc; |
291 | } | 349 | } |
@@ -294,6 +352,7 @@ static void __exit tifm_exit(void) | |||
294 | { | 352 | { |
295 | class_unregister(&tifm_adapter_class); | 353 | class_unregister(&tifm_adapter_class); |
296 | bus_unregister(&tifm_bus_type); | 354 | bus_unregister(&tifm_bus_type); |
355 | destroy_workqueue(workqueue); | ||
297 | } | 356 | } |
298 | 357 | ||
299 | subsys_initcall(tifm_init); | 358 | subsys_initcall(tifm_init); |
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 12af9c718764..6c97491543db 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig | |||
@@ -19,110 +19,10 @@ config MMC_DEBUG | |||
19 | This is an option for use by developers; most people should | 19 | This is an option for use by developers; most people should |
20 | say N here. This enables MMC core and driver debugging. | 20 | say N here. This enables MMC core and driver debugging. |
21 | 21 | ||
22 | config MMC_BLOCK | 22 | source "drivers/mmc/core/Kconfig" |
23 | tristate "MMC block device driver" | ||
24 | depends on MMC && BLOCK | ||
25 | default y | ||
26 | help | ||
27 | Say Y here to enable the MMC block device driver support. | ||
28 | This provides a block device driver, which you can use to | ||
29 | mount the filesystem. Almost everyone wishing MMC support | ||
30 | should say Y or M here. | ||
31 | |||
32 | config MMC_ARMMMCI | ||
33 | tristate "ARM AMBA Multimedia Card Interface support" | ||
34 | depends on ARM_AMBA && MMC | ||
35 | help | ||
36 | This selects the ARM(R) AMBA(R) PrimeCell Multimedia Card | ||
37 | Interface (PL180 and PL181) support. If you have an ARM(R) | ||
38 | platform with a Multimedia Card slot, say Y or M here. | ||
39 | |||
40 | If unsure, say N. | ||
41 | |||
42 | config MMC_PXA | ||
43 | tristate "Intel PXA25x/26x/27x Multimedia Card Interface support" | ||
44 | depends on ARCH_PXA && MMC | ||
45 | help | ||
46 | This selects the Intel(R) PXA(R) Multimedia card Interface. | ||
47 | If you have a PXA(R) platform with a Multimedia Card slot, | ||
48 | say Y or M here. | ||
49 | |||
50 | If unsure, say N. | ||
51 | |||
52 | config MMC_SDHCI | ||
53 | tristate "Secure Digital Host Controller Interface support (EXPERIMENTAL)" | ||
54 | depends on PCI && MMC && EXPERIMENTAL | ||
55 | help | ||
56 | This select the generic Secure Digital Host Controller Interface. | ||
57 | It is used by manufacturers such as Texas Instruments(R), Ricoh(R) | ||
58 | and Toshiba(R). Most controllers found in laptops are of this type. | ||
59 | If you have a controller with this interface, say Y or M here. | ||
60 | |||
61 | If unsure, say N. | ||
62 | |||
63 | config MMC_OMAP | ||
64 | tristate "TI OMAP Multimedia Card Interface support" | ||
65 | depends on ARCH_OMAP && MMC | ||
66 | select TPS65010 if MACH_OMAP_H2 | ||
67 | help | ||
68 | This selects the TI OMAP Multimedia card Interface. | ||
69 | If you have an OMAP board with a Multimedia Card slot, | ||
70 | say Y or M here. | ||
71 | |||
72 | If unsure, say N. | ||
73 | 23 | ||
74 | config MMC_WBSD | 24 | source "drivers/mmc/card/Kconfig" |
75 | tristate "Winbond W83L51xD SD/MMC Card Interface support" | ||
76 | depends on MMC && ISA_DMA_API | ||
77 | help | ||
78 | This selects the Winbond(R) W83L51xD Secure digital and | ||
79 | Multimedia card Interface. | ||
80 | If you have a machine with a integrated W83L518D or W83L519D | ||
81 | SD/MMC card reader, say Y or M here. | ||
82 | |||
83 | If unsure, say N. | ||
84 | |||
85 | config MMC_AU1X | ||
86 | tristate "Alchemy AU1XX0 MMC Card Interface support" | ||
87 | depends on MMC && SOC_AU1200 | ||
88 | help | ||
89 | This selects the AMD Alchemy(R) Multimedia card interface. | ||
90 | If you have a Alchemy platform with a MMC slot, say Y or M here. | ||
91 | |||
92 | If unsure, say N. | ||
93 | |||
94 | config MMC_AT91 | ||
95 | tristate "AT91 SD/MMC Card Interface support" | ||
96 | depends on ARCH_AT91 && MMC | ||
97 | help | ||
98 | This selects the AT91 MCI controller. | ||
99 | |||
100 | If unsure, say N. | ||
101 | |||
102 | config MMC_IMX | ||
103 | tristate "Motorola i.MX Multimedia Card Interface support" | ||
104 | depends on ARCH_IMX && MMC | ||
105 | help | ||
106 | This selects the Motorola i.MX Multimedia card Interface. | ||
107 | If you have a i.MX platform with a Multimedia Card slot, | ||
108 | say Y or M here. | ||
109 | |||
110 | If unsure, say N. | ||
111 | |||
112 | config MMC_TIFM_SD | ||
113 | tristate "TI Flash Media MMC/SD Interface support (EXPERIMENTAL)" | ||
114 | depends on MMC && EXPERIMENTAL && PCI | ||
115 | select TIFM_CORE | ||
116 | help | ||
117 | Say Y here if you want to be able to access MMC/SD cards with | ||
118 | the Texas Instruments(R) Flash Media card reader, found in many | ||
119 | laptops. | ||
120 | This option 'selects' (turns on, enables) 'TIFM_CORE', but you | ||
121 | probably also need appropriate card reader host adapter, such as | ||
122 | 'Misc devices: TI Flash Media PCI74xx/PCI76xx host adapter support | ||
123 | (TIFM_7XX1)'. | ||
124 | 25 | ||
125 | To compile this driver as a module, choose M here: the | 26 | source "drivers/mmc/host/Kconfig" |
126 | module will be called tifm_sd. | ||
127 | 27 | ||
128 | endmenu | 28 | endmenu |
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 83ffb9326a54..9979f5e9765b 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile | |||
@@ -2,32 +2,11 @@ | |||
2 | # Makefile for the kernel mmc device drivers. | 2 | # Makefile for the kernel mmc device drivers. |
3 | # | 3 | # |
4 | 4 | ||
5 | # | ||
6 | # Core | ||
7 | # | ||
8 | obj-$(CONFIG_MMC) += mmc_core.o | ||
9 | |||
10 | # | ||
11 | # Media drivers | ||
12 | # | ||
13 | obj-$(CONFIG_MMC_BLOCK) += mmc_block.o | ||
14 | |||
15 | # | ||
16 | # Host drivers | ||
17 | # | ||
18 | obj-$(CONFIG_MMC_ARMMMCI) += mmci.o | ||
19 | obj-$(CONFIG_MMC_PXA) += pxamci.o | ||
20 | obj-$(CONFIG_MMC_IMX) += imxmmc.o | ||
21 | obj-$(CONFIG_MMC_SDHCI) += sdhci.o | ||
22 | obj-$(CONFIG_MMC_WBSD) += wbsd.o | ||
23 | obj-$(CONFIG_MMC_AU1X) += au1xmmc.o | ||
24 | obj-$(CONFIG_MMC_OMAP) += omap.o | ||
25 | obj-$(CONFIG_MMC_AT91) += at91_mci.o | ||
26 | obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o | ||
27 | |||
28 | mmc_core-y := mmc.o mmc_sysfs.o | ||
29 | mmc_core-$(CONFIG_BLOCK) += mmc_queue.o | ||
30 | |||
31 | ifeq ($(CONFIG_MMC_DEBUG),y) | 5 | ifeq ($(CONFIG_MMC_DEBUG),y) |
32 | EXTRA_CFLAGS += -DDEBUG | 6 | EXTRA_CFLAGS += -DDEBUG |
33 | endif | 7 | endif |
8 | |||
9 | obj-$(CONFIG_MMC) += core/ | ||
10 | obj-$(CONFIG_MMC) += card/ | ||
11 | obj-$(CONFIG_MMC) += host/ | ||
12 | |||
diff --git a/drivers/mmc/card/Kconfig b/drivers/mmc/card/Kconfig new file mode 100644 index 000000000000..01a9fd376a1f --- /dev/null +++ b/drivers/mmc/card/Kconfig | |||
@@ -0,0 +1,17 @@ | |||
1 | # | ||
2 | # MMC/SD card drivers | ||
3 | # | ||
4 | |||
5 | comment "MMC/SD Card Drivers" | ||
6 | depends MMC | ||
7 | |||
8 | config MMC_BLOCK | ||
9 | tristate "MMC block device driver" | ||
10 | depends on MMC && BLOCK | ||
11 | default y | ||
12 | help | ||
13 | Say Y here to enable the MMC block device driver support. | ||
14 | This provides a block device driver, which you can use to | ||
15 | mount the filesystem. Almost everyone wishing MMC support | ||
16 | should say Y or M here. | ||
17 | |||
diff --git a/drivers/mmc/card/Makefile b/drivers/mmc/card/Makefile new file mode 100644 index 000000000000..cf8c939867f5 --- /dev/null +++ b/drivers/mmc/card/Makefile | |||
@@ -0,0 +1,11 @@ | |||
1 | # | ||
2 | # Makefile for MMC/SD card drivers | ||
3 | # | ||
4 | |||
5 | ifeq ($(CONFIG_MMC_DEBUG),y) | ||
6 | EXTRA_CFLAGS += -DDEBUG | ||
7 | endif | ||
8 | |||
9 | obj-$(CONFIG_MMC_BLOCK) += mmc_block.o | ||
10 | mmc_block-objs := block.o queue.o | ||
11 | |||
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/card/block.c index 86439a0bb271..d24ab234394c 100644 --- a/drivers/mmc/mmc_block.c +++ b/drivers/mmc/card/block.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * Block driver for media (i.e., flash cards) | 2 | * Block driver for media (i.e., flash cards) |
3 | * | 3 | * |
4 | * Copyright 2002 Hewlett-Packard Company | 4 | * Copyright 2002 Hewlett-Packard Company |
5 | * Copyright 2005-2007 Pierre Ossman | ||
5 | * | 6 | * |
6 | * Use consistent with the GNU GPL is permitted, | 7 | * Use consistent with the GNU GPL is permitted, |
7 | * provided that this copyright notice is | 8 | * provided that this copyright notice is |
@@ -31,13 +32,13 @@ | |||
31 | 32 | ||
32 | #include <linux/mmc/card.h> | 33 | #include <linux/mmc/card.h> |
33 | #include <linux/mmc/host.h> | 34 | #include <linux/mmc/host.h> |
34 | #include <linux/mmc/protocol.h> | 35 | #include <linux/mmc/mmc.h> |
35 | #include <linux/mmc/host.h> | 36 | #include <linux/mmc/sd.h> |
36 | 37 | ||
37 | #include <asm/system.h> | 38 | #include <asm/system.h> |
38 | #include <asm/uaccess.h> | 39 | #include <asm/uaccess.h> |
39 | 40 | ||
40 | #include "mmc_queue.h" | 41 | #include "queue.h" |
41 | 42 | ||
42 | /* | 43 | /* |
43 | * max 8 partitions per card | 44 | * max 8 partitions per card |
@@ -223,10 +224,9 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
223 | struct mmc_blk_data *md = mq->data; | 224 | struct mmc_blk_data *md = mq->data; |
224 | struct mmc_card *card = md->queue.card; | 225 | struct mmc_card *card = md->queue.card; |
225 | struct mmc_blk_request brq; | 226 | struct mmc_blk_request brq; |
226 | int ret = 1; | 227 | int ret = 1, sg_pos, data_size; |
227 | 228 | ||
228 | if (mmc_card_claim_host(card)) | 229 | mmc_claim_host(card->host); |
229 | goto flush_queue; | ||
230 | 230 | ||
231 | do { | 231 | do { |
232 | struct mmc_command cmd; | 232 | struct mmc_command cmd; |
@@ -283,6 +283,20 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
283 | brq.data.sg = mq->sg; | 283 | brq.data.sg = mq->sg; |
284 | brq.data.sg_len = blk_rq_map_sg(req->q, req, brq.data.sg); | 284 | brq.data.sg_len = blk_rq_map_sg(req->q, req, brq.data.sg); |
285 | 285 | ||
286 | if (brq.data.blocks != | ||
287 | (req->nr_sectors >> (md->block_bits - 9))) { | ||
288 | data_size = brq.data.blocks * brq.data.blksz; | ||
289 | for (sg_pos = 0; sg_pos < brq.data.sg_len; sg_pos++) { | ||
290 | data_size -= mq->sg[sg_pos].length; | ||
291 | if (data_size <= 0) { | ||
292 | mq->sg[sg_pos].length += data_size; | ||
293 | sg_pos++; | ||
294 | break; | ||
295 | } | ||
296 | } | ||
297 | brq.data.sg_len = sg_pos; | ||
298 | } | ||
299 | |||
286 | mmc_wait_for_req(card->host, &brq.mrq); | 300 | mmc_wait_for_req(card->host, &brq.mrq); |
287 | if (brq.cmd.error) { | 301 | if (brq.cmd.error) { |
288 | printk(KERN_ERR "%s: error %d sending read/write command\n", | 302 | printk(KERN_ERR "%s: error %d sending read/write command\n", |
@@ -342,7 +356,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
342 | spin_unlock_irq(&md->lock); | 356 | spin_unlock_irq(&md->lock); |
343 | } while (ret); | 357 | } while (ret); |
344 | 358 | ||
345 | mmc_card_release_host(card); | 359 | mmc_release_host(card->host); |
346 | 360 | ||
347 | return 1; | 361 | return 1; |
348 | 362 | ||
@@ -378,9 +392,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
378 | spin_unlock_irq(&md->lock); | 392 | spin_unlock_irq(&md->lock); |
379 | } | 393 | } |
380 | 394 | ||
381 | flush_queue: | 395 | mmc_release_host(card->host); |
382 | |||
383 | mmc_card_release_host(card); | ||
384 | 396 | ||
385 | spin_lock_irq(&md->lock); | 397 | spin_lock_irq(&md->lock); |
386 | while (ret) { | 398 | while (ret) { |
@@ -477,11 +489,20 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) | |||
477 | 489 | ||
478 | blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits); | 490 | blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits); |
479 | 491 | ||
480 | /* | 492 | if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { |
481 | * The CSD capacity field is in units of read_blkbits. | 493 | /* |
482 | * set_capacity takes units of 512 bytes. | 494 | * The EXT_CSD sector count is in number or 512 byte |
483 | */ | 495 | * sectors. |
484 | set_capacity(md->disk, card->csd.capacity << (card->csd.read_blkbits - 9)); | 496 | */ |
497 | set_capacity(md->disk, card->ext_csd.sectors); | ||
498 | } else { | ||
499 | /* | ||
500 | * The CSD capacity field is in units of read_blkbits. | ||
501 | * set_capacity takes units of 512 bytes. | ||
502 | */ | ||
503 | set_capacity(md->disk, | ||
504 | card->csd.capacity << (card->csd.read_blkbits - 9)); | ||
505 | } | ||
485 | return md; | 506 | return md; |
486 | 507 | ||
487 | err_putdisk: | 508 | err_putdisk: |
@@ -502,12 +523,12 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card) | |||
502 | if (mmc_card_blockaddr(card)) | 523 | if (mmc_card_blockaddr(card)) |
503 | return 0; | 524 | return 0; |
504 | 525 | ||
505 | mmc_card_claim_host(card); | 526 | mmc_claim_host(card->host); |
506 | cmd.opcode = MMC_SET_BLOCKLEN; | 527 | cmd.opcode = MMC_SET_BLOCKLEN; |
507 | cmd.arg = 1 << md->block_bits; | 528 | cmd.arg = 1 << md->block_bits; |
508 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | 529 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
509 | err = mmc_wait_for_cmd(card->host, &cmd, 5); | 530 | err = mmc_wait_for_cmd(card->host, &cmd, 5); |
510 | mmc_card_release_host(card); | 531 | mmc_release_host(card->host); |
511 | 532 | ||
512 | if (err) { | 533 | if (err) { |
513 | printk(KERN_ERR "%s: unable to set block size to %d: %d\n", | 534 | printk(KERN_ERR "%s: unable to set block size to %d: %d\n", |
diff --git a/drivers/mmc/mmc_queue.c b/drivers/mmc/card/queue.c index c27e42645cdb..2e77963db334 100644 --- a/drivers/mmc/mmc_queue.c +++ b/drivers/mmc/card/queue.c | |||
@@ -1,7 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/mmc_queue.c | 2 | * linux/drivers/mmc/queue.c |
3 | * | 3 | * |
4 | * Copyright (C) 2003 Russell King, All Rights Reserved. | 4 | * Copyright (C) 2003 Russell King, All Rights Reserved. |
5 | * Copyright 2006-2007 Pierre Ossman | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
@@ -14,7 +15,7 @@ | |||
14 | 15 | ||
15 | #include <linux/mmc/card.h> | 16 | #include <linux/mmc/card.h> |
16 | #include <linux/mmc/host.h> | 17 | #include <linux/mmc/host.h> |
17 | #include "mmc_queue.h" | 18 | #include "queue.h" |
18 | 19 | ||
19 | #define MMC_QUEUE_SUSPENDED (1 << 0) | 20 | #define MMC_QUEUE_SUSPENDED (1 << 0) |
20 | 21 | ||
@@ -179,7 +180,6 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock | |||
179 | blk_cleanup_queue(mq->queue); | 180 | blk_cleanup_queue(mq->queue); |
180 | return ret; | 181 | return ret; |
181 | } | 182 | } |
182 | EXPORT_SYMBOL(mmc_init_queue); | ||
183 | 183 | ||
184 | void mmc_cleanup_queue(struct mmc_queue *mq) | 184 | void mmc_cleanup_queue(struct mmc_queue *mq) |
185 | { | 185 | { |
@@ -191,6 +191,9 @@ void mmc_cleanup_queue(struct mmc_queue *mq) | |||
191 | q->queuedata = NULL; | 191 | q->queuedata = NULL; |
192 | spin_unlock_irqrestore(q->queue_lock, flags); | 192 | spin_unlock_irqrestore(q->queue_lock, flags); |
193 | 193 | ||
194 | /* Make sure the queue isn't suspended, as that will deadlock */ | ||
195 | mmc_queue_resume(mq); | ||
196 | |||
194 | /* Then terminate our worker thread */ | 197 | /* Then terminate our worker thread */ |
195 | kthread_stop(mq->thread); | 198 | kthread_stop(mq->thread); |
196 | 199 | ||
@@ -226,7 +229,6 @@ void mmc_queue_suspend(struct mmc_queue *mq) | |||
226 | down(&mq->thread_sem); | 229 | down(&mq->thread_sem); |
227 | } | 230 | } |
228 | } | 231 | } |
229 | EXPORT_SYMBOL(mmc_queue_suspend); | ||
230 | 232 | ||
231 | /** | 233 | /** |
232 | * mmc_queue_resume - resume a previously suspended MMC request queue | 234 | * mmc_queue_resume - resume a previously suspended MMC request queue |
@@ -247,4 +249,4 @@ void mmc_queue_resume(struct mmc_queue *mq) | |||
247 | spin_unlock_irqrestore(q->queue_lock, flags); | 249 | spin_unlock_irqrestore(q->queue_lock, flags); |
248 | } | 250 | } |
249 | } | 251 | } |
250 | EXPORT_SYMBOL(mmc_queue_resume); | 252 | |
diff --git a/drivers/mmc/mmc_queue.h b/drivers/mmc/card/queue.h index c9f139e764f6..c9f139e764f6 100644 --- a/drivers/mmc/mmc_queue.h +++ b/drivers/mmc/card/queue.h | |||
diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig new file mode 100644 index 000000000000..94222b9a15ea --- /dev/null +++ b/drivers/mmc/core/Kconfig | |||
@@ -0,0 +1,17 @@ | |||
1 | # | ||
2 | # MMC core configuration | ||
3 | # | ||
4 | |||
5 | config MMC_UNSAFE_RESUME | ||
6 | bool "Allow unsafe resume (DANGEROUS)" | ||
7 | depends on MMC != n | ||
8 | help | ||
9 | If you say Y here, the MMC layer will assume that all cards | ||
10 | stayed in their respective slots during the suspend. The | ||
11 | normal behaviour is to remove them at suspend and | ||
12 | redetecting them at resume. Breaking this assumption will | ||
13 | in most cases result in data corruption. | ||
14 | |||
15 | This option is usually just for embedded systems which use | ||
16 | a MMC/SD card for rootfs. Most people should say N here. | ||
17 | |||
diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile new file mode 100644 index 000000000000..1075b02ae754 --- /dev/null +++ b/drivers/mmc/core/Makefile | |||
@@ -0,0 +1,11 @@ | |||
1 | # | ||
2 | # Makefile for the kernel mmc core. | ||
3 | # | ||
4 | |||
5 | ifeq ($(CONFIG_MMC_DEBUG),y) | ||
6 | EXTRA_CFLAGS += -DDEBUG | ||
7 | endif | ||
8 | |||
9 | obj-$(CONFIG_MMC) += mmc_core.o | ||
10 | mmc_core-y := core.o sysfs.o mmc.o mmc_ops.o sd.o sd_ops.o | ||
11 | |||
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c new file mode 100644 index 000000000000..72c7cf4a9f9d --- /dev/null +++ b/drivers/mmc/core/core.c | |||
@@ -0,0 +1,727 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/core/core.c | ||
3 | * | ||
4 | * Copyright (C) 2003-2004 Russell King, All Rights Reserved. | ||
5 | * SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. | ||
6 | * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. | ||
7 | * MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/completion.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/pagemap.h> | ||
20 | #include <linux/err.h> | ||
21 | #include <asm/scatterlist.h> | ||
22 | #include <linux/scatterlist.h> | ||
23 | |||
24 | #include <linux/mmc/card.h> | ||
25 | #include <linux/mmc/host.h> | ||
26 | #include <linux/mmc/mmc.h> | ||
27 | #include <linux/mmc/sd.h> | ||
28 | |||
29 | #include "core.h" | ||
30 | #include "sysfs.h" | ||
31 | |||
32 | #include "mmc_ops.h" | ||
33 | #include "sd_ops.h" | ||
34 | |||
35 | extern int mmc_attach_mmc(struct mmc_host *host, u32 ocr); | ||
36 | extern int mmc_attach_sd(struct mmc_host *host, u32 ocr); | ||
37 | |||
38 | /** | ||
39 | * mmc_request_done - finish processing an MMC request | ||
40 | * @host: MMC host which completed request | ||
41 | * @mrq: MMC request which request | ||
42 | * | ||
43 | * MMC drivers should call this function when they have completed | ||
44 | * their processing of a request. | ||
45 | */ | ||
46 | void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) | ||
47 | { | ||
48 | struct mmc_command *cmd = mrq->cmd; | ||
49 | int err = cmd->error; | ||
50 | |||
51 | pr_debug("%s: req done (CMD%u): %d/%d/%d: %08x %08x %08x %08x\n", | ||
52 | mmc_hostname(host), cmd->opcode, err, | ||
53 | mrq->data ? mrq->data->error : 0, | ||
54 | mrq->stop ? mrq->stop->error : 0, | ||
55 | cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); | ||
56 | |||
57 | if (err && cmd->retries) { | ||
58 | cmd->retries--; | ||
59 | cmd->error = 0; | ||
60 | host->ops->request(host, mrq); | ||
61 | } else if (mrq->done) { | ||
62 | mrq->done(mrq); | ||
63 | } | ||
64 | } | ||
65 | |||
66 | EXPORT_SYMBOL(mmc_request_done); | ||
67 | |||
68 | /** | ||
69 | * mmc_start_request - start a command on a host | ||
70 | * @host: MMC host to start command on | ||
71 | * @mrq: MMC request to start | ||
72 | * | ||
73 | * Queue a command on the specified host. We expect the | ||
74 | * caller to be holding the host lock with interrupts disabled. | ||
75 | */ | ||
76 | void | ||
77 | mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) | ||
78 | { | ||
79 | #ifdef CONFIG_MMC_DEBUG | ||
80 | unsigned int i, sz; | ||
81 | #endif | ||
82 | |||
83 | pr_debug("%s: starting CMD%u arg %08x flags %08x\n", | ||
84 | mmc_hostname(host), mrq->cmd->opcode, | ||
85 | mrq->cmd->arg, mrq->cmd->flags); | ||
86 | |||
87 | WARN_ON(!host->claimed); | ||
88 | |||
89 | mrq->cmd->error = 0; | ||
90 | mrq->cmd->mrq = mrq; | ||
91 | if (mrq->data) { | ||
92 | BUG_ON(mrq->data->blksz > host->max_blk_size); | ||
93 | BUG_ON(mrq->data->blocks > host->max_blk_count); | ||
94 | BUG_ON(mrq->data->blocks * mrq->data->blksz > | ||
95 | host->max_req_size); | ||
96 | |||
97 | #ifdef CONFIG_MMC_DEBUG | ||
98 | sz = 0; | ||
99 | for (i = 0;i < mrq->data->sg_len;i++) | ||
100 | sz += mrq->data->sg[i].length; | ||
101 | BUG_ON(sz != mrq->data->blocks * mrq->data->blksz); | ||
102 | #endif | ||
103 | |||
104 | mrq->cmd->data = mrq->data; | ||
105 | mrq->data->error = 0; | ||
106 | mrq->data->mrq = mrq; | ||
107 | if (mrq->stop) { | ||
108 | mrq->data->stop = mrq->stop; | ||
109 | mrq->stop->error = 0; | ||
110 | mrq->stop->mrq = mrq; | ||
111 | } | ||
112 | } | ||
113 | host->ops->request(host, mrq); | ||
114 | } | ||
115 | |||
116 | EXPORT_SYMBOL(mmc_start_request); | ||
117 | |||
118 | static void mmc_wait_done(struct mmc_request *mrq) | ||
119 | { | ||
120 | complete(mrq->done_data); | ||
121 | } | ||
122 | |||
123 | int mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) | ||
124 | { | ||
125 | DECLARE_COMPLETION_ONSTACK(complete); | ||
126 | |||
127 | mrq->done_data = &complete; | ||
128 | mrq->done = mmc_wait_done; | ||
129 | |||
130 | mmc_start_request(host, mrq); | ||
131 | |||
132 | wait_for_completion(&complete); | ||
133 | |||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | EXPORT_SYMBOL(mmc_wait_for_req); | ||
138 | |||
139 | /** | ||
140 | * mmc_wait_for_cmd - start a command and wait for completion | ||
141 | * @host: MMC host to start command | ||
142 | * @cmd: MMC command to start | ||
143 | * @retries: maximum number of retries | ||
144 | * | ||
145 | * Start a new MMC command for a host, and wait for the command | ||
146 | * to complete. Return any error that occurred while the command | ||
147 | * was executing. Do not attempt to parse the response. | ||
148 | */ | ||
149 | int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries) | ||
150 | { | ||
151 | struct mmc_request mrq; | ||
152 | |||
153 | BUG_ON(!host->claimed); | ||
154 | |||
155 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
156 | |||
157 | memset(cmd->resp, 0, sizeof(cmd->resp)); | ||
158 | cmd->retries = retries; | ||
159 | |||
160 | mrq.cmd = cmd; | ||
161 | cmd->data = NULL; | ||
162 | |||
163 | mmc_wait_for_req(host, &mrq); | ||
164 | |||
165 | return cmd->error; | ||
166 | } | ||
167 | |||
168 | EXPORT_SYMBOL(mmc_wait_for_cmd); | ||
169 | |||
170 | /** | ||
171 | * mmc_set_data_timeout - set the timeout for a data command | ||
172 | * @data: data phase for command | ||
173 | * @card: the MMC card associated with the data transfer | ||
174 | * @write: flag to differentiate reads from writes | ||
175 | */ | ||
176 | void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card, | ||
177 | int write) | ||
178 | { | ||
179 | unsigned int mult; | ||
180 | |||
181 | /* | ||
182 | * SD cards use a 100 multiplier rather than 10 | ||
183 | */ | ||
184 | mult = mmc_card_sd(card) ? 100 : 10; | ||
185 | |||
186 | /* | ||
187 | * Scale up the multiplier (and therefore the timeout) by | ||
188 | * the r2w factor for writes. | ||
189 | */ | ||
190 | if (write) | ||
191 | mult <<= card->csd.r2w_factor; | ||
192 | |||
193 | data->timeout_ns = card->csd.tacc_ns * mult; | ||
194 | data->timeout_clks = card->csd.tacc_clks * mult; | ||
195 | |||
196 | /* | ||
197 | * SD cards also have an upper limit on the timeout. | ||
198 | */ | ||
199 | if (mmc_card_sd(card)) { | ||
200 | unsigned int timeout_us, limit_us; | ||
201 | |||
202 | timeout_us = data->timeout_ns / 1000; | ||
203 | timeout_us += data->timeout_clks * 1000 / | ||
204 | (card->host->ios.clock / 1000); | ||
205 | |||
206 | if (write) | ||
207 | limit_us = 250000; | ||
208 | else | ||
209 | limit_us = 100000; | ||
210 | |||
211 | /* | ||
212 | * SDHC cards always use these fixed values. | ||
213 | */ | ||
214 | if (timeout_us > limit_us || mmc_card_blockaddr(card)) { | ||
215 | data->timeout_ns = limit_us * 1000; | ||
216 | data->timeout_clks = 0; | ||
217 | } | ||
218 | } | ||
219 | } | ||
220 | EXPORT_SYMBOL(mmc_set_data_timeout); | ||
221 | |||
222 | /** | ||
223 | * __mmc_claim_host - exclusively claim a host | ||
224 | * @host: mmc host to claim | ||
225 | * @card: mmc card to claim host for | ||
226 | * | ||
227 | * Claim a host for a set of operations. If a valid card | ||
228 | * is passed and this wasn't the last card selected, select | ||
229 | * the card before returning. | ||
230 | * | ||
231 | * Note: you should use mmc_card_claim_host or mmc_claim_host. | ||
232 | */ | ||
233 | void mmc_claim_host(struct mmc_host *host) | ||
234 | { | ||
235 | DECLARE_WAITQUEUE(wait, current); | ||
236 | unsigned long flags; | ||
237 | |||
238 | add_wait_queue(&host->wq, &wait); | ||
239 | spin_lock_irqsave(&host->lock, flags); | ||
240 | while (1) { | ||
241 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
242 | if (!host->claimed) | ||
243 | break; | ||
244 | spin_unlock_irqrestore(&host->lock, flags); | ||
245 | schedule(); | ||
246 | spin_lock_irqsave(&host->lock, flags); | ||
247 | } | ||
248 | set_current_state(TASK_RUNNING); | ||
249 | host->claimed = 1; | ||
250 | spin_unlock_irqrestore(&host->lock, flags); | ||
251 | remove_wait_queue(&host->wq, &wait); | ||
252 | } | ||
253 | |||
254 | EXPORT_SYMBOL(mmc_claim_host); | ||
255 | |||
256 | /** | ||
257 | * mmc_release_host - release a host | ||
258 | * @host: mmc host to release | ||
259 | * | ||
260 | * Release a MMC host, allowing others to claim the host | ||
261 | * for their operations. | ||
262 | */ | ||
263 | void mmc_release_host(struct mmc_host *host) | ||
264 | { | ||
265 | unsigned long flags; | ||
266 | |||
267 | BUG_ON(!host->claimed); | ||
268 | |||
269 | spin_lock_irqsave(&host->lock, flags); | ||
270 | host->claimed = 0; | ||
271 | spin_unlock_irqrestore(&host->lock, flags); | ||
272 | |||
273 | wake_up(&host->wq); | ||
274 | } | ||
275 | |||
276 | EXPORT_SYMBOL(mmc_release_host); | ||
277 | |||
278 | /* | ||
279 | * Internal function that does the actual ios call to the host driver, | ||
280 | * optionally printing some debug output. | ||
281 | */ | ||
282 | static inline void mmc_set_ios(struct mmc_host *host) | ||
283 | { | ||
284 | struct mmc_ios *ios = &host->ios; | ||
285 | |||
286 | pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u " | ||
287 | "width %u timing %u\n", | ||
288 | mmc_hostname(host), ios->clock, ios->bus_mode, | ||
289 | ios->power_mode, ios->chip_select, ios->vdd, | ||
290 | ios->bus_width, ios->timing); | ||
291 | |||
292 | host->ops->set_ios(host, ios); | ||
293 | } | ||
294 | |||
295 | /* | ||
296 | * Control chip select pin on a host. | ||
297 | */ | ||
298 | void mmc_set_chip_select(struct mmc_host *host, int mode) | ||
299 | { | ||
300 | host->ios.chip_select = mode; | ||
301 | mmc_set_ios(host); | ||
302 | } | ||
303 | |||
304 | /* | ||
305 | * Sets the host clock to the highest possible frequency that | ||
306 | * is below "hz". | ||
307 | */ | ||
308 | void mmc_set_clock(struct mmc_host *host, unsigned int hz) | ||
309 | { | ||
310 | WARN_ON(hz < host->f_min); | ||
311 | |||
312 | if (hz > host->f_max) | ||
313 | hz = host->f_max; | ||
314 | |||
315 | host->ios.clock = hz; | ||
316 | mmc_set_ios(host); | ||
317 | } | ||
318 | |||
319 | /* | ||
320 | * Change the bus mode (open drain/push-pull) of a host. | ||
321 | */ | ||
322 | void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode) | ||
323 | { | ||
324 | host->ios.bus_mode = mode; | ||
325 | mmc_set_ios(host); | ||
326 | } | ||
327 | |||
328 | /* | ||
329 | * Change data bus width of a host. | ||
330 | */ | ||
331 | void mmc_set_bus_width(struct mmc_host *host, unsigned int width) | ||
332 | { | ||
333 | host->ios.bus_width = width; | ||
334 | mmc_set_ios(host); | ||
335 | } | ||
336 | |||
337 | /* | ||
338 | * Mask off any voltages we don't support and select | ||
339 | * the lowest voltage | ||
340 | */ | ||
341 | u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) | ||
342 | { | ||
343 | int bit; | ||
344 | |||
345 | ocr &= host->ocr_avail; | ||
346 | |||
347 | bit = ffs(ocr); | ||
348 | if (bit) { | ||
349 | bit -= 1; | ||
350 | |||
351 | ocr &= 3 << bit; | ||
352 | |||
353 | host->ios.vdd = bit; | ||
354 | mmc_set_ios(host); | ||
355 | } else { | ||
356 | ocr = 0; | ||
357 | } | ||
358 | |||
359 | return ocr; | ||
360 | } | ||
361 | |||
362 | /* | ||
363 | * Select timing parameters for host. | ||
364 | */ | ||
365 | void mmc_set_timing(struct mmc_host *host, unsigned int timing) | ||
366 | { | ||
367 | host->ios.timing = timing; | ||
368 | mmc_set_ios(host); | ||
369 | } | ||
370 | |||
371 | /* | ||
372 | * Allocate a new MMC card | ||
373 | */ | ||
374 | struct mmc_card *mmc_alloc_card(struct mmc_host *host) | ||
375 | { | ||
376 | struct mmc_card *card; | ||
377 | |||
378 | card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL); | ||
379 | if (!card) | ||
380 | return ERR_PTR(-ENOMEM); | ||
381 | |||
382 | mmc_init_card(card, host); | ||
383 | |||
384 | return card; | ||
385 | } | ||
386 | |||
387 | /* | ||
388 | * Apply power to the MMC stack. This is a two-stage process. | ||
389 | * First, we enable power to the card without the clock running. | ||
390 | * We then wait a bit for the power to stabilise. Finally, | ||
391 | * enable the bus drivers and clock to the card. | ||
392 | * | ||
393 | * We must _NOT_ enable the clock prior to power stablising. | ||
394 | * | ||
395 | * If a host does all the power sequencing itself, ignore the | ||
396 | * initial MMC_POWER_UP stage. | ||
397 | */ | ||
398 | static void mmc_power_up(struct mmc_host *host) | ||
399 | { | ||
400 | int bit = fls(host->ocr_avail) - 1; | ||
401 | |||
402 | host->ios.vdd = bit; | ||
403 | host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; | ||
404 | host->ios.chip_select = MMC_CS_DONTCARE; | ||
405 | host->ios.power_mode = MMC_POWER_UP; | ||
406 | host->ios.bus_width = MMC_BUS_WIDTH_1; | ||
407 | host->ios.timing = MMC_TIMING_LEGACY; | ||
408 | mmc_set_ios(host); | ||
409 | |||
410 | mmc_delay(1); | ||
411 | |||
412 | host->ios.clock = host->f_min; | ||
413 | host->ios.power_mode = MMC_POWER_ON; | ||
414 | mmc_set_ios(host); | ||
415 | |||
416 | mmc_delay(2); | ||
417 | } | ||
418 | |||
419 | static void mmc_power_off(struct mmc_host *host) | ||
420 | { | ||
421 | host->ios.clock = 0; | ||
422 | host->ios.vdd = 0; | ||
423 | host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; | ||
424 | host->ios.chip_select = MMC_CS_DONTCARE; | ||
425 | host->ios.power_mode = MMC_POWER_OFF; | ||
426 | host->ios.bus_width = MMC_BUS_WIDTH_1; | ||
427 | host->ios.timing = MMC_TIMING_LEGACY; | ||
428 | mmc_set_ios(host); | ||
429 | } | ||
430 | |||
431 | /* | ||
432 | * Assign a mmc bus handler to a host. Only one bus handler may control a | ||
433 | * host at any given time. | ||
434 | */ | ||
435 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops) | ||
436 | { | ||
437 | unsigned long flags; | ||
438 | |||
439 | BUG_ON(!host); | ||
440 | BUG_ON(!ops); | ||
441 | |||
442 | BUG_ON(!host->claimed); | ||
443 | |||
444 | spin_lock_irqsave(&host->lock, flags); | ||
445 | |||
446 | BUG_ON(host->bus_ops); | ||
447 | BUG_ON(host->bus_refs); | ||
448 | |||
449 | host->bus_ops = ops; | ||
450 | host->bus_refs = 1; | ||
451 | host->bus_dead = 0; | ||
452 | |||
453 | spin_unlock_irqrestore(&host->lock, flags); | ||
454 | } | ||
455 | |||
456 | /* | ||
457 | * Remove the current bus handler from a host. Assumes that there are | ||
458 | * no interesting cards left, so the bus is powered down. | ||
459 | */ | ||
460 | void mmc_detach_bus(struct mmc_host *host) | ||
461 | { | ||
462 | unsigned long flags; | ||
463 | |||
464 | BUG_ON(!host); | ||
465 | |||
466 | BUG_ON(!host->claimed); | ||
467 | BUG_ON(!host->bus_ops); | ||
468 | |||
469 | spin_lock_irqsave(&host->lock, flags); | ||
470 | |||
471 | host->bus_dead = 1; | ||
472 | |||
473 | spin_unlock_irqrestore(&host->lock, flags); | ||
474 | |||
475 | mmc_power_off(host); | ||
476 | |||
477 | mmc_bus_put(host); | ||
478 | } | ||
479 | |||
480 | /* | ||
481 | * Cleanup when the last reference to the bus operator is dropped. | ||
482 | */ | ||
483 | void __mmc_release_bus(struct mmc_host *host) | ||
484 | { | ||
485 | BUG_ON(!host); | ||
486 | BUG_ON(host->bus_refs); | ||
487 | BUG_ON(!host->bus_dead); | ||
488 | |||
489 | host->bus_ops = NULL; | ||
490 | } | ||
491 | |||
492 | /** | ||
493 | * mmc_detect_change - process change of state on a MMC socket | ||
494 | * @host: host which changed state. | ||
495 | * @delay: optional delay to wait before detection (jiffies) | ||
496 | * | ||
497 | * All we know is that card(s) have been inserted or removed | ||
498 | * from the socket(s). We don't know which socket or cards. | ||
499 | */ | ||
500 | void mmc_detect_change(struct mmc_host *host, unsigned long delay) | ||
501 | { | ||
502 | #ifdef CONFIG_MMC_DEBUG | ||
503 | mmc_claim_host(host); | ||
504 | BUG_ON(host->removed); | ||
505 | mmc_release_host(host); | ||
506 | #endif | ||
507 | |||
508 | mmc_schedule_delayed_work(&host->detect, delay); | ||
509 | } | ||
510 | |||
511 | EXPORT_SYMBOL(mmc_detect_change); | ||
512 | |||
513 | |||
514 | static void mmc_rescan(struct work_struct *work) | ||
515 | { | ||
516 | struct mmc_host *host = | ||
517 | container_of(work, struct mmc_host, detect.work); | ||
518 | u32 ocr; | ||
519 | int err; | ||
520 | |||
521 | mmc_bus_get(host); | ||
522 | |||
523 | if (host->bus_ops == NULL) { | ||
524 | /* | ||
525 | * Only we can add a new handler, so it's safe to | ||
526 | * release the lock here. | ||
527 | */ | ||
528 | mmc_bus_put(host); | ||
529 | |||
530 | mmc_claim_host(host); | ||
531 | |||
532 | mmc_power_up(host); | ||
533 | mmc_go_idle(host); | ||
534 | |||
535 | mmc_send_if_cond(host, host->ocr_avail); | ||
536 | |||
537 | err = mmc_send_app_op_cond(host, 0, &ocr); | ||
538 | if (err == MMC_ERR_NONE) { | ||
539 | if (mmc_attach_sd(host, ocr)) | ||
540 | mmc_power_off(host); | ||
541 | } else { | ||
542 | /* | ||
543 | * If we fail to detect any SD cards then try | ||
544 | * searching for MMC cards. | ||
545 | */ | ||
546 | err = mmc_send_op_cond(host, 0, &ocr); | ||
547 | if (err == MMC_ERR_NONE) { | ||
548 | if (mmc_attach_mmc(host, ocr)) | ||
549 | mmc_power_off(host); | ||
550 | } else { | ||
551 | mmc_power_off(host); | ||
552 | mmc_release_host(host); | ||
553 | } | ||
554 | } | ||
555 | } else { | ||
556 | if (host->bus_ops->detect && !host->bus_dead) | ||
557 | host->bus_ops->detect(host); | ||
558 | |||
559 | mmc_bus_put(host); | ||
560 | } | ||
561 | } | ||
562 | |||
563 | |||
564 | /** | ||
565 | * mmc_alloc_host - initialise the per-host structure. | ||
566 | * @extra: sizeof private data structure | ||
567 | * @dev: pointer to host device model structure | ||
568 | * | ||
569 | * Initialise the per-host structure. | ||
570 | */ | ||
571 | struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | ||
572 | { | ||
573 | struct mmc_host *host; | ||
574 | |||
575 | host = mmc_alloc_host_sysfs(extra, dev); | ||
576 | if (host) { | ||
577 | spin_lock_init(&host->lock); | ||
578 | init_waitqueue_head(&host->wq); | ||
579 | INIT_DELAYED_WORK(&host->detect, mmc_rescan); | ||
580 | |||
581 | /* | ||
582 | * By default, hosts do not support SGIO or large requests. | ||
583 | * They have to set these according to their abilities. | ||
584 | */ | ||
585 | host->max_hw_segs = 1; | ||
586 | host->max_phys_segs = 1; | ||
587 | host->max_seg_size = PAGE_CACHE_SIZE; | ||
588 | |||
589 | host->max_req_size = PAGE_CACHE_SIZE; | ||
590 | host->max_blk_size = 512; | ||
591 | host->max_blk_count = PAGE_CACHE_SIZE / 512; | ||
592 | } | ||
593 | |||
594 | return host; | ||
595 | } | ||
596 | |||
597 | EXPORT_SYMBOL(mmc_alloc_host); | ||
598 | |||
599 | /** | ||
600 | * mmc_add_host - initialise host hardware | ||
601 | * @host: mmc host | ||
602 | */ | ||
603 | int mmc_add_host(struct mmc_host *host) | ||
604 | { | ||
605 | int ret; | ||
606 | |||
607 | ret = mmc_add_host_sysfs(host); | ||
608 | if (ret == 0) { | ||
609 | mmc_power_off(host); | ||
610 | mmc_detect_change(host, 0); | ||
611 | } | ||
612 | |||
613 | return ret; | ||
614 | } | ||
615 | |||
616 | EXPORT_SYMBOL(mmc_add_host); | ||
617 | |||
618 | /** | ||
619 | * mmc_remove_host - remove host hardware | ||
620 | * @host: mmc host | ||
621 | * | ||
622 | * Unregister and remove all cards associated with this host, | ||
623 | * and power down the MMC bus. | ||
624 | */ | ||
625 | void mmc_remove_host(struct mmc_host *host) | ||
626 | { | ||
627 | #ifdef CONFIG_MMC_DEBUG | ||
628 | mmc_claim_host(host); | ||
629 | host->removed = 1; | ||
630 | mmc_release_host(host); | ||
631 | #endif | ||
632 | |||
633 | mmc_flush_scheduled_work(); | ||
634 | |||
635 | mmc_bus_get(host); | ||
636 | if (host->bus_ops && !host->bus_dead) { | ||
637 | if (host->bus_ops->remove) | ||
638 | host->bus_ops->remove(host); | ||
639 | |||
640 | mmc_claim_host(host); | ||
641 | mmc_detach_bus(host); | ||
642 | mmc_release_host(host); | ||
643 | } | ||
644 | mmc_bus_put(host); | ||
645 | |||
646 | BUG_ON(host->card); | ||
647 | |||
648 | mmc_power_off(host); | ||
649 | mmc_remove_host_sysfs(host); | ||
650 | } | ||
651 | |||
652 | EXPORT_SYMBOL(mmc_remove_host); | ||
653 | |||
654 | /** | ||
655 | * mmc_free_host - free the host structure | ||
656 | * @host: mmc host | ||
657 | * | ||
658 | * Free the host once all references to it have been dropped. | ||
659 | */ | ||
660 | void mmc_free_host(struct mmc_host *host) | ||
661 | { | ||
662 | mmc_free_host_sysfs(host); | ||
663 | } | ||
664 | |||
665 | EXPORT_SYMBOL(mmc_free_host); | ||
666 | |||
667 | #ifdef CONFIG_PM | ||
668 | |||
669 | /** | ||
670 | * mmc_suspend_host - suspend a host | ||
671 | * @host: mmc host | ||
672 | * @state: suspend mode (PM_SUSPEND_xxx) | ||
673 | */ | ||
674 | int mmc_suspend_host(struct mmc_host *host, pm_message_t state) | ||
675 | { | ||
676 | mmc_flush_scheduled_work(); | ||
677 | |||
678 | mmc_bus_get(host); | ||
679 | if (host->bus_ops && !host->bus_dead) { | ||
680 | if (host->bus_ops->suspend) | ||
681 | host->bus_ops->suspend(host); | ||
682 | if (!host->bus_ops->resume) { | ||
683 | if (host->bus_ops->remove) | ||
684 | host->bus_ops->remove(host); | ||
685 | |||
686 | mmc_claim_host(host); | ||
687 | mmc_detach_bus(host); | ||
688 | mmc_release_host(host); | ||
689 | } | ||
690 | } | ||
691 | mmc_bus_put(host); | ||
692 | |||
693 | mmc_power_off(host); | ||
694 | |||
695 | return 0; | ||
696 | } | ||
697 | |||
698 | EXPORT_SYMBOL(mmc_suspend_host); | ||
699 | |||
700 | /** | ||
701 | * mmc_resume_host - resume a previously suspended host | ||
702 | * @host: mmc host | ||
703 | */ | ||
704 | int mmc_resume_host(struct mmc_host *host) | ||
705 | { | ||
706 | mmc_bus_get(host); | ||
707 | if (host->bus_ops && !host->bus_dead) { | ||
708 | mmc_power_up(host); | ||
709 | BUG_ON(!host->bus_ops->resume); | ||
710 | host->bus_ops->resume(host); | ||
711 | } | ||
712 | mmc_bus_put(host); | ||
713 | |||
714 | /* | ||
715 | * We add a slight delay here so that resume can progress | ||
716 | * in parallel. | ||
717 | */ | ||
718 | mmc_detect_change(host, 1); | ||
719 | |||
720 | return 0; | ||
721 | } | ||
722 | |||
723 | EXPORT_SYMBOL(mmc_resume_host); | ||
724 | |||
725 | #endif | ||
726 | |||
727 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h new file mode 100644 index 000000000000..177264d090ac --- /dev/null +++ b/drivers/mmc/core/core.h | |||
@@ -0,0 +1,70 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/core/core.h | ||
3 | * | ||
4 | * Copyright (C) 2003 Russell King, All Rights Reserved. | ||
5 | * Copyright 2007 Pierre Ossman | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | #ifndef _MMC_CORE_CORE_H | ||
12 | #define _MMC_CORE_CORE_H | ||
13 | |||
14 | #include <linux/delay.h> | ||
15 | |||
16 | #define MMC_CMD_RETRIES 3 | ||
17 | |||
18 | struct mmc_bus_ops { | ||
19 | void (*remove)(struct mmc_host *); | ||
20 | void (*detect)(struct mmc_host *); | ||
21 | void (*suspend)(struct mmc_host *); | ||
22 | void (*resume)(struct mmc_host *); | ||
23 | }; | ||
24 | |||
25 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); | ||
26 | void mmc_detach_bus(struct mmc_host *host); | ||
27 | |||
28 | void __mmc_release_bus(struct mmc_host *host); | ||
29 | |||
30 | static inline void mmc_bus_get(struct mmc_host *host) | ||
31 | { | ||
32 | unsigned long flags; | ||
33 | |||
34 | spin_lock_irqsave(&host->lock, flags); | ||
35 | host->bus_refs++; | ||
36 | spin_unlock_irqrestore(&host->lock, flags); | ||
37 | } | ||
38 | |||
39 | static inline void mmc_bus_put(struct mmc_host *host) | ||
40 | { | ||
41 | unsigned long flags; | ||
42 | |||
43 | spin_lock_irqsave(&host->lock, flags); | ||
44 | host->bus_refs--; | ||
45 | if ((host->bus_refs == 0) && host->bus_ops) | ||
46 | __mmc_release_bus(host); | ||
47 | spin_unlock_irqrestore(&host->lock, flags); | ||
48 | } | ||
49 | |||
50 | void mmc_set_chip_select(struct mmc_host *host, int mode); | ||
51 | void mmc_set_clock(struct mmc_host *host, unsigned int hz); | ||
52 | void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode); | ||
53 | void mmc_set_bus_width(struct mmc_host *host, unsigned int width); | ||
54 | u32 mmc_select_voltage(struct mmc_host *host, u32 ocr); | ||
55 | void mmc_set_timing(struct mmc_host *host, unsigned int timing); | ||
56 | |||
57 | struct mmc_card *mmc_alloc_card(struct mmc_host *host); | ||
58 | |||
59 | static inline void mmc_delay(unsigned int ms) | ||
60 | { | ||
61 | if (ms < 1000 / HZ) { | ||
62 | cond_resched(); | ||
63 | mdelay(ms); | ||
64 | } else { | ||
65 | msleep(ms); | ||
66 | } | ||
67 | } | ||
68 | |||
69 | #endif | ||
70 | |||
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c new file mode 100644 index 000000000000..42cc2867ed7d --- /dev/null +++ b/drivers/mmc/core/mmc.c | |||
@@ -0,0 +1,537 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/mmc.c | ||
3 | * | ||
4 | * Copyright (C) 2003-2004 Russell King, All Rights Reserved. | ||
5 | * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. | ||
6 | * MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/err.h> | ||
14 | |||
15 | #include <linux/mmc/host.h> | ||
16 | #include <linux/mmc/card.h> | ||
17 | #include <linux/mmc/mmc.h> | ||
18 | |||
19 | #include "core.h" | ||
20 | #include "sysfs.h" | ||
21 | #include "mmc_ops.h" | ||
22 | |||
23 | static const unsigned int tran_exp[] = { | ||
24 | 10000, 100000, 1000000, 10000000, | ||
25 | 0, 0, 0, 0 | ||
26 | }; | ||
27 | |||
28 | static const unsigned char tran_mant[] = { | ||
29 | 0, 10, 12, 13, 15, 20, 25, 30, | ||
30 | 35, 40, 45, 50, 55, 60, 70, 80, | ||
31 | }; | ||
32 | |||
33 | static const unsigned int tacc_exp[] = { | ||
34 | 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, | ||
35 | }; | ||
36 | |||
37 | static const unsigned int tacc_mant[] = { | ||
38 | 0, 10, 12, 13, 15, 20, 25, 30, | ||
39 | 35, 40, 45, 50, 55, 60, 70, 80, | ||
40 | }; | ||
41 | |||
42 | #define UNSTUFF_BITS(resp,start,size) \ | ||
43 | ({ \ | ||
44 | const int __size = size; \ | ||
45 | const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \ | ||
46 | const int __off = 3 - ((start) / 32); \ | ||
47 | const int __shft = (start) & 31; \ | ||
48 | u32 __res; \ | ||
49 | \ | ||
50 | __res = resp[__off] >> __shft; \ | ||
51 | if (__size + __shft > 32) \ | ||
52 | __res |= resp[__off-1] << ((32 - __shft) % 32); \ | ||
53 | __res & __mask; \ | ||
54 | }) | ||
55 | |||
56 | /* | ||
57 | * Given the decoded CSD structure, decode the raw CID to our CID structure. | ||
58 | */ | ||
59 | static int mmc_decode_cid(struct mmc_card *card) | ||
60 | { | ||
61 | u32 *resp = card->raw_cid; | ||
62 | |||
63 | /* | ||
64 | * The selection of the format here is based upon published | ||
65 | * specs from sandisk and from what people have reported. | ||
66 | */ | ||
67 | switch (card->csd.mmca_vsn) { | ||
68 | case 0: /* MMC v1.0 - v1.2 */ | ||
69 | case 1: /* MMC v1.4 */ | ||
70 | card->cid.manfid = UNSTUFF_BITS(resp, 104, 24); | ||
71 | card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); | ||
72 | card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); | ||
73 | card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); | ||
74 | card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); | ||
75 | card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); | ||
76 | card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8); | ||
77 | card->cid.prod_name[6] = UNSTUFF_BITS(resp, 48, 8); | ||
78 | card->cid.hwrev = UNSTUFF_BITS(resp, 44, 4); | ||
79 | card->cid.fwrev = UNSTUFF_BITS(resp, 40, 4); | ||
80 | card->cid.serial = UNSTUFF_BITS(resp, 16, 24); | ||
81 | card->cid.month = UNSTUFF_BITS(resp, 12, 4); | ||
82 | card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997; | ||
83 | break; | ||
84 | |||
85 | case 2: /* MMC v2.0 - v2.2 */ | ||
86 | case 3: /* MMC v3.1 - v3.3 */ | ||
87 | case 4: /* MMC v4 */ | ||
88 | card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); | ||
89 | card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); | ||
90 | card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); | ||
91 | card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); | ||
92 | card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); | ||
93 | card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); | ||
94 | card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); | ||
95 | card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8); | ||
96 | card->cid.serial = UNSTUFF_BITS(resp, 16, 32); | ||
97 | card->cid.month = UNSTUFF_BITS(resp, 12, 4); | ||
98 | card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997; | ||
99 | break; | ||
100 | |||
101 | default: | ||
102 | printk("%s: card has unknown MMCA version %d\n", | ||
103 | mmc_hostname(card->host), card->csd.mmca_vsn); | ||
104 | return -EINVAL; | ||
105 | } | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * Given a 128-bit response, decode to our card CSD structure. | ||
112 | */ | ||
113 | static int mmc_decode_csd(struct mmc_card *card) | ||
114 | { | ||
115 | struct mmc_csd *csd = &card->csd; | ||
116 | unsigned int e, m, csd_struct; | ||
117 | u32 *resp = card->raw_csd; | ||
118 | |||
119 | /* | ||
120 | * We only understand CSD structure v1.1 and v1.2. | ||
121 | * v1.2 has extra information in bits 15, 11 and 10. | ||
122 | */ | ||
123 | csd_struct = UNSTUFF_BITS(resp, 126, 2); | ||
124 | if (csd_struct != 1 && csd_struct != 2) { | ||
125 | printk("%s: unrecognised CSD structure version %d\n", | ||
126 | mmc_hostname(card->host), csd_struct); | ||
127 | return -EINVAL; | ||
128 | } | ||
129 | |||
130 | csd->mmca_vsn = UNSTUFF_BITS(resp, 122, 4); | ||
131 | m = UNSTUFF_BITS(resp, 115, 4); | ||
132 | e = UNSTUFF_BITS(resp, 112, 3); | ||
133 | csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10; | ||
134 | csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100; | ||
135 | |||
136 | m = UNSTUFF_BITS(resp, 99, 4); | ||
137 | e = UNSTUFF_BITS(resp, 96, 3); | ||
138 | csd->max_dtr = tran_exp[e] * tran_mant[m]; | ||
139 | csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); | ||
140 | |||
141 | e = UNSTUFF_BITS(resp, 47, 3); | ||
142 | m = UNSTUFF_BITS(resp, 62, 12); | ||
143 | csd->capacity = (1 + m) << (e + 2); | ||
144 | |||
145 | csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); | ||
146 | csd->read_partial = UNSTUFF_BITS(resp, 79, 1); | ||
147 | csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); | ||
148 | csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); | ||
149 | csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); | ||
150 | csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); | ||
151 | csd->write_partial = UNSTUFF_BITS(resp, 21, 1); | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | /* | ||
157 | * Read and decode extended CSD. | ||
158 | */ | ||
159 | static int mmc_read_ext_csd(struct mmc_card *card) | ||
160 | { | ||
161 | int err; | ||
162 | u8 *ext_csd; | ||
163 | |||
164 | BUG_ON(!card); | ||
165 | |||
166 | err = MMC_ERR_FAILED; | ||
167 | |||
168 | if (card->csd.mmca_vsn < CSD_SPEC_VER_4) | ||
169 | return MMC_ERR_NONE; | ||
170 | |||
171 | /* | ||
172 | * As the ext_csd is so large and mostly unused, we don't store the | ||
173 | * raw block in mmc_card. | ||
174 | */ | ||
175 | ext_csd = kmalloc(512, GFP_KERNEL); | ||
176 | if (!ext_csd) { | ||
177 | printk(KERN_ERR "%s: could not allocate a buffer to " | ||
178 | "receive the ext_csd. mmc v4 cards will be " | ||
179 | "treated as v3.\n", mmc_hostname(card->host)); | ||
180 | return MMC_ERR_FAILED; | ||
181 | } | ||
182 | |||
183 | err = mmc_send_ext_csd(card, ext_csd); | ||
184 | if (err != MMC_ERR_NONE) { | ||
185 | /* | ||
186 | * High capacity cards should have this "magic" size | ||
187 | * stored in their CSD. | ||
188 | */ | ||
189 | if (card->csd.capacity == (4096 * 512)) { | ||
190 | printk(KERN_ERR "%s: unable to read EXT_CSD " | ||
191 | "on a possible high capacity card. " | ||
192 | "Card will be ignored.\n", | ||
193 | mmc_hostname(card->host)); | ||
194 | } else { | ||
195 | printk(KERN_WARNING "%s: unable to read " | ||
196 | "EXT_CSD, performance might " | ||
197 | "suffer.\n", | ||
198 | mmc_hostname(card->host)); | ||
199 | err = MMC_ERR_NONE; | ||
200 | } | ||
201 | goto out; | ||
202 | } | ||
203 | |||
204 | card->ext_csd.sectors = | ||
205 | ext_csd[EXT_CSD_SEC_CNT + 0] << 0 | | ||
206 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8 | | ||
207 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16 | | ||
208 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24; | ||
209 | if (card->ext_csd.sectors) | ||
210 | mmc_card_set_blockaddr(card); | ||
211 | |||
212 | switch (ext_csd[EXT_CSD_CARD_TYPE]) { | ||
213 | case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: | ||
214 | card->ext_csd.hs_max_dtr = 52000000; | ||
215 | break; | ||
216 | case EXT_CSD_CARD_TYPE_26: | ||
217 | card->ext_csd.hs_max_dtr = 26000000; | ||
218 | break; | ||
219 | default: | ||
220 | /* MMC v4 spec says this cannot happen */ | ||
221 | printk(KERN_WARNING "%s: card is mmc v4 but doesn't " | ||
222 | "support any high-speed modes.\n", | ||
223 | mmc_hostname(card->host)); | ||
224 | goto out; | ||
225 | } | ||
226 | |||
227 | out: | ||
228 | kfree(ext_csd); | ||
229 | |||
230 | return err; | ||
231 | } | ||
232 | |||
233 | /* | ||
234 | * Handle the detection and initialisation of a card. | ||
235 | * | ||
236 | * In the case of a resume, "curcard" will contain the card | ||
237 | * we're trying to reinitialise. | ||
238 | */ | ||
239 | static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | ||
240 | struct mmc_card *oldcard) | ||
241 | { | ||
242 | struct mmc_card *card; | ||
243 | int err; | ||
244 | u32 cid[4]; | ||
245 | unsigned int max_dtr; | ||
246 | |||
247 | BUG_ON(!host); | ||
248 | BUG_ON(!host->claimed); | ||
249 | |||
250 | /* | ||
251 | * Since we're changing the OCR value, we seem to | ||
252 | * need to tell some cards to go back to the idle | ||
253 | * state. We wait 1ms to give cards time to | ||
254 | * respond. | ||
255 | */ | ||
256 | mmc_go_idle(host); | ||
257 | |||
258 | /* The extra bit indicates that we support high capacity */ | ||
259 | err = mmc_send_op_cond(host, ocr | (1 << 30), NULL); | ||
260 | if (err != MMC_ERR_NONE) | ||
261 | goto err; | ||
262 | |||
263 | /* | ||
264 | * Fetch CID from card. | ||
265 | */ | ||
266 | err = mmc_all_send_cid(host, cid); | ||
267 | if (err != MMC_ERR_NONE) | ||
268 | goto err; | ||
269 | |||
270 | if (oldcard) { | ||
271 | if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) | ||
272 | goto err; | ||
273 | |||
274 | card = oldcard; | ||
275 | } else { | ||
276 | /* | ||
277 | * Allocate card structure. | ||
278 | */ | ||
279 | card = mmc_alloc_card(host); | ||
280 | if (IS_ERR(card)) | ||
281 | goto err; | ||
282 | |||
283 | card->type = MMC_TYPE_MMC; | ||
284 | card->rca = 1; | ||
285 | memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); | ||
286 | } | ||
287 | |||
288 | /* | ||
289 | * Set card RCA. | ||
290 | */ | ||
291 | err = mmc_set_relative_addr(card); | ||
292 | if (err != MMC_ERR_NONE) | ||
293 | goto free_card; | ||
294 | |||
295 | mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); | ||
296 | |||
297 | if (!oldcard) { | ||
298 | /* | ||
299 | * Fetch CSD from card. | ||
300 | */ | ||
301 | err = mmc_send_csd(card, card->raw_csd); | ||
302 | if (err != MMC_ERR_NONE) | ||
303 | goto free_card; | ||
304 | |||
305 | err = mmc_decode_csd(card); | ||
306 | if (err < 0) | ||
307 | goto free_card; | ||
308 | err = mmc_decode_cid(card); | ||
309 | if (err < 0) | ||
310 | goto free_card; | ||
311 | } | ||
312 | |||
313 | /* | ||
314 | * Select card, as all following commands rely on that. | ||
315 | */ | ||
316 | err = mmc_select_card(card); | ||
317 | if (err != MMC_ERR_NONE) | ||
318 | goto free_card; | ||
319 | |||
320 | if (!oldcard) { | ||
321 | /* | ||
322 | * Fetch and process extened CSD. | ||
323 | */ | ||
324 | err = mmc_read_ext_csd(card); | ||
325 | if (err != MMC_ERR_NONE) | ||
326 | goto free_card; | ||
327 | } | ||
328 | |||
329 | /* | ||
330 | * Activate high speed (if supported) | ||
331 | */ | ||
332 | if ((card->ext_csd.hs_max_dtr != 0) && | ||
333 | (host->caps & MMC_CAP_MMC_HIGHSPEED)) { | ||
334 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | ||
335 | EXT_CSD_HS_TIMING, 1); | ||
336 | if (err != MMC_ERR_NONE) | ||
337 | goto free_card; | ||
338 | |||
339 | mmc_card_set_highspeed(card); | ||
340 | |||
341 | mmc_set_timing(card->host, MMC_TIMING_MMC_HS); | ||
342 | } | ||
343 | |||
344 | /* | ||
345 | * Compute bus speed. | ||
346 | */ | ||
347 | max_dtr = (unsigned int)-1; | ||
348 | |||
349 | if (mmc_card_highspeed(card)) { | ||
350 | if (max_dtr > card->ext_csd.hs_max_dtr) | ||
351 | max_dtr = card->ext_csd.hs_max_dtr; | ||
352 | } else if (max_dtr > card->csd.max_dtr) { | ||
353 | max_dtr = card->csd.max_dtr; | ||
354 | } | ||
355 | |||
356 | mmc_set_clock(host, max_dtr); | ||
357 | |||
358 | /* | ||
359 | * Activate wide bus (if supported). | ||
360 | */ | ||
361 | if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && | ||
362 | (host->caps & MMC_CAP_4_BIT_DATA)) { | ||
363 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | ||
364 | EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4); | ||
365 | if (err != MMC_ERR_NONE) | ||
366 | goto free_card; | ||
367 | |||
368 | mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); | ||
369 | } | ||
370 | |||
371 | if (!oldcard) | ||
372 | host->card = card; | ||
373 | |||
374 | return MMC_ERR_NONE; | ||
375 | |||
376 | free_card: | ||
377 | if (!oldcard) | ||
378 | mmc_remove_card(card); | ||
379 | err: | ||
380 | |||
381 | return MMC_ERR_FAILED; | ||
382 | } | ||
383 | |||
384 | /* | ||
385 | * Host is being removed. Free up the current card. | ||
386 | */ | ||
387 | static void mmc_remove(struct mmc_host *host) | ||
388 | { | ||
389 | BUG_ON(!host); | ||
390 | BUG_ON(!host->card); | ||
391 | |||
392 | mmc_remove_card(host->card); | ||
393 | host->card = NULL; | ||
394 | } | ||
395 | |||
396 | /* | ||
397 | * Card detection callback from host. | ||
398 | */ | ||
399 | static void mmc_detect(struct mmc_host *host) | ||
400 | { | ||
401 | int err; | ||
402 | |||
403 | BUG_ON(!host); | ||
404 | BUG_ON(!host->card); | ||
405 | |||
406 | mmc_claim_host(host); | ||
407 | |||
408 | /* | ||
409 | * Just check if our card has been removed. | ||
410 | */ | ||
411 | err = mmc_send_status(host->card, NULL); | ||
412 | |||
413 | mmc_release_host(host); | ||
414 | |||
415 | if (err != MMC_ERR_NONE) { | ||
416 | mmc_remove_card(host->card); | ||
417 | host->card = NULL; | ||
418 | |||
419 | mmc_claim_host(host); | ||
420 | mmc_detach_bus(host); | ||
421 | mmc_release_host(host); | ||
422 | } | ||
423 | } | ||
424 | |||
425 | #ifdef CONFIG_MMC_UNSAFE_RESUME | ||
426 | |||
427 | /* | ||
428 | * Suspend callback from host. | ||
429 | */ | ||
430 | static void mmc_suspend(struct mmc_host *host) | ||
431 | { | ||
432 | BUG_ON(!host); | ||
433 | BUG_ON(!host->card); | ||
434 | |||
435 | mmc_claim_host(host); | ||
436 | mmc_deselect_cards(host); | ||
437 | host->card->state &= ~MMC_STATE_HIGHSPEED; | ||
438 | mmc_release_host(host); | ||
439 | } | ||
440 | |||
441 | /* | ||
442 | * Resume callback from host. | ||
443 | * | ||
444 | * This function tries to determine if the same card is still present | ||
445 | * and, if so, restore all state to it. | ||
446 | */ | ||
447 | static void mmc_resume(struct mmc_host *host) | ||
448 | { | ||
449 | int err; | ||
450 | |||
451 | BUG_ON(!host); | ||
452 | BUG_ON(!host->card); | ||
453 | |||
454 | mmc_claim_host(host); | ||
455 | |||
456 | err = mmc_sd_init_card(host, host->ocr, host->card); | ||
457 | if (err != MMC_ERR_NONE) { | ||
458 | mmc_remove_card(host->card); | ||
459 | host->card = NULL; | ||
460 | |||
461 | mmc_detach_bus(host); | ||
462 | } | ||
463 | |||
464 | mmc_release_host(host); | ||
465 | } | ||
466 | |||
467 | #else | ||
468 | |||
469 | #define mmc_suspend NULL | ||
470 | #define mmc_resume NULL | ||
471 | |||
472 | #endif | ||
473 | |||
474 | static const struct mmc_bus_ops mmc_ops = { | ||
475 | .remove = mmc_remove, | ||
476 | .detect = mmc_detect, | ||
477 | .suspend = mmc_suspend, | ||
478 | .resume = mmc_resume, | ||
479 | }; | ||
480 | |||
481 | /* | ||
482 | * Starting point for MMC card init. | ||
483 | */ | ||
484 | int mmc_attach_mmc(struct mmc_host *host, u32 ocr) | ||
485 | { | ||
486 | int err; | ||
487 | |||
488 | BUG_ON(!host); | ||
489 | BUG_ON(!host->claimed); | ||
490 | |||
491 | mmc_attach_bus(host, &mmc_ops); | ||
492 | |||
493 | /* | ||
494 | * Sanity check the voltages that the card claims to | ||
495 | * support. | ||
496 | */ | ||
497 | if (ocr & 0x7F) { | ||
498 | printk(KERN_WARNING "%s: card claims to support voltages " | ||
499 | "below the defined range. These will be ignored.\n", | ||
500 | mmc_hostname(host)); | ||
501 | ocr &= ~0x7F; | ||
502 | } | ||
503 | |||
504 | host->ocr = mmc_select_voltage(host, ocr); | ||
505 | |||
506 | /* | ||
507 | * Can we support the voltage of the card? | ||
508 | */ | ||
509 | if (!host->ocr) | ||
510 | goto err; | ||
511 | |||
512 | /* | ||
513 | * Detect and init the card. | ||
514 | */ | ||
515 | err = mmc_sd_init_card(host, host->ocr, NULL); | ||
516 | if (err != MMC_ERR_NONE) | ||
517 | goto err; | ||
518 | |||
519 | mmc_release_host(host); | ||
520 | |||
521 | err = mmc_register_card(host->card); | ||
522 | if (err) | ||
523 | goto reclaim_host; | ||
524 | |||
525 | return 0; | ||
526 | |||
527 | reclaim_host: | ||
528 | mmc_claim_host(host); | ||
529 | mmc_remove_card(host->card); | ||
530 | host->card = NULL; | ||
531 | err: | ||
532 | mmc_detach_bus(host); | ||
533 | mmc_release_host(host); | ||
534 | |||
535 | return 0; | ||
536 | } | ||
537 | |||
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c new file mode 100644 index 000000000000..7dd720fa5895 --- /dev/null +++ b/drivers/mmc/core/mmc_ops.c | |||
@@ -0,0 +1,276 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/mmc_ops.h | ||
3 | * | ||
4 | * Copyright 2006-2007 Pierre Ossman | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or (at | ||
9 | * your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/types.h> | ||
13 | #include <asm/scatterlist.h> | ||
14 | #include <linux/scatterlist.h> | ||
15 | |||
16 | #include <linux/mmc/host.h> | ||
17 | #include <linux/mmc/card.h> | ||
18 | #include <linux/mmc/mmc.h> | ||
19 | |||
20 | #include "core.h" | ||
21 | #include "mmc_ops.h" | ||
22 | |||
23 | static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card) | ||
24 | { | ||
25 | int err; | ||
26 | struct mmc_command cmd; | ||
27 | |||
28 | BUG_ON(!host); | ||
29 | |||
30 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
31 | |||
32 | cmd.opcode = MMC_SELECT_CARD; | ||
33 | |||
34 | if (card) { | ||
35 | cmd.arg = card->rca << 16; | ||
36 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
37 | } else { | ||
38 | cmd.arg = 0; | ||
39 | cmd.flags = MMC_RSP_NONE | MMC_CMD_AC; | ||
40 | } | ||
41 | |||
42 | err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); | ||
43 | if (err != MMC_ERR_NONE) | ||
44 | return err; | ||
45 | |||
46 | return MMC_ERR_NONE; | ||
47 | } | ||
48 | |||
49 | int mmc_select_card(struct mmc_card *card) | ||
50 | { | ||
51 | BUG_ON(!card); | ||
52 | |||
53 | return _mmc_select_card(card->host, card); | ||
54 | } | ||
55 | |||
56 | int mmc_deselect_cards(struct mmc_host *host) | ||
57 | { | ||
58 | return _mmc_select_card(host, NULL); | ||
59 | } | ||
60 | |||
61 | int mmc_go_idle(struct mmc_host *host) | ||
62 | { | ||
63 | int err; | ||
64 | struct mmc_command cmd; | ||
65 | |||
66 | mmc_set_chip_select(host, MMC_CS_HIGH); | ||
67 | |||
68 | mmc_delay(1); | ||
69 | |||
70 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
71 | |||
72 | cmd.opcode = MMC_GO_IDLE_STATE; | ||
73 | cmd.arg = 0; | ||
74 | cmd.flags = MMC_RSP_NONE | MMC_CMD_BC; | ||
75 | |||
76 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
77 | |||
78 | mmc_delay(1); | ||
79 | |||
80 | mmc_set_chip_select(host, MMC_CS_DONTCARE); | ||
81 | |||
82 | mmc_delay(1); | ||
83 | |||
84 | return err; | ||
85 | } | ||
86 | |||
87 | int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | ||
88 | { | ||
89 | struct mmc_command cmd; | ||
90 | int i, err = 0; | ||
91 | |||
92 | BUG_ON(!host); | ||
93 | |||
94 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
95 | |||
96 | cmd.opcode = MMC_SEND_OP_COND; | ||
97 | cmd.arg = ocr; | ||
98 | cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; | ||
99 | |||
100 | for (i = 100; i; i--) { | ||
101 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
102 | if (err != MMC_ERR_NONE) | ||
103 | break; | ||
104 | |||
105 | if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) | ||
106 | break; | ||
107 | |||
108 | err = MMC_ERR_TIMEOUT; | ||
109 | |||
110 | mmc_delay(10); | ||
111 | } | ||
112 | |||
113 | if (rocr) | ||
114 | *rocr = cmd.resp[0]; | ||
115 | |||
116 | return err; | ||
117 | } | ||
118 | |||
119 | int mmc_all_send_cid(struct mmc_host *host, u32 *cid) | ||
120 | { | ||
121 | int err; | ||
122 | struct mmc_command cmd; | ||
123 | |||
124 | BUG_ON(!host); | ||
125 | BUG_ON(!cid); | ||
126 | |||
127 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
128 | |||
129 | cmd.opcode = MMC_ALL_SEND_CID; | ||
130 | cmd.arg = 0; | ||
131 | cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; | ||
132 | |||
133 | err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); | ||
134 | if (err != MMC_ERR_NONE) | ||
135 | return err; | ||
136 | |||
137 | memcpy(cid, cmd.resp, sizeof(u32) * 4); | ||
138 | |||
139 | return MMC_ERR_NONE; | ||
140 | } | ||
141 | |||
142 | int mmc_set_relative_addr(struct mmc_card *card) | ||
143 | { | ||
144 | int err; | ||
145 | struct mmc_command cmd; | ||
146 | |||
147 | BUG_ON(!card); | ||
148 | BUG_ON(!card->host); | ||
149 | |||
150 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
151 | |||
152 | cmd.opcode = MMC_SET_RELATIVE_ADDR; | ||
153 | cmd.arg = card->rca << 16; | ||
154 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
155 | |||
156 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); | ||
157 | if (err != MMC_ERR_NONE) | ||
158 | return err; | ||
159 | |||
160 | return MMC_ERR_NONE; | ||
161 | } | ||
162 | |||
163 | int mmc_send_csd(struct mmc_card *card, u32 *csd) | ||
164 | { | ||
165 | int err; | ||
166 | struct mmc_command cmd; | ||
167 | |||
168 | BUG_ON(!card); | ||
169 | BUG_ON(!card->host); | ||
170 | BUG_ON(!csd); | ||
171 | |||
172 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
173 | |||
174 | cmd.opcode = MMC_SEND_CSD; | ||
175 | cmd.arg = card->rca << 16; | ||
176 | cmd.flags = MMC_RSP_R2 | MMC_CMD_AC; | ||
177 | |||
178 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); | ||
179 | if (err != MMC_ERR_NONE) | ||
180 | return err; | ||
181 | |||
182 | memcpy(csd, cmd.resp, sizeof(u32) * 4); | ||
183 | |||
184 | return MMC_ERR_NONE; | ||
185 | } | ||
186 | |||
187 | int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd) | ||
188 | { | ||
189 | struct mmc_request mrq; | ||
190 | struct mmc_command cmd; | ||
191 | struct mmc_data data; | ||
192 | struct scatterlist sg; | ||
193 | |||
194 | BUG_ON(!card); | ||
195 | BUG_ON(!card->host); | ||
196 | BUG_ON(!ext_csd); | ||
197 | |||
198 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
199 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
200 | memset(&data, 0, sizeof(struct mmc_data)); | ||
201 | |||
202 | mrq.cmd = &cmd; | ||
203 | mrq.data = &data; | ||
204 | |||
205 | cmd.opcode = MMC_SEND_EXT_CSD; | ||
206 | cmd.arg = 0; | ||
207 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
208 | |||
209 | data.blksz = 512; | ||
210 | data.blocks = 1; | ||
211 | data.flags = MMC_DATA_READ; | ||
212 | data.sg = &sg; | ||
213 | data.sg_len = 1; | ||
214 | |||
215 | sg_init_one(&sg, ext_csd, 512); | ||
216 | |||
217 | mmc_set_data_timeout(&data, card, 0); | ||
218 | |||
219 | mmc_wait_for_req(card->host, &mrq); | ||
220 | |||
221 | if (cmd.error != MMC_ERR_NONE) | ||
222 | return cmd.error; | ||
223 | if (data.error != MMC_ERR_NONE) | ||
224 | return data.error; | ||
225 | |||
226 | return MMC_ERR_NONE; | ||
227 | } | ||
228 | |||
229 | int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value) | ||
230 | { | ||
231 | int err; | ||
232 | struct mmc_command cmd; | ||
233 | |||
234 | BUG_ON(!card); | ||
235 | BUG_ON(!card->host); | ||
236 | |||
237 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
238 | |||
239 | cmd.opcode = MMC_SWITCH; | ||
240 | cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | | ||
241 | (index << 16) | | ||
242 | (value << 8) | | ||
243 | set; | ||
244 | cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; | ||
245 | |||
246 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); | ||
247 | if (err != MMC_ERR_NONE) | ||
248 | return err; | ||
249 | |||
250 | return MMC_ERR_NONE; | ||
251 | } | ||
252 | |||
253 | int mmc_send_status(struct mmc_card *card, u32 *status) | ||
254 | { | ||
255 | int err; | ||
256 | struct mmc_command cmd; | ||
257 | |||
258 | BUG_ON(!card); | ||
259 | BUG_ON(!card->host); | ||
260 | |||
261 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
262 | |||
263 | cmd.opcode = MMC_SEND_STATUS; | ||
264 | cmd.arg = card->rca << 16; | ||
265 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
266 | |||
267 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); | ||
268 | if (err != MMC_ERR_NONE) | ||
269 | return err; | ||
270 | |||
271 | if (status) | ||
272 | *status = cmd.resp[0]; | ||
273 | |||
274 | return MMC_ERR_NONE; | ||
275 | } | ||
276 | |||
diff --git a/drivers/mmc/core/mmc_ops.h b/drivers/mmc/core/mmc_ops.h new file mode 100644 index 000000000000..7a481e8ca5ea --- /dev/null +++ b/drivers/mmc/core/mmc_ops.h | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/mmc_ops.h | ||
3 | * | ||
4 | * Copyright 2006-2007 Pierre Ossman | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or (at | ||
9 | * your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #ifndef _MMC_MMC_OPS_H | ||
13 | #define _MMC_MMC_OPS_H | ||
14 | |||
15 | int mmc_select_card(struct mmc_card *card); | ||
16 | int mmc_deselect_cards(struct mmc_host *host); | ||
17 | int mmc_go_idle(struct mmc_host *host); | ||
18 | int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr); | ||
19 | int mmc_all_send_cid(struct mmc_host *host, u32 *cid); | ||
20 | int mmc_set_relative_addr(struct mmc_card *card); | ||
21 | int mmc_send_csd(struct mmc_card *card, u32 *csd); | ||
22 | int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd); | ||
23 | int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value); | ||
24 | int mmc_send_status(struct mmc_card *card, u32 *status); | ||
25 | |||
26 | #endif | ||
27 | |||
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c new file mode 100644 index 000000000000..c1dfd03d559a --- /dev/null +++ b/drivers/mmc/core/sd.c | |||
@@ -0,0 +1,587 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/sd.c | ||
3 | * | ||
4 | * Copyright (C) 2003-2004 Russell King, All Rights Reserved. | ||
5 | * SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. | ||
6 | * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/err.h> | ||
14 | |||
15 | #include <linux/mmc/host.h> | ||
16 | #include <linux/mmc/card.h> | ||
17 | #include <linux/mmc/mmc.h> | ||
18 | |||
19 | #include "core.h" | ||
20 | #include "sysfs.h" | ||
21 | #include "mmc_ops.h" | ||
22 | #include "sd_ops.h" | ||
23 | |||
24 | #include "core.h" | ||
25 | |||
26 | static const unsigned int tran_exp[] = { | ||
27 | 10000, 100000, 1000000, 10000000, | ||
28 | 0, 0, 0, 0 | ||
29 | }; | ||
30 | |||
31 | static const unsigned char tran_mant[] = { | ||
32 | 0, 10, 12, 13, 15, 20, 25, 30, | ||
33 | 35, 40, 45, 50, 55, 60, 70, 80, | ||
34 | }; | ||
35 | |||
36 | static const unsigned int tacc_exp[] = { | ||
37 | 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, | ||
38 | }; | ||
39 | |||
40 | static const unsigned int tacc_mant[] = { | ||
41 | 0, 10, 12, 13, 15, 20, 25, 30, | ||
42 | 35, 40, 45, 50, 55, 60, 70, 80, | ||
43 | }; | ||
44 | |||
45 | #define UNSTUFF_BITS(resp,start,size) \ | ||
46 | ({ \ | ||
47 | const int __size = size; \ | ||
48 | const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \ | ||
49 | const int __off = 3 - ((start) / 32); \ | ||
50 | const int __shft = (start) & 31; \ | ||
51 | u32 __res; \ | ||
52 | \ | ||
53 | __res = resp[__off] >> __shft; \ | ||
54 | if (__size + __shft > 32) \ | ||
55 | __res |= resp[__off-1] << ((32 - __shft) % 32); \ | ||
56 | __res & __mask; \ | ||
57 | }) | ||
58 | |||
59 | /* | ||
60 | * Given the decoded CSD structure, decode the raw CID to our CID structure. | ||
61 | */ | ||
62 | static void mmc_decode_cid(struct mmc_card *card) | ||
63 | { | ||
64 | u32 *resp = card->raw_cid; | ||
65 | |||
66 | memset(&card->cid, 0, sizeof(struct mmc_cid)); | ||
67 | |||
68 | /* | ||
69 | * SD doesn't currently have a version field so we will | ||
70 | * have to assume we can parse this. | ||
71 | */ | ||
72 | card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); | ||
73 | card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); | ||
74 | card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); | ||
75 | card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); | ||
76 | card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); | ||
77 | card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); | ||
78 | card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); | ||
79 | card->cid.hwrev = UNSTUFF_BITS(resp, 60, 4); | ||
80 | card->cid.fwrev = UNSTUFF_BITS(resp, 56, 4); | ||
81 | card->cid.serial = UNSTUFF_BITS(resp, 24, 32); | ||
82 | card->cid.year = UNSTUFF_BITS(resp, 12, 8); | ||
83 | card->cid.month = UNSTUFF_BITS(resp, 8, 4); | ||
84 | |||
85 | card->cid.year += 2000; /* SD cards year offset */ | ||
86 | } | ||
87 | |||
88 | /* | ||
89 | * Given a 128-bit response, decode to our card CSD structure. | ||
90 | */ | ||
91 | static int mmc_decode_csd(struct mmc_card *card) | ||
92 | { | ||
93 | struct mmc_csd *csd = &card->csd; | ||
94 | unsigned int e, m, csd_struct; | ||
95 | u32 *resp = card->raw_csd; | ||
96 | |||
97 | csd_struct = UNSTUFF_BITS(resp, 126, 2); | ||
98 | |||
99 | switch (csd_struct) { | ||
100 | case 0: | ||
101 | m = UNSTUFF_BITS(resp, 115, 4); | ||
102 | e = UNSTUFF_BITS(resp, 112, 3); | ||
103 | csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10; | ||
104 | csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100; | ||
105 | |||
106 | m = UNSTUFF_BITS(resp, 99, 4); | ||
107 | e = UNSTUFF_BITS(resp, 96, 3); | ||
108 | csd->max_dtr = tran_exp[e] * tran_mant[m]; | ||
109 | csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); | ||
110 | |||
111 | e = UNSTUFF_BITS(resp, 47, 3); | ||
112 | m = UNSTUFF_BITS(resp, 62, 12); | ||
113 | csd->capacity = (1 + m) << (e + 2); | ||
114 | |||
115 | csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); | ||
116 | csd->read_partial = UNSTUFF_BITS(resp, 79, 1); | ||
117 | csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); | ||
118 | csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); | ||
119 | csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); | ||
120 | csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); | ||
121 | csd->write_partial = UNSTUFF_BITS(resp, 21, 1); | ||
122 | break; | ||
123 | case 1: | ||
124 | /* | ||
125 | * This is a block-addressed SDHC card. Most | ||
126 | * interesting fields are unused and have fixed | ||
127 | * values. To avoid getting tripped by buggy cards, | ||
128 | * we assume those fixed values ourselves. | ||
129 | */ | ||
130 | mmc_card_set_blockaddr(card); | ||
131 | |||
132 | csd->tacc_ns = 0; /* Unused */ | ||
133 | csd->tacc_clks = 0; /* Unused */ | ||
134 | |||
135 | m = UNSTUFF_BITS(resp, 99, 4); | ||
136 | e = UNSTUFF_BITS(resp, 96, 3); | ||
137 | csd->max_dtr = tran_exp[e] * tran_mant[m]; | ||
138 | csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); | ||
139 | |||
140 | m = UNSTUFF_BITS(resp, 48, 22); | ||
141 | csd->capacity = (1 + m) << 10; | ||
142 | |||
143 | csd->read_blkbits = 9; | ||
144 | csd->read_partial = 0; | ||
145 | csd->write_misalign = 0; | ||
146 | csd->read_misalign = 0; | ||
147 | csd->r2w_factor = 4; /* Unused */ | ||
148 | csd->write_blkbits = 9; | ||
149 | csd->write_partial = 0; | ||
150 | break; | ||
151 | default: | ||
152 | printk("%s: unrecognised CSD structure version %d\n", | ||
153 | mmc_hostname(card->host), csd_struct); | ||
154 | return -EINVAL; | ||
155 | } | ||
156 | |||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | /* | ||
161 | * Given a 64-bit response, decode to our card SCR structure. | ||
162 | */ | ||
163 | static int mmc_decode_scr(struct mmc_card *card) | ||
164 | { | ||
165 | struct sd_scr *scr = &card->scr; | ||
166 | unsigned int scr_struct; | ||
167 | u32 resp[4]; | ||
168 | |||
169 | BUG_ON(!mmc_card_sd(card)); | ||
170 | |||
171 | resp[3] = card->raw_scr[1]; | ||
172 | resp[2] = card->raw_scr[0]; | ||
173 | |||
174 | scr_struct = UNSTUFF_BITS(resp, 60, 4); | ||
175 | if (scr_struct != 0) { | ||
176 | printk("%s: unrecognised SCR structure version %d\n", | ||
177 | mmc_hostname(card->host), scr_struct); | ||
178 | return -EINVAL; | ||
179 | } | ||
180 | |||
181 | scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4); | ||
182 | scr->bus_widths = UNSTUFF_BITS(resp, 48, 4); | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | /* | ||
188 | * Fetches and decodes switch information | ||
189 | */ | ||
190 | static int mmc_read_switch(struct mmc_card *card) | ||
191 | { | ||
192 | int err; | ||
193 | u8 *status; | ||
194 | |||
195 | err = MMC_ERR_FAILED; | ||
196 | |||
197 | status = kmalloc(64, GFP_KERNEL); | ||
198 | if (!status) { | ||
199 | printk("%s: could not allocate a buffer for switch " | ||
200 | "capabilities.\n", | ||
201 | mmc_hostname(card->host)); | ||
202 | return err; | ||
203 | } | ||
204 | |||
205 | err = mmc_sd_switch(card, 0, 0, 1, status); | ||
206 | if (err != MMC_ERR_NONE) { | ||
207 | /* | ||
208 | * Card not supporting high-speed will ignore the | ||
209 | * command. | ||
210 | */ | ||
211 | err = MMC_ERR_NONE; | ||
212 | goto out; | ||
213 | } | ||
214 | |||
215 | if (status[13] & 0x02) | ||
216 | card->sw_caps.hs_max_dtr = 50000000; | ||
217 | |||
218 | out: | ||
219 | kfree(status); | ||
220 | |||
221 | return err; | ||
222 | } | ||
223 | |||
224 | /* | ||
225 | * Test if the card supports high-speed mode and, if so, switch to it. | ||
226 | */ | ||
227 | static int mmc_switch_hs(struct mmc_card *card) | ||
228 | { | ||
229 | int err; | ||
230 | u8 *status; | ||
231 | |||
232 | if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) | ||
233 | return MMC_ERR_NONE; | ||
234 | |||
235 | if (card->sw_caps.hs_max_dtr == 0) | ||
236 | return MMC_ERR_NONE; | ||
237 | |||
238 | err = MMC_ERR_FAILED; | ||
239 | |||
240 | status = kmalloc(64, GFP_KERNEL); | ||
241 | if (!status) { | ||
242 | printk("%s: could not allocate a buffer for switch " | ||
243 | "capabilities.\n", | ||
244 | mmc_hostname(card->host)); | ||
245 | return err; | ||
246 | } | ||
247 | |||
248 | err = mmc_sd_switch(card, 1, 0, 1, status); | ||
249 | if (err != MMC_ERR_NONE) | ||
250 | goto out; | ||
251 | |||
252 | if ((status[16] & 0xF) != 1) { | ||
253 | printk(KERN_WARNING "%s: Problem switching card " | ||
254 | "into high-speed mode!\n", | ||
255 | mmc_hostname(card->host)); | ||
256 | } else { | ||
257 | mmc_card_set_highspeed(card); | ||
258 | mmc_set_timing(card->host, MMC_TIMING_SD_HS); | ||
259 | } | ||
260 | |||
261 | out: | ||
262 | kfree(status); | ||
263 | |||
264 | return err; | ||
265 | } | ||
266 | |||
267 | /* | ||
268 | * Handle the detection and initialisation of a card. | ||
269 | * | ||
270 | * In the case of a resume, "curcard" will contain the card | ||
271 | * we're trying to reinitialise. | ||
272 | */ | ||
273 | static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | ||
274 | struct mmc_card *oldcard) | ||
275 | { | ||
276 | struct mmc_card *card; | ||
277 | int err; | ||
278 | u32 cid[4]; | ||
279 | unsigned int max_dtr; | ||
280 | |||
281 | BUG_ON(!host); | ||
282 | BUG_ON(!host->claimed); | ||
283 | |||
284 | /* | ||
285 | * Since we're changing the OCR value, we seem to | ||
286 | * need to tell some cards to go back to the idle | ||
287 | * state. We wait 1ms to give cards time to | ||
288 | * respond. | ||
289 | */ | ||
290 | mmc_go_idle(host); | ||
291 | |||
292 | /* | ||
293 | * If SD_SEND_IF_COND indicates an SD 2.0 | ||
294 | * compliant card and we should set bit 30 | ||
295 | * of the ocr to indicate that we can handle | ||
296 | * block-addressed SDHC cards. | ||
297 | */ | ||
298 | err = mmc_send_if_cond(host, ocr); | ||
299 | if (err == MMC_ERR_NONE) | ||
300 | ocr |= 1 << 30; | ||
301 | |||
302 | err = mmc_send_app_op_cond(host, ocr, NULL); | ||
303 | if (err != MMC_ERR_NONE) | ||
304 | goto err; | ||
305 | |||
306 | /* | ||
307 | * Fetch CID from card. | ||
308 | */ | ||
309 | err = mmc_all_send_cid(host, cid); | ||
310 | if (err != MMC_ERR_NONE) | ||
311 | goto err; | ||
312 | |||
313 | if (oldcard) { | ||
314 | if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) | ||
315 | goto err; | ||
316 | |||
317 | card = oldcard; | ||
318 | } else { | ||
319 | /* | ||
320 | * Allocate card structure. | ||
321 | */ | ||
322 | card = mmc_alloc_card(host); | ||
323 | if (IS_ERR(card)) | ||
324 | goto err; | ||
325 | |||
326 | card->type = MMC_TYPE_SD; | ||
327 | memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); | ||
328 | } | ||
329 | |||
330 | /* | ||
331 | * Set card RCA. | ||
332 | */ | ||
333 | err = mmc_send_relative_addr(host, &card->rca); | ||
334 | if (err != MMC_ERR_NONE) | ||
335 | goto free_card; | ||
336 | |||
337 | mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); | ||
338 | |||
339 | if (!oldcard) { | ||
340 | /* | ||
341 | * Fetch CSD from card. | ||
342 | */ | ||
343 | err = mmc_send_csd(card, card->raw_csd); | ||
344 | if (err != MMC_ERR_NONE) | ||
345 | goto free_card; | ||
346 | |||
347 | err = mmc_decode_csd(card); | ||
348 | if (err < 0) | ||
349 | goto free_card; | ||
350 | |||
351 | mmc_decode_cid(card); | ||
352 | } | ||
353 | |||
354 | /* | ||
355 | * Select card, as all following commands rely on that. | ||
356 | */ | ||
357 | err = mmc_select_card(card); | ||
358 | if (err != MMC_ERR_NONE) | ||
359 | goto free_card; | ||
360 | |||
361 | if (!oldcard) { | ||
362 | /* | ||
363 | * Fetch SCR from card. | ||
364 | */ | ||
365 | err = mmc_app_send_scr(card, card->raw_scr); | ||
366 | if (err != MMC_ERR_NONE) | ||
367 | goto free_card; | ||
368 | |||
369 | err = mmc_decode_scr(card); | ||
370 | if (err < 0) | ||
371 | goto free_card; | ||
372 | |||
373 | /* | ||
374 | * Fetch switch information from card. | ||
375 | */ | ||
376 | err = mmc_read_switch(card); | ||
377 | if (err != MMC_ERR_NONE) | ||
378 | goto free_card; | ||
379 | } | ||
380 | |||
381 | /* | ||
382 | * Attempt to change to high-speed (if supported) | ||
383 | */ | ||
384 | err = mmc_switch_hs(card); | ||
385 | if (err != MMC_ERR_NONE) | ||
386 | goto free_card; | ||
387 | |||
388 | /* | ||
389 | * Compute bus speed. | ||
390 | */ | ||
391 | max_dtr = (unsigned int)-1; | ||
392 | |||
393 | if (mmc_card_highspeed(card)) { | ||
394 | if (max_dtr > card->sw_caps.hs_max_dtr) | ||
395 | max_dtr = card->sw_caps.hs_max_dtr; | ||
396 | } else if (max_dtr > card->csd.max_dtr) { | ||
397 | max_dtr = card->csd.max_dtr; | ||
398 | } | ||
399 | |||
400 | mmc_set_clock(host, max_dtr); | ||
401 | |||
402 | /* | ||
403 | * Switch to wider bus (if supported). | ||
404 | */ | ||
405 | if ((host->caps && MMC_CAP_4_BIT_DATA) && | ||
406 | (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { | ||
407 | err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); | ||
408 | if (err != MMC_ERR_NONE) | ||
409 | goto free_card; | ||
410 | |||
411 | mmc_set_bus_width(host, MMC_BUS_WIDTH_4); | ||
412 | } | ||
413 | |||
414 | if (!oldcard) | ||
415 | host->card = card; | ||
416 | |||
417 | return MMC_ERR_NONE; | ||
418 | |||
419 | free_card: | ||
420 | if (!oldcard) | ||
421 | mmc_remove_card(card); | ||
422 | err: | ||
423 | |||
424 | return MMC_ERR_FAILED; | ||
425 | } | ||
426 | |||
427 | /* | ||
428 | * Host is being removed. Free up the current card. | ||
429 | */ | ||
430 | static void mmc_sd_remove(struct mmc_host *host) | ||
431 | { | ||
432 | BUG_ON(!host); | ||
433 | BUG_ON(!host->card); | ||
434 | |||
435 | mmc_remove_card(host->card); | ||
436 | host->card = NULL; | ||
437 | } | ||
438 | |||
439 | /* | ||
440 | * Card detection callback from host. | ||
441 | */ | ||
442 | static void mmc_sd_detect(struct mmc_host *host) | ||
443 | { | ||
444 | int err; | ||
445 | |||
446 | BUG_ON(!host); | ||
447 | BUG_ON(!host->card); | ||
448 | |||
449 | mmc_claim_host(host); | ||
450 | |||
451 | /* | ||
452 | * Just check if our card has been removed. | ||
453 | */ | ||
454 | err = mmc_send_status(host->card, NULL); | ||
455 | |||
456 | mmc_release_host(host); | ||
457 | |||
458 | if (err != MMC_ERR_NONE) { | ||
459 | mmc_remove_card(host->card); | ||
460 | host->card = NULL; | ||
461 | |||
462 | mmc_claim_host(host); | ||
463 | mmc_detach_bus(host); | ||
464 | mmc_release_host(host); | ||
465 | } | ||
466 | } | ||
467 | |||
468 | #ifdef CONFIG_MMC_UNSAFE_RESUME | ||
469 | |||
470 | /* | ||
471 | * Suspend callback from host. | ||
472 | */ | ||
473 | static void mmc_sd_suspend(struct mmc_host *host) | ||
474 | { | ||
475 | BUG_ON(!host); | ||
476 | BUG_ON(!host->card); | ||
477 | |||
478 | mmc_claim_host(host); | ||
479 | mmc_deselect_cards(host); | ||
480 | host->card->state &= ~MMC_STATE_HIGHSPEED; | ||
481 | mmc_release_host(host); | ||
482 | } | ||
483 | |||
484 | /* | ||
485 | * Resume callback from host. | ||
486 | * | ||
487 | * This function tries to determine if the same card is still present | ||
488 | * and, if so, restore all state to it. | ||
489 | */ | ||
490 | static void mmc_sd_resume(struct mmc_host *host) | ||
491 | { | ||
492 | int err; | ||
493 | |||
494 | BUG_ON(!host); | ||
495 | BUG_ON(!host->card); | ||
496 | |||
497 | mmc_claim_host(host); | ||
498 | |||
499 | err = mmc_sd_init_card(host, host->ocr, host->card); | ||
500 | if (err != MMC_ERR_NONE) { | ||
501 | mmc_remove_card(host->card); | ||
502 | host->card = NULL; | ||
503 | |||
504 | mmc_detach_bus(host); | ||
505 | } | ||
506 | |||
507 | mmc_release_host(host); | ||
508 | } | ||
509 | |||
510 | #else | ||
511 | |||
512 | #define mmc_sd_suspend NULL | ||
513 | #define mmc_sd_resume NULL | ||
514 | |||
515 | #endif | ||
516 | |||
517 | static const struct mmc_bus_ops mmc_sd_ops = { | ||
518 | .remove = mmc_sd_remove, | ||
519 | .detect = mmc_sd_detect, | ||
520 | .suspend = mmc_sd_suspend, | ||
521 | .resume = mmc_sd_resume, | ||
522 | }; | ||
523 | |||
524 | /* | ||
525 | * Starting point for SD card init. | ||
526 | */ | ||
527 | int mmc_attach_sd(struct mmc_host *host, u32 ocr) | ||
528 | { | ||
529 | int err; | ||
530 | |||
531 | BUG_ON(!host); | ||
532 | BUG_ON(!host->claimed); | ||
533 | |||
534 | mmc_attach_bus(host, &mmc_sd_ops); | ||
535 | |||
536 | /* | ||
537 | * Sanity check the voltages that the card claims to | ||
538 | * support. | ||
539 | */ | ||
540 | if (ocr & 0x7F) { | ||
541 | printk(KERN_WARNING "%s: card claims to support voltages " | ||
542 | "below the defined range. These will be ignored.\n", | ||
543 | mmc_hostname(host)); | ||
544 | ocr &= ~0x7F; | ||
545 | } | ||
546 | |||
547 | if (ocr & MMC_VDD_165_195) { | ||
548 | printk(KERN_WARNING "%s: SD card claims to support the " | ||
549 | "incompletely defined 'low voltage range'. This " | ||
550 | "will be ignored.\n", mmc_hostname(host)); | ||
551 | ocr &= ~MMC_VDD_165_195; | ||
552 | } | ||
553 | |||
554 | host->ocr = mmc_select_voltage(host, ocr); | ||
555 | |||
556 | /* | ||
557 | * Can we support the voltage(s) of the card(s)? | ||
558 | */ | ||
559 | if (!host->ocr) | ||
560 | goto err; | ||
561 | |||
562 | /* | ||
563 | * Detect and init the card. | ||
564 | */ | ||
565 | err = mmc_sd_init_card(host, host->ocr, NULL); | ||
566 | if (err != MMC_ERR_NONE) | ||
567 | goto err; | ||
568 | |||
569 | mmc_release_host(host); | ||
570 | |||
571 | err = mmc_register_card(host->card); | ||
572 | if (err) | ||
573 | goto reclaim_host; | ||
574 | |||
575 | return 0; | ||
576 | |||
577 | reclaim_host: | ||
578 | mmc_claim_host(host); | ||
579 | mmc_remove_card(host->card); | ||
580 | host->card = NULL; | ||
581 | err: | ||
582 | mmc_detach_bus(host); | ||
583 | mmc_release_host(host); | ||
584 | |||
585 | return 0; | ||
586 | } | ||
587 | |||
diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c new file mode 100644 index 000000000000..9697ce581101 --- /dev/null +++ b/drivers/mmc/core/sd_ops.c | |||
@@ -0,0 +1,316 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/sd_ops.h | ||
3 | * | ||
4 | * Copyright 2006-2007 Pierre Ossman | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or (at | ||
9 | * your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/types.h> | ||
13 | #include <asm/scatterlist.h> | ||
14 | #include <linux/scatterlist.h> | ||
15 | |||
16 | #include <linux/mmc/host.h> | ||
17 | #include <linux/mmc/card.h> | ||
18 | #include <linux/mmc/mmc.h> | ||
19 | #include <linux/mmc/sd.h> | ||
20 | |||
21 | #include "core.h" | ||
22 | #include "sd_ops.h" | ||
23 | |||
24 | /** | ||
25 | * mmc_wait_for_app_cmd - start an application command and wait for | ||
26 | completion | ||
27 | * @host: MMC host to start command | ||
28 | * @rca: RCA to send MMC_APP_CMD to | ||
29 | * @cmd: MMC command to start | ||
30 | * @retries: maximum number of retries | ||
31 | * | ||
32 | * Sends a MMC_APP_CMD, checks the card response, sends the command | ||
33 | * in the parameter and waits for it to complete. Return any error | ||
34 | * that occurred while the command was executing. Do not attempt to | ||
35 | * parse the response. | ||
36 | */ | ||
37 | int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card, | ||
38 | struct mmc_command *cmd, int retries) | ||
39 | { | ||
40 | struct mmc_request mrq; | ||
41 | |||
42 | int i, err; | ||
43 | |||
44 | BUG_ON(!cmd); | ||
45 | BUG_ON(retries < 0); | ||
46 | |||
47 | err = MMC_ERR_INVALID; | ||
48 | |||
49 | /* | ||
50 | * We have to resend MMC_APP_CMD for each attempt so | ||
51 | * we cannot use the retries field in mmc_command. | ||
52 | */ | ||
53 | for (i = 0;i <= retries;i++) { | ||
54 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
55 | |||
56 | err = mmc_app_cmd(host, card); | ||
57 | if (err != MMC_ERR_NONE) | ||
58 | continue; | ||
59 | |||
60 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
61 | |||
62 | memset(cmd->resp, 0, sizeof(cmd->resp)); | ||
63 | cmd->retries = 0; | ||
64 | |||
65 | mrq.cmd = cmd; | ||
66 | cmd->data = NULL; | ||
67 | |||
68 | mmc_wait_for_req(host, &mrq); | ||
69 | |||
70 | err = cmd->error; | ||
71 | if (cmd->error == MMC_ERR_NONE) | ||
72 | break; | ||
73 | } | ||
74 | |||
75 | return err; | ||
76 | } | ||
77 | |||
78 | EXPORT_SYMBOL(mmc_wait_for_app_cmd); | ||
79 | |||
80 | int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card) | ||
81 | { | ||
82 | int err; | ||
83 | struct mmc_command cmd; | ||
84 | |||
85 | BUG_ON(!host); | ||
86 | BUG_ON(card && (card->host != host)); | ||
87 | |||
88 | cmd.opcode = MMC_APP_CMD; | ||
89 | |||
90 | if (card) { | ||
91 | cmd.arg = card->rca << 16; | ||
92 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
93 | } else { | ||
94 | cmd.arg = 0; | ||
95 | cmd.flags = MMC_RSP_R1 | MMC_CMD_BCR; | ||
96 | } | ||
97 | |||
98 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
99 | if (err != MMC_ERR_NONE) | ||
100 | return err; | ||
101 | |||
102 | /* Check that card supported application commands */ | ||
103 | if (!(cmd.resp[0] & R1_APP_CMD)) | ||
104 | return MMC_ERR_FAILED; | ||
105 | |||
106 | return MMC_ERR_NONE; | ||
107 | } | ||
108 | |||
109 | int mmc_app_set_bus_width(struct mmc_card *card, int width) | ||
110 | { | ||
111 | int err; | ||
112 | struct mmc_command cmd; | ||
113 | |||
114 | BUG_ON(!card); | ||
115 | BUG_ON(!card->host); | ||
116 | |||
117 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
118 | |||
119 | cmd.opcode = SD_APP_SET_BUS_WIDTH; | ||
120 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
121 | |||
122 | switch (width) { | ||
123 | case MMC_BUS_WIDTH_1: | ||
124 | cmd.arg = SD_BUS_WIDTH_1; | ||
125 | break; | ||
126 | case MMC_BUS_WIDTH_4: | ||
127 | cmd.arg = SD_BUS_WIDTH_4; | ||
128 | break; | ||
129 | default: | ||
130 | return MMC_ERR_INVALID; | ||
131 | } | ||
132 | |||
133 | err = mmc_wait_for_app_cmd(card->host, card, &cmd, MMC_CMD_RETRIES); | ||
134 | if (err != MMC_ERR_NONE) | ||
135 | return err; | ||
136 | |||
137 | return MMC_ERR_NONE; | ||
138 | } | ||
139 | |||
140 | int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | ||
141 | { | ||
142 | struct mmc_command cmd; | ||
143 | int i, err = 0; | ||
144 | |||
145 | BUG_ON(!host); | ||
146 | |||
147 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
148 | |||
149 | cmd.opcode = SD_APP_OP_COND; | ||
150 | cmd.arg = ocr; | ||
151 | cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; | ||
152 | |||
153 | for (i = 100; i; i--) { | ||
154 | err = mmc_wait_for_app_cmd(host, NULL, &cmd, MMC_CMD_RETRIES); | ||
155 | if (err != MMC_ERR_NONE) | ||
156 | break; | ||
157 | |||
158 | if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) | ||
159 | break; | ||
160 | |||
161 | err = MMC_ERR_TIMEOUT; | ||
162 | |||
163 | mmc_delay(10); | ||
164 | } | ||
165 | |||
166 | if (rocr) | ||
167 | *rocr = cmd.resp[0]; | ||
168 | |||
169 | return err; | ||
170 | } | ||
171 | |||
172 | int mmc_send_if_cond(struct mmc_host *host, u32 ocr) | ||
173 | { | ||
174 | struct mmc_command cmd; | ||
175 | int err; | ||
176 | static const u8 test_pattern = 0xAA; | ||
177 | |||
178 | /* | ||
179 | * To support SD 2.0 cards, we must always invoke SD_SEND_IF_COND | ||
180 | * before SD_APP_OP_COND. This command will harmlessly fail for | ||
181 | * SD 1.0 cards. | ||
182 | */ | ||
183 | cmd.opcode = SD_SEND_IF_COND; | ||
184 | cmd.arg = ((ocr & 0xFF8000) != 0) << 8 | test_pattern; | ||
185 | cmd.flags = MMC_RSP_R7 | MMC_CMD_BCR; | ||
186 | |||
187 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
188 | if (err != MMC_ERR_NONE) | ||
189 | return err; | ||
190 | |||
191 | if ((cmd.resp[0] & 0xFF) != test_pattern) | ||
192 | return MMC_ERR_FAILED; | ||
193 | |||
194 | return MMC_ERR_NONE; | ||
195 | } | ||
196 | |||
197 | int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca) | ||
198 | { | ||
199 | int err; | ||
200 | struct mmc_command cmd; | ||
201 | |||
202 | BUG_ON(!host); | ||
203 | BUG_ON(!rca); | ||
204 | |||
205 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
206 | |||
207 | cmd.opcode = SD_SEND_RELATIVE_ADDR; | ||
208 | cmd.arg = 0; | ||
209 | cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; | ||
210 | |||
211 | err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); | ||
212 | if (err != MMC_ERR_NONE) | ||
213 | return err; | ||
214 | |||
215 | *rca = cmd.resp[0] >> 16; | ||
216 | |||
217 | return MMC_ERR_NONE; | ||
218 | } | ||
219 | |||
220 | int mmc_app_send_scr(struct mmc_card *card, u32 *scr) | ||
221 | { | ||
222 | int err; | ||
223 | struct mmc_request mrq; | ||
224 | struct mmc_command cmd; | ||
225 | struct mmc_data data; | ||
226 | struct scatterlist sg; | ||
227 | |||
228 | BUG_ON(!card); | ||
229 | BUG_ON(!card->host); | ||
230 | BUG_ON(!scr); | ||
231 | |||
232 | err = mmc_app_cmd(card->host, card); | ||
233 | if (err != MMC_ERR_NONE) | ||
234 | return err; | ||
235 | |||
236 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
237 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
238 | memset(&data, 0, sizeof(struct mmc_data)); | ||
239 | |||
240 | mrq.cmd = &cmd; | ||
241 | mrq.data = &data; | ||
242 | |||
243 | cmd.opcode = SD_APP_SEND_SCR; | ||
244 | cmd.arg = 0; | ||
245 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
246 | |||
247 | data.blksz = 8; | ||
248 | data.blocks = 1; | ||
249 | data.flags = MMC_DATA_READ; | ||
250 | data.sg = &sg; | ||
251 | data.sg_len = 1; | ||
252 | |||
253 | sg_init_one(&sg, scr, 8); | ||
254 | |||
255 | mmc_set_data_timeout(&data, card, 0); | ||
256 | |||
257 | mmc_wait_for_req(card->host, &mrq); | ||
258 | |||
259 | if (cmd.error != MMC_ERR_NONE) | ||
260 | return cmd.error; | ||
261 | if (data.error != MMC_ERR_NONE) | ||
262 | return data.error; | ||
263 | |||
264 | scr[0] = ntohl(scr[0]); | ||
265 | scr[1] = ntohl(scr[1]); | ||
266 | |||
267 | return MMC_ERR_NONE; | ||
268 | } | ||
269 | |||
270 | int mmc_sd_switch(struct mmc_card *card, int mode, int group, | ||
271 | u8 value, u8 *resp) | ||
272 | { | ||
273 | struct mmc_request mrq; | ||
274 | struct mmc_command cmd; | ||
275 | struct mmc_data data; | ||
276 | struct scatterlist sg; | ||
277 | |||
278 | BUG_ON(!card); | ||
279 | BUG_ON(!card->host); | ||
280 | |||
281 | mode = !!mode; | ||
282 | value &= 0xF; | ||
283 | |||
284 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
285 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
286 | memset(&data, 0, sizeof(struct mmc_data)); | ||
287 | |||
288 | mrq.cmd = &cmd; | ||
289 | mrq.data = &data; | ||
290 | |||
291 | cmd.opcode = SD_SWITCH; | ||
292 | cmd.arg = mode << 31 | 0x00FFFFFF; | ||
293 | cmd.arg &= ~(0xF << (group * 4)); | ||
294 | cmd.arg |= value << (group * 4); | ||
295 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
296 | |||
297 | data.blksz = 64; | ||
298 | data.blocks = 1; | ||
299 | data.flags = MMC_DATA_READ; | ||
300 | data.sg = &sg; | ||
301 | data.sg_len = 1; | ||
302 | |||
303 | sg_init_one(&sg, resp, 64); | ||
304 | |||
305 | mmc_set_data_timeout(&data, card, 0); | ||
306 | |||
307 | mmc_wait_for_req(card->host, &mrq); | ||
308 | |||
309 | if (cmd.error != MMC_ERR_NONE) | ||
310 | return cmd.error; | ||
311 | if (data.error != MMC_ERR_NONE) | ||
312 | return data.error; | ||
313 | |||
314 | return MMC_ERR_NONE; | ||
315 | } | ||
316 | |||
diff --git a/drivers/mmc/core/sd_ops.h b/drivers/mmc/core/sd_ops.h new file mode 100644 index 000000000000..1240fddba5e3 --- /dev/null +++ b/drivers/mmc/core/sd_ops.h | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/sd_ops.h | ||
3 | * | ||
4 | * Copyright 2006-2007 Pierre Ossman | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or (at | ||
9 | * your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #ifndef _MMC_SD_OPS_H | ||
13 | #define _MMC_SD_OPS_H | ||
14 | |||
15 | int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card); | ||
16 | int mmc_app_set_bus_width(struct mmc_card *card, int width); | ||
17 | int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr); | ||
18 | int mmc_send_if_cond(struct mmc_host *host, u32 ocr); | ||
19 | int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca); | ||
20 | int mmc_app_send_scr(struct mmc_card *card, u32 *scr); | ||
21 | int mmc_sd_switch(struct mmc_card *card, int mode, int group, | ||
22 | u8 value, u8 *resp); | ||
23 | |||
24 | #endif | ||
25 | |||
diff --git a/drivers/mmc/mmc_sysfs.c b/drivers/mmc/core/sysfs.c index e0e82d849d5f..843b1fbba557 100644 --- a/drivers/mmc/mmc_sysfs.c +++ b/drivers/mmc/core/sysfs.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/mmc_sysfs.c | 2 | * linux/drivers/mmc/core/sysfs.c |
3 | * | 3 | * |
4 | * Copyright (C) 2003 Russell King, All Rights Reserved. | 4 | * Copyright (C) 2003 Russell King, All Rights Reserved. |
5 | * | 5 | * |
@@ -18,7 +18,7 @@ | |||
18 | #include <linux/mmc/card.h> | 18 | #include <linux/mmc/card.h> |
19 | #include <linux/mmc/host.h> | 19 | #include <linux/mmc/host.h> |
20 | 20 | ||
21 | #include "mmc.h" | 21 | #include "sysfs.h" |
22 | 22 | ||
23 | #define dev_to_mmc_card(d) container_of(d, struct mmc_card, dev) | 23 | #define dev_to_mmc_card(d) container_of(d, struct mmc_card, dev) |
24 | #define to_mmc_driver(d) container_of(d, struct mmc_driver, drv) | 24 | #define to_mmc_driver(d) container_of(d, struct mmc_driver, drv) |
@@ -72,12 +72,11 @@ static void mmc_release_card(struct device *dev) | |||
72 | /* | 72 | /* |
73 | * This currently matches any MMC driver to any MMC card - drivers | 73 | * This currently matches any MMC driver to any MMC card - drivers |
74 | * themselves make the decision whether to drive this card in their | 74 | * themselves make the decision whether to drive this card in their |
75 | * probe method. However, we force "bad" cards to fail. | 75 | * probe method. |
76 | */ | 76 | */ |
77 | static int mmc_bus_match(struct device *dev, struct device_driver *drv) | 77 | static int mmc_bus_match(struct device *dev, struct device_driver *drv) |
78 | { | 78 | { |
79 | struct mmc_card *card = dev_to_mmc_card(dev); | 79 | return 1; |
80 | return !mmc_card_bad(card); | ||
81 | } | 80 | } |
82 | 81 | ||
83 | static int | 82 | static int |
@@ -217,6 +216,8 @@ int mmc_register_card(struct mmc_card *card) | |||
217 | device_del(&card->dev); | 216 | device_del(&card->dev); |
218 | } | 217 | } |
219 | } | 218 | } |
219 | if (ret == 0) | ||
220 | mmc_card_set_present(card); | ||
220 | return ret; | 221 | return ret; |
221 | } | 222 | } |
222 | 223 | ||
diff --git a/drivers/mmc/mmc.h b/drivers/mmc/core/sysfs.h index 149affe0b686..80e29b358282 100644 --- a/drivers/mmc/mmc.h +++ b/drivers/mmc/core/sysfs.h | |||
@@ -1,15 +1,16 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/mmc.h | 2 | * linux/drivers/mmc/core/sysfs.h |
3 | * | 3 | * |
4 | * Copyright (C) 2003 Russell King, All Rights Reserved. | 4 | * Copyright (C) 2003 Russell King, All Rights Reserved. |
5 | * Copyright 2007 Pierre Ossman | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
9 | */ | 10 | */ |
10 | #ifndef _MMC_H | 11 | #ifndef _MMC_CORE_SYSFS_H |
11 | #define _MMC_H | 12 | #define _MMC_CORE_SYSFS_H |
12 | /* core-internal functions */ | 13 | |
13 | void mmc_init_card(struct mmc_card *card, struct mmc_host *host); | 14 | void mmc_init_card(struct mmc_card *card, struct mmc_host *host); |
14 | int mmc_register_card(struct mmc_card *card); | 15 | int mmc_register_card(struct mmc_card *card); |
15 | void mmc_remove_card(struct mmc_card *card); | 16 | void mmc_remove_card(struct mmc_card *card); |
@@ -22,4 +23,5 @@ void mmc_free_host_sysfs(struct mmc_host *host); | |||
22 | int mmc_schedule_work(struct work_struct *work); | 23 | int mmc_schedule_work(struct work_struct *work); |
23 | int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay); | 24 | int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay); |
24 | void mmc_flush_scheduled_work(void); | 25 | void mmc_flush_scheduled_work(void); |
26 | |||
25 | #endif | 27 | #endif |
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig new file mode 100644 index 000000000000..ed4deab2203d --- /dev/null +++ b/drivers/mmc/host/Kconfig | |||
@@ -0,0 +1,103 @@ | |||
1 | # | ||
2 | # MMC/SD host controller drivers | ||
3 | # | ||
4 | |||
5 | comment "MMC/SD Host Controller Drivers" | ||
6 | depends on MMC | ||
7 | |||
8 | config MMC_ARMMMCI | ||
9 | tristate "ARM AMBA Multimedia Card Interface support" | ||
10 | depends on ARM_AMBA && MMC | ||
11 | help | ||
12 | This selects the ARM(R) AMBA(R) PrimeCell Multimedia Card | ||
13 | Interface (PL180 and PL181) support. If you have an ARM(R) | ||
14 | platform with a Multimedia Card slot, say Y or M here. | ||
15 | |||
16 | If unsure, say N. | ||
17 | |||
18 | config MMC_PXA | ||
19 | tristate "Intel PXA25x/26x/27x Multimedia Card Interface support" | ||
20 | depends on ARCH_PXA && MMC | ||
21 | help | ||
22 | This selects the Intel(R) PXA(R) Multimedia card Interface. | ||
23 | If you have a PXA(R) platform with a Multimedia Card slot, | ||
24 | say Y or M here. | ||
25 | |||
26 | If unsure, say N. | ||
27 | |||
28 | config MMC_SDHCI | ||
29 | tristate "Secure Digital Host Controller Interface support (EXPERIMENTAL)" | ||
30 | depends on PCI && MMC && EXPERIMENTAL | ||
31 | help | ||
32 | This select the generic Secure Digital Host Controller Interface. | ||
33 | It is used by manufacturers such as Texas Instruments(R), Ricoh(R) | ||
34 | and Toshiba(R). Most controllers found in laptops are of this type. | ||
35 | If you have a controller with this interface, say Y or M here. | ||
36 | |||
37 | If unsure, say N. | ||
38 | |||
39 | config MMC_OMAP | ||
40 | tristate "TI OMAP Multimedia Card Interface support" | ||
41 | depends on ARCH_OMAP && MMC | ||
42 | select TPS65010 if MACH_OMAP_H2 | ||
43 | help | ||
44 | This selects the TI OMAP Multimedia card Interface. | ||
45 | If you have an OMAP board with a Multimedia Card slot, | ||
46 | say Y or M here. | ||
47 | |||
48 | If unsure, say N. | ||
49 | |||
50 | config MMC_WBSD | ||
51 | tristate "Winbond W83L51xD SD/MMC Card Interface support" | ||
52 | depends on MMC && ISA_DMA_API | ||
53 | help | ||
54 | This selects the Winbond(R) W83L51xD Secure digital and | ||
55 | Multimedia card Interface. | ||
56 | If you have a machine with a integrated W83L518D or W83L519D | ||
57 | SD/MMC card reader, say Y or M here. | ||
58 | |||
59 | If unsure, say N. | ||
60 | |||
61 | config MMC_AU1X | ||
62 | tristate "Alchemy AU1XX0 MMC Card Interface support" | ||
63 | depends on MMC && SOC_AU1200 | ||
64 | help | ||
65 | This selects the AMD Alchemy(R) Multimedia card interface. | ||
66 | If you have a Alchemy platform with a MMC slot, say Y or M here. | ||
67 | |||
68 | If unsure, say N. | ||
69 | |||
70 | config MMC_AT91 | ||
71 | tristate "AT91 SD/MMC Card Interface support" | ||
72 | depends on ARCH_AT91 && MMC | ||
73 | help | ||
74 | This selects the AT91 MCI controller. | ||
75 | |||
76 | If unsure, say N. | ||
77 | |||
78 | config MMC_IMX | ||
79 | tristate "Motorola i.MX Multimedia Card Interface support" | ||
80 | depends on ARCH_IMX && MMC | ||
81 | help | ||
82 | This selects the Motorola i.MX Multimedia card Interface. | ||
83 | If you have a i.MX platform with a Multimedia Card slot, | ||
84 | say Y or M here. | ||
85 | |||
86 | If unsure, say N. | ||
87 | |||
88 | config MMC_TIFM_SD | ||
89 | tristate "TI Flash Media MMC/SD Interface support (EXPERIMENTAL)" | ||
90 | depends on MMC && EXPERIMENTAL && PCI | ||
91 | select TIFM_CORE | ||
92 | help | ||
93 | Say Y here if you want to be able to access MMC/SD cards with | ||
94 | the Texas Instruments(R) Flash Media card reader, found in many | ||
95 | laptops. | ||
96 | This option 'selects' (turns on, enables) 'TIFM_CORE', but you | ||
97 | probably also need appropriate card reader host adapter, such as | ||
98 | 'Misc devices: TI Flash Media PCI74xx/PCI76xx host adapter support | ||
99 | (TIFM_7XX1)'. | ||
100 | |||
101 | To compile this driver as a module, choose M here: the | ||
102 | module will be called tifm_sd. | ||
103 | |||
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile new file mode 100644 index 000000000000..6685f64345b4 --- /dev/null +++ b/drivers/mmc/host/Makefile | |||
@@ -0,0 +1,18 @@ | |||
1 | # | ||
2 | # Makefile for MMC/SD host controller drivers | ||
3 | # | ||
4 | |||
5 | ifeq ($(CONFIG_MMC_DEBUG),y) | ||
6 | EXTRA_CFLAGS += -DDEBUG | ||
7 | endif | ||
8 | |||
9 | obj-$(CONFIG_MMC_ARMMMCI) += mmci.o | ||
10 | obj-$(CONFIG_MMC_PXA) += pxamci.o | ||
11 | obj-$(CONFIG_MMC_IMX) += imxmmc.o | ||
12 | obj-$(CONFIG_MMC_SDHCI) += sdhci.o | ||
13 | obj-$(CONFIG_MMC_WBSD) += wbsd.o | ||
14 | obj-$(CONFIG_MMC_AU1X) += au1xmmc.o | ||
15 | obj-$(CONFIG_MMC_OMAP) += omap.o | ||
16 | obj-$(CONFIG_MMC_AT91) += at91_mci.o | ||
17 | obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o | ||
18 | |||
diff --git a/drivers/mmc/at91_mci.c b/drivers/mmc/host/at91_mci.c index 459f4b4feded..e37943c314cb 100644 --- a/drivers/mmc/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c | |||
@@ -67,7 +67,6 @@ | |||
67 | #include <linux/atmel_pdc.h> | 67 | #include <linux/atmel_pdc.h> |
68 | 68 | ||
69 | #include <linux/mmc/host.h> | 69 | #include <linux/mmc/host.h> |
70 | #include <linux/mmc/protocol.h> | ||
71 | 70 | ||
72 | #include <asm/io.h> | 71 | #include <asm/io.h> |
73 | #include <asm/irq.h> | 72 | #include <asm/irq.h> |
diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index b834be261ab7..b7156a4555b5 100644 --- a/drivers/mmc/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c | |||
@@ -42,7 +42,6 @@ | |||
42 | #include <linux/dma-mapping.h> | 42 | #include <linux/dma-mapping.h> |
43 | 43 | ||
44 | #include <linux/mmc/host.h> | 44 | #include <linux/mmc/host.h> |
45 | #include <linux/mmc/protocol.h> | ||
46 | #include <asm/io.h> | 45 | #include <asm/io.h> |
47 | #include <asm/mach-au1x00/au1000.h> | 46 | #include <asm/mach-au1x00/au1000.h> |
48 | #include <asm/mach-au1x00/au1xxx_dbdma.h> | 47 | #include <asm/mach-au1x00/au1xxx_dbdma.h> |
diff --git a/drivers/mmc/au1xmmc.h b/drivers/mmc/host/au1xmmc.h index 341cbdf0baca..341cbdf0baca 100644 --- a/drivers/mmc/au1xmmc.h +++ b/drivers/mmc/host/au1xmmc.h | |||
diff --git a/drivers/mmc/imxmmc.c b/drivers/mmc/host/imxmmc.c index 0de5c9e94e74..7ee2045acbef 100644 --- a/drivers/mmc/imxmmc.c +++ b/drivers/mmc/host/imxmmc.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #include <linux/dma-mapping.h> | 41 | #include <linux/dma-mapping.h> |
42 | #include <linux/mmc/host.h> | 42 | #include <linux/mmc/host.h> |
43 | #include <linux/mmc/card.h> | 43 | #include <linux/mmc/card.h> |
44 | #include <linux/mmc/protocol.h> | ||
45 | #include <linux/delay.h> | 44 | #include <linux/delay.h> |
46 | 45 | ||
47 | #include <asm/dma.h> | 46 | #include <asm/dma.h> |
diff --git a/drivers/mmc/imxmmc.h b/drivers/mmc/host/imxmmc.h index e5339e334dbb..e5339e334dbb 100644 --- a/drivers/mmc/imxmmc.h +++ b/drivers/mmc/host/imxmmc.h | |||
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/host/mmci.c index 5941dd951e82..d11c2d23ceea 100644 --- a/drivers/mmc/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/err.h> | 17 | #include <linux/err.h> |
18 | #include <linux/highmem.h> | 18 | #include <linux/highmem.h> |
19 | #include <linux/mmc/host.h> | 19 | #include <linux/mmc/host.h> |
20 | #include <linux/mmc/protocol.h> | ||
21 | #include <linux/amba/bus.h> | 20 | #include <linux/amba/bus.h> |
22 | #include <linux/clk.h> | 21 | #include <linux/clk.h> |
23 | 22 | ||
diff --git a/drivers/mmc/mmci.h b/drivers/mmc/host/mmci.h index 6d7eadc9a678..6d7eadc9a678 100644 --- a/drivers/mmc/mmci.h +++ b/drivers/mmc/host/mmci.h | |||
diff --git a/drivers/mmc/omap.c b/drivers/mmc/host/omap.c index 1e96a2f65022..1914e65d4db1 100644 --- a/drivers/mmc/omap.c +++ b/drivers/mmc/host/omap.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/spinlock.h> | 22 | #include <linux/spinlock.h> |
23 | #include <linux/timer.h> | 23 | #include <linux/timer.h> |
24 | #include <linux/mmc/host.h> | 24 | #include <linux/mmc/host.h> |
25 | #include <linux/mmc/protocol.h> | ||
26 | #include <linux/mmc/card.h> | 25 | #include <linux/mmc/card.h> |
27 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
28 | 27 | ||
@@ -605,7 +604,7 @@ static void mmc_omap_switch_handler(struct work_struct *work) | |||
605 | } | 604 | } |
606 | if (mmc_omap_cover_is_open(host)) { | 605 | if (mmc_omap_cover_is_open(host)) { |
607 | if (!complained) { | 606 | if (!complained) { |
608 | dev_info(mmc_dev(host->mmc), "cover is open"); | 607 | dev_info(mmc_dev(host->mmc), "cover is open\n"); |
609 | complained = 1; | 608 | complained = 1; |
610 | } | 609 | } |
611 | if (mmc_omap_enable_poll) | 610 | if (mmc_omap_enable_poll) |
@@ -937,48 +936,55 @@ static void mmc_omap_power(struct mmc_omap_host *host, int on) | |||
937 | } | 936 | } |
938 | } | 937 | } |
939 | 938 | ||
940 | static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 939 | static int mmc_omap_calc_divisor(struct mmc_host *mmc, struct mmc_ios *ios) |
941 | { | 940 | { |
942 | struct mmc_omap_host *host = mmc_priv(mmc); | 941 | struct mmc_omap_host *host = mmc_priv(mmc); |
942 | int func_clk_rate = clk_get_rate(host->fclk); | ||
943 | int dsor; | 943 | int dsor; |
944 | int realclock, i; | ||
945 | |||
946 | realclock = ios->clock; | ||
947 | 944 | ||
948 | if (ios->clock == 0) | 945 | if (ios->clock == 0) |
949 | dsor = 0; | 946 | return 0; |
950 | else { | ||
951 | int func_clk_rate = clk_get_rate(host->fclk); | ||
952 | |||
953 | dsor = func_clk_rate / realclock; | ||
954 | if (dsor < 1) | ||
955 | dsor = 1; | ||
956 | 947 | ||
957 | if (func_clk_rate / dsor > realclock) | 948 | dsor = func_clk_rate / ios->clock; |
958 | dsor++; | 949 | if (dsor < 1) |
950 | dsor = 1; | ||
959 | 951 | ||
960 | if (dsor > 250) | 952 | if (func_clk_rate / dsor > ios->clock) |
961 | dsor = 250; | ||
962 | dsor++; | 953 | dsor++; |
963 | 954 | ||
964 | if (ios->bus_width == MMC_BUS_WIDTH_4) | 955 | if (dsor > 250) |
965 | dsor |= 1 << 15; | 956 | dsor = 250; |
966 | } | 957 | dsor++; |
958 | |||
959 | if (ios->bus_width == MMC_BUS_WIDTH_4) | ||
960 | dsor |= 1 << 15; | ||
961 | |||
962 | return dsor; | ||
963 | } | ||
964 | |||
965 | static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | ||
966 | { | ||
967 | struct mmc_omap_host *host = mmc_priv(mmc); | ||
968 | int dsor; | ||
969 | int i; | ||
970 | |||
971 | dsor = mmc_omap_calc_divisor(mmc, ios); | ||
972 | host->bus_mode = ios->bus_mode; | ||
973 | host->hw_bus_mode = host->bus_mode; | ||
967 | 974 | ||
968 | switch (ios->power_mode) { | 975 | switch (ios->power_mode) { |
969 | case MMC_POWER_OFF: | 976 | case MMC_POWER_OFF: |
970 | mmc_omap_power(host, 0); | 977 | mmc_omap_power(host, 0); |
971 | break; | 978 | break; |
972 | case MMC_POWER_UP: | 979 | case MMC_POWER_UP: |
973 | case MMC_POWER_ON: | 980 | /* Cannot touch dsor yet, just power up MMC */ |
974 | mmc_omap_power(host, 1); | 981 | mmc_omap_power(host, 1); |
982 | return; | ||
983 | case MMC_POWER_ON: | ||
975 | dsor |= 1 << 11; | 984 | dsor |= 1 << 11; |
976 | break; | 985 | break; |
977 | } | 986 | } |
978 | 987 | ||
979 | host->bus_mode = ios->bus_mode; | ||
980 | host->hw_bus_mode = host->bus_mode; | ||
981 | |||
982 | clk_enable(host->fclk); | 988 | clk_enable(host->fclk); |
983 | 989 | ||
984 | /* On insanely high arm_per frequencies something sometimes | 990 | /* On insanely high arm_per frequencies something sometimes |
@@ -987,7 +993,7 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
987 | * Writing to the CON register twice seems to do the trick. */ | 993 | * Writing to the CON register twice seems to do the trick. */ |
988 | for (i = 0; i < 2; i++) | 994 | for (i = 0; i < 2; i++) |
989 | OMAP_MMC_WRITE(host, CON, dsor); | 995 | OMAP_MMC_WRITE(host, CON, dsor); |
990 | if (ios->power_mode == MMC_POWER_UP) { | 996 | if (ios->power_mode == MMC_POWER_ON) { |
991 | /* Send clock cycles, poll completion */ | 997 | /* Send clock cycles, poll completion */ |
992 | OMAP_MMC_WRITE(host, IE, 0); | 998 | OMAP_MMC_WRITE(host, IE, 0); |
993 | OMAP_MMC_WRITE(host, STAT, 0xffff); | 999 | OMAP_MMC_WRITE(host, STAT, 0xffff); |
diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/host/pxamci.c index 9774fc68b61a..a98ff98fa567 100644 --- a/drivers/mmc/pxamci.c +++ b/drivers/mmc/host/pxamci.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/dma-mapping.h> | 25 | #include <linux/dma-mapping.h> |
26 | #include <linux/mmc/host.h> | 26 | #include <linux/mmc/host.h> |
27 | #include <linux/mmc/protocol.h> | ||
28 | 27 | ||
29 | #include <asm/dma.h> | 28 | #include <asm/dma.h> |
30 | #include <asm/io.h> | 29 | #include <asm/io.h> |
diff --git a/drivers/mmc/pxamci.h b/drivers/mmc/host/pxamci.h index 1b163220df2b..1b163220df2b 100644 --- a/drivers/mmc/pxamci.h +++ b/drivers/mmc/host/pxamci.h | |||
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/host/sdhci.c index d749f08601b8..ff5bf73cdd25 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/sdhci.c - Secure Digital Host Controller Interface driver | 2 | * linux/drivers/mmc/sdhci.c - Secure Digital Host Controller Interface driver |
3 | * | 3 | * |
4 | * Copyright (C) 2005-2006 Pierre Ossman, All Rights Reserved. | 4 | * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/dma-mapping.h> | 15 | #include <linux/dma-mapping.h> |
16 | 16 | ||
17 | #include <linux/mmc/host.h> | 17 | #include <linux/mmc/host.h> |
18 | #include <linux/mmc/protocol.h> | ||
19 | 18 | ||
20 | #include <asm/scatterlist.h> | 19 | #include <asm/scatterlist.h> |
21 | 20 | ||
@@ -247,14 +246,13 @@ static void sdhci_read_block_pio(struct sdhci_host *host) | |||
247 | chunk_remain = min(blksize, 4); | 246 | chunk_remain = min(blksize, 4); |
248 | } | 247 | } |
249 | 248 | ||
250 | size = min(host->size, host->remain); | 249 | size = min(host->remain, chunk_remain); |
251 | size = min(size, chunk_remain); | ||
252 | 250 | ||
253 | chunk_remain -= size; | 251 | chunk_remain -= size; |
254 | blksize -= size; | 252 | blksize -= size; |
255 | host->offset += size; | 253 | host->offset += size; |
256 | host->remain -= size; | 254 | host->remain -= size; |
257 | host->size -= size; | 255 | |
258 | while (size) { | 256 | while (size) { |
259 | *buffer = data & 0xFF; | 257 | *buffer = data & 0xFF; |
260 | buffer++; | 258 | buffer++; |
@@ -289,14 +287,13 @@ static void sdhci_write_block_pio(struct sdhci_host *host) | |||
289 | buffer = sdhci_sg_to_buffer(host) + host->offset; | 287 | buffer = sdhci_sg_to_buffer(host) + host->offset; |
290 | 288 | ||
291 | while (blksize) { | 289 | while (blksize) { |
292 | size = min(host->size, host->remain); | 290 | size = min(host->remain, chunk_remain); |
293 | size = min(size, chunk_remain); | ||
294 | 291 | ||
295 | chunk_remain -= size; | 292 | chunk_remain -= size; |
296 | blksize -= size; | 293 | blksize -= size; |
297 | host->offset += size; | 294 | host->offset += size; |
298 | host->remain -= size; | 295 | host->remain -= size; |
299 | host->size -= size; | 296 | |
300 | while (size) { | 297 | while (size) { |
301 | data >>= 8; | 298 | data >>= 8; |
302 | data |= (u32)*buffer << 24; | 299 | data |= (u32)*buffer << 24; |
@@ -325,7 +322,7 @@ static void sdhci_transfer_pio(struct sdhci_host *host) | |||
325 | 322 | ||
326 | BUG_ON(!host->data); | 323 | BUG_ON(!host->data); |
327 | 324 | ||
328 | if (host->size == 0) | 325 | if (host->num_sg == 0) |
329 | return; | 326 | return; |
330 | 327 | ||
331 | if (host->data->flags & MMC_DATA_READ) | 328 | if (host->data->flags & MMC_DATA_READ) |
@@ -339,10 +336,8 @@ static void sdhci_transfer_pio(struct sdhci_host *host) | |||
339 | else | 336 | else |
340 | sdhci_write_block_pio(host); | 337 | sdhci_write_block_pio(host); |
341 | 338 | ||
342 | if (host->size == 0) | 339 | if (host->num_sg == 0) |
343 | break; | 340 | break; |
344 | |||
345 | BUG_ON(host->num_sg == 0); | ||
346 | } | 341 | } |
347 | 342 | ||
348 | DBG("PIO transfer complete.\n"); | 343 | DBG("PIO transfer complete.\n"); |
@@ -408,8 +403,6 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) | |||
408 | 403 | ||
409 | writel(sg_dma_address(data->sg), host->ioaddr + SDHCI_DMA_ADDRESS); | 404 | writel(sg_dma_address(data->sg), host->ioaddr + SDHCI_DMA_ADDRESS); |
410 | } else { | 405 | } else { |
411 | host->size = data->blksz * data->blocks; | ||
412 | |||
413 | host->cur_sg = data->sg; | 406 | host->cur_sg = data->sg; |
414 | host->num_sg = data->sg_len; | 407 | host->num_sg = data->sg_len; |
415 | 408 | ||
@@ -473,10 +466,6 @@ static void sdhci_finish_data(struct sdhci_host *host) | |||
473 | "though there were blocks left.\n", | 466 | "though there were blocks left.\n", |
474 | mmc_hostname(host->mmc)); | 467 | mmc_hostname(host->mmc)); |
475 | data->error = MMC_ERR_FAILED; | 468 | data->error = MMC_ERR_FAILED; |
476 | } else if (host->size != 0) { | ||
477 | printk(KERN_ERR "%s: %d bytes were left untransferred.\n", | ||
478 | mmc_hostname(host->mmc), host->size); | ||
479 | data->error = MMC_ERR_FAILED; | ||
480 | } | 469 | } |
481 | 470 | ||
482 | DBG("Ending data transfer (%d bytes)\n", data->bytes_xfered); | 471 | DBG("Ending data transfer (%d bytes)\n", data->bytes_xfered); |
@@ -669,20 +658,16 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) | |||
669 | 658 | ||
670 | pwr = SDHCI_POWER_ON; | 659 | pwr = SDHCI_POWER_ON; |
671 | 660 | ||
672 | switch (power) { | 661 | switch (1 << power) { |
673 | case MMC_VDD_170: | 662 | case MMC_VDD_165_195: |
674 | case MMC_VDD_180: | ||
675 | case MMC_VDD_190: | ||
676 | pwr |= SDHCI_POWER_180; | 663 | pwr |= SDHCI_POWER_180; |
677 | break; | 664 | break; |
678 | case MMC_VDD_290: | 665 | case MMC_VDD_29_30: |
679 | case MMC_VDD_300: | 666 | case MMC_VDD_30_31: |
680 | case MMC_VDD_310: | ||
681 | pwr |= SDHCI_POWER_300; | 667 | pwr |= SDHCI_POWER_300; |
682 | break; | 668 | break; |
683 | case MMC_VDD_320: | 669 | case MMC_VDD_32_33: |
684 | case MMC_VDD_330: | 670 | case MMC_VDD_33_34: |
685 | case MMC_VDD_340: | ||
686 | pwr |= SDHCI_POWER_330; | 671 | pwr |= SDHCI_POWER_330; |
687 | break; | 672 | break; |
688 | default: | 673 | default: |
@@ -1294,7 +1279,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) | |||
1294 | if (caps & SDHCI_CAN_VDD_300) | 1279 | if (caps & SDHCI_CAN_VDD_300) |
1295 | mmc->ocr_avail |= MMC_VDD_29_30|MMC_VDD_30_31; | 1280 | mmc->ocr_avail |= MMC_VDD_29_30|MMC_VDD_30_31; |
1296 | if (caps & SDHCI_CAN_VDD_180) | 1281 | if (caps & SDHCI_CAN_VDD_180) |
1297 | mmc->ocr_avail |= MMC_VDD_17_18|MMC_VDD_18_19; | 1282 | mmc->ocr_avail |= MMC_VDD_165_195; |
1298 | 1283 | ||
1299 | if (mmc->ocr_avail == 0) { | 1284 | if (mmc->ocr_avail == 0) { |
1300 | printk(KERN_ERR "%s: Hardware doesn't report any " | 1285 | printk(KERN_ERR "%s: Hardware doesn't report any " |
diff --git a/drivers/mmc/sdhci.h b/drivers/mmc/host/sdhci.h index e324f0a623dc..7400f4bc114f 100644 --- a/drivers/mmc/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/sdhci.h - Secure Digital Host Controller Interface driver | 2 | * linux/drivers/mmc/sdhci.h - Secure Digital Host Controller Interface driver |
3 | * | 3 | * |
4 | * Copyright (C) 2005 Pierre Ossman, All Rights Reserved. | 4 | * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -187,8 +187,6 @@ struct sdhci_host { | |||
187 | int offset; /* Offset into current sg */ | 187 | int offset; /* Offset into current sg */ |
188 | int remain; /* Bytes left in current */ | 188 | int remain; /* Bytes left in current */ |
189 | 189 | ||
190 | int size; /* Remaining bytes in transfer */ | ||
191 | |||
192 | char slot_descr[20]; /* Name for reservations */ | 190 | char slot_descr[20]; /* Name for reservations */ |
193 | 191 | ||
194 | int irq; /* Device IRQ */ | 192 | int irq; /* Device IRQ */ |
diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c new file mode 100644 index 000000000000..7511f961c67b --- /dev/null +++ b/drivers/mmc/host/tifm_sd.c | |||
@@ -0,0 +1,1102 @@ | |||
1 | /* | ||
2 | * tifm_sd.c - TI FlashMedia driver | ||
3 | * | ||
4 | * Copyright (C) 2006 Alex Dubov <oakad@yahoo.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * Special thanks to Brad Campbell for extensive testing of this driver. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | |||
15 | #include <linux/tifm.h> | ||
16 | #include <linux/mmc/host.h> | ||
17 | #include <linux/highmem.h> | ||
18 | #include <linux/scatterlist.h> | ||
19 | #include <asm/io.h> | ||
20 | |||
21 | #define DRIVER_NAME "tifm_sd" | ||
22 | #define DRIVER_VERSION "0.8" | ||
23 | |||
24 | static int no_dma = 0; | ||
25 | static int fixed_timeout = 0; | ||
26 | module_param(no_dma, bool, 0644); | ||
27 | module_param(fixed_timeout, bool, 0644); | ||
28 | |||
29 | /* Constants here are mostly from OMAP5912 datasheet */ | ||
30 | #define TIFM_MMCSD_RESET 0x0002 | ||
31 | #define TIFM_MMCSD_CLKMASK 0x03ff | ||
32 | #define TIFM_MMCSD_POWER 0x0800 | ||
33 | #define TIFM_MMCSD_4BBUS 0x8000 | ||
34 | #define TIFM_MMCSD_RXDE 0x8000 /* rx dma enable */ | ||
35 | #define TIFM_MMCSD_TXDE 0x0080 /* tx dma enable */ | ||
36 | #define TIFM_MMCSD_BUFINT 0x0c00 /* set bits: AE, AF */ | ||
37 | #define TIFM_MMCSD_DPE 0x0020 /* data timeout counted in kilocycles */ | ||
38 | #define TIFM_MMCSD_INAB 0x0080 /* abort / initialize command */ | ||
39 | #define TIFM_MMCSD_READ 0x8000 | ||
40 | |||
41 | #define TIFM_MMCSD_ERRMASK 0x01e0 /* set bits: CCRC, CTO, DCRC, DTO */ | ||
42 | #define TIFM_MMCSD_EOC 0x0001 /* end of command phase */ | ||
43 | #define TIFM_MMCSD_CD 0x0002 /* card detect */ | ||
44 | #define TIFM_MMCSD_CB 0x0004 /* card enter busy state */ | ||
45 | #define TIFM_MMCSD_BRS 0x0008 /* block received/sent */ | ||
46 | #define TIFM_MMCSD_EOFB 0x0010 /* card exit busy state */ | ||
47 | #define TIFM_MMCSD_DTO 0x0020 /* data time-out */ | ||
48 | #define TIFM_MMCSD_DCRC 0x0040 /* data crc error */ | ||
49 | #define TIFM_MMCSD_CTO 0x0080 /* command time-out */ | ||
50 | #define TIFM_MMCSD_CCRC 0x0100 /* command crc error */ | ||
51 | #define TIFM_MMCSD_AF 0x0400 /* fifo almost full */ | ||
52 | #define TIFM_MMCSD_AE 0x0800 /* fifo almost empty */ | ||
53 | #define TIFM_MMCSD_OCRB 0x1000 /* OCR busy */ | ||
54 | #define TIFM_MMCSD_CIRQ 0x2000 /* card irq (cmd40/sdio) */ | ||
55 | #define TIFM_MMCSD_CERR 0x4000 /* card status error */ | ||
56 | |||
57 | #define TIFM_MMCSD_ODTO 0x0040 /* open drain / extended timeout */ | ||
58 | #define TIFM_MMCSD_CARD_RO 0x0200 /* card is read-only */ | ||
59 | |||
60 | #define TIFM_MMCSD_FIFO_SIZE 0x0020 | ||
61 | |||
62 | #define TIFM_MMCSD_RSP_R0 0x0000 | ||
63 | #define TIFM_MMCSD_RSP_R1 0x0100 | ||
64 | #define TIFM_MMCSD_RSP_R2 0x0200 | ||
65 | #define TIFM_MMCSD_RSP_R3 0x0300 | ||
66 | #define TIFM_MMCSD_RSP_R4 0x0400 | ||
67 | #define TIFM_MMCSD_RSP_R5 0x0500 | ||
68 | #define TIFM_MMCSD_RSP_R6 0x0600 | ||
69 | |||
70 | #define TIFM_MMCSD_RSP_BUSY 0x0800 | ||
71 | |||
72 | #define TIFM_MMCSD_CMD_BC 0x0000 | ||
73 | #define TIFM_MMCSD_CMD_BCR 0x1000 | ||
74 | #define TIFM_MMCSD_CMD_AC 0x2000 | ||
75 | #define TIFM_MMCSD_CMD_ADTC 0x3000 | ||
76 | |||
77 | #define TIFM_MMCSD_MAX_BLOCK_SIZE 0x0800UL | ||
78 | |||
79 | enum { | ||
80 | CMD_READY = 0x0001, | ||
81 | FIFO_READY = 0x0002, | ||
82 | BRS_READY = 0x0004, | ||
83 | SCMD_ACTIVE = 0x0008, | ||
84 | SCMD_READY = 0x0010, | ||
85 | CARD_BUSY = 0x0020, | ||
86 | DATA_CARRY = 0x0040 | ||
87 | }; | ||
88 | |||
89 | struct tifm_sd { | ||
90 | struct tifm_dev *dev; | ||
91 | |||
92 | unsigned short eject:1, | ||
93 | open_drain:1, | ||
94 | no_dma:1; | ||
95 | unsigned short cmd_flags; | ||
96 | |||
97 | unsigned int clk_freq; | ||
98 | unsigned int clk_div; | ||
99 | unsigned long timeout_jiffies; | ||
100 | |||
101 | struct tasklet_struct finish_tasklet; | ||
102 | struct timer_list timer; | ||
103 | struct mmc_request *req; | ||
104 | |||
105 | int sg_len; | ||
106 | int sg_pos; | ||
107 | unsigned int block_pos; | ||
108 | struct scatterlist bounce_buf; | ||
109 | unsigned char bounce_buf_data[TIFM_MMCSD_MAX_BLOCK_SIZE]; | ||
110 | }; | ||
111 | |||
112 | /* for some reason, host won't respond correctly to readw/writew */ | ||
113 | static void tifm_sd_read_fifo(struct tifm_sd *host, struct page *pg, | ||
114 | unsigned int off, unsigned int cnt) | ||
115 | { | ||
116 | struct tifm_dev *sock = host->dev; | ||
117 | unsigned char *buf; | ||
118 | unsigned int pos = 0, val; | ||
119 | |||
120 | buf = kmap_atomic(pg, KM_BIO_DST_IRQ) + off; | ||
121 | if (host->cmd_flags & DATA_CARRY) { | ||
122 | buf[pos++] = host->bounce_buf_data[0]; | ||
123 | host->cmd_flags &= ~DATA_CARRY; | ||
124 | } | ||
125 | |||
126 | while (pos < cnt) { | ||
127 | val = readl(sock->addr + SOCK_MMCSD_DATA); | ||
128 | buf[pos++] = val & 0xff; | ||
129 | if (pos == cnt) { | ||
130 | host->bounce_buf_data[0] = (val >> 8) & 0xff; | ||
131 | host->cmd_flags |= DATA_CARRY; | ||
132 | break; | ||
133 | } | ||
134 | buf[pos++] = (val >> 8) & 0xff; | ||
135 | } | ||
136 | kunmap_atomic(buf - off, KM_BIO_DST_IRQ); | ||
137 | } | ||
138 | |||
139 | static void tifm_sd_write_fifo(struct tifm_sd *host, struct page *pg, | ||
140 | unsigned int off, unsigned int cnt) | ||
141 | { | ||
142 | struct tifm_dev *sock = host->dev; | ||
143 | unsigned char *buf; | ||
144 | unsigned int pos = 0, val; | ||
145 | |||
146 | buf = kmap_atomic(pg, KM_BIO_SRC_IRQ) + off; | ||
147 | if (host->cmd_flags & DATA_CARRY) { | ||
148 | val = host->bounce_buf_data[0] | ((buf[pos++] << 8) & 0xff00); | ||
149 | writel(val, sock->addr + SOCK_MMCSD_DATA); | ||
150 | host->cmd_flags &= ~DATA_CARRY; | ||
151 | } | ||
152 | |||
153 | while (pos < cnt) { | ||
154 | val = buf[pos++]; | ||
155 | if (pos == cnt) { | ||
156 | host->bounce_buf_data[0] = val & 0xff; | ||
157 | host->cmd_flags |= DATA_CARRY; | ||
158 | break; | ||
159 | } | ||
160 | val |= (buf[pos++] << 8) & 0xff00; | ||
161 | writel(val, sock->addr + SOCK_MMCSD_DATA); | ||
162 | } | ||
163 | kunmap_atomic(buf - off, KM_BIO_SRC_IRQ); | ||
164 | } | ||
165 | |||
166 | static void tifm_sd_transfer_data(struct tifm_sd *host) | ||
167 | { | ||
168 | struct mmc_data *r_data = host->req->cmd->data; | ||
169 | struct scatterlist *sg = r_data->sg; | ||
170 | unsigned int off, cnt, t_size = TIFM_MMCSD_FIFO_SIZE * 2; | ||
171 | unsigned int p_off, p_cnt; | ||
172 | struct page *pg; | ||
173 | |||
174 | if (host->sg_pos == host->sg_len) | ||
175 | return; | ||
176 | while (t_size) { | ||
177 | cnt = sg[host->sg_pos].length - host->block_pos; | ||
178 | if (!cnt) { | ||
179 | host->block_pos = 0; | ||
180 | host->sg_pos++; | ||
181 | if (host->sg_pos == host->sg_len) { | ||
182 | if ((r_data->flags & MMC_DATA_WRITE) | ||
183 | && DATA_CARRY) | ||
184 | writel(host->bounce_buf_data[0], | ||
185 | host->dev->addr | ||
186 | + SOCK_MMCSD_DATA); | ||
187 | |||
188 | return; | ||
189 | } | ||
190 | cnt = sg[host->sg_pos].length; | ||
191 | } | ||
192 | off = sg[host->sg_pos].offset + host->block_pos; | ||
193 | |||
194 | pg = nth_page(sg[host->sg_pos].page, off >> PAGE_SHIFT); | ||
195 | p_off = offset_in_page(off); | ||
196 | p_cnt = PAGE_SIZE - p_off; | ||
197 | p_cnt = min(p_cnt, cnt); | ||
198 | p_cnt = min(p_cnt, t_size); | ||
199 | |||
200 | if (r_data->flags & MMC_DATA_READ) | ||
201 | tifm_sd_read_fifo(host, pg, p_off, p_cnt); | ||
202 | else if (r_data->flags & MMC_DATA_WRITE) | ||
203 | tifm_sd_write_fifo(host, pg, p_off, p_cnt); | ||
204 | |||
205 | t_size -= p_cnt; | ||
206 | host->block_pos += p_cnt; | ||
207 | } | ||
208 | } | ||
209 | |||
210 | static void tifm_sd_copy_page(struct page *dst, unsigned int dst_off, | ||
211 | struct page *src, unsigned int src_off, | ||
212 | unsigned int count) | ||
213 | { | ||
214 | unsigned char *src_buf = kmap_atomic(src, KM_BIO_SRC_IRQ) + src_off; | ||
215 | unsigned char *dst_buf = kmap_atomic(dst, KM_BIO_DST_IRQ) + dst_off; | ||
216 | |||
217 | memcpy(dst_buf, src_buf, count); | ||
218 | |||
219 | kunmap_atomic(dst_buf - dst_off, KM_BIO_DST_IRQ); | ||
220 | kunmap_atomic(src_buf - src_off, KM_BIO_SRC_IRQ); | ||
221 | } | ||
222 | |||
223 | static void tifm_sd_bounce_block(struct tifm_sd *host, struct mmc_data *r_data) | ||
224 | { | ||
225 | struct scatterlist *sg = r_data->sg; | ||
226 | unsigned int t_size = r_data->blksz; | ||
227 | unsigned int off, cnt; | ||
228 | unsigned int p_off, p_cnt; | ||
229 | struct page *pg; | ||
230 | |||
231 | dev_dbg(&host->dev->dev, "bouncing block\n"); | ||
232 | while (t_size) { | ||
233 | cnt = sg[host->sg_pos].length - host->block_pos; | ||
234 | if (!cnt) { | ||
235 | host->block_pos = 0; | ||
236 | host->sg_pos++; | ||
237 | if (host->sg_pos == host->sg_len) | ||
238 | return; | ||
239 | cnt = sg[host->sg_pos].length; | ||
240 | } | ||
241 | off = sg[host->sg_pos].offset + host->block_pos; | ||
242 | |||
243 | pg = nth_page(sg[host->sg_pos].page, off >> PAGE_SHIFT); | ||
244 | p_off = offset_in_page(off); | ||
245 | p_cnt = PAGE_SIZE - p_off; | ||
246 | p_cnt = min(p_cnt, cnt); | ||
247 | p_cnt = min(p_cnt, t_size); | ||
248 | |||
249 | if (r_data->flags & MMC_DATA_WRITE) | ||
250 | tifm_sd_copy_page(host->bounce_buf.page, | ||
251 | r_data->blksz - t_size, | ||
252 | pg, p_off, p_cnt); | ||
253 | else if (r_data->flags & MMC_DATA_READ) | ||
254 | tifm_sd_copy_page(pg, p_off, host->bounce_buf.page, | ||
255 | r_data->blksz - t_size, p_cnt); | ||
256 | |||
257 | t_size -= p_cnt; | ||
258 | host->block_pos += p_cnt; | ||
259 | } | ||
260 | } | ||
261 | |||
262 | static int tifm_sd_set_dma_data(struct tifm_sd *host, struct mmc_data *r_data) | ||
263 | { | ||
264 | struct tifm_dev *sock = host->dev; | ||
265 | unsigned int t_size = TIFM_DMA_TSIZE * r_data->blksz; | ||
266 | unsigned int dma_len, dma_blk_cnt, dma_off; | ||
267 | struct scatterlist *sg = NULL; | ||
268 | unsigned long flags; | ||
269 | |||
270 | if (host->sg_pos == host->sg_len) | ||
271 | return 1; | ||
272 | |||
273 | if (host->cmd_flags & DATA_CARRY) { | ||
274 | host->cmd_flags &= ~DATA_CARRY; | ||
275 | local_irq_save(flags); | ||
276 | tifm_sd_bounce_block(host, r_data); | ||
277 | local_irq_restore(flags); | ||
278 | if (host->sg_pos == host->sg_len) | ||
279 | return 1; | ||
280 | } | ||
281 | |||
282 | dma_len = sg_dma_len(&r_data->sg[host->sg_pos]) - host->block_pos; | ||
283 | if (!dma_len) { | ||
284 | host->block_pos = 0; | ||
285 | host->sg_pos++; | ||
286 | if (host->sg_pos == host->sg_len) | ||
287 | return 1; | ||
288 | dma_len = sg_dma_len(&r_data->sg[host->sg_pos]); | ||
289 | } | ||
290 | |||
291 | if (dma_len < t_size) { | ||
292 | dma_blk_cnt = dma_len / r_data->blksz; | ||
293 | dma_off = host->block_pos; | ||
294 | host->block_pos += dma_blk_cnt * r_data->blksz; | ||
295 | } else { | ||
296 | dma_blk_cnt = TIFM_DMA_TSIZE; | ||
297 | dma_off = host->block_pos; | ||
298 | host->block_pos += t_size; | ||
299 | } | ||
300 | |||
301 | if (dma_blk_cnt) | ||
302 | sg = &r_data->sg[host->sg_pos]; | ||
303 | else if (dma_len) { | ||
304 | if (r_data->flags & MMC_DATA_WRITE) { | ||
305 | local_irq_save(flags); | ||
306 | tifm_sd_bounce_block(host, r_data); | ||
307 | local_irq_restore(flags); | ||
308 | } else | ||
309 | host->cmd_flags |= DATA_CARRY; | ||
310 | |||
311 | sg = &host->bounce_buf; | ||
312 | dma_off = 0; | ||
313 | dma_blk_cnt = 1; | ||
314 | } else | ||
315 | return 1; | ||
316 | |||
317 | dev_dbg(&sock->dev, "setting dma for %d blocks\n", dma_blk_cnt); | ||
318 | writel(sg_dma_address(sg) + dma_off, sock->addr + SOCK_DMA_ADDRESS); | ||
319 | if (r_data->flags & MMC_DATA_WRITE) | ||
320 | writel((dma_blk_cnt << 8) | TIFM_DMA_TX | TIFM_DMA_EN, | ||
321 | sock->addr + SOCK_DMA_CONTROL); | ||
322 | else | ||
323 | writel((dma_blk_cnt << 8) | TIFM_DMA_EN, | ||
324 | sock->addr + SOCK_DMA_CONTROL); | ||
325 | |||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | static unsigned int tifm_sd_op_flags(struct mmc_command *cmd) | ||
330 | { | ||
331 | unsigned int rc = 0; | ||
332 | |||
333 | switch (mmc_resp_type(cmd)) { | ||
334 | case MMC_RSP_NONE: | ||
335 | rc |= TIFM_MMCSD_RSP_R0; | ||
336 | break; | ||
337 | case MMC_RSP_R1B: | ||
338 | rc |= TIFM_MMCSD_RSP_BUSY; // deliberate fall-through | ||
339 | case MMC_RSP_R1: | ||
340 | rc |= TIFM_MMCSD_RSP_R1; | ||
341 | break; | ||
342 | case MMC_RSP_R2: | ||
343 | rc |= TIFM_MMCSD_RSP_R2; | ||
344 | break; | ||
345 | case MMC_RSP_R3: | ||
346 | rc |= TIFM_MMCSD_RSP_R3; | ||
347 | break; | ||
348 | default: | ||
349 | BUG(); | ||
350 | } | ||
351 | |||
352 | switch (mmc_cmd_type(cmd)) { | ||
353 | case MMC_CMD_BC: | ||
354 | rc |= TIFM_MMCSD_CMD_BC; | ||
355 | break; | ||
356 | case MMC_CMD_BCR: | ||
357 | rc |= TIFM_MMCSD_CMD_BCR; | ||
358 | break; | ||
359 | case MMC_CMD_AC: | ||
360 | rc |= TIFM_MMCSD_CMD_AC; | ||
361 | break; | ||
362 | case MMC_CMD_ADTC: | ||
363 | rc |= TIFM_MMCSD_CMD_ADTC; | ||
364 | break; | ||
365 | default: | ||
366 | BUG(); | ||
367 | } | ||
368 | return rc; | ||
369 | } | ||
370 | |||
371 | static void tifm_sd_exec(struct tifm_sd *host, struct mmc_command *cmd) | ||
372 | { | ||
373 | struct tifm_dev *sock = host->dev; | ||
374 | unsigned int cmd_mask = tifm_sd_op_flags(cmd); | ||
375 | |||
376 | if (host->open_drain) | ||
377 | cmd_mask |= TIFM_MMCSD_ODTO; | ||
378 | |||
379 | if (cmd->data && (cmd->data->flags & MMC_DATA_READ)) | ||
380 | cmd_mask |= TIFM_MMCSD_READ; | ||
381 | |||
382 | dev_dbg(&sock->dev, "executing opcode 0x%x, arg: 0x%x, mask: 0x%x\n", | ||
383 | cmd->opcode, cmd->arg, cmd_mask); | ||
384 | |||
385 | writel((cmd->arg >> 16) & 0xffff, sock->addr + SOCK_MMCSD_ARG_HIGH); | ||
386 | writel(cmd->arg & 0xffff, sock->addr + SOCK_MMCSD_ARG_LOW); | ||
387 | writel(cmd->opcode | cmd_mask, sock->addr + SOCK_MMCSD_COMMAND); | ||
388 | } | ||
389 | |||
390 | static void tifm_sd_fetch_resp(struct mmc_command *cmd, struct tifm_dev *sock) | ||
391 | { | ||
392 | cmd->resp[0] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x1c) << 16) | ||
393 | | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x18); | ||
394 | cmd->resp[1] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x14) << 16) | ||
395 | | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x10); | ||
396 | cmd->resp[2] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x0c) << 16) | ||
397 | | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x08); | ||
398 | cmd->resp[3] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x04) << 16) | ||
399 | | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x00); | ||
400 | } | ||
401 | |||
402 | static void tifm_sd_check_status(struct tifm_sd *host) | ||
403 | { | ||
404 | struct tifm_dev *sock = host->dev; | ||
405 | struct mmc_command *cmd = host->req->cmd; | ||
406 | |||
407 | if (cmd->error != MMC_ERR_NONE) | ||
408 | goto finish_request; | ||
409 | |||
410 | if (!(host->cmd_flags & CMD_READY)) | ||
411 | return; | ||
412 | |||
413 | if (cmd->data) { | ||
414 | if (cmd->data->error != MMC_ERR_NONE) { | ||
415 | if ((host->cmd_flags & SCMD_ACTIVE) | ||
416 | && !(host->cmd_flags & SCMD_READY)) | ||
417 | return; | ||
418 | |||
419 | goto finish_request; | ||
420 | } | ||
421 | |||
422 | if (!(host->cmd_flags & BRS_READY)) | ||
423 | return; | ||
424 | |||
425 | if (!(host->no_dma || (host->cmd_flags & FIFO_READY))) | ||
426 | return; | ||
427 | |||
428 | if (cmd->data->flags & MMC_DATA_WRITE) { | ||
429 | if (host->req->stop) { | ||
430 | if (!(host->cmd_flags & SCMD_ACTIVE)) { | ||
431 | host->cmd_flags |= SCMD_ACTIVE; | ||
432 | writel(TIFM_MMCSD_EOFB | ||
433 | | readl(sock->addr | ||
434 | + SOCK_MMCSD_INT_ENABLE), | ||
435 | sock->addr | ||
436 | + SOCK_MMCSD_INT_ENABLE); | ||
437 | tifm_sd_exec(host, host->req->stop); | ||
438 | return; | ||
439 | } else { | ||
440 | if (!(host->cmd_flags & SCMD_READY) | ||
441 | || (host->cmd_flags & CARD_BUSY)) | ||
442 | return; | ||
443 | writel((~TIFM_MMCSD_EOFB) | ||
444 | & readl(sock->addr | ||
445 | + SOCK_MMCSD_INT_ENABLE), | ||
446 | sock->addr | ||
447 | + SOCK_MMCSD_INT_ENABLE); | ||
448 | } | ||
449 | } else { | ||
450 | if (host->cmd_flags & CARD_BUSY) | ||
451 | return; | ||
452 | writel((~TIFM_MMCSD_EOFB) | ||
453 | & readl(sock->addr | ||
454 | + SOCK_MMCSD_INT_ENABLE), | ||
455 | sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
456 | } | ||
457 | } else { | ||
458 | if (host->req->stop) { | ||
459 | if (!(host->cmd_flags & SCMD_ACTIVE)) { | ||
460 | host->cmd_flags |= SCMD_ACTIVE; | ||
461 | tifm_sd_exec(host, host->req->stop); | ||
462 | return; | ||
463 | } else { | ||
464 | if (!(host->cmd_flags & SCMD_READY)) | ||
465 | return; | ||
466 | } | ||
467 | } | ||
468 | } | ||
469 | } | ||
470 | finish_request: | ||
471 | tasklet_schedule(&host->finish_tasklet); | ||
472 | } | ||
473 | |||
474 | /* Called from interrupt handler */ | ||
475 | static void tifm_sd_data_event(struct tifm_dev *sock) | ||
476 | { | ||
477 | struct tifm_sd *host; | ||
478 | unsigned int fifo_status = 0; | ||
479 | struct mmc_data *r_data = NULL; | ||
480 | |||
481 | spin_lock(&sock->lock); | ||
482 | host = mmc_priv((struct mmc_host*)tifm_get_drvdata(sock)); | ||
483 | fifo_status = readl(sock->addr + SOCK_DMA_FIFO_STATUS); | ||
484 | dev_dbg(&sock->dev, "data event: fifo_status %x, flags %x\n", | ||
485 | fifo_status, host->cmd_flags); | ||
486 | |||
487 | if (host->req) { | ||
488 | r_data = host->req->cmd->data; | ||
489 | |||
490 | if (r_data && (fifo_status & TIFM_FIFO_READY)) { | ||
491 | if (tifm_sd_set_dma_data(host, r_data)) { | ||
492 | host->cmd_flags |= FIFO_READY; | ||
493 | tifm_sd_check_status(host); | ||
494 | } | ||
495 | } | ||
496 | } | ||
497 | |||
498 | writel(fifo_status, sock->addr + SOCK_DMA_FIFO_STATUS); | ||
499 | spin_unlock(&sock->lock); | ||
500 | } | ||
501 | |||
502 | /* Called from interrupt handler */ | ||
503 | static void tifm_sd_card_event(struct tifm_dev *sock) | ||
504 | { | ||
505 | struct tifm_sd *host; | ||
506 | unsigned int host_status = 0; | ||
507 | int cmd_error = MMC_ERR_NONE; | ||
508 | struct mmc_command *cmd = NULL; | ||
509 | unsigned long flags; | ||
510 | |||
511 | spin_lock(&sock->lock); | ||
512 | host = mmc_priv((struct mmc_host*)tifm_get_drvdata(sock)); | ||
513 | host_status = readl(sock->addr + SOCK_MMCSD_STATUS); | ||
514 | dev_dbg(&sock->dev, "host event: host_status %x, flags %x\n", | ||
515 | host_status, host->cmd_flags); | ||
516 | |||
517 | if (host->req) { | ||
518 | cmd = host->req->cmd; | ||
519 | |||
520 | if (host_status & TIFM_MMCSD_ERRMASK) { | ||
521 | writel(host_status & TIFM_MMCSD_ERRMASK, | ||
522 | sock->addr + SOCK_MMCSD_STATUS); | ||
523 | if (host_status & TIFM_MMCSD_CTO) | ||
524 | cmd_error = MMC_ERR_TIMEOUT; | ||
525 | else if (host_status & TIFM_MMCSD_CCRC) | ||
526 | cmd_error = MMC_ERR_BADCRC; | ||
527 | |||
528 | if (cmd->data) { | ||
529 | if (host_status & TIFM_MMCSD_DTO) | ||
530 | cmd->data->error = MMC_ERR_TIMEOUT; | ||
531 | else if (host_status & TIFM_MMCSD_DCRC) | ||
532 | cmd->data->error = MMC_ERR_BADCRC; | ||
533 | } | ||
534 | |||
535 | writel(TIFM_FIFO_INT_SETALL, | ||
536 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); | ||
537 | writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL); | ||
538 | |||
539 | if (host->req->stop) { | ||
540 | if (host->cmd_flags & SCMD_ACTIVE) { | ||
541 | host->req->stop->error = cmd_error; | ||
542 | host->cmd_flags |= SCMD_READY; | ||
543 | } else { | ||
544 | cmd->error = cmd_error; | ||
545 | host->cmd_flags |= SCMD_ACTIVE; | ||
546 | tifm_sd_exec(host, host->req->stop); | ||
547 | goto done; | ||
548 | } | ||
549 | } else | ||
550 | cmd->error = cmd_error; | ||
551 | } else { | ||
552 | if (host_status & (TIFM_MMCSD_EOC | TIFM_MMCSD_CERR)) { | ||
553 | if (!(host->cmd_flags & CMD_READY)) { | ||
554 | host->cmd_flags |= CMD_READY; | ||
555 | tifm_sd_fetch_resp(cmd, sock); | ||
556 | } else if (host->cmd_flags & SCMD_ACTIVE) { | ||
557 | host->cmd_flags |= SCMD_READY; | ||
558 | tifm_sd_fetch_resp(host->req->stop, | ||
559 | sock); | ||
560 | } | ||
561 | } | ||
562 | if (host_status & TIFM_MMCSD_BRS) | ||
563 | host->cmd_flags |= BRS_READY; | ||
564 | } | ||
565 | |||
566 | if (host->no_dma && cmd->data) { | ||
567 | if (host_status & TIFM_MMCSD_AE) | ||
568 | writel(host_status & TIFM_MMCSD_AE, | ||
569 | sock->addr + SOCK_MMCSD_STATUS); | ||
570 | |||
571 | if (host_status & (TIFM_MMCSD_AE | TIFM_MMCSD_AF | ||
572 | | TIFM_MMCSD_BRS)) { | ||
573 | local_irq_save(flags); | ||
574 | tifm_sd_transfer_data(host); | ||
575 | local_irq_restore(flags); | ||
576 | host_status &= ~TIFM_MMCSD_AE; | ||
577 | } | ||
578 | } | ||
579 | |||
580 | if (host_status & TIFM_MMCSD_EOFB) | ||
581 | host->cmd_flags &= ~CARD_BUSY; | ||
582 | else if (host_status & TIFM_MMCSD_CB) | ||
583 | host->cmd_flags |= CARD_BUSY; | ||
584 | |||
585 | tifm_sd_check_status(host); | ||
586 | } | ||
587 | done: | ||
588 | writel(host_status, sock->addr + SOCK_MMCSD_STATUS); | ||
589 | spin_unlock(&sock->lock); | ||
590 | } | ||
591 | |||
592 | static void tifm_sd_set_data_timeout(struct tifm_sd *host, | ||
593 | struct mmc_data *data) | ||
594 | { | ||
595 | struct tifm_dev *sock = host->dev; | ||
596 | unsigned int data_timeout = data->timeout_clks; | ||
597 | |||
598 | if (fixed_timeout) | ||
599 | return; | ||
600 | |||
601 | data_timeout += data->timeout_ns / | ||
602 | ((1000000000UL / host->clk_freq) * host->clk_div); | ||
603 | |||
604 | if (data_timeout < 0xffff) { | ||
605 | writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO); | ||
606 | writel((~TIFM_MMCSD_DPE) | ||
607 | & readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG), | ||
608 | sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG); | ||
609 | } else { | ||
610 | data_timeout = (data_timeout >> 10) + 1; | ||
611 | if (data_timeout > 0xffff) | ||
612 | data_timeout = 0; /* set to unlimited */ | ||
613 | writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO); | ||
614 | writel(TIFM_MMCSD_DPE | ||
615 | | readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG), | ||
616 | sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG); | ||
617 | } | ||
618 | } | ||
619 | |||
620 | static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq) | ||
621 | { | ||
622 | struct tifm_sd *host = mmc_priv(mmc); | ||
623 | struct tifm_dev *sock = host->dev; | ||
624 | unsigned long flags; | ||
625 | struct mmc_data *r_data = mrq->cmd->data; | ||
626 | |||
627 | spin_lock_irqsave(&sock->lock, flags); | ||
628 | if (host->eject) { | ||
629 | spin_unlock_irqrestore(&sock->lock, flags); | ||
630 | goto err_out; | ||
631 | } | ||
632 | |||
633 | if (host->req) { | ||
634 | printk(KERN_ERR "%s : unfinished request detected\n", | ||
635 | sock->dev.bus_id); | ||
636 | spin_unlock_irqrestore(&sock->lock, flags); | ||
637 | goto err_out; | ||
638 | } | ||
639 | |||
640 | host->cmd_flags = 0; | ||
641 | host->block_pos = 0; | ||
642 | host->sg_pos = 0; | ||
643 | |||
644 | if (r_data) { | ||
645 | tifm_sd_set_data_timeout(host, r_data); | ||
646 | |||
647 | if ((r_data->flags & MMC_DATA_WRITE) && !mrq->stop) | ||
648 | writel(TIFM_MMCSD_EOFB | ||
649 | | readl(sock->addr + SOCK_MMCSD_INT_ENABLE), | ||
650 | sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
651 | |||
652 | if (host->no_dma) { | ||
653 | writel(TIFM_MMCSD_BUFINT | ||
654 | | readl(sock->addr + SOCK_MMCSD_INT_ENABLE), | ||
655 | sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
656 | writel(((TIFM_MMCSD_FIFO_SIZE - 1) << 8) | ||
657 | | (TIFM_MMCSD_FIFO_SIZE - 1), | ||
658 | sock->addr + SOCK_MMCSD_BUFFER_CONFIG); | ||
659 | |||
660 | host->sg_len = r_data->sg_len; | ||
661 | } else { | ||
662 | sg_init_one(&host->bounce_buf, host->bounce_buf_data, | ||
663 | r_data->blksz); | ||
664 | |||
665 | if(1 != tifm_map_sg(sock, &host->bounce_buf, 1, | ||
666 | r_data->flags & MMC_DATA_WRITE | ||
667 | ? PCI_DMA_TODEVICE | ||
668 | : PCI_DMA_FROMDEVICE)) { | ||
669 | printk(KERN_ERR "%s : scatterlist map failed\n", | ||
670 | sock->dev.bus_id); | ||
671 | spin_unlock_irqrestore(&sock->lock, flags); | ||
672 | goto err_out; | ||
673 | } | ||
674 | host->sg_len = tifm_map_sg(sock, r_data->sg, | ||
675 | r_data->sg_len, | ||
676 | r_data->flags | ||
677 | & MMC_DATA_WRITE | ||
678 | ? PCI_DMA_TODEVICE | ||
679 | : PCI_DMA_FROMDEVICE); | ||
680 | if (host->sg_len < 1) { | ||
681 | printk(KERN_ERR "%s : scatterlist map failed\n", | ||
682 | sock->dev.bus_id); | ||
683 | tifm_unmap_sg(sock, &host->bounce_buf, 1, | ||
684 | r_data->flags & MMC_DATA_WRITE | ||
685 | ? PCI_DMA_TODEVICE | ||
686 | : PCI_DMA_FROMDEVICE); | ||
687 | spin_unlock_irqrestore(&sock->lock, flags); | ||
688 | goto err_out; | ||
689 | } | ||
690 | |||
691 | writel(TIFM_FIFO_INT_SETALL, | ||
692 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); | ||
693 | writel(ilog2(r_data->blksz) - 2, | ||
694 | sock->addr + SOCK_FIFO_PAGE_SIZE); | ||
695 | writel(TIFM_FIFO_ENABLE, | ||
696 | sock->addr + SOCK_FIFO_CONTROL); | ||
697 | writel(TIFM_FIFO_INTMASK, | ||
698 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); | ||
699 | |||
700 | if (r_data->flags & MMC_DATA_WRITE) | ||
701 | writel(TIFM_MMCSD_TXDE, | ||
702 | sock->addr + SOCK_MMCSD_BUFFER_CONFIG); | ||
703 | else | ||
704 | writel(TIFM_MMCSD_RXDE, | ||
705 | sock->addr + SOCK_MMCSD_BUFFER_CONFIG); | ||
706 | |||
707 | tifm_sd_set_dma_data(host, r_data); | ||
708 | } | ||
709 | |||
710 | writel(r_data->blocks - 1, | ||
711 | sock->addr + SOCK_MMCSD_NUM_BLOCKS); | ||
712 | writel(r_data->blksz - 1, | ||
713 | sock->addr + SOCK_MMCSD_BLOCK_LEN); | ||
714 | } | ||
715 | |||
716 | host->req = mrq; | ||
717 | mod_timer(&host->timer, jiffies + host->timeout_jiffies); | ||
718 | writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL), | ||
719 | sock->addr + SOCK_CONTROL); | ||
720 | tifm_sd_exec(host, mrq->cmd); | ||
721 | spin_unlock_irqrestore(&sock->lock, flags); | ||
722 | return; | ||
723 | |||
724 | err_out: | ||
725 | mrq->cmd->error = MMC_ERR_TIMEOUT; | ||
726 | mmc_request_done(mmc, mrq); | ||
727 | } | ||
728 | |||
729 | static void tifm_sd_end_cmd(unsigned long data) | ||
730 | { | ||
731 | struct tifm_sd *host = (struct tifm_sd*)data; | ||
732 | struct tifm_dev *sock = host->dev; | ||
733 | struct mmc_host *mmc = tifm_get_drvdata(sock); | ||
734 | struct mmc_request *mrq; | ||
735 | struct mmc_data *r_data = NULL; | ||
736 | unsigned long flags; | ||
737 | |||
738 | spin_lock_irqsave(&sock->lock, flags); | ||
739 | |||
740 | del_timer(&host->timer); | ||
741 | mrq = host->req; | ||
742 | host->req = NULL; | ||
743 | |||
744 | if (!mrq) { | ||
745 | printk(KERN_ERR " %s : no request to complete?\n", | ||
746 | sock->dev.bus_id); | ||
747 | spin_unlock_irqrestore(&sock->lock, flags); | ||
748 | return; | ||
749 | } | ||
750 | |||
751 | r_data = mrq->cmd->data; | ||
752 | if (r_data) { | ||
753 | if (host->no_dma) { | ||
754 | writel((~TIFM_MMCSD_BUFINT) | ||
755 | & readl(sock->addr + SOCK_MMCSD_INT_ENABLE), | ||
756 | sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
757 | } else { | ||
758 | tifm_unmap_sg(sock, &host->bounce_buf, 1, | ||
759 | (r_data->flags & MMC_DATA_WRITE) | ||
760 | ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | ||
761 | tifm_unmap_sg(sock, r_data->sg, r_data->sg_len, | ||
762 | (r_data->flags & MMC_DATA_WRITE) | ||
763 | ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | ||
764 | } | ||
765 | |||
766 | r_data->bytes_xfered = r_data->blocks | ||
767 | - readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1; | ||
768 | r_data->bytes_xfered *= r_data->blksz; | ||
769 | r_data->bytes_xfered += r_data->blksz | ||
770 | - readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1; | ||
771 | } | ||
772 | |||
773 | writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), | ||
774 | sock->addr + SOCK_CONTROL); | ||
775 | |||
776 | spin_unlock_irqrestore(&sock->lock, flags); | ||
777 | mmc_request_done(mmc, mrq); | ||
778 | } | ||
779 | |||
780 | static void tifm_sd_abort(unsigned long data) | ||
781 | { | ||
782 | struct tifm_sd *host = (struct tifm_sd*)data; | ||
783 | |||
784 | printk(KERN_ERR | ||
785 | "%s : card failed to respond for a long period of time " | ||
786 | "(%x, %x)\n", | ||
787 | host->dev->dev.bus_id, host->req->cmd->opcode, host->cmd_flags); | ||
788 | |||
789 | tifm_eject(host->dev); | ||
790 | } | ||
791 | |||
792 | static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios) | ||
793 | { | ||
794 | struct tifm_sd *host = mmc_priv(mmc); | ||
795 | struct tifm_dev *sock = host->dev; | ||
796 | unsigned int clk_div1, clk_div2; | ||
797 | unsigned long flags; | ||
798 | |||
799 | spin_lock_irqsave(&sock->lock, flags); | ||
800 | |||
801 | dev_dbg(&sock->dev, "ios: clock = %u, vdd = %x, bus_mode = %x, " | ||
802 | "chip_select = %x, power_mode = %x, bus_width = %x\n", | ||
803 | ios->clock, ios->vdd, ios->bus_mode, ios->chip_select, | ||
804 | ios->power_mode, ios->bus_width); | ||
805 | |||
806 | if (ios->bus_width == MMC_BUS_WIDTH_4) { | ||
807 | writel(TIFM_MMCSD_4BBUS | readl(sock->addr + SOCK_MMCSD_CONFIG), | ||
808 | sock->addr + SOCK_MMCSD_CONFIG); | ||
809 | } else { | ||
810 | writel((~TIFM_MMCSD_4BBUS) | ||
811 | & readl(sock->addr + SOCK_MMCSD_CONFIG), | ||
812 | sock->addr + SOCK_MMCSD_CONFIG); | ||
813 | } | ||
814 | |||
815 | if (ios->clock) { | ||
816 | clk_div1 = 20000000 / ios->clock; | ||
817 | if (!clk_div1) | ||
818 | clk_div1 = 1; | ||
819 | |||
820 | clk_div2 = 24000000 / ios->clock; | ||
821 | if (!clk_div2) | ||
822 | clk_div2 = 1; | ||
823 | |||
824 | if ((20000000 / clk_div1) > ios->clock) | ||
825 | clk_div1++; | ||
826 | if ((24000000 / clk_div2) > ios->clock) | ||
827 | clk_div2++; | ||
828 | if ((20000000 / clk_div1) > (24000000 / clk_div2)) { | ||
829 | host->clk_freq = 20000000; | ||
830 | host->clk_div = clk_div1; | ||
831 | writel((~TIFM_CTRL_FAST_CLK) | ||
832 | & readl(sock->addr + SOCK_CONTROL), | ||
833 | sock->addr + SOCK_CONTROL); | ||
834 | } else { | ||
835 | host->clk_freq = 24000000; | ||
836 | host->clk_div = clk_div2; | ||
837 | writel(TIFM_CTRL_FAST_CLK | ||
838 | | readl(sock->addr + SOCK_CONTROL), | ||
839 | sock->addr + SOCK_CONTROL); | ||
840 | } | ||
841 | } else { | ||
842 | host->clk_div = 0; | ||
843 | } | ||
844 | host->clk_div &= TIFM_MMCSD_CLKMASK; | ||
845 | writel(host->clk_div | ||
846 | | ((~TIFM_MMCSD_CLKMASK) | ||
847 | & readl(sock->addr + SOCK_MMCSD_CONFIG)), | ||
848 | sock->addr + SOCK_MMCSD_CONFIG); | ||
849 | |||
850 | host->open_drain = (ios->bus_mode == MMC_BUSMODE_OPENDRAIN); | ||
851 | |||
852 | /* chip_select : maybe later */ | ||
853 | //vdd | ||
854 | //power is set before probe / after remove | ||
855 | |||
856 | spin_unlock_irqrestore(&sock->lock, flags); | ||
857 | } | ||
858 | |||
859 | static int tifm_sd_ro(struct mmc_host *mmc) | ||
860 | { | ||
861 | int rc = 0; | ||
862 | struct tifm_sd *host = mmc_priv(mmc); | ||
863 | struct tifm_dev *sock = host->dev; | ||
864 | unsigned long flags; | ||
865 | |||
866 | spin_lock_irqsave(&sock->lock, flags); | ||
867 | if (TIFM_MMCSD_CARD_RO & readl(sock->addr + SOCK_PRESENT_STATE)) | ||
868 | rc = 1; | ||
869 | spin_unlock_irqrestore(&sock->lock, flags); | ||
870 | return rc; | ||
871 | } | ||
872 | |||
873 | static const struct mmc_host_ops tifm_sd_ops = { | ||
874 | .request = tifm_sd_request, | ||
875 | .set_ios = tifm_sd_ios, | ||
876 | .get_ro = tifm_sd_ro | ||
877 | }; | ||
878 | |||
879 | static int tifm_sd_initialize_host(struct tifm_sd *host) | ||
880 | { | ||
881 | int rc; | ||
882 | unsigned int host_status = 0; | ||
883 | struct tifm_dev *sock = host->dev; | ||
884 | |||
885 | writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
886 | mmiowb(); | ||
887 | host->clk_div = 61; | ||
888 | host->clk_freq = 20000000; | ||
889 | writel(TIFM_MMCSD_RESET, sock->addr + SOCK_MMCSD_SYSTEM_CONTROL); | ||
890 | writel(host->clk_div | TIFM_MMCSD_POWER, | ||
891 | sock->addr + SOCK_MMCSD_CONFIG); | ||
892 | |||
893 | /* wait up to 0.51 sec for reset */ | ||
894 | for (rc = 32; rc <= 256; rc <<= 1) { | ||
895 | if (1 & readl(sock->addr + SOCK_MMCSD_SYSTEM_STATUS)) { | ||
896 | rc = 0; | ||
897 | break; | ||
898 | } | ||
899 | msleep(rc); | ||
900 | } | ||
901 | |||
902 | if (rc) { | ||
903 | printk(KERN_ERR "%s : controller failed to reset\n", | ||
904 | sock->dev.bus_id); | ||
905 | return -ENODEV; | ||
906 | } | ||
907 | |||
908 | writel(0, sock->addr + SOCK_MMCSD_NUM_BLOCKS); | ||
909 | writel(host->clk_div | TIFM_MMCSD_POWER, | ||
910 | sock->addr + SOCK_MMCSD_CONFIG); | ||
911 | writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG); | ||
912 | |||
913 | // command timeout fixed to 64 clocks for now | ||
914 | writel(64, sock->addr + SOCK_MMCSD_COMMAND_TO); | ||
915 | writel(TIFM_MMCSD_INAB, sock->addr + SOCK_MMCSD_COMMAND); | ||
916 | |||
917 | for (rc = 16; rc <= 64; rc <<= 1) { | ||
918 | host_status = readl(sock->addr + SOCK_MMCSD_STATUS); | ||
919 | writel(host_status, sock->addr + SOCK_MMCSD_STATUS); | ||
920 | if (!(host_status & TIFM_MMCSD_ERRMASK) | ||
921 | && (host_status & TIFM_MMCSD_EOC)) { | ||
922 | rc = 0; | ||
923 | break; | ||
924 | } | ||
925 | msleep(rc); | ||
926 | } | ||
927 | |||
928 | if (rc) { | ||
929 | printk(KERN_ERR | ||
930 | "%s : card not ready - probe failed on initialization\n", | ||
931 | sock->dev.bus_id); | ||
932 | return -ENODEV; | ||
933 | } | ||
934 | |||
935 | writel(TIFM_MMCSD_CERR | TIFM_MMCSD_BRS | TIFM_MMCSD_EOC | ||
936 | | TIFM_MMCSD_ERRMASK, | ||
937 | sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
938 | mmiowb(); | ||
939 | |||
940 | return 0; | ||
941 | } | ||
942 | |||
943 | static int tifm_sd_probe(struct tifm_dev *sock) | ||
944 | { | ||
945 | struct mmc_host *mmc; | ||
946 | struct tifm_sd *host; | ||
947 | int rc = -EIO; | ||
948 | |||
949 | if (!(TIFM_SOCK_STATE_OCCUPIED | ||
950 | & readl(sock->addr + SOCK_PRESENT_STATE))) { | ||
951 | printk(KERN_WARNING "%s : card gone, unexpectedly\n", | ||
952 | sock->dev.bus_id); | ||
953 | return rc; | ||
954 | } | ||
955 | |||
956 | mmc = mmc_alloc_host(sizeof(struct tifm_sd), &sock->dev); | ||
957 | if (!mmc) | ||
958 | return -ENOMEM; | ||
959 | |||
960 | host = mmc_priv(mmc); | ||
961 | host->no_dma = no_dma; | ||
962 | tifm_set_drvdata(sock, mmc); | ||
963 | host->dev = sock; | ||
964 | host->timeout_jiffies = msecs_to_jiffies(1000); | ||
965 | |||
966 | tasklet_init(&host->finish_tasklet, tifm_sd_end_cmd, | ||
967 | (unsigned long)host); | ||
968 | setup_timer(&host->timer, tifm_sd_abort, (unsigned long)host); | ||
969 | |||
970 | mmc->ops = &tifm_sd_ops; | ||
971 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | ||
972 | mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE; | ||
973 | mmc->f_min = 20000000 / 60; | ||
974 | mmc->f_max = 24000000; | ||
975 | |||
976 | mmc->max_blk_count = 2048; | ||
977 | mmc->max_hw_segs = mmc->max_blk_count; | ||
978 | mmc->max_blk_size = min(TIFM_MMCSD_MAX_BLOCK_SIZE, PAGE_SIZE); | ||
979 | mmc->max_seg_size = mmc->max_blk_count * mmc->max_blk_size; | ||
980 | mmc->max_req_size = mmc->max_seg_size; | ||
981 | mmc->max_phys_segs = mmc->max_hw_segs; | ||
982 | |||
983 | sock->card_event = tifm_sd_card_event; | ||
984 | sock->data_event = tifm_sd_data_event; | ||
985 | rc = tifm_sd_initialize_host(host); | ||
986 | |||
987 | if (!rc) | ||
988 | rc = mmc_add_host(mmc); | ||
989 | if (!rc) | ||
990 | return 0; | ||
991 | |||
992 | mmc_free_host(mmc); | ||
993 | return rc; | ||
994 | } | ||
995 | |||
996 | static void tifm_sd_remove(struct tifm_dev *sock) | ||
997 | { | ||
998 | struct mmc_host *mmc = tifm_get_drvdata(sock); | ||
999 | struct tifm_sd *host = mmc_priv(mmc); | ||
1000 | unsigned long flags; | ||
1001 | |||
1002 | spin_lock_irqsave(&sock->lock, flags); | ||
1003 | host->eject = 1; | ||
1004 | writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
1005 | mmiowb(); | ||
1006 | spin_unlock_irqrestore(&sock->lock, flags); | ||
1007 | |||
1008 | tasklet_kill(&host->finish_tasklet); | ||
1009 | |||
1010 | spin_lock_irqsave(&sock->lock, flags); | ||
1011 | if (host->req) { | ||
1012 | writel(TIFM_FIFO_INT_SETALL, | ||
1013 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); | ||
1014 | writel(0, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); | ||
1015 | host->req->cmd->error = MMC_ERR_TIMEOUT; | ||
1016 | if (host->req->stop) | ||
1017 | host->req->stop->error = MMC_ERR_TIMEOUT; | ||
1018 | tasklet_schedule(&host->finish_tasklet); | ||
1019 | } | ||
1020 | spin_unlock_irqrestore(&sock->lock, flags); | ||
1021 | mmc_remove_host(mmc); | ||
1022 | dev_dbg(&sock->dev, "after remove\n"); | ||
1023 | |||
1024 | /* The meaning of the bit majority in this constant is unknown. */ | ||
1025 | writel(0xfff8 & readl(sock->addr + SOCK_CONTROL), | ||
1026 | sock->addr + SOCK_CONTROL); | ||
1027 | |||
1028 | mmc_free_host(mmc); | ||
1029 | } | ||
1030 | |||
1031 | #ifdef CONFIG_PM | ||
1032 | |||
1033 | static int tifm_sd_suspend(struct tifm_dev *sock, pm_message_t state) | ||
1034 | { | ||
1035 | struct mmc_host *mmc = tifm_get_drvdata(sock); | ||
1036 | int rc; | ||
1037 | |||
1038 | rc = mmc_suspend_host(mmc, state); | ||
1039 | /* The meaning of the bit majority in this constant is unknown. */ | ||
1040 | writel(0xfff8 & readl(sock->addr + SOCK_CONTROL), | ||
1041 | sock->addr + SOCK_CONTROL); | ||
1042 | return rc; | ||
1043 | } | ||
1044 | |||
1045 | static int tifm_sd_resume(struct tifm_dev *sock) | ||
1046 | { | ||
1047 | struct mmc_host *mmc = tifm_get_drvdata(sock); | ||
1048 | struct tifm_sd *host = mmc_priv(mmc); | ||
1049 | int rc; | ||
1050 | |||
1051 | rc = tifm_sd_initialize_host(host); | ||
1052 | dev_dbg(&sock->dev, "resume initialize %d\n", rc); | ||
1053 | |||
1054 | if (rc) | ||
1055 | host->eject = 1; | ||
1056 | else | ||
1057 | rc = mmc_resume_host(mmc); | ||
1058 | |||
1059 | return rc; | ||
1060 | } | ||
1061 | |||
1062 | #else | ||
1063 | |||
1064 | #define tifm_sd_suspend NULL | ||
1065 | #define tifm_sd_resume NULL | ||
1066 | |||
1067 | #endif /* CONFIG_PM */ | ||
1068 | |||
1069 | static struct tifm_device_id tifm_sd_id_tbl[] = { | ||
1070 | { TIFM_TYPE_SD }, { } | ||
1071 | }; | ||
1072 | |||
1073 | static struct tifm_driver tifm_sd_driver = { | ||
1074 | .driver = { | ||
1075 | .name = DRIVER_NAME, | ||
1076 | .owner = THIS_MODULE | ||
1077 | }, | ||
1078 | .id_table = tifm_sd_id_tbl, | ||
1079 | .probe = tifm_sd_probe, | ||
1080 | .remove = tifm_sd_remove, | ||
1081 | .suspend = tifm_sd_suspend, | ||
1082 | .resume = tifm_sd_resume | ||
1083 | }; | ||
1084 | |||
1085 | static int __init tifm_sd_init(void) | ||
1086 | { | ||
1087 | return tifm_register_driver(&tifm_sd_driver); | ||
1088 | } | ||
1089 | |||
1090 | static void __exit tifm_sd_exit(void) | ||
1091 | { | ||
1092 | tifm_unregister_driver(&tifm_sd_driver); | ||
1093 | } | ||
1094 | |||
1095 | MODULE_AUTHOR("Alex Dubov"); | ||
1096 | MODULE_DESCRIPTION("TI FlashMedia SD driver"); | ||
1097 | MODULE_LICENSE("GPL"); | ||
1098 | MODULE_DEVICE_TABLE(tifm, tifm_sd_id_tbl); | ||
1099 | MODULE_VERSION(DRIVER_VERSION); | ||
1100 | |||
1101 | module_init(tifm_sd_init); | ||
1102 | module_exit(tifm_sd_exit); | ||
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/host/wbsd.c index 05ccfc43168f..867ca6a69298 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/host/wbsd.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/wbsd.c - Winbond W83L51xD SD/MMC driver | 2 | * linux/drivers/mmc/wbsd.c - Winbond W83L51xD SD/MMC driver |
3 | * | 3 | * |
4 | * Copyright (C) 2004-2006 Pierre Ossman, All Rights Reserved. | 4 | * Copyright (C) 2004-2007 Pierre Ossman, All Rights Reserved. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/pnp.h> | 33 | #include <linux/pnp.h> |
34 | #include <linux/highmem.h> | 34 | #include <linux/highmem.h> |
35 | #include <linux/mmc/host.h> | 35 | #include <linux/mmc/host.h> |
36 | #include <linux/mmc/protocol.h> | ||
37 | 36 | ||
38 | #include <asm/io.h> | 37 | #include <asm/io.h> |
39 | #include <asm/dma.h> | 38 | #include <asm/dma.h> |
@@ -178,9 +177,8 @@ static void wbsd_init_device(struct wbsd_host *host) | |||
178 | ier = 0; | 177 | ier = 0; |
179 | ier |= WBSD_EINT_CARD; | 178 | ier |= WBSD_EINT_CARD; |
180 | ier |= WBSD_EINT_FIFO_THRE; | 179 | ier |= WBSD_EINT_FIFO_THRE; |
181 | ier |= WBSD_EINT_CCRC; | ||
182 | ier |= WBSD_EINT_TIMEOUT; | ||
183 | ier |= WBSD_EINT_CRC; | 180 | ier |= WBSD_EINT_CRC; |
181 | ier |= WBSD_EINT_TIMEOUT; | ||
184 | ier |= WBSD_EINT_TC; | 182 | ier |= WBSD_EINT_TC; |
185 | 183 | ||
186 | outb(ier, host->base + WBSD_EIR); | 184 | outb(ier, host->base + WBSD_EIR); |
@@ -278,90 +276,36 @@ static inline char *wbsd_sg_to_buffer(struct wbsd_host *host) | |||
278 | 276 | ||
279 | static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data) | 277 | static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data) |
280 | { | 278 | { |
281 | unsigned int len, i, size; | 279 | unsigned int len, i; |
282 | struct scatterlist *sg; | 280 | struct scatterlist *sg; |
283 | char *dmabuf = host->dma_buffer; | 281 | char *dmabuf = host->dma_buffer; |
284 | char *sgbuf; | 282 | char *sgbuf; |
285 | 283 | ||
286 | size = host->size; | ||
287 | |||
288 | sg = data->sg; | 284 | sg = data->sg; |
289 | len = data->sg_len; | 285 | len = data->sg_len; |
290 | 286 | ||
291 | /* | ||
292 | * Just loop through all entries. Size might not | ||
293 | * be the entire list though so make sure that | ||
294 | * we do not transfer too much. | ||
295 | */ | ||
296 | for (i = 0; i < len; i++) { | 287 | for (i = 0; i < len; i++) { |
297 | sgbuf = page_address(sg[i].page) + sg[i].offset; | 288 | sgbuf = page_address(sg[i].page) + sg[i].offset; |
298 | if (size < sg[i].length) | 289 | memcpy(dmabuf, sgbuf, sg[i].length); |
299 | memcpy(dmabuf, sgbuf, size); | ||
300 | else | ||
301 | memcpy(dmabuf, sgbuf, sg[i].length); | ||
302 | dmabuf += sg[i].length; | 290 | dmabuf += sg[i].length; |
303 | |||
304 | if (size < sg[i].length) | ||
305 | size = 0; | ||
306 | else | ||
307 | size -= sg[i].length; | ||
308 | |||
309 | if (size == 0) | ||
310 | break; | ||
311 | } | 291 | } |
312 | |||
313 | /* | ||
314 | * Check that we didn't get a request to transfer | ||
315 | * more data than can fit into the SG list. | ||
316 | */ | ||
317 | |||
318 | BUG_ON(size != 0); | ||
319 | |||
320 | host->size -= size; | ||
321 | } | 292 | } |
322 | 293 | ||
323 | static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data) | 294 | static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data) |
324 | { | 295 | { |
325 | unsigned int len, i, size; | 296 | unsigned int len, i; |
326 | struct scatterlist *sg; | 297 | struct scatterlist *sg; |
327 | char *dmabuf = host->dma_buffer; | 298 | char *dmabuf = host->dma_buffer; |
328 | char *sgbuf; | 299 | char *sgbuf; |
329 | 300 | ||
330 | size = host->size; | ||
331 | |||
332 | sg = data->sg; | 301 | sg = data->sg; |
333 | len = data->sg_len; | 302 | len = data->sg_len; |
334 | 303 | ||
335 | /* | ||
336 | * Just loop through all entries. Size might not | ||
337 | * be the entire list though so make sure that | ||
338 | * we do not transfer too much. | ||
339 | */ | ||
340 | for (i = 0; i < len; i++) { | 304 | for (i = 0; i < len; i++) { |
341 | sgbuf = page_address(sg[i].page) + sg[i].offset; | 305 | sgbuf = page_address(sg[i].page) + sg[i].offset; |
342 | if (size < sg[i].length) | 306 | memcpy(sgbuf, dmabuf, sg[i].length); |
343 | memcpy(sgbuf, dmabuf, size); | ||
344 | else | ||
345 | memcpy(sgbuf, dmabuf, sg[i].length); | ||
346 | dmabuf += sg[i].length; | 307 | dmabuf += sg[i].length; |
347 | |||
348 | if (size < sg[i].length) | ||
349 | size = 0; | ||
350 | else | ||
351 | size -= sg[i].length; | ||
352 | |||
353 | if (size == 0) | ||
354 | break; | ||
355 | } | 308 | } |
356 | |||
357 | /* | ||
358 | * Check that we didn't get a request to transfer | ||
359 | * more data than can fit into the SG list. | ||
360 | */ | ||
361 | |||
362 | BUG_ON(size != 0); | ||
363 | |||
364 | host->size -= size; | ||
365 | } | 309 | } |
366 | 310 | ||
367 | /* | 311 | /* |
@@ -484,7 +428,7 @@ static void wbsd_empty_fifo(struct wbsd_host *host) | |||
484 | /* | 428 | /* |
485 | * Handle excessive data. | 429 | * Handle excessive data. |
486 | */ | 430 | */ |
487 | if (data->bytes_xfered == host->size) | 431 | if (host->num_sg == 0) |
488 | return; | 432 | return; |
489 | 433 | ||
490 | buffer = wbsd_sg_to_buffer(host) + host->offset; | 434 | buffer = wbsd_sg_to_buffer(host) + host->offset; |
@@ -514,31 +458,14 @@ static void wbsd_empty_fifo(struct wbsd_host *host) | |||
514 | data->bytes_xfered++; | 458 | data->bytes_xfered++; |
515 | 459 | ||
516 | /* | 460 | /* |
517 | * Transfer done? | ||
518 | */ | ||
519 | if (data->bytes_xfered == host->size) | ||
520 | return; | ||
521 | |||
522 | /* | ||
523 | * End of scatter list entry? | 461 | * End of scatter list entry? |
524 | */ | 462 | */ |
525 | if (host->remain == 0) { | 463 | if (host->remain == 0) { |
526 | /* | 464 | /* |
527 | * Get next entry. Check if last. | 465 | * Get next entry. Check if last. |
528 | */ | 466 | */ |
529 | if (!wbsd_next_sg(host)) { | 467 | if (!wbsd_next_sg(host)) |
530 | /* | ||
531 | * We should never reach this point. | ||
532 | * It means that we're trying to | ||
533 | * transfer more blocks than can fit | ||
534 | * into the scatter list. | ||
535 | */ | ||
536 | BUG_ON(1); | ||
537 | |||
538 | host->size = data->bytes_xfered; | ||
539 | |||
540 | return; | 468 | return; |
541 | } | ||
542 | 469 | ||
543 | buffer = wbsd_sg_to_buffer(host); | 470 | buffer = wbsd_sg_to_buffer(host); |
544 | } | 471 | } |
@@ -550,7 +477,7 @@ static void wbsd_empty_fifo(struct wbsd_host *host) | |||
550 | * hardware problem. The chip doesn't trigger | 477 | * hardware problem. The chip doesn't trigger |
551 | * FIFO threshold interrupts properly. | 478 | * FIFO threshold interrupts properly. |
552 | */ | 479 | */ |
553 | if ((host->size - data->bytes_xfered) < 16) | 480 | if ((data->blocks * data->blksz - data->bytes_xfered) < 16) |
554 | tasklet_schedule(&host->fifo_tasklet); | 481 | tasklet_schedule(&host->fifo_tasklet); |
555 | } | 482 | } |
556 | 483 | ||
@@ -564,7 +491,7 @@ static void wbsd_fill_fifo(struct wbsd_host *host) | |||
564 | * Check that we aren't being called after the | 491 | * Check that we aren't being called after the |
565 | * entire buffer has been transfered. | 492 | * entire buffer has been transfered. |
566 | */ | 493 | */ |
567 | if (data->bytes_xfered == host->size) | 494 | if (host->num_sg == 0) |
568 | return; | 495 | return; |
569 | 496 | ||
570 | buffer = wbsd_sg_to_buffer(host) + host->offset; | 497 | buffer = wbsd_sg_to_buffer(host) + host->offset; |
@@ -594,31 +521,14 @@ static void wbsd_fill_fifo(struct wbsd_host *host) | |||
594 | data->bytes_xfered++; | 521 | data->bytes_xfered++; |
595 | 522 | ||
596 | /* | 523 | /* |
597 | * Transfer done? | ||
598 | */ | ||
599 | if (data->bytes_xfered == host->size) | ||
600 | return; | ||
601 | |||
602 | /* | ||
603 | * End of scatter list entry? | 524 | * End of scatter list entry? |
604 | */ | 525 | */ |
605 | if (host->remain == 0) { | 526 | if (host->remain == 0) { |
606 | /* | 527 | /* |
607 | * Get next entry. Check if last. | 528 | * Get next entry. Check if last. |
608 | */ | 529 | */ |
609 | if (!wbsd_next_sg(host)) { | 530 | if (!wbsd_next_sg(host)) |
610 | /* | ||
611 | * We should never reach this point. | ||
612 | * It means that we're trying to | ||
613 | * transfer more blocks than can fit | ||
614 | * into the scatter list. | ||
615 | */ | ||
616 | BUG_ON(1); | ||
617 | |||
618 | host->size = data->bytes_xfered; | ||
619 | |||
620 | return; | 531 | return; |
621 | } | ||
622 | 532 | ||
623 | buffer = wbsd_sg_to_buffer(host); | 533 | buffer = wbsd_sg_to_buffer(host); |
624 | } | 534 | } |
@@ -638,6 +548,7 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) | |||
638 | u16 blksize; | 548 | u16 blksize; |
639 | u8 setup; | 549 | u8 setup; |
640 | unsigned long dmaflags; | 550 | unsigned long dmaflags; |
551 | unsigned int size; | ||
641 | 552 | ||
642 | DBGF("blksz %04x blks %04x flags %08x\n", | 553 | DBGF("blksz %04x blks %04x flags %08x\n", |
643 | data->blksz, data->blocks, data->flags); | 554 | data->blksz, data->blocks, data->flags); |
@@ -647,7 +558,7 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) | |||
647 | /* | 558 | /* |
648 | * Calculate size. | 559 | * Calculate size. |
649 | */ | 560 | */ |
650 | host->size = data->blocks * data->blksz; | 561 | size = data->blocks * data->blksz; |
651 | 562 | ||
652 | /* | 563 | /* |
653 | * Check timeout values for overflow. | 564 | * Check timeout values for overflow. |
@@ -705,8 +616,8 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) | |||
705 | /* | 616 | /* |
706 | * The buffer for DMA is only 64 kB. | 617 | * The buffer for DMA is only 64 kB. |
707 | */ | 618 | */ |
708 | BUG_ON(host->size > 0x10000); | 619 | BUG_ON(size > 0x10000); |
709 | if (host->size > 0x10000) { | 620 | if (size > 0x10000) { |
710 | data->error = MMC_ERR_INVALID; | 621 | data->error = MMC_ERR_INVALID; |
711 | return; | 622 | return; |
712 | } | 623 | } |
@@ -729,7 +640,7 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) | |||
729 | else | 640 | else |
730 | set_dma_mode(host->dma, DMA_MODE_WRITE & ~0x40); | 641 | set_dma_mode(host->dma, DMA_MODE_WRITE & ~0x40); |
731 | set_dma_addr(host->dma, host->dma_addr); | 642 | set_dma_addr(host->dma, host->dma_addr); |
732 | set_dma_count(host->dma, host->size); | 643 | set_dma_count(host->dma, size); |
733 | 644 | ||
734 | enable_dma(host->dma); | 645 | enable_dma(host->dma); |
735 | release_dma_lock(dmaflags); | 646 | release_dma_lock(dmaflags); |
@@ -812,6 +723,10 @@ static void wbsd_finish_data(struct wbsd_host *host, struct mmc_data *data) | |||
812 | count = get_dma_residue(host->dma); | 723 | count = get_dma_residue(host->dma); |
813 | release_dma_lock(dmaflags); | 724 | release_dma_lock(dmaflags); |
814 | 725 | ||
726 | data->bytes_xfered = host->mrq->data->blocks * | ||
727 | host->mrq->data->blksz - count; | ||
728 | data->bytes_xfered -= data->bytes_xfered % data->blksz; | ||
729 | |||
815 | /* | 730 | /* |
816 | * Any leftover data? | 731 | * Any leftover data? |
817 | */ | 732 | */ |
@@ -820,7 +735,8 @@ static void wbsd_finish_data(struct wbsd_host *host, struct mmc_data *data) | |||
820 | "%d bytes left.\n", | 735 | "%d bytes left.\n", |
821 | mmc_hostname(host->mmc), count); | 736 | mmc_hostname(host->mmc), count); |
822 | 737 | ||
823 | data->error = MMC_ERR_FAILED; | 738 | if (data->error == MMC_ERR_NONE) |
739 | data->error = MMC_ERR_FAILED; | ||
824 | } else { | 740 | } else { |
825 | /* | 741 | /* |
826 | * Transfer data from DMA buffer to | 742 | * Transfer data from DMA buffer to |
@@ -828,8 +744,11 @@ static void wbsd_finish_data(struct wbsd_host *host, struct mmc_data *data) | |||
828 | */ | 744 | */ |
829 | if (data->flags & MMC_DATA_READ) | 745 | if (data->flags & MMC_DATA_READ) |
830 | wbsd_dma_to_sg(host, data); | 746 | wbsd_dma_to_sg(host, data); |
747 | } | ||
831 | 748 | ||
832 | data->bytes_xfered = host->size; | 749 | if (data->error != MMC_ERR_NONE) { |
750 | if (data->bytes_xfered) | ||
751 | data->bytes_xfered -= data->blksz; | ||
833 | } | 752 | } |
834 | } | 753 | } |
835 | 754 | ||
@@ -869,24 +788,7 @@ static void wbsd_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
869 | goto done; | 788 | goto done; |
870 | } | 789 | } |
871 | 790 | ||
872 | /* | ||
873 | * Does the request include data? | ||
874 | */ | ||
875 | if (cmd->data) { | 791 | if (cmd->data) { |
876 | wbsd_prepare_data(host, cmd->data); | ||
877 | |||
878 | if (cmd->data->error != MMC_ERR_NONE) | ||
879 | goto done; | ||
880 | } | ||
881 | |||
882 | wbsd_send_command(host, cmd); | ||
883 | |||
884 | /* | ||
885 | * If this is a data transfer the request | ||
886 | * will be finished after the data has | ||
887 | * transfered. | ||
888 | */ | ||
889 | if (cmd->data && (cmd->error == MMC_ERR_NONE)) { | ||
890 | /* | 792 | /* |
891 | * The hardware is so delightfully stupid that it has a list | 793 | * The hardware is so delightfully stupid that it has a list |
892 | * of "data" commands. If a command isn't on this list, it'll | 794 | * of "data" commands. If a command isn't on this list, it'll |
@@ -918,14 +820,30 @@ static void wbsd_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
918 | "supported by this controller.\n", | 820 | "supported by this controller.\n", |
919 | mmc_hostname(host->mmc), cmd->opcode); | 821 | mmc_hostname(host->mmc), cmd->opcode); |
920 | #endif | 822 | #endif |
921 | cmd->data->error = MMC_ERR_INVALID; | 823 | cmd->error = MMC_ERR_INVALID; |
922 | |||
923 | if (cmd->data->stop) | ||
924 | wbsd_send_command(host, cmd->data->stop); | ||
925 | 824 | ||
926 | goto done; | 825 | goto done; |
927 | }; | 826 | }; |
827 | } | ||
828 | |||
829 | /* | ||
830 | * Does the request include data? | ||
831 | */ | ||
832 | if (cmd->data) { | ||
833 | wbsd_prepare_data(host, cmd->data); | ||
834 | |||
835 | if (cmd->data->error != MMC_ERR_NONE) | ||
836 | goto done; | ||
837 | } | ||
838 | |||
839 | wbsd_send_command(host, cmd); | ||
928 | 840 | ||
841 | /* | ||
842 | * If this is a data transfer the request | ||
843 | * will be finished after the data has | ||
844 | * transfered. | ||
845 | */ | ||
846 | if (cmd->data && (cmd->error == MMC_ERR_NONE)) { | ||
929 | /* | 847 | /* |
930 | * Dirty fix for hardware bug. | 848 | * Dirty fix for hardware bug. |
931 | */ | 849 | */ |
@@ -1167,7 +1085,7 @@ static void wbsd_tasklet_fifo(unsigned long param) | |||
1167 | /* | 1085 | /* |
1168 | * Done? | 1086 | * Done? |
1169 | */ | 1087 | */ |
1170 | if (host->size == data->bytes_xfered) { | 1088 | if (host->num_sg == 0) { |
1171 | wbsd_write_index(host, WBSD_IDX_FIFOEN, 0); | 1089 | wbsd_write_index(host, WBSD_IDX_FIFOEN, 0); |
1172 | tasklet_schedule(&host->finish_tasklet); | 1090 | tasklet_schedule(&host->finish_tasklet); |
1173 | } | 1091 | } |
@@ -1245,30 +1163,6 @@ end: | |||
1245 | spin_unlock(&host->lock); | 1163 | spin_unlock(&host->lock); |
1246 | } | 1164 | } |
1247 | 1165 | ||
1248 | static void wbsd_tasklet_block(unsigned long param) | ||
1249 | { | ||
1250 | struct wbsd_host *host = (struct wbsd_host *)param; | ||
1251 | struct mmc_data *data; | ||
1252 | |||
1253 | spin_lock(&host->lock); | ||
1254 | |||
1255 | if ((wbsd_read_index(host, WBSD_IDX_CRCSTATUS) & WBSD_CRC_MASK) != | ||
1256 | WBSD_CRC_OK) { | ||
1257 | data = wbsd_get_data(host); | ||
1258 | if (!data) | ||
1259 | goto end; | ||
1260 | |||
1261 | DBGF("CRC error\n"); | ||
1262 | |||
1263 | data->error = MMC_ERR_BADCRC; | ||
1264 | |||
1265 | tasklet_schedule(&host->finish_tasklet); | ||
1266 | } | ||
1267 | |||
1268 | end: | ||
1269 | spin_unlock(&host->lock); | ||
1270 | } | ||
1271 | |||
1272 | /* | 1166 | /* |
1273 | * Interrupt handling | 1167 | * Interrupt handling |
1274 | */ | 1168 | */ |
@@ -1299,8 +1193,6 @@ static irqreturn_t wbsd_irq(int irq, void *dev_id) | |||
1299 | tasklet_hi_schedule(&host->crc_tasklet); | 1193 | tasklet_hi_schedule(&host->crc_tasklet); |
1300 | if (isr & WBSD_INT_TIMEOUT) | 1194 | if (isr & WBSD_INT_TIMEOUT) |
1301 | tasklet_hi_schedule(&host->timeout_tasklet); | 1195 | tasklet_hi_schedule(&host->timeout_tasklet); |
1302 | if (isr & WBSD_INT_BUSYEND) | ||
1303 | tasklet_hi_schedule(&host->block_tasklet); | ||
1304 | if (isr & WBSD_INT_TC) | 1196 | if (isr & WBSD_INT_TC) |
1305 | tasklet_schedule(&host->finish_tasklet); | 1197 | tasklet_schedule(&host->finish_tasklet); |
1306 | 1198 | ||
@@ -1601,8 +1493,6 @@ static int __devinit wbsd_request_irq(struct wbsd_host *host, int irq) | |||
1601 | (unsigned long)host); | 1493 | (unsigned long)host); |
1602 | tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, | 1494 | tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, |
1603 | (unsigned long)host); | 1495 | (unsigned long)host); |
1604 | tasklet_init(&host->block_tasklet, wbsd_tasklet_block, | ||
1605 | (unsigned long)host); | ||
1606 | 1496 | ||
1607 | return 0; | 1497 | return 0; |
1608 | } | 1498 | } |
@@ -1621,7 +1511,6 @@ static void __devexit wbsd_release_irq(struct wbsd_host *host) | |||
1621 | tasklet_kill(&host->crc_tasklet); | 1511 | tasklet_kill(&host->crc_tasklet); |
1622 | tasklet_kill(&host->timeout_tasklet); | 1512 | tasklet_kill(&host->timeout_tasklet); |
1623 | tasklet_kill(&host->finish_tasklet); | 1513 | tasklet_kill(&host->finish_tasklet); |
1624 | tasklet_kill(&host->block_tasklet); | ||
1625 | } | 1514 | } |
1626 | 1515 | ||
1627 | /* | 1516 | /* |
diff --git a/drivers/mmc/wbsd.h b/drivers/mmc/host/wbsd.h index d06718b0e2ab..873bda1e59b4 100644 --- a/drivers/mmc/wbsd.h +++ b/drivers/mmc/host/wbsd.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/wbsd.h - Winbond W83L51xD SD/MMC driver | 2 | * linux/drivers/mmc/wbsd.h - Winbond W83L51xD SD/MMC driver |
3 | * | 3 | * |
4 | * Copyright (C) 2004-2005 Pierre Ossman, All Rights Reserved. | 4 | * Copyright (C) 2004-2007 Pierre Ossman, All Rights Reserved. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -46,10 +46,10 @@ | |||
46 | 46 | ||
47 | #define WBSD_EINT_CARD 0x40 | 47 | #define WBSD_EINT_CARD 0x40 |
48 | #define WBSD_EINT_FIFO_THRE 0x20 | 48 | #define WBSD_EINT_FIFO_THRE 0x20 |
49 | #define WBSD_EINT_CCRC 0x10 | 49 | #define WBSD_EINT_CRC 0x10 |
50 | #define WBSD_EINT_TIMEOUT 0x08 | 50 | #define WBSD_EINT_TIMEOUT 0x08 |
51 | #define WBSD_EINT_PROGEND 0x04 | 51 | #define WBSD_EINT_PROGEND 0x04 |
52 | #define WBSD_EINT_CRC 0x02 | 52 | #define WBSD_EINT_BUSYEND 0x02 |
53 | #define WBSD_EINT_TC 0x01 | 53 | #define WBSD_EINT_TC 0x01 |
54 | 54 | ||
55 | #define WBSD_INT_PENDING 0x80 | 55 | #define WBSD_INT_PENDING 0x80 |
@@ -158,8 +158,6 @@ struct wbsd_host | |||
158 | unsigned int offset; /* Offset into current entry */ | 158 | unsigned int offset; /* Offset into current entry */ |
159 | unsigned int remain; /* Data left in curren entry */ | 159 | unsigned int remain; /* Data left in curren entry */ |
160 | 160 | ||
161 | int size; /* Total size of transfer */ | ||
162 | |||
163 | char* dma_buffer; /* ISA DMA buffer */ | 161 | char* dma_buffer; /* ISA DMA buffer */ |
164 | dma_addr_t dma_addr; /* Physical address for same */ | 162 | dma_addr_t dma_addr; /* Physical address for same */ |
165 | 163 | ||
@@ -182,7 +180,6 @@ struct wbsd_host | |||
182 | struct tasklet_struct crc_tasklet; | 180 | struct tasklet_struct crc_tasklet; |
183 | struct tasklet_struct timeout_tasklet; | 181 | struct tasklet_struct timeout_tasklet; |
184 | struct tasklet_struct finish_tasklet; | 182 | struct tasklet_struct finish_tasklet; |
185 | struct tasklet_struct block_tasklet; | ||
186 | 183 | ||
187 | struct timer_list ignore_timer; /* Ignore detection timer */ | 184 | struct timer_list ignore_timer; /* Ignore detection timer */ |
188 | }; | 185 | }; |
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c deleted file mode 100644 index 4a73e8b2428d..000000000000 --- a/drivers/mmc/mmc.c +++ /dev/null | |||
@@ -1,1724 +0,0 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/mmc.c | ||
3 | * | ||
4 | * Copyright (C) 2003-2004 Russell King, All Rights Reserved. | ||
5 | * SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. | ||
6 | * SD support Copyright (C) 2005 Pierre Ossman, All Rights Reserved. | ||
7 | * MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/completion.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/pagemap.h> | ||
20 | #include <linux/err.h> | ||
21 | #include <asm/scatterlist.h> | ||
22 | #include <linux/scatterlist.h> | ||
23 | |||
24 | #include <linux/mmc/card.h> | ||
25 | #include <linux/mmc/host.h> | ||
26 | #include <linux/mmc/protocol.h> | ||
27 | |||
28 | #include "mmc.h" | ||
29 | |||
30 | #define CMD_RETRIES 3 | ||
31 | |||
32 | /* | ||
33 | * OCR Bit positions to 10s of Vdd mV. | ||
34 | */ | ||
35 | static const unsigned short mmc_ocr_bit_to_vdd[] = { | ||
36 | 150, 155, 160, 165, 170, 180, 190, 200, | ||
37 | 210, 220, 230, 240, 250, 260, 270, 280, | ||
38 | 290, 300, 310, 320, 330, 340, 350, 360 | ||
39 | }; | ||
40 | |||
41 | static const unsigned int tran_exp[] = { | ||
42 | 10000, 100000, 1000000, 10000000, | ||
43 | 0, 0, 0, 0 | ||
44 | }; | ||
45 | |||
46 | static const unsigned char tran_mant[] = { | ||
47 | 0, 10, 12, 13, 15, 20, 25, 30, | ||
48 | 35, 40, 45, 50, 55, 60, 70, 80, | ||
49 | }; | ||
50 | |||
51 | static const unsigned int tacc_exp[] = { | ||
52 | 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, | ||
53 | }; | ||
54 | |||
55 | static const unsigned int tacc_mant[] = { | ||
56 | 0, 10, 12, 13, 15, 20, 25, 30, | ||
57 | 35, 40, 45, 50, 55, 60, 70, 80, | ||
58 | }; | ||
59 | |||
60 | |||
61 | /** | ||
62 | * mmc_request_done - finish processing an MMC request | ||
63 | * @host: MMC host which completed request | ||
64 | * @mrq: MMC request which request | ||
65 | * | ||
66 | * MMC drivers should call this function when they have completed | ||
67 | * their processing of a request. | ||
68 | */ | ||
69 | void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) | ||
70 | { | ||
71 | struct mmc_command *cmd = mrq->cmd; | ||
72 | int err = cmd->error; | ||
73 | |||
74 | pr_debug("%s: req done (CMD%u): %d/%d/%d: %08x %08x %08x %08x\n", | ||
75 | mmc_hostname(host), cmd->opcode, err, | ||
76 | mrq->data ? mrq->data->error : 0, | ||
77 | mrq->stop ? mrq->stop->error : 0, | ||
78 | cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); | ||
79 | |||
80 | if (err && cmd->retries) { | ||
81 | cmd->retries--; | ||
82 | cmd->error = 0; | ||
83 | host->ops->request(host, mrq); | ||
84 | } else if (mrq->done) { | ||
85 | mrq->done(mrq); | ||
86 | } | ||
87 | } | ||
88 | |||
89 | EXPORT_SYMBOL(mmc_request_done); | ||
90 | |||
91 | /** | ||
92 | * mmc_start_request - start a command on a host | ||
93 | * @host: MMC host to start command on | ||
94 | * @mrq: MMC request to start | ||
95 | * | ||
96 | * Queue a command on the specified host. We expect the | ||
97 | * caller to be holding the host lock with interrupts disabled. | ||
98 | */ | ||
99 | void | ||
100 | mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) | ||
101 | { | ||
102 | pr_debug("%s: starting CMD%u arg %08x flags %08x\n", | ||
103 | mmc_hostname(host), mrq->cmd->opcode, | ||
104 | mrq->cmd->arg, mrq->cmd->flags); | ||
105 | |||
106 | WARN_ON(!host->claimed); | ||
107 | |||
108 | mrq->cmd->error = 0; | ||
109 | mrq->cmd->mrq = mrq; | ||
110 | if (mrq->data) { | ||
111 | BUG_ON(mrq->data->blksz > host->max_blk_size); | ||
112 | BUG_ON(mrq->data->blocks > host->max_blk_count); | ||
113 | BUG_ON(mrq->data->blocks * mrq->data->blksz > | ||
114 | host->max_req_size); | ||
115 | |||
116 | mrq->cmd->data = mrq->data; | ||
117 | mrq->data->error = 0; | ||
118 | mrq->data->mrq = mrq; | ||
119 | if (mrq->stop) { | ||
120 | mrq->data->stop = mrq->stop; | ||
121 | mrq->stop->error = 0; | ||
122 | mrq->stop->mrq = mrq; | ||
123 | } | ||
124 | } | ||
125 | host->ops->request(host, mrq); | ||
126 | } | ||
127 | |||
128 | EXPORT_SYMBOL(mmc_start_request); | ||
129 | |||
130 | static void mmc_wait_done(struct mmc_request *mrq) | ||
131 | { | ||
132 | complete(mrq->done_data); | ||
133 | } | ||
134 | |||
135 | int mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) | ||
136 | { | ||
137 | DECLARE_COMPLETION_ONSTACK(complete); | ||
138 | |||
139 | mrq->done_data = &complete; | ||
140 | mrq->done = mmc_wait_done; | ||
141 | |||
142 | mmc_start_request(host, mrq); | ||
143 | |||
144 | wait_for_completion(&complete); | ||
145 | |||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | EXPORT_SYMBOL(mmc_wait_for_req); | ||
150 | |||
151 | /** | ||
152 | * mmc_wait_for_cmd - start a command and wait for completion | ||
153 | * @host: MMC host to start command | ||
154 | * @cmd: MMC command to start | ||
155 | * @retries: maximum number of retries | ||
156 | * | ||
157 | * Start a new MMC command for a host, and wait for the command | ||
158 | * to complete. Return any error that occurred while the command | ||
159 | * was executing. Do not attempt to parse the response. | ||
160 | */ | ||
161 | int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries) | ||
162 | { | ||
163 | struct mmc_request mrq; | ||
164 | |||
165 | BUG_ON(!host->claimed); | ||
166 | |||
167 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
168 | |||
169 | memset(cmd->resp, 0, sizeof(cmd->resp)); | ||
170 | cmd->retries = retries; | ||
171 | |||
172 | mrq.cmd = cmd; | ||
173 | cmd->data = NULL; | ||
174 | |||
175 | mmc_wait_for_req(host, &mrq); | ||
176 | |||
177 | return cmd->error; | ||
178 | } | ||
179 | |||
180 | EXPORT_SYMBOL(mmc_wait_for_cmd); | ||
181 | |||
182 | /** | ||
183 | * mmc_wait_for_app_cmd - start an application command and wait for | ||
184 | completion | ||
185 | * @host: MMC host to start command | ||
186 | * @rca: RCA to send MMC_APP_CMD to | ||
187 | * @cmd: MMC command to start | ||
188 | * @retries: maximum number of retries | ||
189 | * | ||
190 | * Sends a MMC_APP_CMD, checks the card response, sends the command | ||
191 | * in the parameter and waits for it to complete. Return any error | ||
192 | * that occurred while the command was executing. Do not attempt to | ||
193 | * parse the response. | ||
194 | */ | ||
195 | int mmc_wait_for_app_cmd(struct mmc_host *host, unsigned int rca, | ||
196 | struct mmc_command *cmd, int retries) | ||
197 | { | ||
198 | struct mmc_request mrq; | ||
199 | struct mmc_command appcmd; | ||
200 | |||
201 | int i, err; | ||
202 | |||
203 | BUG_ON(!host->claimed); | ||
204 | BUG_ON(retries < 0); | ||
205 | |||
206 | err = MMC_ERR_INVALID; | ||
207 | |||
208 | /* | ||
209 | * We have to resend MMC_APP_CMD for each attempt so | ||
210 | * we cannot use the retries field in mmc_command. | ||
211 | */ | ||
212 | for (i = 0;i <= retries;i++) { | ||
213 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
214 | |||
215 | appcmd.opcode = MMC_APP_CMD; | ||
216 | appcmd.arg = rca << 16; | ||
217 | appcmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
218 | appcmd.retries = 0; | ||
219 | memset(appcmd.resp, 0, sizeof(appcmd.resp)); | ||
220 | appcmd.data = NULL; | ||
221 | |||
222 | mrq.cmd = &appcmd; | ||
223 | appcmd.data = NULL; | ||
224 | |||
225 | mmc_wait_for_req(host, &mrq); | ||
226 | |||
227 | if (appcmd.error) { | ||
228 | err = appcmd.error; | ||
229 | continue; | ||
230 | } | ||
231 | |||
232 | /* Check that card supported application commands */ | ||
233 | if (!(appcmd.resp[0] & R1_APP_CMD)) | ||
234 | return MMC_ERR_FAILED; | ||
235 | |||
236 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
237 | |||
238 | memset(cmd->resp, 0, sizeof(cmd->resp)); | ||
239 | cmd->retries = 0; | ||
240 | |||
241 | mrq.cmd = cmd; | ||
242 | cmd->data = NULL; | ||
243 | |||
244 | mmc_wait_for_req(host, &mrq); | ||
245 | |||
246 | err = cmd->error; | ||
247 | if (cmd->error == MMC_ERR_NONE) | ||
248 | break; | ||
249 | } | ||
250 | |||
251 | return err; | ||
252 | } | ||
253 | |||
254 | EXPORT_SYMBOL(mmc_wait_for_app_cmd); | ||
255 | |||
256 | /** | ||
257 | * mmc_set_data_timeout - set the timeout for a data command | ||
258 | * @data: data phase for command | ||
259 | * @card: the MMC card associated with the data transfer | ||
260 | * @write: flag to differentiate reads from writes | ||
261 | */ | ||
262 | void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card, | ||
263 | int write) | ||
264 | { | ||
265 | unsigned int mult; | ||
266 | |||
267 | /* | ||
268 | * SD cards use a 100 multiplier rather than 10 | ||
269 | */ | ||
270 | mult = mmc_card_sd(card) ? 100 : 10; | ||
271 | |||
272 | /* | ||
273 | * Scale up the multiplier (and therefore the timeout) by | ||
274 | * the r2w factor for writes. | ||
275 | */ | ||
276 | if (write) | ||
277 | mult <<= card->csd.r2w_factor; | ||
278 | |||
279 | data->timeout_ns = card->csd.tacc_ns * mult; | ||
280 | data->timeout_clks = card->csd.tacc_clks * mult; | ||
281 | |||
282 | /* | ||
283 | * SD cards also have an upper limit on the timeout. | ||
284 | */ | ||
285 | if (mmc_card_sd(card)) { | ||
286 | unsigned int timeout_us, limit_us; | ||
287 | |||
288 | timeout_us = data->timeout_ns / 1000; | ||
289 | timeout_us += data->timeout_clks * 1000 / | ||
290 | (card->host->ios.clock / 1000); | ||
291 | |||
292 | if (write) | ||
293 | limit_us = 250000; | ||
294 | else | ||
295 | limit_us = 100000; | ||
296 | |||
297 | /* | ||
298 | * SDHC cards always use these fixed values. | ||
299 | */ | ||
300 | if (timeout_us > limit_us || mmc_card_blockaddr(card)) { | ||
301 | data->timeout_ns = limit_us * 1000; | ||
302 | data->timeout_clks = 0; | ||
303 | } | ||
304 | } | ||
305 | } | ||
306 | EXPORT_SYMBOL(mmc_set_data_timeout); | ||
307 | |||
308 | static int mmc_select_card(struct mmc_host *host, struct mmc_card *card); | ||
309 | |||
310 | /** | ||
311 | * __mmc_claim_host - exclusively claim a host | ||
312 | * @host: mmc host to claim | ||
313 | * @card: mmc card to claim host for | ||
314 | * | ||
315 | * Claim a host for a set of operations. If a valid card | ||
316 | * is passed and this wasn't the last card selected, select | ||
317 | * the card before returning. | ||
318 | * | ||
319 | * Note: you should use mmc_card_claim_host or mmc_claim_host. | ||
320 | */ | ||
321 | int __mmc_claim_host(struct mmc_host *host, struct mmc_card *card) | ||
322 | { | ||
323 | DECLARE_WAITQUEUE(wait, current); | ||
324 | unsigned long flags; | ||
325 | int err = 0; | ||
326 | |||
327 | add_wait_queue(&host->wq, &wait); | ||
328 | spin_lock_irqsave(&host->lock, flags); | ||
329 | while (1) { | ||
330 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
331 | if (!host->claimed) | ||
332 | break; | ||
333 | spin_unlock_irqrestore(&host->lock, flags); | ||
334 | schedule(); | ||
335 | spin_lock_irqsave(&host->lock, flags); | ||
336 | } | ||
337 | set_current_state(TASK_RUNNING); | ||
338 | host->claimed = 1; | ||
339 | spin_unlock_irqrestore(&host->lock, flags); | ||
340 | remove_wait_queue(&host->wq, &wait); | ||
341 | |||
342 | if (card != (void *)-1) { | ||
343 | err = mmc_select_card(host, card); | ||
344 | if (err != MMC_ERR_NONE) | ||
345 | return err; | ||
346 | } | ||
347 | |||
348 | return err; | ||
349 | } | ||
350 | |||
351 | EXPORT_SYMBOL(__mmc_claim_host); | ||
352 | |||
353 | /** | ||
354 | * mmc_release_host - release a host | ||
355 | * @host: mmc host to release | ||
356 | * | ||
357 | * Release a MMC host, allowing others to claim the host | ||
358 | * for their operations. | ||
359 | */ | ||
360 | void mmc_release_host(struct mmc_host *host) | ||
361 | { | ||
362 | unsigned long flags; | ||
363 | |||
364 | BUG_ON(!host->claimed); | ||
365 | |||
366 | spin_lock_irqsave(&host->lock, flags); | ||
367 | host->claimed = 0; | ||
368 | spin_unlock_irqrestore(&host->lock, flags); | ||
369 | |||
370 | wake_up(&host->wq); | ||
371 | } | ||
372 | |||
373 | EXPORT_SYMBOL(mmc_release_host); | ||
374 | |||
375 | static inline void mmc_set_ios(struct mmc_host *host) | ||
376 | { | ||
377 | struct mmc_ios *ios = &host->ios; | ||
378 | |||
379 | pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u " | ||
380 | "width %u timing %u\n", | ||
381 | mmc_hostname(host), ios->clock, ios->bus_mode, | ||
382 | ios->power_mode, ios->chip_select, ios->vdd, | ||
383 | ios->bus_width, ios->timing); | ||
384 | |||
385 | host->ops->set_ios(host, ios); | ||
386 | } | ||
387 | |||
388 | static int mmc_select_card(struct mmc_host *host, struct mmc_card *card) | ||
389 | { | ||
390 | int err; | ||
391 | struct mmc_command cmd; | ||
392 | |||
393 | BUG_ON(!host->claimed); | ||
394 | |||
395 | if (host->card_selected == card) | ||
396 | return MMC_ERR_NONE; | ||
397 | |||
398 | host->card_selected = card; | ||
399 | |||
400 | cmd.opcode = MMC_SELECT_CARD; | ||
401 | cmd.arg = card->rca << 16; | ||
402 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
403 | |||
404 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | ||
405 | if (err != MMC_ERR_NONE) | ||
406 | return err; | ||
407 | |||
408 | /* | ||
409 | * We can only change the bus width of SD cards when | ||
410 | * they are selected so we have to put the handling | ||
411 | * here. | ||
412 | * | ||
413 | * The card is in 1 bit mode by default so | ||
414 | * we only need to change if it supports the | ||
415 | * wider version. | ||
416 | */ | ||
417 | if (mmc_card_sd(card) && | ||
418 | (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { | ||
419 | |||
420 | /* | ||
421 | * Default bus width is 1 bit. | ||
422 | */ | ||
423 | host->ios.bus_width = MMC_BUS_WIDTH_1; | ||
424 | |||
425 | if (host->caps & MMC_CAP_4_BIT_DATA) { | ||
426 | struct mmc_command cmd; | ||
427 | cmd.opcode = SD_APP_SET_BUS_WIDTH; | ||
428 | cmd.arg = SD_BUS_WIDTH_4; | ||
429 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
430 | |||
431 | err = mmc_wait_for_app_cmd(host, card->rca, &cmd, | ||
432 | CMD_RETRIES); | ||
433 | if (err != MMC_ERR_NONE) | ||
434 | return err; | ||
435 | |||
436 | host->ios.bus_width = MMC_BUS_WIDTH_4; | ||
437 | } | ||
438 | } | ||
439 | |||
440 | mmc_set_ios(host); | ||
441 | |||
442 | return MMC_ERR_NONE; | ||
443 | } | ||
444 | |||
445 | /* | ||
446 | * Ensure that no card is selected. | ||
447 | */ | ||
448 | static void mmc_deselect_cards(struct mmc_host *host) | ||
449 | { | ||
450 | struct mmc_command cmd; | ||
451 | |||
452 | if (host->card_selected) { | ||
453 | host->card_selected = NULL; | ||
454 | |||
455 | cmd.opcode = MMC_SELECT_CARD; | ||
456 | cmd.arg = 0; | ||
457 | cmd.flags = MMC_RSP_NONE | MMC_CMD_AC; | ||
458 | |||
459 | mmc_wait_for_cmd(host, &cmd, 0); | ||
460 | } | ||
461 | } | ||
462 | |||
463 | |||
464 | static inline void mmc_delay(unsigned int ms) | ||
465 | { | ||
466 | if (ms < 1000 / HZ) { | ||
467 | cond_resched(); | ||
468 | mdelay(ms); | ||
469 | } else { | ||
470 | msleep(ms); | ||
471 | } | ||
472 | } | ||
473 | |||
474 | /* | ||
475 | * Mask off any voltages we don't support and select | ||
476 | * the lowest voltage | ||
477 | */ | ||
478 | static u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) | ||
479 | { | ||
480 | int bit; | ||
481 | |||
482 | ocr &= host->ocr_avail; | ||
483 | |||
484 | bit = ffs(ocr); | ||
485 | if (bit) { | ||
486 | bit -= 1; | ||
487 | |||
488 | ocr &= 3 << bit; | ||
489 | |||
490 | host->ios.vdd = bit; | ||
491 | mmc_set_ios(host); | ||
492 | } else { | ||
493 | ocr = 0; | ||
494 | } | ||
495 | |||
496 | return ocr; | ||
497 | } | ||
498 | |||
499 | #define UNSTUFF_BITS(resp,start,size) \ | ||
500 | ({ \ | ||
501 | const int __size = size; \ | ||
502 | const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \ | ||
503 | const int __off = 3 - ((start) / 32); \ | ||
504 | const int __shft = (start) & 31; \ | ||
505 | u32 __res; \ | ||
506 | \ | ||
507 | __res = resp[__off] >> __shft; \ | ||
508 | if (__size + __shft > 32) \ | ||
509 | __res |= resp[__off-1] << ((32 - __shft) % 32); \ | ||
510 | __res & __mask; \ | ||
511 | }) | ||
512 | |||
513 | /* | ||
514 | * Given the decoded CSD structure, decode the raw CID to our CID structure. | ||
515 | */ | ||
516 | static void mmc_decode_cid(struct mmc_card *card) | ||
517 | { | ||
518 | u32 *resp = card->raw_cid; | ||
519 | |||
520 | memset(&card->cid, 0, sizeof(struct mmc_cid)); | ||
521 | |||
522 | if (mmc_card_sd(card)) { | ||
523 | /* | ||
524 | * SD doesn't currently have a version field so we will | ||
525 | * have to assume we can parse this. | ||
526 | */ | ||
527 | card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); | ||
528 | card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); | ||
529 | card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); | ||
530 | card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); | ||
531 | card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); | ||
532 | card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); | ||
533 | card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); | ||
534 | card->cid.hwrev = UNSTUFF_BITS(resp, 60, 4); | ||
535 | card->cid.fwrev = UNSTUFF_BITS(resp, 56, 4); | ||
536 | card->cid.serial = UNSTUFF_BITS(resp, 24, 32); | ||
537 | card->cid.year = UNSTUFF_BITS(resp, 12, 8); | ||
538 | card->cid.month = UNSTUFF_BITS(resp, 8, 4); | ||
539 | |||
540 | card->cid.year += 2000; /* SD cards year offset */ | ||
541 | } else { | ||
542 | /* | ||
543 | * The selection of the format here is based upon published | ||
544 | * specs from sandisk and from what people have reported. | ||
545 | */ | ||
546 | switch (card->csd.mmca_vsn) { | ||
547 | case 0: /* MMC v1.0 - v1.2 */ | ||
548 | case 1: /* MMC v1.4 */ | ||
549 | card->cid.manfid = UNSTUFF_BITS(resp, 104, 24); | ||
550 | card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); | ||
551 | card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); | ||
552 | card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); | ||
553 | card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); | ||
554 | card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); | ||
555 | card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8); | ||
556 | card->cid.prod_name[6] = UNSTUFF_BITS(resp, 48, 8); | ||
557 | card->cid.hwrev = UNSTUFF_BITS(resp, 44, 4); | ||
558 | card->cid.fwrev = UNSTUFF_BITS(resp, 40, 4); | ||
559 | card->cid.serial = UNSTUFF_BITS(resp, 16, 24); | ||
560 | card->cid.month = UNSTUFF_BITS(resp, 12, 4); | ||
561 | card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997; | ||
562 | break; | ||
563 | |||
564 | case 2: /* MMC v2.0 - v2.2 */ | ||
565 | case 3: /* MMC v3.1 - v3.3 */ | ||
566 | case 4: /* MMC v4 */ | ||
567 | card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); | ||
568 | card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); | ||
569 | card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); | ||
570 | card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); | ||
571 | card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); | ||
572 | card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); | ||
573 | card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); | ||
574 | card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8); | ||
575 | card->cid.serial = UNSTUFF_BITS(resp, 16, 32); | ||
576 | card->cid.month = UNSTUFF_BITS(resp, 12, 4); | ||
577 | card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997; | ||
578 | break; | ||
579 | |||
580 | default: | ||
581 | printk("%s: card has unknown MMCA version %d\n", | ||
582 | mmc_hostname(card->host), card->csd.mmca_vsn); | ||
583 | mmc_card_set_bad(card); | ||
584 | break; | ||
585 | } | ||
586 | } | ||
587 | } | ||
588 | |||
589 | /* | ||
590 | * Given a 128-bit response, decode to our card CSD structure. | ||
591 | */ | ||
592 | static void mmc_decode_csd(struct mmc_card *card) | ||
593 | { | ||
594 | struct mmc_csd *csd = &card->csd; | ||
595 | unsigned int e, m, csd_struct; | ||
596 | u32 *resp = card->raw_csd; | ||
597 | |||
598 | if (mmc_card_sd(card)) { | ||
599 | csd_struct = UNSTUFF_BITS(resp, 126, 2); | ||
600 | |||
601 | switch (csd_struct) { | ||
602 | case 0: | ||
603 | m = UNSTUFF_BITS(resp, 115, 4); | ||
604 | e = UNSTUFF_BITS(resp, 112, 3); | ||
605 | csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10; | ||
606 | csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100; | ||
607 | |||
608 | m = UNSTUFF_BITS(resp, 99, 4); | ||
609 | e = UNSTUFF_BITS(resp, 96, 3); | ||
610 | csd->max_dtr = tran_exp[e] * tran_mant[m]; | ||
611 | csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); | ||
612 | |||
613 | e = UNSTUFF_BITS(resp, 47, 3); | ||
614 | m = UNSTUFF_BITS(resp, 62, 12); | ||
615 | csd->capacity = (1 + m) << (e + 2); | ||
616 | |||
617 | csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); | ||
618 | csd->read_partial = UNSTUFF_BITS(resp, 79, 1); | ||
619 | csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); | ||
620 | csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); | ||
621 | csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); | ||
622 | csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); | ||
623 | csd->write_partial = UNSTUFF_BITS(resp, 21, 1); | ||
624 | break; | ||
625 | case 1: | ||
626 | /* | ||
627 | * This is a block-addressed SDHC card. Most | ||
628 | * interesting fields are unused and have fixed | ||
629 | * values. To avoid getting tripped by buggy cards, | ||
630 | * we assume those fixed values ourselves. | ||
631 | */ | ||
632 | mmc_card_set_blockaddr(card); | ||
633 | |||
634 | csd->tacc_ns = 0; /* Unused */ | ||
635 | csd->tacc_clks = 0; /* Unused */ | ||
636 | |||
637 | m = UNSTUFF_BITS(resp, 99, 4); | ||
638 | e = UNSTUFF_BITS(resp, 96, 3); | ||
639 | csd->max_dtr = tran_exp[e] * tran_mant[m]; | ||
640 | csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); | ||
641 | |||
642 | m = UNSTUFF_BITS(resp, 48, 22); | ||
643 | csd->capacity = (1 + m) << 10; | ||
644 | |||
645 | csd->read_blkbits = 9; | ||
646 | csd->read_partial = 0; | ||
647 | csd->write_misalign = 0; | ||
648 | csd->read_misalign = 0; | ||
649 | csd->r2w_factor = 4; /* Unused */ | ||
650 | csd->write_blkbits = 9; | ||
651 | csd->write_partial = 0; | ||
652 | break; | ||
653 | default: | ||
654 | printk("%s: unrecognised CSD structure version %d\n", | ||
655 | mmc_hostname(card->host), csd_struct); | ||
656 | mmc_card_set_bad(card); | ||
657 | return; | ||
658 | } | ||
659 | } else { | ||
660 | /* | ||
661 | * We only understand CSD structure v1.1 and v1.2. | ||
662 | * v1.2 has extra information in bits 15, 11 and 10. | ||
663 | */ | ||
664 | csd_struct = UNSTUFF_BITS(resp, 126, 2); | ||
665 | if (csd_struct != 1 && csd_struct != 2) { | ||
666 | printk("%s: unrecognised CSD structure version %d\n", | ||
667 | mmc_hostname(card->host), csd_struct); | ||
668 | mmc_card_set_bad(card); | ||
669 | return; | ||
670 | } | ||
671 | |||
672 | csd->mmca_vsn = UNSTUFF_BITS(resp, 122, 4); | ||
673 | m = UNSTUFF_BITS(resp, 115, 4); | ||
674 | e = UNSTUFF_BITS(resp, 112, 3); | ||
675 | csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10; | ||
676 | csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100; | ||
677 | |||
678 | m = UNSTUFF_BITS(resp, 99, 4); | ||
679 | e = UNSTUFF_BITS(resp, 96, 3); | ||
680 | csd->max_dtr = tran_exp[e] * tran_mant[m]; | ||
681 | csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); | ||
682 | |||
683 | e = UNSTUFF_BITS(resp, 47, 3); | ||
684 | m = UNSTUFF_BITS(resp, 62, 12); | ||
685 | csd->capacity = (1 + m) << (e + 2); | ||
686 | |||
687 | csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); | ||
688 | csd->read_partial = UNSTUFF_BITS(resp, 79, 1); | ||
689 | csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); | ||
690 | csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); | ||
691 | csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); | ||
692 | csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); | ||
693 | csd->write_partial = UNSTUFF_BITS(resp, 21, 1); | ||
694 | } | ||
695 | } | ||
696 | |||
697 | /* | ||
698 | * Given a 64-bit response, decode to our card SCR structure. | ||
699 | */ | ||
700 | static void mmc_decode_scr(struct mmc_card *card) | ||
701 | { | ||
702 | struct sd_scr *scr = &card->scr; | ||
703 | unsigned int scr_struct; | ||
704 | u32 resp[4]; | ||
705 | |||
706 | BUG_ON(!mmc_card_sd(card)); | ||
707 | |||
708 | resp[3] = card->raw_scr[1]; | ||
709 | resp[2] = card->raw_scr[0]; | ||
710 | |||
711 | scr_struct = UNSTUFF_BITS(resp, 60, 4); | ||
712 | if (scr_struct != 0) { | ||
713 | printk("%s: unrecognised SCR structure version %d\n", | ||
714 | mmc_hostname(card->host), scr_struct); | ||
715 | mmc_card_set_bad(card); | ||
716 | return; | ||
717 | } | ||
718 | |||
719 | scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4); | ||
720 | scr->bus_widths = UNSTUFF_BITS(resp, 48, 4); | ||
721 | } | ||
722 | |||
723 | /* | ||
724 | * Locate a MMC card on this MMC host given a raw CID. | ||
725 | */ | ||
726 | static struct mmc_card *mmc_find_card(struct mmc_host *host, u32 *raw_cid) | ||
727 | { | ||
728 | struct mmc_card *card; | ||
729 | |||
730 | list_for_each_entry(card, &host->cards, node) { | ||
731 | if (memcmp(card->raw_cid, raw_cid, sizeof(card->raw_cid)) == 0) | ||
732 | return card; | ||
733 | } | ||
734 | return NULL; | ||
735 | } | ||
736 | |||
737 | /* | ||
738 | * Allocate a new MMC card, and assign a unique RCA. | ||
739 | */ | ||
740 | static struct mmc_card * | ||
741 | mmc_alloc_card(struct mmc_host *host, u32 *raw_cid, unsigned int *frca) | ||
742 | { | ||
743 | struct mmc_card *card, *c; | ||
744 | unsigned int rca = *frca; | ||
745 | |||
746 | card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL); | ||
747 | if (!card) | ||
748 | return ERR_PTR(-ENOMEM); | ||
749 | |||
750 | mmc_init_card(card, host); | ||
751 | memcpy(card->raw_cid, raw_cid, sizeof(card->raw_cid)); | ||
752 | |||
753 | again: | ||
754 | list_for_each_entry(c, &host->cards, node) | ||
755 | if (c->rca == rca) { | ||
756 | rca++; | ||
757 | goto again; | ||
758 | } | ||
759 | |||
760 | card->rca = rca; | ||
761 | |||
762 | *frca = rca; | ||
763 | |||
764 | return card; | ||
765 | } | ||
766 | |||
767 | /* | ||
768 | * Tell attached cards to go to IDLE state | ||
769 | */ | ||
770 | static void mmc_idle_cards(struct mmc_host *host) | ||
771 | { | ||
772 | struct mmc_command cmd; | ||
773 | |||
774 | host->ios.chip_select = MMC_CS_HIGH; | ||
775 | mmc_set_ios(host); | ||
776 | |||
777 | mmc_delay(1); | ||
778 | |||
779 | cmd.opcode = MMC_GO_IDLE_STATE; | ||
780 | cmd.arg = 0; | ||
781 | cmd.flags = MMC_RSP_NONE | MMC_CMD_BC; | ||
782 | |||
783 | mmc_wait_for_cmd(host, &cmd, 0); | ||
784 | |||
785 | mmc_delay(1); | ||
786 | |||
787 | host->ios.chip_select = MMC_CS_DONTCARE; | ||
788 | mmc_set_ios(host); | ||
789 | |||
790 | mmc_delay(1); | ||
791 | } | ||
792 | |||
793 | /* | ||
794 | * Apply power to the MMC stack. This is a two-stage process. | ||
795 | * First, we enable power to the card without the clock running. | ||
796 | * We then wait a bit for the power to stabilise. Finally, | ||
797 | * enable the bus drivers and clock to the card. | ||
798 | * | ||
799 | * We must _NOT_ enable the clock prior to power stablising. | ||
800 | * | ||
801 | * If a host does all the power sequencing itself, ignore the | ||
802 | * initial MMC_POWER_UP stage. | ||
803 | */ | ||
804 | static void mmc_power_up(struct mmc_host *host) | ||
805 | { | ||
806 | int bit = fls(host->ocr_avail) - 1; | ||
807 | |||
808 | host->ios.vdd = bit; | ||
809 | host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; | ||
810 | host->ios.chip_select = MMC_CS_DONTCARE; | ||
811 | host->ios.power_mode = MMC_POWER_UP; | ||
812 | host->ios.bus_width = MMC_BUS_WIDTH_1; | ||
813 | host->ios.timing = MMC_TIMING_LEGACY; | ||
814 | mmc_set_ios(host); | ||
815 | |||
816 | mmc_delay(1); | ||
817 | |||
818 | host->ios.clock = host->f_min; | ||
819 | host->ios.power_mode = MMC_POWER_ON; | ||
820 | mmc_set_ios(host); | ||
821 | |||
822 | mmc_delay(2); | ||
823 | } | ||
824 | |||
825 | static void mmc_power_off(struct mmc_host *host) | ||
826 | { | ||
827 | host->ios.clock = 0; | ||
828 | host->ios.vdd = 0; | ||
829 | host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; | ||
830 | host->ios.chip_select = MMC_CS_DONTCARE; | ||
831 | host->ios.power_mode = MMC_POWER_OFF; | ||
832 | host->ios.bus_width = MMC_BUS_WIDTH_1; | ||
833 | host->ios.timing = MMC_TIMING_LEGACY; | ||
834 | mmc_set_ios(host); | ||
835 | } | ||
836 | |||
837 | static int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | ||
838 | { | ||
839 | struct mmc_command cmd; | ||
840 | int i, err = 0; | ||
841 | |||
842 | cmd.opcode = MMC_SEND_OP_COND; | ||
843 | cmd.arg = ocr; | ||
844 | cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; | ||
845 | |||
846 | for (i = 100; i; i--) { | ||
847 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
848 | if (err != MMC_ERR_NONE) | ||
849 | break; | ||
850 | |||
851 | if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) | ||
852 | break; | ||
853 | |||
854 | err = MMC_ERR_TIMEOUT; | ||
855 | |||
856 | mmc_delay(10); | ||
857 | } | ||
858 | |||
859 | if (rocr) | ||
860 | *rocr = cmd.resp[0]; | ||
861 | |||
862 | return err; | ||
863 | } | ||
864 | |||
865 | static int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | ||
866 | { | ||
867 | struct mmc_command cmd; | ||
868 | int i, err = 0; | ||
869 | |||
870 | cmd.opcode = SD_APP_OP_COND; | ||
871 | cmd.arg = ocr; | ||
872 | cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; | ||
873 | |||
874 | for (i = 100; i; i--) { | ||
875 | err = mmc_wait_for_app_cmd(host, 0, &cmd, CMD_RETRIES); | ||
876 | if (err != MMC_ERR_NONE) | ||
877 | break; | ||
878 | |||
879 | if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) | ||
880 | break; | ||
881 | |||
882 | err = MMC_ERR_TIMEOUT; | ||
883 | |||
884 | mmc_delay(10); | ||
885 | } | ||
886 | |||
887 | if (rocr) | ||
888 | *rocr = cmd.resp[0]; | ||
889 | |||
890 | return err; | ||
891 | } | ||
892 | |||
893 | static int mmc_send_if_cond(struct mmc_host *host, u32 ocr, int *rsd2) | ||
894 | { | ||
895 | struct mmc_command cmd; | ||
896 | int err, sd2; | ||
897 | static const u8 test_pattern = 0xAA; | ||
898 | |||
899 | /* | ||
900 | * To support SD 2.0 cards, we must always invoke SD_SEND_IF_COND | ||
901 | * before SD_APP_OP_COND. This command will harmlessly fail for | ||
902 | * SD 1.0 cards. | ||
903 | */ | ||
904 | cmd.opcode = SD_SEND_IF_COND; | ||
905 | cmd.arg = ((ocr & 0xFF8000) != 0) << 8 | test_pattern; | ||
906 | cmd.flags = MMC_RSP_R7 | MMC_CMD_BCR; | ||
907 | |||
908 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
909 | if (err == MMC_ERR_NONE) { | ||
910 | if ((cmd.resp[0] & 0xFF) == test_pattern) { | ||
911 | sd2 = 1; | ||
912 | } else { | ||
913 | sd2 = 0; | ||
914 | err = MMC_ERR_FAILED; | ||
915 | } | ||
916 | } else { | ||
917 | /* | ||
918 | * Treat errors as SD 1.0 card. | ||
919 | */ | ||
920 | sd2 = 0; | ||
921 | err = MMC_ERR_NONE; | ||
922 | } | ||
923 | if (rsd2) | ||
924 | *rsd2 = sd2; | ||
925 | return err; | ||
926 | } | ||
927 | |||
928 | /* | ||
929 | * Discover cards by requesting their CID. If this command | ||
930 | * times out, it is not an error; there are no further cards | ||
931 | * to be discovered. Add new cards to the list. | ||
932 | * | ||
933 | * Create a mmc_card entry for each discovered card, assigning | ||
934 | * it an RCA, and save the raw CID for decoding later. | ||
935 | */ | ||
936 | static void mmc_discover_cards(struct mmc_host *host) | ||
937 | { | ||
938 | struct mmc_card *card; | ||
939 | unsigned int first_rca = 1, err; | ||
940 | |||
941 | while (1) { | ||
942 | struct mmc_command cmd; | ||
943 | |||
944 | cmd.opcode = MMC_ALL_SEND_CID; | ||
945 | cmd.arg = 0; | ||
946 | cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; | ||
947 | |||
948 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | ||
949 | if (err == MMC_ERR_TIMEOUT) { | ||
950 | err = MMC_ERR_NONE; | ||
951 | break; | ||
952 | } | ||
953 | if (err != MMC_ERR_NONE) { | ||
954 | printk(KERN_ERR "%s: error requesting CID: %d\n", | ||
955 | mmc_hostname(host), err); | ||
956 | break; | ||
957 | } | ||
958 | |||
959 | card = mmc_find_card(host, cmd.resp); | ||
960 | if (!card) { | ||
961 | card = mmc_alloc_card(host, cmd.resp, &first_rca); | ||
962 | if (IS_ERR(card)) { | ||
963 | err = PTR_ERR(card); | ||
964 | break; | ||
965 | } | ||
966 | list_add(&card->node, &host->cards); | ||
967 | } | ||
968 | |||
969 | card->state &= ~MMC_STATE_DEAD; | ||
970 | |||
971 | if (host->mode == MMC_MODE_SD) { | ||
972 | mmc_card_set_sd(card); | ||
973 | |||
974 | cmd.opcode = SD_SEND_RELATIVE_ADDR; | ||
975 | cmd.arg = 0; | ||
976 | cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; | ||
977 | |||
978 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | ||
979 | if (err != MMC_ERR_NONE) | ||
980 | mmc_card_set_dead(card); | ||
981 | else { | ||
982 | card->rca = cmd.resp[0] >> 16; | ||
983 | |||
984 | if (!host->ops->get_ro) { | ||
985 | printk(KERN_WARNING "%s: host does not " | ||
986 | "support reading read-only " | ||
987 | "switch. assuming write-enable.\n", | ||
988 | mmc_hostname(host)); | ||
989 | } else { | ||
990 | if (host->ops->get_ro(host)) | ||
991 | mmc_card_set_readonly(card); | ||
992 | } | ||
993 | } | ||
994 | } else { | ||
995 | cmd.opcode = MMC_SET_RELATIVE_ADDR; | ||
996 | cmd.arg = card->rca << 16; | ||
997 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
998 | |||
999 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | ||
1000 | if (err != MMC_ERR_NONE) | ||
1001 | mmc_card_set_dead(card); | ||
1002 | } | ||
1003 | } | ||
1004 | } | ||
1005 | |||
1006 | static void mmc_read_csds(struct mmc_host *host) | ||
1007 | { | ||
1008 | struct mmc_card *card; | ||
1009 | |||
1010 | list_for_each_entry(card, &host->cards, node) { | ||
1011 | struct mmc_command cmd; | ||
1012 | int err; | ||
1013 | |||
1014 | if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT)) | ||
1015 | continue; | ||
1016 | |||
1017 | cmd.opcode = MMC_SEND_CSD; | ||
1018 | cmd.arg = card->rca << 16; | ||
1019 | cmd.flags = MMC_RSP_R2 | MMC_CMD_AC; | ||
1020 | |||
1021 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | ||
1022 | if (err != MMC_ERR_NONE) { | ||
1023 | mmc_card_set_dead(card); | ||
1024 | continue; | ||
1025 | } | ||
1026 | |||
1027 | memcpy(card->raw_csd, cmd.resp, sizeof(card->raw_csd)); | ||
1028 | |||
1029 | mmc_decode_csd(card); | ||
1030 | mmc_decode_cid(card); | ||
1031 | } | ||
1032 | } | ||
1033 | |||
1034 | static void mmc_process_ext_csds(struct mmc_host *host) | ||
1035 | { | ||
1036 | int err; | ||
1037 | struct mmc_card *card; | ||
1038 | |||
1039 | struct mmc_request mrq; | ||
1040 | struct mmc_command cmd; | ||
1041 | struct mmc_data data; | ||
1042 | |||
1043 | struct scatterlist sg; | ||
1044 | |||
1045 | /* | ||
1046 | * As the ext_csd is so large and mostly unused, we don't store the | ||
1047 | * raw block in mmc_card. | ||
1048 | */ | ||
1049 | u8 *ext_csd; | ||
1050 | ext_csd = kmalloc(512, GFP_KERNEL); | ||
1051 | if (!ext_csd) { | ||
1052 | printk("%s: could not allocate a buffer to receive the ext_csd." | ||
1053 | "mmc v4 cards will be treated as v3.\n", | ||
1054 | mmc_hostname(host)); | ||
1055 | return; | ||
1056 | } | ||
1057 | |||
1058 | list_for_each_entry(card, &host->cards, node) { | ||
1059 | if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT)) | ||
1060 | continue; | ||
1061 | if (mmc_card_sd(card)) | ||
1062 | continue; | ||
1063 | if (card->csd.mmca_vsn < CSD_SPEC_VER_4) | ||
1064 | continue; | ||
1065 | |||
1066 | err = mmc_select_card(host, card); | ||
1067 | if (err != MMC_ERR_NONE) { | ||
1068 | mmc_card_set_dead(card); | ||
1069 | continue; | ||
1070 | } | ||
1071 | |||
1072 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
1073 | |||
1074 | cmd.opcode = MMC_SEND_EXT_CSD; | ||
1075 | cmd.arg = 0; | ||
1076 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
1077 | |||
1078 | memset(&data, 0, sizeof(struct mmc_data)); | ||
1079 | |||
1080 | mmc_set_data_timeout(&data, card, 0); | ||
1081 | |||
1082 | data.blksz = 512; | ||
1083 | data.blocks = 1; | ||
1084 | data.flags = MMC_DATA_READ; | ||
1085 | data.sg = &sg; | ||
1086 | data.sg_len = 1; | ||
1087 | |||
1088 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
1089 | |||
1090 | mrq.cmd = &cmd; | ||
1091 | mrq.data = &data; | ||
1092 | |||
1093 | sg_init_one(&sg, ext_csd, 512); | ||
1094 | |||
1095 | mmc_wait_for_req(host, &mrq); | ||
1096 | |||
1097 | if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) { | ||
1098 | printk("%s: unable to read EXT_CSD, performance " | ||
1099 | "might suffer.\n", mmc_hostname(card->host)); | ||
1100 | continue; | ||
1101 | } | ||
1102 | |||
1103 | switch (ext_csd[EXT_CSD_CARD_TYPE]) { | ||
1104 | case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: | ||
1105 | card->ext_csd.hs_max_dtr = 52000000; | ||
1106 | break; | ||
1107 | case EXT_CSD_CARD_TYPE_26: | ||
1108 | card->ext_csd.hs_max_dtr = 26000000; | ||
1109 | break; | ||
1110 | default: | ||
1111 | /* MMC v4 spec says this cannot happen */ | ||
1112 | printk("%s: card is mmc v4 but doesn't support " | ||
1113 | "any high-speed modes.\n", | ||
1114 | mmc_hostname(card->host)); | ||
1115 | continue; | ||
1116 | } | ||
1117 | |||
1118 | if (host->caps & MMC_CAP_MMC_HIGHSPEED) { | ||
1119 | /* Activate highspeed support. */ | ||
1120 | cmd.opcode = MMC_SWITCH; | ||
1121 | cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | | ||
1122 | (EXT_CSD_HS_TIMING << 16) | | ||
1123 | (1 << 8) | | ||
1124 | EXT_CSD_CMD_SET_NORMAL; | ||
1125 | cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; | ||
1126 | |||
1127 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | ||
1128 | if (err != MMC_ERR_NONE) { | ||
1129 | printk("%s: failed to switch card to mmc v4 " | ||
1130 | "high-speed mode.\n", | ||
1131 | mmc_hostname(card->host)); | ||
1132 | continue; | ||
1133 | } | ||
1134 | |||
1135 | mmc_card_set_highspeed(card); | ||
1136 | |||
1137 | host->ios.timing = MMC_TIMING_SD_HS; | ||
1138 | mmc_set_ios(host); | ||
1139 | } | ||
1140 | |||
1141 | /* Check for host support for wide-bus modes. */ | ||
1142 | if (host->caps & MMC_CAP_4_BIT_DATA) { | ||
1143 | /* Activate 4-bit support. */ | ||
1144 | cmd.opcode = MMC_SWITCH; | ||
1145 | cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | | ||
1146 | (EXT_CSD_BUS_WIDTH << 16) | | ||
1147 | (EXT_CSD_BUS_WIDTH_4 << 8) | | ||
1148 | EXT_CSD_CMD_SET_NORMAL; | ||
1149 | cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; | ||
1150 | |||
1151 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | ||
1152 | if (err != MMC_ERR_NONE) { | ||
1153 | printk("%s: failed to switch card to " | ||
1154 | "mmc v4 4-bit bus mode.\n", | ||
1155 | mmc_hostname(card->host)); | ||
1156 | continue; | ||
1157 | } | ||
1158 | |||
1159 | host->ios.bus_width = MMC_BUS_WIDTH_4; | ||
1160 | mmc_set_ios(host); | ||
1161 | } | ||
1162 | } | ||
1163 | |||
1164 | kfree(ext_csd); | ||
1165 | |||
1166 | mmc_deselect_cards(host); | ||
1167 | } | ||
1168 | |||
1169 | static void mmc_read_scrs(struct mmc_host *host) | ||
1170 | { | ||
1171 | int err; | ||
1172 | struct mmc_card *card; | ||
1173 | struct mmc_request mrq; | ||
1174 | struct mmc_command cmd; | ||
1175 | struct mmc_data data; | ||
1176 | struct scatterlist sg; | ||
1177 | |||
1178 | list_for_each_entry(card, &host->cards, node) { | ||
1179 | if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT)) | ||
1180 | continue; | ||
1181 | if (!mmc_card_sd(card)) | ||
1182 | continue; | ||
1183 | |||
1184 | err = mmc_select_card(host, card); | ||
1185 | if (err != MMC_ERR_NONE) { | ||
1186 | mmc_card_set_dead(card); | ||
1187 | continue; | ||
1188 | } | ||
1189 | |||
1190 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
1191 | |||
1192 | cmd.opcode = MMC_APP_CMD; | ||
1193 | cmd.arg = card->rca << 16; | ||
1194 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
1195 | |||
1196 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
1197 | if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD)) { | ||
1198 | mmc_card_set_dead(card); | ||
1199 | continue; | ||
1200 | } | ||
1201 | |||
1202 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
1203 | |||
1204 | cmd.opcode = SD_APP_SEND_SCR; | ||
1205 | cmd.arg = 0; | ||
1206 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
1207 | |||
1208 | memset(&data, 0, sizeof(struct mmc_data)); | ||
1209 | |||
1210 | mmc_set_data_timeout(&data, card, 0); | ||
1211 | |||
1212 | data.blksz = 1 << 3; | ||
1213 | data.blocks = 1; | ||
1214 | data.flags = MMC_DATA_READ; | ||
1215 | data.sg = &sg; | ||
1216 | data.sg_len = 1; | ||
1217 | |||
1218 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
1219 | |||
1220 | mrq.cmd = &cmd; | ||
1221 | mrq.data = &data; | ||
1222 | |||
1223 | sg_init_one(&sg, (u8*)card->raw_scr, 8); | ||
1224 | |||
1225 | mmc_wait_for_req(host, &mrq); | ||
1226 | |||
1227 | if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) { | ||
1228 | mmc_card_set_dead(card); | ||
1229 | continue; | ||
1230 | } | ||
1231 | |||
1232 | card->raw_scr[0] = ntohl(card->raw_scr[0]); | ||
1233 | card->raw_scr[1] = ntohl(card->raw_scr[1]); | ||
1234 | |||
1235 | mmc_decode_scr(card); | ||
1236 | } | ||
1237 | |||
1238 | mmc_deselect_cards(host); | ||
1239 | } | ||
1240 | |||
1241 | static void mmc_read_switch_caps(struct mmc_host *host) | ||
1242 | { | ||
1243 | int err; | ||
1244 | struct mmc_card *card; | ||
1245 | struct mmc_request mrq; | ||
1246 | struct mmc_command cmd; | ||
1247 | struct mmc_data data; | ||
1248 | unsigned char *status; | ||
1249 | struct scatterlist sg; | ||
1250 | |||
1251 | if (!(host->caps & MMC_CAP_SD_HIGHSPEED)) | ||
1252 | return; | ||
1253 | |||
1254 | status = kmalloc(64, GFP_KERNEL); | ||
1255 | if (!status) { | ||
1256 | printk(KERN_WARNING "%s: Unable to allocate buffer for " | ||
1257 | "reading switch capabilities.\n", | ||
1258 | mmc_hostname(host)); | ||
1259 | return; | ||
1260 | } | ||
1261 | |||
1262 | list_for_each_entry(card, &host->cards, node) { | ||
1263 | if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT)) | ||
1264 | continue; | ||
1265 | if (!mmc_card_sd(card)) | ||
1266 | continue; | ||
1267 | if (card->scr.sda_vsn < SCR_SPEC_VER_1) | ||
1268 | continue; | ||
1269 | |||
1270 | err = mmc_select_card(host, card); | ||
1271 | if (err != MMC_ERR_NONE) { | ||
1272 | mmc_card_set_dead(card); | ||
1273 | continue; | ||
1274 | } | ||
1275 | |||
1276 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
1277 | |||
1278 | cmd.opcode = SD_SWITCH; | ||
1279 | cmd.arg = 0x00FFFFF1; | ||
1280 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
1281 | |||
1282 | memset(&data, 0, sizeof(struct mmc_data)); | ||
1283 | |||
1284 | mmc_set_data_timeout(&data, card, 0); | ||
1285 | |||
1286 | data.blksz = 64; | ||
1287 | data.blocks = 1; | ||
1288 | data.flags = MMC_DATA_READ; | ||
1289 | data.sg = &sg; | ||
1290 | data.sg_len = 1; | ||
1291 | |||
1292 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
1293 | |||
1294 | mrq.cmd = &cmd; | ||
1295 | mrq.data = &data; | ||
1296 | |||
1297 | sg_init_one(&sg, status, 64); | ||
1298 | |||
1299 | mmc_wait_for_req(host, &mrq); | ||
1300 | |||
1301 | if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) { | ||
1302 | printk("%s: unable to read switch capabilities, " | ||
1303 | "performance might suffer.\n", | ||
1304 | mmc_hostname(card->host)); | ||
1305 | continue; | ||
1306 | } | ||
1307 | |||
1308 | if (status[13] & 0x02) | ||
1309 | card->sw_caps.hs_max_dtr = 50000000; | ||
1310 | |||
1311 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
1312 | |||
1313 | cmd.opcode = SD_SWITCH; | ||
1314 | cmd.arg = 0x80FFFFF1; | ||
1315 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
1316 | |||
1317 | memset(&data, 0, sizeof(struct mmc_data)); | ||
1318 | |||
1319 | mmc_set_data_timeout(&data, card, 0); | ||
1320 | |||
1321 | data.blksz = 64; | ||
1322 | data.blocks = 1; | ||
1323 | data.flags = MMC_DATA_READ; | ||
1324 | data.sg = &sg; | ||
1325 | data.sg_len = 1; | ||
1326 | |||
1327 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
1328 | |||
1329 | mrq.cmd = &cmd; | ||
1330 | mrq.data = &data; | ||
1331 | |||
1332 | sg_init_one(&sg, status, 64); | ||
1333 | |||
1334 | mmc_wait_for_req(host, &mrq); | ||
1335 | |||
1336 | if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE || | ||
1337 | (status[16] & 0xF) != 1) { | ||
1338 | printk(KERN_WARNING "%s: Problem switching card " | ||
1339 | "into high-speed mode!\n", | ||
1340 | mmc_hostname(host)); | ||
1341 | continue; | ||
1342 | } | ||
1343 | |||
1344 | mmc_card_set_highspeed(card); | ||
1345 | |||
1346 | host->ios.timing = MMC_TIMING_SD_HS; | ||
1347 | mmc_set_ios(host); | ||
1348 | } | ||
1349 | |||
1350 | kfree(status); | ||
1351 | |||
1352 | mmc_deselect_cards(host); | ||
1353 | } | ||
1354 | |||
1355 | static unsigned int mmc_calculate_clock(struct mmc_host *host) | ||
1356 | { | ||
1357 | struct mmc_card *card; | ||
1358 | unsigned int max_dtr = host->f_max; | ||
1359 | |||
1360 | list_for_each_entry(card, &host->cards, node) | ||
1361 | if (!mmc_card_dead(card)) { | ||
1362 | if (mmc_card_highspeed(card) && mmc_card_sd(card)) { | ||
1363 | if (max_dtr > card->sw_caps.hs_max_dtr) | ||
1364 | max_dtr = card->sw_caps.hs_max_dtr; | ||
1365 | } else if (mmc_card_highspeed(card) && !mmc_card_sd(card)) { | ||
1366 | if (max_dtr > card->ext_csd.hs_max_dtr) | ||
1367 | max_dtr = card->ext_csd.hs_max_dtr; | ||
1368 | } else if (max_dtr > card->csd.max_dtr) { | ||
1369 | max_dtr = card->csd.max_dtr; | ||
1370 | } | ||
1371 | } | ||
1372 | |||
1373 | pr_debug("%s: selected %d.%03dMHz transfer rate\n", | ||
1374 | mmc_hostname(host), | ||
1375 | max_dtr / 1000000, (max_dtr / 1000) % 1000); | ||
1376 | |||
1377 | return max_dtr; | ||
1378 | } | ||
1379 | |||
1380 | /* | ||
1381 | * Check whether cards we already know about are still present. | ||
1382 | * We do this by requesting status, and checking whether a card | ||
1383 | * responds. | ||
1384 | * | ||
1385 | * A request for status does not cause a state change in data | ||
1386 | * transfer mode. | ||
1387 | */ | ||
1388 | static void mmc_check_cards(struct mmc_host *host) | ||
1389 | { | ||
1390 | struct list_head *l, *n; | ||
1391 | |||
1392 | mmc_deselect_cards(host); | ||
1393 | |||
1394 | list_for_each_safe(l, n, &host->cards) { | ||
1395 | struct mmc_card *card = mmc_list_to_card(l); | ||
1396 | struct mmc_command cmd; | ||
1397 | int err; | ||
1398 | |||
1399 | cmd.opcode = MMC_SEND_STATUS; | ||
1400 | cmd.arg = card->rca << 16; | ||
1401 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
1402 | |||
1403 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | ||
1404 | if (err == MMC_ERR_NONE) | ||
1405 | continue; | ||
1406 | |||
1407 | mmc_card_set_dead(card); | ||
1408 | } | ||
1409 | } | ||
1410 | |||
1411 | static void mmc_setup(struct mmc_host *host) | ||
1412 | { | ||
1413 | if (host->ios.power_mode != MMC_POWER_ON) { | ||
1414 | int err; | ||
1415 | u32 ocr; | ||
1416 | |||
1417 | host->mode = MMC_MODE_SD; | ||
1418 | |||
1419 | mmc_power_up(host); | ||
1420 | mmc_idle_cards(host); | ||
1421 | |||
1422 | err = mmc_send_if_cond(host, host->ocr_avail, NULL); | ||
1423 | if (err != MMC_ERR_NONE) { | ||
1424 | return; | ||
1425 | } | ||
1426 | err = mmc_send_app_op_cond(host, 0, &ocr); | ||
1427 | |||
1428 | /* | ||
1429 | * If we fail to detect any SD cards then try | ||
1430 | * searching for MMC cards. | ||
1431 | */ | ||
1432 | if (err != MMC_ERR_NONE) { | ||
1433 | host->mode = MMC_MODE_MMC; | ||
1434 | |||
1435 | err = mmc_send_op_cond(host, 0, &ocr); | ||
1436 | if (err != MMC_ERR_NONE) | ||
1437 | return; | ||
1438 | } | ||
1439 | |||
1440 | host->ocr = mmc_select_voltage(host, ocr); | ||
1441 | |||
1442 | /* | ||
1443 | * Since we're changing the OCR value, we seem to | ||
1444 | * need to tell some cards to go back to the idle | ||
1445 | * state. We wait 1ms to give cards time to | ||
1446 | * respond. | ||
1447 | */ | ||
1448 | if (host->ocr) | ||
1449 | mmc_idle_cards(host); | ||
1450 | } else { | ||
1451 | host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; | ||
1452 | host->ios.clock = host->f_min; | ||
1453 | mmc_set_ios(host); | ||
1454 | |||
1455 | /* | ||
1456 | * We should remember the OCR mask from the existing | ||
1457 | * cards, and detect the new cards OCR mask, combine | ||
1458 | * the two and re-select the VDD. However, if we do | ||
1459 | * change VDD, we should do an idle, and then do a | ||
1460 | * full re-initialisation. We would need to notify | ||
1461 | * drivers so that they can re-setup the cards as | ||
1462 | * well, while keeping their queues at bay. | ||
1463 | * | ||
1464 | * For the moment, we take the easy way out - if the | ||
1465 | * new cards don't like our currently selected VDD, | ||
1466 | * they drop off the bus. | ||
1467 | */ | ||
1468 | } | ||
1469 | |||
1470 | if (host->ocr == 0) | ||
1471 | return; | ||
1472 | |||
1473 | /* | ||
1474 | * Send the selected OCR multiple times... until the cards | ||
1475 | * all get the idea that they should be ready for CMD2. | ||
1476 | * (My SanDisk card seems to need this.) | ||
1477 | */ | ||
1478 | if (host->mode == MMC_MODE_SD) { | ||
1479 | int err, sd2; | ||
1480 | err = mmc_send_if_cond(host, host->ocr, &sd2); | ||
1481 | if (err == MMC_ERR_NONE) { | ||
1482 | /* | ||
1483 | * If SD_SEND_IF_COND indicates an SD 2.0 | ||
1484 | * compliant card and we should set bit 30 | ||
1485 | * of the ocr to indicate that we can handle | ||
1486 | * block-addressed SDHC cards. | ||
1487 | */ | ||
1488 | mmc_send_app_op_cond(host, host->ocr | (sd2 << 30), NULL); | ||
1489 | } | ||
1490 | } else { | ||
1491 | mmc_send_op_cond(host, host->ocr, NULL); | ||
1492 | } | ||
1493 | |||
1494 | mmc_discover_cards(host); | ||
1495 | |||
1496 | /* | ||
1497 | * Ok, now switch to push-pull mode. | ||
1498 | */ | ||
1499 | host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; | ||
1500 | mmc_set_ios(host); | ||
1501 | |||
1502 | mmc_read_csds(host); | ||
1503 | |||
1504 | if (host->mode == MMC_MODE_SD) { | ||
1505 | mmc_read_scrs(host); | ||
1506 | mmc_read_switch_caps(host); | ||
1507 | } else | ||
1508 | mmc_process_ext_csds(host); | ||
1509 | } | ||
1510 | |||
1511 | |||
1512 | /** | ||
1513 | * mmc_detect_change - process change of state on a MMC socket | ||
1514 | * @host: host which changed state. | ||
1515 | * @delay: optional delay to wait before detection (jiffies) | ||
1516 | * | ||
1517 | * All we know is that card(s) have been inserted or removed | ||
1518 | * from the socket(s). We don't know which socket or cards. | ||
1519 | */ | ||
1520 | void mmc_detect_change(struct mmc_host *host, unsigned long delay) | ||
1521 | { | ||
1522 | mmc_schedule_delayed_work(&host->detect, delay); | ||
1523 | } | ||
1524 | |||
1525 | EXPORT_SYMBOL(mmc_detect_change); | ||
1526 | |||
1527 | |||
1528 | static void mmc_rescan(struct work_struct *work) | ||
1529 | { | ||
1530 | struct mmc_host *host = | ||
1531 | container_of(work, struct mmc_host, detect.work); | ||
1532 | struct list_head *l, *n; | ||
1533 | unsigned char power_mode; | ||
1534 | |||
1535 | mmc_claim_host(host); | ||
1536 | |||
1537 | /* | ||
1538 | * Check for removed cards and newly inserted ones. We check for | ||
1539 | * removed cards first so we can intelligently re-select the VDD. | ||
1540 | */ | ||
1541 | power_mode = host->ios.power_mode; | ||
1542 | if (power_mode == MMC_POWER_ON) | ||
1543 | mmc_check_cards(host); | ||
1544 | |||
1545 | mmc_setup(host); | ||
1546 | |||
1547 | /* | ||
1548 | * Some broken cards process CMD1 even in stand-by state. There is | ||
1549 | * no reply, but an ILLEGAL_COMMAND error is cached and returned | ||
1550 | * after next command. We poll for card status here to clear any | ||
1551 | * possibly pending error. | ||
1552 | */ | ||
1553 | if (power_mode == MMC_POWER_ON) | ||
1554 | mmc_check_cards(host); | ||
1555 | |||
1556 | if (!list_empty(&host->cards)) { | ||
1557 | /* | ||
1558 | * (Re-)calculate the fastest clock rate which the | ||
1559 | * attached cards and the host support. | ||
1560 | */ | ||
1561 | host->ios.clock = mmc_calculate_clock(host); | ||
1562 | mmc_set_ios(host); | ||
1563 | } | ||
1564 | |||
1565 | mmc_release_host(host); | ||
1566 | |||
1567 | list_for_each_safe(l, n, &host->cards) { | ||
1568 | struct mmc_card *card = mmc_list_to_card(l); | ||
1569 | |||
1570 | /* | ||
1571 | * If this is a new and good card, register it. | ||
1572 | */ | ||
1573 | if (!mmc_card_present(card) && !mmc_card_dead(card)) { | ||
1574 | if (mmc_register_card(card)) | ||
1575 | mmc_card_set_dead(card); | ||
1576 | else | ||
1577 | mmc_card_set_present(card); | ||
1578 | } | ||
1579 | |||
1580 | /* | ||
1581 | * If this card is dead, destroy it. | ||
1582 | */ | ||
1583 | if (mmc_card_dead(card)) { | ||
1584 | list_del(&card->node); | ||
1585 | mmc_remove_card(card); | ||
1586 | } | ||
1587 | } | ||
1588 | |||
1589 | /* | ||
1590 | * If we discover that there are no cards on the | ||
1591 | * bus, turn off the clock and power down. | ||
1592 | */ | ||
1593 | if (list_empty(&host->cards)) | ||
1594 | mmc_power_off(host); | ||
1595 | } | ||
1596 | |||
1597 | |||
1598 | /** | ||
1599 | * mmc_alloc_host - initialise the per-host structure. | ||
1600 | * @extra: sizeof private data structure | ||
1601 | * @dev: pointer to host device model structure | ||
1602 | * | ||
1603 | * Initialise the per-host structure. | ||
1604 | */ | ||
1605 | struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | ||
1606 | { | ||
1607 | struct mmc_host *host; | ||
1608 | |||
1609 | host = mmc_alloc_host_sysfs(extra, dev); | ||
1610 | if (host) { | ||
1611 | spin_lock_init(&host->lock); | ||
1612 | init_waitqueue_head(&host->wq); | ||
1613 | INIT_LIST_HEAD(&host->cards); | ||
1614 | INIT_DELAYED_WORK(&host->detect, mmc_rescan); | ||
1615 | |||
1616 | /* | ||
1617 | * By default, hosts do not support SGIO or large requests. | ||
1618 | * They have to set these according to their abilities. | ||
1619 | */ | ||
1620 | host->max_hw_segs = 1; | ||
1621 | host->max_phys_segs = 1; | ||
1622 | host->max_seg_size = PAGE_CACHE_SIZE; | ||
1623 | |||
1624 | host->max_req_size = PAGE_CACHE_SIZE; | ||
1625 | host->max_blk_size = 512; | ||
1626 | host->max_blk_count = PAGE_CACHE_SIZE / 512; | ||
1627 | } | ||
1628 | |||
1629 | return host; | ||
1630 | } | ||
1631 | |||
1632 | EXPORT_SYMBOL(mmc_alloc_host); | ||
1633 | |||
1634 | /** | ||
1635 | * mmc_add_host - initialise host hardware | ||
1636 | * @host: mmc host | ||
1637 | */ | ||
1638 | int mmc_add_host(struct mmc_host *host) | ||
1639 | { | ||
1640 | int ret; | ||
1641 | |||
1642 | ret = mmc_add_host_sysfs(host); | ||
1643 | if (ret == 0) { | ||
1644 | mmc_power_off(host); | ||
1645 | mmc_detect_change(host, 0); | ||
1646 | } | ||
1647 | |||
1648 | return ret; | ||
1649 | } | ||
1650 | |||
1651 | EXPORT_SYMBOL(mmc_add_host); | ||
1652 | |||
1653 | /** | ||
1654 | * mmc_remove_host - remove host hardware | ||
1655 | * @host: mmc host | ||
1656 | * | ||
1657 | * Unregister and remove all cards associated with this host, | ||
1658 | * and power down the MMC bus. | ||
1659 | */ | ||
1660 | void mmc_remove_host(struct mmc_host *host) | ||
1661 | { | ||
1662 | struct list_head *l, *n; | ||
1663 | |||
1664 | list_for_each_safe(l, n, &host->cards) { | ||
1665 | struct mmc_card *card = mmc_list_to_card(l); | ||
1666 | |||
1667 | mmc_remove_card(card); | ||
1668 | } | ||
1669 | |||
1670 | mmc_power_off(host); | ||
1671 | mmc_remove_host_sysfs(host); | ||
1672 | } | ||
1673 | |||
1674 | EXPORT_SYMBOL(mmc_remove_host); | ||
1675 | |||
1676 | /** | ||
1677 | * mmc_free_host - free the host structure | ||
1678 | * @host: mmc host | ||
1679 | * | ||
1680 | * Free the host once all references to it have been dropped. | ||
1681 | */ | ||
1682 | void mmc_free_host(struct mmc_host *host) | ||
1683 | { | ||
1684 | mmc_flush_scheduled_work(); | ||
1685 | mmc_free_host_sysfs(host); | ||
1686 | } | ||
1687 | |||
1688 | EXPORT_SYMBOL(mmc_free_host); | ||
1689 | |||
1690 | #ifdef CONFIG_PM | ||
1691 | |||
1692 | /** | ||
1693 | * mmc_suspend_host - suspend a host | ||
1694 | * @host: mmc host | ||
1695 | * @state: suspend mode (PM_SUSPEND_xxx) | ||
1696 | */ | ||
1697 | int mmc_suspend_host(struct mmc_host *host, pm_message_t state) | ||
1698 | { | ||
1699 | mmc_claim_host(host); | ||
1700 | mmc_deselect_cards(host); | ||
1701 | mmc_power_off(host); | ||
1702 | mmc_release_host(host); | ||
1703 | |||
1704 | return 0; | ||
1705 | } | ||
1706 | |||
1707 | EXPORT_SYMBOL(mmc_suspend_host); | ||
1708 | |||
1709 | /** | ||
1710 | * mmc_resume_host - resume a previously suspended host | ||
1711 | * @host: mmc host | ||
1712 | */ | ||
1713 | int mmc_resume_host(struct mmc_host *host) | ||
1714 | { | ||
1715 | mmc_rescan(&host->detect.work); | ||
1716 | |||
1717 | return 0; | ||
1718 | } | ||
1719 | |||
1720 | EXPORT_SYMBOL(mmc_resume_host); | ||
1721 | |||
1722 | #endif | ||
1723 | |||
1724 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c deleted file mode 100644 index 0581d09c58fc..000000000000 --- a/drivers/mmc/tifm_sd.c +++ /dev/null | |||
@@ -1,987 +0,0 @@ | |||
1 | /* | ||
2 | * tifm_sd.c - TI FlashMedia driver | ||
3 | * | ||
4 | * Copyright (C) 2006 Alex Dubov <oakad@yahoo.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | |||
13 | #include <linux/tifm.h> | ||
14 | #include <linux/mmc/protocol.h> | ||
15 | #include <linux/mmc/host.h> | ||
16 | #include <linux/highmem.h> | ||
17 | #include <asm/io.h> | ||
18 | |||
19 | #define DRIVER_NAME "tifm_sd" | ||
20 | #define DRIVER_VERSION "0.7" | ||
21 | |||
22 | static int no_dma = 0; | ||
23 | static int fixed_timeout = 0; | ||
24 | module_param(no_dma, bool, 0644); | ||
25 | module_param(fixed_timeout, bool, 0644); | ||
26 | |||
27 | /* Constants here are mostly from OMAP5912 datasheet */ | ||
28 | #define TIFM_MMCSD_RESET 0x0002 | ||
29 | #define TIFM_MMCSD_CLKMASK 0x03ff | ||
30 | #define TIFM_MMCSD_POWER 0x0800 | ||
31 | #define TIFM_MMCSD_4BBUS 0x8000 | ||
32 | #define TIFM_MMCSD_RXDE 0x8000 /* rx dma enable */ | ||
33 | #define TIFM_MMCSD_TXDE 0x0080 /* tx dma enable */ | ||
34 | #define TIFM_MMCSD_BUFINT 0x0c00 /* set bits: AE, AF */ | ||
35 | #define TIFM_MMCSD_DPE 0x0020 /* data timeout counted in kilocycles */ | ||
36 | #define TIFM_MMCSD_INAB 0x0080 /* abort / initialize command */ | ||
37 | #define TIFM_MMCSD_READ 0x8000 | ||
38 | |||
39 | #define TIFM_MMCSD_DATAMASK 0x401d /* set bits: CERR, EOFB, BRS, CB, EOC */ | ||
40 | #define TIFM_MMCSD_ERRMASK 0x01e0 /* set bits: CCRC, CTO, DCRC, DTO */ | ||
41 | #define TIFM_MMCSD_EOC 0x0001 /* end of command phase */ | ||
42 | #define TIFM_MMCSD_CB 0x0004 /* card enter busy state */ | ||
43 | #define TIFM_MMCSD_BRS 0x0008 /* block received/sent */ | ||
44 | #define TIFM_MMCSD_EOFB 0x0010 /* card exit busy state */ | ||
45 | #define TIFM_MMCSD_DTO 0x0020 /* data time-out */ | ||
46 | #define TIFM_MMCSD_DCRC 0x0040 /* data crc error */ | ||
47 | #define TIFM_MMCSD_CTO 0x0080 /* command time-out */ | ||
48 | #define TIFM_MMCSD_CCRC 0x0100 /* command crc error */ | ||
49 | #define TIFM_MMCSD_AF 0x0400 /* fifo almost full */ | ||
50 | #define TIFM_MMCSD_AE 0x0800 /* fifo almost empty */ | ||
51 | #define TIFM_MMCSD_CERR 0x4000 /* card status error */ | ||
52 | |||
53 | #define TIFM_MMCSD_FIFO_SIZE 0x0020 | ||
54 | |||
55 | #define TIFM_MMCSD_RSP_R0 0x0000 | ||
56 | #define TIFM_MMCSD_RSP_R1 0x0100 | ||
57 | #define TIFM_MMCSD_RSP_R2 0x0200 | ||
58 | #define TIFM_MMCSD_RSP_R3 0x0300 | ||
59 | #define TIFM_MMCSD_RSP_R4 0x0400 | ||
60 | #define TIFM_MMCSD_RSP_R5 0x0500 | ||
61 | #define TIFM_MMCSD_RSP_R6 0x0600 | ||
62 | |||
63 | #define TIFM_MMCSD_RSP_BUSY 0x0800 | ||
64 | |||
65 | #define TIFM_MMCSD_CMD_BC 0x0000 | ||
66 | #define TIFM_MMCSD_CMD_BCR 0x1000 | ||
67 | #define TIFM_MMCSD_CMD_AC 0x2000 | ||
68 | #define TIFM_MMCSD_CMD_ADTC 0x3000 | ||
69 | |||
70 | typedef enum { | ||
71 | IDLE = 0, | ||
72 | CMD, /* main command ended */ | ||
73 | BRS, /* block transfer finished */ | ||
74 | SCMD, /* stop command ended */ | ||
75 | CARD, /* card left busy state */ | ||
76 | FIFO, /* FIFO operation completed (uncertain) */ | ||
77 | READY | ||
78 | } card_state_t; | ||
79 | |||
80 | enum { | ||
81 | FIFO_RDY = 0x0001, /* hardware dependent value */ | ||
82 | EJECT = 0x0004, | ||
83 | EJECT_DONE = 0x0008, | ||
84 | CARD_BUSY = 0x0010, | ||
85 | OPENDRAIN = 0x0040, /* hardware dependent value */ | ||
86 | CARD_EVENT = 0x0100, /* hardware dependent value */ | ||
87 | CARD_RO = 0x0200, /* hardware dependent value */ | ||
88 | FIFO_EVENT = 0x10000 }; /* hardware dependent value */ | ||
89 | |||
90 | struct tifm_sd { | ||
91 | struct tifm_dev *dev; | ||
92 | |||
93 | unsigned int flags; | ||
94 | card_state_t state; | ||
95 | unsigned int clk_freq; | ||
96 | unsigned int clk_div; | ||
97 | unsigned long timeout_jiffies; | ||
98 | |||
99 | struct tasklet_struct finish_tasklet; | ||
100 | struct timer_list timer; | ||
101 | struct mmc_request *req; | ||
102 | wait_queue_head_t notify; | ||
103 | |||
104 | size_t written_blocks; | ||
105 | size_t buffer_size; | ||
106 | size_t buffer_pos; | ||
107 | |||
108 | }; | ||
109 | |||
110 | static char* tifm_sd_data_buffer(struct mmc_data *data) | ||
111 | { | ||
112 | return page_address(data->sg->page) + data->sg->offset; | ||
113 | } | ||
114 | |||
115 | static int tifm_sd_transfer_data(struct tifm_dev *sock, struct tifm_sd *host, | ||
116 | unsigned int host_status) | ||
117 | { | ||
118 | struct mmc_command *cmd = host->req->cmd; | ||
119 | unsigned int t_val = 0, cnt = 0; | ||
120 | char *buffer; | ||
121 | |||
122 | if (host_status & TIFM_MMCSD_BRS) { | ||
123 | /* in non-dma rx mode BRS fires when fifo is still not empty */ | ||
124 | if (no_dma && (cmd->data->flags & MMC_DATA_READ)) { | ||
125 | buffer = tifm_sd_data_buffer(host->req->data); | ||
126 | while (host->buffer_size > host->buffer_pos) { | ||
127 | t_val = readl(sock->addr + SOCK_MMCSD_DATA); | ||
128 | buffer[host->buffer_pos++] = t_val & 0xff; | ||
129 | buffer[host->buffer_pos++] = | ||
130 | (t_val >> 8) & 0xff; | ||
131 | } | ||
132 | } | ||
133 | return 1; | ||
134 | } else if (no_dma) { | ||
135 | buffer = tifm_sd_data_buffer(host->req->data); | ||
136 | if ((cmd->data->flags & MMC_DATA_READ) && | ||
137 | (host_status & TIFM_MMCSD_AF)) { | ||
138 | for (cnt = 0; cnt < TIFM_MMCSD_FIFO_SIZE; cnt++) { | ||
139 | t_val = readl(sock->addr + SOCK_MMCSD_DATA); | ||
140 | if (host->buffer_size > host->buffer_pos) { | ||
141 | buffer[host->buffer_pos++] = | ||
142 | t_val & 0xff; | ||
143 | buffer[host->buffer_pos++] = | ||
144 | (t_val >> 8) & 0xff; | ||
145 | } | ||
146 | } | ||
147 | } else if ((cmd->data->flags & MMC_DATA_WRITE) | ||
148 | && (host_status & TIFM_MMCSD_AE)) { | ||
149 | for (cnt = 0; cnt < TIFM_MMCSD_FIFO_SIZE; cnt++) { | ||
150 | if (host->buffer_size > host->buffer_pos) { | ||
151 | t_val = buffer[host->buffer_pos++] | ||
152 | & 0x00ff; | ||
153 | t_val |= ((buffer[host->buffer_pos++]) | ||
154 | << 8) & 0xff00; | ||
155 | writel(t_val, | ||
156 | sock->addr + SOCK_MMCSD_DATA); | ||
157 | } | ||
158 | } | ||
159 | } | ||
160 | } | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static unsigned int tifm_sd_op_flags(struct mmc_command *cmd) | ||
165 | { | ||
166 | unsigned int rc = 0; | ||
167 | |||
168 | switch (mmc_resp_type(cmd)) { | ||
169 | case MMC_RSP_NONE: | ||
170 | rc |= TIFM_MMCSD_RSP_R0; | ||
171 | break; | ||
172 | case MMC_RSP_R1B: | ||
173 | rc |= TIFM_MMCSD_RSP_BUSY; // deliberate fall-through | ||
174 | case MMC_RSP_R1: | ||
175 | rc |= TIFM_MMCSD_RSP_R1; | ||
176 | break; | ||
177 | case MMC_RSP_R2: | ||
178 | rc |= TIFM_MMCSD_RSP_R2; | ||
179 | break; | ||
180 | case MMC_RSP_R3: | ||
181 | rc |= TIFM_MMCSD_RSP_R3; | ||
182 | break; | ||
183 | default: | ||
184 | BUG(); | ||
185 | } | ||
186 | |||
187 | switch (mmc_cmd_type(cmd)) { | ||
188 | case MMC_CMD_BC: | ||
189 | rc |= TIFM_MMCSD_CMD_BC; | ||
190 | break; | ||
191 | case MMC_CMD_BCR: | ||
192 | rc |= TIFM_MMCSD_CMD_BCR; | ||
193 | break; | ||
194 | case MMC_CMD_AC: | ||
195 | rc |= TIFM_MMCSD_CMD_AC; | ||
196 | break; | ||
197 | case MMC_CMD_ADTC: | ||
198 | rc |= TIFM_MMCSD_CMD_ADTC; | ||
199 | break; | ||
200 | default: | ||
201 | BUG(); | ||
202 | } | ||
203 | return rc; | ||
204 | } | ||
205 | |||
206 | static void tifm_sd_exec(struct tifm_sd *host, struct mmc_command *cmd) | ||
207 | { | ||
208 | struct tifm_dev *sock = host->dev; | ||
209 | unsigned int cmd_mask = tifm_sd_op_flags(cmd) | | ||
210 | (host->flags & OPENDRAIN); | ||
211 | |||
212 | if (cmd->data && (cmd->data->flags & MMC_DATA_READ)) | ||
213 | cmd_mask |= TIFM_MMCSD_READ; | ||
214 | |||
215 | dev_dbg(&sock->dev, "executing opcode 0x%x, arg: 0x%x, mask: 0x%x\n", | ||
216 | cmd->opcode, cmd->arg, cmd_mask); | ||
217 | |||
218 | writel((cmd->arg >> 16) & 0xffff, sock->addr + SOCK_MMCSD_ARG_HIGH); | ||
219 | writel(cmd->arg & 0xffff, sock->addr + SOCK_MMCSD_ARG_LOW); | ||
220 | writel(cmd->opcode | cmd_mask, sock->addr + SOCK_MMCSD_COMMAND); | ||
221 | } | ||
222 | |||
223 | static void tifm_sd_fetch_resp(struct mmc_command *cmd, struct tifm_dev *sock) | ||
224 | { | ||
225 | cmd->resp[0] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x1c) << 16) | ||
226 | | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x18); | ||
227 | cmd->resp[1] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x14) << 16) | ||
228 | | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x10); | ||
229 | cmd->resp[2] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x0c) << 16) | ||
230 | | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x08); | ||
231 | cmd->resp[3] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x04) << 16) | ||
232 | | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x00); | ||
233 | } | ||
234 | |||
235 | static void tifm_sd_process_cmd(struct tifm_dev *sock, struct tifm_sd *host, | ||
236 | unsigned int host_status) | ||
237 | { | ||
238 | struct mmc_command *cmd = host->req->cmd; | ||
239 | |||
240 | change_state: | ||
241 | switch (host->state) { | ||
242 | case IDLE: | ||
243 | return; | ||
244 | case CMD: | ||
245 | if (host_status & (TIFM_MMCSD_EOC | TIFM_MMCSD_CERR)) { | ||
246 | tifm_sd_fetch_resp(cmd, sock); | ||
247 | if (cmd->data) { | ||
248 | host->state = BRS; | ||
249 | } else { | ||
250 | host->state = READY; | ||
251 | } | ||
252 | goto change_state; | ||
253 | } | ||
254 | break; | ||
255 | case BRS: | ||
256 | if (tifm_sd_transfer_data(sock, host, host_status)) { | ||
257 | if (cmd->data->flags & MMC_DATA_WRITE) { | ||
258 | host->state = CARD; | ||
259 | } else { | ||
260 | if (no_dma) { | ||
261 | if (host->req->stop) { | ||
262 | tifm_sd_exec(host, host->req->stop); | ||
263 | host->state = SCMD; | ||
264 | } else { | ||
265 | host->state = READY; | ||
266 | } | ||
267 | } else { | ||
268 | host->state = FIFO; | ||
269 | } | ||
270 | } | ||
271 | goto change_state; | ||
272 | } | ||
273 | break; | ||
274 | case SCMD: | ||
275 | if (host_status & TIFM_MMCSD_EOC) { | ||
276 | tifm_sd_fetch_resp(host->req->stop, sock); | ||
277 | host->state = READY; | ||
278 | goto change_state; | ||
279 | } | ||
280 | break; | ||
281 | case CARD: | ||
282 | dev_dbg(&sock->dev, "waiting for CARD, have %zd blocks\n", | ||
283 | host->written_blocks); | ||
284 | if (!(host->flags & CARD_BUSY) | ||
285 | && (host->written_blocks == cmd->data->blocks)) { | ||
286 | if (no_dma) { | ||
287 | if (host->req->stop) { | ||
288 | tifm_sd_exec(host, host->req->stop); | ||
289 | host->state = SCMD; | ||
290 | } else { | ||
291 | host->state = READY; | ||
292 | } | ||
293 | } else { | ||
294 | host->state = FIFO; | ||
295 | } | ||
296 | goto change_state; | ||
297 | } | ||
298 | break; | ||
299 | case FIFO: | ||
300 | if (host->flags & FIFO_RDY) { | ||
301 | host->flags &= ~FIFO_RDY; | ||
302 | if (host->req->stop) { | ||
303 | tifm_sd_exec(host, host->req->stop); | ||
304 | host->state = SCMD; | ||
305 | } else { | ||
306 | host->state = READY; | ||
307 | } | ||
308 | goto change_state; | ||
309 | } | ||
310 | break; | ||
311 | case READY: | ||
312 | tasklet_schedule(&host->finish_tasklet); | ||
313 | return; | ||
314 | } | ||
315 | |||
316 | } | ||
317 | |||
318 | /* Called from interrupt handler */ | ||
319 | static void tifm_sd_signal_irq(struct tifm_dev *sock, | ||
320 | unsigned int sock_irq_status) | ||
321 | { | ||
322 | struct tifm_sd *host; | ||
323 | unsigned int host_status = 0, fifo_status = 0; | ||
324 | int error_code = 0; | ||
325 | |||
326 | spin_lock(&sock->lock); | ||
327 | host = mmc_priv((struct mmc_host*)tifm_get_drvdata(sock)); | ||
328 | |||
329 | if (sock_irq_status & FIFO_EVENT) { | ||
330 | fifo_status = readl(sock->addr + SOCK_DMA_FIFO_STATUS); | ||
331 | writel(fifo_status, sock->addr + SOCK_DMA_FIFO_STATUS); | ||
332 | |||
333 | host->flags |= fifo_status & FIFO_RDY; | ||
334 | } | ||
335 | |||
336 | if (sock_irq_status & CARD_EVENT) { | ||
337 | host_status = readl(sock->addr + SOCK_MMCSD_STATUS); | ||
338 | writel(host_status, sock->addr + SOCK_MMCSD_STATUS); | ||
339 | |||
340 | if (!host->req) | ||
341 | goto done; | ||
342 | |||
343 | if (host_status & TIFM_MMCSD_ERRMASK) { | ||
344 | if (host_status & (TIFM_MMCSD_CTO | TIFM_MMCSD_DTO)) | ||
345 | error_code = MMC_ERR_TIMEOUT; | ||
346 | else if (host_status | ||
347 | & (TIFM_MMCSD_CCRC | TIFM_MMCSD_DCRC)) | ||
348 | error_code = MMC_ERR_BADCRC; | ||
349 | |||
350 | writel(TIFM_FIFO_INT_SETALL, | ||
351 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); | ||
352 | writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL); | ||
353 | |||
354 | if (host->req->stop) { | ||
355 | if (host->state == SCMD) { | ||
356 | host->req->stop->error = error_code; | ||
357 | } else if (host->state == BRS | ||
358 | || host->state == CARD | ||
359 | || host->state == FIFO) { | ||
360 | host->req->cmd->error = error_code; | ||
361 | tifm_sd_exec(host, host->req->stop); | ||
362 | host->state = SCMD; | ||
363 | goto done; | ||
364 | } else { | ||
365 | host->req->cmd->error = error_code; | ||
366 | } | ||
367 | } else { | ||
368 | host->req->cmd->error = error_code; | ||
369 | } | ||
370 | host->state = READY; | ||
371 | } | ||
372 | |||
373 | if (host_status & TIFM_MMCSD_CB) | ||
374 | host->flags |= CARD_BUSY; | ||
375 | if ((host_status & TIFM_MMCSD_EOFB) | ||
376 | && (host->flags & CARD_BUSY)) { | ||
377 | host->written_blocks++; | ||
378 | host->flags &= ~CARD_BUSY; | ||
379 | } | ||
380 | } | ||
381 | |||
382 | if (host->req) | ||
383 | tifm_sd_process_cmd(sock, host, host_status); | ||
384 | done: | ||
385 | dev_dbg(&sock->dev, "host_status %x, fifo_status %x\n", | ||
386 | host_status, fifo_status); | ||
387 | spin_unlock(&sock->lock); | ||
388 | } | ||
389 | |||
390 | static void tifm_sd_prepare_data(struct tifm_sd *host, struct mmc_command *cmd) | ||
391 | { | ||
392 | struct tifm_dev *sock = host->dev; | ||
393 | unsigned int dest_cnt; | ||
394 | |||
395 | /* DMA style IO */ | ||
396 | dev_dbg(&sock->dev, "setting dma for %d blocks\n", | ||
397 | cmd->data->blocks); | ||
398 | writel(TIFM_FIFO_INT_SETALL, | ||
399 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); | ||
400 | writel(ilog2(cmd->data->blksz) - 2, | ||
401 | sock->addr + SOCK_FIFO_PAGE_SIZE); | ||
402 | writel(TIFM_FIFO_ENABLE, sock->addr + SOCK_FIFO_CONTROL); | ||
403 | writel(TIFM_FIFO_INTMASK, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); | ||
404 | |||
405 | dest_cnt = (cmd->data->blocks) << 8; | ||
406 | |||
407 | writel(sg_dma_address(cmd->data->sg), sock->addr + SOCK_DMA_ADDRESS); | ||
408 | |||
409 | writel(cmd->data->blocks - 1, sock->addr + SOCK_MMCSD_NUM_BLOCKS); | ||
410 | writel(cmd->data->blksz - 1, sock->addr + SOCK_MMCSD_BLOCK_LEN); | ||
411 | |||
412 | if (cmd->data->flags & MMC_DATA_WRITE) { | ||
413 | writel(TIFM_MMCSD_TXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG); | ||
414 | writel(dest_cnt | TIFM_DMA_TX | TIFM_DMA_EN, | ||
415 | sock->addr + SOCK_DMA_CONTROL); | ||
416 | } else { | ||
417 | writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG); | ||
418 | writel(dest_cnt | TIFM_DMA_EN, sock->addr + SOCK_DMA_CONTROL); | ||
419 | } | ||
420 | } | ||
421 | |||
422 | static void tifm_sd_set_data_timeout(struct tifm_sd *host, | ||
423 | struct mmc_data *data) | ||
424 | { | ||
425 | struct tifm_dev *sock = host->dev; | ||
426 | unsigned int data_timeout = data->timeout_clks; | ||
427 | |||
428 | if (fixed_timeout) | ||
429 | return; | ||
430 | |||
431 | data_timeout += data->timeout_ns / | ||
432 | ((1000000000UL / host->clk_freq) * host->clk_div); | ||
433 | |||
434 | if (data_timeout < 0xffff) { | ||
435 | writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO); | ||
436 | writel((~TIFM_MMCSD_DPE) | ||
437 | & readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG), | ||
438 | sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG); | ||
439 | } else { | ||
440 | data_timeout = (data_timeout >> 10) + 1; | ||
441 | if (data_timeout > 0xffff) | ||
442 | data_timeout = 0; /* set to unlimited */ | ||
443 | writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO); | ||
444 | writel(TIFM_MMCSD_DPE | ||
445 | | readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG), | ||
446 | sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG); | ||
447 | } | ||
448 | } | ||
449 | |||
450 | static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq) | ||
451 | { | ||
452 | struct tifm_sd *host = mmc_priv(mmc); | ||
453 | struct tifm_dev *sock = host->dev; | ||
454 | unsigned long flags; | ||
455 | int sg_count = 0; | ||
456 | struct mmc_data *r_data = mrq->cmd->data; | ||
457 | |||
458 | spin_lock_irqsave(&sock->lock, flags); | ||
459 | if (host->flags & EJECT) { | ||
460 | spin_unlock_irqrestore(&sock->lock, flags); | ||
461 | goto err_out; | ||
462 | } | ||
463 | |||
464 | if (host->req) { | ||
465 | printk(KERN_ERR DRIVER_NAME ": unfinished request detected\n"); | ||
466 | spin_unlock_irqrestore(&sock->lock, flags); | ||
467 | goto err_out; | ||
468 | } | ||
469 | |||
470 | if (r_data) { | ||
471 | tifm_sd_set_data_timeout(host, r_data); | ||
472 | |||
473 | sg_count = tifm_map_sg(sock, r_data->sg, r_data->sg_len, | ||
474 | mrq->cmd->flags & MMC_DATA_WRITE | ||
475 | ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | ||
476 | if (sg_count != 1) { | ||
477 | printk(KERN_ERR DRIVER_NAME | ||
478 | ": scatterlist map failed\n"); | ||
479 | spin_unlock_irqrestore(&sock->lock, flags); | ||
480 | goto err_out; | ||
481 | } | ||
482 | |||
483 | host->written_blocks = 0; | ||
484 | host->flags &= ~CARD_BUSY; | ||
485 | tifm_sd_prepare_data(host, mrq->cmd); | ||
486 | } | ||
487 | |||
488 | host->req = mrq; | ||
489 | mod_timer(&host->timer, jiffies + host->timeout_jiffies); | ||
490 | host->state = CMD; | ||
491 | writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL), | ||
492 | sock->addr + SOCK_CONTROL); | ||
493 | tifm_sd_exec(host, mrq->cmd); | ||
494 | spin_unlock_irqrestore(&sock->lock, flags); | ||
495 | return; | ||
496 | |||
497 | err_out: | ||
498 | if (sg_count > 0) | ||
499 | tifm_unmap_sg(sock, r_data->sg, r_data->sg_len, | ||
500 | (r_data->flags & MMC_DATA_WRITE) | ||
501 | ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | ||
502 | |||
503 | mrq->cmd->error = MMC_ERR_TIMEOUT; | ||
504 | mmc_request_done(mmc, mrq); | ||
505 | } | ||
506 | |||
507 | static void tifm_sd_end_cmd(unsigned long data) | ||
508 | { | ||
509 | struct tifm_sd *host = (struct tifm_sd*)data; | ||
510 | struct tifm_dev *sock = host->dev; | ||
511 | struct mmc_host *mmc = tifm_get_drvdata(sock); | ||
512 | struct mmc_request *mrq; | ||
513 | struct mmc_data *r_data = NULL; | ||
514 | unsigned long flags; | ||
515 | |||
516 | spin_lock_irqsave(&sock->lock, flags); | ||
517 | |||
518 | del_timer(&host->timer); | ||
519 | mrq = host->req; | ||
520 | host->req = NULL; | ||
521 | host->state = IDLE; | ||
522 | |||
523 | if (!mrq) { | ||
524 | printk(KERN_ERR DRIVER_NAME ": no request to complete?\n"); | ||
525 | spin_unlock_irqrestore(&sock->lock, flags); | ||
526 | return; | ||
527 | } | ||
528 | |||
529 | r_data = mrq->cmd->data; | ||
530 | if (r_data) { | ||
531 | if (r_data->flags & MMC_DATA_WRITE) { | ||
532 | r_data->bytes_xfered = host->written_blocks | ||
533 | * r_data->blksz; | ||
534 | } else { | ||
535 | r_data->bytes_xfered = r_data->blocks - | ||
536 | readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1; | ||
537 | r_data->bytes_xfered *= r_data->blksz; | ||
538 | r_data->bytes_xfered += r_data->blksz - | ||
539 | readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1; | ||
540 | } | ||
541 | tifm_unmap_sg(sock, r_data->sg, r_data->sg_len, | ||
542 | (r_data->flags & MMC_DATA_WRITE) | ||
543 | ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | ||
544 | } | ||
545 | |||
546 | writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), | ||
547 | sock->addr + SOCK_CONTROL); | ||
548 | |||
549 | spin_unlock_irqrestore(&sock->lock, flags); | ||
550 | mmc_request_done(mmc, mrq); | ||
551 | } | ||
552 | |||
553 | static void tifm_sd_request_nodma(struct mmc_host *mmc, struct mmc_request *mrq) | ||
554 | { | ||
555 | struct tifm_sd *host = mmc_priv(mmc); | ||
556 | struct tifm_dev *sock = host->dev; | ||
557 | unsigned long flags; | ||
558 | struct mmc_data *r_data = mrq->cmd->data; | ||
559 | |||
560 | spin_lock_irqsave(&sock->lock, flags); | ||
561 | if (host->flags & EJECT) { | ||
562 | spin_unlock_irqrestore(&sock->lock, flags); | ||
563 | goto err_out; | ||
564 | } | ||
565 | |||
566 | if (host->req) { | ||
567 | printk(KERN_ERR DRIVER_NAME ": unfinished request detected\n"); | ||
568 | spin_unlock_irqrestore(&sock->lock, flags); | ||
569 | goto err_out; | ||
570 | } | ||
571 | |||
572 | if (r_data) { | ||
573 | tifm_sd_set_data_timeout(host, r_data); | ||
574 | |||
575 | host->buffer_size = mrq->cmd->data->blocks | ||
576 | * mrq->cmd->data->blksz; | ||
577 | |||
578 | writel(TIFM_MMCSD_BUFINT | ||
579 | | readl(sock->addr + SOCK_MMCSD_INT_ENABLE), | ||
580 | sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
581 | writel(((TIFM_MMCSD_FIFO_SIZE - 1) << 8) | ||
582 | | (TIFM_MMCSD_FIFO_SIZE - 1), | ||
583 | sock->addr + SOCK_MMCSD_BUFFER_CONFIG); | ||
584 | |||
585 | host->written_blocks = 0; | ||
586 | host->flags &= ~CARD_BUSY; | ||
587 | host->buffer_pos = 0; | ||
588 | writel(r_data->blocks - 1, sock->addr + SOCK_MMCSD_NUM_BLOCKS); | ||
589 | writel(r_data->blksz - 1, sock->addr + SOCK_MMCSD_BLOCK_LEN); | ||
590 | } | ||
591 | |||
592 | host->req = mrq; | ||
593 | mod_timer(&host->timer, jiffies + host->timeout_jiffies); | ||
594 | host->state = CMD; | ||
595 | writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL), | ||
596 | sock->addr + SOCK_CONTROL); | ||
597 | tifm_sd_exec(host, mrq->cmd); | ||
598 | spin_unlock_irqrestore(&sock->lock, flags); | ||
599 | return; | ||
600 | |||
601 | err_out: | ||
602 | mrq->cmd->error = MMC_ERR_TIMEOUT; | ||
603 | mmc_request_done(mmc, mrq); | ||
604 | } | ||
605 | |||
606 | static void tifm_sd_end_cmd_nodma(unsigned long data) | ||
607 | { | ||
608 | struct tifm_sd *host = (struct tifm_sd*)data; | ||
609 | struct tifm_dev *sock = host->dev; | ||
610 | struct mmc_host *mmc = tifm_get_drvdata(sock); | ||
611 | struct mmc_request *mrq; | ||
612 | struct mmc_data *r_data = NULL; | ||
613 | unsigned long flags; | ||
614 | |||
615 | spin_lock_irqsave(&sock->lock, flags); | ||
616 | |||
617 | del_timer(&host->timer); | ||
618 | mrq = host->req; | ||
619 | host->req = NULL; | ||
620 | host->state = IDLE; | ||
621 | |||
622 | if (!mrq) { | ||
623 | printk(KERN_ERR DRIVER_NAME ": no request to complete?\n"); | ||
624 | spin_unlock_irqrestore(&sock->lock, flags); | ||
625 | return; | ||
626 | } | ||
627 | |||
628 | r_data = mrq->cmd->data; | ||
629 | if (r_data) { | ||
630 | writel((~TIFM_MMCSD_BUFINT) & | ||
631 | readl(sock->addr + SOCK_MMCSD_INT_ENABLE), | ||
632 | sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
633 | |||
634 | if (r_data->flags & MMC_DATA_WRITE) { | ||
635 | r_data->bytes_xfered = host->written_blocks | ||
636 | * r_data->blksz; | ||
637 | } else { | ||
638 | r_data->bytes_xfered = r_data->blocks - | ||
639 | readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1; | ||
640 | r_data->bytes_xfered *= r_data->blksz; | ||
641 | r_data->bytes_xfered += r_data->blksz - | ||
642 | readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1; | ||
643 | } | ||
644 | host->buffer_pos = 0; | ||
645 | host->buffer_size = 0; | ||
646 | } | ||
647 | |||
648 | writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), | ||
649 | sock->addr + SOCK_CONTROL); | ||
650 | |||
651 | spin_unlock_irqrestore(&sock->lock, flags); | ||
652 | |||
653 | mmc_request_done(mmc, mrq); | ||
654 | } | ||
655 | |||
656 | static void tifm_sd_terminate(struct tifm_sd *host) | ||
657 | { | ||
658 | struct tifm_dev *sock = host->dev; | ||
659 | unsigned long flags; | ||
660 | |||
661 | writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
662 | mmiowb(); | ||
663 | spin_lock_irqsave(&sock->lock, flags); | ||
664 | host->flags |= EJECT; | ||
665 | if (host->req) { | ||
666 | writel(TIFM_FIFO_INT_SETALL, | ||
667 | sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); | ||
668 | writel(0, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); | ||
669 | tasklet_schedule(&host->finish_tasklet); | ||
670 | } | ||
671 | spin_unlock_irqrestore(&sock->lock, flags); | ||
672 | } | ||
673 | |||
674 | static void tifm_sd_abort(unsigned long data) | ||
675 | { | ||
676 | struct tifm_sd *host = (struct tifm_sd*)data; | ||
677 | |||
678 | printk(KERN_ERR DRIVER_NAME | ||
679 | ": card failed to respond for a long period of time"); | ||
680 | |||
681 | tifm_sd_terminate(host); | ||
682 | tifm_eject(host->dev); | ||
683 | } | ||
684 | |||
685 | static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios) | ||
686 | { | ||
687 | struct tifm_sd *host = mmc_priv(mmc); | ||
688 | struct tifm_dev *sock = host->dev; | ||
689 | unsigned int clk_div1, clk_div2; | ||
690 | unsigned long flags; | ||
691 | |||
692 | spin_lock_irqsave(&sock->lock, flags); | ||
693 | |||
694 | dev_dbg(&sock->dev, "Setting bus width %d, power %d\n", ios->bus_width, | ||
695 | ios->power_mode); | ||
696 | if (ios->bus_width == MMC_BUS_WIDTH_4) { | ||
697 | writel(TIFM_MMCSD_4BBUS | readl(sock->addr + SOCK_MMCSD_CONFIG), | ||
698 | sock->addr + SOCK_MMCSD_CONFIG); | ||
699 | } else { | ||
700 | writel((~TIFM_MMCSD_4BBUS) | ||
701 | & readl(sock->addr + SOCK_MMCSD_CONFIG), | ||
702 | sock->addr + SOCK_MMCSD_CONFIG); | ||
703 | } | ||
704 | |||
705 | if (ios->clock) { | ||
706 | clk_div1 = 20000000 / ios->clock; | ||
707 | if (!clk_div1) | ||
708 | clk_div1 = 1; | ||
709 | |||
710 | clk_div2 = 24000000 / ios->clock; | ||
711 | if (!clk_div2) | ||
712 | clk_div2 = 1; | ||
713 | |||
714 | if ((20000000 / clk_div1) > ios->clock) | ||
715 | clk_div1++; | ||
716 | if ((24000000 / clk_div2) > ios->clock) | ||
717 | clk_div2++; | ||
718 | if ((20000000 / clk_div1) > (24000000 / clk_div2)) { | ||
719 | host->clk_freq = 20000000; | ||
720 | host->clk_div = clk_div1; | ||
721 | writel((~TIFM_CTRL_FAST_CLK) | ||
722 | & readl(sock->addr + SOCK_CONTROL), | ||
723 | sock->addr + SOCK_CONTROL); | ||
724 | } else { | ||
725 | host->clk_freq = 24000000; | ||
726 | host->clk_div = clk_div2; | ||
727 | writel(TIFM_CTRL_FAST_CLK | ||
728 | | readl(sock->addr + SOCK_CONTROL), | ||
729 | sock->addr + SOCK_CONTROL); | ||
730 | } | ||
731 | } else { | ||
732 | host->clk_div = 0; | ||
733 | } | ||
734 | host->clk_div &= TIFM_MMCSD_CLKMASK; | ||
735 | writel(host->clk_div | ||
736 | | ((~TIFM_MMCSD_CLKMASK) | ||
737 | & readl(sock->addr + SOCK_MMCSD_CONFIG)), | ||
738 | sock->addr + SOCK_MMCSD_CONFIG); | ||
739 | |||
740 | if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) | ||
741 | host->flags |= OPENDRAIN; | ||
742 | else | ||
743 | host->flags &= ~OPENDRAIN; | ||
744 | |||
745 | /* chip_select : maybe later */ | ||
746 | //vdd | ||
747 | //power is set before probe / after remove | ||
748 | //I believe, power_off when already marked for eject is sufficient to | ||
749 | // allow removal. | ||
750 | if ((host->flags & EJECT) && ios->power_mode == MMC_POWER_OFF) { | ||
751 | host->flags |= EJECT_DONE; | ||
752 | wake_up_all(&host->notify); | ||
753 | } | ||
754 | |||
755 | spin_unlock_irqrestore(&sock->lock, flags); | ||
756 | } | ||
757 | |||
758 | static int tifm_sd_ro(struct mmc_host *mmc) | ||
759 | { | ||
760 | int rc; | ||
761 | struct tifm_sd *host = mmc_priv(mmc); | ||
762 | struct tifm_dev *sock = host->dev; | ||
763 | unsigned long flags; | ||
764 | |||
765 | spin_lock_irqsave(&sock->lock, flags); | ||
766 | |||
767 | host->flags |= (CARD_RO & readl(sock->addr + SOCK_PRESENT_STATE)); | ||
768 | rc = (host->flags & CARD_RO) ? 1 : 0; | ||
769 | |||
770 | spin_unlock_irqrestore(&sock->lock, flags); | ||
771 | return rc; | ||
772 | } | ||
773 | |||
774 | static struct mmc_host_ops tifm_sd_ops = { | ||
775 | .request = tifm_sd_request, | ||
776 | .set_ios = tifm_sd_ios, | ||
777 | .get_ro = tifm_sd_ro | ||
778 | }; | ||
779 | |||
780 | static int tifm_sd_initialize_host(struct tifm_sd *host) | ||
781 | { | ||
782 | int rc; | ||
783 | unsigned int host_status = 0; | ||
784 | struct tifm_dev *sock = host->dev; | ||
785 | |||
786 | writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
787 | mmiowb(); | ||
788 | host->clk_div = 61; | ||
789 | host->clk_freq = 20000000; | ||
790 | writel(TIFM_MMCSD_RESET, sock->addr + SOCK_MMCSD_SYSTEM_CONTROL); | ||
791 | writel(host->clk_div | TIFM_MMCSD_POWER, | ||
792 | sock->addr + SOCK_MMCSD_CONFIG); | ||
793 | |||
794 | /* wait up to 0.51 sec for reset */ | ||
795 | for (rc = 2; rc <= 256; rc <<= 1) { | ||
796 | if (1 & readl(sock->addr + SOCK_MMCSD_SYSTEM_STATUS)) { | ||
797 | rc = 0; | ||
798 | break; | ||
799 | } | ||
800 | msleep(rc); | ||
801 | } | ||
802 | |||
803 | if (rc) { | ||
804 | printk(KERN_ERR DRIVER_NAME | ||
805 | ": controller failed to reset\n"); | ||
806 | return -ENODEV; | ||
807 | } | ||
808 | |||
809 | writel(0, sock->addr + SOCK_MMCSD_NUM_BLOCKS); | ||
810 | writel(host->clk_div | TIFM_MMCSD_POWER, | ||
811 | sock->addr + SOCK_MMCSD_CONFIG); | ||
812 | writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG); | ||
813 | |||
814 | // command timeout fixed to 64 clocks for now | ||
815 | writel(64, sock->addr + SOCK_MMCSD_COMMAND_TO); | ||
816 | writel(TIFM_MMCSD_INAB, sock->addr + SOCK_MMCSD_COMMAND); | ||
817 | |||
818 | /* INAB should take much less than reset */ | ||
819 | for (rc = 1; rc <= 16; rc <<= 1) { | ||
820 | host_status = readl(sock->addr + SOCK_MMCSD_STATUS); | ||
821 | writel(host_status, sock->addr + SOCK_MMCSD_STATUS); | ||
822 | if (!(host_status & TIFM_MMCSD_ERRMASK) | ||
823 | && (host_status & TIFM_MMCSD_EOC)) { | ||
824 | rc = 0; | ||
825 | break; | ||
826 | } | ||
827 | msleep(rc); | ||
828 | } | ||
829 | |||
830 | if (rc) { | ||
831 | printk(KERN_ERR DRIVER_NAME | ||
832 | ": card not ready - probe failed on initialization\n"); | ||
833 | return -ENODEV; | ||
834 | } | ||
835 | |||
836 | writel(TIFM_MMCSD_DATAMASK | TIFM_MMCSD_ERRMASK, | ||
837 | sock->addr + SOCK_MMCSD_INT_ENABLE); | ||
838 | mmiowb(); | ||
839 | |||
840 | return 0; | ||
841 | } | ||
842 | |||
843 | static int tifm_sd_probe(struct tifm_dev *sock) | ||
844 | { | ||
845 | struct mmc_host *mmc; | ||
846 | struct tifm_sd *host; | ||
847 | int rc = -EIO; | ||
848 | |||
849 | if (!(TIFM_SOCK_STATE_OCCUPIED | ||
850 | & readl(sock->addr + SOCK_PRESENT_STATE))) { | ||
851 | printk(KERN_WARNING DRIVER_NAME ": card gone, unexpectedly\n"); | ||
852 | return rc; | ||
853 | } | ||
854 | |||
855 | mmc = mmc_alloc_host(sizeof(struct tifm_sd), &sock->dev); | ||
856 | if (!mmc) | ||
857 | return -ENOMEM; | ||
858 | |||
859 | host = mmc_priv(mmc); | ||
860 | tifm_set_drvdata(sock, mmc); | ||
861 | host->dev = sock; | ||
862 | host->timeout_jiffies = msecs_to_jiffies(1000); | ||
863 | |||
864 | init_waitqueue_head(&host->notify); | ||
865 | tasklet_init(&host->finish_tasklet, | ||
866 | no_dma ? tifm_sd_end_cmd_nodma : tifm_sd_end_cmd, | ||
867 | (unsigned long)host); | ||
868 | setup_timer(&host->timer, tifm_sd_abort, (unsigned long)host); | ||
869 | |||
870 | tifm_sd_ops.request = no_dma ? tifm_sd_request_nodma : tifm_sd_request; | ||
871 | mmc->ops = &tifm_sd_ops; | ||
872 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | ||
873 | mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE; | ||
874 | mmc->f_min = 20000000 / 60; | ||
875 | mmc->f_max = 24000000; | ||
876 | mmc->max_hw_segs = 1; | ||
877 | mmc->max_phys_segs = 1; | ||
878 | // limited by DMA counter - it's safer to stick with | ||
879 | // block counter has 11 bits though | ||
880 | mmc->max_blk_count = 256; | ||
881 | // 2k maximum hw block length | ||
882 | mmc->max_blk_size = 2048; | ||
883 | mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; | ||
884 | mmc->max_seg_size = mmc->max_req_size; | ||
885 | sock->signal_irq = tifm_sd_signal_irq; | ||
886 | rc = tifm_sd_initialize_host(host); | ||
887 | |||
888 | if (!rc) | ||
889 | rc = mmc_add_host(mmc); | ||
890 | if (rc) | ||
891 | goto out_free_mmc; | ||
892 | |||
893 | return 0; | ||
894 | out_free_mmc: | ||
895 | mmc_free_host(mmc); | ||
896 | return rc; | ||
897 | } | ||
898 | |||
899 | static void tifm_sd_remove(struct tifm_dev *sock) | ||
900 | { | ||
901 | struct mmc_host *mmc = tifm_get_drvdata(sock); | ||
902 | struct tifm_sd *host = mmc_priv(mmc); | ||
903 | |||
904 | del_timer_sync(&host->timer); | ||
905 | tifm_sd_terminate(host); | ||
906 | wait_event_timeout(host->notify, host->flags & EJECT_DONE, | ||
907 | host->timeout_jiffies); | ||
908 | tasklet_kill(&host->finish_tasklet); | ||
909 | mmc_remove_host(mmc); | ||
910 | |||
911 | /* The meaning of the bit majority in this constant is unknown. */ | ||
912 | writel(0xfff8 & readl(sock->addr + SOCK_CONTROL), | ||
913 | sock->addr + SOCK_CONTROL); | ||
914 | |||
915 | tifm_set_drvdata(sock, NULL); | ||
916 | mmc_free_host(mmc); | ||
917 | } | ||
918 | |||
919 | #ifdef CONFIG_PM | ||
920 | |||
921 | static int tifm_sd_suspend(struct tifm_dev *sock, pm_message_t state) | ||
922 | { | ||
923 | struct mmc_host *mmc = tifm_get_drvdata(sock); | ||
924 | int rc; | ||
925 | |||
926 | rc = mmc_suspend_host(mmc, state); | ||
927 | /* The meaning of the bit majority in this constant is unknown. */ | ||
928 | writel(0xfff8 & readl(sock->addr + SOCK_CONTROL), | ||
929 | sock->addr + SOCK_CONTROL); | ||
930 | return rc; | ||
931 | } | ||
932 | |||
933 | static int tifm_sd_resume(struct tifm_dev *sock) | ||
934 | { | ||
935 | struct mmc_host *mmc = tifm_get_drvdata(sock); | ||
936 | struct tifm_sd *host = mmc_priv(mmc); | ||
937 | |||
938 | if (sock->media_id != FM_SD | ||
939 | || tifm_sd_initialize_host(host)) { | ||
940 | tifm_eject(sock); | ||
941 | return 0; | ||
942 | } else { | ||
943 | return mmc_resume_host(mmc); | ||
944 | } | ||
945 | } | ||
946 | |||
947 | #else | ||
948 | |||
949 | #define tifm_sd_suspend NULL | ||
950 | #define tifm_sd_resume NULL | ||
951 | |||
952 | #endif /* CONFIG_PM */ | ||
953 | |||
954 | static tifm_media_id tifm_sd_id_tbl[] = { | ||
955 | FM_SD, 0 | ||
956 | }; | ||
957 | |||
958 | static struct tifm_driver tifm_sd_driver = { | ||
959 | .driver = { | ||
960 | .name = DRIVER_NAME, | ||
961 | .owner = THIS_MODULE | ||
962 | }, | ||
963 | .id_table = tifm_sd_id_tbl, | ||
964 | .probe = tifm_sd_probe, | ||
965 | .remove = tifm_sd_remove, | ||
966 | .suspend = tifm_sd_suspend, | ||
967 | .resume = tifm_sd_resume | ||
968 | }; | ||
969 | |||
970 | static int __init tifm_sd_init(void) | ||
971 | { | ||
972 | return tifm_register_driver(&tifm_sd_driver); | ||
973 | } | ||
974 | |||
975 | static void __exit tifm_sd_exit(void) | ||
976 | { | ||
977 | tifm_unregister_driver(&tifm_sd_driver); | ||
978 | } | ||
979 | |||
980 | MODULE_AUTHOR("Alex Dubov"); | ||
981 | MODULE_DESCRIPTION("TI FlashMedia SD driver"); | ||
982 | MODULE_LICENSE("GPL"); | ||
983 | MODULE_DEVICE_TABLE(tifm, tifm_sd_id_tbl); | ||
984 | MODULE_VERSION(DRIVER_VERSION); | ||
985 | |||
986 | module_init(tifm_sd_init); | ||
987 | module_exit(tifm_sd_exit); | ||
diff --git a/include/asm-arm/arch-imx/mmc.h b/include/asm-arm/arch-imx/mmc.h index 1937151665c7..84c726934ace 100644 --- a/include/asm-arm/arch-imx/mmc.h +++ b/include/asm-arm/arch-imx/mmc.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #ifndef ASMARM_ARCH_MMC_H | 1 | #ifndef ASMARM_ARCH_MMC_H |
2 | #define ASMARM_ARCH_MMC_H | 2 | #define ASMARM_ARCH_MMC_H |
3 | 3 | ||
4 | #include <linux/mmc/protocol.h> | 4 | #include <linux/mmc/host.h> |
5 | 5 | ||
6 | struct imxmmc_platform_data { | 6 | struct imxmmc_platform_data { |
7 | int (*card_present)(void); | 7 | int (*card_present)(void); |
diff --git a/include/asm-arm/arch-pxa/mmc.h b/include/asm-arm/arch-pxa/mmc.h index a38a28c4bbd8..ef4f570381d1 100644 --- a/include/asm-arm/arch-pxa/mmc.h +++ b/include/asm-arm/arch-pxa/mmc.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #ifndef ASMARM_ARCH_MMC_H | 1 | #ifndef ASMARM_ARCH_MMC_H |
2 | #define ASMARM_ARCH_MMC_H | 2 | #define ASMARM_ARCH_MMC_H |
3 | 3 | ||
4 | #include <linux/mmc/protocol.h> | 4 | #include <linux/mmc/host.h> |
5 | #include <linux/interrupt.h> | 5 | #include <linux/interrupt.h> |
6 | 6 | ||
7 | struct device; | 7 | struct device; |
diff --git a/include/asm-arm/mach/mmc.h b/include/asm-arm/mach/mmc.h index 1b3555d4b41e..eb91145c00c4 100644 --- a/include/asm-arm/mach/mmc.h +++ b/include/asm-arm/mach/mmc.h | |||
@@ -4,7 +4,7 @@ | |||
4 | #ifndef ASMARM_MACH_MMC_H | 4 | #ifndef ASMARM_MACH_MMC_H |
5 | #define ASMARM_MACH_MMC_H | 5 | #define ASMARM_MACH_MMC_H |
6 | 6 | ||
7 | #include <linux/mmc/protocol.h> | 7 | #include <linux/mmc/host.h> |
8 | 8 | ||
9 | struct mmc_platform_data { | 9 | struct mmc_platform_data { |
10 | unsigned int ocr_mask; /* available voltages */ | 10 | unsigned int ocr_mask; /* available voltages */ |
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index e45712acfac5..badf702fcff4 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h | |||
@@ -10,7 +10,7 @@ | |||
10 | #ifndef LINUX_MMC_CARD_H | 10 | #ifndef LINUX_MMC_CARD_H |
11 | #define LINUX_MMC_CARD_H | 11 | #define LINUX_MMC_CARD_H |
12 | 12 | ||
13 | #include <linux/mmc/mmc.h> | 13 | #include <linux/mmc/core.h> |
14 | 14 | ||
15 | struct mmc_cid { | 15 | struct mmc_cid { |
16 | unsigned int manfid; | 16 | unsigned int manfid; |
@@ -41,6 +41,7 @@ struct mmc_csd { | |||
41 | 41 | ||
42 | struct mmc_ext_csd { | 42 | struct mmc_ext_csd { |
43 | unsigned int hs_max_dtr; | 43 | unsigned int hs_max_dtr; |
44 | unsigned int sectors; | ||
44 | }; | 45 | }; |
45 | 46 | ||
46 | struct sd_scr { | 47 | struct sd_scr { |
@@ -60,18 +61,17 @@ struct mmc_host; | |||
60 | * MMC device | 61 | * MMC device |
61 | */ | 62 | */ |
62 | struct mmc_card { | 63 | struct mmc_card { |
63 | struct list_head node; /* node in hosts devices list */ | ||
64 | struct mmc_host *host; /* the host this device belongs to */ | 64 | struct mmc_host *host; /* the host this device belongs to */ |
65 | struct device dev; /* the device */ | 65 | struct device dev; /* the device */ |
66 | unsigned int rca; /* relative card address of device */ | 66 | unsigned int rca; /* relative card address of device */ |
67 | unsigned int type; /* card type */ | ||
68 | #define MMC_TYPE_MMC 0 /* MMC card */ | ||
69 | #define MMC_TYPE_SD 1 /* SD card */ | ||
67 | unsigned int state; /* (our) card state */ | 70 | unsigned int state; /* (our) card state */ |
68 | #define MMC_STATE_PRESENT (1<<0) /* present in sysfs */ | 71 | #define MMC_STATE_PRESENT (1<<0) /* present in sysfs */ |
69 | #define MMC_STATE_DEAD (1<<1) /* device no longer in stack */ | 72 | #define MMC_STATE_READONLY (1<<1) /* card is read-only */ |
70 | #define MMC_STATE_BAD (1<<2) /* unrecognised device */ | 73 | #define MMC_STATE_HIGHSPEED (1<<2) /* card is in high speed mode */ |
71 | #define MMC_STATE_SDCARD (1<<3) /* is an SD card */ | 74 | #define MMC_STATE_BLOCKADDR (1<<3) /* card uses block-addressing */ |
72 | #define MMC_STATE_READONLY (1<<4) /* card is read-only */ | ||
73 | #define MMC_STATE_HIGHSPEED (1<<5) /* card is in high speed mode */ | ||
74 | #define MMC_STATE_BLOCKADDR (1<<6) /* card uses block-addressing */ | ||
75 | u32 raw_cid[4]; /* raw card CID */ | 75 | u32 raw_cid[4]; /* raw card CID */ |
76 | u32 raw_csd[4]; /* raw card CSD */ | 76 | u32 raw_csd[4]; /* raw card CSD */ |
77 | u32 raw_scr[2]; /* raw card SCR */ | 77 | u32 raw_scr[2]; /* raw card SCR */ |
@@ -82,18 +82,15 @@ struct mmc_card { | |||
82 | struct sd_switch_caps sw_caps; /* switch (CMD6) caps */ | 82 | struct sd_switch_caps sw_caps; /* switch (CMD6) caps */ |
83 | }; | 83 | }; |
84 | 84 | ||
85 | #define mmc_card_mmc(c) ((c)->type == MMC_TYPE_MMC) | ||
86 | #define mmc_card_sd(c) ((c)->type == MMC_TYPE_SD) | ||
87 | |||
85 | #define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT) | 88 | #define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT) |
86 | #define mmc_card_dead(c) ((c)->state & MMC_STATE_DEAD) | ||
87 | #define mmc_card_bad(c) ((c)->state & MMC_STATE_BAD) | ||
88 | #define mmc_card_sd(c) ((c)->state & MMC_STATE_SDCARD) | ||
89 | #define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY) | 89 | #define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY) |
90 | #define mmc_card_highspeed(c) ((c)->state & MMC_STATE_HIGHSPEED) | 90 | #define mmc_card_highspeed(c) ((c)->state & MMC_STATE_HIGHSPEED) |
91 | #define mmc_card_blockaddr(c) ((c)->state & MMC_STATE_BLOCKADDR) | 91 | #define mmc_card_blockaddr(c) ((c)->state & MMC_STATE_BLOCKADDR) |
92 | 92 | ||
93 | #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) | 93 | #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) |
94 | #define mmc_card_set_dead(c) ((c)->state |= MMC_STATE_DEAD) | ||
95 | #define mmc_card_set_bad(c) ((c)->state |= MMC_STATE_BAD) | ||
96 | #define mmc_card_set_sd(c) ((c)->state |= MMC_STATE_SDCARD) | ||
97 | #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) | 94 | #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) |
98 | #define mmc_card_set_highspeed(c) ((c)->state |= MMC_STATE_HIGHSPEED) | 95 | #define mmc_card_set_highspeed(c) ((c)->state |= MMC_STATE_HIGHSPEED) |
99 | #define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR) | 96 | #define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR) |
@@ -119,11 +116,4 @@ struct mmc_driver { | |||
119 | extern int mmc_register_driver(struct mmc_driver *); | 116 | extern int mmc_register_driver(struct mmc_driver *); |
120 | extern void mmc_unregister_driver(struct mmc_driver *); | 117 | extern void mmc_unregister_driver(struct mmc_driver *); |
121 | 118 | ||
122 | static inline int mmc_card_claim_host(struct mmc_card *card) | ||
123 | { | ||
124 | return __mmc_claim_host(card->host, card); | ||
125 | } | ||
126 | |||
127 | #define mmc_card_release_host(c) mmc_release_host((c)->host) | ||
128 | |||
129 | #endif | 119 | #endif |
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h new file mode 100644 index 000000000000..04bbe12fae8d --- /dev/null +++ b/include/linux/mmc/core.h | |||
@@ -0,0 +1,112 @@ | |||
1 | /* | ||
2 | * linux/include/linux/mmc/core.h | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | #ifndef LINUX_MMC_CORE_H | ||
9 | #define LINUX_MMC_CORE_H | ||
10 | |||
11 | #include <linux/interrupt.h> | ||
12 | #include <linux/device.h> | ||
13 | |||
14 | struct request; | ||
15 | struct mmc_data; | ||
16 | struct mmc_request; | ||
17 | |||
18 | struct mmc_command { | ||
19 | u32 opcode; | ||
20 | u32 arg; | ||
21 | u32 resp[4]; | ||
22 | unsigned int flags; /* expected response type */ | ||
23 | #define MMC_RSP_PRESENT (1 << 0) | ||
24 | #define MMC_RSP_136 (1 << 1) /* 136 bit response */ | ||
25 | #define MMC_RSP_CRC (1 << 2) /* expect valid crc */ | ||
26 | #define MMC_RSP_BUSY (1 << 3) /* card may send busy */ | ||
27 | #define MMC_RSP_OPCODE (1 << 4) /* response contains opcode */ | ||
28 | #define MMC_CMD_MASK (3 << 5) /* command type */ | ||
29 | #define MMC_CMD_AC (0 << 5) | ||
30 | #define MMC_CMD_ADTC (1 << 5) | ||
31 | #define MMC_CMD_BC (2 << 5) | ||
32 | #define MMC_CMD_BCR (3 << 5) | ||
33 | |||
34 | /* | ||
35 | * These are the response types, and correspond to valid bit | ||
36 | * patterns of the above flags. One additional valid pattern | ||
37 | * is all zeros, which means we don't expect a response. | ||
38 | */ | ||
39 | #define MMC_RSP_NONE (0) | ||
40 | #define MMC_RSP_R1 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) | ||
41 | #define MMC_RSP_R1B (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY) | ||
42 | #define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC) | ||
43 | #define MMC_RSP_R3 (MMC_RSP_PRESENT) | ||
44 | #define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) | ||
45 | #define MMC_RSP_R7 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) | ||
46 | |||
47 | #define mmc_resp_type(cmd) ((cmd)->flags & (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC|MMC_RSP_BUSY|MMC_RSP_OPCODE)) | ||
48 | |||
49 | /* | ||
50 | * These are the command types. | ||
51 | */ | ||
52 | #define mmc_cmd_type(cmd) ((cmd)->flags & MMC_CMD_MASK) | ||
53 | |||
54 | unsigned int retries; /* max number of retries */ | ||
55 | unsigned int error; /* command error */ | ||
56 | |||
57 | #define MMC_ERR_NONE 0 | ||
58 | #define MMC_ERR_TIMEOUT 1 | ||
59 | #define MMC_ERR_BADCRC 2 | ||
60 | #define MMC_ERR_FIFO 3 | ||
61 | #define MMC_ERR_FAILED 4 | ||
62 | #define MMC_ERR_INVALID 5 | ||
63 | |||
64 | struct mmc_data *data; /* data segment associated with cmd */ | ||
65 | struct mmc_request *mrq; /* associated request */ | ||
66 | }; | ||
67 | |||
68 | struct mmc_data { | ||
69 | unsigned int timeout_ns; /* data timeout (in ns, max 80ms) */ | ||
70 | unsigned int timeout_clks; /* data timeout (in clocks) */ | ||
71 | unsigned int blksz; /* data block size */ | ||
72 | unsigned int blocks; /* number of blocks */ | ||
73 | unsigned int error; /* data error */ | ||
74 | unsigned int flags; | ||
75 | |||
76 | #define MMC_DATA_WRITE (1 << 8) | ||
77 | #define MMC_DATA_READ (1 << 9) | ||
78 | #define MMC_DATA_STREAM (1 << 10) | ||
79 | #define MMC_DATA_MULTI (1 << 11) | ||
80 | |||
81 | unsigned int bytes_xfered; | ||
82 | |||
83 | struct mmc_command *stop; /* stop command */ | ||
84 | struct mmc_request *mrq; /* associated request */ | ||
85 | |||
86 | unsigned int sg_len; /* size of scatter list */ | ||
87 | struct scatterlist *sg; /* I/O scatter list */ | ||
88 | }; | ||
89 | |||
90 | struct mmc_request { | ||
91 | struct mmc_command *cmd; | ||
92 | struct mmc_data *data; | ||
93 | struct mmc_command *stop; | ||
94 | |||
95 | void *done_data; /* completion data */ | ||
96 | void (*done)(struct mmc_request *);/* completion function */ | ||
97 | }; | ||
98 | |||
99 | struct mmc_host; | ||
100 | struct mmc_card; | ||
101 | |||
102 | extern int mmc_wait_for_req(struct mmc_host *, struct mmc_request *); | ||
103 | extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int); | ||
104 | extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, | ||
105 | struct mmc_command *, int); | ||
106 | |||
107 | extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *, int); | ||
108 | |||
109 | extern void mmc_claim_host(struct mmc_host *host); | ||
110 | extern void mmc_release_host(struct mmc_host *host); | ||
111 | |||
112 | #endif | ||
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index bfcef8a1ad8b..b1350dfd3e91 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h | |||
@@ -10,36 +10,13 @@ | |||
10 | #ifndef LINUX_MMC_HOST_H | 10 | #ifndef LINUX_MMC_HOST_H |
11 | #define LINUX_MMC_HOST_H | 11 | #define LINUX_MMC_HOST_H |
12 | 12 | ||
13 | #include <linux/mmc/mmc.h> | 13 | #include <linux/mmc/core.h> |
14 | 14 | ||
15 | struct mmc_ios { | 15 | struct mmc_ios { |
16 | unsigned int clock; /* clock rate */ | 16 | unsigned int clock; /* clock rate */ |
17 | unsigned short vdd; | 17 | unsigned short vdd; |
18 | 18 | ||
19 | #define MMC_VDD_150 0 | 19 | /* vdd stores the bit number of the selected voltage range from below. */ |
20 | #define MMC_VDD_155 1 | ||
21 | #define MMC_VDD_160 2 | ||
22 | #define MMC_VDD_165 3 | ||
23 | #define MMC_VDD_170 4 | ||
24 | #define MMC_VDD_180 5 | ||
25 | #define MMC_VDD_190 6 | ||
26 | #define MMC_VDD_200 7 | ||
27 | #define MMC_VDD_210 8 | ||
28 | #define MMC_VDD_220 9 | ||
29 | #define MMC_VDD_230 10 | ||
30 | #define MMC_VDD_240 11 | ||
31 | #define MMC_VDD_250 12 | ||
32 | #define MMC_VDD_260 13 | ||
33 | #define MMC_VDD_270 14 | ||
34 | #define MMC_VDD_280 15 | ||
35 | #define MMC_VDD_290 16 | ||
36 | #define MMC_VDD_300 17 | ||
37 | #define MMC_VDD_310 18 | ||
38 | #define MMC_VDD_320 19 | ||
39 | #define MMC_VDD_330 20 | ||
40 | #define MMC_VDD_340 21 | ||
41 | #define MMC_VDD_350 22 | ||
42 | #define MMC_VDD_360 23 | ||
43 | 20 | ||
44 | unsigned char bus_mode; /* command output mode */ | 21 | unsigned char bus_mode; /* command output mode */ |
45 | 22 | ||
@@ -88,6 +65,24 @@ struct mmc_host { | |||
88 | unsigned int f_max; | 65 | unsigned int f_max; |
89 | u32 ocr_avail; | 66 | u32 ocr_avail; |
90 | 67 | ||
68 | #define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */ | ||
69 | #define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */ | ||
70 | #define MMC_VDD_21_22 0x00000200 /* VDD voltage 2.1 ~ 2.2 */ | ||
71 | #define MMC_VDD_22_23 0x00000400 /* VDD voltage 2.2 ~ 2.3 */ | ||
72 | #define MMC_VDD_23_24 0x00000800 /* VDD voltage 2.3 ~ 2.4 */ | ||
73 | #define MMC_VDD_24_25 0x00001000 /* VDD voltage 2.4 ~ 2.5 */ | ||
74 | #define MMC_VDD_25_26 0x00002000 /* VDD voltage 2.5 ~ 2.6 */ | ||
75 | #define MMC_VDD_26_27 0x00004000 /* VDD voltage 2.6 ~ 2.7 */ | ||
76 | #define MMC_VDD_27_28 0x00008000 /* VDD voltage 2.7 ~ 2.8 */ | ||
77 | #define MMC_VDD_28_29 0x00010000 /* VDD voltage 2.8 ~ 2.9 */ | ||
78 | #define MMC_VDD_29_30 0x00020000 /* VDD voltage 2.9 ~ 3.0 */ | ||
79 | #define MMC_VDD_30_31 0x00040000 /* VDD voltage 3.0 ~ 3.1 */ | ||
80 | #define MMC_VDD_31_32 0x00080000 /* VDD voltage 3.1 ~ 3.2 */ | ||
81 | #define MMC_VDD_32_33 0x00100000 /* VDD voltage 3.2 ~ 3.3 */ | ||
82 | #define MMC_VDD_33_34 0x00200000 /* VDD voltage 3.3 ~ 3.4 */ | ||
83 | #define MMC_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */ | ||
84 | #define MMC_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */ | ||
85 | |||
91 | unsigned long caps; /* Host capabilities */ | 86 | unsigned long caps; /* Host capabilities */ |
92 | 87 | ||
93 | #define MMC_CAP_4_BIT_DATA (1 << 0) /* Can the host do 4 bit transfers */ | 88 | #define MMC_CAP_4_BIT_DATA (1 << 0) /* Can the host do 4 bit transfers */ |
@@ -106,6 +101,8 @@ struct mmc_host { | |||
106 | unsigned int max_blk_count; /* maximum number of blocks in one req */ | 101 | unsigned int max_blk_count; /* maximum number of blocks in one req */ |
107 | 102 | ||
108 | /* private data */ | 103 | /* private data */ |
104 | spinlock_t lock; /* lock for claim and bus ops */ | ||
105 | |||
109 | struct mmc_ios ios; /* current io bus settings */ | 106 | struct mmc_ios ios; /* current io bus settings */ |
110 | u32 ocr; /* the current OCR setting */ | 107 | u32 ocr; /* the current OCR setting */ |
111 | 108 | ||
@@ -113,15 +110,19 @@ struct mmc_host { | |||
113 | #define MMC_MODE_MMC 0 | 110 | #define MMC_MODE_MMC 0 |
114 | #define MMC_MODE_SD 1 | 111 | #define MMC_MODE_SD 1 |
115 | 112 | ||
116 | struct list_head cards; /* devices attached to this host */ | 113 | struct mmc_card *card; /* device attached to this host */ |
117 | 114 | ||
118 | wait_queue_head_t wq; | 115 | wait_queue_head_t wq; |
119 | spinlock_t lock; /* claimed lock */ | ||
120 | unsigned int claimed:1; /* host exclusively claimed */ | 116 | unsigned int claimed:1; /* host exclusively claimed */ |
121 | 117 | ||
122 | struct mmc_card *card_selected; /* the selected MMC card */ | ||
123 | |||
124 | struct delayed_work detect; | 118 | struct delayed_work detect; |
119 | #ifdef CONFIG_MMC_DEBUG | ||
120 | unsigned int removed:1; /* host is being removed */ | ||
121 | #endif | ||
122 | |||
123 | const struct mmc_bus_ops *bus_ops; /* current bus driver */ | ||
124 | unsigned int bus_refs; /* reference counter */ | ||
125 | unsigned int bus_dead:1; /* bus has been released */ | ||
125 | 126 | ||
126 | unsigned long private[0] ____cacheline_aligned; | 127 | unsigned long private[0] ____cacheline_aligned; |
127 | }; | 128 | }; |
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index cdc54be804f1..e3ed9b95040e 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h | |||
@@ -1,119 +1,257 @@ | |||
1 | /* | 1 | /* |
2 | * linux/include/linux/mmc/mmc.h | 2 | * Header for MultiMediaCard (MMC) |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify | 4 | * Copyright 2002 Hewlett-Packard Company |
5 | * it under the terms of the GNU General Public License version 2 as | 5 | * |
6 | * published by the Free Software Foundation. | 6 | * Use consistent with the GNU GPL is permitted, |
7 | * provided that this copyright notice is | ||
8 | * preserved in its entirety in all copies and derived works. | ||
9 | * | ||
10 | * HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED, | ||
11 | * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS | ||
12 | * FITNESS FOR ANY PARTICULAR PURPOSE. | ||
13 | * | ||
14 | * Many thanks to Alessandro Rubini and Jonathan Corbet! | ||
15 | * | ||
16 | * Based strongly on code by: | ||
17 | * | ||
18 | * Author: Yong-iL Joh <tolkien@mizi.com> | ||
19 | * Date : $Date: 2002/06/18 12:37:30 $ | ||
20 | * | ||
21 | * Author: Andrew Christian | ||
22 | * 15 May 2002 | ||
7 | */ | 23 | */ |
8 | #ifndef MMC_H | 24 | |
9 | #define MMC_H | 25 | #ifndef MMC_MMC_H |
10 | 26 | #define MMC_MMC_H | |
11 | #include <linux/list.h> | 27 | |
12 | #include <linux/interrupt.h> | 28 | /* Standard MMC commands (4.1) type argument response */ |
13 | #include <linux/device.h> | 29 | /* class 1 */ |
14 | 30 | #define MMC_GO_IDLE_STATE 0 /* bc */ | |
15 | struct request; | 31 | #define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */ |
16 | struct mmc_data; | 32 | #define MMC_ALL_SEND_CID 2 /* bcr R2 */ |
17 | struct mmc_request; | 33 | #define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */ |
18 | 34 | #define MMC_SET_DSR 4 /* bc [31:16] RCA */ | |
19 | struct mmc_command { | 35 | #define MMC_SWITCH 6 /* ac [31:0] See below R1b */ |
20 | u32 opcode; | 36 | #define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */ |
21 | u32 arg; | 37 | #define MMC_SEND_EXT_CSD 8 /* adtc R1 */ |
22 | u32 resp[4]; | 38 | #define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */ |
23 | unsigned int flags; /* expected response type */ | 39 | #define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */ |
24 | #define MMC_RSP_PRESENT (1 << 0) | 40 | #define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */ |
25 | #define MMC_RSP_136 (1 << 1) /* 136 bit response */ | 41 | #define MMC_STOP_TRANSMISSION 12 /* ac R1b */ |
26 | #define MMC_RSP_CRC (1 << 2) /* expect valid crc */ | 42 | #define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */ |
27 | #define MMC_RSP_BUSY (1 << 3) /* card may send busy */ | 43 | #define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */ |
28 | #define MMC_RSP_OPCODE (1 << 4) /* response contains opcode */ | 44 | |
29 | #define MMC_CMD_MASK (3 << 5) /* command type */ | 45 | /* class 2 */ |
30 | #define MMC_CMD_AC (0 << 5) | 46 | #define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */ |
31 | #define MMC_CMD_ADTC (1 << 5) | 47 | #define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */ |
32 | #define MMC_CMD_BC (2 << 5) | 48 | #define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */ |
33 | #define MMC_CMD_BCR (3 << 5) | 49 | |
50 | /* class 3 */ | ||
51 | #define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */ | ||
52 | |||
53 | /* class 4 */ | ||
54 | #define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */ | ||
55 | #define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */ | ||
56 | #define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */ | ||
57 | #define MMC_PROGRAM_CID 26 /* adtc R1 */ | ||
58 | #define MMC_PROGRAM_CSD 27 /* adtc R1 */ | ||
59 | |||
60 | /* class 6 */ | ||
61 | #define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */ | ||
62 | #define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */ | ||
63 | #define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */ | ||
64 | |||
65 | /* class 5 */ | ||
66 | #define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */ | ||
67 | #define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */ | ||
68 | #define MMC_ERASE 38 /* ac R1b */ | ||
69 | |||
70 | /* class 9 */ | ||
71 | #define MMC_FAST_IO 39 /* ac <Complex> R4 */ | ||
72 | #define MMC_GO_IRQ_STATE 40 /* bcr R5 */ | ||
73 | |||
74 | /* class 7 */ | ||
75 | #define MMC_LOCK_UNLOCK 42 /* adtc R1b */ | ||
76 | |||
77 | /* class 8 */ | ||
78 | #define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */ | ||
79 | #define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */ | ||
34 | 80 | ||
35 | /* | 81 | /* |
36 | * These are the response types, and correspond to valid bit | 82 | * MMC_SWITCH argument format: |
37 | * patterns of the above flags. One additional valid pattern | 83 | * |
38 | * is all zeros, which means we don't expect a response. | 84 | * [31:26] Always 0 |
85 | * [25:24] Access Mode | ||
86 | * [23:16] Location of target Byte in EXT_CSD | ||
87 | * [15:08] Value Byte | ||
88 | * [07:03] Always 0 | ||
89 | * [02:00] Command Set | ||
39 | */ | 90 | */ |
40 | #define MMC_RSP_NONE (0) | ||
41 | #define MMC_RSP_R1 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) | ||
42 | #define MMC_RSP_R1B (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY) | ||
43 | #define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC) | ||
44 | #define MMC_RSP_R3 (MMC_RSP_PRESENT) | ||
45 | #define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) | ||
46 | #define MMC_RSP_R7 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) | ||
47 | |||
48 | #define mmc_resp_type(cmd) ((cmd)->flags & (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC|MMC_RSP_BUSY|MMC_RSP_OPCODE)) | ||
49 | 91 | ||
50 | /* | 92 | /* |
51 | * These are the command types. | 93 | MMC status in R1 |
94 | Type | ||
95 | e : error bit | ||
96 | s : status bit | ||
97 | r : detected and set for the actual command response | ||
98 | x : detected and set during command execution. the host must poll | ||
99 | the card by sending status command in order to read these bits. | ||
100 | Clear condition | ||
101 | a : according to the card state | ||
102 | b : always related to the previous command. Reception of | ||
103 | a valid command will clear it (with a delay of one command) | ||
104 | c : clear by read | ||
52 | */ | 105 | */ |
53 | #define mmc_cmd_type(cmd) ((cmd)->flags & MMC_CMD_MASK) | ||
54 | 106 | ||
55 | unsigned int retries; /* max number of retries */ | 107 | #define R1_OUT_OF_RANGE (1 << 31) /* er, c */ |
56 | unsigned int error; /* command error */ | 108 | #define R1_ADDRESS_ERROR (1 << 30) /* erx, c */ |
109 | #define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */ | ||
110 | #define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */ | ||
111 | #define R1_ERASE_PARAM (1 << 27) /* ex, c */ | ||
112 | #define R1_WP_VIOLATION (1 << 26) /* erx, c */ | ||
113 | #define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */ | ||
114 | #define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */ | ||
115 | #define R1_COM_CRC_ERROR (1 << 23) /* er, b */ | ||
116 | #define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */ | ||
117 | #define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */ | ||
118 | #define R1_CC_ERROR (1 << 20) /* erx, c */ | ||
119 | #define R1_ERROR (1 << 19) /* erx, c */ | ||
120 | #define R1_UNDERRUN (1 << 18) /* ex, c */ | ||
121 | #define R1_OVERRUN (1 << 17) /* ex, c */ | ||
122 | #define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */ | ||
123 | #define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */ | ||
124 | #define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */ | ||
125 | #define R1_ERASE_RESET (1 << 13) /* sr, c */ | ||
126 | #define R1_STATUS(x) (x & 0xFFFFE000) | ||
127 | #define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */ | ||
128 | #define R1_READY_FOR_DATA (1 << 8) /* sx, a */ | ||
129 | #define R1_APP_CMD (1 << 5) /* sr, c */ | ||
57 | 130 | ||
58 | #define MMC_ERR_NONE 0 | 131 | /* These are unpacked versions of the actual responses */ |
59 | #define MMC_ERR_TIMEOUT 1 | ||
60 | #define MMC_ERR_BADCRC 2 | ||
61 | #define MMC_ERR_FIFO 3 | ||
62 | #define MMC_ERR_FAILED 4 | ||
63 | #define MMC_ERR_INVALID 5 | ||
64 | 132 | ||
65 | struct mmc_data *data; /* data segment associated with cmd */ | 133 | struct _mmc_csd { |
66 | struct mmc_request *mrq; /* associated request */ | 134 | u8 csd_structure; |
135 | u8 spec_vers; | ||
136 | u8 taac; | ||
137 | u8 nsac; | ||
138 | u8 tran_speed; | ||
139 | u16 ccc; | ||
140 | u8 read_bl_len; | ||
141 | u8 read_bl_partial; | ||
142 | u8 write_blk_misalign; | ||
143 | u8 read_blk_misalign; | ||
144 | u8 dsr_imp; | ||
145 | u16 c_size; | ||
146 | u8 vdd_r_curr_min; | ||
147 | u8 vdd_r_curr_max; | ||
148 | u8 vdd_w_curr_min; | ||
149 | u8 vdd_w_curr_max; | ||
150 | u8 c_size_mult; | ||
151 | union { | ||
152 | struct { /* MMC system specification version 3.1 */ | ||
153 | u8 erase_grp_size; | ||
154 | u8 erase_grp_mult; | ||
155 | } v31; | ||
156 | struct { /* MMC system specification version 2.2 */ | ||
157 | u8 sector_size; | ||
158 | u8 erase_grp_size; | ||
159 | } v22; | ||
160 | } erase; | ||
161 | u8 wp_grp_size; | ||
162 | u8 wp_grp_enable; | ||
163 | u8 default_ecc; | ||
164 | u8 r2w_factor; | ||
165 | u8 write_bl_len; | ||
166 | u8 write_bl_partial; | ||
167 | u8 file_format_grp; | ||
168 | u8 copy; | ||
169 | u8 perm_write_protect; | ||
170 | u8 tmp_write_protect; | ||
171 | u8 file_format; | ||
172 | u8 ecc; | ||
67 | }; | 173 | }; |
68 | 174 | ||
69 | struct mmc_data { | 175 | /* |
70 | unsigned int timeout_ns; /* data timeout (in ns, max 80ms) */ | 176 | * OCR bits are mostly in host.h |
71 | unsigned int timeout_clks; /* data timeout (in clocks) */ | 177 | */ |
72 | unsigned int blksz; /* data block size */ | 178 | #define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */ |
73 | unsigned int blocks; /* number of blocks */ | ||
74 | unsigned int error; /* data error */ | ||
75 | unsigned int flags; | ||
76 | 179 | ||
77 | #define MMC_DATA_WRITE (1 << 8) | 180 | /* |
78 | #define MMC_DATA_READ (1 << 9) | 181 | * Card Command Classes (CCC) |
79 | #define MMC_DATA_STREAM (1 << 10) | 182 | */ |
80 | #define MMC_DATA_MULTI (1 << 11) | 183 | #define CCC_BASIC (1<<0) /* (0) Basic protocol functions */ |
184 | /* (CMD0,1,2,3,4,7,9,10,12,13,15) */ | ||
185 | #define CCC_STREAM_READ (1<<1) /* (1) Stream read commands */ | ||
186 | /* (CMD11) */ | ||
187 | #define CCC_BLOCK_READ (1<<2) /* (2) Block read commands */ | ||
188 | /* (CMD16,17,18) */ | ||
189 | #define CCC_STREAM_WRITE (1<<3) /* (3) Stream write commands */ | ||
190 | /* (CMD20) */ | ||
191 | #define CCC_BLOCK_WRITE (1<<4) /* (4) Block write commands */ | ||
192 | /* (CMD16,24,25,26,27) */ | ||
193 | #define CCC_ERASE (1<<5) /* (5) Ability to erase blocks */ | ||
194 | /* (CMD32,33,34,35,36,37,38,39) */ | ||
195 | #define CCC_WRITE_PROT (1<<6) /* (6) Able to write protect blocks */ | ||
196 | /* (CMD28,29,30) */ | ||
197 | #define CCC_LOCK_CARD (1<<7) /* (7) Able to lock down card */ | ||
198 | /* (CMD16,CMD42) */ | ||
199 | #define CCC_APP_SPEC (1<<8) /* (8) Application specific */ | ||
200 | /* (CMD55,56,57,ACMD*) */ | ||
201 | #define CCC_IO_MODE (1<<9) /* (9) I/O mode */ | ||
202 | /* (CMD5,39,40,52,53) */ | ||
203 | #define CCC_SWITCH (1<<10) /* (10) High speed switch */ | ||
204 | /* (CMD6,34,35,36,37,50) */ | ||
205 | /* (11) Reserved */ | ||
206 | /* (CMD?) */ | ||
81 | 207 | ||
82 | unsigned int bytes_xfered; | 208 | /* |
209 | * CSD field definitions | ||
210 | */ | ||
83 | 211 | ||
84 | struct mmc_command *stop; /* stop command */ | 212 | #define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */ |
85 | struct mmc_request *mrq; /* associated request */ | 213 | #define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */ |
214 | #define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 - 3.2 - 3.31 - 4.0 - 4.1 */ | ||
215 | #define CSD_STRUCT_EXT_CSD 3 /* Version is coded in CSD_STRUCTURE in EXT_CSD */ | ||
86 | 216 | ||
87 | unsigned int sg_len; /* size of scatter list */ | 217 | #define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */ |
88 | struct scatterlist *sg; /* I/O scatter list */ | 218 | #define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */ |
89 | }; | 219 | #define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */ |
220 | #define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 - 3.2 - 3.31 */ | ||
221 | #define CSD_SPEC_VER_4 4 /* Implements system specification 4.0 - 4.1 */ | ||
90 | 222 | ||
91 | struct mmc_request { | 223 | /* |
92 | struct mmc_command *cmd; | 224 | * EXT_CSD fields |
93 | struct mmc_data *data; | 225 | */ |
94 | struct mmc_command *stop; | ||
95 | 226 | ||
96 | void *done_data; /* completion data */ | 227 | #define EXT_CSD_BUS_WIDTH 183 /* R/W */ |
97 | void (*done)(struct mmc_request *);/* completion function */ | 228 | #define EXT_CSD_HS_TIMING 185 /* R/W */ |
98 | }; | 229 | #define EXT_CSD_CARD_TYPE 196 /* RO */ |
230 | #define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ | ||
231 | |||
232 | /* | ||
233 | * EXT_CSD field definitions | ||
234 | */ | ||
99 | 235 | ||
100 | struct mmc_host; | 236 | #define EXT_CSD_CMD_SET_NORMAL (1<<0) |
101 | struct mmc_card; | 237 | #define EXT_CSD_CMD_SET_SECURE (1<<1) |
238 | #define EXT_CSD_CMD_SET_CPSECURE (1<<2) | ||
102 | 239 | ||
103 | extern int mmc_wait_for_req(struct mmc_host *, struct mmc_request *); | 240 | #define EXT_CSD_CARD_TYPE_26 (1<<0) /* Card can run at 26MHz */ |
104 | extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int); | 241 | #define EXT_CSD_CARD_TYPE_52 (1<<1) /* Card can run at 52MHz */ |
105 | extern int mmc_wait_for_app_cmd(struct mmc_host *, unsigned int, | ||
106 | struct mmc_command *, int); | ||
107 | 242 | ||
108 | extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *, int); | 243 | #define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */ |
244 | #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ | ||
245 | #define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */ | ||
109 | 246 | ||
110 | extern int __mmc_claim_host(struct mmc_host *host, struct mmc_card *card); | 247 | /* |
248 | * MMC_SWITCH access modes | ||
249 | */ | ||
111 | 250 | ||
112 | static inline void mmc_claim_host(struct mmc_host *host) | 251 | #define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */ |
113 | { | 252 | #define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits which are 1 in value */ |
114 | __mmc_claim_host(host, (struct mmc_card *)-1); | 253 | #define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */ |
115 | } | 254 | #define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */ |
116 | 255 | ||
117 | extern void mmc_release_host(struct mmc_host *host); | 256 | #endif /* MMC_MMC_PROTOCOL_H */ |
118 | 257 | ||
119 | #endif | ||
diff --git a/include/linux/mmc/protocol.h b/include/linux/mmc/protocol.h deleted file mode 100644 index c90b6768329d..000000000000 --- a/include/linux/mmc/protocol.h +++ /dev/null | |||
@@ -1,327 +0,0 @@ | |||
1 | /* | ||
2 | * Header for MultiMediaCard (MMC) | ||
3 | * | ||
4 | * Copyright 2002 Hewlett-Packard Company | ||
5 | * | ||
6 | * Use consistent with the GNU GPL is permitted, | ||
7 | * provided that this copyright notice is | ||
8 | * preserved in its entirety in all copies and derived works. | ||
9 | * | ||
10 | * HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED, | ||
11 | * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS | ||
12 | * FITNESS FOR ANY PARTICULAR PURPOSE. | ||
13 | * | ||
14 | * Many thanks to Alessandro Rubini and Jonathan Corbet! | ||
15 | * | ||
16 | * Based strongly on code by: | ||
17 | * | ||
18 | * Author: Yong-iL Joh <tolkien@mizi.com> | ||
19 | * Date : $Date: 2002/06/18 12:37:30 $ | ||
20 | * | ||
21 | * Author: Andrew Christian | ||
22 | * 15 May 2002 | ||
23 | */ | ||
24 | |||
25 | #ifndef MMC_MMC_PROTOCOL_H | ||
26 | #define MMC_MMC_PROTOCOL_H | ||
27 | |||
28 | /* Standard MMC commands (4.1) type argument response */ | ||
29 | /* class 1 */ | ||
30 | #define MMC_GO_IDLE_STATE 0 /* bc */ | ||
31 | #define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */ | ||
32 | #define MMC_ALL_SEND_CID 2 /* bcr R2 */ | ||
33 | #define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */ | ||
34 | #define MMC_SET_DSR 4 /* bc [31:16] RCA */ | ||
35 | #define MMC_SWITCH 6 /* ac [31:0] See below R1b */ | ||
36 | #define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */ | ||
37 | #define MMC_SEND_EXT_CSD 8 /* adtc R1 */ | ||
38 | #define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */ | ||
39 | #define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */ | ||
40 | #define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */ | ||
41 | #define MMC_STOP_TRANSMISSION 12 /* ac R1b */ | ||
42 | #define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */ | ||
43 | #define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */ | ||
44 | |||
45 | /* class 2 */ | ||
46 | #define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */ | ||
47 | #define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */ | ||
48 | #define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */ | ||
49 | |||
50 | /* class 3 */ | ||
51 | #define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */ | ||
52 | |||
53 | /* class 4 */ | ||
54 | #define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */ | ||
55 | #define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */ | ||
56 | #define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */ | ||
57 | #define MMC_PROGRAM_CID 26 /* adtc R1 */ | ||
58 | #define MMC_PROGRAM_CSD 27 /* adtc R1 */ | ||
59 | |||
60 | /* class 6 */ | ||
61 | #define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */ | ||
62 | #define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */ | ||
63 | #define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */ | ||
64 | |||
65 | /* class 5 */ | ||
66 | #define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */ | ||
67 | #define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */ | ||
68 | #define MMC_ERASE 38 /* ac R1b */ | ||
69 | |||
70 | /* class 9 */ | ||
71 | #define MMC_FAST_IO 39 /* ac <Complex> R4 */ | ||
72 | #define MMC_GO_IRQ_STATE 40 /* bcr R5 */ | ||
73 | |||
74 | /* class 7 */ | ||
75 | #define MMC_LOCK_UNLOCK 42 /* adtc R1b */ | ||
76 | |||
77 | /* class 8 */ | ||
78 | #define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */ | ||
79 | #define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */ | ||
80 | |||
81 | /* SD commands type argument response */ | ||
82 | /* class 0 */ | ||
83 | /* This is basically the same command as for MMC with some quirks. */ | ||
84 | #define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */ | ||
85 | #define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */ | ||
86 | |||
87 | /* class 10 */ | ||
88 | #define SD_SWITCH 6 /* adtc [31:0] See below R1 */ | ||
89 | |||
90 | /* Application commands */ | ||
91 | #define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */ | ||
92 | #define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */ | ||
93 | #define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */ | ||
94 | #define SD_APP_SEND_SCR 51 /* adtc R1 */ | ||
95 | |||
96 | /* | ||
97 | * MMC_SWITCH argument format: | ||
98 | * | ||
99 | * [31:26] Always 0 | ||
100 | * [25:24] Access Mode | ||
101 | * [23:16] Location of target Byte in EXT_CSD | ||
102 | * [15:08] Value Byte | ||
103 | * [07:03] Always 0 | ||
104 | * [02:00] Command Set | ||
105 | */ | ||
106 | |||
107 | /* | ||
108 | * SD_SWITCH argument format: | ||
109 | * | ||
110 | * [31] Check (0) or switch (1) | ||
111 | * [30:24] Reserved (0) | ||
112 | * [23:20] Function group 6 | ||
113 | * [19:16] Function group 5 | ||
114 | * [15:12] Function group 4 | ||
115 | * [11:8] Function group 3 | ||
116 | * [7:4] Function group 2 | ||
117 | * [3:0] Function group 1 | ||
118 | */ | ||
119 | |||
120 | /* | ||
121 | * SD_SEND_IF_COND argument format: | ||
122 | * | ||
123 | * [31:12] Reserved (0) | ||
124 | * [11:8] Host Voltage Supply Flags | ||
125 | * [7:0] Check Pattern (0xAA) | ||
126 | */ | ||
127 | |||
128 | /* | ||
129 | MMC status in R1 | ||
130 | Type | ||
131 | e : error bit | ||
132 | s : status bit | ||
133 | r : detected and set for the actual command response | ||
134 | x : detected and set during command execution. the host must poll | ||
135 | the card by sending status command in order to read these bits. | ||
136 | Clear condition | ||
137 | a : according to the card state | ||
138 | b : always related to the previous command. Reception of | ||
139 | a valid command will clear it (with a delay of one command) | ||
140 | c : clear by read | ||
141 | */ | ||
142 | |||
143 | #define R1_OUT_OF_RANGE (1 << 31) /* er, c */ | ||
144 | #define R1_ADDRESS_ERROR (1 << 30) /* erx, c */ | ||
145 | #define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */ | ||
146 | #define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */ | ||
147 | #define R1_ERASE_PARAM (1 << 27) /* ex, c */ | ||
148 | #define R1_WP_VIOLATION (1 << 26) /* erx, c */ | ||
149 | #define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */ | ||
150 | #define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */ | ||
151 | #define R1_COM_CRC_ERROR (1 << 23) /* er, b */ | ||
152 | #define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */ | ||
153 | #define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */ | ||
154 | #define R1_CC_ERROR (1 << 20) /* erx, c */ | ||
155 | #define R1_ERROR (1 << 19) /* erx, c */ | ||
156 | #define R1_UNDERRUN (1 << 18) /* ex, c */ | ||
157 | #define R1_OVERRUN (1 << 17) /* ex, c */ | ||
158 | #define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */ | ||
159 | #define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */ | ||
160 | #define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */ | ||
161 | #define R1_ERASE_RESET (1 << 13) /* sr, c */ | ||
162 | #define R1_STATUS(x) (x & 0xFFFFE000) | ||
163 | #define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */ | ||
164 | #define R1_READY_FOR_DATA (1 << 8) /* sx, a */ | ||
165 | #define R1_APP_CMD (1 << 5) /* sr, c */ | ||
166 | |||
167 | /* These are unpacked versions of the actual responses */ | ||
168 | |||
169 | struct _mmc_csd { | ||
170 | u8 csd_structure; | ||
171 | u8 spec_vers; | ||
172 | u8 taac; | ||
173 | u8 nsac; | ||
174 | u8 tran_speed; | ||
175 | u16 ccc; | ||
176 | u8 read_bl_len; | ||
177 | u8 read_bl_partial; | ||
178 | u8 write_blk_misalign; | ||
179 | u8 read_blk_misalign; | ||
180 | u8 dsr_imp; | ||
181 | u16 c_size; | ||
182 | u8 vdd_r_curr_min; | ||
183 | u8 vdd_r_curr_max; | ||
184 | u8 vdd_w_curr_min; | ||
185 | u8 vdd_w_curr_max; | ||
186 | u8 c_size_mult; | ||
187 | union { | ||
188 | struct { /* MMC system specification version 3.1 */ | ||
189 | u8 erase_grp_size; | ||
190 | u8 erase_grp_mult; | ||
191 | } v31; | ||
192 | struct { /* MMC system specification version 2.2 */ | ||
193 | u8 sector_size; | ||
194 | u8 erase_grp_size; | ||
195 | } v22; | ||
196 | } erase; | ||
197 | u8 wp_grp_size; | ||
198 | u8 wp_grp_enable; | ||
199 | u8 default_ecc; | ||
200 | u8 r2w_factor; | ||
201 | u8 write_bl_len; | ||
202 | u8 write_bl_partial; | ||
203 | u8 file_format_grp; | ||
204 | u8 copy; | ||
205 | u8 perm_write_protect; | ||
206 | u8 tmp_write_protect; | ||
207 | u8 file_format; | ||
208 | u8 ecc; | ||
209 | }; | ||
210 | |||
211 | #define MMC_VDD_145_150 0x00000001 /* VDD voltage 1.45 - 1.50 */ | ||
212 | #define MMC_VDD_150_155 0x00000002 /* VDD voltage 1.50 - 1.55 */ | ||
213 | #define MMC_VDD_155_160 0x00000004 /* VDD voltage 1.55 - 1.60 */ | ||
214 | #define MMC_VDD_160_165 0x00000008 /* VDD voltage 1.60 - 1.65 */ | ||
215 | #define MMC_VDD_165_170 0x00000010 /* VDD voltage 1.65 - 1.70 */ | ||
216 | #define MMC_VDD_17_18 0x00000020 /* VDD voltage 1.7 - 1.8 */ | ||
217 | #define MMC_VDD_18_19 0x00000040 /* VDD voltage 1.8 - 1.9 */ | ||
218 | #define MMC_VDD_19_20 0x00000080 /* VDD voltage 1.9 - 2.0 */ | ||
219 | #define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */ | ||
220 | #define MMC_VDD_21_22 0x00000200 /* VDD voltage 2.1 ~ 2.2 */ | ||
221 | #define MMC_VDD_22_23 0x00000400 /* VDD voltage 2.2 ~ 2.3 */ | ||
222 | #define MMC_VDD_23_24 0x00000800 /* VDD voltage 2.3 ~ 2.4 */ | ||
223 | #define MMC_VDD_24_25 0x00001000 /* VDD voltage 2.4 ~ 2.5 */ | ||
224 | #define MMC_VDD_25_26 0x00002000 /* VDD voltage 2.5 ~ 2.6 */ | ||
225 | #define MMC_VDD_26_27 0x00004000 /* VDD voltage 2.6 ~ 2.7 */ | ||
226 | #define MMC_VDD_27_28 0x00008000 /* VDD voltage 2.7 ~ 2.8 */ | ||
227 | #define MMC_VDD_28_29 0x00010000 /* VDD voltage 2.8 ~ 2.9 */ | ||
228 | #define MMC_VDD_29_30 0x00020000 /* VDD voltage 2.9 ~ 3.0 */ | ||
229 | #define MMC_VDD_30_31 0x00040000 /* VDD voltage 3.0 ~ 3.1 */ | ||
230 | #define MMC_VDD_31_32 0x00080000 /* VDD voltage 3.1 ~ 3.2 */ | ||
231 | #define MMC_VDD_32_33 0x00100000 /* VDD voltage 3.2 ~ 3.3 */ | ||
232 | #define MMC_VDD_33_34 0x00200000 /* VDD voltage 3.3 ~ 3.4 */ | ||
233 | #define MMC_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */ | ||
234 | #define MMC_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */ | ||
235 | #define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */ | ||
236 | |||
237 | /* | ||
238 | * Card Command Classes (CCC) | ||
239 | */ | ||
240 | #define CCC_BASIC (1<<0) /* (0) Basic protocol functions */ | ||
241 | /* (CMD0,1,2,3,4,7,9,10,12,13,15) */ | ||
242 | #define CCC_STREAM_READ (1<<1) /* (1) Stream read commands */ | ||
243 | /* (CMD11) */ | ||
244 | #define CCC_BLOCK_READ (1<<2) /* (2) Block read commands */ | ||
245 | /* (CMD16,17,18) */ | ||
246 | #define CCC_STREAM_WRITE (1<<3) /* (3) Stream write commands */ | ||
247 | /* (CMD20) */ | ||
248 | #define CCC_BLOCK_WRITE (1<<4) /* (4) Block write commands */ | ||
249 | /* (CMD16,24,25,26,27) */ | ||
250 | #define CCC_ERASE (1<<5) /* (5) Ability to erase blocks */ | ||
251 | /* (CMD32,33,34,35,36,37,38,39) */ | ||
252 | #define CCC_WRITE_PROT (1<<6) /* (6) Able to write protect blocks */ | ||
253 | /* (CMD28,29,30) */ | ||
254 | #define CCC_LOCK_CARD (1<<7) /* (7) Able to lock down card */ | ||
255 | /* (CMD16,CMD42) */ | ||
256 | #define CCC_APP_SPEC (1<<8) /* (8) Application specific */ | ||
257 | /* (CMD55,56,57,ACMD*) */ | ||
258 | #define CCC_IO_MODE (1<<9) /* (9) I/O mode */ | ||
259 | /* (CMD5,39,40,52,53) */ | ||
260 | #define CCC_SWITCH (1<<10) /* (10) High speed switch */ | ||
261 | /* (CMD6,34,35,36,37,50) */ | ||
262 | /* (11) Reserved */ | ||
263 | /* (CMD?) */ | ||
264 | |||
265 | /* | ||
266 | * CSD field definitions | ||
267 | */ | ||
268 | |||
269 | #define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */ | ||
270 | #define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */ | ||
271 | #define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 - 3.2 - 3.31 - 4.0 - 4.1 */ | ||
272 | #define CSD_STRUCT_EXT_CSD 3 /* Version is coded in CSD_STRUCTURE in EXT_CSD */ | ||
273 | |||
274 | #define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */ | ||
275 | #define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */ | ||
276 | #define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */ | ||
277 | #define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 - 3.2 - 3.31 */ | ||
278 | #define CSD_SPEC_VER_4 4 /* Implements system specification 4.0 - 4.1 */ | ||
279 | |||
280 | /* | ||
281 | * EXT_CSD fields | ||
282 | */ | ||
283 | |||
284 | #define EXT_CSD_BUS_WIDTH 183 /* R/W */ | ||
285 | #define EXT_CSD_HS_TIMING 185 /* R/W */ | ||
286 | #define EXT_CSD_CARD_TYPE 196 /* RO */ | ||
287 | |||
288 | /* | ||
289 | * EXT_CSD field definitions | ||
290 | */ | ||
291 | |||
292 | #define EXT_CSD_CMD_SET_NORMAL (1<<0) | ||
293 | #define EXT_CSD_CMD_SET_SECURE (1<<1) | ||
294 | #define EXT_CSD_CMD_SET_CPSECURE (1<<2) | ||
295 | |||
296 | #define EXT_CSD_CARD_TYPE_26 (1<<0) /* Card can run at 26MHz */ | ||
297 | #define EXT_CSD_CARD_TYPE_52 (1<<1) /* Card can run at 52MHz */ | ||
298 | |||
299 | #define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */ | ||
300 | #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ | ||
301 | #define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */ | ||
302 | |||
303 | /* | ||
304 | * MMC_SWITCH access modes | ||
305 | */ | ||
306 | |||
307 | #define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */ | ||
308 | #define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits which are 1 in value */ | ||
309 | #define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */ | ||
310 | #define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */ | ||
311 | |||
312 | /* | ||
313 | * SCR field definitions | ||
314 | */ | ||
315 | |||
316 | #define SCR_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.01 */ | ||
317 | #define SCR_SPEC_VER_1 1 /* Implements system specification 1.10 */ | ||
318 | #define SCR_SPEC_VER_2 2 /* Implements system specification 2.00 */ | ||
319 | |||
320 | /* | ||
321 | * SD bus widths | ||
322 | */ | ||
323 | #define SD_BUS_WIDTH_1 0 | ||
324 | #define SD_BUS_WIDTH_4 2 | ||
325 | |||
326 | #endif /* MMC_MMC_PROTOCOL_H */ | ||
327 | |||
diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h new file mode 100644 index 000000000000..f310062cffb4 --- /dev/null +++ b/include/linux/mmc/sd.h | |||
@@ -0,0 +1,83 @@ | |||
1 | /* | ||
2 | * include/linux/mmc/sd.h | ||
3 | * | ||
4 | * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or (at | ||
9 | * your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #ifndef MMC_SD_H | ||
13 | #define MMC_SD_H | ||
14 | |||
15 | /* SD commands type argument response */ | ||
16 | /* class 0 */ | ||
17 | /* This is basically the same command as for MMC with some quirks. */ | ||
18 | #define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */ | ||
19 | #define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */ | ||
20 | |||
21 | /* class 10 */ | ||
22 | #define SD_SWITCH 6 /* adtc [31:0] See below R1 */ | ||
23 | |||
24 | /* Application commands */ | ||
25 | #define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */ | ||
26 | #define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */ | ||
27 | #define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */ | ||
28 | #define SD_APP_SEND_SCR 51 /* adtc R1 */ | ||
29 | |||
30 | /* | ||
31 | * SD_SWITCH argument format: | ||
32 | * | ||
33 | * [31] Check (0) or switch (1) | ||
34 | * [30:24] Reserved (0) | ||
35 | * [23:20] Function group 6 | ||
36 | * [19:16] Function group 5 | ||
37 | * [15:12] Function group 4 | ||
38 | * [11:8] Function group 3 | ||
39 | * [7:4] Function group 2 | ||
40 | * [3:0] Function group 1 | ||
41 | */ | ||
42 | |||
43 | /* | ||
44 | * SD_SEND_IF_COND argument format: | ||
45 | * | ||
46 | * [31:12] Reserved (0) | ||
47 | * [11:8] Host Voltage Supply Flags | ||
48 | * [7:0] Check Pattern (0xAA) | ||
49 | */ | ||
50 | |||
51 | /* | ||
52 | * SCR field definitions | ||
53 | */ | ||
54 | |||
55 | #define SCR_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.01 */ | ||
56 | #define SCR_SPEC_VER_1 1 /* Implements system specification 1.10 */ | ||
57 | #define SCR_SPEC_VER_2 2 /* Implements system specification 2.00 */ | ||
58 | |||
59 | /* | ||
60 | * SD bus widths | ||
61 | */ | ||
62 | #define SD_BUS_WIDTH_1 0 | ||
63 | #define SD_BUS_WIDTH_4 2 | ||
64 | |||
65 | /* | ||
66 | * SD_SWITCH mode | ||
67 | */ | ||
68 | #define SD_SWITCH_CHECK 0 | ||
69 | #define SD_SWITCH_SET 1 | ||
70 | |||
71 | /* | ||
72 | * SD_SWITCH function groups | ||
73 | */ | ||
74 | #define SD_SWITCH_GRP_ACCESS 0 | ||
75 | |||
76 | /* | ||
77 | * SD_SWITCH access modes | ||
78 | */ | ||
79 | #define SD_SWITCH_ACCESS_DEF 0 | ||
80 | #define SD_SWITCH_ACCESS_HS 1 | ||
81 | |||
82 | #endif | ||
83 | |||
diff --git a/include/linux/tifm.h b/include/linux/tifm.h index 3deb0a6c1370..2a196982601f 100644 --- a/include/linux/tifm.h +++ b/include/linux/tifm.h | |||
@@ -14,16 +14,16 @@ | |||
14 | 14 | ||
15 | #include <linux/spinlock.h> | 15 | #include <linux/spinlock.h> |
16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
17 | #include <linux/wait.h> | ||
18 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
19 | #include <linux/pci.h> | 18 | #include <linux/pci.h> |
20 | #include <linux/kthread.h> | 19 | #include <linux/workqueue.h> |
21 | 20 | ||
22 | /* Host registers (relative to pci base address): */ | 21 | /* Host registers (relative to pci base address): */ |
23 | enum { | 22 | enum { |
24 | FM_SET_INTERRUPT_ENABLE = 0x008, | 23 | FM_SET_INTERRUPT_ENABLE = 0x008, |
25 | FM_CLEAR_INTERRUPT_ENABLE = 0x00c, | 24 | FM_CLEAR_INTERRUPT_ENABLE = 0x00c, |
26 | FM_INTERRUPT_STATUS = 0x014 }; | 25 | FM_INTERRUPT_STATUS = 0x014 |
26 | }; | ||
27 | 27 | ||
28 | /* Socket registers (relative to socket base address): */ | 28 | /* Socket registers (relative to socket base address): */ |
29 | enum { | 29 | enum { |
@@ -58,14 +58,8 @@ enum { | |||
58 | SOCK_MS_DATA = 0x188, | 58 | SOCK_MS_DATA = 0x188, |
59 | SOCK_MS_STATUS = 0x18c, | 59 | SOCK_MS_STATUS = 0x18c, |
60 | SOCK_MS_SYSTEM = 0x190, | 60 | SOCK_MS_SYSTEM = 0x190, |
61 | SOCK_FIFO_ACCESS = 0x200 }; | 61 | SOCK_FIFO_ACCESS = 0x200 |
62 | 62 | }; | |
63 | |||
64 | #define TIFM_IRQ_ENABLE 0x80000000 | ||
65 | #define TIFM_IRQ_SOCKMASK(x) (x) | ||
66 | #define TIFM_IRQ_CARDMASK(x) ((x) << 8) | ||
67 | #define TIFM_IRQ_FIFOMASK(x) ((x) << 16) | ||
68 | #define TIFM_IRQ_SETALL 0xffffffff | ||
69 | 63 | ||
70 | #define TIFM_CTRL_LED 0x00000040 | 64 | #define TIFM_CTRL_LED 0x00000040 |
71 | #define TIFM_CTRL_FAST_CLK 0x00000100 | 65 | #define TIFM_CTRL_FAST_CLK 0x00000100 |
@@ -73,63 +67,76 @@ enum { | |||
73 | #define TIFM_SOCK_STATE_OCCUPIED 0x00000008 | 67 | #define TIFM_SOCK_STATE_OCCUPIED 0x00000008 |
74 | #define TIFM_SOCK_STATE_POWERED 0x00000080 | 68 | #define TIFM_SOCK_STATE_POWERED 0x00000080 |
75 | 69 | ||
76 | #define TIFM_FIFO_ENABLE 0x00000001 /* Meaning of this constant is unverified */ | 70 | #define TIFM_FIFO_ENABLE 0x00000001 |
71 | #define TIFM_FIFO_READY 0x00000001 | ||
77 | #define TIFM_FIFO_INT_SETALL 0x0000ffff | 72 | #define TIFM_FIFO_INT_SETALL 0x0000ffff |
78 | #define TIFM_FIFO_INTMASK 0x00000005 /* Meaning of this constant is unverified */ | 73 | #define TIFM_FIFO_INTMASK 0x00000005 |
74 | |||
75 | #define TIFM_DMA_RESET 0x00000002 | ||
76 | #define TIFM_DMA_TX 0x00008000 | ||
77 | #define TIFM_DMA_EN 0x00000001 | ||
78 | #define TIFM_DMA_TSIZE 0x0000007f | ||
79 | 79 | ||
80 | #define TIFM_DMA_RESET 0x00000002 /* Meaning of this constant is unverified */ | 80 | #define TIFM_TYPE_XD 1 |
81 | #define TIFM_DMA_TX 0x00008000 /* Meaning of this constant is unverified */ | 81 | #define TIFM_TYPE_MS 2 |
82 | #define TIFM_DMA_EN 0x00000001 /* Meaning of this constant is unverified */ | 82 | #define TIFM_TYPE_SD 3 |
83 | 83 | ||
84 | typedef enum {FM_NULL = 0, FM_XD = 0x01, FM_MS = 0x02, FM_SD = 0x03} tifm_media_id; | 84 | struct tifm_device_id { |
85 | unsigned char type; | ||
86 | }; | ||
85 | 87 | ||
86 | struct tifm_driver; | 88 | struct tifm_driver; |
87 | struct tifm_dev { | 89 | struct tifm_dev { |
88 | char __iomem *addr; | 90 | char __iomem *addr; |
89 | spinlock_t lock; | 91 | spinlock_t lock; |
90 | tifm_media_id media_id; | 92 | unsigned char type; |
91 | unsigned int socket_id; | 93 | unsigned int socket_id; |
92 | 94 | ||
93 | void (*signal_irq)(struct tifm_dev *sock, | 95 | void (*card_event)(struct tifm_dev *sock); |
94 | unsigned int sock_irq_status); | 96 | void (*data_event)(struct tifm_dev *sock); |
95 | 97 | ||
96 | struct tifm_driver *drv; | 98 | struct device dev; |
97 | struct device dev; | ||
98 | }; | 99 | }; |
99 | 100 | ||
100 | struct tifm_driver { | 101 | struct tifm_driver { |
101 | tifm_media_id *id_table; | 102 | struct tifm_device_id *id_table; |
102 | int (*probe)(struct tifm_dev *dev); | 103 | int (*probe)(struct tifm_dev *dev); |
103 | void (*remove)(struct tifm_dev *dev); | 104 | void (*remove)(struct tifm_dev *dev); |
104 | int (*suspend)(struct tifm_dev *dev, | 105 | int (*suspend)(struct tifm_dev *dev, |
105 | pm_message_t state); | 106 | pm_message_t state); |
106 | int (*resume)(struct tifm_dev *dev); | 107 | int (*resume)(struct tifm_dev *dev); |
107 | 108 | ||
108 | struct device_driver driver; | 109 | struct device_driver driver; |
109 | }; | 110 | }; |
110 | 111 | ||
111 | struct tifm_adapter { | 112 | struct tifm_adapter { |
112 | char __iomem *addr; | 113 | char __iomem *addr; |
113 | spinlock_t lock; | 114 | spinlock_t lock; |
114 | unsigned int irq_status; | 115 | unsigned int irq_status; |
115 | unsigned int socket_change_set; | 116 | unsigned int socket_change_set; |
116 | wait_queue_head_t change_set_notify; | 117 | unsigned int id; |
117 | unsigned int id; | 118 | unsigned int num_sockets; |
118 | unsigned int num_sockets; | 119 | struct completion *finish_me; |
119 | struct tifm_dev **sockets; | 120 | |
120 | struct task_struct *media_switcher; | 121 | struct work_struct media_switcher; |
121 | struct class_device cdev; | 122 | struct class_device cdev; |
122 | struct device *dev; | 123 | |
123 | 124 | void (*eject)(struct tifm_adapter *fm, | |
124 | void (*eject)(struct tifm_adapter *fm, struct tifm_dev *sock); | 125 | struct tifm_dev *sock); |
126 | |||
127 | struct tifm_dev *sockets[0]; | ||
125 | }; | 128 | }; |
126 | 129 | ||
127 | struct tifm_adapter *tifm_alloc_adapter(void); | 130 | struct tifm_adapter *tifm_alloc_adapter(unsigned int num_sockets, |
128 | void tifm_free_device(struct device *dev); | 131 | struct device *dev); |
129 | void tifm_free_adapter(struct tifm_adapter *fm); | 132 | int tifm_add_adapter(struct tifm_adapter *fm); |
130 | int tifm_add_adapter(struct tifm_adapter *fm, int (*mediathreadfn)(void *data)); | ||
131 | void tifm_remove_adapter(struct tifm_adapter *fm); | 133 | void tifm_remove_adapter(struct tifm_adapter *fm); |
132 | struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm); | 134 | void tifm_free_adapter(struct tifm_adapter *fm); |
135 | |||
136 | void tifm_free_device(struct device *dev); | ||
137 | struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id, | ||
138 | unsigned char type); | ||
139 | |||
133 | int tifm_register_driver(struct tifm_driver *drv); | 140 | int tifm_register_driver(struct tifm_driver *drv); |
134 | void tifm_unregister_driver(struct tifm_driver *drv); | 141 | void tifm_unregister_driver(struct tifm_driver *drv); |
135 | void tifm_eject(struct tifm_dev *sock); | 142 | void tifm_eject(struct tifm_dev *sock); |
@@ -137,11 +144,11 @@ int tifm_map_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents, | |||
137 | int direction); | 144 | int direction); |
138 | void tifm_unmap_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents, | 145 | void tifm_unmap_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents, |
139 | int direction); | 146 | int direction); |
140 | 147 | void tifm_queue_work(struct work_struct *work); | |
141 | 148 | ||
142 | static inline void *tifm_get_drvdata(struct tifm_dev *dev) | 149 | static inline void *tifm_get_drvdata(struct tifm_dev *dev) |
143 | { | 150 | { |
144 | return dev_get_drvdata(&dev->dev); | 151 | return dev_get_drvdata(&dev->dev); |
145 | } | 152 | } |
146 | 153 | ||
147 | static inline void tifm_set_drvdata(struct tifm_dev *dev, void *data) | 154 | static inline void tifm_set_drvdata(struct tifm_dev *dev, void *data) |
@@ -149,8 +156,4 @@ static inline void tifm_set_drvdata(struct tifm_dev *dev, void *data) | |||
149 | dev_set_drvdata(&dev->dev, data); | 156 | dev_set_drvdata(&dev->dev, data); |
150 | } | 157 | } |
151 | 158 | ||
152 | struct tifm_device_id { | ||
153 | tifm_media_id media_id; | ||
154 | }; | ||
155 | |||
156 | #endif | 159 | #endif |