ACPI: create acpi_fan_suspend()/acpi_fan_resume()

http://bugzilla.kernel.org/show_bug.cgi?id=5000

Signed-off-by: Len Brown <len.brown@intel.com>
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 606f873..eff696f 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -205,12 +205,14 @@
 	 * 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->flags.force_power_state) {
+		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",
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index e8165c4..1cd2578 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -48,6 +48,8 @@
 
 static int acpi_fan_add(struct acpi_device *device);
 static int acpi_fan_remove(struct acpi_device *device, int type);
+static int acpi_fan_suspend(struct acpi_device *device, int state);
+static int acpi_fan_resume(struct acpi_device *device, int state);
 
 static struct acpi_driver acpi_fan_driver = {
 	.name = ACPI_FAN_DRIVER_NAME,
@@ -56,6 +58,8 @@
 	.ops = {
 		.add = acpi_fan_add,
 		.remove = acpi_fan_remove,
+		.suspend = acpi_fan_suspend,
+		.resume = acpi_fan_resume,
 		},
 };
 
@@ -206,6 +210,10 @@
 		goto end;
 	}
 
+	device->flags.force_power_state = 1;
+	acpi_bus_set_power(device->handle, state);
+	device->flags.force_power_state = 0;
+
 	result = acpi_fan_add_fs(device);
 	if (result)
 		goto end;
@@ -239,6 +247,38 @@
 	return_VALUE(0);
 }
 
+static int acpi_fan_suspend(struct acpi_device *device, int state)
+{
+	if (!device)
+		return -EINVAL;
+
+	acpi_bus_set_power(device->handle, ACPI_STATE_D0);
+
+	return AE_OK;
+}
+
+static int acpi_fan_resume(struct acpi_device *device, int state)
+{
+	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;
+}
+
 static int __init acpi_fan_init(void)
 {
 	int result = 0;
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 0de199a..7f8ed9d 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -169,7 +169,8 @@
 	u32 power_manageable:1;
 	u32 performance_manageable:1;
 	u32 wake_capable:1;	/* Wakeup(_PRW) supported? */
-	u32 reserved:20;
+	u32 force_power_state:1;
+	u32 reserved:19;
 };
 
 /* File System */