xref: /titanic_52/usr/src/uts/sun4u/opl/io/oplpanel/oplpanel.c (revision a1bf6e2eba3dc9acc46299eac9c6ef1bc1e15c2b)
125cf1a30Sjl139090 /*
225cf1a30Sjl139090  * CDDL HEADER START
325cf1a30Sjl139090  *
425cf1a30Sjl139090  * The contents of this file are subject to the terms of the
525cf1a30Sjl139090  * Common Development and Distribution License (the "License").
625cf1a30Sjl139090  * You may not use this file except in compliance with the License.
725cf1a30Sjl139090  *
825cf1a30Sjl139090  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
925cf1a30Sjl139090  * or http://www.opensolaris.org/os/licensing.
1025cf1a30Sjl139090  * See the License for the specific language governing permissions
1125cf1a30Sjl139090  * and limitations under the License.
1225cf1a30Sjl139090  *
1325cf1a30Sjl139090  * When distributing Covered Code, include this CDDL HEADER in each
1425cf1a30Sjl139090  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1525cf1a30Sjl139090  * If applicable, add the following below this CDDL HEADER, with the
1625cf1a30Sjl139090  * fields enclosed by brackets "[]" replaced with your own identifying
1725cf1a30Sjl139090  * information: Portions Copyright [yyyy] [name of copyright owner]
1825cf1a30Sjl139090  *
1925cf1a30Sjl139090  * CDDL HEADER END
2025cf1a30Sjl139090  */
2119397407SSherry Moore 
2225cf1a30Sjl139090 /*
2325cf1a30Sjl139090  * All Rights Reserved, Copyright (c) FUJITSU LIMITED 2006
2425cf1a30Sjl139090  */
2525cf1a30Sjl139090 
2619397407SSherry Moore /*
27*a1bf6e2eSChristopher Baumbauer - Oracle America - San Diego United States  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
2819397407SSherry Moore  */
2919397407SSherry Moore 
3025cf1a30Sjl139090 
3125cf1a30Sjl139090 #include <sys/types.h>
3225cf1a30Sjl139090 #include <sys/time.h>
3325cf1a30Sjl139090 #include <sys/errno.h>
3425cf1a30Sjl139090 #include <sys/cmn_err.h>
3525cf1a30Sjl139090 #include <sys/param.h>
3625cf1a30Sjl139090 #include <sys/modctl.h>
3725cf1a30Sjl139090 #include <sys/conf.h>
3825cf1a30Sjl139090 #include <sys/open.h>
3925cf1a30Sjl139090 #include <sys/stat.h>
4025cf1a30Sjl139090 #include <sys/ddi.h>
4125cf1a30Sjl139090 #include <sys/sunddi.h>
4225cf1a30Sjl139090 #include <sys/file.h>
4325cf1a30Sjl139090 #include <sys/intr.h>
4425cf1a30Sjl139090 #include <sys/machsystm.h>
4525cf1a30Sjl139090 
4625cf1a30Sjl139090 #define	PNLIE_MASK	0x010	/* interrupt enable/disable */
4725cf1a30Sjl139090 #define	PNLINT_MASK	0x001	/* interrupted flag */
4825cf1a30Sjl139090 
4925cf1a30Sjl139090 #ifdef DEBUG
5025cf1a30Sjl139090 int panel_debug = 0;
5125cf1a30Sjl139090 static void panel_ddi_put8(ddi_acc_handle_t, uint8_t *, uint8_t);
5225cf1a30Sjl139090 #define	DCMN_ERR(x)	if (panel_debug) cmn_err x
5325cf1a30Sjl139090 
5425cf1a30Sjl139090 #else
5525cf1a30Sjl139090 
5625cf1a30Sjl139090 #define	DCMN_ERR(x)
5725cf1a30Sjl139090 #define	panel_ddi_put8(x, y, z)	ddi_put8(x, y, z)
5825cf1a30Sjl139090 
5925cf1a30Sjl139090 #endif
6025cf1a30Sjl139090 
6125cf1a30Sjl139090 static int	panel_getinfo(dev_info_t *, ddi_info_cmd_t, void *,  void **);
6225cf1a30Sjl139090 static int	panel_attach(dev_info_t *, ddi_attach_cmd_t);
6325cf1a30Sjl139090 static int	panel_detach(dev_info_t *, ddi_detach_cmd_t);
6425cf1a30Sjl139090 static uint_t	panel_intr(caddr_t);
6525cf1a30Sjl139090 static int	panel_open(dev_t *, int, int, cred_t *);
6625cf1a30Sjl139090 static int	panel_close(dev_t, int, int, cred_t *);
6725cf1a30Sjl139090 
6825cf1a30Sjl139090 static char	*panel_name = "oplpanel";
6925cf1a30Sjl139090 int		panel_enable = 1;	/* enable or disable */
7025cf1a30Sjl139090 
71b0fc0e77Sgovinda extern uint64_t	cpc_level15_inum;	/* in cpc_subr.c */
7225cf1a30Sjl139090 
7325cf1a30Sjl139090 struct panel_state {
7425cf1a30Sjl139090 	dev_info_t		*dip;
7525cf1a30Sjl139090 	ddi_iblock_cookie_t	iblock_cookie;
7625cf1a30Sjl139090 	ddi_acc_handle_t	panel_regs_handle;
7725cf1a30Sjl139090 	uint8_t			*panelregs;		/* mapping address */
7825cf1a30Sjl139090 	uint8_t			panelregs_state;	/* keeping regs. */
7925cf1a30Sjl139090 };
8025cf1a30Sjl139090 
8125cf1a30Sjl139090 struct cb_ops panel_cb_ops = {
8225cf1a30Sjl139090 	nodev,		/* open */
8325cf1a30Sjl139090 	nodev,		/* close */
8425cf1a30Sjl139090 	nodev,		/* strategy */
8525cf1a30Sjl139090 	nodev,		/* print */
8625cf1a30Sjl139090 	nodev,		/* dump */
8725cf1a30Sjl139090 	nodev,		/* read */
8825cf1a30Sjl139090 	nodev,		/* write */
8925cf1a30Sjl139090 	nodev,		/* ioctl */
9025cf1a30Sjl139090 	nodev,		/* devmap */
9125cf1a30Sjl139090 	nodev,		/* mmap */
9225cf1a30Sjl139090 	nodev,		/* segmap */
9325cf1a30Sjl139090 	nochpoll,	/* poll */
9425cf1a30Sjl139090 	nodev,		/* prop_op */
9525cf1a30Sjl139090 	NULL,		/* streamtab */
9625cf1a30Sjl139090 	D_NEW | D_MP | D_HOTPLUG,	/* flag */
9725cf1a30Sjl139090 	CB_REV,		/* cb_rev */
9825cf1a30Sjl139090 	nodev,		/* async I/O read entry point */
9925cf1a30Sjl139090 	nodev		/* async I/O write entry point */
10025cf1a30Sjl139090 };
10125cf1a30Sjl139090 
10225cf1a30Sjl139090 static struct dev_ops panel_dev_ops = {
10325cf1a30Sjl139090 	DEVO_REV,		/* driver build version */
10425cf1a30Sjl139090 	0,			/* device reference count */
10525cf1a30Sjl139090 	panel_getinfo,		/* getinfo */
10625cf1a30Sjl139090 	nulldev,		/* identify */
10725cf1a30Sjl139090 	nulldev,		/* probe */
10825cf1a30Sjl139090 	panel_attach,		/* attach */
10925cf1a30Sjl139090 	panel_detach,		/* detach */
11025cf1a30Sjl139090 	nulldev,		/* reset */
11125cf1a30Sjl139090 	&panel_cb_ops,		/* cb_ops */
11225cf1a30Sjl139090 	NULL,			/* bus_ops */
11319397407SSherry Moore 	nulldev,		/* power */
11419397407SSherry Moore 	ddi_quiesce_not_supported,	/* devo_quiesce */
11525cf1a30Sjl139090 };
11625cf1a30Sjl139090 
11725cf1a30Sjl139090 /* module configuration stuff */
11825cf1a30Sjl139090 static void		*panelstates;
11925cf1a30Sjl139090 extern struct mod_ops	mod_driverops;
12025cf1a30Sjl139090 
12125cf1a30Sjl139090 static struct modldrv modldrv = {
12225cf1a30Sjl139090 	&mod_driverops,
12319397407SSherry Moore 	"OPL panel driver",
12425cf1a30Sjl139090 	&panel_dev_ops
12525cf1a30Sjl139090 };
12625cf1a30Sjl139090 
12725cf1a30Sjl139090 static struct modlinkage modlinkage = {
12825cf1a30Sjl139090 	MODREV_1,
12925cf1a30Sjl139090 	&modldrv,
13025cf1a30Sjl139090 	0
13125cf1a30Sjl139090 };
13225cf1a30Sjl139090 
13325cf1a30Sjl139090 
13425cf1a30Sjl139090 int
13525cf1a30Sjl139090 _init(void)
13625cf1a30Sjl139090 {
13725cf1a30Sjl139090 	int	status;
13825cf1a30Sjl139090 
13925cf1a30Sjl139090 	DCMN_ERR((CE_CONT, "%s: _init\n", panel_name));
14025cf1a30Sjl139090 
14125cf1a30Sjl139090 	status = ddi_soft_state_init(&panelstates,
14225cf1a30Sjl139090 	    sizeof (struct panel_state), 0);
14325cf1a30Sjl139090 	if (status != 0) {
14425cf1a30Sjl139090 		cmn_err(CE_WARN, "%s: ddi_soft_state_init failed.",
14525cf1a30Sjl139090 		    panel_name);
14625cf1a30Sjl139090 		return (status);
14725cf1a30Sjl139090 	}
14825cf1a30Sjl139090 
14925cf1a30Sjl139090 	status = mod_install(&modlinkage);
15025cf1a30Sjl139090 	if (status != 0) {
15125cf1a30Sjl139090 		ddi_soft_state_fini(&panelstates);
15225cf1a30Sjl139090 	}
15325cf1a30Sjl139090 
15425cf1a30Sjl139090 	return (status);
15525cf1a30Sjl139090 }
15625cf1a30Sjl139090 
15725cf1a30Sjl139090 int
15825cf1a30Sjl139090 _fini(void)
15925cf1a30Sjl139090 {
16025cf1a30Sjl139090 	/*
16125cf1a30Sjl139090 	 * Can't unload to make sure the panel switch always works.
16225cf1a30Sjl139090 	 */
16325cf1a30Sjl139090 	return (EBUSY);
16425cf1a30Sjl139090 }
16525cf1a30Sjl139090 
16625cf1a30Sjl139090 int
16725cf1a30Sjl139090 _info(struct modinfo *modinfop)
16825cf1a30Sjl139090 {
16925cf1a30Sjl139090 	return (mod_info(&modlinkage, modinfop));
17025cf1a30Sjl139090 }
17125cf1a30Sjl139090 
17225cf1a30Sjl139090 static int
17325cf1a30Sjl139090 panel_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
17425cf1a30Sjl139090 {
17525cf1a30Sjl139090 
17625cf1a30Sjl139090 	int instance;
17725cf1a30Sjl139090 	struct panel_state *statep = NULL;
17825cf1a30Sjl139090 
17925cf1a30Sjl139090 	ddi_device_acc_attr_t access_attr = {
18025cf1a30Sjl139090 		DDI_DEVICE_ATTR_V0,
18125cf1a30Sjl139090 		DDI_STRUCTURE_BE_ACC,
18225cf1a30Sjl139090 		DDI_STRICTORDER_ACC
18325cf1a30Sjl139090 	};
18425cf1a30Sjl139090 
18525cf1a30Sjl139090 	instance = ddi_get_instance(dip);
18625cf1a30Sjl139090 
18725cf1a30Sjl139090 	DCMN_ERR((CE_CONT, "%s%d: attach\n", panel_name, instance));
18825cf1a30Sjl139090 
18925cf1a30Sjl139090 	switch (cmd) {
19025cf1a30Sjl139090 	case DDI_ATTACH:
19125cf1a30Sjl139090 		DCMN_ERR((CE_CONT, "%s%d: DDI_ATTACH\n",
19225cf1a30Sjl139090 		    panel_name, instance));
19325cf1a30Sjl139090 		break;
19425cf1a30Sjl139090 
19525cf1a30Sjl139090 	case DDI_RESUME:
19625cf1a30Sjl139090 		DCMN_ERR((CE_CONT, "%s%d: DDI_RESUME\n",
19725cf1a30Sjl139090 		    panel_name, instance));
19825cf1a30Sjl139090 
19925cf1a30Sjl139090 		if ((statep = (struct panel_state *)
20025cf1a30Sjl139090 		    ddi_get_soft_state(panelstates, instance)) == NULL) {
20125cf1a30Sjl139090 			cmn_err(CE_WARN, "%s%d: ddi_get_soft_state failed.",
20225cf1a30Sjl139090 			    panel_name, instance);
20325cf1a30Sjl139090 			return (DDI_FAILURE);
20425cf1a30Sjl139090 		}
20525cf1a30Sjl139090 
20625cf1a30Sjl139090 		/* enable the interrupt just in case */
20725cf1a30Sjl139090 		panel_ddi_put8(statep->panel_regs_handle, statep->panelregs,
20825cf1a30Sjl139090 		    statep->panelregs_state);
20925cf1a30Sjl139090 		return (DDI_SUCCESS);
21025cf1a30Sjl139090 
21125cf1a30Sjl139090 	default:
21225cf1a30Sjl139090 		return (DDI_FAILURE);
21325cf1a30Sjl139090 	}
21425cf1a30Sjl139090 
21525cf1a30Sjl139090 	/*
21625cf1a30Sjl139090 	 * Attach routine
21725cf1a30Sjl139090 	 */
21825cf1a30Sjl139090 
21925cf1a30Sjl139090 	/* alloc and get soft state */
22025cf1a30Sjl139090 	if (ddi_soft_state_zalloc(panelstates, instance) != DDI_SUCCESS) {
22125cf1a30Sjl139090 		cmn_err(CE_WARN, "%s%d: ddi_soft_state_zalloc failed.",
22225cf1a30Sjl139090 		    panel_name, instance);
22325cf1a30Sjl139090 		goto attach_failed2;
22425cf1a30Sjl139090 	}
22525cf1a30Sjl139090 	if ((statep = (struct panel_state *)
22625cf1a30Sjl139090 	    ddi_get_soft_state(panelstates, instance)) == NULL) {
22725cf1a30Sjl139090 		cmn_err(CE_WARN, "%s%d: ddi_get_soft_state failed.",
22825cf1a30Sjl139090 		    panel_name, instance);
22925cf1a30Sjl139090 		goto attach_failed1;
23025cf1a30Sjl139090 	}
23125cf1a30Sjl139090 
23225cf1a30Sjl139090 	/* set the dip in the soft state */
23325cf1a30Sjl139090 	statep->dip = dip;
23425cf1a30Sjl139090 
23525cf1a30Sjl139090 	/* mapping register */
23625cf1a30Sjl139090 	if (ddi_regs_map_setup(dip, 0, (caddr_t *)&statep->panelregs,
23725cf1a30Sjl139090 	    0, 0, /* the entire space is mapped */
23825cf1a30Sjl139090 	    &access_attr, &statep->panel_regs_handle) != DDI_SUCCESS) {
23925cf1a30Sjl139090 		cmn_err(CE_WARN, "%s%d: ddi_regs_map_setup failed.",
24025cf1a30Sjl139090 		    panel_name, instance);
24125cf1a30Sjl139090 		goto attach_failed1;
24225cf1a30Sjl139090 	}
24325cf1a30Sjl139090 
24425cf1a30Sjl139090 	/* setup the interrupt handler */
24507d06da5SSurya Prakki 	(void) ddi_get_iblock_cookie(dip, 0, &statep->iblock_cookie);
24625cf1a30Sjl139090 	if (ddi_add_intr(dip, 0, &statep->iblock_cookie, 0, &panel_intr,
24725cf1a30Sjl139090 	    (caddr_t)statep) != DDI_SUCCESS) {
24825cf1a30Sjl139090 		cmn_err(CE_WARN, "%s%d: cannot add interrupt handler.",
24925cf1a30Sjl139090 		    panel_name, instance);
25025cf1a30Sjl139090 		goto attach_failed0;
25125cf1a30Sjl139090 	}
25225cf1a30Sjl139090 
25325cf1a30Sjl139090 	/* ATTACH SUCCESS */
25425cf1a30Sjl139090 
25525cf1a30Sjl139090 	/* announce the device */
25625cf1a30Sjl139090 	ddi_report_dev(dip);
25725cf1a30Sjl139090 
25825cf1a30Sjl139090 	/* turn on interrupt */
25925cf1a30Sjl139090 	statep->panelregs_state = 0 | PNLIE_MASK;
26025cf1a30Sjl139090 	panel_ddi_put8(statep->panel_regs_handle, statep->panelregs,
26125cf1a30Sjl139090 	    statep->panelregs_state);
26225cf1a30Sjl139090 
26325cf1a30Sjl139090 	return (DDI_SUCCESS);
26425cf1a30Sjl139090 
26525cf1a30Sjl139090 attach_failed0:
26625cf1a30Sjl139090 	ddi_regs_map_free(&statep->panel_regs_handle);
26725cf1a30Sjl139090 attach_failed1:
26825cf1a30Sjl139090 	ddi_soft_state_free(panelstates, instance);
26925cf1a30Sjl139090 attach_failed2:
27025cf1a30Sjl139090 	DCMN_ERR((CE_NOTE, "%s%d: attach failed", panel_name, instance));
27125cf1a30Sjl139090 	return (DDI_FAILURE);
27225cf1a30Sjl139090 }
27325cf1a30Sjl139090 
27425cf1a30Sjl139090 static int
27525cf1a30Sjl139090 panel_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
27625cf1a30Sjl139090 {
27725cf1a30Sjl139090 	int instance;
27825cf1a30Sjl139090 	struct panel_state *statep;
27925cf1a30Sjl139090 
28025cf1a30Sjl139090 	instance = ddi_get_instance(dip);
28125cf1a30Sjl139090 
28225cf1a30Sjl139090 	DCMN_ERR((CE_CONT, "%s%d: detach\n", panel_name, instance));
28325cf1a30Sjl139090 
28425cf1a30Sjl139090 	if ((statep = (struct panel_state *)
28525cf1a30Sjl139090 	    ddi_get_soft_state(panelstates, instance)) == NULL) {
28625cf1a30Sjl139090 		cmn_err(CE_WARN, "%s%d: ddi_get_soft_state failed.",
28725cf1a30Sjl139090 		    panel_name, instance);
28825cf1a30Sjl139090 		return (DDI_FAILURE);
28925cf1a30Sjl139090 	}
29025cf1a30Sjl139090 
29125cf1a30Sjl139090 	switch (cmd) {
29225cf1a30Sjl139090 	case DDI_DETACH:
29325cf1a30Sjl139090 		DCMN_ERR((CE_CONT, "%s%d: DDI_DETACH\n",
29425cf1a30Sjl139090 		    panel_name, instance));
29525cf1a30Sjl139090 
29625cf1a30Sjl139090 		/* turn off interrupt */
29725cf1a30Sjl139090 		statep->panelregs_state &= ~PNLIE_MASK;
29825cf1a30Sjl139090 		panel_ddi_put8(statep->panel_regs_handle, statep->panelregs,
29925cf1a30Sjl139090 		    statep->panelregs_state);
30025cf1a30Sjl139090 
30125cf1a30Sjl139090 		/* free all resources for the dip */
30225cf1a30Sjl139090 		ddi_remove_intr(dip, 0, statep->iblock_cookie);
30325cf1a30Sjl139090 
30425cf1a30Sjl139090 		/* need not free iblock_cookie */
30525cf1a30Sjl139090 		ddi_regs_map_free(&statep->panel_regs_handle);
30625cf1a30Sjl139090 		ddi_soft_state_free(panelstates, instance);
30725cf1a30Sjl139090 
30825cf1a30Sjl139090 		return (DDI_SUCCESS);
30925cf1a30Sjl139090 
31025cf1a30Sjl139090 	case DDI_SUSPEND:
31125cf1a30Sjl139090 		DCMN_ERR((CE_CONT, "%s%d: DDI_SUSPEND\n",
31225cf1a30Sjl139090 		    panel_name, instance));
31325cf1a30Sjl139090 		return (DDI_SUCCESS);
31425cf1a30Sjl139090 
31525cf1a30Sjl139090 	default:
31625cf1a30Sjl139090 		return (DDI_FAILURE);
31725cf1a30Sjl139090 
31825cf1a30Sjl139090 	}
31925cf1a30Sjl139090 	/* Not reached */
32025cf1a30Sjl139090 }
32125cf1a30Sjl139090 
32225cf1a30Sjl139090 /*ARGSUSED*/
32325cf1a30Sjl139090 static int
32425cf1a30Sjl139090 panel_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg,  void **resultp)
32525cf1a30Sjl139090 {
32625cf1a30Sjl139090 	struct panel_state *statep;
32725cf1a30Sjl139090 	int	instance;
32825cf1a30Sjl139090 	dev_t	dev = (dev_t)arg;
32925cf1a30Sjl139090 
33025cf1a30Sjl139090 	instance = getminor(dev);
33125cf1a30Sjl139090 
33225cf1a30Sjl139090 	DCMN_ERR((CE_CONT, "%s%d: getinfo\n", panel_name, instance));
33325cf1a30Sjl139090 
33425cf1a30Sjl139090 	switch (cmd) {
33525cf1a30Sjl139090 	case DDI_INFO_DEVT2DEVINFO:
33625cf1a30Sjl139090 		if ((statep = (struct panel_state *)
33725cf1a30Sjl139090 		    ddi_get_soft_state(panelstates, instance)) == NULL) {
33825cf1a30Sjl139090 			cmn_err(CE_WARN, "%s%d: ddi_get_soft_state failed.",
33925cf1a30Sjl139090 			    panel_name, instance);
34025cf1a30Sjl139090 			*resultp = NULL;
34125cf1a30Sjl139090 			return (DDI_FAILURE);
34225cf1a30Sjl139090 		}
34325cf1a30Sjl139090 		*resultp = statep->dip;
34425cf1a30Sjl139090 		break;
34525cf1a30Sjl139090 	case DDI_INFO_DEVT2INSTANCE:
34625cf1a30Sjl139090 		*resultp = (void *)(uintptr_t)instance;
34725cf1a30Sjl139090 		break;
34825cf1a30Sjl139090 	default:
34925cf1a30Sjl139090 		return (DDI_FAILURE);
35025cf1a30Sjl139090 	}
35125cf1a30Sjl139090 
35225cf1a30Sjl139090 	return (DDI_SUCCESS);
35325cf1a30Sjl139090 }
35425cf1a30Sjl139090 
35525cf1a30Sjl139090 static  uint_t
35625cf1a30Sjl139090 panel_intr(caddr_t arg)
35725cf1a30Sjl139090 {
35825cf1a30Sjl139090 	struct panel_state *statep = (struct panel_state *)arg;
35925cf1a30Sjl139090 
36025cf1a30Sjl139090 	/* to confirm the validity of the interrupt */
36125cf1a30Sjl139090 	if (!(ddi_get8(statep->panel_regs_handle, statep->panelregs) &
36225cf1a30Sjl139090 	    PNLINT_MASK)) {
36325cf1a30Sjl139090 		return (DDI_INTR_UNCLAIMED);
36425cf1a30Sjl139090 	}
36525cf1a30Sjl139090 
36697cc145dShyw 	/*
36797cc145dShyw 	 * Clear the PNLINT bit
36897cc145dShyw 	 * HW reported that there might be a delay in the PNLINT bit
36997cc145dShyw 	 * clearing. We force synchronization by attempting to read
37097cc145dShyw 	 * back the reg after clearing the bit.
37197cc145dShyw 	 */
37225cf1a30Sjl139090 	panel_ddi_put8(statep->panel_regs_handle, statep->panelregs,
37325cf1a30Sjl139090 	    statep->panelregs_state | PNLINT_MASK);
37407d06da5SSurya Prakki 	(void) ddi_get8(statep->panel_regs_handle, statep->panelregs);
37525cf1a30Sjl139090 
37625cf1a30Sjl139090 	if (panel_enable) {
37725cf1a30Sjl139090 		/* avoid double panic */
37825cf1a30Sjl139090 		panel_enable 	= 0;
37925cf1a30Sjl139090 
38025cf1a30Sjl139090 		cmn_err(CE_PANIC,
38125cf1a30Sjl139090 		    "System Panel Driver: Emergency panic request "
38225cf1a30Sjl139090 		    "detected!");
38325cf1a30Sjl139090 		/* Not reached */
38425cf1a30Sjl139090 	}
38525cf1a30Sjl139090 
38625cf1a30Sjl139090 	return (DDI_INTR_CLAIMED);
38725cf1a30Sjl139090 }
38825cf1a30Sjl139090 
38925cf1a30Sjl139090 #ifdef DEBUG
39025cf1a30Sjl139090 static void
39125cf1a30Sjl139090 panel_ddi_put8(ddi_acc_handle_t handle, uint8_t *dev_addr, uint8_t value)
39225cf1a30Sjl139090 {
39325cf1a30Sjl139090 	if (panel_debug) {
39425cf1a30Sjl139090 		cmn_err(CE_CONT, "%s: old value = 0x%x\n",
39525cf1a30Sjl139090 		    panel_name, ddi_get8(handle, dev_addr));
39625cf1a30Sjl139090 		cmn_err(CE_CONT, "%s: writing value = 0x%x\n",
39725cf1a30Sjl139090 		    panel_name, value);
39825cf1a30Sjl139090 		ddi_put8(handle, dev_addr, value);
39925cf1a30Sjl139090 		cmn_err(CE_CONT, "%s: new value = 0x%x\n",
40025cf1a30Sjl139090 		    panel_name, ddi_get8(handle, dev_addr));
40125cf1a30Sjl139090 	} else {
40225cf1a30Sjl139090 		ddi_put8(handle, dev_addr, value);
40325cf1a30Sjl139090 	}
40425cf1a30Sjl139090 }
40525cf1a30Sjl139090 #endif
406