diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-03 12:44:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-03 12:44:08 -0400 |
commit | a54dfb1a845c38a97686268d8c4086a63d9493aa (patch) | |
tree | 3b31c81672fa89102aae929cc6c1e48e6e9382f4 /drivers/of | |
parent | eb0ad9c06d51edb5d18a7007fd4d77a8805b2ba7 (diff) | |
parent | 36165f55055781a0e4bf32d775241796414504b0 (diff) |
Merge tag 'dt-for-3.7' of git://sources.calxeda.com/kernel/linux
Pull devicetree updates from Rob Herring:
- Import of latest upstream device tree compiler (dtc)
- New function of_get_child_by_name
- Support for #size-cells of 0 and #addr-cells of >2
- Couple of DT binding documentation updates
Fix up trivial conflicts due to of_get_child_by_name() having been added
next to the new of_get_next_available_child().
* tag 'dt-for-3.7' of git://sources.calxeda.com/kernel/linux:
MAINTAINERS: add scripts/dtc under Devicetree maintainers
dtc: import latest upstream dtc
dt: Document general interrupt controller bindings
dt/s3c64xx/spi: Use of_get_child_by_name to get a named child
dt: introduce of_get_child_by_name to get child node by name
of: i2c: add support for wakeup-source property
of/address: Handle #address-cells > 2 specially
DT: export of_irq_to_resource_table()
devicetree: serial: Add documentation for imx serial
devicetree: pwm: mxs-pwm.txt: Fix reg field annotation
of: Allow busses with #size-cells=0
Diffstat (limited to 'drivers/of')
-rw-r--r-- | drivers/of/address.c | 35 | ||||
-rw-r--r-- | drivers/of/base.c | 23 | ||||
-rw-r--r-- | drivers/of/irq.c | 1 | ||||
-rw-r--r-- | drivers/of/of_i2c.c | 3 | ||||
-rw-r--r-- | drivers/of/platform.c | 16 |
5 files changed, 71 insertions, 7 deletions
diff --git a/drivers/of/address.c b/drivers/of/address.c index 7e262a6124c5..72e496f1e9b0 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c | |||
@@ -9,8 +9,8 @@ | |||
9 | 9 | ||
10 | /* Max address size we deal with */ | 10 | /* Max address size we deal with */ |
11 | #define OF_MAX_ADDR_CELLS 4 | 11 | #define OF_MAX_ADDR_CELLS 4 |
12 | #define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \ | 12 | #define OF_CHECK_ADDR_COUNT(na) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS) |
13 | (ns) > 0) | 13 | #define OF_CHECK_COUNTS(na, ns) (OF_CHECK_ADDR_COUNT(na) && (ns) > 0) |
14 | 14 | ||
15 | static struct of_bus *of_match_bus(struct device_node *np); | 15 | static struct of_bus *of_match_bus(struct device_node *np); |
16 | static int __of_address_to_resource(struct device_node *dev, | 16 | static int __of_address_to_resource(struct device_node *dev, |
@@ -69,6 +69,14 @@ static u64 of_bus_default_map(u32 *addr, const __be32 *range, | |||
69 | (unsigned long long)cp, (unsigned long long)s, | 69 | (unsigned long long)cp, (unsigned long long)s, |
70 | (unsigned long long)da); | 70 | (unsigned long long)da); |
71 | 71 | ||
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 | |||
72 | if (da < cp || da >= (cp + s)) | 80 | if (da < cp || da >= (cp + s)) |
73 | return OF_BAD_ADDR; | 81 | return OF_BAD_ADDR; |
74 | return da - cp; | 82 | return da - cp; |
@@ -182,7 +190,7 @@ const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, | |||
182 | } | 190 | } |
183 | bus->count_cells(dev, &na, &ns); | 191 | bus->count_cells(dev, &na, &ns); |
184 | of_node_put(parent); | 192 | of_node_put(parent); |
185 | if (!OF_CHECK_COUNTS(na, ns)) | 193 | if (!OF_CHECK_ADDR_COUNT(na)) |
186 | return NULL; | 194 | return NULL; |
187 | 195 | ||
188 | /* Get "reg" or "assigned-addresses" property */ | 196 | /* Get "reg" or "assigned-addresses" property */ |
@@ -490,6 +498,25 @@ u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr) | |||
490 | } | 498 | } |
491 | EXPORT_SYMBOL(of_translate_dma_address); | 499 | EXPORT_SYMBOL(of_translate_dma_address); |
492 | 500 | ||
501 | bool 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 | } | ||
518 | EXPORT_SYMBOL(of_can_translate_address); | ||
519 | |||
493 | const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, | 520 | const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, |
494 | unsigned int *flags) | 521 | unsigned int *flags) |
495 | { | 522 | { |
@@ -506,7 +533,7 @@ const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, | |||
506 | bus = of_match_bus(parent); | 533 | bus = of_match_bus(parent); |
507 | bus->count_cells(dev, &na, &ns); | 534 | bus->count_cells(dev, &na, &ns); |
508 | of_node_put(parent); | 535 | of_node_put(parent); |
509 | if (!OF_CHECK_COUNTS(na, ns)) | 536 | if (!OF_CHECK_ADDR_COUNT(na)) |
510 | return NULL; | 537 | return NULL; |
511 | 538 | ||
512 | /* Get "reg" or "assigned-addresses" property */ | 539 | /* Get "reg" or "assigned-addresses" property */ |
diff --git a/drivers/of/base.c b/drivers/of/base.c index d4a1c9a043e1..af3b22ac7627 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
@@ -391,6 +391,29 @@ struct device_node *of_get_next_available_child(const struct device_node *node, | |||
391 | EXPORT_SYMBOL(of_get_next_available_child); | 391 | EXPORT_SYMBOL(of_get_next_available_child); |
392 | 392 | ||
393 | /** | 393 | /** |
394 | * of_get_child_by_name - Find the child node by name for a given parent | ||
395 | * @node: parent node | ||
396 | * @name: child name to look for. | ||
397 | * | ||
398 | * This function looks for child node for given matching name | ||
399 | * | ||
400 | * Returns a node pointer if found, with refcount incremented, use | ||
401 | * of_node_put() on it when done. | ||
402 | * Returns NULL if node is not found. | ||
403 | */ | ||
404 | struct device_node *of_get_child_by_name(const struct device_node *node, | ||
405 | const char *name) | ||
406 | { | ||
407 | struct device_node *child; | ||
408 | |||
409 | for_each_child_of_node(node, child) | ||
410 | if (child->name && (of_node_cmp(child->name, name) == 0)) | ||
411 | break; | ||
412 | return child; | ||
413 | } | ||
414 | EXPORT_SYMBOL(of_get_child_by_name); | ||
415 | |||
416 | /** | ||
394 | * of_find_node_by_path - Find a node matching a full OF path | 417 | * of_find_node_by_path - Find a node matching a full OF path |
395 | * @path: The full path to match | 418 | * @path: The full path to match |
396 | * | 419 | * |
diff --git a/drivers/of/irq.c b/drivers/of/irq.c index ff8ab7b27373..a23ec7779997 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c | |||
@@ -392,6 +392,7 @@ int of_irq_to_resource_table(struct device_node *dev, struct resource *res, | |||
392 | 392 | ||
393 | return i; | 393 | return i; |
394 | } | 394 | } |
395 | EXPORT_SYMBOL_GPL(of_irq_to_resource_table); | ||
395 | 396 | ||
396 | struct intc_desc { | 397 | struct intc_desc { |
397 | struct list_head list; | 398 | struct list_head list; |
diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index 1e173f357674..3550f3bf4f92 100644 --- a/drivers/of/of_i2c.c +++ b/drivers/of/of_i2c.c | |||
@@ -61,6 +61,9 @@ void of_i2c_register_devices(struct i2c_adapter *adap) | |||
61 | info.of_node = of_node_get(node); | 61 | info.of_node = of_node_get(node); |
62 | info.archdata = &dev_ad; | 62 | info.archdata = &dev_ad; |
63 | 63 | ||
64 | if (of_get_property(node, "wakeup-source", NULL)) | ||
65 | info.flags |= I2C_CLIENT_WAKE; | ||
66 | |||
64 | request_module("%s%s", I2C_MODULE_PREFIX, info.type); | 67 | request_module("%s%s", I2C_MODULE_PREFIX, info.type); |
65 | 68 | ||
66 | result = i2c_new_device(adap, &info); | 69 | result = i2c_new_device(adap, &info); |
diff --git a/drivers/of/platform.c b/drivers/of/platform.c index e44f8c2d239d..9bdeaf30b17d 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c | |||
@@ -78,6 +78,7 @@ void of_device_make_bus_id(struct device *dev) | |||
78 | struct device_node *node = dev->of_node; | 78 | struct device_node *node = dev->of_node; |
79 | const u32 *reg; | 79 | const u32 *reg; |
80 | u64 addr; | 80 | u64 addr; |
81 | const __be32 *addrp; | ||
81 | int magic; | 82 | int magic; |
82 | 83 | ||
83 | #ifdef CONFIG_PPC_DCR | 84 | #ifdef CONFIG_PPC_DCR |
@@ -105,7 +106,15 @@ void of_device_make_bus_id(struct device *dev) | |||
105 | */ | 106 | */ |
106 | reg = of_get_property(node, "reg", NULL); | 107 | reg = of_get_property(node, "reg", NULL); |
107 | if (reg) { | 108 | if (reg) { |
108 | addr = of_translate_address(node, reg); | 109 | if (of_can_translate_address(node)) { |
110 | addr = of_translate_address(node, reg); | ||
111 | } else { | ||
112 | addrp = of_get_address(node, 0, NULL, NULL); | ||
113 | if (addrp) | ||
114 | addr = of_read_number(addrp, 1); | ||
115 | else | ||
116 | addr = OF_BAD_ADDR; | ||
117 | } | ||
109 | if (addr != OF_BAD_ADDR) { | 118 | if (addr != OF_BAD_ADDR) { |
110 | dev_set_name(dev, "%llx.%s", | 119 | dev_set_name(dev, "%llx.%s", |
111 | (unsigned long long)addr, node->name); | 120 | (unsigned long long)addr, node->name); |
@@ -140,8 +149,9 @@ struct platform_device *of_device_alloc(struct device_node *np, | |||
140 | return NULL; | 149 | return NULL; |
141 | 150 | ||
142 | /* count the io and irq resources */ | 151 | /* count the io and irq resources */ |
143 | while (of_address_to_resource(np, num_reg, &temp_res) == 0) | 152 | if (of_can_translate_address(np)) |
144 | num_reg++; | 153 | while (of_address_to_resource(np, num_reg, &temp_res) == 0) |
154 | num_reg++; | ||
145 | num_irq = of_irq_count(np); | 155 | num_irq = of_irq_count(np); |
146 | 156 | ||
147 | /* Populate the resource table */ | 157 | /* Populate the resource table */ |