From 852663d94f0cc44199c31c0e42d4801302f41705 Mon Sep 17 00:00:00 2001 From: Pawel Moll Date: Tue, 4 Sep 2012 17:06:20 +0100 Subject: [PATCH 01/15] ARM: vexpress: Make the debug UART detection more specific Base the UART detection heuristic on architecturally defined MIDR register instead of implementation dependent CBAR. The only tile using the original memory map is V2P-CA9 with Cortex A9 r0p1, which MIDR contains value 0x410fc091. Signed-off-by: Pawel Moll --- arch/arm/include/debug/vexpress.S | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/arm/include/debug/vexpress.S b/arch/arm/include/debug/vexpress.S index 9f509f55d07..0c6abbf4c82 100644 --- a/arch/arm/include/debug/vexpress.S +++ b/arch/arm/include/debug/vexpress.S @@ -23,12 +23,14 @@ .macro addruart,rp,rv,tmp @ Make an educated guess regarding the memory map: - @ - the original A9 core tile, which has MPCore peripherals - @ located at 0x1e000000, should use UART at 0x10009000 + @ - the original A9 core tile (based on ARM Cortex-A9 r0p1) + @ should use UART at 0x10009000 @ - all other (RS1 complaint) tiles use UART mapped @ at 0x1c090000 - mrc p15, 4, \tmp, c15, c0, 0 - cmp \tmp, #0x1e000000 + mrc p15, 0, \rp, c0, c0, 0 + movw \rv, #0xc091 + movt \rv, #0x410f + cmp \rp, \rv @ Original memory map moveq \rp, #DEBUG_LL_UART_OFFSET From 9ad90238bf4faa488680cf6dddf0d2b137960cc8 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 10 Sep 2012 04:49:23 +0000 Subject: [PATCH 02/15] ARM: davinci: dm644x evm: move pointer dereference below NULL check Pointer dereference should be moved below the NULL test. spatch with a semantic match is used to found this. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/board-dm644x-evm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index f22572cee49..f8a99ee6bff 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -519,13 +519,11 @@ static int dm6444evm_msp430_get_pins(void) char buf[4]; struct i2c_msg msg[2] = { { - .addr = dm6446evm_msp->addr, .flags = 0, .len = 2, .buf = (void __force *)txbuf, }, { - .addr = dm6446evm_msp->addr, .flags = I2C_M_RD, .len = 4, .buf = buf, @@ -536,6 +534,9 @@ static int dm6444evm_msp430_get_pins(void) if (!dm6446evm_msp) return -ENXIO; + msg[0].addr = dm6446evm_msp->addr; + msg[1].addr = dm6446evm_msp->addr; + /* Command 4 == get input state, returns port 2 and port3 data * S Addr W [A] len=2 [A] cmd=4 [A] * RS Addr R [A] [len=4] A [cmd=4] A [port2] A [port3] N P From 5604f69eec0aed392cea2909ee49dd834b782fac Mon Sep 17 00:00:00 2001 From: Henrique Camargo Date: Thu, 13 Sep 2012 15:04:36 -0300 Subject: [PATCH 03/15] ARM: davinci: serial.h: fix uart number in the comment The bit 0 of the field is uart0 and the bit 1 is uart1 and so on. Signed-off-by: Henrique Camargo Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/include/mach/serial.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-davinci/include/mach/serial.h b/arch/arm/mach-davinci/include/mach/serial.h index 46b3cd11c3c..86a01fa6d3f 100644 --- a/arch/arm/mach-davinci/include/mach/serial.h +++ b/arch/arm/mach-davinci/include/mach/serial.h @@ -38,7 +38,7 @@ #ifndef __ASSEMBLY__ struct davinci_uart_config { - /* Bit field of UARTs present; bit 0 --> UART1 */ + /* Bit field of UARTs present; bit 0 --> UART0 */ unsigned int enabled_uarts; }; From 09aaf994e37c3e37fd2b0e9b1856038e31ae3b68 Mon Sep 17 00:00:00 2001 From: Sekhar Nori Date: Tue, 28 Aug 2012 14:38:05 +0530 Subject: [PATCH 04/15] ARM: davinci: uncompress.h: bail out if uart not initialized Bail out of UART access functions in uncompress.h if the uart port is not setup. This will happen when booting from DT since machine type matching does not work in this case. This may also happen if a correct machine type is not setup by bootloader. Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/include/mach/uncompress.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/mach-davinci/include/mach/uncompress.h b/arch/arm/mach-davinci/include/mach/uncompress.h index 18cfd497715..3a0ff905a69 100644 --- a/arch/arm/mach-davinci/include/mach/uncompress.h +++ b/arch/arm/mach-davinci/include/mach/uncompress.h @@ -32,6 +32,9 @@ u32 *uart; /* PORT_16C550A, in polled non-fifo mode */ static void putc(char c) { + if (!uart) + return; + while (!(uart[UART_LSR] & UART_LSR_THRE)) barrier(); uart[UART_TX] = c; @@ -39,6 +42,9 @@ static void putc(char c) static inline void flush(void) { + if (!uart) + return; + while (!(uart[UART_LSR] & UART_LSR_THRE)) barrier(); } From 5a6a86121f55681b5ae7891d19a462883635beef Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 21 Sep 2012 14:12:31 +0800 Subject: [PATCH 05/15] ARM: davinci: fix return value check by using IS_ERR in tnetv107x_devices_init() In case of error, the function clk_get() returns ERR_PTR() not NULL pointer. The NULL test in the error handling should be replaced with IS_ERR(). dpatch engine is used to auto generated this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/devices-tnetv107x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-davinci/devices-tnetv107x.c b/arch/arm/mach-davinci/devices-tnetv107x.c index 29b17f7d3a5..773ab07a71a 100644 --- a/arch/arm/mach-davinci/devices-tnetv107x.c +++ b/arch/arm/mach-davinci/devices-tnetv107x.c @@ -374,7 +374,7 @@ void __init tnetv107x_devices_init(struct tnetv107x_device_info *info) * complete sample conversion in time. */ tsc_clk = clk_get(NULL, "sys_tsc_clk"); - if (tsc_clk) { + if (!IS_ERR(tsc_clk)) { error = clk_set_rate(tsc_clk, 5000000); WARN_ON(error < 0); clk_put(tsc_clk); From c962184459ab75502b242efb04291c2cf8700bc3 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Thu, 18 Oct 2012 12:20:04 +0300 Subject: [PATCH 06/15] ARM: OMAP4: PM: add errata support Added similar PM errata flag support as omap3 has. This should be used in similar manner, set the flags during init time, and check the flag values during runtime. Signed-off-by: Tero Kristo Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm.h | 7 +++++++ arch/arm/mach-omap2/pm44xx.c | 1 + 2 files changed, 8 insertions(+) diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 67d66131cfa..f76a0d0f839 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -102,6 +102,13 @@ extern void enable_omap3630_toggle_l2_on_restore(void); static inline void enable_omap3630_toggle_l2_on_restore(void) { } #endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */ +#if defined(CONFIG_ARCH_OMAP4) +extern u16 pm44xx_errata; +#define IS_PM44XX_ERRATUM(id) (pm44xx_errata & (id)) +#else +#define IS_PM44XX_ERRATUM(id) 0 +#endif + #ifdef CONFIG_POWER_AVS_OMAP extern int omap_devinit_smartreflex(void); extern void omap_enable_smartreflex_on_init(void); diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 04922d14906..0adbd7d81ce 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -34,6 +34,7 @@ struct power_state { }; static LIST_HEAD(pwrst_list); +u16 pm44xx_errata; #ifdef CONFIG_SUSPEND static int omap4_pm_suspend(void) From ff999b8a0983ee15668394ed49e38d3568fc6859 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Thu, 18 Oct 2012 12:20:05 +0300 Subject: [PATCH 07/15] ARM: OMAP4460: Workaround for ROM bug because of CA9 r2pX GIC control register change. On OMAP4+ devices, GIC register context is lost when MPUSS hits the OSWR(Open Switch Retention). On the CPU wakeup path, ROM code gets executed and one of the steps in it is to restore the saved context of the GIC. The ROM Code GIC distributor restoration is split in two parts: CPU specific register done by each CPU and common register done by only one CPU. Below is the abstract flow. ............................................................... - MPUSS in OSWR state. - CPU0 wakes up on the event(interrupt) and start executing ROM code. [..] - CPU0 executes "GIC Restoration:" [...] - CPU0 swicthes to non-secure mode and jumps to OS resume code. [...] - CPU0 is online in OS - CPU0 enables the GIC distributor. GICD.Enable Non-secure = 1 - CPU0 wakes up CPU1 with clock-domain force wakeup method. - CPU0 continues it's execution. [..] - CPU1 wakes up and start executing ROM code. [..] - CPU1 executes "GIC Restoration:" [..] - CPU1 swicthes to non-secure mode and jumps to OS resume code. [...] - CPU1 is online in OS and start executing. [...] - GIC Restoration: /* Common routine for HS and GP devices */ { if (GICD != 1) { /* This will be true in OSWR state */ if (GIC_SAR_BACKUP_STATE == SAVED) - CPU restores GIC distributor else - reconfigure GIC distributor to boot values. GICD.Enable secure = 1 } if (GIC_SAR_BACKUP_STATE == SAVED) - CPU restore its GIC CPU interface registers if saved. else - reconfigure its GIC CPU interface registers to boot values. } ............................................................... So as mentioned in the flow, GICD != 1 condition decides how the GIC registers are handled in ROM code wakeup path from OSWR. As evident from the flow, ROM code relies on the entire GICD register value and not specific register bits. The assumption was valid till CortexA9 r1pX version since there was only one banked bit to control secure and non-secure GICD. Secure view which ROM code sees: bit 0 == Enable Non-secure Non-secure view which HLOS sees: bit 0 == Enable secure But GICD register has changed between CortexA9 r1pX and r2pX. On r2pX GICD register is composed of 2 bits. Secure view which ROM code sees: bit 1 == Enable Non-secure bit 0 == Enable secure Non-secure view which HLOS sees: bit 0 == Enable Non-secure Hence on OMAP4460(r2pX) devices, if you go through the above flow again during CPU1 wakeup, GICD == 3 and hence ROM code fails to understand the real wakeup power state and reconfigures GIC distributor to boot values. This is nasty since you loose the entire interrupt controller context in a live system. The ROM code fix done on next OMAP4 device (OMAP4470 - r2px) is to check "GICD.Enable secure != 1" for GIC restoration in OSWR wakeup path. Since ROM code can't be fixed on OMAP4460 devices, a work around needs to be implemented. As evident from the flow, as long as CPU1 sees GICD == 1 in it's wakeup path from OSWR, the issue won't happen. Below is the flow with the work-around. ............................................................... - MPUSS in OSWR state. - CPU0 wakes up on the event(interrupt) and start executing ROM code. [..] - CPU0 executes "GIC Restoration:" [..] - CPU0 swicthes to non-secure mode and jumps to OS resume code. [..] - CPU0 is online in OS. - CPU0 does GICD.Enable Non-secure = 0 - CPU0 wakes up CPU1 with clock domain force wakeup method. - CPU0 waits for GICD.Enable Non-secure = 1 - CPU0 coninues it's execution. [..] - CPU1 wakes up and start executing ROM code. [..] - CPU1 executes "GIC Restoration:" [..] - CPU1 swicthes to non-secure mode and jumps to OS resume code. [..] - CPU1 is online in OS - CPU1 does GICD.Enable Non-secure = 1 - CPU1 start executing [...] ............................................................... With this procedure, the GIC configuration done between the CPU0 wakeup and CPU1 wakeup will not be lost but during this short windows, the CPU0 will not receive interrupts. The BUG is applicable to only OMAP4460(r2pX) devices. OMAP4470 (also r2pX) is not affected by this bug because ROM code has been fixed. Signed-off-by: Santosh Shilimkar Signed-off-by: Tero Kristo Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/common.h | 2 ++ arch/arm/mach-omap2/omap-headsmp.S | 38 +++++++++++++++++++++++ arch/arm/mach-omap2/omap-mpuss-lowpower.c | 9 +++++- arch/arm/mach-omap2/omap-smp.c | 28 ++++++++++++++++- arch/arm/mach-omap2/omap4-common.c | 8 ++++- arch/arm/mach-omap2/pm.h | 2 ++ 6 files changed, 84 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 7045e4d61ac..70993a9fcb5 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -275,6 +275,7 @@ static inline void __iomem *omap4_get_scu_base(void) #endif extern void __init gic_init_irq(void); +extern void gic_dist_disable(void); extern void omap_smc1(u32 fn, u32 arg); extern void __iomem *omap4_get_sar_ram_base(void); extern void omap_do_wfi(void); @@ -282,6 +283,7 @@ extern void omap_do_wfi(void); #ifdef CONFIG_SMP /* Needed for secondary core boot */ extern void omap_secondary_startup(void); +extern void omap_secondary_startup_4460(void); extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); extern void omap_auxcoreboot_addr(u32 cpu_addr); extern u32 omap_read_auxcoreboot0(void); diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S index 502e3135aad..0ea09faf327 100644 --- a/arch/arm/mach-omap2/omap-headsmp.S +++ b/arch/arm/mach-omap2/omap-headsmp.S @@ -18,6 +18,8 @@ #include #include +#include "omap44xx.h" + __CPUINIT /* Physical address needed since MMU not enabled yet on secondary core */ @@ -64,3 +66,39 @@ hold: ldr r12,=0x103 b secondary_startup ENDPROC(omap_secondary_startup) +ENTRY(omap_secondary_startup_4460) +hold_2: ldr r12,=0x103 + dsb + smc #0 @ read from AuxCoreBoot0 + mov r0, r0, lsr #9 + mrc p15, 0, r4, c0, c0, 5 + and r4, r4, #0x0f + cmp r0, r4 + bne hold_2 + + /* + * GIC distributor control register has changed between + * CortexA9 r1pX and r2pX. The Control Register secure + * banked version is now composed of 2 bits: + * bit 0 == Secure Enable + * bit 1 == Non-Secure Enable + * The Non-Secure banked register has not changed + * Because the ROM Code is based on the r1pX GIC, the CPU1 + * GIC restoration will cause a problem to CPU0 Non-Secure SW. + * The workaround must be: + * 1) Before doing the CPU1 wakeup, CPU0 must disable + * the GIC distributor + * 2) CPU1 must re-enable the GIC distributor on + * it's wakeup path. + */ + ldr r1, =OMAP44XX_GIC_DIST_BASE + ldr r0, [r1] + orr r0, #1 + str r0, [r1] + + /* + * we've been released from the wait loop,secondary_stack + * should now contain the SVC stack for this core + */ + b secondary_startup +ENDPROC(omap_secondary_startup_4460) diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index ff4e6a0e9c7..c8bc3ad85f6 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -67,6 +67,7 @@ struct omap4_cpu_pm_info { void __iomem *scu_sar_addr; void __iomem *wkup_sar_addr; void __iomem *l2x0_sar_addr; + void (*secondary_startup)(void); }; static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); @@ -299,6 +300,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) { unsigned int cpu_state = 0; + struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu); if (omap_rev() == OMAP4430_REV_ES1_0) return -ENXIO; @@ -308,7 +310,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) clear_cpu_prev_pwrst(cpu); set_cpu_next_pwrst(cpu, power_state); - set_cpu_wakeup_addr(cpu, virt_to_phys(omap_secondary_startup)); + set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup)); scu_pwrst_prepare(cpu, power_state); /* @@ -359,6 +361,11 @@ int __init omap4_mpuss_init(void) pm_info->scu_sar_addr = sar_base + SCU_OFFSET1; pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET; pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1; + if (cpu_is_omap446x()) + pm_info->secondary_startup = omap_secondary_startup_4460; + else + pm_info->secondary_startup = omap_secondary_startup; + pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm"); if (!pm_info->pwrdm) { pr_err("Lookup failed for CPU1 pwrdm\n"); diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 4d05fa8a4e4..7d9c0e3fedc 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -32,6 +32,7 @@ #include "iomap.h" #include "common.h" #include "clockdomain.h" +#include "pm.h" #define CPU_MASK 0xff0ffff0 #define CPU_CORTEX_A9 0x410FC090 @@ -118,6 +119,24 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct * * 4.3.4.2 Power States of CPU0 and CPU1 */ if (booted) { + /* + * GIC distributor control register has changed between + * CortexA9 r1pX and r2pX. The Control Register secure + * banked version is now composed of 2 bits: + * bit 0 == Secure Enable + * bit 1 == Non-Secure Enable + * The Non-Secure banked register has not changed + * Because the ROM Code is based on the r1pX GIC, the CPU1 + * GIC restoration will cause a problem to CPU0 Non-Secure SW. + * The workaround must be: + * 1) Before doing the CPU1 wakeup, CPU0 must disable + * the GIC distributor + * 2) CPU1 must re-enable the GIC distributor on + * it's wakeup path. + */ + if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) + gic_dist_disable(); + clkdm_wakeup(cpu1_clkdm); clkdm_allow_idle(cpu1_clkdm); } else { @@ -138,7 +157,14 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct * static void __init wakeup_secondary(void) { + void *startup_addr = omap_secondary_startup; void __iomem *base = omap_get_wakeupgen_base(); + + if (cpu_is_omap446x()) { + startup_addr = omap_secondary_startup_4460; + pm44xx_errata |= PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD; + } + /* * Write the address of secondary startup routine into the * AuxCoreBoot1 where ROM code will jump and start executing @@ -146,7 +172,7 @@ static void __init wakeup_secondary(void) * A barrier is added to ensure that write buffer is drained */ if (omap_secure_apis_support()) - omap_auxcoreboot_addr(virt_to_phys(omap_secondary_startup)); + omap_auxcoreboot_addr(virt_to_phys(startup_addr)); else __raw_writel(virt_to_phys(omap5_secondary_startup), base + OMAP_AUX_CORE_BOOT_1); diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index e1f289748c5..72cf396a0fc 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c @@ -41,6 +41,7 @@ static void __iomem *l2cache_base; #endif static void __iomem *sar_ram_base; +static void __iomem *gic_dist_base_addr; #ifdef CONFIG_OMAP4_ERRATA_I688 /* Used to implement memory barrier on DRAM path */ @@ -95,7 +96,6 @@ void __init omap_barriers_init(void) void __init gic_init_irq(void) { void __iomem *omap_irq_base; - void __iomem *gic_dist_base_addr; /* Static mapping, never released */ gic_dist_base_addr = ioremap(OMAP44XX_GIC_DIST_BASE, SZ_4K); @@ -110,6 +110,12 @@ void __init gic_init_irq(void) gic_init(0, 29, gic_dist_base_addr, omap_irq_base); } +void gic_dist_disable(void) +{ + if (gic_dist_base_addr) + __raw_writel(0x0, gic_dist_base_addr + GIC_DIST_CTRL); +} + #ifdef CONFIG_CACHE_L2X0 void __iomem *omap4_get_l2cache_base(void) diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index f76a0d0f839..fc3c96d5e01 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -102,6 +102,8 @@ extern void enable_omap3630_toggle_l2_on_restore(void); static inline void enable_omap3630_toggle_l2_on_restore(void) { } #endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */ +#define PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD (1 << 0) + #if defined(CONFIG_ARCH_OMAP4) extern u16 pm44xx_errata; #define IS_PM44XX_ERRATUM(id) (pm44xx_errata & (id)) From cd8ce159031813eb870a5f3d5b27c3be36cd6e3a Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 18 Oct 2012 12:20:08 +0300 Subject: [PATCH 08/15] ARM: OMAP4: retrigger localtimers after re-enabling gic 'Workaround for ROM bug because of CA9 r2pX gic control' register change disables the gic distributor while the secondary cpu is being booted. If a localtimer interrupt on the primary cpu occurs when the distributor is turned off, the interrupt is lost, and the localtimer never fires again. Make the primary cpu wait for the secondary cpu to reenable the gic distributor (with interrupts off for safety), and then check if the pending bit is set in the localtimer but not the gic. If so, ack it in the localtimer, and reset the timer with the minimum timeout to trigger a new timer interrupt. Signed-off-by: Colin Cross [s-jan@ti.com: adapted to k3.4 + validated functionality] Signed-off-by: Sebastien Jan [t-kristo@ti.com: dropped generic ARM kernel exports from the code, rebased to mainline] Signed-off-by: Tero Kristo Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/common.h | 2 ++ arch/arm/mach-omap2/omap-smp.c | 13 +++++++++++- arch/arm/mach-omap2/omap4-common.c | 34 ++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 70993a9fcb5..d29dbaa2962 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -276,6 +276,8 @@ static inline void __iomem *omap4_get_scu_base(void) extern void __init gic_init_irq(void); extern void gic_dist_disable(void); +extern bool gic_dist_disabled(void); +extern void gic_timer_retrigger(void); extern void omap_smc1(u32 fn, u32 arg); extern void __iomem *omap4_get_sar_ram_base(void); extern void omap_do_wfi(void); diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 7d9c0e3fedc..49a08dfe8d8 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -134,11 +134,22 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct * * 2) CPU1 must re-enable the GIC distributor on * it's wakeup path. */ - if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) + if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) { + local_irq_disable(); gic_dist_disable(); + } clkdm_wakeup(cpu1_clkdm); clkdm_allow_idle(cpu1_clkdm); + + if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) { + while (gic_dist_disabled()) { + udelay(1); + cpu_relax(); + } + gic_timer_retrigger(); + local_irq_enable(); + } } else { dsb_sev(); booted = true; diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index 72cf396a0fc..6f94b4e7b18 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +25,7 @@ #include #include #include +#include #include #include @@ -42,6 +44,9 @@ static void __iomem *l2cache_base; static void __iomem *sar_ram_base; static void __iomem *gic_dist_base_addr; +static void __iomem *twd_base; + +#define IRQ_LOCALTIMER 29 #ifdef CONFIG_OMAP4_ERRATA_I688 /* Used to implement memory barrier on DRAM path */ @@ -101,6 +106,9 @@ void __init gic_init_irq(void) gic_dist_base_addr = ioremap(OMAP44XX_GIC_DIST_BASE, SZ_4K); BUG_ON(!gic_dist_base_addr); + twd_base = ioremap(OMAP44XX_LOCAL_TWD_BASE, SZ_4K); + BUG_ON(!twd_base); + /* Static mapping, never released */ omap_irq_base = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512); BUG_ON(!omap_irq_base); @@ -116,6 +124,32 @@ void gic_dist_disable(void) __raw_writel(0x0, gic_dist_base_addr + GIC_DIST_CTRL); } +bool gic_dist_disabled(void) +{ + return !(__raw_readl(gic_dist_base_addr + GIC_DIST_CTRL) & 0x1); +} + +void gic_timer_retrigger(void) +{ + u32 twd_int = __raw_readl(twd_base + TWD_TIMER_INTSTAT); + u32 gic_int = __raw_readl(gic_dist_base_addr + GIC_DIST_PENDING_SET); + u32 twd_ctrl = __raw_readl(twd_base + TWD_TIMER_CONTROL); + + if (twd_int && !(gic_int & BIT(IRQ_LOCALTIMER))) { + /* + * The local timer interrupt got lost while the distributor was + * disabled. Ack the pending interrupt, and retrigger it. + */ + pr_warn("%s: lost localtimer interrupt\n", __func__); + __raw_writel(1, twd_base + TWD_TIMER_INTSTAT); + if (!(twd_ctrl & TWD_TIMER_CONTROL_PERIODIC)) { + __raw_writel(1, twd_base + TWD_TIMER_COUNTER); + twd_ctrl |= TWD_TIMER_CONTROL_ENABLE; + __raw_writel(twd_ctrl, twd_base + TWD_TIMER_CONTROL); + } + } +} + #ifdef CONFIG_CACHE_L2X0 void __iomem *omap4_get_l2cache_base(void) From d892a91730013b306cef3b55be6cc0b2755d6d24 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 8 Nov 2012 14:05:23 +0000 Subject: [PATCH 09/15] ARM: vexpress: fix ll debug code when building multiplatform After "ARM: vexpress: Make the debug UART detection more specific", building allyesconfig in linux-next now gives me: arch/arm/kernel/debug.S: Assembler messages: arch/arm/kernel/debug.S:81: Error: selected processor does not support ARM mode `movw r2,#0xc 091' arch/arm/kernel/debug.S:81: Error: selected processor does not support ARM mode `movt r2,#0x4 10f' arch/arm/kernel/debug.S:97: Error: selected processor does not support ARM mode `movw r2,#0xc 091' arch/arm/kernel/debug.S:97: Error: selected processor does not support ARM mode `movt r2,#0x4 10f' arch/arm/kernel/debug.S:104: Error: selected processor does not support ARM mode `movw r3,#0x c091' arch/arm/kernel/debug.S:104: Error: selected processor does not support ARM mode `movt r3,#0x 410f' Since the code can never get executed on ARMv6 but might be built in a configuration that has ARMv6 enabled, it's safe to just mark it in the assembly source for being ARMv7-only. Signed-off-by: Arnd Bergmann Acked-by: Pawel Moll --- arch/arm/include/debug/vexpress.S | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/include/debug/vexpress.S b/arch/arm/include/debug/vexpress.S index 0c6abbf4c82..dc8e882a625 100644 --- a/arch/arm/include/debug/vexpress.S +++ b/arch/arm/include/debug/vexpress.S @@ -21,6 +21,7 @@ #if defined(CONFIG_DEBUG_VEXPRESS_UART0_DETECT) .macro addruart,rp,rv,tmp + .arch armv7-a @ Make an educated guess regarding the memory map: @ - the original A9 core tile (based on ARM Cortex-A9 r0p1) From 6c8e94a57c30e31d0807f038b4f98b659fd67776 Mon Sep 17 00:00:00 2001 From: Imre Kaloz Date: Thu, 8 Nov 2012 06:37:09 +0100 Subject: [PATCH 10/15] ARM: cns3xxx: drop unnecessary symbol selection ARCH_CNS3XXX already selects MIGHT_HAVE_PCI, so boards don't have to Signed-off-by: Imre Kaloz Signed-off-by: Arnd Bergmann --- arch/arm/mach-cns3xxx/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-cns3xxx/Kconfig b/arch/arm/mach-cns3xxx/Kconfig index 29b13f249aa..9ebfcc46feb 100644 --- a/arch/arm/mach-cns3xxx/Kconfig +++ b/arch/arm/mach-cns3xxx/Kconfig @@ -3,7 +3,6 @@ menu "CNS3XXX platform type" config MACH_CNS3420VB bool "Support for CNS3420 Validation Board" - select MIGHT_HAVE_PCI help Include support for the Cavium Networks CNS3420 MPCore Platform Baseboard. From 936407358759adb302df93ab61fa68141897270c Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Wed, 14 Nov 2012 16:54:27 -0800 Subject: [PATCH 11/15] ARM: OMAP4: PM: fix errata handling when CONFIG_PM=n commit c9621844 (ARM: OMAP4: PM: add errata support) introduced errata handling for OMAP4, but was broken when CONFIG_PM=n. When CONFIG_PM=n, pm44xx.c is not compiled, yet that is where pm44xx_errata is defined. However, these errata are needed for the SMP boot/hotplug case also, and are primarily used in omap-smp.c. Move the definition of pm44xx_errata to omap-smp.c so that it's available even in the CONFIG_PM=n case. Cc: Tero Kristo Signed-off-by: Kevin Hilman Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/omap-smp.c | 2 ++ arch/arm/mach-omap2/pm44xx.c | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 49a08dfe8d8..cd42d921940 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -40,6 +40,8 @@ #define OMAP5_CORE_COUNT 0x2 +u16 pm44xx_errata; + /* SCU base address */ static void __iomem *scu_base; diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 0adbd7d81ce..04922d14906 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -34,7 +34,6 @@ struct power_state { }; static LIST_HEAD(pwrst_list); -u16 pm44xx_errata; #ifdef CONFIG_SUSPEND static int omap4_pm_suspend(void) From 8757e168190a6ed2cd4aa23fc59bf86b0091b596 Mon Sep 17 00:00:00 2001 From: Andrea Adami Date: Wed, 21 Nov 2012 01:37:25 +0100 Subject: [PATCH 12/15] ARM: pxa: fix pxa25x gpio wakeup setting * Since 3.3 gpio wakeup is broken on pxa25x (tested on corgi and poodle). * Use gpio_set_wake like done for pxa27x with commit id * b95ace54a23e2f8ebb032744cebb17c9f43bf651 Signed-off-by: Andrea Adami Acked-by: Haojian Zhuang --- arch/arm/mach-pxa/pxa25x.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index 3352b37b60c..aeb913eee8a 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -338,6 +338,10 @@ void __init pxa25x_map_io(void) pxa25x_get_clk_frequency_khz(1); } +static struct pxa_gpio_platform_data pxa25x_gpio_info __initdata = { + .gpio_set_wake = gpio_set_wake, +}; + static struct platform_device *pxa25x_devices[] __initdata = { &pxa25x_device_udc, &pxa_device_pmu, @@ -370,6 +374,7 @@ static int __init pxa25x_init(void) register_syscore_ops(&pxa2xx_mfp_syscore_ops); register_syscore_ops(&pxa2xx_clock_syscore_ops); + pxa_register_device(&pxa_device_gpio, &pxa25x_gpio_info); ret = platform_add_devices(pxa25x_devices, ARRAY_SIZE(pxa25x_devices)); if (ret) From d90cb69ddd032854b633c4069ba3493651cb8ebc Mon Sep 17 00:00:00 2001 From: Andrea Adami Date: Fri, 23 Nov 2012 01:03:39 +0100 Subject: [PATCH 13/15] ARM: pxa: add dummy SA1100 rtc clock in pxa25x * fix failure seen on Zaurus corgi: * sa1100-rtc sa1100-rtc: failed to find rtc clock source * sa1100-rtc: probe of sa1100-rtc failed with error -2 Signed-off-by: Andrea Adami Acked-by: Haojian Zhuang --- arch/arm/mach-pxa/pxa25x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index aeb913eee8a..3f5171eaf67 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -209,6 +209,7 @@ static struct clk_lookup pxa25x_clkregs[] = { INIT_CLKREG(&clk_pxa25x_gpio12, NULL, "GPIO12_CLK"), INIT_CLKREG(&clk_pxa25x_mem, "pxa2xx-pcmcia", NULL), INIT_CLKREG(&clk_dummy, "pxa-gpio", NULL), + INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL), }; static struct clk_lookup pxa25x_hwuart_clkreg = From 678a09905002aa1dcade4af0227afc67ee13b2ce Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sun, 25 Nov 2012 18:53:40 +0400 Subject: [PATCH 14/15] ARM: Fix Kconfig symbols typo for LEDS Correct option should be LEDS_TRIGGERS, not LEDS_TRIGGER. Signed-off-by: Alexander Shiyan Signed-off-by: Arnd Bergmann --- arch/arm/mach-s3c24xx/Kconfig | 2 +- arch/arm/plat-versatile/Kconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig index 2b6cb5f29c2..d7a13d1771a 100644 --- a/arch/arm/mach-s3c24xx/Kconfig +++ b/arch/arm/mach-s3c24xx/Kconfig @@ -400,7 +400,7 @@ config MACH_MINI2440 bool "MINI2440 development board" select EEPROM_AT24 select LEDS_CLASS - select LEDS_TRIGGER + select LEDS_TRIGGERS select LEDS_TRIGGER_BACKLIGHT select NEW_LEDS select S3C_DEV_NAND diff --git a/arch/arm/plat-versatile/Kconfig b/arch/arm/plat-versatile/Kconfig index 2a4ae8a6a08..eb50231c4ef 100644 --- a/arch/arm/plat-versatile/Kconfig +++ b/arch/arm/plat-versatile/Kconfig @@ -19,7 +19,7 @@ config PLAT_VERSATILE_LEDS def_bool y if NEW_LEDS depends on ARCH_REALVIEW || ARCH_VERSATILE select LEDS_CLASS - select LEDS_TRIGGER + select LEDS_TRIGGERS config PLAT_VERSATILE_SCHED_CLOCK def_bool y From 5e2125985045270564f84ce8891a0453320f27cb Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Tue, 27 Nov 2012 11:41:49 +0900 Subject: [PATCH 15/15] Update ARM/SHMOBILE section of MAINTAINERS I have been handling maintenance of shmobile for a little over a release-cycle now and it seems to appropriate to update the MAINTAINERS file accordingly. Acked-by: Paul Mundt Signed-off-by: Simon Horman --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index e73060fe078..056200c3ad5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1114,12 +1114,12 @@ S: Maintained F: drivers/media/platform/s5p-tv/ ARM/SHMOBILE ARM ARCHITECTURE -M: Paul Mundt +M: Simon Horman M: Magnus Damm L: linux-sh@vger.kernel.org W: http://oss.renesas.com Q: http://patchwork.kernel.org/project/linux-sh/list/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6.git rmobile-latest +T: git git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git next S: Supported F: arch/arm/mach-shmobile/ F: drivers/sh/