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 69110e73f9Sschwartz _init(void) 70110e73f9Sschwartz { 710ad689d6Sschwartz if (fpc_init_platform_check() != SUCCESS) 720ad689d6Sschwartz return (ENODEV); 73110e73f9Sschwartz return (mod_install(&ml)); 74110e73f9Sschwartz } 75110e73f9Sschwartz 76110e73f9Sschwartz int 77110e73f9Sschwartz _info(struct modinfo *modinfop) 78110e73f9Sschwartz { 79110e73f9Sschwartz return (mod_info(&ml, modinfop)); 80110e73f9Sschwartz } 81110e73f9Sschwartz 82110e73f9Sschwartz int 83110e73f9Sschwartz _fini(void) 84110e73f9Sschwartz { 85110e73f9Sschwartz return (mod_remove(&ml)); 86110e73f9Sschwartz } 87110e73f9Sschwartz 88110e73f9Sschwartz static int 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 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