aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of/address.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/of/address.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/of/address.c')
-rw-r--r--drivers/of/address.c76
1 files changed, 21 insertions, 55 deletions
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 0125524c08c..72c33fbe451 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -1,5 +1,4 @@
1 1
2#include <linux/device.h>
3#include <linux/io.h> 2#include <linux/io.h>
4#include <linux/ioport.h> 3#include <linux/ioport.h>
5#include <linux/module.h> 4#include <linux/module.h>
@@ -9,13 +8,13 @@
9 8
10/* Max address size we deal with */ 9/* Max address size we deal with */
11#define OF_MAX_ADDR_CELLS 4 10#define OF_MAX_ADDR_CELLS 4
12#define OF_CHECK_ADDR_COUNT(na) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS) 11#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
13#define OF_CHECK_COUNTS(na, ns) (OF_CHECK_ADDR_COUNT(na) && (ns) > 0) 12 (ns) > 0)
14 13
15static struct of_bus *of_match_bus(struct device_node *np); 14static struct of_bus *of_match_bus(struct device_node *np);
16static int __of_address_to_resource(struct device_node *dev, 15static int __of_address_to_resource(struct device_node *dev,
17 const __be32 *addrp, u64 size, unsigned int flags, 16 const __be32 *addrp, u64 size, unsigned int flags,
18 const char *name, struct resource *r); 17 struct resource *r);
19 18
20/* Debug utility */ 19/* Debug utility */
21#ifdef DEBUG 20#ifdef DEBUG
@@ -37,9 +36,9 @@ struct of_bus {
37 int (*match)(struct device_node *parent); 36 int (*match)(struct device_node *parent);
38 void (*count_cells)(struct device_node *child, 37 void (*count_cells)(struct device_node *child,
39 int *addrc, int *sizec); 38 int *addrc, int *sizec);
40 u64 (*map)(__be32 *addr, const __be32 *range, 39 u64 (*map)(u32 *addr, const __be32 *range,
41 int na, int ns, int pna); 40 int na, int ns, int pna);
42 int (*translate)(__be32 *addr, u64 offset, int na); 41 int (*translate)(u32 *addr, u64 offset, int na);
43 unsigned int (*get_flags)(const __be32 *addr); 42 unsigned int (*get_flags)(const __be32 *addr);
44}; 43};
45 44
@@ -56,7 +55,7 @@ static void of_bus_default_count_cells(struct device_node *dev,
56 *sizec = of_n_size_cells(dev); 55 *sizec = of_n_size_cells(dev);
57} 56}
58 57
59static u64 of_bus_default_map(__be32 *addr, const __be32 *range, 58static u64 of_bus_default_map(u32 *addr, const __be32 *range,
60 int na, int ns, int pna) 59 int na, int ns, int pna)
61{ 60{
62 u64 cp, s, da; 61 u64 cp, s, da;
@@ -69,20 +68,12 @@ static u64 of_bus_default_map(__be32 *addr, const __be32 *range,
69 (unsigned long long)cp, (unsigned long long)s, 68 (unsigned long long)cp, (unsigned long long)s,
70 (unsigned long long)da); 69 (unsigned long long)da);
71 70
72 /*
73 * If the number of address cells is larger than 2 we assume the
74 * mapping doesn't specify a physical address. Rather, the address
75 * specifies an identifier that must match exactly.
76 */
77 if (na > 2 && memcmp(range, addr, na * 4) != 0)
78 return OF_BAD_ADDR;
79
80 if (da < cp || da >= (cp + s)) 71 if (da < cp || da >= (cp + s))
81 return OF_BAD_ADDR; 72 return OF_BAD_ADDR;
82 return da - cp; 73 return da - cp;
83} 74}
84 75
85static int of_bus_default_translate(__be32 *addr, u64 offset, int na) 76static int of_bus_default_translate(u32 *addr, u64 offset, int na)
86{ 77{
87 u64 a = of_read_number(addr, na); 78 u64 a = of_read_number(addr, na);
88 memset(addr, 0, na * 4); 79 memset(addr, 0, na * 4);
@@ -138,7 +129,7 @@ static unsigned int of_bus_pci_get_flags(const __be32 *addr)
138 return flags; 129 return flags;
139} 130}
140 131
141static u64 of_bus_pci_map(__be32 *addr, const __be32 *range, int na, int ns, 132static u64 of_bus_pci_map(u32 *addr, const __be32 *range, int na, int ns,
142 int pna) 133 int pna)
143{ 134{
144 u64 cp, s, da; 135 u64 cp, s, da;
@@ -165,7 +156,7 @@ static u64 of_bus_pci_map(__be32 *addr, const __be32 *range, int na, int ns,
165 return da - cp; 156 return da - cp;
166} 157}
167 158
168static int of_bus_pci_translate(__be32 *addr, u64 offset, int na) 159static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
169{ 160{
170 return of_bus_default_translate(addr + 1, offset, na - 1); 161 return of_bus_default_translate(addr + 1, offset, na - 1);
171} 162}
@@ -190,7 +181,7 @@ const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
190 } 181 }
191 bus->count_cells(dev, &na, &ns); 182 bus->count_cells(dev, &na, &ns);
192 of_node_put(parent); 183 of_node_put(parent);
193 if (!OF_CHECK_ADDR_COUNT(na)) 184 if (!OF_CHECK_COUNTS(na, ns))
194 return NULL; 185 return NULL;
195 186
196 /* Get "reg" or "assigned-addresses" property */ 187 /* Get "reg" or "assigned-addresses" property */
@@ -224,7 +215,7 @@ int of_pci_address_to_resource(struct device_node *dev, int bar,
224 addrp = of_get_pci_address(dev, bar, &size, &flags); 215 addrp = of_get_pci_address(dev, bar, &size, &flags);
225 if (addrp == NULL) 216 if (addrp == NULL)
226 return -EINVAL; 217 return -EINVAL;
227 return __of_address_to_resource(dev, addrp, size, flags, NULL, r); 218 return __of_address_to_resource(dev, addrp, size, flags, r);
228} 219}
229EXPORT_SYMBOL_GPL(of_pci_address_to_resource); 220EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
230#endif /* CONFIG_PCI */ 221#endif /* CONFIG_PCI */
@@ -247,7 +238,7 @@ static void of_bus_isa_count_cells(struct device_node *child,
247 *sizec = 1; 238 *sizec = 1;
248} 239}
249 240
250static u64 of_bus_isa_map(__be32 *addr, const __be32 *range, int na, int ns, 241static u64 of_bus_isa_map(u32 *addr, const __be32 *range, int na, int ns,
251 int pna) 242 int pna)
252{ 243{
253 u64 cp, s, da; 244 u64 cp, s, da;
@@ -270,7 +261,7 @@ static u64 of_bus_isa_map(__be32 *addr, const __be32 *range, int na, int ns,
270 return da - cp; 261 return da - cp;
271} 262}
272 263
273static int of_bus_isa_translate(__be32 *addr, u64 offset, int na) 264static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
274{ 265{
275 return of_bus_default_translate(addr + 1, offset, na - 1); 266 return of_bus_default_translate(addr + 1, offset, na - 1);
276} 267}
@@ -338,7 +329,7 @@ static struct of_bus *of_match_bus(struct device_node *np)
338} 329}
339 330
340static int of_translate_one(struct device_node *parent, struct of_bus *bus, 331static int of_translate_one(struct device_node *parent, struct of_bus *bus,
341 struct of_bus *pbus, __be32 *addr, 332 struct of_bus *pbus, u32 *addr,
342 int na, int ns, int pna, const char *rprop) 333 int na, int ns, int pna, const char *rprop)
343{ 334{
344 const __be32 *ranges; 335 const __be32 *ranges;
@@ -409,12 +400,12 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
409 * that can be mapped to a cpu physical address). This is not really specified 400 * that can be mapped to a cpu physical address). This is not really specified
410 * that way, but this is traditionally the way IBM at least do things 401 * that way, but this is traditionally the way IBM at least do things
411 */ 402 */
412static u64 __of_translate_address(struct device_node *dev, 403u64 __of_translate_address(struct device_node *dev, const __be32 *in_addr,
413 const __be32 *in_addr, const char *rprop) 404 const char *rprop)
414{ 405{
415 struct device_node *parent = NULL; 406 struct device_node *parent = NULL;
416 struct of_bus *bus, *pbus; 407 struct of_bus *bus, *pbus;
417 __be32 addr[OF_MAX_ADDR_CELLS]; 408 u32 addr[OF_MAX_ADDR_CELLS];
418 int na, ns, pna, pns; 409 int na, ns, pna, pns;
419 u64 result = OF_BAD_ADDR; 410 u64 result = OF_BAD_ADDR;
420 411
@@ -498,25 +489,6 @@ u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr)
498} 489}
499EXPORT_SYMBOL(of_translate_dma_address); 490EXPORT_SYMBOL(of_translate_dma_address);
500 491
501bool of_can_translate_address(struct device_node *dev)
502{
503 struct device_node *parent;
504 struct of_bus *bus;
505 int na, ns;
506
507 parent = of_get_parent(dev);
508 if (parent == NULL)
509 return false;
510
511 bus = of_match_bus(parent);
512 bus->count_cells(dev, &na, &ns);
513
514 of_node_put(parent);
515
516 return OF_CHECK_COUNTS(na, ns);
517}
518EXPORT_SYMBOL(of_can_translate_address);
519
520const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, 492const __be32 *of_get_address(struct device_node *dev, int index, u64 *size,
521 unsigned int *flags) 493 unsigned int *flags)
522{ 494{
@@ -533,7 +505,7 @@ const __be32 *of_get_address(struct device_node *dev, int index, u64 *size,
533 bus = of_match_bus(parent); 505 bus = of_match_bus(parent);
534 bus->count_cells(dev, &na, &ns); 506 bus->count_cells(dev, &na, &ns);
535 of_node_put(parent); 507 of_node_put(parent);
536 if (!OF_CHECK_ADDR_COUNT(na)) 508 if (!OF_CHECK_COUNTS(na, ns))
537 return NULL; 509 return NULL;
538 510
539 /* Get "reg" or "assigned-addresses" property */ 511 /* Get "reg" or "assigned-addresses" property */
@@ -557,7 +529,7 @@ EXPORT_SYMBOL(of_get_address);
557 529
558static int __of_address_to_resource(struct device_node *dev, 530static int __of_address_to_resource(struct device_node *dev,
559 const __be32 *addrp, u64 size, unsigned int flags, 531 const __be32 *addrp, u64 size, unsigned int flags,
560 const char *name, struct resource *r) 532 struct resource *r)
561{ 533{
562 u64 taddr; 534 u64 taddr;
563 535
@@ -579,8 +551,7 @@ static int __of_address_to_resource(struct device_node *dev,
579 r->end = taddr + size - 1; 551 r->end = taddr + size - 1;
580 } 552 }
581 r->flags = flags; 553 r->flags = flags;
582 r->name = name ? name : dev->full_name; 554 r->name = dev->full_name;
583
584 return 0; 555 return 0;
585} 556}
586 557
@@ -598,16 +569,11 @@ int of_address_to_resource(struct device_node *dev, int index,
598 const __be32 *addrp; 569 const __be32 *addrp;
599 u64 size; 570 u64 size;
600 unsigned int flags; 571 unsigned int flags;
601 const char *name = NULL;
602 572
603 addrp = of_get_address(dev, index, &size, &flags); 573 addrp = of_get_address(dev, index, &size, &flags);
604 if (addrp == NULL) 574 if (addrp == NULL)
605 return -EINVAL; 575 return -EINVAL;
606 576 return __of_address_to_resource(dev, addrp, size, flags, r);
607 /* Get optional "reg-names" property to add a name to a resource */
608 of_property_read_string_index(dev, "reg-names", index, &name);
609
610 return __of_address_to_resource(dev, addrp, size, flags, name, r);
611} 577}
612EXPORT_SYMBOL_GPL(of_address_to_resource); 578EXPORT_SYMBOL_GPL(of_address_to_resource);
613 579