3. Get rid of pmf_device_register completely, and treat
suspend/resume/shutdown as event handlers.

Can you explain this variant?

Sure. All PMF callbacks that are not suspend or resume are currently
registered using pmf_event_register/deregister. From the man page:

pmf_event_register(dev, ev, handler, global)
Register the callback handler to be called whenever an ev event
is triggered. If global is true, handler accepts anonymous
events from pmf_event_inject().

So we could add PMFE_DEVICE_{SUSPEND,RESUME,SHUTDOWN} types to the
pmf_generic_event_t enum, and use pmf_event_inject to invoke shutdown
handlers for devices. pmf_event_inject is currently asynchronous, so we
will need to add a flags argument to it to make it run a handler
synchronously.