Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8f2ddb37 authored by Len Brown's avatar Len Brown
Browse files

Pull bugzilla-5000 into release branch

parents 5b542e44 74ce1468
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -205,6 +205,7 @@ int acpi_bus_set_power(acpi_handle handle, int state)
	 * Get device's current power state if it's unknown
	 * This means device power state isn't initialized or previous setting failed
	 */
	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) {
@@ -212,6 +213,7 @@ int acpi_bus_set_power(acpi_handle handle, int state)
					  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));
+40 −0
Original line number Diff line number Diff line
@@ -48,6 +48,8 @@ MODULE_LICENSE("GPL");

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 @@ static struct acpi_driver acpi_fan_driver = {
	.ops = {
		.add = acpi_fan_add,
		.remove = acpi_fan_remove,
		.suspend = acpi_fan_suspend,
		.resume = acpi_fan_resume,
		},
};

@@ -206,6 +210,10 @@ static int acpi_fan_add(struct acpi_device *device)
		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 @@ static int acpi_fan_remove(struct acpi_device *device, int type)
	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;
+110 −0
Original line number Diff line number Diff line
@@ -1341,6 +1341,100 @@ static int acpi_bus_scan_fixed(struct acpi_device *root)
	return_VALUE(result);
}


static inline struct acpi_device * to_acpi_dev(struct device * dev)
{
	return container_of(dev, struct acpi_device, dev);
}


static int root_suspend(struct acpi_device * acpi_dev, pm_message_t state)
{
	struct acpi_device * dev, * next;
	int result;

	spin_lock(&acpi_device_lock);
	list_for_each_entry_safe_reverse(dev, next, &acpi_device_list, g_list) {
		if (dev->driver && dev->driver->ops.suspend) {
			spin_unlock(&acpi_device_lock);
			result = dev->driver->ops.suspend(dev, 0);
			if (result) {
				printk(KERN_ERR PREFIX "[%s - %s] Suspend failed: %d\n",
				       acpi_device_name(dev),
				       acpi_device_bid(dev), result);
			}
			spin_lock(&acpi_device_lock);
		}
	}
	spin_unlock(&acpi_device_lock);
	return 0;
}


static int acpi_device_suspend(struct device * dev, pm_message_t state)
{
	struct acpi_device * acpi_dev = to_acpi_dev(dev);

	/*
	 * For now, we should only register 1 generic device -
	 * the ACPI root device - and from there, we walk the
	 * tree of ACPI devices to suspend each one using the
	 * ACPI driver methods.
	 */
	if (acpi_dev->handle == ACPI_ROOT_OBJECT)
		root_suspend(acpi_dev, state);
	return 0;
}



static int root_resume(struct acpi_device * acpi_dev)
{
	struct acpi_device * dev, * next;
	int result;

	spin_lock(&acpi_device_lock);
	list_for_each_entry_safe(dev, next, &acpi_device_list, g_list) {
		if (dev->driver && dev->driver->ops.resume) {
			spin_unlock(&acpi_device_lock);
			result = dev->driver->ops.resume(dev, 0);
			if (result) {
				printk(KERN_ERR PREFIX "[%s - %s] resume failed: %d\n",
				       acpi_device_name(dev),
				       acpi_device_bid(dev), result);
			}
			spin_lock(&acpi_device_lock);
		}
	}
	spin_unlock(&acpi_device_lock);
	return 0;
}


static int acpi_device_resume(struct device * dev)
{
	struct acpi_device * acpi_dev = to_acpi_dev(dev);

	/*
	 * For now, we should only register 1 generic device -
	 * the ACPI root device - and from there, we walk the
	 * tree of ACPI devices to resume each one using the
	 * ACPI driver methods.
	 */
	if (acpi_dev->handle == ACPI_ROOT_OBJECT)
		root_resume(acpi_dev);
	return 0;
}


struct bus_type acpi_bus_type = {
	.name		= "acpi",
	.suspend	= acpi_device_suspend,
	.resume		= acpi_device_resume,
};



static int __init acpi_scan_init(void)
{
	int result;
@@ -1353,6 +1447,12 @@ static int __init acpi_scan_init(void)

	kset_register(&acpi_namespace_kset);

	result = bus_register(&acpi_bus_type);
	if (result) {
		/* We don't want to quit even if we failed to add suspend/resume */
		printk(KERN_ERR PREFIX "Could not register bus type\n");
	}

	/*
	 * Create the root device in the bus's device tree
	 */
@@ -1362,6 +1462,16 @@ static int __init acpi_scan_init(void)
		goto Done;

	result = acpi_start_single_object(acpi_root);
	if (result)
		goto Done;

	acpi_root->dev.bus = &acpi_bus_type;
	snprintf(acpi_root->dev.bus_id, BUS_ID_SIZE, "%s", acpi_bus_type.name);
	result = device_register(&acpi_root->dev);
	if (result) {
		/* We don't want to quit even if we failed to add suspend/resume */
		printk(KERN_ERR PREFIX "Could not register device\n");
	}

	/*
	 * Enumerate devices in the ACPI namespace.
+16 −0
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n");

static int acpi_thermal_add(struct acpi_device *device);
static int acpi_thermal_remove(struct acpi_device *device, int type);
static int acpi_thermal_resume(struct acpi_device *device, int state);
static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
@@ -103,6 +104,7 @@ static struct acpi_driver acpi_thermal_driver = {
	.ops = {
		.add = acpi_thermal_add,
		.remove = acpi_thermal_remove,
		.resume = acpi_thermal_resume,
		},
};

@@ -1417,6 +1419,20 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
	return_VALUE(0);
}

static int acpi_thermal_resume(struct acpi_device *device, int state)
{
	struct acpi_thermal *tz = NULL;

	if (!device || !acpi_driver_data(device))
		return_VALUE(-EINVAL);

	tz = (struct acpi_thermal *)acpi_driver_data(device);

	acpi_thermal_check(tz);

	return AE_OK;
}

static int __init acpi_thermal_init(void)
{
	int result = 0;
+4 −2
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@
#ifndef __ACPI_BUS_H__
#define __ACPI_BUS_H__

#include <linux/kobject.h>
#include <linux/device.h>

#include <acpi/acpi.h>

@@ -169,7 +169,8 @@ struct acpi_device_flags {
	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 */
@@ -296,6 +297,7 @@ struct acpi_device {
	struct acpi_driver *driver;
	void *driver_data;
	struct kobject kobj;
	struct device dev;
};

#define acpi_driver_data(d)	((d)->driver_data)