x86, UV: add uv_setup_irq() and uv_teardown_irq() functions, v3
[safe/jmp/linux-2.6] / arch / x86 / kernel / uv_irq.c
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * SGI UV IRQ functions
7  *
8  * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved.
9  */
10
11 #include <linux/module.h>
12 #include <linux/irq.h>
13 #include <asm/uv/uv_irq.h>
14
15 static void uv_noop(unsigned int irq)
16 {
17 }
18
19 static unsigned int uv_noop_ret(unsigned int irq)
20 {
21         return 0;
22 }
23
24 static void uv_ack_apic(unsigned int irq)
25 {
26         ack_APIC_irq();
27 }
28
29 struct irq_chip uv_irq_chip = {
30         .name           = "UV-CORE",
31         .startup        = uv_noop_ret,
32         .shutdown       = uv_noop,
33         .enable         = uv_noop,
34         .disable        = uv_noop,
35         .ack            = uv_noop,
36         .mask           = uv_noop,
37         .unmask         = uv_noop,
38         .eoi            = uv_ack_apic,
39         .end            = uv_noop,
40 };
41
42 /*
43  * Set up a mapping of an available irq and vector, and enable the specified
44  * MMR that defines the MSI that is to be sent to the specified CPU when an
45  * interrupt is raised.
46  */
47 int uv_setup_irq(char *irq_name, int cpu, int mmr_blade,
48                  unsigned long mmr_offset)
49 {
50         int irq;
51         int ret;
52
53         irq = create_irq();
54         if (irq <= 0)
55                 return -EBUSY;
56
57         ret = arch_enable_uv_irq(irq_name, irq, cpu, mmr_blade, mmr_offset);
58         if (ret != irq)
59                 destroy_irq(irq);
60
61         return ret;
62 }
63 EXPORT_SYMBOL_GPL(uv_setup_irq);
64
65 /*
66  * Tear down a mapping of an irq and vector, and disable the specified MMR that
67  * defined the MSI that was to be sent to the specified CPU when an interrupt
68  * was raised.
69  *
70  * Set mmr_blade and mmr_offset to what was passed in on uv_setup_irq().
71  */
72 void uv_teardown_irq(unsigned int irq, int mmr_blade, unsigned long mmr_offset)
73 {
74         arch_disable_uv_irq(mmr_blade, mmr_offset);
75         destroy_irq(irq);
76 }
77 EXPORT_SYMBOL_GPL(uv_teardown_irq);