jmb38x_ms.c 26 KB

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