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: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
5693c0f26f
commit
f4277a0e42
|
@ -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,
|
||||||
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);
|
||||||
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
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) {
|
||||||
.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) {
|
||||||
.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)
|
||||||
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) {
|
||||||
.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 @@
|
||||||
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);
|
||||||
|
|
Loading…
Reference in New Issue