Root/
Source at commit 0de2b2b3be81048189a32f7a3d3ba0ba9ec817b6 created 11 years 11 months ago. By Maarten ter Huurne, MIPS: JZ4740: Fixed value for round robin constant. | |
---|---|
1 | #include <linux/string.h> |
2 | #include <linux/kernel.h> |
3 | #include <linux/of.h> |
4 | #include <linux/init.h> |
5 | #include <linux/export.h> |
6 | #include <linux/mod_devicetable.h> |
7 | #include <linux/errno.h> |
8 | #include <linux/irq.h> |
9 | #include <linux/of_device.h> |
10 | #include <linux/of_platform.h> |
11 | |
12 | #include "of_device_common.h" |
13 | |
14 | unsigned int irq_of_parse_and_map(struct device_node *node, int index) |
15 | { |
16 | struct platform_device *op = of_find_device_by_node(node); |
17 | |
18 | if (!op || index >= op->archdata.num_irqs) |
19 | return 0; |
20 | |
21 | return op->archdata.irqs[index]; |
22 | } |
23 | EXPORT_SYMBOL(irq_of_parse_and_map); |
24 | |
25 | int of_address_to_resource(struct device_node *node, int index, |
26 | struct resource *r) |
27 | { |
28 | struct platform_device *op = of_find_device_by_node(node); |
29 | |
30 | if (!op || index >= op->num_resources) |
31 | return -EINVAL; |
32 | |
33 | memcpy(r, &op->archdata.resource[index], sizeof(*r)); |
34 | return 0; |
35 | } |
36 | EXPORT_SYMBOL_GPL(of_address_to_resource); |
37 | |
38 | void __iomem *of_iomap(struct device_node *node, int index) |
39 | { |
40 | struct platform_device *op = of_find_device_by_node(node); |
41 | struct resource *r; |
42 | |
43 | if (!op || index >= op->num_resources) |
44 | return NULL; |
45 | |
46 | r = &op->archdata.resource[index]; |
47 | |
48 | return of_ioremap(r, 0, resource_size(r), (char *) r->name); |
49 | } |
50 | EXPORT_SYMBOL(of_iomap); |
51 | |
52 | /* Take the archdata values for IOMMU, STC, and HOSTDATA found in |
53 | * BUS and propagate to all child platform_device objects. |
54 | */ |
55 | void of_propagate_archdata(struct platform_device *bus) |
56 | { |
57 | struct dev_archdata *bus_sd = &bus->dev.archdata; |
58 | struct device_node *bus_dp = bus->dev.of_node; |
59 | struct device_node *dp; |
60 | |
61 | for (dp = bus_dp->child; dp; dp = dp->sibling) { |
62 | struct platform_device *op = of_find_device_by_node(dp); |
63 | |
64 | op->dev.archdata.iommu = bus_sd->iommu; |
65 | op->dev.archdata.stc = bus_sd->stc; |
66 | op->dev.archdata.host_controller = bus_sd->host_controller; |
67 | op->dev.archdata.numa_node = bus_sd->numa_node; |
68 | |
69 | if (dp->child) |
70 | of_propagate_archdata(op); |
71 | } |
72 | } |
73 | |
74 | static void get_cells(struct device_node *dp, int *addrc, int *sizec) |
75 | { |
76 | if (addrc) |
77 | *addrc = of_n_addr_cells(dp); |
78 | if (sizec) |
79 | *sizec = of_n_size_cells(dp); |
80 | } |
81 | |
82 | /* |
83 | * Default translator (generic bus) |
84 | */ |
85 | |
86 | void of_bus_default_count_cells(struct device_node *dev, int *addrc, int *sizec) |
87 | { |
88 | get_cells(dev, addrc, sizec); |
89 | } |
90 | |
91 | /* Make sure the least significant 64-bits are in-range. Even |
92 | * for 3 or 4 cell values it is a good enough approximation. |
93 | */ |
94 | int of_out_of_range(const u32 *addr, const u32 *base, |
95 | const u32 *size, int na, int ns) |
96 | { |
97 | u64 a = of_read_addr(addr, na); |
98 | u64 b = of_read_addr(base, na); |
99 | |
100 | if (a < b) |
101 | return 1; |
102 | |
103 | b += of_read_addr(size, ns); |
104 | if (a >= b) |
105 | return 1; |
106 | |
107 | return 0; |
108 | } |
109 | |
110 | int of_bus_default_map(u32 *addr, const u32 *range, int na, int ns, int pna) |
111 | { |
112 | u32 result[OF_MAX_ADDR_CELLS]; |
113 | int i; |
114 | |
115 | if (ns > 2) { |
116 | printk("of_device: Cannot handle size cells (%d) > 2.", ns); |
117 | return -EINVAL; |
118 | } |
119 | |
120 | if (of_out_of_range(addr, range, range + na + pna, na, ns)) |
121 | return -EINVAL; |
122 | |
123 | /* Start with the parent range base. */ |
124 | memcpy(result, range + na, pna * 4); |
125 | |
126 | /* Add in the child address offset. */ |
127 | for (i = 0; i < na; i++) |
128 | result[pna - 1 - i] += |
129 | (addr[na - 1 - i] - |
130 | range[na - 1 - i]); |
131 | |
132 | memcpy(addr, result, pna * 4); |
133 | |
134 | return 0; |
135 | } |
136 | |
137 | unsigned long of_bus_default_get_flags(const u32 *addr, unsigned long flags) |
138 | { |
139 | if (flags) |
140 | return flags; |
141 | return IORESOURCE_MEM; |
142 | } |
143 | |
144 | /* |
145 | * SBUS bus specific translator |
146 | */ |
147 | |
148 | int of_bus_sbus_match(struct device_node *np) |
149 | { |
150 | struct device_node *dp = np; |
151 | |
152 | while (dp) { |
153 | if (!strcmp(dp->name, "sbus") || |
154 | !strcmp(dp->name, "sbi")) |
155 | return 1; |
156 | |
157 | /* Have a look at use_1to1_mapping(). We're trying |
158 | * to match SBUS if that's the top-level bus and we |
159 | * don't have some intervening real bus that provides |
160 | * ranges based translations. |
161 | */ |
162 | if (of_find_property(dp, "ranges", NULL) != NULL) |
163 | break; |
164 | |
165 | dp = dp->parent; |
166 | } |
167 | |
168 | return 0; |
169 | } |
170 | |
171 | void of_bus_sbus_count_cells(struct device_node *child, int *addrc, int *sizec) |
172 | { |
173 | if (addrc) |
174 | *addrc = 2; |
175 | if (sizec) |
176 | *sizec = 1; |
177 | } |
178 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9