|
15 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16 | 16 | */
|
17 | 17 |
|
| 18 | +#include <linux/acpi_iort.h> |
18 | 19 | #include <linux/msi.h>
|
19 | 20 | #include <linux/of.h>
|
20 | 21 | #include <linux/of_irq.h>
|
@@ -144,9 +145,52 @@ static int __init its_pci_of_msi_init(void)
|
144 | 145 | return 0;
|
145 | 146 | }
|
146 | 147 |
|
| 148 | +#ifdef CONFIG_ACPI |
| 149 | + |
| 150 | +static int __init |
| 151 | +its_pci_msi_parse_madt(struct acpi_subtable_header *header, |
| 152 | + const unsigned long end) |
| 153 | +{ |
| 154 | + struct acpi_madt_generic_translator *its_entry; |
| 155 | + struct fwnode_handle *dom_handle; |
| 156 | + const char *node_name; |
| 157 | + int err = -ENXIO; |
| 158 | + |
| 159 | + its_entry = (struct acpi_madt_generic_translator *)header; |
| 160 | + node_name = kasprintf(GFP_KERNEL, "ITS@0x%lx", |
| 161 | + (long)its_entry->base_address); |
| 162 | + dom_handle = iort_find_domain_token(its_entry->translation_id); |
| 163 | + if (!dom_handle) { |
| 164 | + pr_err("%s: Unable to locate ITS domain handle\n", node_name); |
| 165 | + goto out; |
| 166 | + } |
| 167 | + |
| 168 | + err = its_pci_msi_init_one(dom_handle, node_name); |
| 169 | + if (!err) |
| 170 | + pr_info("PCI/MSI: %s domain created\n", node_name); |
| 171 | + |
| 172 | +out: |
| 173 | + kfree(node_name); |
| 174 | + return err; |
| 175 | +} |
| 176 | + |
| 177 | +static int __init its_pci_acpi_msi_init(void) |
| 178 | +{ |
| 179 | + acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR, |
| 180 | + its_pci_msi_parse_madt, 0); |
| 181 | + return 0; |
| 182 | +} |
| 183 | +#else |
| 184 | +static int __init its_pci_acpi_msi_init(void) |
| 185 | +{ |
| 186 | + return 0; |
| 187 | +} |
| 188 | +#endif |
| 189 | + |
147 | 190 | static int __init its_pci_msi_init(void)
|
148 | 191 | {
|
149 | 192 | its_pci_of_msi_init();
|
| 193 | + its_pci_acpi_msi_init(); |
150 | 194 |
|
151 | 195 | return 0;
|
152 | 196 | }
|
|
0 commit comments