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