drivers/acpi/resource.c

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

File Facts

System
Linux kernel
Corpus path
drivers/acpi/resource.c
Extension
.c
Size
32852 bytes
Lines
1175
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

struct irq_override_cmp {
	const struct dmi_system_id *system;
	unsigned char irq;
	unsigned char triggering;
	unsigned char polarity;
	unsigned char shareable;
	bool override;
};

static const struct irq_override_cmp override_table[] = {
	{ irq1_level_low_skip_override, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, false },
	{ irq1_level_low_skip_override, 10, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 1, false },
	{ irq1_level_low_skip_override, 11, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 1, false },
	{ irq1_edge_low_force_override, 1, ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_LOW, 1, true },
};

static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity,
				  u8 shareable)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(override_table); i++) {
		const struct irq_override_cmp *entry = &override_table[i];

		if (entry->irq == gsi &&
		    entry->triggering == triggering &&
		    entry->polarity == polarity &&
		    entry->shareable == shareable &&
		    dmi_check_system(entry->system))
			return entry->override;
	}

#ifdef CONFIG_X86
	/*
	 * Always use the MADT override info, except for the i8042 PS/2 ctrl
	 * IRQs (1 and 12). For these the DSDT IRQ settings should sometimes
	 * be used otherwise PS/2 keyboards / mice will not work.
	 */
	if (gsi != 1 && gsi != 12)
		return true;

	/* If the override comes from an INT_SRC_OVR MADT entry, honor it. */
	if (acpi_int_src_ovr[gsi])
		return true;

	/*
	 * IRQ override isn't needed on modern AMD Zen systems and
	 * this override breaks active low IRQs on AMD Ryzen 6000 and
	 * newer systems. Skip it.
	 */
	if (boot_cpu_has(X86_FEATURE_ZEN))
		return false;
#endif

	return true;
}

static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
				     u8 triggering, u8 polarity, u8 shareable,
				     u8 wake_capable, bool check_override)
{
	int irq, p, t;

	if (!valid_IRQ(gsi)) {
		irqresource_disabled(res, gsi);
		return;
	}

	/*
	 * In IO-APIC mode, use overridden attribute. Two reasons:
	 * 1. BIOS bug in DSDT
	 * 2. BIOS uses IO-APIC mode Interrupt Source Override
	 *
	 * We do this only if we are dealing with IRQ() or IRQNoFlags()
	 * resource (the legacy ISA resources). With modern ACPI 5 devices
	 * using extended IRQ descriptors we take the IRQ configuration
	 * from _CRS directly.
	 */
	if (check_override &&
	    acpi_dev_irq_override(gsi, triggering, polarity, shareable) &&
	    !acpi_get_override_irq(gsi, &t, &p)) {
		u8 trig = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
		u8 pol = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;

		if (triggering != trig || polarity != pol) {
			pr_warn("ACPI: IRQ %d override to %s%s, %s%s\n", gsi,
				t ? "level" : "edge",
				trig == triggering ? "" : "(!)",
				str_low_high(p),
				pol == polarity ? "" : "(!)");

Annotation

Implementation Notes