Date
1 - 3 of 3
RFC [2/3] - SoC, CPU LPS, Tickless idle and Device power management
Thomas, Ramesh
***These are implemented and under review***
https://gerrit.zephyrproject.org/r/#/c/532/ https://gerrit.zephyrproject.org/r/#/c/528/ https://gerrit.zephyrproject.org/r/#/c/525/ Device driver power management hook infrastructure ------------------------------------------------------ When the _sys_soc_suspend() and _sys_soc_resume() hook functions are called, the PM service app may want to do some device specific operations. Zephyr kernel provides this infrastructure to enable device drivers to define suspend and resume hook functions that can be called by the PM service app. Following are the goals for providing this infrastructure: 1. A framework for drivers to implement generic suspend/resume hook functions. 2. Provide means for PM app service to call the suspend and resume functions of all devices in the system. This is necessary especially to do suspend and resume operations on system devices like the APIC device which do not export device binding interface. 3. Since not all devices need to implement suspend and resume hook functions, provide a no-op function by default for such devices. By default all devices would be setup with the no-op function for their hooks. The device drivers who need specific handling would assign the addresses of the functions they implement to these hooks during initialization. Non-goals: The implementation of the hook functions by the device drivers is up to each driver, the integrator and the system power management policies. All device power management infrastructure implementations is enclosed inside CONFIG_DEVICE_POWER flag. The hook functions for the PM service app: a) int device_suspend(struct device *port) param port: Device structure of the driver instance return: DEV_OK for success, error code otherwise Details - calls the suspend hook of the device associated with the device structure parameter. b) int device_resume(struct device *port) param port: Device structure of the driver instance return: DEV_OK for success, error code otherwise Details - calls the resume hook of the device associated with the device structure parameter. c) void device_suspend_all(bool system_devices) param system_devices Boolean true for only the system devices; else all devices Details: Kernel holds a list of all devices in the system. This function will iterate through that list and call the suspend hook function of each device in the list. It will do this in the reverse order in which the devices were initialized. If the <system_devices> parameter is false then it would call all devices. If it is true then it would call the suspend/resume of only system devices. This parameter is provided because it is mandatory for the PM service app to call this function for system devices. This is because it cannot bind to them and call their suspend/resume functions directly. For non-system devices, the PM service app can bind to thm and has the flexibility to call whichever device it requires to call and in the order it chooses to. If it chooses to call the suspend/resume functions of non-system devices individually, then it would call this function passing true for the <system_devices> parameter. d) void device_resume_all(bool system_devices) param system_devices Boolean true for only the system devices; else all devices Details: The description is same as for device_suspend_all() except, this would call the resume hook functions of devices and they would be called in the same order as the devices were initialized. API for device drivers: Structure storing the hook functions. This structure is stored in the device's "device" structure. struct device_power_ops { device_op_t suspend; device_op_t resume; } The NO-OP function: int device_pm_noop(struct device *unused) return - always returns DEV_OK. Details: No-op function that does nothing and returns DEV_OK immediately. This can be used to initialize hooks for which the device has no operation to do. The hooks inside device_power_ops structure are by default initialized with this function by the kernel. Device drivers which have specific operations for the hooks would overwrite with a suspend and resume functions during driver initialization. a) void device_power_ops_configure(struct device *port, device_op_t suspend_fn, device_op_t resume_fn) param port - device structure of driver instance param suspend_fn - Address of suspend function param resume_fn - Address of resume function Details: Initializes the hook functions in device_power_ops with the functions passed as parameters. This function should be called by devices during the time of initialization if they have a specific suspend or resume function implementation. Drivers can also pass the no-op function as parameter for any of the hooks it does not have an operation. If it does not have any operation for both suspend and resume then it need not call this function at all. This is because the hooks for the devices are by default initialized with the no-op function by the kernel.
|
|
Dirk Brandewie <dirk.j.brandewie@...>
On 02/29/2016 01:59 AM, Thomas, Ramesh wrote:
***These are implemented and under review***There is a basic disconnects between my original RFC and this one. In mine all drivers are required to provide an implementation of suspend/resume even if it is null. All the information for the system to interact with the driver is contained in the device structure. The new version of DEVICE_INIT() is there to keep everything compiling while *all* the drivers are updated to satisfy the requirement to support suspend/resume. Once that is done DEVICE_INIT_PM() turns into DEVICE_INIT() with a tree wide sed script. Moving *all* the drivers will be moderately painful but now is the right time to do it before we get a bunch more drivers added to the tree. To be honest if I had thought about it more when I was defining the device model we would no be here :-( --Dirk Following are the goals for providing this infrastructure:
|
|
Thomas, Ramesh
On Tue, 2016-03-01 at 11:03 -0800, Dirk Brandewie wrote:
On 02/29/2016 01:59 AM, Thomas, Ramesh wrote:device***These are implemented and under review*** calleddrivers to define suspend and resume hook functions that can be In this RFC I tried to keep the main ideas and feedbacks from theby the PM service app.There is a basic disconnects between my original RFC and this one. original RFCs but made some modifications as I encountered issues during implementation. These should not impact the general goals of the changes. Listed below are the differences which can be reviewed again if necessary. Way device_ops structure gets initialized changed. 1. (Original RFC) Modify DEVICE_INIT call of all drivers in the system and add a suspend_fn and resume_fn parameter to it. The macro would statically create the device_ops structure and initialize it with the passed suspend_fn and resume_fn. Caller of DEVICE_INIT can pass the address of a "null" function if they do not have any operation for either suspend or resume. 2. (This RFC) DEVICE_INIT() macro would create the device_ops structure same as option #1 but would by default initialize it with no-op functions for suspend and resume. So this DEVICE_INIT macro API params need not be changed. Drivers which need any operation for suspend/resume, would at run time, update the device_ops with their suspend/resume function using device_power_ops_configure(suspend_fn, resume_fn). The "null" function referred to in #1 is same as the "no-op" function in #2 except for the name change. I picked #2 for the implementation because of the following reasons. 1. No need to modify DEVICE_INIT macros of all drivers (I greped 75+) 2. Scalable because if device_ops needs to be modified later to include more ops, remove ops or add other fields, then we do not need to modify all drivers calling DEVICE_INIT() (I figured this only when I was about to modify the drivers and missed it during original RFC discussion) Let us review the above options and do whatever is appropriate. I have no problem switching to any of them. Also please review the other change from the original RFC - device_suspend_all/device_resume_all now takes a parameter system_devices. This gives an option to use this function only for system devices if the PM app choses to call other devices suspend/resume directly. Let us review that also and if the parameter is not required then we can remove it. To be honest if I had thought about it more when I was definingto devicedo suspend and resume operations on system devices like the APIC thewhich do not export device binding interface. toaddresses of the functions they implement to these hooks during policies.each driver, the integrator and the system power management enclosed deviceinside CONFIG_DEVICE_POWER flag. willstructure parameter. theiterate through that list and call the suspend hook function of each fordevices were initialized. functionsthe PM service app to call this function for system devices. This is thmdirectly. For non-system devices, the PM service app can bind to andand has the flexibility to call whichever device it requires to call thisin the order it chooses to. If it chooses to call the suspend/resume wouldfunction passing true for the <system_devices> parameter. incall the resume hook functions of devices and they would be called thethe same order as the devices were initialized. Thisdevice's "device" structure. operation to do.can be used to initialize hooks for which the device has no initialized specificwith this function by the kernel. Device drivers which have functionsoperations for the hooks would overwrite with a suspend and resume duringpassed as parameters. This function should be called by devices asthe time of initialization if they have a specific suspend or resume notparameter for any of the hooks it does not have an operation. If it arecall this function at all. This is because the hooks for the devices by default initialized with the no-op function by the kernel.
|
|