25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * CDDL HEADER START
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * The contents of this file are subject to the terms of the
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Common Development and Distribution License (the "License").
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * You may not use this file except in compliance with the License.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * or http://www.opensolaris.org/os/licensing.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * See the License for the specific language governing permissions
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * and limitations under the License.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * When distributing Covered Code, include this CDDL HEADER in each
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * If applicable, add the following below this CDDL HEADER, with the
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * fields enclosed by brackets "[]" replaced with your own identifying
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * information: Portions Copyright [yyyy] [name of copyright owner]
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * CDDL HEADER END
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
193974072f41a843678abf5f61979c748687e66bSherry Moore
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * All Rights Reserved, Copyright (c) FUJITSU LIMITED 2006
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
193974072f41a843678abf5f61979c748687e66bSherry Moore/*
a1bf6e2eba3dc9acc46299eac9c6ef1bc1e15c2bChristopher Baumbauer - Oracle America - San Diego United States * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
193974072f41a843678abf5f61979c748687e66bSherry Moore */
193974072f41a843678abf5f61979c748687e66bSherry Moore
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/types.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/time.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/errno.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/cmn_err.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/param.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/modctl.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/conf.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/open.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/stat.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/ddi.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/sunddi.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/file.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/intr.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/machsystm.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define PNLIE_MASK 0x010 /* interrupt enable/disable */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define PNLINT_MASK 0x001 /* interrupted flag */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#ifdef DEBUG
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint panel_debug = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic void panel_ddi_put8(ddi_acc_handle_t, uint8_t *, uint8_t);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define DCMN_ERR(x) if (panel_debug) cmn_err x
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#else
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define DCMN_ERR(x)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define panel_ddi_put8(x, y, z) ddi_put8(x, y, z)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#endif
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int panel_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int panel_attach(dev_info_t *, ddi_attach_cmd_t);
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int panel_detach(dev_info_t *, ddi_detach_cmd_t);
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic uint_t panel_intr(caddr_t);
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int panel_open(dev_t *, int, int, cred_t *);
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int panel_close(dev_t, int, int, cred_t *);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic char *panel_name = "oplpanel";
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint panel_enable = 1; /* enable or disable */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
b0fc0e77220f1fa4c933fd58a4e1dedcd650b0f1govindaextern uint64_t cpc_level15_inum; /* in cpc_subr.c */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstruct panel_state {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl dev_info_t *dip;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_iblock_cookie_t iblock_cookie;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_acc_handle_t panel_regs_handle;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl uint8_t *panelregs; /* mapping address */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl uint8_t panelregs_state; /* keeping regs. */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl};
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstruct cb_ops panel_cb_ops = {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* open */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* close */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* strategy */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* print */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* dump */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* read */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* write */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* ioctl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* devmap */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* mmap */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* segmap */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nochpoll, /* poll */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* prop_op */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl NULL, /* streamtab */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl D_NEW | D_MP | D_HOTPLUG, /* flag */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl CB_REV, /* cb_rev */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* async I/O read entry point */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev /* async I/O write entry point */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl};
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic struct dev_ops panel_dev_ops = {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DEVO_REV, /* driver build version */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl 0, /* device reference count */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl panel_getinfo, /* getinfo */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nulldev, /* identify */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nulldev, /* probe */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl panel_attach, /* attach */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl panel_detach, /* detach */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nulldev, /* reset */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &panel_cb_ops, /* cb_ops */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl NULL, /* bus_ops */
193974072f41a843678abf5f61979c748687e66bSherry Moore nulldev, /* power */
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_quiesce_not_supported, /* devo_quiesce */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl};
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/* module configuration stuff */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic void *panelstates;
25cf1a301a396c38e8adf52c15f537b80d2483f7jlextern struct mod_ops mod_driverops;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic struct modldrv modldrv = {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &mod_driverops,
193974072f41a843678abf5f61979c748687e66bSherry Moore "OPL panel driver",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &panel_dev_ops
25cf1a301a396c38e8adf52c15f537b80d2483f7jl};
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic struct modlinkage modlinkage = {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl MODREV_1,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &modldrv,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl 0
25cf1a301a396c38e8adf52c15f537b80d2483f7jl};
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jl_init(void)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int status;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DCMN_ERR((CE_CONT, "%s: _init\n", panel_name));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl status = ddi_soft_state_init(&panelstates,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl sizeof (struct panel_state), 0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (status != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "%s: ddi_soft_state_init failed.",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl panel_name);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (status);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl status = mod_install(&modlinkage);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (status != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_soft_state_fini(&panelstates);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (status);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jl_fini(void)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Can't unload to make sure the panel switch always works.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EBUSY);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jl_info(struct modinfo *modinfop)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (mod_info(&modlinkage, modinfop));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int
25cf1a301a396c38e8adf52c15f537b80d2483f7jlpanel_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int instance;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl struct panel_state *statep = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_device_acc_attr_t access_attr = {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DDI_DEVICE_ATTR_V0,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DDI_STRUCTURE_BE_ACC,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DDI_STRICTORDER_ACC
25cf1a301a396c38e8adf52c15f537b80d2483f7jl };
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl instance = ddi_get_instance(dip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DCMN_ERR((CE_CONT, "%s%d: attach\n", panel_name, instance));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl switch (cmd) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case DDI_ATTACH:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DCMN_ERR((CE_CONT, "%s%d: DDI_ATTACH\n",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl panel_name, instance));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case DDI_RESUME:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DCMN_ERR((CE_CONT, "%s%d: DDI_RESUME\n",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl panel_name, instance));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((statep = (struct panel_state *)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_get_soft_state(panelstates, instance)) == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "%s%d: ddi_get_soft_state failed.",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl panel_name, instance);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_FAILURE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* enable the interrupt just in case */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl panel_ddi_put8(statep->panel_regs_handle, statep->panelregs,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl statep->panelregs_state);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl default:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_FAILURE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Attach routine
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* alloc and get soft state */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ddi_soft_state_zalloc(panelstates, instance) != DDI_SUCCESS) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "%s%d: ddi_soft_state_zalloc failed.",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl panel_name, instance);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl goto attach_failed2;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((statep = (struct panel_state *)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_get_soft_state(panelstates, instance)) == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "%s%d: ddi_get_soft_state failed.",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl panel_name, instance);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl goto attach_failed1;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* set the dip in the soft state */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl statep->dip = dip;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* mapping register */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ddi_regs_map_setup(dip, 0, (caddr_t *)&statep->panelregs,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl 0, 0, /* the entire space is mapped */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &access_attr, &statep->panel_regs_handle) != DDI_SUCCESS) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "%s%d: ddi_regs_map_setup failed.",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl panel_name, instance);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl goto attach_failed1;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* setup the interrupt handler */
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) ddi_get_iblock_cookie(dip, 0, &statep->iblock_cookie);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ddi_add_intr(dip, 0, &statep->iblock_cookie, 0, &panel_intr,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (caddr_t)statep) != DDI_SUCCESS) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "%s%d: cannot add interrupt handler.",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl panel_name, instance);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl goto attach_failed0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* ATTACH SUCCESS */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* announce the device */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_report_dev(dip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* turn on interrupt */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl statep->panelregs_state = 0 | PNLIE_MASK;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl panel_ddi_put8(statep->panel_regs_handle, statep->panelregs,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl statep->panelregs_state);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlattach_failed0:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_regs_map_free(&statep->panel_regs_handle);
25cf1a301a396c38e8adf52c15f537b80d2483f7jlattach_failed1:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_soft_state_free(panelstates, instance);
25cf1a301a396c38e8adf52c15f537b80d2483f7jlattach_failed2:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DCMN_ERR((CE_NOTE, "%s%d: attach failed", panel_name, instance));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_FAILURE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int
25cf1a301a396c38e8adf52c15f537b80d2483f7jlpanel_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int instance;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl struct panel_state *statep;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl instance = ddi_get_instance(dip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DCMN_ERR((CE_CONT, "%s%d: detach\n", panel_name, instance));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((statep = (struct panel_state *)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_get_soft_state(panelstates, instance)) == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "%s%d: ddi_get_soft_state failed.",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl panel_name, instance);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_FAILURE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl switch (cmd) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case DDI_DETACH:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DCMN_ERR((CE_CONT, "%s%d: DDI_DETACH\n",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl panel_name, instance));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* turn off interrupt */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl statep->panelregs_state &= ~PNLIE_MASK;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl panel_ddi_put8(statep->panel_regs_handle, statep->panelregs,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl statep->panelregs_state);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* free all resources for the dip */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_remove_intr(dip, 0, statep->iblock_cookie);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* need not free iblock_cookie */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_regs_map_free(&statep->panel_regs_handle);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_soft_state_free(panelstates, instance);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case DDI_SUSPEND:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DCMN_ERR((CE_CONT, "%s%d: DDI_SUSPEND\n",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl panel_name, instance));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl default:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_FAILURE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Not reached */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*ARGSUSED*/
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int
25cf1a301a396c38e8adf52c15f537b80d2483f7jlpanel_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl struct panel_state *statep;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int instance;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl dev_t dev = (dev_t)arg;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl instance = getminor(dev);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DCMN_ERR((CE_CONT, "%s%d: getinfo\n", panel_name, instance));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl switch (cmd) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case DDI_INFO_DEVT2DEVINFO:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((statep = (struct panel_state *)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_get_soft_state(panelstates, instance)) == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "%s%d: ddi_get_soft_state failed.",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl panel_name, instance);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *resultp = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_FAILURE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *resultp = statep->dip;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case DDI_INFO_DEVT2INSTANCE:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *resultp = (void *)(uintptr_t)instance;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl default:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_FAILURE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic uint_t
25cf1a301a396c38e8adf52c15f537b80d2483f7jlpanel_intr(caddr_t arg)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl struct panel_state *statep = (struct panel_state *)arg;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* to confirm the validity of the interrupt */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (!(ddi_get8(statep->panel_regs_handle, statep->panelregs) &
25cf1a301a396c38e8adf52c15f537b80d2483f7jl PNLINT_MASK)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_INTR_UNCLAIMED);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
97cc145da041e216ed7f1da0e02b877050900e88hyw /*
97cc145da041e216ed7f1da0e02b877050900e88hyw * Clear the PNLINT bit
97cc145da041e216ed7f1da0e02b877050900e88hyw * HW reported that there might be a delay in the PNLINT bit
97cc145da041e216ed7f1da0e02b877050900e88hyw * clearing. We force synchronization by attempting to read
97cc145da041e216ed7f1da0e02b877050900e88hyw * back the reg after clearing the bit.
97cc145da041e216ed7f1da0e02b877050900e88hyw */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl panel_ddi_put8(statep->panel_regs_handle, statep->panelregs,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl statep->panelregs_state | PNLINT_MASK);
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) ddi_get8(statep->panel_regs_handle, statep->panelregs);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (panel_enable) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* avoid double panic */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl panel_enable = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_PANIC,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "System Panel Driver: Emergency panic request "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "detected!");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Not reached */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_INTR_CLAIMED);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#ifdef DEBUG
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic void
25cf1a301a396c38e8adf52c15f537b80d2483f7jlpanel_ddi_put8(ddi_acc_handle_t handle, uint8_t *dev_addr, uint8_t value)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (panel_debug) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_CONT, "%s: old value = 0x%x\n",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl panel_name, ddi_get8(handle, dev_addr));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_CONT, "%s: writing value = 0x%x\n",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl panel_name, value);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_put8(handle, dev_addr, value);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_CONT, "%s: new value = 0x%x\n",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl panel_name, ddi_get8(handle, dev_addr));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_put8(handle, dev_addr, value);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#endif