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 struct irq_host_ops *ops = mpic->irqhost->ops; 36 struct device_node *np; 37 int flags, index, i; 38 struct of_irq 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 for (i = 0; i < 8; i++) 44 msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i); 45 46 for (i = 42; i < 46; i++) 47 msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i); 48 49 for (i = 100; i < 105; i++) 50 msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i); 51 52 np = NULL; 53 while ((np = of_find_all_nodes(np))) { 54 pr_debug("mpic: mapping hwirqs for %s\n", np->full_name); 55 56 index = 0; 57 while (of_irq_map_one(np, index++, &oirq) == 0) { 58 ops->xlate(mpic->irqhost, NULL, oirq.specifier, 59 oirq.size, &hwirq, &flags); 60 msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, hwirq); 61 } 62 } 63 64 return 0; 65 } 66 #else 67 static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic) 68 { 69 return -1; 70 } 71 #endif 72 73 int mpic_msi_init_allocator(struct mpic *mpic) 74 { 75 int rc; 76 77 rc = msi_bitmap_alloc(&mpic->msi_bitmap, mpic->irq_count, 78 mpic->irqhost->of_node); 79 if (rc) 80 return rc; 81 82 rc = msi_bitmap_reserve_dt_hwirqs(&mpic->msi_bitmap); 83 if (rc > 0) { 84 if (mpic->flags & MPIC_U3_HT_IRQS) 85 rc = mpic_msi_reserve_u3_hwirqs(mpic); 86 87 if (rc) { 88 msi_bitmap_free(&mpic->msi_bitmap); 89 return rc; 90 } 91 } 92 93 return 0; 94 } 95