aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-s390
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-05 13:11:02 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-05 13:11:02 -0500
commit39ce941ec15032c0efc3632b9f00a6b2365e1870 (patch)
tree9ac548adf0444b8a74e31c984e5a49766fc2c385 /include/asm-s390
parent3d412f60b71e588544e7b75861084f12aa1d7acd (diff)
parentc5411dba58c28736d25cffef65da1e01ed7d1423 (diff)
Merge branch 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6: [S390] dcss: Initialize workqueue before using it. [S390] Remove BUILD_BUG_ON() in vmem code. [S390] sclp_tty/sclp_vt220: Fix scheduling while atomic [S390] dasd: fix panic caused by alias device offline [S390] dasd: add ifcc handling [S390] latencytop s390 support. [S390] Implement ext2_find_next_bit. [S390] Cleanup & optimize bitops. [S390] Define GENERIC_LOCKBREAK. [S390] console: allow vt220 console to be the only console [S390] Fix couple of section mismatches. [S390] Fix smp_call_function_mask semantics. [S390] Fix linker script. [S390] DEBUG_PAGEALLOC support for s390. [S390] cio: Add shutdown callback for ccwgroup. [S390] cio: Update documentation. [S390] cio: Clean up chsc response code handling. [S390] cio: make sense id procedure work with partial hardware response
Diffstat (limited to 'include/asm-s390')
-rw-r--r--include/asm-s390/bitops.h558
-rw-r--r--include/asm-s390/cacheflush.h4
-rw-r--r--include/asm-s390/ccwgroup.h2
-rw-r--r--include/asm-s390/pgtable.h12
4 files changed, 275 insertions, 301 deletions
diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h
index dba6fecad0be..882db054110c 100644
--- a/include/asm-s390/bitops.h
+++ b/include/asm-s390/bitops.h
@@ -440,242 +440,256 @@ __constant_test_bit(unsigned long nr, const volatile unsigned long *addr) {
440 __test_bit((nr),(addr)) ) 440 __test_bit((nr),(addr)) )
441 441
442/* 442/*
443 * ffz = Find First Zero in word. Undefined if no zero exists, 443 * Optimized find bit helper functions.
444 * so code should check against ~0UL first..
445 */ 444 */
446static inline unsigned long ffz(unsigned long word) 445
446/**
447 * __ffz_word_loop - find byte offset of first long != -1UL
448 * @addr: pointer to array of unsigned long
449 * @size: size of the array in bits
450 */
451static inline unsigned long __ffz_word_loop(const unsigned long *addr,
452 unsigned long size)
447{ 453{
448 unsigned long bit = 0; 454 typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype;
455 unsigned long bytes = 0;
449 456
457 asm volatile(
458#ifndef __s390x__
459 " ahi %1,31\n"
460 " srl %1,5\n"
461 "0: c %2,0(%0,%3)\n"
462 " jne 1f\n"
463 " la %0,4(%0)\n"
464 " brct %1,0b\n"
465 "1:\n"
466#else
467 " aghi %1,63\n"
468 " srlg %1,%1,6\n"
469 "0: cg %2,0(%0,%3)\n"
470 " jne 1f\n"
471 " la %0,8(%0)\n"
472 " brct %1,0b\n"
473 "1:\n"
474#endif
475 : "+a" (bytes), "+d" (size)
476 : "d" (-1UL), "a" (addr), "m" (*(addrtype *) addr)
477 : "cc" );
478 return bytes;
479}
480
481/**
482 * __ffs_word_loop - find byte offset of first long != 0UL
483 * @addr: pointer to array of unsigned long
484 * @size: size of the array in bits
485 */
486static inline unsigned long __ffs_word_loop(const unsigned long *addr,
487 unsigned long size)
488{
489 typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype;
490 unsigned long bytes = 0;
491
492 asm volatile(
493#ifndef __s390x__
494 " ahi %1,31\n"
495 " srl %1,5\n"
496 "0: c %2,0(%0,%3)\n"
497 " jne 1f\n"
498 " la %0,4(%0)\n"
499 " brct %1,0b\n"
500 "1:\n"
501#else
502 " aghi %1,63\n"
503 " srlg %1,%1,6\n"
504 "0: cg %2,0(%0,%3)\n"
505 " jne 1f\n"
506 " la %0,8(%0)\n"
507 " brct %1,0b\n"
508 "1:\n"
509#endif
510 : "+a" (bytes), "+a" (size)
511 : "d" (0UL), "a" (addr), "m" (*(addrtype *) addr)
512 : "cc" );
513 return bytes;
514}
515
516/**
517 * __ffz_word - add number of the first unset bit
518 * @nr: base value the bit number is added to
519 * @word: the word that is searched for unset bits
520 */
521static inline unsigned long __ffz_word(unsigned long nr, unsigned long word)
522{
450#ifdef __s390x__ 523#ifdef __s390x__
451 if (likely((word & 0xffffffff) == 0xffffffff)) { 524 if (likely((word & 0xffffffff) == 0xffffffff)) {
452 word >>= 32; 525 word >>= 32;
453 bit += 32; 526 nr += 32;
454 } 527 }
455#endif 528#endif
456 if (likely((word & 0xffff) == 0xffff)) { 529 if (likely((word & 0xffff) == 0xffff)) {
457 word >>= 16; 530 word >>= 16;
458 bit += 16; 531 nr += 16;
459 } 532 }
460 if (likely((word & 0xff) == 0xff)) { 533 if (likely((word & 0xff) == 0xff)) {
461 word >>= 8; 534 word >>= 8;
462 bit += 8; 535 nr += 8;
463 } 536 }
464 return bit + _zb_findmap[word & 0xff]; 537 return nr + _zb_findmap[(unsigned char) word];
465} 538}
466 539
467/* 540/**
468 * __ffs = find first bit in word. Undefined if no bit exists, 541 * __ffs_word - add number of the first set bit
469 * so code should check against 0UL first.. 542 * @nr: base value the bit number is added to
543 * @word: the word that is searched for set bits
470 */ 544 */
471static inline unsigned long __ffs (unsigned long word) 545static inline unsigned long __ffs_word(unsigned long nr, unsigned long word)
472{ 546{
473 unsigned long bit = 0;
474
475#ifdef __s390x__ 547#ifdef __s390x__
476 if (likely((word & 0xffffffff) == 0)) { 548 if (likely((word & 0xffffffff) == 0)) {
477 word >>= 32; 549 word >>= 32;
478 bit += 32; 550 nr += 32;
479 } 551 }
480#endif 552#endif
481 if (likely((word & 0xffff) == 0)) { 553 if (likely((word & 0xffff) == 0)) {
482 word >>= 16; 554 word >>= 16;
483 bit += 16; 555 nr += 16;
484 } 556 }
485 if (likely((word & 0xff) == 0)) { 557 if (likely((word & 0xff) == 0)) {
486 word >>= 8; 558 word >>= 8;
487 bit += 8; 559 nr += 8;
488 } 560 }
489 return bit + _sb_findmap[word & 0xff]; 561 return nr + _sb_findmap[(unsigned char) word];
490} 562}
491 563
492/*
493 * Find-bit routines..
494 */
495 564
496#ifndef __s390x__ 565/**
566 * __load_ulong_be - load big endian unsigned long
567 * @p: pointer to array of unsigned long
568 * @offset: byte offset of source value in the array
569 */
570static inline unsigned long __load_ulong_be(const unsigned long *p,
571 unsigned long offset)
572{
573 p = (unsigned long *)((unsigned long) p + offset);
574 return *p;
575}
497 576
498static inline int 577/**
499find_first_zero_bit(const unsigned long * addr, unsigned long size) 578 * __load_ulong_le - load little endian unsigned long
579 * @p: pointer to array of unsigned long
580 * @offset: byte offset of source value in the array
581 */
582static inline unsigned long __load_ulong_le(const unsigned long *p,
583 unsigned long offset)
500{ 584{
501 typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; 585 unsigned long word;
502 unsigned long cmp, count;
503 unsigned int res;
504 586
505 if (!size) 587 p = (unsigned long *)((unsigned long) p + offset);
506 return 0; 588#ifndef __s390x__
507 asm volatile( 589 asm volatile(
508 " lhi %1,-1\n" 590 " ic %0,0(%1)\n"
509 " lr %2,%3\n" 591 " icm %0,2,1(%1)\n"
510 " slr %0,%0\n" 592 " icm %0,4,2(%1)\n"
511 " ahi %2,31\n" 593 " icm %0,8,3(%1)"
512 " srl %2,5\n" 594 : "=&d" (word) : "a" (p), "m" (*p) : "cc");
513 "0: c %1,0(%0,%4)\n" 595#else
514 " jne 1f\n" 596 asm volatile(
515 " la %0,4(%0)\n" 597 " lrvg %0,%1"
516 " brct %2,0b\n" 598 : "=d" (word) : "m" (*p) );
517 " lr %0,%3\n" 599#endif
518 " j 4f\n" 600 return word;
519 "1: l %2,0(%0,%4)\n"
520 " sll %0,3\n"
521 " lhi %1,0xff\n"
522 " tml %2,0xffff\n"
523 " jno 2f\n"
524 " ahi %0,16\n"
525 " srl %2,16\n"
526 "2: tml %2,0x00ff\n"
527 " jno 3f\n"
528 " ahi %0,8\n"
529 " srl %2,8\n"
530 "3: nr %2,%1\n"
531 " ic %2,0(%2,%5)\n"
532 " alr %0,%2\n"
533 "4:"
534 : "=&a" (res), "=&d" (cmp), "=&a" (count)
535 : "a" (size), "a" (addr), "a" (&_zb_findmap),
536 "m" (*(addrtype *) addr) : "cc");
537 return (res < size) ? res : size;
538} 601}
539 602
540static inline int 603/*
541find_first_bit(const unsigned long * addr, unsigned long size) 604 * The various find bit functions.
605 */
606
607/*
608 * ffz - find first zero in word.
609 * @word: The word to search
610 *
611 * Undefined if no zero exists, so code should check against ~0UL first.
612 */
613static inline unsigned long ffz(unsigned long word)
542{ 614{
543 typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; 615 return __ffz_word(0, word);
544 unsigned long cmp, count; 616}
545 unsigned int res;
546 617
547 if (!size) 618/**
548 return 0; 619 * __ffs - find first bit in word.
549 asm volatile( 620 * @word: The word to search
550 " slr %1,%1\n" 621 *
551 " lr %2,%3\n" 622 * Undefined if no bit exists, so code should check against 0 first.
552 " slr %0,%0\n" 623 */
553 " ahi %2,31\n" 624static inline unsigned long __ffs (unsigned long word)
554 " srl %2,5\n" 625{
555 "0: c %1,0(%0,%4)\n" 626 return __ffs_word(0, word);
556 " jne 1f\n"
557 " la %0,4(%0)\n"
558 " brct %2,0b\n"
559 " lr %0,%3\n"
560 " j 4f\n"
561 "1: l %2,0(%0,%4)\n"
562 " sll %0,3\n"
563 " lhi %1,0xff\n"
564 " tml %2,0xffff\n"
565 " jnz 2f\n"
566 " ahi %0,16\n"
567 " srl %2,16\n"
568 "2: tml %2,0x00ff\n"
569 " jnz 3f\n"
570 " ahi %0,8\n"
571 " srl %2,8\n"
572 "3: nr %2,%1\n"
573 " ic %2,0(%2,%5)\n"
574 " alr %0,%2\n"
575 "4:"
576 : "=&a" (res), "=&d" (cmp), "=&a" (count)
577 : "a" (size), "a" (addr), "a" (&_sb_findmap),
578 "m" (*(addrtype *) addr) : "cc");
579 return (res < size) ? res : size;
580} 627}
581 628
582#else /* __s390x__ */ 629/**
630 * ffs - find first bit set
631 * @x: the word to search
632 *
633 * This is defined the same way as
634 * the libc and compiler builtin ffs routines, therefore
635 * differs in spirit from the above ffz (man ffs).
636 */
637static inline int ffs(int x)
638{
639 if (!x)
640 return 0;
641 return __ffs_word(1, x);
642}
583 643
584static inline unsigned long 644/**
585find_first_zero_bit(const unsigned long * addr, unsigned long size) 645 * find_first_zero_bit - find the first zero bit in a memory region
646 * @addr: The address to start the search at
647 * @size: The maximum size to search
648 *
649 * Returns the bit-number of the first zero bit, not the number of the byte
650 * containing a bit.
651 */
652static inline unsigned long find_first_zero_bit(const unsigned long *addr,
653 unsigned long size)
586{ 654{
587 typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; 655 unsigned long bytes, bits;
588 unsigned long res, cmp, count;
589 656
590 if (!size) 657 if (!size)
591 return 0; 658 return 0;
592 asm volatile( 659 bytes = __ffz_word_loop(addr, size);
593 " lghi %1,-1\n" 660 bits = __ffz_word(bytes*8, __load_ulong_be(addr, bytes));
594 " lgr %2,%3\n" 661 return (bits < size) ? bits : size;
595 " slgr %0,%0\n" 662}
596 " aghi %2,63\n" 663
597 " srlg %2,%2,6\n" 664/**
598 "0: cg %1,0(%0,%4)\n" 665 * find_first_bit - find the first set bit in a memory region
599 " jne 1f\n" 666 * @addr: The address to start the search at
600 " la %0,8(%0)\n" 667 * @size: The maximum size to search
601 " brct %2,0b\n" 668 *
602 " lgr %0,%3\n" 669 * Returns the bit-number of the first set bit, not the number of the byte
603 " j 5f\n" 670 * containing a bit.
604 "1: lg %2,0(%0,%4)\n" 671 */
605 " sllg %0,%0,3\n" 672static inline unsigned long find_first_bit(const unsigned long * addr,
606 " clr %2,%1\n" 673 unsigned long size)
607 " jne 2f\n"
608 " aghi %0,32\n"
609 " srlg %2,%2,32\n"
610 "2: lghi %1,0xff\n"
611 " tmll %2,0xffff\n"
612 " jno 3f\n"
613 " aghi %0,16\n"
614 " srl %2,16\n"
615 "3: tmll %2,0x00ff\n"
616 " jno 4f\n"
617 " aghi %0,8\n"
618 " srl %2,8\n"
619 "4: ngr %2,%1\n"
620 " ic %2,0(%2,%5)\n"
621 " algr %0,%2\n"
622 "5:"
623 : "=&a" (res), "=&d" (cmp), "=&a" (count)
624 : "a" (size), "a" (addr), "a" (&_zb_findmap),
625 "m" (*(addrtype *) addr) : "cc");
626 return (res < size) ? res : size;
627}
628
629static inline unsigned long
630find_first_bit(const unsigned long * addr, unsigned long size)
631{ 674{
632 typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; 675 unsigned long bytes, bits;
633 unsigned long res, cmp, count;
634 676
635 if (!size) 677 if (!size)
636 return 0; 678 return 0;
637 asm volatile( 679 bytes = __ffs_word_loop(addr, size);
638 " slgr %1,%1\n" 680 bits = __ffs_word(bytes*8, __load_ulong_be(addr, bytes));
639 " lgr %2,%3\n" 681 return (bits < size) ? bits : size;
640 " slgr %0,%0\n"
641 " aghi %2,63\n"
642 " srlg %2,%2,6\n"
643 "0: cg %1,0(%0,%4)\n"
644 " jne 1f\n"
645 " aghi %0,8\n"
646 " brct %2,0b\n"
647 " lgr %0,%3\n"
648 " j 5f\n"
649 "1: lg %2,0(%0,%4)\n"
650 " sllg %0,%0,3\n"
651 " clr %2,%1\n"
652 " jne 2f\n"
653 " aghi %0,32\n"
654 " srlg %2,%2,32\n"
655 "2: lghi %1,0xff\n"
656 " tmll %2,0xffff\n"
657 " jnz 3f\n"
658 " aghi %0,16\n"
659 " srl %2,16\n"
660 "3: tmll %2,0x00ff\n"
661 " jnz 4f\n"
662 " aghi %0,8\n"
663 " srl %2,8\n"
664 "4: ngr %2,%1\n"
665 " ic %2,0(%2,%5)\n"
666 " algr %0,%2\n"
667 "5:"
668 : "=&a" (res), "=&d" (cmp), "=&a" (count)
669 : "a" (size), "a" (addr), "a" (&_sb_findmap),
670 "m" (*(addrtype *) addr) : "cc");
671 return (res < size) ? res : size;
672} 682}
673 683
674#endif /* __s390x__ */ 684/**
675 685 * find_next_zero_bit - find the first zero bit in a memory region
676static inline int 686 * @addr: The address to base the search on
677find_next_zero_bit (const unsigned long * addr, unsigned long size, 687 * @offset: The bitnumber to start searching at
678 unsigned long offset) 688 * @size: The maximum size to search
689 */
690static inline int find_next_zero_bit (const unsigned long * addr,
691 unsigned long size,
692 unsigned long offset)
679{ 693{
680 const unsigned long *p; 694 const unsigned long *p;
681 unsigned long bit, set; 695 unsigned long bit, set;
@@ -688,10 +702,10 @@ find_next_zero_bit (const unsigned long * addr, unsigned long size,
688 p = addr + offset / __BITOPS_WORDSIZE; 702 p = addr + offset / __BITOPS_WORDSIZE;
689 if (bit) { 703 if (bit) {
690 /* 704 /*
691 * s390 version of ffz returns __BITOPS_WORDSIZE 705 * __ffz_word returns __BITOPS_WORDSIZE
692 * if no zero bit is present in the word. 706 * if no zero bit is present in the word.
693 */ 707 */
694 set = ffz(*p >> bit) + bit; 708 set = __ffz_word(0, *p >> bit) + bit;
695 if (set >= size) 709 if (set >= size)
696 return size + offset; 710 return size + offset;
697 if (set < __BITOPS_WORDSIZE) 711 if (set < __BITOPS_WORDSIZE)
@@ -703,9 +717,15 @@ find_next_zero_bit (const unsigned long * addr, unsigned long size,
703 return offset + find_first_zero_bit(p, size); 717 return offset + find_first_zero_bit(p, size);
704} 718}
705 719
706static inline int 720/**
707find_next_bit (const unsigned long * addr, unsigned long size, 721 * find_next_bit - find the first set bit in a memory region
708 unsigned long offset) 722 * @addr: The address to base the search on
723 * @offset: The bitnumber to start searching at
724 * @size: The maximum size to search
725 */
726static inline int find_next_bit (const unsigned long * addr,
727 unsigned long size,
728 unsigned long offset)
709{ 729{
710 const unsigned long *p; 730 const unsigned long *p;
711 unsigned long bit, set; 731 unsigned long bit, set;
@@ -718,10 +738,10 @@ find_next_bit (const unsigned long * addr, unsigned long size,
718 p = addr + offset / __BITOPS_WORDSIZE; 738 p = addr + offset / __BITOPS_WORDSIZE;
719 if (bit) { 739 if (bit) {
720 /* 740 /*
721 * s390 version of __ffs returns __BITOPS_WORDSIZE 741 * __ffs_word returns __BITOPS_WORDSIZE
722 * if no one bit is present in the word. 742 * if no one bit is present in the word.
723 */ 743 */
724 set = __ffs(*p & (~0UL << bit)); 744 set = __ffs_word(0, *p & (~0UL << bit));
725 if (set >= size) 745 if (set >= size)
726 return size + offset; 746 return size + offset;
727 if (set < __BITOPS_WORDSIZE) 747 if (set < __BITOPS_WORDSIZE)
@@ -744,8 +764,6 @@ static inline int sched_find_first_bit(unsigned long *b)
744 return find_first_bit(b, 140); 764 return find_first_bit(b, 140);
745} 765}
746 766
747#include <asm-generic/bitops/ffs.h>
748
749#include <asm-generic/bitops/fls.h> 767#include <asm-generic/bitops/fls.h>
750#include <asm-generic/bitops/fls64.h> 768#include <asm-generic/bitops/fls64.h>
751 769
@@ -772,108 +790,23 @@ static inline int sched_find_first_bit(unsigned long *b)
772 test_and_clear_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr) 790 test_and_clear_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr)
773#define ext2_test_bit(nr, addr) \ 791#define ext2_test_bit(nr, addr) \
774 test_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr) 792 test_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr)
775#define ext2_find_next_bit(addr, size, off) \
776 generic_find_next_le_bit((unsigned long *)(addr), (size), (off))
777 793
778#ifndef __s390x__ 794static inline int ext2_find_first_zero_bit(void *vaddr, unsigned int size)
779
780static inline int
781ext2_find_first_zero_bit(void *vaddr, unsigned int size)
782{ 795{
783 typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; 796 unsigned long bytes, bits;
784 unsigned long cmp, count;
785 unsigned int res;
786 797
787 if (!size) 798 if (!size)
788 return 0; 799 return 0;
789 asm volatile( 800 bytes = __ffz_word_loop(vaddr, size);
790 " lhi %1,-1\n" 801 bits = __ffz_word(bytes*8, __load_ulong_le(vaddr, bytes));
791 " lr %2,%3\n" 802 return (bits < size) ? bits : size;
792 " ahi %2,31\n"
793 " srl %2,5\n"
794 " slr %0,%0\n"
795 "0: cl %1,0(%0,%4)\n"
796 " jne 1f\n"
797 " ahi %0,4\n"
798 " brct %2,0b\n"
799 " lr %0,%3\n"
800 " j 4f\n"
801 "1: l %2,0(%0,%4)\n"
802 " sll %0,3\n"
803 " ahi %0,24\n"
804 " lhi %1,0xff\n"
805 " tmh %2,0xffff\n"
806 " jo 2f\n"
807 " ahi %0,-16\n"
808 " srl %2,16\n"
809 "2: tml %2,0xff00\n"
810 " jo 3f\n"
811 " ahi %0,-8\n"
812 " srl %2,8\n"
813 "3: nr %2,%1\n"
814 " ic %2,0(%2,%5)\n"
815 " alr %0,%2\n"
816 "4:"
817 : "=&a" (res), "=&d" (cmp), "=&a" (count)
818 : "a" (size), "a" (vaddr), "a" (&_zb_findmap),
819 "m" (*(addrtype *) vaddr) : "cc");
820 return (res < size) ? res : size;
821} 803}
822 804
823#else /* __s390x__ */ 805static inline int ext2_find_next_zero_bit(void *vaddr, unsigned long size,
824 806 unsigned long offset)
825static inline unsigned long
826ext2_find_first_zero_bit(void *vaddr, unsigned long size)
827{
828 typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype;
829 unsigned long res, cmp, count;
830
831 if (!size)
832 return 0;
833 asm volatile(
834 " lghi %1,-1\n"
835 " lgr %2,%3\n"
836 " aghi %2,63\n"
837 " srlg %2,%2,6\n"
838 " slgr %0,%0\n"
839 "0: clg %1,0(%0,%4)\n"
840 " jne 1f\n"
841 " aghi %0,8\n"
842 " brct %2,0b\n"
843 " lgr %0,%3\n"
844 " j 5f\n"
845 "1: cl %1,0(%0,%4)\n"
846 " jne 2f\n"
847 " aghi %0,4\n"
848 "2: l %2,0(%0,%4)\n"
849 " sllg %0,%0,3\n"
850 " aghi %0,24\n"
851 " lghi %1,0xff\n"
852 " tmlh %2,0xffff\n"
853 " jo 3f\n"
854 " aghi %0,-16\n"
855 " srl %2,16\n"
856 "3: tmll %2,0xff00\n"
857 " jo 4f\n"
858 " aghi %0,-8\n"
859 " srl %2,8\n"
860 "4: ngr %2,%1\n"
861 " ic %2,0(%2,%5)\n"
862 " algr %0,%2\n"
863 "5:"
864 : "=&a" (res), "=&d" (cmp), "=&a" (count)
865 : "a" (size), "a" (vaddr), "a" (&_zb_findmap),
866 "m" (*(addrtype *) vaddr) : "cc");
867 return (res < size) ? res : size;
868}
869
870#endif /* __s390x__ */
871
872static inline int
873ext2_find_next_zero_bit(void *vaddr, unsigned long size, unsigned long offset)
874{ 807{
875 unsigned long *addr = vaddr, *p; 808 unsigned long *addr = vaddr, *p;
876 unsigned long word, bit, set; 809 unsigned long bit, set;
877 810
878 if (offset >= size) 811 if (offset >= size)
879 return size; 812 return size;
@@ -882,23 +815,11 @@ ext2_find_next_zero_bit(void *vaddr, unsigned long size, unsigned long offset)
882 size -= offset; 815 size -= offset;
883 p = addr + offset / __BITOPS_WORDSIZE; 816 p = addr + offset / __BITOPS_WORDSIZE;
884 if (bit) { 817 if (bit) {
885#ifndef __s390x__
886 asm volatile(
887 " ic %0,0(%1)\n"
888 " icm %0,2,1(%1)\n"
889 " icm %0,4,2(%1)\n"
890 " icm %0,8,3(%1)"
891 : "=&a" (word) : "a" (p), "m" (*p) : "cc");
892#else
893 asm volatile(
894 " lrvg %0,%1"
895 : "=a" (word) : "m" (*p) );
896#endif
897 /* 818 /*
898 * s390 version of ffz returns __BITOPS_WORDSIZE 819 * s390 version of ffz returns __BITOPS_WORDSIZE
899 * if no zero bit is present in the word. 820 * if no zero bit is present in the word.
900 */ 821 */
901 set = ffz(word >> bit) + bit; 822 set = ffz(__load_ulong_le(p, 0) >> bit) + bit;
902 if (set >= size) 823 if (set >= size)
903 return size + offset; 824 return size + offset;
904 if (set < __BITOPS_WORDSIZE) 825 if (set < __BITOPS_WORDSIZE)
@@ -910,6 +831,47 @@ ext2_find_next_zero_bit(void *vaddr, unsigned long size, unsigned long offset)
910 return offset + ext2_find_first_zero_bit(p, size); 831 return offset + ext2_find_first_zero_bit(p, size);
911} 832}
912 833
834static inline unsigned long ext2_find_first_bit(void *vaddr,
835 unsigned long size)
836{
837 unsigned long bytes, bits;
838
839 if (!size)
840 return 0;
841 bytes = __ffs_word_loop(vaddr, size);
842 bits = __ffs_word(bytes*8, __load_ulong_le(vaddr, bytes));
843 return (bits < size) ? bits : size;
844}
845
846static inline int ext2_find_next_bit(void *vaddr, unsigned long size,
847 unsigned long offset)
848{
849 unsigned long *addr = vaddr, *p;
850 unsigned long bit, set;
851
852 if (offset >= size)
853 return size;
854 bit = offset & (__BITOPS_WORDSIZE - 1);
855 offset -= bit;
856 size -= offset;
857 p = addr + offset / __BITOPS_WORDSIZE;
858 if (bit) {
859 /*
860 * s390 version of ffz returns __BITOPS_WORDSIZE
861 * if no zero bit is present in the word.
862 */
863 set = ffs(__load_ulong_le(p, 0) >> bit) + bit;
864 if (set >= size)
865 return size + offset;
866 if (set < __BITOPS_WORDSIZE)
867 return set + offset;
868 offset += __BITOPS_WORDSIZE;
869 size -= __BITOPS_WORDSIZE;
870 p++;
871 }
872 return offset + ext2_find_first_bit(p, size);
873}
874
913#include <asm-generic/bitops/minix.h> 875#include <asm-generic/bitops/minix.h>
914 876
915#endif /* __KERNEL__ */ 877#endif /* __KERNEL__ */
diff --git a/include/asm-s390/cacheflush.h b/include/asm-s390/cacheflush.h
index f7cade8083f3..49d5af916d01 100644
--- a/include/asm-s390/cacheflush.h
+++ b/include/asm-s390/cacheflush.h
@@ -24,4 +24,8 @@
24#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ 24#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
25 memcpy(dst, src, len) 25 memcpy(dst, src, len)
26 26
27#ifdef CONFIG_DEBUG_PAGEALLOC
28void kernel_map_pages(struct page *page, int numpages, int enable);
29#endif
30
27#endif /* _S390_CACHEFLUSH_H */ 31#endif /* _S390_CACHEFLUSH_H */
diff --git a/include/asm-s390/ccwgroup.h b/include/asm-s390/ccwgroup.h
index 7109c7cab87e..289053ef5e60 100644
--- a/include/asm-s390/ccwgroup.h
+++ b/include/asm-s390/ccwgroup.h
@@ -37,6 +37,7 @@ struct ccwgroup_device {
37 * @remove: function called on remove 37 * @remove: function called on remove
38 * @set_online: function called when device is set online 38 * @set_online: function called when device is set online
39 * @set_offline: function called when device is set offline 39 * @set_offline: function called when device is set offline
40 * @shutdown: function called when device is shut down
40 * @driver: embedded driver structure 41 * @driver: embedded driver structure
41 */ 42 */
42struct ccwgroup_driver { 43struct ccwgroup_driver {
@@ -49,6 +50,7 @@ struct ccwgroup_driver {
49 void (*remove) (struct ccwgroup_device *); 50 void (*remove) (struct ccwgroup_device *);
50 int (*set_online) (struct ccwgroup_device *); 51 int (*set_online) (struct ccwgroup_device *);
51 int (*set_offline) (struct ccwgroup_device *); 52 int (*set_offline) (struct ccwgroup_device *);
53 void (*shutdown)(struct ccwgroup_device *);
52 54
53 struct device_driver driver; 55 struct device_driver driver;
54}; 56};
diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h
index 79b9eab1a0c7..3f520754e71c 100644
--- a/include/asm-s390/pgtable.h
+++ b/include/asm-s390/pgtable.h
@@ -115,15 +115,21 @@ extern char empty_zero_page[PAGE_SIZE];
115#ifndef __s390x__ 115#ifndef __s390x__
116#define VMALLOC_START 0x78000000UL 116#define VMALLOC_START 0x78000000UL
117#define VMALLOC_END 0x7e000000UL 117#define VMALLOC_END 0x7e000000UL
118#define VMEM_MAP_MAX 0x80000000UL 118#define VMEM_MAP_END 0x80000000UL
119#else /* __s390x__ */ 119#else /* __s390x__ */
120#define VMALLOC_START 0x3e000000000UL 120#define VMALLOC_START 0x3e000000000UL
121#define VMALLOC_END 0x3e040000000UL 121#define VMALLOC_END 0x3e040000000UL
122#define VMEM_MAP_MAX 0x40000000000UL 122#define VMEM_MAP_END 0x40000000000UL
123#endif /* __s390x__ */ 123#endif /* __s390x__ */
124 124
125/*
126 * VMEM_MAX_PHYS is the highest physical address that can be added to the 1:1
127 * mapping. This needs to be calculated at compile time since the size of the
128 * VMEM_MAP is static but the size of struct page can change.
129 */
130#define VMEM_MAX_PHYS min(VMALLOC_START, ((VMEM_MAP_END - VMALLOC_END) / \
131 sizeof(struct page) * PAGE_SIZE) & ~((16 << 20) - 1))
125#define VMEM_MAP ((struct page *) VMALLOC_END) 132#define VMEM_MAP ((struct page *) VMALLOC_END)
126#define VMEM_MAP_SIZE ((VMALLOC_START / PAGE_SIZE) * sizeof(struct page))
127 133
128/* 134/*
129 * A 31 bit pagetable entry of S390 has following format: 135 * A 31 bit pagetable entry of S390 has following format: