- preparation for upcoming patches
- open-code current nvkm_uoutp() macro

Signed-off-by: Ben Skeggs <bske...@nvidia.com>
---
 .../gpu/drm/nouveau/nvkm/engine/disp/outp.h   |   3 +-
 .../gpu/drm/nouveau/nvkm/engine/disp/uoutp.c  | 131 ++++++++++--------
 .../gpu/drm/nouveau/nvkm/engine/disp/uoutp.h  |   6 +
 3 files changed, 78 insertions(+), 62 deletions(-)
 create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.h

diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
index ebd2f499b4b1..1beba54f80eb 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
@@ -63,10 +63,11 @@ struct nvkm_outp {
                } dp;
        };
 
-       struct nvkm_object object;
        struct {
                struct nvkm_head *head;
        } asy;
+
+       bool user; /* protected by disp->user.lock */
 };
 
 int nvkm_outp_new_(const struct nvkm_outp_func *, struct nvkm_disp *, int 
index,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
index 75669d5f8a42..8d39dad73a40 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
@@ -19,8 +19,7 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  */
-#define nvkm_uoutp(p) container_of((p), struct nvkm_outp, object)
-#include "outp.h"
+#include "uoutp.h"
 #include "dp.h"
 #include "head.h"
 #include "ior.h"
@@ -29,6 +28,11 @@
 
 #include <nvif/if0012.h>
 
+struct nvif_outp_priv {
+       struct nvkm_object object;
+       struct nvkm_outp *outp;
+};
+
 static int
 nvkm_uoutp_mthd_dp_mst_vcpi(struct nvkm_outp *outp, void *argv, u32 argc)
 {
@@ -543,7 +547,7 @@ nvkm_uoutp_mthd_noacquire(struct nvkm_outp *outp, u32 mthd, 
void *argv, u32 argc
 static int
 nvkm_uoutp_mthd(struct nvkm_object *object, u32 mthd, void *argv, u32 argc)
 {
-       struct nvkm_outp *outp = nvkm_uoutp(object);
+       struct nvkm_outp *outp = container_of(object, struct nvif_outp_priv, 
object)->outp;
        struct nvkm_disp *disp = outp->disp;
        bool invalid = false;
        int ret;
@@ -567,13 +571,13 @@ nvkm_uoutp_mthd(struct nvkm_object *object, u32 mthd, 
void *argv, u32 argc)
 static void *
 nvkm_uoutp_dtor(struct nvkm_object *object)
 {
-       struct nvkm_outp *outp = nvkm_uoutp(object);
-       struct nvkm_disp *disp = outp->disp;
+       struct nvif_outp_priv *uoutp = container_of(object, typeof(*uoutp), 
object);
+       struct nvkm_disp *disp = uoutp->outp->disp;
 
        spin_lock(&disp->user.lock);
-       outp->object.func = NULL;
+       uoutp->outp->user = false;
        spin_unlock(&disp->user.lock);
-       return NULL;
+       return uoutp;
 }
 
 static const struct nvkm_object_func
@@ -589,7 +593,7 @@ nvkm_uoutp_new(const struct nvkm_oclass *oclass, void 
*argv, u32 argc, struct nv
        struct nvkm_disp *disp = container_of(oclass->parent, struct 
nvif_disp_priv, object)->disp;
        struct nvkm_outp *outt, *outp = NULL;
        union nvif_outp_args *args = argv;
-       int ret;
+       struct nvif_outp_priv *uoutp;
 
        if (argc != sizeof(args->v0) || args->v0.version != 0)
                return -ENOSYS;
@@ -604,63 +608,68 @@ nvkm_uoutp_new(const struct nvkm_oclass *oclass, void 
*argv, u32 argc, struct nv
        if (!outp)
                return -EINVAL;
 
-       ret = -EBUSY;
-       spin_lock(&disp->user.lock);
-       if (!outp->object.func) {
-               switch (outp->info.type) {
-               case DCB_OUTPUT_ANALOG:
-                       args->v0.type = NVIF_OUTP_V0_TYPE_DAC;
-                       args->v0.proto = NVIF_OUTP_V0_PROTO_RGB_CRT;
-                       args->v0.rgb_crt.freq_max = outp->info.crtconf.maxfreq;
-                       break;
-               case DCB_OUTPUT_TMDS:
-                       if (!outp->info.location) {
-                               args->v0.type = NVIF_OUTP_V0_TYPE_SOR;
-                               args->v0.tmds.dual = 
(outp->info.tmdsconf.sor.link == 3);
-                       } else {
-                               args->v0.type = NVIF_OUTP_V0_TYPE_PIOR;
-                               args->v0.tmds.dual = 0;
-                       }
-                       args->v0.proto = NVIF_OUTP_V0_PROTO_TMDS;
-                       break;
-               case DCB_OUTPUT_LVDS:
+       switch (outp->info.type) {
+       case DCB_OUTPUT_ANALOG:
+               args->v0.type = NVIF_OUTP_V0_TYPE_DAC;
+               args->v0.proto = NVIF_OUTP_V0_PROTO_RGB_CRT;
+               args->v0.rgb_crt.freq_max = outp->info.crtconf.maxfreq;
+               break;
+       case DCB_OUTPUT_TMDS:
+               if (!outp->info.location) {
                        args->v0.type = NVIF_OUTP_V0_TYPE_SOR;
-                       args->v0.proto = NVIF_OUTP_V0_PROTO_LVDS;
-                       args->v0.lvds.acpi_edid = 
outp->info.lvdsconf.use_acpi_for_edid;
-                       break;
-               case DCB_OUTPUT_DP:
-                       if (!outp->info.location) {
-                               args->v0.type = NVIF_OUTP_V0_TYPE_SOR;
-                               args->v0.dp.aux = outp->info.i2c_index;
-                       } else {
-                               args->v0.type = NVIF_OUTP_V0_TYPE_PIOR;
-                               args->v0.dp.aux = 
NVKM_I2C_AUX_EXT(outp->info.extdev);
-                       }
-                       args->v0.proto = NVIF_OUTP_V0_PROTO_DP;
-                       args->v0.dp.mst = outp->dp.mst;
-                       args->v0.dp.increased_wm = outp->dp.increased_wm;
-                       args->v0.dp.link_nr = outp->info.dpconf.link_nr;
-                       args->v0.dp.link_bw = outp->info.dpconf.link_bw * 27000;
-                       break;
-               default:
-                       WARN_ON(1);
-                       ret = -EINVAL;
-                       goto done;
+                       args->v0.tmds.dual = (outp->info.tmdsconf.sor.link == 
3);
+               } else {
+                       args->v0.type = NVIF_OUTP_V0_TYPE_PIOR;
+                       args->v0.tmds.dual = 0;
                }
+               args->v0.proto = NVIF_OUTP_V0_PROTO_TMDS;
+               break;
+       case DCB_OUTPUT_LVDS:
+               args->v0.type = NVIF_OUTP_V0_TYPE_SOR;
+               args->v0.proto = NVIF_OUTP_V0_PROTO_LVDS;
+               args->v0.lvds.acpi_edid = outp->info.lvdsconf.use_acpi_for_edid;
+               break;
+       case DCB_OUTPUT_DP:
+               if (!outp->info.location) {
+                       args->v0.type = NVIF_OUTP_V0_TYPE_SOR;
+                       args->v0.dp.aux = outp->info.i2c_index;
+               } else {
+                       args->v0.type = NVIF_OUTP_V0_TYPE_PIOR;
+                       args->v0.dp.aux = NVKM_I2C_AUX_EXT(outp->info.extdev);
+               }
+               args->v0.proto = NVIF_OUTP_V0_PROTO_DP;
+               args->v0.dp.mst = outp->dp.mst;
+               args->v0.dp.increased_wm = outp->dp.increased_wm;
+               args->v0.dp.link_nr = outp->info.dpconf.link_nr;
+               args->v0.dp.link_bw = outp->info.dpconf.link_bw * 27000;
+               break;
+       default:
+               WARN_ON(1);
+               return -EINVAL;
+       }
 
-               if (outp->info.location)
-                       args->v0.ddc = NVKM_I2C_BUS_EXT(outp->info.extdev);
-               else
-                       args->v0.ddc = outp->info.i2c_index;
-               args->v0.heads = outp->info.heads;
-               args->v0.conn = outp->info.connector;
+       if (outp->info.location)
+               args->v0.ddc = NVKM_I2C_BUS_EXT(outp->info.extdev);
+       else
+               args->v0.ddc = outp->info.i2c_index;
+       args->v0.heads = outp->info.heads;
+       args->v0.conn = outp->info.connector;
 
-               nvkm_object_ctor(&nvkm_uoutp, oclass, &outp->object);
-               *pobject = &outp->object;
-               ret = 0;
-       }
+       uoutp = kzalloc(sizeof(*uoutp), GFP_KERNEL);
+       if (!uoutp)
+               return -ENOMEM;
 
-done:
+       spin_lock(&disp->user.lock);
+       if (outp->user) {
+               spin_unlock(&disp->user.lock);
+               kfree(uoutp);
+               return -EBUSY;
+       }
+       outp->user = true;
        spin_unlock(&disp->user.lock);
-       return ret;
+
+       nvkm_object_ctor(&nvkm_uoutp, oclass, &uoutp->object);
+       uoutp->outp = outp;
+       *pobject = &uoutp->object;
+       return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.h 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.h
new file mode 100644
index 000000000000..37ecd2891a1a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.h
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: MIT */
+#ifndef __NVKM_UOUTP_H__
+#define __NVKM_UOUTP_H__
+#include "outp.h"
+
+#endif
-- 
2.41.0

Reply via email to