diff options
Diffstat (limited to 'arch/arm/mach-ux500/pm.c')
| -rw-r--r-- | arch/arm/mach-ux500/pm.c | 52 |
1 files changed, 43 insertions, 9 deletions
diff --git a/arch/arm/mach-ux500/pm.c b/arch/arm/mach-ux500/pm.c index 1a468f0fd22e..dc962d006b08 100644 --- a/arch/arm/mach-ux500/pm.c +++ b/arch/arm/mach-ux500/pm.c @@ -1,19 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) ST-Ericsson SA 2010-2013 * Author: Rickard Andersson <rickard.andersson@stericsson.com> for * ST-Ericsson. * Author: Daniel Lezcano <daniel.lezcano@linaro.org> for Linaro. - * License terms: GNU General Public License (GPL) version 2 - * + * Author: Ulf Hansson <ulf.hansson@linaro.org> for Linaro. */ #include <linux/kernel.h> #include <linux/irqchip/arm-gic.h> #include <linux/delay.h> #include <linux/io.h> +#include <linux/suspend.h> #include <linux/platform_data/arm-ux500-pm.h> - -#include "db8500-regs.h" +#include <linux/of.h> +#include <linux/of_address.h> /* ARM WFI Standby signal register */ #define PRCM_ARM_WFI_STANDBY (prcmu_base + 0x130) @@ -38,6 +39,7 @@ #define PRCM_ARMITVAL127TO96 (prcmu_base + 0x26C) static void __iomem *prcmu_base; +static void __iomem *dist_base; /* This function decouple the gic from the prcmu */ int prcmu_gic_decouple(void) @@ -84,7 +86,6 @@ bool prcmu_gic_pending_irq(void) { u32 pr; /* Pending register */ u32 er; /* Enable register */ - void __iomem *dist_base = __io_address(U8500_GIC_DIST_BASE); int i; /* 5 registers. STI & PPI not skipped */ @@ -121,15 +122,15 @@ bool prcmu_pending_irq(void) } /* - * This function checks if the specified cpu is in in WFI. It's usage + * This function checks if the specified cpu is in WFI. It's usage * makes sense only if the gic is decoupled with the db8500_prcmu_gic_decouple * function. Of course passing smp_processor_id() to this function will * always return false... */ bool prcmu_is_cpu_in_wfi(int cpu) { - return readl(PRCM_ARM_WFI_STANDBY) & cpu ? PRCM_ARM_WFI_STANDBY_WFI1 : - PRCM_ARM_WFI_STANDBY_WFI0; + return readl(PRCM_ARM_WFI_STANDBY) & + (cpu ? PRCM_ARM_WFI_STANDBY_WFI1 : PRCM_ARM_WFI_STANDBY_WFI0); } /* @@ -139,7 +140,6 @@ bool prcmu_is_cpu_in_wfi(int cpu) int prcmu_copy_gic_settings(void) { u32 er; /* Enable register */ - void __iomem *dist_base = __io_address(U8500_GIC_DIST_BASE); int i; /* We skip the STI and PPI */ @@ -152,16 +152,50 @@ int prcmu_copy_gic_settings(void) return 0; } +#ifdef CONFIG_SUSPEND +static int ux500_suspend_enter(suspend_state_t state) +{ + cpu_do_idle(); + return 0; +} + +static int ux500_suspend_valid(suspend_state_t state) +{ + return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY; +} + +static const struct platform_suspend_ops ux500_suspend_ops = { + .enter = ux500_suspend_enter, + .valid = ux500_suspend_valid, +}; +#define UX500_SUSPEND_OPS (&ux500_suspend_ops) +#else +#define UX500_SUSPEND_OPS NULL +#endif + void __init ux500_pm_init(u32 phy_base, u32 size) { + struct device_node *np; + prcmu_base = ioremap(phy_base, size); if (!prcmu_base) { pr_err("could not remap PRCMU for PM functions\n"); return; } + np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-gic"); + dist_base = of_iomap(np, 0); + of_node_put(np); + if (!dist_base) { + pr_err("could not remap GIC dist base for PM functions\n"); + return; + } + /* * On watchdog reboot the GIC is in some cases decoupled. * This will make sure that the GIC is correctly configured. */ prcmu_gic_recouple(); + + /* Set up ux500 suspend callbacks. */ + suspend_set_ops(UX500_SUSPEND_OPS); } |
