diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/char/xilinx_hwicap | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (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.c | 142 |
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. */ |
114 | static DEFINE_MUTEX(hwicap_mutex); | ||
115 | static bool probed_devices[HWICAP_DEVICES]; | 115 | static bool probed_devices[HWICAP_DEVICES]; |
116 | static struct mutex icap_sem; | 116 | static 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 | ||
572 | static int __devinit hwicap_setup(struct device *dev, int id, | 573 | static 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 | ||
716 | static int __devinit hwicap_drv_probe(struct platform_device *pdev) | 717 | #ifdef CONFIG_OF |
718 | static 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 | |
745 | static int __devexit hwicap_drv_remove(struct platform_device *pdev) | 754 | static 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 | ||
750 | static struct platform_driver hwicap_platform_driver = { | 761 | static const struct of_device_id __devinitconst hwicap_of_match[]; |
751 | .probe = hwicap_drv_probe, | 762 | static 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) | ||
764 | static int __devinit | ||
765 | hwicap_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 | ||
802 | static int __devexit hwicap_of_remove(struct platform_device *op) | 796 | static 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 */ | ||
808 | static const struct of_device_id __devinitconst hwicap_of_match[] = { | 803 | static 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 | }; |
813 | MODULE_DEVICE_TABLE(of, hwicap_of_match); | 808 | MODULE_DEVICE_TABLE(of, hwicap_of_match); |
809 | #else | ||
810 | #define hwicap_of_match NULL | ||
811 | #endif | ||
814 | 812 | ||
815 | static struct of_platform_driver hwicap_of_driver = { | 813 | static 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 */ | ||
826 | static 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 | |||
832 | static 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 */ | ||
838 | static inline int __init hwicap_of_register(void) { return 0; } | ||
839 | static inline void __exit hwicap_of_unregister(void) { } | ||
840 | #endif /* CONFIG_OF */ | ||
841 | |||
842 | static int __init hwicap_module_init(void) | 823 | static 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 | ||