drm/nouveau/disp: expose conn event class
authorBen Skeggs <bskeggs@redhat.com>
Wed, 1 Jun 2022 10:46:38 +0000 (20:46 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 9 Nov 2022 00:44:27 +0000 (10:44 +1000)
This removes some now-unnecessary nesting of workqueues.

v2:
- use ?: (lyude)

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
21 files changed:
drivers/gpu/drm/nouveau/include/nvif/conn.h
drivers/gpu/drm/nouveau/include/nvif/event.h
drivers/gpu/drm/nouveau/include/nvif/if0011.h
drivers/gpu/drm/nouveau/include/nvkm/subdev/gpio.h
drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h
drivers/gpu/drm/nouveau/nouveau_connector.c
drivers/gpu/drm/nouveau/nouveau_connector.h
drivers/gpu/drm/nouveau/nouveau_display.c
drivers/gpu/drm/nouveau/nouveau_dp.c
drivers/gpu/drm/nouveau/nouveau_encoder.h
drivers/gpu/drm/nouveau/nvif/conn.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.c
drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c
drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c

index f72a8f138f47f644bfb06ff4018e744d41b83a45..dc355e1dfafa033db7fa02955015c8993ce82cb2 100644 (file)
@@ -2,6 +2,7 @@
 #ifndef __NVIF_CONN_H__
 #define __NVIF_CONN_H__
 #include <nvif/object.h>
+#include <nvif/event.h>
 struct nvif_disp;
 
 struct nvif_conn {
@@ -11,8 +12,17 @@ struct nvif_conn {
 int nvif_conn_ctor(struct nvif_disp *, const char *name, int id, struct nvif_conn *);
 void nvif_conn_dtor(struct nvif_conn *);
 
+static inline int
+nvif_conn_id(struct nvif_conn *conn)
+{
+       return conn->object.handle;
+}
+
 #define NVIF_CONN_HPD_STATUS_UNSUPPORTED 0 /* negative if query fails */
 #define NVIF_CONN_HPD_STATUS_NOT_PRESENT 1
 #define NVIF_CONN_HPD_STATUS_PRESENT     2
 int nvif_conn_hpd_status(struct nvif_conn *);
+
+int nvif_conn_event_ctor(struct nvif_conn *, const char *name, nvif_event_func, u8 types,
+                        struct nvif_event *);
 #endif
index 679950400f536f96b06bfa037a7e311cbc064418..3afcda2034d65f8e532adda14bd396e554ea0a80 100644 (file)
@@ -52,25 +52,6 @@ struct nvif_notify_rep_v0 {
        __u8  data[];   /* reply data (below) */
 };
 
-struct nvif_notify_conn_req_v0 {
-       /* nvif_notify_req ... */
-       __u8  version;
-#define NVIF_NOTIFY_CONN_V0_PLUG                                           0x01
-#define NVIF_NOTIFY_CONN_V0_UNPLUG                                         0x02
-#define NVIF_NOTIFY_CONN_V0_IRQ                                            0x04
-#define NVIF_NOTIFY_CONN_V0_ANY                                            0x07
-       __u8  mask;
-       __u8  conn;
-       __u8  pad03[5];
-};
-
-struct nvif_notify_conn_rep_v0 {
-       /* nvif_notify_rep ... */
-       __u8  version;
-       __u8  mask;
-       __u8  pad02[6];
-};
-
 struct nvif_notify_uevent_req {
        /* nvif_notify_req ... */
 };
index 04ba6581f840388103e93c32b94ecce6f75dff74..69b0b779f9424853c316a14274a5cce42a4e507c 100644 (file)
@@ -10,6 +10,17 @@ union nvif_conn_args {
        } v0;
 };
 
+union nvif_conn_event_args {
+       struct nvif_conn_event_v0 {
+               __u8 version;
+#define NVIF_CONN_EVENT_V0_PLUG   0x01
+#define NVIF_CONN_EVENT_V0_UNPLUG 0x02
+#define NVIF_CONN_EVENT_V0_IRQ    0x04
+               __u8 types;
+               __u8 pad02[6];
+       } v0;
+};
+
 #define NVIF_CONN_V0_HPD_STATUS 0x00000000
 
 union nvif_conn_hpd_status_args {
index 0e46ea1fe97291296bb73ab66d508b3674e13077..537c4fc58b4faeaf7a3807af6df7490acb1c9190 100644 (file)
@@ -8,9 +8,6 @@
 #include <subdev/bios/gpio.h>
 
 struct nvkm_gpio_ntfy_req {
-#define NVKM_GPIO_HI                                                       0x01
-#define NVKM_GPIO_LO                                                       0x02
-#define NVKM_GPIO_TOGGLED                                                  0x03
        u8 mask;
        u8 line;
 };
@@ -23,6 +20,9 @@ struct nvkm_gpio {
        const struct nvkm_gpio_func *func;
        struct nvkm_subdev subdev;
 
+#define NVKM_GPIO_HI       BIT(0)
+#define NVKM_GPIO_LO       BIT(1)
+#define NVKM_GPIO_TOGGLED (NVKM_GPIO_HI | NVKM_GPIO_LO)
        struct nvkm_event event;
 };
 
index 146e13292203df767794823272d5849e4a5a53c8..40a1065ae626ea3dbd70d139d030b0070e7ac92f 100644 (file)
@@ -7,20 +7,6 @@
 #include <subdev/bios.h>
 #include <subdev/bios/i2c.h>
 
-struct nvkm_i2c_ntfy_req {
-#define NVKM_I2C_PLUG                                                      0x01
-#define NVKM_I2C_UNPLUG                                                    0x02
-#define NVKM_I2C_IRQ                                                       0x04
-#define NVKM_I2C_DONE                                                      0x08
-#define NVKM_I2C_ANY                                                       0x0f
-       u8 mask;
-       u8 port;
-};
-
-struct nvkm_i2c_ntfy_rep {
-       u8 mask;
-};
-
 struct nvkm_i2c_bus_probe {
        struct i2c_board_info dev;
        u8 udelay; /* set to 0 to use the standard delay */
@@ -79,6 +65,11 @@ struct nvkm_i2c {
        struct list_head bus;
        struct list_head aux;
 
+#define NVKM_I2C_PLUG   BIT(0)
+#define NVKM_I2C_UNPLUG BIT(1)
+#define NVKM_I2C_IRQ    BIT(2)
+#define NVKM_I2C_DONE   BIT(3)
+#define NVKM_I2C_ANY   (NVKM_I2C_PLUG | NVKM_I2C_UNPLUG | NVKM_I2C_IRQ | NVKM_I2C_DONE)
        struct nvkm_event event;
 };
 
index bbd17ee608538d18ca03cef3e8e068014576f14e..086b66b60d918a488dcda36db23d816e281ebebf 100644 (file)
@@ -47,8 +47,7 @@
 #include "nouveau_crtc.h"
 
 #include <nvif/class.h>
-#include <nvif/cl0046.h>
-#include <nvif/event.h>
+#include <nvif/if0011.h>
 
 struct drm_display_mode *
 nouveau_conn_native_mode(struct drm_connector *connector)
@@ -396,7 +395,8 @@ static void
 nouveau_connector_destroy(struct drm_connector *connector)
 {
        struct nouveau_connector *nv_connector = nouveau_connector(connector);
-       nvif_notify_dtor(&nv_connector->hpd);
+       nvif_event_dtor(&nv_connector->irq);
+       nvif_event_dtor(&nv_connector->hpd);
        kfree(nv_connector->edid);
        drm_connector_unregister(connector);
        drm_connector_cleanup(connector);
@@ -1178,23 +1178,22 @@ nouveau_connector_hpd(struct nouveau_connector *nv_connector, u64 bits)
 }
 
 static int
-nouveau_connector_hotplug(struct nvif_notify *notify)
+nouveau_connector_irq(struct nvif_event *event, void *repv, u32 repc)
 {
-       struct nouveau_connector *nv_connector =
-               container_of(notify, typeof(*nv_connector), hpd);
-       struct drm_connector *connector = &nv_connector->base;
-       struct drm_device *dev = connector->dev;
-       struct nouveau_drm *drm = nouveau_drm(dev);
-       const struct nvif_notify_conn_rep_v0 *rep = notify->data;
+       struct nouveau_connector *nv_connector = container_of(event, typeof(*nv_connector), irq);
 
-       if (rep->mask & NVIF_NOTIFY_CONN_V0_IRQ) {
-               nouveau_dp_irq(drm, nv_connector);
-               return NVIF_NOTIFY_KEEP;
-       }
+       schedule_work(&nv_connector->irq_work);
+       return NVIF_EVENT_KEEP;
+}
 
-       nouveau_connector_hpd(nv_connector, rep->mask);
+static int
+nouveau_connector_hotplug(struct nvif_event *event, void *repv, u32 repc)
+{
+       struct nouveau_connector *nv_connector = container_of(event, typeof(*nv_connector), hpd);
+       struct nvif_conn_event_v0 *rep = repv;
 
-       return NVIF_NOTIFY_KEEP;
+       nouveau_connector_hpd(nv_connector, rep->types);
+       return NVIF_EVENT_KEEP;
 }
 
 static ssize_t
@@ -1290,6 +1289,7 @@ nouveau_connector_create(struct drm_device *dev,
 
        connector = &nv_connector->base;
        nv_connector->index = index;
+       INIT_WORK(&nv_connector->irq_work, nouveau_dp_irq);
 
        /* attempt to parse vbios connector type and hotplug gpio */
        nv_connector->dcb = olddcb_conn(dev, index);
@@ -1401,6 +1401,7 @@ nouveau_connector_create(struct drm_device *dev,
 
        drm_connector_init(dev, connector, funcs, type);
        drm_connector_helper_add(connector, &nouveau_connector_helper_funcs);
+       connector->polled = DRM_CONNECTOR_POLL_CONNECT;
 
        if (nv_connector->dcb && (disp->disp.conn_mask & BIT(nv_connector->index))) {
                ret = nvif_conn_ctor(&disp->disp, nv_connector->base.name, nv_connector->index,
@@ -1409,6 +1410,25 @@ nouveau_connector_create(struct drm_device *dev,
                        kfree(nv_connector);
                        return ERR_PTR(ret);
                }
+
+               ret = nvif_conn_event_ctor(&nv_connector->conn, "kmsHotplug",
+                                          nouveau_connector_hotplug,
+                                          NVIF_CONN_EVENT_V0_PLUG | NVIF_CONN_EVENT_V0_UNPLUG,
+                                          &nv_connector->hpd);
+               if (ret == 0)
+                       connector->polled = DRM_CONNECTOR_POLL_HPD;
+
+               if (nv_connector->aux.transfer) {
+                       ret = nvif_conn_event_ctor(&nv_connector->conn, "kmsDpIrq",
+                                                  nouveau_connector_irq, NVIF_CONN_EVENT_V0_IRQ,
+                                                  &nv_connector->irq);
+                       if (ret) {
+                               nvif_event_dtor(&nv_connector->hpd);
+                               nvif_conn_dtor(&nv_connector->conn);
+                               kfree(nv_connector);
+                               return ERR_PTR(ret);
+                       }
+               }
        }
 
        connector->funcs->reset(connector);
@@ -1452,21 +1472,6 @@ nouveau_connector_create(struct drm_device *dev,
                break;
        }
 
-       ret = nvif_notify_ctor(&disp->disp.object, "kmsHotplug",
-                              nouveau_connector_hotplug,
-                              true, NV04_DISP_NTFY_CONN,
-                              &(struct nvif_notify_conn_req_v0) {
-                               .mask = NVIF_NOTIFY_CONN_V0_ANY,
-                               .conn = index,
-                              },
-                              sizeof(struct nvif_notify_conn_req_v0),
-                              sizeof(struct nvif_notify_conn_rep_v0),
-                              &nv_connector->hpd);
-       if (ret)
-               connector->polled = DRM_CONNECTOR_POLL_CONNECT;
-       else
-               connector->polled = DRM_CONNECTOR_POLL_HPD;
-
        drm_connector_register(connector);
        return connector;
 }
index 1bbf8bf6ba445d49e7c5cf774a958c7657b2deef..35bcb541722b8bb3ea710ff986232cc91121fd60 100644 (file)
@@ -27,7 +27,7 @@
 #ifndef __NOUVEAU_CONNECTOR_H__
 #define __NOUVEAU_CONNECTOR_H__
 #include <nvif/conn.h>
-#include <nvif/notify.h>
+#include <nvif/event.h>
 
 #include <nvhw/class/cl507d.h>
 #include <nvhw/class/cl907d.h>
@@ -125,7 +125,9 @@ struct nouveau_connector {
 
        struct nvif_conn conn;
        u64 hpd_pending;
-       struct nvif_notify hpd;
+       struct nvif_event hpd;
+       struct nvif_event irq;
+       struct work_struct irq_work;
 
        struct drm_dp_aux aux;
 
index e88845ae752044646f6e961883f8d1028be3713a..55099d9ce1c8fcf83439db53833bce268405b9bb 100644 (file)
@@ -42,8 +42,8 @@
 #include "nv50_display.h"
 
 #include <nvif/class.h>
+#include <nvif/if0011.h>
 #include <nvif/if0013.h>
-#include <nvif/event.h>
 #include <dispnv50/crc.h>
 
 int
@@ -497,11 +497,11 @@ nouveau_display_hpd_work(struct work_struct *work)
 
                drm_dbg_kms(dev, "[CONNECTOR:%d:%s] plug:%d unplug:%d irq:%d\n",
                            connector->base.id, connector->name,
-                           !!(bits & NVIF_NOTIFY_CONN_V0_PLUG),
-                           !!(bits & NVIF_NOTIFY_CONN_V0_UNPLUG),
-                           !!(bits & NVIF_NOTIFY_CONN_V0_IRQ));
+                           !!(bits & NVIF_CONN_EVENT_V0_PLUG),
+                           !!(bits & NVIF_CONN_EVENT_V0_UNPLUG),
+                           !!(bits & NVIF_CONN_EVENT_V0_IRQ));
 
-               if (bits & NVIF_NOTIFY_CONN_V0_IRQ) {
+               if (bits & NVIF_CONN_EVENT_V0_IRQ) {
                        if (nouveau_dp_link_check(nv_connector))
                                continue;
                }
@@ -584,7 +584,8 @@ nouveau_display_init(struct drm_device *dev, bool resume, bool runtime)
        drm_connector_list_iter_begin(dev, &conn_iter);
        nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) {
                struct nouveau_connector *conn = nouveau_connector(connector);
-               nvif_notify_get(&conn->hpd);
+               nvif_event_allow(&conn->hpd);
+               nvif_event_allow(&conn->irq);
        }
        drm_connector_list_iter_end(&conn_iter);
 
@@ -619,7 +620,8 @@ nouveau_display_fini(struct drm_device *dev, bool suspend, bool runtime)
        drm_connector_list_iter_begin(dev, &conn_iter);
        nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) {
                struct nouveau_connector *conn = nouveau_connector(connector);
-               nvif_notify_put(&conn->hpd);
+               nvif_event_block(&conn->irq);
+               nvif_event_block(&conn->hpd);
        }
        drm_connector_list_iter_end(&conn_iter);
 
index bde58d00fbf53930de8271dce12245cf8bdaa5bf..e00876f92aeea582c13642664b4774cf4c5726c8 100644 (file)
@@ -29,7 +29,7 @@
 #include "nouveau_encoder.h"
 #include "nouveau_crtc.h"
 
-#include <nvif/event.h>
+#include <nvif/if0011.h>
 
 MODULE_PARM_DESC(mst, "Enable DisplayPort multi-stream (default: enabled)");
 static int nouveau_mst = 1;
@@ -222,11 +222,14 @@ nouveau_dp_link_check(struct nouveau_connector *nv_connector)
        return nvif_outp_dp_retrain(&nv_encoder->outp) == 0;
 }
 
-void nouveau_dp_irq(struct nouveau_drm *drm,
-                   struct nouveau_connector *nv_connector)
+void
+nouveau_dp_irq(struct work_struct *work)
 {
+       struct nouveau_connector *nv_connector =
+               container_of(work, typeof(*nv_connector), irq_work);
        struct drm_connector *connector = &nv_connector->base;
        struct nouveau_encoder *outp = find_encoder(connector, DCB_OUTPUT_DP);
+       struct nouveau_drm *drm = nouveau_drm(outp->base.base.dev);
        struct nv50_mstm *mstm;
        u64 hpd = 0;
        int ret;
@@ -241,14 +244,14 @@ void nouveau_dp_irq(struct nouveau_drm *drm,
 
        if (mstm && mstm->is_mst) {
                if (!nv50_mstm_service(drm, nv_connector, mstm))
-                       hpd |= NVIF_NOTIFY_CONN_V0_UNPLUG;
+                       hpd |= NVIF_CONN_EVENT_V0_UNPLUG;
        } else {
                drm_dp_cec_irq(&nv_connector->aux);
 
                if (nouveau_dp_has_sink_count(connector, outp)) {
                        ret = drm_dp_read_sink_count(&nv_connector->aux);
                        if (ret != outp->dp.sink_count)
-                               hpd |= NVIF_NOTIFY_CONN_V0_PLUG;
+                               hpd |= NVIF_CONN_EVENT_V0_PLUG;
                        if (ret >= 0)
                                outp->dp.sink_count = ret;
                }
@@ -256,7 +259,7 @@ void nouveau_dp_irq(struct nouveau_drm *drm,
 
        mutex_unlock(&outp->dp.hpd_irq_lock);
 
-       nouveau_connector_hpd(nv_connector, NVIF_NOTIFY_CONN_V0_IRQ | hpd);
+       nouveau_connector_hpd(nv_connector, NVIF_CONN_EVENT_V0_IRQ | hpd);
 }
 
 /* TODO:
index 8524d211f4e1066ef90235e9bb4522af4ae6ac14..70c1ad6c4d9dbac8858e459db81ada48325cdc48 100644 (file)
@@ -142,8 +142,7 @@ enum nouveau_dp_status {
 
 int nouveau_dp_detect(struct nouveau_connector *, struct nouveau_encoder *);
 bool nouveau_dp_link_check(struct nouveau_connector *);
-void nouveau_dp_irq(struct nouveau_drm *drm,
-                   struct nouveau_connector *nv_connector);
+void nouveau_dp_irq(struct work_struct *);
 enum drm_mode_status nv50_dp_mode_valid(struct drm_connector *,
                                        struct nouveau_encoder *,
                                        const struct drm_display_mode *,
index 4ce935d58c906f4abe6dad6dfa75b1009642061b..a3cf91aeae2de8478febb2b14d1eb21c458ce187 100644 (file)
 #include <nvif/class.h>
 #include <nvif/if0011.h>
 
+int
+nvif_conn_event_ctor(struct nvif_conn *conn, const char *name, nvif_event_func func, u8 types,
+                    struct nvif_event *event)
+{
+       struct {
+               struct nvif_event_v0 base;
+               struct nvif_conn_event_v0 conn;
+       } args;
+       int ret;
+
+       args.conn.version = 0;
+       args.conn.types = types;
+
+       ret = nvif_event_ctor_(&conn->object, name ?: "nvifConnHpd", nvif_conn_id(conn),
+                              func, true, &args.base, sizeof(args), false, event);
+       NVIF_DEBUG(&conn->object, "[NEW EVENT:HPD types:%02x]", types);
+       return ret;
+}
+
 int
 nvif_conn_hpd_status(struct nvif_conn *conn)
 {
index 399195946823e63e00efa117f00910796b7f0c8f..c1d81cf74c57c0e51d5a5f06a94521b96cc26ddd 100644 (file)
@@ -29,7 +29,6 @@
 #include "outp.h"
 
 #include <core/client.h>
-#include <core/notify.h>
 #include <core/ramht.h>
 #include <subdev/bios.h>
 #include <subdev/bios/dcb.h>
@@ -69,54 +68,6 @@ nvkm_disp_vblank(struct nvkm_disp *disp, int head)
        nvkm_event_send(&disp->vblank, NVKM_DISP_HEAD_EVENT_VBLANK, head, NULL, 0);
 }
 
-static int
-nvkm_disp_hpd_ctor(struct nvkm_object *object, void *data, u32 size,
-                  struct nvkm_notify *notify)
-{
-       struct nvkm_disp *disp =
-               container_of(notify->event, typeof(*disp), hpd);
-       union {
-               struct nvif_notify_conn_req_v0 v0;
-       } *req = data;
-       struct nvkm_outp *outp;
-       int ret = -ENOSYS;
-
-       if (!(ret = nvif_unpack(ret, &data, &size, req->v0, 0, 0, false))) {
-               notify->size = sizeof(struct nvif_notify_conn_rep_v0);
-               list_for_each_entry(outp, &disp->outps, head) {
-                       if (ret = -ENXIO, outp->conn->index == req->v0.conn) {
-                               if (ret = -ENODEV, outp->conn->hpd.event) {
-                                       notify->types = req->v0.mask;
-                                       notify->index = req->v0.conn;
-                                       ret = 0;
-                               }
-                               break;
-                       }
-               }
-       }
-
-       return ret;
-}
-
-static const struct nvkm_event_func
-nvkm_disp_hpd_func = {
-       .ctor = nvkm_disp_hpd_ctor
-};
-
-int
-nvkm_disp_ntfy(struct nvkm_object *object, u32 type, struct nvkm_event **event)
-{
-       struct nvkm_disp *disp = nvkm_disp(object->engine);
-       switch (type) {
-       case NV04_DISP_NTFY_CONN:
-               *event = &disp->hpd;
-               return 0;
-       default:
-               break;
-       }
-       return -EINVAL;
-}
-
 static int
 nvkm_disp_class_new(struct nvkm_device *device,
                    const struct nvkm_oclass *oclass, void *data, u32 size,
@@ -325,10 +276,6 @@ nvkm_disp_oneinit(struct nvkm_engine *engine)
                list_add_tail(&outp->conn->head, &disp->conns);
        }
 
-       ret = nvkm_event_init(&nvkm_disp_hpd_func, subdev, 3, hpd, &disp->hpd);
-       if (ret)
-               return ret;
-
        if (disp->func->oneinit) {
                ret = disp->func->oneinit(disp);
                if (ret)
@@ -376,7 +323,6 @@ nvkm_disp_dtor(struct nvkm_engine *engine)
        }
 
        nvkm_event_fini(&disp->vblank);
-       nvkm_event_fini(&disp->hpd);
 
        while (!list_empty(&disp->conns)) {
                conn = list_first_entry(&disp->conns, typeof(*conn), head);
index 7ed11801a3ae6951fd6946a41087a1ab9c7a565b..fbdae11378646f79f247ef09d436dd02325432be 100644 (file)
 
 #include <nvif/event.h>
 
-static int
-nvkm_conn_hpd(struct nvkm_notify *notify)
-{
-       struct nvkm_conn *conn = container_of(notify, typeof(*conn), hpd);
-       struct nvkm_disp *disp = conn->disp;
-       struct nvkm_gpio *gpio = disp->engine.subdev.device->gpio;
-       const struct nvkm_gpio_ntfy_rep *line = notify->data;
-       struct nvif_notify_conn_rep_v0 rep;
-       int index = conn->index;
-
-       CONN_DBG(conn, "HPD: %d", line->mask);
-
-       if (!nvkm_gpio_get(gpio, 0, DCB_GPIO_UNUSED, conn->hpd.index))
-               rep.mask = NVIF_NOTIFY_CONN_V0_UNPLUG;
-       else
-               rep.mask = NVIF_NOTIFY_CONN_V0_PLUG;
-       rep.version = 0;
-
-       nvkm_event_send(&disp->hpd, rep.mask, index, &rep, sizeof(rep));
-       return NVKM_NOTIFY_KEEP;
-}
-
 void
 nvkm_conn_fini(struct nvkm_conn *conn)
 {
-       nvkm_notify_put(&conn->hpd);
 }
 
 void
 nvkm_conn_init(struct nvkm_conn *conn)
 {
-       nvkm_notify_get(&conn->hpd);
 }
 
 void
@@ -68,7 +44,6 @@ nvkm_conn_del(struct nvkm_conn **pconn)
 {
        struct nvkm_conn *conn = *pconn;
        if (conn) {
-               nvkm_notify_fini(&conn->hpd);
                kfree(*pconn);
                *pconn = NULL;
        }
@@ -106,20 +81,6 @@ nvkm_conn_ctor(struct nvkm_disp *disp, int index, struct nvbios_connE *info,
                }
 
                conn->info.hpd = func.line;
-
-               ret = nvkm_notify_init(NULL, &gpio->event, nvkm_conn_hpd,
-                                      true, &(struct nvkm_gpio_ntfy_req) {
-                                       .mask = NVKM_GPIO_TOGGLED,
-                                       .line = func.line,
-                                      },
-                                      sizeof(struct nvkm_gpio_ntfy_req),
-                                      sizeof(struct nvkm_gpio_ntfy_rep),
-                                      &conn->hpd);
-               if (ret) {
-                       CONN_ERR(conn, "func %02x failed, %d", info->hpd, ret);
-               } else {
-                       CONN_DBG(conn, "func %02x (HPD)", info->hpd);
-               }
        }
 }
 
index f109634ce5ca89569c3d41bbb782748808560279..a0600e72b0ecdc04850c140cdb4696cf1d6f5e2b 100644 (file)
@@ -3,7 +3,6 @@
 #define __NVKM_DISP_CONN_H__
 #include "priv.h"
 
-#include <core/notify.h>
 #include <subdev/bios.h>
 #include <subdev/bios/conn.h>
 
@@ -12,8 +11,6 @@ struct nvkm_conn {
        int index;
        struct nvbios_connE info;
 
-       struct nvkm_notify hpd;
-
        struct list_head head;
 
        struct nvkm_object object;
index 730c3a6f33626ecd7a52469a2be2aa7fd88576af..40c8ea43c42f2bb6888ebbb45fbe4f50eb1d94f5 100644 (file)
@@ -738,31 +738,9 @@ nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr)
        }
 }
 
-static int
-nvkm_dp_hpd(struct nvkm_notify *notify)
-{
-       const struct nvkm_i2c_ntfy_rep *line = notify->data;
-       struct nvkm_outp *outp = container_of(notify, typeof(*outp), dp.hpd);
-       struct nvkm_conn *conn = outp->conn;
-       struct nvkm_disp *disp = outp->disp;
-       struct nvif_notify_conn_rep_v0 rep = {};
-
-       OUTP_DBG(outp, "HPD: %d", line->mask);
-       if (line->mask & NVKM_I2C_IRQ)
-               rep.mask |= NVIF_NOTIFY_CONN_V0_IRQ;
-       if (line->mask & NVKM_I2C_UNPLUG)
-               rep.mask |= NVIF_NOTIFY_CONN_V0_UNPLUG;
-       if (line->mask & NVKM_I2C_PLUG)
-               rep.mask |= NVIF_NOTIFY_CONN_V0_PLUG;
-
-       nvkm_event_send(&disp->hpd, rep.mask, conn->index, &rep, sizeof(rep));
-       return NVKM_NOTIFY_KEEP;
-}
-
 static void
 nvkm_dp_fini(struct nvkm_outp *outp)
 {
-       nvkm_notify_put(&outp->dp.hpd);
        nvkm_dp_enable(outp, false);
 }
 
@@ -770,14 +748,11 @@ static void
 nvkm_dp_init(struct nvkm_outp *outp)
 {
        nvkm_dp_enable(outp, outp->dp.enabled);
-       nvkm_notify_put(&outp->conn->hpd);
-       nvkm_notify_get(&outp->dp.hpd);
 }
 
 static void *
 nvkm_dp_dtor(struct nvkm_outp *outp)
 {
-       nvkm_notify_fini(&outp->dp.hpd);
        return outp;
 }
 
@@ -826,21 +801,6 @@ nvkm_dp_new(struct nvkm_disp *disp, int index, struct dcb_output *dcbE, struct n
 
        OUTP_DBG(outp, "bios dp %02x %02x %02x %02x", outp->dp.version, hdr, cnt, len);
 
-       /* hotplug detect, replaces gpio-based mechanism with aux events */
-       ret = nvkm_notify_init(NULL, &i2c->event, nvkm_dp_hpd, true,
-                              &(struct nvkm_i2c_ntfy_req) {
-                               .mask = NVKM_I2C_PLUG | NVKM_I2C_UNPLUG |
-                                       NVKM_I2C_IRQ,
-                               .port = outp->dp.aux->id,
-                              },
-                              sizeof(struct nvkm_i2c_ntfy_req),
-                              sizeof(struct nvkm_i2c_ntfy_rep),
-                              &outp->dp.hpd);
-       if (ret) {
-               OUTP_ERR(outp, "error monitoring aux hpd: %d", ret);
-               return ret;
-       }
-
        mutex_init(&outp->dp.mutex);
        atomic_set(&outp->dp.lt.done, 0);
        return 0;
index 66def8ae316556234bd50b48eae4c63184b53868..b7631c1ab2420fcaf34af9157bd3bde383c2ba37 100644 (file)
@@ -2,7 +2,6 @@
 #ifndef __NVKM_DISP_OUTP_H__
 #define __NVKM_DISP_OUTP_H__
 #include "priv.h"
-#include <core/notify.h>
 
 #include <subdev/bios.h>
 #include <subdev/bios/dcb.h>
@@ -38,7 +37,6 @@ struct nvkm_outp {
 
                        struct nvkm_i2c_aux *aux;
 
-                       struct nvkm_notify hpd;
                        bool enabled;
                        bool aux_pwr;
                        bool aux_pwr_pu;
index a98b57f82fe773bcd49e36ac58263e9c27357ec0..ec5292a8f3c8513782b886aacf60429c84a382a5 100644 (file)
@@ -42,8 +42,6 @@ struct nvkm_disp_func {
        } user[];
 };
 
-int  nvkm_disp_ntfy(struct nvkm_object *, u32, struct nvkm_event **);
-
 int nv50_disp_oneinit(struct nvkm_disp *);
 int nv50_disp_init(struct nvkm_disp *);
 void nv50_disp_fini(struct nvkm_disp *);
index fd9f18144c26599e5f18c5cae561b7ad39c6b113..dad942be6679c12ef2b09cef8c7aa1e4ccb3126a 100644 (file)
  */
 #define nvkm_uconn(p) container_of((p), struct nvkm_conn, object)
 #include "conn.h"
+#include "outp.h"
 
+#include <core/client.h>
+#include <core/event.h>
 #include <subdev/gpio.h>
+#include <subdev/i2c.h>
 
 #include <nvif/if0011.h>
 
+static int
+nvkm_uconn_uevent_aux(struct nvkm_object *object, u64 token, u32 bits)
+{
+       union nvif_conn_event_args args;
+
+       args.v0.version = 0;
+       args.v0.types = 0;
+       if (bits & NVKM_I2C_PLUG)
+               args.v0.types |= NVIF_CONN_EVENT_V0_PLUG;
+       if (bits & NVKM_I2C_UNPLUG)
+               args.v0.types |= NVIF_CONN_EVENT_V0_UNPLUG;
+       if (bits & NVKM_I2C_IRQ)
+               args.v0.types |= NVIF_CONN_EVENT_V0_IRQ;
+
+       return object->client->event(token, &args, sizeof(args.v0));
+}
+
+static int
+nvkm_uconn_uevent_gpio(struct nvkm_object *object, u64 token, u32 bits)
+{
+       union nvif_conn_event_args args;
+
+       args.v0.version = 0;
+       args.v0.types = 0;
+       if (bits & NVKM_GPIO_HI)
+               args.v0.types |= NVIF_CONN_EVENT_V0_PLUG;
+       if (bits & NVKM_GPIO_LO)
+               args.v0.types |= NVIF_CONN_EVENT_V0_UNPLUG;
+
+       return object->client->event(token, &args, sizeof(args.v0));
+}
+
+static int
+nvkm_uconn_uevent(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_uevent *uevent)
+{
+       struct nvkm_conn *conn = nvkm_uconn(object);
+       struct nvkm_device *device = conn->disp->engine.subdev.device;
+       struct nvkm_outp *outp;
+       union nvif_conn_event_args *args = argv;
+       u64 bits = 0;
+
+       if (!uevent) {
+               if (conn->info.hpd == DCB_GPIO_UNUSED)
+                       return -ENOSYS;
+               return 0;
+       }
+
+       if (argc != sizeof(args->v0) || args->v0.version != 0)
+               return -ENOSYS;
+
+       list_for_each_entry(outp, &conn->disp->outps, head) {
+               if (outp->info.connector == conn->index && outp->dp.aux) {
+                       if (args->v0.types & NVIF_CONN_EVENT_V0_PLUG  ) bits |= NVKM_I2C_PLUG;
+                       if (args->v0.types & NVIF_CONN_EVENT_V0_UNPLUG) bits |= NVKM_I2C_UNPLUG;
+                       if (args->v0.types & NVIF_CONN_EVENT_V0_IRQ   ) bits |= NVKM_I2C_IRQ;
+
+                       return nvkm_uevent_add(uevent, &device->i2c->event, outp->dp.aux->id, bits,
+                                              nvkm_uconn_uevent_aux);
+               }
+       }
+
+       if (args->v0.types & NVIF_CONN_EVENT_V0_PLUG  ) bits |= NVKM_GPIO_HI;
+       if (args->v0.types & NVIF_CONN_EVENT_V0_UNPLUG) bits |= NVKM_GPIO_LO;
+       if (args->v0.types & NVIF_CONN_EVENT_V0_IRQ)
+               return -EINVAL;
+
+       return nvkm_uevent_add(uevent, &device->gpio->event, conn->info.hpd, bits,
+                              nvkm_uconn_uevent_gpio);
+}
+
 static int
 nvkm_uconn_mthd_hpd_status(struct nvkm_conn *conn, void *argv, u32 argc)
 {
@@ -82,6 +156,7 @@ static const struct nvkm_object_func
 nvkm_uconn = {
        .dtor = nvkm_uconn_dtor,
        .mthd = nvkm_uconn_mthd,
+       .uevent = nvkm_uconn_uevent,
 };
 
 int
index c9bd32220fe174cfcc0911266f6d1d65db6c14a8..0268d1d75805bc188a532bc23941584929d66690 100644 (file)
@@ -74,7 +74,6 @@ nvkm_udisp_dtor(struct nvkm_object *object)
 static const struct nvkm_object_func
 nvkm_udisp = {
        .dtor = nvkm_udisp_dtor,
-       .ntfy = nvkm_disp_ntfy,
        .sclass = nvkm_udisp_sclass,
 };
 
index f2ccbcf219ca897e637c4b449839d78c4a4e5025..2c2c23b8663b6a0c388504d2d92d0cea1e4dd75b 100644 (file)
@@ -24,7 +24,6 @@
 #include "priv.h"
 
 #include <core/option.h>
-#include <core/notify.h>
 
 static int
 nvkm_gpio_drive(struct nvkm_gpio *gpio, int idx, int line, int dir, int out)
@@ -123,23 +122,8 @@ nvkm_gpio_intr_init(struct nvkm_event *event, int type, int index)
        gpio->func->intr_mask(gpio, type, 1 << index, 1 << index);
 }
 
-static int
-nvkm_gpio_intr_ctor(struct nvkm_object *object, void *data, u32 size,
-                   struct nvkm_notify *notify)
-{
-       struct nvkm_gpio_ntfy_req *req = data;
-       if (!WARN_ON(size != sizeof(*req))) {
-               notify->size  = sizeof(struct nvkm_gpio_ntfy_rep);
-               notify->types = req->mask;
-               notify->index = req->line;
-               return 0;
-       }
-       return -EINVAL;
-}
-
 static const struct nvkm_event_func
 nvkm_gpio_intr_func = {
-       .ctor = nvkm_gpio_intr_ctor,
        .init = nvkm_gpio_intr_init,
        .fini = nvkm_gpio_intr_fini,
 };
@@ -153,11 +137,9 @@ nvkm_gpio_intr(struct nvkm_subdev *subdev)
        gpio->func->intr_stat(gpio, &hi, &lo);
 
        for (i = 0; (hi | lo) && i < gpio->func->lines; i++) {
-               struct nvkm_gpio_ntfy_rep rep = {
-                       .mask = (NVKM_GPIO_HI * !!(hi & (1 << i))) |
-                               (NVKM_GPIO_LO * !!(lo & (1 << i))),
-               };
-               nvkm_event_send(&gpio->event, rep.mask, i, &rep, sizeof(rep));
+               u32 mask = (NVKM_GPIO_HI * !!(hi & (1 << i))) |
+                          (NVKM_GPIO_LO * !!(lo & (1 << i)));
+               nvkm_event_send(&gpio->event, mask, i, NULL, 0);
        }
 }
 
index 49a84ef146e9fed17cd19c92e43007e013b2d33f..feb7de985d2d74f8521931f31fa60310e895d9a1 100644 (file)
@@ -26,7 +26,6 @@
 #include "bus.h"
 #include "pad.h"
 
-#include <core/notify.h>
 #include <core/option.h>
 #include <subdev/bios.h>
 #include <subdev/bios/dcb.h>
@@ -104,23 +103,8 @@ nvkm_i2c_intr_init(struct nvkm_event *event, int type, int id)
                i2c->func->aux_mask(i2c, type, aux->intr, aux->intr);
 }
 
-static int
-nvkm_i2c_intr_ctor(struct nvkm_object *object, void *data, u32 size,
-                  struct nvkm_notify *notify)
-{
-       struct nvkm_i2c_ntfy_req *req = data;
-       if (!WARN_ON(size != sizeof(*req))) {
-               notify->size  = sizeof(struct nvkm_i2c_ntfy_rep);
-               notify->types = req->mask;
-               notify->index = req->port;
-               return 0;
-       }
-       return -EINVAL;
-}
-
 static const struct nvkm_event_func
 nvkm_i2c_intr_func = {
-       .ctor = nvkm_i2c_intr_ctor,
        .init = nvkm_i2c_intr_init,
        .fini = nvkm_i2c_intr_fini,
 };
@@ -145,13 +129,8 @@ nvkm_i2c_intr(struct nvkm_subdev *subdev)
                if (lo & aux->intr) mask |= NVKM_I2C_UNPLUG;
                if (rq & aux->intr) mask |= NVKM_I2C_IRQ;
                if (tx & aux->intr) mask |= NVKM_I2C_DONE;
-               if (mask) {
-                       struct nvkm_i2c_ntfy_rep rep = {
-                               .mask = mask,
-                       };
-                       nvkm_event_send(&i2c->event, rep.mask, aux->id,
-                                       &rep, sizeof(rep));
-               }
+               if (mask)
+                       nvkm_event_send(&i2c->event, mask, aux->id, NULL, 0);
        }
 }