Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
6b884a8d GL |
2 | #ifndef __OF_ADDRESS_H |
3 | #define __OF_ADDRESS_H | |
4 | #include <linux/ioport.h> | |
99ce39e3 | 5 | #include <linux/errno.h> |
6b884a8d | 6 | #include <linux/of.h> |
fcd71d9c | 7 | #include <linux/io.h> |
6b884a8d | 8 | |
2f96593e JY |
9 | struct of_bus; |
10 | ||
29b635c0 AM |
11 | struct of_pci_range_parser { |
12 | struct device_node *node; | |
2f96593e | 13 | struct of_bus *bus; |
29b635c0 AM |
14 | const __be32 *range; |
15 | const __be32 *end; | |
bc5e522e RH |
16 | int na; |
17 | int ns; | |
29b635c0 | 18 | int pna; |
645c1386 | 19 | bool dma; |
29b635c0 | 20 | }; |
bc5e522e | 21 | #define of_range_parser of_pci_range_parser |
29b635c0 AM |
22 | |
23 | struct of_pci_range { | |
bc5e522e RH |
24 | union { |
25 | u64 pci_addr; | |
26 | u64 bus_addr; | |
27 | }; | |
29b635c0 AM |
28 | u64 cpu_addr; |
29 | u64 size; | |
30 | u32 flags; | |
31 | }; | |
bc5e522e | 32 | #define of_range of_pci_range |
29b635c0 AM |
33 | |
34 | #define for_each_of_pci_range(parser, range) \ | |
35 | for (; of_pci_range_parser_one(parser, range);) | |
bc5e522e | 36 | #define for_each_of_range for_each_of_pci_range |
29b635c0 | 37 | |
b50c788a RH |
38 | /* |
39 | * of_range_count - Get the number of "ranges" or "dma-ranges" entries | |
40 | * @parser: Parser state initialized by of_range_parser_init() | |
41 | * | |
42 | * Returns the number of entries or 0 if none. | |
43 | * | |
44 | * Note that calling this within or after the for_each_of_range() iterator will | |
45 | * be inaccurate giving the number of entries remaining. | |
46 | */ | |
47 | static inline int of_range_count(const struct of_range_parser *parser) | |
48 | { | |
49 | if (!parser || !parser->node || !parser->range || parser->range == parser->end) | |
50 | return 0; | |
51 | return (parser->end - parser->range) / (parser->na + parser->pna + parser->ns); | |
52 | } | |
53 | ||
d0dfa16a RH |
54 | /* Translate a DMA address from device space to CPU space */ |
55 | extern u64 of_translate_dma_address(struct device_node *dev, | |
56 | const __be32 *in_addr); | |
e251c213 TR |
57 | extern const __be32 *of_translate_dma_region(struct device_node *dev, const __be32 *addr, |
58 | phys_addr_t *start, size_t *length); | |
d0dfa16a | 59 | |
a850a755 | 60 | #ifdef CONFIG_OF_ADDRESS |
0131d897 | 61 | extern u64 of_translate_address(struct device_node *np, const __be32 *addr); |
1f5bef30 GL |
62 | extern int of_address_to_resource(struct device_node *dev, int index, |
63 | struct resource *r); | |
6b884a8d | 64 | extern void __iomem *of_iomap(struct device_node *device, int index); |
fcd71d9c SM |
65 | void __iomem *of_io_request_and_map(struct device_node *device, |
66 | int index, const char *name); | |
6b884a8d | 67 | |
22ae782f GL |
68 | /* Extract an address from a device, returns the region size and |
69 | * the address space flags too. The PCI version uses a BAR number | |
70 | * instead of an absolute index | |
71 | */ | |
050a2c62 RH |
72 | extern const __be32 *__of_get_address(struct device_node *dev, int index, int bar_no, |
73 | u64 *size, unsigned int *flags); | |
22ae782f | 74 | |
ff61bacd RH |
75 | int of_property_read_reg(struct device_node *np, int idx, u64 *addr, u64 *size); |
76 | ||
29b635c0 AM |
77 | extern int of_pci_range_parser_init(struct of_pci_range_parser *parser, |
78 | struct device_node *node); | |
a060c210 MG |
79 | extern int of_pci_dma_range_parser_init(struct of_pci_range_parser *parser, |
80 | struct device_node *node); | |
29b635c0 AM |
81 | extern struct of_pci_range *of_pci_range_parser_one( |
82 | struct of_pci_range_parser *parser, | |
83 | struct of_pci_range *range); | |
c3c0dc75 RH |
84 | extern int of_pci_address_to_resource(struct device_node *dev, int bar, |
85 | struct resource *r); | |
86 | extern int of_pci_range_to_resource(struct of_pci_range *range, | |
87 | struct device_node *np, | |
88 | struct resource *res); | |
c75a7949 RH |
89 | extern int of_range_to_resource(struct device_node *np, int index, |
90 | struct resource *res); | |
92ea637e | 91 | extern bool of_dma_is_coherent(struct device_node *np); |
a850a755 | 92 | #else /* CONFIG_OF_ADDRESS */ |
fcd71d9c SM |
93 | static inline void __iomem *of_io_request_and_map(struct device_node *device, |
94 | int index, const char *name) | |
95 | { | |
96 | return IOMEM_ERR_PTR(-EINVAL); | |
97 | } | |
b1d06b60 GR |
98 | |
99 | static inline u64 of_translate_address(struct device_node *np, | |
100 | const __be32 *addr) | |
101 | { | |
102 | return OF_BAD_ADDR; | |
103 | } | |
104 | ||
050a2c62 RH |
105 | static inline const __be32 *__of_get_address(struct device_node *dev, int index, int bar_no, |
106 | u64 *size, unsigned int *flags) | |
a850a755 GL |
107 | { |
108 | return NULL; | |
109 | } | |
29b635c0 | 110 | |
ff61bacd RH |
111 | static inline int of_property_read_reg(struct device_node *np, int idx, u64 *addr, u64 *size) |
112 | { | |
113 | return -ENOSYS; | |
114 | } | |
115 | ||
29b635c0 AM |
116 | static inline int of_pci_range_parser_init(struct of_pci_range_parser *parser, |
117 | struct device_node *node) | |
118 | { | |
a060c210 MG |
119 | return -ENOSYS; |
120 | } | |
121 | ||
122 | static inline int of_pci_dma_range_parser_init(struct of_pci_range_parser *parser, | |
123 | struct device_node *node) | |
124 | { | |
125 | return -ENOSYS; | |
29b635c0 AM |
126 | } |
127 | ||
128 | static inline struct of_pci_range *of_pci_range_parser_one( | |
129 | struct of_pci_range_parser *parser, | |
130 | struct of_pci_range *range) | |
131 | { | |
132 | return NULL; | |
133 | } | |
18308c94 | 134 | |
c3c0dc75 RH |
135 | static inline int of_pci_address_to_resource(struct device_node *dev, int bar, |
136 | struct resource *r) | |
137 | { | |
138 | return -ENOSYS; | |
139 | } | |
140 | ||
141 | static inline int of_pci_range_to_resource(struct of_pci_range *range, | |
142 | struct device_node *np, | |
143 | struct resource *res) | |
144 | { | |
145 | return -ENOSYS; | |
146 | } | |
147 | ||
c75a7949 RH |
148 | static inline int of_range_to_resource(struct device_node *np, int index, |
149 | struct resource *res) | |
150 | { | |
151 | return -ENOSYS; | |
152 | } | |
153 | ||
92ea637e SS |
154 | static inline bool of_dma_is_coherent(struct device_node *np) |
155 | { | |
156 | return false; | |
157 | } | |
a850a755 GL |
158 | #endif /* CONFIG_OF_ADDRESS */ |
159 | ||
4acf4b9c RH |
160 | #ifdef CONFIG_OF |
161 | extern int of_address_to_resource(struct device_node *dev, int index, | |
162 | struct resource *r); | |
163 | void __iomem *of_iomap(struct device_node *node, int index); | |
164 | #else | |
165 | static inline int of_address_to_resource(struct device_node *dev, int index, | |
166 | struct resource *r) | |
167 | { | |
168 | return -EINVAL; | |
169 | } | |
170 | ||
171 | static inline void __iomem *of_iomap(struct device_node *device, int index) | |
172 | { | |
173 | return NULL; | |
174 | } | |
175 | #endif | |
2f96593e | 176 | #define of_range_parser_init of_pci_range_parser_init |
a850a755 | 177 | |
050a2c62 RH |
178 | static inline const __be32 *of_get_address(struct device_node *dev, int index, |
179 | u64 *size, unsigned int *flags) | |
180 | { | |
181 | return __of_get_address(dev, index, -1, size, flags); | |
182 | } | |
183 | ||
184 | static inline const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, | |
185 | u64 *size, unsigned int *flags) | |
186 | { | |
187 | return __of_get_address(dev, -1, bar_no, size, flags); | |
188 | } | |
189 | ||
16988c74 YY |
190 | static inline int of_address_count(struct device_node *np) |
191 | { | |
192 | struct resource res; | |
193 | int count = 0; | |
194 | ||
195 | while (of_address_to_resource(np, count, &res) == 0) | |
196 | count++; | |
197 | ||
198 | return count; | |
199 | } | |
200 | ||
6b884a8d | 201 | #endif /* __OF_ADDRESS_H */ |