diff options
Diffstat (limited to 'drivers/gpu/drm/arm/hdlcd_drv.c')
-rw-r--r-- | drivers/gpu/drm/arm/hdlcd_drv.c | 68 |
1 files changed, 29 insertions, 39 deletions
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index b987c63ba8d6..a6ca36f0096f 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c @@ -49,8 +49,6 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags) atomic_set(&hdlcd->dma_end_count, 0); #endif - INIT_LIST_HEAD(&hdlcd->event_list); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hdlcd->mmio = devm_ioremap_resource(drm->dev, res); if (IS_ERR(hdlcd->mmio)) { @@ -84,11 +82,7 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags) goto setup_fail; } - pm_runtime_enable(drm->dev); - - pm_runtime_get_sync(drm->dev); ret = drm_irq_install(drm, platform_get_irq(pdev, 0)); - pm_runtime_put_sync(drm->dev); if (ret < 0) { DRM_ERROR("failed to install IRQ handler\n"); goto irq_fail; @@ -164,24 +158,9 @@ static irqreturn_t hdlcd_irq(int irq, void *arg) atomic_inc(&hdlcd->vsync_count); #endif - if (irq_status & HDLCD_INTERRUPT_VSYNC) { - bool events_sent = false; - unsigned long flags; - struct drm_pending_vblank_event *e, *t; - + if (irq_status & HDLCD_INTERRUPT_VSYNC) drm_crtc_handle_vblank(&hdlcd->crtc); - spin_lock_irqsave(&drm->event_lock, flags); - list_for_each_entry_safe(e, t, &hdlcd->event_list, base.link) { - list_del(&e->base.link); - drm_crtc_send_vblank_event(&hdlcd->crtc, e); - events_sent = true; - } - if (events_sent) - drm_crtc_vblank_put(&hdlcd->crtc); - spin_unlock_irqrestore(&drm->event_lock, flags); - } - /* acknowledge interrupt(s) */ hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status); @@ -275,6 +254,7 @@ static int hdlcd_show_pxlclock(struct seq_file *m, void *arg) static struct drm_info_list hdlcd_debugfs_list[] = { { "interrupt_count", hdlcd_show_underrun_count, 0 }, { "clocks", hdlcd_show_pxlclock, 0 }, + { "fb", drm_fb_cma_debugfs_show, 0 }, }; static int hdlcd_debugfs_init(struct drm_minor *minor) @@ -357,6 +337,8 @@ static int hdlcd_drm_bind(struct device *dev) return -ENOMEM; drm->dev_private = hdlcd; + dev_set_drvdata(dev, drm); + hdlcd_setup_mode_config(drm); ret = hdlcd_load(drm, 0); if (ret) @@ -366,14 +348,18 @@ static int hdlcd_drm_bind(struct device *dev) if (ret) goto err_unload; - dev_set_drvdata(dev, drm); - ret = component_bind_all(dev, drm); if (ret) { DRM_ERROR("Failed to bind all components\n"); goto err_unregister; } + ret = pm_runtime_set_active(dev); + if (ret) + goto err_pm_active; + + pm_runtime_enable(dev); + ret = drm_vblank_init(drm, drm->mode_config.num_crtc); if (ret < 0) { DRM_ERROR("failed to initialise vblank\n"); @@ -399,16 +385,16 @@ err_fbdev: drm_mode_config_cleanup(drm); drm_vblank_cleanup(drm); err_vblank: + pm_runtime_disable(drm->dev); +err_pm_active: component_unbind_all(dev, drm); err_unregister: drm_dev_unregister(drm); err_unload: - pm_runtime_get_sync(drm->dev); drm_irq_uninstall(drm); - pm_runtime_put_sync(drm->dev); - pm_runtime_disable(drm->dev); of_reserved_mem_device_release(drm->dev); err_free: + dev_set_drvdata(dev, NULL); drm_dev_unref(drm); return ret; @@ -495,30 +481,34 @@ MODULE_DEVICE_TABLE(of, hdlcd_of_match); static int __maybe_unused hdlcd_pm_suspend(struct device *dev) { struct drm_device *drm = dev_get_drvdata(dev); - struct drm_crtc *crtc; + struct hdlcd_drm_private *hdlcd = drm ? drm->dev_private : NULL; - if (pm_runtime_suspended(dev)) + if (!hdlcd) return 0; - drm_modeset_lock_all(drm); - list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) - hdlcd_crtc_suspend(crtc); - drm_modeset_unlock_all(drm); + drm_kms_helper_poll_disable(drm); + + hdlcd->state = drm_atomic_helper_suspend(drm); + if (IS_ERR(hdlcd->state)) { + drm_kms_helper_poll_enable(drm); + return PTR_ERR(hdlcd->state); + } + return 0; } static int __maybe_unused hdlcd_pm_resume(struct device *dev) { struct drm_device *drm = dev_get_drvdata(dev); - struct drm_crtc *crtc; + struct hdlcd_drm_private *hdlcd = drm ? drm->dev_private : NULL; - if (!pm_runtime_suspended(dev)) + if (!hdlcd) return 0; - drm_modeset_lock_all(drm); - list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) - hdlcd_crtc_resume(crtc); - drm_modeset_unlock_all(drm); + drm_atomic_helper_resume(drm, hdlcd->state); + drm_kms_helper_poll_enable(drm); + pm_runtime_set_active(dev); + return 0; } |