mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-04 02:46:43 +07:00
[media] media-device: add support for MEDIA_IOC_G_TOPOLOGY ioctl
Add support for the new MEDIA_IOC_G_TOPOLOGY ioctl, according with the RFC for the MC next generation. Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
This commit is contained in:
parent
2521fdac28
commit
8309f47c32
@ -232,6 +232,156 @@ static long media_device_setup_link(struct media_device *mdev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long __media_device_get_topology(struct media_device *mdev,
|
||||
struct media_v2_topology *topo)
|
||||
{
|
||||
struct media_entity *entity;
|
||||
struct media_interface *intf;
|
||||
struct media_pad *pad;
|
||||
struct media_link *link;
|
||||
struct media_v2_entity uentity;
|
||||
struct media_v2_interface uintf;
|
||||
struct media_v2_pad upad;
|
||||
struct media_v2_link ulink;
|
||||
int ret = 0, i;
|
||||
|
||||
topo->topology_version = mdev->topology_version;
|
||||
|
||||
/* Get entities and number of entities */
|
||||
i = 0;
|
||||
media_device_for_each_entity(entity, mdev) {
|
||||
i++;
|
||||
|
||||
if (ret || !topo->entities)
|
||||
continue;
|
||||
|
||||
if (i > topo->num_entities) {
|
||||
ret = -ENOSPC;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Copy fields to userspace struct if not error */
|
||||
memset(&uentity, 0, sizeof(uentity));
|
||||
uentity.id = entity->graph_obj.id;
|
||||
strncpy(uentity.name, entity->name,
|
||||
sizeof(uentity.name));
|
||||
|
||||
if (copy_to_user(&topo->entities[i - 1], &uentity, sizeof(uentity)))
|
||||
ret = -EFAULT;
|
||||
}
|
||||
topo->num_entities = i;
|
||||
|
||||
/* Get interfaces and number of interfaces */
|
||||
i = 0;
|
||||
media_device_for_each_intf(intf, mdev) {
|
||||
i++;
|
||||
|
||||
if (ret || !topo->interfaces)
|
||||
continue;
|
||||
|
||||
if (i > topo->num_interfaces) {
|
||||
ret = -ENOSPC;
|
||||
continue;
|
||||
}
|
||||
|
||||
memset(&uintf, 0, sizeof(uintf));
|
||||
|
||||
/* Copy intf fields to userspace struct */
|
||||
uintf.id = intf->graph_obj.id;
|
||||
uintf.intf_type = intf->type;
|
||||
uintf.flags = intf->flags;
|
||||
|
||||
if (media_type(&intf->graph_obj) == MEDIA_GRAPH_INTF_DEVNODE) {
|
||||
struct media_intf_devnode *devnode;
|
||||
|
||||
devnode = intf_to_devnode(intf);
|
||||
|
||||
uintf.devnode.major = devnode->major;
|
||||
uintf.devnode.minor = devnode->minor;
|
||||
}
|
||||
|
||||
if (copy_to_user(&topo->interfaces[i - 1], &uintf, sizeof(uintf)))
|
||||
ret = -EFAULT;
|
||||
}
|
||||
topo->num_interfaces = i;
|
||||
|
||||
/* Get pads and number of pads */
|
||||
i = 0;
|
||||
media_device_for_each_pad(pad, mdev) {
|
||||
i++;
|
||||
|
||||
if (ret || !topo->pads)
|
||||
continue;
|
||||
|
||||
if (i > topo->num_pads) {
|
||||
ret = -ENOSPC;
|
||||
continue;
|
||||
}
|
||||
|
||||
memset(&upad, 0, sizeof(upad));
|
||||
|
||||
/* Copy pad fields to userspace struct */
|
||||
upad.id = pad->graph_obj.id;
|
||||
upad.entity_id = pad->entity->graph_obj.id;
|
||||
upad.flags = pad->flags;
|
||||
|
||||
if (copy_to_user(&topo->pads[i - 1], &upad, sizeof(upad)))
|
||||
ret = -EFAULT;
|
||||
}
|
||||
topo->num_pads = i;
|
||||
|
||||
/* Get links and number of links */
|
||||
i = 0;
|
||||
media_device_for_each_link(link, mdev) {
|
||||
i++;
|
||||
|
||||
if (ret || !topo->links)
|
||||
continue;
|
||||
|
||||
if (i > topo->num_links) {
|
||||
ret = -ENOSPC;
|
||||
continue;
|
||||
}
|
||||
|
||||
memset(&ulink, 0, sizeof(ulink));
|
||||
|
||||
/* Copy link fields to userspace struct */
|
||||
ulink.id = link->graph_obj.id;
|
||||
ulink.source_id = link->gobj0->id;
|
||||
ulink.sink_id = link->gobj1->id;
|
||||
ulink.flags = link->flags;
|
||||
|
||||
if (media_type(link->gobj0) != MEDIA_GRAPH_PAD)
|
||||
ulink.flags |= MEDIA_LNK_FL_INTERFACE_LINK;
|
||||
|
||||
if (copy_to_user(&topo->links[i - 1], &ulink, sizeof(ulink)))
|
||||
ret = -EFAULT;
|
||||
}
|
||||
topo->num_links = i;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long media_device_get_topology(struct media_device *mdev,
|
||||
struct media_v2_topology __user *utopo)
|
||||
{
|
||||
struct media_v2_topology ktopo;
|
||||
int ret;
|
||||
|
||||
ret = copy_from_user(&ktopo, utopo, sizeof(ktopo));
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = __media_device_get_topology(mdev, &ktopo);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = copy_to_user(utopo, &ktopo, sizeof(*utopo));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long media_device_ioctl(struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
@ -264,6 +414,13 @@ static long media_device_ioctl(struct file *filp, unsigned int cmd,
|
||||
mutex_unlock(&dev->graph_mutex);
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
default:
|
||||
ret = -ENOIOCTLCMD;
|
||||
}
|
||||
@ -312,6 +469,7 @@ static long media_device_compat_ioctl(struct file *filp, unsigned int cmd,
|
||||
case MEDIA_IOC_DEVICE_INFO:
|
||||
case MEDIA_IOC_ENUM_ENTITIES:
|
||||
case MEDIA_IOC_SETUP_LINK:
|
||||
case MEDIA_IOC_G_TOPOLOGY:
|
||||
return media_device_ioctl(filp, cmd, arg);
|
||||
|
||||
case MEDIA_IOC_ENUM_LINKS32:
|
||||
|
Loading…
Reference in New Issue
Block a user