Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

of/pci: move of_irq_map_pci() into generic code

There is a tiny difference between PPC32 and PPC64. Microblaze uses the
PPC32 variant.

Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
[grant.likely@secretlab.ca: Added comment to #endif, moved documentation
block to function implementation, fixed for non ppc and microblaze
compiles]
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>

authored by

Sebastian Andrzej Siewior and committed by
Grant Likely
04bea68b c64eae9a

+131 -191
+12
arch/microblaze/include/asm/pci-bridge.h
··· 104 104 int global_number; /* PCI domain number */ 105 105 }; 106 106 107 + #ifdef CONFIG_PCI 107 108 static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus) 108 109 { 109 110 return bus->sysdata; 111 + } 112 + 113 + static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus) 114 + { 115 + struct pci_controller *host; 116 + 117 + if (bus->self) 118 + return pci_device_to_OF_node(bus->self); 119 + host = pci_bus_to_host(bus); 120 + return host ? host->dn : NULL; 110 121 } 111 122 112 123 static inline int isa_vaddr_is_ioport(void __iomem *address) ··· 127 116 */ 128 117 return 0; 129 118 } 119 + #endif /* CONFIG_PCI */ 130 120 131 121 /* These are used for config access before all the PCI probing 132 122 has been done. */
-15
arch/microblaze/include/asm/prom.h
··· 64 64 /* CPU OF node matching */ 65 65 struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); 66 66 67 - /** 68 - * of_irq_map_pci - Resolve the interrupt for a PCI device 69 - * @pdev: the device whose interrupt is to be resolved 70 - * @out_irq: structure of_irq filled by this function 71 - * 72 - * This function resolves the PCI interrupt for a given PCI device. If a 73 - * device-node exists for a given pci_dev, it will use normal OF tree 74 - * walking. If not, it will implement standard swizzling and walk up the 75 - * PCI tree until an device-node is found, at which point it will finish 76 - * resolving using the OF tree walking. 77 - */ 78 - struct pci_dev; 79 - struct of_irq; 80 - extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); 81 - 82 67 #endif /* __ASSEMBLY__ */ 83 68 #endif /* __KERNEL__ */ 84 69
-77
arch/microblaze/kernel/prom_parse.c
··· 2 2 3 3 #include <linux/kernel.h> 4 4 #include <linux/string.h> 5 - #include <linux/pci_regs.h> 6 5 #include <linux/module.h> 7 6 #include <linux/ioport.h> 8 7 #include <linux/etherdevice.h> 9 8 #include <linux/of_address.h> 10 9 #include <asm/prom.h> 11 - #include <asm/pci-bridge.h> 12 - 13 - #ifdef CONFIG_PCI 14 - int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) 15 - { 16 - struct device_node *dn, *ppnode; 17 - struct pci_dev *ppdev; 18 - u32 lspec; 19 - u32 laddr[3]; 20 - u8 pin; 21 - int rc; 22 - 23 - /* Check if we have a device node, if yes, fallback to standard OF 24 - * parsing 25 - */ 26 - dn = pci_device_to_OF_node(pdev); 27 - if (dn) 28 - return of_irq_map_one(dn, 0, out_irq); 29 - 30 - /* Ok, we don't, time to have fun. Let's start by building up an 31 - * interrupt spec. we assume #interrupt-cells is 1, which is standard 32 - * for PCI. If you do different, then don't use that routine. 33 - */ 34 - rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin); 35 - if (rc != 0) 36 - return rc; 37 - /* No pin, exit */ 38 - if (pin == 0) 39 - return -ENODEV; 40 - 41 - /* Now we walk up the PCI tree */ 42 - lspec = pin; 43 - for (;;) { 44 - /* Get the pci_dev of our parent */ 45 - ppdev = pdev->bus->self; 46 - 47 - /* Ouch, it's a host bridge... */ 48 - if (ppdev == NULL) { 49 - struct pci_controller *host; 50 - host = pci_bus_to_host(pdev->bus); 51 - ppnode = host ? host->dn : NULL; 52 - /* No node for host bridge ? give up */ 53 - if (ppnode == NULL) 54 - return -EINVAL; 55 - } else 56 - /* We found a P2P bridge, check if it has a node */ 57 - ppnode = pci_device_to_OF_node(ppdev); 58 - 59 - /* Ok, we have found a parent with a device-node, hand over to 60 - * the OF parsing code. 61 - * We build a unit address from the linux device to be used for 62 - * resolution. Note that we use the linux bus number which may 63 - * not match your firmware bus numbering. 64 - * Fortunately, in most cases, interrupt-map-mask doesn't 65 - * include the bus number as part of the matching. 66 - * You should still be careful about that though if you intend 67 - * to rely on this function (you ship a firmware that doesn't 68 - * create device nodes for all PCI devices). 69 - */ 70 - if (ppnode) 71 - break; 72 - 73 - /* We can only get here if we hit a P2P bridge with no node, 74 - * let's do standard swizzling and try again 75 - */ 76 - lspec = pci_swizzle_interrupt_pin(pdev, lspec); 77 - pdev = ppdev; 78 - } 79 - 80 - laddr[0] = (pdev->bus->number << 16) 81 - | (pdev->devfn << 8); 82 - laddr[1] = laddr[2] = 0; 83 - return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq); 84 - } 85 - EXPORT_SYMBOL_GPL(of_irq_map_pci); 86 - #endif /* CONFIG_PCI */ 87 10 88 11 void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, 89 12 unsigned long *busno, unsigned long *phys, unsigned long *size)
+1
arch/microblaze/pci/pci-common.c
··· 29 29 #include <linux/slab.h> 30 30 #include <linux/of.h> 31 31 #include <linux/of_address.h> 32 + #include <linux/of_pci.h> 32 33 33 34 #include <asm/processor.h> 34 35 #include <asm/io.h>
+10
arch/powerpc/include/asm/pci-bridge.h
··· 171 171 return bus->sysdata; 172 172 } 173 173 174 + static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus) 175 + { 176 + struct pci_controller *host; 177 + 178 + if (bus->self) 179 + return pci_device_to_OF_node(bus->self); 180 + host = pci_bus_to_host(bus); 181 + return host ? host->dn : NULL; 182 + } 183 + 174 184 static inline int isa_vaddr_is_ioport(void __iomem *address) 175 185 { 176 186 /* No specific ISA handling on ppc32 at this stage, it
-15
arch/powerpc/include/asm/prom.h
··· 70 70 #endif 71 71 #define of_node_to_nid of_node_to_nid 72 72 73 - /** 74 - * of_irq_map_pci - Resolve the interrupt for a PCI device 75 - * @pdev: the device whose interrupt is to be resolved 76 - * @out_irq: structure of_irq filled by this function 77 - * 78 - * This function resolves the PCI interrupt for a given PCI device. If a 79 - * device-node exists for a given pci_dev, it will use normal OF tree 80 - * walking. If not, it will implement standard swizzling and walk up the 81 - * PCI tree until an device-node is found, at which point it will finish 82 - * resolving using the OF tree walking. 83 - */ 84 - struct pci_dev; 85 - struct of_irq; 86 - extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); 87 - 88 73 extern void of_instantiate_rtc(void); 89 74 90 75 /* These includes are put at the bottom because they may contain things
+1
arch/powerpc/kernel/pci-common.c
··· 22 22 #include <linux/init.h> 23 23 #include <linux/bootmem.h> 24 24 #include <linux/of_address.h> 25 + #include <linux/of_pci.h> 25 26 #include <linux/mm.h> 26 27 #include <linux/list.h> 27 28 #include <linux/syscalls.h>
-84
arch/powerpc/kernel/prom_parse.c
··· 2 2 3 3 #include <linux/kernel.h> 4 4 #include <linux/string.h> 5 - #include <linux/pci_regs.h> 6 5 #include <linux/module.h> 7 6 #include <linux/ioport.h> 8 7 #include <linux/etherdevice.h> 9 8 #include <linux/of_address.h> 10 9 #include <asm/prom.h> 11 - #include <asm/pci-bridge.h> 12 - 13 - #ifdef CONFIG_PCI 14 - int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) 15 - { 16 - struct device_node *dn, *ppnode; 17 - struct pci_dev *ppdev; 18 - u32 lspec; 19 - u32 laddr[3]; 20 - u8 pin; 21 - int rc; 22 - 23 - /* Check if we have a device node, if yes, fallback to standard OF 24 - * parsing 25 - */ 26 - dn = pci_device_to_OF_node(pdev); 27 - if (dn) { 28 - rc = of_irq_map_one(dn, 0, out_irq); 29 - if (!rc) 30 - return rc; 31 - } 32 - 33 - /* Ok, we don't, time to have fun. Let's start by building up an 34 - * interrupt spec. we assume #interrupt-cells is 1, which is standard 35 - * for PCI. If you do different, then don't use that routine. 36 - */ 37 - rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin); 38 - if (rc != 0) 39 - return rc; 40 - /* No pin, exit */ 41 - if (pin == 0) 42 - return -ENODEV; 43 - 44 - /* Now we walk up the PCI tree */ 45 - lspec = pin; 46 - for (;;) { 47 - /* Get the pci_dev of our parent */ 48 - ppdev = pdev->bus->self; 49 - 50 - /* Ouch, it's a host bridge... */ 51 - if (ppdev == NULL) { 52 - #ifdef CONFIG_PPC64 53 - ppnode = pci_bus_to_OF_node(pdev->bus); 54 - #else 55 - struct pci_controller *host; 56 - host = pci_bus_to_host(pdev->bus); 57 - ppnode = host ? host->dn : NULL; 58 - #endif 59 - /* No node for host bridge ? give up */ 60 - if (ppnode == NULL) 61 - return -EINVAL; 62 - } else 63 - /* We found a P2P bridge, check if it has a node */ 64 - ppnode = pci_device_to_OF_node(ppdev); 65 - 66 - /* Ok, we have found a parent with a device-node, hand over to 67 - * the OF parsing code. 68 - * We build a unit address from the linux device to be used for 69 - * resolution. Note that we use the linux bus number which may 70 - * not match your firmware bus numbering. 71 - * Fortunately, in most cases, interrupt-map-mask doesn't include 72 - * the bus number as part of the matching. 73 - * You should still be careful about that though if you intend 74 - * to rely on this function (you ship a firmware that doesn't 75 - * create device nodes for all PCI devices). 76 - */ 77 - if (ppnode) 78 - break; 79 - 80 - /* We can only get here if we hit a P2P bridge with no node, 81 - * let's do standard swizzling and try again 82 - */ 83 - lspec = pci_swizzle_interrupt_pin(pdev, lspec); 84 - pdev = ppdev; 85 - } 86 - 87 - laddr[0] = (pdev->bus->number << 16) 88 - | (pdev->devfn << 8); 89 - laddr[1] = laddr[2] = 0; 90 - return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq); 91 - } 92 - EXPORT_SYMBOL_GPL(of_irq_map_pci); 93 - #endif /* CONFIG_PCI */ 94 10 95 11 void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, 96 12 unsigned long *busno, unsigned long *phys, unsigned long *size)
+6
drivers/of/Kconfig
··· 69 69 help 70 70 OpenFirmware MDIO bus (Ethernet PHY) accessors 71 71 72 + config OF_PCI 73 + def_tristate PCI 74 + depends on PCI && (PPC || MICROBLAZE) 75 + help 76 + OpenFirmware PCI bus accessors 77 + 72 78 endmenu # OF
+1
drivers/of/Makefile
··· 9 9 obj-$(CONFIG_OF_NET) += of_net.o 10 10 obj-$(CONFIG_OF_SPI) += of_spi.o 11 11 obj-$(CONFIG_OF_MDIO) += of_mdio.o 12 + obj-$(CONFIG_OF_PCI) += of_pci.o
+91
drivers/of/of_pci.c
··· 1 + #include <linux/kernel.h> 2 + #include <linux/of_pci.h> 3 + #include <asm/prom.h> 4 + 5 + /** 6 + * of_irq_map_pci - Resolve the interrupt for a PCI device 7 + * @pdev: the device whose interrupt is to be resolved 8 + * @out_irq: structure of_irq filled by this function 9 + * 10 + * This function resolves the PCI interrupt for a given PCI device. If a 11 + * device-node exists for a given pci_dev, it will use normal OF tree 12 + * walking. If not, it will implement standard swizzling and walk up the 13 + * PCI tree until an device-node is found, at which point it will finish 14 + * resolving using the OF tree walking. 15 + */ 16 + int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) 17 + { 18 + struct device_node *dn, *ppnode; 19 + struct pci_dev *ppdev; 20 + u32 lspec; 21 + __be32 lspec_be; 22 + __be32 laddr[3]; 23 + u8 pin; 24 + int rc; 25 + 26 + /* Check if we have a device node, if yes, fallback to standard 27 + * device tree parsing 28 + */ 29 + dn = pci_device_to_OF_node(pdev); 30 + if (dn) { 31 + rc = of_irq_map_one(dn, 0, out_irq); 32 + if (!rc) 33 + return rc; 34 + } 35 + 36 + /* Ok, we don't, time to have fun. Let's start by building up an 37 + * interrupt spec. we assume #interrupt-cells is 1, which is standard 38 + * for PCI. If you do different, then don't use that routine. 39 + */ 40 + rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin); 41 + if (rc != 0) 42 + return rc; 43 + /* No pin, exit */ 44 + if (pin == 0) 45 + return -ENODEV; 46 + 47 + /* Now we walk up the PCI tree */ 48 + lspec = pin; 49 + for (;;) { 50 + /* Get the pci_dev of our parent */ 51 + ppdev = pdev->bus->self; 52 + 53 + /* Ouch, it's a host bridge... */ 54 + if (ppdev == NULL) { 55 + ppnode = pci_bus_to_OF_node(pdev->bus); 56 + 57 + /* No node for host bridge ? give up */ 58 + if (ppnode == NULL) 59 + return -EINVAL; 60 + } else { 61 + /* We found a P2P bridge, check if it has a node */ 62 + ppnode = pci_device_to_OF_node(ppdev); 63 + } 64 + 65 + /* Ok, we have found a parent with a device-node, hand over to 66 + * the OF parsing code. 67 + * We build a unit address from the linux device to be used for 68 + * resolution. Note that we use the linux bus number which may 69 + * not match your firmware bus numbering. 70 + * Fortunately, in most cases, interrupt-map-mask doesn't 71 + * include the bus number as part of the matching. 72 + * You should still be careful about that though if you intend 73 + * to rely on this function (you ship a firmware that doesn't 74 + * create device nodes for all PCI devices). 75 + */ 76 + if (ppnode) 77 + break; 78 + 79 + /* We can only get here if we hit a P2P bridge with no node, 80 + * let's do standard swizzling and try again 81 + */ 82 + lspec = pci_swizzle_interrupt_pin(pdev, lspec); 83 + pdev = ppdev; 84 + } 85 + 86 + lspec_be = cpu_to_be32(lspec); 87 + laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8)); 88 + laddr[1] = laddr[2] = cpu_to_be32(0); 89 + return of_irq_map_raw(ppnode, &lspec_be, 1, laddr, out_irq); 90 + } 91 + EXPORT_SYMBOL_GPL(of_irq_map_pci);
+9
include/linux/of_pci.h
··· 1 + #ifndef __OF_PCI_H 2 + #define __OF_PCI_H 3 + 4 + #include <linux/pci.h> 5 + 6 + struct pci_dev; 7 + struct of_irq; 8 + int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); 9 + #endif