/* * drivers/base/power/main.c - Where the driver meets power management. * * Copyright (c) 2003 Patrick Mochel * Copyright (c) 2003 Open Source Development Lab * * This file is released under the GPLv2 * * * The driver model core calls device_pm_add() when a device is registered. * This will initialize the embedded device_pm_info object in the device * and add it to the list of power-controlled devices. sysfs entries for * controlling device power management will also be added. * * A separate list is used for keeping track of power info, because the power * domain dependencies may differ from the ancestral dependencies that the * subsystem list maintains. */#include <linux/device.h>#include <linux/kallsyms.h>#include <linux/export.h>#include <linux/mutex.h>#include <linux/pm.h>#include <linux/pm_runtime.h>#include <linux/resume-trace.h>#include <linux/interrupt.h>#include <linux/sched.h>#include <linux/async.h>#include <linux/suspend.h>#include <linux/cpuidle.h>#include"../base.h"#include"power.h"typedefint(*pm_callback_t)(struct device *);/* * The entries in the dpm_list list are in a depth first order, simply * because children are guaranteed to be discovered after parents, and * are inserted at the back of the list on discovery. * * Since device_pm_add() may be called with a device lock held, * we must never try to acquire a device lock while holding * dpm_list_mutex. */LIST_HEAD(dpm_list);staticLIST_HEAD(dpm_prepared_list);staticLIST_HEAD(dpm_suspended_list);staticLIST_HEAD(dpm_late_early_list);staticLIST_HEAD(dpm_noirq_list);struct suspend_stats suspend_stats;staticDEFINE_MUTEX(dpm_list_mtx);static pm_message_t pm_transition;static int async_error;/** * device_pm_sleep_init - Initialize system suspend-related device fields. * @dev: Device object being initialized. */voiddevice_pm_sleep_init(struct device *dev){
dev->power.is_prepared =false;
dev->power.is_suspended =false;init_completion(&dev->power.completion);complete_all(&dev->power.completion);
dev->power.wakeup = NULL;INIT_LIST_HEAD(&dev->power.entry);}/** * device_pm_lock - Lock the list of active devices used by the PM core. */voiddevice_pm_lock(void){mutex_lock(&dpm_list_mtx);}/** * device_pm_unlock - Unlock the list of active devices used by the PM core. */voiddevice_pm_unlock(void){mutex_unlock(&dpm_list_mtx);}/** * device_pm_add - Add a device to the PM core's list of active devices. * @dev: Device to add to the list. */voiddevice_pm_add(struct device *dev){pr_debug("PM: Adding info for%s:%s\n",
dev->bus ? dev->bus->name :"No Bus"