Re: [PATCH v2 07/42] misc/mei/hdcp: Get & Put for mei cl_device

2018-03-12 Thread Ramalingam C



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 
---
  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, _hdcp);

ret = mei_cldev_enable(cldev);
-   if (ret < 0)
+   if (ret < 0) {
dev_err(>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 ..774b26da0c26
--- /dev/null
+++ b/include/linux/mei_hdcp.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2017 Intel Corporation
+ *
+ * Permission to use, copy, 

RE: [PATCH v2 07/42] misc/mei/hdcp: Get & Put for mei cl_device

2018-03-08 Thread Winkler, Tomas
> 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. 
This is not needed and I'm not sure it will ever work.

Tomas

 
> Signed-off-by: Ramalingam C 
> ---
>  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, _hdcp);
> 
>   ret = mei_cldev_enable(cldev);
> - if (ret < 0)
> + if (ret < 0) {
>   dev_err(>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_GUIDUUID_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 ..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
> 

[PATCH v2 07/42] misc/mei/hdcp: Get & Put for mei cl_device

2018-03-08 Thread Ramalingam C
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.

Signed-off-by: Ramalingam C 
---
 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, _hdcp);
 
ret = mei_cldev_enable(cldev);
-   if (ret < 0)
+   if (ret < 0) {
dev_err(>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 ..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