1 #include <linux/kernel.h> 2 #include <linux/string.h> 3 #include <linux/errno.h> 4 5 #include "irq_remapping.h" 6 7 int irq_remapping_enabled; 8 9 int disable_irq_remap; 10 int disable_sourceid_checking; 11 int no_x2apic_optout; 12 13 static struct irq_remap_ops *remap_ops; 14 15 static __init int setup_nointremap(char *str) 16 { 17 disable_irq_remap = 1; 18 return 0; 19 } 20 early_param("nointremap", setup_nointremap); 21 22 static __init int setup_irqremap(char *str) 23 { 24 if (!str) 25 return -EINVAL; 26 27 while (*str) { 28 if (!strncmp(str, "on", 2)) 29 disable_irq_remap = 0; 30 else if (!strncmp(str, "off", 3)) 31 disable_irq_remap = 1; 32 else if (!strncmp(str, "nosid", 5)) 33 disable_sourceid_checking = 1; 34 else if (!strncmp(str, "no_x2apic_optout", 16)) 35 no_x2apic_optout = 1; 36 37 str += strcspn(str, ","); 38 while (*str == ',') 39 str++; 40 } 41 42 return 0; 43 } 44 early_param("intremap", setup_irqremap); 45 46 void __init setup_irq_remapping_ops(void) 47 { 48 remap_ops = &intel_irq_remap_ops; 49 } 50 51 int irq_remapping_supported(void) 52 { 53 if (disable_irq_remap) 54 return 0; 55 56 if (!remap_ops || !remap_ops->supported) 57 return 0; 58 59 return remap_ops->supported(); 60 } 61 62 int __init irq_remapping_prepare(void) 63 { 64 if (!remap_ops || !remap_ops->prepare) 65 return -ENODEV; 66 67 return remap_ops->prepare(); 68 } 69 70 int __init irq_remapping_enable(void) 71 { 72 if (!remap_ops || !remap_ops->enable) 73 return -ENODEV; 74 75 return remap_ops->enable(); 76 } 77 78 void irq_remapping_disable(void) 79 { 80 if (!remap_ops || !remap_ops->disable) 81 return; 82 83 remap_ops->disable(); 84 } 85 86 int irq_remapping_reenable(int mode) 87 { 88 if (!remap_ops || !remap_ops->reenable) 89 return 0; 90 91 return remap_ops->reenable(mode); 92 } 93 94 int __init irq_remap_enable_fault_handling(void) 95 { 96 if (!remap_ops || !remap_ops->enable_faulting) 97 return -ENODEV; 98 99 return remap_ops->enable_faulting(); 100 } 101 102 int setup_ioapic_remapped_entry(int irq, 103 struct IO_APIC_route_entry *entry, 104 unsigned int destination, int vector, 105 struct io_apic_irq_attr *attr) 106 { 107 if (!remap_ops || !remap_ops->setup_ioapic_entry) 108 return -ENODEV; 109 110 return remap_ops->setup_ioapic_entry(irq, entry, destination, 111 vector, attr); 112 } 113 114 #ifdef CONFIG_SMP 115 int set_remapped_irq_affinity(struct irq_data *data, const struct cpumask *mask, 116 bool force) 117 { 118 if (!remap_ops || !remap_ops->set_affinity) 119 return 0; 120 121 return remap_ops->set_affinity(data, mask, force); 122 } 123 #endif 124 125 void free_remapped_irq(int irq) 126 { 127 if (!remap_ops || !remap_ops->free_irq) 128 return; 129 130 remap_ops->free_irq(irq); 131 } 132 133 void compose_remapped_msi_msg(struct pci_dev *pdev, 134 unsigned int irq, unsigned int dest, 135 struct msi_msg *msg, u8 hpet_id) 136 { 137 if (!remap_ops || !remap_ops->compose_msi_msg) 138 return; 139 140 remap_ops->compose_msi_msg(pdev, irq, dest, msg, hpet_id); 141 } 142 143 int msi_alloc_remapped_irq(struct pci_dev *pdev, int irq, int nvec) 144 { 145 if (!remap_ops || !remap_ops->msi_alloc_irq) 146 return -ENODEV; 147 148 return remap_ops->msi_alloc_irq(pdev, irq, nvec); 149 } 150 151 int msi_setup_remapped_irq(struct pci_dev *pdev, unsigned int irq, 152 int index, int sub_handle) 153 { 154 if (!remap_ops || !remap_ops->msi_setup_irq) 155 return -ENODEV; 156 157 return remap_ops->msi_setup_irq(pdev, irq, index, sub_handle); 158 } 159 160 int setup_hpet_msi_remapped(unsigned int irq, unsigned int id) 161 { 162 if (!remap_ops || !remap_ops->setup_hpet_msi) 163 return -ENODEV; 164 165 return remap_ops->setup_hpet_msi(irq, id); 166 } 167