Hi All, I've been considering strategies for improving runtime power management, selective suspends, and device power management in general. Here are some of my ideas. I would appreciate any comments or suggestions. suspend() and resume() need to be improved. =========================================== - the current logical state should be clear and available (e.g. it's difficult to determine when to resume from FREEZE or SUSPEND.) - I'm not sure what's currently in pm_message_t, but it would nice if the driver could be provided a reason for the state change request. (e.g. userspace requested this change, the system is being suspended, emergency power accounting issue, etc.) - We need to specify global system states. suspend/resume should be aware of the current global system state and the target global system state. - it should be possible to call suspend() more than once. (e.g. FREEZE followed by SUSPEND) No action should be taken if the current state is equal to the requested state. - resume should always take us back to the ON state. We need to add start() and stop() to "struct device_driver". ============================================================ start() would enable the logical functionality of the device stop() would disable the logical functionality of the device ACPI has had this feature in its driver model for a while now. It seems clear to me that the driver core should provide this functionality for the following reason: A device can either be operational or disabled. At least three different entry points are concerned with controlling this logical state. 1.) suspend/resume 2.) probe/remove 3.) driver-specific runtime power management In addition some drivers will also need to start/stop devices from the following entry points: 4.) parent change required because of child logical state changes 5.) device class requests (e.g. ifconfig eth0 down) It seems like it would be useful for the driver core to track the current logical device state. We could even create an iterative algorithm that "starts" parents up the tree when a child is started. In general, adding start() and stop() would allow us to centralize logical state transition code and simplify drivers. It should be easy for device drivers to manipulate physical power states. ========================================================================= We can use an API like the following to represent and manipulate power resources. struct pm_state { char *name; /* a human-readable name */ unsigned int state; /* an index value */ unsigned int state_type; /* a PMSTATE_TYPE */ }; enum { PMSTATE_TYPE_ON, /* functional, most current, no latency */ PMSTATE_TYPE_STANDBY, /* not functional, less current, more latency */ PMSTATE_TYPE_OFF, /* not functional, least current, most latency */ }; struct pm_device { struct kobject kobj; struct semaphore sem; /* protects power state etc. */ struct pm_interface *intf; /* specifies the type of pm device */ struct pm_device *parent; /* the power container */ struct device *dev; /* the physical device if any */ struct pm_state *state; /* the active power state */ char pm_id[PM_ID_SIZE]; /* kobject name */ void (*release) (struct device * dev); }; struct pm_interface { const char *name; /* a unique name for this PM protocol */ struct pm_attribute *pm_attrs; /* default group of attributes */ int (*enter_state) (struct pm_device *dev, struct pm_state *state); /* enters a given state */ }; extern int pm_register_device(struct pm_device *dev); extern void pm_unregister_device(struct pm_device *dev); extern struct pm_state * __pm_get_state(struct pm_device *dev); extern int __pm_set_state(struct pm_device *dev, struct pm_state *state); extern int pm_set_state(struct pm_device *dev, struct pm_state *state); extern struct pm_device * pm_get_device(struct pm_device *dev); extern void pm_put_device(struct pm_device *dev); In this case we would create objects in sysfs under a power subsystem. Devices could then symlink to these objects. PCI power management needs to be overhauled. ============================================ - pci_save_state() isn't necessary. This information is already contained in "struct pci_dev". - pci_restore_state() should be more careful and not write to read-only registers. - We may need logic to enable ASPM when using PCI express hardware. - PCI Bus power management isn't supported at all. - PCI could attach to the power object model proposed above. - PCI wake support needs to be usable for runtime power management. ACPI needs better driver model integration. =========================================== - ACPI devices have power states too. We need to show them. - ACPI power resources could be represented with the power object code. Thanks, Adam