summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2014-05-13 10:17:35 +1000
committerBen Skeggs <bskeggs@redhat.com>2014-06-11 16:02:08 +1000
commit83adf1b108dfc0322b59e2d92eeb2652cb39e7d5 (patch)
treeac88bfbdac744f6328bed323304db2b704ad8cb1
parentc56fc2aa7bc7b46168f42dfb1d2207efa4449ed8 (diff)
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>
-rw-r--r--nvkm/subdev/gpio/base.c70
-rw-r--r--nvkm/subdev/gpio/nv10.c36
-rw-r--r--nvkm/subdev/gpio/nv50.c44
-rw-r--r--nvkm/subdev/gpio/nv92.c6
-rw-r--r--nvkm/subdev/gpio/nvd0.c6
-rw-r--r--nvkm/subdev/gpio/nve0.c37
-rw-r--r--nvkm/subdev/gpio/priv.h19
7 files changed, 80 insertions, 138 deletions
diff --git a/nvkm/subdev/gpio/base.c b/nvkm/subdev/gpio/base.c
index dbf9b5d0..2ead9eb6 100644
--- a/nvkm/subdev/gpio/base.c
+++ b/nvkm/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/nvkm/subdev/gpio/nv10.c b/nvkm/subdev/gpio/nv10.c
index b0267e58..ff1785b9 100644
--- a/nvkm/subdev/gpio/nv10.c
+++ b/nvkm/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/nvkm/subdev/gpio/nv50.c b/nvkm/subdev/gpio/nv50.c
index 18493e21..067390f6 100644
--- a/nvkm/subdev/gpio/nv50.c
+++ b/nvkm/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/nvkm/subdev/gpio/nv92.c b/nvkm/subdev/gpio/nv92.c
index 20c8849a..ab789ee1 100644
--- a/nvkm/subdev/gpio/nv92.c
+++ b/nvkm/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/nvkm/subdev/gpio/nvd0.c b/nvkm/subdev/gpio/nvd0.c
index e08eade7..e91c36ef 100644
--- a/nvkm/subdev/gpio/nvd0.c
+++ b/nvkm/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/nvkm/subdev/gpio/nve0.c b/nvkm/subdev/gpio/nve0.c
index d407f906..017c3c1e 100644
--- a/nvkm/subdev/gpio/nve0.c
+++ b/nvkm/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/nvkm/subdev/gpio/priv.h b/nvkm/subdev/gpio/priv.h
index a31b7bae..4f7b616a 100644
--- a/nvkm/subdev/gpio/priv.h
+++ b/nvkm/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);