aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/xilinx_hwicap
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/char/xilinx_hwicap
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/char/xilinx_hwicap')
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.c142
1 files changed, 56 insertions, 86 deletions
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
index b663d573aad9..39ccdeada791 100644
--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -67,7 +67,7 @@
67 * cp foo.bit /dev/icap0 67 * cp foo.bit /dev/icap0
68 * 68 *
69 * Note that unless foo.bit is an appropriately constructed partial 69 * Note that unless foo.bit is an appropriately constructed partial
70 * bitstream, this has a high likelyhood of overwriting the design 70 * bitstream, this has a high likelihood of overwriting the design
71 * currently programmed in the FPGA. 71 * currently programmed in the FPGA.
72 */ 72 */
73 73
@@ -81,7 +81,6 @@
81#include <linux/poll.h> 81#include <linux/poll.h>
82#include <linux/proc_fs.h> 82#include <linux/proc_fs.h>
83#include <linux/mutex.h> 83#include <linux/mutex.h>
84#include <linux/smp_lock.h>
85#include <linux/sysctl.h> 84#include <linux/sysctl.h>
86#include <linux/fs.h> 85#include <linux/fs.h>
87#include <linux/cdev.h> 86#include <linux/cdev.h>
@@ -112,6 +111,7 @@
112#define HWICAP_DEVICES 1 111#define HWICAP_DEVICES 1
113 112
114/* An array, which is set to true when the device is registered. */ 113/* An array, which is set to true when the device is registered. */
114static DEFINE_MUTEX(hwicap_mutex);
115static bool probed_devices[HWICAP_DEVICES]; 115static bool probed_devices[HWICAP_DEVICES];
116static struct mutex icap_sem; 116static struct mutex icap_sem;
117 117
@@ -502,7 +502,7 @@ static int hwicap_open(struct inode *inode, struct file *file)
502 struct hwicap_drvdata *drvdata; 502 struct hwicap_drvdata *drvdata;
503 int status; 503 int status;
504 504
505 lock_kernel(); 505 mutex_lock(&hwicap_mutex);
506 drvdata = container_of(inode->i_cdev, struct hwicap_drvdata, cdev); 506 drvdata = container_of(inode->i_cdev, struct hwicap_drvdata, cdev);
507 507
508 status = mutex_lock_interruptible(&drvdata->sem); 508 status = mutex_lock_interruptible(&drvdata->sem);
@@ -528,7 +528,7 @@ static int hwicap_open(struct inode *inode, struct file *file)
528 error: 528 error:
529 mutex_unlock(&drvdata->sem); 529 mutex_unlock(&drvdata->sem);
530 out: 530 out:
531 unlock_kernel(); 531 mutex_unlock(&hwicap_mutex);
532 return status; 532 return status;
533} 533}
534 534
@@ -567,6 +567,7 @@ static const struct file_operations hwicap_fops = {
567 .read = hwicap_read, 567 .read = hwicap_read,
568 .open = hwicap_open, 568 .open = hwicap_open,
569 .release = hwicap_release, 569 .release = hwicap_release,
570 .llseek = noop_llseek,
570}; 571};
571 572
572static int __devinit hwicap_setup(struct device *dev, int id, 573static int __devinit hwicap_setup(struct device *dev, int id,
@@ -713,20 +714,29 @@ static int __devexit hwicap_remove(struct device *dev)
713 return 0; /* success */ 714 return 0; /* success */
714} 715}
715 716
716static int __devinit hwicap_drv_probe(struct platform_device *pdev) 717#ifdef CONFIG_OF
718static int __devinit hwicap_of_probe(struct platform_device *op,
719 const struct hwicap_driver_config *config)
717{ 720{
718 struct resource *res; 721 struct resource res;
719 const struct config_registers *regs; 722 const unsigned int *id;
720 const char *family; 723 const char *family;
724 int rc;
725 const struct config_registers *regs;
721 726
722 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 727
723 if (!res) 728 rc = of_address_to_resource(op->dev.of_node, 0, &res);
724 return -ENODEV; 729 if (rc) {
730 dev_err(&op->dev, "invalid address\n");
731 return rc;
732 }
733
734 id = of_get_property(op->dev.of_node, "port-number", NULL);
725 735
726 /* It's most likely that we're using V4, if the family is not 736 /* It's most likely that we're using V4, if the family is not
727 specified */ 737 specified */
728 regs = &v4_config_registers; 738 regs = &v4_config_registers;
729 family = pdev->dev.platform_data; 739 family = of_get_property(op->dev.of_node, "xlnx,family", NULL);
730 740
731 if (family) { 741 if (family) {
732 if (!strcmp(family, "virtex2p")) { 742 if (!strcmp(family, "virtex2p")) {
@@ -737,54 +747,37 @@ static int __devinit hwicap_drv_probe(struct platform_device *pdev)
737 regs = &v5_config_registers; 747 regs = &v5_config_registers;
738 } 748 }
739 } 749 }
740 750 return hwicap_setup(&op->dev, id ? *id : -1, &res, config,
741 return hwicap_setup(&pdev->dev, pdev->id, res, 751 regs);
742 &buffer_icap_config, regs);
743} 752}
744 753#else
745static int __devexit hwicap_drv_remove(struct platform_device *pdev) 754static inline int hwicap_of_probe(struct platform_device *op,
755 const struct hwicap_driver_config *config)
746{ 756{
747 return hwicap_remove(&pdev->dev); 757 return -EINVAL;
748} 758}
759#endif /* CONFIG_OF */
749 760
750static struct platform_driver hwicap_platform_driver = { 761static const struct of_device_id __devinitconst hwicap_of_match[];
751 .probe = hwicap_drv_probe, 762static int __devinit hwicap_drv_probe(struct platform_device *pdev)
752 .remove = hwicap_drv_remove,
753 .driver = {
754 .owner = THIS_MODULE,
755 .name = DRIVER_NAME,
756 },
757};
758
759/* ---------------------------------------------------------------------
760 * OF bus binding
761 */
762
763#if defined(CONFIG_OF)
764static int __devinit
765hwicap_of_probe(struct platform_device *op, const struct of_device_id *match)
766{ 763{
767 struct resource res; 764 const struct of_device_id *match;
768 const unsigned int *id; 765 struct resource *res;
769 const char *family;
770 int rc;
771 const struct hwicap_driver_config *config = match->data;
772 const struct config_registers *regs; 766 const struct config_registers *regs;
767 const char *family;
773 768
774 dev_dbg(&op->dev, "hwicap_of_probe(%p, %p)\n", op, match); 769 match = of_match_device(hwicap_of_match, &pdev->dev);
775 770 if (match)
776 rc = of_address_to_resource(op->dev.of_node, 0, &res); 771 return hwicap_of_probe(pdev, match->data);
777 if (rc) {
778 dev_err(&op->dev, "invalid address\n");
779 return rc;
780 }
781 772
782 id = of_get_property(op->dev.of_node, "port-number", NULL); 773 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
774 if (!res)
775 return -ENODEV;
783 776
784 /* It's most likely that we're using V4, if the family is not 777 /* It's most likely that we're using V4, if the family is not
785 specified */ 778 specified */
786 regs = &v4_config_registers; 779 regs = &v4_config_registers;
787 family = of_get_property(op->dev.of_node, "xlnx,family", NULL); 780 family = pdev->dev.platform_data;
788 781
789 if (family) { 782 if (family) {
790 if (!strcmp(family, "virtex2p")) { 783 if (!strcmp(family, "virtex2p")) {
@@ -795,50 +788,38 @@ hwicap_of_probe(struct platform_device *op, const struct of_device_id *match)
795 regs = &v5_config_registers; 788 regs = &v5_config_registers;
796 } 789 }
797 } 790 }
798 return hwicap_setup(&op->dev, id ? *id : -1, &res, config, 791
799 regs); 792 return hwicap_setup(&pdev->dev, pdev->id, res,
793 &buffer_icap_config, regs);
800} 794}
801 795
802static int __devexit hwicap_of_remove(struct platform_device *op) 796static int __devexit hwicap_drv_remove(struct platform_device *pdev)
803{ 797{
804 return hwicap_remove(&op->dev); 798 return hwicap_remove(&pdev->dev);
805} 799}
806 800
807/* Match table for of_platform binding */ 801#ifdef CONFIG_OF
802/* Match table for device tree binding */
808static const struct of_device_id __devinitconst hwicap_of_match[] = { 803static const struct of_device_id __devinitconst hwicap_of_match[] = {
809 { .compatible = "xlnx,opb-hwicap-1.00.b", .data = &buffer_icap_config}, 804 { .compatible = "xlnx,opb-hwicap-1.00.b", .data = &buffer_icap_config},
810 { .compatible = "xlnx,xps-hwicap-1.00.a", .data = &fifo_icap_config}, 805 { .compatible = "xlnx,xps-hwicap-1.00.a", .data = &fifo_icap_config},
811 {}, 806 {},
812}; 807};
813MODULE_DEVICE_TABLE(of, hwicap_of_match); 808MODULE_DEVICE_TABLE(of, hwicap_of_match);
809#else
810#define hwicap_of_match NULL
811#endif
814 812
815static struct of_platform_driver hwicap_of_driver = { 813static struct platform_driver hwicap_platform_driver = {
816 .probe = hwicap_of_probe, 814 .probe = hwicap_drv_probe,
817 .remove = __devexit_p(hwicap_of_remove), 815 .remove = hwicap_drv_remove,
818 .driver = { 816 .driver = {
819 .name = DRIVER_NAME,
820 .owner = THIS_MODULE, 817 .owner = THIS_MODULE,
818 .name = DRIVER_NAME,
821 .of_match_table = hwicap_of_match, 819 .of_match_table = hwicap_of_match,
822 }, 820 },
823}; 821};
824 822
825/* Registration helpers to keep the number of #ifdefs to a minimum */
826static inline int __init hwicap_of_register(void)
827{
828 pr_debug("hwicap: calling of_register_platform_driver()\n");
829 return of_register_platform_driver(&hwicap_of_driver);
830}
831
832static inline void __exit hwicap_of_unregister(void)
833{
834 of_unregister_platform_driver(&hwicap_of_driver);
835}
836#else /* CONFIG_OF */
837/* CONFIG_OF not enabled; do nothing helpers */
838static inline int __init hwicap_of_register(void) { return 0; }
839static inline void __exit hwicap_of_unregister(void) { }
840#endif /* CONFIG_OF */
841
842static int __init hwicap_module_init(void) 823static int __init hwicap_module_init(void)
843{ 824{
844 dev_t devt; 825 dev_t devt;
@@ -855,21 +836,12 @@ static int __init hwicap_module_init(void)
855 return retval; 836 return retval;
856 837
857 retval = platform_driver_register(&hwicap_platform_driver); 838 retval = platform_driver_register(&hwicap_platform_driver);
858
859 if (retval)
860 goto failed1;
861
862 retval = hwicap_of_register();
863
864 if (retval) 839 if (retval)
865 goto failed2; 840 goto failed;
866 841
867 return retval; 842 return retval;
868 843
869 failed2: 844 failed:
870 platform_driver_unregister(&hwicap_platform_driver);
871
872 failed1:
873 unregister_chrdev_region(devt, HWICAP_DEVICES); 845 unregister_chrdev_region(devt, HWICAP_DEVICES);
874 846
875 return retval; 847 return retval;
@@ -883,8 +855,6 @@ static void __exit hwicap_module_cleanup(void)
883 855
884 platform_driver_unregister(&hwicap_platform_driver); 856 platform_driver_unregister(&hwicap_platform_driver);
885 857
886 hwicap_of_unregister();
887
888 unregister_chrdev_region(devt, HWICAP_DEVICES); 858 unregister_chrdev_region(devt, HWICAP_DEVICES);
889} 859}
890 860