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. |
|