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

Commit 8661423e authored by Hans de Goede's avatar Hans de Goede Committed by Rafael J. Wysocki
Browse files

ACPI / utils: Add new acpi_dev_present helper



acpi_dev_found just iterates over all ACPI-ids and sees if one matches.
This means that it will return true for devices which are in the DSDT
but disabled (their _STA method returns 0).

For some drivers it is useful to be able to check if a certain HID
is not only present in the namespace, but also actually present as in
acpi_device_is_present() will return true for the device. For example
because if a certain device is present then the driver will want to use
an extcon or IIO ADC channel provided by that device.

This commit adds a new acpi_dev_present helper which drivers can use
to this end.

Like acpi_dev_found, acpi_dev_present take a HID as argument, but
it also has 2 extra optional arguments to only check for an ACPI
device with a specific UID and/or HRV value. This makes it more
generic and allows it to replace custom code doing similar checks
in several places.

Arguably acpi_dev_present is what acpi_dev_found should have been, but
there are too many users to just change acpi_dev_found without the risk
of breaking something.

Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Reviewed-by: default avatarLukas Wunner <lukas@wunner.de>
Reviewed-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 4f7d029b
Loading
Loading
Loading
Loading
+66 −0
Original line number Diff line number Diff line
@@ -736,6 +736,72 @@ bool acpi_dev_found(const char *hid)
}
EXPORT_SYMBOL(acpi_dev_found);

struct acpi_dev_present_info {
	struct acpi_device_id hid[2];
	const char *uid;
	s64 hrv;
};

static int acpi_dev_present_cb(struct device *dev, void *data)
{
	struct acpi_device *adev = to_acpi_device(dev);
	struct acpi_dev_present_info *match = data;
	unsigned long long hrv;
	acpi_status status;

	if (acpi_match_device_ids(adev, match->hid))
		return 0;

	if (match->uid && (!adev->pnp.unique_id ||
	    strcmp(adev->pnp.unique_id, match->uid)))
		return 0;

	if (match->hrv == -1)
		return 1;

	status = acpi_evaluate_integer(adev->handle, "_HRV", NULL, &hrv);
	if (ACPI_FAILURE(status))
		return 0;

	return hrv == match->hrv;
}

/**
 * acpi_dev_present - Detect that a given ACPI device is present
 * @hid: Hardware ID of the device.
 * @uid: Unique ID of the device, pass NULL to not check _UID
 * @hrv: Hardware Revision of the device, pass -1 to not check _HRV
 *
 * Return %true if a matching device was present at the moment of invocation.
 * Note that if the device is pluggable, it may since have disappeared.
 *
 * Note that unlike acpi_dev_found() this function checks the status
 * of the device. So for devices which are present in the dsdt, but
 * which are disabled (their _STA callback returns 0) this function
 * will return false.
 *
 * For this function to work, acpi_bus_scan() must have been executed
 * which happens in the subsys_initcall() subsection. Hence, do not
 * call from a subsys_initcall() or earlier (use acpi_get_devices()
 * instead). Calling from module_init() is fine (which is synonymous
 * with device_initcall()).
 */
bool acpi_dev_present(const char *hid, const char *uid, s64 hrv)
{
	struct acpi_dev_present_info match = {};
	struct device *dev;

	strlcpy(match.hid[0].id, hid, sizeof(match.hid[0].id));
	match.uid = uid;
	match.hrv = hrv;

	dev = bus_find_device(&acpi_bus_type, NULL, &match,
			      acpi_dev_present_cb);

	return !!dev;
}
EXPORT_SYMBOL(acpi_dev_present);

/*
 * acpi_backlight= handling, this is done here rather then in video_detect.c
 * because __setup cannot be used in modules.
+1 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ acpi_evaluate_dsm_typed(acpi_handle handle, const u8 *uuid, u64 rev, u64 func,
	}

bool acpi_dev_found(const char *hid);
bool acpi_dev_present(const char *hid, const char *uid, s64 hrv);

#ifdef CONFIG_ACPI

+5 −0
Original line number Diff line number Diff line
@@ -611,6 +611,11 @@ static inline bool acpi_dev_found(const char *hid)
	return false;
}

static inline bool acpi_dev_present(const char *hid, const char *uid, s64 hrv)
{
	return false;
}

static inline bool is_acpi_node(struct fwnode_handle *fwnode)
{
	return false;