]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/acpi/arm64/iort.c
1ac2720da96de114f1e168f169d5cec8abf77205
[karo-tx-linux.git] / drivers / acpi / arm64 / iort.c
1 /*
2  * Copyright (C) 2016, Semihalf
3  *      Author: Tomasz Nowicki <tn@semihalf.com>
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * This file implements early detection/parsing of I/O mapping
15  * reported to OS through firmware via I/O Remapping Table (IORT)
16  * IORT document number: ARM DEN 0049A
17  */
18
19 #define pr_fmt(fmt)     "ACPI: IORT: " fmt
20
21 #include <linux/acpi_iort.h>
22 #include <linux/kernel.h>
23 #include <linux/list.h>
24 #include <linux/pci.h>
25 #include <linux/slab.h>
26
27 struct iort_its_msi_chip {
28         struct list_head        list;
29         struct fwnode_handle    *fw_node;
30         u32                     translation_id;
31 };
32
33 struct iort_fwnode {
34         struct list_head list;
35         struct acpi_iort_node *iort_node;
36         struct fwnode_handle *fwnode;
37 };
38 static LIST_HEAD(iort_fwnode_list);
39 static DEFINE_SPINLOCK(iort_fwnode_lock);
40
41 /**
42  * iort_set_fwnode() - Create iort_fwnode and use it to register
43  *                     iommu data in the iort_fwnode_list
44  *
45  * @node: IORT table node associated with the IOMMU
46  * @fwnode: fwnode associated with the IORT node
47  *
48  * Returns: 0 on success
49  *          <0 on failure
50  */
51 static inline int iort_set_fwnode(struct acpi_iort_node *iort_node,
52                                   struct fwnode_handle *fwnode)
53 {
54         struct iort_fwnode *np;
55
56         np = kzalloc(sizeof(struct iort_fwnode), GFP_ATOMIC);
57
58         if (WARN_ON(!np))
59                 return -ENOMEM;
60
61         INIT_LIST_HEAD(&np->list);
62         np->iort_node = iort_node;
63         np->fwnode = fwnode;
64
65         spin_lock(&iort_fwnode_lock);
66         list_add_tail(&np->list, &iort_fwnode_list);
67         spin_unlock(&iort_fwnode_lock);
68
69         return 0;
70 }
71
72 /**
73  * iort_get_fwnode() - Retrieve fwnode associated with an IORT node
74  *
75  * @node: IORT table node to be looked-up
76  *
77  * Returns: fwnode_handle pointer on success, NULL on failure
78  */
79 static inline
80 struct fwnode_handle *iort_get_fwnode(struct acpi_iort_node *node)
81 {
82         struct iort_fwnode *curr;
83         struct fwnode_handle *fwnode = NULL;
84
85         spin_lock(&iort_fwnode_lock);
86         list_for_each_entry(curr, &iort_fwnode_list, list) {
87                 if (curr->iort_node == node) {
88                         fwnode = curr->fwnode;
89                         break;
90                 }
91         }
92         spin_unlock(&iort_fwnode_lock);
93
94         return fwnode;
95 }
96
97 /**
98  * iort_delete_fwnode() - Delete fwnode associated with an IORT node
99  *
100  * @node: IORT table node associated with fwnode to delete
101  */
102 static inline void iort_delete_fwnode(struct acpi_iort_node *node)
103 {
104         struct iort_fwnode *curr, *tmp;
105
106         spin_lock(&iort_fwnode_lock);
107         list_for_each_entry_safe(curr, tmp, &iort_fwnode_list, list) {
108                 if (curr->iort_node == node) {
109                         list_del(&curr->list);
110                         kfree(curr);
111                         break;
112                 }
113         }
114         spin_unlock(&iort_fwnode_lock);
115 }
116
117 typedef acpi_status (*iort_find_node_callback)
118         (struct acpi_iort_node *node, void *context);
119
120 /* Root pointer to the mapped IORT table */
121 static struct acpi_table_header *iort_table;
122
123 static LIST_HEAD(iort_msi_chip_list);
124 static DEFINE_SPINLOCK(iort_msi_chip_lock);
125
126 /**
127  * iort_register_domain_token() - register domain token and related ITS ID
128  * to the list from where we can get it back later on.
129  * @trans_id: ITS ID.
130  * @fw_node: Domain token.
131  *
132  * Returns: 0 on success, -ENOMEM if no memory when allocating list element
133  */
134 int iort_register_domain_token(int trans_id, struct fwnode_handle *fw_node)
135 {
136         struct iort_its_msi_chip *its_msi_chip;
137
138         its_msi_chip = kzalloc(sizeof(*its_msi_chip), GFP_KERNEL);
139         if (!its_msi_chip)
140                 return -ENOMEM;
141
142         its_msi_chip->fw_node = fw_node;
143         its_msi_chip->translation_id = trans_id;
144
145         spin_lock(&iort_msi_chip_lock);
146         list_add(&its_msi_chip->list, &iort_msi_chip_list);
147         spin_unlock(&iort_msi_chip_lock);
148
149         return 0;
150 }
151
152 /**
153  * iort_deregister_domain_token() - Deregister domain token based on ITS ID
154  * @trans_id: ITS ID.
155  *
156  * Returns: none.
157  */
158 void iort_deregister_domain_token(int trans_id)
159 {
160         struct iort_its_msi_chip *its_msi_chip, *t;
161
162         spin_lock(&iort_msi_chip_lock);
163         list_for_each_entry_safe(its_msi_chip, t, &iort_msi_chip_list, list) {
164                 if (its_msi_chip->translation_id == trans_id) {
165                         list_del(&its_msi_chip->list);
166                         kfree(its_msi_chip);
167                         break;
168                 }
169         }
170         spin_unlock(&iort_msi_chip_lock);
171 }
172
173 /**
174  * iort_find_domain_token() - Find domain token based on given ITS ID
175  * @trans_id: ITS ID.
176  *
177  * Returns: domain token when find on the list, NULL otherwise
178  */
179 struct fwnode_handle *iort_find_domain_token(int trans_id)
180 {
181         struct fwnode_handle *fw_node = NULL;
182         struct iort_its_msi_chip *its_msi_chip;
183
184         spin_lock(&iort_msi_chip_lock);
185         list_for_each_entry(its_msi_chip, &iort_msi_chip_list, list) {
186                 if (its_msi_chip->translation_id == trans_id) {
187                         fw_node = its_msi_chip->fw_node;
188                         break;
189                 }
190         }
191         spin_unlock(&iort_msi_chip_lock);
192
193         return fw_node;
194 }
195
196 static struct acpi_iort_node *iort_scan_node(enum acpi_iort_node_type type,
197                                              iort_find_node_callback callback,
198                                              void *context)
199 {
200         struct acpi_iort_node *iort_node, *iort_end;
201         struct acpi_table_iort *iort;
202         int i;
203
204         if (!iort_table)
205                 return NULL;
206
207         /* Get the first IORT node */
208         iort = (struct acpi_table_iort *)iort_table;
209         iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort,
210                                  iort->node_offset);
211         iort_end = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
212                                 iort_table->length);
213
214         for (i = 0; i < iort->node_count; i++) {
215                 if (WARN_TAINT(iort_node >= iort_end, TAINT_FIRMWARE_WORKAROUND,
216                                "IORT node pointer overflows, bad table!\n"))
217                         return NULL;
218
219                 if (iort_node->type == type &&
220                     ACPI_SUCCESS(callback(iort_node, context)))
221                                 return iort_node;
222
223                 iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort_node,
224                                          iort_node->length);
225         }
226
227         return NULL;
228 }
229
230 static acpi_status iort_match_node_callback(struct acpi_iort_node *node,
231                                             void *context)
232 {
233         struct device *dev = context;
234         acpi_status status;
235
236         if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT) {
237                 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
238                 struct acpi_device *adev = to_acpi_device_node(dev->fwnode);
239                 struct acpi_iort_named_component *ncomp;
240
241                 if (!adev) {
242                         status = AE_NOT_FOUND;
243                         goto out;
244                 }
245
246                 status = acpi_get_name(adev->handle, ACPI_FULL_PATHNAME, &buf);
247                 if (ACPI_FAILURE(status)) {
248                         dev_warn(dev, "Can't get device full path name\n");
249                         goto out;
250                 }
251
252                 ncomp = (struct acpi_iort_named_component *)node->node_data;
253                 status = !strcmp(ncomp->device_name, buf.pointer) ?
254                                                         AE_OK : AE_NOT_FOUND;
255                 acpi_os_free(buf.pointer);
256         } else if (node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) {
257                 struct acpi_iort_root_complex *pci_rc;
258                 struct pci_bus *bus;
259
260                 bus = to_pci_bus(dev);
261                 pci_rc = (struct acpi_iort_root_complex *)node->node_data;
262
263                 /*
264                  * It is assumed that PCI segment numbers maps one-to-one
265                  * with root complexes. Each segment number can represent only
266                  * one root complex.
267                  */
268                 status = pci_rc->pci_segment_number == pci_domain_nr(bus) ?
269                                                         AE_OK : AE_NOT_FOUND;
270         } else {
271                 status = AE_NOT_FOUND;
272         }
273 out:
274         return status;
275 }
276
277 static int iort_id_map(struct acpi_iort_id_mapping *map, u8 type, u32 rid_in,
278                        u32 *rid_out)
279 {
280         /* Single mapping does not care for input id */
281         if (map->flags & ACPI_IORT_ID_SINGLE_MAPPING) {
282                 if (type == ACPI_IORT_NODE_NAMED_COMPONENT ||
283                     type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) {
284                         *rid_out = map->output_base;
285                         return 0;
286                 }
287
288                 pr_warn(FW_BUG "[map %p] SINGLE MAPPING flag not allowed for node type %d, skipping ID map\n",
289                         map, type);
290                 return -ENXIO;
291         }
292
293         if (rid_in < map->input_base ||
294             (rid_in >= map->input_base + map->id_count))
295                 return -ENXIO;
296
297         *rid_out = map->output_base + (rid_in - map->input_base);
298         return 0;
299 }
300
301 static struct acpi_iort_node *iort_node_map_rid(struct acpi_iort_node *node,
302                                                 u32 rid_in, u32 *rid_out,
303                                                 u8 type)
304 {
305         u32 rid = rid_in;
306
307         /* Parse the ID mapping tree to find specified node type */
308         while (node) {
309                 struct acpi_iort_id_mapping *map;
310                 int i;
311
312                 if (node->type == type) {
313                         if (rid_out)
314                                 *rid_out = rid;
315                         return node;
316                 }
317
318                 if (!node->mapping_offset || !node->mapping_count)
319                         goto fail_map;
320
321                 map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node,
322                                    node->mapping_offset);
323
324                 /* Firmware bug! */
325                 if (!map->output_reference) {
326                         pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n",
327                                node, node->type);
328                         goto fail_map;
329                 }
330
331                 /* Do the RID translation */
332                 for (i = 0; i < node->mapping_count; i++, map++) {
333                         if (!iort_id_map(map, node->type, rid, &rid))
334                                 break;
335                 }
336
337                 if (i == node->mapping_count)
338                         goto fail_map;
339
340                 node = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
341                                     map->output_reference);
342         }
343
344 fail_map:
345         /* Map input RID to output RID unchanged on mapping failure*/
346         if (rid_out)
347                 *rid_out = rid_in;
348
349         return NULL;
350 }
351
352 static struct acpi_iort_node *iort_find_dev_node(struct device *dev)
353 {
354         struct pci_bus *pbus;
355
356         if (!dev_is_pci(dev))
357                 return iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
358                                       iort_match_node_callback, dev);
359
360         /* Find a PCI root bus */
361         pbus = to_pci_dev(dev)->bus;
362         while (!pci_is_root_bus(pbus))
363                 pbus = pbus->parent;
364
365         return iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
366                               iort_match_node_callback, &pbus->dev);
367 }
368
369 /**
370  * iort_msi_map_rid() - Map a MSI requester ID for a device
371  * @dev: The device for which the mapping is to be done.
372  * @req_id: The device requester ID.
373  *
374  * Returns: mapped MSI RID on success, input requester ID otherwise
375  */
376 u32 iort_msi_map_rid(struct device *dev, u32 req_id)
377 {
378         struct acpi_iort_node *node;
379         u32 dev_id;
380
381         node = iort_find_dev_node(dev);
382         if (!node)
383                 return req_id;
384
385         iort_node_map_rid(node, req_id, &dev_id, ACPI_IORT_NODE_ITS_GROUP);
386         return dev_id;
387 }
388
389 /**
390  * iort_dev_find_its_id() - Find the ITS identifier for a device
391  * @dev: The device.
392  * @idx: Index of the ITS identifier list.
393  * @its_id: ITS identifier.
394  *
395  * Returns: 0 on success, appropriate error value otherwise
396  */
397 static int iort_dev_find_its_id(struct device *dev, u32 req_id,
398                                 unsigned int idx, int *its_id)
399 {
400         struct acpi_iort_its_group *its;
401         struct acpi_iort_node *node;
402
403         node = iort_find_dev_node(dev);
404         if (!node)
405                 return -ENXIO;
406
407         node = iort_node_map_rid(node, req_id, NULL, ACPI_IORT_NODE_ITS_GROUP);
408         if (!node)
409                 return -ENXIO;
410
411         /* Move to ITS specific data */
412         its = (struct acpi_iort_its_group *)node->node_data;
413         if (idx > its->its_count) {
414                 dev_err(dev, "requested ITS ID index [%d] is greater than available [%d]\n",
415                         idx, its->its_count);
416                 return -ENXIO;
417         }
418
419         *its_id = its->identifiers[idx];
420         return 0;
421 }
422
423 /**
424  * iort_get_device_domain() - Find MSI domain related to a device
425  * @dev: The device.
426  * @req_id: Requester ID for the device.
427  *
428  * Returns: the MSI domain for this device, NULL otherwise
429  */
430 struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
431 {
432         struct fwnode_handle *handle;
433         int its_id;
434
435         if (iort_dev_find_its_id(dev, req_id, 0, &its_id))
436                 return NULL;
437
438         handle = iort_find_domain_token(its_id);
439         if (!handle)
440                 return NULL;
441
442         return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
443 }
444
445 void __init acpi_iort_init(void)
446 {
447         acpi_status status;
448
449         status = acpi_get_table(ACPI_SIG_IORT, 0, &iort_table);
450         if (ACPI_FAILURE(status)) {
451                 if (status != AE_NOT_FOUND) {
452                         const char *msg = acpi_format_exception(status);
453
454                         pr_err("Failed to get table, %s\n", msg);
455                 }
456
457                 return;
458         }
459
460         acpi_probe_device_table(iort);
461 }