xref: /illumos-gate/usr/src/uts/sun4/io/fpc/fpc.c (revision 19397407)
1110e73f9Sschwartz /*
2110e73f9Sschwartz  * CDDL HEADER START
3110e73f9Sschwartz  *
4110e73f9Sschwartz  * The contents of this file are subject to the terms of the
5110e73f9Sschwartz  * Common Development and Distribution License (the "License").
6110e73f9Sschwartz  * You may not use this file except in compliance with the License.
7110e73f9Sschwartz  *
8110e73f9Sschwartz  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9110e73f9Sschwartz  * or http://www.opensolaris.org/os/licensing.
10110e73f9Sschwartz  * See the License for the specific language governing permissions
11110e73f9Sschwartz  * and limitations under the License.
12110e73f9Sschwartz  *
13110e73f9Sschwartz  * When distributing Covered Code, include this CDDL HEADER in each
14110e73f9Sschwartz  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15110e73f9Sschwartz  * If applicable, add the following below this CDDL HEADER, with the
16110e73f9Sschwartz  * fields enclosed by brackets "[]" replaced with your own identifying
17110e73f9Sschwartz  * information: Portions Copyright [yyyy] [name of copyright owner]
18110e73f9Sschwartz  *
19110e73f9Sschwartz  * CDDL HEADER END
20110e73f9Sschwartz  */
21110e73f9Sschwartz 
22110e73f9Sschwartz /*
23*19397407SSherry Moore  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24110e73f9Sschwartz  * Use is subject to license terms.
25110e73f9Sschwartz  */
26110e73f9Sschwartz 
27110e73f9Sschwartz 
28110e73f9Sschwartz #include <sys/types.h>
29110e73f9Sschwartz #include <sys/sunddi.h>
30110e73f9Sschwartz #include <sys/sunndi.h>
31110e73f9Sschwartz #include <sys/conf.h>
32110e73f9Sschwartz #include <sys/modctl.h>
33110e73f9Sschwartz #include <sys/stat.h>
34110e73f9Sschwartz #include <fpc.h>
35110e73f9Sschwartz 
36110e73f9Sschwartz static int fpc_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
37110e73f9Sschwartz static int fpc_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
38110e73f9Sschwartz 
39110e73f9Sschwartz static struct dev_ops fpc_ops = {
40110e73f9Sschwartz 	DEVO_REV,
41110e73f9Sschwartz 	0,
42110e73f9Sschwartz 	nulldev,
43110e73f9Sschwartz 	nulldev,
44110e73f9Sschwartz 	nulldev,
45110e73f9Sschwartz 	fpc_attach,
46110e73f9Sschwartz 	fpc_detach,
47110e73f9Sschwartz 	nodev,
48110e73f9Sschwartz 	NULL,
49110e73f9Sschwartz 	NULL,
50*19397407SSherry Moore 	nodev,
51*19397407SSherry Moore 	ddi_quiesce_not_needed,		/* quiesce */
52110e73f9Sschwartz };
53110e73f9Sschwartz 
54110e73f9Sschwartz extern struct mod_ops mod_driverops;
55110e73f9Sschwartz 
56110e73f9Sschwartz static struct modldrv md = {
57110e73f9Sschwartz 	&mod_driverops,
58*19397407SSherry Moore 	"IO Chip Perf Counter",
59110e73f9Sschwartz 	&fpc_ops,
60110e73f9Sschwartz };
61110e73f9Sschwartz 
62110e73f9Sschwartz static struct modlinkage ml = {
63110e73f9Sschwartz 	MODREV_1,
64110e73f9Sschwartz 	(void *)&md,
65110e73f9Sschwartz 	NULL
66110e73f9Sschwartz };
67110e73f9Sschwartz 
68110e73f9Sschwartz int
_init(void)69110e73f9Sschwartz _init(void)
70110e73f9Sschwartz {
710ad689d6Sschwartz 	if (fpc_init_platform_check() != SUCCESS)
720ad689d6Sschwartz 		return (ENODEV);
73110e73f9Sschwartz 	return (mod_install(&ml));
74110e73f9Sschwartz }
75110e73f9Sschwartz 
76110e73f9Sschwartz int
_info(struct modinfo * modinfop)77110e73f9Sschwartz _info(struct modinfo *modinfop)
78110e73f9Sschwartz {
79110e73f9Sschwartz 	return (mod_info(&ml, modinfop));
80110e73f9Sschwartz }
81110e73f9Sschwartz 
82110e73f9Sschwartz int
_fini(void)83110e73f9Sschwartz _fini(void)
84110e73f9Sschwartz {
85110e73f9Sschwartz 	return (mod_remove(&ml));
86110e73f9Sschwartz }
87110e73f9Sschwartz 
88110e73f9Sschwartz static int
fpc_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)89110e73f9Sschwartz fpc_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
90110e73f9Sschwartz {
91110e73f9Sschwartz 	switch (cmd) {
92110e73f9Sschwartz 	/*
93110e73f9Sschwartz 	 * Since the driver saves no state between calls, we can fully detach
94110e73f9Sschwartz 	 * on suspend and fully attach on resume.
95110e73f9Sschwartz 	 *
96110e73f9Sschwartz 	 * An RFE might be to save event register states for restore.
97110e73f9Sschwartz 	 * The result of not doing this is that the kstat reader (busstat)
98110e73f9Sschwartz 	 * may quit upon resume, seeing that the events have changed out from
99110e73f9Sschwartz 	 * underneath it (since the registers were powered off upon suspend).
100110e73f9Sschwartz 	 */
101110e73f9Sschwartz 	case DDI_RESUME:
102110e73f9Sschwartz 	case DDI_ATTACH:
103110e73f9Sschwartz 		if (fpc_kstat_init(dip) != DDI_SUCCESS) {
104110e73f9Sschwartz 			(void) fpc_detach(dip, DDI_DETACH);
105110e73f9Sschwartz 			return (DDI_FAILURE);
106110e73f9Sschwartz 		}
107110e73f9Sschwartz 		return (DDI_SUCCESS);
108110e73f9Sschwartz 	default:
109110e73f9Sschwartz 		return (DDI_FAILURE);
110110e73f9Sschwartz 	}
111110e73f9Sschwartz }
112110e73f9Sschwartz 
113110e73f9Sschwartz static int
fpc_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)114110e73f9Sschwartz fpc_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
115110e73f9Sschwartz {
116110e73f9Sschwartz 	switch (cmd) {
117110e73f9Sschwartz 	case DDI_SUSPEND:
118110e73f9Sschwartz 	case DDI_DETACH:
119110e73f9Sschwartz 		fpc_kstat_fini(dip);
120110e73f9Sschwartz 		return (DDI_SUCCESS);
121110e73f9Sschwartz 	default:
122110e73f9Sschwartz 		return (DDI_FAILURE);
123110e73f9Sschwartz 	}
124110e73f9Sschwartz }
125