drm/nouveau/gpio: move on-reset intr disable-and-ack to common code
authorBen Skeggs <bskeggs@redhat.com>
Tue, 13 May 2014 00:17:35 +0000 (10:17 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 11 Jun 2014 06:09:14 +0000 (16:09 +1000)
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>
drivers/gpu/drm/nouveau/core/subdev/gpio/base.c
drivers/gpu/drm/nouveau/core/subdev/gpio/nv10.c
drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c
drivers/gpu/drm/nouveau/core/subdev/gpio/nv92.c
drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c
drivers/gpu/drm/nouveau/core/subdev/gpio/nve0.c
drivers/gpu/drm/nouveau/core/subdev/gpio/priv.h

index dbf9b5d..2ead9eb 100644 (file)
@@ -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;
 }
index b0267e5..ff1785b 100644 (file)
@@ -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,
index 18493e2..067390f 100644 (file)
@@ -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,
index 20c8849..ab789ee 100644 (file)
@@ -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,
index e08eade..e91c36e 100644 (file)
@@ -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,
index d407f90..017c3c1 100644 (file)
@@ -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,
index a31b7ba..4f7b616 100644 (file)
@@ -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);