| 
					
				 | 
			
			
				@@ -140,3 +140,188 @@ static void wakeupgen_mask(struct irq_data *d) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Architecture specific Unmask extension 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void wakeupgen_unmask(struct irq_data *d) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	unsigned long flags; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	spin_lock_irqsave(&wakeupgen_lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	_wakeupgen_set(d->irq, irq_target_cpu[d->irq]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	spin_unlock_irqrestore(&wakeupgen_lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifdef CONFIG_HOTPLUG_CPU 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static DEFINE_PER_CPU(u32 [MAX_NR_REG_BANKS], irqmasks); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void _wakeupgen_save_masks(unsigned int cpu) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u8 i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (i = 0; i < irq_banks; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		per_cpu(irqmasks, cpu)[i] = wakeupgen_readl(i, cpu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void _wakeupgen_restore_masks(unsigned int cpu) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u8 i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (i = 0; i < irq_banks; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		wakeupgen_writel(per_cpu(irqmasks, cpu)[i], i, cpu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void _wakeupgen_set_all(unsigned int cpu, unsigned int reg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u8 i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (i = 0; i < irq_banks; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		wakeupgen_writel(reg, i, cpu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Mask or unmask all interrupts on given CPU. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *	0 = Mask all interrupts on the 'cpu' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *	1 = Unmask all interrupts on the 'cpu' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Ensure that the initial mask is maintained. This is faster than 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * iterating through GIC registers to arrive at the correct masks. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void wakeupgen_irqmask_all(unsigned int cpu, unsigned int set) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	unsigned long flags; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	spin_lock_irqsave(&wakeupgen_lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (set) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		_wakeupgen_save_masks(cpu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		_wakeupgen_set_all(cpu, WKG_MASK_ALL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		_wakeupgen_set_all(cpu, WKG_UNMASK_ALL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		_wakeupgen_restore_masks(cpu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	spin_unlock_irqrestore(&wakeupgen_lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifdef CONFIG_CPU_PM 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline void omap4_irq_save_context(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u32 i, val; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (omap_rev() == OMAP4430_REV_ES1_0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (i = 0; i < irq_banks; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		/* Save the CPUx interrupt mask for IRQ 0 to 127 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		val = wakeupgen_readl(i, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		sar_writel(val, WAKEUPGENENB_OFFSET_CPU0, i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		val = wakeupgen_readl(i, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		sar_writel(val, WAKEUPGENENB_OFFSET_CPU1, i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * Disable the secure interrupts for CPUx. The restore 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * code blindly restores secure and non-secure interrupt 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * masks from SAR RAM. Secure interrupts are not suppose 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * to be enabled from HLOS. So overwrite the SAR location 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * so that the secure interrupt remains disabled. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		sar_writel(0x0, WAKEUPGENENB_SECURE_OFFSET_CPU0, i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		sar_writel(0x0, WAKEUPGENENB_SECURE_OFFSET_CPU1, i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* Save AuxBoot* registers */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	__raw_writel(val, sar_base + AUXCOREBOOT0_OFFSET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	__raw_writel(val, sar_base + AUXCOREBOOT1_OFFSET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* Save SyncReq generation logic */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	val = __raw_readl(wakeupgen_base + OMAP_PTMSYNCREQ_MASK); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	__raw_writel(val, sar_base + PTMSYNCREQ_MASK_OFFSET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	val = __raw_readl(wakeupgen_base + OMAP_PTMSYNCREQ_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	__raw_writel(val, sar_base + PTMSYNCREQ_EN_OFFSET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* Set the Backup Bit Mask status */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	val = __raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	val |= SAR_BACKUP_STATUS_WAKEUPGEN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	__raw_writel(val, sar_base + SAR_BACKUP_STATUS_OFFSET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline void omap5_irq_save_context(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u32 i, val; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (i = 0; i < irq_banks; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		/* Save the CPUx interrupt mask for IRQ 0 to 159 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		val = wakeupgen_readl(i, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		sar_writel(val, OMAP5_WAKEUPGENENB_OFFSET_CPU0, i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		val = wakeupgen_readl(i, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		sar_writel(val, OMAP5_WAKEUPGENENB_OFFSET_CPU1, i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		sar_writel(0x0, OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU0, i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		sar_writel(0x0, OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU1, i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* Save AuxBoot* registers */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	__raw_writel(val, sar_base + OMAP5_AUXCOREBOOT0_OFFSET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	__raw_writel(val, sar_base + OMAP5_AUXCOREBOOT1_OFFSET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* Set the Backup Bit Mask status */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	val = __raw_readl(sar_base + OMAP5_SAR_BACKUP_STATUS_OFFSET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	val |= SAR_BACKUP_STATUS_WAKEUPGEN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	__raw_writel(val, sar_base + OMAP5_SAR_BACKUP_STATUS_OFFSET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Save WakeupGen interrupt context in SAR BANK3. Restore is done by 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * ROM code. WakeupGen IP is integrated along with GIC to manage the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * interrupt wakeups from CPU low power states. It manages 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * masking/unmasking of Shared peripheral interrupts(SPI). So the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * interrupt enable/disable control should be in sync and consistent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * at WakeupGen and GIC so that interrupts are not lost. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void irq_save_context(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!sar_base) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		sar_base = omap4_get_sar_ram_base(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (soc_is_omap54xx()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		omap5_irq_save_context(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		omap4_irq_save_context(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Clear WakeupGen SAR backup status. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void irq_sar_clear(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u32 val; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u32 offset = SAR_BACKUP_STATUS_OFFSET; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (soc_is_omap54xx()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		offset = OMAP5_SAR_BACKUP_STATUS_OFFSET; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	val = __raw_readl(sar_base + offset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	val &= ~SAR_BACKUP_STATUS_WAKEUPGEN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	__raw_writel(val, sar_base + offset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Save GIC and Wakeupgen interrupt context using secure API 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * for HS/EMU devices. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void irq_save_secure_context(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u32 ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	ret = omap_secure_dispatcher(OMAP4_HAL_SAVEGIC_INDEX, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				FLAG_START_CRITICAL, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				0, 0, 0, 0, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (ret != API_HAL_RET_VALUE_OK) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		pr_err("GIC and Wakeupgen context save failed\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifdef CONFIG_HOTPLUG_CPU 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static int __cpuinit irq_cpu_hotplug_notify(struct notifier_block *self, 
			 |