From 24f287e412ae90de8d281543c8b1043b6ed6c019 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 15 Oct 2007 16:41:44 -0700 Subject: [SPARC64]: Implement atomic backoff. When the cpu count is high and contention hits an atomic object, the processors can synchronize such that some cpus continually get knocked out and cannot complete the atomic update. So implement an exponential backoff when SMP. Signed-off-by: David S. Miller diff --git a/arch/sparc64/lib/atomic.S b/arch/sparc64/lib/atomic.S index 9633750..70ac418 100644 --- a/arch/sparc64/lib/atomic.S +++ b/arch/sparc64/lib/atomic.S @@ -1,10 +1,10 @@ -/* $Id: atomic.S,v 1.4 2001/11/18 00:12:56 davem Exp $ - * atomic.S: These things are too big to do inline. +/* atomic.S: These things are too big to do inline. * - * Copyright (C) 1999 David S. Miller (davem@redhat.com) + * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net) */ #include +#include .text @@ -16,27 +16,31 @@ .globl atomic_add .type atomic_add,#function atomic_add: /* %o0 = increment, %o1 = atomic_ptr */ + BACKOFF_SETUP(%o2) 1: lduw [%o1], %g1 add %g1, %o0, %g7 cas [%o1], %g1, %g7 cmp %g1, %g7 - bne,pn %icc, 1b + bne,pn %icc, 2f nop retl nop +2: BACKOFF_SPIN(%o2, %o3, 1b) .size atomic_add, .-atomic_add .globl atomic_sub .type atomic_sub,#function atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */ + BACKOFF_SETUP(%o2) 1: lduw [%o1], %g1 sub %g1, %o0, %g7 cas [%o1], %g1, %g7 cmp %g1, %g7 - bne,pn %icc, 1b + bne,pn %icc, 2f nop retl nop +2: BACKOFF_SPIN(%o2, %o3, 1b) .size atomic_sub, .-atomic_sub /* On SMP we need to use memory barriers to ensure @@ -60,89 +64,101 @@ atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */ .globl atomic_add_ret .type atomic_add_ret,#function atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ + BACKOFF_SETUP(%o2) ATOMIC_PRE_BARRIER 1: lduw [%o1], %g1 add %g1, %o0, %g7 cas [%o1], %g1, %g7 cmp %g1, %g7 - bne,pn %icc, 1b + bne,pn %icc, 2f add %g7, %o0, %g7 sra %g7, 0, %o0 ATOMIC_POST_BARRIER retl nop +2: BACKOFF_SPIN(%o2, %o3, 1b) .size atomic_add_ret, .-atomic_add_ret .globl atomic_sub_ret .type atomic_sub_ret,#function atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ + BACKOFF_SETUP(%o2) ATOMIC_PRE_BARRIER 1: lduw [%o1], %g1 sub %g1, %o0, %g7 cas [%o1], %g1, %g7 cmp %g1, %g7 - bne,pn %icc, 1b + bne,pn %icc, 2f sub %g7, %o0, %g7 sra %g7, 0, %o0 ATOMIC_POST_BARRIER retl nop +2: BACKOFF_SPIN(%o2, %o3, 1b) .size atomic_sub_ret, .-atomic_sub_ret .globl atomic64_add .type atomic64_add,#function atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */ + BACKOFF_SETUP(%o2) 1: ldx [%o1], %g1 add %g1, %o0, %g7 casx [%o1], %g1, %g7 cmp %g1, %g7 - bne,pn %xcc, 1b + bne,pn %xcc, 2f nop retl nop +2: BACKOFF_SPIN(%o2, %o3, 1b) .size atomic64_add, .-atomic64_add .globl atomic64_sub .type atomic64_sub,#function atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */ + BACKOFF_SETUP(%o2) 1: ldx [%o1], %g1 sub %g1, %o0, %g7 casx [%o1], %g1, %g7 cmp %g1, %g7 - bne,pn %xcc, 1b + bne,pn %xcc, 2f nop retl nop +2: BACKOFF_SPIN(%o2, %o3, 1b) .size atomic64_sub, .-atomic64_sub .globl atomic64_add_ret .type atomic64_add_ret,#function atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ + BACKOFF_SETUP(%o2) ATOMIC_PRE_BARRIER 1: ldx [%o1], %g1 add %g1, %o0, %g7 casx [%o1], %g1, %g7 cmp %g1, %g7 - bne,pn %xcc, 1b + bne,pn %xcc, 2f add %g7, %o0, %g7 mov %g7, %o0 ATOMIC_POST_BARRIER retl nop +2: BACKOFF_SPIN(%o2, %o3, 1b) .size atomic64_add_ret, .-atomic64_add_ret .globl atomic64_sub_ret .type atomic64_sub_ret,#function atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ + BACKOFF_SETUP(%o2) ATOMIC_PRE_BARRIER 1: ldx [%o1], %g1 sub %g1, %o0, %g7 casx [%o1], %g1, %g7 cmp %g1, %g7 - bne,pn %xcc, 1b + bne,pn %xcc, 2f sub %g7, %o0, %g7 mov %g7, %o0 ATOMIC_POST_BARRIER retl nop +2: BACKOFF_SPIN(%o2, %o3, 1b) .size atomic64_sub_ret, .-atomic64_sub_ret diff --git a/arch/sparc64/lib/bitops.S b/arch/sparc64/lib/bitops.S index 892431a..6b015a6 100644 --- a/arch/sparc64/lib/bitops.S +++ b/arch/sparc64/lib/bitops.S @@ -1,10 +1,10 @@ -/* $Id: bitops.S,v 1.3 2001/11/18 00:12:56 davem Exp $ - * bitops.S: Sparc64 atomic bit operations. +/* bitops.S: Sparc64 atomic bit operations. * - * Copyright (C) 2000 David S. Miller (davem@redhat.com) + * Copyright (C) 2000, 2007 David S. Miller (davem@davemloft.net) */ #include +#include .text @@ -29,6 +29,7 @@ .globl test_and_set_bit .type test_and_set_bit,#function test_and_set_bit: /* %o0=nr, %o1=addr */ + BACKOFF_SETUP(%o3) BITOP_PRE_BARRIER srlx %o0, 6, %g1 mov 1, %o2 @@ -40,18 +41,20 @@ test_and_set_bit: /* %o0=nr, %o1=addr */ or %g7, %o2, %g1 casx [%o1], %g7, %g1 cmp %g7, %g1 - bne,pn %xcc, 1b + bne,pn %xcc, 2f and %g7, %o2, %g2 clr %o0 movrne %g2, 1, %o0 BITOP_POST_BARRIER retl nop +2: BACKOFF_SPIN(%o3, %o4, 1b) .size test_and_set_bit, .-test_and_set_bit .globl test_and_clear_bit .type test_and_clear_bit,#function test_and_clear_bit: /* %o0=nr, %o1=addr */ + BACKOFF_SETUP(%o3) BITOP_PRE_BARRIER srlx %o0, 6, %g1 mov 1, %o2 @@ -63,18 +66,20 @@ test_and_clear_bit: /* %o0=nr, %o1=addr */ andn %g7, %o2, %g1 casx [%o1], %g7, %g1 cmp %g7, %g1 - bne,pn %xcc, 1b + bne,pn %xcc, 2f and %g7, %o2, %g2 clr %o0 movrne %g2, 1, %o0 BITOP_POST_BARRIER retl nop +2: BACKOFF_SPIN(%o3, %o4, 1b) .size test_and_clear_bit, .-test_and_clear_bit .globl test_and_change_bit .type test_and_change_bit,#function test_and_change_bit: /* %o0=nr, %o1=addr */ + BACKOFF_SETUP(%o3) BITOP_PRE_BARRIER srlx %o0, 6, %g1 mov 1, %o2 @@ -86,18 +91,20 @@ test_and_change_bit: /* %o0=nr, %o1=addr */ xor %g7, %o2, %g1 casx [%o1], %g7, %g1 cmp %g7, %g1 - bne,pn %xcc, 1b + bne,pn %xcc, 2f and %g7, %o2, %g2 clr %o0 movrne %g2, 1, %o0 BITOP_POST_BARRIER retl nop +2: BACKOFF_SPIN(%o3, %o4, 1b) .size test_and_change_bit, .-test_and_change_bit .globl set_bit .type set_bit,#function set_bit: /* %o0=nr, %o1=addr */ + BACKOFF_SETUP(%o3) srlx %o0, 6, %g1 mov 1, %o2 sllx %g1, 3, %g3 @@ -108,15 +115,17 @@ set_bit: /* %o0=nr, %o1=addr */ or %g7, %o2, %g1 casx [%o1], %g7, %g1 cmp %g7, %g1 - bne,pn %xcc, 1b + bne,pn %xcc, 2f nop retl nop +2: BACKOFF_SPIN(%o3, %o4, 1b) .size set_bit, .-set_bit .globl clear_bit .type clear_bit,#function clear_bit: /* %o0=nr, %o1=addr */ + BACKOFF_SETUP(%o3) srlx %o0, 6, %g1 mov 1, %o2 sllx %g1, 3, %g3 @@ -127,15 +136,17 @@ clear_bit: /* %o0=nr, %o1=addr */ andn %g7, %o2, %g1 casx [%o1], %g7, %g1 cmp %g7, %g1 - bne,pn %xcc, 1b + bne,pn %xcc, 2f nop retl nop +2: BACKOFF_SPIN(%o3, %o4, 1b) .size clear_bit, .-clear_bit .globl change_bit .type change_bit,#function change_bit: /* %o0=nr, %o1=addr */ + BACKOFF_SETUP(%o3) srlx %o0, 6, %g1 mov 1, %o2 sllx %g1, 3, %g3 @@ -146,8 +157,9 @@ change_bit: /* %o0=nr, %o1=addr */ xor %g7, %o2, %g1 casx [%o1], %g7, %g1 cmp %g7, %g1 - bne,pn %xcc, 1b + bne,pn %xcc, 2f nop retl nop +2: BACKOFF_SPIN(%o3, %o4, 1b) .size change_bit, .-change_bit diff --git a/include/asm-sparc64/backoff.h b/include/asm-sparc64/backoff.h new file mode 100644 index 0000000..0e32f8b --- /dev/null +++ b/include/asm-sparc64/backoff.h @@ -0,0 +1,28 @@ +#ifndef _SPARC64_BACKOFF_H +#define _SPARC64_BACKOFF_H + +#define BACKOFF_LIMIT (4 * 1024) + +#ifdef CONFIG_SMP + +#define BACKOFF_SETUP(reg) \ + mov 1, reg + +#define BACKOFF_SPIN(reg, tmp, label) \ + mov reg, tmp; \ +88: brnz,pt tmp, 88b; \ + sub tmp, 1, tmp; \ + cmp reg, BACKOFF_LIMIT; \ + bg,pn %xcc, label; \ + nop; \ + ba,pt %xcc, label; \ + sllx reg, 1, reg; + +#else + +#define BACKOFF_SETUP(reg) +#define BACKOFF_SPIN(reg, tmp, label) + +#endif + +#endif /* _SPARC64_BACKOFF_H */ -- cgit v0.10.2 From 719023fb90009855c4515a16349fc6d0a2f93a74 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 15 Oct 2007 16:43:19 -0700 Subject: [SPARC64]: Fix boot failures due to bootmem. Do not use *alloc_bootmem_low*(), because ARCH_LOW_ADDRESS_LIMIT is 4GB and this results in boot failures if all of the physical memory in the machine is above 4GB. Signed-off-by: David S. Miller diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index f3922e5..2c3bea2 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -877,7 +877,7 @@ void __cpuinit sun4v_register_mondo_queues(int this_cpu) static void __init alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask) { unsigned long size = PAGE_ALIGN(qmask + 1); - void *p = __alloc_bootmem_low(size, size, 0); + void *p = __alloc_bootmem(size, size, 0); if (!p) { prom_printf("SUN4V: Error, cannot allocate mondo queue.\n"); prom_halt(); @@ -889,7 +889,7 @@ static void __init alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask) static void __init alloc_one_kbuf(unsigned long *pa_ptr, unsigned long qmask) { unsigned long size = PAGE_ALIGN(qmask + 1); - void *p = __alloc_bootmem_low(size, size, 0); + void *p = __alloc_bootmem(size, size, 0); if (!p) { prom_printf("SUN4V: Error, cannot allocate kbuf page.\n"); @@ -906,7 +906,7 @@ static void __init init_cpu_send_mondo_info(struct trap_per_cpu *tb) BUILD_BUG_ON((NR_CPUS * sizeof(u16)) > (PAGE_SIZE - 64)); - page = alloc_bootmem_low_pages(PAGE_SIZE); + page = alloc_bootmem_pages(PAGE_SIZE); if (!page) { prom_printf("SUN4V: Error, cannot allocate cpu mondo page.\n"); prom_halt(); @@ -953,7 +953,7 @@ void __init init_IRQ(void) kill_prom_timer(); size = sizeof(struct ino_bucket) * NUM_IVECS; - ivector_table = alloc_bootmem_low(size); + ivector_table = alloc_bootmem(size); if (!ivector_table) { prom_printf("Fatal error, cannot allocate ivector_table\n"); prom_halt(); -- cgit v0.10.2 From 4209ab098c61b1a9684bb4d3fc287352fc2438c3 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 15 Oct 2007 20:45:32 -0700 Subject: [SPARC64]: Check of_get_property() return in pci_determine_mem_io_space(). If the PCI controller lacks the 'ranges' property nothing is going to work. Noticed by Al Viro. Signed-off-by: David S. Miller diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c index c76bfbb..923e0bc 100644 --- a/arch/sparc64/kernel/pci_common.c +++ b/arch/sparc64/kernel/pci_common.c @@ -396,6 +396,13 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm) saw_mem = saw_io = 0; pbm_ranges = of_get_property(pbm->prom_node, "ranges", &i); + if (!pbm_ranges) { + prom_printf("PCI: Fatal error, missing PBM ranges property " + " for %s\n", + pbm->name); + prom_halt(); + } + num_pbm_ranges = i / sizeof(*pbm_ranges); for (i = 0; i < num_pbm_ranges; i++) { -- cgit v0.10.2 From 6050afbbb01d1f5a867f7839be6460bac801f5bc Mon Sep 17 00:00:00 2001 From: David Miller Date: Wed, 17 Oct 2007 19:38:10 -0700 Subject: [SPARC]: Support for new termios. [akpm@linux-foundation.org: coding-style tweaks] Signed-off-by: David Miller Signed-off-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: David S. Miller diff --git a/include/asm-sparc/ioctls.h b/include/asm-sparc/ioctls.h index bdf77b0..058c206 100644 --- a/include/asm-sparc/ioctls.h +++ b/include/asm-sparc/ioctls.h @@ -15,6 +15,10 @@ #define TCSETS _IOW('T', 9, struct termios) #define TCSETSW _IOW('T', 10, struct termios) #define TCSETSF _IOW('T', 11, struct termios) +#define TCGETS2 _IOR('T', 12, struct termios2) +#define TCSETS2 _IOW('T', 13, struct termios2) +#define TCSETSW2 _IOW('T', 14, struct termios2) +#define TCSETSF2 _IOW('T', 15, struct termios2) /* Note that all the ioctls that are not available in Linux have a * double underscore on the front to: a) avoid some programs to diff --git a/include/asm-sparc/termbits.h b/include/asm-sparc/termbits.h index 5eb00a1..90cf221 100644 --- a/include/asm-sparc/termbits.h +++ b/include/asm-sparc/termbits.h @@ -31,6 +31,18 @@ struct termios { #endif }; +struct termios2 { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + cc_t _x_cc[2]; /* padding to match ktermios */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + struct ktermios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ @@ -160,6 +172,7 @@ struct ktermios { #define CLOCAL 0x00000800 #define CBAUDEX 0x00001000 /* We'll never see these speeds with the Zilogs, but for completeness... */ +#define BOTHER 0x00001000 #define B57600 0x00001001 #define B115200 0x00001002 #define B230400 0x00001003 @@ -189,6 +202,8 @@ struct ktermios { #define CMSPAR 0x40000000 /* mark or space (stick) parity */ #define CRTSCTS 0x80000000 /* flow control */ +#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ + /* c_lflag bits */ #define ISIG 0x00000001 #define ICANON 0x00000002 diff --git a/include/asm-sparc/termios.h b/include/asm-sparc/termios.h index d767f20..4333232 100644 --- a/include/asm-sparc/termios.h +++ b/include/asm-sparc/termios.h @@ -108,13 +108,55 @@ struct winsize { #define user_termios_to_kernel_termios(k, u) \ ({ \ + int err; \ + err = get_user((k)->c_iflag, &(u)->c_iflag); \ + err |= get_user((k)->c_oflag, &(u)->c_oflag); \ + err |= get_user((k)->c_cflag, &(u)->c_cflag); \ + err |= get_user((k)->c_lflag, &(u)->c_lflag); \ + err |= get_user((k)->c_line, &(u)->c_line); \ + err |= copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \ + if ((k)->c_lflag & ICANON) { \ + err |= get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ + err |= get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ + } else { \ + err |= get_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ + err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ + } \ + err |= get_user((k)->c_ispeed, &(u)->c_ispeed); \ + err |= get_user((k)->c_ospeed, &(u)->c_ospeed); \ + err; \ +}) + +#define kernel_termios_to_user_termios(u, k) \ +({ \ + int err; \ + err = put_user((k)->c_iflag, &(u)->c_iflag); \ + err |= put_user((k)->c_oflag, &(u)->c_oflag); \ + err |= put_user((k)->c_cflag, &(u)->c_cflag); \ + err |= put_user((k)->c_lflag, &(u)->c_lflag); \ + err |= put_user((k)->c_line, &(u)->c_line); \ + err |= copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \ + if (!((k)->c_lflag & ICANON)) { \ + err |= put_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ + err |= put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ + } else { \ + err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ + err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ + } \ + err |= put_user((k)->c_ispeed, &(u)->c_ispeed); \ + err |= put_user((k)->c_ospeed, &(u)->c_ospeed); \ + err; \ +}) + +#define user_termios_to_kernel_termios_1(k, u) \ +({ \ get_user((k)->c_iflag, &(u)->c_iflag); \ get_user((k)->c_oflag, &(u)->c_oflag); \ get_user((k)->c_cflag, &(u)->c_cflag); \ get_user((k)->c_lflag, &(u)->c_lflag); \ get_user((k)->c_line, &(u)->c_line); \ copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \ - if((k)->c_lflag & ICANON) { \ + if ((k)->c_lflag & ICANON) { \ get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ } else { \ @@ -124,7 +166,7 @@ struct winsize { 0; \ }) -#define kernel_termios_to_user_termios(u, k) \ +#define kernel_termios_to_user_termios_1(u, k) \ ({ \ put_user((k)->c_iflag, &(u)->c_iflag); \ put_user((k)->c_oflag, &(u)->c_oflag); \ @@ -132,7 +174,7 @@ struct winsize { put_user((k)->c_lflag, &(u)->c_lflag); \ put_user((k)->c_line, &(u)->c_line); \ copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \ - if(!((k)->c_lflag & ICANON)) { \ + if (!((k)->c_lflag & ICANON)) { \ put_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ } else { \ diff --git a/include/asm-sparc64/ioctls.h b/include/asm-sparc64/ioctls.h index 2223b6d..083c9a0 100644 --- a/include/asm-sparc64/ioctls.h +++ b/include/asm-sparc64/ioctls.h @@ -16,6 +16,10 @@ #define TCSETS _IOW('T', 9, struct termios) #define TCSETSW _IOW('T', 10, struct termios) #define TCSETSF _IOW('T', 11, struct termios) +#define TCGETS2 _IOR('T', 12, struct termios2) +#define TCSETS2 _IOW('T', 13, struct termios2) +#define TCSETSW2 _IOW('T', 14, struct termios2) +#define TCSETSF2 _IOW('T', 15, struct termios2) /* Note that all the ioctls that are not available in Linux have a * double underscore on the front to: a) avoid some programs to diff --git a/include/asm-sparc64/termbits.h b/include/asm-sparc64/termbits.h index 705cd44..ebe31c1 100644 --- a/include/asm-sparc64/termbits.h +++ b/include/asm-sparc64/termbits.h @@ -5,8 +5,6 @@ typedef unsigned char cc_t; typedef unsigned int speed_t; - -/* XXX is this right for sparc64? it was an unsigned long... XXX */ typedef unsigned int tcflag_t; #define NCC 8 @@ -33,6 +31,18 @@ struct termios { #endif }; +struct termios2 { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + cc_t _x_cc[2]; /* padding to match ktermios */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + struct ktermios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ @@ -161,6 +171,7 @@ struct ktermios { #define HUPCL 0x00000400 #define CLOCAL 0x00000800 #define CBAUDEX 0x00001000 +#define BOTHER 0x00001000 #define B57600 0x00001001 #define B115200 0x00001002 #define B230400 0x00001003 @@ -190,6 +201,8 @@ struct ktermios { #define CMSPAR 0x40000000 /* mark or space (stick) parity */ #define CRTSCTS 0x80000000 /* flow control */ +#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ + /* c_lflag bits */ #define ISIG 0x00000001 #define ICANON 0x00000002 diff --git a/include/asm-sparc64/termios.h b/include/asm-sparc64/termios.h index f05d390..ef52721 100644 --- a/include/asm-sparc64/termios.h +++ b/include/asm-sparc64/termios.h @@ -123,6 +123,8 @@ struct winsize { err |= get_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ } \ + err |= get_user((k)->c_ispeed, &(u)->c_ispeed); \ + err |= get_user((k)->c_ospeed, &(u)->c_ospeed); \ err; \ }) @@ -142,6 +144,46 @@ struct winsize { err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ } \ + err |= put_user((k)->c_ispeed, &(u)->c_ispeed); \ + err |= put_user((k)->c_ospeed, &(u)->c_ospeed); \ + err; \ +}) + +#define user_termios_to_kernel_termios_1(k, u) \ +({ \ + int err; \ + err = get_user((k)->c_iflag, &(u)->c_iflag); \ + err |= get_user((k)->c_oflag, &(u)->c_oflag); \ + err |= get_user((k)->c_cflag, &(u)->c_cflag); \ + err |= get_user((k)->c_lflag, &(u)->c_lflag); \ + err |= get_user((k)->c_line, &(u)->c_line); \ + err |= copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \ + if((k)->c_lflag & ICANON) { \ + err |= get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ + err |= get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ + } else { \ + err |= get_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ + err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ + } \ + err; \ +}) + +#define kernel_termios_to_user_termios_1(u, k) \ +({ \ + int err; \ + err = put_user((k)->c_iflag, &(u)->c_iflag); \ + err |= put_user((k)->c_oflag, &(u)->c_oflag); \ + err |= put_user((k)->c_cflag, &(u)->c_cflag); \ + err |= put_user((k)->c_lflag, &(u)->c_lflag); \ + err |= put_user((k)->c_line, &(u)->c_line); \ + err |= copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \ + if(!((k)->c_lflag & ICANON)) { \ + err |= put_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ + err |= put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ + } else { \ + err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ + err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ + } \ err; \ }) -- cgit v0.10.2 From 7b96dc023a1b487bce59256fde14b8bb28b45aea Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Wed, 17 Oct 2007 19:40:31 -0700 Subject: [SPARC] Videopix Frame Grabber: Convert device_lock_sem to mutex Videopix Frame Grabber: Convert the semaphore device_lock_sem to the mutex API Signed-off-by: Matthias Kaehlcke Signed-off-by: David S. Miller diff --git a/drivers/sbus/char/vfc.h b/drivers/sbus/char/vfc.h index 63941a2..f1aa138 100644 --- a/drivers/sbus/char/vfc.h +++ b/drivers/sbus/char/vfc.h @@ -126,7 +126,7 @@ struct vfc_dev { volatile struct vfc_regs __iomem *regs; struct vfc_regs *phys_regs; unsigned int control_reg; - struct semaphore device_lock_sem; + struct mutex device_lock_mtx; int instance; int busy; unsigned long which_io; diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c index 9269f7f..e7a1642 100644 --- a/drivers/sbus/char/vfc_dev.c +++ b/drivers/sbus/char/vfc_dev.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -54,12 +55,12 @@ static unsigned char saa9051_init_array[VFC_SAA9051_NR] = { void vfc_lock_device(struct vfc_dev *dev) { - down(&dev->device_lock_sem); + mutex_lock(&dev->device_lock_mtx); } void vfc_unlock_device(struct vfc_dev *dev) { - up(&dev->device_lock_sem); + mutex_unlock(&dev->device_lock_mtx); } -- cgit v0.10.2 From 5c45708352a040f19caceb683c78bc86aad466f6 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 17 Oct 2007 21:17:42 -0700 Subject: [SPARC/64]: Consolidate of_register_driver Also of_unregister_driver. These will be shortly also used by the PowerPC code. Signed-off-by: Stephen Rothwell Signed-off-by: David S. Miller diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c index fb2caef..3ea000d 100644 --- a/arch/sparc/kernel/of_device.c +++ b/arch/sparc/kernel/of_device.c @@ -585,24 +585,6 @@ static int __init of_debug(char *str) __setup("of_debug=", of_debug); -int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) -{ - /* initialize common driver fields */ - if (!drv->driver.name) - drv->driver.name = drv->name; - if (!drv->driver.owner) - drv->driver.owner = drv->owner; - drv->driver.bus = bus; - - /* register with core */ - return driver_register(&drv->driver); -} - -void of_unregister_driver(struct of_platform_driver *drv) -{ - driver_unregister(&drv->driver); -} - struct of_device* of_platform_device_create(struct device_node *np, const char *bus_id, struct device *parent, @@ -628,6 +610,4 @@ struct of_device* of_platform_device_create(struct device_node *np, return dev; } -EXPORT_SYMBOL(of_register_driver); -EXPORT_SYMBOL(of_unregister_driver); EXPORT_SYMBOL(of_platform_device_create); diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index 42d7798..fc5c0cc 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c @@ -869,26 +869,6 @@ static int __init of_debug(char *str) __setup("of_debug=", of_debug); -int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) -{ - /* initialize common driver fields */ - if (!drv->driver.name) - drv->driver.name = drv->name; - if (!drv->driver.owner) - drv->driver.owner = drv->owner; - drv->driver.bus = bus; - - /* register with core */ - return driver_register(&drv->driver); -} -EXPORT_SYMBOL(of_register_driver); - -void of_unregister_driver(struct of_platform_driver *drv) -{ - driver_unregister(&drv->driver); -} -EXPORT_SYMBOL(of_unregister_driver); - struct of_device* of_platform_device_create(struct device_node *np, const char *bus_id, struct device *parent, diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 864f09f..b47bb2d 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -12,6 +12,7 @@ * */ #include +#include #include #include #include @@ -94,3 +95,23 @@ int of_bus_type_init(struct bus_type *bus, const char *name) bus->resume = of_platform_device_resume; return bus_register(bus); } + +int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) +{ + /* initialize common driver fields */ + if (!drv->driver.name) + drv->driver.name = drv->name; + if (!drv->driver.owner) + drv->driver.owner = drv->owner; + drv->driver.bus = bus; + + /* register with core */ + return driver_register(&drv->driver); +} +EXPORT_SYMBOL(of_register_driver); + +void of_unregister_driver(struct of_platform_driver *drv) +{ + driver_unregister(&drv->driver); +} +EXPORT_SYMBOL(of_unregister_driver); diff --git a/include/asm-sparc/of_platform.h b/include/asm-sparc/of_platform.h index 64a2300..d638737 100644 --- a/include/asm-sparc/of_platform.h +++ b/include/asm-sparc/of_platform.h @@ -18,12 +18,9 @@ extern struct bus_type ebus_bus_type; extern struct bus_type sbus_bus_type; -extern struct bus_type of_platform_bus_type; + #define of_bus_type of_platform_bus_type /* for compatibility */ -extern int of_register_driver(struct of_platform_driver *drv, - struct bus_type *bus); -extern void of_unregister_driver(struct of_platform_driver *drv); extern struct of_device *of_platform_device_create(struct device_node *np, const char *bus_id, struct device *parent, diff --git a/include/asm-sparc64/of_platform.h b/include/asm-sparc64/of_platform.h index f7c1f17..f15cfa7 100644 --- a/include/asm-sparc64/of_platform.h +++ b/include/asm-sparc64/of_platform.h @@ -19,12 +19,9 @@ extern struct bus_type isa_bus_type; extern struct bus_type ebus_bus_type; extern struct bus_type sbus_bus_type; -extern struct bus_type of_platform_bus_type; + #define of_bus_type of_platform_bus_type /* for compatibility */ -extern int of_register_driver(struct of_platform_driver *drv, - struct bus_type *bus); -extern void of_unregister_driver(struct of_platform_driver *drv); extern struct of_device *of_platform_device_create(struct device_node *np, const char *bus_id, struct device *parent, diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index 448f70b..a8efcfe 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -48,6 +48,10 @@ struct of_platform_driver #define to_of_platform_driver(drv) \ container_of(drv,struct of_platform_driver, driver) +extern int of_register_driver(struct of_platform_driver *drv, + struct bus_type *bus); +extern void of_unregister_driver(struct of_platform_driver *drv); + #include extern struct of_device *of_find_device_by_node(struct device_node *np); -- cgit v0.10.2