jmb38x_ms.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954
  1. /*
  2. * jmb38x_ms.c - JMicron jmb38x MemoryStick card reader
  3. *
  4. * Copyright (C) 2008 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. #include <linux/spinlock.h>
  12. #include <linux/interrupt.h>
  13. #include <linux/pci.h>
  14. #include <linux/dma-mapping.h>
  15. #include <linux/delay.h>
  16. #include <linux/highmem.h>
  17. #include <linux/memstick.h>
  18. #define DRIVER_NAME "jmb38x_ms"
  19. static int no_dma;
  20. module_param(no_dma, bool, 0644);
  21. enum {
  22. DMA_ADDRESS = 0x00,
  23. BLOCK = 0x04,
  24. DMA_CONTROL = 0x08,
  25. TPC_P0 = 0x0c,
  26. TPC_P1 = 0x10,
  27. TPC = 0x14,
  28. HOST_CONTROL = 0x18,
  29. DATA = 0x1c,
  30. STATUS = 0x20,
  31. INT_STATUS = 0x24,
  32. INT_STATUS_ENABLE = 0x28,
  33. INT_SIGNAL_ENABLE = 0x2c,
  34. TIMER = 0x30,
  35. TIMER_CONTROL = 0x34,
  36. PAD_OUTPUT_ENABLE = 0x38,
  37. PAD_PU_PD = 0x3c,
  38. CLOCK_DELAY = 0x40,
  39. ADMA_ADDRESS = 0x44,
  40. CLOCK_CONTROL = 0x48,
  41. LED_CONTROL = 0x4c,
  42. VERSION = 0x50
  43. };
  44. struct jmb38x_ms_host {
  45. struct jmb38x_ms *chip;
  46. void __iomem *addr;
  47. spinlock_t lock;
  48. int id;
  49. char host_id[DEVICE_ID_SIZE];
  50. int irq;
  51. unsigned int block_pos;
  52. unsigned long timeout_jiffies;
  53. struct timer_list timer;
  54. struct memstick_request *req;
  55. unsigned char cmd_flags;
  56. unsigned char io_pos;
  57. unsigned int io_word[2];
  58. };
  59. struct jmb38x_ms {
  60. struct pci_dev *pdev;
  61. int host_cnt;
  62. struct memstick_host *hosts[];
  63. };
  64. #define BLOCK_COUNT_MASK 0xffff0000
  65. #define BLOCK_SIZE_MASK 0x00000fff
  66. #define DMA_CONTROL_ENABLE 0x00000001
  67. #define TPC_DATA_SEL 0x00008000
  68. #define TPC_DIR 0x00004000
  69. #define TPC_WAIT_INT 0x00002000
  70. #define TPC_GET_INT 0x00000800
  71. #define TPC_CODE_SZ_MASK 0x00000700
  72. #define TPC_DATA_SZ_MASK 0x00000007
  73. #define HOST_CONTROL_RESET_REQ 0x00008000
  74. #define HOST_CONTROL_REI 0x00004000
  75. #define HOST_CONTROL_LED 0x00000400
  76. #define HOST_CONTROL_FAST_CLK 0x00000200
  77. #define HOST_CONTROL_RESET 0x00000100
  78. #define HOST_CONTROL_POWER_EN 0x00000080
  79. #define HOST_CONTROL_CLOCK_EN 0x00000040
  80. #define HOST_CONTROL_IF_SHIFT 4
  81. #define HOST_CONTROL_IF_SERIAL 0x0
  82. #define HOST_CONTROL_IF_PAR4 0x1
  83. #define HOST_CONTROL_IF_PAR8 0x3
  84. #define STATUS_BUSY 0x00080000
  85. #define STATUS_MS_DAT7 0x00040000
  86. #define STATUS_MS_DAT6 0x00020000
  87. #define STATUS_MS_DAT5 0x00010000
  88. #define STATUS_MS_DAT4 0x00008000
  89. #define STATUS_MS_DAT3 0x00004000
  90. #define STATUS_MS_DAT2 0x00002000
  91. #define STATUS_MS_DAT1 0x00001000
  92. #define STATUS_MS_DAT0 0x00000800
  93. #define STATUS_HAS_MEDIA 0x00000400
  94. #define STATUS_FIFO_EMPTY 0x00000200
  95. #define STATUS_FIFO_FULL 0x00000100
  96. #define STATUS_MS_CED 0x00000080
  97. #define STATUS_MS_ERR 0x00000040
  98. #define STATUS_MS_BRQ 0x00000020
  99. #define STATUS_MS_CNK 0x00000001
  100. #define INT_STATUS_TPC_ERR 0x00080000
  101. #define INT_STATUS_CRC_ERR 0x00040000
  102. #define INT_STATUS_TIMER_TO 0x00020000
  103. #define INT_STATUS_HSK_TO 0x00010000
  104. #define INT_STATUS_ANY_ERR 0x00008000
  105. #define INT_STATUS_FIFO_WRDY 0x00000080
  106. #define INT_STATUS_FIFO_RRDY 0x00000040
  107. #define INT_STATUS_MEDIA_OUT 0x00000010
  108. #define INT_STATUS_MEDIA_IN 0x00000008
  109. #define INT_STATUS_DMA_BOUNDARY 0x00000004
  110. #define INT_STATUS_EOTRAN 0x00000002
  111. #define INT_STATUS_EOTPC 0x00000001
  112. #define INT_STATUS_ALL 0x000f801f
  113. #define PAD_OUTPUT_ENABLE_MS 0x0F3F
  114. #define PAD_PU_PD_OFF 0x7FFF0000
  115. #define PAD_PU_PD_ON_MS_SOCK0 0x5f8f0000
  116. #define PAD_PU_PD_ON_MS_SOCK1 0x0f0f0000
  117. enum {
  118. CMD_READY = 0x01,
  119. FIFO_READY = 0x02,
  120. REG_DATA = 0x04,
  121. DMA_DATA = 0x08
  122. };
  123. static unsigned int jmb38x_ms_read_data(struct jmb38x_ms_host *host,
  124. unsigned char *buf, unsigned int length)
  125. {
  126. unsigned int off = 0;
  127. while (host->io_pos && length) {
  128. buf[off++] = host->io_word[0] & 0xff;
  129. host->io_word[0] >>= 8;
  130. length--;
  131. host->io_pos--;
  132. }
  133. if (!length)
  134. return off;
  135. while (!(STATUS_FIFO_EMPTY & readl(host->addr + STATUS))) {
  136. if (length < 4)
  137. break;
  138. *(unsigned int *)(buf + off) = __raw_readl(host->addr + DATA);
  139. length -= 4;
  140. off += 4;
  141. }
  142. if (length
  143. && !(STATUS_FIFO_EMPTY & readl(host->addr + STATUS))) {
  144. host->io_word[0] = readl(host->addr + DATA);
  145. for (host->io_pos = 4; host->io_pos; --host->io_pos) {
  146. buf[off++] = host->io_word[0] & 0xff;
  147. host->io_word[0] >>= 8;
  148. length--;
  149. if (!length)
  150. break;
  151. }
  152. }
  153. return off;
  154. }
  155. static unsigned int jmb38x_ms_read_reg_data(struct jmb38x_ms_host *host,
  156. unsigned char *buf,
  157. unsigned int length)
  158. {
  159. unsigned int off = 0;
  160. while (host->io_pos > 4 && length) {
  161. buf[off++] = host->io_word[0] & 0xff;
  162. host->io_word[0] >>= 8;
  163. length--;
  164. host->io_pos--;
  165. }
  166. if (!length)
  167. return off;
  168. while (host->io_pos && length) {
  169. buf[off++] = host->io_word[1] & 0xff;
  170. host->io_word[1] >>= 8;
  171. length--;
  172. host->io_pos--;
  173. }
  174. return off;
  175. }
  176. static unsigned int jmb38x_ms_write_data(struct jmb38x_ms_host *host,
  177. unsigned char *buf,
  178. unsigned int length)
  179. {
  180. unsigned int off = 0;
  181. if (host->io_pos) {
  182. while (host->io_pos < 4 && length) {
  183. host->io_word[0] |= buf[off++] << (host->io_pos * 8);
  184. host->io_pos++;
  185. length--;
  186. }
  187. }
  188. if (host->io_pos == 4
  189. && !(STATUS_FIFO_FULL & readl(host->addr + STATUS))) {
  190. writel(host->io_word[0], host->addr + DATA);
  191. host->io_pos = 0;
  192. host->io_word[0] = 0;
  193. } else if (host->io_pos) {
  194. return off;
  195. }
  196. if (!length)
  197. return off;
  198. while (!(STATUS_FIFO_FULL & readl(host->addr + STATUS))) {
  199. if (length < 4)
  200. break;
  201. __raw_writel(*(unsigned int *)(buf + off),
  202. host->addr + DATA);
  203. length -= 4;
  204. off += 4;
  205. }
  206. switch (length) {
  207. case 3:
  208. host->io_word[0] |= buf[off + 2] << 16;
  209. host->io_pos++;
  210. case 2:
  211. host->io_word[0] |= buf[off + 1] << 8;
  212. host->io_pos++;
  213. case 1:
  214. host->io_word[0] |= buf[off];
  215. host->io_pos++;
  216. }
  217. off += host->io_pos;
  218. return off;
  219. }
  220. static unsigned int jmb38x_ms_write_reg_data(struct jmb38x_ms_host *host,
  221. unsigned char *buf,
  222. unsigned int length)
  223. {
  224. unsigned int off = 0;
  225. while (host->io_pos < 4 && length) {
  226. host->io_word[0] &= ~(0xff << (host->io_pos * 8));
  227. host->io_word[0] |= buf[off++] << (host->io_pos * 8);
  228. host->io_pos++;
  229. length--;
  230. }
  231. if (!length)
  232. return off;
  233. while (host->io_pos < 8 && length) {
  234. host->io_word[1] &= ~(0xff << (host->io_pos * 8));
  235. host->io_word[1] |= buf[off++] << (host->io_pos * 8);
  236. host->io_pos++;
  237. length--;
  238. }
  239. return off;
  240. }
  241. static int jmb38x_ms_transfer_data(struct jmb38x_ms_host *host)
  242. {
  243. unsigned int length;
  244. unsigned int off;
  245. unsigned int t_size, p_cnt;
  246. unsigned char *buf;
  247. struct page *pg;
  248. unsigned long flags = 0;
  249. if (host->req->long_data) {
  250. length = host->req->sg.length - host->block_pos;
  251. off = host->req->sg.offset + host->block_pos;
  252. } else {
  253. length = host->req->data_len - host->block_pos;
  254. off = 0;
  255. }
  256. while (length) {
  257. unsigned int uninitialized_var(p_off);
  258. if (host->req->long_data) {
  259. pg = nth_page(sg_page(&host->req->sg),
  260. off >> PAGE_SHIFT);
  261. p_off = offset_in_page(off);
  262. p_cnt = PAGE_SIZE - p_off;
  263. p_cnt = min(p_cnt, length);
  264. local_irq_save(flags);
  265. buf = kmap_atomic(pg, KM_BIO_SRC_IRQ) + p_off;
  266. } else {
  267. buf = host->req->data + host->block_pos;
  268. p_cnt = host->req->data_len - host->block_pos;
  269. }
  270. if (host->req->data_dir == WRITE)
  271. t_size = !(host->cmd_flags & REG_DATA)
  272. ? jmb38x_ms_write_data(host, buf, p_cnt)
  273. : jmb38x_ms_write_reg_data(host, buf, p_cnt);
  274. else
  275. t_size = !(host->cmd_flags & REG_DATA)
  276. ? jmb38x_ms_read_data(host, buf, p_cnt)
  277. : jmb38x_ms_read_reg_data(host, buf, p_cnt);
  278. if (host->req->long_data) {
  279. kunmap_atomic(buf - p_off, KM_BIO_SRC_IRQ);
  280. local_irq_restore(flags);
  281. }
  282. if (!t_size)
  283. break;
  284. host->block_pos += t_size;
  285. length -= t_size;
  286. off += t_size;
  287. }
  288. if (!length && host->req->data_dir == WRITE) {
  289. if (host->cmd_flags & REG_DATA) {
  290. writel(host->io_word[0], host->addr + TPC_P0);
  291. writel(host->io_word[1], host->addr + TPC_P1);
  292. } else if (host->io_pos) {
  293. writel(host->io_word[0], host->addr + DATA);
  294. }
  295. }
  296. return length;
  297. }
  298. static int jmb38x_ms_issue_cmd(struct memstick_host *msh)
  299. {
  300. struct jmb38x_ms_host *host = memstick_priv(msh);
  301. unsigned char *data;
  302. unsigned int data_len, cmd, t_val;
  303. if (!(STATUS_HAS_MEDIA & readl(host->addr + STATUS))) {
  304. dev_dbg(msh->cdev.dev, "no media status\n");
  305. host->req->error = -ETIME;
  306. return host->req->error;
  307. }
  308. dev_dbg(msh->cdev.dev, "control %08x\n",
  309. readl(host->addr + HOST_CONTROL));
  310. dev_dbg(msh->cdev.dev, "status %08x\n", readl(host->addr + INT_STATUS));
  311. dev_dbg(msh->cdev.dev, "hstatus %08x\n", readl(host->addr + STATUS));
  312. host->cmd_flags = 0;
  313. host->block_pos = 0;
  314. host->io_pos = 0;
  315. host->io_word[0] = 0;
  316. host->io_word[1] = 0;
  317. cmd = host->req->tpc << 16;
  318. cmd |= TPC_DATA_SEL;
  319. if (host->req->data_dir == READ)
  320. cmd |= TPC_DIR;
  321. if (host->req->need_card_int)
  322. cmd |= TPC_WAIT_INT;
  323. data = host->req->data;
  324. if (!no_dma)
  325. host->cmd_flags |= DMA_DATA;
  326. if (host->req->long_data) {
  327. data_len = host->req->sg.length;
  328. } else {
  329. data_len = host->req->data_len;
  330. host->cmd_flags &= ~DMA_DATA;
  331. }
  332. if (data_len <= 8) {
  333. cmd &= ~(TPC_DATA_SEL | 0xf);
  334. host->cmd_flags |= REG_DATA;
  335. cmd |= data_len & 0xf;
  336. host->cmd_flags &= ~DMA_DATA;
  337. }
  338. if (host->cmd_flags & DMA_DATA) {
  339. if (1 != pci_map_sg(host->chip->pdev, &host->req->sg, 1,
  340. host->req->data_dir == READ
  341. ? PCI_DMA_FROMDEVICE
  342. : PCI_DMA_TODEVICE)) {
  343. host->req->error = -ENOMEM;
  344. return host->req->error;
  345. }
  346. data_len = sg_dma_len(&host->req->sg);
  347. writel(sg_dma_address(&host->req->sg),
  348. host->addr + DMA_ADDRESS);
  349. writel(((1 << 16) & BLOCK_COUNT_MASK)
  350. | (data_len & BLOCK_SIZE_MASK),
  351. host->addr + BLOCK);
  352. writel(DMA_CONTROL_ENABLE, host->addr + DMA_CONTROL);
  353. } else if (!(host->cmd_flags & REG_DATA)) {
  354. writel(((1 << 16) & BLOCK_COUNT_MASK)
  355. | (data_len & BLOCK_SIZE_MASK),
  356. host->addr + BLOCK);
  357. t_val = readl(host->addr + INT_STATUS_ENABLE);
  358. t_val |= host->req->data_dir == READ
  359. ? INT_STATUS_FIFO_RRDY
  360. : INT_STATUS_FIFO_WRDY;
  361. writel(t_val, host->addr + INT_STATUS_ENABLE);
  362. writel(t_val, host->addr + INT_SIGNAL_ENABLE);
  363. } else {
  364. cmd &= ~(TPC_DATA_SEL | 0xf);
  365. host->cmd_flags |= REG_DATA;
  366. cmd |= data_len & 0xf;
  367. if (host->req->data_dir == WRITE) {
  368. jmb38x_ms_transfer_data(host);
  369. writel(host->io_word[0], host->addr + TPC_P0);
  370. writel(host->io_word[1], host->addr + TPC_P1);
  371. }
  372. }
  373. mod_timer(&host->timer, jiffies + host->timeout_jiffies);
  374. writel(HOST_CONTROL_LED | readl(host->addr + HOST_CONTROL),
  375. host->addr + HOST_CONTROL);
  376. host->req->error = 0;
  377. writel(cmd, host->addr + TPC);
  378. dev_dbg(msh->cdev.dev, "executing TPC %08x, len %x\n", cmd, data_len);
  379. return 0;
  380. }
  381. static void jmb38x_ms_complete_cmd(struct memstick_host *msh, int last)
  382. {
  383. struct jmb38x_ms_host *host = memstick_priv(msh);
  384. unsigned int t_val = 0;
  385. int rc;
  386. del_timer(&host->timer);
  387. dev_dbg(msh->cdev.dev, "c control %08x\n",
  388. readl(host->addr + HOST_CONTROL));
  389. dev_dbg(msh->cdev.dev, "c status %08x\n",
  390. readl(host->addr + INT_STATUS));
  391. dev_dbg(msh->cdev.dev, "c hstatus %08x\n", readl(host->addr + STATUS));
  392. host->req->int_reg = readl(host->addr + STATUS) & 0xff;
  393. writel(0, host->addr + BLOCK);
  394. writel(0, host->addr + DMA_CONTROL);
  395. if (host->cmd_flags & DMA_DATA) {
  396. pci_unmap_sg(host->chip->pdev, &host->req->sg, 1,
  397. host->req->data_dir == READ
  398. ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
  399. } else {
  400. t_val = readl(host->addr + INT_STATUS_ENABLE);
  401. if (host->req->data_dir == READ)
  402. t_val &= ~INT_STATUS_FIFO_RRDY;
  403. else
  404. t_val &= ~INT_STATUS_FIFO_WRDY;
  405. writel(t_val, host->addr + INT_STATUS_ENABLE);
  406. writel(t_val, host->addr + INT_SIGNAL_ENABLE);
  407. }
  408. writel((~HOST_CONTROL_LED) & readl(host->addr + HOST_CONTROL),
  409. host->addr + HOST_CONTROL);
  410. if (!last) {
  411. do {
  412. rc = memstick_next_req(msh, &host->req);
  413. } while (!rc && jmb38x_ms_issue_cmd(msh));
  414. } else {
  415. do {
  416. rc = memstick_next_req(msh, &host->req);
  417. if (!rc)
  418. host->req->error = -ETIME;
  419. } while (!rc);
  420. }
  421. }
  422. static irqreturn_t jmb38x_ms_isr(int irq, void *dev_id)
  423. {
  424. struct memstick_host *msh = dev_id;
  425. struct jmb38x_ms_host *host = memstick_priv(msh);
  426. unsigned int irq_status;
  427. spin_lock(&host->lock);
  428. irq_status = readl(host->addr + INT_STATUS);
  429. dev_dbg(&host->chip->pdev->dev, "irq_status = %08x\n", irq_status);
  430. if (irq_status == 0 || irq_status == (~0)) {
  431. spin_unlock(&host->lock);
  432. return IRQ_NONE;
  433. }
  434. if (host->req) {
  435. if (irq_status & INT_STATUS_ANY_ERR) {
  436. if (irq_status & INT_STATUS_CRC_ERR)
  437. host->req->error = -EILSEQ;
  438. else
  439. host->req->error = -ETIME;
  440. } else {
  441. if (host->cmd_flags & DMA_DATA) {
  442. if (irq_status & INT_STATUS_EOTRAN)
  443. host->cmd_flags |= FIFO_READY;
  444. } else {
  445. if (irq_status & (INT_STATUS_FIFO_RRDY
  446. | INT_STATUS_FIFO_WRDY))
  447. jmb38x_ms_transfer_data(host);
  448. if (irq_status & INT_STATUS_EOTRAN) {
  449. jmb38x_ms_transfer_data(host);
  450. host->cmd_flags |= FIFO_READY;
  451. }
  452. }
  453. if (irq_status & INT_STATUS_EOTPC) {
  454. host->cmd_flags |= CMD_READY;
  455. if (host->cmd_flags & REG_DATA) {
  456. if (host->req->data_dir == READ) {
  457. host->io_word[0]
  458. = readl(host->addr
  459. + TPC_P0);
  460. host->io_word[1]
  461. = readl(host->addr
  462. + TPC_P1);
  463. host->io_pos = 8;
  464. jmb38x_ms_transfer_data(host);
  465. }
  466. host->cmd_flags |= FIFO_READY;
  467. }
  468. }
  469. }
  470. }
  471. if (irq_status & (INT_STATUS_MEDIA_IN | INT_STATUS_MEDIA_OUT)) {
  472. dev_dbg(&host->chip->pdev->dev, "media changed\n");
  473. memstick_detect_change(msh);
  474. }
  475. writel(irq_status, host->addr + INT_STATUS);
  476. if (host->req
  477. && (((host->cmd_flags & CMD_READY)
  478. && (host->cmd_flags & FIFO_READY))
  479. || host->req->error))
  480. jmb38x_ms_complete_cmd(msh, 0);
  481. spin_unlock(&host->lock);
  482. return IRQ_HANDLED;
  483. }
  484. static void jmb38x_ms_abort(unsigned long data)
  485. {
  486. struct memstick_host *msh = (struct memstick_host *)data;
  487. struct jmb38x_ms_host *host = memstick_priv(msh);
  488. unsigned long flags;
  489. dev_dbg(&host->chip->pdev->dev, "abort\n");
  490. spin_lock_irqsave(&host->lock, flags);
  491. if (host->req) {
  492. host->req->error = -ETIME;
  493. jmb38x_ms_complete_cmd(msh, 0);
  494. }
  495. spin_unlock_irqrestore(&host->lock, flags);
  496. }
  497. static void jmb38x_ms_request(struct memstick_host *msh)
  498. {
  499. struct jmb38x_ms_host *host = memstick_priv(msh);
  500. unsigned long flags;
  501. int rc;
  502. spin_lock_irqsave(&host->lock, flags);
  503. if (host->req) {
  504. spin_unlock_irqrestore(&host->lock, flags);
  505. BUG();
  506. return;
  507. }
  508. do {
  509. rc = memstick_next_req(msh, &host->req);
  510. } while (!rc && jmb38x_ms_issue_cmd(msh));
  511. spin_unlock_irqrestore(&host->lock, flags);
  512. }
  513. static void jmb38x_ms_reset(struct jmb38x_ms_host *host)
  514. {
  515. unsigned int host_ctl = readl(host->addr + HOST_CONTROL);
  516. writel(host_ctl | HOST_CONTROL_RESET_REQ | HOST_CONTROL_RESET,
  517. host->addr + HOST_CONTROL);
  518. while (HOST_CONTROL_RESET_REQ
  519. & (host_ctl = readl(host->addr + HOST_CONTROL))) {
  520. ndelay(100);
  521. dev_dbg(&host->chip->pdev->dev, "reset\n");
  522. }
  523. writel(INT_STATUS_ALL, host->addr + INT_STATUS_ENABLE);
  524. writel(INT_STATUS_ALL, host->addr + INT_SIGNAL_ENABLE);
  525. dev_dbg(&host->chip->pdev->dev, "reset\n");
  526. }
  527. static void jmb38x_ms_set_param(struct memstick_host *msh,
  528. enum memstick_param param,
  529. int value)
  530. {
  531. struct jmb38x_ms_host *host = memstick_priv(msh);
  532. unsigned int host_ctl;
  533. unsigned long flags;
  534. spin_lock_irqsave(&host->lock, flags);
  535. switch (param) {
  536. case MEMSTICK_POWER:
  537. if (value == MEMSTICK_POWER_ON) {
  538. jmb38x_ms_reset(host);
  539. writel(host->id ? PAD_PU_PD_ON_MS_SOCK1
  540. : PAD_PU_PD_ON_MS_SOCK0,
  541. host->addr + PAD_PU_PD);
  542. writel(PAD_OUTPUT_ENABLE_MS,
  543. host->addr + PAD_OUTPUT_ENABLE);
  544. host_ctl = readl(host->addr + HOST_CONTROL);
  545. host_ctl |= 7;
  546. writel(host_ctl | (HOST_CONTROL_POWER_EN
  547. | HOST_CONTROL_CLOCK_EN),
  548. host->addr + HOST_CONTROL);
  549. dev_dbg(&host->chip->pdev->dev, "power on\n");
  550. } else if (value == MEMSTICK_POWER_OFF) {
  551. writel(readl(host->addr + HOST_CONTROL)
  552. & ~(HOST_CONTROL_POWER_EN
  553. | HOST_CONTROL_CLOCK_EN),
  554. host->addr + HOST_CONTROL);
  555. writel(0, host->addr + PAD_OUTPUT_ENABLE);
  556. writel(PAD_PU_PD_OFF, host->addr + PAD_PU_PD);
  557. dev_dbg(&host->chip->pdev->dev, "power off\n");
  558. }
  559. break;
  560. case MEMSTICK_INTERFACE:
  561. /* jmb38x_ms_reset(host); */
  562. host_ctl = readl(host->addr + HOST_CONTROL);
  563. host_ctl &= ~(3 << HOST_CONTROL_IF_SHIFT);
  564. /* host_ctl |= 7; */
  565. if (value == MEMSTICK_SERIAL) {
  566. host_ctl &= ~HOST_CONTROL_FAST_CLK;
  567. host_ctl |= HOST_CONTROL_IF_SERIAL
  568. << HOST_CONTROL_IF_SHIFT;
  569. host_ctl |= HOST_CONTROL_REI;
  570. writel(0, host->addr + CLOCK_DELAY);
  571. } else if (value == MEMSTICK_PAR4) {
  572. host_ctl |= HOST_CONTROL_FAST_CLK;
  573. host_ctl |= HOST_CONTROL_IF_PAR4
  574. << HOST_CONTROL_IF_SHIFT;
  575. host_ctl &= ~HOST_CONTROL_REI;
  576. writel(4, host->addr + CLOCK_DELAY);
  577. } else if (value == MEMSTICK_PAR8) {
  578. host_ctl |= HOST_CONTROL_FAST_CLK;
  579. host_ctl |= HOST_CONTROL_IF_PAR8
  580. << HOST_CONTROL_IF_SHIFT;
  581. host_ctl &= ~HOST_CONTROL_REI;
  582. writel(4, host->addr + CLOCK_DELAY);
  583. }
  584. writel(host_ctl, host->addr + HOST_CONTROL);
  585. break;
  586. };
  587. spin_unlock_irqrestore(&host->lock, flags);
  588. }
  589. #ifdef CONFIG_PM
  590. static int jmb38x_ms_suspend(struct pci_dev *dev, pm_message_t state)
  591. {
  592. struct jmb38x_ms *jm = pci_get_drvdata(dev);
  593. int cnt;
  594. for (cnt = 0; cnt < jm->host_cnt; ++cnt) {
  595. if (!jm->hosts[cnt])
  596. break;
  597. memstick_suspend_host(jm->hosts[cnt]);
  598. }
  599. pci_save_state(dev);
  600. pci_enable_wake(dev, pci_choose_state(dev, state), 0);
  601. pci_disable_device(dev);
  602. pci_set_power_state(dev, pci_choose_state(dev, state));
  603. return 0;
  604. }
  605. static int jmb38x_ms_resume(struct pci_dev *dev)
  606. {
  607. struct jmb38x_ms *jm = pci_get_drvdata(dev);
  608. int rc;
  609. pci_set_power_state(dev, PCI_D0);
  610. pci_restore_state(dev);
  611. rc = pci_enable_device(dev);
  612. if (rc)
  613. return rc;
  614. pci_set_master(dev);
  615. pci_read_config_dword(dev, 0xac, &rc);
  616. pci_write_config_dword(dev, 0xac, rc | 0x00470000);
  617. for (rc = 0; rc < jm->host_cnt; ++rc) {
  618. if (!jm->hosts[rc])
  619. break;
  620. memstick_resume_host(jm->hosts[rc]);
  621. memstick_detect_change(jm->hosts[rc]);
  622. }
  623. return 0;
  624. }
  625. #else
  626. #define jmb38x_ms_suspend NULL
  627. #define jmb38x_ms_resume NULL
  628. #endif /* CONFIG_PM */
  629. static int jmb38x_ms_count_slots(struct pci_dev *pdev)
  630. {
  631. int cnt, rc = 0;
  632. for (cnt = 0; cnt < PCI_ROM_RESOURCE; ++cnt) {
  633. if (!(IORESOURCE_MEM & pci_resource_flags(pdev, cnt)))
  634. break;
  635. if (256 != pci_resource_len(pdev, cnt))
  636. break;
  637. ++rc;
  638. }
  639. return rc;
  640. }
  641. static struct memstick_host *jmb38x_ms_alloc_host(struct jmb38x_ms *jm, int cnt)
  642. {
  643. struct memstick_host *msh;
  644. struct jmb38x_ms_host *host;
  645. msh = memstick_alloc_host(sizeof(struct jmb38x_ms_host),
  646. &jm->pdev->dev);
  647. if (!msh)
  648. return NULL;
  649. host = memstick_priv(msh);
  650. host->chip = jm;
  651. host->addr = ioremap(pci_resource_start(jm->pdev, cnt),
  652. pci_resource_len(jm->pdev, cnt));
  653. if (!host->addr)
  654. goto err_out_free;
  655. spin_lock_init(&host->lock);
  656. host->id = cnt;
  657. snprintf(host->host_id, DEVICE_ID_SIZE, DRIVER_NAME ":slot%d",
  658. host->id);
  659. host->irq = jm->pdev->irq;
  660. host->timeout_jiffies = msecs_to_jiffies(1000);
  661. msh->request = jmb38x_ms_request;
  662. msh->set_param = jmb38x_ms_set_param;
  663. msh->caps = MEMSTICK_CAP_PAR4 | MEMSTICK_CAP_PAR8;
  664. setup_timer(&host->timer, jmb38x_ms_abort, (unsigned long)msh);
  665. if (!request_irq(host->irq, jmb38x_ms_isr, IRQF_SHARED, host->host_id,
  666. msh))
  667. return msh;
  668. iounmap(host->addr);
  669. err_out_free:
  670. kfree(msh);
  671. return NULL;
  672. }
  673. static void jmb38x_ms_free_host(struct memstick_host *msh)
  674. {
  675. struct jmb38x_ms_host *host = memstick_priv(msh);
  676. free_irq(host->irq, msh);
  677. iounmap(host->addr);
  678. memstick_free_host(msh);
  679. }
  680. static int jmb38x_ms_probe(struct pci_dev *pdev,
  681. const struct pci_device_id *dev_id)
  682. {
  683. struct jmb38x_ms *jm;
  684. int pci_dev_busy = 0;
  685. int rc, cnt;
  686. rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
  687. if (rc)
  688. return rc;
  689. rc = pci_enable_device(pdev);
  690. if (rc)
  691. return rc;
  692. pci_set_master(pdev);
  693. rc = pci_request_regions(pdev, DRIVER_NAME);
  694. if (rc) {
  695. pci_dev_busy = 1;
  696. goto err_out;
  697. }
  698. pci_read_config_dword(pdev, 0xac, &rc);
  699. pci_write_config_dword(pdev, 0xac, rc | 0x00470000);
  700. cnt = jmb38x_ms_count_slots(pdev);
  701. if (!cnt) {
  702. rc = -ENODEV;
  703. pci_dev_busy = 1;
  704. goto err_out;
  705. }
  706. jm = kzalloc(sizeof(struct jmb38x_ms)
  707. + cnt * sizeof(struct memstick_host *), GFP_KERNEL);
  708. if (!jm) {
  709. rc = -ENOMEM;
  710. goto err_out_int;
  711. }
  712. jm->pdev = pdev;
  713. jm->host_cnt = cnt;
  714. pci_set_drvdata(pdev, jm);
  715. for (cnt = 0; cnt < jm->host_cnt; ++cnt) {
  716. jm->hosts[cnt] = jmb38x_ms_alloc_host(jm, cnt);
  717. if (!jm->hosts[cnt])
  718. break;
  719. rc = memstick_add_host(jm->hosts[cnt]);
  720. if (rc) {
  721. jmb38x_ms_free_host(jm->hosts[cnt]);
  722. jm->hosts[cnt] = NULL;
  723. break;
  724. }
  725. }
  726. if (cnt)
  727. return 0;
  728. rc = -ENODEV;
  729. pci_set_drvdata(pdev, NULL);
  730. kfree(jm);
  731. err_out_int:
  732. pci_release_regions(pdev);
  733. err_out:
  734. if (!pci_dev_busy)
  735. pci_disable_device(pdev);
  736. return rc;
  737. }
  738. static void jmb38x_ms_remove(struct pci_dev *dev)
  739. {
  740. struct jmb38x_ms *jm = pci_get_drvdata(dev);
  741. struct jmb38x_ms_host *host;
  742. int cnt;
  743. unsigned long flags;
  744. for (cnt = 0; cnt < jm->host_cnt; ++cnt) {
  745. if (!jm->hosts[cnt])
  746. break;
  747. host = memstick_priv(jm->hosts[cnt]);
  748. writel(0, host->addr + INT_SIGNAL_ENABLE);
  749. writel(0, host->addr + INT_STATUS_ENABLE);
  750. mmiowb();
  751. dev_dbg(&jm->pdev->dev, "interrupts off\n");
  752. spin_lock_irqsave(&host->lock, flags);
  753. if (host->req) {
  754. host->req->error = -ETIME;
  755. jmb38x_ms_complete_cmd(jm->hosts[cnt], 1);
  756. }
  757. spin_unlock_irqrestore(&host->lock, flags);
  758. memstick_remove_host(jm->hosts[cnt]);
  759. dev_dbg(&jm->pdev->dev, "host removed\n");
  760. jmb38x_ms_free_host(jm->hosts[cnt]);
  761. }
  762. pci_set_drvdata(dev, NULL);
  763. pci_release_regions(dev);
  764. pci_disable_device(dev);
  765. kfree(jm);
  766. }
  767. static struct pci_device_id jmb38x_ms_id_tbl [] = {
  768. { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_MS, PCI_ANY_ID,
  769. PCI_ANY_ID, 0, 0, 0 },
  770. { }
  771. };
  772. static struct pci_driver jmb38x_ms_driver = {
  773. .name = DRIVER_NAME,
  774. .id_table = jmb38x_ms_id_tbl,
  775. .probe = jmb38x_ms_probe,
  776. .remove = jmb38x_ms_remove,
  777. .suspend = jmb38x_ms_suspend,
  778. .resume = jmb38x_ms_resume
  779. };
  780. static int __init jmb38x_ms_init(void)
  781. {
  782. return pci_register_driver(&jmb38x_ms_driver);
  783. }
  784. static void __exit jmb38x_ms_exit(void)
  785. {
  786. pci_unregister_driver(&jmb38x_ms_driver);
  787. }
  788. MODULE_AUTHOR("Alex Dubov");
  789. MODULE_DESCRIPTION("JMicron jmb38x MemoryStick driver");
  790. MODULE_LICENSE("GPL");
  791. MODULE_DEVICE_TABLE(pci, jmb38x_ms_id_tbl);
  792. module_init(jmb38x_ms_init);
  793. module_exit(jmb38x_ms_exit);