powerpc: Update OF address parsers
Subsystems (2)
PATCH 1/1 powerpc: Update OF address parsers
This updates the OF address parsers to return the IO flags indicating the type of address obtained. It also adds a PCI call for converting physical addresses that hit IO space into into IO tokens, and add routines that return the translated addresses into struct resource
Signed-off-by Benjamin Herrenschmidt <[email protected]>
---
For powerpc tree, not for 2.6.15
include/asm-powerpc/prom.h +25 -3
@@ -223,14 +223,36 @@ extern struct resource *request_OF_resou int index, const char* name_postfix);extern int release_OF_resource (struct device_node * node,int index); +/* -* Address translation function(s) +* OF address retreival & translation +*/ + + +/* Translate an OF address block into a CPU physical address */ #define OF_BAD_ADDR ((u64)-1)extern u64 of_translate_address (struct device_node *np,u32 *addr); -extern u32 *of_get_address (struct device_node *dev,int index,u64 *size); -extern u32 *of_get_pci_address (struct device_node *dev,int bar_no,u64 *size); +/* Extract an address from a device, returns the region size and +* the address space flags too. The PCI version uses a BAR number +* instead of an absolute index +*/ +extern u32 *of_get_address (struct device_node *dev,int index, +u64 *size,unsigned int *flags); +extern u32 *of_get_pci_address (struct device_node *dev,int bar_no, +u64 *size,unsigned int *flags); + +/* Get an address as a resource. Note that if your address is +* a PIO address, the conversion will fail if the physical address +* can't be internally converted to an IO token with +* pci_address_to_pio(), that is because it's either called to early +* or it can't be matched to any host bridge IO space +*/ +extern int of_address_to_resource (struct device_node *dev,int index, +struct resource *r); +extern int of_pci_address_to_resource (struct device_node *dev,int bar, +struct resource *r);#endif /* __KERNEL__ */ #endif /* _POWERPC_PROM_H */
arch/powerpc/kernel/legacy_serial.c +3 -2
@@ -146,6 +146,7 @@ static int __init add_legacy_pci_port(st {phys_addr_t addr, base;u32 *addrp; +unsigned int flags;int iotype, index =-1 , lindex =0 ;/* We only support ports that have a clock frequency properly
@@ -159,12 +160,12 @@ static int __init add_legacy_pci_port(streturn -1 ;/* Get the PCI address. Assume BAR 0 */ - addrp =of_get_pci_address (pci_dev,0 ,NULL ); + addrp =of_get_pci_address (pci_dev,0 ,NULL , &flags);if (addrp ==NULL )return -1 ;/* We only support BAR 0 for now */ - iotype = (addrp[0 ] &0x02000000 ) ?UPIO_MEM :UPIO_PORT ; + iotype = (flags &IORESOURCE_MEM ) ?UPIO_MEM :UPIO_PORT ; addr =of_translate_address (pci_dev, addrp);/* Set the IO base to the same as the translated address for MMIO,
arch/powerpc/kernel/pci_64.c +14 -0
@@ -1181,6 +1181,20 @@ void phbs_remap_io(void)remap_bus_range (hose->bus); } +unsigned int pci_address_to_pio (phys_addr_t address) +{ +struct pci_controller *hose, *tmp; + +list_for_each_entry_safe (hose, tmp, &hose_list, list_node) { +if (address >= hose->io_base_phys && + address < (hose->io_base_phys + hose->pci_io_size)) +return (unsigned int )hose->io_base_virt + + (address - hose->io_base_phys); + } +return (unsigned int )-1 ; +} +EXPORT_SYMBOL_GPL (pci_address_to_pio); +static void __devinit fixup_resource (struct resource *res,struct pci_dev *dev) {struct pci_controller *hose =pci_bus_to_host (dev->bus);
arch/powerpc/kernel/prom_parse.c +146 -19
260 lines not on this page · raw message
arch/powerpc/platforms/powermac/feature.c +1 -1
@@ -2672,7 +2672,7 @@ static void __init probe_one_macio(constprintk (KERN_ERR "pmac_feature: %s skipped\n" , node->full_name);return ; } - addrp =of_get_pci_address (node,0 , &size); + addrp =of_get_pci_address (node,0 , &size,NULL );if (addrp ==NULL ) {printk (KERN_ERR "pmac_feature: %s: can't find base !\n" , node->full_name);
arch/ppc/kernel/pci.c +15 -0
@@ -1805,6 +1805,21 @@ void pci_iounmap(struct pci_dev *dev, voEXPORT_SYMBOL (pci_iomap);EXPORT_SYMBOL (pci_iounmap); +unsigned int pci_address_to_pio (phys_addr_t address) +{ +struct pci_controller * hose = hose_head; + +for (; hose; hose = hose->next) { +unsigned int size = hose->io_resource.end - + hose->io_resource.start +1 ; +if (address >= hose->io_base_phys && + address < (hose->io_base_phys + size)) +return (unsigned int )hose->io_base_virt + + (address - hose->io_base_phys); + } +return (unsigned int )-1 ; +} +EXPORT_SYMBOL (pci_address_to_pio);/* * Null PCI config access functions, for the case when we can't
drivers/macintosh/macio_asic.c +4 -8
@@ -332,18 +332,14 @@ static void macio_setup_resources(struct struct resource *parent_res) {struct device_node *np = dev->ofdev.node; -u32 *addr; -u64 size; +struct resource r;int index; -for (index =0 ; (addr =of_get_address (np, index, &size)) !=NULL ; - index++) { +for (index =0 ;of_address_to_resource (np, index, &r) ==0 ; index++) {struct resource *res = &dev->resource[index];if (index >=MACIO_DEV_COUNT_RESOURCES )break ; - res->start =of_translate_address (np, addr); - res->end = res->start + (unsigned long )size -1 ; - res->flags =IORESOURCE_MEM ; + *res = r; res->name = dev->ofdev.dev.bus_id;if (macio_resource_quirks (np, res, index)) {
@@ -353,7 +349,7 @@ static void macio_setup_resources(struct/* Currently, we consider failure as harmless, this may * change in the future, once I've found all the device * tree bugs in older machines & worked around them -*/ +l */ if (insert_resource (parent_res, res)) { printk(KERN_WARNING "Can't request resource " "%d for MacIO device %s\n",
include/asm-powerpc/pci-bridge.h +9 -0
@@ -157,6 +157,15 @@ extern struct pci_controller * pcibios_alloc_controller(struct device_node *dev);extern void pcibios_free_controller (struct pci_controller *phb); +#ifdef CONFIG_PCI +extern unsigned int pci_address_to_pio (phys_addr_t address); +#else +static inline unsigned int pci_address_to_pio (phys_addr_t address) +{ +return (unsigned int )-1 ; +} +#endif +/* Return values for ppc_md.pci_probe_mode function */ #define PCI_PROBE_NONE -1/* Don't look at this bus at all */ #define PCI_PROBE_NORMAL 0/* Do normal PCI probing */
include/asm-ppc/pci-bridge.h +9 -0
@@ -137,5 +137,14 @@ static inline unsigned char bridge_swizz*/ extern int pciauto_bus_scan (struct pci_controller *,int ); +#ifdef CONFIG_PCI +extern unsigned int pci_address_to_pio (phys_addr_t address); +#else +static inline unsigned int pci_address_to_pio (phys_addr_t address) +{ +return (unsigned int )-1 ; +} +#endif +#endif #endif /* __KERNEL__ */
include/asm-ppc/prom.h +25 -3
@@ -138,12 +138,34 @@ extern unsigned long sub_reloc_offset(un/* -* Address translation function(s) +* OF address retreival & translation +*/ + + +/* Translate an OF address block into a CPU physical address */ #define OF_BAD_ADDR ((u64)-1)extern u64 of_translate_address (struct device_node *np,u32 *addr); -extern u32 *of_get_address (struct device_node *dev,int index,u64 *size); -extern u32 *of_get_pci_address (struct device_node *dev,int bar_no,u64 *size); + +/* Extract an address from a device, returns the region size and +* the address space flags too. The PCI version uses a BAR number +* instead of an absolute index +*/ +extern u32 *of_get_address (struct device_node *dev,int index, +u64 *size,unsigned int *flags); +extern u32 *of_get_pci_address (struct device_node *dev,int bar_no, +u64 *size,unsigned int *flags); + +/* Get an address as a resource. Note that if your address is +* a PIO address, the conversion will fail if the physical address +* can't be internally converted to an IO token with +* pci_address_to_pio(), that is because it's either called to early +* or it can't be matched to any host bridge IO space +*/ +extern int of_address_to_resource (struct device_node *dev,int index, +struct resource *r); +extern int of_pci_address_to_resource (struct device_node *dev,int bar, +struct resource *r);#endif /* _PPC_PROM_H */