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

fbdev: Add fb_append_extra_logo()

Add fb_append_extra_logo(), to append extra lines of logos below the standard
Linux logo.

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
Acked-By: James Simmons <jsimmons@infradead.org>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Geert Uytterhoeven and committed by
Linus Torvalds
9900abfb 90da63e5

+155 -69
+143 -69
drivers/video/fbmem.c
··· 404 404 } 405 405 } 406 406 407 - int fb_prepare_logo(struct fb_info *info, int rotate) 408 - { 409 - int depth = fb_get_color_depth(&info->var, &info->fix); 410 - int yres; 411 - 412 - memset(&fb_logo, 0, sizeof(struct logo_data)); 413 - 414 - if (info->flags & FBINFO_MISC_TILEBLITTING || 415 - info->flags & FBINFO_MODULE) 416 - return 0; 417 - 418 - if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) { 419 - depth = info->var.blue.length; 420 - if (info->var.red.length < depth) 421 - depth = info->var.red.length; 422 - if (info->var.green.length < depth) 423 - depth = info->var.green.length; 424 - } 425 - 426 - if (info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR && depth > 4) { 427 - /* assume console colormap */ 428 - depth = 4; 429 - } 430 - 431 - if (depth >= 8) { 432 - switch (info->fix.visual) { 433 - case FB_VISUAL_TRUECOLOR: 434 - fb_logo.needs_truepalette = 1; 435 - break; 436 - case FB_VISUAL_DIRECTCOLOR: 437 - fb_logo.needs_directpalette = 1; 438 - fb_logo.needs_cmapreset = 1; 439 - break; 440 - case FB_VISUAL_PSEUDOCOLOR: 441 - fb_logo.needs_cmapreset = 1; 442 - break; 443 - } 444 - } 445 - 446 - /* Return if no suitable logo was found */ 447 - fb_logo.logo = fb_find_logo(depth); 448 - 449 - if (!fb_logo.logo) { 450 - return 0; 451 - } 452 - 453 - if (rotate == FB_ROTATE_UR || rotate == FB_ROTATE_UD) 454 - yres = info->var.yres; 455 - else 456 - yres = info->var.xres; 457 - 458 - if (fb_logo.logo->height > yres) { 459 - fb_logo.logo = NULL; 460 - return 0; 461 - } 462 - 463 - /* What depth we asked for might be different from what we get */ 464 - if (fb_logo.logo->type == LINUX_LOGO_CLUT224) 465 - fb_logo.depth = 8; 466 - else if (fb_logo.logo->type == LINUX_LOGO_VGA16) 467 - fb_logo.depth = 4; 468 - else 469 - fb_logo.depth = 1; 470 - return fb_logo.logo->height; 471 - } 472 - 473 407 static int fb_show_logo_line(struct fb_info *info, int rotate, 474 408 const struct linux_logo *logo, int y, 475 409 unsigned int n) ··· 423 489 if (fb_logo.needs_cmapreset) 424 490 fb_set_logocmap(info, logo); 425 491 426 - if (fb_logo.needs_truepalette || 492 + if (fb_logo.needs_truepalette || 427 493 fb_logo.needs_directpalette) { 428 494 palette = kmalloc(256 * 4, GFP_KERNEL); 429 495 if (palette == NULL) ··· 472 538 return logo->height; 473 539 } 474 540 541 + 542 + #ifdef CONFIG_FB_LOGO_EXTRA 543 + 544 + #define FB_LOGO_EX_NUM_MAX 10 545 + static struct logo_data_extra { 546 + const struct linux_logo *logo; 547 + unsigned int n; 548 + } fb_logo_ex[FB_LOGO_EX_NUM_MAX]; 549 + static unsigned int fb_logo_ex_num; 550 + 551 + void fb_append_extra_logo(const struct linux_logo *logo, unsigned int n) 552 + { 553 + if (!n || fb_logo_ex_num == FB_LOGO_EX_NUM_MAX) 554 + return; 555 + 556 + fb_logo_ex[fb_logo_ex_num].logo = logo; 557 + fb_logo_ex[fb_logo_ex_num].n = n; 558 + fb_logo_ex_num++; 559 + } 560 + 561 + static int fb_prepare_extra_logos(struct fb_info *info, unsigned int height, 562 + unsigned int yres) 563 + { 564 + unsigned int i; 565 + 566 + /* FIXME: logo_ex supports only truecolor fb. */ 567 + if (info->fix.visual != FB_VISUAL_TRUECOLOR) 568 + fb_logo_ex_num = 0; 569 + 570 + for (i = 0; i < fb_logo_ex_num; i++) { 571 + height += fb_logo_ex[i].logo->height; 572 + if (height > yres) { 573 + height -= fb_logo_ex[i].logo->height; 574 + fb_logo_ex_num = i; 575 + break; 576 + } 577 + } 578 + return height; 579 + } 580 + 581 + static int fb_show_extra_logos(struct fb_info *info, int y, int rotate) 582 + { 583 + unsigned int i; 584 + 585 + for (i = 0; i < fb_logo_ex_num; i++) 586 + y += fb_show_logo_line(info, rotate, 587 + fb_logo_ex[i].logo, y, fb_logo_ex[i].n); 588 + 589 + return y; 590 + } 591 + 592 + #else /* !CONFIG_FB_LOGO_EXTRA */ 593 + 594 + static inline int fb_prepare_extra_logos(struct fb_info *info, 595 + unsigned int height, 596 + unsigned int yres) 597 + { 598 + return height; 599 + } 600 + 601 + static inline int fb_show_extra_logos(struct fb_info *info, int y, int rotate) 602 + { 603 + return y; 604 + } 605 + 606 + #endif /* CONFIG_FB_LOGO_EXTRA */ 607 + 608 + 609 + int fb_prepare_logo(struct fb_info *info, int rotate) 610 + { 611 + int depth = fb_get_color_depth(&info->var, &info->fix); 612 + unsigned int yres; 613 + 614 + memset(&fb_logo, 0, sizeof(struct logo_data)); 615 + 616 + if (info->flags & FBINFO_MISC_TILEBLITTING || 617 + info->flags & FBINFO_MODULE) 618 + return 0; 619 + 620 + if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) { 621 + depth = info->var.blue.length; 622 + if (info->var.red.length < depth) 623 + depth = info->var.red.length; 624 + if (info->var.green.length < depth) 625 + depth = info->var.green.length; 626 + } 627 + 628 + if (info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR && depth > 4) { 629 + /* assume console colormap */ 630 + depth = 4; 631 + } 632 + 633 + if (depth >= 8) { 634 + switch (info->fix.visual) { 635 + case FB_VISUAL_TRUECOLOR: 636 + fb_logo.needs_truepalette = 1; 637 + break; 638 + case FB_VISUAL_DIRECTCOLOR: 639 + fb_logo.needs_directpalette = 1; 640 + fb_logo.needs_cmapreset = 1; 641 + break; 642 + case FB_VISUAL_PSEUDOCOLOR: 643 + fb_logo.needs_cmapreset = 1; 644 + break; 645 + } 646 + } 647 + 648 + /* Return if no suitable logo was found */ 649 + fb_logo.logo = fb_find_logo(depth); 650 + 651 + if (!fb_logo.logo) { 652 + return 0; 653 + } 654 + 655 + if (rotate == FB_ROTATE_UR || rotate == FB_ROTATE_UD) 656 + yres = info->var.yres; 657 + else 658 + yres = info->var.xres; 659 + 660 + if (fb_logo.logo->height > yres) { 661 + fb_logo.logo = NULL; 662 + return 0; 663 + } 664 + 665 + /* What depth we asked for might be different from what we get */ 666 + if (fb_logo.logo->type == LINUX_LOGO_CLUT224) 667 + fb_logo.depth = 8; 668 + else if (fb_logo.logo->type == LINUX_LOGO_VGA16) 669 + fb_logo.depth = 4; 670 + else 671 + fb_logo.depth = 1; 672 + 673 + return fb_prepare_extra_logos(info, fb_logo.logo->height, yres); 674 + } 675 + 475 676 int fb_show_logo(struct fb_info *info, int rotate) 476 677 { 477 - return fb_show_logo_line(info, rotate, fb_logo.logo, 0, 478 - num_online_cpus()); 678 + int y; 679 + 680 + y = fb_show_logo_line(info, rotate, fb_logo.logo, 0, 681 + num_online_cpus()); 682 + y = fb_show_extra_logos(info, y, rotate); 683 + 684 + return y; 479 685 } 480 686 #else 481 687 int fb_prepare_logo(struct fb_info *info, int rotate) { return 0; }
+4
drivers/video/logo/Kconfig
··· 10 10 11 11 if LOGO 12 12 13 + config FB_LOGO_EXTRA 14 + bool 15 + depends on FB 16 + 13 17 config LOGO_LINUX_MONO 14 18 bool "Standard black and white Linux logo" 15 19 default y
+8
include/linux/linux_logo.h
··· 33 33 }; 34 34 35 35 extern const struct linux_logo *fb_find_logo(int depth); 36 + #ifdef CONFIG_FB_LOGO_EXTRA 37 + extern void fb_append_extra_logo(const struct linux_logo *logo, 38 + unsigned int n); 39 + #else 40 + static inline void fb_append_extra_logo(const struct linux_logo *logo, 41 + unsigned int n) 42 + {} 43 + #endif 36 44 37 45 #endif /* _LINUX_LINUX_LOGO_H */