diff options
Diffstat (limited to 'arch/ia64/kernel/msi_ia64.c')
-rw-r--r-- | arch/ia64/kernel/msi_ia64.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c index c81080df70df..2fdbd5c3f213 100644 --- a/arch/ia64/kernel/msi_ia64.c +++ b/arch/ia64/kernel/msi_ia64.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #define MSI_DATA_VECTOR_SHIFT 0 | 14 | #define MSI_DATA_VECTOR_SHIFT 0 |
15 | #define MSI_DATA_VECTOR(v) (((u8)v) << MSI_DATA_VECTOR_SHIFT) | 15 | #define MSI_DATA_VECTOR(v) (((u8)v) << MSI_DATA_VECTOR_SHIFT) |
16 | #define MSI_DATA_VECTOR_MASK 0xffffff00 | ||
16 | 17 | ||
17 | #define MSI_DATA_DELIVERY_SHIFT 8 | 18 | #define MSI_DATA_DELIVERY_SHIFT 8 |
18 | #define MSI_DATA_DELIVERY_FIXED (0 << MSI_DATA_DELIVERY_SHIFT) | 19 | #define MSI_DATA_DELIVERY_FIXED (0 << MSI_DATA_DELIVERY_SHIFT) |
@@ -50,17 +51,29 @@ static struct irq_chip ia64_msi_chip; | |||
50 | static void ia64_set_msi_irq_affinity(unsigned int irq, cpumask_t cpu_mask) | 51 | static void ia64_set_msi_irq_affinity(unsigned int irq, cpumask_t cpu_mask) |
51 | { | 52 | { |
52 | struct msi_msg msg; | 53 | struct msi_msg msg; |
53 | u32 addr; | 54 | u32 addr, data; |
55 | int cpu = first_cpu(cpu_mask); | ||
56 | |||
57 | if (!cpu_online(cpu)) | ||
58 | return; | ||
59 | |||
60 | if (reassign_irq_vector(irq, cpu)) | ||
61 | return; | ||
54 | 62 | ||
55 | read_msi_msg(irq, &msg); | 63 | read_msi_msg(irq, &msg); |
56 | 64 | ||
57 | addr = msg.address_lo; | 65 | addr = msg.address_lo; |
58 | addr &= MSI_ADDR_DESTID_MASK; | 66 | addr &= MSI_ADDR_DESTID_MASK; |
59 | addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(first_cpu(cpu_mask))); | 67 | addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(cpu)); |
60 | msg.address_lo = addr; | 68 | msg.address_lo = addr; |
61 | 69 | ||
70 | data = msg.data; | ||
71 | data &= MSI_DATA_VECTOR_MASK; | ||
72 | data |= MSI_DATA_VECTOR(irq_to_vector(irq)); | ||
73 | msg.data = data; | ||
74 | |||
62 | write_msi_msg(irq, &msg); | 75 | write_msi_msg(irq, &msg); |
63 | irq_desc[irq].affinity = cpu_mask; | 76 | irq_desc[irq].affinity = cpumask_of_cpu(cpu); |
64 | } | 77 | } |
65 | #endif /* CONFIG_SMP */ | 78 | #endif /* CONFIG_SMP */ |
66 | 79 | ||
@@ -69,13 +82,15 @@ int ia64_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) | |||
69 | struct msi_msg msg; | 82 | struct msi_msg msg; |
70 | unsigned long dest_phys_id; | 83 | unsigned long dest_phys_id; |
71 | int irq, vector; | 84 | int irq, vector; |
85 | cpumask_t mask; | ||
72 | 86 | ||
73 | irq = create_irq(); | 87 | irq = create_irq(); |
74 | if (irq < 0) | 88 | if (irq < 0) |
75 | return irq; | 89 | return irq; |
76 | 90 | ||
77 | set_irq_msi(irq, desc); | 91 | set_irq_msi(irq, desc); |
78 | dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map)); | 92 | cpus_and(mask, irq_to_domain(irq), cpu_online_map); |
93 | dest_phys_id = cpu_physical_id(first_cpu(mask)); | ||
79 | vector = irq_to_vector(irq); | 94 | vector = irq_to_vector(irq); |
80 | 95 | ||
81 | msg.address_hi = 0; | 96 | msg.address_hi = 0; |