linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers
@ 2016-01-06 20:26 Shuah Khan
  2016-01-06 20:26 ` [PATCH 01/31] uapi/media.h: Declare interface types for ALSA Shuah Khan
                   ` (30 more replies)
  0 siblings, 31 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:26 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

This patch series updates ALSA driver, and au0828 core
driver to use Managed Media controller API and Media
Controller API to share tuner.

Media Controller Next Generation API has been enhanced
to add 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.

Mauro and Takashi: I am hoping you can both coordinate
and decide on ALSA patches once the reviews are done
and the patches look good.

Design Highlights:
1. ALSA to check for resources and hold in snd_usb_hw_params(),
   and release from snd_usb_hw_free(). This change fixed the
   lockdep warnings seen when resources were held in
   TRIGGER_START and released from TRIGGER_STOP which could
   run in IRQ context. I acknowledge Clemens Ladisch for
   suggesting the correct places to hold/free resources to
   avoid IRQ path complications.
2. The Bridge driver (au0828) owns and drives the graph creation
   as well as enabling and disabling tuner. It also keeps state
   information to avoid graph walks in enable_source and
   disable_source handler. I acknowledge Hans Verkuil for his
   suggestions and ideas for this change.

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.

Please find the graphs generated using mc_nextgen_test tool at
various points during testing at:
https://drive.google.com/folderview?id=0B0NIL0BQg-AlRndaaXViSXdPeTA&usp=sharing

This patch series is a rebase and update to the latest Media
Controller Next Gen API of the Media Controller Next Generation
API port.

Rebase highlights:
1. Changes to videobuf2 framework required additional
   v4l2 helper function to enable the tuner from
   vb2_core_streamon(). Patch 9 has this work.
2. Media device initialization and registration steps
   are now split in the latest Media Controller Next Gen
   API. This required changes to au0828 and ALSA to coordinate
   initialization and registration of the Managed Media Device
   they share. Patch 19 shows au0828 changes. ALSA changes
   for this are folded into the main ALSA patch 26.
3. Media device unregistration does more cleanup now. As a
   result, au0828 and ALSA need to coordinate so media device
   is done only once. These changes are in patches: 29, 30,
   and 31.
4. In addition, media device resources cleanup gets done
   before snd_card_disconnect(). This work is in patch 30.

Media Controller Next Generation API port from Media Controller API:
The patch series below was a port of the Patch v3 - Media Controller API
to Next Gen API and Mixer patch update to address comments and bug fixes:
https://www.mail-archive.com/linux-media@vger.kernel.org/msg93086.html
https://www.mail-archive.com/linux-media@vger.kernel.org/msg93417.html

Patch v3 - Media Controller API:
https://www.mail-archive.com/linux-media@vger.kernel.org/msg92572.html

Mauro Carvalho Chehab (1):
  uapi/media.h: Declare interface types for ALSA

Shuah Khan (30):
  media: Add ALSA Media Controller function entities
  media: Media Controller register/unregister entity_notify API
  media: Media Controller enable/disable source handler API
  media: Media Controller fix to not let stream_count go negative
  media: Media Controller export non locking __media_entity_setup_link()
  media: Media Controller non-locking
    __media_entity_pipeline_start/stop()
  media: v4l-core add v4l_enable/disable_media_tuner() helper functions
  media: v4l2-core add v4l_vb2q_enable_media_tuner() helper
  media: Move au8522_media_pads enum to au8522.h from au8522_priv.h
  media: au8522 change to create MC pad for ALSA Audio Out
  media: au0828 Use au8522_media_pads enum for pad defines
  media: au0828 fix au0828_create_media_graph() entity checks
  media: Change v4l-core to check for tuner availability
  media: dvb-frontend invoke enable/disable_source handlers
  media: au0828 video remove au0828_enable_analog_tuner()
  media: au0828 video change to use v4l_enable_media_tuner()
  media: au0828 change to use Managed Media Controller API
  media: au0828 handle media_init and media_register window
  media: au0828 change to register/unregister entity_notify hook
  media: au0828 create tuner to decoder link in deactivated state
  media: dvb-core create tuner to demod pad link in disabled state
  media: au0828 implement enable_source and disable_source handlers
  media: au0828 fix null pointer reference in
    au0828_create_media_graph()
  media: au0828 fix to not call media_device_unregister_entity_notify()
  sound/usb: Update ALSA driver to use Managed Media Controller API
  sound/usb: Create media mixer function and control interface entities
  media: au0828 create link between ALSA Mixer and decoder
  media: track media device unregister in progress
  sound/usb: Check media device unregister progress state
  media: au0828 change to check media device unregister progress state

 drivers/media/dvb-core/dvb_frontend.c        | 139 ++---------
 drivers/media/dvb-core/dvb_frontend.h        |   3 +
 drivers/media/dvb-core/dvbdev.c              |   3 +-
 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                 |  66 ++++-
 drivers/media/media-entity.c                 |  65 +++--
 drivers/media/usb/au0828/au0828-core.c       | 355 ++++++++++++++++++++++-----
 drivers/media/usb/au0828/au0828-video.c      |  75 +-----
 drivers/media/usb/au0828/au0828.h            |   9 +
 drivers/media/v4l2-core/v4l2-dev.c           |  48 ++++
 drivers/media/v4l2-core/v4l2-fh.c            |   1 +
 drivers/media/v4l2-core/v4l2-ioctl.c         |  29 +++
 drivers/media/v4l2-core/videobuf2-core.c     |   4 +
 include/media/media-device.h                 |  61 +++++
 include/media/media-entity.h                 |  12 +
 include/media/v4l2-dev.h                     |   5 +
 include/uapi/linux/media.h                   |  17 +-
 sound/usb/Makefile                           |  15 +-
 sound/usb/card.c                             |  16 ++
 sound/usb/card.h                             |   1 +
 sound/usb/media.c                            | 325 ++++++++++++++++++++++++
 sound/usb/media.h                            |  75 ++++++
 sound/usb/mixer.h                            |   1 +
 sound/usb/pcm.c                              |  26 +-
 sound/usb/quirks-table.h                     |   1 +
 sound/usb/quirks.c                           |   9 +-
 sound/usb/stream.c                           |   1 +
 sound/usb/usbaudio.h                         |   2 +
 30 files changed, 1111 insertions(+), 270 deletions(-)
 create mode 100644 sound/usb/media.c
 create mode 100644 sound/usb/media.h

-- 
2.5.0


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

* [PATCH 01/31] uapi/media.h: Declare interface types for ALSA
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
@ 2016-01-06 20:26 ` Shuah Khan
  2016-01-28 14:59   ` Mauro Carvalho Chehab
  2016-01-06 20:26 ` [PATCH 02/31] media: Add ALSA Media Controller function entities Shuah Khan
                   ` (29 subsequent siblings)
  30 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:26 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: pawel, m.szyprowski, kyungmin.park, perex, arnd, dan.carpenter,
	tvboxspy, crope, ruchandani.tina, corbet, chehabrafael,
	k.kozlowski, stefanr, inki.dae, jh1009.sung, elfring,
	prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda, labbott,
	pierre-louis.bossart, ricard.wanderlof, julian, takamichiho,
	dominic.sacre, misterpib, daniel, gtmkramer, normalperson, joe,
	linuxbugs, johan, linux-kernel, linux-media, linux-api,
	alsa-devel

From: Mauro Carvalho Chehab <mchehab@osg.samsung.com>

Declare the interface types to be used on alsa for the new
G_TOPOLOGY ioctl.

Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
---
 drivers/media/media-entity.c | 12 ++++++++++++
 include/uapi/linux/media.h   |  8 ++++++++
 2 files changed, 20 insertions(+)

diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index eb38bc3..6e02d19 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -65,6 +65,18 @@ static inline const char *intf_type(struct media_interface *intf)
 		return "v4l2-subdev";
 	case MEDIA_INTF_T_V4L_SWRADIO:
 		return "swradio";
+	case MEDIA_INTF_T_ALSA_PCM_CAPTURE:
+		return "pcm-capture";
+	case MEDIA_INTF_T_ALSA_PCM_PLAYBACK:
+		return "pcm-playback";
+	case MEDIA_INTF_T_ALSA_CONTROL:
+		return "alsa-control";
+	case MEDIA_INTF_T_ALSA_COMPRESS:
+		return "compress";
+	case MEDIA_INTF_T_ALSA_RAWMIDI:
+		return "rawmidi";
+	case MEDIA_INTF_T_ALSA_HWDEP:
+		return "hwdep";
 	default:
 		return "unknown-intf";
 	}
diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h
index cacfceb..75cbe92 100644
--- a/include/uapi/linux/media.h
+++ b/include/uapi/linux/media.h
@@ -252,6 +252,7 @@ struct media_links_enum {
 
 #define MEDIA_INTF_T_DVB_BASE	0x00000100
 #define MEDIA_INTF_T_V4L_BASE	0x00000200
+#define MEDIA_INTF_T_ALSA_BASE	0x00000300
 
 /* Interface types */
 
@@ -267,6 +268,13 @@ struct media_links_enum {
 #define MEDIA_INTF_T_V4L_SUBDEV (MEDIA_INTF_T_V4L_BASE + 3)
 #define MEDIA_INTF_T_V4L_SWRADIO (MEDIA_INTF_T_V4L_BASE + 4)
 
+#define MEDIA_INTF_T_ALSA_PCM_CAPTURE   (MEDIA_INTF_T_ALSA_BASE)
+#define MEDIA_INTF_T_ALSA_PCM_PLAYBACK  (MEDIA_INTF_T_ALSA_BASE + 1)
+#define MEDIA_INTF_T_ALSA_CONTROL       (MEDIA_INTF_T_ALSA_BASE + 2)
+#define MEDIA_INTF_T_ALSA_COMPRESS      (MEDIA_INTF_T_ALSA_BASE + 3)
+#define MEDIA_INTF_T_ALSA_RAWMIDI       (MEDIA_INTF_T_ALSA_BASE + 4)
+#define MEDIA_INTF_T_ALSA_HWDEP         (MEDIA_INTF_T_ALSA_BASE + 5)
+
 /*
  * MC next gen API definitions
  *
-- 
2.5.0


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

* [PATCH 02/31] media: Add ALSA Media Controller function entities
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
  2016-01-06 20:26 ` [PATCH 01/31] uapi/media.h: Declare interface types for ALSA Shuah Khan
@ 2016-01-06 20:26 ` Shuah Khan
  2016-01-28 15:02   ` Mauro Carvalho Chehab
  2016-01-06 20:26 ` [PATCH 03/31] media: Media Controller register/unregister entity_notify API Shuah Khan
                   ` (28 subsequent siblings)
  30 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:26 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Add ALSA Media Controller capture, playback, and mixer
function entity defines.

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

diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h
index 75cbe92..53a96ae 100644
--- a/include/uapi/linux/media.h
+++ b/include/uapi/linux/media.h
@@ -89,6 +89,13 @@ struct media_device_info {
 #define MEDIA_ENT_F_IO_SWRADIO		(MEDIA_ENT_F_BASE + 33)
 
 /*
+ * ALSA entities MEDIA_ENT_F_AUDIO_IO is for Capture and Playback
+*/
+#define MEDIA_ENT_F_AUDIO_CAPTURE	(MEDIA_ENT_F_BASE + 200)
+#define MEDIA_ENT_F_AUDIO_PLAYBACK	(MEDIA_ENT_F_BASE + 201)
+#define MEDIA_ENT_F_AUDIO_MIXER		(MEDIA_ENT_F_BASE + 202)
+
+/*
  * Don't touch on those. The ranges MEDIA_ENT_F_OLD_BASE and
  * MEDIA_ENT_F_OLD_SUBDEV_BASE are kept to keep backward compatibility
  * with the legacy v1 API.The number range is out of range by purpose:
@@ -130,7 +137,7 @@ struct media_device_info {
 #define MEDIA_ENT_T_DEVNODE		MEDIA_ENT_F_OLD_BASE
 #define MEDIA_ENT_T_DEVNODE_V4L		MEDIA_ENT_F_IO_V4L
 #define MEDIA_ENT_T_DEVNODE_FB		(MEDIA_ENT_T_DEVNODE + 2)
-#define MEDIA_ENT_T_DEVNODE_ALSA	(MEDIA_ENT_T_DEVNODE + 3)
+#define MEDIA_ENT_T_DEVNODE_ALSA	MEDIA_ENT_F_AUDIO_IO
 #define MEDIA_ENT_T_DEVNODE_DVB		(MEDIA_ENT_T_DEVNODE + 4)
 
 #define MEDIA_ENT_T_UNKNOWN		MEDIA_ENT_F_UNKNOWN
-- 
2.5.0


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

* [PATCH 03/31] media: Media Controller register/unregister entity_notify API
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
  2016-01-06 20:26 ` [PATCH 01/31] uapi/media.h: Declare interface types for ALSA Shuah Khan
  2016-01-06 20:26 ` [PATCH 02/31] media: Add ALSA Media Controller function entities Shuah Khan
@ 2016-01-06 20:26 ` Shuah Khan
  2016-01-28 15:13   ` Mauro Carvalho Chehab
  2016-01-06 20:26 ` [PATCH 04/31] media: Media Controller enable/disable source handler API Shuah Khan
                   ` (27 subsequent siblings)
  30 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:26 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-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 | 61 ++++++++++++++++++++++++++++++++++++++++++++
 include/media/media-device.h | 25 ++++++++++++++++++
 2 files changed, 86 insertions(+)

diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index b786b10..20c85a9 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -536,6 +536,7 @@ static void media_device_release(struct media_devnode *mdev)
 int __must_check media_device_register_entity(struct media_device *mdev,
 					      struct media_entity *entity)
 {
+	struct media_entity_notify *notify, *next;
 	unsigned int i;
 	int ret;
 
@@ -575,6 +576,11 @@ int __must_check media_device_register_entity(struct media_device *mdev,
 		media_gobj_create(mdev, MEDIA_GRAPH_PAD,
 			       &entity->pads[i].graph_obj);
 
+	/* invoke entity_notify callbacks */
+	list_for_each_entry_safe(notify, next, &mdev->entity_notify, list) {
+		(notify)->notify(entity, notify->notify_data);
+	}
+
 	spin_unlock(&mdev->lock);
 
 	return 0;
@@ -608,6 +614,8 @@ static void __media_device_unregister_entity(struct media_entity *entity)
 	/* Remove the entity */
 	media_gobj_destroy(&entity->graph_obj);
 
+	/* invoke entity_notify callbacks to handle entity removal?? */
+
 	entity->graph_obj.mdev = NULL;
 }
 
@@ -633,6 +641,7 @@ int __must_check media_device_init(struct media_device *mdev)
 	INIT_LIST_HEAD(&mdev->interfaces);
 	INIT_LIST_HEAD(&mdev->pads);
 	INIT_LIST_HEAD(&mdev->links);
+	INIT_LIST_HEAD(&mdev->entity_notify);
 	spin_lock_init(&mdev->lock);
 	mutex_init(&mdev->graph_mutex);
 	ida_init(&mdev->entity_internal_idx);
@@ -680,11 +689,59 @@ int __must_check __media_device_register(struct media_device *mdev,
 }
 EXPORT_SYMBOL_GPL(__media_device_register);
 
+/**
+ * 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
+ * Non-locking version. Should be called with mdev->lock held.
+ */
+static void __media_device_unregister_entity_notify(struct media_device *mdev,
+					struct media_entity_notify *nptr)
+{
+	list_del(&nptr->list);
+}
+
+/**
+ * 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);
+	__media_device_unregister_entity_notify(mdev, nptr);
+	spin_unlock(&mdev->lock);
+}
+EXPORT_SYMBOL_GPL(media_device_unregister_entity_notify);
+
 void media_device_unregister(struct media_device *mdev)
 {
 	struct media_entity *entity;
 	struct media_entity *next;
 	struct media_interface *intf, *tmp_intf;
+	struct media_entity_notify *notify, *nextp;
 
 	if (mdev == NULL)
 		return;
@@ -701,6 +758,10 @@ void media_device_unregister(struct media_device *mdev)
 	list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list)
 		__media_device_unregister_entity(entity);
 
+	/* Remove all entity_notify callbacks from the media device */
+	list_for_each_entry_safe(notify, nextp, &mdev->entity_notify, list)
+		__media_device_unregister_entity_notify(mdev, notify);
+
 	/* Remove all interfaces from the media device */
 	list_for_each_entry_safe(intf, tmp_intf, &mdev->interfaces,
 				 graph_obj.list) {
diff --git a/include/media/media-device.h b/include/media/media-device.h
index 122963a..6520d1c 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -264,6 +264,12 @@
 struct ida;
 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
@@ -319,6 +325,9 @@ struct media_device {
 	struct list_head pads;
 	struct list_head links;
 
+	/* notify callback list invoked when a new entity is registered */
+	struct list_head entity_notify;
+
 	/* Protects the graph objects creation/removal */
 	spinlock_t lock;
 	/* Serializes graph operations. */
@@ -497,6 +506,11 @@ int __must_check media_device_register_entity(struct media_device *mdev,
  */
 void media_device_unregister_entity(struct media_entity *entity);
 
+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);
+
 /**
  * media_device_get_devres() -	get media device as device resource
  *				creates if one doesn't exist
@@ -552,6 +566,17 @@ static inline int media_device_register_entity(struct media_device *mdev,
 static inline void media_device_unregister_entity(struct media_entity *entity)
 {
 }
+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 struct media_device *media_device_get_devres(struct device *dev)
 {
 	return NULL;
-- 
2.5.0


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

* [PATCH 04/31] media: Media Controller enable/disable source handler API
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (2 preceding siblings ...)
  2016-01-06 20:26 ` [PATCH 03/31] media: Media Controller register/unregister entity_notify API Shuah Khan
@ 2016-01-06 20:26 ` Shuah Khan
  2016-01-28 15:19   ` Mauro Carvalho Chehab
  2016-01-06 20:26 ` [PATCH 05/31] media: Media Controller fix to not let stream_count go negative Shuah Khan
                   ` (26 subsequent siblings)
  30 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:26 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Add new fields to struct media_device to add enable_source, and
disable_source handlers, and source_priv to stash driver private
data that is need to run these handlers. The enable_source handler
finds source entity for the passed in 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 these
handlers and private data 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 it and start pipeline between
the source and the entity. The disable_source handler deactivates the
link and stops the pipeline. This handler can be invoked from the
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 | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/include/media/media-device.h b/include/media/media-device.h
index 6520d1c..04b6c2e 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -333,6 +333,25 @@ struct media_device {
 	/* Serializes graph operations. */
 	struct mutex graph_mutex;
 
+	/* Handlers to find source entity for the sink entity and
+	 * check if it is available, and activate the link using
+	 * media_entity_setup_link() interface and start pipeline
+	 * from the source to the entity.
+	 * 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.
+	 * Bridge driver sets source_priv with information
+	 * necessary to run enable/disable source handlers.
+	 *
+	 * 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.
+	*/
+	void *source_priv;
+	int (*enable_source)(struct media_entity *entity,
+			     struct media_pipeline *pipe);
+	void (*disable_source)(struct media_entity *entity);
+
 	int (*link_notify)(struct media_link *link, u32 flags,
 			   unsigned int notification);
 };
-- 
2.5.0


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

* [PATCH 05/31] media: Media Controller fix to not let stream_count go negative
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (3 preceding siblings ...)
  2016-01-06 20:26 ` [PATCH 04/31] media: Media Controller enable/disable source handler API Shuah Khan
@ 2016-01-06 20:26 ` Shuah Khan
  2016-01-06 20:26 ` [PATCH 06/31] media: Media Controller export non locking __media_entity_setup_link() Shuah Khan
                   ` (25 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:26 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Add a range check to not let the stream_count become negative.
Wthout this check, calls to stop pipeline when there is no active
pipeline will result in stream_count < 0 condition and lock and
preventing link state (activate/deactivate) changes. This will
happen from error leg in start pipeline interface.

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

diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 6e02d19..78486a9 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -464,9 +464,12 @@ error:
 	media_entity_graph_walk_start(graph, entity_err);
 
 	while ((entity_err = media_entity_graph_walk_next(graph))) {
-		entity_err->stream_count--;
-		if (entity_err->stream_count == 0)
-			entity_err->pipe = NULL;
+		/* don't let the stream_count go negative */
+		if (entity->stream_count > 0) {
+			entity_err->stream_count--;
+			if (entity_err->stream_count == 0)
+				entity_err->pipe = NULL;
+		}
 
 		/*
 		 * We haven't increased stream_count further than this
@@ -498,9 +501,12 @@ void media_entity_pipeline_stop(struct media_entity *entity)
 	media_entity_graph_walk_start(graph, entity);
 
 	while ((entity = media_entity_graph_walk_next(graph))) {
-		entity->stream_count--;
-		if (entity->stream_count == 0)
-			entity->pipe = NULL;
+		/* don't let the stream_count go negative */
+		if (entity->stream_count > 0) {
+			entity->stream_count--;
+			if (entity->stream_count == 0)
+				entity->pipe = NULL;
+		}
 	}
 
 	if (!--pipe->streaming_count)
-- 
2.5.0


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

* [PATCH 06/31] media: Media Controller export non locking __media_entity_setup_link()
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (4 preceding siblings ...)
  2016-01-06 20:26 ` [PATCH 05/31] media: Media Controller fix to not let stream_count go negative Shuah Khan
@ 2016-01-06 20:26 ` Shuah Khan
  2016-01-06 20:26 ` [PATCH 07/31] media: Media Controller non-locking __media_entity_pipeline_start/stop() Shuah Khan
                   ` (24 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:26 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Export __media_entity_setup_link() to be used from code paths that hold
the graph_mutex.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/media-entity.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 78486a9..b8769aa 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -736,6 +736,7 @@ int __media_entity_setup_link(struct media_link *link, u32 flags)
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(__media_entity_setup_link);
 
 int media_entity_setup_link(struct media_link *link, u32 flags)
 {
-- 
2.5.0


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

* [PATCH 07/31] media: Media Controller non-locking __media_entity_pipeline_start/stop()
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (5 preceding siblings ...)
  2016-01-06 20:26 ` [PATCH 06/31] media: Media Controller export non locking __media_entity_setup_link() Shuah Khan
@ 2016-01-06 20:26 ` Shuah Khan
  2016-01-06 20:26 ` [PATCH 08/31] media: v4l-core add v4l_enable/disable_media_tuner() helper functions Shuah Khan
                   ` (23 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:26 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Add non-locking __media_entity_pipeline_start/stop() interfaces
to be called from code paths that hold the graph_mutex. For this
change, the media_entity_pipeline_start() routine is renamed to
__media_entity_pipeline_start() minus the graph_mutex lock and
unlock. media_entity_pipeline_start() now calls the non-locking
__media_entity_pipeline_start() holding the graph_lock. The stop
interface, media_entity_pipeline_stop() routine is renamed to
__media_entity_pipeline_stop() minus the graph_mutex lock and
unlock. media_entity_pipeline_stop() now calls the non-locking
__media_entity_pipeline_stop() holding the graph_lock.

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

diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index b8769aa..270ade2 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -361,8 +361,8 @@ EXPORT_SYMBOL_GPL(media_entity_graph_walk_next);
  * Pipeline management
  */
 
-__must_check int media_entity_pipeline_start(struct media_entity *entity,
-					     struct media_pipeline *pipe)
+__must_check int __media_entity_pipeline_start(struct media_entity *entity,
+					       struct media_pipeline *pipe)
 {
 	struct media_device *mdev = entity->graph_obj.mdev;
 	struct media_entity_graph *graph = &pipe->graph;
@@ -370,8 +370,6 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
 	struct media_link *link;
 	int ret;
 
-	mutex_lock(&mdev->graph_mutex);
-
 	if (!pipe->streaming_count++) {
 		ret = media_entity_graph_walk_init(&pipe->graph, mdev);
 		if (ret)
@@ -452,8 +450,6 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
 		}
 	}
 
-	mutex_unlock(&mdev->graph_mutex);
-
 	return 0;
 
 error:
@@ -483,19 +479,28 @@ error_graph_walk_start:
 	if (!--pipe->streaming_count)
 		media_entity_graph_walk_cleanup(graph);
 
-	mutex_unlock(&mdev->graph_mutex);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(__media_entity_pipeline_start);
 
+__must_check int media_entity_pipeline_start(struct media_entity *entity,
+					     struct media_pipeline *pipe)
+{
+	struct media_device *mdev = entity->graph_obj.mdev;
+	int ret;
+
+	mutex_lock(&mdev->graph_mutex);
+	ret = __media_entity_pipeline_start(entity, pipe);
+	mutex_unlock(&mdev->graph_mutex);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(media_entity_pipeline_start);
 
-void media_entity_pipeline_stop(struct media_entity *entity)
+void __media_entity_pipeline_stop(struct media_entity *entity)
 {
-	struct media_device *mdev = entity->graph_obj.mdev;
 	struct media_entity_graph *graph = &entity->pipe->graph;
 	struct media_pipeline *pipe = entity->pipe;
 
-	mutex_lock(&mdev->graph_mutex);
 
 	WARN_ON(!pipe->streaming_count);
 	media_entity_graph_walk_start(graph, entity);
@@ -512,6 +517,15 @@ void media_entity_pipeline_stop(struct media_entity *entity)
 	if (!--pipe->streaming_count)
 		media_entity_graph_walk_cleanup(graph);
 
+}
+EXPORT_SYMBOL_GPL(__media_entity_pipeline_stop);
+
+void media_entity_pipeline_stop(struct media_entity *entity)
+{
+	struct media_device *mdev = entity->graph_obj.mdev;
+
+	mutex_lock(&mdev->graph_mutex);
+	__media_entity_pipeline_stop(entity);
 	mutex_unlock(&mdev->graph_mutex);
 }
 EXPORT_SYMBOL_GPL(media_entity_pipeline_stop);
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index 79dd81f..3f4f577 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -781,6 +781,12 @@ 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);
+/**
+ * non-locking __media_entity_pipeline_start() can be called from
+ * code paths that hold the graph_mutex
+ */
+__must_check int __media_entity_pipeline_start(struct media_entity *entity,
+					       struct media_pipeline *pipe);
 
 /**
  * media_entity_pipeline_stop - Mark a pipeline as not streaming
@@ -797,6 +803,12 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
 void media_entity_pipeline_stop(struct media_entity *entity);
 
 /**
+ * non-locking __media_entity_pipeline_stop() can be called from
+ * code paths that hold the graph_mutex
+ */
+void __media_entity_pipeline_stop(struct media_entity *entity);
+
+/**
  * media_devnode_create() - creates and initializes a device node interface
  *
  * @mdev:	pointer to struct &media_device
-- 
2.5.0


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

* [PATCH 08/31] media: v4l-core add v4l_enable/disable_media_tuner() helper functions
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (6 preceding siblings ...)
  2016-01-06 20:26 ` [PATCH 07/31] media: Media Controller non-locking __media_entity_pipeline_start/stop() Shuah Khan
@ 2016-01-06 20:26 ` Shuah Khan
  2016-01-28 15:26   ` Mauro Carvalho Chehab
  2016-01-06 20:26 ` [PATCH 09/31] media: v4l2-core add v4l_vb2q_enable_media_tuner() helper Shuah Khan
                   ` (22 subsequent siblings)
  30 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:26 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Add a new interfaces to be used by v4l-core to invoke enable
source and disable_source handlers in the media_device. The
enable_source helper function invokes the enable_source handler
to find tuner entity connected to the decoder and check is it
is available or busy. If tuner is available, link is activated
and pipeline is started. The disable_source helper function
invokes the disable_source handler to deactivate and stop the
pipeline.

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

diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index d8e5994..f06da6e 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -233,6 +233,33 @@ 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->entity.graph_obj.mdev;
+	int ret;
+
+	if (!mdev || !mdev->enable_source)
+		return 0;
+	ret = mdev->enable_source(&vdev->entity, &vdev->pipe);
+	if (ret)
+		return -EBUSY;
+	return 0;
+#endif /* CONFIG_MEDIA_CONTROLLER */
+	return 0;
+}
+EXPORT_SYMBOL_GPL(v4l_enable_media_tuner);
+
+void v4l_disable_media_tuner(struct video_device *vdev)
+{
+#ifdef CONFIG_MEDIA_CONTROLLER
+	struct media_device *mdev = vdev->entity.graph_obj.mdev;
+
+	if (mdev && mdev->disable_source)
+		mdev->disable_source(&vdev->entity);
+#endif /* CONFIG_MEDIA_CONTROLLER */
+}
+EXPORT_SYMBOL_GPL(v4l_disable_media_tuner);
 
 /* Priority handling */
 
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index eeabf20..68999a3 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -87,6 +87,7 @@ struct video_device
 #if defined(CONFIG_MEDIA_CONTROLLER)
 	struct media_entity entity;
 	struct media_intf_devnode *intf_devnode;
+	struct media_pipeline pipe;
 #endif
 	/* device ops */
 	const struct v4l2_file_operations *fops;
@@ -176,6 +177,9 @@ void video_unregister_device(struct video_device *vdev);
    latter can also be used for video_device->release(). */
 struct video_device * __must_check video_device_alloc(void);
 
+int v4l_enable_media_tuner(struct video_device *vdev);
+void v4l_disable_media_tuner(struct video_device *vdev);
+
 /* this release function frees the vdev pointer */
 void video_device_release(struct video_device *vdev);
 
-- 
2.5.0


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

* [PATCH 09/31] media: v4l2-core add v4l_vb2q_enable_media_tuner() helper
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (7 preceding siblings ...)
  2016-01-06 20:26 ` [PATCH 08/31] media: v4l-core add v4l_enable/disable_media_tuner() helper functions Shuah Khan
@ 2016-01-06 20:26 ` Shuah Khan
  2016-01-28 15:29   ` Mauro Carvalho Chehab
  2016-01-06 20:26 ` [PATCH 10/31] media: Move au8522_media_pads enum to au8522.h from au8522_priv.h Shuah Khan
                   ` (21 subsequent siblings)
  30 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:26 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Add a new v4l_vb2q_enable_media_tuner() wrapper function
to be called from v4l2-core to enable the media tuner with
videobuf2 queue, when the calling frunction has the videobuf2
queue and doesn't have the struct video_device associated with
the queue handy as in the case of vb2_core_streamon(). This
function simply calls v4l_enable_media_tuner() passing in the
pointer to struct video_device.

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

diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index f06da6e..9ef675a 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -30,6 +30,7 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
+#include <media/videobuf2-core.h>
 
 #define VIDEO_NUM_DEVICES	256
 #define VIDEO_NAME              "video4linux"
@@ -261,6 +262,26 @@ void v4l_disable_media_tuner(struct video_device *vdev)
 }
 EXPORT_SYMBOL_GPL(v4l_disable_media_tuner);
 
+/**
+ * v4l_vb2q_enable_media_tuner - Wrapper for v4l_enable_media_tuner()
+ * @q:         videobuf2 queue
+ *
+ * This function is intended to be called from v4l2-core
+ * to enable the media tuner with videobuf2 queue, when
+ * the calling frunction has the videobuf2 queue and doesn't
+ * have the struct video_device associated with the
+ * queue handy as in the case of vb2_core_streamon(). This
+ * function simply calls v4l_enable_media_tuner() passing
+ * in the pointer to struct video_device.
+ */
+int v4l_vb2q_enable_media_tuner(struct vb2_queue *q)
+{
+	struct v4l2_fh *fh = q->owner;
+
+	return v4l_enable_media_tuner(fh->vdev);
+}
+EXPORT_SYMBOL_GPL(v4l_vb2q_enable_media_tuner);
+
 /* Priority handling */
 
 static inline bool prio_is_valid(enum v4l2_priority prio)
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index 68999a3..1948097 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -179,6 +179,7 @@ struct video_device * __must_check video_device_alloc(void);
 
 int v4l_enable_media_tuner(struct video_device *vdev);
 void v4l_disable_media_tuner(struct video_device *vdev);
+int v4l_vb2q_enable_media_tuner(struct vb2_queue *q);
 
 /* this release function frees the vdev pointer */
 void video_device_release(struct video_device *vdev);
-- 
2.5.0


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

* [PATCH 10/31] media: Move au8522_media_pads enum to au8522.h from au8522_priv.h
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (8 preceding siblings ...)
  2016-01-06 20:26 ` [PATCH 09/31] media: v4l2-core add v4l_vb2q_enable_media_tuner() helper Shuah Khan
@ 2016-01-06 20:26 ` Shuah Khan
  2016-01-06 20:27 ` [PATCH 11/31] media: au8522 change to create MC pad for ALSA Audio Out Shuah Khan
                   ` (20 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:26 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

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      | 7 +++++++
 drivers/media/dvb-frontends/au8522_priv.h | 8 --------
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/media/dvb-frontends/au8522.h b/drivers/media/dvb-frontends/au8522.h
index dde6158..3c72f40 100644
--- a/drivers/media/dvb-frontends/au8522.h
+++ b/drivers/media/dvb-frontends/au8522.h
@@ -90,4 +90,11 @@ enum au8522_audio_input {
 	AU8522_AUDIO_SIF,
 };
 
+enum au8522_media_pads {
+	AU8522_PAD_INPUT,
+	AU8522_PAD_VID_OUT,
+	AU8522_PAD_VBI_OUT,
+
+	AU8522_NUM_PADS
+};
 #endif /* __AU8522_H__ */
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.5.0


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

* [PATCH 11/31] media: au8522 change to create MC pad for ALSA Audio Out
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (9 preceding siblings ...)
  2016-01-06 20:26 ` [PATCH 10/31] media: Move au8522_media_pads enum to au8522.h from au8522_priv.h Shuah Khan
@ 2016-01-06 20:27 ` Shuah Khan
  2016-01-06 20:27 ` [PATCH 12/31] media: au0828 Use au8522_media_pads enum for pad defines Shuah Khan
                   ` (19 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:27 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Add new pad for ALSA Audio Out to au8522_media_pads.

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

diff --git a/drivers/media/dvb-frontends/au8522.h b/drivers/media/dvb-frontends/au8522.h
index 3c72f40..d7a997f 100644
--- a/drivers/media/dvb-frontends/au8522.h
+++ b/drivers/media/dvb-frontends/au8522.h
@@ -94,6 +94,7 @@ enum au8522_media_pads {
 	AU8522_PAD_INPUT,
 	AU8522_PAD_VID_OUT,
 	AU8522_PAD_VBI_OUT,
+	AU8522_PAD_AUDIO_OUT,
 
 	AU8522_NUM_PADS
 };
diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c
index 9674cef..2c53b61 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_SOURCE;
 	sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
 
 	ret = media_entity_pads_init(&sd->entity, ARRAY_SIZE(state->pads),
-- 
2.5.0


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

* [PATCH 12/31] media: au0828 Use au8522_media_pads enum for pad defines
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (10 preceding siblings ...)
  2016-01-06 20:27 ` [PATCH 11/31] media: au8522 change to create MC pad for ALSA Audio Out Shuah Khan
@ 2016-01-06 20:27 ` Shuah Khan
  2016-01-06 20:27 ` [PATCH 13/31] media: au0828 fix au0828_create_media_graph() entity checks Shuah Khan
                   ` (18 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:27 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Change au0828-core to use au8522_media_pads enum 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/usb/au0828/au0828-core.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 101d329..f46fb43 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>
@@ -290,11 +291,13 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
 		if (ret)
 			return ret;
 	}
-	ret = media_create_pad_link(decoder, 1, &dev->vdev.entity, 0,
+	ret = media_create_pad_link(decoder, AU8522_PAD_VID_OUT,
+				    &dev->vdev.entity, 0,
 				    MEDIA_LNK_FL_ENABLED);
 	if (ret)
 		return ret;
-	ret = media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0,
+	ret = media_create_pad_link(decoder, AU8522_PAD_VBI_OUT,
+				    &dev->vbi_dev.entity, 0,
 				    MEDIA_LNK_FL_ENABLED);
 	if (ret)
 		return ret;
-- 
2.5.0


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

* [PATCH 13/31] media: au0828 fix au0828_create_media_graph() entity checks
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (11 preceding siblings ...)
  2016-01-06 20:27 ` [PATCH 12/31] media: au0828 Use au8522_media_pads enum for pad defines Shuah Khan
@ 2016-01-06 20:27 ` Shuah Khan
  2016-01-28 15:37   ` Mauro Carvalho Chehab
  2016-01-06 20:27 ` [PATCH 14/31] media: Change v4l-core to check for tuner availability Shuah Khan
                   ` (17 subsequent siblings)
  30 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:27 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

au0828_create_media_graph() doesn't do any checks to determine,
if vbi_dev, vdev, and input entities have been registered prior
to creating pad links. Checking graph_obj.mdev field works as
the graph_obj.mdev field gets initialized in the entity register
interface. Fix it to check graph_obj.mdev field before creating
pad links.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/usb/au0828/au0828-core.c | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index f46fb43..8ef7c71 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -291,20 +291,27 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
 		if (ret)
 			return ret;
 	}
-	ret = media_create_pad_link(decoder, AU8522_PAD_VID_OUT,
-				    &dev->vdev.entity, 0,
-				    MEDIA_LNK_FL_ENABLED);
-	if (ret)
-		return ret;
-	ret = media_create_pad_link(decoder, AU8522_PAD_VBI_OUT,
-				    &dev->vbi_dev.entity, 0,
-				    MEDIA_LNK_FL_ENABLED);
-	if (ret)
-		return ret;
+	if (dev->vdev.entity.graph_obj.mdev) {
+		ret = media_create_pad_link(decoder, AU8522_PAD_VID_OUT,
+					    &dev->vdev.entity, 0,
+					    MEDIA_LNK_FL_ENABLED);
+		if (ret)
+			return ret;
+	}
+	if (dev->vbi_dev.entity.graph_obj.mdev) {
+		ret = media_create_pad_link(decoder, AU8522_PAD_VBI_OUT,
+					    &dev->vbi_dev.entity, 0,
+					    MEDIA_LNK_FL_ENABLED);
+		if (ret)
+			return ret;
+	}
 
 	for (i = 0; i < AU0828_MAX_INPUT; i++) {
 		struct media_entity *ent = &dev->input_ent[i];
 
+		if (!ent->graph_obj.mdev)
+			continue;
+
 		if (AUVI_INPUT(i).type == AU0828_VMUX_UNDEFINED)
 			break;
 
-- 
2.5.0


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

* [PATCH 14/31] media: Change v4l-core to check for tuner availability
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (12 preceding siblings ...)
  2016-01-06 20:27 ` [PATCH 13/31] media: au0828 fix au0828_create_media_graph() entity checks Shuah Khan
@ 2016-01-06 20:27 ` Shuah Khan
  2016-01-06 20:27 ` [PATCH 15/31] media: dvb-frontend invoke enable/disable_source handlers Shuah Khan
                   ` (16 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:27 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Change s_input, s_fmt, s_tuner, s_frequency, querystd,
s_hw_freq_seek, and vb2_core_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. v4l_disable_media_tuner() is called from
v4l2_fh_exit() to release the tuner. vb2_core_streamon()
uses v4l_vb2q_enable_media_tuner().

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

diff --git a/drivers/media/v4l2-core/v4l2-fh.c b/drivers/media/v4l2-core/v4l2-fh.c
index c97067a..538db62 100644
--- a/drivers/media/v4l2-core/v4l2-fh.c
+++ b/drivers/media/v4l2-core/v4l2-fh.c
@@ -92,6 +92,7 @@ void v4l2_fh_exit(struct v4l2_fh *fh)
 {
 	if (fh->vdev == NULL)
 		return;
+	v4l_disable_media_tuner(fh->vdev);
 	v4l2_event_unsubscribe_all(fh);
 	fh->vdev = NULL;
 }
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 8a018c6..ed7f600 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1041,6 +1041,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);
 }
 
@@ -1448,6 +1454,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) {
@@ -1637,7 +1646,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);
@@ -1691,7 +1704,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_SDR && p->type != V4L2_TUNER_RF)
 			return -EINVAL;
@@ -1746,7 +1763,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;
@@ -1760,7 +1781,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
@@ -1779,7 +1804,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 33bdd81..c9bbb87 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -25,6 +25,7 @@
 #include <linux/kthread.h>
 
 #include <media/videobuf2-core.h>
+#include <media/v4l2-dev.h>
 
 #include <trace/events/vb2.h>
 
@@ -1742,6 +1743,9 @@ int vb2_core_streamon(struct vb2_queue *q, unsigned int type)
 	 * are available.
 	 */
 	if (q->queued_count >= q->min_buffers_needed) {
+		ret = v4l_vb2q_enable_media_tuner(q);
+		if (ret)
+			return ret;
 		ret = vb2_start_streaming(q);
 		if (ret) {
 			__vb2_queue_cancel(q);
-- 
2.5.0


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

* [PATCH 15/31] media: dvb-frontend invoke enable/disable_source handlers
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (13 preceding siblings ...)
  2016-01-06 20:27 ` [PATCH 14/31] media: Change v4l-core to check for tuner availability Shuah Khan
@ 2016-01-06 20:27 ` Shuah Khan
  2016-01-28 15:53   ` Mauro Carvalho Chehab
  2016-01-06 20:27 ` [PATCH 16/31] media: au0828 video remove au0828_enable_analog_tuner() Shuah Khan
                   ` (15 subsequent siblings)
  30 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:27 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-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. In addition, make a change to invoke
enable_source and disable_source handlers to check for
tuner availability. The enable_source handler finds tuner
entity connected to the decoder and check is it is available
or busy. If tuner is available, link is activated and pipeline
is started. The disable_source handler to deactivate and stop
the pipeline. dvb_enable_media_tuner() is removed as it is no
longer necessary with dvb invoking enable_source and
disable_source handlers. pipe_start_entity field is removed
and pipe field is moved to dvb_frontend from dvb_frontend_private.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/dvb-core/dvb_frontend.c | 139 +++++-----------------------------
 drivers/media/dvb-core/dvb_frontend.h |   3 +
 2 files changed, 24 insertions(+), 118 deletions(-)

diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index 4008064..c15f3d8 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -131,11 +131,6 @@ struct dvb_frontend_private {
 	int quality;
 	unsigned int check_wrapped;
 	enum dvbfe_search algo_status;
-
-#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
-	struct media_pipeline pipe;
-	struct media_entity *pipe_start_entity;
-#endif
 };
 
 static void dvb_frontend_wakeup(struct dvb_frontend *fe);
@@ -596,104 +591,12 @@ static void dvb_frontend_wakeup(struct dvb_frontend *fe)
 	wake_up_interruptible(&fepriv->wait_queue);
 }
 
-/**
- * dvb_enable_media_tuner() - tries to enable the DVB tuner
- *
- * @fe:		struct dvb_frontend pointer
- *
- * This function ensures that just one media tuner is enabled for a given
- * frontend. It has two different behaviors:
- * - For trivial devices with just one tuner:
- *   it just enables the existing tuner->fe link
- * - For devices with more than one tuner:
- *   It is up to the driver to implement the logic that will enable one tuner
- *   and disable the other ones. However, if more than one tuner is enabled for
- *   the same frontend, it will print an error message and return -EINVAL.
- *
- * At return, it will return the error code returned by media_entity_setup_link,
- * or 0 if everything is OK, if no tuner is linked to the frontend or if the
- * mdev is NULL.
- */
-#ifdef CONFIG_MEDIA_CONTROLLER_DVB
-static int dvb_enable_media_tuner(struct dvb_frontend *fe)
-{
-	struct dvb_frontend_private *fepriv = fe->frontend_priv;
-	struct dvb_adapter *adapter = fe->dvb;
-	struct media_device *mdev = adapter->mdev;
-	struct media_entity  *entity, *source;
-	struct media_link *link, *found_link = NULL;
-	int ret, n_links = 0, active_links = 0;
-
-	fepriv->pipe_start_entity = NULL;
-
-	if (!mdev)
-		return 0;
-
-	entity = fepriv->dvbdev->entity;
-	fepriv->pipe_start_entity = entity;
-
-	list_for_each_entry(link, &entity->links, list) {
-		if (link->sink->entity == entity) {
-			found_link = link;
-			n_links++;
-			if (link->flags & MEDIA_LNK_FL_ENABLED)
-				active_links++;
-		}
-	}
-
-	if (!n_links || active_links == 1 || !found_link)
-		return 0;
-
-	/*
-	 * If a frontend has more than one tuner linked, it is up to the driver
-	 * to select with one will be the active one, as the frontend core can't
-	 * guess. If the driver doesn't do that, it is a bug.
-	 */
-	if (n_links > 1 && active_links != 1) {
-		dev_err(fe->dvb->device,
-			"WARNING: there are %d active links among %d tuners. This is a driver's bug!\n",
-			active_links, n_links);
-		return -EINVAL;
-	}
-
-	source = found_link->source->entity;
-	fepriv->pipe_start_entity = source;
-	list_for_each_entry(link, &source->links, list) {
-		struct media_entity *sink;
-		int flags = 0;
-
-		sink = link->sink->entity;
-		if (sink == entity)
-			flags = MEDIA_LNK_FL_ENABLED;
-
-		ret = media_entity_setup_link(link, flags);
-		if (ret) {
-			dev_err(fe->dvb->device,
-				"Couldn't change link %s->%s to %s. Error %d\n",
-				source->name, sink->name,
-				flags ? "enabled" : "disabled",
-				ret);
-			return ret;
-		} else
-			dev_dbg(fe->dvb->device,
-				"link %s->%s was %s\n",
-				source->name, sink->name,
-				flags ? "ENABLED" : "disabled");
-	}
-	return 0;
-}
-#endif
-
 static int dvb_frontend_thread(void *data)
 {
 	struct dvb_frontend *fe = 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;
 
@@ -706,20 +609,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();
@@ -829,12 +718,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);
@@ -2612,9 +2495,20 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
 		fepriv->tone = -1;
 		fepriv->voltage = -1;
 
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+		if (fe->dvb->mdev && fe->dvb->mdev->enable_source) {
+			ret = fe->dvb->mdev->enable_source(dvbdev->entity,
+							   &fe->pipe);
+			if (ret) {
+				dev_err(fe->dvb->device,
+					"Tuner is busy. Error %d\n", ret);
+				goto err2;
+			}
+		}
+#endif
 		ret = dvb_frontend_start (fe);
 		if (ret)
-			goto err2;
+			goto err3;
 
 		/*  empty event queue */
 		fepriv->events.eventr = fepriv->events.eventw = 0;
@@ -2624,7 +2518,12 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
 		mutex_unlock (&adapter->mfe_lock);
 	return ret;
 
+err3:
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+	if (fe->dvb->mdev && fe->dvb->mdev->disable_source)
+		fe->dvb->mdev->disable_source(dvbdev->entity);
 err2:
+#endif
 	dvb_generic_release(inode, file);
 err1:
 	if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl)
@@ -2653,6 +2552,10 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
 
 	if (dvbdev->users == -1) {
 		wake_up(&fepriv->wait_queue);
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+		if (fe->dvb->mdev && fe->dvb->mdev->disable_source)
+			fe->dvb->mdev->disable_source(dvbdev->entity);
+#endif
 		if (fe->exit != DVB_FE_NO_EXIT)
 			wake_up(&dvbdev->wait_queue);
 		if (fe->ops.ts_bus_ctrl)
diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h
index 458bcce..9466906 100644
--- a/drivers/media/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb-core/dvb_frontend.h
@@ -686,6 +686,9 @@ struct dvb_frontend {
 	int (*callback)(void *adapter_priv, int component, int cmd, int arg);
 	int id;
 	unsigned int exit;
+#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
+	struct media_pipeline pipe;
+#endif
 };
 
 /**
-- 
2.5.0


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

* [PATCH 16/31] media: au0828 video remove au0828_enable_analog_tuner()
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (14 preceding siblings ...)
  2016-01-06 20:27 ` [PATCH 15/31] media: dvb-frontend invoke enable/disable_source handlers Shuah Khan
@ 2016-01-06 20:27 ` Shuah Khan
  2016-01-06 20:27 ` [PATCH 17/31] media: au0828 video change to use v4l_enable_media_tuner() Shuah Khan
                   ` (14 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:27 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

au0828_enable_analog_tuner() is no longer needed with
v4l2-core and au0828-video invoking enable_source and
disable_source handlers. In addition, it is unnecessary
to check for tuner availability in queue_setup() as
v4l2-core handles the tuner availability checks.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/usb/au0828/au0828-video.c | 61 ---------------------------------
 1 file changed, 61 deletions(-)

diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index 3ea9d4f..32bcc56 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -638,64 +638,6 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
 	return rc;
 }
 
-static int au0828_enable_analog_tuner(struct au0828_dev *dev)
-{
-#ifdef CONFIG_MEDIA_CONTROLLER
-	struct media_device *mdev = dev->media_dev;
-	struct media_entity *source;
-	struct media_link *link, *found_link = NULL;
-	int ret, active_links = 0;
-
-	if (!mdev || !dev->decoder)
-		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.
-	 */
-	list_for_each_entry(link, &dev->decoder->links, list) {
-		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;
-	list_for_each_entry(link, &source->links, list) {
-		struct media_entity *sink;
-		int flags = 0;
-
-		sink = link->sink->entity;
-
-		if (sink == dev->decoder)
-			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");
-	}
-#endif
-	return 0;
-}
-
 static int queue_setup(struct vb2_queue *vq, const void *parg,
 		       unsigned int *nbuffers, unsigned int *nplanes,
 		       unsigned int sizes[], void *alloc_ctxs[])
@@ -711,9 +653,6 @@ static int queue_setup(struct vb2_queue *vq, const void *parg,
 
 	*nplanes = 1;
 	sizes[0] = size;
-
-	au0828_enable_analog_tuner(dev);
-
 	return 0;
 }
 
-- 
2.5.0


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

* [PATCH 17/31] media: au0828 video change to use v4l_enable_media_tuner()
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (15 preceding siblings ...)
  2016-01-06 20:27 ` [PATCH 16/31] media: au0828 video remove au0828_enable_analog_tuner() Shuah Khan
@ 2016-01-06 20:27 ` Shuah Khan
  2016-01-28 15:57   ` Mauro Carvalho Chehab
  2016-01-06 20:27 ` [PATCH 18/31] media: au0828 change to use Managed Media Controller API Shuah Khan
                   ` (13 subsequent siblings)
  30 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:27 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

au0828 is changed to use v4l_enable_media_tuner() to check for
tuner availability from vidioc_g_tuner(), and au0828_v4l2_close(),
before changing tuner settings. If tuner isn't free, return busy
condition from vidioc_g_tuner() and in au0828_v4l2_close() tuner
is left untouched without powering down to save energy.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/usb/au0828/au0828-video.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index 32bcc56..ed3ba05 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -1010,8 +1010,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 = v4l_enable_media_tuner(vdev);
+		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
@@ -1412,10 +1416,16 @@ 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);
+	struct video_device *vfd = video_devdata(file);
+	int ret;
 
 	if (t->index != 0)
 		return -EINVAL;
 
+	ret = v4l_enable_media_tuner(vfd);
+	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);
 
-- 
2.5.0


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

* [PATCH 18/31] media: au0828 change to use Managed Media Controller API
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (16 preceding siblings ...)
  2016-01-06 20:27 ` [PATCH 17/31] media: au0828 video change to use v4l_enable_media_tuner() Shuah Khan
@ 2016-01-06 20:27 ` Shuah Khan
  2016-01-06 20:27 ` [PATCH 19/31] media: au0828 handle media_init and media_register window Shuah Khan
                   ` (12 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:27 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-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.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/usb/au0828/au0828-core.c | 44 +++++++++++++++++-----------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 8ef7c71..1f97fc0 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -135,10 +135,10 @@ static void au0828_unregister_media_device(struct au0828_dev *dev)
 {
 
 #ifdef CONFIG_MEDIA_CONTROLLER
-	if (dev->media_dev) {
+	if (dev->media_dev &&
+		media_devnode_is_registered(&dev->media_dev->devnode)) {
 		media_device_unregister(dev->media_dev);
 		media_device_cleanup(dev->media_dev);
-		kfree(dev->media_dev);
 		dev->media_dev = NULL;
 	}
 #endif
@@ -225,29 +225,29 @@ static int au0828_media_device_init(struct au0828_dev *dev,
 	struct media_device *mdev;
 	int ret;
 
-	mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
+	mdev = media_device_get_devres(&udev->dev);
 	if (!mdev)
 		return -ENOMEM;
 
-	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_init(mdev);
-	if (ret) {
-		pr_err(
-			"Couldn't create a media device. Error: %d\n",
-			ret);
-		kfree(mdev);
-		return ret;
+	if (!media_devnode_is_registered(&mdev->devnode)) {
+		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);
+
+		ret = media_device_init(mdev);
+		if (ret) {
+			dev_err(&udev->dev,
+				"Couldn't create a media device. Error: %d\n",
+				ret);
+			return ret;
+		}
 	}
 
 	dev->media_dev = mdev;
-- 
2.5.0


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

* [PATCH 19/31] media: au0828 handle media_init and media_register window
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (17 preceding siblings ...)
  2016-01-06 20:27 ` [PATCH 18/31] media: au0828 change to use Managed Media Controller API Shuah Khan
@ 2016-01-06 20:27 ` Shuah Khan
  2016-01-06 20:27 ` [PATCH 20/31] media: au0828 change to register/unregister entity_notify hook Shuah Khan
                   ` (11 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:27 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Media device initialization and registration is split
and there is a window between media device init and
media device register during usb probe. au0828 bridge
driver has to coordinate managed media device init and
register with snd-usb-audio. Checking if the device is
registered during media device init could result in the
two drivers stepping on each other for media init. Change
the media device init in au0828 to check if media device
dev is set as this happens at the end of media device
init in au0828 and snd-usb-audio. Change register step
in au0828 to check if media device in registered.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/usb/au0828/au0828-core.c | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 1f97fc0..6ef177c 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -229,7 +229,8 @@ static int au0828_media_device_init(struct au0828_dev *dev,
 	if (!mdev)
 		return -ENOMEM;
 
-	if (!media_devnode_is_registered(&mdev->devnode)) {
+	/* check if media device is already initialized */
+	if (!mdev->dev) {
 		mdev->dev = &udev->dev;
 
 		if (udev->product)
@@ -342,6 +343,27 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
 	return 0;
 }
 
+static int au0828_media_device_register(struct au0828_dev *dev,
+					struct usb_device *udev)
+{
+#ifdef CONFIG_MEDIA_CONTROLLER
+	int ret;
+
+	if (dev->media_dev &&
+		!media_devnode_is_registered(&dev->media_dev->devnode)) {
+
+		/* register media device */
+		ret = media_device_register(dev->media_dev);
+		if (ret) {
+			dev_err(&udev->dev,
+				"Media Device Register Error: %d\n", ret);
+			return ret;
+		}
+	}
+#endif
+	return 0;
+}
+
 static int au0828_usb_probe(struct usb_interface *interface,
 	const struct usb_device_id *id)
 {
@@ -469,7 +491,7 @@ static int au0828_usb_probe(struct usb_interface *interface,
 	}
 
 #ifdef CONFIG_MEDIA_CONTROLLER
-	retval = media_device_register(dev->media_dev);
+	retval = au0828_media_device_register(dev, usbdev);
 #endif
 
 done:
-- 
2.5.0


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

* [PATCH 20/31] media: au0828 change to register/unregister entity_notify hook
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (18 preceding siblings ...)
  2016-01-06 20:27 ` [PATCH 19/31] media: au0828 handle media_init and media_register window Shuah Khan
@ 2016-01-06 20:27 ` Shuah Khan
  2016-01-28 16:36   ` Mauro Carvalho Chehab
  2016-01-06 20:27 ` [PATCH 21/31] media: au0828 create tuner to decoder link in deactivated state Shuah Khan
                   ` (10 subsequent siblings)
  30 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:27 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

au0828 registers entity_notify hook to create media graph for
the device. This handler runs whenvere a new entity gets added
to the media device. It creates necessary links from video, vbi,
and ALSA entities to decoder and links tuner and decoder entities.
As this handler runs as entities get added, it has to maintain
state on the links it already created. New fields are added to
au0828_dev to keep this state information. entity_notify gets
unregistered before media_device unregister.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/usb/au0828/au0828-core.c | 104 +++++++++++++++++++++++----------
 drivers/media/usb/au0828/au0828.h      |   6 ++
 2 files changed, 78 insertions(+), 32 deletions(-)

diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 6ef177c..a381660 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -137,6 +137,8 @@ static void au0828_unregister_media_device(struct au0828_dev *dev)
 #ifdef CONFIG_MEDIA_CONTROLLER
 	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);
 		media_device_cleanup(dev->media_dev);
 		dev->media_dev = NULL;
@@ -263,11 +265,16 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
 	struct media_device *mdev = dev->media_dev;
 	struct media_entity *entity;
 	struct media_entity *tuner = NULL, *decoder = NULL;
+	struct media_entity *audio_capture = NULL;
 	int i, ret;
 
 	if (!mdev)
 		return 0;
 
+	if (dev->tuner_linked && dev->vdev_linked && dev->vbi_linked &&
+	    dev->audio_capture_linked)
+		return 0;
+
 	media_device_for_each_entity(entity, mdev) {
 		switch (entity->function) {
 		case MEDIA_ENT_F_TUNER:
@@ -276,6 +283,9 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
 		case MEDIA_ENT_F_ATV_DECODER:
 			decoder = entity;
 			break;
+		case MEDIA_ENT_F_AUDIO_CAPTURE:
+			audio_capture = entity;
+			break;
 		}
 	}
 
@@ -285,60 +295,77 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
 	if (!decoder)
 		return -EINVAL;
 
-	if (tuner) {
+	if (tuner  && !dev->tuner_linked) {
+		dev->tuner = tuner;
 		ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT,
 					    decoder, 0,
 					    MEDIA_LNK_FL_ENABLED);
 		if (ret)
 			return ret;
+		dev->tuner_linked = 1;
 	}
-	if (dev->vdev.entity.graph_obj.mdev) {
+	if (dev->vdev.entity.graph_obj.mdev && !dev->vdev_linked) {
 		ret = media_create_pad_link(decoder, AU8522_PAD_VID_OUT,
 					    &dev->vdev.entity, 0,
 					    MEDIA_LNK_FL_ENABLED);
 		if (ret)
 			return ret;
+		dev->vdev_linked = 1;
 	}
-	if (dev->vbi_dev.entity.graph_obj.mdev) {
+	if (dev->vbi_dev.entity.graph_obj.mdev && !dev->vbi_linked) {
 		ret = media_create_pad_link(decoder, AU8522_PAD_VBI_OUT,
 					    &dev->vbi_dev.entity, 0,
 					    MEDIA_LNK_FL_ENABLED);
 		if (ret)
 			return ret;
-	}
-
-	for (i = 0; i < AU0828_MAX_INPUT; i++) {
-		struct media_entity *ent = &dev->input_ent[i];
+		dev->vbi_linked = 1;
 
-		if (!ent->graph_obj.mdev)
-			continue;
+		/*
+		 * Input entities are registered before vbi entity,
+		 * create graph nodes for them after vbi is created
+		*/
+		for (i = 0; i < AU0828_MAX_INPUT; i++) {
+			struct media_entity *ent = &dev->input_ent[i];
 
-		if (AUVI_INPUT(i).type == AU0828_VMUX_UNDEFINED)
-			break;
+			if (!ent->graph_obj.mdev)
+				continue;
 
-		switch (AUVI_INPUT(i).type) {
-		case AU0828_VMUX_CABLE:
-		case AU0828_VMUX_TELEVISION:
-		case AU0828_VMUX_DVB:
-			if (!tuner)
+			if (AUVI_INPUT(i).type == AU0828_VMUX_UNDEFINED)
 				break;
 
-			ret = media_create_pad_link(ent, 0, tuner,
-						    TUNER_PAD_RF_INPUT,
-						    MEDIA_LNK_FL_ENABLED);
-			if (ret)
-				return ret;
-			break;
-		case AU0828_VMUX_COMPOSITE:
-		case AU0828_VMUX_SVIDEO:
-		default: /* AU0828_VMUX_DEBUG */
-			/* FIXME: fix the decoder PAD */
-			ret = media_create_pad_link(ent, 0, decoder, 0, 0);
-			if (ret)
-				return ret;
-			break;
+			switch (AUVI_INPUT(i).type) {
+			case AU0828_VMUX_CABLE:
+			case AU0828_VMUX_TELEVISION:
+			case AU0828_VMUX_DVB:
+				if (!tuner)
+					break;
+
+				ret = media_create_pad_link(ent, 0, tuner,
+							TUNER_PAD_RF_INPUT,
+							MEDIA_LNK_FL_ENABLED);
+				if (ret)
+					return ret;
+				break;
+			case AU0828_VMUX_COMPOSITE:
+			case AU0828_VMUX_SVIDEO:
+			default: /* AU0828_VMUX_DEBUG */
+				/* FIXME: fix the decoder PAD */
+				ret = media_create_pad_link(ent, 0, decoder,
+							    0, 0);
+				if (ret)
+					return ret;
+				break;
+			}
 		}
 	}
+	if (audio_capture && !dev->audio_capture_linked) {
+		ret = media_create_pad_link(decoder, AU8522_PAD_AUDIO_OUT,
+					    audio_capture, 0,
+					    MEDIA_LNK_FL_ENABLED);
+		if (ret)
+			return ret;
+		dev->audio_capture_linked = 1;
+	}
 #endif
 	return 0;
 }
@@ -349,8 +376,10 @@ static int au0828_media_device_register(struct au0828_dev *dev,
 #ifdef CONFIG_MEDIA_CONTROLLER
 	int ret;
 
-	if (dev->media_dev &&
-		!media_devnode_is_registered(&dev->media_dev->devnode)) {
+	if (!dev->media_dev)
+		return 0;
+
+	if (!media_devnode_is_registered(&dev->media_dev->devnode)) {
 
 		/* register media device */
 		ret = media_device_register(dev->media_dev);
@@ -360,6 +389,17 @@ static int au0828_media_device_register(struct au0828_dev *dev,
 			return ret;
 		}
 	}
+	/* register entity_notify callback */
+	dev->entity_notify.notify_data = (void *) dev;
+	dev->entity_notify.notify = (void *) au0828_create_media_graph;
+	ret = media_device_register_entity_notify(dev->media_dev,
+						  &dev->entity_notify);
+	if (ret) {
+		dev_err(&udev->dev,
+			"Media Device register entity_notify Error: %d\n",
+			ret);
+		return ret;
+	}
 #endif
 	return 0;
 }
diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
index 8276072..cfb6d58 100644
--- a/drivers/media/usb/au0828/au0828.h
+++ b/drivers/media/usb/au0828/au0828.h
@@ -283,6 +283,12 @@ struct au0828_dev {
 	struct media_entity *decoder;
 	struct media_entity input_ent[AU0828_MAX_INPUT];
 	struct media_pad input_pad[AU0828_MAX_INPUT];
+	struct media_entity_notify entity_notify;
+	struct media_entity *tuner;
+	bool tuner_linked;
+	bool vdev_linked;
+	bool vbi_linked;
+	bool audio_capture_linked;
 #endif
 };
 
-- 
2.5.0


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

* [PATCH 21/31] media: au0828 create tuner to decoder link in deactivated state
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (19 preceding siblings ...)
  2016-01-06 20:27 ` [PATCH 20/31] media: au0828 change to register/unregister entity_notify hook Shuah Khan
@ 2016-01-06 20:27 ` Shuah Khan
  2016-01-06 20:27 ` [PATCH 22/31] media: dvb-core create tuner to demod pad link in disabled state Shuah Khan
                   ` (9 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:27 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Create tuner to demod pad link in disabled state to help
avoid disable step when tuner resource is requested by dvb.

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

diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index a381660..a15a61a 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -297,9 +297,9 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
 
 	if (tuner  && !dev->tuner_linked) {
 		dev->tuner = tuner;
+		/* create tuner to decoder link in deactivated state */
 		ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT,
-					    decoder, 0,
-					    MEDIA_LNK_FL_ENABLED);
+					    decoder, 0, 0);
 		if (ret)
 			return ret;
 		dev->tuner_linked = 1;
-- 
2.5.0


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

* [PATCH 22/31] media: dvb-core create tuner to demod pad link in disabled state
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (20 preceding siblings ...)
  2016-01-06 20:27 ` [PATCH 21/31] media: au0828 create tuner to decoder link in deactivated state Shuah Khan
@ 2016-01-06 20:27 ` Shuah Khan
  2016-01-28 16:38   ` Mauro Carvalho Chehab
  2016-01-06 20:27 ` [PATCH 23/31] media: au0828 implement enable_source and disable_source handlers Shuah Khan
                   ` (8 subsequent siblings)
  30 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:27 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Create tuner to demod pad link in disabled state to help avoid
disable step when tuner resource is requested by video or audio.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/dvb-core/dvbdev.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
index b56e008..1d10fa6 100644
--- a/drivers/media/dvb-core/dvbdev.c
+++ b/drivers/media/dvb-core/dvbdev.c
@@ -593,8 +593,9 @@ int dvb_create_media_graph(struct dvb_adapter *adap)
 	}
 
 	if (tuner && demod) {
+		/* create tuner to demod link deactivated */
 		ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT,
-					    demod, 0, MEDIA_LNK_FL_ENABLED);
+					    demod, 0, 0);
 		if (ret)
 			return ret;
 	}
-- 
2.5.0


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

* [PATCH 23/31] media: au0828 implement enable_source and disable_source handlers
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (21 preceding siblings ...)
  2016-01-06 20:27 ` [PATCH 22/31] media: dvb-core create tuner to demod pad link in disabled state Shuah Khan
@ 2016-01-06 20:27 ` Shuah Khan
  2016-01-28 16:43   ` Mauro Carvalho Chehab
  2016-01-06 20:27 ` [PATCH 24/31] media: au0828 fix null pointer reference in au0828_create_media_graph() Shuah Khan
                   ` (7 subsequent siblings)
  30 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:27 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Implements enable_source and disable_source handlers for other
drivers (v4l2-core, dvb-core, and ALSA) to use to check for
tuner connected to the decoder and activate the link if tuner
is free, and deactivate and free the tuner when it is no longer
needed.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/usb/au0828/au0828-core.c | 148 +++++++++++++++++++++++++++++++++
 drivers/media/usb/au0828/au0828.h      |   2 +
 2 files changed, 150 insertions(+)

diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index a15a61a..f8d2db3 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -370,6 +370,150 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
 	return 0;
 }
 
+static int au0828_enable_source(struct media_entity *entity,
+				struct media_pipeline *pipe)
+{
+#ifdef CONFIG_MEDIA_CONTROLLER
+	struct media_entity  *source;
+	struct media_entity *sink;
+	struct media_link *link, *found_link = NULL;
+	int ret = 0;
+	struct media_device *mdev = entity->graph_obj.mdev;
+	struct au0828_dev *dev;
+
+	if (!mdev)
+		return -ENODEV;
+
+	/* for Audio and Video entities, source is the decoder */
+	mutex_lock(&mdev->graph_mutex);
+
+	dev = mdev->source_priv;
+	if (!dev->tuner || !dev->decoder) {
+		ret = -ENODEV;
+		goto end;
+	}
+
+	/*
+	 * For Audio and V4L2 entity, find the link to which decoder
+	 * is the sink. Look for an active link between decoder and
+	 * tuner, if one exists, nothing to do. If not, look for any
+	 * active links between tuner and any other entity. If one
+	 * exists, tuner is busy. If tuner is free, setup link and
+	 * start pipeline from source (tuner).
+	 * For DVB FE entity, the source for the link is the tuner.
+	 * Check if tuner is available and setup link and start
+	 * pipeline.
+	*/
+	if (entity->function != MEDIA_ENT_F_DTV_DEMOD)
+		sink = dev->decoder;
+	else
+		sink = entity;
+
+	/* Is an active link between sink and tuner */
+	if (dev->active_link) {
+		if (dev->active_link->sink->entity == sink &&
+		    dev->active_link->source->entity == dev->tuner) {
+			ret = 0;
+			goto end;
+		} else {
+			ret = -EBUSY;
+			goto end;
+		}
+	}
+
+	list_for_each_entry(link, &sink->links, list) {
+		/* Check sink, and source */
+		if (link->sink->entity == sink &&
+		    link->source->entity == dev->tuner) {
+			found_link = link;
+			break;
+		}
+	}
+
+	if (!found_link) {
+		ret = -ENODEV;
+		goto end;
+	}
+
+	/* activate link between source and sink and start pipeline */
+	source = found_link->source->entity;
+	ret = __media_entity_setup_link(found_link, MEDIA_LNK_FL_ENABLED);
+	if (ret) {
+		pr_err(
+			"Activate tuner link %s->%s. Error %d\n",
+			source->name, sink->name, ret);
+		goto end;
+	}
+
+	ret = __media_entity_pipeline_start(entity, pipe);
+	if (ret) {
+		pr_err("Start Pipeline: %s->%s Error %d\n",
+			source->name, entity->name, ret);
+		ret = __media_entity_setup_link(found_link, 0);
+		pr_err("Deactive link Error %d\n", ret);
+		goto end;
+	}
+	/*
+	 * save active link and active link owner to avoid audio
+	 * deactivating video owned link from disable_source and
+	 * vice versa
+	*/
+	dev->active_link = found_link;
+	dev->active_link_owner = entity;
+end:
+	mutex_unlock(&mdev->graph_mutex);
+	pr_debug("au0828_enable_source() end %s %d %d\n",
+		entity->name, entity->function, ret);
+	return ret;
+#endif
+	return 0;
+}
+
+static void au0828_disable_source(struct media_entity *entity)
+{
+#ifdef CONFIG_MEDIA_CONTROLLER
+	struct media_entity *sink;
+	int ret = 0;
+	struct media_device *mdev = entity->graph_obj.mdev;
+	struct au0828_dev *dev;
+
+	if (!mdev)
+		return;
+
+	mutex_lock(&mdev->graph_mutex);
+	dev = mdev->source_priv;
+	if (!dev->tuner || !dev->decoder || !dev->active_link) {
+		ret = -ENODEV;
+		goto end;
+	}
+
+	if (entity->function != MEDIA_ENT_F_DTV_DEMOD)
+		sink = dev->decoder;
+	else
+		sink = entity;
+
+	/* link is active - stop pipeline from source (tuner) */
+	if (dev->active_link && dev->active_link->sink->entity == sink &&
+	    dev->active_link->source->entity == dev->tuner) {
+		/*
+		 * prevent video from deactivating link when audio
+		 * has active pipeline
+		*/
+		if (dev->active_link_owner != entity)
+			goto end;
+		__media_entity_pipeline_stop(entity);
+		ret = __media_entity_setup_link(dev->active_link, 0);
+		if (ret)
+			pr_err("Deactive link Error %d\n", ret);
+		dev->active_link = NULL;
+		dev->active_link_owner = NULL;
+	}
+
+end:
+	mutex_unlock(&mdev->graph_mutex);
+#endif
+}
+
 static int au0828_media_device_register(struct au0828_dev *dev,
 					struct usb_device *udev)
 {
@@ -400,6 +544,10 @@ static int au0828_media_device_register(struct au0828_dev *dev,
 			ret);
 		return ret;
 	}
+	/* set enable_source */
+	dev->media_dev->source_priv = (void *) dev;
+	dev->media_dev->enable_source = au0828_enable_source;
+	dev->media_dev->disable_source = au0828_disable_source;
 #endif
 	return 0;
 }
diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
index cfb6d58..3707664 100644
--- a/drivers/media/usb/au0828/au0828.h
+++ b/drivers/media/usb/au0828/au0828.h
@@ -289,6 +289,8 @@ struct au0828_dev {
 	bool vdev_linked;
 	bool vbi_linked;
 	bool audio_capture_linked;
+	struct media_link *active_link;
+	struct media_entity *active_link_owner;
 #endif
 };
 
-- 
2.5.0


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

* [PATCH 24/31] media: au0828 fix null pointer reference in au0828_create_media_graph()
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (22 preceding siblings ...)
  2016-01-06 20:27 ` [PATCH 23/31] media: au0828 implement enable_source and disable_source handlers Shuah Khan
@ 2016-01-06 20:27 ` Shuah Khan
  2016-01-28 16:44   ` Mauro Carvalho Chehab
  2016-01-06 20:27 ` [PATCH 28/31] media: au0828 create link between ALSA Mixer and decoder Shuah Khan
                   ` (6 subsequent siblings)
  30 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:27 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Add a new wrapper function to au0828_create_media_graph()
to be called as an entity_notify function to fix null
pointer dereference. A rebasing mistake resulted in
registering au0828_create_media_graph() without the
correct parameters which lead to the following
null pointer dereference:

[   69.006164] Call Trace:
[   69.006169]  [<ffffffff81a9a1b0>] dump_stack+0x44/0x64
[   69.006175]  [<ffffffff81503af9>] print_trailer+0xf9/0x150
[   69.006180]  [<ffffffff81509284>] object_err+0x34/0x40
[   69.006185]  [<ffffffff815063c4>] ? ___slab_alloc+0x4c4/0x4e0
[   69.006190]  [<ffffffff8150b732>] kasan_report_error+0x212/0x520
[   69.006196]  [<ffffffff815063c4>] ? ___slab_alloc+0x4c4/0x4e0
[   69.006201]  [<ffffffff8150ba83>] __asan_report_load1_noabort+0x43/0x50
[   69.006208]  [<ffffffffa0d30991>] ? au0828_create_media_graph+0x641/0x730 [au0828]
[   69.006215]  [<ffffffffa0d30991>] au0828_create_media_graph+0x641/0x730 [au0828]
[   69.006221]  [<ffffffff82245c3d>] media_device_register_entity+0x33d/0x4f0
[   69.006234]  [<ffffffffa0ebeb1c>] media_stream_init+0x2ac/0x610 [snd_usb_audio]
[   69.006247]  [<ffffffffa0ea9a70>] snd_usb_pcm_open+0xcd0/0x1280 [snd_usb_audio]

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/usb/au0828/au0828-core.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index f8d2db3..9497ad1 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -370,6 +370,20 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
 	return 0;
 }
 
+void au0828_create_media_graph_notify(struct media_entity *new,
+				      void *notify_data)
+{
+#ifdef CONFIG_MEDIA_CONTROLLER
+	struct au0828_dev *dev = (struct au0828_dev *) notify_data;
+	int ret;
+
+	ret = au0828_create_media_graph(dev);
+	if (ret)
+		pr_err("%s() media graph create failed for new entity %s\n",
+		       __func__, new->name);
+#endif
+}
+
 static int au0828_enable_source(struct media_entity *entity,
 				struct media_pipeline *pipe)
 {
@@ -535,7 +549,7 @@ static int au0828_media_device_register(struct au0828_dev *dev,
 	}
 	/* register entity_notify callback */
 	dev->entity_notify.notify_data = (void *) dev;
-	dev->entity_notify.notify = (void *) au0828_create_media_graph;
+	dev->entity_notify.notify = au0828_create_media_graph_notify;
 	ret = media_device_register_entity_notify(dev->media_dev,
 						  &dev->entity_notify);
 	if (ret) {
-- 
2.5.0


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

* [PATCH 28/31] media: au0828 create link between ALSA Mixer and decoder
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (23 preceding siblings ...)
  2016-01-06 20:27 ` [PATCH 24/31] media: au0828 fix null pointer reference in au0828_create_media_graph() Shuah Khan
@ 2016-01-06 20:27 ` Shuah Khan
  2016-01-28 16:58   ` Mauro Carvalho Chehab
  2016-01-06 20:27 ` [PATCH 29/31] media: track media device unregister in progress Shuah Khan
                   ` (5 subsequent siblings)
  30 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:27 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Change au0828_create_media_graph() to create pad link
between MEDIA_ENT_F_AUDIO_MIXER entity and decoder's
AU8522_PAD_AUDIO_OUT. With mixer entity now linked to
decoder, change to link MEDIA_ENT_F_AUDIO_CAPTURE to
mixer's source pad.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/usb/au0828/au0828-core.c | 17 ++++++++++++++---
 drivers/media/usb/au0828/au0828.h      |  1 +
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 722e073..886fb28 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -264,6 +264,7 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
 	struct media_entity *entity;
 	struct media_entity *tuner = NULL, *decoder = NULL;
 	struct media_entity *audio_capture = NULL;
+	struct media_entity *mixer = NULL;
 	int i, ret;
 
 	if (!mdev)
@@ -284,6 +285,9 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
 		case MEDIA_ENT_F_AUDIO_CAPTURE:
 			audio_capture = entity;
 			break;
+		case MEDIA_ENT_F_AUDIO_MIXER:
+			mixer = entity;
+			break;
 		}
 	}
 
@@ -356,14 +360,21 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
 			}
 		}
 	}
-	if (audio_capture && !dev->audio_capture_linked) {
-		ret = media_create_pad_link(decoder, AU8522_PAD_AUDIO_OUT,
-					    audio_capture, 0,
+	if (mixer && audio_capture && !dev->audio_capture_linked) {
+		ret = media_create_pad_link(mixer, 1, audio_capture, 0,
 					    MEDIA_LNK_FL_ENABLED);
 		if (ret)
 			return ret;
 		dev->audio_capture_linked = 1;
 	}
+	if (mixer && !dev->mixer_linked) {
+		ret = media_create_pad_link(decoder, AU8522_PAD_AUDIO_OUT,
+					    mixer, 0,
+					    MEDIA_LNK_FL_ENABLED);
+		if (ret)
+			return ret;
+		dev->mixer_linked = 1;
+	}
 #endif
 	return 0;
 }
diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
index 3707664..b9aa74f 100644
--- a/drivers/media/usb/au0828/au0828.h
+++ b/drivers/media/usb/au0828/au0828.h
@@ -289,6 +289,7 @@ struct au0828_dev {
 	bool vdev_linked;
 	bool vbi_linked;
 	bool audio_capture_linked;
+	bool mixer_linked;
 	struct media_link *active_link;
 	struct media_entity *active_link_owner;
 #endif
-- 
2.5.0


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

* [PATCH 29/31] media: track media device unregister in progress
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (24 preceding siblings ...)
  2016-01-06 20:27 ` [PATCH 28/31] media: au0828 create link between ALSA Mixer and decoder Shuah Khan
@ 2016-01-06 20:27 ` Shuah Khan
  2016-01-28 17:01   ` Mauro Carvalho Chehab
  2016-01-06 20:27 ` [PATCH 30/31] sound/usb: Check media device unregister progress state Shuah Khan
                   ` (4 subsequent siblings)
  30 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:27 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Add support to track media device unregister in progress
state to prevent more than one driver entering unregister.
This enables fixing the general protection faults while
snd-usb-audio was cleaning up media resources for pcm
streams and mixers. In this patch a new interface is added
to return the unregister in progress state. Subsequent
patches to snd-usb-audio and au0828-core use this interface
to avoid entering unregister and attempting to unregister
entities and remove devnodes while unregister is in progress.
Media device unregister removes entities and interface nodes.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/media-device.c |  5 ++++-
 include/media/media-device.h | 17 +++++++++++++++++
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 20c85a9..1bb9a5f 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -749,10 +749,13 @@ void media_device_unregister(struct media_device *mdev)
 	spin_lock(&mdev->lock);
 
 	/* Check if mdev was ever registered at all */
-	if (!media_devnode_is_registered(&mdev->devnode)) {
+	/* check if unregister is in progress */
+	if (!media_devnode_is_registered(&mdev->devnode) ||
+	    mdev->unregister_in_progress) {
 		spin_unlock(&mdev->lock);
 		return;
 	}
+	mdev->unregister_in_progress = true;
 
 	/* Remove all entities from the media device */
 	list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list)
diff --git a/include/media/media-device.h b/include/media/media-device.h
index 04b6c2e..0807292 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -332,6 +332,10 @@ struct media_device {
 	spinlock_t lock;
 	/* Serializes graph operations. */
 	struct mutex graph_mutex;
+	/* Tracks unregister in progress state to prevent
+	 * more than one driver entering unregister
+	*/
+	bool unregister_in_progress;
 
 	/* Handlers to find source entity for the sink entity and
 	 * check if it is available, and activate the link using
@@ -365,6 +369,7 @@ struct media_device {
 /* media_devnode to media_device */
 #define to_media_device(node) container_of(node, struct media_device, devnode)
 
+
 /**
  * media_entity_enum_init - Initialise an entity enumeration
  *
@@ -553,6 +558,12 @@ struct media_device *media_device_get_devres(struct device *dev);
  * @dev: pointer to struct &device.
  */
 struct media_device *media_device_find_devres(struct device *dev);
+/* return unregister in progress state */
+static inline bool media_device_is_unregister_in_progress(
+					struct media_device *mdev)
+{
+	return mdev->unregister_in_progress;
+}
 
 /* Iterate over all entities. */
 #define media_device_for_each_entity(entity, mdev)			\
@@ -569,6 +580,7 @@ struct media_device *media_device_find_devres(struct device *dev);
 /* Iterate over all links. */
 #define media_device_for_each_link(link, mdev)			\
 	list_for_each_entry(link, &(mdev)->links, graph_obj.list)
+
 #else
 static inline int media_device_register(struct media_device *mdev)
 {
@@ -604,5 +616,10 @@ static inline struct media_device *media_device_find_devres(struct device *dev)
 {
 	return NULL;
 }
+static inline bool media_device_is_unregister_in_progress(
+					struct media_device *mdev)
+{
+	return false;
+}
 #endif /* CONFIG_MEDIA_CONTROLLER */
 #endif
-- 
2.5.0


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

* [PATCH 30/31] sound/usb: Check media device unregister progress state
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (25 preceding siblings ...)
  2016-01-06 20:27 ` [PATCH 29/31] media: track media device unregister in progress Shuah Khan
@ 2016-01-06 20:27 ` Shuah Khan
  2016-01-06 20:27 ` [PATCH 31/31] media: au0828 change to check " Shuah Khan
                   ` (3 subsequent siblings)
  30 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:27 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Change to release media resources for pcm streams
and mixer before snd_card_disconnect() is done from
usb_audio_disconnect(). The stream and mixer resource
release interfaces access managed media resources
(device resources) created on the usb device parent.
These interfaces should be called before the last
put_device() which releases all the device resources.
In addition, changed the stream and mixer resource
release interfaces to check if media device unregister
is in progress and avoid calling Media Controller API
to unregister entities and remove devnodes. Media device
unregister takes care of all of this. This fixes the
the general protection faults while snd-usb-audio was
cleaning up media resources for pcm streams and mixers.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 sound/usb/card.c   |  8 ++++++--
 sound/usb/media.c  | 41 +++++++++++++++++++++++++++++++----------
 sound/usb/media.h  |  4 ++--
 sound/usb/stream.c |  1 -
 4 files changed, 39 insertions(+), 15 deletions(-)

diff --git a/sound/usb/card.c b/sound/usb/card.c
index e965982..8959ccb 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -608,6 +608,12 @@ static void usb_audio_disconnect(struct usb_interface *intf)
 		 */
 		wait_event(chip->shutdown_wait,
 			   !atomic_read(&chip->usage_count));
+
+		/* release media pcm stream resources */
+		media_stream_delete(chip);
+		/* delete mixer media resources */
+		media_mixer_delete(chip);
+
 		snd_card_disconnect(card);
 		/* release the pcm resources */
 		list_for_each_entry(as, &chip->pcm_list, list) {
@@ -621,8 +627,6 @@ static void usb_audio_disconnect(struct usb_interface *intf)
 		list_for_each(p, &chip->midi_list) {
 			snd_usbmidi_disconnect(p);
 		}
-		/* delete mixer media resources */
-		media_mixer_delete(chip);
 		/* release mixer resources */
 		list_for_each_entry(mixer, &chip->mixer_list, list) {
 			snd_usb_mixer_disconnect(mixer);
diff --git a/sound/usb/media.c b/sound/usb/media.c
index 4f99086..9d29e1d 100644
--- a/sound/usb/media.c
+++ b/sound/usb/media.c
@@ -98,8 +98,11 @@ void media_device_delete(struct usb_interface *iface)
 	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);
+	if (mdev) {
+		if (media_devnode_is_registered(&mdev->devnode) &&
+		    !media_device_is_unregister_in_progress(mdev))
+			media_device_unregister(mdev);
+	}
 }
 
 static int media_enable_source(struct media_ctl *mctl)
@@ -177,7 +180,7 @@ int media_stream_init(struct snd_usb_substream *subs, struct snd_pcm *pcm,
 	return 0;
 }
 
-void media_stream_delete(struct snd_usb_substream *subs)
+static void __media_stream_delete(struct snd_usb_substream *subs)
 {
 	struct media_ctl *mctl = (struct media_ctl *) subs->media_ctl;
 
@@ -185,7 +188,7 @@ void media_stream_delete(struct snd_usb_substream *subs)
 		struct media_device *mdev;
 
 		mdev = media_device_find_devres(&subs->dev->dev);
-		if (mdev) {
+		if (mdev && !media_device_is_unregister_in_progress(mdev)) {
 			media_devnode_remove(mctl->intf_devnode);
 			media_device_unregister_entity(&mctl->media_entity);
 			media_entity_cleanup(&mctl->media_entity);
@@ -195,6 +198,21 @@ void media_stream_delete(struct snd_usb_substream *subs)
 	}
 }
 
+void media_stream_delete(struct snd_usb_audio *chip)
+{
+	struct snd_usb_stream *as;
+
+	list_for_each_entry(as, &chip->pcm_list, list) {
+		struct snd_usb_substream *subs;
+		int idx;
+
+		for (idx = 0; idx < 2; idx++) {
+			subs = &as->substream[idx];
+			__media_stream_delete(subs);
+		}
+	}
+}
+
 int media_start_pipeline(struct snd_usb_substream *subs)
 {
 	struct media_ctl *mctl = (struct media_ctl *) subs->media_ctl;
@@ -283,22 +301,25 @@ void media_mixer_delete(struct snd_usb_audio *chip)
 	struct media_device *mdev;
 
 	mdev = media_device_find_devres(&chip->dev->dev);
-	if (!mdev)
-		return;
 
+	if (chip->ctl_intf_media_devnode) {
+		if (mdev && !media_device_is_unregister_in_progress(mdev))
+			media_devnode_remove(chip->ctl_intf_media_devnode);
+		chip->ctl_intf_media_devnode = NULL;
+	}
 	list_for_each_entry(mixer, &chip->mixer_list, list) {
 		struct media_mixer_ctl *mctl;
 
 		mctl = (struct media_mixer_ctl *) mixer->media_mixer_ctl;
 		if (!mixer->media_mixer_ctl)
 			continue;
-
-		media_device_unregister_entity(&mctl->media_entity);
-		media_entity_cleanup(&mctl->media_entity);
+		if (mdev && !media_device_is_unregister_in_progress(mdev)) {
+			media_device_unregister_entity(&mctl->media_entity);
+			media_entity_cleanup(&mctl->media_entity);
+		}
 		kfree(mctl);
 		mixer->media_mixer_ctl = NULL;
 	}
-	media_devnode_remove(chip->ctl_intf_media_devnode);
 }
 
 #endif
diff --git a/sound/usb/media.h b/sound/usb/media.h
index 00884b5..bd1b1ec 100644
--- a/sound/usb/media.h
+++ b/sound/usb/media.h
@@ -52,7 +52,7 @@ int media_device_create(struct snd_usb_audio *chip,
 void media_device_delete(struct usb_interface *iface);
 int media_stream_init(struct snd_usb_substream *subs, struct snd_pcm *pcm,
 			int stream);
-void media_stream_delete(struct snd_usb_substream *subs);
+void media_stream_delete(struct snd_usb_audio *chip);
 int media_start_pipeline(struct snd_usb_substream *subs);
 void media_stop_pipeline(struct snd_usb_substream *subs);
 int media_mixer_init(struct snd_usb_audio *chip);
@@ -65,7 +65,7 @@ static inline void media_device_delete(struct usb_interface *iface) { }
 static inline int media_stream_init(struct snd_usb_substream *subs,
 					struct snd_pcm *pcm, int stream)
 						{ return 0; }
-static inline void media_stream_delete(struct snd_usb_substream *subs) { }
+static inline void media_stream_delete(struct snd_usb_audio *chip) { }
 static inline int media_start_pipeline(struct snd_usb_substream *subs)
 					{ return 0; }
 static inline void media_stop_pipeline(struct snd_usb_substream *subs) { }
diff --git a/sound/usb/stream.c b/sound/usb/stream.c
index 789e515..f96f539 100644
--- a/sound/usb/stream.c
+++ b/sound/usb/stream.c
@@ -53,7 +53,6 @@ static void free_substream(struct snd_usb_substream *subs)
 		kfree(fp);
 	}
 	kfree(subs->rate_list.list);
-	media_stream_delete(subs);
 }
 
 
-- 
2.5.0


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

* [PATCH 31/31] media: au0828 change to check media device unregister progress state
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (26 preceding siblings ...)
  2016-01-06 20:27 ` [PATCH 30/31] sound/usb: Check media device unregister progress state Shuah Khan
@ 2016-01-06 20:27 ` Shuah Khan
  2016-01-28 17:05   ` Mauro Carvalho Chehab
  2016-01-06 21:01 ` [PATCH 25/31] media: au0828 fix to not call media_device_unregister_entity_notify() Shuah Khan
                   ` (2 subsequent siblings)
  30 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 20:27 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Change au0828_unregister_media_device() to check media
device media device unregister is in progress and avoid
calling media_device_unregister() and other cleanup done
in au0828_unregister_media_device().

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/usb/au0828/au0828-core.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 886fb28..de357a2 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -136,7 +136,9 @@ static void au0828_unregister_media_device(struct au0828_dev *dev)
 
 #ifdef CONFIG_MEDIA_CONTROLLER
 	if (dev->media_dev &&
-		media_devnode_is_registered(&dev->media_dev->devnode)) {
+		media_devnode_is_registered(&dev->media_dev->devnode) &&
+		!media_device_is_unregister_in_progress(dev->media_dev)) {
+
 		media_device_unregister(dev->media_dev);
 		media_device_cleanup(dev->media_dev);
 		dev->media_dev = NULL;
-- 
2.5.0


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

* [PATCH 25/31] media: au0828 fix to not call media_device_unregister_entity_notify()
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (27 preceding siblings ...)
  2016-01-06 20:27 ` [PATCH 31/31] media: au0828 change to check " Shuah Khan
@ 2016-01-06 21:01 ` Shuah Khan
  2016-01-28 16:45   ` Mauro Carvalho Chehab
  2016-01-06 21:05 ` [PATCH 26/31] sound/usb: Update ALSA driver to use Managed Media Controller API Shuah Khan
  2016-01-06 21:05 ` [PATCH 27/31] sound/usb: Create media mixer function and control interface entities Shuah Khan
  30 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 21:01 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

entity_notify handlers are removed from media_device_unregister().
There is no need to call media_device_unregister_entity_notify()
to do that right before calling media_device_unregister().

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/usb/au0828/au0828-core.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 9497ad1..722e073 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -137,8 +137,6 @@ static void au0828_unregister_media_device(struct au0828_dev *dev)
 #ifdef CONFIG_MEDIA_CONTROLLER
 	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);
 		media_device_cleanup(dev->media_dev);
 		dev->media_dev = NULL;
-- 
2.5.0


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

* [PATCH 26/31] sound/usb: Update ALSA driver to use Managed Media Controller API
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (28 preceding siblings ...)
  2016-01-06 21:01 ` [PATCH 25/31] media: au0828 fix to not call media_device_unregister_entity_notify() Shuah Khan
@ 2016-01-06 21:05 ` Shuah Khan
  2016-01-07 15:44   ` Takashi Iwai
  2016-01-06 21:05 ` [PATCH 27/31] sound/usb: Create media mixer function and control interface entities Shuah Khan
  30 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 21:05 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-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 initialze (if necessary) and
register the media device if it isn't already initialized
and 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_hw_params(). If enable_source returns
with tuner busy condition, then snd_usb_hw_params() will fail
with -EBUSY. Media pipeline is stopped from snd_usb_hw_free().

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 sound/usb/Makefile       |  15 +++-
 sound/usb/card.c         |   7 ++
 sound/usb/card.h         |   1 +
 sound/usb/media.c        | 214 +++++++++++++++++++++++++++++++++++++++++++++++
 sound/usb/media.h        |  54 ++++++++++++
 sound/usb/pcm.c          |  26 ++++--
 sound/usb/quirks-table.h |   1 +
 sound/usb/quirks.c       |   9 +-
 sound/usb/stream.c       |   2 +
 sound/usb/usbaudio.h     |   1 +
 10 files changed, 323 insertions(+), 7 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 18f5664..1a63851 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");
@@ -621,6 +622,12 @@ 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 71778ca..c15a03c 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -156,6 +156,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..747a66a
--- /dev/null
+++ b/sound/usb/media.c
@@ -0,0 +1,214 @@
+/*
+ * 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_create(struct snd_usb_audio *chip,
+			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 (!mdev->dev) {
+		/* 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_init(mdev);
+		if (ret) {
+			dev_err(&usbdev->dev,
+				"Couldn't create a media device. Error: %d\n",
+				ret);
+			return ret;
+		}
+	}
+	if (!media_devnode_is_registered(&mdev->devnode)) {
+		ret = media_device_register(mdev);
+		if (ret) {
+			dev_err(&usbdev->dev,
+				"Couldn't register 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 int media_enable_source(struct media_ctl *mctl)
+{
+	if (mctl && mctl->media_dev->enable_source)
+		return mctl->media_dev->enable_source(&mctl->media_entity,
+						      &mctl->media_pipe);
+	return 0;
+}
+
+static void media_disable_source(struct media_ctl *mctl)
+{
+	if (mctl && mctl->media_dev->disable_source)
+		mctl->media_dev->disable_source(&mctl->media_entity);
+}
+
+int 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;
+	u32 intf_type;
+	int ret = 0;
+
+	mdev = media_device_find_devres(&subs->dev->dev);
+	if (!mdev)
+		return -ENODEV;
+
+	if (subs->media_ctl)
+		return 0;
+
+	/* allocate media_ctl */
+	mctl = kzalloc(sizeof(*mctl), GFP_KERNEL);
+	if (!mctl)
+		return -ENOMEM;
+
+	mctl->media_dev = mdev;
+	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		intf_type = MEDIA_INTF_T_ALSA_PCM_PLAYBACK;
+		mctl->media_entity.function = MEDIA_ENT_F_AUDIO_PLAYBACK;
+	} else {
+		intf_type = MEDIA_INTF_T_ALSA_PCM_CAPTURE;
+		mctl->media_entity.function = MEDIA_ENT_F_AUDIO_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_pads_init(&mctl->media_entity, 1, &mctl->media_pad);
+	ret =  media_device_register_entity(mctl->media_dev,
+					    &mctl->media_entity);
+	if (ret) {
+		kfree(mctl);
+		return ret;
+	}
+	mctl->intf_devnode = media_devnode_create(mdev, intf_type, 0,
+						  MAJOR(pcm_dev->devt),
+						  MINOR(pcm_dev->devt));
+	if (!mctl->intf_devnode) {
+		media_device_unregister_entity(&mctl->media_entity);
+		kfree(mctl);
+		return -ENOMEM;
+	}
+	mctl->intf_link = media_create_intf_link(&mctl->media_entity,
+						 &mctl->intf_devnode->intf,
+						 MEDIA_LNK_FL_ENABLED);
+	if (!mctl->intf_link) {
+		media_devnode_remove(mctl->intf_devnode);
+		media_device_unregister_entity(&mctl->media_entity);
+		kfree(mctl);
+		return -ENOMEM;
+	}
+	subs->media_ctl = (void *) mctl;
+	return 0;
+}
+
+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_devnode_remove(mctl->intf_devnode);
+			media_device_unregister_entity(&mctl->media_entity);
+			media_entity_cleanup(&mctl->media_entity);
+		}
+		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;
+
+	if (mctl)
+		return media_enable_source(mctl);
+	return 0;
+}
+
+void media_stop_pipeline(struct snd_usb_substream *subs)
+{
+	struct media_ctl *mctl = (struct media_ctl *) subs->media_ctl;
+
+	if (mctl)
+		media_disable_source(mctl);
+}
+#endif
diff --git a/sound/usb/media.h b/sound/usb/media.h
new file mode 100644
index 0000000..4a93dbd
--- /dev/null
+++ b/sound/usb/media.h
@@ -0,0 +1,54 @@
+/*
+ * 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 media_entity;
+	struct media_intf_devnode *intf_devnode;
+	struct media_link *intf_link;
+	struct media_pad media_pad;
+	struct media_pipeline media_pipe;
+};
+
+int media_device_create(struct snd_usb_audio *chip,
+			struct usb_interface *iface);
+void media_device_delete(struct usb_interface *iface);
+int 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_create(struct snd_usb_audio *chip,
+				      struct usb_interface *iface)
+						{ return 0; }
+static inline void media_device_delete(struct usb_interface *iface) { }
+static inline int media_stream_init(struct snd_usb_substream *subs,
+					struct snd_pcm *pcm, int stream)
+						{ return 0; }
+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 9245f52..30bc183 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
@@ -715,10 +716,14 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
 	struct audioformat *fmt;
 	int ret;
 
+	ret = media_start_pipeline(subs);
+	if (ret)
+		return ret;
+
 	ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
 					       params_buffer_bytes(hw_params));
 	if (ret < 0)
-		return ret;
+		goto err_ret;
 
 	subs->pcm_format = params_format(hw_params);
 	subs->period_bytes = params_period_bytes(hw_params);
@@ -732,22 +737,27 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
 		dev_dbg(&subs->dev->dev,
 			"cannot set format: format = %#x, rate = %d, channels = %d\n",
 			   subs->pcm_format, subs->cur_rate, subs->channels);
-		return -EINVAL;
+		ret = -EINVAL;
+		goto err_ret;
 	}
 
 	ret = snd_usb_lock_shutdown(subs->stream->chip);
 	if (ret < 0)
-		return ret;
+		goto err_ret;
 	ret = set_format(subs, fmt);
 	snd_usb_unlock_shutdown(subs->stream->chip);
 	if (ret < 0)
-		return ret;
+		goto err_ret;
 
 	subs->interface = fmt->iface;
 	subs->altset_idx = fmt->altset_idx;
 	subs->need_setup_ep = true;
 
 	return 0;
+
+err_ret:
+	media_stop_pipeline(subs);
+	return ret;
 }
 
 /*
@@ -759,6 +769,7 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream)
 {
 	struct snd_usb_substream *subs = substream->runtime->private_data;
 
+	media_stop_pipeline(subs);
 	subs->cur_audiofmt = NULL;
 	subs->cur_rate = 0;
 	subs->period_bytes = 0;
@@ -1219,6 +1230,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;
@@ -1232,7 +1244,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)
+		ret = media_stream_init(subs, as->pcm, direction);
+	return ret;
 }
 
 static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction)
@@ -1241,6 +1256,7 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction)
 	struct snd_usb_substream *subs = &as->substream[direction];
 
 	stop_endpoints(subs, true);
+	media_stop_pipeline(subs);
 
 	if (subs->interface >= 0 &&
 	    !snd_usb_lock_shutdown(subs->stream->chip)) {
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index 1a1e2e4..8f7b71b 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -2875,6 +2875,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 5ca80e7..dc6878c 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
@@ -544,13 +545,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_create() fails */
+		media_device_create(chip, 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 8ee14f2..789e515 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 15a1271..e3fac29 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -109,6 +109,7 @@ struct snd_usb_audio_quirk {
 	const char *product_name;
 	int16_t ifnum;
 	uint16_t type;
+	bool media_device;
 	const void *data;
 };
 
-- 
2.5.0


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

* [PATCH 27/31] sound/usb: Create media mixer function and control interface entities
  2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
                   ` (29 preceding siblings ...)
  2016-01-06 21:05 ` [PATCH 26/31] sound/usb: Update ALSA driver to use Managed Media Controller API Shuah Khan
@ 2016-01-06 21:05 ` Shuah Khan
  30 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-06 21:05 UTC (permalink / raw)
  To: mchehab, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier
  Cc: Shuah Khan, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Add support for creating MEDIA_ENT_F_AUDIO_MIXER entity for
each mixer and a MEDIA_INTF_T_ALSA_CONTROL control interface
entity that links to mixer entities. MEDIA_INTF_T_ALSA_CONTROL
entity corresponds to the control device for the card.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 sound/usb/card.c     |  5 +++
 sound/usb/media.c    | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 sound/usb/media.h    | 21 ++++++++++++
 sound/usb/mixer.h    |  1 +
 sound/usb/usbaudio.h |  1 +
 5 files changed, 118 insertions(+)

diff --git a/sound/usb/card.c b/sound/usb/card.c
index 1a63851..e965982 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -562,6 +562,9 @@ static int usb_audio_probe(struct usb_interface *intf,
 	if (err < 0)
 		goto __error;
 
+	/* Create media entities for mixer and control dev */
+	media_mixer_init(chip);
+
 	usb_chip[chip->index] = chip;
 	chip->num_interfaces++;
 	usb_set_intfdata(intf, chip);
@@ -618,6 +621,8 @@ static void usb_audio_disconnect(struct usb_interface *intf)
 		list_for_each(p, &chip->midi_list) {
 			snd_usbmidi_disconnect(p);
 		}
+		/* delete mixer media resources */
+		media_mixer_delete(chip);
 		/* release mixer resources */
 		list_for_each_entry(mixer, &chip->mixer_list, list) {
 			snd_usb_mixer_disconnect(mixer);
diff --git a/sound/usb/media.c b/sound/usb/media.c
index 747a66a..4f99086 100644
--- a/sound/usb/media.c
+++ b/sound/usb/media.c
@@ -211,4 +211,94 @@ void media_stop_pipeline(struct snd_usb_substream *subs)
 	if (mctl)
 		media_disable_source(mctl);
 }
+
+int media_mixer_init(struct snd_usb_audio *chip)
+{
+	struct device *ctl_dev = &chip->card->ctl_dev;
+	struct media_intf_devnode *ctl_intf;
+	struct usb_mixer_interface *mixer;
+	struct media_device *mdev;
+	struct media_mixer_ctl *mctl;
+	u32 intf_type = MEDIA_INTF_T_ALSA_CONTROL;
+	int ret;
+
+	mdev = media_device_find_devres(&chip->dev->dev);
+	if (!mdev)
+		return -ENODEV;
+
+	ctl_intf = chip->ctl_intf_media_devnode;
+	if (!ctl_intf) {
+		ctl_intf = (void *) media_devnode_create(mdev,
+							 intf_type, 0,
+							 MAJOR(ctl_dev->devt),
+							 MINOR(ctl_dev->devt));
+		if (!ctl_intf)
+			return -ENOMEM;
+		chip->ctl_intf_media_devnode = ctl_intf;
+	}
+
+	list_for_each_entry(mixer, &chip->mixer_list, list) {
+
+		if (mixer->media_mixer_ctl)
+			continue;
+
+		/* allocate media_mixer_ctl */
+		mctl = kzalloc(sizeof(*mctl), GFP_KERNEL);
+		if (!mctl)
+			return -ENOMEM;
+
+		mctl->media_dev = mdev;
+		mctl->media_entity.function = MEDIA_ENT_F_AUDIO_MIXER;
+		mctl->media_entity.name = chip->card->mixername;
+		mctl->media_pad[0].flags = MEDIA_PAD_FL_SINK;
+		mctl->media_pad[1].flags = MEDIA_PAD_FL_SOURCE;
+		mctl->media_pad[2].flags = MEDIA_PAD_FL_SOURCE;
+		media_entity_pads_init(&mctl->media_entity, MEDIA_MIXER_PAD_MAX,
+				  mctl->media_pad);
+		ret =  media_device_register_entity(mctl->media_dev,
+						    &mctl->media_entity);
+		if (ret) {
+			kfree(mctl);
+			return ret;
+		}
+
+		mctl->intf_link = media_create_intf_link(&mctl->media_entity,
+							 &ctl_intf->intf,
+							 MEDIA_LNK_FL_ENABLED);
+		if (!mctl->intf_link) {
+			media_device_unregister_entity(&mctl->media_entity);
+			media_entity_cleanup(&mctl->media_entity);
+			kfree(mctl);
+			return -ENOMEM;
+		}
+		mctl->intf_devnode = ctl_intf;
+		mixer->media_mixer_ctl = (void *) mctl;
+	}
+	return 0;
+}
+
+void media_mixer_delete(struct snd_usb_audio *chip)
+{
+	struct usb_mixer_interface *mixer;
+	struct media_device *mdev;
+
+	mdev = media_device_find_devres(&chip->dev->dev);
+	if (!mdev)
+		return;
+
+	list_for_each_entry(mixer, &chip->mixer_list, list) {
+		struct media_mixer_ctl *mctl;
+
+		mctl = (struct media_mixer_ctl *) mixer->media_mixer_ctl;
+		if (!mixer->media_mixer_ctl)
+			continue;
+
+		media_device_unregister_entity(&mctl->media_entity);
+		media_entity_cleanup(&mctl->media_entity);
+		kfree(mctl);
+		mixer->media_mixer_ctl = NULL;
+	}
+	media_devnode_remove(chip->ctl_intf_media_devnode);
+}
+
 #endif
diff --git a/sound/usb/media.h b/sound/usb/media.h
index 4a93dbd..00884b5 100644
--- a/sound/usb/media.h
+++ b/sound/usb/media.h
@@ -20,6 +20,7 @@
 #ifdef USE_MEDIA_CONTROLLER
 #include <media/media-device.h>
 #include <media/media-entity.h>
+#include <sound/asound.h>
 
 struct media_ctl {
 	struct media_device *media_dev;
@@ -30,6 +31,22 @@ struct media_ctl {
 	struct media_pipeline media_pipe;
 };
 
+/*
+ * One source pad each for SNDRV_PCM_STREAM_CAPTURE and
+ * SNDRV_PCM_STREAM_PLAYBACK. One for sink pad to link
+ * to AUDIO Source
+*/
+#define MEDIA_MIXER_PAD_MAX    (SNDRV_PCM_STREAM_LAST + 2)
+
+struct media_mixer_ctl {
+	struct media_device *media_dev;
+	struct media_entity media_entity;
+	struct media_intf_devnode *intf_devnode;
+	struct media_link *intf_link;
+	struct media_pad media_pad[MEDIA_MIXER_PAD_MAX];
+	struct media_pipeline media_pipe;
+};
+
 int media_device_create(struct snd_usb_audio *chip,
 			struct usb_interface *iface);
 void media_device_delete(struct usb_interface *iface);
@@ -38,6 +55,8 @@ int media_stream_init(struct snd_usb_substream *subs, struct snd_pcm *pcm,
 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);
+int media_mixer_init(struct snd_usb_audio *chip);
+void media_mixer_delete(struct snd_usb_audio *chip);
 #else
 static inline int media_device_create(struct snd_usb_audio *chip,
 				      struct usb_interface *iface)
@@ -50,5 +69,7 @@ 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) { }
+static int media_mixer_init(struct snd_usb_audio *chip) { return 0; }
+static void media_mixer_delete(struct snd_usb_audio *chip) { }
 #endif
 #endif /* __MEDIA_H */
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
index 3417ef3..787b352 100644
--- a/sound/usb/mixer.h
+++ b/sound/usb/mixer.h
@@ -22,6 +22,7 @@ struct usb_mixer_interface {
 	struct urb *rc_urb;
 	struct usb_ctrlrequest *rc_setup_packet;
 	u8 rc_buffer[6];
+	void *media_mixer_ctl;
 };
 
 #define MAX_CHANNELS	16	/* max logical channels */
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index e3fac29..490b16a 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -60,6 +60,7 @@ struct snd_usb_audio {
 	bool autoclock;			/* from the 'autoclock' module param */
 
 	struct usb_host_interface *ctrl_intf;	/* the audio control interface */
+	void *ctl_intf_media_devnode;
 };
 
 #define usb_audio_err(chip, fmt, args...) \
-- 
2.5.0


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

* Re: [PATCH 26/31] sound/usb: Update ALSA driver to use Managed Media Controller API
  2016-01-06 21:05 ` [PATCH 26/31] sound/usb: Update ALSA driver to use Managed Media Controller API Shuah Khan
@ 2016-01-07 15:44   ` Takashi Iwai
  2016-01-07 20:27     ` Shuah Khan
  0 siblings, 1 reply; 79+ messages in thread
From: Takashi Iwai @ 2016-01-07 15:44 UTC (permalink / raw)
  To: Shuah Khan
  Cc: hans.verkuil, laurent.pinchart, clemens, sakari.ailus, javier,
	mchehab, alsa-devel, arnd, ricard.wanderlof, labbott,
	chehabrafael, misterpib, prabhakar.csengg, ricardo.ribalda,
	ruchandani.tina, takamichiho, tvboxspy, dominic.sacre, crope,
	julian, pierre-louis.bossart, corbet, joe, johan, dan.carpenter,
	pawel, p.zabel, perex, stefanr, inki.dae, jh1009.sung,
	k.kozlowski, kyungmin.park, m.szyprowski, sw0312.kim, elfring,
	linux-api, linux-kernel, linux-media, linuxbugs, gtmkramer,
	normalperson, daniel

On Wed, 06 Jan 2016 22:05:35 +0100,
Shuah Khan wrote:
> 
> 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

Can't we define this rather via Kconfig?
Doing this in Makefile is way too tricky, and it's unclear to users
whether MC is actually enabled or not.


> diff --git a/sound/usb/media.c b/sound/usb/media.c
> new file mode 100644
> index 0000000..747a66a
> --- /dev/null
> +++ b/sound/usb/media.c
> @@ -0,0 +1,214 @@
> +/*
> + * 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"

I believe we can get rid of many include files just for MC support...


> +#ifdef USE_MEDIA_CONTROLLER

This ifdef can be removed once if we build this object file
conditionally in Makefile.


> @@ -1232,7 +1244,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)
> +		ret = media_stream_init(subs, as->pcm, direction);

Need to call snd_usb_autosuspend() in the error path.


> --- a/sound/usb/quirks.c
> +++ b/sound/usb/quirks.c
> @@ -544,13 +545,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_create() fails */
> +		media_device_create(chip, iface);
> +	}

So far, so good...

>  	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;

Any reason to change this?


Takashi

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

* Re: [PATCH 26/31] sound/usb: Update ALSA driver to use Managed Media Controller API
  2016-01-07 15:44   ` Takashi Iwai
@ 2016-01-07 20:27     ` Shuah Khan
  0 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-07 20:27 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: hans.verkuil, laurent.pinchart, clemens, sakari.ailus, javier,
	mchehab, alsa-devel, arnd, ricard.wanderlof, labbott,
	chehabrafael, misterpib, prabhakar.csengg, ricardo.ribalda,
	ruchandani.tina, takamichiho, tvboxspy, dominic.sacre, crope,
	julian, pierre-louis.bossart, corbet, joe, johan, dan.carpenter,
	pawel, p.zabel, perex, stefanr, inki.dae, jh1009.sung,
	k.kozlowski, kyungmin.park, m.szyprowski, sw0312.kim, elfring,
	linux-api, linux-kernel, linux-media, linuxbugs, gtmkramer,
	normalperson, daniel, Shuah Khan

On 01/07/2016 08:44 AM, Takashi Iwai wrote:
> On Wed, 06 Jan 2016 22:05:35 +0100,
> Shuah Khan wrote:
>>
>> 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
> 
> Can't we define this rather via Kconfig?
> Doing this in Makefile is way too tricky, and it's unclear to users
> whether MC is actually enabled or not.
> 

Yeah doing this in Makefile is a bit tricky
and can lead to confusion.

I can't think of any specific reason why I added
this check to the Makefile instead of Kconfig.
Looks like I added this in my second version
of the patch series several months ago and didn't
revisit. I will add this to Kconfig.
> 
>> diff --git a/sound/usb/media.c b/sound/usb/media.c
>> new file mode 100644
>> index 0000000..747a66a
>> --- /dev/null
>> +++ b/sound/usb/media.c
>> @@ -0,0 +1,214 @@
>> +/*
>> + * 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"
> 
> I believe we can get rid of many include files just for MC support...
> 
> 
>> +#ifdef USE_MEDIA_CONTROLLER
> 
> This ifdef can be removed once if we build this object file
> conditionally in Makefile.

Right.

> 
> 
>> @@ -1232,7 +1244,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)
>> +		ret = media_stream_init(subs, as->pcm, direction);
> 
> Need to call snd_usb_autosuspend() in the error path.

I will add it.

> 
> 
>> --- a/sound/usb/quirks.c
>> +++ b/sound/usb/quirks.c
>> @@ -544,13 +545,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_create() fails */
>> +		media_device_create(chip, iface);
>> +	}
> 
> So far, so good...
> 
>>  	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;
> 
> Any reason to change this?

Thanks for catching this. I think I might have
added some debug code to print ret value and
missed it when I cleaned up the debug code.
I will fix it.

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] 79+ messages in thread

* Re: [PATCH 01/31] uapi/media.h: Declare interface types for ALSA
  2016-01-06 20:26 ` [PATCH 01/31] uapi/media.h: Declare interface types for ALSA Shuah Khan
@ 2016-01-28 14:59   ` Mauro Carvalho Chehab
  2016-02-01 16:07     ` Shuah Khan
  0 siblings, 1 reply; 79+ messages in thread
From: Mauro Carvalho Chehab @ 2016-01-28 14:59 UTC (permalink / raw)
  To: Shuah Khan
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Em Wed,  6 Jan 2016 13:26:50 -0700
Shuah Khan <shuahkh@osg.samsung.com> escreveu:

> From: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
> 
> Declare the interface types to be used on alsa for the new
> G_TOPOLOGY ioctl.
> 
> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
> ---
>  drivers/media/media-entity.c | 12 ++++++++++++
>  include/uapi/linux/media.h   |  8 ++++++++
>  2 files changed, 20 insertions(+)
> 
> diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
> index eb38bc3..6e02d19 100644
> --- a/drivers/media/media-entity.c
> +++ b/drivers/media/media-entity.c
> @@ -65,6 +65,18 @@ static inline const char *intf_type(struct media_interface *intf)
>  		return "v4l2-subdev";
>  	case MEDIA_INTF_T_V4L_SWRADIO:
>  		return "swradio";
> +	case MEDIA_INTF_T_ALSA_PCM_CAPTURE:
> +		return "pcm-capture";
> +	case MEDIA_INTF_T_ALSA_PCM_PLAYBACK:
> +		return "pcm-playback";
> +	case MEDIA_INTF_T_ALSA_CONTROL:
> +		return "alsa-control";
> +	case MEDIA_INTF_T_ALSA_COMPRESS:
> +		return "compress";
> +	case MEDIA_INTF_T_ALSA_RAWMIDI:
> +		return "rawmidi";
> +	case MEDIA_INTF_T_ALSA_HWDEP:
> +		return "hwdep";
>  	default:
>  		return "unknown-intf";
>  	}
> diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h
> index cacfceb..75cbe92 100644
> --- a/include/uapi/linux/media.h
> +++ b/include/uapi/linux/media.h
> @@ -252,6 +252,7 @@ struct media_links_enum {
>  
>  #define MEDIA_INTF_T_DVB_BASE	0x00000100
>  #define MEDIA_INTF_T_V4L_BASE	0x00000200
> +#define MEDIA_INTF_T_ALSA_BASE	0x00000300
>  
>  /* Interface types */
>  
> @@ -267,6 +268,13 @@ struct media_links_enum {
>  #define MEDIA_INTF_T_V4L_SUBDEV (MEDIA_INTF_T_V4L_BASE + 3)
>  #define MEDIA_INTF_T_V4L_SWRADIO (MEDIA_INTF_T_V4L_BASE + 4)
>  
> +#define MEDIA_INTF_T_ALSA_PCM_CAPTURE   (MEDIA_INTF_T_ALSA_BASE)
> +#define MEDIA_INTF_T_ALSA_PCM_PLAYBACK  (MEDIA_INTF_T_ALSA_BASE + 1)
> +#define MEDIA_INTF_T_ALSA_CONTROL       (MEDIA_INTF_T_ALSA_BASE + 2)
> +#define MEDIA_INTF_T_ALSA_COMPRESS      (MEDIA_INTF_T_ALSA_BASE + 3)
> +#define MEDIA_INTF_T_ALSA_RAWMIDI       (MEDIA_INTF_T_ALSA_BASE + 4)
> +#define MEDIA_INTF_T_ALSA_HWDEP         (MEDIA_INTF_T_ALSA_BASE + 5)

Patch looks ok, but please document the new media interfaces at KernelDoc
documentation.

> +
>  /*
>   * MC next gen API definitions
>   *

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

* Re: [PATCH 02/31] media: Add ALSA Media Controller function entities
  2016-01-06 20:26 ` [PATCH 02/31] media: Add ALSA Media Controller function entities Shuah Khan
@ 2016-01-28 15:02   ` Mauro Carvalho Chehab
  0 siblings, 0 replies; 79+ messages in thread
From: Mauro Carvalho Chehab @ 2016-01-28 15:02 UTC (permalink / raw)
  To: Shuah Khan
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Em Wed,  6 Jan 2016 13:26:51 -0700
Shuah Khan <shuahkh@osg.samsung.com> escreveu:

> Add ALSA Media Controller capture, playback, and mixer
> function entity defines.
> 
> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
> ---
>  include/uapi/linux/media.h | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h
> index 75cbe92..53a96ae 100644
> --- a/include/uapi/linux/media.h
> +++ b/include/uapi/linux/media.h
> @@ -89,6 +89,13 @@ struct media_device_info {
>  #define MEDIA_ENT_F_IO_SWRADIO		(MEDIA_ENT_F_BASE + 33)
>  
>  /*
> + * ALSA entities MEDIA_ENT_F_AUDIO_IO is for Capture and Playback
> +*/
> +#define MEDIA_ENT_F_AUDIO_CAPTURE	(MEDIA_ENT_F_BASE + 200)
> +#define MEDIA_ENT_F_AUDIO_PLAYBACK	(MEDIA_ENT_F_BASE + 201)
> +#define MEDIA_ENT_F_AUDIO_MIXER		(MEDIA_ENT_F_BASE + 202)

Please document at KernelDoc.

> +
> +/*
>   * Don't touch on those. The ranges MEDIA_ENT_F_OLD_BASE and
>   * MEDIA_ENT_F_OLD_SUBDEV_BASE are kept to keep backward compatibility
>   * with the legacy v1 API.The number range is out of range by purpose:
> @@ -130,7 +137,7 @@ struct media_device_info {
>  #define MEDIA_ENT_T_DEVNODE		MEDIA_ENT_F_OLD_BASE
>  #define MEDIA_ENT_T_DEVNODE_V4L		MEDIA_ENT_F_IO_V4L
>  #define MEDIA_ENT_T_DEVNODE_FB		(MEDIA_ENT_T_DEVNODE + 2)
> -#define MEDIA_ENT_T_DEVNODE_ALSA	(MEDIA_ENT_T_DEVNODE + 3)
> +#define MEDIA_ENT_T_DEVNODE_ALSA	MEDIA_ENT_F_AUDIO_IO

Please preserve the old number here, as we don't want to break kABI.

>  #define MEDIA_ENT_T_DEVNODE_DVB		(MEDIA_ENT_T_DEVNODE + 4)
>  
>  #define MEDIA_ENT_T_UNKNOWN		MEDIA_ENT_F_UNKNOWN

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

* Re: [PATCH 03/31] media: Media Controller register/unregister entity_notify API
  2016-01-06 20:26 ` [PATCH 03/31] media: Media Controller register/unregister entity_notify API Shuah Khan
@ 2016-01-28 15:13   ` Mauro Carvalho Chehab
  2016-01-28 17:09     ` Shuah Khan
  0 siblings, 1 reply; 79+ messages in thread
From: Mauro Carvalho Chehab @ 2016-01-28 15:13 UTC (permalink / raw)
  To: Shuah Khan
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Em Wed,  6 Jan 2016 13:26:52 -0700
Shuah Khan <shuahkh@osg.samsung.com> escreveu:

> 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 | 61 ++++++++++++++++++++++++++++++++++++++++++++
>  include/media/media-device.h | 25 ++++++++++++++++++
>  2 files changed, 86 insertions(+)
> 
> diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
> index b786b10..20c85a9 100644
> --- a/drivers/media/media-device.c
> +++ b/drivers/media/media-device.c
> @@ -536,6 +536,7 @@ static void media_device_release(struct media_devnode *mdev)
>  int __must_check media_device_register_entity(struct media_device *mdev,
>  					      struct media_entity *entity)
>  {
> +	struct media_entity_notify *notify, *next;
>  	unsigned int i;
>  	int ret;
>  
> @@ -575,6 +576,11 @@ int __must_check media_device_register_entity(struct media_device *mdev,
>  		media_gobj_create(mdev, MEDIA_GRAPH_PAD,
>  			       &entity->pads[i].graph_obj);
>  
> +	/* invoke entity_notify callbacks */
> +	list_for_each_entry_safe(notify, next, &mdev->entity_notify, list) {
> +		(notify)->notify(entity, notify->notify_data);
> +	}
> +
>  	spin_unlock(&mdev->lock);
>  
>  	return 0;
> @@ -608,6 +614,8 @@ static void __media_device_unregister_entity(struct media_entity *entity)
>  	/* Remove the entity */
>  	media_gobj_destroy(&entity->graph_obj);
>  
> +	/* invoke entity_notify callbacks to handle entity removal?? */
> +
>  	entity->graph_obj.mdev = NULL;
>  }
>  
> @@ -633,6 +641,7 @@ int __must_check media_device_init(struct media_device *mdev)
>  	INIT_LIST_HEAD(&mdev->interfaces);
>  	INIT_LIST_HEAD(&mdev->pads);
>  	INIT_LIST_HEAD(&mdev->links);
> +	INIT_LIST_HEAD(&mdev->entity_notify);
>  	spin_lock_init(&mdev->lock);
>  	mutex_init(&mdev->graph_mutex);
>  	ida_init(&mdev->entity_internal_idx);
> @@ -680,11 +689,59 @@ int __must_check __media_device_register(struct media_device *mdev,
>  }
>  EXPORT_SYMBOL_GPL(__media_device_register);
>  
> +/**
> + * 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
> + */

Please put the documentation only at the header files. Please mention that
it locks the addition using the mdev->lock spinlock.

Also, please follow the format that we're using with other KernelDoc
tags:

/**
 * function() - short description
 *
 * @foo:	foo description
 * @bar:	bar description
 *
 * detailed description
 */

In case of doubts, please check Documentation/kernel-doc-nano-HOWTO.txt.

Don't forget to check if the documentation looks sane by compiling it
with:
	make cleandocs
	make DOCBOOKS=device-drivers.xml htmldocs

Same applies to other documentation below and on other patches in this
series.

> +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
> + * Non-locking version. Should be called with mdev->lock held.
> + */
> +static void __media_device_unregister_entity_notify(struct media_device *mdev,
> +					struct media_entity_notify *nptr)

__must_check

> +{
> +	list_del(&nptr->list);
> +}
> +
> +/**
> + * 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);
> +	__media_device_unregister_entity_notify(mdev, nptr);
> +	spin_unlock(&mdev->lock);
> +}
> +EXPORT_SYMBOL_GPL(media_device_unregister_entity_notify);
> +
>  void media_device_unregister(struct media_device *mdev)
>  {
>  	struct media_entity *entity;
>  	struct media_entity *next;
>  	struct media_interface *intf, *tmp_intf;
> +	struct media_entity_notify *notify, *nextp;
>  
>  	if (mdev == NULL)
>  		return;
> @@ -701,6 +758,10 @@ void media_device_unregister(struct media_device *mdev)
>  	list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list)
>  		__media_device_unregister_entity(entity);
>  
> +	/* Remove all entity_notify callbacks from the media device */
> +	list_for_each_entry_safe(notify, nextp, &mdev->entity_notify, list)
> +		__media_device_unregister_entity_notify(mdev, notify);
> +
>  	/* Remove all interfaces from the media device */
>  	list_for_each_entry_safe(intf, tmp_intf, &mdev->interfaces,
>  				 graph_obj.list) {
> diff --git a/include/media/media-device.h b/include/media/media-device.h
> index 122963a..6520d1c 100644
> --- a/include/media/media-device.h
> +++ b/include/media/media-device.h
> @@ -264,6 +264,12 @@
>  struct ida;
>  struct device;
>  
> +struct media_entity_notify {
> +	struct list_head list;
> +	void *notify_data;
> +	void (*notify)(struct media_entity *entity, void *notify_data);
> +};

Please document the structure.

> +
>  /**
>   * struct media_device - Media device
>   * @dev:	Parent device
> @@ -319,6 +325,9 @@ struct media_device {
>  	struct list_head pads;
>  	struct list_head links;
>  
> +	/* notify callback list invoked when a new entity is registered */
> +	struct list_head entity_notify;
> +

Please document the new field at the Kernel-doc header.

>  	/* Protects the graph objects creation/removal */
>  	spinlock_t lock;
>  	/* Serializes graph operations. */
> @@ -497,6 +506,11 @@ int __must_check media_device_register_entity(struct media_device *mdev,
>   */
>  void media_device_unregister_entity(struct media_entity *entity);
>  
> +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);
> +

Documentation?

>  /**
>   * media_device_get_devres() -	get media device as device resource
>   *				creates if one doesn't exist
> @@ -552,6 +566,17 @@ static inline int media_device_register_entity(struct media_device *mdev,
>  static inline void media_device_unregister_entity(struct media_entity *entity)
>  {
>  }
> +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 struct media_device *media_device_get_devres(struct device *dev)
>  {
>  	return NULL;

Documentation?

Regards,
Mauro

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

* Re: [PATCH 04/31] media: Media Controller enable/disable source handler API
  2016-01-06 20:26 ` [PATCH 04/31] media: Media Controller enable/disable source handler API Shuah Khan
@ 2016-01-28 15:19   ` Mauro Carvalho Chehab
  2016-01-28 16:28     ` Shuah Khan
  0 siblings, 1 reply; 79+ messages in thread
From: Mauro Carvalho Chehab @ 2016-01-28 15:19 UTC (permalink / raw)
  To: Shuah Khan
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Em Wed,  6 Jan 2016 13:26:53 -0700
Shuah Khan <shuahkh@osg.samsung.com> escreveu:

> Add new fields to struct media_device to add enable_source, and
> disable_source handlers, and source_priv to stash driver private
> data that is need to run these handlers. The enable_source handler
> finds source entity for the passed in 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 these
> handlers and private data 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 it and start pipeline between
> the source and the entity. The disable_source handler deactivates the
> link and stops the pipeline. This handler can be invoked from the
> 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 | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/include/media/media-device.h b/include/media/media-device.h
> index 6520d1c..04b6c2e 100644
> --- a/include/media/media-device.h
> +++ b/include/media/media-device.h
> @@ -333,6 +333,25 @@ struct media_device {
>  	/* Serializes graph operations. */
>  	struct mutex graph_mutex;
>  
> +	/* Handlers to find source entity for the sink entity and
> +	 * check if it is available, and activate the link using
> +	 * media_entity_setup_link() interface and start pipeline
> +	 * from the source to the entity.
> +	 * 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.
> +	 * Bridge driver sets source_priv with information
> +	 * necessary to run enable/disable source handlers.
> +	 *
> +	 * 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.
> +	*/
> +	void *source_priv;
> +	int (*enable_source)(struct media_entity *entity,
> +			     struct media_pipeline *pipe);
> +	void (*disable_source)(struct media_entity *entity);

Please document the new fields at the right place (Kernel-doc
comment declared before the struct).

Is this used by the media core? If so, please but the implementation
here, to make it clearer why we need those things.

> +
>  	int (*link_notify)(struct media_link *link, u32 flags,
>  			   unsigned int notification);
>  };

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

* Re: [PATCH 08/31] media: v4l-core add v4l_enable/disable_media_tuner() helper functions
  2016-01-06 20:26 ` [PATCH 08/31] media: v4l-core add v4l_enable/disable_media_tuner() helper functions Shuah Khan
@ 2016-01-28 15:26   ` Mauro Carvalho Chehab
  2016-01-28 17:12     ` Shuah Khan
  0 siblings, 1 reply; 79+ messages in thread
From: Mauro Carvalho Chehab @ 2016-01-28 15:26 UTC (permalink / raw)
  To: Shuah Khan
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Em Wed,  6 Jan 2016 13:26:57 -0700
Shuah Khan <shuahkh@osg.samsung.com> escreveu:

> Add a new interfaces to be used by v4l-core to invoke enable
> source and disable_source handlers in the media_device. The
> enable_source helper function invokes the enable_source handler
> to find tuner entity connected to the decoder and check is it
> is available or busy. If tuner is available, link is activated
> and pipeline is started. The disable_source helper function
> invokes the disable_source handler to deactivate and stop the
> pipeline.
> 
> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
> ---
>  drivers/media/v4l2-core/v4l2-dev.c | 27 +++++++++++++++++++++++++++
>  include/media/v4l2-dev.h           |  4 ++++
>  2 files changed, 31 insertions(+)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
> index d8e5994..f06da6e 100644
> --- a/drivers/media/v4l2-core/v4l2-dev.c
> +++ b/drivers/media/v4l2-core/v4l2-dev.c
> @@ -233,6 +233,33 @@ struct video_device *video_devdata(struct file *file)
>  }
>  EXPORT_SYMBOL(video_devdata);
>  
> +int v4l_enable_media_tuner(struct video_device *vdev)

IMHO, the better is to put those MC ancillary routines on a separate file.
Hans suggested to add them at v4l2-mc.h and v4l2-mc.h.

> +{
> +#ifdef CONFIG_MEDIA_CONTROLLER
> +	struct media_device *mdev = vdev->entity.graph_obj.mdev;
> +	int ret;
> +
> +	if (!mdev || !mdev->enable_source)
> +		return 0;
> +	ret = mdev->enable_source(&vdev->entity, &vdev->pipe);
> +	if (ret)
> +		return -EBUSY;
> +	return 0;
> +#endif /* CONFIG_MEDIA_CONTROLLER */
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(v4l_enable_media_tuner);
> +
> +void v4l_disable_media_tuner(struct video_device *vdev)
> +{
> +#ifdef CONFIG_MEDIA_CONTROLLER
> +	struct media_device *mdev = vdev->entity.graph_obj.mdev;
> +
> +	if (mdev && mdev->disable_source)
> +		mdev->disable_source(&vdev->entity);
> +#endif /* CONFIG_MEDIA_CONTROLLER */
> +}
> +EXPORT_SYMBOL_GPL(v4l_disable_media_tuner);
>  
>  /* Priority handling */
>  
> diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
> index eeabf20..68999a3 100644
> --- a/include/media/v4l2-dev.h
> +++ b/include/media/v4l2-dev.h
> @@ -87,6 +87,7 @@ struct video_device
>  #if defined(CONFIG_MEDIA_CONTROLLER)
>  	struct media_entity entity;
>  	struct media_intf_devnode *intf_devnode;
> +	struct media_pipeline pipe;
>  #endif
>  	/* device ops */
>  	const struct v4l2_file_operations *fops;
> @@ -176,6 +177,9 @@ void video_unregister_device(struct video_device *vdev);
>     latter can also be used for video_device->release(). */
>  struct video_device * __must_check video_device_alloc(void);
>  
> +int v4l_enable_media_tuner(struct video_device *vdev);
> +void v4l_disable_media_tuner(struct video_device *vdev);

Documentation?

> +
>  /* this release function frees the vdev pointer */
>  void video_device_release(struct video_device *vdev);
>  

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

* Re: [PATCH 09/31] media: v4l2-core add v4l_vb2q_enable_media_tuner() helper
  2016-01-06 20:26 ` [PATCH 09/31] media: v4l2-core add v4l_vb2q_enable_media_tuner() helper Shuah Khan
@ 2016-01-28 15:29   ` Mauro Carvalho Chehab
  2016-01-28 17:31     ` Shuah Khan
  0 siblings, 1 reply; 79+ messages in thread
From: Mauro Carvalho Chehab @ 2016-01-28 15:29 UTC (permalink / raw)
  To: Shuah Khan
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Em Wed,  6 Jan 2016 13:26:58 -0700
Shuah Khan <shuahkh@osg.samsung.com> escreveu:

> Add a new v4l_vb2q_enable_media_tuner() wrapper function
> to be called from v4l2-core to enable the media tuner with
> videobuf2 queue, when the calling frunction has the videobuf2
> queue and doesn't have the struct video_device associated with
> the queue handy as in the case of vb2_core_streamon(). This
> function simply calls v4l_enable_media_tuner() passing in the
> pointer to struct video_device.
> 
> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
> ---
>  drivers/media/v4l2-core/v4l2-dev.c | 21 +++++++++++++++++++++
>  include/media/v4l2-dev.h           |  1 +
>  2 files changed, 22 insertions(+)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
> index f06da6e..9ef675a 100644
> --- a/drivers/media/v4l2-core/v4l2-dev.c
> +++ b/drivers/media/v4l2-core/v4l2-dev.c
> @@ -30,6 +30,7 @@
>  #include <media/v4l2-common.h>
>  #include <media/v4l2-device.h>
>  #include <media/v4l2-ioctl.h>
> +#include <media/videobuf2-core.h>
>  
>  #define VIDEO_NUM_DEVICES	256
>  #define VIDEO_NAME              "video4linux"
> @@ -261,6 +262,26 @@ void v4l_disable_media_tuner(struct video_device *vdev)
>  }
>  EXPORT_SYMBOL_GPL(v4l_disable_media_tuner);
>  
> +/**
> + * v4l_vb2q_enable_media_tuner - Wrapper for v4l_enable_media_tuner()
> + * @q:         videobuf2 queue
> + *
> + * This function is intended to be called from v4l2-core
> + * to enable the media tuner with videobuf2 queue, when
> + * the calling frunction has the videobuf2 queue and doesn't

	typo: function

> + * have the struct video_device associated with the
> + * queue handy as in the case of vb2_core_streamon(). This
> + * function simply calls v4l_enable_media_tuner() passing
> + * in the pointer to struct video_device.

The hole description seems confusing. I'm not seeing the light
about why this is needed.

> + */
> +int v4l_vb2q_enable_media_tuner(struct vb2_queue *q)
> +{
> +	struct v4l2_fh *fh = q->owner;
> +
> +	return v4l_enable_media_tuner(fh->vdev);
> +}
> +EXPORT_SYMBOL_GPL(v4l_vb2q_enable_media_tuner);
> +
>  /* Priority handling */
>  
>  static inline bool prio_is_valid(enum v4l2_priority prio)
> diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
> index 68999a3..1948097 100644
> --- a/include/media/v4l2-dev.h
> +++ b/include/media/v4l2-dev.h
> @@ -179,6 +179,7 @@ struct video_device * __must_check video_device_alloc(void);
>  
>  int v4l_enable_media_tuner(struct video_device *vdev);
>  void v4l_disable_media_tuner(struct video_device *vdev);
> +int v4l_vb2q_enable_media_tuner(struct vb2_queue *q);

Documentation?

>  
>  /* this release function frees the vdev pointer */
>  void video_device_release(struct video_device *vdev);

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

* Re: [PATCH 13/31] media: au0828 fix au0828_create_media_graph() entity checks
  2016-01-06 20:27 ` [PATCH 13/31] media: au0828 fix au0828_create_media_graph() entity checks Shuah Khan
@ 2016-01-28 15:37   ` Mauro Carvalho Chehab
  2016-01-28 18:57     ` Shuah Khan
  0 siblings, 1 reply; 79+ messages in thread
From: Mauro Carvalho Chehab @ 2016-01-28 15:37 UTC (permalink / raw)
  To: Shuah Khan
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Em Wed,  6 Jan 2016 13:27:02 -0700
Shuah Khan <shuahkh@osg.samsung.com> escreveu:

> au0828_create_media_graph() doesn't do any checks to determine,
> if vbi_dev, vdev, and input entities have been registered prior
> to creating pad links. Checking graph_obj.mdev field works as
> the graph_obj.mdev field gets initialized in the entity register
> interface. Fix it to check graph_obj.mdev field before creating
> pad links.

> 
> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
> ---
>  drivers/media/usb/au0828/au0828-core.c | 27 +++++++++++++++++----------
>  1 file changed, 17 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
> index f46fb43..8ef7c71 100644
> --- a/drivers/media/usb/au0828/au0828-core.c
> +++ b/drivers/media/usb/au0828/au0828-core.c
> @@ -291,20 +291,27 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
>  		if (ret)
>  			return ret;
>  	}
> -	ret = media_create_pad_link(decoder, AU8522_PAD_VID_OUT,
> -				    &dev->vdev.entity, 0,
> -				    MEDIA_LNK_FL_ENABLED);
> -	if (ret)
> -		return ret;
> -	ret = media_create_pad_link(decoder, AU8522_PAD_VBI_OUT,
> -				    &dev->vbi_dev.entity, 0,
> -				    MEDIA_LNK_FL_ENABLED);
> -	if (ret)
> -		return ret;
> +	if (dev->vdev.entity.graph_obj.mdev) {
> +		ret = media_create_pad_link(decoder, AU8522_PAD_VID_OUT,
> +					    &dev->vdev.entity, 0,
> +					    MEDIA_LNK_FL_ENABLED);
> +		if (ret)
> +			return ret;
> +	}

Those new if() doesn't look right. We can't continue if the entities
weren't registered, as the graph would have troubles. The logic should
ensure that the entities will always be created before running 
au0828_create_media_graph(). If this is not the case, some async
logic is needed to ensure that.

> +	if (dev->vbi_dev.entity.graph_obj.mdev) {
> +		ret = media_create_pad_link(decoder, AU8522_PAD_VBI_OUT,
> +					    &dev->vbi_dev.entity, 0,
> +					    MEDIA_LNK_FL_ENABLED);
> +		if (ret)
> +			return ret;
> +	}
>  
>  	for (i = 0; i < AU0828_MAX_INPUT; i++) {
>  		struct media_entity *ent = &dev->input_ent[i];
>  
> +		if (!ent->graph_obj.mdev)
> +			continue;
> +
>  		if (AUVI_INPUT(i).type == AU0828_VMUX_UNDEFINED)
>  			break;
>  

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

* Re: [PATCH 15/31] media: dvb-frontend invoke enable/disable_source handlers
  2016-01-06 20:27 ` [PATCH 15/31] media: dvb-frontend invoke enable/disable_source handlers Shuah Khan
@ 2016-01-28 15:53   ` Mauro Carvalho Chehab
  2016-01-28 16:07     ` One Thousand Gnomes
  0 siblings, 1 reply; 79+ messages in thread
From: Mauro Carvalho Chehab @ 2016-01-28 15:53 UTC (permalink / raw)
  To: Shuah Khan
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Em Wed,  6 Jan 2016 13:27:04 -0700
Shuah Khan <shuahkh@osg.samsung.com> escreveu:

> 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.

That's wrong, as DVB can be opened on read-only mode, where
it won't be changing anything.

Also, I don't think POSIX allows to return an error like EBUSY
on open:
	http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html

> In addition, make a change to invoke
> enable_source and disable_source handlers to check for
> tuner availability. The enable_source handler finds tuner
> entity connected to the decoder and check is it is available
> or busy. If tuner is available, link is activated and pipeline
> is started. The disable_source handler to deactivate and stop
> the pipeline. dvb_enable_media_tuner() is removed as it is no
> longer necessary with dvb invoking enable_source and
> disable_source handlers. pipe_start_entity field is removed
> and pipe field is moved to dvb_frontend from dvb_frontend_private.
> 
> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
> ---
>  drivers/media/dvb-core/dvb_frontend.c | 139 +++++-----------------------------
>  drivers/media/dvb-core/dvb_frontend.h |   3 +
>  2 files changed, 24 insertions(+), 118 deletions(-)
> 
> diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
> index 4008064..c15f3d8 100644
> --- a/drivers/media/dvb-core/dvb_frontend.c
> +++ b/drivers/media/dvb-core/dvb_frontend.c
> @@ -131,11 +131,6 @@ struct dvb_frontend_private {
>  	int quality;
>  	unsigned int check_wrapped;
>  	enum dvbfe_search algo_status;
> -
> -#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
> -	struct media_pipeline pipe;
> -	struct media_entity *pipe_start_entity;
> -#endif
>  };
>  
>  static void dvb_frontend_wakeup(struct dvb_frontend *fe);
> @@ -596,104 +591,12 @@ static void dvb_frontend_wakeup(struct dvb_frontend *fe)
>  	wake_up_interruptible(&fepriv->wait_queue);
>  }
>  
> -/**
> - * dvb_enable_media_tuner() - tries to enable the DVB tuner
> - *
> - * @fe:		struct dvb_frontend pointer
> - *
> - * This function ensures that just one media tuner is enabled for a given
> - * frontend. It has two different behaviors:
> - * - For trivial devices with just one tuner:
> - *   it just enables the existing tuner->fe link
> - * - For devices with more than one tuner:
> - *   It is up to the driver to implement the logic that will enable one tuner
> - *   and disable the other ones. However, if more than one tuner is enabled for
> - *   the same frontend, it will print an error message and return -EINVAL.
> - *
> - * At return, it will return the error code returned by media_entity_setup_link,
> - * or 0 if everything is OK, if no tuner is linked to the frontend or if the
> - * mdev is NULL.
> - */
> -#ifdef CONFIG_MEDIA_CONTROLLER_DVB
> -static int dvb_enable_media_tuner(struct dvb_frontend *fe)
> -{
> -	struct dvb_frontend_private *fepriv = fe->frontend_priv;
> -	struct dvb_adapter *adapter = fe->dvb;
> -	struct media_device *mdev = adapter->mdev;
> -	struct media_entity  *entity, *source;
> -	struct media_link *link, *found_link = NULL;
> -	int ret, n_links = 0, active_links = 0;
> -
> -	fepriv->pipe_start_entity = NULL;
> -
> -	if (!mdev)
> -		return 0;
> -
> -	entity = fepriv->dvbdev->entity;
> -	fepriv->pipe_start_entity = entity;
> -
> -	list_for_each_entry(link, &entity->links, list) {
> -		if (link->sink->entity == entity) {
> -			found_link = link;
> -			n_links++;
> -			if (link->flags & MEDIA_LNK_FL_ENABLED)
> -				active_links++;
> -		}
> -	}
> -
> -	if (!n_links || active_links == 1 || !found_link)
> -		return 0;
> -
> -	/*
> -	 * If a frontend has more than one tuner linked, it is up to the driver
> -	 * to select with one will be the active one, as the frontend core can't
> -	 * guess. If the driver doesn't do that, it is a bug.
> -	 */
> -	if (n_links > 1 && active_links != 1) {
> -		dev_err(fe->dvb->device,
> -			"WARNING: there are %d active links among %d tuners. This is a driver's bug!\n",
> -			active_links, n_links);
> -		return -EINVAL;
> -	}
> -
> -	source = found_link->source->entity;
> -	fepriv->pipe_start_entity = source;
> -	list_for_each_entry(link, &source->links, list) {
> -		struct media_entity *sink;
> -		int flags = 0;
> -
> -		sink = link->sink->entity;
> -		if (sink == entity)
> -			flags = MEDIA_LNK_FL_ENABLED;
> -
> -		ret = media_entity_setup_link(link, flags);
> -		if (ret) {
> -			dev_err(fe->dvb->device,
> -				"Couldn't change link %s->%s to %s. Error %d\n",
> -				source->name, sink->name,
> -				flags ? "enabled" : "disabled",
> -				ret);
> -			return ret;
> -		} else
> -			dev_dbg(fe->dvb->device,
> -				"link %s->%s was %s\n",
> -				source->name, sink->name,
> -				flags ? "ENABLED" : "disabled");
> -	}
> -	return 0;
> -}
> -#endif
> -
>  static int dvb_frontend_thread(void *data)
>  {
>  	struct dvb_frontend *fe = 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;
>  
> @@ -706,20 +609,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();
> @@ -829,12 +718,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);
> @@ -2612,9 +2495,20 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
>  		fepriv->tone = -1;
>  		fepriv->voltage = -1;
>  
> +#ifdef CONFIG_MEDIA_CONTROLLER_DVB
> +		if (fe->dvb->mdev && fe->dvb->mdev->enable_source) {
> +			ret = fe->dvb->mdev->enable_source(dvbdev->entity,
> +							   &fe->pipe);
> +			if (ret) {
> +				dev_err(fe->dvb->device,
> +					"Tuner is busy. Error %d\n", ret);
> +				goto err2;
> +			}
> +		}
> +#endif
>  		ret = dvb_frontend_start (fe);
>  		if (ret)
> -			goto err2;
> +			goto err3;
>  
>  		/*  empty event queue */
>  		fepriv->events.eventr = fepriv->events.eventw = 0;
> @@ -2624,7 +2518,12 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
>  		mutex_unlock (&adapter->mfe_lock);
>  	return ret;
>  
> +err3:
> +#ifdef CONFIG_MEDIA_CONTROLLER_DVB
> +	if (fe->dvb->mdev && fe->dvb->mdev->disable_source)
> +		fe->dvb->mdev->disable_source(dvbdev->entity);
>  err2:
> +#endif
>  	dvb_generic_release(inode, file);
>  err1:
>  	if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl)
> @@ -2653,6 +2552,10 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
>  
>  	if (dvbdev->users == -1) {
>  		wake_up(&fepriv->wait_queue);
> +#ifdef CONFIG_MEDIA_CONTROLLER_DVB
> +		if (fe->dvb->mdev && fe->dvb->mdev->disable_source)
> +			fe->dvb->mdev->disable_source(dvbdev->entity);
> +#endif
>  		if (fe->exit != DVB_FE_NO_EXIT)
>  			wake_up(&dvbdev->wait_queue);
>  		if (fe->ops.ts_bus_ctrl)
> diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h
> index 458bcce..9466906 100644
> --- a/drivers/media/dvb-core/dvb_frontend.h
> +++ b/drivers/media/dvb-core/dvb_frontend.h
> @@ -686,6 +686,9 @@ struct dvb_frontend {
>  	int (*callback)(void *adapter_priv, int component, int cmd, int arg);
>  	int id;
>  	unsigned int exit;
> +#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
> +	struct media_pipeline pipe;
> +#endif
>  };
>  
>  /**

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

* Re: [PATCH 17/31] media: au0828 video change to use v4l_enable_media_tuner()
  2016-01-06 20:27 ` [PATCH 17/31] media: au0828 video change to use v4l_enable_media_tuner() Shuah Khan
@ 2016-01-28 15:57   ` Mauro Carvalho Chehab
  2016-01-28 19:21     ` Shuah Khan
  0 siblings, 1 reply; 79+ messages in thread
From: Mauro Carvalho Chehab @ 2016-01-28 15:57 UTC (permalink / raw)
  To: Shuah Khan
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Em Wed,  6 Jan 2016 13:27:06 -0700
Shuah Khan <shuahkh@osg.samsung.com> escreveu:

> au0828 is changed to use v4l_enable_media_tuner() to check for
> tuner availability from vidioc_g_tuner(), and au0828_v4l2_close(),
> before changing tuner settings. If tuner isn't free, return busy
> condition from vidioc_g_tuner() and in au0828_v4l2_close() tuner
> is left untouched without powering down to save energy.

Did you test the code when the input is not a tuner, but, instead,
Composite or S-Video connector, as shown at:
	https://mchehab.fedorapeople.org/mc-next-gen/au0828.png

I guess calling it v4l-enable_media_tuner() is not right, specially
since there are hybrid devices that have DTV (via DVB API) and
S-Video and/or Composite/RCA capture via V4L2 API.

> 
> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
> ---
>  drivers/media/usb/au0828/au0828-video.c | 14 ++++++++++++--
>  1 file changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
> index 32bcc56..ed3ba05 100644
> --- a/drivers/media/usb/au0828/au0828-video.c
> +++ b/drivers/media/usb/au0828/au0828-video.c
> @@ -1010,8 +1010,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 = v4l_enable_media_tuner(vdev);
> +		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
> @@ -1412,10 +1416,16 @@ 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);
> +	struct video_device *vfd = video_devdata(file);
> +	int ret;
>  
>  	if (t->index != 0)
>  		return -EINVAL;
>  
> +	ret = v4l_enable_media_tuner(vfd);
> +	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);
>  

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

* Re: [PATCH 15/31] media: dvb-frontend invoke enable/disable_source handlers
  2016-01-28 15:53   ` Mauro Carvalho Chehab
@ 2016-01-28 16:07     ` One Thousand Gnomes
  2016-01-28 16:59       ` Shuah Khan
  0 siblings, 1 reply; 79+ messages in thread
From: One Thousand Gnomes @ 2016-01-28 16:07 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: Shuah Khan, tiwai, clemens, hans.verkuil, laurent.pinchart,
	sakari.ailus, javier, pawel, m.szyprowski, kyungmin.park, perex,
	arnd, dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

On Thu, 28 Jan 2016 13:53:04 -0200
Mauro Carvalho Chehab <mchehab@osg.samsung.com> wrote:

> Em Wed,  6 Jan 2016 13:27:04 -0700
> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> 
> > 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.  
> 
> That's wrong, as DVB can be opened on read-only mode, where
> it won't be changing anything.
> 
> Also, I don't think POSIX allows to return an error like EBUSY
> on open:
> 	http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html

It doesn't document all the errors you may return. Quite a lot of
kernel drivers return EBUSY when they are "single open" things.

POSIX documents certain cases that *must* error and what the error code
is. It documents certain possible failures and what their error code is.
Beyond that it's up to you.

Alan

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

* Re: [PATCH 04/31] media: Media Controller enable/disable source handler API
  2016-01-28 15:19   ` Mauro Carvalho Chehab
@ 2016-01-28 16:28     ` Shuah Khan
  2016-01-28 17:15       ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-28 16:28 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel, Shuah Khan

On 01/28/2016 08:19 AM, Mauro Carvalho Chehab wrote:
> Em Wed,  6 Jan 2016 13:26:53 -0700
> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> 
>> Add new fields to struct media_device to add enable_source, and
>> disable_source handlers, and source_priv to stash driver private
>> data that is need to run these handlers. The enable_source handler
>> finds source entity for the passed in 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 these
>> handlers and private data 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 it and start pipeline between
>> the source and the entity. The disable_source handler deactivates the
>> link and stops the pipeline. This handler can be invoked from the
>> 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 | 19 +++++++++++++++++++
>>  1 file changed, 19 insertions(+)
>>
>> diff --git a/include/media/media-device.h b/include/media/media-device.h
>> index 6520d1c..04b6c2e 100644
>> --- a/include/media/media-device.h
>> +++ b/include/media/media-device.h
>> @@ -333,6 +333,25 @@ struct media_device {
>>  	/* Serializes graph operations. */
>>  	struct mutex graph_mutex;
>>  
>> +	/* Handlers to find source entity for the sink entity and
>> +	 * check if it is available, and activate the link using
>> +	 * media_entity_setup_link() interface and start pipeline
>> +	 * from the source to the entity.
>> +	 * 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.
>> +	 * Bridge driver sets source_priv with information
>> +	 * necessary to run enable/disable source handlers.
>> +	 *
>> +	 * 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.
>> +	*/
>> +	void *source_priv;
>> +	int (*enable_source)(struct media_entity *entity,
>> +			     struct media_pipeline *pipe);
>> +	void (*disable_source)(struct media_entity *entity);
> 
> Please document the new fields at the right place (Kernel-doc
> comment declared before the struct).
> 
> Is this used by the media core? If so, please but the implementation
> here, to make it clearer why we need those things.
> 
>> +
>>  	int (*link_notify)(struct media_link *link, u32 flags,
>>  			   unsigned int notification);
>>  };

Hi Mauro,

I don't have any problems adding documentation. I would
like to add documentation in a add-on to the patch series.
The main reason is once I add documentation to this patch,
the rest of the patches on this file don't apply and require
rebase and rework. I went though a couple of rounds of this
while you were adding documentation to the interfaces you
added.

How about I add the documentation patches at the end of
the patch series? I am concerned that rebasing for the
documentation changes will introduce bugs. Are you okay
with this proposal?

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] 79+ messages in thread

* Re: [PATCH 20/31] media: au0828 change to register/unregister entity_notify hook
  2016-01-06 20:27 ` [PATCH 20/31] media: au0828 change to register/unregister entity_notify hook Shuah Khan
@ 2016-01-28 16:36   ` Mauro Carvalho Chehab
  2016-01-28 20:05     ` Shuah Khan
  0 siblings, 1 reply; 79+ messages in thread
From: Mauro Carvalho Chehab @ 2016-01-28 16:36 UTC (permalink / raw)
  To: Shuah Khan
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Em Wed,  6 Jan 2016 13:27:09 -0700
Shuah Khan <shuahkh@osg.samsung.com> escreveu:

> au0828 registers entity_notify hook to create media graph for
> the device. This handler runs whenvere a new entity gets added

typo: whenever.

> to the media device. It creates necessary links from video, vbi,
> and ALSA entities to decoder and links tuner and decoder entities.
> As this handler runs as entities get added, it has to maintain
> state on the links it already created. New fields are added to
> au0828_dev to keep this state information. entity_notify gets
> unregistered before media_device unregister.

Bty, please avoid long paragraphs at the patch description, 
and please try to be clearer on your patch descriptions... That
makes boring to read everything. :-;

> 
> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
> ---
>  drivers/media/usb/au0828/au0828-core.c | 104 +++++++++++++++++++++++----------
>  drivers/media/usb/au0828/au0828.h      |   6 ++
>  2 files changed, 78 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
> index 6ef177c..a381660 100644
> --- a/drivers/media/usb/au0828/au0828-core.c
> +++ b/drivers/media/usb/au0828/au0828-core.c
> @@ -137,6 +137,8 @@ static void au0828_unregister_media_device(struct au0828_dev *dev)
>  #ifdef CONFIG_MEDIA_CONTROLLER
>  	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);
>  		media_device_cleanup(dev->media_dev);
>  		dev->media_dev = NULL;
> @@ -263,11 +265,16 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
>  	struct media_device *mdev = dev->media_dev;
>  	struct media_entity *entity;
>  	struct media_entity *tuner = NULL, *decoder = NULL;
> +	struct media_entity *audio_capture = NULL;
>  	int i, ret;
>  
>  	if (!mdev)
>  		return 0;
>  
> +	if (dev->tuner_linked && dev->vdev_linked && dev->vbi_linked &&
> +	    dev->audio_capture_linked)
> +		return 0;
> +
>  	media_device_for_each_entity(entity, mdev) {
>  		switch (entity->function) {
>  		case MEDIA_ENT_F_TUNER:
> @@ -276,6 +283,9 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
>  		case MEDIA_ENT_F_ATV_DECODER:
>  			decoder = entity;
>  			break;
> +		case MEDIA_ENT_F_AUDIO_CAPTURE:
> +			audio_capture = entity;
> +			break;
>  		}
>  	}
>  
> @@ -285,60 +295,77 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
>  	if (!decoder)
>  		return -EINVAL;
>  
> -	if (tuner) {
> +	if (tuner  && !dev->tuner_linked) {
> +		dev->tuner = tuner;
>  		ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT,
>  					    decoder, 0,
>  					    MEDIA_LNK_FL_ENABLED);
>  		if (ret)
>  			return ret;
> +		dev->tuner_linked = 1;
>  	}
> -	if (dev->vdev.entity.graph_obj.mdev) {
> +	if (dev->vdev.entity.graph_obj.mdev && !dev->vdev_linked) {
>  		ret = media_create_pad_link(decoder, AU8522_PAD_VID_OUT,
>  					    &dev->vdev.entity, 0,
>  					    MEDIA_LNK_FL_ENABLED);
>  		if (ret)
>  			return ret;
> +		dev->vdev_linked = 1;
>  	}
> -	if (dev->vbi_dev.entity.graph_obj.mdev) {
> +	if (dev->vbi_dev.entity.graph_obj.mdev && !dev->vbi_linked) {
>  		ret = media_create_pad_link(decoder, AU8522_PAD_VBI_OUT,
>  					    &dev->vbi_dev.entity, 0,
>  					    MEDIA_LNK_FL_ENABLED);
>  		if (ret)
>  			return ret;
> -	}
> -
> -	for (i = 0; i < AU0828_MAX_INPUT; i++) {
> -		struct media_entity *ent = &dev->input_ent[i];
> +		dev->vbi_linked = 1;
>  
> -		if (!ent->graph_obj.mdev)
> -			continue;
> +		/*
> +		 * Input entities are registered before vbi entity,
> +		 * create graph nodes for them after vbi is created
> +		*/
> +		for (i = 0; i < AU0828_MAX_INPUT; i++) {
> +			struct media_entity *ent = &dev->input_ent[i];
>  
> -		if (AUVI_INPUT(i).type == AU0828_VMUX_UNDEFINED)
> -			break;
> +			if (!ent->graph_obj.mdev)
> +				continue;
>  
> -		switch (AUVI_INPUT(i).type) {
> -		case AU0828_VMUX_CABLE:
> -		case AU0828_VMUX_TELEVISION:
> -		case AU0828_VMUX_DVB:
> -			if (!tuner)
> +			if (AUVI_INPUT(i).type == AU0828_VMUX_UNDEFINED)
>  				break;
>  
> -			ret = media_create_pad_link(ent, 0, tuner,
> -						    TUNER_PAD_RF_INPUT,
> -						    MEDIA_LNK_FL_ENABLED);
> -			if (ret)
> -				return ret;
> -			break;
> -		case AU0828_VMUX_COMPOSITE:
> -		case AU0828_VMUX_SVIDEO:
> -		default: /* AU0828_VMUX_DEBUG */
> -			/* FIXME: fix the decoder PAD */
> -			ret = media_create_pad_link(ent, 0, decoder, 0, 0);
> -			if (ret)
> -				return ret;
> -			break;
> +			switch (AUVI_INPUT(i).type) {
> +			case AU0828_VMUX_CABLE:
> +			case AU0828_VMUX_TELEVISION:
> +			case AU0828_VMUX_DVB:
> +				if (!tuner)
> +					break;
> +
> +				ret = media_create_pad_link(ent, 0, tuner,
> +							TUNER_PAD_RF_INPUT,
> +							MEDIA_LNK_FL_ENABLED);
> +				if (ret)
> +					return ret;
> +				break;
> +			case AU0828_VMUX_COMPOSITE:
> +			case AU0828_VMUX_SVIDEO:
> +			default: /* AU0828_VMUX_DEBUG */
> +				/* FIXME: fix the decoder PAD */
> +				ret = media_create_pad_link(ent, 0, decoder,
> +							    0, 0);
> +				if (ret)
> +					return ret;
> +				break;
> +			}
>  		}
>  	}
> +	if (audio_capture && !dev->audio_capture_linked) {
> +		ret = media_create_pad_link(decoder, AU8522_PAD_AUDIO_OUT,
> +					    audio_capture, 0,
> +					    MEDIA_LNK_FL_ENABLED);
> +		if (ret)
> +			return ret;
> +		dev->audio_capture_linked = 1;
> +	}
>  #endif
>  	return 0;
>  }
> @@ -349,8 +376,10 @@ static int au0828_media_device_register(struct au0828_dev *dev,
>  #ifdef CONFIG_MEDIA_CONTROLLER
>  	int ret;
>  
> -	if (dev->media_dev &&
> -		!media_devnode_is_registered(&dev->media_dev->devnode)) {
> +	if (!dev->media_dev)
> +		return 0;
> +
> +	if (!media_devnode_is_registered(&dev->media_dev->devnode)) {
>  
>  		/* register media device */
>  		ret = media_device_register(dev->media_dev);
> @@ -360,6 +389,17 @@ static int au0828_media_device_register(struct au0828_dev *dev,
>  			return ret;
>  		}
>  	}
> +	/* register entity_notify callback */
> +	dev->entity_notify.notify_data = (void *) dev;
> +	dev->entity_notify.notify = (void *) au0828_create_media_graph;
> +	ret = media_device_register_entity_notify(dev->media_dev,
> +						  &dev->entity_notify);
> +	if (ret) {
> +		dev_err(&udev->dev,
> +			"Media Device register entity_notify Error: %d\n",
> +			ret);
> +		return ret;
> +	}
>  #endif
>  	return 0;
>  }
> diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
> index 8276072..cfb6d58 100644
> --- a/drivers/media/usb/au0828/au0828.h
> +++ b/drivers/media/usb/au0828/au0828.h
> @@ -283,6 +283,12 @@ struct au0828_dev {
>  	struct media_entity *decoder;
>  	struct media_entity input_ent[AU0828_MAX_INPUT];
>  	struct media_pad input_pad[AU0828_MAX_INPUT];
> +	struct media_entity_notify entity_notify;
> +	struct media_entity *tuner;
> +	bool tuner_linked;
> +	bool vdev_linked;
> +	bool vbi_linked;
> +	bool audio_capture_linked;

Hmm... now I understood why you did the changes on patch 13/31.

I see what you're doing, but not sure if this is a good idea
to have one bool for each possible device. On au0828, the
topology is actually simpler than on other devices, as it
currently supports a very few set of I2C devices, but on other
drivers, things can be messier.

See, for example, two graphs for em28xx-based devices:
	https://mchehab.fedorapeople.org/mc-next-gen/wintv_usb2.png
	https://mchehab.fedorapeople.org/mc-next-gen/hvr_950.png

On the first graph, the tuner is not connected directly to the
analog demod, but, instead, to two other elements:
	- tda9887 - for video
	- msp3400 - for audio

IMHO, the best way to handle graph setup is that each driver
should handle the links that belong only to them synchronously,
after creating/registering all the entities.

So, only the links between two drivers would be asynchronously
created. So, In the case of au0828:

- au0828 core will create the connector entities;

- I2C drivers will create their own entities;

- DVB core will create the DVB entities/interfaces;

- V4L core will create V4L interfaces and I/O entities;

- au0828 V4L driver will create all V4L links, after
  ensuring that the needed I2C drivers were bound;

- snd-usb-audio will create all ALSA-specific entities links;

The V4L->ALSA links will either be created by au0828-core,
via the notification handler.

With that in mind, I don't see any need to touch at
au0828_create_media_graph(). It will need an extra function
to handle the notification when ALSA gets registered
(or when the entities there are added, whatever works best).

Regards,
Mauro






>  #endif
>  };
>  

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

* Re: [PATCH 22/31] media: dvb-core create tuner to demod pad link in disabled state
  2016-01-06 20:27 ` [PATCH 22/31] media: dvb-core create tuner to demod pad link in disabled state Shuah Khan
@ 2016-01-28 16:38   ` Mauro Carvalho Chehab
  2016-01-28 20:09     ` Shuah Khan
  0 siblings, 1 reply; 79+ messages in thread
From: Mauro Carvalho Chehab @ 2016-01-28 16:38 UTC (permalink / raw)
  To: Shuah Khan
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Em Wed,  6 Jan 2016 13:27:11 -0700
Shuah Khan <shuahkh@osg.samsung.com> escreveu:

> Create tuner to demod pad link in disabled state to help avoid
> disable step when tuner resource is requested by video or audio.
> 
> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
> ---
>  drivers/media/dvb-core/dvbdev.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
> index b56e008..1d10fa6 100644
> --- a/drivers/media/dvb-core/dvbdev.c
> +++ b/drivers/media/dvb-core/dvbdev.c
> @@ -593,8 +593,9 @@ int dvb_create_media_graph(struct dvb_adapter *adap)
>  	}
>  
>  	if (tuner && demod) {
> +		/* create tuner to demod link deactivated */
>  		ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT,
> -					    demod, 0, MEDIA_LNK_FL_ENABLED);
> +					    demod, 0, 0);

This is not right, as it makes no sense for DVB-only drivers.

>  		if (ret)
>  			return ret;
>  	}

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

* Re: [PATCH 23/31] media: au0828 implement enable_source and disable_source handlers
  2016-01-06 20:27 ` [PATCH 23/31] media: au0828 implement enable_source and disable_source handlers Shuah Khan
@ 2016-01-28 16:43   ` Mauro Carvalho Chehab
  2016-01-28 20:14     ` Shuah Khan
  0 siblings, 1 reply; 79+ messages in thread
From: Mauro Carvalho Chehab @ 2016-01-28 16:43 UTC (permalink / raw)
  To: Shuah Khan
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Em Wed,  6 Jan 2016 13:27:12 -0700
Shuah Khan <shuahkh@osg.samsung.com> escreveu:

> Implements enable_source and disable_source handlers for other
> drivers (v4l2-core, dvb-core, and ALSA) to use to check for
> tuner connected to the decoder and activate the link if tuner
> is free, and deactivate and free the tuner when it is no longer
> needed.
> 
> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
> ---
>  drivers/media/usb/au0828/au0828-core.c | 148 +++++++++++++++++++++++++++++++++
>  drivers/media/usb/au0828/au0828.h      |   2 +
>  2 files changed, 150 insertions(+)
> 
> diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
> index a15a61a..f8d2db3 100644
> --- a/drivers/media/usb/au0828/au0828-core.c
> +++ b/drivers/media/usb/au0828/au0828-core.c
> @@ -370,6 +370,150 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
>  	return 0;
>  }
>  
> +static int au0828_enable_source(struct media_entity *entity,
> +				struct media_pipeline *pipe)
> +{

The best would be to put those enable source stuff at the core, in a way
that other drivers could share it.

Not sure about the implementation, as this requires testing ;)
Did you consider the cases where the source connector is S-Video
or Composite?

> +#ifdef CONFIG_MEDIA_CONTROLLER
> +	struct media_entity  *source;
> +	struct media_entity *sink;
> +	struct media_link *link, *found_link = NULL;
> +	int ret = 0;
> +	struct media_device *mdev = entity->graph_obj.mdev;
> +	struct au0828_dev *dev;
> +
> +	if (!mdev)
> +		return -ENODEV;
> +
> +	/* for Audio and Video entities, source is the decoder */
> +	mutex_lock(&mdev->graph_mutex);
> +
> +	dev = mdev->source_priv;
> +	if (!dev->tuner || !dev->decoder) {
> +		ret = -ENODEV;
> +		goto end;
> +	}
> +
> +	/*
> +	 * For Audio and V4L2 entity, find the link to which decoder
> +	 * is the sink. Look for an active link between decoder and
> +	 * tuner, if one exists, nothing to do. If not, look for any
> +	 * active links between tuner and any other entity. If one
> +	 * exists, tuner is busy. If tuner is free, setup link and
> +	 * start pipeline from source (tuner).
> +	 * For DVB FE entity, the source for the link is the tuner.
> +	 * Check if tuner is available and setup link and start
> +	 * pipeline.
> +	*/
> +	if (entity->function != MEDIA_ENT_F_DTV_DEMOD)
> +		sink = dev->decoder;
> +	else
> +		sink = entity;
> +
> +	/* Is an active link between sink and tuner */
> +	if (dev->active_link) {
> +		if (dev->active_link->sink->entity == sink &&
> +		    dev->active_link->source->entity == dev->tuner) {
> +			ret = 0;
> +			goto end;
> +		} else {
> +			ret = -EBUSY;
> +			goto end;
> +		}
> +	}
> +
> +	list_for_each_entry(link, &sink->links, list) {
> +		/* Check sink, and source */
> +		if (link->sink->entity == sink &&
> +		    link->source->entity == dev->tuner) {
> +			found_link = link;
> +			break;
> +		}
> +	}
> +
> +	if (!found_link) {
> +		ret = -ENODEV;
> +		goto end;
> +	}
> +
> +	/* activate link between source and sink and start pipeline */
> +	source = found_link->source->entity;
> +	ret = __media_entity_setup_link(found_link, MEDIA_LNK_FL_ENABLED);
> +	if (ret) {
> +		pr_err(
> +			"Activate tuner link %s->%s. Error %d\n",
> +			source->name, sink->name, ret);
> +		goto end;
> +	}
> +
> +	ret = __media_entity_pipeline_start(entity, pipe);
> +	if (ret) {
> +		pr_err("Start Pipeline: %s->%s Error %d\n",
> +			source->name, entity->name, ret);
> +		ret = __media_entity_setup_link(found_link, 0);
> +		pr_err("Deactive link Error %d\n", ret);
> +		goto end;
> +	}
> +	/*
> +	 * save active link and active link owner to avoid audio
> +	 * deactivating video owned link from disable_source and
> +	 * vice versa
> +	*/
> +	dev->active_link = found_link;
> +	dev->active_link_owner = entity;
> +end:
> +	mutex_unlock(&mdev->graph_mutex);
> +	pr_debug("au0828_enable_source() end %s %d %d\n",
> +		entity->name, entity->function, ret);
> +	return ret;
> +#endif
> +	return 0;
> +}
> +
> +static void au0828_disable_source(struct media_entity *entity)
> +{
> +#ifdef CONFIG_MEDIA_CONTROLLER
> +	struct media_entity *sink;
> +	int ret = 0;
> +	struct media_device *mdev = entity->graph_obj.mdev;
> +	struct au0828_dev *dev;
> +
> +	if (!mdev)
> +		return;
> +
> +	mutex_lock(&mdev->graph_mutex);
> +	dev = mdev->source_priv;
> +	if (!dev->tuner || !dev->decoder || !dev->active_link) {
> +		ret = -ENODEV;
> +		goto end;
> +	}
> +
> +	if (entity->function != MEDIA_ENT_F_DTV_DEMOD)
> +		sink = dev->decoder;
> +	else
> +		sink = entity;
> +
> +	/* link is active - stop pipeline from source (tuner) */
> +	if (dev->active_link && dev->active_link->sink->entity == sink &&
> +	    dev->active_link->source->entity == dev->tuner) {
> +		/*
> +		 * prevent video from deactivating link when audio
> +		 * has active pipeline
> +		*/
> +		if (dev->active_link_owner != entity)
> +			goto end;
> +		__media_entity_pipeline_stop(entity);
> +		ret = __media_entity_setup_link(dev->active_link, 0);
> +		if (ret)
> +			pr_err("Deactive link Error %d\n", ret);
> +		dev->active_link = NULL;
> +		dev->active_link_owner = NULL;
> +	}
> +
> +end:
> +	mutex_unlock(&mdev->graph_mutex);
> +#endif
> +}
> +
>  static int au0828_media_device_register(struct au0828_dev *dev,
>  					struct usb_device *udev)
>  {
> @@ -400,6 +544,10 @@ static int au0828_media_device_register(struct au0828_dev *dev,
>  			ret);
>  		return ret;
>  	}
> +	/* set enable_source */
> +	dev->media_dev->source_priv = (void *) dev;
> +	dev->media_dev->enable_source = au0828_enable_source;
> +	dev->media_dev->disable_source = au0828_disable_source;
>  #endif
>  	return 0;
>  }
> diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
> index cfb6d58..3707664 100644
> --- a/drivers/media/usb/au0828/au0828.h
> +++ b/drivers/media/usb/au0828/au0828.h
> @@ -289,6 +289,8 @@ struct au0828_dev {
>  	bool vdev_linked;
>  	bool vbi_linked;
>  	bool audio_capture_linked;
> +	struct media_link *active_link;
> +	struct media_entity *active_link_owner;
>  #endif
>  };
>  

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

* Re: [PATCH 24/31] media: au0828 fix null pointer reference in au0828_create_media_graph()
  2016-01-06 20:27 ` [PATCH 24/31] media: au0828 fix null pointer reference in au0828_create_media_graph() Shuah Khan
@ 2016-01-28 16:44   ` Mauro Carvalho Chehab
  2016-01-28 20:15     ` Shuah Khan
  0 siblings, 1 reply; 79+ messages in thread
From: Mauro Carvalho Chehab @ 2016-01-28 16:44 UTC (permalink / raw)
  To: Shuah Khan
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Em Wed,  6 Jan 2016 13:27:13 -0700
Shuah Khan <shuahkh@osg.samsung.com> escreveu:

> Add a new wrapper function to au0828_create_media_graph()
> to be called as an entity_notify function to fix null
> pointer dereference. A rebasing mistake resulted in
> registering au0828_create_media_graph() without the
> correct parameters which lead to the following
> null pointer dereference:
> 
> [   69.006164] Call Trace:
> [   69.006169]  [<ffffffff81a9a1b0>] dump_stack+0x44/0x64
> [   69.006175]  [<ffffffff81503af9>] print_trailer+0xf9/0x150
> [   69.006180]  [<ffffffff81509284>] object_err+0x34/0x40
> [   69.006185]  [<ffffffff815063c4>] ? ___slab_alloc+0x4c4/0x4e0
> [   69.006190]  [<ffffffff8150b732>] kasan_report_error+0x212/0x520
> [   69.006196]  [<ffffffff815063c4>] ? ___slab_alloc+0x4c4/0x4e0
> [   69.006201]  [<ffffffff8150ba83>] __asan_report_load1_noabort+0x43/0x50
> [   69.006208]  [<ffffffffa0d30991>] ? au0828_create_media_graph+0x641/0x730 [au0828]
> [   69.006215]  [<ffffffffa0d30991>] au0828_create_media_graph+0x641/0x730 [au0828]
> [   69.006221]  [<ffffffff82245c3d>] media_device_register_entity+0x33d/0x4f0
> [   69.006234]  [<ffffffffa0ebeb1c>] media_stream_init+0x2ac/0x610 [snd_usb_audio]
> [   69.006247]  [<ffffffffa0ea9a70>] snd_usb_pcm_open+0xcd0/0x1280 [snd_usb_audio]

Please merge the fix with the patch that caused the regression.

> 
> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
> ---
>  drivers/media/usb/au0828/au0828-core.c | 16 +++++++++++++++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
> index f8d2db3..9497ad1 100644
> --- a/drivers/media/usb/au0828/au0828-core.c
> +++ b/drivers/media/usb/au0828/au0828-core.c
> @@ -370,6 +370,20 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
>  	return 0;
>  }
>  
> +void au0828_create_media_graph_notify(struct media_entity *new,
> +				      void *notify_data)
> +{
> +#ifdef CONFIG_MEDIA_CONTROLLER
> +	struct au0828_dev *dev = (struct au0828_dev *) notify_data;
> +	int ret;
> +
> +	ret = au0828_create_media_graph(dev);
> +	if (ret)
> +		pr_err("%s() media graph create failed for new entity %s\n",
> +		       __func__, new->name);
> +#endif
> +}
> +
>  static int au0828_enable_source(struct media_entity *entity,
>  				struct media_pipeline *pipe)
>  {
> @@ -535,7 +549,7 @@ static int au0828_media_device_register(struct au0828_dev *dev,
>  	}
>  	/* register entity_notify callback */
>  	dev->entity_notify.notify_data = (void *) dev;
> -	dev->entity_notify.notify = (void *) au0828_create_media_graph;
> +	dev->entity_notify.notify = au0828_create_media_graph_notify;
>  	ret = media_device_register_entity_notify(dev->media_dev,
>  						  &dev->entity_notify);
>  	if (ret) {

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

* Re: [PATCH 25/31] media: au0828 fix to not call media_device_unregister_entity_notify()
  2016-01-06 21:01 ` [PATCH 25/31] media: au0828 fix to not call media_device_unregister_entity_notify() Shuah Khan
@ 2016-01-28 16:45   ` Mauro Carvalho Chehab
  2016-01-28 20:15     ` Shuah Khan
  0 siblings, 1 reply; 79+ messages in thread
From: Mauro Carvalho Chehab @ 2016-01-28 16:45 UTC (permalink / raw)
  To: Shuah Khan
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Em Wed,  6 Jan 2016 14:01:54 -0700
Shuah Khan <shuahkh@osg.samsung.com> escreveu:

> entity_notify handlers are removed from media_device_unregister().
> There is no need to call media_device_unregister_entity_notify()
> to do that right before calling media_device_unregister().

Please merge with the patch that added it.

> 
> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
> ---
>  drivers/media/usb/au0828/au0828-core.c | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
> index 9497ad1..722e073 100644
> --- a/drivers/media/usb/au0828/au0828-core.c
> +++ b/drivers/media/usb/au0828/au0828-core.c
> @@ -137,8 +137,6 @@ static void au0828_unregister_media_device(struct au0828_dev *dev)
>  #ifdef CONFIG_MEDIA_CONTROLLER
>  	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);
>  		media_device_cleanup(dev->media_dev);
>  		dev->media_dev = NULL;

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

* Re: [PATCH 28/31] media: au0828 create link between ALSA Mixer and decoder
  2016-01-06 20:27 ` [PATCH 28/31] media: au0828 create link between ALSA Mixer and decoder Shuah Khan
@ 2016-01-28 16:58   ` Mauro Carvalho Chehab
  2016-01-28 20:17     ` Shuah Khan
  0 siblings, 1 reply; 79+ messages in thread
From: Mauro Carvalho Chehab @ 2016-01-28 16:58 UTC (permalink / raw)
  To: Shuah Khan
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Em Wed,  6 Jan 2016 13:27:17 -0700
Shuah Khan <shuahkh@osg.samsung.com> escreveu:

> Change au0828_create_media_graph() to create pad link
> between MEDIA_ENT_F_AUDIO_MIXER entity and decoder's
> AU8522_PAD_AUDIO_OUT. With mixer entity now linked to
> decoder, change to link MEDIA_ENT_F_AUDIO_CAPTURE to
> mixer's source pad.

See my comments about doing only this asynchronously on the previous
patches.

Regards,
Mauro

> 
> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
> ---
>  drivers/media/usb/au0828/au0828-core.c | 17 ++++++++++++++---
>  drivers/media/usb/au0828/au0828.h      |  1 +
>  2 files changed, 15 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
> index 722e073..886fb28 100644
> --- a/drivers/media/usb/au0828/au0828-core.c
> +++ b/drivers/media/usb/au0828/au0828-core.c
> @@ -264,6 +264,7 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
>  	struct media_entity *entity;
>  	struct media_entity *tuner = NULL, *decoder = NULL;
>  	struct media_entity *audio_capture = NULL;
> +	struct media_entity *mixer = NULL;
>  	int i, ret;
>  
>  	if (!mdev)
> @@ -284,6 +285,9 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
>  		case MEDIA_ENT_F_AUDIO_CAPTURE:
>  			audio_capture = entity;
>  			break;
> +		case MEDIA_ENT_F_AUDIO_MIXER:
> +			mixer = entity;
> +			break;
>  		}
>  	}
>  
> @@ -356,14 +360,21 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
>  			}
>  		}
>  	}
> -	if (audio_capture && !dev->audio_capture_linked) {
> -		ret = media_create_pad_link(decoder, AU8522_PAD_AUDIO_OUT,
> -					    audio_capture, 0,
> +	if (mixer && audio_capture && !dev->audio_capture_linked) {
> +		ret = media_create_pad_link(mixer, 1, audio_capture, 0,
>  					    MEDIA_LNK_FL_ENABLED);
>  		if (ret)
>  			return ret;
>  		dev->audio_capture_linked = 1;
>  	}
> +	if (mixer && !dev->mixer_linked) {
> +		ret = media_create_pad_link(decoder, AU8522_PAD_AUDIO_OUT,
> +					    mixer, 0,
> +					    MEDIA_LNK_FL_ENABLED);
> +		if (ret)
> +			return ret;
> +		dev->mixer_linked = 1;
> +	}
>  #endif
>  	return 0;
>  }
> diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
> index 3707664..b9aa74f 100644
> --- a/drivers/media/usb/au0828/au0828.h
> +++ b/drivers/media/usb/au0828/au0828.h
> @@ -289,6 +289,7 @@ struct au0828_dev {
>  	bool vdev_linked;
>  	bool vbi_linked;
>  	bool audio_capture_linked;
> +	bool mixer_linked;
>  	struct media_link *active_link;
>  	struct media_entity *active_link_owner;
>  #endif

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

* Re: [PATCH 15/31] media: dvb-frontend invoke enable/disable_source handlers
  2016-01-28 16:07     ` One Thousand Gnomes
@ 2016-01-28 16:59       ` Shuah Khan
  2016-01-28 17:31         ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-28 16:59 UTC (permalink / raw)
  To: One Thousand Gnomes, Mauro Carvalho Chehab
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel, Shuah Khan

On 01/28/2016 09:07 AM, One Thousand Gnomes wrote:
> On Thu, 28 Jan 2016 13:53:04 -0200
> Mauro Carvalho Chehab <mchehab@osg.samsung.com> wrote:
> 
>> Em Wed,  6 Jan 2016 13:27:04 -0700
>> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
>>
>>> 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.  
>>
>> That's wrong, as DVB can be opened on read-only mode, where
>> it won't be changing anything.

Correct. Please check the code. Tuner availability check is
done when the device is opened in Write mode in the following
conditional.

       if ((file->f_flags & O_ACCMODE) != O_RDONLY) {

>>
>> Also, I don't think POSIX allows to return an error like EBUSY
>> on open:
>> 	http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html
> 
> It doesn't document all the errors you may return. Quite a lot of
> kernel drivers return EBUSY when they are "single open" things.
> 
> POSIX documents certain cases that *must* error and what the error code
> is. It documents certain possible failures and what their error code is.
> Beyond that it's up to you.
> 

Returning EBUSY clearly indicates the reason why the device
can't be opened in this case.

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] 79+ messages in thread

* Re: [PATCH 29/31] media: track media device unregister in progress
  2016-01-06 20:27 ` [PATCH 29/31] media: track media device unregister in progress Shuah Khan
@ 2016-01-28 17:01   ` Mauro Carvalho Chehab
  2016-01-28 17:04     ` Shuah Khan
  0 siblings, 1 reply; 79+ messages in thread
From: Mauro Carvalho Chehab @ 2016-01-28 17:01 UTC (permalink / raw)
  To: Shuah Khan
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Em Wed,  6 Jan 2016 13:27:18 -0700
Shuah Khan <shuahkh@osg.samsung.com> escreveu:

> Add support to track media device unregister in progress
> state to prevent more than one driver entering unregister.
> This enables fixing the general protection faults while
> snd-usb-audio was cleaning up media resources for pcm
> streams and mixers. In this patch a new interface is added
> to return the unregister in progress state. Subsequent
> patches to snd-usb-audio and au0828-core use this interface
> to avoid entering unregister and attempting to unregister
> entities and remove devnodes while unregister is in progress.
> Media device unregister removes entities and interface nodes.

Hmm... isn't the spinlock enough to serialize it? It seems weird the
need of an extra bool here to warrant that this is really serialized.

> 
> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
> ---
>  drivers/media/media-device.c |  5 ++++-
>  include/media/media-device.h | 17 +++++++++++++++++
>  2 files changed, 21 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
> index 20c85a9..1bb9a5f 100644
> --- a/drivers/media/media-device.c
> +++ b/drivers/media/media-device.c
> @@ -749,10 +749,13 @@ void media_device_unregister(struct media_device *mdev)
>  	spin_lock(&mdev->lock);
>  
>  	/* Check if mdev was ever registered at all */
> -	if (!media_devnode_is_registered(&mdev->devnode)) {
> +	/* check if unregister is in progress */
> +	if (!media_devnode_is_registered(&mdev->devnode) ||
> +	    mdev->unregister_in_progress) {
>  		spin_unlock(&mdev->lock);
>  		return;
>  	}
> +	mdev->unregister_in_progress = true;
>  
>  	/* Remove all entities from the media device */
>  	list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list)
> diff --git a/include/media/media-device.h b/include/media/media-device.h
> index 04b6c2e..0807292 100644
> --- a/include/media/media-device.h
> +++ b/include/media/media-device.h
> @@ -332,6 +332,10 @@ struct media_device {
>  	spinlock_t lock;
>  	/* Serializes graph operations. */
>  	struct mutex graph_mutex;
> +	/* Tracks unregister in progress state to prevent
> +	 * more than one driver entering unregister
> +	*/
> +	bool unregister_in_progress;
>  
>  	/* Handlers to find source entity for the sink entity and
>  	 * check if it is available, and activate the link using
> @@ -365,6 +369,7 @@ struct media_device {
>  /* media_devnode to media_device */
>  #define to_media_device(node) container_of(node, struct media_device, devnode)
>  
> +
>  /**
>   * media_entity_enum_init - Initialise an entity enumeration
>   *
> @@ -553,6 +558,12 @@ struct media_device *media_device_get_devres(struct device *dev);
>   * @dev: pointer to struct &device.
>   */
>  struct media_device *media_device_find_devres(struct device *dev);
> +/* return unregister in progress state */
> +static inline bool media_device_is_unregister_in_progress(
> +					struct media_device *mdev)
> +{
> +	return mdev->unregister_in_progress;
> +}
>  
>  /* Iterate over all entities. */
>  #define media_device_for_each_entity(entity, mdev)			\
> @@ -569,6 +580,7 @@ struct media_device *media_device_find_devres(struct device *dev);
>  /* Iterate over all links. */
>  #define media_device_for_each_link(link, mdev)			\
>  	list_for_each_entry(link, &(mdev)->links, graph_obj.list)
> +
>  #else
>  static inline int media_device_register(struct media_device *mdev)
>  {
> @@ -604,5 +616,10 @@ static inline struct media_device *media_device_find_devres(struct device *dev)
>  {
>  	return NULL;
>  }
> +static inline bool media_device_is_unregister_in_progress(
> +					struct media_device *mdev)
> +{
> +	return false;
> +}
>  #endif /* CONFIG_MEDIA_CONTROLLER */
>  #endif

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

* Re: [PATCH 29/31] media: track media device unregister in progress
  2016-01-28 17:01   ` Mauro Carvalho Chehab
@ 2016-01-28 17:04     ` Shuah Khan
  2016-01-28 17:28       ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-28 17:04 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel, Shuah Khan

On 01/28/2016 10:01 AM, Mauro Carvalho Chehab wrote:
> Em Wed,  6 Jan 2016 13:27:18 -0700
> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> 
>> Add support to track media device unregister in progress
>> state to prevent more than one driver entering unregister.
>> This enables fixing the general protection faults while
>> snd-usb-audio was cleaning up media resources for pcm
>> streams and mixers. In this patch a new interface is added
>> to return the unregister in progress state. Subsequent
>> patches to snd-usb-audio and au0828-core use this interface
>> to avoid entering unregister and attempting to unregister
>> entities and remove devnodes while unregister is in progress.
>> Media device unregister removes entities and interface nodes.
> 
> Hmm... isn't the spinlock enough to serialize it? It seems weird the
> need of an extra bool here to warrant that this is really serialized.
> 

The spinlock and check for media_devnode_is_registered(&mdev->devnode)
aren't enough to ensure only one driver enters the unregister. Please
note that the devnode isn't marked unregistered until the end in
media_device_unregister().


>>
>> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
>> ---
>>  drivers/media/media-device.c |  5 ++++-
>>  include/media/media-device.h | 17 +++++++++++++++++
>>  2 files changed, 21 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
>> index 20c85a9..1bb9a5f 100644
>> --- a/drivers/media/media-device.c
>> +++ b/drivers/media/media-device.c
>> @@ -749,10 +749,13 @@ void media_device_unregister(struct media_device *mdev)
>>  	spin_lock(&mdev->lock);
>>  
>>  	/* Check if mdev was ever registered at all */
>> -	if (!media_devnode_is_registered(&mdev->devnode)) {
>> +	/* check if unregister is in progress */
>> +	if (!media_devnode_is_registered(&mdev->devnode) ||
>> +	    mdev->unregister_in_progress) {
>>  		spin_unlock(&mdev->lock);
>>  		return;
>>  	}
>> +	mdev->unregister_in_progress = true;
>>  
>>  	/* Remove all entities from the media device */
>>  	list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list)
>> diff --git a/include/media/media-device.h b/include/media/media-device.h
>> index 04b6c2e..0807292 100644
>> --- a/include/media/media-device.h
>> +++ b/include/media/media-device.h
>> @@ -332,6 +332,10 @@ struct media_device {
>>  	spinlock_t lock;
>>  	/* Serializes graph operations. */
>>  	struct mutex graph_mutex;
>> +	/* Tracks unregister in progress state to prevent
>> +	 * more than one driver entering unregister
>> +	*/
>> +	bool unregister_in_progress;
>>  
>>  	/* Handlers to find source entity for the sink entity and
>>  	 * check if it is available, and activate the link using
>> @@ -365,6 +369,7 @@ struct media_device {
>>  /* media_devnode to media_device */
>>  #define to_media_device(node) container_of(node, struct media_device, devnode)
>>  
>> +
>>  /**
>>   * media_entity_enum_init - Initialise an entity enumeration
>>   *
>> @@ -553,6 +558,12 @@ struct media_device *media_device_get_devres(struct device *dev);
>>   * @dev: pointer to struct &device.
>>   */
>>  struct media_device *media_device_find_devres(struct device *dev);
>> +/* return unregister in progress state */
>> +static inline bool media_device_is_unregister_in_progress(
>> +					struct media_device *mdev)
>> +{
>> +	return mdev->unregister_in_progress;
>> +}
>>  
>>  /* Iterate over all entities. */
>>  #define media_device_for_each_entity(entity, mdev)			\
>> @@ -569,6 +580,7 @@ struct media_device *media_device_find_devres(struct device *dev);
>>  /* Iterate over all links. */
>>  #define media_device_for_each_link(link, mdev)			\
>>  	list_for_each_entry(link, &(mdev)->links, graph_obj.list)
>> +
>>  #else
>>  static inline int media_device_register(struct media_device *mdev)
>>  {
>> @@ -604,5 +616,10 @@ static inline struct media_device *media_device_find_devres(struct device *dev)
>>  {
>>  	return NULL;
>>  }
>> +static inline bool media_device_is_unregister_in_progress(
>> +					struct media_device *mdev)
>> +{
>> +	return false;
>> +}
>>  #endif /* CONFIG_MEDIA_CONTROLLER */
>>  #endif


-- 
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] 79+ messages in thread

* Re: [PATCH 31/31] media: au0828 change to check media device unregister progress state
  2016-01-06 20:27 ` [PATCH 31/31] media: au0828 change to check " Shuah Khan
@ 2016-01-28 17:05   ` Mauro Carvalho Chehab
  2016-01-28 20:31     ` Shuah Khan
  0 siblings, 1 reply; 79+ messages in thread
From: Mauro Carvalho Chehab @ 2016-01-28 17:05 UTC (permalink / raw)
  To: Shuah Khan
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Em Wed,  6 Jan 2016 13:27:20 -0700
Shuah Khan <shuahkh@osg.samsung.com> escreveu:

> Change au0828_unregister_media_device() to check media
> device media device unregister is in progress and avoid
> calling media_device_unregister() and other cleanup done
> in au0828_unregister_media_device().
> 
> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
> ---
>  drivers/media/usb/au0828/au0828-core.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
> index 886fb28..de357a2 100644
> --- a/drivers/media/usb/au0828/au0828-core.c
> +++ b/drivers/media/usb/au0828/au0828-core.c
> @@ -136,7 +136,9 @@ static void au0828_unregister_media_device(struct au0828_dev *dev)
>  
>  #ifdef CONFIG_MEDIA_CONTROLLER
>  	if (dev->media_dev &&
> -		media_devnode_is_registered(&dev->media_dev->devnode)) {
> +		media_devnode_is_registered(&dev->media_dev->devnode) &&
> +		!media_device_is_unregister_in_progress(dev->media_dev)) {
> +

A kref would likely work better here.

>  		media_device_unregister(dev->media_dev);
>  		media_device_cleanup(dev->media_dev);
>  		dev->media_dev = NULL;

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

* Re: [PATCH 03/31] media: Media Controller register/unregister entity_notify API
  2016-01-28 15:13   ` Mauro Carvalho Chehab
@ 2016-01-28 17:09     ` Shuah Khan
  0 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-28 17:09 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel, Shuah Khan

On 01/28/2016 08:13 AM, Mauro Carvalho Chehab wrote:
> Em Wed,  6 Jan 2016 13:26:52 -0700
> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> 
>> 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 | 61 ++++++++++++++++++++++++++++++++++++++++++++
>>  include/media/media-device.h | 25 ++++++++++++++++++
>>  2 files changed, 86 insertions(+)
>>
>> diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
>> index b786b10..20c85a9 100644
>> --- a/drivers/media/media-device.c
>> +++ b/drivers/media/media-device.c
>> @@ -536,6 +536,7 @@ static void media_device_release(struct media_devnode *mdev)
>>  int __must_check media_device_register_entity(struct media_device *mdev,
>>  					      struct media_entity *entity)
>>  {
>> +	struct media_entity_notify *notify, *next;
>>  	unsigned int i;
>>  	int ret;
>>  
>> @@ -575,6 +576,11 @@ int __must_check media_device_register_entity(struct media_device *mdev,
>>  		media_gobj_create(mdev, MEDIA_GRAPH_PAD,
>>  			       &entity->pads[i].graph_obj);
>>  
>> +	/* invoke entity_notify callbacks */
>> +	list_for_each_entry_safe(notify, next, &mdev->entity_notify, list) {
>> +		(notify)->notify(entity, notify->notify_data);
>> +	}
>> +
>>  	spin_unlock(&mdev->lock);
>>  
>>  	return 0;
>> @@ -608,6 +614,8 @@ static void __media_device_unregister_entity(struct media_entity *entity)
>>  	/* Remove the entity */
>>  	media_gobj_destroy(&entity->graph_obj);
>>  
>> +	/* invoke entity_notify callbacks to handle entity removal?? */
>> +
>>  	entity->graph_obj.mdev = NULL;
>>  }
>>  
>> @@ -633,6 +641,7 @@ int __must_check media_device_init(struct media_device *mdev)
>>  	INIT_LIST_HEAD(&mdev->interfaces);
>>  	INIT_LIST_HEAD(&mdev->pads);
>>  	INIT_LIST_HEAD(&mdev->links);
>> +	INIT_LIST_HEAD(&mdev->entity_notify);
>>  	spin_lock_init(&mdev->lock);
>>  	mutex_init(&mdev->graph_mutex);
>>  	ida_init(&mdev->entity_internal_idx);
>> @@ -680,11 +689,59 @@ int __must_check __media_device_register(struct media_device *mdev,
>>  }
>>  EXPORT_SYMBOL_GPL(__media_device_register);
>>  
>> +/**
>> + * 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
>> + */
> 
> Please put the documentation only at the header files. Please mention that
> it locks the addition using the mdev->lock spinlock.
> 
> Also, please follow the format that we're using with other KernelDoc
> tags:
> 
> /**
>  * function() - short description
>  *
>  * @foo:	foo description
>  * @bar:	bar description
>  *
>  * detailed description
>  */
> 
> In case of doubts, please check Documentation/kernel-doc-nano-HOWTO.txt.
> 
> Don't forget to check if the documentation looks sane by compiling it
> with:
> 	make cleandocs
> 	make DOCBOOKS=device-drivers.xml htmldocs
> 
> Same applies to other documentation below and on other patches in this
> series.
> 
>> +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
>> + * Non-locking version. Should be called with mdev->lock held.
>> + */
>> +static void __media_device_unregister_entity_notify(struct media_device *mdev,
>> +					struct media_entity_notify *nptr)
> 
> __must_check

Thanks for the catch. Will fix it.

> 
>> +{
>> +	list_del(&nptr->list);
>> +}
>> +
>> +/**
>> + * 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);
>> +	__media_device_unregister_entity_notify(mdev, nptr);
>> +	spin_unlock(&mdev->lock);
>> +}
>> +EXPORT_SYMBOL_GPL(media_device_unregister_entity_notify);
>> +
>>  void media_device_unregister(struct media_device *mdev)
>>  {
>>  	struct media_entity *entity;
>>  	struct media_entity *next;
>>  	struct media_interface *intf, *tmp_intf;
>> +	struct media_entity_notify *notify, *nextp;
>>  
>>  	if (mdev == NULL)
>>  		return;
>> @@ -701,6 +758,10 @@ void media_device_unregister(struct media_device *mdev)
>>  	list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list)
>>  		__media_device_unregister_entity(entity);
>>  
>> +	/* Remove all entity_notify callbacks from the media device */
>> +	list_for_each_entry_safe(notify, nextp, &mdev->entity_notify, list)
>> +		__media_device_unregister_entity_notify(mdev, notify);
>> +
>>  	/* Remove all interfaces from the media device */
>>  	list_for_each_entry_safe(intf, tmp_intf, &mdev->interfaces,
>>  				 graph_obj.list) {
>> diff --git a/include/media/media-device.h b/include/media/media-device.h
>> index 122963a..6520d1c 100644
>> --- a/include/media/media-device.h
>> +++ b/include/media/media-device.h
>> @@ -264,6 +264,12 @@
>>  struct ida;
>>  struct device;
>>  
>> +struct media_entity_notify {
>> +	struct list_head list;
>> +	void *notify_data;
>> +	void (*notify)(struct media_entity *entity, void *notify_data);
>> +};
> 
> Please document the structure.
> 
>> +
>>  /**
>>   * struct media_device - Media device
>>   * @dev:	Parent device
>> @@ -319,6 +325,9 @@ struct media_device {
>>  	struct list_head pads;
>>  	struct list_head links;
>>  
>> +	/* notify callback list invoked when a new entity is registered */
>> +	struct list_head entity_notify;
>> +
> 
> Please document the new field at the Kernel-doc header.
> 
>>  	/* Protects the graph objects creation/removal */
>>  	spinlock_t lock;
>>  	/* Serializes graph operations. */
>> @@ -497,6 +506,11 @@ int __must_check media_device_register_entity(struct media_device *mdev,
>>   */
>>  void media_device_unregister_entity(struct media_entity *entity);
>>  
>> +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);
>> +
> 
> Documentation?

I would like to add documentation as an add-on to the series,
as I explained in response to [PATCH 04/31]

Hope that is okay for this patch as well.

thanks,
-- Shuah
> 
>>  /**
>>   * media_device_get_devres() -	get media device as device resource
>>   *				creates if one doesn't exist
>> @@ -552,6 +566,17 @@ static inline int media_device_register_entity(struct media_device *mdev,
>>  static inline void media_device_unregister_entity(struct media_entity *entity)
>>  {
>>  }
>> +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 struct media_device *media_device_get_devres(struct device *dev)
>>  {
>>  	return NULL;
> 
> Documentation?
> 
> Regards,
> Mauro
> 


-- 
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] 79+ messages in thread

* Re: [PATCH 08/31] media: v4l-core add v4l_enable/disable_media_tuner() helper functions
  2016-01-28 15:26   ` Mauro Carvalho Chehab
@ 2016-01-28 17:12     ` Shuah Khan
  0 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-28 17:12 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel, Shuah Khan

On 01/28/2016 08:26 AM, Mauro Carvalho Chehab wrote:
> Em Wed,  6 Jan 2016 13:26:57 -0700
> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> 
>> Add a new interfaces to be used by v4l-core to invoke enable
>> source and disable_source handlers in the media_device. The
>> enable_source helper function invokes the enable_source handler
>> to find tuner entity connected to the decoder and check is it
>> is available or busy. If tuner is available, link is activated
>> and pipeline is started. The disable_source helper function
>> invokes the disable_source handler to deactivate and stop the
>> pipeline.
>>
>> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
>> ---
>>  drivers/media/v4l2-core/v4l2-dev.c | 27 +++++++++++++++++++++++++++
>>  include/media/v4l2-dev.h           |  4 ++++
>>  2 files changed, 31 insertions(+)
>>
>> diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
>> index d8e5994..f06da6e 100644
>> --- a/drivers/media/v4l2-core/v4l2-dev.c
>> +++ b/drivers/media/v4l2-core/v4l2-dev.c
>> @@ -233,6 +233,33 @@ struct video_device *video_devdata(struct file *file)
>>  }
>>  EXPORT_SYMBOL(video_devdata);
>>  
>> +int v4l_enable_media_tuner(struct video_device *vdev)
> 
> IMHO, the better is to put those MC ancillary routines on a separate file.
> Hans suggested to add them at v4l2-mc.h and v4l2-mc.h.

ok I can do that.

> 
>> +{
>> +#ifdef CONFIG_MEDIA_CONTROLLER
>> +	struct media_device *mdev = vdev->entity.graph_obj.mdev;
>> +	int ret;
>> +
>> +	if (!mdev || !mdev->enable_source)
>> +		return 0;
>> +	ret = mdev->enable_source(&vdev->entity, &vdev->pipe);
>> +	if (ret)
>> +		return -EBUSY;
>> +	return 0;
>> +#endif /* CONFIG_MEDIA_CONTROLLER */
>> +	return 0;
>> +}
>> +EXPORT_SYMBOL_GPL(v4l_enable_media_tuner);
>> +
>> +void v4l_disable_media_tuner(struct video_device *vdev)
>> +{
>> +#ifdef CONFIG_MEDIA_CONTROLLER
>> +	struct media_device *mdev = vdev->entity.graph_obj.mdev;
>> +
>> +	if (mdev && mdev->disable_source)
>> +		mdev->disable_source(&vdev->entity);
>> +#endif /* CONFIG_MEDIA_CONTROLLER */
>> +}
>> +EXPORT_SYMBOL_GPL(v4l_disable_media_tuner);
>>  
>>  /* Priority handling */
>>  
>> diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
>> index eeabf20..68999a3 100644
>> --- a/include/media/v4l2-dev.h
>> +++ b/include/media/v4l2-dev.h
>> @@ -87,6 +87,7 @@ struct video_device
>>  #if defined(CONFIG_MEDIA_CONTROLLER)
>>  	struct media_entity entity;
>>  	struct media_intf_devnode *intf_devnode;
>> +	struct media_pipeline pipe;
>>  #endif
>>  	/* device ops */
>>  	const struct v4l2_file_operations *fops;
>> @@ -176,6 +177,9 @@ void video_unregister_device(struct video_device *vdev);
>>     latter can also be used for video_device->release(). */
>>  struct video_device * __must_check video_device_alloc(void);
>>  
>> +int v4l_enable_media_tuner(struct video_device *vdev);
>> +void v4l_disable_media_tuner(struct video_device *vdev);
> 
> Documentation?

Since I am going to be adding a new source file, I can
add documentation in the same patch.

thanks,
-- Shuah

> 
>> +
>>  /* this release function frees the vdev pointer */
>>  void video_device_release(struct video_device *vdev);
>>  


-- 
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] 79+ messages in thread

* Re: [PATCH 04/31] media: Media Controller enable/disable source handler API
  2016-01-28 16:28     ` Shuah Khan
@ 2016-01-28 17:15       ` Mauro Carvalho Chehab
  2016-01-28 20:33         ` Shuah Khan
  0 siblings, 1 reply; 79+ messages in thread
From: Mauro Carvalho Chehab @ 2016-01-28 17:15 UTC (permalink / raw)
  To: Shuah Khan
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Em Thu, 28 Jan 2016 09:28:37 -0700
Shuah Khan <shuahkh@osg.samsung.com> escreveu:

> On 01/28/2016 08:19 AM, Mauro Carvalho Chehab wrote:
> > Em Wed,  6 Jan 2016 13:26:53 -0700
> > Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> >   
> >> Add new fields to struct media_device to add enable_source, and
> >> disable_source handlers, and source_priv to stash driver private
> >> data that is need to run these handlers. The enable_source handler
> >> finds source entity for the passed in 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 these
> >> handlers and private data 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 it and start pipeline between
> >> the source and the entity. The disable_source handler deactivates the
> >> link and stops the pipeline. This handler can be invoked from the
> >> 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 | 19 +++++++++++++++++++
> >>  1 file changed, 19 insertions(+)
> >>
> >> diff --git a/include/media/media-device.h b/include/media/media-device.h
> >> index 6520d1c..04b6c2e 100644
> >> --- a/include/media/media-device.h
> >> +++ b/include/media/media-device.h
> >> @@ -333,6 +333,25 @@ struct media_device {
> >>  	/* Serializes graph operations. */
> >>  	struct mutex graph_mutex;
> >>  
> >> +	/* Handlers to find source entity for the sink entity and
> >> +	 * check if it is available, and activate the link using
> >> +	 * media_entity_setup_link() interface and start pipeline
> >> +	 * from the source to the entity.
> >> +	 * 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.
> >> +	 * Bridge driver sets source_priv with information
> >> +	 * necessary to run enable/disable source handlers.
> >> +	 *
> >> +	 * 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.
> >> +	*/
> >> +	void *source_priv;
> >> +	int (*enable_source)(struct media_entity *entity,
> >> +			     struct media_pipeline *pipe);
> >> +	void (*disable_source)(struct media_entity *entity);  
> > 
> > Please document the new fields at the right place (Kernel-doc
> > comment declared before the struct).
> > 
> > Is this used by the media core? If so, please but the implementation
> > here, to make it clearer why we need those things.
> >   
> >> +
> >>  	int (*link_notify)(struct media_link *link, u32 flags,
> >>  			   unsigned int notification);
> >>  };  
> 
> Hi Mauro,
> 
> I don't have any problems adding documentation. I would
> like to add documentation in a add-on to the patch series.
> The main reason is once I add documentation to this patch,
> the rest of the patches on this file don't apply and require
> rebase and rework. I went though a couple of rounds of this
> while you were adding documentation to the interfaces you
> added.
> 
> How about I add the documentation patches at the end of
> the patch series? I am concerned that rebasing for the
> documentation changes will introduce bugs. Are you okay
> with this proposal?

I'm ok with that for those inlined kernel-doc stuff. On
the changes at the uapi/linux/media.h, I would prefer if
you could add the documentation together with the patch,
as it makes clearer for the reviewers. As you only
touched it on one or two patches, this won't cause any
breakages on the remaining patches.

Regards,
Mauro



> 
> thanks,
> -- Shuah
> 

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

* Re: [PATCH 29/31] media: track media device unregister in progress
  2016-01-28 17:04     ` Shuah Khan
@ 2016-01-28 17:28       ` Mauro Carvalho Chehab
  2016-01-28 20:42         ` Shuah Khan
  0 siblings, 1 reply; 79+ messages in thread
From: Mauro Carvalho Chehab @ 2016-01-28 17:28 UTC (permalink / raw)
  To: Shuah Khan
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Em Thu, 28 Jan 2016 10:04:24 -0700
Shuah Khan <shuahkh@osg.samsung.com> escreveu:

> On 01/28/2016 10:01 AM, Mauro Carvalho Chehab wrote:
> > Em Wed,  6 Jan 2016 13:27:18 -0700
> > Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> >   
> >> Add support to track media device unregister in progress
> >> state to prevent more than one driver entering unregister.
> >> This enables fixing the general protection faults while
> >> snd-usb-audio was cleaning up media resources for pcm
> >> streams and mixers. In this patch a new interface is added
> >> to return the unregister in progress state. Subsequent
> >> patches to snd-usb-audio and au0828-core use this interface
> >> to avoid entering unregister and attempting to unregister
> >> entities and remove devnodes while unregister is in progress.
> >> Media device unregister removes entities and interface nodes.  
> > 
> > Hmm... isn't the spinlock enough to serialize it? It seems weird the
> > need of an extra bool here to warrant that this is really serialized.
> >   
> 
> The spinlock and check for media_devnode_is_registered(&mdev->devnode)
> aren't enough to ensure only one driver enters the unregister. 
>
> Please
> note that the devnode isn't marked unregistered until the end in
> media_device_unregister().

I guess the call to:
	device_remove_file(&mdev->devnode.dev, &dev_attr_model);

IMO, This should be, instead, at media_devnode_unregister().

Then, we can change the logic at media_devnode_unregister() to:

void media_devnode_unregister(struct media_devnode *mdev)
{
	mutex_lock(&media_devnode_lock);

	/* Check if mdev was ever registered at all */
	if (!media_devnode_is_registered(mdev)) {
		mutex_unlock(&media_devnode_lock);
		return;
	}

	clear_bit(MEDIA_FLAG_REGISTERED, &mdev->flags);
	mutex_unlock(&media_devnode_lock);
	device_remove_file(&mdev->devnode.dev, &dev_attr_model);
	device_unregister(&mdev->dev);
}

This sounds enough to avoid device_unregister() or device_remove_file()
to be called twice.

> 
> 
> >>
> >> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
> >> ---
> >>  drivers/media/media-device.c |  5 ++++-
> >>  include/media/media-device.h | 17 +++++++++++++++++
> >>  2 files changed, 21 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
> >> index 20c85a9..1bb9a5f 100644
> >> --- a/drivers/media/media-device.c
> >> +++ b/drivers/media/media-device.c
> >> @@ -749,10 +749,13 @@ void media_device_unregister(struct media_device *mdev)
> >>  	spin_lock(&mdev->lock);
> >>  
> >>  	/* Check if mdev was ever registered at all */
> >> -	if (!media_devnode_is_registered(&mdev->devnode)) {
> >> +	/* check if unregister is in progress */
> >> +	if (!media_devnode_is_registered(&mdev->devnode) ||
> >> +	    mdev->unregister_in_progress) {
> >>  		spin_unlock(&mdev->lock);
> >>  		return;
> >>  	}
> >> +	mdev->unregister_in_progress = true;
> >>  
> >>  	/* Remove all entities from the media device */
> >>  	list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list)
> >> diff --git a/include/media/media-device.h b/include/media/media-device.h
> >> index 04b6c2e..0807292 100644
> >> --- a/include/media/media-device.h
> >> +++ b/include/media/media-device.h
> >> @@ -332,6 +332,10 @@ struct media_device {
> >>  	spinlock_t lock;
> >>  	/* Serializes graph operations. */
> >>  	struct mutex graph_mutex;
> >> +	/* Tracks unregister in progress state to prevent
> >> +	 * more than one driver entering unregister
> >> +	*/
> >> +	bool unregister_in_progress;
> >>  
> >>  	/* Handlers to find source entity for the sink entity and
> >>  	 * check if it is available, and activate the link using
> >> @@ -365,6 +369,7 @@ struct media_device {
> >>  /* media_devnode to media_device */
> >>  #define to_media_device(node) container_of(node, struct media_device, devnode)
> >>  
> >> +
> >>  /**
> >>   * media_entity_enum_init - Initialise an entity enumeration
> >>   *
> >> @@ -553,6 +558,12 @@ struct media_device *media_device_get_devres(struct device *dev);
> >>   * @dev: pointer to struct &device.
> >>   */
> >>  struct media_device *media_device_find_devres(struct device *dev);
> >> +/* return unregister in progress state */
> >> +static inline bool media_device_is_unregister_in_progress(
> >> +					struct media_device *mdev)
> >> +{
> >> +	return mdev->unregister_in_progress;
> >> +}
> >>  
> >>  /* Iterate over all entities. */
> >>  #define media_device_for_each_entity(entity, mdev)			\
> >> @@ -569,6 +580,7 @@ struct media_device *media_device_find_devres(struct device *dev);
> >>  /* Iterate over all links. */
> >>  #define media_device_for_each_link(link, mdev)			\
> >>  	list_for_each_entry(link, &(mdev)->links, graph_obj.list)
> >> +
> >>  #else
> >>  static inline int media_device_register(struct media_device *mdev)
> >>  {
> >> @@ -604,5 +616,10 @@ static inline struct media_device *media_device_find_devres(struct device *dev)
> >>  {
> >>  	return NULL;
> >>  }
> >> +static inline bool media_device_is_unregister_in_progress(
> >> +					struct media_device *mdev)
> >> +{
> >> +	return false;
> >> +}
> >>  #endif /* CONFIG_MEDIA_CONTROLLER */
> >>  #endif  
> 
> 

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

* Re: [PATCH 09/31] media: v4l2-core add v4l_vb2q_enable_media_tuner() helper
  2016-01-28 15:29   ` Mauro Carvalho Chehab
@ 2016-01-28 17:31     ` Shuah Khan
  2016-01-28 17:34       ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-28 17:31 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel, Shuah Khan

On 01/28/2016 08:29 AM, Mauro Carvalho Chehab wrote:
> Em Wed,  6 Jan 2016 13:26:58 -0700
> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> 
>> Add a new v4l_vb2q_enable_media_tuner() wrapper function
>> to be called from v4l2-core to enable the media tuner with
>> videobuf2 queue, when the calling frunction has the videobuf2
>> queue and doesn't have the struct video_device associated with
>> the queue handy as in the case of vb2_core_streamon(). This
>> function simply calls v4l_enable_media_tuner() passing in the
>> pointer to struct video_device.
>>
>> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
>> ---
>>  drivers/media/v4l2-core/v4l2-dev.c | 21 +++++++++++++++++++++
>>  include/media/v4l2-dev.h           |  1 +
>>  2 files changed, 22 insertions(+)
>>
>> diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
>> index f06da6e..9ef675a 100644
>> --- a/drivers/media/v4l2-core/v4l2-dev.c
>> +++ b/drivers/media/v4l2-core/v4l2-dev.c
>> @@ -30,6 +30,7 @@
>>  #include <media/v4l2-common.h>
>>  #include <media/v4l2-device.h>
>>  #include <media/v4l2-ioctl.h>
>> +#include <media/videobuf2-core.h>
>>  
>>  #define VIDEO_NUM_DEVICES	256
>>  #define VIDEO_NAME              "video4linux"
>> @@ -261,6 +262,26 @@ void v4l_disable_media_tuner(struct video_device *vdev)
>>  }
>>  EXPORT_SYMBOL_GPL(v4l_disable_media_tuner);
>>  
>> +/**
>> + * v4l_vb2q_enable_media_tuner - Wrapper for v4l_enable_media_tuner()
>> + * @q:         videobuf2 queue
>> + *
>> + * This function is intended to be called from v4l2-core
>> + * to enable the media tuner with videobuf2 queue, when
>> + * the calling frunction has the videobuf2 queue and doesn't
> 
> 	typo: function

ok thanks

> 
>> + * have the struct video_device associated with the
>> + * queue handy as in the case of vb2_core_streamon(). This
>> + * function simply calls v4l_enable_media_tuner() passing
>> + * in the pointer to struct video_device.
> 
> The hole description seems confusing. I'm not seeing the light
> about why this is needed.

Sorry if the description isn't clear. During videobuf2
work, owner field in struct vb2_queue is changed from
struct v4l2_fh * to void. Prior to this work, I could
call v4l_enable_media_tuner(). 

+               ret = v4l_enable_media_tuner(q->owner->vdev);
+               if (ret)
+                       return ret;

As you can see with the videobuf2, to be able to call
v4l_enable_media_tuner() from vb2_core_streamon(), I have
had to this wrapper to maintain the abstraction introduced
in videobuf2 work.

Hope this helps the need for this wrapper.

thanks,
-- Shuah
> 
>> + */
>> +int v4l_vb2q_enable_media_tuner(struct vb2_queue *q)
>> +{
>> +	struct v4l2_fh *fh = q->owner;
>> +
>> +	return v4l_enable_media_tuner(fh->vdev);
>> +}
>> +EXPORT_SYMBOL_GPL(v4l_vb2q_enable_media_tuner);
>> +
>>  /* Priority handling */
>>  
>>  static inline bool prio_is_valid(enum v4l2_priority prio)
>> diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
>> index 68999a3..1948097 100644
>> --- a/include/media/v4l2-dev.h
>> +++ b/include/media/v4l2-dev.h
>> @@ -179,6 +179,7 @@ struct video_device * __must_check video_device_alloc(void);
>>  
>>  int v4l_enable_media_tuner(struct video_device *vdev);
>>  void v4l_disable_media_tuner(struct video_device *vdev);
>> +int v4l_vb2q_enable_media_tuner(struct vb2_queue *q);
> 
> Documentation?
> 
>>  
>>  /* this release function frees the vdev pointer */
>>  void video_device_release(struct video_device *vdev);


-- 
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] 79+ messages in thread

* Re: [PATCH 15/31] media: dvb-frontend invoke enable/disable_source handlers
  2016-01-28 16:59       ` Shuah Khan
@ 2016-01-28 17:31         ` Mauro Carvalho Chehab
  0 siblings, 0 replies; 79+ messages in thread
From: Mauro Carvalho Chehab @ 2016-01-28 17:31 UTC (permalink / raw)
  To: Shuah Khan
  Cc: One Thousand Gnomes, tiwai, clemens, hans.verkuil,
	laurent.pinchart, sakari.ailus, javier, pawel, m.szyprowski,
	kyungmin.park, perex, arnd, dan.carpenter, tvboxspy, crope,
	ruchandani.tina, corbet, chehabrafael, k.kozlowski, stefanr,
	inki.dae, jh1009.sung, elfring, prabhakar.csengg, sw0312.kim,
	p.zabel, ricardo.ribalda, labbott, pierre-louis.bossart,
	ricard.wanderlof, julian, takamichiho, dominic.sacre, misterpib,
	daniel, gtmkramer, normalperson, joe, linuxbugs, johan,
	linux-kernel, linux-media, linux-api, alsa-devel

Em Thu, 28 Jan 2016 09:59:38 -0700
Shuah Khan <shuahkh@osg.samsung.com> escreveu:

> On 01/28/2016 09:07 AM, One Thousand Gnomes wrote:
> > On Thu, 28 Jan 2016 13:53:04 -0200
> > Mauro Carvalho Chehab <mchehab@osg.samsung.com> wrote:
> >   
> >> Em Wed,  6 Jan 2016 13:27:04 -0700
> >> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> >>  
> >>> 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.    
> >>
> >> That's wrong, as DVB can be opened on read-only mode, where
> >> it won't be changing anything.  
> 
> Correct. Please check the code. Tuner availability check is
> done when the device is opened in Write mode in the following
> conditional.
> 
>        if ((file->f_flags & O_ACCMODE) != O_RDONLY) {

OK.

Thanks!
Mauro
, I don't think POSIX allows to return an error like EBUSY
> >> on open:
> >> 	http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html  
> > 
> > It doesn't document all the errors you may return. Quite a lot of
> > kernel drivers return EBUSY when they are "single open" things.
> > 
> > POSIX documents certain cases that *must* error and what the error code
> > is. It documents certain possible failures and what their error code is.
> > Beyond that it's up to you.
> >   
> 
> Returning EBUSY clearly indicates the reason why the device
> can't be opened in this case.
> 
> thanks,
> -- Shuah
> 
> 
Thanks!
Mauro

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

* Re: [PATCH 09/31] media: v4l2-core add v4l_vb2q_enable_media_tuner() helper
  2016-01-28 17:31     ` Shuah Khan
@ 2016-01-28 17:34       ` Mauro Carvalho Chehab
  0 siblings, 0 replies; 79+ messages in thread
From: Mauro Carvalho Chehab @ 2016-01-28 17:34 UTC (permalink / raw)
  To: Shuah Khan
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Em Thu, 28 Jan 2016 10:31:21 -0700
Shuah Khan <shuahkh@osg.samsung.com> escreveu:

> On 01/28/2016 08:29 AM, Mauro Carvalho Chehab wrote:
> > Em Wed,  6 Jan 2016 13:26:58 -0700
> > Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> >   
> >> Add a new v4l_vb2q_enable_media_tuner() wrapper function
> >> to be called from v4l2-core to enable the media tuner with
> >> videobuf2 queue, when the calling frunction has the videobuf2
> >> queue and doesn't have the struct video_device associated with
> >> the queue handy as in the case of vb2_core_streamon(). This
> >> function simply calls v4l_enable_media_tuner() passing in the
> >> pointer to struct video_device.
> >>
> >> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
> >> ---
> >>  drivers/media/v4l2-core/v4l2-dev.c | 21 +++++++++++++++++++++
> >>  include/media/v4l2-dev.h           |  1 +
> >>  2 files changed, 22 insertions(+)
> >>
> >> diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
> >> index f06da6e..9ef675a 100644
> >> --- a/drivers/media/v4l2-core/v4l2-dev.c
> >> +++ b/drivers/media/v4l2-core/v4l2-dev.c
> >> @@ -30,6 +30,7 @@
> >>  #include <media/v4l2-common.h>
> >>  #include <media/v4l2-device.h>
> >>  #include <media/v4l2-ioctl.h>
> >> +#include <media/videobuf2-core.h>
> >>  
> >>  #define VIDEO_NUM_DEVICES	256
> >>  #define VIDEO_NAME              "video4linux"
> >> @@ -261,6 +262,26 @@ void v4l_disable_media_tuner(struct video_device *vdev)
> >>  }
> >>  EXPORT_SYMBOL_GPL(v4l_disable_media_tuner);
> >>  
> >> +/**
> >> + * v4l_vb2q_enable_media_tuner - Wrapper for v4l_enable_media_tuner()
> >> + * @q:         videobuf2 queue
> >> + *
> >> + * This function is intended to be called from v4l2-core
> >> + * to enable the media tuner with videobuf2 queue, when
> >> + * the calling frunction has the videobuf2 queue and doesn't  
> > 
> > 	typo: function  
> 
> ok thanks
> 
> >   
> >> + * have the struct video_device associated with the
> >> + * queue handy as in the case of vb2_core_streamon(). This
> >> + * function simply calls v4l_enable_media_tuner() passing
> >> + * in the pointer to struct video_device.  
> > 
> > The hole description seems confusing. I'm not seeing the light
> > about why this is needed.  
> 
> Sorry if the description isn't clear. During videobuf2
> work, owner field in struct vb2_queue is changed from
> struct v4l2_fh * to void. Prior to this work, I could
> call v4l_enable_media_tuner(). 
> 
> +               ret = v4l_enable_media_tuner(q->owner->vdev);
> +               if (ret)
> +                       return ret;
> 
> As you can see with the videobuf2, to be able to call
> v4l_enable_media_tuner() from vb2_core_streamon(), I have
> had to this wrapper to maintain the abstraction introduced
> in videobuf2 work.
> 
> Hope this helps the need for this wrapper.


It is clearer now. Please improve the description of the patch
on the next version for us to remember ;)

Regards,
Mauro
> 
> thanks,
> -- Shuah
> >   
> >> + */
> >> +int v4l_vb2q_enable_media_tuner(struct vb2_queue *q)
> >> +{
> >> +	struct v4l2_fh *fh = q->owner;
> >> +
> >> +	return v4l_enable_media_tuner(fh->vdev);
> >> +}
> >> +EXPORT_SYMBOL_GPL(v4l_vb2q_enable_media_tuner);
> >> +
> >>  /* Priority handling */
> >>  
> >>  static inline bool prio_is_valid(enum v4l2_priority prio)
> >> diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
> >> index 68999a3..1948097 100644
> >> --- a/include/media/v4l2-dev.h
> >> +++ b/include/media/v4l2-dev.h
> >> @@ -179,6 +179,7 @@ struct video_device * __must_check video_device_alloc(void);
> >>  
> >>  int v4l_enable_media_tuner(struct video_device *vdev);
> >>  void v4l_disable_media_tuner(struct video_device *vdev);
> >> +int v4l_vb2q_enable_media_tuner(struct vb2_queue *q);  
> > 
> > Documentation?
> >   
> >>  
> >>  /* this release function frees the vdev pointer */
> >>  void video_device_release(struct video_device *vdev);  
> 
> 

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

* Re: [PATCH 13/31] media: au0828 fix au0828_create_media_graph() entity checks
  2016-01-28 15:37   ` Mauro Carvalho Chehab
@ 2016-01-28 18:57     ` Shuah Khan
  0 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-28 18:57 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel, Shuah Khan

On 01/28/2016 08:37 AM, Mauro Carvalho Chehab wrote:
> Em Wed,  6 Jan 2016 13:27:02 -0700
> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> 
>> au0828_create_media_graph() doesn't do any checks to determine,
>> if vbi_dev, vdev, and input entities have been registered prior
>> to creating pad links. Checking graph_obj.mdev field works as
>> the graph_obj.mdev field gets initialized in the entity register
>> interface. Fix it to check graph_obj.mdev field before creating
>> pad links.
> 
>>
>> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
>> ---
>>  drivers/media/usb/au0828/au0828-core.c | 27 +++++++++++++++++----------
>>  1 file changed, 17 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
>> index f46fb43..8ef7c71 100644
>> --- a/drivers/media/usb/au0828/au0828-core.c
>> +++ b/drivers/media/usb/au0828/au0828-core.c
>> @@ -291,20 +291,27 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
>>  		if (ret)
>>  			return ret;
>>  	}
>> -	ret = media_create_pad_link(decoder, AU8522_PAD_VID_OUT,
>> -				    &dev->vdev.entity, 0,
>> -				    MEDIA_LNK_FL_ENABLED);
>> -	if (ret)
>> -		return ret;
>> -	ret = media_create_pad_link(decoder, AU8522_PAD_VBI_OUT,
>> -				    &dev->vbi_dev.entity, 0,
>> -				    MEDIA_LNK_FL_ENABLED);
>> -	if (ret)
>> -		return ret;
>> +	if (dev->vdev.entity.graph_obj.mdev) {
>> +		ret = media_create_pad_link(decoder, AU8522_PAD_VID_OUT,
>> +					    &dev->vdev.entity, 0,
>> +					    MEDIA_LNK_FL_ENABLED);
>> +		if (ret)
>> +			return ret;
>> +	}
> 
> Those new if() doesn't look right. We can't continue if the entities
> weren't registered, as the graph would have troubles. The logic should
> ensure that the entities will always be created before running 
> au0828_create_media_graph(). If this is not the case, some async
> logic is needed to ensure that.

There have been some changes in au0828 media init and
register sequence in 4.5-rc1. wau0828 does its graph
creation before it registers media_device.

I needed these checks before this above. It looks
like I might have simply rebased my patch over
without taking this change into account. I will
try without these checks.

Async method is already in place for snd-usb-audio
part of the graph. Please see patch 20 in the series.

thanks,
-- Shuah

> 
>> +	if (dev->vbi_dev.entity.graph_obj.mdev) {
>> +		ret = media_create_pad_link(decoder, AU8522_PAD_VBI_OUT,
>> +					    &dev->vbi_dev.entity, 0,
>> +					    MEDIA_LNK_FL_ENABLED);
>> +		if (ret)
>> +			return ret;
>> +	}
>>  
>>  	for (i = 0; i < AU0828_MAX_INPUT; i++) {
>>  		struct media_entity *ent = &dev->input_ent[i];
>>  
>> +		if (!ent->graph_obj.mdev)
>> +			continue;
>> +
>>  		if (AUVI_INPUT(i).type == AU0828_VMUX_UNDEFINED)
>>  			break;
>>  


-- 
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] 79+ messages in thread

* Re: [PATCH 17/31] media: au0828 video change to use v4l_enable_media_tuner()
  2016-01-28 15:57   ` Mauro Carvalho Chehab
@ 2016-01-28 19:21     ` Shuah Khan
  2016-01-28 19:33       ` Devin Heitmueller
  0 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-28 19:21 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel, Shuah Khan

On 01/28/2016 08:57 AM, Mauro Carvalho Chehab wrote:
> Em Wed,  6 Jan 2016 13:27:06 -0700
> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> 
>> au0828 is changed to use v4l_enable_media_tuner() to check for
>> tuner availability from vidioc_g_tuner(), and au0828_v4l2_close(),
>> before changing tuner settings. If tuner isn't free, return busy
>> condition from vidioc_g_tuner() and in au0828_v4l2_close() tuner
>> is left untouched without powering down to save energy.
> 
> Did you test the code when the input is not a tuner, but, instead,
> Composite or S-Video connector, as shown at:
> 	https://mchehab.fedorapeople.org/mc-next-gen/au0828.png

I am not sure if I did or not. I can double check this case.
Do you have concerns that this won't work?

> 
> I guess calling it v4l-enable_media_tuner() is not right, specially
> since there are hybrid devices that have DTV (via DVB API) and
> S-Video and/or Composite/RCA capture via V4L2 API.

How does  v4l-enable_media_source() sound?

thanks,
-- Shuah

> 
>>
>> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
>> ---
>>  drivers/media/usb/au0828/au0828-video.c | 14 ++++++++++++--
>>  1 file changed, 12 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
>> index 32bcc56..ed3ba05 100644
>> --- a/drivers/media/usb/au0828/au0828-video.c
>> +++ b/drivers/media/usb/au0828/au0828-video.c
>> @@ -1010,8 +1010,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 = v4l_enable_media_tuner(vdev);
>> +		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
>> @@ -1412,10 +1416,16 @@ 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);
>> +	struct video_device *vfd = video_devdata(file);
>> +	int ret;
>>  
>>  	if (t->index != 0)
>>  		return -EINVAL;
>>  
>> +	ret = v4l_enable_media_tuner(vfd);
>> +	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);
>>  


-- 
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] 79+ messages in thread

* Re: [PATCH 17/31] media: au0828 video change to use v4l_enable_media_tuner()
  2016-01-28 19:21     ` Shuah Khan
@ 2016-01-28 19:33       ` Devin Heitmueller
  0 siblings, 0 replies; 79+ messages in thread
From: Devin Heitmueller @ 2016-01-28 19:33 UTC (permalink / raw)
  To: Shuah Khan
  Cc: Mauro Carvalho Chehab, tiwai, Clemens Ladisch, Hans Verkuil,
	Laurent Pinchart, sakari.ailus, javier, Pawel Osciak,
	Marek Szyprowski, Kyungmin Park, Jaroslav Kysela, Arnd Bergmann,
	dan.carpenter, Malcolm Priestley, Antti Palosaari,
	ruchandani.tina, corbet, chehabrafael, k.kozlowski,
	Stefan Richter, inki.dae, jh1009.sung, SF Markus Elfring,
	Prabhakar Lad, sw0312.kim, p.zabel, Ricardo Ribalda Delgado,
	labbott, Pierre-Louis Bossart, ricard.wanderlof, Julian Scheel,
	takamichiho, dominic.sacre, misterpib, daniel, Jurgen Kramer,
	normalperson, joe, linuxbugs, johan, Linux Kernel,
	Linux Media Mailing List, linux-api, alsa-devel

Hi Shuah, Mauro,

>> Did you test the code when the input is not a tuner, but, instead,
>> Composite or S-Video connector, as shown at:
>>       https://mchehab.fedorapeople.org/mc-next-gen/au0828.png
>
> I am not sure if I did or not. I can double check this case.
> Do you have concerns that this won't work?

I'm not sure how you expect the MC framework to be handling this case,
but I can tell you that the hardware will *not* support simultaneous
streaming of the DVB feed at the same time as the analog feed, even if
you're using the composite/s-video input and not actually using the
xc5000 tuner in analog mode.

Devin

-- 
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com

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

* Re: [PATCH 20/31] media: au0828 change to register/unregister entity_notify hook
  2016-01-28 16:36   ` Mauro Carvalho Chehab
@ 2016-01-28 20:05     ` Shuah Khan
  2016-01-28 20:20       ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-28 20:05 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel, Shuah Khan

On 01/28/2016 09:36 AM, Mauro Carvalho Chehab wrote:
> Em Wed,  6 Jan 2016 13:27:09 -0700
> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> 
>> au0828 registers entity_notify hook to create media graph for
>> the device. This handler runs whenvere a new entity gets added
> 
> typo: whenever.

ok

> 
>> to the media device. It creates necessary links from video, vbi,
>> and ALSA entities to decoder and links tuner and decoder entities.
>> As this handler runs as entities get added, it has to maintain
>> state on the links it already created. New fields are added to
>> au0828_dev to keep this state information. entity_notify gets
>> unregistered before media_device unregister.
> 
> Bty, please avoid long paragraphs at the patch description, 
> and please try to be clearer on your patch descriptions... That
> makes boring to read everything. :-;

Yeah I like to add details I consider relevant to the log.
I will try to be concise.

> 
>>
>> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
>> ---
>>  drivers/media/usb/au0828/au0828-core.c | 104 +++++++++++++++++++++++----------
>>  drivers/media/usb/au0828/au0828.h      |   6 ++
>>  2 files changed, 78 insertions(+), 32 deletions(-)
>>
>> diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
>> index 6ef177c..a381660 100644
>> --- a/drivers/media/usb/au0828/au0828-core.c
>> +++ b/drivers/media/usb/au0828/au0828-core.c
>> @@ -137,6 +137,8 @@ static void au0828_unregister_media_device(struct au0828_dev *dev)
>>  #ifdef CONFIG_MEDIA_CONTROLLER
>>  	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);
>>  		media_device_cleanup(dev->media_dev);
>>  		dev->media_dev = NULL;
>> @@ -263,11 +265,16 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
>>  	struct media_device *mdev = dev->media_dev;
>>  	struct media_entity *entity;
>>  	struct media_entity *tuner = NULL, *decoder = NULL;
>> +	struct media_entity *audio_capture = NULL;
>>  	int i, ret;
>>  
>>  	if (!mdev)
>>  		return 0;
>>  
>> +	if (dev->tuner_linked && dev->vdev_linked && dev->vbi_linked &&
>> +	    dev->audio_capture_linked)
>> +		return 0;
>> +
>>  	media_device_for_each_entity(entity, mdev) {
>>  		switch (entity->function) {
>>  		case MEDIA_ENT_F_TUNER:
>> @@ -276,6 +283,9 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
>>  		case MEDIA_ENT_F_ATV_DECODER:
>>  			decoder = entity;
>>  			break;
>> +		case MEDIA_ENT_F_AUDIO_CAPTURE:
>> +			audio_capture = entity;
>> +			break;
>>  		}
>>  	}
>>  
>> @@ -285,60 +295,77 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
>>  	if (!decoder)
>>  		return -EINVAL;
>>  
>> -	if (tuner) {
>> +	if (tuner  && !dev->tuner_linked) {
>> +		dev->tuner = tuner;
>>  		ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT,
>>  					    decoder, 0,
>>  					    MEDIA_LNK_FL_ENABLED);
>>  		if (ret)
>>  			return ret;
>> +		dev->tuner_linked = 1;
>>  	}
>> -	if (dev->vdev.entity.graph_obj.mdev) {
>> +	if (dev->vdev.entity.graph_obj.mdev && !dev->vdev_linked) {
>>  		ret = media_create_pad_link(decoder, AU8522_PAD_VID_OUT,
>>  					    &dev->vdev.entity, 0,
>>  					    MEDIA_LNK_FL_ENABLED);
>>  		if (ret)
>>  			return ret;
>> +		dev->vdev_linked = 1;
>>  	}
>> -	if (dev->vbi_dev.entity.graph_obj.mdev) {
>> +	if (dev->vbi_dev.entity.graph_obj.mdev && !dev->vbi_linked) {
>>  		ret = media_create_pad_link(decoder, AU8522_PAD_VBI_OUT,
>>  					    &dev->vbi_dev.entity, 0,
>>  					    MEDIA_LNK_FL_ENABLED);
>>  		if (ret)
>>  			return ret;
>> -	}
>> -
>> -	for (i = 0; i < AU0828_MAX_INPUT; i++) {
>> -		struct media_entity *ent = &dev->input_ent[i];
>> +		dev->vbi_linked = 1;
>>  
>> -		if (!ent->graph_obj.mdev)
>> -			continue;
>> +		/*
>> +		 * Input entities are registered before vbi entity,
>> +		 * create graph nodes for them after vbi is created
>> +		*/
>> +		for (i = 0; i < AU0828_MAX_INPUT; i++) {
>> +			struct media_entity *ent = &dev->input_ent[i];
>>  
>> -		if (AUVI_INPUT(i).type == AU0828_VMUX_UNDEFINED)
>> -			break;
>> +			if (!ent->graph_obj.mdev)
>> +				continue;
>>  
>> -		switch (AUVI_INPUT(i).type) {
>> -		case AU0828_VMUX_CABLE:
>> -		case AU0828_VMUX_TELEVISION:
>> -		case AU0828_VMUX_DVB:
>> -			if (!tuner)
>> +			if (AUVI_INPUT(i).type == AU0828_VMUX_UNDEFINED)
>>  				break;
>>  
>> -			ret = media_create_pad_link(ent, 0, tuner,
>> -						    TUNER_PAD_RF_INPUT,
>> -						    MEDIA_LNK_FL_ENABLED);
>> -			if (ret)
>> -				return ret;
>> -			break;
>> -		case AU0828_VMUX_COMPOSITE:
>> -		case AU0828_VMUX_SVIDEO:
>> -		default: /* AU0828_VMUX_DEBUG */
>> -			/* FIXME: fix the decoder PAD */
>> -			ret = media_create_pad_link(ent, 0, decoder, 0, 0);
>> -			if (ret)
>> -				return ret;
>> -			break;
>> +			switch (AUVI_INPUT(i).type) {
>> +			case AU0828_VMUX_CABLE:
>> +			case AU0828_VMUX_TELEVISION:
>> +			case AU0828_VMUX_DVB:
>> +				if (!tuner)
>> +					break;
>> +
>> +				ret = media_create_pad_link(ent, 0, tuner,
>> +							TUNER_PAD_RF_INPUT,
>> +							MEDIA_LNK_FL_ENABLED);
>> +				if (ret)
>> +					return ret;
>> +				break;
>> +			case AU0828_VMUX_COMPOSITE:
>> +			case AU0828_VMUX_SVIDEO:
>> +			default: /* AU0828_VMUX_DEBUG */
>> +				/* FIXME: fix the decoder PAD */
>> +				ret = media_create_pad_link(ent, 0, decoder,
>> +							    0, 0);
>> +				if (ret)
>> +					return ret;
>> +				break;
>> +			}
>>  		}
>>  	}
>> +	if (audio_capture && !dev->audio_capture_linked) {
>> +		ret = media_create_pad_link(decoder, AU8522_PAD_AUDIO_OUT,
>> +					    audio_capture, 0,
>> +					    MEDIA_LNK_FL_ENABLED);
>> +		if (ret)
>> +			return ret;
>> +		dev->audio_capture_linked = 1;
>> +	}
>>  #endif
>>  	return 0;
>>  }
>> @@ -349,8 +376,10 @@ static int au0828_media_device_register(struct au0828_dev *dev,
>>  #ifdef CONFIG_MEDIA_CONTROLLER
>>  	int ret;
>>  
>> -	if (dev->media_dev &&
>> -		!media_devnode_is_registered(&dev->media_dev->devnode)) {
>> +	if (!dev->media_dev)
>> +		return 0;
>> +
>> +	if (!media_devnode_is_registered(&dev->media_dev->devnode)) {
>>  
>>  		/* register media device */
>>  		ret = media_device_register(dev->media_dev);
>> @@ -360,6 +389,17 @@ static int au0828_media_device_register(struct au0828_dev *dev,
>>  			return ret;
>>  		}
>>  	}
>> +	/* register entity_notify callback */
>> +	dev->entity_notify.notify_data = (void *) dev;
>> +	dev->entity_notify.notify = (void *) au0828_create_media_graph;
>> +	ret = media_device_register_entity_notify(dev->media_dev,
>> +						  &dev->entity_notify);
>> +	if (ret) {
>> +		dev_err(&udev->dev,
>> +			"Media Device register entity_notify Error: %d\n",
>> +			ret);
>> +		return ret;
>> +	}
>>  #endif
>>  	return 0;
>>  }
>> diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
>> index 8276072..cfb6d58 100644
>> --- a/drivers/media/usb/au0828/au0828.h
>> +++ b/drivers/media/usb/au0828/au0828.h
>> @@ -283,6 +283,12 @@ struct au0828_dev {
>>  	struct media_entity *decoder;
>>  	struct media_entity input_ent[AU0828_MAX_INPUT];
>>  	struct media_pad input_pad[AU0828_MAX_INPUT];
>> +	struct media_entity_notify entity_notify;
>> +	struct media_entity *tuner;
>> +	bool tuner_linked;
>> +	bool vdev_linked;
>> +	bool vbi_linked;
>> +	bool audio_capture_linked;
> 
> Hmm... now I understood why you did the changes on patch 13/31.
> 
> I see what you're doing, but not sure if this is a good idea
> to have one bool for each possible device. On au0828, the
> topology is actually simpler than on other devices, as it
> currently supports a very few set of I2C devices, but on other
> drivers, things can be messier.
> 
> See, for example, two graphs for em28xx-based devices:
> 	https://mchehab.fedorapeople.org/mc-next-gen/wintv_usb2.png
> 	https://mchehab.fedorapeople.org/mc-next-gen/hvr_950.png
> 
> On the first graph, the tuner is not connected directly to the
> analog demod, but, instead, to two other elements:
> 	- tda9887 - for video
> 	- msp3400 - for audio
> 
> IMHO, the best way to handle graph setup is that each driver
> should handle the links that belong only to them synchronously,
> after creating/registering all the entities.

Except for the ALSA part of the graph, we are close
to drivers creating their graphs. You are right that
au0828 graph creation routine shouldn't need to create
links from Alsa mixer to Alsa capture nodes.
 
> 
> So, only the links between two drivers would be asynchronously
> created. So, In the case of au0828:
> 
> - au0828 core will create the connector entities;
> 
> - I2C drivers will create their own entities;
> 
> - DVB core will create the DVB entities/interfaces;
> 
> - V4L core will create V4L interfaces and I/O entities;
> 
> - au0828 V4L driver will create all V4L links, after
>   ensuring that the needed I2C drivers were bound;
> 
> - snd-usb-audio will create all ALSA-specific entities links;
> 
> The V4L->ALSA links will either be created by au0828-core,
> via the notification handler.

Right - that is part of what au0828_create_media_graph()
is doing now.

> 
> With that in mind, I don't see any need to touch at
> au0828_create_media_graph(). It will need an extra function
> to handle the notification when ALSA gets registered
> (or when the entities there are added, whatever works best).
> 

If I understand correctly, what you are saying is:

Don't add async handling that creates V4L->ALSA
to au0828_create_media_graph() and keep that in
an async handler.

I will make changes to address this.

thanks,
-- Shuah
> 
> 
> 
> 
> 
>>  #endif
>>  };
>>  


-- 
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] 79+ messages in thread

* Re: [PATCH 22/31] media: dvb-core create tuner to demod pad link in disabled state
  2016-01-28 16:38   ` Mauro Carvalho Chehab
@ 2016-01-28 20:09     ` Shuah Khan
  0 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-28 20:09 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel, Shuah Khan

On 01/28/2016 09:38 AM, Mauro Carvalho Chehab wrote:
> Em Wed,  6 Jan 2016 13:27:11 -0700
> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> 
>> Create tuner to demod pad link in disabled state to help avoid
>> disable step when tuner resource is requested by video or audio.
>>
>> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
>> ---
>>  drivers/media/dvb-core/dvbdev.c | 3 ++-
>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
>> index b56e008..1d10fa6 100644
>> --- a/drivers/media/dvb-core/dvbdev.c
>> +++ b/drivers/media/dvb-core/dvbdev.c
>> @@ -593,8 +593,9 @@ int dvb_create_media_graph(struct dvb_adapter *adap)
>>  	}
>>  
>>  	if (tuner && demod) {
>> +		/* create tuner to demod link deactivated */
>>  		ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT,
>> -					    demod, 0, MEDIA_LNK_FL_ENABLED);
>> +					    demod, 0, 0);
> 
> This is not right, as it makes no sense for DVB-only drivers.

Right. Not a good change for DVB only drivers. But does make
sense on hybrid. I will make sure it gets done only in hyrbid
cases.

thanks,
-- Shuah

> 
>>  		if (ret)
>>  			return ret;
>>  	}


-- 
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] 79+ messages in thread

* Re: [PATCH 23/31] media: au0828 implement enable_source and disable_source handlers
  2016-01-28 16:43   ` Mauro Carvalho Chehab
@ 2016-01-28 20:14     ` Shuah Khan
  0 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-28 20:14 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, hans.verkuil
  Cc: tiwai, clemens, laurent.pinchart, sakari.ailus, javier, pawel,
	m.szyprowski, kyungmin.park, perex, arnd, dan.carpenter,
	tvboxspy, crope, ruchandani.tina, corbet, chehabrafael,
	k.kozlowski, stefanr, inki.dae, jh1009.sung, elfring,
	prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda, labbott,
	pierre-louis.bossart, ricard.wanderlof, julian, takamichiho,
	dominic.sacre, misterpib, daniel, gtmkramer, normalperson, joe,
	linuxbugs, johan, linux-kernel, linux-media, linux-api,
	alsa-devel, Shuah Khan

On 01/28/2016 09:43 AM, Mauro Carvalho Chehab wrote:
> Em Wed,  6 Jan 2016 13:27:12 -0700
> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> 
>> Implements enable_source and disable_source handlers for other
>> drivers (v4l2-core, dvb-core, and ALSA) to use to check for
>> tuner connected to the decoder and activate the link if tuner
>> is free, and deactivate and free the tuner when it is no longer
>> needed.
>>
>> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
>> ---
>>  drivers/media/usb/au0828/au0828-core.c | 148 +++++++++++++++++++++++++++++++++
>>  drivers/media/usb/au0828/au0828.h      |   2 +
>>  2 files changed, 150 insertions(+)
>>
>> diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
>> index a15a61a..f8d2db3 100644
>> --- a/drivers/media/usb/au0828/au0828-core.c
>> +++ b/drivers/media/usb/au0828/au0828-core.c
>> @@ -370,6 +370,150 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
>>  	return 0;
>>  }
>>  
>> +static int au0828_enable_source(struct media_entity *entity,
>> +				struct media_pipeline *pipe)
>> +{
> 
> The best would be to put those enable source stuff at the core, in a way
> that other drivers could share it.

Hans and I discussed this at the Media Summit in Finland.
It will be very difficult to make this work in a generic
way. Besides, bridge driver knows the hardware it has and
it would make sense for it to implement enable and disable
source handlers.

> 
> Not sure about the implementation, as this requires testing ;)
> Did you consider the cases where the source connector is S-Video
> or Composite?

I think you asked this question on another patch and Devin
responded to that thread. Let's discuss it there.

thanks,
-- Shuah
> 
>> +#ifdef CONFIG_MEDIA_CONTROLLER
>> +	struct media_entity  *source;
>> +	struct media_entity *sink;
>> +	struct media_link *link, *found_link = NULL;
>> +	int ret = 0;
>> +	struct media_device *mdev = entity->graph_obj.mdev;
>> +	struct au0828_dev *dev;
>> +
>> +	if (!mdev)
>> +		return -ENODEV;
>> +
>> +	/* for Audio and Video entities, source is the decoder */
>> +	mutex_lock(&mdev->graph_mutex);
>> +
>> +	dev = mdev->source_priv;
>> +	if (!dev->tuner || !dev->decoder) {
>> +		ret = -ENODEV;
>> +		goto end;
>> +	}
>> +
>> +	/*
>> +	 * For Audio and V4L2 entity, find the link to which decoder
>> +	 * is the sink. Look for an active link between decoder and
>> +	 * tuner, if one exists, nothing to do. If not, look for any
>> +	 * active links between tuner and any other entity. If one
>> +	 * exists, tuner is busy. If tuner is free, setup link and
>> +	 * start pipeline from source (tuner).
>> +	 * For DVB FE entity, the source for the link is the tuner.
>> +	 * Check if tuner is available and setup link and start
>> +	 * pipeline.
>> +	*/
>> +	if (entity->function != MEDIA_ENT_F_DTV_DEMOD)
>> +		sink = dev->decoder;
>> +	else
>> +		sink = entity;
>> +
>> +	/* Is an active link between sink and tuner */
>> +	if (dev->active_link) {
>> +		if (dev->active_link->sink->entity == sink &&
>> +		    dev->active_link->source->entity == dev->tuner) {
>> +			ret = 0;
>> +			goto end;
>> +		} else {
>> +			ret = -EBUSY;
>> +			goto end;
>> +		}
>> +	}
>> +
>> +	list_for_each_entry(link, &sink->links, list) {
>> +		/* Check sink, and source */
>> +		if (link->sink->entity == sink &&
>> +		    link->source->entity == dev->tuner) {
>> +			found_link = link;
>> +			break;
>> +		}
>> +	}
>> +
>> +	if (!found_link) {
>> +		ret = -ENODEV;
>> +		goto end;
>> +	}
>> +
>> +	/* activate link between source and sink and start pipeline */
>> +	source = found_link->source->entity;
>> +	ret = __media_entity_setup_link(found_link, MEDIA_LNK_FL_ENABLED);
>> +	if (ret) {
>> +		pr_err(
>> +			"Activate tuner link %s->%s. Error %d\n",
>> +			source->name, sink->name, ret);
>> +		goto end;
>> +	}
>> +
>> +	ret = __media_entity_pipeline_start(entity, pipe);
>> +	if (ret) {
>> +		pr_err("Start Pipeline: %s->%s Error %d\n",
>> +			source->name, entity->name, ret);
>> +		ret = __media_entity_setup_link(found_link, 0);
>> +		pr_err("Deactive link Error %d\n", ret);
>> +		goto end;
>> +	}
>> +	/*
>> +	 * save active link and active link owner to avoid audio
>> +	 * deactivating video owned link from disable_source and
>> +	 * vice versa
>> +	*/
>> +	dev->active_link = found_link;
>> +	dev->active_link_owner = entity;
>> +end:
>> +	mutex_unlock(&mdev->graph_mutex);
>> +	pr_debug("au0828_enable_source() end %s %d %d\n",
>> +		entity->name, entity->function, ret);
>> +	return ret;
>> +#endif
>> +	return 0;
>> +}
>> +
>> +static void au0828_disable_source(struct media_entity *entity)
>> +{
>> +#ifdef CONFIG_MEDIA_CONTROLLER
>> +	struct media_entity *sink;
>> +	int ret = 0;
>> +	struct media_device *mdev = entity->graph_obj.mdev;
>> +	struct au0828_dev *dev;
>> +
>> +	if (!mdev)
>> +		return;
>> +
>> +	mutex_lock(&mdev->graph_mutex);
>> +	dev = mdev->source_priv;
>> +	if (!dev->tuner || !dev->decoder || !dev->active_link) {
>> +		ret = -ENODEV;
>> +		goto end;
>> +	}
>> +
>> +	if (entity->function != MEDIA_ENT_F_DTV_DEMOD)
>> +		sink = dev->decoder;
>> +	else
>> +		sink = entity;
>> +
>> +	/* link is active - stop pipeline from source (tuner) */
>> +	if (dev->active_link && dev->active_link->sink->entity == sink &&
>> +	    dev->active_link->source->entity == dev->tuner) {
>> +		/*
>> +		 * prevent video from deactivating link when audio
>> +		 * has active pipeline
>> +		*/
>> +		if (dev->active_link_owner != entity)
>> +			goto end;
>> +		__media_entity_pipeline_stop(entity);
>> +		ret = __media_entity_setup_link(dev->active_link, 0);
>> +		if (ret)
>> +			pr_err("Deactive link Error %d\n", ret);
>> +		dev->active_link = NULL;
>> +		dev->active_link_owner = NULL;
>> +	}
>> +
>> +end:
>> +	mutex_unlock(&mdev->graph_mutex);
>> +#endif
>> +}
>> +
>>  static int au0828_media_device_register(struct au0828_dev *dev,
>>  					struct usb_device *udev)
>>  {
>> @@ -400,6 +544,10 @@ static int au0828_media_device_register(struct au0828_dev *dev,
>>  			ret);
>>  		return ret;
>>  	}
>> +	/* set enable_source */
>> +	dev->media_dev->source_priv = (void *) dev;
>> +	dev->media_dev->enable_source = au0828_enable_source;
>> +	dev->media_dev->disable_source = au0828_disable_source;
>>  #endif
>>  	return 0;
>>  }
>> diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
>> index cfb6d58..3707664 100644
>> --- a/drivers/media/usb/au0828/au0828.h
>> +++ b/drivers/media/usb/au0828/au0828.h
>> @@ -289,6 +289,8 @@ struct au0828_dev {
>>  	bool vdev_linked;
>>  	bool vbi_linked;
>>  	bool audio_capture_linked;
>> +	struct media_link *active_link;
>> +	struct media_entity *active_link_owner;
>>  #endif
>>  };
>>  


-- 
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] 79+ messages in thread

* Re: [PATCH 24/31] media: au0828 fix null pointer reference in au0828_create_media_graph()
  2016-01-28 16:44   ` Mauro Carvalho Chehab
@ 2016-01-28 20:15     ` Shuah Khan
  0 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-28 20:15 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel, Shuah Khan

On 01/28/2016 09:44 AM, Mauro Carvalho Chehab wrote:
> Em Wed,  6 Jan 2016 13:27:13 -0700
> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> 
>> Add a new wrapper function to au0828_create_media_graph()
>> to be called as an entity_notify function to fix null
>> pointer dereference. A rebasing mistake resulted in
>> registering au0828_create_media_graph() without the
>> correct parameters which lead to the following
>> null pointer dereference:
>>
>> [   69.006164] Call Trace:
>> [   69.006169]  [<ffffffff81a9a1b0>] dump_stack+0x44/0x64
>> [   69.006175]  [<ffffffff81503af9>] print_trailer+0xf9/0x150
>> [   69.006180]  [<ffffffff81509284>] object_err+0x34/0x40
>> [   69.006185]  [<ffffffff815063c4>] ? ___slab_alloc+0x4c4/0x4e0
>> [   69.006190]  [<ffffffff8150b732>] kasan_report_error+0x212/0x520
>> [   69.006196]  [<ffffffff815063c4>] ? ___slab_alloc+0x4c4/0x4e0
>> [   69.006201]  [<ffffffff8150ba83>] __asan_report_load1_noabort+0x43/0x50
>> [   69.006208]  [<ffffffffa0d30991>] ? au0828_create_media_graph+0x641/0x730 [au0828]
>> [   69.006215]  [<ffffffffa0d30991>] au0828_create_media_graph+0x641/0x730 [au0828]
>> [   69.006221]  [<ffffffff82245c3d>] media_device_register_entity+0x33d/0x4f0
>> [   69.006234]  [<ffffffffa0ebeb1c>] media_stream_init+0x2ac/0x610 [snd_usb_audio]
>> [   69.006247]  [<ffffffffa0ea9a70>] snd_usb_pcm_open+0xcd0/0x1280 [snd_usb_audio]
> 
> Please merge the fix with the patch that caused the regression.

ok will merge it.

thanks,
-- Shuah
> 
>>
>> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
>> ---
>>  drivers/media/usb/au0828/au0828-core.c | 16 +++++++++++++++-
>>  1 file changed, 15 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
>> index f8d2db3..9497ad1 100644
>> --- a/drivers/media/usb/au0828/au0828-core.c
>> +++ b/drivers/media/usb/au0828/au0828-core.c
>> @@ -370,6 +370,20 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
>>  	return 0;
>>  }
>>  
>> +void au0828_create_media_graph_notify(struct media_entity *new,
>> +				      void *notify_data)
>> +{
>> +#ifdef CONFIG_MEDIA_CONTROLLER
>> +	struct au0828_dev *dev = (struct au0828_dev *) notify_data;
>> +	int ret;
>> +
>> +	ret = au0828_create_media_graph(dev);
>> +	if (ret)
>> +		pr_err("%s() media graph create failed for new entity %s\n",
>> +		       __func__, new->name);
>> +#endif
>> +}
>> +
>>  static int au0828_enable_source(struct media_entity *entity,
>>  				struct media_pipeline *pipe)
>>  {
>> @@ -535,7 +549,7 @@ static int au0828_media_device_register(struct au0828_dev *dev,
>>  	}
>>  	/* register entity_notify callback */
>>  	dev->entity_notify.notify_data = (void *) dev;
>> -	dev->entity_notify.notify = (void *) au0828_create_media_graph;
>> +	dev->entity_notify.notify = au0828_create_media_graph_notify;
>>  	ret = media_device_register_entity_notify(dev->media_dev,
>>  						  &dev->entity_notify);
>>  	if (ret) {


-- 
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] 79+ messages in thread

* Re: [PATCH 25/31] media: au0828 fix to not call media_device_unregister_entity_notify()
  2016-01-28 16:45   ` Mauro Carvalho Chehab
@ 2016-01-28 20:15     ` Shuah Khan
  0 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-28 20:15 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel, Shuah Khan

On 01/28/2016 09:45 AM, Mauro Carvalho Chehab wrote:
> Em Wed,  6 Jan 2016 14:01:54 -0700
> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> 
>> entity_notify handlers are removed from media_device_unregister().
>> There is no need to call media_device_unregister_entity_notify()
>> to do that right before calling media_device_unregister().
> 
> Please merge with the patch that added it.

ok

> 
>>
>> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
>> ---
>>  drivers/media/usb/au0828/au0828-core.c | 2 --
>>  1 file changed, 2 deletions(-)
>>
>> diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
>> index 9497ad1..722e073 100644
>> --- a/drivers/media/usb/au0828/au0828-core.c
>> +++ b/drivers/media/usb/au0828/au0828-core.c
>> @@ -137,8 +137,6 @@ static void au0828_unregister_media_device(struct au0828_dev *dev)
>>  #ifdef CONFIG_MEDIA_CONTROLLER
>>  	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);
>>  		media_device_cleanup(dev->media_dev);
>>  		dev->media_dev = NULL;


-- 
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] 79+ messages in thread

* Re: [PATCH 28/31] media: au0828 create link between ALSA Mixer and decoder
  2016-01-28 16:58   ` Mauro Carvalho Chehab
@ 2016-01-28 20:17     ` Shuah Khan
  0 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-28 20:17 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel, Shuah Khan

On 01/28/2016 09:58 AM, Mauro Carvalho Chehab wrote:
> Em Wed,  6 Jan 2016 13:27:17 -0700
> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> 
>> Change au0828_create_media_graph() to create pad link
>> between MEDIA_ENT_F_AUDIO_MIXER entity and decoder's
>> AU8522_PAD_AUDIO_OUT. With mixer entity now linked to
>> decoder, change to link MEDIA_ENT_F_AUDIO_CAPTURE to
>> mixer's source pad.
> 
> See my comments about doing only this asynchronously on the previous
> patches.
> 

Yes. I responded to that one. I might collapse both ALSA
patch that adds capture and mixer into one. Might make
it lot easier and handle them at the same time.

thanks,
-- Shuah

> 
>>
>> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
>> ---
>>  drivers/media/usb/au0828/au0828-core.c | 17 ++++++++++++++---
>>  drivers/media/usb/au0828/au0828.h      |  1 +
>>  2 files changed, 15 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
>> index 722e073..886fb28 100644
>> --- a/drivers/media/usb/au0828/au0828-core.c
>> +++ b/drivers/media/usb/au0828/au0828-core.c
>> @@ -264,6 +264,7 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
>>  	struct media_entity *entity;
>>  	struct media_entity *tuner = NULL, *decoder = NULL;
>>  	struct media_entity *audio_capture = NULL;
>> +	struct media_entity *mixer = NULL;
>>  	int i, ret;
>>  
>>  	if (!mdev)
>> @@ -284,6 +285,9 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
>>  		case MEDIA_ENT_F_AUDIO_CAPTURE:
>>  			audio_capture = entity;
>>  			break;
>> +		case MEDIA_ENT_F_AUDIO_MIXER:
>> +			mixer = entity;
>> +			break;
>>  		}
>>  	}
>>  
>> @@ -356,14 +360,21 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
>>  			}
>>  		}
>>  	}
>> -	if (audio_capture && !dev->audio_capture_linked) {
>> -		ret = media_create_pad_link(decoder, AU8522_PAD_AUDIO_OUT,
>> -					    audio_capture, 0,
>> +	if (mixer && audio_capture && !dev->audio_capture_linked) {
>> +		ret = media_create_pad_link(mixer, 1, audio_capture, 0,
>>  					    MEDIA_LNK_FL_ENABLED);
>>  		if (ret)
>>  			return ret;
>>  		dev->audio_capture_linked = 1;
>>  	}
>> +	if (mixer && !dev->mixer_linked) {
>> +		ret = media_create_pad_link(decoder, AU8522_PAD_AUDIO_OUT,
>> +					    mixer, 0,
>> +					    MEDIA_LNK_FL_ENABLED);
>> +		if (ret)
>> +			return ret;
>> +		dev->mixer_linked = 1;
>> +	}
>>  #endif
>>  	return 0;
>>  }
>> diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
>> index 3707664..b9aa74f 100644
>> --- a/drivers/media/usb/au0828/au0828.h
>> +++ b/drivers/media/usb/au0828/au0828.h
>> @@ -289,6 +289,7 @@ struct au0828_dev {
>>  	bool vdev_linked;
>>  	bool vbi_linked;
>>  	bool audio_capture_linked;
>> +	bool mixer_linked;
>>  	struct media_link *active_link;
>>  	struct media_entity *active_link_owner;
>>  #endif


-- 
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] 79+ messages in thread

* Re: [PATCH 20/31] media: au0828 change to register/unregister entity_notify hook
  2016-01-28 20:05     ` Shuah Khan
@ 2016-01-28 20:20       ` Mauro Carvalho Chehab
  0 siblings, 0 replies; 79+ messages in thread
From: Mauro Carvalho Chehab @ 2016-01-28 20:20 UTC (permalink / raw)
  To: Shuah Khan
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel

Em Thu, 28 Jan 2016 13:05:35 -0700
Shuah Khan <shuahkh@osg.samsung.com> escreveu:

> On 01/28/2016 09:36 AM, Mauro Carvalho Chehab wrote:
> > Em Wed,  6 Jan 2016 13:27:09 -0700
> > Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> >   
> >> au0828 registers entity_notify hook to create media graph for
> >> the device. This handler runs whenvere a new entity gets added  
> > 
> > typo: whenever.  
> 
> ok
> 
> >   
> >> to the media device. It creates necessary links from video, vbi,
> >> and ALSA entities to decoder and links tuner and decoder entities.
> >> As this handler runs as entities get added, it has to maintain
> >> state on the links it already created. New fields are added to
> >> au0828_dev to keep this state information. entity_notify gets
> >> unregistered before media_device unregister.  
> > 
> > Bty, please avoid long paragraphs at the patch description, 
> > and please try to be clearer on your patch descriptions... That
> > makes boring to read everything. :-;  
> 
> Yeah I like to add details I consider relevant to the log.
> I will try to be concise.

It is not a matter of removing details, but better organizing the
ideas. A single huge paragraph with lots of contents mixed inside
doesn't make easier for the readers ;)

> 
> >   
> >>
> >> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
> >> ---
> >>  drivers/media/usb/au0828/au0828-core.c | 104 +++++++++++++++++++++++----------
> >>  drivers/media/usb/au0828/au0828.h      |   6 ++
> >>  2 files changed, 78 insertions(+), 32 deletions(-)
> >>
> >> diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
> >> index 6ef177c..a381660 100644
> >> --- a/drivers/media/usb/au0828/au0828-core.c
> >> +++ b/drivers/media/usb/au0828/au0828-core.c
> >> @@ -137,6 +137,8 @@ static void au0828_unregister_media_device(struct au0828_dev *dev)
> >>  #ifdef CONFIG_MEDIA_CONTROLLER
> >>  	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);
> >>  		media_device_cleanup(dev->media_dev);
> >>  		dev->media_dev = NULL;
> >> @@ -263,11 +265,16 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
> >>  	struct media_device *mdev = dev->media_dev;
> >>  	struct media_entity *entity;
> >>  	struct media_entity *tuner = NULL, *decoder = NULL;
> >> +	struct media_entity *audio_capture = NULL;
> >>  	int i, ret;
> >>  
> >>  	if (!mdev)
> >>  		return 0;
> >>  
> >> +	if (dev->tuner_linked && dev->vdev_linked && dev->vbi_linked &&
> >> +	    dev->audio_capture_linked)
> >> +		return 0;
> >> +
> >>  	media_device_for_each_entity(entity, mdev) {
> >>  		switch (entity->function) {
> >>  		case MEDIA_ENT_F_TUNER:
> >> @@ -276,6 +283,9 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
> >>  		case MEDIA_ENT_F_ATV_DECODER:
> >>  			decoder = entity;
> >>  			break;
> >> +		case MEDIA_ENT_F_AUDIO_CAPTURE:
> >> +			audio_capture = entity;
> >> +			break;
> >>  		}
> >>  	}
> >>  
> >> @@ -285,60 +295,77 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
> >>  	if (!decoder)
> >>  		return -EINVAL;
> >>  
> >> -	if (tuner) {
> >> +	if (tuner  && !dev->tuner_linked) {
> >> +		dev->tuner = tuner;
> >>  		ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT,
> >>  					    decoder, 0,
> >>  					    MEDIA_LNK_FL_ENABLED);
> >>  		if (ret)
> >>  			return ret;
> >> +		dev->tuner_linked = 1;
> >>  	}
> >> -	if (dev->vdev.entity.graph_obj.mdev) {
> >> +	if (dev->vdev.entity.graph_obj.mdev && !dev->vdev_linked) {
> >>  		ret = media_create_pad_link(decoder, AU8522_PAD_VID_OUT,
> >>  					    &dev->vdev.entity, 0,
> >>  					    MEDIA_LNK_FL_ENABLED);
> >>  		if (ret)
> >>  			return ret;
> >> +		dev->vdev_linked = 1;
> >>  	}
> >> -	if (dev->vbi_dev.entity.graph_obj.mdev) {
> >> +	if (dev->vbi_dev.entity.graph_obj.mdev && !dev->vbi_linked) {
> >>  		ret = media_create_pad_link(decoder, AU8522_PAD_VBI_OUT,
> >>  					    &dev->vbi_dev.entity, 0,
> >>  					    MEDIA_LNK_FL_ENABLED);
> >>  		if (ret)
> >>  			return ret;
> >> -	}
> >> -
> >> -	for (i = 0; i < AU0828_MAX_INPUT; i++) {
> >> -		struct media_entity *ent = &dev->input_ent[i];
> >> +		dev->vbi_linked = 1;
> >>  
> >> -		if (!ent->graph_obj.mdev)
> >> -			continue;
> >> +		/*
> >> +		 * Input entities are registered before vbi entity,
> >> +		 * create graph nodes for them after vbi is created
> >> +		*/
> >> +		for (i = 0; i < AU0828_MAX_INPUT; i++) {
> >> +			struct media_entity *ent = &dev->input_ent[i];
> >>  
> >> -		if (AUVI_INPUT(i).type == AU0828_VMUX_UNDEFINED)
> >> -			break;
> >> +			if (!ent->graph_obj.mdev)
> >> +				continue;
> >>  
> >> -		switch (AUVI_INPUT(i).type) {
> >> -		case AU0828_VMUX_CABLE:
> >> -		case AU0828_VMUX_TELEVISION:
> >> -		case AU0828_VMUX_DVB:
> >> -			if (!tuner)
> >> +			if (AUVI_INPUT(i).type == AU0828_VMUX_UNDEFINED)
> >>  				break;
> >>  
> >> -			ret = media_create_pad_link(ent, 0, tuner,
> >> -						    TUNER_PAD_RF_INPUT,
> >> -						    MEDIA_LNK_FL_ENABLED);
> >> -			if (ret)
> >> -				return ret;
> >> -			break;
> >> -		case AU0828_VMUX_COMPOSITE:
> >> -		case AU0828_VMUX_SVIDEO:
> >> -		default: /* AU0828_VMUX_DEBUG */
> >> -			/* FIXME: fix the decoder PAD */
> >> -			ret = media_create_pad_link(ent, 0, decoder, 0, 0);
> >> -			if (ret)
> >> -				return ret;
> >> -			break;
> >> +			switch (AUVI_INPUT(i).type) {
> >> +			case AU0828_VMUX_CABLE:
> >> +			case AU0828_VMUX_TELEVISION:
> >> +			case AU0828_VMUX_DVB:
> >> +				if (!tuner)
> >> +					break;
> >> +
> >> +				ret = media_create_pad_link(ent, 0, tuner,
> >> +							TUNER_PAD_RF_INPUT,
> >> +							MEDIA_LNK_FL_ENABLED);
> >> +				if (ret)
> >> +					return ret;
> >> +				break;
> >> +			case AU0828_VMUX_COMPOSITE:
> >> +			case AU0828_VMUX_SVIDEO:
> >> +			default: /* AU0828_VMUX_DEBUG */
> >> +				/* FIXME: fix the decoder PAD */
> >> +				ret = media_create_pad_link(ent, 0, decoder,
> >> +							    0, 0);
> >> +				if (ret)
> >> +					return ret;
> >> +				break;
> >> +			}
> >>  		}
> >>  	}
> >> +	if (audio_capture && !dev->audio_capture_linked) {
> >> +		ret = media_create_pad_link(decoder, AU8522_PAD_AUDIO_OUT,
> >> +					    audio_capture, 0,
> >> +					    MEDIA_LNK_FL_ENABLED);
> >> +		if (ret)
> >> +			return ret;
> >> +		dev->audio_capture_linked = 1;
> >> +	}
> >>  #endif
> >>  	return 0;
> >>  }
> >> @@ -349,8 +376,10 @@ static int au0828_media_device_register(struct au0828_dev *dev,
> >>  #ifdef CONFIG_MEDIA_CONTROLLER
> >>  	int ret;
> >>  
> >> -	if (dev->media_dev &&
> >> -		!media_devnode_is_registered(&dev->media_dev->devnode)) {
> >> +	if (!dev->media_dev)
> >> +		return 0;
> >> +
> >> +	if (!media_devnode_is_registered(&dev->media_dev->devnode)) {
> >>  
> >>  		/* register media device */
> >>  		ret = media_device_register(dev->media_dev);
> >> @@ -360,6 +389,17 @@ static int au0828_media_device_register(struct au0828_dev *dev,
> >>  			return ret;
> >>  		}
> >>  	}
> >> +	/* register entity_notify callback */
> >> +	dev->entity_notify.notify_data = (void *) dev;
> >> +	dev->entity_notify.notify = (void *) au0828_create_media_graph;
> >> +	ret = media_device_register_entity_notify(dev->media_dev,
> >> +						  &dev->entity_notify);
> >> +	if (ret) {
> >> +		dev_err(&udev->dev,
> >> +			"Media Device register entity_notify Error: %d\n",
> >> +			ret);
> >> +		return ret;
> >> +	}
> >>  #endif
> >>  	return 0;
> >>  }
> >> diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
> >> index 8276072..cfb6d58 100644
> >> --- a/drivers/media/usb/au0828/au0828.h
> >> +++ b/drivers/media/usb/au0828/au0828.h
> >> @@ -283,6 +283,12 @@ struct au0828_dev {
> >>  	struct media_entity *decoder;
> >>  	struct media_entity input_ent[AU0828_MAX_INPUT];
> >>  	struct media_pad input_pad[AU0828_MAX_INPUT];
> >> +	struct media_entity_notify entity_notify;
> >> +	struct media_entity *tuner;
> >> +	bool tuner_linked;
> >> +	bool vdev_linked;
> >> +	bool vbi_linked;
> >> +	bool audio_capture_linked;  
> > 
> > Hmm... now I understood why you did the changes on patch 13/31.
> > 
> > I see what you're doing, but not sure if this is a good idea
> > to have one bool for each possible device. On au0828, the
> > topology is actually simpler than on other devices, as it
> > currently supports a very few set of I2C devices, but on other
> > drivers, things can be messier.
> > 
> > See, for example, two graphs for em28xx-based devices:
> > 	https://mchehab.fedorapeople.org/mc-next-gen/wintv_usb2.png
> > 	https://mchehab.fedorapeople.org/mc-next-gen/hvr_950.png
> > 
> > On the first graph, the tuner is not connected directly to the
> > analog demod, but, instead, to two other elements:
> > 	- tda9887 - for video
> > 	- msp3400 - for audio
> > 
> > IMHO, the best way to handle graph setup is that each driver
> > should handle the links that belong only to them synchronously,
> > after creating/registering all the entities.  
> 
> Except for the ALSA part of the graph, we are close
> to drivers creating their graphs. You are right that
> au0828 graph creation routine shouldn't need to create
> links from Alsa mixer to Alsa capture nodes.
>  
> > 
> > So, only the links between two drivers would be asynchronously
> > created. So, In the case of au0828:
> > 
> > - au0828 core will create the connector entities;
> > 
> > - I2C drivers will create their own entities;
> > 
> > - DVB core will create the DVB entities/interfaces;
> > 
> > - V4L core will create V4L interfaces and I/O entities;
> > 
> > - au0828 V4L driver will create all V4L links, after
> >   ensuring that the needed I2C drivers were bound;
> > 
> > - snd-usb-audio will create all ALSA-specific entities links;
> > 
> > The V4L->ALSA links will either be created by au0828-core,
> > via the notification handler.  
> 
> Right - that is part of what au0828_create_media_graph()
> is doing now.
> 
> > 
> > With that in mind, I don't see any need to touch at
> > au0828_create_media_graph(). It will need an extra function
> > to handle the notification when ALSA gets registered
> > (or when the entities there are added, whatever works best).
> >   
> 
> If I understand correctly, what you are saying is:
> 
> Don't add async handling that creates V4L->ALSA
> to au0828_create_media_graph() and keep that in
> an async handler.
> 
> I will make changes to address this.

Yes, instead of modifying the existing routine to make it async
and harder to read, add a separate function that will handle
just the things that need to be async there. That should reduce
the code complexity and the possibility of having potencial
hidden race conditions.

It also allows more complex logic on the sync routine when
it is needed, like the one needed to identify if the tuner is alone,
or if it has multiple IF and/or video processors (with is common
on some kinds of hardware). See such logic at:
	https://git.linuxtv.org/mchehab/experimental.git/commit/?h=mc_em28xx&id=f6c245842bc4ec6faf66aaf8b85baad47a730e3b

on em28xx_v4l2_create_media_graph() where the tuner logic
needs to check for both audio and video IF-PLL hardware.

Regards,
Mauro

> 
> thanks,
> -- Shuah
> > 
> > 
> > 
> > 
> >   
> >>  #endif
> >>  };
> >>    
> 
> 

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

* Re: [PATCH 31/31] media: au0828 change to check media device unregister progress state
  2016-01-28 17:05   ` Mauro Carvalho Chehab
@ 2016-01-28 20:31     ` Shuah Khan
  0 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-28 20:31 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel, Shuah Khan

On 01/28/2016 10:05 AM, Mauro Carvalho Chehab wrote:
> Em Wed,  6 Jan 2016 13:27:20 -0700
> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> 
>> Change au0828_unregister_media_device() to check media
>> device media device unregister is in progress and avoid
>> calling media_device_unregister() and other cleanup done
>> in au0828_unregister_media_device().
>>
>> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
>> ---
>>  drivers/media/usb/au0828/au0828-core.c | 4 +++-
>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
>> index 886fb28..de357a2 100644
>> --- a/drivers/media/usb/au0828/au0828-core.c
>> +++ b/drivers/media/usb/au0828/au0828-core.c
>> @@ -136,7 +136,9 @@ static void au0828_unregister_media_device(struct au0828_dev *dev)
>>  
>>  #ifdef CONFIG_MEDIA_CONTROLLER
>>  	if (dev->media_dev &&
>> -		media_devnode_is_registered(&dev->media_dev->devnode)) {
>> +		media_devnode_is_registered(&dev->media_dev->devnode) &&
>> +		!media_device_is_unregister_in_progress(dev->media_dev)) {
>> +
> 
> A kref would likely work better here.

Hope you saw my response to[PATCH 29/31] on why ensuring
two drivers don't get into unregister is necessary.

Could you please elaborate on kref. Are you saying adding
kref to struct media_device?

thanks,
-- Shuah
> 
>>  		media_device_unregister(dev->media_dev);
>>  		media_device_cleanup(dev->media_dev);
>>  		dev->media_dev = NULL;


-- 
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] 79+ messages in thread

* Re: [PATCH 04/31] media: Media Controller enable/disable source handler API
  2016-01-28 17:15       ` Mauro Carvalho Chehab
@ 2016-01-28 20:33         ` Shuah Khan
  0 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-01-28 20:33 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel, Shuah Khan

On 01/28/2016 10:15 AM, Mauro Carvalho Chehab wrote:
> Em Thu, 28 Jan 2016 09:28:37 -0700
> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> 
>> On 01/28/2016 08:19 AM, Mauro Carvalho Chehab wrote:
>>> Em Wed,  6 Jan 2016 13:26:53 -0700
>>> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
>>>   
>>>> Add new fields to struct media_device to add enable_source, and
>>>> disable_source handlers, and source_priv to stash driver private
>>>> data that is need to run these handlers. The enable_source handler
>>>> finds source entity for the passed in 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 these
>>>> handlers and private data 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 it and start pipeline between
>>>> the source and the entity. The disable_source handler deactivates the
>>>> link and stops the pipeline. This handler can be invoked from the
>>>> 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 | 19 +++++++++++++++++++
>>>>  1 file changed, 19 insertions(+)
>>>>
>>>> diff --git a/include/media/media-device.h b/include/media/media-device.h
>>>> index 6520d1c..04b6c2e 100644
>>>> --- a/include/media/media-device.h
>>>> +++ b/include/media/media-device.h
>>>> @@ -333,6 +333,25 @@ struct media_device {
>>>>  	/* Serializes graph operations. */
>>>>  	struct mutex graph_mutex;
>>>>  
>>>> +	/* Handlers to find source entity for the sink entity and
>>>> +	 * check if it is available, and activate the link using
>>>> +	 * media_entity_setup_link() interface and start pipeline
>>>> +	 * from the source to the entity.
>>>> +	 * 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.
>>>> +	 * Bridge driver sets source_priv with information
>>>> +	 * necessary to run enable/disable source handlers.
>>>> +	 *
>>>> +	 * 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.
>>>> +	*/
>>>> +	void *source_priv;
>>>> +	int (*enable_source)(struct media_entity *entity,
>>>> +			     struct media_pipeline *pipe);
>>>> +	void (*disable_source)(struct media_entity *entity);  
>>>
>>> Please document the new fields at the right place (Kernel-doc
>>> comment declared before the struct).
>>>
>>> Is this used by the media core? If so, please but the implementation
>>> here, to make it clearer why we need those things.
>>>   
>>>> +
>>>>  	int (*link_notify)(struct media_link *link, u32 flags,
>>>>  			   unsigned int notification);
>>>>  };  
>>
>> Hi Mauro,
>>
>> I don't have any problems adding documentation. I would
>> like to add documentation in a add-on to the patch series.
>> The main reason is once I add documentation to this patch,
>> the rest of the patches on this file don't apply and require
>> rebase and rework. I went though a couple of rounds of this
>> while you were adding documentation to the interfaces you
>> added.
>>
>> How about I add the documentation patches at the end of
>> the patch series? I am concerned that rebasing for the
>> documentation changes will introduce bugs. Are you okay
>> with this proposal?
> 
> I'm ok with that for those inlined kernel-doc stuff. On
> the changes at the uapi/linux/media.h, I would prefer if
> you could add the documentation together with the patch,
> as it makes clearer for the reviewers. As you only
> touched it on one or two patches, this won't cause any
> breakages on the remaining patches.
> 

ok I can add documentation to uapi/linux/media.h in the
same patch that adds new defines.

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] 79+ messages in thread

* Re: [PATCH 29/31] media: track media device unregister in progress
  2016-01-28 17:28       ` Mauro Carvalho Chehab
@ 2016-01-28 20:42         ` Shuah Khan
  2016-02-03 19:32           ` Shuah Khan
  0 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-01-28 20:42 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel, Shuah Khan

On 01/28/2016 10:28 AM, Mauro Carvalho Chehab wrote:
> Em Thu, 28 Jan 2016 10:04:24 -0700
> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> 
>> On 01/28/2016 10:01 AM, Mauro Carvalho Chehab wrote:
>>> Em Wed,  6 Jan 2016 13:27:18 -0700
>>> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
>>>   
>>>> Add support to track media device unregister in progress
>>>> state to prevent more than one driver entering unregister.
>>>> This enables fixing the general protection faults while
>>>> snd-usb-audio was cleaning up media resources for pcm
>>>> streams and mixers. In this patch a new interface is added
>>>> to return the unregister in progress state. Subsequent
>>>> patches to snd-usb-audio and au0828-core use this interface
>>>> to avoid entering unregister and attempting to unregister
>>>> entities and remove devnodes while unregister is in progress.
>>>> Media device unregister removes entities and interface nodes.  
>>>
>>> Hmm... isn't the spinlock enough to serialize it? It seems weird the
>>> need of an extra bool here to warrant that this is really serialized.
>>>   
>>
>> The spinlock and check for media_devnode_is_registered(&mdev->devnode)
>> aren't enough to ensure only one driver enters the unregister. 
>>
>> Please
>> note that the devnode isn't marked unregistered until the end in
>> media_device_unregister().
> 
> I guess the call to:
> 	device_remove_file(&mdev->devnode.dev, &dev_attr_model);
> 
> IMO, This should be, instead, at media_devnode_unregister().
> 
> Then, we can change the logic at media_devnode_unregister() to:
> 
> void media_devnode_unregister(struct media_devnode *mdev)
> {
> 	mutex_lock(&media_devnode_lock);
> 
> 	/* Check if mdev was ever registered at all */
> 	if (!media_devnode_is_registered(mdev)) {
> 		mutex_unlock(&media_devnode_lock);
> 		return;
> 	}
> 
> 	clear_bit(MEDIA_FLAG_REGISTERED, &mdev->flags);
> 	mutex_unlock(&media_devnode_lock);
> 	device_remove_file(&mdev->devnode.dev, &dev_attr_model);
> 	device_unregister(&mdev->dev);
> }
> 
> This sounds enough to avoid device_unregister() or device_remove_file()
> to be called twice.
> 

I can give it a try. There might other problems that could
result from media device being a devres in this case. The
last put_device on the usbdev parent device (media device
is created as devres for this), all device resources get
released. That might have to be solved in a different way.

For now I will see if your solution works.

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] 79+ messages in thread

* Re: [PATCH 01/31] uapi/media.h: Declare interface types for ALSA
  2016-01-28 14:59   ` Mauro Carvalho Chehab
@ 2016-02-01 16:07     ` Shuah Khan
  2016-02-01 16:18       ` Takashi Iwai
  0 siblings, 1 reply; 79+ messages in thread
From: Shuah Khan @ 2016-02-01 16:07 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, tiwai
  Cc: clemens, hans.verkuil, laurent.pinchart, sakari.ailus, javier,
	pawel, m.szyprowski, kyungmin.park, perex, arnd, dan.carpenter,
	tvboxspy, crope, ruchandani.tina, corbet, chehabrafael,
	k.kozlowski, stefanr, inki.dae, jh1009.sung, elfring,
	prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda, labbott,
	pierre-louis.bossart, ricard.wanderlof, julian, takamichiho,
	dominic.sacre, misterpib, daniel, gtmkramer, normalperson, joe,
	linuxbugs, johan, linux-kernel, linux-media, linux-api,
	alsa-devel

On 01/28/2016 07:59 AM, Mauro Carvalho Chehab wrote:
> Em Wed,  6 Jan 2016 13:26:50 -0700
> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> 
>> From: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
>>
>> Declare the interface types to be used on alsa for the new
>> G_TOPOLOGY ioctl.
>>
>> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
>> ---
>>  drivers/media/media-entity.c | 12 ++++++++++++
>>  include/uapi/linux/media.h   |  8 ++++++++
>>  2 files changed, 20 insertions(+)
>>
>> diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
>> index eb38bc3..6e02d19 100644
>> --- a/drivers/media/media-entity.c
>> +++ b/drivers/media/media-entity.c
>> @@ -65,6 +65,18 @@ static inline const char *intf_type(struct media_interface *intf)
>>  		return "v4l2-subdev";
>>  	case MEDIA_INTF_T_V4L_SWRADIO:
>>  		return "swradio";
>> +	case MEDIA_INTF_T_ALSA_PCM_CAPTURE:
>> +		return "pcm-capture";
>> +	case MEDIA_INTF_T_ALSA_PCM_PLAYBACK:
>> +		return "pcm-playback";
>> +	case MEDIA_INTF_T_ALSA_CONTROL:
>> +		return "alsa-control";
>> +	case MEDIA_INTF_T_ALSA_COMPRESS:
>> +		return "compress";
>> +	case MEDIA_INTF_T_ALSA_RAWMIDI:
>> +		return "rawmidi";
>> +	case MEDIA_INTF_T_ALSA_HWDEP:
>> +		return "hwdep";
>>  	default:
>>  		return "unknown-intf";
>>  	}
>> diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h
>> index cacfceb..75cbe92 100644
>> --- a/include/uapi/linux/media.h
>> +++ b/include/uapi/linux/media.h
>> @@ -252,6 +252,7 @@ struct media_links_enum {
>>  
>>  #define MEDIA_INTF_T_DVB_BASE	0x00000100
>>  #define MEDIA_INTF_T_V4L_BASE	0x00000200
>> +#define MEDIA_INTF_T_ALSA_BASE	0x00000300
>>  
>>  /* Interface types */
>>  
>> @@ -267,6 +268,13 @@ struct media_links_enum {
>>  #define MEDIA_INTF_T_V4L_SUBDEV (MEDIA_INTF_T_V4L_BASE + 3)
>>  #define MEDIA_INTF_T_V4L_SWRADIO (MEDIA_INTF_T_V4L_BASE + 4)
>>  
>> +#define MEDIA_INTF_T_ALSA_PCM_CAPTURE   (MEDIA_INTF_T_ALSA_BASE)
>> +#define MEDIA_INTF_T_ALSA_PCM_PLAYBACK  (MEDIA_INTF_T_ALSA_BASE + 1)
>> +#define MEDIA_INTF_T_ALSA_CONTROL       (MEDIA_INTF_T_ALSA_BASE + 2)
>> +#define MEDIA_INTF_T_ALSA_COMPRESS      (MEDIA_INTF_T_ALSA_BASE + 3)
>> +#define MEDIA_INTF_T_ALSA_RAWMIDI       (MEDIA_INTF_T_ALSA_BASE + 4)
>> +#define MEDIA_INTF_T_ALSA_HWDEP         (MEDIA_INTF_T_ALSA_BASE + 5)
> 
> Patch looks ok, but please document the new media interfaces at KernelDoc
> documentation.
> 

Hi Takashi,

If you are okay with these changes, could you please
Ack this patch. I am addressing documentation comment
from Mauro.

thanks,
-- Shuah
>> +
>>  /*
>>   * MC next gen API definitions
>>   *


-- 
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] 79+ messages in thread

* Re: [PATCH 01/31] uapi/media.h: Declare interface types for ALSA
  2016-02-01 16:07     ` Shuah Khan
@ 2016-02-01 16:18       ` Takashi Iwai
  2016-02-01 17:04         ` Shuah Khan
  0 siblings, 1 reply; 79+ messages in thread
From: Takashi Iwai @ 2016-02-01 16:18 UTC (permalink / raw)
  To: Shuah Khan
  Cc: Mauro Carvalho Chehab, alsa-devel, arnd, ricard.wanderlof,
	hans.verkuil, labbott, chehabrafael, misterpib, prabhakar.csengg,
	ricardo.ribalda, ruchandani.tina, takamichiho, tvboxspy,
	dominic.sacre, laurent.pinchart, crope, julian, clemens,
	pierre-louis.bossart, sakari.ailus, corbet, joe, johan,
	dan.carpenter, pawel, javier, p.zabel, perex, stefanr, inki.dae,
	jh1009.sung, k.kozlowski, kyungmin.park, m.szyprowski,
	sw0312.kim, elfring, linux-api, linux-kernel, linux-media,
	linuxbugs, gtmkramer, normalperson, daniel

On Mon, 01 Feb 2016 17:07:51 +0100,
Shuah Khan wrote:
> 
> On 01/28/2016 07:59 AM, Mauro Carvalho Chehab wrote:
> > Em Wed,  6 Jan 2016 13:26:50 -0700
> > Shuah Khan <shuahkh@osg.samsung.com> escreveu:
> > 
> >> From: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
> >>
> >> Declare the interface types to be used on alsa for the new
> >> G_TOPOLOGY ioctl.
> >>
> >> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
> >> ---
> >>  drivers/media/media-entity.c | 12 ++++++++++++
> >>  include/uapi/linux/media.h   |  8 ++++++++
> >>  2 files changed, 20 insertions(+)
> >>
> >> diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
> >> index eb38bc3..6e02d19 100644
> >> --- a/drivers/media/media-entity.c
> >> +++ b/drivers/media/media-entity.c
> >> @@ -65,6 +65,18 @@ static inline const char *intf_type(struct media_interface *intf)
> >>  		return "v4l2-subdev";
> >>  	case MEDIA_INTF_T_V4L_SWRADIO:
> >>  		return "swradio";
> >> +	case MEDIA_INTF_T_ALSA_PCM_CAPTURE:
> >> +		return "pcm-capture";
> >> +	case MEDIA_INTF_T_ALSA_PCM_PLAYBACK:
> >> +		return "pcm-playback";
> >> +	case MEDIA_INTF_T_ALSA_CONTROL:
> >> +		return "alsa-control";
> >> +	case MEDIA_INTF_T_ALSA_COMPRESS:
> >> +		return "compress";
> >> +	case MEDIA_INTF_T_ALSA_RAWMIDI:
> >> +		return "rawmidi";
> >> +	case MEDIA_INTF_T_ALSA_HWDEP:
> >> +		return "hwdep";
> >>  	default:
> >>  		return "unknown-intf";
> >>  	}
> >> diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h
> >> index cacfceb..75cbe92 100644
> >> --- a/include/uapi/linux/media.h
> >> +++ b/include/uapi/linux/media.h
> >> @@ -252,6 +252,7 @@ struct media_links_enum {
> >>  
> >>  #define MEDIA_INTF_T_DVB_BASE	0x00000100
> >>  #define MEDIA_INTF_T_V4L_BASE	0x00000200
> >> +#define MEDIA_INTF_T_ALSA_BASE	0x00000300
> >>  
> >>  /* Interface types */
> >>  
> >> @@ -267,6 +268,13 @@ struct media_links_enum {
> >>  #define MEDIA_INTF_T_V4L_SUBDEV (MEDIA_INTF_T_V4L_BASE + 3)
> >>  #define MEDIA_INTF_T_V4L_SWRADIO (MEDIA_INTF_T_V4L_BASE + 4)
> >>  
> >> +#define MEDIA_INTF_T_ALSA_PCM_CAPTURE   (MEDIA_INTF_T_ALSA_BASE)
> >> +#define MEDIA_INTF_T_ALSA_PCM_PLAYBACK  (MEDIA_INTF_T_ALSA_BASE + 1)
> >> +#define MEDIA_INTF_T_ALSA_CONTROL       (MEDIA_INTF_T_ALSA_BASE + 2)
> >> +#define MEDIA_INTF_T_ALSA_COMPRESS      (MEDIA_INTF_T_ALSA_BASE + 3)
> >> +#define MEDIA_INTF_T_ALSA_RAWMIDI       (MEDIA_INTF_T_ALSA_BASE + 4)
> >> +#define MEDIA_INTF_T_ALSA_HWDEP         (MEDIA_INTF_T_ALSA_BASE + 5)
> > 
> > Patch looks ok, but please document the new media interfaces at KernelDoc
> > documentation.
> > 
> 
> Hi Takashi,
> 
> If you are okay with these changes, could you please
> Ack this patch. I am addressing documentation comment
> from Mauro.

Well, the available ALSA devices are:

CONTROL
SEQUENCER
TIMER
COMPRESS
HWDEP
RAWMIDI
PCM_PLAYBACK
PCM_CAPTURE

as found in sound/minors.h.

Any reason not to define for some of them?


Takashi

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

* Re: [PATCH 01/31] uapi/media.h: Declare interface types for ALSA
  2016-02-01 16:18       ` Takashi Iwai
@ 2016-02-01 17:04         ` Shuah Khan
  0 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-02-01 17:04 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Mauro Carvalho Chehab, alsa-devel, arnd, ricard.wanderlof,
	hans.verkuil, labbott, chehabrafael, misterpib, prabhakar.csengg,
	ricardo.ribalda, ruchandani.tina, takamichiho, tvboxspy,
	dominic.sacre, laurent.pinchart, crope, julian, clemens,
	pierre-louis.bossart, sakari.ailus, corbet, joe, johan,
	dan.carpenter, pawel, javier, p.zabel, perex, stefanr, inki.dae,
	jh1009.sung, k.kozlowski, kyungmin.park, m.szyprowski,
	sw0312.kim, elfring, linux-api, linux-kernel, linux-media,
	linuxbugs, gtmkramer, normalperson, daniel, Shuah Khan

On 02/01/2016 09:18 AM, Takashi Iwai wrote:
> On Mon, 01 Feb 2016 17:07:51 +0100,
> Shuah Khan wrote:
>>
>> On 01/28/2016 07:59 AM, Mauro Carvalho Chehab wrote:
>>> Em Wed,  6 Jan 2016 13:26:50 -0700
>>> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
>>>
>>>> From: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
>>>>
>>>> Declare the interface types to be used on alsa for the new
>>>> G_TOPOLOGY ioctl.
>>>>
>>>> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
>>>> ---
>>>>  drivers/media/media-entity.c | 12 ++++++++++++
>>>>  include/uapi/linux/media.h   |  8 ++++++++
>>>>  2 files changed, 20 insertions(+)
>>>>
>>>> diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
>>>> index eb38bc3..6e02d19 100644
>>>> --- a/drivers/media/media-entity.c
>>>> +++ b/drivers/media/media-entity.c
>>>> @@ -65,6 +65,18 @@ static inline const char *intf_type(struct media_interface *intf)
>>>>  		return "v4l2-subdev";
>>>>  	case MEDIA_INTF_T_V4L_SWRADIO:
>>>>  		return "swradio";
>>>> +	case MEDIA_INTF_T_ALSA_PCM_CAPTURE:
>>>> +		return "pcm-capture";
>>>> +	case MEDIA_INTF_T_ALSA_PCM_PLAYBACK:
>>>> +		return "pcm-playback";
>>>> +	case MEDIA_INTF_T_ALSA_CONTROL:
>>>> +		return "alsa-control";
>>>> +	case MEDIA_INTF_T_ALSA_COMPRESS:
>>>> +		return "compress";
>>>> +	case MEDIA_INTF_T_ALSA_RAWMIDI:
>>>> +		return "rawmidi";
>>>> +	case MEDIA_INTF_T_ALSA_HWDEP:
>>>> +		return "hwdep";
>>>>  	default:
>>>>  		return "unknown-intf";
>>>>  	}
>>>> diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h
>>>> index cacfceb..75cbe92 100644
>>>> --- a/include/uapi/linux/media.h
>>>> +++ b/include/uapi/linux/media.h
>>>> @@ -252,6 +252,7 @@ struct media_links_enum {
>>>>  
>>>>  #define MEDIA_INTF_T_DVB_BASE	0x00000100
>>>>  #define MEDIA_INTF_T_V4L_BASE	0x00000200
>>>> +#define MEDIA_INTF_T_ALSA_BASE	0x00000300
>>>>  
>>>>  /* Interface types */
>>>>  
>>>> @@ -267,6 +268,13 @@ struct media_links_enum {
>>>>  #define MEDIA_INTF_T_V4L_SUBDEV (MEDIA_INTF_T_V4L_BASE + 3)
>>>>  #define MEDIA_INTF_T_V4L_SWRADIO (MEDIA_INTF_T_V4L_BASE + 4)
>>>>  
>>>> +#define MEDIA_INTF_T_ALSA_PCM_CAPTURE   (MEDIA_INTF_T_ALSA_BASE)
>>>> +#define MEDIA_INTF_T_ALSA_PCM_PLAYBACK  (MEDIA_INTF_T_ALSA_BASE + 1)
>>>> +#define MEDIA_INTF_T_ALSA_CONTROL       (MEDIA_INTF_T_ALSA_BASE + 2)
>>>> +#define MEDIA_INTF_T_ALSA_COMPRESS      (MEDIA_INTF_T_ALSA_BASE + 3)
>>>> +#define MEDIA_INTF_T_ALSA_RAWMIDI       (MEDIA_INTF_T_ALSA_BASE + 4)
>>>> +#define MEDIA_INTF_T_ALSA_HWDEP         (MEDIA_INTF_T_ALSA_BASE + 5)
>>>
>>> Patch looks ok, but please document the new media interfaces at KernelDoc
>>> documentation.
>>>
>>
>> Hi Takashi,
>>
>> If you are okay with these changes, could you please
>> Ack this patch. I am addressing documentation comment
>> from Mauro.
> 
> Well, the available ALSA devices are:
> 
> CONTROL
> SEQUENCER
> TIMER
> COMPRESS
> HWDEP
> RAWMIDI
> PCM_PLAYBACK
> PCM_CAPTURE
> 
> as found in sound/minors.h.
> 
> Any reason not to define for some of them?

Looks like SEQUENCER and TIMER are missing in
the MC defines. I can see how SEQUENCER could
be relevant as an MC node, however not sure
about TIMER use-case. That said, I don't see
any reason for not including it.

I will add Media Interface Types for both
of these missing ones.

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] 79+ messages in thread

* Re: [PATCH 29/31] media: track media device unregister in progress
  2016-01-28 20:42         ` Shuah Khan
@ 2016-02-03 19:32           ` Shuah Khan
  0 siblings, 0 replies; 79+ messages in thread
From: Shuah Khan @ 2016-02-03 19:32 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: tiwai, clemens, hans.verkuil, laurent.pinchart, sakari.ailus,
	javier, pawel, m.szyprowski, kyungmin.park, perex, arnd,
	dan.carpenter, tvboxspy, crope, ruchandani.tina, corbet,
	chehabrafael, k.kozlowski, stefanr, inki.dae, jh1009.sung,
	elfring, prabhakar.csengg, sw0312.kim, p.zabel, ricardo.ribalda,
	labbott, pierre-louis.bossart, ricard.wanderlof, julian,
	takamichiho, dominic.sacre, misterpib, daniel, gtmkramer,
	normalperson, joe, linuxbugs, johan, linux-kernel, linux-media,
	linux-api, alsa-devel, Shuah Khan

On 01/28/2016 01:42 PM, Shuah Khan wrote:
> On 01/28/2016 10:28 AM, Mauro Carvalho Chehab wrote:
>> Em Thu, 28 Jan 2016 10:04:24 -0700
>> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
>>
>>> On 01/28/2016 10:01 AM, Mauro Carvalho Chehab wrote:
>>>> Em Wed,  6 Jan 2016 13:27:18 -0700
>>>> Shuah Khan <shuahkh@osg.samsung.com> escreveu:
>>>>   
>>>>> Add support to track media device unregister in progress
>>>>> state to prevent more than one driver entering unregister.
>>>>> This enables fixing the general protection faults while
>>>>> snd-usb-audio was cleaning up media resources for pcm
>>>>> streams and mixers. In this patch a new interface is added
>>>>> to return the unregister in progress state. Subsequent
>>>>> patches to snd-usb-audio and au0828-core use this interface
>>>>> to avoid entering unregister and attempting to unregister
>>>>> entities and remove devnodes while unregister is in progress.
>>>>> Media device unregister removes entities and interface nodes.  
>>>>
>>>> Hmm... isn't the spinlock enough to serialize it? It seems weird the
>>>> need of an extra bool here to warrant that this is really serialized.
>>>>   
>>>
>>> The spinlock and check for media_devnode_is_registered(&mdev->devnode)
>>> aren't enough to ensure only one driver enters the unregister. 
>>>
>>> Please
>>> note that the devnode isn't marked unregistered until the end in
>>> media_device_unregister().
>>
>> I guess the call to:
>> 	device_remove_file(&mdev->devnode.dev, &dev_attr_model);
>>
>> IMO, This should be, instead, at media_devnode_unregister().
>>
>> Then, we can change the logic at media_devnode_unregister() to:
>>
>> void media_devnode_unregister(struct media_devnode *mdev)
>> {
>> 	mutex_lock(&media_devnode_lock);
>>
>> 	/* Check if mdev was ever registered at all */
>> 	if (!media_devnode_is_registered(mdev)) {
>> 		mutex_unlock(&media_devnode_lock);
>> 		return;
>> 	}
>>
>> 	clear_bit(MEDIA_FLAG_REGISTERED, &mdev->flags);
>> 	mutex_unlock(&media_devnode_lock);
>> 	device_remove_file(&mdev->devnode.dev, &dev_attr_model);
>> 	device_unregister(&mdev->dev);
>> }
>>
>> This sounds enough to avoid device_unregister() or device_remove_file()
>> to be called twice.
>>
> 
> I can give it a try. There might other problems that could
> result from media device being a devres in this case. The
> last put_device on the usbdev parent device (media device
> is created as devres for this), all device resources get
> released. That might have to be solved in a different way.
> 
> For now I will see if your solution works.

Hi Mauro,

Moving device_remove_file() won't be easy without
making more changes. The file is created in
media_device_regsiter() and all the attributes are
handled in media-device.c

One solution I can think of is clearing the
MEDIA_FLAG_REGISTERED bit very early in
media_device_unregister()

--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -759,6 +759,9 @@ void media_device_unregister(struct media_device *mdev)
                return;
        }
 
+       /* Protect unregister path - clear MEDIA_FLAG_REGISTERED */
+       clear_bit(MEDIA_FLAG_REGISTERED, &mdev->devnode.flags);
+
        /* Remove all entities from the media device */
        list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list)
                __media_device_unregister_entity(entity);

and changing media_devnode_unregister() to simply call
device_unregister(&mdev->dev);

Again clearing MEDIA_FLAG_REGISTERED bit in
media_device_unregister() some problems.
For one thing clearing this bit should be
done holding media_devnode_lock. It can be
done cleanly if we do the following:

How about if we split media_devnode_unregister()
into twp ohases:

media_devnode_start_unregister()
to clear this bit. It can do:

media_devnode_start_unregister()
{
	mutex_lock(&media_devnode_lock);
	if (!media_devnode_is_registered(mdev)) {
		mutex_unlock(&media_devnode_lock);
		return;
	}
	clear_bit(MEDIA_FLAG_REGISTERED, &mdev->flags);
	mutex_unlock(&media_devnode_lock);
}

then:media_device_unregister(struct media_device *mdev)
will call this first thing and then hold mdev->lock
do the rest and the call media_devnode_unregister()
and which will be changed to as follows:

--- a/drivers/media/media-devnode.c
+++ b/drivers/media/media-devnode.c
@@ -274,13 +274,6 @@ error:
 
 void media_devnode_unregister(struct media_devnode *mdev)
 {
-       /* Check if mdev was ever registered at all */
-       if (!media_devnode_is_registered(mdev))
-               return;
-
-       mutex_lock(&media_devnode_lock);
-       clear_bit(MEDIA_FLAG_REGISTERED, &mdev->flags);
-       mutex_unlock(&media_devnode_lock);
        device_unregister(&mdev->dev);
 }

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] 79+ messages in thread

end of thread, other threads:[~2016-02-03 19:33 UTC | newest]

Thread overview: 79+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-06 20:26 [PATCH 00/31] Sharing media resources across ALSA and au0828 drivers Shuah Khan
2016-01-06 20:26 ` [PATCH 01/31] uapi/media.h: Declare interface types for ALSA Shuah Khan
2016-01-28 14:59   ` Mauro Carvalho Chehab
2016-02-01 16:07     ` Shuah Khan
2016-02-01 16:18       ` Takashi Iwai
2016-02-01 17:04         ` Shuah Khan
2016-01-06 20:26 ` [PATCH 02/31] media: Add ALSA Media Controller function entities Shuah Khan
2016-01-28 15:02   ` Mauro Carvalho Chehab
2016-01-06 20:26 ` [PATCH 03/31] media: Media Controller register/unregister entity_notify API Shuah Khan
2016-01-28 15:13   ` Mauro Carvalho Chehab
2016-01-28 17:09     ` Shuah Khan
2016-01-06 20:26 ` [PATCH 04/31] media: Media Controller enable/disable source handler API Shuah Khan
2016-01-28 15:19   ` Mauro Carvalho Chehab
2016-01-28 16:28     ` Shuah Khan
2016-01-28 17:15       ` Mauro Carvalho Chehab
2016-01-28 20:33         ` Shuah Khan
2016-01-06 20:26 ` [PATCH 05/31] media: Media Controller fix to not let stream_count go negative Shuah Khan
2016-01-06 20:26 ` [PATCH 06/31] media: Media Controller export non locking __media_entity_setup_link() Shuah Khan
2016-01-06 20:26 ` [PATCH 07/31] media: Media Controller non-locking __media_entity_pipeline_start/stop() Shuah Khan
2016-01-06 20:26 ` [PATCH 08/31] media: v4l-core add v4l_enable/disable_media_tuner() helper functions Shuah Khan
2016-01-28 15:26   ` Mauro Carvalho Chehab
2016-01-28 17:12     ` Shuah Khan
2016-01-06 20:26 ` [PATCH 09/31] media: v4l2-core add v4l_vb2q_enable_media_tuner() helper Shuah Khan
2016-01-28 15:29   ` Mauro Carvalho Chehab
2016-01-28 17:31     ` Shuah Khan
2016-01-28 17:34       ` Mauro Carvalho Chehab
2016-01-06 20:26 ` [PATCH 10/31] media: Move au8522_media_pads enum to au8522.h from au8522_priv.h Shuah Khan
2016-01-06 20:27 ` [PATCH 11/31] media: au8522 change to create MC pad for ALSA Audio Out Shuah Khan
2016-01-06 20:27 ` [PATCH 12/31] media: au0828 Use au8522_media_pads enum for pad defines Shuah Khan
2016-01-06 20:27 ` [PATCH 13/31] media: au0828 fix au0828_create_media_graph() entity checks Shuah Khan
2016-01-28 15:37   ` Mauro Carvalho Chehab
2016-01-28 18:57     ` Shuah Khan
2016-01-06 20:27 ` [PATCH 14/31] media: Change v4l-core to check for tuner availability Shuah Khan
2016-01-06 20:27 ` [PATCH 15/31] media: dvb-frontend invoke enable/disable_source handlers Shuah Khan
2016-01-28 15:53   ` Mauro Carvalho Chehab
2016-01-28 16:07     ` One Thousand Gnomes
2016-01-28 16:59       ` Shuah Khan
2016-01-28 17:31         ` Mauro Carvalho Chehab
2016-01-06 20:27 ` [PATCH 16/31] media: au0828 video remove au0828_enable_analog_tuner() Shuah Khan
2016-01-06 20:27 ` [PATCH 17/31] media: au0828 video change to use v4l_enable_media_tuner() Shuah Khan
2016-01-28 15:57   ` Mauro Carvalho Chehab
2016-01-28 19:21     ` Shuah Khan
2016-01-28 19:33       ` Devin Heitmueller
2016-01-06 20:27 ` [PATCH 18/31] media: au0828 change to use Managed Media Controller API Shuah Khan
2016-01-06 20:27 ` [PATCH 19/31] media: au0828 handle media_init and media_register window Shuah Khan
2016-01-06 20:27 ` [PATCH 20/31] media: au0828 change to register/unregister entity_notify hook Shuah Khan
2016-01-28 16:36   ` Mauro Carvalho Chehab
2016-01-28 20:05     ` Shuah Khan
2016-01-28 20:20       ` Mauro Carvalho Chehab
2016-01-06 20:27 ` [PATCH 21/31] media: au0828 create tuner to decoder link in deactivated state Shuah Khan
2016-01-06 20:27 ` [PATCH 22/31] media: dvb-core create tuner to demod pad link in disabled state Shuah Khan
2016-01-28 16:38   ` Mauro Carvalho Chehab
2016-01-28 20:09     ` Shuah Khan
2016-01-06 20:27 ` [PATCH 23/31] media: au0828 implement enable_source and disable_source handlers Shuah Khan
2016-01-28 16:43   ` Mauro Carvalho Chehab
2016-01-28 20:14     ` Shuah Khan
2016-01-06 20:27 ` [PATCH 24/31] media: au0828 fix null pointer reference in au0828_create_media_graph() Shuah Khan
2016-01-28 16:44   ` Mauro Carvalho Chehab
2016-01-28 20:15     ` Shuah Khan
2016-01-06 20:27 ` [PATCH 28/31] media: au0828 create link between ALSA Mixer and decoder Shuah Khan
2016-01-28 16:58   ` Mauro Carvalho Chehab
2016-01-28 20:17     ` Shuah Khan
2016-01-06 20:27 ` [PATCH 29/31] media: track media device unregister in progress Shuah Khan
2016-01-28 17:01   ` Mauro Carvalho Chehab
2016-01-28 17:04     ` Shuah Khan
2016-01-28 17:28       ` Mauro Carvalho Chehab
2016-01-28 20:42         ` Shuah Khan
2016-02-03 19:32           ` Shuah Khan
2016-01-06 20:27 ` [PATCH 30/31] sound/usb: Check media device unregister progress state Shuah Khan
2016-01-06 20:27 ` [PATCH 31/31] media: au0828 change to check " Shuah Khan
2016-01-28 17:05   ` Mauro Carvalho Chehab
2016-01-28 20:31     ` Shuah Khan
2016-01-06 21:01 ` [PATCH 25/31] media: au0828 fix to not call media_device_unregister_entity_notify() Shuah Khan
2016-01-28 16:45   ` Mauro Carvalho Chehab
2016-01-28 20:15     ` Shuah Khan
2016-01-06 21:05 ` [PATCH 26/31] sound/usb: Update ALSA driver to use Managed Media Controller API Shuah Khan
2016-01-07 15:44   ` Takashi Iwai
2016-01-07 20:27     ` Shuah Khan
2016-01-06 21:05 ` [PATCH 27/31] sound/usb: Create media mixer function and control interface entities 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).