Merge commit '840f5b0572ea' into v4l_for_linus
* commit '840f5b0572ea': (381 commits) media: au0828 disable tuner to demod link in au0828_media_device_register() [media] touptek: cast char types on %x printk [media] touptek: don't DMA at the stack [media] mceusb: use %*ph for small buffer dumps [media] v4l: exynos4-is: Drop unneeded check when setting up fimc-lite links [media] v4l: vsp1: Check if an entity is a subdev with the right function [media] hide unused functions for !MEDIA_CONTROLLER [media] em28xx: fix Terratec Grabby AC97 codec detection [media] media: add prefixes to interface types [media] media: rc: nuvoton: switch attribute wakeup_data to text [media] v4l2-ioctl: fix YUV422P pixel format description [media] media: fix null pointer dereference in v4l_vb2q_enable_media_source() [media] v4l2-mc.h: fix yet more compiler errors [media] staging/media: add missing TODO files [media] media.h: always start with 1 for the audio entities [media] sound/usb: Use meaninful names for goto labels [media] v4l2-mc.h: fix compiler warnings [media] media: au0828 audio mixer isn't connected to decoder [media] sound/usb: Use Media Controller API to share media resources [media] dw2102: add support for TeVii S662 ...
This commit is contained in:
@@ -30,6 +30,8 @@
|
||||
#include <linux/media.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/usb.h>
|
||||
|
||||
#include <media/media-device.h>
|
||||
#include <media/media-devnode.h>
|
||||
@@ -41,6 +43,11 @@
|
||||
* Userspace API
|
||||
*/
|
||||
|
||||
static inline void __user *media_get_uptr(__u64 arg)
|
||||
{
|
||||
return (void __user *)(uintptr_t)arg;
|
||||
}
|
||||
|
||||
static int media_device_open(struct file *filp)
|
||||
{
|
||||
return 0;
|
||||
@@ -58,7 +65,11 @@ static int media_device_get_info(struct media_device *dev,
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
strlcpy(info.driver, dev->dev->driver->name, sizeof(info.driver));
|
||||
if (dev->driver_name[0])
|
||||
strlcpy(info.driver, dev->driver_name, sizeof(info.driver));
|
||||
else
|
||||
strlcpy(info.driver, dev->dev->driver->name, sizeof(info.driver));
|
||||
|
||||
strlcpy(info.model, dev->model, sizeof(info.model));
|
||||
strlcpy(info.serial, dev->serial, sizeof(info.serial));
|
||||
strlcpy(info.bus_info, dev->bus_info, sizeof(info.bus_info));
|
||||
@@ -257,7 +268,6 @@ static long media_device_setup_link(struct media_device *mdev,
|
||||
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)
|
||||
{
|
||||
@@ -265,10 +275,10 @@ static long __media_device_get_topology(struct media_device *mdev,
|
||||
struct media_interface *intf;
|
||||
struct media_pad *pad;
|
||||
struct media_link *link;
|
||||
struct media_v2_entity kentity, *uentity;
|
||||
struct media_v2_interface kintf, *uintf;
|
||||
struct media_v2_pad kpad, *upad;
|
||||
struct media_v2_link klink, *ulink;
|
||||
struct media_v2_entity kentity, __user *uentity;
|
||||
struct media_v2_interface kintf, __user *uintf;
|
||||
struct media_v2_pad kpad, __user *upad;
|
||||
struct media_v2_link klink, __user *ulink;
|
||||
unsigned int i;
|
||||
int ret = 0;
|
||||
|
||||
@@ -413,7 +423,6 @@ static long media_device_get_topology(struct media_device *mdev,
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static long media_device_ioctl(struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
@@ -447,14 +456,13 @@ static long media_device_ioctl(struct file *filp, unsigned int cmd,
|
||||
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;
|
||||
}
|
||||
@@ -503,9 +511,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:
|
||||
#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:
|
||||
@@ -564,6 +570,7 @@ static void media_device_release(struct media_devnode *mdev)
|
||||
int __must_check media_device_register_entity(struct media_device *mdev,
|
||||
struct media_entity *entity)
|
||||
{
|
||||
struct media_entity_notify *notify, *next;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
@@ -603,8 +610,33 @@ int __must_check media_device_register_entity(struct media_device *mdev,
|
||||
media_gobj_create(mdev, MEDIA_GRAPH_PAD,
|
||||
&entity->pads[i].graph_obj);
|
||||
|
||||
/* invoke entity_notify callbacks */
|
||||
list_for_each_entry_safe(notify, next, &mdev->entity_notify, list) {
|
||||
(notify)->notify(entity, notify->notify_data);
|
||||
}
|
||||
|
||||
spin_unlock(&mdev->lock);
|
||||
|
||||
mutex_lock(&mdev->graph_mutex);
|
||||
if (mdev->entity_internal_idx_max
|
||||
>= mdev->pm_count_walk.ent_enum.idx_max) {
|
||||
struct media_entity_graph new = { .top = 0 };
|
||||
|
||||
/*
|
||||
* Initialise the new graph walk before cleaning up
|
||||
* the old one in order not to spoil the graph walk
|
||||
* object of the media device if graph walk init fails.
|
||||
*/
|
||||
ret = media_entity_graph_walk_init(&new, mdev);
|
||||
if (ret) {
|
||||
mutex_unlock(&mdev->graph_mutex);
|
||||
return ret;
|
||||
}
|
||||
media_entity_graph_walk_cleanup(&mdev->pm_count_walk);
|
||||
mdev->pm_count_walk = new;
|
||||
}
|
||||
mutex_unlock(&mdev->graph_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(media_device_register_entity);
|
||||
@@ -636,6 +668,8 @@ static void __media_device_unregister_entity(struct media_entity *entity)
|
||||
/* Remove the entity */
|
||||
media_gobj_destroy(&entity->graph_obj);
|
||||
|
||||
/* invoke entity_notify callbacks to handle entity removal?? */
|
||||
|
||||
entity->graph_obj.mdev = NULL;
|
||||
}
|
||||
|
||||
@@ -668,6 +702,7 @@ void media_device_init(struct media_device *mdev)
|
||||
INIT_LIST_HEAD(&mdev->interfaces);
|
||||
INIT_LIST_HEAD(&mdev->pads);
|
||||
INIT_LIST_HEAD(&mdev->links);
|
||||
INIT_LIST_HEAD(&mdev->entity_notify);
|
||||
spin_lock_init(&mdev->lock);
|
||||
mutex_init(&mdev->graph_mutex);
|
||||
ida_init(&mdev->entity_internal_idx);
|
||||
@@ -680,6 +715,7 @@ void media_device_cleanup(struct media_device *mdev)
|
||||
{
|
||||
ida_destroy(&mdev->entity_internal_idx);
|
||||
mdev->entity_internal_idx_max = 0;
|
||||
media_entity_graph_walk_cleanup(&mdev->pm_count_walk);
|
||||
mutex_destroy(&mdev->graph_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(media_device_cleanup);
|
||||
@@ -713,11 +749,40 @@ int __must_check __media_device_register(struct media_device *mdev,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__media_device_register);
|
||||
|
||||
int __must_check media_device_register_entity_notify(struct media_device *mdev,
|
||||
struct media_entity_notify *nptr)
|
||||
{
|
||||
spin_lock(&mdev->lock);
|
||||
list_add_tail(&nptr->list, &mdev->entity_notify);
|
||||
spin_unlock(&mdev->lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(media_device_register_entity_notify);
|
||||
|
||||
/*
|
||||
* Note: Should be called with mdev->lock held.
|
||||
*/
|
||||
static void __media_device_unregister_entity_notify(struct media_device *mdev,
|
||||
struct media_entity_notify *nptr)
|
||||
{
|
||||
list_del(&nptr->list);
|
||||
}
|
||||
|
||||
void media_device_unregister_entity_notify(struct media_device *mdev,
|
||||
struct media_entity_notify *nptr)
|
||||
{
|
||||
spin_lock(&mdev->lock);
|
||||
__media_device_unregister_entity_notify(mdev, nptr);
|
||||
spin_unlock(&mdev->lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(media_device_unregister_entity_notify);
|
||||
|
||||
void media_device_unregister(struct media_device *mdev)
|
||||
{
|
||||
struct media_entity *entity;
|
||||
struct media_entity *next;
|
||||
struct media_interface *intf, *tmp_intf;
|
||||
struct media_entity_notify *notify, *nextp;
|
||||
|
||||
if (mdev == NULL)
|
||||
return;
|
||||
@@ -734,6 +799,10 @@ void media_device_unregister(struct media_device *mdev)
|
||||
list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list)
|
||||
__media_device_unregister_entity(entity);
|
||||
|
||||
/* Remove all entity_notify callbacks from the media device */
|
||||
list_for_each_entry_safe(notify, nextp, &mdev->entity_notify, list)
|
||||
__media_device_unregister_entity_notify(mdev, notify);
|
||||
|
||||
/* Remove all interfaces from the media device */
|
||||
list_for_each_entry_safe(intf, tmp_intf, &mdev->interfaces,
|
||||
graph_obj.list) {
|
||||
@@ -777,4 +846,58 @@ struct media_device *media_device_find_devres(struct device *dev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(media_device_find_devres);
|
||||
|
||||
void media_device_pci_init(struct media_device *mdev,
|
||||
struct pci_dev *pci_dev,
|
||||
const char *name)
|
||||
{
|
||||
#ifdef CONFIG_PCI
|
||||
mdev->dev = &pci_dev->dev;
|
||||
|
||||
if (name)
|
||||
strlcpy(mdev->model, name, sizeof(mdev->model));
|
||||
else
|
||||
strlcpy(mdev->model, pci_name(pci_dev), sizeof(mdev->model));
|
||||
|
||||
sprintf(mdev->bus_info, "PCI:%s", pci_name(pci_dev));
|
||||
|
||||
mdev->hw_revision = (pci_dev->subsystem_vendor << 16)
|
||||
| pci_dev->subsystem_device;
|
||||
|
||||
mdev->driver_version = LINUX_VERSION_CODE;
|
||||
|
||||
media_device_init(mdev);
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(media_device_pci_init);
|
||||
|
||||
void __media_device_usb_init(struct media_device *mdev,
|
||||
struct usb_device *udev,
|
||||
const char *board_name,
|
||||
const char *driver_name)
|
||||
{
|
||||
#ifdef CONFIG_USB
|
||||
mdev->dev = &udev->dev;
|
||||
|
||||
if (driver_name)
|
||||
strlcpy(mdev->driver_name, driver_name,
|
||||
sizeof(mdev->driver_name));
|
||||
|
||||
if (board_name)
|
||||
strlcpy(mdev->model, board_name, sizeof(mdev->model));
|
||||
else if (udev->product)
|
||||
strlcpy(mdev->model, udev->product, sizeof(mdev->model));
|
||||
else
|
||||
strlcpy(mdev->model, "unknown model", sizeof(mdev->model));
|
||||
if (udev->serial)
|
||||
strlcpy(mdev->serial, udev->serial, sizeof(mdev->serial));
|
||||
usb_make_path(udev, mdev->bus_info, sizeof(mdev->bus_info));
|
||||
mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
|
||||
mdev->driver_version = LINUX_VERSION_CODE;
|
||||
|
||||
media_device_init(mdev);
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__media_device_usb_init);
|
||||
|
||||
|
||||
#endif /* CONFIG_MEDIA_CONTROLLER */
|
||||
|
Reference in New Issue
Block a user