[PATCH 07/11] video: ramfb: use new qemu fw_cfg FS
Ahmad Fatoum
a.fatoum at pengutronix.de
Thu Mar 13 03:17:24 PDT 2025
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 <a.fatoum at pengutronix.de>
---
drivers/video/Kconfig | 2 +-
drivers/video/ramfb.c | 114 +++++++++++++++---------------------------
2 files changed, 42 insertions(+), 74 deletions(-)
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 0539e2d453da..437b6a3ba0f6 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..0a0888fcfbcb 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,75 @@ 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 struct driver ramfb_driver = {
+ .probe = ramfb_probe,
+ .name = "qemu-ramfb",
+};
+
static int ramfb_driver_init(void)
{
struct cdev *cdev;
- int err = 0;
+ struct device *dev;
+ const char *mntpath;
+ int dirfd, fd;
- for_each_cdev(cdev) {
- int fd, ret;
+ platform_driver_register(&ramfb_driver);
- if (!strstarts(cdev->name, "fw_cfg"))
- continue;
+ cdev = cdev_by_name("fw_cfg");
+ if (!cdev)
+ return 0;
- fd = cdev_fdopen(cdev, O_RDWR);
- if (fd < 0) {
- err = fd;
- continue;
- }
+ mntpath = cdev_mount(cdev);
+ if (IS_ERR(mntpath))
+ return PTR_ERR(mntpath);
- ret = ramfb_probe(cdev->dev, fd);
- if (ret == 0)
- continue;
- if (ret != -ENODEV && ret != -ENXIO)
- err = ret;
+ dirfd = open(mntpath, O_PATH);
+ if (dirfd < 0)
+ return dirfd;
- close(fd);
- }
+ fd = openat(dirfd, "by_name/etc/ramfb", O_WRONLY);
+ close(dirfd);
+ if (fd == -ENOENT)
+ return 0;
+ if (fd < 0)
+ return fd;
- return err;
+ 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;
}
-device_initcall(ramfb_driver_init);
+late_initcall(ramfb_driver_init);
MODULE_AUTHOR("Adrian Negreanu <adrian.negreanu at nxp.com>");
MODULE_DESCRIPTION("QEMU RamFB driver");
--
2.39.5
More information about the barebox
mailing list