Skip to content

Commit 4697995

Browse files
jbarnes993keith-packard
authored andcommitted
drm/i915: split irq handling into per-chipset functions
Set the IRQ handling functions in driver load so they'll just be used directly, rather than branching over most of the code in the chipset functions. Signed-off-by: Jesse Barnes <[email protected]> Reviewed-by: Keith Packard <[email protected]> Signed-off-by: Keith Packard <[email protected]>
1 parent 674cf96 commit 4697995

File tree

3 files changed

+43
-20
lines changed

3 files changed

+43
-20
lines changed

drivers/gpu/drm/i915/i915_dma.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,6 +1266,18 @@ static int i915_load_modeset_init(struct drm_device *dev)
12661266

12671267
intel_modeset_gem_init(dev);
12681268

1269+
if (HAS_PCH_SPLIT(dev)) {
1270+
dev->driver->irq_handler = ironlake_irq_handler;
1271+
dev->driver->irq_preinstall = ironlake_irq_preinstall;
1272+
dev->driver->irq_postinstall = ironlake_irq_postinstall;
1273+
dev->driver->irq_uninstall = ironlake_irq_uninstall;
1274+
} else {
1275+
dev->driver->irq_preinstall = i915_driver_irq_preinstall;
1276+
dev->driver->irq_postinstall = i915_driver_irq_postinstall;
1277+
dev->driver->irq_uninstall = i915_driver_irq_uninstall;
1278+
dev->driver->irq_handler = i915_driver_irq_handler;
1279+
}
1280+
12691281
ret = drm_irq_install(dev);
12701282
if (ret)
12711283
goto cleanup_gem;

drivers/gpu/drm/i915/i915_drv.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,6 +1028,12 @@ extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
10281028
extern void i915_driver_irq_preinstall(struct drm_device * dev);
10291029
extern int i915_driver_irq_postinstall(struct drm_device *dev);
10301030
extern void i915_driver_irq_uninstall(struct drm_device * dev);
1031+
1032+
extern irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS);
1033+
extern void ironlake_irq_preinstall(struct drm_device *dev);
1034+
extern int ironlake_irq_postinstall(struct drm_device *dev);
1035+
extern void ironlake_irq_uninstall(struct drm_device *dev);
1036+
10311037
extern int i915_vblank_pipe_set(struct drm_device *dev, void *data,
10321038
struct drm_file *file_priv);
10331039
extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,

drivers/gpu/drm/i915/i915_irq.c

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -462,15 +462,18 @@ static void pch_irq_handler(struct drm_device *dev)
462462
DRM_DEBUG_DRIVER("PCH transcoder A underrun interrupt\n");
463463
}
464464

465-
static irqreturn_t ironlake_irq_handler(struct drm_device *dev)
465+
irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
466466
{
467+
struct drm_device *dev = (struct drm_device *) arg;
467468
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
468469
int ret = IRQ_NONE;
469470
u32 de_iir, gt_iir, de_ier, pch_iir, pm_iir;
470471
u32 hotplug_mask;
471472
struct drm_i915_master_private *master_priv;
472473
u32 bsd_usr_interrupt = GT_BSD_USER_INTERRUPT;
473474

475+
atomic_inc(&dev_priv->irq_received);
476+
474477
if (IS_GEN6(dev))
475478
bsd_usr_interrupt = GT_GEN6_BSD_USER_INTERRUPT;
476479

@@ -1134,9 +1137,6 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
11341137

11351138
atomic_inc(&dev_priv->irq_received);
11361139

1137-
if (HAS_PCH_SPLIT(dev))
1138-
return ironlake_irq_handler(dev);
1139-
11401140
iir = I915_READ(IIR);
11411141

11421142
if (INTEL_INFO(dev)->gen >= 4)
@@ -1593,10 +1593,15 @@ void i915_hangcheck_elapsed(unsigned long data)
15931593

15941594
/* drm_dma.h hooks
15951595
*/
1596-
static void ironlake_irq_preinstall(struct drm_device *dev)
1596+
void ironlake_irq_preinstall(struct drm_device *dev)
15971597
{
15981598
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
15991599

1600+
atomic_set(&dev_priv->irq_received, 0);
1601+
1602+
INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
1603+
INIT_WORK(&dev_priv->error_work, i915_error_work_func);
1604+
16001605
I915_WRITE(HWSTAM, 0xeffe);
16011606

16021607
/* XXX hotplug from PCH */
@@ -1616,7 +1621,7 @@ static void ironlake_irq_preinstall(struct drm_device *dev)
16161621
POSTING_READ(SDEIER);
16171622
}
16181623

1619-
static int ironlake_irq_postinstall(struct drm_device *dev)
1624+
int ironlake_irq_postinstall(struct drm_device *dev)
16201625
{
16211626
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
16221627
/* enable kind of interrupts always enabled */
@@ -1625,6 +1630,13 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
16251630
u32 render_irqs;
16261631
u32 hotplug_mask;
16271632

1633+
DRM_INIT_WAITQUEUE(&dev_priv->ring[RCS].irq_queue);
1634+
if (HAS_BSD(dev))
1635+
DRM_INIT_WAITQUEUE(&dev_priv->ring[VCS].irq_queue);
1636+
if (HAS_BLT(dev))
1637+
DRM_INIT_WAITQUEUE(&dev_priv->ring[BCS].irq_queue);
1638+
1639+
dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
16281640
dev_priv->irq_mask = ~display_mask;
16291641

16301642
/* should always can generate irq */
@@ -1692,11 +1704,6 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
16921704
INIT_WORK(&dev_priv->error_work, i915_error_work_func);
16931705
INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work);
16941706

1695-
if (HAS_PCH_SPLIT(dev)) {
1696-
ironlake_irq_preinstall(dev);
1697-
return;
1698-
}
1699-
17001707
if (I915_HAS_HOTPLUG(dev)) {
17011708
I915_WRITE(PORT_HOTPLUG_EN, 0);
17021709
I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
@@ -1722,9 +1729,6 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
17221729

17231730
dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
17241731

1725-
if (HAS_PCH_SPLIT(dev))
1726-
return ironlake_irq_postinstall(dev);
1727-
17281732
/* Unmask the interrupts that we always want on. */
17291733
dev_priv->irq_mask = ~I915_INTERRUPT_ENABLE_FIX;
17301734

@@ -1793,9 +1797,15 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
17931797
return 0;
17941798
}
17951799

1796-
static void ironlake_irq_uninstall(struct drm_device *dev)
1800+
void ironlake_irq_uninstall(struct drm_device *dev)
17971801
{
17981802
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1803+
1804+
if (!dev_priv)
1805+
return;
1806+
1807+
dev_priv->vblank_pipe = 0;
1808+
17991809
I915_WRITE(HWSTAM, 0xffffffff);
18001810

18011811
I915_WRITE(DEIMR, 0xffffffff);
@@ -1817,11 +1827,6 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
18171827

18181828
dev_priv->vblank_pipe = 0;
18191829

1820-
if (HAS_PCH_SPLIT(dev)) {
1821-
ironlake_irq_uninstall(dev);
1822-
return;
1823-
}
1824-
18251830
if (I915_HAS_HOTPLUG(dev)) {
18261831
I915_WRITE(PORT_HOTPLUG_EN, 0);
18271832
I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));

0 commit comments

Comments
 (0)