2010-06-08 21:48:09 +08:00
|
|
|
#ifndef __OF_ADDRESS_H
|
|
|
|
#define __OF_ADDRESS_H
|
|
|
|
#include <linux/ioport.h>
|
2011-07-06 13:42:37 +08:00
|
|
|
#include <linux/errno.h>
|
2010-06-08 21:48:09 +08:00
|
|
|
#include <linux/of.h>
|
|
|
|
|
of/pci: Provide support for parsing PCI DT ranges property
This patch factors out common implementation patterns to reduce overall kernel
code and provide a means for host bridge drivers to directly obtain struct
resources from the DT's ranges property without relying on architecture specific
DT handling. This will make it easier to write archiecture independent host bridge
drivers and mitigate against further duplication of DT parsing code.
This patch can be used in the following way:
struct of_pci_range_parser parser;
struct of_pci_range range;
if (of_pci_range_parser_init(&parser, np))
; //no ranges property
for_each_of_pci_range(&parser, &range) {
/*
directly access properties of the address range, e.g.:
range.pci_space, range.pci_addr, range.cpu_addr,
range.size, range.flags
alternatively obtain a struct resource, e.g.:
struct resource res;
of_pci_range_to_resource(&range, np, &res);
*/
}
Additionally the implementation takes care of adjacent ranges and merges them
into a single range (as was the case with powerpc and microblaze).
Signed-off-by: Andrew Murray <Andrew.Murray@arm.com>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Reviewed-by: Rob Herring <rob.herring@calxeda.com>
Tested-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Tested-by: Linus Walleij <linus.walleij@linaro.org>
Tested-by: Jingoo Han <jg1.han@samsung.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
2013-05-16 23:55:17 +08:00
|
|
|
struct of_pci_range_parser {
|
|
|
|
struct device_node *node;
|
|
|
|
const __be32 *range;
|
|
|
|
const __be32 *end;
|
|
|
|
int np;
|
|
|
|
int pna;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct of_pci_range {
|
|
|
|
u32 pci_space;
|
|
|
|
u64 pci_addr;
|
|
|
|
u64 cpu_addr;
|
|
|
|
u64 size;
|
|
|
|
u32 flags;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define for_each_of_pci_range(parser, range) \
|
|
|
|
for (; of_pci_range_parser_one(parser, range);)
|
|
|
|
|
|
|
|
static inline void of_pci_range_to_resource(struct of_pci_range *range,
|
|
|
|
struct device_node *np,
|
|
|
|
struct resource *res)
|
|
|
|
{
|
|
|
|
res->flags = range->flags;
|
|
|
|
res->start = range->cpu_addr;
|
|
|
|
res->end = range->cpu_addr + range->size - 1;
|
|
|
|
res->parent = res->child = res->sibling = NULL;
|
|
|
|
res->name = np->full_name;
|
|
|
|
}
|
|
|
|
|
2013-09-17 10:05:05 +08:00
|
|
|
/* Translate a DMA address from device space to CPU space */
|
|
|
|
extern u64 of_translate_dma_address(struct device_node *dev,
|
|
|
|
const __be32 *in_addr);
|
|
|
|
|
2012-02-15 05:06:55 +08:00
|
|
|
#ifdef CONFIG_OF_ADDRESS
|
2010-12-01 17:54:46 +08:00
|
|
|
extern u64 of_translate_address(struct device_node *np, const __be32 *addr);
|
2012-07-26 07:34:37 +08:00
|
|
|
extern bool of_can_translate_address(struct device_node *dev);
|
2010-06-08 21:48:09 +08:00
|
|
|
extern int of_address_to_resource(struct device_node *dev, int index,
|
|
|
|
struct resource *r);
|
2011-07-06 13:42:28 +08:00
|
|
|
extern struct device_node *of_find_matching_node_by_address(
|
|
|
|
struct device_node *from,
|
|
|
|
const struct of_device_id *matches,
|
|
|
|
u64 base_address);
|
2010-06-08 21:48:09 +08:00
|
|
|
extern void __iomem *of_iomap(struct device_node *device, int index);
|
|
|
|
|
2010-07-30 01:49:01 +08:00
|
|
|
/* Extract an address from a device, returns the region size and
|
|
|
|
* the address space flags too. The PCI version uses a BAR number
|
|
|
|
* instead of an absolute index
|
|
|
|
*/
|
2012-10-09 08:41:58 +08:00
|
|
|
extern const __be32 *of_get_address(struct device_node *dev, int index,
|
2010-07-30 01:49:01 +08:00
|
|
|
u64 *size, unsigned int *flags);
|
|
|
|
|
2013-09-08 03:07:11 +08:00
|
|
|
extern unsigned long pci_address_to_pio(phys_addr_t addr);
|
2010-07-30 01:49:01 +08:00
|
|
|
|
of/pci: Provide support for parsing PCI DT ranges property
This patch factors out common implementation patterns to reduce overall kernel
code and provide a means for host bridge drivers to directly obtain struct
resources from the DT's ranges property without relying on architecture specific
DT handling. This will make it easier to write archiecture independent host bridge
drivers and mitigate against further duplication of DT parsing code.
This patch can be used in the following way:
struct of_pci_range_parser parser;
struct of_pci_range range;
if (of_pci_range_parser_init(&parser, np))
; //no ranges property
for_each_of_pci_range(&parser, &range) {
/*
directly access properties of the address range, e.g.:
range.pci_space, range.pci_addr, range.cpu_addr,
range.size, range.flags
alternatively obtain a struct resource, e.g.:
struct resource res;
of_pci_range_to_resource(&range, np, &res);
*/
}
Additionally the implementation takes care of adjacent ranges and merges them
into a single range (as was the case with powerpc and microblaze).
Signed-off-by: Andrew Murray <Andrew.Murray@arm.com>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Reviewed-by: Rob Herring <rob.herring@calxeda.com>
Tested-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Tested-by: Linus Walleij <linus.walleij@linaro.org>
Tested-by: Jingoo Han <jg1.han@samsung.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
2013-05-16 23:55:17 +08:00
|
|
|
extern int of_pci_range_parser_init(struct of_pci_range_parser *parser,
|
|
|
|
struct device_node *node);
|
|
|
|
extern struct of_pci_range *of_pci_range_parser_one(
|
|
|
|
struct of_pci_range_parser *parser,
|
|
|
|
struct of_pci_range *range);
|
2012-02-15 05:06:55 +08:00
|
|
|
#else /* CONFIG_OF_ADDRESS */
|
|
|
|
static inline struct device_node *of_find_matching_node_by_address(
|
|
|
|
struct device_node *from,
|
|
|
|
const struct of_device_id *matches,
|
|
|
|
u64 base_address)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
2013-09-17 10:03:24 +08:00
|
|
|
|
2012-10-09 08:41:58 +08:00
|
|
|
static inline const __be32 *of_get_address(struct device_node *dev, int index,
|
2012-02-15 05:06:55 +08:00
|
|
|
u64 *size, unsigned int *flags)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
of/pci: Provide support for parsing PCI DT ranges property
This patch factors out common implementation patterns to reduce overall kernel
code and provide a means for host bridge drivers to directly obtain struct
resources from the DT's ranges property without relying on architecture specific
DT handling. This will make it easier to write archiecture independent host bridge
drivers and mitigate against further duplication of DT parsing code.
This patch can be used in the following way:
struct of_pci_range_parser parser;
struct of_pci_range range;
if (of_pci_range_parser_init(&parser, np))
; //no ranges property
for_each_of_pci_range(&parser, &range) {
/*
directly access properties of the address range, e.g.:
range.pci_space, range.pci_addr, range.cpu_addr,
range.size, range.flags
alternatively obtain a struct resource, e.g.:
struct resource res;
of_pci_range_to_resource(&range, np, &res);
*/
}
Additionally the implementation takes care of adjacent ranges and merges them
into a single range (as was the case with powerpc and microblaze).
Signed-off-by: Andrew Murray <Andrew.Murray@arm.com>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Reviewed-by: Rob Herring <rob.herring@calxeda.com>
Tested-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Tested-by: Linus Walleij <linus.walleij@linaro.org>
Tested-by: Jingoo Han <jg1.han@samsung.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
2013-05-16 23:55:17 +08:00
|
|
|
|
|
|
|
static inline int of_pci_range_parser_init(struct of_pci_range_parser *parser,
|
|
|
|
struct device_node *node)
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline struct of_pci_range *of_pci_range_parser_one(
|
|
|
|
struct of_pci_range_parser *parser,
|
|
|
|
struct of_pci_range *range)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
2012-02-15 05:06:55 +08:00
|
|
|
#endif /* CONFIG_OF_ADDRESS */
|
|
|
|
|
2013-09-17 10:03:24 +08:00
|
|
|
#ifdef CONFIG_OF
|
|
|
|
extern int of_address_to_resource(struct device_node *dev, int index,
|
|
|
|
struct resource *r);
|
|
|
|
void __iomem *of_iomap(struct device_node *node, int index);
|
|
|
|
#else
|
|
|
|
static inline int of_address_to_resource(struct device_node *dev, int index,
|
|
|
|
struct resource *r)
|
|
|
|
{
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void __iomem *of_iomap(struct device_node *device, int index)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
#endif
|
2012-02-15 05:06:55 +08:00
|
|
|
|
|
|
|
#if defined(CONFIG_OF_ADDRESS) && defined(CONFIG_PCI)
|
2010-12-01 17:54:46 +08:00
|
|
|
extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
|
2010-07-30 01:49:01 +08:00
|
|
|
u64 *size, unsigned int *flags);
|
|
|
|
extern int of_pci_address_to_resource(struct device_node *dev, int bar,
|
|
|
|
struct resource *r);
|
2012-02-15 05:06:55 +08:00
|
|
|
#else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
|
2010-07-30 01:49:01 +08:00
|
|
|
static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
|
|
|
|
struct resource *r)
|
|
|
|
{
|
|
|
|
return -ENOSYS;
|
|
|
|
}
|
|
|
|
|
2010-12-01 17:54:46 +08:00
|
|
|
static inline const __be32 *of_get_pci_address(struct device_node *dev,
|
2010-07-30 01:49:01 +08:00
|
|
|
int bar_no, u64 *size, unsigned int *flags)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
2012-02-15 05:06:55 +08:00
|
|
|
#endif /* CONFIG_OF_ADDRESS && CONFIG_PCI */
|
2010-07-30 01:49:01 +08:00
|
|
|
|
2010-06-08 21:48:09 +08:00
|
|
|
#endif /* __OF_ADDRESS_H */
|
|
|
|
|