Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fbdev/core: Add fb_device_{create,destroy}()

Move the logic to create and destroy fbdev devices into the new
helpers fb_device_create() and fb_device_destroy().

There was a call to fb_cleanup_device() in do_unregister_framebuffer()
that was too late. The device had already been removed at this point.
Move the call into fb_device_destroy().

Declare the helpers in the new internal header file fb_internal.h, as
they are only used within the fbdev core module.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20230613110953.24176-35-tzimmermann@suse.de

+52 -22
+12
drivers/video/fbdev/core/fb_internal.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + #ifndef _FB_INTERNAL_H 4 + #define _FB_INTERNAL_H 5 + 6 + struct fb_info; 7 + 8 + /* fbsysfs.c */ 9 + int fb_device_create(struct fb_info *fb_info); 10 + void fb_device_destroy(struct fb_info *fb_info); 11 + 12 + #endif
+4 -17
drivers/video/fbdev/core/fbmem.c
··· 40 40 #include <video/nomodeset.h> 41 41 #include <video/vga.h> 42 42 43 + #include "fb_internal.h" 44 + 43 45 /* 44 46 * Frame buffer device initialization and setup routines 45 47 */ ··· 1449 1447 mutex_init(&fb_info->lock); 1450 1448 mutex_init(&fb_info->mm_lock); 1451 1449 1452 - fb_info->dev = device_create(fb_class, fb_info->device, 1453 - MKDEV(FB_MAJOR, i), NULL, "fb%d", i); 1454 - if (IS_ERR(fb_info->dev)) { 1455 - /* Not fatal */ 1456 - printk(KERN_WARNING "Unable to create device for framebuffer %d; errno = %ld\n", i, PTR_ERR(fb_info->dev)); 1457 - fb_info->dev = NULL; 1458 - } else 1459 - fb_init_device(fb_info); 1450 + fb_device_create(fb_info); 1460 1451 1461 1452 if (fb_info->pixmap.addr == NULL) { 1462 1453 fb_info->pixmap.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL); ··· 1510 1515 if (WARN_ON(i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)) 1511 1516 return; 1512 1517 1513 - if (!fb_info->dev) 1514 - return; 1515 - 1516 - device_destroy(fb_class, MKDEV(FB_MAJOR, i)); 1517 - 1518 + fb_device_destroy(fb_info); 1518 1519 pm_vt_switch_unregister(fb_info->device); 1519 - 1520 1520 unbind_console(fb_info); 1521 - 1522 - fb_info->dev = NULL; 1523 1521 } 1524 1522 1525 1523 static void do_unregister_framebuffer(struct fb_info *fb_info) ··· 1527 1539 fb_destroy_modelist(&fb_info->modelist); 1528 1540 registered_fb[fb_info->node] = NULL; 1529 1541 num_registered_fb--; 1530 - fb_cleanup_device(fb_info); 1531 1542 #ifdef CONFIG_GUMSTIX_AM200EPD 1532 1543 { 1533 1544 struct fb_event event;
+36 -2
drivers/video/fbdev/core/fbsysfs.c
··· 8 8 #include <linux/console.h> 9 9 #include <linux/fb.h> 10 10 #include <linux/fbcon.h> 11 + #include <linux/major.h> 12 + 13 + #include "fb_internal.h" 11 14 12 15 #define FB_SYSFS_FLAG_ATTR 1 13 16 ··· 438 435 #endif 439 436 }; 440 437 441 - int fb_init_device(struct fb_info *fb_info) 438 + static int fb_init_device(struct fb_info *fb_info) 442 439 { 443 440 int i, error = 0; 444 441 ··· 462 459 return 0; 463 460 } 464 461 465 - void fb_cleanup_device(struct fb_info *fb_info) 462 + static void fb_cleanup_device(struct fb_info *fb_info) 466 463 { 467 464 unsigned int i; 468 465 ··· 472 469 473 470 fb_info->class_flag &= ~FB_SYSFS_FLAG_ATTR; 474 471 } 472 + } 473 + 474 + int fb_device_create(struct fb_info *fb_info) 475 + { 476 + int node = fb_info->node; 477 + dev_t devt = MKDEV(FB_MAJOR, node); 478 + int ret; 479 + 480 + fb_info->dev = device_create(fb_class, fb_info->device, devt, NULL, "fb%d", node); 481 + if (IS_ERR(fb_info->dev)) { 482 + /* Not fatal */ 483 + ret = PTR_ERR(fb_info->dev); 484 + pr_warn("Unable to create device for framebuffer %d; error %d\n", node, ret); 485 + fb_info->dev = NULL; 486 + } else { 487 + fb_init_device(fb_info); 488 + } 489 + 490 + return 0; 491 + } 492 + 493 + void fb_device_destroy(struct fb_info *fb_info) 494 + { 495 + dev_t devt = MKDEV(FB_MAJOR, fb_info->node); 496 + 497 + if (!fb_info->dev) 498 + return; 499 + 500 + fb_cleanup_device(fb_info); 501 + device_destroy(fb_class, devt); 502 + fb_info->dev = NULL; 475 503 }
-3
include/linux/fb.h
··· 735 735 #endif /* CONFIG_FB_FOREIGN_ENDIAN */ 736 736 } 737 737 738 - /* drivers/video/fbsysfs.c */ 739 738 extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev); 740 739 extern void framebuffer_release(struct fb_info *info); 741 - extern int fb_init_device(struct fb_info *fb_info); 742 - extern void fb_cleanup_device(struct fb_info *head); 743 740 extern void fb_bl_default_curve(struct fb_info *fb_info, u8 off, u8 min, u8 max); 744 741 745 742 /* drivers/video/fbmon.c */