patch-2.4.26 linux-2.4.26/arch/i386/kernel/acpi.c
Next file: linux-2.4.26/arch/i386/kernel/dmi_scan.c
Previous file: linux-2.4.26/arch/i386/defconfig
Back to the patch index
Back to the overall index
- Lines: 243
- Date:
2004-04-14 06:05:25.000000000 -0700
- Orig file:
linux-2.4.25/arch/i386/kernel/acpi.c
- Orig date:
2004-02-18 05:36:30.000000000 -0800
diff -urN linux-2.4.25/arch/i386/kernel/acpi.c linux-2.4.26/arch/i386/kernel/acpi.c
@@ -49,14 +49,16 @@
#define PREFIX "ACPI: "
-int acpi_lapic = 0;
-int acpi_ioapic = 0;
+int acpi_lapic;
+int acpi_ioapic;
+int acpi_strict;
+acpi_interrupt_flags acpi_sci_flags __initdata;
+int acpi_sci_override_gsi __initdata;
/* --------------------------------------------------------------------------
Boot-time Configuration
-------------------------------------------------------------------------- */
-#ifdef CONFIG_ACPI_BOOT
int acpi_noirq __initdata = 0; /* skip ACPI IRQ initialization */
int acpi_ht __initdata = 1; /* enable HT */
@@ -214,6 +216,59 @@
return 0;
}
+/*
+ * Parse Interrupt Source Override for the ACPI SCI
+ */
+static void
+acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
+{
+ if (trigger == 0) /* compatible SCI trigger is level */
+ trigger = 3;
+
+ if (polarity == 0) /* compatible SCI polarity is low */
+ polarity = 3;
+
+ /* Command-line over-ride via acpi_sci= */
+ if (acpi_sci_flags.trigger)
+ trigger = acpi_sci_flags.trigger;
+
+ if (acpi_sci_flags.polarity)
+ polarity = acpi_sci_flags.polarity;
+
+ /*
+ * mp_config_acpi_legacy_irqs() already setup IRQs < 16
+ * If GSI is < 16, this will update its flags,
+ * else it will create a new mp_irqs[] entry.
+ */
+ mp_override_legacy_irq(gsi, polarity, trigger, gsi);
+
+ /*
+ * stash over-ride to indicate we've been here
+ * and for later update of acpi_fadt
+ */
+ acpi_sci_override_gsi = gsi;
+ return;
+}
+
+static int __init
+acpi_parse_fadt(unsigned long phys, unsigned long size)
+{
+ struct fadt_descriptor_rev2 *fadt =0;
+
+ fadt = (struct fadt_descriptor_rev2*) __acpi_map_table(phys,size);
+ if (!fadt) {
+ printk(KERN_WARNING PREFIX "Unable to map FADT\n");
+ return 0;
+ }
+
+#ifdef CONFIG_ACPI_INTERPRETER
+ /* initialize sci_int early for INT_SRC_OVR MADT parsing */
+ acpi_fadt.sci_int = fadt->sci_int;
+#endif
+
+ return 0;
+}
+
static int __init
acpi_parse_int_src_ovr (
@@ -227,6 +282,12 @@
acpi_table_print_madt_entry(header);
+ if (intsrc->bus_irq == acpi_fadt.sci_int) {
+ acpi_sci_ioapic_setup(intsrc->global_irq,
+ intsrc->flags.polarity, intsrc->flags.trigger);
+ return 0;
+ }
+
mp_override_legacy_irq (
intsrc->bus_irq,
intsrc->flags.polarity,
@@ -307,7 +368,7 @@
* acpi_lapic = 1 if LAPIC found
* acpi_ioapic = 1 if IOAPIC found
* if (acpi_lapic && acpi_ioapic) smp_found_config = 1;
- * if acpi_blacklisted() acpi_disabled = 1;
+ * if acpi_blacklisted() disable_acpi()
* acpi_irq_model=...
* ...
*
@@ -334,14 +395,14 @@
*/
result = acpi_table_init();
if (result) {
- acpi_disabled = 1;
+ disable_acpi();
return result;
}
result = acpi_blacklisted();
if (result) {
printk(KERN_NOTICE PREFIX "BIOS listed in blacklist, disabling ACPI support\n");
- acpi_disabled = 1;
+ disable_acpi();
return result;
}
@@ -444,6 +505,9 @@
/* Build a default routing table for legacy (ISA) interrupts. */
mp_config_acpi_legacy_irqs();
+ /* Record sci_int for use when looking for MADT sci_int override */
+ acpi_table_parse(ACPI_FADT, acpi_parse_fadt);
+
result = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr);
if (result < 0) {
printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");
@@ -451,6 +515,13 @@
return result;
}
+ /*
+ * If BIOS did not supply an INT_SRC_OVR for the SCI
+ * pretend we got one so we can set the SCI flags.
+ */
+ if (!acpi_sci_override_gsi)
+ acpi_sci_ioapic_setup(acpi_fadt.sci_int, 0, 0);
+
result = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src);
if (result < 0) {
printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
@@ -472,17 +543,15 @@
return 0;
}
-#endif /*CONFIG_ACPI_BOOT*/
#ifdef CONFIG_ACPI_BUS
/*
- * "acpi_pic_sci=level" (current default)
- * programs the PIC-mode SCI to Level Trigger.
- * (NO-OP if the BIOS set Level Trigger already)
- *
- * If a PIC-mode SCI is not recogznied or gives spurious IRQ7's
- * it may require Edge Trigger -- use "acpi_pic_sci=edge"
- * (NO-OP if the BIOS set Edge Trigger already)
+ * acpi_pic_sci_set_trigger()
+ *
+ * use ELCR to set PIC-mode trigger type for SCI
+ *
+ * If a PIC-mode SCI is not recognized or gives spurious IRQ7's
+ * it may require Edge Trigger -- use "acpi_sci=edge"
*
* Port 0x4d0-4d1 are ECLR1 and ECLR2, the Edge/Level Control Registers
* for the 8259 PIC. bit[n] = 1 means irq[n] is Level, otherwise Edge.
@@ -490,56 +559,41 @@
* ECLR2 is IRQ's 8-15 (IRQ 8, 13 must be 0)
*/
-static __initdata int acpi_pic_sci_trigger; /* 0: level, 1: edge */
-
void __init
-acpi_pic_sci_set_trigger(unsigned int irq)
+acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
{
unsigned char mask = 1 << (irq & 7);
unsigned int port = 0x4d0 + (irq >> 3);
unsigned char val = inb(port);
-
+
printk(PREFIX "IRQ%d SCI:", irq);
if (!(val & mask)) {
printk(" Edge");
- if (!acpi_pic_sci_trigger) {
+ if (trigger == 3) {
printk(" set to Level");
outb(val | mask, port);
}
} else {
printk(" Level");
- if (acpi_pic_sci_trigger) {
+ if (trigger == 1) {
printk(" set to Edge");
- outb(val | mask, port);
+ outb(val & ~mask, port);
}
}
printk(" Trigger.\n");
}
-int __init
-acpi_pic_sci_setup(char *str)
-{
- while (str && *str) {
- if (strncmp(str, "level", 5) == 0)
- acpi_pic_sci_trigger = 0; /* force level trigger */
- if (strncmp(str, "edge", 4) == 0)
- acpi_pic_sci_trigger = 1; /* force edge trigger */
- str = strchr(str, ',');
- if (str)
- str += strspn(str, ", \t");
- }
- return 1;
-}
-
-__setup("acpi_pic_sci=", acpi_pic_sci_setup);
-
#endif /* CONFIG_ACPI_BUS */
+#ifndef __HAVE_ARCH_CMPXCHG
+#warning ACPI uses CMPXCHG, i486 and later hardware
+#endif
+
/* --------------------------------------------------------------------------
Low-Level Sleep Support
-------------------------------------------------------------------------- */
@@ -656,7 +710,8 @@
void __init acpi_reserve_bootmem(void)
{
acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE);
- printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address);
+ if (!acpi_wakeup_address)
+ printk(KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n");
}
void do_suspend_lowlevel_s4bios(int resume)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)