aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/rc/rc-main.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-24 00:12:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-24 00:12:49 -0400
commitdf462b3dbeeaae7141f1b63cbfcc1e1bae6a85fc (patch)
treebca52fce066159f136d75c69e79016422212cb1d /drivers/media/rc/rc-main.c
parent343800e7d20944aead238c2c6e3f7789f8b6587c (diff)
parentcf25220677b3f10468a74278130fe224f73632a6 (diff)
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (247 commits) [media] gspca - sunplus: Fix some warnings and simplify code [media] gspca: Fix some warnings tied to 'no debug' [media] gspca: Unset debug by default [media] gspca - cpia1: Remove a bad conditional compilation instruction [media] gspca - main: Remove USB traces [media] gspca - main: Version change to 2.13 [media] gspca - stk014 / t613: Accept the index 0 in querymenu [media] gspca - kinect: Remove __devinitdata [media] gspca - cpia1: Fix some warnings [media] video/Kconfig: Fix mis-classified devices [media] support for medion dvb stick 1660:1921 [media] tm6000: fix uninitialized field, change prink to dprintk [media] cx231xx: Add support for Iconbit U100 [media] saa7134 add new TV cards [media] Use a more consistent value for RC repeat period [media] cx18: Move spinlock and vb_type initialisation into stream_init [media] tm6000: remove tm6010 sif audio start and stop [media] tm6000: remove unused exports [media] tm6000: add pts logging [media] tm6000: change from ioctl to unlocked_ioctl ...
Diffstat (limited to 'drivers/media/rc/rc-main.c')
-rw-r--r--drivers/media/rc/rc-main.c54
1 files changed, 48 insertions, 6 deletions
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index a2706648e365..f57cd5677ac2 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -749,6 +749,9 @@ static struct {
749 * it is trigged by reading /sys/class/rc/rc?/protocols. 749 * it is trigged by reading /sys/class/rc/rc?/protocols.
750 * It returns the protocol names of supported protocols. 750 * It returns the protocol names of supported protocols.
751 * Enabled protocols are printed in brackets. 751 * Enabled protocols are printed in brackets.
752 *
753 * dev->lock is taken to guard against races between device
754 * registration, store_protocols and show_protocols.
752 */ 755 */
753static ssize_t show_protocols(struct device *device, 756static ssize_t show_protocols(struct device *device,
754 struct device_attribute *mattr, char *buf) 757 struct device_attribute *mattr, char *buf)
@@ -762,6 +765,8 @@ static ssize_t show_protocols(struct device *device,
762 if (!dev) 765 if (!dev)
763 return -EINVAL; 766 return -EINVAL;
764 767
768 mutex_lock(&dev->lock);
769
765 if (dev->driver_type == RC_DRIVER_SCANCODE) { 770 if (dev->driver_type == RC_DRIVER_SCANCODE) {
766 enabled = dev->rc_map.rc_type; 771 enabled = dev->rc_map.rc_type;
767 allowed = dev->allowed_protos; 772 allowed = dev->allowed_protos;
@@ -784,6 +789,9 @@ static ssize_t show_protocols(struct device *device,
784 if (tmp != buf) 789 if (tmp != buf)
785 tmp--; 790 tmp--;
786 *tmp = '\n'; 791 *tmp = '\n';
792
793 mutex_unlock(&dev->lock);
794
787 return tmp + 1 - buf; 795 return tmp + 1 - buf;
788} 796}
789 797
@@ -802,6 +810,9 @@ static ssize_t show_protocols(struct device *device,
802 * Writing "none" will disable all protocols. 810 * Writing "none" will disable all protocols.
803 * Returns -EINVAL if an invalid protocol combination or unknown protocol name 811 * Returns -EINVAL if an invalid protocol combination or unknown protocol name
804 * is used, otherwise @len. 812 * is used, otherwise @len.
813 *
814 * dev->lock is taken to guard against races between device
815 * registration, store_protocols and show_protocols.
805 */ 816 */
806static ssize_t store_protocols(struct device *device, 817static ssize_t store_protocols(struct device *device,
807 struct device_attribute *mattr, 818 struct device_attribute *mattr,
@@ -815,18 +826,22 @@ static ssize_t store_protocols(struct device *device,
815 u64 mask; 826 u64 mask;
816 int rc, i, count = 0; 827 int rc, i, count = 0;
817 unsigned long flags; 828 unsigned long flags;
829 ssize_t ret;
818 830
819 /* Device is being removed */ 831 /* Device is being removed */
820 if (!dev) 832 if (!dev)
821 return -EINVAL; 833 return -EINVAL;
822 834
835 mutex_lock(&dev->lock);
836
823 if (dev->driver_type == RC_DRIVER_SCANCODE) 837 if (dev->driver_type == RC_DRIVER_SCANCODE)
824 type = dev->rc_map.rc_type; 838 type = dev->rc_map.rc_type;
825 else if (dev->raw) 839 else if (dev->raw)
826 type = dev->raw->enabled_protocols; 840 type = dev->raw->enabled_protocols;
827 else { 841 else {
828 IR_dprintk(1, "Protocol switching not supported\n"); 842 IR_dprintk(1, "Protocol switching not supported\n");
829 return -EINVAL; 843 ret = -EINVAL;
844 goto out;
830 } 845 }
831 846
832 while ((tmp = strsep((char **) &data, " \n")) != NULL) { 847 while ((tmp = strsep((char **) &data, " \n")) != NULL) {
@@ -860,7 +875,8 @@ static ssize_t store_protocols(struct device *device,
860 } 875 }
861 if (i == ARRAY_SIZE(proto_names)) { 876 if (i == ARRAY_SIZE(proto_names)) {
862 IR_dprintk(1, "Unknown protocol: '%s'\n", tmp); 877 IR_dprintk(1, "Unknown protocol: '%s'\n", tmp);
863 return -EINVAL; 878 ret = -EINVAL;
879 goto out;
864 } 880 }
865 count++; 881 count++;
866 } 882 }
@@ -875,7 +891,8 @@ static ssize_t store_protocols(struct device *device,
875 891
876 if (!count) { 892 if (!count) {
877 IR_dprintk(1, "Protocol not specified\n"); 893 IR_dprintk(1, "Protocol not specified\n");
878 return -EINVAL; 894 ret = -EINVAL;
895 goto out;
879 } 896 }
880 897
881 if (dev->change_protocol) { 898 if (dev->change_protocol) {
@@ -883,7 +900,8 @@ static ssize_t store_protocols(struct device *device,
883 if (rc < 0) { 900 if (rc < 0) {
884 IR_dprintk(1, "Error setting protocols to 0x%llx\n", 901 IR_dprintk(1, "Error setting protocols to 0x%llx\n",
885 (long long)type); 902 (long long)type);
886 return -EINVAL; 903 ret = -EINVAL;
904 goto out;
887 } 905 }
888 } 906 }
889 907
@@ -898,7 +916,11 @@ static ssize_t store_protocols(struct device *device,
898 IR_dprintk(1, "Current protocol(s): 0x%llx\n", 916 IR_dprintk(1, "Current protocol(s): 0x%llx\n",
899 (long long)type); 917 (long long)type);
900 918
901 return len; 919 ret = len;
920
921out:
922 mutex_unlock(&dev->lock);
923 return ret;
902} 924}
903 925
904static void rc_dev_release(struct device *device) 926static void rc_dev_release(struct device *device)
@@ -974,6 +996,7 @@ struct rc_dev *rc_allocate_device(void)
974 996
975 spin_lock_init(&dev->rc_map.lock); 997 spin_lock_init(&dev->rc_map.lock);
976 spin_lock_init(&dev->keylock); 998 spin_lock_init(&dev->keylock);
999 mutex_init(&dev->lock);
977 setup_timer(&dev->timer_keyup, ir_timer_keyup, (unsigned long)dev); 1000 setup_timer(&dev->timer_keyup, ir_timer_keyup, (unsigned long)dev);
978 1001
979 dev->dev.type = &rc_dev_type; 1002 dev->dev.type = &rc_dev_type;
@@ -1019,12 +1042,21 @@ int rc_register_device(struct rc_dev *dev)
1019 if (dev->close) 1042 if (dev->close)
1020 dev->input_dev->close = ir_close; 1043 dev->input_dev->close = ir_close;
1021 1044
1045 /*
1046 * Take the lock here, as the device sysfs node will appear
1047 * when device_add() is called, which may trigger an ir-keytable udev
1048 * rule, which will in turn call show_protocols and access either
1049 * dev->rc_map.rc_type or dev->raw->enabled_protocols before it has
1050 * been initialized.
1051 */
1052 mutex_lock(&dev->lock);
1053
1022 dev->devno = (unsigned long)(atomic_inc_return(&devno) - 1); 1054 dev->devno = (unsigned long)(atomic_inc_return(&devno) - 1);
1023 dev_set_name(&dev->dev, "rc%ld", dev->devno); 1055 dev_set_name(&dev->dev, "rc%ld", dev->devno);
1024 dev_set_drvdata(&dev->dev, dev); 1056 dev_set_drvdata(&dev->dev, dev);
1025 rc = device_add(&dev->dev); 1057 rc = device_add(&dev->dev);
1026 if (rc) 1058 if (rc)
1027 return rc; 1059 goto out_unlock;
1028 1060
1029 rc = ir_setkeytable(dev, rc_map); 1061 rc = ir_setkeytable(dev, rc_map);
1030 if (rc) 1062 if (rc)
@@ -1046,6 +1078,13 @@ int rc_register_device(struct rc_dev *dev)
1046 */ 1078 */
1047 dev->input_dev->rep[REP_DELAY] = 500; 1079 dev->input_dev->rep[REP_DELAY] = 500;
1048 1080
1081 /*
1082 * As a repeat event on protocols like RC-5 and NEC take as long as
1083 * 110/114ms, using 33ms as a repeat period is not the right thing
1084 * to do.
1085 */
1086 dev->input_dev->rep[REP_PERIOD] = 125;
1087
1049 path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL); 1088 path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
1050 printk(KERN_INFO "%s: %s as %s\n", 1089 printk(KERN_INFO "%s: %s as %s\n",
1051 dev_name(&dev->dev), 1090 dev_name(&dev->dev),
@@ -1058,6 +1097,7 @@ int rc_register_device(struct rc_dev *dev)
1058 if (rc < 0) 1097 if (rc < 0)
1059 goto out_input; 1098 goto out_input;
1060 } 1099 }
1100 mutex_unlock(&dev->lock);
1061 1101
1062 if (dev->change_protocol) { 1102 if (dev->change_protocol) {
1063 rc = dev->change_protocol(dev, rc_map->rc_type); 1103 rc = dev->change_protocol(dev, rc_map->rc_type);
@@ -1083,6 +1123,8 @@ out_table:
1083 ir_free_table(&dev->rc_map); 1123 ir_free_table(&dev->rc_map);
1084out_dev: 1124out_dev:
1085 device_del(&dev->dev); 1125 device_del(&dev->dev);
1126out_unlock:
1127 mutex_unlock(&dev->lock);
1086 return rc; 1128 return rc;
1087} 1129}
1088EXPORT_SYMBOL_GPL(rc_register_device); 1130EXPORT_SYMBOL_GPL(rc_register_device);