summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/subdev/gpio/base.c')
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/gpio/base.c42
1 files changed, 39 insertions, 3 deletions
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c
index 20cb5f2..dbf9b5d0 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c
@@ -103,6 +103,37 @@ nouveau_gpio_get(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line)
return ret;
}
+static void
+nouveau_gpio_intr_disable(struct nouveau_event *event, int type, int index)
+{
+ struct nouveau_gpio *gpio = nouveau_gpio(event->priv);
+ const struct nouveau_gpio_impl *impl = (void *)nv_object(gpio)->oclass;
+ impl->intr_mask(gpio, NVKM_GPIO_TOGGLED, 1 << index, 0);
+}
+
+static void
+nouveau_gpio_intr_enable(struct nouveau_event *event, int type, int index)
+{
+ struct nouveau_gpio *gpio = nouveau_gpio(event->priv);
+ const struct nouveau_gpio_impl *impl = (void *)nv_object(gpio)->oclass;
+ impl->intr_mask(gpio, NVKM_GPIO_TOGGLED, 1 << index, 1 << index);
+}
+
+static void
+nouveau_gpio_intr(struct nouveau_subdev *subdev)
+{
+ struct nouveau_gpio *gpio = nouveau_gpio(subdev);
+ const struct nouveau_gpio_impl *impl = (void *)nv_object(gpio)->oclass;
+ u32 hi, lo, i;
+
+ impl->intr_stat(gpio, &hi, &lo);
+
+ for (i = 0; (hi | lo) && i < impl->lines; i++) {
+ if ((hi | lo) & (1 << i))
+ nouveau_event_trigger(gpio->events, 1, i);
+ }
+}
+
void
_nouveau_gpio_dtor(struct nouveau_object *object)
{
@@ -127,13 +158,18 @@ nouveau_gpio_create_(struct nouveau_object *parent,
if (ret)
return ret;
+ gpio->find = nouveau_gpio_find;
+ gpio->set = nouveau_gpio_set;
+ gpio->get = nouveau_gpio_get;
+
ret = nouveau_event_create(1, impl->lines, &gpio->events);
if (ret)
return ret;
- gpio->find = nouveau_gpio_find;
- gpio->set = nouveau_gpio_set;
- gpio->get = nouveau_gpio_get;
+ gpio->events->priv = gpio;
+ gpio->events->enable = nouveau_gpio_intr_enable;
+ gpio->events->disable = nouveau_gpio_intr_disable;
+ nv_subdev(gpio)->intr = nouveau_gpio_intr;
return 0;
}
OpenPOWER on IntegriCloud