int afu_register_irqs(struct cxl_context *ctx, u32 count) { irq_hw_number_t hwirq; int rc, r, i; if ((rc = cxl_alloc_irq_ranges(&ctx->irqs, ctx->afu->adapter, count))) return rc; /* Multiplexed PSL Interrupt */ ctx->irqs.offset[0] = ctx->afu->psl_hwirq; ctx->irqs.range[0] = 1; ctx->irq_count = count; ctx->irq_bitmap = kcalloc(BITS_TO_LONGS(count), sizeof(*ctx->irq_bitmap), GFP_KERNEL); if (!ctx->irq_bitmap) return -ENOMEM; for (r = 1; r < CXL_IRQ_RANGES; r++) { hwirq = ctx->irqs.offset[r]; for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) { cxl_map_irq(ctx->afu->adapter, hwirq, cxl_irq_afu, ctx); } } return 0; }
int cxl_allocate_afu_irqs(struct cxl_context *ctx, int num) { int res; irq_hw_number_t hwirq; if (num == 0) num = ctx->afu->pp_irqs; res = afu_allocate_irqs(ctx, num); if (res) return res; if (!cpu_has_feature(CPU_FTR_HVMODE)) { /* In a guest, the PSL interrupt is not multiplexed. It was * allocated above, and we need to set its handler */ hwirq = cxl_find_afu_irq(ctx, 0); if (hwirq) cxl_map_irq(ctx->afu->adapter, hwirq, cxl_ops->psl_interrupt, ctx, "psl"); } if (ctx->status == STARTED) { if (cxl_ops->update_ivtes) cxl_ops->update_ivtes(ctx); else WARN(1, "BUG: cxl_allocate_afu_irqs must be called prior to starting the context on this platform\n"); } return res; }
int cxl_map_afu_irq(struct cxl_context *ctx, int num, irq_handler_t handler, void *cookie, char *name) { irq_hw_number_t hwirq; /* * Find interrupt we are to register. */ hwirq = cxl_find_afu_irq(ctx, num); if (!hwirq) return -ENOENT; return cxl_map_irq(ctx->afu->adapter, hwirq, handler, cookie, name); }
static int cxl_register_one_irq(struct cxl *adapter, irq_handler_t handler, void *cookie, irq_hw_number_t *dest_hwirq, unsigned int *dest_virq) { int hwirq, virq; if ((hwirq = cxl_alloc_one_irq(adapter)) < 0) return hwirq; if (!(virq = cxl_map_irq(adapter, hwirq, handler, cookie))) goto err; *dest_hwirq = hwirq; *dest_virq = virq; return 0; err: cxl_release_one_irq(adapter, hwirq); return -ENOMEM; }