summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2014-05-13 10:33:23 +1000
committerBen Skeggs <bskeggs@redhat.com>2014-06-11 16:02:08 +1000
commit9dd7079a34c0a7b6ce7e9179241b3af1cb9e76ce (patch)
treee808b0800b33976b8c2d271020117ea862fec81d
parent83adf1b108dfc0322b59e2d92eeb2652cb39e7d5 (diff)
gpio: use base constructor for all implementations
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--nvkm/include/subdev/gpio.h5
-rw-r--r--nvkm/subdev/gpio/base.c7
-rw-r--r--nvkm/subdev/gpio/nv10.c26
-rw-r--r--nvkm/subdev/gpio/nv50.c37
-rw-r--r--nvkm/subdev/gpio/nv92.c5
-rw-r--r--nvkm/subdev/gpio/nvd0.c33
-rw-r--r--nvkm/subdev/gpio/nve0.c28
-rw-r--r--nvkm/subdev/gpio/priv.h25
8 files changed, 47 insertions, 119 deletions
diff --git a/nvkm/include/subdev/gpio.h b/nvkm/include/subdev/gpio.h
index 856216aa..2e2effa6 100644
--- a/nvkm/include/subdev/gpio.h
+++ b/nvkm/include/subdev/gpio.h
@@ -13,12 +13,7 @@ struct nouveau_gpio {
struct nouveau_event *events;
- /* hardware interfaces */
void (*reset)(struct nouveau_gpio *, u8 func);
- int (*drive)(struct nouveau_gpio *, int line, int dir, int out);
- int (*sense)(struct nouveau_gpio *, int line);
-
- /* software interfaces */
int (*find)(struct nouveau_gpio *, int idx, u8 tag, u8 line,
struct dcb_gpio_func *);
int (*set)(struct nouveau_gpio *, int idx, u8 tag, u8 line, int state);
diff --git a/nvkm/subdev/gpio/base.c b/nvkm/subdev/gpio/base.c
index 2ead9eb6..e43bc9f0 100644
--- a/nvkm/subdev/gpio/base.c
+++ b/nvkm/subdev/gpio/base.c
@@ -31,13 +31,15 @@ static int
nouveau_gpio_drive(struct nouveau_gpio *gpio,
int idx, int line, int dir, int out)
{
- return gpio->drive ? gpio->drive(gpio, line, dir, out) : -ENODEV;
+ const struct nouveau_gpio_impl *impl = (void *)nv_object(gpio)->oclass;
+ return impl->drive ? impl->drive(gpio, line, dir, out) : -ENODEV;
}
static int
nouveau_gpio_sense(struct nouveau_gpio *gpio, int idx, int line)
{
- return gpio->sense ? gpio->sense(gpio, line) : -ENODEV;
+ const struct nouveau_gpio_impl *impl = (void *)nv_object(gpio)->oclass;
+ return impl->sense ? impl->sense(gpio, line) : -ENODEV;
}
static int
@@ -201,6 +203,7 @@ nouveau_gpio_create_(struct nouveau_object *parent,
gpio->find = nouveau_gpio_find;
gpio->set = nouveau_gpio_set;
gpio->get = nouveau_gpio_get;
+ gpio->reset = impl->reset;
ret = nouveau_event_create(1, impl->lines, &gpio->events);
if (ret)
diff --git a/nvkm/subdev/gpio/nv10.c b/nvkm/subdev/gpio/nv10.c
index ff1785b9..27ad23ea 100644
--- a/nvkm/subdev/gpio/nv10.c
+++ b/nvkm/subdev/gpio/nv10.c
@@ -26,10 +26,6 @@
#include "priv.h"
-struct nv10_gpio_priv {
- struct nouveau_gpio base;
-};
-
static int
nv10_gpio_sense(struct nouveau_gpio *gpio, int line)
{
@@ -103,29 +99,11 @@ nv10_gpio_intr_mask(struct nouveau_gpio *gpio, u32 type, u32 mask, u32 data)
nv_wr32(gpio, 0x001144, inte);
}
-static int
-nv10_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nv10_gpio_priv *priv;
- int ret;
-
- ret = nouveau_gpio_create(parent, engine, oclass, &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- priv->base.drive = nv10_gpio_drive;
- priv->base.sense = nv10_gpio_sense;
- return 0;
-}
-
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,
+ .ctor = _nouveau_gpio_ctor,
.dtor = _nouveau_gpio_dtor,
.init = _nouveau_gpio_init,
.fini = _nouveau_gpio_fini,
@@ -133,4 +111,6 @@ nv10_gpio_oclass = &(struct nouveau_gpio_impl) {
.lines = 16,
.intr_stat = nv10_gpio_intr_stat,
.intr_mask = nv10_gpio_intr_mask,
+ .drive = nv10_gpio_drive,
+ .sense = nv10_gpio_sense,
}.base;
diff --git a/nvkm/subdev/gpio/nv50.c b/nvkm/subdev/gpio/nv50.c
index 067390f6..1864fa98 100644
--- a/nvkm/subdev/gpio/nv50.c
+++ b/nvkm/subdev/gpio/nv50.c
@@ -24,15 +24,10 @@
#include "priv.h"
-struct nv50_gpio_priv {
- struct nouveau_gpio base;
-};
-
-static void
+void
nv50_gpio_reset(struct nouveau_gpio *gpio, u8 match)
{
struct nouveau_bios *bios = nouveau_bios(gpio);
- struct nv50_gpio_priv *priv = (void *)gpio;
u8 ver, len;
u16 entry;
int ent = -1;
@@ -55,7 +50,7 @@ nv50_gpio_reset(struct nouveau_gpio *gpio, u8 match)
gpio->set(gpio, 0, func, line, defs);
- nv_mask(priv, reg, 0x00010001 << lsh, val << lsh);
+ nv_mask(gpio, reg, 0x00010001 << lsh, val << lsh);
}
}
@@ -72,7 +67,7 @@ nv50_gpio_location(int line, u32 *reg, u32 *shift)
return 0;
}
-static int
+int
nv50_gpio_drive(struct nouveau_gpio *gpio, int line, int dir, int out)
{
u32 reg, shift;
@@ -84,7 +79,7 @@ nv50_gpio_drive(struct nouveau_gpio *gpio, int line, int dir, int out)
return 0;
}
-static int
+int
nv50_gpio_sense(struct nouveau_gpio *gpio, int line)
{
u32 reg, shift;
@@ -116,30 +111,11 @@ nv50_gpio_intr_mask(struct nouveau_gpio *gpio, u32 type, u32 mask, u32 data)
nv_wr32(gpio, 0x00e050, inte);
}
-int
-nv50_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nv50_gpio_priv *priv;
- int ret;
-
- ret = nouveau_gpio_create(parent, engine, oclass, &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- priv->base.reset = nv50_gpio_reset;
- priv->base.drive = nv50_gpio_drive;
- priv->base.sense = nv50_gpio_sense;
- return 0;
-}
-
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,
+ .ctor = _nouveau_gpio_ctor,
.dtor = _nouveau_gpio_dtor,
.init = _nouveau_gpio_init,
.fini = _nouveau_gpio_fini,
@@ -147,4 +123,7 @@ nv50_gpio_oclass = &(struct nouveau_gpio_impl) {
.lines = 16,
.intr_stat = nv50_gpio_intr_stat,
.intr_mask = nv50_gpio_intr_mask,
+ .drive = nv50_gpio_drive,
+ .sense = nv50_gpio_sense,
+ .reset = nv50_gpio_reset,
}.base;
diff --git a/nvkm/subdev/gpio/nv92.c b/nvkm/subdev/gpio/nv92.c
index ab789ee1..252083d3 100644
--- a/nvkm/subdev/gpio/nv92.c
+++ b/nvkm/subdev/gpio/nv92.c
@@ -60,7 +60,7 @@ struct nouveau_oclass *
nv92_gpio_oclass = &(struct nouveau_gpio_impl) {
.base.handle = NV_SUBDEV(GPIO, 0x92),
.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv50_gpio_ctor,
+ .ctor = _nouveau_gpio_ctor,
.dtor = _nouveau_gpio_dtor,
.init = _nouveau_gpio_init,
.fini = _nouveau_gpio_fini,
@@ -68,4 +68,7 @@ nv92_gpio_oclass = &(struct nouveau_gpio_impl) {
.lines = 32,
.intr_stat = nv92_gpio_intr_stat,
.intr_mask = nv92_gpio_intr_mask,
+ .drive = nv50_gpio_drive,
+ .sense = nv50_gpio_sense,
+ .reset = nv50_gpio_reset,
}.base;
diff --git a/nvkm/subdev/gpio/nvd0.c b/nvkm/subdev/gpio/nvd0.c
index e91c36ef..a4682b09 100644
--- a/nvkm/subdev/gpio/nvd0.c
+++ b/nvkm/subdev/gpio/nvd0.c
@@ -24,15 +24,10 @@
#include "priv.h"
-struct nvd0_gpio_priv {
- struct nouveau_gpio base;
-};
-
void
nvd0_gpio_reset(struct nouveau_gpio *gpio, u8 match)
{
struct nouveau_bios *bios = nouveau_bios(gpio);
- struct nvd0_gpio_priv *priv = (void *)gpio;
u8 ver, len;
u16 entry;
int ent = -1;
@@ -51,9 +46,9 @@ nvd0_gpio_reset(struct nouveau_gpio *gpio, u8 match)
gpio->set(gpio, 0, func, line, defs);
- nv_mask(priv, 0x00d610 + (line * 4), 0xff, unk0);
+ nv_mask(gpio, 0x00d610 + (line * 4), 0xff, unk0);
if (unk1--)
- nv_mask(priv, 0x00d740 + (unk1 * 4), 0xff, line);
+ nv_mask(gpio, 0x00d740 + (unk1 * 4), 0xff, line);
}
}
@@ -72,30 +67,11 @@ nvd0_gpio_sense(struct nouveau_gpio *gpio, int line)
return !!(nv_rd32(gpio, 0x00d610 + (line * 4)) & 0x00004000);
}
-static int
-nvd0_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nvd0_gpio_priv *priv;
- int ret;
-
- ret = nouveau_gpio_create(parent, engine, oclass, &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- priv->base.reset = nvd0_gpio_reset;
- priv->base.drive = nvd0_gpio_drive;
- priv->base.sense = nvd0_gpio_sense;
- return 0;
-}
-
struct nouveau_oclass *
nvd0_gpio_oclass = &(struct nouveau_gpio_impl) {
.base.handle = NV_SUBDEV(GPIO, 0xd0),
.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvd0_gpio_ctor,
+ .ctor = _nouveau_gpio_ctor,
.dtor = _nouveau_gpio_dtor,
.init = _nouveau_gpio_init,
.fini = _nouveau_gpio_fini,
@@ -103,4 +79,7 @@ nvd0_gpio_oclass = &(struct nouveau_gpio_impl) {
.lines = 32,
.intr_stat = nv92_gpio_intr_stat,
.intr_mask = nv92_gpio_intr_mask,
+ .drive = nvd0_gpio_drive,
+ .sense = nvd0_gpio_sense,
+ .reset = nvd0_gpio_reset,
}.base;
diff --git a/nvkm/subdev/gpio/nve0.c b/nvkm/subdev/gpio/nve0.c
index 017c3c1e..e1145b48 100644
--- a/nvkm/subdev/gpio/nve0.c
+++ b/nvkm/subdev/gpio/nve0.c
@@ -24,10 +24,6 @@
#include "priv.h"
-struct nve0_gpio_priv {
- struct nouveau_gpio base;
-};
-
static void
nve0_gpio_intr_stat(struct nouveau_gpio *gpio, u32 *hi, u32 *lo)
{
@@ -60,30 +56,11 @@ nve0_gpio_intr_mask(struct nouveau_gpio *gpio, u32 type, u32 mask, u32 data)
nv_wr32(gpio, 0x00dc88, inte1);
}
-static int
-nve0_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nve0_gpio_priv *priv;
- int ret;
-
- ret = nouveau_gpio_create(parent, engine, oclass, &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- priv->base.reset = nvd0_gpio_reset;
- priv->base.drive = nvd0_gpio_drive;
- priv->base.sense = nvd0_gpio_sense;
- return 0;
-}
-
struct nouveau_oclass *
nve0_gpio_oclass = &(struct nouveau_gpio_impl) {
.base.handle = NV_SUBDEV(GPIO, 0xe0),
.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nve0_gpio_ctor,
+ .ctor = _nouveau_gpio_ctor,
.dtor = _nouveau_gpio_dtor,
.init = _nouveau_gpio_init,
.fini = _nouveau_gpio_fini,
@@ -91,4 +68,7 @@ nve0_gpio_oclass = &(struct nouveau_gpio_impl) {
.lines = 32,
.intr_stat = nve0_gpio_intr_stat,
.intr_mask = nve0_gpio_intr_mask,
+ .drive = nvd0_gpio_drive,
+ .sense = nvd0_gpio_sense,
+ .reset = nvd0_gpio_reset,
}.base;
diff --git a/nvkm/subdev/gpio/priv.h b/nvkm/subdev/gpio/priv.h
index 4f7b616a..5c023983 100644
--- a/nvkm/subdev/gpio/priv.h
+++ b/nvkm/subdev/gpio/priv.h
@@ -27,14 +27,6 @@ void _nouveau_gpio_dtor(struct nouveau_object *);
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 nvd0_gpio_reset(struct nouveau_gpio *, u8);
-int nvd0_gpio_drive(struct nouveau_gpio *, int, int, int);
-int nvd0_gpio_sense(struct nouveau_gpio *, int);
-
enum nvkm_gpio_event {
NVKM_GPIO_HI = 1,
NVKM_GPIO_LO = 2,
@@ -55,10 +47,27 @@ struct nouveau_gpio_impl {
* given set of gpio lines
*/
void (*intr_mask)(struct nouveau_gpio *, u32, u32, u32);
+
+ /* configure gpio direction and output value */
+ int (*drive)(struct nouveau_gpio *, int line, int dir, int out);
+
+ /* sense current state of given gpio line */
+ int (*sense)(struct nouveau_gpio *, int line);
+
+ /*XXX*/
+ void (*reset)(struct nouveau_gpio *, u8);
};
+void nv50_gpio_reset(struct nouveau_gpio *, u8);
+int nv50_gpio_drive(struct nouveau_gpio *, int, int, int);
+int nv50_gpio_sense(struct nouveau_gpio *, int);
+
void nv92_gpio_intr_stat(struct nouveau_gpio *, u32 *, u32 *);
void nv92_gpio_intr_mask(struct nouveau_gpio *, u32, u32, u32);
+void nvd0_gpio_reset(struct nouveau_gpio *, u8);
+int nvd0_gpio_drive(struct nouveau_gpio *, int, int, int);
+int nvd0_gpio_sense(struct nouveau_gpio *, int);
+
#endif