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

📄 battery.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		return result;	return device_create_file(battery->bat.dev, &alarm_attr);}static void sysfs_remove_battery(struct acpi_battery *battery){	if (!battery->bat.dev)		return;	device_remove_file(battery->bat.dev, &alarm_attr);	power_supply_unregister(&battery->bat);	battery->bat.dev = NULL;}#endifstatic int acpi_battery_update(struct acpi_battery *battery){	int result;	result = acpi_battery_get_status(battery);	if (result)		return result;#ifdef CONFIG_ACPI_SYSFS_POWER	if (!acpi_battery_present(battery)) {		sysfs_remove_battery(battery);		battery->update_time = 0;		return 0;	}#endif	if (!battery->update_time) {		result = acpi_battery_get_info(battery);		if (result)			return result;		acpi_battery_init_alarm(battery);	}#ifdef CONFIG_ACPI_SYSFS_POWER	if (!battery->bat.dev)		sysfs_add_battery(battery);#endif	return acpi_battery_get_state(battery);}/* --------------------------------------------------------------------------                              FS Interface (/proc)   -------------------------------------------------------------------------- */#ifdef CONFIG_ACPI_PROCFS_POWERstatic struct proc_dir_entry *acpi_battery_dir;static int acpi_battery_print_info(struct seq_file *seq, int result){	struct acpi_battery *battery = seq->private;	if (result)		goto end;	seq_printf(seq, "present:                 %s\n",		   acpi_battery_present(battery)?"yes":"no");	if (!acpi_battery_present(battery))		goto end;	if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)		seq_printf(seq, "design capacity:         unknown\n");	else		seq_printf(seq, "design capacity:         %d %sh\n",			   battery->design_capacity,			   acpi_battery_units(battery));	if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)		seq_printf(seq, "last full capacity:      unknown\n");	else		seq_printf(seq, "last full capacity:      %d %sh\n",			   battery->full_charge_capacity,			   acpi_battery_units(battery));	seq_printf(seq, "battery technology:      %srechargeable\n",		   (!battery->technology)?"non-":"");	if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)		seq_printf(seq, "design voltage:          unknown\n");	else		seq_printf(seq, "design voltage:          %d mV\n",			   battery->design_voltage);	seq_printf(seq, "design capacity warning: %d %sh\n",		   battery->design_capacity_warning,		   acpi_battery_units(battery));	seq_printf(seq, "design capacity low:     %d %sh\n",		   battery->design_capacity_low,		   acpi_battery_units(battery));	seq_printf(seq, "capacity granularity 1:  %d %sh\n",		   battery->capacity_granularity_1,		   acpi_battery_units(battery));	seq_printf(seq, "capacity granularity 2:  %d %sh\n",		   battery->capacity_granularity_2,		   acpi_battery_units(battery));	seq_printf(seq, "model number:            %s\n", battery->model_number);	seq_printf(seq, "serial number:           %s\n", battery->serial_number);	seq_printf(seq, "battery type:            %s\n", battery->type);	seq_printf(seq, "OEM info:                %s\n", battery->oem_info);      end:	if (result)		seq_printf(seq, "ERROR: Unable to read battery info\n");	return result;}static int acpi_battery_print_state(struct seq_file *seq, int result){	struct acpi_battery *battery = seq->private;	if (result)		goto end;	seq_printf(seq, "present:                 %s\n",		   acpi_battery_present(battery)?"yes":"no");	if (!acpi_battery_present(battery))		goto end;	seq_printf(seq, "capacity state:          %s\n",			(battery->state & 0x04)?"critical":"ok");	if ((battery->state & 0x01) && (battery->state & 0x02))		seq_printf(seq,			   "charging state:          charging/discharging\n");	else if (battery->state & 0x01)		seq_printf(seq, "charging state:          discharging\n");	else if (battery->state & 0x02)		seq_printf(seq, "charging state:          charging\n");	else		seq_printf(seq, "charging state:          charged\n");	if (battery->current_now == ACPI_BATTERY_VALUE_UNKNOWN)		seq_printf(seq, "present rate:            unknown\n");	else		seq_printf(seq, "present rate:            %d %s\n",			   battery->current_now, acpi_battery_units(battery));	if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)		seq_printf(seq, "remaining capacity:      unknown\n");	else		seq_printf(seq, "remaining capacity:      %d %sh\n",			   battery->capacity_now, acpi_battery_units(battery));	if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)		seq_printf(seq, "present voltage:         unknown\n");	else		seq_printf(seq, "present voltage:         %d mV\n",			   battery->voltage_now);      end:	if (result)		seq_printf(seq, "ERROR: Unable to read battery state\n");	return result;}static int acpi_battery_print_alarm(struct seq_file *seq, int result){	struct acpi_battery *battery = seq->private;	if (result)		goto end;	if (!acpi_battery_present(battery)) {		seq_printf(seq, "present:                 no\n");		goto end;	}	seq_printf(seq, "alarm:                   ");	if (!battery->alarm)		seq_printf(seq, "unsupported\n");	else		seq_printf(seq, "%u %sh\n", battery->alarm,				acpi_battery_units(battery));      end:	if (result)		seq_printf(seq, "ERROR: Unable to read battery alarm\n");	return result;}static ssize_t acpi_battery_write_alarm(struct file *file,					const char __user * buffer,					size_t count, loff_t * ppos){	int result = 0;	char alarm_string[12] = { '\0' };	struct seq_file *m = file->private_data;	struct acpi_battery *battery = m->private;	if (!battery || (count > sizeof(alarm_string) - 1))		return -EINVAL;	if (!acpi_battery_present(battery)) {		result = -ENODEV;		goto end;	}	if (copy_from_user(alarm_string, buffer, count)) {		result = -EFAULT;		goto end;	}	alarm_string[count] = '\0';	battery->alarm = simple_strtol(alarm_string, NULL, 0);	result = acpi_battery_set_alarm(battery);      end:	if (!result)		return count;	return result;}typedef int(*print_func)(struct seq_file *seq, int result);static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = {	acpi_battery_print_info,	acpi_battery_print_state,	acpi_battery_print_alarm,};static int acpi_battery_read(int fid, struct seq_file *seq){	struct acpi_battery *battery = seq->private;	int result = acpi_battery_update(battery);	return acpi_print_funcs[fid](seq, result);}#define DECLARE_FILE_FUNCTIONS(_name) \static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \{ \	return acpi_battery_read(_name##_tag, seq); \} \static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \{ \	return single_open(file, acpi_battery_read_##_name, PDE(inode)->data); \}DECLARE_FILE_FUNCTIONS(info);DECLARE_FILE_FUNCTIONS(state);DECLARE_FILE_FUNCTIONS(alarm);#undef DECLARE_FILE_FUNCTIONS#define FILE_DESCRIPTION_RO(_name) \	{ \	.name = __stringify(_name), \	.mode = S_IRUGO, \	.ops = { \		.open = acpi_battery_##_name##_open_fs, \		.read = seq_read, \		.llseek = seq_lseek, \		.release = single_release, \		.owner = THIS_MODULE, \		}, \	}#define FILE_DESCRIPTION_RW(_name) \	{ \	.name = __stringify(_name), \	.mode = S_IFREG | S_IRUGO | S_IWUSR, \	.ops = { \		.open = acpi_battery_##_name##_open_fs, \		.read = seq_read, \		.llseek = seq_lseek, \		.write = acpi_battery_write_##_name, \		.release = single_release, \		.owner = THIS_MODULE, \		}, \	}static struct battery_file {	struct file_operations ops;	mode_t mode;	char *name;} acpi_battery_file[] = {	FILE_DESCRIPTION_RO(info),	FILE_DESCRIPTION_RO(state),	FILE_DESCRIPTION_RW(alarm),};#undef FILE_DESCRIPTION_RO#undef FILE_DESCRIPTION_RWstatic int acpi_battery_add_fs(struct acpi_device *device){	struct proc_dir_entry *entry = NULL;	int i;	if (!acpi_device_dir(device)) {		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),						     acpi_battery_dir);		if (!acpi_device_dir(device))			return -ENODEV;		acpi_device_dir(device)->owner = THIS_MODULE;	}	for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {		entry = create_proc_entry(acpi_battery_file[i].name,				  acpi_battery_file[i].mode, acpi_device_dir(device));		if (!entry)			return -ENODEV;		else {			entry->proc_fops = &acpi_battery_file[i].ops;			entry->data = acpi_driver_data(device);			entry->owner = THIS_MODULE;		}	}	return 0;}static void acpi_battery_remove_fs(struct acpi_device *device){	int i;	if (!acpi_device_dir(device))		return;	for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i)		remove_proc_entry(acpi_battery_file[i].name,				  acpi_device_dir(device));	remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);	acpi_device_dir(device) = NULL;}#endif/* --------------------------------------------------------------------------                                 Driver Interface   -------------------------------------------------------------------------- */static void acpi_battery_notify(acpi_handle handle, u32 event, void *data){	struct acpi_battery *battery = data;	struct acpi_device *device;	if (!battery)		return;	device = battery->device;	acpi_battery_update(battery);	acpi_bus_generate_proc_event(device, event,				     acpi_battery_present(battery));	acpi_bus_generate_netlink_event(device->pnp.device_class,					device->dev.bus_id, event,					acpi_battery_present(battery));#ifdef CONFIG_ACPI_SYSFS_POWER	/* acpi_batter_update could remove power_supply object */	if (battery->bat.dev)		kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE);#endif}static int acpi_battery_add(struct acpi_device *device){	int result = 0;	acpi_status status = 0;	struct acpi_battery *battery = NULL;	if (!device)		return -EINVAL;	battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);	if (!battery)		return -ENOMEM;	battery->device = device;	strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);	strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);	acpi_driver_data(device) = battery;	mutex_init(&battery->lock);	acpi_battery_update(battery);#ifdef CONFIG_ACPI_PROCFS_POWER	result = acpi_battery_add_fs(device);	if (result)		goto end;#endif	status = acpi_install_notify_handler(device->handle,					     ACPI_ALL_NOTIFY,					     acpi_battery_notify, battery);	if (ACPI_FAILURE(status)) {		ACPI_EXCEPTION((AE_INFO, status, "Installing notify handler"));		result = -ENODEV;		goto end;	}	printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",	       ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),	       device->status.battery_present ? "present" : "absent");      end:	if (result) {#ifdef CONFIG_ACPI_PROCFS_POWER		acpi_battery_remove_fs(device);#endif		kfree(battery);	}	return result;}static int acpi_battery_remove(struct acpi_device *device, int type){	acpi_status status = 0;	struct acpi_battery *battery = NULL;	if (!device || !acpi_driver_data(device))		return -EINVAL;	battery = acpi_driver_data(device);	status = acpi_remove_notify_handler(device->handle,					    ACPI_ALL_NOTIFY,					    acpi_battery_notify);#ifdef CONFIG_ACPI_PROCFS_POWER	acpi_battery_remove_fs(device);#endif#ifdef CONFIG_ACPI_SYSFS_POWER	sysfs_remove_battery(battery);#endif	mutex_destroy(&battery->lock);	kfree(battery);	return 0;}/* this is needed to learn about changes made in suspended state */static int acpi_battery_resume(struct acpi_device *device){	struct acpi_battery *battery;	if (!device)		return -EINVAL;	battery = acpi_driver_data(device);	battery->update_time = 0;	acpi_battery_update(battery);	return 0;}static struct acpi_driver acpi_battery_driver = {	.name = "battery",	.class = ACPI_BATTERY_CLASS,	.ids = battery_device_ids,	.ops = {		.add = acpi_battery_add,		.resume = acpi_battery_resume,		.remove = acpi_battery_remove,		},};static int __init acpi_battery_init(void){	if (acpi_disabled)		return -ENODEV;#ifdef CONFIG_ACPI_PROCFS_POWER	acpi_battery_dir = acpi_lock_battery_dir();	if (!acpi_battery_dir)		return -ENODEV;#endif	if (acpi_bus_register_driver(&acpi_battery_driver) < 0) {#ifdef CONFIG_ACPI_PROCFS_POWER		acpi_unlock_battery_dir(acpi_battery_dir);#endif		return -ENODEV;	}	return 0;}static void __exit acpi_battery_exit(void){	acpi_bus_unregister_driver(&acpi_battery_driver);#ifdef CONFIG_ACPI_PROCFS_POWER	acpi_unlock_battery_dir(acpi_battery_dir);#endif}module_init(acpi_battery_init);module_exit(acpi_battery_exit);

⌨️ 快捷键说明

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