aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/rc/rc-main.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index e6e3ec7141bf..b1a690054834 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -918,11 +918,12 @@ static ssize_t store_protocols(struct device *device,
918 struct rc_filter_attribute *fattr = to_rc_filter_attr(mattr); 918 struct rc_filter_attribute *fattr = to_rc_filter_attr(mattr);
919 bool enable, disable; 919 bool enable, disable;
920 const char *tmp; 920 const char *tmp;
921 u64 type; 921 u64 old_type, type;
922 u64 mask; 922 u64 mask;
923 int rc, i, count = 0; 923 int rc, i, count = 0;
924 ssize_t ret; 924 ssize_t ret;
925 int (*change_protocol)(struct rc_dev *dev, u64 *rc_type); 925 int (*change_protocol)(struct rc_dev *dev, u64 *rc_type);
926 struct rc_scancode_filter local_filter, *filter;
926 927
927 /* Device is being removed */ 928 /* Device is being removed */
928 if (!dev) 929 if (!dev)
@@ -935,7 +936,8 @@ static ssize_t store_protocols(struct device *device,
935 ret = -EINVAL; 936 ret = -EINVAL;
936 goto out; 937 goto out;
937 } 938 }
938 type = dev->enabled_protocols[fattr->type]; 939 old_type = dev->enabled_protocols[fattr->type];
940 type = old_type;
939 941
940 while ((tmp = strsep((char **) &data, " \n")) != NULL) { 942 while ((tmp = strsep((char **) &data, " \n")) != NULL) {
941 if (!*tmp) 943 if (!*tmp)
@@ -999,6 +1001,36 @@ static ssize_t store_protocols(struct device *device,
999 IR_dprintk(1, "Current protocol(s): 0x%llx\n", 1001 IR_dprintk(1, "Current protocol(s): 0x%llx\n",
1000 (long long)type); 1002 (long long)type);
1001 1003
1004 /*
1005 * If the protocol is changed the filter needs updating.
1006 * Try setting the same filter with the new protocol (if any).
1007 * Fall back to clearing the filter.
1008 */
1009 filter = &dev->scancode_filters[fattr->type];
1010 if (old_type != type && filter->mask) {
1011 local_filter = *filter;
1012 if (!type) {
1013 /* no protocol => clear filter */
1014 ret = -1;
1015 } else if (!dev->s_filter) {
1016 /* generic filtering => accept any filter */
1017 ret = 0;
1018 } else {
1019 /* hardware filtering => try setting, otherwise clear */
1020 ret = dev->s_filter(dev, fattr->type, &local_filter);
1021 }
1022 if (ret < 0) {
1023 /* clear the filter */
1024 local_filter.data = 0;
1025 local_filter.mask = 0;
1026 if (dev->s_filter)
1027 dev->s_filter(dev, fattr->type, &local_filter);
1028 }
1029
1030 /* commit the new filter */
1031 *filter = local_filter;
1032 }
1033
1002 ret = len; 1034 ret = len;
1003 1035
1004out: 1036out:
@@ -1096,6 +1128,11 @@ static ssize_t store_filter(struct device *device,
1096 local_filter.mask = val; 1128 local_filter.mask = val;
1097 else 1129 else
1098 local_filter.data = val; 1130 local_filter.data = val;
1131 if (!dev->enabled_protocols[fattr->type] && local_filter.mask) {
1132 /* refuse to set a filter unless a protocol is enabled */
1133 ret = -EINVAL;
1134 goto unlock;
1135 }
1099 if (dev->s_filter) { 1136 if (dev->s_filter) {
1100 ret = dev->s_filter(dev, fattr->type, &local_filter); 1137 ret = dev->s_filter(dev, fattr->type, &local_filter);
1101 if (ret < 0) 1138 if (ret < 0)