axis-fifo.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Xilinx AXIS FIFO: interface to the Xilinx AXI-Stream FIFO IP core
  4. *
  5. * Copyright (C) 2018 Jacob Feder
  6. *
  7. * Authors: Jacob Feder <jacobsfeder@gmail.com>
  8. *
  9. * See Xilinx PG080 document for IP details
  10. */
  11. /* ----------------------------
  12. * includes
  13. * ----------------------------
  14. */
  15. #include <linux/kernel.h>
  16. #include <linux/wait.h>
  17. #include <linux/mutex.h>
  18. #include <linux/device.h>
  19. #include <linux/cdev.h>
  20. #include <linux/init.h>
  21. #include <linux/module.h>
  22. #include <linux/slab.h>
  23. #include <linux/io.h>
  24. #include <linux/moduleparam.h>
  25. #include <linux/interrupt.h>
  26. #include <linux/param.h>
  27. #include <linux/fs.h>
  28. #include <linux/types.h>
  29. #include <linux/uaccess.h>
  30. #include <linux/jiffies.h>
  31. #include <linux/of_address.h>
  32. #include <linux/of_device.h>
  33. #include <linux/of_platform.h>
  34. /* ----------------------------
  35. * driver parameters
  36. * ----------------------------
  37. */
  38. #define DRIVER_NAME "axis_fifo"
  39. #define READ_BUF_SIZE 128U /* read buffer length in words */
  40. #define WRITE_BUF_SIZE 128U /* write buffer length in words */
  41. /* ----------------------------
  42. * IP register offsets
  43. * ----------------------------
  44. */
  45. #define XLLF_ISR_OFFSET 0x00000000 /* Interrupt Status */
  46. #define XLLF_IER_OFFSET 0x00000004 /* Interrupt Enable */
  47. #define XLLF_TDFR_OFFSET 0x00000008 /* Transmit Reset */
  48. #define XLLF_TDFV_OFFSET 0x0000000c /* Transmit Vacancy */
  49. #define XLLF_TDFD_OFFSET 0x00000010 /* Transmit Data */
  50. #define XLLF_TLR_OFFSET 0x00000014 /* Transmit Length */
  51. #define XLLF_RDFR_OFFSET 0x00000018 /* Receive Reset */
  52. #define XLLF_RDFO_OFFSET 0x0000001c /* Receive Occupancy */
  53. #define XLLF_RDFD_OFFSET 0x00000020 /* Receive Data */
  54. #define XLLF_RLR_OFFSET 0x00000024 /* Receive Length */
  55. #define XLLF_SRR_OFFSET 0x00000028 /* Local Link Reset */
  56. #define XLLF_TDR_OFFSET 0x0000002C /* Transmit Destination */
  57. #define XLLF_RDR_OFFSET 0x00000030 /* Receive Destination */
  58. /* ----------------------------
  59. * reset register masks
  60. * ----------------------------
  61. */
  62. #define XLLF_RDFR_RESET_MASK 0x000000a5 /* receive reset value */
  63. #define XLLF_TDFR_RESET_MASK 0x000000a5 /* Transmit reset value */
  64. #define XLLF_SRR_RESET_MASK 0x000000a5 /* Local Link reset value */
  65. /* ----------------------------
  66. * interrupt masks
  67. * ----------------------------
  68. */
  69. #define XLLF_INT_RPURE_MASK 0x80000000 /* Receive under-read */
  70. #define XLLF_INT_RPORE_MASK 0x40000000 /* Receive over-read */
  71. #define XLLF_INT_RPUE_MASK 0x20000000 /* Receive underrun (empty) */
  72. #define XLLF_INT_TPOE_MASK 0x10000000 /* Transmit overrun */
  73. #define XLLF_INT_TC_MASK 0x08000000 /* Transmit complete */
  74. #define XLLF_INT_RC_MASK 0x04000000 /* Receive complete */
  75. #define XLLF_INT_TSE_MASK 0x02000000 /* Transmit length mismatch */
  76. #define XLLF_INT_TRC_MASK 0x01000000 /* Transmit reset complete */
  77. #define XLLF_INT_RRC_MASK 0x00800000 /* Receive reset complete */
  78. #define XLLF_INT_TFPF_MASK 0x00400000 /* Tx FIFO Programmable Full */
  79. #define XLLF_INT_TFPE_MASK 0x00200000 /* Tx FIFO Programmable Empty */
  80. #define XLLF_INT_RFPF_MASK 0x00100000 /* Rx FIFO Programmable Full */
  81. #define XLLF_INT_RFPE_MASK 0x00080000 /* Rx FIFO Programmable Empty */
  82. #define XLLF_INT_ALL_MASK 0xfff80000 /* All the ints */
  83. #define XLLF_INT_ERROR_MASK 0xf2000000 /* Error status ints */
  84. #define XLLF_INT_RXERROR_MASK 0xe0000000 /* Receive Error status ints */
  85. #define XLLF_INT_TXERROR_MASK 0x12000000 /* Transmit Error status ints */
  86. /* ----------------------------
  87. * globals
  88. * ----------------------------
  89. */
  90. static struct class *axis_fifo_driver_class; /* char device class */
  91. static int read_timeout = 1000; /* ms to wait before read() times out */
  92. static int write_timeout = 1000; /* ms to wait before write() times out */
  93. /* ----------------------------
  94. * module command-line arguments
  95. * ----------------------------
  96. */
  97. module_param(read_timeout, int, 0444);
  98. MODULE_PARM_DESC(read_timeout, "ms to wait before blocking read() timing out; set to -1 for no timeout");
  99. module_param(write_timeout, int, 0444);
  100. MODULE_PARM_DESC(write_timeout, "ms to wait before blocking write() timing out; set to -1 for no timeout");
  101. /* ----------------------------
  102. * types
  103. * ----------------------------
  104. */
  105. struct axis_fifo {
  106. int irq; /* interrupt */
  107. void __iomem *base_addr; /* kernel space memory */
  108. unsigned int rx_fifo_depth; /* max words in the receive fifo */
  109. unsigned int tx_fifo_depth; /* max words in the transmit fifo */
  110. int has_rx_fifo; /* whether the IP has the rx fifo enabled */
  111. int has_tx_fifo; /* whether the IP has the tx fifo enabled */
  112. wait_queue_head_t read_queue; /* wait queue for asynchronos read */
  113. struct mutex read_lock; /* lock for reading */
  114. wait_queue_head_t write_queue; /* wait queue for asynchronos write */
  115. struct mutex write_lock; /* lock for writing */
  116. unsigned int write_flags; /* write file flags */
  117. unsigned int read_flags; /* read file flags */
  118. struct device *dt_device; /* device created from the device tree */
  119. struct device *device; /* device associated with char_device */
  120. dev_t devt; /* our char device number */
  121. struct cdev char_device; /* our char device */
  122. };
  123. /* ----------------------------
  124. * sysfs entries
  125. * ----------------------------
  126. */
  127. static ssize_t sysfs_write(struct device *dev, const char *buf,
  128. size_t count, unsigned int addr_offset)
  129. {
  130. struct axis_fifo *fifo = dev_get_drvdata(dev);
  131. unsigned long tmp;
  132. int rc;
  133. rc = kstrtoul(buf, 0, &tmp);
  134. if (rc < 0)
  135. return rc;
  136. iowrite32(tmp, fifo->base_addr + addr_offset);
  137. return count;
  138. }
  139. static ssize_t sysfs_read(struct device *dev, char *buf,
  140. unsigned int addr_offset)
  141. {
  142. struct axis_fifo *fifo = dev_get_drvdata(dev);
  143. unsigned int read_val;
  144. unsigned int len;
  145. char tmp[32];
  146. read_val = ioread32(fifo->base_addr + addr_offset);
  147. len = snprintf(tmp, sizeof(tmp), "0x%x\n", read_val);
  148. memcpy(buf, tmp, len);
  149. return len;
  150. }
  151. static ssize_t isr_store(struct device *dev, struct device_attribute *attr,
  152. const char *buf, size_t count)
  153. {
  154. return sysfs_write(dev, buf, count, XLLF_ISR_OFFSET);
  155. }
  156. static ssize_t isr_show(struct device *dev,
  157. struct device_attribute *attr, char *buf)
  158. {
  159. return sysfs_read(dev, buf, XLLF_ISR_OFFSET);
  160. }
  161. static DEVICE_ATTR_RW(isr);
  162. static ssize_t ier_store(struct device *dev, struct device_attribute *attr,
  163. const char *buf, size_t count)
  164. {
  165. return sysfs_write(dev, buf, count, XLLF_IER_OFFSET);
  166. }
  167. static ssize_t ier_show(struct device *dev,
  168. struct device_attribute *attr, char *buf)
  169. {
  170. return sysfs_read(dev, buf, XLLF_IER_OFFSET);
  171. }
  172. static DEVICE_ATTR_RW(ier);
  173. static ssize_t tdfr_store(struct device *dev, struct device_attribute *attr,
  174. const char *buf, size_t count)
  175. {
  176. return sysfs_write(dev, buf, count, XLLF_TDFR_OFFSET);
  177. }
  178. static DEVICE_ATTR_WO(tdfr);
  179. static ssize_t tdfv_show(struct device *dev,
  180. struct device_attribute *attr, char *buf)
  181. {
  182. return sysfs_read(dev, buf, XLLF_TDFV_OFFSET);
  183. }
  184. static DEVICE_ATTR_RO(tdfv);
  185. static ssize_t tdfd_store(struct device *dev, struct device_attribute *attr,
  186. const char *buf, size_t count)
  187. {
  188. return sysfs_write(dev, buf, count, XLLF_TDFD_OFFSET);
  189. }
  190. static DEVICE_ATTR_WO(tdfd);
  191. static ssize_t tlr_store(struct device *dev, struct device_attribute *attr,
  192. const char *buf, size_t count)
  193. {
  194. return sysfs_write(dev, buf, count, XLLF_TLR_OFFSET);
  195. }
  196. static DEVICE_ATTR_WO(tlr);
  197. static ssize_t rdfr_store(struct device *dev, struct device_attribute *attr,
  198. const char *buf, size_t count)
  199. {
  200. return sysfs_write(dev, buf, count, XLLF_RDFR_OFFSET);
  201. }
  202. static DEVICE_ATTR_WO(rdfr);
  203. static ssize_t rdfo_show(struct device *dev,
  204. struct device_attribute *attr, char *buf)
  205. {
  206. return sysfs_read(dev, buf, XLLF_RDFO_OFFSET);
  207. }
  208. static DEVICE_ATTR_RO(rdfo);
  209. static ssize_t rdfd_show(struct device *dev,
  210. struct device_attribute *attr, char *buf)
  211. {
  212. return sysfs_read(dev, buf, XLLF_RDFD_OFFSET);
  213. }
  214. static DEVICE_ATTR_RO(rdfd);
  215. static ssize_t rlr_show(struct device *dev,
  216. struct device_attribute *attr, char *buf)
  217. {
  218. return sysfs_read(dev, buf, XLLF_RLR_OFFSET);
  219. }
  220. static DEVICE_ATTR_RO(rlr);
  221. static ssize_t srr_store(struct device *dev, struct device_attribute *attr,
  222. const char *buf, size_t count)
  223. {
  224. return sysfs_write(dev, buf, count, XLLF_SRR_OFFSET);
  225. }
  226. static DEVICE_ATTR_WO(srr);
  227. static ssize_t tdr_store(struct device *dev, struct device_attribute *attr,
  228. const char *buf, size_t count)
  229. {
  230. return sysfs_write(dev, buf, count, XLLF_TDR_OFFSET);
  231. }
  232. static DEVICE_ATTR_WO(tdr);
  233. static ssize_t rdr_show(struct device *dev,
  234. struct device_attribute *attr, char *buf)
  235. {
  236. return sysfs_read(dev, buf, XLLF_RDR_OFFSET);
  237. }
  238. static DEVICE_ATTR_RO(rdr);
  239. static struct attribute *axis_fifo_attrs[] = {
  240. &dev_attr_isr.attr,
  241. &dev_attr_ier.attr,
  242. &dev_attr_tdfr.attr,
  243. &dev_attr_tdfv.attr,
  244. &dev_attr_tdfd.attr,
  245. &dev_attr_tlr.attr,
  246. &dev_attr_rdfr.attr,
  247. &dev_attr_rdfo.attr,
  248. &dev_attr_rdfd.attr,
  249. &dev_attr_rlr.attr,
  250. &dev_attr_srr.attr,
  251. &dev_attr_tdr.attr,
  252. &dev_attr_rdr.attr,
  253. NULL,
  254. };
  255. static const struct attribute_group axis_fifo_attrs_group = {
  256. .name = "ip_registers",
  257. .attrs = axis_fifo_attrs,
  258. };
  259. /* ----------------------------
  260. * implementation
  261. * ----------------------------
  262. */
  263. static void reset_ip_core(struct axis_fifo *fifo)
  264. {
  265. iowrite32(XLLF_SRR_RESET_MASK, fifo->base_addr + XLLF_SRR_OFFSET);
  266. iowrite32(XLLF_TDFR_RESET_MASK, fifo->base_addr + XLLF_TDFR_OFFSET);
  267. iowrite32(XLLF_RDFR_RESET_MASK, fifo->base_addr + XLLF_RDFR_OFFSET);
  268. iowrite32(XLLF_INT_TC_MASK | XLLF_INT_RC_MASK | XLLF_INT_RPURE_MASK |
  269. XLLF_INT_RPORE_MASK | XLLF_INT_RPUE_MASK |
  270. XLLF_INT_TPOE_MASK | XLLF_INT_TSE_MASK,
  271. fifo->base_addr + XLLF_IER_OFFSET);
  272. iowrite32(XLLF_INT_ALL_MASK, fifo->base_addr + XLLF_ISR_OFFSET);
  273. }
  274. /**
  275. * axis_fifo_write() - Read a packet from AXIS-FIFO character device.
  276. * @f Open file.
  277. * @buf User space buffer to read to.
  278. * @len User space buffer length.
  279. * @off Buffer offset.
  280. *
  281. * As defined by the device's documentation, we need to check the device's
  282. * occupancy before reading the length register and then the data. All these
  283. * operations must be executed atomically, in order and one after the other
  284. * without missing any.
  285. *
  286. * Returns the number of bytes read from the device or negative error code
  287. * on failure.
  288. */
  289. static ssize_t axis_fifo_read(struct file *f, char __user *buf,
  290. size_t len, loff_t *off)
  291. {
  292. struct axis_fifo *fifo = (struct axis_fifo *)f->private_data;
  293. size_t bytes_available;
  294. unsigned int words_available;
  295. unsigned int copied;
  296. unsigned int copy;
  297. unsigned int i;
  298. int ret;
  299. u32 tmp_buf[READ_BUF_SIZE];
  300. if (fifo->read_flags & O_NONBLOCK) {
  301. /*
  302. * Device opened in non-blocking mode. Try to lock it and then
  303. * check if any packet is available.
  304. */
  305. if (!mutex_trylock(&fifo->read_lock))
  306. return -EAGAIN;
  307. if (!ioread32(fifo->base_addr + XLLF_RDFO_OFFSET)) {
  308. ret = -EAGAIN;
  309. goto end_unlock;
  310. }
  311. } else {
  312. /* opened in blocking mode
  313. * wait for a packet available interrupt (or timeout)
  314. * if nothing is currently available
  315. */
  316. mutex_lock(&fifo->read_lock);
  317. ret = wait_event_interruptible_timeout(fifo->read_queue,
  318. ioread32(fifo->base_addr + XLLF_RDFO_OFFSET),
  319. (read_timeout >= 0) ?
  320. msecs_to_jiffies(read_timeout) :
  321. MAX_SCHEDULE_TIMEOUT);
  322. if (ret <= 0) {
  323. if (ret == 0) {
  324. ret = -EAGAIN;
  325. } else if (ret != -ERESTARTSYS) {
  326. dev_err(fifo->dt_device, "wait_event_interruptible_timeout() error in read (ret=%i)\n",
  327. ret);
  328. }
  329. goto end_unlock;
  330. }
  331. }
  332. bytes_available = ioread32(fifo->base_addr + XLLF_RLR_OFFSET);
  333. if (!bytes_available) {
  334. dev_err(fifo->dt_device, "received a packet of length 0 - fifo core will be reset\n");
  335. reset_ip_core(fifo);
  336. ret = -EIO;
  337. goto end_unlock;
  338. }
  339. if (bytes_available > len) {
  340. dev_err(fifo->dt_device, "user read buffer too small (available bytes=%zu user buffer bytes=%zu) - fifo core will be reset\n",
  341. bytes_available, len);
  342. reset_ip_core(fifo);
  343. ret = -EINVAL;
  344. goto end_unlock;
  345. }
  346. if (bytes_available % sizeof(u32)) {
  347. /* this probably can't happen unless IP
  348. * registers were previously mishandled
  349. */
  350. dev_err(fifo->dt_device, "received a packet that isn't word-aligned - fifo core will be reset\n");
  351. reset_ip_core(fifo);
  352. ret = -EIO;
  353. goto end_unlock;
  354. }
  355. words_available = bytes_available / sizeof(u32);
  356. /* read data into an intermediate buffer, copying the contents
  357. * to userspace when the buffer is full
  358. */
  359. copied = 0;
  360. while (words_available > 0) {
  361. copy = min(words_available, READ_BUF_SIZE);
  362. for (i = 0; i < copy; i++) {
  363. tmp_buf[i] = ioread32(fifo->base_addr +
  364. XLLF_RDFD_OFFSET);
  365. }
  366. if (copy_to_user(buf + copied * sizeof(u32), tmp_buf,
  367. copy * sizeof(u32))) {
  368. reset_ip_core(fifo);
  369. ret = -EFAULT;
  370. goto end_unlock;
  371. }
  372. copied += copy;
  373. words_available -= copy;
  374. }
  375. ret = bytes_available;
  376. end_unlock:
  377. mutex_unlock(&fifo->read_lock);
  378. return ret;
  379. }
  380. /**
  381. * axis_fifo_write() - Write buffer to AXIS-FIFO character device.
  382. * @f Open file.
  383. * @buf User space buffer to write to the device.
  384. * @len User space buffer length.
  385. * @off Buffer offset.
  386. *
  387. * As defined by the device's documentation, we need to write to the device's
  388. * data buffer then to the device's packet length register atomically. Also,
  389. * we need to lock before checking if the device has available space to avoid
  390. * any concurrency issue.
  391. *
  392. * Returns the number of bytes written to the device or negative error code
  393. * on failure.
  394. */
  395. static ssize_t axis_fifo_write(struct file *f, const char __user *buf,
  396. size_t len, loff_t *off)
  397. {
  398. struct axis_fifo *fifo = (struct axis_fifo *)f->private_data;
  399. unsigned int words_to_write;
  400. unsigned int copied;
  401. unsigned int copy;
  402. unsigned int i;
  403. int ret;
  404. u32 tmp_buf[WRITE_BUF_SIZE];
  405. if (len % sizeof(u32)) {
  406. dev_err(fifo->dt_device,
  407. "tried to send a packet that isn't word-aligned\n");
  408. return -EINVAL;
  409. }
  410. words_to_write = len / sizeof(u32);
  411. if (!words_to_write) {
  412. dev_err(fifo->dt_device,
  413. "tried to send a packet of length 0\n");
  414. return -EINVAL;
  415. }
  416. if (words_to_write > fifo->tx_fifo_depth) {
  417. dev_err(fifo->dt_device, "tried to write more words [%u] than slots in the fifo buffer [%u]\n",
  418. words_to_write, fifo->tx_fifo_depth);
  419. return -EINVAL;
  420. }
  421. if (fifo->write_flags & O_NONBLOCK) {
  422. /*
  423. * Device opened in non-blocking mode. Try to lock it and then
  424. * check if there is any room to write the given buffer.
  425. */
  426. if (!mutex_trylock(&fifo->write_lock))
  427. return -EAGAIN;
  428. if (words_to_write > ioread32(fifo->base_addr +
  429. XLLF_TDFV_OFFSET)) {
  430. ret = -EAGAIN;
  431. goto end_unlock;
  432. }
  433. } else {
  434. /* opened in blocking mode */
  435. /* wait for an interrupt (or timeout) if there isn't
  436. * currently enough room in the fifo
  437. */
  438. mutex_lock(&fifo->write_lock);
  439. ret = wait_event_interruptible_timeout(fifo->write_queue,
  440. ioread32(fifo->base_addr + XLLF_TDFV_OFFSET)
  441. >= words_to_write,
  442. (write_timeout >= 0) ?
  443. msecs_to_jiffies(write_timeout) :
  444. MAX_SCHEDULE_TIMEOUT);
  445. if (ret <= 0) {
  446. if (ret == 0) {
  447. ret = -EAGAIN;
  448. } else if (ret != -ERESTARTSYS) {
  449. dev_err(fifo->dt_device, "wait_event_interruptible_timeout() error in write (ret=%i)\n",
  450. ret);
  451. }
  452. goto end_unlock;
  453. }
  454. }
  455. /* write data from an intermediate buffer into the fifo IP, refilling
  456. * the buffer with userspace data as needed
  457. */
  458. copied = 0;
  459. while (words_to_write > 0) {
  460. copy = min(words_to_write, WRITE_BUF_SIZE);
  461. if (copy_from_user(tmp_buf, buf + copied * sizeof(u32),
  462. copy * sizeof(u32))) {
  463. reset_ip_core(fifo);
  464. ret = -EFAULT;
  465. goto end_unlock;
  466. }
  467. for (i = 0; i < copy; i++)
  468. iowrite32(tmp_buf[i], fifo->base_addr +
  469. XLLF_TDFD_OFFSET);
  470. copied += copy;
  471. words_to_write -= copy;
  472. }
  473. ret = copied * sizeof(u32);
  474. /* write packet size to fifo */
  475. iowrite32(ret, fifo->base_addr + XLLF_TLR_OFFSET);
  476. end_unlock:
  477. mutex_unlock(&fifo->write_lock);
  478. return ret;
  479. }
  480. static irqreturn_t axis_fifo_irq(int irq, void *dw)
  481. {
  482. struct axis_fifo *fifo = (struct axis_fifo *)dw;
  483. unsigned int pending_interrupts;
  484. do {
  485. pending_interrupts = ioread32(fifo->base_addr +
  486. XLLF_IER_OFFSET) &
  487. ioread32(fifo->base_addr
  488. + XLLF_ISR_OFFSET);
  489. if (pending_interrupts & XLLF_INT_RC_MASK) {
  490. /* packet received */
  491. /* wake the reader process if it is waiting */
  492. wake_up(&fifo->read_queue);
  493. /* clear interrupt */
  494. iowrite32(XLLF_INT_RC_MASK & XLLF_INT_ALL_MASK,
  495. fifo->base_addr + XLLF_ISR_OFFSET);
  496. } else if (pending_interrupts & XLLF_INT_TC_MASK) {
  497. /* packet sent */
  498. /* wake the writer process if it is waiting */
  499. wake_up(&fifo->write_queue);
  500. iowrite32(XLLF_INT_TC_MASK & XLLF_INT_ALL_MASK,
  501. fifo->base_addr + XLLF_ISR_OFFSET);
  502. } else if (pending_interrupts & XLLF_INT_TFPF_MASK) {
  503. /* transmit fifo programmable full */
  504. iowrite32(XLLF_INT_TFPF_MASK & XLLF_INT_ALL_MASK,
  505. fifo->base_addr + XLLF_ISR_OFFSET);
  506. } else if (pending_interrupts & XLLF_INT_TFPE_MASK) {
  507. /* transmit fifo programmable empty */
  508. iowrite32(XLLF_INT_TFPE_MASK & XLLF_INT_ALL_MASK,
  509. fifo->base_addr + XLLF_ISR_OFFSET);
  510. } else if (pending_interrupts & XLLF_INT_RFPF_MASK) {
  511. /* receive fifo programmable full */
  512. iowrite32(XLLF_INT_RFPF_MASK & XLLF_INT_ALL_MASK,
  513. fifo->base_addr + XLLF_ISR_OFFSET);
  514. } else if (pending_interrupts & XLLF_INT_RFPE_MASK) {
  515. /* receive fifo programmable empty */
  516. iowrite32(XLLF_INT_RFPE_MASK & XLLF_INT_ALL_MASK,
  517. fifo->base_addr + XLLF_ISR_OFFSET);
  518. } else if (pending_interrupts & XLLF_INT_TRC_MASK) {
  519. /* transmit reset complete interrupt */
  520. iowrite32(XLLF_INT_TRC_MASK & XLLF_INT_ALL_MASK,
  521. fifo->base_addr + XLLF_ISR_OFFSET);
  522. } else if (pending_interrupts & XLLF_INT_RRC_MASK) {
  523. /* receive reset complete interrupt */
  524. iowrite32(XLLF_INT_RRC_MASK & XLLF_INT_ALL_MASK,
  525. fifo->base_addr + XLLF_ISR_OFFSET);
  526. } else if (pending_interrupts & XLLF_INT_RPURE_MASK) {
  527. /* receive fifo under-read error interrupt */
  528. dev_err(fifo->dt_device,
  529. "receive under-read interrupt\n");
  530. iowrite32(XLLF_INT_RPURE_MASK & XLLF_INT_ALL_MASK,
  531. fifo->base_addr + XLLF_ISR_OFFSET);
  532. } else if (pending_interrupts & XLLF_INT_RPORE_MASK) {
  533. /* receive over-read error interrupt */
  534. dev_err(fifo->dt_device,
  535. "receive over-read interrupt\n");
  536. iowrite32(XLLF_INT_RPORE_MASK & XLLF_INT_ALL_MASK,
  537. fifo->base_addr + XLLF_ISR_OFFSET);
  538. } else if (pending_interrupts & XLLF_INT_RPUE_MASK) {
  539. /* receive underrun error interrupt */
  540. dev_err(fifo->dt_device,
  541. "receive underrun error interrupt\n");
  542. iowrite32(XLLF_INT_RPUE_MASK & XLLF_INT_ALL_MASK,
  543. fifo->base_addr + XLLF_ISR_OFFSET);
  544. } else if (pending_interrupts & XLLF_INT_TPOE_MASK) {
  545. /* transmit overrun error interrupt */
  546. dev_err(fifo->dt_device,
  547. "transmit overrun error interrupt\n");
  548. iowrite32(XLLF_INT_TPOE_MASK & XLLF_INT_ALL_MASK,
  549. fifo->base_addr + XLLF_ISR_OFFSET);
  550. } else if (pending_interrupts & XLLF_INT_TSE_MASK) {
  551. /* transmit length mismatch error interrupt */
  552. dev_err(fifo->dt_device,
  553. "transmit length mismatch error interrupt\n");
  554. iowrite32(XLLF_INT_TSE_MASK & XLLF_INT_ALL_MASK,
  555. fifo->base_addr + XLLF_ISR_OFFSET);
  556. } else if (pending_interrupts) {
  557. /* unknown interrupt type */
  558. dev_err(fifo->dt_device,
  559. "unknown interrupt(s) 0x%x\n",
  560. pending_interrupts);
  561. iowrite32(XLLF_INT_ALL_MASK,
  562. fifo->base_addr + XLLF_ISR_OFFSET);
  563. }
  564. } while (pending_interrupts);
  565. return IRQ_HANDLED;
  566. }
  567. static int axis_fifo_open(struct inode *inod, struct file *f)
  568. {
  569. struct axis_fifo *fifo = (struct axis_fifo *)container_of(inod->i_cdev,
  570. struct axis_fifo, char_device);
  571. f->private_data = fifo;
  572. if (((f->f_flags & O_ACCMODE) == O_WRONLY) ||
  573. ((f->f_flags & O_ACCMODE) == O_RDWR)) {
  574. if (fifo->has_tx_fifo) {
  575. fifo->write_flags = f->f_flags;
  576. } else {
  577. dev_err(fifo->dt_device, "tried to open device for write but the transmit fifo is disabled\n");
  578. return -EPERM;
  579. }
  580. }
  581. if (((f->f_flags & O_ACCMODE) == O_RDONLY) ||
  582. ((f->f_flags & O_ACCMODE) == O_RDWR)) {
  583. if (fifo->has_rx_fifo) {
  584. fifo->read_flags = f->f_flags;
  585. } else {
  586. dev_err(fifo->dt_device, "tried to open device for read but the receive fifo is disabled\n");
  587. return -EPERM;
  588. }
  589. }
  590. return 0;
  591. }
  592. static int axis_fifo_close(struct inode *inod, struct file *f)
  593. {
  594. f->private_data = NULL;
  595. return 0;
  596. }
  597. static const struct file_operations fops = {
  598. .owner = THIS_MODULE,
  599. .open = axis_fifo_open,
  600. .release = axis_fifo_close,
  601. .read = axis_fifo_read,
  602. .write = axis_fifo_write
  603. };
  604. /* read named property from the device tree */
  605. static int get_dts_property(struct axis_fifo *fifo,
  606. char *name, unsigned int *var)
  607. {
  608. int rc;
  609. rc = of_property_read_u32(fifo->dt_device->of_node, name, var);
  610. if (rc) {
  611. dev_err(fifo->dt_device, "couldn't read IP dts property '%s'",
  612. name);
  613. return rc;
  614. }
  615. dev_dbg(fifo->dt_device, "dts property '%s' = %u\n",
  616. name, *var);
  617. return 0;
  618. }
  619. static int axis_fifo_parse_dt(struct axis_fifo *fifo)
  620. {
  621. int ret;
  622. unsigned int value;
  623. ret = get_dts_property(fifo, "xlnx,axi-str-rxd-tdata-width", &value);
  624. if (ret) {
  625. dev_err(fifo->dt_device, "missing xlnx,axi-str-rxd-tdata-width property\n");
  626. goto end;
  627. } else if (value != 32) {
  628. dev_err(fifo->dt_device, "xlnx,axi-str-rxd-tdata-width only supports 32 bits\n");
  629. ret = -EIO;
  630. goto end;
  631. }
  632. ret = get_dts_property(fifo, "xlnx,axi-str-txd-tdata-width", &value);
  633. if (ret) {
  634. dev_err(fifo->dt_device, "missing xlnx,axi-str-txd-tdata-width property\n");
  635. goto end;
  636. } else if (value != 32) {
  637. dev_err(fifo->dt_device, "xlnx,axi-str-txd-tdata-width only supports 32 bits\n");
  638. ret = -EIO;
  639. goto end;
  640. }
  641. ret = get_dts_property(fifo, "xlnx,rx-fifo-depth",
  642. &fifo->rx_fifo_depth);
  643. if (ret) {
  644. dev_err(fifo->dt_device, "missing xlnx,rx-fifo-depth property\n");
  645. ret = -EIO;
  646. goto end;
  647. }
  648. ret = get_dts_property(fifo, "xlnx,tx-fifo-depth",
  649. &fifo->tx_fifo_depth);
  650. if (ret) {
  651. dev_err(fifo->dt_device, "missing xlnx,tx-fifo-depth property\n");
  652. ret = -EIO;
  653. goto end;
  654. }
  655. /* IP sets TDFV to fifo depth - 4 so we will do the same */
  656. fifo->tx_fifo_depth -= 4;
  657. ret = get_dts_property(fifo, "xlnx,use-rx-data", &fifo->has_rx_fifo);
  658. if (ret) {
  659. dev_err(fifo->dt_device, "missing xlnx,use-rx-data property\n");
  660. ret = -EIO;
  661. goto end;
  662. }
  663. ret = get_dts_property(fifo, "xlnx,use-tx-data", &fifo->has_tx_fifo);
  664. if (ret) {
  665. dev_err(fifo->dt_device, "missing xlnx,use-tx-data property\n");
  666. ret = -EIO;
  667. goto end;
  668. }
  669. end:
  670. return ret;
  671. }
  672. static int axis_fifo_probe(struct platform_device *pdev)
  673. {
  674. struct resource *r_irq; /* interrupt resources */
  675. struct resource *r_mem; /* IO mem resources */
  676. struct device *dev = &pdev->dev; /* OS device (from device tree) */
  677. struct axis_fifo *fifo = NULL;
  678. char device_name[32];
  679. int rc = 0; /* error return value */
  680. /* ----------------------------
  681. * init wrapper device
  682. * ----------------------------
  683. */
  684. /* allocate device wrapper memory */
  685. fifo = devm_kmalloc(dev, sizeof(*fifo), GFP_KERNEL);
  686. if (!fifo)
  687. return -ENOMEM;
  688. dev_set_drvdata(dev, fifo);
  689. fifo->dt_device = dev;
  690. init_waitqueue_head(&fifo->read_queue);
  691. init_waitqueue_head(&fifo->write_queue);
  692. mutex_init(&fifo->read_lock);
  693. mutex_init(&fifo->write_lock);
  694. /* ----------------------------
  695. * init device memory space
  696. * ----------------------------
  697. */
  698. /* get iospace for the device */
  699. r_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  700. if (!r_mem) {
  701. dev_err(fifo->dt_device, "invalid address\n");
  702. rc = -ENODEV;
  703. goto err_initial;
  704. }
  705. /* request physical memory */
  706. fifo->base_addr = devm_ioremap_resource(fifo->dt_device, r_mem);
  707. if (IS_ERR(fifo->base_addr)) {
  708. rc = PTR_ERR(fifo->base_addr);
  709. dev_err(fifo->dt_device, "can't remap IO resource (%d)\n", rc);
  710. goto err_initial;
  711. }
  712. dev_dbg(fifo->dt_device, "remapped memory to 0x%p\n", fifo->base_addr);
  713. /* create unique device name */
  714. snprintf(device_name, sizeof(device_name), "%s_%pa",
  715. DRIVER_NAME, &r_mem->start);
  716. dev_dbg(fifo->dt_device, "device name [%s]\n", device_name);
  717. /* ----------------------------
  718. * init IP
  719. * ----------------------------
  720. */
  721. rc = axis_fifo_parse_dt(fifo);
  722. if (rc)
  723. goto err_initial;
  724. reset_ip_core(fifo);
  725. /* ----------------------------
  726. * init device interrupts
  727. * ----------------------------
  728. */
  729. /* get IRQ resource */
  730. r_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  731. if (!r_irq) {
  732. dev_err(fifo->dt_device, "no IRQ found for 0x%pa\n",
  733. &r_mem->start);
  734. rc = -EIO;
  735. goto err_initial;
  736. }
  737. /* request IRQ */
  738. fifo->irq = r_irq->start;
  739. rc = devm_request_irq(fifo->dt_device, fifo->irq, &axis_fifo_irq, 0,
  740. DRIVER_NAME, fifo);
  741. if (rc) {
  742. dev_err(fifo->dt_device, "couldn't allocate interrupt %i\n",
  743. fifo->irq);
  744. goto err_initial;
  745. }
  746. /* ----------------------------
  747. * init char device
  748. * ----------------------------
  749. */
  750. /* allocate device number */
  751. rc = alloc_chrdev_region(&fifo->devt, 0, 1, DRIVER_NAME);
  752. if (rc < 0)
  753. goto err_initial;
  754. dev_dbg(fifo->dt_device, "allocated device number major %i minor %i\n",
  755. MAJOR(fifo->devt), MINOR(fifo->devt));
  756. /* create driver file */
  757. fifo->device = device_create(axis_fifo_driver_class, NULL, fifo->devt,
  758. NULL, device_name);
  759. if (IS_ERR(fifo->device)) {
  760. dev_err(fifo->dt_device,
  761. "couldn't create driver file\n");
  762. rc = PTR_ERR(fifo->device);
  763. goto err_chrdev_region;
  764. }
  765. dev_set_drvdata(fifo->device, fifo);
  766. /* create character device */
  767. cdev_init(&fifo->char_device, &fops);
  768. rc = cdev_add(&fifo->char_device, fifo->devt, 1);
  769. if (rc < 0) {
  770. dev_err(fifo->dt_device, "couldn't create character device\n");
  771. goto err_dev;
  772. }
  773. /* create sysfs entries */
  774. rc = devm_device_add_group(fifo->device, &axis_fifo_attrs_group);
  775. if (rc < 0) {
  776. dev_err(fifo->dt_device, "couldn't register sysfs group\n");
  777. goto err_cdev;
  778. }
  779. dev_info(fifo->dt_device, "axis-fifo created at %pa mapped to 0x%pa, irq=%i, major=%i, minor=%i\n",
  780. &r_mem->start, &fifo->base_addr, fifo->irq,
  781. MAJOR(fifo->devt), MINOR(fifo->devt));
  782. return 0;
  783. err_cdev:
  784. cdev_del(&fifo->char_device);
  785. err_dev:
  786. device_destroy(axis_fifo_driver_class, fifo->devt);
  787. err_chrdev_region:
  788. unregister_chrdev_region(fifo->devt, 1);
  789. err_initial:
  790. dev_set_drvdata(dev, NULL);
  791. return rc;
  792. }
  793. static int axis_fifo_remove(struct platform_device *pdev)
  794. {
  795. struct device *dev = &pdev->dev;
  796. struct axis_fifo *fifo = dev_get_drvdata(dev);
  797. cdev_del(&fifo->char_device);
  798. dev_set_drvdata(fifo->device, NULL);
  799. device_destroy(axis_fifo_driver_class, fifo->devt);
  800. unregister_chrdev_region(fifo->devt, 1);
  801. dev_set_drvdata(dev, NULL);
  802. return 0;
  803. }
  804. static const struct of_device_id axis_fifo_of_match[] = {
  805. { .compatible = "xlnx,axi-fifo-mm-s-4.1", },
  806. {},
  807. };
  808. MODULE_DEVICE_TABLE(of, axis_fifo_of_match);
  809. static struct platform_driver axis_fifo_driver = {
  810. .driver = {
  811. .name = DRIVER_NAME,
  812. .of_match_table = axis_fifo_of_match,
  813. },
  814. .probe = axis_fifo_probe,
  815. .remove = axis_fifo_remove,
  816. };
  817. static int __init axis_fifo_init(void)
  818. {
  819. pr_info("axis-fifo driver loaded with parameters read_timeout = %i, write_timeout = %i\n",
  820. read_timeout, write_timeout);
  821. axis_fifo_driver_class = class_create(THIS_MODULE, DRIVER_NAME);
  822. if (IS_ERR(axis_fifo_driver_class))
  823. return PTR_ERR(axis_fifo_driver_class);
  824. return platform_driver_register(&axis_fifo_driver);
  825. }
  826. module_init(axis_fifo_init);
  827. static void __exit axis_fifo_exit(void)
  828. {
  829. platform_driver_unregister(&axis_fifo_driver);
  830. class_destroy(axis_fifo_driver_class);
  831. }
  832. module_exit(axis_fifo_exit);
  833. MODULE_LICENSE("GPL");
  834. MODULE_AUTHOR("Jacob Feder <jacobsfeder@gmail.com>");
  835. MODULE_DESCRIPTION("Xilinx AXI-Stream FIFO v4.1 IP core driver");