On 03/01/2014 15:47, Andrew Lunn wrote: > On Fri, Jan 03, 2014 at 10:59:44AM +0100, Gregory CLEMENT wrote: >> All the mvebu SoCs have information related to their variant and >> revision that can be read from the PCI control register. >> >> This patch adds support for Armada XP and Armada 370. This reading of >> the revision and the ID are done before the PCI initialization to >> avoid any conflicts. Once these data are retrieved, the resources are >> freed to let the PCI subsystem use it. >> >> Cc: stable@xxxxxxxxxxxxxxx >> Signed-off-by: Gregory CLEMENT <gregory.clement@xxxxxxxxxxxxxxxxxx> >> --- >> arch/arm/mach-mvebu/Makefile | 2 +- >> arch/arm/mach-mvebu/mvebu-soc-id.c | 111 +++++++++++++++++++++++++++++++++++++ >> include/linux/mvebu-soc-id.h | 32 +++++++++++ >> 3 files changed, 144 insertions(+), 1 deletion(-) >> create mode 100644 arch/arm/mach-mvebu/mvebu-soc-id.c >> create mode 100644 include/linux/mvebu-soc-id.h >> >> diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile >> index 2d04f0e21870..878aebe98dcc 100644 >> --- a/arch/arm/mach-mvebu/Makefile >> +++ b/arch/arm/mach-mvebu/Makefile >> @@ -3,7 +3,7 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \ >> >> AFLAGS_coherency_ll.o := -Wa,-march=armv7-a >> >> -obj-y += system-controller.o >> +obj-y += system-controller.o mvebu-soc-id.o >> obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o >> obj-$(CONFIG_ARCH_MVEBU) += coherency.o coherency_ll.o pmsu.o >> obj-$(CONFIG_SMP) += platsmp.o headsmp.o >> diff --git a/arch/arm/mach-mvebu/mvebu-soc-id.c b/arch/arm/mach-mvebu/mvebu-soc-id.c >> new file mode 100644 >> index 000000000000..86c901be284c >> --- /dev/null >> +++ b/arch/arm/mach-mvebu/mvebu-soc-id.c >> @@ -0,0 +1,111 @@ >> +/* >> + * Variant and revision information for mvebu SoCs >> + * >> + * Copyright (C) 2014 Marvell >> + * >> + * Gregory CLEMENT <gregory.clement@xxxxxxxxxxxxxxxxxx> >> + * >> + * This file is licensed under the terms of the GNU General Public >> + * License version 2. This program is licensed "as is" without any >> + * warranty of any kind, whether express or implied. >> + * >> + * All the mvebu SoCs have information related to their variant and >> + * revision that can be read from the PCI control register. This is >> + * done before the PCI initialization to avoid any conflict. Once the >> + * ID and revision are retrieved, the mapping is freed. >> + */ >> + >> +#include <linux/clk.h> >> +#include <linux/init.h> >> +#include <linux/io.h> >> +#include <linux/kernel.h> >> +#include <linux/mvebu-soc-id.h> >> +#include <linux/of.h> >> +#include <linux/of_address.h> >> + >> +#define PCIE_DEV_ID_OFF 0x0 >> +#define PCIE_DEV_REV_OFF 0x8 >> + >> +#define SOC_ID_MASK 0xFFFF0000 >> +#define SOC_REV_MASK 0xFF >> + >> +static u32 soc_dev_id; >> +static u32 soc_rev; >> +static bool is_id_valid; >> + >> +static const struct of_device_id mvebu_pcie_of_match_table[] = { >> + { .compatible = "marvell,armada-xp-pcie", }, >> + { .compatible = "marvell,armada-370-pcie", }, >> + {}, >> +}; >> + >> +int mvebu_get_soc_id(u32 *dev, u32 *rev) >> +{ >> + if (is_id_valid) { >> + *dev = soc_dev_id; >> + *rev = soc_rev; >> + return 0; >> + } else >> + return -1; >> +} >> + >> +EXPORT_SYMBOL(mvebu_get_soc_id); >> + >> +static int __init mvebu_soc_id_init(void) >> +{ >> + struct device_node *np; >> + int ret = 0; >> + >> + np = of_find_matching_node(NULL, mvebu_pcie_of_match_table); >> + if (np) { >> + void __iomem *pci_base; >> + struct clk *clk; >> + /* >> + * ID and revision are available from any port, so we >> + * just pick the first one >> + */ >> + struct device_node *child = of_get_next_child(np, NULL); > > Hi Gregory > > I'm away from my hardware at the moment. > > Does this work when all the PCIe ports have status = "disabled";? We > have many kirkwood devices in NAS boxes which don't use PCIe, so all > the ports are disabled. But they still exist in the SoC, so we can > read the IDs from them. I just don't know if of_get_next_child() will > only return enabled children? There is a function named of_get_next_available_child, so I assumed that of_get_next_child() will return all the children. But I can test it to be sure of it. > > Thanks > Andrew > >> + >> + clk = of_clk_get_by_name(child, NULL); >> + if (IS_ERR(clk)) { >> + pr_err("%s: cannot get clock\n", __func__); >> + ret = -ENOMEM; >> + goto clk_err; >> + } >> + >> + ret = clk_prepare_enable(clk); >> + if (ret) { >> + pr_err("%s: cannot enable clock\n", __func__); >> + goto clk_err; >> + } >> + >> + pci_base = of_iomap(child, 0); >> + if (IS_ERR(pci_base)) { >> + pr_err("%s: cannot map registers\n", __func__); >> + ret = -ENOMEM; >> + goto res_ioremap; >> + } >> + >> + /* SoC ID */ >> + soc_dev_id = __raw_readl(pci_base + PCIE_DEV_ID_OFF) >> 16; >> + >> + /* SoC revision */ >> + soc_rev = __raw_readl(pci_base + PCIE_DEV_REV_OFF) >> + & SOC_REV_MASK; >> + >> + is_id_valid = true; >> + >> + iounmap(pci_base); >> + >> +res_ioremap: >> + clk_disable_unprepare(clk); >> + >> +clk_err: >> + of_node_put(child); >> + of_node_put(np); >> + } >> + >> + return ret; >> +} >> +arch_initcall(mvebu_soc_id_init); >> + >> diff --git a/include/linux/mvebu-soc-id.h b/include/linux/mvebu-soc-id.h >> new file mode 100644 >> index 000000000000..602ce1c50d1d >> --- /dev/null >> +++ b/include/linux/mvebu-soc-id.h >> @@ -0,0 +1,32 @@ >> +/* >> + * Marvell EBU SoC ID and revision definitions. >> + * >> + * Copyright (C) 2014 Marvell Semiconductor >> + * >> + * This file is licensed under the terms of the GNU General Public >> + * License version 2. This program is licensed "as is" without any >> + * warranty of any kind, whether express or implied. >> + */ >> + >> +#ifndef __LINUX_MVEBU_SOC_ID_H >> +#define __LINUX_MVEBU_SOC_ID_H >> + >> +/* Armada XP ID */ >> +#define MV78230_DEV_ID 0x7823 >> +#define MV78260_DEV_ID 0x7826 >> +#define MV78460_DEV_ID 0x7846 >> + >> +/* Armada XP Revision */ >> +#define MV78XX0_A0_REV 0x1 >> +#define MV78XX0_B0_REV 0x2 >> + >> +#ifdef CONFIG_ARCH_MVEBU >> +int mvebu_get_soc_id(u32 *dev, u32 *rev); >> +#else >> +int mvebu_get_soc_id(u32 *dev, u32 *rev) >> +{ >> + return -1; >> +} >> +#endif >> + >> +#endif /* __LINUX_MVEBU_SOC_ID_H */ >> -- >> 1.8.1.2 >> -- Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html