Commit 4effe89c authored by Alex Williamson's avatar Alex Williamson Committed by David Mosberger

[PATCH] ia64: interrupt fixes/cleanup

Here's some cleanups/fixes/changes for interrupts on 2.5.67 + ia64.
Specifically:

  - Cleanup some ugliness with polarity/trigger setup.

  - Add iosapic_enable_intr() to set_rte on an interupt when the
    device is enabled.  IMHO, we really only want to unmask RTEs
    for PRTs we might actually use.  This moves the interrupt
    distribution here too.

  - When changing a vector from edge to level, call register_intr()
    to do it so all the data structures get set correctly.  If we
    have to guess how to setup an interupt and get it wrong, this
    should close some holes in changing it back to the correct type.

  - Register the HCDP interrupt in 8250_hcdp - this is where we have
    to guess the polarity/trigger.  The real handler will get fixed
    up via PCI setup or ACPI namespace serial support, this gets it
    associated w/ the port at setup.  This should allow interrupts
    to work when using builtin UARTs as console on HP Itanium2 boxes.
parent 8e53f7e0
......@@ -922,8 +922,7 @@ acpi_register_irq (u32 gsi, u32 polarity, u32 trigger)
return 0;
/* Turn it on */
vector = iosapic_register_intr (gsi, polarity ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
trigger ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
vector = iosapic_register_intr (gsi, polarity, trigger);
return vector;
}
......
......@@ -644,20 +644,11 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
}
}
static void __init
fixup_vector (int vector, unsigned int gsi, const char *pci_id)
void
iosapic_enable_intr (unsigned int vector)
{
struct hw_interrupt_type *irq_type = &irq_type_iosapic_level;
irq_desc_t *idesc;
unsigned int dest;
idesc = irq_desc(vector);
if (idesc->handler != irq_type) {
if (idesc->handler != &no_irq_type)
printk(KERN_INFO "IOSAPIC: changing vector %d from %s to %s\n",
vector, idesc->handler->typename, irq_type->typename);
idesc->handler = irq_type;
}
#ifdef CONFIG_SMP
/*
* For platforms that do not support interrupt redirect via the XTP interface, we
......@@ -685,8 +676,8 @@ fixup_vector (int vector, unsigned int gsi, const char *pci_id)
#endif
set_rte(vector, dest);
printk(KERN_INFO "IOSAPIC: %s -> GSI 0x%x -> CPU 0x%04x vector %d\n",
pci_id, gsi, dest, vector);
printk(KERN_INFO "IOSAPIC: vector %d -> CPU 0x%04x, enabled\n",
vector, dest);
}
void __init
......@@ -697,6 +688,8 @@ iosapic_parse_prt (void)
unsigned int gsi;
int vector;
char pci_id[16];
struct hw_interrupt_type *irq_type = &irq_type_iosapic_level;
irq_desc_t *idesc;
list_for_each(node, &acpi_prt.entries) {
entry = list_entry(node, struct acpi_prt_entry, node);
......@@ -724,6 +717,13 @@ iosapic_parse_prt (void)
snprintf(pci_id, sizeof(pci_id), "%02x:%02x:%02x[%c]",
entry->id.segment, entry->id.bus, entry->id.device, 'A' + entry->pin);
fixup_vector(vector, gsi, pci_id);
/*
* If vector was previously initialized to a different
* handler, re-initialize.
*/
idesc = irq_desc(vector);
if (idesc->handler != irq_type)
register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW, IOSAPIC_LEVEL);
}
}
......@@ -57,6 +57,7 @@ extern void __init iosapic_init (unsigned long address,
extern int gsi_to_vector (unsigned int gsi);
extern int gsi_to_irq (unsigned int gsi);
extern void __init iosapic_parse_prt (void);
extern void iosapic_enable_intr (unsigned int vector);
extern int iosapic_register_intr (unsigned int gsi, unsigned long polarity,
unsigned long trigger);
extern void __init iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment