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

Commit 955ba395 authored by Len Brown's avatar Len Brown
Browse files

Merge branch 'bugfixes' into test

parents aa58329f 383d7a11
Loading
Loading
Loading
Loading
+41 −14
Original line number Diff line number Diff line
@@ -217,21 +217,48 @@ and is between 256 and 4096 characters. It is defined in the file
	acpi.debug_level=	[HW,ACPI]
			Format: <int>
			Each bit of the <int> indicates an ACPI debug level,
			1: enable, 0: disable. It is useful for boot time
			debugging. After system has booted up, it can be set
			via /sys/module/acpi/parameters/debug_level.
			CONFIG_ACPI_DEBUG must be enabled for this to produce any output.
			Available bits (add the numbers together) to enable different
			debug output levels of the ACPI subsystem:
			0x01 error 0x02 warn 0x04 init 0x08 debug object
			0x10 info 0x20 init names 0x40 parse 0x80 load
			0x100 dispatch 0x200 execute 0x400 names 0x800 operation region
			0x1000 bfield 0x2000 tables 0x4000 values 0x8000 objects
			0x10000 resources 0x20000 user requests 0x40000 package.
			which corresponds to the level in an ACPI_DEBUG_PRINT
			statement.  After system has booted up, this mask
			can be set via /sys/module/acpi/parameters/debug_level.

			CONFIG_ACPI_DEBUG must be enabled for this to produce
			any output.  The number can be in decimal or prefixed
			with 0x in hex.  Some of these options produce so much
			output that the system is unusable.

			The following global components are defined by the
			ACPI CA:
			       0x01 error
			       0x02 warn
			       0x04 init
			       0x08 debug object
			       0x10 info
			       0x20 init names
			       0x40 parse
			       0x80 load
			      0x100 dispatch
			      0x200 execute
			      0x400 names
			      0x800 operation region
			     0x1000 bfield
			     0x2000 tables
			     0x4000 values
			     0x8000 objects
			    0x10000 resources
			    0x20000 user requests
			    0x40000 package
 			The number can be in decimal or prefixed with 0x in hex.
 			Warning: Many of these options can produce a lot of
 			output and make your system unusable. Be very careful.

 	acpi.power_nocheck=	[HW,ACPI]
 			Format: 1/0 enable/disable the check of power state.
 			On some bogus BIOS the _PSC object/_STA object of
 			power resource can't return the correct device power
 			state. In such case it is unneccessary to check its
 			power state again in power transition.
 			1 : disable the power state check

	acpi_pm_good	[X86-32,X86-64]
			Override the pmtimer bug detection: force the kernel
			to assume that this machine's pmtimer latches its value
+43 −10
Original line number Diff line number Diff line
@@ -48,6 +48,23 @@ EXPORT_SYMBOL(acpi_root_dir);

#define STRUCT_TO_INT(s)	(*((int*)&s))

static int set_power_nocheck(const struct dmi_system_id *id)
{
	printk(KERN_NOTICE PREFIX "%s detected - "
		"disable power check in power transistion\n", id->ident);
	acpi_power_nocheck = 1;
	return 0;
}
static struct dmi_system_id __cpuinitdata power_nocheck_dmi_table[] = {
	{
	set_power_nocheck, "HP Pavilion 05", {
	DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
	DMI_MATCH(DMI_SYS_VENDOR, "HP Pavilion 05"),
	DMI_MATCH(DMI_PRODUCT_VERSION, "2001211RE101GLEND") }, NULL},
	{},
};


/* --------------------------------------------------------------------------
                                Device Management
   -------------------------------------------------------------------------- */
@@ -95,21 +112,21 @@ int acpi_bus_get_status(struct acpi_device *device)
	}

	/*
	 * Otherwise we assume the status of our parent (unless we don't
	 * have one, in which case status is implied).
	 * According to ACPI spec some device can be present and functional
	 * even if the parent is not present but functional.
	 * In such conditions the child device should not inherit the status
	 * from the parent.
	 */
	else if (device->parent)
		device->status = device->parent->status;
	else
		STRUCT_TO_INT(device->status) =
		    ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
		    ACPI_STA_DEVICE_UI      | ACPI_STA_DEVICE_FUNCTIONING;

	if (device->status.functional && !device->status.present) {
		printk(KERN_WARNING PREFIX "Device [%s] status [%08x]: "
		       "functional but not present; setting present\n",
		       device->pnp.bus_id, (u32) STRUCT_TO_INT(device->status));
		device->status.present = 1;
		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]: "
		       "functional but not present;\n",
			device->pnp.bus_id,
			(u32) STRUCT_TO_INT(device->status)));
	}

	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n",
@@ -223,7 +240,19 @@ int acpi_bus_set_power(acpi_handle handle, int state)
	/*
	 * 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));
@@ -818,7 +847,11 @@ static int __init acpi_init(void)
		}
	} else
		disable_acpi();

	/*
	 * If the laptop falls into the DMI check table, the power state check
	 * will be disabled in the course of device power transistion.
	 */
	dmi_check_system(power_nocheck_dmi_table);
	return result;
}

+2 −2
Original line number Diff line number Diff line
@@ -709,7 +709,7 @@ int acpi_pci_link_free_irq(acpi_handle handle)
			  acpi_device_bid(link->device)));

	if (link->refcnt == 0) {
		acpi_ut_evaluate_object(link->device->handle, "_DIS", 0, NULL);
		acpi_evaluate_object(link->device->handle, "_DIS", NULL, NULL);
	}
	mutex_unlock(&acpi_link_lock);
	return (link->irq.active);
@@ -773,7 +773,7 @@ static int acpi_pci_link_add(struct acpi_device *device)

      end:
	/* disable all links -- to be activated on use */
	acpi_ut_evaluate_object(device->handle, "_DIS", 0, NULL);
	acpi_evaluate_object(device->handle, "_DIS", NULL, NULL);
	mutex_unlock(&acpi_link_lock);

	if (result)
+45 −23
Original line number Diff line number Diff line
@@ -54,6 +54,14 @@ ACPI_MODULE_NAME("power");
#define ACPI_POWER_RESOURCE_STATE_OFF	0x00
#define ACPI_POWER_RESOURCE_STATE_ON	0x01
#define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF

#ifdef MODULE_PARAM_PREFIX
#undef MODULE_PARAM_PREFIX
#endif
#define MODULE_PARAM_PREFIX "acpi."
int acpi_power_nocheck;
module_param_named(power_nocheck, acpi_power_nocheck, bool, 000);

static int acpi_power_add(struct acpi_device *device);
static int acpi_power_remove(struct acpi_device *device, int type);
static int acpi_power_resume(struct acpi_device *device);
@@ -128,16 +136,16 @@ acpi_power_get_context(acpi_handle handle,
	return 0;
}

static int acpi_power_get_state(struct acpi_power_resource *resource, int *state)
static int acpi_power_get_state(acpi_handle handle, int *state)
{
	acpi_status status = AE_OK;
	unsigned long sta = 0;


	if (!resource || !state)
	if (!handle || !state)
		return -EINVAL;

	status = acpi_evaluate_integer(resource->device->handle, "_STA", NULL, &sta);
	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
	if (ACPI_FAILURE(status))
		return -ENODEV;

@@ -145,7 +153,7 @@ static int acpi_power_get_state(struct acpi_power_resource *resource, int *state
			      ACPI_POWER_RESOURCE_STATE_OFF;

	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n",
			  resource->name, state ? "on" : "off"));
			  acpi_ut_get_node_name(handle), state ? "on" : "off"));

	return 0;
}
@@ -153,7 +161,6 @@ static int acpi_power_get_state(struct acpi_power_resource *resource, int *state
static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
{
	int result = 0, state1;
	struct acpi_power_resource *resource = NULL;
	u32 i = 0;


@@ -161,12 +168,15 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
		return -EINVAL;

	/* The state of the list is 'on' IFF all resources are 'on'. */
	/* */

	for (i = 0; i < list->count; i++) {
		result = acpi_power_get_context(list->handles[i], &resource);
		if (result)
			return result;
		result = acpi_power_get_state(resource, &state1);
		/*
		 * The state of the power resource can be obtained by
		 * using the ACPI handle. In such case it is unnecessary to
		 * get the Power resource first and then get its state again.
		 */
		result = acpi_power_get_state(list->handles[i], &state1);
		if (result)
			return result;

@@ -226,12 +236,18 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev)
	if (ACPI_FAILURE(status))
		return -ENODEV;

	result = acpi_power_get_state(resource, &state);
	if (!acpi_power_nocheck) {
		/*
		 * If acpi_power_nocheck is set, it is unnecessary to check
		 * the power state after power transition.
		 */
		result = acpi_power_get_state(resource->device->handle,
				&state);
		if (result)
			return result;
		if (state != ACPI_POWER_RESOURCE_STATE_ON)
			return -ENOEXEC;

	}
	/* Update the power resource's _device_ power state */
	resource->device->power.state = ACPI_STATE_D0;

@@ -277,11 +293,17 @@ static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev)
	if (ACPI_FAILURE(status))
		return -ENODEV;

	result = acpi_power_get_state(resource, &state);
	if (!acpi_power_nocheck) {
		/*
		 * If acpi_power_nocheck is set, it is unnecessary to check
		 * the power state after power transition.
		 */
		result = acpi_power_get_state(handle, &state);
		if (result)
			return result;
		if (state != ACPI_POWER_RESOURCE_STATE_OFF)
			return -ENOEXEC;
	}

	/* Update the power resource's _device_ power state */
	resource->device->power.state = ACPI_STATE_D3;
@@ -555,7 +577,7 @@ static int acpi_power_seq_show(struct seq_file *seq, void *offset)
	if (!resource)
		goto end;

	result = acpi_power_get_state(resource, &state);
	result = acpi_power_get_state(resource->device->handle, &state);
	if (result)
		goto end;

@@ -668,7 +690,7 @@ static int acpi_power_add(struct acpi_device *device)
	resource->system_level = acpi_object.power_resource.system_level;
	resource->order = acpi_object.power_resource.resource_order;

	result = acpi_power_get_state(resource, &state);
	result = acpi_power_get_state(device->handle, &state);
	if (result)
		goto end;

@@ -735,7 +757,7 @@ static int acpi_power_resume(struct acpi_device *device)

	resource = (struct acpi_power_resource *)acpi_driver_data(device);

	result = acpi_power_get_state(resource, &state);
	result = acpi_power_get_state(device->handle, &state);
	if (result)
		return result;

+36 −26
Original line number Diff line number Diff line
@@ -276,6 +276,13 @@ int acpi_match_device_ids(struct acpi_device *device,
{
	const struct acpi_device_id *id;

	/*
	 * If the device is not present, it is unnecessary to load device
	 * driver for it.
	 */
	if (!device->status.present)
		return -ENODEV;

	if (device->flags.hardware_id) {
		for (id = ids; id->id[0]; id++) {
			if (!strcmp((char*)id->id, device->pnp.hardware_id))
@@ -807,6 +814,7 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
	/* TBD: System wake support and resource requirements. */

	device->power.state = ACPI_STATE_UNKNOWN;
	acpi_bus_get_power(device->handle, &(device->power.state));

	return 0;
}
@@ -1152,20 +1160,6 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
	return 0;
}

static int
acpi_is_child_device(struct acpi_device *device,
			int (*matcher)(struct acpi_device *))
{
	int result = -ENODEV;

	do {
		if (ACPI_SUCCESS(matcher(device)))
			return AE_OK;
	} while ((device = device->parent));

	return result;
}

static int
acpi_add_single_object(struct acpi_device **child,
		       struct acpi_device *parent, acpi_handle handle, int type,
@@ -1221,16 +1215,19 @@ acpi_add_single_object(struct acpi_device **child,
			result = -ENODEV;
			goto end;
		}
		if (!device->status.present) {
			/* Bay and dock should be handled even if absent */
			if (!ACPI_SUCCESS(
			     acpi_is_child_device(device, acpi_bay_match)) &&
			    !ACPI_SUCCESS(
			     acpi_is_child_device(device, acpi_dock_match))) {
		/*
		 * When the device is neither present nor functional, the
		 * device should not be added to Linux ACPI device tree.
		 * When the status of the device is not present but functinal,
		 * it should be added to Linux ACPI tree. For example : bay
		 * device , dock device.
		 * In such conditions it is unncessary to check whether it is
		 * bay device or dock device.
		 */
		if (!device->status.present && !device->status.functional) {
			result = -ENODEV;
			goto end;
		}
		}
		break;
	default:
		STRUCT_TO_INT(device->status) =
@@ -1251,6 +1248,16 @@ acpi_add_single_object(struct acpi_device **child,
	 */
	acpi_device_set_id(device, parent, handle, type);

	/*
	 * The ACPI device is attached to acpi handle before getting
	 * the power/wakeup/peformance flags. Otherwise OS can't get
	 * the corresponding ACPI device by the acpi handle in the course
	 * of getting the power/wakeup/performance flags.
	 */
	result = acpi_device_set_context(device, type);
	if (result)
		goto end;

	/*
	 * Power Management
	 * ----------------
@@ -1281,8 +1288,6 @@ acpi_add_single_object(struct acpi_device **child,
			goto end;
	}

	if ((result = acpi_device_set_context(device, type)))
		goto end;

	result = acpi_device_register(device, parent);

@@ -1402,7 +1407,12 @@ static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops)
		 * TBD: Need notifications and other detection mechanisms
		 *      in place before we can fully implement this.
		 */
		if (child->status.present) {
		 /*
		 * When the device is not present but functional, it is also
		 * necessary to scan the children of this device.
		 */
		if (child->status.present || (!child->status.present &&
					child->status.functional)) {
			status = acpi_get_next_object(ACPI_TYPE_ANY, chandle,
						      NULL, NULL);
			if (ACPI_SUCCESS(status)) {
Loading