jmb38x_ms.c 24 KB

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