diff --git a/msm/msm_drv.c b/msm/msm_drv.c index 7025d9d84f1f..4fa5943cae3e 100644 --- a/msm/msm_drv.c +++ b/msm/msm_drv.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "msm_drv.h" #include "msm_kms.h" @@ -379,6 +380,11 @@ static int msm_drm_uninit(struct device *dev) priv->registered = false; } + if (priv->msm_drv_notifier.notifier_call) { + unregister_reboot_notifier(&priv->msm_drv_notifier); + priv->msm_drv_notifier.notifier_call = NULL; + } + #ifdef CONFIG_DRM_FBDEV_EMULATION if (fbdev && priv->fbdev) msm_fbdev_free(ddev); @@ -697,6 +703,23 @@ static struct msm_kms *_msm_drm_init_helper(struct msm_drm_private *priv, return kms; } +static void msm_pdev_shutdown(struct platform_device *pdev); +static int msm_drv_shutdown_notifier_cb(struct notifier_block *nb, + unsigned long event, void *unused) +{ + struct device *dev; + struct platform_device *pdev; + struct msm_drm_private *priv = container_of(nb, struct msm_drm_private, + msm_drv_notifier); + + dev = priv->dev->dev; + pdev = to_platform_device(dev); + dev_warn(dev, "prepare to shutdown\n"); + msm_pdev_shutdown(pdev); + + return NOTIFY_DONE; +} + static int msm_drm_init(struct device *dev, struct drm_driver *drv) { struct platform_device *pdev = to_platform_device(dev); @@ -827,6 +850,16 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) drm_kms_helper_poll_init(ddev); + priv->msm_drv_notifier.notifier_call = msm_drv_shutdown_notifier_cb; + priv->msm_drv_notifier.next = NULL; + priv->msm_drv_notifier.priority = 1; + ret = register_reboot_notifier(&priv->msm_drv_notifier); + if (ret) { + dev_err(dev, "Failed to register for reboot_notifier. ret = %d\n", + ret); + goto fail; + } + return 0; fail: diff --git a/msm/msm_drv.h b/msm/msm_drv.h index d3acbfe4536c..cc0fc3754081 100644 --- a/msm/msm_drv.h +++ b/msm/msm_drv.h @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -731,6 +732,8 @@ struct msm_drm_private { /* update the flag when msm driver receives shutdown notification */ bool shutdown_in_progress; + + struct notifier_block msm_drv_notifier; }; /* get struct msm_kms * from drm_device * */