1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright 2006-2007, Michael Ellerman, IBM Corporation. 4 */ 5 6 #include <linux/irq.h> 7 #include <linux/irqdomain.h> 8 #include <linux/of_irq.h> 9 #include <linux/bitmap.h> 10 #include <linux/msi.h> 11 #include <asm/mpic.h> 12 #include <asm/hw_irq.h> 13 #include <asm/ppc-pci.h> 14 #include <asm/msi_bitmap.h> 15 16 #include <sysdev/mpic.h> 17 18 void mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq) 19 { 20 /* The mpic calls this even when there is no allocator setup */ 21 if (!mpic->msi_bitmap.bitmap) 22 return; 23 24 msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, hwirq); 25 } 26 27 #ifdef CONFIG_MPIC_U3_HT_IRQS 28 static int __init mpic_msi_reserve_u3_hwirqs(struct mpic *mpic) 29 { 30 irq_hw_number_t hwirq; 31 const struct irq_domain_ops *ops = mpic->irqhost->ops; 32 struct device_node *np; 33 int flags, index, i; 34 struct of_phandle_args oirq; 35 36 pr_debug("mpic: found U3, guessing msi allocator setup\n"); 37 38 /* Reserve source numbers we know are reserved in the HW. 39 * 40 * This is a bit of a mix of U3 and U4 reserves but that's going 41 * to work fine, we have plenty enough numbers left so let's just 42 * mark anything we don't like reserved. 43 */ 44 for (i = 0; i < 8; i++) 45 msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i); 46 47 for (i = 42; i < 46; i++) 48 msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i); 49 50 for (i = 100; i < 105; i++) 51 msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i); 52 53 for (i = 124; i < mpic->num_sources; i++) 54 msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i); 55 56 57 np = NULL; 58 while ((np = of_find_all_nodes(np))) { 59 pr_debug("mpic: mapping hwirqs for %pOF\n", np); 60 61 index = 0; 62 while (of_irq_parse_one(np, index++, &oirq) == 0) { 63 ops->xlate(mpic->irqhost, NULL, oirq.args, 64 oirq.args_count, &hwirq, &flags); 65 msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, hwirq); 66 } 67 } 68 69 return 0; 70 } 71 #else 72 static int __init mpic_msi_reserve_u3_hwirqs(struct mpic *mpic) 73 { 74 return -1; 75 } 76 #endif 77 78 int __init mpic_msi_init_allocator(struct mpic *mpic) 79 { 80 int rc; 81 82 rc = msi_bitmap_alloc(&mpic->msi_bitmap, mpic->num_sources, 83 irq_domain_get_of_node(mpic->irqhost)); 84 if (rc) 85 return rc; 86 87 rc = msi_bitmap_reserve_dt_hwirqs(&mpic->msi_bitmap); 88 if (rc > 0) { 89 if (mpic->flags & MPIC_U3_HT_IRQS) 90 rc = mpic_msi_reserve_u3_hwirqs(mpic); 91 92 if (rc) { 93 msi_bitmap_free(&mpic->msi_bitmap); 94 return rc; 95 } 96 } 97 98 return 0; 99 } 100