11370Sschwartz /* 21370Sschwartz * CDDL HEADER START 31370Sschwartz * 41370Sschwartz * The contents of this file are subject to the terms of the 51370Sschwartz * Common Development and Distribution License (the "License"). 61370Sschwartz * You may not use this file except in compliance with the License. 71370Sschwartz * 81370Sschwartz * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 91370Sschwartz * or http://www.opensolaris.org/os/licensing. 101370Sschwartz * See the License for the specific language governing permissions 111370Sschwartz * and limitations under the License. 121370Sschwartz * 131370Sschwartz * When distributing Covered Code, include this CDDL HEADER in each 141370Sschwartz * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 151370Sschwartz * If applicable, add the following below this CDDL HEADER, with the 161370Sschwartz * fields enclosed by brackets "[]" replaced with your own identifying 171370Sschwartz * information: Portions Copyright [yyyy] [name of copyright owner] 181370Sschwartz * 191370Sschwartz * CDDL HEADER END 201370Sschwartz */ 211370Sschwartz 221370Sschwartz /* 231370Sschwartz * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 241370Sschwartz * Use is subject to license terms. 251370Sschwartz */ 261370Sschwartz 271370Sschwartz #pragma ident "%Z%%M% %I% %E% SMI" 281370Sschwartz 291370Sschwartz #include <sys/types.h> 301370Sschwartz #include <sys/sunddi.h> 311370Sschwartz #include <sys/sunndi.h> 321370Sschwartz #include <sys/conf.h> 331370Sschwartz #include <sys/modctl.h> 341370Sschwartz #include <sys/stat.h> 351370Sschwartz #include <fpc.h> 361370Sschwartz 371370Sschwartz static int fpc_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 381370Sschwartz static int fpc_detach(dev_info_t *dip, ddi_detach_cmd_t cmd); 391370Sschwartz 401370Sschwartz static struct dev_ops fpc_ops = { 411370Sschwartz DEVO_REV, 421370Sschwartz 0, 431370Sschwartz nulldev, 441370Sschwartz nulldev, 451370Sschwartz nulldev, 461370Sschwartz fpc_attach, 471370Sschwartz fpc_detach, 481370Sschwartz nodev, 491370Sschwartz NULL, 501370Sschwartz NULL, 511370Sschwartz nodev 521370Sschwartz }; 531370Sschwartz 541370Sschwartz extern struct mod_ops mod_driverops; 551370Sschwartz 561370Sschwartz static struct modldrv md = { 571370Sschwartz &mod_driverops, 581370Sschwartz "IO Chip Perf Counter %I%", 591370Sschwartz &fpc_ops, 601370Sschwartz }; 611370Sschwartz 621370Sschwartz static struct modlinkage ml = { 631370Sschwartz MODREV_1, 641370Sschwartz (void *)&md, 651370Sschwartz NULL 661370Sschwartz }; 671370Sschwartz 681370Sschwartz int 691370Sschwartz _init(void) 701370Sschwartz { 71*1691Sschwartz if (fpc_init_platform_check() != SUCCESS) 72*1691Sschwartz return (ENODEV); 731370Sschwartz return (mod_install(&ml)); 741370Sschwartz } 751370Sschwartz 761370Sschwartz int 771370Sschwartz _info(struct modinfo *modinfop) 781370Sschwartz { 791370Sschwartz return (mod_info(&ml, modinfop)); 801370Sschwartz } 811370Sschwartz 821370Sschwartz int 831370Sschwartz _fini(void) 841370Sschwartz { 851370Sschwartz return (mod_remove(&ml)); 861370Sschwartz } 871370Sschwartz 881370Sschwartz static int 891370Sschwartz fpc_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 901370Sschwartz { 911370Sschwartz switch (cmd) { 921370Sschwartz /* 931370Sschwartz * Since the driver saves no state between calls, we can fully detach 941370Sschwartz * on suspend and fully attach on resume. 951370Sschwartz * 961370Sschwartz * An RFE might be to save event register states for restore. 971370Sschwartz * The result of not doing this is that the kstat reader (busstat) 981370Sschwartz * may quit upon resume, seeing that the events have changed out from 991370Sschwartz * underneath it (since the registers were powered off upon suspend). 1001370Sschwartz */ 1011370Sschwartz case DDI_RESUME: 1021370Sschwartz case DDI_ATTACH: 1031370Sschwartz if (fpc_kstat_init(dip) != DDI_SUCCESS) { 1041370Sschwartz (void) fpc_detach(dip, DDI_DETACH); 1051370Sschwartz return (DDI_FAILURE); 1061370Sschwartz } 1071370Sschwartz return (DDI_SUCCESS); 1081370Sschwartz default: 1091370Sschwartz return (DDI_FAILURE); 1101370Sschwartz } 1111370Sschwartz } 1121370Sschwartz 1131370Sschwartz static int 1141370Sschwartz fpc_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1151370Sschwartz { 1161370Sschwartz switch (cmd) { 1171370Sschwartz case DDI_SUSPEND: 1181370Sschwartz case DDI_DETACH: 1191370Sschwartz fpc_kstat_fini(dip); 1201370Sschwartz return (DDI_SUCCESS); 1211370Sschwartz default: 1221370Sschwartz return (DDI_FAILURE); 1231370Sschwartz } 1241370Sschwartz } 125