Commit f4277a0e authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/gpio: move on-reset intr disable-and-ack to common code

Re-uses the implementation's accessor functions rather than requiring
and init/fini implementation for each chipset.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 5693c0f2
...@@ -134,6 +134,46 @@ nouveau_gpio_intr(struct nouveau_subdev *subdev) ...@@ -134,6 +134,46 @@ nouveau_gpio_intr(struct nouveau_subdev *subdev)
} }
} }
int
_nouveau_gpio_fini(struct nouveau_object *object, bool suspend)
{
const struct nouveau_gpio_impl *impl = (void *)object->oclass;
struct nouveau_gpio *gpio = nouveau_gpio(object);
u32 mask = (1 << impl->lines) - 1;
impl->intr_mask(gpio, NVKM_GPIO_TOGGLED, mask, 0);
impl->intr_stat(gpio, &mask, &mask);
return nouveau_subdev_fini(&gpio->base, suspend);
}
static struct dmi_system_id gpio_reset_ids[] = {
{
.ident = "Apple Macbook 10,1",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro10,1"),
}
},
{ }
};
int
_nouveau_gpio_init(struct nouveau_object *object)
{
struct nouveau_gpio *gpio = nouveau_gpio(object);
int ret;
ret = nouveau_subdev_init(&gpio->base);
if (ret)
return ret;
if (gpio->reset && dmi_check_system(gpio_reset_ids))
gpio->reset(gpio, DCB_GPIO_UNUSED);
return ret;
}
void void
_nouveau_gpio_dtor(struct nouveau_object *object) _nouveau_gpio_dtor(struct nouveau_object *object)
{ {
...@@ -173,24 +213,18 @@ nouveau_gpio_create_(struct nouveau_object *parent, ...@@ -173,24 +213,18 @@ nouveau_gpio_create_(struct nouveau_object *parent,
return 0; return 0;
} }
static struct dmi_system_id gpio_reset_ids[] = {
{
.ident = "Apple Macbook 10,1",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro10,1"),
}
},
{ }
};
int int
nouveau_gpio_init(struct nouveau_gpio *gpio) _nouveau_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{ {
int ret = nouveau_subdev_init(&gpio->base); struct nouveau_gpio *gpio;
if (ret == 0 && gpio->reset) { int ret;
if (dmi_check_system(gpio_reset_ids))
gpio->reset(gpio, DCB_GPIO_UNUSED); ret = nouveau_gpio_create(parent, engine, oclass, &gpio);
} *pobject = nv_object(gpio);
return ret; if (ret)
return ret;
return 0;
} }
...@@ -121,44 +121,14 @@ nv10_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -121,44 +121,14 @@ nv10_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0; return 0;
} }
static void
nv10_gpio_dtor(struct nouveau_object *object)
{
struct nv10_gpio_priv *priv = (void *)object;
nouveau_gpio_destroy(&priv->base);
}
static int
nv10_gpio_init(struct nouveau_object *object)
{
struct nv10_gpio_priv *priv = (void *)object;
int ret;
ret = nouveau_gpio_init(&priv->base);
if (ret)
return ret;
nv_wr32(priv, 0x001144, 0x00000000);
nv_wr32(priv, 0x001104, 0xffffffff);
return 0;
}
static int
nv10_gpio_fini(struct nouveau_object *object, bool suspend)
{
struct nv10_gpio_priv *priv = (void *)object;
nv_wr32(priv, 0x001144, 0x00000000);
return nouveau_gpio_fini(&priv->base, suspend);
}
struct nouveau_oclass * struct nouveau_oclass *
nv10_gpio_oclass = &(struct nouveau_gpio_impl) { nv10_gpio_oclass = &(struct nouveau_gpio_impl) {
.base.handle = NV_SUBDEV(GPIO, 0x10), .base.handle = NV_SUBDEV(GPIO, 0x10),
.base.ofuncs = &(struct nouveau_ofuncs) { .base.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv10_gpio_ctor, .ctor = nv10_gpio_ctor,
.dtor = nv10_gpio_dtor, .dtor = _nouveau_gpio_dtor,
.init = nv10_gpio_init, .init = _nouveau_gpio_init,
.fini = nv10_gpio_fini, .fini = _nouveau_gpio_fini,
}, },
.lines = 16, .lines = 16,
.intr_stat = nv10_gpio_intr_stat, .intr_stat = nv10_gpio_intr_stat,
......
...@@ -135,52 +135,14 @@ nv50_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -135,52 +135,14 @@ nv50_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0; return 0;
} }
void
nv50_gpio_dtor(struct nouveau_object *object)
{
struct nv50_gpio_priv *priv = (void *)object;
nouveau_gpio_destroy(&priv->base);
}
int
nv50_gpio_init(struct nouveau_object *object)
{
struct nv50_gpio_priv *priv = (void *)object;
int ret;
ret = nouveau_gpio_init(&priv->base);
if (ret)
return ret;
/* disable, and ack any pending gpio interrupts */
nv_wr32(priv, 0xe050, 0x00000000);
nv_wr32(priv, 0xe054, 0xffffffff);
if (nv_device(priv)->chipset > 0x92) {
nv_wr32(priv, 0xe070, 0x00000000);
nv_wr32(priv, 0xe074, 0xffffffff);
}
return 0;
}
int
nv50_gpio_fini(struct nouveau_object *object, bool suspend)
{
struct nv50_gpio_priv *priv = (void *)object;
nv_wr32(priv, 0xe050, 0x00000000);
if (nv_device(priv)->chipset > 0x92)
nv_wr32(priv, 0xe070, 0x00000000);
return nouveau_gpio_fini(&priv->base, suspend);
}
struct nouveau_oclass * struct nouveau_oclass *
nv50_gpio_oclass = &(struct nouveau_gpio_impl) { nv50_gpio_oclass = &(struct nouveau_gpio_impl) {
.base.handle = NV_SUBDEV(GPIO, 0x50), .base.handle = NV_SUBDEV(GPIO, 0x50),
.base.ofuncs = &(struct nouveau_ofuncs) { .base.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv50_gpio_ctor, .ctor = nv50_gpio_ctor,
.dtor = nv50_gpio_dtor, .dtor = _nouveau_gpio_dtor,
.init = nv50_gpio_init, .init = _nouveau_gpio_init,
.fini = nv50_gpio_fini, .fini = _nouveau_gpio_fini,
}, },
.lines = 16, .lines = 16,
.intr_stat = nv50_gpio_intr_stat, .intr_stat = nv50_gpio_intr_stat,
......
...@@ -61,9 +61,9 @@ nv92_gpio_oclass = &(struct nouveau_gpio_impl) { ...@@ -61,9 +61,9 @@ nv92_gpio_oclass = &(struct nouveau_gpio_impl) {
.base.handle = NV_SUBDEV(GPIO, 0x92), .base.handle = NV_SUBDEV(GPIO, 0x92),
.base.ofuncs = &(struct nouveau_ofuncs) { .base.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv50_gpio_ctor, .ctor = nv50_gpio_ctor,
.dtor = nv50_gpio_dtor, .dtor = _nouveau_gpio_dtor,
.init = nv50_gpio_init, .init = _nouveau_gpio_init,
.fini = nv50_gpio_fini, .fini = _nouveau_gpio_fini,
}, },
.lines = 32, .lines = 32,
.intr_stat = nv92_gpio_intr_stat, .intr_stat = nv92_gpio_intr_stat,
......
...@@ -96,9 +96,9 @@ nvd0_gpio_oclass = &(struct nouveau_gpio_impl) { ...@@ -96,9 +96,9 @@ nvd0_gpio_oclass = &(struct nouveau_gpio_impl) {
.base.handle = NV_SUBDEV(GPIO, 0xd0), .base.handle = NV_SUBDEV(GPIO, 0xd0),
.base.ofuncs = &(struct nouveau_ofuncs) { .base.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nvd0_gpio_ctor, .ctor = nvd0_gpio_ctor,
.dtor = nv50_gpio_dtor, .dtor = _nouveau_gpio_dtor,
.init = nv50_gpio_init, .init = _nouveau_gpio_init,
.fini = nv50_gpio_fini, .fini = _nouveau_gpio_fini,
}, },
.lines = 32, .lines = 32,
.intr_stat = nv92_gpio_intr_stat, .intr_stat = nv92_gpio_intr_stat,
......
...@@ -60,37 +60,6 @@ nve0_gpio_intr_mask(struct nouveau_gpio *gpio, u32 type, u32 mask, u32 data) ...@@ -60,37 +60,6 @@ nve0_gpio_intr_mask(struct nouveau_gpio *gpio, u32 type, u32 mask, u32 data)
nv_wr32(gpio, 0x00dc88, inte1); nv_wr32(gpio, 0x00dc88, inte1);
} }
int
nve0_gpio_fini(struct nouveau_object *object, bool suspend)
{
struct nve0_gpio_priv *priv = (void *)object;
nv_wr32(priv, 0xdc08, 0x00000000);
nv_wr32(priv, 0xdc88, 0x00000000);
return nouveau_gpio_fini(&priv->base, suspend);
}
int
nve0_gpio_init(struct nouveau_object *object)
{
struct nve0_gpio_priv *priv = (void *)object;
int ret;
ret = nouveau_gpio_init(&priv->base);
if (ret)
return ret;
nv_wr32(priv, 0xdc00, 0xffffffff);
nv_wr32(priv, 0xdc80, 0xffffffff);
return 0;
}
void
nve0_gpio_dtor(struct nouveau_object *object)
{
struct nve0_gpio_priv *priv = (void *)object;
nouveau_gpio_destroy(&priv->base);
}
static int static int
nve0_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine, nve0_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_oclass *oclass, void *data, u32 size,
...@@ -115,9 +84,9 @@ nve0_gpio_oclass = &(struct nouveau_gpio_impl) { ...@@ -115,9 +84,9 @@ nve0_gpio_oclass = &(struct nouveau_gpio_impl) {
.base.handle = NV_SUBDEV(GPIO, 0xe0), .base.handle = NV_SUBDEV(GPIO, 0xe0),
.base.ofuncs = &(struct nouveau_ofuncs) { .base.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nve0_gpio_ctor, .ctor = nve0_gpio_ctor,
.dtor = nv50_gpio_dtor, .dtor = _nouveau_gpio_dtor,
.init = nve0_gpio_init, .init = _nouveau_gpio_init,
.fini = nve0_gpio_fini, .fini = _nouveau_gpio_fini,
}, },
.lines = 32, .lines = 32,
.intr_stat = nve0_gpio_intr_stat, .intr_stat = nve0_gpio_intr_stat,
......
...@@ -9,20 +9,27 @@ ...@@ -9,20 +9,27 @@
struct nouveau_gpio *gpio = (p); \ struct nouveau_gpio *gpio = (p); \
_nouveau_gpio_dtor(nv_object(gpio)); \ _nouveau_gpio_dtor(nv_object(gpio)); \
}) })
#define nouveau_gpio_fini(p,s) \ #define nouveau_gpio_init(p) ({ \
nouveau_subdev_fini(&(p)->base, (s)) struct nouveau_gpio *gpio = (p); \
_nouveau_gpio_init(nv_object(gpio)); \
})
#define nouveau_gpio_fini(p,s) ({ \
struct nouveau_gpio *gpio = (p); \
_nouveau_gpio_fini(nv_object(gpio), (s)); \
})
int nouveau_gpio_create_(struct nouveau_object *, struct nouveau_object *, int nouveau_gpio_create_(struct nouveau_object *, struct nouveau_object *,
struct nouveau_oclass *, int, void **); struct nouveau_oclass *, int, void **);
int _nouveau_gpio_ctor(struct nouveau_object *, struct nouveau_object *,
struct nouveau_oclass *, void *, u32,
struct nouveau_object **);
void _nouveau_gpio_dtor(struct nouveau_object *); void _nouveau_gpio_dtor(struct nouveau_object *);
int nouveau_gpio_init(struct nouveau_gpio *); int _nouveau_gpio_init(struct nouveau_object *);
int _nouveau_gpio_fini(struct nouveau_object *, bool);
int nv50_gpio_ctor(struct nouveau_object *, struct nouveau_object *, int nv50_gpio_ctor(struct nouveau_object *, struct nouveau_object *,
struct nouveau_oclass *, void *, u32, struct nouveau_oclass *, void *, u32,
struct nouveau_object **); struct nouveau_object **);
void nv50_gpio_dtor(struct nouveau_object *);
int nv50_gpio_init(struct nouveau_object *);
int nv50_gpio_fini(struct nouveau_object *, bool);
void nvd0_gpio_reset(struct nouveau_gpio *, u8); void nvd0_gpio_reset(struct nouveau_gpio *, u8);
int nvd0_gpio_drive(struct nouveau_gpio *, int, int, int); int nvd0_gpio_drive(struct nouveau_gpio *, int, int, int);
......
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