NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/49645: radeon pmf hooks
>Number: 49645
>Category: kern
>Synopsis: radeon pmf hooks
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: kern-bug-people
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Thu Feb 05 18:15:00 +0000 2015
>Originator: Arto Huusko
>Release: 7.99.4
>Organization:
>Environment:
7.99.4 amd64 GENERIC
>Description:
The radeon kms driver does not support suspend/resume.
>How-To-Repeat:
sysctl -w hw.acpi.sleep.state=3
...
the following drivers do not support: radeon
...
>Fix:
The following patch worked for me with vendor 1002, product 9612, or
drm: initializing kernel modesetting (RS780 0x1002:0x9612 0x1025:0x0148)
Did not try with X11 yet, but suspend/resume worked from console.
--- sys/external/bsd/drm2/radeon/radeon_pci.c
+++ sys/external/bsd/drm2/radeon/radeon_pci.c
@@ -100,6 +100,9 @@ static void radeon_attach(device_t, device_t, void *);
static void radeon_attach_real(device_t);
static int radeon_detach(device_t, int);
+static bool radeon_pmf_suspend(device_t, const pmf_qual_t *);
+static bool radeon_pmf_resume(device_t, const pmf_qual_t *);
+
static void radeon_task_work(struct work *, void *);
CFATTACH_DECL_NEW(radeon, sizeof(struct radeon_softc),
@@ -157,6 +160,9 @@ radeon_attach(device_t parent, device_t self, void *aux)
pci_aprint_devinfo(pa, NULL);
+ if (!pmf_device_register(self, &radeon_pmf_suspend, &radeon_pmf_resume))
+ aprint_error_dev(self, "unable to establish power handler\n");
+
/*
* Trivial initialization first; the rest will come after we
* have mounted the root file system and can load firmware
@@ -228,14 +234,14 @@ radeon_detach(device_t self, int flags)
return error;
if (sc->sc_task_state == RADEON_TASK_ATTACH)
- return 0;
+ goto out;
if (sc->sc_task_u.workqueue != NULL) {
workqueue_destroy(sc->sc_task_u.workqueue);
sc->sc_task_u.workqueue = NULL;
}
if (sc->sc_drm_dev == NULL)
- return 0;
+ goto out;
/* XXX errno Linux->NetBSD */
error = -drm_pci_detach(sc->sc_drm_dev, flags);
if (error)
@@ -243,9 +249,45 @@ radeon_detach(device_t self, int flags)
return error;
sc->sc_drm_dev = NULL;
+out: pmf_device_deregister(self);
+
return 0;
}
+static bool
+radeon_pmf_suspend(device_t self, const pmf_qual_t *qual)
+{
+ struct radeon_softc *const sc = device_private(self);
+ struct drm_device *const dev = sc->sc_drm_dev;
+ int ret;
+
+ if (dev == NULL)
+ return true;
+
+ ret = radeon_suspend_kms(dev, true, true);
+ if (ret)
+ return false;
+
+ return true;
+}
+
+static bool
+radeon_pmf_resume(device_t self, const pmf_qual_t *qual)
+{
+ struct radeon_softc *const sc = device_private(self);
+ struct drm_device *const dev = sc->sc_drm_dev;
+ int ret;
+
+ if (dev == NULL)
+ return true;
+
+ ret = radeon_resume_kms(dev, false, true);
+ if (ret)
+ return false;
+
+ return true;
+}
+
static void
radeon_task_work(struct work *work, void *cookie __unused)
{
Home |
Main Index |
Thread Index |
Old Index