#include <linux/compat.h>
#include <linux/export.h>
+#include <linux/idr.h>
#include <linux/ioctl.h>
#include <linux/media.h>
#include <linux/slab.h>
return ret;
}
+#if 0 /* Let's postpone it to Kernel 4.6 */
static long __media_device_get_topology(struct media_device *mdev,
struct media_v2_topology *topo)
{
struct media_v2_topology ktopo;
int ret;
- ret = copy_from_user(&ktopo, utopo, sizeof(ktopo));
-
- if (ret < 0)
- return ret;
+ if (copy_from_user(&ktopo, utopo, sizeof(ktopo)))
+ return -EFAULT;
ret = __media_device_get_topology(mdev, &ktopo);
if (ret < 0)
return ret;
- ret = copy_to_user(utopo, &ktopo, sizeof(*utopo));
+ if (copy_to_user(utopo, &ktopo, sizeof(*utopo)))
+ return -EFAULT;
- return ret;
+ return 0;
}
+#endif
static long media_device_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
mutex_unlock(&dev->graph_mutex);
break;
+#if 0 /* Let's postpone it to Kernel 4.6 */
case MEDIA_IOC_G_TOPOLOGY:
mutex_lock(&dev->graph_mutex);
ret = media_device_get_topology(dev,
(struct media_v2_topology __user *)arg);
mutex_unlock(&dev->graph_mutex);
break;
-
+#endif
default:
ret = -ENOIOCTLCMD;
}
case MEDIA_IOC_DEVICE_INFO:
case MEDIA_IOC_ENUM_ENTITIES:
case MEDIA_IOC_SETUP_LINK:
+#if 0 /* Let's postpone it to Kernel 4.6 */
case MEDIA_IOC_G_TOPOLOGY:
+#endif
return media_device_ioctl(filp, cmd, arg);
case MEDIA_IOC_ENUM_LINKS32:
struct media_entity *entity)
{
unsigned int i;
+ int ret;
if (entity->function == MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN ||
entity->function == MEDIA_ENT_F_UNKNOWN)
entity->num_links = 0;
entity->num_backlinks = 0;
+ if (!ida_pre_get(&mdev->entity_internal_idx, GFP_KERNEL))
+ return -ENOMEM;
+
spin_lock(&mdev->lock);
+
+ ret = ida_get_new_above(&mdev->entity_internal_idx, 1,
+ &entity->internal_idx);
+ if (ret < 0) {
+ spin_unlock(&mdev->lock);
+ return ret;
+ }
+
+ mdev->entity_internal_idx_max =
+ max(mdev->entity_internal_idx_max, entity->internal_idx);
+
/* Initialize media_gobj embedded at the entity */
media_gobj_create(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj);
}
EXPORT_SYMBOL_GPL(media_device_register_entity);
-/**
- * media_device_unregister_entity - Unregister an entity
- * @entity: The entity
- *
- * If the entity has never been registered this function will return
- * immediately.
- */
static void __media_device_unregister_entity(struct media_entity *entity)
{
struct media_device *mdev = entity->graph_obj.mdev;
struct media_interface *intf;
unsigned int i;
+ ida_simple_remove(&mdev->entity_internal_idx, entity->internal_idx);
+
/* Remove all interface links pointing to this entity */
list_for_each_entry(intf, &mdev->interfaces, graph_obj.list) {
list_for_each_entry_safe(link, tmp, &intf->links, list) {
}
EXPORT_SYMBOL_GPL(media_device_unregister_entity);
-
/**
* media_device_init() - initialize a media device
* @mdev: The media device
INIT_LIST_HEAD(&mdev->links);
spin_lock_init(&mdev->lock);
mutex_init(&mdev->graph_mutex);
+ ida_init(&mdev->entity_internal_idx);
dev_dbg(mdev->dev, "Media device initialized\n");
}
EXPORT_SYMBOL_GPL(media_device_init);
-/**
- * media_device_cleanup() - Cleanup a media device
- * @mdev: The media device
- *
- */
void media_device_cleanup(struct media_device *mdev)
{
+ ida_destroy(&mdev->entity_internal_idx);
+ mdev->entity_internal_idx_max = 0;
mutex_destroy(&mdev->graph_mutex);
}
EXPORT_SYMBOL_GPL(media_device_cleanup);
-/**
- * __media_device_register() - register a media device
- * @mdev: The media device
- * @owner: The module owner
- *
- * returns zero on success or a negative error code.
- */
int __must_check __media_device_register(struct media_device *mdev,
struct module *owner)
{
mdev->devnode.fops = &media_device_fops;
mdev->devnode.parent = mdev->dev;
mdev->devnode.release = media_device_release;
+
+ /* Set version 0 to indicate user-space that the graph is static */
+ mdev->topology_version = 0;
+
ret = media_devnode_register(&mdev->devnode, owner);
if (ret < 0)
return ret;
}
EXPORT_SYMBOL_GPL(__media_device_register);
-/**
- * media_device_unregister - unregister a media device
- * @mdev: The media device
- *
- * It is safe to call this function on an unregistered
- * (but initialised) media device.
- */
void media_device_unregister(struct media_device *mdev)
{
struct media_entity *entity;