4 * This an attempt to get Power Management going for the IBM 4xx processor.
5 * This was derived from the ppc4xx._setup.c file
7 * Armin Kuster akuster@mvista.com
11 * Copyright 2002 MontaVista Softare Inc.
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
21 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * You should have received a copy of the GNU General Public License along
30 * with this program; if not, write to the Free Software Foundation, Inc.,
31 * 675 Mass Ave, Cambridge, MA 02139, USA.
33 * Version 1.0 (02/14/01) - A. Kuster
34 * Initial version - moved pm code from ppc4xx_setup.c
36 * 1.1 02/21/01 - A. Kuster
37 * minor fixes, init value to 0 & += to &=
38 * added stb03 ifdef for 2nd i2c device
40 * 1.2 02/23/01 - A. Kuster
41 * Added 4xx version of apm support
43 * 1.3 05/25/02 - Armin
44 * name change *_driver *_dev
46 * 1.4 06/18/02 - Armin
49 * 1.5 07/24/02 - Armin
50 * fixed ppc4xx_pm_init so it inits now
51 * and am using a default Power Managment bitmap
54 #include <linux/config.h>
55 #include <linux/init.h>
56 #include <linux/kernel.h>
57 #include <linux/list.h>
58 #include <linux/module.h>
60 #include <asm/ibm4xx.h>
61 #include <platforms/ibm_ocp.h>
62 #include <asm/system.h>
67 #define DBG(x...) printk(x)
72 LIST_HEAD(ocp_devices);
76 * OCP Power management..
78 * This needs to be done centralized, so that we power manage PCI
79 * devices in the right order: we should not shut down PCI bridges
80 * before we've shut down the devices behind them, and we should
81 * not wake up devices before we've woken up the bridge to the
84 * We do not touch devices that don't have a driver that exports
85 * a suspend/resume function. That is just too dangerous. If the default
86 * PCI suspend/resume functions work for a device, the driver can
87 * easily implement them (ie just have a suspend function that calls
88 * the pci_set_power_state() function).
91 static int ocp_pm_save_state_device(struct ocp_dev *dev, u32 state)
95 struct ocp_dev *driver = dev->driver;
96 if (driver && driver->save_state)
97 error = driver->save_state(dev,state);
102 static int ocp_pm_suspend_device(struct ocp_dev *dev, u32 state)
106 struct ocp_dev *driver = dev->driver;
107 if (driver && driver->suspend)
108 error = driver->suspend(dev,state);
113 static int ocp_pm_resume_device(struct ocp_dev *dev)
117 struct ocp_dev *driver = dev->driver;
118 if (driver && driver->resume)
119 error = driver->resume(dev);
125 ocp_pm_callback(struct pm_dev *pm_device, pm_request_t rqst, void *data)
131 error = ocp_pm_save_state_device((u32)data);
134 error = ocp_pm_suspend_device((u32)data);
137 error = ocp_pm_resume_device((u32)data);
144 * ocp_register_driver - register a new ocp driver
145 * @drv: the driver structure to register
147 * Adds the driver structure to the list of registered drivers
148 * Returns the number of ocp devices which were claimed by the driver
149 * during registration. The driver remains registered even if the
150 * return value is zero.
153 ocp_register_driver(struct ocp_dev *drv)
157 list_add_tail(&drv->node, &ocp_devs);
161 EXPORT_SYMBOL(ocp_register_driver);
164 /* When bits are "1" then the given clock is
165 * stopped therefore saving power
167 * The objected is to turn off all unneccessary
168 * clocks and have the drivers enable/disable
169 * them when in use. We set the default
170 * in the <core>.h file
177 mtdcr(DCRN_CPMFR, 0);
179 /* turn off unused hardware to save power */
181 printk(KERN_INFO "OCP 4xx power management enabled\n");
182 mtdcr(DCRN_CPMFR, DFLT_IBM4xx_PM);
185 pm_gpio = pm_register(PM_SYS_DEV, 0, ocp_pm_callback);
188 __initcall(ppc4xx_pm_init);
190 /* Force/unforce power down for CPM Class 1 devices */
193 ppc4xx_cpm_fr(u32 bits, int val)
201 mtdcr(DCRN_CPMFR, mfdcr(DCRN_CPMFR) | bits);
203 mtdcr(DCRN_CPMFR, mfdcr(DCRN_CPMFR) & ~bits);
205 restore_flags(flags);