Skip to content

Commit 0fa9061

Browse files
author
Ben Skeggs
committed
drm/nouveau/mc: handle irq-related setup ourselves
We need to be able to process interrupts before the DRM code is able to actually enable them, set it up ourselves. Also, it's less convoluted to *not* use the DRM wrappers it appears... Signed-off-by: Ben Skeggs <[email protected]>
1 parent 1a64634 commit 0fa9061

File tree

12 files changed

+75
-127
lines changed

12 files changed

+75
-127
lines changed

drivers/gpu/drm/nouveau/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ nouveau-y += core/engine/vp/nve0.o
213213

214214
# drm/core
215215
nouveau-y += nouveau_drm.o nouveau_chan.o nouveau_dma.o nouveau_fence.o
216-
nouveau-y += nouveau_irq.o nouveau_vga.o nouveau_agp.o
216+
nouveau-y += nouveau_vga.o nouveau_agp.o
217217
nouveau-y += nouveau_ttm.o nouveau_sgdma.o nouveau_bo.o nouveau_gem.o
218218
nouveau-y += nouveau_prime.o nouveau_abi16.o
219219
nouveau-y += nv04_fence.o nv10_fence.o nv17_fence.o

drivers/gpu/drm/nouveau/core/include/subdev/mc.h

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,27 +21,29 @@ nouveau_mc(void *obj)
2121
}
2222

2323
#define nouveau_mc_create(p,e,o,d) \
24-
nouveau_subdev_create_((p), (e), (o), 0, "PMC", "master", \
25-
sizeof(**d), (void **)d)
26-
#define nouveau_mc_destroy(p) \
27-
nouveau_subdev_destroy(&(p)->base)
28-
#define nouveau_mc_init(p) \
29-
nouveau_subdev_init(&(p)->base)
30-
#define nouveau_mc_fini(p,s) \
31-
nouveau_subdev_fini(&(p)->base, (s))
32-
33-
#define _nouveau_mc_dtor _nouveau_subdev_dtor
34-
#define _nouveau_mc_init _nouveau_subdev_init
35-
#define _nouveau_mc_fini _nouveau_subdev_fini
24+
nouveau_mc_create_((p), (e), (o), sizeof(**d), (void **)d)
25+
#define nouveau_mc_destroy(p) ({ \
26+
struct nouveau_mc *pmc = (p); _nouveau_mc_dtor(nv_object(pmc)); \
27+
})
28+
#define nouveau_mc_init(p) ({ \
29+
struct nouveau_mc *pmc = (p); _nouveau_mc_init(nv_object(pmc)); \
30+
})
31+
#define nouveau_mc_fini(p,s) ({ \
32+
struct nouveau_mc *pmc = (p); _nouveau_mc_fini(nv_object(pmc), (s)); \
33+
})
34+
35+
int nouveau_mc_create_(struct nouveau_object *, struct nouveau_object *,
36+
struct nouveau_oclass *, int, void **);
37+
void _nouveau_mc_dtor(struct nouveau_object *);
38+
int _nouveau_mc_init(struct nouveau_object *);
39+
int _nouveau_mc_fini(struct nouveau_object *, bool);
3640

3741
extern struct nouveau_oclass nv04_mc_oclass;
3842
extern struct nouveau_oclass nv44_mc_oclass;
3943
extern struct nouveau_oclass nv50_mc_oclass;
4044
extern struct nouveau_oclass nv98_mc_oclass;
4145
extern struct nouveau_oclass nvc0_mc_oclass;
4246

43-
void nouveau_mc_intr(struct nouveau_subdev *);
44-
4547
extern const struct nouveau_mc_intr nv04_mc_intr[];
4648
int nv04_mc_init(struct nouveau_object *);
4749
int nv50_mc_init(struct nouveau_object *);

drivers/gpu/drm/nouveau/core/os.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/acpi.h>
1818
#include <linux/dmi.h>
1919
#include <linux/reboot.h>
20+
#include <linux/interrupt.h>
2021

2122
#include <asm/unaligned.h>
2223

drivers/gpu/drm/nouveau/core/subdev/mc/base.c

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,18 @@
2424

2525
#include <subdev/mc.h>
2626

27-
void
28-
nouveau_mc_intr(struct nouveau_subdev *subdev)
27+
static irqreturn_t
28+
nouveau_mc_intr(int irq, void *arg)
2929
{
30-
struct nouveau_mc *pmc = nouveau_mc(subdev);
30+
struct nouveau_mc *pmc = arg;
3131
const struct nouveau_mc_intr *map = pmc->intr_map;
3232
struct nouveau_subdev *unit;
3333
u32 stat, intr;
3434

3535
intr = stat = nv_rd32(pmc, 0x000100);
3636
while (stat && map->stat) {
3737
if (stat & map->stat) {
38-
unit = nouveau_subdev(subdev, map->unit);
38+
unit = nouveau_subdev(pmc, map->unit);
3939
if (unit && unit->intr)
4040
unit->intr(unit);
4141
intr &= ~map->stat;
@@ -46,4 +46,56 @@ nouveau_mc_intr(struct nouveau_subdev *subdev)
4646
if (intr) {
4747
nv_error(pmc, "unknown intr 0x%08x\n", stat);
4848
}
49+
50+
return stat ? IRQ_HANDLED : IRQ_NONE;
51+
}
52+
53+
int
54+
_nouveau_mc_fini(struct nouveau_object *object, bool suspend)
55+
{
56+
struct nouveau_mc *pmc = (void *)object;
57+
nv_wr32(pmc, 0x000140, 0x00000000);
58+
return nouveau_subdev_fini(&pmc->base, suspend);
59+
}
60+
61+
int
62+
_nouveau_mc_init(struct nouveau_object *object)
63+
{
64+
struct nouveau_mc *pmc = (void *)object;
65+
int ret = nouveau_subdev_init(&pmc->base);
66+
if (ret)
67+
return ret;
68+
nv_wr32(pmc, 0x000140, 0x00000001);
69+
return 0;
70+
}
71+
72+
void
73+
_nouveau_mc_dtor(struct nouveau_object *object)
74+
{
75+
struct nouveau_device *device = nv_device(object);
76+
struct nouveau_mc *pmc = (void *)object;
77+
free_irq(device->pdev->irq, pmc);
78+
nouveau_subdev_destroy(&pmc->base);
79+
}
80+
81+
int
82+
nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
83+
struct nouveau_oclass *oclass, int length, void **pobject)
84+
{
85+
struct nouveau_device *device = nv_device(parent);
86+
struct nouveau_mc *pmc;
87+
int ret;
88+
89+
ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PMC",
90+
"master", length, pobject);
91+
pmc = *pobject;
92+
if (ret)
93+
return ret;
94+
95+
ret = request_irq(device->pdev->irq, nouveau_mc_intr,
96+
IRQF_SHARED, "nouveau", pmc);
97+
if (ret < 0)
98+
return ret;
99+
100+
return 0;
49101
}

drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ nv04_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
5555
if (ret)
5656
return ret;
5757

58-
nv_subdev(priv)->intr = nouveau_mc_intr;
5958
priv->base.intr_map = nv04_mc_intr;
6059
return 0;
6160
}

drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ nv44_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
4141
if (ret)
4242
return ret;
4343

44-
nv_subdev(priv)->intr = nouveau_mc_intr;
4544
priv->base.intr_map = nv04_mc_intr;
4645
return 0;
4746
}

drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ nv50_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
5757
if (ret)
5858
return ret;
5959

60-
nv_subdev(priv)->intr = nouveau_mc_intr;
6160
priv->base.intr_map = nv50_mc_intr;
6261
return 0;
6362
}

drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ nv98_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
5959
if (ret)
6060
return ret;
6161

62-
nv_subdev(priv)->intr = nouveau_mc_intr;
6362
priv->base.intr_map = nv98_mc_intr;
6463
return 0;
6564
}

drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ nvc0_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
6161
if (ret)
6262
return ret;
6363

64-
nv_subdev(priv)->intr = nouveau_mc_intr;
6564
priv->base.intr_map = nvc0_mc_intr;
6665
return 0;
6766
}

drivers/gpu/drm/nouveau/nouveau_drm.c

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
#include <engine/disp.h>
3838

3939
#include "nouveau_drm.h"
40-
#include "nouveau_irq.h"
4140
#include "nouveau_dma.h"
4241
#include "nouveau_ttm.h"
4342
#include "nouveau_gem.h"
@@ -365,10 +364,6 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
365364
if (ret)
366365
goto fail_bios;
367366

368-
ret = nouveau_irq_init(dev);
369-
if (ret)
370-
goto fail_irq;
371-
372367
ret = nouveau_display_create(dev);
373368
if (ret)
374369
goto fail_dispctor;
@@ -388,8 +383,6 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
388383
fail_dispinit:
389384
nouveau_display_destroy(dev);
390385
fail_dispctor:
391-
nouveau_irq_fini(dev);
392-
fail_irq:
393386
nouveau_bios_takedown(dev);
394387
fail_bios:
395388
nouveau_ttm_fini(drm);
@@ -415,7 +408,6 @@ nouveau_drm_unload(struct drm_device *dev)
415408
nouveau_display_fini(dev);
416409
nouveau_display_destroy(dev);
417410

418-
nouveau_irq_fini(dev);
419411
nouveau_bios_takedown(dev);
420412

421413
nouveau_ttm_fini(drm);
@@ -533,7 +525,6 @@ nouveau_do_resume(struct drm_device *dev)
533525
nouveau_fence(drm)->resume(drm);
534526

535527
nouveau_run_vbios_init(dev);
536-
nouveau_irq_postinstall(dev);
537528
nouveau_pm_resume(dev);
538529

539530
if (dev->mode_config.num_crtc) {
@@ -669,8 +660,7 @@ static struct drm_driver
669660
driver = {
670661
.driver_features =
671662
DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG |
672-
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM |
673-
DRIVER_MODESET | DRIVER_PRIME,
663+
DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME,
674664

675665
.load = nouveau_drm_load,
676666
.unload = nouveau_drm_unload,
@@ -684,11 +674,6 @@ driver = {
684674
.debugfs_cleanup = nouveau_debugfs_takedown,
685675
#endif
686676

687-
.irq_preinstall = nouveau_irq_preinstall,
688-
.irq_postinstall = nouveau_irq_postinstall,
689-
.irq_uninstall = nouveau_irq_uninstall,
690-
.irq_handler = nouveau_irq_handler,
691-
692677
.get_vblank_counter = drm_vblank_count,
693678
.enable_vblank = nouveau_drm_vblank_enable,
694679
.disable_vblank = nouveau_drm_vblank_disable,

0 commit comments

Comments
 (0)