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

📄 thermal.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		return -EINVAL;	if (!tz->flags.cooling_mode)		return -ENODEV;	if (copy_from_user(mode_string, buffer, count))		return -EFAULT;	mode_string[count] = '\0';	result = acpi_thermal_set_cooling_mode(tz,					       simple_strtoul(mode_string, NULL,							      0));	if (result)		return result;	acpi_thermal_check(tz);	return count;}static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset){	struct acpi_thermal *tz = seq->private;	if (!tz)		goto end;	if (!tz->polling_frequency) {		seq_puts(seq, "<polling disabled>\n");		goto end;	}	seq_printf(seq, "polling frequency:       %lu seconds\n",		   (tz->polling_frequency / 10));      end:	return 0;}static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file){	return single_open(file, acpi_thermal_polling_seq_show,			   PDE(inode)->data);}static ssize_tacpi_thermal_write_polling(struct file *file,			   const char __user * buffer,			   size_t count, loff_t * ppos){	struct seq_file *m = file->private_data;	struct acpi_thermal *tz = m->private;	int result = 0;	char polling_string[12] = { '\0' };	int seconds = 0;	if (!tz || (count > sizeof(polling_string) - 1))		return -EINVAL;	if (copy_from_user(polling_string, buffer, count))		return -EFAULT;	polling_string[count] = '\0';	seconds = simple_strtoul(polling_string, NULL, 0);	result = acpi_thermal_set_polling(tz, seconds);	if (result)		return result;	acpi_thermal_check(tz);	return count;}static int acpi_thermal_add_fs(struct acpi_device *device){	struct proc_dir_entry *entry = NULL;	if (!acpi_device_dir(device)) {		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),						     acpi_thermal_dir);		if (!acpi_device_dir(device))			return -ENODEV;		acpi_device_dir(device)->owner = THIS_MODULE;	}	/* 'state' [R] */	entry = create_proc_entry(ACPI_THERMAL_FILE_STATE,				  S_IRUGO, acpi_device_dir(device));	if (!entry)		return -ENODEV;	else {		entry->proc_fops = &acpi_thermal_state_fops;		entry->data = acpi_driver_data(device);		entry->owner = THIS_MODULE;	}	/* 'temperature' [R] */	entry = create_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE,				  S_IRUGO, acpi_device_dir(device));	if (!entry)		return -ENODEV;	else {		entry->proc_fops = &acpi_thermal_temp_fops;		entry->data = acpi_driver_data(device);		entry->owner = THIS_MODULE;	}	/* 'trip_points' [R] */	entry = create_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS,				  S_IRUGO,				  acpi_device_dir(device));	if (!entry)		return -ENODEV;	else {		entry->proc_fops = &acpi_thermal_trip_fops;		entry->data = acpi_driver_data(device);		entry->owner = THIS_MODULE;	}	/* 'cooling_mode' [R/W] */	entry = create_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE,				  S_IFREG | S_IRUGO | S_IWUSR,				  acpi_device_dir(device));	if (!entry)		return -ENODEV;	else {		entry->proc_fops = &acpi_thermal_cooling_fops;		entry->data = acpi_driver_data(device);		entry->owner = THIS_MODULE;	}	/* 'polling_frequency' [R/W] */	entry = create_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ,				  S_IFREG | S_IRUGO | S_IWUSR,				  acpi_device_dir(device));	if (!entry)		return -ENODEV;	else {		entry->proc_fops = &acpi_thermal_polling_fops;		entry->data = acpi_driver_data(device);		entry->owner = THIS_MODULE;	}	return 0;}static int acpi_thermal_remove_fs(struct acpi_device *device){	if (acpi_device_dir(device)) {		remove_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ,				  acpi_device_dir(device));		remove_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE,				  acpi_device_dir(device));		remove_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS,				  acpi_device_dir(device));		remove_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE,				  acpi_device_dir(device));		remove_proc_entry(ACPI_THERMAL_FILE_STATE,				  acpi_device_dir(device));		remove_proc_entry(acpi_device_bid(device), acpi_thermal_dir);		acpi_device_dir(device) = NULL;	}	return 0;}/* --------------------------------------------------------------------------                                 Driver Interface   -------------------------------------------------------------------------- */static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data){	struct acpi_thermal *tz = data;	struct acpi_device *device = NULL;	if (!tz)		return;	device = tz->device;	switch (event) {	case ACPI_THERMAL_NOTIFY_TEMPERATURE:		acpi_thermal_check(tz);		break;	case ACPI_THERMAL_NOTIFY_THRESHOLDS:		acpi_thermal_get_trip_points(tz);		acpi_thermal_check(tz);		acpi_bus_generate_proc_event(device, event, 0);		acpi_bus_generate_netlink_event(device->pnp.device_class,						  device->dev.bus_id, event, 0);		break;	case ACPI_THERMAL_NOTIFY_DEVICES:		if (tz->flags.devices)			acpi_thermal_get_devices(tz);		acpi_bus_generate_proc_event(device, event, 0);		acpi_bus_generate_netlink_event(device->pnp.device_class,						  device->dev.bus_id, event, 0);		break;	default:		ACPI_DEBUG_PRINT((ACPI_DB_INFO,				  "Unsupported event [0x%x]\n", event));		break;	}	return;}static int acpi_thermal_get_info(struct acpi_thermal *tz){	int result = 0;	if (!tz)		return -EINVAL;	/* Get temperature [_TMP] (required) */	result = acpi_thermal_get_temperature(tz);	if (result)		return result;	/* Get trip points [_CRT, _PSV, etc.] (required) */	result = acpi_thermal_get_trip_points(tz);	if (result)		return result;	/* Set the cooling mode [_SCP] to active cooling (default) */	result = acpi_thermal_set_cooling_mode(tz, ACPI_THERMAL_MODE_ACTIVE);	if (!result)		tz->flags.cooling_mode = 1;	/* Get default polling frequency [_TZP] (optional) */	if (tzp)		tz->polling_frequency = tzp;	else		acpi_thermal_get_polling_frequency(tz);	/* Get devices in this thermal zone [_TZD] (optional) */	result = acpi_thermal_get_devices(tz);	if (!result)		tz->flags.devices = 1;	return 0;}static int acpi_thermal_add(struct acpi_device *device){	int result = 0;	acpi_status status = AE_OK;	struct acpi_thermal *tz = NULL;	if (!device)		return -EINVAL;	tz = kzalloc(sizeof(struct acpi_thermal), GFP_KERNEL);	if (!tz)		return -ENOMEM;	tz->device = device;	strcpy(tz->name, device->pnp.bus_id);	strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME);	strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS);	acpi_driver_data(device) = tz;	mutex_init(&tz->lock);	result = acpi_thermal_get_info(tz);	if (result)		goto end;	result = acpi_thermal_add_fs(device);	if (result)		goto end;	init_timer(&tz->timer);	acpi_thermal_check(tz);	status = acpi_install_notify_handler(device->handle,					     ACPI_DEVICE_NOTIFY,					     acpi_thermal_notify, tz);	if (ACPI_FAILURE(status)) {		result = -ENODEV;		goto end;	}	printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n",	       acpi_device_name(device), acpi_device_bid(device),	       KELVIN_TO_CELSIUS(tz->temperature));      end:	if (result) {		acpi_thermal_remove_fs(device);		kfree(tz);	}	return result;}static int acpi_thermal_remove(struct acpi_device *device, int type){	acpi_status status = AE_OK;	struct acpi_thermal *tz = NULL;	if (!device || !acpi_driver_data(device))		return -EINVAL;	tz = acpi_driver_data(device);	/* avoid timer adding new defer task */	tz->zombie = 1;	/* wait for running timer (on other CPUs) finish */	del_timer_sync(&(tz->timer));	/* synchronize deferred task */	acpi_os_wait_events_complete(NULL);	/* deferred task may reinsert timer */	del_timer_sync(&(tz->timer));	status = acpi_remove_notify_handler(device->handle,					    ACPI_DEVICE_NOTIFY,					    acpi_thermal_notify);	/* Terminate policy */	if (tz->trips.passive.flags.valid && tz->trips.passive.flags.enabled) {		tz->trips.passive.flags.enabled = 0;		acpi_thermal_passive(tz);	}	if (tz->trips.active[0].flags.valid	    && tz->trips.active[0].flags.enabled) {		tz->trips.active[0].flags.enabled = 0;		acpi_thermal_active(tz);	}	acpi_thermal_remove_fs(device);	mutex_destroy(&tz->lock);	kfree(tz);	return 0;}static int acpi_thermal_resume(struct acpi_device *device){	struct acpi_thermal *tz = NULL;	int i, j, power_state, result;	if (!device || !acpi_driver_data(device))		return -EINVAL;	tz = acpi_driver_data(device);	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {		if (!(&tz->trips.active[i]))			break;		if (!tz->trips.active[i].flags.valid)			break;		tz->trips.active[i].flags.enabled = 1;		for (j = 0; j < tz->trips.active[i].devices.count; j++) {			result = acpi_bus_get_power(tz->trips.active[i].devices.			    handles[j], &power_state);			if (result || (power_state != ACPI_STATE_D0)) {				tz->trips.active[i].flags.enabled = 0;				break;			}		}		tz->state.active |= tz->trips.active[i].flags.enabled;	}	acpi_thermal_check(tz);	return AE_OK;}#ifdef CONFIG_DMIstatic int thermal_act(const struct dmi_system_id *d) {	if (act == 0) {		printk(KERN_NOTICE "ACPI: %s detected: "			"disabling all active thermal trip points\n", d->ident);		act = -1;	}	return 0;}static int thermal_nocrt(const struct dmi_system_id *d) {	printk(KERN_NOTICE "ACPI: %s detected: "		"disabling all critical thermal trip point actions.\n", d->ident);	nocrt = 1;	return 0;}static int thermal_tzp(const struct dmi_system_id *d) {	if (tzp == 0) {		printk(KERN_NOTICE "ACPI: %s detected: "			"enabling thermal zone polling\n", d->ident);		tzp = 300;	/* 300 dS = 30 Seconds */	}	return 0;}static int thermal_psv(const struct dmi_system_id *d) {	if (psv == 0) {		printk(KERN_NOTICE "ACPI: %s detected: "			"disabling all passive thermal trip points\n", d->ident);		psv = -1;	}	return 0;}static struct dmi_system_id thermal_dmi_table[] __initdata = {	/*	 * Award BIOS on this AOpen makes thermal control almost worthless.	 * http://bugzilla.kernel.org/show_bug.cgi?id=8842	 */	{	 .callback = thermal_act,	 .ident = "AOpen i915GMm-HFS",	 .matches = {		DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),		DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),		},	},	{	 .callback = thermal_psv,	 .ident = "AOpen i915GMm-HFS",	 .matches = {		DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),		DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),		},	},	{	 .callback = thermal_tzp,	 .ident = "AOpen i915GMm-HFS",	 .matches = {		DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),		DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),		},	},	{	 .callback = thermal_nocrt,	 .ident = "Gigabyte GA-7ZX",	 .matches = {		DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."),		DMI_MATCH(DMI_BOARD_NAME, "7ZX"),		},	},	{}};#endif /* CONFIG_DMI */static int __init acpi_thermal_init(void){	int result = 0;	dmi_check_system(thermal_dmi_table);	if (off) {		printk(KERN_NOTICE "ACPI: thermal control disabled\n");		return -ENODEV;	}	acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir);	if (!acpi_thermal_dir)		return -ENODEV;	acpi_thermal_dir->owner = THIS_MODULE;	result = acpi_bus_register_driver(&acpi_thermal_driver);	if (result < 0) {		remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir);		return -ENODEV;	}	return 0;}static void __exit acpi_thermal_exit(void){	acpi_bus_unregister_driver(&acpi_thermal_driver);	remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir);	return;}module_init(acpi_thermal_init);module_exit(acpi_thermal_exit);

⌨️ 快捷键说明

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