summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/sti
diff options
context:
space:
mode:
authorbenjamin.gaignard@linaro.org <benjamin.gaignard@linaro.org>2016-01-07 14:30:37 +0100
committerVincent Abriou <vincent.abriou@st.com>2016-02-26 10:03:55 +0100
commit20c476010d19758e98edf0bf9192121636f910dc (patch)
tree7862c887aaa1b1e6be5891aa3625607edd766817 /drivers/gpu/drm/sti
parent44ab4042178bd596275927ea050980aa4257581b (diff)
drm/sti: fix potential crash in gdp
In some cases last_close() could be called before sti_gdp_disable() and make kernel crash because mixer structure has been destroy. Let's gdp keep a reference on vtg to fix that (like it is already done in HQVDP) Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org> Reviewed-by: Vincent Abriou <vincent.abriou@st.com>
Diffstat (limited to 'drivers/gpu/drm/sti')
-rw-r--r--drivers/gpu/drm/sti/sti_gdp.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/drivers/gpu/drm/sti/sti_gdp.c b/drivers/gpu/drm/sti/sti_gdp.c
index f9a1d92c9d95..990b28ee3eac 100644
--- a/drivers/gpu/drm/sti/sti_gdp.c
+++ b/drivers/gpu/drm/sti/sti_gdp.c
@@ -97,6 +97,7 @@ struct sti_gdp_node_list {
* @vtg_field_nb: callback for VTG FIELD (top or bottom) notification
* @is_curr_top: true if the current node processed is the top field
* @node_list: array of node list
+ * @vtg: registered vtg
*/
struct sti_gdp {
struct sti_plane plane;
@@ -108,6 +109,7 @@ struct sti_gdp {
struct notifier_block vtg_field_nb;
bool is_curr_top;
struct sti_gdp_node_list node_list[GDP_NODE_NB_BANK];
+ struct sti_vtg *vtg;
};
#define to_sti_gdp(x) container_of(x, struct sti_gdp, plane)
@@ -240,9 +242,6 @@ end:
*/
static void sti_gdp_disable(struct sti_gdp *gdp)
{
- struct drm_plane *drm_plane = &gdp->plane.drm_plane;
- struct sti_mixer *mixer = to_sti_mixer(drm_plane->crtc);
- struct sti_compositor *compo = dev_get_drvdata(gdp->dev);
unsigned int i;
DRM_DEBUG_DRIVER("%s\n", sti_plane_to_str(&gdp->plane));
@@ -253,8 +252,7 @@ static void sti_gdp_disable(struct sti_gdp *gdp)
gdp->node_list[i].btm_field->gam_gdp_ppt |= GAM_GDP_PPT_IGNORE;
}
- if (sti_vtg_unregister_client(mixer->id == STI_MIXER_MAIN ?
- compo->vtg_main : compo->vtg_aux, &gdp->vtg_field_nb))
+ if (sti_vtg_unregister_client(gdp->vtg, &gdp->vtg_field_nb))
DRM_DEBUG_DRIVER("Warning: cannot unregister VTG notifier\n");
if (gdp->clk_pix)
@@ -490,7 +488,10 @@ static void sti_gdp_atomic_update(struct drm_plane *drm_plane,
if (first_prepare) {
/* Register gdp callback */
- if (sti_vtg_register_client(mixer->id == STI_MIXER_MAIN ?
+ gdp->vtg = mixer->id == STI_MIXER_MAIN ?
+ compo->vtg_main : compo->vtg_aux;
+
+ if (sti_vtg_register_client(gdp->vtg == STI_MIXER_MAIN ?
compo->vtg_main : compo->vtg_aux,
&gdp->vtg_field_nb, crtc)) {
DRM_ERROR("Cannot register VTG notifier\n");