omap: gpmc: enable irq mode in gpmc
authorSukumar Ghorai <s-ghorai@ti.com>
Fri, 28 Jan 2011 10:12:05 +0000 (15:42 +0530)
committerTony Lindgren <tony@atomide.com>
Thu, 17 Feb 2011 23:32:53 +0000 (15:32 -0800)
add support the irq mode in GPMC.
gpmc_init() function move after omap_init_irq() as it has dependecy on irq.

Signed-off-by: Sukumar Ghorai <s-ghorai@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
arch/arm/mach-omap2/gpmc.c
arch/arm/mach-omap2/io.c
arch/arm/plat-omap/include/plat/gpmc.h
arch/arm/plat-omap/include/plat/irqs.h

index 1b7b3e7d02f74f6fd606244baa2c2d366968109e..382dea83e4f038a74f0677418f5212ab8e2b76aa 100644 (file)
@@ -14,6 +14,7 @@
  */
 #undef DEBUG
 
+#include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/err.h>
@@ -22,6 +23,7 @@
 #include <linux/spinlock.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/interrupt.h>
 
 #include <asm/mach-types.h>
 #include <plat/gpmc.h>
@@ -100,6 +102,8 @@ static void __iomem *gpmc_base;
 
 static struct clk *gpmc_l3_clk;
 
+static irqreturn_t gpmc_handle_irq(int irq, void *dev);
+
 static void gpmc_write_reg(int idx, u32 val)
 {
        __raw_writel(val, gpmc_base + idx);
@@ -497,6 +501,10 @@ int gpmc_cs_configure(int cs, int cmd, int wval)
        u32 regval = 0;
 
        switch (cmd) {
+       case GPMC_ENABLE_IRQ:
+               gpmc_write_reg(GPMC_IRQENABLE, wval);
+               break;
+
        case GPMC_SET_IRQ_STATUS:
                gpmc_write_reg(GPMC_IRQSTATUS, wval);
                break;
@@ -678,9 +686,10 @@ static void __init gpmc_mem_init(void)
        }
 }
 
-void __init gpmc_init(void)
+static int __init gpmc_init(void)
 {
-       u32 l;
+       u32 l, irq;
+       int cs, ret = -EINVAL;
        char *ck = NULL;
 
        if (cpu_is_omap24xx()) {
@@ -698,7 +707,7 @@ void __init gpmc_init(void)
        }
 
        if (WARN_ON(!ck))
-               return;
+               return ret;
 
        gpmc_l3_clk = clk_get(NULL, ck);
        if (IS_ERR(gpmc_l3_clk)) {
@@ -723,6 +732,36 @@ void __init gpmc_init(void)
        l |= (0x02 << 3) | (1 << 0);
        gpmc_write_reg(GPMC_SYSCONFIG, l);
        gpmc_mem_init();
+
+       /* initalize the irq_chained */
+       irq = OMAP_GPMC_IRQ_BASE;
+       for (cs = 0; cs < GPMC_CS_NUM; cs++) {
+               set_irq_handler(irq, handle_simple_irq);
+               set_irq_flags(irq, IRQF_VALID);
+               irq++;
+       }
+
+       ret = request_irq(INT_34XX_GPMC_IRQ,
+                       gpmc_handle_irq, IRQF_SHARED, "gpmc", gpmc_base);
+       if (ret)
+               pr_err("gpmc: irq-%d could not claim: err %d\n",
+                                               INT_34XX_GPMC_IRQ, ret);
+       return ret;
+}
+postcore_initcall(gpmc_init);
+
+static irqreturn_t gpmc_handle_irq(int irq, void *dev)
+{
+       u8 cs;
+
+       if (irq != INT_34XX_GPMC_IRQ)
+               return IRQ_HANDLED;
+       /* check cs to invoke the irq */
+       cs = ((gpmc_read_reg(GPMC_PREFETCH_CONFIG1)) >> CS_NUM_SHIFT) & 0x7;
+       if (OMAP_GPMC_IRQ_BASE+cs <= OMAP_GPMC_IRQ_END)
+               generic_handle_irq(OMAP_GPMC_IRQ_BASE+cs);
+
+       return IRQ_HANDLED;
 }
 
 #ifdef CONFIG_ARCH_OMAP3
index b8b49e4ae928b32014b5e09a3b70a3ef6d0a8c21..657f3c84687c24fa4d50a1606709a9402913fd7c 100644 (file)
@@ -30,7 +30,6 @@
 
 #include <plat/sram.h>
 #include <plat/sdrc.h>
-#include <plat/gpmc.h>
 #include <plat/serial.h>
 
 #include "clock2xxx.h"
@@ -422,7 +421,6 @@ void __init omap2_init_common_devices(struct omap_sdrc_params *sdrc_cs0,
                omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
                _omap2_init_reprogram_sdrc();
        }
-       gpmc_init();
 
        omap_irq_base_init();
 }
index 85ded598853e60af6baf3f7f9d12d4939b08b0cb..9c060da0a873db3c475d311c86b9a1c3bf9d4819 100644 (file)
@@ -41,6 +41,8 @@
 #define GPMC_NAND_ADDRESS      0x0000000b
 #define GPMC_NAND_DATA         0x0000000c
 
+#define GPMC_ENABLE_IRQ                0x0000000d
+
 /* ECC commands */
 #define GPMC_ECC_READ          0 /* Reset Hardware ECC for read */
 #define GPMC_ECC_WRITE         1 /* Reset Hardware ECC for write */
@@ -78,6 +80,8 @@
 #define WR_RD_PIN_MONITORING           0x00600000
 #define GPMC_PREFETCH_STATUS_FIFO_CNT(val)     ((val >> 24) & 0x7F)
 #define GPMC_PREFETCH_STATUS_COUNT(val)        (val & 0x00003fff)
+#define GPMC_IRQ_FIFOEVENTENABLE       0x01
+#define GPMC_IRQ_COUNT_EVENT           0x02
 
 /*
  * Note that all values in this struct are in nanoseconds except sync_clk
@@ -135,7 +139,6 @@ extern int gpmc_prefetch_enable(int cs, int dma_mode,
 extern int gpmc_prefetch_reset(int cs);
 extern void omap3_gpmc_save_context(void);
 extern void omap3_gpmc_restore_context(void);
-extern void gpmc_init(void);
 extern int gpmc_read_status(int cmd);
 extern int gpmc_cs_configure(int cs, int cmd, int wval);
 extern int gpmc_nand_read(int cs, int cmd);
index 2910de921c52b3acf70246ccd55d1da0611b40a5..1b911681e911bd93d0e0a208d1d670049519edf8 100644 (file)
 #define INT_34XX_PRCM_MPU_IRQ  11
 #define INT_34XX_MCBSP1_IRQ    16
 #define INT_34XX_MCBSP2_IRQ    17
+#define INT_34XX_GPMC_IRQ      20
 #define INT_34XX_MCBSP3_IRQ    22
 #define INT_34XX_MCBSP4_IRQ    23
 #define INT_34XX_CAM_IRQ       24
 #define TWL_IRQ_END            TWL6030_IRQ_END
 #endif
 
-#define NR_IRQS                        TWL_IRQ_END
+/* GPMC related */
+#define OMAP_GPMC_IRQ_BASE     (TWL_IRQ_END)
+#define OMAP_GPMC_NR_IRQS      7
+#define OMAP_GPMC_IRQ_END      (OMAP_GPMC_IRQ_BASE + OMAP_GPMC_NR_IRQS)
+
+
+#define NR_IRQS                        OMAP_GPMC_IRQ_END
 
 #define OMAP_IRQ_BIT(irq)      (1 << ((irq) % 32))