Hi.
While I've been working for suspend/resume, I've noticed that some devices
are reported "WARNING: power management not supported" in config_attach_loc()
even though the driver has pmf_device_register() in it. The reason is that
pmf_device_register is deferred by config_interrupts(). It's not a real bug,
but the above message is important for suspend/resume work. I wrote the
following patch:
Index: sys/sys/device.h
===================================================================
RCS file: /cvsroot/src/sys/sys/device.h,v
retrieving revision 1.156
diff -u -p -r1.156 device.h
--- sys/sys/device.h 18 Sep 2018 01:25:09 -0000 1.156
+++ sys/sys/device.h 29 Nov 2018 08:33:29 -0000
@@ -202,6 +202,7 @@ struct device {
#define DVF_CLASS_SUSPENDED 0x0008 /* device class suspend was called */
#define DVF_DRIVER_SUSPENDED 0x0010 /* device driver suspend was called */
#define DVF_BUS_SUSPENDED 0x0020 /* device bus suspend was called */
+#define DVF_ATTACH_INPROGRESS 0x0040 /* device attach is in progress */
#define DVF_DETACH_SHUTDOWN 0x0080 /* device detaches safely at shutdown */
#ifdef _KERNEL
Index: sys/kern/subr_autoconf.c
===================================================================
RCS file: /cvsroot/src/sys/kern/subr_autoconf.c,v
retrieving revision 1.263
diff -u -p -r1.263 subr_autoconf.c
--- sys/kern/subr_autoconf.c 18 Sep 2018 01:25:09 -0000 1.263
+++ sys/kern/subr_autoconf.c 29 Nov 2018 08:33:30 -0000
@@ -446,6 +446,10 @@ config_interrupts_thread(void *cookie)
while ((dc = TAILQ_FIRST(&interrupt_config_queue)) != NULL) {
TAILQ_REMOVE(&interrupt_config_queue, dc, dc_queue);
(*dc->dc_func)(dc->dc_dev);
+ dc->dc_dev->dv_flags &= ~DVF_ATTACH_INPROGRESS;
+ if (!device_pmf_is_registered(dc->dc_dev))
+ aprint_debug_dev(dc->dc_dev,
+ "WARNING: power management not supported\n");
config_pending_decr(dc->dc_dev);
kmem_free(dc, sizeof(*dc));
}
@@ -1597,9 +1601,10 @@ config_attach_loc(device_t parent, cfdat
(*dev->dv_cfattach->ca_attach)(parent, dev, aux);
- if (!device_pmf_is_registered(dev))
- aprint_debug_dev(dev, "WARNING: power management not "
- "supported\n");
+ if (((dev->dv_flags & DVF_ATTACH_INPROGRESS) == 0)
+ && !device_pmf_is_registered(dev))
+ aprint_debug_dev(dev,
+ "WARNING: power management not supported\n");
config_process_deferred(&deferred_config_queue, dev);
@@ -1996,6 +2001,7 @@ config_interrupts(device_t dev, void (*f
dc->dc_func = func;
TAILQ_INSERT_TAIL(&interrupt_config_queue, dc, dc_queue);
config_pending_incr(dev);
+ dev->dv_flags |= DVF_ATTACH_INPROGRESS;
}
/*
Index: sys/external/bsd/drm2/i915drm/intelfb.c
===================================================================
RCS file: /cvsroot/src/sys/external/bsd/drm2/i915drm/intelfb.c,v
retrieving revision 1.15
diff -u -p -r1.15 intelfb.c
--- sys/external/bsd/drm2/i915drm/intelfb.c 27 Aug 2018 15:09:35 -0000 1.15
+++ sys/external/bsd/drm2/i915drm/intelfb.c 29 Nov 2018 08:33:30 -0000
@@ -119,6 +119,7 @@ intelfb_attach(device_t parent, device_t
error);
goto fail1;
}
+ self->dv_flags |= DVF_ATTACH_INPROGRESS;
sc->sc_scheduled = true;
/* Success! */
@@ -177,6 +178,7 @@ intelfb_attach_task(struct i915drmkms_ta
};
int error;
+ sc->sc_dev->dv_flags &= ~DVF_ATTACH_INPROGRESS;
error = drmfb_attach(&sc->sc_drmfb, &da);
if (error) {
aprint_error_dev(sc->sc_dev, "failed to attach drmfb: %d\n",
(intelfb.c doesn't use config_interrupts)
OK?