0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
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
0041
0042
0043
0044 #define DRIVER_NAME "axis_fifo"
0045
0046 #define READ_BUF_SIZE 128U
0047 #define WRITE_BUF_SIZE 128U
0048
0049
0050
0051
0052
0053
0054 #define XLLF_ISR_OFFSET 0x00000000
0055 #define XLLF_IER_OFFSET 0x00000004
0056
0057 #define XLLF_TDFR_OFFSET 0x00000008
0058 #define XLLF_TDFV_OFFSET 0x0000000c
0059 #define XLLF_TDFD_OFFSET 0x00000010
0060 #define XLLF_TLR_OFFSET 0x00000014
0061
0062 #define XLLF_RDFR_OFFSET 0x00000018
0063 #define XLLF_RDFO_OFFSET 0x0000001c
0064 #define XLLF_RDFD_OFFSET 0x00000020
0065 #define XLLF_RLR_OFFSET 0x00000024
0066 #define XLLF_SRR_OFFSET 0x00000028
0067 #define XLLF_TDR_OFFSET 0x0000002C
0068 #define XLLF_RDR_OFFSET 0x00000030
0069
0070
0071
0072
0073
0074
0075 #define XLLF_RDFR_RESET_MASK 0x000000a5
0076 #define XLLF_TDFR_RESET_MASK 0x000000a5
0077 #define XLLF_SRR_RESET_MASK 0x000000a5
0078
0079
0080
0081
0082
0083
0084 #define XLLF_INT_RPURE_MASK 0x80000000
0085 #define XLLF_INT_RPORE_MASK 0x40000000
0086 #define XLLF_INT_RPUE_MASK 0x20000000
0087 #define XLLF_INT_TPOE_MASK 0x10000000
0088 #define XLLF_INT_TC_MASK 0x08000000
0089 #define XLLF_INT_RC_MASK 0x04000000
0090 #define XLLF_INT_TSE_MASK 0x02000000
0091 #define XLLF_INT_TRC_MASK 0x01000000
0092 #define XLLF_INT_RRC_MASK 0x00800000
0093 #define XLLF_INT_TFPF_MASK 0x00400000
0094 #define XLLF_INT_TFPE_MASK 0x00200000
0095 #define XLLF_INT_RFPF_MASK 0x00100000
0096 #define XLLF_INT_RFPE_MASK 0x00080000
0097 #define XLLF_INT_ALL_MASK 0xfff80000
0098 #define XLLF_INT_ERROR_MASK 0xf2000000
0099 #define XLLF_INT_RXERROR_MASK 0xe0000000
0100 #define XLLF_INT_TXERROR_MASK 0x12000000
0101
0102
0103
0104
0105
0106 static int read_timeout = 1000;
0107 static int write_timeout = 1000;
0108
0109
0110
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
0121
0122
0123
0124 struct axis_fifo {
0125 int irq;
0126 void __iomem *base_addr;
0127
0128 unsigned int rx_fifo_depth;
0129 unsigned int tx_fifo_depth;
0130 int has_rx_fifo;
0131 int has_tx_fifo;
0132
0133 wait_queue_head_t read_queue;
0134 struct mutex read_lock;
0135 wait_queue_head_t write_queue;
0136 struct mutex write_lock;
0137 unsigned int write_flags;
0138 unsigned int read_flags;
0139
0140 struct device *dt_device;
0141 struct miscdevice miscdev;
0142 };
0143
0144
0145
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
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
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
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
0370
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
0381
0382
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
0421
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
0432
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
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
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
0511
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
0523
0524
0525
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
0548
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
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
0592
0593
0594 wake_up(&fifo->read_queue);
0595
0596
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
0601
0602
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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;
0813 struct device *dev = &pdev->dev;
0814 struct axis_fifo *fifo = NULL;
0815 char *device_name;
0816 int rc = 0;
0817
0818
0819
0820
0821
0822
0823 device_name = devm_kzalloc(dev, 32, GFP_KERNEL);
0824 if (!device_name)
0825 return -ENOMEM;
0826
0827
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
0843
0844
0845
0846
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
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
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
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
0880
0881
0882
0883
0884 rc = platform_get_irq(pdev, 0);
0885 if (rc < 0)
0886 goto err_initial;
0887
0888
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
0900
0901
0902
0903
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");