1 /* Realtek PCI-Express Memstick Card Interface driver 2 * 3 * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License as published by the 7 * Free Software Foundation; either version 2, or (at your option) any 8 * later version. 9 * 10 * This program is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, see <http://www.gnu.org/licenses/>. 17 * 18 * Author: 19 * Wei WANG <wei_wang@realsil.com.cn> 20 */ 21 22 #include <linux/module.h> 23 #include <linux/highmem.h> 24 #include <linux/delay.h> 25 #include <linux/platform_device.h> 26 #include <linux/memstick.h> 27 #include <linux/mfd/rtsx_pci.h> 28 #include <asm/unaligned.h> 29 30 struct realtek_pci_ms { 31 struct platform_device *pdev; 32 struct rtsx_pcr *pcr; 33 struct memstick_host *msh; 34 struct memstick_request *req; 35 36 struct mutex host_mutex; 37 struct work_struct handle_req; 38 39 u8 ssc_depth; 40 unsigned int clock; 41 unsigned char ifmode; 42 bool eject; 43 }; 44 45 static inline struct device *ms_dev(struct realtek_pci_ms *host) 46 { 47 return &(host->pdev->dev); 48 } 49 50 static inline void ms_clear_error(struct realtek_pci_ms *host) 51 { 52 rtsx_pci_write_register(host->pcr, CARD_STOP, 53 MS_STOP | MS_CLR_ERR, MS_STOP | MS_CLR_ERR); 54 } 55 56 #ifdef DEBUG 57 58 static void ms_print_debug_regs(struct realtek_pci_ms *host) 59 { 60 struct rtsx_pcr *pcr = host->pcr; 61 u16 i; 62 u8 *ptr; 63 64 /* Print MS host internal registers */ 65 rtsx_pci_init_cmd(pcr); 66 for (i = 0xFD40; i <= 0xFD44; i++) 67 rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0); 68 for (i = 0xFD52; i <= 0xFD69; i++) 69 rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0); 70 rtsx_pci_send_cmd(pcr, 100); 71 72 ptr = rtsx_pci_get_cmd_data(pcr); 73 for (i = 0xFD40; i <= 0xFD44; i++) 74 dev_dbg(ms_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++)); 75 for (i = 0xFD52; i <= 0xFD69; i++) 76 dev_dbg(ms_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++)); 77 } 78 79 #else 80 81 #define ms_print_debug_regs(host) 82 83 #endif 84 85 static int ms_power_on(struct realtek_pci_ms *host) 86 { 87 struct rtsx_pcr *pcr = host->pcr; 88 int err; 89 90 rtsx_pci_init_cmd(pcr); 91 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_SELECT, 0x07, MS_MOD_SEL); 92 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_SHARE_MODE, 93 CARD_SHARE_MASK, CARD_SHARE_48_MS); 94 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_EN, 95 MS_CLK_EN, MS_CLK_EN); 96 err = rtsx_pci_send_cmd(pcr, 100); 97 if (err < 0) 98 return err; 99 100 err = rtsx_pci_card_pull_ctl_enable(pcr, RTSX_MS_CARD); 101 if (err < 0) 102 return err; 103 104 err = rtsx_pci_card_power_on(pcr, RTSX_MS_CARD); 105 if (err < 0) 106 return err; 107 108 /* Wait ms power stable */ 109 msleep(150); 110 111 err = rtsx_pci_write_register(pcr, CARD_OE, 112 MS_OUTPUT_EN, MS_OUTPUT_EN); 113 if (err < 0) 114 return err; 115 116 return 0; 117 } 118 119 static int ms_power_off(struct realtek_pci_ms *host) 120 { 121 struct rtsx_pcr *pcr = host->pcr; 122 int err; 123 124 rtsx_pci_init_cmd(pcr); 125 126 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_EN, MS_CLK_EN, 0); 127 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_OE, MS_OUTPUT_EN, 0); 128 129 err = rtsx_pci_send_cmd(pcr, 100); 130 if (err < 0) 131 return err; 132 133 err = rtsx_pci_card_power_off(pcr, RTSX_MS_CARD); 134 if (err < 0) 135 return err; 136 137 return rtsx_pci_card_pull_ctl_disable(pcr, RTSX_MS_CARD); 138 } 139 140 static int ms_transfer_data(struct realtek_pci_ms *host, unsigned char data_dir, 141 u8 tpc, u8 cfg, struct scatterlist *sg) 142 { 143 struct rtsx_pcr *pcr = host->pcr; 144 int err; 145 unsigned int length = sg->length; 146 u16 sec_cnt = (u16)(length / 512); 147 u8 val, trans_mode, dma_dir; 148 struct memstick_dev *card = host->msh->card; 149 bool pro_card = card->id.type == MEMSTICK_TYPE_PRO; 150 151 dev_dbg(ms_dev(host), "%s: tpc = 0x%02x, data_dir = %s, length = %d\n", 152 __func__, tpc, (data_dir == READ) ? "READ" : "WRITE", 153 length); 154 155 if (data_dir == READ) { 156 dma_dir = DMA_DIR_FROM_CARD; 157 trans_mode = pro_card ? MS_TM_AUTO_READ : MS_TM_NORMAL_READ; 158 } else { 159 dma_dir = DMA_DIR_TO_CARD; 160 trans_mode = pro_card ? MS_TM_AUTO_WRITE : MS_TM_NORMAL_WRITE; 161 } 162 163 rtsx_pci_init_cmd(pcr); 164 165 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); 166 if (pro_card) { 167 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_H, 168 0xFF, (u8)(sec_cnt >> 8)); 169 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_L, 170 0xFF, (u8)sec_cnt); 171 } 172 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); 173 174 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0, 175 DMA_DONE_INT, DMA_DONE_INT); 176 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC3, 0xFF, (u8)(length >> 24)); 177 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC2, 0xFF, (u8)(length >> 16)); 178 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC1, 0xFF, (u8)(length >> 8)); 179 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC0, 0xFF, (u8)length); 180 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMACTL, 181 0x03 | DMA_PACK_SIZE_MASK, dma_dir | DMA_EN | DMA_512); 182 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE, 183 0x01, RING_BUFFER); 184 185 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANSFER, 186 0xFF, MS_TRANSFER_START | trans_mode); 187 rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, MS_TRANSFER, 188 MS_TRANSFER_END, MS_TRANSFER_END); 189 190 rtsx_pci_send_cmd_no_wait(pcr); 191 192 err = rtsx_pci_transfer_data(pcr, sg, 1, data_dir == READ, 10000); 193 if (err < 0) { 194 ms_clear_error(host); 195 return err; 196 } 197 198 rtsx_pci_read_register(pcr, MS_TRANS_CFG, &val); 199 if (pro_card) { 200 if (val & (MS_INT_CMDNK | MS_INT_ERR | 201 MS_CRC16_ERR | MS_RDY_TIMEOUT)) 202 return -EIO; 203 } else { 204 if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) 205 return -EIO; 206 } 207 208 return 0; 209 } 210 211 static int ms_write_bytes(struct realtek_pci_ms *host, u8 tpc, 212 u8 cfg, u8 cnt, u8 *data, u8 *int_reg) 213 { 214 struct rtsx_pcr *pcr = host->pcr; 215 int err, i; 216 217 dev_dbg(ms_dev(host), "%s: tpc = 0x%02x\n", __func__, tpc); 218 219 if (!data) 220 return -EINVAL; 221 222 rtsx_pci_init_cmd(pcr); 223 224 for (i = 0; i < cnt; i++) 225 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, 226 PPBUF_BASE2 + i, 0xFF, data[i]); 227 if (cnt % 2) 228 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, 229 PPBUF_BASE2 + i, 0xFF, 0xFF); 230 231 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); 232 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); 233 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); 234 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE, 235 0x01, PINGPONG_BUFFER); 236 237 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANSFER, 238 0xFF, MS_TRANSFER_START | MS_TM_WRITE_BYTES); 239 rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, MS_TRANSFER, 240 MS_TRANSFER_END, MS_TRANSFER_END); 241 if (int_reg) 242 rtsx_pci_add_cmd(pcr, READ_REG_CMD, MS_TRANS_CFG, 0, 0); 243 244 err = rtsx_pci_send_cmd(pcr, 5000); 245 if (err < 0) { 246 u8 val; 247 248 rtsx_pci_read_register(pcr, MS_TRANS_CFG, &val); 249 dev_dbg(ms_dev(host), "MS_TRANS_CFG: 0x%02x\n", val); 250 251 if (int_reg) 252 *int_reg = val & 0x0F; 253 254 ms_print_debug_regs(host); 255 256 ms_clear_error(host); 257 258 if (!(tpc & 0x08)) { 259 if (val & MS_CRC16_ERR) 260 return -EIO; 261 } else { 262 if (!(val & 0x80)) { 263 if (val & (MS_INT_ERR | MS_INT_CMDNK)) 264 return -EIO; 265 } 266 } 267 268 return -ETIMEDOUT; 269 } 270 271 if (int_reg) { 272 u8 *ptr = rtsx_pci_get_cmd_data(pcr) + 1; 273 *int_reg = *ptr & 0x0F; 274 } 275 276 return 0; 277 } 278 279 static int ms_read_bytes(struct realtek_pci_ms *host, u8 tpc, 280 u8 cfg, u8 cnt, u8 *data, u8 *int_reg) 281 { 282 struct rtsx_pcr *pcr = host->pcr; 283 int err, i; 284 u8 *ptr; 285 286 dev_dbg(ms_dev(host), "%s: tpc = 0x%02x\n", __func__, tpc); 287 288 if (!data) 289 return -EINVAL; 290 291 rtsx_pci_init_cmd(pcr); 292 293 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); 294 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); 295 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); 296 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE, 297 0x01, PINGPONG_BUFFER); 298 299 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANSFER, 300 0xFF, MS_TRANSFER_START | MS_TM_READ_BYTES); 301 rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, MS_TRANSFER, 302 MS_TRANSFER_END, MS_TRANSFER_END); 303 for (i = 0; i < cnt - 1; i++) 304 rtsx_pci_add_cmd(pcr, READ_REG_CMD, PPBUF_BASE2 + i, 0, 0); 305 if (cnt % 2) 306 rtsx_pci_add_cmd(pcr, READ_REG_CMD, PPBUF_BASE2 + cnt, 0, 0); 307 else 308 rtsx_pci_add_cmd(pcr, READ_REG_CMD, 309 PPBUF_BASE2 + cnt - 1, 0, 0); 310 if (int_reg) 311 rtsx_pci_add_cmd(pcr, READ_REG_CMD, MS_TRANS_CFG, 0, 0); 312 313 err = rtsx_pci_send_cmd(pcr, 5000); 314 if (err < 0) { 315 u8 val; 316 317 rtsx_pci_read_register(pcr, MS_TRANS_CFG, &val); 318 dev_dbg(ms_dev(host), "MS_TRANS_CFG: 0x%02x\n", val); 319 320 if (int_reg) 321 *int_reg = val & 0x0F; 322 323 ms_print_debug_regs(host); 324 325 ms_clear_error(host); 326 327 if (!(tpc & 0x08)) { 328 if (val & MS_CRC16_ERR) 329 return -EIO; 330 } else { 331 if (!(val & 0x80)) { 332 if (val & (MS_INT_ERR | MS_INT_CMDNK)) 333 return -EIO; 334 } 335 } 336 337 return -ETIMEDOUT; 338 } 339 340 ptr = rtsx_pci_get_cmd_data(pcr) + 1; 341 for (i = 0; i < cnt; i++) 342 data[i] = *ptr++; 343 344 if (int_reg) 345 *int_reg = *ptr & 0x0F; 346 347 return 0; 348 } 349 350 static int rtsx_pci_ms_issue_cmd(struct realtek_pci_ms *host) 351 { 352 struct memstick_request *req = host->req; 353 int err = 0; 354 u8 cfg = 0, int_reg; 355 356 dev_dbg(ms_dev(host), "%s\n", __func__); 357 358 if (req->need_card_int) { 359 if (host->ifmode != MEMSTICK_SERIAL) 360 cfg = WAIT_INT; 361 } 362 363 if (req->long_data) { 364 err = ms_transfer_data(host, req->data_dir, 365 req->tpc, cfg, &(req->sg)); 366 } else { 367 if (req->data_dir == READ) { 368 err = ms_read_bytes(host, req->tpc, cfg, 369 req->data_len, req->data, &int_reg); 370 } else { 371 err = ms_write_bytes(host, req->tpc, cfg, 372 req->data_len, req->data, &int_reg); 373 } 374 } 375 if (err < 0) 376 return err; 377 378 if (req->need_card_int && (host->ifmode == MEMSTICK_SERIAL)) { 379 err = ms_read_bytes(host, MS_TPC_GET_INT, 380 NO_WAIT_INT, 1, &int_reg, NULL); 381 if (err < 0) 382 return err; 383 } 384 385 if (req->need_card_int) { 386 dev_dbg(ms_dev(host), "int_reg: 0x%02x\n", int_reg); 387 388 if (int_reg & MS_INT_CMDNK) 389 req->int_reg |= MEMSTICK_INT_CMDNAK; 390 if (int_reg & MS_INT_BREQ) 391 req->int_reg |= MEMSTICK_INT_BREQ; 392 if (int_reg & MS_INT_ERR) 393 req->int_reg |= MEMSTICK_INT_ERR; 394 if (int_reg & MS_INT_CED) 395 req->int_reg |= MEMSTICK_INT_CED; 396 } 397 398 return 0; 399 } 400 401 static void rtsx_pci_ms_handle_req(struct work_struct *work) 402 { 403 struct realtek_pci_ms *host = container_of(work, 404 struct realtek_pci_ms, handle_req); 405 struct rtsx_pcr *pcr = host->pcr; 406 struct memstick_host *msh = host->msh; 407 int rc; 408 409 mutex_lock(&pcr->pcr_mutex); 410 411 rtsx_pci_start_run(pcr); 412 413 rtsx_pci_switch_clock(host->pcr, host->clock, host->ssc_depth, 414 false, true, false); 415 rtsx_pci_write_register(pcr, CARD_SELECT, 0x07, MS_MOD_SEL); 416 rtsx_pci_write_register(pcr, CARD_SHARE_MODE, 417 CARD_SHARE_MASK, CARD_SHARE_48_MS); 418 419 if (!host->req) { 420 do { 421 rc = memstick_next_req(msh, &host->req); 422 dev_dbg(ms_dev(host), "next req %d\n", rc); 423 424 if (!rc) 425 host->req->error = rtsx_pci_ms_issue_cmd(host); 426 } while (!rc); 427 } 428 429 mutex_unlock(&pcr->pcr_mutex); 430 } 431 432 static void rtsx_pci_ms_request(struct memstick_host *msh) 433 { 434 struct realtek_pci_ms *host = memstick_priv(msh); 435 436 dev_dbg(ms_dev(host), "--> %s\n", __func__); 437 438 if (rtsx_pci_card_exclusive_check(host->pcr, RTSX_MS_CARD)) 439 return; 440 441 schedule_work(&host->handle_req); 442 } 443 444 static int rtsx_pci_ms_set_param(struct memstick_host *msh, 445 enum memstick_param param, int value) 446 { 447 struct realtek_pci_ms *host = memstick_priv(msh); 448 struct rtsx_pcr *pcr = host->pcr; 449 unsigned int clock = 0; 450 u8 ssc_depth = 0; 451 int err; 452 453 dev_dbg(ms_dev(host), "%s: param = %d, value = %d\n", 454 __func__, param, value); 455 456 err = rtsx_pci_card_exclusive_check(host->pcr, RTSX_MS_CARD); 457 if (err) 458 return err; 459 460 switch (param) { 461 case MEMSTICK_POWER: 462 if (value == MEMSTICK_POWER_ON) 463 err = ms_power_on(host); 464 else if (value == MEMSTICK_POWER_OFF) 465 err = ms_power_off(host); 466 else 467 return -EINVAL; 468 break; 469 470 case MEMSTICK_INTERFACE: 471 if (value == MEMSTICK_SERIAL) { 472 clock = 19000000; 473 ssc_depth = RTSX_SSC_DEPTH_500K; 474 475 err = rtsx_pci_write_register(pcr, MS_CFG, 0x58, 476 MS_BUS_WIDTH_1 | PUSH_TIME_DEFAULT); 477 if (err < 0) 478 return err; 479 } else if (value == MEMSTICK_PAR4) { 480 clock = 39000000; 481 ssc_depth = RTSX_SSC_DEPTH_1M; 482 483 err = rtsx_pci_write_register(pcr, MS_CFG, 484 0x58, MS_BUS_WIDTH_4 | PUSH_TIME_ODD); 485 if (err < 0) 486 return err; 487 } else { 488 return -EINVAL; 489 } 490 491 err = rtsx_pci_switch_clock(pcr, clock, 492 ssc_depth, false, true, false); 493 if (err < 0) 494 return err; 495 496 host->ssc_depth = ssc_depth; 497 host->clock = clock; 498 host->ifmode = value; 499 break; 500 } 501 502 return 0; 503 } 504 505 #ifdef CONFIG_PM 506 507 static int rtsx_pci_ms_suspend(struct platform_device *pdev, pm_message_t state) 508 { 509 struct realtek_pci_ms *host = platform_get_drvdata(pdev); 510 struct memstick_host *msh = host->msh; 511 512 dev_dbg(ms_dev(host), "--> %s\n", __func__); 513 514 memstick_suspend_host(msh); 515 return 0; 516 } 517 518 static int rtsx_pci_ms_resume(struct platform_device *pdev) 519 { 520 struct realtek_pci_ms *host = platform_get_drvdata(pdev); 521 struct memstick_host *msh = host->msh; 522 523 dev_dbg(ms_dev(host), "--> %s\n", __func__); 524 525 memstick_resume_host(msh); 526 return 0; 527 } 528 529 #else /* CONFIG_PM */ 530 531 #define rtsx_pci_ms_suspend NULL 532 #define rtsx_pci_ms_resume NULL 533 534 #endif /* CONFIG_PM */ 535 536 static void rtsx_pci_ms_card_event(struct platform_device *pdev) 537 { 538 struct realtek_pci_ms *host = platform_get_drvdata(pdev); 539 540 memstick_detect_change(host->msh); 541 } 542 543 static int rtsx_pci_ms_drv_probe(struct platform_device *pdev) 544 { 545 struct memstick_host *msh; 546 struct realtek_pci_ms *host; 547 struct rtsx_pcr *pcr; 548 struct pcr_handle *handle = pdev->dev.platform_data; 549 int rc; 550 551 if (!handle) 552 return -ENXIO; 553 554 pcr = handle->pcr; 555 if (!pcr) 556 return -ENXIO; 557 558 dev_dbg(&(pdev->dev), 559 ": Realtek PCI-E Memstick controller found\n"); 560 561 msh = memstick_alloc_host(sizeof(*host), &pdev->dev); 562 if (!msh) 563 return -ENOMEM; 564 565 host = memstick_priv(msh); 566 host->pcr = pcr; 567 host->msh = msh; 568 host->pdev = pdev; 569 platform_set_drvdata(pdev, host); 570 pcr->slots[RTSX_MS_CARD].p_dev = pdev; 571 pcr->slots[RTSX_MS_CARD].card_event = rtsx_pci_ms_card_event; 572 573 mutex_init(&host->host_mutex); 574 575 INIT_WORK(&host->handle_req, rtsx_pci_ms_handle_req); 576 msh->request = rtsx_pci_ms_request; 577 msh->set_param = rtsx_pci_ms_set_param; 578 msh->caps = MEMSTICK_CAP_PAR4; 579 580 rc = memstick_add_host(msh); 581 if (rc) { 582 memstick_free_host(msh); 583 return rc; 584 } 585 586 return 0; 587 } 588 589 static int rtsx_pci_ms_drv_remove(struct platform_device *pdev) 590 { 591 struct realtek_pci_ms *host = platform_get_drvdata(pdev); 592 struct rtsx_pcr *pcr; 593 struct memstick_host *msh; 594 int rc; 595 596 if (!host) 597 return 0; 598 599 pcr = host->pcr; 600 pcr->slots[RTSX_MS_CARD].p_dev = NULL; 601 pcr->slots[RTSX_MS_CARD].card_event = NULL; 602 msh = host->msh; 603 host->eject = true; 604 605 mutex_lock(&host->host_mutex); 606 if (host->req) { 607 dev_dbg(&(pdev->dev), 608 "%s: Controller removed during transfer\n", 609 dev_name(&msh->dev)); 610 611 rtsx_pci_complete_unfinished_transfer(pcr); 612 613 host->req->error = -ENOMEDIUM; 614 do { 615 rc = memstick_next_req(msh, &host->req); 616 if (!rc) 617 host->req->error = -ENOMEDIUM; 618 } while (!rc); 619 } 620 mutex_unlock(&host->host_mutex); 621 622 memstick_remove_host(msh); 623 memstick_free_host(msh); 624 625 dev_dbg(&(pdev->dev), 626 ": Realtek PCI-E Memstick controller has been removed\n"); 627 628 return 0; 629 } 630 631 static struct platform_device_id rtsx_pci_ms_ids[] = { 632 { 633 .name = DRV_NAME_RTSX_PCI_MS, 634 }, { 635 /* sentinel */ 636 } 637 }; 638 MODULE_DEVICE_TABLE(platform, rtsx_pci_ms_ids); 639 640 static struct platform_driver rtsx_pci_ms_driver = { 641 .probe = rtsx_pci_ms_drv_probe, 642 .remove = rtsx_pci_ms_drv_remove, 643 .id_table = rtsx_pci_ms_ids, 644 .suspend = rtsx_pci_ms_suspend, 645 .resume = rtsx_pci_ms_resume, 646 .driver = { 647 .owner = THIS_MODULE, 648 .name = DRV_NAME_RTSX_PCI_MS, 649 }, 650 }; 651 module_platform_driver(rtsx_pci_ms_driver); 652 653 MODULE_LICENSE("GPL"); 654 MODULE_AUTHOR("Wei WANG <wei_wang@realsil.com.cn>"); 655 MODULE_DESCRIPTION("Realtek PCI-E Memstick Card Host Driver"); 656