mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* drm: Platform helpers for exynos-style component registration.
@ 2015-09-16 18:14 Eric Anholt
  2015-09-16 18:14 ` [PATCH 1/4] drm: Put platform driver registration/unregistration loops in core Eric Anholt
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Eric Anholt @ 2015-09-16 18:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-kernel, David Airlie, Inki Dae, Joonyoung Shim,
	Seung-Woo Kim, Kyungmin Park, linux-arm-msm, Rob Clark

I had previously modeled vc4 off of msm's component driver
registration, but on further investigation exynos has an even cleaner
way of doing it.  Here's a series to turn exynos's style into core
helpers, and use it from msm.

The patches are build tested, but I don't have either of the platforms
to test on.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] drm: Put platform driver registration/unregistration loops in core.
  2015-09-16 18:14 drm: Platform helpers for exynos-style component registration Eric Anholt
@ 2015-09-16 18:14 ` Eric Anholt
  2015-09-16 19:20   ` Daniel Vetter
  2015-09-16 18:14 ` [PATCH 2/4] drm/msm: Use drm_platform_register/unregister_drivers() Eric Anholt
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 6+ messages in thread
From: Eric Anholt @ 2015-09-16 18:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-kernel, David Airlie, Inki Dae, Joonyoung Shim,
	Seung-Woo Kim, Kyungmin Park, linux-arm-msm, Rob Clark,
	Eric Anholt

This is mostly just a move of the code from exynos, with a slight
reformat.  I wanted to do a similar thing for vc4, and msm looks like
a good candidate as well.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 drivers/gpu/drm/Makefile                |  3 ++-
 drivers/gpu/drm/drm_platform_helpers.c  | 45 +++++++++++++++++++++++++++++++++
 drivers/gpu/drm/exynos/exynos_drm_drv.c | 38 +++++-----------------------
 include/drm/drmP.h                      |  4 +++
 4 files changed, 57 insertions(+), 33 deletions(-)
 create mode 100644 drivers/gpu/drm/drm_platform_helpers.c

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 45e7719..266d199 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -7,7 +7,8 @@ drm-y       :=	drm_auth.o drm_bufs.o drm_cache.o \
 		drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \
 		drm_lock.o drm_memory.o drm_drv.o drm_vm.o \
 		drm_agpsupport.o drm_scatter.o drm_pci.o \
-		drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \
+		drm_platform.o drm_platform_helpers.o \
+		drm_sysfs.o drm_hashtab.o drm_mm.o \
 		drm_crtc.o drm_modes.o drm_edid.o \
 		drm_info.o drm_debugfs.o drm_encoder_slave.o \
 		drm_trace_points.o drm_global.o drm_prime.o \
diff --git a/drivers/gpu/drm/drm_platform_helpers.c b/drivers/gpu/drm/drm_platform_helpers.c
new file mode 100644
index 0000000..a54c3e3
--- /dev/null
+++ b/drivers/gpu/drm/drm_platform_helpers.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <drm/drmP.h>
+
+/**
+ * drm_platform_register_drivers - Helper to register an array of
+ * struct platform_drivers.
+ */
+int drm_platform_register_drivers(struct platform_driver *const *drv,
+				  int count)
+{
+	int i, ret;
+
+	for (i = 0; i < count; ++i) {
+		ret = platform_driver_register(drv[i]);
+		if (ret) {
+			while (--i >= 0)
+				platform_driver_unregister(drv[i]);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(drm_platform_register_drivers);
+
+/**
+ * drm_platform_unregister_drivers - Helper to unregister an array of
+ * struct platform_drivers (in the opposite order they would have been
+ * registered by drm_platform_register_drivers()).
+ */
+void drm_platform_unregister_drivers(struct platform_driver *const *drv,
+				     int count)
+{
+	while (--count >= 0)
+		platform_driver_unregister(drv[count]);
+}
+EXPORT_SYMBOL_GPL(drm_platform_unregister_drivers);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index fa5194c..83f829b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -520,53 +520,27 @@ static int exynos_drm_register_devices(void)
 	return 0;
 }
 
-static void exynos_drm_unregister_drivers(struct platform_driver * const *drv,
-					  int count)
-{
-	while (--count >= 0)
-		platform_driver_unregister(drv[count]);
-}
-
-static int exynos_drm_register_drivers(struct platform_driver * const *drv,
-				       int count)
-{
-	int i, ret;
-
-	for (i = 0; i < count; ++i) {
-		ret = platform_driver_register(drv[i]);
-		if (!ret)
-			continue;
-
-		while (--i >= 0)
-			platform_driver_unregister(drv[i]);
-
-		return ret;
-	}
-
-	return 0;
-}
-
 static inline int exynos_drm_register_kms_drivers(void)
 {
-	return exynos_drm_register_drivers(exynos_drm_kms_drivers,
-					ARRAY_SIZE(exynos_drm_kms_drivers));
+	return drm_platform_register_drivers(exynos_drm_kms_drivers,
+					     ARRAY_SIZE(exynos_drm_kms_drivers));
 }
 
 static inline int exynos_drm_register_non_kms_drivers(void)
 {
-	return exynos_drm_register_drivers(exynos_drm_non_kms_drivers,
-					ARRAY_SIZE(exynos_drm_non_kms_drivers));
+	return drm_platform_register_drivers(exynos_drm_non_kms_drivers,
+					     ARRAY_SIZE(exynos_drm_non_kms_drivers));
 }
 
 static inline void exynos_drm_unregister_kms_drivers(void)
 {
-	exynos_drm_unregister_drivers(exynos_drm_kms_drivers,
+	drm_platform_unregister_drivers(exynos_drm_kms_drivers,
 					ARRAY_SIZE(exynos_drm_kms_drivers));
 }
 
 static inline void exynos_drm_unregister_non_kms_drivers(void)
 {
-	exynos_drm_unregister_drivers(exynos_drm_non_kms_drivers,
+	drm_platform_unregister_drivers(exynos_drm_non_kms_drivers,
 					ARRAY_SIZE(exynos_drm_non_kms_drivers));
 }
 
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 8b5ce7c..a774574 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -1087,6 +1087,10 @@ extern int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *speed_mask);
 /* platform section */
 extern int drm_platform_init(struct drm_driver *driver, struct platform_device *platform_device);
 extern int drm_platform_set_busid(struct drm_device *d, struct drm_master *m);
+int drm_platform_register_drivers(struct platform_driver *const *drv,
+				  int count);
+void drm_platform_unregister_drivers(struct platform_driver *const *drv,
+				     int count);
 
 /* returns true if currently okay to sleep */
 static __inline__ bool drm_can_sleep(void)
-- 
2.1.4


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 2/4] drm/msm: Use drm_platform_register/unregister_drivers().
  2015-09-16 18:14 drm: Platform helpers for exynos-style component registration Eric Anholt
  2015-09-16 18:14 ` [PATCH 1/4] drm: Put platform driver registration/unregistration loops in core Eric Anholt
@ 2015-09-16 18:14 ` Eric Anholt
  2015-09-16 18:14 ` [PATCH 3/4] drm: Move exynos "match_add all devices matching my drivers" to core Eric Anholt
  2015-09-16 18:14 ` [PATCH 4/4] drm/msm: Use exynos's model for handling component driver matching Eric Anholt
  3 siblings, 0 replies; 6+ messages in thread
From: Eric Anholt @ 2015-09-16 18:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-kernel, David Airlie, Inki Dae, Joonyoung Shim,
	Seung-Woo Kim, Kyungmin Park, linux-arm-msm, Rob Clark,
	Eric Anholt

This matches how exynos handles the registration of its component
drivers.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 drivers/gpu/drm/msm/adreno/adreno_device.c | 12 +-----------
 drivers/gpu/drm/msm/dsi/dsi.c              | 16 +---------------
 drivers/gpu/drm/msm/dsi/dsi.h              |  2 --
 drivers/gpu/drm/msm/dsi/phy/dsi_phy.c      | 12 +-----------
 drivers/gpu/drm/msm/edp/edp.c              | 14 +-------------
 drivers/gpu/drm/msm/hdmi/hdmi.c            | 12 +-----------
 drivers/gpu/drm/msm/msm_drv.c              | 26 ++++++++++++++++++--------
 drivers/gpu/drm/msm/msm_drv.h              | 16 ++++------------
 drivers/gpu/drm/msm/msm_gpu.h              |  3 +--
 9 files changed, 28 insertions(+), 85 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
index 1ea2df5..8b0eb95 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -286,7 +286,7 @@ static const struct of_device_id dt_match[] = {
 	{}
 };
 
-static struct platform_driver adreno_driver = {
+struct platform_driver adreno_driver = {
 	.probe = adreno_probe,
 	.remove = adreno_remove,
 	.driver = {
@@ -294,13 +294,3 @@ static struct platform_driver adreno_driver = {
 		.of_match_table = dt_match,
 	},
 };
-
-void __init adreno_register(void)
-{
-	platform_driver_register(&adreno_driver);
-}
-
-void __exit adreno_unregister(void)
-{
-	platform_driver_unregister(&adreno_driver);
-}
diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c
index 6edcd6f..41cfbd5 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.c
+++ b/drivers/gpu/drm/msm/dsi/dsi.c
@@ -163,7 +163,7 @@ static const struct of_device_id dt_match[] = {
 	{}
 };
 
-static struct platform_driver dsi_driver = {
+struct platform_driver msm_dsi_driver = {
 	.probe = dsi_dev_probe,
 	.remove = dsi_dev_remove,
 	.driver = {
@@ -172,20 +172,6 @@ static struct platform_driver dsi_driver = {
 	},
 };
 
-void __init msm_dsi_register(void)
-{
-	DBG("");
-	msm_dsi_phy_driver_register();
-	platform_driver_register(&dsi_driver);
-}
-
-void __exit msm_dsi_unregister(void)
-{
-	DBG("");
-	msm_dsi_phy_driver_unregister();
-	platform_driver_unregister(&dsi_driver);
-}
-
 int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
 		struct drm_encoder *encoders[MSM_DSI_ENCODER_NUM])
 {
diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index 5f5a373..08fff5c 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -164,8 +164,6 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi);
 
 /* dsi phy */
 struct msm_dsi_phy;
-void msm_dsi_phy_driver_register(void);
-void msm_dsi_phy_driver_unregister(void);
 int msm_dsi_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
 	const unsigned long bit_rate, const unsigned long esc_rate);
 void msm_dsi_phy_disable(struct msm_dsi_phy *phy);
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
index 401ff58..f918b56 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
@@ -375,7 +375,7 @@ static int dsi_phy_driver_remove(struct platform_device *pdev)
 	return 0;
 }
 
-static struct platform_driver dsi_phy_platform_driver = {
+struct platform_driver msm_dsi_phy_driver = {
 	.probe      = dsi_phy_driver_probe,
 	.remove     = dsi_phy_driver_remove,
 	.driver     = {
@@ -384,16 +384,6 @@ static struct platform_driver dsi_phy_platform_driver = {
 	},
 };
 
-void __init msm_dsi_phy_driver_register(void)
-{
-	platform_driver_register(&dsi_phy_platform_driver);
-}
-
-void __exit msm_dsi_phy_driver_unregister(void)
-{
-	platform_driver_unregister(&dsi_phy_platform_driver);
-}
-
 int msm_dsi_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
 	const unsigned long bit_rate, const unsigned long esc_rate)
 {
diff --git a/drivers/gpu/drm/msm/edp/edp.c b/drivers/gpu/drm/msm/edp/edp.c
index 0940e84..0bf75b0 100644
--- a/drivers/gpu/drm/msm/edp/edp.c
+++ b/drivers/gpu/drm/msm/edp/edp.c
@@ -122,7 +122,7 @@ static const struct of_device_id dt_match[] = {
 	{}
 };
 
-static struct platform_driver edp_driver = {
+struct platform_driver msm_edp_driver = {
 	.probe = edp_dev_probe,
 	.remove = edp_dev_remove,
 	.driver = {
@@ -131,18 +131,6 @@ static struct platform_driver edp_driver = {
 	},
 };
 
-void __init msm_edp_register(void)
-{
-	DBG("");
-	platform_driver_register(&edp_driver);
-}
-
-void __exit msm_edp_unregister(void)
-{
-	DBG("");
-	platform_driver_unregister(&edp_driver);
-}
-
 /* Second part of initialization, the drm/kms level modeset_init */
 int msm_edp_modeset_init(struct msm_edp *edp, struct drm_device *dev,
 				struct drm_encoder *encoder)
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index 101b324..b44b3f1 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -518,7 +518,7 @@ static int hdmi_dev_remove(struct platform_device *pdev)
 	return 0;
 }
 
-static struct platform_driver hdmi_driver = {
+struct platform_driver msm_hdmi_driver = {
 	.probe = hdmi_dev_probe,
 	.remove = hdmi_dev_remove,
 	.driver = {
@@ -526,13 +526,3 @@ static struct platform_driver hdmi_driver = {
 		.of_match_table = dt_match,
 	},
 };
-
-void __init hdmi_register(void)
-{
-	platform_driver_register(&hdmi_driver);
-}
-
-void __exit hdmi_unregister(void)
-{
-	platform_driver_unregister(&hdmi_driver);
-}
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 0339c5d..a9b0573 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -1159,13 +1159,25 @@ static struct platform_driver msm_platform_driver = {
 	.id_table   = msm_id,
 };
 
+static struct platform_driver *const component_drivers[] = {
+#if IS_ENABLED(CONFIG_DRM_MSM_DSI)
+	&msm_dsi_phy_driver,
+	&msm_dsi_driver,
+#endif
+	&msm_hdmi_driver,
+	&adreno_driver,
+};
+
 static int __init msm_drm_register(void)
 {
+	int ret;
+
 	DBG("init");
-	msm_dsi_register();
-	msm_edp_register();
-	hdmi_register();
-	adreno_register();
+	ret = drm_platform_register_drivers(component_drivers,
+					    ARRAY_SIZE(component_drivers));
+	if (ret)
+		return ret;
+
 	return platform_driver_register(&msm_platform_driver);
 }
 
@@ -1173,10 +1185,8 @@ static void __exit msm_drm_unregister(void)
 {
 	DBG("fini");
 	platform_driver_unregister(&msm_platform_driver);
-	hdmi_unregister();
-	adreno_unregister();
-	msm_edp_unregister();
-	msm_dsi_unregister();
+	drm_platform_unregister_drivers(component_drivers,
+					ARRAY_SIZE(component_drivers));
 }
 
 module_init(msm_drm_register);
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 3be7a56..88e542b 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -249,12 +249,10 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev);
 struct hdmi;
 int hdmi_modeset_init(struct hdmi *hdmi, struct drm_device *dev,
 		struct drm_encoder *encoder);
-void __init hdmi_register(void);
-void __exit hdmi_unregister(void);
+extern struct platform_driver msm_hdmi_driver;
 
 struct msm_edp;
-void __init msm_edp_register(void);
-void __exit msm_edp_unregister(void);
+extern struct platform_driver msm_edp_driver;
 int msm_edp_modeset_init(struct msm_edp *edp, struct drm_device *dev,
 		struct drm_encoder *encoder);
 
@@ -265,17 +263,11 @@ enum msm_dsi_encoder_id {
 	MSM_DSI_ENCODER_NUM = 2
 };
 #ifdef CONFIG_DRM_MSM_DSI
-void __init msm_dsi_register(void);
-void __exit msm_dsi_unregister(void);
+extern struct platform_driver msm_dsi_driver;
+extern struct platform_driver msm_dsi_phy_driver;
 int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
 		struct drm_encoder *encoders[MSM_DSI_ENCODER_NUM]);
 #else
-static inline void __init msm_dsi_register(void)
-{
-}
-static inline void __exit msm_dsi_unregister(void)
-{
-}
 static inline int msm_dsi_modeset_init(struct msm_dsi *msm_dsi,
 		struct drm_device *dev,
 		struct drm_encoder *encoders[MSM_DSI_ENCODER_NUM])
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index 2bbe85a..2cd6a68 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -169,7 +169,6 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
 void msm_gpu_cleanup(struct msm_gpu *gpu);
 
 struct msm_gpu *adreno_load_gpu(struct drm_device *dev);
-void __init adreno_register(void);
-void __exit adreno_unregister(void);
+extern struct platform_driver adreno_driver;
 
 #endif /* __MSM_GPU_H__ */
-- 
2.1.4


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 3/4] drm: Move exynos "match_add all devices matching my drivers" to core.
  2015-09-16 18:14 drm: Platform helpers for exynos-style component registration Eric Anholt
  2015-09-16 18:14 ` [PATCH 1/4] drm: Put platform driver registration/unregistration loops in core Eric Anholt
  2015-09-16 18:14 ` [PATCH 2/4] drm/msm: Use drm_platform_register/unregister_drivers() Eric Anholt
@ 2015-09-16 18:14 ` Eric Anholt
  2015-09-16 18:14 ` [PATCH 4/4] drm/msm: Use exynos's model for handling component driver matching Eric Anholt
  3 siblings, 0 replies; 6+ messages in thread
From: Eric Anholt @ 2015-09-16 18:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-kernel, David Airlie, Inki Dae, Joonyoung Shim,
	Seung-Woo Kim, Kyungmin Park, linux-arm-msm, Rob Clark,
	Eric Anholt

This is a really nice way to handle the component setup.  The
subsystem driver knows that it's got a bunch of component drivers, and
for any devices that matched its component drivers, it wants all of
those to bind to it as master.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 drivers/gpu/drm/drm_platform_helpers.c  | 33 +++++++++++++++++++++++++++++
 drivers/gpu/drm/exynos/exynos_drm_drv.c | 37 +++++++--------------------------
 include/drm/drmP.h                      |  5 +++++
 3 files changed, 45 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/drm_platform_helpers.c b/drivers/gpu/drm/drm_platform_helpers.c
index a54c3e3..0819c49 100644
--- a/drivers/gpu/drm/drm_platform_helpers.c
+++ b/drivers/gpu/drm/drm_platform_helpers.c
@@ -7,6 +7,7 @@
  * option) any later version.
  */
 
+#include <linux/component.h>
 #include <drm/drmP.h>
 
 /**
@@ -43,3 +44,35 @@ void drm_platform_unregister_drivers(struct platform_driver *const *drv,
 		platform_driver_unregister(drv[count]);
 }
 EXPORT_SYMBOL_GPL(drm_platform_unregister_drivers);
+
+static int compare_dev(struct device *dev, void *data)
+{
+	return dev == (struct device *)data;
+}
+
+/**
+ * drm_platform_component_match_add_drivers - For each driver passed
+ * in, finds each device that matched to it and adds it as a component
+ * driver to the match list.
+ */
+void drm_platform_component_match_add_drivers(struct device *dev,
+					      struct component_match **match,
+					      struct platform_driver *const *drivers,
+					      int count)
+{
+	int i;
+
+	for (i = 0; i < count; i++) {
+		struct device_driver *drv = &drivers[i]->driver;
+		struct device *p = NULL, *d;
+
+		while ((d = bus_find_device(&platform_bus_type, p, drv,
+					    (void *)platform_bus_type.match))) {
+			put_device(p);
+			component_match_add(dev, match, compare_dev, d);
+			p = d;
+		}
+		put_device(p);
+	}
+}
+EXPORT_SYMBOL_GPL(drm_platform_component_match_add_drivers);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 83f829b..9151304 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -412,32 +412,6 @@ static struct platform_driver *const exynos_drm_drv_with_simple_dev[] = {
 };
 #define PDEV_COUNT ARRAY_SIZE(exynos_drm_drv_with_simple_dev)
 
-static int compare_dev(struct device *dev, void *data)
-{
-	return dev == (struct device *)data;
-}
-
-static struct component_match *exynos_drm_match_add(struct device *dev)
-{
-	struct component_match *match = NULL;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(exynos_drm_kms_drivers); ++i) {
-		struct device_driver *drv = &exynos_drm_kms_drivers[i]->driver;
-		struct device *p = NULL, *d;
-
-		while ((d = bus_find_device(&platform_bus_type, p, drv,
-					    (void *)platform_bus_type.match))) {
-			put_device(p);
-			component_match_add(dev, &match, compare_dev, d);
-			p = d;
-		}
-		put_device(p);
-	}
-
-	return match ?: ERR_PTR(-ENODEV);
-}
-
 static int exynos_drm_bind(struct device *dev)
 {
 	return drm_platform_init(&exynos_drm_driver, to_platform_device(dev));
@@ -455,14 +429,17 @@ static const struct component_master_ops exynos_drm_ops = {
 
 static int exynos_drm_platform_probe(struct platform_device *pdev)
 {
-	struct component_match *match;
+	struct component_match *match = NULL;
 
 	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 	exynos_drm_driver.num_ioctls = ARRAY_SIZE(exynos_ioctls);
 
-	match = exynos_drm_match_add(&pdev->dev);
-	if (IS_ERR(match))
-		return PTR_ERR(match);
+	drm_platform_component_match_add_drivers(&pdev->dev, &match,
+						 exynos_drm_kms_drivers,
+						 ARRAY_SIZE(exynos_drm_kms_drivers));
+
+	if (!match)
+		return -ENODEV;
 
 	return component_master_add_with_match(&pdev->dev, &exynos_drm_ops,
 					       match);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index a774574..b65d886 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -88,6 +88,7 @@ struct device_node;
 struct videomode;
 struct reservation_object;
 struct dma_buf_attachment;
+struct component_match;
 
 /*
  * 4 debug categories are defined:
@@ -1091,6 +1092,10 @@ int drm_platform_register_drivers(struct platform_driver *const *drv,
 				  int count);
 void drm_platform_unregister_drivers(struct platform_driver *const *drv,
 				     int count);
+void drm_platform_component_match_add_drivers(struct device *dev,
+					      struct component_match **match,
+					      struct platform_driver **drivers,
+					      int count);
 
 /* returns true if currently okay to sleep */
 static __inline__ bool drm_can_sleep(void)
-- 
2.1.4


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 4/4] drm/msm: Use exynos's model for handling component driver matching.
  2015-09-16 18:14 drm: Platform helpers for exynos-style component registration Eric Anholt
                   ` (2 preceding siblings ...)
  2015-09-16 18:14 ` [PATCH 3/4] drm: Move exynos "match_add all devices matching my drivers" to core Eric Anholt
@ 2015-09-16 18:14 ` Eric Anholt
  3 siblings, 0 replies; 6+ messages in thread
From: Eric Anholt @ 2015-09-16 18:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-kernel, David Airlie, Inki Dae, Joonyoung Shim,
	Seung-Woo Kim, Kyungmin Park, linux-arm-msm, Rob Clark,
	Eric Anholt

This eliminates the need for the "connectors" and "gpus" nodes in the
devicetree, which we were doing nothing connector- or gpu-specific
with.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 drivers/gpu/drm/msm/msm_drv.c | 65 +++++++++++++++++--------------------------
 include/drm/drmP.h            |  2 +-
 2 files changed, 27 insertions(+), 40 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index a9b0573..4e1263b 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -1039,34 +1039,7 @@ static const struct dev_pm_ops msm_pm_ops = {
  * Componentized driver support:
  */
 
-#ifdef CONFIG_OF
-/* NOTE: the CONFIG_OF case duplicates the same code as exynos or imx
- * (or probably any other).. so probably some room for some helpers
- */
-static int compare_of(struct device *dev, void *data)
-{
-	return dev->of_node == data;
-}
-
-static int add_components(struct device *dev, struct component_match **matchptr,
-		const char *name)
-{
-	struct device_node *np = dev->of_node;
-	unsigned i;
-
-	for (i = 0; ; i++) {
-		struct device_node *node;
-
-		node = of_parse_phandle(np, name, i);
-		if (!node)
-			break;
-
-		component_match_add(dev, matchptr, compare_of, node);
-	}
-
-	return 0;
-}
-#else
+#ifndef CONFIG_OF
 static int compare_dev(struct device *dev, void *data)
 {
 	return dev == data;
@@ -1088,6 +1061,20 @@ static const struct component_master_ops msm_drm_ops = {
 	.unbind = msm_drm_unbind,
 };
 
+static struct platform_driver *const noncomponent_drivers[] = {
+#if IS_ENABLED(CONFIG_DRM_MSM_DSI)
+	&msm_dsi_phy_driver,
+#endif
+};
+
+static struct platform_driver *const component_drivers[] = {
+#if IS_ENABLED(CONFIG_DRM_MSM_DSI)
+	&msm_dsi_driver,
+#endif
+	&msm_hdmi_driver,
+	&adreno_driver,
+};
+
 /*
  * Platform driver:
  */
@@ -1096,8 +1083,9 @@ static int msm_pdev_probe(struct platform_device *pdev)
 {
 	struct component_match *match = NULL;
 #ifdef CONFIG_OF
-	add_components(&pdev->dev, &match, "connectors");
-	add_components(&pdev->dev, &match, "gpus");
+	drm_platform_component_match_add_drivers(&pdev->dev, &match,
+						 component_drivers,
+						 ARRAY_SIZE(component_drivers));
 #else
 	/* For non-DT case, it kinda sucks.  We don't actually have a way
 	 * to know whether or not we are waiting for certain devices (or if
@@ -1159,20 +1147,17 @@ static struct platform_driver msm_platform_driver = {
 	.id_table   = msm_id,
 };
 
-static struct platform_driver *const component_drivers[] = {
-#if IS_ENABLED(CONFIG_DRM_MSM_DSI)
-	&msm_dsi_phy_driver,
-	&msm_dsi_driver,
-#endif
-	&msm_hdmi_driver,
-	&adreno_driver,
-};
-
 static int __init msm_drm_register(void)
 {
 	int ret;
 
 	DBG("init");
+
+	ret = drm_platform_register_drivers(noncomponent_drivers,
+					    ARRAY_SIZE(noncomponent_drivers));
+	if (ret)
+		return ret;
+
 	ret = drm_platform_register_drivers(component_drivers,
 					    ARRAY_SIZE(component_drivers));
 	if (ret)
@@ -1187,6 +1172,8 @@ static void __exit msm_drm_unregister(void)
 	platform_driver_unregister(&msm_platform_driver);
 	drm_platform_unregister_drivers(component_drivers,
 					ARRAY_SIZE(component_drivers));
+	drm_platform_unregister_drivers(noncomponent_drivers,
+					ARRAY_SIZE(noncomponent_drivers));
 }
 
 module_init(msm_drm_register);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index b65d886..0da8599 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -1094,7 +1094,7 @@ void drm_platform_unregister_drivers(struct platform_driver *const *drv,
 				     int count);
 void drm_platform_component_match_add_drivers(struct device *dev,
 					      struct component_match **match,
-					      struct platform_driver **drivers,
+					      struct platform_driver *const *drivers,
 					      int count);
 
 /* returns true if currently okay to sleep */
-- 
2.1.4


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/4] drm: Put platform driver registration/unregistration loops in core.
  2015-09-16 18:14 ` [PATCH 1/4] drm: Put platform driver registration/unregistration loops in core Eric Anholt
@ 2015-09-16 19:20   ` Daniel Vetter
  0 siblings, 0 replies; 6+ messages in thread
From: Daniel Vetter @ 2015-09-16 19:20 UTC (permalink / raw)
  To: Eric Anholt
  Cc: dri-devel, linux-arm-msm, Seung-Woo Kim,
	Linux Kernel Mailing List, Kyungmin Park

On Wed, Sep 16, 2015 at 11:14 AM, Eric Anholt <eric@anholt.net> wrote:
> This is mostly just a move of the code from exynos, with a slight
> reformat.  I wanted to do a similar thing for vc4, and msm looks like
> a good candidate as well.
>
> Signed-off-by: Eric Anholt <eric@anholt.net>
> ---
>  drivers/gpu/drm/Makefile                |  3 ++-
>  drivers/gpu/drm/drm_platform_helpers.c  | 45 +++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/exynos/exynos_drm_drv.c | 38 +++++-----------------------
>  include/drm/drmP.h                      |  4 +++
>  4 files changed, 57 insertions(+), 33 deletions(-)
>  create mode 100644 drivers/gpu/drm/drm_platform_helpers.c
>
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index 45e7719..266d199 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -7,7 +7,8 @@ drm-y       :=  drm_auth.o drm_bufs.o drm_cache.o \
>                 drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \
>                 drm_lock.o drm_memory.o drm_drv.o drm_vm.o \
>                 drm_agpsupport.o drm_scatter.o drm_pci.o \
> -               drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \
> +               drm_platform.o drm_platform_helpers.o \
> +               drm_sysfs.o drm_hashtab.o drm_mm.o \

Imo it'd would be good to have a separate module for helpers like
these (maybe even put them into the kms helpers). At least that
explicit split on the modeset side seems to help with a clean split
between mandatory core bits and helper code.

>                 drm_crtc.o drm_modes.o drm_edid.o \
>                 drm_info.o drm_debugfs.o drm_encoder_slave.o \
>                 drm_trace_points.o drm_global.o drm_prime.o \
> diff --git a/drivers/gpu/drm/drm_platform_helpers.c b/drivers/gpu/drm/drm_platform_helpers.c
> new file mode 100644
> index 0000000..a54c3e3
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_platform_helpers.c
> @@ -0,0 +1,45 @@
> +/*
> + * Copyright (c) 2011 Samsung Electronics Co., Ltd.
> + *
> + * This program is free software; you can redistribute  it and/or modify it
> + * under  the terms of  the GNU General  Public License as published by the
> + * Free Software Foundation;  either version 2 of the  License, or (at your
> + * option) any later version.
> + */
> +
> +#include <drm/drmP.h>
> +
> +/**
> + * drm_platform_register_drivers - Helper to register an array of
> + * struct platform_drivers.
> + */

Please add a new section to Documentation/DocBook/drm.tmpl so that
these kerneldoc comments are included. Without that 0day won't catch
mismatches in kerneldoc and hopefully including it will also make it a
bit more discoverable. And with the new markdown stuff in
drm-intel-nightly you could even include an example snippet for how to
use it, but that's kinda overkilla ;-) If you do that kerneldoc will
complain about the missing parameter helpers. Also I recommend to
point at other functions which should be used together with this one
(like _unregister), in 4.3 the htmldocs will actually insert
hyperlinks for that.

Thanks, Daniel

> +int drm_platform_register_drivers(struct platform_driver *const *drv,
> +                                 int count)
> +{
> +       int i, ret;
> +
> +       for (i = 0; i < count; ++i) {
> +               ret = platform_driver_register(drv[i]);
> +               if (ret) {
> +                       while (--i >= 0)
> +                               platform_driver_unregister(drv[i]);
> +                       return ret;
> +               }
> +       }
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL_GPL(drm_platform_register_drivers);
> +
> +/**
> + * drm_platform_unregister_drivers - Helper to unregister an array of
> + * struct platform_drivers (in the opposite order they would have been
> + * registered by drm_platform_register_drivers()).
> + */
> +void drm_platform_unregister_drivers(struct platform_driver *const *drv,
> +                                    int count)
> +{
> +       while (--count >= 0)
> +               platform_driver_unregister(drv[count]);
> +}
> +EXPORT_SYMBOL_GPL(drm_platform_unregister_drivers);
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> index fa5194c..83f829b 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> @@ -520,53 +520,27 @@ static int exynos_drm_register_devices(void)
>         return 0;
>  }
>
> -static void exynos_drm_unregister_drivers(struct platform_driver * const *drv,
> -                                         int count)
> -{
> -       while (--count >= 0)
> -               platform_driver_unregister(drv[count]);
> -}
> -
> -static int exynos_drm_register_drivers(struct platform_driver * const *drv,
> -                                      int count)
> -{
> -       int i, ret;
> -
> -       for (i = 0; i < count; ++i) {
> -               ret = platform_driver_register(drv[i]);
> -               if (!ret)
> -                       continue;
> -
> -               while (--i >= 0)
> -                       platform_driver_unregister(drv[i]);
> -
> -               return ret;
> -       }
> -
> -       return 0;
> -}
> -
>  static inline int exynos_drm_register_kms_drivers(void)
>  {
> -       return exynos_drm_register_drivers(exynos_drm_kms_drivers,
> -                                       ARRAY_SIZE(exynos_drm_kms_drivers));
> +       return drm_platform_register_drivers(exynos_drm_kms_drivers,
> +                                            ARRAY_SIZE(exynos_drm_kms_drivers));
>  }
>
>  static inline int exynos_drm_register_non_kms_drivers(void)
>  {
> -       return exynos_drm_register_drivers(exynos_drm_non_kms_drivers,
> -                                       ARRAY_SIZE(exynos_drm_non_kms_drivers));
> +       return drm_platform_register_drivers(exynos_drm_non_kms_drivers,
> +                                            ARRAY_SIZE(exynos_drm_non_kms_drivers));
>  }
>
>  static inline void exynos_drm_unregister_kms_drivers(void)
>  {
> -       exynos_drm_unregister_drivers(exynos_drm_kms_drivers,
> +       drm_platform_unregister_drivers(exynos_drm_kms_drivers,
>                                         ARRAY_SIZE(exynos_drm_kms_drivers));
>  }
>
>  static inline void exynos_drm_unregister_non_kms_drivers(void)
>  {
> -       exynos_drm_unregister_drivers(exynos_drm_non_kms_drivers,
> +       drm_platform_unregister_drivers(exynos_drm_non_kms_drivers,
>                                         ARRAY_SIZE(exynos_drm_non_kms_drivers));
>  }
>
> diff --git a/include/drm/drmP.h b/include/drm/drmP.h
> index 8b5ce7c..a774574 100644
> --- a/include/drm/drmP.h
> +++ b/include/drm/drmP.h
> @@ -1087,6 +1087,10 @@ extern int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *speed_mask);
>  /* platform section */
>  extern int drm_platform_init(struct drm_driver *driver, struct platform_device *platform_device);
>  extern int drm_platform_set_busid(struct drm_device *d, struct drm_master *m);
> +int drm_platform_register_drivers(struct platform_driver *const *drv,
> +                                 int count);
> +void drm_platform_unregister_drivers(struct platform_driver *const *drv,
> +                                    int count);
>
>  /* returns true if currently okay to sleep */
>  static __inline__ bool drm_can_sleep(void)
> --
> 2.1.4
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2015-09-16 19:20 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-16 18:14 drm: Platform helpers for exynos-style component registration Eric Anholt
2015-09-16 18:14 ` [PATCH 1/4] drm: Put platform driver registration/unregistration loops in core Eric Anholt
2015-09-16 19:20   ` Daniel Vetter
2015-09-16 18:14 ` [PATCH 2/4] drm/msm: Use drm_platform_register/unregister_drivers() Eric Anholt
2015-09-16 18:14 ` [PATCH 3/4] drm: Move exynos "match_add all devices matching my drivers" to core Eric Anholt
2015-09-16 18:14 ` [PATCH 4/4] drm/msm: Use exynos's model for handling component driver matching Eric Anholt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®