]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Merge branch 'genirq' of master.kernel.org:/home/rmk/linux-2.6-arm
authorLinus Torvalds <torvalds@g5.osdl.org>
Sun, 2 Jul 2006 22:07:45 +0000 (15:07 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Sun, 2 Jul 2006 22:07:45 +0000 (15:07 -0700)
* 'genirq' of master.kernel.org:/home/rmk/linux-2.6-arm: (24 commits)
  [ARM] 3683/2:  ARM: Convert at91rm9200 to generic irq handling
  [ARM] 3682/2:  ARM: Convert ixp4xx to generic irq handling
  [ARM] 3702/1: ARM: Convert ixp23xx to generic irq handling
  [ARM] 3701/1: ARM: Convert plat-omap to generic irq handling
  [ARM] 3700/1: ARM: Convert lh7a40x to generic irq handling
  [ARM] 3699/1: ARM: Convert s3c2410 to generic irq handling
  [ARM] 3698/1: ARM: Convert sa1100 to generic irq handling
  [ARM] 3697/1: ARM: Convert shark to generic irq handling
  [ARM] 3696/1: ARM: Convert clps711x to generic irq handling
  [ARM] 3694/1: ARM: Convert ecard driver to generic irq handling
  [ARM] 3693/1: ARM: Convert omap1 to generic irq handling
  [ARM] 3691/1: ARM: Convert imx to generic irq handling
  [ARM] 3688/1: ARM: Convert clps7500 to generic irq handling
  [ARM] 3687/1: ARM: Convert integrator to generic irq handling
  [ARM] 3685/1: ARM: Convert pxa to generic irq handling
  [ARM] 3684/1: ARM: Convert l7200 to generic irq handling
  [ARM] 3681/1: ARM: Convert ixp2000 to generic irq handling
  [ARM] 3680/1: ARM: Convert footbridge to generic irq handling
  [ARM] 3695/1: ARM drivers/pcmcia: Fixup includes
  [ARM] 3689/1: ARM drivers/input/touchscreen: Fixup includes
  ...

Manual conflict resolved in kernel/irq/handle.c (butt-ugly ARM tickless
code).

1  2 
arch/arm/Kconfig
arch/arm/mach-at91rm9200/at91rm9200_time.c
arch/arm/mach-omap1/board-osk.c
arch/arm/plat-omap/dma.c
arch/arm/plat-omap/gpio.c
drivers/input/touchscreen/corgi_ts.c
drivers/pcmcia/soc_common.c
include/linux/irq.h
kernel/irq/handle.c

diff --combined arch/arm/Kconfig
index 919d8b92aaa4b072820c0148c4ebb5dd10fe520f,531661ac01b4337e027f58a1bb798caf1124aafe..f81a62380addefde7db4f0cde3902cb872c1c061
@@@ -47,6 -47,18 +47,18 @@@ config MC
          <file:Documentation/mca.txt> (and especially the web page given
          there) before attempting to build an MCA bus kernel.
  
+ config GENERIC_HARDIRQS
+       bool
+       default y
+ config HARDIRQS_SW_RESEND
+       bool
+       default y
+ config GENERIC_IRQ_PROBE
+       bool
+       default y
  config RWSEM_GENERIC_SPINLOCK
        bool
        default y
@@@ -121,11 -133,11 +133,11 @@@ config ARCH_VERSATIL
        help
          This enables support for ARM Ltd Versatile board.
  
 -config ARCH_AT91RM9200
 -      bool "Atmel AT91RM9200"
 +config ARCH_AT91
 +      bool "Atmel AT91"
        help
 -        Say Y here if you intend to run this kernel on an Atmel
 -        AT91RM9200-based board.
 +        This enables support for systems based on the Atmel AT91RM9200
 +        and AT91SAM9xxx processors.
  
  config ARCH_CLPS7500
        bool "Cirrus CL-PS7500FE"
@@@ -547,7 -559,7 +559,7 @@@ config LED
                   ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \
                   ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \
                   ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \
 -                 ARCH_AT91RM9200
 +                 ARCH_AT91RM9200 || MACH_TRIZEPS4
        help
          If you say Y here, the LEDs on your machine will be used
          to provide useful information about your current system status.
@@@ -678,7 -690,7 +690,7 @@@ config XIP_PHYS_ADD
  
  endmenu
  
 -if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP1)
 +if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP)
  
  menu "CPU Frequency scaling"
  
index dc38e06ada6376d67952f3e8b97848338701acf7,1f080e6ea509ed9492b46f459e606c87f1fabb69..0aa22650a00f2e8ac4564cc34f29573e717ba0fb
@@@ -1,5 -1,5 +1,5 @@@
  /*
 - * linux/arch/arm/mach-at91rm9200/time.c
 + * linux/arch/arm/mach-at91rm9200/at91rm9200_time.c
   *
   *  Copyright (C) 2003 SAN People
   *  Copyright (C) 2003 ATMEL
  
  #include <linux/init.h>
  #include <linux/interrupt.h>
+ #include <linux/irq.h>
  #include <linux/kernel.h>
  #include <linux/sched.h>
  #include <linux/time.h>
  
  #include <asm/hardware.h>
  #include <asm/io.h>
- #include <asm/irq.h>
  #include <asm/mach/time.h>
  
  static unsigned long last_crtr;
index e0711d23a6b01bec0189b7fce0fa145e7ec49709,ef7685d224d585b17739b69340b1cb70caacee02..91933301bb73268325f46152cefc358a279b732a
  #include <linux/kernel.h>
  #include <linux/init.h>
  #include <linux/platform_device.h>
- #include <linux/interrupt.h>
+ #include <linux/irq.h>
  
  #include <linux/mtd/mtd.h>
  #include <linux/mtd/partitions.h>
 -#include <linux/input.h>
  
  #include <asm/hardware.h>
  #include <asm/mach-types.h>
  #include <asm/arch/usb.h>
  #include <asm/arch/mux.h>
  #include <asm/arch/tc.h>
 -#include <asm/arch/keypad.h>
  #include <asm/arch/common.h>
  #include <asm/arch/mcbsp.h>
  #include <asm/arch/omap-alsa.h>
  
 -static int osk_keymap[] = {
 -      KEY(0, 0, KEY_F1),
 -      KEY(0, 3, KEY_UP),
 -      KEY(1, 1, KEY_LEFTCTRL),
 -      KEY(1, 2, KEY_LEFT),
 -      KEY(2, 0, KEY_SPACE),
 -      KEY(2, 1, KEY_ESC),
 -      KEY(2, 2, KEY_DOWN),
 -      KEY(3, 2, KEY_ENTER),
 -      KEY(3, 3, KEY_RIGHT),
 -      0
 -};
 -
 -
  static struct mtd_partition osk_partitions[] = {
        /* bootloader (U-Boot, etc) in first sector */
        {
@@@ -165,17 -181,48 +165,17 @@@ static struct omap_alsa_codec_config al
  
  static struct platform_device osk5912_mcbsp1_device = {
        .name   = "omap_alsa_mcbsp",
 -      .id     = 1,
 +      .id     = 1,
        .dev = {
                .platform_data  = &alsa_config,
        },
  };
  
 -static struct resource osk5912_kp_resources[] = {
 -      [0] = {
 -              .start  = INT_KEYBOARD,
 -              .end    = INT_KEYBOARD,
 -              .flags  = IORESOURCE_IRQ,
 -      },
 -};
 -
 -static struct omap_kp_platform_data osk_kp_data = {
 -      .rows   = 8,
 -      .cols   = 8,
 -      .keymap = osk_keymap,
 -};
 -
 -static struct platform_device osk5912_kp_device = {
 -      .name           = "omap-keypad",
 -      .id             = -1,
 -      .dev            = {
 -              .platform_data = &osk_kp_data,
 -      },
 -      .num_resources  = ARRAY_SIZE(osk5912_kp_resources),
 -      .resource       = osk5912_kp_resources,
 -};
 -
 -static struct platform_device osk5912_lcd_device = {
 -      .name           = "lcd_osk",
 -      .id             = -1,
 -};
 -
  static struct platform_device *osk5912_devices[] __initdata = {
        &osk5912_flash_device,
        &osk5912_smc91x_device,
        &osk5912_cf_device,
        &osk5912_mcbsp1_device,
 -      &osk5912_kp_device,
 -      &osk5912_lcd_device,
  };
  
  static void __init osk_init_smc91x(void)
@@@ -229,100 -276,18 +229,100 @@@ static struct omap_uart_config osk_uart
        .enabled_uarts = (1 << 0),
  };
  
 +#ifdef        CONFIG_OMAP_OSK_MISTRAL
  static struct omap_lcd_config osk_lcd_config __initdata = {
        .ctrl_name      = "internal",
  };
 +#endif
  
  static struct omap_board_config_kernel osk_config[] = {
        { OMAP_TAG_USB,           &osk_usb_config },
        { OMAP_TAG_UART,                &osk_uart_config },
 +#ifdef        CONFIG_OMAP_OSK_MISTRAL
        { OMAP_TAG_LCD,                 &osk_lcd_config },
 +#endif
  };
  
  #ifdef        CONFIG_OMAP_OSK_MISTRAL
  
 +#include <linux/input.h>
 +#include <linux/spi/spi.h>
 +#include <linux/spi/ads7846.h>
 +
 +#include <asm/arch/keypad.h>
 +
 +static const int osk_keymap[] = {
 +      /* KEY(col, row, code) */
 +      KEY(0, 0, KEY_F1),              /* SW4 */
 +      KEY(0, 3, KEY_UP),              /* (sw2/up) */
 +      KEY(1, 1, KEY_LEFTCTRL),        /* SW5 */
 +      KEY(1, 2, KEY_LEFT),            /* (sw2/left) */
 +      KEY(2, 0, KEY_SPACE),           /* SW3 */
 +      KEY(2, 1, KEY_ESC),             /* SW6 */
 +      KEY(2, 2, KEY_DOWN),            /* (sw2/down) */
 +      KEY(3, 2, KEY_ENTER),           /* (sw2/select) */
 +      KEY(3, 3, KEY_RIGHT),           /* (sw2/right) */
 +      0
 +};
 +
 +static struct omap_kp_platform_data osk_kp_data = {
 +      .rows   = 8,
 +      .cols   = 8,
 +      .keymap = (int *) osk_keymap,
 +};
 +
 +static struct resource osk5912_kp_resources[] = {
 +      [0] = {
 +              .start  = INT_KEYBOARD,
 +              .end    = INT_KEYBOARD,
 +              .flags  = IORESOURCE_IRQ,
 +      },
 +};
 +
 +static struct platform_device osk5912_kp_device = {
 +      .name           = "omap-keypad",
 +      .id             = -1,
 +      .dev            = {
 +              .platform_data = &osk_kp_data,
 +      },
 +      .num_resources  = ARRAY_SIZE(osk5912_kp_resources),
 +      .resource       = osk5912_kp_resources,
 +};
 +
 +static struct platform_device osk5912_lcd_device = {
 +      .name           = "lcd_osk",
 +      .id             = -1,
 +};
 +
 +static struct platform_device *mistral_devices[] __initdata = {
 +      &osk5912_kp_device,
 +      &osk5912_lcd_device,
 +};
 +
 +static int mistral_get_pendown_state(void)
 +{
 +      return !omap_get_gpio_datain(4);
 +}
 +
 +static const struct ads7846_platform_data mistral_ts_info = {
 +      .model                  = 7846,
 +      .vref_delay_usecs       = 100,  /* internal, no capacitor */
 +      .x_plate_ohms           = 419,
 +      .y_plate_ohms           = 486,
 +      .get_pendown_state      = mistral_get_pendown_state,
 +};
 +
 +static struct spi_board_info __initdata mistral_boardinfo[] = { {
 +      /* MicroWire (bus 2) CS0 has an ads7846e */
 +      .modalias               = "ads7846",
 +      .platform_data          = &mistral_ts_info,
 +      .irq                    = OMAP_GPIO_IRQ(4),
 +      .max_speed_hz           = 120000 /* max sample rate at 3V */
 +                                      * 26 /* command + data + overhead */,
 +      .bus_num                = 2,
 +      .chip_select            = 0,
 +} };
 +
  #ifdef        CONFIG_PM
  static irqreturn_t
  osk_mistral_wake_interrupt(int irq, void *ignored, struct pt_regs *regs)
  
  static void __init osk_mistral_init(void)
  {
 -      /* FIXME here's where to feed in framebuffer, touchpad, and
 -       * keyboard setup ...  not in the drivers for those devices!
 -       *
 -       * NOTE:  we could actually tell if there's a Mistral board
 +      /* NOTE:  we could actually tell if there's a Mistral board
         * attached, e.g. by trying to read something from the ads7846.
 -       * But this is too early for that...
 +       * But this arch_init() code is too early for that, since we
 +       * can't talk to the ads or even the i2c eeprom.
         */
  
 +      // omap_cfg_reg(P19_1610_GPIO6);        // BUSY
 +      omap_cfg_reg(P20_1610_GPIO4);   // PENIRQ
 +      set_irq_type(OMAP_GPIO_IRQ(4), IRQT_FALLING);
 +      spi_register_board_info(mistral_boardinfo,
 +                      ARRAY_SIZE(mistral_boardinfo));
 +
        /* the sideways button (SW1) is for use as a "wakeup" button */
        omap_cfg_reg(N15_1610_MPUIO2);
        if (omap_request_gpio(OMAP_MPUIO(2)) == 0) {
  #endif
        } else
                printk(KERN_ERR "OSK+Mistral: wakeup button is awol\n");
 +
 +      platform_add_devices(mistral_devices, ARRAY_SIZE(mistral_devices));
  }
  #else
  static void __init osk_mistral_init(void) { }
diff --combined arch/arm/plat-omap/dma.c
index c5d0214ef1911f1d0d4769f68642ecd60139cea9,2525633fcd09ca47224d098fa8825671007a3ca8..c2c05ef863488201988229c29ca0fc440f233fbc
@@@ -24,9 -24,9 +24,9 @@@
  #include <linux/spinlock.h>
  #include <linux/errno.h>
  #include <linux/interrupt.h>
+ #include <linux/irq.h>
  
  #include <asm/system.h>
- #include <asm/irq.h>
  #include <asm/hardware.h>
  #include <asm/dma.h>
  #include <asm/io.h>
@@@ -43,7 -43,6 +43,7 @@@
  
  #define OMAP_DMA_ACTIVE               0x01
  #define OMAP_DMA_CCR_EN               (1 << 7)
 +#define OMAP2_DMA_CSR_CLEAR_MASK      0xffe
  
  #define OMAP_FUNC_MUX_ARM_BASE        (0xfffe1000 + 0xec)
  
@@@ -167,24 -166,18 +167,24 @@@ void omap_set_dma_transfer_params(int l
        if (cpu_is_omap24xx() && dma_trigger) {
                u32 val = OMAP_DMA_CCR_REG(lch);
  
 +              val &= ~(3 << 19);
                if (dma_trigger > 63)
                        val |= 1 << 20;
                if (dma_trigger > 31)
                        val |= 1 << 19;
  
 +              val &= ~(0x1f);
                val |= (dma_trigger & 0x1f);
  
                if (sync_mode & OMAP_DMA_SYNC_FRAME)
                        val |= 1 << 5;
 +              else
 +                      val &= ~(1 << 5);
  
                if (sync_mode & OMAP_DMA_SYNC_BLOCK)
                        val |= 1 << 18;
 +              else
 +                      val &= ~(1 << 18);
  
                if (src_or_dst_synch)
                        val |= 1 << 24;         /* source synch */
@@@ -293,39 -286,22 +293,39 @@@ void omap_set_dma_src_data_pack(int lch
  
  void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
  {
 +      unsigned int burst = 0;
        OMAP_DMA_CSDP_REG(lch) &= ~(0x03 << 7);
  
        switch (burst_mode) {
        case OMAP_DMA_DATA_BURST_DIS:
                break;
        case OMAP_DMA_DATA_BURST_4:
 -              OMAP_DMA_CSDP_REG(lch) |= (0x02 << 7);
 +              if (cpu_is_omap24xx())
 +                      burst = 0x1;
 +              else
 +                      burst = 0x2;
                break;
        case OMAP_DMA_DATA_BURST_8:
 -              /* not supported by current hardware
 +              if (cpu_is_omap24xx()) {
 +                      burst = 0x2;
 +                      break;
 +              }
 +              /* not supported by current hardware on OMAP1
                 * w |= (0x03 << 7);
                 * fall through
                 */
 +      case OMAP_DMA_DATA_BURST_16:
 +              if (cpu_is_omap24xx()) {
 +                      burst = 0x3;
 +                      break;
 +              }
 +              /* OMAP1 don't support burst 16
 +               * fall through
 +               */
        default:
                BUG();
        }
 +      OMAP_DMA_CSDP_REG(lch) |= (burst << 7);
  }
  
  /* Note that dest_port is only for OMAP1 */
@@@ -372,49 -348,30 +372,49 @@@ void omap_set_dma_dest_data_pack(int lc
  
  void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
  {
 +      unsigned int burst = 0;
        OMAP_DMA_CSDP_REG(lch) &= ~(0x03 << 14);
  
        switch (burst_mode) {
        case OMAP_DMA_DATA_BURST_DIS:
                break;
        case OMAP_DMA_DATA_BURST_4:
 -              OMAP_DMA_CSDP_REG(lch) |= (0x02 << 14);
 +              if (cpu_is_omap24xx())
 +                      burst = 0x1;
 +              else
 +                      burst = 0x2;
                break;
        case OMAP_DMA_DATA_BURST_8:
 -              OMAP_DMA_CSDP_REG(lch) |= (0x03 << 14);
 +              if (cpu_is_omap24xx())
 +                      burst = 0x2;
 +              else
 +                      burst = 0x3;
                break;
 +      case OMAP_DMA_DATA_BURST_16:
 +              if (cpu_is_omap24xx()) {
 +                      burst = 0x3;
 +                      break;
 +              }
 +              /* OMAP1 don't support burst 16
 +               * fall through
 +               */
        default:
                printk(KERN_ERR "Invalid DMA burst mode\n");
                BUG();
                return;
        }
 +      OMAP_DMA_CSDP_REG(lch) |= (burst << 14);
  }
  
  static inline void omap_enable_channel_irq(int lch)
  {
        u32 status;
  
 -      /* Read CSR to make sure it's cleared. */
 -      status = OMAP_DMA_CSR_REG(lch);
 +      /* Clear CSR */
 +      if (cpu_class_is_omap1())
 +              status = OMAP_DMA_CSR_REG(lch);
 +      else if (cpu_is_omap24xx())
 +              OMAP_DMA_CSR_REG(lch) = OMAP2_DMA_CSR_CLEAR_MASK;
  
        /* Enable some nice interrupts. */
        OMAP_DMA_CICR_REG(lch) = dma_chan[lch].enabled_irqs;
@@@ -513,13 -470,11 +513,13 @@@ int omap_request_dma(int dev_id, const 
        chan->dev_name = dev_name;
        chan->callback = callback;
        chan->data = data;
 -      chan->enabled_irqs = OMAP_DMA_TOUT_IRQ | OMAP_DMA_DROP_IRQ |
 -                              OMAP_DMA_BLOCK_IRQ;
 +      chan->enabled_irqs = OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ;
  
 -      if (cpu_is_omap24xx())
 -              chan->enabled_irqs |= OMAP2_DMA_TRANS_ERR_IRQ;
 +      if (cpu_class_is_omap1())
 +              chan->enabled_irqs |= OMAP1_DMA_TOUT_IRQ;
 +      else if (cpu_is_omap24xx())
 +              chan->enabled_irqs |= OMAP2_DMA_MISALIGNED_ERR_IRQ |
 +                      OMAP2_DMA_TRANS_ERR_IRQ;
  
        if (cpu_is_omap16xx()) {
                /* If the sync device is set, configure it dynamically. */
  
                omap_enable_channel_irq(free_ch);
                /* Clear the CSR register and IRQ status register */
 -              OMAP_DMA_CSR_REG(free_ch) = 0x0;
 +              OMAP_DMA_CSR_REG(free_ch) = OMAP2_DMA_CSR_CLEAR_MASK;
                omap_writel(~0x0, OMAP_DMA4_IRQSTATUS_L0);
        }
  
@@@ -579,7 -534,7 +579,7 @@@ void omap_free_dma(int lch
                omap_writel(val, OMAP_DMA4_IRQENABLE_L0);
  
                /* Clear the CSR register and IRQ status register */
 -              OMAP_DMA_CSR_REG(lch) = 0x0;
 +              OMAP_DMA_CSR_REG(lch) = OMAP2_DMA_CSR_CLEAR_MASK;
  
                val = omap_readl(OMAP_DMA4_IRQSTATUS_L0);
                val |= 1 << lch;
@@@ -843,7 -798,7 +843,7 @@@ static int omap1_dma_handle_ch(int ch
                       "%d (CSR %04x)\n", ch, csr);
                return 0;
        }
 -      if (unlikely(csr & OMAP_DMA_TOUT_IRQ))
 +      if (unlikely(csr & OMAP1_DMA_TOUT_IRQ))
                printk(KERN_WARNING "DMA timeout with device %d\n",
                       dma_chan[ch].dev_id);
        if (unlikely(csr & OMAP_DMA_DROP_IRQ))
@@@ -891,21 -846,20 +891,21 @@@ static int omap2_dma_handle_ch(int ch
                return 0;
        if (unlikely(dma_chan[ch].dev_id == -1))
                return 0;
 -      /* REVISIT: According to 24xx TRM, there's no TOUT_IE */
 -      if (unlikely(status & OMAP_DMA_TOUT_IRQ))
 -              printk(KERN_INFO "DMA timeout with device %d\n",
 -                     dma_chan[ch].dev_id);
        if (unlikely(status & OMAP_DMA_DROP_IRQ))
                printk(KERN_INFO
                       "DMA synchronization event drop occurred with device "
                       "%d\n", dma_chan[ch].dev_id);
 -
        if (unlikely(status & OMAP2_DMA_TRANS_ERR_IRQ))
                printk(KERN_INFO "DMA transaction error with device %d\n",
                       dma_chan[ch].dev_id);
 +      if (unlikely(status & OMAP2_DMA_SECURE_ERR_IRQ))
 +              printk(KERN_INFO "DMA secure error with device %d\n",
 +                     dma_chan[ch].dev_id);
 +      if (unlikely(status & OMAP2_DMA_MISALIGNED_ERR_IRQ))
 +              printk(KERN_INFO "DMA misaligned error with device %d\n",
 +                     dma_chan[ch].dev_id);
  
 -      OMAP_DMA_CSR_REG(ch) = 0x20;
 +      OMAP_DMA_CSR_REG(ch) = OMAP2_DMA_CSR_CLEAR_MASK;
  
        val = omap_readl(OMAP_DMA4_IRQSTATUS_L0);
        /* ch in this function is from 0-31 while in register it is 1-32 */
index ae08eeec7aad0ace52c250c7f688788471c40131,312ace515d170d93ac0ab10c774717ead09b4cae..cb0c21d384c066ec1441b346810355113dfa7bab
@@@ -536,49 -536,6 +536,49 @@@ static inline void _clear_gpio_irqstatu
        _clear_gpio_irqbank(bank, 1 << get_gpio_index(gpio));
  }
  
 +static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)
 +{
 +      void __iomem *reg = bank->base;
 +      int inv = 0;
 +      u32 l;
 +      u32 mask;
 +
 +      switch (bank->method) {
 +      case METHOD_MPUIO:
 +              reg += OMAP_MPUIO_GPIO_MASKIT;
 +              mask = 0xffff;
 +              inv = 1;
 +              break;
 +      case METHOD_GPIO_1510:
 +              reg += OMAP1510_GPIO_INT_MASK;
 +              mask = 0xffff;
 +              inv = 1;
 +              break;
 +      case METHOD_GPIO_1610:
 +              reg += OMAP1610_GPIO_IRQENABLE1;
 +              mask = 0xffff;
 +              break;
 +      case METHOD_GPIO_730:
 +              reg += OMAP730_GPIO_INT_MASK;
 +              mask = 0xffffffff;
 +              inv = 1;
 +              break;
 +      case METHOD_GPIO_24XX:
 +              reg += OMAP24XX_GPIO_IRQENABLE1;
 +              mask = 0xffffffff;
 +              break;
 +      default:
 +              BUG();
 +              return 0;
 +      }
 +
 +      l = __raw_readl(reg);
 +      if (inv)
 +              l = ~l;
 +      l &= mask;
 +      return l;
 +}
 +
  static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable)
  {
        void __iomem *reg = bank->base;
@@@ -778,12 -735,10 +778,12 @@@ static void gpio_irq_handler(unsigned i
        u32 isr;
        unsigned int gpio_irq;
        struct gpio_bank *bank;
 +      u32 retrigger = 0;
 +      int unmasked = 0;
  
        desc->chip->ack(irq);
  
-       bank = (struct gpio_bank *) desc->data;
+       bank = get_irq_data(irq);
        if (bank->method == METHOD_MPUIO)
                isr_reg = bank->base + OMAP_MPUIO_GPIO_INT;
  #ifdef CONFIG_ARCH_OMAP15XX
  #endif
        while(1) {
                u32 isr_saved, level_mask = 0;
 +              u32 enabled;
  
 -              isr_saved = isr = __raw_readl(isr_reg);
 +              enabled = _get_gpio_irqbank_mask(bank);
 +              isr_saved = isr = __raw_readl(isr_reg) & enabled;
  
                if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO))
                        isr &= 0x0000ffff;
  
 -              if (cpu_is_omap24xx())
 +              if (cpu_is_omap24xx()) {
                        level_mask =
                                __raw_readl(bank->base +
                                        OMAP24XX_GPIO_LEVELDETECT0) |
                                __raw_readl(bank->base +
                                        OMAP24XX_GPIO_LEVELDETECT1);
 +                      level_mask &= enabled;
 +              }
  
                /* clear edge sensitive interrupts before handler(s) are
                called so that we don't miss any interrupt occurred while
  
                /* if there is only edge sensitive GPIO pin interrupts
                configured, we could unmask GPIO bank interrupt immediately */
 -              if (!level_mask)
 +              if (!level_mask && !unmasked) {
 +                      unmasked = 1;
                        desc->chip->unmask(irq);
 +              }
  
 +              isr |= retrigger;
 +              retrigger = 0;
                if (!isr)
                        break;
  
                gpio_irq = bank->virtual_irq_start;
                for (; isr != 0; isr >>= 1, gpio_irq++) {
                        struct irqdesc *d;
 +                      int irq_mask;
                        if (!(isr & 1))
                                continue;
                        d = irq_desc + gpio_irq;
 +                      /* Don't run the handler if it's already running
 +                       * or was disabled lazely.
 +                       */
 +                      if (unlikely((d->disable_depth || d->running))) {
 +                              irq_mask = 1 <<
 +                                      (gpio_irq - bank->virtual_irq_start);
 +                              /* The unmasking will be done by
 +                               * enable_irq in case it is disabled or
 +                               * after returning from the handler if
 +                               * it's already running.
 +                               */
 +                              _enable_gpio_irqbank(bank, irq_mask, 0);
 +                              if (!d->disable_depth) {
 +                                      /* Level triggered interrupts
 +                                       * won't ever be reentered
 +                                       */
 +                                      BUG_ON(level_mask & irq_mask);
 +                                      d->pending = 1;
 +                              }
 +                              continue;
 +                      }
 +                      d->running = 1;
                        desc_handle_irq(gpio_irq, d, regs);
 +                      d->running = 0;
 +                      if (unlikely(d->pending && !d->disable_depth)) {
 +                              irq_mask = 1 <<
 +                                      (gpio_irq - bank->virtual_irq_start);
 +                              d->pending = 0;
 +                              _enable_gpio_irqbank(bank, irq_mask, 1);
 +                              retrigger |= irq_mask;
 +                      }
                }
  
                if (cpu_is_omap24xx()) {
                        _enable_gpio_irqbank(bank, isr_saved & level_mask, 1);
                }
  
 -              /* if bank has any level sensitive GPIO pin interrupt
 -              configured, we must unmask the bank interrupt only after
 -              handler(s) are executed in order to avoid spurious bank
 -              interrupt */
 -              if (level_mask)
 -                      desc->chip->unmask(irq);
        }
 +      /* if bank has any level sensitive GPIO pin interrupt
 +      configured, we must unmask the bank interrupt only after
 +      handler(s) are executed in order to avoid spurious bank
 +      interrupt */
 +      if (!unmasked)
 +              desc->chip->unmask(irq);
 +
  }
  
  static void gpio_ack_irq(unsigned int irq)
index d2f9759cd3ed12ed1dbeff4d4c30fbab37145b6e,b3eaf23b17c82b2f77725a2765205a730b22c4bd..9b66271d3ba82feefd4104f59473b4c3f53f95cc
@@@ -17,7 -17,7 +17,7 @@@
  #include <linux/interrupt.h>
  #include <linux/module.h>
  #include <linux/slab.h>
//#include <asm/irq.h>
#include <linux/irq.h>
  
  #include <asm/arch/sharpsl.h>
  #include <asm/arch/hardware.h>
@@@ -318,7 -318,7 +318,7 @@@ static int __init corgits_probe(struct 
        corgi_ssp_ads7846_putget((5u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
        mdelay(5);
  
 -      if (request_irq(corgi_ts->irq_gpio, ts_interrupt, SA_INTERRUPT, "ts", corgi_ts)) {
 +      if (request_irq(corgi_ts->irq_gpio, ts_interrupt, IRQF_DISABLED, "ts", corgi_ts)) {
                err = -EBUSY;
                goto fail;
        }
index 888358fac59843dc68e0f884ab652e4d998ae260,8ef3f91310d24cd94a1fa1ea7296a5afda36308b..ecaa132fa5924aefd4ef7b0e8d4dc2ee5bc6c0b7
  #include <linux/timer.h>
  #include <linux/mm.h>
  #include <linux/interrupt.h>
+ #include <linux/irq.h>
  #include <linux/spinlock.h>
  #include <linux/cpufreq.h>
  
  #include <asm/hardware.h>
  #include <asm/io.h>
- #include <asm/irq.h>
  #include <asm/system.h>
  
  #include "soc_common.h"
@@@ -523,7 -523,7 +523,7 @@@ int soc_pcmcia_request_irqs(struct soc_
                if (irqs[i].sock != skt->nr)
                        continue;
                res = request_irq(irqs[i].irq, soc_common_pcmcia_interrupt,
 -                                SA_INTERRUPT, irqs[i].str, skt);
 +                                IRQF_DISABLED, irqs[i].str, skt);
                if (res)
                        break;
                set_irq_type(irqs[i].irq, IRQT_NOEDGE);
diff --combined include/linux/irq.h
index ae1e422f18e3dc97f5278c396e40faef61048c40,00b6ef8b2f936bf55f9ed5a6454b31be511eeeea..95d7aa7954d20b8aa706567e7eee52e391da8b00
  
  /*
   * IRQ line status.
 + *
 + * Bits 0-16 are reserved for the IRQF_* bits in linux/interrupt.h
 + *
 + * IRQ types
   */
 -#define IRQ_INPROGRESS        1       /* IRQ handler active - do not enter! */
 -#define IRQ_DISABLED  2       /* IRQ disabled - do not enter! */
 -#define IRQ_PENDING   4       /* IRQ pending - replay on enable */
 -#define IRQ_REPLAY    8       /* IRQ has been replayed but not acked yet */
 -#define IRQ_AUTODETECT        16      /* IRQ is being autodetected */
 -#define IRQ_WAITING   32      /* IRQ not yet seen - for autodetection */
 -#define IRQ_LEVEL     64      /* IRQ level triggered */
 -#define IRQ_MASKED    128     /* IRQ masked - shouldn't be seen again */
 +#define IRQ_TYPE_NONE         0x00000000      /* Default, unspecified type */
 +#define IRQ_TYPE_EDGE_RISING  0x00000001      /* Edge rising type */
 +#define IRQ_TYPE_EDGE_FALLING 0x00000002      /* Edge falling type */
 +#define IRQ_TYPE_EDGE_BOTH (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)
 +#define IRQ_TYPE_LEVEL_HIGH   0x00000004      /* Level high type */
 +#define IRQ_TYPE_LEVEL_LOW    0x00000008      /* Level low type */
 +#define IRQ_TYPE_SENSE_MASK   0x0000000f      /* Mask of the above */
 +#define IRQ_TYPE_PROBE                0x00000010      /* Probing in progress */
 +
 +/* Internal flags */
 +#define IRQ_INPROGRESS                0x00010000      /* IRQ handler active - do not enter! */
 +#define IRQ_DISABLED          0x00020000      /* IRQ disabled - do not enter! */
 +#define IRQ_PENDING           0x00040000      /* IRQ pending - replay on enable */
 +#define IRQ_REPLAY            0x00080000      /* IRQ has been replayed but not acked yet */
 +#define IRQ_AUTODETECT                0x00100000      /* IRQ is being autodetected */
 +#define IRQ_WAITING           0x00200000      /* IRQ not yet seen - for autodetection */
 +#define IRQ_LEVEL             0x00400000      /* IRQ level triggered */
 +#define IRQ_MASKED            0x00800000      /* IRQ masked - shouldn't be seen again */
  #ifdef CONFIG_IRQ_PER_CPU
 -# define IRQ_PER_CPU  256     /* IRQ is per CPU */
 +# define IRQ_PER_CPU          0x01000000      /* IRQ is per CPU */
  # define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU)
  #else
  # define CHECK_IRQ_PER_CPU(var) 0
  #endif
  
 -#define IRQ_NOPROBE   512     /* IRQ is not valid for probing */
 -#define IRQ_NOREQUEST 1024    /* IRQ cannot be requested */
 -#define IRQ_NOAUTOEN  2048    /* IRQ will not be enabled on request irq */
 -#define IRQ_DELAYED_DISABLE \
 -                      4096    /* IRQ disable (masking) happens delayed. */
 -
 -/*
 - * IRQ types, see also include/linux/interrupt.h
 - */
 -#define IRQ_TYPE_NONE         0x0000          /* Default, unspecified type */
 -#define IRQ_TYPE_EDGE_RISING  0x0001          /* Edge rising type */
 -#define IRQ_TYPE_EDGE_FALLING 0x0002          /* Edge falling type */
 -#define IRQ_TYPE_EDGE_BOTH (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)
 -#define IRQ_TYPE_LEVEL_HIGH   0x0004          /* Level high type */
 -#define IRQ_TYPE_LEVEL_LOW    0x0008          /* Level low type */
 -#define IRQ_TYPE_SENSE_MASK   0x000f          /* Mask of the above */
 -#define IRQ_TYPE_SIMPLE               0x0010          /* Simple type */
 -#define IRQ_TYPE_PERCPU               0x0020          /* Per CPU type */
 -#define IRQ_TYPE_PROBE                0x0040          /* Probing in progress */
 +#define IRQ_NOPROBE           0x02000000      /* IRQ is not valid for probing */
 +#define IRQ_NOREQUEST         0x04000000      /* IRQ cannot be requested */
 +#define IRQ_NOAUTOEN          0x08000000      /* IRQ will not be enabled on request irq */
 +#define IRQ_DELAYED_DISABLE   0x10000000      /* IRQ disable (masking) happens delayed. */
  
  struct proc_dir_entry;
  
@@@ -347,8 -348,9 +347,9 @@@ extern int noirqdebug_setup(char *str)
  /* Checks whether the interrupt can be requested by request_irq(): */
  extern int can_request_irq(unsigned int irq, unsigned long irqflags);
  
- /* Dummy irq-chip implementation: */
+ /* Dummy irq-chip implementations: */
  extern struct irq_chip no_irq_chip;
+ extern struct irq_chip dummy_irq_chip;
  
  extern void
  set_irq_chip_and_handler(unsigned int irq, struct irq_chip *chip,
diff --combined kernel/irq/handle.c
index 6070e046469018521279fb93c4466cffaa88790e,e71266c3803ef32f06a7620308d6450d4800274c..6d8b30114961a46669455b7e5721319751e94744
  #include <linux/interrupt.h>
  #include <linux/kernel_stat.h>
  
+ #if defined(CONFIG_NO_IDLE_HZ) && defined(CONFIG_ARM)
+ #include <asm/dyntick.h>
+ #endif
  #include "internals.h"
  
  /**
@@@ -91,6 -95,22 +95,22 @@@ struct irq_chip no_irq_chip = 
        .end            = noop,
  };
  
+ /*
+  * Generic dummy implementation which can be used for
+  * real dumb interrupt sources
+  */
+ struct irq_chip dummy_irq_chip = {
+       .name           = "dummy",
+       .startup        = noop_ret,
+       .shutdown       = noop,
+       .enable         = noop,
+       .disable        = noop,
+       .ack            = noop,
+       .mask           = noop,
+       .unmask         = noop,
+       .end            = noop,
+ };
  /*
   * Special, empty irq handler:
   */
@@@ -113,7 -133,16 +133,16 @@@ irqreturn_t handle_IRQ_event(unsigned i
        irqreturn_t ret, retval = IRQ_NONE;
        unsigned int status = 0;
  
 -      if (!(action->flags & SA_INTERRUPT))
+ #if defined(CONFIG_NO_IDLE_HZ) && defined(CONFIG_ARM)
+       if (!(action->flags & SA_TIMER) && system_timer->dyn_tick != NULL) {
+               write_seqlock(&xtime_lock);
+               if (system_timer->dyn_tick->state & DYN_TICK_ENABLED)
+                       system_timer->dyn_tick->handler(irq, 0, regs);
+               write_sequnlock(&xtime_lock);
+       }
+ #endif
 +      if (!(action->flags & IRQF_DISABLED))
                local_irq_enable();
  
        do {
                action = action->next;
        } while (action);
  
 -      if (status & SA_SAMPLE_RANDOM)
 +      if (status & IRQF_SAMPLE_RANDOM)
                add_interrupt_randomness(irq);
        local_irq_disable();