drivers/acpi/utils.c

Source file repositories/reference/linux-study-clean/drivers/acpi/utils.c

File Facts

System
Linux kernel
Corpus path
drivers/acpi/utils.c
Extension
.c
Size
28850 bytes
Lines
1085
Domain
Driver Families
Bucket
drivers/acpi
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

* 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_found(const char *hid)
{
	struct acpi_device_bus_id *acpi_device_bus_id;
	bool found = false;

	mutex_lock(&acpi_device_lock);
	list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node)
		if (!strcmp(acpi_device_bus_id->bus_id, hid)) {
			found = true;
			break;
		}
	mutex_unlock(&acpi_device_lock);

	return found;
}
EXPORT_SYMBOL(acpi_dev_found);

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

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

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

	if (match->uid && !acpi_dev_uid_match(adev, 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_match_info match = {};
	struct device *dev;

	strscpy(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_match_cb);
	put_device(dev);
	return !!dev;
}
EXPORT_SYMBOL(acpi_dev_present);

/**
 * acpi_dev_get_next_match_dev - Return the next match of ACPI device
 * @adev: Pointer to the previous ACPI device matching this @hid, @uid and @hrv
 * @hid: Hardware ID of the device.

Annotation

Implementation Notes