diff options
author | Dean Nelson <dcn@sgi.com> | 2008-10-02 13:18:21 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-16 10:53:12 -0400 |
commit | 4173a0e7371ece227559b44943c6fd456ee470d1 (patch) | |
tree | e9a6dd475bfc72b373c1db13c21c8d82591636ec /arch/x86/kernel/io_apic.c | |
parent | 5f79f2f2ad39b5177c52ed08ffd066ea0c1da924 (diff) |
x86, UV: add uv_setup_irq() and uv_teardown_irq() functions, v3
Provide a means for UV interrupt MMRs to be setup with the message to be sent
when an MSI is raised.
Signed-off-by: Dean Nelson <dcn@sgi.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.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c index 4ee270d30358..260c95a5e6dc 100644 --- a/arch/x86/kernel/io_apic.c +++ b/arch/x86/kernel/io_apic.c | |||
@@ -58,6 +58,8 @@ | |||
58 | #include <asm/setup.h> | 58 | #include <asm/setup.h> |
59 | #include <asm/irq_remapping.h> | 59 | #include <asm/irq_remapping.h> |
60 | #include <asm/hpet.h> | 60 | #include <asm/hpet.h> |
61 | #include <asm/uv/uv_hub.h> | ||
62 | #include <asm/uv/uv_irq.h> | ||
61 | 63 | ||
62 | #include <mach_ipi.h> | 64 | #include <mach_ipi.h> |
63 | #include <mach_apic.h> | 65 | #include <mach_apic.h> |
@@ -3692,6 +3694,72 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) | |||
3692 | } | 3694 | } |
3693 | #endif /* CONFIG_HT_IRQ */ | 3695 | #endif /* CONFIG_HT_IRQ */ |
3694 | 3696 | ||
3697 | #ifdef CONFIG_X86_64 | ||
3698 | /* | ||
3699 | * Re-target the irq to the specified CPU and enable the specified MMR located | ||
3700 | * on the specified blade to allow the sending of MSIs to the specified CPU. | ||
3701 | */ | ||
3702 | int arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, | ||
3703 | unsigned long mmr_offset) | ||
3704 | { | ||
3705 | const cpumask_t *eligible_cpu = get_cpu_mask(cpu); | ||
3706 | struct irq_cfg *cfg; | ||
3707 | int mmr_pnode; | ||
3708 | unsigned long mmr_value; | ||
3709 | struct uv_IO_APIC_route_entry *entry; | ||
3710 | unsigned long flags; | ||
3711 | int err; | ||
3712 | |||
3713 | err = assign_irq_vector(irq, *eligible_cpu); | ||
3714 | if (err != 0) | ||
3715 | return err; | ||
3716 | |||
3717 | spin_lock_irqsave(&vector_lock, flags); | ||
3718 | set_irq_chip_and_handler_name(irq, &uv_irq_chip, handle_percpu_irq, | ||
3719 | irq_name); | ||
3720 | spin_unlock_irqrestore(&vector_lock, flags); | ||
3721 | |||
3722 | cfg = irq_cfg(irq); | ||
3723 | |||
3724 | mmr_value = 0; | ||
3725 | entry = (struct uv_IO_APIC_route_entry *)&mmr_value; | ||
3726 | BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long)); | ||
3727 | |||
3728 | entry->vector = cfg->vector; | ||
3729 | entry->delivery_mode = INT_DELIVERY_MODE; | ||
3730 | entry->dest_mode = INT_DEST_MODE; | ||
3731 | entry->polarity = 0; | ||
3732 | entry->trigger = 0; | ||
3733 | entry->mask = 0; | ||
3734 | entry->dest = cpu_mask_to_apicid(*eligible_cpu); | ||
3735 | |||
3736 | mmr_pnode = uv_blade_to_pnode(mmr_blade); | ||
3737 | uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value); | ||
3738 | |||
3739 | return irq; | ||
3740 | } | ||
3741 | |||
3742 | /* | ||
3743 | * Disable the specified MMR located on the specified blade so that MSIs are | ||
3744 | * longer allowed to be sent. | ||
3745 | */ | ||
3746 | void arch_disable_uv_irq(int mmr_blade, unsigned long mmr_offset) | ||
3747 | { | ||
3748 | unsigned long mmr_value; | ||
3749 | struct uv_IO_APIC_route_entry *entry; | ||
3750 | int mmr_pnode; | ||
3751 | |||
3752 | mmr_value = 0; | ||
3753 | entry = (struct uv_IO_APIC_route_entry *)&mmr_value; | ||
3754 | BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long)); | ||
3755 | |||
3756 | entry->mask = 1; | ||
3757 | |||
3758 | mmr_pnode = uv_blade_to_pnode(mmr_blade); | ||
3759 | uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value); | ||
3760 | } | ||
3761 | #endif /* CONFIG_X86_64 */ | ||
3762 | |||
3695 | int __init io_apic_get_redir_entries (int ioapic) | 3763 | int __init io_apic_get_redir_entries (int ioapic) |
3696 | { | 3764 | { |
3697 | union IO_APIC_reg_01 reg_01; | 3765 | union IO_APIC_reg_01 reg_01; |