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@xxxxxxxxxxxxxx> --- 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@xxxxxxx>"); MODULE_DESCRIPTION("QEMU RamFB driver"); -- 2.39.5