Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Xilinx AXIS FIFO: interface to the Xilinx AXI-Stream FIFO IP core
0004  *
0005  * Copyright (C) 2018 Jacob Feder
0006  *
0007  * Authors:  Jacob Feder <jacobsfeder@gmail.com>
0008  *
0009  * See Xilinx PG080 document for IP details
0010  */
0011 
0012 /* ----------------------------
0013  *           includes
0014  * ----------------------------
0015  */
0016 
0017 #include <linux/kernel.h>
0018 #include <linux/wait.h>
0019 #include <linux/mutex.h>
0020 #include <linux/device.h>
0021 #include <linux/cdev.h>
0022 #include <linux/init.h>
0023 #include <linux/module.h>
0024 #include <linux/slab.h>
0025 #include <linux/io.h>
0026 #include <linux/moduleparam.h>
0027 #include <linux/interrupt.h>
0028 #include <linux/param.h>
0029 #include <linux/fs.h>
0030 #include <linux/types.h>
0031 #include <linux/uaccess.h>
0032 #include <linux/jiffies.h>
0033 #include <linux/miscdevice.h>
0034 
0035 #include <linux/of_address.h>
0036 #include <linux/of_device.h>
0037 #include <linux/of_platform.h>
0038 
0039 /* ----------------------------
0040  *       driver parameters
0041  * ----------------------------
0042  */
0043 
0044 #define DRIVER_NAME "axis_fifo"
0045 
0046 #define READ_BUF_SIZE 128U /* read buffer length in words */
0047 #define WRITE_BUF_SIZE 128U /* write buffer length in words */
0048 
0049 /* ----------------------------
0050  *     IP register offsets
0051  * ----------------------------
0052  */
0053 
0054 #define XLLF_ISR_OFFSET  0x00000000  /* Interrupt Status */
0055 #define XLLF_IER_OFFSET  0x00000004  /* Interrupt Enable */
0056 
0057 #define XLLF_TDFR_OFFSET 0x00000008  /* Transmit Reset */
0058 #define XLLF_TDFV_OFFSET 0x0000000c  /* Transmit Vacancy */
0059 #define XLLF_TDFD_OFFSET 0x00000010  /* Transmit Data */
0060 #define XLLF_TLR_OFFSET  0x00000014  /* Transmit Length */
0061 
0062 #define XLLF_RDFR_OFFSET 0x00000018  /* Receive Reset */
0063 #define XLLF_RDFO_OFFSET 0x0000001c  /* Receive Occupancy */
0064 #define XLLF_RDFD_OFFSET 0x00000020  /* Receive Data */
0065 #define XLLF_RLR_OFFSET  0x00000024  /* Receive Length */
0066 #define XLLF_SRR_OFFSET  0x00000028  /* Local Link Reset */
0067 #define XLLF_TDR_OFFSET  0x0000002C  /* Transmit Destination */
0068 #define XLLF_RDR_OFFSET  0x00000030  /* Receive Destination */
0069 
0070 /* ----------------------------
0071  *     reset register masks
0072  * ----------------------------
0073  */
0074 
0075 #define XLLF_RDFR_RESET_MASK        0x000000a5 /* receive reset value */
0076 #define XLLF_TDFR_RESET_MASK        0x000000a5 /* Transmit reset value */
0077 #define XLLF_SRR_RESET_MASK         0x000000a5 /* Local Link reset value */
0078 
0079 /* ----------------------------
0080  *       interrupt masks
0081  * ----------------------------
0082  */
0083 
0084 #define XLLF_INT_RPURE_MASK       0x80000000 /* Receive under-read */
0085 #define XLLF_INT_RPORE_MASK       0x40000000 /* Receive over-read */
0086 #define XLLF_INT_RPUE_MASK        0x20000000 /* Receive underrun (empty) */
0087 #define XLLF_INT_TPOE_MASK        0x10000000 /* Transmit overrun */
0088 #define XLLF_INT_TC_MASK          0x08000000 /* Transmit complete */
0089 #define XLLF_INT_RC_MASK          0x04000000 /* Receive complete */
0090 #define XLLF_INT_TSE_MASK         0x02000000 /* Transmit length mismatch */
0091 #define XLLF_INT_TRC_MASK         0x01000000 /* Transmit reset complete */
0092 #define XLLF_INT_RRC_MASK         0x00800000 /* Receive reset complete */
0093 #define XLLF_INT_TFPF_MASK        0x00400000 /* Tx FIFO Programmable Full */
0094 #define XLLF_INT_TFPE_MASK        0x00200000 /* Tx FIFO Programmable Empty */
0095 #define XLLF_INT_RFPF_MASK        0x00100000 /* Rx FIFO Programmable Full */
0096 #define XLLF_INT_RFPE_MASK        0x00080000 /* Rx FIFO Programmable Empty */
0097 #define XLLF_INT_ALL_MASK         0xfff80000 /* All the ints */
0098 #define XLLF_INT_ERROR_MASK       0xf2000000 /* Error status ints */
0099 #define XLLF_INT_RXERROR_MASK     0xe0000000 /* Receive Error status ints */
0100 #define XLLF_INT_TXERROR_MASK     0x12000000 /* Transmit Error status ints */
0101 
0102 /* ----------------------------
0103  *           globals
0104  * ----------------------------
0105  */
0106 static int read_timeout = 1000; /* ms to wait before read() times out */
0107 static int write_timeout = 1000; /* ms to wait before write() times out */
0108 
0109 /* ----------------------------
0110  * module command-line arguments
0111  * ----------------------------
0112  */
0113 
0114 module_param(read_timeout, int, 0444);
0115 MODULE_PARM_DESC(read_timeout, "ms to wait before blocking read() timing out; set to -1 for no timeout");
0116 module_param(write_timeout, int, 0444);
0117 MODULE_PARM_DESC(write_timeout, "ms to wait before blocking write() timing out; set to -1 for no timeout");
0118 
0119 /* ----------------------------
0120  *            types
0121  * ----------------------------
0122  */
0123 
0124 struct axis_fifo {
0125     int irq; /* interrupt */
0126     void __iomem *base_addr; /* kernel space memory */
0127 
0128     unsigned int rx_fifo_depth; /* max words in the receive fifo */
0129     unsigned int tx_fifo_depth; /* max words in the transmit fifo */
0130     int has_rx_fifo; /* whether the IP has the rx fifo enabled */
0131     int has_tx_fifo; /* whether the IP has the tx fifo enabled */
0132 
0133     wait_queue_head_t read_queue; /* wait queue for asynchronos read */
0134     struct mutex read_lock; /* lock for reading */
0135     wait_queue_head_t write_queue; /* wait queue for asynchronos write */
0136     struct mutex write_lock; /* lock for writing */
0137     unsigned int write_flags; /* write file flags */
0138     unsigned int read_flags; /* read file flags */
0139 
0140     struct device *dt_device; /* device created from the device tree */
0141     struct miscdevice miscdev;
0142 };
0143 
0144 /* ----------------------------
0145  *         sysfs entries
0146  * ----------------------------
0147  */
0148 
0149 static ssize_t sysfs_write(struct device *dev, const char *buf,
0150                size_t count, unsigned int addr_offset)
0151 {
0152     struct axis_fifo *fifo = dev_get_drvdata(dev);
0153     unsigned long tmp;
0154     int rc;
0155 
0156     rc = kstrtoul(buf, 0, &tmp);
0157     if (rc < 0)
0158         return rc;
0159 
0160     iowrite32(tmp, fifo->base_addr + addr_offset);
0161 
0162     return count;
0163 }
0164 
0165 static ssize_t sysfs_read(struct device *dev, char *buf,
0166               unsigned int addr_offset)
0167 {
0168     struct axis_fifo *fifo = dev_get_drvdata(dev);
0169     unsigned int read_val;
0170     unsigned int len;
0171     char tmp[32];
0172 
0173     read_val = ioread32(fifo->base_addr + addr_offset);
0174     len =  snprintf(tmp, sizeof(tmp), "0x%x\n", read_val);
0175     memcpy(buf, tmp, len);
0176 
0177     return len;
0178 }
0179 
0180 static ssize_t isr_store(struct device *dev, struct device_attribute *attr,
0181              const char *buf, size_t count)
0182 {
0183     return sysfs_write(dev, buf, count, XLLF_ISR_OFFSET);
0184 }
0185 
0186 static ssize_t isr_show(struct device *dev,
0187             struct device_attribute *attr, char *buf)
0188 {
0189     return sysfs_read(dev, buf, XLLF_ISR_OFFSET);
0190 }
0191 
0192 static DEVICE_ATTR_RW(isr);
0193 
0194 static ssize_t ier_store(struct device *dev, struct device_attribute *attr,
0195              const char *buf, size_t count)
0196 {
0197     return sysfs_write(dev, buf, count, XLLF_IER_OFFSET);
0198 }
0199 
0200 static ssize_t ier_show(struct device *dev,
0201             struct device_attribute *attr, char *buf)
0202 {
0203     return sysfs_read(dev, buf, XLLF_IER_OFFSET);
0204 }
0205 
0206 static DEVICE_ATTR_RW(ier);
0207 
0208 static ssize_t tdfr_store(struct device *dev, struct device_attribute *attr,
0209               const char *buf, size_t count)
0210 {
0211     return sysfs_write(dev, buf, count, XLLF_TDFR_OFFSET);
0212 }
0213 
0214 static DEVICE_ATTR_WO(tdfr);
0215 
0216 static ssize_t tdfv_show(struct device *dev,
0217              struct device_attribute *attr, char *buf)
0218 {
0219     return sysfs_read(dev, buf, XLLF_TDFV_OFFSET);
0220 }
0221 
0222 static DEVICE_ATTR_RO(tdfv);
0223 
0224 static ssize_t tdfd_store(struct device *dev, struct device_attribute *attr,
0225               const char *buf, size_t count)
0226 {
0227     return sysfs_write(dev, buf, count, XLLF_TDFD_OFFSET);
0228 }
0229 
0230 static DEVICE_ATTR_WO(tdfd);
0231 
0232 static ssize_t tlr_store(struct device *dev, struct device_attribute *attr,
0233              const char *buf, size_t count)
0234 {
0235     return sysfs_write(dev, buf, count, XLLF_TLR_OFFSET);
0236 }
0237 
0238 static DEVICE_ATTR_WO(tlr);
0239 
0240 static ssize_t rdfr_store(struct device *dev, struct device_attribute *attr,
0241               const char *buf, size_t count)
0242 {
0243     return sysfs_write(dev, buf, count, XLLF_RDFR_OFFSET);
0244 }
0245 
0246 static DEVICE_ATTR_WO(rdfr);
0247 
0248 static ssize_t rdfo_show(struct device *dev,
0249              struct device_attribute *attr, char *buf)
0250 {
0251     return sysfs_read(dev, buf, XLLF_RDFO_OFFSET);
0252 }
0253 
0254 static DEVICE_ATTR_RO(rdfo);
0255 
0256 static ssize_t rdfd_show(struct device *dev,
0257              struct device_attribute *attr, char *buf)
0258 {
0259     return sysfs_read(dev, buf, XLLF_RDFD_OFFSET);
0260 }
0261 
0262 static DEVICE_ATTR_RO(rdfd);
0263 
0264 static ssize_t rlr_show(struct device *dev,
0265             struct device_attribute *attr, char *buf)
0266 {
0267     return sysfs_read(dev, buf, XLLF_RLR_OFFSET);
0268 }
0269 
0270 static DEVICE_ATTR_RO(rlr);
0271 
0272 static ssize_t srr_store(struct device *dev, struct device_attribute *attr,
0273              const char *buf, size_t count)
0274 {
0275     return sysfs_write(dev, buf, count, XLLF_SRR_OFFSET);
0276 }
0277 
0278 static DEVICE_ATTR_WO(srr);
0279 
0280 static ssize_t tdr_store(struct device *dev, struct device_attribute *attr,
0281              const char *buf, size_t count)
0282 {
0283     return sysfs_write(dev, buf, count, XLLF_TDR_OFFSET);
0284 }
0285 
0286 static DEVICE_ATTR_WO(tdr);
0287 
0288 static ssize_t rdr_show(struct device *dev,
0289             struct device_attribute *attr, char *buf)
0290 {
0291     return sysfs_read(dev, buf, XLLF_RDR_OFFSET);
0292 }
0293 
0294 static DEVICE_ATTR_RO(rdr);
0295 
0296 static struct attribute *axis_fifo_attrs[] = {
0297     &dev_attr_isr.attr,
0298     &dev_attr_ier.attr,
0299     &dev_attr_tdfr.attr,
0300     &dev_attr_tdfv.attr,
0301     &dev_attr_tdfd.attr,
0302     &dev_attr_tlr.attr,
0303     &dev_attr_rdfr.attr,
0304     &dev_attr_rdfo.attr,
0305     &dev_attr_rdfd.attr,
0306     &dev_attr_rlr.attr,
0307     &dev_attr_srr.attr,
0308     &dev_attr_tdr.attr,
0309     &dev_attr_rdr.attr,
0310     NULL,
0311 };
0312 
0313 static const struct attribute_group axis_fifo_attrs_group = {
0314     .name = "ip_registers",
0315     .attrs = axis_fifo_attrs,
0316 };
0317 
0318 static const struct attribute_group *axis_fifo_attrs_groups[] = {
0319     &axis_fifo_attrs_group,
0320     NULL,
0321 };
0322 
0323 /* ----------------------------
0324  *        implementation
0325  * ----------------------------
0326  */
0327 
0328 static void reset_ip_core(struct axis_fifo *fifo)
0329 {
0330     iowrite32(XLLF_SRR_RESET_MASK, fifo->base_addr + XLLF_SRR_OFFSET);
0331     iowrite32(XLLF_TDFR_RESET_MASK, fifo->base_addr + XLLF_TDFR_OFFSET);
0332     iowrite32(XLLF_RDFR_RESET_MASK, fifo->base_addr + XLLF_RDFR_OFFSET);
0333     iowrite32(XLLF_INT_TC_MASK | XLLF_INT_RC_MASK | XLLF_INT_RPURE_MASK |
0334           XLLF_INT_RPORE_MASK | XLLF_INT_RPUE_MASK |
0335           XLLF_INT_TPOE_MASK | XLLF_INT_TSE_MASK,
0336           fifo->base_addr + XLLF_IER_OFFSET);
0337     iowrite32(XLLF_INT_ALL_MASK, fifo->base_addr + XLLF_ISR_OFFSET);
0338 }
0339 
0340 /**
0341  * axis_fifo_read() - Read a packet from AXIS-FIFO character device.
0342  * @f: Open file.
0343  * @buf: User space buffer to read to.
0344  * @len: User space buffer length.
0345  * @off: Buffer offset.
0346  *
0347  * As defined by the device's documentation, we need to check the device's
0348  * occupancy before reading the length register and then the data. All these
0349  * operations must be executed atomically, in order and one after the other
0350  * without missing any.
0351  *
0352  * Returns the number of bytes read from the device or negative error code
0353  *  on failure.
0354  */
0355 static ssize_t axis_fifo_read(struct file *f, char __user *buf,
0356                   size_t len, loff_t *off)
0357 {
0358     struct axis_fifo *fifo = (struct axis_fifo *)f->private_data;
0359     size_t bytes_available;
0360     unsigned int words_available;
0361     unsigned int copied;
0362     unsigned int copy;
0363     unsigned int i;
0364     int ret;
0365     u32 tmp_buf[READ_BUF_SIZE];
0366 
0367     if (fifo->read_flags & O_NONBLOCK) {
0368         /*
0369          * Device opened in non-blocking mode. Try to lock it and then
0370          * check if any packet is available.
0371          */
0372         if (!mutex_trylock(&fifo->read_lock))
0373             return -EAGAIN;
0374 
0375         if (!ioread32(fifo->base_addr + XLLF_RDFO_OFFSET)) {
0376             ret = -EAGAIN;
0377             goto end_unlock;
0378         }
0379     } else {
0380         /* opened in blocking mode
0381          * wait for a packet available interrupt (or timeout)
0382          * if nothing is currently available
0383          */
0384         mutex_lock(&fifo->read_lock);
0385         ret = wait_event_interruptible_timeout(fifo->read_queue,
0386             ioread32(fifo->base_addr + XLLF_RDFO_OFFSET),
0387                  (read_timeout >= 0) ?
0388                   msecs_to_jiffies(read_timeout) :
0389                   MAX_SCHEDULE_TIMEOUT);
0390 
0391         if (ret <= 0) {
0392             if (ret == 0) {
0393                 ret = -EAGAIN;
0394             } else if (ret != -ERESTARTSYS) {
0395                 dev_err(fifo->dt_device, "wait_event_interruptible_timeout() error in read (ret=%i)\n",
0396                     ret);
0397             }
0398 
0399             goto end_unlock;
0400         }
0401     }
0402 
0403     bytes_available = ioread32(fifo->base_addr + XLLF_RLR_OFFSET);
0404     if (!bytes_available) {
0405         dev_err(fifo->dt_device, "received a packet of length 0 - fifo core will be reset\n");
0406         reset_ip_core(fifo);
0407         ret = -EIO;
0408         goto end_unlock;
0409     }
0410 
0411     if (bytes_available > len) {
0412         dev_err(fifo->dt_device, "user read buffer too small (available bytes=%zu user buffer bytes=%zu) - fifo core will be reset\n",
0413             bytes_available, len);
0414         reset_ip_core(fifo);
0415         ret = -EINVAL;
0416         goto end_unlock;
0417     }
0418 
0419     if (bytes_available % sizeof(u32)) {
0420         /* this probably can't happen unless IP
0421          * registers were previously mishandled
0422          */
0423         dev_err(fifo->dt_device, "received a packet that isn't word-aligned - fifo core will be reset\n");
0424         reset_ip_core(fifo);
0425         ret = -EIO;
0426         goto end_unlock;
0427     }
0428 
0429     words_available = bytes_available / sizeof(u32);
0430 
0431     /* read data into an intermediate buffer, copying the contents
0432      * to userspace when the buffer is full
0433      */
0434     copied = 0;
0435     while (words_available > 0) {
0436         copy = min(words_available, READ_BUF_SIZE);
0437 
0438         for (i = 0; i < copy; i++) {
0439             tmp_buf[i] = ioread32(fifo->base_addr +
0440                           XLLF_RDFD_OFFSET);
0441         }
0442 
0443         if (copy_to_user(buf + copied * sizeof(u32), tmp_buf,
0444                  copy * sizeof(u32))) {
0445             reset_ip_core(fifo);
0446             ret = -EFAULT;
0447             goto end_unlock;
0448         }
0449 
0450         copied += copy;
0451         words_available -= copy;
0452     }
0453 
0454     ret = bytes_available;
0455 
0456 end_unlock:
0457     mutex_unlock(&fifo->read_lock);
0458 
0459     return ret;
0460 }
0461 
0462 /**
0463  * axis_fifo_write() - Write buffer to AXIS-FIFO character device.
0464  * @f: Open file.
0465  * @buf: User space buffer to write to the device.
0466  * @len: User space buffer length.
0467  * @off: Buffer offset.
0468  *
0469  * As defined by the device's documentation, we need to write to the device's
0470  * data buffer then to the device's packet length register atomically. Also,
0471  * we need to lock before checking if the device has available space to avoid
0472  * any concurrency issue.
0473  *
0474  * Returns the number of bytes written to the device or negative error code
0475  *  on failure.
0476  */
0477 static ssize_t axis_fifo_write(struct file *f, const char __user *buf,
0478                    size_t len, loff_t *off)
0479 {
0480     struct axis_fifo *fifo = (struct axis_fifo *)f->private_data;
0481     unsigned int words_to_write;
0482     unsigned int copied;
0483     unsigned int copy;
0484     unsigned int i;
0485     int ret;
0486     u32 tmp_buf[WRITE_BUF_SIZE];
0487 
0488     if (len % sizeof(u32)) {
0489         dev_err(fifo->dt_device,
0490             "tried to send a packet that isn't word-aligned\n");
0491         return -EINVAL;
0492     }
0493 
0494     words_to_write = len / sizeof(u32);
0495 
0496     if (!words_to_write) {
0497         dev_err(fifo->dt_device,
0498             "tried to send a packet of length 0\n");
0499         return -EINVAL;
0500     }
0501 
0502     if (words_to_write > fifo->tx_fifo_depth) {
0503         dev_err(fifo->dt_device, "tried to write more words [%u] than slots in the fifo buffer [%u]\n",
0504             words_to_write, fifo->tx_fifo_depth);
0505         return -EINVAL;
0506     }
0507 
0508     if (fifo->write_flags & O_NONBLOCK) {
0509         /*
0510          * Device opened in non-blocking mode. Try to lock it and then
0511          * check if there is any room to write the given buffer.
0512          */
0513         if (!mutex_trylock(&fifo->write_lock))
0514             return -EAGAIN;
0515 
0516         if (words_to_write > ioread32(fifo->base_addr +
0517                           XLLF_TDFV_OFFSET)) {
0518             ret = -EAGAIN;
0519             goto end_unlock;
0520         }
0521     } else {
0522         /* opened in blocking mode */
0523 
0524         /* wait for an interrupt (or timeout) if there isn't
0525          * currently enough room in the fifo
0526          */
0527         mutex_lock(&fifo->write_lock);
0528         ret = wait_event_interruptible_timeout(fifo->write_queue,
0529             ioread32(fifo->base_addr + XLLF_TDFV_OFFSET)
0530                  >= words_to_write,
0531                  (write_timeout >= 0) ?
0532                   msecs_to_jiffies(write_timeout) :
0533                   MAX_SCHEDULE_TIMEOUT);
0534 
0535         if (ret <= 0) {
0536             if (ret == 0) {
0537                 ret = -EAGAIN;
0538             } else if (ret != -ERESTARTSYS) {
0539                 dev_err(fifo->dt_device, "wait_event_interruptible_timeout() error in write (ret=%i)\n",
0540                     ret);
0541             }
0542 
0543             goto end_unlock;
0544         }
0545     }
0546 
0547     /* write data from an intermediate buffer into the fifo IP, refilling
0548      * the buffer with userspace data as needed
0549      */
0550     copied = 0;
0551     while (words_to_write > 0) {
0552         copy = min(words_to_write, WRITE_BUF_SIZE);
0553 
0554         if (copy_from_user(tmp_buf, buf + copied * sizeof(u32),
0555                    copy * sizeof(u32))) {
0556             reset_ip_core(fifo);
0557             ret = -EFAULT;
0558             goto end_unlock;
0559         }
0560 
0561         for (i = 0; i < copy; i++)
0562             iowrite32(tmp_buf[i], fifo->base_addr +
0563                   XLLF_TDFD_OFFSET);
0564 
0565         copied += copy;
0566         words_to_write -= copy;
0567     }
0568 
0569     ret = copied * sizeof(u32);
0570 
0571     /* write packet size to fifo */
0572     iowrite32(ret, fifo->base_addr + XLLF_TLR_OFFSET);
0573 
0574 end_unlock:
0575     mutex_unlock(&fifo->write_lock);
0576 
0577     return ret;
0578 }
0579 
0580 static irqreturn_t axis_fifo_irq(int irq, void *dw)
0581 {
0582     struct axis_fifo *fifo = (struct axis_fifo *)dw;
0583     unsigned int pending_interrupts;
0584 
0585     do {
0586         pending_interrupts = ioread32(fifo->base_addr +
0587                           XLLF_IER_OFFSET) &
0588                           ioread32(fifo->base_addr
0589                           + XLLF_ISR_OFFSET);
0590         if (pending_interrupts & XLLF_INT_RC_MASK) {
0591             /* packet received */
0592 
0593             /* wake the reader process if it is waiting */
0594             wake_up(&fifo->read_queue);
0595 
0596             /* clear interrupt */
0597             iowrite32(XLLF_INT_RC_MASK & XLLF_INT_ALL_MASK,
0598                   fifo->base_addr + XLLF_ISR_OFFSET);
0599         } else if (pending_interrupts & XLLF_INT_TC_MASK) {
0600             /* packet sent */
0601 
0602             /* wake the writer process if it is waiting */
0603             wake_up(&fifo->write_queue);
0604 
0605             iowrite32(XLLF_INT_TC_MASK & XLLF_INT_ALL_MASK,
0606                   fifo->base_addr + XLLF_ISR_OFFSET);
0607         } else if (pending_interrupts & XLLF_INT_TFPF_MASK) {
0608             /* transmit fifo programmable full */
0609 
0610             iowrite32(XLLF_INT_TFPF_MASK & XLLF_INT_ALL_MASK,
0611                   fifo->base_addr + XLLF_ISR_OFFSET);
0612         } else if (pending_interrupts & XLLF_INT_TFPE_MASK) {
0613             /* transmit fifo programmable empty */
0614 
0615             iowrite32(XLLF_INT_TFPE_MASK & XLLF_INT_ALL_MASK,
0616                   fifo->base_addr + XLLF_ISR_OFFSET);
0617         } else if (pending_interrupts & XLLF_INT_RFPF_MASK) {
0618             /* receive fifo programmable full */
0619 
0620             iowrite32(XLLF_INT_RFPF_MASK & XLLF_INT_ALL_MASK,
0621                   fifo->base_addr + XLLF_ISR_OFFSET);
0622         } else if (pending_interrupts & XLLF_INT_RFPE_MASK) {
0623             /* receive fifo programmable empty */
0624 
0625             iowrite32(XLLF_INT_RFPE_MASK & XLLF_INT_ALL_MASK,
0626                   fifo->base_addr + XLLF_ISR_OFFSET);
0627         } else if (pending_interrupts & XLLF_INT_TRC_MASK) {
0628             /* transmit reset complete interrupt */
0629 
0630             iowrite32(XLLF_INT_TRC_MASK & XLLF_INT_ALL_MASK,
0631                   fifo->base_addr + XLLF_ISR_OFFSET);
0632         } else if (pending_interrupts & XLLF_INT_RRC_MASK) {
0633             /* receive reset complete interrupt */
0634 
0635             iowrite32(XLLF_INT_RRC_MASK & XLLF_INT_ALL_MASK,
0636                   fifo->base_addr + XLLF_ISR_OFFSET);
0637         } else if (pending_interrupts & XLLF_INT_RPURE_MASK) {
0638             /* receive fifo under-read error interrupt */
0639             dev_err(fifo->dt_device,
0640                 "receive under-read interrupt\n");
0641 
0642             iowrite32(XLLF_INT_RPURE_MASK & XLLF_INT_ALL_MASK,
0643                   fifo->base_addr + XLLF_ISR_OFFSET);
0644         } else if (pending_interrupts & XLLF_INT_RPORE_MASK) {
0645             /* receive over-read error interrupt */
0646             dev_err(fifo->dt_device,
0647                 "receive over-read interrupt\n");
0648 
0649             iowrite32(XLLF_INT_RPORE_MASK & XLLF_INT_ALL_MASK,
0650                   fifo->base_addr + XLLF_ISR_OFFSET);
0651         } else if (pending_interrupts & XLLF_INT_RPUE_MASK) {
0652             /* receive underrun error interrupt */
0653             dev_err(fifo->dt_device,
0654                 "receive underrun error interrupt\n");
0655 
0656             iowrite32(XLLF_INT_RPUE_MASK & XLLF_INT_ALL_MASK,
0657                   fifo->base_addr + XLLF_ISR_OFFSET);
0658         } else if (pending_interrupts & XLLF_INT_TPOE_MASK) {
0659             /* transmit overrun error interrupt */
0660             dev_err(fifo->dt_device,
0661                 "transmit overrun error interrupt\n");
0662 
0663             iowrite32(XLLF_INT_TPOE_MASK & XLLF_INT_ALL_MASK,
0664                   fifo->base_addr + XLLF_ISR_OFFSET);
0665         } else if (pending_interrupts & XLLF_INT_TSE_MASK) {
0666             /* transmit length mismatch error interrupt */
0667             dev_err(fifo->dt_device,
0668                 "transmit length mismatch error interrupt\n");
0669 
0670             iowrite32(XLLF_INT_TSE_MASK & XLLF_INT_ALL_MASK,
0671                   fifo->base_addr + XLLF_ISR_OFFSET);
0672         } else if (pending_interrupts) {
0673             /* unknown interrupt type */
0674             dev_err(fifo->dt_device,
0675                 "unknown interrupt(s) 0x%x\n",
0676                 pending_interrupts);
0677 
0678             iowrite32(XLLF_INT_ALL_MASK,
0679                   fifo->base_addr + XLLF_ISR_OFFSET);
0680         }
0681     } while (pending_interrupts);
0682 
0683     return IRQ_HANDLED;
0684 }
0685 
0686 static int axis_fifo_open(struct inode *inod, struct file *f)
0687 {
0688     struct axis_fifo *fifo = container_of(f->private_data,
0689                           struct axis_fifo, miscdev);
0690     f->private_data = fifo;
0691 
0692     if (((f->f_flags & O_ACCMODE) == O_WRONLY) ||
0693         ((f->f_flags & O_ACCMODE) == O_RDWR)) {
0694         if (fifo->has_tx_fifo) {
0695             fifo->write_flags = f->f_flags;
0696         } else {
0697             dev_err(fifo->dt_device, "tried to open device for write but the transmit fifo is disabled\n");
0698             return -EPERM;
0699         }
0700     }
0701 
0702     if (((f->f_flags & O_ACCMODE) == O_RDONLY) ||
0703         ((f->f_flags & O_ACCMODE) == O_RDWR)) {
0704         if (fifo->has_rx_fifo) {
0705             fifo->read_flags = f->f_flags;
0706         } else {
0707             dev_err(fifo->dt_device, "tried to open device for read but the receive fifo is disabled\n");
0708             return -EPERM;
0709         }
0710     }
0711 
0712     return 0;
0713 }
0714 
0715 static int axis_fifo_close(struct inode *inod, struct file *f)
0716 {
0717     f->private_data = NULL;
0718 
0719     return 0;
0720 }
0721 
0722 static const struct file_operations fops = {
0723     .owner = THIS_MODULE,
0724     .open = axis_fifo_open,
0725     .release = axis_fifo_close,
0726     .read = axis_fifo_read,
0727     .write = axis_fifo_write
0728 };
0729 
0730 /* read named property from the device tree */
0731 static int get_dts_property(struct axis_fifo *fifo,
0732                 char *name, unsigned int *var)
0733 {
0734     int rc;
0735 
0736     rc = of_property_read_u32(fifo->dt_device->of_node, name, var);
0737     if (rc) {
0738         dev_err(fifo->dt_device, "couldn't read IP dts property '%s'",
0739             name);
0740         return rc;
0741     }
0742     dev_dbg(fifo->dt_device, "dts property '%s' = %u\n",
0743         name, *var);
0744 
0745     return 0;
0746 }
0747 
0748 static int axis_fifo_parse_dt(struct axis_fifo *fifo)
0749 {
0750     int ret;
0751     unsigned int value;
0752 
0753     ret = get_dts_property(fifo, "xlnx,axi-str-rxd-tdata-width", &value);
0754     if (ret) {
0755         dev_err(fifo->dt_device, "missing xlnx,axi-str-rxd-tdata-width property\n");
0756         goto end;
0757     } else if (value != 32) {
0758         dev_err(fifo->dt_device, "xlnx,axi-str-rxd-tdata-width only supports 32 bits\n");
0759         ret = -EIO;
0760         goto end;
0761     }
0762 
0763     ret = get_dts_property(fifo, "xlnx,axi-str-txd-tdata-width", &value);
0764     if (ret) {
0765         dev_err(fifo->dt_device, "missing xlnx,axi-str-txd-tdata-width property\n");
0766         goto end;
0767     } else if (value != 32) {
0768         dev_err(fifo->dt_device, "xlnx,axi-str-txd-tdata-width only supports 32 bits\n");
0769         ret = -EIO;
0770         goto end;
0771     }
0772 
0773     ret = get_dts_property(fifo, "xlnx,rx-fifo-depth",
0774                    &fifo->rx_fifo_depth);
0775     if (ret) {
0776         dev_err(fifo->dt_device, "missing xlnx,rx-fifo-depth property\n");
0777         ret = -EIO;
0778         goto end;
0779     }
0780 
0781     ret = get_dts_property(fifo, "xlnx,tx-fifo-depth",
0782                    &fifo->tx_fifo_depth);
0783     if (ret) {
0784         dev_err(fifo->dt_device, "missing xlnx,tx-fifo-depth property\n");
0785         ret = -EIO;
0786         goto end;
0787     }
0788 
0789     /* IP sets TDFV to fifo depth - 4 so we will do the same */
0790     fifo->tx_fifo_depth -= 4;
0791 
0792     ret = get_dts_property(fifo, "xlnx,use-rx-data", &fifo->has_rx_fifo);
0793     if (ret) {
0794         dev_err(fifo->dt_device, "missing xlnx,use-rx-data property\n");
0795         ret = -EIO;
0796         goto end;
0797     }
0798 
0799     ret = get_dts_property(fifo, "xlnx,use-tx-data", &fifo->has_tx_fifo);
0800     if (ret) {
0801         dev_err(fifo->dt_device, "missing xlnx,use-tx-data property\n");
0802         ret = -EIO;
0803         goto end;
0804     }
0805 
0806 end:
0807     return ret;
0808 }
0809 
0810 static int axis_fifo_probe(struct platform_device *pdev)
0811 {
0812     struct resource *r_mem; /* IO mem resources */
0813     struct device *dev = &pdev->dev; /* OS device (from device tree) */
0814     struct axis_fifo *fifo = NULL;
0815     char *device_name;
0816     int rc = 0; /* error return value */
0817 
0818     /* ----------------------------
0819      *     init wrapper device
0820      * ----------------------------
0821      */
0822 
0823     device_name = devm_kzalloc(dev, 32, GFP_KERNEL);
0824     if (!device_name)
0825         return -ENOMEM;
0826 
0827     /* allocate device wrapper memory */
0828     fifo = devm_kzalloc(dev, sizeof(*fifo), GFP_KERNEL);
0829     if (!fifo)
0830         return -ENOMEM;
0831 
0832     dev_set_drvdata(dev, fifo);
0833     fifo->dt_device = dev;
0834 
0835     init_waitqueue_head(&fifo->read_queue);
0836     init_waitqueue_head(&fifo->write_queue);
0837 
0838     mutex_init(&fifo->read_lock);
0839     mutex_init(&fifo->write_lock);
0840 
0841     /* ----------------------------
0842      *   init device memory space
0843      * ----------------------------
0844      */
0845 
0846     /* get iospace for the device */
0847     r_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0848     if (!r_mem) {
0849         dev_err(fifo->dt_device, "invalid address\n");
0850         rc = -ENODEV;
0851         goto err_initial;
0852     }
0853 
0854     /* request physical memory */
0855     fifo->base_addr = devm_ioremap_resource(fifo->dt_device, r_mem);
0856     if (IS_ERR(fifo->base_addr)) {
0857         rc = PTR_ERR(fifo->base_addr);
0858         goto err_initial;
0859     }
0860 
0861     dev_dbg(fifo->dt_device, "remapped memory to 0x%p\n", fifo->base_addr);
0862 
0863     /* create unique device name */
0864     snprintf(device_name, 32, "%s_%pa", DRIVER_NAME, &r_mem->start);
0865     dev_dbg(fifo->dt_device, "device name [%s]\n", device_name);
0866 
0867     /* ----------------------------
0868      *          init IP
0869      * ----------------------------
0870      */
0871 
0872     rc = axis_fifo_parse_dt(fifo);
0873     if (rc)
0874         goto err_initial;
0875 
0876     reset_ip_core(fifo);
0877 
0878     /* ----------------------------
0879      *    init device interrupts
0880      * ----------------------------
0881      */
0882 
0883     /* get IRQ resource */
0884     rc = platform_get_irq(pdev, 0);
0885     if (rc < 0)
0886         goto err_initial;
0887 
0888     /* request IRQ */
0889     fifo->irq = rc;
0890     rc = devm_request_irq(fifo->dt_device, fifo->irq, &axis_fifo_irq, 0,
0891                   DRIVER_NAME, fifo);
0892     if (rc) {
0893         dev_err(fifo->dt_device, "couldn't allocate interrupt %i\n",
0894             fifo->irq);
0895         goto err_initial;
0896     }
0897 
0898     /* ----------------------------
0899      *      init char device
0900      * ----------------------------
0901      */
0902 
0903     /* create character device */
0904     fifo->miscdev.fops = &fops;
0905     fifo->miscdev.minor = MISC_DYNAMIC_MINOR;
0906     fifo->miscdev.name = device_name;
0907     fifo->miscdev.groups = axis_fifo_attrs_groups;
0908     fifo->miscdev.parent = dev;
0909     rc = misc_register(&fifo->miscdev);
0910     if (rc < 0)
0911         goto err_initial;
0912 
0913     dev_info(fifo->dt_device, "axis-fifo created at %pa mapped to 0x%pa, irq=%i\n",
0914          &r_mem->start, &fifo->base_addr, fifo->irq);
0915 
0916     return 0;
0917 
0918 err_initial:
0919     dev_set_drvdata(dev, NULL);
0920     return rc;
0921 }
0922 
0923 static int axis_fifo_remove(struct platform_device *pdev)
0924 {
0925     struct device *dev = &pdev->dev;
0926     struct axis_fifo *fifo = dev_get_drvdata(dev);
0927 
0928     misc_deregister(&fifo->miscdev);
0929     dev_set_drvdata(dev, NULL);
0930 
0931     return 0;
0932 }
0933 
0934 static const struct of_device_id axis_fifo_of_match[] = {
0935     { .compatible = "xlnx,axi-fifo-mm-s-4.1", },
0936     {},
0937 };
0938 MODULE_DEVICE_TABLE(of, axis_fifo_of_match);
0939 
0940 static struct platform_driver axis_fifo_driver = {
0941     .driver = {
0942         .name = DRIVER_NAME,
0943         .of_match_table = axis_fifo_of_match,
0944     },
0945     .probe      = axis_fifo_probe,
0946     .remove     = axis_fifo_remove,
0947 };
0948 
0949 static int __init axis_fifo_init(void)
0950 {
0951     pr_info("axis-fifo driver loaded with parameters read_timeout = %i, write_timeout = %i\n",
0952         read_timeout, write_timeout);
0953     return platform_driver_register(&axis_fifo_driver);
0954 }
0955 
0956 module_init(axis_fifo_init);
0957 
0958 static void __exit axis_fifo_exit(void)
0959 {
0960     platform_driver_unregister(&axis_fifo_driver);
0961 }
0962 
0963 module_exit(axis_fifo_exit);
0964 
0965 MODULE_LICENSE("GPL");
0966 MODULE_AUTHOR("Jacob Feder <jacobsfeder@gmail.com>");
0967 MODULE_DESCRIPTION("Xilinx AXI-Stream FIFO v4.1 IP core driver");