110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz/*
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz * CDDL HEADER START
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz *
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz * The contents of this file are subject to the terms of the
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz * Common Development and Distribution License (the "License").
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz * You may not use this file except in compliance with the License.
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz *
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz * or http://www.opensolaris.org/os/licensing.
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz * See the License for the specific language governing permissions
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz * and limitations under the License.
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz *
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz * When distributing Covered Code, include this CDDL HEADER in each
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz * If applicable, add the following below this CDDL HEADER, with the
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz * fields enclosed by brackets "[]" replaced with your own identifying
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz * information: Portions Copyright [yyyy] [name of copyright owner]
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz *
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz * CDDL HEADER END
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz */
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz/*
193974072f41a843678abf5f61979c748687e66bSherry Moore * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz * Use is subject to license terms.
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz */
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz#include <sys/types.h>
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz#include <sys/sunddi.h>
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz#include <sys/sunndi.h>
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz#include <sys/conf.h>
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz#include <sys/modctl.h>
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz#include <sys/stat.h>
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz#include <fpc.h>
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartzstatic int fpc_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartzstatic int fpc_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartzstatic struct dev_ops fpc_ops = {
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz DEVO_REV,
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz 0,
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz nulldev,
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz nulldev,
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz nulldev,
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz fpc_attach,
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz fpc_detach,
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz nodev,
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz NULL,
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz NULL,
193974072f41a843678abf5f61979c748687e66bSherry Moore nodev,
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_quiesce_not_needed, /* quiesce */
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz};
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartzextern struct mod_ops mod_driverops;
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartzstatic struct modldrv md = {
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz &mod_driverops,
193974072f41a843678abf5f61979c748687e66bSherry Moore "IO Chip Perf Counter",
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz &fpc_ops,
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz};
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartzstatic struct modlinkage ml = {
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz MODREV_1,
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz (void *)&md,
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz NULL
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz};
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartzint
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz_init(void)
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz{
0ad689d678ef901f32945172f48ddc7b16dde50dschwartz if (fpc_init_platform_check() != SUCCESS)
0ad689d678ef901f32945172f48ddc7b16dde50dschwartz return (ENODEV);
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz return (mod_install(&ml));
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz}
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartzint
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz_info(struct modinfo *modinfop)
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz{
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz return (mod_info(&ml, modinfop));
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz}
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartzint
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz_fini(void)
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz{
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz return (mod_remove(&ml));
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz}
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartzstatic int
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartzfpc_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz{
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz switch (cmd) {
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz /*
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz * Since the driver saves no state between calls, we can fully detach
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz * on suspend and fully attach on resume.
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz *
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz * An RFE might be to save event register states for restore.
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz * The result of not doing this is that the kstat reader (busstat)
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz * may quit upon resume, seeing that the events have changed out from
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz * underneath it (since the registers were powered off upon suspend).
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz */
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz case DDI_RESUME:
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz case DDI_ATTACH:
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz if (fpc_kstat_init(dip) != DDI_SUCCESS) {
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz (void) fpc_detach(dip, DDI_DETACH);
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz return (DDI_FAILURE);
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz }
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz return (DDI_SUCCESS);
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz default:
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz return (DDI_FAILURE);
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz }
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz}
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartzstatic int
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartzfpc_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz{
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz switch (cmd) {
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz case DDI_SUSPEND:
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz case DDI_DETACH:
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz fpc_kstat_fini(dip);
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz return (DDI_SUCCESS);
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz default:
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz return (DDI_FAILURE);
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz }
110e73f9b5ccaa10e26a8f79807001a5da72604eschwartz}