msm_shared: Move qgic code to msm_shared

QGIC is shared across multiple platforms and should reside
in msm_shared instead of duplicating code for all platforms.

Change-Id: If879192af552ec433da07c4c998bc62cad123c27
diff --git a/platform/msm8960/interrupts.c b/platform/msm8960/interrupts.c
deleted file mode 100644
index d040f2d..0000000
--- a/platform/msm8960/interrupts.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (c) 2008, Google Inc.
- * All rights reserved.
- *
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *  * Neither the name of Google, Inc. nor the names of its contributors
- *    may be used to endorse or promote products derived from this
- *    software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <debug.h>
-#include <reg.h>
-#include <arch/arm.h>
-#include <kernel/thread.h>
-#include <platform/interrupts.h>
-
-#include <platform/irqs.h>
-#include <platform/iomap.h>
-
-#define GIC_CPU_REG(off)            (MSM_GIC_CPU_BASE  + (off))
-#define GIC_DIST_REG(off)           (MSM_GIC_DIST_BASE + (off))
-
-#define GIC_CPU_CTRL                GIC_CPU_REG(0x00)
-#define GIC_CPU_PRIMASK             GIC_CPU_REG(0x04)
-#define GIC_CPU_BINPOINT            GIC_CPU_REG(0x08)
-#define GIC_CPU_INTACK              GIC_CPU_REG(0x0c)
-#define GIC_CPU_EOI                 GIC_CPU_REG(0x10)
-#define GIC_CPU_RUNNINGPRI          GIC_CPU_REG(0x14)
-#define GIC_CPU_HIGHPRI             GIC_CPU_REG(0x18)
-
-#define GIC_DIST_CTRL               GIC_DIST_REG(0x000)
-#define GIC_DIST_CTR                GIC_DIST_REG(0x004)
-#define GIC_DIST_ENABLE_SET         GIC_DIST_REG(0x100)
-#define GIC_DIST_ENABLE_CLEAR       GIC_DIST_REG(0x180)
-#define GIC_DIST_PENDING_SET        GIC_DIST_REG(0x200)
-#define GIC_DIST_PENDING_CLEAR      GIC_DIST_REG(0x280)
-#define GIC_DIST_ACTIVE_BIT         GIC_DIST_REG(0x300)
-#define GIC_DIST_PRI                GIC_DIST_REG(0x400)
-#define GIC_DIST_TARGET             GIC_DIST_REG(0x800)
-#define GIC_DIST_CONFIG             GIC_DIST_REG(0xc00)
-#define GIC_DIST_SOFTINT            GIC_DIST_REG(0xf00)
-
-struct ihandler {
-    int_handler func;
-    void *arg;
-};
-
-static struct ihandler handler[NR_IRQS];
-static void platform_gic_dist_init(void);
-static void platform_gic_cpu_init(void);
-
-void platform_init_interrupts(void)
-{
-    platform_gic_dist_init();
-    platform_gic_cpu_init();
-}
-
-void platform_gic_dist_init(void)
-{
-    unsigned int i;
-    unsigned num_irq = 0;
-    unsigned cpumask = 1;
-
-    cpumask |= cpumask << 8;
-    cpumask |= cpumask << 16;
-
-    /* Disabling GIC */
-    writel(0, GIC_DIST_CTRL);
-
-    /*
-     * Find out how many interrupts are supported.
-     */
-    num_irq = readl(GIC_DIST_CTR) & 0x1f;
-    num_irq = (num_irq + 1) * 32;
-
-    /* Set each interrupt line to use N-N software model
-       and edge sensitive, active high */
-    for (i=32; i < num_irq; i += 16)
-        writel(0xffffffff, GIC_DIST_CONFIG + i * 4/16 );
-
-    writel(0xffffffff, GIC_DIST_CONFIG + 4);
-
-    /* Set up interrupts for this CPU */
-    for (i = 32; i < num_irq; i += 4)
-        writel(cpumask, GIC_DIST_TARGET + i * 4 / 4);
-
-    /* Set priority of all interrupts*/
-
-    /*
-     * In bootloader we dont care about priority so
-     * setting up equal priorities for all
-     */
-    for (i=0; i < num_irq; i += 4)
-        writel(0xa0a0a0a0, GIC_DIST_PRI + i * 4/4);
-
-    /*Disabling interrupts*/
-    for (i=0; i < num_irq; i += 32)
-        writel(0xffffffff, GIC_DIST_ENABLE_CLEAR + i * 4/32);
-
-    writel(0x0000ffff, GIC_DIST_ENABLE_SET);
-
-    /*Enabling GIC*/
-    writel(1, GIC_DIST_CTRL);
-}
-
-void platform_gic_cpu_init(void)
-{
-    writel(0xf0, GIC_CPU_PRIMASK);
-    writel(1, GIC_CPU_CTRL);
-}
-
-enum handler_return platform_irq(struct arm_iframe *frame)
-{
-    unsigned num;
-    enum handler_return ret;
-    num = readl(GIC_CPU_INTACK);
-    if (num > NR_IRQS)
-        return 0;
-    ret = handler[num].func(handler[num].arg);
-    writel(num, GIC_CPU_EOI);
-    return ret;
-}
-
-void platform_fiq(struct arm_iframe *frame)
-{
-    PANIC_UNIMPLEMENTED;
-}
-
-status_t mask_interrupt(unsigned int vector)
-{
-    unsigned reg = GIC_DIST_ENABLE_CLEAR + (vector/32)*4;
-    unsigned bit = 1 << (vector & 31);
-    writel(bit, reg);
-    return 0;
-}
-
-status_t unmask_interrupt(unsigned int vector)
-{
-
-    unsigned reg = GIC_DIST_ENABLE_SET + (vector/32)*4;
-    unsigned bit = 1 << (vector & 31);
-    writel(bit, reg);
-    return 0;
-}
-
-void register_int_handler(unsigned int vector, int_handler func, void *arg)
-{
-    if (vector >= NR_IRQS)
-        return;
-
-    enter_critical_section();
-    handler[vector].func = func;
-    handler[vector].arg = arg;
-    exit_critical_section();
-}
-
-void clear_pending_int(void)
-{
-    unsigned num_irq = 0;
-
-    num_irq = readl(GIC_DIST_CTR) & 0x1f;
-    num_irq = (num_irq + 1) * 32;
-    unsigned i;
-    for (i = 0; i < num_irq; i += 32)
-        writel(0xffffffff, GIC_DIST_PENDING_CLEAR + i * 4 / 32);
-}
diff --git a/platform/msm8960/platform.c b/platform/msm8960/platform.c
index 054502b..4f20bc1 100644
--- a/platform/msm8960/platform.c
+++ b/platform/msm8960/platform.c
@@ -31,13 +31,13 @@
 #include <debug.h>
 #include <reg.h>
 #include <platform/iomap.h>
+#include <qgic.h>
 #include <uart_dm.h>
 #include <dev/fbcon.h>
 #include <mmu.h>
 #include <arch/arm/mmu.h>
 
 extern void platform_init_timer(void);
-extern void platform_init_interrupts(void);
 extern void mipi_panel_reset(void);
 extern void mipi_dsi_panel_power_on(void);
 extern void mdp_clock_init(void);
@@ -77,7 +77,7 @@
 void platform_early_init(void)
 {
     uart_init(target_uart_gsbi());
-    platform_init_interrupts();
+    qgic_init();
     platform_init_timer();
 }
 
diff --git a/platform/msm8960/rules.mk b/platform/msm8960/rules.mk
index 7804f60..fef2c6a 100644
--- a/platform/msm8960/rules.mk
+++ b/platform/msm8960/rules.mk
@@ -18,7 +18,6 @@
 
 OBJS += \
 	$(LOCAL_DIR)/platform.o \
-	$(LOCAL_DIR)/interrupts.o \
 	$(LOCAL_DIR)/acpuclock.o \
 	$(LOCAL_DIR)/gpio.o \
 
diff --git a/platform/msm8x60/interrupts.c b/platform/msm8x60/interrupts.c
deleted file mode 100755
index 8118981..0000000
--- a/platform/msm8x60/interrupts.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (c) 2008, Google Inc.
- * All rights reserved.
- *
- * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *  * Neither the name of Google, Inc. nor the names of its contributors
- *    may be used to endorse or promote products derived from this
- *    software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <debug.h>
-#include <arch/arm.h>
-#include <reg.h>
-#include <kernel/thread.h>
-#include <platform/interrupts.h>
-
-#include <platform/irqs.h>
-#include <platform/iomap.h>
-
-#define GIC_CPU_REG(off) (MSM_GIC_CPU_BASE + (off))
-#define GIC_DIST_REG(off) (MSM_GIC_DIST_BASE + (off))
-
-#define GIC_CPU_CTRL                GIC_CPU_REG(0x00)
-#define GIC_CPU_PRIMASK             GIC_CPU_REG(0x04)
-#define GIC_CPU_BINPOINT            GIC_CPU_REG(0x08)
-#define GIC_CPU_INTACK              GIC_CPU_REG(0x0c)
-#define GIC_CPU_EOI                 GIC_CPU_REG(0x10)
-#define GIC_CPU_RUNNINGPRI          GIC_CPU_REG(0x14)
-#define GIC_CPU_HIGHPRI             GIC_CPU_REG(0x18)
-
-#define GIC_DIST_CTRL               GIC_DIST_REG(0x000)
-#define GIC_DIST_CTR                GIC_DIST_REG(0x004)
-#define GIC_DIST_ENABLE_SET         GIC_DIST_REG(0x100)
-#define GIC_DIST_ENABLE_CLEAR       GIC_DIST_REG(0x180)
-#define GIC_DIST_PENDING_SET        GIC_DIST_REG(0x200)
-#define GIC_DIST_PENDING_CLEAR      GIC_DIST_REG(0x280)
-#define GIC_DIST_ACTIVE_BIT         GIC_DIST_REG(0x300)
-#define GIC_DIST_PRI                GIC_DIST_REG(0x400)
-#define GIC_DIST_TARGET             GIC_DIST_REG(0x800)
-#define GIC_DIST_CONFIG             GIC_DIST_REG(0xc00)
-#define GIC_DIST_SOFTINT            GIC_DIST_REG(0xf00)
-
-struct ihandler {
-    int_handler func;
-    void *arg;
-};
-
-static struct ihandler handler[NR_IRQS];
-
-void platform_init_interrupts(void)
-{
-    platform_gic_dist_init();
-    platform_gic_cpu_init();
-}
-
-void platform_gic_dist_init(void)
-{
-    unsigned int i;
-    unsigned num_irq = 0;
-    unsigned cpumask = 1;
-
-    cpumask |= cpumask << 8;
-    cpumask |= cpumask << 16;
-
-    /* Disabling GIC */
-    writel(0, GIC_DIST_CTRL);
-
-    /*
-     * Find out how many interrupts are supported.
-     */
-    num_irq = readl(GIC_DIST_CTR) & 0x1f;
-    num_irq = (num_irq + 1) * 32;
-
-    /* Set each interrupt line to use N-N software model
-       and edge sensitive, active high */
-    for (i=32; i < num_irq; i += 16)
-        writel(0xffffffff, GIC_DIST_CONFIG + i * 4/16 );
-
-    writel(0xffffffff, GIC_DIST_CONFIG + 4);
-
-    /* Set up interrupts for this CPU */
-    for (i = 32; i < num_irq; i += 4)
-        writel(cpumask, GIC_DIST_TARGET + i * 4 / 4);
-
-    /* Set priority of all interrupts*/
-
-    /*
-     * In bootloader we dont care about priority so
-     * setting up equal priorities for all
-     */
-    for (i=0; i < num_irq; i += 4)
-        writel(0xa0a0a0a0, GIC_DIST_PRI + i * 4/4);
-
-    /*Disabling interrupts*/
-    for (i=0; i < num_irq; i += 32)
-        writel(0xffffffff, GIC_DIST_ENABLE_CLEAR + i * 4/32);
-
-    writel(0x0000ffff, GIC_DIST_ENABLE_SET);
-
-    /*Enabling GIC*/
-    writel(1, GIC_DIST_CTRL);
-}
-
-void platform_gic_cpu_init(void)
-{
-    writel(0xf0, GIC_CPU_PRIMASK);
-    writel(1, GIC_CPU_CTRL);
-}
-
-enum handler_return platform_irq(struct arm_iframe *frame)
-{
-    unsigned num;
-    enum handler_return ret;
-    num = readl(GIC_CPU_INTACK);
-    if (num > NR_IRQS)
-        return 0;
-    ret = handler[num].func(handler[num].arg);
-    writel(num, GIC_CPU_EOI);
-    return ret;
-}
-
-void platform_fiq(struct arm_iframe *frame)
-{
-    PANIC_UNIMPLEMENTED;
-}
-
-status_t mask_interrupt(unsigned int vector)
-{
-    unsigned reg = GIC_DIST_ENABLE_CLEAR + (vector/32)*4;
-    unsigned bit = 1 << (vector & 31);
-    writel(bit, reg);
-    return 0;
-}
-
-status_t unmask_interrupt(unsigned int vector)
-{
-
-    unsigned reg = GIC_DIST_ENABLE_SET + (vector/32)*4;
-    unsigned bit = 1 << (vector & 31);
-    writel(bit, reg);
-    return 0;
-}
-
-void register_int_handler(unsigned int vector, int_handler func, void *arg)
-{
-    if (vector >= NR_IRQS)
-        return;
-
-    enter_critical_section();
-    handler[vector].func = func;
-    handler[vector].arg = arg;
-    exit_critical_section();
-}
-
-void clear_pending_int(void)
-{
-    unsigned num_irq = 0;
-
-    num_irq = readl(GIC_DIST_CTR) & 0x1f;
-    num_irq = (num_irq + 1) * 32;
-    unsigned i;
-    for (i = 0; i < num_irq; i += 32)
-        writel(0xffffffff, GIC_DIST_PENDING_CLEAR + i * 4 / 32);
-}
diff --git a/platform/msm8x60/platform.c b/platform/msm8x60/platform.c
old mode 100755
new mode 100644
index 63d72bf..80dae3b
--- a/platform/msm8x60/platform.c
+++ b/platform/msm8x60/platform.c
@@ -37,6 +37,7 @@
 #include <kernel/thread.h>
 #include <platform/debug.h>
 #include <platform/iomap.h>
+#include <qgic.h>
 #include <i2c_qup.h>
 #include <gsbi.h>
 #include <uart_dm.h>
@@ -93,10 +94,8 @@
     uint32_t reserved2;
 }__attribute__((packed));
 
-void platform_init_interrupts(void);
 void platform_init_timer();
 
-void uart3_clock_init(void);
 
 struct fbcon_config *lcdc_init(void);
 
@@ -109,7 +108,7 @@
 void platform_early_init(void)
 {
     uart_init(target_uart_gsbi());
-    platform_init_interrupts();
+    qgic_init();
     platform_init_timer();
 }
 
diff --git a/platform/msm8x60/rules.mk b/platform/msm8x60/rules.mk
index 2aa1d55..0c45242 100644
--- a/platform/msm8x60/rules.mk
+++ b/platform/msm8x60/rules.mk
@@ -22,7 +22,6 @@
 
 OBJS += \
 	$(LOCAL_DIR)/platform.o \
-	$(LOCAL_DIR)/interrupts.o \
 	$(LOCAL_DIR)/acpuclock.o \
 	$(LOCAL_DIR)/gpio.o \
 	$(LOCAL_DIR)/panel.o \
diff --git a/platform/msm_shared/include/qgic.h b/platform/msm_shared/include/qgic.h
new file mode 100644
index 0000000..956cf89
--- /dev/null
+++ b/platform/msm_shared/include/qgic.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PLATFORM_MSM_SHARED_QGIC_H
+#define __PLATFORM_MSM_SHARED_QGIC_H
+
+#include <platform/iomap.h>
+#include <platform/interrupts.h>
+
+#define GIC_CPU_REG(off)            (MSM_GIC_CPU_BASE  + (off))
+#define GIC_DIST_REG(off)           (MSM_GIC_DIST_BASE + (off))
+
+#define GIC_CPU_CTRL                GIC_CPU_REG(0x00)
+#define GIC_CPU_PRIMASK             GIC_CPU_REG(0x04)
+#define GIC_CPU_BINPOINT            GIC_CPU_REG(0x08)
+#define GIC_CPU_INTACK              GIC_CPU_REG(0x0c)
+#define GIC_CPU_EOI                 GIC_CPU_REG(0x10)
+#define GIC_CPU_RUNNINGPRI          GIC_CPU_REG(0x14)
+#define GIC_CPU_HIGHPRI             GIC_CPU_REG(0x18)
+
+#define GIC_DIST_CTRL               GIC_DIST_REG(0x000)
+#define GIC_DIST_CTR                GIC_DIST_REG(0x004)
+#define GIC_DIST_ENABLE_SET         GIC_DIST_REG(0x100)
+#define GIC_DIST_ENABLE_CLEAR       GIC_DIST_REG(0x180)
+#define GIC_DIST_PENDING_SET        GIC_DIST_REG(0x200)
+#define GIC_DIST_PENDING_CLEAR      GIC_DIST_REG(0x280)
+#define GIC_DIST_ACTIVE_BIT         GIC_DIST_REG(0x300)
+#define GIC_DIST_PRI                GIC_DIST_REG(0x400)
+#define GIC_DIST_TARGET             GIC_DIST_REG(0x800)
+#define GIC_DIST_CONFIG             GIC_DIST_REG(0xc00)
+#define GIC_DIST_SOFTINT            GIC_DIST_REG(0xf00)
+
+struct ihandler {
+    int_handler func;
+    void *arg;
+};
+
+void qgic_init(void);
+
+#endif
diff --git a/platform/msm_shared/qgic.c b/platform/msm_shared/qgic.c
new file mode 100644
index 0000000..af90fbb
--- /dev/null
+++ b/platform/msm_shared/qgic.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2008, Google Inc.
+ * All rights reserved.
+ *
+ * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name of Google, Inc. nor the names of its contributors
+ *    may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <reg.h>
+#include <debug.h>
+#include <arch/arm.h>
+#include <kernel/thread.h>
+#include <platform/irqs.h>
+#include <qgic.h>
+
+static struct ihandler handler[NR_IRQS];
+
+/* Intialize distributor */
+static void qgic_dist_init(void)
+{
+	uint32_t i;
+	uint32_t num_irq = 0;
+	uint32_t cpumask = 1;
+
+	cpumask |= cpumask << 8;
+	cpumask |= cpumask << 16;
+
+	/* Disabling GIC */
+	writel(0, GIC_DIST_CTRL);
+
+	/*
+	 * Find out how many interrupts are supported.
+	 */
+	num_irq = readl(GIC_DIST_CTR) & 0x1f;
+	num_irq = (num_irq + 1) * 32;
+
+	/* Set each interrupt line to use N-N software model
+	 * and edge sensitive, active high
+	 */
+	for (i=32; i < num_irq; i += 16)
+		writel(0xffffffff, GIC_DIST_CONFIG + i * 4/16 );
+
+	writel(0xffffffff, GIC_DIST_CONFIG + 4);
+
+	/* Set up interrupts for this CPU */
+	for (i = 32; i < num_irq; i += 4)
+		writel(cpumask, GIC_DIST_TARGET + i * 4 / 4);
+
+	/* Set priority of all interrupts*/
+
+	/*
+	 * In bootloader we dont care about priority so
+	 * setting up equal priorities for all
+	 */
+	for (i=0; i < num_irq; i += 4)
+		writel(0xa0a0a0a0, GIC_DIST_PRI + i * 4/4);
+
+	/* Disabling interrupts*/
+	for (i=0; i < num_irq; i += 32)
+		writel(0xffffffff, GIC_DIST_ENABLE_CLEAR + i * 4/32);
+
+	writel(0x0000ffff, GIC_DIST_ENABLE_SET);
+
+	/*Enabling GIC*/
+	writel(1, GIC_DIST_CTRL);
+}
+
+/* Intialize cpu specific controller */
+static void qgic_cpu_init(void)
+{
+	writel(0xf0, GIC_CPU_PRIMASK);
+	writel(1, GIC_CPU_CTRL);
+}
+
+/* Initialize QGIC. Called from platform specific init code */
+void qgic_init(void)
+{
+	qgic_dist_init();
+	qgic_cpu_init();
+}
+
+/* IRQ handler */
+enum handler_return platform_irq(struct arm_iframe *frame)
+{
+	uint32_t num;
+	enum handler_return ret;
+
+	num = readl(GIC_CPU_INTACK);
+	if (num > NR_IRQS)
+		return 0;
+
+	ret = handler[num].func(handler[num].arg);
+	writel(num, GIC_CPU_EOI);
+
+	return ret;
+}
+
+/* FIQ handler */
+void platform_fiq(struct arm_iframe *frame)
+{
+	PANIC_UNIMPLEMENTED;
+}
+
+/* Mask interrupt */
+status_t mask_interrupt(unsigned int vector)
+{
+	uint32_t reg = GIC_DIST_ENABLE_CLEAR + (vector/32)*4;
+	uint32_t bit = 1 << (vector & 31);
+
+	writel(bit, reg);
+
+	return 0;
+}
+
+/* Un-mask interrupt */
+status_t unmask_interrupt(unsigned int vector)
+{
+	uint32_t reg = GIC_DIST_ENABLE_SET + (vector/32)*4;
+	uint32_t bit = 1 << (vector & 31);
+
+	writel(bit, reg);
+
+	return 0;
+}
+
+/* Register interrupt handler */
+void register_int_handler(unsigned int vector, int_handler func, void *arg)
+{
+	ASSERT(vector < NR_IRQS);
+
+	enter_critical_section();
+	handler[vector].func = func;
+	handler[vector].arg = arg;
+	exit_critical_section();
+}
+
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index 39d5cb6..d64947f 100644
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -20,40 +20,42 @@
 
 ifeq ($(PLATFORM),msm8x60)
 	OBJS += $(LOCAL_DIR)/mipi_dsi.o \
-	        $(LOCAL_DIR)/i2c_qup.o \
-	        $(LOCAL_DIR)/uart_dm.o \
-	        $(LOCAL_DIR)/crypto_eng.o \
-	        $(LOCAL_DIR)/crypto_hash.o \
-		$(LOCAL_DIR)/scm_decrypt.o \
-		$(LOCAL_DIR)/lcdc.o \
-		$(LOCAL_DIR)/mddi.o
+			$(LOCAL_DIR)/i2c_qup.o \
+			$(LOCAL_DIR)/uart_dm.o \
+			$(LOCAL_DIR)/crypto_eng.o \
+			$(LOCAL_DIR)/crypto_hash.o \
+			$(LOCAL_DIR)/scm_decrypt.o \
+			$(LOCAL_DIR)/lcdc.o \
+			$(LOCAL_DIR)/mddi.o \
+			$(LOCAL_DIR)/qgic.o
 endif
 
 ifeq ($(PLATFORM),msm8960)
 	OBJS += $(LOCAL_DIR)/mipi_dsi.o \
-	        $(LOCAL_DIR)/i2c_qup.o \
-	        $(LOCAL_DIR)/uart_dm.o
+			$(LOCAL_DIR)/i2c_qup.o \
+			$(LOCAL_DIR)/uart_dm.o \
+			$(LOCAL_DIR)/qgic.o
 endif
 
 ifeq ($(PLATFORM),msm7x27a)
 	OBJS += $(LOCAL_DIR)/uart.o \
-		$(LOCAL_DIR)/proc_comm.o \
-		$(LOCAL_DIR)/lcdc.o \
-		$(LOCAL_DIR)/mddi.o
+			$(LOCAL_DIR)/proc_comm.o \
+			$(LOCAL_DIR)/lcdc.o \
+			$(LOCAL_DIR)/mddi.o
 endif
 
 ifeq ($(PLATFORM),msm7k)
 	OBJS += $(LOCAL_DIR)/uart.o \
-		$(LOCAL_DIR)/proc_comm.o \
-		$(LOCAL_DIR)/lcdc.o \
-		$(LOCAL_DIR)/mddi.o
+			$(LOCAL_DIR)/proc_comm.o \
+			$(LOCAL_DIR)/lcdc.o \
+			$(LOCAL_DIR)/mddi.o
 endif
 
 ifeq ($(PLATFORM),msm7x30)
 	OBJS += $(LOCAL_DIR)/crypto_eng.o \
-		$(LOCAL_DIR)/crypto_hash.o \
-		$(LOCAL_DIR)/uart.o \
-		$(LOCAL_DIR)/proc_comm.o \
-		$(LOCAL_DIR)/lcdc.o \
-		$(LOCAL_DIR)/mddi.o
+			$(LOCAL_DIR)/crypto_hash.o \
+			$(LOCAL_DIR)/uart.o \
+			$(LOCAL_DIR)/proc_comm.o \
+			$(LOCAL_DIR)/lcdc.o \
+			$(LOCAL_DIR)/mddi.o
 endif