diff options
Diffstat (limited to 'drivers/mmc/host/rtsx_pci_sdmmc.c')
-rw-r--r-- | drivers/mmc/host/rtsx_pci_sdmmc.c | 542 |
1 files changed, 303 insertions, 239 deletions
diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c index c70b602f8f1e..1d3d6c4bfdc6 100644 --- a/drivers/mmc/host/rtsx_pci_sdmmc.c +++ b/drivers/mmc/host/rtsx_pci_sdmmc.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/mmc/host.h> | 28 | #include <linux/mmc/host.h> |
29 | #include <linux/mmc/mmc.h> | 29 | #include <linux/mmc/mmc.h> |
30 | #include <linux/mmc/sd.h> | 30 | #include <linux/mmc/sd.h> |
31 | #include <linux/mmc/sdio.h> | ||
31 | #include <linux/mmc/card.h> | 32 | #include <linux/mmc/card.h> |
32 | #include <linux/mfd/rtsx_pci.h> | 33 | #include <linux/mfd/rtsx_pci.h> |
33 | #include <asm/unaligned.h> | 34 | #include <asm/unaligned.h> |
@@ -53,9 +54,9 @@ struct realtek_pci_sdmmc { | |||
53 | #define SDMMC_POWER_ON 1 | 54 | #define SDMMC_POWER_ON 1 |
54 | #define SDMMC_POWER_OFF 0 | 55 | #define SDMMC_POWER_OFF 0 |
55 | 56 | ||
56 | unsigned int sg_count; | 57 | int sg_count; |
57 | s32 cookie; | 58 | s32 cookie; |
58 | unsigned int cookie_sg_count; | 59 | int cookie_sg_count; |
59 | bool using_cookie; | 60 | bool using_cookie; |
60 | }; | 61 | }; |
61 | 62 | ||
@@ -71,30 +72,83 @@ static inline void sd_clear_error(struct realtek_pci_sdmmc *host) | |||
71 | } | 72 | } |
72 | 73 | ||
73 | #ifdef DEBUG | 74 | #ifdef DEBUG |
74 | static void sd_print_debug_regs(struct realtek_pci_sdmmc *host) | 75 | static void dump_reg_range(struct realtek_pci_sdmmc *host, u16 start, u16 end) |
75 | { | 76 | { |
76 | struct rtsx_pcr *pcr = host->pcr; | 77 | u16 len = end - start + 1; |
77 | u16 i; | 78 | int i; |
78 | u8 *ptr; | 79 | u8 data[8]; |
80 | |||
81 | for (i = 0; i < len; i += 8) { | ||
82 | int j; | ||
83 | int n = min(8, len - i); | ||
84 | |||
85 | memset(&data, 0, sizeof(data)); | ||
86 | for (j = 0; j < n; j++) | ||
87 | rtsx_pci_read_register(host->pcr, start + i + j, | ||
88 | data + j); | ||
89 | dev_dbg(sdmmc_dev(host), "0x%04X(%d): %8ph\n", | ||
90 | start + i, n, data); | ||
91 | } | ||
92 | } | ||
79 | 93 | ||
80 | /* Print SD host internal registers */ | 94 | static void sd_print_debug_regs(struct realtek_pci_sdmmc *host) |
81 | rtsx_pci_init_cmd(pcr); | 95 | { |
82 | for (i = 0xFDA0; i <= 0xFDAE; i++) | 96 | dump_reg_range(host, 0xFDA0, 0xFDB3); |
83 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0); | 97 | dump_reg_range(host, 0xFD52, 0xFD69); |
84 | for (i = 0xFD52; i <= 0xFD69; i++) | ||
85 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0); | ||
86 | rtsx_pci_send_cmd(pcr, 100); | ||
87 | |||
88 | ptr = rtsx_pci_get_cmd_data(pcr); | ||
89 | for (i = 0xFDA0; i <= 0xFDAE; i++) | ||
90 | dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++)); | ||
91 | for (i = 0xFD52; i <= 0xFD69; i++) | ||
92 | dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++)); | ||
93 | } | 98 | } |
94 | #else | 99 | #else |
95 | #define sd_print_debug_regs(host) | 100 | #define sd_print_debug_regs(host) |
96 | #endif /* DEBUG */ | 101 | #endif /* DEBUG */ |
97 | 102 | ||
103 | static inline int sd_get_cd_int(struct realtek_pci_sdmmc *host) | ||
104 | { | ||
105 | return rtsx_pci_readl(host->pcr, RTSX_BIPR) & SD_EXIST; | ||
106 | } | ||
107 | |||
108 | static void sd_cmd_set_sd_cmd(struct rtsx_pcr *pcr, struct mmc_command *cmd) | ||
109 | { | ||
110 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0, 0xFF, | ||
111 | SD_CMD_START | cmd->opcode); | ||
112 | rtsx_pci_write_be32(pcr, SD_CMD1, cmd->arg); | ||
113 | } | ||
114 | |||
115 | static void sd_cmd_set_data_len(struct rtsx_pcr *pcr, u16 blocks, u16 blksz) | ||
116 | { | ||
117 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, blocks); | ||
118 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, blocks >> 8); | ||
119 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, blksz); | ||
120 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, blksz >> 8); | ||
121 | } | ||
122 | |||
123 | static int sd_response_type(struct mmc_command *cmd) | ||
124 | { | ||
125 | switch (mmc_resp_type(cmd)) { | ||
126 | case MMC_RSP_NONE: | ||
127 | return SD_RSP_TYPE_R0; | ||
128 | case MMC_RSP_R1: | ||
129 | return SD_RSP_TYPE_R1; | ||
130 | case MMC_RSP_R1 & ~MMC_RSP_CRC: | ||
131 | return SD_RSP_TYPE_R1 | SD_NO_CHECK_CRC7; | ||
132 | case MMC_RSP_R1B: | ||
133 | return SD_RSP_TYPE_R1b; | ||
134 | case MMC_RSP_R2: | ||
135 | return SD_RSP_TYPE_R2; | ||
136 | case MMC_RSP_R3: | ||
137 | return SD_RSP_TYPE_R3; | ||
138 | default: | ||
139 | return -EINVAL; | ||
140 | } | ||
141 | } | ||
142 | |||
143 | static int sd_status_index(int resp_type) | ||
144 | { | ||
145 | if (resp_type == SD_RSP_TYPE_R0) | ||
146 | return 0; | ||
147 | else if (resp_type == SD_RSP_TYPE_R2) | ||
148 | return 16; | ||
149 | |||
150 | return 5; | ||
151 | } | ||
98 | /* | 152 | /* |
99 | * sd_pre_dma_transfer - do dma_map_sg() or using cookie | 153 | * sd_pre_dma_transfer - do dma_map_sg() or using cookie |
100 | * | 154 | * |
@@ -166,123 +220,6 @@ static void sdmmc_post_req(struct mmc_host *mmc, struct mmc_request *mrq, | |||
166 | data->host_cookie = 0; | 220 | data->host_cookie = 0; |
167 | } | 221 | } |
168 | 222 | ||
169 | static int sd_read_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt, | ||
170 | u8 *buf, int buf_len, int timeout) | ||
171 | { | ||
172 | struct rtsx_pcr *pcr = host->pcr; | ||
173 | int err, i; | ||
174 | u8 trans_mode; | ||
175 | |||
176 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD%d\n", __func__, cmd[0] - 0x40); | ||
177 | |||
178 | if (!buf) | ||
179 | buf_len = 0; | ||
180 | |||
181 | if ((cmd[0] & 0x3F) == MMC_SEND_TUNING_BLOCK) | ||
182 | trans_mode = SD_TM_AUTO_TUNING; | ||
183 | else | ||
184 | trans_mode = SD_TM_NORMAL_READ; | ||
185 | |||
186 | rtsx_pci_init_cmd(pcr); | ||
187 | |||
188 | for (i = 0; i < 5; i++) | ||
189 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0 + i, 0xFF, cmd[i]); | ||
190 | |||
191 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt); | ||
192 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H, | ||
193 | 0xFF, (u8)(byte_cnt >> 8)); | ||
194 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1); | ||
195 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0); | ||
196 | |||
197 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, | ||
198 | SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | | ||
199 | SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6); | ||
200 | if (trans_mode != SD_TM_AUTO_TUNING) | ||
201 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, | ||
202 | CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); | ||
203 | |||
204 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, | ||
205 | 0xFF, trans_mode | SD_TRANSFER_START); | ||
206 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, | ||
207 | SD_TRANSFER_END, SD_TRANSFER_END); | ||
208 | |||
209 | err = rtsx_pci_send_cmd(pcr, timeout); | ||
210 | if (err < 0) { | ||
211 | sd_print_debug_regs(host); | ||
212 | dev_dbg(sdmmc_dev(host), | ||
213 | "rtsx_pci_send_cmd fail (err = %d)\n", err); | ||
214 | return err; | ||
215 | } | ||
216 | |||
217 | if (buf && buf_len) { | ||
218 | err = rtsx_pci_read_ppbuf(pcr, buf, buf_len); | ||
219 | if (err < 0) { | ||
220 | dev_dbg(sdmmc_dev(host), | ||
221 | "rtsx_pci_read_ppbuf fail (err = %d)\n", err); | ||
222 | return err; | ||
223 | } | ||
224 | } | ||
225 | |||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | static int sd_write_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt, | ||
230 | u8 *buf, int buf_len, int timeout) | ||
231 | { | ||
232 | struct rtsx_pcr *pcr = host->pcr; | ||
233 | int err, i; | ||
234 | u8 trans_mode; | ||
235 | |||
236 | if (!buf) | ||
237 | buf_len = 0; | ||
238 | |||
239 | if (buf && buf_len) { | ||
240 | err = rtsx_pci_write_ppbuf(pcr, buf, buf_len); | ||
241 | if (err < 0) { | ||
242 | dev_dbg(sdmmc_dev(host), | ||
243 | "rtsx_pci_write_ppbuf fail (err = %d)\n", err); | ||
244 | return err; | ||
245 | } | ||
246 | } | ||
247 | |||
248 | trans_mode = cmd ? SD_TM_AUTO_WRITE_2 : SD_TM_AUTO_WRITE_3; | ||
249 | rtsx_pci_init_cmd(pcr); | ||
250 | |||
251 | if (cmd) { | ||
252 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d\n", __func__, | ||
253 | cmd[0] - 0x40); | ||
254 | |||
255 | for (i = 0; i < 5; i++) | ||
256 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, | ||
257 | SD_CMD0 + i, 0xFF, cmd[i]); | ||
258 | } | ||
259 | |||
260 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt); | ||
261 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H, | ||
262 | 0xFF, (u8)(byte_cnt >> 8)); | ||
263 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1); | ||
264 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0); | ||
265 | |||
266 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, | ||
267 | SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | | ||
268 | SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6); | ||
269 | |||
270 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF, | ||
271 | trans_mode | SD_TRANSFER_START); | ||
272 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, | ||
273 | SD_TRANSFER_END, SD_TRANSFER_END); | ||
274 | |||
275 | err = rtsx_pci_send_cmd(pcr, timeout); | ||
276 | if (err < 0) { | ||
277 | sd_print_debug_regs(host); | ||
278 | dev_dbg(sdmmc_dev(host), | ||
279 | "rtsx_pci_send_cmd fail (err = %d)\n", err); | ||
280 | return err; | ||
281 | } | ||
282 | |||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host, | 223 | static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host, |
287 | struct mmc_command *cmd) | 224 | struct mmc_command *cmd) |
288 | { | 225 | { |
@@ -293,47 +230,18 @@ static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host, | |||
293 | int timeout = 100; | 230 | int timeout = 100; |
294 | int i; | 231 | int i; |
295 | u8 *ptr; | 232 | u8 *ptr; |
296 | int stat_idx = 0; | 233 | int rsp_type; |
297 | u8 rsp_type; | 234 | int stat_idx; |
298 | int rsp_len = 5; | ||
299 | bool clock_toggled = false; | 235 | bool clock_toggled = false; |
300 | 236 | ||
301 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n", | 237 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n", |
302 | __func__, cmd_idx, arg); | 238 | __func__, cmd_idx, arg); |
303 | 239 | ||
304 | /* Response type: | 240 | rsp_type = sd_response_type(cmd); |
305 | * R0 | 241 | if (rsp_type < 0) |
306 | * R1, R5, R6, R7 | ||
307 | * R1b | ||
308 | * R2 | ||
309 | * R3, R4 | ||
310 | */ | ||
311 | switch (mmc_resp_type(cmd)) { | ||
312 | case MMC_RSP_NONE: | ||
313 | rsp_type = SD_RSP_TYPE_R0; | ||
314 | rsp_len = 0; | ||
315 | break; | ||
316 | case MMC_RSP_R1: | ||
317 | rsp_type = SD_RSP_TYPE_R1; | ||
318 | break; | ||
319 | case MMC_RSP_R1 & ~MMC_RSP_CRC: | ||
320 | rsp_type = SD_RSP_TYPE_R1 | SD_NO_CHECK_CRC7; | ||
321 | break; | ||
322 | case MMC_RSP_R1B: | ||
323 | rsp_type = SD_RSP_TYPE_R1b; | ||
324 | break; | ||
325 | case MMC_RSP_R2: | ||
326 | rsp_type = SD_RSP_TYPE_R2; | ||
327 | rsp_len = 16; | ||
328 | break; | ||
329 | case MMC_RSP_R3: | ||
330 | rsp_type = SD_RSP_TYPE_R3; | ||
331 | break; | ||
332 | default: | ||
333 | dev_dbg(sdmmc_dev(host), "cmd->flag is not valid\n"); | ||
334 | err = -EINVAL; | ||
335 | goto out; | 242 | goto out; |
336 | } | 243 | |
244 | stat_idx = sd_status_index(rsp_type); | ||
337 | 245 | ||
338 | if (rsp_type == SD_RSP_TYPE_R1b) | 246 | if (rsp_type == SD_RSP_TYPE_R1b) |
339 | timeout = 3000; | 247 | timeout = 3000; |
@@ -348,13 +256,7 @@ static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host, | |||
348 | } | 256 | } |
349 | 257 | ||
350 | rtsx_pci_init_cmd(pcr); | 258 | rtsx_pci_init_cmd(pcr); |
351 | 259 | sd_cmd_set_sd_cmd(pcr, cmd); | |
352 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0, 0xFF, 0x40 | cmd_idx); | ||
353 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD1, 0xFF, (u8)(arg >> 24)); | ||
354 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD2, 0xFF, (u8)(arg >> 16)); | ||
355 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD3, 0xFF, (u8)(arg >> 8)); | ||
356 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD4, 0xFF, (u8)arg); | ||
357 | |||
358 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, rsp_type); | 260 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, rsp_type); |
359 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE, | 261 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE, |
360 | 0x01, PINGPONG_BUFFER); | 262 | 0x01, PINGPONG_BUFFER); |
@@ -368,12 +270,10 @@ static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host, | |||
368 | /* Read data from ping-pong buffer */ | 270 | /* Read data from ping-pong buffer */ |
369 | for (i = PPBUF_BASE2; i < PPBUF_BASE2 + 16; i++) | 271 | for (i = PPBUF_BASE2; i < PPBUF_BASE2 + 16; i++) |
370 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0); | 272 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0); |
371 | stat_idx = 16; | ||
372 | } else if (rsp_type != SD_RSP_TYPE_R0) { | 273 | } else if (rsp_type != SD_RSP_TYPE_R0) { |
373 | /* Read data from SD_CMDx registers */ | 274 | /* Read data from SD_CMDx registers */ |
374 | for (i = SD_CMD0; i <= SD_CMD4; i++) | 275 | for (i = SD_CMD0; i <= SD_CMD4; i++) |
375 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0); | 276 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0); |
376 | stat_idx = 5; | ||
377 | } | 277 | } |
378 | 278 | ||
379 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, SD_STAT1, 0, 0); | 279 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, SD_STAT1, 0, 0); |
@@ -438,71 +338,213 @@ out: | |||
438 | SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0); | 338 | SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0); |
439 | } | 339 | } |
440 | 340 | ||
441 | static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq) | 341 | static int sd_read_data(struct realtek_pci_sdmmc *host, struct mmc_command *cmd, |
342 | u16 byte_cnt, u8 *buf, int buf_len, int timeout) | ||
343 | { | ||
344 | struct rtsx_pcr *pcr = host->pcr; | ||
345 | int err; | ||
346 | u8 trans_mode; | ||
347 | |||
348 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n", | ||
349 | __func__, cmd->opcode, cmd->arg); | ||
350 | |||
351 | if (!buf) | ||
352 | buf_len = 0; | ||
353 | |||
354 | if (cmd->opcode == MMC_SEND_TUNING_BLOCK) | ||
355 | trans_mode = SD_TM_AUTO_TUNING; | ||
356 | else | ||
357 | trans_mode = SD_TM_NORMAL_READ; | ||
358 | |||
359 | rtsx_pci_init_cmd(pcr); | ||
360 | sd_cmd_set_sd_cmd(pcr, cmd); | ||
361 | sd_cmd_set_data_len(pcr, 1, byte_cnt); | ||
362 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, | ||
363 | SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | | ||
364 | SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6); | ||
365 | if (trans_mode != SD_TM_AUTO_TUNING) | ||
366 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, | ||
367 | CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); | ||
368 | |||
369 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, | ||
370 | 0xFF, trans_mode | SD_TRANSFER_START); | ||
371 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, | ||
372 | SD_TRANSFER_END, SD_TRANSFER_END); | ||
373 | |||
374 | err = rtsx_pci_send_cmd(pcr, timeout); | ||
375 | if (err < 0) { | ||
376 | sd_print_debug_regs(host); | ||
377 | dev_dbg(sdmmc_dev(host), | ||
378 | "rtsx_pci_send_cmd fail (err = %d)\n", err); | ||
379 | return err; | ||
380 | } | ||
381 | |||
382 | if (buf && buf_len) { | ||
383 | err = rtsx_pci_read_ppbuf(pcr, buf, buf_len); | ||
384 | if (err < 0) { | ||
385 | dev_dbg(sdmmc_dev(host), | ||
386 | "rtsx_pci_read_ppbuf fail (err = %d)\n", err); | ||
387 | return err; | ||
388 | } | ||
389 | } | ||
390 | |||
391 | return 0; | ||
392 | } | ||
393 | |||
394 | static int sd_write_data(struct realtek_pci_sdmmc *host, | ||
395 | struct mmc_command *cmd, u16 byte_cnt, u8 *buf, int buf_len, | ||
396 | int timeout) | ||
397 | { | ||
398 | struct rtsx_pcr *pcr = host->pcr; | ||
399 | int err; | ||
400 | |||
401 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n", | ||
402 | __func__, cmd->opcode, cmd->arg); | ||
403 | |||
404 | if (!buf) | ||
405 | buf_len = 0; | ||
406 | |||
407 | sd_send_cmd_get_rsp(host, cmd); | ||
408 | if (cmd->error) | ||
409 | return cmd->error; | ||
410 | |||
411 | if (buf && buf_len) { | ||
412 | err = rtsx_pci_write_ppbuf(pcr, buf, buf_len); | ||
413 | if (err < 0) { | ||
414 | dev_dbg(sdmmc_dev(host), | ||
415 | "rtsx_pci_write_ppbuf fail (err = %d)\n", err); | ||
416 | return err; | ||
417 | } | ||
418 | } | ||
419 | |||
420 | rtsx_pci_init_cmd(pcr); | ||
421 | sd_cmd_set_data_len(pcr, 1, byte_cnt); | ||
422 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, | ||
423 | SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | | ||
424 | SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_0); | ||
425 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF, | ||
426 | SD_TRANSFER_START | SD_TM_AUTO_WRITE_3); | ||
427 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, | ||
428 | SD_TRANSFER_END, SD_TRANSFER_END); | ||
429 | |||
430 | err = rtsx_pci_send_cmd(pcr, timeout); | ||
431 | if (err < 0) { | ||
432 | sd_print_debug_regs(host); | ||
433 | dev_dbg(sdmmc_dev(host), | ||
434 | "rtsx_pci_send_cmd fail (err = %d)\n", err); | ||
435 | return err; | ||
436 | } | ||
437 | |||
438 | return 0; | ||
439 | } | ||
440 | |||
441 | static int sd_read_long_data(struct realtek_pci_sdmmc *host, | ||
442 | struct mmc_request *mrq) | ||
442 | { | 443 | { |
443 | struct rtsx_pcr *pcr = host->pcr; | 444 | struct rtsx_pcr *pcr = host->pcr; |
444 | struct mmc_host *mmc = host->mmc; | 445 | struct mmc_host *mmc = host->mmc; |
445 | struct mmc_card *card = mmc->card; | 446 | struct mmc_card *card = mmc->card; |
447 | struct mmc_command *cmd = mrq->cmd; | ||
446 | struct mmc_data *data = mrq->data; | 448 | struct mmc_data *data = mrq->data; |
447 | int uhs = mmc_card_uhs(card); | 449 | int uhs = mmc_card_uhs(card); |
448 | int read = (data->flags & MMC_DATA_READ) ? 1 : 0; | 450 | u8 cfg2 = 0; |
449 | u8 cfg2, trans_mode; | ||
450 | int err; | 451 | int err; |
452 | int resp_type; | ||
451 | size_t data_len = data->blksz * data->blocks; | 453 | size_t data_len = data->blksz * data->blocks; |
452 | 454 | ||
453 | if (read) { | 455 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n", |
454 | cfg2 = SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | | 456 | __func__, cmd->opcode, cmd->arg); |
455 | SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_0; | 457 | |
456 | trans_mode = SD_TM_AUTO_READ_3; | 458 | resp_type = sd_response_type(cmd); |
457 | } else { | 459 | if (resp_type < 0) |
458 | cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 | | 460 | return resp_type; |
459 | SD_NO_WAIT_BUSY_END | SD_NO_CHECK_CRC7 | SD_RSP_LEN_0; | ||
460 | trans_mode = SD_TM_AUTO_WRITE_3; | ||
461 | } | ||
462 | 461 | ||
463 | if (!uhs) | 462 | if (!uhs) |
464 | cfg2 |= SD_NO_CHECK_WAIT_CRC_TO; | 463 | cfg2 |= SD_NO_CHECK_WAIT_CRC_TO; |
465 | 464 | ||
466 | rtsx_pci_init_cmd(pcr); | 465 | rtsx_pci_init_cmd(pcr); |
467 | 466 | sd_cmd_set_sd_cmd(pcr, cmd); | |
468 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0x00); | 467 | sd_cmd_set_data_len(pcr, data->blocks, data->blksz); |
469 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, 0x02); | ||
470 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, | ||
471 | 0xFF, (u8)data->blocks); | ||
472 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, | ||
473 | 0xFF, (u8)(data->blocks >> 8)); | ||
474 | |||
475 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0, | 468 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0, |
476 | DMA_DONE_INT, DMA_DONE_INT); | 469 | DMA_DONE_INT, DMA_DONE_INT); |
477 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC3, | 470 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC3, |
478 | 0xFF, (u8)(data_len >> 24)); | 471 | 0xFF, (u8)(data_len >> 24)); |
479 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC2, | 472 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC2, |
480 | 0xFF, (u8)(data_len >> 16)); | 473 | 0xFF, (u8)(data_len >> 16)); |
481 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC1, | 474 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC1, |
482 | 0xFF, (u8)(data_len >> 8)); | 475 | 0xFF, (u8)(data_len >> 8)); |
483 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC0, 0xFF, (u8)data_len); | 476 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC0, 0xFF, (u8)data_len); |
484 | if (read) { | 477 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMACTL, |
485 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMACTL, | 478 | 0x03 | DMA_PACK_SIZE_MASK, |
486 | 0x03 | DMA_PACK_SIZE_MASK, | 479 | DMA_DIR_FROM_CARD | DMA_EN | DMA_512); |
487 | DMA_DIR_FROM_CARD | DMA_EN | DMA_512); | 480 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE, |
488 | } else { | 481 | 0x01, RING_BUFFER); |
489 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMACTL, | 482 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, cfg2 | resp_type); |
490 | 0x03 | DMA_PACK_SIZE_MASK, | 483 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF, |
491 | DMA_DIR_TO_CARD | DMA_EN | DMA_512); | 484 | SD_TRANSFER_START | SD_TM_AUTO_READ_2); |
485 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, | ||
486 | SD_TRANSFER_END, SD_TRANSFER_END); | ||
487 | rtsx_pci_send_cmd_no_wait(pcr); | ||
488 | |||
489 | err = rtsx_pci_dma_transfer(pcr, data->sg, host->sg_count, 1, 10000); | ||
490 | if (err < 0) { | ||
491 | sd_print_debug_regs(host); | ||
492 | sd_clear_error(host); | ||
493 | return err; | ||
492 | } | 494 | } |
493 | 495 | ||
496 | return 0; | ||
497 | } | ||
498 | |||
499 | static int sd_write_long_data(struct realtek_pci_sdmmc *host, | ||
500 | struct mmc_request *mrq) | ||
501 | { | ||
502 | struct rtsx_pcr *pcr = host->pcr; | ||
503 | struct mmc_host *mmc = host->mmc; | ||
504 | struct mmc_card *card = mmc->card; | ||
505 | struct mmc_command *cmd = mrq->cmd; | ||
506 | struct mmc_data *data = mrq->data; | ||
507 | int uhs = mmc_card_uhs(card); | ||
508 | u8 cfg2; | ||
509 | int err; | ||
510 | size_t data_len = data->blksz * data->blocks; | ||
511 | |||
512 | sd_send_cmd_get_rsp(host, cmd); | ||
513 | if (cmd->error) | ||
514 | return cmd->error; | ||
515 | |||
516 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n", | ||
517 | __func__, cmd->opcode, cmd->arg); | ||
518 | |||
519 | cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 | | ||
520 | SD_NO_WAIT_BUSY_END | SD_NO_CHECK_CRC7 | SD_RSP_LEN_0; | ||
521 | |||
522 | if (!uhs) | ||
523 | cfg2 |= SD_NO_CHECK_WAIT_CRC_TO; | ||
524 | |||
525 | rtsx_pci_init_cmd(pcr); | ||
526 | sd_cmd_set_data_len(pcr, data->blocks, data->blksz); | ||
527 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0, | ||
528 | DMA_DONE_INT, DMA_DONE_INT); | ||
529 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC3, | ||
530 | 0xFF, (u8)(data_len >> 24)); | ||
531 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC2, | ||
532 | 0xFF, (u8)(data_len >> 16)); | ||
533 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC1, | ||
534 | 0xFF, (u8)(data_len >> 8)); | ||
535 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC0, 0xFF, (u8)data_len); | ||
536 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMACTL, | ||
537 | 0x03 | DMA_PACK_SIZE_MASK, | ||
538 | DMA_DIR_TO_CARD | DMA_EN | DMA_512); | ||
494 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE, | 539 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE, |
495 | 0x01, RING_BUFFER); | 540 | 0x01, RING_BUFFER); |
496 | |||
497 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, cfg2); | 541 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, cfg2); |
498 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF, | 542 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF, |
499 | trans_mode | SD_TRANSFER_START); | 543 | SD_TRANSFER_START | SD_TM_AUTO_WRITE_3); |
500 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, | 544 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, |
501 | SD_TRANSFER_END, SD_TRANSFER_END); | 545 | SD_TRANSFER_END, SD_TRANSFER_END); |
502 | |||
503 | rtsx_pci_send_cmd_no_wait(pcr); | 546 | rtsx_pci_send_cmd_no_wait(pcr); |
504 | 547 | err = rtsx_pci_dma_transfer(pcr, data->sg, host->sg_count, 0, 10000); | |
505 | err = rtsx_pci_dma_transfer(pcr, data->sg, host->sg_count, read, 10000); | ||
506 | if (err < 0) { | 548 | if (err < 0) { |
507 | sd_clear_error(host); | 549 | sd_clear_error(host); |
508 | return err; | 550 | return err; |
@@ -511,6 +553,23 @@ static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq) | |||
511 | return 0; | 553 | return 0; |
512 | } | 554 | } |
513 | 555 | ||
556 | static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq) | ||
557 | { | ||
558 | struct mmc_data *data = mrq->data; | ||
559 | |||
560 | if (host->sg_count < 0) { | ||
561 | data->error = host->sg_count; | ||
562 | dev_dbg(sdmmc_dev(host), "%s: sg_count = %d is invalid\n", | ||
563 | __func__, host->sg_count); | ||
564 | return data->error; | ||
565 | } | ||
566 | |||
567 | if (data->flags & MMC_DATA_READ) | ||
568 | return sd_read_long_data(host, mrq); | ||
569 | |||
570 | return sd_write_long_data(host, mrq); | ||
571 | } | ||
572 | |||
514 | static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host) | 573 | static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host) |
515 | { | 574 | { |
516 | rtsx_pci_write_register(host->pcr, SD_CFG1, | 575 | rtsx_pci_write_register(host->pcr, SD_CFG1, |
@@ -528,10 +587,7 @@ static void sd_normal_rw(struct realtek_pci_sdmmc *host, | |||
528 | { | 587 | { |
529 | struct mmc_command *cmd = mrq->cmd; | 588 | struct mmc_command *cmd = mrq->cmd; |
530 | struct mmc_data *data = mrq->data; | 589 | struct mmc_data *data = mrq->data; |
531 | u8 _cmd[5], *buf; | 590 | u8 *buf; |
532 | |||
533 | _cmd[0] = 0x40 | (u8)cmd->opcode; | ||
534 | put_unaligned_be32(cmd->arg, (u32 *)(&_cmd[1])); | ||
535 | 591 | ||
536 | buf = kzalloc(data->blksz, GFP_NOIO); | 592 | buf = kzalloc(data->blksz, GFP_NOIO); |
537 | if (!buf) { | 593 | if (!buf) { |
@@ -543,7 +599,7 @@ static void sd_normal_rw(struct realtek_pci_sdmmc *host, | |||
543 | if (host->initial_mode) | 599 | if (host->initial_mode) |
544 | sd_disable_initial_mode(host); | 600 | sd_disable_initial_mode(host); |
545 | 601 | ||
546 | cmd->error = sd_read_data(host, _cmd, (u16)data->blksz, buf, | 602 | cmd->error = sd_read_data(host, cmd, (u16)data->blksz, buf, |
547 | data->blksz, 200); | 603 | data->blksz, 200); |
548 | 604 | ||
549 | if (host->initial_mode) | 605 | if (host->initial_mode) |
@@ -553,7 +609,7 @@ static void sd_normal_rw(struct realtek_pci_sdmmc *host, | |||
553 | } else { | 609 | } else { |
554 | sg_copy_to_buffer(data->sg, data->sg_len, buf, data->blksz); | 610 | sg_copy_to_buffer(data->sg, data->sg_len, buf, data->blksz); |
555 | 611 | ||
556 | cmd->error = sd_write_data(host, _cmd, (u16)data->blksz, buf, | 612 | cmd->error = sd_write_data(host, cmd, (u16)data->blksz, buf, |
557 | data->blksz, 200); | 613 | data->blksz, 200); |
558 | } | 614 | } |
559 | 615 | ||
@@ -653,14 +709,14 @@ static int sd_tuning_rx_cmd(struct realtek_pci_sdmmc *host, | |||
653 | u8 opcode, u8 sample_point) | 709 | u8 opcode, u8 sample_point) |
654 | { | 710 | { |
655 | int err; | 711 | int err; |
656 | u8 cmd[5] = {0}; | 712 | struct mmc_command cmd = {0}; |
657 | 713 | ||
658 | err = sd_change_phase(host, sample_point, true); | 714 | err = sd_change_phase(host, sample_point, true); |
659 | if (err < 0) | 715 | if (err < 0) |
660 | return err; | 716 | return err; |
661 | 717 | ||
662 | cmd[0] = 0x40 | opcode; | 718 | cmd.opcode = opcode; |
663 | err = sd_read_data(host, cmd, 0x40, NULL, 0, 100); | 719 | err = sd_read_data(host, &cmd, 0x40, NULL, 0, 100); |
664 | if (err < 0) { | 720 | if (err < 0) { |
665 | /* Wait till SD DATA IDLE */ | 721 | /* Wait till SD DATA IDLE */ |
666 | sd_wait_data_idle(host); | 722 | sd_wait_data_idle(host); |
@@ -727,6 +783,12 @@ static int sd_tuning_rx(struct realtek_pci_sdmmc *host, u8 opcode) | |||
727 | return 0; | 783 | return 0; |
728 | } | 784 | } |
729 | 785 | ||
786 | static inline int sdio_extblock_cmd(struct mmc_command *cmd, | ||
787 | struct mmc_data *data) | ||
788 | { | ||
789 | return (cmd->opcode == SD_IO_RW_EXTENDED) && (data->blksz == 512); | ||
790 | } | ||
791 | |||
730 | static inline int sd_rw_cmd(struct mmc_command *cmd) | 792 | static inline int sd_rw_cmd(struct mmc_command *cmd) |
731 | { | 793 | { |
732 | return mmc_op_multi(cmd->opcode) || | 794 | return mmc_op_multi(cmd->opcode) || |
@@ -748,7 +810,7 @@ static void sd_request(struct work_struct *work) | |||
748 | unsigned int data_size = 0; | 810 | unsigned int data_size = 0; |
749 | int err; | 811 | int err; |
750 | 812 | ||
751 | if (host->eject) { | 813 | if (host->eject || !sd_get_cd_int(host)) { |
752 | cmd->error = -ENOMEDIUM; | 814 | cmd->error = -ENOMEDIUM; |
753 | goto finish; | 815 | goto finish; |
754 | } | 816 | } |
@@ -776,17 +838,15 @@ static void sd_request(struct work_struct *work) | |||
776 | if (mrq->data) | 838 | if (mrq->data) |
777 | data_size = data->blocks * data->blksz; | 839 | data_size = data->blocks * data->blksz; |
778 | 840 | ||
779 | if (!data_size || sd_rw_cmd(cmd)) { | 841 | if (!data_size) { |
780 | sd_send_cmd_get_rsp(host, cmd); | 842 | sd_send_cmd_get_rsp(host, cmd); |
843 | } else if (sd_rw_cmd(cmd) || sdio_extblock_cmd(cmd, data)) { | ||
844 | cmd->error = sd_rw_multi(host, mrq); | ||
845 | if (!host->using_cookie) | ||
846 | sdmmc_post_req(host->mmc, host->mrq, 0); | ||
781 | 847 | ||
782 | if (!cmd->error && data_size) { | 848 | if (mmc_op_multi(cmd->opcode) && mrq->stop) |
783 | sd_rw_multi(host, mrq); | 849 | sd_send_cmd_get_rsp(host, mrq->stop); |
784 | if (!host->using_cookie) | ||
785 | sdmmc_post_req(host->mmc, host->mrq, 0); | ||
786 | |||
787 | if (mmc_op_multi(cmd->opcode) && mrq->stop) | ||
788 | sd_send_cmd_get_rsp(host, mrq->stop); | ||
789 | } | ||
790 | } else { | 850 | } else { |
791 | sd_normal_rw(host, mrq); | 851 | sd_normal_rw(host, mrq); |
792 | } | 852 | } |
@@ -801,8 +861,10 @@ static void sd_request(struct work_struct *work) | |||
801 | mutex_unlock(&pcr->pcr_mutex); | 861 | mutex_unlock(&pcr->pcr_mutex); |
802 | 862 | ||
803 | finish: | 863 | finish: |
804 | if (cmd->error) | 864 | if (cmd->error) { |
805 | dev_dbg(sdmmc_dev(host), "cmd->error = %d\n", cmd->error); | 865 | dev_dbg(sdmmc_dev(host), "CMD %d 0x%08x error(%d)\n", |
866 | cmd->opcode, cmd->arg, cmd->error); | ||
867 | } | ||
806 | 868 | ||
807 | mutex_lock(&host->host_mutex); | 869 | mutex_lock(&host->host_mutex); |
808 | host->mrq = NULL; | 870 | host->mrq = NULL; |
@@ -820,7 +882,7 @@ static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
820 | host->mrq = mrq; | 882 | host->mrq = mrq; |
821 | mutex_unlock(&host->host_mutex); | 883 | mutex_unlock(&host->host_mutex); |
822 | 884 | ||
823 | if (sd_rw_cmd(mrq->cmd)) | 885 | if (sd_rw_cmd(mrq->cmd) || sdio_extblock_cmd(mrq->cmd, data)) |
824 | host->using_cookie = sd_pre_dma_transfer(host, data, false); | 886 | host->using_cookie = sd_pre_dma_transfer(host, data, false); |
825 | 887 | ||
826 | queue_work(host->workq, &host->work); | 888 | queue_work(host->workq, &host->work); |
@@ -1066,7 +1128,7 @@ static int sdmmc_get_cd(struct mmc_host *mmc) | |||
1066 | u32 val; | 1128 | u32 val; |
1067 | 1129 | ||
1068 | if (host->eject) | 1130 | if (host->eject) |
1069 | return -ENOMEDIUM; | 1131 | return cd; |
1070 | 1132 | ||
1071 | mutex_lock(&pcr->pcr_mutex); | 1133 | mutex_lock(&pcr->pcr_mutex); |
1072 | 1134 | ||
@@ -1317,6 +1379,7 @@ static void rtsx_pci_sdmmc_card_event(struct platform_device *pdev) | |||
1317 | { | 1379 | { |
1318 | struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev); | 1380 | struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev); |
1319 | 1381 | ||
1382 | host->cookie = -1; | ||
1320 | mmc_detect_change(host->mmc, 0); | 1383 | mmc_detect_change(host->mmc, 0); |
1321 | } | 1384 | } |
1322 | 1385 | ||
@@ -1349,6 +1412,7 @@ static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev) | |||
1349 | host->pcr = pcr; | 1412 | host->pcr = pcr; |
1350 | host->mmc = mmc; | 1413 | host->mmc = mmc; |
1351 | host->pdev = pdev; | 1414 | host->pdev = pdev; |
1415 | host->cookie = -1; | ||
1352 | host->power_state = SDMMC_POWER_OFF; | 1416 | host->power_state = SDMMC_POWER_OFF; |
1353 | INIT_WORK(&host->work, sd_request); | 1417 | INIT_WORK(&host->work, sd_request); |
1354 | platform_set_drvdata(pdev, host); | 1418 | platform_set_drvdata(pdev, host); |