From 6b0f2c2891bbac93e32df8809c21984af03b178d Mon Sep 17 00:00:00 2001 From: raghavendra ambadas Date: Wed, 19 Mar 2014 13:02:48 +0530 Subject: [PATCH] msm: mdss: Dynamically enabling ESD Allow the check_status interval time to be configurable via /sys interface. Allow the dsi_check_status function to be enabled or disabled via /sys interface Combine MDP3 & MDP5 code and separate the platform specific code. Change-Id: I0a6be25b6974ff8dafa472febbdbde517d35cbbc Signed-off-by: Raghavendra Ambadas --- drivers/video/msm/mdss/Makefile | 8 +- drivers/video/msm/mdss/dsi_status_6g.c | 109 ++++++++++++++++ drivers/video/msm/mdss/dsi_status_v2.c | 148 +++------------------- drivers/video/msm/mdss/mdp3.c | 1 + drivers/video/msm/mdss/mdp3.h | 2 + drivers/video/msm/mdss/mdss_dsi.h | 6 + drivers/video/msm/mdss/mdss_dsi_status.c | 153 ++++++++++------------- drivers/video/msm/mdss/mdss_fb.h | 1 + drivers/video/msm/mdss/mdss_mdp.c | 1 + drivers/video/msm/mdss/mdss_mdp.h | 1 + 10 files changed, 207 insertions(+), 223 deletions(-) create mode 100644 drivers/video/msm/mdss/dsi_status_6g.c diff --git a/drivers/video/msm/mdss/Makefile b/drivers/video/msm/mdss/Makefile index cba7c22b352..ddea7352d21 100644 --- a/drivers/video/msm/mdss/Makefile +++ b/drivers/video/msm/mdss/Makefile @@ -1,8 +1,8 @@ -mdss-mdp3-objs = mdp3.o mdp3_dma.o mdp3_ctrl.o +mdss-mdp3-objs = mdp3.o mdp3_dma.o mdp3_ctrl.o dsi_status_v2.o mdss-mdp3-objs += mdp3_ppp.o mdp3_ppp_hwio.o mdp3_ppp_data.o obj-$(CONFIG_FB_MSM_MDSS_MDP3) += mdss-mdp3.o -mdss-mdp-objs := mdss_mdp.o mdss_mdp_ctl.o mdss_mdp_pipe.o mdss_mdp_util.o +mdss-mdp-objs := mdss_mdp.o mdss_mdp_ctl.o mdss_mdp_pipe.o mdss_mdp_util.o dsi_status_6g.o mdss-mdp-objs += mdss_mdp_pp.o mdss-mdp-objs += mdss_mdp_intf_video.o mdss-mdp-objs += mdss_mdp_intf_cmd.o @@ -42,8 +42,4 @@ obj-$(CONFIG_FB_MSM_QPIC_ILI_QVGA_PANEL) += qpic_panel_ili_qvga.o obj-$(CONFIG_FB_MSM_MDSS) += mdss_fb.o -ifeq ($(CONFIG_FB_MSM_MDSS_MDP3),y) -obj-$(CONFIG_FB_MSM_MDSS_DSI_CTRL_STATUS) += dsi_status_v2.o -else obj-$(CONFIG_FB_MSM_MDSS_DSI_CTRL_STATUS) += mdss_dsi_status.o -endif diff --git a/drivers/video/msm/mdss/dsi_status_6g.c b/drivers/video/msm/mdss/dsi_status_6g.c new file mode 100644 index 00000000000..31c90229a83 --- /dev/null +++ b/drivers/video/msm/mdss/dsi_status_6g.c @@ -0,0 +1,109 @@ +/* Copyright (c) 2013-2014, 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. + */ + +#include +#include +#include +#include + +#include "mdss_dsi.h" +#include "mdss_mdp.h" + +/* + * mdss_check_dsi_ctrl_status() - Check MDP5 DSI controller status periodically. + * @work : dsi controller status data + * @interval : duration in milliseconds to schedule work queue + * + * This function calls check_status API on DSI controller to send the BTA + * command. If DSI controller fails to acknowledge the BTA command, it sends + * the PANEL_ALIVE=0 status to HAL layer. + */ +void mdss_check_dsi_ctrl_status(struct work_struct *work, uint32_t interval) +{ + struct dsi_status_data *pstatus_data = NULL; + struct mdss_panel_data *pdata = NULL; + struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; + struct mdss_overlay_private *mdp5_data = NULL; + struct mdss_mdp_ctl *ctl = NULL; + int ret = 0; + + pstatus_data = container_of(to_delayed_work(work), + struct dsi_status_data, check_status); + + pdata = dev_get_platdata(&pstatus_data->mfd->pdev->dev); + if (!pdata) { + pr_err("%s: Panel data not available\n", __func__); + return; + } + + ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, + panel_data); + if (!ctrl_pdata || !ctrl_pdata->check_status) { + pr_err("%s: DSI ctrl or status_check callback not available\n", + __func__); + return; + } + + mdp5_data = mfd_to_mdp5_data(pstatus_data->mfd); + ctl = mfd_to_ctl(pstatus_data->mfd); + + if (ctl->shared_lock) + mutex_lock(ctl->shared_lock); + mutex_lock(&mdp5_data->ov_lock); + + if (pstatus_data->mfd->shutdown_pending) { + mutex_unlock(&mdp5_data->ov_lock); + if (ctl->shared_lock) + mutex_unlock(ctl->shared_lock); + pr_err("%s: DSI turning off, avoiding BTA status check\n", + __func__); + return; + } + + /* + * For the command mode panels, we return pan display + * IOCTL on vsync interrupt. So, after vsync interrupt comes + * and when DMA_P is in progress, if the panel stops responding + * and if we trigger BTA before DMA_P finishes, then the DSI + * FIFO will not be cleared since the DSI data bus control + * doesn't come back to the host after BTA. This may cause the + * display reset not to be proper. Hence, wait for DMA_P done + * for command mode panels before triggering BTA. + */ + if (ctl->wait_pingpong) + ctl->wait_pingpong(ctl, NULL); + + pr_debug("%s: DSI ctrl wait for ping pong done\n", __func__); + + mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false); + ret = ctrl_pdata->check_status(ctrl_pdata); + mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false); + + mutex_unlock(&mdp5_data->ov_lock); + if (ctl->shared_lock) + mutex_unlock(ctl->shared_lock); + + if ((pstatus_data->mfd->panel_power_on)) { + if (ret > 0) { + schedule_delayed_work(&pstatus_data->check_status, + msecs_to_jiffies(interval)); + } else { + char *envp[2] = {"PANEL_ALIVE=0", NULL}; + pdata->panel_info.panel_dead = true; + ret = kobject_uevent_env( + &pstatus_data->mfd->fbi->dev->kobj, + KOBJ_CHANGE, envp); + pr_err("%s: Panel has gone bad, sending uevent - %s\n", + __func__, envp[0]); + } + } +} diff --git a/drivers/video/msm/mdss/dsi_status_v2.c b/drivers/video/msm/mdss/dsi_status_v2.c index 565401d6aee..c8915e67b11 100644 --- a/drivers/video/msm/mdss/dsi_status_v2.c +++ b/drivers/video/msm/mdss/dsi_status_v2.c @@ -10,49 +10,26 @@ * GNU General Public License for more details. */ -#include -#include -#include -#include -#include #include #include -#include -#include -#include -#include #include #include #include -#include "mdss_fb.h" #include "mdss_dsi.h" -#include "mdss_panel.h" #include "mdp3_ctrl.h" -#define STATUS_CHECK_INTERVAL 5000 - -/** - * dsi_status_data - Stores all the data necessary for this module - * @fb_notif: Used to egister for the fb events - * @live_status: Delayed worker structure, used to associate the - * delayed worker function - * @mfd: Used to store the msm_fb_data_type received when the notifier - * call back happens - * @root: Stores the dir created by debuugfs - * @debugfs_reset_panel: The debugfs variable used to inject errors +/* + * mdp3_check_dsi_ctrl_status() - Check MDP3 DSI controller status periodically. + * @work : dsi controller status data + * @interval : duration in milliseconds to schedule work queue + * + * This function calls check_status API on DSI controller to send the BTA + * command. If DSI controller fails to acknowledge the BTA command, it sends + * the PANEL_ALIVE=0 status to HAL layer. */ - -struct dsi_status_data { - struct notifier_block fb_notifier; - struct delayed_work check_status; - struct msm_fb_data_type *mfd; - uint32_t check_interval; -}; -struct dsi_status_data *pstatus_data; -static uint32_t interval = STATUS_CHECK_INTERVAL; - -void check_dsi_ctrl_status(struct work_struct *work) +void mdp3_check_dsi_ctrl_status(struct work_struct *work, + uint32_t interval) { struct dsi_status_data *pdsi_status = NULL; struct mdss_panel_data *pdata = NULL; @@ -61,27 +38,25 @@ void check_dsi_ctrl_status(struct work_struct *work) int ret = 0; pdsi_status = container_of(to_delayed_work(work), - struct dsi_status_data, check_status); - if (!pdsi_status) { - pr_err("%s: DSI status data not available\n", __func__); - return; - } + struct dsi_status_data, check_status); pdata = dev_get_platdata(&pdsi_status->mfd->pdev->dev); if (!pdata) { pr_err("%s: Panel data not available\n", __func__); return; } + ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); + if (!ctrl_pdata || !ctrl_pdata->check_status) { - pr_err("%s: DSI ctrl or status_check callback not avilable\n", + pr_err("%s: DSI ctrl or status_check callback not available\n", __func__); return; } + mdp3_session = pdsi_status->mfd->mdp.private1; mutex_lock(&mdp3_session->lock); - if (!mdp3_session->status) { pr_info("display off already\n"); mutex_unlock(&mdp3_session->lock); @@ -94,107 +69,22 @@ void check_dsi_ctrl_status(struct work_struct *work) if (!ret) ret = ctrl_pdata->check_status(ctrl_pdata); else - pr_err("wait_for_dma_done error\n"); - + pr_err("%s: wait_for_dma_done error\n", __func__); mutex_unlock(&mdp3_session->lock); if ((pdsi_status->mfd->panel_power_on)) { if (ret > 0) { schedule_delayed_work(&pdsi_status->check_status, - msecs_to_jiffies(pdsi_status->check_interval)); + msecs_to_jiffies(interval)); } else { char *envp[2] = {"PANEL_ALIVE=0", NULL}; pdata->panel_info.panel_dead = true; ret = kobject_uevent_env( - &pdsi_status->mfd->fbi->dev->kobj, - KOBJ_CHANGE, envp); + &pdsi_status->mfd->fbi->dev->kobj, + KOBJ_CHANGE, envp); pr_err("%s: Panel has gone bad, sending uevent - %s\n", __func__, envp[0]); } } } -/** - * fb_notifier_callback() - Call back function for the fb_register_client() - * notifying events - * @self : notifier block - * @event : The event that was triggered - * @data : Of type struct fb_event - * - * - This function listens for FB_BLANK_UNBLANK and FB_BLANK_POWERDOWN events - * - Based on the event the delayed work is either scheduled again after - * PANEL_STATUS_CHECK_INTERVAL or cancelled - */ -static int fb_event_callback(struct notifier_block *self, - unsigned long event, void *data) -{ - struct fb_event *evdata = (struct fb_event *)data; - struct dsi_status_data *pdata = container_of(self, - struct dsi_status_data, fb_notifier); - pdata->mfd = (struct msm_fb_data_type *)evdata->info->par; - - if (event == FB_EVENT_BLANK && evdata) { - int *blank = evdata->data; - switch (*blank) { - case FB_BLANK_UNBLANK: - schedule_delayed_work(&pdata->check_status, - msecs_to_jiffies(STATUS_CHECK_INTERVAL)); - break; - case FB_BLANK_POWERDOWN: - cancel_delayed_work(&pdata->check_status); - break; - } - } - return 0; -} - -int __init mdss_dsi_status_init(void) -{ - int rc; - - pstatus_data = kzalloc(sizeof(struct dsi_status_data), GFP_KERNEL); - if (!pstatus_data) { - pr_err("%s: can't alloc mem\n", __func__); - rc = -ENOMEM; - return rc; - } - - memset(pstatus_data, 0, sizeof(struct dsi_status_data)); - - pstatus_data->fb_notifier.notifier_call = fb_event_callback; - - rc = fb_register_client(&pstatus_data->fb_notifier); - if (rc < 0) { - pr_err("%s: fb_register_client failed, returned with rc=%d\n", - __func__, rc); - kfree(pstatus_data); - return -EPERM; - } - - pstatus_data->check_interval = interval; - pr_info("%s: DSI status check interval:%d\n", __func__, interval); - - INIT_DELAYED_WORK(&pstatus_data->check_status, check_dsi_ctrl_status); - - pr_debug("%s: DSI ctrl status thread initialized\n", __func__); - - return rc; -} - -void __exit mdss_dsi_status_exit(void) -{ - fb_unregister_client(&pstatus_data->fb_notifier); - cancel_delayed_work_sync(&pstatus_data->check_status); - kfree(pstatus_data); - pr_debug("%s: DSI ctrl status thread removed\n", __func__); -} - -module_param(interval, uint, 0); -MODULE_PARM_DESC(interval, - "Duration in milliseconds to send BTA command for checking" - "DSI status periodically"); - -module_init(mdss_dsi_status_init); -module_exit(mdss_dsi_status_exit); - -MODULE_LICENSE("GPL v2"); diff --git a/drivers/video/msm/mdss/mdp3.c b/drivers/video/msm/mdss/mdp3.c index ad7cb810b2c..8e2ae4dd1bb 100644 --- a/drivers/video/msm/mdss/mdp3.c +++ b/drivers/video/msm/mdss/mdp3.c @@ -2266,6 +2266,7 @@ static int mdp3_probe(struct platform_device *pdev) .panel_register_done = mdp3_panel_register_done, .fb_stride = mdp3_fb_stride, .fb_mem_alloc_fnc = mdp3_alloc, + .check_dsi_status = mdp3_check_dsi_ctrl_status, }; struct mdp3_intr_cb underrun_cb = { diff --git a/drivers/video/msm/mdss/mdp3.h b/drivers/video/msm/mdss/mdp3.h index 15aab591b60..137a1b86143 100644 --- a/drivers/video/msm/mdss/mdp3.h +++ b/drivers/video/msm/mdss/mdp3.h @@ -209,6 +209,8 @@ void mdp3_batfet_ctrl(int enable); int mdp3_misr_set(struct mdp_misr *misr_req); int mdp3_misr_get(struct mdp_misr *misr_resp); void mdp3_enable_regulator(int enable); +void mdp3_check_dsi_ctrl_status(struct work_struct *work, + uint32_t interval); #define MDP3_REG_WRITE(addr, val) writel_relaxed(val, mdp3_res->mdp_base + addr) #define MDP3_REG_READ(addr) readl_relaxed(mdp3_res->mdp_base + addr) diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h index f6f6cd417d2..962599de581 100644 --- a/drivers/video/msm/mdss/mdss_dsi.h +++ b/drivers/video/msm/mdss/mdss_dsi.h @@ -302,6 +302,12 @@ struct mdss_dsi_ctrl_pdata { struct dsi_buf rx_buf; }; +struct dsi_status_data { + struct notifier_block fb_notifier; + struct delayed_work check_status; + struct msm_fb_data_type *mfd; +}; + int dsi_panel_device_register(struct device_node *pan_node, struct mdss_dsi_ctrl_pdata *ctrl_pdata); diff --git a/drivers/video/msm/mdss/mdss_dsi_status.c b/drivers/video/msm/mdss/mdss_dsi_status.c index 1dca08eb5bc..116b778b27a 100644 --- a/drivers/video/msm/mdss/mdss_dsi_status.c +++ b/drivers/video/msm/mdss/mdss_dsi_status.c @@ -30,36 +30,26 @@ #include "mdss_panel.h" #include "mdss_mdp.h" -#define STATUS_CHECK_INTERVAL 5000 +#define STATUS_CHECK_INTERVAL_MS 5000 +#define STATUS_CHECK_INTERVAL_MIN_MS 200 +#define DSI_STATUS_CHECK_DISABLE 1 -struct dsi_status_data { - struct notifier_block fb_notifier; - struct delayed_work check_status; - struct msm_fb_data_type *mfd; - uint32_t check_interval; -}; +static uint32_t interval = STATUS_CHECK_INTERVAL_MS; +static uint32_t dsi_status_disable = DSI_STATUS_CHECK_DISABLE; struct dsi_status_data *pstatus_data; -static uint32_t interval = STATUS_CHECK_INTERVAL; /* - * check_dsi_ctrl_status() - Check DSI controller status periodically. + * check_dsi_ctrl_status() - Reads MFD structure and + * calls platform specific DSI ctrl Status function. * @work : dsi controller status data - * - * This function calls check_status API on DSI controller to send the BTA - * command. If DSI controller fails to acknowledge the BTA command, it sends - * the PANEL_ALIVE=0 status to HAL layer. */ static void check_dsi_ctrl_status(struct work_struct *work) { struct dsi_status_data *pdsi_status = NULL; - struct mdss_panel_data *pdata = NULL; - struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; - struct mdss_overlay_private *mdp5_data = NULL; - struct mdss_mdp_ctl *ctl = NULL; - int ret = 0; pdsi_status = container_of(to_delayed_work(work), struct dsi_status_data, check_status); + if (!pdsi_status) { pr_err("%s: DSI status data not available\n", __func__); return; @@ -70,73 +60,7 @@ static void check_dsi_ctrl_status(struct work_struct *work) return; } - pdata = dev_get_platdata(&pdsi_status->mfd->pdev->dev); - if (!pdata) { - pr_err("%s: Panel data not available\n", __func__); - return; - } - - ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, - panel_data); - if (!ctrl_pdata || !ctrl_pdata->check_status) { - pr_err("%s: DSI ctrl or status_check callback not available\n", - __func__); - return; - } - - mdp5_data = mfd_to_mdp5_data(pdsi_status->mfd); - ctl = mfd_to_ctl(pdsi_status->mfd); - - if (ctl->shared_lock) - mutex_lock(ctl->shared_lock); - mutex_lock(&mdp5_data->ov_lock); - - if (pdsi_status->mfd->shutdown_pending) { - mutex_unlock(&mdp5_data->ov_lock); - if (ctl->shared_lock) - mutex_unlock(ctl->shared_lock); - pr_err("%s: DSI turning off, avoiding BTA status check\n", - __func__); - return; - } - - /* - * For the command mode panels, we return pan display - * IOCTL on vsync interrupt. So, after vsync interrupt comes - * and when DMA_P is in progress, if the panel stops responding - * and if we trigger BTA before DMA_P finishes, then the DSI - * FIFO will not be cleared since the DSI data bus control - * doesn't come back to the host after BTA. This may cause the - * display reset not to be proper. Hence, wait for DMA_P done - * for command mode panels before triggering BTA. - */ - if (ctl->wait_pingpong) - ctl->wait_pingpong(ctl, NULL); - - pr_debug("%s: DSI ctrl wait for ping pong done\n", __func__); - - mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false); - ret = ctrl_pdata->check_status(ctrl_pdata); - mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false); - - mutex_unlock(&mdp5_data->ov_lock); - if (ctl->shared_lock) - mutex_unlock(ctl->shared_lock); - - if ((pdsi_status->mfd->panel_power_on)) { - if (ret > 0) { - schedule_delayed_work(&pdsi_status->check_status, - msecs_to_jiffies(pdsi_status->check_interval)); - } else { - char *envp[2] = {"PANEL_ALIVE=0", NULL}; - pdata->panel_info.panel_dead = true; - ret = kobject_uevent_env( - &pdsi_status->mfd->fbi->dev->kobj, - KOBJ_CHANGE, envp); - pr_err("%s: Panel has gone bad, sending uevent - %s\n", - __func__, envp[0]); - } - } + pdsi_status->mfd->mdp.check_dsi_status(work, interval); } /* @@ -156,6 +80,19 @@ static int fb_event_callback(struct notifier_block *self, struct fb_event *evdata = data; struct dsi_status_data *pdata = container_of(self, struct dsi_status_data, fb_notifier); + struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; + + pdata->mfd = evdata->info->par; + ctrl_pdata = container_of(dev_get_platdata(&pdata->mfd->pdev->dev), + struct mdss_dsi_ctrl_pdata, panel_data); + if (!ctrl_pdata) { + pr_err("%s: DSI ctrl not available\n", __func__); + return NOTIFY_BAD; + } + if (dsi_status_disable) { + pr_debug("%s: DSI status disabled\n", __func__); + return NOTIFY_DONE; + } if (event == FB_EVENT_BLANK && evdata) { int *blank = evdata->data; @@ -166,7 +103,7 @@ static int fb_event_callback(struct notifier_block *self, switch (*blank) { case FB_BLANK_UNBLANK: schedule_delayed_work(&pdata->check_status, - msecs_to_jiffies(pdata->check_interval)); + msecs_to_jiffies(interval)); break; case FB_BLANK_POWERDOWN: cancel_delayed_work(&pdata->check_status); @@ -176,6 +113,41 @@ static int fb_event_callback(struct notifier_block *self, return 0; } +static int param_dsi_status_disable(const char *val, struct kernel_param *kp) +{ + int ret = 0; + int int_val; + + ret = kstrtos32(val, 0, &int_val); + if (ret) + return ret; + + pr_info("%s: Set DSI status disable to %d\n", + __func__, int_val); + *((int *)kp->arg) = int_val; + return ret; +} + +static int param_set_interval(const char *val, struct kernel_param *kp) +{ + int ret = 0; + int int_val; + + ret = kstrtos32(val, 0, &int_val); + if (ret) + return ret; + if (int_val < STATUS_CHECK_INTERVAL_MIN_MS) { + pr_err("%s: Invalid value %d used, ignoring\n", + __func__, int_val); + ret = -EINVAL; + } else { + pr_info("%s: Set check interval to %d msecs\n", + __func__, int_val); + *((int *)kp->arg) = int_val; + } + return ret; +} + int __init mdss_dsi_status_init(void) { int rc = 0; @@ -196,7 +168,6 @@ int __init mdss_dsi_status_init(void) return -EPERM; } - pstatus_data->check_interval = interval; pr_info("%s: DSI status check interval:%d\n", __func__, interval); INIT_DELAYED_WORK(&pstatus_data->check_status, check_dsi_ctrl_status); @@ -214,11 +185,17 @@ void __exit mdss_dsi_status_exit(void) pr_debug("%s: DSI ctrl status work queue removed\n", __func__); } -module_param(interval, uint, 0); +module_param_call(interval, param_set_interval, param_get_uint, + &interval, 0644); MODULE_PARM_DESC(interval, "Duration in milliseconds to send BTA command for checking" "DSI status periodically"); +module_param_call(dsi_status_disable, param_dsi_status_disable, param_get_uint, + &dsi_status_disable, 0644); +MODULE_PARM_DESC(dsi_status_disable, + "Disable DSI status check"); + module_init(mdss_dsi_status_init); module_exit(mdss_dsi_status_exit); diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h index febd2537bbe..894dbbcad79 100644 --- a/drivers/video/msm/mdss/mdss_fb.h +++ b/drivers/video/msm/mdss/mdss_fb.h @@ -135,6 +135,7 @@ struct msm_mdp_interface { int (*splash_fnc) (struct msm_fb_data_type *mfd, int *index, int req); struct msm_sync_pt_data *(*get_sync_fnc)(struct msm_fb_data_type *mfd, const struct mdp_buf_sync *buf_sync); + void (*check_dsi_status)(struct work_struct *work, uint32_t interval); void *private1; }; diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c index 667e4b761e9..97d4dc90910 100644 --- a/drivers/video/msm/mdss/mdss_mdp.c +++ b/drivers/video/msm/mdss/mdss_mdp.c @@ -68,6 +68,7 @@ struct msm_mdp_interface mdp5 = { .fb_mem_get_iommu_domain = mdss_fb_mem_get_iommu_domain, .panel_register_done = mdss_panel_register_done, .fb_stride = mdss_mdp_fb_stride, + .check_dsi_status = mdss_check_dsi_ctrl_status, }; #define DEFAULT_TOTAL_RGB_PIPES 3 diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h index e528219274f..fe66e371545 100644 --- a/drivers/video/msm/mdss/mdss_mdp.h +++ b/drivers/video/msm/mdss/mdss_mdp.h @@ -692,6 +692,7 @@ int mdss_mdp_wb_ioctl_handler(struct msm_fb_data_type *mfd, u32 cmd, void *arg); int mdss_mdp_get_ctl_mixers(u32 fb_num, u32 *mixer_id); u32 mdss_mdp_fb_stride(u32 fb_index, u32 xres, int bpp); +void mdss_check_dsi_ctrl_status(struct work_struct *work, uint32_t interval); int mdss_panel_register_done(struct mdss_panel_data *pdata); int mdss_mdp_limited_lut_igc_config(struct mdss_mdp_ctl *ctl);