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

Commit 778cbc1d authored by Bjorn Helgaas's avatar Bjorn Helgaas Committed by Len Brown
Browse files

ACPI: factor out device type and status checking



This patch adds acpi_bus_type_and_status(), which determines the type
of the object and whether we want to build an acpi_device for it.  If
it is acpi_device-worthy, it returns the type and the device's current
status.

Signed-off-by: default avatarBjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 402ac536
Loading
Loading
Loading
Loading
+52 −77
Original line number Diff line number Diff line
@@ -1252,6 +1252,7 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)

static int acpi_add_single_object(struct acpi_device **child,
				  acpi_handle handle, int type,
				  unsigned long long sta,
				  struct acpi_bus_ops *ops)
{
	int result;
@@ -1268,60 +1269,20 @@ static int acpi_add_single_object(struct acpi_device **child,
	device->handle = handle;
	device->parent = acpi_bus_get_parent(handle);
	device->bus_ops = *ops; /* workround for not call .start */
	STRUCT_TO_INT(device->status) = sta;

	acpi_device_get_busid(device);

	/*
	 * Flags
	 * -----
	 * Get prior to calling acpi_bus_get_status() so we know whether
	 * or not _STA is present.  Note that we only look for object
	 * handles -- cannot evaluate objects until we know the device is
	 * present and properly initialized.
	 * Note that we only look for object handles -- cannot evaluate objects
	 * until we know the device is present and properly initialized.
	 */
	result = acpi_bus_get_flags(device);
	if (result)
		goto end;

	/*
	 * Status
	 * ------
	 * See if the device is present.  We always assume that non-Device
	 * and non-Processor objects (e.g. thermal zones, power resources,
	 * etc.) are present, functioning, etc. (at least when parent object
	 * is present).  Note that _STA has a different meaning for some
	 * objects (e.g. power resources) so we need to be careful how we use
	 * it.
	 */
	switch (type) {
	case ACPI_BUS_TYPE_PROCESSOR:
	case ACPI_BUS_TYPE_DEVICE:
		result = acpi_bus_get_status(device);
		if (ACPI_FAILURE(result)) {
			result = -ENODEV;
			goto end;
		}
		/*
		 * 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) =
		    ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
		    ACPI_STA_DEVICE_UI      | ACPI_STA_DEVICE_FUNCTIONING;
		break;
	}

	/*
	 * Initialize Device
	 * -----------------
@@ -1393,41 +1354,69 @@ static int acpi_add_single_object(struct acpi_device **child,
	return result;
}

static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
				      void *context, void **return_value)
#define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \
			  ACPI_STA_DEVICE_UI      | ACPI_STA_DEVICE_FUNCTIONING)

static int acpi_bus_type_and_status(acpi_handle handle, int *type,
				    unsigned long long *sta)
{
	acpi_status status = AE_OK;
	struct acpi_device *device = NULL;
	acpi_object_type type = 0;
	struct acpi_bus_ops *ops = context;
	acpi_status status;
	acpi_object_type acpi_type;

	status = acpi_get_type(handle, &type);
	status = acpi_get_type(handle, &acpi_type);
	if (ACPI_FAILURE(status))
		return AE_OK;
		return -ENODEV;

	/*
	 * We're only interested in objects that we consider 'devices'.
	 */
	switch (type) {
	switch (acpi_type) {
	case ACPI_TYPE_ANY:		/* for ACPI_ROOT_OBJECT */
	case ACPI_TYPE_DEVICE:
		type = ACPI_BUS_TYPE_DEVICE;
		*type = ACPI_BUS_TYPE_DEVICE;
		status = acpi_bus_get_status_handle(handle, sta);
		if (ACPI_FAILURE(status))
			return -ENODEV;
		break;
	case ACPI_TYPE_PROCESSOR:
		type = ACPI_BUS_TYPE_PROCESSOR;
		*type = ACPI_BUS_TYPE_PROCESSOR;
		status = acpi_bus_get_status_handle(handle, sta);
		if (ACPI_FAILURE(status))
			return -ENODEV;
		break;
	case ACPI_TYPE_THERMAL:
		type = ACPI_BUS_TYPE_THERMAL;
		*type = ACPI_BUS_TYPE_THERMAL;
		*sta = ACPI_STA_DEFAULT;
		break;
	case ACPI_TYPE_POWER:
		type = ACPI_BUS_TYPE_POWER;
		*type = ACPI_BUS_TYPE_POWER;
		*sta = ACPI_STA_DEFAULT;
		break;
	default:
		return AE_OK;
		return -ENODEV;
	}

	return 0;
}

static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
				      void *context, void **return_value)
{
	struct acpi_bus_ops *ops = context;
	struct acpi_device *device = NULL;
	acpi_status status;
	int type;
	unsigned long long sta;
	int result;

	result = acpi_bus_type_and_status(handle, &type, &sta);
	if (result)
		return AE_OK;

	if (!(sta & ACPI_STA_DEVICE_PRESENT) &&
	    !(sta & ACPI_STA_DEVICE_FUNCTIONING))
		return AE_CTRL_DEPTH;

	if (ops->acpi_op_add)
		status = acpi_add_single_object(&device, handle, type, ops);
		status = acpi_add_single_object(&device, handle, type, sta,
						ops);
	else
		status = acpi_bus_get_device(handle, &device);

@@ -1440,22 +1429,6 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
			return AE_CTRL_DEPTH;
	}

	/*
	 * If the device is present, enabled, and functioning then
	 * parse its scope (depth-first).  Note that we need to
	 * represent absent devices to facilitate PnP notifications
	 * -- but only the subtree head (not all of its children,
	 * which will be enumerated when the parent is inserted).
	 *
	 * TBD: Need notifications and other detection mechanisms
	 *      in place before we can fully implement this.
	 *
	 * When the device is not present but functional, it is also
	 * necessary to scan the children of this device.
	 */
	if (!device->status.present && !device->status.functional)
		return AE_CTRL_DEPTH;

	if (!*return_value)
		*return_value = device;
	return AE_OK;
@@ -1579,12 +1552,14 @@ static int acpi_bus_scan_fixed(void)
	if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) {
		result = acpi_add_single_object(&device, NULL,
						ACPI_BUS_TYPE_POWER_BUTTON,
						ACPI_STA_DEFAULT,
						&ops);
	}

	if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) {
		result = acpi_add_single_object(&device, NULL,
						ACPI_BUS_TYPE_SLEEP_BUTTON,
						ACPI_STA_DEFAULT,
						&ops);
	}