From ffc2849b614113426c919d2fc3b00435ed887c86 Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Thu, 18 May 2017 17:51:33 -0700 Subject: [PATCH] drivers/misc: move hdcp sysfs nodes to misc hdcp driver Currently the sysfs nodes for receiving minimum encryption level reside within the SDE HDMI driver. Move the nodes to the misc hdcp driver so that they are available for use for targets using DRM SDE driver. Change-Id: I94daa981536e56930f7b15eb0ca7b895b9bc9c44 Signed-off-by: Abhinav Kumar --- .../drm/msm/hdmi-staging/sde_hdmi_hdcp2p2.c | 39 ++++++++++ drivers/misc/hdcp.c | 74 +++++++++++++++---- include/linux/hdcp_qseecom.h | 1 + 3 files changed, 98 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_hdcp2p2.c b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_hdcp2p2.c index 986b33fe1016..1e673440f399 100644 --- a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_hdcp2p2.c +++ b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_hdcp2p2.c @@ -284,6 +284,44 @@ static int sde_hdmi_hdcp2p2_reauthenticate(void *input) return sde_hdmi_hdcp2p2_authenticate(input); } +static void sde_hdmi_hdcp2p2_min_level_change(void *client_ctx, +int min_enc_lvl) +{ + struct sde_hdmi_hdcp2p2_ctrl *ctrl = + (struct sde_hdmi_hdcp2p2_ctrl *)client_ctx; + struct hdcp_lib_wakeup_data cdata = { + HDCP_LIB_WKUP_CMD_QUERY_STREAM_TYPE}; + bool enc_notify = true; + enum sde_hdcp_states enc_lvl; + + if (!ctrl) { + SDE_ERROR("invalid input\n"); + return; + } + + switch (min_enc_lvl) { + case 0: + enc_lvl = HDCP_STATE_AUTH_ENC_NONE; + break; + case 1: + enc_lvl = HDCP_STATE_AUTH_ENC_1X; + break; + case 2: + enc_lvl = HDCP_STATE_AUTH_ENC_2P2; + break; + default: + enc_notify = false; + } + + SDE_HDCP_DEBUG("enc level changed %d\n", min_enc_lvl); + + cdata.context = ctrl->lib_ctx; + sde_hdmi_hdcp2p2_wakeup_lib(ctrl, &cdata); + + if (enc_notify && ctrl->init_data.notify_status) + ctrl->init_data.notify_status(ctrl->init_data.cb_data, enc_lvl); +} + static void sde_hdmi_hdcp2p2_auth_failed(struct sde_hdmi_hdcp2p2_ctrl *ctrl) { if (!ctrl) { @@ -849,6 +887,7 @@ void *sde_hdmi_hdcp2p2_init(struct sde_hdcp_init_data *init_data) static struct hdcp_client_ops client_ops = { .wakeup = sde_hdmi_hdcp2p2_wakeup, + .notify_lvl_change = sde_hdmi_hdcp2p2_min_level_change, }; static struct hdcp_txmtr_ops txmtr_ops; diff --git a/drivers/misc/hdcp.c b/drivers/misc/hdcp.c index 19950b4e8059..c6f2dbfe573d 100644 --- a/drivers/misc/hdcp.c +++ b/drivers/misc/hdcp.c @@ -38,21 +38,6 @@ #include "qseecom_kernel.h" -struct msm_hdcp_mgr { - struct platform_device *pdev; - dev_t dev_num; - struct cdev cdev; - struct class *class; - struct device *device; - struct HDCP_V2V1_MSG_TOPOLOGY cached_tp; - u32 tp_msgid; -}; - -#define CLASS_NAME "hdcp" -#define DRIVER_NAME "msm_hdcp" - -static struct msm_hdcp_mgr *hdcp_drv_mgr; - #define TZAPP_NAME "hdcp2p2" #define HDCP1_APP_NAME "hdcp1" #define QSEECOM_SBUFF_SIZE 0x1000 @@ -562,6 +547,24 @@ struct hdcp_lib_message_map { const char *msg_name; }; +struct msm_hdcp_mgr { + struct platform_device *pdev; + dev_t dev_num; + struct cdev cdev; + struct class *class; + struct device *device; + struct HDCP_V2V1_MSG_TOPOLOGY cached_tp; + u32 tp_msgid; + void *client_ctx; + struct hdcp_lib_handle *handle; +}; + +#define CLASS_NAME "hdcp" +#define DRIVER_NAME "msm_hdcp" + +static struct msm_hdcp_mgr *hdcp_drv_mgr; +static struct hdcp_lib_handle *drv_client_handle; + static void hdcp_lib_clean(struct hdcp_lib_handle *handle); static void hdcp_lib_init(struct hdcp_lib_handle *handle); static void hdcp_lib_msg_sent(struct hdcp_lib_handle *handle); @@ -2413,7 +2416,13 @@ int hdcp_library_register(struct hdcp_register_data *data) } *data->hdcp_ctx = handle; + /* Cache the client ctx to be used later + * HDCP driver probe happens earlier than + * SDE driver probe hence caching it to + * be used later. + */ + drv_client_handle = handle; handle->thread = kthread_run(kthread_worker_fn, &handle->worker, "hdcp_tz_lib"); @@ -2543,8 +2552,35 @@ static ssize_t msm_hdcp_1x_sysfs_wta_tp(struct device *dev, return ret; } /* hdmi_tx_sysfs_wta_hpd */ +static ssize_t hdmi_hdcp2p2_sysfs_wta_min_level_change(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int rc; + int min_enc_lvl; + struct hdcp_lib_handle *handle; + ssize_t ret = count; + + handle = hdcp_drv_mgr->handle; + + rc = kstrtoint(buf, 10, &min_enc_lvl); + if (rc) { + pr_err("%s: kstrtoint failed. rc=%d\n", __func__, rc); + return -EINVAL; + } + + if (handle && handle->client_ops->notify_lvl_change) { + handle->client_ops->notify_lvl_change(handle->client_ctx, + min_enc_lvl); + } + + return ret; +} + static DEVICE_ATTR(tp, S_IRUGO | S_IWUSR, msm_hdcp_1x_sysfs_rda_tp, - msm_hdcp_1x_sysfs_wta_tp); +msm_hdcp_1x_sysfs_wta_tp); + +static DEVICE_ATTR(min_level_change, S_IWUSR, NULL, +hdmi_hdcp2p2_sysfs_wta_min_level_change); void hdcp1_cache_repeater_topology(void *hdcp1_cached_tp) { @@ -2555,6 +2591,7 @@ void hdcp1_cache_repeater_topology(void *hdcp1_cached_tp) static struct attribute *msm_hdcp_fs_attrs[] = { &dev_attr_tp.attr, + &dev_attr_min_level_change.attr, NULL }; @@ -2632,6 +2669,11 @@ static int msm_hdcp_probe(struct platform_device *pdev) if (ret) pr_err("unable to register rotator sysfs nodes\n"); + /* Store the handle in the hdcp drv mgr + * to be used for the sysfs notifications + */ + hdcp_drv_mgr->handle = drv_client_handle; + return 0; error_cdev_add: device_destroy(hdcp_drv_mgr->class, hdcp_drv_mgr->dev_num); diff --git a/include/linux/hdcp_qseecom.h b/include/linux/hdcp_qseecom.h index dc4af867a3bc..dc513fbab580 100644 --- a/include/linux/hdcp_qseecom.h +++ b/include/linux/hdcp_qseecom.h @@ -125,6 +125,7 @@ struct hdcp_txmtr_ops { struct hdcp_client_ops { int (*wakeup)(struct hdmi_hdcp_wakeup_data *data); + void (*notify_lvl_change)(void *client_ctx, int min_lvl); }; enum hdcp_device_type {