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