summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorOwain Ainsworth <oga@cvs.openbsd.org>2008-11-23 21:35:02 +0000
committerOwain Ainsworth <oga@cvs.openbsd.org>2008-11-23 21:35:02 +0000
commitebcc0685bc5a51f710b5063c90f783646d4dbb53 (patch)
tree4bcfaa5f472f81112a5ee846adf18228e990ea42 /sys/dev
parent17ac785bb3a684774ebdad9381363f2883fec44a (diff)
Map device interrupts in the attach routine. and remove more need for
dev->pa by doing the pci_intr_establish/disestablish dance in the driver function, not in drm. This removes the need for interrupt_{pre,post}install callbacks, instead just provide a interrupt_install() callback.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/drm/drmP.h10
-rw-r--r--sys/dev/pci/drm/drm_bufs.c3
-rw-r--r--sys/dev/pci/drm/drm_irq.c31
-rw-r--r--sys/dev/pci/drm/i915_drv.c9
-rw-r--r--sys/dev/pci/drm/i915_drv.h7
-rw-r--r--sys/dev/pci/drm/i915_irq.c13
-rw-r--r--sys/dev/pci/drm/mach64_drv.c9
-rw-r--r--sys/dev/pci/drm/mach64_drv.h6
-rw-r--r--sys/dev/pci/drm/mach64_irq.c12
-rw-r--r--sys/dev/pci/drm/mga_drv.c11
-rw-r--r--sys/dev/pci/drm/mga_drv.h7
-rw-r--r--sys/dev/pci/drm/mga_irq.c18
-rw-r--r--sys/dev/pci/drm/r128_drv.c9
-rw-r--r--sys/dev/pci/drm/r128_drv.h6
-rw-r--r--sys/dev/pci/drm/r128_irq.c16
-rw-r--r--sys/dev/pci/drm/radeon_drv.c9
-rw-r--r--sys/dev/pci/drm/radeon_drv.h7
-rw-r--r--sys/dev/pci/drm/radeon_irq.c17
18 files changed, 120 insertions, 80 deletions
diff --git a/sys/dev/pci/drm/drmP.h b/sys/dev/pci/drm/drmP.h
index 603b59e6965..a130d495214 100644
--- a/sys/dev/pci/drm/drmP.h
+++ b/sys/dev/pci/drm/drmP.h
@@ -449,8 +449,7 @@ struct drm_driver_info {
int (*dma_quiescent)(struct drm_device *);
int (*context_ctor)(struct drm_device *, int);
int (*context_dtor)(struct drm_device *, int);
- void (*irq_preinstall)(struct drm_device *);
- int (*irq_postinstall)(struct drm_device *);
+ int (*irq_install)(struct drm_device *);
void (*irq_uninstall)(struct drm_device *);
irqreturn_t (*irq_handler)(DRM_IRQ_ARGS);
int vblank_pipes;
@@ -531,8 +530,6 @@ struct drm_device {
int irq; /* Interrupt used by board */
int irq_enabled; /* True if the irq handler is enabled */
struct pci_attach_args pa;
- int unit; /* drm unit number */
- void *irqh; /* Handle from bus_setup_intr */
int pci_domain;
int pci_bus;
@@ -635,10 +632,7 @@ void drm_reclaim_buffers(struct drm_device *, struct drm_file *);
/* IRQ support (drm_irq.c) */
int drm_irq_install(struct drm_device *);
int drm_irq_uninstall(struct drm_device *);
-irqreturn_t drm_irq_handler(DRM_IRQ_ARGS);
-void drm_driver_irq_preinstall(struct drm_device *);
-void drm_driver_irq_postinstall(struct drm_device *);
-void drm_driver_irq_uninstall(struct drm_device *);
+irqreturn_t drm_irq_handler_wrap(DRM_IRQ_ARGS);
void drm_vblank_cleanup(struct drm_device *);
int drm_vblank_init(struct drm_device *, int);
u_int32_t drm_vblank_count(struct drm_device *, int);
diff --git a/sys/dev/pci/drm/drm_bufs.c b/sys/dev/pci/drm/drm_bufs.c
index 7360d0a099c..bd0c74ad8c6 100644
--- a/sys/dev/pci/drm/drm_bufs.c
+++ b/sys/dev/pci/drm/drm_bufs.c
@@ -289,7 +289,6 @@ drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map)
switch (map->type) {
case _DRM_REGISTERS:
- drm_ioremapfree(map);
/* FALLTHROUGH */
case _DRM_FRAME_BUFFER:
if (map->mtrr) {
@@ -301,9 +300,11 @@ drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map)
}
break;
case _DRM_AGP:
+ /* FALLTHROUGH */
case _DRM_SCATTER_GATHER:
break;
case _DRM_SHM:
+ /* FALLTHROUGH */
case _DRM_CONSISTENT:
drm_pci_free(dev->pa.pa_dmat, map->dmah);
break;
diff --git a/sys/dev/pci/drm/drm_irq.c b/sys/dev/pci/drm/drm_irq.c
index ede6c66baf4..e4eaa8e1718 100644
--- a/sys/dev/pci/drm/drm_irq.c
+++ b/sys/dev/pci/drm/drm_irq.c
@@ -35,7 +35,6 @@
#include "drmP.h"
#include "drm.h"
-irqreturn_t drm_irq_handler_wrap(DRM_IRQ_ARGS);
void drm_update_vblank_count(struct drm_device *, int);
void vblank_disable(void *);
@@ -74,9 +73,7 @@ drm_irq_handler_wrap(DRM_IRQ_ARGS)
int
drm_irq_install(struct drm_device *dev)
{
- int retcode;
- pci_intr_handle_t ih;
- const char *istr;
+ int ret;
if (dev->irq == 0 || dev->dev_private == NULL)
return (EINVAL);
@@ -93,34 +90,16 @@ drm_irq_install(struct drm_device *dev)
mtx_init(&dev->irq_lock, IPL_BIO);
- /* Before installing handler */
- dev->driver->irq_preinstall(dev);
-
- /* Install handler */
- if (pci_intr_map(&dev->pa, &ih) != 0) {
- retcode = ENOENT;
- goto err;
- }
- istr = pci_intr_string(dev->pa.pa_pc, ih);
- dev->irqh = pci_intr_establish(dev->pa.pa_pc, ih, IPL_BIO,
- drm_irq_handler_wrap, dev, dev->device.dv_xname);
- if (!dev->irqh) {
- retcode = ENOENT;
+ if ((ret = dev->driver->irq_install(dev)) != 0)
goto err;
- }
- DRM_DEBUG("%s: interrupting at %s\n", dev->device.dv_xname, istr);
-
- /* After installing handler */
- if (dev->driver->irq_postinstall != NULL)
- dev->driver->irq_postinstall(dev);
- return 0;
+ return (0);
err:
DRM_LOCK();
dev->irq_enabled = 0;
DRM_SPINUNINIT(&dev->irq_lock);
DRM_UNLOCK();
- return retcode;
+ return (ret);
}
int
@@ -140,8 +119,6 @@ drm_irq_uninstall(struct drm_device *dev)
dev->driver->irq_uninstall(dev);
- pci_intr_disestablish(dev->pa.pa_pc, dev->irqh);
-
DRM_SPINUNINIT(&dev->irq_lock);
return 0;
diff --git a/sys/dev/pci/drm/i915_drv.c b/sys/dev/pci/drm/i915_drv.c
index 6425c36f823..830b068629e 100644
--- a/sys/dev/pci/drm/i915_drv.c
+++ b/sys/dev/pci/drm/i915_drv.c
@@ -99,8 +99,7 @@ static const struct drm_driver_info inteldrm_driver = {
.get_vblank_counter = i915_get_vblank_counter,
.enable_vblank = i915_enable_vblank,
.disable_vblank = i915_disable_vblank,
- .irq_preinstall = i915_driver_irq_preinstall,
- .irq_postinstall = i915_driver_irq_postinstall,
+ .irq_install = i915_driver_irq_install,
.irq_uninstall = i915_driver_irq_uninstall,
.irq_handler = i915_driver_irq_handler,
@@ -133,6 +132,7 @@ inteldrm_attach(struct device *parent, struct device *self, void *aux)
PCI_PRODUCT(pa->pa_id), inteldrm_pciidlist);
dev_priv->flags = id_entry->driver_private;
dev_priv->pci_device = PCI_PRODUCT(pa->pa_id);
+ dev_priv->pc = pa->pa_pc;
/* Add register map (needed for suspend/resume) */
bar = vga_pci_bar_info((struct vga_pci_softc *)parent,
@@ -149,6 +149,11 @@ inteldrm_attach(struct device *parent, struct device *self, void *aux)
return;
}
+ if (pci_intr_map(pa, &dev_priv->ih) != 0) {
+ printf(": couldn't map interrupt\n");
+ return;
+ }
+
/* Init HWS */
if (!I915_NEED_GFX_HWS(dev_priv)) {
if (i915_init_phys_hws(dev_priv, pa->pa_dmat) != 0) {
diff --git a/sys/dev/pci/drm/i915_drv.h b/sys/dev/pci/drm/i915_drv.h
index fdec2c460d0..7a6787ffd4e 100644
--- a/sys/dev/pci/drm/i915_drv.h
+++ b/sys/dev/pci/drm/i915_drv.h
@@ -84,6 +84,10 @@ typedef struct drm_i915_private {
u_long flags;
u_int16_t pci_device;
+ pci_chipset_tag_t pc;
+ pci_intr_handle_t ih;
+ void *irqh;
+
struct vga_pci_bar *regs;
drm_local_map_t *sarea;
@@ -250,8 +254,7 @@ extern int i915_irq_wait(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
-extern void i915_driver_irq_preinstall(struct drm_device * dev);
-extern int i915_driver_irq_postinstall(struct drm_device * dev);
+extern int i915_driver_irq_install(struct drm_device * dev);
extern void i915_driver_irq_uninstall(struct drm_device * dev);
extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
struct drm_file *file_priv);
diff --git a/sys/dev/pci/drm/i915_irq.c b/sys/dev/pci/drm/i915_irq.c
index 567ee14b093..315c4b97955 100644
--- a/sys/dev/pci/drm/i915_irq.c
+++ b/sys/dev/pci/drm/i915_irq.c
@@ -400,7 +400,8 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data,
/* drm_dma.h hooks
*/
-void i915_driver_irq_preinstall(struct drm_device * dev)
+int
+i915_driver_irq_install(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -410,11 +411,11 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
I915_WRITE(IMR, 0xffffffff);
I915_WRITE(IER, 0x0);
(void)I915_READ(IER);
-}
-int i915_driver_irq_postinstall(struct drm_device * dev)
-{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ dev_priv->irqh = pci_intr_establish(dev_priv->pc, dev_priv->ih, IPL_BIO,
+ drm_irq_handler_wrap, dev, dev_priv->dev.dv_xname);
+ if (dev_priv->irqh == NULL)
+ return (ENOENT);
dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
@@ -452,4 +453,6 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff);
I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff);
I915_WRITE(IIR, I915_READ(IIR));
+
+ pci_intr_disestablish(dev_priv->pc, dev_priv->irqh);
}
diff --git a/sys/dev/pci/drm/mach64_drv.c b/sys/dev/pci/drm/mach64_drv.c
index 9e7446c9ba5..dc29df381ec 100644
--- a/sys/dev/pci/drm/mach64_drv.c
+++ b/sys/dev/pci/drm/mach64_drv.c
@@ -75,7 +75,7 @@ static const struct drm_driver_info machdrm_driver = {
.get_vblank_counter = mach64_get_vblank_counter,
.enable_vblank = mach64_enable_vblank,
.disable_vblank = mach64_disable_vblank,
- .irq_preinstall = mach64_driver_irq_preinstall,
+ .irq_install = mach64_driver_irq_install,
.irq_uninstall = mach64_driver_irq_uninstall,
.irq_handler = mach64_driver_irq_handler,
.dma_ioctl = mach64_dma_buffers,
@@ -103,6 +103,8 @@ machdrm_attach(struct device *parent, struct device *self, void *aux)
struct pci_attach_args *pa = aux;
struct vga_pci_bar *bar;
+ dev_priv->pc = pa->pa_pc;
+
bar = vga_pci_bar_info((struct vga_pci_softc *)parent, 2);
if (bar == NULL) {
printf(": can't get BAR info\n");
@@ -116,6 +118,11 @@ machdrm_attach(struct device *parent, struct device *self, void *aux)
return;
}
+ if (pci_intr_map(pa, &dev_priv->ih) != 0) {
+ printf(": couldn't map interrupt\n");
+ return;
+ }
+
dev_priv->drmdev = drm_attach_mi(&machdrm_driver, pa, self);
}
diff --git a/sys/dev/pci/drm/mach64_drv.h b/sys/dev/pci/drm/mach64_drv.h
index 7d95fbc0b55..fb0ca6a8a1a 100644
--- a/sys/dev/pci/drm/mach64_drv.h
+++ b/sys/dev/pci/drm/mach64_drv.h
@@ -76,6 +76,10 @@ typedef struct drm_mach64_private {
struct device dev;
struct device *drmdev;
+ pci_chipset_tag_t pc;
+ pci_intr_handle_t ih;
+ void *irqh;
+
struct vga_pci_bar *regs;
drm_mach64_sarea_t *sarea_priv;
@@ -167,7 +171,7 @@ extern u32 mach64_get_vblank_counter(struct drm_device *dev, int crtc);
extern int mach64_enable_vblank(struct drm_device *dev, int crtc);
extern void mach64_disable_vblank(struct drm_device *dev, int crtc);
extern irqreturn_t mach64_driver_irq_handler(DRM_IRQ_ARGS);
-extern void mach64_driver_irq_preinstall(struct drm_device *dev);
+extern int mach64_driver_irq_install(struct drm_device *dev);
extern void mach64_driver_irq_uninstall(struct drm_device *dev);
/* ================================================================
diff --git a/sys/dev/pci/drm/mach64_irq.c b/sys/dev/pci/drm/mach64_irq.c
index 55c2cb14c57..9713f38cafe 100644
--- a/sys/dev/pci/drm/mach64_irq.c
+++ b/sys/dev/pci/drm/mach64_irq.c
@@ -130,7 +130,8 @@ static void mach64_disable_vblank_local(struct drm_device * dev, int crtc)
| MACH64_CRTC_VBLANK_INT);
}
-void mach64_driver_irq_preinstall(struct drm_device * dev)
+int
+mach64_driver_irq_install(struct drm_device * dev)
{
drm_mach64_private_t *dev_priv = dev->dev_private;
@@ -139,16 +140,21 @@ void mach64_driver_irq_preinstall(struct drm_device * dev)
DRM_DEBUG("before install CRTC_INT_CTNL: 0x%08x\n", status);
mach64_disable_vblank_local(dev, 0);
+
+ dev_priv->irqh = pci_intr_establish(dev_priv->pc, dev_priv->ih, IPL_BIO,
+ drm_irq_handler_wrap, dev, dev_priv->dev.dv_xname);
+ if (dev_priv->irqh == NULL)
+ return (ENOENT);
+ return (0);
}
void mach64_driver_irq_uninstall(struct drm_device * dev)
{
drm_mach64_private_t *dev_priv = dev->dev_private;
- if (!dev_priv)
- return;
mach64_disable_vblank_local(dev, 0);
DRM_DEBUG("after uninstall CRTC_INT_CTNL: 0x%08x\n",
MACH64_READ(MACH64_CRTC_INT_CNTL));
+ pci_intr_disestablish(dev_priv->pc, dev_priv->irqh);
}
diff --git a/sys/dev/pci/drm/mga_drv.c b/sys/dev/pci/drm/mga_drv.c
index 776a0d5e7ba..cd548590644 100644
--- a/sys/dev/pci/drm/mga_drv.c
+++ b/sys/dev/pci/drm/mga_drv.c
@@ -110,8 +110,7 @@ static const struct drm_driver_info mga_driver = {
.enable_vblank = mga_enable_vblank,
.disable_vblank = mga_disable_vblank,
.get_vblank_counter = mga_get_vblank_counter,
- .irq_preinstall = mga_driver_irq_preinstall,
- .irq_postinstall = mga_driver_irq_postinstall,
+ .irq_install = mga_driver_irq_install,
.irq_uninstall = mga_driver_irq_uninstall,
.irq_handler = mga_driver_irq_handler,
.dma_ioctl = mga_dma_buffers,
@@ -144,6 +143,7 @@ mgadrm_attach(struct device *parent, struct device *self, void *aux)
drm_pci_id_list_t *id_entry;
dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT;
+ dev_priv->pc = pa->pa_pc;
id_entry = drm_find_description(PCI_VENDOR(pa->pa_id),
PCI_PRODUCT(pa->pa_id), mgadrm_pciidlist);
@@ -161,6 +161,13 @@ mgadrm_attach(struct device *parent, struct device *self, void *aux)
return;
}
+ dev_priv->regs = vga_pci_bar_map((struct vga_pci_softc *)parent,
+ bar->addr, bar->size, 0);
+ if (dev_priv->regs == NULL) {
+ printf(": can't map mmio space\n");
+ return;
+ }
+
dev_priv->drmdev = drm_attach_mi(&mga_driver, pa, self);
}
diff --git a/sys/dev/pci/drm/mga_drv.h b/sys/dev/pci/drm/mga_drv.h
index 77d62d9c5dc..a46858aa549 100644
--- a/sys/dev/pci/drm/mga_drv.h
+++ b/sys/dev/pci/drm/mga_drv.h
@@ -78,6 +78,10 @@ typedef struct drm_mga_private {
struct device dev;
struct device *drmdev;
+ pci_chipset_tag_t pc;
+ pci_intr_handle_t ih;
+ void *irqh;
+
struct vga_pci_bar *regs;
drm_mga_primary_buffer_t prim;
@@ -185,8 +189,7 @@ extern u32 mga_get_vblank_counter(struct drm_device *dev, int crtc);
extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence);
extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence);
extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS);
-extern void mga_driver_irq_preinstall(struct drm_device * dev);
-extern int mga_driver_irq_postinstall(struct drm_device * dev);
+extern int mga_driver_irq_install(struct drm_device * dev);
extern void mga_driver_irq_uninstall(struct drm_device * dev);
extern long mga_compat_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg);
diff --git a/sys/dev/pci/drm/mga_irq.c b/sys/dev/pci/drm/mga_irq.c
index a4ed2b18546..df1c68664e9 100644
--- a/sys/dev/pci/drm/mga_irq.c
+++ b/sys/dev/pci/drm/mga_irq.c
@@ -141,7 +141,8 @@ int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence)
return ret;
}
-void mga_driver_irq_preinstall(struct drm_device * dev)
+int
+mga_driver_irq_install(struct drm_device * dev)
{
drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
@@ -149,11 +150,11 @@ void mga_driver_irq_preinstall(struct drm_device * dev)
MGA_WRITE(MGA_IEN, 0);
/* Clear bits if they're already high */
MGA_WRITE(MGA_ICLEAR, ~0);
-}
-int mga_driver_irq_postinstall(struct drm_device * dev)
-{
- drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
+ dev_priv->irqh = pci_intr_establish(dev_priv->pc, dev_priv->ih, IPL_BIO,
+ drm_irq_handler_wrap, dev, dev_priv->dev.dv_xname);
+ if (dev_priv->irqh == NULL)
+ return (ENOENT);
/* Turn on soft trap interrupt. Vertical blank interrupts are enabled
* in mga_enable_vblank.
@@ -162,14 +163,13 @@ int mga_driver_irq_postinstall(struct drm_device * dev)
return 0;
}
-void mga_driver_irq_uninstall(struct drm_device * dev)
+void
+mga_driver_irq_uninstall(struct drm_device * dev)
{
drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
- if (!dev_priv)
- return;
/* Disable *all* interrupts */
MGA_WRITE(MGA_IEN, 0);
- dev->irq_enabled = 0;
+ pci_intr_disestablish(dev_priv->pc, dev_priv->irqh);
}
diff --git a/sys/dev/pci/drm/r128_drv.c b/sys/dev/pci/drm/r128_drv.c
index d864567a97e..97bd7908e72 100644
--- a/sys/dev/pci/drm/r128_drv.c
+++ b/sys/dev/pci/drm/r128_drv.c
@@ -91,7 +91,7 @@ static const struct drm_driver_info ragedrm_driver = {
.get_vblank_counter = r128_get_vblank_counter,
.enable_vblank = r128_enable_vblank,
.disable_vblank = r128_disable_vblank,
- .irq_preinstall = r128_driver_irq_preinstall,
+ .irq_install = r128_driver_irq_install,
.irq_uninstall = r128_driver_irq_uninstall,
.irq_handler = r128_driver_irq_handler,
.dma_ioctl = r128_cce_buffers,
@@ -120,6 +120,8 @@ ragedrm_attach(struct device *parent, struct device *self, void *aux)
struct pci_attach_args *pa = aux;
struct vga_pci_bar *bar;
+ dev_priv->pc = pa->pa_pc;
+
bar = vga_pci_bar_info((struct vga_pci_softc *)parent, 2);
if (bar == NULL) {
printf(": can't get BAR info\n");
@@ -133,6 +135,11 @@ ragedrm_attach(struct device *parent, struct device *self, void *aux)
return;
}
+ if (pci_intr_map(pa, &dev_priv->ih) != 0) {
+ printf(": couldn't map interrupt\n");
+ return;
+ }
+
dev_priv->drmdev = drm_attach_mi(&ragedrm_driver, pa, self);
}
diff --git a/sys/dev/pci/drm/r128_drv.h b/sys/dev/pci/drm/r128_drv.h
index 37d697e2930..ca647af09e4 100644
--- a/sys/dev/pci/drm/r128_drv.h
+++ b/sys/dev/pci/drm/r128_drv.h
@@ -79,6 +79,10 @@ typedef struct drm_r128_private {
struct device dev;
struct device *drmdev;
+ pci_chipset_tag_t pc;
+ pci_intr_handle_t ih;
+ void *irqh;
+
struct vga_pci_bar *regs;
drm_r128_ring_buffer_t ring;
drm_r128_sarea_t *sarea_priv;
@@ -165,7 +169,7 @@ extern int r128_enable_vblank(struct drm_device *dev, int crtc);
extern void r128_disable_vblank(struct drm_device *dev, int crtc);
extern u32 r128_get_vblank_counter(struct drm_device *dev, int crtc);
extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS);
-extern void r128_driver_irq_preinstall(struct drm_device * dev);
+extern int r128_driver_irq_install(struct drm_device * dev);
extern void r128_driver_irq_uninstall(struct drm_device * dev);
extern void r128_driver_lastclose(struct drm_device * dev);
extern void r128_driver_preclose(struct drm_device * dev,
diff --git a/sys/dev/pci/drm/r128_irq.c b/sys/dev/pci/drm/r128_irq.c
index 50f1f08920d..48ef8987f77 100644
--- a/sys/dev/pci/drm/r128_irq.c
+++ b/sys/dev/pci/drm/r128_irq.c
@@ -90,7 +90,8 @@ void r128_disable_vblank(struct drm_device *dev, int crtc)
*/
}
-void r128_driver_irq_preinstall(struct drm_device * dev)
+int
+r128_driver_irq_install(struct drm_device * dev)
{
drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
@@ -98,14 +99,21 @@ void r128_driver_irq_preinstall(struct drm_device * dev)
R128_WRITE(R128_GEN_INT_CNTL, 0);
/* Clear vblank bit if it's already high */
R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
+
+ dev_priv->irqh = pci_intr_establish(dev_priv->pc, dev_priv->ih, IPL_BIO,
+ drm_irq_handler_wrap, dev, dev_priv->dev.dv_xname);
+ if (dev_priv->irqh == NULL)
+ return (ENOENT);
+ return (0);
}
-void r128_driver_irq_uninstall(struct drm_device * dev)
+void
+r128_driver_irq_uninstall(struct drm_device * dev)
{
drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
- if (!dev_priv)
- return;
/* Disable *all* interrupts */
R128_WRITE(R128_GEN_INT_CNTL, 0);
+
+ pci_intr_disestablish(dev_priv->pc, dev_priv->irqh);
}
diff --git a/sys/dev/pci/drm/radeon_drv.c b/sys/dev/pci/drm/radeon_drv.c
index 337101a30a4..22fdf1cf55e 100644
--- a/sys/dev/pci/drm/radeon_drv.c
+++ b/sys/dev/pci/drm/radeon_drv.c
@@ -488,8 +488,7 @@ static const struct drm_driver_info radeondrm_driver = {
.get_vblank_counter = radeon_get_vblank_counter,
.enable_vblank = radeon_enable_vblank,
.disable_vblank = radeon_disable_vblank,
- .irq_preinstall = radeon_driver_irq_preinstall,
- .irq_postinstall = radeon_driver_irq_postinstall,
+ .irq_install = radeon_driver_irq_install,
.irq_uninstall = radeon_driver_irq_uninstall,
.irq_handler = radeon_driver_irq_handler,
.dma_ioctl = radeon_cp_buffers,
@@ -522,6 +521,7 @@ radeondrm_attach(struct device *parent, struct device *self, void *aux)
id_entry = drm_find_description(PCI_VENDOR(pa->pa_id),
PCI_PRODUCT(pa->pa_id), radeondrm_pciidlist);
dev_priv->flags = id_entry->driver_private;
+ dev_priv->pc = pa->pa_pc;
bar = vga_pci_bar_info((struct vga_pci_softc *)parent, 0);
if (bar == NULL) {
@@ -544,6 +544,11 @@ radeondrm_attach(struct device *parent, struct device *self, void *aux)
return;
}
+ if (pci_intr_map(pa, &dev_priv->ih) != 0) {
+ printf(": couldn't map interrupt\n");
+ return;
+ }
+
switch (dev_priv->flags & RADEON_FAMILY_MASK) {
case CHIP_R100:
case CHIP_RV200:
diff --git a/sys/dev/pci/drm/radeon_drv.h b/sys/dev/pci/drm/radeon_drv.h
index d6ada2b4733..f5dd17611fa 100644
--- a/sys/dev/pci/drm/radeon_drv.h
+++ b/sys/dev/pci/drm/radeon_drv.h
@@ -224,6 +224,10 @@ typedef struct drm_radeon_private {
struct device dev;
struct device *drmdev;
+ pci_chipset_tag_t pc;
+ pci_intr_handle_t ih;
+ void *irqh;
+
struct vga_pci_bar *regs;
drm_radeon_ring_buffer_t ring;
drm_radeon_sarea_t *sarea_priv;
@@ -398,8 +402,7 @@ extern u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc);
extern int radeon_enable_vblank(struct drm_device *dev, int crtc);
extern void radeon_disable_vblank(struct drm_device *dev, int crtc);
extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS);
-extern void radeon_driver_irq_preinstall(struct drm_device * dev);
-extern int radeon_driver_irq_postinstall(struct drm_device * dev);
+extern int radeon_driver_irq_install(struct drm_device * dev);
extern void radeon_driver_irq_uninstall(struct drm_device * dev);
extern int radeon_vblank_crtc_get(struct drm_device *dev);
extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value);
diff --git a/sys/dev/pci/drm/radeon_irq.c b/sys/dev/pci/drm/radeon_irq.c
index f0255e28017..5ca8abf1e74 100644
--- a/sys/dev/pci/drm/radeon_irq.c
+++ b/sys/dev/pci/drm/radeon_irq.c
@@ -320,7 +320,8 @@ int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_pr
/* drm_dma.h hooks
*/
-void radeon_driver_irq_preinstall(struct drm_device * dev)
+int
+radeon_driver_irq_install(struct drm_device * dev)
{
drm_radeon_private_t *dev_priv =
(drm_radeon_private_t *) dev->dev_private;
@@ -333,12 +334,11 @@ void radeon_driver_irq_preinstall(struct drm_device * dev)
/* Clear bits if they're already high */
radeon_acknowledge_irqs(dev_priv, &dummy);
-}
-int radeon_driver_irq_postinstall(struct drm_device * dev)
-{
- drm_radeon_private_t *dev_priv =
- (drm_radeon_private_t *) dev->dev_private;
+ dev_priv->irqh = pci_intr_establish(dev_priv->pc, dev_priv->ih, IPL_BIO,
+ drm_irq_handler_wrap, dev, dev_priv->dev.dv_xname);
+ if (dev_priv->irqh == NULL)
+ return (ENOENT);
atomic_set(&dev_priv->swi_emitted, 0);
@@ -349,7 +349,8 @@ int radeon_driver_irq_postinstall(struct drm_device * dev)
return 0;
}
-void radeon_driver_irq_uninstall(struct drm_device * dev)
+void
+radeon_driver_irq_uninstall(struct drm_device * dev)
{
drm_radeon_private_t *dev_priv =
(drm_radeon_private_t *) dev->dev_private;
@@ -362,6 +363,8 @@ void radeon_driver_irq_uninstall(struct drm_device * dev)
RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
/* Disable *all* interrupts */
RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
+
+ pci_intr_disestablish(dev_priv->pc, dev_priv->irqh);
}