1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * ACPI GSI IRQ layer 4 * 5 * Copyright (C) 2015 ARM Ltd. 6 * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> 7 */ 8 #include <linux/acpi.h> 9 #include <linux/irq.h> 10 #include <linux/irqdomain.h> 11 #include <linux/of.h> 12 13 enum acpi_irq_model_id acpi_irq_model; 14 15 static acpi_gsi_domain_disp_fn acpi_get_gsi_domain_id; 16 static acpi_gsi_handle_disp_fn acpi_get_gsi_handle; 17 static u32 (*acpi_gsi_to_irq_fallback)(u32 gsi); 18 19 /** 20 * acpi_gsi_to_irq() - Retrieve the linux irq number for a given GSI 21 * @gsi: GSI IRQ number to map 22 * @irq: pointer where linux IRQ number is stored 23 * 24 * irq location updated with irq value [>0 on success, 0 on failure] 25 * 26 * Returns: 0 on success 27 * -EINVAL on failure 28 */ 29 int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) 30 { 31 struct irq_domain *d; 32 33 d = irq_find_matching_fwnode(acpi_get_gsi_domain_id(gsi), 34 DOMAIN_BUS_ANY); 35 *irq = irq_find_mapping(d, gsi); 36 /* 37 * *irq == 0 means no mapping, that should be reported as a 38 * failure, unless there is an arch-specific fallback handler. 39 */ 40 if (!*irq && acpi_gsi_to_irq_fallback) 41 *irq = acpi_gsi_to_irq_fallback(gsi); 42 43 return (*irq > 0) ? 0 : -EINVAL; 44 } 45 EXPORT_SYMBOL_GPL(acpi_gsi_to_irq); 46 47 /** 48 * acpi_register_gsi() - Map a GSI to a linux IRQ number 49 * @dev: device for which IRQ has to be mapped 50 * @gsi: GSI IRQ number 51 * @trigger: trigger type of the GSI number to be mapped 52 * @polarity: polarity of the GSI to be mapped 53 * 54 * Returns: a valid linux IRQ number on success 55 * -EINVAL on failure 56 */ 57 int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, 58 int polarity) 59 { 60 struct irq_fwspec fwspec; 61 unsigned int irq; 62 63 fwspec.fwnode = acpi_get_gsi_domain_id(gsi); 64 if (WARN_ON(!fwspec.fwnode)) { 65 pr_warn("GSI: No registered irqchip, giving up\n"); 66 return -EINVAL; 67 } 68 69 fwspec.param[0] = gsi; 70 fwspec.param[1] = acpi_dev_get_irq_type(trigger, polarity); 71 fwspec.param_count = 2; 72 73 irq = irq_create_fwspec_mapping(&fwspec); 74 if (!irq) 75 return -EINVAL; 76 77 return irq; 78 } 79 EXPORT_SYMBOL_GPL(acpi_register_gsi); 80 81 /** 82 * acpi_unregister_gsi() - Free a GSI<->linux IRQ number mapping 83 * @gsi: GSI IRQ number 84 */ 85 void acpi_unregister_gsi(u32 gsi) 86 { 87 struct irq_domain *d; 88 int irq; 89 90 if (WARN_ON(acpi_irq_model == ACPI_IRQ_MODEL_GIC && gsi < 16)) 91 return; 92 93 d = irq_find_matching_fwnode(acpi_get_gsi_domain_id(gsi), 94 DOMAIN_BUS_ANY); 95 irq = irq_find_mapping(d, gsi); 96 irq_dispose_mapping(irq); 97 } 98 EXPORT_SYMBOL_GPL(acpi_unregister_gsi); 99 100 /** 101 * acpi_get_irq_source_fwhandle() - Retrieve fwhandle from IRQ resource source. 102 * @source: acpi_resource_source to use for the lookup. 103 * @gsi: GSI IRQ number 104 * 105 * Description: 106 * Retrieve the fwhandle of the device referenced by the given IRQ resource 107 * source. 108 * 109 * Return: 110 * The referenced device fwhandle or NULL on failure 111 */ 112 static struct fwnode_handle * 113 acpi_get_irq_source_fwhandle(const struct acpi_resource_source *source, 114 u32 gsi) 115 { 116 struct fwnode_handle *result; 117 struct acpi_device *device; 118 acpi_handle handle; 119 acpi_status status; 120 121 if (!source->string_length) 122 return acpi_get_gsi_domain_id(gsi); 123 124 status = acpi_get_handle(NULL, source->string_ptr, &handle); 125 if (WARN_ON(ACPI_FAILURE(status))) 126 return NULL; 127 128 device = acpi_get_acpi_dev(handle); 129 if (WARN_ON(!device)) 130 return NULL; 131 132 result = &device->fwnode; 133 acpi_put_acpi_dev(device); 134 return result; 135 } 136 137 /* 138 * Context for the resource walk used to lookup IRQ resources. 139 * Contains a return code, the lookup index, and references to the flags 140 * and fwspec where the result is returned. 141 */ 142 struct acpi_irq_parse_one_ctx { 143 int rc; 144 unsigned int index; 145 unsigned long *res_flags; 146 struct irq_fwspec *fwspec; 147 }; 148 149 /** 150 * acpi_irq_parse_one_match - Handle a matching IRQ resource. 151 * @fwnode: matching fwnode 152 * @hwirq: hardware IRQ number 153 * @triggering: triggering attributes of hwirq 154 * @polarity: polarity attributes of hwirq 155 * @polarity: polarity attributes of hwirq 156 * @shareable: shareable attributes of hwirq 157 * @wake_capable: wake capable attribute of hwirq 158 * @ctx: acpi_irq_parse_one_ctx updated by this function 159 * 160 * Description: 161 * Handle a matching IRQ resource by populating the given ctx with 162 * the information passed. 163 */ 164 static inline void acpi_irq_parse_one_match(struct fwnode_handle *fwnode, 165 u32 hwirq, u8 triggering, 166 u8 polarity, u8 shareable, 167 u8 wake_capable, 168 struct acpi_irq_parse_one_ctx *ctx) 169 { 170 if (!fwnode) 171 return; 172 ctx->rc = 0; 173 *ctx->res_flags = acpi_dev_irq_flags(triggering, polarity, shareable, wake_capable); 174 ctx->fwspec->fwnode = fwnode; 175 ctx->fwspec->param[0] = hwirq; 176 ctx->fwspec->param[1] = acpi_dev_get_irq_type(triggering, polarity); 177 ctx->fwspec->param_count = 2; 178 } 179 180 /** 181 * acpi_irq_parse_one_cb - Handle the given resource. 182 * @ares: resource to handle 183 * @context: context for the walk 184 * 185 * Description: 186 * This is called by acpi_walk_resources passing each resource returned by 187 * the _CRS method. We only inspect IRQ resources. Since IRQ resources 188 * might contain multiple interrupts we check if the index is within this 189 * one's interrupt array, otherwise we subtract the current resource IRQ 190 * count from the lookup index to prepare for the next resource. 191 * Once a match is found we call acpi_irq_parse_one_match to populate 192 * the result and end the walk by returning AE_CTRL_TERMINATE. 193 * 194 * Return: 195 * AE_OK if the walk should continue, AE_CTRL_TERMINATE if a matching 196 * IRQ resource was found. 197 */ 198 static acpi_status acpi_irq_parse_one_cb(struct acpi_resource *ares, 199 void *context) 200 { 201 struct acpi_irq_parse_one_ctx *ctx = context; 202 struct acpi_resource_irq *irq; 203 struct acpi_resource_extended_irq *eirq; 204 struct fwnode_handle *fwnode; 205 206 switch (ares->type) { 207 case ACPI_RESOURCE_TYPE_IRQ: 208 irq = &ares->data.irq; 209 if (ctx->index >= irq->interrupt_count) { 210 ctx->index -= irq->interrupt_count; 211 return AE_OK; 212 } 213 fwnode = acpi_get_gsi_domain_id(irq->interrupts[ctx->index]); 214 acpi_irq_parse_one_match(fwnode, irq->interrupts[ctx->index], 215 irq->triggering, irq->polarity, 216 irq->shareable, irq->wake_capable, ctx); 217 return AE_CTRL_TERMINATE; 218 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 219 eirq = &ares->data.extended_irq; 220 if (eirq->producer_consumer == ACPI_PRODUCER) 221 return AE_OK; 222 if (ctx->index >= eirq->interrupt_count) { 223 ctx->index -= eirq->interrupt_count; 224 return AE_OK; 225 } 226 fwnode = acpi_get_irq_source_fwhandle(&eirq->resource_source, 227 eirq->interrupts[ctx->index]); 228 acpi_irq_parse_one_match(fwnode, eirq->interrupts[ctx->index], 229 eirq->triggering, eirq->polarity, 230 eirq->shareable, eirq->wake_capable, ctx); 231 return AE_CTRL_TERMINATE; 232 } 233 234 return AE_OK; 235 } 236 237 /** 238 * acpi_irq_parse_one - Resolve an interrupt for a device 239 * @handle: the device whose interrupt is to be resolved 240 * @index: index of the interrupt to resolve 241 * @fwspec: structure irq_fwspec filled by this function 242 * @flags: resource flags filled by this function 243 * 244 * Description: 245 * Resolves an interrupt for a device by walking its CRS resources to find 246 * the appropriate ACPI IRQ resource and populating the given struct irq_fwspec 247 * and flags. 248 * 249 * Return: 250 * The result stored in ctx.rc by the callback, or the default -EINVAL value 251 * if an error occurs. 252 */ 253 static int acpi_irq_parse_one(acpi_handle handle, unsigned int index, 254 struct irq_fwspec *fwspec, unsigned long *flags) 255 { 256 struct acpi_irq_parse_one_ctx ctx = { -EINVAL, index, flags, fwspec }; 257 258 acpi_walk_resources(handle, METHOD_NAME__CRS, acpi_irq_parse_one_cb, &ctx); 259 return ctx.rc; 260 } 261 262 /** 263 * acpi_irq_get - Lookup an ACPI IRQ resource and use it to initialize resource. 264 * @handle: ACPI device handle 265 * @index: ACPI IRQ resource index to lookup 266 * @res: Linux IRQ resource to initialize 267 * 268 * Description: 269 * Look for the ACPI IRQ resource with the given index and use it to initialize 270 * the given Linux IRQ resource. 271 * 272 * Return: 273 * 0 on success 274 * -EINVAL if an error occurs 275 * -EPROBE_DEFER if the IRQ lookup/conversion failed 276 */ 277 int acpi_irq_get(acpi_handle handle, unsigned int index, struct resource *res) 278 { 279 struct irq_fwspec fwspec; 280 struct irq_domain *domain; 281 unsigned long flags; 282 int rc; 283 284 rc = acpi_irq_parse_one(handle, index, &fwspec, &flags); 285 if (rc) 286 return rc; 287 288 domain = irq_find_matching_fwnode(fwspec.fwnode, DOMAIN_BUS_ANY); 289 if (!domain) 290 return -EPROBE_DEFER; 291 292 rc = irq_create_fwspec_mapping(&fwspec); 293 if (rc <= 0) 294 return -EINVAL; 295 296 res->start = rc; 297 res->end = rc; 298 res->flags = flags; 299 300 return 0; 301 } 302 EXPORT_SYMBOL_GPL(acpi_irq_get); 303 304 const struct cpumask *acpi_irq_get_affinity(acpi_handle handle, 305 unsigned int index) 306 { 307 struct irq_fwspec_info info; 308 struct irq_fwspec fwspec; 309 unsigned long flags; 310 311 if (acpi_irq_parse_one(handle, index, &fwspec, &flags)) 312 return NULL; 313 314 if (irq_populate_fwspec_info(&fwspec, &info)) 315 return NULL; 316 317 if (!(info.flags & IRQ_FWSPEC_INFO_AFFINITY_VALID)) 318 return NULL; 319 320 return info.affinity; 321 } 322 323 /** 324 * acpi_set_irq_model - Setup the GSI irqdomain information 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 * 331 */ 332 void __init acpi_set_irq_model(enum acpi_irq_model_id model, 333 acpi_gsi_domain_disp_fn fn, acpi_gsi_handle_disp_fn gsi_dep_fn) 334 { 335 acpi_irq_model = model; 336 acpi_get_gsi_domain_id = fn; 337 acpi_get_gsi_handle = gsi_dep_fn; 338 } 339 340 /* 341 * acpi_get_gsi_dispatcher() - Get the GSI dispatcher function 342 * 343 * Return the dispatcher function that computes the domain fwnode for 344 * a given GSI. 345 */ 346 acpi_gsi_domain_disp_fn acpi_get_gsi_dispatcher(void) 347 { 348 return acpi_get_gsi_domain_id; 349 } 350 EXPORT_SYMBOL_GPL(acpi_get_gsi_dispatcher); 351 352 /** 353 * acpi_set_gsi_to_irq_fallback - Register a GSI transfer 354 * callback to fallback to arch specified implementation. 355 * @fn: arch-specific fallback handler 356 */ 357 void __init acpi_set_gsi_to_irq_fallback(u32 (*fn)(u32)) 358 { 359 acpi_gsi_to_irq_fallback = fn; 360 } 361 362 /** 363 * acpi_irq_create_hierarchy - Create a hierarchical IRQ domain with the default 364 * GSI domain as its parent. 365 * @flags: Irq domain flags associated with the domain 366 * @size: Size of the domain. 367 * @fwnode: Optional fwnode of the interrupt controller 368 * @ops: Pointer to the interrupt domain callbacks 369 * @host_data: Controller private data pointer 370 */ 371 struct irq_domain *acpi_irq_create_hierarchy(unsigned int flags, 372 unsigned int size, 373 struct fwnode_handle *fwnode, 374 const struct irq_domain_ops *ops, 375 void *host_data) 376 { 377 struct irq_domain *d; 378 379 /* This only works for the GIC model... */ 380 if (acpi_irq_model != ACPI_IRQ_MODEL_GIC) 381 return NULL; 382 383 d = irq_find_matching_fwnode(acpi_get_gsi_domain_id(0), 384 DOMAIN_BUS_ANY); 385 386 if (!d) 387 return NULL; 388 389 return irq_domain_create_hierarchy(d, flags, size, fwnode, ops, 390 host_data); 391 } 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 } 552