Commit 737ba109 authored by Haixia Shi's avatar Haixia Shi Committed by Sean Paul

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: default avatarHaixia Shi <hshi@chromium.org>
Reviewed-by: default avatarStéphane Marchesin <marcheu@chromium.org>
[seanpaul fixed checkpatch warnings and gave marcheu his é back]
Signed-off-by: default avatarSean Paul <seanpaul@chromium.org>
Link: http://patchwork.freedesktop.org/patch/msgid/1472593821-38429-2-git-send-email-hshi@chromium.org
parent ae0119f5
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment