Mei hdcp driver is designed as component slave for the I915 component
master.

v2:
  Rebased.
v3:
  Notifier chain is adopted for cldev state update [Tomas]
v4:
  Made static dummy functions as inline in mei_hdcp.h
  API for polling client device status
  IS_ENABLED used in header, for config status for mei_hdcp.
v5:
  Replacing the notifier with component framework. [Daniel]

Signed-off-by: Ramalingam C <ramalinga...@intel.com>
---
 drivers/misc/mei/hdcp/mei_hdcp.c | 94 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 92 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c
index 4cd6fdd01181..ba7550215b7f 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.c
+++ b/drivers/misc/mei/hdcp/mei_hdcp.c
@@ -31,6 +31,83 @@
 #include <linux/slab.h>
 #include <linux/uuid.h>
 #include <linux/mei_cl_bus.h>
+#include <linux/component.h>
+#include <drm/i915_component.h>
+
+bool mei_hdcp_component_registered;
+static struct mei_cl_device *mei_cldev;
+
+struct i915_hdcp_component_ops mei_hdcp_component_ops = {
+       .owner                                  = THIS_MODULE,
+       .initiate_hdcp2_session                 = NULL,
+       .verify_receiver_cert_prepare_km        = NULL,
+       .verify_hprime                          = NULL,
+       .store_pairing_info                     = NULL,
+       .initiate_locality_check                = NULL,
+       .verify_lprime                          = NULL,
+       .get_session_key                        = NULL,
+       .repeater_check_flow_prepare_ack        = NULL,
+       .verify_mprime                          = NULL,
+       .enable_hdcp_authentication             = NULL,
+       .close_hdcp_session                     = NULL,
+};
+
+static int mei_hdcp_component_bind(struct device *mei_kdev,
+                                  struct device *i915_kdev, void *data)
+{
+       struct i915_hdcp_component *comp = data;
+
+       WARN_ON(!mutex_is_locked(&comp->mutex));
+       if (WARN_ON(comp->ops || comp->dev))
+               return -EEXIST;
+
+       dev_info(mei_kdev, "MEI HDCP comp bind\n");
+       comp->ops = &mei_hdcp_component_ops;
+       comp->i915_kdev = i915_kdev;
+       comp->mei_cldev = mei_cldev;
+       mei_cldev_set_drvdata(mei_cldev, (void *)comp);
+
+       return 0;
+}
+
+static void mei_hdcp_component_unbind(struct device *mei_kdev,
+                                     struct device *i915_kdev, void *data)
+{
+       struct i915_hdcp_component *comp = data;
+
+       WARN_ON(!mutex_is_locked(&comp->mutex));
+       dev_info(mei_kdev, "MEI HDCP comp unbind\n");
+       comp->ops = NULL;
+       comp->dev = NULL;
+       comp->mei_cldev = NULL;
+}
+
+static const struct component_ops mei_hdcp_component_bind_ops = {
+       .bind   = mei_hdcp_component_bind,
+       .unbind = mei_hdcp_component_unbind,
+};
+
+void mei_hdcp_component_init(struct device *dev)
+{
+       int ret;
+
+       ret = component_add(dev, &mei_hdcp_component_bind_ops);
+       if (ret < 0) {
+               dev_err(dev, "Failed to add MEI HDCP comp (%d)\n", ret);
+               return;
+       }
+
+       mei_hdcp_component_registered = true;
+}
+
+void mei_hdcp_component_cleanup(struct device *dev)
+{
+       if (!mei_hdcp_component_registered)
+               return;
+
+       component_del(dev, &mei_hdcp_component_bind_ops);
+       mei_hdcp_component_registered = false;
+}
 
 static int mei_hdcp_probe(struct mei_cl_device *cldev,
                          const struct mei_cl_device_id *id)
@@ -38,15 +115,28 @@ static int mei_hdcp_probe(struct mei_cl_device *cldev,
        int ret;
 
        ret = mei_cldev_enable(cldev);
-       if (ret < 0)
+       if (ret < 0) {
                dev_err(&cldev->dev, "mei_cldev_enable Failed. %d\n", ret);
+               return ret;
+       }
 
-       return ret;
+       mei_cldev = cldev;
+       mei_hdcp_component_init(&cldev->dev);
+       return 0;
 }
 
 static int mei_hdcp_remove(struct mei_cl_device *cldev)
 {
+       struct i915_hdcp_component *comp;
+
+       comp = mei_cldev_get_drvdata(cldev);
+       if (comp && comp->master_ops && comp->master_ops->pull_down_interface)
+               comp->master_ops->pull_down_interface(comp->i915_kdev);
+
+       mei_cldev = NULL;
        mei_cldev_set_drvdata(cldev, NULL);
+       mei_hdcp_component_cleanup(&cldev->dev);
+
        return mei_cldev_disable(cldev);
 }
 
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to