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