drivers/acpi/ioapic.c

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

File Facts

System
Linux kernel
Corpus path
drivers/acpi/ioapic.c
Extension
.c
Size
6076 bytes
Lines
250
Domain
Driver Families
Bucket
drivers/acpi
Inferred role
Driver Families: implementation source
Status
source 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

struct acpi_pci_ioapic {
	acpi_handle	root_handle;
	acpi_handle	handle;
	u32		gsi_base;
	struct resource	res;
	struct pci_dev	*pdev;
	struct list_head list;
};

static LIST_HEAD(ioapic_list);
static DEFINE_MUTEX(ioapic_list_lock);

static acpi_status setup_res(struct acpi_resource *acpi_res, void *data)
{
	struct resource *res = data;
	struct resource_win win;

	/*
	 * We might assign this to 'res' later, make sure all pointers are
	 * cleared before the resource is added to the global list
	 */
	memset(&win, 0, sizeof(win));

	res->flags = 0;
	if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM))
		return AE_OK;

	if (!acpi_dev_resource_memory(acpi_res, res)) {
		if (acpi_dev_resource_address_space(acpi_res, &win) ||
		    acpi_dev_resource_ext_address_space(acpi_res, &win))
			*res = win.res;
	}
	if ((res->flags & IORESOURCE_PREFETCH) ||
	    (res->flags & IORESOURCE_DISABLED))
		res->flags = 0;

	return AE_CTRL_TERMINATE;
}

static bool acpi_is_ioapic(acpi_handle handle, char **type)
{
	acpi_status status;
	struct acpi_device_info *info;
	char *hid = NULL;
	bool match = false;

	if (!acpi_has_method(handle, "_GSB"))
		return false;

	status = acpi_get_object_info(handle, &info);
	if (ACPI_SUCCESS(status)) {
		if (info->valid & ACPI_VALID_HID)
			hid = info->hardware_id.string;
		if (hid) {
			if (strcmp(hid, "ACPI0009") == 0) {
				*type = "IOxAPIC";
				match = true;
			} else if (strcmp(hid, "ACPI000A") == 0) {
				*type = "IOAPIC";
				match = true;
			}
		}
		kfree(info);
	}

	return match;
}

static acpi_status handle_ioapic_add(acpi_handle handle, u32 lvl,
				     void *context, void **rv)
{
	acpi_status status;
	unsigned long long gsi_base;
	struct acpi_pci_ioapic *ioapic;
	struct pci_dev *dev = NULL;
	struct resource *res = NULL, *pci_res = NULL, *crs_res;
	char *type = NULL;

	if (!acpi_is_ioapic(handle, &type))
		return AE_OK;

	mutex_lock(&ioapic_list_lock);
	list_for_each_entry(ioapic, &ioapic_list, list)
		if (ioapic->handle == handle) {
			mutex_unlock(&ioapic_list_lock);
			return AE_OK;
		}

	status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsi_base);
	if (ACPI_FAILURE(status)) {

Annotation

Implementation Notes