mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Ahmad Fatoum <a.fatoum@barebox.org>
To: barebox@lists.infradead.org
Cc: Adrian Negreanu <adrian.negreanu@nxp.com>
Subject: [PATCH v2 3/4] video: ramfb: use new qemu fw_cfg FS
Date: Fri,  6 Jun 2025 09:29:38 +0200	[thread overview]
Message-ID: <20250606072939.2082971-4-a.fatoum@barebox.org> (raw)
In-Reply-To: <20250606072939.2082971-1-a.fatoum@barebox.org>

From: Ahmad Fatoum <ahmad@a3f.at>

The new qemu_fw_cfg file system can simplify the ramfb driver a great
deal as it's then no longer necessary to enumerate the files in the
driver.

Signed-off-by: Ahmad Fatoum <ahmad@a3f.at>
---
 drivers/video/Kconfig |  2 +-
 drivers/video/ramfb.c | 98 +++++++------------------------------------
 fs/qemu_fw_cfg.c      | 36 ++++++++++++++++
 3 files changed, 52 insertions(+), 84 deletions(-)

diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index ef19948219f3..86f780ffc417 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -106,7 +106,7 @@ config DRIVER_VIDEO_SIMPLEFB
 
 config DRIVER_VIDEO_RAMFB
 	bool "QEMU RamFB support"
-	select QEMU_FW_CFG
+	select FS_QEMU_FW_CFG
 	help
 	  Add support for setting up a QEMU RamFB driver.
 
diff --git a/drivers/video/ramfb.c b/drivers/video/ramfb.c
index 5b03d8a9c821..cc490496175b 100644
--- a/drivers/video/ramfb.c
+++ b/drivers/video/ramfb.c
@@ -19,7 +19,6 @@ struct ramfb {
 	struct fb_info info;
 	dma_addr_t screen_dma;
 	struct fb_videomode mode;
-	u16 etcfb_select;
 };
 
 struct fw_cfg_etc_ramfb {
@@ -31,37 +30,6 @@ struct fw_cfg_etc_ramfb {
 	u32 stride;
 } __packed;
 
-static int fw_cfg_find_file(struct device *dev, int fd, const char *filename)
-{
-	size_t filename_len = strlen(filename);
-	ssize_t ret;
-	__be32 count;
-	int i;
-
-	ioctl(fd, FW_CFG_SELECT, &(u16) { FW_CFG_FILE_DIR });
-
-	lseek(fd, 0, SEEK_SET);
-
-	ret = read(fd, &count, sizeof(count));
-	if (ret < 0)
-		return ret;
-
-	for (i = 0; i < be32_to_cpu(count); i++) {
-		struct fw_cfg_file qfile;
-
-		read(fd, &qfile, sizeof(qfile));
-
-		dev_dbg(dev, "enumerating file %s\n", qfile.name);
-
-		if (memcmp(qfile.name, filename, filename_len))
-			continue;
-
-		return be16_to_cpu(qfile.select);
-	}
-
-	return -ENOENT;
-}
-
 static void ramfb_populate_modes(struct ramfb *ramfb)
 {
 	struct fb_info *info = &ramfb->info;
@@ -81,14 +49,15 @@ static void ramfb_populate_modes(struct ramfb *ramfb)
 static int ramfb_activate_var(struct fb_info *fbi)
 {
 	struct ramfb *ramfb = fbi->priv;
+	struct device *hwdev = fbi->dev.parent->parent;
 
 	if (fbi->screen_base)
-		dma_free_coherent(DMA_DEVICE_BROKEN,
-				  fbi->screen_base, ramfb->screen_dma, fbi->screen_size);
+		dma_free_coherent(hwdev, fbi->screen_base, ramfb->screen_dma,
+				  fbi->screen_size);
 
 	fbi->screen_size = fbi->xres * fbi->yres * fbi->bits_per_pixel / BITS_PER_BYTE;
-	fbi->screen_base = dma_alloc_coherent(DMA_DEVICE_BROKEN,
-					      fbi->screen_size, &ramfb->screen_dma);
+	fbi->screen_base = dma_alloc_coherent(hwdev, fbi->screen_size,
+					      &ramfb->screen_dma);
 
 	return 0;
 }
@@ -107,8 +76,6 @@ static void ramfb_enable(struct fb_info *fbi)
 	etc_ramfb->height = cpu_to_be32(fbi->yres);
 	etc_ramfb->stride = cpu_to_be32(fbi->line_length);
 
-	ioctl(ramfb->fd, FW_CFG_SELECT, &ramfb->etcfb_select);
-
 	pwrite(ramfb->fd, etc_ramfb, sizeof(*etc_ramfb), 0);
 
 	dma_free(etc_ramfb);
@@ -119,74 +86,39 @@ static struct fb_ops ramfb_ops = {
 	.fb_enable = ramfb_enable,
 };
 
-static int ramfb_probe(struct device *parent_dev, int fd)
+static int ramfb_probe(struct device *dev)
 {
 	int ret;
 	struct ramfb *ramfb;
 	struct fb_info *fbi;
 
-	ret = -ENODEV;
-
 	ramfb = xzalloc(sizeof(*ramfb));
 
-	ramfb->fd = fd;
-
-	ret = fw_cfg_find_file(parent_dev, fd, "etc/ramfb");
-	if (ret < 0) {
-		dev_dbg(parent_dev, "ramfb: fw_cfg (etc/ramfb) file not found\n");
-		return -ENODEV;
-	}
-
-	ramfb->etcfb_select = ret;
-	dev_dbg(parent_dev, "etc/ramfb file at slot 0x%x\n", ramfb->etcfb_select);
+	ramfb->fd = (int)(uintptr_t)dev->platform_data;
 
 	fbi = &ramfb->info;
 	fbi->priv = ramfb;
 	fbi->fbops = &ramfb_ops;
-	fbi->dev.parent = parent_dev;
+	fbi->dev.parent = dev;
 
 	ramfb_populate_modes(ramfb);
 
 	ret = register_framebuffer(fbi);
 	if (ret < 0) {
-		dev_err(parent_dev, "Unable to register ramfb: %d\n", ret);
+		dev_err(dev, "Unable to register ramfb: %d\n", ret);
 		return ret;
 	}
 
-	dev_info(parent_dev, "ramfb registered\n");
+	dev_info(dev, "ramfb registered\n");
 
 	return 0;
 }
 
-static int ramfb_driver_init(void)
-{
-	struct cdev *cdev;
-	int err = 0;
-
-	for_each_cdev(cdev) {
-		int fd, ret;
-
-		if (!strstarts(cdev->name, "fw_cfg"))
-			continue;
-
-		fd = cdev_fdopen(cdev, O_RDWR);
-		if (fd < 0) {
-			err = fd;
-			continue;
-		}
-
-		ret = ramfb_probe(cdev->dev, fd);
-		if (ret == 0)
-			continue;
-		if (ret != -ENODEV && ret != -ENXIO)
-			err = ret;
-
-		close(fd);
-	}
-
-	return err;
-}
-device_initcall(ramfb_driver_init);
+static struct driver ramfb_driver = {
+	.probe = ramfb_probe,
+	.name = "qemu-ramfb",
+};
+device_platform_driver(ramfb_driver);
 
 MODULE_AUTHOR("Adrian Negreanu <adrian.negreanu@nxp.com>");
 MODULE_DESCRIPTION("QEMU RamFB driver");
diff --git a/fs/qemu_fw_cfg.c b/fs/qemu_fw_cfg.c
index a21e6fbf637b..1aa44fb52c70 100644
--- a/fs/qemu_fw_cfg.c
+++ b/fs/qemu_fw_cfg.c
@@ -401,3 +401,39 @@ static int qemu_fw_cfg_fs_init(void)
 	return register_fs_driver(&fw_cfg_fs_driver);
 }
 coredevice_initcall(qemu_fw_cfg_fs_init);
+
+static int qemu_fw_cfg_early_mount(void)
+{
+	struct cdev *cdev;
+	struct device *dev;
+	const char *mntpath;
+	int dirfd, fd;
+
+	cdev = cdev_by_name("fw_cfg");
+	if (!cdev)
+		return 0;
+
+	/*
+	 * Trigger a mount, so ramfb device can be detected and
+	 * environment can be loaded
+	 */
+	mntpath = cdev_mount(cdev);
+	if (IS_ERR(mntpath))
+		return PTR_ERR(mntpath);
+
+	dirfd = open(mntpath, O_PATH | O_DIRECTORY);
+	if (dirfd < 0)
+		return dirfd;
+
+	fd = openat(dirfd, "by_name/etc/ramfb", O_WRONLY);
+	close(dirfd);
+	if (fd >= 0) {
+		dev = device_alloc("qemu-ramfb", DEVICE_ID_SINGLE);
+		dev->parent = cdev->dev;
+		dev->platform_data = (void *)(uintptr_t)fd;
+		platform_device_register(dev);
+	}
+
+	return 0;
+}
+late_initcall(qemu_fw_cfg_early_mount);
-- 
2.39.5




  parent reply	other threads:[~2025-06-06  7:35 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-06  7:29 [PATCH v2 0/4] firmware: qemu_fw_cfg: implement file system Ahmad Fatoum
2025-06-06  7:29 ` [PATCH v2 1/4] fs: add qemu_fw_cfg " Ahmad Fatoum
2025-06-06  7:29 ` [PATCH v2 2/4] firmware: qemu_fw_cfg: register at device initcall level Ahmad Fatoum
2025-06-06  7:29 ` Ahmad Fatoum [this message]
2025-06-06  7:29 ` [PATCH v2 4/4] fs: qemu_fw_cfg: support populating environment via QEMU fw_cfg Ahmad Fatoum

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250606072939.2082971-4-a.fatoum@barebox.org \
    --to=a.fatoum@barebox.org \
    --cc=adrian.negreanu@nxp.com \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox