From 773bcf8c9ce04c62c513182620efb729c97452fc Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 6 Apr 2014 10:48:31 -0300 Subject: [media] v4l2-common: fix warning when used on userpace As reported by Linus, make headers_check is reporting: usr/include/linux/v4l2-common.h:72: found __[us]{8,16,32,64} type without #include which seems to have come in through commits 777f4f85b75f1 and 254a47770163f. That happens because struct v4l2_edid should be visible by both subdev and V4L2 APIs. So, it was moved to v4l2-common.h. As Linus pointed, the proper fix is to just add an include for linux/types.h at v4l2-common.h. Reported-by: Linus Torvalds Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/v4l2-common.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/uapi/linux/v4l2-common.h b/include/uapi/linux/v4l2-common.h index 270db8914c01..9bf508ad0957 100644 --- a/include/uapi/linux/v4l2-common.h +++ b/include/uapi/linux/v4l2-common.h @@ -29,6 +29,8 @@ #ifndef __V4L2_COMMON__ #define __V4L2_COMMON__ +#include + /* * * Selection interface definitions -- cgit v1.2.3 From 23c843b5eb11198e7de3a2af0756d1f897117932 Mon Sep 17 00:00:00 2001 From: David Härdeman Date: Fri, 4 Apr 2014 19:06:01 -0300 Subject: [media] rc-core: split dev->s_filter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Overloading dev->s_filter to do two different functions (set wakeup filters and generic hardware filters) makes it impossible to tell what the hardware actually supports, so create a separate dev->s_wakeup_filter and make the distinction explicit. Signed-off-by: David Härdeman Acked-by: James Hogan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/img-ir/img-ir-hw.c | 15 ++++++++++++++- drivers/media/rc/rc-main.c | 24 +++++++++++++++++------- include/media/rc-core.h | 6 ++++-- 3 files changed, 35 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/drivers/media/rc/img-ir/img-ir-hw.c b/drivers/media/rc/img-ir/img-ir-hw.c index 579a52b3edce..0127dd257a57 100644 --- a/drivers/media/rc/img-ir/img-ir-hw.c +++ b/drivers/media/rc/img-ir/img-ir-hw.c @@ -504,6 +504,18 @@ unlock: return ret; } +static int img_ir_set_normal_filter(struct rc_dev *dev, + struct rc_scancode_filter *sc_filter) +{ + return img_ir_set_filter(dev, RC_FILTER_NORMAL, sc_filter); +} + +static int img_ir_set_wakeup_filter(struct rc_dev *dev, + struct rc_scancode_filter *sc_filter) +{ + return img_ir_set_filter(dev, RC_FILTER_WAKEUP, sc_filter); +} + /** * img_ir_set_decoder() - Set the current decoder. * @priv: IR private data. @@ -986,7 +998,8 @@ int img_ir_probe_hw(struct img_ir_priv *priv) rdev->map_name = RC_MAP_EMPTY; rc_set_allowed_protocols(rdev, img_ir_allowed_protos(priv)); rdev->input_name = "IMG Infrared Decoder"; - rdev->s_filter = img_ir_set_filter; + rdev->s_filter = img_ir_set_normal_filter; + rdev->s_wakeup_filter = img_ir_set_wakeup_filter; /* Register hardware decoder */ error = rc_register_device(rdev); diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 99697aae92ff..ecbc20c4252e 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -923,6 +923,7 @@ static ssize_t store_protocols(struct device *device, int rc, i, count = 0; ssize_t ret; int (*change_protocol)(struct rc_dev *dev, u64 *rc_type); + int (*set_filter)(struct rc_dev *dev, struct rc_scancode_filter *filter); struct rc_scancode_filter local_filter, *filter; /* Device is being removed */ @@ -1007,24 +1008,27 @@ static ssize_t store_protocols(struct device *device, * Fall back to clearing the filter. */ filter = &dev->scancode_filters[fattr->type]; + set_filter = (fattr->type == RC_FILTER_NORMAL) + ? dev->s_filter : dev->s_wakeup_filter; + if (old_type != type && filter->mask) { local_filter = *filter; if (!type) { /* no protocol => clear filter */ ret = -1; - } else if (!dev->s_filter) { + } else if (!set_filter) { /* generic filtering => accept any filter */ ret = 0; } else { /* hardware filtering => try setting, otherwise clear */ - ret = dev->s_filter(dev, fattr->type, &local_filter); + ret = set_filter(dev, &local_filter); } if (ret < 0) { /* clear the filter */ local_filter.data = 0; local_filter.mask = 0; - if (dev->s_filter) - dev->s_filter(dev, fattr->type, &local_filter); + if (set_filter) + set_filter(dev, &local_filter); } /* commit the new filter */ @@ -1106,6 +1110,7 @@ static ssize_t store_filter(struct device *device, struct rc_scancode_filter local_filter, *filter; int ret; unsigned long val; + int (*set_filter)(struct rc_dev *dev, struct rc_scancode_filter *filter); /* Device is being removed */ if (!dev) @@ -1115,8 +1120,11 @@ static ssize_t store_filter(struct device *device, if (ret < 0) return ret; + set_filter = (fattr->type == RC_FILTER_NORMAL) ? dev->s_filter : + dev->s_wakeup_filter; + /* Scancode filter not supported (but still accept 0) */ - if (!dev->s_filter && fattr->type != RC_FILTER_NORMAL) + if (!set_filter && fattr->type == RC_FILTER_WAKEUP) return val ? -EINVAL : count; mutex_lock(&dev->lock); @@ -1128,13 +1136,15 @@ static ssize_t store_filter(struct device *device, local_filter.mask = val; else local_filter.data = val; + if (!dev->enabled_protocols[fattr->type] && local_filter.mask) { /* refuse to set a filter unless a protocol is enabled */ ret = -EINVAL; goto unlock; } - if (dev->s_filter) { - ret = dev->s_filter(dev, fattr->type, &local_filter); + + if (set_filter) { + ret = set_filter(dev, &local_filter); if (ret < 0) goto unlock; } diff --git a/include/media/rc-core.h b/include/media/rc-core.h index 0b9f890ce431..6dbc7c11224f 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -112,7 +112,8 @@ enum rc_filter_type { * device doesn't interrupt host until it sees IR pulses * @s_learning_mode: enable wide band receiver used for learning * @s_carrier_report: enable carrier reports - * @s_filter: set the scancode filter of a given type + * @s_filter: set the scancode filter + * @s_wakeup_filter: set the wakeup scancode filter */ struct rc_dev { struct device dev; @@ -159,8 +160,9 @@ struct rc_dev { int (*s_learning_mode)(struct rc_dev *dev, int enable); int (*s_carrier_report) (struct rc_dev *dev, int enable); int (*s_filter)(struct rc_dev *dev, - enum rc_filter_type type, struct rc_scancode_filter *filter); + int (*s_wakeup_filter)(struct rc_dev *dev, + struct rc_scancode_filter *filter); }; #define to_rc_dev(d) container_of(d, struct rc_dev, dev) -- cgit v1.2.3 From 99b0f3c96cebf3af9a645d9b00db14cb04fcdfa2 Mon Sep 17 00:00:00 2001 From: David Härdeman Date: Fri, 4 Apr 2014 19:06:06 -0300 Subject: [media] rc-core: remove generic scancode filter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The generic scancode filtering has questionable value and makes it impossible to determine from userspace if there is an actual scancode hw filter present or not. So revert the generic parts. Based on a patch from James Hogan , but this version also makes sure that only the valid sysfs files are created in the first place. Signed-off-by: David Härdeman Acked-by: James Hogan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/rc-main.c | 88 ++++++++++++++++++++++++++++------------------ include/media/rc-core.h | 2 ++ 2 files changed, 55 insertions(+), 35 deletions(-) (limited to 'include') diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index ecbc20c4252e..970b93d6f399 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -633,19 +633,13 @@ EXPORT_SYMBOL_GPL(rc_repeat); static void ir_do_keydown(struct rc_dev *dev, int scancode, u32 keycode, u8 toggle) { - struct rc_scancode_filter *filter; - bool new_event = !dev->keypressed || - dev->last_scancode != scancode || - dev->last_toggle != toggle; + bool new_event = (!dev->keypressed || + dev->last_scancode != scancode || + dev->last_toggle != toggle); if (new_event && dev->keypressed) ir_do_keyup(dev, false); - /* Generic scancode filtering */ - filter = &dev->scancode_filters[RC_FILTER_NORMAL]; - if (filter->mask && ((scancode ^ filter->data) & filter->mask)) - return; - input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode); if (new_event && keycode != KEY_RESERVED) { @@ -1011,14 +1005,11 @@ static ssize_t store_protocols(struct device *device, set_filter = (fattr->type == RC_FILTER_NORMAL) ? dev->s_filter : dev->s_wakeup_filter; - if (old_type != type && filter->mask) { + if (set_filter && old_type != type && filter->mask) { local_filter = *filter; if (!type) { /* no protocol => clear filter */ ret = -1; - } else if (!set_filter) { - /* generic filtering => accept any filter */ - ret = 0; } else { /* hardware filtering => try setting, otherwise clear */ ret = set_filter(dev, &local_filter); @@ -1027,8 +1018,7 @@ static ssize_t store_protocols(struct device *device, /* clear the filter */ local_filter.data = 0; local_filter.mask = 0; - if (set_filter) - set_filter(dev, &local_filter); + set_filter(dev, &local_filter); } /* commit the new filter */ @@ -1072,7 +1062,10 @@ static ssize_t show_filter(struct device *device, return -EINVAL; mutex_lock(&dev->lock); - if (fattr->mask) + if ((fattr->type == RC_FILTER_NORMAL && !dev->s_filter) || + (fattr->type == RC_FILTER_WAKEUP && !dev->s_wakeup_filter)) + val = 0; + else if (fattr->mask) val = dev->scancode_filters[fattr->type].mask; else val = dev->scancode_filters[fattr->type].data; @@ -1120,12 +1113,11 @@ static ssize_t store_filter(struct device *device, if (ret < 0) return ret; + /* Can the scancode filter be set? */ set_filter = (fattr->type == RC_FILTER_NORMAL) ? dev->s_filter : dev->s_wakeup_filter; - - /* Scancode filter not supported (but still accept 0) */ - if (!set_filter && fattr->type == RC_FILTER_WAKEUP) - return val ? -EINVAL : count; + if (!set_filter) + return -EINVAL; mutex_lock(&dev->lock); @@ -1143,11 +1135,9 @@ static ssize_t store_filter(struct device *device, goto unlock; } - if (set_filter) { - ret = set_filter(dev, &local_filter); - if (ret < 0) - goto unlock; - } + ret = set_filter(dev, &local_filter); + if (ret < 0) + goto unlock; /* Success, commit the new filter */ *filter = local_filter; @@ -1199,27 +1189,45 @@ static RC_FILTER_ATTR(wakeup_filter, S_IRUGO|S_IWUSR, static RC_FILTER_ATTR(wakeup_filter_mask, S_IRUGO|S_IWUSR, show_filter, store_filter, RC_FILTER_WAKEUP, true); -static struct attribute *rc_dev_attrs[] = { +static struct attribute *rc_dev_protocol_attrs[] = { &dev_attr_protocols.attr.attr, + NULL, +}; + +static struct attribute_group rc_dev_protocol_attr_grp = { + .attrs = rc_dev_protocol_attrs, +}; + +static struct attribute *rc_dev_wakeup_protocol_attrs[] = { &dev_attr_wakeup_protocols.attr.attr, + NULL, +}; + +static struct attribute_group rc_dev_wakeup_protocol_attr_grp = { + .attrs = rc_dev_wakeup_protocol_attrs, +}; + +static struct attribute *rc_dev_filter_attrs[] = { &dev_attr_filter.attr.attr, &dev_attr_filter_mask.attr.attr, - &dev_attr_wakeup_filter.attr.attr, - &dev_attr_wakeup_filter_mask.attr.attr, NULL, }; -static struct attribute_group rc_dev_attr_grp = { - .attrs = rc_dev_attrs, +static struct attribute_group rc_dev_filter_attr_grp = { + .attrs = rc_dev_filter_attrs, }; -static const struct attribute_group *rc_dev_attr_groups[] = { - &rc_dev_attr_grp, - NULL +static struct attribute *rc_dev_wakeup_filter_attrs[] = { + &dev_attr_wakeup_filter.attr.attr, + &dev_attr_wakeup_filter_mask.attr.attr, + NULL, +}; + +static struct attribute_group rc_dev_wakeup_filter_attr_grp = { + .attrs = rc_dev_wakeup_filter_attrs, }; static struct device_type rc_dev_type = { - .groups = rc_dev_attr_groups, .release = rc_dev_release, .uevent = rc_dev_uevent, }; @@ -1276,7 +1284,7 @@ int rc_register_device(struct rc_dev *dev) static bool raw_init = false; /* raw decoders loaded? */ struct rc_map *rc_map; const char *path; - int rc, devno; + int rc, devno, attr = 0; if (!dev || !dev->map_name) return -EINVAL; @@ -1304,6 +1312,16 @@ int rc_register_device(struct rc_dev *dev) return -ENOMEM; } while (test_and_set_bit(devno, ir_core_dev_number)); + dev->dev.groups = dev->sysfs_groups; + dev->sysfs_groups[attr++] = &rc_dev_protocol_attr_grp; + if (dev->s_filter) + dev->sysfs_groups[attr++] = &rc_dev_filter_attr_grp; + if (dev->s_wakeup_filter) + dev->sysfs_groups[attr++] = &rc_dev_wakeup_filter_attr_grp; + if (dev->change_wakeup_protocol) + dev->sysfs_groups[attr++] = &rc_dev_wakeup_protocol_attr_grp; + dev->sysfs_groups[attr++] = NULL; + /* * Take the lock here, as the device sysfs node will appear * when device_add() is called, which may trigger an ir-keytable udev diff --git a/include/media/rc-core.h b/include/media/rc-core.h index 6dbc7c11224f..fde142e5f25a 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -60,6 +60,7 @@ enum rc_filter_type { /** * struct rc_dev - represents a remote control device * @dev: driver model's view of this device + * @sysfs_groups: sysfs attribute groups * @input_name: name of the input child device * @input_phys: physical path to the input child device * @input_id: id of the input child device (struct input_id) @@ -117,6 +118,7 @@ enum rc_filter_type { */ struct rc_dev { struct device dev; + const struct attribute_group *sysfs_groups[5]; const char *input_name; const char *input_phys; struct input_id input_id; -- cgit v1.2.3