[PATCH 048/156] drm/nouveau/nvkm: detach user handling from nvkm_conn

Ben Skeggs bskeggs at nvidia.com
Tue Apr 16 23:38:14 UTC 2024


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

Signed-off-by: Ben Skeggs <bskeggs at nvidia.com>
---
 .../gpu/drm/nouveau/nvkm/engine/disp/conn.h   |  2 +-
 .../gpu/drm/nouveau/nvkm/engine/disp/uconn.c  | 91 +++++++++++--------
 .../gpu/drm/nouveau/nvkm/engine/disp/uconn.h  |  6 ++
 3 files changed, 58 insertions(+), 41 deletions(-)
 create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.h

diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.h
index 01c3146c7066..0eb15e28d0c8 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.h
@@ -13,7 +13,7 @@ struct nvkm_conn {
 
 	struct list_head head;
 
-	struct nvkm_object object;
+	bool user; /* protected by disp->user.lock */
 };
 
 int nvkm_conn_new(struct nvkm_disp *, int index, struct nvbios_connE *,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c
index 5e44ec977d42..773e49e557f8 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.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_uconn(p) container_of((p), struct nvkm_conn, object)
-#include "conn.h"
+#include "uconn.h"
 #include "outp.h"
 
 #include <core/client.h>
@@ -30,6 +29,11 @@
 
 #include <nvif/if0011.h>
 
+struct nvif_conn_priv {
+	struct nvkm_object object;
+	struct nvkm_conn *conn;
+};
+
 static int
 nvkm_uconn_uevent_gsp(struct nvkm_object *object, u64 token, u32 bits)
 {
@@ -94,7 +98,7 @@ nvkm_connector_is_dp_dms(u8 type)
 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_conn *conn = container_of(object, struct nvif_conn_priv, object)->conn;
 	struct nvkm_disp *disp = conn->disp;
 	struct nvkm_device *device = disp->engine.subdev.device;
 	struct nvkm_outp *outp;
@@ -151,13 +155,13 @@ nvkm_uconn_uevent(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_
 static void *
 nvkm_uconn_dtor(struct nvkm_object *object)
 {
-	struct nvkm_conn *conn = nvkm_uconn(object);
-	struct nvkm_disp *disp = conn->disp;
+	struct nvif_conn_priv *uconn = container_of(object, typeof(*uconn), object);
+	struct nvkm_disp *disp = uconn->conn->disp;
 
 	spin_lock(&disp->user.lock);
-	conn->object.func = NULL;
+	uconn->conn->user = false;
 	spin_unlock(&disp->user.lock);
-	return NULL;
+	return uconn;
 }
 
 static const struct nvkm_object_func
@@ -173,7 +177,7 @@ nvkm_uconn_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_conn *cont, *conn = NULL;
 	union nvif_conn_args *args = argv;
-	int ret;
+	struct nvif_conn_priv *uconn;
 
 	if (argc != sizeof(args->v0) || args->v0.version != 0)
 		return -ENOSYS;
@@ -188,39 +192,46 @@ nvkm_uconn_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nv
 	if (!conn)
 		return -EINVAL;
 
-	ret = -EBUSY;
-	spin_lock(&disp->user.lock);
-	if (!conn->object.func) {
-		switch (conn->info.type) {
-		case DCB_CONNECTOR_VGA      : args->v0.type = NVIF_CONN_V0_VGA; break;
-		case DCB_CONNECTOR_TV_0     :
-		case DCB_CONNECTOR_TV_1     :
-		case DCB_CONNECTOR_TV_3     : args->v0.type = NVIF_CONN_V0_TV; break;
-		case DCB_CONNECTOR_DMS59_0  :
-		case DCB_CONNECTOR_DMS59_1  :
-		case DCB_CONNECTOR_DVI_I    : args->v0.type = NVIF_CONN_V0_DVI_I; break;
-		case DCB_CONNECTOR_DVI_D    : args->v0.type = NVIF_CONN_V0_DVI_D; break;
-		case DCB_CONNECTOR_LVDS     : args->v0.type = NVIF_CONN_V0_LVDS; break;
-		case DCB_CONNECTOR_LVDS_SPWG: args->v0.type = NVIF_CONN_V0_LVDS_SPWG; break;
-		case DCB_CONNECTOR_DMS59_DP0:
-		case DCB_CONNECTOR_DMS59_DP1:
-		case DCB_CONNECTOR_DP       :
-		case DCB_CONNECTOR_mDP      :
-		case DCB_CONNECTOR_USB_C    : args->v0.type = NVIF_CONN_V0_DP; break;
-		case DCB_CONNECTOR_eDP      : args->v0.type = NVIF_CONN_V0_EDP; break;
-		case DCB_CONNECTOR_HDMI_0   :
-		case DCB_CONNECTOR_HDMI_1   :
-		case DCB_CONNECTOR_HDMI_C   : args->v0.type = NVIF_CONN_V0_HDMI; break;
-		default:
-			WARN_ON(1);
-			ret = -EINVAL;
-			break;
-		}
+	switch (conn->info.type) {
+	case DCB_CONNECTOR_VGA      : args->v0.type = NVIF_CONN_V0_VGA; break;
+	case DCB_CONNECTOR_TV_0     :
+	case DCB_CONNECTOR_TV_1     :
+	case DCB_CONNECTOR_TV_3     : args->v0.type = NVIF_CONN_V0_TV; break;
+	case DCB_CONNECTOR_DMS59_0  :
+	case DCB_CONNECTOR_DMS59_1  :
+	case DCB_CONNECTOR_DVI_I    : args->v0.type = NVIF_CONN_V0_DVI_I; break;
+	case DCB_CONNECTOR_DVI_D    : args->v0.type = NVIF_CONN_V0_DVI_D; break;
+	case DCB_CONNECTOR_LVDS     : args->v0.type = NVIF_CONN_V0_LVDS; break;
+	case DCB_CONNECTOR_LVDS_SPWG: args->v0.type = NVIF_CONN_V0_LVDS_SPWG; break;
+	case DCB_CONNECTOR_DMS59_DP0:
+	case DCB_CONNECTOR_DMS59_DP1:
+	case DCB_CONNECTOR_DP       :
+	case DCB_CONNECTOR_mDP      :
+	case DCB_CONNECTOR_USB_C    : args->v0.type = NVIF_CONN_V0_DP; break;
+	case DCB_CONNECTOR_eDP      : args->v0.type = NVIF_CONN_V0_EDP; break;
+	case DCB_CONNECTOR_HDMI_0   :
+	case DCB_CONNECTOR_HDMI_1   :
+	case DCB_CONNECTOR_HDMI_C   : args->v0.type = NVIF_CONN_V0_HDMI; break;
+	default:
+		WARN_ON(1);
+		return -EINVAL;
+	}
 
-		nvkm_object_ctor(&nvkm_uconn, oclass, &conn->object);
-		*pobject = &conn->object;
-		ret = 0;
+	uconn = kzalloc(sizeof(*uconn), GFP_KERNEL);
+	if (!uconn)
+		return -ENOMEM;
+
+	spin_lock(&disp->user.lock);
+	if (conn->user) {
+		spin_unlock(&disp->user.lock);
+		kfree(uconn);
+		return -EBUSY;
 	}
+	conn->user = true;
 	spin_unlock(&disp->user.lock);
-	return ret;
+
+	nvkm_object_ctor(&nvkm_uconn, oclass, &uconn->object);
+	uconn->conn = conn;
+	*pobject = &uconn->object;
+	return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.h
new file mode 100644
index 000000000000..f53d151e5b09
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.h
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: MIT */
+#ifndef __NVKM_UCONN_H__
+#define __NVKM_UCONN_H__
+#include "conn.h"
+
+#endif
-- 
2.41.0



More information about the Nouveau mailing list