]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'for-rmk' of git://pasiphae.extern.pengutronix.de/git/imx/linux-2.6.git
authorRussell King <rmk@dyn-67.arm.linux.org.uk>
Thu, 9 Oct 2008 20:33:03 +0000 (21:33 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Thu, 9 Oct 2008 20:33:03 +0000 (21:33 +0100)
Merge branch 'imx-devel' into devel

1  2 
arch/arm/mach-imx/irq.c
arch/arm/mach-mx3/mx31ads.c
arch/arm/plat-mxc/irq.c

diff --combined arch/arm/mach-imx/irq.c
index 232e3b9f880db1cf78029078ea816e6bd95ba049,2bb829e721cdfad22a41bc225a52408c28a60eab..531b95deadc003ba5e08f0b85a38b21b7af62441
  #include <linux/init.h>
  #include <linux/list.h>
  #include <linux/timer.h>
 +#include <linux/io.h>
  
  #include <mach/hardware.h>
  #include <asm/irq.h>
 -#include <asm/io.h>
  
  #include <asm/mach/irq.h>
  
  /*
   *
   * We simply use the ENABLE DISABLE registers inside of the IMX
-  * to turn on/off specific interrupts.  FIXME- We should
-  * also add support for the accelerated interrupt controller
-  * by putting offets to irq jump code in the appropriate
-  * places.
+  * to turn on/off specific interrupts.
   *
   */
  
@@@ -102,6 -99,28 +99,28 @@@ imx_unmask_irq(unsigned int irq
        __raw_writel(irq, IMX_AITC_INTENNUM);
  }
  
+ #ifdef CONFIG_FIQ
+ int imx_set_irq_fiq(unsigned int irq, unsigned int type)
+ {
+       unsigned int irqt;
+       if (irq >= IMX_IRQS)
+               return -EINVAL;
+       if (irq < IMX_IRQS / 2) {
+               irqt = __raw_readl(IMX_AITC_INTTYPEL) & ~(1 << irq);
+               __raw_writel(irqt | (!!type << irq), IMX_AITC_INTTYPEL);
+       } else {
+               irq -= IMX_IRQS / 2;
+               irqt = __raw_readl(IMX_AITC_INTTYPEH) & ~(1 << irq);
+               __raw_writel(irqt | (!!type << irq), IMX_AITC_INTTYPEH);
+       }
+       return 0;
+ }
+ EXPORT_SYMBOL(imx_set_irq_fiq);
+ #endif /* CONFIG_FIQ */
  static int
  imx_gpio_irq_type(unsigned int _irq, unsigned int type)
  {
@@@ -182,12 -201,14 +201,12 @@@ static voi
  imx_gpio_handler(unsigned int mask, unsigned int irq,
                   struct irq_desc *desc)
  {
 -      desc = irq_desc + irq;
        while (mask) {
                if (mask & 1) {
                        DEBUG_IRQ("handling irq %d\n", irq);
 -                      desc_handle_irq(irq, desc);
 +                      generic_handle_irq(irq);
                }
                irq++;
 -              desc++;
                mask >>= 1;
        }
  }
@@@ -284,4 -305,9 +303,9 @@@ imx_init_irq(void
  
        /* Release masking of interrupts according to priority */
        __raw_writel(-1, IMX_AITC_NIMASK);
+ #ifdef CONFIG_FIQ
+       /* Initialize FIQ */
+       init_FIQ();
+ #endif
  }
index 0cd90a9667c8a3d1f758588876e41d50761d6244,0803fc6c021779438b5d01fff5155570370e4d11..1be4a390c63f1ae64ed84415ffed60bfec0be646
@@@ -22,6 -22,7 +22,7 @@@
  #include <linux/init.h>
  #include <linux/clk.h>
  #include <linux/serial_8250.h>
+ #include <linux/irq.h>
  
  #include <mach/hardware.h>
  #include <asm/mach-types.h>
@@@ -31,6 -32,8 +32,8 @@@
  #include <asm/mach/map.h>
  #include <mach/common.h>
  #include <mach/board-mx31ads.h>
+ #include <mach/imx-uart.h>
+ #include <mach/iomux-mx3.h>
  
  /*!
   * @file mx31ads.c
@@@ -84,6 -87,108 +87,108 @@@ static inline int mxc_init_extuart(void
  }
  #endif
  
+ #if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
+ static struct imxuart_platform_data uart_pdata = {
+       .flags = IMXUART_HAVE_RTSCTS,
+ };
+ static inline void mxc_init_imx_uart(void)
+ {
+       mxc_iomux_mode(MX31_PIN_CTS1__CTS1);
+       mxc_iomux_mode(MX31_PIN_RTS1__RTS1);
+       mxc_iomux_mode(MX31_PIN_TXD1__TXD1);
+       mxc_iomux_mode(MX31_PIN_RXD1__RXD1);
+       mxc_register_device(&mxc_uart_device0, &uart_pdata);
+ }
+ #else /* !SERIAL_IMX */
+ static inline void mxc_init_imx_uart(void)
+ {
+ }
+ #endif /* !SERIAL_IMX */
+ static void mx31ads_expio_irq_handler(u32 irq, struct irq_desc *desc)
+ {
+       u32 imr_val;
+       u32 int_valid;
+       u32 expio_irq;
+       imr_val = __raw_readw(PBC_INTMASK_SET_REG);
+       int_valid = __raw_readw(PBC_INTSTATUS_REG) & imr_val;
+       expio_irq = MXC_EXP_IO_BASE;
+       for (; int_valid != 0; int_valid >>= 1, expio_irq++) {
+               if ((int_valid & 1) == 0)
+                       continue;
+               generic_handle_irq(expio_irq);
+       }
+ }
+ /*
+  * Disable an expio pin's interrupt by setting the bit in the imr.
+  * @param irq           an expio virtual irq number
+  */
+ static void expio_mask_irq(u32 irq)
+ {
+       u32 expio = MXC_IRQ_TO_EXPIO(irq);
+       /* mask the interrupt */
+       __raw_writew(1 << expio, PBC_INTMASK_CLEAR_REG);
+       __raw_readw(PBC_INTMASK_CLEAR_REG);
+ }
+ /*
+  * Acknowledge an expanded io pin's interrupt by clearing the bit in the isr.
+  * @param irq           an expanded io virtual irq number
+  */
+ static void expio_ack_irq(u32 irq)
+ {
+       u32 expio = MXC_IRQ_TO_EXPIO(irq);
+       /* clear the interrupt status */
+       __raw_writew(1 << expio, PBC_INTSTATUS_REG);
+ }
+ /*
+  * Enable a expio pin's interrupt by clearing the bit in the imr.
+  * @param irq           a expio virtual irq number
+  */
+ static void expio_unmask_irq(u32 irq)
+ {
+       u32 expio = MXC_IRQ_TO_EXPIO(irq);
+       /* unmask the interrupt */
+       __raw_writew(1 << expio, PBC_INTMASK_SET_REG);
+ }
+ static struct irq_chip expio_irq_chip = {
+       .ack = expio_ack_irq,
+       .mask = expio_mask_irq,
+       .unmask = expio_unmask_irq,
+ };
+ static void __init mx31ads_init_expio(void)
+ {
+       int i;
+       printk(KERN_INFO "MX31ADS EXPIO(CPLD) hardware\n");
+       /*
+        * Configure INT line as GPIO input
+        */
+       mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_4, IOMUX_CONFIG_GPIO));
+       /* disable the interrupt and clear the status */
+       __raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG);
+       __raw_writew(0xFFFF, PBC_INTSTATUS_REG);
+       for (i = MXC_EXP_IO_BASE; i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES);
+            i++) {
+               set_irq_chip(i, &expio_irq_chip);
+               set_irq_handler(i, handle_level_irq);
+               set_irq_flags(i, IRQF_VALID);
+       }
+       set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_HIGH);
+       set_irq_chained_handler(EXPIO_PARENT_INT, mx31ads_expio_irq_handler);
+ }
  /*!
   * This structure defines static mappings for the i.MX31ADS board.
   */
@@@ -92,17 -197,17 +197,17 @@@ static struct map_desc mx31ads_io_desc[
                .virtual        = AIPS1_BASE_ADDR_VIRT,
                .pfn            = __phys_to_pfn(AIPS1_BASE_ADDR),
                .length         = AIPS1_SIZE,
 -              .type           = MT_NONSHARED_DEVICE
 +              .type           = MT_DEVICE_NONSHARED
        }, {
                .virtual        = SPBA0_BASE_ADDR_VIRT,
                .pfn            = __phys_to_pfn(SPBA0_BASE_ADDR),
                .length         = SPBA0_SIZE,
 -              .type           = MT_NONSHARED_DEVICE
 +              .type           = MT_DEVICE_NONSHARED
        }, {
                .virtual        = AIPS2_BASE_ADDR_VIRT,
                .pfn            = __phys_to_pfn(AIPS2_BASE_ADDR),
                .length         = AIPS2_SIZE,
 -              .type           = MT_NONSHARED_DEVICE
 +              .type           = MT_DEVICE_NONSHARED
        }, {
                .virtual        = CS4_BASE_ADDR_VIRT,
                .pfn            = __phys_to_pfn(CS4_BASE_ADDR),
@@@ -120,12 -225,19 +225,19 @@@ void __init mx31ads_map_io(void
        iotable_init(mx31ads_io_desc, ARRAY_SIZE(mx31ads_io_desc));
  }
  
+ void __init mx31ads_init_irq(void)
+ {
+       mxc_init_irq();
+       mx31ads_init_expio();
+ }
  /*!
   * Board specific initialization.
   */
  static void __init mxc_board_init(void)
  {
        mxc_init_extuart();
+       mxc_init_imx_uart();
  }
  
  static void __init mx31ads_timer_init(void)
@@@ -148,7 -260,7 +260,7 @@@ MACHINE_START(MX31ADS, "Freescale MX31A
        .io_pg_offst    = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
        .boot_params    = PHYS_OFFSET + 0x100,
        .map_io         = mx31ads_map_io,
-       .init_irq       = mxc_init_irq,
+       .init_irq       = mx31ads_init_irq,
        .init_machine   = mxc_board_init,
        .timer          = &mx31ads_timer,
  MACHINE_END
diff --combined arch/arm/plat-mxc/irq.c
index c6b837893d87b876ee8842abc365f2ec734dc671,da28105e35eded51a982a6293dc8c2cff2ce118f..d862c9e5f8dbc935a7f89ba5576746186427eb86
@@@ -18,7 -18,7 +18,7 @@@
   */
  
  #include <linux/irq.h>
 -#include <asm/io.h>
 +#include <linux/io.h>
  #include <mach/common.h>
  
  #define AVIC_BASE             IO_ADDRESS(AVIC_BASE_ADDR)
  #define AVIC_INTENABLEL               (AVIC_BASE + 0x14)      /* int enable reg low */
  #define AVIC_INTTYPEH         (AVIC_BASE + 0x18)      /* int type reg high */
  #define AVIC_INTTYPEL         (AVIC_BASE + 0x1C)      /* int type reg low */
- #define AVIC_NIPRIORITY7      (AVIC_BASE + 0x20)      /* norm int priority lvl7 */
- #define AVIC_NIPRIORITY6      (AVIC_BASE + 0x24)      /* norm int priority lvl6 */
- #define AVIC_NIPRIORITY5      (AVIC_BASE + 0x28)      /* norm int priority lvl5 */
- #define AVIC_NIPRIORITY4      (AVIC_BASE + 0x2C)      /* norm int priority lvl4 */
- #define AVIC_NIPRIORITY3      (AVIC_BASE + 0x30)      /* norm int priority lvl3 */
- #define AVIC_NIPRIORITY2      (AVIC_BASE + 0x34)      /* norm int priority lvl2 */
- #define AVIC_NIPRIORITY1      (AVIC_BASE + 0x38)      /* norm int priority lvl1 */
- #define AVIC_NIPRIORITY0      (AVIC_BASE + 0x3C)      /* norm int priority lvl0 */
+ #define AVIC_NIPRIORITY(x)    (AVIC_BASE + (0x20 + 4 * (7 - (x)))) /* int priority */
  #define AVIC_NIVECSR          (AVIC_BASE + 0x40)      /* norm int vector/status */
  #define AVIC_FIVECSR          (AVIC_BASE + 0x44)      /* fast int vector/status */
  #define AVIC_INTSRCH          (AVIC_BASE + 0x48)      /* int source reg high */
  #define IIM_PROD_REV_SH               3
  #define IIM_PROD_REV_LEN      5
  
+ #ifdef CONFIG_MXC_IRQ_PRIOR
+ void imx_irq_set_priority(unsigned char irq, unsigned char prio)
+ {
+       unsigned int temp;
+       unsigned int mask = 0x0F << irq % 8 * 4;
+       if (irq > 63)
+               return;
+       temp = __raw_readl(AVIC_NIPRIORITY(irq / 8));
+       temp &= ~mask;
+       temp |= prio & mask;
+       __raw_writel(temp, AVIC_NIPRIORITY(irq / 8));
+ }
+ EXPORT_SYMBOL(imx_irq_set_priority);
+ #endif
  /* Disable interrupt number "irq" in the AVIC */
  static void mxc_mask_irq(unsigned int irq)
  {
@@@ -101,10 -112,9 +112,9 @@@ void __init mxc_init_irq(void
                set_irq_flags(i, IRQF_VALID);
        }
  
-       /* Set WDOG2's interrupt the highest priority level (bit 28-31) */
-       reg = __raw_readl(AVIC_NIPRIORITY6);
-       reg |= (0xF << 28);
-       __raw_writel(reg, AVIC_NIPRIORITY6);
+       /* Set default priority value (0) for all IRQ's */
+       for (i = 0; i < 8; i++)
+               __raw_writel(0, AVIC_NIPRIORITY(i));
  
        /* init architectures chained interrupt handler */
        mxc_register_gpios();