atheros: convert AR5312 GPIO code to platform driver
[openwrt/openwrt.git] / target / linux / atheros / patches-3.14 / 100-board.patch
index 4840813669cb3d6ea82a43cc9ab1b2ed2bc13d64..8ffa91caffa85c5154ced8c5c3cd5378a3afb95f 100644 (file)
 +load-$(CONFIG_ATHEROS_AR231X)          += 0xffffffff80041000
 --- /dev/null
 +++ b/arch/mips/ar231x/Kconfig
-@@ -0,0 +1,16 @@
-+config ATHEROS_AR5312
+@@ -0,0 +1,9 @@
++config SOC_AR5312
 +      bool "Atheros 5312/2312+ support"
 +      depends on ATHEROS_AR231X
 +      default y
 +
-+config ATHEROS_AR2315
++config SOC_AR2315
 +      bool "Atheros 2315+ support"
 +      depends on ATHEROS_AR231X
-+      select DMA_NONCOHERENT
-+      select CEVT_R4K
-+      select CSRC_R4K
-+      select IRQ_CPU
-+      select SYS_HAS_CPU_MIPS32_R1
-+      select SYS_SUPPORTS_32BIT_KERNEL
-+      select SYS_SUPPORTS_BIG_ENDIAN
 +      default y
 --- /dev/null
 +++ b/arch/mips/ar231x/Makefile
@@ -80,8 +73,8 @@
 +#
 +
 +obj-y += board.o prom.o devices.o
-+obj-$(CONFIG_ATHEROS_AR5312) += ar5312.o
-+obj-$(CONFIG_ATHEROS_AR2315) += ar2315.o
++obj-$(CONFIG_SOC_AR5312) += ar5312.o
++obj-$(CONFIG_SOC_AR2315) += ar2315.o
 --- /dev/null
 +++ b/arch/mips/ar231x/board.c
 @@ -0,0 +1,229 @@
 +/* #define cpu_has_mcheck             ? */
 +#define cpu_has_ejtag                 1
 +
-+#if !defined(CONFIG_ATHEROS_AR5312)
++#if !defined(CONFIG_SOC_AR5312)
 +#  define cpu_has_llsc                        1
 +#else
 +/*
 +
 +#define cpu_has_mips32r1              1
 +
-+#if !defined(CONFIG_ATHEROS_AR5312)
++#if !defined(CONFIG_SOC_AR5312)
 +#  define cpu_has_mips32r2            1
 +#endif
 +
 +#endif /* __ASM_MACH_AR231X_CPU_FEATURE_OVERRIDES_H */
 --- /dev/null
 +++ b/arch/mips/include/asm/mach-ar231x/dma-coherence.h
-@@ -0,0 +1,77 @@
+@@ -0,0 +1,76 @@
 +/*
 + * This file is subject to the terms and conditions of the GNU General Public
 + * License.  See the file "COPYING" in the main directory of this archive
 +#ifndef __ASM_MACH_AR231X_DMA_COHERENCE_H
 +#define __ASM_MACH_AR231X_DMA_COHERENCE_H
 +
-+#define PCI_DMA_OFFSET        0x20000000
-+
 +#include <linux/device.h>
++#include <ar2315_regs.h>
 +
 +static inline dma_addr_t ar231x_dev_offset(struct device *dev)
 +{
 +      extern struct bus_type pci_bus_type;
 +
 +      if (dev && dev->bus == &pci_bus_type)
-+              return PCI_DMA_OFFSET;
++              return AR2315_PCI_HOST_SDRAM_BASEADDR;
 +#endif
 +      return 0;
 +}
 +#endif /* __ASM_MACH_AR231X_DMA_COHERENCE_H */
 --- /dev/null
 +++ b/arch/mips/include/asm/mach-ar231x/gpio.h
-@@ -0,0 +1,30 @@
+@@ -0,0 +1,16 @@
 +#ifndef __ASM_MACH_AR231X_GPIO_H
 +#define __ASM_MACH_AR231X_GPIO_H
 +
-+#include <ar231x.h>
++#include <asm-generic/gpio.h>
 +
 +#define gpio_get_value __gpio_get_value
 +#define gpio_set_value __gpio_set_value
 +#define gpio_cansleep __gpio_cansleep
++#define gpio_to_irq __gpio_to_irq
 +
-+/*
-+ * Wrappers for the generic GPIO layer
-+ */
-+
-+/* not sure if these are used? */
-+
-+/* Returns IRQ to attach for gpio.  Unchecked function */
-+static inline int gpio_to_irq(unsigned gpio)
-+{
-+      return AR231X_GPIO_IRQ(gpio);
-+}
-+
-+/* Returns gpio for IRQ attached.  Unchecked function */
 +static inline int irq_to_gpio(unsigned irq)
 +{
-+      return irq - AR231X_GPIO_IRQ(0);
++      return -EINVAL;
 +}
 +
-+#include <asm-generic/gpio.h> /* cansleep wrappers */
-+
 +#endif        /* __ASM_MACH_AR231X_GPIO_H */
 --- /dev/null
 +++ b/arch/mips/include/asm/mach-ar231x/reset.h
 +#endif /* __ASM_MACH_AR231X_WAR_H */
 --- /dev/null
 +++ b/arch/mips/include/asm/mach-ar231x/ar2315_regs.h
-@@ -0,0 +1,614 @@
+@@ -0,0 +1,630 @@
 +/*
 + * Register definitions for AR2315+
 + *
 +/*
 + * Miscellaneous interrupts, which share IP2.
 + */
-+#define AR2315_MISC_IRQ_NONE          (AR231X_MISC_IRQ_BASE+0)
-+#define AR2315_MISC_IRQ_UART0         (AR231X_MISC_IRQ_BASE+1)
-+#define AR2315_MISC_IRQ_I2C_RSVD      (AR231X_MISC_IRQ_BASE+2)
-+#define AR2315_MISC_IRQ_SPI           (AR231X_MISC_IRQ_BASE+3)
-+#define AR2315_MISC_IRQ_AHB           (AR231X_MISC_IRQ_BASE+4)
-+#define AR2315_MISC_IRQ_APB           (AR231X_MISC_IRQ_BASE+5)
-+#define AR2315_MISC_IRQ_TIMER         (AR231X_MISC_IRQ_BASE+6)
-+#define AR2315_MISC_IRQ_GPIO          (AR231X_MISC_IRQ_BASE+7)
-+#define AR2315_MISC_IRQ_WATCHDOG      (AR231X_MISC_IRQ_BASE+8)
-+#define AR2315_MISC_IRQ_IR_RSVD               (AR231X_MISC_IRQ_BASE+9)
-+#define AR2315_MISC_IRQ_COUNT         10
++#define AR2315_MISC_IRQ_UART0         (AR231X_MISC_IRQ_BASE+0)
++#define AR2315_MISC_IRQ_I2C_RSVD      (AR231X_MISC_IRQ_BASE+1)
++#define AR2315_MISC_IRQ_SPI           (AR231X_MISC_IRQ_BASE+2)
++#define AR2315_MISC_IRQ_AHB           (AR231X_MISC_IRQ_BASE+3)
++#define AR2315_MISC_IRQ_APB           (AR231X_MISC_IRQ_BASE+4)
++#define AR2315_MISC_IRQ_TIMER         (AR231X_MISC_IRQ_BASE+5)
++#define AR2315_MISC_IRQ_GPIO          (AR231X_MISC_IRQ_BASE+6)
++#define AR2315_MISC_IRQ_WATCHDOG      (AR231X_MISC_IRQ_BASE+7)
++#define AR2315_MISC_IRQ_IR_RSVD               (AR231X_MISC_IRQ_BASE+8)
++#define AR2315_MISC_IRQ_COUNT         9
++
++/*
++ * PCI interrupts, which share IP5
++ * Keep ordered according to AR2315_PCI_INT_XXX bits
++ */
++#define AR2315_PCI_IRQ_BASE           0x50
++#define AR2315_PCI_IRQ_EXT            (AR2315_PCI_IRQ_BASE+0)
++#define AR2315_PCI_IRQ_ABORT          (AR2315_PCI_IRQ_BASE+1)
++#define AR2315_PCI_IRQ_COUNT          2
++#define AR2315_PCI_IRQ_SHIFT          25      /* in AR2315_PCI_INT_STATUS */
 +
 +/*
 + * Address map
 +#define AR2315_UART0            0x11100000      /* UART MMR */
 +#define AR2315_SPI_MMR          0x11300000      /* SPI FLASH MMR */
 +#define AR2315_PCIEXT           0x80000000      /* pci external */
++#define AR2315_PCIEXT_SZ      0x40000000
 +
 +/* MII registers offset inside Ethernet MMR region */
 +#define AR2315_ENET0_MII      (AR2315_ENET0 + 0x14)
 +
 +#define AR2315_PCI_OUT_PTR      (AR2315_PCI + 0x0408)
 +
-+#define AR2315_PCI_INT_STATUS   (AR2315_PCI + 0x0500)   /* write one to clr */
-+#define AR2315_PCI_TXINT        0x00000001      /* Desc In Completed */
-+#define AR2315_PCI_TXOK         0x00000002      /* Desc In OK */
-+#define AR2315_PCI_TXERR        0x00000004      /* Desc In ERR */
-+#define AR2315_PCI_TXEOL        0x00000008      /* Desc In End-of-List */
-+#define AR2315_PCI_RXINT        0x00000010      /* Desc Out Completed */
-+#define AR2315_PCI_RXOK         0x00000020      /* Desc Out OK */
-+#define AR2315_PCI_RXERR        0x00000040      /* Desc Out ERR */
-+#define AR2315_PCI_RXEOL        0x00000080      /* Desc Out EOL */
-+#define AR2315_PCI_TXOOD        0x00000200      /* Desc In Out-of-Desc */
-+#define AR2315_PCI_MASK         0x0000FFFF      /* Desc Mask */
-+#define AR2315_PCI_EXT_INT      0x02000000
-+#define AR2315_PCI_ABORT_INT    0x04000000
-+
-+#define AR2315_PCI_INT_MASK     (AR2315_PCI + 0x0504)  /* same as INT_STATUS */
-+
-+#define AR2315_PCI_INTEN_REG    (AR2315_PCI + 0x0508)
-+#define AR2315_PCI_INT_DISABLE  0x00            /* disable pci interrupts */
-+#define AR2315_PCI_INT_ENABLE   0x01            /* enable pci interrupts */
++#define AR2315_PCI_ISR          (AR2315_PCI + 0x0500)   /* write one to clr */
++#define AR2315_PCI_INT_TX       0x00000001      /* Desc In Completed */
++#define AR2315_PCI_INT_TXOK     0x00000002      /* Desc In OK */
++#define AR2315_PCI_INT_TXERR    0x00000004      /* Desc In ERR */
++#define AR2315_PCI_INT_TXEOL    0x00000008      /* Desc In End-of-List */
++#define AR2315_PCI_INT_RX       0x00000010      /* Desc Out Completed */
++#define AR2315_PCI_INT_RXOK     0x00000020      /* Desc Out OK */
++#define AR2315_PCI_INT_RXERR    0x00000040      /* Desc Out ERR */
++#define AR2315_PCI_INT_RXEOL    0x00000080      /* Desc Out EOL */
++#define AR2315_PCI_INT_TXOOD    0x00000200      /* Desc In Out-of-Desc */
++#define AR2315_PCI_INT_DESCMASK 0x0000FFFF      /* Desc Mask */
++#define AR2315_PCI_INT_EXT      0x02000000      /* Extern PCI INTA */
++#define AR2315_PCI_INT_ABORT    0x04000000      /* PCI bus abort event */
++
++#define AR2315_PCI_IMR          (AR2315_PCI + 0x0504)  /* mask _PCI_ISR bits */
++
++#define AR2315_PCI_IER          (AR2315_PCI + 0x0508)  /* global PCI int en */
++#define AR2315_PCI_IER_DISABLE  0x00            /* disable pci interrupts */
++#define AR2315_PCI_IER_ENABLE   0x01            /* enable pci interrupts */
 +
 +#define AR2315_PCI_HOST_IN_EN   (AR2315_PCI + 0x0800)
 +#define AR2315_PCI_HOST_IN_DIS  (AR2315_PCI + 0x0804)
 +#define AR2315_IRCFG_SEQ_END_WIN_THRESH       0x001f0000
 +#define AR2315_IRCFG_NUM_BACKOFF_WORDS        0x01e00000
 +
-+#define HOST_PCI_DEV_ID         3
-+#define HOST_PCI_MBAR0          0x10000000
-+#define HOST_PCI_MBAR1          0x20000000
-+#define HOST_PCI_MBAR2          0x30000000
++/*
++ * We need some arbitrary non-zero value to be programmed to the BAR1 register
++ * of PCI host controller to enable DMA. The same value should be used as the
++ * offset to calculate the physical address of DMA buffer for PCI devices.
++ */
++#define AR2315_PCI_HOST_SDRAM_BASEADDR        0x20000000
 +
-+#define HOST_PCI_SDRAM_BASEADDR HOST_PCI_MBAR1
-+#define PCI_DEVICE_MEM_SPACE    0x800000
++/* ??? access BAR */
++#define AR2315_PCI_HOST_MBAR0         0x10000000
++/* RAM access BAR */
++#define AR2315_PCI_HOST_MBAR1         AR2315_PCI_HOST_SDRAM_BASEADDR
++/* ??? access BAR */
++#define AR2315_PCI_HOST_MBAR2         0x30000000
 +
 +#endif /* __ASM_MACH_AR231X_AR2315_REGS_H */
 --- /dev/null
 +++ b/arch/mips/include/asm/mach-ar231x/ar5312_regs.h
-@@ -0,0 +1,249 @@
+@@ -0,0 +1,235 @@
 +/*
 + * This file is subject to the terms and conditions of the GNU General Public
 + * License.  See the file "COPYING" in the main directory of this archive
 +/*
 + * Miscellaneous interrupts, which share IP6.
 + */
-+#define AR5312_MISC_IRQ_NONE          (AR231X_MISC_IRQ_BASE+0)
-+#define AR5312_MISC_IRQ_TIMER         (AR231X_MISC_IRQ_BASE+1)
-+#define AR5312_MISC_IRQ_AHB_PROC      (AR231X_MISC_IRQ_BASE+2)
-+#define AR5312_MISC_IRQ_AHB_DMA               (AR231X_MISC_IRQ_BASE+3)
-+#define AR5312_MISC_IRQ_GPIO          (AR231X_MISC_IRQ_BASE+4)
-+#define AR5312_MISC_IRQ_UART0         (AR231X_MISC_IRQ_BASE+5)
-+#define AR5312_MISC_IRQ_UART0_DMA     (AR231X_MISC_IRQ_BASE+6)
-+#define AR5312_MISC_IRQ_WATCHDOG      (AR231X_MISC_IRQ_BASE+7)
-+#define AR5312_MISC_IRQ_LOCAL         (AR231X_MISC_IRQ_BASE+8)
-+#define AR5312_MISC_IRQ_SPI           (AR231X_MISC_IRQ_BASE+9)
-+#define AR5312_MISC_IRQ_COUNT         10
++#define AR5312_MISC_IRQ_TIMER         (AR231X_MISC_IRQ_BASE+0)
++#define AR5312_MISC_IRQ_AHB_PROC      (AR231X_MISC_IRQ_BASE+1)
++#define AR5312_MISC_IRQ_AHB_DMA               (AR231X_MISC_IRQ_BASE+2)
++#define AR5312_MISC_IRQ_GPIO          (AR231X_MISC_IRQ_BASE+3)
++#define AR5312_MISC_IRQ_UART0         (AR231X_MISC_IRQ_BASE+4)
++#define AR5312_MISC_IRQ_UART0_DMA     (AR231X_MISC_IRQ_BASE+5)
++#define AR5312_MISC_IRQ_WATCHDOG      (AR231X_MISC_IRQ_BASE+6)
++#define AR5312_MISC_IRQ_LOCAL         (AR231X_MISC_IRQ_BASE+7)
++#define AR5312_MISC_IRQ_SPI           (AR231X_MISC_IRQ_BASE+8)
++#define AR5312_MISC_IRQ_COUNT         9
 +
 +/*
 + * Address Map
 +#define AR5312_WD_CTRL_RESET             0x0002
 +
 +/* AR5312_ISR register bit field definitions */
-+#define AR5312_ISR_NONE               0x0000
 +#define AR5312_ISR_TIMER      0x0001
 +#define AR5312_ISR_AHBPROC    0x0002
 +#define AR5312_ISR_AHBDMA     0x0004
 +#define MEM_CFG1_AC1    0x00007000      /* bank 1: SDRAM addr check (added) */
 +#define MEM_CFG1_AC1_S  12
 +
-+/* GPIO Address Map */
 +#define AR5312_GPIO         (AR5312_APBBASE  + 0x2000)
-+#define AR5312_GPIO_DO      (AR5312_GPIO + 0x00)        /* output register */
-+#define AR5312_GPIO_DI      (AR5312_GPIO + 0x04)        /* intput register */
-+#define AR5312_GPIO_CR      (AR5312_GPIO + 0x08)        /* control register */
-+
-+/* GPIO Control Register bit field definitions */
-+#define AR5312_GPIO_CR_M(x)    (1 << (x))               /* mask for i/o */
-+#define AR5312_GPIO_CR_O(x)    (0 << (x))               /* mask for output */
-+#define AR5312_GPIO_CR_I(x)    (1 << (x))               /* mask for input */
-+#define AR5312_GPIO_CR_INT(x)  (1 << ((x)+8))           /* mask for interrupt*/
-+#define AR5312_GPIO_CR_UART(x) (1 << ((x)+16))          /* uart multiplex */
-+#define AR5312_NUM_GPIO               8
 +
 +#endif        /* __ASM_MACH_AR231X_AR5312_REGS_H */
 --- /dev/null
 +++ b/arch/mips/ar231x/ar5312.c
-@@ -0,0 +1,534 @@
+@@ -0,0 +1,476 @@
 +/*
 + * This file is subject to the terms and conditions of the GNU General Public
 + * License.  See the file "COPYING" in the main directory of this archive
 +                                       ar231x_read_reg(AR5312_IMR);
 +
 +      if (ar231x_misc_intrs & AR5312_ISR_TIMER) {
-+              do_IRQ(AR5312_MISC_IRQ_TIMER);
++              generic_handle_irq(AR5312_MISC_IRQ_TIMER);
 +              (void)ar231x_read_reg(AR5312_TIMER);
 +      } else if (ar231x_misc_intrs & AR5312_ISR_AHBPROC)
-+              do_IRQ(AR5312_MISC_IRQ_AHB_PROC);
++              generic_handle_irq(AR5312_MISC_IRQ_AHB_PROC);
 +      else if ((ar231x_misc_intrs & AR5312_ISR_UART0))
-+              do_IRQ(AR5312_MISC_IRQ_UART0);
++              generic_handle_irq(AR5312_MISC_IRQ_UART0);
 +      else if (ar231x_misc_intrs & AR5312_ISR_WD)
-+              do_IRQ(AR5312_MISC_IRQ_WATCHDOG);
++              generic_handle_irq(AR5312_MISC_IRQ_WATCHDOG);
 +      else
-+              do_IRQ(AR5312_MISC_IRQ_NONE);
++              spurious_interrupt();
 +}
 +
 +static asmlinkage void
 +              do_IRQ(AR5312_IRQ_MISC_INTRS);
 +      else if (pending & CAUSEF_IP7)
 +              do_IRQ(AR231X_IRQ_CPU_CLOCK);
++      else
++              spurious_interrupt();
 +}
 +
 +/* Enable the specified AR5312_MISC_IRQ interrupt */
 +      unsigned int imr;
 +
 +      imr = ar231x_read_reg(AR5312_IMR);
-+      imr |= (1 << (d->irq - AR231X_MISC_IRQ_BASE - 1));
++      imr |= 1 << (d->irq - AR231X_MISC_IRQ_BASE);
 +      ar231x_write_reg(AR5312_IMR, imr);
 +}
 +
 +      unsigned int imr;
 +
 +      imr = ar231x_read_reg(AR5312_IMR);
-+      imr &= ~(1 << (d->irq - AR231X_MISC_IRQ_BASE - 1));
++      imr &= ~(1 << (d->irq - AR231X_MISC_IRQ_BASE));
 +      ar231x_write_reg(AR5312_IMR, imr);
 +      ar231x_read_reg(AR5312_IMR); /* flush write buffer */
 +}
 +      irq_set_chained_handler(AR5312_IRQ_MISC_INTRS, ar5312_misc_irq_handler);
 +}
 +
-+/*
-+ * gpiolib implementations
-+ */
-+static int
-+ar5312_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
-+{
-+      return (ar231x_read_reg(AR5312_GPIO_DI) >> gpio) & 1;
-+}
-+
-+static void
-+ar5312_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value)
-+{
-+      u32 reg = ar231x_read_reg(AR5312_GPIO_DO);
-+
-+      reg = value ? reg | (1 << gpio) : reg & ~(1 << gpio);
-+      ar231x_write_reg(AR5312_GPIO_DO, reg);
-+}
-+
-+static int
-+ar5312_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
-+{
-+      ar231x_mask_reg(AR5312_GPIO_CR, 0, 1 << gpio);
-+      return 0;
-+}
-+
-+static int
-+ar5312_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value)
-+{
-+      ar231x_mask_reg(AR5312_GPIO_CR, 1 << gpio, 0);
-+      ar5312_gpio_set_value(chip, gpio, value);
-+      return 0;
-+}
-+
-+static struct gpio_chip ar5312_gpio_chip = {
-+      .label                  = "ar5312-gpio",
-+      .direction_input        = ar5312_gpio_direction_input,
-+      .direction_output       = ar5312_gpio_direction_output,
-+      .set                    = ar5312_gpio_set_value,
-+      .get                    = ar5312_gpio_get_value,
-+      .base                   = 0,
-+      .ngpio                  = AR5312_NUM_GPIO, /* 8 */
-+};
-+
-+/* end of gpiolib */
-+
 +static void ar5312_device_reset_set(u32 mask)
 +{
 +      u32 val;
 +      mips_hpt_frequency = ar5312_cpu_frequency() / 2;
 +}
 +
-+static int __init
-+ar5312_gpio_init(void)
-+{
-+      int ret = gpiochip_add(&ar5312_gpio_chip);
-+
-+      if (ret) {
-+              pr_err("%s: failed to add gpiochip\n", ar5312_gpio_chip.label);
-+              return ret;
-+      }
-+      pr_info("%s: registered %d GPIOs\n", ar5312_gpio_chip.label,
-+              ar5312_gpio_chip.ngpio);
-+      return ret;
-+}
-+
 +void __init
 +ar5312_prom_init(void)
 +{
 +      devid >>= AR5312_REV_WMAC_MIN_S;
 +      devid &= AR5312_REV_CHIP;
 +      ar231x_board.devid = (u16)devid;
-+      ar5312_gpio_init();
 +}
 +
 +void __init
 +
 --- /dev/null
 +++ b/arch/mips/ar231x/ar2315.c
-@@ -0,0 +1,556 @@
+@@ -0,0 +1,570 @@
 +/*
 + * This file is subject to the terms and conditions of the GNU General Public
 + * License.  See the file "COPYING" in the main directory of this archive
 +              return;
 +
 +      if (bit >= 0)
-+              do_IRQ(AR231X_GPIO_IRQ_BASE + bit);
++              generic_handle_irq(AR231X_GPIO_IRQ_BASE + bit);
 +}
 +
 +static void ar2315_misc_irq_handler(unsigned irq, struct irq_desc *desc)
 +                               ar231x_read_reg(AR2315_IMR);
 +
 +      if (misc_intr & AR2315_ISR_SPI)
-+              do_IRQ(AR2315_MISC_IRQ_SPI);
++              generic_handle_irq(AR2315_MISC_IRQ_SPI);
 +      else if (misc_intr & AR2315_ISR_TIMER)
-+              do_IRQ(AR2315_MISC_IRQ_TIMER);
++              generic_handle_irq(AR2315_MISC_IRQ_TIMER);
 +      else if (misc_intr & AR2315_ISR_AHB)
-+              do_IRQ(AR2315_MISC_IRQ_AHB);
++              generic_handle_irq(AR2315_MISC_IRQ_AHB);
 +      else if (misc_intr & AR2315_ISR_GPIO)
-+              do_IRQ(AR2315_MISC_IRQ_GPIO);
++              generic_handle_irq(AR2315_MISC_IRQ_GPIO);
 +      else if (misc_intr & AR2315_ISR_UART0)
-+              do_IRQ(AR2315_MISC_IRQ_UART0);
++              generic_handle_irq(AR2315_MISC_IRQ_UART0);
 +      else if (misc_intr & AR2315_ISR_WD) {
 +              ar231x_write_reg(AR2315_ISR, AR2315_ISR_WD);
-+              do_IRQ(AR2315_MISC_IRQ_WATCHDOG);
++              generic_handle_irq(AR2315_MISC_IRQ_WATCHDOG);
 +      } else
-+              do_IRQ(AR2315_MISC_IRQ_NONE);
++              spurious_interrupt();
 +}
 +
 +/*
 +              do_IRQ(AR2315_IRQ_MISC_INTRS);
 +      else if (pending & CAUSEF_IP7)
 +              do_IRQ(AR231X_IRQ_CPU_CLOCK);
++      else
++              spurious_interrupt();
 +}
 +
 +static void ar2315_set_gpiointmask(int gpio, int level)
 +      unsigned int imr;
 +
 +      imr = ar231x_read_reg(AR2315_IMR);
-+      imr |= 1 << (d->irq - AR231X_MISC_IRQ_BASE - 1);
++      imr |= 1 << (d->irq - AR231X_MISC_IRQ_BASE);
 +      ar231x_write_reg(AR2315_IMR, imr);
 +}
 +
 +      unsigned int imr;
 +
 +      imr = ar231x_read_reg(AR2315_IMR);
-+      imr &= ~(1 << (d->irq - AR231X_MISC_IRQ_BASE - 1));
++      imr &= ~(1 << (d->irq - AR231X_MISC_IRQ_BASE));
 +      ar231x_write_reg(AR2315_IMR, imr);
 +}
 +
 +      return 0;
 +}
 +
++static int ar2315_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
++{
++      return AR231X_GPIO_IRQ_BASE + gpio;
++}
++
 +static struct gpio_chip ar2315_gpio_chip = {
 +      .label                  = "ar2315-gpio",
 +      .direction_input        = ar2315_gpio_direction_input,
 +      .direction_output       = ar2315_gpio_direction_output,
 +      .set                    = ar2315_gpio_set_value,
 +      .get                    = ar2315_gpio_get_value,
++      .to_irq                 = ar2315_gpio_to_irq,
 +      .base                   = 0,
 +      .ngpio                  = AR2315_NUM_GPIO, /* 22 */
 +};
 +      /* Detect the hardware based on the device ID */
 +      devid = ar231x_read_reg(AR2315_SREV) & AR2315_REV_CHIP;
 +      switch (devid) {
++      case 0x91:      /* Need to check */
++              ar231x_devtype = DEV_TYPE_AR2318;
++              break;
 +      case 0x90:
-+      case 0x91:
 +              ar231x_devtype = DEV_TYPE_AR2317;
 +              break;
++      case 0x87:
++              ar231x_devtype = DEV_TYPE_AR2316;
++              break;
++      case 0x86:
 +      default:
 +              ar231x_devtype = DEV_TYPE_AR2315;
 +              break;
 +#ifndef __AR2315_H
 +#define __AR2315_H
 +
-+#ifdef CONFIG_ATHEROS_AR2315
++#ifdef CONFIG_SOC_AR2315
 +
 +void ar2315_irq_init(void);
 +int ar2315_init_devices(void);
 +#ifndef __AR5312_H
 +#define __AR5312_H
 +
-+#ifdef CONFIG_ATHEROS_AR5312
++#ifdef CONFIG_SOC_AR5312
 +
 +void ar5312_irq_init(void);
 +int ar5312_init_devices(void);
 +#endif
 --- /dev/null
 +++ b/arch/mips/include/asm/mach-ar231x/ar231x.h
-@@ -0,0 +1,43 @@
+@@ -0,0 +1,38 @@
 +#ifndef __ASM_MACH_AR231X_H
 +#define __ASM_MACH_AR231X_H
 +
 +#define AR231X_GPIO_IRQ_BASE          0x30
 +
 +/* Software's idea of interrupts handled by "CPU Interrupt Controller" */
-+#define AR231X_IRQ_NONE               (MIPS_CPU_IRQ_BASE+0)
 +#define AR231X_IRQ_CPU_CLOCK  (MIPS_CPU_IRQ_BASE+7) /* C0_CAUSE: 0x8000 */
 +
-+/* GPIO Interrupts, share ARXXXX_MISC_IRQ_GPIO */
-+#define AR231X_GPIO_IRQ_NONE            (AR231X_GPIO_IRQ_BASE+0)
-+#define AR231X_GPIO_IRQ(n)              (AR231X_GPIO_IRQ_BASE+n)
-+
 +static inline u32
 +ar231x_read_reg(u32 reg)
 +{
 +#endif        /* __ASM_MACH_AR231X_H */
 --- /dev/null
 +++ b/arch/mips/ar231x/devices.h
-@@ -0,0 +1,38 @@
+@@ -0,0 +1,39 @@
 +#ifndef __AR231X_DEVICES_H
 +#define __AR231X_DEVICES_H
 +
 +      DEV_TYPE_AR2315,
 +      DEV_TYPE_AR2316,
 +      DEV_TYPE_AR2317,
++      DEV_TYPE_AR2318,
 +
 +      DEV_TYPE_UNKNOWN
 +};
 +#endif
 --- /dev/null
 +++ b/arch/mips/ar231x/devices.c
-@@ -0,0 +1,180 @@
+@@ -0,0 +1,181 @@
 +#include <linux/kernel.h>
 +#include <linux/init.h>
 +#include <linux/serial.h>
 +      [DEV_TYPE_AR2315] = "Atheros AR2315",
 +      [DEV_TYPE_AR2316] = "Atheros AR2316",
 +      [DEV_TYPE_AR2317] = "Atheros AR2317",
++      [DEV_TYPE_AR2318] = "Atheros AR2318",
 +      [DEV_TYPE_UNKNOWN] = "Atheros (unknown)",
 +};
 +