diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi index 3cc0aa348bd8..63de28017f3d 100644 --- a/arch/arm64/boot/dts/qcom/sdm670.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi @@ -809,6 +809,10 @@ <&apps_smmu 0x716 0x1>; }; + qcom_msmhdcp: qcom,msm_hdcp { + compatible = "qcom,msm-hdcp"; + }; + qcom_crypto: qcrypto@1de0000 { compatible = "qcom,qcrypto"; reg = <0x1de0000 0x20000>, diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 053ee20e2f4d..dce54aacb36d 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -48,11 +48,6 @@ struct dp_hdcp { void *hdcp1; void *hdcp2; - int enc_lvl; - - bool auth_state; - bool hdcp1_present; - bool hdcp2_present; bool feature_enabled; }; @@ -93,7 +88,6 @@ struct dp_display_private { struct work_struct attention_work; struct mutex hdcp_mutex; struct mutex session_lock; - int hdcp_status; unsigned long audio_status; }; @@ -109,9 +103,8 @@ static bool dp_display_framework_ready(struct dp_display_private *dp) static inline bool dp_display_is_hdcp_enabled(struct dp_display_private *dp) { - return dp->hdcp.feature_enabled && - (dp->hdcp.hdcp1_present || dp->hdcp.hdcp2_present) && - dp->hdcp.ops; + return dp->hdcp.feature_enabled && dp->link->hdcp_status.hdcp_version + && dp->hdcp.ops; } static irqreturn_t dp_display_irq(int irq, void *dev_id) @@ -156,32 +149,25 @@ static void dp_display_hdcp_cb_work(struct work_struct *work) ops = dp->hdcp.ops; - switch (dp->hdcp_status) { - case HDCP_STATE_AUTHENTICATING: - pr_debug("start authenticaton\n"); + pr_debug("%s: %s\n", + sde_hdcp_version(dp->link->hdcp_status.hdcp_version), + sde_hdcp_state_name(dp->link->hdcp_status.hdcp_state)); + switch (dp->link->hdcp_status.hdcp_state) { + case HDCP_STATE_AUTHENTICATING: if (dp->hdcp.ops && dp->hdcp.ops->authenticate) rc = dp->hdcp.ops->authenticate(dp->hdcp.data); - - break; - case HDCP_STATE_AUTHENTICATED: - pr_debug("hdcp authenticated\n"); - dp->hdcp.auth_state = true; break; case HDCP_STATE_AUTH_FAIL: - dp->hdcp.auth_state = false; - if (dp->power_on) { - pr_debug("Reauthenticating\n"); if (ops && ops->reauthenticate) { rc = ops->reauthenticate(dp->hdcp.data); if (rc) - pr_err("reauth failed rc=%d\n", rc); + pr_err("failed rc=%d\n", rc); } } else { pr_debug("not reauthenticating, cable disconnected\n"); } - break; default: break; @@ -189,7 +175,7 @@ static void dp_display_hdcp_cb_work(struct work_struct *work) } static void dp_display_notify_hdcp_status_cb(void *ptr, - enum sde_hdcp_states status) + enum sde_hdcp_state state) { struct dp_display_private *dp = ptr; @@ -198,7 +184,7 @@ static void dp_display_notify_hdcp_status_cb(void *ptr, return; } - dp->hdcp_status = status; + dp->link->hdcp_status.hdcp_state = state; if (dp->dp_display.is_connected) queue_delayed_work(dp->wq, &dp->hdcp_cb_work, HZ/4); @@ -214,12 +200,16 @@ static void dp_display_update_hdcp_info(struct dp_display_private *dp) { void *fd = NULL; struct sde_hdcp_ops *ops = NULL; + bool hdcp2_present = false, hdcp1_present = false; if (!dp) { pr_err("invalid input\n"); return; } + dp->link->hdcp_status.hdcp_state = HDCP_STATE_INACTIVE; + dp->link->hdcp_status.hdcp_version = HDCP_VERSION_NONE; + if (!dp->hdcp.feature_enabled) { pr_debug("feature not enabled\n"); return; @@ -230,26 +220,29 @@ static void dp_display_update_hdcp_info(struct dp_display_private *dp) ops = sde_dp_hdcp2p2_start(fd); if (ops && ops->feature_supported) - dp->hdcp.hdcp2_present = ops->feature_supported(fd); + hdcp2_present = ops->feature_supported(fd); else - dp->hdcp.hdcp2_present = false; + hdcp2_present = false; pr_debug("hdcp2p2: %s\n", - dp->hdcp.hdcp2_present ? "supported" : "not supported"); + hdcp2_present ? "supported" : "not supported"); - if (!dp->hdcp.hdcp2_present) { - dp->hdcp.hdcp1_present = hdcp1_check_if_supported_load_app(); + if (!hdcp2_present) { + hdcp1_present = hdcp1_check_if_supported_load_app(); - if (dp->hdcp.hdcp1_present) { + if (hdcp1_present) { fd = dp->hdcp.hdcp1; ops = sde_hdcp_1x_start(fd); + dp->link->hdcp_status.hdcp_version = HDCP_VERSION_1X; } + } else { + dp->link->hdcp_status.hdcp_version = HDCP_VERSION_2P2; } pr_debug("hdcp1x: %s\n", - dp->hdcp.hdcp1_present ? "supported" : "not supported"); + hdcp1_present ? "supported" : "not supported"); - if (dp->hdcp.hdcp2_present || dp->hdcp.hdcp1_present) { + if (hdcp2_present || hdcp1_present) { dp->hdcp.data = fd; dp->hdcp.ops = ops; } else { @@ -287,7 +280,6 @@ static int dp_display_initialize_hdcp(struct dp_display_private *dp) hdcp_init_data.drm_aux = dp->aux->drm_aux; hdcp_init_data.cb_data = (void *)dp; hdcp_init_data.workq = dp->wq; - hdcp_init_data.mutex = &dp->hdcp_mutex; hdcp_init_data.sec_access = true; hdcp_init_data.notify_status = dp_display_notify_hdcp_status_cb; hdcp_init_data.core_io = &dp->parser->io.ctrl_io; @@ -298,6 +290,7 @@ static int dp_display_initialize_hdcp(struct dp_display_private *dp) hdcp_init_data.qfprom_io = &dp->parser->io.qfprom_io; hdcp_init_data.hdcp_io = &dp->parser->io.hdcp_io; hdcp_init_data.revision = &dp->panel->link_info.revision; + hdcp_init_data.msm_hdcp_dev = dp->parser->msm_hdcp_dev; dp->hdcp.hdcp1 = sde_hdcp_1x_init(&hdcp_init_data); if (IS_ERR_OR_NULL(dp->hdcp.hdcp1)) { @@ -623,7 +616,7 @@ end: static void dp_display_clean(struct dp_display_private *dp) { if (dp_display_is_hdcp_enabled(dp)) { - dp->hdcp_status = HDCP_STATE_INACTIVE; + dp->link->hdcp_status.hdcp_state = HDCP_STATE_INACTIVE; cancel_delayed_work_sync(&dp->hdcp_cb_work); if (dp->hdcp.ops->off) @@ -1103,7 +1096,7 @@ static int dp_display_post_enable(struct dp_display *dp_display) if (dp_display_is_hdcp_enabled(dp)) { cancel_delayed_work_sync(&dp->hdcp_cb_work); - dp->hdcp_status = HDCP_STATE_AUTHENTICATING; + dp->link->hdcp_status.hdcp_state = HDCP_STATE_AUTHENTICATING; queue_delayed_work(dp->wq, &dp->hdcp_cb_work, HZ / 2); } @@ -1137,7 +1130,7 @@ static int dp_display_pre_disable(struct dp_display *dp_display) } if (dp_display_is_hdcp_enabled(dp)) { - dp->hdcp_status = HDCP_STATE_INACTIVE; + dp->link->hdcp_status.hdcp_state = HDCP_STATE_INACTIVE; cancel_delayed_work_sync(&dp->hdcp_cb_work); if (dp->hdcp.ops->off) diff --git a/drivers/gpu/drm/msm/dp/dp_hdcp2p2.c b/drivers/gpu/drm/msm/dp/dp_hdcp2p2.c index 0e1490fae55d..2b7b2171351e 100644 --- a/drivers/gpu/drm/msm/dp/dp_hdcp2p2.c +++ b/drivers/gpu/drm/msm/dp/dp_hdcp2p2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "sde_hdcp.h" @@ -320,35 +321,16 @@ static void dp_hdcp2p2_min_level_change(void *client_ctx, struct dp_hdcp2p2_ctrl *ctrl = (struct dp_hdcp2p2_ctrl *)client_ctx; struct hdcp_lib_wakeup_data cdata = { HDCP_LIB_WKUP_CMD_QUERY_STREAM_TYPE}; - bool enc_notify = true; - int enc_lvl; if (!ctrl) { pr_err("invalid input\n"); return; } - switch (min_enc_level) { - 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; - } - pr_debug("enc level changed %d\n", min_enc_level); cdata.context = ctrl->lib_ctx; dp_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 dp_hdcp2p2_auth_failed(struct dp_hdcp2p2_ctrl *ctrl) @@ -812,7 +794,6 @@ void *sde_dp_hdcp2p2_init(struct sde_hdcp_init_data *init_data) static struct hdcp_client_ops client_ops = { .wakeup = dp_hdcp2p2_wakeup, - .notify_lvl_change = dp_hdcp2p2_min_level_change, }; static struct dp_hdcp2p2_int_set int_set1[] = { {BIT(17), "authentication successful", NULL}, @@ -867,6 +848,9 @@ void *sde_dp_hdcp2p2_init(struct sde_hdcp_init_data *init_data) goto error; } + msm_hdcp_register_cb(init_data->msm_hdcp_dev, ctrl, + dp_hdcp2p2_min_level_change); + kthread_init_worker(&ctrl->worker); kthread_init_work(&ctrl->auth, dp_hdcp2p2_auth_work); diff --git a/drivers/gpu/drm/msm/dp/dp_link.h b/drivers/gpu/drm/msm/dp/dp_link.h index 46d30a7b21d6..d14b88155444 100644 --- a/drivers/gpu/drm/msm/dp/dp_link.h +++ b/drivers/gpu/drm/msm/dp/dp_link.h @@ -72,6 +72,11 @@ struct dp_link_test_audio { u32 test_audio_period_ch_8; }; +struct dp_link_hdcp_status { + int hdcp_state; + int hdcp_version; +}; + struct dp_link_phy_params { u32 phy_test_pattern_sel; u8 v_level; @@ -110,6 +115,7 @@ struct dp_link { struct dp_link_test_audio test_audio; struct dp_link_phy_params phy_params; struct dp_link_params link_params; + struct dp_link_hdcp_status hdcp_status; u32 (*get_test_bits_depth)(struct dp_link *dp_link, u32 bpp); int (*process_request)(struct dp_link *dp_link); diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c index c112cdc8c90a..9a46549b4f3a 100644 --- a/drivers/gpu/drm/msm/dp/dp_parser.c +++ b/drivers/gpu/drm/msm/dp/dp_parser.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -15,6 +15,7 @@ #define pr_fmt(fmt) "[drm-dp] %s: " fmt, __func__ #include +#include #include "dp_parser.h" @@ -215,6 +216,30 @@ static int dp_parser_misc(struct dp_parser *parser) return 0; } +static int dp_parser_msm_hdcp_dev(struct dp_parser *parser) +{ + struct device_node *node; + struct platform_device *pdev; + + node = of_find_compatible_node(NULL, NULL, "qcom,msm-hdcp"); + if (!node) { + // This is a non-fatal error, module initialization can proceed + pr_warn("couldn't find msm-hdcp node\n"); + return 0; + } + + pdev = of_find_device_by_node(node); + if (!pdev) { + // This is a non-fatal error, module initialization can proceed + pr_warn("couldn't find msm-hdcp pdev\n"); + return 0; + } + + parser->msm_hdcp_dev = &pdev->dev; + + return 0; +} + static int dp_parser_pinctrl(struct dp_parser *parser) { int rc = 0; @@ -643,6 +668,10 @@ static int dp_parser_parse(struct dp_parser *parser) goto err; rc = dp_parser_pinctrl(parser); + if (rc) + goto err; + + rc = dp_parser_msm_hdcp_dev(parser); err: return rc; } diff --git a/drivers/gpu/drm/msm/dp/dp_parser.h b/drivers/gpu/drm/msm/dp/dp_parser.h index 72da38169c4d..16ac698770d5 100644 --- a/drivers/gpu/drm/msm/dp/dp_parser.h +++ b/drivers/gpu/drm/msm/dp/dp_parser.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -166,6 +166,7 @@ static inline char *dp_phy_aux_config_type_to_string(u32 cfg_type) * struct dp_parser - DP parser's data exposed to clients * * @pdev: platform data of the client + * @msm_hdcp_dev: device pointer for the HDCP driver * @mp: gpio, regulator and clock related data * @pinctrl: pin-control related data * @ctrl_resouce: controller's register address realated data @@ -174,6 +175,7 @@ static inline char *dp_phy_aux_config_type_to_string(u32 cfg_type) */ struct dp_parser { struct platform_device *pdev; + struct device *msm_hdcp_dev; struct dss_module_power mp[DP_MAX_PM]; struct dp_pinctrl pinctrl; struct dp_io io; diff --git a/drivers/gpu/drm/msm/sde_hdcp.h b/drivers/gpu/drm/msm/sde_hdcp.h index 6c4426026ce2..c8e84d3ccb27 100644 --- a/drivers/gpu/drm/msm/sde_hdcp.h +++ b/drivers/gpu/drm/msm/sde_hdcp.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012, 2014-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012, 2014-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -30,17 +30,21 @@ enum sde_hdcp_client_id { HDCP_CLIENT_DP, }; -enum sde_hdcp_states { +enum sde_hdcp_state { HDCP_STATE_INACTIVE, HDCP_STATE_AUTHENTICATING, HDCP_STATE_AUTHENTICATED, HDCP_STATE_AUTH_FAIL, - HDCP_STATE_AUTH_ENC_NONE, - HDCP_STATE_AUTH_ENC_1X, - HDCP_STATE_AUTH_ENC_2P2 +}; + +enum sde_hdcp_version { + HDCP_VERSION_NONE, + HDCP_VERSION_1X, + HDCP_VERSION_2P2 }; struct sde_hdcp_init_data { + struct device *msm_hdcp_dev; struct dss_io_data *core_io; struct dss_io_data *dp_ahb; struct dss_io_data *dp_aux; @@ -52,7 +56,7 @@ struct sde_hdcp_init_data { struct mutex *mutex; struct workqueue_struct *workq; void *cb_data; - void (*notify_status)(void *cb_data, enum sde_hdcp_states status); + void (*notify_status)(void *cb_data, enum sde_hdcp_state state); u8 sink_rx_status; unsigned char *revision; u32 phy_addr; @@ -69,11 +73,32 @@ struct sde_hdcp_ops { void (*off)(void *hdcp_ctrl); }; +static inline const char *sde_hdcp_state_name(enum sde_hdcp_state hdcp_state) +{ + switch (hdcp_state) { + case HDCP_STATE_INACTIVE: return "HDCP_STATE_INACTIVE"; + case HDCP_STATE_AUTHENTICATING: return "HDCP_STATE_AUTHENTICATING"; + case HDCP_STATE_AUTHENTICATED: return "HDCP_STATE_AUTHENTICATED"; + case HDCP_STATE_AUTH_FAIL: return "HDCP_STATE_AUTH_FAIL"; + default: return "???"; + } +} + +static inline const char *sde_hdcp_version(enum sde_hdcp_version hdcp_version) +{ + switch (hdcp_version) { + case HDCP_VERSION_NONE: return "HDCP_VERSION_NONE"; + case HDCP_VERSION_1X: return "HDCP_VERSION_1X"; + case HDCP_VERSION_2P2: return "HDCP_VERSION_2P2"; + default: return "???"; + } +} + void *sde_hdcp_1x_init(struct sde_hdcp_init_data *init_data); void sde_hdcp_1x_deinit(void *input); struct sde_hdcp_ops *sde_hdcp_1x_start(void *input); void *sde_dp_hdcp2p2_init(struct sde_hdcp_init_data *init_data); void sde_dp_hdcp2p2_deinit(void *input); -const char *sde_hdcp_state_name(enum sde_hdcp_states hdcp_state); +const char *sde_hdcp_state_name(enum sde_hdcp_state hdcp_state); struct sde_hdcp_ops *sde_dp_hdcp2p2_start(void *input); #endif /* __SDE_HDCP_H__ */ diff --git a/drivers/gpu/drm/msm/sde_hdcp_1x.c b/drivers/gpu/drm/msm/sde_hdcp_1x.c index 2f900ece8aa0..2c7f52c7970b 100644 --- a/drivers/gpu/drm/msm/sde_hdcp_1x.c +++ b/drivers/gpu/drm/msm/sde_hdcp_1x.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include "sde_hdcp.h" @@ -213,8 +214,7 @@ struct sde_hdcp_1x { bool sink_r0_ready; bool reauth; bool ksv_ready; - enum sde_hdcp_states hdcp_state; - struct HDCP_V2V1_MSG_TOPOLOGY cached_tp; + enum sde_hdcp_state hdcp_state; struct HDCP_V2V1_MSG_TOPOLOGY current_tp; struct delayed_work hdcp_auth_work; struct completion r0_checked; @@ -227,17 +227,6 @@ struct sde_hdcp_1x { struct workqueue_struct *workq; }; -const char *sde_hdcp_state_name(enum sde_hdcp_states hdcp_state) -{ - switch (hdcp_state) { - case HDCP_STATE_INACTIVE: return "HDCP_STATE_INACTIVE"; - case HDCP_STATE_AUTHENTICATING: return "HDCP_STATE_AUTHENTICATING"; - case HDCP_STATE_AUTHENTICATED: return "HDCP_STATE_AUTHENTICATED"; - case HDCP_STATE_AUTH_FAIL: return "HDCP_STATE_AUTH_FAIL"; - default: return "???"; - } -} - static int sde_hdcp_1x_count_one(u8 *array, u8 len) { int i, j, count = 0; @@ -1062,30 +1051,12 @@ error: return rc; } -static void sde_hdcp_1x_cache_topology(struct sde_hdcp_1x *hdcp) -{ - if (!hdcp || !hdcp->init_data.dp_ahb || !hdcp->init_data.dp_aux || - !hdcp->init_data.dp_link || !hdcp->init_data.dp_p0) { - pr_err("invalid input\n"); - return; - } - - memcpy((void *)&hdcp->cached_tp, - (void *) &hdcp->current_tp, - sizeof(hdcp->cached_tp)); - hdcp1_cache_repeater_topology((void *)&hdcp->cached_tp); -} - -static void sde_hdcp_1x_notify_topology(void) -{ - hdcp1_notify_topology(); -} - static void sde_hdcp_1x_update_auth_status(struct sde_hdcp_1x *hdcp) { if (sde_hdcp_1x_state(HDCP_STATE_AUTHENTICATED)) { - sde_hdcp_1x_cache_topology(hdcp); - sde_hdcp_1x_notify_topology(); + msm_hdcp_cache_repeater_topology(hdcp->init_data.msm_hdcp_dev, + &hdcp->current_tp); + msm_hdcp_notify_topology(hdcp->init_data.msm_hdcp_dev); } if (hdcp->init_data.notify_status && @@ -1262,11 +1233,9 @@ static void sde_hdcp_1x_off(void *input) * Also, need to set the state to inactive here so that any ongoing * reauth works will know that the HDCP session has been turned off. */ - mutex_lock(hdcp->init_data.mutex); DSS_REG_W(io, isr->int_reg, DSS_REG_R(io, isr->int_reg) & ~HDCP_INT_EN); hdcp->hdcp_state = HDCP_STATE_INACTIVE; - mutex_unlock(hdcp->init_data.mutex); /* complete any wait pending */ complete_all(&hdcp->sink_r0_available); @@ -1510,7 +1479,7 @@ void *sde_hdcp_1x_init(struct sde_hdcp_init_data *init_data) .off = sde_hdcp_1x_off }; - if (!init_data || !init_data->mutex || !init_data->notify_status || + if (!init_data || !init_data->notify_status || !init_data->workq || !init_data->cb_data) { pr_err("invalid input\n"); goto error; diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 744001af414f..fb07ce4c44df 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -49,7 +49,8 @@ obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o obj-$(CONFIG_SRAM) += sram.o obj-y += mic/ obj-$(CONFIG_GENWQE) += genwqe/ -obj-$(CONFIG_HDCP_QSEECOM) += hdcp.o +obj-$(CONFIG_HDCP_QSEECOM) += hdcp_qseecom.o +obj-$(CONFIG_HDCP_QSEECOM) += msm_hdcp.o obj-$(CONFIG_QSEECOM) += qseecom.o obj-$(CONFIG_ECHO) += echo/ obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o diff --git a/drivers/misc/hdcp.c b/drivers/misc/hdcp_qseecom.c similarity index 87% rename from drivers/misc/hdcp.c rename to drivers/misc/hdcp_qseecom.c index a86d9f1dd105..6ce377667623 100644 --- a/drivers/misc/hdcp.c +++ b/drivers/misc/hdcp_qseecom.c @@ -38,8 +38,6 @@ #include "qseecom_kernel.h" -#define CLASS_NAME "hdcp" -#define DRIVER_NAME "msm_hdcp" #define TZAPP_NAME "hdcp2p2" #define HDCP1_APP_NAME "hdcp1" #define QSEECOM_SBUFF_SIZE 0x1000 @@ -509,21 +507,6 @@ 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; -}; - -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); @@ -751,7 +734,7 @@ static int hdcp_lib_enable_encryption(struct hdcp_lib_handle *handle) QSEECOM_ALIGN(sizeof (struct hdcp_set_hw_key_rsp))); - if ((rc < 0) || (rsp_buf->status < 0)) { + if ((rc < 0) || (rsp_buf->status != HDCP_SUCCESS)) { pr_err("qseecom cmd failed with err = %d status = %d\n", rc, rsp_buf->status); rc = -EINVAL; @@ -1125,7 +1108,7 @@ static int hdcp_lib_session_deinit(struct hdcp_lib_handle *handle) (struct hdcp_lib_session_deinit_rsp))); - if ((rc < 0) || (rsp_buf->status < 0) || + if ((rc < 0) || (rsp_buf->status != HDCP_SUCCESS) || (rsp_buf->commandid != HDCP_SESSION_DEINIT)) { pr_err("qseecom cmd failed with err = %d status = %d\n", rc, rsp_buf->status); @@ -1231,7 +1214,7 @@ static int hdcp_lib_txmtr_deinit(struct hdcp_lib_handle *handle) QSEECOM_ALIGN(sizeof (struct hdcp_deinit_rsp))); - if ((rc < 0) || (rsp_buf->status < 0) || + if ((rc < 0) || (rsp_buf->status != HDCP_SUCCESS) || (rsp_buf->commandid != HDCP_TXMTR_DEINIT)) { pr_err("qseecom cmd failed with err = %d status = %d\n", rc, rsp_buf->status); @@ -1285,7 +1268,7 @@ static int hdcp_lib_start_auth(struct hdcp_lib_handle *handle) if ((rc < 0) || (rsp_buf->status != HDCP_SUCCESS) || (rsp_buf->commandid != HDCP_TXMTR_START_AUTHENTICATE) || - (rsp_buf->msglen <= 0) || (rsp_buf->message == NULL)) { + (rsp_buf->msglen == 0) || (rsp_buf->message == NULL)) { pr_err("qseecom cmd failed with err = %d, status = %d\n", rc, rsp_buf->status); rc = -EINVAL; @@ -1352,9 +1335,10 @@ static void hdcp_lib_stream(struct hdcp_lib_handle *handle) (struct hdcp_query_stream_type_rsp))); - if ((rc < 0) || (rsp_buf->status < 0) || (rsp_buf->msglen <= 0) || - (rsp_buf->commandid != HDCP_TXMTR_QUERY_STREAM_TYPE) || - (rsp_buf->msg == NULL)) { + if ((rc < 0) || (rsp_buf->status != HDCP_SUCCESS) || + (rsp_buf->msglen == 0) || + (rsp_buf->commandid != HDCP_TXMTR_QUERY_STREAM_TYPE) || + (rsp_buf->msg == NULL)) { pr_err("qseecom cmd failed with err=%d status=%d\n", rc, rsp_buf->status); rc = -EINVAL; @@ -1851,7 +1835,7 @@ static void hdcp_lib_msg_recvd(struct hdcp_lib_handle *handle) mutex_lock(&handle->msg_lock); msglen = handle->last_msg_recvd_len; - if (msglen <= 0) { + if (msglen == 0) { pr_err("invalid msg len\n"); mutex_unlock(&handle->msg_lock); rc = -EINVAL; @@ -1937,9 +1921,10 @@ static void hdcp_lib_msg_recvd(struct hdcp_lib_handle *handle) goto exit; } - if ((rc < 0) || (rsp_buf->status != 0) || (rsp_buf->msglen <= 0) || - (rsp_buf->commandid != HDCP_TXMTR_PROCESS_RECEIVED_MESSAGE) || - (rsp_buf->msg == NULL)) { + if ((rc < 0) || (rsp_buf->status != HDCP_SUCCESS) || + (rsp_buf->msglen == 0) || + (rsp_buf->commandid != HDCP_TXMTR_PROCESS_RECEIVED_MESSAGE) || + (rsp_buf->msg == NULL)) { pr_err("qseecom cmd failed with err=%d status=%d\n", rc, rsp_buf->status); rc = -EINVAL; @@ -2089,14 +2074,10 @@ int hdcp1_set_keys(uint32_t *aksv_msb, uint32_t *aksv_lsb) } /* copy bytes into msb and lsb */ - *aksv_msb = key_set_rsp->ksv[0] << 24; - *aksv_msb |= key_set_rsp->ksv[1] << 16; - *aksv_msb |= key_set_rsp->ksv[2] << 8; - *aksv_msb |= key_set_rsp->ksv[3]; - *aksv_lsb = key_set_rsp->ksv[4] << 24; - *aksv_lsb |= key_set_rsp->ksv[5] << 16; - *aksv_lsb |= key_set_rsp->ksv[6] << 8; - *aksv_lsb |= key_set_rsp->ksv[7]; + *aksv_msb = key_set_rsp->ksv[0] << 24 | key_set_rsp->ksv[1] << 16 | + key_set_rsp->ksv[2] << 8 | key_set_rsp->ksv[3]; + *aksv_lsb = key_set_rsp->ksv[4] << 24 | key_set_rsp->ksv[5] << 16 | + key_set_rsp->ksv[6] << 8 | key_set_rsp->ksv[7]; return 0; } @@ -2217,23 +2198,6 @@ int hdcp_library_register(struct hdcp_register_data *data) *data->hdcp_ctx = handle; - /* Cache the client ctx to be used later if - * Misc HDCP driver probe happens later than - * SDE driver probe hence caching it to - * be used later. - */ - drv_client_handle = handle; - - /* if misc HDCP driver probe happens earlier - * than SDE driver probe store the client - * handle to be used to sysfs notifications. - */ - - if (hdcp_drv_mgr && !hdcp_drv_mgr->handle) { - if (drv_client_handle) - hdcp_drv_mgr->handle = drv_client_handle; - } - handle->thread = kthread_run(kthread_worker_fn, &handle->worker, "hdcp_tz_lib"); @@ -2274,287 +2238,3 @@ void hdcp_library_deregister(void *phdcpcontext) } EXPORT_SYMBOL(hdcp_library_deregister); -void hdcp1_notify_topology(void) -{ - char *envp[4]; - char *a; - char *b; - - if (!hdcp_drv_mgr) { - pr_err("invalid input\n"); - return; - } - - a = kzalloc(SZ_16, GFP_KERNEL); - - if (!a) - return; - - b = kzalloc(SZ_16, GFP_KERNEL); - - if (!b) { - kfree(a); - return; - } - - envp[0] = "HDCP_MGR_EVENT=MSG_READY"; - envp[1] = a; - envp[2] = b; - envp[3] = NULL; - - snprintf(envp[1], 16, "%d", (int)DOWN_CHECK_TOPOLOGY); - snprintf(envp[2], 16, "%d", (int)HDCP_V1_TX); - - kobject_uevent_env(&hdcp_drv_mgr->device->kobj, KOBJ_CHANGE, envp); - kfree(a); - kfree(b); -} - -static ssize_t msm_hdcp_1x_sysfs_rda_tp(struct device *dev, -struct device_attribute *attr, char *buf) -{ - ssize_t ret = 0; - - if (!hdcp_drv_mgr) { - pr_err("invalid input\n"); - return -EINVAL; - } - - switch (hdcp_drv_mgr->tp_msgid) { - case DOWN_CHECK_TOPOLOGY: - case DOWN_REQUEST_TOPOLOGY: - buf[MSG_ID_IDX] = hdcp_drv_mgr->tp_msgid; - buf[RET_CODE_IDX] = HDCP_AUTHED; - ret = HEADER_LEN; - - memcpy(buf + HEADER_LEN, &hdcp_drv_mgr->cached_tp, - sizeof(struct HDCP_V2V1_MSG_TOPOLOGY)); - - ret += sizeof(struct HDCP_V2V1_MSG_TOPOLOGY); - - /* clear the flag once data is read back to user space*/ - hdcp_drv_mgr->tp_msgid = -1; - break; - default: - ret = -EINVAL; - } - - return ret; -} - -static ssize_t msm_hdcp_1x_sysfs_wta_tp(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int msgid = 0; - ssize_t ret = count; - - if (!hdcp_drv_mgr || !buf) { - pr_err("invalid input\n"); - return -EINVAL; - } - - msgid = buf[0]; - - switch (msgid) { - case DOWN_CHECK_TOPOLOGY: - case DOWN_REQUEST_TOPOLOGY: - hdcp_drv_mgr->tp_msgid = msgid; - break; - /* more cases added here */ - default: - ret = -EINVAL; - } - - return ret; -} - -static ssize_t 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; - - if (!hdcp_drv_mgr) { - pr_err("invalid input\n"); - return -EINVAL; - } - - 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, 0644, msm_hdcp_1x_sysfs_rda_tp, - msm_hdcp_1x_sysfs_wta_tp); - -static DEVICE_ATTR(min_level_change, 0200, NULL, - hdcp2p2_sysfs_wta_min_level_change); - -void hdcp1_cache_repeater_topology(void *hdcp1_cached_tp) -{ - if (!hdcp_drv_mgr) { - pr_err("invalid input\n"); - return; - } - - memcpy((void *)&hdcp_drv_mgr->cached_tp, - hdcp1_cached_tp, - sizeof(struct HDCP_V2V1_MSG_TOPOLOGY)); -} - -static struct attribute *msm_hdcp_fs_attrs[] = { - &dev_attr_tp.attr, - &dev_attr_min_level_change.attr, - NULL -}; - -static struct attribute_group msm_hdcp_fs_attr_group = { - .attrs = msm_hdcp_fs_attrs -}; - -static int msm_hdcp_open(struct inode *inode, struct file *file) -{ - return 0; -} - -static int msm_hdcp_close(struct inode *inode, struct file *file) -{ - return 0; -} - -static const struct file_operations msm_hdcp_fops = { - .owner = THIS_MODULE, - .open = msm_hdcp_open, - .release = msm_hdcp_close, -}; - -static const struct of_device_id msm_hdcp_dt_match[] = { - { .compatible = "qcom,msm-hdcp",}, - {} -}; - -MODULE_DEVICE_TABLE(of, msm_hdcp_dt_match); - -static int msm_hdcp_probe(struct platform_device *pdev) -{ - int ret; - - hdcp_drv_mgr = devm_kzalloc(&pdev->dev, sizeof(struct msm_hdcp_mgr), - GFP_KERNEL); - if (!hdcp_drv_mgr) - return -ENOMEM; - - hdcp_drv_mgr->pdev = pdev; - - platform_set_drvdata(pdev, hdcp_drv_mgr); - - ret = alloc_chrdev_region(&hdcp_drv_mgr->dev_num, 0, 1, DRIVER_NAME); - if (ret < 0) { - pr_err("alloc_chrdev_region failed ret = %d\n", ret); - goto error_get_dev_num; - } - - hdcp_drv_mgr->class = class_create(THIS_MODULE, CLASS_NAME); - if (IS_ERR(hdcp_drv_mgr->class)) { - ret = PTR_ERR(hdcp_drv_mgr->class); - pr_err("couldn't create class rc = %d\n", ret); - goto error_class_create; - } - - hdcp_drv_mgr->device = device_create(hdcp_drv_mgr->class, NULL, - hdcp_drv_mgr->dev_num, NULL, DRIVER_NAME); - if (IS_ERR(hdcp_drv_mgr->device)) { - ret = PTR_ERR(hdcp_drv_mgr->device); - pr_err("device_create failed %d\n", ret); - goto error_class_device_create; - } - - cdev_init(&hdcp_drv_mgr->cdev, &msm_hdcp_fops); - ret = cdev_add(&hdcp_drv_mgr->cdev, - MKDEV(MAJOR(hdcp_drv_mgr->dev_num), 0), 1); - if (ret < 0) { - pr_err("cdev_add failed %d\n", ret); - goto error_cdev_add; - } - - ret = sysfs_create_group(&hdcp_drv_mgr->device->kobj, - &msm_hdcp_fs_attr_group); - 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); -error_class_device_create: - class_destroy(hdcp_drv_mgr->class); -error_class_create: - unregister_chrdev_region(hdcp_drv_mgr->dev_num, 1); -error_get_dev_num: - devm_kfree(&pdev->dev, hdcp_drv_mgr); - hdcp_drv_mgr = NULL; - return ret; -} - -static int msm_hdcp_remove(struct platform_device *pdev) -{ - struct msm_hdcp_mgr *mgr; - - mgr = (struct msm_hdcp_mgr *)platform_get_drvdata(pdev); - if (!mgr) - return -ENODEV; - - sysfs_remove_group(&hdcp_drv_mgr->device->kobj, - &msm_hdcp_fs_attr_group); - cdev_del(&hdcp_drv_mgr->cdev); - device_destroy(hdcp_drv_mgr->class, hdcp_drv_mgr->dev_num); - class_destroy(hdcp_drv_mgr->class); - unregister_chrdev_region(hdcp_drv_mgr->dev_num, 1); - - devm_kfree(&pdev->dev, hdcp_drv_mgr); - hdcp_drv_mgr = NULL; - return 0; -} - -static struct platform_driver msm_hdcp_driver = { - .probe = msm_hdcp_probe, - .remove = msm_hdcp_remove, - .driver = { - .name = "msm_hdcp", - .of_match_table = msm_hdcp_dt_match, - .pm = NULL, - } -}; - -static int __init msm_hdcp_init(void) -{ - return platform_driver_register(&msm_hdcp_driver); -} - -static void __exit msm_hdcp_exit(void) -{ - return platform_driver_unregister(&msm_hdcp_driver); -} - -module_init(msm_hdcp_init); -module_exit(msm_hdcp_exit); - -MODULE_DESCRIPTION("MSM HDCP driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/misc/msm_hdcp.c b/drivers/misc/msm_hdcp.c new file mode 100644 index 000000000000..ea8e84dff74e --- /dev/null +++ b/drivers/misc/msm_hdcp.c @@ -0,0 +1,356 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define pr_fmt(fmt) "[msm-hdcp] %s: " fmt, __func__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CLASS_NAME "hdcp" +#define DRIVER_NAME "msm_hdcp" + +struct msm_hdcp { + 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; + void (*cb)(void *ctx, int data); +}; + +void msm_hdcp_register_cb(struct device *dev, void *ctx, + void (*cb)(void *ctx, int data)) +{ + struct msm_hdcp *hdcp = NULL; + + if (!dev) { + pr_err("invalid device pointer\n"); + return; + } + + hdcp = dev_get_drvdata(dev); + if (!hdcp) { + pr_err("invalid driver pointer\n"); + return; + } + + hdcp->cb = cb; + hdcp->client_ctx = ctx; +} + +void msm_hdcp_notify_topology(struct device *dev) +{ + char *envp[4]; + char tp[SZ_16]; + char ver[SZ_16]; + struct msm_hdcp *hdcp = NULL; + + if (!dev) { + pr_err("invalid device pointer\n"); + return; + } + + hdcp = dev_get_drvdata(dev); + if (!hdcp) { + pr_err("invalid driver pointer\n"); + return; + } + + snprintf(tp, SZ_16, "%d", DOWN_CHECK_TOPOLOGY); + snprintf(ver, SZ_16, "%d", HDCP_V1_TX); + + envp[0] = "HDCP_MGR_EVENT=MSG_READY"; + envp[1] = tp; + envp[2] = ver; + envp[3] = NULL; + + kobject_uevent_env(&hdcp->device->kobj, KOBJ_CHANGE, envp); +} + +void msm_hdcp_cache_repeater_topology(struct device *dev, + struct HDCP_V2V1_MSG_TOPOLOGY *tp) +{ + struct msm_hdcp *hdcp = NULL; + + if (!dev || !tp) { + pr_err("invalid input\n"); + return; + } + + hdcp = dev_get_drvdata(dev); + if (!hdcp) { + pr_err("invalid driver pointer\n"); + return; + } + + memcpy(&hdcp->cached_tp, tp, + sizeof(struct HDCP_V2V1_MSG_TOPOLOGY)); +} + +static ssize_t msm_hdcp_1x_sysfs_rda_tp(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret = 0; + struct msm_hdcp *hdcp = NULL; + + if (!dev) { + pr_err("invalid device pointer\n"); + return -ENODEV; + } + + hdcp = dev_get_drvdata(dev); + if (!hdcp) { + pr_err("invalid driver pointer\n"); + return -ENODEV; + } + + switch (hdcp->tp_msgid) { + case DOWN_CHECK_TOPOLOGY: + case DOWN_REQUEST_TOPOLOGY: + buf[MSG_ID_IDX] = hdcp->tp_msgid; + buf[RET_CODE_IDX] = HDCP_AUTHED; + ret = HEADER_LEN; + + memcpy(buf + HEADER_LEN, &hdcp->cached_tp, + sizeof(struct HDCP_V2V1_MSG_TOPOLOGY)); + + ret += sizeof(struct HDCP_V2V1_MSG_TOPOLOGY); + + /* clear the flag once data is read back to user space*/ + hdcp->tp_msgid = -1; + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static ssize_t msm_hdcp_1x_sysfs_wta_tp(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int msgid = 0; + ssize_t ret = count; + struct msm_hdcp *hdcp = NULL; + + if (!dev) { + pr_err("invalid device pointer\n"); + return -ENODEV; + } + + hdcp = dev_get_drvdata(dev); + if (!hdcp) { + pr_err("invalid driver pointer\n"); + return -ENODEV; + } + + msgid = buf[0]; + + switch (msgid) { + case DOWN_CHECK_TOPOLOGY: + case DOWN_REQUEST_TOPOLOGY: + hdcp->tp_msgid = msgid; + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static ssize_t msm_hdcp_2x_sysfs_wta_min_level_change(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int rc; + int min_enc_lvl; + ssize_t ret = count; + struct msm_hdcp *hdcp = NULL; + + if (!dev) { + pr_err("invalid device pointer\n"); + return -ENODEV; + } + + hdcp = dev_get_drvdata(dev); + if (!hdcp) { + pr_err("invalid driver pointer\n"); + return -ENODEV; + } + + rc = kstrtoint(buf, 10, &min_enc_lvl); + if (rc) { + pr_err("kstrtoint failed. rc=%d\n", rc); + return -EINVAL; + } + + if (hdcp->cb && hdcp->client_ctx) + hdcp->cb(hdcp->client_ctx, min_enc_lvl); + + return ret; +} + +static DEVICE_ATTR(tp, 0644, msm_hdcp_1x_sysfs_rda_tp, + msm_hdcp_1x_sysfs_wta_tp); + +static DEVICE_ATTR(min_level_change, 0200, NULL, + msm_hdcp_2x_sysfs_wta_min_level_change); + +static struct attribute *msm_hdcp_fs_attrs[] = { + &dev_attr_tp.attr, + &dev_attr_min_level_change.attr, + NULL +}; + +static struct attribute_group msm_hdcp_fs_attr_group = { + .attrs = msm_hdcp_fs_attrs +}; + +static int msm_hdcp_open(struct inode *inode, struct file *file) +{ + return 0; +} + +static int msm_hdcp_close(struct inode *inode, struct file *file) +{ + return 0; +} + +static const struct file_operations msm_hdcp_fops = { + .owner = THIS_MODULE, + .open = msm_hdcp_open, + .release = msm_hdcp_close, +}; + +static const struct of_device_id msm_hdcp_dt_match[] = { + { .compatible = "qcom,msm-hdcp",}, + {} +}; + +MODULE_DEVICE_TABLE(of, msm_hdcp_dt_match); + +static int msm_hdcp_probe(struct platform_device *pdev) +{ + int ret; + struct msm_hdcp *hdcp; + + hdcp = devm_kzalloc(&pdev->dev, sizeof(struct msm_hdcp), GFP_KERNEL); + if (!hdcp) + return -ENOMEM; + + hdcp->pdev = pdev; + + platform_set_drvdata(pdev, hdcp); + + ret = alloc_chrdev_region(&hdcp->dev_num, 0, 1, DRIVER_NAME); + if (ret < 0) { + pr_err("alloc_chrdev_region failed ret = %d\n", ret); + goto error_get_dev_num; + } + + hdcp->class = class_create(THIS_MODULE, CLASS_NAME); + if (IS_ERR(hdcp->class)) { + ret = PTR_ERR(hdcp->class); + pr_err("couldn't create class rc = %d\n", ret); + goto error_class_create; + } + + hdcp->device = device_create(hdcp->class, NULL, + hdcp->dev_num, NULL, DRIVER_NAME); + if (IS_ERR(hdcp->device)) { + ret = PTR_ERR(hdcp->device); + pr_err("device_create failed %d\n", ret); + goto error_class_device_create; + } + + cdev_init(&hdcp->cdev, &msm_hdcp_fops); + ret = cdev_add(&hdcp->cdev, MKDEV(MAJOR(hdcp->dev_num), 0), 1); + if (ret < 0) { + pr_err("cdev_add failed %d\n", ret); + goto error_cdev_add; + } + + ret = sysfs_create_group(&hdcp->device->kobj, &msm_hdcp_fs_attr_group); + if (ret) + pr_err("unable to register msm_hdcp sysfs nodes\n"); + + return 0; +error_cdev_add: + device_destroy(hdcp->class, hdcp->dev_num); +error_class_device_create: + class_destroy(hdcp->class); +error_class_create: + unregister_chrdev_region(hdcp->dev_num, 1); +error_get_dev_num: + devm_kfree(&pdev->dev, hdcp); + hdcp = NULL; + return ret; +} + +static int msm_hdcp_remove(struct platform_device *pdev) +{ + struct msm_hdcp *hdcp; + + hdcp = platform_get_drvdata(pdev); + if (!hdcp) + return -ENODEV; + + sysfs_remove_group(&hdcp->device->kobj, + &msm_hdcp_fs_attr_group); + cdev_del(&hdcp->cdev); + device_destroy(hdcp->class, hdcp->dev_num); + class_destroy(hdcp->class); + unregister_chrdev_region(hdcp->dev_num, 1); + + devm_kfree(&pdev->dev, hdcp); + hdcp = NULL; + return 0; +} + +static struct platform_driver msm_hdcp_driver = { + .probe = msm_hdcp_probe, + .remove = msm_hdcp_remove, + .driver = { + .name = "msm_hdcp", + .of_match_table = msm_hdcp_dt_match, + .pm = NULL, + } +}; + +static int __init msm_hdcp_init(void) +{ + return platform_driver_register(&msm_hdcp_driver); +} + +static void __exit msm_hdcp_exit(void) +{ + return platform_driver_unregister(&msm_hdcp_driver); +} + +module_init(msm_hdcp_init); +module_exit(msm_hdcp_exit); + +MODULE_DESCRIPTION("MSM HDCP driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/hdcp_qseecom.h b/include/linux/hdcp_qseecom.h index 20f5cba11f96..08f30a46726f 100644 --- a/include/linux/hdcp_qseecom.h +++ b/include/linux/hdcp_qseecom.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -181,11 +181,9 @@ struct hdcp_txmtr_ops { /** * struct hdcp_client_ops - call back functions to display transport layer * @wakeup: wake up display transport layer with a new command - * @notify_lvl_change notify of encryption level changes */ struct hdcp_client_ops { int (*wakeup)(struct hdcp_wakeup_data *data); - void (*notify_lvl_change)(void *client_ctx, int min_lvl); }; /** @@ -219,6 +217,4 @@ void hdcp_library_deregister(void *phdcpcontext); bool hdcp1_check_if_supported_load_app(void); int hdcp1_set_keys(uint32_t *aksv_msb, uint32_t *aksv_lsb); int hdcp1_set_enc(bool enable); -void hdcp1_cache_repeater_topology(void *hdcp1_cached_tp); -void hdcp1_notify_topology(void); #endif /* __HDCP_QSEECOM_H */ diff --git a/include/linux/msm_hdcp.h b/include/linux/msm_hdcp.h new file mode 100644 index 000000000000..e25d242e0819 --- /dev/null +++ b/include/linux/msm_hdcp.h @@ -0,0 +1,26 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MSM_HDCP_H +#define __MSM_HDCP_H +#include +#include "video/msm_hdmi_hdcp_mgr.h" + +void msm_hdcp_notify_topology(struct device *dev); +void msm_hdcp_cache_repeater_topology(struct device *dev, + struct HDCP_V2V1_MSG_TOPOLOGY *tp); +void msm_hdcp_register_cb(struct device *dev, void *ctx, + void (*cb)(void *ctx, int data)); + +#endif /* __MSM_HDCP_H */ + + diff --git a/include/uapi/video/msm_hdmi_hdcp_mgr.h b/include/uapi/video/msm_hdmi_hdcp_mgr.h index 85fa918f2579..1c19d4a15bb7 100644 --- a/include/uapi/video/msm_hdmi_hdcp_mgr.h +++ b/include/uapi/video/msm_hdmi_hdcp_mgr.h @@ -1,4 +1,4 @@ -#ifndef _UAPI__HDMI_HDCP_MGR_H +#ifndef _UAPI__MSM_HDMI_HDCP_MGR_H #define _UAPI__MSM_HDMI_HDCP_MGR_H enum DS_TYPE { /* type of downstream device */