/* * Continue initialise the wakeupgen initialization after sar * is initialized */ void __init omap_wakeupgen_init_finish(void) { int i; unsigned int max_spi_reg; /* * Find out how many interrupts are supported. * OMAP4 supports max of 128 SPIs where as GIC can support * up to 1020 interrupt sources. On OMAP4, maximum SPIs are * fused in DIST_CTR bit-fields as 128. Hence the code is safe * from reserved register writes since its well within 1020. */ max_spi_reg = gic_readl(GIC_DIST_CTR, 0) & 0x1f; /* * Set CPU0 GIC backup flag permanently for omap4460/70 GP, * this is needed because of the ROM code bug that breaks * GIC during wakeup from device off. This errata fix also * clears the GIC save area during init to prevent restoring * garbage to the GIC. */ if ((cpu_is_omap446x() || cpu_is_omap447x()) && omap_type() == OMAP2_DEVICE_TYPE_GP) pm44xx_errata |= PM_OMAP4_ROM_CPU1_BACKUP_ERRATUM_xxx; if (cpu_is_omap44xx() && (omap_type() == OMAP2_DEVICE_TYPE_GP)) { sar_base = omap4_get_sar_ram_base(); if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_CPU1_BACKUP_ERRATUM_xxx)) for (i = SAR_BACKUP_STATUS_OFFSET; i < WAKEUPGENENB_OFFSET_CPU0; i += 4) sar_writel(0, i, 0); sar_writel(GIC_ISR_NON_SECURE, SAR_ICDISR_CPU0_OFFSET, 0); sar_writel(GIC_ISR_NON_SECURE, SAR_ICDISR_CPU1_OFFSET, 0); for (i = 0; i < max_spi_reg; i++) sar_writel(GIC_ISR_NON_SECURE, SAR_ICDISR_SPI_OFFSET, i); if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_CPU1_BACKUP_ERRATUM_xxx)) __raw_writel(SAR_BACKUP_STATUS_GIC_CPU0, sar_base + SAR_BACKUP_STATUS_OFFSET); } else { l3_main_3_oh = omap_hwmod_lookup("l3_main_3"); if (!l3_main_3_oh) pr_err("%s: failed to get l3_main_3_oh\n", __func__); } }
/* * Initialise the wakeupgen module. */ int __init omap_wakeupgen_init(void) { int i; unsigned int boot_cpu = smp_processor_id(); unsigned int max_spi_reg; /* Not supported on OMAP4 ES1.0 silicon */ if (omap_rev() == OMAP4430_REV_ES1_0) { WARN(1, "WakeupGen: Not supported on OMAP4430 ES1.0\n"); return -EPERM; } /* Static mapping, never released */ wakeupgen_base = ioremap(OMAP_WKUPGEN_BASE, SZ_4K); if (WARN_ON(!wakeupgen_base)) return -ENOMEM; if (cpu_is_omap44xx()) { irq_banks = OMAP4_NR_BANKS; max_irqs = OMAP4_NR_IRQS; secure_api_index = OMAP4_HAL_SAVEGIC_INDEX; secure_hw_api_index = OMAP4_HAL_SAVEHW_INDEX; secure_hal_save_all_api_index = OMAP4_HAL_SAVEALL_INDEX; secure_ram_api_index = OMAP4_HAL_SAVESECURERAM_INDEX; } else if (cpu_is_omap54xx()) { secure_api_index = OMAP5_HAL_SAVEGIC_INDEX; secure_hw_api_index = OMAP5_HAL_SAVEHW_INDEX; secure_hal_save_all_api_index = OMAP5_HAL_SAVEALL_INDEX; secure_ram_api_index = OMAP5_HAL_SAVESECURERAM_INDEX; } /* Clear all IRQ bitmasks at wakeupGen level */ for (i = 0; i < irq_banks; i++) { wakeupgen_writel(0, i, CPU0_ID); wakeupgen_writel(0, i, CPU1_ID); } /* * Override GIC architecture specific functions to add * OMAP WakeupGen interrupt controller along with GIC */ gic_arch_extn.irq_mask = wakeupgen_mask; gic_arch_extn.irq_unmask = wakeupgen_unmask; gic_arch_extn.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE; /* * FIXME: Add support to set_smp_affinity() once the core * GIC code has necessary hooks in place. */ /* Associate all the IRQs to boot CPU like GIC init does. */ for (i = 0; i < max_irqs; i++) irq_target_cpu[i] = boot_cpu; /* * Find out how many interrupts are supported. * OMAP4 supports max of 128 SPIs where as GIC can support * up to 1020 interrupt sources. On OMAP4, maximum SPIs are * fused in DIST_CTR bit-fields as 128. Hence the code is safe * from reserved register writes since its well within 1020. */ max_spi_reg = gic_readl(GIC_DIST_CTR, 0) & 0x1f; spi_irq_banks = min(max_spi_reg, irq_banks); irq_hotplug_init(); irq_pm_init(); return 0; }
/** * omap_wakeupgen_check_interrupts() - sanity check for pending interrupts * @report_string: what is used to report * * Return false if there are no pending interrupts, else, if there * are pending interrupts, return true. * * NOTE: if report_string is not NULL, then logic will search beyond * the first occurance and report all such pending events. if report_string * is NULL, search returns true at the very first occurance of event. */ bool omap_wakeupgen_check_interrupts(char *report_string) { int i, k; u32 gica, wakea_c0, wakea_c1; int ret = false; for (i = 0; i < spi_irq_banks - 1; i++) { gica = gic_readl(GIC_DIST_PENDING_SET, i + 1); /* * HACK: On OMAP4 GP devices 8th (secure) interrupt * is constantly pending and thus preventing suspend. * The source of this interrupt is CONTROL_CORE_SEC_STATUS * register. This register can't be cleared on GP device * because it is accessible for write only from secure * privileged mode. So just ignore 8th interrupt in this check. */ if (i == 0 && cpu_is_omap44xx() && (omap_type() == OMAP2_DEVICE_TYPE_GP)) gica &= ~(1 << 8); wakea_c0 = wakeupgen_readl(i, 0); wakea_c1 = wakeupgen_readl(i, 1); /* If there is nothing pending, nothing to report */ if (!gica) continue; /* report register dump for debug */ pr_debug("%s: %s: IRQ Bank = %d GIC Pending status=0x%08x " "GIC Enable = 0x%08x Wakeupgen Config =" "cpu0=0x%08x cpu1=0x%08x\n", __func__, report_string, i, gica, gic_readl(GIC_DIST_ENABLE_SET, i + 1), wakea_c0, wakea_c1); k = 0; while (gica) { if (gica & 0x1) { struct irq_desc *desc; const char *name, *wc0, *wc1; int irq; /* Return true if pending interrupts */ ret = true; /* * we need to search for more ONLY if * there is something to report */ if (!report_string) goto quit_search; /* Grab the current wakeup state for CPU0,1 */ wc0 = (wakea_c0 & 0x1) ? "yes" : "no"; wc1 = (wakea_c1 & 0x1) ? "yes" : "no"; /* Since we skip GIC PPI and SGI, base 32 */ irq = 32 + i * 32 + k; desc = irq_to_desc(irq); if (desc && desc->action && desc->action->name) { name = desc->action->name; } else if (irq == OMAP44XX_IRQ_PRCM) { name = NULL; print_prcm_wakeirq(irq, report_string); } else { name = "unknown"; } if (name) pr_info("%s: IRQ %d(%s)(OMAP-IRQ=%d) "\ "Pending! Wakeup Enable: "\ "CPU0=%s,CPU1=%s\n", report_string, irq, name, (irq - 32), wc0, wc1); } k++; gica >>= 1; wakea_c0 >>= 1; wakea_c1 >>= 1; } } quit_search: return ret; }
static void gic_save_context(void) { u8 i; u32 val; offset= 0; /* Save CPU 0 Interrupt Set Enable register */ val = gic_readl(GIC_DIST_ENABLE_SET, 0); gic_context[offset] = val; offset++; /* Save all SPI Set Enable register */ for (i = 0; i < max_spi_reg; i++) { val = gic_readl(GIC_DIST_ENABLE_SET + SPI_ENABLE_SET_OFFSET, i); gic_context[offset] = val; offset++; } /* Save SGI priority registers (Software Generated Interrupt) */ for (i = 0; i < 4; i++) { val = gic_readl(GIC_DIST_PRI, i); /* Save the priority bits of the Interrupts */ gic_context[offset] = val; offset++; } /* Save PPI priority registers (Private Peripheral Intterupts) */ for (i = 0; i < 4; i++) { val = gic_readl(GIC_DIST_PRI + PPI_PRI_OFFSET, i); /* Save the priority bits of the Interrupts */ gic_context[offset] = val; offset++; } /* SPI priority registers - 4 interrupts/register */ for (i = 0; i < (max_spi_irq / 4); i++) { val = gic_readl((GIC_DIST_PRI + SPI_PRI_OFFSET), i); gic_context[offset] = val; offset++; } /* SPI Interrupt Target registers - 4 interrupts/register * ICDIPTR0 ~ ICDIPTR7 are read-only */ for (i = 0; i < (max_spi_irq / 4); i++) { val = gic_readl((GIC_DIST_TARGET + SPI_TARGET_OFFSET), i); gic_context[offset] = val; offset++; } /* SPI Interrupt Congigeration eegisters- 16 interrupts/register */ for (i = 0; i < (max_spi_irq / 16); i++) { val = gic_readl((GIC_DIST_CONFIG + SPI_CONFIG_OFFSET), i); gic_context[offset] = val; offset++; } offset--; #ifdef CONFIG_SPRD_PM_DEBUG printk("****** %s, save %d gic registers \n ", __func__, offset); dump_gic_saved_context(); #endif return; }
/* * Initialise the wakeupgen module. */ int __init omap_wakeupgen_init(void) { int i; unsigned int boot_cpu = smp_processor_id(); unsigned int max_spi_reg; /* Not supported on OMAP4 ES1.0 silicon */ if (omap_rev() == OMAP4430_REV_ES1_0) { WARN(1, "WakeupGen: Not supported on OMAP4430 ES1.0\n"); return -EPERM; } /* Static mapping, never released */ wakeupgen_base = ioremap(OMAP_WKUPGEN_BASE, SZ_4K); if (WARN_ON(!wakeupgen_base)) return -ENOMEM; if (cpu_is_omap44xx()) { irq_banks = OMAP4_NR_BANKS; max_irqs = OMAP4_NR_IRQS; secure_api_index = OMAP4_HAL_SAVEGIC_INDEX; secure_hw_api_index = OMAP4_HAL_SAVEHW_INDEX; secure_hal_save_all_api_index = OMAP4_HAL_SAVEALL_INDEX; secure_ram_api_index = OMAP4_HAL_SAVESECURERAM_INDEX; } else if (cpu_is_omap54xx()) { secure_api_index = OMAP5_HAL_SAVEGIC_INDEX; secure_hw_api_index = OMAP5_HAL_SAVEHW_INDEX; secure_hal_save_all_api_index = OMAP5_HAL_SAVEALL_INDEX; secure_ram_api_index = OMAP5_HAL_SAVESECURERAM_INDEX; } /* Clear all IRQ bitmasks at wakeupGen level */ for (i = 0; i < irq_banks; i++) { wakeupgen_writel(0, i, CPU0_ID); wakeupgen_writel(0, i, CPU1_ID); } /* * Override GIC architecture specific functions to add * OMAP WakeupGen interrupt controller along with GIC */ gic_arch_extn.irq_mask = wakeupgen_mask; gic_arch_extn.irq_unmask = wakeupgen_unmask; gic_arch_extn.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE; /* * FIXME: Add support to set_smp_affinity() once the core * GIC code has necessary hooks in place. */ /* Associate all the IRQs to boot CPU like GIC init does. */ for (i = 0; i < max_irqs; i++) irq_target_cpu[i] = boot_cpu; /* * Find out how many interrupts are supported. * OMAP4 supports max of 128 SPIs where as GIC can support * up to 1020 interrupt sources. On OMAP4, maximum SPIs are * fused in DIST_CTR bit-fields as 128. Hence the code is safe * from reserved register writes since its well within 1020. */ max_spi_reg = gic_readl(GIC_DIST_CTR, 0) & 0x1f; spi_irq_banks = min(max_spi_reg, irq_banks); /* * Set CPU0 GIC backup flag permanently for omap4460 GP, * this is needed because of the ROM code bug that breaks * GIC during wakeup from device off. This errata fix also * clears the GIC save area during init to prevent restoring * garbage to the GIC. */ if (cpu_is_omap446x() && omap_type() == OMAP2_DEVICE_TYPE_GP) pm44xx_errata |= PM_OMAP4_ROM_CPU1_BACKUP_ERRATUM_xxx; if (cpu_is_omap44xx() && (omap_type() == OMAP2_DEVICE_TYPE_GP)) { sar_base = omap4_get_sar_ram_base(); if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_CPU1_BACKUP_ERRATUM_xxx)) for (i = SAR_BACKUP_STATUS_OFFSET; i < WAKEUPGENENB_OFFSET_CPU0; i += 4) sar_writel(0, i, 0); sar_writel(GIC_ISR_NON_SECURE, SAR_ICDISR_CPU0_OFFSET, 0); sar_writel(GIC_ISR_NON_SECURE, SAR_ICDISR_CPU1_OFFSET, 0); for (i = 0; i < max_spi_reg; i++) sar_writel(GIC_ISR_NON_SECURE, SAR_ICDISR_SPI_OFFSET, i); if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_CPU1_BACKUP_ERRATUM_xxx)) __raw_writel(SAR_BACKUP_STATUS_GIC_CPU0, sar_base + SAR_BACKUP_STATUS_OFFSET); } else { l3_main_3_oh = omap_hwmod_lookup("l3_main_3"); if (!l3_main_3_oh) pr_err("%s: failed to get l3_main_3_oh\n", __func__); } irq_hotplug_init(); irq_pm_init(); return 0; }
/** * omap_wakeupgen_check_interrupts() - sanity check for pending interrupts * @report_string: what is used to report * * Return false if there are no pending interrupts, else, if there * are pending interrupts, return true. * * NOTE: if report_string is not NULL, then logic will search beyond * the first occurance and report all such pending events. if report_string * is NULL, search returns true at the very first occurance of event. */ bool omap_wakeupgen_check_interrupts(char *report_string) { int i, k; u32 gica, wakea_c0, wakea_c1; int ret = false; for (i = 0; i < spi_irq_banks - 1; i++) { gica = gic_readl(GIC_DIST_PENDING_SET, i + 1); wakea_c0 = wakeupgen_readl(i, 0); wakea_c1 = wakeupgen_readl(i, 1); /* If there is nothing pending, nothing to report */ if (!gica) continue; /* report register dump for debug */ pr_debug("%s: %s: IRQ Bank = %d GIC Pending status=0x%08x " "GIC Enable = 0x%08x Wakeupgen Config =" "cpu0=0x%08x cpu1=0x%08x\n", __func__, report_string, i, gica, gic_readl(GIC_DIST_ENABLE_SET, i + 1), wakea_c0, wakea_c1); k = 0; while (gica) { if (gica & 0x1) { struct irq_desc *desc; const char *name, *wc0, *wc1; int irq; /* Return true if pending interrupts */ ret = true; /* * we need to search for more ONLY if * there is something to report */ if (!report_string) goto quit_search; /* Grab the current wakeup state for CPU0,1 */ wc0 = (wakea_c0 & 0x1) ? "yes" : "no"; wc1 = (wakea_c1 & 0x1) ? "yes" : "no"; /* Since we skip GIC PPI and SGI, base 32 */ irq = 32 + i * 32 + k; desc = irq_to_desc(irq); if (desc && desc->action && desc->action->name) { name = desc->action->name; } else if (irq == OMAP44XX_IRQ_PRCM) { name = NULL; print_prcm_wakeirq(irq, report_string); } else { name = "unknown"; } if (name) pr_info("%s: IRQ %d(%s)(OMAP-IRQ=%d) "\ "Pending! Wakeup Enable: "\ "CPU0=%s,CPU1=%s\n", report_string, irq, name, (irq - 32), wc0, wc1); } k++; gica >>= 1; wakea_c0 >>= 1; wakea_c1 >>= 1; } } quit_search: return ret; }