Merge irqchip changes related to ACPI support that are needed to enable GICv5 IWB ACPI probe ordering detection on ARM, including the addition of acpi_device_clear_deps() and RISC-V interrupt controller management code refactoring to extract generic code from it into the common ACPI IRQ code (Lorenzo Pieralisi) * acpi-irqchip: irqchip/gic-v5: Enable GICv5 IWB ACPI probe ordering detection ACPI/IORT: Implement ACPI infrastructure to enable GICv5 IWB probe deferral ACPI: irq: Move RISC-V interrupt controllers autodep to ACPI IRQ code ACPI: RISC-V: Fix riscv_acpi_add_prt_dep() loop handling ACPI: RISC-V: Check acpi_get_handle() status in riscv_acpi_add_prt_dep() ACPI: RISC-V: Fix riscv_acpi_irq_get_dep() loop termination ACPI: Add acpi_device_clear_deps() helper function
Unified · Split
| @@ -67,6 +67,7 @@ int acpi_get_riscv_isa(struct acpi_table_header *table, · 66 unmodified lines | ||
| 67 | 67 | |
| 68 | 68 | void acpi_get_cbo_block_size(struct acpi_table_header *table, u32 *cbom_size, |
| 69 | 69 | u32 *cboz_size, u32 *cbop_size); |
| 70 | +acpi_handle acpi_get_riscv_gsi_handle(u32 gsi); | |
| 70 | 71 | #else |
| 71 | 72 | static inline void acpi_init_rintc_map(void) { } |
| 72 | 73 | static inline struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu) |
| @@ -789,11 +789,9 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 id, · 788 unmodified lines | ||
| 789 | 789 | return irq_find_matching_fwnode(handle, bus_token); |
| 790 | 790 | } |
| 791 | 791 | |
| 792 | −struct fwnode_handle *iort_iwb_handle(u32 iwb_id) | |
| 792 | +acpi_handle iort_iwb_handle(u32 iwb_id) | |
| 793 | 793 | { |
| 794 | − struct fwnode_handle *fwnode; | |
| 795 | 794 | struct acpi_iort_node *node; |
| 796 | − struct acpi_device *device; | |
| 797 | 795 | struct acpi_iort_iwb *iwb; |
| 798 | 796 | acpi_status status; |
| 799 | 797 | acpi_handle handle; |
| @@ -808,6 +806,19 @@ struct fwnode_handle *iort_iwb_handle(u32 iwb_id) · 8 unmodified lines | ||
| 808 | 806 | if (ACPI_FAILURE(status)) |
| 809 | 807 | return NULL; |
| 810 | 808 | |
| 809 | + return handle; | |
| 810 | +} | |
| 811 | + | |
| 812 | +struct fwnode_handle *iort_iwb_handle_fwnode(u32 iwb_id) | |
| 813 | +{ | |
| 814 | + struct fwnode_handle *fwnode; | |
| 815 | + struct acpi_device *device; | |
| 816 | + acpi_handle handle; | |
| 817 | + | |
| 818 | + handle = iort_iwb_handle(iwb_id); | |
| 819 | + if (!handle) | |
| 820 | + return NULL; | |
| 821 | + | |
| 811 | 822 | device = acpi_get_acpi_dev(handle); |
| 812 | 823 | if (!device) |
| 813 | 824 | return NULL; |
| @@ -2090,6 +2101,11 @@ static void __init iort_init_platform_devices(void) · 1276 unmodified lines | ||
| 2090 | 2101 | } |
| 2091 | 2102 | } |
| 2092 | 2103 | |
| 2104 | +u32 arch_acpi_add_auto_dep(acpi_handle handle) | |
| 2105 | +{ | |
| 2106 | + return acpi_irq_add_auto_dep(handle); | |
| 2107 | +} | |
| 2108 | + | |
| 2093 | 2109 | void __init acpi_iort_init(void) |
| 2094 | 2110 | { |
| 2095 | 2111 | acpi_status status; |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | enum acpi_irq_model_id acpi_irq_model; |
| 14 | 14 | |
| 15 | 15 | static acpi_gsi_domain_disp_fn acpi_get_gsi_domain_id; |
| 16 | +static acpi_gsi_handle_disp_fn acpi_get_gsi_handle; | |
| 16 | 17 | static u32 (*acpi_gsi_to_irq_fallback)(u32 gsi); |
| 17 | 18 | |
| 18 | 19 | /** |
| @@ -321,15 +322,19 @@ const struct cpumask *acpi_irq_get_affinity(acpi_handle handle, · 302 unmodified lines | ||
| 321 | 322 | |
| 322 | 323 | /** |
| 323 | 324 | * acpi_set_irq_model - Setup the GSI irqdomain information |
| 324 | − * @model: the value assigned to acpi_irq_model | |
| 325 | − * @fn: a dispatcher function that will return the domain fwnode | |
| 326 | − * for a given GSI | |
| 325 | + * @model: the value assigned to acpi_irq_model | |
| 326 | + * @fn: a dispatcher function that will return the domain fwnode | |
| 327 | + * for a given GSI | |
| 328 | + * @gsi_dep_fn: a function to retrieve the acpi_handle a GSI interrupt is | |
| 329 | + * dependent on | |
| 330 | + * | |
| 327 | 331 | */ |
| 328 | 332 | void __init acpi_set_irq_model(enum acpi_irq_model_id model, |
| 329 | − acpi_gsi_domain_disp_fn fn) | |
| 333 | + acpi_gsi_domain_disp_fn fn, acpi_gsi_handle_disp_fn gsi_dep_fn) | |
| 330 | 334 | { |
| 331 | 335 | acpi_irq_model = model; |
| 332 | 336 | acpi_get_gsi_domain_id = fn; |
| 337 | + acpi_get_gsi_handle = gsi_dep_fn; | |
| 333 | 338 | } |
| 334 | 339 | |
| 335 | 340 | /* |
| @@ -385,3 +390,162 @@ struct irq_domain *acpi_irq_create_hierarchy(unsigned int flags, · 49 unmodified lines | ||
| 385 | 390 | host_data); |
| 386 | 391 | } |
| 387 | 392 | EXPORT_SYMBOL_GPL(acpi_irq_create_hierarchy); |
| 393 | + | |
| 394 | +struct acpi_irq_dep_ctx { | |
| 395 | + int rc; | |
| 396 | + unsigned int index; | |
| 397 | + acpi_handle handle; | |
| 398 | +}; | |
| 399 | + | |
| 400 | +static acpi_status acpi_irq_get_parent(struct acpi_resource *ares, void *context) | |
| 401 | +{ | |
| 402 | + struct acpi_irq_dep_ctx *ctx = context; | |
| 403 | + struct acpi_resource_irq *irq; | |
| 404 | + struct acpi_resource_extended_irq *eirq; | |
| 405 | + | |
| 406 | + switch (ares->type) { | |
| 407 | + case ACPI_RESOURCE_TYPE_IRQ: | |
| 408 | + irq = &ares->data.irq; | |
| 409 | + if (ctx->index >= irq->interrupt_count) { | |
| 410 | + ctx->index -= irq->interrupt_count; | |
| 411 | + return AE_OK; | |
| 412 | + } | |
| 413 | + ctx->handle = acpi_get_gsi_handle(irq->interrupts[ctx->index]); | |
| 414 | + ctx->rc = 0; | |
| 415 | + return AE_CTRL_TERMINATE; | |
| 416 | + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: | |
| 417 | + eirq = &ares->data.extended_irq; | |
| 418 | + if (eirq->producer_consumer == ACPI_PRODUCER) | |
| 419 | + return AE_OK; | |
| 420 | + | |
| 421 | + if (ctx->index >= eirq->interrupt_count) { | |
| 422 | + ctx->index -= eirq->interrupt_count; | |
| 423 | + return AE_OK; | |
| 424 | + } | |
| 425 | + | |
| 426 | + /* Support GSIs only */ | |
| 427 | + if (eirq->resource_source.string_length) | |
| 428 | + return AE_OK; | |
| 429 | + | |
| 430 | + ctx->handle = acpi_get_gsi_handle(eirq->interrupts[ctx->index]); | |
| 431 | + ctx->rc = 0; | |
| 432 | + return AE_CTRL_TERMINATE; | |
| 433 | + } | |
| 434 | + | |
| 435 | + return AE_OK; | |
| 436 | +} | |
| 437 | + | |
| 438 | +static int acpi_irq_get_dep(acpi_handle handle, unsigned int index, acpi_handle *gsi_handle) | |
| 439 | +{ | |
| 440 | + struct acpi_irq_dep_ctx ctx = {-EINVAL, index, NULL}; | |
| 441 | + | |
| 442 | + if (!gsi_handle) | |
| 443 | + return -EINVAL; | |
| 444 | + | |
| 445 | + acpi_walk_resources(handle, METHOD_NAME__CRS, acpi_irq_get_parent, &ctx); | |
| 446 | + *gsi_handle = ctx.handle; | |
| 447 | + | |
| 448 | + return ctx.rc; | |
| 449 | +} | |
| 450 | + | |
| 451 | +static bool acpi_prt_entry_valid(void *prt_entry) | |
| 452 | +{ | |
| 453 | + struct acpi_pci_routing_table *entry = prt_entry; | |
| 454 | + | |
| 455 | + return entry && entry->length > 0; | |
| 456 | +} | |
| 457 | + | |
| 458 | +static void *acpi_prt_next_entry(void *prt_entry) | |
| 459 | +{ | |
| 460 | + struct acpi_pci_routing_table *entry = prt_entry; | |
| 461 | + | |
| 462 | + return prt_entry + entry->length; | |
| 463 | +} | |
| 464 | + | |
| 465 | +static u32 acpi_add_prt_dep(acpi_handle handle) | |
| 466 | +{ | |
| 467 | + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | |
| 468 | + struct acpi_pci_routing_table *entry; | |
| 469 | + struct acpi_handle_list dep_devices; | |
| 470 | + acpi_handle gsi_handle; | |
| 471 | + acpi_handle link_handle; | |
| 472 | + acpi_status status; | |
| 473 | + u32 count = 0; | |
| 474 | + | |
| 475 | + status = acpi_get_irq_routing_table(handle, &buffer); | |
| 476 | + if (ACPI_FAILURE(status)) { | |
| 477 | + acpi_handle_err(handle, "failed to get IRQ routing table\n"); | |
| 478 | + kfree(buffer.pointer); | |
| 479 | + return 0; | |
| 480 | + } | |
| 481 | + | |
| 482 | + entry = buffer.pointer; | |
| 483 | + for (; acpi_prt_entry_valid(entry); entry = acpi_prt_next_entry(entry)) { | |
| 484 | + if (entry->source[0]) { | |
| 485 | + status = acpi_get_handle(handle, entry->source, &link_handle); | |
| 486 | + if (ACPI_FAILURE(status)) | |
| 487 | + continue; | |
| 488 | + dep_devices.count = 1; | |
| 489 | + dep_devices.handles = kcalloc(1, sizeof(*dep_devices.handles), GFP_KERNEL); | |
| 490 | + if (!dep_devices.handles) { | |
| 491 | + acpi_handle_err(handle, "failed to allocate memory\n"); | |
| 492 | + continue; | |
| 493 | + } | |
| 494 | + | |
| 495 | + dep_devices.handles[0] = link_handle; | |
| 496 | + count += acpi_scan_add_dep(handle, &dep_devices); | |
| 497 | + } else { | |
| 498 | + gsi_handle = acpi_get_gsi_handle(entry->source_index); | |
| 499 | + if (!gsi_handle) | |
| 500 | + continue; | |
| 501 | + dep_devices.count = 1; | |
| 502 | + dep_devices.handles = kcalloc(1, sizeof(*dep_devices.handles), GFP_KERNEL); | |
| 503 | + if (!dep_devices.handles) { | |
| 504 | + acpi_handle_err(handle, "failed to allocate memory\n"); | |
| 505 | + continue; | |
| 506 | + } | |
| 507 | + | |
| 508 | + dep_devices.handles[0] = gsi_handle; | |
| 509 | + count += acpi_scan_add_dep(handle, &dep_devices); | |
| 510 | + } | |
| 511 | + } | |
| 512 | + | |
| 513 | + kfree(buffer.pointer); | |
| 514 | + return count; | |
| 515 | +} | |
| 516 | + | |
| 517 | +static u32 acpi_add_irq_dep(acpi_handle handle) | |
| 518 | +{ | |
| 519 | + struct acpi_handle_list dep_devices; | |
| 520 | + acpi_handle gsi_handle; | |
| 521 | + u32 count = 0; | |
| 522 | + int i; | |
| 523 | + | |
| 524 | + for (i = 0; !acpi_irq_get_dep(handle, i, &gsi_handle); i++) { | |
| 525 | + if (!gsi_handle) | |
| 526 | + continue; | |
| 527 | + | |
| 528 | + dep_devices.count = 1; | |
| 529 | + dep_devices.handles = kcalloc(1, sizeof(*dep_devices.handles), GFP_KERNEL); | |
| 530 | + if (!dep_devices.handles) { | |
| 531 | + acpi_handle_err(handle, "failed to allocate memory\n"); | |
| 532 | + continue; | |
| 533 | + } | |
| 534 | + | |
| 535 | + dep_devices.handles[0] = gsi_handle; | |
| 536 | + count += acpi_scan_add_dep(handle, &dep_devices); | |
| 537 | + } | |
| 538 | + | |
| 539 | + return count; | |
| 540 | +} | |
| 541 | + | |
| 542 | +u32 acpi_irq_add_auto_dep(acpi_handle handle) | |
| 543 | +{ | |
| 544 | + if (!acpi_get_gsi_handle) | |
| 545 | + return 0; | |
| 546 | + | |
| 547 | + if (acpi_has_method(handle, "_PRT")) | |
| 548 | + return acpi_add_prt_dep(handle); | |
| 549 | + | |
| 550 | + return acpi_add_irq_dep(handle); | |
| 551 | +} | |
| @@ -23,12 +23,6 @@ struct riscv_ext_intc_list { · 22 unmodified lines | ||
| 23 | 23 | struct list_head list; |
| 24 | 24 | }; |
| 25 | 25 | |
| 26 | −struct acpi_irq_dep_ctx { | |
| 27 | − int rc; | |
| 28 | − unsigned int index; | |
| 29 | − acpi_handle handle; | |
| 30 | −}; | |
| 31 | − | |
| 32 | 26 | LIST_HEAD(ext_intc_list); |
| 33 | 27 | |
| 34 | 28 | static int irqchip_cmp_func(const void *in0, const void *in1) |
| @@ -254,7 +248,7 @@ void __init riscv_acpi_init_gsi_mapping(void) · 219 unmodified lines | ||
| 254 | 248 | acpi_get_devices("RSCV0006", riscv_acpi_create_gsi_map_smsi, NULL, NULL); |
| 255 | 249 | } |
| 256 | 250 | |
| 257 | −static acpi_handle riscv_acpi_get_gsi_handle(u32 gsi) | |
| 251 | +acpi_handle acpi_get_riscv_gsi_handle(u32 gsi) | |
| 258 | 252 | { |
| 259 | 253 | struct riscv_ext_intc_list *ext_intc_element; |
| 260 | 254 | struct list_head *i; |
| @@ -269,138 +263,7 @@ static acpi_handle riscv_acpi_get_gsi_handle(u32 gsi) · 8 unmodified lines | ||
| 269 | 263 | return NULL; |
| 270 | 264 | } |
| 271 | 265 | |
| 272 | −static acpi_status riscv_acpi_irq_get_parent(struct acpi_resource *ares, void *context) | |
| 273 | −{ | |
| 274 | − struct acpi_irq_dep_ctx *ctx = context; | |
| 275 | − struct acpi_resource_irq *irq; | |
| 276 | − struct acpi_resource_extended_irq *eirq; | |
| 277 | − | |
| 278 | − switch (ares->type) { | |
| 279 | − case ACPI_RESOURCE_TYPE_IRQ: | |
| 280 | − irq = &ares->data.irq; | |
| 281 | − if (ctx->index >= irq->interrupt_count) { | |
| 282 | − ctx->index -= irq->interrupt_count; | |
| 283 | − return AE_OK; | |
| 284 | − } | |
| 285 | − ctx->handle = riscv_acpi_get_gsi_handle(irq->interrupts[ctx->index]); | |
| 286 | − return AE_CTRL_TERMINATE; | |
| 287 | − case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: | |
| 288 | − eirq = &ares->data.extended_irq; | |
| 289 | − if (eirq->producer_consumer == ACPI_PRODUCER) | |
| 290 | − return AE_OK; | |
| 291 | − | |
| 292 | − if (ctx->index >= eirq->interrupt_count) { | |
| 293 | − ctx->index -= eirq->interrupt_count; | |
| 294 | − return AE_OK; | |
| 295 | − } | |
| 296 | − | |
| 297 | − /* Support GSIs only */ | |
| 298 | − if (eirq->resource_source.string_length) | |
| 299 | − return AE_OK; | |
| 300 | − | |
| 301 | − ctx->handle = riscv_acpi_get_gsi_handle(eirq->interrupts[ctx->index]); | |
| 302 | − return AE_CTRL_TERMINATE; | |
| 303 | − } | |
| 304 | − | |
| 305 | − return AE_OK; | |
| 306 | −} | |
| 307 | − | |
| 308 | −static int riscv_acpi_irq_get_dep(acpi_handle handle, unsigned int index, acpi_handle *gsi_handle) | |
| 309 | −{ | |
| 310 | − struct acpi_irq_dep_ctx ctx = {-EINVAL, index, NULL}; | |
| 311 | − | |
| 312 | − if (!gsi_handle) | |
| 313 | − return 0; | |
| 314 | − | |
| 315 | − acpi_walk_resources(handle, METHOD_NAME__CRS, riscv_acpi_irq_get_parent, &ctx); | |
| 316 | − *gsi_handle = ctx.handle; | |
| 317 | − if (*gsi_handle) | |
| 318 | − return 1; | |
| 319 | − | |
| 320 | − return 0; | |
| 321 | −} | |
| 322 | − | |
| 323 | −static u32 riscv_acpi_add_prt_dep(acpi_handle handle) | |
| 324 | −{ | |
| 325 | − struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | |
| 326 | − struct acpi_pci_routing_table *entry; | |
| 327 | − struct acpi_handle_list dep_devices; | |
| 328 | − acpi_handle gsi_handle; | |
| 329 | − acpi_handle link_handle; | |
| 330 | − acpi_status status; | |
| 331 | − u32 count = 0; | |
| 332 | − | |
| 333 | − status = acpi_get_irq_routing_table(handle, &buffer); | |
| 334 | − if (ACPI_FAILURE(status)) { | |
| 335 | − acpi_handle_err(handle, "failed to get IRQ routing table\n"); | |
| 336 | − kfree(buffer.pointer); | |
| 337 | − return 0; | |
| 338 | − } | |
| 339 | − | |
| 340 | − entry = buffer.pointer; | |
| 341 | − while (entry && (entry->length > 0)) { | |
| 342 | − if (entry->source[0]) { | |
| 343 | − acpi_get_handle(handle, entry->source, &link_handle); | |
| 344 | − dep_devices.count = 1; | |
| 345 | − dep_devices.handles = kzalloc_objs(*dep_devices.handles, | |
| 346 | − 1); | |
| 347 | − if (!dep_devices.handles) { | |
| 348 | − acpi_handle_err(handle, "failed to allocate memory\n"); | |
| 349 | − continue; | |
| 350 | − } | |
| 351 | − | |
| 352 | − dep_devices.handles[0] = link_handle; | |
| 353 | − count += acpi_scan_add_dep(handle, &dep_devices); | |
| 354 | − } else { | |
| 355 | − gsi_handle = riscv_acpi_get_gsi_handle(entry->source_index); | |
| 356 | − dep_devices.count = 1; | |
| 357 | − dep_devices.handles = kzalloc_objs(*dep_devices.handles, | |
| 358 | − 1); | |
| 359 | − if (!dep_devices.handles) { | |
| 360 | − acpi_handle_err(handle, "failed to allocate memory\n"); | |
| 361 | − continue; | |
| 362 | − } | |
| 363 | − | |
| 364 | − dep_devices.handles[0] = gsi_handle; | |
| 365 | − count += acpi_scan_add_dep(handle, &dep_devices); | |
| 366 | − } | |
| 367 | − | |
| 368 | − entry = (struct acpi_pci_routing_table *) | |
| 369 | − ((unsigned long)entry + entry->length); | |
| 370 | − } | |
| 371 | − | |
| 372 | − kfree(buffer.pointer); | |
| 373 | − return count; | |
| 374 | −} | |
| 375 | − | |
| 376 | −static u32 riscv_acpi_add_irq_dep(acpi_handle handle) | |
| 377 | −{ | |
| 378 | − struct acpi_handle_list dep_devices; | |
| 379 | − acpi_handle gsi_handle; | |
| 380 | − u32 count = 0; | |
| 381 | − int i; | |
| 382 | − | |
| 383 | − for (i = 0; | |
| 384 | − riscv_acpi_irq_get_dep(handle, i, &gsi_handle); | |
| 385 | − i++) { | |
| 386 | − dep_devices.count = 1; | |
| 387 | − dep_devices.handles = kzalloc_objs(*dep_devices.handles, 1); | |
| 388 | − if (!dep_devices.handles) { | |
| 389 | − acpi_handle_err(handle, "failed to allocate memory\n"); | |
| 390 | − continue; | |
| 391 | − } | |
| 392 | − | |
| 393 | − dep_devices.handles[0] = gsi_handle; | |
| 394 | − count += acpi_scan_add_dep(handle, &dep_devices); | |
| 395 | − } | |
| 396 | − | |
| 397 | − return count; | |
| 398 | −} | |
| 399 | − | |
| 400 | 266 | u32 arch_acpi_add_auto_dep(acpi_handle handle) |
| 401 | 267 | { |
| 402 | − if (acpi_has_method(handle, "_PRT")) | |
| 403 | − return riscv_acpi_add_prt_dep(handle); | |
| 404 | − | |
| 405 | − return riscv_acpi_add_irq_dep(handle); | |
| 268 | + return acpi_irq_add_auto_dep(handle); | |
| 406 | 269 | } |
| @@ -850,6 +850,7 @@ static const char * const acpi_ignore_dep_ids[] = { · 849 unmodified lines | ||
| 850 | 850 | |
| 851 | 851 | /* List of HIDs for which we honor deps of matching ACPI devs, when checking _DEP lists. */ |
| 852 | 852 | static const char * const acpi_honor_dep_ids[] = { |
| 853 | + "ARMH0003", /* ARM GICv5 IWB */ | |
| 853 | 854 | "INT3472", /* Camera sensor PMIC / clk and regulator info */ |
| 854 | 855 | "INTC1059", /* IVSC (TGL) driver must be loaded to allow i2c access to camera sensors */ |
| 855 | 856 | "INTC1095", /* IVSC (ADL) driver must be loaded to allow i2c access to camera sensors */ |
| @@ -2588,7 +2588,7 @@ gic_acpi_init(union acpi_subtable_headers *header, const unsigned long end) · 2587 unmodified lines | ||
| 2588 | 2588 | if (err) |
| 2589 | 2589 | goto out_fwhandle_free; |
| 2590 | 2590 | |
| 2591 | − acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, gic_v3_get_gsi_domain_id); | |
| 2591 | + acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, gic_v3_get_gsi_domain_id, NULL); | |
| 2592 | 2592 | |
| 2593 | 2593 | if (static_branch_likely(&supports_deactivate_key)) |
| 2594 | 2594 | gic_acpi_setup_kvm_info(); |
| @@ -269,6 +269,8 @@ static int gicv5_iwb_device_probe(struct platform_device *pdev) · 268 unmodified lines | ||
| 269 | 269 | if (IS_ERR(iwb_node)) |
| 270 | 270 | return PTR_ERR(iwb_node); |
| 271 | 271 | |
| 272 | + acpi_device_clear_deps(&pdev->dev); | |
| 273 | + | |
| 272 | 274 | return 0; |
| 273 | 275 | } |
| 274 | 276 | |
| @@ -1226,11 +1226,19 @@ static struct fwnode_handle *gsi_domain_handle; · 1225 unmodified lines | ||
| 1226 | 1226 | static struct fwnode_handle *gic_v5_get_gsi_domain_id(u32 gsi) |
| 1227 | 1227 | { |
| 1228 | 1228 | if (FIELD_GET(GICV5_GSI_IC_TYPE, gsi) == GICV5_GSI_IWB_TYPE) |
| 1229 | − return iort_iwb_handle(FIELD_GET(GICV5_GSI_IWB_FRAME_ID, gsi)); | |
| 1229 | + return iort_iwb_handle_fwnode(FIELD_GET(GICV5_GSI_IWB_FRAME_ID, gsi)); | |
| 1230 | 1230 | |
| 1231 | 1231 | return gsi_domain_handle; |
| 1232 | 1232 | } |
| 1233 | 1233 | |
| 1234 | +static acpi_handle gic_v5_get_gsi_handle(u32 gsi) | |
| 1235 | +{ | |
| 1236 | + if (FIELD_GET(GICV5_GSI_IC_TYPE, gsi) == GICV5_GSI_IWB_TYPE) | |
| 1237 | + return iort_iwb_handle(FIELD_GET(GICV5_GSI_IWB_FRAME_ID, gsi)); | |
| 1238 | + | |
| 1239 | + return NULL; | |
| 1240 | +} | |
| 1241 | + | |
| 1234 | 1242 | static int __init gic_acpi_init(union acpi_subtable_headers *header, const unsigned long end) |
| 1235 | 1243 | { |
| 1236 | 1244 | struct acpi_madt_gicv5_irs *irs = (struct acpi_madt_gicv5_irs *)header; |
| @@ -1251,7 +1259,8 @@ static int __init gic_acpi_init(union acpi_subtable_headers *header, const unsig · 14 unmodified lines | ||
| 1251 | 1259 | if (ret) |
| 1252 | 1260 | goto out_irs; |
| 1253 | 1261 | |
| 1254 | − acpi_set_irq_model(ACPI_IRQ_MODEL_GIC_V5, gic_v5_get_gsi_domain_id); | |
| 1262 | + acpi_set_irq_model(ACPI_IRQ_MODEL_GIC_V5, gic_v5_get_gsi_domain_id, | |
| 1263 | + gic_v5_get_gsi_handle); | |
| 1255 | 1264 | |
| 1256 | 1265 | return 0; |
| 1257 | 1266 | |
| @@ -1690,7 +1690,7 @@ static int __init gic_v2_acpi_init(union acpi_subtable_headers *header, · 1689 unmodified lines | ||
| 1690 | 1690 | return ret; |
| 1691 | 1691 | } |
| 1692 | 1692 | |
| 1693 | − acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, gic_v2_get_gsi_domain_id); | |
| 1693 | + acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, gic_v2_get_gsi_domain_id, NULL); | |
| 1694 | 1694 | |
| 1695 | 1695 | if (IS_ENABLED(CONFIG_ARM_GIC_V2M)) |
| 1696 | 1696 | gicv2m_init(NULL, gic_data[0].domain); |
| @@ -168,7 +168,7 @@ static int __init cpuintc_acpi_init(union acpi_subtable_headers *header, · 167 unmodified lines | ||
| 168 | 168 | panic("Failed to add irqdomain for LoongArch CPU"); |
| 169 | 169 | |
| 170 | 170 | set_handle_irq(&handle_cpu_irq); |
| 171 | − acpi_set_irq_model(ACPI_IRQ_MODEL_LPIC, lpic_get_gsi_domain_id); | |
| 171 | + acpi_set_irq_model(ACPI_IRQ_MODEL_LPIC, lpic_get_gsi_domain_id, NULL); | |
| 172 | 172 | acpi_set_gsi_to_irq_fallback(lpic_gsi_to_irq); |
| 173 | 173 | ret = acpi_cascade_irqdomain_init(); |
| 174 | 174 | |
| @@ -384,7 +384,8 @@ static int __init riscv_intc_acpi_init(union acpi_subtable_headers *header, · 383 unmodified lines | ||
| 384 | 384 | if (rc) |
| 385 | 385 | irq_domain_free_fwnode(fn); |
| 386 | 386 | else |
| 387 | − acpi_set_irq_model(ACPI_IRQ_MODEL_RINTC, riscv_acpi_get_gsi_domain_id); | |
| 387 | + acpi_set_irq_model(ACPI_IRQ_MODEL_RINTC, riscv_acpi_get_gsi_domain_id, | |
| 388 | + acpi_get_riscv_gsi_handle); | |
| 388 | 389 | |
| 389 | 390 | return rc; |
| 390 | 391 | } |
| @@ -94,6 +94,12 @@ static inline void acpi_preset_companion(struct device *dev, · 93 unmodified lines | ||
| 94 | 94 | ACPI_COMPANION_SET(dev, acpi_find_child_device(parent, addr, false)); |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | +static inline void acpi_device_clear_deps(struct device *dev) | |
| 98 | +{ | |
| 99 | + if (has_acpi_companion(dev)) | |
| 100 | + acpi_dev_clear_dependencies(ACPI_COMPANION(dev)); | |
| 101 | +} | |
| 102 | + | |
| 97 | 103 | static inline const char *acpi_dev_name(struct acpi_device *adev) |
| 98 | 104 | { |
| 99 | 105 | return dev_name(&adev->dev); |
| @@ -360,9 +366,10 @@ int acpi_gsi_to_irq (u32 gsi, unsigned int *irq); · 260 unmodified lines | ||
| 360 | 366 | int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi); |
| 361 | 367 | |
| 362 | 368 | typedef struct fwnode_handle *(*acpi_gsi_domain_disp_fn)(u32); |
| 369 | +typedef acpi_handle (*acpi_gsi_handle_disp_fn)(u32); | |
| 363 | 370 | |
| 364 | 371 | void acpi_set_irq_model(enum acpi_irq_model_id model, |
| 365 | − acpi_gsi_domain_disp_fn fn); | |
| 372 | + acpi_gsi_domain_disp_fn fn, acpi_gsi_handle_disp_fn gsi_dep_fn); | |
| 366 | 373 | acpi_gsi_domain_disp_fn acpi_get_gsi_dispatcher(void); |
| 367 | 374 | void acpi_set_gsi_to_irq_fallback(u32 (*)(u32)); |
| 368 | 375 | |
| @@ -372,6 +379,8 @@ struct irq_domain *acpi_irq_create_hierarchy(unsigned int flags, · 3 unmodified lines | ||
| 372 | 379 | const struct irq_domain_ops *ops, |
| 373 | 380 | void *host_data); |
| 374 | 381 | |
| 382 | +u32 acpi_irq_add_auto_dep(acpi_handle handle); | |
| 383 | + | |
| 375 | 384 | #ifdef CONFIG_X86_IO_APIC |
| 376 | 385 | extern int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity); |
| 377 | 386 | #else |
| @@ -908,6 +917,8 @@ static inline void acpi_preset_companion(struct device *dev, · 530 unmodified lines | ||
| 908 | 917 | { |
| 909 | 918 | } |
| 910 | 919 | |
| 920 | +static inline void acpi_device_clear_deps(struct device *dev) {} | |
| 921 | + | |
| 911 | 922 | static inline const char *acpi_dev_name(struct acpi_device *adev) |
| 912 | 923 | { |
| 913 | 924 | return NULL; |
| @@ -27,7 +27,8 @@ int iort_register_domain_token(int trans_id, phys_addr_t base, · 26 unmodified lines | ||
| 27 | 27 | struct fwnode_handle *fw_node); |
| 28 | 28 | void iort_deregister_domain_token(int trans_id); |
| 29 | 29 | struct fwnode_handle *iort_find_domain_token(int trans_id); |
| 30 | −struct fwnode_handle *iort_iwb_handle(u32 iwb_id); | |
| 30 | +acpi_handle iort_iwb_handle(u32 iwb_id); | |
| 31 | +struct fwnode_handle *iort_iwb_handle_fwnode(u32 iwb_id); | |
| 31 | 32 | |
| 32 | 33 | #ifdef CONFIG_ACPI_IORT |
| 33 | 34 | u32 iort_msi_map_id(struct device *dev, u32 id); |