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

1 // SPDX-License-Identifier: GPL-2.0-or-later
32 #include <asm/xive-regs.h>
37 #include "xive-internal.h"
57 return -ENOMEM; in xive_irq_bitmap_add()
59 spin_lock_init(&xibm->lock); in xive_irq_bitmap_add()
60 xibm->base = base; in xive_irq_bitmap_add()
61 xibm->count = count; in xive_irq_bitmap_add()
62 xibm->bitmap = bitmap_zalloc(xibm->count, GFP_KERNEL); in xive_irq_bitmap_add()
63 if (!xibm->bitmap) { in xive_irq_bitmap_add()
65 return -ENOMEM; in xive_irq_bitmap_add()
67 list_add(&xibm->list, &xive_irq_bitmaps); in xive_irq_bitmap_add()
69 pr_info("Using IRQ range [%x-%x]", xibm->base, in xive_irq_bitmap_add()
70 xibm->base + xibm->count - 1); in xive_irq_bitmap_add()
79 list_del(&xibm->list); in xive_irq_bitmap_remove_all()
80 bitmap_free(xibm->bitmap); in xive_irq_bitmap_remove_all()
89 irq = find_first_zero_bit(xibm->bitmap, xibm->count); in __xive_irq_bitmap_alloc()
90 if (irq != xibm->count) { in __xive_irq_bitmap_alloc()
91 set_bit(irq, xibm->bitmap); in __xive_irq_bitmap_alloc()
92 irq += xibm->base; in __xive_irq_bitmap_alloc()
94 irq = -ENOMEM; in __xive_irq_bitmap_alloc()
104 int irq = -ENOENT; in xive_irq_bitmap_alloc()
107 spin_lock_irqsave(&xibm->lock, flags); in xive_irq_bitmap_alloc()
109 spin_unlock_irqrestore(&xibm->lock, flags); in xive_irq_bitmap_alloc()
122 if ((irq >= xibm->base) && (irq < xibm->base + xibm->count)) { in xive_irq_bitmap_free()
123 spin_lock_irqsave(&xibm->lock, flags); in xive_irq_bitmap_free()
124 clear_bit(irq - xibm->base, xibm->bitmap); in xive_irq_bitmap_free()
125 spin_unlock_irqrestore(&xibm->lock, flags); in xive_irq_bitmap_free()
133 static unsigned int plpar_busy_delay_time(long rc) in plpar_busy_delay_time() argument
137 if (H_IS_LONG_BUSY(rc)) { in plpar_busy_delay_time()
138 ms = get_longbusy_msecs(rc); in plpar_busy_delay_time()
139 } else if (rc == H_BUSY) { in plpar_busy_delay_time()
146 static unsigned int plpar_busy_delay(int rc) in plpar_busy_delay() argument
150 ms = plpar_busy_delay_time(rc); in plpar_busy_delay()
164 long rc; in plpar_int_reset() local
167 rc = plpar_hcall_norets(H_INT_RESET, flags); in plpar_int_reset()
168 } while (plpar_busy_delay(rc)); in plpar_int_reset()
170 if (rc) in plpar_int_reset()
171 pr_err("H_INT_RESET failed %ld\n", rc); in plpar_int_reset()
173 return rc; in plpar_int_reset()
184 long rc; in plpar_int_get_source_info() local
187 rc = plpar_hcall(H_INT_GET_SOURCE_INFO, retbuf, flags, lisn); in plpar_int_get_source_info()
188 } while (plpar_busy_delay(rc)); in plpar_int_get_source_info()
190 if (rc) { in plpar_int_get_source_info()
191 pr_err("H_INT_GET_SOURCE_INFO lisn=0x%lx failed %ld\n", lisn, rc); in plpar_int_get_source_info()
192 return rc; in plpar_int_get_source_info()
200 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()
206 #define XIVE_SRC_SET_EISN (1ull << (63 - 62))
207 #define XIVE_SRC_MASK (1ull << (63 - 63)) /* unused */
215 long rc; in plpar_int_set_source_config() local
218 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()
223 rc = plpar_hcall_norets(H_INT_SET_SOURCE_CONFIG, flags, lisn, in plpar_int_set_source_config()
225 } while (plpar_busy_delay(rc)); in plpar_int_set_source_config()
227 if (rc) { in plpar_int_set_source_config()
228 pr_err("H_INT_SET_SOURCE_CONFIG lisn=0x%lx target=%ld prio=%ld failed %ld\n", in plpar_int_set_source_config()
229 lisn, target, prio, rc); in plpar_int_set_source_config()
230 return rc; in plpar_int_set_source_config()
243 long rc; in plpar_int_get_source_config() local
245 pr_debug("H_INT_GET_SOURCE_CONFIG flags=0x%lx lisn=0x%lx\n", flags, lisn); in plpar_int_get_source_config()
248 rc = plpar_hcall(H_INT_GET_SOURCE_CONFIG, retbuf, flags, lisn, in plpar_int_get_source_config()
250 } while (plpar_busy_delay(rc)); in plpar_int_get_source_config()
252 if (rc) { in plpar_int_get_source_config()
253 pr_err("H_INT_GET_SOURCE_CONFIG lisn=0x%lx failed %ld\n", in plpar_int_get_source_config()
254 lisn, rc); in plpar_int_get_source_config()
255 return rc; in plpar_int_get_source_config()
275 long rc; in plpar_int_get_queue_info() local
278 rc = plpar_hcall(H_INT_GET_QUEUE_INFO, retbuf, flags, target, in plpar_int_get_queue_info()
280 } while (plpar_busy_delay(rc)); in plpar_int_get_queue_info()
282 if (rc) { in plpar_int_get_queue_info()
284 target, priority, rc); in plpar_int_get_queue_info()
285 return rc; in plpar_int_get_queue_info()
291 pr_debug("H_INT_GET_QUEUE_INFO cpu=%ld prio=%ld page=0x%lx size=0x%lx\n", in plpar_int_get_queue_info()
297 #define XIVE_EQ_ALWAYS_NOTIFY (1ull << (63 - 63))
305 long rc; in plpar_int_set_queue_config() local
307 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()
311 rc = plpar_hcall_norets(H_INT_SET_QUEUE_CONFIG, flags, target, in plpar_int_set_queue_config()
313 } while (plpar_busy_delay(rc)); in plpar_int_set_queue_config()
315 if (rc) { in plpar_int_set_queue_config()
316 pr_err("H_INT_SET_QUEUE_CONFIG cpu=%ld prio=%ld qpage=0x%lx returned %ld\n", in plpar_int_set_queue_config()
317 target, priority, qpage, rc); in plpar_int_set_queue_config()
318 return rc; in plpar_int_set_queue_config()
326 long rc; in plpar_int_sync() local
329 rc = plpar_hcall_norets(H_INT_SYNC, flags, lisn); in plpar_int_sync()
330 } while (plpar_busy_delay(rc)); in plpar_int_sync()
332 if (rc) { in plpar_int_sync()
333 pr_err("H_INT_SYNC lisn=0x%lx returned %ld\n", lisn, rc); in plpar_int_sync()
334 return rc; in plpar_int_sync()
340 #define XIVE_ESB_FLAG_STORE (1ull << (63 - 63))
349 long rc; in plpar_int_esb() local
351 pr_debug("H_INT_ESB flags=0x%lx lisn=0x%lx offset=0x%lx in=0x%lx\n", in plpar_int_esb()
355 rc = plpar_hcall(H_INT_ESB, retbuf, flags, lisn, offset, in plpar_int_esb()
357 } while (plpar_busy_delay(rc)); in plpar_int_esb()
359 if (rc) { in plpar_int_esb()
360 pr_err("H_INT_ESB lisn=0x%lx offset=0x%lx returned %ld\n", in plpar_int_esb()
361 lisn, offset, rc); in plpar_int_esb()
362 return rc; in plpar_int_esb()
373 long rc; in xive_spapr_esb_rw() local
375 rc = plpar_int_esb(write ? XIVE_ESB_FLAG_STORE : 0, in xive_spapr_esb_rw()
377 if (rc) in xive_spapr_esb_rw()
378 return -1; in xive_spapr_esb_rw()
383 #define XIVE_SRC_H_INT_ESB (1ull << (63 - 60))
384 #define XIVE_SRC_LSI (1ull << (63 - 61))
385 #define XIVE_SRC_TRIGGER (1ull << (63 - 62))
386 #define XIVE_SRC_STORE_EOI (1ull << (63 - 63))
390 long rc; in xive_spapr_populate_irq_data() local
398 rc = plpar_int_get_source_info(0, hw_irq, &flags, &eoi_page, &trig_page, in xive_spapr_populate_irq_data()
400 if (rc) in xive_spapr_populate_irq_data()
401 return -EINVAL; in xive_spapr_populate_irq_data()
404 data->flags |= XIVE_IRQ_FLAG_H_INT_ESB; in xive_spapr_populate_irq_data()
406 data->flags |= XIVE_IRQ_FLAG_STORE_EOI; in xive_spapr_populate_irq_data()
408 data->flags |= XIVE_IRQ_FLAG_LSI; in xive_spapr_populate_irq_data()
409 data->eoi_page = eoi_page; in xive_spapr_populate_irq_data()
410 data->esb_shift = esb_shift; in xive_spapr_populate_irq_data()
411 data->trig_page = trig_page; in xive_spapr_populate_irq_data()
413 data->hw_irq = hw_irq; in xive_spapr_populate_irq_data()
416 * No chip-id for the sPAPR backend. This has an impact how we in xive_spapr_populate_irq_data()
419 data->src_chip = XIVE_INVALID_CHIP_ID; in xive_spapr_populate_irq_data()
426 if (data->flags & XIVE_IRQ_FLAG_H_INT_ESB) in xive_spapr_populate_irq_data()
429 data->eoi_mmio = ioremap(data->eoi_page, 1u << data->esb_shift); in xive_spapr_populate_irq_data()
430 if (!data->eoi_mmio) { in xive_spapr_populate_irq_data()
431 pr_err("Failed to map EOI page for irq 0x%x\n", hw_irq); in xive_spapr_populate_irq_data()
432 return -ENOMEM; in xive_spapr_populate_irq_data()
437 data->trig_mmio = data->eoi_mmio; in xive_spapr_populate_irq_data()
441 data->trig_mmio = ioremap(data->trig_page, 1u << data->esb_shift); in xive_spapr_populate_irq_data()
442 if (!data->trig_mmio) { in xive_spapr_populate_irq_data()
443 iounmap(data->eoi_mmio); in xive_spapr_populate_irq_data()
444 pr_err("Failed to map trigger page for irq 0x%x\n", hw_irq); in xive_spapr_populate_irq_data()
445 return -ENOMEM; in xive_spapr_populate_irq_data()
452 long rc; in xive_spapr_configure_irq() local
454 rc = plpar_int_set_source_config(XIVE_SRC_SET_EISN, hw_irq, target, in xive_spapr_configure_irq()
457 return rc == 0 ? 0 : -ENXIO; in xive_spapr_configure_irq()
463 long rc; in xive_spapr_get_irq_config() local
468 rc = plpar_int_get_source_config(0, hw_irq, &h_target, &h_prio, in xive_spapr_get_irq_config()
475 return rc == 0 ? 0 : -ENXIO; in xive_spapr_get_irq_config()
482 s64 rc = 0; in xive_spapr_configure_queue() local
490 return -EINVAL; in xive_spapr_configure_queue()
497 q->msk = order ? ((1u << (order - 2)) - 1) : 0; in xive_spapr_configure_queue()
498 q->idx = 0; in xive_spapr_configure_queue()
499 q->toggle = 0; in xive_spapr_configure_queue()
501 rc = plpar_int_get_queue_info(0, target, prio, &esn_page, &esn_size); in xive_spapr_configure_queue()
502 if (rc) { in xive_spapr_configure_queue()
503 pr_err("Error %lld getting queue info CPU %d prio %d\n", rc, in xive_spapr_configure_queue()
505 rc = -EIO; in xive_spapr_configure_queue()
510 q->eoi_phys = esn_page; in xive_spapr_configure_queue()
516 rc = plpar_int_set_queue_config(flags, target, prio, qpage_phys, order); in xive_spapr_configure_queue()
517 if (rc) { in xive_spapr_configure_queue()
518 pr_err("Error %lld setting queue for CPU %d prio %d\n", rc, in xive_spapr_configure_queue()
520 rc = -EIO; in xive_spapr_configure_queue()
522 q->qpage = qpage; in xive_spapr_configure_queue()
528 return rc; in xive_spapr_configure_queue()
534 struct xive_q *q = &xc->queue[prio]; in xive_spapr_setup_queue()
548 struct xive_q *q = &xc->queue[prio]; in xive_spapr_cleanup_queue()
550 long rc; in xive_spapr_cleanup_queue() local
553 rc = plpar_int_set_queue_config(0, hw_cpu, prio, 0, 0); in xive_spapr_cleanup_queue()
554 if (rc) in xive_spapr_cleanup_queue()
555 pr_err("Error %ld setting queue for CPU %d prio %d\n", rc, in xive_spapr_cleanup_queue()
560 uv_unshare_page(PHYS_PFN(__pa(q->qpage)), 1 << alloc_order); in xive_spapr_cleanup_queue()
561 free_pages((unsigned long)q->qpage, alloc_order); in xive_spapr_cleanup_queue()
562 q->qpage = NULL; in xive_spapr_cleanup_queue()
578 return -ENXIO; in xive_spapr_get_ipi()
581 xc->hw_ipi = irq; in xive_spapr_get_ipi()
587 if (xc->hw_ipi == XIVE_BAD_IRQ) in xive_spapr_put_ipi()
590 xive_irq_bitmap_free(xc->hw_ipi); in xive_spapr_put_ipi()
591 xc->hw_ipi = XIVE_BAD_IRQ; in xive_spapr_put_ipi()
632 xc->pending_prio |= 1 << cppr; in xive_spapr_update_pending()
638 if (cppr >= xc->cppr) in xive_spapr_update_pending()
640 smp_processor_id(), cppr, xc->cppr); in xive_spapr_update_pending()
643 xc->cppr = cppr; in xive_spapr_update_pending()
650 pr_debug("(HW value: %08x %08x %08x)\n", in xive_spapr_setup_cpu()
673 return -ENOMEM; in xive_spapr_debug_show()
677 bitmap_print_to_pagebuf(true, buf, xibm->bitmap, xibm->count); in xive_spapr_debug_show()
678 seq_printf(m, "bitmap #%d: %s", xibm->count, buf); in xive_spapr_debug_show()
707 * get max priority from "/ibm,plat-res-int-priorities"
722 reg = of_get_property(rootdn, "ibm,plat-res-int-priorities", &len); in xive_get_max_prio()
725 pr_err("Failed to read 'ibm,plat-res-int-priorities' property\n"); in xive_get_max_prio()
730 pr_err("invalid 'ibm,plat-res-int-priorities' property\n"); in xive_get_max_prio()
734 /* HW supports priorities in the range [0-7] and 0xFF is a in xive_get_max_prio()
756 pr_err("no valid priority found in 'ibm,plat-res-int-priorities'\n"); in xive_get_max_prio()
772 if (chosen == -FDT_ERR_NOTFOUND) in get_vec5_feature()
775 vec5 = of_get_flat_dt_prop(chosen, "ibm,architecture-vec-5", &size); in get_vec5_feature()
804 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", val) { in xive_spapr_init()
880 pr_info("Using %dkB queues\n", 1 << (xive_queue_shift - 10)); in xive_spapr_init()