aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/io_apic.c
diff options
context:
space:
mode:
authorvenkatesh.pallipadi@intel.com <venkatesh.pallipadi@intel.com>2008-09-05 21:02:17 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-16 10:53:07 -0400
commit58ac1e76ce77d515bd5cb65dbc465a040da341c6 (patch)
treee1bd9e60aaaa5098ea368c04043adf2a79fca604 /arch/x86/kernel/io_apic.c
parentb40d575bf0679c45aaf9e1161fc51a6b041b7210 (diff)
x86: HPET_MSI Basic HPET_MSI setup code
Basic HPET MSI setup code. Routines to perform basic MSI read write in HPET memory map and setting up irq_chip for HPET MSI. Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> Signed-off-by: Shaohua Li <shaohua.li@intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/io_apic.c')
-rw-r--r--arch/x86/kernel/io_apic.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c
index d22fecf828b8..77fa155becf6 100644
--- a/arch/x86/kernel/io_apic.c
+++ b/arch/x86/kernel/io_apic.c
@@ -41,6 +41,7 @@
41#endif 41#endif
42#include <linux/bootmem.h> 42#include <linux/bootmem.h>
43#include <linux/dmar.h> 43#include <linux/dmar.h>
44#include <linux/hpet.h>
44 45
45#include <asm/idle.h> 46#include <asm/idle.h>
46#include <asm/io.h> 47#include <asm/io.h>
@@ -56,6 +57,7 @@
56#include <asm/hypertransport.h> 57#include <asm/hypertransport.h>
57#include <asm/setup.h> 58#include <asm/setup.h>
58#include <asm/irq_remapping.h> 59#include <asm/irq_remapping.h>
60#include <asm/hpet.h>
59 61
60#include <mach_ipi.h> 62#include <mach_ipi.h>
61#include <mach_apic.h> 63#include <mach_apic.h>
@@ -3522,6 +3524,68 @@ int arch_setup_dmar_msi(unsigned int irq)
3522} 3524}
3523#endif 3525#endif
3524 3526
3527#ifdef CONFIG_HPET_TIMER
3528
3529#ifdef CONFIG_SMP
3530static void hpet_msi_set_affinity(unsigned int irq, cpumask_t mask)
3531{
3532 struct irq_cfg *cfg;
3533 struct irq_desc *desc;
3534 struct msi_msg msg;
3535 unsigned int dest;
3536 cpumask_t tmp;
3537
3538 cpus_and(tmp, mask, cpu_online_map);
3539 if (cpus_empty(tmp))
3540 return;
3541
3542 if (assign_irq_vector(irq, mask))
3543 return;
3544
3545 cfg = irq_cfg(irq);
3546 cpus_and(tmp, cfg->domain, mask);
3547 dest = cpu_mask_to_apicid(tmp);
3548
3549 hpet_msi_read(irq, &msg);
3550
3551 msg.data &= ~MSI_DATA_VECTOR_MASK;
3552 msg.data |= MSI_DATA_VECTOR(cfg->vector);
3553 msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
3554 msg.address_lo |= MSI_ADDR_DEST_ID(dest);
3555
3556 hpet_msi_write(irq, &msg);
3557 desc = irq_to_desc(irq);
3558 desc->affinity = mask;
3559}
3560#endif /* CONFIG_SMP */
3561
3562struct irq_chip hpet_msi_type = {
3563 .name = "HPET_MSI",
3564 .unmask = hpet_msi_unmask,
3565 .mask = hpet_msi_mask,
3566 .ack = ack_apic_edge,
3567#ifdef CONFIG_SMP
3568 .set_affinity = hpet_msi_set_affinity,
3569#endif
3570 .retrigger = ioapic_retrigger_irq,
3571};
3572
3573int arch_setup_hpet_msi(unsigned int irq)
3574{
3575 int ret;
3576 struct msi_msg msg;
3577
3578 ret = msi_compose_msg(NULL, irq, &msg);
3579 if (ret < 0)
3580 return ret;
3581
3582 hpet_msi_write(irq, &msg);
3583 set_irq_chip_and_handler_name(irq, &hpet_msi_type, handle_edge_irq,
3584 "edge");
3585 return 0;
3586}
3587#endif
3588
3525#endif /* CONFIG_PCI_MSI */ 3589#endif /* CONFIG_PCI_MSI */
3526/* 3590/*
3527 * Hypertransport interrupt support 3591 * Hypertransport interrupt support