diff options
-rw-r--r-- | arch/arm/mach-tegra/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board_nvodm.c | 76 | ||||
-rw-r--r-- | arch/arm/mach-tegra/gpio.c | 89 | ||||
-rw-r--r-- | arch/arm/mach-tegra/include/mach/irqs.h | 46 | ||||
-rwxr-xr-x | arch/arm/mach-tegra/init_common.c | 52 | ||||
-rw-r--r-- | arch/arm/mach-tegra/irq.c | 436 | ||||
-rw-r--r-- | arch/arm/mach-tegra/irq_dma.c | 125 | ||||
-rw-r--r-- | arch/arm/mach-tegra/irq_gpio.c | 315 | ||||
-rw-r--r-- | arch/arm/mach-tegra/nvos/nvos.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-tegra/power-context-t2.c | 372 | ||||
-rw-r--r-- | arch/arm/mach-tegra/power-t2.c | 177 |
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 |