drm_irq.c revision 60405de4d8688d96dd05157c28db3ade5c9bc234
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Use is subject to license terms.
60405de4d8688d96dd05157c28db3ade5c9bc234kz */
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*
60405de4d8688d96dd05157c28db3ade5c9bc234kz * drm_irq.c -- IRQ IOCTL and function support
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Created: Fri Oct 18 2003 by anholt@FreeBSD.org
60405de4d8688d96dd05157c28db3ade5c9bc234kz */
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Copyright 2003 Eric Anholt
60405de4d8688d96dd05157c28db3ade5c9bc234kz * All Rights Reserved.
60405de4d8688d96dd05157c28db3ade5c9bc234kz *
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Permission is hereby granted, free of charge, to any person obtaining a
60405de4d8688d96dd05157c28db3ade5c9bc234kz * copy of this software and associated documentation files (the "Software"),
60405de4d8688d96dd05157c28db3ade5c9bc234kz * to deal in the Software without restriction, including without limitation
60405de4d8688d96dd05157c28db3ade5c9bc234kz * the rights to use, copy, modify, merge, publish, distribute, sublicense,
60405de4d8688d96dd05157c28db3ade5c9bc234kz * and/or sell copies of the Software, and to permit persons to whom the
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Software is furnished to do so, subject to the following conditions:
60405de4d8688d96dd05157c28db3ade5c9bc234kz *
60405de4d8688d96dd05157c28db3ade5c9bc234kz * The above copyright notice and this permission notice (including the next
60405de4d8688d96dd05157c28db3ade5c9bc234kz * paragraph) shall be included in all copies or substantial portions of the
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Software.
60405de4d8688d96dd05157c28db3ade5c9bc234kz *
60405de4d8688d96dd05157c28db3ade5c9bc234kz * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
60405de4d8688d96dd05157c28db3ade5c9bc234kz * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
60405de4d8688d96dd05157c28db3ade5c9bc234kz * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
60405de4d8688d96dd05157c28db3ade5c9bc234kz * ERIC ANHOLT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
60405de4d8688d96dd05157c28db3ade5c9bc234kz * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
60405de4d8688d96dd05157c28db3ade5c9bc234kz * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
60405de4d8688d96dd05157c28db3ade5c9bc234kz *
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Authors:
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Eric Anholt <anholt@FreeBSD.org>
60405de4d8688d96dd05157c28db3ade5c9bc234kz *
60405de4d8688d96dd05157c28db3ade5c9bc234kz */
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz#pragma ident "%Z%%M% %I% %E% SMI"
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz#include "drmP.h"
60405de4d8688d96dd05157c28db3ade5c9bc234kz#include "drm.h"
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*ARGSUSED*/
60405de4d8688d96dd05157c28db3ade5c9bc234kzint
60405de4d8688d96dd05157c28db3ade5c9bc234kzdrm_irq_by_busid(DRM_IOCTL_ARGS)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_DEVICE;
60405de4d8688d96dd05157c28db3ade5c9bc234kz drm_irq_busid_t irq;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_COPY_FROM_USER_IOCTL(irq, (drm_irq_busid_t *)data, sizeof (irq));
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz if ((irq.busnum >> 8) != dev->pci_domain ||
60405de4d8688d96dd05157c28db3ade5c9bc234kz (irq.busnum & 0xff) != dev->pci_bus ||
60405de4d8688d96dd05157c28db3ade5c9bc234kz irq.devnum != dev->pci_slot ||
60405de4d8688d96dd05157c28db3ade5c9bc234kz irq.funcnum != dev->pci_func)
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (DRM_ERR(EINVAL));
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz irq.irq = dev->irq;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_DEBUG("%x:%x:%x => IRQ %x\n",
60405de4d8688d96dd05157c28db3ade5c9bc234kz irq.busnum, irq.devnum, irq.funcnum, irq.irq);
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_COPY_TO_USER_IOCTL((drm_irq_busid_t *)data, irq, sizeof (irq));
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (0);
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*ARGSUSED*/
60405de4d8688d96dd05157c28db3ade5c9bc234kzstatic int
60405de4d8688d96dd05157c28db3ade5c9bc234kzdrm_install_irq_handle(drm_softstate_t *dev)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
60405de4d8688d96dd05157c28db3ade5c9bc234kz dev_info_t *dip = NULL;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz dip = dev->dip;
60405de4d8688d96dd05157c28db3ade5c9bc234kz if (dip == NULL) {
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_ERROR("drm_install_irq_handle: cannot get vgatext's dip");
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (DDI_FAILURE);
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz if (ddi_intr_hilevel(dip, 0) != 0) {
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_ERROR("drm_install_irq_handle: "
60405de4d8688d96dd05157c28db3ade5c9bc234kz "high-level interrupts are not supported");
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (DDI_FAILURE);
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz if (ddi_get_iblock_cookie(dip, (uint_t)0,
60405de4d8688d96dd05157c28db3ade5c9bc234kz &dev->intr_block) != DDI_SUCCESS) {
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_ERROR("drm_install_irq_handle: cannot get iblock cookie");
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (DDI_FAILURE);
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz mutex_init(&dev->irq_lock, NULL, MUTEX_DRIVER, (void *)dev->intr_block);
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz /* setup the interrupt handler */
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz if (ddi_add_intr(dip, 0, &dev->intr_block,
60405de4d8688d96dd05157c28db3ade5c9bc234kz (ddi_idevice_cookie_t *)NULL, dev->irq_handler,
60405de4d8688d96dd05157c28db3ade5c9bc234kz (caddr_t)dev) != DDI_SUCCESS) {
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_ERROR("drm_install_irq_handle: ddi_add_intr failed");
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (DDI_FAILURE);
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_DEBUG("drm_install_irq_handle: add the intr handle successful");
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (DDI_SUCCESS);
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*ARGSUSED*/
60405de4d8688d96dd05157c28db3ade5c9bc234kzint
60405de4d8688d96dd05157c28db3ade5c9bc234kzdrm_irq_install(drm_softstate_t *dev)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
60405de4d8688d96dd05157c28db3ade5c9bc234kz int ret;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz if (dev->dev_private == NULL) {
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_ERROR("drm_irq_install: dev_private is NULL");
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (DRM_ERR(EINVAL));
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz if (dev->irq_enabled) {
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_ERROR("drm_irq_install: irq already enabled");
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (DRM_ERR(EBUSY));
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz dev->context_flag = 0;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz /* before installing handler */
60405de4d8688d96dd05157c28db3ade5c9bc234kz dev->irq_preinstall(dev);
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz /* install handler */
60405de4d8688d96dd05157c28db3ade5c9bc234kz ret = drm_install_irq_handle(dev);
60405de4d8688d96dd05157c28db3ade5c9bc234kz if (ret != DDI_SUCCESS) {
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_ERROR("drm_irq_install: drm_install_irq_handle failed");
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (ret);
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz /* after installing handler */
60405de4d8688d96dd05157c28db3ade5c9bc234kz dev->irq_postinstall(dev);
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz dev->irq_enabled = 1;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (DDI_SUCCESS);
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kzstatic void
60405de4d8688d96dd05157c28db3ade5c9bc234kzdrm_uninstall_irq_handle(drm_device_t *dev)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
60405de4d8688d96dd05157c28db3ade5c9bc234kz ASSERT(dev->dip);
60405de4d8688d96dd05157c28db3ade5c9bc234kz ddi_remove_intr(dev->dip, 0, dev->intr_block);
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*ARGSUSED*/
60405de4d8688d96dd05157c28db3ade5c9bc234kzint
60405de4d8688d96dd05157c28db3ade5c9bc234kzdrm_irq_uninstall(drm_softstate_t *dev)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz dev->irq_enabled = 0;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz dev->irq_uninstall(dev);
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz drm_uninstall_irq_handle(dev);
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (DDI_SUCCESS);
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*ARGSUSED*/
60405de4d8688d96dd05157c28db3ade5c9bc234kzint
60405de4d8688d96dd05157c28db3ade5c9bc234kzdrm_control(DRM_IOCTL_ARGS)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_DEVICE;
60405de4d8688d96dd05157c28db3ade5c9bc234kz drm_control_t ctl;
60405de4d8688d96dd05157c28db3ade5c9bc234kz int err;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_DEBUG("drm_control: install irq = %x\n", dev->irq);
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_COPY_FROM_USER_IOCTL(ctl, (drm_control_t *)data, sizeof (ctl));
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz switch (ctl.func) {
60405de4d8688d96dd05157c28db3ade5c9bc234kz case DRM_INST_HANDLER:
60405de4d8688d96dd05157c28db3ade5c9bc234kz /*
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Handle drivers whose DRM used to require IRQ setup but the
60405de4d8688d96dd05157c28db3ade5c9bc234kz * no longer does.
60405de4d8688d96dd05157c28db3ade5c9bc234kz */
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (drm_irq_install(dev));
60405de4d8688d96dd05157c28db3ade5c9bc234kz case DRM_UNINST_HANDLER:
60405de4d8688d96dd05157c28db3ade5c9bc234kz err = drm_irq_uninstall(dev);
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (err);
60405de4d8688d96dd05157c28db3ade5c9bc234kz default:
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (DRM_ERR(EINVAL));
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*ARGSUSED*/
60405de4d8688d96dd05157c28db3ade5c9bc234kzint
60405de4d8688d96dd05157c28db3ade5c9bc234kzdrm_wait_vblank(DRM_IOCTL_ARGS)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (0);
60405de4d8688d96dd05157c28db3ade5c9bc234kz}