A cpuidle_driver structure represents a cpuidle driver likeacpi_idle, intel_idle providing low level idle routines.A cpuidle_driver is global in nature as it provides routinesfor all the CPUS. Each CPU registered with the cpuidle subsystem isrepresented as a cpuidle_device. A cpuidle_device structurepoints to the low level idle routines for that CPU provided bya certain driver. In other words, a cpuidle driver creates acpuidle_device structure for each CPU that it registers with thecpuidle subsystem. Whenever cpuidle idle loop is called, the cpuidlesubsystem picks the cpuidle_device structure for that cpu andcalls one of the low level idle routines through that structure.

In the current design, only one cpuidle_driver may be registeredand registration of any subsequent driver fails. The same registereddriver provides low level idle routines for each cpuidle_device.

A list based registration for cpuidle_driver provides a cleanmechanism for multiple subsystems/modules to register their own idleroutines and thus avoids using pm_idle.

This patch implements a list based registration for cpuidledriver. Different drivers can be registered and the driver tobe used is selected based on a per driver priority. On acpuidle driver registration or unregistration cpuidle_devicestructure for each CPU is changed. Each cpuidle_device pointsto its driver to facilitate this registration and unregistration.

+ if (dev->registered)+ return 0; if (!sys_dev) return -EINVAL;- if (!try_module_get(cpuidle_driver->owner))+ /*+ * This will maintain compatibility with old cpuidle_device+ * structure where driver pointer is not set.+ *+ * To Do: Change all call sites to set dev->drv pointer.+ * This can be changed to BUG() later in case somebody+ * registers without a driver pointer.+ */+ if (!dev->drv)+ dev->drv = cpuidle_driver;+ if (!try_module_get(dev->drv->owner)) return -EINVAL;