aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/msi-apic.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2006-10-04 05:16:59 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 10:55:29 -0400
commit3b7d1921f4cdd6d6ddb7899ae7a8d413991c5cf4 (patch)
tree5f809e0c4310f60dfa6f65d54fbaf9f01e2ebff9 /drivers/pci/msi-apic.c
parent277bc33bc2479707e88b0b2ae6fe56e8e4aabe81 (diff)
[PATCH] msi: refactor and move the msi irq_chip into the arch code
It turns out msi_ops was simply not enough to abstract the architecture specific details of msi. So I have moved the resposibility of constructing the struct irq_chip to the architectures, and have two architecture specific functions arch_setup_msi_irq, and arch_teardown_msi_irq. For simple architectures those functions can do all of the work. For architectures with platform dependencies they can call into the appropriate platform code. With this msi.c is finally free of assuming you have an apic, and this actually takes less code. The helpers for the architecture specific code are declared in the linux/msi.h to keep them separate from the msi functions used by drivers in linux/pci.h Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Tony Luck <tony.luck@intel.com> Cc: Andi Kleen <ak@suse.de> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Greg KH <greg@kroah.com> 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 'drivers/pci/msi-apic.c')
-rw-r--r--drivers/pci/msi-apic.c86
1 files changed, 64 insertions, 22 deletions
diff --git a/drivers/pci/msi-apic.c b/drivers/pci/msi-apic.c
index afc0ed13aa89..822e59a1b822 100644
--- a/drivers/pci/msi-apic.c
+++ b/drivers/pci/msi-apic.c
@@ -4,10 +4,9 @@
4 4
5#include <linux/pci.h> 5#include <linux/pci.h>
6#include <linux/irq.h> 6#include <linux/irq.h>
7#include <linux/msi.h>
7#include <asm/smp.h> 8#include <asm/smp.h>
8 9
9#include "msi.h"
10
11/* 10/*
12 * Shifts for APIC-based data 11 * Shifts for APIC-based data
13 */ 12 */
@@ -31,6 +30,7 @@
31 * Shift/mask fields for APIC-based bus address 30 * Shift/mask fields for APIC-based bus address
32 */ 31 */
33 32
33#define MSI_TARGET_CPU_SHIFT 4
34#define MSI_ADDR_HEADER 0xfee00000 34#define MSI_ADDR_HEADER 0xfee00000
35 35
36#define MSI_ADDR_DESTID_MASK 0xfff0000f 36#define MSI_ADDR_DESTID_MASK 0xfff0000f
@@ -44,58 +44,100 @@
44#define MSI_ADDR_REDIRECTION_CPU (0 << MSI_ADDR_REDIRECTION_SHIFT) 44#define MSI_ADDR_REDIRECTION_CPU (0 << MSI_ADDR_REDIRECTION_SHIFT)
45#define MSI_ADDR_REDIRECTION_LOWPRI (1 << MSI_ADDR_REDIRECTION_SHIFT) 45#define MSI_ADDR_REDIRECTION_LOWPRI (1 << MSI_ADDR_REDIRECTION_SHIFT)
46 46
47static struct irq_chip ia64_msi_chip;
47 48
48static void 49#ifdef CONFIG_SMP
49msi_target_apic(unsigned int irq, cpumask_t cpu_mask, struct msi_msg *msg) 50static void ia64_set_msi_irq_affinity(unsigned int irq, cpumask_t cpu_mask)
50{ 51{
51 u32 addr = msg->address_lo; 52 struct msi_msg msg;
53 u32 addr;
54
55 read_msi_msg(irq, &msg);
52 56
57 addr = msg.address_lo;
53 addr &= MSI_ADDR_DESTID_MASK; 58 addr &= MSI_ADDR_DESTID_MASK;
54 addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(first_cpu(cpu_mask))); 59 addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(first_cpu(cpu_mask)));
60 msg.address_lo = addr;
55 61
56 msg->address_lo = addr; 62 write_msi_msg(irq, &msg);
63 set_native_irq_info(irq, cpu_mask);
57} 64}
65#endif /* CONFIG_SMP */
58 66
59static int 67int ia64_setup_msi_irq(unsigned int irq, struct pci_dev *pdev)
60msi_setup_apic(struct pci_dev *pdev, /* unused in generic */
61 unsigned int irq,
62 struct msi_msg *msg)
63{ 68{
69 struct msi_msg msg;
64 unsigned long dest_phys_id; 70 unsigned long dest_phys_id;
65 unsigned int vector; 71 unsigned int vector;
66 72
67 dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map)); 73 dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map));
68 vector = irq; 74 vector = irq;
69 75
70 msg->address_hi = 0; 76 msg.address_hi = 0;
71 msg->address_lo = 77 msg.address_lo =
72 MSI_ADDR_HEADER | 78 MSI_ADDR_HEADER |
73 MSI_ADDR_DESTMODE_PHYS | 79 MSI_ADDR_DESTMODE_PHYS |
74 MSI_ADDR_REDIRECTION_CPU | 80 MSI_ADDR_REDIRECTION_CPU |
75 MSI_ADDR_DESTID_CPU(dest_phys_id); 81 MSI_ADDR_DESTID_CPU(dest_phys_id);
76 82
77 msg->data = 83 msg.data =
78 MSI_DATA_TRIGGER_EDGE | 84 MSI_DATA_TRIGGER_EDGE |
79 MSI_DATA_LEVEL_ASSERT | 85 MSI_DATA_LEVEL_ASSERT |
80 MSI_DATA_DELIVERY_FIXED | 86 MSI_DATA_DELIVERY_FIXED |
81 MSI_DATA_VECTOR(vector); 87 MSI_DATA_VECTOR(vector);
82 88
89 write_msi_msg(irq, &msg);
90 set_irq_chip_and_handler(irq, &ia64_msi_chip, handle_edge_irq);
91
83 return 0; 92 return 0;
84} 93}
85 94
86static void 95void ia64_teardown_msi_irq(unsigned int irq)
87msi_teardown_apic(unsigned int irq)
88{ 96{
89 return; /* no-op */ 97 return; /* no-op */
90} 98}
91 99
100static void ia64_ack_msi_irq(unsigned int irq)
101{
102 move_native_irq(irq);
103 ia64_eoi();
104}
105
106static int ia64_msi_retrigger_irq(unsigned int irq)
107{
108 unsigned int vector = irq;
109 ia64_resend_irq(vector);
110
111 return 1;
112}
113
92/* 114/*
93 * Generic ops used on most IA archs/platforms. Set with msi_register() 115 * Generic ops used on most IA64 platforms.
94 */ 116 */
95 117static struct irq_chip ia64_msi_chip = {
96struct msi_ops msi_apic_ops = { 118 .name = "PCI-MSI",
97 .needs_64bit_address = 0, 119 .mask = mask_msi_irq,
98 .setup = msi_setup_apic, 120 .unmask = unmask_msi_irq,
99 .teardown = msi_teardown_apic, 121 .ack = ia64_ack_msi_irq,
100 .target = msi_target_apic, 122#ifdef CONFIG_SMP
123 .set_affinity = ia64_set_msi_irq_affinity,
124#endif
125 .retrigger = ia64_msi_retrigger_irq,
101}; 126};
127
128
129int arch_setup_msi_irq(unsigned int irq, struct pci_dev *pdev)
130{
131 if (platform_setup_msi_irq)
132 return platform_setup_msi_irq(irq, pdev);
133
134 return ia64_setup_msi_irq(irq, pdev);
135}
136
137void arch_teardown_msi_irq(unsigned int irq)
138{
139 if (platform_teardown_msi_irq)
140 return platform_teardown_msi_irq(irq);
141
142 return ia64_teardown_msi_irq(irq);
143}