aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/carma/carma-fpga.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/misc/carma/carma-fpga.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/misc/carma/carma-fpga.c')
-rw-r--r--drivers/misc/carma/carma-fpga.c140
1 files changed, 64 insertions, 76 deletions
diff --git a/drivers/misc/carma/carma-fpga.c b/drivers/misc/carma/carma-fpga.c
index 8835eabb3b8..3965821fef1 100644
--- a/drivers/misc/carma/carma-fpga.c
+++ b/drivers/misc/carma/carma-fpga.c
@@ -560,9 +560,6 @@ static void data_enable_interrupts(struct fpga_device *priv)
560 560
561 /* flush the writes */ 561 /* flush the writes */
562 fpga_read_reg(priv, 0, MMAP_REG_STATUS); 562 fpga_read_reg(priv, 0, MMAP_REG_STATUS);
563 fpga_read_reg(priv, 1, MMAP_REG_STATUS);
564 fpga_read_reg(priv, 2, MMAP_REG_STATUS);
565 fpga_read_reg(priv, 3, MMAP_REG_STATUS);
566 563
567 /* switch back to the external interrupt source */ 564 /* switch back to the external interrupt source */
568 iowrite32be(0x3F, priv->regs + SYS_IRQ_SOURCE_CTL); 565 iowrite32be(0x3F, priv->regs + SYS_IRQ_SOURCE_CTL);
@@ -594,12 +591,8 @@ static void data_dma_cb(void *data)
594 list_move_tail(&priv->inflight->entry, &priv->used); 591 list_move_tail(&priv->inflight->entry, &priv->used);
595 priv->inflight = NULL; 592 priv->inflight = NULL;
596 593
597 /* 594 /* clear the FPGA status and re-enable interrupts */
598 * If data dumping is still enabled, then clear the FPGA 595 data_enable_interrupts(priv);
599 * status registers and re-enable FPGA interrupts
600 */
601 if (priv->enabled)
602 data_enable_interrupts(priv);
603 596
604 spin_unlock_irqrestore(&priv->lock, flags); 597 spin_unlock_irqrestore(&priv->lock, flags);
605 598
@@ -666,7 +659,7 @@ static int data_submit_dma(struct fpga_device *priv, struct data_buf *buf)
666 src = SYS_FPGA_BLOCK; 659 src = SYS_FPGA_BLOCK;
667 tx = chan->device->device_prep_dma_memcpy(chan, dst, src, 660 tx = chan->device->device_prep_dma_memcpy(chan, dst, src,
668 REG_BLOCK_SIZE, 661 REG_BLOCK_SIZE,
669 0); 662 DMA_PREP_INTERRUPT);
670 if (!tx) { 663 if (!tx) {
671 dev_err(priv->dev, "unable to prep SYS-FPGA DMA\n"); 664 dev_err(priv->dev, "unable to prep SYS-FPGA DMA\n");
672 return -ENOMEM; 665 return -ENOMEM;
@@ -715,15 +708,6 @@ static irqreturn_t data_irq(int irq, void *dev_id)
715 708
716 spin_lock(&priv->lock); 709 spin_lock(&priv->lock);
717 710
718 /*
719 * This is an error case that should never happen.
720 *
721 * If this driver has a bug and manages to re-enable interrupts while
722 * a DMA is in progress, then we will hit this statement and should
723 * start paying attention immediately.
724 */
725 BUG_ON(priv->inflight != NULL);
726
727 /* hide the interrupt by switching the IRQ driver to GPIO */ 711 /* hide the interrupt by switching the IRQ driver to GPIO */
728 data_disable_interrupts(priv); 712 data_disable_interrupts(priv);
729 713
@@ -778,15 +762,11 @@ out:
778 */ 762 */
779static int data_device_enable(struct fpga_device *priv) 763static int data_device_enable(struct fpga_device *priv)
780{ 764{
781 bool enabled;
782 u32 val; 765 u32 val;
783 int ret; 766 int ret;
784 767
785 /* multiple enables are safe: they do nothing */ 768 /* multiple enables are safe: they do nothing */
786 spin_lock_irq(&priv->lock); 769 if (priv->enabled)
787 enabled = priv->enabled;
788 spin_unlock_irq(&priv->lock);
789 if (enabled)
790 return 0; 770 return 0;
791 771
792 /* check that the FPGAs are programmed */ 772 /* check that the FPGAs are programmed */
@@ -817,9 +797,6 @@ static int data_device_enable(struct fpga_device *priv)
817 goto out_error; 797 goto out_error;
818 } 798 }
819 799
820 /* prevent the FPGAs from generating interrupts */
821 data_disable_interrupts(priv);
822
823 /* hookup the irq handler */ 800 /* hookup the irq handler */
824 ret = request_irq(priv->irq, data_irq, IRQF_SHARED, drv_name, priv); 801 ret = request_irq(priv->irq, data_irq, IRQF_SHARED, drv_name, priv);
825 if (ret) { 802 if (ret) {
@@ -827,13 +804,11 @@ static int data_device_enable(struct fpga_device *priv)
827 goto out_error; 804 goto out_error;
828 } 805 }
829 806
830 /* allow the DMA callback to re-enable FPGA interrupts */ 807 /* switch to the external FPGA IRQ line */
831 spin_lock_irq(&priv->lock);
832 priv->enabled = true;
833 spin_unlock_irq(&priv->lock);
834
835 /* allow the FPGAs to generate interrupts */
836 data_enable_interrupts(priv); 808 data_enable_interrupts(priv);
809
810 /* success, we're enabled */
811 priv->enabled = true;
837 return 0; 812 return 0;
838 813
839out_error: 814out_error:
@@ -859,40 +834,41 @@ out_error:
859 */ 834 */
860static int data_device_disable(struct fpga_device *priv) 835static int data_device_disable(struct fpga_device *priv)
861{ 836{
862 spin_lock_irq(&priv->lock); 837 int ret;
863 838
864 /* allow multiple disable */ 839 /* allow multiple disable */
865 if (!priv->enabled) { 840 if (!priv->enabled)
866 spin_unlock_irq(&priv->lock);
867 return 0; 841 return 0;
868 }
869
870 /*
871 * Mark the device disabled
872 *
873 * This stops DMA callbacks from re-enabling interrupts
874 */
875 priv->enabled = false;
876 842
877 /* prevent the FPGAs from generating interrupts */ 843 /* switch to the internal GPIO IRQ line */
878 data_disable_interrupts(priv); 844 data_disable_interrupts(priv);
879 845
880 /* wait until all ongoing DMA has finished */
881 while (priv->inflight != NULL) {
882 spin_unlock_irq(&priv->lock);
883 wait_event(priv->wait, priv->inflight == NULL);
884 spin_lock_irq(&priv->lock);
885 }
886
887 spin_unlock_irq(&priv->lock);
888
889 /* unhook the irq handler */ 846 /* unhook the irq handler */
890 free_irq(priv->irq, priv); 847 free_irq(priv->irq, priv);
891 848
849 /*
850 * wait for all outstanding DMA to complete
851 *
852 * Device interrupts are disabled, therefore another buffer cannot
853 * be marked inflight.
854 */
855 ret = wait_event_interruptible(priv->wait, priv->inflight == NULL);
856 if (ret)
857 return ret;
858
892 /* free the correlation table */ 859 /* free the correlation table */
893 sg_free_table(&priv->corl_table); 860 sg_free_table(&priv->corl_table);
894 priv->corl_nents = 0; 861 priv->corl_nents = 0;
895 862
863 /*
864 * We are taking the spinlock not to protect priv->enabled, but instead
865 * to make sure that there are no readers in the process of altering
866 * the free or used lists while we are setting this flag.
867 */
868 spin_lock_irq(&priv->lock);
869 priv->enabled = false;
870 spin_unlock_irq(&priv->lock);
871
896 /* free all buffers: the free and used lists are not being changed */ 872 /* free all buffers: the free and used lists are not being changed */
897 data_free_buffers(priv); 873 data_free_buffers(priv);
898 return 0; 874 return 0;
@@ -920,6 +896,15 @@ static unsigned int list_num_entries(struct list_head *list)
920static int data_debug_show(struct seq_file *f, void *offset) 896static int data_debug_show(struct seq_file *f, void *offset)
921{ 897{
922 struct fpga_device *priv = f->private; 898 struct fpga_device *priv = f->private;
899 int ret;
900
901 /*
902 * Lock the mutex first, so that we get an accurate value for enable
903 * Lock the spinlock next, to get accurate list counts
904 */
905 ret = mutex_lock_interruptible(&priv->mutex);
906 if (ret)
907 return ret;
923 908
924 spin_lock_irq(&priv->lock); 909 spin_lock_irq(&priv->lock);
925 910
@@ -932,6 +917,7 @@ static int data_debug_show(struct seq_file *f, void *offset)
932 seq_printf(f, "num_dropped: %d\n", priv->num_dropped); 917 seq_printf(f, "num_dropped: %d\n", priv->num_dropped);
933 918
934 spin_unlock_irq(&priv->lock); 919 spin_unlock_irq(&priv->lock);
920 mutex_unlock(&priv->mutex);
935 return 0; 921 return 0;
936} 922}
937 923
@@ -984,13 +970,7 @@ static ssize_t data_en_show(struct device *dev, struct device_attribute *attr,
984 char *buf) 970 char *buf)
985{ 971{
986 struct fpga_device *priv = dev_get_drvdata(dev); 972 struct fpga_device *priv = dev_get_drvdata(dev);
987 int ret; 973 return snprintf(buf, PAGE_SIZE, "%u\n", priv->enabled);
988
989 spin_lock_irq(&priv->lock);
990 ret = snprintf(buf, PAGE_SIZE, "%u\n", priv->enabled);
991 spin_unlock_irq(&priv->lock);
992
993 return ret;
994} 974}
995 975
996static ssize_t data_en_set(struct device *dev, struct device_attribute *attr, 976static ssize_t data_en_set(struct device *dev, struct device_attribute *attr,
@@ -1006,7 +986,6 @@ static ssize_t data_en_set(struct device *dev, struct device_attribute *attr,
1006 return -EINVAL; 986 return -EINVAL;
1007 } 987 }
1008 988
1009 /* protect against concurrent enable/disable */
1010 ret = mutex_lock_interruptible(&priv->mutex); 989 ret = mutex_lock_interruptible(&priv->mutex);
1011 if (ret) 990 if (ret)
1012 return ret; 991 return ret;
@@ -1100,7 +1079,6 @@ static ssize_t data_read(struct file *filp, char __user *ubuf, size_t count,
1100 struct fpga_reader *reader = filp->private_data; 1079 struct fpga_reader *reader = filp->private_data;
1101 struct fpga_device *priv = reader->priv; 1080 struct fpga_device *priv = reader->priv;
1102 struct list_head *used = &priv->used; 1081 struct list_head *used = &priv->used;
1103 bool drop_buffer = false;
1104 struct data_buf *dbuf; 1082 struct data_buf *dbuf;
1105 size_t avail; 1083 size_t avail;
1106 void *data; 1084 void *data;
@@ -1188,12 +1166,10 @@ have_buffer:
1188 * One of two things has happened, the device is disabled, or the 1166 * One of two things has happened, the device is disabled, or the
1189 * device has been reconfigured underneath us. In either case, we 1167 * device has been reconfigured underneath us. In either case, we
1190 * should just throw away the buffer. 1168 * should just throw away the buffer.
1191 *
1192 * Lockdep complains if this is done under the spinlock, so we
1193 * handle it during the unlock path.
1194 */ 1169 */
1195 if (!priv->enabled || dbuf->size != priv->bufsize) { 1170 if (!priv->enabled || dbuf->size != priv->bufsize) {
1196 drop_buffer = true; 1171 videobuf_dma_unmap(priv->dev, &dbuf->vb);
1172 data_free_buffer(dbuf);
1197 goto out_unlock; 1173 goto out_unlock;
1198 } 1174 }
1199 1175
@@ -1202,12 +1178,6 @@ have_buffer:
1202 1178
1203out_unlock: 1179out_unlock:
1204 spin_unlock_irq(&priv->lock); 1180 spin_unlock_irq(&priv->lock);
1205
1206 if (drop_buffer) {
1207 videobuf_dma_unmap(priv->dev, &dbuf->vb);
1208 data_free_buffer(dbuf);
1209 }
1210
1211 return count; 1181 return count;
1212} 1182}
1213 1183
@@ -1243,6 +1213,8 @@ static int data_mmap(struct file *filp, struct vm_area_struct *vma)
1243 return -EINVAL; 1213 return -EINVAL;
1244 } 1214 }
1245 1215
1216 /* IO memory (stop cacheing) */
1217 vma->vm_flags |= VM_IO | VM_RESERVED;
1246 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 1218 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
1247 1219
1248 return io_remap_pfn_range(vma, vma->vm_start, addr, vsize, 1220 return io_remap_pfn_range(vma, vma->vm_start, addr, vsize,
@@ -1277,7 +1249,8 @@ static bool dma_filter(struct dma_chan *chan, void *data)
1277 return true; 1249 return true;
1278} 1250}
1279 1251
1280static int data_of_probe(struct platform_device *op) 1252static int data_of_probe(struct platform_device *op,
1253 const struct of_device_id *match)
1281{ 1254{
1282 struct device_node *of_node = op->dev.of_node; 1255 struct device_node *of_node = op->dev.of_node;
1283 struct device *this_device; 1256 struct device *this_device;
@@ -1428,7 +1401,7 @@ static struct of_device_id data_of_match[] = {
1428 {}, 1401 {},
1429}; 1402};
1430 1403
1431static struct platform_driver data_of_driver = { 1404static struct of_platform_driver data_of_driver = {
1432 .probe = data_of_probe, 1405 .probe = data_of_probe,
1433 .remove = data_of_remove, 1406 .remove = data_of_remove,
1434 .driver = { 1407 .driver = {
@@ -1438,8 +1411,23 @@ static struct platform_driver data_of_driver = {
1438 }, 1411 },
1439}; 1412};
1440 1413
1441module_platform_driver(data_of_driver); 1414/*
1415 * Module Init / Exit
1416 */
1417
1418static int __init data_init(void)
1419{
1420 return of_register_platform_driver(&data_of_driver);
1421}
1422
1423static void __exit data_exit(void)
1424{
1425 of_unregister_platform_driver(&data_of_driver);
1426}
1442 1427
1443MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>"); 1428MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>");
1444MODULE_DESCRIPTION("CARMA DATA-FPGA Access Driver"); 1429MODULE_DESCRIPTION("CARMA DATA-FPGA Access Driver");
1445MODULE_LICENSE("GPL"); 1430MODULE_LICENSE("GPL");
1431
1432module_init(data_init);
1433module_exit(data_exit);