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

📄 power.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		ret = acpi_power_off_device(dev->wakeup.resources.handles[i], dev);		if (ret) {			printk(KERN_ERR PREFIX "Transition power state\n");			dev->wakeup.flags.valid = 0;			return -1;		}	}	return ret;}/* --------------------------------------------------------------------------                             Device Power Management   -------------------------------------------------------------------------- */int acpi_power_get_inferred_state(struct acpi_device *device){	int result = 0;	struct acpi_handle_list *list = NULL;	int list_state = 0;	int i = 0;	if (!device)		return -EINVAL;	device->power.state = ACPI_STATE_UNKNOWN;	/*	 * We know a device's inferred power state when all the resources	 * required for a given D-state are 'on'.	 */	for (i = ACPI_STATE_D0; i < ACPI_STATE_D3; i++) {		list = &device->power.states[i].resources;		if (list->count < 1)			continue;		result = acpi_power_get_list_state(list, &list_state);		if (result)			return result;		if (list_state == ACPI_POWER_RESOURCE_STATE_ON) {			device->power.state = i;			return 0;		}	}	device->power.state = ACPI_STATE_D3;	return 0;}int acpi_power_transition(struct acpi_device *device, int state){	int result = 0;	struct acpi_handle_list *cl = NULL;	/* Current Resources */	struct acpi_handle_list *tl = NULL;	/* Target Resources */	int i = 0;	if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))		return -EINVAL;	if ((device->power.state < ACPI_STATE_D0)	    || (device->power.state > ACPI_STATE_D3))		return -ENODEV;	cl = &device->power.states[device->power.state].resources;	tl = &device->power.states[state].resources;	if (!cl->count && !tl->count) {		result = -ENODEV;		goto end;	}	/* TBD: Resources must be ordered. */	/*	 * First we reference all power resources required in the target list	 * (e.g. so the device doesn't lose power while transitioning).	 */	for (i = 0; i < tl->count; i++) {		result = acpi_power_on(tl->handles[i], device);		if (result)			goto end;	}	if (device->power.state == state) {		goto end;	}	/*	 * Then we dereference all power resources used in the current list.	 */	for (i = 0; i < cl->count; i++) {		result = acpi_power_off_device(cl->handles[i], device);		if (result)			goto end;	}     end:	if (result) {		device->power.state = ACPI_STATE_UNKNOWN;		printk(KERN_WARNING PREFIX "Transitioning device [%s] to D%d\n",			      device->pnp.bus_id, state);	} else {	/* We shouldn't change the state till all above operations succeed */		device->power.state = state;	}	return result;}/* --------------------------------------------------------------------------                              FS Interface (/proc)   -------------------------------------------------------------------------- */static struct proc_dir_entry *acpi_power_dir;static int acpi_power_seq_show(struct seq_file *seq, void *offset){	int count = 0;	int result = 0, state;	struct acpi_power_resource *resource = NULL;	struct list_head *node, *next;	struct acpi_power_reference *ref;	resource = seq->private;	if (!resource)		goto end;	result = acpi_power_get_state(resource, &state);	if (result)		goto end;	seq_puts(seq, "state:                   ");	switch (state) {	case ACPI_POWER_RESOURCE_STATE_ON:		seq_puts(seq, "on\n");		break;	case ACPI_POWER_RESOURCE_STATE_OFF:		seq_puts(seq, "off\n");		break;	default:		seq_puts(seq, "unknown\n");		break;	}	mutex_lock(&resource->resource_lock);	list_for_each_safe(node, next, &resource->reference) {		ref = container_of(node, struct acpi_power_reference, node);		count++;	}	mutex_unlock(&resource->resource_lock);	seq_printf(seq, "system level:            S%d\n"		   "order:                   %d\n"		   "reference count:         %d\n",		   resource->system_level,		   resource->order, count);      end:	return 0;}static int acpi_power_open_fs(struct inode *inode, struct file *file){	return single_open(file, acpi_power_seq_show, PDE(inode)->data);}static int acpi_power_add_fs(struct acpi_device *device){	struct proc_dir_entry *entry = NULL;	if (!device)		return -EINVAL;	if (!acpi_device_dir(device)) {		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),						     acpi_power_dir);		if (!acpi_device_dir(device))			return -ENODEV;	}	/* 'status' [R] */	entry = create_proc_entry(ACPI_POWER_FILE_STATUS,				  S_IRUGO, acpi_device_dir(device));	if (!entry)		return -EIO;	else {		entry->proc_fops = &acpi_power_fops;		entry->data = acpi_driver_data(device);	}	return 0;}static int acpi_power_remove_fs(struct acpi_device *device){	if (acpi_device_dir(device)) {		remove_proc_entry(ACPI_POWER_FILE_STATUS,				  acpi_device_dir(device));		remove_proc_entry(acpi_device_bid(device), acpi_power_dir);		acpi_device_dir(device) = NULL;	}	return 0;}/* --------------------------------------------------------------------------                                Driver Interface   -------------------------------------------------------------------------- */static int acpi_power_add(struct acpi_device *device){	int result = 0, state;	acpi_status status = AE_OK;	struct acpi_power_resource *resource = NULL;	union acpi_object acpi_object;	struct acpi_buffer buffer = { sizeof(acpi_object), &acpi_object };	if (!device)		return -EINVAL;	resource = kzalloc(sizeof(struct acpi_power_resource), GFP_KERNEL);	if (!resource)		return -ENOMEM;	resource->device = device;	mutex_init(&resource->resource_lock);	INIT_LIST_HEAD(&resource->reference);	strcpy(resource->name, device->pnp.bus_id);	strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);	strcpy(acpi_device_class(device), ACPI_POWER_CLASS);	acpi_driver_data(device) = resource;	/* Evalute the object to get the system level and resource order. */	status = acpi_evaluate_object(device->handle, NULL, NULL, &buffer);	if (ACPI_FAILURE(status)) {		result = -ENODEV;		goto end;	}	resource->system_level = acpi_object.power_resource.system_level;	resource->order = acpi_object.power_resource.resource_order;	result = acpi_power_get_state(resource, &state);	if (result)		goto end;	switch (state) {	case ACPI_POWER_RESOURCE_STATE_ON:		device->power.state = ACPI_STATE_D0;		break;	case ACPI_POWER_RESOURCE_STATE_OFF:		device->power.state = ACPI_STATE_D3;		break;	default:		device->power.state = ACPI_STATE_UNKNOWN;		break;	}	result = acpi_power_add_fs(device);	if (result)		goto end;	printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device),	       acpi_device_bid(device), state ? "on" : "off");      end:	if (result)		kfree(resource);	return result;}static int acpi_power_remove(struct acpi_device *device, int type){	struct acpi_power_resource *resource = NULL;	struct list_head *node, *next;	if (!device || !acpi_driver_data(device))		return -EINVAL;	resource = acpi_driver_data(device);	acpi_power_remove_fs(device);	mutex_lock(&resource->resource_lock);	list_for_each_safe(node, next, &resource->reference) {		struct acpi_power_reference *ref = container_of(node, struct acpi_power_reference, node);		list_del(&ref->node);		kfree(ref);	}	mutex_unlock(&resource->resource_lock);	kfree(resource);	return 0;}static int acpi_power_resume(struct acpi_device *device){	int result = 0, state;	struct acpi_power_resource *resource = NULL;	struct acpi_power_reference *ref;	if (!device || !acpi_driver_data(device))		return -EINVAL;	resource = (struct acpi_power_resource *)acpi_driver_data(device);	result = acpi_power_get_state(resource, &state);	if (result)		return result;	mutex_lock(&resource->resource_lock);	if (state == ACPI_POWER_RESOURCE_STATE_OFF &&	    !list_empty(&resource->reference)) {		ref = container_of(resource->reference.next, struct acpi_power_reference, node);		mutex_unlock(&resource->resource_lock);		result = acpi_power_on(device->handle, ref->device);		return result;	}	mutex_unlock(&resource->resource_lock);	return 0;}static int __init acpi_power_init(void){	int result = 0;	if (acpi_disabled)		return 0;	INIT_LIST_HEAD(&acpi_power_resource_list);	acpi_power_dir = proc_mkdir(ACPI_POWER_CLASS, acpi_root_dir);	if (!acpi_power_dir)		return -ENODEV;	result = acpi_bus_register_driver(&acpi_power_driver);	if (result < 0) {		remove_proc_entry(ACPI_POWER_CLASS, acpi_root_dir);		return -ENODEV;	}	return 0;}subsys_initcall(acpi_power_init);

⌨️ 快捷键说明

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