linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/19] Update ALSA, and au0828 drivers to use Managed Media Controller API
@ 2015-07-22 22:42 Shuah Khan
  2015-07-22 22:42 ` [PATCH v2 01/19] Revert "[media] media: media controller entity framework enhancements for ALSA" Shuah Khan
                   ` (19 more replies)
  0 siblings, 20 replies; 21+ messages in thread
From: Shuah Khan @ 2015-07-22 22:42 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, tiwai, sakari.ailus,
	perex, crope, arnd, stefanr, ruchandani.tina, chehabrafael,
	dan.carpenter, prabhakar.csengg, chris.j.arges, agoode,
	pierre-louis.bossart, gtmkramer, clemens, daniel, vladcatoi,
	misterpib, damien, pmatilai, takamichiho, normalperson,
	bugzilla.frnkcg, joe, calcprogrammer1, jussi, kyungmin.park,
	s.nawrocki, kgene, hyun.kwon, michal.simek, soren.brinkmann,
	pawel, m.szyprowski, gregkh, skd08, nsekhar, boris.brezillon,
	Julia.Lawall, elfring, p.zabel, ricardo.ribalda
  Cc: Shuah Khan, linux-media, alsa-devel, linux-samsung-soc,
	linux-arm-kernel, devel

This patch series updates ALSA driver, and au0828 core driver to
use Managed Media controller API to share tuner. Please note that
Managed Media Controller API and DVB and V4L2 drivers updates to
use Media Controller API have been added in a prior patch series.

Media Controller API is enhanced with two new interfaces to
register and unregister entity_notify hooks to allow drivers
to take appropriate actions when as new entities get added to
the shared media device.

Tested exclusion between digital, analog, and audio to ensure
when tuner has an active link to DVB FE, analog, and audio will
detect and honor the tuner busy conditions and vice versa.

Changes since v1:
Link to v1: http://www.spinics.net/lists/linux-media/msg91697.html

1. Fixed Open Issue:

ALSA has makes media_entity_pipeline_start() call in irq
path. I am seeing warnings that the graph_mutex is unsafe
irq lock. Media Controller API updates to start/stop pipeline
to be irq safe might be necessary. Maybe there are other MC
interfaces that need to be irq safe, but I haven't seen any
problems with my testing.

graph_mutex is changed to a spinlock. Changed drivers that
directly hold the lock for graph walks.

media_entity_setup_link() might need to be made IRQ safe.
I am running more tests to ensure there is no lock warns
when dvb, video, and audio apps. run at the sametime and
use MC API (that holds graph_lock) to check for tuner
availability. Initial testing looked good so far.

2. Add enable_source handler field to struct media_device

Add a new field to enable handler to find source entity for the
sink entity and check if it is available, and activate the link
using media_entity_setup_link() interface. Bridge driver is
expected to implement and set the handler when media_device is
registered or when bridge driver finds the media_device during
probe. This is to enable the use-case to find tuner entity
connected to the decoder entity and check if it is available,
and activate the using media_entity_setup_link() if it is available.
This hanlder can be invoked from media core (v4l-core, dvb-core)
as well as other drivers such as ALSA that control the media device.

3. Changes to v4l2-core, ALSA to use enable_source handler

4. Changes to au0828 bridge driver to implement enable_source handler

Note: This series includes a revert to a patch that added media
controller entity framework enhancements that implemented entity
ops for entity_notify functionality. Entity ops for entity_notify
doesn't handle and cover entity create ordering variations that
could occur during boot. entity_notify list has been moved to media
device level which makes the entity_notify calls to work correctly.

History:
This patch series has been updated to address comments from
3 previous versions of this series. Links to v3 version
for reference are:

https://www.mail-archive.com/linux-media%40vger.kernel.org/msg89491.html
https://www.mail-archive.com/linux-media@vger.kernel.org/msg89492.html
https://www.mail-archive.com/linux-media%40vger.kernel.org/msg89493.html

Shuah Khan (19):
  Revert "[media] media: media controller entity framework enhancements
    for ALSA"
  media: Media Controller register/unregister entity_notify API
  media: Add ALSA Media Controller devnodes
  media: au8522 change to create MC pad for ALSA Audio Out
  media: Convert graph_mutex to a spinlock and call it graph_lock
  media: platform exynos4-is: Update graph_mutex to graph_lock spinlock
  media: platform omap3isp: Update graph_mutex to graph_lock spinlock
  media: platform s3c-camif: Update graph_mutex to graph_lock spinlock
  media: platform vsp1: Update graph_mutex to graph_lock spinlock
  media: platform xilinx: Update graph_mutex to graph_lock spinlock
  staging media: davinci_vpfe: Update graph_mutex to graph_lock spinlock
  staging media: omap4iss: Update graph_mutex to graph_lock spinlock
  media: Add irq safe Media Controller start/stop pipeline API
  media: Add enable_source handler field to struct media_device
  media: v4l-core add v4l_enable_media_tuner() to check for tuner
    availability
  media: Change v4l-core to check for tuner availability
  media: dvb-frontend change to check for tuner availability from open
  media: au0828 change to use Managed Media Controller API
  sound/usb: Update ALSA driver to use Managed Media Controller API

 drivers/media/dvb-core/dvb_frontend.c              |  43 ++--
 drivers/media/dvb-frontends/au8522.h               |   8 +
 drivers/media/dvb-frontends/au8522_decoder.c       |   1 +
 drivers/media/dvb-frontends/au8522_priv.h          |   8 -
 drivers/media/media-device.c                       |  60 +++++-
 drivers/media/media-entity.c                       |  88 ++++++--
 drivers/media/platform/exynos4-is/fimc-isp-video.c |   8 +-
 drivers/media/platform/exynos4-is/fimc-lite.c      |   8 +-
 drivers/media/platform/exynos4-is/media-dev.c      |  14 +-
 drivers/media/platform/exynos4-is/media-dev.h      |   4 +-
 drivers/media/platform/omap3isp/isp.c              |   4 +-
 drivers/media/platform/omap3isp/ispvideo.c         |   4 +-
 drivers/media/platform/s3c-camif/camif-core.c      |   6 +-
 drivers/media/platform/vsp1/vsp1_video.c           |   4 +-
 drivers/media/platform/xilinx/xilinx-dma.c         |   4 +-
 drivers/media/usb/au0828/au0828-core.c             | 184 ++++++++++++-----
 drivers/media/usb/au0828/au0828-video.c            |  72 ++-----
 drivers/media/usb/au0828/au0828.h                  |   5 +
 drivers/media/v4l2-core/v4l2-dev.c                 |  17 ++
 drivers/media/v4l2-core/v4l2-ioctl.c               |  29 +++
 drivers/media/v4l2-core/videobuf2-core.c           |   5 +
 drivers/staging/media/davinci_vpfe/vpfe_video.c    |  12 +-
 drivers/staging/media/omap4iss/iss.c               |   4 +-
 drivers/staging/media/omap4iss/iss_video.c         |   4 +-
 include/media/media-device.h                       |  41 +++-
 include/media/media-entity.h                       |   7 +-
 include/media/v4l2-dev.h                           |   3 +
 include/uapi/linux/media.h                         |   5 +
 sound/usb/Makefile                                 |  15 +-
 sound/usb/card.c                                   |   5 +
 sound/usb/card.h                                   |   1 +
 sound/usb/media.c                                  | 227 +++++++++++++++++++++
 sound/usb/media.h                                  |  52 +++++
 sound/usb/pcm.c                                    |  15 +-
 sound/usb/quirks-table.h                           |   1 +
 sound/usb/quirks.c                                 |   9 +-
 sound/usb/stream.c                                 |   2 +
 sound/usb/usbaudio.h                               |   1 +
 38 files changed, 765 insertions(+), 215 deletions(-)
 create mode 100644 sound/usb/media.c
 create mode 100644 sound/usb/media.h

-- 
2.1.4


^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH v2 01/19] Revert "[media] media: media controller entity framework enhancements for ALSA"
  2015-07-22 22:42 [PATCH v2 00/19] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
@ 2015-07-22 22:42 ` Shuah Khan
  2015-07-22 22:42 ` [PATCH v2 02/19] media: Media Controller register/unregister entity_notify API Shuah Khan
                   ` (18 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Shuah Khan @ 2015-07-22 22:42 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, tiwai, sakari.ailus,
	perex, crope, arnd, stefanr, ruchandani.tina, chehabrafael,
	dan.carpenter, prabhakar.csengg, chris.j.arges, agoode,
	pierre-louis.bossart, gtmkramer, clemens, daniel, vladcatoi,
	misterpib, damien, pmatilai, takamichiho, normalperson,
	bugzilla.frnkcg, joe, calcprogrammer1, jussi, kyungmin.park,
	s.nawrocki, kgene, hyun.kwon, michal.simek, soren.brinkmann,
	pawel, m.szyprowski, gregkh, skd08, nsekhar, boris.brezillon,
	Julia.Lawall, elfring, p.zabel, ricardo.ribalda
  Cc: Shuah Khan, linux-media, alsa-devel, linux-samsung-soc,
	linux-arm-kernel, devel

This reverts commit ed64cf1e182fb30fe67652386c0880fcf3302f97.
This patch is no longer necessary as the entity register
callback is implemented at media_device level.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/media-device.c | 7 -------
 include/media/media-entity.h | 4 ----
 2 files changed, 11 deletions(-)

diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 76590ba..c55ab50 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -428,8 +428,6 @@ EXPORT_SYMBOL_GPL(media_device_unregister);
 int __must_check media_device_register_entity(struct media_device *mdev,
 					      struct media_entity *entity)
 {
-	struct media_entity *eptr;
-
 	/* Warn if we apparently re-register an entity */
 	WARN_ON(entity->parent != NULL);
 	entity->parent = mdev;
@@ -442,11 +440,6 @@ int __must_check media_device_register_entity(struct media_device *mdev,
 	list_add_tail(&entity->list, &mdev->entities);
 	spin_unlock(&mdev->lock);
 
-	media_device_for_each_entity(eptr, mdev) {
-		if (eptr != entity)
-			media_entity_call(eptr, register_notify);
-	}
-
 	return 0;
 }
 EXPORT_SYMBOL_GPL(media_device_register_entity);
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index 0bc4c2f..0c003d8 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -46,7 +46,6 @@ struct media_pad {
 
 /**
  * struct media_entity_operations - Media entity operations
- * @register_notify	Notify entity of newly registered entity
  * @link_setup:		Notify the entity of link changes. The operation can
  *			return an error, in which case link setup will be
  *			cancelled. Optional.
@@ -55,7 +54,6 @@ struct media_pad {
  *			validates all links by calling this operation. Optional.
  */
 struct media_entity_operations {
-	int (*register_notify)(struct media_entity *entity);
 	int (*link_setup)(struct media_entity *entity,
 			  const struct media_pad *local,
 			  const struct media_pad *remote, u32 flags);
@@ -103,8 +101,6 @@ struct media_entity {
 		/* Sub-device specifications */
 		/* Nothing needed yet */
 	} info;
-
-	void *private;			/* private data for the entity */
 };
 
 static inline u32 media_entity_type(struct media_entity *entity)
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 02/19] media: Media Controller register/unregister entity_notify API
  2015-07-22 22:42 [PATCH v2 00/19] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
  2015-07-22 22:42 ` [PATCH v2 01/19] Revert "[media] media: media controller entity framework enhancements for ALSA" Shuah Khan
@ 2015-07-22 22:42 ` Shuah Khan
  2015-07-22 22:42 ` [PATCH v2 03/19] media: Add ALSA Media Controller devnodes Shuah Khan
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Shuah Khan @ 2015-07-22 22:42 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, tiwai, sakari.ailus,
	perex, crope, arnd, stefanr, ruchandani.tina, chehabrafael,
	dan.carpenter, prabhakar.csengg, chris.j.arges, agoode,
	pierre-louis.bossart, gtmkramer, clemens, daniel, vladcatoi,
	misterpib, damien, pmatilai, takamichiho, normalperson,
	bugzilla.frnkcg, joe, calcprogrammer1, jussi, kyungmin.park,
	s.nawrocki, kgene, hyun.kwon, michal.simek, soren.brinkmann,
	pawel, m.szyprowski, gregkh, skd08, nsekhar, boris.brezillon,
	Julia.Lawall, elfring, p.zabel, ricardo.ribalda
  Cc: Shuah Khan, linux-media, alsa-devel, linux-samsung-soc,
	linux-arm-kernel, devel

Add new interfaces to register and unregister entity_notify
hook to media device to allow drivers to take appropriate
actions when as new entities get added to the shared media
device.When a new entity is registered, all registered
entity_notify hooks are invoked to allow drivers or modules
that registered hook to take appropriate action. For example,
ALSA driver registers an entity_notify hook to parse the list
of registered entities to determine if decoder has been linked
to ALSA entity. au0828 bridge driver registers an entity_notify
hook to create media graph for the device.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/media-device.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
 include/media/media-device.h | 23 ++++++++++++++++++++++
 2 files changed, 68 insertions(+)

diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index c55ab50..22565a8 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -381,6 +381,7 @@ int __must_check __media_device_register(struct media_device *mdev,
 
 	mdev->entity_id = 1;
 	INIT_LIST_HEAD(&mdev->entities);
+	INIT_LIST_HEAD(&mdev->entity_notify);
 	spin_lock_init(&mdev->lock);
 	mutex_init(&mdev->graph_mutex);
 
@@ -411,9 +412,12 @@ void media_device_unregister(struct media_device *mdev)
 {
 	struct media_entity *entity;
 	struct media_entity *next;
+	struct media_entity_notify *notify, *nextp;
 
 	list_for_each_entry_safe(entity, next, &mdev->entities, list)
 		media_device_unregister_entity(entity);
+	list_for_each_entry_safe(notify, nextp, &mdev->entity_notify, list)
+		media_device_unregister_entity_notify(mdev, notify);
 
 	device_remove_file(&mdev->devnode.dev, &dev_attr_model);
 	media_devnode_unregister(&mdev->devnode);
@@ -421,6 +425,39 @@ void media_device_unregister(struct media_device *mdev)
 EXPORT_SYMBOL_GPL(media_device_unregister);
 
 /**
+ * media_device_register_entity_notify - Register a media entity notify
+ * callback with a media device. When a new entity is registered, all
+ * the registered media_entity_notify callbacks are invoked.
+ * @mdev:	The media device
+ * @nptr:	The media_entity_notify
+ */
+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);
+
+/**
+ * media_device_unregister_entity_notify - Unregister a media entity notify
+ * callback with a media device. When a new entity is registered, all
+ * the registered media_entity_notify callbacks are invoked.
+ * @mdev:	The media device
+ * @nptr:	The media_entity_notify
+ */
+void media_device_unregister_entity_notify(struct media_device *mdev,
+					struct media_entity_notify *nptr)
+{
+	spin_lock(&mdev->lock);
+	list_del(&nptr->list);
+	spin_unlock(&mdev->lock);
+}
+EXPORT_SYMBOL_GPL(media_device_unregister_entity_notify);
+
+/**
  * media_device_register_entity - Register an entity with a media device
  * @mdev:	The media device
  * @entity:	The entity
@@ -428,6 +465,8 @@ EXPORT_SYMBOL_GPL(media_device_unregister);
 int __must_check media_device_register_entity(struct media_device *mdev,
 					      struct media_entity *entity)
 {
+	struct media_entity_notify *notify, *next;
+
 	/* Warn if we apparently re-register an entity */
 	WARN_ON(entity->parent != NULL);
 	entity->parent = mdev;
@@ -440,6 +479,11 @@ int __must_check media_device_register_entity(struct media_device *mdev,
 	list_add_tail(&entity->list, &mdev->entities);
 	spin_unlock(&mdev->lock);
 
+	/* invoke entity_notify callbacks */
+	list_for_each_entry_safe(notify, next, &mdev->entity_notify, list) {
+		(notify)->notify(entity, notify->notify_data);
+	}
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(media_device_register_entity);
@@ -462,6 +506,7 @@ void media_device_unregister_entity(struct media_entity *entity)
 	list_del(&entity->list);
 	spin_unlock(&mdev->lock);
 	entity->parent = NULL;
+	/* invoke entity_notify callbacks to handle entity removal?? */
 }
 EXPORT_SYMBOL_GPL(media_device_unregister_entity);
 
diff --git a/include/media/media-device.h b/include/media/media-device.h
index a44f18f..a3854f6 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -32,6 +32,12 @@
 
 struct device;
 
+struct media_entity_notify {
+	struct list_head list;
+	void *notify_data;
+	void (*notify)(struct media_entity *entity, void *notify_data);
+};
+
 /**
  * struct media_device - Media device
  * @dev:	Parent device
@@ -70,6 +76,8 @@ struct media_device {
 
 	u32 entity_id;
 	struct list_head entities;
+	/* notify callback list invoked when a new entity is registered */
+	struct list_head entity_notify;
 
 	/* Protects the entities list */
 	spinlock_t lock;
@@ -94,6 +102,10 @@ int __must_check __media_device_register(struct media_device *mdev,
 #define media_device_register(mdev) __media_device_register(mdev, THIS_MODULE)
 void media_device_unregister(struct media_device *mdev);
 
+int __must_check media_device_register_entity_notify(struct media_device *mdev,
+					struct media_entity_notify *nptr);
+void media_device_unregister_entity_notify(struct media_device *mdev,
+					struct media_entity_notify *nptr);
 int __must_check media_device_register_entity(struct media_device *mdev,
 					      struct media_entity *entity);
 void media_device_unregister_entity(struct media_entity *entity);
@@ -112,6 +124,17 @@ static inline int media_device_register(struct media_device *mdev)
 static inline void media_device_unregister(struct media_device *mdev)
 {
 }
+static inline int media_device_register_entity_notify(
+					struct media_device *mdev,
+					struct media_entity_notify *nptr)
+{
+	return 0;
+}
+static inline void media_device_unregister_entity_notify(
+					struct media_device *mdev,
+					struct media_entity_notify *nptr)
+{
+}
 static inline int media_device_register_entity(struct media_device *mdev,
 						struct media_entity *entity)
 {
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 03/19] media: Add ALSA Media Controller devnodes
  2015-07-22 22:42 [PATCH v2 00/19] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
  2015-07-22 22:42 ` [PATCH v2 01/19] Revert "[media] media: media controller entity framework enhancements for ALSA" Shuah Khan
  2015-07-22 22:42 ` [PATCH v2 02/19] media: Media Controller register/unregister entity_notify API Shuah Khan
@ 2015-07-22 22:42 ` Shuah Khan
  2015-07-22 22:42 ` [PATCH v2 04/19] media: au8522 change to create MC pad for ALSA Audio Out Shuah Khan
                   ` (16 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Shuah Khan @ 2015-07-22 22:42 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, tiwai, sakari.ailus,
	perex, crope, arnd, stefanr, ruchandani.tina, chehabrafael,
	dan.carpenter, prabhakar.csengg, chris.j.arges, agoode,
	pierre-louis.bossart, gtmkramer, clemens, daniel, vladcatoi,
	misterpib, damien, pmatilai, takamichiho, normalperson,
	bugzilla.frnkcg, joe, calcprogrammer1, jussi, kyungmin.park,
	s.nawrocki, kgene, hyun.kwon, michal.simek, soren.brinkmann,
	pawel, m.szyprowski, gregkh, skd08, nsekhar, boris.brezillon,
	Julia.Lawall, elfring, p.zabel, ricardo.ribalda
  Cc: Shuah Khan, linux-media, alsa-devel, linux-samsung-soc,
	linux-arm-kernel, devel

Add ALSA Media Controller capture, playback, and mixer
devnode defines.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 include/uapi/linux/media.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h
index 4e816be..4a30ea3 100644
--- a/include/uapi/linux/media.h
+++ b/include/uapi/linux/media.h
@@ -49,12 +49,17 @@ struct media_device_info {
 #define MEDIA_ENT_T_DEVNODE		(1 << MEDIA_ENT_TYPE_SHIFT)
 #define MEDIA_ENT_T_DEVNODE_V4L		(MEDIA_ENT_T_DEVNODE + 1)
 #define MEDIA_ENT_T_DEVNODE_FB		(MEDIA_ENT_T_DEVNODE + 2)
+/* Legacy ALSA symbol. Keep it to avoid userspace compilation breakages */
 #define MEDIA_ENT_T_DEVNODE_ALSA	(MEDIA_ENT_T_DEVNODE + 3)
 #define MEDIA_ENT_T_DEVNODE_DVB_FE	(MEDIA_ENT_T_DEVNODE + 4)
 #define MEDIA_ENT_T_DEVNODE_DVB_DEMUX	(MEDIA_ENT_T_DEVNODE + 5)
 #define MEDIA_ENT_T_DEVNODE_DVB_DVR	(MEDIA_ENT_T_DEVNODE + 6)
 #define MEDIA_ENT_T_DEVNODE_DVB_CA	(MEDIA_ENT_T_DEVNODE + 7)
 #define MEDIA_ENT_T_DEVNODE_DVB_NET	(MEDIA_ENT_T_DEVNODE + 8)
+/* ALSA devnodes */
+#define MEDIA_ENT_T_DEVNODE_ALSA_CAPTURE	(MEDIA_ENT_T_DEVNODE + 9)
+#define MEDIA_ENT_T_DEVNODE_ALSA_PLAYBACK	(MEDIA_ENT_T_DEVNODE + 10)
+#define MEDIA_ENT_T_DEVNODE_ALSA_MIXER		(MEDIA_ENT_T_DEVNODE + 11)
 
 /* Legacy symbol. Use it to avoid userspace compilation breakages */
 #define MEDIA_ENT_T_DEVNODE_DVB		MEDIA_ENT_T_DEVNODE_DVB_FE
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 04/19] media: au8522 change to create MC pad for ALSA Audio Out
  2015-07-22 22:42 [PATCH v2 00/19] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (2 preceding siblings ...)
  2015-07-22 22:42 ` [PATCH v2 03/19] media: Add ALSA Media Controller devnodes Shuah Khan
@ 2015-07-22 22:42 ` Shuah Khan
  2015-07-22 22:42 ` [PATCH v2 05/19] media: Convert graph_mutex to a spinlock and call it graph_lock Shuah Khan
                   ` (15 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Shuah Khan @ 2015-07-22 22:42 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, tiwai, sakari.ailus,
	perex, crope, arnd, stefanr, ruchandani.tina, chehabrafael,
	dan.carpenter, prabhakar.csengg, chris.j.arges, agoode,
	pierre-louis.bossart, gtmkramer, clemens, daniel, vladcatoi,
	misterpib, damien, pmatilai, takamichiho, normalperson,
	bugzilla.frnkcg, joe, calcprogrammer1, jussi, kyungmin.park,
	s.nawrocki, kgene, hyun.kwon, michal.simek, soren.brinkmann,
	pawel, m.szyprowski, gregkh, skd08, nsekhar, boris.brezillon,
	Julia.Lawall, elfring, p.zabel, ricardo.ribalda
  Cc: Shuah Khan, linux-media, alsa-devel, linux-samsung-soc,
	linux-arm-kernel, devel

Add new pad for ALSA Audio Out to au8522_media_pads. Move the
au8522_media_pads enum to au8522.h from au8522_priv.h. This will
allow au0828-core to use these defines instead of hard-coding the
pad values when it creates media graph linking decode pads to other
entities.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/dvb-frontends/au8522.h         | 8 ++++++++
 drivers/media/dvb-frontends/au8522_decoder.c | 1 +
 drivers/media/dvb-frontends/au8522_priv.h    | 8 --------
 3 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/media/dvb-frontends/au8522.h b/drivers/media/dvb-frontends/au8522.h
index dde6158..d7a997f 100644
--- a/drivers/media/dvb-frontends/au8522.h
+++ b/drivers/media/dvb-frontends/au8522.h
@@ -90,4 +90,12 @@ enum au8522_audio_input {
 	AU8522_AUDIO_SIF,
 };
 
+enum au8522_media_pads {
+	AU8522_PAD_INPUT,
+	AU8522_PAD_VID_OUT,
+	AU8522_PAD_VBI_OUT,
+	AU8522_PAD_AUDIO_OUT,
+
+	AU8522_NUM_PADS
+};
 #endif /* __AU8522_H__ */
diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c
index 24990db..01d8fe7 100644
--- a/drivers/media/dvb-frontends/au8522_decoder.c
+++ b/drivers/media/dvb-frontends/au8522_decoder.c
@@ -775,6 +775,7 @@ static int au8522_probe(struct i2c_client *client,
 	state->pads[AU8522_PAD_INPUT].flags = MEDIA_PAD_FL_SINK;
 	state->pads[AU8522_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
 	state->pads[AU8522_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
+	state->pads[AU8522_PAD_AUDIO_OUT].flags = MEDIA_PAD_FL_SINK;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
 
 	ret = media_entity_init(&sd->entity, ARRAY_SIZE(state->pads),
diff --git a/drivers/media/dvb-frontends/au8522_priv.h b/drivers/media/dvb-frontends/au8522_priv.h
index d6209d9..4c2a6ed 100644
--- a/drivers/media/dvb-frontends/au8522_priv.h
+++ b/drivers/media/dvb-frontends/au8522_priv.h
@@ -39,14 +39,6 @@
 #define AU8522_DIGITAL_MODE 1
 #define AU8522_SUSPEND_MODE 2
 
-enum au8522_media_pads {
-	AU8522_PAD_INPUT,
-	AU8522_PAD_VID_OUT,
-	AU8522_PAD_VBI_OUT,
-
-	AU8522_NUM_PADS
-};
-
 struct au8522_state {
 	struct i2c_client *c;
 	struct i2c_adapter *i2c;
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 05/19] media: Convert graph_mutex to a spinlock and call it graph_lock
  2015-07-22 22:42 [PATCH v2 00/19] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (3 preceding siblings ...)
  2015-07-22 22:42 ` [PATCH v2 04/19] media: au8522 change to create MC pad for ALSA Audio Out Shuah Khan
@ 2015-07-22 22:42 ` Shuah Khan
  2015-07-22 22:42 ` [PATCH v2 06/19] media: platform exynos4-is: Update graph_mutex to graph_lock spinlock Shuah Khan
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Shuah Khan @ 2015-07-22 22:42 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, tiwai, sakari.ailus,
	perex, crope, arnd, stefanr, ruchandani.tina, chehabrafael,
	dan.carpenter, prabhakar.csengg, chris.j.arges, agoode,
	pierre-louis.bossart, gtmkramer, clemens, daniel, vladcatoi,
	misterpib, damien, pmatilai, takamichiho, normalperson,
	bugzilla.frnkcg, joe, calcprogrammer1, jussi, kyungmin.park,
	s.nawrocki, kgene, hyun.kwon, michal.simek, soren.brinkmann,
	pawel, m.szyprowski, gregkh, skd08, nsekhar, boris.brezillon,
	Julia.Lawall, elfring, p.zabel, ricardo.ribalda
  Cc: Shuah Khan, linux-media, alsa-devel, linux-samsung-soc,
	linux-arm-kernel, devel

ALSA driver calls Media Controller start/stop pipeline
interfaces from IRQ handler. Start/stop pipeline lock
graph_mutex which is unsafe from a IRQ handler. Convert
graph_mutex into a spinlock and call it graph_lock. IRQ
safe start/stop pipeline interfaces will be added based
on this change.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/media-device.c | 14 +++++++-------
 drivers/media/media-entity.c | 18 +++++++++---------
 include/media/media-device.h |  4 ++--
 3 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 22565a8..b0fafd7 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -251,17 +251,17 @@ static long media_device_ioctl(struct file *filp, unsigned int cmd,
 		break;
 
 	case MEDIA_IOC_ENUM_LINKS:
-		mutex_lock(&dev->graph_mutex);
+		spin_lock(&dev->graph_lock);
 		ret = media_device_enum_links(dev,
 				(struct media_links_enum __user *)arg);
-		mutex_unlock(&dev->graph_mutex);
+		spin_unlock(&dev->graph_lock);
 		break;
 
 	case MEDIA_IOC_SETUP_LINK:
-		mutex_lock(&dev->graph_mutex);
+		spin_lock(&dev->graph_lock);
 		ret = media_device_setup_link(dev,
 				(struct media_link_desc __user *)arg);
-		mutex_unlock(&dev->graph_mutex);
+		spin_unlock(&dev->graph_lock);
 		break;
 
 	default:
@@ -315,10 +315,10 @@ static long media_device_compat_ioctl(struct file *filp, unsigned int cmd,
 		return media_device_ioctl(filp, cmd, arg);
 
 	case MEDIA_IOC_ENUM_LINKS32:
-		mutex_lock(&dev->graph_mutex);
+		spin_lock(&dev->graph_lock);
 		ret = media_device_enum_links32(dev,
 				(struct media_links_enum32 __user *)arg);
-		mutex_unlock(&dev->graph_mutex);
+		spin_unlock(&dev->graph_lock);
 		break;
 
 	default:
@@ -383,7 +383,7 @@ int __must_check __media_device_register(struct media_device *mdev,
 	INIT_LIST_HEAD(&mdev->entities);
 	INIT_LIST_HEAD(&mdev->entity_notify);
 	spin_lock_init(&mdev->lock);
-	mutex_init(&mdev->graph_mutex);
+	spin_lock_init(&mdev->graph_lock);
 
 	/* Register the device node. */
 	mdev->devnode.fops = &media_device_fops;
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 4d8e01c..31132573 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -230,7 +230,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
 	struct media_entity *entity_err = entity;
 	int ret;
 
-	mutex_lock(&mdev->graph_mutex);
+	spin_lock(&mdev->graph_lock);
 
 	media_entity_graph_walk_start(&graph, entity);
 
@@ -303,7 +303,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
 		}
 	}
 
-	mutex_unlock(&mdev->graph_mutex);
+	spin_unlock(&mdev->graph_lock);
 
 	return 0;
 
@@ -327,7 +327,7 @@ error:
 			break;
 	}
 
-	mutex_unlock(&mdev->graph_mutex);
+	spin_unlock(&mdev->graph_lock);
 
 	return ret;
 }
@@ -350,7 +350,7 @@ void media_entity_pipeline_stop(struct media_entity *entity)
 	struct media_device *mdev = entity->parent;
 	struct media_entity_graph graph;
 
-	mutex_lock(&mdev->graph_mutex);
+	spin_lock(&mdev->graph_lock);
 
 	media_entity_graph_walk_start(&graph, entity);
 
@@ -360,7 +360,7 @@ void media_entity_pipeline_stop(struct media_entity *entity)
 			entity->pipe = NULL;
 	}
 
-	mutex_unlock(&mdev->graph_mutex);
+	spin_unlock(&mdev->graph_lock);
 }
 EXPORT_SYMBOL_GPL(media_entity_pipeline_stop);
 
@@ -519,9 +519,9 @@ void media_entity_remove_links(struct media_entity *entity)
 	if (entity->parent == NULL)
 		return;
 
-	mutex_lock(&entity->parent->graph_mutex);
+	spin_lock(&entity->parent->graph_lock);
 	__media_entity_remove_links(entity);
-	mutex_unlock(&entity->parent->graph_mutex);
+	spin_unlock(&entity->parent->graph_lock);
 }
 EXPORT_SYMBOL_GPL(media_entity_remove_links);
 
@@ -611,9 +611,9 @@ int media_entity_setup_link(struct media_link *link, u32 flags)
 {
 	int ret;
 
-	mutex_lock(&link->source->entity->parent->graph_mutex);
+	spin_lock(&link->source->entity->parent->graph_lock);
 	ret = __media_entity_setup_link(link, flags);
-	mutex_unlock(&link->source->entity->parent->graph_mutex);
+	spin_unlock(&link->source->entity->parent->graph_lock);
 
 	return ret;
 }
diff --git a/include/media/media-device.h b/include/media/media-device.h
index a3854f6..e73642c 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -50,7 +50,7 @@ struct media_entity_notify {
  * @entity_id:	ID of the next entity to be registered
  * @entities:	List of registered entities
  * @lock:	Entities list lock
- * @graph_mutex: Entities graph operation lock
+ * @graph_lock: Entities graph operation lock
  * @link_notify: Link state change notification callback
  *
  * This structure represents an abstract high-level media device. It allows easy
@@ -82,7 +82,7 @@ struct media_device {
 	/* Protects the entities list */
 	spinlock_t lock;
 	/* Serializes graph operations. */
-	struct mutex graph_mutex;
+	spinlock_t graph_lock;
 
 	int (*link_notify)(struct media_link *link, u32 flags,
 			   unsigned int notification);
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 06/19] media: platform exynos4-is: Update graph_mutex to graph_lock spinlock
  2015-07-22 22:42 [PATCH v2 00/19] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (4 preceding siblings ...)
  2015-07-22 22:42 ` [PATCH v2 05/19] media: Convert graph_mutex to a spinlock and call it graph_lock Shuah Khan
@ 2015-07-22 22:42 ` Shuah Khan
  2015-07-22 22:42 ` [PATCH v2 07/19] media: platform omap3isp: " Shuah Khan
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Shuah Khan @ 2015-07-22 22:42 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, tiwai, sakari.ailus,
	perex, crope, arnd, stefanr, ruchandani.tina, chehabrafael,
	dan.carpenter, prabhakar.csengg, chris.j.arges, agoode,
	pierre-louis.bossart, gtmkramer, clemens, daniel, vladcatoi,
	misterpib, damien, pmatilai, takamichiho, normalperson,
	bugzilla.frnkcg, joe, calcprogrammer1, jussi, kyungmin.park,
	s.nawrocki, kgene, hyun.kwon, michal.simek, soren.brinkmann,
	pawel, m.szyprowski, gregkh, skd08, nsekhar, boris.brezillon,
	Julia.Lawall, elfring, p.zabel, ricardo.ribalda
  Cc: Shuah Khan, linux-media, alsa-devel, linux-samsung-soc,
	linux-arm-kernel, devel

Update graph_mutex to graph_lock spinlock to be in sync with
the Media Conttroller change for the same.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/platform/exynos4-is/fimc-isp-video.c |  8 ++++----
 drivers/media/platform/exynos4-is/fimc-lite.c      |  8 ++++----
 drivers/media/platform/exynos4-is/media-dev.c      | 14 +++++++-------
 drivers/media/platform/exynos4-is/media-dev.h      |  4 ++--
 4 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c
index 76b6b4d..5ff0a54 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp-video.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c
@@ -288,7 +288,7 @@ static int isp_video_open(struct file *file)
 		goto rel_fh;
 
 	if (v4l2_fh_is_singular_file(file)) {
-		mutex_lock(&me->parent->graph_mutex);
+		spin_lock(&me->parent->graph_lock);
 
 		ret = fimc_pipeline_call(ve, open, me, true);
 
@@ -296,7 +296,7 @@ static int isp_video_open(struct file *file)
 		if (ret == 0)
 			me->use_count++;
 
-		mutex_unlock(&me->parent->graph_mutex);
+		spin_unlock(&me->parent->graph_lock);
 	}
 	if (!ret)
 		goto unlock;
@@ -326,9 +326,9 @@ static int isp_video_release(struct file *file)
 	if (v4l2_fh_is_singular_file(file)) {
 		fimc_pipeline_call(&ivc->ve, close);
 
-		mutex_lock(&mdev->graph_mutex);
+		spin_lock(&mdev->graph_lock);
 		entity->use_count--;
-		mutex_unlock(&mdev->graph_mutex);
+		spin_unlock(&mdev->graph_lock);
 	}
 
 	pm_runtime_put(&isp->pdev->dev);
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index ca6261a..cb1ea29 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -500,7 +500,7 @@ static int fimc_lite_open(struct file *file)
 	    atomic_read(&fimc->out_path) != FIMC_IO_DMA)
 		goto unlock;
 
-	mutex_lock(&me->parent->graph_mutex);
+	spin_lock(&me->parent->graph_lock);
 
 	ret = fimc_pipeline_call(&fimc->ve, open, me, true);
 
@@ -508,7 +508,7 @@ static int fimc_lite_open(struct file *file)
 	if (ret == 0)
 		me->use_count++;
 
-	mutex_unlock(&me->parent->graph_mutex);
+	spin_unlock(&me->parent->graph_lock);
 
 	if (!ret) {
 		fimc_lite_clear_event_counters(fimc);
@@ -541,9 +541,9 @@ static int fimc_lite_release(struct file *file)
 		fimc_pipeline_call(&fimc->ve, close);
 		clear_bit(ST_FLITE_IN_USE, &fimc->state);
 
-		mutex_lock(&entity->parent->graph_mutex);
+		spin_lock(&entity->parent->graph_lock);
 		entity->use_count--;
-		mutex_unlock(&entity->parent->graph_mutex);
+		spin_unlock(&entity->parent->graph_lock);
 	}
 
 	_vb2_fop_release(file, NULL);
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index 4f5586a..3e296e8 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -1046,7 +1046,7 @@ static int __fimc_md_modify_pipeline(struct media_entity *entity, bool enable)
 	return ret;
 }
 
-/* Locking: called with entity->parent->graph_mutex mutex held. */
+/* Locking: called with entity->parent->graph_lock lock held. */
 static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)
 {
 	struct media_entity *entity_err = entity;
@@ -1305,7 +1305,7 @@ static int subdev_notifier_complete(struct v4l2_async_notifier *notifier)
 	struct fimc_md *fmd = notifier_to_fimc_md(notifier);
 	int ret;
 
-	mutex_lock(&fmd->media_dev.graph_mutex);
+	spin_lock(&fmd->media_dev.graph_lock);
 
 	ret = fimc_md_create_links(fmd);
 	if (ret < 0)
@@ -1313,7 +1313,7 @@ static int subdev_notifier_complete(struct v4l2_async_notifier *notifier)
 
 	ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev);
 unlock:
-	mutex_unlock(&fmd->media_dev.graph_mutex);
+	spin_unlock(&fmd->media_dev.graph_lock);
 	return ret;
 }
 
@@ -1371,21 +1371,21 @@ static int fimc_md_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, fmd);
 
 	/* Protect the media graph while we're registering entities */
-	mutex_lock(&fmd->media_dev.graph_mutex);
+	spin_lock(&fmd->media_dev.graph_lock);
 
 	ret = fimc_md_register_platform_entities(fmd, dev->of_node);
 	if (ret) {
-		mutex_unlock(&fmd->media_dev.graph_mutex);
+		spin_unlock(&fmd->media_dev.graph_lock);
 		goto err_clk;
 	}
 
 	ret = fimc_md_register_sensor_entities(fmd);
 	if (ret) {
-		mutex_unlock(&fmd->media_dev.graph_mutex);
+		spin_unlock(&fmd->media_dev.graph_lock);
 		goto err_m_ent;
 	}
 
-	mutex_unlock(&fmd->media_dev.graph_mutex);
+	spin_unlock(&fmd->media_dev.graph_lock);
 
 	ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode);
 	if (ret)
diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h
index 0321454..91edd9b 100644
--- a/drivers/media/platform/exynos4-is/media-dev.h
+++ b/drivers/media/platform/exynos4-is/media-dev.h
@@ -175,12 +175,12 @@ static inline struct fimc_md *notifier_to_fimc_md(struct v4l2_async_notifier *n)
 
 static inline void fimc_md_graph_lock(struct exynos_video_entity *ve)
 {
-	mutex_lock(&ve->vdev.entity.parent->graph_mutex);
+	spin_lock(&ve->vdev.entity.parent->graph_lock);
 }
 
 static inline void fimc_md_graph_unlock(struct exynos_video_entity *ve)
 {
-	mutex_unlock(&ve->vdev.entity.parent->graph_mutex);
+	spin_unlock(&ve->vdev.entity.parent->graph_lock);
 }
 
 int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on);
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 07/19] media: platform omap3isp: Update graph_mutex to graph_lock spinlock
  2015-07-22 22:42 [PATCH v2 00/19] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (5 preceding siblings ...)
  2015-07-22 22:42 ` [PATCH v2 06/19] media: platform exynos4-is: Update graph_mutex to graph_lock spinlock Shuah Khan
@ 2015-07-22 22:42 ` Shuah Khan
  2015-07-22 22:42 ` [PATCH v2 08/19] media: platform s3c-camif: " Shuah Khan
                   ` (12 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Shuah Khan @ 2015-07-22 22:42 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, tiwai, sakari.ailus,
	perex, crope, arnd, stefanr, ruchandani.tina, chehabrafael,
	dan.carpenter, prabhakar.csengg, chris.j.arges, agoode,
	pierre-louis.bossart, gtmkramer, clemens, daniel, vladcatoi,
	misterpib, damien, pmatilai, takamichiho, normalperson,
	bugzilla.frnkcg, joe, calcprogrammer1, jussi, kyungmin.park,
	s.nawrocki, kgene, hyun.kwon, michal.simek, soren.brinkmann,
	pawel, m.szyprowski, gregkh, skd08, nsekhar, boris.brezillon,
	Julia.Lawall, elfring, p.zabel, ricardo.ribalda
  Cc: Shuah Khan, linux-media, alsa-devel, linux-samsung-soc,
	linux-arm-kernel, devel

Update graph_mutex to graph_lock spinlock to be in sync with
the Media Conttroller change for the same.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/platform/omap3isp/isp.c      | 4 ++--
 drivers/media/platform/omap3isp/ispvideo.c | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 18d0a87..a6e7f92 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -789,7 +789,7 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use)
 	int change = use ? 1 : -1;
 	int ret;
 
-	mutex_lock(&entity->parent->graph_mutex);
+	spin_lock(&entity->parent->graph_lock);
 
 	/* Apply use count to node. */
 	entity->use_count += change;
@@ -800,7 +800,7 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use)
 	if (ret < 0)
 		entity->use_count -= change;
 
-	mutex_unlock(&entity->parent->graph_mutex);
+	spin_unlock(&entity->parent->graph_lock);
 
 	return ret;
 }
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
index d285af1..9ec3bb7 100644
--- a/drivers/media/platform/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -229,7 +229,7 @@ static int isp_video_get_graph_data(struct isp_video *video,
 	struct media_device *mdev = entity->parent;
 	struct isp_video *far_end = NULL;
 
-	mutex_lock(&mdev->graph_mutex);
+	spin_lock(&mdev->graph_lock);
 	media_entity_graph_walk_start(&graph, entity);
 
 	while ((entity = media_entity_graph_walk_next(&graph))) {
@@ -251,7 +251,7 @@ static int isp_video_get_graph_data(struct isp_video *video,
 			far_end = __video;
 	}
 
-	mutex_unlock(&mdev->graph_mutex);
+	spin_unlock(&mdev->graph_lock);
 
 	if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
 		pipe->input = far_end;
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 08/19] media: platform s3c-camif: Update graph_mutex to graph_lock spinlock
  2015-07-22 22:42 [PATCH v2 00/19] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (6 preceding siblings ...)
  2015-07-22 22:42 ` [PATCH v2 07/19] media: platform omap3isp: " Shuah Khan
@ 2015-07-22 22:42 ` Shuah Khan
  2015-07-22 22:42 ` [PATCH v2 09/19] media: platform vsp1: " Shuah Khan
                   ` (11 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Shuah Khan @ 2015-07-22 22:42 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, tiwai, sakari.ailus,
	perex, crope, arnd, stefanr, ruchandani.tina, chehabrafael,
	dan.carpenter, prabhakar.csengg, chris.j.arges, agoode,
	pierre-louis.bossart, gtmkramer, clemens, daniel, vladcatoi,
	misterpib, damien, pmatilai, takamichiho, normalperson,
	bugzilla.frnkcg, joe, calcprogrammer1, jussi, kyungmin.park,
	s.nawrocki, kgene, hyun.kwon, michal.simek, soren.brinkmann,
	pawel, m.szyprowski, gregkh, skd08, nsekhar, boris.brezillon,
	Julia.Lawall, elfring, p.zabel, ricardo.ribalda
  Cc: Shuah Khan, linux-media, alsa-devel, linux-samsung-soc,
	linux-arm-kernel, devel

Update graph_mutex to graph_lock spinlock to be in sync with
the Media Conttroller change for the same.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/platform/s3c-camif/camif-core.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c
index f47b332..90dd781 100644
--- a/drivers/media/platform/s3c-camif/camif-core.c
+++ b/drivers/media/platform/s3c-camif/camif-core.c
@@ -495,7 +495,7 @@ static int s3c_camif_probe(struct platform_device *pdev)
 	if (ret < 0)
 		goto err_sens;
 
-	mutex_lock(&camif->media_dev.graph_mutex);
+	spin_lock(&camif->media_dev.graph_lock);
 
 	ret = v4l2_device_register_subdev_nodes(&camif->v4l2_dev);
 	if (ret < 0)
@@ -509,12 +509,12 @@ static int s3c_camif_probe(struct platform_device *pdev)
 	if (ret < 0)
 		goto err_unlock;
 
-	mutex_unlock(&camif->media_dev.graph_mutex);
+	spin_unlock(&camif->media_dev.graph_lock);
 	pm_runtime_put(dev);
 	return 0;
 
 err_unlock:
-	mutex_unlock(&camif->media_dev.graph_mutex);
+	spin_unlock(&camif->media_dev.graph_lock);
 err_sens:
 	v4l2_device_unregister(&camif->v4l2_dev);
 	media_device_unregister(&camif->media_dev);
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 09/19] media: platform vsp1: Update graph_mutex to graph_lock spinlock
  2015-07-22 22:42 [PATCH v2 00/19] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (7 preceding siblings ...)
  2015-07-22 22:42 ` [PATCH v2 08/19] media: platform s3c-camif: " Shuah Khan
@ 2015-07-22 22:42 ` Shuah Khan
  2015-07-22 22:42 ` [PATCH v2 10/19] media: platform xilinx: " Shuah Khan
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Shuah Khan @ 2015-07-22 22:42 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, tiwai, sakari.ailus,
	perex, crope, arnd, stefanr, ruchandani.tina, chehabrafael,
	dan.carpenter, prabhakar.csengg, chris.j.arges, agoode,
	pierre-louis.bossart, gtmkramer, clemens, daniel, vladcatoi,
	misterpib, damien, pmatilai, takamichiho, normalperson,
	bugzilla.frnkcg, joe, calcprogrammer1, jussi, kyungmin.park,
	s.nawrocki, kgene, hyun.kwon, michal.simek, soren.brinkmann,
	pawel, m.szyprowski, gregkh, skd08, nsekhar, boris.brezillon,
	Julia.Lawall, elfring, p.zabel, ricardo.ribalda
  Cc: Shuah Khan, linux-media, alsa-devel, linux-samsung-soc,
	linux-arm-kernel, devel

Update graph_mutex to graph_lock spinlock to be in sync with
the Media Conttroller change for the same.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/platform/vsp1/vsp1_video.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index d91f19a..c012fb8 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -413,7 +413,7 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,
 	unsigned int i;
 	int ret;
 
-	mutex_lock(&mdev->graph_mutex);
+	spin_lock(&mdev->graph_lock);
 
 	/* Walk the graph to locate the entities and video nodes. */
 	media_entity_graph_walk_start(&graph, entity);
@@ -447,7 +447,7 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,
 		}
 	}
 
-	mutex_unlock(&mdev->graph_mutex);
+	spin_unlock(&mdev->graph_lock);
 
 	/* We need one output and at least one input. */
 	if (pipe->num_inputs == 0 || !pipe->output) {
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 10/19] media: platform xilinx: Update graph_mutex to graph_lock spinlock
  2015-07-22 22:42 [PATCH v2 00/19] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (8 preceding siblings ...)
  2015-07-22 22:42 ` [PATCH v2 09/19] media: platform vsp1: " Shuah Khan
@ 2015-07-22 22:42 ` Shuah Khan
  2015-07-22 22:42 ` [PATCH v2 11/19] staging media: davinci_vpfe: " Shuah Khan
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Shuah Khan @ 2015-07-22 22:42 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, tiwai, sakari.ailus,
	perex, crope, arnd, stefanr, ruchandani.tina, chehabrafael,
	dan.carpenter, prabhakar.csengg, chris.j.arges, agoode,
	pierre-louis.bossart, gtmkramer, clemens, daniel, vladcatoi,
	misterpib, damien, pmatilai, takamichiho, normalperson,
	bugzilla.frnkcg, joe, calcprogrammer1, jussi, kyungmin.park,
	s.nawrocki, kgene, hyun.kwon, michal.simek, soren.brinkmann,
	pawel, m.szyprowski, gregkh, skd08, nsekhar, boris.brezillon,
	Julia.Lawall, elfring, p.zabel, ricardo.ribalda
  Cc: Shuah Khan, linux-media, alsa-devel, linux-samsung-soc,
	linux-arm-kernel, devel

Update graph_mutex to graph_lock spinlock to be in sync with
the Media Conttroller change for the same.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/platform/xilinx/xilinx-dma.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c
index 98e50e4..784f7a4 100644
--- a/drivers/media/platform/xilinx/xilinx-dma.c
+++ b/drivers/media/platform/xilinx/xilinx-dma.c
@@ -185,7 +185,7 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe,
 	unsigned int num_inputs = 0;
 	unsigned int num_outputs = 0;
 
-	mutex_lock(&mdev->graph_mutex);
+	spin_lock(&mdev->graph_lock);
 
 	/* Walk the graph to locate the video nodes. */
 	media_entity_graph_walk_start(&graph, entity);
@@ -206,7 +206,7 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe,
 		}
 	}
 
-	mutex_unlock(&mdev->graph_mutex);
+	spin_unlock(&mdev->graph_lock);
 
 	/* We need exactly one output and zero or one input. */
 	if (num_outputs != 1 || num_inputs > 1)
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 11/19] staging media: davinci_vpfe: Update graph_mutex to graph_lock spinlock
  2015-07-22 22:42 [PATCH v2 00/19] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (9 preceding siblings ...)
  2015-07-22 22:42 ` [PATCH v2 10/19] media: platform xilinx: " Shuah Khan
@ 2015-07-22 22:42 ` Shuah Khan
  2015-07-22 22:42 ` [PATCH v2 12/19] staging media: omap4iss: " Shuah Khan
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Shuah Khan @ 2015-07-22 22:42 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, tiwai, sakari.ailus,
	perex, crope, arnd, stefanr, ruchandani.tina, chehabrafael,
	dan.carpenter, prabhakar.csengg, chris.j.arges, agoode,
	pierre-louis.bossart, gtmkramer, clemens, daniel, vladcatoi,
	misterpib, damien, pmatilai, takamichiho, normalperson,
	bugzilla.frnkcg, joe, calcprogrammer1, jussi, kyungmin.park,
	s.nawrocki, kgene, hyun.kwon, michal.simek, soren.brinkmann,
	pawel, m.szyprowski, gregkh, skd08, nsekhar, boris.brezillon,
	Julia.Lawall, elfring, p.zabel, ricardo.ribalda
  Cc: Shuah Khan, linux-media, alsa-devel, linux-samsung-soc,
	linux-arm-kernel, devel

Update graph_mutex to graph_lock spinlock to be in sync with
the Media Conttroller change for the same.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/staging/media/davinci_vpfe/vpfe_video.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c
index 87048a1..2511614 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_video.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c
@@ -143,7 +143,7 @@ static void vpfe_prepare_pipeline(struct vpfe_video_device *video)
 	else
 		pipe->outputs[pipe->output_num++] = video;
 
-	mutex_lock(&mdev->graph_mutex);
+	spin_lock(&mdev->graph_lock);
 	media_entity_graph_walk_start(&graph, entity);
 	while ((entity = media_entity_graph_walk_next(&graph))) {
 		if (entity == &video->video_dev.entity)
@@ -156,7 +156,7 @@ static void vpfe_prepare_pipeline(struct vpfe_video_device *video)
 		else
 			pipe->outputs[pipe->output_num++] = far_end;
 	}
-	mutex_unlock(&mdev->graph_mutex);
+	spin_unlock(&mdev->graph_lock);
 }
 
 /* update pipe state selected by user */
@@ -289,7 +289,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe)
 		entity = &pipe->inputs[0]->video_dev.entity;
 
 	mdev = entity->parent;
-	mutex_lock(&mdev->graph_mutex);
+	spin_lock(&mdev->graph_lock);
 	media_entity_graph_walk_start(&graph, entity);
 	while ((entity = media_entity_graph_walk_next(&graph))) {
 
@@ -300,7 +300,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe)
 		if (ret < 0 && ret != -ENOIOCTLCMD)
 			break;
 	}
-	mutex_unlock(&mdev->graph_mutex);
+	spin_unlock(&mdev->graph_lock);
 	return ret;
 }
 
@@ -329,7 +329,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)
 		entity = &pipe->inputs[0]->video_dev.entity;
 
 	mdev = entity->parent;
-	mutex_lock(&mdev->graph_mutex);
+	spin_lock(&mdev->graph_lock);
 	media_entity_graph_walk_start(&graph, entity);
 
 	while ((entity = media_entity_graph_walk_next(&graph))) {
@@ -341,7 +341,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)
 		if (ret < 0 && ret != -ENOIOCTLCMD)
 			break;
 	}
-	mutex_unlock(&mdev->graph_mutex);
+	spin_unlock(&mdev->graph_lock);
 
 	return ret ? -ETIMEDOUT : 0;
 }
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 12/19] staging media: omap4iss: Update graph_mutex to graph_lock spinlock
  2015-07-22 22:42 [PATCH v2 00/19] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (10 preceding siblings ...)
  2015-07-22 22:42 ` [PATCH v2 11/19] staging media: davinci_vpfe: " Shuah Khan
@ 2015-07-22 22:42 ` Shuah Khan
  2015-07-22 22:42 ` [PATCH v2 13/19] media: Add irq safe Media Controller start/stop pipeline API Shuah Khan
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Shuah Khan @ 2015-07-22 22:42 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, tiwai, sakari.ailus,
	perex, crope, arnd, stefanr, ruchandani.tina, chehabrafael,
	dan.carpenter, prabhakar.csengg, chris.j.arges, agoode,
	pierre-louis.bossart, gtmkramer, clemens, daniel, vladcatoi,
	misterpib, damien, pmatilai, takamichiho, normalperson,
	bugzilla.frnkcg, joe, calcprogrammer1, jussi, kyungmin.park,
	s.nawrocki, kgene, hyun.kwon, michal.simek, soren.brinkmann,
	pawel, m.szyprowski, gregkh, skd08, nsekhar, boris.brezillon,
	Julia.Lawall, elfring, p.zabel, ricardo.ribalda
  Cc: Shuah Khan, linux-media, alsa-devel, linux-samsung-soc,
	linux-arm-kernel, devel

Update graph_mutex to graph_lock spinlock to be in sync with
the Media Conttroller change for the same.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/staging/media/omap4iss/iss.c       | 4 ++--
 drivers/staging/media/omap4iss/iss_video.c | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c
index 9bfb725..017ef74 100644
--- a/drivers/staging/media/omap4iss/iss.c
+++ b/drivers/staging/media/omap4iss/iss.c
@@ -494,7 +494,7 @@ int omap4iss_pipeline_pm_use(struct media_entity *entity, int use)
 	int change = use ? 1 : -1;
 	int ret;
 
-	mutex_lock(&entity->parent->graph_mutex);
+	spin_lock(&entity->parent->graph_lock);
 
 	/* Apply use count to node. */
 	entity->use_count += change;
@@ -505,7 +505,7 @@ int omap4iss_pipeline_pm_use(struct media_entity *entity, int use)
 	if (ret < 0)
 		entity->use_count -= change;
 
-	mutex_unlock(&entity->parent->graph_mutex);
+	spin_unlock(&entity->parent->graph_lock);
 
 	return ret;
 }
diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c
index 85c54fe..2db9d16 100644
--- a/drivers/staging/media/omap4iss/iss_video.c
+++ b/drivers/staging/media/omap4iss/iss_video.c
@@ -210,7 +210,7 @@ iss_video_far_end(struct iss_video *video)
 	struct media_device *mdev = entity->parent;
 	struct iss_video *far_end = NULL;
 
-	mutex_lock(&mdev->graph_mutex);
+	spin_lock(&mdev->graph_lock);
 	media_entity_graph_walk_start(&graph, entity);
 
 	while ((entity = media_entity_graph_walk_next(&graph))) {
@@ -227,7 +227,7 @@ iss_video_far_end(struct iss_video *video)
 		far_end = NULL;
 	}
 
-	mutex_unlock(&mdev->graph_mutex);
+	spin_unlock(&mdev->graph_lock);
 	return far_end;
 }
 
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 13/19] media: Add irq safe Media Controller start/stop pipeline API
  2015-07-22 22:42 [PATCH v2 00/19] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (11 preceding siblings ...)
  2015-07-22 22:42 ` [PATCH v2 12/19] staging media: omap4iss: " Shuah Khan
@ 2015-07-22 22:42 ` Shuah Khan
  2015-07-22 22:42 ` [PATCH v2 14/19] media: Add enable_source handler field to struct media_device Shuah Khan
                   ` (6 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Shuah Khan @ 2015-07-22 22:42 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, tiwai, sakari.ailus,
	perex, crope, arnd, stefanr, ruchandani.tina, chehabrafael,
	dan.carpenter, prabhakar.csengg, chris.j.arges, agoode,
	pierre-louis.bossart, gtmkramer, clemens, daniel, vladcatoi,
	misterpib, damien, pmatilai, takamichiho, normalperson,
	bugzilla.frnkcg, joe, calcprogrammer1, jussi, kyungmin.park,
	s.nawrocki, kgene, hyun.kwon, michal.simek, soren.brinkmann,
	pawel, m.szyprowski, gregkh, skd08, nsekhar, boris.brezillon,
	Julia.Lawall, elfring, p.zabel, ricardo.ribalda
  Cc: Shuah Khan, linux-media, alsa-devel, linux-samsung-soc,
	linux-arm-kernel, devel

Add irq safe Media Controller start/stop pipeline API
media_entity_pipeline_start_irq()
media_entity_pipeline_stop_irq()
to be used from inside interrupt context.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/media-entity.c | 80 +++++++++++++++++++++++++++++++++++++-------
 include/media/media-entity.h |  3 ++
 2 files changed, 70 insertions(+), 13 deletions(-)

diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 31132573..293cf25 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -210,6 +210,8 @@ EXPORT_SYMBOL_GPL(media_entity_graph_walk_next);
 
 /**
  * media_entity_pipeline_start - Mark a pipeline as streaming
+ * media_entity_pipeline_start_irq - Mark a pipeline as streaming
+ *			(safe to be used from inside interrupt context)
  * @entity: Starting entity
  * @pipe: Media pipeline to be assigned to all entities in the pipeline.
  *
@@ -222,16 +224,18 @@ EXPORT_SYMBOL_GPL(media_entity_graph_walk_next);
  * pipeline pointer must be identical for all nested calls to
  * media_entity_pipeline_start().
  */
-__must_check int media_entity_pipeline_start(struct media_entity *entity,
-					     struct media_pipeline *pipe)
+/*
+ * __media_entity_pipeline_start()
+ * Should be called with graph_lock held
+*/
+static __must_check int __media_entity_pipeline_start(
+						struct media_entity *entity,
+						struct media_pipeline *pipe)
 {
-	struct media_device *mdev = entity->parent;
 	struct media_entity_graph graph;
 	struct media_entity *entity_err = entity;
 	int ret;
 
-	spin_lock(&mdev->graph_lock);
-
 	media_entity_graph_walk_start(&graph, entity);
 
 	while ((entity = media_entity_graph_walk_next(&graph))) {
@@ -303,8 +307,6 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
 		}
 	}
 
-	spin_unlock(&mdev->graph_lock);
-
 	return 0;
 
 error:
@@ -327,14 +329,46 @@ error:
 			break;
 	}
 
-	spin_unlock(&mdev->graph_lock);
+	return ret;
+}
 
+/*
+ * media_entity_pipeline_start - Mark a pipeline as streaming
+ *			(unsafe to be used from inside interrupt context)
+*/
+__must_check int media_entity_pipeline_start(struct media_entity *entity,
+					     struct media_pipeline *pipe)
+{
+	int ret;
+
+	spin_lock(&entity->parent->graph_lock);
+	ret = __media_entity_pipeline_start(entity, pipe);
+	spin_unlock(&entity->parent->graph_lock);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(media_entity_pipeline_start);
 
+/*
+ * media_entity_pipeline_start_irq - Mark a pipeline as streaming
+ *			(safe to be used from inside interrupt context)
+*/
+__must_check int media_entity_pipeline_start_irq(struct media_entity *entity,
+						 struct media_pipeline *pipe)
+{
+	int ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(&entity->parent->graph_lock, flags);
+	ret = __media_entity_pipeline_start(entity, pipe);
+	spin_unlock_irqrestore(&entity->parent->graph_lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(media_entity_pipeline_start_irq);
+
 /**
  * media_entity_pipeline_stop - Mark a pipeline as not streaming
+ * media_entity_pipeline_stop_irq - Mark a pipeline as not streaming
+ *			(safe to be used from inside interrupt context)
  * @entity: Starting entity
  *
  * Mark all entities connected to a given entity through enabled links, either
@@ -345,13 +379,10 @@ EXPORT_SYMBOL_GPL(media_entity_pipeline_start);
  * number of calls to this function are required to mark the pipeline as not
  * streaming.
  */
-void media_entity_pipeline_stop(struct media_entity *entity)
+static void __media_entity_pipeline_stop(struct media_entity *entity)
 {
-	struct media_device *mdev = entity->parent;
 	struct media_entity_graph graph;
 
-	spin_lock(&mdev->graph_lock);
-
 	media_entity_graph_walk_start(&graph, entity);
 
 	while ((entity = media_entity_graph_walk_next(&graph))) {
@@ -359,11 +390,34 @@ void media_entity_pipeline_stop(struct media_entity *entity)
 		if (entity->stream_count == 0)
 			entity->pipe = NULL;
 	}
+}
 
-	spin_unlock(&mdev->graph_lock);
+/*
+ * media_entity_pipeline_stop - Mark a pipeline as not streaming
+ *			(unsafe to be used from inside interrupt context)
+*/
+void media_entity_pipeline_stop(struct media_entity *entity)
+{
+	spin_lock(&entity->parent->graph_lock);
+	__media_entity_pipeline_stop(entity);
+	spin_unlock(&entity->parent->graph_lock);
 }
 EXPORT_SYMBOL_GPL(media_entity_pipeline_stop);
 
+/*
+ * media_entity_pipeline_stop_irq - Mark a pipeline as not streaming
+ *			(safe to be used from inside interrupt context)
+*/
+void media_entity_pipeline_stop_irq(struct media_entity *entity)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&entity->parent->graph_lock, flags);
+	__media_entity_pipeline_stop(entity);
+	spin_unlock_irqrestore(&entity->parent->graph_lock, flags);
+}
+EXPORT_SYMBOL_GPL(media_entity_pipeline_stop_irq);
+
 /* -----------------------------------------------------------------------------
  * Module use count
  */
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index 0c003d8..a4be306 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -151,6 +151,9 @@ media_entity_graph_walk_next(struct media_entity_graph *graph);
 __must_check int media_entity_pipeline_start(struct media_entity *entity,
 					     struct media_pipeline *pipe);
 void media_entity_pipeline_stop(struct media_entity *entity);
+__must_check int media_entity_pipeline_start_irq(struct media_entity *entity,
+					     struct media_pipeline *pipe);
+void media_entity_pipeline_stop_irq(struct media_entity *entity);
 
 #define media_entity_call(entity, operation, args...)			\
 	(((entity)->ops && (entity)->ops->operation) ?			\
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 14/19] media: Add enable_source handler field to struct media_device
  2015-07-22 22:42 [PATCH v2 00/19] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (12 preceding siblings ...)
  2015-07-22 22:42 ` [PATCH v2 13/19] media: Add irq safe Media Controller start/stop pipeline API Shuah Khan
@ 2015-07-22 22:42 ` Shuah Khan
  2015-07-22 22:42 ` [PATCH v2 15/19] media: v4l-core add v4l_enable_media_tuner() to check for tuner availability Shuah Khan
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Shuah Khan @ 2015-07-22 22:42 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, tiwai, sakari.ailus,
	perex, crope, arnd, stefanr, ruchandani.tina, chehabrafael,
	dan.carpenter, prabhakar.csengg, chris.j.arges, agoode,
	pierre-louis.bossart, gtmkramer, clemens, daniel, vladcatoi,
	misterpib, damien, pmatilai, takamichiho, normalperson,
	bugzilla.frnkcg, joe, calcprogrammer1, jussi, kyungmin.park,
	s.nawrocki, kgene, hyun.kwon, michal.simek, soren.brinkmann,
	pawel, m.szyprowski, gregkh, skd08, nsekhar, boris.brezillon,
	Julia.Lawall, elfring, p.zabel, ricardo.ribalda
  Cc: Shuah Khan, linux-media, alsa-devel, linux-samsung-soc,
	linux-arm-kernel, devel

Add a new field to enable_source handler to find source entity
for the sink entity and check if it is available, and activate
the link using media_entity_setup_link() interface. Bridge driver
is expected to implement and set the handler when media_device is
registered or when bridge driver finds the media_device during
probe. This is to enable the use-case to find tuner entity
connected to the decoder entity and check if it is available,
and activate the using media_entity_setup_link() if it is available.
This hanlder can be invoked from media core (v4l-core, dvb-core)
as well as other drivers such as ALSA that control the media device.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 include/media/media-device.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/include/media/media-device.h b/include/media/media-device.h
index e73642c..377102b 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -84,6 +84,18 @@ struct media_device {
 	/* Serializes graph operations. */
 	spinlock_t graph_lock;
 
+	/* Handler to find source entity for the sink entity and
+	 * check if it is available, and activate the link using
+	 * media_entity_setup_link() interface.
+	 * Bridge driver is expected to implement and set the
+	 * handler when media_device is registered or when
+	 * bridge driver finds the media_device during probe.
+	 *
+	 * Use-case: find tuner entity connected to the decoder
+	 * entity and check if it is available, and activate the
+	 * using media_entity_setup_link() if it is available.
+	*/
+	int (*enable_source)(struct media_entity *sink);
 	int (*link_notify)(struct media_link *link, u32 flags,
 			   unsigned int notification);
 };
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 15/19] media: v4l-core add v4l_enable_media_tuner() to check for tuner availability
  2015-07-22 22:42 [PATCH v2 00/19] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (13 preceding siblings ...)
  2015-07-22 22:42 ` [PATCH v2 14/19] media: Add enable_source handler field to struct media_device Shuah Khan
@ 2015-07-22 22:42 ` Shuah Khan
  2015-07-22 22:42 ` [PATCH v2 16/19] media: Change v4l-core " Shuah Khan
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Shuah Khan @ 2015-07-22 22:42 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, tiwai, sakari.ailus,
	perex, crope, arnd, stefanr, ruchandani.tina, chehabrafael,
	dan.carpenter, prabhakar.csengg, chris.j.arges, agoode,
	pierre-louis.bossart, gtmkramer, clemens, daniel, vladcatoi,
	misterpib, damien, pmatilai, takamichiho, normalperson,
	bugzilla.frnkcg, joe, calcprogrammer1, jussi, kyungmin.park,
	s.nawrocki, kgene, hyun.kwon, michal.simek, soren.brinkmann,
	pawel, m.szyprowski, gregkh, skd08, nsekhar, boris.brezillon,
	Julia.Lawall, elfring, p.zabel, ricardo.ribalda
  Cc: Shuah Khan, linux-media, alsa-devel, linux-samsung-soc,
	linux-arm-kernel, devel

Add a new interface to be used by v4l-core to invoke enable_source
handler in the media_device to find tuner entity connected to the
decoder and check is it is available. enable_source handler will
activate the link if tuner is available.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/v4l2-core/v4l2-dev.c | 17 +++++++++++++++++
 include/media/v4l2-dev.h           |  3 +++
 2 files changed, 20 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index 71a1b93..00fc71d 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -230,6 +230,23 @@ struct video_device *video_devdata(struct file *file)
 }
 EXPORT_SYMBOL(video_devdata);
 
+int v4l_enable_media_tuner(struct video_device *vdev)
+{
+#ifdef CONFIG_MEDIA_CONTROLLER
+	struct media_device *mdev = vdev->decoder->parent;
+	int ret;
+
+	/* decoder */
+	if (!mdev || !mdev->enable_source)
+			return 0;
+	ret = mdev->enable_source(vdev->decoder);
+	if (ret)
+		return -EBUSY;
+	return 0;
+#endif /* CONFIG_MEDIA_CONTROLLER */
+	return 0;
+}
+EXPORT_SYMBOL_GPL(v4l_enable_media_tuner);
 
 /* Priority handling */
 
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index acbcd2f..eff3852 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -86,6 +86,7 @@ struct video_device
 {
 #if defined(CONFIG_MEDIA_CONTROLLER)
 	struct media_entity entity;
+	struct media_entity *decoder;
 #endif
 	/* device ops */
 	const struct v4l2_file_operations *fops;
@@ -178,6 +179,8 @@ struct video_device * __must_check video_device_alloc(void);
 /* this release function frees the vdev pointer */
 void video_device_release(struct video_device *vdev);
 
+int v4l_enable_media_tuner(struct video_device *vdev);
+
 /* this release function does nothing, use when the video_device is a
    static global struct. Note that having a static video_device is
    a dubious construction at best. */
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 16/19] media: Change v4l-core to check for tuner availability
  2015-07-22 22:42 [PATCH v2 00/19] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (14 preceding siblings ...)
  2015-07-22 22:42 ` [PATCH v2 15/19] media: v4l-core add v4l_enable_media_tuner() to check for tuner availability Shuah Khan
@ 2015-07-22 22:42 ` Shuah Khan
  2015-07-22 22:42 ` [PATCH v2 17/19] media: dvb-frontend change to check for tuner availability from open Shuah Khan
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Shuah Khan @ 2015-07-22 22:42 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, tiwai, sakari.ailus,
	perex, crope, arnd, stefanr, ruchandani.tina, chehabrafael,
	dan.carpenter, prabhakar.csengg, chris.j.arges, agoode,
	pierre-louis.bossart, gtmkramer, clemens, daniel, vladcatoi,
	misterpib, damien, pmatilai, takamichiho, normalperson,
	bugzilla.frnkcg, joe, calcprogrammer1, jussi, kyungmin.park,
	s.nawrocki, kgene, hyun.kwon, michal.simek, soren.brinkmann,
	pawel, m.szyprowski, gregkh, skd08, nsekhar, boris.brezillon,
	Julia.Lawall, elfring, p.zabel, ricardo.ribalda
  Cc: Shuah Khan, linux-media, alsa-devel, linux-samsung-soc,
	linux-arm-kernel, devel

Change s_input, s_fmt, s_tuner, s_frequency, querystd,
s_hw_freq_seek, and vb2_streamon interfaces that alter
the tuner configuration to check for tuner availability
by calling v4l_enable_media_tuner(). If tuner isn't free,
return -EBUSY.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/v4l2-core/v4l2-ioctl.c     | 29 +++++++++++++++++++++++++++++
 drivers/media/v4l2-core/videobuf2-core.c |  5 +++++
 2 files changed, 34 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 85de455..deffc1b 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1035,6 +1035,12 @@ static int v4l_querycap(const struct v4l2_ioctl_ops *ops,
 static int v4l_s_input(const struct v4l2_ioctl_ops *ops,
 				struct file *file, void *fh, void *arg)
 {
+	struct video_device *vfd = video_devdata(file);
+	int ret;
+
+	ret = v4l_enable_media_tuner(vfd);
+	if (ret)
+		return ret;
 	return ops->vidioc_s_input(file, fh, *(unsigned int *)arg);
 }
 
@@ -1433,6 +1439,9 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
 	int ret;
 
+	ret = v4l_enable_media_tuner(vfd);
+	if (ret)
+		return ret;
 	v4l_sanitize_format(p);
 
 	switch (p->type) {
@@ -1612,7 +1621,11 @@ static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops,
 {
 	struct video_device *vfd = video_devdata(file);
 	struct v4l2_tuner *p = arg;
+	int ret;
 
+	ret = v4l_enable_media_tuner(vfd);
+	if (ret)
+		return ret;
 	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
 			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
 	return ops->vidioc_s_tuner(file, fh, p);
@@ -1650,7 +1663,11 @@ static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops,
 	struct video_device *vfd = video_devdata(file);
 	const struct v4l2_frequency *p = arg;
 	enum v4l2_tuner_type type;
+	int ret;
 
+	ret = v4l_enable_media_tuner(vfd);
+	if (ret)
+		return ret;
 	if (vfd->vfl_type == VFL_TYPE_SDR) {
 		if (p->type != V4L2_TUNER_ADC && p->type != V4L2_TUNER_RF)
 			return -EINVAL;
@@ -1705,7 +1722,11 @@ static int v4l_s_std(const struct v4l2_ioctl_ops *ops,
 {
 	struct video_device *vfd = video_devdata(file);
 	v4l2_std_id id = *(v4l2_std_id *)arg, norm;
+	int ret;
 
+	ret = v4l_enable_media_tuner(vfd);
+	if (ret)
+		return ret;
 	norm = id & vfd->tvnorms;
 	if (vfd->tvnorms && !norm)	/* Check if std is supported */
 		return -EINVAL;
@@ -1719,7 +1740,11 @@ static int v4l_querystd(const struct v4l2_ioctl_ops *ops,
 {
 	struct video_device *vfd = video_devdata(file);
 	v4l2_std_id *p = arg;
+	int ret;
 
+	ret = v4l_enable_media_tuner(vfd);
+	if (ret)
+		return ret;
 	/*
 	 * If no signal is detected, then the driver should return
 	 * V4L2_STD_UNKNOWN. Otherwise it should return tvnorms with
@@ -1738,7 +1763,11 @@ static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops,
 	struct video_device *vfd = video_devdata(file);
 	struct v4l2_hw_freq_seek *p = arg;
 	enum v4l2_tuner_type type;
+	int ret;
 
+	ret = v4l_enable_media_tuner(vfd);
+	if (ret)
+		return ret;
 	/* s_hw_freq_seek is not supported for SDR for now */
 	if (vfd->vfl_type == VFL_TYPE_SDR)
 		return -EINVAL;
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index d835814..f2711e4 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -2300,10 +2300,15 @@ EXPORT_SYMBOL_GPL(vb2_queue_error);
  */
 int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
 {
+	int ret;
+
 	if (vb2_fileio_is_active(q)) {
 		dprintk(1, "file io in progress\n");
 		return -EBUSY;
 	}
+	ret = v4l_enable_media_tuner(q->owner->vdev);
+	if (ret)
+		return ret;
 	return vb2_internal_streamon(q, type);
 }
 EXPORT_SYMBOL_GPL(vb2_streamon);
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 17/19] media: dvb-frontend change to check for tuner availability from open
  2015-07-22 22:42 [PATCH v2 00/19] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (15 preceding siblings ...)
  2015-07-22 22:42 ` [PATCH v2 16/19] media: Change v4l-core " Shuah Khan
@ 2015-07-22 22:42 ` Shuah Khan
  2015-07-22 22:42 ` [PATCH v2 18/19] media: au0828 change to use Managed Media Controller API Shuah Khan
                   ` (2 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Shuah Khan @ 2015-07-22 22:42 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, tiwai, sakari.ailus,
	perex, crope, arnd, stefanr, ruchandani.tina, chehabrafael,
	dan.carpenter, prabhakar.csengg, chris.j.arges, agoode,
	pierre-louis.bossart, gtmkramer, clemens, daniel, vladcatoi,
	misterpib, damien, pmatilai, takamichiho, normalperson,
	bugzilla.frnkcg, joe, calcprogrammer1, jussi, kyungmin.park,
	s.nawrocki, kgene, hyun.kwon, michal.simek, soren.brinkmann,
	pawel, m.szyprowski, gregkh, skd08, nsekhar, boris.brezillon,
	Julia.Lawall, elfring, p.zabel, ricardo.ribalda
  Cc: Shuah Khan, linux-media, alsa-devel, linux-samsung-soc,
	linux-arm-kernel, devel

Checking for tuner availability from frontend thread start
disrupts video stream. Change to check for tuner and start
pipeline from frontend open instead and stop pipeline from
frontend release.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/dvb-core/dvb_frontend.c | 43 ++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 24 deletions(-)

diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index 842b9c8..b394e1e 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -694,10 +694,6 @@ static int dvb_frontend_thread(void *data)
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 	enum fe_status s;
 	enum dvbfe_algo algo;
-#ifdef CONFIG_MEDIA_CONTROLLER_DVB
-	int ret;
-#endif
-
 	bool re_tune = false;
 	bool semheld = false;
 
@@ -710,20 +706,6 @@ static int dvb_frontend_thread(void *data)
 	fepriv->wakeup = 0;
 	fepriv->reinitialise = 0;
 
-#ifdef CONFIG_MEDIA_CONTROLLER_DVB
-	ret = dvb_enable_media_tuner(fe);
-	if (ret) {
-		/* FIXME: return an error if it fails */
-		dev_info(fe->dvb->device,
-			"proceeding with FE task\n");
-	} else if (fepriv->pipe_start_entity) {
-		ret = media_entity_pipeline_start(fepriv->pipe_start_entity,
-						  &fepriv->pipe);
-		if (ret)
-			return ret;
-	}
-#endif
-
 	dvb_frontend_init(fe);
 
 	set_freezable();
@@ -833,12 +815,6 @@ restart:
 		}
 	}
 
-#ifdef CONFIG_MEDIA_CONTROLLER_DVB
-	if (fepriv->pipe_start_entity)
-		media_entity_pipeline_stop(fepriv->pipe_start_entity);
-	fepriv->pipe_start_entity = NULL;
-#endif
-
 	if (dvb_powerdown_on_sleep) {
 		if (fe->ops.set_voltage)
 			fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF);
@@ -2616,6 +2592,20 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
 		fepriv->tone = -1;
 		fepriv->voltage = -1;
 
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+		ret = dvb_enable_media_tuner(fe);
+		if (ret) {
+			dev_err(fe->dvb->device,
+				"Tuner is busy. Error %d\n", ret);
+			goto err1;
+		} else if (fepriv->pipe_start_entity) {
+			ret = media_entity_pipeline_start(
+						fepriv->pipe_start_entity,
+						&fepriv->pipe);
+			if (ret)
+				goto err1;
+		}
+#endif
 		ret = dvb_frontend_start (fe);
 		if (ret)
 			goto err2;
@@ -2659,6 +2649,11 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
 		wake_up(&fepriv->wait_queue);
 		if (fe->exit != DVB_FE_NO_EXIT)
 			wake_up(&dvbdev->wait_queue);
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+		if (fepriv->pipe_start_entity)
+			media_entity_pipeline_stop(fepriv->pipe_start_entity);
+		fepriv->pipe_start_entity = NULL;
+#endif
 		if (fe->ops.ts_bus_ctrl)
 			fe->ops.ts_bus_ctrl(fe, 0);
 	}
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 18/19] media: au0828 change to use Managed Media Controller API
  2015-07-22 22:42 [PATCH v2 00/19] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (16 preceding siblings ...)
  2015-07-22 22:42 ` [PATCH v2 17/19] media: dvb-frontend change to check for tuner availability from open Shuah Khan
@ 2015-07-22 22:42 ` Shuah Khan
  2015-07-22 22:42 ` [PATCH v2 19/19] sound/usb: Update ALSA driver " Shuah Khan
  2015-07-23 18:13 ` [PATCH v2 00/19] Update ALSA, and au0828 drivers " Shuah Khan
  19 siblings, 0 replies; 21+ messages in thread
From: Shuah Khan @ 2015-07-22 22:42 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, tiwai, sakari.ailus,
	perex, crope, arnd, stefanr, ruchandani.tina, chehabrafael,
	dan.carpenter, prabhakar.csengg, chris.j.arges, agoode,
	pierre-louis.bossart, gtmkramer, clemens, daniel, vladcatoi,
	misterpib, damien, pmatilai, takamichiho, normalperson,
	bugzilla.frnkcg, joe, calcprogrammer1, jussi, kyungmin.park,
	s.nawrocki, kgene, hyun.kwon, michal.simek, soren.brinkmann,
	pawel, m.szyprowski, gregkh, skd08, nsekhar, boris.brezillon,
	Julia.Lawall, elfring, p.zabel, ricardo.ribalda
  Cc: Shuah Khan, linux-media, alsa-devel, linux-samsung-soc,
	linux-arm-kernel, devel

Change au0828 to use Managed Media Controller API to coordinate
creating/deleting media device on parent usb device it shares
with the snd-usb-audio driver. With this change, au0828 uses
media_device_get_devres() to allocate a new media device devres
or return an existing one, if it finds one.

au0828 registers entity_notify hook to create media graph for
the device. It creates necessary links from video, vbi, and
ALSA entities to decoder and links tuner and decoder entities.

Implements enable_source hanlder for other drivers to use to
check for tuner connected to the decoder and activate the link
if tuner is free. In addition, au0828-video will populate decoder
field struct video_device for v4l-core to use it when it invokes
enable_source hanlder. au0828 is changed to use enable_source
hanlder to check for tuner availability from vidioc_g_tuner(),
au0828_v4l2_close(), and queue_setup() prior to changing tuner
settings. If tuner isn't free, return busy condition.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/usb/au0828/au0828-core.c  | 184 +++++++++++++++++++++++---------
 drivers/media/usb/au0828/au0828-video.c |  72 ++++---------
 drivers/media/usb/au0828/au0828.h       |   5 +
 3 files changed, 155 insertions(+), 106 deletions(-)

diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 0378a2c..ffdde58 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -20,6 +20,7 @@
  */
 
 #include "au0828.h"
+#include "au8522.h"
 
 #include <linux/module.h>
 #include <linux/slab.h>
@@ -129,12 +130,13 @@ static int recv_control_msg(struct au0828_dev *dev, u16 request, u32 value,
 
 static void au0828_unregister_media_device(struct au0828_dev *dev)
 {
-
 #ifdef CONFIG_MEDIA_CONTROLLER
-	if (dev->media_dev) {
-		media_device_unregister(dev->media_dev);
-		kfree(dev->media_dev);
-		dev->media_dev = NULL;
+	if (dev->media_dev &&
+	    media_devnode_is_registered(&dev->media_dev->devnode)) {
+		media_device_unregister_entity_notify(dev->media_dev,
+						      &dev->entity_notify);
+			media_device_unregister(dev->media_dev);
+			dev->media_dev = NULL;
 	}
 #endif
 }
@@ -196,53 +198,23 @@ static void au0828_usb_disconnect(struct usb_interface *interface)
 	au0828_usb_release(dev);
 }
 
-static void au0828_media_device_register(struct au0828_dev *dev,
-					  struct usb_device *udev)
-{
-#ifdef CONFIG_MEDIA_CONTROLLER
-	struct media_device *mdev;
-	int ret;
-
-	mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
-	if (!mdev)
-		return;
-
-	mdev->dev = &udev->dev;
-
-	if (!dev->board.name)
-		strlcpy(mdev->model, "unknown au0828", sizeof(mdev->model));
-	else
-		strlcpy(mdev->model, dev->board.name, sizeof(mdev->model));
-	if (udev->serial)
-		strlcpy(mdev->serial, udev->serial, sizeof(mdev->serial));
-	strcpy(mdev->bus_info, udev->devpath);
-	mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
-	mdev->driver_version = LINUX_VERSION_CODE;
-
-	ret = media_device_register(mdev);
-	if (ret) {
-		pr_err(
-			"Couldn't create a media device. Error: %d\n",
-			ret);
-		kfree(mdev);
-		return;
-	}
-
-	dev->media_dev = mdev;
-#endif
-}
-
-
-static void au0828_create_media_graph(struct au0828_dev *dev)
+void au0828_create_media_graph(struct media_entity *new, void *notify_data)
 {
 #ifdef CONFIG_MEDIA_CONTROLLER
+	struct au0828_dev *dev = (struct au0828_dev *) notify_data;
 	struct media_device *mdev = dev->media_dev;
 	struct media_entity *entity;
 	struct media_entity *tuner = NULL, *decoder = NULL;
+	struct media_entity *alsa_capture = NULL;
+	int ret = 0;
 
 	if (!mdev)
 		return;
 
+	if (dev->tuner_linked && dev->vdev_linked && dev->vbi_linked &&
+		dev->alsa_capture_linked)
+		return;
+
 	media_device_for_each_entity(entity, mdev) {
 		switch (entity->type) {
 		case MEDIA_ENT_T_V4L2_SUBDEV_TUNER:
@@ -251,6 +223,9 @@ static void au0828_create_media_graph(struct au0828_dev *dev)
 		case MEDIA_ENT_T_V4L2_SUBDEV_DECODER:
 			decoder = entity;
 			break;
+		case MEDIA_ENT_T_DEVNODE_ALSA_CAPTURE:
+			alsa_capture = entity;
+			break;
 		}
 	}
 
@@ -259,15 +234,120 @@ static void au0828_create_media_graph(struct au0828_dev *dev)
 	if (!decoder)
 		return;
 
-	if (tuner)
-		media_entity_create_link(tuner, 0, decoder, 0,
+	if (tuner && !dev->tuner_linked) {
+		ret = media_entity_create_link(tuner, 0, decoder, 0,
 					 MEDIA_LNK_FL_ENABLED);
-	if (dev->vdev.entity.links)
-		media_entity_create_link(decoder, 1, &dev->vdev.entity, 0,
-				 MEDIA_LNK_FL_ENABLED);
-	if (dev->vbi_dev.entity.links)
-		media_entity_create_link(decoder, 2, &dev->vbi_dev.entity, 0,
-				 MEDIA_LNK_FL_ENABLED);
+		if (ret == 0)
+			dev->tuner_linked = 1;
+	}
+	if (dev->vdev.entity.links && !dev->vdev_linked) {
+		ret = media_entity_create_link(decoder, AU8522_PAD_VID_OUT,
+				&dev->vdev.entity, 0, MEDIA_LNK_FL_ENABLED);
+		if (ret == 0)
+			dev->vdev_linked = 1;
+	}
+	if (dev->vbi_dev.entity.links && !dev->vbi_linked) {
+		ret = media_entity_create_link(decoder, AU8522_PAD_VBI_OUT,
+				&dev->vbi_dev.entity, 0, MEDIA_LNK_FL_ENABLED);
+		if (ret == 0)
+			dev->vbi_linked = 1;
+	}
+	if (alsa_capture && !dev->alsa_capture_linked) {
+		ret = media_entity_create_link(decoder, AU8522_PAD_AUDIO_OUT,
+						alsa_capture, 0,
+						MEDIA_LNK_FL_ENABLED);
+		if (ret == 0)
+			dev->alsa_capture_linked = 1;
+	}
+#endif
+}
+
+int au0828_enable_source(struct media_entity *enable_sink)
+{
+#ifdef CONFIG_MEDIA_CONTROLLER
+	struct media_entity  *source;
+	struct media_link *link, *found_link = NULL;
+	int i, ret, active_links = 0, n_links = 0;
+
+	for (i = 0; i < enable_sink->num_links; i++) {
+		link = &enable_sink->links[i];
+		if (link->sink->entity == enable_sink) {
+			found_link = link;
+			n_links++;
+			if (link->flags & MEDIA_LNK_FL_ENABLED)
+				active_links++;
+			break;
+		}
+	}
+
+	if (!n_links || active_links == 1 || !found_link)
+		return 0;
+
+	source = found_link->source->entity;
+	for (i = 0; i < source->num_links; i++) {
+		struct media_entity *sink;
+		int flags = 0;
+
+		link = &source->links[i];
+		sink = link->sink->entity;
+
+		if (sink == enable_sink)
+			flags = MEDIA_LNK_FL_ENABLED;
+
+		ret = media_entity_setup_link(link, flags);
+		if (ret) {
+			pr_err(
+				"Change tuner link %s->%s to %s. Error %d\n",
+				source->name, sink->name,
+				flags ? "enabled" : "disabled",
+				ret);
+			return ret;
+		}
+	}
+	return 0;
+#endif
+	return 0;
+}
+
+static void au0828_media_device_register(struct au0828_dev *dev,
+					  struct usb_device *udev)
+{
+#ifdef CONFIG_MEDIA_CONTROLLER
+	struct media_device *mdev;
+	int ret;
+
+	mdev = media_device_get_devres(&udev->dev);
+	if (!mdev)
+		return;
+
+	if (!media_devnode_is_registered(&mdev->devnode)) {
+		/* register media device */
+		mdev->dev = &udev->dev;
+		if (udev->product)
+			strlcpy(mdev->model, udev->product,
+				sizeof(mdev->model));
+		if (udev->serial)
+			strlcpy(mdev->serial, udev->serial,
+				sizeof(mdev->serial));
+		strcpy(mdev->bus_info, udev->devpath);
+		mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
+		mdev->enable_source = au0828_enable_source;
+		ret = media_device_register(mdev);
+		if (ret) {
+			dev_err(&udev->dev,
+				"Couldn't create a media device. Error: %d\n",
+				ret);
+			return;
+		}
+		/* register entity_notify callback */
+		dev->entity_notify.notify_data = (void *) dev;
+		dev->entity_notify.notify = au0828_create_media_graph;
+		media_device_register_entity_notify(mdev, &dev->entity_notify);
+	}
+	/* If ALSA registered the media device - set enable_source */
+	if (!mdev->enable_source)
+		mdev->enable_source = au0828_enable_source;
+	dev->media_dev = mdev;
 #endif
 }
 
@@ -383,8 +463,6 @@ static int au0828_usb_probe(struct usb_interface *interface,
 
 	mutex_unlock(&dev->lock);
 
-	au0828_create_media_graph(dev);
-
 	return retval;
 }
 
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index 939b2ad..de3140e 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -641,58 +641,10 @@ static int au0828_enable_analog_tuner(struct au0828_dev *dev)
 {
 #ifdef CONFIG_MEDIA_CONTROLLER
 	struct media_device *mdev = dev->media_dev;
-	struct media_entity  *entity, *source;
-	struct media_link *link, *found_link = NULL;
-	int i, ret, active_links = 0;
 
-	if (!mdev || !dev->decoder)
+	if (!mdev || !dev->decoder || !mdev->enable_source)
 		return 0;
-
-	/*
-	 * This will find the tuner that is connected into the decoder.
-	 * Technically, this is not 100% correct, as the device may be
-	 * using an analog input instead of the tuner. However, as we can't
-	 * do DVB streaming while the DMA engine is being used for V4L2,
-	 * this should be enough for the actual needs.
-	 */
-	for (i = 0; i < dev->decoder->num_links; i++) {
-		link = &dev->decoder->links[i];
-		if (link->sink->entity == dev->decoder) {
-			found_link = link;
-			if (link->flags & MEDIA_LNK_FL_ENABLED)
-				active_links++;
-			break;
-		}
-	}
-
-	if (active_links == 1 || !found_link)
-		return 0;
-
-	source = found_link->source->entity;
-	for (i = 0; i < source->num_links; i++) {
-		struct media_entity *sink;
-		int flags = 0;
-
-		link = &source->links[i];
-		sink = link->sink->entity;
-
-		if (sink == entity)
-			flags = MEDIA_LNK_FL_ENABLED;
-
-		ret = media_entity_setup_link(link, flags);
-		if (ret) {
-			pr_err(
-				"Couldn't change link %s->%s to %s. Error %d\n",
-				source->name, sink->name,
-				flags ? "enabled" : "disabled",
-				ret);
-			return ret;
-		} else
-			au0828_isocdbg(
-				"link %s->%s was %s\n",
-				source->name, sink->name,
-				flags ? "ENABLED" : "disabled");
-	}
+	return mdev->enable_source(dev->decoder);
 #endif
 	return 0;
 }
@@ -704,6 +656,7 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
 	struct au0828_dev *dev = vb2_get_drv_priv(vq);
 	unsigned long img_size = dev->height * dev->bytesperline;
 	unsigned long size;
+	int ret;
 
 	size = fmt ? fmt->fmt.pix.sizeimage : img_size;
 	if (size < img_size)
@@ -712,7 +665,9 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
 	*nplanes = 1;
 	sizes[0] = size;
 
-	au0828_enable_analog_tuner(dev);
+	ret = au0828_enable_analog_tuner(dev);
+	if (ret)
+		return ret;
 
 	return 0;
 }
@@ -1067,8 +1022,12 @@ static int au0828_v4l2_close(struct file *filp)
 		goto end;
 
 	if (dev->users == 1) {
-		/* Save some power by putting tuner to sleep */
-		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
+		/* Save some power by putting tuner to sleep, if it is free */
+		/* What happens when radio is using tuner?? */
+		ret = au0828_enable_analog_tuner(dev);
+		if (ret == 0)
+			v4l2_device_call_all(&dev->v4l2_dev, 0, core,
+						s_power, 0);
 		dev->std_set_in_tuner_core = 0;
 
 		/* When close the device, set the usb intf0 into alt0 to free
@@ -1469,10 +1428,15 @@ static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio
 static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
 {
 	struct au0828_dev *dev = video_drvdata(file);
+	int ret;
 
 	if (t->index != 0)
 		return -EINVAL;
 
+	ret = au0828_enable_analog_tuner(dev);
+	if (ret)
+		return ret;
+
 	dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
 		dev->std_set_in_tuner_core, dev->dev_state);
 
@@ -1884,11 +1848,13 @@ int au0828_analog_register(struct au0828_dev *dev,
 	strcpy(dev->vbi_dev.name, "au0828a vbi");
 
 #if defined(CONFIG_MEDIA_CONTROLLER)
+	dev->vdev.decoder = dev->decoder;
 	dev->video_pad.flags = MEDIA_PAD_FL_SINK;
 	ret = media_entity_init(&dev->vdev.entity, 1, &dev->video_pad, 0);
 	if (ret < 0)
 		pr_err("failed to initialize video media entity!\n");
 
+	dev->vbi_dev.decoder = dev->decoder;
 	dev->vbi_pad.flags = MEDIA_PAD_FL_SINK;
 	ret = media_entity_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad, 0);
 	if (ret < 0)
diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
index d3644b3..a59ba08 100644
--- a/drivers/media/usb/au0828/au0828.h
+++ b/drivers/media/usb/au0828/au0828.h
@@ -281,6 +281,11 @@ struct au0828_dev {
 	struct media_device *media_dev;
 	struct media_pad video_pad, vbi_pad;
 	struct media_entity *decoder;
+	struct media_entity_notify entity_notify;
+	bool tuner_linked;
+	bool vdev_linked;
+	bool vbi_linked;
+	bool alsa_capture_linked;
 #endif
 };
 
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 19/19] sound/usb: Update ALSA driver to use Managed Media Controller API
  2015-07-22 22:42 [PATCH v2 00/19] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (17 preceding siblings ...)
  2015-07-22 22:42 ` [PATCH v2 18/19] media: au0828 change to use Managed Media Controller API Shuah Khan
@ 2015-07-22 22:42 ` Shuah Khan
  2015-07-23 18:13 ` [PATCH v2 00/19] Update ALSA, and au0828 drivers " Shuah Khan
  19 siblings, 0 replies; 21+ messages in thread
From: Shuah Khan @ 2015-07-22 22:42 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, tiwai, sakari.ailus,
	perex, crope, arnd, stefanr, ruchandani.tina, chehabrafael,
	dan.carpenter, prabhakar.csengg, chris.j.arges, agoode,
	pierre-louis.bossart, gtmkramer, clemens, daniel, vladcatoi,
	misterpib, damien, pmatilai, takamichiho, normalperson,
	bugzilla.frnkcg, joe, calcprogrammer1, jussi, kyungmin.park,
	s.nawrocki, kgene, hyun.kwon, michal.simek, soren.brinkmann,
	pawel, m.szyprowski, gregkh, skd08, nsekhar, boris.brezillon,
	Julia.Lawall, elfring, p.zabel, ricardo.ribalda
  Cc: Shuah Khan, linux-media, alsa-devel, linux-samsung-soc,
	linux-arm-kernel, devel

Change ALSA driver to use Managed ~media Managed Controller
API to share tuner with DVB and V4L2 drivers that control
AU0828 media device.  Media device is created based on a
newly added field value in the struct snd_usb_audio_quirk.
Using this approach, the media controller API usage can be
added for a specific device. In this patch, Media Controller
API is enabled for AU0828 hw. snd_usb_create_quirk() will
check this new field, if set will create a media device using
media_device_get_devres() interface.

media_device_get_devres() will allocate a new media device
devres or return an existing one, if it finds one.

During probe, media usb driver could have created the media
device devres. It will then register the media device if it
isn't already registered. Media device unregister is done from
usb_audio_disconnect().

During probe, media usb driver could have created the
media device devres. It will then register the media
device if it isn't already registered. Media device
unregister is done from usb_audio_disconnect().

New structure media_ctl is added to group the new
fields to support media entity and links. This new
structure is added to struct snd_usb_substream.

A new entity_notify hook and a new ALSA capture media
entity are registered from snd_usb_pcm_open() after
setting up hardware information for the PCM device.

When a new entity is registered, Media Controller API
interface media_device_register_entity() invokes all
registered entity_notify hooks for the media device.
ALSA entity_notify hook parses all the entity list to
find a link from decoder it ALSA entity. This indicates
that the bridge driver created a link from decoder to
ALSA capture entity.

ALSA will attempt to enable the tuner to link the tuner
to the decoder calling enable_source handler if one is
provided by the bridge driver prior to starting Media
pipeline from snd_usb_substream_capture_trigger(). If
enable_source returns with tuner busy condition, then
SNDRV_PCM_TRIGGER_START will fail with -EBUSY. Media
pipeline is stopped in response to SNDRV_PCM_TRIGGER_STOP.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 sound/usb/Makefile       |  15 +++-
 sound/usb/card.c         |   5 ++
 sound/usb/card.h         |   1 +
 sound/usb/media.c        | 227 +++++++++++++++++++++++++++++++++++++++++++++++
 sound/usb/media.h        |  52 +++++++++++
 sound/usb/pcm.c          |  15 +++-
 sound/usb/quirks-table.h |   1 +
 sound/usb/quirks.c       |   9 +-
 sound/usb/stream.c       |   2 +
 sound/usb/usbaudio.h     |   1 +
 10 files changed, 324 insertions(+), 4 deletions(-)
 create mode 100644 sound/usb/media.c
 create mode 100644 sound/usb/media.h

diff --git a/sound/usb/Makefile b/sound/usb/Makefile
index 2d2d122..665fdd9 100644
--- a/sound/usb/Makefile
+++ b/sound/usb/Makefile
@@ -2,6 +2,18 @@
 # Makefile for ALSA
 #
 
+# Media Controller
+ifeq ($(CONFIG_MEDIA_CONTROLLER),y)
+  ifeq ($(CONFIG_MEDIA_SUPPORT),y)
+        KBUILD_CFLAGS += -DUSE_MEDIA_CONTROLLER
+  endif
+  ifeq ($(CONFIG_MEDIA_SUPPORT_MODULE),y)
+    ifeq ($(MODULE),y)
+          KBUILD_CFLAGS += -DUSE_MEDIA_CONTROLLER
+    endif
+  endif
+endif
+
 snd-usb-audio-objs := 	card.o \
 			clock.o \
 			endpoint.o \
@@ -13,7 +25,8 @@ snd-usb-audio-objs := 	card.o \
 			pcm.o \
 			proc.o \
 			quirks.o \
-			stream.o
+			stream.o \
+			media.o
 
 snd-usbmidi-lib-objs := midi.o
 
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 1fab977..469d2bf 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -66,6 +66,7 @@
 #include "format.h"
 #include "power.h"
 #include "stream.h"
+#include "media.h"
 
 MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
 MODULE_DESCRIPTION("USB Audio");
@@ -619,6 +620,10 @@ static void usb_audio_disconnect(struct usb_interface *intf)
 		list_for_each_entry(mixer, &chip->mixer_list, list) {
 			snd_usb_mixer_disconnect(mixer);
 		}
+		/* Nice to check quirk && quirk->media_device
+		 * need some special handlings. Doesn't look like
+		 * we have access to quirk here */
+		media_device_delete(intf);
 	}
 
 	chip->num_interfaces--;
diff --git a/sound/usb/card.h b/sound/usb/card.h
index ef580b4..235a85f 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -155,6 +155,7 @@ struct snd_usb_substream {
 	} dsd_dop;
 
 	bool trigger_tstamp_pending_update; /* trigger timestamp being updated from initial estimate */
+	void *media_ctl;
 };
 
 struct snd_usb_stream {
diff --git a/sound/usb/media.c b/sound/usb/media.c
new file mode 100644
index 0000000..ffc028a
--- /dev/null
+++ b/sound/usb/media.c
@@ -0,0 +1,227 @@
+/*
+ * media.c - Media Controller specific ALSA driver code
+ *
+ * Copyright (c) 2015 Shuah Khan <shuahkh@osg.samsung.com>
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * This file is released under the GPLv2.
+ */
+
+/*
+ * This file adds Media Controller support to ALSA driver
+ * to use the Media Controller API to share tuner with DVB
+ * and V4L2 drivers that control media device. Media device
+ * is created based on existing quirks framework. Using this
+ * approach, the media controller API usage can be added for
+ * a specific device.
+*/
+
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/usb.h>
+#include <linux/moduleparam.h>
+#include <linux/mutex.h>
+#include <linux/usb/audio.h>
+#include <linux/usb/audio-v2.h>
+#include <linux/module.h>
+
+#include <sound/control.h>
+#include <sound/core.h>
+#include <sound/info.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/initval.h>
+
+#include "usbaudio.h"
+#include "card.h"
+#include "midi.h"
+#include "mixer.h"
+#include "proc.h"
+#include "quirks.h"
+#include "endpoint.h"
+#include "helper.h"
+#include "debug.h"
+#include "pcm.h"
+#include "format.h"
+#include "power.h"
+#include "stream.h"
+#include "media.h"
+
+#ifdef USE_MEDIA_CONTROLLER
+int media_device_init(struct usb_interface *iface)
+{
+	struct media_device *mdev;
+	struct usb_device *usbdev = interface_to_usbdev(iface);
+	int ret;
+
+	mdev = media_device_get_devres(&usbdev->dev);
+	if (!mdev)
+		return -ENOMEM;
+	if (!media_devnode_is_registered(&mdev->devnode)) {
+		/* register media device */
+		mdev->dev = &usbdev->dev;
+		if (usbdev->product)
+			strlcpy(mdev->model, usbdev->product,
+				sizeof(mdev->model));
+		if (usbdev->serial)
+			strlcpy(mdev->serial, usbdev->serial,
+				sizeof(mdev->serial));
+		strcpy(mdev->bus_info, usbdev->devpath);
+		mdev->hw_revision = le16_to_cpu(usbdev->descriptor.bcdDevice);
+		ret = media_device_register(mdev);
+		if (ret) {
+			dev_err(&usbdev->dev,
+				"Couldn't create a media device. Error: %d\n",
+				ret);
+			return ret;
+		}
+	}
+	return 0;
+}
+
+void media_device_delete(struct usb_interface *iface)
+{
+	struct media_device *mdev;
+	struct usb_device *usbdev = interface_to_usbdev(iface);
+
+	mdev = media_device_find_devres(&usbdev->dev);
+	if (mdev && media_devnode_is_registered(&mdev->devnode))
+		media_device_unregister(mdev);
+}
+
+static void media_entity_alsa_create_link(struct media_entity *entity,
+					void *notify_data)
+{
+	struct snd_usb_substream *subs;
+	struct media_ctl *mctl;
+	struct media_entity *eptr;
+
+	/* private and mctl should be valid for ALSA DEVNODEs */
+	subs = (struct snd_usb_substream *) notify_data;
+	mctl = (struct media_ctl *) subs->media_ctl;
+
+	if (mctl->decoder_linked)
+		return;
+
+	media_device_for_each_entity(eptr, mctl->media_dev) {
+		if (eptr->type == MEDIA_ENT_T_V4L2_SUBDEV_DECODER) {
+			int i;
+
+			for (i = 0; i < eptr->num_links; i++) {
+				struct media_link *link = &eptr->links[i];
+				struct media_entity *sink = link->sink->entity;
+
+				if (!(link->flags & MEDIA_LNK_FL_ENABLED))
+					continue;
+				if (sink == &mctl->media_entity) {
+					mctl->decoder_linked = 1;
+					mctl->decoder = eptr;
+				}
+			}
+		}
+	}
+}
+
+static int media_enable_tuner(struct media_ctl *mctl)
+{
+	int ret;
+
+	if (mctl && mctl->decoder && mctl->media_dev->enable_source) {
+		ret = mctl->media_dev->enable_source(mctl->decoder);
+		if (ret) {
+			mctl->tuner_enabled = 0;
+			return ret;
+		}
+		mctl->tuner_enabled = 1;
+	}
+	return 0;
+}
+
+void media_stream_init(struct snd_usb_substream *subs, struct snd_pcm *pcm,
+			int stream)
+{
+	struct media_device *mdev;
+	struct media_ctl *mctl;
+	struct device *pcm_dev = &pcm->streams[stream].dev;
+
+	mdev = media_device_find_devres(&subs->dev->dev);
+	if (!mdev)
+		return;
+
+	if (subs->media_ctl)
+		return;
+
+	/* allocate media_ctl */
+	mctl = kzalloc(sizeof(struct media_ctl), GFP_KERNEL);
+	if (!mctl)
+		return;
+
+	subs->media_ctl = (void *) mctl;
+	mctl->media_dev = mdev;
+	mctl->entity_notify.notify_data = (void *) subs;
+	mctl->entity_notify.notify = media_entity_alsa_create_link;
+	media_device_register_entity_notify(mctl->media_dev,
+							&mctl->entity_notify);
+	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+		mctl->media_entity.type = MEDIA_ENT_T_DEVNODE_ALSA_PLAYBACK;
+	else
+		mctl->media_entity.type = MEDIA_ENT_T_DEVNODE_ALSA_CAPTURE;
+	mctl->media_entity.name = pcm->name;
+	mctl->media_entity.info.dev.major = MAJOR(pcm_dev->devt);
+	mctl->media_entity.info.dev.minor = MINOR(pcm_dev->devt);
+	mctl->media_pad.flags = MEDIA_PAD_FL_SINK;
+	media_entity_init(&mctl->media_entity, 1, &mctl->media_pad, 0);
+	media_device_register_entity(mctl->media_dev, &mctl->media_entity);
+}
+
+void media_stream_delete(struct snd_usb_substream *subs)
+{
+	struct media_ctl *mctl = (struct media_ctl *) subs->media_ctl;
+
+	if (mctl && mctl->media_dev) {
+		struct media_device *mdev;
+
+		mdev = media_device_find_devres(&subs->dev->dev);
+		if (mdev) {
+			media_entity_remove_links(&mctl->media_entity);
+			media_device_unregister_entity(&mctl->media_entity);
+			media_entity_cleanup(&mctl->media_entity);
+			media_device_unregister_entity_notify(mctl->media_dev,
+							&mctl->entity_notify);
+		}
+		mctl->media_dev = NULL;
+		mctl->decoder_linked = 0;
+		mctl->decoder = NULL;
+		mctl->tuner_enabled = 0;
+		kfree(mctl);
+		subs->media_ctl = NULL;
+	}
+}
+
+int media_start_pipeline(struct snd_usb_substream *subs)
+{
+	struct media_ctl *mctl = (struct media_ctl *) subs->media_ctl;
+	int ret;
+
+	if (!mctl)
+		return 0;
+
+	ret = media_enable_tuner(mctl);
+	if (ret)
+		return ret;
+	ret = media_entity_pipeline_start_irq(&mctl->media_entity,
+						&mctl->media_pipe);
+	return ret;
+}
+
+void media_stop_pipeline(struct snd_usb_substream *subs)
+{
+	struct media_ctl *mctl = (struct media_ctl *) subs->media_ctl;
+
+	if (mctl && mctl->decoder_linked && mctl->tuner_enabled)
+		media_entity_pipeline_stop_irq(&mctl->media_entity);
+}
+#endif
diff --git a/sound/usb/media.h b/sound/usb/media.h
new file mode 100644
index 0000000..07799b4
--- /dev/null
+++ b/sound/usb/media.h
@@ -0,0 +1,52 @@
+/*
+ * media.h - Media Controller specific ALSA driver code
+ *
+ * Copyright (c) 2015 Shuah Khan <shuahkh@osg.samsung.com>
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * This file is released under the GPLv2.
+ */
+
+/*
+ * This file adds Media Controller support to ALSA driver
+ * to use the Media Controller API to share tuner with DVB
+ * and V4L2 drivers that control media device. Media device
+ * is created based on existing quirks framework. Using this
+ * approach, the media controller API usage can be added for
+ * a specific device.
+*/
+#ifndef __MEDIA_H
+
+#ifdef USE_MEDIA_CONTROLLER
+#include <media/media-device.h>
+#include <media/media-entity.h>
+
+struct media_ctl {
+	struct media_device *media_dev;
+	struct media_entity_notify entity_notify;
+	struct media_entity media_entity;
+	struct media_pad media_pad;
+	struct media_pipeline media_pipe;
+	struct media_entity *decoder;
+	bool   decoder_linked;
+	bool   tuner_enabled;
+};
+
+int media_device_init(struct usb_interface *iface);
+void media_device_delete(struct usb_interface *iface);
+void media_stream_init(struct snd_usb_substream *subs, struct snd_pcm *pcm,
+			int stream);
+void media_stream_delete(struct snd_usb_substream *subs);
+int media_start_pipeline(struct snd_usb_substream *subs);
+void media_stop_pipeline(struct snd_usb_substream *subs);
+#else
+static inline int media_device_init(struct usb_interface *iface) { return 0; }
+static inline void media_device_delete(struct usb_interface *iface) { }
+static inline void media_stream_init(struct snd_usb_substream *subs,
+					struct snd_pcm *pcm, int stream) { }
+static inline void media_stream_delete(struct snd_usb_substream *subs) { }
+static inline int media_start_pipeline(struct snd_usb_substream *subs)
+					{ return 0; }
+static inline void media_stop_pipeline(struct snd_usb_substream *subs) { }
+#endif
+#endif /* __MEDIA_H */
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index b4ef410..0e73a3a 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -35,6 +35,7 @@
 #include "pcm.h"
 #include "clock.h"
 #include "power.h"
+#include "media.h"
 
 #define SUBSTREAM_FLAG_DATA_EP_STARTED	0
 #define SUBSTREAM_FLAG_SYNC_EP_STARTED	1
@@ -1195,6 +1196,7 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction)
 	struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_usb_substream *subs = &as->substream[direction];
+	int ret;
 
 	subs->interface = -1;
 	subs->altset_idx = 0;
@@ -1208,7 +1210,10 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction)
 	subs->dsd_dop.channel = 0;
 	subs->dsd_dop.marker = 1;
 
-	return setup_hw_info(runtime, subs);
+	ret = setup_hw_info(runtime, subs);
+	if (ret == 0)
+		media_stream_init(subs, as->pcm, direction);
+	return ret;
 }
 
 static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction)
@@ -1587,9 +1592,14 @@ static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
+		err = media_start_pipeline(subs);
+		if (err)
+			return err;
 		err = start_endpoints(subs, false);
-		if (err < 0)
+		if (err < 0) {
+			media_stop_pipeline(subs);
 			return err;
+		}
 
 		subs->data_endpoint->retire_data_urb = retire_capture_urb;
 		subs->running = 1;
@@ -1597,6 +1607,7 @@ static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream
 	case SNDRV_PCM_TRIGGER_STOP:
 		stop_endpoints(subs, false);
 		subs->running = 0;
+		media_stop_pipeline(subs);
 		return 0;
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 		subs->data_endpoint->retire_data_urb = NULL;
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index 2f6d3e9..51c544f 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -2798,6 +2798,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 		.product_name = pname, \
 		.ifnum = QUIRK_ANY_INTERFACE, \
 		.type = QUIRK_AUDIO_ALIGN_TRANSFER, \
+		.media_device = 1, \
 	} \
 }
 
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 7c5a701..e9a2009 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -36,6 +36,7 @@
 #include "pcm.h"
 #include "clock.h"
 #include "stream.h"
+#include "media.h"
 
 /*
  * handle the quirks for the contained interfaces
@@ -541,13 +542,19 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip,
 		[QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk,
 		[QUIRK_AUDIO_STANDARD_MIXER] = create_standard_mixer_quirk,
 	};
+	int ret;
 
+	if (quirk->media_device) {
+		/* don't want to fail when media_device_init() doesn't work */
+		media_device_init(iface);
+	}
 	if (quirk->type < QUIRK_TYPE_COUNT) {
-		return quirk_funcs[quirk->type](chip, iface, driver, quirk);
+		ret = quirk_funcs[quirk->type](chip, iface, driver, quirk);
 	} else {
 		usb_audio_err(chip, "invalid quirk type %d\n", quirk->type);
 		return -ENXIO;
 	}
+	return ret;
 }
 
 /*
diff --git a/sound/usb/stream.c b/sound/usb/stream.c
index 310a382..6d01c47 100644
--- a/sound/usb/stream.c
+++ b/sound/usb/stream.c
@@ -36,6 +36,7 @@
 #include "format.h"
 #include "clock.h"
 #include "stream.h"
+#include "media.h"
 
 /*
  * free a substream
@@ -52,6 +53,7 @@ static void free_substream(struct snd_usb_substream *subs)
 		kfree(fp);
 	}
 	kfree(subs->rate_list.list);
+	media_stream_delete(subs);
 }
 
 
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 91d0380..c2dbf1d 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -108,6 +108,7 @@ struct snd_usb_audio_quirk {
 	const char *product_name;
 	int16_t ifnum;
 	uint16_t type;
+	bool media_device;
 	const void *data;
 };
 
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH v2 00/19] Update ALSA, and au0828 drivers to use Managed Media Controller API
  2015-07-22 22:42 [PATCH v2 00/19] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (18 preceding siblings ...)
  2015-07-22 22:42 ` [PATCH v2 19/19] sound/usb: Update ALSA driver " Shuah Khan
@ 2015-07-23 18:13 ` Shuah Khan
  19 siblings, 0 replies; 21+ messages in thread
From: Shuah Khan @ 2015-07-23 18:13 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, tiwai, sakari.ailus,
	perex, crope, arnd, stefanr, ruchandani.tina, chehabrafael,
	dan.carpenter, prabhakar.csengg, chris.j.arges, agoode,
	pierre-louis.bossart, gtmkramer, clemens, daniel, vladcatoi,
	misterpib, damien, pmatilai, takamichiho, normalperson,
	bugzilla.frnkcg, joe, calcprogrammer1, jussi, kyungmin.park,
	s.nawrocki, kgene, hyun.kwon, michal.simek, soren.brinkmann,
	pawel, m.szyprowski, gregkh, skd08, nsekhar, boris.brezillon,
	Julia.Lawall, elfring, p.zabel, ricardo.ribalda
  Cc: linux-media, alsa-devel, linux-samsung-soc, linux-arm-kernel,
	devel, Shuah Khan

On 07/22/2015 04:42 PM, Shuah Khan wrote:
> This patch series updates ALSA driver, and au0828 core driver to
> use Managed Media controller API to share tuner. Please note that
> Managed Media Controller API and DVB and V4L2 drivers updates to
> use Media Controller API have been added in a prior patch series.
> 
> Media Controller API is enhanced with two new interfaces to
> register and unregister entity_notify hooks to allow drivers
> to take appropriate actions when as new entities get added to
> the shared media device.
> 
> Tested exclusion between digital, analog, and audio to ensure
> when tuner has an active link to DVB FE, analog, and audio will
> detect and honor the tuner busy conditions and vice versa.
> 
> Changes since v1:
> Link to v1: http://www.spinics.net/lists/linux-media/msg91697.html

I uploaded this patch series to my linux.git media_controller branch
on kernel.org:

git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux.git
media_controller branch

thanks,
-- Shuah

-- 
Shuah Khan
Sr. Linux Kernel Developer
Open Source Innovation Group
Samsung Research America (Silicon Valley)
shuahkh@osg.samsung.com | (970) 217-8978

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2015-07-23 18:13 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-22 22:42 [PATCH v2 00/19] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
2015-07-22 22:42 ` [PATCH v2 01/19] Revert "[media] media: media controller entity framework enhancements for ALSA" Shuah Khan
2015-07-22 22:42 ` [PATCH v2 02/19] media: Media Controller register/unregister entity_notify API Shuah Khan
2015-07-22 22:42 ` [PATCH v2 03/19] media: Add ALSA Media Controller devnodes Shuah Khan
2015-07-22 22:42 ` [PATCH v2 04/19] media: au8522 change to create MC pad for ALSA Audio Out Shuah Khan
2015-07-22 22:42 ` [PATCH v2 05/19] media: Convert graph_mutex to a spinlock and call it graph_lock Shuah Khan
2015-07-22 22:42 ` [PATCH v2 06/19] media: platform exynos4-is: Update graph_mutex to graph_lock spinlock Shuah Khan
2015-07-22 22:42 ` [PATCH v2 07/19] media: platform omap3isp: " Shuah Khan
2015-07-22 22:42 ` [PATCH v2 08/19] media: platform s3c-camif: " Shuah Khan
2015-07-22 22:42 ` [PATCH v2 09/19] media: platform vsp1: " Shuah Khan
2015-07-22 22:42 ` [PATCH v2 10/19] media: platform xilinx: " Shuah Khan
2015-07-22 22:42 ` [PATCH v2 11/19] staging media: davinci_vpfe: " Shuah Khan
2015-07-22 22:42 ` [PATCH v2 12/19] staging media: omap4iss: " Shuah Khan
2015-07-22 22:42 ` [PATCH v2 13/19] media: Add irq safe Media Controller start/stop pipeline API Shuah Khan
2015-07-22 22:42 ` [PATCH v2 14/19] media: Add enable_source handler field to struct media_device Shuah Khan
2015-07-22 22:42 ` [PATCH v2 15/19] media: v4l-core add v4l_enable_media_tuner() to check for tuner availability Shuah Khan
2015-07-22 22:42 ` [PATCH v2 16/19] media: Change v4l-core " Shuah Khan
2015-07-22 22:42 ` [PATCH v2 17/19] media: dvb-frontend change to check for tuner availability from open Shuah Khan
2015-07-22 22:42 ` [PATCH v2 18/19] media: au0828 change to use Managed Media Controller API Shuah Khan
2015-07-22 22:42 ` [PATCH v2 19/19] sound/usb: Update ALSA driver " Shuah Khan
2015-07-23 18:13 ` [PATCH v2 00/19] Update ALSA, and au0828 drivers " Shuah Khan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).