Commit 6ff8c76a authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/mc: fix race condition between constructor and request_irq()

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 0ff42c5a
...@@ -20,8 +20,8 @@ nouveau_mc(void *obj) ...@@ -20,8 +20,8 @@ nouveau_mc(void *obj)
return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_MC]; return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_MC];
} }
#define nouveau_mc_create(p,e,o,d) \ #define nouveau_mc_create(p,e,o,m,d) \
nouveau_mc_create_((p), (e), (o), sizeof(**d), (void **)d) nouveau_mc_create_((p), (e), (o), (m), sizeof(**d), (void **)d)
#define nouveau_mc_destroy(p) ({ \ #define nouveau_mc_destroy(p) ({ \
struct nouveau_mc *pmc = (p); _nouveau_mc_dtor(nv_object(pmc)); \ struct nouveau_mc *pmc = (p); _nouveau_mc_dtor(nv_object(pmc)); \
}) })
...@@ -33,7 +33,8 @@ nouveau_mc(void *obj) ...@@ -33,7 +33,8 @@ nouveau_mc(void *obj)
}) })
int nouveau_mc_create_(struct nouveau_object *, struct nouveau_object *, int nouveau_mc_create_(struct nouveau_object *, struct nouveau_object *,
struct nouveau_oclass *, int, void **); struct nouveau_oclass *, const struct nouveau_mc_intr *,
int, void **);
void _nouveau_mc_dtor(struct nouveau_object *); void _nouveau_mc_dtor(struct nouveau_object *);
int _nouveau_mc_init(struct nouveau_object *); int _nouveau_mc_init(struct nouveau_object *);
int _nouveau_mc_fini(struct nouveau_object *, bool); int _nouveau_mc_fini(struct nouveau_object *, bool);
......
...@@ -80,7 +80,9 @@ _nouveau_mc_dtor(struct nouveau_object *object) ...@@ -80,7 +80,9 @@ _nouveau_mc_dtor(struct nouveau_object *object)
int int
nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine, nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, int length, void **pobject) struct nouveau_oclass *oclass,
const struct nouveau_mc_intr *intr_map,
int length, void **pobject)
{ {
struct nouveau_device *device = nv_device(parent); struct nouveau_device *device = nv_device(parent);
struct nouveau_mc *pmc; struct nouveau_mc *pmc;
...@@ -92,6 +94,8 @@ nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -92,6 +94,8 @@ nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret) if (ret)
return ret; return ret;
pmc->intr_map = intr_map;
ret = request_irq(device->pdev->irq, nouveau_mc_intr, ret = request_irq(device->pdev->irq, nouveau_mc_intr,
IRQF_SHARED, "nouveau", pmc); IRQF_SHARED, "nouveau", pmc);
if (ret < 0) if (ret < 0)
......
...@@ -50,12 +50,11 @@ nv04_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -50,12 +50,11 @@ nv04_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv04_mc_priv *priv; struct nv04_mc_priv *priv;
int ret; int ret;
ret = nouveau_mc_create(parent, engine, oclass, &priv); ret = nouveau_mc_create(parent, engine, oclass, nv04_mc_intr, &priv);
*pobject = nv_object(priv); *pobject = nv_object(priv);
if (ret) if (ret)
return ret; return ret;
priv->base.intr_map = nv04_mc_intr;
return 0; return 0;
} }
......
...@@ -36,12 +36,11 @@ nv44_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -36,12 +36,11 @@ nv44_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv44_mc_priv *priv; struct nv44_mc_priv *priv;
int ret; int ret;
ret = nouveau_mc_create(parent, engine, oclass, &priv); ret = nouveau_mc_create(parent, engine, oclass, nv04_mc_intr, &priv);
*pobject = nv_object(priv); *pobject = nv_object(priv);
if (ret) if (ret)
return ret; return ret;
priv->base.intr_map = nv04_mc_intr;
return 0; return 0;
} }
......
...@@ -53,12 +53,11 @@ nv50_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -53,12 +53,11 @@ nv50_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv50_mc_priv *priv; struct nv50_mc_priv *priv;
int ret; int ret;
ret = nouveau_mc_create(parent, engine, oclass, &priv); ret = nouveau_mc_create(parent, engine, oclass, nv50_mc_intr, &priv);
*pobject = nv_object(priv); *pobject = nv_object(priv);
if (ret) if (ret)
return ret; return ret;
priv->base.intr_map = nv50_mc_intr;
return 0; return 0;
} }
......
...@@ -54,12 +54,11 @@ nv98_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -54,12 +54,11 @@ nv98_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv98_mc_priv *priv; struct nv98_mc_priv *priv;
int ret; int ret;
ret = nouveau_mc_create(parent, engine, oclass, &priv); ret = nouveau_mc_create(parent, engine, oclass, nv98_mc_intr, &priv);
*pobject = nv_object(priv); *pobject = nv_object(priv);
if (ret) if (ret)
return ret; return ret;
priv->base.intr_map = nv98_mc_intr;
return 0; return 0;
} }
......
...@@ -57,12 +57,11 @@ nvc0_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -57,12 +57,11 @@ nvc0_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nvc0_mc_priv *priv; struct nvc0_mc_priv *priv;
int ret; int ret;
ret = nouveau_mc_create(parent, engine, oclass, &priv); ret = nouveau_mc_create(parent, engine, oclass, nvc0_mc_intr, &priv);
*pobject = nv_object(priv); *pobject = nv_object(priv);
if (ret) if (ret)
return ret; return ret;
priv->base.intr_map = nvc0_mc_intr;
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment