switch (type) { case IRQ_TYPE_LEVEL_LOW:
type &= ~IRQ_TYPE_LEVEL_MASK;
type |= IRQ_TYPE_LEVEL_HIGH;
inverted = true; break; case IRQ_TYPE_EDGE_FALLING:
type &= ~IRQ_TYPE_EDGE_BOTH;
type |= IRQ_TYPE_EDGE_RISING;
inverted = true; break; default: break;
}
if (inverted && d->hwirq != SYS_NIRQ1_EXT_SYS_IRQ_1 &&
d->hwirq != SYS_NIRQ2_EXT_SYS_IRQ_2)
pr_warn("wakeupgen: irq%li polarity inverted in dts\n",
d->hwirq);
#ifdef CONFIG_CPU_PM staticinlinevoid 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);
/* Save AuxBoot* registers */
val = readl_relaxed(wakeupgen_base + OMAP_AUX_CORE_BOOT_0);
writel_relaxed(val, sar_base + AUXCOREBOOT0_OFFSET);
val = readl_relaxed(wakeupgen_base + OMAP_AUX_CORE_BOOT_1);
writel_relaxed(val, sar_base + AUXCOREBOOT1_OFFSET);
/* Save SyncReq generation logic */
val = readl_relaxed(wakeupgen_base + OMAP_PTMSYNCREQ_MASK);
writel_relaxed(val, sar_base + PTMSYNCREQ_MASK_OFFSET);
val = readl_relaxed(wakeupgen_base + OMAP_PTMSYNCREQ_EN);
writel_relaxed(val, sar_base + PTMSYNCREQ_EN_OFFSET);
/* Set the Backup Bit Mask status */
val = readl_relaxed(sar_base + SAR_BACKUP_STATUS_OFFSET);
val |= SAR_BACKUP_STATUS_WAKEUPGEN;
writel_relaxed(val, sar_base + SAR_BACKUP_STATUS_OFFSET);
}
staticinlinevoid 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 = readl_relaxed(wakeupgen_base + OMAP_AUX_CORE_BOOT_0);
writel_relaxed(val, sar_base + OMAP5_AUXCOREBOOT0_OFFSET);
val = readl_relaxed(wakeupgen_base + OMAP_AUX_CORE_BOOT_0);
writel_relaxed(val, sar_base + OMAP5_AUXCOREBOOT1_OFFSET);
/* Set the Backup Bit Mask status */
val = readl_relaxed(sar_base + OMAP5_SAR_BACKUP_STATUS_OFFSET);
val |= SAR_BACKUP_STATUS_WAKEUPGEN;
writel_relaxed(val, sar_base + OMAP5_SAR_BACKUP_STATUS_OFFSET);
for (i = 0; i < irq_banks; i++) {
wakeupgen_context[i] = wakeupgen_readl(i, 0);
wakeupgen_writel(0, i, CPU0_ID);
}
}
/* *SaveWakeupGeninterruptcontextinSARBANK3.Restoreisdoneby *ROMcode.WakeupGenIPisintegratedalongwithGICtomanagethe *interruptwakeupsfromCPUlowpowerstates.Itmanages *masking/unmaskingofSharedperipheralinterrupts(SPI).Sothe *interruptenable/disablecontrolshouldbeinsyncandconsistent *atWakeupGenandGICsothatinterruptsarenotlost.
*/ staticvoid irq_save_context(void)
{ /* DRA7 has no SAR to save */ if (soc_is_dra7xx()) return;
if (wakeupgen_ops && wakeupgen_ops->save_context)
wakeupgen_ops->save_context();
}
/* *ClearWakeupGenSARbackupstatus.
*/ staticvoid irq_sar_clear(void)
{
u32 val;
u32 offset = SAR_BACKUP_STATUS_OFFSET; /* DRA7 has no SAR to save */ if (soc_is_dra7xx()) return;
if (soc_is_omap54xx())
offset = OMAP5_SAR_BACKUP_STATUS_OFFSET;
val = readl_relaxed(sar_base + offset);
val &= ~SAR_BACKUP_STATUS_WAKEUPGEN;
writel_relaxed(val, sar_base + offset);
}
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");
}
/* Define ops for context save and restore for each SoC */ staticstruct omap_wakeupgen_ops omap4_wakeupgen_ops = {
.save_context = omap4_irq_save_context,
.restore_context = irq_sar_clear,
};
staticvoid __init irq_pm_init(void)
{ /* FIXME: Remove this when MPU OSWR support is added */ if (!IS_PM44XX_ERRATUM(PM_OMAP4_CPU_OSWR_DISABLE))
cpu_pm_register_notifier(&irq_notifier_block);
} #else staticvoid __init irq_pm_init(void)
{} #endif
if (fwspec->param_count != 3) return -EINVAL; /* Not GIC compliant */ if (fwspec->param[0] != 0) return -EINVAL; /* No PPI should point to this domain */
hwirq = fwspec->param[1]; if (hwirq >= MAX_IRQS) return -EINVAL; /* Can't deal with this */
for (i = 0; i < nr_irqs; i++)
irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
&wakeupgen_chip, NULL);
/* Clear all IRQ bitmasks at wakeupGen level */ for (i = 0; i < irq_banks; i++) {
wakeupgen_writel(0, i, CPU0_ID); if (!soc_is_am43xx())
wakeupgen_writel(0, i, CPU1_ID);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.