Lines Matching +full:x +full:- +full:rc

1 // SPDX-License-Identifier: GPL-2.0-or-later
31 #include <asm/xive-regs.h>
36 #include "xive-internal.h"
56 return -ENOMEM; in xive_irq_bitmap_add()
58 spin_lock_init(&xibm->lock); in xive_irq_bitmap_add()
59 xibm->base = base; in xive_irq_bitmap_add()
60 xibm->count = count; in xive_irq_bitmap_add()
61 xibm->bitmap = bitmap_zalloc(xibm->count, GFP_KERNEL); in xive_irq_bitmap_add()
62 if (!xibm->bitmap) { in xive_irq_bitmap_add()
64 return -ENOMEM; in xive_irq_bitmap_add()
66 list_add(&xibm->list, &xive_irq_bitmaps); in xive_irq_bitmap_add()
68 pr_info("Using IRQ range [%x-%x]", xibm->base, in xive_irq_bitmap_add()
69 xibm->base + xibm->count - 1); in xive_irq_bitmap_add()
78 list_del(&xibm->list); in xive_irq_bitmap_remove_all()
79 bitmap_free(xibm->bitmap); in xive_irq_bitmap_remove_all()
88 irq = find_first_zero_bit(xibm->bitmap, xibm->count); in __xive_irq_bitmap_alloc()
89 if (irq != xibm->count) { in __xive_irq_bitmap_alloc()
90 set_bit(irq, xibm->bitmap); in __xive_irq_bitmap_alloc()
91 irq += xibm->base; in __xive_irq_bitmap_alloc()
93 irq = -ENOMEM; in __xive_irq_bitmap_alloc()
103 int irq = -ENOENT; in xive_irq_bitmap_alloc()
106 spin_lock_irqsave(&xibm->lock, flags); in xive_irq_bitmap_alloc()
108 spin_unlock_irqrestore(&xibm->lock, flags); in xive_irq_bitmap_alloc()
121 if ((irq >= xibm->base) && (irq < xibm->base + xibm->count)) { in xive_irq_bitmap_free()
122 spin_lock_irqsave(&xibm->lock, flags); in xive_irq_bitmap_free()
123 clear_bit(irq - xibm->base, xibm->bitmap); in xive_irq_bitmap_free()
124 spin_unlock_irqrestore(&xibm->lock, flags); in xive_irq_bitmap_free()
132 static unsigned int plpar_busy_delay_time(long rc) in plpar_busy_delay_time() argument
136 if (H_IS_LONG_BUSY(rc)) { in plpar_busy_delay_time()
137 ms = get_longbusy_msecs(rc); in plpar_busy_delay_time()
138 } else if (rc == H_BUSY) { in plpar_busy_delay_time()
145 static unsigned int plpar_busy_delay(int rc) in plpar_busy_delay() argument
149 ms = plpar_busy_delay_time(rc); in plpar_busy_delay()
163 long rc; in plpar_int_reset() local
166 rc = plpar_hcall_norets(H_INT_RESET, flags); in plpar_int_reset()
167 } while (plpar_busy_delay(rc)); in plpar_int_reset()
169 if (rc) in plpar_int_reset()
170 pr_err("H_INT_RESET failed %ld\n", rc); in plpar_int_reset()
172 return rc; in plpar_int_reset()
183 long rc; in plpar_int_get_source_info() local
186 rc = plpar_hcall(H_INT_GET_SOURCE_INFO, retbuf, flags, lisn); in plpar_int_get_source_info()
187 } while (plpar_busy_delay(rc)); in plpar_int_get_source_info()
189 if (rc) { in plpar_int_get_source_info()
190 pr_err("H_INT_GET_SOURCE_INFO lisn=0x%lx failed %ld\n", lisn, rc); in plpar_int_get_source_info()
191 return rc; in plpar_int_get_source_info()
199 pr_debug("H_INT_GET_SOURCE_INFO lisn=0x%lx flags=0x%lx eoi=0x%lx trig=0x%lx shift=0x%lx\n", in plpar_int_get_source_info()
205 #define XIVE_SRC_SET_EISN (1ull << (63 - 62))
206 #define XIVE_SRC_MASK (1ull << (63 - 63)) /* unused */
214 long rc; in plpar_int_set_source_config() local
217 pr_debug("H_INT_SET_SOURCE_CONFIG flags=0x%lx lisn=0x%lx target=%ld prio=%ld sw_irq=%ld\n", in plpar_int_set_source_config()
222 rc = plpar_hcall_norets(H_INT_SET_SOURCE_CONFIG, flags, lisn, in plpar_int_set_source_config()
224 } while (plpar_busy_delay(rc)); in plpar_int_set_source_config()
226 if (rc) { in plpar_int_set_source_config()
227 pr_err("H_INT_SET_SOURCE_CONFIG lisn=0x%lx target=%ld prio=%ld failed %ld\n", in plpar_int_set_source_config()
228 lisn, target, prio, rc); in plpar_int_set_source_config()
229 return rc; in plpar_int_set_source_config()
242 long rc; in plpar_int_get_source_config() local
244 pr_debug("H_INT_GET_SOURCE_CONFIG flags=0x%lx lisn=0x%lx\n", flags, lisn); in plpar_int_get_source_config()
247 rc = plpar_hcall(H_INT_GET_SOURCE_CONFIG, retbuf, flags, lisn, in plpar_int_get_source_config()
249 } while (plpar_busy_delay(rc)); in plpar_int_get_source_config()
251 if (rc) { in plpar_int_get_source_config()
252 pr_err("H_INT_GET_SOURCE_CONFIG lisn=0x%lx failed %ld\n", in plpar_int_get_source_config()
253 lisn, rc); in plpar_int_get_source_config()
254 return rc; in plpar_int_get_source_config()
274 long rc; in plpar_int_get_queue_info() local
277 rc = plpar_hcall(H_INT_GET_QUEUE_INFO, retbuf, flags, target, in plpar_int_get_queue_info()
279 } while (plpar_busy_delay(rc)); in plpar_int_get_queue_info()
281 if (rc) { in plpar_int_get_queue_info()
283 target, priority, rc); in plpar_int_get_queue_info()
284 return rc; in plpar_int_get_queue_info()
290 pr_debug("H_INT_GET_QUEUE_INFO cpu=%ld prio=%ld page=0x%lx size=0x%lx\n", in plpar_int_get_queue_info()
296 #define XIVE_EQ_ALWAYS_NOTIFY (1ull << (63 - 63))
304 long rc; in plpar_int_set_queue_config() local
306 pr_debug("H_INT_SET_QUEUE_CONFIG flags=0x%lx target=%ld priority=0x%lx qpage=0x%lx qsize=0x%lx\n", in plpar_int_set_queue_config()
310 rc = plpar_hcall_norets(H_INT_SET_QUEUE_CONFIG, flags, target, in plpar_int_set_queue_config()
312 } while (plpar_busy_delay(rc)); in plpar_int_set_queue_config()
314 if (rc) { in plpar_int_set_queue_config()
315 pr_err("H_INT_SET_QUEUE_CONFIG cpu=%ld prio=%ld qpage=0x%lx returned %ld\n", in plpar_int_set_queue_config()
316 target, priority, qpage, rc); in plpar_int_set_queue_config()
317 return rc; in plpar_int_set_queue_config()
325 long rc; in plpar_int_sync() local
328 rc = plpar_hcall_norets(H_INT_SYNC, flags, lisn); in plpar_int_sync()
329 } while (plpar_busy_delay(rc)); in plpar_int_sync()
331 if (rc) { in plpar_int_sync()
332 pr_err("H_INT_SYNC lisn=0x%lx returned %ld\n", lisn, rc); in plpar_int_sync()
333 return rc; in plpar_int_sync()
339 #define XIVE_ESB_FLAG_STORE (1ull << (63 - 63))
348 long rc; in plpar_int_esb() local
350 pr_debug("H_INT_ESB flags=0x%lx lisn=0x%lx offset=0x%lx in=0x%lx\n", in plpar_int_esb()
354 rc = plpar_hcall(H_INT_ESB, retbuf, flags, lisn, offset, in plpar_int_esb()
356 } while (plpar_busy_delay(rc)); in plpar_int_esb()
358 if (rc) { in plpar_int_esb()
359 pr_err("H_INT_ESB lisn=0x%lx offset=0x%lx returned %ld\n", in plpar_int_esb()
360 lisn, offset, rc); in plpar_int_esb()
361 return rc; in plpar_int_esb()
372 long rc; in xive_spapr_esb_rw() local
374 rc = plpar_int_esb(write ? XIVE_ESB_FLAG_STORE : 0, in xive_spapr_esb_rw()
376 if (rc) in xive_spapr_esb_rw()
377 return -1; in xive_spapr_esb_rw()
382 #define XIVE_SRC_H_INT_ESB (1ull << (63 - 60))
383 #define XIVE_SRC_LSI (1ull << (63 - 61))
384 #define XIVE_SRC_TRIGGER (1ull << (63 - 62))
385 #define XIVE_SRC_STORE_EOI (1ull << (63 - 63))
389 long rc; in xive_spapr_populate_irq_data() local
397 rc = plpar_int_get_source_info(0, hw_irq, &flags, &eoi_page, &trig_page, in xive_spapr_populate_irq_data()
399 if (rc) in xive_spapr_populate_irq_data()
400 return -EINVAL; in xive_spapr_populate_irq_data()
403 data->flags |= XIVE_IRQ_FLAG_H_INT_ESB; in xive_spapr_populate_irq_data()
405 data->flags |= XIVE_IRQ_FLAG_STORE_EOI; in xive_spapr_populate_irq_data()
407 data->flags |= XIVE_IRQ_FLAG_LSI; in xive_spapr_populate_irq_data()
408 data->eoi_page = eoi_page; in xive_spapr_populate_irq_data()
409 data->esb_shift = esb_shift; in xive_spapr_populate_irq_data()
410 data->trig_page = trig_page; in xive_spapr_populate_irq_data()
412 data->hw_irq = hw_irq; in xive_spapr_populate_irq_data()
415 * No chip-id for the sPAPR backend. This has an impact how we in xive_spapr_populate_irq_data()
418 data->src_chip = XIVE_INVALID_CHIP_ID; in xive_spapr_populate_irq_data()
425 if (data->flags & XIVE_IRQ_FLAG_H_INT_ESB) in xive_spapr_populate_irq_data()
428 data->eoi_mmio = ioremap(data->eoi_page, 1u << data->esb_shift); in xive_spapr_populate_irq_data()
429 if (!data->eoi_mmio) { in xive_spapr_populate_irq_data()
430 pr_err("Failed to map EOI page for irq 0x%x\n", hw_irq); in xive_spapr_populate_irq_data()
431 return -ENOMEM; in xive_spapr_populate_irq_data()
436 data->trig_mmio = data->eoi_mmio; in xive_spapr_populate_irq_data()
440 data->trig_mmio = ioremap(data->trig_page, 1u << data->esb_shift); in xive_spapr_populate_irq_data()
441 if (!data->trig_mmio) { in xive_spapr_populate_irq_data()
442 iounmap(data->eoi_mmio); in xive_spapr_populate_irq_data()
443 pr_err("Failed to map trigger page for irq 0x%x\n", hw_irq); in xive_spapr_populate_irq_data()
444 return -ENOMEM; in xive_spapr_populate_irq_data()
451 long rc; in xive_spapr_configure_irq() local
453 rc = plpar_int_set_source_config(XIVE_SRC_SET_EISN, hw_irq, target, in xive_spapr_configure_irq()
456 return rc == 0 ? 0 : -ENXIO; in xive_spapr_configure_irq()
462 long rc; in xive_spapr_get_irq_config() local
467 rc = plpar_int_get_source_config(0, hw_irq, &h_target, &h_prio, in xive_spapr_get_irq_config()
474 return rc == 0 ? 0 : -ENXIO; in xive_spapr_get_irq_config()
481 s64 rc = 0; in xive_spapr_configure_queue() local
489 return -EINVAL; in xive_spapr_configure_queue()
496 q->msk = order ? ((1u << (order - 2)) - 1) : 0; in xive_spapr_configure_queue()
497 q->idx = 0; in xive_spapr_configure_queue()
498 q->toggle = 0; in xive_spapr_configure_queue()
500 rc = plpar_int_get_queue_info(0, target, prio, &esn_page, &esn_size); in xive_spapr_configure_queue()
501 if (rc) { in xive_spapr_configure_queue()
502 pr_err("Error %lld getting queue info CPU %d prio %d\n", rc, in xive_spapr_configure_queue()
504 rc = -EIO; in xive_spapr_configure_queue()
509 q->eoi_phys = esn_page; in xive_spapr_configure_queue()
515 rc = plpar_int_set_queue_config(flags, target, prio, qpage_phys, order); in xive_spapr_configure_queue()
516 if (rc) { in xive_spapr_configure_queue()
517 pr_err("Error %lld setting queue for CPU %d prio %d\n", rc, in xive_spapr_configure_queue()
519 rc = -EIO; in xive_spapr_configure_queue()
521 q->qpage = qpage; in xive_spapr_configure_queue()
527 return rc; in xive_spapr_configure_queue()
533 struct xive_q *q = &xc->queue[prio]; in xive_spapr_setup_queue()
547 struct xive_q *q = &xc->queue[prio]; in xive_spapr_cleanup_queue()
549 long rc; in xive_spapr_cleanup_queue() local
552 rc = plpar_int_set_queue_config(0, hw_cpu, prio, 0, 0); in xive_spapr_cleanup_queue()
553 if (rc) in xive_spapr_cleanup_queue()
554 pr_err("Error %ld setting queue for CPU %d prio %d\n", rc, in xive_spapr_cleanup_queue()
559 uv_unshare_page(PHYS_PFN(__pa(q->qpage)), 1 << alloc_order); in xive_spapr_cleanup_queue()
560 free_pages((unsigned long)q->qpage, alloc_order); in xive_spapr_cleanup_queue()
561 q->qpage = NULL; in xive_spapr_cleanup_queue()
577 return -ENXIO; in xive_spapr_get_ipi()
580 xc->hw_ipi = irq; in xive_spapr_get_ipi()
586 if (xc->hw_ipi == XIVE_BAD_IRQ) in xive_spapr_put_ipi()
589 xive_irq_bitmap_free(xc->hw_ipi); in xive_spapr_put_ipi()
590 xc->hw_ipi = XIVE_BAD_IRQ; in xive_spapr_put_ipi()
631 xc->pending_prio |= 1 << cppr; in xive_spapr_update_pending()
637 if (cppr >= xc->cppr) in xive_spapr_update_pending()
639 smp_processor_id(), cppr, xc->cppr); in xive_spapr_update_pending()
642 xc->cppr = cppr; in xive_spapr_update_pending()
649 pr_debug("(HW value: %08x %08x %08x)\n", in xive_spapr_setup_cpu()
672 return -ENOMEM; in xive_spapr_debug_show()
676 bitmap_print_to_pagebuf(true, buf, xibm->bitmap, xibm->count); in xive_spapr_debug_show()
677 seq_printf(m, "bitmap #%d: %s", xibm->count, buf); in xive_spapr_debug_show()
706 * get max priority from "/ibm,plat-res-int-priorities"
721 reg = of_get_property(rootdn, "ibm,plat-res-int-priorities", &len); in xive_get_max_prio()
724 pr_err("Failed to read 'ibm,plat-res-int-priorities' property\n"); in xive_get_max_prio()
729 pr_err("invalid 'ibm,plat-res-int-priorities' property\n"); in xive_get_max_prio()
733 /* HW supports priorities in the range [0-7] and 0xFF is a in xive_get_max_prio()
755 pr_err("no valid priority found in 'ibm,plat-res-int-priorities'\n"); in xive_get_max_prio()
771 if (chosen == -FDT_ERR_NOTFOUND) in get_vec5_feature()
774 vec5 = of_get_flat_dt_prop(chosen, "ibm,architecture-vec-5", &size); in get_vec5_feature()
803 pr_warn("%s: Unknown xive support option: 0x%x\n", in xive_spapr_disabled()
828 np = of_find_compatible_node(NULL, NULL, "ibm,power-ivpe"); in xive_spapr_init()
833 pr_devel("Found %s\n", np->full_name); in xive_spapr_init()
850 reg = of_get_property(np, "ibm,xive-lisn-ranges", &len); in xive_spapr_init()
852 pr_err("Failed to read 'ibm,xive-lisn-ranges' property\n"); in xive_spapr_init()
857 pr_err("invalid 'ibm,xive-lisn-ranges' property\n"); in xive_spapr_init()
869 of_property_for_each_u32(np, "ibm,xive-eq-sizes", prop, reg, val) { in xive_spapr_init()
880 pr_info("Using %dkB queues\n", 1 << (xive_queue_shift - 10)); in xive_spapr_init()