xref: /titanic_53/usr/src/uts/common/sys/epm.h (revision 2df1fe9ca32bb227b9158c67f5c00b54c20b10fd)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5c42872d4Smh27603  * Common Development and Distribution License (the "License").
6c42872d4Smh27603  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22c50cf65dSkchow  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #ifndef	_SYS_EPM_H
277c478bd9Sstevel@tonic-gate #define	_SYS_EPM_H
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate #include <sys/pm.h>
327c478bd9Sstevel@tonic-gate #include <sys/dditypes.h>
337c478bd9Sstevel@tonic-gate #include <sys/devops.h>
347c478bd9Sstevel@tonic-gate #include <sys/ddi_impldefs.h>
357c478bd9Sstevel@tonic-gate #include <sys/taskq.h>
367c478bd9Sstevel@tonic-gate 
37*2df1fe9cSrandyf /*
38*2df1fe9cSrandyf  * XXXX
39*2df1fe9cSrandyf  * Do we really need this include?  It may be leftover from early CPUPM code.
40*2df1fe9cSrandyf  * #include <sys/processor.h>
41*2df1fe9cSrandyf  */
42*2df1fe9cSrandyf 
437c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
447c478bd9Sstevel@tonic-gate extern "C" {
457c478bd9Sstevel@tonic-gate #endif
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate #ifdef	_KERNEL
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate /*
507c478bd9Sstevel@tonic-gate  * epm.h:	Function prototypes and data structs for kernel pm functions.
517c478bd9Sstevel@tonic-gate  */
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate void e_pm_props(dev_info_t *);
547c478bd9Sstevel@tonic-gate int e_new_pm_props(dev_info_t *);
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate #define	PM_LEVEL_UPONLY (-2)	/* only raise power level */
577c478bd9Sstevel@tonic-gate #define	PM_LEVEL_DOWNONLY (-3)	/* only lower power level */
587c478bd9Sstevel@tonic-gate #define	PM_LEVEL_EXACT (-4)	/* wants exact power level */
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate /*
617c478bd9Sstevel@tonic-gate  * Values used by e_pm_props and friends, found in devi_pm_flags
627c478bd9Sstevel@tonic-gate  */
637c478bd9Sstevel@tonic-gate #define	PMC_NEEDS_SR		0x00001	/* do suspend/resume despite no "reg" */
647c478bd9Sstevel@tonic-gate #define	PMC_NO_SR		0x00002	/* don't suspend/resume despite "reg" */
657c478bd9Sstevel@tonic-gate #define	PMC_PARENTAL_SR		0x00004	/* call up tree to suspend/resume */
667c478bd9Sstevel@tonic-gate #define	PMC_WANTS_NOTIFY	0x00008	/* notify if child pwr level changes */
677c478bd9Sstevel@tonic-gate #define	PMC_BC			0x00010	/* no pm-components, backwards compat */
687c478bd9Sstevel@tonic-gate #define	PMC_COMPONENTS_DONE	0x00020 /* parsed pm-components */
697c478bd9Sstevel@tonic-gate #define	PMC_COMPONENTS_FAILED	0x00040 /* failed parsing pm-components */
707c478bd9Sstevel@tonic-gate #define	PMC_SUSPENDED		0x00080 /* device has been suspended */
717c478bd9Sstevel@tonic-gate #define	PMC_DEF_THRESH		0x00100 /* thresholds are default */
727c478bd9Sstevel@tonic-gate #define	PMC_DEV_THRESH		0x00200 /* SET_THRESHOLD ioctl seen */
737c478bd9Sstevel@tonic-gate #define	PMC_COMP_THRESH		0x00400 /* relative threshold set */
747c478bd9Sstevel@tonic-gate #define	PMC_NEXDEF_THRESH	0x00800 /* relative threshold set for nexus */
757c478bd9Sstevel@tonic-gate #define	PMC_NOPMKID		0x01000 /* non-pm'd child of pm'd parent */
767c478bd9Sstevel@tonic-gate #define	PMC_NO_INVOL		0x02000 /* no pm without driver's consent */
777c478bd9Sstevel@tonic-gate #define	PMC_VOLPMD		0x04000 /* went down voluntarily */
787c478bd9Sstevel@tonic-gate #define	PMC_SKIP_BRINGUP	0x08000 /* Skipped a dependency bringup */
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate /*
817c478bd9Sstevel@tonic-gate  * A node which is the console frame buffer, and should not be powered down
827c478bd9Sstevel@tonic-gate  * automatically because the OBP driver doesn't know how to power it back up
837c478bd9Sstevel@tonic-gate  * before using it  (can remove this when prom calls back into kernel to do
847c478bd9Sstevel@tonic-gate  * io to console).
857c478bd9Sstevel@tonic-gate  */
867c478bd9Sstevel@tonic-gate #define	PMC_CONSOLE_FB		0x10000	/* console framebuffer */
877c478bd9Sstevel@tonic-gate #define	PMC_NOINVOL_DONE	0x20000 /* processed by pm_noinvol_specd() */
887c478bd9Sstevel@tonic-gate #define	PMC_DRIVER_REMOVED	0x40000 /* driver is removed	*/
89c42872d4Smh27603 #define	PMC_CPU_DEVICE		0x80000 /* device is a power manageable CPU */
90c42872d4Smh27603 #define	PMC_CPU_THRESH		0x100000 /* cpu threshold set */
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate #define	PMC_THRESH_ALL	(PMC_DEF_THRESH | PMC_DEV_THRESH | \
93c42872d4Smh27603     PMC_COMP_THRESH | PMC_NEXDEF_THRESH | PMC_CPU_THRESH)
947c478bd9Sstevel@tonic-gate #define	PMC_THRESH_NONE	~(PMC_THRESH_ALL)
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate /* Flags for the component */
977c478bd9Sstevel@tonic-gate #define	PM_POWER_OP		0x00001	/* set power in process */
987c478bd9Sstevel@tonic-gate #define	PM_PHC_WHILE_SET_POWER	0x00002	/* phc and set power deadlock */
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate /*
1017c478bd9Sstevel@tonic-gate  * One of these is attached to each devinfo that is autopm'd.
1027c478bd9Sstevel@tonic-gate  */
1037c478bd9Sstevel@tonic-gate typedef struct pm_scan {
1047c478bd9Sstevel@tonic-gate 	int		ps_idle_down;	/* PMID_XXX flags */
1057c478bd9Sstevel@tonic-gate 	int		ps_scan_flags;	/* scan flags, defined below */
1067c478bd9Sstevel@tonic-gate 	timeout_id_t	ps_scan_id;	/* per dip scan timeout id */
1077c478bd9Sstevel@tonic-gate } pm_scan_t;
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate /*
1107c478bd9Sstevel@tonic-gate  * ps_scan_flags may take the following values, plus possibly
1117c478bd9Sstevel@tonic-gate  * more defined.
1127c478bd9Sstevel@tonic-gate  */
1137c478bd9Sstevel@tonic-gate #define	PM_SCANNING		0x100	/* scanning: pm_scan_dev is active */
1147c478bd9Sstevel@tonic-gate #define	PM_SCAN_AGAIN		0x200
1157c478bd9Sstevel@tonic-gate #define	PM_SCAN_STOP		0x400
1167c478bd9Sstevel@tonic-gate #define	PM_SCAN_DISPATCHED	0x800
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate #define	PM_MIN_SCAN	((clock_t)15)	/* Minimum scan interval in seconds */
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate /*
1217c478bd9Sstevel@tonic-gate  * Power management component definitions, used for tracking idleness of
1227c478bd9Sstevel@tonic-gate  * devices.  An array of these hangs off the devi_pm_components member of the
1237c478bd9Sstevel@tonic-gate  * dev_info struct (if initialized by driver and/or auto-pm)
1247c478bd9Sstevel@tonic-gate  * The array of these structs is followed in the same kmem_zalloc'd chunk by
1257c478bd9Sstevel@tonic-gate  * the names pointed to by the structs.
1267c478bd9Sstevel@tonic-gate  */
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate /*
1297c478bd9Sstevel@tonic-gate  * This (sub-)struct contains all the info extracted from the pm-components
1307c478bd9Sstevel@tonic-gate  * property for each component (name of component, names and values of power
1317c478bd9Sstevel@tonic-gate  * levels supported).  It is in a separate structure to allow it to be handled
1327c478bd9Sstevel@tonic-gate  * as a struct assignment.
1337c478bd9Sstevel@tonic-gate  */
1347c478bd9Sstevel@tonic-gate typedef struct pm_comp {
1357c478bd9Sstevel@tonic-gate 	char 	*pmc_name;		/* name of component */
1367c478bd9Sstevel@tonic-gate 	int	pmc_numlevels;		/* number of power levels supported */
1377c478bd9Sstevel@tonic-gate 	int	*pmc_lvals;		/* numerical values of levels */
1387c478bd9Sstevel@tonic-gate 	int	*pmc_thresh;		/* thresholds in secs, last INT_MAX */
1397c478bd9Sstevel@tonic-gate 	char	**pmc_lnames;		/* human readable names of levels */
1407c478bd9Sstevel@tonic-gate 	/*
1417c478bd9Sstevel@tonic-gate 	 * This part is just bookkeeping for the storage space involved above
1427c478bd9Sstevel@tonic-gate 	 * used for copying and freeing the struct members.  This because C
1437c478bd9Sstevel@tonic-gate 	 * is really an assembler at heart.
1447c478bd9Sstevel@tonic-gate 	 */
1457c478bd9Sstevel@tonic-gate 	size_t	pmc_name_sz;		/* size of name string		*/
1467c478bd9Sstevel@tonic-gate 	char	*pmc_lname_buf;		/* buffer holding *pmc_lnames	*/
1477c478bd9Sstevel@tonic-gate 	size_t	pmc_lnames_sz;		/* total size of pmc_lname_buf	*/
1487c478bd9Sstevel@tonic-gate } pm_comp_t;
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate /*
1517c478bd9Sstevel@tonic-gate  * Here we have the rest of what we need to know about a component.
1527c478bd9Sstevel@tonic-gate  */
1537c478bd9Sstevel@tonic-gate typedef struct pm_component {
1547c478bd9Sstevel@tonic-gate 	uint_t pmc_flags;		/* flags this component */
1557c478bd9Sstevel@tonic-gate 	uint_t pmc_busycount;		/* for nesting busy calls */
1567c478bd9Sstevel@tonic-gate 	time_t pmc_timestamp;		/* timestamp */
1577c478bd9Sstevel@tonic-gate 	uint_t pmc_norm_pwr;		/* normal power index (or value) */
1587c478bd9Sstevel@tonic-gate 	int pmc_cur_pwr;		/* current power index (or value)  */
1597c478bd9Sstevel@tonic-gate 	int pmc_phc_pwr;		/* prev. value of curpwr (deadlock) */
1607c478bd9Sstevel@tonic-gate 	pm_comp_t pmc_comp;		/* component description */
1617c478bd9Sstevel@tonic-gate } pm_component_t;
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate /*
1647c478bd9Sstevel@tonic-gate  * All members of this struct are protected by PM_LOCK_DIP(dip).
1657c478bd9Sstevel@tonic-gate  *
1667c478bd9Sstevel@tonic-gate  * kidsupcnt counts (the number of components of new-style children at non-zero
1677c478bd9Sstevel@tonic-gate  * level (unknown counts as non-zero)) + (the number of old-style children with
1687c478bd9Sstevel@tonic-gate  * component 0 at non-zero level) for parents that have not asked for
1697c478bd9Sstevel@tonic-gate  * notifcation.  When kidsupcnt is 0 for a nexus node, then pm scans it,
1707c478bd9Sstevel@tonic-gate  * otherwise it leaves it alone.
1717c478bd9Sstevel@tonic-gate  * Parents that ask for notification always get get scanned,
1727c478bd9Sstevel@tonic-gate  * so we keep their kidsupcnt at zero.
1737c478bd9Sstevel@tonic-gate  */
1747c478bd9Sstevel@tonic-gate typedef struct pm_info {
1757c478bd9Sstevel@tonic-gate 	uint_t		pmi_dev_pm_state; /* PM state of a device */
1767c478bd9Sstevel@tonic-gate 	int		pmi_clone;	/* owner for direct pm'd devs */
1777c478bd9Sstevel@tonic-gate 	int		pmi_levels[2];	/* storage space for 2 levels */
1787c478bd9Sstevel@tonic-gate 	int		*pmi_lp;	/* storage space for >2 levels */
1797c478bd9Sstevel@tonic-gate 	kcondvar_t	pmi_cv;		/* condvar for direct PM access */
1807c478bd9Sstevel@tonic-gate } pm_info_t;
1817c478bd9Sstevel@tonic-gate 
1827c478bd9Sstevel@tonic-gate /*
1837c478bd9Sstevel@tonic-gate  * Work request structure for the dependency processing thread.
1847c478bd9Sstevel@tonic-gate  */
1857c478bd9Sstevel@tonic-gate typedef struct pm_dep_wk {
1867c478bd9Sstevel@tonic-gate 	int		pdw_type;		/* Type of request */
1877c478bd9Sstevel@tonic-gate 	int		pdw_wait;		/* caller waits for result */
1887c478bd9Sstevel@tonic-gate 	int		pdw_done;		/* set when req is done */
1897c478bd9Sstevel@tonic-gate 	int		pdw_ret;		/* return value to caller */
1907c478bd9Sstevel@tonic-gate 	int		pdw_pwr;		/* pwr level of keeper */
1917c478bd9Sstevel@tonic-gate 	kcondvar_t	pdw_cv;			/* cv to wake up caller */
1927c478bd9Sstevel@tonic-gate 	struct		pm_dep_wk *pdw_next;	/* next element */
1937c478bd9Sstevel@tonic-gate 	char		*pdw_keeper;
1947c478bd9Sstevel@tonic-gate 	char		*pdw_kept;
1957c478bd9Sstevel@tonic-gate } pm_dep_wk_t;
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate /*
1987c478bd9Sstevel@tonic-gate  * Types of work, depends on when it gets called:
1997c478bd9Sstevel@tonic-gate  */
2007c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_POWER_ON		1	/* power on */
2017c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_POWER_OFF		2	/* power off */
2027c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_DETACH		3	/* detach */
2037c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_REMOVE_DEP		4	/* dependency removed */
2047c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_BRINGUP_SELF		5	/* released from direct PM */
2057c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_RECORD_KEEPER		6	/* PM_ADD_DEPENDENT */
2067c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_RECORD_KEEPER_PROP	7	/* PM_ADD_DEPENDENT_PROP */
2077c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_KEPT			8	/* dep. work as a kept */
2087c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_KEEPER		9	/* dep. work as a keeper */
2097c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_ATTACH		10	/* when dip is attached */
2107c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_CHECK_KEPT		11	/* check if this is a kept */
2117c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_CPR_SUSPEND		12	/* Suspend dep. during CPR */
2127c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_CPR_RESUME		13	/* Resume dep. after CPR */
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate /*
2157c478bd9Sstevel@tonic-gate  * Wait for dependency work to finish or not.
2167c478bd9Sstevel@tonic-gate  */
2177c478bd9Sstevel@tonic-gate #define	PM_DEP_WAIT	1
2187c478bd9Sstevel@tonic-gate #define	PM_DEP_NOWAIT	0
2197c478bd9Sstevel@tonic-gate 
2207c478bd9Sstevel@tonic-gate typedef enum pm_canblock
2217c478bd9Sstevel@tonic-gate {
2227c478bd9Sstevel@tonic-gate 	PM_CANBLOCK_BLOCK,	/* wait for controlling process action */
2237c478bd9Sstevel@tonic-gate 	PM_CANBLOCK_FAIL,	/* don't wait, fail request */
2247c478bd9Sstevel@tonic-gate 	PM_CANBLOCK_BYPASS	/* don't wait, ignore controlling process */
2257c478bd9Sstevel@tonic-gate } pm_canblock_t;
2267c478bd9Sstevel@tonic-gate 
227c42872d4Smh27603 typedef enum pm_cpupm
228c42872d4Smh27603 {
229c42872d4Smh27603 	PM_CPUPM_NOTSET,	/* no specific treatment of CPU devices */
230c42872d4Smh27603 	PM_CPUPM_ENABLE,	/* power manage CPU devices */
231c42872d4Smh27603 	PM_CPUPM_DISABLE	/* do not power manage CPU devices */
232c42872d4Smh27603 } pm_cpupm_t;
233c42872d4Smh27603 
234*2df1fe9cSrandyf #define	PPM(dip) ((dev_info_t *)DEVI(dip)->devi_pm_ppm)
235*2df1fe9cSrandyf 
2367c478bd9Sstevel@tonic-gate /*
2377c478bd9Sstevel@tonic-gate  * The power request struct uses for the DDI_CTLOPS_POWER busctl.
2387c478bd9Sstevel@tonic-gate  *
2397c478bd9Sstevel@tonic-gate  * Note: When changing this enum it is necessary to maintain binary
2407c478bd9Sstevel@tonic-gate  * compatibility with older versions.  To insure that, add new values only
2417c478bd9Sstevel@tonic-gate  * at the end and refrain from deleting any existing values.
2427c478bd9Sstevel@tonic-gate  */
2437c478bd9Sstevel@tonic-gate typedef enum {
2447c478bd9Sstevel@tonic-gate 	PMR_SET_POWER = 1,		/* called ddi_power (obsolete)	*/
2457c478bd9Sstevel@tonic-gate 	PMR_SUSPEND,			/* parental suspend		*/
2467c478bd9Sstevel@tonic-gate 	PMR_RESUME,			/* parental resume		*/
2477c478bd9Sstevel@tonic-gate 	PMR_PRE_SET_POWER,		/* parent's "pre" notification	*/
2487c478bd9Sstevel@tonic-gate 	PMR_POST_SET_POWER,		/* parent's "post" notification	*/
2497c478bd9Sstevel@tonic-gate 	PMR_PPM_SET_POWER,		/* platform pm set power	*/
2507c478bd9Sstevel@tonic-gate 	PMR_PPM_ATTACH,			/* ppm attach notify - unused	*/
2517c478bd9Sstevel@tonic-gate 	PMR_PPM_DETACH,			/* ppm detach notify - unused   */
2527c478bd9Sstevel@tonic-gate 	PMR_PPM_POWER_CHANGE_NOTIFY,	/* ppm level change notify	*/
2537c478bd9Sstevel@tonic-gate 	PMR_REPORT_PMCAP,		/* report pm capability		*/
2547c478bd9Sstevel@tonic-gate 	PMR_CHANGED_POWER,		/* parent's power_has_changed notif. */
2557c478bd9Sstevel@tonic-gate 	PMR_PPM_PRE_PROBE,		/* ppm pre probe notify		*/
2567c478bd9Sstevel@tonic-gate 	PMR_PPM_POST_PROBE,		/* ppm post probe notify	*/
2577c478bd9Sstevel@tonic-gate 	PMR_PPM_PRE_ATTACH,		/* ppm pre attach notify	*/
2587c478bd9Sstevel@tonic-gate 	PMR_PPM_POST_ATTACH,		/* ppm post pm attach notify	*/
2597c478bd9Sstevel@tonic-gate 	PMR_PPM_PRE_DETACH,		/* ppm pre pm detach notify	*/
2607c478bd9Sstevel@tonic-gate 	PMR_PPM_POST_DETACH,		/* ppm post pm detach notify	*/
2617c478bd9Sstevel@tonic-gate 	PMR_PPM_UNMANAGE,		/* device being unmanaged	*/
2627c478bd9Sstevel@tonic-gate 	PMR_PPM_PRE_RESUME,		/* ppm resume notify		*/
2637c478bd9Sstevel@tonic-gate 	PMR_PPM_ALL_LOWEST,		/* ppm all lowest power notify	*/
2647c478bd9Sstevel@tonic-gate 	PMR_PPM_LOCK_POWER,		/* ppm lock power		*/
2657c478bd9Sstevel@tonic-gate 	PMR_PPM_UNLOCK_POWER,		/* ppm unlock power		*/
2667c478bd9Sstevel@tonic-gate 	PMR_PPM_TRY_LOCK_POWER,		/* ppm try lock power		*/
2677c478bd9Sstevel@tonic-gate 	PMR_PPM_INIT_CHILD,		/* ppm init child notify	*/
2687c478bd9Sstevel@tonic-gate 	PMR_PPM_UNINIT_CHILD,		/* ppm uninit child notify	*/
269*2df1fe9cSrandyf 	PMR_PPM_POWER_LOCK_OWNER,	/* ppm power lock owner's address */
270*2df1fe9cSrandyf 	PMR_PPM_ENTER_SX,		/* ppm: enter ACPI S[2-4] state	*/
271*2df1fe9cSrandyf 	PMR_PPM_EXIT_SX,		/* ppm: enter ACPI S[2-4] state	*/
272*2df1fe9cSrandyf 	PMR_PPM_SEARCH_LIST		/* ppm: search tuple list	*/
2737c478bd9Sstevel@tonic-gate } pm_request_type;
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate /*
2767c478bd9Sstevel@tonic-gate  * When changing the elements of the union below it is necessary to
2777c478bd9Sstevel@tonic-gate  * maintain binary compatibility with older versions.  Refrain from
2787c478bd9Sstevel@tonic-gate  * deleting existing elements of the union or modifying their contents.
2797c478bd9Sstevel@tonic-gate  * Avoid increasing the total size of this structure if new elements
2807c478bd9Sstevel@tonic-gate  * must be added.
2817c478bd9Sstevel@tonic-gate  */
2827c478bd9Sstevel@tonic-gate typedef struct power_req {
2837c478bd9Sstevel@tonic-gate 	pm_request_type request_type;
2847c478bd9Sstevel@tonic-gate 	union req {
2857c478bd9Sstevel@tonic-gate 		/*
2867c478bd9Sstevel@tonic-gate 		 * PMR_SET_POWER (obsolete)
2877c478bd9Sstevel@tonic-gate 		 */
2887c478bd9Sstevel@tonic-gate 		struct set_power_req {
2897c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
2907c478bd9Sstevel@tonic-gate 			int		cmpt;
2917c478bd9Sstevel@tonic-gate 			int		level;
2927c478bd9Sstevel@tonic-gate 		} set_power_req;
2937c478bd9Sstevel@tonic-gate 		/*
2947c478bd9Sstevel@tonic-gate 		 * PMR_SUSPEND
2957c478bd9Sstevel@tonic-gate 		 */
2967c478bd9Sstevel@tonic-gate 		struct suspend_req {
2977c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
2987c478bd9Sstevel@tonic-gate 			ddi_detach_cmd_t cmd;
2997c478bd9Sstevel@tonic-gate 		} suspend_req;
3007c478bd9Sstevel@tonic-gate 		/*
3017c478bd9Sstevel@tonic-gate 		 * PMR_PPM_PRE_RESUME or PMR_RESUME
3027c478bd9Sstevel@tonic-gate 		 */
3037c478bd9Sstevel@tonic-gate 		struct resume_req {
3047c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
3057c478bd9Sstevel@tonic-gate 			ddi_attach_cmd_t cmd;
3067c478bd9Sstevel@tonic-gate 		} resume_req;
3077c478bd9Sstevel@tonic-gate 		/*
3087c478bd9Sstevel@tonic-gate 		 * PMR_PRE_SET_POWER
3097c478bd9Sstevel@tonic-gate 		 */
3107c478bd9Sstevel@tonic-gate 		struct pre_set_power_req {
3117c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
3127c478bd9Sstevel@tonic-gate 			int		cmpt;
3137c478bd9Sstevel@tonic-gate 			int		old_level;
3147c478bd9Sstevel@tonic-gate 			int		new_level;
3157c478bd9Sstevel@tonic-gate 		} pre_set_power_req;
3167c478bd9Sstevel@tonic-gate 		/*
3177c478bd9Sstevel@tonic-gate 		 * PMR_POST_SET_POWER
3187c478bd9Sstevel@tonic-gate 		 */
3197c478bd9Sstevel@tonic-gate 		struct post_set_power_req {
3207c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
3217c478bd9Sstevel@tonic-gate 			int		cmpt;
3227c478bd9Sstevel@tonic-gate 			int		old_level;
3237c478bd9Sstevel@tonic-gate 			int		new_level;
3247c478bd9Sstevel@tonic-gate 			int		result;		/* driver's return */
3257c478bd9Sstevel@tonic-gate 		} post_set_power_req;
3267c478bd9Sstevel@tonic-gate 		/*
3277c478bd9Sstevel@tonic-gate 		 * PMR_PPM_SET_POWER
3287c478bd9Sstevel@tonic-gate 		 */
3297c478bd9Sstevel@tonic-gate 		struct ppm_set_power_req {
3307c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
3317c478bd9Sstevel@tonic-gate 			int		cmpt;
3327c478bd9Sstevel@tonic-gate 			int		old_level;
3337c478bd9Sstevel@tonic-gate 			int		new_level;
3347c478bd9Sstevel@tonic-gate 			pm_canblock_t	canblock;
3357c478bd9Sstevel@tonic-gate 			void		*cookie;
3367c478bd9Sstevel@tonic-gate 		} ppm_set_power_req;
3377c478bd9Sstevel@tonic-gate 		/*
3387c478bd9Sstevel@tonic-gate 		 * PMR_PPM_POWER_CHANGE_NOTIFY
3397c478bd9Sstevel@tonic-gate 		 */
3407c478bd9Sstevel@tonic-gate 		struct ppm_notify_level_req {
3417c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
3427c478bd9Sstevel@tonic-gate 			int		cmpt;
3437c478bd9Sstevel@tonic-gate 			int		old_level;
3447c478bd9Sstevel@tonic-gate 			int		new_level;
3457c478bd9Sstevel@tonic-gate 		} ppm_notify_level_req;
3467c478bd9Sstevel@tonic-gate 		/*
3477c478bd9Sstevel@tonic-gate 		 * PMR_REPORT_PMCAP
3487c478bd9Sstevel@tonic-gate 		 */
3497c478bd9Sstevel@tonic-gate 		struct report_pmcap_req {
3507c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
3517c478bd9Sstevel@tonic-gate 			int		cap;
3527c478bd9Sstevel@tonic-gate 			void 		*arg;
3537c478bd9Sstevel@tonic-gate 		} report_pmcap_req;
3547c478bd9Sstevel@tonic-gate 		/*
3557c478bd9Sstevel@tonic-gate 		 * PMR_CHANGED_POWER
3567c478bd9Sstevel@tonic-gate 		 */
3577c478bd9Sstevel@tonic-gate 		struct changed_power_req {
3587c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
3597c478bd9Sstevel@tonic-gate 			int		cmpt;
3607c478bd9Sstevel@tonic-gate 			int		old_level;
3617c478bd9Sstevel@tonic-gate 			int		new_level;
3627c478bd9Sstevel@tonic-gate 			int		result;
3637c478bd9Sstevel@tonic-gate 		} changed_power_req;
3647c478bd9Sstevel@tonic-gate 		/*
3657c478bd9Sstevel@tonic-gate 		 * PMR_PPM_PRE_PROBE, PMR_PPM_POST_PROBE, PMR_PPM_PRE_ATTACH,
3667c478bd9Sstevel@tonic-gate 		 * PMR_PPM_POST_ATTACH, PMR_PPM_PRE_DETACH, PMR_PPM_POST_DETACH
3677c478bd9Sstevel@tonic-gate 		 * PMR_PPM_INIT_CHILD, PMR_PPM_UNINIT_CHILD, or PMR_PPM_UNMANAGE
3687c478bd9Sstevel@tonic-gate 		 */
3697c478bd9Sstevel@tonic-gate 		struct ppm_config_req {
3707c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
3717c478bd9Sstevel@tonic-gate 			int		result;		/* post only */
3727c478bd9Sstevel@tonic-gate 		} ppm_config_req;
3737c478bd9Sstevel@tonic-gate 		/*
3747c478bd9Sstevel@tonic-gate 		 * PMR_PPM_ALL_LOWEST
3757c478bd9Sstevel@tonic-gate 		 */
3767c478bd9Sstevel@tonic-gate 		struct ppm_all_lowest_req {
3777c478bd9Sstevel@tonic-gate 			int		mode;
3787c478bd9Sstevel@tonic-gate 		} ppm_all_lowest_req;
3797c478bd9Sstevel@tonic-gate 		/*
3807c478bd9Sstevel@tonic-gate 		 * PMR_PPM_LOCK_POWER, PMR_PPM_TRY_LOCK_POWER
3817c478bd9Sstevel@tonic-gate 		 */
3827c478bd9Sstevel@tonic-gate 		struct ppm_lock_power_req {
3837c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
3847c478bd9Sstevel@tonic-gate 			int		*circp;
3857c478bd9Sstevel@tonic-gate 		} ppm_lock_power_req;
3867c478bd9Sstevel@tonic-gate 		/*
3877c478bd9Sstevel@tonic-gate 		 * PMR_PPM_UNLOCK_POWER
3887c478bd9Sstevel@tonic-gate 		 */
3897c478bd9Sstevel@tonic-gate 		struct ppm_unlock_power_req {
3907c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
3917c478bd9Sstevel@tonic-gate 			int		circ;
3927c478bd9Sstevel@tonic-gate 		} ppm_unlock_power_req;
3937c478bd9Sstevel@tonic-gate 		/*
3947c478bd9Sstevel@tonic-gate 		 * PMR_PPM_POWER_LOCK_OWNER
3957c478bd9Sstevel@tonic-gate 		 */
3967c478bd9Sstevel@tonic-gate 		struct ppm_power_lock_owner_req {
3977c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
3987c478bd9Sstevel@tonic-gate 			kthread_t	*owner;
3997c478bd9Sstevel@tonic-gate 		} ppm_power_lock_owner_req;
400*2df1fe9cSrandyf 		/*
401*2df1fe9cSrandyf 		 * PMR_PPM_POWER_ENTER_SX
402*2df1fe9cSrandyf 		 */
403*2df1fe9cSrandyf 		struct ppm_power_enter_sx_req {
404*2df1fe9cSrandyf 			int	sx_state;	/* S3, S4 */
405*2df1fe9cSrandyf 			int	test_point;	/* test point */
406*2df1fe9cSrandyf 			uint64_t wakephys;	/* restart vector phys addr */
407*2df1fe9cSrandyf 			void *psr;		/* PSM (apic) state buffer */
408*2df1fe9cSrandyf 		} ppm_power_enter_sx_req;
409*2df1fe9cSrandyf 		/*
410*2df1fe9cSrandyf 		 * PMR_PPM_SEARCH_LIST
411*2df1fe9cSrandyf 		 */
412*2df1fe9cSrandyf 		struct ppm_search_list {
413*2df1fe9cSrandyf 			pm_searchargs_t *searchlist;
414*2df1fe9cSrandyf 			int		result;
415*2df1fe9cSrandyf 		} ppm_search_list_req;
4167c478bd9Sstevel@tonic-gate 	} req;
4177c478bd9Sstevel@tonic-gate } power_req_t;
4187c478bd9Sstevel@tonic-gate 
419*2df1fe9cSrandyf #define	S3	3
420*2df1fe9cSrandyf #define	S4	4
421*2df1fe9cSrandyf 
422*2df1fe9cSrandyf extern int cpr_test_point;
423*2df1fe9cSrandyf extern major_t cpr_device;
424*2df1fe9cSrandyf 
425*2df1fe9cSrandyf #define	LOOP_BACK_NONE	0
426*2df1fe9cSrandyf #define	LOOP_BACK_PASS	1
427*2df1fe9cSrandyf #define	LOOP_BACK_FAIL	2
428*2df1fe9cSrandyf #define	FORCE_SUSPEND_TO_RAM	3
429*2df1fe9cSrandyf #define	DEVICE_SUSPEND_TO_RAM	4
430*2df1fe9cSrandyf 
431*2df1fe9cSrandyf /*
432*2df1fe9cSrandyf  * Struct passed as arg to appm_ioctl
433*2df1fe9cSrandyf  */
434*2df1fe9cSrandyf typedef struct s3_args {
435*2df1fe9cSrandyf 	int		s3a_state;	/* S3, S4 */
436*2df1fe9cSrandyf 	int		s3a_test_point;	/* test point */
437*2df1fe9cSrandyf 	uint64_t	s3a_wakephys;	/* restart vector physical addr */
438*2df1fe9cSrandyf 	void		*s3a_psr;	/* apic state save buffer */
439*2df1fe9cSrandyf } s3a_t;
440*2df1fe9cSrandyf 
4417c478bd9Sstevel@tonic-gate /*
4427c478bd9Sstevel@tonic-gate  * Structure used by the following bus_power operations:
4437c478bd9Sstevel@tonic-gate  *
4447c478bd9Sstevel@tonic-gate  *	BUS_POWER_PRE_NOTIFICATION
4457c478bd9Sstevel@tonic-gate  *	BUS_POWER_POST_NOTIFICATION
4467c478bd9Sstevel@tonic-gate  *	BUS_POWER_CHILD_PWRCHG
4477c478bd9Sstevel@tonic-gate  */
4487c478bd9Sstevel@tonic-gate typedef struct pm_bp_child_pwrchg {
4497c478bd9Sstevel@tonic-gate 	dev_info_t	*bpc_dip;	/* dip of the target device */
4507c478bd9Sstevel@tonic-gate 	char		*bpc_path;	/* path to the target device */
4517c478bd9Sstevel@tonic-gate 	int		bpc_comp;	/* component changing power */
4527c478bd9Sstevel@tonic-gate 	int		bpc_olevel;	/* old power level */
4537c478bd9Sstevel@tonic-gate 	int		bpc_nlevel;	/* new power level */
4547c478bd9Sstevel@tonic-gate 	void		*bpc_private;	/* PM framework private */
4557c478bd9Sstevel@tonic-gate } pm_bp_child_pwrchg_t;
4567c478bd9Sstevel@tonic-gate 
4577c478bd9Sstevel@tonic-gate /*
4587c478bd9Sstevel@tonic-gate  * Structure used by the BUS_POWER_NEXUS_PWRUP operation
4597c478bd9Sstevel@tonic-gate  */
4607c478bd9Sstevel@tonic-gate typedef struct pm_bp_nexus_pwrup {
4617c478bd9Sstevel@tonic-gate 	dev_info_t	*bpn_dip;	/* dip of the nexus device */
4627c478bd9Sstevel@tonic-gate 	int		bpn_comp;	/* component powering up */
4637c478bd9Sstevel@tonic-gate 	int		bpn_level;	/* new power level */
4647c478bd9Sstevel@tonic-gate 	void		*bpn_private;	/* PM framework private */
4657c478bd9Sstevel@tonic-gate } pm_bp_nexus_pwrup_t;
4667c478bd9Sstevel@tonic-gate 
4677c478bd9Sstevel@tonic-gate /*
4687c478bd9Sstevel@tonic-gate  * Structure used by the BUS_POWER_HAS_CHANGED operation
4697c478bd9Sstevel@tonic-gate  */
4707c478bd9Sstevel@tonic-gate typedef struct pm_bp_has_changed {
4717c478bd9Sstevel@tonic-gate 	dev_info_t	*bphc_dip;	/* dip of the target device */
4727c478bd9Sstevel@tonic-gate 	char		*bphc_path;	/* path to the target device */
4737c478bd9Sstevel@tonic-gate 	int		bphc_comp;	/* component changing power */
4747c478bd9Sstevel@tonic-gate 	int		bphc_olevel;	/* old power level */
4757c478bd9Sstevel@tonic-gate 	int		bphc_nlevel;	/* new power level */
4767c478bd9Sstevel@tonic-gate 	void		*bphc_private;	/* PM framework private */
4777c478bd9Sstevel@tonic-gate } pm_bp_has_changed_t;
4787c478bd9Sstevel@tonic-gate 
4797c478bd9Sstevel@tonic-gate /*
4807c478bd9Sstevel@tonic-gate  * Commands indicating which activity is requiring an
4817c478bd9Sstevel@tonic-gate  * update to the noinvol counters.
4827c478bd9Sstevel@tonic-gate  */
4837c478bd9Sstevel@tonic-gate #define	PM_BP_NOINVOL_ATTACH	1
4847c478bd9Sstevel@tonic-gate #define	PM_BP_NOINVOL_DETACH	2
4857c478bd9Sstevel@tonic-gate #define	PM_BP_NOINVOL_REMDRV	3
4867c478bd9Sstevel@tonic-gate #define	PM_BP_NOINVOL_CFB	4
4877c478bd9Sstevel@tonic-gate #define	PM_BP_NOINVOL_POWER	5
4887c478bd9Sstevel@tonic-gate 
4897c478bd9Sstevel@tonic-gate /*
4907c478bd9Sstevel@tonic-gate  * Structure used by the BUS_POWER_NOINVOL operation.
4917c478bd9Sstevel@tonic-gate  */
4927c478bd9Sstevel@tonic-gate typedef struct pm_bp_noinvol {
4937c478bd9Sstevel@tonic-gate 	dev_info_t	*bpni_dip;	/* dip of the target device */
4947c478bd9Sstevel@tonic-gate 	char		*bpni_path;	/* path to the target device */
4957c478bd9Sstevel@tonic-gate 	int		bpni_cmd;	/* how to update the counters */
4967c478bd9Sstevel@tonic-gate 	int		bpni_volpmd;	/* volpmd of target device */
4977c478bd9Sstevel@tonic-gate 	int		bpni_wasvolpmd;	/* whether to update volpmd */
4987c478bd9Sstevel@tonic-gate 	void		*bpni_private;	/* PM framework private */
4997c478bd9Sstevel@tonic-gate } pm_bp_noinvol_t;
5007c478bd9Sstevel@tonic-gate 
5017c478bd9Sstevel@tonic-gate /*
5027c478bd9Sstevel@tonic-gate  * This struct is used by the code that makes a PMR_PPM_SET_POWER request
5037c478bd9Sstevel@tonic-gate  * to ppm. Devices that changed power other than the primary device (which
5047c478bd9Sstevel@tonic-gate  * was requested) are passed back to the pm framework through this
5057c478bd9Sstevel@tonic-gate  * structure.
5067c478bd9Sstevel@tonic-gate  */
5077c478bd9Sstevel@tonic-gate typedef struct pm_ppm_devlist {
5087c478bd9Sstevel@tonic-gate 	dev_info_t	*ppd_who;
5097c478bd9Sstevel@tonic-gate 	int		ppd_cmpt;
5107c478bd9Sstevel@tonic-gate 	int		ppd_old_level;
5117c478bd9Sstevel@tonic-gate 	int		ppd_new_level;
5127c478bd9Sstevel@tonic-gate 	struct pm_ppm_devlist	*ppd_next;
5137c478bd9Sstevel@tonic-gate } pm_ppm_devlist_t;
5147c478bd9Sstevel@tonic-gate 
5157c478bd9Sstevel@tonic-gate /*
5167c478bd9Sstevel@tonic-gate  * This struct is used by the code that brings up parents and notifies
5177c478bd9Sstevel@tonic-gate  * ppm drivers across probe/attach/detach (pm_pre/post_probe/attach/detach())
5187c478bd9Sstevel@tonic-gate  */
5197c478bd9Sstevel@tonic-gate typedef struct pm_ppm_cookie {
5207c478bd9Sstevel@tonic-gate 	dev_info_t		*ppc_dip;	/* dip of target node */
5217c478bd9Sstevel@tonic-gate 	dev_info_t		*ppc_pdip;	/* parent's dip */
5227c478bd9Sstevel@tonic-gate 	dev_info_t		*ppc_ppm;	/* interested ppm driver */
5237c478bd9Sstevel@tonic-gate 	int			ppc_cmd;	/* attach/detach cmd */
5247c478bd9Sstevel@tonic-gate } pm_ppm_cookie_t;
5257c478bd9Sstevel@tonic-gate 
5267c478bd9Sstevel@tonic-gate /*
5277c478bd9Sstevel@tonic-gate  * This struct records one dependency (a device keeps another or others up)
5287c478bd9Sstevel@tonic-gate  * pdr_size includes size of strings.
5297c478bd9Sstevel@tonic-gate  */
5307c478bd9Sstevel@tonic-gate typedef struct pm_dep_rec {
5317c478bd9Sstevel@tonic-gate 	char *pdr_keeper;		/* physpath of device keeping up */
5327c478bd9Sstevel@tonic-gate 	char *pdr_kept;			/* physpath or property name */
5337c478bd9Sstevel@tonic-gate 	char **pdr_kept_paths;		/* array of kept devices' paths */
5347c478bd9Sstevel@tonic-gate 	struct pm_dep_rec *pdr_next;	/* next dependency device */
5357c478bd9Sstevel@tonic-gate 	size_t pdr_size;		/* size to kmem_free */
5367c478bd9Sstevel@tonic-gate 	major_t pdr_major;		/* major of kept driver (not props) */
5377c478bd9Sstevel@tonic-gate 	int pdr_isprop;			/* true if kept is property name */
5387c478bd9Sstevel@tonic-gate 	int pdr_kept_count;		/* how many kept altogether */
5397c478bd9Sstevel@tonic-gate 	int pdr_satisfied;		/* true if in force (not properties) */
5407c478bd9Sstevel@tonic-gate } pm_pdr_t;
5417c478bd9Sstevel@tonic-gate 
5427c478bd9Sstevel@tonic-gate 
5437c478bd9Sstevel@tonic-gate /*
5447c478bd9Sstevel@tonic-gate  * This struct records threshold information about a single component
5457c478bd9Sstevel@tonic-gate  */
5467c478bd9Sstevel@tonic-gate typedef struct pm_thresh_entry {
5477c478bd9Sstevel@tonic-gate 	int pte_numthresh;
5487c478bd9Sstevel@tonic-gate 	int *pte_thresh;
5497c478bd9Sstevel@tonic-gate } pm_pte_t;
5507c478bd9Sstevel@tonic-gate 
5517c478bd9Sstevel@tonic-gate /*
5527c478bd9Sstevel@tonic-gate  * Note that this header and its array of entry structs with their arrays
5537c478bd9Sstevel@tonic-gate  * of thresholds and string storage for physpath are all kmem_alloced in one
5547c478bd9Sstevel@tonic-gate  * chunk for easy freeing ptr_size is the size of that chunk
5557c478bd9Sstevel@tonic-gate  */
5567c478bd9Sstevel@tonic-gate typedef struct pm_thresh_rec {
5577c478bd9Sstevel@tonic-gate 	char			*ptr_physpath;	/* identifies node */
5587c478bd9Sstevel@tonic-gate 	struct pm_thresh_rec	*ptr_next;
5597c478bd9Sstevel@tonic-gate 	int			ptr_numcomps;	/* number of components */
5607c478bd9Sstevel@tonic-gate 	size_t			ptr_size;	/* total size for kmem_free */
5617c478bd9Sstevel@tonic-gate 	pm_pte_t 		*ptr_entries;
5627c478bd9Sstevel@tonic-gate } pm_thresh_rec_t;
5637c478bd9Sstevel@tonic-gate 
5647c478bd9Sstevel@tonic-gate /*
5657c478bd9Sstevel@tonic-gate  * pmi_dev_pm_state state bits:
5667c478bd9Sstevel@tonic-gate  */
5677c478bd9Sstevel@tonic-gate 
5687c478bd9Sstevel@tonic-gate /*
5697c478bd9Sstevel@tonic-gate  * a direct-pm device, not scanned, but controlled by a process
5707c478bd9Sstevel@tonic-gate  */
5717c478bd9Sstevel@tonic-gate #define	PM_DIRECT	0x1
5727c478bd9Sstevel@tonic-gate /*
5737c478bd9Sstevel@tonic-gate  * autopm is suspended while waiting to see if detach succeeds
5747c478bd9Sstevel@tonic-gate  */
5757c478bd9Sstevel@tonic-gate #define	PM_DETACHING	0x2
5767c478bd9Sstevel@tonic-gate 
5777c478bd9Sstevel@tonic-gate /*
5787c478bd9Sstevel@tonic-gate  * An all_to_normal operation for an autopm device that is detaching, is
5797c478bd9Sstevel@tonic-gate  * deferred in case the detach fails.
5807c478bd9Sstevel@tonic-gate  */
5817c478bd9Sstevel@tonic-gate #define	PM_ALLNORM_DEFERRED	0x4
5827c478bd9Sstevel@tonic-gate 
5837c478bd9Sstevel@tonic-gate #define	PM_GET_PM_INFO(dip) (DEVI(dip)->devi_pm_info)
5847c478bd9Sstevel@tonic-gate #define	PM_GET_PM_SCAN(dip) (DEVI(dip)->devi_pm_scan)
5857c478bd9Sstevel@tonic-gate 
5867c478bd9Sstevel@tonic-gate #define	PM_NUMCMPTS(dip) (DEVI(dip)->devi_pm_num_components)
5877c478bd9Sstevel@tonic-gate #define	PM_CP(dip, comp) (&DEVI(dip)->devi_pm_components[comp])
5887c478bd9Sstevel@tonic-gate 
5897c478bd9Sstevel@tonic-gate /*
5907c478bd9Sstevel@tonic-gate  * Returns true if the device specified by dip is directly power managed
5917c478bd9Sstevel@tonic-gate  */
5927c478bd9Sstevel@tonic-gate #define	PM_ISDIRECT(dip) \
5937c478bd9Sstevel@tonic-gate 	(((pm_info_t *)PM_GET_PM_INFO(dip))->pmi_dev_pm_state & PM_DIRECT)
5947c478bd9Sstevel@tonic-gate 
5957c478bd9Sstevel@tonic-gate /*
5967c478bd9Sstevel@tonic-gate  * Returns true if the device specified by dip is an old node for which we
5977c478bd9Sstevel@tonic-gate  * provide backwards compatible behavior (e.g. no pm-components property).
5987c478bd9Sstevel@tonic-gate  */
5997c478bd9Sstevel@tonic-gate #define	PM_ISBC(dip) (DEVI(dip)->devi_pm_flags & PMC_BC)
6007c478bd9Sstevel@tonic-gate 
6017c478bd9Sstevel@tonic-gate /*
6027c478bd9Sstevel@tonic-gate  * Returns true if we have skipped a dependency bringup on this dip.
6037c478bd9Sstevel@tonic-gate  */
6047c478bd9Sstevel@tonic-gate #define	PM_SKBU(dip) (DEVI(dip)->devi_pm_flags & PMC_SKIP_BRINGUP)
6057c478bd9Sstevel@tonic-gate 
606c42872d4Smh27603 /*
607c42872d4Smh27603  * Returns true if device specified by dip is a power manageable CPU.
608c42872d4Smh27603  */
609c42872d4Smh27603 #define	PM_ISCPU(dip) (DEVI(dip)->devi_pm_flags & PMC_CPU_DEVICE)
610c42872d4Smh27603 
611c42872d4Smh27603 /*
612c42872d4Smh27603  * Returns true if cpupm is enabled.
613c42872d4Smh27603  */
614c42872d4Smh27603 #define	PM_CPUPM_ENABLED (cpupm == PM_CPUPM_ENABLE)
615c42872d4Smh27603 
616c42872d4Smh27603 /*
617c42872d4Smh27603  * Returns true if is disabled.
618c42872d4Smh27603  */
619c42872d4Smh27603 #define	PM_CPUPM_DISABLED (cpupm == PM_CPUPM_DISABLE)
620c42872d4Smh27603 
621c42872d4Smh27603 /*
622c42872d4Smh27603  * If (autopm is enabled and
623c42872d4Smh27603  *      (CPUs are not disabled, or it isn't a cpu)) OR
624c42872d4Smh27603  *    (CPUs are enabled and it is one)
625c42872d4Smh27603  */
626c42872d4Smh27603 #define	PM_SCANABLE(dip) ((autopm_enabled && \
627c42872d4Smh27603 (!PM_CPUPM_DISABLED || !PM_ISCPU(dip))) || (PM_CPUPM_ENABLED && PM_ISCPU(dip)))
628c42872d4Smh27603 
6297c478bd9Sstevel@tonic-gate #define	PM_NOT_ALL_LOWEST	0x0	/* not all components are at lowest */
6307c478bd9Sstevel@tonic-gate #define	PM_ALL_LOWEST		0x1	/* all components are at lowest lvl */
6317c478bd9Sstevel@tonic-gate 
6327c478bd9Sstevel@tonic-gate #define	PM_ADDR(dip)	(ddi_get_name_addr(dip) ? ddi_get_name_addr(dip) : "")
6337c478bd9Sstevel@tonic-gate #define	PM_NAME(dip)	(ddi_binding_name(dip))
6347c478bd9Sstevel@tonic-gate #define	PM_NODE(dip)	(ddi_node_name(dip))
6357c478bd9Sstevel@tonic-gate #define	PM_INST(dip)	(ddi_get_instance(dip))
6367c478bd9Sstevel@tonic-gate #define	PM_DEVICE(dip)	PM_NAME(dip), PM_ADDR(dip), PM_NODE(dip), PM_INST(dip)
6377c478bd9Sstevel@tonic-gate 
6387c478bd9Sstevel@tonic-gate #ifdef	DEBUG
6397c478bd9Sstevel@tonic-gate /*
6407c478bd9Sstevel@tonic-gate  * Flags passed to PMD to enable debug printfs.  If the same flag is set in
6417c478bd9Sstevel@tonic-gate  * pm_debug below then the message is printed.  The most generally useful
6427c478bd9Sstevel@tonic-gate  * ones are the first 3 or 4.
6437c478bd9Sstevel@tonic-gate  */
6447c478bd9Sstevel@tonic-gate #define	PMD_ERROR	0x0000001
6457c478bd9Sstevel@tonic-gate #define	PMD_FAIL	0x0000002
6467c478bd9Sstevel@tonic-gate #define	PMD_IOCTL	0x0000004
6477c478bd9Sstevel@tonic-gate #define	PMD_SCAN	0x0000008
6487c478bd9Sstevel@tonic-gate #define	PMD_RESCAN	0x0000010
6497c478bd9Sstevel@tonic-gate #define	PMD_REMINFO	0x0000020
6507c478bd9Sstevel@tonic-gate #define	PMD_NAMETODIP	0x0000040
6517c478bd9Sstevel@tonic-gate #define	PMD_CLOSE	0x0000080
6527c478bd9Sstevel@tonic-gate #define	PMD_DIN		0x0000100	/* Dev Is Needed */
6537c478bd9Sstevel@tonic-gate #define	PMD_PMC		0x0000200	/* for testing with sun4m pmc driver */
6547c478bd9Sstevel@tonic-gate #define	PMD_PPM		0x0000400
6557c478bd9Sstevel@tonic-gate #define	PMD_DEP		0x0000800	/* dependency processing */
6567c478bd9Sstevel@tonic-gate #define	PMD_IDLEDOWN	0x0001000
6577c478bd9Sstevel@tonic-gate #define	PMD_SET		0x0002000
6587c478bd9Sstevel@tonic-gate #define	PMD_BRING	0x0004000
6597c478bd9Sstevel@tonic-gate #define	PMD_ALLNORM	0x0008000
6607c478bd9Sstevel@tonic-gate #define	PMD_REMDEV	0x0010000
6617c478bd9Sstevel@tonic-gate #define	PMD_LEVEL	0x0020000
6627c478bd9Sstevel@tonic-gate #define	PMD_THRESH	0x0040000
6637c478bd9Sstevel@tonic-gate #define	PMD_DPM		0x0080000	/* Direct Power Management */
6647c478bd9Sstevel@tonic-gate #define	PMD_NORM	0x0100000
6657c478bd9Sstevel@tonic-gate #define	PMD_STATS	0x0200000
6667c478bd9Sstevel@tonic-gate #define	PMD_DEREG	0x0400000
6677c478bd9Sstevel@tonic-gate #define	PMD_KEEPS	0x0800000
6687c478bd9Sstevel@tonic-gate #define	PMD_KIDSUP	0x1000000
6697c478bd9Sstevel@tonic-gate #define	PMD_TCHECK	0x2000000
6707c478bd9Sstevel@tonic-gate #define	PMD_NOINVOL	0x4000000
6717c478bd9Sstevel@tonic-gate #define	PMD_CFB		0x8000000	/* console fb pm */
6727c478bd9Sstevel@tonic-gate #define	PMD_DHR		0x10000000	/* driver hold/rele changes */
6737c478bd9Sstevel@tonic-gate #define	PMD_PIL		0x20000000	/* print out PIL when calling power */
6747c478bd9Sstevel@tonic-gate #define	PMD_PHC		0x40000000	/* pm_power_has_changed messages */
6757c478bd9Sstevel@tonic-gate #define	PMD_LOCK	0x80000000
676*2df1fe9cSrandyf #define	PMD_SX		0x80000000	/* ACPI S[1234] states */
677*2df1fe9cSrandyf #define	PMD_PROTO	PMD_SX		/* and other Prototype stuff */
6787c478bd9Sstevel@tonic-gate 
6797c478bd9Sstevel@tonic-gate extern uint_t	pm_debug;
6807c478bd9Sstevel@tonic-gate extern uint_t	pm_divertdebug;
6817c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/
6827c478bd9Sstevel@tonic-gate extern void	pm_log(const char *fmt, ...) __KPRINTFLIKE(1);
6837c478bd9Sstevel@tonic-gate 
684*2df1fe9cSrandyf #if !defined(__sparc)
685*2df1fe9cSrandyf /*
686*2df1fe9cSrandyf  * On non-sparc machines, PMDDEBUG isn't as big a deal as Sparc, so we
687*2df1fe9cSrandyf  * define PMDDEUG here for use on non-sparc platforms.
688*2df1fe9cSrandyf  */
689*2df1fe9cSrandyf #define	PMDDEBUG
690*2df1fe9cSrandyf #endif /* !__sparc */
691*2df1fe9cSrandyf 
692c50cf65dSkchow #ifdef PMDDEBUG
6937c478bd9Sstevel@tonic-gate #define	PMD(level, arglist) { 			\
6947c478bd9Sstevel@tonic-gate 	if (pm_debug & (level)) {		\
6957c478bd9Sstevel@tonic-gate 		pm_log arglist;			\
6967c478bd9Sstevel@tonic-gate 	}					\
6977c478bd9Sstevel@tonic-gate }
698*2df1fe9cSrandyf #else /* !PMDDEBUG */
699c50cf65dSkchow #define	PMD(level, arglist)	((void)0);
700*2df1fe9cSrandyf #endif /* PMDDEBUG */
701*2df1fe9cSrandyf #ifndef	sparc
702*2df1fe9cSrandyf extern clock_t pt_sleep;
703*2df1fe9cSrandyf /* code is char hex number to display on POST LED */
704*2df1fe9cSrandyf #define	PT(code) {outb(0x80, (char)code); drv_usecwait(pt_sleep); }
705*2df1fe9cSrandyf #else
706*2df1fe9cSrandyf #define	PT(code)
707c50cf65dSkchow #endif
7087c478bd9Sstevel@tonic-gate #else
7097c478bd9Sstevel@tonic-gate #define	PMD(level, arglist)
710*2df1fe9cSrandyf #define	PT(code)
7117c478bd9Sstevel@tonic-gate #endif
712*2df1fe9cSrandyf /*
713*2df1fe9cSrandyf  * Code	Value	Indication
714*2df1fe9cSrandyf  *
715*2df1fe9cSrandyf  */
716*2df1fe9cSrandyf #define	PT_SPL7		0x01	/* pm_suspend spl7 */
717*2df1fe9cSrandyf #define	PT_PMSRET	0x02	/* pm_suspend returns */
718*2df1fe9cSrandyf #define	PT_PPMCTLOP	0x03	/* invoking ppm_ctlops */
719*2df1fe9cSrandyf #define	PT_ACPISDEV	0x04	/* acpi suspend devices */
720*2df1fe9cSrandyf #define	PT_IC		0x05	/* acpi intr_clear */
721*2df1fe9cSrandyf #define	PT_1to1		0x06	/* 1:1 mapping */
722*2df1fe9cSrandyf #define	PT_SC		0x07	/* save context */
723*2df1fe9cSrandyf #define	PT_SWV		0x08	/* set waking vector */
724*2df1fe9cSrandyf #define	PT_SWV_FAIL	0x09	/* set waking vector failed */
725*2df1fe9cSrandyf #define	PT_EWE		0x0a	/* enable wake events */
726*2df1fe9cSrandyf #define	PT_EWE_FAIL	0x0b	/* enable wake events failed */
727*2df1fe9cSrandyf #define	PT_RTCW		0x0c	/* setting rtc wakeup */
728*2df1fe9cSrandyf #define	PT_RTCW_FAIL	0x0d	/* setting rtc wakeup failed */
729*2df1fe9cSrandyf #define	PT_TOD		0x0e	/* setting tod */
730*2df1fe9cSrandyf #define	PT_SXP		0x0f	/* sx prep */
731*2df1fe9cSrandyf #define	PT_SXE		0x10	/* sx enter */
732*2df1fe9cSrandyf #define	PT_SXE_FAIL	0x11	/* sx enter failed */
733*2df1fe9cSrandyf #define	PT_INSOM	0x12	/* insomnia label */
734*2df1fe9cSrandyf #define	PT_WOKE		0x20	/* woke up */
735*2df1fe9cSrandyf #define	PT_UNDO1to1	0x21	/* Undo 1:1 mapping */
736*2df1fe9cSrandyf #define	PT_LSS		0x22	/* leave sleep state */
737*2df1fe9cSrandyf #define	PT_LSS_FAIL	0x23	/* leave sleep state failed */
738*2df1fe9cSrandyf #define	PT_DPB		0x24	/* disable power button */
739*2df1fe9cSrandyf #define	PT_DPB_FAIL	0x25	/* disable power button failed */
740*2df1fe9cSrandyf #define	PT_DRTC_FAIL	0x26	/* disable rtc fails */
741*2df1fe9cSrandyf #define	PT_ACPIREINIT	0x27	/* reinit apic */
742*2df1fe9cSrandyf #define	PT_ACPIRESTORE	0x28	/* restore apic */
743*2df1fe9cSrandyf #define	PT_INTRRESTORE	0x28	/* restore interrupts */
744*2df1fe9cSrandyf #define	PT_RESDEV	0x2a	/* ressume acpi devices */
745*2df1fe9cSrandyf #define	PT_CPU		0x2b	/* init_cpu_syscall */
746*2df1fe9cSrandyf #define	PT_PRESUME	0x30	/* pm_resume entered */
747*2df1fe9cSrandyf #define	PT_RSUS		0x31	/* pm_resume "suspended" */
748*2df1fe9cSrandyf #define	PT_RKERN	0x32	/* pm_resume "kernel" */
749*2df1fe9cSrandyf #define	PT_RDRV		0x33	/* pm_resume "driver" */
750*2df1fe9cSrandyf #define	PT_RDRV_FAIL	0x34	/* pm_resume "driver" failed */
751*2df1fe9cSrandyf #define	PT_RRNOINVOL	0x35	/* pm_resume "reattach_noinvol" */
752*2df1fe9cSrandyf #define	PT_RUSER	0x36	/* pm_resume "user" */
753*2df1fe9cSrandyf #define	PT_RAPMSIG	0x37	/* pm_resume APM/SRN signal */
754*2df1fe9cSrandyf #define	PT_RMPO		0x38	/* pm_resume "mp_online" */
755*2df1fe9cSrandyf #define	PT_RDONE	0x39	/* pm_resume done */
7567c478bd9Sstevel@tonic-gate 
7577c478bd9Sstevel@tonic-gate extern void	pm_detaching(dev_info_t *);
7587c478bd9Sstevel@tonic-gate extern void	pm_detach_failed(dev_info_t *);
7597c478bd9Sstevel@tonic-gate extern int	pm_power(dev_info_t *, int, int);
7607c478bd9Sstevel@tonic-gate extern int	pm_unmanage(dev_info_t *);
7617c478bd9Sstevel@tonic-gate extern void	pm_rem_info(dev_info_t *);
7627c478bd9Sstevel@tonic-gate extern int	pm_get_norm_pwrs(dev_info_t *, int **, size_t *);
7637c478bd9Sstevel@tonic-gate extern dev_info_t *pm_name_to_dip(char *, int);
7647c478bd9Sstevel@tonic-gate extern int	pm_power_up(dev_info_t *, int, int, int, pm_info_t *);
7657c478bd9Sstevel@tonic-gate extern int	pm_default_idle_threshold;
7667c478bd9Sstevel@tonic-gate extern void	pm_set_device_threshold(dev_info_t *, int, int);
7677c478bd9Sstevel@tonic-gate extern int	pm_valid_power(dev_info_t *, int, int);
7687c478bd9Sstevel@tonic-gate extern void	pm_lock_power(dev_info_t *, int *);
7697c478bd9Sstevel@tonic-gate extern void	pm_unlock_power(dev_info_t *, int);
7707c478bd9Sstevel@tonic-gate extern int	pm_try_locking_power(dev_info_t *, int *);
7717c478bd9Sstevel@tonic-gate extern void	pm_lock_power_single(dev_info_t *, int *);
7727c478bd9Sstevel@tonic-gate extern void	pm_unlock_power_single(dev_info_t *, int);
7737c478bd9Sstevel@tonic-gate extern int	pm_try_locking_power_single(dev_info_t *, int *);
7747c478bd9Sstevel@tonic-gate extern int	pm_isbc(dev_info_t *dip);
7757c478bd9Sstevel@tonic-gate extern int	pm_isdirect(dev_info_t *dip);
7767c478bd9Sstevel@tonic-gate extern int	pm_ctlops(dev_info_t *d, dev_info_t *r, ddi_ctl_enum_t o,
7777c478bd9Sstevel@tonic-gate 			void *a, void *v);
7787c478bd9Sstevel@tonic-gate extern int	pm_noinvol_detached(char *);
7797c478bd9Sstevel@tonic-gate extern int	pm_init_child(dev_info_t *);
7807c478bd9Sstevel@tonic-gate extern int	pm_uninit_child(dev_info_t *);
7817c478bd9Sstevel@tonic-gate 
7827c478bd9Sstevel@tonic-gate extern int	pm_all_to_normal(dev_info_t *, pm_canblock_t);
7837c478bd9Sstevel@tonic-gate extern int	pm_set_power(dev_info_t *, int, int, int, pm_canblock_t, int,
7847c478bd9Sstevel@tonic-gate 			int *);
7857c478bd9Sstevel@tonic-gate extern void	pm_scan_init(dev_info_t *dip);
7867c478bd9Sstevel@tonic-gate extern void	pm_scan_fini(dev_info_t *dip);
7877c478bd9Sstevel@tonic-gate extern void	pm_scan_stop(dev_info_t *dip);
7887c478bd9Sstevel@tonic-gate extern int	pm_scan_stop_walk(dev_info_t *dip, void *);
7897c478bd9Sstevel@tonic-gate extern void	pm_scan(void *);
7907c478bd9Sstevel@tonic-gate extern time_t	pm_scan_dev(dev_info_t *dip);
7917c478bd9Sstevel@tonic-gate extern void	pm_rescan(void *);
7927c478bd9Sstevel@tonic-gate extern int	pm_rescan_walk(dev_info_t *, void *);
7937c478bd9Sstevel@tonic-gate extern void	pm_forget_power_level(dev_info_t *);
7947c478bd9Sstevel@tonic-gate extern int	pm_pre_config(dev_info_t *, char *);
7957c478bd9Sstevel@tonic-gate extern int	pm_pre_unconfig(dev_info_t *, int, int *, char *);
7967c478bd9Sstevel@tonic-gate extern void	pm_post_config(dev_info_t *, char *);
7977c478bd9Sstevel@tonic-gate extern void	pm_post_unconfig(dev_info_t *, int, char *);
7987c478bd9Sstevel@tonic-gate extern void	pm_pre_probe(dev_info_t *, pm_ppm_cookie_t *);
7997c478bd9Sstevel@tonic-gate extern void	pm_post_probe(pm_ppm_cookie_t *, int, int);
8007c478bd9Sstevel@tonic-gate extern void	pm_post_attach(pm_ppm_cookie_t *, int);
8017c478bd9Sstevel@tonic-gate extern void	pm_pre_attach(dev_info_t *, pm_ppm_cookie_t *,
8027c478bd9Sstevel@tonic-gate 			ddi_attach_cmd_t);
8037c478bd9Sstevel@tonic-gate extern void	pm_pre_detach(dev_info_t *, ddi_detach_cmd_t,
8047c478bd9Sstevel@tonic-gate 			pm_ppm_cookie_t *);
8057c478bd9Sstevel@tonic-gate extern void	pm_post_detach(pm_ppm_cookie_t *, int);
8067c478bd9Sstevel@tonic-gate extern int	pm_powerup(dev_info_t *);
8077c478bd9Sstevel@tonic-gate extern int	pm_all_at_normal(dev_info_t *);
8087c478bd9Sstevel@tonic-gate extern int	pm_busop_bus_power(dev_info_t *, void *,
8097c478bd9Sstevel@tonic-gate 		    pm_bus_power_op_t, void *, void *);
8107c478bd9Sstevel@tonic-gate extern void	pm_hold_power(dev_info_t *);
8117c478bd9Sstevel@tonic-gate extern void	pm_rele_power(dev_info_t *);
8127c478bd9Sstevel@tonic-gate extern void	pm_driver_removed(major_t);
8137c478bd9Sstevel@tonic-gate extern void	pm_borrow_lock(kthread_t *);
8147c478bd9Sstevel@tonic-gate extern void	pm_return_lock(void);
8157c478bd9Sstevel@tonic-gate extern int	pm_reattach_noinvol(void);
8167c478bd9Sstevel@tonic-gate extern void	pm_reattach_noinvol_fini();
8177c478bd9Sstevel@tonic-gate extern void	pm_restore_direct_levels(void);
8187c478bd9Sstevel@tonic-gate extern void	pm_save_direct_levels(void);
8197c478bd9Sstevel@tonic-gate extern void	pm_cfb_setup(const char *);
8207c478bd9Sstevel@tonic-gate extern void	pm_proceed(dev_info_t *, int, int, int);
8217c478bd9Sstevel@tonic-gate extern void	pm_get_timestamps(dev_info_t *, time_t *);
8227c478bd9Sstevel@tonic-gate extern void	pm_deregister_watcher(int, dev_info_t *);
8237c478bd9Sstevel@tonic-gate extern void	pm_dispatch_to_dep_thread(int, char *, char *, int, int *, int);
8247c478bd9Sstevel@tonic-gate extern int	e_pm_valid_comp(dev_info_t *, int, pm_component_t **);
8257c478bd9Sstevel@tonic-gate extern int	e_pm_valid_info(dev_info_t *, pm_info_t **);
8267c478bd9Sstevel@tonic-gate extern int	e_pm_valid_power(dev_info_t *, int, int);
8277c478bd9Sstevel@tonic-gate extern void	pm_init_locks(void);
8287c478bd9Sstevel@tonic-gate extern int	pm_register_ppm(int (*)(dev_info_t *), dev_info_t *);
8297c478bd9Sstevel@tonic-gate extern int	pm_is_cfb(dev_info_t *);
8307c478bd9Sstevel@tonic-gate #ifdef	DEBUG
8317c478bd9Sstevel@tonic-gate extern int	pm_cfb_is_up(void);
8327c478bd9Sstevel@tonic-gate #endif
8337c478bd9Sstevel@tonic-gate 
834*2df1fe9cSrandyf #ifdef DIPLOCKDEBUG
8357c478bd9Sstevel@tonic-gate #define	PM_LOCK_DIP(dip)	{ PMD(PMD_LOCK, ("dip lock %s@%s(%s#%d) " \
8367c478bd9Sstevel@tonic-gate 				    "%s %d\n", PM_DEVICE(dip),		  \
8377c478bd9Sstevel@tonic-gate 				    __FILE__, __LINE__)) 		  \
8387c478bd9Sstevel@tonic-gate 				    mutex_enter(&DEVI(dip)->devi_pm_lock); }
8397c478bd9Sstevel@tonic-gate #define	PM_UNLOCK_DIP(dip)	{ PMD(PMD_LOCK, ("dip unlock %s@%s(%s#%d) " \
8407c478bd9Sstevel@tonic-gate 				    "%s %d\n", PM_DEVICE(dip),		    \
8417c478bd9Sstevel@tonic-gate 				    __FILE__, __LINE__))		    \
8427c478bd9Sstevel@tonic-gate 				    mutex_exit(&DEVI(dip)->devi_pm_lock); }
8437c478bd9Sstevel@tonic-gate #else
8447c478bd9Sstevel@tonic-gate #define	PM_LOCK_DIP(dip)	mutex_enter(&DEVI(dip)->devi_pm_lock)
8457c478bd9Sstevel@tonic-gate #define	PM_UNLOCK_DIP(dip)	mutex_exit(&DEVI(dip)->devi_pm_lock)
8467c478bd9Sstevel@tonic-gate #endif
8477c478bd9Sstevel@tonic-gate 
8487c478bd9Sstevel@tonic-gate /*
8497c478bd9Sstevel@tonic-gate  * These are the same DEBUG or not
8507c478bd9Sstevel@tonic-gate  */
8517c478bd9Sstevel@tonic-gate #define	PM_LOCK_BUSY(dip)	mutex_enter(&DEVI(dip)->devi_pm_busy_lock)
8527c478bd9Sstevel@tonic-gate #define	PM_UNLOCK_BUSY(dip)	mutex_exit(&DEVI(dip)->devi_pm_busy_lock)
8537c478bd9Sstevel@tonic-gate #define	PM_LOCK_POWER(dip, circp)	pm_lock_power(dip, circp)
8547c478bd9Sstevel@tonic-gate #define	PM_UNLOCK_POWER(dip, circ)	pm_unlock_power(dip, circ)
8557c478bd9Sstevel@tonic-gate #define	PM_TRY_LOCK_POWER(dip, circp)	pm_try_locking_power(dip, circp)
8567c478bd9Sstevel@tonic-gate #define	PM_IAM_LOCKING_DIP(dip)	(mutex_owned(&DEVI(dip)->devi_pm_lock))
8577c478bd9Sstevel@tonic-gate 
8587c478bd9Sstevel@tonic-gate #define	PM_DEFAULT_SYS_IDLENESS	1800	/* 30 minutes */
8597c478bd9Sstevel@tonic-gate 
8607c478bd9Sstevel@tonic-gate /*
8617c478bd9Sstevel@tonic-gate  * Codes put into the pr_retval field of pm_rsvp_t that tell pm_block()
8627c478bd9Sstevel@tonic-gate  * how to proceed
8637c478bd9Sstevel@tonic-gate  */
8647c478bd9Sstevel@tonic-gate #define	PMP_SUCCEED	0x1	/* return success, the process did it */
8657c478bd9Sstevel@tonic-gate #define	PMP_FAIL	0x2	/* return fail, process did something else */
8667c478bd9Sstevel@tonic-gate #define	PMP_RELEASE	0x3	/* let it go, the process has lost interest */
8677c478bd9Sstevel@tonic-gate 				/* also arg to pm_proceed to signal this */
8687c478bd9Sstevel@tonic-gate /*
8697c478bd9Sstevel@tonic-gate  * Values of "style" for e_pm_manage and pm_premanage
8707c478bd9Sstevel@tonic-gate  */
8717c478bd9Sstevel@tonic-gate #define	PM_STYLE_NEW		0
8727c478bd9Sstevel@tonic-gate #define	PM_STYLE_UNKNOWN	1
8737c478bd9Sstevel@tonic-gate 
8747c478bd9Sstevel@tonic-gate /*
8757c478bd9Sstevel@tonic-gate  * Arg passed to pm_proceed that results in PMP_SUCCEED or PMP_FAIL being set
8767c478bd9Sstevel@tonic-gate  * in pr_retval depending on what is pending
8777c478bd9Sstevel@tonic-gate  */
8787c478bd9Sstevel@tonic-gate #define	PMP_SETPOWER	0x4
8797c478bd9Sstevel@tonic-gate 
8807c478bd9Sstevel@tonic-gate #define	PM_MAX_CLONE	256
8817c478bd9Sstevel@tonic-gate 
8827c478bd9Sstevel@tonic-gate typedef struct pm_rsvp {
8837c478bd9Sstevel@tonic-gate 	dev_info_t	*pr_dip;
8847c478bd9Sstevel@tonic-gate 	int		pr_comp;
8857c478bd9Sstevel@tonic-gate 	int		pr_newlevel;
8867c478bd9Sstevel@tonic-gate 	int		pr_oldlevel;
8877c478bd9Sstevel@tonic-gate 	kcondvar_t	pr_cv;		/* a place to sleep */
8887c478bd9Sstevel@tonic-gate 	int		pr_retval;	/* what to do when you wake up */
8897c478bd9Sstevel@tonic-gate 	struct pm_rsvp	*pr_next;
8907c478bd9Sstevel@tonic-gate 	struct pm_rsvp	*pr_prev;
8917c478bd9Sstevel@tonic-gate } pm_rsvp_t;
8927c478bd9Sstevel@tonic-gate 
8937c478bd9Sstevel@tonic-gate typedef struct psce {	/* pm_state_change_entries */
8947c478bd9Sstevel@tonic-gate 	struct pm_state_change		*psce_first;
8957c478bd9Sstevel@tonic-gate 	struct pm_state_change		*psce_in;
8967c478bd9Sstevel@tonic-gate 	struct pm_state_change		*psce_out;
8977c478bd9Sstevel@tonic-gate 	struct pm_state_change		*psce_last;
8987c478bd9Sstevel@tonic-gate 	int				psce_overruns;
8997c478bd9Sstevel@tonic-gate 	int				psce_references;
9007c478bd9Sstevel@tonic-gate 	kmutex_t			psce_lock;
9017c478bd9Sstevel@tonic-gate } psce_t;
9027c478bd9Sstevel@tonic-gate 
9037c478bd9Sstevel@tonic-gate typedef struct pscc {			/* pm_state_change_control */
9047c478bd9Sstevel@tonic-gate 	int		pscc_clone;
9057c478bd9Sstevel@tonic-gate 	dev_info_t	*pscc_dip;
9067c478bd9Sstevel@tonic-gate 	psce_t		*pscc_entries;
9077c478bd9Sstevel@tonic-gate 	struct pscc	*pscc_next;
9087c478bd9Sstevel@tonic-gate 	struct pscc	*pscc_prev;
9097c478bd9Sstevel@tonic-gate } pscc_t;
9107c478bd9Sstevel@tonic-gate 
9117c478bd9Sstevel@tonic-gate #define	PSCCOUNT 128	/* number of state change entries kept per process */
9127c478bd9Sstevel@tonic-gate 
9137c478bd9Sstevel@tonic-gate /*
9147c478bd9Sstevel@tonic-gate  * Struct used to track the existance of devices exporting the
9157c478bd9Sstevel@tonic-gate  * no-involuntary-power-cycles property, and remember things from their
9167c478bd9Sstevel@tonic-gate  * devinfo node for later attach.
9177c478bd9Sstevel@tonic-gate  */
9187c478bd9Sstevel@tonic-gate typedef struct pm_noinvol {
9197c478bd9Sstevel@tonic-gate 	struct pm_noinvol	*ni_next;
9207c478bd9Sstevel@tonic-gate 	char			*ni_path;
9217c478bd9Sstevel@tonic-gate 	major_t			ni_major;	/* for attaching at cpr time */
9227c478bd9Sstevel@tonic-gate 	uint_t			ni_flags;	/* selected PMC_* values */
9237c478bd9Sstevel@tonic-gate 	uint_t			ni_noinvolpm;	/* saved noinvolpm count */
9247c478bd9Sstevel@tonic-gate 	uint_t			ni_volpmd;	/* saved volpmd count */
9257c478bd9Sstevel@tonic-gate 	uint_t			ni_wasvolpmd;	/* was vol pm'd at detach */
9267c478bd9Sstevel@tonic-gate 	size_t			ni_size;
9277c478bd9Sstevel@tonic-gate 	int			ni_persistent;	/* still around */
9287c478bd9Sstevel@tonic-gate } pm_noinvol_t;
9297c478bd9Sstevel@tonic-gate 
9307c478bd9Sstevel@tonic-gate #define	PMID_IOCTIMER		0x1		/* pm_ioctl sets during timer */
9317c478bd9Sstevel@tonic-gate #define	PMID_CFBTIMER		0x2		/* cfb sets during timer */
9327c478bd9Sstevel@tonic-gate #define	PMID_IOCSCAN		0x4		/* pm_ioctl sets during scan */
9337c478bd9Sstevel@tonic-gate #define	PMID_CFBSCAN		0x8		/* cfb sets during scan */
9347c478bd9Sstevel@tonic-gate 
9357c478bd9Sstevel@tonic-gate #define	PMID_IOC		(PMID_IOCTIMER | PMID_IOCSCAN)
9367c478bd9Sstevel@tonic-gate #define	PMID_CFB		(PMID_CFBTIMER | PMID_CFBSCAN)
9377c478bd9Sstevel@tonic-gate #define	PMID_TIMERS		(PMID_IOCTIMER | PMID_CFBTIMER)
9387c478bd9Sstevel@tonic-gate #define	PMID_SCANS		(PMID_IOCSCAN | PMID_CFBSCAN)
9397c478bd9Sstevel@tonic-gate #define	PMID_SCANS_SHIFT	2
9407c478bd9Sstevel@tonic-gate #define	PMID_SET_SCANS(pmid)	(pmid) |= (((pmid) & PMID_TIMERS) <<	\
9417c478bd9Sstevel@tonic-gate 				    PMID_SCANS_SHIFT);
9427c478bd9Sstevel@tonic-gate #define	PMID_IS_IOC(pmid)	((pmid) & PMID_IOC)
9437c478bd9Sstevel@tonic-gate #define	PMID_IS_CFB(pmid, dip)	(((pmid) & PMID_CFB) &&			\
9447c478bd9Sstevel@tonic-gate 				    (DEVI(dip)->devi_pm_flags &		\
9457c478bd9Sstevel@tonic-gate 				    (PMC_DEF_THRESH | PMC_NEXDEF_THRESH)))
9467c478bd9Sstevel@tonic-gate #define	PM_IS_PID(dip)	(PMID_IS_IOC(PM_GET_PM_SCAN(dip)->ps_idle_down) || \
9477c478bd9Sstevel@tonic-gate 	PMID_IS_CFB(PM_GET_PM_SCAN(dip)->ps_idle_down, dip))
9487c478bd9Sstevel@tonic-gate #define	PM_IS_CFB(dip)		(DEVI(dip)->devi_pm_flags & PMC_CONSOLE_FB)
9497c478bd9Sstevel@tonic-gate #define	PM_KUC(dip)		(DEVI(dip)->devi_pm_kidsupcnt)
9507c478bd9Sstevel@tonic-gate #define	PM_CURPOWER(dip, comp)	cur_power(PM_CP(dip, comp))
9517c478bd9Sstevel@tonic-gate 
9527c478bd9Sstevel@tonic-gate #define	PM_WANTS_NOTIFICATION(dip)					\
9537c478bd9Sstevel@tonic-gate 	(DEVI(dip)->devi_pm_flags & PMC_WANTS_NOTIFY)
9547c478bd9Sstevel@tonic-gate 
9557c478bd9Sstevel@tonic-gate #define	PM_HAS_BUS_POWER(dip)						\
9567c478bd9Sstevel@tonic-gate 	((DEVI(dip)->devi_ops->devo_bus_ops != NULL) &&			\
9577c478bd9Sstevel@tonic-gate 	(DEVI(dip)->devi_ops->devo_bus_ops->busops_rev >= BUSO_REV_7) &&\
9587c478bd9Sstevel@tonic-gate 	(DEVI(dip)->devi_ops->devo_bus_ops->bus_power != NULL))
9597c478bd9Sstevel@tonic-gate 
9607c478bd9Sstevel@tonic-gate #define	PM_BUS_POWER_FUNC(dip)						\
9617c478bd9Sstevel@tonic-gate 	DEVI(dip)->devi_ops->devo_bus_ops->bus_power
9627c478bd9Sstevel@tonic-gate 
9637c478bd9Sstevel@tonic-gate /*
9647c478bd9Sstevel@tonic-gate  * Structure used to pass down sunpm's private data variables
9657c478bd9Sstevel@tonic-gate  * through the bus_power bus_op calls
9667c478bd9Sstevel@tonic-gate  */
9677c478bd9Sstevel@tonic-gate typedef struct pm_sp_misc {
9687c478bd9Sstevel@tonic-gate 	pm_canblock_t   pspm_canblock;
9697c478bd9Sstevel@tonic-gate 	int pspm_scan;
9707c478bd9Sstevel@tonic-gate 	int *pspm_errnop;
9717c478bd9Sstevel@tonic-gate 	int pspm_direction;
9727c478bd9Sstevel@tonic-gate } pm_sp_misc_t;
9737c478bd9Sstevel@tonic-gate 
9747c478bd9Sstevel@tonic-gate /*
9757c478bd9Sstevel@tonic-gate  * This structure is used in validating that the power level
9767c478bd9Sstevel@tonic-gate  * of the descendents are off, while a device is powered off.
9777c478bd9Sstevel@tonic-gate  */
9787c478bd9Sstevel@tonic-gate typedef struct pm_desc_pwrchk {
9797c478bd9Sstevel@tonic-gate 	dev_info_t *pdpc_dip;
9807c478bd9Sstevel@tonic-gate 	int pdpc_par_involved;
9817c478bd9Sstevel@tonic-gate } pm_desc_pwrchk_t;
9827c478bd9Sstevel@tonic-gate 
9837c478bd9Sstevel@tonic-gate 
9847c478bd9Sstevel@tonic-gate /*
9857c478bd9Sstevel@tonic-gate  * These defines are used by pm_trans_check() to calculate time.
9867c478bd9Sstevel@tonic-gate  * Mostly copied from "tzfile.h".
9877c478bd9Sstevel@tonic-gate  */
9887c478bd9Sstevel@tonic-gate #define	EPOCH_YEAR		1970
9897c478bd9Sstevel@tonic-gate #define	SECSPERMIN		60
9907c478bd9Sstevel@tonic-gate #define	MINSPERHOUR		60
9917c478bd9Sstevel@tonic-gate #define	HOURSPERDAY		24
9927c478bd9Sstevel@tonic-gate #define	DAYSPERWEEK		7
9937c478bd9Sstevel@tonic-gate #define	DAYSPERNYEAR		365
9947c478bd9Sstevel@tonic-gate #define	SECSPERHOUR		(SECSPERMIN * MINSPERHOUR)
9957c478bd9Sstevel@tonic-gate #define	SECSPERDAY		(SECSPERHOUR * HOURSPERDAY)
9967c478bd9Sstevel@tonic-gate #define	DC_SPY			(SECSPERDAY * DAYSPERNYEAR)
9977c478bd9Sstevel@tonic-gate #define	DC_SPW			(SECSPERDAY * DAYSPERWEEK)
9987c478bd9Sstevel@tonic-gate #define	DC_SPD			SECSPERDAY
9997c478bd9Sstevel@tonic-gate 
10007c478bd9Sstevel@tonic-gate #define	DC_SCSI_YEAR_LEN	4		/* YYYY */
10017c478bd9Sstevel@tonic-gate #define	DC_SCSI_WEEK_LEN	2		/* WW */
10027c478bd9Sstevel@tonic-gate #define	DC_SCSI_NPY		5		/* # power-cycle years */
10037c478bd9Sstevel@tonic-gate 
10047c478bd9Sstevel@tonic-gate #endif	/* _KERNEL */
10057c478bd9Sstevel@tonic-gate 
10067c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
10077c478bd9Sstevel@tonic-gate }
10087c478bd9Sstevel@tonic-gate #endif
10097c478bd9Sstevel@tonic-gate 
10107c478bd9Sstevel@tonic-gate #endif /* _SYS_EPM_H */
1011