blob: 9b6554fff5c193db7bb98bd8b32bee2d8ca0bfe8 [file] [log] [blame]
From 621dba32010600142345476db96c8fa0d1534b99 Mon Sep 17 00:00:00 2001
From: Brandon Pollack <brpol@chromium.org>
Date: Fri, 23 Jun 2023 18:23:43 -0400
Subject: [PATCH] FROMLIST: drm/vkms: Back VKMS with DRM memory management
instead of static objects
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is a small refactor to make ConfigFS support easier. Once we
support ConfigFS, there can be multiple devices instantiated by the
driver, and so moving everything into managed memory makes things much
easier.
This should be a no-op refactor.
Signed-off-by: Jim Shargo <jshargo@chromium.org>
Signed-off-by: Brandon Pollack <brpol@chromium.org>
(am from https://patchwork.kernel.org/project/dri-devel/patch/20230829053201.423261-2-brpol@chromium.org/)
The change is in the final stages of review (fifth iteration), All that
remains is some (potential) igt tests and final signoff.
Some reasons we'd like to submit in chromeOS are:
This will allow our virtual multi display tests to run in presubmit.
This real world case will be compelling evidence if/when upstream
requests some data that this ran for real in production (and avoiding
the chicken egg problem of we need this in the kernel to run the tests
but without running the tests we can't submit upstream).
Signed-off-by: Brandon Pollack <brpol@chromium.org>
BUG=241800059
BUG=283357160
TEST=new tests defined here passing https://chromium-review.googlesource.com/c/chromiumos/platform/tast-tests/+/4666669
Change-Id: I05cf40405f6ea413984e136d6d32030c45285b55
Signed-off-by: Brandon Pollack <brpol@google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/4810098
Reviewed-by: Sean Paul <sean@poorly.run>
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
---
drivers/gpu/drm/vkms/vkms_drv.c | 128 +++++++++++++++--------------
drivers/gpu/drm/vkms/vkms_drv.h | 4 +-
drivers/gpu/drm/vkms/vkms_output.c | 6 +-
3 files changed, 70 insertions(+), 68 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index 0c1a713b7b7b3bc61f7a23ae4f240f0233d937a5..b5ca99011a23bf8f4df2c905910cfc94f88fb1c4 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -9,10 +9,12 @@
* the GPU in DRM API tests.
*/
+#include <linux/device.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
+#include <drm/drm_device.h>
#include <drm/drm_gem.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
@@ -37,8 +39,6 @@
#define DRIVER_MAJOR 1
#define DRIVER_MINOR 0
-static struct vkms_config *default_config;
-
static bool enable_cursor = true;
module_param_named(enable_cursor, enable_cursor, bool, 0444);
MODULE_PARM_DESC(enable_cursor, "Enable/Disable cursor support");
@@ -96,9 +96,9 @@ static int vkms_config_show(struct seq_file *m, void *data)
struct drm_device *dev = entry->dev;
struct vkms_device *vkmsdev = drm_device_to_vkms_device(dev);
- seq_printf(m, "writeback=%d\n", vkmsdev->config->writeback);
- seq_printf(m, "cursor=%d\n", vkmsdev->config->cursor);
- seq_printf(m, "overlay=%d\n", vkmsdev->config->overlay);
+ seq_printf(m, "writeback=%d\n", vkmsdev->config.writeback);
+ seq_printf(m, "cursor=%d\n", vkmsdev->config.cursor);
+ seq_printf(m, "overlay=%d\n", vkmsdev->config.overlay);
return 0;
}
@@ -164,10 +164,9 @@ static int vkms_modeset_init(struct vkms_device *vkmsdev)
dev->mode_config.max_height = YRES_MAX;
dev->mode_config.cursor_width = 512;
dev->mode_config.cursor_height = 512;
- /*
- * FIXME: There's a confusion between bpp and depth between this and
+ /* FIXME: There's a confusion between bpp and depth between this and
* fbdev helpers. We have to go with 0, meaning "pick the default",
- * which is XRGB8888 in all cases.
+ * which ix XRGB8888 in all cases.
*/
dev->mode_config.preferred_depth = 0;
dev->mode_config.helper_private = &vkms_mode_config_helpers;
@@ -175,114 +174,119 @@ static int vkms_modeset_init(struct vkms_device *vkmsdev)
return vkms_output_init(vkmsdev, 0);
}
-static int vkms_create(struct vkms_config *config)
+static int vkms_platform_probe(struct platform_device *pdev)
{
int ret;
- struct platform_device *pdev;
struct vkms_device *vkms_device;
+ void *grp;
- pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
- if (IS_ERR(pdev))
- return PTR_ERR(pdev);
-
- if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL)) {
- ret = -ENOMEM;
- goto out_unregister;
- }
+ grp = devres_open_group(&pdev->dev, NULL, GFP_KERNEL);
+ if (!grp)
+ return -ENOMEM;
vkms_device = devm_drm_dev_alloc(&pdev->dev, &vkms_driver,
struct vkms_device, drm);
if (IS_ERR(vkms_device)) {
ret = PTR_ERR(vkms_device);
- goto out_devres;
+ goto out_release_group;
}
vkms_device->platform = pdev;
- vkms_device->config = config;
- config->dev = vkms_device;
+ vkms_device->config.cursor = enable_cursor;
+ vkms_device->config.writeback = enable_writeback;
+ vkms_device->config.overlay = enable_overlay;
ret = dma_coerce_mask_and_coherent(vkms_device->drm.dev,
DMA_BIT_MASK(64));
if (ret) {
DRM_ERROR("Could not initialize DMA support\n");
- goto out_devres;
+ goto out_release_group;
}
ret = drm_vblank_init(&vkms_device->drm, 1);
if (ret) {
DRM_ERROR("Failed to vblank\n");
- goto out_devres;
+ goto out_release_group;
}
ret = vkms_modeset_init(vkms_device);
- if (ret)
- goto out_devres;
+ if (ret) {
+ DRM_ERROR("Unable to initialize modesetting\n");
+ goto out_release_group;
+ }
drm_debugfs_add_files(&vkms_device->drm, vkms_config_debugfs_list,
ARRAY_SIZE(vkms_config_debugfs_list));
ret = drm_dev_register(&vkms_device->drm, 0);
- if (ret)
- goto out_devres;
+ if (ret) {
+ DRM_ERROR("Unable to register device with id %d\n", pdev->id);
+ goto out_release_group;
+ }
drm_fbdev_shmem_setup(&vkms_device->drm, 0);
+ platform_set_drvdata(pdev, vkms_device);
+ devres_close_group(&pdev->dev, grp);
return 0;
-out_devres:
- devres_release_group(&pdev->dev, NULL);
-out_unregister:
- platform_device_unregister(pdev);
+out_release_group:
+ devres_release_group(&pdev->dev, grp);
return ret;
}
-static int __init vkms_init(void)
+static int vkms_platform_remove(struct platform_device *pdev)
{
- int ret;
- struct vkms_config *config;
-
- config = kmalloc(sizeof(*config), GFP_KERNEL);
- if (!config)
- return -ENOMEM;
-
- default_config = config;
-
- config->cursor = enable_cursor;
- config->writeback = enable_writeback;
- config->overlay = enable_overlay;
+ struct vkms_device *vkms_device;
- ret = vkms_create(config);
- if (ret)
- kfree(config);
+ vkms_device = platform_get_drvdata(pdev);
+ if (!vkms_device)
+ return 0;
- return ret;
+ drm_dev_unregister(&vkms_device->drm);
+ drm_atomic_helper_shutdown(&vkms_device->drm);
+ return 0;
}
-static void vkms_destroy(struct vkms_config *config)
+static struct platform_driver vkms_platform_driver = {
+ .probe = vkms_platform_probe,
+ .remove = vkms_platform_remove,
+ .driver.name = DRIVER_NAME,
+};
+
+static int __init vkms_init(void)
{
+ int ret;
struct platform_device *pdev;
- if (!config->dev) {
- DRM_INFO("vkms_device is NULL.\n");
- return;
+ ret = platform_driver_register(&vkms_platform_driver);
+ if (ret) {
+ DRM_ERROR("Unable to register platform driver\n");
+ return ret;
}
- pdev = config->dev->platform;
-
- drm_dev_unregister(&config->dev->drm);
- drm_atomic_helper_shutdown(&config->dev->drm);
- devres_release_group(&pdev->dev, NULL);
- platform_device_unregister(pdev);
+ pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
+ if (IS_ERR(pdev)) {
+ platform_driver_unregister(&vkms_platform_driver);
+ return PTR_ERR(pdev);
+ }
- config->dev = NULL;
+ return 0;
}
static void __exit vkms_exit(void)
{
- if (default_config->dev)
- vkms_destroy(default_config);
+ struct device *dev;
+
+ while ((dev = platform_find_device_by_driver(
+ NULL, &vkms_platform_driver.driver))) {
+ // platform_find_device_by_driver increments the refcount. Drop
+ // it so we don't leak memory.
+ put_device(dev);
+ platform_device_unregister(to_platform_device(dev));
+ }
- kfree(default_config);
+ platform_driver_unregister(&vkms_platform_driver);
}
module_init(vkms_init);
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index 5e46ea5b96dcc4412d4d78d5fb99287cdf33a293..74658ad2a8d85bf1fe74a70de450bd78a9731a31 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -121,15 +121,13 @@ struct vkms_config {
bool writeback;
bool cursor;
bool overlay;
- /* only set when instantiated */
- struct vkms_device *dev;
};
struct vkms_device {
struct drm_device drm;
struct platform_device *platform;
struct vkms_output output;
- const struct vkms_config *config;
+ struct vkms_config config;
};
#define drm_crtc_to_vkms_output(target) \
diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c
index 5ce70dd946aa631d156589202d10d779018844ff..963a64cf068bbfbdeb89b03bafb843bf7fb895b7 100644
--- a/drivers/gpu/drm/vkms/vkms_output.c
+++ b/drivers/gpu/drm/vkms/vkms_output.c
@@ -62,7 +62,7 @@ int vkms_output_init(struct vkms_device *vkmsdev, int index)
if (IS_ERR(primary))
return PTR_ERR(primary);
- if (vkmsdev->config->overlay) {
+ if (vkmsdev->config.overlay) {
for (n = 0; n < NUM_OVERLAY_PLANES; n++) {
ret = vkms_add_overlay_plane(vkmsdev, index, crtc);
if (ret)
@@ -70,7 +70,7 @@ int vkms_output_init(struct vkms_device *vkmsdev, int index)
}
}
- if (vkmsdev->config->cursor) {
+ if (vkmsdev->config.cursor) {
cursor = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_CURSOR, index);
if (IS_ERR(cursor))
return PTR_ERR(cursor);
@@ -103,7 +103,7 @@ int vkms_output_init(struct vkms_device *vkmsdev, int index)
goto err_attach;
}
- if (vkmsdev->config->writeback) {
+ if (vkmsdev->config.writeback) {
writeback = vkms_enable_writeback_connector(vkmsdev);
if (writeback)
DRM_ERROR("Failed to init writeback connector\n");
--
2.47.0.338.g60cca15819-goog