Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
irq_remapping.c
Go to the documentation of this file.
1 #include <linux/kernel.h>
2 #include <linux/string.h>
3 #include <linux/cpumask.h>
4 #include <linux/errno.h>
5 #include <linux/msi.h>
6 
7 #include <asm/hw_irq.h>
8 #include <asm/irq_remapping.h>
9 
10 #include "irq_remapping.h"
11 
13 
17 
18 static struct irq_remap_ops *remap_ops;
19 
20 static __init int setup_nointremap(char *str)
21 {
23  return 0;
24 }
25 early_param("nointremap", setup_nointremap);
26 
27 static __init int setup_irqremap(char *str)
28 {
29  if (!str)
30  return -EINVAL;
31 
32  while (*str) {
33  if (!strncmp(str, "on", 2))
35  else if (!strncmp(str, "off", 3))
37  else if (!strncmp(str, "nosid", 5))
39  else if (!strncmp(str, "no_x2apic_optout", 16))
40  no_x2apic_optout = 1;
41 
42  str += strcspn(str, ",");
43  while (*str == ',')
44  str++;
45  }
46 
47  return 0;
48 }
49 early_param("intremap", setup_irqremap);
50 
52 {
53  remap_ops = &intel_irq_remap_ops;
54 
55 #ifdef CONFIG_AMD_IOMMU
56  if (amd_iommu_irq_ops.prepare() == 0)
57  remap_ops = &amd_iommu_irq_ops;
58 #endif
59 }
60 
62 {
64  return 0;
65 
66  if (!remap_ops || !remap_ops->supported)
67  return 0;
68 
69  return remap_ops->supported();
70 }
71 
73 {
74  if (!remap_ops || !remap_ops->prepare)
75  return -ENODEV;
76 
77  return remap_ops->prepare();
78 }
79 
81 {
82  if (!remap_ops || !remap_ops->enable)
83  return -ENODEV;
84 
85  return remap_ops->enable();
86 }
87 
89 {
90  if (!remap_ops || !remap_ops->disable)
91  return;
92 
93  remap_ops->disable();
94 }
95 
97 {
98  if (!remap_ops || !remap_ops->reenable)
99  return 0;
100 
101  return remap_ops->reenable(mode);
102 }
103 
105 {
106  if (!remap_ops || !remap_ops->enable_faulting)
107  return -ENODEV;
108 
109  return remap_ops->enable_faulting();
110 }
111 
113  struct IO_APIC_route_entry *entry,
114  unsigned int destination, int vector,
115  struct io_apic_irq_attr *attr)
116 {
117  if (!remap_ops || !remap_ops->setup_ioapic_entry)
118  return -ENODEV;
119 
120  return remap_ops->setup_ioapic_entry(irq, entry, destination,
121  vector, attr);
122 }
123 
125  bool force)
126 {
127  if (!config_enabled(CONFIG_SMP) || !remap_ops ||
128  !remap_ops->set_affinity)
129  return 0;
130 
131  return remap_ops->set_affinity(data, mask, force);
132 }
133 
134 void free_remapped_irq(int irq)
135 {
136  if (!remap_ops || !remap_ops->free_irq)
137  return;
138 
139  remap_ops->free_irq(irq);
140 }
141 
143  unsigned int irq, unsigned int dest,
144  struct msi_msg *msg, u8 hpet_id)
145 {
146  if (!remap_ops || !remap_ops->compose_msi_msg)
147  return;
148 
149  remap_ops->compose_msi_msg(pdev, irq, dest, msg, hpet_id);
150 }
151 
152 int msi_alloc_remapped_irq(struct pci_dev *pdev, int irq, int nvec)
153 {
154  if (!remap_ops || !remap_ops->msi_alloc_irq)
155  return -ENODEV;
156 
157  return remap_ops->msi_alloc_irq(pdev, irq, nvec);
158 }
159 
160 int msi_setup_remapped_irq(struct pci_dev *pdev, unsigned int irq,
161  int index, int sub_handle)
162 {
163  if (!remap_ops || !remap_ops->msi_setup_irq)
164  return -ENODEV;
165 
166  return remap_ops->msi_setup_irq(pdev, irq, index, sub_handle);
167 }
168 
169 int setup_hpet_msi_remapped(unsigned int irq, unsigned int id)
170 {
171  if (!remap_ops || !remap_ops->setup_hpet_msi)
172  return -ENODEV;
173 
174  return remap_ops->setup_hpet_msi(irq, id);
175 }