.. | .. |
---|
22 | 22 | #include <linux/module.h> |
---|
23 | 23 | #include <linux/of.h> |
---|
24 | 24 | #include <linux/of_irq.h> |
---|
25 | | -#include <linux/of_pci.h> |
---|
26 | 25 | #include <linux/string.h> |
---|
27 | 26 | #include <linux/slab.h> |
---|
28 | 27 | |
---|
.. | .. |
---|
274 | 273 | } |
---|
275 | 274 | EXPORT_SYMBOL_GPL(of_irq_parse_raw); |
---|
276 | 275 | |
---|
277 | | -int of_irq_domain_map(const struct irq_fwspec *in, struct irq_fwspec *out) |
---|
278 | | -{ |
---|
279 | | - char *stem_name; |
---|
280 | | - char *cells_name, *map_name = NULL, *mask_name = NULL; |
---|
281 | | - char *pass_name = NULL; |
---|
282 | | - struct device_node *cur, *new = NULL; |
---|
283 | | - const __be32 *map, *mask, *pass; |
---|
284 | | - static const __be32 dummy_mask[] = { [0 ... MAX_PHANDLE_ARGS] = ~0 }; |
---|
285 | | - static const __be32 dummy_pass[] = { [0 ... MAX_PHANDLE_ARGS] = 0 }; |
---|
286 | | - __be32 initial_match_array[MAX_PHANDLE_ARGS]; |
---|
287 | | - const __be32 *match_array = initial_match_array; |
---|
288 | | - int i, ret, map_len, match; |
---|
289 | | - u32 in_size, out_size; |
---|
290 | | - |
---|
291 | | - stem_name = ""; |
---|
292 | | - cells_name = "#interrupt-cells"; |
---|
293 | | - |
---|
294 | | - ret = -ENOMEM; |
---|
295 | | - map_name = kasprintf(GFP_KERNEL, "irqdomain%s-map", stem_name); |
---|
296 | | - if (!map_name) |
---|
297 | | - goto free; |
---|
298 | | - |
---|
299 | | - mask_name = kasprintf(GFP_KERNEL, "irqdomain%s-map-mask", stem_name); |
---|
300 | | - if (!mask_name) |
---|
301 | | - goto free; |
---|
302 | | - |
---|
303 | | - pass_name = kasprintf(GFP_KERNEL, "irqdomain%s-map-pass-thru", stem_name); |
---|
304 | | - if (!pass_name) |
---|
305 | | - goto free; |
---|
306 | | - |
---|
307 | | - /* Get the #interrupt-cells property */ |
---|
308 | | - cur = to_of_node(in->fwnode); |
---|
309 | | - ret = of_property_read_u32(cur, cells_name, &in_size); |
---|
310 | | - if (ret < 0) |
---|
311 | | - goto put; |
---|
312 | | - |
---|
313 | | - /* Precalculate the match array - this simplifies match loop */ |
---|
314 | | - for (i = 0; i < in_size; i++) |
---|
315 | | - initial_match_array[i] = cpu_to_be32(in->param[i]); |
---|
316 | | - |
---|
317 | | - ret = -EINVAL; |
---|
318 | | - /* Get the irqdomain-map property */ |
---|
319 | | - map = of_get_property(cur, map_name, &map_len); |
---|
320 | | - if (!map) { |
---|
321 | | - ret = 0; |
---|
322 | | - goto free; |
---|
323 | | - } |
---|
324 | | - map_len /= sizeof(u32); |
---|
325 | | - |
---|
326 | | - /* Get the irqdomain-map-mask property (optional) */ |
---|
327 | | - mask = of_get_property(cur, mask_name, NULL); |
---|
328 | | - if (!mask) |
---|
329 | | - mask = dummy_mask; |
---|
330 | | - /* Iterate through irqdomain-map property */ |
---|
331 | | - match = 0; |
---|
332 | | - while (map_len > (in_size + 1) && !match) { |
---|
333 | | - /* Compare specifiers */ |
---|
334 | | - match = 1; |
---|
335 | | - for (i = 0; i < in_size; i++, map_len--) |
---|
336 | | - match &= !((match_array[i] ^ *map++) & mask[i]); |
---|
337 | | - |
---|
338 | | - of_node_put(new); |
---|
339 | | - new = of_find_node_by_phandle(be32_to_cpup(map)); |
---|
340 | | - map++; |
---|
341 | | - map_len--; |
---|
342 | | - |
---|
343 | | - /* Check if not found */ |
---|
344 | | - if (!new) |
---|
345 | | - goto put; |
---|
346 | | - |
---|
347 | | - if (!of_device_is_available(new)) |
---|
348 | | - match = 0; |
---|
349 | | - |
---|
350 | | - ret = of_property_read_u32(new, cells_name, &out_size); |
---|
351 | | - if (ret) |
---|
352 | | - goto put; |
---|
353 | | - |
---|
354 | | - /* Check for malformed properties */ |
---|
355 | | - if (WARN_ON(out_size > MAX_PHANDLE_ARGS)) |
---|
356 | | - goto put; |
---|
357 | | - if (map_len < out_size) |
---|
358 | | - goto put; |
---|
359 | | - |
---|
360 | | - /* Move forward by new node's #interrupt-cells amount */ |
---|
361 | | - map += out_size; |
---|
362 | | - map_len -= out_size; |
---|
363 | | - } |
---|
364 | | - if (match) { |
---|
365 | | - /* Get the irqdomain-map-pass-thru property (optional) */ |
---|
366 | | - pass = of_get_property(cur, pass_name, NULL); |
---|
367 | | - if (!pass) |
---|
368 | | - pass = dummy_pass; |
---|
369 | | - |
---|
370 | | - /* |
---|
371 | | - * Successfully parsed a irqdomain-map translation; copy new |
---|
372 | | - * specifier into the out structure, keeping the |
---|
373 | | - * bits specified in irqdomain-map-pass-thru. |
---|
374 | | - */ |
---|
375 | | - match_array = map - out_size; |
---|
376 | | - for (i = 0; i < out_size; i++) { |
---|
377 | | - __be32 val = *(map - out_size + i); |
---|
378 | | - |
---|
379 | | - out->param[i] = in->param[i]; |
---|
380 | | - if (i < in_size) { |
---|
381 | | - val &= ~pass[i]; |
---|
382 | | - val |= cpu_to_be32(out->param[i]) & pass[i]; |
---|
383 | | - } |
---|
384 | | - |
---|
385 | | - out->param[i] = be32_to_cpu(val); |
---|
386 | | - } |
---|
387 | | - out->param_count = in_size = out_size; |
---|
388 | | - out->fwnode = of_node_to_fwnode(new); |
---|
389 | | - } |
---|
390 | | -put: |
---|
391 | | - of_node_put(cur); |
---|
392 | | - of_node_put(new); |
---|
393 | | -free: |
---|
394 | | - kfree(mask_name); |
---|
395 | | - kfree(map_name); |
---|
396 | | - kfree(pass_name); |
---|
397 | | - |
---|
398 | | - return ret; |
---|
399 | | -} |
---|
400 | | -EXPORT_SYMBOL(of_irq_domain_map); |
---|
401 | | - |
---|
402 | 276 | /** |
---|
403 | 277 | * of_irq_parse_one - Resolve an interrupt for a device |
---|
404 | 278 | * @device: the device whose interrupt is to be resolved |
---|
405 | 279 | * @index: index of the interrupt to resolve |
---|
406 | | - * @out_irq: structure of_irq filled by this function |
---|
| 280 | + * @out_irq: structure of_phandle_args filled by this function |
---|
407 | 281 | * |
---|
408 | 282 | * This function resolves an interrupt for a node by walking the interrupt tree, |
---|
409 | 283 | * finding which interrupt controller node it is attached to, and returning the |
---|
.. | .. |
---|
626 | 500 | * pointer, interrupt-parent device_node etc. |
---|
627 | 501 | */ |
---|
628 | 502 | desc = kzalloc(sizeof(*desc), GFP_KERNEL); |
---|
629 | | - if (WARN_ON(!desc)) { |
---|
| 503 | + if (!desc) { |
---|
630 | 504 | of_node_put(np); |
---|
631 | 505 | goto err; |
---|
632 | 506 | } |
---|
.. | .. |
---|
702 | 576 | } |
---|
703 | 577 | } |
---|
704 | 578 | |
---|
705 | | -static u32 __of_msi_map_rid(struct device *dev, struct device_node **np, |
---|
706 | | - u32 rid_in) |
---|
| 579 | +static u32 __of_msi_map_id(struct device *dev, struct device_node **np, |
---|
| 580 | + u32 id_in) |
---|
707 | 581 | { |
---|
708 | 582 | struct device *parent_dev; |
---|
709 | | - u32 rid_out = rid_in; |
---|
| 583 | + u32 id_out = id_in; |
---|
710 | 584 | |
---|
711 | 585 | /* |
---|
712 | 586 | * Walk up the device parent links looking for one with a |
---|
713 | 587 | * "msi-map" property. |
---|
714 | 588 | */ |
---|
715 | 589 | for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent) |
---|
716 | | - if (!of_pci_map_rid(parent_dev->of_node, rid_in, "msi-map", |
---|
717 | | - "msi-map-mask", np, &rid_out)) |
---|
| 590 | + if (!of_map_id(parent_dev->of_node, id_in, "msi-map", |
---|
| 591 | + "msi-map-mask", np, &id_out)) |
---|
718 | 592 | break; |
---|
719 | | - return rid_out; |
---|
| 593 | + return id_out; |
---|
720 | 594 | } |
---|
721 | 595 | |
---|
722 | 596 | /** |
---|
723 | | - * of_msi_map_rid - Map a MSI requester ID for a device. |
---|
| 597 | + * of_msi_map_id - Map a MSI ID for a device. |
---|
724 | 598 | * @dev: device for which the mapping is to be done. |
---|
725 | 599 | * @msi_np: device node of the expected msi controller. |
---|
726 | | - * @rid_in: unmapped MSI requester ID for the device. |
---|
| 600 | + * @id_in: unmapped MSI ID for the device. |
---|
727 | 601 | * |
---|
728 | 602 | * Walk up the device hierarchy looking for devices with a "msi-map" |
---|
729 | | - * property. If found, apply the mapping to @rid_in. |
---|
| 603 | + * property. If found, apply the mapping to @id_in. |
---|
730 | 604 | * |
---|
731 | | - * Returns the mapped MSI requester ID. |
---|
| 605 | + * Returns the mapped MSI ID. |
---|
732 | 606 | */ |
---|
733 | | -u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in) |
---|
| 607 | +u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in) |
---|
734 | 608 | { |
---|
735 | | - return __of_msi_map_rid(dev, &msi_np, rid_in); |
---|
| 609 | + return __of_msi_map_id(dev, &msi_np, id_in); |
---|
736 | 610 | } |
---|
737 | 611 | |
---|
738 | 612 | /** |
---|
739 | 613 | * of_msi_map_get_device_domain - Use msi-map to find the relevant MSI domain |
---|
740 | 614 | * @dev: device for which the mapping is to be done. |
---|
741 | | - * @rid: Requester ID for the device. |
---|
| 615 | + * @id: Device ID. |
---|
| 616 | + * @bus_token: Bus token |
---|
742 | 617 | * |
---|
743 | 618 | * Walk up the device hierarchy looking for devices with a "msi-map" |
---|
744 | 619 | * property. |
---|
745 | 620 | * |
---|
746 | 621 | * Returns: the MSI domain for this device (or NULL on failure) |
---|
747 | 622 | */ |
---|
748 | | -struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 rid) |
---|
| 623 | +struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 id, |
---|
| 624 | + u32 bus_token) |
---|
749 | 625 | { |
---|
750 | 626 | struct device_node *np = NULL; |
---|
751 | 627 | |
---|
752 | | - __of_msi_map_rid(dev, &np, rid); |
---|
753 | | - return irq_find_matching_host(np, DOMAIN_BUS_PCI_MSI); |
---|
| 628 | + __of_msi_map_id(dev, &np, id); |
---|
| 629 | + return irq_find_matching_host(np, bus_token); |
---|
754 | 630 | } |
---|
755 | 631 | |
---|
756 | 632 | /** |
---|