Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
of_device_32.c
Go to the documentation of this file.
1 #include <linux/string.h>
2 #include <linux/kernel.h>
3 #include <linux/of.h>
4 #include <linux/init.h>
6 #include <linux/slab.h>
7 #include <linux/errno.h>
8 #include <linux/irq.h>
9 #include <linux/of_device.h>
10 #include <linux/of_platform.h>
11 #include <asm/leon.h>
12 #include <asm/leon_amba.h>
13 
14 #include "of_device_common.h"
15 #include "irq.h"
16 
17 /*
18  * PCI bus specific translator
19  */
20 
21 static int of_bus_pci_match(struct device_node *np)
22 {
23  if (!strcmp(np->type, "pci") || !strcmp(np->type, "pciex")) {
24  /* Do not do PCI specific frobbing if the
25  * PCI bridge lacks a ranges property. We
26  * want to pass it through up to the next
27  * parent as-is, not with the PCI translate
28  * method which chops off the top address cell.
29  */
30  if (!of_find_property(np, "ranges", NULL))
31  return 0;
32 
33  return 1;
34  }
35 
36  return 0;
37 }
38 
39 static void of_bus_pci_count_cells(struct device_node *np,
40  int *addrc, int *sizec)
41 {
42  if (addrc)
43  *addrc = 3;
44  if (sizec)
45  *sizec = 2;
46 }
47 
48 static int of_bus_pci_map(u32 *addr, const u32 *range,
49  int na, int ns, int pna)
50 {
52  int i;
53 
54  /* Check address type match */
55  if ((addr[0] ^ range[0]) & 0x03000000)
56  return -EINVAL;
57 
58  if (of_out_of_range(addr + 1, range + 1, range + na + pna,
59  na - 1, ns))
60  return -EINVAL;
61 
62  /* Start with the parent range base. */
63  memcpy(result, range + na, pna * 4);
64 
65  /* Add in the child address offset, skipping high cell. */
66  for (i = 0; i < na - 1; i++)
67  result[pna - 1 - i] +=
68  (addr[na - 1 - i] -
69  range[na - 1 - i]);
70 
71  memcpy(addr, result, pna * 4);
72 
73  return 0;
74 }
75 
76 static unsigned long of_bus_pci_get_flags(const u32 *addr, unsigned long flags)
77 {
78  u32 w = addr[0];
79 
80  /* For PCI, we override whatever child busses may have used. */
81  flags = 0;
82  switch((w >> 24) & 0x03) {
83  case 0x01:
84  flags |= IORESOURCE_IO;
85  break;
86 
87  case 0x02: /* 32 bits */
88  case 0x03: /* 64 bits */
89  flags |= IORESOURCE_MEM;
90  break;
91  }
92  if (w & 0x40000000)
93  flags |= IORESOURCE_PREFETCH;
94  return flags;
95 }
96 
97 static unsigned long of_bus_sbus_get_flags(const u32 *addr, unsigned long flags)
98 {
99  return IORESOURCE_MEM;
100 }
101 
102  /*
103  * AMBAPP bus specific translator
104  */
105 
106 static int of_bus_ambapp_match(struct device_node *np)
107 {
108  return !strcmp(np->type, "ambapp");
109 }
110 
111 static void of_bus_ambapp_count_cells(struct device_node *child,
112  int *addrc, int *sizec)
113 {
114  if (addrc)
115  *addrc = 1;
116  if (sizec)
117  *sizec = 1;
118 }
119 
120 static int of_bus_ambapp_map(u32 *addr, const u32 *range,
121  int na, int ns, int pna)
122 {
123  return of_bus_default_map(addr, range, na, ns, pna);
124 }
125 
126 static unsigned long of_bus_ambapp_get_flags(const u32 *addr,
127  unsigned long flags)
128 {
129  return IORESOURCE_MEM;
130 }
131 
132 /*
133  * Array of bus specific translators
134  */
135 
136 static struct of_bus of_busses[] = {
137  /* PCI */
138  {
139  .name = "pci",
140  .addr_prop_name = "assigned-addresses",
141  .match = of_bus_pci_match,
142  .count_cells = of_bus_pci_count_cells,
143  .map = of_bus_pci_map,
144  .get_flags = of_bus_pci_get_flags,
145  },
146  /* SBUS */
147  {
148  .name = "sbus",
149  .addr_prop_name = "reg",
150  .match = of_bus_sbus_match,
151  .count_cells = of_bus_sbus_count_cells,
152  .map = of_bus_default_map,
153  .get_flags = of_bus_sbus_get_flags,
154  },
155  /* AMBA */
156  {
157  .name = "ambapp",
158  .addr_prop_name = "reg",
159  .match = of_bus_ambapp_match,
160  .count_cells = of_bus_ambapp_count_cells,
161  .map = of_bus_ambapp_map,
162  .get_flags = of_bus_ambapp_get_flags,
163  },
164  /* Default */
165  {
166  .name = "default",
167  .addr_prop_name = "reg",
168  .match = NULL,
169  .count_cells = of_bus_default_count_cells,
170  .map = of_bus_default_map,
171  .get_flags = of_bus_default_get_flags,
172  },
173 };
174 
175 static struct of_bus *of_match_bus(struct device_node *np)
176 {
177  int i;
178 
179  for (i = 0; i < ARRAY_SIZE(of_busses); i ++)
180  if (!of_busses[i].match || of_busses[i].match(np))
181  return &of_busses[i];
182  BUG();
183  return NULL;
184 }
185 
186 static int __init build_one_resource(struct device_node *parent,
187  struct of_bus *bus,
188  struct of_bus *pbus,
189  u32 *addr,
190  int na, int ns, int pna)
191 {
192  const u32 *ranges;
193  unsigned int rlen;
194  int rone;
195 
196  ranges = of_get_property(parent, "ranges", &rlen);
197  if (ranges == NULL || rlen == 0) {
198  u32 result[OF_MAX_ADDR_CELLS];
199  int i;
200 
201  memset(result, 0, pna * 4);
202  for (i = 0; i < na; i++)
203  result[pna - 1 - i] =
204  addr[na - 1 - i];
205 
206  memcpy(addr, result, pna * 4);
207  return 0;
208  }
209 
210  /* Now walk through the ranges */
211  rlen /= 4;
212  rone = na + pna + ns;
213  for (; rlen >= rone; rlen -= rone, ranges += rone) {
214  if (!bus->map(addr, ranges, na, ns, pna))
215  return 0;
216  }
217 
218  return 1;
219 }
220 
221 static int __init use_1to1_mapping(struct device_node *pp)
222 {
223  /* If we have a ranges property in the parent, use it. */
224  if (of_find_property(pp, "ranges", NULL) != NULL)
225  return 0;
226 
227  /* Some SBUS devices use intermediate nodes to express
228  * hierarchy within the device itself. These aren't
229  * real bus nodes, and don't have a 'ranges' property.
230  * But, we should still pass the translation work up
231  * to the SBUS itself.
232  */
233  if (!strcmp(pp->name, "dma") ||
234  !strcmp(pp->name, "espdma") ||
235  !strcmp(pp->name, "ledma") ||
236  !strcmp(pp->name, "lebuffer"))
237  return 0;
238 
239  return 1;
240 }
241 
242 static int of_resource_verbose;
243 
244 static void __init build_device_resources(struct platform_device *op,
245  struct device *parent)
246 {
247  struct platform_device *p_op;
248  struct of_bus *bus;
249  int na, ns;
250  int index, num_reg;
251  const void *preg;
252 
253  if (!parent)
254  return;
255 
256  p_op = to_platform_device(parent);
257  bus = of_match_bus(p_op->dev.of_node);
258  bus->count_cells(op->dev.of_node, &na, &ns);
259 
260  preg = of_get_property(op->dev.of_node, bus->addr_prop_name, &num_reg);
261  if (!preg || num_reg == 0)
262  return;
263 
264  /* Convert to num-cells. */
265  num_reg /= 4;
266 
267  /* Conver to num-entries. */
268  num_reg /= na + ns;
269 
270  op->resource = op->archdata.resource;
271  op->num_resources = num_reg;
272  for (index = 0; index < num_reg; index++) {
273  struct resource *r = &op->resource[index];
274  u32 addr[OF_MAX_ADDR_CELLS];
275  const u32 *reg = (preg + (index * ((na + ns) * 4)));
276  struct device_node *dp = op->dev.of_node;
277  struct device_node *pp = p_op->dev.of_node;
278  struct of_bus *pbus, *dbus;
279  u64 size, result = OF_BAD_ADDR;
280  unsigned long flags;
281  int dna, dns;
282  int pna, pns;
283 
284  size = of_read_addr(reg + na, ns);
285 
286  memcpy(addr, reg, na * 4);
287 
288  flags = bus->get_flags(reg, 0);
289 
290  if (use_1to1_mapping(pp)) {
291  result = of_read_addr(addr, na);
292  goto build_res;
293  }
294 
295  dna = na;
296  dns = ns;
297  dbus = bus;
298 
299  while (1) {
300  dp = pp;
301  pp = dp->parent;
302  if (!pp) {
303  result = of_read_addr(addr, dna);
304  break;
305  }
306 
307  pbus = of_match_bus(pp);
308  pbus->count_cells(dp, &pna, &pns);
309 
310  if (build_one_resource(dp, dbus, pbus, addr,
311  dna, dns, pna))
312  break;
313 
314  flags = pbus->get_flags(addr, flags);
315 
316  dna = pna;
317  dns = pns;
318  dbus = pbus;
319  }
320 
321  build_res:
322  memset(r, 0, sizeof(*r));
323 
324  if (of_resource_verbose)
325  printk("%s reg[%d] -> %llx\n",
326  op->dev.of_node->full_name, index,
327  result);
328 
329  if (result != OF_BAD_ADDR) {
330  r->start = result & 0xffffffff;
331  r->end = result + size - 1;
332  r->flags = flags | ((result >> 32ULL) & 0xffUL);
333  }
334  r->name = op->dev.of_node->name;
335  }
336 }
337 
338 static struct platform_device * __init scan_one_device(struct device_node *dp,
339  struct device *parent)
340 {
341  struct platform_device *op = kzalloc(sizeof(*op), GFP_KERNEL);
342  const struct linux_prom_irqs *intr;
343  struct dev_archdata *sd;
344  int len, i;
345 
346  if (!op)
347  return NULL;
348 
349  sd = &op->dev.archdata;
350  sd->op = op;
351 
352  op->dev.of_node = dp;
353 
354  intr = of_get_property(dp, "intr", &len);
355  if (intr) {
356  op->archdata.num_irqs = len / sizeof(struct linux_prom_irqs);
357  for (i = 0; i < op->archdata.num_irqs; i++)
358  op->archdata.irqs[i] =
359  sparc_config.build_device_irq(op, intr[i].pri);
360  } else {
361  const unsigned int *irq =
362  of_get_property(dp, "interrupts", &len);
363 
364  if (irq) {
365  op->archdata.num_irqs = len / sizeof(unsigned int);
366  for (i = 0; i < op->archdata.num_irqs; i++)
367  op->archdata.irqs[i] =
368  sparc_config.build_device_irq(op, irq[i]);
369  } else {
370  op->archdata.num_irqs = 0;
371  }
372  }
373 
374  build_device_resources(op, parent);
375 
376  op->dev.parent = parent;
377  op->dev.bus = &platform_bus_type;
378  if (!parent)
379  dev_set_name(&op->dev, "root");
380  else
381  dev_set_name(&op->dev, "%08x", dp->phandle);
382 
383  if (of_device_register(op)) {
384  printk("%s: Could not register of device.\n",
385  dp->full_name);
386  kfree(op);
387  op = NULL;
388  }
389 
390  return op;
391 }
392 
393 static void __init scan_tree(struct device_node *dp, struct device *parent)
394 {
395  while (dp) {
396  struct platform_device *op = scan_one_device(dp, parent);
397 
398  if (op)
399  scan_tree(dp->child, &op->dev);
400 
401  dp = dp->sibling;
402  }
403 }
404 
405 static int __init scan_of_devices(void)
406 {
407  struct device_node *root = of_find_node_by_path("/");
408  struct platform_device *parent;
409 
410  parent = scan_one_device(root, NULL);
411  if (!parent)
412  return 0;
413 
414  scan_tree(root->child, &parent->dev);
415  return 0;
416 }
417 postcore_initcall(scan_of_devices);
418 
419 static int __init of_debug(char *str)
420 {
421  int val = 0;
422 
423  get_option(&str, &val);
424  if (val & 1)
425  of_resource_verbose = 1;
426  return 1;
427 }
428 
429 __setup("of_debug=", of_debug);