📄 thermal.c
字号:
if ( tz->cooling_mode == ACPI_THERMAL_MODE_CRT ) seq_printf(seq, "cooling mode: critical\n"); else seq_printf(seq, "cooling mode: %s\n", tz->cooling_mode?"passive":"active");end: return 0;}static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file){ return single_open(file, acpi_thermal_cooling_seq_show, PDE(inode)->data);}static ssize_tacpi_thermal_write_cooling_mode ( struct file *file, const char __user *buffer, size_t count, loff_t *ppos){ struct seq_file *m = (struct seq_file *)file->private_data; struct acpi_thermal *tz = (struct acpi_thermal *)m->private; int result = 0; char mode_string[12] = {'\0'}; ACPI_FUNCTION_TRACE("acpi_thermal_write_cooling_mode"); if (!tz || (count > sizeof(mode_string) - 1)) return_VALUE(-EINVAL); if (!tz->flags.cooling_mode) return_VALUE(-ENODEV); if (copy_from_user(mode_string, buffer, count)) return_VALUE(-EFAULT); mode_string[count] = '\0'; result = acpi_thermal_set_cooling_mode(tz, simple_strtoul(mode_string, NULL, 0)); if (result) return_VALUE(result); acpi_thermal_check(tz); return_VALUE(count);}static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset){ struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; ACPI_FUNCTION_TRACE("acpi_thermal_polling_seq_show"); 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 = (struct seq_file *)file->private_data; struct acpi_thermal *tz = (struct acpi_thermal *)m->private; int result = 0; char polling_string[12] = {'\0'}; int seconds = 0; ACPI_FUNCTION_TRACE("acpi_thermal_write_polling"); if (!tz || (count > sizeof(polling_string) - 1)) return_VALUE(-EINVAL); if (copy_from_user(polling_string, buffer, count)) return_VALUE(-EFAULT); polling_string[count] = '\0'; seconds = simple_strtoul(polling_string, NULL, 0); result = acpi_thermal_set_polling(tz, seconds); if (result) return_VALUE(result); acpi_thermal_check(tz); return_VALUE(count);}static intacpi_thermal_add_fs ( struct acpi_device *device){ struct proc_dir_entry *entry = NULL; ACPI_FUNCTION_TRACE("acpi_thermal_add_fs"); if (!acpi_device_dir(device)) { acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), acpi_thermal_dir); if (!acpi_device_dir(device)) return_VALUE(-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) ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create '%s' fs entry\n", ACPI_THERMAL_FILE_STATE)); 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) ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create '%s' fs entry\n", ACPI_THERMAL_FILE_TEMPERATURE)); else { entry->proc_fops = &acpi_thermal_temp_fops; entry->data = acpi_driver_data(device); entry->owner = THIS_MODULE; } /* 'trip_points' [R/W] */ entry = create_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS, S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); if (!entry) ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create '%s' fs entry\n", ACPI_THERMAL_FILE_TRIP_POINTS)); 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) ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create '%s' fs entry\n", ACPI_THERMAL_FILE_COOLING_MODE)); 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) ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create '%s' fs entry\n", ACPI_THERMAL_FILE_POLLING_FREQ)); else { entry->proc_fops = &acpi_thermal_polling_fops; entry->data = acpi_driver_data(device); entry->owner = THIS_MODULE; } return_VALUE(0);}static intacpi_thermal_remove_fs ( struct acpi_device *device){ ACPI_FUNCTION_TRACE("acpi_thermal_remove_fs"); 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_VALUE(0);}/* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */static voidacpi_thermal_notify ( acpi_handle handle, u32 event, void *data){ struct acpi_thermal *tz = (struct acpi_thermal *) data; struct acpi_device *device = NULL; ACPI_FUNCTION_TRACE("acpi_thermal_notify"); if (!tz) return_VOID; if (acpi_bus_get_device(tz->handle, &device)) return_VOID; 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_event(device, event, 0); break; case ACPI_THERMAL_NOTIFY_DEVICES: if (tz->flags.devices) acpi_thermal_get_devices(tz); acpi_bus_generate_event(device, event, 0); break; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported event [0x%x]\n", event)); break; } return_VOID;}static intacpi_thermal_get_info ( struct acpi_thermal *tz){ int result = 0; ACPI_FUNCTION_TRACE("acpi_thermal_get_info"); if (!tz) return_VALUE(-EINVAL); /* Get temperature [_TMP] (required) */ result = acpi_thermal_get_temperature(tz); if (result) return_VALUE(result); /* Get trip points [_CRT, _PSV, etc.] (required) */ result = acpi_thermal_get_trip_points(tz); if (result) return_VALUE(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; else { /* Oh,we have not _SCP method. Generally show cooling_mode by _ACx, _PSV,spec 12.2*/ tz->flags.cooling_mode = 0; if ( tz->trips.active[0].flags.valid && tz->trips.passive.flags.valid ) { if ( tz->trips.passive.temperature > tz->trips.active[0].temperature ) tz->cooling_mode = ACPI_THERMAL_MODE_ACTIVE; else tz->cooling_mode = ACPI_THERMAL_MODE_PASSIVE; } else if ( !tz->trips.active[0].flags.valid && tz->trips.passive.flags.valid ) { tz->cooling_mode = ACPI_THERMAL_MODE_PASSIVE; } else if ( tz->trips.active[0].flags.valid && !tz->trips.passive.flags.valid ) { tz->cooling_mode = ACPI_THERMAL_MODE_ACTIVE; } else { /* _ACx and _PSV are optional, but _CRT is required */ tz->cooling_mode = ACPI_THERMAL_MODE_CRT; } } /* 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_VALUE(0);}static intacpi_thermal_add ( struct acpi_device *device){ int result = 0; acpi_status status = AE_OK; struct acpi_thermal *tz = NULL; ACPI_FUNCTION_TRACE("acpi_thermal_add"); if (!device) return_VALUE(-EINVAL); tz = kmalloc(sizeof(struct acpi_thermal), GFP_KERNEL); if (!tz) return_VALUE(-ENOMEM); memset(tz, 0, sizeof(struct acpi_thermal)); tz->handle = device->handle; 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; result = acpi_thermal_get_info(tz); if (result) goto end; result = acpi_thermal_add_fs(device); if (result) return_VALUE(result); init_timer(&tz->timer); acpi_thermal_check(tz); status = acpi_install_notify_handler(tz->handle, ACPI_DEVICE_NOTIFY, acpi_thermal_notify, tz); if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error installing notify handler\n")); 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_VALUE(result);}static intacpi_thermal_remove ( struct acpi_device *device, int type){ acpi_status status = AE_OK; struct acpi_thermal *tz = NULL; ACPI_FUNCTION_TRACE("acpi_thermal_remove"); if (!device || !acpi_driver_data(device)) return_VALUE(-EINVAL); tz = (struct acpi_thermal *) 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(tz->handle, ACPI_DEVICE_NOTIFY, acpi_thermal_notify); if (ACPI_FAILURE(status)) ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error removing notify handler\n")); /* 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); kfree(tz); return_VALUE(0);}static int __initacpi_thermal_init (void){ int result = 0; ACPI_FUNCTION_TRACE("acpi_thermal_init"); acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir); if (!acpi_thermal_dir) return_VALUE(-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_VALUE(-ENODEV); } return_VALUE(0);}static void __exitacpi_thermal_exit (void){ ACPI_FUNCTION_TRACE("acpi_thermal_exit"); acpi_bus_unregister_driver(&acpi_thermal_driver); remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); return_VOID;}module_init(acpi_thermal_init);module_exit(acpi_thermal_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -