xref: /linux-6.15/include/linux/of_address.h (revision 4dbf0155)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
26b884a8dSGrant Likely #ifndef __OF_ADDRESS_H
36b884a8dSGrant Likely #define __OF_ADDRESS_H
46b884a8dSGrant Likely #include <linux/ioport.h>
599ce39e3SGrant Likely #include <linux/errno.h>
66b884a8dSGrant Likely #include <linux/of.h>
7fcd71d9cSSudip Mukherjee #include <linux/io.h>
86b884a8dSGrant Likely 
92f96593eSJiaxun Yang struct of_bus;
102f96593eSJiaxun Yang 
1129b635c0SAndrew Murray struct of_pci_range_parser {
1229b635c0SAndrew Murray 	struct device_node *node;
13d79616b0SRob Herring (Arm) 	const struct of_bus *bus;
1429b635c0SAndrew Murray 	const __be32 *range;
1529b635c0SAndrew Murray 	const __be32 *end;
16bc5e522eSRob Herring 	int na;
17bc5e522eSRob Herring 	int ns;
1829b635c0SAndrew Murray 	int pna;
19645c1386SRob Herring 	bool dma;
2029b635c0SAndrew Murray };
21bc5e522eSRob Herring #define of_range_parser of_pci_range_parser
2229b635c0SAndrew Murray 
2329b635c0SAndrew Murray struct of_pci_range {
24bc5e522eSRob Herring 	union {
2529b635c0SAndrew Murray 		u64 pci_addr;
26bc5e522eSRob Herring 		u64 bus_addr;
27bc5e522eSRob Herring 	};
2829b635c0SAndrew Murray 	u64 cpu_addr;
29*4dbf0155SFrank Li 	u64 parent_bus_addr;
3029b635c0SAndrew Murray 	u64 size;
3129b635c0SAndrew Murray 	u32 flags;
3229b635c0SAndrew Murray };
33bc5e522eSRob Herring #define of_range of_pci_range
3429b635c0SAndrew Murray 
3529b635c0SAndrew Murray #define for_each_of_pci_range(parser, range) \
3629b635c0SAndrew Murray 	for (; of_pci_range_parser_one(parser, range);)
37bc5e522eSRob Herring #define for_each_of_range for_each_of_pci_range
3829b635c0SAndrew Murray 
39b50c788aSRob Herring /*
40b50c788aSRob Herring  * of_range_count - Get the number of "ranges" or "dma-ranges" entries
41b50c788aSRob Herring  * @parser:	Parser state initialized by of_range_parser_init()
42b50c788aSRob Herring  *
43b50c788aSRob Herring  * Returns the number of entries or 0 if none.
44b50c788aSRob Herring  *
45b50c788aSRob Herring  * Note that calling this within or after the for_each_of_range() iterator will
46b50c788aSRob Herring  * be inaccurate giving the number of entries remaining.
47b50c788aSRob Herring  */
of_range_count(const struct of_range_parser * parser)48b50c788aSRob Herring static inline int of_range_count(const struct of_range_parser *parser)
49b50c788aSRob Herring {
50b50c788aSRob Herring 	if (!parser || !parser->node || !parser->range || parser->range == parser->end)
51b50c788aSRob Herring 		return 0;
52b50c788aSRob Herring 	return (parser->end - parser->range) / (parser->na + parser->pna + parser->ns);
53b50c788aSRob Herring }
54b50c788aSRob Herring 
55d0dfa16aSRob Herring /* Translate a DMA address from device space to CPU space */
56d0dfa16aSRob Herring extern u64 of_translate_dma_address(struct device_node *dev,
57d0dfa16aSRob Herring 				    const __be32 *in_addr);
58e251c213SThierry Reding extern const __be32 *of_translate_dma_region(struct device_node *dev, const __be32 *addr,
59e251c213SThierry Reding 					     phys_addr_t *start, size_t *length);
60d0dfa16aSRob Herring 
61a850a755SGrant Likely #ifdef CONFIG_OF_ADDRESS
620131d897SSebastian Andrzej Siewior extern u64 of_translate_address(struct device_node *np, const __be32 *addr);
631f5bef30SGrant Likely extern int of_address_to_resource(struct device_node *dev, int index,
641f5bef30SGrant Likely 				  struct resource *r);
656b884a8dSGrant Likely extern void __iomem *of_iomap(struct device_node *device, int index);
66fcd71d9cSSudip Mukherjee void __iomem *of_io_request_and_map(struct device_node *device,
67fcd71d9cSSudip Mukherjee 				    int index, const char *name);
686b884a8dSGrant Likely 
6922ae782fSGrant Likely /* Extract an address from a device, returns the region size and
7022ae782fSGrant Likely  * the address space flags too. The PCI version uses a BAR number
7122ae782fSGrant Likely  * instead of an absolute index
7222ae782fSGrant Likely  */
73050a2c62SRob Herring extern const __be32 *__of_get_address(struct device_node *dev, int index, int bar_no,
7422ae782fSGrant Likely 				      u64 *size, unsigned int *flags);
7522ae782fSGrant Likely 
76ff61bacdSRob Herring int of_property_read_reg(struct device_node *np, int idx, u64 *addr, u64 *size);
77ff61bacdSRob Herring 
7829b635c0SAndrew Murray extern int of_pci_range_parser_init(struct of_pci_range_parser *parser,
7929b635c0SAndrew Murray 			struct device_node *node);
80a060c210SMarc Gonzalez extern int of_pci_dma_range_parser_init(struct of_pci_range_parser *parser,
81a060c210SMarc Gonzalez 			struct device_node *node);
8229b635c0SAndrew Murray extern struct of_pci_range *of_pci_range_parser_one(
8329b635c0SAndrew Murray 					struct of_pci_range_parser *parser,
8429b635c0SAndrew Murray 					struct of_pci_range *range);
85c3c0dc75SRob Herring extern int of_pci_address_to_resource(struct device_node *dev, int bar,
86c3c0dc75SRob Herring 				      struct resource *r);
87ec8c2329SRob Herring (Arm) extern int of_pci_range_to_resource(const struct of_pci_range *range,
88ec8c2329SRob Herring (Arm) 				    const struct device_node *np,
89c3c0dc75SRob Herring 				    struct resource *res);
90c75a7949SRob Herring extern int of_range_to_resource(struct device_node *np, int index,
91c75a7949SRob Herring 				struct resource *res);
9292ea637eSSantosh Shilimkar extern bool of_dma_is_coherent(struct device_node *np);
93a850a755SGrant Likely #else /* CONFIG_OF_ADDRESS */
of_io_request_and_map(struct device_node * device,int index,const char * name)94fcd71d9cSSudip Mukherjee static inline void __iomem *of_io_request_and_map(struct device_node *device,
95fcd71d9cSSudip Mukherjee 						  int index, const char *name)
96fcd71d9cSSudip Mukherjee {
97fcd71d9cSSudip Mukherjee 	return IOMEM_ERR_PTR(-EINVAL);
98fcd71d9cSSudip Mukherjee }
99b1d06b60SGuenter Roeck 
of_translate_address(struct device_node * np,const __be32 * addr)100b1d06b60SGuenter Roeck static inline u64 of_translate_address(struct device_node *np,
101b1d06b60SGuenter Roeck 				       const __be32 *addr)
102b1d06b60SGuenter Roeck {
103b1d06b60SGuenter Roeck 	return OF_BAD_ADDR;
104b1d06b60SGuenter Roeck }
105b1d06b60SGuenter Roeck 
__of_get_address(struct device_node * dev,int index,int bar_no,u64 * size,unsigned int * flags)106050a2c62SRob Herring static inline const __be32 *__of_get_address(struct device_node *dev, int index, int bar_no,
107a850a755SGrant Likely 					     u64 *size, unsigned int *flags)
108a850a755SGrant Likely {
109a850a755SGrant Likely 	return NULL;
110a850a755SGrant Likely }
11129b635c0SAndrew Murray 
of_property_read_reg(struct device_node * np,int idx,u64 * addr,u64 * size)112ff61bacdSRob Herring static inline int of_property_read_reg(struct device_node *np, int idx, u64 *addr, u64 *size)
113ff61bacdSRob Herring {
114ff61bacdSRob Herring 	return -ENOSYS;
115ff61bacdSRob Herring }
116ff61bacdSRob Herring 
of_pci_range_parser_init(struct of_pci_range_parser * parser,struct device_node * node)11729b635c0SAndrew Murray static inline int of_pci_range_parser_init(struct of_pci_range_parser *parser,
11829b635c0SAndrew Murray 			struct device_node *node)
11929b635c0SAndrew Murray {
120a060c210SMarc Gonzalez 	return -ENOSYS;
121a060c210SMarc Gonzalez }
122a060c210SMarc Gonzalez 
of_pci_dma_range_parser_init(struct of_pci_range_parser * parser,struct device_node * node)123a060c210SMarc Gonzalez static inline int of_pci_dma_range_parser_init(struct of_pci_range_parser *parser,
124a060c210SMarc Gonzalez 			struct device_node *node)
125a060c210SMarc Gonzalez {
126a060c210SMarc Gonzalez 	return -ENOSYS;
12729b635c0SAndrew Murray }
12829b635c0SAndrew Murray 
of_pci_range_parser_one(struct of_pci_range_parser * parser,struct of_pci_range * range)12929b635c0SAndrew Murray static inline struct of_pci_range *of_pci_range_parser_one(
13029b635c0SAndrew Murray 					struct of_pci_range_parser *parser,
13129b635c0SAndrew Murray 					struct of_pci_range *range)
13229b635c0SAndrew Murray {
13329b635c0SAndrew Murray 	return NULL;
13429b635c0SAndrew Murray }
13518308c94SGrygorii Strashko 
of_pci_address_to_resource(struct device_node * dev,int bar,struct resource * r)136c3c0dc75SRob Herring static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
137c3c0dc75SRob Herring 				             struct resource *r)
138c3c0dc75SRob Herring {
139c3c0dc75SRob Herring 	return -ENOSYS;
140c3c0dc75SRob Herring }
141c3c0dc75SRob Herring 
of_pci_range_to_resource(struct of_pci_range * range,struct device_node * np,struct resource * res)142c3c0dc75SRob Herring static inline int of_pci_range_to_resource(struct of_pci_range *range,
143c3c0dc75SRob Herring 					   struct device_node *np,
144c3c0dc75SRob Herring 					   struct resource *res)
145c3c0dc75SRob Herring {
146c3c0dc75SRob Herring 	return -ENOSYS;
147c3c0dc75SRob Herring }
148c3c0dc75SRob Herring 
of_range_to_resource(struct device_node * np,int index,struct resource * res)149c75a7949SRob Herring static inline int of_range_to_resource(struct device_node *np, int index,
150c75a7949SRob Herring 				       struct resource *res)
151c75a7949SRob Herring {
152c75a7949SRob Herring 	return -ENOSYS;
153c75a7949SRob Herring }
154c75a7949SRob Herring 
of_dma_is_coherent(struct device_node * np)15592ea637eSSantosh Shilimkar static inline bool of_dma_is_coherent(struct device_node *np)
15692ea637eSSantosh Shilimkar {
15792ea637eSSantosh Shilimkar 	return false;
15892ea637eSSantosh Shilimkar }
159a850a755SGrant Likely #endif /* CONFIG_OF_ADDRESS */
160a850a755SGrant Likely 
1614acf4b9cSRob Herring #ifdef CONFIG_OF
1624acf4b9cSRob Herring extern int of_address_to_resource(struct device_node *dev, int index,
1634acf4b9cSRob Herring 				  struct resource *r);
1644acf4b9cSRob Herring void __iomem *of_iomap(struct device_node *node, int index);
1654acf4b9cSRob Herring #else
of_address_to_resource(struct device_node * dev,int index,struct resource * r)1664acf4b9cSRob Herring static inline int of_address_to_resource(struct device_node *dev, int index,
1674acf4b9cSRob Herring 					 struct resource *r)
1684acf4b9cSRob Herring {
1694acf4b9cSRob Herring 	return -EINVAL;
1704acf4b9cSRob Herring }
1714acf4b9cSRob Herring 
of_iomap(struct device_node * device,int index)1724acf4b9cSRob Herring static inline void __iomem *of_iomap(struct device_node *device, int index)
1734acf4b9cSRob Herring {
1744acf4b9cSRob Herring 	return NULL;
1754acf4b9cSRob Herring }
1764acf4b9cSRob Herring #endif
1772f96593eSJiaxun Yang #define of_range_parser_init of_pci_range_parser_init
178a850a755SGrant Likely 
of_get_address(struct device_node * dev,int index,u64 * size,unsigned int * flags)179050a2c62SRob Herring static inline const __be32 *of_get_address(struct device_node *dev, int index,
180050a2c62SRob Herring 					   u64 *size, unsigned int *flags)
181050a2c62SRob Herring {
182050a2c62SRob Herring 	return __of_get_address(dev, index, -1, size, flags);
183050a2c62SRob Herring }
184050a2c62SRob Herring 
of_get_pci_address(struct device_node * dev,int bar_no,u64 * size,unsigned int * flags)185050a2c62SRob Herring static inline const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
186050a2c62SRob Herring 					       u64 *size, unsigned int *flags)
187050a2c62SRob Herring {
188050a2c62SRob Herring 	return __of_get_address(dev, -1, bar_no, size, flags);
189050a2c62SRob Herring }
190050a2c62SRob Herring 
of_address_count(struct device_node * np)19116988c74SYang Yingliang static inline int of_address_count(struct device_node *np)
19216988c74SYang Yingliang {
19316988c74SYang Yingliang 	struct resource res;
19416988c74SYang Yingliang 	int count = 0;
19516988c74SYang Yingliang 
19616988c74SYang Yingliang 	while (of_address_to_resource(np, count, &res) == 0)
19716988c74SYang Yingliang 		count++;
19816988c74SYang Yingliang 
19916988c74SYang Yingliang 	return count;
20016988c74SYang Yingliang }
20116988c74SYang Yingliang 
2026b884a8dSGrant Likely #endif /* __OF_ADDRESS_H */
203