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