On Thursday 08 March 2018 06:40 PM, Winkler, Tomas wrote:
Interfaces to obtain and release the cl_device reference is developed.
Using these interfaces intel hdcp driver will get the reference to the mei
client devices, so that hdcp2.2 service calls can be routed to that client
device.

During registration, call back function will be registered with mei_hdcp driver
so that when the client device is removed intel hdcp driver can be informed.

At a time only one reference is allowed in this interfaces.

v2:
   Rebased.
Linux kernel already provide notification chain,  please use that.
Sensing a problem here. Publisher module (mei_hdcp) for the notifier chain is loaded later than the I915's hdcp init (subscriber to the module). Events that we will be interested are enabled and disabled states of the mei_hdcp_device.

I will explore further. Thanks for the suggestion
This is not needed and I'm not sure it will ever work.
I am not sure, why do you think like that. This might not be in good shape but this is completely functional.
This v2 series is tested for HDCP2.2 feature on drm-tip before publishing.

From starting I was not comfortable with this handshaking part between I915 and mei_hdcp. Thanks for the suggestions.
I will work on them.

--Ram

Tomas

Signed-off-by: Ramalingam C <ramalinga...@intel.com>
---
  drivers/misc/mei/hdcp/mei_hdcp.c | 55
+++++++++++++++++++++++++++++++++++++++-
  drivers/misc/mei/hdcp/mei_hdcp.h |  9 +++++++
  include/linux/mei_hdcp.h         | 47 ++++++++++++++++++++++++++++++++++
  3 files changed, 110 insertions(+), 1 deletion(-)  create mode 100644
include/linux/mei_hdcp.h

diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c
b/drivers/misc/mei/hdcp/mei_hdcp.c
index 25df7034cfb4..63f77800a6f7 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.c
+++ b/drivers/misc/mei/hdcp/mei_hdcp.c
@@ -55,18 +55,71 @@ static int mei_hdcp_probe(struct mei_cl_device
*cldev,
        mei_cldev_set_drvdata(cldev, &mei_hdcp);

        ret = mei_cldev_enable(cldev);
-       if (ret < 0)
+       if (ret < 0) {
                dev_err(&cldev->dev, "mei_cldev_enable Failed. %d\n", ret);
+               goto err;
+       }
+
+       if (mei_hdcp.notify_on_cldev_change)
+               mei_hdcp.notify_on_cldev_change(mei_hdcp.client, cldev);
+
+       return 0;
+err:
+       if (mei_hdcp.notify_on_cldev_change)
+               mei_hdcp.notify_on_cldev_change(mei_hdcp.client, NULL);

        return ret;
  }

  static int mei_hdcp_remove(struct mei_cl_device *cldev)  {
+       struct mei_hdcp *mei_hdcp = mei_cldev_get_drvdata(cldev);
+
+       if (mei_hdcp->notify_on_cldev_change)
+               mei_hdcp->notify_on_cldev_change(mei_hdcp->client, NULL);
+
        mei_cldev_disable(cldev);
+
        return 0;
  }

+int mei_hdcp_cldev_get_reference(void *client_data,
+                                struct mei_cl_device **cldev,
+                                void (*notify_change)(void *client,
+                                                      struct mei_cl_device
+                                                      *cldev))
+{
+       if (!notify_change || !client_data)
+               return -EINVAL;
+
+       if (mei_hdcp.ref_cnt)
+               return -EBUSY;
+
+       if (!mei_cldev_active_and_enabled(mei_hdcp.cldev)) {
+               if (!notify_change)
+                       return -EAGAIN;
+       } else {
+               *cldev = mei_hdcp.cldev;
+       }
+
+       mei_hdcp.ref_cnt++;
+       mei_hdcp.client = client_data;
+       mei_hdcp.notify_on_cldev_change = notify_change;
+
+       return 0;
+}
+EXPORT_SYMBOL(mei_hdcp_cldev_get_reference);
+
+void mei_hdcp_cldev_put_reference(struct mei_cl_device *cldev) {
+       if (cldev == mei_hdcp.cldev) {
+               mei_hdcp.ref_cnt--;
+               mei_hdcp.client = NULL;
+               mei_hdcp.notify_on_cldev_change = NULL;
+       }
+}
+EXPORT_SYMBOL(mei_hdcp_cldev_put_reference);
+
  #define WIDI_HECI_CLIENT_GUID UUID_LE(0xB638AB7E, 0x94E2,
0x4EA2, 0xA5, \
                                        0x52, 0xD1, 0xC5, 0x4B, \
                                        0x62, 0x7F, 0x04)
diff --git a/drivers/misc/mei/hdcp/mei_hdcp.h
b/drivers/misc/mei/hdcp/mei_hdcp.h
index c06c0d767c4f..7d792b5ad703 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.h
+++ b/drivers/misc/mei/hdcp/mei_hdcp.h
@@ -27,6 +27,15 @@

  struct mei_hdcp {
        struct mei_cl_device *cldev;
+
+       /* Reference to the HDCP2.2 service consumer */
+       void *client;
+
+       /* Callback function for the consumer on cl_device state change */
+       void (*notify_on_cldev_change)(void *client,
+                                     struct mei_cl_device *cldev);
+
+       int ref_cnt;
  };

  #endif /* __MEI_HDCP_H__ */
diff --git a/include/linux/mei_hdcp.h b/include/linux/mei_hdcp.h new file
mode 100644 index 000000000000..774b26da0c26
--- /dev/null
+++ b/include/linux/mei_hdcp.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2017 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+and its
+ * documentation for any purpose is hereby granted without fee,
+provided that
+ * the above copyright notice appear in all copies and that both that
+copyright
+ * notice and this permission notice appear in supporting
+documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without
+specific,
+ * written prior permission.  The copyright holders make no
+representations
+ * about the suitability of this software for any purpose.  It is
+provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO
THIS
+SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN
+NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL,
+INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
FROM LOSS
+OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR
+OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
OR
+PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _LINUX_MEI_HDCP_H
+#define _LINUX_MEI_HDCP_H
+
+#ifdef CONFIG_INTEL_MEI_HDCP
+int mei_hdcp_cldev_get_reference(void *client_data,
+                                struct mei_cl_device **cldev,
+                                void (*notify_change)(void *client,
+                                                      struct mei_cl_device
+                                                      *cldev));
+void mei_hdcp_cldev_put_reference(struct mei_cl_device *cldev); #else
+static inline int mei_hdcp_cldev_get_reference(void *client_data,
+                                struct mei_cl_device **cldev,
+                                void (*notify_change)(void *client,
+                                                      struct mei_cl_device
+                                                      *cldev))
+{
+       return -ENODEV;
+}
+static inline
+void mei_hdcp_cldev_put_reference(struct mei_cl_device *cldev) {}
+#endif /* defined (CONFIG_INTEL_MEI_HDCP) */ #endif /* defined
+(_LINUX_MEI_HDCP_H) */
--
2.7.4

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to