diff options
author | Luka Perkov <luka@openwrt.org> | 2014-02-11 02:07:38 +0000 |
---|---|---|
committer | Luka Perkov <luka@openwrt.org> | 2014-02-11 02:07:38 +0000 |
commit | 69d323f23119ce6986c2803f34d95869144a00e6 (patch) | |
tree | 15747b34c6f9a8dfb622f3d61cbffe043f67e573 /target/linux/mvebu/patches-3.10/0004-of-pci-Provide-support-for-parsing-PCI-DT-ranges-pro.patch | |
parent | 31fb795fd01ac711ff6ca881271fdd4268e34570 (diff) | |
download | mtk-20170518-69d323f23119ce6986c2803f34d95869144a00e6.zip mtk-20170518-69d323f23119ce6986c2803f34d95869144a00e6.tar.gz mtk-20170518-69d323f23119ce6986c2803f34d95869144a00e6.tar.bz2 |
mvebu: backport mainline patches from kernel 3.11
This is a backport of the patches accepted to the Linux mainline related to
mvebu SoC (Armada XP and Armada 370) between Linux v3.10, and Linux v3.11.
This work mainly covers:
* Enabling USB storage, and PCI to mvebu_defconfig.
* Add support for NOR flash.
* Some PCI device tree related updates, and bus parsing.
* Adding Armada XP & 370 PCI driver, and update some clock gating
specifics.
* Introduce Marvell EBU Device Bus driver.
* Enaling USB in the armada*.dts.
* Enabling, and updating the mvebu-mbus.
* Some SATA and Ethernet related fixes.
Signed-off-by: Seif Mazareeb <seif.mazareeb@gmail.com>
CC: Luka Perkov <luka@openwrt.org>
SVN-Revision: 39564
Diffstat (limited to 'target/linux/mvebu/patches-3.10/0004-of-pci-Provide-support-for-parsing-PCI-DT-ranges-pro.patch')
-rw-r--r-- | target/linux/mvebu/patches-3.10/0004-of-pci-Provide-support-for-parsing-PCI-DT-ranges-pro.patch | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/target/linux/mvebu/patches-3.10/0004-of-pci-Provide-support-for-parsing-PCI-DT-ranges-pro.patch b/target/linux/mvebu/patches-3.10/0004-of-pci-Provide-support-for-parsing-PCI-DT-ranges-pro.patch new file mode 100644 index 0000000..6c82070 --- /dev/null +++ b/target/linux/mvebu/patches-3.10/0004-of-pci-Provide-support-for-parsing-PCI-DT-ranges-pro.patch @@ -0,0 +1,196 @@ +From 7d375772a601bdf227902454705e402fc65b8bdf Mon Sep 17 00:00:00 2001 +From: Andrew Murray <Andrew.Murray@arm.com> +Date: Tue, 7 May 2013 16:31:12 +0100 +Subject: [PATCH 004/203] 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> +--- + drivers/of/address.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++ + include/linux/of_address.h | 48 +++++++++++++++++++++++++++++++++ + 2 files changed, 115 insertions(+) + +--- a/drivers/of/address.c ++++ b/drivers/of/address.c +@@ -223,6 +223,73 @@ int of_pci_address_to_resource(struct de + return __of_address_to_resource(dev, addrp, size, flags, NULL, r); + } + EXPORT_SYMBOL_GPL(of_pci_address_to_resource); ++ ++int of_pci_range_parser_init(struct of_pci_range_parser *parser, ++ struct device_node *node) ++{ ++ const int na = 3, ns = 2; ++ int rlen; ++ ++ parser->node = node; ++ parser->pna = of_n_addr_cells(node); ++ parser->np = parser->pna + na + ns; ++ ++ parser->range = of_get_property(node, "ranges", &rlen); ++ if (parser->range == NULL) ++ return -ENOENT; ++ ++ parser->end = parser->range + rlen / sizeof(__be32); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(of_pci_range_parser_init); ++ ++struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser, ++ struct of_pci_range *range) ++{ ++ const int na = 3, ns = 2; ++ ++ if (!range) ++ return NULL; ++ ++ if (!parser->range || parser->range + parser->np > parser->end) ++ return NULL; ++ ++ range->pci_space = parser->range[0]; ++ range->flags = of_bus_pci_get_flags(parser->range); ++ range->pci_addr = of_read_number(parser->range + 1, ns); ++ range->cpu_addr = of_translate_address(parser->node, ++ parser->range + na); ++ range->size = of_read_number(parser->range + parser->pna + na, ns); ++ ++ parser->range += parser->np; ++ ++ /* Now consume following elements while they are contiguous */ ++ while (parser->range + parser->np <= parser->end) { ++ u32 flags, pci_space; ++ u64 pci_addr, cpu_addr, size; ++ ++ pci_space = be32_to_cpup(parser->range); ++ flags = of_bus_pci_get_flags(parser->range); ++ pci_addr = of_read_number(parser->range + 1, ns); ++ cpu_addr = of_translate_address(parser->node, ++ parser->range + na); ++ size = of_read_number(parser->range + parser->pna + na, ns); ++ ++ if (flags != range->flags) ++ break; ++ if (pci_addr != range->pci_addr + range->size || ++ cpu_addr != range->cpu_addr + range->size) ++ break; ++ ++ range->size += size; ++ parser->range += parser->np; ++ } ++ ++ return range; ++} ++EXPORT_SYMBOL_GPL(of_pci_range_parser_one); ++ + #endif /* CONFIG_PCI */ + + /* +--- a/include/linux/of_address.h ++++ b/include/linux/of_address.h +@@ -4,6 +4,36 @@ + #include <linux/errno.h> + #include <linux/of.h> + ++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; ++} ++ + #ifdef CONFIG_OF_ADDRESS + extern u64 of_translate_address(struct device_node *np, const __be32 *addr); + extern bool of_can_translate_address(struct device_node *dev); +@@ -27,6 +57,11 @@ static inline unsigned long pci_address_ + #define pci_address_to_pio pci_address_to_pio + #endif + ++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); + #else /* CONFIG_OF_ADDRESS */ + #ifndef of_address_to_resource + static inline int of_address_to_resource(struct device_node *dev, int index, +@@ -53,6 +88,19 @@ static inline const __be32 *of_get_addre + { + return NULL; + } ++ ++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; ++} + #endif /* CONFIG_OF_ADDRESS */ + + |