| .. | .. |
|---|
| 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 | /** |
|---|