aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/char
diff options
context:
space:
mode:
authorPeter Oberparleiter <peter.oberparleiter@de.ibm.com>2008-07-14 03:59:07 -0400
committerHeiko Carstens <heiko.carstens@de.ibm.com>2008-07-14 04:02:13 -0400
commitad211790c040fae3459e9c4c8cbd681ae126d2b8 (patch)
tree2f9cb8e384ce571d9a34eee45886177025ba0807 /drivers/s390/char
parent773922e1dab93a62e60cfb34afadb0f66d5f12e9 (diff)
[S390] sclp: simplify vt220 cleanup logic
Fix a number of sclp_vt220 cleanup problems: * fix list_empty check after list_del() * mark init-only flag as __initdata * remove implicit dependency between slab_available() and num_pages * straighten multiple init handling (use init count) Signed-off-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Diffstat (limited to 'drivers/s390/char')
-rw-r--r--drivers/s390/char/sclp_vt220.c55
1 files changed, 28 insertions, 27 deletions
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index 3e577f655b18..baea4d548523 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -82,8 +82,8 @@ static struct sclp_vt220_request *sclp_vt220_current_request;
82/* Number of characters in current request buffer */ 82/* Number of characters in current request buffer */
83static int sclp_vt220_buffered_chars; 83static int sclp_vt220_buffered_chars;
84 84
85/* Flag indicating whether this driver has already been initialized */ 85/* Counter controlling core driver initialization. */
86static int sclp_vt220_initialized = 0; 86static int __initdata sclp_vt220_init_count;
87 87
88/* Flag indicating that sclp_vt220_current_request should really 88/* Flag indicating that sclp_vt220_current_request should really
89 * have been already queued but wasn't because the SCLP was processing 89 * have been already queued but wasn't because the SCLP was processing
@@ -609,10 +609,8 @@ sclp_vt220_flush_buffer(struct tty_struct *tty)
609 sclp_vt220_emit_current(); 609 sclp_vt220_emit_current();
610} 610}
611 611
612/* 612/* Release allocated pages. */
613 * Initialize all relevant components and register driver with system. 613static void __init __sclp_vt220_free_pages(void)
614 */
615static void __init __sclp_vt220_cleanup(void)
616{ 614{
617 struct list_head *page, *p; 615 struct list_head *page, *p;
618 616
@@ -623,21 +621,30 @@ static void __init __sclp_vt220_cleanup(void)
623 else 621 else
624 free_bootmem((unsigned long) page, PAGE_SIZE); 622 free_bootmem((unsigned long) page, PAGE_SIZE);
625 } 623 }
626 if (!list_empty(&sclp_vt220_register.list))
627 sclp_unregister(&sclp_vt220_register);
628 sclp_vt220_initialized = 0;
629} 624}
630 625
631static int __init __sclp_vt220_init(void) 626/* Release memory and unregister from sclp core. Controlled by init counting -
627 * only the last invoker will actually perform these actions. */
628static void __init __sclp_vt220_cleanup(void)
629{
630 sclp_vt220_init_count--;
631 if (sclp_vt220_init_count != 0)
632 return;
633 sclp_unregister(&sclp_vt220_register);
634 __sclp_vt220_free_pages();
635}
636
637/* Allocate buffer pages and register with sclp core. Controlled by init
638 * counting - only the first invoker will actually perform these actions. */
639static int __init __sclp_vt220_init(int num_pages)
632{ 640{
633 void *page; 641 void *page;
634 int i; 642 int i;
635 int num_pages;
636 int rc; 643 int rc;
637 644
638 if (sclp_vt220_initialized) 645 sclp_vt220_init_count++;
646 if (sclp_vt220_init_count != 1)
639 return 0; 647 return 0;
640 sclp_vt220_initialized = 1;
641 spin_lock_init(&sclp_vt220_lock); 648 spin_lock_init(&sclp_vt220_lock);
642 INIT_LIST_HEAD(&sclp_vt220_empty); 649 INIT_LIST_HEAD(&sclp_vt220_empty);
643 INIT_LIST_HEAD(&sclp_vt220_outqueue); 650 INIT_LIST_HEAD(&sclp_vt220_outqueue);
@@ -649,24 +656,22 @@ static int __init __sclp_vt220_init(void)
649 sclp_vt220_flush_later = 0; 656 sclp_vt220_flush_later = 0;
650 657
651 /* Allocate pages for output buffering */ 658 /* Allocate pages for output buffering */
652 num_pages = slab_is_available() ? MAX_KMEM_PAGES : MAX_CONSOLE_PAGES;
653 for (i = 0; i < num_pages; i++) { 659 for (i = 0; i < num_pages; i++) {
654 if (slab_is_available()) 660 if (slab_is_available())
655 page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); 661 page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
656 else 662 else
657 page = alloc_bootmem_low_pages(PAGE_SIZE); 663 page = alloc_bootmem_low_pages(PAGE_SIZE);
658 if (!page) { 664 if (!page) {
659 __sclp_vt220_cleanup(); 665 rc = -ENOMEM;
660 return -ENOMEM; 666 goto out;
661 } 667 }
662 list_add_tail((struct list_head *) page, &sclp_vt220_empty); 668 list_add_tail((struct list_head *) page, &sclp_vt220_empty);
663 } 669 }
664 rc = sclp_register(&sclp_vt220_register); 670 rc = sclp_register(&sclp_vt220_register);
671out:
665 if (rc) { 672 if (rc) {
666 printk(KERN_ERR SCLP_VT220_PRINT_HEADER 673 __sclp_vt220_free_pages();
667 "could not register vt220 - " 674 sclp_vt220_init_count--;
668 "sclp_register returned %d\n", rc);
669 __sclp_vt220_cleanup();
670 } 675 }
671 return rc; 676 return rc;
672} 677}
@@ -689,15 +694,13 @@ static int __init sclp_vt220_tty_init(void)
689{ 694{
690 struct tty_driver *driver; 695 struct tty_driver *driver;
691 int rc; 696 int rc;
692 int cleanup;
693 697
694 /* Note: we're not testing for CONSOLE_IS_SCLP here to preserve 698 /* Note: we're not testing for CONSOLE_IS_SCLP here to preserve
695 * symmetry between VM and LPAR systems regarding ttyS1. */ 699 * symmetry between VM and LPAR systems regarding ttyS1. */
696 driver = alloc_tty_driver(1); 700 driver = alloc_tty_driver(1);
697 if (!driver) 701 if (!driver)
698 return -ENOMEM; 702 return -ENOMEM;
699 cleanup = !sclp_vt220_initialized; 703 rc = __sclp_vt220_init(MAX_KMEM_PAGES);
700 rc = __sclp_vt220_init();
701 if (rc) 704 if (rc)
702 goto out_driver; 705 goto out_driver;
703 706
@@ -723,8 +726,7 @@ static int __init sclp_vt220_tty_init(void)
723 return 0; 726 return 0;
724 727
725out_init: 728out_init:
726 if (cleanup) 729 __sclp_vt220_cleanup();
727 __sclp_vt220_cleanup();
728out_driver: 730out_driver:
729 put_tty_driver(driver); 731 put_tty_driver(driver);
730 return rc; 732 return rc;
@@ -773,10 +775,9 @@ sclp_vt220_con_init(void)
773{ 775{
774 int rc; 776 int rc;
775 777
776 INIT_LIST_HEAD(&sclp_vt220_register.list);
777 if (!CONSOLE_IS_SCLP) 778 if (!CONSOLE_IS_SCLP)
778 return 0; 779 return 0;
779 rc = __sclp_vt220_init(); 780 rc = __sclp_vt220_init(MAX_CONSOLE_PAGES);
780 if (rc) 781 if (rc)
781 return rc; 782 return rc;
782 /* Attach linux console */ 783 /* Attach linux console */