12dcf78c0SUwe Kleine-König /* 22dcf78c0SUwe Kleine-König * i.MX27 Power Management Routines 32dcf78c0SUwe Kleine-König * 42dcf78c0SUwe Kleine-König * Based on Freescale's BSP 52dcf78c0SUwe Kleine-König * 62dcf78c0SUwe Kleine-König * This program is free software; you can redistribute it and/or 72dcf78c0SUwe Kleine-König * modify it under the terms of the GNU General Public License. 82dcf78c0SUwe Kleine-König */ 92dcf78c0SUwe Kleine-König 10d54debc7SFabio Estevam #include <linux/of_address.h> 112dcf78c0SUwe Kleine-König #include <linux/kernel.h> 122dcf78c0SUwe Kleine-König #include <linux/suspend.h> 132dcf78c0SUwe Kleine-König #include <linux/io.h> 1450f2de61SShawn Guo 15*779b56bbSFabio Estevam #include "common.h" 1650f2de61SShawn Guo #include "hardware.h" 172dcf78c0SUwe Kleine-König mx27_suspend_enter(suspend_state_t state)182dcf78c0SUwe Kleine-Königstatic int mx27_suspend_enter(suspend_state_t state) 192dcf78c0SUwe Kleine-König { 20d54debc7SFabio Estevam void __iomem *ccm_base; 21d54debc7SFabio Estevam struct device_node *np; 222dcf78c0SUwe Kleine-König u32 cscr; 23d54debc7SFabio Estevam 24d54debc7SFabio Estevam np = of_find_compatible_node(NULL, NULL, "fsl,imx27-ccm"); 25d54debc7SFabio Estevam ccm_base = of_iomap(np, 0); 26d54debc7SFabio Estevam BUG_ON(!ccm_base); 27d54debc7SFabio Estevam 282dcf78c0SUwe Kleine-König switch (state) { 292dcf78c0SUwe Kleine-König case PM_SUSPEND_MEM: 302dcf78c0SUwe Kleine-König /* Clear MPEN and SPEN to disable MPLL/SPLL */ 31d54debc7SFabio Estevam cscr = imx_readl(ccm_base); 322dcf78c0SUwe Kleine-König cscr &= 0xFFFFFFFC; 33d54debc7SFabio Estevam imx_writel(cscr, ccm_base); 342dcf78c0SUwe Kleine-König /* Executes WFI */ 354a3ea244SNicolas Pitre cpu_do_idle(); 362dcf78c0SUwe Kleine-König break; 372dcf78c0SUwe Kleine-König 382dcf78c0SUwe Kleine-König default: 392dcf78c0SUwe Kleine-König return -EINVAL; 402dcf78c0SUwe Kleine-König } 412dcf78c0SUwe Kleine-König return 0; 422dcf78c0SUwe Kleine-König } 432dcf78c0SUwe Kleine-König 442f55ac07SLionel Debroux static const struct platform_suspend_ops mx27_suspend_ops = { 452dcf78c0SUwe Kleine-König .enter = mx27_suspend_enter, 462dcf78c0SUwe Kleine-König .valid = suspend_valid_only_mem, 472dcf78c0SUwe Kleine-König }; 482dcf78c0SUwe Kleine-König imx27_pm_init(void)4948e076daSArnd Bergmannvoid __init imx27_pm_init(void) 502dcf78c0SUwe Kleine-König { 512dcf78c0SUwe Kleine-König suspend_set_ops(&mx27_suspend_ops); 522dcf78c0SUwe Kleine-König } 53