summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAjay Singh Parmar <aparmar@codeaurora.org>2016-04-18 16:08:47 -0700
committerJeevan Shriram <jshriram@codeaurora.org>2016-05-05 15:05:54 -0700
commit3aa9bfccc48428e80c18ca9b77c031a821c8a199 (patch)
tree0729a62c70301fdac54de02a9e908f0c3f7742bc
parent12fcd447522e37cdafd2f9c3e35b488fd412691f (diff)
msm: mdss: hdmi: refactor initialization of features
HDMI driver initializes many features like EDID (Extended Display Identification Data), CEC (Consumer Electronics Control), HDCP ( Hight-Bandwidth Digital Content Protection) and related sub-modules. Initialize them in separate functions for cleaner approach. Change-Id: I5b73d3b558af576b5114c42b63260bb688f2d8d1 Signed-off-by: Ajay Singh Parmar <aparmar@codeaurora.org>
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_tx.c323
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_tx.h2
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_util.h14
3 files changed, 210 insertions, 129 deletions
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c
index bddd9eb181b5..6df5c0d94e1f 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c
+++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.c
@@ -79,6 +79,9 @@
#define HDMI_TX_4_MAX_PCLK_RATE 600000
#define HDMI_TX_KHZ_TO_HZ 1000U
+#define hdmi_tx_get_fd(x) (x ? hdmi_ctrl->feature_data[ffs(x) - 1] : 0)
+#define hdmi_tx_set_fd(x, y) {if (x) hdmi_ctrl->feature_data[ffs(x) - 1] = y; }
+
/* Enable HDCP by default */
static bool hdcp_feature_on = true;
@@ -447,7 +450,7 @@ static int hdmi_tx_get_vic_from_panel_info(struct hdmi_tx_ctrl *hdmi_ctrl,
static inline u32 hdmi_tx_is_dvi_mode(struct hdmi_tx_ctrl *hdmi_ctrl)
{
return hdmi_edid_get_sink_mode(
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID]) ? 0 : 1;
+ hdmi_tx_get_fd(HDMI_TX_FEAT_EDID)) ? 0 : 1;
} /* hdmi_tx_is_dvi_mode */
static inline bool hdmi_tx_is_panel_on(struct hdmi_tx_ctrl *hdmi_ctrl)
@@ -457,21 +460,23 @@ static inline bool hdmi_tx_is_panel_on(struct hdmi_tx_ctrl *hdmi_ctrl)
static inline bool hdmi_tx_is_cec_wakeup_en(struct hdmi_tx_ctrl *hdmi_ctrl)
{
- if (!hdmi_ctrl || !hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC_HW])
+ void *fd = hdmi_tx_get_fd(HDMI_TX_FEAT_CEC_HW);
+
+ if (!hdmi_ctrl || !fd)
return false;
- return hdmi_cec_is_wakeup_en(
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC_HW]);
+ return hdmi_cec_is_wakeup_en(fd);
}
static inline void hdmi_tx_cec_device_suspend(struct hdmi_tx_ctrl *hdmi_ctrl,
bool suspend)
{
- if (!hdmi_ctrl || !hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC_HW])
+ void *fd = hdmi_tx_get_fd(HDMI_TX_FEAT_CEC_HW);
+
+ if (!hdmi_ctrl || !fd)
return;
- hdmi_cec_device_suspend(hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC_HW],
- suspend);
+ hdmi_cec_device_suspend(fd, suspend);
}
@@ -591,7 +596,7 @@ void *hdmi_get_featuredata_from_sysfs_dev(struct device *device,
hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(device);
if (hdmi_ctrl)
- return hdmi_ctrl->feature_data[feature_type];
+ return hdmi_tx_get_fd(feature_type);
else
return NULL;
@@ -1280,7 +1285,7 @@ static ssize_t hdmi_tx_sysfs_wta_s3d_mode(struct device *dev,
if (s3d_mode > HDMI_S3D_NONE &&
!hdmi_edid_is_s3d_mode_supported(
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID],
+ hdmi_tx_get_fd(HDMI_TX_FEAT_EDID),
hdmi_ctrl->vid_cfg.vic,
s3d_mode)) {
DEV_ERR("%s: s3d mode not supported in current video mode\n",
@@ -1772,58 +1777,50 @@ end:
}
/* Enable HDMI features */
-static int hdmi_tx_init_features(struct hdmi_tx_ctrl *hdmi_ctrl,
- struct fb_info *fbi)
+static int hdmi_tx_init_edid(struct hdmi_tx_ctrl *hdmi_ctrl)
{
struct hdmi_edid_init_data edid_init_data = {0};
- struct hdmi_hdcp_init_data hdcp_init_data = {0};
- struct hdmi_cec_init_data cec_init_data = {0};
- struct cec_abstract_init_data cec_abst_init_data = {0};
- struct hdmi_audio_init_data audio_init_data = {0};
- struct resource *res = NULL;
- void *fd = NULL;
- int ret = 0;
- void *cec_hw_data, *cec_abst_data;
-
- if (!hdmi_ctrl || !fbi) {
- DEV_ERR("%s: invalid input\n", __func__);
- ret = -EINVAL;
- goto end;
- }
+ void *edid_data;
+ int rc = 0;
- /* Initialize EDID feature */
edid_init_data.kobj = hdmi_ctrl->kobj;
edid_init_data.ds_data = hdmi_ctrl->ds_data;
edid_init_data.max_pclk_khz = hdmi_ctrl->max_pclk_khz;
- fd = hdmi_edid_init(&edid_init_data);
- if (!fd) {
- DEV_ERR("%s: hdmi_edid_init failed\n", __func__);
- ret = -ENODEV;
+ edid_data = hdmi_edid_init(&edid_init_data);
+ if (!edid_data) {
+ DEV_ERR("%s: edid init failed\n", __func__);
+ rc = -ENODEV;
goto end;
}
- hdmi_ctrl->panel_data.panel_info.edid_data = fd;
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID] = fd;
+ hdmi_ctrl->panel_data.panel_info.edid_data = edid_data;
+ hdmi_tx_set_fd(HDMI_TX_FEAT_EDID, edid_data);
/* get edid buffer from edid parser */
hdmi_ctrl->edid_buf = edid_init_data.buf;
hdmi_ctrl->edid_buf_size = edid_init_data.buf_size;
- hdmi_edid_set_video_resolution(fd, hdmi_ctrl->vid_cfg.vic, true);
+ hdmi_edid_set_video_resolution(edid_data, hdmi_ctrl->vid_cfg.vic, true);
+end:
+ return rc;
+}
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID] = fd;
+static int hdmi_tx_init_hdcp(struct hdmi_tx_ctrl *hdmi_ctrl)
+{
+ struct hdmi_hdcp_init_data hdcp_init_data = {0};
+ struct resource *res;
+ void *hdcp_data;
+ int rc = 0;
res = platform_get_resource_byname(hdmi_ctrl->pdev,
IORESOURCE_MEM, hdmi_tx_io_name(HDMI_TX_CORE_IO));
if (!res) {
- DEV_ERR("%s: Error getting HDMI tx core resource\n",
- __func__);
- ret = -ENODEV;
- goto err_res;
+ DEV_ERR("%s: Error getting HDMI tx core resource\n", __func__);
+ rc = -EINVAL;
+ goto end;
}
- /* Initialize HDCP features */
hdcp_init_data.phy_addr = res->start;
hdcp_init_data.core_io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
hdcp_init_data.qfprom_io = &hdmi_ctrl->pdata.io[HDMI_TX_QFPROM_IO];
@@ -1838,30 +1835,38 @@ static int hdmi_tx_init_features(struct hdmi_tx_ctrl *hdmi_ctrl,
hdcp_init_data.timing = &hdmi_ctrl->vid_cfg.timing;
if (hdmi_ctrl->hdcp14_present) {
- fd = hdmi_hdcp_init(&hdcp_init_data);
+ hdcp_data = hdmi_hdcp_init(&hdcp_init_data);
- if (IS_ERR_OR_NULL(fd)) {
- DEV_WARN("%s: hdmi_hdcp_init failed\n", __func__);
- ret = -ENODEV;
- goto err_res;
+ if (IS_ERR_OR_NULL(hdcp_data)) {
+ DEV_ERR("%s: hdcp 1.4 init failed\n", __func__);
+ rc = -EINVAL;
+ goto end;
} else {
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP] = fd;
- DEV_DBG("%s: HDCP 1.4 configured\n", __func__);
+ hdmi_tx_set_fd(HDMI_TX_FEAT_HDCP, hdcp_data);
+ DEV_DBG("%s: HDCP 1.4 initialized\n", __func__);
}
}
- fd = hdmi_hdcp2p2_init(&hdcp_init_data);
+ hdcp_data = hdmi_hdcp2p2_init(&hdcp_init_data);
- if (IS_ERR_OR_NULL(fd)) {
- DEV_WARN("%s: hdmi_hdcp2p2_init failed\n", __func__);
- ret = -ENODEV;
- goto err_hdcp;
+ if (IS_ERR_OR_NULL(hdcp_data)) {
+ DEV_ERR("%s: hdcp 2.2 init failed\n", __func__);
+ rc = -EINVAL;
+ goto end;
} else {
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP2P2] = fd;
- DEV_DBG("%s: HDCP 2.2 configured\n", __func__);
+ hdmi_tx_set_fd(HDMI_TX_FEAT_HDCP2P2, hdcp_data);
+ DEV_DBG("%s: HDCP 2.2 initialized\n", __func__);
}
+end:
+ return rc;
+}
+
+static int hdmi_tx_init_cec_hw(struct hdmi_tx_ctrl *hdmi_ctrl)
+{
+ struct hdmi_cec_init_data cec_init_data = {0};
+ void *cec_hw_data;
+ int rc = 0;
- /* initialize cec hw feature and get ops */
cec_init_data.io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
cec_init_data.workq = hdmi_ctrl->workq;
cec_init_data.pinfo = &hdmi_ctrl->panel_data.panel_info;
@@ -1870,53 +1875,153 @@ static int hdmi_tx_init_features(struct hdmi_tx_ctrl *hdmi_ctrl,
cec_hw_data = hdmi_cec_init(&cec_init_data);
if (IS_ERR_OR_NULL(cec_hw_data)) {
- DEV_ERR("%s: error cec init\n", __func__);
- goto err_cec_hw;
+ DEV_ERR("%s: cec init failed\n", __func__);
+ rc = -EINVAL;
+ } else {
+ hdmi_ctrl->panel_data.panel_info.is_cec_supported = true;
+ hdmi_tx_set_fd(HDMI_TX_FEAT_CEC_HW, cec_hw_data);
+ DEV_DBG("%s: cec hw initialized\n", __func__);
}
- hdmi_ctrl->panel_data.panel_info.is_cec_supported = true;
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC_HW] = cec_hw_data;
+ return rc;
+}
+
+static int hdmi_tx_init_cec_abst(struct hdmi_tx_ctrl *hdmi_ctrl)
+{
+ struct cec_abstract_init_data cec_abst_init_data = {0};
+ void *cec_abst_data;
+ int rc = 0;
- /* initialize cec abstract layer and get callbacks */
cec_abst_init_data.kobj = hdmi_ctrl->kobj;
cec_abst_init_data.ops = &hdmi_ctrl->hdmi_cec_ops;
cec_abst_init_data.cbs = &hdmi_ctrl->hdmi_cec_cbs;
cec_abst_data = cec_abstract_init(&cec_abst_init_data);
if (IS_ERR_OR_NULL(cec_abst_data)) {
- DEV_ERR("%s: error cec init\n", __func__);
- goto err_cec_abst;
+ DEV_ERR("%s: cec abst init failed\n", __func__);
+ rc = -EINVAL;
+ } else {
+ hdmi_tx_set_fd(HDMI_TX_FEAT_CEC_ABST, cec_abst_data);
+ hdmi_ctrl->panel_data.panel_info.cec_data = cec_abst_data;
+ DEV_DBG("%s: cec abst initialized\n", __func__);
}
- /* keep cec abstract data */
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC_ABST] = cec_abst_data;
- hdmi_ctrl->panel_data.panel_info.cec_data = cec_abst_data;
+ return rc;
+}
+
+static int hdmi_tx_init_audio(struct hdmi_tx_ctrl *hdmi_ctrl)
+{
+ struct hdmi_audio_init_data audio_init_data = {0};
+ void *audio_data;
+ int rc = 0;
audio_init_data.io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
audio_init_data.ops = &hdmi_ctrl->audio_ops;
- hdmi_ctrl->audio_data = hdmi_audio_register(&audio_init_data);
- return 0;
+ audio_data = hdmi_audio_register(&audio_init_data);
+ if (!audio_data) {
+ rc = -EINVAL;
+ DEV_ERR("%s: audio init failed\n", __func__);
+ } else {
+ hdmi_ctrl->audio_data = audio_data;
+ DEV_DBG("%s: audio initialized\n", __func__);
+ }
-err_cec_abst:
- hdmi_cec_deinit(hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC_HW]);
- hdmi_ctrl->panel_data.panel_info.is_cec_supported = false;
-err_cec_hw:
- if (hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP2P2]) {
- hdmi_hdcp2p2_deinit(
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP2P2]);
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP2P2] = NULL;
- }
-err_hdcp:
- if (hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP]) {
- hdmi_hdcp_deinit(hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP]);
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP] = NULL;
- }
-err_res:
- hdmi_edid_deinit(hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID]);
+ return rc;
+}
+
+static void hdmi_tx_deinit_features(struct hdmi_tx_ctrl *hdmi_ctrl,
+ u32 features)
+{
+ void *fd;
+
+ if (features & HDMI_TX_FEAT_CEC_ABST) {
+ fd = hdmi_tx_get_fd(HDMI_TX_FEAT_CEC_ABST);
+
+ cec_abstract_deinit(fd);
+
+ hdmi_ctrl->panel_data.panel_info.cec_data = NULL;
+ hdmi_tx_set_fd(HDMI_TX_FEAT_CEC_ABST, 0);
+ }
+
+ if (features & HDMI_TX_FEAT_CEC_HW) {
+ fd = hdmi_tx_get_fd(HDMI_TX_FEAT_CEC_HW);
+
+ hdmi_cec_deinit(fd);
+ hdmi_ctrl->panel_data.panel_info.is_cec_supported = false;
+ hdmi_tx_set_fd(HDMI_TX_FEAT_CEC_HW, 0);
+ }
+
+ if (features & HDMI_TX_FEAT_HDCP2P2) {
+ fd = hdmi_tx_get_fd(HDMI_TX_FEAT_HDCP2P2);
+
+ hdmi_hdcp2p2_deinit(fd);
+ hdmi_tx_set_fd(HDMI_TX_FEAT_HDCP2P2, 0);
+ }
+
+ if (features & HDMI_TX_FEAT_HDCP) {
+ fd = hdmi_tx_get_fd(HDMI_TX_FEAT_HDCP);
+
+ hdmi_hdcp_deinit(fd);
+ hdmi_tx_set_fd(HDMI_TX_FEAT_HDCP, 0);
+ }
+
+ if (features & HDMI_TX_FEAT_EDID) {
+ fd = hdmi_tx_get_fd(HDMI_TX_FEAT_EDID);
+
+ hdmi_edid_deinit(fd);
+ hdmi_ctrl->edid_buf = NULL;
+ hdmi_ctrl->edid_buf_size = 0;
+ hdmi_tx_set_fd(HDMI_TX_FEAT_EDID, 0);
+ }
+} /* hdmi_tx_init_features */
+
+static int hdmi_tx_init_features(struct hdmi_tx_ctrl *hdmi_ctrl,
+ struct fb_info *fbi)
+{
+ int ret = 0;
+ u32 deinit_features = 0;
+
+ if (!hdmi_ctrl || !fbi) {
+ DEV_ERR("%s: invalid input\n", __func__);
+ ret = -EINVAL;
+ goto end;
+ }
+
+ ret = hdmi_tx_init_edid(hdmi_ctrl);
+ if (ret)
+ goto end;
+
+ ret = hdmi_tx_init_hdcp(hdmi_ctrl);
+ if (ret) {
+ deinit_features |= HDMI_TX_FEAT_EDID;
+ goto err;
+ }
+
+ ret = hdmi_tx_init_cec_hw(hdmi_ctrl);
+ if (ret) {
+ deinit_features |= HDMI_TX_FEAT_HDCP;
+ goto err;
+ }
+
+ ret = hdmi_tx_init_cec_abst(hdmi_ctrl);
+ if (ret) {
+ deinit_features |= HDMI_TX_FEAT_CEC_HW;
+ goto err;
+ }
+
+ ret = hdmi_tx_init_audio(hdmi_ctrl);
+ if (ret) {
+ deinit_features |= HDMI_TX_FEAT_CEC_ABST;
+ goto err;
+ }
+
+ return 0;
+err:
+ hdmi_tx_deinit_features(hdmi_ctrl, deinit_features);
end:
return ret;
-} /* hdmi_tx_init_features */
+}
static inline u32 hdmi_tx_is_controller_on(struct hdmi_tx_ctrl *hdmi_ctrl)
{
@@ -1985,7 +2090,7 @@ static int hdmi_tx_read_sink_info(struct hdmi_tx_ctrl *hdmi_ctrl)
return -EINVAL;
}
- data = hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID];
+ data = hdmi_tx_get_fd(HDMI_TX_FEAT_EDID);
if (!hdmi_tx_is_controller_on(hdmi_ctrl)) {
DEV_ERR("%s: failed: HDMI controller is off", __func__);
@@ -2025,7 +2130,7 @@ static void hdmi_tx_update_hdcp_info(struct hdmi_tx_ctrl *hdmi_ctrl)
}
/* check first if hdcp2p2 is supported */
- fd = hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP2P2];
+ fd = hdmi_tx_get_fd(HDMI_TX_FEAT_HDCP2P2);
if (fd)
ops = hdmi_hdcp2p2_start(fd);
@@ -2040,7 +2145,7 @@ static void hdmi_tx_update_hdcp_info(struct hdmi_tx_ctrl *hdmi_ctrl)
hdcp1_check_if_supported_load_app();
if (hdmi_ctrl->hdcp14_present) {
- fd = hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP];
+ fd = hdmi_tx_get_fd(HDMI_TX_FEAT_HDCP);
ops = hdmi_hdcp_start(fd);
}
}
@@ -2211,7 +2316,7 @@ static int hdmi_tx_set_video_fmt(struct hdmi_tx_ctrl *hdmi_ctrl,
vid_cfg->vic = new_vic;
vid_cfg->avi_iframe.pixel_format = pinfo->out_format;
vid_cfg->avi_iframe.scan_info = hdmi_edid_get_sink_scaninfo(
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID],
+ hdmi_tx_get_fd(HDMI_TX_FEAT_EDID),
hdmi_ctrl->vid_cfg.vic);
vid_cfg->avi_iframe.bar_info.end_of_top_bar = 0x0;
@@ -2245,7 +2350,7 @@ static int hdmi_tx_set_video_fmt(struct hdmi_tx_ctrl *hdmi_ctrl,
(vid_cfg->timing.pixel_freq * 1000) >> div;
hdmi_edid_set_video_resolution(
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID],
+ hdmi_tx_get_fd(HDMI_TX_FEAT_EDID),
vid_cfg->vic, false);
hdmi_tx_update_panel_data(hdmi_ctrl);
@@ -2562,7 +2667,7 @@ static void hdmi_tx_set_vendor_specific_infoframe(
if ((hdmi_ctrl->s3d_mode != HDMI_S3D_NONE) &&
hdmi_edid_is_s3d_mode_supported(
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID],
+ hdmi_tx_get_fd(HDMI_TX_FEAT_EDID),
hdmi_ctrl->vid_cfg.vic,
hdmi_ctrl->s3d_mode)) {
switch (hdmi_ctrl->s3d_mode) {
@@ -2766,8 +2871,7 @@ static void hdmi_tx_set_mode(struct hdmi_tx_ctrl *hdmi_ctrl, u32 power_on)
reg_val |= BIT(2);
/* Set transmission mode to DVI based in EDID info */
- if (hdmi_edid_get_sink_mode(
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID]) == 0)
+ if (!hdmi_edid_get_sink_mode(hdmi_tx_get_fd(HDMI_TX_FEAT_EDID)))
reg_val &= ~BIT(1); /* DVI mode */
/*
@@ -3229,7 +3333,7 @@ static int hdmi_tx_get_audio_edid_blk(struct platform_device *pdev,
}
return hdmi_edid_get_audio_blk(
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID], blk);
+ hdmi_tx_get_fd(HDMI_TX_FEAT_EDID), blk);
} /* hdmi_tx_get_audio_edid_blk */
static u8 hdmi_tx_tmds_enabled(struct platform_device *pdev)
@@ -3408,7 +3512,7 @@ int hdmi_tx_setup_scrambler(struct hdmi_tx_ctrl *hdmi_ctrl)
return -EINVAL;
}
- edid_data = hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID];
+ edid_data = hdmi_tx_get_fd(HDMI_TX_FEAT_EDID);
timing = &hdmi_ctrl->vid_cfg.timing;
if (!timing) {
@@ -3967,9 +4071,10 @@ static irqreturn_t hdmi_tx_isr(int irq, void *data)
hdmi_ctrl->hdmi_tx_ver))
DEV_ERR("%s: hdmi_ddc_isr failed\n", __func__);
- if (hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC_HW])
- if (hdmi_cec_isr(hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC_HW]))
+ if (hdmi_tx_get_fd(HDMI_TX_FEAT_CEC_HW)) {
+ if (hdmi_cec_isr(hdmi_tx_get_fd(HDMI_TX_FEAT_CEC_HW)))
DEV_ERR("%s: hdmi_cec_isr failed\n", __func__);
+ }
if (hdmi_ctrl->hdcp_ops && hdmi_ctrl->hdcp_data) {
if (hdmi_ctrl->hdcp_ops->hdmi_hdcp_isr) {
@@ -3990,37 +4095,11 @@ static void hdmi_tx_dev_deinit(struct hdmi_tx_ctrl *hdmi_ctrl)
return;
}
- if (hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC_ABST]) {
- cec_abstract_deinit(
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC_ABST]);
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC_ABST] = NULL;
- }
-
- if (hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC_HW]) {
- hdmi_cec_deinit(hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC_HW]);
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC_HW] = NULL;
- hdmi_ctrl->panel_data.panel_info.is_cec_supported = false;
- }
-
- if (hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP]) {
- hdmi_hdcp_deinit(hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP]);
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP] = NULL;
- }
-
- if (hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP2P2]) {
- hdmi_hdcp2p2_deinit(
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP2P2]);
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_HDCP2P2] = NULL;
- }
+ hdmi_tx_deinit_features(hdmi_ctrl, HDMI_TX_FEAT_MAX);
hdmi_ctrl->hdcp_ops = NULL;
hdmi_ctrl->hdcp_data = NULL;
- if (hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID]) {
- hdmi_edid_deinit(hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID]);
- hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID] = NULL;
- }
-
switch_dev_unregister(&hdmi_ctrl->sdev);
if (hdmi_ctrl->workq)
destroy_workqueue(hdmi_ctrl->workq);
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.h b/drivers/video/fbdev/msm/mdss_hdmi_tx.h
index 5db8f2934a68..ff7b9f72ae6f 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_tx.h
+++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.h
@@ -184,7 +184,7 @@ struct hdmi_tx_ctrl {
void *downstream_data;
void *audio_data;
- void *feature_data[HDMI_TX_FEAT_MAX];
+ void *feature_data[hweight8(HDMI_TX_FEAT_MAX)];
struct hdmi_hdcp_ops *hdcp_ops;
void *hdcp_data;
bool hdcp22_present;
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_util.h b/drivers/video/fbdev/msm/mdss_hdmi_util.h
index cb459ab17bd7..cbe22b751e77 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_util.h
+++ b/drivers/video/fbdev/msm/mdss_hdmi_util.h
@@ -368,12 +368,14 @@
#define HDMI_DEFAULT_TIMEOUT_HSYNC 28571
enum hdmi_tx_feature_type {
- HDMI_TX_FEAT_EDID,
- HDMI_TX_FEAT_HDCP,
- HDMI_TX_FEAT_HDCP2P2,
- HDMI_TX_FEAT_CEC_HW,
- HDMI_TX_FEAT_CEC_ABST,
- HDMI_TX_FEAT_MAX,
+ HDMI_TX_FEAT_EDID = BIT(0),
+ HDMI_TX_FEAT_HDCP = BIT(1),
+ HDMI_TX_FEAT_HDCP2P2 = BIT(2),
+ HDMI_TX_FEAT_CEC_HW = BIT(3),
+ HDMI_TX_FEAT_CEC_ABST = BIT(4),
+ HDMI_TX_FEAT_MAX = HDMI_TX_FEAT_EDID | HDMI_TX_FEAT_HDCP |
+ HDMI_TX_FEAT_HDCP2P2 | HDMI_TX_FEAT_CEC_HW |
+ HDMI_TX_FEAT_CEC_ABST
};
enum hdmi_tx_scdc_access_type {