[POWERPC] New registration for common Xilinx Virtex ppc405 platform devices
authorGrant Likely <grant.likely@secretlab.ca>
Fri, 27 Apr 2007 19:50:01 +0000 (05:50 +1000)
committerPaul Mackerras <paulus@samba.org>
Mon, 30 Apr 2007 01:02:04 +0000 (11:02 +1000)
Currently virtex support in mainline make use of the infrastructure in
arch/ppc/syslib/ppc_sys.c for registering common devices on virtex ppc405
platforms.  The ppc_sys.c code is not well suited to the dynamic nature of
FPGA designs and makes adding new board ports more complex.  This patch
adds a new listing of common devices which does not depend on the ppc_sys.c
infrastructure.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Paul Mackerras <paulus@samba.org>
arch/ppc/syslib/virtex_devices.c [new file with mode: 0644]
arch/ppc/syslib/virtex_devices.h [new file with mode: 0644]

diff --git a/arch/ppc/syslib/virtex_devices.c b/arch/ppc/syslib/virtex_devices.c
new file mode 100644 (file)
index 0000000..1654678
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * Virtex hard ppc405 core common device listing
+ *
+ * Copyright 2005-2007 Secret Lab Technologies Ltd.
+ * Copyright 2005 Freescale Semiconductor Inc.
+ * Copyright 2002-2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/serial_8250.h>
+#include <syslib/virtex_devices.h>
+#include <platforms/4xx/xparameters/xparameters.h>
+#include <asm/io.h>
+
+/*
+ * UARTLITE: shortcut macro for single instance
+ */
+#define XPAR_UARTLITE(num) { \
+       .name = "uartlite", \
+       .id = num, \
+       .num_resources = 2, \
+       .resource = (struct resource[]) { \
+               { \
+                       .start = XPAR_UARTLITE_##num##_BASEADDR + 3, \
+                       .end = XPAR_UARTLITE_##num##_HIGHADDR, \
+                       .flags = IORESOURCE_MEM, \
+               }, \
+               { \
+                       .start = XPAR_INTC_0_UARTLITE_##num##_VEC_ID, \
+                       .flags = IORESOURCE_IRQ, \
+               }, \
+       }, \
+}
+
+/*
+ * Full UART: shortcut macro for single instance + platform data structure
+ */
+#define XPAR_UART(num) { \
+       .mapbase = XPAR_UARTNS550_##num##_BASEADDR + 3, \
+       .irq = XPAR_INTC_0_UARTNS550_##num##_VEC_ID, \
+       .iotype = UPIO_MEM, \
+       .uartclk = XPAR_UARTNS550_##num##_CLOCK_FREQ_HZ, \
+       .flags = UPF_BOOT_AUTOCONF, \
+       .regshift = 2, \
+}
+
+/*
+ * SystemACE: shortcut macro for single instance
+ */
+#define XPAR_SYSACE(num) { \
+       .name           = "xsysace", \
+       .id             = XPAR_SYSACE_##num##_DEVICE_ID, \
+       .num_resources  = 2, \
+       .resource = (struct resource[]) { \
+               { \
+                       .start  = XPAR_SYSACE_##num##_BASEADDR, \
+                       .end    = XPAR_SYSACE_##num##_HIGHADDR, \
+                       .flags  = IORESOURCE_MEM, \
+               }, \
+               { \
+                       .start  = XPAR_INTC_0_SYSACE_##num##_VEC_ID, \
+                       .flags  = IORESOURCE_IRQ, \
+               }, \
+       }, \
+}
+
+
+/* UART 8250 driver platform data table */
+struct plat_serial8250_port virtex_serial_platform_data[] = {
+#if defined(XPAR_UARTNS550_0_BASEADDR)
+       XPAR_UART(0),
+#endif
+#if defined(XPAR_UARTNS550_1_BASEADDR)
+       XPAR_UART(1),
+#endif
+#if defined(XPAR_UARTNS550_2_BASEADDR)
+       XPAR_UART(2),
+#endif
+#if defined(XPAR_UARTNS550_3_BASEADDR)
+       XPAR_UART(3),
+#endif
+#if defined(XPAR_UARTNS550_4_BASEADDR)
+       XPAR_UART(4),
+#endif
+#if defined(XPAR_UARTNS550_5_BASEADDR)
+       XPAR_UART(5),
+#endif
+#if defined(XPAR_UARTNS550_6_BASEADDR)
+       XPAR_UART(6),
+#endif
+#if defined(XPAR_UARTNS550_7_BASEADDR)
+       XPAR_UART(7),
+#endif
+       { }, /* terminated by empty record */
+};
+
+
+struct platform_device virtex_platform_devices[] = {
+       /* UARTLITE instances */
+#if defined(XPAR_UARTLITE_0_BASEADDR)
+       XPAR_UARTLITE(0),
+#endif
+#if defined(XPAR_UARTLITE_1_BASEADDR)
+       XPAR_UARTLITE(1),
+#endif
+#if defined(XPAR_UARTLITE_2_BASEADDR)
+       XPAR_UARTLITE(2),
+#endif
+#if defined(XPAR_UARTLITE_3_BASEADDR)
+       XPAR_UARTLITE(3),
+#endif
+#if defined(XPAR_UARTLITE_4_BASEADDR)
+       XPAR_UARTLITE(4),
+#endif
+#if defined(XPAR_UARTLITE_5_BASEADDR)
+       XPAR_UARTLITE(5),
+#endif
+#if defined(XPAR_UARTLITE_6_BASEADDR)
+       XPAR_UARTLITE(6),
+#endif
+#if defined(XPAR_UARTLITE_7_BASEADDR)
+       XPAR_UARTLITE(7),
+#endif
+
+       /* Full UART instances */
+#if defined(XPAR_UARTNS550_0_BASEADDR)
+       {
+               .name           = "serial8250",
+               .id             = 0,
+               .dev.platform_data = virtex_serial_platform_data,
+       },
+#endif
+
+       /* SystemACE instances */
+#if defined(XPAR_SYSACE_0_BASEADDR)
+       XPAR_SYSACE(0),
+#endif
+#if defined(XPAR_SYSACE_1_BASEADDR)
+       XPAR_SYSACE(1),
+#endif
+
+       /* ML300/403 reference design framebuffer */
+#if defined(XPAR_TFT_0_BASEADDR)
+       {
+               .name           = "xilinxfb",
+               .id             = 0,
+               .num_resources  = 1,
+               .resource = (struct resource[]) {
+                       {
+                               .start  = XPAR_TFT_0_BASEADDR,
+                               .end    = XPAR_TFT_0_BASEADDR+7,
+                               .flags  = IORESOURCE_IO,
+                       },
+               },
+       },
+#endif
+};
+
+/* Early serial support functions */
+static void __init
+virtex_early_serial_init(int num, struct plat_serial8250_port *pdata)
+{
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
+       struct uart_port serial_req;
+
+       memset(&serial_req, 0, sizeof(serial_req));
+       serial_req.mapbase      = pdata->mapbase;
+       serial_req.membase      = pdata->membase;
+       serial_req.irq          = pdata->irq;
+       serial_req.uartclk      = pdata->uartclk;
+       serial_req.regshift     = pdata->regshift;
+       serial_req.iotype       = pdata->iotype;
+       serial_req.flags        = pdata->flags;
+       gen550_init(num, &serial_req);
+#endif
+}
+
+void __init
+virtex_early_serial_map(void)
+{
+#ifdef CONFIG_SERIAL_8250
+       struct plat_serial8250_port *pdata;
+       int i = 0;
+
+       pdata = virtex_serial_platform_data;
+       while(pdata && pdata->flags) {
+               pdata->membase = ioremap(pdata->mapbase, 0x100);
+               virtex_early_serial_init(i, pdata);
+               pdata++;
+               i++;
+       }
+#endif /* CONFIG_SERIAL_8250 */
+}
+
+/*
+ * default fixup routine; do nothing and return success.
+ *
+ * Reimplement this routine in your custom board support file to
+ * override the default behaviour
+ */
+int __attribute__ ((weak))
+virtex_device_fixup(struct platform_device *dev)
+{
+       return 0;
+}
+
+static int __init virtex_init(void)
+{
+       struct platform_device *index = virtex_platform_devices;
+       unsigned int ret = 0;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(virtex_platform_devices); i++, index++) {
+               if (virtex_device_fixup(index) != 0)
+                       continue;
+
+               if (platform_device_register(index)) {
+                       ret = 1;
+                       printk(KERN_ERR "cannot register dev %s:%d\n",
+                              index->name, index->id);
+               }
+       }
+       return ret;
+}
+
+subsys_initcall(virtex_init);
diff --git a/arch/ppc/syslib/virtex_devices.h b/arch/ppc/syslib/virtex_devices.h
new file mode 100644 (file)
index 0000000..4a17dd3
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Common support header for virtex ppc405 platforms
+ *
+ * Copyright 2007 Secret Lab Technologies Ltd.
+ *
+ * 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 __ASM_VIRTEX_DEVICES_H__
+#define __ASM_VIRTEX_DEVICES_H__
+
+#include <linux/platform_device.h>
+
+void __init virtex_early_serial_map(void);
+
+/* Prototype for device fixup routine.  Implement this routine in the
+ * board specific fixup code and the generic setup code will call it for
+ * each device is the platform device list.
+ *
+ * If the hook returns a non-zero value, then the device will not get
+ * registered with the platform bus
+ */
+int virtex_device_fixup(struct platform_device *dev);
+
+#endif  /* __ASM_VIRTEX_DEVICES_H__ */