xref: /openbmc/linux/drivers/of/address.c (revision d3571c3a)
16b884a8dSGrant Likely 
26b884a8dSGrant Likely #include <linux/io.h>
36b884a8dSGrant Likely #include <linux/ioport.h>
4dbbdee94SGrant Likely #include <linux/module.h>
56b884a8dSGrant Likely #include <linux/of_address.h>
6dbbdee94SGrant Likely #include <linux/pci_regs.h>
7dbbdee94SGrant Likely #include <linux/string.h>
86b884a8dSGrant Likely 
9dbbdee94SGrant Likely /* Max address size we deal with */
10dbbdee94SGrant Likely #define OF_MAX_ADDR_CELLS	4
11dbbdee94SGrant Likely #define OF_CHECK_COUNTS(na, ns)	((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
12dbbdee94SGrant Likely 			(ns) > 0)
13dbbdee94SGrant Likely 
14dbbdee94SGrant Likely static struct of_bus *of_match_bus(struct device_node *np);
15dbbdee94SGrant Likely static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
16dbbdee94SGrant Likely 				    u64 size, unsigned int flags,
17dbbdee94SGrant Likely 				    struct resource *r);
18dbbdee94SGrant Likely 
19dbbdee94SGrant Likely /* Debug utility */
20dbbdee94SGrant Likely #ifdef DEBUG
21dbbdee94SGrant Likely static void of_dump_addr(const char *s, const u32 *addr, int na)
22dbbdee94SGrant Likely {
23dbbdee94SGrant Likely 	printk(KERN_DEBUG "%s", s);
24dbbdee94SGrant Likely 	while (na--)
25154063a9SGrant Likely 		printk(" %08x", be32_to_cpu(*(addr++)));
26dbbdee94SGrant Likely 	printk("\n");
27dbbdee94SGrant Likely }
28dbbdee94SGrant Likely #else
29dbbdee94SGrant Likely static void of_dump_addr(const char *s, const u32 *addr, int na) { }
30dbbdee94SGrant Likely #endif
31dbbdee94SGrant Likely 
32dbbdee94SGrant Likely /* Callbacks for bus specific translators */
33dbbdee94SGrant Likely struct of_bus {
34dbbdee94SGrant Likely 	const char	*name;
35dbbdee94SGrant Likely 	const char	*addresses;
36dbbdee94SGrant Likely 	int		(*match)(struct device_node *parent);
37dbbdee94SGrant Likely 	void		(*count_cells)(struct device_node *child,
38dbbdee94SGrant Likely 				       int *addrc, int *sizec);
39dbbdee94SGrant Likely 	u64		(*map)(u32 *addr, const u32 *range,
40dbbdee94SGrant Likely 				int na, int ns, int pna);
41dbbdee94SGrant Likely 	int		(*translate)(u32 *addr, u64 offset, int na);
42dbbdee94SGrant Likely 	unsigned int	(*get_flags)(const u32 *addr);
43dbbdee94SGrant Likely };
44dbbdee94SGrant Likely 
45dbbdee94SGrant Likely /*
46dbbdee94SGrant Likely  * Default translator (generic bus)
47dbbdee94SGrant Likely  */
48dbbdee94SGrant Likely 
49dbbdee94SGrant Likely static void of_bus_default_count_cells(struct device_node *dev,
50dbbdee94SGrant Likely 				       int *addrc, int *sizec)
51dbbdee94SGrant Likely {
52dbbdee94SGrant Likely 	if (addrc)
53dbbdee94SGrant Likely 		*addrc = of_n_addr_cells(dev);
54dbbdee94SGrant Likely 	if (sizec)
55dbbdee94SGrant Likely 		*sizec = of_n_size_cells(dev);
56dbbdee94SGrant Likely }
57dbbdee94SGrant Likely 
58dbbdee94SGrant Likely static u64 of_bus_default_map(u32 *addr, const u32 *range,
59dbbdee94SGrant Likely 		int na, int ns, int pna)
60dbbdee94SGrant Likely {
61dbbdee94SGrant Likely 	u64 cp, s, da;
62dbbdee94SGrant Likely 
63dbbdee94SGrant Likely 	cp = of_read_number(range, na);
64dbbdee94SGrant Likely 	s  = of_read_number(range + na + pna, ns);
65dbbdee94SGrant Likely 	da = of_read_number(addr, na);
66dbbdee94SGrant Likely 
67dbbdee94SGrant Likely 	pr_debug("OF: default map, cp=%llx, s=%llx, da=%llx\n",
68dbbdee94SGrant Likely 		 (unsigned long long)cp, (unsigned long long)s,
69dbbdee94SGrant Likely 		 (unsigned long long)da);
70dbbdee94SGrant Likely 
71dbbdee94SGrant Likely 	if (da < cp || da >= (cp + s))
72dbbdee94SGrant Likely 		return OF_BAD_ADDR;
73dbbdee94SGrant Likely 	return da - cp;
74dbbdee94SGrant Likely }
75dbbdee94SGrant Likely 
76dbbdee94SGrant Likely static int of_bus_default_translate(u32 *addr, u64 offset, int na)
77dbbdee94SGrant Likely {
78dbbdee94SGrant Likely 	u64 a = of_read_number(addr, na);
79dbbdee94SGrant Likely 	memset(addr, 0, na * 4);
80dbbdee94SGrant Likely 	a += offset;
81dbbdee94SGrant Likely 	if (na > 1)
82154063a9SGrant Likely 		addr[na - 2] = cpu_to_be32(a >> 32);
83154063a9SGrant Likely 	addr[na - 1] = cpu_to_be32(a & 0xffffffffu);
84dbbdee94SGrant Likely 
85dbbdee94SGrant Likely 	return 0;
86dbbdee94SGrant Likely }
87dbbdee94SGrant Likely 
88dbbdee94SGrant Likely static unsigned int of_bus_default_get_flags(const u32 *addr)
89dbbdee94SGrant Likely {
90dbbdee94SGrant Likely 	return IORESOURCE_MEM;
91dbbdee94SGrant Likely }
92dbbdee94SGrant Likely 
93dbbdee94SGrant Likely #ifdef CONFIG_PCI
94dbbdee94SGrant Likely /*
95dbbdee94SGrant Likely  * PCI bus specific translator
96dbbdee94SGrant Likely  */
97dbbdee94SGrant Likely 
98dbbdee94SGrant Likely static int of_bus_pci_match(struct device_node *np)
99dbbdee94SGrant Likely {
100dbbdee94SGrant Likely 	/* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */
101dbbdee94SGrant Likely 	return !strcmp(np->type, "pci") || !strcmp(np->type, "vci");
102dbbdee94SGrant Likely }
103dbbdee94SGrant Likely 
104dbbdee94SGrant Likely static void of_bus_pci_count_cells(struct device_node *np,
105dbbdee94SGrant Likely 				   int *addrc, int *sizec)
106dbbdee94SGrant Likely {
107dbbdee94SGrant Likely 	if (addrc)
108dbbdee94SGrant Likely 		*addrc = 3;
109dbbdee94SGrant Likely 	if (sizec)
110dbbdee94SGrant Likely 		*sizec = 2;
111dbbdee94SGrant Likely }
112dbbdee94SGrant Likely 
113dbbdee94SGrant Likely static unsigned int of_bus_pci_get_flags(const u32 *addr)
114dbbdee94SGrant Likely {
115dbbdee94SGrant Likely 	unsigned int flags = 0;
116dbbdee94SGrant Likely 	u32 w = addr[0];
117dbbdee94SGrant Likely 
118dbbdee94SGrant Likely 	switch((w >> 24) & 0x03) {
119dbbdee94SGrant Likely 	case 0x01:
120dbbdee94SGrant Likely 		flags |= IORESOURCE_IO;
121dbbdee94SGrant Likely 		break;
122dbbdee94SGrant Likely 	case 0x02: /* 32 bits */
123dbbdee94SGrant Likely 	case 0x03: /* 64 bits */
124dbbdee94SGrant Likely 		flags |= IORESOURCE_MEM;
125dbbdee94SGrant Likely 		break;
126dbbdee94SGrant Likely 	}
127dbbdee94SGrant Likely 	if (w & 0x40000000)
128dbbdee94SGrant Likely 		flags |= IORESOURCE_PREFETCH;
129dbbdee94SGrant Likely 	return flags;
130dbbdee94SGrant Likely }
131dbbdee94SGrant Likely 
132dbbdee94SGrant Likely static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna)
133dbbdee94SGrant Likely {
134dbbdee94SGrant Likely 	u64 cp, s, da;
135dbbdee94SGrant Likely 	unsigned int af, rf;
136dbbdee94SGrant Likely 
137dbbdee94SGrant Likely 	af = of_bus_pci_get_flags(addr);
138dbbdee94SGrant Likely 	rf = of_bus_pci_get_flags(range);
139dbbdee94SGrant Likely 
140dbbdee94SGrant Likely 	/* Check address type match */
141dbbdee94SGrant Likely 	if ((af ^ rf) & (IORESOURCE_MEM | IORESOURCE_IO))
142dbbdee94SGrant Likely 		return OF_BAD_ADDR;
143dbbdee94SGrant Likely 
144dbbdee94SGrant Likely 	/* Read address values, skipping high cell */
145dbbdee94SGrant Likely 	cp = of_read_number(range + 1, na - 1);
146dbbdee94SGrant Likely 	s  = of_read_number(range + na + pna, ns);
147dbbdee94SGrant Likely 	da = of_read_number(addr + 1, na - 1);
148dbbdee94SGrant Likely 
149dbbdee94SGrant Likely 	pr_debug("OF: PCI map, cp=%llx, s=%llx, da=%llx\n",
150dbbdee94SGrant Likely 		 (unsigned long long)cp, (unsigned long long)s,
151dbbdee94SGrant Likely 		 (unsigned long long)da);
152dbbdee94SGrant Likely 
153dbbdee94SGrant Likely 	if (da < cp || da >= (cp + s))
154dbbdee94SGrant Likely 		return OF_BAD_ADDR;
155dbbdee94SGrant Likely 	return da - cp;
156dbbdee94SGrant Likely }
157dbbdee94SGrant Likely 
158dbbdee94SGrant Likely static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
159dbbdee94SGrant Likely {
160dbbdee94SGrant Likely 	return of_bus_default_translate(addr + 1, offset, na - 1);
161dbbdee94SGrant Likely }
162dbbdee94SGrant Likely 
163dbbdee94SGrant Likely const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
164dbbdee94SGrant Likely 			unsigned int *flags)
165dbbdee94SGrant Likely {
166dbbdee94SGrant Likely 	const u32 *prop;
167dbbdee94SGrant Likely 	unsigned int psize;
168dbbdee94SGrant Likely 	struct device_node *parent;
169dbbdee94SGrant Likely 	struct of_bus *bus;
170dbbdee94SGrant Likely 	int onesize, i, na, ns;
171dbbdee94SGrant Likely 
172dbbdee94SGrant Likely 	/* Get parent & match bus type */
173dbbdee94SGrant Likely 	parent = of_get_parent(dev);
174dbbdee94SGrant Likely 	if (parent == NULL)
175dbbdee94SGrant Likely 		return NULL;
176dbbdee94SGrant Likely 	bus = of_match_bus(parent);
177dbbdee94SGrant Likely 	if (strcmp(bus->name, "pci")) {
178dbbdee94SGrant Likely 		of_node_put(parent);
179dbbdee94SGrant Likely 		return NULL;
180dbbdee94SGrant Likely 	}
181dbbdee94SGrant Likely 	bus->count_cells(dev, &na, &ns);
182dbbdee94SGrant Likely 	of_node_put(parent);
183dbbdee94SGrant Likely 	if (!OF_CHECK_COUNTS(na, ns))
184dbbdee94SGrant Likely 		return NULL;
185dbbdee94SGrant Likely 
186dbbdee94SGrant Likely 	/* Get "reg" or "assigned-addresses" property */
187dbbdee94SGrant Likely 	prop = of_get_property(dev, bus->addresses, &psize);
188dbbdee94SGrant Likely 	if (prop == NULL)
189dbbdee94SGrant Likely 		return NULL;
190dbbdee94SGrant Likely 	psize /= 4;
191dbbdee94SGrant Likely 
192dbbdee94SGrant Likely 	onesize = na + ns;
193154063a9SGrant Likely 	for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) {
194154063a9SGrant Likely 		u32 val = be32_to_cpu(prop[0]);
195154063a9SGrant Likely 		if ((val & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) {
196dbbdee94SGrant Likely 			if (size)
197dbbdee94SGrant Likely 				*size = of_read_number(prop + na, ns);
198dbbdee94SGrant Likely 			if (flags)
199dbbdee94SGrant Likely 				*flags = bus->get_flags(prop);
200dbbdee94SGrant Likely 			return prop;
201dbbdee94SGrant Likely 		}
202154063a9SGrant Likely 	}
203dbbdee94SGrant Likely 	return NULL;
204dbbdee94SGrant Likely }
205dbbdee94SGrant Likely EXPORT_SYMBOL(of_get_pci_address);
206dbbdee94SGrant Likely 
207dbbdee94SGrant Likely int of_pci_address_to_resource(struct device_node *dev, int bar,
208dbbdee94SGrant Likely 			       struct resource *r)
209dbbdee94SGrant Likely {
210dbbdee94SGrant Likely 	const u32	*addrp;
211dbbdee94SGrant Likely 	u64		size;
212dbbdee94SGrant Likely 	unsigned int	flags;
213dbbdee94SGrant Likely 
214dbbdee94SGrant Likely 	addrp = of_get_pci_address(dev, bar, &size, &flags);
215dbbdee94SGrant Likely 	if (addrp == NULL)
216dbbdee94SGrant Likely 		return -EINVAL;
217dbbdee94SGrant Likely 	return __of_address_to_resource(dev, addrp, size, flags, r);
218dbbdee94SGrant Likely }
219dbbdee94SGrant Likely EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
220dbbdee94SGrant Likely #endif /* CONFIG_PCI */
221dbbdee94SGrant Likely 
222dbbdee94SGrant Likely /*
223dbbdee94SGrant Likely  * ISA bus specific translator
224dbbdee94SGrant Likely  */
225dbbdee94SGrant Likely 
226dbbdee94SGrant Likely static int of_bus_isa_match(struct device_node *np)
227dbbdee94SGrant Likely {
228dbbdee94SGrant Likely 	return !strcmp(np->name, "isa");
229dbbdee94SGrant Likely }
230dbbdee94SGrant Likely 
231dbbdee94SGrant Likely static void of_bus_isa_count_cells(struct device_node *child,
232dbbdee94SGrant Likely 				   int *addrc, int *sizec)
233dbbdee94SGrant Likely {
234dbbdee94SGrant Likely 	if (addrc)
235dbbdee94SGrant Likely 		*addrc = 2;
236dbbdee94SGrant Likely 	if (sizec)
237dbbdee94SGrant Likely 		*sizec = 1;
238dbbdee94SGrant Likely }
239dbbdee94SGrant Likely 
240dbbdee94SGrant Likely static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna)
241dbbdee94SGrant Likely {
242dbbdee94SGrant Likely 	u64 cp, s, da;
243dbbdee94SGrant Likely 
244dbbdee94SGrant Likely 	/* Check address type match */
245dbbdee94SGrant Likely 	if ((addr[0] ^ range[0]) & 0x00000001)
246dbbdee94SGrant Likely 		return OF_BAD_ADDR;
247dbbdee94SGrant Likely 
248dbbdee94SGrant Likely 	/* Read address values, skipping high cell */
249dbbdee94SGrant Likely 	cp = of_read_number(range + 1, na - 1);
250dbbdee94SGrant Likely 	s  = of_read_number(range + na + pna, ns);
251dbbdee94SGrant Likely 	da = of_read_number(addr + 1, na - 1);
252dbbdee94SGrant Likely 
253dbbdee94SGrant Likely 	pr_debug("OF: ISA map, cp=%llx, s=%llx, da=%llx\n",
254dbbdee94SGrant Likely 		 (unsigned long long)cp, (unsigned long long)s,
255dbbdee94SGrant Likely 		 (unsigned long long)da);
256dbbdee94SGrant Likely 
257dbbdee94SGrant Likely 	if (da < cp || da >= (cp + s))
258dbbdee94SGrant Likely 		return OF_BAD_ADDR;
259dbbdee94SGrant Likely 	return da - cp;
260dbbdee94SGrant Likely }
261dbbdee94SGrant Likely 
262dbbdee94SGrant Likely static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
263dbbdee94SGrant Likely {
264dbbdee94SGrant Likely 	return of_bus_default_translate(addr + 1, offset, na - 1);
265dbbdee94SGrant Likely }
266dbbdee94SGrant Likely 
267dbbdee94SGrant Likely static unsigned int of_bus_isa_get_flags(const u32 *addr)
268dbbdee94SGrant Likely {
269dbbdee94SGrant Likely 	unsigned int flags = 0;
270dbbdee94SGrant Likely 	u32 w = addr[0];
271dbbdee94SGrant Likely 
272dbbdee94SGrant Likely 	if (w & 1)
273dbbdee94SGrant Likely 		flags |= IORESOURCE_IO;
274dbbdee94SGrant Likely 	else
275dbbdee94SGrant Likely 		flags |= IORESOURCE_MEM;
276dbbdee94SGrant Likely 	return flags;
277dbbdee94SGrant Likely }
278dbbdee94SGrant Likely 
279dbbdee94SGrant Likely /*
280dbbdee94SGrant Likely  * Array of bus specific translators
281dbbdee94SGrant Likely  */
282dbbdee94SGrant Likely 
283dbbdee94SGrant Likely static struct of_bus of_busses[] = {
284dbbdee94SGrant Likely #ifdef CONFIG_PCI
285dbbdee94SGrant Likely 	/* PCI */
286dbbdee94SGrant Likely 	{
287dbbdee94SGrant Likely 		.name = "pci",
288dbbdee94SGrant Likely 		.addresses = "assigned-addresses",
289dbbdee94SGrant Likely 		.match = of_bus_pci_match,
290dbbdee94SGrant Likely 		.count_cells = of_bus_pci_count_cells,
291dbbdee94SGrant Likely 		.map = of_bus_pci_map,
292dbbdee94SGrant Likely 		.translate = of_bus_pci_translate,
293dbbdee94SGrant Likely 		.get_flags = of_bus_pci_get_flags,
294dbbdee94SGrant Likely 	},
295dbbdee94SGrant Likely #endif /* CONFIG_PCI */
296dbbdee94SGrant Likely 	/* ISA */
297dbbdee94SGrant Likely 	{
298dbbdee94SGrant Likely 		.name = "isa",
299dbbdee94SGrant Likely 		.addresses = "reg",
300dbbdee94SGrant Likely 		.match = of_bus_isa_match,
301dbbdee94SGrant Likely 		.count_cells = of_bus_isa_count_cells,
302dbbdee94SGrant Likely 		.map = of_bus_isa_map,
303dbbdee94SGrant Likely 		.translate = of_bus_isa_translate,
304dbbdee94SGrant Likely 		.get_flags = of_bus_isa_get_flags,
305dbbdee94SGrant Likely 	},
306dbbdee94SGrant Likely 	/* Default */
307dbbdee94SGrant Likely 	{
308dbbdee94SGrant Likely 		.name = "default",
309dbbdee94SGrant Likely 		.addresses = "reg",
310dbbdee94SGrant Likely 		.match = NULL,
311dbbdee94SGrant Likely 		.count_cells = of_bus_default_count_cells,
312dbbdee94SGrant Likely 		.map = of_bus_default_map,
313dbbdee94SGrant Likely 		.translate = of_bus_default_translate,
314dbbdee94SGrant Likely 		.get_flags = of_bus_default_get_flags,
315dbbdee94SGrant Likely 	},
316dbbdee94SGrant Likely };
317dbbdee94SGrant Likely 
318dbbdee94SGrant Likely static struct of_bus *of_match_bus(struct device_node *np)
319dbbdee94SGrant Likely {
320dbbdee94SGrant Likely 	int i;
321dbbdee94SGrant Likely 
322dbbdee94SGrant Likely 	for (i = 0; i < ARRAY_SIZE(of_busses); i++)
323dbbdee94SGrant Likely 		if (!of_busses[i].match || of_busses[i].match(np))
324dbbdee94SGrant Likely 			return &of_busses[i];
325dbbdee94SGrant Likely 	BUG();
326dbbdee94SGrant Likely 	return NULL;
327dbbdee94SGrant Likely }
328dbbdee94SGrant Likely 
329dbbdee94SGrant Likely static int of_translate_one(struct device_node *parent, struct of_bus *bus,
330dbbdee94SGrant Likely 			    struct of_bus *pbus, u32 *addr,
331dbbdee94SGrant Likely 			    int na, int ns, int pna, const char *rprop)
332dbbdee94SGrant Likely {
333dbbdee94SGrant Likely 	const u32 *ranges;
334dbbdee94SGrant Likely 	unsigned int rlen;
335dbbdee94SGrant Likely 	int rone;
336dbbdee94SGrant Likely 	u64 offset = OF_BAD_ADDR;
337dbbdee94SGrant Likely 
338dbbdee94SGrant Likely 	/* Normally, an absence of a "ranges" property means we are
339dbbdee94SGrant Likely 	 * crossing a non-translatable boundary, and thus the addresses
340dbbdee94SGrant Likely 	 * below the current not cannot be converted to CPU physical ones.
341dbbdee94SGrant Likely 	 * Unfortunately, while this is very clear in the spec, it's not
342dbbdee94SGrant Likely 	 * what Apple understood, and they do have things like /uni-n or
343dbbdee94SGrant Likely 	 * /ht nodes with no "ranges" property and a lot of perfectly
344dbbdee94SGrant Likely 	 * useable mapped devices below them. Thus we treat the absence of
345dbbdee94SGrant Likely 	 * "ranges" as equivalent to an empty "ranges" property which means
346dbbdee94SGrant Likely 	 * a 1:1 translation at that level. It's up to the caller not to try
347dbbdee94SGrant Likely 	 * to translate addresses that aren't supposed to be translated in
348dbbdee94SGrant Likely 	 * the first place. --BenH.
3493930f294SGrant Likely 	 *
3503930f294SGrant Likely 	 * As far as we know, this damage only exists on Apple machines, so
3513930f294SGrant Likely 	 * This code is only enabled on powerpc. --gcl
352dbbdee94SGrant Likely 	 */
353dbbdee94SGrant Likely 	ranges = of_get_property(parent, rprop, &rlen);
3543930f294SGrant Likely #if !defined(CONFIG_PPC)
3553930f294SGrant Likely 	if (ranges == NULL) {
3563930f294SGrant Likely 		pr_err("OF: no ranges; cannot translate\n");
3573930f294SGrant Likely 		return 1;
3583930f294SGrant Likely 	}
3593930f294SGrant Likely #endif /* !defined(CONFIG_PPC) */
360dbbdee94SGrant Likely 	if (ranges == NULL || rlen == 0) {
361dbbdee94SGrant Likely 		offset = of_read_number(addr, na);
362dbbdee94SGrant Likely 		memset(addr, 0, pna * 4);
3633930f294SGrant Likely 		pr_debug("OF: empty ranges; 1:1 translation\n");
364dbbdee94SGrant Likely 		goto finish;
365dbbdee94SGrant Likely 	}
366dbbdee94SGrant Likely 
367dbbdee94SGrant Likely 	pr_debug("OF: walking ranges...\n");
368dbbdee94SGrant Likely 
369dbbdee94SGrant Likely 	/* Now walk through the ranges */
370dbbdee94SGrant Likely 	rlen /= 4;
371dbbdee94SGrant Likely 	rone = na + pna + ns;
372dbbdee94SGrant Likely 	for (; rlen >= rone; rlen -= rone, ranges += rone) {
373dbbdee94SGrant Likely 		offset = bus->map(addr, ranges, na, ns, pna);
374dbbdee94SGrant Likely 		if (offset != OF_BAD_ADDR)
375dbbdee94SGrant Likely 			break;
376dbbdee94SGrant Likely 	}
377dbbdee94SGrant Likely 	if (offset == OF_BAD_ADDR) {
378dbbdee94SGrant Likely 		pr_debug("OF: not found !\n");
379dbbdee94SGrant Likely 		return 1;
380dbbdee94SGrant Likely 	}
381dbbdee94SGrant Likely 	memcpy(addr, ranges + na, 4 * pna);
382dbbdee94SGrant Likely 
383dbbdee94SGrant Likely  finish:
384dbbdee94SGrant Likely 	of_dump_addr("OF: parent translation for:", addr, pna);
385dbbdee94SGrant Likely 	pr_debug("OF: with offset: %llx\n", (unsigned long long)offset);
386dbbdee94SGrant Likely 
387dbbdee94SGrant Likely 	/* Translate it into parent bus space */
388dbbdee94SGrant Likely 	return pbus->translate(addr, offset, pna);
389dbbdee94SGrant Likely }
390dbbdee94SGrant Likely 
391dbbdee94SGrant Likely /*
392dbbdee94SGrant Likely  * Translate an address from the device-tree into a CPU physical address,
393dbbdee94SGrant Likely  * this walks up the tree and applies the various bus mappings on the
394dbbdee94SGrant Likely  * way.
395dbbdee94SGrant Likely  *
396dbbdee94SGrant Likely  * Note: We consider that crossing any level with #size-cells == 0 to mean
397dbbdee94SGrant Likely  * that translation is impossible (that is we are not dealing with a value
398dbbdee94SGrant Likely  * that can be mapped to a cpu physical address). This is not really specified
399dbbdee94SGrant Likely  * that way, but this is traditionally the way IBM at least do things
400dbbdee94SGrant Likely  */
401dbbdee94SGrant Likely u64 __of_translate_address(struct device_node *dev, const u32 *in_addr,
402dbbdee94SGrant Likely 			   const char *rprop)
403dbbdee94SGrant Likely {
404dbbdee94SGrant Likely 	struct device_node *parent = NULL;
405dbbdee94SGrant Likely 	struct of_bus *bus, *pbus;
406dbbdee94SGrant Likely 	u32 addr[OF_MAX_ADDR_CELLS];
407dbbdee94SGrant Likely 	int na, ns, pna, pns;
408dbbdee94SGrant Likely 	u64 result = OF_BAD_ADDR;
409dbbdee94SGrant Likely 
410dbbdee94SGrant Likely 	pr_debug("OF: ** translation for device %s **\n", dev->full_name);
411dbbdee94SGrant Likely 
412dbbdee94SGrant Likely 	/* Increase refcount at current level */
413dbbdee94SGrant Likely 	of_node_get(dev);
414dbbdee94SGrant Likely 
415dbbdee94SGrant Likely 	/* Get parent & match bus type */
416dbbdee94SGrant Likely 	parent = of_get_parent(dev);
417dbbdee94SGrant Likely 	if (parent == NULL)
418dbbdee94SGrant Likely 		goto bail;
419dbbdee94SGrant Likely 	bus = of_match_bus(parent);
420dbbdee94SGrant Likely 
421dbbdee94SGrant Likely 	/* Cound address cells & copy address locally */
422dbbdee94SGrant Likely 	bus->count_cells(dev, &na, &ns);
423dbbdee94SGrant Likely 	if (!OF_CHECK_COUNTS(na, ns)) {
424dbbdee94SGrant Likely 		printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
425dbbdee94SGrant Likely 		       dev->full_name);
426dbbdee94SGrant Likely 		goto bail;
427dbbdee94SGrant Likely 	}
428dbbdee94SGrant Likely 	memcpy(addr, in_addr, na * 4);
429dbbdee94SGrant Likely 
430dbbdee94SGrant Likely 	pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n",
431dbbdee94SGrant Likely 	    bus->name, na, ns, parent->full_name);
432dbbdee94SGrant Likely 	of_dump_addr("OF: translating address:", addr, na);
433dbbdee94SGrant Likely 
434dbbdee94SGrant Likely 	/* Translate */
435dbbdee94SGrant Likely 	for (;;) {
436dbbdee94SGrant Likely 		/* Switch to parent bus */
437dbbdee94SGrant Likely 		of_node_put(dev);
438dbbdee94SGrant Likely 		dev = parent;
439dbbdee94SGrant Likely 		parent = of_get_parent(dev);
440dbbdee94SGrant Likely 
441dbbdee94SGrant Likely 		/* If root, we have finished */
442dbbdee94SGrant Likely 		if (parent == NULL) {
443dbbdee94SGrant Likely 			pr_debug("OF: reached root node\n");
444dbbdee94SGrant Likely 			result = of_read_number(addr, na);
445dbbdee94SGrant Likely 			break;
446dbbdee94SGrant Likely 		}
447dbbdee94SGrant Likely 
448dbbdee94SGrant Likely 		/* Get new parent bus and counts */
449dbbdee94SGrant Likely 		pbus = of_match_bus(parent);
450dbbdee94SGrant Likely 		pbus->count_cells(dev, &pna, &pns);
451dbbdee94SGrant Likely 		if (!OF_CHECK_COUNTS(pna, pns)) {
452dbbdee94SGrant Likely 			printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
453dbbdee94SGrant Likely 			       dev->full_name);
454dbbdee94SGrant Likely 			break;
455dbbdee94SGrant Likely 		}
456dbbdee94SGrant Likely 
457dbbdee94SGrant Likely 		pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n",
458dbbdee94SGrant Likely 		    pbus->name, pna, pns, parent->full_name);
459dbbdee94SGrant Likely 
460dbbdee94SGrant Likely 		/* Apply bus translation */
461dbbdee94SGrant Likely 		if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop))
462dbbdee94SGrant Likely 			break;
463dbbdee94SGrant Likely 
464dbbdee94SGrant Likely 		/* Complete the move up one level */
465dbbdee94SGrant Likely 		na = pna;
466dbbdee94SGrant Likely 		ns = pns;
467dbbdee94SGrant Likely 		bus = pbus;
468dbbdee94SGrant Likely 
469dbbdee94SGrant Likely 		of_dump_addr("OF: one level translation:", addr, na);
470dbbdee94SGrant Likely 	}
471dbbdee94SGrant Likely  bail:
472dbbdee94SGrant Likely 	of_node_put(parent);
473dbbdee94SGrant Likely 	of_node_put(dev);
474dbbdee94SGrant Likely 
475dbbdee94SGrant Likely 	return result;
476dbbdee94SGrant Likely }
477dbbdee94SGrant Likely 
478dbbdee94SGrant Likely u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
479dbbdee94SGrant Likely {
480dbbdee94SGrant Likely 	return __of_translate_address(dev, in_addr, "ranges");
481dbbdee94SGrant Likely }
482dbbdee94SGrant Likely EXPORT_SYMBOL(of_translate_address);
483dbbdee94SGrant Likely 
484dbbdee94SGrant Likely u64 of_translate_dma_address(struct device_node *dev, const u32 *in_addr)
485dbbdee94SGrant Likely {
486dbbdee94SGrant Likely 	return __of_translate_address(dev, in_addr, "dma-ranges");
487dbbdee94SGrant Likely }
488dbbdee94SGrant Likely EXPORT_SYMBOL(of_translate_dma_address);
489dbbdee94SGrant Likely 
490dbbdee94SGrant Likely const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
491dbbdee94SGrant Likely 		    unsigned int *flags)
492dbbdee94SGrant Likely {
493dbbdee94SGrant Likely 	const u32 *prop;
494dbbdee94SGrant Likely 	unsigned int psize;
495dbbdee94SGrant Likely 	struct device_node *parent;
496dbbdee94SGrant Likely 	struct of_bus *bus;
497dbbdee94SGrant Likely 	int onesize, i, na, ns;
498dbbdee94SGrant Likely 
499dbbdee94SGrant Likely 	/* Get parent & match bus type */
500dbbdee94SGrant Likely 	parent = of_get_parent(dev);
501dbbdee94SGrant Likely 	if (parent == NULL)
502dbbdee94SGrant Likely 		return NULL;
503dbbdee94SGrant Likely 	bus = of_match_bus(parent);
504dbbdee94SGrant Likely 	bus->count_cells(dev, &na, &ns);
505dbbdee94SGrant Likely 	of_node_put(parent);
506dbbdee94SGrant Likely 	if (!OF_CHECK_COUNTS(na, ns))
507dbbdee94SGrant Likely 		return NULL;
508dbbdee94SGrant Likely 
509dbbdee94SGrant Likely 	/* Get "reg" or "assigned-addresses" property */
510dbbdee94SGrant Likely 	prop = of_get_property(dev, bus->addresses, &psize);
511dbbdee94SGrant Likely 	if (prop == NULL)
512dbbdee94SGrant Likely 		return NULL;
513dbbdee94SGrant Likely 	psize /= 4;
514dbbdee94SGrant Likely 
515dbbdee94SGrant Likely 	onesize = na + ns;
516dbbdee94SGrant Likely 	for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
517dbbdee94SGrant Likely 		if (i == index) {
518dbbdee94SGrant Likely 			if (size)
519dbbdee94SGrant Likely 				*size = of_read_number(prop + na, ns);
520dbbdee94SGrant Likely 			if (flags)
521dbbdee94SGrant Likely 				*flags = bus->get_flags(prop);
522dbbdee94SGrant Likely 			return prop;
523dbbdee94SGrant Likely 		}
524dbbdee94SGrant Likely 	return NULL;
525dbbdee94SGrant Likely }
526dbbdee94SGrant Likely EXPORT_SYMBOL(of_get_address);
527dbbdee94SGrant Likely 
528dbbdee94SGrant Likely static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
5291f5bef30SGrant Likely 				    u64 size, unsigned int flags,
5301f5bef30SGrant Likely 				    struct resource *r)
5311f5bef30SGrant Likely {
5321f5bef30SGrant Likely 	u64 taddr;
5331f5bef30SGrant Likely 
5341f5bef30SGrant Likely 	if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
5351f5bef30SGrant Likely 		return -EINVAL;
5361f5bef30SGrant Likely 	taddr = of_translate_address(dev, addrp);
5371f5bef30SGrant Likely 	if (taddr == OF_BAD_ADDR)
5381f5bef30SGrant Likely 		return -EINVAL;
5391f5bef30SGrant Likely 	memset(r, 0, sizeof(struct resource));
5401f5bef30SGrant Likely 	if (flags & IORESOURCE_IO) {
5411f5bef30SGrant Likely 		unsigned long port;
5421f5bef30SGrant Likely 		port = pci_address_to_pio(taddr);
5431f5bef30SGrant Likely 		if (port == (unsigned long)-1)
5441f5bef30SGrant Likely 			return -EINVAL;
5451f5bef30SGrant Likely 		r->start = port;
5461f5bef30SGrant Likely 		r->end = port + size - 1;
5471f5bef30SGrant Likely 	} else {
5481f5bef30SGrant Likely 		r->start = taddr;
5491f5bef30SGrant Likely 		r->end = taddr + size - 1;
5501f5bef30SGrant Likely 	}
5511f5bef30SGrant Likely 	r->flags = flags;
552d3571c3aSGrant Likely 	r->name = dev->full_name;
5531f5bef30SGrant Likely 	return 0;
5541f5bef30SGrant Likely }
5551f5bef30SGrant Likely 
5561f5bef30SGrant Likely /**
5571f5bef30SGrant Likely  * of_address_to_resource - Translate device tree address and return as resource
5581f5bef30SGrant Likely  *
5591f5bef30SGrant Likely  * Note that if your address is a PIO address, the conversion will fail if
5601f5bef30SGrant Likely  * the physical address can't be internally converted to an IO token with
5611f5bef30SGrant Likely  * pci_address_to_pio(), that is because it's either called to early or it
5621f5bef30SGrant Likely  * can't be matched to any host bridge IO space
5631f5bef30SGrant Likely  */
5641f5bef30SGrant Likely int of_address_to_resource(struct device_node *dev, int index,
5651f5bef30SGrant Likely 			   struct resource *r)
5661f5bef30SGrant Likely {
5671f5bef30SGrant Likely 	const u32	*addrp;
5681f5bef30SGrant Likely 	u64		size;
5691f5bef30SGrant Likely 	unsigned int	flags;
5701f5bef30SGrant Likely 
5711f5bef30SGrant Likely 	addrp = of_get_address(dev, index, &size, &flags);
5721f5bef30SGrant Likely 	if (addrp == NULL)
5731f5bef30SGrant Likely 		return -EINVAL;
5741f5bef30SGrant Likely 	return __of_address_to_resource(dev, addrp, size, flags, r);
5751f5bef30SGrant Likely }
5761f5bef30SGrant Likely EXPORT_SYMBOL_GPL(of_address_to_resource);
5771f5bef30SGrant Likely 
5781f5bef30SGrant Likely 
5796b884a8dSGrant Likely /**
5806b884a8dSGrant Likely  * of_iomap - Maps the memory mapped IO for a given device_node
5816b884a8dSGrant Likely  * @device:	the device whose io range will be mapped
5826b884a8dSGrant Likely  * @index:	index of the io range
5836b884a8dSGrant Likely  *
5846b884a8dSGrant Likely  * Returns a pointer to the mapped memory
5856b884a8dSGrant Likely  */
5866b884a8dSGrant Likely void __iomem *of_iomap(struct device_node *np, int index)
5876b884a8dSGrant Likely {
5886b884a8dSGrant Likely 	struct resource res;
5896b884a8dSGrant Likely 
5906b884a8dSGrant Likely 	if (of_address_to_resource(np, index, &res))
5916b884a8dSGrant Likely 		return NULL;
5926b884a8dSGrant Likely 
5936b884a8dSGrant Likely 	return ioremap(res.start, 1 + res.end - res.start);
5946b884a8dSGrant Likely }
5956b884a8dSGrant Likely EXPORT_SYMBOL(of_iomap);
596