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) ...@@ -16,6 +16,20 @@ static int udl_driver_set_busid(struct drm_device *d, struct drm_master *m)
return 0; 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 = { static const struct vm_operations_struct udl_gem_vm_ops = {
.fault = udl_gem_fault, .fault = udl_gem_fault,
.open = drm_gem_vm_open, .open = drm_gem_vm_open,
...@@ -122,6 +136,8 @@ static struct usb_driver udl_driver = { ...@@ -122,6 +136,8 @@ static struct usb_driver udl_driver = {
.name = "udl", .name = "udl",
.probe = udl_usb_probe, .probe = udl_usb_probe,
.disconnect = udl_usb_disconnect, .disconnect = udl_usb_disconnect,
.suspend = udl_usb_suspend,
.resume = udl_usb_resume,
.id_table = id_table, .id_table = id_table,
}; };
module_usb_driver(udl_driver); module_usb_driver(udl_driver);
......
...@@ -52,6 +52,7 @@ struct udl_device { ...@@ -52,6 +52,7 @@ struct udl_device {
struct device *dev; struct device *dev;
struct drm_device *ddev; struct drm_device *ddev;
struct usb_device *udev; struct usb_device *udev;
struct drm_crtc *crtc;
int sku_pixel_limit; int sku_pixel_limit;
...@@ -87,6 +88,7 @@ struct udl_framebuffer { ...@@ -87,6 +88,7 @@ struct udl_framebuffer {
/* modeset */ /* modeset */
int udl_modeset_init(struct drm_device *dev); int udl_modeset_init(struct drm_device *dev);
void udl_modeset_restore(struct drm_device *dev);
void udl_modeset_cleanup(struct drm_device *dev); void udl_modeset_cleanup(struct drm_device *dev);
int udl_connector_init(struct drm_device *dev, struct drm_encoder *encoder); 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, ...@@ -309,6 +309,8 @@ static int udl_crtc_mode_set(struct drm_crtc *crtc,
char *wrptr; char *wrptr;
int color_depth = 0; int color_depth = 0;
udl->crtc = crtc;
buf = (char *)udl->mode_buf; buf = (char *)udl->mode_buf;
/* for now we just clip 24 -> 16 - if we fix that fix this */ /* 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) ...@@ -450,6 +452,18 @@ int udl_modeset_init(struct drm_device *dev)
return 0; 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) void udl_modeset_cleanup(struct drm_device *dev)
{ {
drm_mode_config_cleanup(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