diff options
Diffstat (limited to 'drivers/of')
-rw-r--r-- | drivers/of/Kconfig | 8 | ||||
-rw-r--r-- | drivers/of/Makefile | 1 | ||||
-rw-r--r-- | drivers/of/address.c | 18 | ||||
-rw-r--r-- | drivers/of/base.c | 65 | ||||
-rw-r--r-- | drivers/of/gpio.c | 11 | ||||
-rw-r--r-- | drivers/of/of_pci.c | 113 | ||||
-rw-r--r-- | drivers/of/of_pci_irq.c | 92 | ||||
-rw-r--r-- | drivers/of/platform.c | 196 |
8 files changed, 407 insertions, 97 deletions
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index d06a6374ed6c..cac63c9f49ae 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig | |||
@@ -71,8 +71,14 @@ config OF_MDIO | |||
71 | 71 | ||
72 | config OF_PCI | 72 | config OF_PCI |
73 | def_tristate PCI | 73 | def_tristate PCI |
74 | depends on PCI && (PPC || MICROBLAZE || X86) | 74 | depends on PCI |
75 | help | 75 | help |
76 | OpenFirmware PCI bus accessors | 76 | OpenFirmware PCI bus accessors |
77 | 77 | ||
78 | config OF_PCI_IRQ | ||
79 | def_tristate PCI | ||
80 | depends on OF_PCI && OF_IRQ | ||
81 | help | ||
82 | OpenFirmware PCI IRQ routing helpers | ||
83 | |||
78 | endmenu # OF | 84 | endmenu # OF |
diff --git a/drivers/of/Makefile b/drivers/of/Makefile index f7861ed2f287..dccb1176be57 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile | |||
@@ -10,3 +10,4 @@ obj-$(CONFIG_OF_NET) += of_net.o | |||
10 | obj-$(CONFIG_OF_SPI) += of_spi.o | 10 | obj-$(CONFIG_OF_SPI) += of_spi.o |
11 | obj-$(CONFIG_OF_MDIO) += of_mdio.o | 11 | obj-$(CONFIG_OF_MDIO) += of_mdio.o |
12 | obj-$(CONFIG_OF_PCI) += of_pci.o | 12 | obj-$(CONFIG_OF_PCI) += of_pci.o |
13 | obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o | ||
diff --git a/drivers/of/address.c b/drivers/of/address.c index b4559c58c095..da1f4b9605df 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c | |||
@@ -577,6 +577,24 @@ int of_address_to_resource(struct device_node *dev, int index, | |||
577 | } | 577 | } |
578 | EXPORT_SYMBOL_GPL(of_address_to_resource); | 578 | EXPORT_SYMBOL_GPL(of_address_to_resource); |
579 | 579 | ||
580 | struct device_node *of_find_matching_node_by_address(struct device_node *from, | ||
581 | const struct of_device_id *matches, | ||
582 | u64 base_address) | ||
583 | { | ||
584 | struct device_node *dn = of_find_matching_node(from, matches); | ||
585 | struct resource res; | ||
586 | |||
587 | while (dn) { | ||
588 | if (of_address_to_resource(dn, 0, &res)) | ||
589 | continue; | ||
590 | if (res.start == base_address) | ||
591 | return dn; | ||
592 | dn = of_find_matching_node(dn, matches); | ||
593 | } | ||
594 | |||
595 | return NULL; | ||
596 | } | ||
597 | |||
580 | 598 | ||
581 | /** | 599 | /** |
582 | * of_iomap - Maps the memory mapped IO for a given device_node | 600 | * of_iomap - Maps the memory mapped IO for a given device_node |
diff --git a/drivers/of/base.c b/drivers/of/base.c index 632ebae7f17a..02ed36719def 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
@@ -596,6 +596,71 @@ struct device_node *of_find_node_by_phandle(phandle handle) | |||
596 | EXPORT_SYMBOL(of_find_node_by_phandle); | 596 | EXPORT_SYMBOL(of_find_node_by_phandle); |
597 | 597 | ||
598 | /** | 598 | /** |
599 | * of_property_read_u32_array - Find and read an array of 32 bit integers | ||
600 | * from a property. | ||
601 | * | ||
602 | * @np: device node from which the property value is to be read. | ||
603 | * @propname: name of the property to be searched. | ||
604 | * @out_value: pointer to return value, modified only if return value is 0. | ||
605 | * | ||
606 | * Search for a property in a device node and read 32-bit value(s) from | ||
607 | * it. Returns 0 on success, -EINVAL if the property does not exist, | ||
608 | * -ENODATA if property does not have a value, and -EOVERFLOW if the | ||
609 | * property data isn't large enough. | ||
610 | * | ||
611 | * The out_value is modified only if a valid u32 value can be decoded. | ||
612 | */ | ||
613 | int of_property_read_u32_array(const struct device_node *np, char *propname, | ||
614 | u32 *out_values, size_t sz) | ||
615 | { | ||
616 | struct property *prop = of_find_property(np, propname, NULL); | ||
617 | const __be32 *val; | ||
618 | |||
619 | if (!prop) | ||
620 | return -EINVAL; | ||
621 | if (!prop->value) | ||
622 | return -ENODATA; | ||
623 | if ((sz * sizeof(*out_values)) > prop->length) | ||
624 | return -EOVERFLOW; | ||
625 | |||
626 | val = prop->value; | ||
627 | while (sz--) | ||
628 | *out_values++ = be32_to_cpup(val++); | ||
629 | return 0; | ||
630 | } | ||
631 | EXPORT_SYMBOL_GPL(of_property_read_u32_array); | ||
632 | |||
633 | /** | ||
634 | * of_property_read_string - Find and read a string from a property | ||
635 | * @np: device node from which the property value is to be read. | ||
636 | * @propname: name of the property to be searched. | ||
637 | * @out_string: pointer to null terminated return string, modified only if | ||
638 | * return value is 0. | ||
639 | * | ||
640 | * Search for a property in a device tree node and retrieve a null | ||
641 | * terminated string value (pointer to data, not a copy). Returns 0 on | ||
642 | * success, -EINVAL if the property does not exist, -ENODATA if property | ||
643 | * does not have a value, and -EILSEQ if the string is not null-terminated | ||
644 | * within the length of the property data. | ||
645 | * | ||
646 | * The out_string pointer is modified only if a valid string can be decoded. | ||
647 | */ | ||
648 | int of_property_read_string(struct device_node *np, char *propname, | ||
649 | const char **out_string) | ||
650 | { | ||
651 | struct property *prop = of_find_property(np, propname, NULL); | ||
652 | if (!prop) | ||
653 | return -EINVAL; | ||
654 | if (!prop->value) | ||
655 | return -ENODATA; | ||
656 | if (strnlen(prop->value, prop->length) >= prop->length) | ||
657 | return -EILSEQ; | ||
658 | *out_string = prop->value; | ||
659 | return 0; | ||
660 | } | ||
661 | EXPORT_SYMBOL_GPL(of_property_read_string); | ||
662 | |||
663 | /** | ||
599 | * of_parse_phandle - Resolve a phandle property to a device_node pointer | 664 | * of_parse_phandle - Resolve a phandle property to a device_node pointer |
600 | * @np: Pointer to device node holding phandle property | 665 | * @np: Pointer to device node holding phandle property |
601 | * @phandle_name: Name of property holding a phandle value | 666 | * @phandle_name: Name of property holding a phandle value |
diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c index 905960338fb2..3007662ac614 100644 --- a/drivers/of/gpio.c +++ b/drivers/of/gpio.c | |||
@@ -21,8 +21,9 @@ | |||
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | 22 | ||
23 | /** | 23 | /** |
24 | * of_get_gpio_flags - Get a GPIO number and flags to use with GPIO API | 24 | * of_get_named_gpio_flags() - Get a GPIO number and flags to use with GPIO API |
25 | * @np: device node to get GPIO from | 25 | * @np: device node to get GPIO from |
26 | * @propname: property name containing gpio specifier(s) | ||
26 | * @index: index of the GPIO | 27 | * @index: index of the GPIO |
27 | * @flags: a flags pointer to fill in | 28 | * @flags: a flags pointer to fill in |
28 | * | 29 | * |
@@ -30,8 +31,8 @@ | |||
30 | * value on the error condition. If @flags is not NULL the function also fills | 31 | * value on the error condition. If @flags is not NULL the function also fills |
31 | * in flags for the GPIO. | 32 | * in flags for the GPIO. |
32 | */ | 33 | */ |
33 | int of_get_gpio_flags(struct device_node *np, int index, | 34 | int of_get_named_gpio_flags(struct device_node *np, const char *propname, |
34 | enum of_gpio_flags *flags) | 35 | int index, enum of_gpio_flags *flags) |
35 | { | 36 | { |
36 | int ret; | 37 | int ret; |
37 | struct device_node *gpio_np; | 38 | struct device_node *gpio_np; |
@@ -40,7 +41,7 @@ int of_get_gpio_flags(struct device_node *np, int index, | |||
40 | const void *gpio_spec; | 41 | const void *gpio_spec; |
41 | const __be32 *gpio_cells; | 42 | const __be32 *gpio_cells; |
42 | 43 | ||
43 | ret = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index, | 44 | ret = of_parse_phandles_with_args(np, propname, "#gpio-cells", index, |
44 | &gpio_np, &gpio_spec); | 45 | &gpio_np, &gpio_spec); |
45 | if (ret) { | 46 | if (ret) { |
46 | pr_debug("%s: can't parse gpios property\n", __func__); | 47 | pr_debug("%s: can't parse gpios property\n", __func__); |
@@ -79,7 +80,7 @@ err0: | |||
79 | pr_debug("%s exited with status %d\n", __func__, ret); | 80 | pr_debug("%s exited with status %d\n", __func__, ret); |
80 | return ret; | 81 | return ret; |
81 | } | 82 | } |
82 | EXPORT_SYMBOL(of_get_gpio_flags); | 83 | EXPORT_SYMBOL(of_get_named_gpio_flags); |
83 | 84 | ||
84 | /** | 85 | /** |
85 | * of_gpio_count - Count GPIOs for a device | 86 | * of_gpio_count - Count GPIOs for a device |
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c index ac1ec54e4fd5..3701b62c1d5e 100644 --- a/drivers/of/of_pci.c +++ b/drivers/of/of_pci.c | |||
@@ -1,92 +1,41 @@ | |||
1 | #include <linux/kernel.h> | 1 | #include <linux/kernel.h> |
2 | #include <linux/of.h> | ||
2 | #include <linux/of_pci.h> | 3 | #include <linux/of_pci.h> |
3 | #include <linux/of_irq.h> | ||
4 | #include <asm/prom.h> | 4 | #include <asm/prom.h> |
5 | 5 | ||
6 | /** | 6 | static inline int __of_pci_pci_compare(struct device_node *node, |
7 | * of_irq_map_pci - Resolve the interrupt for a PCI device | 7 | unsigned int devfn) |
8 | * @pdev: the device whose interrupt is to be resolved | ||
9 | * @out_irq: structure of_irq filled by this function | ||
10 | * | ||
11 | * This function resolves the PCI interrupt for a given PCI device. If a | ||
12 | * device-node exists for a given pci_dev, it will use normal OF tree | ||
13 | * walking. If not, it will implement standard swizzling and walk up the | ||
14 | * PCI tree until an device-node is found, at which point it will finish | ||
15 | * resolving using the OF tree walking. | ||
16 | */ | ||
17 | int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) | ||
18 | { | 8 | { |
19 | struct device_node *dn, *ppnode; | 9 | unsigned int size; |
20 | struct pci_dev *ppdev; | 10 | const __be32 *reg = of_get_property(node, "reg", &size); |
21 | u32 lspec; | ||
22 | __be32 lspec_be; | ||
23 | __be32 laddr[3]; | ||
24 | u8 pin; | ||
25 | int rc; | ||
26 | 11 | ||
27 | /* Check if we have a device node, if yes, fallback to standard | 12 | if (!reg || size < 5 * sizeof(__be32)) |
28 | * device tree parsing | 13 | return 0; |
29 | */ | 14 | return ((be32_to_cpup(®[0]) >> 8) & 0xff) == devfn; |
30 | dn = pci_device_to_OF_node(pdev); | 15 | } |
31 | if (dn) { | ||
32 | rc = of_irq_map_one(dn, 0, out_irq); | ||
33 | if (!rc) | ||
34 | return rc; | ||
35 | } | ||
36 | |||
37 | /* Ok, we don't, time to have fun. Let's start by building up an | ||
38 | * interrupt spec. we assume #interrupt-cells is 1, which is standard | ||
39 | * for PCI. If you do different, then don't use that routine. | ||
40 | */ | ||
41 | rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin); | ||
42 | if (rc != 0) | ||
43 | return rc; | ||
44 | /* No pin, exit */ | ||
45 | if (pin == 0) | ||
46 | return -ENODEV; | ||
47 | |||
48 | /* Now we walk up the PCI tree */ | ||
49 | lspec = pin; | ||
50 | for (;;) { | ||
51 | /* Get the pci_dev of our parent */ | ||
52 | ppdev = pdev->bus->self; | ||
53 | |||
54 | /* Ouch, it's a host bridge... */ | ||
55 | if (ppdev == NULL) { | ||
56 | ppnode = pci_bus_to_OF_node(pdev->bus); | ||
57 | |||
58 | /* No node for host bridge ? give up */ | ||
59 | if (ppnode == NULL) | ||
60 | return -EINVAL; | ||
61 | } else { | ||
62 | /* We found a P2P bridge, check if it has a node */ | ||
63 | ppnode = pci_device_to_OF_node(ppdev); | ||
64 | } | ||
65 | |||
66 | /* Ok, we have found a parent with a device-node, hand over to | ||
67 | * the OF parsing code. | ||
68 | * We build a unit address from the linux device to be used for | ||
69 | * resolution. Note that we use the linux bus number which may | ||
70 | * not match your firmware bus numbering. | ||
71 | * Fortunately, in most cases, interrupt-map-mask doesn't | ||
72 | * include the bus number as part of the matching. | ||
73 | * You should still be careful about that though if you intend | ||
74 | * to rely on this function (you ship a firmware that doesn't | ||
75 | * create device nodes for all PCI devices). | ||
76 | */ | ||
77 | if (ppnode) | ||
78 | break; | ||
79 | 16 | ||
80 | /* We can only get here if we hit a P2P bridge with no node, | 17 | struct device_node *of_pci_find_child_device(struct device_node *parent, |
81 | * let's do standard swizzling and try again | 18 | unsigned int devfn) |
19 | { | ||
20 | struct device_node *node, *node2; | ||
21 | |||
22 | for_each_child_of_node(parent, node) { | ||
23 | if (__of_pci_pci_compare(node, devfn)) | ||
24 | return node; | ||
25 | /* | ||
26 | * Some OFs create a parent node "multifunc-device" as | ||
27 | * a fake root for all functions of a multi-function | ||
28 | * device we go down them as well. | ||
82 | */ | 29 | */ |
83 | lspec = pci_swizzle_interrupt_pin(pdev, lspec); | 30 | if (!strcmp(node->name, "multifunc-device")) { |
84 | pdev = ppdev; | 31 | for_each_child_of_node(node, node2) { |
32 | if (__of_pci_pci_compare(node2, devfn)) { | ||
33 | of_node_put(node); | ||
34 | return node2; | ||
35 | } | ||
36 | } | ||
37 | } | ||
85 | } | 38 | } |
86 | 39 | return NULL; | |
87 | lspec_be = cpu_to_be32(lspec); | ||
88 | laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8)); | ||
89 | laddr[1] = laddr[2] = cpu_to_be32(0); | ||
90 | return of_irq_map_raw(ppnode, &lspec_be, 1, laddr, out_irq); | ||
91 | } | 40 | } |
92 | EXPORT_SYMBOL_GPL(of_irq_map_pci); | 41 | EXPORT_SYMBOL_GPL(of_pci_find_child_device); |
diff --git a/drivers/of/of_pci_irq.c b/drivers/of/of_pci_irq.c new file mode 100644 index 000000000000..ac1ec54e4fd5 --- /dev/null +++ b/drivers/of/of_pci_irq.c | |||
@@ -0,0 +1,92 @@ | |||
1 | #include <linux/kernel.h> | ||
2 | #include <linux/of_pci.h> | ||
3 | #include <linux/of_irq.h> | ||
4 | #include <asm/prom.h> | ||
5 | |||
6 | /** | ||
7 | * of_irq_map_pci - Resolve the interrupt for a PCI device | ||
8 | * @pdev: the device whose interrupt is to be resolved | ||
9 | * @out_irq: structure of_irq filled by this function | ||
10 | * | ||
11 | * This function resolves the PCI interrupt for a given PCI device. If a | ||
12 | * device-node exists for a given pci_dev, it will use normal OF tree | ||
13 | * walking. If not, it will implement standard swizzling and walk up the | ||
14 | * PCI tree until an device-node is found, at which point it will finish | ||
15 | * resolving using the OF tree walking. | ||
16 | */ | ||
17 | int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) | ||
18 | { | ||
19 | struct device_node *dn, *ppnode; | ||
20 | struct pci_dev *ppdev; | ||
21 | u32 lspec; | ||
22 | __be32 lspec_be; | ||
23 | __be32 laddr[3]; | ||
24 | u8 pin; | ||
25 | int rc; | ||
26 | |||
27 | /* Check if we have a device node, if yes, fallback to standard | ||
28 | * device tree parsing | ||
29 | */ | ||
30 | dn = pci_device_to_OF_node(pdev); | ||
31 | if (dn) { | ||
32 | rc = of_irq_map_one(dn, 0, out_irq); | ||
33 | if (!rc) | ||
34 | return rc; | ||
35 | } | ||
36 | |||
37 | /* Ok, we don't, time to have fun. Let's start by building up an | ||
38 | * interrupt spec. we assume #interrupt-cells is 1, which is standard | ||
39 | * for PCI. If you do different, then don't use that routine. | ||
40 | */ | ||
41 | rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin); | ||
42 | if (rc != 0) | ||
43 | return rc; | ||
44 | /* No pin, exit */ | ||
45 | if (pin == 0) | ||
46 | return -ENODEV; | ||
47 | |||
48 | /* Now we walk up the PCI tree */ | ||
49 | lspec = pin; | ||
50 | for (;;) { | ||
51 | /* Get the pci_dev of our parent */ | ||
52 | ppdev = pdev->bus->self; | ||
53 | |||
54 | /* Ouch, it's a host bridge... */ | ||
55 | if (ppdev == NULL) { | ||
56 | ppnode = pci_bus_to_OF_node(pdev->bus); | ||
57 | |||
58 | /* No node for host bridge ? give up */ | ||
59 | if (ppnode == NULL) | ||
60 | return -EINVAL; | ||
61 | } else { | ||
62 | /* We found a P2P bridge, check if it has a node */ | ||
63 | ppnode = pci_device_to_OF_node(ppdev); | ||
64 | } | ||
65 | |||
66 | /* Ok, we have found a parent with a device-node, hand over to | ||
67 | * the OF parsing code. | ||
68 | * We build a unit address from the linux device to be used for | ||
69 | * resolution. Note that we use the linux bus number which may | ||
70 | * not match your firmware bus numbering. | ||
71 | * Fortunately, in most cases, interrupt-map-mask doesn't | ||
72 | * include the bus number as part of the matching. | ||
73 | * You should still be careful about that though if you intend | ||
74 | * to rely on this function (you ship a firmware that doesn't | ||
75 | * create device nodes for all PCI devices). | ||
76 | */ | ||
77 | if (ppnode) | ||
78 | break; | ||
79 | |||
80 | /* We can only get here if we hit a P2P bridge with no node, | ||
81 | * let's do standard swizzling and try again | ||
82 | */ | ||
83 | lspec = pci_swizzle_interrupt_pin(pdev, lspec); | ||
84 | pdev = ppdev; | ||
85 | } | ||
86 | |||
87 | lspec_be = cpu_to_be32(lspec); | ||
88 | laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8)); | ||
89 | laddr[1] = laddr[2] = cpu_to_be32(0); | ||
90 | return of_irq_map_raw(ppnode, &lspec_be, 1, laddr, out_irq); | ||
91 | } | ||
92 | EXPORT_SYMBOL_GPL(of_irq_map_pci); | ||
diff --git a/drivers/of/platform.c b/drivers/of/platform.c index cfc6a7969401..ed5a6d3c26aa 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c | |||
@@ -13,6 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/amba/bus.h> | ||
16 | #include <linux/device.h> | 17 | #include <linux/device.h> |
17 | #include <linux/dma-mapping.h> | 18 | #include <linux/dma-mapping.h> |
18 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
@@ -22,6 +23,14 @@ | |||
22 | #include <linux/of_platform.h> | 23 | #include <linux/of_platform.h> |
23 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
24 | 25 | ||
26 | const struct of_device_id of_default_bus_match_table[] = { | ||
27 | { .compatible = "simple-bus", }, | ||
28 | #ifdef CONFIG_ARM_AMBA | ||
29 | { .compatible = "arm,amba-bus", }, | ||
30 | #endif /* CONFIG_ARM_AMBA */ | ||
31 | {} /* Empty terminated list */ | ||
32 | }; | ||
33 | |||
25 | static int of_dev_node_match(struct device *dev, void *data) | 34 | static int of_dev_node_match(struct device *dev, void *data) |
26 | { | 35 | { |
27 | return dev->of_node == data; | 36 | return dev->of_node == data; |
@@ -168,17 +177,20 @@ struct platform_device *of_device_alloc(struct device_node *np, | |||
168 | EXPORT_SYMBOL(of_device_alloc); | 177 | EXPORT_SYMBOL(of_device_alloc); |
169 | 178 | ||
170 | /** | 179 | /** |
171 | * of_platform_device_create - Alloc, initialize and register an of_device | 180 | * of_platform_device_create_pdata - Alloc, initialize and register an of_device |
172 | * @np: pointer to node to create device for | 181 | * @np: pointer to node to create device for |
173 | * @bus_id: name to assign device | 182 | * @bus_id: name to assign device |
183 | * @platform_data: pointer to populate platform_data pointer with | ||
174 | * @parent: Linux device model parent device. | 184 | * @parent: Linux device model parent device. |
175 | * | 185 | * |
176 | * Returns pointer to created platform device, or NULL if a device was not | 186 | * Returns pointer to created platform device, or NULL if a device was not |
177 | * registered. Unavailable devices will not get registered. | 187 | * registered. Unavailable devices will not get registered. |
178 | */ | 188 | */ |
179 | struct platform_device *of_platform_device_create(struct device_node *np, | 189 | struct platform_device *of_platform_device_create_pdata( |
180 | const char *bus_id, | 190 | struct device_node *np, |
181 | struct device *parent) | 191 | const char *bus_id, |
192 | void *platform_data, | ||
193 | struct device *parent) | ||
182 | { | 194 | { |
183 | struct platform_device *dev; | 195 | struct platform_device *dev; |
184 | 196 | ||
@@ -194,6 +206,7 @@ struct platform_device *of_platform_device_create(struct device_node *np, | |||
194 | #endif | 206 | #endif |
195 | dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); | 207 | dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); |
196 | dev->dev.bus = &platform_bus_type; | 208 | dev->dev.bus = &platform_bus_type; |
209 | dev->dev.platform_data = platform_data; | ||
197 | 210 | ||
198 | /* We do not fill the DMA ops for platform devices by default. | 211 | /* We do not fill the DMA ops for platform devices by default. |
199 | * This is currently the responsibility of the platform code | 212 | * This is currently the responsibility of the platform code |
@@ -207,8 +220,111 @@ struct platform_device *of_platform_device_create(struct device_node *np, | |||
207 | 220 | ||
208 | return dev; | 221 | return dev; |
209 | } | 222 | } |
223 | |||
224 | /** | ||
225 | * of_platform_device_create - Alloc, initialize and register an of_device | ||
226 | * @np: pointer to node to create device for | ||
227 | * @bus_id: name to assign device | ||
228 | * @parent: Linux device model parent device. | ||
229 | * | ||
230 | * Returns pointer to created platform device, or NULL if a device was not | ||
231 | * registered. Unavailable devices will not get registered. | ||
232 | */ | ||
233 | struct platform_device *of_platform_device_create(struct device_node *np, | ||
234 | const char *bus_id, | ||
235 | struct device *parent) | ||
236 | { | ||
237 | return of_platform_device_create_pdata(np, bus_id, NULL, parent); | ||
238 | } | ||
210 | EXPORT_SYMBOL(of_platform_device_create); | 239 | EXPORT_SYMBOL(of_platform_device_create); |
211 | 240 | ||
241 | #ifdef CONFIG_ARM_AMBA | ||
242 | static struct amba_device *of_amba_device_create(struct device_node *node, | ||
243 | const char *bus_id, | ||
244 | void *platform_data, | ||
245 | struct device *parent) | ||
246 | { | ||
247 | struct amba_device *dev; | ||
248 | const void *prop; | ||
249 | int i, ret; | ||
250 | |||
251 | pr_debug("Creating amba device %s\n", node->full_name); | ||
252 | |||
253 | if (!of_device_is_available(node)) | ||
254 | return NULL; | ||
255 | |||
256 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
257 | if (!dev) | ||
258 | return NULL; | ||
259 | |||
260 | /* setup generic device info */ | ||
261 | dev->dev.coherent_dma_mask = ~0; | ||
262 | dev->dev.of_node = of_node_get(node); | ||
263 | dev->dev.parent = parent; | ||
264 | dev->dev.platform_data = platform_data; | ||
265 | if (bus_id) | ||
266 | dev_set_name(&dev->dev, "%s", bus_id); | ||
267 | else | ||
268 | of_device_make_bus_id(&dev->dev); | ||
269 | |||
270 | /* setup amba-specific device info */ | ||
271 | dev->dma_mask = ~0; | ||
272 | |||
273 | /* Allow the HW Peripheral ID to be overridden */ | ||
274 | prop = of_get_property(node, "arm,primecell-periphid", NULL); | ||
275 | if (prop) | ||
276 | dev->periphid = of_read_ulong(prop, 1); | ||
277 | |||
278 | /* Decode the IRQs and address ranges */ | ||
279 | for (i = 0; i < AMBA_NR_IRQS; i++) | ||
280 | dev->irq[i] = irq_of_parse_and_map(node, i); | ||
281 | |||
282 | ret = of_address_to_resource(node, 0, &dev->res); | ||
283 | if (ret) | ||
284 | goto err_free; | ||
285 | |||
286 | ret = amba_device_register(dev, &iomem_resource); | ||
287 | if (ret) | ||
288 | goto err_free; | ||
289 | |||
290 | return dev; | ||
291 | |||
292 | err_free: | ||
293 | kfree(dev); | ||
294 | return NULL; | ||
295 | } | ||
296 | #else /* CONFIG_ARM_AMBA */ | ||
297 | static struct amba_device *of_amba_device_create(struct device_node *node, | ||
298 | const char *bus_id, | ||
299 | void *platform_data, | ||
300 | struct device *parent) | ||
301 | { | ||
302 | return NULL; | ||
303 | } | ||
304 | #endif /* CONFIG_ARM_AMBA */ | ||
305 | |||
306 | /** | ||
307 | * of_devname_lookup() - Given a device node, lookup the preferred Linux name | ||
308 | */ | ||
309 | static const struct of_dev_auxdata *of_dev_lookup(const struct of_dev_auxdata *lookup, | ||
310 | struct device_node *np) | ||
311 | { | ||
312 | struct resource res; | ||
313 | if (lookup) { | ||
314 | for(; lookup->name != NULL; lookup++) { | ||
315 | if (!of_device_is_compatible(np, lookup->compatible)) | ||
316 | continue; | ||
317 | if (of_address_to_resource(np, 0, &res)) | ||
318 | continue; | ||
319 | if (res.start != lookup->phys_addr) | ||
320 | continue; | ||
321 | pr_debug("%s: devname=%s\n", np->full_name, lookup->name); | ||
322 | return lookup; | ||
323 | } | ||
324 | } | ||
325 | return NULL; | ||
326 | } | ||
327 | |||
212 | /** | 328 | /** |
213 | * of_platform_bus_create() - Create a device for a node and its children. | 329 | * of_platform_bus_create() - Create a device for a node and its children. |
214 | * @bus: device node of the bus to instantiate | 330 | * @bus: device node of the bus to instantiate |
@@ -221,19 +337,41 @@ EXPORT_SYMBOL(of_platform_device_create); | |||
221 | */ | 337 | */ |
222 | static int of_platform_bus_create(struct device_node *bus, | 338 | static int of_platform_bus_create(struct device_node *bus, |
223 | const struct of_device_id *matches, | 339 | const struct of_device_id *matches, |
224 | struct device *parent) | 340 | const struct of_dev_auxdata *lookup, |
341 | struct device *parent, bool strict) | ||
225 | { | 342 | { |
343 | const struct of_dev_auxdata *auxdata; | ||
226 | struct device_node *child; | 344 | struct device_node *child; |
227 | struct platform_device *dev; | 345 | struct platform_device *dev; |
346 | const char *bus_id = NULL; | ||
347 | void *platform_data = NULL; | ||
228 | int rc = 0; | 348 | int rc = 0; |
229 | 349 | ||
230 | dev = of_platform_device_create(bus, NULL, parent); | 350 | /* Make sure it has a compatible property */ |
351 | if (strict && (!of_get_property(bus, "compatible", NULL))) { | ||
352 | pr_debug("%s() - skipping %s, no compatible prop\n", | ||
353 | __func__, bus->full_name); | ||
354 | return 0; | ||
355 | } | ||
356 | |||
357 | auxdata = of_dev_lookup(lookup, bus); | ||
358 | if (auxdata) { | ||
359 | bus_id = auxdata->name; | ||
360 | platform_data = auxdata->platform_data; | ||
361 | } | ||
362 | |||
363 | if (of_device_is_compatible(bus, "arm,primecell")) { | ||
364 | of_amba_device_create(bus, bus_id, platform_data, parent); | ||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | dev = of_platform_device_create_pdata(bus, bus_id, platform_data, parent); | ||
231 | if (!dev || !of_match_node(matches, bus)) | 369 | if (!dev || !of_match_node(matches, bus)) |
232 | return 0; | 370 | return 0; |
233 | 371 | ||
234 | for_each_child_of_node(bus, child) { | 372 | for_each_child_of_node(bus, child) { |
235 | pr_debug(" create child: %s\n", child->full_name); | 373 | pr_debug(" create child: %s\n", child->full_name); |
236 | rc = of_platform_bus_create(child, matches, &dev->dev); | 374 | rc = of_platform_bus_create(child, matches, lookup, &dev->dev, strict); |
237 | if (rc) { | 375 | if (rc) { |
238 | of_node_put(child); | 376 | of_node_put(child); |
239 | break; | 377 | break; |
@@ -267,11 +405,11 @@ int of_platform_bus_probe(struct device_node *root, | |||
267 | 405 | ||
268 | /* Do a self check of bus type, if there's a match, create children */ | 406 | /* Do a self check of bus type, if there's a match, create children */ |
269 | if (of_match_node(matches, root)) { | 407 | if (of_match_node(matches, root)) { |
270 | rc = of_platform_bus_create(root, matches, parent); | 408 | rc = of_platform_bus_create(root, matches, NULL, parent, false); |
271 | } else for_each_child_of_node(root, child) { | 409 | } else for_each_child_of_node(root, child) { |
272 | if (!of_match_node(matches, child)) | 410 | if (!of_match_node(matches, child)) |
273 | continue; | 411 | continue; |
274 | rc = of_platform_bus_create(child, matches, parent); | 412 | rc = of_platform_bus_create(child, matches, NULL, parent, false); |
275 | if (rc) | 413 | if (rc) |
276 | break; | 414 | break; |
277 | } | 415 | } |
@@ -280,4 +418,44 @@ int of_platform_bus_probe(struct device_node *root, | |||
280 | return rc; | 418 | return rc; |
281 | } | 419 | } |
282 | EXPORT_SYMBOL(of_platform_bus_probe); | 420 | EXPORT_SYMBOL(of_platform_bus_probe); |
421 | |||
422 | /** | ||
423 | * of_platform_populate() - Populate platform_devices from device tree data | ||
424 | * @root: parent of the first level to probe or NULL for the root of the tree | ||
425 | * @matches: match table, NULL to use the default | ||
426 | * @parent: parent to hook devices from, NULL for toplevel | ||
427 | * | ||
428 | * Similar to of_platform_bus_probe(), this function walks the device tree | ||
429 | * and creates devices from nodes. It differs in that it follows the modern | ||
430 | * convention of requiring all device nodes to have a 'compatible' property, | ||
431 | * and it is suitable for creating devices which are children of the root | ||
432 | * node (of_platform_bus_probe will only create children of the root which | ||
433 | * are selected by the @matches argument). | ||
434 | * | ||
435 | * New board support should be using this function instead of | ||
436 | * of_platform_bus_probe(). | ||
437 | * | ||
438 | * Returns 0 on success, < 0 on failure. | ||
439 | */ | ||
440 | int of_platform_populate(struct device_node *root, | ||
441 | const struct of_device_id *matches, | ||
442 | const struct of_dev_auxdata *lookup, | ||
443 | struct device *parent) | ||
444 | { | ||
445 | struct device_node *child; | ||
446 | int rc = 0; | ||
447 | |||
448 | root = root ? of_node_get(root) : of_find_node_by_path("/"); | ||
449 | if (!root) | ||
450 | return -EINVAL; | ||
451 | |||
452 | for_each_child_of_node(root, child) { | ||
453 | rc = of_platform_bus_create(child, matches, lookup, parent, true); | ||
454 | if (rc) | ||
455 | break; | ||
456 | } | ||
457 | |||
458 | of_node_put(root); | ||
459 | return rc; | ||
460 | } | ||
283 | #endif /* !CONFIG_SPARC */ | 461 | #endif /* !CONFIG_SPARC */ |