drm/udl: implement usb_driver suspend/resume.
The usb_driver suspend and resume function pointers must be populated to prevent forced unbinding of USB interface driver. See usb/core/driver.c: unbind_no_pm_drivers_interfaces(). Restore mode and damage the entire frame buffer upon resume. TEST=suspend and resume with the same UDL device connected TEST=suspend with UDL, unplug UDL and resume TEST=suspend with UDL, unplug and connect another UDL device then resume Signed-off-by: Haixia Shi <hshi@chromium.org> Reviewed-by: Stéphane Marchesin <marcheu@chromium.org> [seanpaul fixed checkpatch warnings and gave marcheu his é back] Signed-off-by: Sean Paul <seanpaul@chromium.org> Link: http://patchwork.freedesktop.org/patch/msgid/1472593821-38429-2-git-send-email-hshi@chromium.org
This commit is contained in:
parent
ae0119f5f7
commit
737ba10928
|
@ -16,6 +16,20 @@ static int udl_driver_set_busid(struct drm_device *d, struct drm_master *m)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int udl_usb_suspend(struct usb_interface *interface,
|
||||
pm_message_t message)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int udl_usb_resume(struct usb_interface *interface)
|
||||
{
|
||||
struct drm_device *dev = usb_get_intfdata(interface);
|
||||
|
||||
udl_modeset_restore(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct vm_operations_struct udl_gem_vm_ops = {
|
||||
.fault = udl_gem_fault,
|
||||
.open = drm_gem_vm_open,
|
||||
|
@ -122,6 +136,8 @@ static struct usb_driver udl_driver = {
|
|||
.name = "udl",
|
||||
.probe = udl_usb_probe,
|
||||
.disconnect = udl_usb_disconnect,
|
||||
.suspend = udl_usb_suspend,
|
||||
.resume = udl_usb_resume,
|
||||
.id_table = id_table,
|
||||
};
|
||||
module_usb_driver(udl_driver);
|
||||
|
|
|
@ -52,6 +52,7 @@ struct udl_device {
|
|||
struct device *dev;
|
||||
struct drm_device *ddev;
|
||||
struct usb_device *udev;
|
||||
struct drm_crtc *crtc;
|
||||
|
||||
int sku_pixel_limit;
|
||||
|
||||
|
@ -87,6 +88,7 @@ struct udl_framebuffer {
|
|||
|
||||
/* modeset */
|
||||
int udl_modeset_init(struct drm_device *dev);
|
||||
void udl_modeset_restore(struct drm_device *dev);
|
||||
void udl_modeset_cleanup(struct drm_device *dev);
|
||||
int udl_connector_init(struct drm_device *dev, struct drm_encoder *encoder);
|
||||
|
||||
|
|
|
@ -309,6 +309,8 @@ static int udl_crtc_mode_set(struct drm_crtc *crtc,
|
|||
char *wrptr;
|
||||
int color_depth = 0;
|
||||
|
||||
udl->crtc = crtc;
|
||||
|
||||
buf = (char *)udl->mode_buf;
|
||||
|
||||
/* for now we just clip 24 -> 16 - if we fix that fix this */
|
||||
|
@ -450,6 +452,18 @@ int udl_modeset_init(struct drm_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void udl_modeset_restore(struct drm_device *dev)
|
||||
{
|
||||
struct udl_device *udl = dev->dev_private;
|
||||
struct udl_framebuffer *ufb;
|
||||
|
||||
if (!udl->crtc || !udl->crtc->primary->fb)
|
||||
return;
|
||||
udl_crtc_commit(udl->crtc);
|
||||
ufb = to_udl_fb(udl->crtc->primary->fb);
|
||||
udl_handle_damage(ufb, 0, 0, ufb->base.width, ufb->base.height);
|
||||
}
|
||||
|
||||
void udl_modeset_cleanup(struct drm_device *dev)
|
||||
{
|
||||
drm_mode_config_cleanup(dev);
|
||||
|
|
Loading…
Reference in New Issue