aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2005-11-30 00:57:28 -0500
committerPaul Mackerras <paulus@samba.org>2006-01-08 22:51:26 -0500
commitd2dd482bc17c3bc240045f80a7c4b4d5cea5e29c (patch)
tree9c40a9ab9a04839f2d578f9d47985b399074ce58
parentbb6b9b28d6847bc71f910e2e82c9040ff4b97ec0 (diff)
[PATCH] 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 <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/kernel/legacy_serial.c5
-rw-r--r--arch/powerpc/kernel/pci_64.c14
-rw-r--r--arch/powerpc/kernel/prom_parse.c165
-rw-r--r--arch/powerpc/platforms/powermac/feature.c2
-rw-r--r--arch/ppc/kernel/pci.c15
-rw-r--r--drivers/macintosh/macio_asic.c12
-rw-r--r--include/asm-powerpc/pci-bridge.h9
-rw-r--r--include/asm-powerpc/prom.h28
-rw-r--r--include/asm-ppc/pci-bridge.h9
-rw-r--r--include/asm-ppc/prom.h28
10 files changed, 251 insertions, 36 deletions
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index 83023bb59ad9..d179ec502292 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -146,6 +146,7 @@ static int __init add_legacy_pci_port(struct device_node *np,
146{ 146{
147 phys_addr_t addr, base; 147 phys_addr_t addr, base;
148 u32 *addrp; 148 u32 *addrp;
149 unsigned int flags;
149 int iotype, index = -1, lindex = 0; 150 int iotype, index = -1, lindex = 0;
150 151
151 /* We only support ports that have a clock frequency properly 152 /* We only support ports that have a clock frequency properly
@@ -159,12 +160,12 @@ static int __init add_legacy_pci_port(struct device_node *np,
159 return -1; 160 return -1;
160 161
161 /* Get the PCI address. Assume BAR 0 */ 162 /* Get the PCI address. Assume BAR 0 */
162 addrp = of_get_pci_address(pci_dev, 0, NULL); 163 addrp = of_get_pci_address(pci_dev, 0, NULL, &flags);
163 if (addrp == NULL) 164 if (addrp == NULL)
164 return -1; 165 return -1;
165 166
166 /* We only support BAR 0 for now */ 167 /* We only support BAR 0 for now */
167 iotype = (addrp[0] & 0x02000000) ? UPIO_MEM : UPIO_PORT; 168 iotype = (flags & IORESOURCE_MEM) ? UPIO_MEM : UPIO_PORT;
168 addr = of_translate_address(pci_dev, addrp); 169 addr = of_translate_address(pci_dev, addrp);
169 170
170 /* Set the IO base to the same as the translated address for MMIO, 171 /* Set the IO base to the same as the translated address for MMIO,
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 5f241fcd88e8..0988222741f0 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -1181,6 +1181,20 @@ void phbs_remap_io(void)
1181 remap_bus_range(hose->bus); 1181 remap_bus_range(hose->bus);
1182} 1182}
1183 1183
1184unsigned int pci_address_to_pio(phys_addr_t address)
1185{
1186 struct pci_controller *hose, *tmp;
1187
1188 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
1189 if (address >= hose->io_base_phys &&
1190 address < (hose->io_base_phys + hose->pci_io_size))
1191 return (unsigned int)hose->io_base_virt +
1192 (address - hose->io_base_phys);
1193 }
1194 return (unsigned int)-1;
1195}
1196EXPORT_SYMBOL_GPL(pci_address_to_pio);
1197
1184static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev) 1198static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
1185{ 1199{
1186 struct pci_controller *hose = pci_bus_to_host(dev->bus); 1200 struct pci_controller *hose = pci_bus_to_host(dev->bus);
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index 23c85af53d47..5b764277f470 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -4,7 +4,9 @@
4#include <linux/string.h> 4#include <linux/string.h>
5#include <linux/pci_regs.h> 5#include <linux/pci_regs.h>
6#include <linux/module.h> 6#include <linux/module.h>
7#include <linux/ioport.h>
7#include <asm/prom.h> 8#include <asm/prom.h>
9#include <asm/pci-bridge.h>
8 10
9#ifdef DEBUG 11#ifdef DEBUG
10#define DBG(fmt...) do { printk(fmt); } while(0) 12#define DBG(fmt...) do { printk(fmt); } while(0)
@@ -54,6 +56,7 @@ struct of_bus {
54 int *addrc, int *sizec); 56 int *addrc, int *sizec);
55 u64 (*map)(u32 *addr, u32 *range, int na, int ns, int pna); 57 u64 (*map)(u32 *addr, u32 *range, int na, int ns, int pna);
56 int (*translate)(u32 *addr, u64 offset, int na); 58 int (*translate)(u32 *addr, u64 offset, int na);
59 unsigned int (*get_flags)(u32 *addr);
57}; 60};
58 61
59 62
@@ -61,8 +64,8 @@ struct of_bus {
61 * Default translator (generic bus) 64 * Default translator (generic bus)
62 */ 65 */
63 66
64static void of_default_count_cells(struct device_node *dev, 67static void of_bus_default_count_cells(struct device_node *dev,
65 int *addrc, int *sizec) 68 int *addrc, int *sizec)
66{ 69{
67 if (addrc) 70 if (addrc)
68 *addrc = prom_n_addr_cells(dev); 71 *addrc = prom_n_addr_cells(dev);
@@ -70,7 +73,7 @@ static void of_default_count_cells(struct device_node *dev,
70 *sizec = prom_n_size_cells(dev); 73 *sizec = prom_n_size_cells(dev);
71} 74}
72 75
73static u64 of_default_map(u32 *addr, u32 *range, int na, int ns, int pna) 76static u64 of_bus_default_map(u32 *addr, u32 *range, int na, int ns, int pna)
74{ 77{
75 u64 cp, s, da; 78 u64 cp, s, da;
76 79
@@ -86,7 +89,7 @@ static u64 of_default_map(u32 *addr, u32 *range, int na, int ns, int pna)
86 return da - cp; 89 return da - cp;
87} 90}
88 91
89static int of_default_translate(u32 *addr, u64 offset, int na) 92static int of_bus_default_translate(u32 *addr, u64 offset, int na)
90{ 93{
91 u64 a = of_read_addr(addr, na); 94 u64 a = of_read_addr(addr, na);
92 memset(addr, 0, na * 4); 95 memset(addr, 0, na * 4);
@@ -98,6 +101,11 @@ static int of_default_translate(u32 *addr, u64 offset, int na)
98 return 0; 101 return 0;
99} 102}
100 103
104static unsigned int of_bus_default_get_flags(u32 *addr)
105{
106 return IORESOURCE_MEM;
107}
108
101 109
102/* 110/*
103 * PCI bus specific translator 111 * PCI bus specific translator
@@ -139,7 +147,24 @@ static u64 of_bus_pci_map(u32 *addr, u32 *range, int na, int ns, int pna)
139 147
140static int of_bus_pci_translate(u32 *addr, u64 offset, int na) 148static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
141{ 149{
142 return of_default_translate(addr + 1, offset, na - 1); 150 return of_bus_default_translate(addr + 1, offset, na - 1);
151}
152
153static unsigned int of_bus_pci_get_flags(u32 *addr)
154{
155 unsigned int flags = 0;
156 u32 w = addr[0];
157
158 switch((w >> 24) & 0x03) {
159 case 0x01:
160 flags |= IORESOURCE_IO;
161 case 0x02: /* 32 bits */
162 case 0x03: /* 64 bits */
163 flags |= IORESOURCE_MEM;
164 }
165 if (w & 0x40000000)
166 flags |= IORESOURCE_PREFETCH;
167 return flags;
143} 168}
144 169
145/* 170/*
@@ -182,9 +207,22 @@ static u64 of_bus_isa_map(u32 *addr, u32 *range, int na, int ns, int pna)
182 207
183static int of_bus_isa_translate(u32 *addr, u64 offset, int na) 208static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
184{ 209{
185 return of_default_translate(addr + 1, offset, na - 1); 210 return of_bus_default_translate(addr + 1, offset, na - 1);
211}
212
213static unsigned int of_bus_isa_get_flags(u32 *addr)
214{
215 unsigned int flags = 0;
216 u32 w = addr[0];
217
218 if (w & 1)
219 flags |= IORESOURCE_IO;
220 else
221 flags |= IORESOURCE_MEM;