diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2013-03-22 00:05:03 (GMT) |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2013-04-26 05:37:52 (GMT) |
commit | 0fa9061ae8c10a9178d696cf48d94c3bf2848f9f (patch) | |
tree | d5edefa2d240ef8ef30a40327f98e853ba2b5853 /drivers/gpu/drm/nouveau/core/subdev | |
parent | 1a6463425552a8b9960e5a19b25421895846925c (diff) | |
download | linux-fsl-qoriq-0fa9061ae8c10a9178d696cf48d94c3bf2848f9f.tar.xz |
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 <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/subdev')
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/mc/base.c | 60 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c | 1 |
6 files changed, 56 insertions, 9 deletions
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/base.c b/drivers/gpu/drm/nouveau/core/subdev/mc/base.c index 8379aaf..1c0330b 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/base.c @@ -24,10 +24,10 @@ #include <subdev/mc.h> -void -nouveau_mc_intr(struct nouveau_subdev *subdev) +static irqreturn_t +nouveau_mc_intr(int irq, void *arg) { - struct nouveau_mc *pmc = nouveau_mc(subdev); + struct nouveau_mc *pmc = arg; const struct nouveau_mc_intr *map = pmc->intr_map; struct nouveau_subdev *unit; u32 stat, intr; @@ -35,7 +35,7 @@ nouveau_mc_intr(struct nouveau_subdev *subdev) intr = stat = nv_rd32(pmc, 0x000100); while (stat && map->stat) { if (stat & map->stat) { - unit = nouveau_subdev(subdev, map->unit); + unit = nouveau_subdev(pmc, map->unit); if (unit && unit->intr) unit->intr(unit); intr &= ~map->stat; @@ -46,4 +46,56 @@ nouveau_mc_intr(struct nouveau_subdev *subdev) if (intr) { nv_error(pmc, "unknown intr 0x%08x\n", stat); } + + return stat ? IRQ_HANDLED : IRQ_NONE; +} + +int +_nouveau_mc_fini(struct nouveau_object *object, bool suspend) +{ + struct nouveau_mc *pmc = (void *)object; + nv_wr32(pmc, 0x000140, 0x00000000); + return nouveau_subdev_fini(&pmc->base, suspend); +} + +int +_nouveau_mc_init(struct nouveau_object *object) +{ + struct nouveau_mc *pmc = (void *)object; + int ret = nouveau_subdev_init(&pmc->base); + if (ret) + return ret; + nv_wr32(pmc, 0x000140, 0x00000001); + return 0; +} + +void +_nouveau_mc_dtor(struct nouveau_object *object) +{ + struct nouveau_device *device = nv_device(object); + struct nouveau_mc *pmc = (void *)object; + free_irq(device->pdev->irq, pmc); + nouveau_subdev_destroy(&pmc->base); +} + +int +nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, int length, void **pobject) +{ + struct nouveau_device *device = nv_device(parent); + struct nouveau_mc *pmc; + int ret; + + ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PMC", + "master", length, pobject); + pmc = *pobject; + if (ret) + return ret; + + ret = request_irq(device->pdev->irq, nouveau_mc_intr, + IRQF_SHARED, "nouveau", pmc); + if (ret < 0) + return ret; + + return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c index 89da8fa..8c76971 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c @@ -55,7 +55,6 @@ nv04_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; - nv_subdev(priv)->intr = nouveau_mc_intr; priv->base.intr_map = nv04_mc_intr; return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c index 397d868..5191937 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c @@ -41,7 +41,6 @@ nv44_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; - nv_subdev(priv)->intr = nouveau_mc_intr; priv->base.intr_map = nv04_mc_intr; return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c index 5965add..d796924 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c @@ -57,7 +57,6 @@ nv50_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; - nv_subdev(priv)->intr = nouveau_mc_intr; priv->base.intr_map = nv50_mc_intr; return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c index 3a80b29..e82fd21 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c @@ -59,7 +59,6 @@ nv98_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; - nv_subdev(priv)->intr = nouveau_mc_intr; priv->base.intr_map = nv98_mc_intr; return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c index 42bbf72..737bd4b 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c @@ -61,7 +61,6 @@ nvc0_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; - nv_subdev(priv)->intr = nouveau_mc_intr; priv->base.intr_map = nvc0_mc_intr; return 0; } |