Runtime device power management or dynamic device power management (dpm). Why dpm: 1. put an idle device into low power state to save power 2. speed up S3/S4. In resume time, we could resume devices only as the devices are used. In suspend time, we could skip suspended devices. (suspend/resume a device equals to change device state) Basically we need device driver support, a kernel framework and a policy (determine when to change a device’s power state). I think we need answer below questions: 1. How to present device’s power info/control interface to policy. Unlike ACPI Dx state, a device’s power state might depend on several parameters, like voltage/clock. We must change several parameters in the meantime to switch device’s power state. 2. How to handle devices dependences. For example, for a PCI endpoint and a pci bridge above the pci endpoint, we should suspend pci endpoint device first and then suspend pci bridge and vice versa in resume. On the other hand, two devices might not have such relationship. Two devices might haven’t any bus relationship. Eg, in embedded system, a clock might drive several devices under different buses. 3. How to detect if a device is idle. 4. where should policy be, kernel/userspace. Userspace policy is flexible, but userspace policy has some limitations like being swapped out. The limitations don’t impact suspend device, but resume device should be quick, eg suspended device should be resumed quickly soon after new service request is coming. My proposal: 1. device’s power parameters. If a device’s power state depends on several parameters, we can map different parameters combining to a single index, which looks like ACPI Dx state. In this way, dpm framework and policy have a generic interface to get/set device’s state. Each state exports some info, including this state’s power consumption/latency. Device driver can export extra info to policy, dpm framework doesn’t handle the extra info, but policy can. 2. The device dependence varies from different systems especially for embedded system. The idea is dpm framework handles device dependence (like, resume a device’s parent before resume the device itself), and policy inputs the dependence data to dpm framework. As device dependence exists, device driver shouldn’t directly resume a device. Instead, let dpm framework resumes the device and handle dependence in the meantime. To input dependence data, policy should know device’s unique name and dpm framework can get corresponding dpm device from the name. Different buses have different device naming methods. To assign a unified name to each device, I just give each device an id regardless which bus the device is on. 3. detect if a device is idle. The idea is each device has a busy timestamp. Every time the driver wants to handle the device, driver will update the timestamp. Policy can poll the timestamp to determine if the device is idle. 4. policy position. The idea is policy resides on userspace. Dpm framework exports device’s busy timestamp, state info, dependence setting to userspace. According to the info, policy suspends a device in specific time. Resuming a device is directly done by dpm framework in kernel. So in my proposal, dpm framework will provide some APIs for device driver and export some info to userspace and a userspace policy determines when to suspend a device. Attached code is my prototype to demonstrate my idea (it even can’t be compiled). With the framework, driver/policy should do: ===================device driver========================== int foo() //all service routines of the driver should do { //wakeup the device if it’s suspended dpm_active_device(); … //do service /* if necessary, mark the device busy to not suspend the device */ dpm_mark_device_busy(); …//do service } struct dpm_driver my_driver { .init = xxx_init, //initialize the dpm device, eg. the device’s state info .get_state = xxx_get_state, //get current device’s power state .set_state = xxx_set_state, //set current device’s power state. Maybe just use .suspend/.resume here }; driver_init() { dpm_device_bind_driver(dev->dpm, &my_driver); } =================user interface====================== Dpm framework will export below sysfs info for every dpm device: ../dpm/ `id /*dpm device’s unique id*/ `state0 /*all device states’ info*/ `power `latency `stateX `power `latency `state /* get/set device state */ `busy_timestamp /* device’s busy timestamp */ `set_dependence /* interface to set device dependence */ `status /* device’s status */ ===================policy=========================== /* initialize device dependences */ Write one device’s id to other device’s set_dependence sysfs file. We consider two type devices: 1. for soundcard, policy does: a. Setup a timer, the timer polls soundcard’s busy_timestamp sysfs file. b. if the timer found soundcard is idle for a long time, write the device’s state sysfs file, and sound card to low power state. c. policy does nothing to resume soundcard. Soundcard driver’s service routine will call ’dpm_active_device’ to resume the device 2. For keyboard or mouse, policy does: a. setup a timer, the timer polls keyboard’s busy_timestamp sysfs file. b. if the timer found keyboard is idle for a long time, write LCD’s state sysfs file to close LCD. c. After LCD is closed, policy polls keyboard’s busy_timestamp sysfs file. d. if the content changed of the file (maybe using inotify), policy will open LCD ==================suspend/resume (S3/S4)===================== 1. Device suspend follows current Linux scheme, but ignore suspended device 2. in resume, don’t do device resume. Device will automatically resume on demand. No policy application involved in the process, as dpm framework will be responsible for device resume. This is my preliminary design, and I’d like to listen to your opinions. Thanks, Shaohua
Attachment:
pm.tgz
Description: application/compressed-tar
_______________________________________________ linux-pm mailing list linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/linux-pm