⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 suspend.c

📁 h内核
💻 C
字号:
/* * suspend.c - Functions for putting devices to sleep. * * Copyright (c) 2003 Patrick Mochel * Copyright (c) 2003 Open Source Development Labs * * This file is released under the GPLv2 * */#include <linux/device.h>#include "power.h"extern int sysdev_suspend(pm_message_t state);/* * The entries in the dpm_active 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. * * All list on the suspend path are done in reverse order, so we operate * on the leaves of the device tree (or forests, depending on how you want * to look at it ;) first. As nodes are removed from the back of the list, * they are inserted into the front of their destintation lists. * * Things are the reverse on the resume path - iterations are done in * forward order, and nodes are inserted at the back of their destination * lists. This way, the ancestors will be accessed before their descendents. *//** *	suspend_device - Save state of one device. *	@dev:	Device. *	@state:	Power state device is entering. */int suspend_device(struct device * dev, pm_message_t state){	int error = 0;	dev_dbg(dev, "suspending\n");	dev->power.prev_state = dev->power.power_state;	if (dev->bus && dev->bus->suspend && !dev->power.power_state)		error = dev->bus->suspend(dev, state);	return error;}/** *	device_suspend - Save state and stop all devices in system. *	@state:		Power state to put each device in. * *	Walk the dpm_active list, call ->suspend() for each device, and move *	it to dpm_off. *	Check the return value for each. If it returns 0, then we move the *	the device to the dpm_off list. If it returns -EAGAIN, we move it to *	the dpm_off_irq list. If we get a different error, try and back out. * *	If we hit a failure with any of the devices, call device_resume() *	above to bring the suspended devices back to life. * */int device_suspend(pm_message_t state){	int error = 0;	down(&dpm_sem);	down(&dpm_list_sem);	while (!list_empty(&dpm_active) && error == 0) {		struct list_head * entry = dpm_active.prev;		struct device * dev = to_device(entry);		get_device(dev);		up(&dpm_list_sem);		error = suspend_device(dev, state);		down(&dpm_list_sem);		/* Check if the device got removed */		if (!list_empty(&dev->power.entry)) {			/* Move it to the dpm_off or dpm_off_irq list */			if (!error) {				list_del(&dev->power.entry);				list_add(&dev->power.entry, &dpm_off);			} else if (error == -EAGAIN) {				list_del(&dev->power.entry);				list_add(&dev->power.entry, &dpm_off_irq);				error = 0;			}		}		if (error)			printk(KERN_ERR "Could not suspend device %s: "				"error %d\n", kobject_name(&dev->kobj), error);		put_device(dev);	}	up(&dpm_list_sem);	if (error)		dpm_resume();	up(&dpm_sem);	return error;}EXPORT_SYMBOL_GPL(device_suspend);/** *	device_power_down - Shut down special devices. *	@state:		Power state to enter. * *	Walk the dpm_off_irq list, calling ->power_down() for each device that *	couldn't power down the device with interrupts enabled. When we're *	done, power down system devices. */int device_power_down(pm_message_t state){	int error = 0;	struct device * dev;	list_for_each_entry_reverse(dev, &dpm_off_irq, power.entry) {		if ((error = suspend_device(dev, state)))			break;	}	if (error)		goto Error;	if ((error = sysdev_suspend(state)))		goto Error; Done:	return error; Error:	dpm_power_up();	goto Done;}EXPORT_SYMBOL_GPL(device_power_down);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -