static int acpi_fujitsu_add(struct acpi_device *device) { int result = 0; int state = 0; ACPI_FUNCTION_TRACE("acpi_fujitsu_add"); if (!device) return -EINVAL; fujitsu->acpi_handle = device->handle; sprintf(acpi_device_name(device), "%s", ACPI_FUJITSU_DEVICE_NAME); sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS); acpi_driver_data(device) = fujitsu; result = acpi_bus_get_power(fujitsu->acpi_handle, &state); if (result) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error reading power state\n")); goto end; } printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device), acpi_device_bid(device), !device->power.state ? "on" : "off"); end: return result; }
static int acpi_fan_read_state ( char *page, char **start, off_t off, int count, int *eof, void *data) { struct acpi_fan *fan = (struct acpi_fan *) data; char *p = page; int len = 0; int state = 0; ACPI_FUNCTION_TRACE("acpi_fan_read_state"); if (!fan || (off != 0)) goto end; if (acpi_bus_get_power(fan->handle, &state)) goto end; p += sprintf(p, "status: %s\n", !state?"on":"off"); end: len = (p - page); if (len <= off+count) *eof = 1; *start = page + off; len -= off; if (len>count) len = count; if (len<0) len = 0; return_VALUE(len); }
static int acpi_fan_add(struct acpi_device *device) { int result = 0; int state = 0; struct thermal_cooling_device *cdev; if (!device) return -EINVAL; strcpy(acpi_device_name(device), "Fan"); strcpy(acpi_device_class(device), ACPI_FAN_CLASS); result = acpi_bus_get_power(device->handle, &state); if (result) { printk(KERN_ERR PREFIX "Reading power state\n"); goto end; } device->flags.force_power_state = 1; acpi_bus_set_power(device->handle, state); device->flags.force_power_state = 0; cdev = thermal_cooling_device_register("Fan", device, &fan_cooling_ops); if (IS_ERR(cdev)) { result = PTR_ERR(cdev); goto end; } dev_dbg(&device->dev, "registered as cooling_device%d\n", cdev->id); device->driver_data = cdev; result = sysfs_create_link(&device->dev.kobj, &cdev->device.kobj, "thermal_cooling"); if (result) dev_err(&device->dev, "Failed to create sysfs link " "'thermal_cooling'\n"); result = sysfs_create_link(&cdev->device.kobj, &device->dev.kobj, "device"); if (result) dev_err(&device->dev, "Failed to create sysfs link " "'device'\n"); result = acpi_fan_add_fs(device); if (result) goto end; printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device), acpi_device_bid(device), !device->power.state ? "on" : "off"); end: return result; }
static int acpi_fan_read_state(struct seq_file *seq, void *offset) { struct acpi_device *device = seq->private; int state = 0; if (device) { if (acpi_bus_get_power(device->handle, &state)) seq_printf(seq, "status: ERROR\n"); else seq_printf(seq, "status: %s\n", !state ? "on" : "off"); } return 0; }
static int fan_get_cur_state(struct thermal_cooling_device *cdev, char *buf) { struct acpi_device *device = cdev->devdata; int state; int result; if (!device) return -EINVAL; result = acpi_bus_get_power(device->handle, &state); if (result) return result; return sprintf(buf, "%s\n", state == ACPI_STATE_D3 ? "0" : (state == ACPI_STATE_D0 ? "1" : "unknown")); }
static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long *state) { struct acpi_device *device = cdev->devdata; int result; int acpi_state; if (!device) return -EINVAL; result = acpi_bus_get_power(device->handle, &acpi_state); if (result) return result; *state = (acpi_state == ACPI_STATE_D3 ? 0 : (acpi_state == ACPI_STATE_D0 ? 1 : -1)); return 0; }
int acpi_fan_add ( struct acpi_device *device) { int result = 0; struct acpi_fan *fan = NULL; int state = 0; ACPI_FUNCTION_TRACE("acpi_fan_add"); if (!device) return_VALUE(-EINVAL); fan = kmalloc(sizeof(struct acpi_fan), GFP_KERNEL); if (!fan) return_VALUE(-ENOMEM); memset(fan, 0, sizeof(struct acpi_fan)); fan->handle = device->handle; sprintf(acpi_device_name(device), "%s", ACPI_FAN_DEVICE_NAME); sprintf(acpi_device_class(device), "%s", ACPI_FAN_CLASS); acpi_driver_data(device) = fan; result = acpi_bus_get_power(fan->handle, &state); if (result) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error reading power state\n")); goto end; } result = acpi_fan_add_fs(device); if (result) goto end; printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device), acpi_device_bid(device), !device->power.state?"on":"off"); end: if (result) kfree(fan); return_VALUE(result); }
static int acpi_fan_resume(struct acpi_device *device) { int result = 0; int power_state = 0; if (!device) return -EINVAL; result = acpi_bus_get_power(device->handle, &power_state); if (result) { printk(KERN_ERR PREFIX "Error reading fan power state\n"); return result; } device->flags.force_power_state = 1; acpi_bus_set_power(device->handle, power_state); device->flags.force_power_state = 0; return result; }
static int acpi_fan_resume(struct acpi_device *device) { int result = 0; int power_state = 0; if (!device) return -EINVAL; result = acpi_bus_get_power(device->handle, &power_state); if (result) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error reading fan power state\n")); return result; } device->flags.force_power_state = 1; acpi_bus_set_power(device->handle, power_state); device->flags.force_power_state = 0; return result; }
int acpi_bus_set_power(acpi_handle handle, int state) { int result = 0; acpi_status status = AE_OK; struct acpi_device *device = NULL; char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' }; result = acpi_bus_get_device(handle, &device); if (result) return result; if ((state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) return -EINVAL; /* Make sure this is a valid target state */ if (!device->flags.power_manageable) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n", kobject_name(&device->dev.kobj))); return -ENODEV; } /* * Get device's current power state */ if (!acpi_power_nocheck) { /* * Maybe the incorrect power state is returned on the bogus * bios, which is different with the real power state. * For example: the bios returns D0 state and the real power * state is D3. OS expects to set the device to D0 state. In * such case if OS uses the power state returned by the BIOS, * the device can't be transisted to the correct power state. * So if the acpi_power_nocheck is set, it is unnecessary to * get the power state by calling acpi_bus_get_power. */ acpi_bus_get_power(device->handle, &device->power.state); } if ((state == device->power.state) && !device->flags.force_power_state) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", state)); return 0; } if (!device->power.states[state].flags.valid) { printk(KERN_WARNING PREFIX "Device does not support D%d\n", state); return -ENODEV; } if (device->parent && (state < device->parent->power.state)) { printk(KERN_WARNING PREFIX "Cannot set device to a higher-powered" " state than parent\n"); return -ENODEV; } /* * Transition Power * ---------------- * On transitions to a high-powered state we first apply power (via * power resources) then evalute _PSx. Conversly for transitions to * a lower-powered state. */ if (state < device->power.state) { if (device->power.flags.power_resources) { result = acpi_power_transition(device, state); if (result) goto end; } if (device->power.states[state].flags.explicit_set) { status = acpi_evaluate_object(device->handle, object_name, NULL, NULL); if (ACPI_FAILURE(status)) { result = -ENODEV; goto end; } } } else { if (device->power.states[state].flags.explicit_set) { status = acpi_evaluate_object(device->handle, object_name, NULL, NULL); if (ACPI_FAILURE(status)) { result = -ENODEV; goto end; } } if (device->power.flags.power_resources) { result = acpi_power_transition(device, state); if (result) goto end; } } end: if (result) printk(KERN_WARNING PREFIX "Transitioning device [%s] to D%d\n", device->pnp.bus_id, state); else { device->power.state = state; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] transitioned to D%d\n", device->pnp.bus_id, state)); } return result; }
VOID Bus_InitializePdo ( PDEVICE_OBJECT Pdo, PFDO_DEVICE_DATA FdoData ) { PPDO_DEVICE_DATA pdoData; int acpistate; DEVICE_POWER_STATE ntState; PAGED_CODE (); pdoData = (PPDO_DEVICE_DATA) Pdo->DeviceExtension; DPRINT("pdo 0x%p, extension 0x%p\n", Pdo, pdoData); if (pdoData->AcpiHandle) acpi_bus_get_power(pdoData->AcpiHandle, &acpistate); else acpistate = ACPI_STATE_D0; switch(acpistate) { case ACPI_STATE_D0: ntState = PowerDeviceD0; break; case ACPI_STATE_D1: ntState = PowerDeviceD1; break; case ACPI_STATE_D2: ntState = PowerDeviceD2; break; case ACPI_STATE_D3: ntState = PowerDeviceD3; break; default: DPRINT1("Unknown power state (%d) returned by acpi\n",acpistate); ntState = PowerDeviceUnspecified; break; } // // Initialize the rest // pdoData->Common.IsFDO = FALSE; pdoData->Common.Self = Pdo; pdoData->ParentFdo = FdoData->Common.Self; INITIALIZE_PNP_STATE(pdoData->Common); pdoData->Common.DevicePowerState = ntState; pdoData->Common.SystemPowerState = FdoData->Common.SystemPowerState; ExAcquireFastMutex (&FdoData->Mutex); InsertTailList(&FdoData->ListOfPDOs, &pdoData->Link); FdoData->NumPDOs++; ExReleaseFastMutex (&FdoData->Mutex); // This should be the last step in initialization. Pdo->Flags &= ~DO_DEVICE_INITIALIZING; }
int acpi_bus_set_power(acpi_handle handle, int state) { int result = 0; acpi_status status = AE_OK; struct acpi_device *device = NULL; char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' }; ACPI_FUNCTION_TRACE("acpi_bus_set_power"); result = acpi_bus_get_device(handle, &device); if (result) return_VALUE(result); if ((state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) return_VALUE(-EINVAL); /* Make sure this is a valid target state */ if (!device->flags.power_manageable) { ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Device is not power manageable\n")); return_VALUE(-ENODEV); } /* * Get device's current power state if it's unknown * This means device power state isn't initialized or previous setting failed */ if (device->power.state == ACPI_STATE_UNKNOWN) acpi_bus_get_power(device->handle, &device->power.state); if (state == device->power.state) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", state)); return_VALUE(0); } if (!device->power.states[state].flags.valid) { ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Device does not support D%d\n", state)); return_VALUE(-ENODEV); } if (device->parent && (state < device->parent->power.state)) { ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Cannot set device to a higher-powered state than parent\n")); return_VALUE(-ENODEV); } /* * Transition Power * ---------------- * On transitions to a high-powered state we first apply power (via * power resources) then evalute _PSx. Conversly for transitions to * a lower-powered state. */ if (state < device->power.state) { if (device->power.flags.power_resources) { result = acpi_power_transition(device, state); if (result) goto end; } if (device->power.states[state].flags.explicit_set) { status = acpi_evaluate_object(device->handle, object_name, NULL, NULL); if (ACPI_FAILURE(status)) { result = -ENODEV; goto end; } } } else { if (device->power.states[state].flags.explicit_set) { status = acpi_evaluate_object(device->handle, object_name, NULL, NULL); if (ACPI_FAILURE(status)) { result = -ENODEV; goto end; } } if (device->power.flags.power_resources) { result = acpi_power_transition(device, state); if (result) goto end; } } end: if (result) ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Error transitioning device [%s] to D%d\n", device->pnp.bus_id, state)); else ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] transitioned to D%d\n", device->pnp.bus_id, state)); return_VALUE(result); }
int acpi_bus_set_power(acpi_handle handle, int state) { int result = 0; acpi_status status = AE_OK; struct acpi_device *device = NULL; char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' }; result = acpi_bus_get_device(handle, &device); if (result) return result; if ((state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) return -EINVAL; /* Make sure this is a valid target state */ if (!device->flags.power_manageable) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n", kobject_name(&device->dev.kobj))); return -ENODEV; } /* * Get device's current power state */ acpi_bus_get_power(device->handle, &device->power.state); if ((state == device->power.state) && !device->flags.force_power_state) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", state)); return 0; } if (!device->power.states[state].flags.valid) { printk(KERN_WARNING PREFIX "Device does not support D%d\n", state); return -ENODEV; } if (device->parent && (state < device->parent->power.state)) { printk(KERN_WARNING PREFIX "Cannot set device to a higher-powered" " state than parent\n"); return -ENODEV; } /* * Transition Power * ---------------- * On transitions to a high-powered state we first apply power (via * power resources) then evalute _PSx. Conversly for transitions to * a lower-powered state. */ if (state < device->power.state) { if (device->power.flags.power_resources) { result = acpi_power_transition(device, state); if (result) goto end; } if (device->power.states[state].flags.explicit_set) { status = acpi_evaluate_object(device->handle, object_name, NULL, NULL); if (ACPI_FAILURE(status)) { result = -ENODEV; goto end; } } } else { if (device->power.states[state].flags.explicit_set) { status = acpi_evaluate_object(device->handle, object_name, NULL, NULL); if (ACPI_FAILURE(status)) { result = -ENODEV; goto end; } } if (device->power.flags.power_resources) { result = acpi_power_transition(device, state); if (result) goto end; } } end: if (result) printk(KERN_WARNING PREFIX "Transitioning device [%s] to D%d\n", device->pnp.bus_id, state); else { device->power.state = state; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] transitioned to D%d\n", device->pnp.bus_id, state)); } return result; }