From f4277a0e4212dab176a2f8cce2f91e7d948a371f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 13 May 2014 10:17:35 +1000 Subject: [PATCH] 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 --- .../gpu/drm/nouveau/core/subdev/gpio/base.c | 70 ++++++++++++++----- .../gpu/drm/nouveau/core/subdev/gpio/nv10.c | 36 +--------- .../gpu/drm/nouveau/core/subdev/gpio/nv50.c | 44 +----------- .../gpu/drm/nouveau/core/subdev/gpio/nv92.c | 6 +- .../gpu/drm/nouveau/core/subdev/gpio/nvd0.c | 6 +- .../gpu/drm/nouveau/core/subdev/gpio/nve0.c | 37 +--------- .../gpu/drm/nouveau/core/subdev/gpio/priv.h | 19 +++-- 7 files changed, 80 insertions(+), 138 deletions(-) diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c index dbf9b5d0e0a2..2ead9eb65940 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c @@ -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 _nouveau_gpio_dtor(struct nouveau_object *object) { @@ -173,24 +213,18 @@ nouveau_gpio_create_(struct nouveau_object *parent, 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 -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); - if (ret == 0 && gpio->reset) { - if (dmi_check_system(gpio_reset_ids)) - gpio->reset(gpio, DCB_GPIO_UNUSED); - } - return ret; + struct nouveau_gpio *gpio; + int ret; + + ret = nouveau_gpio_create(parent, engine, oclass, &gpio); + *pobject = nv_object(gpio); + if (ret) + return ret; + + return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv10.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv10.c index b0267e58e0d8..ff1785b9667a 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv10.c +++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv10.c @@ -121,44 +121,14 @@ nv10_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine, 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 * nv10_gpio_oclass = &(struct nouveau_gpio_impl) { .base.handle = NV_SUBDEV(GPIO, 0x10), .base.ofuncs = &(struct nouveau_ofuncs) { .ctor = nv10_gpio_ctor, - .dtor = nv10_gpio_dtor, - .init = nv10_gpio_init, - .fini = nv10_gpio_fini, + .dtor = _nouveau_gpio_dtor, + .init = _nouveau_gpio_init, + .fini = _nouveau_gpio_fini, }, .lines = 16, .intr_stat = nv10_gpio_intr_stat, diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c index 18493e21bfa5..067390f697f9 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c @@ -135,52 +135,14 @@ nv50_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine, 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 * nv50_gpio_oclass = &(struct nouveau_gpio_impl) { .base.handle = NV_SUBDEV(GPIO, 0x50), .base.ofuncs = &(struct nouveau_ofuncs) { .ctor = nv50_gpio_ctor, - .dtor = nv50_gpio_dtor, - .init = nv50_gpio_init, - .fini = nv50_gpio_fini, + .dtor = _nouveau_gpio_dtor, + .init = _nouveau_gpio_init, + .fini = _nouveau_gpio_fini, }, .lines = 16, .intr_stat = nv50_gpio_intr_stat, diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv92.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv92.c index 20c8849afc31..ab789ee16d30 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv92.c +++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv92.c @@ -61,9 +61,9 @@ nv92_gpio_oclass = &(struct nouveau_gpio_impl) { .base.handle = NV_SUBDEV(GPIO, 0x92), .base.ofuncs = &(struct nouveau_ofuncs) { .ctor = nv50_gpio_ctor, - .dtor = nv50_gpio_dtor, - .init = nv50_gpio_init, - .fini = nv50_gpio_fini, + .dtor = _nouveau_gpio_dtor, + .init = _nouveau_gpio_init, + .fini = _nouveau_gpio_fini, }, .lines = 32, .intr_stat = nv92_gpio_intr_stat, diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c index e08eade7d907..e91c36efd295 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c @@ -96,9 +96,9 @@ nvd0_gpio_oclass = &(struct nouveau_gpio_impl) { .base.handle = NV_SUBDEV(GPIO, 0xd0), .base.ofuncs = &(struct nouveau_ofuncs) { .ctor = nvd0_gpio_ctor, - .dtor = nv50_gpio_dtor, - .init = nv50_gpio_init, - .fini = nv50_gpio_fini, + .dtor = _nouveau_gpio_dtor, + .init = _nouveau_gpio_init, + .fini = _nouveau_gpio_fini, }, .lines = 32, .intr_stat = nv92_gpio_intr_stat, diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nve0.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/nve0.c index d407f9067a85..017c3c1eb024 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nve0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nve0.c @@ -60,37 +60,6 @@ nve0_gpio_intr_mask(struct nouveau_gpio *gpio, u32 type, u32 mask, u32 data) 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 nve0_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine, 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.ofuncs = &(struct nouveau_ofuncs) { .ctor = nve0_gpio_ctor, - .dtor = nv50_gpio_dtor, - .init = nve0_gpio_init, - .fini = nve0_gpio_fini, + .dtor = _nouveau_gpio_dtor, + .init = _nouveau_gpio_init, + .fini = _nouveau_gpio_fini, }, .lines = 32, .intr_stat = nve0_gpio_intr_stat, diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/priv.h b/drivers/gpu/drm/nouveau/core/subdev/gpio/priv.h index a31b7bae20b3..4f7b616a3e9e 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/gpio/priv.h +++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/priv.h @@ -9,20 +9,27 @@ struct nouveau_gpio *gpio = (p); \ _nouveau_gpio_dtor(nv_object(gpio)); \ }) -#define nouveau_gpio_fini(p,s) \ - nouveau_subdev_fini(&(p)->base, (s)) +#define nouveau_gpio_init(p) ({ \ + 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 *, 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 *); -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 *, struct nouveau_oclass *, void *, u32, 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); int nvd0_gpio_drive(struct nouveau_gpio *, int, int, int); -- GitLab