[ARM] 3215/1: Iomega NAS 100d (MACH_NAS100D) machine support
authorRod Whitby <rod@whitby.id.au>
Wed, 4 Jan 2006 17:17:11 +0000 (17:17 +0000)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Wed, 4 Jan 2006 17:17:11 +0000 (17:17 +0000)
Patch from Rod Whitby

This patch adds support for a new arm/ixp4xx machine - the Iomega NAS 100d network attached storage product.  The NAS100D is a consumer device containing a 266MHz Intel IXP420 processor, 16MB of flash, 64MB of RAM, a 160Gb internal IDE hard disk, and 802.11b/g wireless on an Atheros mini-PCI card.

Work on porting the latest 2.6.x kernel to this device is being done by
the NSLU2-Linux project (the same team who maintains the port to the
Linksys NSLU2 device).  In particular, the majority of this patch was
authored by Alessandro Zummo, based on the work done for MACH_NSLU2
support by the NSLU2-Linux core team of developers.

MACH_NAS100D (as implemented by this patch) can be enabled in jumbo
ixp4xx kernels without any affect on the other machines supported by
that kernel.

This patch applies cleanly against 2.6.15-rc7 and should be trivial to
apply to later kernel versions. It does not depend upon any other
patches.

Modified files (and number of lines inserted):
 arch/arm/mach-ixp4xx/Kconfig           |    8
 arch/arm/mach-ixp4xx/Makefile          |    1
 include/asm-arm/arch-ixp4xx/hardware.h |    1
 include/asm-arm/arch-ixp4xx/irqs.h     |    9
 include/asm-arm/arch-ixp4xx/nas100d.h  |   75
 arch/arm/mach-ixp4xx/nas100d-pci.c     |   77
 arch/arm/mach-ixp4xx/nas100d-power.c   |   69
 arch/arm/mach-ixp4xx/nas100d-setup.c   |  133

-- Rod Whitby (NSLU2-Linux project lead)

Signed-off-by: Rod Whitby <rod@whitby.id.au>
Signed-off-by: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/mach-ixp4xx/Kconfig
arch/arm/mach-ixp4xx/Makefile
arch/arm/mach-ixp4xx/nas100d-pci.c [new file with mode: 0644]
arch/arm/mach-ixp4xx/nas100d-power.c [new file with mode: 0644]
arch/arm/mach-ixp4xx/nas100d-setup.c [new file with mode: 0644]
include/asm-arm/arch-ixp4xx/hardware.h
include/asm-arm/arch-ixp4xx/irqs.h
include/asm-arm/arch-ixp4xx/nas100d.h [new file with mode: 0644]

index 385285851cb5cd6561f48cdd228201a3ffe94b76..daadc78e271b47cd9d9338b11a93b0cd4fd023c0 100644 (file)
@@ -71,6 +71,14 @@ config ARCH_PRPMC1100
          PrPCM1100 Processor Mezanine Module. For more information on
          this platform, see <file:Documentation/arm/IXP4xx>.
 
+config MACH_NAS100D
+       bool
+       prompt "NAS100D"
+       help
+         Say 'Y' here if you want your kernel to support Iomega's
+         NAS 100d device. For more information on this platform,
+         see http://www.nslu2-linux.org/wiki/NAS100d/HomePage
+
 #
 # Avila and IXDP share the same source for now. Will change in future
 #
index 7a15629c18d0bd397fdbb09d928133b2c5a28774..0471044fa179869a26ac07b41d63274dfd595c3b 100644 (file)
@@ -9,4 +9,5 @@ obj-$(CONFIG_MACH_IXDPG425)     += ixdpg425-pci.o coyote-setup.o
 obj-$(CONFIG_ARCH_ADI_COYOTE)  += coyote-pci.o coyote-setup.o
 obj-$(CONFIG_MACH_GTWX5715)    += gtwx5715-pci.o gtwx5715-setup.o
 obj-$(CONFIG_MACH_NSLU2)       += nslu2-pci.o nslu2-setup.o nslu2-power.o
+obj-$(CONFIG_MACH_NAS100D)     += nas100d-pci.o nas100d-setup.o nas100d-power.o
 
diff --git a/arch/arm/mach-ixp4xx/nas100d-pci.c b/arch/arm/mach-ixp4xx/nas100d-pci.c
new file mode 100644 (file)
index 0000000..9bd0294
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * arch/arm/mach-ixp4xx/nas100d-pci.c
+ *
+ * NAS 100d board-level PCI initialization
+ *
+ * based on ixdp425-pci.c:
+ *     Copyright (C) 2002 Intel Corporation.
+ *     Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * Maintainer: http://www.nslu2-linux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+void __init nas100d_pci_preinit(void)
+{
+       set_irq_type(IRQ_NAS100D_PCI_INTA, IRQT_LOW);
+       set_irq_type(IRQ_NAS100D_PCI_INTB, IRQT_LOW);
+       set_irq_type(IRQ_NAS100D_PCI_INTC, IRQT_LOW);
+       set_irq_type(IRQ_NAS100D_PCI_INTD, IRQT_LOW);
+       set_irq_type(IRQ_NAS100D_PCI_INTE, IRQT_LOW);
+
+       gpio_line_isr_clear(NAS100D_PCI_INTA_PIN);
+       gpio_line_isr_clear(NAS100D_PCI_INTB_PIN);
+       gpio_line_isr_clear(NAS100D_PCI_INTC_PIN);
+       gpio_line_isr_clear(NAS100D_PCI_INTD_PIN);
+       gpio_line_isr_clear(NAS100D_PCI_INTE_PIN);
+
+       ixp4xx_pci_preinit();
+}
+
+static int __init nas100d_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+       static int pci_irq_table[NAS100D_PCI_MAX_DEV][NAS100D_PCI_IRQ_LINES] =
+       {
+               { IRQ_NAS100D_PCI_INTA, -1, -1 },
+               { IRQ_NAS100D_PCI_INTB, -1, -1 },
+               { IRQ_NAS100D_PCI_INTC, IRQ_NAS100D_PCI_INTD, IRQ_NAS100D_PCI_INTE },
+       };
+
+       int irq = -1;
+
+       if (slot >= 1 && slot <= NAS100D_PCI_MAX_DEV &&
+               pin >= 1 && pin <= NAS100D_PCI_IRQ_LINES)
+               irq = pci_irq_table[slot-1][pin-1];
+
+       return irq;
+}
+
+struct hw_pci __initdata nas100d_pci = {
+       .nr_controllers = 1,
+       .preinit        = nas100d_pci_preinit,
+       .swizzle        = pci_std_swizzle,
+       .setup          = ixp4xx_setup,
+       .scan           = ixp4xx_scan_bus,
+       .map_irq        = nas100d_map_irq,
+};
+
+int __init nas100d_pci_init(void)
+{
+       if (machine_is_nas100d())
+               pci_common_init(&nas100d_pci);
+
+       return 0;
+}
+
+subsys_initcall(nas100d_pci_init);
diff --git a/arch/arm/mach-ixp4xx/nas100d-power.c b/arch/arm/mach-ixp4xx/nas100d-power.c
new file mode 100644 (file)
index 0000000..c74a190
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * arch/arm/mach-ixp4xx/nas100d-power.c
+ *
+ * NAS 100d Power/Reset driver
+ *
+ * Copyright (C) 2005 Tower Technologies
+ *
+ * based on nas100d-io.c
+ *  Copyright (C) 2004 Karen Spearel
+ *
+ * Author: Alessandro Zummo <a.zummo@towertech.it>
+ * Maintainers: http://www.nslu2-linux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/reboot.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach-types.h>
+
+extern void ctrl_alt_del(void);
+
+static irqreturn_t nas100d_reset_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+       /* Signal init to do the ctrlaltdel action, this will bypass init if
+        * it hasn't started and do a kernel_restart.
+        */
+       ctrl_alt_del();
+
+       return IRQ_HANDLED;
+}
+
+static int __init nas100d_power_init(void)
+{
+       if (!(machine_is_nas100d()))
+               return 0;
+
+       set_irq_type(NAS100D_RB_IRQ, IRQT_LOW);
+
+       gpio_line_isr_clear(NAS100D_RB_GPIO);
+
+       if (request_irq(NAS100D_RB_IRQ, &nas100d_reset_handler,
+               SA_INTERRUPT, "NAS100D reset button", NULL) < 0) {
+
+               printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
+                       NAS100D_RB_IRQ);
+
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static void __exit nas100d_power_exit(void)
+{
+       free_irq(NAS100D_RB_IRQ, NULL);
+}
+
+module_init(nas100d_power_init);
+module_exit(nas100d_power_exit);
+
+MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
+MODULE_DESCRIPTION("NAS100D Power/Reset driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c
new file mode 100644 (file)
index 0000000..bde9648
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * arch/arm/mach-ixp4xx/nas100d-setup.c
+ *
+ * NAS 100d board-setup
+ *
+ * based ixdp425-setup.c:
+ *      Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * Author: Alessandro Zummo <a.zummo@towertech.it>
+ * Author: Rod Whitby <rod@whitby.id.au>
+ * Maintainers: http://www.nslu2-linux.org/
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+static struct flash_platform_data nas100d_flash_data = {
+       .map_name               = "cfi_probe",
+       .width                  = 2,
+};
+
+static struct resource nas100d_flash_resource = {
+       .start                  = NAS100D_FLASH_BASE,
+       .end                    = NAS100D_FLASH_BASE + NAS100D_FLASH_SIZE,
+       .flags                  = IORESOURCE_MEM,
+};
+
+static struct platform_device nas100d_flash = {
+       .name                   = "IXP4XX-Flash",
+       .id                     = 0,
+       .dev.platform_data      = &nas100d_flash_data,
+       .num_resources          = 1,
+       .resource               = &nas100d_flash_resource,
+};
+
+static struct ixp4xx_i2c_pins nas100d_i2c_gpio_pins = {
+       .sda_pin                = NAS100D_SDA_PIN,
+       .scl_pin                = NAS100D_SCL_PIN,
+};
+
+static struct platform_device nas100d_i2c_controller = {
+       .name                   = "IXP4XX-I2C",
+       .id                     = 0,
+       .dev.platform_data      = &nas100d_i2c_gpio_pins,
+       .num_resources          = 0,
+};
+
+static struct resource nas100d_uart_resources[] = {
+       {
+               .start          = IXP4XX_UART1_BASE_PHYS,
+               .end            = IXP4XX_UART1_BASE_PHYS + 0x0fff,
+               .flags          = IORESOURCE_MEM,
+       },
+       {
+               .start          = IXP4XX_UART2_BASE_PHYS,
+               .end            = IXP4XX_UART2_BASE_PHYS + 0x0fff,
+               .flags          = IORESOURCE_MEM,
+       }
+};
+
+static struct plat_serial8250_port nas100d_uart_data[] = {
+       {
+               .mapbase        = IXP4XX_UART1_BASE_PHYS,
+               .membase        = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
+               .irq            = IRQ_IXP4XX_UART1,
+               .flags          = UPF_BOOT_AUTOCONF,
+               .iotype         = UPIO_MEM,
+               .regshift       = 2,
+               .uartclk        = IXP4XX_UART_XTAL,
+       },
+       {
+               .mapbase        = IXP4XX_UART2_BASE_PHYS,
+               .membase        = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
+               .irq            = IRQ_IXP4XX_UART2,
+               .flags          = UPF_BOOT_AUTOCONF,
+               .iotype         = UPIO_MEM,
+               .regshift       = 2,
+               .uartclk        = IXP4XX_UART_XTAL,
+       },
+       { }
+};
+
+static struct platform_device nas100d_uart = {
+       .name                   = "serial8250",
+       .id                     = PLAT8250_DEV_PLATFORM,
+       .dev.platform_data      = nas100d_uart_data,
+       .num_resources          = 2,
+       .resource               = nas100d_uart_resources,
+};
+
+static struct platform_device *nas100d_devices[] __initdata = {
+       &nas100d_i2c_controller,
+       &nas100d_flash,
+       &nas100d_uart,
+};
+
+static void nas100d_power_off(void)
+{
+       /* This causes the box to drop the power and go dead. */
+
+       /* enable the pwr cntl gpio */
+       gpio_line_config(NAS100D_PO_GPIO, IXP4XX_GPIO_OUT);
+
+       /* do the deed */
+       gpio_line_set(NAS100D_PO_GPIO, IXP4XX_GPIO_HIGH);
+}
+
+static void __init nas100d_init(void)
+{
+       ixp4xx_sys_init();
+
+       pm_power_off = nas100d_power_off;
+
+       platform_add_devices(nas100d_devices, ARRAY_SIZE(nas100d_devices));
+}
+
+MACHINE_START(NAS100D, "Iomega NAS 100d")
+       /* Maintainer: www.nslu2-linux.org */
+       .phys_ram       = PHYS_OFFSET,
+       .phys_io        = IXP4XX_PERIPHERAL_BASE_PHYS,
+       .io_pg_offst    = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC,
+       .boot_params    = 0x00000100,
+       .map_io         = ixp4xx_map_io,
+       .init_irq       = ixp4xx_init_irq,
+       .timer          = &ixp4xx_timer,
+       .init_machine   = nas100d_init,
+MACHINE_END
index cfb413c845f76334bca5b1a8be4c57976351eb18..6acb69c95ef9cfebf262034fc7a0c1998a410420 100644 (file)
@@ -45,5 +45,6 @@ extern unsigned int processor_id;
 #include "coyote.h"
 #include "prpmc1100.h"
 #include "nslu2.h"
+#include "nas100d.h"
 
 #endif  /* _ASM_ARCH_HARDWARE_H */
index 2cf4930372bca1ad7e5880b376386d2d7a9628c3..f24b763ca18e406cf698d7096534ddb1f0282137 100644 (file)
 #define        IRQ_NSLU2_PCI_INTB      IRQ_IXP4XX_GPIO10
 #define        IRQ_NSLU2_PCI_INTC      IRQ_IXP4XX_GPIO9
 
+/*
+ * NAS100D board IRQs
+ */
+#define        IRQ_NAS100D_PCI_INTA    IRQ_IXP4XX_GPIO11
+#define        IRQ_NAS100D_PCI_INTB    IRQ_IXP4XX_GPIO10
+#define        IRQ_NAS100D_PCI_INTC    IRQ_IXP4XX_GPIO9
+#define        IRQ_NAS100D_PCI_INTD    IRQ_IXP4XX_GPIO8
+#define        IRQ_NAS100D_PCI_INTE    IRQ_IXP4XX_GPIO7
+
 #endif
diff --git a/include/asm-arm/arch-ixp4xx/nas100d.h b/include/asm-arm/arch-ixp4xx/nas100d.h
new file mode 100644 (file)
index 0000000..ce7a86a
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * include/asm-arm/arch-ixp4xx/nas100d.h
+ *
+ * NAS100D platform specific definitions
+ *
+ * Copyright (c) 2005 Tower Technologies
+ *
+ * Author: Alessandro Zummo <a.zummo@towertech.it>
+ *
+ * based on ixdp425.h:
+ *     Copyright 2004 (c) MontaVista, Software, Inc.
+ *
+ * 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_ARCH_HARDWARE_H__
+#error "Do not include this directly, instead #include <asm/hardware.h>"
+#endif
+
+#define NAS100D_FLASH_BASE     IXP4XX_EXP_BUS_CS0_BASE_PHYS
+#define NAS100D_FLASH_SIZE     IXP4XX_EXP_BUS_CSX_REGION_SIZE
+
+#define NAS100D_SDA_PIN                6
+#define NAS100D_SCL_PIN                5
+
+/*
+ * NAS100D PCI IRQs
+ */
+#define NAS100D_PCI_MAX_DEV    3
+#define NAS100D_PCI_IRQ_LINES  3
+
+
+/* PCI controller GPIO to IRQ pin mappings */
+#define NAS100D_PCI_INTA_PIN   11
+#define NAS100D_PCI_INTB_PIN   10
+#define NAS100D_PCI_INTC_PIN   9
+#define NAS100D_PCI_INTD_PIN   8
+#define NAS100D_PCI_INTE_PIN   7
+
+/* GPIO */
+
+#define NAS100D_GPIO0           0
+#define NAS100D_GPIO1           1
+#define NAS100D_GPIO2           2
+#define NAS100D_GPIO3           3
+#define NAS100D_GPIO4           4
+#define NAS100D_GPIO5           5
+#define NAS100D_GPIO6           6
+#define NAS100D_GPIO7           7
+#define NAS100D_GPIO8           8
+#define NAS100D_GPIO9           9
+#define NAS100D_GPIO10          10
+#define NAS100D_GPIO11          11
+#define NAS100D_GPIO12          12
+#define NAS100D_GPIO13          13
+#define NAS100D_GPIO14          14
+#define NAS100D_GPIO15          15
+
+
+/* Buttons */
+
+#define NAS100D_PB_GPIO         NAS100D_GPIO14
+#define NAS100D_RB_GPIO         NAS100D_GPIO4
+#define NAS100D_PO_GPIO         NAS100D_GPIO12   /* power off */
+
+#define NAS100D_PB_IRQ          IRQ_IXP4XX_GPIO14
+#define NAS100D_RB_IRQ          IRQ_IXP4XX_GPIO4
+
+/*
+#define NAS100D_PB_BM           (1L << NAS100D_PB_GPIO)
+#define NAS100D_PO_BM           (1L << NAS100D_PO_GPIO)
+#define NAS100D_RB_BM           (1L << NAS100D_RB_GPIO)
+*/