summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-tegra/Makefile1
-rw-r--r--arch/arm/mach-tegra/board_nvodm.c76
-rw-r--r--arch/arm/mach-tegra/gpio.c89
-rw-r--r--arch/arm/mach-tegra/include/mach/irqs.h46
-rwxr-xr-xarch/arm/mach-tegra/init_common.c52
-rw-r--r--arch/arm/mach-tegra/irq.c436
-rw-r--r--arch/arm/mach-tegra/irq_dma.c125
-rw-r--r--arch/arm/mach-tegra/irq_gpio.c315
-rw-r--r--arch/arm/mach-tegra/nvos/nvos.c10
-rw-r--r--arch/arm/mach-tegra/power-context-t2.c372
-rw-r--r--arch/arm/mach-tegra/power-t2.c177
11 files changed, 445 insertions, 1254 deletions
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index decf60bb0e2e..8a73618b997c 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -11,7 +11,6 @@ endif
obj-y += clock.o
obj-y += io.o
obj-y += irq.o
-obj-y += irq_dma.o
obj-y += gpio.o
obj-y += timer.o
obj-y += tegra_sysmap.o
diff --git a/arch/arm/mach-tegra/board_nvodm.c b/arch/arm/mach-tegra/board_nvodm.c
index 907d708a310a..f81736679916 100644
--- a/arch/arm/mach-tegra/board_nvodm.c
+++ b/arch/arm/mach-tegra/board_nvodm.c
@@ -33,6 +33,8 @@
#include <asm/mach/arch.h>
#include <mach/board.h>
+#include <mach/platform.h>
+#include <mach/kbc.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
@@ -155,14 +157,6 @@ static struct platform_device tegra_accelerometer_device =
};
#endif
-#ifdef CONFIG_KEYBOARD_TEGRA
-static struct platform_device tegra_kbc_device =
-{
- .name = "tegra_kbc",
- .id = -1,
-};
-#endif
-
#ifdef CONFIG_INPUT_TEGRA_ODM_SCROLL
static struct platform_device tegra_scrollwheel_device =
{
@@ -392,6 +386,68 @@ static void __init register_enc28j60(void)
}
#endif
+#ifndef CONFIG_KEYBOARD_TEGRA
+#define kbc_init() do { } while (0)
+
+#else
+extern struct tegra_kbc_plat *tegra_kbc_odm_to_plat(void);
+
+static void kbc_init(void)
+{
+ struct platform_device *dev = NULL;
+ struct tegra_kbc_plat *pdata = NULL;
+ static struct resource res[2];
+
+ dev = platform_device_alloc("tegra_kbc", -1);
+ if (!dev)
+ goto fail;
+
+ pdata = tegra_kbc_odm_to_plat();
+ if (!pdata) {
+ pr_err("tegra_kbc ODM kit to platform data translation failed\n");
+ goto fail;
+ }
+
+ res[0].flags = IORESOURCE_MEM;
+ res[0].start = tegra_get_module_inst_base("kbc", 0);
+ res[0].end = (res[0].start + tegra_get_module_inst_size("kbc", 0));
+ res[1].flags = IORESOURCE_IRQ;
+ res[1].start = res[1].end =
+ tegra_get_module_inst_irq("kbc", 0, 0);
+
+ if ((res[0].end <= res[0].start) || (res[1].start == NO_IRQ)) {
+ pr_err("no tegra_kbc module present\n");
+ goto fail;
+ }
+
+ if (platform_device_add_resources(dev, res, ARRAY_SIZE(res))) {
+ pr_err("failed to add resources to tegra_kbc device\n");
+ goto fail;
+ }
+
+ if (platform_device_add_data(dev, pdata, sizeof(*pdata))) {
+ pr_err("failed to add platform data to tegra_kbc device\n");
+ goto fail;
+ }
+
+ /* fixme: something about wakeup irq, here */
+
+ if (platform_device_add(dev)) {
+ pr_err("failed to add tegra_kbc device\n");
+ goto fail;
+ }
+
+ return;
+
+fail:
+ if (dev)
+ platform_device_del(dev);
+
+ kfree(pdata);
+ return;
+}
+#endif
+
static void __init tegra_machine_init(void)
{
#if defined(CONFIG_USB_ANDROID) || defined(CONFIG_USB_ANDROID_MODULE)
@@ -436,9 +492,7 @@ static void __init tegra_machine_init(void)
(void) platform_device_register(&tegra_rtc_device);
#endif
-#ifdef CONFIG_KEYBOARD_TEGRA
- (void) platform_device_register(&tegra_kbc_device);
-#endif
+ kbc_init();
#if defined(CONFIG_BATTERY_TEGRA_ODM) || defined(CONFIG_TEGRA_BATTERY_NVEC)
(void) platform_device_register(&tegra_battery_device);
diff --git a/arch/arm/mach-tegra/gpio.c b/arch/arm/mach-tegra/gpio.c
index d40f3345e0af..fcd706c717c3 100644
--- a/arch/arm/mach-tegra/gpio.c
+++ b/arch/arm/mach-tegra/gpio.c
@@ -28,6 +28,8 @@
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/io.h>
+#include <linux/interrupt.h>
+
#include <asm/io.h>
#include <asm/gpio.h>
@@ -68,6 +70,13 @@ struct tegra_gpio_bank {
int bank;
int irq;
spinlock_t lvl_lock[4];
+#ifdef CONFIG_PM
+ u32 cnf[4];
+ u32 out[4];
+ u32 oe[4];
+ u32 int_enb[4];
+ u32 int_lvl[4];
+#endif
};
static struct tegra_gpio_bank tegra_gpio_banks[] = {
@@ -121,12 +130,13 @@ static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
return 0;
}
-static int tegra_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
- int value)
+static int tegra_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
{
tegra_gpio_mask_write(GPIO_MSK_OE(offset), offset, 1);
return 0;
}
+
static struct gpio_chip tegra_gpio_chip = {
.label = "tegra-gpio",
.direction_input = tegra_gpio_direction_input,
@@ -209,14 +219,77 @@ static int tegra_gpio_irq_set_type(unsigned int irq, unsigned int type)
return 0;
}
+#ifdef CONFIG_PM
+void tegra_gpio_resume(void)
+{
+ unsigned long flags;
+ int b, p, i;
+
+ local_irq_save(flags);
+
+ for (b=0; b<ARRAY_SIZE(tegra_gpio_banks); b++) {
+ struct tegra_gpio_bank *bank = &tegra_gpio_banks[b];
+
+ for (p=0; p<ARRAY_SIZE(bank->oe); p++) {
+ unsigned int gpio = (b<<5) | (p<<3);
+ __raw_writel(bank->cnf[p], GPIO_CNF(gpio));
+ __raw_writel(bank->out[p], GPIO_OUT(gpio));
+ __raw_writel(bank->oe[p], GPIO_OE(gpio));
+ __raw_writel(bank->int_lvl[p], GPIO_INT_LVL(gpio));
+ __raw_writel(bank->int_enb[p], GPIO_INT_ENB(gpio));
+ }
+
+ }
+
+ local_irq_restore(flags);
+
+ for (i=INT_GPIO_BASE; i<(INT_GPIO_BASE+ARCH_NR_GPIOS); i++) {
+ struct irq_desc *desc = irq_to_desc(i);
+ if (!desc || (desc->status & IRQ_WAKEUP)) continue;
+ enable_irq(i);
+ }
+}
+
+void tegra_gpio_suspend(void)
+{
+ unsigned long flags;
+ int b, p, i;
+
+
+ for (i=INT_GPIO_BASE; i<(INT_GPIO_BASE+ARCH_NR_GPIOS); i++) {
+ struct irq_desc *desc = irq_to_desc(i);
+ if (!desc) continue;
+ if (desc->status & IRQ_WAKEUP) {
+ int gpio = i - INT_GPIO_BASE;
+ pr_debug("gpio %d.%d is wakeup\n", gpio/8, gpio&7);
+ continue;
+ }
+ disable_irq(i);
+ }
+
+ local_irq_save(flags);
+ for (b=0; b<ARRAY_SIZE(tegra_gpio_banks); b++) {
+ struct tegra_gpio_bank *bank = &tegra_gpio_banks[b];
+
+ for (p=0; p<ARRAY_SIZE(bank->oe); p++) {
+ unsigned int gpio = (b<<5) | (p<<3);
+ bank->cnf[p] = __raw_readl(GPIO_CNF(gpio));
+ bank->out[p] = __raw_readl(GPIO_OUT(gpio));
+ bank->oe[p] = __raw_readl(GPIO_OE(gpio));
+ bank->int_enb[p] = __raw_readl(GPIO_INT_ENB(gpio));
+ bank->int_lvl[p] = __raw_readl(GPIO_INT_LVL(gpio));
+ }
+
+ }
+ local_irq_restore(flags);
+}
+
static int tegra_gpio_wake_enable(unsigned int irq, unsigned int enable)
{
- if (enable)
- tegra_gpio_irq_unmask(irq);
- else
- tegra_gpio_irq_mask(irq);
- return 0;
+ struct tegra_gpio_bank *bank = get_irq_chip_data(irq);
+ return set_irq_wake(bank->irq, enable);
}
+#endif
static struct irq_chip tegra_gpio_irq_chip = {
.name = "GPIO",
@@ -224,7 +297,9 @@ static struct irq_chip tegra_gpio_irq_chip = {
.mask = tegra_gpio_irq_mask,
.unmask = tegra_gpio_irq_unmask,
.set_type = tegra_gpio_irq_set_type,
+#ifdef CONFIG_PM
.set_wake = tegra_gpio_wake_enable,
+#endif
};
static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
diff --git a/arch/arm/mach-tegra/include/mach/irqs.h b/arch/arm/mach-tegra/include/mach/irqs.h
index eacbb6cf1f63..0851d73947b9 100644
--- a/arch/arm/mach-tegra/include/mach/irqs.h
+++ b/arch/arm/mach-tegra/include/mach/irqs.h
@@ -21,29 +21,43 @@
#ifndef __MACH_TEGRA_IRQS_H
#define __MACH_TEGRA_IRQS_H
-
-#if defined(CONFIG_ARCH_TEGRA_1x_SOC)
-#define NR_IRQS 512
-#elif defined(CONFIG_ARCH_TEGRA_2x_SOC)
+#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
#define NR_IRQS 512
-/* Gpio interrupt details */
-#define INT_SEC_BASE 64
-#define INT_GPIO1 (INT_SEC_BASE + 0)
-#define INT_GPIO2 (INT_SEC_BASE + 1)
-#define INT_GPIO3 (INT_SEC_BASE + 2)
-#define INT_GPIO4 (INT_SEC_BASE + 3)
-#define INT_GPIO5 (INT_SEC_BASE + 23)
+#define INT_PRI_BASE 32
+#define INT_RTC (INT_PRI_BASE + 2)
+#define INT_USB (INT_PRI_BASE + 20)
+#define INT_USB2 (INT_PRI_BASE + 21)
+#define INT_APB_DMA (INT_PRI_BASE + 26)
+
+#define INT_SEC_BASE (INT_PRI_BASE + 32)
+#define INT_GPIO1 (INT_SEC_BASE + 0)
+#define INT_GPIO2 (INT_SEC_BASE + 1)
+#define INT_GPIO3 (INT_SEC_BASE + 2)
+#define INT_GPIO4 (INT_SEC_BASE + 3)
+#define INT_SYS_STATS_MON (INT_SEC_BASE + 22)
+#define INT_GPIO5 (INT_SEC_BASE + 23)
-#define INT_TRI_BASE 96
-#define INT_GPIO6 (INT_TRI_BASE + 23)
-#define INT_GPIO7 (INT_TRI_BASE + 25)
+#define INT_TRI_BASE (INT_SEC_BASE + 32)
+#define INT_KBC (INT_TRI_BASE + 21)
+#define INT_EXTERNAL_PMU (INT_TRI_BASE + 22)
+#define INT_GPIO6 (INT_TRI_BASE + 23)
+#define INT_GPIO7 (INT_TRI_BASE + 25)
-#define INT_GPIO_BASE (128 + 32)
-#define INT_GPIO_NR (7*4* 8)
+#define INT_QUAD_BASE (INT_TRI_BASE + 32)
+#define INT_USB3 (INT_QUAD_BASE + 1)
+
+#define INT_GPIO_BASE (INT_QUAD_BASE + 32)
+#define INT_GPIO_NR (28*8)
+
+#define INT_APBDMA_BASE (INT_GPIO_BASE + INT_GPIO_NR)
+#define INT_APBDMA_NR (16)
#else
#error "Invalid Tegra SoC family selection"
#endif
+#define INT_SYS_NR (INT_GPIO_BASE - INT_PRI_BASE)
+#define INT_SYS_SZ (INT_SEC_BASE - INT_PRI_BASE)
+
#endif
diff --git a/arch/arm/mach-tegra/init_common.c b/arch/arm/mach-tegra/init_common.c
index c890fb66bdc0..df1453d999bd 100755
--- a/arch/arm/mach-tegra/init_common.c
+++ b/arch/arm/mach-tegra/init_common.c
@@ -26,7 +26,10 @@
#include <linux/fsl_devices.h>
#include <linux/dma-mapping.h>
#include <linux/tegra_devices.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
#include <mach/iovmm.h>
+#include <mach/gpio-names.h>
#include "nvcommon.h"
#include "nvrm_init.h"
#include "nvrm_drf.h"
@@ -952,6 +955,46 @@ static void __init tegra_init_cpu(void)
#error "Unrecognized Tegra SoC family"
#endif
+#ifndef CONFIG_PM
+#define tegra_wake_init() do {} while (0)
+#else
+static void __init tegra_wake_init(void)
+{
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+ const int wakepad_irq[] = {
+ gpio_to_irq(TEGRA_GPIO_PO5), gpio_to_irq(TEGRA_GPIO_PV3),
+ gpio_to_irq(TEGRA_GPIO_PL1), gpio_to_irq(TEGRA_GPIO_PB6),
+ gpio_to_irq(TEGRA_GPIO_PN7), gpio_to_irq(TEGRA_GPIO_PA0),
+ gpio_to_irq(TEGRA_GPIO_PA0), gpio_to_irq(TEGRA_GPIO_PU5),
+ gpio_to_irq(TEGRA_GPIO_PU6), gpio_to_irq(TEGRA_GPIO_PC7),
+ gpio_to_irq(TEGRA_GPIO_PAA1), gpio_to_irq(TEGRA_GPIO_PW3),
+ gpio_to_irq(TEGRA_GPIO_PW2), gpio_to_irq(TEGRA_GPIO_PY6),
+ gpio_to_irq(TEGRA_GPIO_PJ7), INT_RTC, INT_KBC,
+ /* FIXME: USB wake pad interrupt mapping may be wrong */
+ INT_EXTERNAL_PMU, INT_USB, INT_USB3, INT_USB, INT_USB3,
+ gpio_to_irq(TEGRA_GPIO_PI5), gpio_to_irq(TEGRA_GPIO_PV2),
+ gpio_to_irq(TEGRA_GPIO_PS4), gpio_to_irq(TEGRA_GPIO_PS5),
+ gpio_to_irq(TEGRA_GPIO_PS0), gpio_to_irq(TEGRA_GPIO_PQ6),
+ gpio_to_irq(TEGRA_GPIO_PQ7), gpio_to_irq(TEGRA_GPIO_PN2),
+ };
+#endif
+ const NvOdmWakeupPadInfo *wakeups;
+ NvU32 wake_num;
+
+ wakeups = NvOdmQueryGetWakeupPadTable(&wake_num);
+ if (!wakeups || !wake_num)
+ return;
+
+ while (--wake_num) {
+ if ((wakeups->WakeupPadNumber < ARRAY_SIZE(wakepad_irq)) &&
+ (wakeups->enable)) {
+ enable_irq_wake(wakepad_irq[wakeups->WakeupPadNumber]);
+ }
+ wakeups++;
+ }
+}
+#endif
+
#ifdef CONFIG_TEGRA_SYSTEM_DMA
extern int __init tegra_dma_init(void);
#else
@@ -978,13 +1021,14 @@ void __init tegra_common_init(void)
tegra_register_sdio();
tegra_register_usb();
tegra_register_w1();
+ tegra_wake_init();
#ifdef CONFIG_PM
#ifdef MACH_TEGRA_GENERIC_DEBUG
- /* This is needed to get prints on UART
- * during suspend/resume */
- console_suspend_enabled = 0;
+ /* This is needed to get prints on UART
+ * during suspend/resume */
+ console_suspend_enabled = 0;
#endif
- tegra_set_suspend_ops();
+ tegra_set_suspend_ops();
#endif
}
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
index d7bd6dc8f05a..b07f01c41b6d 100644
--- a/arch/arm/mach-tegra/irq.c
+++ b/arch/arm/mach-tegra/irq.c
@@ -21,301 +21,259 @@
*/
#include <linux/init.h>
-#include <linux/interrupt.h>
+#include <linux/kernel.h>
#include <linux/irq.h>
+#include <linux/smp.h>
#include <linux/io.h>
-#include <asm/hardware/gic.h>
-
-#include "nvcommon.h"
-#include "nvrm_init.h"
-#include "nvrm_drf.h"
-#include "nvrm_hardware_access.h"
-#include "nvrm_module.h"
-#include "nvrm_interrupt.h"
-#include "mach/nvrm_linux.h"
-#include "ap15/arictlr.h"
-#include "ap15/arapb_misc.h"
-#include "ap20/arfic_proc_if.h"
-#include "ap20/arfic_dist.h"
-#include "mach/board.h"
-
-#ifdef CONFIG_TEGRA_SYSTEM_DMA
-extern void __init tegra_init_dma(void); /* irq_dma.c */
-#endif
-extern void __init tegra_init_gpio(void); /* irq_gpio.c */
-
-/* Exported symbol shared with NvOs defining the number of non-GPIO interrupts
- * present on the system */
-NvU32 g_NvNumSocIrqs = 0;
-
-/* Causes the interrupt decoder to use the legacy portal player decoder */
-NvU32 g_NvUsePpiDecoder = 0;
-void __iomem *g_NvIctlrBase = NULL;
-
-#ifdef CONFIG_CPU_AP15
-#define NV_MAX_IRQ_INSTANCES 3
-static volatile NvU8 *s_Controllers[NV_MAX_IRQ_INSTANCES] = {NULL};
-
-static struct irq_chip s_NvIrqDispatch = {
- .name = "tegra",
-};
+#include <linux/interrupt.h>
-static void NvPrivAckIrq(unsigned int irq)
-{
- /* nothing to do */
-}
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <mach/platform.h>
-static void NvPrivAp15MaskIrq(unsigned int irq)
-{
- NV_WRITE32(s_Controllers[irq>>5] + ICTLR_CPU_IER_CLR_0,
- 1 << (irq & 31));
-}
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+#define INT_PPI_ADDRESS(_inst) (0x60004000ul + 0x100*(_inst))
+#define INT_APBDMA_ADDRESS 0x6000a000ul
+#else
+#error "interrupt controller addresses not defined"
+#endif
-static void NvPrivAp15UnmaskIrq(unsigned int irq)
-{
- NV_WRITE32(s_Controllers[irq>>5] + ICTLR_CPU_IER_SET_0,
- 1 << (irq & 31));
-}
+#ifdef CONFIG_ARM_GIC
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+#define ARM_PERIF_BASE 0x50040000ul
+#define GIC_PROC_IF_BASE (ARM_PERIF_BASE + 0x100ul)
+#define GIC_DIST_BASE (ARM_PERIF_BASE + 0x1000ul)
+#else
+#error "interrupt distributor address not defined"
+#endif
+#endif
-static struct irq_chip* __init NvPrivAp15InitIrq(void)
-{
- NvU32 i;
- NvRmPhysAddr Phys;
- NvU32 Len;
- NvU32 Num;
-
- Num = NvRmModuleGetNumInstances(s_hRmGlobal,NvRmPrivModuleID_Interrupt);
- if (Num > NV_MAX_IRQ_INSTANCES) {
- printk("More interrupt controllers than static array size\n");
- while (1) { }
- }
- g_NvNumSocIrqs = Num*32;
-
- for (i=0; i<Num; i++) {
- NvRmModuleGetBaseAddress(s_hRmGlobal,
- NVRM_MODULE_ID(NvRmPrivModuleID_Interrupt,i),
- &Phys, &Len);
- if (NvRmPhysicalMemMap(Phys, Len, NVOS_MEM_READ_WRITE,
- NvOsMemAttribute_Uncached,
- (void **)&s_Controllers[i])!=NvSuccess) {
- printk("Failed to get IRQ controller base address\n");
- while (1) { }
- }
- NV_WRITE32(s_Controllers[i] + ICTLR_CPU_IER_CLR_0, ~0UL);
- NV_WRITE32(s_Controllers[i] + ICTLR_CPU_IEP_CLASS_0, 0);
- }
+#define ICTLR_CPU_IER_0 0x20
+#define ICTLR_CPU_IER_SET_0 0x24
+#define ICTLR_CPU_IER_CLR_0 0x28
+#define ICTLR_CPU_IEP_CLASS_0 0x2c
+#define ICTLR_COP_IER_0 0x30
+#define ICTLR_COP_IER_SET_0 0x34
+#define ICTLR_COP_IER_CLR_0 0x38
+#define ICTLR_COP_IEP_CLASS_0 0x3c
- s_NvIrqDispatch.mask = NvPrivAp15MaskIrq;
- s_NvIrqDispatch.unmask = NvPrivAp15UnmaskIrq;
- s_NvIrqDispatch.ack = NvPrivAckIrq;
- s_NvIrqDispatch.set_type = NULL;
- g_NvIctlrBase = (void __iomem*)s_Controllers[0];
- g_NvUsePpiDecoder = 1;
- return &s_NvIrqDispatch;
-}
-#endif
+#define APBDMA_IRQ_STA_CPU_0 0x14
+#define APBDMA_IRQ_MASK_SET_0 0x20
+#define APBDMA_IRQ_MASK_CLR_0 0x24
#ifdef CONFIG_ARM_GIC
-#define NV_MAX_IRQ_INSTANCES 4
-static volatile NvU8 *s_Controllers[NV_MAX_IRQ_INSTANCES] = {NULL};
extern void gic_mask_irq(unsigned int);
extern void gic_unmask_irq(unsigned int);
extern void gic_ack_irq(unsigned int);
extern void gic_set_cpu(unsigned int, const struct cpumask*);
+extern void gic_dist_init(unsigned int, void __iomem *, unsigned int);
+extern void gic_cpu_init(unsigned int, void __iomem *);
+#else
+#define gic_mask_irq(i) do { } while (0)
+#define gic_unmask_irq(i) do { } while (0)
+#define gic_ack_irq(i) do { } while (0)
+#define gic_set_cpu NULL
+#define gic_dist_init(i, p, s) do { } while (0)
+#define gic_cpu_init(i, p) do { } while (0)
+#endif
-static struct irq_chip s_NvIrqDispatch =
-{
- .name = "tegra2",
+struct tegra_irq_chip {
+ unsigned int irq_start;
+ void __iomem *mmio;
+ /* context save/restore data for interrupts */
+#ifdef CONFIG_PM
+ u32 cpu_ier;
+ u32 cop_ier;
+#endif
};
-void NvPrivAp20MaskIrq(unsigned int irq)
+static struct tegra_irq_chip tegra_chip[(INT_SYS_NR+INT_SYS_SZ-1)/INT_SYS_SZ];
+
+static void tegra_mask(unsigned int irq)
{
+ struct tegra_irq_chip *chip;
gic_mask_irq(irq);
-
- irq -= 32;
-
- NV_WRITE32(s_Controllers[irq>>5] + ICTLR_CPU_IER_CLR_0,
- 1 << (irq & 31));
-
+ irq -= INT_PRI_BASE;
+ chip = &tegra_chip[irq/INT_SYS_SZ];
+ writel(1<<(irq&31), chip->mmio + ICTLR_CPU_IER_CLR_0);
}
-void NvPrivAp20UnmaskIrq(unsigned int irq)
+static void tegra_unmask(unsigned int irq)
{
+ struct tegra_irq_chip *chip;
gic_unmask_irq(irq);
-
- irq -= 32;
-
- NV_WRITE32(s_Controllers[irq>>5] + ICTLR_CPU_IER_SET_0,
- 1 << (irq & 31));
+ irq -= INT_PRI_BASE;
+ chip = &tegra_chip[irq/INT_SYS_SZ];
+ writel(1<<(irq&31), chip->mmio + ICTLR_CPU_IER_SET_0);
}
-static void NvPrivAp20AckIrq(unsigned int irq)
+static void tegra_ack(unsigned int irq)
{
gic_ack_irq(irq);
}
-#ifdef CONFIG_SMP
-static void NvPrivAp20SetCpu(unsigned int irq, const struct cpumask *mask_val)
+#ifdef CONFIG_PM
+
+static int tegra_set_wake(unsigned int irq, unsigned int on)
{
- gic_set_cpu(irq, mask_val);
+ return 0;
}
-#endif
-static void tegra_irq_register_module(NvRmModuleID Module,
- struct irq_chip* pIrq)
+void tegra_irq_resume(void)
{
- NvU32 i, Num;
- Num = NvRmModuleGetNumInstances(s_hRmGlobal, Module);
- for (i=0; i<Num; i++) {
- NvU32 Ints;
- Ints = NvRmGetIrqCountForLogicalInterrupt(s_hRmGlobal,
- NVRM_MODULE_ID(Module,i));
- while (Ints) {
- NvU32 Irq;
- --Ints;
- if (Module == NvRmPrivModuleID_Gpio) {
- /* GPIOs are handled differently. Here we set the
- * handler for the entire GPIO controller. Each GPIO
- * controller has a set of GPIO ports which can
- * programmed by the GPIO APIs. Check the NvRmGpio*
- * APIs for more information
- *
- * To get the main IRQ line connected to the GPIO line,
- * use an index value of 0xff.
- */
- Irq = NvRmGetIrqForLogicalInterrupt(s_hRmGlobal,
- NVRM_MODULE_ID(Module, i), 0xff);
- } else {
- Irq = NvRmGetIrqForLogicalInterrupt(s_hRmGlobal,
- NVRM_MODULE_ID(Module, i), Ints);
- }
-
- if (pIrq) {
- if (set_irq_chip(Irq, pIrq)) {
- panic("set_irq_chip %d failed\n", Irq);
- }
- set_irq_handler(Irq, handle_level_irq);
- }
-
- set_irq_flags(Irq, IRQF_VALID);
- }
+ unsigned long flags;
+ int i;
+
+ local_irq_save(flags);
+ for (i=0; i<ARRAY_SIZE(tegra_chip); i++) {
+ struct tegra_irq_chip *chip = &tegra_chip[i];
+ writel(chip->cpu_ier, chip->mmio + ICTLR_CPU_IER_SET_0);
+ writel(0, chip->mmio + ICTLR_CPU_IEP_CLASS_0);
+ writel(chip->cop_ier, chip->mmio + ICTLR_COP_IER_SET_0);
+ writel(0, chip->mmio + ICTLR_COP_IEP_CLASS_0);
+ }
+ local_irq_restore(flags);
+
+ for (i=INT_PRI_BASE; i<INT_GPIO_BASE; i++) {
+ struct irq_desc *desc = irq_to_desc(i);
+ if (!desc || (desc->status & IRQ_WAKEUP)) continue;
+ enable_irq(i);
}
+
+ for (i=INT_APBDMA_BASE; i<INT_APBDMA_BASE+INT_APBDMA_NR; i++)
+ enable_irq(i);
}
-static struct irq_chip* __init NvPrivGicInitIrq(void)
+void tegra_irq_suspend(void)
{
- NvRmPhysAddr Phys;
- NvU32 Len;
- NvU32 Num;
- NvU32 i;
- volatile NvU8 *pArm = NULL;
-
- Num = NvRmModuleGetNumInstances(s_hRmGlobal,
- NvRmPrivModuleID_Interrupt);
- g_NvNumSocIrqs = (Num+1)*32;
-
- NvRmModuleGetBaseAddress(s_hRmGlobal,
- NVRM_MODULE_ID(NvRmPrivModuleID_ArmPerif,0), &Phys, &Len);
-
- if (NvRmPhysicalMemMap(Phys, Len, NVOS_MEM_READ_WRITE,
- NvOsMemAttribute_Uncached, (void **)&pArm)!=NvSuccess) {
- panic("Unable to map interrupt controller aperture\n");
- }
+ unsigned long flags;
+ int i;
+
+ for (i=INT_APBDMA_BASE; i<INT_APBDMA_BASE+INT_APBDMA_NR; i++)
+ disable_irq(i);
- gic_dist_init(0,
- (void __iomem*)(pArm + FIC_DIST_DISTRIBUTOR_ENABLE_0), 29);
- gic_cpu_init(0, (void __iomem*)(pArm + FIC_PROC_IF_CONTROL_0));
-
- g_NvIctlrBase = (void __iomem*)(pArm + FIC_PROC_IF_CONTROL_0);
-
- /* gic_dist_init sets the IRQF_PROBE and IRQF_VALID flags for the entire
- * range of distributor IRQs. The Tegra code undoes this, and then
- * respecifies the desired flags for only valid IRQ numbers */
- for (i=32; i<g_NvNumSocIrqs; i++)
- set_irq_flags(i, 0);
-
- /* Set up the legacy controller as well. Needed for flow controller */
- for (i=0; i<Num; i++) {
- NvRmModuleGetBaseAddress(s_hRmGlobal,
- NVRM_MODULE_ID(NvRmPrivModuleID_Interrupt,i),
- &Phys, &Len);
- if (NvRmPhysicalMemMap(Phys, Len, NVOS_MEM_READ_WRITE,
- NvOsMemAttribute_Uncached,
- (void **)&s_Controllers[i])!=NvSuccess) {
- printk("failed to get IRQ controller base address\n");
- while (1) { }
+ for (i=INT_PRI_BASE; i<INT_GPIO_BASE; i++) {
+ struct irq_desc *desc= irq_to_desc(i);
+ if (!desc) continue;
+ if (desc->status & IRQ_WAKEUP) {
+ pr_debug("irq %d is wakeup\n", i);
+ continue;
}
- NV_WRITE32(s_Controllers[i] + ICTLR_CPU_IER_CLR_0, ~0UL);
- NV_WRITE32(s_Controllers[i] + ICTLR_CPU_IEP_CLASS_0, 0);
+ disable_irq(i);
}
- //Set up the irq_chip for AP20
- s_NvIrqDispatch.mask = NvPrivAp20MaskIrq;
- s_NvIrqDispatch.unmask = NvPrivAp20UnmaskIrq;
- s_NvIrqDispatch.ack = NvPrivAp20AckIrq;
-#ifdef CONFIG_SMP
- s_NvIrqDispatch.set_affinity = NvPrivAp20SetCpu;
+ local_irq_save(flags);
+ for (i=0; i<ARRAY_SIZE(tegra_chip); i++) {
+ struct tegra_irq_chip *chip = &tegra_chip[i];
+ chip->cpu_ier = readl(chip->mmio + ICTLR_CPU_IER_0);
+ chip->cop_ier = readl(chip->mmio + ICTLR_COP_IER_0);
+ writel(~0ul, chip->mmio + ICTLR_COP_IER_CLR_0);
+ }
+ local_irq_restore(flags);
+}
+
#endif
- return &s_NvIrqDispatch;
+
+#ifdef CONFIG_TEGRA_SYSTEM_DMA
+struct apbdma_irq_chip {
+ unsigned int irq_start;
+ void __iomem *mmio;
+ spinlock_t lock;
+};
+
+static struct apbdma_irq_chip apbdma_chip;
+
+static void apbdma_ack(unsigned int irq) { }
+
+static void apbdma_mask(unsigned int irq)
+{
+ struct apbdma_irq_chip *chip = get_irq_chip_data(irq);
+ irq -= chip->irq_start;
+ writel(1<<irq, chip->mmio + APBDMA_IRQ_MASK_CLR_0);
}
-#endif
+static void apbdma_unmask(unsigned int irq)
+{
+ struct apbdma_irq_chip *chip = get_irq_chip_data(irq);
+ irq -= chip->irq_start;
+ writel(1<<irq, chip->mmio + APBDMA_IRQ_MASK_SET_0);
+}
-void __init tegra_init_irq(void)
+static void apbdma_cascade(unsigned int irq, struct irq_desc *desc)
{
- NvRmModuleID Module;
- NvU32 ChipId;
- volatile NvU8 *MiscRegionVirtual;
- NvRmPhysAddr Phys;
- NvU32 Len;
- struct irq_chip* pIrq = NULL;
-
- NvRmModuleGetBaseAddress(s_hRmGlobal,
- NVRM_MODULE_ID(NvRmModuleID_Misc,0),
- &Phys, &Len);
-
- if (NvRmPhysicalMemMap(Phys, Len, NVOS_MEM_READ_WRITE,
- NvOsMemAttribute_Uncached,
- (void **)&MiscRegionVirtual)!=NvSuccess) {
- printk("ERROR: Failed to get Misc controller base address\n");
- while (1) { };
+ struct irq_chip *pri = get_irq_chip(irq);
+ struct apbdma_irq_chip *chip = get_irq_data(irq);
+ u32 reg, ch=0;
+
+ pri->ack(irq);
+ spin_lock(&chip->lock);
+ reg = readl(chip->mmio + APBDMA_IRQ_STA_CPU_0);
+ if (reg) {
+ reg = __fls(reg);
+ writel(1<<reg, chip->mmio + APBDMA_IRQ_STA_CPU_0);
+ ch = chip->irq_start + reg;
}
+ spin_unlock(&chip->lock);
+ if (ch) generic_handle_irq(ch);
+ pri->unmask(irq);
+}
- ChipId = NV_READ32(MiscRegionVirtual + APB_MISC_GP_HIDREV_0);
- ChipId = NV_DRF_VAL(APB_MISC_GP, HIDREV, CHIPID, ChipId);
+static struct irq_chip apbdma_irq = {
+ .name = "APBDMA",
+ .ack = apbdma_ack,
+ .mask = apbdma_mask,
+ .unmask = apbdma_unmask,
+};
+#endif
- if (ChipId==0x15 || ChipId==0x16) {
-#ifdef CONFIG_CPU_AP15
- pIrq = NvPrivAp15InitIrq();
-#else
- panic("Kernel built without APX 2600 support\n");
+static struct irq_chip tegra_irq = {
+ .name = "PPI",
+ .mask = tegra_mask,
+ .unmask = tegra_unmask,
+ .ack = tegra_ack,
+#ifdef CONFIG_PM
+ .set_wake = tegra_set_wake,
#endif
- }
- else if (ChipId==0x20) {
-#ifdef CONFIG_ARM_GIC
- pIrq = NvPrivGicInitIrq();
-#else
- panic("Kernel built without AP2x support\n");
+#ifdef CONFIG_SMP
+ .set_affinity = gic_set_cpu,
#endif
- }
- else {
- panic("Unsupported chip ID: 0x%x\n", ChipId);
- }
- for (Module = NvRmModuleID_Cpu; Module<NvRmPrivModuleID_Num; Module++) {
+};
- /* Skip interrupt registration for interrupt controllers */
- if ((Module == NvRmPrivModuleID_Interrupt)
- || (Module == NvRmPrivModuleID_ArmInterruptctrl)) {
- continue;
- }
+void __init tegra_init_irq(void)
+{
+ unsigned int i;
- tegra_irq_register_module(Module, pIrq);
+ for (i=0; i<ARRAY_SIZE(tegra_chip); i++) {
+ tegra_chip[i].irq_start = INT_PRI_BASE + INT_SYS_SZ*i;
+ tegra_chip[i].mmio = IO_ADDRESS(INT_PPI_ADDRESS(i));
+ writel(~0ul, tegra_chip[i].mmio + ICTLR_CPU_IER_CLR_0);
+ writel(0, tegra_chip[i].mmio + ICTLR_CPU_IEP_CLASS_0);
+ }
+
+ gic_dist_init(0, IO_ADDRESS(GIC_DIST_BASE), 29);
+ gic_cpu_init(0, IO_ADDRESS(GIC_PROC_IF_BASE));
+
+ for (i=INT_PRI_BASE; i<INT_GPIO_BASE; i++) {
+ set_irq_chip(i, &tegra_irq);
+ set_irq_handler(i, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
}
-
#ifdef CONFIG_TEGRA_SYSTEM_DMA
- tegra_init_dma();
+ apbdma_chip.mmio = IO_ADDRESS(INT_APBDMA_ADDRESS);
+ spin_lock_init(&apbdma_chip.lock);
+ apbdma_chip.irq_start = INT_APBDMA_BASE;
+
+ for (i=INT_APBDMA_BASE; i<INT_APBDMA_NR+INT_APBDMA_BASE; i++) {
+ set_irq_chip(i, &apbdma_irq);
+ set_irq_chip_data(i, &apbdma_chip);
+ set_irq_handler(i, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+ if (set_irq_data(INT_APB_DMA, &apbdma_chip))
+ BUG();
+ set_irq_chained_handler(INT_APB_DMA, apbdma_cascade);
#endif
}
diff --git a/arch/arm/mach-tegra/irq_dma.c b/arch/arm/mach-tegra/irq_dma.c
deleted file mode 100644
index 37487af7ae35..000000000000
--- a/arch/arm/mach-tegra/irq_dma.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * arch/arm/mach-tegra/irq_dma.c
- *
- * Second-level IRQ decoder for system DMA driver
- *
- * Copyright (c) 2009, NVIDIA Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include "ap15/arapbdma.h"
-#include <asm/io.h>
-
-#include <mach/nvrm_linux.h>
-#include "nvrm_interrupt.h"
-
-static int dma_irq_start;
-static int dma_main_irq;
-static void __iomem *apb_dma_regs;
-static NvOsPhysAddr dma_phys;
-static unsigned int dma_size;
-
-static void dma_irq_mask(unsigned int irq)
-{
- unsigned long reg;
-
- reg = 1 << (irq - dma_irq_start);
- writel(reg, apb_dma_regs + APBDMA_IRQ_MASK_CLR_0);
-}
-
-static void dma_irq_unmask(unsigned int irq)
-{
- unsigned long reg;
-
- reg = 1 << (irq - dma_irq_start);
- writel(reg, apb_dma_regs + APBDMA_IRQ_MASK_SET_0);
-}
-
-static void dma_irq_ack(unsigned int irq)
-{
-
-}
-
-static struct irq_chip dma_irq_chip = {
- .name = "APBDMA",
- .ack = dma_irq_ack,
- .mask = dma_irq_mask,
- .unmask = dma_irq_unmask,
-};
-
-
-static void dma_irq_handler(unsigned int irqMain, struct irq_desc *desc)
-{
- struct irq_chip *chip = get_irq_chip(irqMain);
- unsigned int channel;
- unsigned int reg;
-
- chip->ack(irqMain);
-
- reg = readl(apb_dma_regs + APBDMA_IRQ_STA_CPU_0);
- if (reg) {
- __asm__ __volatile__ ( \
- "clz %0, %1 \r\t" \
- :"=r"(channel) \
- :"r"(reg));
- channel = 31 - channel;
-
- reg = writel(1 << channel, apb_dma_regs + APBDMA_IRQ_STA_CPU_0);
- generic_handle_irq(channel + dma_irq_start);
- }
- chip->unmask(irqMain);
-}
-
-void __init tegra_init_dma(void)
-{
- int num_channels;
- int channel;
- int irq;
-
- NvRmModuleGetBaseAddress(s_hRmGlobal,
- NVRM_MODULE_ID(NvRmPrivModuleID_ApbDma, 0),
- &dma_phys, &dma_size);
-
- apb_dma_regs = IO_ADDRESS(dma_phys);
- if (!apb_dma_regs)
- return;
-
- num_channels = NvRmModuleGetNumInstances(s_hRmGlobal, NvRmPrivModuleID_ApbDmaChannel);
- if (num_channels == 0)
- return;
-
- dma_main_irq = NvRmGetIrqForLogicalInterrupt(s_hRmGlobal,
- NVRM_MODULE_ID(NvRmPrivModuleID_ApbDma, 0), 0xff);
-
- dma_irq_start = NvRmGetIrqForLogicalInterrupt(s_hRmGlobal,
- NVRM_MODULE_ID(NvRmPrivModuleID_ApbDma, 0), 0);
-
- channel = num_channels;
- while (channel--)
- {
- irq = NvRmGetIrqForLogicalInterrupt(s_hRmGlobal,
- NVRM_MODULE_ID(NvRmPrivModuleID_ApbDma, 0), channel);
-
- set_irq_chip(irq, &dma_irq_chip);
- set_irq_handler(irq, handle_level_irq);
- set_irq_flags(irq, IRQF_VALID);
- }
- set_irq_chained_handler(dma_main_irq, dma_irq_handler);
-}
-
diff --git a/arch/arm/mach-tegra/irq_gpio.c b/arch/arm/mach-tegra/irq_gpio.c
deleted file mode 100644
index 5b2d59f5e106..000000000000
--- a/arch/arm/mach-tegra/irq_gpio.c
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * arch/arm/mach-tegra/irq_gpio.c
- *
- * Second-level IRQ decoder for GPIOs
- *
- * Copyright (c) 2009, NVIDIA Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-
-#include <mach/nvrm_linux.h>
-#include "nvrm_init.h"
-#include "nvrm_module.h"
-#include "nvrm_interrupt.h"
-#include "nvrm_gpio.h"
-#include "ap15/argpio.h"
-#include "nvassert.h"
-#include "nvrm_hardware_access.h"
-
-#define NVRM_GPIO_INTERRUPT_TEST 0
-
-// Size of a port register
-#define NV_GPIO_PORT_REG_SIZE (GPIO_CNF_1 - GPIO_CNF_0)
-// NUmber of GPIO ports per controller
-#define NV_GPIO_PORTS_PER_CONTROLLER (4)
-// Number of GPIO pins per controller port
-#define NV_GPIO_PINS_PER_PORT (8)
-#define NV_GPIO_PORT_REG_MASK ((1 << NV_GPIO_PINS_PER_PORT) - 1)
-#define NV_GPIO_MASK(bit, val) \
- ((1 << ((bit) + NV_GPIO_PINS_PER_PORT)) | \
- (((val) << (bit)) & NV_GPIO_PORT_REG_MASK))
-
-// Gpio register read/write macros
-#define NV_GPIO_REGR( addr, Port, Reg ) \
- NV_READ32((NvU32)addr + ((Port) * NV_GPIO_PORT_REG_SIZE)+(GPIO_##Reg##_0));
-
-#define NV_GPIO_REGW( addr, Port, Reg, data ) \
- do \
- { \
- NV_WRITE32(((NvU32)(addr) + ((Port) * NV_GPIO_PORT_REG_SIZE) + \
- (GPIO_##Reg##_0)), (data)); \
- } while (0)
-
-struct NvGpioInstance
-{
- void __iomem *base;
- NvU32 phys;
- NvU32 size;
- u16 irqMain;
- u16 irqStart;
- u16 irqCount;
- u16 irqEnd;
-};
-
-#define MAX_GPIO_INSTANCES 10
-
-static struct NvGpioInstance s_GpioInstances[MAX_GPIO_INSTANCES];
-NvU32 s_GpioInstanceMax;
-
-static void NvPrivGpioEnable(unsigned int irq, NvBool enable)
-{
- NvU32 i;
-
-
- i = s_GpioInstanceMax;
- while (i--)
- {
- if ((irq >= s_GpioInstances[i].irqStart)
- && (irq < s_GpioInstances[i].irqEnd))
- {
- NvU32 relative_irq;
- NvU32 Port;
- NvU32 Bit;
-
-
- relative_irq = irq - s_GpioInstances[i].irqStart;
-
- // Get the controller number, port number and bit number.
- Port = relative_irq / NV_GPIO_PINS_PER_PORT;
- Bit = relative_irq - (Port * NV_GPIO_PINS_PER_PORT);
-
- // Enable/Disable the specified GPIO controller main interrupt.
- NV_GPIO_REGW(s_GpioInstances[i].base, Port, MSK_INT_ENB,
- NV_GPIO_MASK(Bit, enable));
-
- return;
- }
- }
-
- /* should not come here */
- NV_ASSERT(0);
- return;
-}
-
-static void NvPrivGpioMaskIrq(unsigned int irq)
-{
- //printk("Disabling IRQ(%d)\n", irq);
- NvPrivGpioEnable(irq, NV_FALSE);
-}
-
-void NvPrivGpioUnMaskIrq(unsigned int irq)
-{
- //printk("Enabling IRQ(%d)\n", irq);
- NvPrivGpioEnable(irq, NV_TRUE);
-}
-
-static void NvPrivGpioAckIrq(unsigned int irq)
-{
- NvU32 i;
-
- i = s_GpioInstanceMax;
- while (i--)
- {
- if ((irq >= s_GpioInstances[i].irqStart)
- && (irq < s_GpioInstances[i].irqEnd))
- {
- NvU32 relative_irq;
- NvU32 Port;
- NvU32 Bit;
- NvU32 Mask;
-
- relative_irq = irq - s_GpioInstances[i].irqStart;
-
- // Get the controller number, port number and bit number.
- Port = relative_irq / NV_GPIO_PINS_PER_PORT;
- Bit = relative_irq - (Port * NV_GPIO_PINS_PER_PORT);
- Mask = 1 << Bit;
-
- NV_GPIO_REGW(s_GpioInstances[i].base, Port, INT_CLR, Mask);
-
- //printk("IRQ acked for %d\n", irq);
- return;
- }
- }
-
- /* should not come here */
- NV_ASSERT(0);
-}
-
-static struct irq_chip s_NvGpioIrqDispatch = {
- .name = "GPIO",
- .ack = NvPrivGpioAckIrq,
- .mask = NvPrivGpioMaskIrq,
- .unmask = NvPrivGpioUnMaskIrq,
-};
-
-
-static void gpio_irq_handler(unsigned int irqMain, struct irq_desc *desc)
-{
- struct irq_chip *chip = get_irq_chip(irqMain);
- NvU32 i = 0;
- NvU32 Port; // Controller port number
- NvU32 Bit; // Port bit number
- NvU32 IntEnable; // Port interrupt enable bits
- NvU32 IntStatus; // Port interrupt status bits
- NvU32 Mask; // Mask of interrupting bit within the port
-
-
- while (i < s_GpioInstanceMax && irqMain != s_GpioInstances[i].irqMain)
- {
- i++;
- }
-
- /* Something wrong in the setup? Why am i getting a callback for the
- * non-GPIO interrupts? */
- NV_ASSERT (i != s_GpioInstanceMax);
-
- /* This does nothing on AP15, on AP20 this disables the interrupt
- * and issues a EOI - see gic_ack_irq in arch/arm/common/gic */
- chip->ack(irqMain);
-
- Port = NV_GPIO_PORTS_PER_CONTROLLER;
- while (Port--)
- {
- IntEnable = NV_GPIO_REGR(s_GpioInstances[i].base, Port, INT_ENB);
- IntStatus = NV_GPIO_REGR(s_GpioInstances[i].base, Port, INT_STA);
-
- // Is there a bit interrupting in this port?
- if ((IntStatus = (IntEnable & IntStatus)) != 0)
- {
- NvU32 irq;
-
- __asm__ __volatile__ ( \
- "clz %0, %1 \r\t" \
- :"=r"(Bit) \
- :"r"(IntStatus));
- Bit = 31 - Bit;
-
- Mask = 1 << Bit;
-
- irq = s_GpioInstances[i].irqStart +
- ((Port * NV_GPIO_PINS_PER_PORT) + Bit);
-
- /* Trigger the interrupt for the client requesting the callback on
- * this GPIO pin */
- generic_handle_irq(irq);
- goto out;
- }
- }
-
- /* Got a spurious interrupt? How is this possible? */
- NV_ASSERT(0);
-
-out:
- /* Re-enable the interrupt on main interrupt controller */
- chip->unmask(irqMain);
- return;
-}
-
-void __init tegra_init_gpio(void)
-{
- NvU32 i;
- NvU32 irq;
- NvU32 count;
-
- s_NvGpioIrqDispatch.set_type = NULL;
-
- s_GpioInstanceMax = NvRmModuleGetNumInstances(s_hRmGlobal, NvRmPrivModuleID_Gpio);
- BUG_ON(s_GpioInstanceMax > MAX_GPIO_INSTANCES);
-
- i = s_GpioInstanceMax;
- while (i--)
- {
- NvRmModuleGetBaseAddress(s_hRmGlobal,
- NVRM_MODULE_ID(NvRmPrivModuleID_Gpio, i),
- &s_GpioInstances[i].phys, &s_GpioInstances[i].size);
-
- NV_ASSERT_SUCCESS(NvRmPhysicalMemMap(s_GpioInstances[i].phys,
- s_GpioInstances[i].size , NVOS_MEM_READ_WRITE,
- NvOsMemAttribute_Uncached,
- (void **)&s_GpioInstances[i].base));
-
- s_GpioInstances[i].irqMain = NvRmGetIrqForLogicalInterrupt(s_hRmGlobal,
- NVRM_MODULE_ID(NvRmPrivModuleID_Gpio, i), 0xff);
-
- s_GpioInstances[i].irqStart = NvRmGetIrqForLogicalInterrupt(
- s_hRmGlobal, NVRM_MODULE_ID(NvRmPrivModuleID_Gpio, i), 0x0);
-
- count = NV_GPIO_PINS_PER_PORT * NV_GPIO_PORTS_PER_CONTROLLER;
- s_GpioInstances[i].irqCount = count;
- s_GpioInstances[i].irqEnd =
- s_GpioInstances[i].irqStart + s_GpioInstances[i].irqCount;
-
- while (count--)
- {
- irq = NvRmGetIrqForLogicalInterrupt(s_hRmGlobal,
- NVRM_MODULE_ID(NvRmPrivModuleID_Gpio,i), count);
-
- set_irq_chip(irq, &s_NvGpioIrqDispatch);
- /* FIXME, Ideally, we use handle_edge_irq for edge interrupts. But,
- * handle_level_irq should also work for most edge interrupts which
- * are handled one at a time. If the edge interrupt is because of
- * very short pulses, then this logic won't work.
- */
- set_irq_handler(irq, handle_level_irq);
- set_irq_flags(irq, IRQF_VALID);
- }
-
- set_irq_chained_handler(s_GpioInstances[i].irqMain, gpio_irq_handler);
- }
-
- return;
-}
-
-
-#if defined(CONFIG_GENERIC_GPIO)
-
-int gpio_set_value(unsigned gpio, int value)
-{
- return 0;
-}
-
-int gpio_get_value(unsigned gpio)
-{
- return 0;
-}
-
-int gpio_direction_input(unsigned gpio)
-{
- return 0;
-}
-
-int gpio_direction_output(unsigned gpio, int value)
-{
- return 0;
-}
-
-int gpio_request(unsigned gpio, const char *tag)
-{
- return 0;
-}
-
-void gpio_free(unsigned gpio)
-{
-}
-
-#endif
diff --git a/arch/arm/mach-tegra/nvos/nvos.c b/arch/arm/mach-tegra/nvos/nvos.c
index b45454b9e515..40651598cba3 100644
--- a/arch/arm/mach-tegra/nvos/nvos.c
+++ b/arch/arm/mach-tegra/nvos/nvos.c
@@ -164,10 +164,6 @@ static NvOsInterruptBlock *s_pIrqList[NVOS_MAX_SYSTEM_IRQS] = { NULL };
static NvBootArgs s_BootArgs = { {0}, {0}, {0}, {0}, {0}, {0}, {{0}} };
-/* Defined in mach-tegra/irq.c. Stores the number of native (non-GPIO) SoC
- * IRQs. */
-extern NvU32 g_NvNumSocIrqs;
-
/* The tasklet "data" parameter is a munging of the s_pIrqList index
* (just the IRQ number), and the InterruptBlock's IrqList index, to
* make interrupt handler lookups O(n)
@@ -1221,9 +1217,7 @@ NvError NvOsInterruptRegisterInternal(
pNewBlock->IrqList[i].Irq = pIrqList[i];
- /* HACK use threads for GPIO and tasklets for all other interrupts.
- * g_NvNumSocIrqs is initialized and defined in mach-tegra/irq.c */
-
+ /* HACK use threads for GPIO and tasklets for all other interrupts. */
if (IsUser)
{
pNewBlock->IrqList[i].pSem = pSemList[i];
@@ -1232,7 +1226,7 @@ NvError NvOsInterruptRegisterInternal(
else
{
pNewBlock->IrqList[i].pHandler = pFnList[i];
- if (pIrqList[i] >= g_NvNumSocIrqs)
+ if (pIrqList[i] >= INT_GPIO_BASE)
pNewBlock->Flags |= NVOS_IRQ_IS_KERNEL_THREAD;
else
pNewBlock->Flags |= NVOS_IRQ_IS_TASKLET;
diff --git a/arch/arm/mach-tegra/power-context-t2.c b/arch/arm/mach-tegra/power-context-t2.c
index 8f79db31b5f8..a67044ded963 100644
--- a/arch/arm/mach-tegra/power-context-t2.c
+++ b/arch/arm/mach-tegra/power-context-t2.c
@@ -344,146 +344,25 @@ fail:
return NULL;
}
-static NvU32* save_intc_context(
- PowerModuleContext Context,
- struct power_context *pAnchor,
- NvU32 *pCM)
+extern void tegra_irq_suspend(void);
+extern void tegra_irq_resume(void);
+static NvU32* save_intc_context(PowerModuleContext Context,
+ struct power_context *pAnchor, NvU32 *pCM)
{
- NvU32 Aperture; //Register base address
- NvU32 ApertureSize; //Register set size
- NvRmModuleID ModuleId; //Composite module id & instance
- NvU32 Instance; //Interrupt Controller Instance
- NvU32 Instances; //Total number of ictlr instances
- NvU32* pBase; //Ptr to list of register base addresses
-
- //NOTE: This controller has multiple instances. Therefore,
- //pAnchor->interrupt.pBase is a pointer to a list of
- //controller instance base addresses and not the controller's
- //base address itself.
-
- //Get the number of interrupt controller instances.
- Instances = NvRmModuleGetNumInstances(s_hRmGlobal,
- NvRmPrivModuleID_Interrupt);
-
- //Get a pointer to the base address list.
- pBase = pAnchor->interrupt.pBase;
-
switch (Context) {
- case PowerModuleContext_Init:
- //Already initialized?
- if (pBase == NULL)
- {
- //Anchor the starting point for the list of
- //instance base addresses.
- pAnchor->interrupt.pBase = pCM;
-
- //For each instance...
- for (Instance = 0; Instance < Instances; ++Instance)
- {
- //Generate the composite module id and instance.
- ModuleId = NVRM_MODULE_ID(NvRmPrivModuleID_Interrupt,
- Instance);
-
- //Retrieve the register base PA
- NvRmModuleGetBaseAddress(s_hRmGlobal, ModuleId,
- &Aperture, &ApertureSize);
-
- //Get the corresponding VA
- if (NvOsPhysicalMemMap(Aperture,
- ApertureSize,
- NvOsMemAttribute_Uncached,
- NVOS_MEM_READ_WRITE,
- (void*)pCM))
- {
- printk("Failed to map the context save area!\n");
- goto fail;
- }
- pCM++;
- }
- }
- break;
-
case PowerModuleContext_Save:
case PowerModuleContext_SaveLP1:
- //Register base address list must have been
- //set by PowerModuleContext_Init.
- if (pBase == NULL)
- goto fail;
-
- //Anchor the starting point for this controller's context.
- pAnchor->interrupt.pContext = pCM;
-
- //For each instance...
- for (Instance = 0; Instance < Instances; ++Instance, ++pBase)
- {
- //Register base address must have been
- //set by PowerModuleContext_Init.
- if (*pBase == 0)
- goto fail;
-
- //Save module registers...
- *pCM++ = NV_ICTLR_REGR(*pBase, CPU_IER);
- *pCM++ = NV_ICTLR_REGR(*pBase, CPU_IEP_CLASS);
- *pCM++ = NV_ICTLR_REGR(*pBase, COP_IER);
- *pCM++ = NV_ICTLR_REGR(*pBase, COP_IEP_CLASS);
- }
+ tegra_irq_suspend();
break;
-
- case PowerModuleContext_Restore:
- case PowerModuleContext_RestoreLP1:
- //Register base address list must have been
- //set by PowerModuleContext_Init.
- if (pBase == NULL)
- goto fail;
-
- //We should be at the same place in the context
- //as when we saved things.
- if (pCM != pAnchor->interrupt.pContext)
- goto fail;
-
- //Retrieve the anchored starting point for this controller's context.
- pCM = pAnchor->interrupt.pContext;
-
- if (pCM == NULL)
- goto fail;
-
- //For each instance...
- for (Instance = 0; Instance < Instances; ++Instance, ++pBase)
- {
- //Register base address must have been
- //set by PowerModuleContext_Init.
- if (*pBase == 0)
- goto fail;
-
- //Restore module registers...
- NV_ICTLR_REGW(*pBase, CPU_IER_SET, *pCM++);
- NV_ICTLR_REGW(*pBase, CPU_IEP_CLASS, *pCM++);
- NV_ICTLR_REGW(*pBase, COP_IER_SET, *pCM++);
- NV_ICTLR_REGW(*pBase, COP_IEP_CLASS, *pCM++);
- }
- break;
-
- case PowerModuleContext_DisableInterrupt:
- //For each instance...
- for (Instance = 0; Instance < Instances; ++Instance, ++pBase)
- {
- if (*pBase == 0)
- goto fail;
-
- //Disable module interrupts.
- NV_ICTLR_REGW(*pBase, CPU_IER_CLR, ~0);
- NV_ICTLR_REGW(*pBase, COP_IER_CLR, ~0);
- }
+ case PowerModuleContext_Restore:
+ case PowerModuleContext_RestoreLP1:
+ tegra_irq_resume();
break;
-
default:
break;
}
return pCM;
-
-fail:
- return NULL;
}
static NvU32* save_misc_context(
@@ -600,243 +479,26 @@ fail:
return NULL;
}
-static NvU32* save_gpio_context(
- PowerModuleContext Context,
- struct power_context *pAnchor,
- NvU32 *pCM)
-{
- NvU32 Aperture; // Register base address
- NvU32 ApertureSize; // Register set size
- NvRmModuleID ModuleId; // Composite module id & instance
- NvU8 Instance; // GPIO Instance
- NvU32 Instances; // Total number of gpio instances
- NvU32* pBase; // Ptr to list of register base addresses
-
- //NOTE: This controller has multiple instances.
- //Therefore, pAnchor->Gpio.pBase is a pointer to a list
- //of controller instance base addresses and not the
- //controller's base address itself.
-
- //Get the number of GPIO controller instances.
- Instances = NvRmModuleGetNumInstances(s_hRmGlobal, NvRmPrivModuleID_Gpio);
-
- //Get a pointer to the base address list.
- pBase = pAnchor->gpio.pBase;
+extern void tegra_gpio_resume(void);
+extern void tegra_gpio_suspend(void);
+static NvU32* save_gpio_context(PowerModuleContext Context,
+ struct power_context *pAnchor, NvU32 *pCM)
+{
switch (Context) {
- case PowerModuleContext_Init:
- //Already initialized?
- if (pBase == NULL)
- {
- //Anchor the starting point for the list
- //of instance base addresses.
- pAnchor->gpio.pBase = pCM;
-
- //For each instance...
- for (Instance = 0; Instance < Instances; ++Instance)
- {
- //Generate the composite module id and instance.
- ModuleId = NVRM_MODULE_ID(NvRmPrivModuleID_Gpio, Instance);
-
- //Retrieve the register base PA
- NvRmModuleGetBaseAddress(s_hRmGlobal, ModuleId,
- &Aperture, &ApertureSize);
-
- //Get the corresponding VA
- if (NvOsPhysicalMemMap(Aperture,
- ApertureSize,
- NvOsMemAttribute_Uncached,
- NVOS_MEM_READ_WRITE,
- (void*)pCM))
- {
- printk("Failed to map the context save area!\n");
- goto fail;
- }
- pCM++;
- }
- }
- break;
- case PowerModuleContext_Save:
- //Register base address list must have been
- //set by PowerModuleContext_Init.
- if (pBase == NULL)
- goto fail;
-
- //Anchor the starting point for this controller's context.
- pAnchor->gpio.pContext = pCM;
-
- //For each instance...
- for (Instance = 0; Instance < Instances; ++Instance, ++pBase)
- {
- //Register base address must have been
- //set by PowerModuleContext_Init.
- if (*pBase == 0)
- goto fail;
-
- //Save the GPIO configuration.
- *pCM++ = NV_GPIO_REGR(*pBase, CNF_0);
- *pCM++ = NV_GPIO_REGR(*pBase, CNF_1);
- *pCM++ = NV_GPIO_REGR(*pBase, CNF_2);
- *pCM++ = NV_GPIO_REGR(*pBase, CNF_3);
-
- //Save the GPIO output settings.
- *pCM++ = NV_GPIO_REGR(*pBase, OUT_0);
- *pCM++ = NV_GPIO_REGR(*pBase, OUT_1);
- *pCM++ = NV_GPIO_REGR(*pBase, OUT_2);
- *pCM++ = NV_GPIO_REGR(*pBase, OUT_3);
-
- //Save the GPIO output enable settings.
- *pCM++ = NV_GPIO_REGR(*pBase, OE_0);
- *pCM++ = NV_GPIO_REGR(*pBase, OE_1);
- *pCM++ = NV_GPIO_REGR(*pBase, OE_2);
- *pCM++ = NV_GPIO_REGR(*pBase, OE_3);
-
- //Save the GPIO level enables.
- *pCM++ = NV_GPIO_REGR(*pBase, INT_ENB_0);
- *pCM++ = NV_GPIO_REGR(*pBase, INT_ENB_1);
- *pCM++ = NV_GPIO_REGR(*pBase, INT_ENB_2);
- *pCM++ = NV_GPIO_REGR(*pBase, INT_ENB_3);
-
- //Save the GPIO
- *pCM++ = NV_GPIO_REGR(*pBase, INT_LVL_0);
- *pCM++ = NV_GPIO_REGR(*pBase, INT_LVL_1);
- *pCM++ = NV_GPIO_REGR(*pBase, INT_LVL_2);
- *pCM++ = NV_GPIO_REGR(*pBase, INT_LVL_3);
- }
- break;
+ case PowerModuleContext_RestoreLP1:
case PowerModuleContext_Restore:
- //Register base address list must have been
- //set by PowerModuleContext_Init.
- if (pBase == NULL)
- goto fail;
-
- //We should be at the same place in the context
- //as when we saved things.
- if (pCM != pAnchor->gpio.pContext)
- goto fail;
-
- //Retrieve the anchored starting point for this controller's context.
- pCM = pAnchor->gpio.pContext;
- if (pCM == NULL)
- goto fail;
-
- //For each instance...
- for (Instance = 0; Instance < Instances; ++Instance, ++pBase)
- {
- //Register base address must have been
- //set by PowerModuleContext_Init.
- if (*pBase == 0)
- goto fail;
-
- //Restore the GPIO configuration.
- NV_GPIO_REGW(*pBase, CNF_0, *pCM++);
- NV_GPIO_REGW(*pBase, CNF_1, *pCM++);
- NV_GPIO_REGW(*pBase, CNF_2, *pCM++);
- NV_GPIO_REGW(*pBase, CNF_3, *pCM++);
-
- //Restore the GPIO output settings.
- NV_GPIO_REGW(*pBase, OUT_0, *pCM++);
- NV_GPIO_REGW(*pBase, OUT_1, *pCM++);
- NV_GPIO_REGW(*pBase, OUT_2, *pCM++);
- NV_GPIO_REGW(*pBase, OUT_3, *pCM++);
-
- //Restore the GPIO output enable settings.
- NV_GPIO_REGW(*pBase, OE_0, *pCM++);
- NV_GPIO_REGW(*pBase, OE_1, *pCM++);
- NV_GPIO_REGW(*pBase, OE_2, *pCM++);
- NV_GPIO_REGW(*pBase, OE_3, *pCM++);
-
- //Restore the GPIO level enables.
- NV_GPIO_REGW(*pBase, INT_ENB_0, *pCM++);
- NV_GPIO_REGW(*pBase, INT_ENB_1, *pCM++);
- NV_GPIO_REGW(*pBase, INT_ENB_2, *pCM++);
- NV_GPIO_REGW(*pBase, INT_ENB_3, *pCM++);
-
- //Restore the shadowed GPIO level settings.
- NV_GPIO_REGW(*pBase, INT_LVL_0, *pCM++);
- NV_GPIO_REGW(*pBase, INT_LVL_1, *pCM++);
- NV_GPIO_REGW(*pBase, INT_LVL_2, *pCM++);
- NV_GPIO_REGW(*pBase, INT_LVL_3, *pCM++);
- }
+ tegra_gpio_resume();
break;
case PowerModuleContext_SaveLP1:
- //Register base address list must have been
- //set by PowerModuleContext_Init.
- if (pBase == NULL)
- goto fail;
-
- //Anchor the starting point for this controller's context.
- pAnchor->gpio.pContext = pCM;
-
- //For each instance...
- for (Instance = 0; Instance < Instances; ++Instance, ++pBase)
- {
- //Register base address must have been
- //set by PowerModuleContext_Init.
- if (*pBase == 0)
- goto fail;
-
- //Save the GPIO enables.
- *pCM++ = NV_GPIO_REGR(*pBase, INT_ENB_0);
- *pCM++ = NV_GPIO_REGR(*pBase, INT_ENB_1);
- *pCM++ = NV_GPIO_REGR(*pBase, INT_ENB_2);
- *pCM++ = NV_GPIO_REGR(*pBase, INT_ENB_3);
- }
- break;
- case PowerModuleContext_RestoreLP1:
- //Register base address list must have been
- //set by PowerModuleContext_Init.
- if (pBase == NULL)
- goto fail;
-
- //We should be at the same place in the context
- //as when we saved things.
- if (pCM != pAnchor->gpio.pContext)
- goto fail;
-
- //For each instance...
- for (Instance = 0; Instance < Instances; ++Instance, ++pBase)
- {
- //Register base address must have been
- //set by PowerModuleContext_Init.
- if (*pBase == 0)
- goto fail;
-
- // Restore the GPIO enables.
- NV_GPIO_REGW(*pBase, INT_ENB_0, *pCM++);
- NV_GPIO_REGW(*pBase, INT_ENB_1, *pCM++);
- NV_GPIO_REGW(*pBase, INT_ENB_2, *pCM++);
- NV_GPIO_REGW(*pBase, INT_ENB_3, *pCM++);
- }
- break;
- case PowerModuleContext_DisableInterrupt:
- //Register base address list must have been
- //set by PowerModuleContext_Init.
- if (pBase == NULL)
- goto fail;
-
- //For each instance...
- for (Instance = 0; Instance < Instances; ++Instance, ++pBase)
- {
- //Register base address must have been
- //set by PowerModuleContext_Init.
- if (*pBase == 0)
- goto fail;
-
- //Disable module interrupts.
- NV_GPIO_REGW(*pBase, INT_ENB_0, 0);
- NV_GPIO_REGW(*pBase, INT_ENB_1, 0);
- NV_GPIO_REGW(*pBase, INT_ENB_2, 0);
- NV_GPIO_REGW(*pBase, INT_ENB_3, 0);
- }
+ case PowerModuleContext_Save:
+ tegra_gpio_suspend();
break;
default:
break;
}
return pCM;
-fail:
- return NULL;
}
static NvU32* save_apbdma_context(
diff --git a/arch/arm/mach-tegra/power-t2.c b/arch/arm/mach-tegra/power-t2.c
index b756fbb5c147..08129b744838 100644
--- a/arch/arm/mach-tegra/power-t2.c
+++ b/arch/arm/mach-tegra/power-t2.c
@@ -23,8 +23,6 @@
#include "power.h"
#include "linux/interrupt.h"
-extern void NvPrivAp20MaskIrq(unsigned int irq);
-extern void NvPrivAp20UnmaskIrq(unsigned int irq);
extern int enter_power_state(PowerState state, unsigned int proc_id);
extern void prepare_for_wb0(void);
extern void prepare_for_wb1(void);
@@ -38,7 +36,6 @@ void enable_plls(NvBool enable);
void do_suspend_prep(void);
void reset_cpu(unsigned int cpu, unsigned int reset);
static void init_lp0_scratch_registers(void);
-static void create_wakeup_irqs(void);
void shadow_runstate_scratch_regs(void);
void shadow_lp0_scratch_regs(void);
@@ -57,60 +54,12 @@ volatile void *g_pPMC, *g_pAHB, *g_pCLK_RST_CONTROLLER;
volatile void *g_pEMC, *g_pMC, *g_pAPB_MISC, *g_pTimerus;
volatile void *g_pIRAM;
-// Chip external specific wakeup events list
-static const struct wakeup_source s_WakeupSources[] =
-{
- WAKEUP_EXTERNAL('o', 5), //wake 0
- WAKEUP_EXTERNAL('v', 3), //wake 1
- WAKEUP_EXTERNAL('l', 1), //wake 2
- WAKEUP_EXTERNAL('b', 6), //wake 3
- WAKEUP_EXTERNAL('n', 7), //wake 4
- WAKEUP_EXTERNAL('a', 0), //wake 5
- WAKEUP_EXTERNAL('u', 5), //wake 6
- WAKEUP_EXTERNAL('u', 6), //wake 7
- WAKEUP_EXTERNAL('c', 7), //wake 8
- WAKEUP_EXTERNAL('s', 2), //wake 9
- WAKEUP_EXTERNAL( aa, 1), //wake 10
- WAKEUP_EXTERNAL('w', 3), //wake 11
- WAKEUP_EXTERNAL('w', 2), //wake 12
- WAKEUP_EXTERNAL('y', 6), //wake 13
- WAKEUP_EXTERNAL('v', 6), //wake 14
- WAKEUP_EXTERNAL('j', 7), //wake 15
- WAKEUP_INTERNAL(NvRmModuleID_Rtc, 0, 0), //wake 16
- WAKEUP_INTERNAL(NvRmModuleID_Kbc, 0, 0), //wake 17
- WAKEUP_INTERNAL(NvRmPrivModuleID_PmuExt, 0, 0), //wake 18
- //TODO: Check if USB values are correct
- WAKEUP_INTERNAL(NvRmModuleID_Usb2Otg, 0, 0), //wake 19
- WAKEUP_INTERNAL(NvRmModuleID_Usb2Otg, 0, 1), //wake 20
- WAKEUP_INTERNAL(NvRmModuleID_Usb2Otg, 1, 0), //wake 21
- WAKEUP_INTERNAL(NvRmModuleID_Usb2Otg, 1, 1), //wake 22
- WAKEUP_EXTERNAL('i', 5), //wake 23
- WAKEUP_EXTERNAL('v', 2), //wake 24
- WAKEUP_EXTERNAL('s', 4), //wake 25
- WAKEUP_EXTERNAL('s', 5), //wake 26
- WAKEUP_EXTERNAL('s', 0), //wake 27
- WAKEUP_EXTERNAL('q', 6), //wake 28
- WAKEUP_EXTERNAL('q', 7), //wake 29
- WAKEUP_EXTERNAL('n', 2), //wake 30
-};
-
#define WAKEUP_SOURCE_INT_RTC 16
#define INVALID_IRQ (0xFFFF)
#define AP20_BASE_PA_BOOT_INFO 0x40000000
#define MAX_IRQ_CONTROLLERS 4
#define MAX_IRQ (32*(MAX_IRQ_CONTROLLERS+1))
-//IRQs of external wake events.
-static NvIrqNumber s_WakeupIrqTable[NV_ARRAY_SIZE(s_WakeupSources)];
-
-//Extended table of external wakeup events. If the wakeup source
-//doesn't fall under the default 16 (chip specific) wakeup sources
-//add it to this list.
-static const NvIrqNumber s_WakeupIrqTableEx[] =
-{
- INVALID_IRQ
-};
-
void cpu_ap20_do_lp0(void)
{
//NOTE: Once we enter this routine, there is no way to avert a LP0.
@@ -171,55 +120,6 @@ void cpu_ap20_do_lp0(void)
//Interrupt, gpio, pin mux, clock management etc
perform_context_operation(PowerModuleContext_Restore);
}
-void prepare_lp1_wake_events(NvBool entry)
-{
- NvU32 irq_count, irq;
-
- for (irq_count=0;irq_count<NV_ARRAY_SIZE(s_WakeupIrqTable);irq_count++)
- {
- irq = s_WakeupIrqTable[irq_count];
-
- if (irq != INVALID_IRQ)
- {
- printk("irq = %d\n", s_WakeupIrqTable[irq_count]);
-
- if (entry) {
- if (irq < MAX_IRQ)
- NvPrivAp20UnmaskIrq(irq);
- else {
- NvU32 irq_top;
- irq_top = NvRmGetIrqForLogicalInterrupt(
- s_hRmGlobal,
- s_WakeupSources[irq_count].Module,
- 0xff);
- NvPrivAp20UnmaskIrq(irq_top);
- enable_irq_wake(irq);
- }
- } else {
- /* resume path only nullifies gpio interrupt */
- if (irq >= MAX_IRQ) {
- disable_irq_wake(irq);
- }
- }
- }
- }
-
- /* Exit if it is called after resume */
- if (entry == NV_FALSE)
- return;
-
- for (irq_count=0;irq_count<NV_ARRAY_SIZE(s_WakeupIrqTableEx);irq_count++)
- {
- irq = s_WakeupIrqTableEx[irq_count];
- if (irq != INVALID_IRQ)
- {
- if (irq < MAX_IRQ)
- NvPrivAp20UnmaskIrq(irq);
- else
- pr_err("specific GPIO wakeups not supported\n");
- }
- }
-}
void cpu_ap20_do_lp1(void)
{
@@ -227,7 +127,6 @@ void cpu_ap20_do_lp1(void)
unsigned int proc_id = smp_processor_id();
prepare_for_wb1();
- prepare_lp1_wake_events(NV_TRUE);
//Inform RM about entry to LP1 state
NvRmPrivPowerSetState(s_hRmGlobal, NvRmPowerState_LP1);
@@ -248,7 +147,7 @@ void cpu_ap20_do_lp1(void)
if (!proc_id)
{
//Disable the Statistics interrupt
- NvPrivAp20MaskIrq(irq);
+ disable_irq(INT_SYS_STATS_MON);
do_suspend_prep();
// Set/save CPU power good count
@@ -266,7 +165,7 @@ void cpu_ap20_do_lp1(void)
if (!proc_id)
{
//We're back
- NvPrivAp20UnmaskIrq(irq);
+ enable_irq(INT_SYS_STATS_MON);
g_NumActiveCPUs = num_online_cpus();
// Assembly LP1 code explicitly turn on PLLX,PLLM and PLLP so no need to enable it
@@ -290,20 +189,13 @@ void cpu_ap20_do_lp1(void)
NvOsMemcpy((void*)g_pIRAM, (void*)g_iramContextSaveVA,
AVP_CONTEXT_SAVE_AREA_SIZE);
- prepare_lp1_wake_events(NV_FALSE);
- //Restore the saved module(s) context
- //Interrupt, gpio, pin mux, clock management etc
perform_context_operation(PowerModuleContext_RestoreLP1);
}
void cpu_ap20_do_lp2(void)
{
- NvU32 irq, moduleId;
unsigned int proc_id = smp_processor_id();
- moduleId = NVRM_MODULE_ID(NvRmModuleID_SysStatMonitor, 0);
- irq = NvRmGetIrqForLogicalInterrupt(s_hRmGlobal, moduleId, 0);
-
//Save our context ptrs to scratch regs
NV_REGW(s_hRmGlobal, NvRmModuleID_Pmif, 0,
APBDEV_PMC_SCRATCH33_0, g_resume);
@@ -315,7 +207,7 @@ void cpu_ap20_do_lp2(void)
if (!proc_id)
{
//Disable the Statistics interrupt
- NvPrivAp20MaskIrq(irq);
+ disable_irq(INT_SYS_STATS_MON);
do_suspend_prep();
}
@@ -325,7 +217,7 @@ void cpu_ap20_do_lp2(void)
if (!proc_id)
{
//We're back
- NvPrivAp20UnmaskIrq(irq);
+ enable_irq(INT_SYS_STATS_MON);
g_NumActiveCPUs = num_online_cpus();
//Delay if needed
@@ -417,11 +309,6 @@ void power_lp0_init(void)
g_lp1CpuPwrGoodCnt =
(4096 * PmuProperty.CpuPowerGoodUs + 124999) / 125000;
- //Create the list of wakeup IRQs.
- create_wakeup_irqs();
- return;
-fail:
- printk("lp0 init failed!\n");
}
//Generate definitions of local variables to hold scratch register values.
@@ -507,62 +394,6 @@ void shadow_lp0_scratch_regs(void)
#undef SHADOW_REG
}
-static void create_wakeup_irqs(void)
-{
- NvU32 WakeupTableSize;
- NvU32 Count;
- NvU32 PadNumber;
- const NvOdmWakeupPadInfo* pNvOdmWakeupPadInfo;
- const NvOdmWakeupPadInfo* pWakeupPad;
-
- //Initialize the wakeup irq table.
- for (Count = 0; Count < NV_ARRAY_SIZE(s_WakeupIrqTable); Count++)
- {
- s_WakeupIrqTable[Count] = INVALID_IRQ;
- }
-
- //Get the wakeup sources table from odm.
- pNvOdmWakeupPadInfo = NvOdmQueryGetWakeupPadTable(&WakeupTableSize);
- if (WakeupTableSize > NV_ARRAY_SIZE(s_WakeupSources))
- goto fail;
-
- //If there is a wakeup pad information table
- if (pNvOdmWakeupPadInfo)
- {
- //Then for each pad ...
- for (Count = 0; Count < WakeupTableSize; Count++)
- {
- //... get it's pad number.
- pWakeupPad = &pNvOdmWakeupPadInfo[Count];
- PadNumber = pWakeupPad->WakeupPadNumber;
-
- if (PadNumber >= NV_ARRAY_SIZE(s_WakeupSources))
- goto fail;
-
- //If the pad is enabled as a wakeup source...
- if (pWakeupPad->enable)
- {
- //... get it's IRQ number.
- s_WakeupIrqTable[PadNumber] = NvRmGetIrqForLogicalInterrupt(
- s_hRmGlobal,
- s_WakeupSources[PadNumber].Module,
- s_WakeupSources[PadNumber].Index);
- if (s_WakeupIrqTable[PadNumber] == INVALID_IRQ)
- goto fail;
- }
- }
- }
-
- // Create internal events those are transparent to ODM.
- //These events will always be enabled.
- //Nothing for now.
-
- return;
-fail:
- printk("Failed to create wakeup irqs\n");
- return;
-}
-
static NvU32 select_wakeup_pll(void)
{
NvU32 Reg = 0; // Scratch register