From 80097be486911493f43ddedd3a391553a012098d Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 9 Jun 2010 17:34:05 -0400 Subject: [PATCH] --- yaml --- r: 207942 b: refs/heads/master c: 96e077ae347912dfce0e93f5958efc3ed6f311f4 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/Documentation/kernel-parameters.txt | 3 - trunk/arch/alpha/include/asm/ioctls.h | 4 +- trunk/arch/alpha/include/asm/termbits.h | 1 - trunk/arch/arm/include/asm/ioctls.h | 2 - trunk/arch/arm/include/asm/termbits.h | 1 - trunk/arch/avr32/include/asm/ioctls.h | 4 +- trunk/arch/avr32/include/asm/termbits.h | 1 - trunk/arch/cris/include/asm/ioctls.h | 4 +- trunk/arch/cris/include/asm/termbits.h | 1 - trunk/arch/frv/include/asm/ioctls.h | 2 - trunk/arch/frv/include/asm/termbits.h | 1 - trunk/arch/h8300/include/asm/ioctls.h | 2 - trunk/arch/h8300/include/asm/termbits.h | 1 - trunk/arch/ia64/include/asm/ioctls.h | 4 +- trunk/arch/ia64/include/asm/termbits.h | 1 - trunk/arch/m32r/include/asm/ioctls.h | 4 +- trunk/arch/m32r/include/asm/termbits.h | 1 - trunk/arch/m68k/include/asm/ioctls.h | 2 - trunk/arch/m68k/include/asm/termbits.h | 1 - trunk/arch/m68k/mac/config.c | 9 - trunk/arch/m68k/mac/misc.c | 6 +- trunk/arch/m68k/sun3/leds.c | 4 +- trunk/arch/mips/include/asm/ioctls.h | 5 +- trunk/arch/mips/include/asm/termbits.h | 1 - trunk/arch/mn10300/include/asm/ioctls.h | 4 +- trunk/arch/mn10300/include/asm/termbits.h | 1 - trunk/arch/parisc/include/asm/ioctls.h | 4 +- trunk/arch/parisc/include/asm/termbits.h | 1 - trunk/arch/powerpc/include/asm/ioctls.h | 2 - trunk/arch/powerpc/include/asm/termbits.h | 1 - trunk/arch/s390/include/asm/ccwdev.h | 2 - trunk/arch/s390/include/asm/ioctls.h | 2 - trunk/arch/s390/include/asm/topology.h | 2 + trunk/arch/s390/kernel/head.S | 2 +- trunk/arch/s390/mm/cmm.c | 11 +- trunk/arch/sh/include/asm/ioctls.h | 2 - trunk/arch/sparc/include/asm/ioctls.h | 2 - trunk/arch/sparc/include/asm/termbits.h | 1 - trunk/arch/xtensa/include/asm/ioctls.h | 2 - trunk/arch/xtensa/include/asm/termbits.h | 1 - trunk/drivers/char/Makefile | 1 - trunk/drivers/char/amiserial.c | 25 +- trunk/drivers/char/briq_panel.c | 6 +- trunk/drivers/char/cyclades.c | 22 +- trunk/drivers/char/epca.c | 4 +- trunk/drivers/char/ip2/ip2main.c | 4 - trunk/drivers/char/isicom.c | 13 +- trunk/drivers/char/istallion.c | 68 +- trunk/drivers/char/keyboard.c | 10 +- trunk/drivers/char/mxser.c | 2 +- trunk/drivers/char/n_gsm.c | 1 + trunk/drivers/char/n_hdlc.c | 16 +- trunk/drivers/char/n_r3964.c | 10 +- trunk/drivers/char/n_tty.c | 17 +- trunk/drivers/char/nozomi.c | 4 +- trunk/drivers/char/pty.c | 47 +- trunk/drivers/char/riscom8.c | 14 +- trunk/drivers/char/rocket.c | 28 +- trunk/drivers/char/selection.c | 13 +- trunk/drivers/char/serial167.c | 8 +- trunk/drivers/char/specialix.c | 13 +- trunk/drivers/char/stallion.c | 20 +- trunk/drivers/char/sx.c | 12 +- trunk/drivers/char/synclink.c | 21 +- trunk/drivers/char/synclink_gt.c | 92 +- trunk/drivers/char/synclinkmp.c | 43 +- trunk/drivers/char/tty_io.c | 150 +- trunk/drivers/char/tty_ioctl.c | 18 +- trunk/drivers/char/tty_ldisc.c | 43 +- trunk/drivers/char/tty_mutex.c | 47 - trunk/drivers/char/tty_port.c | 4 +- trunk/drivers/char/vc_screen.c | 4 +- trunk/drivers/char/vt.c | 37 +- trunk/drivers/char/vt_ioctl.c | 17 +- trunk/drivers/gpu/drm/i915/intel_fb.c | 4 +- trunk/drivers/gpu/drm/nouveau/nouveau_fbcon.c | 1 - trunk/drivers/gpu/drm/radeon/radeon_fb.c | 2 +- trunk/drivers/media/video/v4l2-dev.c | 52 +- trunk/drivers/s390/block/dasd_devmap.c | 44 - trunk/drivers/s390/block/dasd_diag.c | 6 +- trunk/drivers/s390/block/dasd_eckd.c | 94 +- trunk/drivers/s390/block/dasd_eckd.h | 7 +- trunk/drivers/s390/block/dasd_fba.c | 4 +- trunk/drivers/s390/block/dasd_int.h | 8 +- trunk/drivers/s390/cio/ccwreq.c | 16 +- trunk/drivers/s390/cio/chsc.c | 48 - trunk/drivers/s390/cio/chsc.h | 2 - trunk/drivers/s390/cio/device.c | 47 +- trunk/drivers/s390/cio/device_pgid.c | 3 - trunk/drivers/s390/cio/io_sch.h | 10 +- trunk/drivers/s390/net/smsgiucv_app.c | 7 - trunk/drivers/serial/21285.c | 10 +- trunk/drivers/serial/68328serial.c | 26 +- trunk/drivers/serial/68360serial.c | 4 +- trunk/drivers/serial/8250.c | 46 +- trunk/drivers/serial/8250_early.c | 57 +- trunk/drivers/serial/8250_pci.c | 13 - trunk/drivers/serial/Kconfig | 44 - trunk/drivers/serial/Makefile | 4 - trunk/drivers/serial/altera_uart.c | 2 +- trunk/drivers/serial/atmel_serial.c | 11 +- trunk/drivers/serial/bfin_5xx.c | 7 +- trunk/drivers/serial/crisv10.c | 12 +- trunk/drivers/serial/imx.c | 10 +- trunk/drivers/serial/ioc3_serial.c | 9 +- trunk/drivers/serial/ioc4_serial.c | 9 +- trunk/drivers/serial/max3100.c | 7 +- trunk/drivers/serial/max3107-aava.c | 344 ---- trunk/drivers/serial/max3107.c | 1197 ------------- trunk/drivers/serial/max3107.h | 441 ----- trunk/drivers/serial/mcf.c | 31 +- trunk/drivers/serial/mfd.c | 1498 ----------------- trunk/drivers/serial/mrst_max3110.c | 844 ---------- trunk/drivers/serial/mrst_max3110.h | 59 - trunk/drivers/serial/serial_core.c | 288 ++-- trunk/drivers/serial/timbuart.c | 6 +- trunk/drivers/staging/easycap/easycap.h | 8 +- trunk/drivers/staging/easycap/easycap_ioctl.c | 52 +- trunk/drivers/staging/easycap/easycap_main.c | 38 +- trunk/drivers/usb/class/cdc-acm.c | 12 +- trunk/drivers/usb/core/hcd.c | 18 +- trunk/drivers/usb/serial/digi_acceleport.c | 14 +- trunk/drivers/video/console/fbcon.c | 4 +- trunk/drivers/video/console/vgacon.c | 2 + trunk/drivers/zorro/proc.c | 17 +- trunk/fs/autofs/root.c | 67 +- trunk/fs/autofs4/root.c | 49 - trunk/fs/compat_ioctl.c | 37 +- trunk/fs/ecryptfs/file.c | 60 +- trunk/fs/ecryptfs/inode.c | 94 +- trunk/fs/ecryptfs/messaging.c | 2 +- trunk/fs/ncpfs/ioctl.c | 1 + trunk/include/asm-generic/ioctls.h | 8 +- trunk/include/asm-generic/termbits.h | 1 - trunk/include/linux/auto_fs.h | 1 - trunk/include/linux/console_struct.h | 4 +- trunk/include/linux/fb.h | 4 - trunk/include/linux/istallion.h | 2 +- trunk/include/linux/serial.h | 9 +- trunk/include/linux/serial_8250.h | 5 - trunk/include/linux/serial_core.h | 11 +- trunk/include/linux/serial_mfd.h | 47 - trunk/include/linux/serial_reg.h | 16 - trunk/include/linux/tty.h | 52 - trunk/include/linux/vt_kern.h | 64 +- trunk/lib/Kconfig.debug | 7 - trunk/lib/scatterlist.c | 23 +- trunk/mm/kmemleak.c | 100 +- 149 files changed, 906 insertions(+), 6198 deletions(-) delete mode 100644 trunk/drivers/char/tty_mutex.c delete mode 100644 trunk/drivers/serial/max3107-aava.c delete mode 100644 trunk/drivers/serial/max3107.c delete mode 100644 trunk/drivers/serial/max3107.h delete mode 100644 trunk/drivers/serial/mfd.c delete mode 100644 trunk/drivers/serial/mrst_max3110.c delete mode 100644 trunk/drivers/serial/mrst_max3110.h delete mode 100644 trunk/include/linux/serial_mfd.h diff --git a/[refs] b/[refs] index dc80bb362c6f..adc962708f48 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: fc385c313275b114bc6ad36e60c5177d63250548 +refs/heads/master: 96e077ae347912dfce0e93f5958efc3ed6f311f4 diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index d529b1363e95..44f6b19c50bb 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -681,11 +681,8 @@ and is between 256 and 4096 characters. It is defined in the file earlycon= [KNL] Output early console device and options. uart[8250],io,[,options] uart[8250],mmio,[,options] - uart[8250],mmio32,[,options] Start an early, polled-mode console on the 8250/16550 UART at the specified I/O port or MMIO address. - MMIO inter-register address stride is either 8bit (mmio) - or 32bit (mmio32). The options are the same as for ttyS, above. earlyprintk= [X86,SH,BLACKFIN] diff --git a/trunk/arch/alpha/include/asm/ioctls.h b/trunk/arch/alpha/include/asm/ioctls.h index 59617c3c2be6..67bb9f6fdbe4 100644 --- a/trunk/arch/alpha/include/asm/ioctls.h +++ b/trunk/arch/alpha/include/asm/ioctls.h @@ -80,7 +80,6 @@ # define TIOCPKT_START 8 # define TIOCPKT_NOSTOP 16 # define TIOCPKT_DOSTOP 32 -# define TIOCPKT_IOCTL 64 #define TIOCNOTTY 0x5422 @@ -92,7 +91,6 @@ #define TIOCGSID 0x5429 /* Return the session ID of FD */ #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ -#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define TIOCSERCONFIG 0x5453 #define TIOCSERGWILD 0x5454 @@ -108,5 +106,7 @@ #define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ +#define TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ +#define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ #endif /* _ASM_ALPHA_IOCTLS_H */ diff --git a/trunk/arch/alpha/include/asm/termbits.h b/trunk/arch/alpha/include/asm/termbits.h index 879dd3589921..ad854a4a3af6 100644 --- a/trunk/arch/alpha/include/asm/termbits.h +++ b/trunk/arch/alpha/include/asm/termbits.h @@ -180,7 +180,6 @@ struct ktermios { #define FLUSHO 0x00800000 #define PENDIN 0x20000000 #define IEXTEN 0x00000400 -#define EXTPROC 0x10000000 /* Values for the ACTION argument to `tcflow'. */ #define TCOOFF 0 diff --git a/trunk/arch/arm/include/asm/ioctls.h b/trunk/arch/arm/include/asm/ioctls.h index 0b30894b5482..7f0b6d13296a 100644 --- a/trunk/arch/arm/include/asm/ioctls.h +++ b/trunk/arch/arm/include/asm/ioctls.h @@ -52,7 +52,6 @@ #define TCSETSF2 _IOW('T',0x2D, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ -#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define TIOCGRS485 0x542E #define TIOCSRS485 0x542F @@ -82,7 +81,6 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 -#define TIOCPKT_IOCTL 64 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/trunk/arch/arm/include/asm/termbits.h b/trunk/arch/arm/include/asm/termbits.h index 704135d28d1d..f784d11f40b5 100644 --- a/trunk/arch/arm/include/asm/termbits.h +++ b/trunk/arch/arm/include/asm/termbits.h @@ -177,7 +177,6 @@ struct ktermios { #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 -#define EXTPROC 0200000 /* tcflow() and TCXONC use these */ #define TCOOFF 0 diff --git a/trunk/arch/avr32/include/asm/ioctls.h b/trunk/arch/avr32/include/asm/ioctls.h index b7dd324b46a9..e6ac0b661076 100644 --- a/trunk/arch/avr32/include/asm/ioctls.h +++ b/trunk/arch/avr32/include/asm/ioctls.h @@ -53,7 +53,6 @@ #define TCSETSF2 _IOW('T',0x2D, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ -#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define TIOCGRS485 0x542E #define TIOCSRS485 0x542F @@ -73,6 +72,8 @@ #define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ +#define TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ +#define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ #define FIOQSIZE 0x5460 /* Used for packet mode */ @@ -83,7 +84,6 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 -#define TIOCPKT_IOCTL 64 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/trunk/arch/avr32/include/asm/termbits.h b/trunk/arch/avr32/include/asm/termbits.h index 366adc5ebb10..db2daab31fdb 100644 --- a/trunk/arch/avr32/include/asm/termbits.h +++ b/trunk/arch/avr32/include/asm/termbits.h @@ -175,7 +175,6 @@ struct ktermios { #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 -#define EXTPROC 0200000 /* tcflow() and TCXONC use these */ #define TCOOFF 0 diff --git a/trunk/arch/cris/include/asm/ioctls.h b/trunk/arch/cris/include/asm/ioctls.h index c9129ed37443..076c07824eb6 100644 --- a/trunk/arch/cris/include/asm/ioctls.h +++ b/trunk/arch/cris/include/asm/ioctls.h @@ -54,7 +54,6 @@ #define TCSETSF2 _IOW('T',0x2D, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ -#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ #define FIOCLEX 0x5451 @@ -71,6 +70,8 @@ #define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ +#define TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ +#define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ #define FIOQSIZE 0x5460 #define TIOCSERSETRS485 0x5461 /* enable rs-485 (deprecated) */ @@ -86,7 +87,6 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 -#define TIOCPKT_IOCTL 64 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/trunk/arch/cris/include/asm/termbits.h b/trunk/arch/cris/include/asm/termbits.h index 1c43bc874ccf..66e1a7492a0c 100644 --- a/trunk/arch/cris/include/asm/termbits.h +++ b/trunk/arch/cris/include/asm/termbits.h @@ -214,7 +214,6 @@ struct ktermios { #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 -#define EXTPROC 0200000 /* tcflow() and TCXONC use these */ #define TCOOFF 0 diff --git a/trunk/arch/frv/include/asm/ioctls.h b/trunk/arch/frv/include/asm/ioctls.h index a993e3759ccf..d0c30e31fbda 100644 --- a/trunk/arch/frv/include/asm/ioctls.h +++ b/trunk/arch/frv/include/asm/ioctls.h @@ -53,7 +53,6 @@ #define TCSETSF2 _IOW('T',0x2D, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ -#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ #define FIOCLEX 0x5451 @@ -80,7 +79,6 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 -#define TIOCPKT_IOCTL 64 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/trunk/arch/frv/include/asm/termbits.h b/trunk/arch/frv/include/asm/termbits.h index 7722e19cc349..5568492b5086 100644 --- a/trunk/arch/frv/include/asm/termbits.h +++ b/trunk/arch/frv/include/asm/termbits.h @@ -180,7 +180,6 @@ struct ktermios { #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 -#define EXTPROC 0200000 /* tcflow() and TCXONC use these */ diff --git a/trunk/arch/h8300/include/asm/ioctls.h b/trunk/arch/h8300/include/asm/ioctls.h index b6b249f9f308..98a53d067269 100644 --- a/trunk/arch/h8300/include/asm/ioctls.h +++ b/trunk/arch/h8300/include/asm/ioctls.h @@ -53,7 +53,6 @@ #define TCSETSF2 _IOW('T',0x2D, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ -#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ #define FIOCLEX 0x5451 @@ -80,7 +79,6 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 -#define TIOCPKT_IOCTL 64 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/trunk/arch/h8300/include/asm/termbits.h b/trunk/arch/h8300/include/asm/termbits.h index 3287a6244d74..31eca81db3f7 100644 --- a/trunk/arch/h8300/include/asm/termbits.h +++ b/trunk/arch/h8300/include/asm/termbits.h @@ -179,7 +179,6 @@ struct ktermios { #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 -#define EXTPROC 0200000 /* tcflow() and TCXONC use these */ diff --git a/trunk/arch/ia64/include/asm/ioctls.h b/trunk/arch/ia64/include/asm/ioctls.h index b79c385114ef..f41b636a0bf6 100644 --- a/trunk/arch/ia64/include/asm/ioctls.h +++ b/trunk/arch/ia64/include/asm/ioctls.h @@ -59,7 +59,6 @@ #define TCSETSF2 _IOW('T',0x2D, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ -#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ #define FIOCLEX 0x5451 @@ -76,6 +75,8 @@ #define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ +#define TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ +#define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ #define FIOQSIZE 0x5460 /* Used for packet mode */ @@ -86,7 +87,6 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 -#define TIOCPKT_IOCTL 64 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/trunk/arch/ia64/include/asm/termbits.h b/trunk/arch/ia64/include/asm/termbits.h index c009b94e58d9..9f162e0089ad 100644 --- a/trunk/arch/ia64/include/asm/termbits.h +++ b/trunk/arch/ia64/include/asm/termbits.h @@ -187,7 +187,6 @@ struct ktermios { #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 -#define EXTPROC 0200000 /* tcflow() and TCXONC use these */ #define TCOOFF 0 diff --git a/trunk/arch/m32r/include/asm/ioctls.h b/trunk/arch/m32r/include/asm/ioctls.h index 66288063a4c0..b9f54bb5d7cf 100644 --- a/trunk/arch/m32r/include/asm/ioctls.h +++ b/trunk/arch/m32r/include/asm/ioctls.h @@ -53,7 +53,6 @@ #define TCSETSF2 _IOW('T',0x2D, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ -#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define FIONCLEX 0x5450 #define FIOCLEX 0x5451 @@ -70,6 +69,8 @@ #define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ +#define TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ +#define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ #define FIOQSIZE 0x5460 /* Used for packet mode */ @@ -80,7 +81,6 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 -#define TIOCPKT_IOCTL 64 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/trunk/arch/m32r/include/asm/termbits.h b/trunk/arch/m32r/include/asm/termbits.h index 957a3c688549..bc104008b55b 100644 --- a/trunk/arch/m32r/include/asm/termbits.h +++ b/trunk/arch/m32r/include/asm/termbits.h @@ -179,7 +179,6 @@ struct ktermios { #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 -#define EXTPROC 0200000 /* tcflow() and TCXONC use these */ #define TCOOFF 0 diff --git a/trunk/arch/m68k/include/asm/ioctls.h b/trunk/arch/m68k/include/asm/ioctls.h index 91a57d665460..b8d2f4be7fd7 100644 --- a/trunk/arch/m68k/include/asm/ioctls.h +++ b/trunk/arch/m68k/include/asm/ioctls.h @@ -52,7 +52,6 @@ #define TCSETSF2 _IOW('T',0x2D, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ -#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ #define FIOCLEX 0x5451 @@ -79,7 +78,6 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 -#define TIOCPKT_IOCTL 64 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/trunk/arch/m68k/include/asm/termbits.h b/trunk/arch/m68k/include/asm/termbits.h index aea1e37b765a..8c14170996bb 100644 --- a/trunk/arch/m68k/include/asm/termbits.h +++ b/trunk/arch/m68k/include/asm/termbits.h @@ -179,7 +179,6 @@ struct ktermios { #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 -#define EXTPROC 0200000 /* tcflow() and TCXONC use these */ diff --git a/trunk/arch/m68k/mac/config.c b/trunk/arch/m68k/mac/config.c index c247de02bc7e..1c16b1baf8db 100644 --- a/trunk/arch/m68k/mac/config.c +++ b/trunk/arch/m68k/mac/config.c @@ -332,15 +332,6 @@ static struct mac_model mac_data_table[] = { .scc_type = MAC_SCC_II, .nubus_type = MAC_NUBUS, .floppy_type = MAC_FLOPPY_SWIM_ADDR2, - }, { - .ident = MAC_MODEL_CCLII, - .name = "Color Classic II", - .adb_type = MAC_ADB_CUDA, - .via_type = MAC_VIA_IIci, - .scsi_type = MAC_SCSI_OLD, - .scc_type = MAC_SCC_II, - .nubus_type = MAC_NUBUS, - .floppy_type = MAC_FLOPPY_SWIM_ADDR2, }, /* diff --git a/trunk/arch/m68k/mac/misc.c b/trunk/arch/m68k/mac/misc.c index e023fc6b37e5..0f118ca156d9 100644 --- a/trunk/arch/m68k/mac/misc.c +++ b/trunk/arch/m68k/mac/misc.c @@ -91,7 +91,7 @@ static void cuda_write_pram(int offset, __u8 data) #define cuda_write_pram NULL #endif -#ifdef CONFIG_ADB_PMU68K +#if 0 /* def CONFIG_ADB_PMU68K */ static long pmu_read_time(void) { struct adb_request req; @@ -102,8 +102,8 @@ static long pmu_read_time(void) while (!req.complete) pmu_poll(); - time = (req.reply[1] << 24) | (req.reply[2] << 16) - | (req.reply[3] << 8) | req.reply[4]; + time = (req.reply[0] << 24) | (req.reply[1] << 16) + | (req.reply[2] << 8) | req.reply[3]; return time - RTC_OFFSET; } diff --git a/trunk/arch/m68k/sun3/leds.c b/trunk/arch/m68k/sun3/leds.c index aad2e0a0682e..a3e948463982 100644 --- a/trunk/arch/m68k/sun3/leds.c +++ b/trunk/arch/m68k/sun3/leds.c @@ -7,7 +7,7 @@ void sun3_leds(unsigned char byte) unsigned char dfc; GET_DFC(dfc); - SET_DFC(FC_CONTROL); - SET_CONTROL_BYTE(AC_LEDS, byte); + SET_DFC(FC_CONTROL); + SET_CONTROL_BYTE(AC_LEDS,byte); SET_DFC(dfc); } diff --git a/trunk/arch/mips/include/asm/ioctls.h b/trunk/arch/mips/include/asm/ioctls.h index d87cb0465693..3f04a995ec54 100644 --- a/trunk/arch/mips/include/asm/ioctls.h +++ b/trunk/arch/mips/include/asm/ioctls.h @@ -41,7 +41,7 @@ #define TIOCPKT_START 0x08 /* start output */ #define TIOCPKT_NOSTOP 0x10 /* no more ^S, ^Q */ #define TIOCPKT_DOSTOP 0x20 /* now do ^S ^Q */ -#define TIOCPKT_IOCTL 0x40 /* state change of pty driver */ +/* #define TIOCPKT_IOCTL 0x40 state change of pty driver */ #define TIOCSWINSZ _IOW('t', 103, struct winsize) /* set window size */ #define TIOCGWINSZ _IOR('t', 104, struct winsize) /* get window size */ #define TIOCNOTTY 0x5471 /* void tty association */ @@ -83,7 +83,6 @@ #define TCSETSF2 _IOW('T', 0x2D, struct termios2) #define TIOCGPTN _IOR('T', 0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */ -#define TIOCSIG _IOW('T', 0x36, int) /* Generate signal on Pty slave */ /* I hope the range from 0x5480 on is free ... */ #define TIOCSCTTY 0x5480 /* become controlling tty */ @@ -104,5 +103,7 @@ #define TIOCSERSETMULTI 0x5490 /* Set multiport config */ #define TIOCMIWAIT 0x5491 /* wait for a change on serial input line(s) */ #define TIOCGICOUNT 0x5492 /* read serial port inline interrupt counts */ +#define TIOCGHAYESESP 0x5493 /* Get Hayes ESP configuration */ +#define TIOCSHAYESESP 0x5494 /* Set Hayes ESP configuration */ #endif /* __ASM_IOCTLS_H */ diff --git a/trunk/arch/mips/include/asm/termbits.h b/trunk/arch/mips/include/asm/termbits.h index 76630b396fac..c83c68444e86 100644 --- a/trunk/arch/mips/include/asm/termbits.h +++ b/trunk/arch/mips/include/asm/termbits.h @@ -203,7 +203,6 @@ struct ktermios { #define PENDIN 0040000 /* Retype pending input (state). */ #define TOSTOP 0100000 /* Send SIGTTOU for background output. */ #define ITOSTOP TOSTOP -#define EXTPROC 0200000 /* External processing on pty */ /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/trunk/arch/mn10300/include/asm/ioctls.h b/trunk/arch/mn10300/include/asm/ioctls.h index cb8cf1902234..dcbfb452974f 100644 --- a/trunk/arch/mn10300/include/asm/ioctls.h +++ b/trunk/arch/mn10300/include/asm/ioctls.h @@ -54,7 +54,6 @@ #define TIOCGPTN _IOR('T', 0x30, unsigned int) /* Get Pty Number * (of pty-mux device) */ #define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */ -#define TIOCSIG _IOW('T', 0x36, int) /* Generate signal on Pty slave */ #define FIONCLEX 0x5450 #define FIOCLEX 0x5451 @@ -71,6 +70,8 @@ #define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ +#define TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ +#define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ #define FIOQSIZE 0x5460 /* Used for packet mode */ @@ -81,7 +82,6 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 -#define TIOCPKT_IOCTL 64 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/trunk/arch/mn10300/include/asm/termbits.h b/trunk/arch/mn10300/include/asm/termbits.h index 130d42495972..eb2b0dc1f696 100644 --- a/trunk/arch/mn10300/include/asm/termbits.h +++ b/trunk/arch/mn10300/include/asm/termbits.h @@ -180,7 +180,6 @@ struct ktermios { #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 -#define EXTPROC 0200000 /* tcflow() and TCXONC use these */ #define TCOOFF 0 diff --git a/trunk/arch/parisc/include/asm/ioctls.h b/trunk/arch/parisc/include/asm/ioctls.h index 4e0614456bea..6747fad07a3e 100644 --- a/trunk/arch/parisc/include/asm/ioctls.h +++ b/trunk/arch/parisc/include/asm/ioctls.h @@ -52,7 +52,6 @@ #define TCSETSF2 _IOW('T',0x2D, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ -#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ #define FIOCLEX 0x5451 @@ -69,6 +68,8 @@ #define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ +#define TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ +#define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ #define FIOQSIZE 0x5460 /* Get exact space used by quota */ #define TIOCSTART 0x5461 @@ -83,7 +84,6 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 -#define TIOCPKT_IOCTL 64 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/trunk/arch/parisc/include/asm/termbits.h b/trunk/arch/parisc/include/asm/termbits.h index d1ab92177a5c..d8bbc73b16b7 100644 --- a/trunk/arch/parisc/include/asm/termbits.h +++ b/trunk/arch/parisc/include/asm/termbits.h @@ -180,7 +180,6 @@ struct ktermios { #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 -#define EXTPROC 0200000 /* tcflow() and TCXONC use these */ #define TCOOFF 0 diff --git a/trunk/arch/powerpc/include/asm/ioctls.h b/trunk/arch/powerpc/include/asm/ioctls.h index 851920052e08..1842186d872c 100644 --- a/trunk/arch/powerpc/include/asm/ioctls.h +++ b/trunk/arch/powerpc/include/asm/ioctls.h @@ -80,7 +80,6 @@ # define TIOCPKT_START 8 # define TIOCPKT_NOSTOP 16 # define TIOCPKT_DOSTOP 32 -# define TIOCPKT_IOCTL 64 #define TIOCNOTTY 0x5422 @@ -94,7 +93,6 @@ #define TIOCSRS485 0x542f #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ -#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define TIOCSERCONFIG 0x5453 #define TIOCSERGWILD 0x5454 diff --git a/trunk/arch/powerpc/include/asm/termbits.h b/trunk/arch/powerpc/include/asm/termbits.h index 549d700e18f2..6698188ca550 100644 --- a/trunk/arch/powerpc/include/asm/termbits.h +++ b/trunk/arch/powerpc/include/asm/termbits.h @@ -189,7 +189,6 @@ struct ktermios { #define FLUSHO 0x00800000 #define PENDIN 0x20000000 #define IEXTEN 0x00000400 -#define EXTPROC 0x10000000 /* Values for the ACTION argument to `tcflow'. */ #define TCOOFF 0 diff --git a/trunk/arch/s390/include/asm/ccwdev.h b/trunk/arch/s390/include/asm/ccwdev.h index f3ba0fa98de6..1c0030f9b890 100644 --- a/trunk/arch/s390/include/asm/ccwdev.h +++ b/trunk/arch/s390/include/asm/ccwdev.h @@ -208,8 +208,6 @@ extern void ccw_device_get_id(struct ccw_device *, struct ccw_dev_id *); extern struct ccw_device *ccw_device_probe_console(void); extern int ccw_device_force_console(void); -int ccw_device_siosl(struct ccw_device *); - // FIXME: these have to go extern int _ccw_device_get_subchannel_number(struct ccw_device *); diff --git a/trunk/arch/s390/include/asm/ioctls.h b/trunk/arch/s390/include/asm/ioctls.h index 2f3d8736361f..40e481b1b461 100644 --- a/trunk/arch/s390/include/asm/ioctls.h +++ b/trunk/arch/s390/include/asm/ioctls.h @@ -60,7 +60,6 @@ #define TCSETSF2 _IOW('T',0x2D, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ -#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ #define FIOCLEX 0x5451 @@ -87,7 +86,6 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 -#define TIOCPKT_IOCTL 64 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/trunk/arch/s390/include/asm/topology.h b/trunk/arch/s390/include/asm/topology.h index 831bd033ea77..dc8a67297d0f 100644 --- a/trunk/arch/s390/include/asm/topology.h +++ b/trunk/arch/s390/include/asm/topology.h @@ -30,6 +30,8 @@ static inline void s390_init_cpu_topology(void) }; #endif +#define SD_MC_INIT SD_CPU_INIT + #include #endif /* _ASM_S390_TOPOLOGY_H */ diff --git a/trunk/arch/s390/kernel/head.S b/trunk/arch/s390/kernel/head.S index db1696e210af..51838ad42d56 100644 --- a/trunk/arch/s390/kernel/head.S +++ b/trunk/arch/s390/kernel/head.S @@ -366,7 +366,7 @@ iplstart: l %r1,.Lstartup br %r1 -.Linitrd:.long _end # default address of initrd +.Linitrd:.long _end + 0x400000 # default address of initrd .Lparm: .long PARMAREA .Lstartup: .long startup .Lreset:.byte 0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40 diff --git a/trunk/arch/s390/mm/cmm.c b/trunk/arch/s390/mm/cmm.c index a9550dca3e4b..eb6a2ef5f82e 100644 --- a/trunk/arch/s390/mm/cmm.c +++ b/trunk/arch/s390/mm/cmm.c @@ -427,7 +427,7 @@ static struct notifier_block cmm_power_notifier = { .notifier_call = cmm_power_event, }; -static int __init cmm_init(void) +static int cmm_init(void) { int rc = -ENOMEM; @@ -435,13 +435,6 @@ static int __init cmm_init(void) if (!cmm_sysctl_header) goto out_sysctl; #ifdef CONFIG_CMM_IUCV - /* convert sender to uppercase characters */ - if (sender) { - int len = strlen(sender); - while (len--) - sender[len] = toupper(sender[len]); - } - rc = smsg_register_callback(SMSG_PREFIX, cmm_smsg_target); if (rc < 0) goto out_smsg; @@ -474,7 +467,7 @@ static int __init cmm_init(void) } module_init(cmm_init); -static void __exit cmm_exit(void) +static void cmm_exit(void) { unregister_sysctl_table(cmm_sysctl_header); #ifdef CONFIG_CMM_IUCV diff --git a/trunk/arch/sh/include/asm/ioctls.h b/trunk/arch/sh/include/asm/ioctls.h index eb6c4c687972..c212c371a4a5 100644 --- a/trunk/arch/sh/include/asm/ioctls.h +++ b/trunk/arch/sh/include/asm/ioctls.h @@ -69,7 +69,6 @@ # define TIOCPKT_START 8 # define TIOCPKT_NOSTOP 16 # define TIOCPKT_DOSTOP 32 -# define TIOCPKT_IOCTL 64 #define TIOCNOTTY _IO('T', 34) /* 0x5422 */ @@ -85,7 +84,6 @@ #define TCSETSF2 _IOW('T', 45, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ -#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define TIOCSERCONFIG _IO('T', 83) /* 0x5453 */ #define TIOCSERGWILD _IOR('T', 84, int) /* 0x5454 */ diff --git a/trunk/arch/sparc/include/asm/ioctls.h b/trunk/arch/sparc/include/asm/ioctls.h index 53f4ee009bdd..1fe6855c5c18 100644 --- a/trunk/arch/sparc/include/asm/ioctls.h +++ b/trunk/arch/sparc/include/asm/ioctls.h @@ -80,7 +80,6 @@ /* Get minor device of a pty master's FD -- Solaris equiv is ISPTM */ #define TIOCGPTN _IOR('t', 134, unsigned int) /* Get Pty Number */ #define TIOCSPTLCK _IOW('t', 135, int) /* Lock/unlock PTY */ -#define TIOCSIG _IOW('t', 136, int) /* Generate signal on Pty slave */ /* Little f */ #define FIOCLEX _IO('f', 1) @@ -133,6 +132,5 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 -#define TIOCPKT_IOCTL 64 #endif /* !(_ASM_SPARC_IOCTLS_H) */ diff --git a/trunk/arch/sparc/include/asm/termbits.h b/trunk/arch/sparc/include/asm/termbits.h index 23b10ff08df2..d72dfed1f9d7 100644 --- a/trunk/arch/sparc/include/asm/termbits.h +++ b/trunk/arch/sparc/include/asm/termbits.h @@ -225,7 +225,6 @@ struct ktermios { #define FLUSHO 0x00002000 #define PENDIN 0x00004000 #define IEXTEN 0x00008000 -#define EXTPROC 0x00010000 /* modem lines */ #define TIOCM_LE 0x001 diff --git a/trunk/arch/xtensa/include/asm/ioctls.h b/trunk/arch/xtensa/include/asm/ioctls.h index ab1800012ed9..0ffa942954b9 100644 --- a/trunk/arch/xtensa/include/asm/ioctls.h +++ b/trunk/arch/xtensa/include/asm/ioctls.h @@ -81,7 +81,6 @@ # define TIOCPKT_START 8 # define TIOCPKT_NOSTOP 16 # define TIOCPKT_DOSTOP 32 -# define TIOCPKT_IOCTL 64 #define TIOCNOTTY _IO('T', 34) @@ -98,7 +97,6 @@ #define TCSETSF2 _IOW('T', 45, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ -#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define TIOCSERCONFIG _IO('T', 83) #define TIOCSERGWILD _IOR('T', 84, int) diff --git a/trunk/arch/xtensa/include/asm/termbits.h b/trunk/arch/xtensa/include/asm/termbits.h index 0d6c8715b24f..85aa6a3c0b6e 100644 --- a/trunk/arch/xtensa/include/asm/termbits.h +++ b/trunk/arch/xtensa/include/asm/termbits.h @@ -196,7 +196,6 @@ struct ktermios { #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 -#define EXTPROC 0200000 /* tcflow() and TCXONC use these */ diff --git a/trunk/drivers/char/Makefile b/trunk/drivers/char/Makefile index dc9641660605..273cee1cc77b 100644 --- a/trunk/drivers/char/Makefile +++ b/trunk/drivers/char/Makefile @@ -9,7 +9,6 @@ FONTMAPFILE = cp437.uni obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o tty_buffer.o tty_port.o -obj-y += tty_mutex.o obj-$(CONFIG_LEGACY_PTYS) += pty.o obj-$(CONFIG_UNIX98_PTYS) += pty.o obj-y += misc.o diff --git a/trunk/drivers/char/amiserial.c b/trunk/drivers/char/amiserial.c index a11c8c9ca3d4..4f8d60c25a98 100644 --- a/trunk/drivers/char/amiserial.c +++ b/trunk/drivers/char/amiserial.c @@ -1072,7 +1072,7 @@ static int get_serial_info(struct async_struct * info, if (!retinfo) return -EFAULT; memset(&tmp, 0, sizeof(tmp)); - tty_lock(); + lock_kernel(); tmp.type = state->type; tmp.line = state->line; tmp.port = state->port; @@ -1083,7 +1083,7 @@ static int get_serial_info(struct async_struct * info, tmp.close_delay = state->close_delay; tmp.closing_wait = state->closing_wait; tmp.custom_divisor = state->custom_divisor; - tty_unlock(); + unlock_kernel(); if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) return -EFAULT; return 0; @@ -1100,14 +1100,14 @@ static int set_serial_info(struct async_struct * info, if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) return -EFAULT; - tty_lock(); + lock_kernel(); state = info->state; old_state = *state; change_irq = new_serial.irq != state->irq; change_port = (new_serial.port != state->port); if(change_irq || change_port || (new_serial.xmit_fifo_size != state->xmit_fifo_size)) { - tty_unlock(); + unlock_kernel(); return -EINVAL; } @@ -1127,7 +1127,7 @@ static int set_serial_info(struct async_struct * info, } if (new_serial.baud_base < 9600) { - tty_unlock(); + unlock_kernel(); return -EINVAL; } @@ -1163,7 +1163,7 @@ static int set_serial_info(struct async_struct * info, } } else retval = startup(info); - tty_unlock(); + unlock_kernel(); return retval; } @@ -1528,7 +1528,6 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) { struct async_struct * info = tty->driver_data; unsigned long orig_jiffies, char_time; - int tty_was_locked = tty_locked(); int lsr; if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent")) @@ -1539,12 +1538,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) orig_jiffies = jiffies; - /* - * tty_wait_until_sent is called from lots of places, - * with or without the BTM. - */ - if (!tty_was_locked) - tty_lock(); + lock_kernel(); /* * Set the check interval to be 1/5 of the estimated time to * send a single character, and make it at least 1. The check @@ -1585,8 +1579,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) break; } __set_current_state(TASK_RUNNING); - if (!tty_was_locked) - tty_unlock(); + unlock_kernel(); #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); #endif @@ -1710,9 +1703,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, printk("block_til_ready blocking: ttys%d, count = %d\n", info->line, state->count); #endif - tty_unlock(); schedule(); - tty_lock(); } __set_current_state(TASK_RUNNING); remove_wait_queue(&info->open_wait, &wait); diff --git a/trunk/drivers/char/briq_panel.c b/trunk/drivers/char/briq_panel.c index d5fa113afe37..555cd93c2ee5 100644 --- a/trunk/drivers/char/briq_panel.c +++ b/trunk/drivers/char/briq_panel.c @@ -67,15 +67,15 @@ static void set_led(char state) static int briq_panel_open(struct inode *ino, struct file *filep) { - tty_lock(); + lock_kernel(); /* enforce single access, vfd_is_open is protected by BKL */ if (vfd_is_open) { - tty_unlock(); + unlock_kernel(); return -EBUSY; } vfd_is_open = 1; - tty_unlock(); + unlock_kernel(); return 0; } diff --git a/trunk/drivers/char/cyclades.c b/trunk/drivers/char/cyclades.c index 27aad9422332..9824b4162904 100644 --- a/trunk/drivers/char/cyclades.c +++ b/trunk/drivers/char/cyclades.c @@ -65,6 +65,7 @@ #include #include #include +#include #include #include #include @@ -1607,7 +1608,7 @@ static int cy_open(struct tty_struct *tty, struct file *filp) * If the port is the middle of closing, bail out now */ if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) { - wait_event_interruptible_tty(info->port.close_wait, + wait_event_interruptible(info->port.close_wait, !(info->port.flags & ASYNC_CLOSING)); return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; } @@ -1654,6 +1655,7 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout) return; /* Just in case.... */ orig_jiffies = jiffies; + lock_kernel(); /* * Set the check interval to be 1/5 of the estimated time to * send a single character, and make it at least 1. The check @@ -1700,6 +1702,7 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout) } /* Run one more char cycle */ msleep_interruptible(jiffies_to_msecs(char_time * 5)); + unlock_kernel(); #ifdef CY_DEBUG_WAIT_UNTIL_SENT printk(KERN_DEBUG "Clean (jiff=%lu)...done\n", jiffies); #endif @@ -1956,6 +1959,7 @@ static int cy_chars_in_buffer(struct tty_struct *tty) int char_count; __u32 tx_put, tx_get, tx_bufsize; + lock_kernel(); tx_get = readl(&buf_ctrl->tx_get); tx_put = readl(&buf_ctrl->tx_put); tx_bufsize = readl(&buf_ctrl->tx_bufsize); @@ -1967,6 +1971,7 @@ static int cy_chars_in_buffer(struct tty_struct *tty) printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n", info->line, info->xmit_cnt + char_count); #endif + unlock_kernel(); return info->xmit_cnt + char_count; } #endif /* Z_EXT_CHARS_IN_BUFFER */ @@ -2354,22 +2359,17 @@ cy_set_serial_info(struct cyclades_port *info, struct tty_struct *tty, struct serial_struct __user *new_info) { struct serial_struct new_serial; - int ret; if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) return -EFAULT; - mutex_lock(&info->port.mutex); if (!capable(CAP_SYS_ADMIN)) { if (new_serial.close_delay != info->port.close_delay || new_serial.baud_base != info->baud || (new_serial.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK) != (info->port.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK)) - { - mutex_unlock(&info->port.mutex); return -EPERM; - } info->port.flags = (info->port.flags & ~ASYNC_USR_MASK) | (new_serial.flags & ASYNC_USR_MASK); info->baud = new_serial.baud_base; @@ -2392,12 +2392,10 @@ cy_set_serial_info(struct cyclades_port *info, struct tty_struct *tty, check_and_exit: if (info->port.flags & ASYNC_INITIALIZED) { cy_set_line_char(info, tty); - ret = 0; + return 0; } else { - ret = cy_startup(info, tty); + return cy_startup(info, tty); } - mutex_unlock(&info->port.mutex); - return ret; } /* set_serial_info */ /* @@ -2440,6 +2438,7 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file) card = info->card; + lock_kernel(); if (!cy_is_Z(card)) { unsigned long flags; int channel = info->line - card->first_line; @@ -2479,6 +2478,7 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file) ((lstatus & C_RS_CTS) ? TIOCM_CTS : 0); } end: + unlock_kernel(); return result; } /* cy_tiomget */ @@ -2696,6 +2696,7 @@ cy_ioctl(struct tty_struct *tty, struct file *file, printk(KERN_DEBUG "cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n", info->line, cmd, arg); #endif + lock_kernel(); switch (cmd) { case CYGETMON: @@ -2816,6 +2817,7 @@ cy_ioctl(struct tty_struct *tty, struct file *file, default: ret_val = -ENOIOCTLCMD; } + unlock_kernel(); #ifdef CY_DEBUG_OTHER printk(KERN_DEBUG "cyc:cy_ioctl done\n"); diff --git a/trunk/drivers/char/epca.c b/trunk/drivers/char/epca.c index d9df46aa0fba..6f5ffe1320f7 100644 --- a/trunk/drivers/char/epca.c +++ b/trunk/drivers/char/epca.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include #include @@ -2105,6 +2105,7 @@ static int pc_ioctl(struct tty_struct *tty, struct file *file, break; case DIGI_SETAW: case DIGI_SETAF: + lock_kernel(); if (cmd == DIGI_SETAW) { /* Setup an event to indicate when the transmit buffer empties */ @@ -2117,6 +2118,7 @@ static int pc_ioctl(struct tty_struct *tty, struct file *file, if (tty->ldisc->ops->flush_buffer) tty->ldisc->ops->flush_buffer(tty); } + unlock_kernel(); /* Fall Thru */ case DIGI_SETA: if (copy_from_user(&ch->digiext, argp, sizeof(digi_t))) diff --git a/trunk/drivers/char/ip2/ip2main.c b/trunk/drivers/char/ip2/ip2main.c index 07f3ea38b582..911e1da6def2 100644 --- a/trunk/drivers/char/ip2/ip2main.c +++ b/trunk/drivers/char/ip2/ip2main.c @@ -1486,9 +1486,7 @@ ip2_open( PTTY tty, struct file *pFile ) if ( tty_hung_up_p(pFile) || ( pCh->flags & ASYNC_CLOSING )) { if ( pCh->flags & ASYNC_CLOSING ) { - tty_unlock(); schedule(); - tty_lock(); } if ( tty_hung_up_p(pFile) ) { set_current_state( TASK_RUNNING ); @@ -1550,9 +1548,7 @@ ip2_open( PTTY tty, struct file *pFile ) rc = (( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS); break; } - tty_unlock(); schedule(); - tty_lock(); } set_current_state( TASK_RUNNING ); remove_wait_queue(&pCh->open_wait, &wait); diff --git a/trunk/drivers/char/isicom.c b/trunk/drivers/char/isicom.c index c27e9d21fea9..98310e1aae30 100644 --- a/trunk/drivers/char/isicom.c +++ b/trunk/drivers/char/isicom.c @@ -124,6 +124,7 @@ #include #include #include +#include #include #include #include @@ -871,6 +872,7 @@ static struct tty_port *isicom_find_port(struct tty_struct *tty) static int isicom_open(struct tty_struct *tty, struct file *filp) { struct isi_port *port; + struct isi_board *card; struct tty_port *tport; tport = isicom_find_port(tty); @@ -1116,7 +1118,8 @@ static int isicom_set_serial_info(struct tty_struct *tty, if (copy_from_user(&newinfo, info, sizeof(newinfo))) return -EFAULT; - mutex_lock(&port->port.mutex); + lock_kernel(); + reconfig_port = ((port->port.flags & ASYNC_SPD_MASK) != (newinfo.flags & ASYNC_SPD_MASK)); @@ -1125,7 +1128,7 @@ static int isicom_set_serial_info(struct tty_struct *tty, (newinfo.closing_wait != port->port.closing_wait) || ((newinfo.flags & ~ASYNC_USR_MASK) != (port->port.flags & ~ASYNC_USR_MASK))) { - mutex_unlock(&port->port.mutex); + unlock_kernel(); return -EPERM; } port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) | @@ -1142,7 +1145,7 @@ static int isicom_set_serial_info(struct tty_struct *tty, isicom_config_port(tty); spin_unlock_irqrestore(&port->card->card_lock, flags); } - mutex_unlock(&port->port.mutex); + unlock_kernel(); return 0; } @@ -1151,7 +1154,7 @@ static int isicom_get_serial_info(struct isi_port *port, { struct serial_struct out_info; - mutex_lock(&port->port.mutex); + lock_kernel(); memset(&out_info, 0, sizeof(out_info)); /* out_info.type = ? */ out_info.line = port - isi_ports; @@ -1161,7 +1164,7 @@ static int isicom_get_serial_info(struct isi_port *port, /* out_info.baud_base = ? */ out_info.close_delay = port->port.close_delay; out_info.closing_wait = port->port.closing_wait; - mutex_unlock(&port->port.mutex); + unlock_kernel(); if (copy_to_user(info, &out_info, sizeof(out_info))) return -EFAULT; return 0; diff --git a/trunk/drivers/char/istallion.c b/trunk/drivers/char/istallion.c index be28391adb79..4e395c956a09 100644 --- a/trunk/drivers/char/istallion.c +++ b/trunk/drivers/char/istallion.c @@ -203,9 +203,9 @@ static int stli_shared; * the board has been detected, and whether it is actually running a slave * or not. */ -#define BST_FOUND 0 -#define BST_STARTED 1 -#define BST_PROBED 2 +#define BST_FOUND 0x1 +#define BST_STARTED 0x2 +#define BST_PROBED 0x4 /* * Define the set of port state flags. These are marked for internal @@ -816,7 +816,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp) brdp = stli_brds[brdnr]; if (brdp == NULL) return -ENODEV; - if (!test_bit(BST_STARTED, &brdp->state)) + if ((brdp->state & BST_STARTED) == 0) return -ENODEV; portnr = MINOR2PORT(minordev); if (portnr > brdp->nrports) @@ -954,7 +954,7 @@ static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned l * order of opens and closes may not be preserved across shared * memory, so we must wait until it is complete. */ - wait_event_interruptible_tty(portp->raw_wait, + wait_event_interruptible(portp->raw_wait, !test_bit(ST_CLOSING, &portp->state)); if (signal_pending(current)) { return -ERESTARTSYS; @@ -989,7 +989,7 @@ static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned l set_bit(ST_OPENING, &portp->state); spin_unlock_irqrestore(&brd_lock, flags); - wait_event_interruptible_tty(portp->raw_wait, + wait_event_interruptible(portp->raw_wait, !test_bit(ST_OPENING, &portp->state)); if (signal_pending(current)) rc = -ERESTARTSYS; @@ -1020,7 +1020,7 @@ static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned * occurs on this port. */ if (wait) { - wait_event_interruptible_tty(portp->raw_wait, + wait_event_interruptible(portp->raw_wait, !test_bit(ST_CLOSING, &portp->state)); if (signal_pending(current)) { return -ERESTARTSYS; @@ -1052,7 +1052,7 @@ static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned * to come back. */ rc = 0; - wait_event_interruptible_tty(portp->raw_wait, + wait_event_interruptible(portp->raw_wait, !test_bit(ST_CLOSING, &portp->state)); if (signal_pending(current)) rc = -ERESTARTSYS; @@ -1073,10 +1073,6 @@ static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback) { - /* - * no need for wait_event_tty because clearing ST_CMDING cannot block - * on BTM - */ wait_event_interruptible(portp->raw_wait, !test_bit(ST_CMDING, &portp->state)); if (signal_pending(current)) @@ -1850,7 +1846,7 @@ static void stli_portinfo(struct seq_file *m, struct stlibrd *brdp, struct stlip rc = stli_portcmdstats(NULL, portp); uart = "UNKNOWN"; - if (test_bit(BST_STARTED, &brdp->state)) { + if (brdp->state & BST_STARTED) { switch (stli_comstats.hwid) { case 0: uart = "2681"; break; case 1: uart = "SC26198"; break; @@ -1859,7 +1855,7 @@ static void stli_portinfo(struct seq_file *m, struct stlibrd *brdp, struct stlip } seq_printf(m, "%d: uart:%s ", portnr, uart); - if (test_bit(BST_STARTED, &brdp->state) && rc >= 0) { + if ((brdp->state & BST_STARTED) && (rc >= 0)) { char sep; seq_printf(m, "tx:%d rx:%d", (int) stli_comstats.txtotal, @@ -2359,7 +2355,7 @@ static void stli_poll(unsigned long arg) brdp = stli_brds[brdnr]; if (brdp == NULL) continue; - if (!test_bit(BST_STARTED, &brdp->state)) + if ((brdp->state & BST_STARTED) == 0) continue; spin_lock(&brd_lock); @@ -3144,7 +3140,7 @@ static int stli_initecp(struct stlibrd *brdp) } - set_bit(BST_FOUND, &brdp->state); + brdp->state |= BST_FOUND; return 0; err_unmap: iounmap(brdp->membase); @@ -3301,7 +3297,7 @@ static int stli_initonb(struct stlibrd *brdp) brdp->panels[0] = brdp->nrports; - set_bit(BST_FOUND, &brdp->state); + brdp->state |= BST_FOUND; return 0; err_unmap: iounmap(brdp->membase); @@ -3411,7 +3407,7 @@ static int stli_startbrd(struct stlibrd *brdp) spin_unlock_irqrestore(&brd_lock, flags); if (rc == 0) - set_bit(BST_STARTED, &brdp->state); + brdp->state |= BST_STARTED; if (! stli_timeron) { stli_timeron++; @@ -3714,7 +3710,7 @@ static int __devinit stli_pciprobe(struct pci_dev *pdev, if (retval) goto err_null; - set_bit(BST_PROBED, &brdp->state); + brdp->state |= BST_PROBED; pci_set_drvdata(pdev, brdp); EBRDENABLE(brdp); @@ -3845,7 +3841,7 @@ static int __init stli_initbrds(void) brdp = stli_brds[i]; if (brdp == NULL) continue; - if (test_bit(BST_FOUND, &brdp->state)) { + if (brdp->state & BST_FOUND) { EBRDENABLE(brdp); brdp->enable = NULL; brdp->disable = NULL; @@ -4015,7 +4011,6 @@ static int stli_getbrdstats(combrd_t __user *bp) return -ENODEV; memset(&stli_brdstats, 0, sizeof(combrd_t)); - stli_brdstats.brd = brdp->brdnr; stli_brdstats.type = brdp->brdtype; stli_brdstats.hwid = 0; @@ -4081,13 +4076,10 @@ static int stli_portcmdstats(struct tty_struct *tty, struct stliport *portp) if (brdp == NULL) return -ENODEV; - mutex_lock(&portp->port.mutex); - if (test_bit(BST_STARTED, &brdp->state)) { + if (brdp->state & BST_STARTED) { if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS, - &stli_cdkstats, sizeof(asystats_t), 1)) < 0) { - mutex_unlock(&portp->port.mutex); + &stli_cdkstats, sizeof(asystats_t), 1)) < 0) return rc; - } } else { memset(&stli_cdkstats, 0, sizeof(asystats_t)); } @@ -4132,7 +4124,6 @@ static int stli_portcmdstats(struct tty_struct *tty, struct stliport *portp) stli_comstats.modem = stli_cdkstats.dcdcnt; stli_comstats.hwid = stli_cdkstats.hwid; stli_comstats.signals = stli_mktiocm(stli_cdkstats.signals); - mutex_unlock(&portp->port.mutex); return 0; } @@ -4195,20 +4186,15 @@ static int stli_clrportstats(struct stliport *portp, comstats_t __user *cp) if (!brdp) return -ENODEV; - mutex_lock(&portp->port.mutex); - - if (test_bit(BST_STARTED, &brdp->state)) { - if ((rc = stli_cmdwait(brdp, portp, A_CLEARSTATS, NULL, 0, 0)) < 0) { - mutex_unlock(&portp->port.mutex); + if (brdp->state & BST_STARTED) { + if ((rc = stli_cmdwait(brdp, portp, A_CLEARSTATS, NULL, 0, 0)) < 0) return rc; - } } memset(&stli_comstats, 0, sizeof(comstats_t)); stli_comstats.brd = portp->brdnr; stli_comstats.panel = portp->panelnr; stli_comstats.port = portp->portnr; - mutex_unlock(&portp->port.mutex); if (copy_to_user(cp, &stli_comstats, sizeof(comstats_t))) return -EFAULT; @@ -4280,6 +4266,8 @@ static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) done = 0; rc = 0; + lock_kernel(); + switch (cmd) { case COM_GETPORTSTATS: rc = stli_getportstats(NULL, NULL, argp); @@ -4302,6 +4290,8 @@ static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) done++; break; } + unlock_kernel(); + if (done) return rc; @@ -4318,6 +4308,8 @@ static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) if (brdp->state == 0) return -ENODEV; + lock_kernel(); + switch (cmd) { case STL_BINTR: EBRDINTR(brdp); @@ -4326,10 +4318,10 @@ static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) rc = stli_startbrd(brdp); break; case STL_BSTOP: - clear_bit(BST_STARTED, &brdp->state); + brdp->state &= ~BST_STARTED; break; case STL_BRESET: - clear_bit(BST_STARTED, &brdp->state); + brdp->state &= ~BST_STARTED; EBRDRESET(brdp); if (stli_shared == 0) { if (brdp->reenable != NULL) @@ -4340,6 +4332,7 @@ static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) rc = -ENOIOCTLCMD; break; } + unlock_kernel(); return rc; } @@ -4385,8 +4378,7 @@ static void istallion_cleanup_isa(void) unsigned int j; for (j = 0; (j < stli_nrbrds); j++) { - if ((brdp = stli_brds[j]) == NULL || - test_bit(BST_PROBED, &brdp->state)) + if ((brdp = stli_brds[j]) == NULL || (brdp->state & BST_PROBED)) continue; stli_cleanup_ports(brdp); diff --git a/trunk/drivers/char/keyboard.c b/trunk/drivers/char/keyboard.c index a7ca75212bfe..25be2102a60a 100644 --- a/trunk/drivers/char/keyboard.c +++ b/trunk/drivers/char/keyboard.c @@ -299,7 +299,7 @@ int kbd_rate(struct kbd_repeat *rep) */ static void put_queue(struct vc_data *vc, int ch) { - struct tty_struct *tty = vc->port.tty; + struct tty_struct *tty = vc->vc_tty; if (tty) { tty_insert_flip_char(tty, ch, 0); @@ -309,7 +309,7 @@ static void put_queue(struct vc_data *vc, int ch) static void puts_queue(struct vc_data *vc, char *cp) { - struct tty_struct *tty = vc->port.tty; + struct tty_struct *tty = vc->vc_tty; if (!tty) return; @@ -485,7 +485,7 @@ static void fn_show_ptregs(struct vc_data *vc) static void fn_hold(struct vc_data *vc) { - struct tty_struct *tty = vc->port.tty; + struct tty_struct *tty = vc->vc_tty; if (rep || !tty) return; @@ -563,7 +563,7 @@ static void fn_inc_console(struct vc_data *vc) static void fn_send_intr(struct vc_data *vc) { - struct tty_struct *tty = vc->port.tty; + struct tty_struct *tty = vc->vc_tty; if (!tty) return; @@ -1162,7 +1162,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) struct keyboard_notifier_param param = { .vc = vc, .value = keycode, .down = down }; int rc; - tty = vc->port.tty; + tty = vc->vc_tty; if (tty && (!tty->driver_data)) { /* No driver data? Strange. Okay we fix it then. */ diff --git a/trunk/drivers/char/mxser.c b/trunk/drivers/char/mxser.c index 3fc89da856ae..d2692d443f7b 100644 --- a/trunk/drivers/char/mxser.c +++ b/trunk/drivers/char/mxser.c @@ -2193,7 +2193,7 @@ static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port port->mon_data.up_txcnt += (cnt - port->xmit_cnt); port->icount.tx += (cnt - port->xmit_cnt); - if (port->xmit_cnt < WAKEUP_CHARS) + if (port->xmit_cnt < WAKEUP_CHARS && tty) tty_wakeup(tty); if (port->xmit_cnt <= 0) { diff --git a/trunk/drivers/char/n_gsm.c b/trunk/drivers/char/n_gsm.c index 099105e0894e..e4089c432f15 100644 --- a/trunk/drivers/char/n_gsm.c +++ b/trunk/drivers/char/n_gsm.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/char/n_hdlc.c b/trunk/drivers/char/n_hdlc.c index 47d32281032c..c68118efad84 100644 --- a/trunk/drivers/char/n_hdlc.c +++ b/trunk/drivers/char/n_hdlc.c @@ -598,18 +598,18 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, return -EFAULT; } - tty_lock(); + lock_kernel(); for (;;) { if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { - tty_unlock(); + unlock_kernel(); return -EIO; } n_hdlc = tty2n_hdlc (tty); if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC || tty != n_hdlc->tty) { - tty_unlock(); + unlock_kernel(); return 0; } @@ -619,13 +619,13 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, /* no data */ if (file->f_flags & O_NONBLOCK) { - tty_unlock(); + unlock_kernel(); return -EAGAIN; } interruptible_sleep_on (&tty->read_wait); if (signal_pending(current)) { - tty_unlock(); + unlock_kernel(); return -EINTR; } } @@ -648,7 +648,7 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, kfree(rbuf); else n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,rbuf); - tty_unlock(); + unlock_kernel(); return ret; } /* end of n_hdlc_tty_read() */ @@ -691,7 +691,7 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, count = maxframe; } - tty_lock(); + lock_kernel(); add_wait_queue(&tty->write_wait, &wait); set_current_state(TASK_INTERRUPTIBLE); @@ -731,7 +731,7 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf); n_hdlc_send_frames(n_hdlc,tty); } - tty_unlock(); + unlock_kernel(); return error; } /* end of n_hdlc_tty_write() */ diff --git a/trunk/drivers/char/n_r3964.c b/trunk/drivers/char/n_r3964.c index a98290d7a2c5..c1d8b54c816d 100644 --- a/trunk/drivers/char/n_r3964.c +++ b/trunk/drivers/char/n_r3964.c @@ -1067,7 +1067,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, TRACE_L("read()"); - tty_lock(); + lock_kernel(); pClient = findClient(pInfo, task_pid(current)); if (pClient) { @@ -1079,7 +1079,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, goto unlock; } /* block until there is a message: */ - wait_event_interruptible_tty(pInfo->read_wait, + wait_event_interruptible(pInfo->read_wait, (pMsg = remove_msg(pInfo, pClient))); } @@ -1109,7 +1109,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, } ret = -EPERM; unlock: - tty_unlock(); + unlock_kernel(); return ret; } @@ -1158,7 +1158,7 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file, pHeader->locks = 0; pHeader->owner = NULL; - tty_lock(); + lock_kernel(); pClient = findClient(pInfo, task_pid(current)); if (pClient) { @@ -1177,7 +1177,7 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file, add_tx_queue(pInfo, pHeader); trigger_transmit(pInfo); - tty_unlock(); + unlock_kernel(); return 0; } diff --git a/trunk/drivers/char/n_tty.c b/trunk/drivers/char/n_tty.c index 428f4fe0b5f7..bdae8327143c 100644 --- a/trunk/drivers/char/n_tty.c +++ b/trunk/drivers/char/n_tty.c @@ -1102,11 +1102,6 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) if (I_IUCLC(tty) && L_IEXTEN(tty)) c = tolower(c); - if (L_EXTPROC(tty)) { - put_tty_queue(c, tty); - return; - } - if (tty->stopped && !tty->flow_stopped && I_IXON(tty) && I_IXANY(tty) && c != START_CHAR(tty) && c != STOP_CHAR(tty) && c != INTR_CHAR(tty) && c != QUIT_CHAR(tty) && c != SUSP_CHAR(tty)) { @@ -1414,8 +1409,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, n_tty_set_room(tty); - if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) || - L_EXTPROC(tty)) { + if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) { kill_fasync(&tty->fasync, SIGIO, POLL_IN); if (waitqueue_active(&tty->read_wait)) wake_up_interruptible(&tty->read_wait); @@ -1591,7 +1585,7 @@ static int n_tty_open(struct tty_struct *tty) static inline int input_available_p(struct tty_struct *tty, int amt) { tty_flush_to_ldisc(tty); - if (tty->icanon && !L_EXTPROC(tty)) { + if (tty->icanon) { if (tty->canon_data) return 1; } else if (tty->read_cnt >= (amt ? amt : 1)) @@ -1638,11 +1632,6 @@ static int copy_from_read_buf(struct tty_struct *tty, spin_lock_irqsave(&tty->read_lock, flags); tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1); tty->read_cnt -= n; - /* Turn single EOF into zero-length read */ - if (L_EXTPROC(tty) && tty->icanon && n == 1) { - if (!tty->read_cnt && (*b)[n-1] == EOF_CHAR(tty)) - n--; - } spin_unlock_irqrestore(&tty->read_lock, flags); *b += n; *nr -= n; @@ -1823,7 +1812,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, nr--; } - if (tty->icanon && !L_EXTPROC(tty)) { + if (tty->icanon) { /* N.B. avoid overrun if nr == 0 */ while (nr && tty->read_cnt) { int eol; diff --git a/trunk/drivers/char/nozomi.c b/trunk/drivers/char/nozomi.c index 18af923093c3..a6638003f530 100644 --- a/trunk/drivers/char/nozomi.c +++ b/trunk/drivers/char/nozomi.c @@ -1611,8 +1611,6 @@ static int ntty_install(struct tty_driver *driver, struct tty_struct *tty) ret = tty_init_termios(tty); if (ret == 0) { tty_driver_kref_get(driver); - tty->count++; - tty->driver_data = port; driver->ttys[tty->index] = tty; } return ret; @@ -1641,7 +1639,7 @@ static int ntty_activate(struct tty_port *tport, struct tty_struct *tty) static int ntty_open(struct tty_struct *tty, struct file *filp) { - struct port *port = tty->driver_data; + struct port *port = get_port_by_tty(tty); return tty_port_open(&port->port, tty, filp); } diff --git a/trunk/drivers/char/pty.c b/trunk/drivers/char/pty.c index ad46eae1f9bb..d83a43130df4 100644 --- a/trunk/drivers/char/pty.c +++ b/trunk/drivers/char/pty.c @@ -62,9 +62,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp) if (tty->driver == ptm_driver) devpts_pty_kill(tty->link); #endif - tty_unlock(); tty_vhangup(tty->link); - tty_lock(); } } @@ -173,23 +171,6 @@ static int pty_set_lock(struct tty_struct *tty, int __user *arg) return 0; } -/* Send a signal to the slave */ -static int pty_signal(struct tty_struct *tty, int sig) -{ - unsigned long flags; - struct pid *pgrp; - - if (tty->link) { - spin_lock_irqsave(&tty->link->ctrl_lock, flags); - pgrp = get_pid(tty->link->pgrp); - spin_unlock_irqrestore(&tty->link->ctrl_lock, flags); - - kill_pgrp(pgrp, sig, 1); - put_pid(pgrp); - } - return 0; -} - static void pty_flush_buffer(struct tty_struct *tty) { struct tty_struct *to = tty->link; @@ -340,8 +321,6 @@ static int pty_bsd_ioctl(struct tty_struct *tty, struct file *file, switch (cmd) { case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */ return pty_set_lock(tty, (int __user *) arg); - case TIOCSIG: /* Send signal to other side of pty */ - return pty_signal(tty, (int) arg); } return -ENOIOCTLCMD; } @@ -497,8 +476,6 @@ static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file, return pty_set_lock(tty, (int __user *)arg); case TIOCGPTN: /* Get PT Number */ return put_user(tty->index, (unsigned int __user *)arg); - case TIOCSIG: /* Send signal to other side of pty */ - return pty_signal(tty, (int) arg); } return -ENOIOCTLCMD; @@ -649,7 +626,7 @@ static const struct tty_operations pty_unix98_ops = { * allocated_ptys_lock handles the list of free pty numbers */ -static int ptmx_open(struct inode *inode, struct file *filp) +static int __ptmx_open(struct inode *inode, struct file *filp) { struct tty_struct *tty; int retval; @@ -658,14 +635,11 @@ static int ptmx_open(struct inode *inode, struct file *filp) nonseekable_open(inode, filp); /* find a device that is not in use. */ - tty_lock(); index = devpts_new_index(inode); - tty_unlock(); if (index < 0) return index; mutex_lock(&tty_mutex); - tty_lock(); tty = tty_init_dev(ptm_driver, index, 1); mutex_unlock(&tty_mutex); @@ -683,21 +657,26 @@ static int ptmx_open(struct inode *inode, struct file *filp) goto out1; retval = ptm_driver->ops->open(tty, filp); - if (retval) - goto out2; + if (!retval) + return 0; out1: - tty_unlock(); - return retval; -out2: - tty_unlock(); tty_release(inode, filp); return retval; out: devpts_kill_index(inode, index); - tty_unlock(); return retval; } +static int ptmx_open(struct inode *inode, struct file *filp) +{ + int ret; + + lock_kernel(); + ret = __ptmx_open(inode, filp); + unlock_kernel(); + return ret; +} + static struct file_operations ptmx_fops; static void __init unix98_pty_init(void) diff --git a/trunk/drivers/char/riscom8.c b/trunk/drivers/char/riscom8.c index af4de1fe8445..b02332a5412f 100644 --- a/trunk/drivers/char/riscom8.c +++ b/trunk/drivers/char/riscom8.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -1183,7 +1184,6 @@ static int rc_set_serial_info(struct tty_struct *tty, struct riscom_port *port, if (copy_from_user(&tmp, newinfo, sizeof(tmp))) return -EFAULT; - mutex_lock(&port->port.mutex); change_speed = ((port->port.flags & ASYNC_SPD_MASK) != (tmp.flags & ASYNC_SPD_MASK)); @@ -1191,10 +1191,8 @@ static int rc_set_serial_info(struct tty_struct *tty, struct riscom_port *port, if ((tmp.close_delay != port->port.close_delay) || (tmp.closing_wait != port->port.closing_wait) || ((tmp.flags & ~ASYNC_USR_MASK) != - (port->port.flags & ~ASYNC_USR_MASK))) { - mutex_unlock(&port->port.mutex); + (port->port.flags & ~ASYNC_USR_MASK))) return -EPERM; - } port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) | (tmp.flags & ASYNC_USR_MASK)); } else { @@ -1210,7 +1208,6 @@ static int rc_set_serial_info(struct tty_struct *tty, struct riscom_port *port, rc_change_speed(tty, bp, port); spin_unlock_irqrestore(&riscom_lock, flags); } - mutex_unlock(&port->port.mutex); return 0; } @@ -1223,15 +1220,12 @@ static int rc_get_serial_info(struct riscom_port *port, memset(&tmp, 0, sizeof(tmp)); tmp.type = PORT_CIRRUS; tmp.line = port - rc_port; - - mutex_lock(&port->port.mutex); tmp.port = bp->base; tmp.irq = bp->irq; tmp.flags = port->port.flags; tmp.baud_base = (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC; tmp.close_delay = port->port.close_delay * HZ/100; tmp.closing_wait = port->port.closing_wait * HZ/100; - mutex_unlock(&port->port.mutex); tmp.xmit_fifo_size = CD180_NFIFO; return copy_to_user(retinfo, &tmp, sizeof(tmp)) ? -EFAULT : 0; } @@ -1248,10 +1242,14 @@ static int rc_ioctl(struct tty_struct *tty, struct file *filp, switch (cmd) { case TIOCGSERIAL: + lock_kernel(); retval = rc_get_serial_info(port, argp); + unlock_kernel(); break; case TIOCSSERIAL: + lock_kernel(); retval = rc_set_serial_info(tty, port, argp); + unlock_kernel(); break; default: retval = -ENOIOCTLCMD; diff --git a/trunk/drivers/char/rocket.c b/trunk/drivers/char/rocket.c index 79c3bc69165a..0e29a23ec4c5 100644 --- a/trunk/drivers/char/rocket.c +++ b/trunk/drivers/char/rocket.c @@ -73,6 +73,7 @@ #include #include #include +#include #include #include #include @@ -1016,7 +1017,6 @@ static void rp_close(struct tty_struct *tty, struct file *filp) if (tty_port_close_start(port, tty, filp) == 0) return; - mutex_lock(&port->mutex); cp = &info->channel; /* * Before we drop DTR, make sure the UART transmitter @@ -1060,13 +1060,9 @@ static void rp_close(struct tty_struct *tty, struct file *filp) info->xmit_buf = NULL; } } - spin_lock_irq(&port->lock); info->port.flags &= ~(ASYNC_INITIALIZED | ASYNC_CLOSING | ASYNC_NORMAL_ACTIVE); tty->closing = 0; - spin_unlock_irq(&port->lock); - mutex_unlock(&port->mutex); tty_port_tty_set(port, NULL); - wake_up_interruptible(&port->close_wait); complete_all(&info->close_wait); atomic_dec(&rp_num_ports_open); @@ -1214,13 +1210,11 @@ static int get_config(struct r_port *info, struct rocket_config __user *retinfo) if (!retinfo) return -EFAULT; memset(&tmp, 0, sizeof (tmp)); - mutex_lock(&info->port.mutex); tmp.line = info->line; tmp.flags = info->flags; tmp.close_delay = info->port.close_delay; tmp.closing_wait = info->port.closing_wait; tmp.port = rcktpt_io_addr[(info->line >> 5) & 3]; - mutex_unlock(&info->port.mutex); if (copy_to_user(retinfo, &tmp, sizeof (*retinfo))) return -EFAULT; @@ -1235,13 +1229,10 @@ static int set_config(struct tty_struct *tty, struct r_port *info, if (copy_from_user(&new_serial, new_info, sizeof (new_serial))) return -EFAULT; - mutex_lock(&info->port.mutex); if (!capable(CAP_SYS_ADMIN)) { - if ((new_serial.flags & ~ROCKET_USR_MASK) != (info->flags & ~ROCKET_USR_MASK)) { - mutex_unlock(&info->port.mutex); + if ((new_serial.flags & ~ROCKET_USR_MASK) != (info->flags & ~ROCKET_USR_MASK)) return -EPERM; - } info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK)); configure_r_port(tty, info, NULL); return 0; @@ -1259,7 +1250,6 @@ static int set_config(struct tty_struct *tty, struct r_port *info, tty->alt_speed = 230400; if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP) tty->alt_speed = 460800; - mutex_unlock(&info->port.mutex); configure_r_port(tty, info, NULL); return 0; @@ -1335,6 +1325,8 @@ static int rp_ioctl(struct tty_struct *tty, struct file *file, if (cmd != RCKP_GET_PORTS && rocket_paranoia_check(info, "rp_ioctl")) return -ENXIO; + lock_kernel(); + switch (cmd) { case RCKP_GET_STRUCT: if (copy_to_user(argp, info, sizeof (struct r_port))) @@ -1358,6 +1350,7 @@ static int rp_ioctl(struct tty_struct *tty, struct file *file, default: ret = -ENOIOCTLCMD; } + unlock_kernel(); return ret; } @@ -1478,6 +1471,7 @@ static void rp_wait_until_sent(struct tty_struct *tty, int timeout) jiffies); printk(KERN_INFO "cps=%d...\n", info->cps); #endif + lock_kernel(); while (1) { txcnt = sGetTxCnt(cp); if (!txcnt) { @@ -1505,6 +1499,7 @@ static void rp_wait_until_sent(struct tty_struct *tty, int timeout) break; } __set_current_state(TASK_RUNNING); + unlock_kernel(); #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies); #endif @@ -1517,7 +1512,6 @@ static void rp_hangup(struct tty_struct *tty) { CHANNEL_t *cp; struct r_port *info = tty->driver_data; - unsigned long flags; if (rocket_paranoia_check(info, "rp_hangup")) return; @@ -1526,15 +1520,11 @@ static void rp_hangup(struct tty_struct *tty) printk(KERN_INFO "rp_hangup of ttyR%d...\n", info->line); #endif rp_flush_buffer(tty); - spin_lock_irqsave(&info->port.lock, flags); - if (info->port.flags & ASYNC_CLOSING) { - spin_unlock_irqrestore(&info->port.lock, flags); + if (info->port.flags & ASYNC_CLOSING) return; - } if (info->port.count) atomic_dec(&rp_num_ports_open); clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); - spin_unlock_irqrestore(&info->port.lock, flags); tty_port_hangup(&info->port); @@ -1545,7 +1535,7 @@ static void rp_hangup(struct tty_struct *tty) sDisCTSFlowCtl(cp); sDisTxSoftFlowCtl(cp); sClrTxXOFF(cp); - clear_bit(ASYNCB_INITIALIZED, &info->port.flags); + info->port.flags &= ~ASYNC_INITIALIZED; wake_up_interruptible(&info->port.open_wait); } diff --git a/trunk/drivers/char/selection.c b/trunk/drivers/char/selection.c index ebae344ce910..f97b9e848064 100644 --- a/trunk/drivers/char/selection.c +++ b/trunk/drivers/char/selection.c @@ -26,7 +26,6 @@ #include #include #include -#include /* Don't take this from : 011-015 on the screen aren't spaces */ #define isspace(c) ((c) == ' ') @@ -313,20 +312,12 @@ int paste_selection(struct tty_struct *tty) struct tty_ldisc *ld; DECLARE_WAITQUEUE(wait, current); - /* always called with BTM from vt_ioctl */ - WARN_ON(!tty_locked()); - acquire_console_sem(); poke_blanked_console(); release_console_sem(); - ld = tty_ldisc_ref(tty); - if (!ld) { - tty_unlock(); - ld = tty_ldisc_ref_wait(tty); - tty_lock(); - } - + ld = tty_ldisc_ref_wait(tty); + add_wait_queue(&vc->paste_wait, &wait); while (sel_buffer && sel_buffer_lth > pasted) { set_current_state(TASK_INTERRUPTIBLE); diff --git a/trunk/drivers/char/serial167.c b/trunk/drivers/char/serial167.c index f646725bd567..ecbe479c7d68 100644 --- a/trunk/drivers/char/serial167.c +++ b/trunk/drivers/char/serial167.c @@ -1505,7 +1505,7 @@ cy_ioctl(struct tty_struct *tty, struct file *file, printk("cy_ioctl %s, cmd = %x arg = %lx\n", tty->name, cmd, arg); /* */ #endif - tty_lock(); + lock_kernel(); switch (cmd) { case CYGETMON: @@ -1561,7 +1561,7 @@ cy_ioctl(struct tty_struct *tty, struct file *file, default: ret_val = -ENOIOCTLCMD; } - tty_unlock(); + unlock_kernel(); #ifdef SERIAL_DEBUG_OTHER printk("cy_ioctl done\n"); @@ -1786,9 +1786,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp, tty->name, info->count); /**/ #endif - tty_unlock(); - schedule(); - tty_lock(); + schedule(); } __set_current_state(TASK_RUNNING); remove_wait_queue(&info->open_wait, &wait); diff --git a/trunk/drivers/char/specialix.c b/trunk/drivers/char/specialix.c index 9f8495b4fc8f..2c24fcdc722a 100644 --- a/trunk/drivers/char/specialix.c +++ b/trunk/drivers/char/specialix.c @@ -1365,9 +1365,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, retval = -ERESTARTSYS; break; } - tty_unlock(); schedule(); - tty_lock(); } set_current_state(TASK_RUNNING); @@ -1865,7 +1863,8 @@ static int sx_set_serial_info(struct specialix_port *port, return -EFAULT; } - mutex_lock(&port->port.mutex); + lock_kernel(); + change_speed = ((port->port.flags & ASYNC_SPD_MASK) != (tmp.flags & ASYNC_SPD_MASK)); change_speed |= (tmp.custom_divisor != port->custom_divisor); @@ -1876,7 +1875,7 @@ static int sx_set_serial_info(struct specialix_port *port, ((tmp.flags & ~ASYNC_USR_MASK) != (port->port.flags & ~ASYNC_USR_MASK))) { func_exit(); - mutex_unlock(&port->port.mutex); + unlock_kernel(); return -EPERM; } port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) | @@ -1893,7 +1892,7 @@ static int sx_set_serial_info(struct specialix_port *port, sx_change_speed(bp, port); func_exit(); - mutex_unlock(&port->port.mutex); + unlock_kernel(); return 0; } @@ -1907,7 +1906,7 @@ static int sx_get_serial_info(struct specialix_port *port, func_enter(); memset(&tmp, 0, sizeof(tmp)); - mutex_lock(&port->port.mutex); + lock_kernel(); tmp.type = PORT_CIRRUS; tmp.line = port - sx_port; tmp.port = bp->base; @@ -1918,7 +1917,7 @@ static int sx_get_serial_info(struct specialix_port *port, tmp.closing_wait = port->port.closing_wait * HZ/100; tmp.custom_divisor = port->custom_divisor; tmp.xmit_fifo_size = CD186x_NFIFO; - mutex_unlock(&port->port.mutex); + unlock_kernel(); if (copy_to_user(retinfo, &tmp, sizeof(tmp))) { func_exit(); return -EFAULT; diff --git a/trunk/drivers/char/stallion.c b/trunk/drivers/char/stallion.c index f2167f8e5aab..6049fd731924 100644 --- a/trunk/drivers/char/stallion.c +++ b/trunk/drivers/char/stallion.c @@ -807,6 +807,7 @@ static void stl_waituntilsent(struct tty_struct *tty, int timeout) timeout = HZ; tend = jiffies + timeout; + lock_kernel(); while (stl_datastate(portp)) { if (signal_pending(current)) break; @@ -814,6 +815,7 @@ static void stl_waituntilsent(struct tty_struct *tty, int timeout) if (time_after_eq(jiffies, tend)) break; } + unlock_kernel(); } /*****************************************************************************/ @@ -1027,8 +1029,6 @@ static int stl_getserial(struct stlport *portp, struct serial_struct __user *sp) pr_debug("stl_getserial(portp=%p,sp=%p)\n", portp, sp); memset(&sio, 0, sizeof(struct serial_struct)); - - mutex_lock(&portp->port.mutex); sio.line = portp->portnr; sio.port = portp->ioaddr; sio.flags = portp->port.flags; @@ -1048,7 +1048,6 @@ static int stl_getserial(struct stlport *portp, struct serial_struct __user *sp) brdp = stl_brds[portp->brdnr]; if (brdp != NULL) sio.irq = brdp->irq; - mutex_unlock(&portp->port.mutex); return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ? -EFAULT : 0; } @@ -1070,15 +1069,12 @@ static int stl_setserial(struct tty_struct *tty, struct serial_struct __user *sp if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) return -EFAULT; - mutex_lock(&portp->port.mutex); if (!capable(CAP_SYS_ADMIN)) { if ((sio.baud_base != portp->baud_base) || (sio.close_delay != portp->close_delay) || ((sio.flags & ~ASYNC_USR_MASK) != - (portp->port.flags & ~ASYNC_USR_MASK))) { - mutex_unlock(&portp->port.mutex); + (portp->port.flags & ~ASYNC_USR_MASK))) return -EPERM; - } } portp->port.flags = (portp->port.flags & ~ASYNC_USR_MASK) | @@ -1087,7 +1083,6 @@ static int stl_setserial(struct tty_struct *tty, struct serial_struct __user *sp portp->close_delay = sio.close_delay; portp->closing_wait = sio.closing_wait; portp->custom_divisor = sio.custom_divisor; - mutex_unlock(&portp->port.mutex); stl_setport(portp, tty->termios); return 0; } @@ -1152,6 +1147,8 @@ static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd rc = 0; + lock_kernel(); + switch (cmd) { case TIOCGSERIAL: rc = stl_getserial(portp, argp); @@ -1176,6 +1173,7 @@ static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd rc = -ENOIOCTLCMD; break; } + unlock_kernel(); return rc; } @@ -2329,7 +2327,6 @@ static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comst return -ENODEV; } - mutex_lock(&portp->port.mutex); portp->stats.state = portp->istate; portp->stats.flags = portp->port.flags; portp->stats.hwid = portp->hwid; @@ -2361,7 +2358,6 @@ static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comst (STL_TXBUFSIZE - (tail - head)); portp->stats.signals = (unsigned long) stl_getsignals(portp); - mutex_unlock(&portp->port.mutex); return copy_to_user(cp, &portp->stats, sizeof(comstats_t)) ? -EFAULT : 0; @@ -2386,12 +2382,10 @@ static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp) return -ENODEV; } - mutex_lock(&portp->port.mutex); memset(&portp->stats, 0, sizeof(comstats_t)); portp->stats.brd = portp->brdnr; portp->stats.panel = portp->panelnr; portp->stats.port = portp->portnr; - mutex_unlock(&portp->port.mutex); return copy_to_user(cp, &portp->stats, sizeof(comstats_t)) ? -EFAULT : 0; } @@ -2457,6 +2451,7 @@ static long stl_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) return -ENODEV; rc = 0; + lock_kernel(); switch (cmd) { case COM_GETPORTSTATS: rc = stl_getportstats(NULL, NULL, argp); @@ -2477,6 +2472,7 @@ static long stl_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) rc = -ENOIOCTLCMD; break; } + unlock_kernel(); return rc; } diff --git a/trunk/drivers/char/sx.c b/trunk/drivers/char/sx.c index 5b24db4ff7f1..a81ec4fcf6ff 100644 --- a/trunk/drivers/char/sx.c +++ b/trunk/drivers/char/sx.c @@ -1699,7 +1699,7 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd, if (!capable(CAP_SYS_RAWIO)) return -EPERM; - tty_lock(); + lock_kernel(); sx_dprintk(SX_DEBUG_FIRMWARE, "IOCTL %x: %lx\n", cmd, arg); @@ -1848,7 +1848,7 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd, break; } out: - tty_unlock(); + unlock_kernel(); func_exit(); return rc; } @@ -1859,7 +1859,7 @@ static int sx_break(struct tty_struct *tty, int flag) int rv; func_enter(); - tty_lock(); + lock_kernel(); if (flag) rv = sx_send_command(port, HS_START, -1, HS_IDLE_BREAK); @@ -1868,7 +1868,7 @@ static int sx_break(struct tty_struct *tty, int flag) if (rv != 1) printk(KERN_ERR "sx: couldn't send break (%x).\n", read_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat))); - tty_unlock(); + unlock_kernel(); func_exit(); return 0; } @@ -1909,7 +1909,7 @@ static int sx_ioctl(struct tty_struct *tty, struct file *filp, /* func_enter2(); */ rc = 0; - tty_lock(); + lock_kernel(); switch (cmd) { case TIOCGSERIAL: rc = gs_getserial(&port->gs, argp); @@ -1921,7 +1921,7 @@ static int sx_ioctl(struct tty_struct *tty, struct file *filp, rc = -ENOIOCTLCMD; break; } - tty_unlock(); + unlock_kernel(); /* func_exit(); */ return rc; diff --git a/trunk/drivers/char/synclink.c b/trunk/drivers/char/synclink.c index a2a58004e188..0658fc548222 100644 --- a/trunk/drivers/char/synclink.c +++ b/trunk/drivers/char/synclink.c @@ -81,6 +81,7 @@ #include #include #include +#include #include #include #include @@ -2435,9 +2436,7 @@ static int mgsl_get_stats(struct mgsl_struct * info, struct mgsl_icount __user * if (!user_icount) { memset(&info->icount, 0, sizeof(info->icount)); } else { - mutex_lock(&info->port.mutex); COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount)); - mutex_unlock(&info->port.mutex); if (err) return -EFAULT; } @@ -2462,9 +2461,7 @@ static int mgsl_get_params(struct mgsl_struct * info, MGSL_PARAMS __user *user_p printk("%s(%d):mgsl_get_params(%s)\n", __FILE__,__LINE__, info->device_name); - mutex_lock(&info->port.mutex); COPY_TO_USER(err,user_params, &info->params, sizeof(MGSL_PARAMS)); - mutex_unlock(&info->port.mutex); if (err) { if ( debug_level >= DEBUG_LEVEL_INFO ) printk( "%s(%d):mgsl_get_params(%s) user buffer copy failed\n", @@ -2504,13 +2501,11 @@ static int mgsl_set_params(struct mgsl_struct * info, MGSL_PARAMS __user *new_pa return -EFAULT; } - mutex_lock(&info->port.mutex); spin_lock_irqsave(&info->irq_spinlock,flags); memcpy(&info->params,&tmp_params,sizeof(MGSL_PARAMS)); spin_unlock_irqrestore(&info->irq_spinlock,flags); mgsl_change_params(info); - mutex_unlock(&info->port.mutex); return 0; @@ -2940,6 +2935,7 @@ static int mgsl_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) { struct mgsl_struct * info = tty->driver_data; + int ret; if (debug_level >= DEBUG_LEVEL_INFO) printk("%s(%d):mgsl_ioctl %s cmd=%08X\n", __FILE__,__LINE__, @@ -2954,7 +2950,10 @@ static int mgsl_ioctl(struct tty_struct *tty, struct file * file, return -EIO; } - return mgsl_ioctl_common(info, cmd, arg); + lock_kernel(); + ret = mgsl_ioctl_common(info, cmd, arg); + unlock_kernel(); + return ret; } static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg) @@ -3110,14 +3109,12 @@ static void mgsl_close(struct tty_struct *tty, struct file * filp) if (tty_port_close_start(&info->port, tty, filp) == 0) goto cleanup; - - mutex_lock(&info->port.mutex); + if (info->port.flags & ASYNC_INITIALIZED) mgsl_wait_until_sent(tty, info->timeout); mgsl_flush_buffer(tty); tty_ldisc_flush(tty); shutdown(info); - mutex_unlock(&info->port.mutex); tty_port_close_end(&info->port, tty); info->port.tty = NULL; @@ -3165,6 +3162,7 @@ static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout) * Note: use tight timings here to satisfy the NIST-PCTS. */ + lock_kernel(); if ( info->params.data_rate ) { char_time = info->timeout/(32 * 5); if (!char_time) @@ -3194,6 +3192,7 @@ static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout) break; } } + unlock_kernel(); exit: if (debug_level >= DEBUG_LEVEL_INFO) @@ -3349,9 +3348,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, printk("%s(%d):block_til_ready blocking on %s count=%d\n", __FILE__,__LINE__, tty->driver->name, port->count ); - tty_unlock(); schedule(); - tty_lock(); } set_current_state(TASK_RUNNING); diff --git a/trunk/drivers/char/synclink_gt.c b/trunk/drivers/char/synclink_gt.c index fef80cfcab5c..334cf5c8c8b6 100644 --- a/trunk/drivers/char/synclink_gt.c +++ b/trunk/drivers/char/synclink_gt.c @@ -40,8 +40,8 @@ #define DBGBH(fmt) if (debug_level >= DEBUG_LEVEL_BH) printk fmt #define DBGISR(fmt) if (debug_level >= DEBUG_LEVEL_ISR) printk fmt #define DBGDATA(info, buf, size, label) if (debug_level >= DEBUG_LEVEL_DATA) trace_block((info), (buf), (size), (label)) -/*#define DBGTBUF(info) dump_tbufs(info)*/ -/*#define DBGRBUF(info) dump_rbufs(info)*/ +//#define DBGTBUF(info) dump_tbufs(info) +//#define DBGRBUF(info) dump_rbufs(info) #include @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -675,14 +676,12 @@ static int open(struct tty_struct *tty, struct file *filp) goto cleanup; } - mutex_lock(&info->port.mutex); info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; spin_lock_irqsave(&info->netlock, flags); if (info->netcount) { retval = -EBUSY; spin_unlock_irqrestore(&info->netlock, flags); - mutex_unlock(&info->port.mutex); goto cleanup; } info->port.count++; @@ -694,7 +693,7 @@ static int open(struct tty_struct *tty, struct file *filp) if (retval < 0) goto cleanup; } - mutex_unlock(&info->port.mutex); + retval = block_til_ready(tty, filp, info); if (retval) { DBGINFO(("%s block_til_ready rc=%d\n", info->device_name, retval)); @@ -726,14 +725,12 @@ static void close(struct tty_struct *tty, struct file *filp) if (tty_port_close_start(&info->port, tty, filp) == 0) goto cleanup; - mutex_lock(&info->port.mutex); if (info->port.flags & ASYNC_INITIALIZED) wait_until_sent(tty, info->timeout); flush_buffer(tty); tty_ldisc_flush(tty); shutdown(info); - mutex_unlock(&info->port.mutex); tty_port_close_end(&info->port, tty); info->port.tty = NULL; @@ -744,23 +741,17 @@ static void close(struct tty_struct *tty, struct file *filp) static void hangup(struct tty_struct *tty) { struct slgt_info *info = tty->driver_data; - unsigned long flags; if (sanity_check(info, tty->name, "hangup")) return; DBGINFO(("%s hangup\n", info->device_name)); flush_buffer(tty); - - mutex_lock(&info->port.mutex); shutdown(info); - spin_lock_irqsave(&info->port.lock, flags); info->port.count = 0; info->port.flags &= ~ASYNC_NORMAL_ACTIVE; info->port.tty = NULL; - spin_unlock_irqrestore(&info->port.lock, flags); - mutex_unlock(&info->port.mutex); wake_up_interruptible(&info->port.open_wait); } @@ -910,6 +901,8 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) * Note: use tight timings here to satisfy the NIST-PCTS. */ + lock_kernel(); + if (info->params.data_rate) { char_time = info->timeout/(32 * 5); if (!char_time) @@ -927,6 +920,8 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) if (timeout && time_after(jiffies, orig_jiffies + timeout)) break; } + unlock_kernel(); + exit: DBGINFO(("%s wait_until_sent exit\n", info->device_name)); } @@ -1046,37 +1041,8 @@ static int ioctl(struct tty_struct *tty, struct file *file, return -EIO; } - switch (cmd) { - case MGSL_IOCWAITEVENT: - return wait_mgsl_event(info, argp); - case TIOCMIWAIT: - return modem_input_wait(info,(int)arg); - case TIOCGICOUNT: - spin_lock_irqsave(&info->lock,flags); - cnow = info->icount; - spin_unlock_irqrestore(&info->lock,flags); - p_cuser = argp; - if (put_user(cnow.cts, &p_cuser->cts) || - put_user(cnow.dsr, &p_cuser->dsr) || - put_user(cnow.rng, &p_cuser->rng) || - put_user(cnow.dcd, &p_cuser->dcd) || - put_user(cnow.rx, &p_cuser->rx) || - put_user(cnow.tx, &p_cuser->tx) || - put_user(cnow.frame, &p_cuser->frame) || - put_user(cnow.overrun, &p_cuser->overrun) || - put_user(cnow.parity, &p_cuser->parity) || - put_user(cnow.brk, &p_cuser->brk) || - put_user(cnow.buf_overrun, &p_cuser->buf_overrun)) - return -EFAULT; - return 0; - case MGSL_IOCSGPIO: - return set_gpio(info, argp); - case MGSL_IOCGGPIO: - return get_gpio(info, argp); - case MGSL_IOCWAITGPIO: - return wait_gpio(info, argp); - } - mutex_lock(&info->port.mutex); + lock_kernel(); + switch (cmd) { case MGSL_IOCGPARAMS: ret = get_params(info, argp); @@ -1102,16 +1068,50 @@ static int ioctl(struct tty_struct *tty, struct file *file, case MGSL_IOCGSTATS: ret = get_stats(info, argp); break; + case MGSL_IOCWAITEVENT: + ret = wait_mgsl_event(info, argp); + break; + case TIOCMIWAIT: + ret = modem_input_wait(info,(int)arg); + break; case MGSL_IOCGIF: ret = get_interface(info, argp); break; case MGSL_IOCSIF: ret = set_interface(info,(int)arg); break; + case MGSL_IOCSGPIO: + ret = set_gpio(info, argp); + break; + case MGSL_IOCGGPIO: + ret = get_gpio(info, argp); + break; + case MGSL_IOCWAITGPIO: + ret = wait_gpio(info, argp); + break; + case TIOCGICOUNT: + spin_lock_irqsave(&info->lock,flags); + cnow = info->icount; + spin_unlock_irqrestore(&info->lock,flags); + p_cuser = argp; + if (put_user(cnow.cts, &p_cuser->cts) || + put_user(cnow.dsr, &p_cuser->dsr) || + put_user(cnow.rng, &p_cuser->rng) || + put_user(cnow.dcd, &p_cuser->dcd) || + put_user(cnow.rx, &p_cuser->rx) || + put_user(cnow.tx, &p_cuser->tx) || + put_user(cnow.frame, &p_cuser->frame) || + put_user(cnow.overrun, &p_cuser->overrun) || + put_user(cnow.parity, &p_cuser->parity) || + put_user(cnow.brk, &p_cuser->brk) || + put_user(cnow.buf_overrun, &p_cuser->buf_overrun)) + ret = -EFAULT; + ret = 0; + break; default: ret = -ENOIOCTLCMD; } - mutex_unlock(&info->port.mutex); + unlock_kernel(); return ret; } @@ -3244,9 +3244,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, } DBGINFO(("%s block_til_ready wait\n", tty->driver->name)); - tty_unlock(); schedule(); - tty_lock(); } set_current_state(TASK_RUNNING); diff --git a/trunk/drivers/char/synclinkmp.c b/trunk/drivers/char/synclinkmp.c index e56caf7d82aa..2b18adc4ee19 100644 --- a/trunk/drivers/char/synclinkmp.c +++ b/trunk/drivers/char/synclinkmp.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -812,15 +813,13 @@ static void close(struct tty_struct *tty, struct file *filp) if (tty_port_close_start(&info->port, tty, filp) == 0) goto cleanup; - - mutex_lock(&info->port.mutex); + if (info->port.flags & ASYNC_INITIALIZED) wait_until_sent(tty, info->timeout); flush_buffer(tty); tty_ldisc_flush(tty); shutdown(info); - mutex_unlock(&info->port.mutex); tty_port_close_end(&info->port, tty); info->port.tty = NULL; @@ -836,7 +835,6 @@ static void close(struct tty_struct *tty, struct file *filp) static void hangup(struct tty_struct *tty) { SLMP_INFO *info = tty->driver_data; - unsigned long flags; if (debug_level >= DEBUG_LEVEL_INFO) printk("%s(%d):%s hangup()\n", @@ -845,16 +843,12 @@ static void hangup(struct tty_struct *tty) if (sanity_check(info, tty->name, "hangup")) return; - mutex_lock(&info->port.mutex); flush_buffer(tty); shutdown(info); - spin_lock_irqsave(&info->port.lock, flags); info->port.count = 0; info->port.flags &= ~ASYNC_NORMAL_ACTIVE; info->port.tty = NULL; - spin_unlock_irqrestore(&info->port.lock, flags); - mutex_unlock(&info->port.mutex); wake_up_interruptible(&info->port.open_wait); } @@ -1068,7 +1062,9 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) if (sanity_check(info, tty->name, "wait_until_sent")) return; - if (!test_bit(ASYNCB_INITIALIZED, &info->port.flags)) + lock_kernel(); + + if (!(info->port.flags & ASYNC_INITIALIZED)) goto exit; orig_jiffies = jiffies; @@ -1098,10 +1094,8 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) break; } } else { - /* - * TODO: determine if there is something similar to USC16C32 - * TXSTATUS_ALL_SENT status - */ + //TODO: determine if there is something similar to USC16C32 + // TXSTATUS_ALL_SENT status while ( info->tx_active && info->tx_enabled) { msleep_interruptible(jiffies_to_msecs(char_time)); if (signal_pending(current)) @@ -1112,6 +1106,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) } exit: + unlock_kernel(); if (debug_level >= DEBUG_LEVEL_INFO) printk("%s(%d):%s wait_until_sent() exit\n", __FILE__,__LINE__, info->device_name ); @@ -1127,6 +1122,7 @@ static int write_room(struct tty_struct *tty) if (sanity_check(info, tty->name, "write_room")) return 0; + lock_kernel(); if (info->params.mode == MGSL_MODE_HDLC) { ret = (info->tx_active) ? 0 : HDLC_MAX_FRAME_SIZE; } else { @@ -1134,6 +1130,7 @@ static int write_room(struct tty_struct *tty) if (ret < 0) ret = 0; } + unlock_kernel(); if (debug_level >= DEBUG_LEVEL_INFO) printk("%s(%d):%s write_room()=%d\n", @@ -1254,7 +1251,7 @@ static void tx_release(struct tty_struct *tty) * * Return Value: 0 if success, otherwise error code */ -static int ioctl(struct tty_struct *tty, struct file *file, +static int do_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { SLMP_INFO *info = tty->driver_data; @@ -1344,6 +1341,16 @@ static int ioctl(struct tty_struct *tty, struct file *file, return 0; } +static int ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg) +{ + int ret; + lock_kernel(); + ret = do_ioctl(tty, file, cmd, arg); + unlock_kernel(); + return ret; +} + /* * /proc fs routines.... */ @@ -2876,9 +2883,7 @@ static int get_stats(SLMP_INFO * info, struct mgsl_icount __user *user_icount) if (!user_icount) { memset(&info->icount, 0, sizeof(info->icount)); } else { - mutex_lock(&info->port.mutex); COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount)); - mutex_unlock(&info->port.mutex); if (err) return -EFAULT; } @@ -2893,9 +2898,7 @@ static int get_params(SLMP_INFO * info, MGSL_PARAMS __user *user_params) printk("%s(%d):%s get_params()\n", __FILE__,__LINE__, info->device_name); - mutex_lock(&info->port.mutex); COPY_TO_USER(err,user_params, &info->params, sizeof(MGSL_PARAMS)); - mutex_unlock(&info->port.mutex); if (err) { if ( debug_level >= DEBUG_LEVEL_INFO ) printk( "%s(%d):%s get_params() user buffer copy failed\n", @@ -2923,13 +2926,11 @@ static int set_params(SLMP_INFO * info, MGSL_PARAMS __user *new_params) return -EFAULT; } - mutex_lock(&info->port.mutex); spin_lock_irqsave(&info->lock,flags); memcpy(&info->params,&tmp_params,sizeof(MGSL_PARAMS)); spin_unlock_irqrestore(&info->lock,flags); change_params(info); - mutex_unlock(&info->port.mutex); return 0; } @@ -3365,9 +3366,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, printk("%s(%d):%s block_til_ready() count=%d\n", __FILE__,__LINE__, tty->driver->name, port->count ); - tty_unlock(); schedule(); - tty_lock(); } set_current_state(TASK_RUNNING); diff --git a/trunk/drivers/char/tty_io.c b/trunk/drivers/char/tty_io.c index 0350c42375a2..507441ac6edb 100644 --- a/trunk/drivers/char/tty_io.c +++ b/trunk/drivers/char/tty_io.c @@ -149,7 +149,6 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd, #else #define tty_compat_ioctl NULL #endif -static int __tty_fasync(int fd, struct file *filp, int on); static int tty_fasync(int fd, struct file *filp, int on); static void release_tty(struct tty_struct *tty, int idx); static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); @@ -471,7 +470,7 @@ void tty_wakeup(struct tty_struct *tty) EXPORT_SYMBOL_GPL(tty_wakeup); /** - * __tty_hangup - actual handler for hangup events + * do_tty_hangup - actual handler for hangup events * @work: tty device * * This can be called by the "eventd" kernel thread. That is process @@ -484,7 +483,7 @@ EXPORT_SYMBOL_GPL(tty_wakeup); * remains intact. * * Locking: - * BTM + * BKL * redirect lock for undoing redirection * file list lock for manipulating list of ttys * tty_ldisc_lock from called functions @@ -492,8 +491,10 @@ EXPORT_SYMBOL_GPL(tty_wakeup); * tasklist_lock to walk task list for hangup event * ->siglock to protect ->signal/->sighand */ -void __tty_hangup(struct tty_struct *tty) +static void do_tty_hangup(struct work_struct *work) { + struct tty_struct *tty = + container_of(work, struct tty_struct, hangup_work); struct file *cons_filp = NULL; struct file *filp, *f = NULL; struct task_struct *p; @@ -512,12 +513,9 @@ void __tty_hangup(struct tty_struct *tty) } spin_unlock(&redirect_lock); - tty_lock(); - - /* inuse_filps is protected by the single tty lock, - this really needs to change if we want to flush the - workqueue with the lock held */ - check_tty_count(tty, "tty_hangup"); + /* inuse_filps is protected by the single kernel lock */ + lock_kernel(); + check_tty_count(tty, "do_tty_hangup"); file_list_lock(); /* This breaks for file handles being sent over AF_UNIX sockets ? */ @@ -527,7 +525,7 @@ void __tty_hangup(struct tty_struct *tty) if (filp->f_op->write != tty_write) continue; closecount++; - __tty_fasync(-1, filp, 0); /* can't block */ + tty_fasync(-1, filp, 0); /* can't block */ filp->f_op = &hung_up_tty_fops; } file_list_unlock(); @@ -596,21 +594,11 @@ void __tty_hangup(struct tty_struct *tty) */ set_bit(TTY_HUPPED, &tty->flags); tty_ldisc_enable(tty); - - tty_unlock(); - + unlock_kernel(); if (f) fput(f); } -static void do_tty_hangup(struct work_struct *work) -{ - struct tty_struct *tty = - container_of(work, struct tty_struct, hangup_work); - - __tty_hangup(tty); -} - /** * tty_hangup - trigger a hangup event * @tty: tty to hangup @@ -646,12 +634,11 @@ void tty_vhangup(struct tty_struct *tty) printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty, buf)); #endif - __tty_hangup(tty); + do_tty_hangup(&tty->hangup_work); } EXPORT_SYMBOL(tty_vhangup); - /** * tty_vhangup_self - process vhangup for own ctty * @@ -709,8 +696,7 @@ static void session_clear_tty(struct pid *session) * exiting; it is 0 if called by the ioctl TIOCNOTTY. * * Locking: - * BTM is taken for hysterical raisins, and held when - * called from no_tty(). + * BKL is taken for hysterical raisins * tty_mutex is taken to protect tty * ->siglock is taken to protect ->signal/->sighand * tasklist_lock is taken to walk process list for sessions @@ -728,10 +714,10 @@ void disassociate_ctty(int on_exit) tty = get_current_tty(); if (tty) { tty_pgrp = get_pid(tty->pgrp); - if (on_exit) { - if (tty->driver->type != TTY_DRIVER_TYPE_PTY) - tty_vhangup(tty); - } + lock_kernel(); + if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) + tty_vhangup(tty); + unlock_kernel(); tty_kref_put(tty); } else if (on_exit) { struct pid *old_pgrp; @@ -788,9 +774,9 @@ void disassociate_ctty(int on_exit) void no_tty(void) { struct task_struct *tsk = current; - tty_lock(); + lock_kernel(); disassociate_ctty(0); - tty_unlock(); + unlock_kernel(); proc_clear_tty(tsk); } @@ -893,7 +879,7 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, struct inode *inode; struct tty_ldisc *ld; - tty = file->private_data; + tty = (struct tty_struct *)file->private_data; inode = file->f_path.dentry->d_inode; if (tty_paranoia_check(tty, inode, "tty_read")) return -EIO; @@ -1027,19 +1013,19 @@ static inline ssize_t do_tty_write( * We don't put it into the syslog queue right now maybe in the future if * really needed. * - * We must still hold the BTM and test the CLOSING flag for the moment. + * We must still hold the BKL and test the CLOSING flag for the moment. */ void tty_write_message(struct tty_struct *tty, char *msg) { if (tty) { mutex_lock(&tty->atomic_write_lock); - tty_lock(); + lock_kernel(); if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) { - tty_unlock(); + unlock_kernel(); tty->ops->write(tty, msg, strlen(msg)); } else - tty_unlock(); + unlock_kernel(); tty_write_unlock(tty); } return; @@ -1070,7 +1056,7 @@ static ssize_t tty_write(struct file *file, const char __user *buf, ssize_t ret; struct tty_ldisc *ld; - tty = file->private_data; + tty = (struct tty_struct *)file->private_data; if (tty_paranoia_check(tty, inode, "tty_write")) return -EIO; if (!tty || !tty->ops->write || @@ -1222,14 +1208,18 @@ static int tty_driver_install_tty(struct tty_driver *driver, int ret; if (driver->ops->install) { + lock_kernel(); ret = driver->ops->install(driver, tty); + unlock_kernel(); return ret; } if (tty_init_termios(tty) == 0) { + lock_kernel(); tty_driver_kref_get(driver); tty->count++; driver->ttys[idx] = tty; + unlock_kernel(); return 0; } return -ENOMEM; @@ -1322,11 +1312,14 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, struct tty_struct *tty; int retval; + lock_kernel(); /* Check if pty master is being opened multiple times */ if (driver->subtype == PTY_TYPE_MASTER && (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) { + unlock_kernel(); return ERR_PTR(-EIO); } + unlock_kernel(); /* * First time open is complex, especially for PTY devices. @@ -1370,7 +1363,9 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, if (printk_ratelimit()) printk(KERN_INFO "tty_init_dev: ldisc open failed, " "clearing slot %d\n", idx); + lock_kernel(); release_tty(tty, idx); + unlock_kernel(); return ERR_PTR(retval); } @@ -1513,14 +1508,14 @@ int tty_release(struct inode *inode, struct file *filp) int idx; char buf[64]; - tty = filp->private_data; + tty = (struct tty_struct *)filp->private_data; if (tty_paranoia_check(tty, inode, "tty_release_dev")) return 0; - tty_lock(); + lock_kernel(); check_tty_count(tty, "tty_release_dev"); - __tty_fasync(-1, filp, 0); + tty_fasync(-1, filp, 0); idx = tty->index; pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && @@ -1532,18 +1527,18 @@ int tty_release(struct inode *inode, struct file *filp) if (idx < 0 || idx >= tty->driver->num) { printk(KERN_DEBUG "tty_release_dev: bad idx when trying to " "free (%s)\n", tty->name); - tty_unlock(); + unlock_kernel(); return 0; } if (!devpts) { if (tty != tty->driver->ttys[idx]) { - tty_unlock(); + unlock_kernel(); printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty " "for (%s)\n", idx, tty->name); return 0; } if (tty->termios != tty->driver->termios[idx]) { - tty_unlock(); + unlock_kernel(); printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios " "for (%s)\n", idx, tty->name); @@ -1561,21 +1556,21 @@ int tty_release(struct inode *inode, struct file *filp) if (tty->driver->other && !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { if (o_tty != tty->driver->other->ttys[idx]) { - tty_unlock(); + unlock_kernel(); printk(KERN_DEBUG "tty_release_dev: other->table[%d] " "not o_tty for (%s)\n", idx, tty->name); return 0 ; } if (o_tty->termios != tty->driver->other->termios[idx]) { - tty_unlock(); + unlock_kernel(); printk(KERN_DEBUG "tty_release_dev: other->termios[%d] " "not o_termios for (%s)\n", idx, tty->name); return 0; } if (o_tty->link != tty) { - tty_unlock(); + unlock_kernel(); printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n"); return 0; } @@ -1584,7 +1579,7 @@ int tty_release(struct inode *inode, struct file *filp) if (tty->ops->close) tty->ops->close(tty, filp); - tty_unlock(); + unlock_kernel(); /* * Sanity check: if tty->count is going to zero, there shouldn't be * any waiters on tty->read_wait or tty->write_wait. We test the @@ -1607,7 +1602,7 @@ int tty_release(struct inode *inode, struct file *filp) opens on /dev/tty */ mutex_lock(&tty_mutex); - tty_lock(); + lock_kernel(); tty_closing = tty->count <= 1; o_tty_closing = o_tty && (o_tty->count <= (pty_master ? 1 : 0)); @@ -1638,7 +1633,7 @@ int tty_release(struct inode *inode, struct file *filp) printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue " "active!\n", tty_name(tty, buf)); - tty_unlock(); + unlock_kernel(); mutex_unlock(&tty_mutex); schedule(); } @@ -1703,7 +1698,7 @@ int tty_release(struct inode *inode, struct file *filp) /* check whether both sides are closing ... */ if (!tty_closing || (o_tty && !o_tty_closing)) { - tty_unlock(); + unlock_kernel(); return 0; } @@ -1723,7 +1718,7 @@ int tty_release(struct inode *inode, struct file *filp) /* Make this pty number available for reallocation */ if (devpts) devpts_kill_index(inode, idx); - tty_unlock(); + unlock_kernel(); return 0; } @@ -1765,12 +1760,12 @@ static int tty_open(struct inode *inode, struct file *filp) retval = 0; mutex_lock(&tty_mutex); - tty_lock(); + lock_kernel(); if (device == MKDEV(TTYAUX_MAJOR, 0)) { tty = get_current_tty(); if (!tty) { - tty_unlock(); + unlock_kernel(); mutex_unlock(&tty_mutex); return -ENXIO; } @@ -1802,14 +1797,14 @@ static int tty_open(struct inode *inode, struct file *filp) goto got_driver; } } - tty_unlock(); + unlock_kernel(); mutex_unlock(&tty_mutex); return -ENODEV; } driver = get_tty_driver(device, &index); if (!driver) { - tty_unlock(); + unlock_kernel(); mutex_unlock(&tty_mutex); return -ENODEV; } @@ -1819,7 +1814,7 @@ static int tty_open(struct inode *inode, struct file *filp) tty = tty_driver_lookup_tty(driver, inode, index); if (IS_ERR(tty)) { - tty_unlock(); + unlock_kernel(); mutex_unlock(&tty_mutex); return PTR_ERR(tty); } @@ -1835,7 +1830,7 @@ static int tty_open(struct inode *inode, struct file *filp) mutex_unlock(&tty_mutex); tty_driver_kref_put(driver); if (IS_ERR(tty)) { - tty_unlock(); + unlock_kernel(); return PTR_ERR(tty); } @@ -1865,29 +1860,29 @@ static int tty_open(struct inode *inode, struct file *filp) printk(KERN_DEBUG "error %d in opening %s...", retval, tty->name); #endif - tty_unlock(); /* need to call tty_release without BTM */ tty_release(inode, filp); - if (retval != -ERESTARTSYS) + if (retval != -ERESTARTSYS) { + unlock_kernel(); return retval; - - if (signal_pending(current)) + } + if (signal_pending(current)) { + unlock_kernel(); return retval; - + } schedule(); /* * Need to reset f_op in case a hangup happened. */ - tty_lock(); if (filp->f_op == &hung_up_tty_fops) filp->f_op = &tty_fops; - tty_unlock(); + unlock_kernel(); goto retry_open; } - tty_unlock(); + unlock_kernel(); mutex_lock(&tty_mutex); - tty_lock(); + lock_kernel(); spin_lock_irq(¤t->sighand->siglock); if (!noctty && current->signal->leader && @@ -1895,7 +1890,7 @@ static int tty_open(struct inode *inode, struct file *filp) tty->session == NULL) __proc_set_tty(current, tty); spin_unlock_irq(¤t->sighand->siglock); - tty_unlock(); + unlock_kernel(); mutex_unlock(&tty_mutex); return 0; } @@ -1920,7 +1915,7 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait) struct tty_ldisc *ld; int ret = 0; - tty = filp->private_data; + tty = (struct tty_struct *)filp->private_data; if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll")) return 0; @@ -1931,13 +1926,14 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait) return ret; } -static int __tty_fasync(int fd, struct file *filp, int on) +static int tty_fasync(int fd, struct file *filp, int on) { struct tty_struct *tty; unsigned long flags; int retval = 0; - tty = filp->private_data; + lock_kernel(); + tty = (struct tty_struct *)filp->private_data; if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync")) goto out; @@ -1970,15 +1966,7 @@ static int __tty_fasync(int fd, struct file *filp, int on) } retval = 0; out: - return retval; -} - -static int tty_fasync(int fd, struct file *filp, int on) -{ - int retval; - tty_lock(); - retval = __tty_fasync(fd, filp, on); - tty_unlock(); + unlock_kernel(); return retval; } @@ -2497,7 +2485,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) struct tty_ldisc *ld; struct inode *inode = file->f_dentry->d_inode; - tty = file->private_data; + tty = (struct tty_struct *)file->private_data; if (tty_paranoia_check(tty, inode, "tty_ioctl")) return -EINVAL; diff --git a/trunk/drivers/char/tty_ioctl.c b/trunk/drivers/char/tty_ioctl.c index 0c1889971459..6bd5f8866c74 100644 --- a/trunk/drivers/char/tty_ioctl.c +++ b/trunk/drivers/char/tty_ioctl.c @@ -517,25 +517,19 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) /* See if packet mode change of state. */ if (tty->link && tty->link->packet) { - int extproc = (old_termios.c_lflag & EXTPROC) | - (tty->termios->c_lflag & EXTPROC); int old_flow = ((old_termios.c_iflag & IXON) && (old_termios.c_cc[VSTOP] == '\023') && (old_termios.c_cc[VSTART] == '\021')); int new_flow = (I_IXON(tty) && STOP_CHAR(tty) == '\023' && START_CHAR(tty) == '\021'); - if ((old_flow != new_flow) || extproc) { + if (old_flow != new_flow) { spin_lock_irqsave(&tty->ctrl_lock, flags); - if (old_flow != new_flow) { - tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP); - if (new_flow) - tty->ctrl_status |= TIOCPKT_DOSTOP; - else - tty->ctrl_status |= TIOCPKT_NOSTOP; - } - if (extproc) - tty->ctrl_status |= TIOCPKT_IOCTL; + tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP); + if (new_flow) + tty->ctrl_status |= TIOCPKT_DOSTOP; + else + tty->ctrl_status |= TIOCPKT_NOSTOP; spin_unlock_irqrestore(&tty->ctrl_lock, flags); wake_up_interruptible(&tty->link->read_wait); } diff --git a/trunk/drivers/char/tty_ldisc.c b/trunk/drivers/char/tty_ldisc.c index 412f9775d19c..500e740ec5e4 100644 --- a/trunk/drivers/char/tty_ldisc.c +++ b/trunk/drivers/char/tty_ldisc.c @@ -440,8 +440,6 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num) * * A helper opening method. Also a convenient debugging and check * point. - * - * Locking: always called with BTM already held. */ static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld) @@ -449,9 +447,10 @@ static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld) WARN_ON(test_and_set_bit(TTY_LDISC_OPEN, &tty->flags)); if (ld->ops->open) { int ret; - /* BTM here locks versus a hangup event */ - WARN_ON(!tty_locked()); + /* BKL here locks verus a hangup event */ + lock_kernel(); ret = ld->ops->open(tty); + unlock_kernel(); return ret; } return 0; @@ -554,7 +553,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) if (IS_ERR(new_ldisc)) return PTR_ERR(new_ldisc); - tty_lock(); + lock_kernel(); /* * We need to look at the tty locking here for pty/tty pairs * when both sides try to change in parallel. @@ -568,12 +567,12 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) */ if (tty->ldisc->ops->num == ldisc) { - tty_unlock(); + unlock_kernel(); tty_ldisc_put(new_ldisc); return 0; } - tty_unlock(); + unlock_kernel(); /* * Problem: What do we do if this blocks ? * We could deadlock here @@ -581,7 +580,6 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) tty_wait_until_sent(tty, 0); - tty_lock(); mutex_lock(&tty->ldisc_mutex); /* @@ -591,13 +589,13 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) while (test_bit(TTY_LDISC_CHANGING, &tty->flags)) { mutex_unlock(&tty->ldisc_mutex); - tty_unlock(); wait_event(tty_ldisc_wait, test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0); - tty_lock(); mutex_lock(&tty->ldisc_mutex); } + lock_kernel(); + set_bit(TTY_LDISC_CHANGING, &tty->flags); /* @@ -609,7 +607,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) o_ldisc = tty->ldisc; - tty_unlock(); + unlock_kernel(); /* * Make sure we don't change while someone holds a * reference to the line discipline. The TTY_LDISC bit @@ -634,15 +632,15 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) flush_scheduled_work(); - tty_lock(); mutex_lock(&tty->ldisc_mutex); + lock_kernel(); if (test_bit(TTY_HUPPED, &tty->flags)) { /* We were raced by the hangup method. It will have stomped the ldisc data and closed the ldisc down */ clear_bit(TTY_LDISC_CHANGING, &tty->flags); mutex_unlock(&tty->ldisc_mutex); tty_ldisc_put(new_ldisc); - tty_unlock(); + unlock_kernel(); return -EIO; } @@ -684,7 +682,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) if (o_work) schedule_delayed_work(&o_tty->buf.work, 1); mutex_unlock(&tty->ldisc_mutex); - tty_unlock(); + unlock_kernel(); return retval; } @@ -782,20 +780,7 @@ void tty_ldisc_hangup(struct tty_struct *tty) * Avoid racing set_ldisc or tty_ldisc_release */ mutex_lock(&tty->ldisc_mutex); - - /* - * this is like tty_ldisc_halt, but we need to give up - * the BTM before calling cancel_delayed_work_sync, - * which may need to wait for another function taking the BTM - */ - clear_bit(TTY_LDISC, &tty->flags); - tty_unlock(); - cancel_delayed_work_sync(&tty->buf.work); - mutex_unlock(&tty->ldisc_mutex); - - tty_lock(); - mutex_lock(&tty->ldisc_mutex); - + tty_ldisc_halt(tty); /* At this point we have a closed ldisc and we want to reopen it. We could defer this to the next open but it means auditing a lot of other paths so this is @@ -866,10 +851,8 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) * race with the set_ldisc code path. */ - tty_unlock(); tty_ldisc_halt(tty); flush_scheduled_work(); - tty_lock(); mutex_lock(&tty->ldisc_mutex); /* diff --git a/trunk/drivers/char/tty_mutex.c b/trunk/drivers/char/tty_mutex.c deleted file mode 100644 index 133697540c73..000000000000 --- a/trunk/drivers/char/tty_mutex.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * drivers/char/tty_lock.c - */ -#include -#include -#include -#include -#include - -/* - * The 'big tty mutex' - * - * This mutex is taken and released by tty_lock() and tty_unlock(), - * replacing the older big kernel lock. - * It can no longer be taken recursively, and does not get - * released implicitly while sleeping. - * - * Don't use in new code. - */ -static DEFINE_MUTEX(big_tty_mutex); -struct task_struct *__big_tty_mutex_owner; -EXPORT_SYMBOL_GPL(__big_tty_mutex_owner); - -/* - * Getting the big tty mutex. - */ -void __lockfunc tty_lock(void) -{ - struct task_struct *task = current; - - WARN_ON(__big_tty_mutex_owner == task); - - mutex_lock(&big_tty_mutex); - __big_tty_mutex_owner = task; -} -EXPORT_SYMBOL(tty_lock); - -void __lockfunc tty_unlock(void) -{ - struct task_struct *task = current; - - WARN_ON(__big_tty_mutex_owner != task); - __big_tty_mutex_owner = NULL; - - mutex_unlock(&big_tty_mutex); -} -EXPORT_SYMBOL(tty_unlock); diff --git a/trunk/drivers/char/tty_port.c b/trunk/drivers/char/tty_port.c index 33d37d230f8f..a3bd1d0b66cf 100644 --- a/trunk/drivers/char/tty_port.c +++ b/trunk/drivers/char/tty_port.c @@ -231,7 +231,7 @@ int tty_port_block_til_ready(struct tty_port *port, /* block if port is in the process of being closed */ if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { - wait_event_interruptible_tty(port->close_wait, + wait_event_interruptible(port->close_wait, !(port->flags & ASYNC_CLOSING)); if (port->flags & ASYNC_HUP_NOTIFY) return -EAGAIN; @@ -294,9 +294,7 @@ int tty_port_block_til_ready(struct tty_port *port, retval = -ERESTARTSYS; break; } - tty_unlock(); schedule(); - tty_lock(); } finish_wait(&port->open_wait, &wait); diff --git a/trunk/drivers/char/vc_screen.c b/trunk/drivers/char/vc_screen.c index bcce46c96b88..c1791a63d99d 100644 --- a/trunk/drivers/char/vc_screen.c +++ b/trunk/drivers/char/vc_screen.c @@ -463,10 +463,10 @@ vcs_open(struct inode *inode, struct file *filp) unsigned int currcons = iminor(inode) & 127; int ret = 0; - tty_lock(); + lock_kernel(); if(currcons && !vc_cons_allocated(currcons-1)) ret = -ENXIO; - tty_unlock(); + unlock_kernel(); return ret; } diff --git a/trunk/drivers/char/vt.c b/trunk/drivers/char/vt.c index c734f9b1263a..44f03ddd8871 100644 --- a/trunk/drivers/char/vt.c +++ b/trunk/drivers/char/vt.c @@ -105,7 +105,6 @@ #include #include #include -#include #define MAX_NR_CON_DRIVER 16 @@ -287,12 +286,8 @@ static inline unsigned short *screenpos(struct vc_data *vc, int offset, int view return p; } -/* Called from the keyboard irq path.. */ static inline void scrolldelta(int lines) { - /* FIXME */ - /* scrolldelta needs some kind of consistency lock, but the BKL was - and still is not protecting versus the scheduled back end */ scrollback_delta += lines; schedule_console_callback(); } @@ -709,10 +704,7 @@ void redraw_screen(struct vc_data *vc, int is_switch) update_attr(vc); clear_buffer_attributes(vc); } - - /* Forcibly update if we're panicing */ - if ((update && vc->vc_mode != KD_GRAPHICS) || - vt_force_oops_output(vc)) + if (update && vc->vc_mode != KD_GRAPHICS) do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2); } set_cursor(vc); @@ -750,7 +742,6 @@ static void visual_init(struct vc_data *vc, int num, int init) vc->vc_hi_font_mask = 0; vc->vc_complement_mask = 0; vc->vc_can_do_color = 0; - vc->vc_panic_force_write = false; vc->vc_sw->con_init(vc, init); if (!vc->vc_complement_mask) vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; @@ -783,7 +774,6 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */ if (!vc) return -ENOMEM; vc_cons[currcons].d = vc; - tty_port_init(&vc->port); INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); visual_init(vc, currcons, 1); if (!*vc->vc_uni_pagedir_loc) @@ -973,12 +963,12 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, * Resize a virtual console as seen from the console end of things. We * use the common vc_do_resize methods to update the structures. The * caller must hold the console sem to protect console internals and - * vc->port.tty + * vc->vc_tty */ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int rows) { - return vc_do_resize(vc->port.tty, vc, cols, rows); + return vc_do_resize(vc->vc_tty, vc, cols, rows); } /** @@ -1806,8 +1796,8 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) vc->vc_state = ESnormal; return; case ESpalette: - if (isxdigit(c)) { - vc->vc_par[vc->vc_npar++] = hex_to_bin(c); + if ( (c>='0'&&c<='9') || (c>='A'&&c<='F') || (c>='a'&&c<='f') ) { + vc->vc_par[vc->vc_npar++] = (c > '9' ? (c & 0xDF) - 'A' + 10 : c - '0'); if (vc->vc_npar == 7) { int i = vc->vc_par[0] * 3, j = 1; vc->vc_palette[i] = 16 * vc->vc_par[j++]; @@ -2515,7 +2505,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count) goto quit; } - if (vc->vc_mode != KD_TEXT && !vt_force_oops_output(vc)) + if (vc->vc_mode != KD_TEXT) goto quit; /* undraw cursor first */ @@ -2621,6 +2611,8 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) return -EFAULT; ret = 0; + lock_kernel(); + switch (type) { case TIOCL_SETSEL: @@ -2695,6 +2687,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) ret = -EINVAL; break; } + unlock_kernel(); return ret; } @@ -2807,12 +2800,12 @@ static int con_open(struct tty_struct *tty, struct file *filp) struct vc_data *vc = vc_cons[currcons].d; /* Still being freed */ - if (vc->port.tty) { + if (vc->vc_tty) { release_console_sem(); return -ERESTARTSYS; } tty->driver_data = vc; - vc->port.tty = tty; + vc->vc_tty = tty; if (!tty->winsize.ws_row && !tty->winsize.ws_col) { tty->winsize.ws_row = vc_cons[currcons].d->vc_rows; @@ -2840,7 +2833,7 @@ static void con_shutdown(struct tty_struct *tty) struct vc_data *vc = tty->driver_data; BUG_ON(vc == NULL); acquire_console_sem(); - vc->port.tty = NULL; + vc->vc_tty = NULL; release_console_sem(); tty_shutdown(tty); } @@ -2922,7 +2915,6 @@ static int __init con_init(void) for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) { vc_cons[currcons].d = vc = kzalloc(sizeof(struct vc_data), GFP_NOWAIT); INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); - tty_port_init(&vc->port); visual_init(vc, currcons, 1); vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT); vc_init(vc, vc->vc_rows, vc->vc_cols, @@ -3791,8 +3783,7 @@ void do_unblank_screen(int leaving_gfx) return; } vc = vc_cons[fg_console].d; - /* Try to unblank in oops case too */ - if (vc->vc_mode != KD_TEXT && !vt_force_oops_output(vc)) + if (vc->vc_mode != KD_TEXT) return; /* but leave console_blanked != 0 */ if (blankinterval) { @@ -3801,7 +3792,7 @@ void do_unblank_screen(int leaving_gfx) } console_blanked = 0; - if (vc->vc_sw->con_blank(vc, 0, leaving_gfx) || vt_force_oops_output(vc)) + if (vc->vc_sw->con_blank(vc, 0, leaving_gfx)) /* Low-level driver cannot restore -> do it ourselves */ update_screen(vc); if (console_blank_hook) diff --git a/trunk/drivers/char/vt_ioctl.c b/trunk/drivers/char/vt_ioctl.c index 2bbeaaea46e9..cb19dbc52136 100644 --- a/trunk/drivers/char/vt_ioctl.c +++ b/trunk/drivers/char/vt_ioctl.c @@ -133,7 +133,7 @@ static void vt_event_wait(struct vt_event_wait *vw) list_add(&vw->list, &vt_events); spin_unlock_irqrestore(&vt_event_lock, flags); /* Wait for it to pass */ - wait_event_interruptible_tty(vt_event_waitqueue, vw->done); + wait_event_interruptible(vt_event_waitqueue, vw->done); /* Dequeue it */ spin_lock_irqsave(&vt_event_lock, flags); list_del(&vw->list); @@ -509,7 +509,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, console = vc->vc_num; - tty_lock(); + lock_kernel(); if (!vc_cons_allocated(console)) { /* impossible? */ ret = -ENOIOCTLCMD; @@ -1336,7 +1336,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, ret = -ENOIOCTLCMD; } out: - tty_unlock(); + unlock_kernel(); return ret; eperm: ret = -EPERM; @@ -1369,7 +1369,7 @@ void vc_SAK(struct work_struct *work) acquire_console_sem(); vc = vc_con->d; if (vc) { - tty = vc->port.tty; + tty = vc->vc_tty; /* * SAK should also work in all raw modes and reset * them properly. @@ -1503,7 +1503,7 @@ long vt_compat_ioctl(struct tty_struct *tty, struct file * file, console = vc->vc_num; - tty_lock(); + lock_kernel(); if (!vc_cons_allocated(console)) { /* impossible? */ ret = -ENOIOCTLCMD; @@ -1571,11 +1571,11 @@ long vt_compat_ioctl(struct tty_struct *tty, struct file * file, goto fallback; } out: - tty_unlock(); + unlock_kernel(); return ret; fallback: - tty_unlock(); + unlock_kernel(); return vt_ioctl(tty, file, cmd, arg); } @@ -1761,13 +1761,10 @@ int vt_move_to_console(unsigned int vt, int alloc) return -EIO; } release_console_sem(); - tty_lock(); if (vt_waitactive(vt + 1)) { pr_debug("Suspend: Can't switch VCs."); - tty_unlock(); return -EINTR; } - tty_unlock(); return prev; } diff --git a/trunk/drivers/gpu/drm/i915/intel_fb.c b/trunk/drivers/gpu/drm/i915/intel_fb.c index a79525f434a8..54acd8b534df 100644 --- a/trunk/drivers/gpu/drm/i915/intel_fb.c +++ b/trunk/drivers/gpu/drm/i915/intel_fb.c @@ -130,7 +130,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev, strcpy(info->fix.id, "inteldrmfb"); - info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; + info->flags = FBINFO_DEFAULT; info->fbops = &intelfb_ops; /* setup aperture base/size for vesafb takeover */ @@ -148,6 +148,8 @@ static int intelfb_create(struct intel_fbdev *ifbdev, info->fix.smem_start = dev->mode_config.fb_base + obj_priv->gtt_offset; info->fix.smem_len = size; + info->flags = FBINFO_DEFAULT; + info->screen_base = ioremap_wc(dev->agp->base + obj_priv->gtt_offset, size); if (!info->screen_base) { diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/trunk/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 099f637264aa..2fb2444d2322 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -250,7 +250,6 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev, info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_IMAGEBLIT; - info->flags |= FBINFO_CAN_FORCE_OUTPUT; info->fbops = &nouveau_fbcon_ops; info->fix.smem_start = dev->mode_config.fb_base + nvbo->bo.offset - dev_priv->vm_vram_base; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_fb.c b/trunk/drivers/gpu/drm/radeon/radeon_fb.c index dbf86962bdd1..dc1634bb0c11 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_fb.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_fb.c @@ -224,7 +224,7 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev, drm_fb_helper_fill_fix(info, fb->pitch, fb->depth); - info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; + info->flags = FBINFO_DEFAULT; info->fbops = &radeonfb_ops; tmp = radeon_bo_gpu_offset(rbo) - rdev->mc.vram_start; diff --git a/trunk/drivers/media/video/v4l2-dev.c b/trunk/drivers/media/video/v4l2-dev.c index 249af6a1d56d..9e89bf617790 100644 --- a/trunk/drivers/media/video/v4l2-dev.c +++ b/trunk/drivers/media/video/v4l2-dev.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include @@ -216,24 +215,28 @@ static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll) return vdev->fops->poll(filp, poll); } -static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +static int v4l2_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { struct video_device *vdev = video_devdata(filp); - int ret; + if (!vdev->fops->ioctl) + return -ENOTTY; /* Allow ioctl to continue even if the device was unregistered. Things like dequeueing buffers might still be useful. */ - if (vdev->fops->unlocked_ioctl) { - ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); - } else if (vdev->fops->ioctl) { - /* TODO: convert all drivers to unlocked_ioctl */ - lock_kernel(); - ret = vdev->fops->ioctl(filp, cmd, arg); - unlock_kernel(); - } else - ret = -ENOTTY; + return vdev->fops->ioctl(filp, cmd, arg); +} - return ret; +static long v4l2_unlocked_ioctl(struct file *filp, + unsigned int cmd, unsigned long arg) +{ + struct video_device *vdev = video_devdata(filp); + + if (!vdev->fops->unlocked_ioctl) + return -ENOTTY; + /* Allow ioctl to continue even if the device was unregistered. + Things like dequeueing buffers might still be useful. */ + return vdev->fops->unlocked_ioctl(filp, cmd, arg); } #ifdef CONFIG_MMU @@ -304,6 +307,22 @@ static int v4l2_release(struct inode *inode, struct file *filp) return ret; } +static const struct file_operations v4l2_unlocked_fops = { + .owner = THIS_MODULE, + .read = v4l2_read, + .write = v4l2_write, + .open = v4l2_open, + .get_unmapped_area = v4l2_get_unmapped_area, + .mmap = v4l2_mmap, + .unlocked_ioctl = v4l2_unlocked_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = v4l2_compat_ioctl32, +#endif + .release = v4l2_release, + .poll = v4l2_poll, + .llseek = no_llseek, +}; + static const struct file_operations v4l2_fops = { .owner = THIS_MODULE, .read = v4l2_read, @@ -311,7 +330,7 @@ static const struct file_operations v4l2_fops = { .open = v4l2_open, .get_unmapped_area = v4l2_get_unmapped_area, .mmap = v4l2_mmap, - .unlocked_ioctl = v4l2_ioctl, + .ioctl = v4l2_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = v4l2_compat_ioctl32, #endif @@ -502,7 +521,10 @@ static int __video_register_device(struct video_device *vdev, int type, int nr, ret = -ENOMEM; goto cleanup; } - vdev->cdev->ops = &v4l2_fops; + if (vdev->fops->unlocked_ioctl) + vdev->cdev->ops = &v4l2_unlocked_fops; + else + vdev->cdev->ops = &v4l2_fops; vdev->cdev->owner = vdev->fops->owner; ret = cdev_add(vdev->cdev, MKDEV(VIDEO_MAJOR, vdev->minor), 1); if (ret < 0) { diff --git a/trunk/drivers/s390/block/dasd_devmap.c b/trunk/drivers/s390/block/dasd_devmap.c index 8d41f3ed38d7..bed7b4634ccd 100644 --- a/trunk/drivers/s390/block/dasd_devmap.c +++ b/trunk/drivers/s390/block/dasd_devmap.c @@ -1083,49 +1083,6 @@ dasd_eer_store(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(eer_enabled, 0644, dasd_eer_show, dasd_eer_store); -/* - * expiration time for default requests - */ -static ssize_t -dasd_expires_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct dasd_device *device; - int len; - - device = dasd_device_from_cdev(to_ccwdev(dev)); - if (IS_ERR(device)) - return -ENODEV; - len = snprintf(buf, PAGE_SIZE, "%lu\n", device->default_expires); - dasd_put_device(device); - return len; -} - -static ssize_t -dasd_expires_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct dasd_device *device; - unsigned long val; - - device = dasd_device_from_cdev(to_ccwdev(dev)); - if (IS_ERR(device)) - return -ENODEV; - - if ((strict_strtoul(buf, 10, &val) != 0) || - (val > DASD_EXPIRES_MAX) || val == 0) { - dasd_put_device(device); - return -EINVAL; - } - - if (val) - device->default_expires = val; - - dasd_put_device(device); - return count; -} - -static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store); - static struct attribute * dasd_attrs[] = { &dev_attr_readonly.attr, &dev_attr_discipline.attr, @@ -1137,7 +1094,6 @@ static struct attribute * dasd_attrs[] = { &dev_attr_eer_enabled.attr, &dev_attr_erplog.attr, &dev_attr_failfast.attr, - &dev_attr_expires.attr, NULL, }; diff --git a/trunk/drivers/s390/block/dasd_diag.c b/trunk/drivers/s390/block/dasd_diag.c index 2b3bc3ec0541..687f323cdc38 100644 --- a/trunk/drivers/s390/block/dasd_diag.c +++ b/trunk/drivers/s390/block/dasd_diag.c @@ -43,7 +43,7 @@ MODULE_LICENSE("GPL"); sizeof(struct dasd_diag_req)) / \ sizeof(struct dasd_diag_bio)) / 2) #define DIAG_MAX_RETRIES 32 -#define DIAG_TIMEOUT 50 +#define DIAG_TIMEOUT 50 * HZ static struct dasd_discipline dasd_diag_discipline; @@ -360,8 +360,6 @@ dasd_diag_check_device(struct dasd_device *device) goto out; } - device->default_expires = DIAG_TIMEOUT; - /* Figure out position of label block */ switch (private->rdc_data.vdev_class) { case DEV_CLASS_FBA: @@ -565,7 +563,7 @@ static struct dasd_ccw_req *dasd_diag_build_cp(struct dasd_device *memdev, cqr->startdev = memdev; cqr->memdev = memdev; cqr->block = block; - cqr->expires = memdev->default_expires * HZ; + cqr->expires = DIAG_TIMEOUT; cqr->status = DASD_CQR_FILLED; return cqr; } diff --git a/trunk/drivers/s390/block/dasd_eckd.c b/trunk/drivers/s390/block/dasd_eckd.c index 66360c24bd48..ab84da5592e8 100644 --- a/trunk/drivers/s390/block/dasd_eckd.c +++ b/trunk/drivers/s390/block/dasd_eckd.c @@ -82,14 +82,6 @@ static struct ccw_driver dasd_eckd_driver; /* see below */ #define INIT_CQR_UNFORMATTED 1 #define INIT_CQR_ERROR 2 -/* emergency request for reserve/release */ -static struct { - struct dasd_ccw_req cqr; - struct ccw1 ccw; - char data[32]; -} *dasd_reserve_req; -static DEFINE_MUTEX(dasd_reserve_mutex); - /* initial attempt at a probe function. this can be simplified once * the other detection code is gone */ @@ -1115,9 +1107,8 @@ dasd_eckd_check_characteristics(struct dasd_device *device) struct dasd_eckd_private *private; struct dasd_block *block; struct dasd_uid temp_uid; - int is_known, rc, i; + int is_known, rc; int readonly; - unsigned long value; if (!ccw_device_is_pathgroup(device->cdev)) { dev_warn(&device->cdev->dev, @@ -1152,18 +1143,6 @@ dasd_eckd_check_characteristics(struct dasd_device *device) if (rc) goto out_err1; - /* set default timeout */ - device->default_expires = DASD_EXPIRES; - if (private->gneq) { - value = 1; - for (i = 0; i < private->gneq->timeout.value; i++) - value = 10 * value; - value = value * private->gneq->timeout.number; - /* do not accept useless values */ - if (value != 0 && value <= DASD_EXPIRES_MAX) - device->default_expires = value; - } - /* Generate device unique id */ rc = dasd_eckd_generate_uid(device); if (rc) @@ -1994,7 +1973,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single( cqr->startdev = startdev; cqr->memdev = startdev; cqr->block = block; - cqr->expires = startdev->default_expires * HZ; /* default 5 minutes */ + cqr->expires = 5 * 60 * HZ; /* 5 minutes */ cqr->lpm = private->path_data.ppm; cqr->retries = 256; cqr->buildclk = get_clock(); @@ -2171,7 +2150,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track( cqr->startdev = startdev; cqr->memdev = startdev; cqr->block = block; - cqr->expires = startdev->default_expires * HZ; /* default 5 minutes */ + cqr->expires = 5 * 60 * HZ; /* 5 minutes */ cqr->lpm = private->path_data.ppm; cqr->retries = 256; cqr->buildclk = get_clock(); @@ -2419,7 +2398,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( cqr->startdev = startdev; cqr->memdev = startdev; cqr->block = block; - cqr->expires = startdev->default_expires * HZ; /* default 5 minutes */ + cqr->expires = 5 * 60 * HZ; /* 5 minutes */ cqr->lpm = private->path_data.ppm; cqr->retries = 256; cqr->buildclk = get_clock(); @@ -2666,23 +2645,15 @@ dasd_eckd_release(struct dasd_device *device) struct dasd_ccw_req *cqr; int rc; struct ccw1 *ccw; - int useglobal; if (!capable(CAP_SYS_ADMIN)) return -EACCES; - useglobal = 0; cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, 32, device); if (IS_ERR(cqr)) { - mutex_lock(&dasd_reserve_mutex); - useglobal = 1; - cqr = &dasd_reserve_req->cqr; - memset(cqr, 0, sizeof(*cqr)); - memset(&dasd_reserve_req->ccw, 0, - sizeof(dasd_reserve_req->ccw)); - cqr->cpaddr = &dasd_reserve_req->ccw; - cqr->data = &dasd_reserve_req->data; - cqr->magic = DASD_ECKD_MAGIC; + DBF_DEV_EVENT(DBF_WARNING, device, "%s", + "Could not allocate initialization request"); + return PTR_ERR(cqr); } ccw = cqr->cpaddr; ccw->cmd_code = DASD_ECKD_CCW_RELEASE; @@ -2700,10 +2671,7 @@ dasd_eckd_release(struct dasd_device *device) rc = dasd_sleep_on_immediatly(cqr); - if (useglobal) - mutex_unlock(&dasd_reserve_mutex); - else - dasd_sfree_request(cqr, cqr->memdev); + dasd_sfree_request(cqr, cqr->memdev); return rc; } @@ -2719,23 +2687,15 @@ dasd_eckd_reserve(struct dasd_device *device) struct dasd_ccw_req *cqr; int rc; struct ccw1 *ccw; - int useglobal; if (!capable(CAP_SYS_ADMIN)) return -EACCES; - useglobal = 0; cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, 32, device); if (IS_ERR(cqr)) { - mutex_lock(&dasd_reserve_mutex); - useglobal = 1; - cqr = &dasd_reserve_req->cqr; - memset(cqr, 0, sizeof(*cqr)); - memset(&dasd_reserve_req->ccw, 0, - sizeof(dasd_reserve_req->ccw)); - cqr->cpaddr = &dasd_reserve_req->ccw; - cqr->data = &dasd_reserve_req->data; - cqr->magic = DASD_ECKD_MAGIC; + DBF_DEV_EVENT(DBF_WARNING, device, "%s", + "Could not allocate initialization request"); + return PTR_ERR(cqr); } ccw = cqr->cpaddr; ccw->cmd_code = DASD_ECKD_CCW_RESERVE; @@ -2753,10 +2713,7 @@ dasd_eckd_reserve(struct dasd_device *device) rc = dasd_sleep_on_immediatly(cqr); - if (useglobal) - mutex_unlock(&dasd_reserve_mutex); - else - dasd_sfree_request(cqr, cqr->memdev); + dasd_sfree_request(cqr, cqr->memdev); return rc; } @@ -2771,23 +2728,15 @@ dasd_eckd_steal_lock(struct dasd_device *device) struct dasd_ccw_req *cqr; int rc; struct ccw1 *ccw; - int useglobal; if (!capable(CAP_SYS_ADMIN)) return -EACCES; - useglobal = 0; cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, 32, device); if (IS_ERR(cqr)) { - mutex_lock(&dasd_reserve_mutex); - useglobal = 1; - cqr = &dasd_reserve_req->cqr; - memset(cqr, 0, sizeof(*cqr)); - memset(&dasd_reserve_req->ccw, 0, - sizeof(dasd_reserve_req->ccw)); - cqr->cpaddr = &dasd_reserve_req->ccw; - cqr->data = &dasd_reserve_req->data; - cqr->magic = DASD_ECKD_MAGIC; + DBF_DEV_EVENT(DBF_WARNING, device, "%s", + "Could not allocate initialization request"); + return PTR_ERR(cqr); } ccw = cqr->cpaddr; ccw->cmd_code = DASD_ECKD_CCW_SLCK; @@ -2805,10 +2754,7 @@ dasd_eckd_steal_lock(struct dasd_device *device) rc = dasd_sleep_on_immediatly(cqr); - if (useglobal) - mutex_unlock(&dasd_reserve_mutex); - else - dasd_sfree_request(cqr, cqr->memdev); + dasd_sfree_request(cqr, cqr->memdev); return rc; } @@ -3542,15 +3488,10 @@ dasd_eckd_init(void) int ret; ASCEBC(dasd_eckd_discipline.ebcname, 4); - dasd_reserve_req = kmalloc(sizeof(*dasd_reserve_req), - GFP_KERNEL | GFP_DMA); - if (!dasd_reserve_req) - return -ENOMEM; ret = ccw_driver_register(&dasd_eckd_driver); if (!ret) wait_for_device_probe(); - else - kfree(dasd_reserve_req); + return ret; } @@ -3558,7 +3499,6 @@ static void __exit dasd_eckd_cleanup(void) { ccw_driver_unregister(&dasd_eckd_driver); - kfree(dasd_reserve_req); } module_init(dasd_eckd_init); diff --git a/trunk/drivers/s390/block/dasd_eckd.h b/trunk/drivers/s390/block/dasd_eckd.h index 0eb49655a6cd..dd6385a5af14 100644 --- a/trunk/drivers/s390/block/dasd_eckd.h +++ b/trunk/drivers/s390/block/dasd_eckd.h @@ -320,12 +320,7 @@ struct dasd_gneq { __u8 identifier:2; __u8 reserved:6; } __attribute__ ((packed)) flags; - __u8 reserved[5]; - struct { - __u8 value:2; - __u8 number:6; - } __attribute__ ((packed)) timeout; - __u8 reserved3; + __u8 reserved[7]; __u16 subsystemID; __u8 reserved2[22]; } __attribute__ ((packed)); diff --git a/trunk/drivers/s390/block/dasd_fba.c b/trunk/drivers/s390/block/dasd_fba.c index bec5486e0e6d..37282b90eecc 100644 --- a/trunk/drivers/s390/block/dasd_fba.c +++ b/trunk/drivers/s390/block/dasd_fba.c @@ -163,8 +163,6 @@ dasd_fba_check_characteristics(struct dasd_device *device) return rc; } - device->default_expires = DASD_EXPIRES; - readonly = dasd_device_is_ro(device); if (readonly) set_bit(DASD_FLAG_DEVICE_RO, &device->flags); @@ -372,7 +370,7 @@ static struct dasd_ccw_req *dasd_fba_build_cp(struct dasd_device * memdev, cqr->startdev = memdev; cqr->memdev = memdev; cqr->block = block; - cqr->expires = memdev->default_expires * HZ; /* default 5 minutes */ + cqr->expires = 5 * 60 * HZ; /* 5 minutes */ cqr->retries = 32; cqr->buildclk = get_clock(); cqr->status = DASD_CQR_FILLED; diff --git a/trunk/drivers/s390/block/dasd_int.h b/trunk/drivers/s390/block/dasd_int.h index 500678d7116c..49b431d135e0 100644 --- a/trunk/drivers/s390/block/dasd_int.h +++ b/trunk/drivers/s390/block/dasd_int.h @@ -186,7 +186,7 @@ struct dasd_ccw_req { /* ... and how */ unsigned long starttime; /* jiffies time of request start */ - unsigned long expires; /* expiration period in jiffies */ + int expires; /* expiration period in jiffies */ char lpm; /* logical path mask */ void *data; /* pointer to data area */ @@ -224,9 +224,6 @@ struct dasd_ccw_req { #define DASD_CQR_CLEARED 0x84 /* request was cleared */ #define DASD_CQR_SUCCESS 0x85 /* request was successful */ -/* default expiration time*/ -#define DASD_EXPIRES 300 -#define DASD_EXPIRES_MAX 40000000 /* per dasd_ccw_req flags */ #define DASD_CQR_FLAGS_USE_ERP 0 /* use ERP for this request */ @@ -407,9 +404,6 @@ struct dasd_device { /* hook for alias management */ struct list_head alias_list; - - /* default expiration time in s */ - unsigned long default_expires; }; struct dasd_block { diff --git a/trunk/drivers/s390/cio/ccwreq.c b/trunk/drivers/s390/cio/ccwreq.c index d15f8b4d78bd..7f206ed44fdf 100644 --- a/trunk/drivers/s390/cio/ccwreq.c +++ b/trunk/drivers/s390/cio/ccwreq.c @@ -38,13 +38,9 @@ static u16 ccwreq_next_path(struct ccw_device *cdev) { struct ccw_request *req = &cdev->private->req; - if (!req->singlepath) { - req->mask = 0; - goto out; - } req->retries = req->maxretries; req->mask = lpm_adjust(req->mask >>= 1, req->lpm); -out: + return req->mask; } @@ -117,12 +113,8 @@ void ccw_request_start(struct ccw_device *cdev) { struct ccw_request *req = &cdev->private->req; - if (req->singlepath) { - /* Try all paths twice to counter link flapping. */ - req->mask = 0x8080; - } else - req->mask = req->lpm; - + /* Try all paths twice to counter link flapping. */ + req->mask = 0x8080; req->retries = req->maxretries; req->mask = lpm_adjust(req->mask, req->lpm); req->drc = 0; @@ -190,8 +182,6 @@ static enum io_status ccwreq_status(struct ccw_device *cdev, struct irb *lcirb) /* Ask the driver what to do */ if (cdev->drv && cdev->drv->uc_handler) { todo = cdev->drv->uc_handler(cdev, lcirb); - CIO_TRACE_EVENT(2, "uc_response"); - CIO_HEX_EVENT(2, &todo, sizeof(todo)); switch (todo) { case UC_TODO_RETRY: return IO_STATUS_ERROR; diff --git a/trunk/drivers/s390/cio/chsc.c b/trunk/drivers/s390/cio/chsc.c index 4cbb1a6ca33c..407d0e9adfaf 100644 --- a/trunk/drivers/s390/cio/chsc.c +++ b/trunk/drivers/s390/cio/chsc.c @@ -29,7 +29,6 @@ #include "chsc.h" static void *sei_page; -static DEFINE_SPINLOCK(siosl_lock); static DEFINE_SPINLOCK(sda_lock); /** @@ -49,7 +48,6 @@ int chsc_error_from_response(int response) case 0x0007: case 0x0008: case 0x000a: - case 0x0104: return -EINVAL; case 0x0004: return -EOPNOTSUPP; @@ -976,49 +974,3 @@ int chsc_sstpi(void *page, void *result, size_t size) return (rr->response.code == 0x0001) ? 0 : -EIO; } -static struct { - struct chsc_header request; - u32 word1; - struct subchannel_id sid; - u32 word3; - struct chsc_header response; - u32 word[11]; -} __attribute__ ((packed)) siosl_area __attribute__ ((__aligned__(PAGE_SIZE))); - -int chsc_siosl(struct subchannel_id schid) -{ - unsigned long flags; - int ccode; - int rc; - - spin_lock_irqsave(&siosl_lock, flags); - memset(&siosl_area, 0, sizeof(siosl_area)); - siosl_area.request.length = 0x0010; - siosl_area.request.code = 0x0046; - siosl_area.word1 = 0x80000000; - siosl_area.sid = schid; - - ccode = chsc(&siosl_area); - if (ccode > 0) { - if (ccode == 3) - rc = -ENODEV; - else - rc = -EBUSY; - CIO_MSG_EVENT(2, "chsc: chsc failed for 0.%x.%04x (ccode=%d)\n", - schid.ssid, schid.sch_no, ccode); - goto out; - } - rc = chsc_error_from_response(siosl_area.response.code); - if (rc) - CIO_MSG_EVENT(2, "chsc: siosl failed for 0.%x.%04x (rc=%04x)\n", - schid.ssid, schid.sch_no, - siosl_area.response.code); - else - CIO_MSG_EVENT(4, "chsc: siosl succeeded for 0.%x.%04x\n", - schid.ssid, schid.sch_no); -out: - spin_unlock_irqrestore(&siosl_lock, flags); - - return rc; -} -EXPORT_SYMBOL_GPL(chsc_siosl); diff --git a/trunk/drivers/s390/cio/chsc.h b/trunk/drivers/s390/cio/chsc.h index 5453013f094b..37aa611d4ac5 100644 --- a/trunk/drivers/s390/cio/chsc.h +++ b/trunk/drivers/s390/cio/chsc.h @@ -80,6 +80,4 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp); int chsc_error_from_response(int response); -int chsc_siosl(struct subchannel_id schid); - #endif diff --git a/trunk/drivers/s390/cio/device.c b/trunk/drivers/s390/cio/device.c index 51bd3687d163..6d229f3523a0 100644 --- a/trunk/drivers/s390/cio/device.c +++ b/trunk/drivers/s390/cio/device.c @@ -36,7 +36,6 @@ #include "ioasm.h" #include "io_sch.h" #include "blacklist.h" -#include "chsc.h" static struct timer_list recovery_timer; static DEFINE_SPINLOCK(recovery_lock); @@ -487,11 +486,9 @@ static int online_store_handle_offline(struct ccw_device *cdev) spin_lock_irq(cdev->ccwlock); ccw_device_sched_todo(cdev, CDEV_TODO_UNREG_EVAL); spin_unlock_irq(cdev->ccwlock); - return 0; - } - if (cdev->drv && cdev->drv->set_offline) + } else if (cdev->online && cdev->drv && cdev->drv->set_offline) return ccw_device_set_offline(cdev); - return -EINVAL; + return 0; } static int online_store_recog_and_online(struct ccw_device *cdev) @@ -508,8 +505,8 @@ static int online_store_recog_and_online(struct ccw_device *cdev) return -EAGAIN; } if (cdev->drv && cdev->drv->set_online) - return ccw_device_set_online(cdev); - return -EINVAL; + ccw_device_set_online(cdev); + return 0; } static int online_store_handle_online(struct ccw_device *cdev, int force) @@ -601,25 +598,6 @@ available_show (struct device *dev, struct device_attribute *attr, char *buf) } } -static ssize_t -initiate_logging(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct subchannel *sch = to_subchannel(dev); - int rc; - - rc = chsc_siosl(sch->schid); - if (rc < 0) { - pr_warning("Logging for subchannel 0.%x.%04x failed with " - "errno=%d\n", - sch->schid.ssid, sch->schid.sch_no, rc); - return rc; - } - pr_notice("Logging for subchannel 0.%x.%04x was triggered\n", - sch->schid.ssid, sch->schid.sch_no); - return count; -} - static DEVICE_ATTR(chpids, 0444, chpids_show, NULL); static DEVICE_ATTR(pimpampom, 0444, pimpampom_show, NULL); static DEVICE_ATTR(devtype, 0444, devtype_show, NULL); @@ -627,12 +605,10 @@ static DEVICE_ATTR(cutype, 0444, cutype_show, NULL); static DEVICE_ATTR(modalias, 0444, modalias_show, NULL); static DEVICE_ATTR(online, 0644, online_show, online_store); static DEVICE_ATTR(availability, 0444, available_show, NULL); -static DEVICE_ATTR(logging, 0200, NULL, initiate_logging); static struct attribute *io_subchannel_attrs[] = { &dev_attr_chpids.attr, &dev_attr_pimpampom.attr, - &dev_attr_logging.attr, NULL, }; @@ -2060,21 +2036,6 @@ void ccw_device_sched_todo(struct ccw_device *cdev, enum cdev_todo todo) } } -/** - * ccw_device_siosl() - initiate logging - * @cdev: ccw device - * - * This function is used to invoke model-dependent logging within the channel - * subsystem. - */ -int ccw_device_siosl(struct ccw_device *cdev) -{ - struct subchannel *sch = to_subchannel(cdev->dev.parent); - - return chsc_siosl(sch->schid); -} -EXPORT_SYMBOL_GPL(ccw_device_siosl); - MODULE_LICENSE("GPL"); EXPORT_SYMBOL(ccw_device_set_online); EXPORT_SYMBOL(ccw_device_set_offline); diff --git a/trunk/drivers/s390/cio/device_pgid.c b/trunk/drivers/s390/cio/device_pgid.c index 82a5ad0d63f6..6facb5499a65 100644 --- a/trunk/drivers/s390/cio/device_pgid.c +++ b/trunk/drivers/s390/cio/device_pgid.c @@ -208,7 +208,6 @@ static void spid_start(struct ccw_device *cdev) req->timeout = PGID_TIMEOUT; req->maxretries = PGID_RETRIES; req->lpm = 0x80; - req->singlepath = 1; req->callback = spid_callback; spid_do(cdev); } @@ -421,7 +420,6 @@ static void verify_start(struct ccw_device *cdev) req->timeout = PGID_TIMEOUT; req->maxretries = PGID_RETRIES; req->lpm = 0x80; - req->singlepath = 1; if (cdev->private->flags.pgroup) { CIO_TRACE_EVENT(4, "snid"); CIO_HEX_EVENT(4, devid, sizeof(*devid)); @@ -509,7 +507,6 @@ void ccw_device_disband_start(struct ccw_device *cdev) req->timeout = PGID_TIMEOUT; req->maxretries = PGID_RETRIES; req->lpm = sch->schib.pmcw.pam & sch->opm; - req->singlepath = 1; req->callback = disband_callback; fn = SPID_FUNC_DISBAND; if (cdev->private->flags.mpath) diff --git a/trunk/drivers/s390/cio/io_sch.h b/trunk/drivers/s390/cio/io_sch.h index 469ef93f2302..b9ce712a7f25 100644 --- a/trunk/drivers/s390/cio/io_sch.h +++ b/trunk/drivers/s390/cio/io_sch.h @@ -92,12 +92,11 @@ enum io_status { * @filter: optional callback to adjust request status based on IRB data * @callback: final callback * @data: user-defined pointer passed to all callbacks - * @singlepath: if set, use only one path from @lpm per start I/O - * @cancel: non-zero if request was cancelled - * @done: non-zero if request was finished * @mask: current path mask * @retries: current number of retries * @drc: delayed return code + * @cancel: non-zero if request was cancelled + * @done: non-zero if request was finished */ struct ccw_request { struct ccw1 *cp; @@ -109,13 +108,12 @@ struct ccw_request { enum io_status); void (*callback)(struct ccw_device *, void *, int); void *data; - unsigned int singlepath:1; /* These fields are used internally. */ - unsigned int cancel:1; - unsigned int done:1; u16 mask; u16 retries; int drc; + int cancel:1; + int done:1; } __attribute__((packed)); /* diff --git a/trunk/drivers/s390/net/smsgiucv_app.c b/trunk/drivers/s390/net/smsgiucv_app.c index 4d2ea4000422..137688790207 100644 --- a/trunk/drivers/s390/net/smsgiucv_app.c +++ b/trunk/drivers/s390/net/smsgiucv_app.c @@ -180,13 +180,6 @@ static int __init smsgiucv_app_init(void) goto fail_put_driver; } - /* convert sender to uppercase characters */ - if (sender) { - int len = strlen(sender); - while (len--) - sender[len] = toupper(sender[len]); - } - /* register with the smsgiucv device driver */ rc = smsg_register_callback(SMSG_PREFIX, smsg_app_callback); if (rc) { diff --git a/trunk/drivers/serial/21285.c b/trunk/drivers/serial/21285.c index d89aa38c5cf0..8681f1345056 100644 --- a/trunk/drivers/serial/21285.c +++ b/trunk/drivers/serial/21285.c @@ -216,7 +216,7 @@ serial21285_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { unsigned long flags; - unsigned int baud, quot, h_lcr, b; + unsigned int baud, quot, h_lcr; /* * We don't support modem control lines. @@ -234,8 +234,12 @@ serial21285_set_termios(struct uart_port *port, struct ktermios *termios, */ baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); quot = uart_get_divisor(port, baud); - b = port->uartclk / (16 * quot); - tty_termios_encode_baud_rate(termios, b, b); + + if (port->state && port->state->port.tty) { + struct tty_struct *tty = port->state->port.tty; + unsigned int b = port->uartclk / (16 * quot); + tty_encode_baud_rate(tty, b, b); + } switch (termios->c_cflag & CSIZE) { case CS5: diff --git a/trunk/drivers/serial/68328serial.c b/trunk/drivers/serial/68328serial.c index 7356a56ac458..30463862603b 100644 --- a/trunk/drivers/serial/68328serial.c +++ b/trunk/drivers/serial/68328serial.c @@ -78,6 +78,10 @@ struct m68k_serial *m68k_consinfo = 0; #define M68K_CLOCK (16667000) /* FIXME: 16MHz is likely wrong */ +#ifdef CONFIG_CONSOLE +extern wait_queue_head_t keypress_wait; +#endif + struct tty_driver *serial_driver; /* number of characters left in xmit buffer before we ask for more */ @@ -98,13 +102,19 @@ static void change_speed(struct m68k_serial *info); * Setup for console. Argument comes from the boot command line. */ -/* note: this is messy, but it works, again, perhaps defined somewhere else?*/ -#ifdef CONFIG_M68VZ328 -#define CONSOLE_BAUD_RATE 19200 -#define DEFAULT_CBAUD B19200 +#if defined(CONFIG_M68EZ328ADS) || defined(CONFIG_ALMA_ANS) || defined(CONFIG_DRAGONIXVZ) +#define CONSOLE_BAUD_RATE 115200 +#define DEFAULT_CBAUD B115200 +#else + /* (es) */ + /* note: this is messy, but it works, again, perhaps defined somewhere else?*/ + #ifdef CONFIG_M68VZ328 + #define CONSOLE_BAUD_RATE 19200 + #define DEFAULT_CBAUD B19200 + #endif + /* (/es) */ #endif - #ifndef CONSOLE_BAUD_RATE #define CONSOLE_BAUD_RATE 9600 #define DEFAULT_CBAUD B9600 @@ -290,6 +300,10 @@ static void receive_chars(struct m68k_serial *info, unsigned short rx) return; #endif /* CONFIG_MAGIC_SYSRQ */ } + /* It is a 'keyboard interrupt' ;-) */ +#ifdef CONFIG_CONSOLE + wake_up(&keypress_wait); +#endif } if(!tty) @@ -1229,9 +1243,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, retval = -ERESTARTSYS; break; } - tty_unlock(); schedule(); - tty_lock(); } current->state = TASK_RUNNING; remove_wait_queue(&info->open_wait, &wait); diff --git a/trunk/drivers/serial/68360serial.c b/trunk/drivers/serial/68360serial.c index 0dff3bbddc8b..768612f8e41e 100644 --- a/trunk/drivers/serial/68360serial.c +++ b/trunk/drivers/serial/68360serial.c @@ -1705,6 +1705,7 @@ static void rs_360_wait_until_sent(struct tty_struct *tty, int timeout) printk("jiff=%lu...", jiffies); #endif + lock_kernel(); /* We go through the loop at least once because we can't tell * exactly when the last character exits the shifter. There can * be at least two characters waiting to be sent after the buffers @@ -1733,6 +1734,7 @@ static void rs_360_wait_until_sent(struct tty_struct *tty, int timeout) bdp--; } while (bdp->status & BD_SC_READY); current->state = TASK_RUNNING; + unlock_kernel(); #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); #endif @@ -1860,9 +1862,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, printk("block_til_ready blocking: ttys%d, count = %d\n", info->line, state->count); #endif - tty_unlock(); schedule(); - tty_lock(); } current->state = TASK_RUNNING; remove_wait_queue(&info->open_wait, &wait); diff --git a/trunk/drivers/serial/8250.c b/trunk/drivers/serial/8250.c index 24110f6f61e0..09ef57034c9c 100644 --- a/trunk/drivers/serial/8250.c +++ b/trunk/drivers/serial/8250.c @@ -241,7 +241,7 @@ static const struct serial8250_config uart_config[] = { .fifo_size = 128, .tx_loadsz = 128, .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, - .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, + .flags = UART_CAP_FIFO, }, [PORT_16654] = { .name = "ST16654", @@ -300,13 +300,6 @@ static const struct serial8250_config uart_config[] = { .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00, .flags = UART_CAP_FIFO | UART_CAP_AFE, }, - [PORT_U6_16550A] = { - .name = "U6_16550A", - .fifo_size = 64, - .tx_loadsz = 64, - .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, - .flags = UART_CAP_FIFO | UART_CAP_AFE, - }, }; #if defined(CONFIG_MIPS_ALCHEMY) @@ -1077,15 +1070,6 @@ static void autoconfig_16550a(struct uart_8250_port *up) DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 "); } serial_outp(up, UART_IER, iersave); - - /* - * We distinguish between 16550A and U6 16550A by counting - * how many bytes are in the FIFO. - */ - if (up->port.type == PORT_16550A && size_fifo(up) == 64) { - up->port.type = PORT_U6_16550A; - up->capabilities |= UART_CAP_AFE; - } } /* @@ -2240,9 +2224,9 @@ static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int return quot; } -void -serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, - struct ktermios *old) +static void +serial8250_set_termios(struct uart_port *port, struct ktermios *termios, + struct ktermios *old) { struct uart_8250_port *up = (struct uart_8250_port *)port; unsigned char cval, fcr = 0; @@ -2418,22 +2402,16 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, if (tty_termios_baud_rate(termios)) tty_termios_encode_baud_rate(termios, baud, baud); } -EXPORT_SYMBOL(serial8250_do_set_termios); static void -serial8250_set_termios(struct uart_port *port, struct ktermios *termios, - struct ktermios *old) +serial8250_set_ldisc(struct uart_port *port) { - if (port->set_termios) - port->set_termios(port, termios, old); - else - serial8250_do_set_termios(port, termios, old); -} + int line = port->line; -static void -serial8250_set_ldisc(struct uart_port *port, int new) -{ - if (new == N_PPS) { + if (line >= port->state->port.tty->driver->num) + return; + + if (port->state->port.tty->ldisc->ops->num == N_PPS) { port->flags |= UPF_HARDPPS_CD; serial8250_enable_ms(port); } else @@ -3009,7 +2987,6 @@ static int __devinit serial8250_probe(struct platform_device *dev) port.type = p->type; port.serial_in = p->serial_in; port.serial_out = p->serial_out; - port.set_termios = p->set_termios; port.dev = &dev->dev; port.irqflags |= irqflag; ret = serial8250_register_port(&port); @@ -3173,9 +3150,6 @@ int serial8250_register_port(struct uart_port *port) uart->port.serial_in = port->serial_in; if (port->serial_out) uart->port.serial_out = port->serial_out; - /* Possibly override set_termios call */ - if (port->set_termios) - uart->port.set_termios = port->set_termios; ret = uart_add_one_port(&serial8250_reg, &uart->port); if (ret == 0) diff --git a/trunk/drivers/serial/8250_early.c b/trunk/drivers/serial/8250_early.c index b745792ec25a..f279745e9fef 100644 --- a/trunk/drivers/serial/8250_early.c +++ b/trunk/drivers/serial/8250_early.c @@ -19,11 +19,9 @@ * The user can specify the device directly, e.g., * earlycon=uart8250,io,0x3f8,9600n8 * earlycon=uart8250,mmio,0xff5e0000,115200n8 - * earlycon=uart8250,mmio32,0xff5e0000,115200n8 * or * console=uart8250,io,0x3f8,9600n8 * console=uart8250,mmio,0xff5e0000,115200n8 - * console=uart8250,mmio32,0xff5e0000,115200n8 */ #include @@ -50,31 +48,18 @@ static struct early_serial8250_device early_device; static unsigned int __init serial_in(struct uart_port *port, int offset) { - switch (port->iotype) { - case UPIO_MEM: + if (port->iotype == UPIO_MEM) return readb(port->membase + offset); - case UPIO_MEM32: - return readl(port->membase + (offset << 2)); - case UPIO_PORT: + else return inb(port->iobase + offset); - default: - return 0; - } } static void __init serial_out(struct uart_port *port, int offset, int value) { - switch (port->iotype) { - case UPIO_MEM: + if (port->iotype == UPIO_MEM) writeb(value, port->membase + offset); - break; - case UPIO_MEM32: - writel(value, port->membase + (offset << 2)); - break; - case UPIO_PORT: + else outb(value, port->iobase + offset); - break; - } } #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) @@ -152,21 +137,15 @@ static int __init parse_options(struct early_serial8250_device *device, char *options) { struct uart_port *port = &device->port; - int mmio, mmio32, length; + int mmio, length; if (!options) return -ENODEV; port->uartclk = BASE_BAUD * 16; - - mmio = !strncmp(options, "mmio,", 5); - mmio32 = !strncmp(options, "mmio32,", 7); - if (mmio || mmio32) { - port->iotype = (mmio ? UPIO_MEM : UPIO_MEM32); - port->mapbase = simple_strtoul(options + (mmio ? 5 : 7), - &options, 0); - if (mmio32) - port->regshift = 2; + if (!strncmp(options, "mmio,", 5)) { + port->iotype = UPIO_MEM; + port->mapbase = simple_strtoul(options + 5, &options, 0); #ifdef CONFIG_FIX_EARLYCON_MEM set_fixmap_nocache(FIX_EARLYCON_MEM_BASE, port->mapbase & PAGE_MASK); @@ -178,10 +157,11 @@ static int __init parse_options(struct early_serial8250_device *device, if (!port->membase) { printk(KERN_ERR "%s: Couldn't ioremap 0x%llx\n", __func__, - (unsigned long long) port->mapbase); + (unsigned long long)port->mapbase); return -ENOMEM; } #endif + mmio = 1; } else if (!strncmp(options, "io,", 3)) { port->iotype = UPIO_PORT; port->iobase = simple_strtoul(options + 3, &options, 0); @@ -201,18 +181,11 @@ static int __init parse_options(struct early_serial8250_device *device, device->baud); } - if (mmio || mmio32) - printk(KERN_INFO - "Early serial console at MMIO%s 0x%llu (options '%s')\n", - mmio32 ? "32" : "", - (unsigned long long)port->mapbase, - device->options); - else - printk(KERN_INFO - "Early serial console at I/O port 0x%lu (options '%s')\n", - port->iobase, - device->options); - + printk(KERN_INFO "Early serial console at %s 0x%llx (options '%s')\n", + mmio ? "MMIO" : "I/O port", + mmio ? (unsigned long long) port->mapbase + : (unsigned long long) port->iobase, + device->options); return 0; } diff --git a/trunk/drivers/serial/8250_pci.c b/trunk/drivers/serial/8250_pci.c index 53be4d35a0aa..746a44621d91 100644 --- a/trunk/drivers/serial/8250_pci.c +++ b/trunk/drivers/serial/8250_pci.c @@ -994,7 +994,6 @@ static int skip_tx_en_setup(struct serial_private *priv, #define PCI_DEVICE_ID_TITAN_800E 0xA014 #define PCI_DEVICE_ID_TITAN_200EI 0xA016 #define PCI_DEVICE_ID_TITAN_200EISI 0xA017 -#define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538 /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 @@ -1543,8 +1542,6 @@ enum pci_board_num_t { pbn_b2_4_921600, pbn_b2_8_921600, - pbn_b2_8_1152000, - pbn_b2_bt_1_115200, pbn_b2_bt_2_115200, pbn_b2_bt_4_115200, @@ -1963,13 +1960,6 @@ static struct pciserial_board pci_boards[] __devinitdata = { .uart_offset = 8, }, - [pbn_b2_8_1152000] = { - .flags = FL_BASE2, - .num_ports = 8, - .base_baud = 1152000, - .uart_offset = 8, - }, - [pbn_b2_bt_1_115200] = { .flags = FL_BASE2|FL_BASE_BARS, .num_ports = 1, @@ -2885,9 +2875,6 @@ static struct pci_device_id serial_pci_tbl[] = { { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b0_bt_2_921600 }, - { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI958, - PCI_ANY_ID , PCI_ANY_ID, 0, 0, - pbn_b2_8_1152000 }, /* * Oxford Semiconductor Inc. Tornado PCI express device range. diff --git a/trunk/drivers/serial/Kconfig b/trunk/drivers/serial/Kconfig index a22e60c06f48..e437ce8c1748 100644 --- a/trunk/drivers/serial/Kconfig +++ b/trunk/drivers/serial/Kconfig @@ -542,7 +542,6 @@ config SERIAL_S5PV210 help Serial port support for Samsung's S5P Family of SoC's - config SERIAL_MAX3100 tristate "MAX3100 support" depends on SPI @@ -550,22 +549,6 @@ config SERIAL_MAX3100 help MAX3100 chip support -config SERIAL_MAX3107 - tristate "MAX3107 support" - depends on SPI - select SERIAL_CORE - help - MAX3107 chip support - -config SERIAL_MAX3107_AAVA - tristate "MAX3107 AAVA platform support" - depends on X86_MRST && SERIAL_MAX3107 && GPIOLIB - select SERIAL_CORE - help - Support for the MAX3107 chip configuration found on the AAVA - platform. Includes the extra initialisation and GPIO support - neded for this device. - config SERIAL_DZ bool "DECstation DZ serial driver" depends on MACH_DECSTATION && 32BIT @@ -707,33 +690,6 @@ config SERIAL_SA1100_CONSOLE your boot loader (lilo or loadlin) about how to pass options to the kernel at boot time.) -config SERIAL_MRST_MAX3110 - tristate "SPI UART driver for Max3110" - depends on SPI_DW_PCI - select SERIAL_CORE - select SERIAL_CORE_CONSOLE - help - This is the UART protocol driver for the MAX3110 device on - the Intel Moorestown platform. On other systems use the max3100 - driver. - -config MRST_MAX3110_IRQ - boolean "Enable GPIO IRQ for Max3110 over Moorestown" - default n - depends on SERIAL_MRST_MAX3110 && GPIO_LANGWELL - help - This has to be enabled after Moorestown GPIO driver is loaded - -config SERIAL_MFD_HSU - tristate "Medfield High Speed UART support" - depends on PCI - select SERIAL_CORE - -config SERIAL_MFD_HSU_CONSOLE - boolean "Medfile HSU serial console support" - depends on SERIAL_MFD_HSU=y - select SERIAL_CORE_CONSOLE - config SERIAL_BFIN tristate "Blackfin serial port support" depends on BLACKFIN diff --git a/trunk/drivers/serial/Makefile b/trunk/drivers/serial/Makefile index 1ca4fd599ffe..208a85572c32 100644 --- a/trunk/drivers/serial/Makefile +++ b/trunk/drivers/serial/Makefile @@ -46,8 +46,6 @@ obj-$(CONFIG_SERIAL_S3C24A0) += s3c24a0.o obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o obj-$(CONFIG_SERIAL_S5PV210) += s5pv210.o obj-$(CONFIG_SERIAL_MAX3100) += max3100.o -obj-$(CONFIG_SERIAL_MAX3107) += max3107.o -obj-$(CONFIG_SERIAL_MAX3107_AAVA) += max3107-aava.o obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o obj-$(CONFIG_SERIAL_MUX) += mux.o obj-$(CONFIG_SERIAL_68328) += 68328serial.o @@ -86,5 +84,3 @@ obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o obj-$(CONFIG_SERIAL_ALTERA_JTAGUART) += altera_jtaguart.o obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o -obj-$(CONFIG_SERIAL_MRST_MAX3110) += mrst_max3110.o -obj-$(CONFIG_SERIAL_MFD_HSU) += mfd.o diff --git a/trunk/drivers/serial/altera_uart.c b/trunk/drivers/serial/altera_uart.c index f8d8a00554da..0f1189605d21 100644 --- a/trunk/drivers/serial/altera_uart.c +++ b/trunk/drivers/serial/altera_uart.c @@ -394,7 +394,7 @@ int __init early_altera_uart_setup(struct altera_uart_platform_uart *platp) static void altera_uart_console_putc(struct uart_port *port, const char c) { while (!(readl(port->membase + ALTERA_UART_STATUS_REG) & - ALTERA_UART_STATUS_TRDY_MSK)) + ALTERA_UART_STATUS_TRDY_MSK)) cpu_relax(); writel(c, port->membase + ALTERA_UART_TXDATA_REG); diff --git a/trunk/drivers/serial/atmel_serial.c b/trunk/drivers/serial/atmel_serial.c index 3892666b5fbd..a182def7007d 100644 --- a/trunk/drivers/serial/atmel_serial.c +++ b/trunk/drivers/serial/atmel_serial.c @@ -217,8 +217,7 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) if (rs485conf->flags & SER_RS485_ENABLED) { dev_dbg(port->dev, "Setting UART to RS485\n"); atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; - if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND) - UART_PUT_TTGR(port, rs485conf->delay_rts_after_send); + UART_PUT_TTGR(port, rs485conf->delay_rts_before_send); mode |= ATMEL_US_USMODE_RS485; } else { dev_dbg(port->dev, "Setting UART to RS232\n"); @@ -293,9 +292,7 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl) if (atmel_port->rs485.flags & SER_RS485_ENABLED) { dev_dbg(port->dev, "Setting UART to RS485\n"); - if (atmel_port->rs485.flags & SER_RS485_RTS_AFTER_SEND) - UART_PUT_TTGR(port, - atmel_port->rs485.delay_rts_after_send); + UART_PUT_TTGR(port, atmel_port->rs485.delay_rts_before_send); mode |= ATMEL_US_USMODE_RS485; } else { dev_dbg(port->dev, "Setting UART to RS232\n"); @@ -1214,9 +1211,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, if (atmel_port->rs485.flags & SER_RS485_ENABLED) { dev_dbg(port->dev, "Setting UART to RS485\n"); - if (atmel_port->rs485.flags & SER_RS485_RTS_AFTER_SEND) - UART_PUT_TTGR(port, - atmel_port->rs485.delay_rts_after_send); + UART_PUT_TTGR(port, atmel_port->rs485.delay_rts_before_send); mode |= ATMEL_US_USMODE_RS485; } else { dev_dbg(port->dev, "Setting UART to RS232\n"); diff --git a/trunk/drivers/serial/bfin_5xx.c b/trunk/drivers/serial/bfin_5xx.c index a9eff2b18eab..511cbf687877 100644 --- a/trunk/drivers/serial/bfin_5xx.c +++ b/trunk/drivers/serial/bfin_5xx.c @@ -957,12 +957,15 @@ bfin_serial_verify_port(struct uart_port *port, struct serial_struct *ser) * Enable the IrDA function if tty->ldisc.num is N_IRDA. * In other cases, disable IrDA function. */ -static void bfin_serial_set_ldisc(struct uart_port *port, int ld) +static void bfin_serial_set_ldisc(struct uart_port *port) { int line = port->line; unsigned short val; - switch (ld) { + if (line >= port->state->port.tty->driver->num) + return; + + switch (port->state->port.tty->termios->c_line) { case N_IRDA: val = UART_GET_GCTL(&bfin_serial_ports[line]); val |= (IREN | RPOLC); diff --git a/trunk/drivers/serial/crisv10.c b/trunk/drivers/serial/crisv10.c index c856905bb3bd..30626440a062 100644 --- a/trunk/drivers/serial/crisv10.c +++ b/trunk/drivers/serial/crisv10.c @@ -3935,6 +3935,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) * Check R_DMA_CHx_STATUS bit 0-6=number of available bytes in FIFO * R_DMA_CHx_HWSW bit 31-16=nbr of bytes left in DMA buffer (0=64k) */ + lock_kernel(); orig_jiffies = jiffies; while (info->xmit.head != info->xmit.tail || /* More in send queue */ (*info->ostatusadr & 0x007f) || /* more in FIFO */ @@ -3951,6 +3952,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) curr_time_usec - info->last_tx_active_usec; } set_current_state(TASK_RUNNING); + unlock_kernel(); } /* @@ -3990,7 +3992,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, */ if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) { - wait_event_interruptible_tty(info->close_wait, + wait_event_interruptible(info->close_wait, !(info->flags & ASYNC_CLOSING)); #ifdef SERIAL_DO_RESTART if (info->flags & ASYNC_HUP_NOTIFY) @@ -4066,9 +4068,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, printk("block_til_ready blocking: ttyS%d, count = %d\n", info->line, info->count); #endif - tty_unlock(); schedule(); - tty_lock(); } set_current_state(TASK_RUNNING); remove_wait_queue(&info->open_wait, &wait); @@ -4150,7 +4150,7 @@ rs_open(struct tty_struct *tty, struct file * filp) */ if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) { - wait_event_interruptible_tty(info->close_wait, + wait_event_interruptible(info->close_wait, !(info->flags & ASYNC_CLOSING)); #ifdef SERIAL_DO_RESTART return ((info->flags & ASYNC_HUP_NOTIFY) ? @@ -4533,8 +4533,8 @@ static int __init rs_init(void) INIT_WORK(&info->work, do_softint); if (info->enabled) { - printk(KERN_INFO "%s%d at %p is a builtin UART with DMA\n", - serial_driver->name, info->line, info->ioport); + printk(KERN_INFO "%s%d at 0x%x is a builtin UART with DMA\n", + serial_driver->name, info->line, (unsigned int)info->ioport); } } #ifdef CONFIG_ETRAX_FAST_TIMER diff --git a/trunk/drivers/serial/imx.c b/trunk/drivers/serial/imx.c index 66ecc7ab6dab..eacb588a9345 100644 --- a/trunk/drivers/serial/imx.c +++ b/trunk/drivers/serial/imx.c @@ -909,11 +909,13 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, rational_best_approximation(16 * div * baud, sport->port.uartclk, 1 << 16, 1 << 16, &num, &denom); - tdiv64 = sport->port.uartclk; - tdiv64 *= num; - do_div(tdiv64, denom * 16 * div); - tty_termios_encode_baud_rate(termios, + if (port->state && port->state->port.tty) { + tdiv64 = sport->port.uartclk; + tdiv64 *= num; + do_div(tdiv64, denom * 16 * div); + tty_encode_baud_rate(sport->port.state->port.tty, (speed_t)tdiv64, (speed_t)tdiv64); + } num -= 1; denom -= 1; diff --git a/trunk/drivers/serial/ioc3_serial.c b/trunk/drivers/serial/ioc3_serial.c index 93de907b1208..f164ba4eba02 100644 --- a/trunk/drivers/serial/ioc3_serial.c +++ b/trunk/drivers/serial/ioc3_serial.c @@ -954,13 +954,12 @@ ioc3_change_speed(struct uart_port *the_port, struct ktermios *new_termios, struct ktermios *old_termios) { struct ioc3_port *port = get_ioc3_port(the_port); - unsigned int cflag, iflag; + unsigned int cflag; int baud; int new_parity = 0, new_parity_enable = 0, new_stop = 0, new_data = 8; struct uart_state *state = the_port->state; cflag = new_termios->c_cflag; - iflag = new_termios->c_iflag; switch (cflag & CSIZE) { case CS5: @@ -1001,12 +1000,12 @@ ioc3_change_speed(struct uart_port *the_port, state->port.tty->low_latency = 1; - if (iflag & IGNPAR) + if (I_IGNPAR(state->port.tty)) the_port->ignore_status_mask &= ~(N_PARITY_ERROR | N_FRAMING_ERROR); - if (iflag & IGNBRK) { + if (I_IGNBRK(state->port.tty)) { the_port->ignore_status_mask &= ~N_BREAK; - if (iflag & IGNPAR) + if (I_IGNPAR(state->port.tty)) the_port->ignore_status_mask &= ~N_OVERRUN_ERROR; } if (!(cflag & CREAD)) { diff --git a/trunk/drivers/serial/ioc4_serial.c b/trunk/drivers/serial/ioc4_serial.c index fcfe82653ac8..8ad28fc64926 100644 --- a/trunk/drivers/serial/ioc4_serial.c +++ b/trunk/drivers/serial/ioc4_serial.c @@ -1685,12 +1685,11 @@ ioc4_change_speed(struct uart_port *the_port, { struct ioc4_port *port = get_ioc4_port(the_port, 0); int baud, bits; - unsigned cflag, iflag; + unsigned cflag; int new_parity = 0, new_parity_enable = 0, new_stop = 0, new_data = 8; struct uart_state *state = the_port->state; cflag = new_termios->c_cflag; - iflag = new_termios->c_iflag; switch (cflag & CSIZE) { case CS5: @@ -1742,12 +1741,12 @@ ioc4_change_speed(struct uart_port *the_port, state->port.tty->low_latency = 1; - if (iflag & IGNPAR) + if (I_IGNPAR(state->port.tty)) the_port->ignore_status_mask &= ~(N_PARITY_ERROR | N_FRAMING_ERROR); - if (iflag & IGNBRK) { + if (I_IGNBRK(state->port.tty)) { the_port->ignore_status_mask &= ~N_BREAK; - if (iflag & IGNPAR) + if (I_IGNPAR(state->port.tty)) the_port->ignore_status_mask &= ~N_OVERRUN_ERROR; } if (!(cflag & CREAD)) { diff --git a/trunk/drivers/serial/max3100.c b/trunk/drivers/serial/max3100.c index beb1afa27d8d..3351c3bd59e4 100644 --- a/trunk/drivers/serial/max3100.c +++ b/trunk/drivers/serial/max3100.c @@ -430,14 +430,17 @@ max3100_set_termios(struct uart_port *port, struct ktermios *termios, int baud = 0; unsigned cflag; u32 param_new, param_mask, parity = 0; + struct tty_struct *tty = s->port.state->port.tty; dev_dbg(&s->spi->dev, "%s\n", __func__); + if (!tty) + return; cflag = termios->c_cflag; param_new = 0; param_mask = 0; - baud = tty_termios_baud_rate(termios); + baud = tty_get_baud_rate(tty); param_new = s->conf & MAX3100_BAUD; switch (baud) { case 300: @@ -482,7 +485,7 @@ max3100_set_termios(struct uart_port *port, struct ktermios *termios, default: baud = s->baud; } - tty_termios_encode_baud_rate(termios, baud, baud); + tty_encode_baud_rate(tty, baud, baud); s->baud = baud; param_mask |= MAX3100_BAUD; diff --git a/trunk/drivers/serial/max3107-aava.c b/trunk/drivers/serial/max3107-aava.c deleted file mode 100644 index a1fe304f2f52..000000000000 --- a/trunk/drivers/serial/max3107-aava.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * max3107.c - spi uart protocol driver for Maxim 3107 - * Based on max3100.c - * by Christian Pellegrin - * and max3110.c - * by Feng Tang - * - * Copyright (C) Aavamobile 2009 - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "max3107.h" - -/* GPIO direction to input function */ -static int max3107_gpio_direction_in(struct gpio_chip *chip, unsigned offset) -{ - struct max3107_port *s = container_of(chip, struct max3107_port, chip); - u16 buf[1]; /* Buffer for SPI transfer */ - - if (offset >= MAX3107_GPIO_COUNT) { - dev_err(&s->spi->dev, "Invalid GPIO\n"); - return -EINVAL; - } - - /* Read current GPIO configuration register */ - buf[0] = MAX3107_GPIOCFG_REG; - /* Perform SPI transfer */ - if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) { - dev_err(&s->spi->dev, "SPI transfer GPIO read failed\n"); - return -EIO; - } - buf[0] &= MAX3107_SPI_RX_DATA_MASK; - - /* Set GPIO to input */ - buf[0] &= ~(0x0001 << offset); - - /* Write new GPIO configuration register value */ - buf[0] |= (MAX3107_WRITE_BIT | MAX3107_GPIOCFG_REG); - /* Perform SPI transfer */ - if (max3107_rw(s, (u8 *)buf, NULL, 2)) { - dev_err(&s->spi->dev, "SPI transfer GPIO write failed\n"); - return -EIO; - } - return 0; -} - -/* GPIO direction to output function */ -static int max3107_gpio_direction_out(struct gpio_chip *chip, unsigned offset, - int value) -{ - struct max3107_port *s = container_of(chip, struct max3107_port, chip); - u16 buf[2]; /* Buffer for SPI transfers */ - - if (offset >= MAX3107_GPIO_COUNT) { - dev_err(&s->spi->dev, "Invalid GPIO\n"); - return -EINVAL; - } - - /* Read current GPIO configuration and data registers */ - buf[0] = MAX3107_GPIOCFG_REG; - buf[1] = MAX3107_GPIODATA_REG; - /* Perform SPI transfer */ - if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 4)) { - dev_err(&s->spi->dev, "SPI transfer gpio failed\n"); - return -EIO; - } - buf[0] &= MAX3107_SPI_RX_DATA_MASK; - buf[1] &= MAX3107_SPI_RX_DATA_MASK; - - /* Set GPIO to output */ - buf[0] |= (0x0001 << offset); - /* Set value */ - if (value) - buf[1] |= (0x0001 << offset); - else - buf[1] &= ~(0x0001 << offset); - - /* Write new GPIO configuration and data register values */ - buf[0] |= (MAX3107_WRITE_BIT | MAX3107_GPIOCFG_REG); - buf[1] |= (MAX3107_WRITE_BIT | MAX3107_GPIODATA_REG); - /* Perform SPI transfer */ - if (max3107_rw(s, (u8 *)buf, NULL, 4)) { - dev_err(&s->spi->dev, - "SPI transfer for GPIO conf data w failed\n"); - return -EIO; - } - return 0; -} - -/* GPIO value query function */ -static int max3107_gpio_get(struct gpio_chip *chip, unsigned offset) -{ - struct max3107_port *s = container_of(chip, struct max3107_port, chip); - u16 buf[1]; /* Buffer for SPI transfer */ - - if (offset >= MAX3107_GPIO_COUNT) { - dev_err(&s->spi->dev, "Invalid GPIO\n"); - return -EINVAL; - } - - /* Read current GPIO data register */ - buf[0] = MAX3107_GPIODATA_REG; - /* Perform SPI transfer */ - if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) { - dev_err(&s->spi->dev, "SPI transfer GPIO data r failed\n"); - return -EIO; - } - buf[0] &= MAX3107_SPI_RX_DATA_MASK; - - /* Return value */ - return buf[0] & (0x0001 << offset); -} - -/* GPIO value set function */ -static void max3107_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -{ - struct max3107_port *s = container_of(chip, struct max3107_port, chip); - u16 buf[2]; /* Buffer for SPI transfers */ - - if (offset >= MAX3107_GPIO_COUNT) { - dev_err(&s->spi->dev, "Invalid GPIO\n"); - return; - } - - /* Read current GPIO configuration registers*/ - buf[0] = MAX3107_GPIODATA_REG; - buf[1] = MAX3107_GPIOCFG_REG; - /* Perform SPI transfer */ - if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 4)) { - dev_err(&s->spi->dev, - "SPI transfer for GPIO data and config read failed\n"); - return; - } - buf[0] &= MAX3107_SPI_RX_DATA_MASK; - buf[1] &= MAX3107_SPI_RX_DATA_MASK; - - if (!(buf[1] & (0x0001 << offset))) { - /* Configured as input, can't set value */ - dev_warn(&s->spi->dev, - "Trying to set value for input GPIO\n"); - return; - } - - /* Set value */ - if (value) - buf[0] |= (0x0001 << offset); - else - buf[0] &= ~(0x0001 << offset); - - /* Write new GPIO data register value */ - buf[0] |= (MAX3107_WRITE_BIT | MAX3107_GPIODATA_REG); - /* Perform SPI transfer */ - if (max3107_rw(s, (u8 *)buf, NULL, 2)) - dev_err(&s->spi->dev, "SPI transfer GPIO data w failed\n"); -} - -/* GPIO chip data */ -static struct gpio_chip max3107_gpio_chip = { - .owner = THIS_MODULE, - .direction_input = max3107_gpio_direction_in, - .direction_output = max3107_gpio_direction_out, - .get = max3107_gpio_get, - .set = max3107_gpio_set, - .can_sleep = 1, - .base = MAX3107_GPIO_BASE, - .ngpio = MAX3107_GPIO_COUNT, -}; - -/** - * max3107_aava_reset - reset on AAVA systems - * @spi: The SPI device we are probing - * - * Reset the device ready for probing. - */ - -static int max3107_aava_reset(struct spi_device *spi) -{ - /* Reset the chip */ - if (gpio_request(MAX3107_RESET_GPIO, "max3107")) { - pr_err("Requesting RESET GPIO failed\n"); - return -EIO; - } - if (gpio_direction_output(MAX3107_RESET_GPIO, 0)) { - pr_err("Setting RESET GPIO to 0 failed\n"); - gpio_free(MAX3107_RESET_GPIO); - return -EIO; - } - msleep(MAX3107_RESET_DELAY); - if (gpio_direction_output(MAX3107_RESET_GPIO, 1)) { - pr_err("Setting RESET GPIO to 1 failed\n"); - gpio_free(MAX3107_RESET_GPIO); - return -EIO; - } - gpio_free(MAX3107_RESET_GPIO); - msleep(MAX3107_WAKEUP_DELAY); - return 0; -} - -static int max3107_aava_configure(struct max3107_port *s) -{ - int retval; - - /* Initialize GPIO chip data */ - s->chip = max3107_gpio_chip; - s->chip.label = s->spi->modalias; - s->chip.dev = &s->spi->dev; - - /* Add GPIO chip */ - retval = gpiochip_add(&s->chip); - if (retval) { - dev_err(&s->spi->dev, "Adding GPIO chip failed\n"); - return retval; - } - - /* Temporary fix for EV2 boot problems, set modem reset to 0 */ - max3107_gpio_direction_out(&s->chip, 3, 0); - return 0; -} - -#if 0 -/* This will get enabled once we have the board stuff merged for this - specific case */ - -static const struct baud_table brg13_ext[] = { - { 300, MAX3107_BRG13_B300 }, - { 600, MAX3107_BRG13_B600 }, - { 1200, MAX3107_BRG13_B1200 }, - { 2400, MAX3107_BRG13_B2400 }, - { 4800, MAX3107_BRG13_B4800 }, - { 9600, MAX3107_BRG13_B9600 }, - { 19200, MAX3107_BRG13_B19200 }, - { 57600, MAX3107_BRG13_B57600 }, - { 115200, MAX3107_BRG13_B115200 }, - { 230400, MAX3107_BRG13_B230400 }, - { 460800, MAX3107_BRG13_B460800 }, - { 921600, MAX3107_BRG13_B921600 }, - { 0, 0 } -}; - -static void max3107_aava_init(struct max3107_port *s) -{ - /*override for AAVA SC specific*/ - if (mrst_platform_id() == MRST_PLATFORM_AAVA_SC) { - if (get_koski_build_id() <= KOSKI_EV2) - if (s->ext_clk) { - s->brg_cfg = MAX3107_BRG13_B9600; - s->baud_tbl = (struct baud_table *)brg13_ext; - } - } -} -#endif - -static int __devexit max3107_aava_remove(struct spi_device *spi) -{ - struct max3107_port *s = dev_get_drvdata(&spi->dev); - - /* Remove GPIO chip */ - if (gpiochip_remove(&s->chip)) - dev_warn(&spi->dev, "Removing GPIO chip failed\n"); - - /* Then do the default remove */ - return max3107_remove(spi); -} - -/* Platform data */ -static struct max3107_plat aava_plat_data = { - .loopback = 0, - .ext_clk = 1, -/* .init = max3107_aava_init, */ - .configure = max3107_aava_configure, - .hw_suspend = max3107_hw_susp, - .polled_mode = 0, - .poll_time = 0, -}; - - -static int __devinit max3107_probe_aava(struct spi_device *spi) -{ - int err = max3107_aava_reset(spi); - if (err < 0) - return err; - return max3107_probe(spi, &aava_plat_data); -} - -/* Spi driver data */ -static struct spi_driver max3107_driver = { - .driver = { - .name = "aava-max3107", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - .probe = max3107_probe_aava, - .remove = __devexit_p(max3107_aava_remove), - .suspend = max3107_suspend, - .resume = max3107_resume, -}; - -/* Driver init function */ -static int __init max3107_init(void) -{ - return spi_register_driver(&max3107_driver); -} - -/* Driver exit function */ -static void __exit max3107_exit(void) -{ - spi_unregister_driver(&max3107_driver); -} - -module_init(max3107_init); -module_exit(max3107_exit); - -MODULE_DESCRIPTION("MAX3107 driver"); -MODULE_AUTHOR("Aavamobile"); -MODULE_ALIAS("aava-max3107-spi"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/serial/max3107.c b/trunk/drivers/serial/max3107.c deleted file mode 100644 index 67283c1a57ff..000000000000 --- a/trunk/drivers/serial/max3107.c +++ /dev/null @@ -1,1197 +0,0 @@ -/* - * max3107.c - spi uart protocol driver for Maxim 3107 - * Based on max3100.c - * by Christian Pellegrin - * and max3110.c - * by Feng Tang - * - * Copyright (C) Aavamobile 2009 - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include "max3107.h" - -static const struct baud_table brg26_ext[] = { - { 300, MAX3107_BRG26_B300 }, - { 600, MAX3107_BRG26_B600 }, - { 1200, MAX3107_BRG26_B1200 }, - { 2400, MAX3107_BRG26_B2400 }, - { 4800, MAX3107_BRG26_B4800 }, - { 9600, MAX3107_BRG26_B9600 }, - { 19200, MAX3107_BRG26_B19200 }, - { 57600, MAX3107_BRG26_B57600 }, - { 115200, MAX3107_BRG26_B115200 }, - { 230400, MAX3107_BRG26_B230400 }, - { 460800, MAX3107_BRG26_B460800 }, - { 921600, MAX3107_BRG26_B921600 }, - { 0, 0 } -}; - -static const struct baud_table brg13_int[] = { - { 300, MAX3107_BRG13_IB300 }, - { 600, MAX3107_BRG13_IB600 }, - { 1200, MAX3107_BRG13_IB1200 }, - { 2400, MAX3107_BRG13_IB2400 }, - { 4800, MAX3107_BRG13_IB4800 }, - { 9600, MAX3107_BRG13_IB9600 }, - { 19200, MAX3107_BRG13_IB19200 }, - { 57600, MAX3107_BRG13_IB57600 }, - { 115200, MAX3107_BRG13_IB115200 }, - { 230400, MAX3107_BRG13_IB230400 }, - { 460800, MAX3107_BRG13_IB460800 }, - { 921600, MAX3107_BRG13_IB921600 }, - { 0, 0 } -}; - -static u32 get_new_brg(int baud, struct max3107_port *s) -{ - int i; - const struct baud_table *baud_tbl = s->baud_tbl; - - for (i = 0; i < 13; i++) { - if (baud == baud_tbl[i].baud) - return baud_tbl[i].new_brg; - } - - return 0; -} - -/* Perform SPI transfer for write/read of device register(s) */ -int max3107_rw(struct max3107_port *s, u8 *tx, u8 *rx, int len) -{ - struct spi_message spi_msg; - struct spi_transfer spi_xfer; - - /* Initialize SPI ,message */ - spi_message_init(&spi_msg); - - /* Initialize SPI transfer */ - memset(&spi_xfer, 0, sizeof spi_xfer); - spi_xfer.len = len; - spi_xfer.tx_buf = tx; - spi_xfer.rx_buf = rx; - spi_xfer.speed_hz = MAX3107_SPI_SPEED; - - /* Add SPI transfer to SPI message */ - spi_message_add_tail(&spi_xfer, &spi_msg); - -#ifdef DBG_TRACE_SPI_DATA - { - int i; - pr_info("tx len %d:\n", spi_xfer.len); - for (i = 0 ; i < spi_xfer.len && i < 32 ; i++) - pr_info(" %x", ((u8 *)spi_xfer.tx_buf)[i]); - pr_info("\n"); - } -#endif - - /* Perform synchronous SPI transfer */ - if (spi_sync(s->spi, &spi_msg)) { - dev_err(&s->spi->dev, "spi_sync failure\n"); - return -EIO; - } - -#ifdef DBG_TRACE_SPI_DATA - if (spi_xfer.rx_buf) { - int i; - pr_info("rx len %d:\n", spi_xfer.len); - for (i = 0 ; i < spi_xfer.len && i < 32 ; i++) - pr_info(" %x", ((u8 *)spi_xfer.rx_buf)[i]); - pr_info("\n"); - } -#endif - return 0; -} -EXPORT_SYMBOL_GPL(max3107_rw); - -/* Puts received data to circular buffer */ -static void put_data_to_circ_buf(struct max3107_port *s, unsigned char *data, - int len) -{ - struct uart_port *port = &s->port; - struct tty_struct *tty; - - if (!port->state) - return; - - tty = port->state->port.tty; - if (!tty) - return; - - /* Insert received data */ - tty_insert_flip_string(tty, data, len); - /* Update RX counter */ - port->icount.rx += len; -} - -/* Handle data receiving */ -static void max3107_handlerx(struct max3107_port *s, u16 rxlvl) -{ - int i; - int j; - int len; /* SPI transfer buffer length */ - u16 *buf; - u8 *valid_str; - - if (!s->rx_enabled) - /* RX is disabled */ - return; - - if (rxlvl == 0) { - /* RX fifo is empty */ - return; - } else if (rxlvl >= MAX3107_RX_FIFO_SIZE) { - dev_warn(&s->spi->dev, "Possible RX FIFO overrun %d\n", rxlvl); - /* Ensure sanity of RX level */ - rxlvl = MAX3107_RX_FIFO_SIZE; - } - if ((s->rxbuf == 0) || (s->rxstr == 0)) { - dev_warn(&s->spi->dev, "Rx buffer/str isn't ready\n"); - return; - } - buf = s->rxbuf; - valid_str = s->rxstr; - while (rxlvl) { - pr_debug("rxlvl %d\n", rxlvl); - /* Clear buffer */ - memset(buf, 0, sizeof(u16) * (MAX3107_RX_FIFO_SIZE + 2)); - len = 0; - if (s->irqen_reg & MAX3107_IRQ_RXFIFO_BIT) { - /* First disable RX FIFO interrupt */ - pr_debug("Disabling RX INT\n"); - buf[0] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG); - s->irqen_reg &= ~MAX3107_IRQ_RXFIFO_BIT; - buf[0] |= s->irqen_reg; - len++; - } - /* Just increase the length by amount of words in FIFO since - * buffer was zeroed and SPI transfer of 0x0000 means reading - * from RX FIFO - */ - len += rxlvl; - /* Append RX level query */ - buf[len] = MAX3107_RXFIFOLVL_REG; - len++; - - /* Perform the SPI transfer */ - if (max3107_rw(s, (u8 *)buf, (u8 *)buf, len * 2)) { - dev_err(&s->spi->dev, "SPI transfer for RX h failed\n"); - return; - } - - /* Skip RX FIFO interrupt disabling word if it was added */ - j = ((len - 1) - rxlvl); - /* Read received words */ - for (i = 0; i < rxlvl; i++, j++) - valid_str[i] = (u8)buf[j]; - put_data_to_circ_buf(s, valid_str, rxlvl); - /* Get new RX level */ - rxlvl = (buf[len - 1] & MAX3107_SPI_RX_DATA_MASK); - } - - if (s->rx_enabled) { - /* RX still enabled, re-enable RX FIFO interrupt */ - pr_debug("Enabling RX INT\n"); - buf[0] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG); - s->irqen_reg |= MAX3107_IRQ_RXFIFO_BIT; - buf[0] |= s->irqen_reg; - if (max3107_rw(s, (u8 *)buf, NULL, 2)) - dev_err(&s->spi->dev, "RX FIFO INT enabling failed\n"); - } - - /* Push the received data to receivers */ - if (s->port.state->port.tty) - tty_flip_buffer_push(s->port.state->port.tty); -} - - -/* Handle data sending */ -static void max3107_handletx(struct max3107_port *s) -{ - struct circ_buf *xmit = &s->port.state->xmit; - int i; - unsigned long flags; - int len; /* SPI transfer buffer length */ - u16 *buf; - - if (!s->tx_fifo_empty) - /* Don't send more data before previous data is sent */ - return; - - if (uart_circ_empty(xmit) || uart_tx_stopped(&s->port)) - /* No data to send or TX is stopped */ - return; - - if (!s->txbuf) { - dev_warn(&s->spi->dev, "Txbuf isn't ready\n"); - return; - } - buf = s->txbuf; - /* Get length of data pending in circular buffer */ - len = uart_circ_chars_pending(xmit); - if (len) { - /* Limit to size of TX FIFO */ - if (len > MAX3107_TX_FIFO_SIZE) - len = MAX3107_TX_FIFO_SIZE; - - pr_debug("txlen %d\n", len); - - /* Update TX counter */ - s->port.icount.tx += len; - - /* TX FIFO will no longer be empty */ - s->tx_fifo_empty = 0; - - i = 0; - if (s->irqen_reg & MAX3107_IRQ_TXEMPTY_BIT) { - /* First disable TX empty interrupt */ - pr_debug("Disabling TE INT\n"); - buf[i] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG); - s->irqen_reg &= ~MAX3107_IRQ_TXEMPTY_BIT; - buf[i] |= s->irqen_reg; - i++; - len++; - } - /* Add data to send */ - spin_lock_irqsave(&s->port.lock, flags); - for ( ; i < len ; i++) { - buf[i] = (MAX3107_WRITE_BIT | MAX3107_THR_REG); - buf[i] |= ((u16)xmit->buf[xmit->tail] & - MAX3107_SPI_TX_DATA_MASK); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - } - spin_unlock_irqrestore(&s->port.lock, flags); - if (!(s->irqen_reg & MAX3107_IRQ_TXEMPTY_BIT)) { - /* Enable TX empty interrupt */ - pr_debug("Enabling TE INT\n"); - buf[i] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG); - s->irqen_reg |= MAX3107_IRQ_TXEMPTY_BIT; - buf[i] |= s->irqen_reg; - i++; - len++; - } - if (!s->tx_enabled) { - /* Enable TX */ - pr_debug("Enable TX\n"); - buf[i] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG); - spin_lock_irqsave(&s->data_lock, flags); - s->mode1_reg &= ~MAX3107_MODE1_TXDIS_BIT; - buf[i] |= s->mode1_reg; - spin_unlock_irqrestore(&s->data_lock, flags); - s->tx_enabled = 1; - i++; - len++; - } - - /* Perform the SPI transfer */ - if (max3107_rw(s, (u8 *)buf, NULL, len*2)) { - dev_err(&s->spi->dev, - "SPI transfer TX handling failed\n"); - return; - } - } - - /* Indicate wake up if circular buffer is getting low on data */ - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&s->port); - -} - -/* Handle interrupts - * Also reads and returns current RX FIFO level - */ -static u16 handle_interrupt(struct max3107_port *s) -{ - u16 buf[4]; /* Buffer for SPI transfers */ - u8 irq_status; - u16 rx_level; - unsigned long flags; - - /* Read IRQ status register */ - buf[0] = MAX3107_IRQSTS_REG; - /* Read status IRQ status register */ - buf[1] = MAX3107_STS_IRQSTS_REG; - /* Read LSR IRQ status register */ - buf[2] = MAX3107_LSR_IRQSTS_REG; - /* Query RX level */ - buf[3] = MAX3107_RXFIFOLVL_REG; - - if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 8)) { - dev_err(&s->spi->dev, - "SPI transfer for INTR handling failed\n"); - return 0; - } - - irq_status = (u8)buf[0]; - pr_debug("IRQSTS %x\n", irq_status); - rx_level = (buf[3] & MAX3107_SPI_RX_DATA_MASK); - - if (irq_status & MAX3107_IRQ_LSR_BIT) { - /* LSR interrupt */ - if (buf[2] & MAX3107_LSR_RXTO_BIT) - /* RX timeout interrupt, - * handled by normal RX handling - */ - pr_debug("RX TO INT\n"); - } - - if (irq_status & MAX3107_IRQ_TXEMPTY_BIT) { - /* Tx empty interrupt, - * disable TX and set tx_fifo_empty flag - */ - pr_debug("TE INT, disabling TX\n"); - buf[0] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG); - spin_lock_irqsave(&s->data_lock, flags); - s->mode1_reg |= MAX3107_MODE1_TXDIS_BIT; - buf[0] |= s->mode1_reg; - spin_unlock_irqrestore(&s->data_lock, flags); - if (max3107_rw(s, (u8 *)buf, NULL, 2)) - dev_err(&s->spi->dev, "SPI transfer TX dis failed\n"); - s->tx_enabled = 0; - s->tx_fifo_empty = 1; - } - - if (irq_status & MAX3107_IRQ_RXFIFO_BIT) - /* RX FIFO interrupt, - * handled by normal RX handling - */ - pr_debug("RFIFO INT\n"); - - /* Return RX level */ - return rx_level; -} - -/* Trigger work thread*/ -static void max3107_dowork(struct max3107_port *s) -{ - if (!work_pending(&s->work) && !freezing(current) && !s->suspended) - queue_work(s->workqueue, &s->work); - else - dev_warn(&s->spi->dev, "interrup isn't serviced normally!\n"); -} - -/* Work thread */ -static void max3107_work(struct work_struct *w) -{ - struct max3107_port *s = container_of(w, struct max3107_port, work); - u16 rxlvl = 0; - int len; /* SPI transfer buffer length */ - u16 buf[5]; /* Buffer for SPI transfers */ - unsigned long flags; - - /* Start by reading current RX FIFO level */ - buf[0] = MAX3107_RXFIFOLVL_REG; - if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) { - dev_err(&s->spi->dev, "SPI transfer RX lev failed\n"); - rxlvl = 0; - } else { - rxlvl = (buf[0] & MAX3107_SPI_RX_DATA_MASK); - } - - do { - pr_debug("rxlvl %d\n", rxlvl); - - /* Handle RX */ - max3107_handlerx(s, rxlvl); - rxlvl = 0; - - if (s->handle_irq) { - /* Handle pending interrupts - * We also get new RX FIFO level since new data may - * have been received while pushing received data to - * receivers - */ - s->handle_irq = 0; - rxlvl = handle_interrupt(s); - } - - /* Handle TX */ - max3107_handletx(s); - - /* Handle configuration changes */ - len = 0; - spin_lock_irqsave(&s->data_lock, flags); - if (s->mode1_commit) { - pr_debug("mode1_commit\n"); - buf[len] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG); - buf[len++] |= s->mode1_reg; - s->mode1_commit = 0; - } - if (s->lcr_commit) { - pr_debug("lcr_commit\n"); - buf[len] = (MAX3107_WRITE_BIT | MAX3107_LCR_REG); - buf[len++] |= s->lcr_reg; - s->lcr_commit = 0; - } - if (s->brg_commit) { - pr_debug("brg_commit\n"); - buf[len] = (MAX3107_WRITE_BIT | MAX3107_BRGDIVMSB_REG); - buf[len++] |= ((s->brg_cfg >> 16) & - MAX3107_SPI_TX_DATA_MASK); - buf[len] = (MAX3107_WRITE_BIT | MAX3107_BRGDIVLSB_REG); - buf[len++] |= ((s->brg_cfg >> 8) & - MAX3107_SPI_TX_DATA_MASK); - buf[len] = (MAX3107_WRITE_BIT | MAX3107_BRGCFG_REG); - buf[len++] |= ((s->brg_cfg) & 0xff); - s->brg_commit = 0; - } - spin_unlock_irqrestore(&s->data_lock, flags); - - if (len > 0) { - if (max3107_rw(s, (u8 *)buf, NULL, len * 2)) - dev_err(&s->spi->dev, - "SPI transfer config failed\n"); - } - - /* Reloop if interrupt handling indicated data in RX FIFO */ - } while (rxlvl); - -} - -/* Set sleep mode */ -static void max3107_set_sleep(struct max3107_port *s, int mode) -{ - u16 buf[1]; /* Buffer for SPI transfer */ - unsigned long flags; - pr_debug("enter, mode %d\n", mode); - - buf[0] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG); - spin_lock_irqsave(&s->data_lock, flags); - switch (mode) { - case MAX3107_DISABLE_FORCED_SLEEP: - s->mode1_reg &= ~MAX3107_MODE1_FORCESLEEP_BIT; - break; - case MAX3107_ENABLE_FORCED_SLEEP: - s->mode1_reg |= MAX3107_MODE1_FORCESLEEP_BIT; - break; - case MAX3107_DISABLE_AUTOSLEEP: - s->mode1_reg &= ~MAX3107_MODE1_AUTOSLEEP_BIT; - break; - case MAX3107_ENABLE_AUTOSLEEP: - s->mode1_reg |= MAX3107_MODE1_AUTOSLEEP_BIT; - break; - default: - spin_unlock_irqrestore(&s->data_lock, flags); - dev_warn(&s->spi->dev, "invalid sleep mode\n"); - return; - } - buf[0] |= s->mode1_reg; - spin_unlock_irqrestore(&s->data_lock, flags); - - if (max3107_rw(s, (u8 *)buf, NULL, 2)) - dev_err(&s->spi->dev, "SPI transfer sleep mode failed\n"); - - if (mode == MAX3107_DISABLE_AUTOSLEEP || - mode == MAX3107_DISABLE_FORCED_SLEEP) - msleep(MAX3107_WAKEUP_DELAY); -} - -/* Perform full register initialization */ -static void max3107_register_init(struct max3107_port *s) -{ - u16 buf[11]; /* Buffer for SPI transfers */ - - /* 1. Configure baud rate, 9600 as default */ - s->baud = 9600; - /* the below is default*/ - if (s->ext_clk) { - s->brg_cfg = MAX3107_BRG26_B9600; - s->baud_tbl = (struct baud_table *)brg26_ext; - } else { - s->brg_cfg = MAX3107_BRG13_IB9600; - s->baud_tbl = (struct baud_table *)brg13_int; - } - - if (s->pdata->init) - s->pdata->init(s); - - buf[0] = (MAX3107_WRITE_BIT | MAX3107_BRGDIVMSB_REG) - | ((s->brg_cfg >> 16) & MAX3107_SPI_TX_DATA_MASK); - buf[1] = (MAX3107_WRITE_BIT | MAX3107_BRGDIVLSB_REG) - | ((s->brg_cfg >> 8) & MAX3107_SPI_TX_DATA_MASK); - buf[2] = (MAX3107_WRITE_BIT | MAX3107_BRGCFG_REG) - | ((s->brg_cfg) & 0xff); - - /* 2. Configure LCR register, 8N1 mode by default */ - s->lcr_reg = MAX3107_LCR_WORD_LEN_8; - buf[3] = (MAX3107_WRITE_BIT | MAX3107_LCR_REG) - | s->lcr_reg; - - /* 3. Configure MODE 1 register */ - s->mode1_reg = 0; - /* Enable IRQ pin */ - s->mode1_reg |= MAX3107_MODE1_IRQSEL_BIT; - /* Disable TX */ - s->mode1_reg |= MAX3107_MODE1_TXDIS_BIT; - s->tx_enabled = 0; - /* RX is enabled */ - s->rx_enabled = 1; - buf[4] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG) - | s->mode1_reg; - - /* 4. Configure MODE 2 register */ - buf[5] = (MAX3107_WRITE_BIT | MAX3107_MODE2_REG); - if (s->loopback) { - /* Enable loopback */ - buf[5] |= MAX3107_MODE2_LOOPBACK_BIT; - } - /* Reset FIFOs */ - buf[5] |= MAX3107_MODE2_FIFORST_BIT; - s->tx_fifo_empty = 1; - - /* 5. Configure FIFO trigger level register */ - buf[6] = (MAX3107_WRITE_BIT | MAX3107_FIFOTRIGLVL_REG); - /* RX FIFO trigger for 16 words, TX FIFO trigger not used */ - buf[6] |= (MAX3107_FIFOTRIGLVL_RX(16) | MAX3107_FIFOTRIGLVL_TX(0)); - - /* 6. Configure flow control levels */ - buf[7] = (MAX3107_WRITE_BIT | MAX3107_FLOWLVL_REG); - /* Flow control halt level 96, resume level 48 */ - buf[7] |= (MAX3107_FLOWLVL_RES(48) | MAX3107_FLOWLVL_HALT(96)); - - /* 7. Configure flow control */ - buf[8] = (MAX3107_WRITE_BIT | MAX3107_FLOWCTRL_REG); - /* Enable auto CTS and auto RTS flow control */ - buf[8] |= (MAX3107_FLOWCTRL_AUTOCTS_BIT | MAX3107_FLOWCTRL_AUTORTS_BIT); - - /* 8. Configure RX timeout register */ - buf[9] = (MAX3107_WRITE_BIT | MAX3107_RXTO_REG); - /* Timeout after 48 character intervals */ - buf[9] |= 0x0030; - - /* 9. Configure LSR interrupt enable register */ - buf[10] = (MAX3107_WRITE_BIT | MAX3107_LSR_IRQEN_REG); - /* Enable RX timeout interrupt */ - buf[10] |= MAX3107_LSR_RXTO_BIT; - - /* Perform SPI transfer */ - if (max3107_rw(s, (u8 *)buf, NULL, 22)) - dev_err(&s->spi->dev, "SPI transfer for init failed\n"); - - /* 10. Clear IRQ status register by reading it */ - buf[0] = MAX3107_IRQSTS_REG; - - /* 11. Configure interrupt enable register */ - /* Enable LSR interrupt */ - s->irqen_reg = MAX3107_IRQ_LSR_BIT; - /* Enable RX FIFO interrupt */ - s->irqen_reg |= MAX3107_IRQ_RXFIFO_BIT; - buf[1] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG) - | s->irqen_reg; - - /* 12. Clear FIFO reset that was set in step 6 */ - buf[2] = (MAX3107_WRITE_BIT | MAX3107_MODE2_REG); - if (s->loopback) { - /* Keep loopback enabled */ - buf[2] |= MAX3107_MODE2_LOOPBACK_BIT; - } - - /* Perform SPI transfer */ - if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 6)) - dev_err(&s->spi->dev, "SPI transfer for init failed\n"); - -} - -/* IRQ handler */ -static irqreturn_t max3107_irq(int irqno, void *dev_id) -{ - struct max3107_port *s = dev_id; - - if (irqno != s->spi->irq) { - /* Unexpected IRQ */ - return IRQ_NONE; - } - - /* Indicate irq */ - s->handle_irq = 1; - - /* Trigger work thread */ - max3107_dowork(s); - - return IRQ_HANDLED; -} - -/* HW suspension function - * - * Currently autosleep is used to decrease current consumption, alternative - * approach would be to set the chip to reset mode if UART is not being - * used but that would mess the GPIOs - * - */ -void max3107_hw_susp(struct max3107_port *s, int suspend) -{ - pr_debug("enter, suspend %d\n", suspend); - - if (suspend) { - /* Suspend requested, - * enable autosleep to decrease current consumption - */ - s->suspended = 1; - max3107_set_sleep(s, MAX3107_ENABLE_AUTOSLEEP); - } else { - /* Resume requested, - * disable autosleep - */ - s->suspended = 0; - max3107_set_sleep(s, MAX3107_DISABLE_AUTOSLEEP); - } -} -EXPORT_SYMBOL_GPL(max3107_hw_susp); - -/* Modem status IRQ enabling */ -static void max3107_enable_ms(struct uart_port *port) -{ - /* Modem status not supported */ -} - -/* Data send function */ -static void max3107_start_tx(struct uart_port *port) -{ - struct max3107_port *s = container_of(port, struct max3107_port, port); - - /* Trigger work thread for sending data */ - max3107_dowork(s); -} - -/* Function for checking that there is no pending transfers */ -static unsigned int max3107_tx_empty(struct uart_port *port) -{ - struct max3107_port *s = container_of(port, struct max3107_port, port); - - pr_debug("returning %d\n", - (s->tx_fifo_empty && uart_circ_empty(&s->port.state->xmit))); - return s->tx_fifo_empty && uart_circ_empty(&s->port.state->xmit); -} - -/* Function for stopping RX */ -static void max3107_stop_rx(struct uart_port *port) -{ - struct max3107_port *s = container_of(port, struct max3107_port, port); - unsigned long flags; - - /* Set RX disabled in MODE 1 register */ - spin_lock_irqsave(&s->data_lock, flags); - s->mode1_reg |= MAX3107_MODE1_RXDIS_BIT; - s->mode1_commit = 1; - spin_unlock_irqrestore(&s->data_lock, flags); - /* Set RX disabled */ - s->rx_enabled = 0; - /* Trigger work thread for doing the actual configuration change */ - max3107_dowork(s); -} - -/* Function for returning control pin states */ -static unsigned int max3107_get_mctrl(struct uart_port *port) -{ - /* DCD and DSR are not wired and CTS/RTS is handled automatically - * so just indicate DSR and CAR asserted - */ - return TIOCM_DSR | TIOCM_CAR; -} - -/* Function for setting control pin states */ -static void max3107_set_mctrl(struct uart_port *port, unsigned int mctrl) -{ - /* DCD and DSR are not wired and CTS/RTS is hadnled automatically - * so do nothing - */ -} - -/* Function for configuring UART parameters */ -static void max3107_set_termios(struct uart_port *port, - struct ktermios *termios, - struct ktermios *old) -{ - struct max3107_port *s = container_of(port, struct max3107_port, port); - struct tty_struct *tty; - int baud; - u16 new_lcr = 0; - u32 new_brg = 0; - unsigned long flags; - - if (!port->state) - return; - - tty = port->state->port.tty; - if (!tty) - return; - - /* Get new LCR register values */ - /* Word size */ - if ((termios->c_cflag & CSIZE) == CS7) - new_lcr |= MAX3107_LCR_WORD_LEN_7; - else - new_lcr |= MAX3107_LCR_WORD_LEN_8; - - /* Parity */ - if (termios->c_cflag & PARENB) { - new_lcr |= MAX3107_LCR_PARITY_BIT; - if (!(termios->c_cflag & PARODD)) - new_lcr |= MAX3107_LCR_EVENPARITY_BIT; - } - - /* Stop bits */ - if (termios->c_cflag & CSTOPB) { - /* 2 stop bits */ - new_lcr |= MAX3107_LCR_STOPLEN_BIT; - } - - /* Mask termios capabilities we don't support */ - termios->c_cflag &= ~CMSPAR; - - /* Set status ignore mask */ - s->port.ignore_status_mask = 0; - if (termios->c_iflag & IGNPAR) - s->port.ignore_status_mask |= MAX3107_ALL_ERRORS; - - /* Set low latency to immediately handle pushed data */ - s->port.state->port.tty->low_latency = 1; - - /* Get new baud rate generator configuration */ - baud = tty_get_baud_rate(tty); - - spin_lock_irqsave(&s->data_lock, flags); - new_brg = get_new_brg(baud, s); - /* if can't find the corrent config, use previous */ - if (!new_brg) { - baud = s->baud; - new_brg = s->brg_cfg; - } - spin_unlock_irqrestore(&s->data_lock, flags); - tty_termios_encode_baud_rate(termios, baud, baud); - s->baud = baud; - - /* Update timeout according to new baud rate */ - uart_update_timeout(port, termios->c_cflag, baud); - - spin_lock_irqsave(&s->data_lock, flags); - if (s->lcr_reg != new_lcr) { - s->lcr_reg = new_lcr; - s->lcr_commit = 1; - } - if (s->brg_cfg != new_brg) { - s->brg_cfg = new_brg; - s->brg_commit = 1; - } - spin_unlock_irqrestore(&s->data_lock, flags); - - /* Trigger work thread for doing the actual configuration change */ - max3107_dowork(s); -} - -/* Port shutdown function */ -static void max3107_shutdown(struct uart_port *port) -{ - struct max3107_port *s = container_of(port, struct max3107_port, port); - - if (s->suspended && s->pdata->hw_suspend) - s->pdata->hw_suspend(s, 0); - - /* Free the interrupt */ - free_irq(s->spi->irq, s); - - if (s->workqueue) { - /* Flush and destroy work queue */ - flush_workqueue(s->workqueue); - destroy_workqueue(s->workqueue); - s->workqueue = NULL; - } - - /* Suspend HW */ - if (s->pdata->hw_suspend) - s->pdata->hw_suspend(s, 1); -} - -/* Port startup function */ -static int max3107_startup(struct uart_port *port) -{ - struct max3107_port *s = container_of(port, struct max3107_port, port); - - /* Initialize work queue */ - s->workqueue = create_freezeable_workqueue("max3107"); - if (!s->workqueue) { - dev_err(&s->spi->dev, "Workqueue creation failed\n"); - return -EBUSY; - } - INIT_WORK(&s->work, max3107_work); - - /* Setup IRQ */ - if (request_irq(s->spi->irq, max3107_irq, IRQF_TRIGGER_FALLING, - "max3107", s)) { - dev_err(&s->spi->dev, "IRQ reguest failed\n"); - destroy_workqueue(s->workqueue); - s->workqueue = NULL; - return -EBUSY; - } - - /* Resume HW */ - if (s->pdata->hw_suspend) - s->pdata->hw_suspend(s, 0); - - /* Init registers */ - max3107_register_init(s); - - return 0; -} - -/* Port type function */ -static const char *max3107_type(struct uart_port *port) -{ - struct max3107_port *s = container_of(port, struct max3107_port, port); - return s->spi->modalias; -} - -/* Port release function */ -static void max3107_release_port(struct uart_port *port) -{ - /* Do nothing */ -} - -/* Port request function */ -static int max3107_request_port(struct uart_port *port) -{ - /* Do nothing */ - return 0; -} - -/* Port config function */ -static void max3107_config_port(struct uart_port *port, int flags) -{ - struct max3107_port *s = container_of(port, struct max3107_port, port); - s->port.type = PORT_MAX3107; -} - -/* Port verify function */ -static int max3107_verify_port(struct uart_port *port, - struct serial_struct *ser) -{ - if (ser->type == PORT_UNKNOWN || ser->type == PORT_MAX3107) - return 0; - - return -EINVAL; -} - -/* Port stop TX function */ -static void max3107_stop_tx(struct uart_port *port) -{ - /* Do nothing */ -} - -/* Port break control function */ -static void max3107_break_ctl(struct uart_port *port, int break_state) -{ - /* We don't support break control, do nothing */ -} - - -/* Port functions */ -static struct uart_ops max3107_ops = { - .tx_empty = max3107_tx_empty, - .set_mctrl = max3107_set_mctrl, - .get_mctrl = max3107_get_mctrl, - .stop_tx = max3107_stop_tx, - .start_tx = max3107_start_tx, - .stop_rx = max3107_stop_rx, - .enable_ms = max3107_enable_ms, - .break_ctl = max3107_break_ctl, - .startup = max3107_startup, - .shutdown = max3107_shutdown, - .set_termios = max3107_set_termios, - .type = max3107_type, - .release_port = max3107_release_port, - .request_port = max3107_request_port, - .config_port = max3107_config_port, - .verify_port = max3107_verify_port, -}; - -/* UART driver data */ -static struct uart_driver max3107_uart_driver = { - .owner = THIS_MODULE, - .driver_name = "ttyMAX", - .dev_name = "ttyMAX", - .nr = 1, -}; - -static int driver_registered = 0; - - - -/* 'Generic' platform data */ -static struct max3107_plat generic_plat_data = { - .loopback = 0, - .ext_clk = 1, - .hw_suspend = max3107_hw_susp, - .polled_mode = 0, - .poll_time = 0, -}; - - -/*******************************************************************/ - -/** - * max3107_probe - SPI bus probe entry point - * @spi: the spi device - * - * SPI wants us to probe this device and if appropriate claim it. - * Perform any platform specific requirements and then initialise - * the device. - */ - -int max3107_probe(struct spi_device *spi, struct max3107_plat *pdata) -{ - struct max3107_port *s; - u16 buf[2]; /* Buffer for SPI transfers */ - int retval; - - pr_info("enter max3107 probe\n"); - - /* Allocate port structure */ - s = kzalloc(sizeof(*s), GFP_KERNEL); - if (!s) { - pr_err("Allocating port structure failed\n"); - return -ENOMEM; - } - - s->pdata = pdata; - - /* SPI Rx buffer - * +2 for RX FIFO interrupt - * disabling and RX level query - */ - s->rxbuf = kzalloc(sizeof(u16) * (MAX3107_RX_FIFO_SIZE+2), GFP_KERNEL); - if (!s->rxbuf) { - pr_err("Allocating RX buffer failed\n"); - return -ENOMEM; - } - s->rxstr = kzalloc(sizeof(u8) * MAX3107_RX_FIFO_SIZE, GFP_KERNEL); - if (!s->rxstr) { - pr_err("Allocating RX buffer failed\n"); - return -ENOMEM; - } - /* SPI Tx buffer - * SPI transfer buffer - * +3 for TX FIFO empty - * interrupt disabling and - * enabling and TX enabling - */ - s->txbuf = kzalloc(sizeof(u16) * MAX3107_TX_FIFO_SIZE + 3, GFP_KERNEL); - if (!s->txbuf) { - pr_err("Allocating TX buffer failed\n"); - return -ENOMEM; - } - /* Initialize shared data lock */ - spin_lock_init(&s->data_lock); - - /* SPI intializations */ - dev_set_drvdata(&spi->dev, s); - spi->mode = SPI_MODE_0; - spi->dev.platform_data = pdata; - spi->bits_per_word = 16; - s->ext_clk = pdata->ext_clk; - s->loopback = pdata->loopback; - spi_setup(spi); - s->spi = spi; - - /* Check REV ID to ensure we are talking to what we expect */ - buf[0] = MAX3107_REVID_REG; - if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) { - dev_err(&s->spi->dev, "SPI transfer for REVID read failed\n"); - return -EIO; - } - if ((buf[0] & MAX3107_SPI_RX_DATA_MASK) != MAX3107_REVID1 && - (buf[0] & MAX3107_SPI_RX_DATA_MASK) != MAX3107_REVID2) { - dev_err(&s->spi->dev, "REVID %x does not match\n", - (buf[0] & MAX3107_SPI_RX_DATA_MASK)); - return -ENODEV; - } - - /* Disable all interrupts */ - buf[0] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG | 0x0000); - buf[0] |= 0x0000; - - /* Configure clock source */ - buf[1] = (MAX3107_WRITE_BIT | MAX3107_CLKSRC_REG); - if (s->ext_clk) { - /* External clock */ - buf[1] |= MAX3107_CLKSRC_EXTCLK_BIT; - } - - /* PLL bypass ON */ - buf[1] |= MAX3107_CLKSRC_PLLBYP_BIT; - - /* Perform SPI transfer */ - if (max3107_rw(s, (u8 *)buf, NULL, 4)) { - dev_err(&s->spi->dev, "SPI transfer for init failed\n"); - return -EIO; - } - - /* Register UART driver */ - if (!driver_registered) { - retval = uart_register_driver(&max3107_uart_driver); - if (retval) { - dev_err(&s->spi->dev, "Registering UART driver failed\n"); - return retval; - } - driver_registered = 1; - } - - /* Initialize UART port data */ - s->port.fifosize = 128; - s->port.ops = &max3107_ops; - s->port.line = 0; - s->port.dev = &spi->dev; - s->port.uartclk = 9600; - s->port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; - s->port.irq = s->spi->irq; - s->port.type = PORT_MAX3107; - - /* Add UART port */ - retval = uart_add_one_port(&max3107_uart_driver, &s->port); - if (retval < 0) { - dev_err(&s->spi->dev, "Adding UART port failed\n"); - return retval; - } - - if (pdata->configure) { - retval = pdata->configure(s); - if (retval < 0) - return retval; - } - - /* Go to suspend mode */ - if (pdata->hw_suspend) - pdata->hw_suspend(s, 1); - - return 0; -} -EXPORT_SYMBOL_GPL(max3107_probe); - -/* Driver remove function */ -int max3107_remove(struct spi_device *spi) -{ - struct max3107_port *s = dev_get_drvdata(&spi->dev); - - pr_info("enter max3107 remove\n"); - - /* Remove port */ - if (uart_remove_one_port(&max3107_uart_driver, &s->port)) - dev_warn(&s->spi->dev, "Removing UART port failed\n"); - - - /* Free TxRx buffer */ - kfree(s->rxbuf); - kfree(s->rxstr); - kfree(s->txbuf); - - /* Free port structure */ - kfree(s); - - return 0; -} -EXPORT_SYMBOL_GPL(max3107_remove); - -/* Driver suspend function */ -int max3107_suspend(struct spi_device *spi, pm_message_t state) -{ -#ifdef CONFIG_PM - struct max3107_port *s = dev_get_drvdata(&spi->dev); - - pr_debug("enter suspend\n"); - - /* Suspend UART port */ - uart_suspend_port(&max3107_uart_driver, &s->port); - - /* Go to suspend mode */ - if (s->pdata->hw_suspend) - s->pdata->hw_suspend(s, 1); -#endif /* CONFIG_PM */ - return 0; -} -EXPORT_SYMBOL_GPL(max3107_suspend); - -/* Driver resume function */ -int max3107_resume(struct spi_device *spi) -{ -#ifdef CONFIG_PM - struct max3107_port *s = dev_get_drvdata(&spi->dev); - - pr_debug("enter resume\n"); - - /* Resume from suspend */ - if (s->pdata->hw_suspend) - s->pdata->hw_suspend(s, 0); - - /* Resume UART port */ - uart_resume_port(&max3107_uart_driver, &s->port); -#endif /* CONFIG_PM */ - return 0; -} -EXPORT_SYMBOL_GPL(max3107_resume); - -static int max3107_probe_generic(struct spi_device *spi) -{ - return max3107_probe(spi, &generic_plat_data); -} - -/* Spi driver data */ -static struct spi_driver max3107_driver = { - .driver = { - .name = "max3107", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - .probe = max3107_probe_generic, - .remove = __devexit_p(max3107_remove), - .suspend = max3107_suspend, - .resume = max3107_resume, -}; - -/* Driver init function */ -static int __init max3107_init(void) -{ - pr_info("enter max3107 init\n"); - return spi_register_driver(&max3107_driver); -} - -/* Driver exit function */ -static void __exit max3107_exit(void) -{ - pr_info("enter max3107 exit\n"); - /* Unregister UART driver */ - if (driver_registered) - uart_unregister_driver(&max3107_uart_driver); - spi_unregister_driver(&max3107_driver); -} - -module_init(max3107_init); -module_exit(max3107_exit); - -MODULE_DESCRIPTION("MAX3107 driver"); -MODULE_AUTHOR("Aavamobile"); -MODULE_ALIAS("max3107-spi"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/serial/max3107.h b/trunk/drivers/serial/max3107.h deleted file mode 100644 index 7ab632392502..000000000000 --- a/trunk/drivers/serial/max3107.h +++ /dev/null @@ -1,441 +0,0 @@ -/* - * max3107.h - spi uart protocol driver header for Maxim 3107 - * - * Copyright (C) Aavamobile 2009 - * Based on serial_max3100.h by Christian Pellegrin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#ifndef _MAX3107_H -#define _MAX3107_H - -/* Serial error status definitions */ -#define MAX3107_PARITY_ERROR 1 -#define MAX3107_FRAME_ERROR 2 -#define MAX3107_OVERRUN_ERROR 4 -#define MAX3107_ALL_ERRORS (MAX3107_PARITY_ERROR | \ - MAX3107_FRAME_ERROR | \ - MAX3107_OVERRUN_ERROR) - -/* GPIO definitions */ -#define MAX3107_GPIO_BASE 88 -#define MAX3107_GPIO_COUNT 4 - - -/* GPIO connected to chip's reset pin */ -#define MAX3107_RESET_GPIO 87 - - -/* Chip reset delay */ -#define MAX3107_RESET_DELAY 10 - -/* Chip wakeup delay */ -#define MAX3107_WAKEUP_DELAY 50 - - -/* Sleep mode definitions */ -#define MAX3107_DISABLE_FORCED_SLEEP 0 -#define MAX3107_ENABLE_FORCED_SLEEP 1 -#define MAX3107_DISABLE_AUTOSLEEP 2 -#define MAX3107_ENABLE_AUTOSLEEP 3 - - -/* Definitions for register access with SPI transfers - * - * SPI transfer format: - * - * Master to slave bits xzzzzzzzyyyyyyyy - * Slave to master bits aaaaaaaabbbbbbbb - * - * where: - * x = 0 for reads, 1 for writes - * z = register address - * y = new register value if write, 0 if read - * a = unspecified - * b = register value if read, unspecified if write - */ - -/* SPI speed */ -#define MAX3107_SPI_SPEED (3125000 * 2) - -/* Write bit */ -#define MAX3107_WRITE_BIT (1 << 15) - -/* SPI TX data mask */ -#define MAX3107_SPI_RX_DATA_MASK (0x00ff) - -/* SPI RX data mask */ -#define MAX3107_SPI_TX_DATA_MASK (0x00ff) - -/* Register access masks */ -#define MAX3107_RHR_REG (0x0000) /* RX FIFO */ -#define MAX3107_THR_REG (0x0000) /* TX FIFO */ -#define MAX3107_IRQEN_REG (0x0100) /* IRQ enable */ -#define MAX3107_IRQSTS_REG (0x0200) /* IRQ status */ -#define MAX3107_LSR_IRQEN_REG (0x0300) /* LSR IRQ enable */ -#define MAX3107_LSR_IRQSTS_REG (0x0400) /* LSR IRQ status */ -#define MAX3107_SPCHR_IRQEN_REG (0x0500) /* Special char IRQ enable */ -#define MAX3107_SPCHR_IRQSTS_REG (0x0600) /* Special char IRQ status */ -#define MAX3107_STS_IRQEN_REG (0x0700) /* Status IRQ enable */ -#define MAX3107_STS_IRQSTS_REG (0x0800) /* Status IRQ status */ -#define MAX3107_MODE1_REG (0x0900) /* MODE1 */ -#define MAX3107_MODE2_REG (0x0a00) /* MODE2 */ -#define MAX3107_LCR_REG (0x0b00) /* LCR */ -#define MAX3107_RXTO_REG (0x0c00) /* RX timeout */ -#define MAX3107_HDPIXDELAY_REG (0x0d00) /* Auto transceiver delays */ -#define MAX3107_IRDA_REG (0x0e00) /* IRDA settings */ -#define MAX3107_FLOWLVL_REG (0x0f00) /* Flow control levels */ -#define MAX3107_FIFOTRIGLVL_REG (0x1000) /* FIFO IRQ trigger levels */ -#define MAX3107_TXFIFOLVL_REG (0x1100) /* TX FIFO level */ -#define MAX3107_RXFIFOLVL_REG (0x1200) /* RX FIFO level */ -#define MAX3107_FLOWCTRL_REG (0x1300) /* Flow control */ -#define MAX3107_XON1_REG (0x1400) /* XON1 character */ -#define MAX3107_XON2_REG (0x1500) /* XON2 character */ -#define MAX3107_XOFF1_REG (0x1600) /* XOFF1 character */ -#define MAX3107_XOFF2_REG (0x1700) /* XOFF2 character */ -#define MAX3107_GPIOCFG_REG (0x1800) /* GPIO config */ -#define MAX3107_GPIODATA_REG (0x1900) /* GPIO data */ -#define MAX3107_PLLCFG_REG (0x1a00) /* PLL config */ -#define MAX3107_BRGCFG_REG (0x1b00) /* Baud rate generator conf */ -#define MAX3107_BRGDIVLSB_REG (0x1c00) /* Baud rate divisor LSB */ -#define MAX3107_BRGDIVMSB_REG (0x1d00) /* Baud rate divisor MSB */ -#define MAX3107_CLKSRC_REG (0x1e00) /* Clock source */ -#define MAX3107_REVID_REG (0x1f00) /* Revision identification */ - -/* IRQ register bits */ -#define MAX3107_IRQ_LSR_BIT (1 << 0) /* LSR interrupt */ -#define MAX3107_IRQ_SPCHR_BIT (1 << 1) /* Special char interrupt */ -#define MAX3107_IRQ_STS_BIT (1 << 2) /* Status interrupt */ -#define MAX3107_IRQ_RXFIFO_BIT (1 << 3) /* RX FIFO interrupt */ -#define MAX3107_IRQ_TXFIFO_BIT (1 << 4) /* TX FIFO interrupt */ -#define MAX3107_IRQ_TXEMPTY_BIT (1 << 5) /* TX FIFO empty interrupt */ -#define MAX3107_IRQ_RXEMPTY_BIT (1 << 6) /* RX FIFO empty interrupt */ -#define MAX3107_IRQ_CTS_BIT (1 << 7) /* CTS interrupt */ - -/* LSR register bits */ -#define MAX3107_LSR_RXTO_BIT (1 << 0) /* RX timeout */ -#define MAX3107_LSR_RXOVR_BIT (1 << 1) /* RX overrun */ -#define MAX3107_LSR_RXPAR_BIT (1 << 2) /* RX parity error */ -#define MAX3107_LSR_FRERR_BIT (1 << 3) /* Frame error */ -#define MAX3107_LSR_RXBRK_BIT (1 << 4) /* RX break */ -#define MAX3107_LSR_RXNOISE_BIT (1 << 5) /* RX noise */ -#define MAX3107_LSR_UNDEF6_BIT (1 << 6) /* Undefined/not used */ -#define MAX3107_LSR_CTS_BIT (1 << 7) /* CTS pin state */ - -/* Special character register bits */ -#define MAX3107_SPCHR_XON1_BIT (1 << 0) /* XON1 character */ -#define MAX3107_SPCHR_XON2_BIT (1 << 1) /* XON2 character */ -#define MAX3107_SPCHR_XOFF1_BIT (1 << 2) /* XOFF1 character */ -#define MAX3107_SPCHR_XOFF2_BIT (1 << 3) /* XOFF2 character */ -#define MAX3107_SPCHR_BREAK_BIT (1 << 4) /* RX break */ -#define MAX3107_SPCHR_MULTIDROP_BIT (1 << 5) /* 9-bit multidrop addr char */ -#define MAX3107_SPCHR_UNDEF6_BIT (1 << 6) /* Undefined/not used */ -#define MAX3107_SPCHR_UNDEF7_BIT (1 << 7) /* Undefined/not used */ - -/* Status register bits */ -#define MAX3107_STS_GPIO0_BIT (1 << 0) /* GPIO 0 interrupt */ -#define MAX3107_STS_GPIO1_BIT (1 << 1) /* GPIO 1 interrupt */ -#define MAX3107_STS_GPIO2_BIT (1 << 2) /* GPIO 2 interrupt */ -#define MAX3107_STS_GPIO3_BIT (1 << 3) /* GPIO 3 interrupt */ -#define MAX3107_STS_UNDEF4_BIT (1 << 4) /* Undefined/not used */ -#define MAX3107_STS_CLKREADY_BIT (1 << 5) /* Clock ready */ -#define MAX3107_STS_SLEEP_BIT (1 << 6) /* Sleep interrupt */ -#define MAX3107_STS_UNDEF7_BIT (1 << 7) /* Undefined/not used */ - -/* MODE1 register bits */ -#define MAX3107_MODE1_RXDIS_BIT (1 << 0) /* RX disable */ -#define MAX3107_MODE1_TXDIS_BIT (1 << 1) /* TX disable */ -#define MAX3107_MODE1_TXHIZ_BIT (1 << 2) /* TX pin three-state */ -#define MAX3107_MODE1_RTSHIZ_BIT (1 << 3) /* RTS pin three-state */ -#define MAX3107_MODE1_TRNSCVCTRL_BIT (1 << 4) /* Transceiver ctrl enable */ -#define MAX3107_MODE1_FORCESLEEP_BIT (1 << 5) /* Force sleep mode */ -#define MAX3107_MODE1_AUTOSLEEP_BIT (1 << 6) /* Auto sleep enable */ -#define MAX3107_MODE1_IRQSEL_BIT (1 << 7) /* IRQ pin enable */ - -/* MODE2 register bits */ -#define MAX3107_MODE2_RST_BIT (1 << 0) /* Chip reset */ -#define MAX3107_MODE2_FIFORST_BIT (1 << 1) /* FIFO reset */ -#define MAX3107_MODE2_RXTRIGINV_BIT (1 << 2) /* RX FIFO INT invert */ -#define MAX3107_MODE2_RXEMPTINV_BIT (1 << 3) /* RX FIFO empty INT invert */ -#define MAX3107_MODE2_SPCHR_BIT (1 << 4) /* Special chr detect enable */ -#define MAX3107_MODE2_LOOPBACK_BIT (1 << 5) /* Internal loopback enable */ -#define MAX3107_MODE2_MULTIDROP_BIT (1 << 6) /* 9-bit multidrop enable */ -#define MAX3107_MODE2_ECHOSUPR_BIT (1 << 7) /* ECHO suppression enable */ - -/* LCR register bits */ -#define MAX3107_LCR_LENGTH0_BIT (1 << 0) /* Word length bit 0 */ -#define MAX3107_LCR_LENGTH1_BIT (1 << 1) /* Word length bit 1 - * - * Word length bits table: - * 00 -> 5 bit words - * 01 -> 6 bit words - * 10 -> 7 bit words - * 11 -> 8 bit words - */ -#define MAX3107_LCR_STOPLEN_BIT (1 << 2) /* STOP length bit - * - * STOP length bit table: - * 0 -> 1 stop bit - * 1 -> 1-1.5 stop bits if - * word length is 5, - * 2 stop bits otherwise - */ -#define MAX3107_LCR_PARITY_BIT (1 << 3) /* Parity bit enable */ -#define MAX3107_LCR_EVENPARITY_BIT (1 << 4) /* Even parity bit enable */ -#define MAX3107_LCR_FORCEPARITY_BIT (1 << 5) /* 9-bit multidrop parity */ -#define MAX3107_LCR_TXBREAK_BIT (1 << 6) /* TX break enable */ -#define MAX3107_LCR_RTS_BIT (1 << 7) /* RTS pin control */ -#define MAX3107_LCR_WORD_LEN_5 (0x0000) -#define MAX3107_LCR_WORD_LEN_6 (0x0001) -#define MAX3107_LCR_WORD_LEN_7 (0x0002) -#define MAX3107_LCR_WORD_LEN_8 (0x0003) - - -/* IRDA register bits */ -#define MAX3107_IRDA_IRDAEN_BIT (1 << 0) /* IRDA mode enable */ -#define MAX3107_IRDA_SIR_BIT (1 << 1) /* SIR mode enable */ -#define MAX3107_IRDA_SHORTIR_BIT (1 << 2) /* Short SIR mode enable */ -#define MAX3107_IRDA_MIR_BIT (1 << 3) /* MIR mode enable */ -#define MAX3107_IRDA_RXINV_BIT (1 << 4) /* RX logic inversion enable */ -#define MAX3107_IRDA_TXINV_BIT (1 << 5) /* TX logic inversion enable */ -#define MAX3107_IRDA_UNDEF6_BIT (1 << 6) /* Undefined/not used */ -#define MAX3107_IRDA_UNDEF7_BIT (1 << 7) /* Undefined/not used */ - -/* Flow control trigger level register masks */ -#define MAX3107_FLOWLVL_HALT_MASK (0x000f) /* Flow control halt level */ -#define MAX3107_FLOWLVL_RES_MASK (0x00f0) /* Flow control resume level */ -#define MAX3107_FLOWLVL_HALT(words) ((words/8) & 0x000f) -#define MAX3107_FLOWLVL_RES(words) (((words/8) & 0x000f) << 4) - -/* FIFO interrupt trigger level register masks */ -#define MAX3107_FIFOTRIGLVL_TX_MASK (0x000f) /* TX FIFO trigger level */ -#define MAX3107_FIFOTRIGLVL_RX_MASK (0x00f0) /* RX FIFO trigger level */ -#define MAX3107_FIFOTRIGLVL_TX(words) ((words/8) & 0x000f) -#define MAX3107_FIFOTRIGLVL_RX(words) (((words/8) & 0x000f) << 4) - -/* Flow control register bits */ -#define MAX3107_FLOWCTRL_AUTORTS_BIT (1 << 0) /* Auto RTS flow ctrl enable */ -#define MAX3107_FLOWCTRL_AUTOCTS_BIT (1 << 1) /* Auto CTS flow ctrl enable */ -#define MAX3107_FLOWCTRL_GPIADDR_BIT (1 << 2) /* Enables that GPIO inputs - * are used in conjunction with - * XOFF2 for definition of - * special character */ -#define MAX3107_FLOWCTRL_SWFLOWEN_BIT (1 << 3) /* Auto SW flow ctrl enable */ -#define MAX3107_FLOWCTRL_SWFLOW0_BIT (1 << 4) /* SWFLOW bit 0 */ -#define MAX3107_FLOWCTRL_SWFLOW1_BIT (1 << 5) /* SWFLOW bit 1 - * - * SWFLOW bits 1 & 0 table: - * 00 -> no transmitter flow - * control - * 01 -> receiver compares - * XON2 and XOFF2 - * and controls - * transmitter - * 10 -> receiver compares - * XON1 and XOFF1 - * and controls - * transmitter - * 11 -> receiver compares - * XON1, XON2, XOFF1 and - * XOFF2 and controls - * transmitter - */ -#define MAX3107_FLOWCTRL_SWFLOW2_BIT (1 << 6) /* SWFLOW bit 2 */ -#define MAX3107_FLOWCTRL_SWFLOW3_BIT (1 << 7) /* SWFLOW bit 3 - * - * SWFLOW bits 3 & 2 table: - * 00 -> no received flow - * control - * 01 -> transmitter generates - * XON2 and XOFF2 - * 10 -> transmitter generates - * XON1 and XOFF1 - * 11 -> transmitter generates - * XON1, XON2, XOFF1 and - * XOFF2 - */ - -/* GPIO configuration register bits */ -#define MAX3107_GPIOCFG_GP0OUT_BIT (1 << 0) /* GPIO 0 output enable */ -#define MAX3107_GPIOCFG_GP1OUT_BIT (1 << 1) /* GPIO 1 output enable */ -#define MAX3107_GPIOCFG_GP2OUT_BIT (1 << 2) /* GPIO 2 output enable */ -#define MAX3107_GPIOCFG_GP3OUT_BIT (1 << 3) /* GPIO 3 output enable */ -#define MAX3107_GPIOCFG_GP0OD_BIT (1 << 4) /* GPIO 0 open-drain enable */ -#define MAX3107_GPIOCFG_GP1OD_BIT (1 << 5) /* GPIO 1 open-drain enable */ -#define MAX3107_GPIOCFG_GP2OD_BIT (1 << 6) /* GPIO 2 open-drain enable */ -#define MAX3107_GPIOCFG_GP3OD_BIT (1 << 7) /* GPIO 3 open-drain enable */ - -/* GPIO DATA register bits */ -#define MAX3107_GPIODATA_GP0OUT_BIT (1 << 0) /* GPIO 0 output value */ -#define MAX3107_GPIODATA_GP1OUT_BIT (1 << 1) /* GPIO 1 output value */ -#define MAX3107_GPIODATA_GP2OUT_BIT (1 << 2) /* GPIO 2 output value */ -#define MAX3107_GPIODATA_GP3OUT_BIT (1 << 3) /* GPIO 3 output value */ -#define MAX3107_GPIODATA_GP0IN_BIT (1 << 4) /* GPIO 0 input value */ -#define MAX3107_GPIODATA_GP1IN_BIT (1 << 5) /* GPIO 1 input value */ -#define MAX3107_GPIODATA_GP2IN_BIT (1 << 6) /* GPIO 2 input value */ -#define MAX3107_GPIODATA_GP3IN_BIT (1 << 7) /* GPIO 3 input value */ - -/* PLL configuration register masks */ -#define MAX3107_PLLCFG_PREDIV_MASK (0x003f) /* PLL predivision value */ -#define MAX3107_PLLCFG_PLLFACTOR_MASK (0x00c0) /* PLL multiplication factor */ - -/* Baud rate generator configuration register masks and bits */ -#define MAX3107_BRGCFG_FRACT_MASK (0x000f) /* Fractional portion of - * Baud rate generator divisor - */ -#define MAX3107_BRGCFG_2XMODE_BIT (1 << 4) /* Double baud rate */ -#define MAX3107_BRGCFG_4XMODE_BIT (1 << 5) /* Quadruple baud rate */ -#define MAX3107_BRGCFG_UNDEF6_BIT (1 << 6) /* Undefined/not used */ -#define MAX3107_BRGCFG_UNDEF7_BIT (1 << 7) /* Undefined/not used */ - -/* Clock source register bits */ -#define MAX3107_CLKSRC_INTOSC_BIT (1 << 0) /* Internal osc enable */ -#define MAX3107_CLKSRC_CRYST_BIT (1 << 1) /* Crystal osc enable */ -#define MAX3107_CLKSRC_PLL_BIT (1 << 2) /* PLL enable */ -#define MAX3107_CLKSRC_PLLBYP_BIT (1 << 3) /* PLL bypass */ -#define MAX3107_CLKSRC_EXTCLK_BIT (1 << 4) /* External clock enable */ -#define MAX3107_CLKSRC_UNDEF5_BIT (1 << 5) /* Undefined/not used */ -#define MAX3107_CLKSRC_UNDEF6_BIT (1 << 6) /* Undefined/not used */ -#define MAX3107_CLKSRC_CLK2RTS_BIT (1 << 7) /* Baud clk to RTS pin */ - - -/* HW definitions */ -#define MAX3107_RX_FIFO_SIZE 128 -#define MAX3107_TX_FIFO_SIZE 128 -#define MAX3107_REVID1 0x00a0 -#define MAX3107_REVID2 0x00a1 - - -/* Baud rate generator configuration values for external clock 13MHz */ -#define MAX3107_BRG13_B300 (0x0A9400 | 0x05) -#define MAX3107_BRG13_B600 (0x054A00 | 0x03) -#define MAX3107_BRG13_B1200 (0x02A500 | 0x01) -#define MAX3107_BRG13_B2400 (0x015200 | 0x09) -#define MAX3107_BRG13_B4800 (0x00A900 | 0x04) -#define MAX3107_BRG13_B9600 (0x005400 | 0x0A) -#define MAX3107_BRG13_B19200 (0x002A00 | 0x05) -#define MAX3107_BRG13_B38400 (0x001500 | 0x03) -#define MAX3107_BRG13_B57600 (0x000E00 | 0x02) -#define MAX3107_BRG13_B115200 (0x000700 | 0x01) -#define MAX3107_BRG13_B230400 (0x000300 | 0x08) -#define MAX3107_BRG13_B460800 (0x000100 | 0x0c) -#define MAX3107_BRG13_B921600 (0x000100 | 0x1c) - -/* Baud rate generator configuration values for external clock 26MHz */ -#define MAX3107_BRG26_B300 (0x152800 | 0x0A) -#define MAX3107_BRG26_B600 (0x0A9400 | 0x05) -#define MAX3107_BRG26_B1200 (0x054A00 | 0x03) -#define MAX3107_BRG26_B2400 (0x02A500 | 0x01) -#define MAX3107_BRG26_B4800 (0x015200 | 0x09) -#define MAX3107_BRG26_B9600 (0x00A900 | 0x04) -#define MAX3107_BRG26_B19200 (0x005400 | 0x0A) -#define MAX3107_BRG26_B38400 (0x002A00 | 0x05) -#define MAX3107_BRG26_B57600 (0x001C00 | 0x03) -#define MAX3107_BRG26_B115200 (0x000E00 | 0x02) -#define MAX3107_BRG26_B230400 (0x000700 | 0x01) -#define MAX3107_BRG26_B460800 (0x000300 | 0x08) -#define MAX3107_BRG26_B921600 (0x000100 | 0x0C) - -/* Baud rate generator configuration values for internal clock */ -#define MAX3107_BRG13_IB300 (0x008000 | 0x00) -#define MAX3107_BRG13_IB600 (0x004000 | 0x00) -#define MAX3107_BRG13_IB1200 (0x002000 | 0x00) -#define MAX3107_BRG13_IB2400 (0x001000 | 0x00) -#define MAX3107_BRG13_IB4800 (0x000800 | 0x00) -#define MAX3107_BRG13_IB9600 (0x000400 | 0x00) -#define MAX3107_BRG13_IB19200 (0x000200 | 0x00) -#define MAX3107_BRG13_IB38400 (0x000100 | 0x00) -#define MAX3107_BRG13_IB57600 (0x000000 | 0x0B) -#define MAX3107_BRG13_IB115200 (0x000000 | 0x05) -#define MAX3107_BRG13_IB230400 (0x000000 | 0x03) -#define MAX3107_BRG13_IB460800 (0x000000 | 0x00) -#define MAX3107_BRG13_IB921600 (0x000000 | 0x00) - - -struct baud_table { - int baud; - u32 new_brg; -}; - -struct max3107_port { - /* UART port structure */ - struct uart_port port; - - /* SPI device structure */ - struct spi_device *spi; - -#if defined(CONFIG_GPIOLIB) - /* GPIO chip stucture */ - struct gpio_chip chip; -#endif - - /* Workqueue that does all the magic */ - struct workqueue_struct *workqueue; - struct work_struct work; - - /* Lock for shared data */ - spinlock_t data_lock; - - /* Device configuration */ - int ext_clk; /* 1 if external clock used */ - int loopback; /* Current loopback mode state */ - int baud; /* Current baud rate */ - - /* State flags */ - int suspended; /* Indicates suspend mode */ - int tx_fifo_empty; /* Flag for TX FIFO state */ - int rx_enabled; /* Flag for receiver state */ - int tx_enabled; /* Flag for transmitter state */ - - u16 irqen_reg; /* Current IRQ enable register value */ - /* Shared data */ - u16 mode1_reg; /* Current mode1 register value*/ - int mode1_commit; /* Flag for setting new mode1 register value */ - u16 lcr_reg; /* Current LCR register value */ - int lcr_commit; /* Flag for setting new LCR register value */ - u32 brg_cfg; /* Current Baud rate generator config */ - int brg_commit; /* Flag for setting new baud rate generator - * config - */ - struct baud_table *baud_tbl; - int handle_irq; /* Indicates that IRQ should be handled */ - - /* Rx buffer and str*/ - u16 *rxbuf; - u8 *rxstr; - /* Tx buffer*/ - u16 *txbuf; - - struct max3107_plat *pdata; /* Platform data */ -}; - -/* Platform data structure */ -struct max3107_plat { - /* Loopback mode enable */ - int loopback; - /* External clock enable */ - int ext_clk; - /* Called during the register initialisation */ - void (*init)(struct max3107_port *s); - /* Called when the port is found and configured */ - int (*configure)(struct max3107_port *s); - /* HW suspend function */ - void (*hw_suspend) (struct max3107_port *s, int suspend); - /* Polling mode enable */ - int polled_mode; - /* Polling period if polling mode enabled */ - int poll_time; -}; - -extern int max3107_rw(struct max3107_port *s, u8 *tx, u8 *rx, int len); -extern void max3107_hw_susp(struct max3107_port *s, int suspend); -extern int max3107_probe(struct spi_device *spi, struct max3107_plat *pdata); -extern int max3107_remove(struct spi_device *spi); -extern int max3107_suspend(struct spi_device *spi, pm_message_t state); -extern int max3107_resume(struct spi_device *spi); - -#endif /* _LINUX_SERIAL_MAX3107_H */ diff --git a/trunk/drivers/serial/mcf.c b/trunk/drivers/serial/mcf.c index 3394b7cc1722..b5aaef965f24 100644 --- a/trunk/drivers/serial/mcf.c +++ b/trunk/drivers/serial/mcf.c @@ -70,14 +70,16 @@ static unsigned int mcf_tx_empty(struct uart_port *port) static unsigned int mcf_get_mctrl(struct uart_port *port) { struct mcf_uart *pp = container_of(port, struct mcf_uart, port); + unsigned long flags; unsigned int sigs; + spin_lock_irqsave(&port->lock, flags); sigs = (readb(port->membase + MCFUART_UIPR) & MCFUART_UIPR_CTS) ? 0 : TIOCM_CTS; sigs |= (pp->sigs & TIOCM_RTS); sigs |= (mcf_getppdcd(port->line) ? TIOCM_CD : 0); sigs |= (mcf_getppdtr(port->line) ? TIOCM_DTR : 0); - + spin_unlock_irqrestore(&port->lock, flags); return sigs; } @@ -86,13 +88,16 @@ static unsigned int mcf_get_mctrl(struct uart_port *port) static void mcf_set_mctrl(struct uart_port *port, unsigned int sigs) { struct mcf_uart *pp = container_of(port, struct mcf_uart, port); + unsigned long flags; + spin_lock_irqsave(&port->lock, flags); pp->sigs = sigs; mcf_setppdtr(port->line, (sigs & TIOCM_DTR)); if (sigs & TIOCM_RTS) writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP1); else writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP0); + spin_unlock_irqrestore(&port->lock, flags); } /****************************************************************************/ @@ -100,9 +105,12 @@ static void mcf_set_mctrl(struct uart_port *port, unsigned int sigs) static void mcf_start_tx(struct uart_port *port) { struct mcf_uart *pp = container_of(port, struct mcf_uart, port); + unsigned long flags; + spin_lock_irqsave(&port->lock, flags); pp->imr |= MCFUART_UIR_TXREADY; writeb(pp->imr, port->membase + MCFUART_UIMR); + spin_unlock_irqrestore(&port->lock, flags); } /****************************************************************************/ @@ -110,9 +118,12 @@ static void mcf_start_tx(struct uart_port *port) static void mcf_stop_tx(struct uart_port *port) { struct mcf_uart *pp = container_of(port, struct mcf_uart, port); + unsigned long flags; + spin_lock_irqsave(&port->lock, flags); pp->imr &= ~MCFUART_UIR_TXREADY; writeb(pp->imr, port->membase + MCFUART_UIMR); + spin_unlock_irqrestore(&port->lock, flags); } /****************************************************************************/ @@ -120,9 +131,12 @@ static void mcf_stop_tx(struct uart_port *port) static void mcf_stop_rx(struct uart_port *port) { struct mcf_uart *pp = container_of(port, struct mcf_uart, port); + unsigned long flags; + spin_lock_irqsave(&port->lock, flags); pp->imr &= ~MCFUART_UIR_RXREADY; writeb(pp->imr, port->membase + MCFUART_UIMR); + spin_unlock_irqrestore(&port->lock, flags); } /****************************************************************************/ @@ -352,22 +366,13 @@ static irqreturn_t mcf_interrupt(int irq, void *data) struct uart_port *port = data; struct mcf_uart *pp = container_of(port, struct mcf_uart, port); unsigned int isr; - irqreturn_t ret = IRQ_NONE; isr = readb(port->membase + MCFUART_UISR) & pp->imr; - - spin_lock(&port->lock); - if (isr & MCFUART_UIR_RXREADY) { + if (isr & MCFUART_UIR_RXREADY) mcf_rx_chars(pp); - ret = IRQ_HANDLED; - } - if (isr & MCFUART_UIR_TXREADY) { + if (isr & MCFUART_UIR_TXREADY) mcf_tx_chars(pp); - ret = IRQ_HANDLED; - } - spin_unlock(&port->lock); - - return ret; + return IRQ_HANDLED; } /****************************************************************************/ diff --git a/trunk/drivers/serial/mfd.c b/trunk/drivers/serial/mfd.c deleted file mode 100644 index bc9af503907f..000000000000 --- a/trunk/drivers/serial/mfd.c +++ /dev/null @@ -1,1498 +0,0 @@ -/* - * mfd.c: driver for High Speed UART device of Intel Medfield platform - * - * Refer pxa.c, 8250.c and some other drivers in drivers/serial/ - * - * (C) Copyright 2010 Intel Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; version 2 - * of the License. - */ - -/* Notes: - * 1. DMA channel allocation: 0/1 channel are assigned to port 0, - * 2/3 chan to port 1, 4/5 chan to port 3. Even number chans - * are used for RX, odd chans for TX - * - * 2. In A0 stepping, UART will not support TX half empty flag - * - * 3. The RI/DSR/DCD/DTR are not pinned out, DCD & DSR are always - * asserted, only when the HW is reset the DDCD and DDSR will - * be triggered - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MFD_HSU_A0_STEPPING 1 - -#define HSU_DMA_BUF_SIZE 2048 - -#define chan_readl(chan, offset) readl(chan->reg + offset) -#define chan_writel(chan, offset, val) writel(val, chan->reg + offset) - -#define mfd_readl(obj, offset) readl(obj->reg + offset) -#define mfd_writel(obj, offset, val) writel(val, obj->reg + offset) - -#define HSU_DMA_TIMEOUT_CHECK_FREQ (HZ/10) - -struct hsu_dma_buffer { - u8 *buf; - dma_addr_t dma_addr; - u32 dma_size; - u32 ofs; -}; - -struct hsu_dma_chan { - u32 id; - enum dma_data_direction dirt; - struct uart_hsu_port *uport; - void __iomem *reg; - struct timer_list rx_timer; /* only needed by RX channel */ -}; - -struct uart_hsu_port { - struct uart_port port; - unsigned char ier; - unsigned char lcr; - unsigned char mcr; - unsigned int lsr_break_flag; - char name[12]; - int index; - struct device *dev; - - struct hsu_dma_chan *txc; - struct hsu_dma_chan *rxc; - struct hsu_dma_buffer txbuf; - struct hsu_dma_buffer rxbuf; - int use_dma; /* flag for DMA/PIO */ - int running; - int dma_tx_on; -}; - -/* Top level data structure of HSU */ -struct hsu_port { - void __iomem *reg; - unsigned long paddr; - unsigned long iolen; - u32 irq; - - struct uart_hsu_port port[3]; - struct hsu_dma_chan chans[10]; - - struct dentry *debugfs; -}; - -static inline unsigned int serial_in(struct uart_hsu_port *up, int offset) -{ - unsigned int val; - - if (offset > UART_MSR) { - offset <<= 2; - val = readl(up->port.membase + offset); - } else - val = (unsigned int)readb(up->port.membase + offset); - - return val; -} - -static inline void serial_out(struct uart_hsu_port *up, int offset, int value) -{ - if (offset > UART_MSR) { - offset <<= 2; - writel(value, up->port.membase + offset); - } else { - unsigned char val = value & 0xff; - writeb(val, up->port.membase + offset); - } -} - -#ifdef CONFIG_DEBUG_FS - -#define HSU_REGS_BUFSIZE 1024 - -static int hsu_show_regs_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t port_show_regs(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct uart_hsu_port *up = file->private_data; - char *buf; - u32 len = 0; - ssize_t ret; - - buf = kzalloc(HSU_REGS_BUFSIZE, GFP_KERNEL); - if (!buf) - return 0; - - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "MFD HSU port[%d] regs:\n", up->index); - - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "=================================\n"); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "IER: \t\t0x%08x\n", serial_in(up, UART_IER)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "IIR: \t\t0x%08x\n", serial_in(up, UART_IIR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "LCR: \t\t0x%08x\n", serial_in(up, UART_LCR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "MCR: \t\t0x%08x\n", serial_in(up, UART_MCR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "LSR: \t\t0x%08x\n", serial_in(up, UART_LSR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "MSR: \t\t0x%08x\n", serial_in(up, UART_MSR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "FOR: \t\t0x%08x\n", serial_in(up, UART_FOR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "PS: \t\t0x%08x\n", serial_in(up, UART_PS)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "MUL: \t\t0x%08x\n", serial_in(up, UART_MUL)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "DIV: \t\t0x%08x\n", serial_in(up, UART_DIV)); - - ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); - kfree(buf); - return ret; -} - -static ssize_t dma_show_regs(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct hsu_dma_chan *chan = file->private_data; - char *buf; - u32 len = 0; - ssize_t ret; - - buf = kzalloc(HSU_REGS_BUFSIZE, GFP_KERNEL); - if (!buf) - return 0; - - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "MFD HSU DMA channel [%d] regs:\n", chan->id); - - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "=================================\n"); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "CR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_CR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "DCR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_DCR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "BSR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_BSR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "MOTSR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_MOTSR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "D0SAR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D0SAR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "D0TSR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D0TSR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "D0SAR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D1SAR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "D0TSR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D1TSR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "D0SAR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D2SAR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "D0TSR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D2TSR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "D0SAR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D3SAR)); - len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, - "D0TSR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D3TSR)); - - ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); - kfree(buf); - return ret; -} - -static const struct file_operations port_regs_ops = { - .owner = THIS_MODULE, - .open = hsu_show_regs_open, - .read = port_show_regs, -}; - -static const struct file_operations dma_regs_ops = { - .owner = THIS_MODULE, - .open = hsu_show_regs_open, - .read = dma_show_regs, -}; - -static int hsu_debugfs_init(struct hsu_port *hsu) -{ - int i; - char name[32]; - - hsu->debugfs = debugfs_create_dir("hsu", NULL); - if (!hsu->debugfs) - return -ENOMEM; - - for (i = 0; i < 3; i++) { - snprintf(name, sizeof(name), "port_%d_regs", i); - debugfs_create_file(name, S_IFREG | S_IRUGO, - hsu->debugfs, (void *)(&hsu->port[i]), &port_regs_ops); - } - - for (i = 0; i < 6; i++) { - snprintf(name, sizeof(name), "dma_chan_%d_regs", i); - debugfs_create_file(name, S_IFREG | S_IRUGO, - hsu->debugfs, (void *)&hsu->chans[i], &dma_regs_ops); - } - - return 0; -} - -static void hsu_debugfs_remove(struct hsu_port *hsu) -{ - if (hsu->debugfs) - debugfs_remove_recursive(hsu->debugfs); -} - -#else -static inline int hsu_debugfs_init(struct hsu_port *hsu) -{ - return 0; -} - -static inline void hsu_debugfs_remove(struct hsu_port *hsu) -{ -} -#endif /* CONFIG_DEBUG_FS */ - -static void serial_hsu_enable_ms(struct uart_port *port) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - - up->ier |= UART_IER_MSI; - serial_out(up, UART_IER, up->ier); -} - -void hsu_dma_tx(struct uart_hsu_port *up) -{ - struct circ_buf *xmit = &up->port.state->xmit; - struct hsu_dma_buffer *dbuf = &up->txbuf; - int count; - - /* test_and_set_bit may be better, but anyway it's in lock protected mode */ - if (up->dma_tx_on) - return; - - /* Update the circ buf info */ - xmit->tail += dbuf->ofs; - xmit->tail &= UART_XMIT_SIZE - 1; - - up->port.icount.tx += dbuf->ofs; - dbuf->ofs = 0; - - /* Disable the channel */ - chan_writel(up->txc, HSU_CH_CR, 0x0); - - if (!uart_circ_empty(xmit) && !uart_tx_stopped(&up->port)) { - dma_sync_single_for_device(up->port.dev, - dbuf->dma_addr, - dbuf->dma_size, - DMA_TO_DEVICE); - - count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); - dbuf->ofs = count; - - /* Reprogram the channel */ - chan_writel(up->txc, HSU_CH_D0SAR, dbuf->dma_addr + xmit->tail); - chan_writel(up->txc, HSU_CH_D0TSR, count); - - /* Reenable the channel */ - chan_writel(up->txc, HSU_CH_DCR, 0x1 - | (0x1 << 8) - | (0x1 << 16) - | (0x1 << 24)); - up->dma_tx_on = 1; - chan_writel(up->txc, HSU_CH_CR, 0x1); - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&up->port); -} - -/* The buffer is already cache coherent */ -void hsu_dma_start_rx_chan(struct hsu_dma_chan *rxc, struct hsu_dma_buffer *dbuf) -{ - dbuf->ofs = 0; - - chan_writel(rxc, HSU_CH_BSR, 32); - chan_writel(rxc, HSU_CH_MOTSR, 4); - - chan_writel(rxc, HSU_CH_D0SAR, dbuf->dma_addr); - chan_writel(rxc, HSU_CH_D0TSR, dbuf->dma_size); - chan_writel(rxc, HSU_CH_DCR, 0x1 | (0x1 << 8) - | (0x1 << 16) - | (0x1 << 24) /* timeout bit, see HSU Errata 1 */ - ); - chan_writel(rxc, HSU_CH_CR, 0x3); - - mod_timer(&rxc->rx_timer, jiffies + HSU_DMA_TIMEOUT_CHECK_FREQ); -} - -/* Protected by spin_lock_irqsave(port->lock) */ -static void serial_hsu_start_tx(struct uart_port *port) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - - if (up->use_dma) { - hsu_dma_tx(up); - } else if (!(up->ier & UART_IER_THRI)) { - up->ier |= UART_IER_THRI; - serial_out(up, UART_IER, up->ier); - } -} - -static void serial_hsu_stop_tx(struct uart_port *port) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - struct hsu_dma_chan *txc = up->txc; - - if (up->use_dma) - chan_writel(txc, HSU_CH_CR, 0x0); - else if (up->ier & UART_IER_THRI) { - up->ier &= ~UART_IER_THRI; - serial_out(up, UART_IER, up->ier); - } -} - -/* This is always called in spinlock protected mode, so - * modify timeout timer is safe here */ -void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts) -{ - struct hsu_dma_buffer *dbuf = &up->rxbuf; - struct hsu_dma_chan *chan = up->rxc; - struct uart_port *port = &up->port; - struct tty_struct *tty = port->state->port.tty; - int count; - - if (!tty) - return; - - /* - * First need to know how many is already transferred, - * then check if its a timeout DMA irq, and return - * the trail bytes out, push them up and reenable the - * channel - */ - - /* Timeout IRQ, need wait some time, see Errata 2 */ - if (int_sts & 0xf00) - udelay(2); - - /* Stop the channel */ - chan_writel(chan, HSU_CH_CR, 0x0); - - count = chan_readl(chan, HSU_CH_D0SAR) - dbuf->dma_addr; - if (!count) { - /* Restart the channel before we leave */ - chan_writel(chan, HSU_CH_CR, 0x3); - return; - } - del_timer(&chan->rx_timer); - - dma_sync_single_for_cpu(port->dev, dbuf->dma_addr, - dbuf->dma_size, DMA_FROM_DEVICE); - - /* - * Head will only wrap around when we recycle - * the DMA buffer, and when that happens, we - * explicitly set tail to 0. So head will - * always be greater than tail. - */ - tty_insert_flip_string(tty, dbuf->buf, count); - port->icount.rx += count; - - dma_sync_single_for_device(up->port.dev, dbuf->dma_addr, - dbuf->dma_size, DMA_FROM_DEVICE); - - /* Reprogram the channel */ - chan_writel(chan, HSU_CH_D0SAR, dbuf->dma_addr); - chan_writel(chan, HSU_CH_D0TSR, dbuf->dma_size); - chan_writel(chan, HSU_CH_DCR, 0x1 - | (0x1 << 8) - | (0x1 << 16) - | (0x1 << 24) /* timeout bit, see HSU Errata 1 */ - ); - tty_flip_buffer_push(tty); - - chan_writel(chan, HSU_CH_CR, 0x3); - chan->rx_timer.expires = jiffies + HSU_DMA_TIMEOUT_CHECK_FREQ; - add_timer(&chan->rx_timer); - -} - -static void serial_hsu_stop_rx(struct uart_port *port) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - struct hsu_dma_chan *chan = up->rxc; - - if (up->use_dma) - chan_writel(chan, HSU_CH_CR, 0x2); - else { - up->ier &= ~UART_IER_RLSI; - up->port.read_status_mask &= ~UART_LSR_DR; - serial_out(up, UART_IER, up->ier); - } -} - -static inline void receive_chars(struct uart_hsu_port *up, int *status) -{ - struct tty_struct *tty = up->port.state->port.tty; - unsigned int ch, flag; - unsigned int max_count = 256; - - if (!tty) - return; - - do { - ch = serial_in(up, UART_RX); - flag = TTY_NORMAL; - up->port.icount.rx++; - - if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | - UART_LSR_FE | UART_LSR_OE))) { - - dev_warn(up->dev, "We really rush into ERR/BI case" - "status = 0x%02x", *status); - /* For statistics only */ - if (*status & UART_LSR_BI) { - *status &= ~(UART_LSR_FE | UART_LSR_PE); - up->port.icount.brk++; - /* - * We do the SysRQ and SAK checking - * here because otherwise the break - * may get masked by ignore_status_mask - * or read_status_mask. - */ - if (uart_handle_break(&up->port)) - goto ignore_char; - } else if (*status & UART_LSR_PE) - up->port.icount.parity++; - else if (*status & UART_LSR_FE) - up->port.icount.frame++; - if (*status & UART_LSR_OE) - up->port.icount.overrun++; - - /* Mask off conditions which should be ignored. */ - *status &= up->port.read_status_mask; - -#ifdef CONFIG_SERIAL_MFD_HSU_CONSOLE - if (up->port.cons && - up->port.cons->index == up->port.line) { - /* Recover the break flag from console xmit */ - *status |= up->lsr_break_flag; - up->lsr_break_flag = 0; - } -#endif - if (*status & UART_LSR_BI) { - flag = TTY_BREAK; - } else if (*status & UART_LSR_PE) - flag = TTY_PARITY; - else if (*status & UART_LSR_FE) - flag = TTY_FRAME; - } - - if (uart_handle_sysrq_char(&up->port, ch)) - goto ignore_char; - - uart_insert_char(&up->port, *status, UART_LSR_OE, ch, flag); - ignore_char: - *status = serial_in(up, UART_LSR); - } while ((*status & UART_LSR_DR) && max_count--); - tty_flip_buffer_push(tty); -} - -static void transmit_chars(struct uart_hsu_port *up) -{ - struct circ_buf *xmit = &up->port.state->xmit; - int count; - - if (up->port.x_char) { - serial_out(up, UART_TX, up->port.x_char); - up->port.icount.tx++; - up->port.x_char = 0; - return; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { - serial_hsu_stop_tx(&up->port); - return; - } - -#ifndef MFD_HSU_A0_STEPPING - count = up->port.fifosize / 2; -#else - /* - * A0 only supports fully empty IRQ, and the first char written - * into it won't clear the EMPT bit, so we may need be cautious - * by useing a shorter buffer - */ - count = up->port.fifosize - 4; -#endif - do { - serial_out(up, UART_TX, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - - up->port.icount.tx++; - if (uart_circ_empty(xmit)) - break; - } while (--count > 0); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&up->port); - - if (uart_circ_empty(xmit)) - serial_hsu_stop_tx(&up->port); -} - -static inline void check_modem_status(struct uart_hsu_port *up) -{ - int status; - - status = serial_in(up, UART_MSR); - - if ((status & UART_MSR_ANY_DELTA) == 0) - return; - - if (status & UART_MSR_TERI) - up->port.icount.rng++; - if (status & UART_MSR_DDSR) - up->port.icount.dsr++; - /* We may only get DDCD when HW init and reset */ - if (status & UART_MSR_DDCD) - uart_handle_dcd_change(&up->port, status & UART_MSR_DCD); - /* Will start/stop_tx accordingly */ - if (status & UART_MSR_DCTS) - uart_handle_cts_change(&up->port, status & UART_MSR_CTS); - - wake_up_interruptible(&up->port.state->port.delta_msr_wait); -} - -/* - * This handles the interrupt from one port. - */ -static irqreturn_t port_irq(int irq, void *dev_id) -{ - struct uart_hsu_port *up = dev_id; - unsigned int iir, lsr; - unsigned long flags; - - if (unlikely(!up->running)) - return IRQ_NONE; - - spin_lock_irqsave(&up->port.lock, flags); - if (up->use_dma) { - lsr = serial_in(up, UART_LSR); - if (unlikely(lsr & (UART_LSR_BI | UART_LSR_PE | - UART_LSR_FE | UART_LSR_OE))) - dev_warn(up->dev, - "Got lsr irq while using DMA, lsr = 0x%2x\n", - lsr); - check_modem_status(up); - spin_unlock_irqrestore(&up->port.lock, flags); - return IRQ_HANDLED; - } - - iir = serial_in(up, UART_IIR); - if (iir & UART_IIR_NO_INT) { - spin_unlock_irqrestore(&up->port.lock, flags); - return IRQ_NONE; - } - - lsr = serial_in(up, UART_LSR); - if (lsr & UART_LSR_DR) - receive_chars(up, &lsr); - check_modem_status(up); - - /* lsr will be renewed during the receive_chars */ - if (lsr & UART_LSR_THRE) - transmit_chars(up); - - spin_unlock_irqrestore(&up->port.lock, flags); - return IRQ_HANDLED; -} - -static inline void dma_chan_irq(struct hsu_dma_chan *chan) -{ - struct uart_hsu_port *up = chan->uport; - unsigned long flags; - u32 int_sts; - - spin_lock_irqsave(&up->port.lock, flags); - - if (!up->use_dma || !up->running) - goto exit; - - /* - * No matter what situation, need read clear the IRQ status - * There is a bug, see Errata 5, HSD 2900918 - */ - int_sts = chan_readl(chan, HSU_CH_SR); - - /* Rx channel */ - if (chan->dirt == DMA_FROM_DEVICE) - hsu_dma_rx(up, int_sts); - - /* Tx channel */ - if (chan->dirt == DMA_TO_DEVICE) { - chan_writel(chan, HSU_CH_CR, 0x0); - up->dma_tx_on = 0; - hsu_dma_tx(up); - } - -exit: - spin_unlock_irqrestore(&up->port.lock, flags); - return; -} - -static irqreturn_t dma_irq(int irq, void *dev_id) -{ - struct hsu_port *hsu = dev_id; - u32 int_sts, i; - - int_sts = mfd_readl(hsu, HSU_GBL_DMAISR); - - /* Currently we only have 6 channels may be used */ - for (i = 0; i < 6; i++) { - if (int_sts & 0x1) - dma_chan_irq(&hsu->chans[i]); - int_sts >>= 1; - } - - return IRQ_HANDLED; -} - -static unsigned int serial_hsu_tx_empty(struct uart_port *port) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - unsigned long flags; - unsigned int ret; - - spin_lock_irqsave(&up->port.lock, flags); - ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; - spin_unlock_irqrestore(&up->port.lock, flags); - - return ret; -} - -static unsigned int serial_hsu_get_mctrl(struct uart_port *port) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - unsigned char status; - unsigned int ret; - - status = serial_in(up, UART_MSR); - - ret = 0; - if (status & UART_MSR_DCD) - ret |= TIOCM_CAR; - if (status & UART_MSR_RI) - ret |= TIOCM_RNG; - if (status & UART_MSR_DSR) - ret |= TIOCM_DSR; - if (status & UART_MSR_CTS) - ret |= TIOCM_CTS; - return ret; -} - -static void serial_hsu_set_mctrl(struct uart_port *port, unsigned int mctrl) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - unsigned char mcr = 0; - - if (mctrl & TIOCM_RTS) - mcr |= UART_MCR_RTS; - if (mctrl & TIOCM_DTR) - mcr |= UART_MCR_DTR; - if (mctrl & TIOCM_OUT1) - mcr |= UART_MCR_OUT1; - if (mctrl & TIOCM_OUT2) - mcr |= UART_MCR_OUT2; - if (mctrl & TIOCM_LOOP) - mcr |= UART_MCR_LOOP; - - mcr |= up->mcr; - - serial_out(up, UART_MCR, mcr); -} - -static void serial_hsu_break_ctl(struct uart_port *port, int break_state) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - unsigned long flags; - - spin_lock_irqsave(&up->port.lock, flags); - if (break_state == -1) - up->lcr |= UART_LCR_SBC; - else - up->lcr &= ~UART_LCR_SBC; - serial_out(up, UART_LCR, up->lcr); - spin_unlock_irqrestore(&up->port.lock, flags); -} - -/* - * What special to do: - * 1. chose the 64B fifo mode - * 2. make sure not to select half empty mode for A0 stepping - * 3. start dma or pio depends on configuration - * 4. we only allocate dma memory when needed - */ -static int serial_hsu_startup(struct uart_port *port) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - unsigned long flags; - - /* - * Clear the FIFO buffers and disable them. - * (they will be reenabled in set_termios()) - */ - serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); - serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | - UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); - serial_out(up, UART_FCR, 0); - - /* Clear the interrupt registers. */ - (void) serial_in(up, UART_LSR); - (void) serial_in(up, UART_RX); - (void) serial_in(up, UART_IIR); - (void) serial_in(up, UART_MSR); - - /* Now, initialize the UART, default is 8n1 */ - serial_out(up, UART_LCR, UART_LCR_WLEN8); - - spin_lock_irqsave(&up->port.lock, flags); - - up->port.mctrl |= TIOCM_OUT2; - serial_hsu_set_mctrl(&up->port, up->port.mctrl); - - /* - * Finally, enable interrupts. Note: Modem status interrupts - * are set via set_termios(), which will be occurring imminently - * anyway, so we don't enable them here. - */ - if (!up->use_dma) - up->ier = UART_IER_RLSI | UART_IER_RDI | UART_IER_RTOIE; - else - up->ier = 0; - serial_out(up, UART_IER, up->ier); - - spin_unlock_irqrestore(&up->port.lock, flags); - - /* DMA init */ - if (up->use_dma) { - struct hsu_dma_buffer *dbuf; - struct circ_buf *xmit = &port->state->xmit; - - up->dma_tx_on = 0; - - /* First allocate the RX buffer */ - dbuf = &up->rxbuf; - dbuf->buf = kzalloc(HSU_DMA_BUF_SIZE, GFP_KERNEL); - if (!dbuf->buf) { - up->use_dma = 0; - goto exit; - } - dbuf->dma_addr = dma_map_single(port->dev, - dbuf->buf, - HSU_DMA_BUF_SIZE, - DMA_FROM_DEVICE); - dbuf->dma_size = HSU_DMA_BUF_SIZE; - - /* Start the RX channel right now */ - hsu_dma_start_rx_chan(up->rxc, dbuf); - - /* Next init the TX DMA */ - dbuf = &up->txbuf; - dbuf->buf = xmit->buf; - dbuf->dma_addr = dma_map_single(port->dev, - dbuf->buf, - UART_XMIT_SIZE, - DMA_TO_DEVICE); - dbuf->dma_size = UART_XMIT_SIZE; - - /* This should not be changed all around */ - chan_writel(up->txc, HSU_CH_BSR, 32); - chan_writel(up->txc, HSU_CH_MOTSR, 4); - dbuf->ofs = 0; - } - -exit: - /* And clear the interrupt registers again for luck. */ - (void) serial_in(up, UART_LSR); - (void) serial_in(up, UART_RX); - (void) serial_in(up, UART_IIR); - (void) serial_in(up, UART_MSR); - - up->running = 1; - return 0; -} - -static void serial_hsu_shutdown(struct uart_port *port) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - unsigned long flags; - - del_timer_sync(&up->rxc->rx_timer); - - /* Disable interrupts from this port */ - up->ier = 0; - serial_out(up, UART_IER, 0); - up->running = 0; - - spin_lock_irqsave(&up->port.lock, flags); - up->port.mctrl &= ~TIOCM_OUT2; - serial_hsu_set_mctrl(&up->port, up->port.mctrl); - spin_unlock_irqrestore(&up->port.lock, flags); - - /* Disable break condition and FIFOs */ - serial_out(up, UART_LCR, serial_in(up, UART_LCR) & ~UART_LCR_SBC); - serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | - UART_FCR_CLEAR_RCVR | - UART_FCR_CLEAR_XMIT); - serial_out(up, UART_FCR, 0); -} - -static void -serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios, - struct ktermios *old) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - struct tty_struct *tty = port->state->port.tty; - unsigned char cval, fcr = 0; - unsigned long flags; - unsigned int baud, quot; - u32 mul = 0x3600; - u32 ps = 0x10; - - switch (termios->c_cflag & CSIZE) { - case CS5: - cval = UART_LCR_WLEN5; - break; - case CS6: - cval = UART_LCR_WLEN6; - break; - case CS7: - cval = UART_LCR_WLEN7; - break; - default: - case CS8: - cval = UART_LCR_WLEN8; - break; - } - - /* CMSPAR isn't supported by this driver */ - if (tty) - tty->termios->c_cflag &= ~CMSPAR; - - if (termios->c_cflag & CSTOPB) - cval |= UART_LCR_STOP; - if (termios->c_cflag & PARENB) - cval |= UART_LCR_PARITY; - if (!(termios->c_cflag & PARODD)) - cval |= UART_LCR_EPAR; - - /* - * For those basic low baud rate we can get the direct - * scalar from 2746800, like 115200 = 2746800/24, for those - * higher baud rate, we have to handle them case by case, - * but DIV reg is never touched as its default value 0x3d09 - */ - baud = uart_get_baud_rate(port, termios, old, 0, 4000000); - quot = uart_get_divisor(port, baud); - - switch (baud) { - case 3500000: - mul = 0x3345; - ps = 0xC; - quot = 1; - break; - case 2500000: - mul = 0x2710; - ps = 0x10; - quot = 1; - break; - case 18432000: - mul = 0x2400; - ps = 0x10; - quot = 1; - break; - case 1500000: - mul = 0x1D4C; - ps = 0xc; - quot = 1; - break; - default: - ; - } - - if ((up->port.uartclk / quot) < (2400 * 16)) - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_HSU_64_1B; - else if ((up->port.uartclk / quot) < (230400 * 16)) - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_HSU_64_16B; - else - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_HSU_64_32B; - - fcr |= UART_FCR_HSU_64B_FIFO; -#ifdef MFD_HSU_A0_STEPPING - /* A0 doesn't support half empty IRQ */ - fcr |= UART_FCR_FULL_EMPT_TXI; -#endif - - /* - * Ok, we're now changing the port state. Do it with - * interrupts disabled. - */ - spin_lock_irqsave(&up->port.lock, flags); - - /* Update the per-port timeout */ - uart_update_timeout(port, termios->c_cflag, baud); - - up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; - if (termios->c_iflag & INPCK) - up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE; - if (termios->c_iflag & (BRKINT | PARMRK)) - up->port.read_status_mask |= UART_LSR_BI; - - /* Characters to ignore */ - up->port.ignore_status_mask = 0; - if (termios->c_iflag & IGNPAR) - up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; - if (termios->c_iflag & IGNBRK) { - up->port.ignore_status_mask |= UART_LSR_BI; - /* - * If we're ignoring parity and break indicators, - * ignore overruns too (for real raw support). - */ - if (termios->c_iflag & IGNPAR) - up->port.ignore_status_mask |= UART_LSR_OE; - } - - /* Ignore all characters if CREAD is not set */ - if ((termios->c_cflag & CREAD) == 0) - up->port.ignore_status_mask |= UART_LSR_DR; - - /* - * CTS flow control flag and modem status interrupts, disable - * MSI by default - */ - up->ier &= ~UART_IER_MSI; - if (UART_ENABLE_MS(&up->port, termios->c_cflag)) - up->ier |= UART_IER_MSI; - - serial_out(up, UART_IER, up->ier); - - if (termios->c_cflag & CRTSCTS) - up->mcr |= UART_MCR_AFE | UART_MCR_RTS; - else - up->mcr &= ~UART_MCR_AFE; - - serial_out(up, UART_LCR, cval | UART_LCR_DLAB); /* set DLAB */ - serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */ - serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */ - serial_out(up, UART_LCR, cval); /* reset DLAB */ - serial_out(up, UART_MUL, mul); /* set MUL */ - serial_out(up, UART_PS, ps); /* set PS */ - up->lcr = cval; /* Save LCR */ - serial_hsu_set_mctrl(&up->port, up->port.mctrl); - serial_out(up, UART_FCR, fcr); - spin_unlock_irqrestore(&up->port.lock, flags); -} - -static void -serial_hsu_pm(struct uart_port *port, unsigned int state, - unsigned int oldstate) -{ -} - -static void serial_hsu_release_port(struct uart_port *port) -{ -} - -static int serial_hsu_request_port(struct uart_port *port) -{ - return 0; -} - -static void serial_hsu_config_port(struct uart_port *port, int flags) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - up->port.type = PORT_MFD; -} - -static int -serial_hsu_verify_port(struct uart_port *port, struct serial_struct *ser) -{ - /* We don't want the core code to modify any port params */ - return -EINVAL; -} - -static const char * -serial_hsu_type(struct uart_port *port) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - return up->name; -} - -/* Mainly for uart console use */ -static struct uart_hsu_port *serial_hsu_ports[3]; -static struct uart_driver serial_hsu_reg; - -#ifdef CONFIG_SERIAL_MFD_HSU_CONSOLE - -#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) - -/* Wait for transmitter & holding register to empty */ -static inline void wait_for_xmitr(struct uart_hsu_port *up) -{ - unsigned int status, tmout = 1000; - - /* Wait up to 1ms for the character to be sent. */ - do { - status = serial_in(up, UART_LSR); - - if (status & UART_LSR_BI) - up->lsr_break_flag = UART_LSR_BI; - - if (--tmout == 0) - break; - udelay(1); - } while (!(status & BOTH_EMPTY)); - - /* Wait up to 1s for flow control if necessary */ - if (up->port.flags & UPF_CONS_FLOW) { - tmout = 1000000; - while (--tmout && - ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0)) - udelay(1); - } -} - -static void serial_hsu_console_putchar(struct uart_port *port, int ch) -{ - struct uart_hsu_port *up = - container_of(port, struct uart_hsu_port, port); - - wait_for_xmitr(up); - serial_out(up, UART_TX, ch); -} - -/* - * Print a string to the serial port trying not to disturb - * any possible real use of the port... - * - * The console_lock must be held when we get here. - */ -static void -serial_hsu_console_write(struct console *co, const char *s, unsigned int count) -{ - struct uart_hsu_port *up = serial_hsu_ports[co->index]; - unsigned long flags; - unsigned int ier; - int locked = 1; - - local_irq_save(flags); - if (up->port.sysrq) - locked = 0; - else if (oops_in_progress) { - locked = spin_trylock(&up->port.lock); - } else - spin_lock(&up->port.lock); - - /* First save the IER then disable the interrupts */ - ier = serial_in(up, UART_IER); - serial_out(up, UART_IER, 0); - - uart_console_write(&up->port, s, count, serial_hsu_console_putchar); - - /* - * Finally, wait for transmitter to become empty - * and restore the IER - */ - wait_for_xmitr(up); - serial_out(up, UART_IER, ier); - - if (locked) - spin_unlock(&up->port.lock); - local_irq_restore(flags); -} - -static struct console serial_hsu_console; - -static int __init -serial_hsu_console_setup(struct console *co, char *options) -{ - struct uart_hsu_port *up; - int baud = 115200; - int bits = 8; - int parity = 'n'; - int flow = 'n'; - int ret; - - if (co->index == -1 || co->index >= serial_hsu_reg.nr) - co->index = 0; - up = serial_hsu_ports[co->index]; - if (!up) - return -ENODEV; - - if (options) - uart_parse_options(options, &baud, &parity, &bits, &flow); - - ret = uart_set_options(&up->port, co, baud, parity, bits, flow); - - return ret; -} - -static struct console serial_hsu_console = { - .name = "ttyMFD", - .write = serial_hsu_console_write, - .device = uart_console_device, - .setup = serial_hsu_console_setup, - .flags = CON_PRINTBUFFER, - .index = 2, - .data = &serial_hsu_reg, -}; -#endif - -struct uart_ops serial_hsu_pops = { - .tx_empty = serial_hsu_tx_empty, - .set_mctrl = serial_hsu_set_mctrl, - .get_mctrl = serial_hsu_get_mctrl, - .stop_tx = serial_hsu_stop_tx, - .start_tx = serial_hsu_start_tx, - .stop_rx = serial_hsu_stop_rx, - .enable_ms = serial_hsu_enable_ms, - .break_ctl = serial_hsu_break_ctl, - .startup = serial_hsu_startup, - .shutdown = serial_hsu_shutdown, - .set_termios = serial_hsu_set_termios, - .pm = serial_hsu_pm, - .type = serial_hsu_type, - .release_port = serial_hsu_release_port, - .request_port = serial_hsu_request_port, - .config_port = serial_hsu_config_port, - .verify_port = serial_hsu_verify_port, -}; - -static struct uart_driver serial_hsu_reg = { - .owner = THIS_MODULE, - .driver_name = "MFD serial", - .dev_name = "ttyMFD", - .major = TTY_MAJOR, - .minor = 128, - .nr = 3, -}; - -#ifdef CONFIG_PM -static int serial_hsu_suspend(struct pci_dev *pdev, pm_message_t state) -{ - void *priv = pci_get_drvdata(pdev); - struct uart_hsu_port *up; - - /* Make sure this is not the internal dma controller */ - if (priv && (pdev->device != 0x081E)) { - up = priv; - uart_suspend_port(&serial_hsu_reg, &up->port); - } - - pci_save_state(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); - return 0; -} - -static int serial_hsu_resume(struct pci_dev *pdev) -{ - void *priv = pci_get_drvdata(pdev); - struct uart_hsu_port *up; - int ret; - - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - - ret = pci_enable_device(pdev); - if (ret) - dev_warn(&pdev->dev, - "HSU: can't re-enable device, try to continue\n"); - - if (priv && (pdev->device != 0x081E)) { - up = priv; - uart_resume_port(&serial_hsu_reg, &up->port); - } - return 0; -} -#else -#define serial_hsu_suspend NULL -#define serial_hsu_resume NULL -#endif - -/* temp global pointer before we settle down on using one or four PCI dev */ -static struct hsu_port *phsu; - -static int serial_hsu_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct uart_hsu_port *uport; - int index, ret; - - printk(KERN_INFO "HSU: found PCI Serial controller(ID: %04x:%04x)\n", - pdev->vendor, pdev->device); - - switch (pdev->device) { - case 0x081B: - index = 0; - break; - case 0x081C: - index = 1; - break; - case 0x081D: - index = 2; - break; - case 0x081E: - /* internal DMA controller */ - index = 3; - break; - default: - dev_err(&pdev->dev, "HSU: out of index!"); - return -ENODEV; - } - - ret = pci_enable_device(pdev); - if (ret) - return ret; - - if (index == 3) { - /* DMA controller */ - ret = request_irq(pdev->irq, dma_irq, 0, "hsu_dma", phsu); - if (ret) { - dev_err(&pdev->dev, "can not get IRQ\n"); - goto err_disable; - } - pci_set_drvdata(pdev, phsu); - } else { - /* UART port 0~2 */ - uport = &phsu->port[index]; - uport->port.irq = pdev->irq; - uport->port.dev = &pdev->dev; - uport->dev = &pdev->dev; - - ret = request_irq(pdev->irq, port_irq, 0, uport->name, uport); - if (ret) { - dev_err(&pdev->dev, "can not get IRQ\n"); - goto err_disable; - } - uart_add_one_port(&serial_hsu_reg, &uport->port); - -#ifdef CONFIG_SERIAL_MFD_HSU_CONSOLE - if (index == 2) { - register_console(&serial_hsu_console); - uport->port.cons = &serial_hsu_console; - } -#endif - pci_set_drvdata(pdev, uport); - } - - return 0; - -err_disable: - pci_disable_device(pdev); - return ret; -} - -static void hsu_dma_rx_timeout(unsigned long data) -{ - struct hsu_dma_chan *chan = (void *)data; - struct uart_hsu_port *up = chan->uport; - struct hsu_dma_buffer *dbuf = &up->rxbuf; - int count = 0; - unsigned long flags; - - spin_lock_irqsave(&up->port.lock, flags); - - count = chan_readl(chan, HSU_CH_D0SAR) - dbuf->dma_addr; - - if (!count) { - mod_timer(&chan->rx_timer, jiffies + HSU_DMA_TIMEOUT_CHECK_FREQ); - goto exit; - } - - hsu_dma_rx(up, 0); -exit: - spin_unlock_irqrestore(&up->port.lock, flags); -} - -static void hsu_global_init(void) -{ - struct hsu_port *hsu; - struct uart_hsu_port *uport; - struct hsu_dma_chan *dchan; - int i, ret; - - hsu = kzalloc(sizeof(struct hsu_port), GFP_KERNEL); - if (!hsu) - return; - - /* Get basic io resource and map it */ - hsu->paddr = 0xffa28000; - hsu->iolen = 0x1000; - - if (!(request_mem_region(hsu->paddr, hsu->iolen, "HSU global"))) - pr_warning("HSU: error in request mem region\n"); - - hsu->reg = ioremap_nocache((unsigned long)hsu->paddr, hsu->iolen); - if (!hsu->reg) { - pr_err("HSU: error in ioremap\n"); - ret = -ENOMEM; - goto err_free_region; - } - - /* Initialise the 3 UART ports */ - uport = hsu->port; - for (i = 0; i < 3; i++) { - uport->port.type = PORT_MFD; - uport->port.iotype = UPIO_MEM; - uport->port.mapbase = (resource_size_t)hsu->paddr - + HSU_PORT_REG_OFFSET - + i * HSU_PORT_REG_LENGTH; - uport->port.membase = hsu->reg + HSU_PORT_REG_OFFSET - + i * HSU_PORT_REG_LENGTH; - - sprintf(uport->name, "hsu_port%d", i); - uport->port.fifosize = 64; - uport->port.ops = &serial_hsu_pops; - uport->port.line = i; - uport->port.flags = UPF_IOREMAP; - /* set the scalable maxim support rate to 2746800 bps */ - uport->port.uartclk = 115200 * 24 * 16; - - uport->running = 0; - uport->txc = &hsu->chans[i * 2]; - uport->rxc = &hsu->chans[i * 2 + 1]; - - serial_hsu_ports[i] = uport; - uport->index = i; - uport++; - } - - /* Initialise 6 dma channels */ - dchan = hsu->chans; - for (i = 0; i < 6; i++) { - dchan->id = i; - dchan->dirt = (i & 0x1) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; - dchan->uport = &hsu->port[i/2]; - dchan->reg = hsu->reg + HSU_DMA_CHANS_REG_OFFSET + - i * HSU_DMA_CHANS_REG_LENGTH; - - /* Work around for RX */ - if (dchan->dirt == DMA_FROM_DEVICE) { - init_timer(&dchan->rx_timer); - dchan->rx_timer.function = hsu_dma_rx_timeout; - dchan->rx_timer.data = (unsigned long)dchan; - } - dchan++; - } - - phsu = hsu; - - hsu_debugfs_init(hsu); - return; - -err_free_region: - release_mem_region(hsu->paddr, hsu->iolen); - kfree(hsu); - return; -} - -static void serial_hsu_remove(struct pci_dev *pdev) -{ - struct hsu_port *hsu; - int i; - - hsu = pci_get_drvdata(pdev); - if (!hsu) - return; - - for (i = 0; i < 3; i++) - uart_remove_one_port(&serial_hsu_reg, &hsu->port[i].port); - - pci_set_drvdata(pdev, NULL); - free_irq(hsu->irq, hsu); - pci_disable_device(pdev); -} - -/* First 3 are UART ports, and the 4th is the DMA */ -static const struct pci_device_id pci_ids[] __devinitdata = { - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081B) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081C) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081D) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081E) }, - {}, -}; - -static struct pci_driver hsu_pci_driver = { - .name = "HSU serial", - .id_table = pci_ids, - .probe = serial_hsu_probe, - .remove = __devexit_p(serial_hsu_remove), - .suspend = serial_hsu_suspend, - .resume = serial_hsu_resume, -}; - -static int __init hsu_pci_init(void) -{ - int ret; - - hsu_global_init(); - - ret = uart_register_driver(&serial_hsu_reg); - if (ret) - return ret; - - return pci_register_driver(&hsu_pci_driver); -} - -static void __exit hsu_pci_exit(void) -{ - pci_unregister_driver(&hsu_pci_driver); - uart_unregister_driver(&serial_hsu_reg); - - hsu_debugfs_remove(phsu); - - kfree(phsu); -} - -module_init(hsu_pci_init); -module_exit(hsu_pci_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:medfield-hsu"); diff --git a/trunk/drivers/serial/mrst_max3110.c b/trunk/drivers/serial/mrst_max3110.c deleted file mode 100644 index f6ad1ecbff79..000000000000 --- a/trunk/drivers/serial/mrst_max3110.c +++ /dev/null @@ -1,844 +0,0 @@ -/* - * max3110.c - spi uart protocol driver for Maxim 3110 on Moorestown - * - * Copyright (C) Intel 2008 Feng Tang - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - */ - -/* - * Note: - * 1. From Max3110 spec, the Rx FIFO has 8 words, while the Tx FIFO only has - * 1 word. If SPI master controller doesn't support sclk frequency change, - * then the char need be sent out one by one with some delay - * - * 2. Currently only RX availabe interrrupt is used, no need for waiting TXE - * interrupt for a low speed UART device - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "mrst_max3110.h" - -#define PR_FMT "mrst_max3110: " - -#define UART_TX_NEEDED 1 -#define CON_TX_NEEDED 2 -#define BIT_IRQ_PENDING 3 - -struct uart_max3110 { - struct uart_port port; - struct spi_device *spi; - char *name; - - wait_queue_head_t wq; - struct task_struct *main_thread; - struct task_struct *read_thread; - struct mutex thread_mutex;; - - u32 baud; - u16 cur_conf; - u8 clock; - u8 parity, word_7bits; - - unsigned long uart_flags; - - /* console related */ - struct circ_buf con_xmit; - - /* irq related */ - u16 irq; -}; - -/* global data structure, may need be removed */ -struct uart_max3110 *pmax; -static inline void receive_char(struct uart_max3110 *max, u8 ch); -static void receive_chars(struct uart_max3110 *max, - unsigned char *str, int len); -static int max3110_read_multi(struct uart_max3110 *max, int len, u8 *buf); -static void max3110_console_receive(struct uart_max3110 *max); - -int max3110_write_then_read(struct uart_max3110 *max, - const u8 *txbuf, u8 *rxbuf, unsigned len, int always_fast) -{ - struct spi_device *spi = max->spi; - struct spi_message message; - struct spi_transfer x; - int ret; - - if (!txbuf || !rxbuf) - return -EINVAL; - - spi_message_init(&message); - memset(&x, 0, sizeof x); - x.len = len; - x.tx_buf = txbuf; - x.rx_buf = rxbuf; - spi_message_add_tail(&x, &message); - - if (always_fast) - x.speed_hz = 3125000; - else if (max->baud) - x.speed_hz = max->baud; - - /* Do the i/o */ - ret = spi_sync(spi, &message); - return ret; -} - -/* Write a u16 to the device, and return one u16 read back */ -int max3110_out(struct uart_max3110 *max, const u16 out) -{ - u16 tmp; - int ret; - - ret = max3110_write_then_read(max, (u8 *)&out, (u8 *)&tmp, 2, 1); - if (ret) - return ret; - - /* If some valid data is read back */ - if (tmp & MAX3110_READ_DATA_AVAILABLE) - receive_char(max, (tmp & 0xff)); - - return ret; -} - -#define MAX_READ_LEN 20 -/* - * This is usually used to read data from SPIC RX FIFO, which doesn't - * need any delay like flushing character out. It returns how many - * valide bytes are read back - */ -static int max3110_read_multi(struct uart_max3110 *max, int len, u8 *buf) -{ - u16 out[MAX_READ_LEN], in[MAX_READ_LEN]; - u8 *pbuf, valid_str[MAX_READ_LEN]; - int i, j, bytelen; - - if (len > MAX_READ_LEN) { - pr_err(PR_FMT "read len %d is too large\n", len); - return 0; - } - - bytelen = len * 2; - memset(out, 0, bytelen); - memset(in, 0, bytelen); - - if (max3110_write_then_read(max, (u8 *)out, (u8 *)in, bytelen, 1)) - return 0; - - /* If caller don't provide a buffer, then handle received char */ - pbuf = buf ? buf : valid_str; - - for (i = 0, j = 0; i < len; i++) { - if (in[i] & MAX3110_READ_DATA_AVAILABLE) - pbuf[j++] = (u8)(in[i] & 0xff); - } - - if (j && (pbuf == valid_str)) - receive_chars(max, valid_str, j); - - return j; -} - -static void serial_m3110_con_putchar(struct uart_port *port, int ch) -{ - struct uart_max3110 *max = - container_of(port, struct uart_max3110, port); - struct circ_buf *xmit = &max->con_xmit; - - if (uart_circ_chars_free(xmit)) { - xmit->buf[xmit->head] = (char)ch; - xmit->head = (xmit->head + 1) & (PAGE_SIZE - 1); - } - - - if (!test_and_set_bit(CON_TX_NEEDED, &max->uart_flags)) - wake_up_process(max->main_thread); -} - -/* - * Print a string to the serial port trying not to disturb - * any possible real use of the port... - * - * The console_lock must be held when we get here. - */ -static void serial_m3110_con_write(struct console *co, - const char *s, unsigned int count) -{ - if (!pmax) - return; - - uart_console_write(&pmax->port, s, count, serial_m3110_con_putchar); -} - -static int __init -serial_m3110_con_setup(struct console *co, char *options) -{ - struct uart_max3110 *max = pmax; - int baud = 115200; - int bits = 8; - int parity = 'n'; - int flow = 'n'; - - pr_info(PR_FMT "setting up console\n"); - - if (!max) { - pr_err(PR_FMT "pmax is NULL, return"); - return -ENODEV; - } - - if (options) - uart_parse_options(options, &baud, &parity, &bits, &flow); - - return uart_set_options(&max->port, co, baud, parity, bits, flow); -} - -static struct tty_driver *serial_m3110_con_device(struct console *co, - int *index) -{ - struct uart_driver *p = co->data; - *index = co->index; - return p->tty_driver; -} - -static struct uart_driver serial_m3110_reg; -static struct console serial_m3110_console = { - .name = "ttyS", - .write = serial_m3110_con_write, - .device = serial_m3110_con_device, - .setup = serial_m3110_con_setup, - .flags = CON_PRINTBUFFER, - .index = -1, - .data = &serial_m3110_reg, -}; - -#define MRST_CONSOLE (&serial_m3110_console) - -static unsigned int serial_m3110_tx_empty(struct uart_port *port) -{ - return 1; -} - -static void serial_m3110_stop_tx(struct uart_port *port) -{ - return; -} - -/* stop_rx will be called in spin_lock env */ -static void serial_m3110_stop_rx(struct uart_port *port) -{ - return; -} - -#define WORDS_PER_XFER 128 -static inline void send_circ_buf(struct uart_max3110 *max, - struct circ_buf *xmit) -{ - int len, left = 0; - u16 obuf[WORDS_PER_XFER], ibuf[WORDS_PER_XFER]; - u8 valid_str[WORDS_PER_XFER]; - int i, j; - - while (!uart_circ_empty(xmit)) { - left = uart_circ_chars_pending(xmit); - while (left) { - len = (left >= WORDS_PER_XFER) ? WORDS_PER_XFER : left; - - memset(obuf, 0, len * 2); - memset(ibuf, 0, len * 2); - for (i = 0; i < len; i++) { - obuf[i] = (u8)xmit->buf[xmit->tail] | WD_TAG; - xmit->tail = (xmit->tail + 1) & - (UART_XMIT_SIZE - 1); - } - max3110_write_then_read(max, (u8 *)obuf, - (u8 *)ibuf, len * 2, 0); - - for (i = 0, j = 0; i < len; i++) { - if (ibuf[i] & MAX3110_READ_DATA_AVAILABLE) - valid_str[j++] = (u8)(ibuf[i] & 0xff); - } - - if (j) - receive_chars(max, valid_str, j); - - max->port.icount.tx += len; - left -= len; - } - } -} - -static void transmit_char(struct uart_max3110 *max) -{ - struct uart_port *port = &max->port; - struct circ_buf *xmit = &port->state->xmit; - - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) - return; - - send_circ_buf(max, xmit); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); - - if (uart_circ_empty(xmit)) - serial_m3110_stop_tx(port); -} - -/* This will be called by uart_write() and tty_write, can't - * go to sleep */ -static void serial_m3110_start_tx(struct uart_port *port) -{ - struct uart_max3110 *max = - container_of(port, struct uart_max3110, port); - - if (!test_and_set_bit(UART_TX_NEEDED, &max->uart_flags)) - wake_up_process(max->main_thread); -} - -static void receive_chars(struct uart_max3110 *max, unsigned char *str, int len) -{ - struct uart_port *port = &max->port; - struct tty_struct *tty; - int usable; - - /* If uart is not opened, just return */ - if (!port->state) - return; - - tty = port->state->port.tty; - if (!tty) - return; /* receive some char before the tty is opened */ - - while (len) { - usable = tty_buffer_request_room(tty, len); - if (usable) { - tty_insert_flip_string(tty, str, usable); - str += usable; - port->icount.rx += usable; - tty_flip_buffer_push(tty); - } - len -= usable; - } -} - -static inline void receive_char(struct uart_max3110 *max, u8 ch) -{ - receive_chars(max, &ch, 1); -} - -static void max3110_console_receive(struct uart_max3110 *max) -{ - int loop = 1, num, total = 0; - u8 recv_buf[512], *pbuf; - - pbuf = recv_buf; - do { - num = max3110_read_multi(max, 8, pbuf); - - if (num) { - loop = 10; - pbuf += num; - total += num; - - if (total >= 500) { - receive_chars(max, recv_buf, total); - pbuf = recv_buf; - total = 0; - } - } - } while (--loop); - - if (total) - receive_chars(max, recv_buf, total); -} - -static int max3110_main_thread(void *_max) -{ - struct uart_max3110 *max = _max; - wait_queue_head_t *wq = &max->wq; - int ret = 0; - struct circ_buf *xmit = &max->con_xmit; - - init_waitqueue_head(wq); - pr_info(PR_FMT "start main thread\n"); - - do { - wait_event_interruptible(*wq, max->uart_flags || kthread_should_stop()); - - mutex_lock(&max->thread_mutex); - - if (test_and_clear_bit(BIT_IRQ_PENDING, &max->uart_flags)) - max3110_console_receive(max); - - /* first handle console output */ - if (test_and_clear_bit(CON_TX_NEEDED, &max->uart_flags)) - send_circ_buf(max, xmit); - - /* handle uart output */ - if (test_and_clear_bit(UART_TX_NEEDED, &max->uart_flags)) - transmit_char(max); - - mutex_unlock(&max->thread_mutex); - - } while (!kthread_should_stop()); - - return ret; -} - -#ifdef CONFIG_MRST_MAX3110_IRQ -static irqreturn_t serial_m3110_irq(int irq, void *dev_id) -{ - struct uart_max3110 *max = dev_id; - - /* max3110's irq is a falling edge, not level triggered, - * so no need to disable the irq */ - if (!test_and_set_bit(BIT_IRQ_PENDING, &max->uart_flags)) - wake_up_process(max->main_thread); - - return IRQ_HANDLED; -} -#else -/* if don't use RX IRQ, then need a thread to polling read */ -static int max3110_read_thread(void *_max) -{ - struct uart_max3110 *max = _max; - - pr_info(PR_FMT "start read thread\n"); - do { - mutex_lock(&max->thread_mutex); - max3110_console_receive(max); - mutex_unlock(&max->thread_mutex); - - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ / 20); - } while (!kthread_should_stop()); - - return 0; -} -#endif - -static int serial_m3110_startup(struct uart_port *port) -{ - struct uart_max3110 *max = - container_of(port, struct uart_max3110, port); - u16 config = 0; - int ret = 0; - - if (port->line != 0) - pr_err(PR_FMT "uart port startup failed\n"); - - /* firstly disable all IRQ and config it to 115200, 8n1 */ - config = WC_TAG | WC_FIFO_ENABLE - | WC_1_STOPBITS - | WC_8BIT_WORD - | WC_BAUD_DR2; - ret = max3110_out(max, config); - - /* as we use thread to handle tx/rx, need set low latency */ - port->state->port.tty->low_latency = 1; - -#ifdef CONFIG_MRST_MAX3110_IRQ - ret = request_irq(max->irq, serial_m3110_irq, - IRQ_TYPE_EDGE_FALLING, "max3110", max); - if (ret) - return ret; - - /* enable RX IRQ only */ - config |= WC_RXA_IRQ_ENABLE; - max3110_out(max, config); -#else - /* if IRQ is disabled, start a read thread for input data */ - max->read_thread = - kthread_run(max3110_read_thread, max, "max3110_read"); -#endif - - max->cur_conf = config; - return 0; -} - -static void serial_m3110_shutdown(struct uart_port *port) -{ - struct uart_max3110 *max = - container_of(port, struct uart_max3110, port); - u16 config; - - if (max->read_thread) { - kthread_stop(max->read_thread); - max->read_thread = NULL; - } - -#ifdef CONFIG_MRST_MAX3110_IRQ - free_irq(max->irq, max); -#endif - - /* Disable interrupts from this port */ - config = WC_TAG | WC_SW_SHDI; - max3110_out(max, config); -} - -static void serial_m3110_release_port(struct uart_port *port) -{ -} - -static int serial_m3110_request_port(struct uart_port *port) -{ - return 0; -} - -static void serial_m3110_config_port(struct uart_port *port, int flags) -{ - /* give it fake type */ - port->type = PORT_PXA; -} - -static int -serial_m3110_verify_port(struct uart_port *port, struct serial_struct *ser) -{ - /* we don't want the core code to modify any port params */ - return -EINVAL; -} - - -static const char *serial_m3110_type(struct uart_port *port) -{ - struct uart_max3110 *max = - container_of(port, struct uart_max3110, port); - return max->name; -} - -static void -serial_m3110_set_termios(struct uart_port *port, struct ktermios *termios, - struct ktermios *old) -{ - struct uart_max3110 *max = - container_of(port, struct uart_max3110, port); - unsigned char cval; - unsigned int baud, parity = 0; - int clk_div = -1; - u16 new_conf = max->cur_conf; - - switch (termios->c_cflag & CSIZE) { - case CS7: - cval = UART_LCR_WLEN7; - new_conf |= WC_7BIT_WORD; - break; - default: - case CS8: - cval = UART_LCR_WLEN8; - new_conf |= WC_8BIT_WORD; - break; - } - - baud = uart_get_baud_rate(port, termios, old, 0, 230400); - - /* first calc the div for 1.8MHZ clock case */ - switch (baud) { - case 300: - clk_div = WC_BAUD_DR384; - break; - case 600: - clk_div = WC_BAUD_DR192; - break; - case 1200: - clk_div = WC_BAUD_DR96; - break; - case 2400: - clk_div = WC_BAUD_DR48; - break; - case 4800: - clk_div = WC_BAUD_DR24; - break; - case 9600: - clk_div = WC_BAUD_DR12; - break; - case 19200: - clk_div = WC_BAUD_DR6; - break; - case 38400: - clk_div = WC_BAUD_DR3; - break; - case 57600: - clk_div = WC_BAUD_DR2; - break; - case 115200: - clk_div = WC_BAUD_DR1; - break; - case 230400: - if (max->clock & MAX3110_HIGH_CLK) - break; - default: - /* pick the previous baud rate */ - baud = max->baud; - clk_div = max->cur_conf & WC_BAUD_DIV_MASK; - tty_termios_encode_baud_rate(termios, baud, baud); - } - - if (max->clock & MAX3110_HIGH_CLK) { - clk_div += 1; - /* high clk version max3110 doesn't support B300 */ - if (baud == 300) - baud = 600; - if (baud == 230400) - clk_div = WC_BAUD_DR1; - tty_termios_encode_baud_rate(termios, baud, baud); - } - - new_conf = (new_conf & ~WC_BAUD_DIV_MASK) | clk_div; - if (termios->c_cflag & CSTOPB) - new_conf |= WC_2_STOPBITS; - else - new_conf &= ~WC_2_STOPBITS; - - if (termios->c_cflag & PARENB) { - new_conf |= WC_PARITY_ENABLE; - parity |= UART_LCR_PARITY; - } else - new_conf &= ~WC_PARITY_ENABLE; - - if (!(termios->c_cflag & PARODD)) - parity |= UART_LCR_EPAR; - max->parity = parity; - - uart_update_timeout(port, termios->c_cflag, baud); - - new_conf |= WC_TAG; - if (new_conf != max->cur_conf) { - max3110_out(max, new_conf); - max->cur_conf = new_conf; - max->baud = baud; - } -} - -/* don't handle hw handshaking */ -static unsigned int serial_m3110_get_mctrl(struct uart_port *port) -{ - return TIOCM_DSR | TIOCM_CAR | TIOCM_DSR; -} - -static void serial_m3110_set_mctrl(struct uart_port *port, unsigned int mctrl) -{ -} - -static void serial_m3110_break_ctl(struct uart_port *port, int break_state) -{ -} - -static void serial_m3110_pm(struct uart_port *port, unsigned int state, - unsigned int oldstate) -{ -} - -static void serial_m3110_enable_ms(struct uart_port *port) -{ -} - -struct uart_ops serial_m3110_ops = { - .tx_empty = serial_m3110_tx_empty, - .set_mctrl = serial_m3110_set_mctrl, - .get_mctrl = serial_m3110_get_mctrl, - .stop_tx = serial_m3110_stop_tx, - .start_tx = serial_m3110_start_tx, - .stop_rx = serial_m3110_stop_rx, - .enable_ms = serial_m3110_enable_ms, - .break_ctl = serial_m3110_break_ctl, - .startup = serial_m3110_startup, - .shutdown = serial_m3110_shutdown, - .set_termios = serial_m3110_set_termios, /* must have */ - .pm = serial_m3110_pm, - .type = serial_m3110_type, - .release_port = serial_m3110_release_port, - .request_port = serial_m3110_request_port, - .config_port = serial_m3110_config_port, - .verify_port = serial_m3110_verify_port, -}; - -static struct uart_driver serial_m3110_reg = { - .owner = THIS_MODULE, - .driver_name = "MRST serial", - .dev_name = "ttyS", - .major = TTY_MAJOR, - .minor = 64, - .nr = 1, - .cons = MRST_CONSOLE, -}; - -static int serial_m3110_suspend(struct spi_device *spi, pm_message_t state) -{ - return 0; -} - -static int serial_m3110_resume(struct spi_device *spi) -{ - return 0; -} - -static struct dw_spi_chip spi0_uart = { - .poll_mode = 1, - .enable_dma = 0, - .type = SPI_FRF_SPI, -}; - -static int serial_m3110_probe(struct spi_device *spi) -{ - struct uart_max3110 *max; - int ret; - unsigned char *buffer; - u16 res; - max = kzalloc(sizeof(*max), GFP_KERNEL); - if (!max) - return -ENOMEM; - - /* set spi info */ - spi->mode = SPI_MODE_0; - spi->bits_per_word = 16; - max->clock = MAX3110_HIGH_CLK; - spi->controller_data = &spi0_uart; - - spi_setup(spi); - - max->port.type = PORT_PXA; /* need apply for a max3110 type */ - max->port.fifosize = 2; /* only have 16b buffer */ - max->port.ops = &serial_m3110_ops; - max->port.line = 0; - max->port.dev = &spi->dev; - max->port.uartclk = 115200; - - max->spi = spi; - max->name = spi->modalias; /* use spi name as the name */ - max->irq = (u16)spi->irq; - - mutex_init(&max->thread_mutex); - - max->word_7bits = 0; - max->parity = 0; - max->baud = 0; - - max->cur_conf = 0; - max->uart_flags = 0; - - /* Check if reading configuration register returns something sane */ - - res = RC_TAG; - ret = max3110_write_then_read(max, (u8 *)&res, (u8 *)&res, 2, 0); - if (ret < 0 || res == 0 || res == 0xffff) { - printk(KERN_ERR "MAX3111 deemed not present (conf reg %04x)", - res); - ret = -ENODEV; - goto err_get_page; - } - buffer = (unsigned char *)__get_free_page(GFP_KERNEL); - if (!buffer) { - ret = -ENOMEM; - goto err_get_page; - } - max->con_xmit.buf = (unsigned char *)buffer; - max->con_xmit.head = max->con_xmit.tail = 0; - - max->main_thread = kthread_run(max3110_main_thread, - max, "max3110_main"); - if (IS_ERR(max->main_thread)) { - ret = PTR_ERR(max->main_thread); - goto err_kthread; - } - - pmax = max; - /* give membase a psudo value to pass serial_core's check */ - max->port.membase = (void *)0xff110000; - uart_add_one_port(&serial_m3110_reg, &max->port); - - return 0; - -err_kthread: - free_page((unsigned long)buffer); -err_get_page: - pmax = NULL; - kfree(max); - return ret; -} - -static int max3110_remove(struct spi_device *dev) -{ - struct uart_max3110 *max = pmax; - - if (!pmax) - return 0; - - pmax = NULL; - uart_remove_one_port(&serial_m3110_reg, &max->port); - - free_page((unsigned long)max->con_xmit.buf); - - if (max->main_thread) - kthread_stop(max->main_thread); - - kfree(max); - return 0; -} - -static struct spi_driver uart_max3110_driver = { - .driver = { - .name = "spi_max3111", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - .probe = serial_m3110_probe, - .remove = __devexit_p(max3110_remove), - .suspend = serial_m3110_suspend, - .resume = serial_m3110_resume, -}; - - -int __init serial_m3110_init(void) -{ - int ret = 0; - - ret = uart_register_driver(&serial_m3110_reg); - if (ret) - return ret; - - ret = spi_register_driver(&uart_max3110_driver); - if (ret) - uart_unregister_driver(&serial_m3110_reg); - - return ret; -} - -void __exit serial_m3110_exit(void) -{ - spi_unregister_driver(&uart_max3110_driver); - uart_unregister_driver(&serial_m3110_reg); -} - -module_init(serial_m3110_init); -module_exit(serial_m3110_exit); - -MODULE_LICENSE("GPL"); -MODULE_ALIAS("max3110-uart"); diff --git a/trunk/drivers/serial/mrst_max3110.h b/trunk/drivers/serial/mrst_max3110.h deleted file mode 100644 index 363478acb2c3..000000000000 --- a/trunk/drivers/serial/mrst_max3110.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef _MRST_MAX3110_H -#define _MRST_MAX3110_H - -#define MAX3110_HIGH_CLK 0x1 /* 3.6864 MHZ */ -#define MAX3110_LOW_CLK 0x0 /* 1.8432 MHZ */ - -/* status bits for all 4 MAX3110 operate modes */ -#define MAX3110_READ_DATA_AVAILABLE (1 << 15) -#define MAX3110_WRITE_BUF_EMPTY (1 << 14) - -#define WC_TAG (3 << 14) -#define RC_TAG (1 << 14) -#define WD_TAG (2 << 14) -#define RD_TAG (0 << 14) - -/* bits def for write configuration */ -#define WC_FIFO_ENABLE_MASK (1 << 13) -#define WC_FIFO_ENABLE (0 << 13) - -#define WC_SW_SHDI (1 << 12) - -#define WC_IRQ_MASK (0xF << 8) -#define WC_TXE_IRQ_ENABLE (1 << 11) /* TX empty irq */ -#define WC_RXA_IRQ_ENABLE (1 << 10) /* RX availabe irq */ -#define WC_PAR_HIGH_IRQ_ENABLE (1 << 9) -#define WC_REC_ACT_IRQ_ENABLE (1 << 8) - -#define WC_IRDA_ENABLE (1 << 7) - -#define WC_STOPBITS_MASK (1 << 6) -#define WC_2_STOPBITS (1 << 6) -#define WC_1_STOPBITS (0 << 6) - -#define WC_PARITY_ENABLE_MASK (1 << 5) -#define WC_PARITY_ENABLE (1 << 5) - -#define WC_WORDLEN_MASK (1 << 4) -#define WC_7BIT_WORD (1 << 4) -#define WC_8BIT_WORD (0 << 4) - -#define WC_BAUD_DIV_MASK (0xF) -#define WC_BAUD_DR1 (0x0) -#define WC_BAUD_DR2 (0x1) -#define WC_BAUD_DR4 (0x2) -#define WC_BAUD_DR8 (0x3) -#define WC_BAUD_DR16 (0x4) -#define WC_BAUD_DR32 (0x5) -#define WC_BAUD_DR64 (0x6) -#define WC_BAUD_DR128 (0x7) -#define WC_BAUD_DR3 (0x8) -#define WC_BAUD_DR6 (0x9) -#define WC_BAUD_DR12 (0xA) -#define WC_BAUD_DR24 (0xB) -#define WC_BAUD_DR48 (0xC) -#define WC_BAUD_DR96 (0xD) -#define WC_BAUD_DR192 (0xE) -#define WC_BAUD_DR384 (0xF) - -#endif diff --git a/trunk/drivers/serial/serial_core.c b/trunk/drivers/serial/serial_core.c index cd8511298bcb..7f2830709512 100644 --- a/trunk/drivers/serial/serial_core.c +++ b/trunk/drivers/serial/serial_core.c @@ -58,9 +58,9 @@ static struct lock_class_key port_lock_key; #define uart_console(port) (0) #endif -static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, +static void uart_change_speed(struct uart_state *state, struct ktermios *old_termios); -static void __uart_wait_until_sent(struct uart_port *port, int timeout); +static void uart_wait_until_sent(struct tty_struct *tty, int timeout); static void uart_change_pm(struct uart_state *state, int pm_state); /* @@ -137,7 +137,7 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear) * Startup the port. This will be called once per open. All calls * will be serialised by the per-port mutex. */ -static int uart_startup(struct tty_struct *tty, struct uart_state *state, int init_hw) +static int uart_startup(struct uart_state *state, int init_hw) { struct uart_port *uport = state->uart_port; struct tty_port *port = &state->port; @@ -152,7 +152,7 @@ static int uart_startup(struct tty_struct *tty, struct uart_state *state, int in * once we have successfully opened the port. Also set * up the tty->alt_speed kludge */ - set_bit(TTY_IO_ERROR, &tty->flags); + set_bit(TTY_IO_ERROR, &port->tty->flags); if (uport->type == PORT_UNKNOWN) return 0; @@ -177,26 +177,26 @@ static int uart_startup(struct tty_struct *tty, struct uart_state *state, int in /* * Initialise the hardware port settings. */ - uart_change_speed(tty, state, NULL); + uart_change_speed(state, NULL); /* * Setup the RTS and DTR signals once the * port is open and ready to respond. */ - if (tty->termios->c_cflag & CBAUD) + if (port->tty->termios->c_cflag & CBAUD) uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR); } if (port->flags & ASYNC_CTS_FLOW) { spin_lock_irq(&uport->lock); if (!(uport->ops->get_mctrl(uport) & TIOCM_CTS)) - tty->hw_stopped = 1; + port->tty->hw_stopped = 1; spin_unlock_irq(&uport->lock); } set_bit(ASYNCB_INITIALIZED, &port->flags); - clear_bit(TTY_IO_ERROR, &tty->flags); + clear_bit(TTY_IO_ERROR, &port->tty->flags); } if (retval && capable(CAP_SYS_ADMIN)) @@ -210,10 +210,11 @@ static int uart_startup(struct tty_struct *tty, struct uart_state *state, int in * DTR is dropped if the hangup on close termio flag is on. Calls to * uart_shutdown are serialised by the per-port semaphore. */ -static void uart_shutdown(struct tty_struct *tty, struct uart_state *state) +static void uart_shutdown(struct uart_state *state) { struct uart_port *uport = state->uart_port; struct tty_port *port = &state->port; + struct tty_struct *tty = port->tty; /* * Set the TTY IO error marker @@ -429,10 +430,11 @@ uart_get_divisor(struct uart_port *port, unsigned int baud) EXPORT_SYMBOL(uart_get_divisor); /* FIXME: Consistent locking policy */ -static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, - struct ktermios *old_termios) +static void +uart_change_speed(struct uart_state *state, struct ktermios *old_termios) { struct tty_port *port = &state->port; + struct tty_struct *tty = port->tty; struct uart_port *uport = state->uart_port; struct ktermios *termios; @@ -461,8 +463,8 @@ static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, uport->ops->set_termios(uport, termios, old_termios); } -static inline int __uart_put_char(struct uart_port *port, - struct circ_buf *circ, unsigned char c) +static inline int +__uart_put_char(struct uart_port *port, struct circ_buf *circ, unsigned char c) { unsigned long flags; int ret = 0; @@ -492,8 +494,8 @@ static void uart_flush_chars(struct tty_struct *tty) uart_start(tty); } -static int uart_write(struct tty_struct *tty, - const unsigned char *buf, int count) +static int +uart_write(struct tty_struct *tty, const unsigned char *buf, int count) { struct uart_state *state = tty->driver_data; struct uart_port *port; @@ -673,7 +675,7 @@ static int uart_get_info(struct uart_state *state, return 0; } -static int uart_set_info(struct tty_struct *tty, struct uart_state *state, +static int uart_set_info(struct uart_state *state, struct serial_struct __user *newinfo) { struct serial_struct new_serial; @@ -768,7 +770,7 @@ static int uart_set_info(struct tty_struct *tty, struct uart_state *state, * We need to shutdown the serial port at the old * port/type/irq combination. */ - uart_shutdown(tty, state); + uart_shutdown(state); } if (change_port) { @@ -867,27 +869,25 @@ static int uart_set_info(struct tty_struct *tty, struct uart_state *state, "is deprecated.\n", current->comm, tty_name(port->tty, buf)); } - uart_change_speed(tty, state, NULL); + uart_change_speed(state, NULL); } } else - retval = uart_startup(tty, state, 1); + retval = uart_startup(state, 1); exit: mutex_unlock(&port->mutex); return retval; } -/** - * uart_get_lsr_info - get line status register info - * @tty: tty associated with the UART - * @state: UART being queried - * @value: returned modem value - * - * Note: uart_ioctl protects us against hangups. + +/* + * uart_get_lsr_info - get line status register info. + * Note: uart_ioctl protects us against hangups. */ -static int uart_get_lsr_info(struct tty_struct *tty, - struct uart_state *state, unsigned int __user *value) +static int uart_get_lsr_info(struct uart_state *state, + unsigned int __user *value) { struct uart_port *uport = state->uart_port; + struct tty_port *port = &state->port; unsigned int result; result = uport->ops->tx_empty(uport); @@ -900,7 +900,7 @@ static int uart_get_lsr_info(struct tty_struct *tty, */ if (uport->x_char || ((uart_circ_chars_pending(&state->xmit) > 0) && - !tty->stopped && !tty->hw_stopped)) + !port->tty->stopped && !port->tty->hw_stopped)) result &= ~TIOCSER_TEMT; return put_user(result, value); @@ -961,7 +961,7 @@ static int uart_break_ctl(struct tty_struct *tty, int break_state) return 0; } -static int uart_do_autoconfig(struct tty_struct *tty,struct uart_state *state) +static int uart_do_autoconfig(struct uart_state *state) { struct uart_port *uport = state->uart_port; struct tty_port *port = &state->port; @@ -980,7 +980,7 @@ static int uart_do_autoconfig(struct tty_struct *tty,struct uart_state *state) ret = -EBUSY; if (tty_port_users(port) == 1) { - uart_shutdown(tty, state); + uart_shutdown(state); /* * If we already have a port type configured, @@ -999,7 +999,7 @@ static int uart_do_autoconfig(struct tty_struct *tty,struct uart_state *state) */ uport->ops->config_port(uport, flags); - ret = uart_startup(tty, state, 1); + ret = uart_startup(state, 1); } mutex_unlock(&port->mutex); return ret; @@ -1122,11 +1122,11 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, break; case TIOCSSERIAL: - ret = uart_set_info(tty, state, uarg); + ret = uart_set_info(state, uarg); break; case TIOCSERCONFIG: - ret = uart_do_autoconfig(tty, state); + ret = uart_do_autoconfig(state); break; case TIOCSERGWILD: /* obsolete */ @@ -1172,7 +1172,7 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, */ switch (cmd) { case TIOCSERGETLSR: /* Get line status register */ - ret = uart_get_lsr_info(tty, state, uarg); + ret = uart_get_lsr_info(state, uarg); break; default: { @@ -1194,7 +1194,7 @@ static void uart_set_ldisc(struct tty_struct *tty) struct uart_port *uport = state->uart_port; if (uport->ops->set_ldisc) - uport->ops->set_ldisc(uport, tty->termios->c_line); + uport->ops->set_ldisc(uport); } static void uart_set_termios(struct tty_struct *tty, @@ -1219,7 +1219,7 @@ static void uart_set_termios(struct tty_struct *tty, return; } - uart_change_speed(tty, state, old_termios); + uart_change_speed(state, old_termios); /* Handle transition to B0 status */ if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) @@ -1272,9 +1272,8 @@ static void uart_close(struct tty_struct *tty, struct file *filp) struct uart_state *state = tty->driver_data; struct tty_port *port; struct uart_port *uport; - unsigned long flags; - BUG_ON(!tty_locked()); + BUG_ON(!kernel_locked()); if (!state) return; @@ -1285,12 +1284,9 @@ static void uart_close(struct tty_struct *tty, struct file *filp) pr_debug("uart_close(%d) called\n", uport->line); mutex_lock(&port->mutex); - spin_lock_irqsave(&port->lock, flags); - if (tty_hung_up_p(filp)) { - spin_unlock_irqrestore(&port->lock, flags); + if (tty_hung_up_p(filp)) goto done; - } if ((tty->count == 1) && (port->count != 1)) { /* @@ -1309,10 +1305,8 @@ static void uart_close(struct tty_struct *tty, struct file *filp) tty->name, port->count); port->count = 0; } - if (port->count) { - spin_unlock_irqrestore(&port->lock, flags); + if (port->count) goto done; - } /* * Now we wait for the transmit buffer to clear; and we notify @@ -1320,18 +1314,9 @@ static void uart_close(struct tty_struct *tty, struct file *filp) * setting tty->closing. */ tty->closing = 1; - spin_unlock_irqrestore(&port->lock, flags); - if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) { - /* - * hack: open-coded tty_wait_until_sent to avoid - * recursive tty_lock - */ - long timeout = msecs_to_jiffies(port->closing_wait); - if (wait_event_interruptible_timeout(tty->write_wait, - !tty_chars_in_buffer(tty), timeout) >= 0) - __uart_wait_until_sent(uport, timeout); - } + if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) + tty_wait_until_sent(tty, msecs_to_jiffies(port->closing_wait)); /* * At this point, we stop accepting input. To do this, we @@ -1347,47 +1332,45 @@ static void uart_close(struct tty_struct *tty, struct file *filp) * has completely drained; this is especially * important if there is a transmit FIFO! */ - __uart_wait_until_sent(uport, uport->timeout); + uart_wait_until_sent(tty, uport->timeout); } - uart_shutdown(tty, state); + uart_shutdown(state); uart_flush_buffer(tty); tty_ldisc_flush(tty); - tty_port_tty_set(port, NULL); - spin_lock_irqsave(&port->lock, flags); tty->closing = 0; + tty_port_tty_set(port, NULL); if (port->blocked_open) { - spin_unlock_irqrestore(&port->lock, flags); if (port->close_delay) msleep_interruptible(port->close_delay); - spin_lock_irqsave(&port->lock, flags); } else if (!uart_console(uport)) { - spin_unlock_irqrestore(&port->lock, flags); uart_change_pm(state, 3); - spin_lock_irqsave(&port->lock, flags); } /* * Wake up anyone trying to open this port. */ clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); - spin_unlock_irqrestore(&port->lock, flags); wake_up_interruptible(&port->open_wait); done: mutex_unlock(&port->mutex); } -static void __uart_wait_until_sent(struct uart_port *port, int timeout) +static void uart_wait_until_sent(struct tty_struct *tty, int timeout) { + struct uart_state *state = tty->driver_data; + struct uart_port *port = state->uart_port; unsigned long char_time, expire; if (port->type == PORT_UNKNOWN || port->fifosize == 0) return; + lock_kernel(); + /* * Set the check interval to be 1/5 of the estimated time to * send a single character, and make it at least 1. The check @@ -1433,16 +1416,7 @@ static void __uart_wait_until_sent(struct uart_port *port, int timeout) break; } set_current_state(TASK_RUNNING); /* might not be needed */ -} - -static void uart_wait_until_sent(struct tty_struct *tty, int timeout) -{ - struct uart_state *state = tty->driver_data; - struct uart_port *port = state->uart_port; - - tty_lock(); - __uart_wait_until_sent(port, timeout); - tty_unlock(); + unlock_kernel(); } /* @@ -1455,19 +1429,16 @@ static void uart_hangup(struct tty_struct *tty) { struct uart_state *state = tty->driver_data; struct tty_port *port = &state->port; - unsigned long flags; - BUG_ON(!tty_locked()); + BUG_ON(!kernel_locked()); pr_debug("uart_hangup(%d)\n", state->uart_port->line); mutex_lock(&port->mutex); if (port->flags & ASYNC_NORMAL_ACTIVE) { uart_flush_buffer(tty); - uart_shutdown(tty, state); - spin_lock_irqsave(&port->lock, flags); + uart_shutdown(state); port->count = 0; clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); - spin_unlock_irqrestore(&port->lock, flags); tty_port_tty_set(port, NULL); wake_up_interruptible(&port->open_wait); wake_up_interruptible(&port->delta_msr_wait); @@ -1475,19 +1446,15 @@ static void uart_hangup(struct tty_struct *tty) mutex_unlock(&port->mutex); } -/** - * uart_update_termios - update the terminal hw settings - * @tty: tty associated with UART - * @state: UART to update - * - * Copy across the serial console cflag setting into the termios settings - * for the initial open of the port. This allows continuity between the - * kernel settings, and the settings init adopts when it opens the port - * for the first time. +/* + * Copy across the serial console cflag setting into the termios settings + * for the initial open of the port. This allows continuity between the + * kernel settings, and the settings init adopts when it opens the port + * for the first time. */ -static void uart_update_termios(struct tty_struct *tty, - struct uart_state *state) +static void uart_update_termios(struct uart_state *state) { + struct tty_struct *tty = state->port.tty; struct uart_port *port = state->uart_port; if (uart_console(port) && port->cons->cflag) { @@ -1504,7 +1471,7 @@ static void uart_update_termios(struct tty_struct *tty, /* * Make termios settings take effect. */ - uart_change_speed(tty, state, NULL); + uart_change_speed(state, NULL); /* * And finally enable the RTS and DTR signals. @@ -1514,37 +1481,90 @@ static void uart_update_termios(struct tty_struct *tty, } } -static int uart_carrier_raised(struct tty_port *port) +/* + * Block the open until the port is ready. We must be called with + * the per-port semaphore held. + */ +static int +uart_block_til_ready(struct file *filp, struct uart_state *state) { - struct uart_state *state = container_of(port, struct uart_state, port); + DECLARE_WAITQUEUE(wait, current); struct uart_port *uport = state->uart_port; - int mctrl; - spin_lock_irq(&uport->lock); - uport->ops->enable_ms(uport); - mctrl = uport->ops->get_mctrl(uport); - spin_unlock_irq(&uport->lock); - if (mctrl & TIOCM_CAR) - return 1; - return 0; -} + struct tty_port *port = &state->port; + unsigned int mctrl; -static void uart_dtr_rts(struct tty_port *port, int onoff) -{ - struct uart_state *state = container_of(port, struct uart_state, port); - struct uart_port *uport = state->uart_port; + port->blocked_open++; + port->count--; - if (onoff) { - uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS); + add_wait_queue(&port->open_wait, &wait); + while (1) { + set_current_state(TASK_INTERRUPTIBLE); /* - * If this is the first open to succeed, - * adjust things to suit. + * If we have been hung up, tell userspace/restart open. */ - if (!test_and_set_bit(ASYNCB_NORMAL_ACTIVE, &port->flags)) - uart_update_termios(port->tty, state); + if (tty_hung_up_p(filp) || port->tty == NULL) + break; + + /* + * If the port has been closed, tell userspace/restart open. + */ + if (!(port->flags & ASYNC_INITIALIZED)) + break; + + /* + * If non-blocking mode is set, or CLOCAL mode is set, + * we don't want to wait for the modem status lines to + * indicate that the port is ready. + * + * Also, if the port is not enabled/configured, we want + * to allow the open to succeed here. Note that we will + * have set TTY_IO_ERROR for a non-existant port. + */ + if ((filp->f_flags & O_NONBLOCK) || + (port->tty->termios->c_cflag & CLOCAL) || + (port->tty->flags & (1 << TTY_IO_ERROR))) + break; + + /* + * Set DTR to allow modem to know we're waiting. Do + * not set RTS here - we want to make sure we catch + * the data from the modem. + */ + if (port->tty->termios->c_cflag & CBAUD) + uart_set_mctrl(uport, TIOCM_DTR); + + /* + * and wait for the carrier to indicate that the + * modem is ready for us. + */ + spin_lock_irq(&uport->lock); + uport->ops->enable_ms(uport); + mctrl = uport->ops->get_mctrl(uport); + spin_unlock_irq(&uport->lock); + if (mctrl & TIOCM_CAR) + break; + + mutex_unlock(&port->mutex); + schedule(); + mutex_lock(&port->mutex); + + if (signal_pending(current)) + break; } - else - uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); + set_current_state(TASK_RUNNING); + remove_wait_queue(&port->open_wait, &wait); + + port->count++; + port->blocked_open--; + + if (signal_pending(current)) + return -ERESTARTSYS; + + if (!port->tty || tty_hung_up_p(filp)) + return -EAGAIN; + + return 0; } static struct uart_state *uart_get(struct uart_driver *drv, int line) @@ -1591,7 +1611,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp) struct tty_port *port; int retval, line = tty->index; - BUG_ON(!tty_locked()); + BUG_ON(!kernel_locked()); pr_debug("uart_open(%d) called\n", line); /* @@ -1648,14 +1668,23 @@ static int uart_open(struct tty_struct *tty, struct file *filp) /* * Start up the serial port. */ - retval = uart_startup(tty, state, 0); + retval = uart_startup(state, 0); /* * If we succeeded, wait until the port is ready. */ - mutex_unlock(&port->mutex); if (retval == 0) - retval = tty_port_block_til_ready(port, tty, filp); + retval = uart_block_til_ready(filp, state); + mutex_unlock(&port->mutex); + + /* + * If this is the first open to succeed, adjust things to suit. + */ + if (retval == 0 && !(port->flags & ASYNC_NORMAL_ACTIVE)) { + set_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); + + uart_update_termios(state); + } fail: return retval; @@ -1981,13 +2010,9 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) struct tty_port *port = &state->port; struct device *tty_dev; struct uart_match match = {uport, drv}; - struct tty_struct *tty; mutex_lock(&port->mutex); - /* Must be inside the mutex lock until we convert to tty_port */ - tty = port->tty; - tty_dev = device_find_child(uport->dev, &match, serial_match_port); if (device_may_wakeup(tty_dev)) { enable_irq_wake(uport->irq); @@ -2080,12 +2105,9 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) ops->set_mctrl(uport, 0); spin_unlock_irq(&uport->lock); if (console_suspend_enabled || !uart_console(uport)) { - /* Protected by port mutex for now */ - struct tty_struct *tty = port->tty; ret = ops->startup(uport); if (ret == 0) { - if (tty) - uart_change_speed(tty, state, NULL); + uart_change_speed(state, NULL); spin_lock_irq(&uport->lock); ops->set_mctrl(uport, uport->mctrl); ops->start_tx(uport); @@ -2097,7 +2119,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) * Clear the "initialized" flag so we won't try * to call the low level drivers shutdown method. */ - uart_shutdown(tty, state); + uart_shutdown(state); } } @@ -2290,11 +2312,6 @@ static const struct tty_operations uart_ops = { #endif }; -static const struct tty_port_operations uart_port_ops = { - .carrier_raised = uart_carrier_raised, - .dtr_rts = uart_dtr_rts, -}; - /** * uart_register_driver - register a driver with the uart core layer * @drv: low level driver structure @@ -2351,7 +2368,6 @@ int uart_register_driver(struct uart_driver *drv) struct tty_port *port = &state->port; tty_port_init(port); - port->ops = &uart_port_ops; port->close_delay = 500; /* .5 seconds */ port->closing_wait = 30000; /* 30 seconds */ tasklet_init(&state->tlet, uart_tasklet_action, diff --git a/trunk/drivers/serial/timbuart.c b/trunk/drivers/serial/timbuart.c index 1f36b7eb7351..67ca642713b8 100644 --- a/trunk/drivers/serial/timbuart.c +++ b/trunk/drivers/serial/timbuart.c @@ -423,7 +423,7 @@ static struct uart_driver timbuart_driver = { .nr = 1 }; -static int __devinit timbuart_probe(struct platform_device *dev) +static int timbuart_probe(struct platform_device *dev) { int err, irq; struct timbuart_port *uart; @@ -489,7 +489,7 @@ static int __devinit timbuart_probe(struct platform_device *dev) return err; } -static int __devexit timbuart_remove(struct platform_device *dev) +static int timbuart_remove(struct platform_device *dev) { struct timbuart_port *uart = platform_get_drvdata(dev); @@ -507,7 +507,7 @@ static struct platform_driver timbuart_platform_driver = { .owner = THIS_MODULE, }, .probe = timbuart_probe, - .remove = __devexit_p(timbuart_remove), + .remove = timbuart_remove, }; /*--------------------------------------------------------------------------*/ diff --git a/trunk/drivers/staging/easycap/easycap.h b/trunk/drivers/staging/easycap/easycap.h index f3c827eb0abe..ad836d2d26fe 100644 --- a/trunk/drivers/staging/easycap/easycap.h +++ b/trunk/drivers/staging/easycap/easycap.h @@ -463,12 +463,15 @@ struct data_buffer audio_buffer[]; void easycap_complete(struct urb *); int easycap_open(struct inode *, struct file *); int easycap_release(struct inode *, struct file *); -long easycap_ioctl(struct file *, unsigned int, unsigned long); +int easycap_ioctl(struct inode *, struct file *, \ + unsigned int, unsigned long); /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #if defined(EASYCAP_IS_VIDEODEV_CLIENT) int easycap_open_noinode(struct file *); int easycap_release_noinode(struct file *); +long easycap_ioctl_noinode(struct file *, \ + unsigned int, unsigned long); int videodev_release(struct video_device *); #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ @@ -512,7 +515,8 @@ void easysnd_complete(struct urb *); ssize_t easysnd_read(struct file *, char __user *, size_t, loff_t *); int easysnd_open(struct inode *, struct file *); int easysnd_release(struct inode *, struct file *); -long easysnd_ioctl(struct file *, unsigned int, unsigned long); +int easysnd_ioctl(struct inode *, struct file *, \ + unsigned int, unsigned long); unsigned int easysnd_poll(struct file *, poll_table *); void easysnd_delete(struct kref *); int submit_audio_urbs(struct easycap *); diff --git a/trunk/drivers/staging/easycap/easycap_ioctl.c b/trunk/drivers/staging/easycap/easycap_ioctl.c index 9a42ae02cd5d..276b63dfe27e 100644 --- a/trunk/drivers/staging/easycap/easycap_ioctl.c +++ b/trunk/drivers/staging/easycap/easycap_ioctl.c @@ -25,7 +25,6 @@ */ /*****************************************************************************/ -#include #include "easycap.h" #include "easycap_debug.h" #include "easycap_standard.h" @@ -774,10 +773,19 @@ while (0xFFFFFFFF != easycap_control[i1].id) { SAY("WARNING: failed to adjust mute: control not found\n"); return -ENOENT; } - +/****************************************************************************/ +/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#if defined(EASYCAP_IS_VIDEODEV_CLIENT) +long +easycap_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg)\ + { + return easycap_ioctl((struct inode *)NULL, file, cmd, arg); +} +#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*--------------------------------------------------------------------------*/ -static int easycap_ioctl_bkl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +int easycap_ioctl(struct inode *inode, struct file *file, \ + unsigned int cmd, unsigned long arg) { static struct easycap *peasycap; static struct usb_device *p; @@ -1948,22 +1956,19 @@ default: { } return 0; } - -long easycap_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +/****************************************************************************/ +/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#if defined(EASYCAP_IS_VIDEODEV_CLIENT) +long +easysnd_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) { - struct inode *inode = file->f_dentry->d_inode; - long ret; - - lock_kernel(); - ret = easycap_ioctl_bkl(inode, file, cmd, arg); - unlock_kernel(); - - return ret; + return easysnd_ioctl((struct inode *)NULL, file, cmd, arg); } - +#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*--------------------------------------------------------------------------*/ -static int easysnd_ioctl_bkl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +int easysnd_ioctl(struct inode *inode, struct file *file, \ + unsigned int cmd, unsigned long arg) { struct easycap *peasycap; struct usb_device *p; @@ -2153,19 +2158,6 @@ default: { } return 0; } - -long easysnd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct inode *inode = file->f_dentry->d_inode; - long ret; - - lock_kernel(); - ret = easysnd_ioctl_bkl(inode, file, cmd, arg); - unlock_kernel(); - - return ret; -} - /*****************************************************************************/ int explain_ioctl(__u32 wot) { diff --git a/trunk/drivers/staging/easycap/easycap_main.c b/trunk/drivers/staging/easycap/easycap_main.c index 5a4bbd9b453f..09c194ce10a3 100644 --- a/trunk/drivers/staging/easycap/easycap_main.c +++ b/trunk/drivers/staging/easycap/easycap_main.c @@ -60,13 +60,13 @@ struct usb_driver easycap_usb_driver = { */ /*---------------------------------------------------------------------------*/ const struct file_operations easycap_fops = { - .owner = THIS_MODULE, - .open = easycap_open, - .release = easycap_release, - .unlocked_ioctl = easycap_ioctl, - .poll = easycap_poll, - .mmap = easycap_mmap, - .llseek = no_llseek, +.owner = THIS_MODULE, +.open = easycap_open, +.release = easycap_release, +.ioctl = easycap_ioctl, +.poll = easycap_poll, +.mmap = easycap_mmap, +.llseek = no_llseek, }; struct vm_operations_struct easycap_vm_ops = { .open = easycap_vma_open, @@ -83,12 +83,12 @@ struct usb_class_driver easycap_class = { #if defined(EASYCAP_IS_VIDEODEV_CLIENT) #if defined(EASYCAP_NEEDS_V4L2_FOPS) const struct v4l2_file_operations v4l2_fops = { - .owner = THIS_MODULE, - .open = easycap_open_noinode, - .release = easycap_release_noinode, - .unlocked_ioctl = easycap_ioctl, - .poll = easycap_poll, - .mmap = easycap_mmap, +.owner = THIS_MODULE, +.open = easycap_open_noinode, +.release = easycap_release_noinode, +.ioctl = easycap_ioctl_noinode, +.poll = easycap_poll, +.mmap = easycap_mmap, }; #endif /*EASYCAP_NEEDS_V4L2_FOPS*/ int video_device_many /*=0*/; @@ -102,12 +102,12 @@ struct video_device *pvideo_array[VIDEO_DEVICE_MANY], *pvideo_device; */ /*--------------------------------------------------------------------------*/ const struct file_operations easysnd_fops = { - .owner = THIS_MODULE, - .open = easysnd_open, - .release = easysnd_release, - .unlocked_ioctl = easysnd_ioctl, - .read = easysnd_read, - .llseek = no_llseek, +.owner = THIS_MODULE, +.open = easysnd_open, +.release = easysnd_release, +.ioctl = easysnd_ioctl, +.read = easysnd_read, +.llseek = no_llseek, }; struct usb_class_driver easysnd_class = { .name = "usb/easysnd%d", diff --git a/trunk/drivers/usb/class/cdc-acm.c b/trunk/drivers/usb/class/cdc-acm.c index 1833b3a71515..89d260d6b031 100644 --- a/trunk/drivers/usb/class/cdc-acm.c +++ b/trunk/drivers/usb/class/cdc-acm.c @@ -636,13 +636,19 @@ static void acm_tty_unregister(struct acm *acm) static int acm_tty_chars_in_buffer(struct tty_struct *tty); -static void acm_port_down(struct acm *acm) +static void acm_port_down(struct acm *acm, int drain) { int i, nr = acm->rx_buflimit; mutex_lock(&open_mutex); if (acm->dev) { usb_autopm_get_interface(acm->control); acm_set_control(acm, acm->ctrlout = 0); + /* try letting the last writes drain naturally */ + if (drain) { + wait_event_interruptible_timeout(acm->drain_wait, + (ACM_NW == acm_wb_is_avail(acm)) || !acm->dev, + ACM_CLOSE_TIMEOUT * HZ); + } usb_kill_urb(acm->ctrlurb); for (i = 0; i < ACM_NW; i++) usb_kill_urb(acm->wb[i].urb); @@ -658,7 +664,7 @@ static void acm_tty_hangup(struct tty_struct *tty) { struct acm *acm = tty->driver_data; tty_port_hangup(&acm->port); - acm_port_down(acm); + acm_port_down(acm, 0); } static void acm_tty_close(struct tty_struct *tty, struct file *filp) @@ -679,7 +685,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) mutex_unlock(&open_mutex); return; } - acm_port_down(acm); + acm_port_down(acm, 0); tty_port_close_end(&acm->port, tty); tty_port_tty_set(&acm->port, NULL); } diff --git a/trunk/drivers/usb/core/hcd.c b/trunk/drivers/usb/core/hcd.c index 12742f152f43..caae4625a1f1 100644 --- a/trunk/drivers/usb/core/hcd.c +++ b/trunk/drivers/usb/core/hcd.c @@ -2229,7 +2229,7 @@ int usb_add_hcd(struct usb_hcd *hcd, rhdev->speed = USB_SPEED_SUPER; break; default: - goto err_allocate_root_hub; + goto err_set_rh_speed; } hcd->self.root_hub = rhdev; @@ -2305,16 +2305,29 @@ int usb_add_hcd(struct usb_hcd *hcd, return retval; error_create_attr_group: + if (HC_IS_RUNNING(hcd->state)) + hcd->state = HC_STATE_QUIESCING; + spin_lock_irq(&hcd_root_hub_lock); + hcd->rh_registered = 0; + spin_unlock_irq(&hcd_root_hub_lock); + +#ifdef CONFIG_USB_SUSPEND + cancel_work_sync(&hcd->wakeup_work); +#endif mutex_lock(&usb_bus_list_lock); usb_disconnect(&hcd->self.root_hub); mutex_unlock(&usb_bus_list_lock); err_register_root_hub: hcd->driver->stop(hcd); + hcd->state = HC_STATE_HALT; + hcd->poll_rh = 0; + del_timer_sync(&hcd->rh_timer); err_hcd_driver_start: if (hcd->irq >= 0) free_irq(irqnum, hcd); err_request_irq: err_hcd_driver_setup: +err_set_rh_speed: hcd->self.root_hub = NULL; usb_put_dev(rhdev); err_allocate_root_hub: @@ -2337,6 +2350,8 @@ void usb_remove_hcd(struct usb_hcd *hcd) { dev_info(hcd->self.controller, "remove, state %x\n", hcd->state); + sysfs_remove_group(&hcd->self.root_hub->dev.kobj, &usb_bus_attr_group); + if (HC_IS_RUNNING (hcd->state)) hcd->state = HC_STATE_QUIESCING; @@ -2349,7 +2364,6 @@ void usb_remove_hcd(struct usb_hcd *hcd) cancel_work_sync(&hcd->wakeup_work); #endif - sysfs_remove_group(&hcd->self.root_hub->dev.kobj, &usb_bus_attr_group); mutex_lock(&usb_bus_list_lock); usb_disconnect(&hcd->self.root_hub); mutex_unlock(&usb_bus_list_lock); diff --git a/trunk/drivers/usb/serial/digi_acceleport.c b/trunk/drivers/usb/serial/digi_acceleport.c index b92070c103cd..fd35f73b5721 100644 --- a/trunk/drivers/usb/serial/digi_acceleport.c +++ b/trunk/drivers/usb/serial/digi_acceleport.c @@ -609,10 +609,8 @@ static void digi_wakeup_write_lock(struct work_struct *work) static void digi_wakeup_write(struct usb_serial_port *port) { struct tty_struct *tty = tty_port_tty_get(&port->port); - if (tty) { - tty_wakeup(tty); - tty_kref_put(tty); - } + tty_wakeup(tty); + tty_kref_put(tty); } @@ -1684,7 +1682,7 @@ static int digi_read_inb_callback(struct urb *urb) priv->dp_throttle_restart = 1; /* receive data */ - if (tty && opcode == DIGI_CMD_RECEIVE_DATA) { + if (opcode == DIGI_CMD_RECEIVE_DATA) { /* get flag from port_status */ flag = 0; @@ -1765,12 +1763,10 @@ static int digi_read_oob_callback(struct urb *urb) return -1; tty = tty_port_tty_get(&port->port); - rts = 0; - if (tty) - rts = tty->termios->c_cflag & CRTSCTS; + rts = tty->termios->c_cflag & CRTSCTS; - if (tty && opcode == DIGI_CMD_READ_INPUT_SIGNALS) { + if (opcode == DIGI_CMD_READ_INPUT_SIGNALS) { spin_lock(&priv->dp_port_lock); /* convert from digi flags to termiox flags */ if (val & DIGI_READ_INPUT_SIGNALS_CTS) { diff --git a/trunk/drivers/video/console/fbcon.c b/trunk/drivers/video/console/fbcon.c index 26bf7cbfecc2..3b3f5749af92 100644 --- a/trunk/drivers/video/console/fbcon.c +++ b/trunk/drivers/video/console/fbcon.c @@ -283,8 +283,7 @@ static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info) struct fbcon_ops *ops = info->fbcon_par; return (info->state != FBINFO_STATE_RUNNING || - vc->vc_mode != KD_TEXT || ops->graphics) && - !vt_force_oops_output(vc); + vc->vc_mode != KD_TEXT || ops->graphics); } static inline int get_color(struct vc_data *vc, struct fb_info *info, @@ -1074,7 +1073,6 @@ static void fbcon_init(struct vc_data *vc, int init) if (p->userfont) charcnt = FNTCHARCNT(p->fontdata); - vc->vc_panic_force_write = !!(info->flags & FBINFO_CAN_FORCE_OUTPUT); vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; if (charcnt == 256) { diff --git a/trunk/drivers/video/console/vgacon.c b/trunk/drivers/video/console/vgacon.c index 54e32c513610..182dd6f8aadd 100644 --- a/trunk/drivers/video/console/vgacon.c +++ b/trunk/drivers/video/console/vgacon.c @@ -1108,6 +1108,7 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512) charmap += 4 * cmapsz; #endif + unlock_kernel(); spin_lock_irq(&vga_lock); /* First, the Sequencer */ vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1); @@ -1191,6 +1192,7 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512) vga_wattr(state->vgabase, VGA_AR_ENABLE_DISPLAY, 0); } spin_unlock_irq(&vga_lock); + lock_kernel(); return 0; } diff --git a/trunk/drivers/zorro/proc.c b/trunk/drivers/zorro/proc.c index cafc50454292..3c7046d79654 100644 --- a/trunk/drivers/zorro/proc.c +++ b/trunk/drivers/zorro/proc.c @@ -22,9 +22,8 @@ static loff_t proc_bus_zorro_lseek(struct file *file, loff_t off, int whence) { loff_t new = -1; - struct inode *inode = file->f_path.dentry->d_inode; - mutex_lock(&inode->i_mutex); + lock_kernel(); switch (whence) { case 0: new = off; @@ -36,12 +35,12 @@ proc_bus_zorro_lseek(struct file *file, loff_t off, int whence) new = sizeof(struct ConfigDev) + off; break; } - if (new < 0 || new > sizeof(struct ConfigDev)) - new = -EINVAL; - else - file->f_pos = new; - mutex_unlock(&inode->i_mutex); - return new; + if (new < 0 || new > sizeof(struct ConfigDev)) { + unlock_kernel(); + return -EINVAL; + } + unlock_kernel(); + return (file->f_pos = new); } static ssize_t @@ -68,7 +67,7 @@ proc_bus_zorro_read(struct file *file, char __user *buf, size_t nbytes, loff_t * cd.cd_BoardAddr = (void *)zorro_resource_start(z); cd.cd_BoardSize = zorro_resource_len(z); - if (copy_to_user(buf, (void *)&cd + pos, nbytes)) + if (copy_to_user(buf, &cd, nbytes)) return -EFAULT; *ppos += nbytes; diff --git a/trunk/fs/autofs/root.c b/trunk/fs/autofs/root.c index 11b1ea786d00..9a0520b50663 100644 --- a/trunk/fs/autofs/root.c +++ b/trunk/fs/autofs/root.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include "autofs_i.h" @@ -26,17 +25,13 @@ static int autofs_root_symlink(struct inode *,struct dentry *,const char *); static int autofs_root_unlink(struct inode *,struct dentry *); static int autofs_root_rmdir(struct inode *,struct dentry *); static int autofs_root_mkdir(struct inode *,struct dentry *,int); -static long autofs_root_ioctl(struct file *,unsigned int,unsigned long); -static long autofs_root_compat_ioctl(struct file *,unsigned int,unsigned long); +static int autofs_root_ioctl(struct inode *, struct file *,unsigned int,unsigned long); const struct file_operations autofs_root_operations = { .llseek = generic_file_llseek, .read = generic_read_dir, .readdir = autofs_root_readdir, - .unlocked_ioctl = autofs_root_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = autofs_root_compat_ioctl, -#endif + .ioctl = autofs_root_ioctl, }; const struct inode_operations autofs_root_inode_operations = { @@ -497,25 +492,6 @@ static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode) } /* Get/set timeout ioctl() operation */ -#ifdef CONFIG_COMPAT -static inline int autofs_compat_get_set_timeout(struct autofs_sb_info *sbi, - unsigned int __user *p) -{ - unsigned long ntimeout; - - if (get_user(ntimeout, p) || - put_user(sbi->exp_timeout / HZ, p)) - return -EFAULT; - - if (ntimeout > UINT_MAX/HZ) - sbi->exp_timeout = 0; - else - sbi->exp_timeout = ntimeout * HZ; - - return 0; -} -#endif - static inline int autofs_get_set_timeout(struct autofs_sb_info *sbi, unsigned long __user *p) { @@ -570,7 +546,7 @@ static inline int autofs_expire_run(struct super_block *sb, * ioctl()'s on the root directory is the chief method for the daemon to * generate kernel reactions */ -static int autofs_do_root_ioctl(struct inode *inode, struct file *filp, +static int autofs_root_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb); @@ -595,10 +571,6 @@ static int autofs_do_root_ioctl(struct inode *inode, struct file *filp, return 0; case AUTOFS_IOC_PROTOVER: /* Get protocol version */ return autofs_get_protover(argp); -#ifdef CONFIG_COMPAT - case AUTOFS_IOC_SETTIMEOUT32: - return autofs_compat_get_set_timeout(sbi, argp); -#endif case AUTOFS_IOC_SETTIMEOUT: return autofs_get_set_timeout(sbi, argp); case AUTOFS_IOC_EXPIRE: @@ -607,37 +579,4 @@ static int autofs_do_root_ioctl(struct inode *inode, struct file *filp, default: return -ENOSYS; } - -} - -static long autofs_root_ioctl(struct file *filp, - unsigned int cmd, unsigned long arg) -{ - int ret; - - lock_kernel(); - ret = autofs_do_root_ioctl(filp->f_path.dentry->d_inode, - filp, cmd, arg); - unlock_kernel(); - - return ret; -} - -#ifdef CONFIG_COMPAT -static long autofs_root_compat_ioctl(struct file *filp, - unsigned int cmd, unsigned long arg) -{ - struct inode *inode = filp->f_path.dentry->d_inode; - int ret; - - lock_kernel(); - if (cmd == AUTOFS_IOC_READY || cmd == AUTOFS_IOC_FAIL) - ret = autofs_do_root_ioctl(inode, filp, cmd, arg); - else - ret = autofs_do_root_ioctl(inode, filp, cmd, - (unsigned long)compat_ptr(arg)); - unlock_kernel(); - - return ret; } -#endif diff --git a/trunk/fs/autofs4/root.c b/trunk/fs/autofs4/root.c index 48e056e70fd6..db4117ed7803 100644 --- a/trunk/fs/autofs4/root.c +++ b/trunk/fs/autofs4/root.c @@ -18,9 +18,7 @@ #include #include #include -#include #include - #include "autofs_i.h" static int autofs4_dir_symlink(struct inode *,struct dentry *,const char *); @@ -28,7 +26,6 @@ static int autofs4_dir_unlink(struct inode *,struct dentry *); static int autofs4_dir_rmdir(struct inode *,struct dentry *); static int autofs4_dir_mkdir(struct inode *,struct dentry *,int); static long autofs4_root_ioctl(struct file *,unsigned int,unsigned long); -static long autofs4_root_compat_ioctl(struct file *,unsigned int,unsigned long); static int autofs4_dir_open(struct inode *inode, struct file *file); static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *); static void *autofs4_follow_link(struct dentry *, struct nameidata *); @@ -43,9 +40,6 @@ const struct file_operations autofs4_root_operations = { .readdir = dcache_readdir, .llseek = dcache_dir_lseek, .unlocked_ioctl = autofs4_root_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = autofs4_root_compat_ioctl, -#endif }; const struct file_operations autofs4_dir_operations = { @@ -846,26 +840,6 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode) } /* Get/set timeout ioctl() operation */ -#ifdef CONFIG_COMPAT -static inline int autofs4_compat_get_set_timeout(struct autofs_sb_info *sbi, - compat_ulong_t __user *p) -{ - int rv; - unsigned long ntimeout; - - if ((rv = get_user(ntimeout, p)) || - (rv = put_user(sbi->exp_timeout/HZ, p))) - return rv; - - if (ntimeout > UINT_MAX/HZ) - sbi->exp_timeout = 0; - else - sbi->exp_timeout = ntimeout * HZ; - - return 0; -} -#endif - static inline int autofs4_get_set_timeout(struct autofs_sb_info *sbi, unsigned long __user *p) { @@ -959,10 +933,6 @@ static int autofs4_root_ioctl_unlocked(struct inode *inode, struct file *filp, return autofs4_get_protosubver(sbi, p); case AUTOFS_IOC_SETTIMEOUT: return autofs4_get_set_timeout(sbi, p); -#ifdef CONFIG_COMPAT - case AUTOFS_IOC_SETTIMEOUT32: - return autofs4_compat_get_set_timeout(sbi, p); -#endif case AUTOFS_IOC_ASKUMOUNT: return autofs4_ask_umount(filp->f_path.mnt, p); @@ -991,22 +961,3 @@ static long autofs4_root_ioctl(struct file *filp, return ret; } - -#ifdef CONFIG_COMPAT -static long autofs4_root_compat_ioctl(struct file *filp, - unsigned int cmd, unsigned long arg) -{ - struct inode *inode = filp->f_path.dentry->d_inode; - int ret; - - lock_kernel(); - if (cmd == AUTOFS_IOC_READY || cmd == AUTOFS_IOC_FAIL) - ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, arg); - else - ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, - (unsigned long)compat_ptr(arg)); - unlock_kernel(); - - return ret; -} -#endif diff --git a/trunk/fs/compat_ioctl.c b/trunk/fs/compat_ioctl.c index 70227e0dc01d..63ae85831464 100644 --- a/trunk/fs/compat_ioctl.c +++ b/trunk/fs/compat_ioctl.c @@ -131,6 +131,23 @@ static int w_long(unsigned int fd, unsigned int cmd, return err; } +static int rw_long(unsigned int fd, unsigned int cmd, + compat_ulong_t __user *argp) +{ + mm_segment_t old_fs = get_fs(); + int err; + unsigned long val; + + if(get_user(val, argp)) + return -EFAULT; + set_fs (KERNEL_DS); + err = sys_ioctl(fd, cmd, (unsigned long)&val); + set_fs (old_fs); + if (!err && put_user(val, argp)) + return -EFAULT; + return err; +} + struct compat_video_event { int32_t type; compat_time_t timestamp; @@ -577,6 +594,12 @@ static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, return err; } +static int ioc_settimeout(unsigned int fd, unsigned int cmd, + compat_ulong_t __user *argp) +{ + return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, argp); +} + /* Bluetooth ioctls */ #define HCIUARTSETPROTO _IOW('U', 200, int) #define HCIUARTGETPROTO _IOR('U', 201, int) @@ -946,7 +969,6 @@ COMPATIBLE_IOCTL(TIOCGPGRP) COMPATIBLE_IOCTL(TIOCGPTN) COMPATIBLE_IOCTL(TIOCSPTLCK) COMPATIBLE_IOCTL(TIOCSERGETLSR) -COMPATIBLE_IOCTL(TIOCSIG) #ifdef TCGETS2 COMPATIBLE_IOCTL(TCGETS2) COMPATIBLE_IOCTL(TCSETS2) @@ -1262,6 +1284,13 @@ COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE5) COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS) COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS) COMPATIBLE_IOCTL(OSS_GETVERSION) +/* AUTOFS */ +COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC) +COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER) +COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE) +COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE_MULTI) +COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOSUBVER) +COMPATIBLE_IOCTL(AUTOFS_IOC_ASKUMOUNT) /* Raw devices */ COMPATIBLE_IOCTL(RAW_SETBIND) COMPATIBLE_IOCTL(RAW_GETBIND) @@ -1528,6 +1557,9 @@ static long do_ioctl_trans(int fd, unsigned int cmd, case RAW_GETBIND: return raw_ioctl(fd, cmd, argp); #endif +#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int) + case AUTOFS_IOC_SETTIMEOUT32: + return ioc_settimeout(fd, cmd, argp); /* One SMB ioctl needs translations. */ #define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t) case SMB_IOC_GETMOUNTUID_32: @@ -1582,6 +1614,9 @@ static long do_ioctl_trans(int fd, unsigned int cmd, case KDSKBMETA: case KDSKBLED: case KDSETLED: + /* AUTOFS */ + case AUTOFS_IOC_READY: + case AUTOFS_IOC_FAIL: /* NBD */ case NBD_SET_SOCK: case NBD_SET_BLKSIZE: diff --git a/trunk/fs/ecryptfs/file.c b/trunk/fs/ecryptfs/file.c index 622c95140802..e8fcf4e2ed7d 100644 --- a/trunk/fs/ecryptfs/file.c +++ b/trunk/fs/ecryptfs/file.c @@ -199,7 +199,7 @@ static int ecryptfs_open(struct inode *inode, struct file *file) "the persistent file for the dentry with name " "[%s]; rc = [%d]\n", __func__, ecryptfs_dentry->d_name.name, rc); - goto out_free; + goto out; } } if ((ecryptfs_inode_to_private(inode)->lower_file->f_flags & O_RDONLY) @@ -207,7 +207,7 @@ static int ecryptfs_open(struct inode *inode, struct file *file) rc = -EPERM; printk(KERN_WARNING "%s: Lower persistent file is RO; eCryptfs " "file must hence be opened RO\n", __func__); - goto out_free; + goto out; } ecryptfs_set_file_lower( file, ecryptfs_inode_to_private(inode)->lower_file); @@ -292,40 +292,12 @@ static int ecryptfs_fasync(int fd, struct file *file, int flag) return rc; } -static long -ecryptfs_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct file *lower_file = NULL; - long rc = -ENOTTY; - - if (ecryptfs_file_to_private(file)) - lower_file = ecryptfs_file_to_lower(file); - if (lower_file && lower_file->f_op && lower_file->f_op->unlocked_ioctl) - rc = lower_file->f_op->unlocked_ioctl(lower_file, cmd, arg); - return rc; -} - -#ifdef CONFIG_COMPAT -static long -ecryptfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct file *lower_file = NULL; - long rc = -ENOIOCTLCMD; - - if (ecryptfs_file_to_private(file)) - lower_file = ecryptfs_file_to_lower(file); - if (lower_file && lower_file->f_op && lower_file->f_op->compat_ioctl) - rc = lower_file->f_op->compat_ioctl(lower_file, cmd, arg); - return rc; -} -#endif +static int ecryptfs_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); const struct file_operations ecryptfs_dir_fops = { .readdir = ecryptfs_readdir, - .unlocked_ioctl = ecryptfs_unlocked_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = ecryptfs_compat_ioctl, -#endif + .ioctl = ecryptfs_ioctl, .open = ecryptfs_open, .flush = ecryptfs_flush, .release = ecryptfs_release, @@ -341,10 +313,7 @@ const struct file_operations ecryptfs_main_fops = { .write = do_sync_write, .aio_write = generic_file_aio_write, .readdir = ecryptfs_readdir, - .unlocked_ioctl = ecryptfs_unlocked_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = ecryptfs_compat_ioctl, -#endif + .ioctl = ecryptfs_ioctl, .mmap = generic_file_mmap, .open = ecryptfs_open, .flush = ecryptfs_flush, @@ -353,3 +322,20 @@ const struct file_operations ecryptfs_main_fops = { .fasync = ecryptfs_fasync, .splice_read = generic_file_splice_read, }; + +static int +ecryptfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) +{ + int rc = 0; + struct file *lower_file = NULL; + + if (ecryptfs_file_to_private(file)) + lower_file = ecryptfs_file_to_lower(file); + if (lower_file && lower_file->f_op && lower_file->f_op->ioctl) + rc = lower_file->f_op->ioctl(ecryptfs_inode_to_lower(inode), + lower_file, cmd, arg); + else + rc = -ENOTTY; + return rc; +} diff --git a/trunk/fs/ecryptfs/inode.c b/trunk/fs/ecryptfs/inode.c index 6c55113e7222..82900b063b1e 100644 --- a/trunk/fs/ecryptfs/inode.c +++ b/trunk/fs/ecryptfs/inode.c @@ -264,7 +264,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, printk(KERN_ERR "%s: Out of memory whilst attempting " "to allocate ecryptfs_dentry_info struct\n", __func__); - goto out_put; + goto out_dput; } ecryptfs_set_dentry_lower(ecryptfs_dentry, lower_dentry); ecryptfs_set_dentry_lower_mnt(ecryptfs_dentry, lower_mnt); @@ -339,84 +339,13 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, out_free_kmem: kmem_cache_free(ecryptfs_header_cache_2, page_virt); goto out; -out_put: +out_dput: dput(lower_dentry); - mntput(lower_mnt); d_drop(ecryptfs_dentry); out: return rc; } -/** - * ecryptfs_new_lower_dentry - * @ename: The name of the new dentry. - * @lower_dir_dentry: Parent directory of the new dentry. - * @nd: nameidata from last lookup. - * - * Create a new dentry or get it from lower parent dir. - */ -static struct dentry * -ecryptfs_new_lower_dentry(struct qstr *name, struct dentry *lower_dir_dentry, - struct nameidata *nd) -{ - struct dentry *new_dentry; - struct dentry *tmp; - struct inode *lower_dir_inode; - - lower_dir_inode = lower_dir_dentry->d_inode; - - tmp = d_alloc(lower_dir_dentry, name); - if (!tmp) - return ERR_PTR(-ENOMEM); - - mutex_lock(&lower_dir_inode->i_mutex); - new_dentry = lower_dir_inode->i_op->lookup(lower_dir_inode, tmp, nd); - mutex_unlock(&lower_dir_inode->i_mutex); - - if (!new_dentry) - new_dentry = tmp; - else - dput(tmp); - - return new_dentry; -} - - -/** - * ecryptfs_lookup_one_lower - * @ecryptfs_dentry: The eCryptfs dentry that we are looking up - * @lower_dir_dentry: lower parent directory - * - * Get the lower dentry from vfs. If lower dentry does not exist yet, - * create it. - */ -static struct dentry * -ecryptfs_lookup_one_lower(struct dentry *ecryptfs_dentry, - struct dentry *lower_dir_dentry) -{ - struct nameidata nd; - struct vfsmount *lower_mnt; - struct qstr *name; - int err; - - name = &ecryptfs_dentry->d_name; - lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt( - ecryptfs_dentry->d_parent)); - err = vfs_path_lookup(lower_dir_dentry, lower_mnt, name->name , 0, &nd); - mntput(lower_mnt); - - if (!err) { - /* we dont need the mount */ - mntput(nd.path.mnt); - return nd.path.dentry; - } - if (err != -ENOENT) - return ERR_PTR(err); - - /* create a new lower dentry */ - return ecryptfs_new_lower_dentry(name, lower_dir_dentry, &nd); -} - /** * ecryptfs_lookup * @ecryptfs_dir_inode: The eCryptfs directory inode @@ -444,12 +373,14 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, goto out_d_drop; } lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent); - - lower_dentry = ecryptfs_lookup_one_lower(ecryptfs_dentry, - lower_dir_dentry); + mutex_lock(&lower_dir_dentry->d_inode->i_mutex); + lower_dentry = lookup_one_len(ecryptfs_dentry->d_name.name, + lower_dir_dentry, + ecryptfs_dentry->d_name.len); + mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); if (IS_ERR(lower_dentry)) { rc = PTR_ERR(lower_dentry); - ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_lower() returned " + ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " "[%d] on lower_dentry = [%s]\n", __func__, rc, encrypted_and_encoded_name); goto out_d_drop; @@ -471,11 +402,14 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, "filename; rc = [%d]\n", __func__, rc); goto out_d_drop; } - lower_dentry = ecryptfs_lookup_one_lower(ecryptfs_dentry, - lower_dir_dentry); + mutex_lock(&lower_dir_dentry->d_inode->i_mutex); + lower_dentry = lookup_one_len(encrypted_and_encoded_name, + lower_dir_dentry, + encrypted_and_encoded_name_size - 1); + mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); if (IS_ERR(lower_dentry)) { rc = PTR_ERR(lower_dentry); - ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_lower() returned " + ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " "[%d] on lower_dentry = [%s]\n", __func__, rc, encrypted_and_encoded_name); goto out_d_drop; diff --git a/trunk/fs/ecryptfs/messaging.c b/trunk/fs/ecryptfs/messaging.c index bcb68c0cb1f0..46c4dd8dfcc3 100644 --- a/trunk/fs/ecryptfs/messaging.c +++ b/trunk/fs/ecryptfs/messaging.c @@ -274,7 +274,7 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, struct user_namespace *user_ns, struct pid *pid, u32 seq) { - struct ecryptfs_daemon *uninitialized_var(daemon); + struct ecryptfs_daemon *daemon; struct ecryptfs_msg_ctx *msg_ctx; size_t msg_size; struct nsproxy *nsproxy; diff --git a/trunk/fs/ncpfs/ioctl.c b/trunk/fs/ncpfs/ioctl.c index 84a8cfc4e38e..023c03d02070 100644 --- a/trunk/fs/ncpfs/ioctl.c +++ b/trunk/fs/ncpfs/ioctl.c @@ -20,6 +20,7 @@ #include #include #include +#include #include diff --git a/trunk/include/asm-generic/ioctls.h b/trunk/include/asm-generic/ioctls.h index 8554cb6a81b9..a799e20a769e 100644 --- a/trunk/include/asm-generic/ioctls.h +++ b/trunk/include/asm-generic/ioctls.h @@ -69,7 +69,6 @@ #define TCSETX 0x5433 #define TCSETXF 0x5434 #define TCSETXW 0x5435 -#define TIOCSIG _IOW('T', 0x36, int) /* pty: generate signal */ #define FIONCLEX 0x5450 #define FIOCLEX 0x5451 @@ -88,10 +87,12 @@ #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ /* - * Some arches already define FIOQSIZE due to a historical - * conflict with a Hayes modem-specific ioctl value. + * some architectures define FIOQSIZE as 0x545E, which is used for + * TIOCGHAYESESP on others */ #ifndef FIOQSIZE +# define TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ +# define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ # define FIOQSIZE 0x5460 #endif @@ -103,7 +104,6 @@ #define TIOCPKT_START 8 #define TIOCPKT_NOSTOP 16 #define TIOCPKT_DOSTOP 32 -#define TIOCPKT_IOCTL 64 #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ diff --git a/trunk/include/asm-generic/termbits.h b/trunk/include/asm-generic/termbits.h index 232b4781aef3..1c9773d48cb0 100644 --- a/trunk/include/asm-generic/termbits.h +++ b/trunk/include/asm-generic/termbits.h @@ -178,7 +178,6 @@ struct ktermios { #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 -#define EXTPROC 0200000 /* tcflow() and TCXONC use these */ #define TCOOFF 0 diff --git a/trunk/include/linux/auto_fs.h b/trunk/include/linux/auto_fs.h index da64e15004b6..7b09c8348fd3 100644 --- a/trunk/include/linux/auto_fs.h +++ b/trunk/include/linux/auto_fs.h @@ -79,7 +79,6 @@ struct autofs_packet_expire { #define AUTOFS_IOC_FAIL _IO(0x93,0x61) #define AUTOFS_IOC_CATATONIC _IO(0x93,0x62) #define AUTOFS_IOC_PROTOVER _IOR(0x93,0x63,int) -#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,compat_ulong_t) #define AUTOFS_IOC_SETTIMEOUT _IOWR(0x93,0x64,unsigned long) #define AUTOFS_IOC_EXPIRE _IOR(0x93,0x65,struct autofs_packet_expire) diff --git a/trunk/include/linux/console_struct.h b/trunk/include/linux/console_struct.h index 7f0c32908568..38fe59dc89ae 100644 --- a/trunk/include/linux/console_struct.h +++ b/trunk/include/linux/console_struct.h @@ -21,8 +21,6 @@ struct vt_struct; #define NPAR 16 struct vc_data { - struct tty_port port; /* Upper level data */ - unsigned short vc_num; /* Console number */ unsigned int vc_cols; /* [#] Console size */ unsigned int vc_rows; @@ -58,6 +56,7 @@ struct vc_data { /* VT terminal data */ unsigned int vc_state; /* Escape sequence parser state */ unsigned int vc_npar,vc_par[NPAR]; /* Parameters of current escape sequence */ + struct tty_struct *vc_tty; /* TTY we are attached to */ /* data for manual vt switching */ struct vt_mode vt_mode; struct pid *vt_pid; @@ -106,7 +105,6 @@ struct vc_data { struct vc_data **vc_display_fg; /* [!] Ptr to var holding fg console for this display */ unsigned long vc_uni_pagedir; unsigned long *vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */ - bool vc_panic_force_write; /* when oops/panic this VC can accept forced output/blanking */ /* additional information is in vt_kern.h */ }; diff --git a/trunk/include/linux/fb.h b/trunk/include/linux/fb.h index f0268deca658..0c5659c41b01 100644 --- a/trunk/include/linux/fb.h +++ b/trunk/include/linux/fb.h @@ -825,10 +825,6 @@ struct fb_tile_ops { */ #define FBINFO_BE_MATH 0x100000 -/* report to the VT layer that this fb driver can accept forced console - output like oopses */ -#define FBINFO_CAN_FORCE_OUTPUT 0x200000 - struct fb_info { int node; int flags; diff --git a/trunk/include/linux/istallion.h b/trunk/include/linux/istallion.h index ad700a60c158..7faca98c7d14 100644 --- a/trunk/include/linux/istallion.h +++ b/trunk/include/linux/istallion.h @@ -86,7 +86,7 @@ struct stlibrd { unsigned long magic; unsigned int brdnr; unsigned int brdtype; - unsigned long state; + unsigned int state; unsigned int nrpanels; unsigned int nrports; unsigned int nrdevs; diff --git a/trunk/include/linux/serial.h b/trunk/include/linux/serial.h index 1ebc694a6d52..c8613c3ff9d3 100644 --- a/trunk/include/linux/serial.h +++ b/trunk/include/linux/serial.h @@ -77,8 +77,7 @@ struct serial_struct { #define PORT_16654 11 #define PORT_16850 12 #define PORT_RSA 13 /* RSA-DV II/S card */ -#define PORT_U6_16550A 14 -#define PORT_MAX 14 +#define PORT_MAX 13 #define SERIAL_IO_PORT 0 #define SERIAL_IO_HUB6 1 @@ -152,7 +151,7 @@ struct serial_uart_config { #define ASYNC_BUGGY_UART (1U << ASYNCB_BUGGY_UART) #define ASYNC_AUTOPROBE (1U << ASYNCB_AUTOPROBE) -#define ASYNC_FLAGS ((1U << (ASYNCB_LAST_USER + 1)) - 1) +#define ASYNC_FLAGS ((1U << ASYNCB_LAST_USER) - 1) #define ASYNC_USR_MASK (ASYNC_SPD_HI|ASYNC_SPD_VHI| \ ASYNC_CALLOUT_NOHUP|ASYNC_SPD_SHI|ASYNC_LOW_LATENCY) #define ASYNC_SPD_CUST (ASYNC_SPD_HI|ASYNC_SPD_VHI) @@ -211,10 +210,8 @@ struct serial_rs485 { #define SER_RS485_ENABLED (1 << 0) #define SER_RS485_RTS_ON_SEND (1 << 1) #define SER_RS485_RTS_AFTER_SEND (1 << 2) -#define SER_RS485_RTS_BEFORE_SEND (1 << 3) __u32 delay_rts_before_send; /* Milliseconds */ - __u32 delay_rts_after_send; /* Milliseconds */ - __u32 padding[5]; /* Memory is cheap, new structs + __u32 padding[6]; /* Memory is cheap, new structs are a royal PITA .. */ }; diff --git a/trunk/include/linux/serial_8250.h b/trunk/include/linux/serial_8250.h index 7638deaaba65..fb46aba11fb5 100644 --- a/trunk/include/linux/serial_8250.h +++ b/trunk/include/linux/serial_8250.h @@ -32,9 +32,6 @@ struct plat_serial8250_port { unsigned int type; /* If UPF_FIXED_TYPE */ unsigned int (*serial_in)(struct uart_port *, int); void (*serial_out)(struct uart_port *, int, int); - void (*set_termios)(struct uart_port *, - struct ktermios *new, - struct ktermios *old); }; /* @@ -74,7 +71,5 @@ extern int early_serial_setup(struct uart_port *port); extern int serial8250_find_port(struct uart_port *p); extern int serial8250_find_port_for_earlycon(void); extern int setup_early_serial8250_console(char *cmdline); -extern void serial8250_do_set_termios(struct uart_port *port, - struct ktermios *termios, struct ktermios *old); #endif diff --git a/trunk/include/linux/serial_core.h b/trunk/include/linux/serial_core.h index 8129ca2d57e3..f10db6e5f3b5 100644 --- a/trunk/include/linux/serial_core.h +++ b/trunk/include/linux/serial_core.h @@ -186,12 +186,6 @@ #define PORT_ALTERA_JTAGUART 91 #define PORT_ALTERA_UART 92 -/* MAX3107 */ -#define PORT_MAX3107 94 - -/* High Speed UART for Medfield */ -#define PORT_MFD 95 - #ifdef __KERNEL__ #include @@ -226,7 +220,7 @@ struct uart_ops { void (*flush_buffer)(struct uart_port *); void (*set_termios)(struct uart_port *, struct ktermios *new, struct ktermios *old); - void (*set_ldisc)(struct uart_port *, int new); + void (*set_ldisc)(struct uart_port *); void (*pm)(struct uart_port *, unsigned int state, unsigned int oldstate); int (*set_wake)(struct uart_port *, unsigned int state); @@ -282,9 +276,6 @@ struct uart_port { unsigned char __iomem *membase; /* read/write[bwl] */ unsigned int (*serial_in)(struct uart_port *, int); void (*serial_out)(struct uart_port *, int, int); - void (*set_termios)(struct uart_port *, - struct ktermios *new, - struct ktermios *old); unsigned int irq; /* irq number */ unsigned long irqflags; /* irq flags */ unsigned int uartclk; /* base uart clock */ diff --git a/trunk/include/linux/serial_mfd.h b/trunk/include/linux/serial_mfd.h deleted file mode 100644 index 2b071e0b034d..000000000000 --- a/trunk/include/linux/serial_mfd.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef _SERIAL_MFD_H_ -#define _SERIAL_MFD_H_ - -/* HW register offset definition */ -#define UART_FOR 0x08 -#define UART_PS 0x0C -#define UART_MUL 0x0D -#define UART_DIV 0x0E - -#define HSU_GBL_IEN 0x0 -#define HSU_GBL_IST 0x4 - -#define HSU_GBL_INT_BIT_PORT0 0x0 -#define HSU_GBL_INT_BIT_PORT1 0x1 -#define HSU_GBL_INT_BIT_PORT2 0x2 -#define HSU_GBL_INT_BIT_IRI 0x3 -#define HSU_GBL_INT_BIT_HDLC 0x4 -#define HSU_GBL_INT_BIT_DMA 0x5 - -#define HSU_GBL_ISR 0x8 -#define HSU_GBL_DMASR 0x400 -#define HSU_GBL_DMAISR 0x404 - -#define HSU_PORT_REG_OFFSET 0x80 -#define HSU_PORT0_REG_OFFSET 0x80 -#define HSU_PORT1_REG_OFFSET 0x100 -#define HSU_PORT2_REG_OFFSET 0x180 -#define HSU_PORT_REG_LENGTH 0x80 - -#define HSU_DMA_CHANS_REG_OFFSET 0x500 -#define HSU_DMA_CHANS_REG_LENGTH 0x40 - -#define HSU_CH_SR 0x0 /* channel status reg */ -#define HSU_CH_CR 0x4 /* control reg */ -#define HSU_CH_DCR 0x8 /* descriptor control reg */ -#define HSU_CH_BSR 0x10 /* max fifo buffer size reg */ -#define HSU_CH_MOTSR 0x14 /* minimum ocp transfer size */ -#define HSU_CH_D0SAR 0x20 /* desc 0 start addr */ -#define HSU_CH_D0TSR 0x24 /* desc 0 transfer size */ -#define HSU_CH_D1SAR 0x28 -#define HSU_CH_D1TSR 0x2C -#define HSU_CH_D2SAR 0x30 -#define HSU_CH_D2TSR 0x34 -#define HSU_CH_D3SAR 0x38 -#define HSU_CH_D3TSR 0x3C - -#endif diff --git a/trunk/include/linux/serial_reg.h b/trunk/include/linux/serial_reg.h index c7a0ce11cd47..cf9327c051ad 100644 --- a/trunk/include/linux/serial_reg.h +++ b/trunk/include/linux/serial_reg.h @@ -221,24 +221,8 @@ #define UART_FCR_PXAR16 0x80 /* receive FIFO threshold = 16 */ #define UART_FCR_PXAR32 0xc0 /* receive FIFO threshold = 32 */ -/* - * Intel MID on-chip HSU (High Speed UART) defined bits - */ -#define UART_FCR_HSU_64_1B 0x00 /* receive FIFO treshold = 1 */ -#define UART_FCR_HSU_64_16B 0x40 /* receive FIFO treshold = 16 */ -#define UART_FCR_HSU_64_32B 0x80 /* receive FIFO treshold = 32 */ -#define UART_FCR_HSU_64_56B 0xc0 /* receive FIFO treshold = 56 */ - -#define UART_FCR_HSU_16_1B 0x00 /* receive FIFO treshold = 1 */ -#define UART_FCR_HSU_16_4B 0x40 /* receive FIFO treshold = 4 */ -#define UART_FCR_HSU_16_8B 0x80 /* receive FIFO treshold = 8 */ -#define UART_FCR_HSU_16_14B 0xc0 /* receive FIFO treshold = 14 */ -#define UART_FCR_HSU_64B_FIFO 0x20 /* chose 64 bytes FIFO */ -#define UART_FCR_HSU_16B_FIFO 0x00 /* chose 16 bytes FIFO */ -#define UART_FCR_HALF_EMPT_TXI 0x00 /* trigger TX_EMPT IRQ for half empty */ -#define UART_FCR_FULL_EMPT_TXI 0x08 /* trigger TX_EMPT IRQ for full empty */ /* * These register definitions are for the 16C950 diff --git a/trunk/include/linux/tty.h b/trunk/include/linux/tty.h index 1437da3ddc62..7802a243ee13 100644 --- a/trunk/include/linux/tty.h +++ b/trunk/include/linux/tty.h @@ -13,7 +13,6 @@ #include #include #include -#include #include @@ -180,7 +179,6 @@ struct tty_bufhead { #define L_FLUSHO(tty) _L_FLAG((tty), FLUSHO) #define L_PENDIN(tty) _L_FLAG((tty), PENDIN) #define L_IEXTEN(tty) _L_FLAG((tty), IEXTEN) -#define L_EXTPROC(tty) _L_FLAG((tty), EXTPROC) struct device; struct signal_struct; @@ -417,7 +415,6 @@ extern int is_ignored(int sig); extern int tty_signal(int sig, struct tty_struct *tty); extern void tty_hangup(struct tty_struct *tty); extern void tty_vhangup(struct tty_struct *tty); -extern void tty_vhangup_locked(struct tty_struct *tty); extern void tty_vhangup_self(void); extern void tty_unhangup(struct file *filp); extern int tty_hung_up_p(struct file *filp); @@ -578,54 +575,5 @@ extern int vt_ioctl(struct tty_struct *tty, struct file *file, extern long vt_compat_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg); -/* tty_mutex.c */ -/* functions for preparation of BKL removal */ -extern void __lockfunc tty_lock(void) __acquires(tty_lock); -extern void __lockfunc tty_unlock(void) __releases(tty_lock); -extern struct task_struct *__big_tty_mutex_owner; -#define tty_locked() (current == __big_tty_mutex_owner) - -/* - * wait_event_interruptible_tty -- wait for a condition with the tty lock held - * - * The condition we are waiting for might take a long time to - * become true, or might depend on another thread taking the - * BTM. In either case, we need to drop the BTM to guarantee - * forward progress. This is a leftover from the conversion - * from the BKL and should eventually get removed as the BTM - * falls out of use. - * - * Do not use in new code. - */ -#define wait_event_interruptible_tty(wq, condition) \ -({ \ - int __ret = 0; \ - if (!(condition)) { \ - __wait_event_interruptible_tty(wq, condition, __ret); \ - } \ - __ret; \ -}) - -#define __wait_event_interruptible_tty(wq, condition, ret) \ -do { \ - DEFINE_WAIT(__wait); \ - \ - for (;;) { \ - prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE); \ - if (condition) \ - break; \ - if (!signal_pending(current)) { \ - tty_unlock(); \ - schedule(); \ - tty_lock(); \ - continue; \ - } \ - ret = -ERESTARTSYS; \ - break; \ - } \ - finish_wait(&wq, &__wait); \ -} while (0) - - #endif /* __KERNEL__ */ #endif diff --git a/trunk/include/linux/vt_kern.h b/trunk/include/linux/vt_kern.h index 6625cc1ab758..7f56db4a79f0 100644 --- a/trunk/include/linux/vt_kern.h +++ b/trunk/include/linux/vt_kern.h @@ -76,52 +76,17 @@ int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc); #define vc_translate(vc, c) ((vc)->vc_translate[(c) | \ ((vc)->vc_toggle_meta ? 0x80 : 0)]) #else -static inline int con_set_trans_old(unsigned char __user *table) -{ - return 0; -} -static inline int con_get_trans_old(unsigned char __user *table) -{ - return -EINVAL; -} -static inline int con_set_trans_new(unsigned short __user *table) -{ - return 0; -} -static inline int con_get_trans_new(unsigned short __user *table) -{ - return -EINVAL; -} -static inline int con_clear_unimap(struct vc_data *vc, struct unimapinit *ui) -{ - return 0; -} -static inline -int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list) -{ - return 0; -} -static inline -int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, - struct unipair __user *list) -{ - return -EINVAL; -} -static inline int con_set_default_unimap(struct vc_data *vc) -{ - return 0; -} -static inline void con_free_unimap(struct vc_data *vc) -{ -} -static inline void con_protect_unimap(struct vc_data *vc, int rdonly) -{ -} -static inline -int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc) -{ - return 0; -} +#define con_set_trans_old(arg) (0) +#define con_get_trans_old(arg) (-EINVAL) +#define con_set_trans_new(arg) (0) +#define con_get_trans_new(arg) (-EINVAL) +#define con_clear_unimap(vc, ui) (0) +#define con_set_unimap(vc, ct, list) (0) +#define con_set_default_unimap(vc) (0) +#define con_copy_unimap(d, s) (0) +#define con_get_unimap(vc, ct, uct, list) (-EINVAL) +#define con_free_unimap(vc) do { ; } while (0) +#define con_protect_unimap(vc, rdonly) do { ; } while (0) #define vc_translate(vc, c) (c) #endif @@ -135,13 +100,6 @@ extern int unbind_con_driver(const struct consw *csw, int first, int last, int deflt); int vty_init(const struct file_operations *console_fops); -static inline bool vt_force_oops_output(struct vc_data *vc) -{ - if (oops_in_progress && vc->vc_panic_force_write) - return true; - return false; -} - /* * vc_screen.c shares this temporary buffer with the console write code so that * we can easily avoid touching user space while holding the console spinlock. diff --git a/trunk/lib/Kconfig.debug b/trunk/lib/Kconfig.debug index 9e06b7f5ecf1..79e0dff1cdcb 100644 --- a/trunk/lib/Kconfig.debug +++ b/trunk/lib/Kconfig.debug @@ -410,13 +410,6 @@ config DEBUG_KMEMLEAK_TEST If unsure, say N. -config DEBUG_KMEMLEAK_DEFAULT_OFF - bool "Default kmemleak to off" - depends on DEBUG_KMEMLEAK - help - Say Y here to disable kmemleak by default. It can then be enabled - on the command line via kmemleak=on. - config DEBUG_PREEMPT bool "Debug preemptible kernel" depends on DEBUG_KERNEL && PREEMPT && TRACE_IRQFLAGS_SUPPORT diff --git a/trunk/lib/scatterlist.c b/trunk/lib/scatterlist.c index a5ec42868f99..9afa25b52a83 100644 --- a/trunk/lib/scatterlist.c +++ b/trunk/lib/scatterlist.c @@ -10,7 +10,6 @@ #include #include #include -#include /** * sg_next - return the next scatterlist entry in a list @@ -116,29 +115,17 @@ EXPORT_SYMBOL(sg_init_one); */ static struct scatterlist *sg_kmalloc(unsigned int nents, gfp_t gfp_mask) { - if (nents == SG_MAX_SINGLE_ALLOC) { - /* - * Kmemleak doesn't track page allocations as they are not - * commonly used (in a raw form) for kernel data structures. - * As we chain together a list of pages and then a normal - * kmalloc (tracked by kmemleak), in order to for that last - * allocation not to become decoupled (and thus a - * false-positive) we need to inform kmemleak of all the - * intermediate allocations. - */ - void *ptr = (void *) __get_free_page(gfp_mask); - kmemleak_alloc(ptr, PAGE_SIZE, 1, gfp_mask); - return ptr; - } else + if (nents == SG_MAX_SINGLE_ALLOC) + return (struct scatterlist *) __get_free_page(gfp_mask); + else return kmalloc(nents * sizeof(struct scatterlist), gfp_mask); } static void sg_kfree(struct scatterlist *sg, unsigned int nents) { - if (nents == SG_MAX_SINGLE_ALLOC) { - kmemleak_free(sg); + if (nents == SG_MAX_SINGLE_ALLOC) free_page((unsigned long) sg); - } else + else kfree(sg); } diff --git a/trunk/mm/kmemleak.c b/trunk/mm/kmemleak.c index bd9bc214091b..2c0d032ac898 100644 --- a/trunk/mm/kmemleak.c +++ b/trunk/mm/kmemleak.c @@ -211,9 +211,6 @@ static signed long jiffies_scan_wait; static int kmemleak_stack_scan = 1; /* protects the memory scanning, parameters and debug/kmemleak file access */ static DEFINE_MUTEX(scan_mutex); -/* setting kmemleak=on, will set this var, skipping the disable */ -static int kmemleak_skip_disable; - /* * Early object allocation/freeing logging. Kmemleak is initialized after the @@ -401,9 +398,7 @@ static struct kmemleak_object *lookup_object(unsigned long ptr, int alias) object = prio_tree_entry(node, struct kmemleak_object, tree_node); if (!alias && object->pointer != ptr) { - pr_warning("Found object by alias at 0x%08lx\n", ptr); - dump_stack(); - dump_object_info(object); + kmemleak_warn("Found object by alias"); object = NULL; } } else @@ -700,7 +695,7 @@ static void paint_ptr(unsigned long ptr, int color) } /* - * Mark an object permanently as gray-colored so that it can no longer be + * Make a object permanently as gray-colored so that it can no longer be * reported as a leak. This is used in general to mark a false positive. */ static void make_gray_object(unsigned long ptr) @@ -843,19 +838,10 @@ static void early_alloc(struct early_log *log) rcu_read_unlock(); } -/** - * kmemleak_alloc - register a newly allocated object - * @ptr: pointer to beginning of the object - * @size: size of the object - * @min_count: minimum number of references to this object. If during memory - * scanning a number of references less than @min_count is found, - * the object is reported as a memory leak. If @min_count is 0, - * the object is never reported as a leak. If @min_count is -1, - * the object is ignored (not scanned and not reported as a leak) - * @gfp: kmalloc() flags used for kmemleak internal memory allocations - * - * This function is called from the kernel allocators when a new object - * (memory block) is allocated (kmem_cache_alloc, kmalloc, vmalloc etc.). +/* + * Memory allocation function callback. This function is called from the + * kernel allocators when a new block is allocated (kmem_cache_alloc, kmalloc, + * vmalloc etc.). */ void __ref kmemleak_alloc(const void *ptr, size_t size, int min_count, gfp_t gfp) @@ -869,12 +855,9 @@ void __ref kmemleak_alloc(const void *ptr, size_t size, int min_count, } EXPORT_SYMBOL_GPL(kmemleak_alloc); -/** - * kmemleak_free - unregister a previously registered object - * @ptr: pointer to beginning of the object - * - * This function is called from the kernel allocators when an object (memory - * block) is freed (kmem_cache_free, kfree, vfree etc.). +/* + * Memory freeing function callback. This function is called from the kernel + * allocators when a block is freed (kmem_cache_free, kfree, vfree etc.). */ void __ref kmemleak_free(const void *ptr) { @@ -887,14 +870,9 @@ void __ref kmemleak_free(const void *ptr) } EXPORT_SYMBOL_GPL(kmemleak_free); -/** - * kmemleak_free_part - partially unregister a previously registered object - * @ptr: pointer to the beginning or inside the object. This also - * represents the start of the range to be freed - * @size: size to be unregistered - * - * This function is called when only a part of a memory block is freed - * (usually from the bootmem allocator). +/* + * Partial memory freeing function callback. This function is usually called + * from bootmem allocator when (part of) a memory block is freed. */ void __ref kmemleak_free_part(const void *ptr, size_t size) { @@ -907,12 +885,9 @@ void __ref kmemleak_free_part(const void *ptr, size_t size) } EXPORT_SYMBOL_GPL(kmemleak_free_part); -/** - * kmemleak_not_leak - mark an allocated object as false positive - * @ptr: pointer to beginning of the object - * - * Calling this function on an object will cause the memory block to no longer - * be reported as leak and always be scanned. +/* + * Mark an already allocated memory block as a false positive. This will cause + * the block to no longer be reported as leak and always be scanned. */ void __ref kmemleak_not_leak(const void *ptr) { @@ -925,14 +900,10 @@ void __ref kmemleak_not_leak(const void *ptr) } EXPORT_SYMBOL(kmemleak_not_leak); -/** - * kmemleak_ignore - ignore an allocated object - * @ptr: pointer to beginning of the object - * - * Calling this function on an object will cause the memory block to be - * ignored (not scanned and not reported as a leak). This is usually done when - * it is known that the corresponding block is not a leak and does not contain - * any references to other allocated memory blocks. +/* + * Ignore a memory block. This is usually done when it is known that the + * corresponding block is not a leak and does not contain any references to + * other allocated memory blocks. */ void __ref kmemleak_ignore(const void *ptr) { @@ -945,16 +916,8 @@ void __ref kmemleak_ignore(const void *ptr) } EXPORT_SYMBOL(kmemleak_ignore); -/** - * kmemleak_scan_area - limit the range to be scanned in an allocated object - * @ptr: pointer to beginning or inside the object. This also - * represents the start of the scan area - * @size: size of the scan area - * @gfp: kmalloc() flags used for kmemleak internal memory allocations - * - * This function is used when it is known that only certain parts of an object - * contain references to other objects. Kmemleak will only scan these areas - * reducing the number false negatives. +/* + * Limit the range to be scanned in an allocated memory block. */ void __ref kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp) { @@ -967,14 +930,8 @@ void __ref kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp) } EXPORT_SYMBOL(kmemleak_scan_area); -/** - * kmemleak_no_scan - do not scan an allocated object - * @ptr: pointer to beginning of the object - * - * This function notifies kmemleak not to scan the given memory block. Useful - * in situations where it is known that the given object does not contain any - * references to other objects. Kmemleak will not scan such objects reducing - * the number of false negatives. +/* + * Inform kmemleak not to scan the given memory block. */ void __ref kmemleak_no_scan(const void *ptr) { @@ -1645,9 +1602,7 @@ static int kmemleak_boot_config(char *str) return -EINVAL; if (strcmp(str, "off") == 0) kmemleak_disable(); - else if (strcmp(str, "on") == 0) - kmemleak_skip_disable = 1; - else + else if (strcmp(str, "on") != 0) return -EINVAL; return 0; } @@ -1661,13 +1616,6 @@ void __init kmemleak_init(void) int i; unsigned long flags; -#ifdef CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF - if (!kmemleak_skip_disable) { - kmemleak_disable(); - return; - } -#endif - jiffies_min_age = msecs_to_jiffies(MSECS_MIN_AGE); jiffies_scan_wait = msecs_to_jiffies(SECS_SCAN_WAIT * 1000);