diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-05 18:57:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-05 18:57:35 -0400 |
commit | 03c0c29aff7e56b722eb6c47eace222b140d0377 (patch) | |
tree | 47267a19b523159cf36a050ef3c35f4dbdb33016 /arch/microblaze | |
parent | c60c6a96b7bb0f1f8bb635fdfcf5b592aaf062b4 (diff) | |
parent | 7fb8f881c54beb05dd4d2c947dada1c636581d87 (diff) |
Merge branch 'next-devicetree' of git://git.secretlab.ca/git/linux-2.6
* 'next-devicetree' of git://git.secretlab.ca/git/linux-2.6: (63 commits)
of/platform: Register of_platform_drivers with an "of:" prefix
of/address: Clean up function declarations
of/spi: call of_register_spi_devices() from spi core code
of: Provide default of_node_to_nid() implementation.
of/device: Make of_device_make_bus_id() usable by other code.
of/irq: Fix endian issues in parsing interrupt specifiers
of: Fix phandle endian issues
of/flattree: fix of_flat_dt_is_compatible() to match the full compatible string
of: remove of_default_bus_ids
of: make of_find_device_by_node generic
microblaze: remove references to of_device and to_of_device
sparc: remove references to of_device and to_of_device
powerpc: remove references to of_device and to_of_device
of/device: Replace of_device with platform_device in includes and core code
of/device: Protect against binding of_platform_drivers to non-OF devices
of: remove asm/of_device.h
of: remove asm/of_platform.h
of/platform: remove all of_bus_type and of_platform_bus_type references
of: Merge of_platform_bus_type with platform_bus_type
drivercore/of: Add OF style matching to platform bus
...
Fix up trivial conflicts in arch/microblaze/kernel/Makefile due to just
some obj-y removals by the devicetree branch, while the microblaze
updates added a new file.
Diffstat (limited to 'arch/microblaze')
-rw-r--r-- | arch/microblaze/Kconfig | 17 | ||||
-rw-r--r-- | arch/microblaze/include/asm/irq.h | 24 | ||||
-rw-r--r-- | arch/microblaze/include/asm/of_device.h | 44 | ||||
-rw-r--r-- | arch/microblaze/include/asm/of_platform.h | 54 | ||||
-rw-r--r-- | arch/microblaze/include/asm/page.h | 7 | ||||
-rw-r--r-- | arch/microblaze/include/asm/pci-bridge.h | 5 | ||||
-rw-r--r-- | arch/microblaze/include/asm/prom.h | 115 | ||||
-rw-r--r-- | arch/microblaze/include/asm/topology.h | 10 | ||||
-rw-r--r-- | arch/microblaze/kernel/Makefile | 4 | ||||
-rw-r--r-- | arch/microblaze/kernel/irq.c | 14 | ||||
-rw-r--r-- | arch/microblaze/kernel/of_device.c | 112 | ||||
-rw-r--r-- | arch/microblaze/kernel/of_platform.c | 200 | ||||
-rw-r--r-- | arch/microblaze/kernel/prom_parse.c | 877 | ||||
-rw-r--r-- | arch/microblaze/kernel/reset.c | 12 | ||||
-rw-r--r-- | arch/microblaze/kernel/setup.c | 6 |
15 files changed, 27 insertions, 1474 deletions
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index be3855250db6..9bd64b4b2b0c 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig | |||
@@ -18,6 +18,8 @@ config MICROBLAZE | |||
18 | select HAVE_DMA_ATTRS | 18 | select HAVE_DMA_ATTRS |
19 | select HAVE_DMA_API_DEBUG | 19 | select HAVE_DMA_API_DEBUG |
20 | select TRACING_SUPPORT | 20 | select TRACING_SUPPORT |
21 | select OF | ||
22 | select OF_FLATTREE | ||
21 | 23 | ||
22 | config SWAP | 24 | config SWAP |
23 | def_bool n | 25 | def_bool n |
@@ -76,9 +78,6 @@ config LOCKDEP_SUPPORT | |||
76 | config HAVE_LATENCYTOP_SUPPORT | 78 | config HAVE_LATENCYTOP_SUPPORT |
77 | def_bool y | 79 | def_bool y |
78 | 80 | ||
79 | config DTC | ||
80 | def_bool y | ||
81 | |||
82 | source "init/Kconfig" | 81 | source "init/Kconfig" |
83 | 82 | ||
84 | source "kernel/Kconfig.freezer" | 83 | source "kernel/Kconfig.freezer" |
@@ -125,18 +124,6 @@ config CMDLINE_FORCE | |||
125 | Set this to have arguments from the default kernel command string | 124 | Set this to have arguments from the default kernel command string |
126 | override those passed by the boot loader. | 125 | override those passed by the boot loader. |
127 | 126 | ||
128 | config OF | ||
129 | def_bool y | ||
130 | select OF_FLATTREE | ||
131 | |||
132 | config PROC_DEVICETREE | ||
133 | bool "Support for device tree in /proc" | ||
134 | depends on PROC_FS | ||
135 | help | ||
136 | This option adds a device-tree directory under /proc which contains | ||
137 | an image of the device tree that the kernel copies from Open | ||
138 | Firmware or other boot firmware. If unsure, say Y here. | ||
139 | |||
140 | endmenu | 127 | endmenu |
141 | 128 | ||
142 | menu "Advanced setup" | 129 | menu "Advanced setup" |
diff --git a/arch/microblaze/include/asm/irq.h b/arch/microblaze/include/asm/irq.h index 31a35c33df63..ec5583d6111c 100644 --- a/arch/microblaze/include/asm/irq.h +++ b/arch/microblaze/include/asm/irq.h | |||
@@ -27,17 +27,6 @@ extern unsigned int nr_irq; | |||
27 | struct pt_regs; | 27 | struct pt_regs; |
28 | extern void do_IRQ(struct pt_regs *regs); | 28 | extern void do_IRQ(struct pt_regs *regs); |
29 | 29 | ||
30 | /** | ||
31 | * irq_of_parse_and_map - Parse and Map an interrupt into linux virq space | ||
32 | * @device: Device node of the device whose interrupt is to be mapped | ||
33 | * @index: Index of the interrupt to map | ||
34 | * | ||
35 | * This function is a wrapper that chains of_irq_map_one() and | ||
36 | * irq_create_of_mapping() to make things easier to callers | ||
37 | */ | ||
38 | struct device_node; | ||
39 | extern unsigned int irq_of_parse_and_map(struct device_node *dev, int index); | ||
40 | |||
41 | /** FIXME - not implement | 30 | /** FIXME - not implement |
42 | * irq_dispose_mapping - Unmap an interrupt | 31 | * irq_dispose_mapping - Unmap an interrupt |
43 | * @virq: linux virq number of the interrupt to unmap | 32 | * @virq: linux virq number of the interrupt to unmap |
@@ -62,17 +51,4 @@ struct irq_host; | |||
62 | extern unsigned int irq_create_mapping(struct irq_host *host, | 51 | extern unsigned int irq_create_mapping(struct irq_host *host, |
63 | irq_hw_number_t hwirq); | 52 | irq_hw_number_t hwirq); |
64 | 53 | ||
65 | /** | ||
66 | * irq_create_of_mapping - Map a hardware interrupt into linux virq space | ||
67 | * @controller: Device node of the interrupt controller | ||
68 | * @inspec: Interrupt specifier from the device-tree | ||
69 | * @intsize: Size of the interrupt specifier from the device-tree | ||
70 | * | ||
71 | * This function is identical to irq_create_mapping except that it takes | ||
72 | * as input informations straight from the device-tree (typically the results | ||
73 | * of the of_irq_map_*() functions. | ||
74 | */ | ||
75 | extern unsigned int irq_create_of_mapping(struct device_node *controller, | ||
76 | u32 *intspec, unsigned int intsize); | ||
77 | |||
78 | #endif /* _ASM_MICROBLAZE_IRQ_H */ | 54 | #endif /* _ASM_MICROBLAZE_IRQ_H */ |
diff --git a/arch/microblaze/include/asm/of_device.h b/arch/microblaze/include/asm/of_device.h deleted file mode 100644 index 73cb98040982..000000000000 --- a/arch/microblaze/include/asm/of_device.h +++ /dev/null | |||
@@ -1,44 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu> | ||
3 | * | ||
4 | * based on PowerPC of_device.h | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file "COPYING" in the main directory of this archive | ||
8 | * for more details. | ||
9 | */ | ||
10 | |||
11 | #ifndef _ASM_MICROBLAZE_OF_DEVICE_H | ||
12 | #define _ASM_MICROBLAZE_OF_DEVICE_H | ||
13 | #ifdef __KERNEL__ | ||
14 | |||
15 | #include <linux/device.h> | ||
16 | #include <linux/of.h> | ||
17 | |||
18 | /* | ||
19 | * The of_device is a kind of "base class" that is a superset of | ||
20 | * struct device for use by devices attached to an OF node and | ||
21 | * probed using OF properties. | ||
22 | */ | ||
23 | struct of_device { | ||
24 | struct device dev; /* Generic device interface */ | ||
25 | struct pdev_archdata archdata; | ||
26 | }; | ||
27 | |||
28 | extern ssize_t of_device_get_modalias(struct of_device *ofdev, | ||
29 | char *str, ssize_t len); | ||
30 | |||
31 | extern struct of_device *of_device_alloc(struct device_node *np, | ||
32 | const char *bus_id, | ||
33 | struct device *parent); | ||
34 | |||
35 | extern int of_device_uevent(struct device *dev, | ||
36 | struct kobj_uevent_env *env); | ||
37 | |||
38 | extern void of_device_make_bus_id(struct of_device *dev); | ||
39 | |||
40 | /* This is just here during the transition */ | ||
41 | #include <linux/of_device.h> | ||
42 | |||
43 | #endif /* __KERNEL__ */ | ||
44 | #endif /* _ASM_MICROBLAZE_OF_DEVICE_H */ | ||
diff --git a/arch/microblaze/include/asm/of_platform.h b/arch/microblaze/include/asm/of_platform.h deleted file mode 100644 index 37491276c6ca..000000000000 --- a/arch/microblaze/include/asm/of_platform.h +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. | ||
3 | * <benh@kernel.crashing.org> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version | ||
8 | * 2 of the License, or (at your option) any later version. | ||
9 | */ | ||
10 | |||
11 | #ifndef _ASM_MICROBLAZE_OF_PLATFORM_H | ||
12 | #define _ASM_MICROBLAZE_OF_PLATFORM_H | ||
13 | |||
14 | /* This is just here during the transition */ | ||
15 | #include <linux/of_platform.h> | ||
16 | |||
17 | /* | ||
18 | * The list of OF IDs below is used for matching bus types in the | ||
19 | * system whose devices are to be exposed as of_platform_devices. | ||
20 | * | ||
21 | * This is the default list valid for most platforms. This file provides | ||
22 | * functions who can take an explicit list if necessary though | ||
23 | * | ||
24 | * The search is always performed recursively looking for children of | ||
25 | * the provided device_node and recursively if such a children matches | ||
26 | * a bus type in the list | ||
27 | */ | ||
28 | |||
29 | static const struct of_device_id of_default_bus_ids[] = { | ||
30 | { .type = "soc", }, | ||
31 | { .compatible = "soc", }, | ||
32 | { .type = "plb5", }, | ||
33 | { .type = "plb4", }, | ||
34 | { .type = "opb", }, | ||
35 | { .type = "simple", }, | ||
36 | {}, | ||
37 | }; | ||
38 | |||
39 | /* Platform devices and busses creation */ | ||
40 | extern struct of_device *of_platform_device_create(struct device_node *np, | ||
41 | const char *bus_id, | ||
42 | struct device *parent); | ||
43 | /* pseudo "matches" value to not do deep probe */ | ||
44 | #define OF_NO_DEEP_PROBE ((struct of_device_id *)-1) | ||
45 | |||
46 | extern int of_platform_bus_probe(struct device_node *root, | ||
47 | const struct of_device_id *matches, | ||
48 | struct device *parent); | ||
49 | |||
50 | extern struct of_device *of_find_device_by_phandle(phandle ph); | ||
51 | |||
52 | extern void of_instantiate_rtc(void); | ||
53 | |||
54 | #endif /* _ASM_MICROBLAZE_OF_PLATFORM_H */ | ||
diff --git a/arch/microblaze/include/asm/page.h b/arch/microblaze/include/asm/page.h index c12c6dfafd9f..4f268faa0126 100644 --- a/arch/microblaze/include/asm/page.h +++ b/arch/microblaze/include/asm/page.h | |||
@@ -47,13 +47,6 @@ | |||
47 | #define PAGE_UP(addr) (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1))) | 47 | #define PAGE_UP(addr) (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1))) |
48 | #define PAGE_DOWN(addr) ((addr)&(~((PAGE_SIZE)-1))) | 48 | #define PAGE_DOWN(addr) ((addr)&(~((PAGE_SIZE)-1))) |
49 | 49 | ||
50 | /* align addr on a size boundary - adjust address up/down if needed */ | ||
51 | #define _ALIGN_UP(addr, size) (((addr)+((size)-1))&(~((size)-1))) | ||
52 | #define _ALIGN_DOWN(addr, size) ((addr)&(~((size)-1))) | ||
53 | |||
54 | /* align addr on a size boundary - adjust address up if needed */ | ||
55 | #define _ALIGN(addr, size) _ALIGN_UP(addr, size) | ||
56 | |||
57 | #ifndef CONFIG_MMU | 50 | #ifndef CONFIG_MMU |
58 | /* | 51 | /* |
59 | * PAGE_OFFSET -- the first address of the first page of memory. When not | 52 | * PAGE_OFFSET -- the first address of the first page of memory. When not |
diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h index 0c77cda9f5d8..0c68764ab547 100644 --- a/arch/microblaze/include/asm/pci-bridge.h +++ b/arch/microblaze/include/asm/pci-bridge.h | |||
@@ -172,13 +172,8 @@ static inline int pci_has_flag(int flag) | |||
172 | 172 | ||
173 | extern struct list_head hose_list; | 173 | extern struct list_head hose_list; |
174 | 174 | ||
175 | extern unsigned long pci_address_to_pio(phys_addr_t address); | ||
176 | extern int pcibios_vaddr_is_ioport(void __iomem *address); | 175 | extern int pcibios_vaddr_is_ioport(void __iomem *address); |
177 | #else | 176 | #else |
178 | static inline unsigned long pci_address_to_pio(phys_addr_t address) | ||
179 | { | ||
180 | return (unsigned long)-1; | ||
181 | } | ||
182 | static inline int pcibios_vaddr_is_ioport(void __iomem *address) | 177 | static inline int pcibios_vaddr_is_ioport(void __iomem *address) |
183 | { | 178 | { |
184 | return 0; | 179 | return 0; |
diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index e7d67a329bd7..101fa098f62a 100644 --- a/arch/microblaze/include/asm/prom.h +++ b/arch/microblaze/include/asm/prom.h | |||
@@ -20,9 +20,6 @@ | |||
20 | #ifndef __ASSEMBLY__ | 20 | #ifndef __ASSEMBLY__ |
21 | 21 | ||
22 | #include <linux/types.h> | 22 | #include <linux/types.h> |
23 | #include <linux/of_fdt.h> | ||
24 | #include <linux/proc_fs.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <asm/irq.h> | 23 | #include <asm/irq.h> |
27 | #include <asm/atomic.h> | 24 | #include <asm/atomic.h> |
28 | 25 | ||
@@ -50,29 +47,10 @@ extern void pci_create_OF_bus_map(void); | |||
50 | * OF address retreival & translation | 47 | * OF address retreival & translation |
51 | */ | 48 | */ |
52 | 49 | ||
53 | /* Translate an OF address block into a CPU physical address | 50 | #ifdef CONFIG_PCI |
54 | */ | 51 | extern unsigned long pci_address_to_pio(phys_addr_t address); |
55 | extern u64 of_translate_address(struct device_node *np, const u32 *addr); | 52 | #define pci_address_to_pio pci_address_to_pio |
56 | 53 | #endif /* CONFIG_PCI */ | |
57 | /* Extract an address from a device, returns the region size and | ||
58 | * the address space flags too. The PCI version uses a BAR number | ||
59 | * instead of an absolute index | ||
60 | */ | ||
61 | extern const u32 *of_get_address(struct device_node *dev, int index, | ||
62 | u64 *size, unsigned int *flags); | ||
63 | extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no, | ||
64 | u64 *size, unsigned int *flags); | ||
65 | |||
66 | /* Get an address as a resource. Note that if your address is | ||
67 | * a PIO address, the conversion will fail if the physical address | ||
68 | * can't be internally converted to an IO token with | ||
69 | * pci_address_to_pio(), that is because it's either called to early | ||
70 | * or it can't be matched to any host bridge IO space | ||
71 | */ | ||
72 | extern int of_address_to_resource(struct device_node *dev, int index, | ||
73 | struct resource *r); | ||
74 | extern int of_pci_address_to_resource(struct device_node *dev, int bar, | ||
75 | struct resource *r); | ||
76 | 54 | ||
77 | /* Parse the ibm,dma-window property of an OF node into the busno, phys and | 55 | /* Parse the ibm,dma-window property of an OF node into the busno, phys and |
78 | * size parameters. | 56 | * size parameters. |
@@ -88,69 +66,6 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); | |||
88 | /* Get the MAC address */ | 66 | /* Get the MAC address */ |
89 | extern const void *of_get_mac_address(struct device_node *np); | 67 | extern const void *of_get_mac_address(struct device_node *np); |
90 | 68 | ||
91 | /* | ||
92 | * OF interrupt mapping | ||
93 | */ | ||
94 | |||
95 | /* This structure is returned when an interrupt is mapped. The controller | ||
96 | * field needs to be put() after use | ||
97 | */ | ||
98 | |||
99 | #define OF_MAX_IRQ_SPEC 4 /* We handle specifiers of at most 4 cells */ | ||
100 | |||
101 | struct of_irq { | ||
102 | struct device_node *controller; /* Interrupt controller node */ | ||
103 | u32 size; /* Specifier size */ | ||
104 | u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */ | ||
105 | }; | ||
106 | |||
107 | /** | ||
108 | * of_irq_map_init - Initialize the irq remapper | ||
109 | * @flags: flags defining workarounds to enable | ||
110 | * | ||
111 | * Some machines have bugs in the device-tree which require certain workarounds | ||
112 | * to be applied. Call this before any interrupt mapping attempts to enable | ||
113 | * those workarounds. | ||
114 | */ | ||
115 | #define OF_IMAP_OLDWORLD_MAC 0x00000001 | ||
116 | #define OF_IMAP_NO_PHANDLE 0x00000002 | ||
117 | |||
118 | extern void of_irq_map_init(unsigned int flags); | ||
119 | |||
120 | /** | ||
121 | * of_irq_map_raw - Low level interrupt tree parsing | ||
122 | * @parent: the device interrupt parent | ||
123 | * @intspec: interrupt specifier ("interrupts" property of the device) | ||
124 | * @ointsize: size of the passed in interrupt specifier | ||
125 | * @addr: address specifier (start of "reg" property of the device) | ||
126 | * @out_irq: structure of_irq filled by this function | ||
127 | * | ||
128 | * Returns 0 on success and a negative number on error | ||
129 | * | ||
130 | * This function is a low-level interrupt tree walking function. It | ||
131 | * can be used to do a partial walk with synthetized reg and interrupts | ||
132 | * properties, for example when resolving PCI interrupts when no device | ||
133 | * node exist for the parent. | ||
134 | * | ||
135 | */ | ||
136 | |||
137 | extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec, | ||
138 | u32 ointsize, const u32 *addr, | ||
139 | struct of_irq *out_irq); | ||
140 | |||
141 | /** | ||
142 | * of_irq_map_one - Resolve an interrupt for a device | ||
143 | * @device: the device whose interrupt is to be resolved | ||
144 | * @index: index of the interrupt to resolve | ||
145 | * @out_irq: structure of_irq filled by this function | ||
146 | * | ||
147 | * This function resolves an interrupt, walking the tree, for a given | ||
148 | * device-tree node. It's the high level pendant to of_irq_map_raw(). | ||
149 | * It also implements the workarounds for OldWolrd Macs. | ||
150 | */ | ||
151 | extern int of_irq_map_one(struct device_node *device, int index, | ||
152 | struct of_irq *out_irq); | ||
153 | |||
154 | /** | 69 | /** |
155 | * of_irq_map_pci - Resolve the interrupt for a PCI device | 70 | * of_irq_map_pci - Resolve the interrupt for a PCI device |
156 | * @pdev: the device whose interrupt is to be resolved | 71 | * @pdev: the device whose interrupt is to be resolved |
@@ -163,20 +78,18 @@ extern int of_irq_map_one(struct device_node *device, int index, | |||
163 | * resolving using the OF tree walking. | 78 | * resolving using the OF tree walking. |
164 | */ | 79 | */ |
165 | struct pci_dev; | 80 | struct pci_dev; |
81 | struct of_irq; | ||
166 | extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); | 82 | extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); |
167 | 83 | ||
168 | extern int of_irq_to_resource(struct device_node *dev, int index, | ||
169 | struct resource *r); | ||
170 | |||
171 | /** | ||
172 | * of_iomap - Maps the memory mapped IO for a given device_node | ||
173 | * @device: the device whose io range will be mapped | ||
174 | * @index: index of the io range | ||
175 | * | ||
176 | * Returns a pointer to the mapped memory | ||
177 | */ | ||
178 | extern void __iomem *of_iomap(struct device_node *device, int index); | ||
179 | |||
180 | #endif /* __ASSEMBLY__ */ | 84 | #endif /* __ASSEMBLY__ */ |
181 | #endif /* __KERNEL__ */ | 85 | #endif /* __KERNEL__ */ |
86 | |||
87 | /* These includes are put at the bottom because they may contain things | ||
88 | * that are overridden by this file. Ideally they shouldn't be included | ||
89 | * by this file, but there are a bunch of .c files that currently depend | ||
90 | * on it. Eventually they will be cleaned up. */ | ||
91 | #include <linux/of_fdt.h> | ||
92 | #include <linux/of_irq.h> | ||
93 | #include <linux/platform_device.h> | ||
94 | |||
182 | #endif /* _ASM_MICROBLAZE_PROM_H */ | 95 | #endif /* _ASM_MICROBLAZE_PROM_H */ |
diff --git a/arch/microblaze/include/asm/topology.h b/arch/microblaze/include/asm/topology.h index 96bcea5a9920..5428f333a02c 100644 --- a/arch/microblaze/include/asm/topology.h +++ b/arch/microblaze/include/asm/topology.h | |||
@@ -1,11 +1 @@ | |||
1 | #include <asm-generic/topology.h> | #include <asm-generic/topology.h> | |
2 | |||
3 | #ifndef _ASM_MICROBLAZE_TOPOLOGY_H | ||
4 | #define _ASM_MICROBLAZE_TOPOLOGY_H | ||
5 | |||
6 | struct device_node; | ||
7 | static inline int of_node_to_nid(struct device_node *device) | ||
8 | { | ||
9 | return 0; | ||
10 | } | ||
11 | #endif /* _ASM_MICROBLAZE_TOPOLOGY_H */ | ||
diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile index 5eecc9f1fbd9..f0cb5c26c81c 100644 --- a/arch/microblaze/kernel/Makefile +++ b/arch/microblaze/kernel/Makefile | |||
@@ -15,8 +15,8 @@ endif | |||
15 | extra-y := head.o vmlinux.lds | 15 | extra-y := head.o vmlinux.lds |
16 | 16 | ||
17 | obj-y += dma.o exceptions.o \ | 17 | obj-y += dma.o exceptions.o \ |
18 | hw_exception_handler.o init_task.o intc.o irq.o of_device.o \ | 18 | hw_exception_handler.o init_task.o intc.o irq.o \ |
19 | of_platform.o process.o prom.o prom_parse.o ptrace.o \ | 19 | process.o prom.o prom_parse.o ptrace.o \ |
20 | reset.o setup.o signal.o sys_microblaze.o timer.o traps.o unwind.o | 20 | reset.o setup.o signal.o sys_microblaze.o timer.o traps.o unwind.o |
21 | 21 | ||
22 | obj-y += cpu/ | 22 | obj-y += cpu/ |
diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c index 598f1fd61c89..a9345fb4906a 100644 --- a/arch/microblaze/kernel/irq.c +++ b/arch/microblaze/kernel/irq.c | |||
@@ -17,20 +17,10 @@ | |||
17 | #include <linux/seq_file.h> | 17 | #include <linux/seq_file.h> |
18 | #include <linux/kernel_stat.h> | 18 | #include <linux/kernel_stat.h> |
19 | #include <linux/irq.h> | 19 | #include <linux/irq.h> |
20 | #include <linux/of_irq.h> | ||
20 | 21 | ||
21 | #include <asm/prom.h> | 22 | #include <asm/prom.h> |
22 | 23 | ||
23 | unsigned int irq_of_parse_and_map(struct device_node *dev, int index) | ||
24 | { | ||
25 | struct of_irq oirq; | ||
26 | |||
27 | if (of_irq_map_one(dev, index, &oirq)) | ||
28 | return NO_IRQ; | ||
29 | |||
30 | return oirq.specifier[0]; | ||
31 | } | ||
32 | EXPORT_SYMBOL_GPL(irq_of_parse_and_map); | ||
33 | |||
34 | static u32 concurrent_irq; | 24 | static u32 concurrent_irq; |
35 | 25 | ||
36 | void __irq_entry do_IRQ(struct pt_regs *regs) | 26 | void __irq_entry do_IRQ(struct pt_regs *regs) |
@@ -106,7 +96,7 @@ unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq) | |||
106 | EXPORT_SYMBOL_GPL(irq_create_mapping); | 96 | EXPORT_SYMBOL_GPL(irq_create_mapping); |
107 | 97 | ||
108 | unsigned int irq_create_of_mapping(struct device_node *controller, | 98 | unsigned int irq_create_of_mapping(struct device_node *controller, |
109 | u32 *intspec, unsigned int intsize) | 99 | const u32 *intspec, unsigned int intsize) |
110 | { | 100 | { |
111 | return intspec[0]; | 101 | return intspec[0]; |
112 | } | 102 | } |
diff --git a/arch/microblaze/kernel/of_device.c b/arch/microblaze/kernel/of_device.c deleted file mode 100644 index b372787886ed..000000000000 --- a/arch/microblaze/kernel/of_device.c +++ /dev/null | |||
@@ -1,112 +0,0 @@ | |||
1 | #include <linux/string.h> | ||
2 | #include <linux/kernel.h> | ||
3 | #include <linux/of.h> | ||
4 | #include <linux/init.h> | ||
5 | #include <linux/module.h> | ||
6 | #include <linux/mod_devicetable.h> | ||
7 | #include <linux/slab.h> | ||
8 | #include <linux/of_device.h> | ||
9 | |||
10 | #include <linux/errno.h> | ||
11 | |||
12 | void of_device_make_bus_id(struct of_device *dev) | ||
13 | { | ||
14 | static atomic_t bus_no_reg_magic; | ||
15 | struct device_node *node = dev->dev.of_node; | ||
16 | const u32 *reg; | ||
17 | u64 addr; | ||
18 | int magic; | ||
19 | |||
20 | /* | ||
21 | * For MMIO, get the physical address | ||
22 | */ | ||
23 | reg = of_get_property(node, "reg", NULL); | ||
24 | if (reg) { | ||
25 | addr = of_translate_address(node, reg); | ||
26 | if (addr != OF_BAD_ADDR) { | ||
27 | dev_set_name(&dev->dev, "%llx.%s", | ||
28 | (unsigned long long)addr, node->name); | ||
29 | return; | ||
30 | } | ||
31 | } | ||
32 | |||
33 | /* | ||
34 | * No BusID, use the node name and add a globally incremented | ||
35 | * counter (and pray...) | ||
36 | */ | ||
37 | magic = atomic_add_return(1, &bus_no_reg_magic); | ||
38 | dev_set_name(&dev->dev, "%s.%d", node->name, magic - 1); | ||
39 | } | ||
40 | EXPORT_SYMBOL(of_device_make_bus_id); | ||
41 | |||
42 | struct of_device *of_device_alloc(struct device_node *np, | ||
43 | const char *bus_id, | ||
44 | struct device *parent) | ||
45 | { | ||
46 | struct of_device *dev; | ||
47 | |||
48 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
49 | if (!dev) | ||
50 | return NULL; | ||
51 | |||
52 | dev->dev.of_node = of_node_get(np); | ||
53 | dev->dev.dma_mask = &dev->archdata.dma_mask; | ||
54 | dev->dev.parent = parent; | ||
55 | dev->dev.release = of_release_dev; | ||
56 | |||
57 | if (bus_id) | ||
58 | dev_set_name(&dev->dev, bus_id); | ||
59 | else | ||
60 | of_device_make_bus_id(dev); | ||
61 | |||
62 | return dev; | ||
63 | } | ||
64 | EXPORT_SYMBOL(of_device_alloc); | ||
65 | |||
66 | int of_device_uevent(struct device *dev, struct kobj_uevent_env *env) | ||
67 | { | ||
68 | struct of_device *ofdev; | ||
69 | const char *compat; | ||
70 | int seen = 0, cplen, sl; | ||
71 | |||
72 | if (!dev) | ||
73 | return -ENODEV; | ||
74 | |||
75 | ofdev = to_of_device(dev); | ||
76 | |||
77 | if (add_uevent_var(env, "OF_NAME=%s", ofdev->dev.of_node->name)) | ||
78 | return -ENOMEM; | ||
79 | |||
80 | if (add_uevent_var(env, "OF_TYPE=%s", ofdev->dev.of_node->type)) | ||
81 | return -ENOMEM; | ||
82 | |||
83 | /* Since the compatible field can contain pretty much anything | ||
84 | * it's not really legal to split it out with commas. We split it | ||
85 | * up using a number of environment variables instead. */ | ||
86 | |||
87 | compat = of_get_property(ofdev->dev.of_node, "compatible", &cplen); | ||
88 | while (compat && *compat && cplen > 0) { | ||
89 | if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat)) | ||
90 | return -ENOMEM; | ||
91 | |||
92 | sl = strlen(compat) + 1; | ||
93 | compat += sl; | ||
94 | cplen -= sl; | ||
95 | seen++; | ||
96 | } | ||
97 | |||
98 | if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen)) | ||
99 | return -ENOMEM; | ||
100 | |||
101 | /* modalias is trickier, we add it in 2 steps */ | ||
102 | if (add_uevent_var(env, "MODALIAS=")) | ||
103 | return -ENOMEM; | ||
104 | sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1], | ||
105 | sizeof(env->buf) - env->buflen); | ||
106 | if (sl >= (sizeof(env->buf) - env->buflen)) | ||
107 | return -ENOMEM; | ||
108 | env->buflen += sl; | ||
109 | |||
110 | return 0; | ||
111 | } | ||
112 | EXPORT_SYMBOL(of_device_uevent); | ||
diff --git a/arch/microblaze/kernel/of_platform.c b/arch/microblaze/kernel/of_platform.c deleted file mode 100644 index ccf6f4257f4b..000000000000 --- a/arch/microblaze/kernel/of_platform.c +++ /dev/null | |||
@@ -1,200 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. | ||
3 | * <benh@kernel.crashing.org> | ||
4 | * and Arnd Bergmann, IBM Corp. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #undef DEBUG | ||
14 | |||
15 | #include <linux/string.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/mod_devicetable.h> | ||
20 | #include <linux/pci.h> | ||
21 | #include <linux/of.h> | ||
22 | #include <linux/of_device.h> | ||
23 | #include <linux/of_platform.h> | ||
24 | |||
25 | #include <linux/errno.h> | ||
26 | #include <linux/topology.h> | ||
27 | #include <asm/atomic.h> | ||
28 | |||
29 | struct bus_type of_platform_bus_type = { | ||
30 | .uevent = of_device_uevent, | ||
31 | }; | ||
32 | EXPORT_SYMBOL(of_platform_bus_type); | ||
33 | |||
34 | static int __init of_bus_driver_init(void) | ||
35 | { | ||
36 | return of_bus_type_init(&of_platform_bus_type, "of_platform"); | ||
37 | } | ||
38 | postcore_initcall(of_bus_driver_init); | ||
39 | |||
40 | struct of_device *of_platform_device_create(struct device_node *np, | ||
41 | const char *bus_id, | ||
42 | struct device *parent) | ||
43 | { | ||
44 | struct of_device *dev; | ||
45 | |||
46 | dev = of_device_alloc(np, bus_id, parent); | ||
47 | if (!dev) | ||
48 | return NULL; | ||
49 | |||
50 | dev->archdata.dma_mask = 0xffffffffUL; | ||
51 | dev->dev.bus = &of_platform_bus_type; | ||
52 | |||
53 | /* We do not fill the DMA ops for platform devices by default. | ||
54 | * This is currently the responsibility of the platform code | ||
55 | * to do such, possibly using a device notifier | ||
56 | */ | ||
57 | |||
58 | if (of_device_register(dev) != 0) { | ||
59 | of_device_free(dev); | ||
60 | return NULL; | ||
61 | } | ||
62 | |||
63 | return dev; | ||
64 | } | ||
65 | EXPORT_SYMBOL(of_platform_device_create); | ||
66 | |||
67 | /** | ||
68 | * of_platform_bus_create - Create an OF device for a bus node and all its | ||
69 | * children. Optionally recursively instanciate matching busses. | ||
70 | * @bus: device node of the bus to instanciate | ||
71 | * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to | ||
72 | * disallow recursive creation of child busses | ||
73 | */ | ||
74 | static int of_platform_bus_create(const struct device_node *bus, | ||
75 | const struct of_device_id *matches, | ||
76 | struct device *parent) | ||
77 | { | ||
78 | struct device_node *child; | ||
79 | struct of_device *dev; | ||
80 | int rc = 0; | ||
81 | |||
82 | for_each_child_of_node(bus, child) { | ||
83 | pr_debug(" create child: %s\n", child->full_name); | ||
84 | dev = of_platform_device_create(child, NULL, parent); | ||
85 | if (dev == NULL) | ||
86 | rc = -ENOMEM; | ||
87 | else if (!of_match_node(matches, child)) | ||
88 | continue; | ||
89 | if (rc == 0) { | ||
90 | pr_debug(" and sub busses\n"); | ||
91 | rc = of_platform_bus_create(child, matches, &dev->dev); | ||
92 | } | ||
93 | if (rc) { | ||
94 | of_node_put(child); | ||
95 | break; | ||
96 | } | ||
97 | } | ||
98 | return rc; | ||
99 | } | ||
100 | |||
101 | |||
102 | /** | ||
103 | * of_platform_bus_probe - Probe the device-tree for platform busses | ||
104 | * @root: parent of the first level to probe or NULL for the root of the tree | ||
105 | * @matches: match table, NULL to use the default | ||
106 | * @parent: parent to hook devices from, NULL for toplevel | ||
107 | * | ||
108 | * Note that children of the provided root are not instanciated as devices | ||
109 | * unless the specified root itself matches the bus list and is not NULL. | ||
110 | */ | ||
111 | |||
112 | int of_platform_bus_probe(struct device_node *root, | ||
113 | const struct of_device_id *matches, | ||
114 | struct device *parent) | ||
115 | { | ||
116 | struct device_node *child; | ||
117 | struct of_device *dev; | ||
118 | int rc = 0; | ||
119 | |||
120 | if (matches == NULL) | ||
121 | matches = of_default_bus_ids; | ||
122 | if (matches == OF_NO_DEEP_PROBE) | ||
123 | return -EINVAL; | ||
124 | if (root == NULL) | ||
125 | root = of_find_node_by_path("/"); | ||
126 | else | ||
127 | of_node_get(root); | ||
128 | |||
129 | pr_debug("of_platform_bus_probe()\n"); | ||
130 | pr_debug(" starting at: %s\n", root->full_name); | ||
131 | |||
132 | /* Do a self check of bus type, if there's a match, create | ||
133 | * children | ||
134 | */ | ||
135 | if (of_match_node(matches, root)) { | ||
136 | pr_debug(" root match, create all sub devices\n"); | ||
137 | dev = of_platform_device_create(root, NULL, parent); | ||
138 | if (dev == NULL) { | ||
139 | rc = -ENOMEM; | ||
140 | goto bail; | ||
141 | } | ||
142 | pr_debug(" create all sub busses\n"); | ||
143 | rc = of_platform_bus_create(root, matches, &dev->dev); | ||
144 | goto bail; | ||
145 | } | ||
146 | for_each_child_of_node(root, child) { | ||
147 | if (!of_match_node(matches, child)) | ||
148 | continue; | ||
149 | |||
150 | pr_debug(" match: %s\n", child->full_name); | ||
151 | dev = of_platform_device_create(child, NULL, parent); | ||
152 | if (dev == NULL) | ||
153 | rc = -ENOMEM; | ||
154 | else | ||
155 | rc = of_platform_bus_create(child, matches, &dev->dev); | ||
156 | if (rc) { | ||
157 | of_node_put(child); | ||
158 | break; | ||
159 | } | ||
160 | } | ||
161 | bail: | ||
162 | of_node_put(root); | ||
163 | return rc; | ||
164 | } | ||
165 | EXPORT_SYMBOL(of_platform_bus_probe); | ||
166 | |||
167 | static int of_dev_node_match(struct device *dev, void *data) | ||
168 | { | ||
169 | return to_of_device(dev)->dev.of_node == data; | ||
170 | } | ||
171 | |||
172 | struct of_device *of_find_device_by_node(struct device_node *np) | ||
173 | { | ||
174 | struct device *dev; | ||
175 | |||
176 | dev = bus_find_device(&of_platform_bus_type, | ||
177 | NULL, np, of_dev_node_match); | ||
178 | if (dev) | ||
179 | return to_of_device(dev); | ||
180 | return NULL; | ||
181 | } | ||
182 | EXPORT_SYMBOL(of_find_device_by_node); | ||
183 | |||
184 | static int of_dev_phandle_match(struct device *dev, void *data) | ||
185 | { | ||
186 | phandle *ph = data; | ||
187 | return to_of_device(dev)->dev.of_node->phandle == *ph; | ||
188 | } | ||
189 | |||
190 | struct of_device *of_find_device_by_phandle(phandle ph) | ||
191 | { | ||
192 | struct device *dev; | ||
193 | |||
194 | dev = bus_find_device(&of_platform_bus_type, | ||
195 | NULL, &ph, of_dev_phandle_match); | ||
196 | if (dev) | ||
197 | return to_of_device(dev); | ||
198 | return NULL; | ||
199 | } | ||
200 | EXPORT_SYMBOL(of_find_device_by_phandle); | ||
diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c index bf7e6c27e318..d33ba17601fa 100644 --- a/arch/microblaze/kernel/prom_parse.c +++ b/arch/microblaze/kernel/prom_parse.c | |||
@@ -6,219 +6,11 @@ | |||
6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
7 | #include <linux/ioport.h> | 7 | #include <linux/ioport.h> |
8 | #include <linux/etherdevice.h> | 8 | #include <linux/etherdevice.h> |
9 | #include <linux/of_address.h> | ||
9 | #include <asm/prom.h> | 10 | #include <asm/prom.h> |
10 | #include <asm/pci-bridge.h> | 11 | #include <asm/pci-bridge.h> |
11 | 12 | ||
12 | #define PRu64 "%llx" | ||
13 | |||
14 | /* Max address size we deal with */ | ||
15 | #define OF_MAX_ADDR_CELLS 4 | ||
16 | #define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \ | ||
17 | (ns) > 0) | ||
18 | |||
19 | static struct of_bus *of_match_bus(struct device_node *np); | ||
20 | static int __of_address_to_resource(struct device_node *dev, | ||
21 | const u32 *addrp, u64 size, unsigned int flags, | ||
22 | struct resource *r); | ||
23 | |||
24 | /* Debug utility */ | ||
25 | #ifdef DEBUG | ||
26 | static void of_dump_addr(const char *s, const u32 *addr, int na) | ||
27 | { | ||
28 | printk(KERN_INFO "%s", s); | ||
29 | while (na--) | ||
30 | printk(KERN_INFO " %08x", *(addr++)); | ||
31 | printk(KERN_INFO "\n"); | ||
32 | } | ||
33 | #else | ||
34 | static void of_dump_addr(const char *s, const u32 *addr, int na) { } | ||
35 | #endif | ||
36 | |||
37 | /* Callbacks for bus specific translators */ | ||
38 | struct of_bus { | ||
39 | const char *name; | ||
40 | const char *addresses; | ||
41 | int (*match)(struct device_node *parent); | ||
42 | void (*count_cells)(struct device_node *child, | ||
43 | int *addrc, int *sizec); | ||
44 | u64 (*map)(u32 *addr, const u32 *range, | ||
45 | int na, int ns, int pna); | ||
46 | int (*translate)(u32 *addr, u64 offset, int na); | ||
47 | unsigned int (*get_flags)(const u32 *addr); | ||
48 | }; | ||
49 | |||
50 | /* | ||
51 | * Default translator (generic bus) | ||
52 | */ | ||
53 | |||
54 | static void of_bus_default_count_cells(struct device_node *dev, | ||
55 | int *addrc, int *sizec) | ||
56 | { | ||
57 | if (addrc) | ||
58 | *addrc = of_n_addr_cells(dev); | ||
59 | if (sizec) | ||
60 | *sizec = of_n_size_cells(dev); | ||
61 | } | ||
62 | |||
63 | static u64 of_bus_default_map(u32 *addr, const u32 *range, | ||
64 | int na, int ns, int pna) | ||
65 | { | ||
66 | u64 cp, s, da; | ||
67 | |||
68 | cp = of_read_number(range, na); | ||
69 | s = of_read_number(range + na + pna, ns); | ||
70 | da = of_read_number(addr, na); | ||
71 | |||
72 | pr_debug("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n", | ||
73 | cp, s, da); | ||
74 | |||
75 | if (da < cp || da >= (cp + s)) | ||
76 | return OF_BAD_ADDR; | ||
77 | return da - cp; | ||
78 | } | ||
79 | |||
80 | static int of_bus_default_translate(u32 *addr, u64 offset, int na) | ||
81 | { | ||
82 | u64 a = of_read_number(addr, na); | ||
83 | memset(addr, 0, na * 4); | ||
84 | a += offset; | ||
85 | if (na > 1) | ||
86 | addr[na - 2] = a >> 32; | ||
87 | addr[na - 1] = a & 0xffffffffu; | ||
88 | |||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static unsigned int of_bus_default_get_flags(const u32 *addr) | ||
93 | { | ||
94 | return IORESOURCE_MEM; | ||
95 | } | ||
96 | |||
97 | #ifdef CONFIG_PCI | 13 | #ifdef CONFIG_PCI |
98 | /* | ||
99 | * PCI bus specific translator | ||
100 | */ | ||
101 | |||
102 | static int of_bus_pci_match(struct device_node *np) | ||
103 | { | ||
104 | /* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */ | ||
105 | return !strcmp(np->type, "pci") || !strcmp(np->type, "vci"); | ||
106 | } | ||
107 | |||
108 | static void of_bus_pci_count_cells(struct device_node *np, | ||
109 | int *addrc, int *sizec) | ||
110 | { | ||
111 | if (addrc) | ||
112 | *addrc = 3; | ||
113 | if (sizec) | ||
114 | *sizec = 2; | ||
115 | } | ||
116 | |||
117 | static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna) | ||
118 | { | ||
119 | u64 cp, s, da; | ||
120 | |||
121 | /* Check address type match */ | ||
122 | if ((addr[0] ^ range[0]) & 0x03000000) | ||
123 | return OF_BAD_ADDR; | ||
124 | |||
125 | /* Read address values, skipping high cell */ | ||
126 | cp = of_read_number(range + 1, na - 1); | ||
127 | s = of_read_number(range + na + pna, ns); | ||
128 | da = of_read_number(addr + 1, na - 1); | ||
129 | |||
130 | pr_debug("OF: PCI map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da); | ||
131 | |||
132 | if (da < cp || da >= (cp + s)) | ||
133 | return OF_BAD_ADDR; | ||
134 | return da - cp; | ||
135 | } | ||
136 | |||
137 | static int of_bus_pci_translate(u32 *addr, u64 offset, int na) | ||
138 | { | ||
139 | return of_bus_default_translate(addr + 1, offset, na - 1); | ||
140 | } | ||
141 | |||
142 | static unsigned int of_bus_pci_get_flags(const u32 *addr) | ||
143 | { | ||
144 | unsigned int flags = 0; | ||
145 | u32 w = addr[0]; | ||
146 | |||
147 | switch ((w >> 24) & 0x03) { | ||
148 | case 0x01: | ||
149 | flags |= IORESOURCE_IO; | ||
150 | break; | ||
151 | case 0x02: /* 32 bits */ | ||
152 | case 0x03: /* 64 bits */ | ||
153 | flags |= IORESOURCE_MEM; | ||
154 | break; | ||
155 | } | ||
156 | if (w & 0x40000000) | ||
157 | flags |= IORESOURCE_PREFETCH; | ||
158 | return flags; | ||
159 | } | ||
160 | |||
161 | const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, | ||
162 | unsigned int *flags) | ||
163 | { | ||
164 | const u32 *prop; | ||
165 | unsigned int psize; | ||
166 | struct device_node *parent; | ||
167 | struct of_bus *bus; | ||
168 | int onesize, i, na, ns; | ||
169 | |||
170 | /* Get parent & match bus type */ | ||
171 | parent = of_get_parent(dev); | ||
172 | if (parent == NULL) | ||
173 | return NULL; | ||
174 | bus = of_match_bus(parent); | ||
175 | if (strcmp(bus->name, "pci")) { | ||
176 | of_node_put(parent); | ||
177 | return NULL; | ||
178 | } | ||
179 | bus->count_cells(dev, &na, &ns); | ||
180 | of_node_put(parent); | ||
181 | if (!OF_CHECK_COUNTS(na, ns)) | ||
182 | return NULL; | ||
183 | |||
184 | /* Get "reg" or "assigned-addresses" property */ | ||
185 | prop = of_get_property(dev, bus->addresses, &psize); | ||
186 | if (prop == NULL) | ||
187 | return NULL; | ||
188 | psize /= 4; | ||
189 | |||
190 | onesize = na + ns; | ||
191 | for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) | ||
192 | if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) { | ||
193 | if (size) | ||
194 | *size = of_read_number(prop + na, ns); | ||
195 | if (flags) | ||
196 | *flags = bus->get_flags(prop); | ||
197 | return prop; | ||
198 | } | ||
199 | return NULL; | ||
200 | } | ||
201 | EXPORT_SYMBOL(of_get_pci_address); | ||
202 | |||
203 | int of_pci_address_to_resource(struct device_node *dev, int bar, | ||
204 | struct resource *r) | ||
205 | { | ||
206 | const u32 *addrp; | ||
207 | u64 size; | ||
208 | unsigned int flags; | ||
209 | |||
210 | addrp = of_get_pci_address(dev, bar, &size, &flags); | ||
211 | if (addrp == NULL) | ||
212 | return -EINVAL; | ||
213 | return __of_address_to_resource(dev, addrp, size, flags, r); | ||
214 | } | ||
215 | EXPORT_SYMBOL_GPL(of_pci_address_to_resource); | ||
216 | |||
217 | static u8 of_irq_pci_swizzle(u8 slot, u8 pin) | ||
218 | { | ||
219 | return (((pin - 1) + slot) % 4) + 1; | ||
220 | } | ||
221 | |||
222 | int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) | 14 | int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) |
223 | { | 15 | { |
224 | struct device_node *dn, *ppnode; | 16 | struct device_node *dn, *ppnode; |
@@ -293,331 +85,6 @@ int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) | |||
293 | EXPORT_SYMBOL_GPL(of_irq_map_pci); | 85 | EXPORT_SYMBOL_GPL(of_irq_map_pci); |
294 | #endif /* CONFIG_PCI */ | 86 | #endif /* CONFIG_PCI */ |
295 | 87 | ||
296 | /* | ||
297 | * ISA bus specific translator | ||
298 | */ | ||
299 | |||
300 | static int of_bus_isa_match(struct device_node *np) | ||
301 | { | ||
302 | return !strcmp(np->name, "isa"); | ||
303 | } | ||
304 | |||
305 | static void of_bus_isa_count_cells(struct device_node *child, | ||
306 | int *addrc, int *sizec) | ||
307 | { | ||
308 | if (addrc) | ||
309 | *addrc = 2; | ||
310 | if (sizec) | ||
311 | *sizec = 1; | ||
312 | } | ||
313 | |||
314 | static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna) | ||
315 | { | ||
316 | u64 cp, s, da; | ||
317 | |||
318 | /* Check address type match */ | ||
319 | if ((addr[0] ^ range[0]) & 0x00000001) | ||
320 | return OF_BAD_ADDR; | ||
321 | |||
322 | /* Read address values, skipping high cell */ | ||
323 | cp = of_read_number(range + 1, na - 1); | ||
324 | s = of_read_number(range + na + pna, ns); | ||
325 | da = of_read_number(addr + 1, na - 1); | ||
326 | |||
327 | pr_debug("OF: ISA map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da); | ||
328 | |||
329 | if (da < cp || da >= (cp + s)) | ||
330 | return OF_BAD_ADDR; | ||
331 | return da - cp; | ||
332 | } | ||
333 | |||
334 | static int of_bus_isa_translate(u32 *addr, u64 offset, int na) | ||
335 | { | ||
336 | return of_bus_default_translate(addr + 1, offset, na - 1); | ||
337 | } | ||
338 | |||
339 | static unsigned int of_bus_isa_get_flags(const u32 *addr) | ||
340 | { | ||
341 | unsigned int flags = 0; | ||
342 | u32 w = addr[0]; | ||
343 | |||
344 | if (w & 1) | ||
345 | flags |= IORESOURCE_IO; | ||
346 | else | ||
347 | flags |= IORESOURCE_MEM; | ||
348 | return flags; | ||
349 | } | ||
350 | |||
351 | /* | ||
352 | * Array of bus specific translators | ||
353 | */ | ||
354 | |||
355 | static struct of_bus of_busses[] = { | ||
356 | #ifdef CONFIG_PCI | ||
357 | /* PCI */ | ||
358 | { | ||
359 | .name = "pci", | ||
360 | .addresses = "assigned-addresses", | ||
361 | .match = of_bus_pci_match, | ||
362 | .count_cells = of_bus_pci_count_cells, | ||
363 | .map = of_bus_pci_map, | ||
364 | .translate = of_bus_pci_translate, | ||
365 | .get_flags = of_bus_pci_get_flags, | ||
366 | }, | ||
367 | #endif /* CONFIG_PCI */ | ||
368 | /* ISA */ | ||
369 | { | ||
370 | .name = "isa", | ||
371 | .addresses = "reg", | ||
372 | .match = of_bus_isa_match, | ||
373 | .count_cells = of_bus_isa_count_cells, | ||
374 | .map = of_bus_isa_map, | ||
375 | .translate = of_bus_isa_translate, | ||
376 | .get_flags = of_bus_isa_get_flags, | ||
377 | }, | ||
378 | /* Default */ | ||
379 | { | ||
380 | .name = "default", | ||
381 | .addresses = "reg", | ||
382 | .match = NULL, | ||
383 | .count_cells = of_bus_default_count_cells, | ||
384 | .map = of_bus_default_map, | ||
385 | .translate = of_bus_default_translate, | ||
386 | .get_flags = of_bus_default_get_flags, | ||
387 | }, | ||
388 | }; | ||
389 | |||
390 | static struct of_bus *of_match_bus(struct device_node *np) | ||
391 | { | ||
392 | int i; | ||
393 | |||
394 | for (i = 0; i < ARRAY_SIZE(of_busses); i++) | ||
395 | if (!of_busses[i].match || of_busses[i].match(np)) | ||
396 | return &of_busses[i]; | ||
397 | BUG(); | ||
398 | return NULL; | ||
399 | } | ||
400 | |||
401 | static int of_translate_one(struct device_node *parent, struct of_bus *bus, | ||
402 | struct of_bus *pbus, u32 *addr, | ||
403 | int na, int ns, int pna) | ||
404 | { | ||
405 | const u32 *ranges; | ||
406 | unsigned int rlen; | ||
407 | int rone; | ||
408 | u64 offset = OF_BAD_ADDR; | ||
409 | |||
410 | /* Normally, an absence of a "ranges" property means we are | ||
411 | * crossing a non-translatable boundary, and thus the addresses | ||
412 | * below the current not cannot be converted to CPU physical ones. | ||
413 | * Unfortunately, while this is very clear in the spec, it's not | ||
414 | * what Apple understood, and they do have things like /uni-n or | ||
415 | * /ht nodes with no "ranges" property and a lot of perfectly | ||
416 | * useable mapped devices below them. Thus we treat the absence of | ||
417 | * "ranges" as equivalent to an empty "ranges" property which means | ||
418 | * a 1:1 translation at that level. It's up to the caller not to try | ||
419 | * to translate addresses that aren't supposed to be translated in | ||
420 | * the first place. --BenH. | ||
421 | */ | ||
422 | ranges = of_get_property(parent, "ranges", (int *) &rlen); | ||
423 | if (ranges == NULL || rlen == 0) { | ||
424 | offset = of_read_number(addr, na); | ||
425 | memset(addr, 0, pna * 4); | ||
426 | pr_debug("OF: no ranges, 1:1 translation\n"); | ||
427 | goto finish; | ||
428 | } | ||
429 | |||
430 | pr_debug("OF: walking ranges...\n"); | ||
431 | |||
432 | /* Now walk through the ranges */ | ||
433 | rlen /= 4; | ||
434 | rone = na + pna + ns; | ||
435 | for (; rlen >= rone; rlen -= rone, ranges += rone) { | ||
436 | offset = bus->map(addr, ranges, na, ns, pna); | ||
437 | if (offset != OF_BAD_ADDR) | ||
438 | break; | ||
439 | } | ||
440 | if (offset == OF_BAD_ADDR) { | ||
441 | pr_debug("OF: not found !\n"); | ||
442 | return 1; | ||
443 | } | ||
444 | memcpy(addr, ranges + na, 4 * pna); | ||
445 | |||
446 | finish: | ||
447 | of_dump_addr("OF: parent translation for:", addr, pna); | ||
448 | pr_debug("OF: with offset: "PRu64"\n", offset); | ||
449 | |||
450 | /* Translate it into parent bus space */ | ||
451 | return pbus->translate(addr, offset, pna); | ||
452 | } | ||
453 | |||
454 | /* | ||
455 | * Translate an address from the device-tree into a CPU physical address, | ||
456 | * this walks up the tree and applies the various bus mappings on the | ||
457 | * way. | ||
458 | * | ||
459 | * Note: We consider that crossing any level with #size-cells == 0 to mean | ||
460 | * that translation is impossible (that is we are not dealing with a value | ||
461 | * that can be mapped to a cpu physical address). This is not really specified | ||
462 | * that way, but this is traditionally the way IBM at least do things | ||
463 | */ | ||
464 | u64 of_translate_address(struct device_node *dev, const u32 *in_addr) | ||
465 | { | ||
466 | struct device_node *parent = NULL; | ||
467 | struct of_bus *bus, *pbus; | ||
468 | u32 addr[OF_MAX_ADDR_CELLS]; | ||
469 | int na, ns, pna, pns; | ||
470 | u64 result = OF_BAD_ADDR; | ||
471 | |||
472 | pr_debug("OF: ** translation for device %s **\n", dev->full_name); | ||
473 | |||
474 | /* Increase refcount at current level */ | ||
475 | of_node_get(dev); | ||
476 | |||
477 | /* Get parent & match bus type */ | ||
478 | parent = of_get_parent(dev); | ||
479 | if (parent == NULL) | ||
480 | goto bail; | ||
481 | bus = of_match_bus(parent); | ||
482 | |||
483 | /* Cound address cells & copy address locally */ | ||
484 | bus->count_cells(dev, &na, &ns); | ||
485 | if (!OF_CHECK_COUNTS(na, ns)) { | ||
486 | printk(KERN_ERR "prom_parse: Bad cell count for %s\n", | ||
487 | dev->full_name); | ||
488 | goto bail; | ||
489 | } | ||
490 | memcpy(addr, in_addr, na * 4); | ||
491 | |||
492 | pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n", | ||
493 | bus->name, na, ns, parent->full_name); | ||
494 | of_dump_addr("OF: translating address:", addr, na); | ||
495 | |||
496 | /* Translate */ | ||
497 | for (;;) { | ||
498 | /* Switch to parent bus */ | ||
499 | of_node_put(dev); | ||
500 | dev = parent; | ||
501 | parent = of_get_parent(dev); | ||
502 | |||
503 | /* If root, we have finished */ | ||
504 | if (parent == NULL) { | ||
505 | pr_debug("OF: reached root node\n"); | ||
506 | result = of_read_number(addr, na); | ||
507 | break; | ||
508 | } | ||
509 | |||
510 | /* Get new parent bus and counts */ | ||
511 | pbus = of_match_bus(parent); | ||
512 | pbus->count_cells(dev, &pna, &pns); | ||
513 | if (!OF_CHECK_COUNTS(pna, pns)) { | ||
514 | printk(KERN_ERR "prom_parse: Bad cell count for %s\n", | ||
515 | dev->full_name); | ||
516 | break; | ||
517 | } | ||
518 | |||
519 | pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n", | ||
520 | pbus->name, pna, pns, parent->full_name); | ||
521 | |||
522 | /* Apply bus translation */ | ||
523 | if (of_translate_one(dev, bus, pbus, addr, na, ns, pna)) | ||
524 | break; | ||
525 | |||
526 | /* Complete the move up one level */ | ||
527 | na = pna; | ||
528 | ns = pns; | ||
529 | bus = pbus; | ||
530 | |||
531 | of_dump_addr("OF: one level translation:", addr, na); | ||
532 | } | ||
533 | bail: | ||
534 | of_node_put(parent); | ||
535 | of_node_put(dev); | ||
536 | |||
537 | return result; | ||
538 | } | ||
539 | EXPORT_SYMBOL(of_translate_address); | ||
540 | |||
541 | const u32 *of_get_address(struct device_node *dev, int index, u64 *size, | ||
542 | unsigned int *flags) | ||
543 | { | ||
544 | const u32 *prop; | ||
545 | unsigned int psize; | ||
546 | struct device_node *parent; | ||
547 | struct of_bus *bus; | ||
548 | int onesize, i, na, ns; | ||
549 | |||
550 | /* Get parent & match bus type */ | ||
551 | parent = of_get_parent(dev); | ||
552 | if (parent == NULL) | ||
553 | return NULL; | ||
554 | bus = of_match_bus(parent); | ||
555 | bus->count_cells(dev, &na, &ns); | ||
556 | of_node_put(parent); | ||
557 | if (!OF_CHECK_COUNTS(na, ns)) | ||
558 | return NULL; | ||
559 | |||
560 | /* Get "reg" or "assigned-addresses" property */ | ||
561 | prop = of_get_property(dev, bus->addresses, (int *) &psize); | ||
562 | if (prop == NULL) | ||
563 | return NULL; | ||
564 | psize /= 4; | ||
565 | |||
566 | onesize = na + ns; | ||
567 | for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) | ||
568 | if (i == index) { | ||
569 | if (size) | ||
570 | *size = of_read_number(prop + na, ns); | ||
571 | if (flags) | ||
572 | *flags = bus->get_flags(prop); | ||
573 | return prop; | ||
574 | } | ||
575 | return NULL; | ||
576 | } | ||
577 | EXPORT_SYMBOL(of_get_address); | ||
578 | |||
579 | static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, | ||
580 | u64 size, unsigned int flags, | ||
581 | struct resource *r) | ||
582 | { | ||
583 | u64 taddr; | ||
584 | |||
585 | if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0) | ||
586 | return -EINVAL; | ||
587 | taddr = of_translate_address(dev, addrp); | ||
588 | if (taddr == OF_BAD_ADDR) | ||
589 | return -EINVAL; | ||
590 | memset(r, 0, sizeof(struct resource)); | ||
591 | if (flags & IORESOURCE_IO) { | ||
592 | unsigned long port; | ||
593 | port = -1; /* pci_address_to_pio(taddr); */ | ||
594 | if (port == (unsigned long)-1) | ||
595 | return -EINVAL; | ||
596 | r->start = port; | ||
597 | r->end = port + size - 1; | ||
598 | } else { | ||
599 | r->start = taddr; | ||
600 | r->end = taddr + size - 1; | ||
601 | } | ||
602 | r->flags = flags; | ||
603 | r->name = dev->name; | ||
604 | return 0; | ||
605 | } | ||
606 | |||
607 | int of_address_to_resource(struct device_node *dev, int index, | ||
608 | struct resource *r) | ||
609 | { | ||
610 | const u32 *addrp; | ||
611 | u64 size; | ||
612 | unsigned int flags; | ||
613 | |||
614 | addrp = of_get_address(dev, index, &size, &flags); | ||
615 | if (addrp == NULL) | ||
616 | return -EINVAL; | ||
617 | return __of_address_to_resource(dev, addrp, size, flags, r); | ||
618 | } | ||
619 | EXPORT_SYMBOL_GPL(of_address_to_resource); | ||
620 | |||
621 | void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, | 88 | void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, |
622 | unsigned long *busno, unsigned long *phys, unsigned long *size) | 89 | unsigned long *busno, unsigned long *phys, unsigned long *size) |
623 | { | 90 | { |
@@ -644,308 +111,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, | |||
644 | *size = of_read_number(dma_window, cells); | 111 | *size = of_read_number(dma_window, cells); |
645 | } | 112 | } |
646 | 113 | ||
647 | /* | ||
648 | * Interrupt remapper | ||
649 | */ | ||
650 | |||
651 | static unsigned int of_irq_workarounds; | ||
652 | static struct device_node *of_irq_dflt_pic; | ||
653 | |||
654 | static struct device_node *of_irq_find_parent(struct device_node *child) | ||
655 | { | ||
656 | struct device_node *p; | ||
657 | const phandle *parp; | ||
658 | |||
659 | if (!of_node_get(child)) | ||
660 | return NULL; | ||
661 | |||
662 | do { | ||
663 | parp = of_get_property(child, "interrupt-parent", NULL); | ||
664 | if (parp == NULL) | ||
665 | p = of_get_parent(child); | ||
666 | else { | ||
667 | if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) | ||
668 | p = of_node_get(of_irq_dflt_pic); | ||
669 | else | ||
670 | p = of_find_node_by_phandle(*parp); | ||
671 | } | ||
672 | of_node_put(child); | ||
673 | child = p; | ||
674 | } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL); | ||
675 | |||
676 | return p; | ||
677 | } | ||
678 | |||
679 | /* This doesn't need to be called if you don't have any special workaround | ||
680 | * flags to pass | ||
681 | */ | ||
682 | void of_irq_map_init(unsigned int flags) | ||
683 | { | ||
684 | of_irq_workarounds = flags; | ||
685 | |||
686 | /* OldWorld, don't bother looking at other things */ | ||
687 | if (flags & OF_IMAP_OLDWORLD_MAC) | ||
688 | return; | ||
689 | |||
690 | /* If we don't have phandles, let's try to locate a default interrupt | ||
691 | * controller (happens when booting with BootX). We do a first match | ||
692 | * here, hopefully, that only ever happens on machines with one | ||
693 | * controller. | ||
694 | */ | ||
695 | if (flags & OF_IMAP_NO_PHANDLE) { | ||
696 | struct device_node *np; | ||
697 | |||
698 | for (np = NULL; (np = of_find_all_nodes(np)) != NULL;) { | ||
699 | if (of_get_property(np, "interrupt-controller", NULL) | ||
700 | == NULL) | ||
701 | continue; | ||
702 | /* Skip /chosen/interrupt-controller */ | ||
703 | if (strcmp(np->name, "chosen") == 0) | ||
704 | continue; | ||
705 | /* It seems like at least one person on this planet | ||
706 | * wants to use BootX on a machine with an AppleKiwi | ||
707 | * controller which happens to pretend to be an | ||
708 | * interrupt controller too. | ||
709 | */ | ||
710 | if (strcmp(np->name, "AppleKiwi") == 0) | ||
711 | continue; | ||
712 | /* I think we found one ! */ | ||
713 | of_irq_dflt_pic = np; | ||
714 | break; | ||
715 | } | ||
716 | } | ||
717 | |||
718 | } | ||
719 | |||
720 | int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, | ||
721 | const u32 *addr, struct of_irq *out_irq) | ||
722 | { | ||
723 | struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; | ||
724 | const u32 *tmp, *imap, *imask; | ||
725 | u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; | ||
726 | int imaplen, match, i; | ||
727 | |||
728 | pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...]," | ||
729 | "ointsize=%d\n", | ||
730 | parent->full_name, intspec[0], intspec[1], ointsize); | ||
731 | |||
732 | ipar = of_node_get(parent); | ||
733 | |||
734 | /* First get the #interrupt-cells property of the current cursor | ||
735 | * that tells us how to interpret the passed-in intspec. If there | ||
736 | * is none, we are nice and just walk up the tree | ||
737 | */ | ||
738 | do { | ||
739 | tmp = of_get_property(ipar, "#interrupt-cells", NULL); | ||
740 | if (tmp != NULL) { | ||
741 | intsize = *tmp; | ||
742 | break; | ||
743 | } | ||
744 | tnode = ipar; | ||
745 | ipar = of_irq_find_parent(ipar); | ||
746 | of_node_put(tnode); | ||
747 | } while (ipar); | ||
748 | if (ipar == NULL) { | ||
749 | pr_debug(" -> no parent found !\n"); | ||
750 | goto fail; | ||
751 | } | ||
752 | |||
753 | pr_debug("of_irq_map_raw: ipar=%s, size=%d\n", | ||
754 | ipar->full_name, intsize); | ||
755 | |||
756 | if (ointsize != intsize) | ||
757 | return -EINVAL; | ||
758 | |||
759 | /* Look for this #address-cells. We have to implement the old linux | ||
760 | * trick of looking for the parent here as some device-trees rely on it | ||
761 | */ | ||
762 | old = of_node_get(ipar); | ||
763 | do { | ||
764 | tmp = of_get_property(old, "#address-cells", NULL); | ||
765 | tnode = of_get_parent(old); | ||
766 | of_node_put(old); | ||
767 | old = tnode; | ||
768 | } while (old && tmp == NULL); | ||
769 | of_node_put(old); | ||
770 | old = NULL; | ||
771 | addrsize = (tmp == NULL) ? 2 : *tmp; | ||
772 | |||
773 | pr_debug(" -> addrsize=%d\n", addrsize); | ||
774 | |||
775 | /* Now start the actual "proper" walk of the interrupt tree */ | ||
776 | while (ipar != NULL) { | ||
777 | /* Now check if cursor is an interrupt-controller and if it is | ||
778 | * then we are done | ||
779 | */ | ||
780 | if (of_get_property(ipar, "interrupt-controller", NULL) != | ||
781 | NULL) { | ||
782 | pr_debug(" -> got it !\n"); | ||
783 | memcpy(out_irq->specifier, intspec, | ||
784 | intsize * sizeof(u32)); | ||
785 | out_irq->size = intsize; | ||
786 | out_irq->controller = ipar; | ||
787 | of_node_put(old); | ||
788 | return 0; | ||
789 | } | ||
790 | |||
791 | /* Now look for an interrupt-map */ | ||
792 | imap = of_get_property(ipar, "interrupt-map", &imaplen); | ||
793 | /* No interrupt map, check for an interrupt parent */ | ||
794 | if (imap == NULL) { | ||
795 | pr_debug(" -> no map, getting parent\n"); | ||
796 | newpar = of_irq_find_parent(ipar); | ||
797 | goto skiplevel; | ||
798 | } | ||
799 | imaplen /= sizeof(u32); | ||
800 | |||
801 | /* Look for a mask */ | ||
802 | imask = of_get_property(ipar, "interrupt-map-mask", NULL); | ||
803 | |||
804 | /* If we were passed no "reg" property and we attempt to parse | ||
805 | * an interrupt-map, then #address-cells must be 0. | ||
806 | * Fail if it's not. | ||
807 | */ | ||
808 | if (addr == NULL && addrsize != 0) { | ||
809 | pr_debug(" -> no reg passed in when needed !\n"); | ||
810 | goto fail; | ||
811 | } | ||
812 | |||
813 | /* Parse interrupt-map */ | ||
814 | match = 0; | ||
815 | while (imaplen > (addrsize + intsize + 1) && !match) { | ||
816 | /* Compare specifiers */ | ||
817 | match = 1; | ||
818 | for (i = 0; i < addrsize && match; ++i) { | ||
819 | u32 mask = imask ? imask[i] : 0xffffffffu; | ||
820 | match = ((addr[i] ^ imap[i]) & mask) == 0; | ||
821 | } | ||
822 | for (; i < (addrsize + intsize) && match; ++i) { | ||
823 | u32 mask = imask ? imask[i] : 0xffffffffu; | ||
824 | match = | ||
825 | ((intspec[i-addrsize] ^ imap[i]) | ||
826 | & mask) == 0; | ||
827 | } | ||
828 | imap += addrsize + intsize; | ||
829 | imaplen -= addrsize + intsize; | ||
830 | |||
831 | pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen); | ||
832 | |||
833 | /* Get the interrupt parent */ | ||
834 | if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) | ||
835 | newpar = of_node_get(of_irq_dflt_pic); | ||
836 | else | ||
837 | newpar = | ||
838 | of_find_node_by_phandle((phandle)*imap); | ||
839 | imap++; | ||
840 | --imaplen; | ||
841 | |||
842 | /* Check if not found */ | ||
843 | if (newpar == NULL) { | ||
844 | pr_debug(" -> imap parent not found !\n"); | ||
845 | goto fail; | ||
846 | } | ||
847 | |||
848 | /* Get #interrupt-cells and #address-cells of new | ||
849 | * parent | ||
850 | */ | ||
851 | tmp = of_get_property(newpar, "#interrupt-cells", NULL); | ||
852 | if (tmp == NULL) { | ||
853 | pr_debug(" -> parent lacks " | ||
854 | "#interrupt-cells!\n"); | ||
855 | goto fail; | ||
856 | } | ||
857 | newintsize = *tmp; | ||
858 | tmp = of_get_property(newpar, "#address-cells", NULL); | ||
859 | newaddrsize = (tmp == NULL) ? 0 : *tmp; | ||
860 | |||
861 | pr_debug(" -> newintsize=%d, newaddrsize=%d\n", | ||
862 | newintsize, newaddrsize); | ||
863 | |||
864 | /* Check for malformed properties */ | ||
865 | if (imaplen < (newaddrsize + newintsize)) | ||
866 | goto fail; | ||
867 | |||
868 | imap += newaddrsize + newintsize; | ||
869 | imaplen -= newaddrsize + newintsize; | ||
870 | |||
871 | pr_debug(" -> imaplen=%d\n", imaplen); | ||
872 | } | ||
873 | if (!match) | ||
874 | goto fail; | ||
875 | |||
876 | of_node_put(old); | ||
877 | old = of_node_get(newpar); | ||
878 | addrsize = newaddrsize; | ||
879 | intsize = newintsize; | ||
880 | intspec = imap - intsize; | ||
881 | addr = intspec - addrsize; | ||
882 | |||
883 | skiplevel: | ||
884 | /* Iterate again with new parent */ | ||
885 | pr_debug(" -> new parent: %s\n", | ||
886 | newpar ? newpar->full_name : "<>"); | ||
887 | of_node_put(ipar); | ||
888 | ipar = newpar; | ||
889 | newpar = NULL; | ||
890 | } | ||
891 | fail: | ||
892 | of_node_put(ipar); | ||
893 | of_node_put(old); | ||
894 | of_node_put(newpar); | ||
895 | |||
896 | return -EINVAL; | ||
897 | } | ||
898 | EXPORT_SYMBOL_GPL(of_irq_map_raw); | ||
899 | |||
900 | int of_irq_map_one(struct device_node *device, | ||
901 | int index, struct of_irq *out_irq) | ||
902 | { | ||
903 | struct device_node *p; | ||
904 | const u32 *intspec, *tmp, *addr; | ||
905 | u32 intsize, intlen; | ||
906 | int res; | ||
907 | |||
908 | pr_debug("of_irq_map_one: dev=%s, index=%d\n", | ||
909 | device->full_name, index); | ||
910 | |||
911 | /* Get the interrupts property */ | ||
912 | intspec = of_get_property(device, "interrupts", (int *) &intlen); | ||
913 | if (intspec == NULL) | ||
914 | return -EINVAL; | ||
915 | intlen /= sizeof(u32); | ||
916 | |||
917 | pr_debug(" intspec=%d intlen=%d\n", *intspec, intlen); | ||
918 | |||
919 | /* Get the reg property (if any) */ | ||
920 | addr = of_get_property(device, "reg", NULL); | ||
921 | |||
922 | /* Look for the interrupt parent. */ | ||
923 | p = of_irq_find_parent(device); | ||
924 | if (p == NULL) | ||
925 | return -EINVAL; | ||
926 | |||
927 | /* Get size of interrupt specifier */ | ||
928 | tmp = of_get_property(p, "#interrupt-cells", NULL); | ||
929 | if (tmp == NULL) { | ||
930 | of_node_put(p); | ||
931 | return -EINVAL; | ||
932 | } | ||
933 | intsize = *tmp; | ||
934 | |||
935 | pr_debug(" intsize=%d intlen=%d\n", intsize, intlen); | ||
936 | |||
937 | /* Check index */ | ||
938 | if ((index + 1) * intsize > intlen) | ||
939 | return -EINVAL; | ||
940 | |||
941 | /* Get new specifier and map it */ | ||
942 | res = of_irq_map_raw(p, intspec + index * intsize, intsize, | ||
943 | addr, out_irq); | ||
944 | of_node_put(p); | ||
945 | return res; | ||
946 | } | ||
947 | EXPORT_SYMBOL_GPL(of_irq_map_one); | ||
948 | |||
949 | /** | 114 | /** |
950 | * Search the device tree for the best MAC address to use. 'mac-address' is | 115 | * Search the device tree for the best MAC address to use. 'mac-address' is |
951 | * checked first, because that is supposed to contain to "most recent" MAC | 116 | * checked first, because that is supposed to contain to "most recent" MAC |
@@ -983,43 +148,3 @@ const void *of_get_mac_address(struct device_node *np) | |||
983 | return NULL; | 148 | return NULL; |
984 | } | 149 | } |
985 | EXPORT_SYMBOL(of_get_mac_address); | 150 | EXPORT_SYMBOL(of_get_mac_address); |
986 | |||
987 | int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) | ||
988 | { | ||
989 | struct of_irq out_irq; | ||
990 | int irq; | ||
991 | int res; | ||
992 | |||
993 | res = of_irq_map_one(dev, index, &out_irq); | ||
994 | |||
995 | /* Get irq for the device */ | ||
996 | if (res) { | ||
997 | pr_debug("IRQ not found... code = %d", res); | ||
998 | return NO_IRQ; | ||
999 | } | ||
1000 | /* Assuming single interrupt controller... */ | ||
1001 | irq = out_irq.specifier[0]; | ||
1002 | |||
1003 | pr_debug("IRQ found = %d", irq); | ||
1004 | |||
1005 | /* Only dereference the resource if both the | ||
1006 | * resource and the irq are valid. */ | ||
1007 | if (r && irq != NO_IRQ) { | ||
1008 | r->start = r->end = irq; | ||
1009 | r->flags = IORESOURCE_IRQ; | ||
1010 | } | ||
1011 | |||
1012 | return irq; | ||
1013 | } | ||
1014 | EXPORT_SYMBOL_GPL(of_irq_to_resource); | ||
1015 | |||
1016 | void __iomem *of_iomap(struct device_node *np, int index) | ||
1017 | { | ||
1018 | struct resource res; | ||
1019 | |||
1020 | if (of_address_to_resource(np, index, &res)) | ||
1021 | return NULL; | ||
1022 | |||
1023 | return ioremap(res.start, 1 + res.end - res.start); | ||
1024 | } | ||
1025 | EXPORT_SYMBOL(of_iomap); | ||
diff --git a/arch/microblaze/kernel/reset.c b/arch/microblaze/kernel/reset.c index a1721a33042e..bd8ccab5ceff 100644 --- a/arch/microblaze/kernel/reset.c +++ b/arch/microblaze/kernel/reset.c | |||
@@ -24,8 +24,8 @@ static int of_reset_gpio_handle(void) | |||
24 | int ret; /* variable which stored handle reset gpio pin */ | 24 | int ret; /* variable which stored handle reset gpio pin */ |
25 | struct device_node *root; /* root node */ | 25 | struct device_node *root; /* root node */ |
26 | struct device_node *gpio; /* gpio node */ | 26 | struct device_node *gpio; /* gpio node */ |
27 | struct of_gpio_chip *of_gc = NULL; | 27 | struct gpio_chip *gc; |
28 | enum of_gpio_flags flags ; | 28 | u32 flags; |
29 | const void *gpio_spec; | 29 | const void *gpio_spec; |
30 | 30 | ||
31 | /* find out root node */ | 31 | /* find out root node */ |
@@ -39,19 +39,19 @@ static int of_reset_gpio_handle(void) | |||
39 | goto err0; | 39 | goto err0; |
40 | } | 40 | } |
41 | 41 | ||
42 | of_gc = gpio->data; | 42 | gc = of_node_to_gpiochip(gpio); |
43 | if (!of_gc) { | 43 | if (!gc) { |
44 | pr_debug("%s: gpio controller %s isn't registered\n", | 44 | pr_debug("%s: gpio controller %s isn't registered\n", |
45 | root->full_name, gpio->full_name); | 45 | root->full_name, gpio->full_name); |
46 | ret = -ENODEV; | 46 | ret = -ENODEV; |
47 | goto err1; | 47 | goto err1; |
48 | } | 48 | } |
49 | 49 | ||
50 | ret = of_gc->xlate(of_gc, root, gpio_spec, &flags); | 50 | ret = gc->of_xlate(gc, root, gpio_spec, &flags); |
51 | if (ret < 0) | 51 | if (ret < 0) |
52 | goto err1; | 52 | goto err1; |
53 | 53 | ||
54 | ret += of_gc->gc.base; | 54 | ret += gc->base; |
55 | err1: | 55 | err1: |
56 | of_node_put(gpio); | 56 | of_node_put(gpio); |
57 | err0: | 57 | err0: |
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c index 17c98dbcec88..f5f768842354 100644 --- a/arch/microblaze/kernel/setup.c +++ b/arch/microblaze/kernel/setup.c | |||
@@ -213,15 +213,9 @@ static struct notifier_block dflt_plat_bus_notifier = { | |||
213 | .priority = INT_MAX, | 213 | .priority = INT_MAX, |
214 | }; | 214 | }; |
215 | 215 | ||
216 | static struct notifier_block dflt_of_bus_notifier = { | ||
217 | .notifier_call = dflt_bus_notify, | ||
218 | .priority = INT_MAX, | ||
219 | }; | ||
220 | |||
221 | static int __init setup_bus_notifier(void) | 216 | static int __init setup_bus_notifier(void) |
222 | { | 217 | { |
223 | bus_register_notifier(&platform_bus_type, &dflt_plat_bus_notifier); | 218 | bus_register_notifier(&platform_bus_type, &dflt_plat_bus_notifier); |
224 | bus_register_notifier(&of_platform_bus_type, &dflt_of_bus_notifier); | ||
225 | 219 | ||
226 | return 0; | 220 | return 0; |
227 | } | 221 | } |