aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/io_apic.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2006-10-04 05:16:55 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 10:55:29 -0400
commit8b955b0dddb35e398b07e217a81f8bd49400796f (patch)
tree6fc307371b6889ac08fa5a7187cde1c137c8d765 /arch/i386/kernel/io_apic.c
parente78d01693be38bf93dd6bb49b86e143da450de86 (diff)
[PATCH] Initial generic hypertransport interrupt support
This patch implements two functions ht_create_irq and ht_destroy_irq for use by drivers. Several other functions are implemented as helpers for arch specific irq_chip handlers. The driver for the card I tested this on isn't yet ready to be merged. However this code is and hypertransport irqs are in use in a few other places in the kernel. Not that any of this will get merged before 2.6.19 Because the ipath-ht400 is slightly out of spec this code will need to be generalized to work there. I think all of the powerpc uses are for a plain interrupt controller in a chipset so support for native hypertransport devices is a little less interesting. However I think this is a half way decent model on how to separate arch specific and generic helper code, and I think this is a functional model of how to get the architecture dependencies out of the msi code. [akpm@osdl.org: Kconfig fix] Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Cc: Greg KH <greg@kroah.com> Cc: Andi Kleen <ak@muc.de> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386/kernel/io_apic.c')
-rw-r--r--arch/i386/kernel/io_apic.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 03e7606be6e6..100406b453b8 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -40,6 +40,7 @@
40#include <asm/i8259.h> 40#include <asm/i8259.h>
41#include <asm/nmi.h> 41#include <asm/nmi.h>
42#include <asm/msidef.h> 42#include <asm/msidef.h>
43#include <asm/hypertransport.h>
43 44
44#include <mach_apic.h> 45#include <mach_apic.h>
45#include <mach_apicdef.h> 46#include <mach_apicdef.h>
@@ -2518,6 +2519,95 @@ struct msi_ops arch_msi_ops = {
2518 2519
2519#endif /* CONFIG_PCI_MSI */ 2520#endif /* CONFIG_PCI_MSI */
2520 2521
2522/*
2523 * Hypertransport interrupt support
2524 */
2525#ifdef CONFIG_HT_IRQ
2526
2527#ifdef CONFIG_SMP
2528
2529static void target_ht_irq(unsigned int irq, unsigned int dest)
2530{
2531 u32 low, high;
2532 low = read_ht_irq_low(irq);
2533 high = read_ht_irq_high(irq);
2534
2535 low &= ~(HT_IRQ_LOW_DEST_ID_MASK);
2536 high &= ~(HT_IRQ_HIGH_DEST_ID_MASK);
2537
2538 low |= HT_IRQ_LOW_DEST_ID(dest);
2539 high |= HT_IRQ_HIGH_DEST_ID(dest);
2540
2541 write_ht_irq_low(irq, low);
2542 write_ht_irq_high(irq, high);
2543}
2544
2545static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask)
2546{
2547 unsigned int dest;
2548 cpumask_t tmp;
2549
2550 cpus_and(tmp, mask, cpu_online_map);
2551 if (cpus_empty(tmp))
2552 tmp = TARGET_CPUS;
2553
2554 cpus_and(mask, tmp, CPU_MASK_ALL);
2555
2556 dest = cpu_mask_to_apicid(mask);
2557
2558 target_ht_irq(irq, dest);
2559 set_native_irq_info(irq, mask);
2560}
2561#endif
2562
2563static struct hw_interrupt_type ht_irq_chip = {
2564 .name = "PCI-HT",
2565 .mask = mask_ht_irq,
2566 .unmask = unmask_ht_irq,
2567 .ack = ack_ioapic_irq,
2568#ifdef CONFIG_SMP
2569 .set_affinity = set_ht_irq_affinity,
2570#endif
2571 .retrigger = ioapic_retrigger_irq,
2572};
2573
2574int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
2575{
2576 int vector;
2577
2578 vector = assign_irq_vector(irq);
2579 if (vector >= 0) {
2580 u32 low, high;
2581 unsigned dest;
2582 cpumask_t tmp;
2583
2584 cpus_clear(tmp);
2585 cpu_set(vector >> 8, tmp);
2586 dest = cpu_mask_to_apicid(tmp);
2587
2588 high = HT_IRQ_HIGH_DEST_ID(dest);
2589
2590 low = HT_IRQ_LOW_BASE |
2591 HT_IRQ_LOW_DEST_ID(dest) |
2592 HT_IRQ_LOW_VECTOR(vector) |
2593 ((INT_DEST_MODE == 0) ?
2594 HT_IRQ_LOW_DM_PHYSICAL :
2595 HT_IRQ_LOW_DM_LOGICAL) |
2596 HT_IRQ_LOW_RQEOI_EDGE |
2597 ((INT_DELIVERY_MODE != dest_LowestPrio) ?
2598 HT_IRQ_LOW_MT_FIXED :
2599 HT_IRQ_LOW_MT_ARBITRATED) |
2600 HT_IRQ_LOW_IRQ_MASKED;
2601
2602 write_ht_irq_low(irq, low);
2603 write_ht_irq_high(irq, high);
2604
2605 set_irq_chip_and_handler(irq, &ht_irq_chip, handle_edge_irq);
2606 }
2607 return vector;
2608}
2609#endif /* CONFIG_HT_IRQ */
2610
2521/* -------------------------------------------------------------------------- 2611/* --------------------------------------------------------------------------
2522 ACPI-based IOAPIC Configuration 2612 ACPI-based IOAPIC Configuration
2523 -------------------------------------------------------------------------- */ 2613 -------------------------------------------------------------------------- */