summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Herring <robh@kernel.org>2015-12-08 20:44:15 (GMT)
committerArnd Bergmann <arnd@arndb.de>2015-12-15 22:53:10 (GMT)
commita8e2894c125f69aaea474592ebebd463bb7e1b0a (patch)
tree013e25d8eaa9af4b726ec8ef0eea638a06467e2b
parent31ade3b83e1821da5fbb2f11b5b3d4ab2ec39db8 (diff)
downloadlinux-a8e2894c125f69aaea474592ebebd463bb7e1b0a.tar.xz
ARM: versatile: add DT based PCI detection
Disable the Versatile PCI DT node when no PCI backplane is detected. This will prevent the Versatile PCI driver from probing when PCI is not populated. Signed-off-by: Rob Herring <robh@kernel.org> Cc: Russell King <linux@arm.linux.org.uk> Cc: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-rw-r--r--arch/arm/mach-versatile/versatile_dt.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/arch/arm/mach-versatile/versatile_dt.c b/arch/arm/mach-versatile/versatile_dt.c
index 7de3e92..a585758 100644
--- a/arch/arm/mach-versatile/versatile_dt.c
+++ b/arch/arm/mach-versatile/versatile_dt.c
@@ -22,15 +22,65 @@
*/
#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
+#include <linux/slab.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include "core.h"
+#define VERSATILE_SYS_PCICTL_OFFSET 0x44
+static void __iomem *versatile_sys_base;
+
+static void __init versatile_dt_pci_init(void)
+{
+ u32 val;
+ struct device_node *np;
+ struct property *newprop;
+
+ np = of_find_compatible_node(NULL, NULL, "arm,versatile-pci");
+ if (!np)
+ return;
+
+ /* Check if PCI backplane is detected */
+ val = readl(versatile_sys_base + VERSATILE_SYS_PCICTL_OFFSET);
+ if (val & 1) {
+ /*
+ * Enable PCI accesses. Note that the documentaton is
+ * inconsistent whether or not this is needed, but the old
+ * driver had it so we will keep it.
+ */
+ writel(1, versatile_sys_base + VERSATILE_SYS_PCICTL_OFFSET);
+ return;
+ }
+
+ newprop = kzalloc(sizeof(*newprop), GFP_KERNEL);
+ if (!newprop)
+ return;
+
+ newprop->name = kstrdup("status", GFP_KERNEL);
+ newprop->value = kstrdup("disabled", GFP_KERNEL);
+ newprop->length = sizeof("disabled");
+ of_update_property(np, newprop);
+
+ pr_info("Not plugged into PCI backplane!\n");
+}
+
static void __init versatile_dt_init(void)
{
+ struct device_node *np;
+
+ np = of_find_compatible_node(NULL, NULL, "arm,core-module-versatile");
+ if (np)
+ versatile_sys_base = of_iomap(np, 0);
+ WARN_ON(!versatile_sys_base);
+
+ versatile_dt_pci_init();
+
of_platform_populate(NULL, of_default_bus_match_table,
versatile_auxdata_lookup, NULL);
}