#include "psb_drv.h"
 #include "psb_reg.h"
 #include "psb_intel_reg.h"
+#include "psb_irq.h"
 #include <linux/mutex.h>
 #include <linux/pm_runtime.h>
 
 
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_file.h>
 #include <drm/drm_ioctl.h>
-#include <drm/drm_irq.h>
 #include <drm/drm_pciids.h>
 #include <drm/drm_vblank.h>
 
 #include "power.h"
 #include "psb_drv.h"
 #include "psb_intel_reg.h"
+#include "psb_irq.h"
 #include "psb_reg.h"
 
 static const struct drm_driver driver;
        PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R);
        spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
 
-       drm_irq_install(dev, pdev->irq);
+       psb_irq_install(dev, pdev->irq);
 
        dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
 
        .lastclose = drm_fb_helper_lastclose,
 
        .num_ioctls = ARRAY_SIZE(psb_ioctls),
-       .irq_preinstall = psb_irq_preinstall,
-       .irq_postinstall = psb_irq_postinstall,
-       .irq_uninstall = psb_irq_uninstall,
-       .irq_handler = psb_irq_handler,
 
        .dumb_create = psb_gem_dumb_create,
        .ioctls = psb_ioctls,
 
 }
 
 /* psb_irq.c */
-extern irqreturn_t psb_irq_handler(int irq, void *arg);
-extern void psb_irq_preinstall(struct drm_device *dev);
-extern int psb_irq_postinstall(struct drm_device *dev);
-extern void psb_irq_uninstall(struct drm_device *dev);
-
 extern void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands);
 extern int psb_vblank_wait2(struct drm_device *dev, unsigned int *sequence);
 extern int psb_vblank_wait(struct drm_device *dev, unsigned int *sequence);
 
  *
  **************************************************************************/
 
+#include <drm/drm_drv.h>
 #include <drm/drm_vblank.h>
 
 #include "power.h"
        PSB_RSGX32(PSB_CR_EVENT_HOST_CLEAR2);
 }
 
-irqreturn_t psb_irq_handler(int irq, void *arg)
+static irqreturn_t psb_irq_handler(int irq, void *arg)
 {
        struct drm_device *dev = arg;
        struct drm_psb_private *dev_priv = dev->dev_private;
        spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
 }
 
-int psb_irq_postinstall(struct drm_device *dev)
+void psb_irq_postinstall(struct drm_device *dev)
 {
        struct drm_psb_private *dev_priv = dev->dev_private;
        unsigned long irqflags;
                dev_priv->ops->hotplug_enable(dev, true);
 
        spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
+}
+
+int psb_irq_install(struct drm_device *dev, unsigned int irq)
+{
+       int ret;
+
+       if (irq == IRQ_NOTCONNECTED)
+               return -ENOTCONN;
+
+       psb_irq_preinstall(dev);
+
+       /* PCI devices require shared interrupts. */
+       ret = request_irq(irq, psb_irq_handler, IRQF_SHARED, dev->driver->name, dev);
+       if (ret)
+               return ret;
+
+       psb_irq_postinstall(dev);
+
        return 0;
 }
 
 void psb_irq_uninstall(struct drm_device *dev)
 {
        struct drm_psb_private *dev_priv = dev->dev_private;
+       struct pci_dev *pdev = to_pci_dev(dev->dev);
        unsigned long irqflags;
        unsigned int i;
 
        /* This register is safe even if display island is off */
        PSB_WVDC32(PSB_RVDC32(PSB_INT_IDENTITY_R), PSB_INT_IDENTITY_R);
        spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
+
+       free_irq(pdev->irq, dev);
 }
 
 /*
 
 void sysirq_uninit(struct drm_device *dev);
 
 void psb_irq_preinstall(struct drm_device *dev);
-int  psb_irq_postinstall(struct drm_device *dev);
+void psb_irq_postinstall(struct drm_device *dev);
+int  psb_irq_install(struct drm_device *dev, unsigned int irq);
 void psb_irq_uninstall(struct drm_device *dev);
-irqreturn_t psb_irq_handler(int irq, void *arg);
 
 int  psb_enable_vblank(struct drm_crtc *crtc);
 void psb_disable_vblank(struct drm_crtc *crtc);