diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-20 14:24:39 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-20 14:24:39 -0400 |
| commit | 843ec558f91b8e8fdb6efc908f2c0506407cc750 (patch) | |
| tree | 1866dccbc298390fc8686875942324075fd83f9d /drivers | |
| parent | 71e7ff2578c3bc67fd893a9ba7f69fd563f271de (diff) | |
| parent | fb8ebec00b04f921ea1614a7303f1a8e5e9e47c5 (diff) | |
Merge tag 'tty-3.3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull TTY/serial patches from Greg KH:
"tty and serial merge for 3.4-rc1
Here's the big serial and tty merge for the 3.4-rc1 tree.
There's loads of fixes and reworks in here from Jiri for the tty
layer, and a number of patches from Alan to help try to wrestle the vt
layer into a sane model.
Other than that, lots of driver updates and fixes, and other minor
stuff, all detailed in the shortlog."
* tag 'tty-3.3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (132 commits)
serial: pxa: add clk_prepare/clk_unprepare calls
TTY: Wrong unicode value copied in con_set_unimap()
serial: PL011: clear pending interrupts
serial: bfin-uart: Don't access tty circular buffer in TX DMA interrupt after it is reset.
vt: NULL dereference in vt_do_kdsk_ioctl()
tty: serial: vt8500: fix annotations for probe/remove
serial: remove back and forth conversions in serial_out_sync
serial: use serial_port_in/out vs serial_in/out in 8250
serial: introduce generic port in/out helpers
serial: reduce number of indirections in 8250 code
serial: delete useless void casts in 8250.c
serial: make 8250's serial_in shareable to other drivers.
serial: delete last unused traces of pausing I/O in 8250
pch_uart: Add module parameter descriptions
pch_uart: Use existing default_baud in setup_console
pch_uart: Add user_uartclk parameter
pch_uart: Add Fish River Island II uart clock quirks
pch_uart: Use uartclk instead of base_baud
mpc5200b/uart: select more tolerant uart prescaler on low baudrates
tty: moxa: fix bit test in moxa_start()
...
Diffstat (limited to 'drivers')
92 files changed, 2795 insertions, 2299 deletions
diff --git a/drivers/accessibility/braille/braille_console.c b/drivers/accessibility/braille/braille_console.c index c339a0880e6e..d21167bfc865 100644 --- a/drivers/accessibility/braille/braille_console.c +++ b/drivers/accessibility/braille/braille_console.c | |||
| @@ -244,16 +244,13 @@ static int keyboard_notifier_call(struct notifier_block *blk, | |||
| 244 | 244 | ||
| 245 | switch (val) { | 245 | switch (val) { |
| 246 | case KVAL(K_CAPS): | 246 | case KVAL(K_CAPS): |
| 247 | on_off = vc_kbd_led(kbd_table + fg_console, | 247 | on_off = vt_get_leds(fg_console, VC_CAPSLOCK); |
| 248 | VC_CAPSLOCK); | ||
| 249 | break; | 248 | break; |
| 250 | case KVAL(K_NUM): | 249 | case KVAL(K_NUM): |
| 251 | on_off = vc_kbd_led(kbd_table + fg_console, | 250 | on_off = vt_get_leds(fg_console, VC_NUMLOCK); |
| 252 | VC_NUMLOCK); | ||
| 253 | break; | 251 | break; |
| 254 | case KVAL(K_HOLD): | 252 | case KVAL(K_HOLD): |
| 255 | on_off = vc_kbd_led(kbd_table + fg_console, | 253 | on_off = vt_get_leds(fg_console, VC_SCROLLOCK); |
| 256 | VC_SCROLLOCK); | ||
| 257 | break; | 254 | break; |
| 258 | } | 255 | } |
| 259 | if (on_off == 1) | 256 | if (on_off == 1) |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 43643033a3ae..ee946865d6cb 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
| @@ -66,21 +66,6 @@ config TTY_PRINTK | |||
| 66 | 66 | ||
| 67 | If unsure, say N. | 67 | If unsure, say N. |
| 68 | 68 | ||
| 69 | config BRIQ_PANEL | ||
| 70 | tristate 'Total Impact briQ front panel driver' | ||
| 71 | depends on PPC_CHRP | ||
| 72 | ---help--- | ||
| 73 | The briQ is a small footprint CHRP computer with a frontpanel VFD, a | ||
| 74 | tristate led and two switches. It is the size of a CDROM drive. | ||
| 75 | |||
| 76 | If you have such one and want anything showing on the VFD then you | ||
| 77 | must answer Y here. | ||
| 78 | |||
| 79 | To compile this driver as a module, choose M here: the | ||
| 80 | module will be called briq_panel. | ||
| 81 | |||
| 82 | It's safe to say N here. | ||
| 83 | |||
| 84 | config BFIN_OTP | 69 | config BFIN_OTP |
| 85 | tristate "Blackfin On-Chip OTP Memory Support" | 70 | tristate "Blackfin On-Chip OTP Memory Support" |
| 86 | depends on BLACKFIN && (BF51x || BF52x || BF54x) | 71 | depends on BLACKFIN && (BF51x || BF52x || BF54x) |
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 32762ba769c2..0dc5d7ce4864 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
| @@ -16,7 +16,6 @@ obj-$(CONFIG_UV_MMTIMER) += uv_mmtimer.o | |||
| 16 | obj-$(CONFIG_VIOTAPE) += viotape.o | 16 | obj-$(CONFIG_VIOTAPE) += viotape.o |
| 17 | obj-$(CONFIG_IBM_BSR) += bsr.o | 17 | obj-$(CONFIG_IBM_BSR) += bsr.o |
| 18 | obj-$(CONFIG_SGI_MBCS) += mbcs.o | 18 | obj-$(CONFIG_SGI_MBCS) += mbcs.o |
| 19 | obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o | ||
| 20 | obj-$(CONFIG_BFIN_OTP) += bfin-otp.o | 19 | obj-$(CONFIG_BFIN_OTP) += bfin-otp.o |
| 21 | 20 | ||
| 22 | obj-$(CONFIG_PRINTER) += lp.o | 21 | obj-$(CONFIG_PRINTER) += lp.o |
diff --git a/drivers/char/briq_panel.c b/drivers/char/briq_panel.c deleted file mode 100644 index 095ab90535ce..000000000000 --- a/drivers/char/briq_panel.c +++ /dev/null | |||
| @@ -1,266 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Drivers for the Total Impact PPC based computer "BRIQ" | ||
| 3 | * by Dr. Karsten Jeppesen | ||
| 4 | * | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include <linux/module.h> | ||
| 8 | |||
| 9 | #include <linux/types.h> | ||
| 10 | #include <linux/errno.h> | ||
| 11 | #include <linux/tty.h> | ||
| 12 | #include <linux/timer.h> | ||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/wait.h> | ||
| 15 | #include <linux/string.h> | ||
| 16 | #include <linux/ioport.h> | ||
| 17 | #include <linux/delay.h> | ||
| 18 | #include <linux/miscdevice.h> | ||
| 19 | #include <linux/fs.h> | ||
| 20 | #include <linux/mm.h> | ||
| 21 | #include <linux/init.h> | ||
| 22 | |||
| 23 | #include <asm/uaccess.h> | ||
| 24 | #include <asm/io.h> | ||
| 25 | #include <asm/prom.h> | ||
| 26 | |||
| 27 | #define BRIQ_PANEL_MINOR 156 | ||
| 28 | #define BRIQ_PANEL_VFD_IOPORT 0x0390 | ||
| 29 | #define BRIQ_PANEL_LED_IOPORT 0x0398 | ||
| 30 | #define BRIQ_PANEL_VER "1.1 (04/20/2002)" | ||
| 31 | #define BRIQ_PANEL_MSG0 "Loading Linux" | ||
| 32 | |||
| 33 | static int vfd_is_open; | ||
| 34 | static unsigned char vfd[40]; | ||
| 35 | static int vfd_cursor; | ||
| 36 | static unsigned char ledpb, led; | ||
| 37 | |||
| 38 | static void update_vfd(void) | ||
| 39 | { | ||
| 40 | int i; | ||
| 41 | |||
| 42 | /* cursor home */ | ||
| 43 | outb(0x02, BRIQ_PANEL_VFD_IOPORT); | ||
| 44 | for (i=0; i<20; i++) | ||
| 45 | outb(vfd[i], BRIQ_PANEL_VFD_IOPORT + 1); | ||
| 46 | |||
| 47 | /* cursor to next line */ | ||
| 48 | outb(0xc0, BRIQ_PANEL_VFD_IOPORT); | ||
| 49 | for (i=20; i<40; i++) | ||
| 50 | outb(vfd[i], BRIQ_PANEL_VFD_IOPORT + 1); | ||
| 51 | |||
| 52 | } | ||
| 53 | |||
| 54 | static void set_led(char state) | ||
| 55 | { | ||
| 56 | if (state == 'R') | ||
| 57 | led = 0x01; | ||
| 58 | else if (state == 'G') | ||
| 59 | led = 0x02; | ||
| 60 | else if (state == 'Y') | ||
| 61 | led = 0x03; | ||
| 62 | else if (state == 'X') | ||
| 63 | led = 0x00; | ||
| 64 | outb(led, BRIQ_PANEL_LED_IOPORT); | ||
| 65 | } | ||
| 66 | |||
| 67 | static int briq_panel_open(struct inode *ino, struct file *filep) | ||
| 68 | { | ||
| 69 | tty_lock(); | ||
| 70 | /* enforce single access, vfd_is_open is protected by BKL */ | ||
| 71 | if (vfd_is_open) { | ||
| 72 | tty_unlock(); | ||
| 73 | return -EBUSY; | ||
| 74 | } | ||
| 75 | vfd_is_open = 1; | ||
| 76 | |||
| 77 | tty_unlock(); | ||
| 78 | return 0; | ||
| 79 | } | ||
| 80 | |||
| 81 | static int briq_panel_release(struct inode *ino, struct file *filep) | ||
| 82 | { | ||
| 83 | if (!vfd_is_open) | ||
| 84 | return -ENODEV; | ||
| 85 | |||
| 86 | vfd_is_open = 0; | ||
| 87 | |||
| 88 | return 0; | ||
| 89 | } | ||
| 90 | |||
| 91 | static ssize_t briq_panel_read(struct file *file, char __user *buf, size_t count, | ||
| 92 | loff_t *ppos) | ||
| 93 | { | ||
| 94 | unsigned short c; | ||
| 95 | unsigned char cp; | ||
| 96 | |||
| 97 | if (!vfd_is_open) | ||
| 98 | return -ENODEV; | ||
| 99 | |||
| 100 | c = (inb(BRIQ_PANEL_LED_IOPORT) & 0x000c) | (ledpb & 0x0003); | ||
| 101 | set_led(' '); | ||
| 102 | /* upper button released */ | ||
| 103 | if ((!(ledpb & 0x0004)) && (c & 0x0004)) { | ||
| 104 | cp = ' '; | ||
| 105 | ledpb = c; | ||
| 106 | if (copy_to_user(buf, &cp, 1)) | ||
| 107 | return -EFAULT; | ||
| 108 | return 1; | ||
| 109 | } | ||
| 110 | /* lower button released */ | ||
| 111 | else if ((!(ledpb & 0x0008)) && (c & 0x0008)) { | ||
| 112 | cp = '\r'; | ||
| 113 | ledpb = c; | ||
| 114 | if (copy_to_user(buf, &cp, 1)) | ||
| 115 | return -EFAULT; | ||
| 116 | return 1; | ||
| 117 | } else { | ||
| 118 | ledpb = c; | ||
| 119 | return 0; | ||
| 120 | } | ||
| 121 | } | ||
| 122 | |||
| 123 | static void scroll_vfd( void ) | ||
| 124 | { | ||
| 125 | int i; | ||
| 126 | |||
| 127 | for (i=0; i<20; i++) { | ||
| 128 | vfd[i] = vfd[i+20]; | ||
| 129 | vfd[i+20] = ' '; | ||
| 130 | } | ||
| 131 | vfd_cursor = 20; | ||
| 132 | } | ||
| 133 | |||
| 134 | static ssize_t briq_panel_write(struct file *file, const char __user *buf, size_t len, | ||
| 135 | loff_t *ppos) | ||
| 136 | { | ||
| 137 | size_t indx = len; | ||
| 138 | int i, esc = 0; | ||
| 139 | |||
| 140 | if (!vfd_is_open) | ||
| 141 | return -EBUSY; | ||
| 142 | |||
| 143 | for (;;) { | ||
| 144 | char c; | ||
| 145 | if (!indx) | ||
| 146 | break; | ||
| 147 | if (get_user(c, buf)) | ||
| 148 | return -EFAULT; | ||
| 149 | if (esc) { | ||
| 150 | set_led(c); | ||
| 151 | esc = 0; | ||
| 152 | } else if (c == 27) { | ||
| 153 | esc = 1; | ||
| 154 | } else if (c == 12) { | ||
| 155 | /* do a form feed */ | ||
| 156 | for (i=0; i<40; i++) | ||
| 157 | vfd[i] = ' '; | ||
| 158 | vfd_cursor = 0; | ||
| 159 | } else if (c == 10) { | ||
| 160 | if (vfd_cursor < 20) | ||
| 161 | vfd_cursor = 20; | ||
| 162 | else if (vfd_cursor < 40) | ||
| 163 | vfd_cursor = 40; | ||
| 164 | else if (vfd_cursor < 60) | ||
| 165 | vfd_cursor = 60; | ||
| 166 | if (vfd_cursor > 59) | ||
| 167 | scroll_vfd(); | ||
| 168 | } else { | ||
| 169 | /* just a character */ | ||
| 170 | if (vfd_cursor > 39) | ||
| 171 | scroll_vfd(); | ||
| 172 | vfd[vfd_cursor++] = c; | ||
| 173 | } | ||
| 174 | indx--; | ||
| 175 | buf++; | ||
| 176 | } | ||
| 177 | update_vfd(); | ||
| 178 | |||
| 179 | return len; | ||
| 180 | } | ||
| 181 | |||
| 182 | static const struct file_operations briq_panel_fops = { | ||
| 183 | .owner = THIS_MODULE, | ||
| 184 | .read = briq_panel_read, | ||
| 185 | .write = briq_panel_write, | ||
| 186 | .open = briq_panel_open, | ||
| 187 | .release = briq_panel_release, | ||
| 188 | .llseek = noop_llseek, | ||
| 189 | }; | ||
| 190 | |||
| 191 | static struct miscdevice briq_panel_miscdev = { | ||
| 192 | BRIQ_PANEL_MINOR, | ||
| 193 | "briq_panel", | ||
| 194 | &briq_panel_fops | ||
| 195 | }; | ||
| 196 | |||
| 197 | static int __init briq_panel_init(void) | ||
| 198 | { | ||
| 199 | struct device_node *root = of_find_node_by_path("/"); | ||
| 200 | const char *machine; | ||
| 201 | int i; | ||
| 202 | |||
| 203 | machine = of_get_property(root, "model", NULL); | ||
| 204 | if (!machine || strncmp(machine, "TotalImpact,BRIQ-1", 18) != 0) { | ||
| 205 | of_node_put(root); | ||
| 206 | return -ENODEV; | ||
| 207 | } | ||
| 208 | of_node_put(root); | ||
| 209 | |||
| 210 | printk(KERN_INFO | ||
| 211 | "briq_panel: v%s Dr. Karsten Jeppesen (kj@totalimpact.com)\n", | ||
| 212 | BRIQ_PANEL_VER); | ||
| 213 | |||
| 214 | if (!request_region(BRIQ_PANEL_VFD_IOPORT, 4, "BRIQ Front Panel")) | ||
| 215 | return -EBUSY; | ||
| 216 | |||
| 217 | if (!request_region(BRIQ_PANEL_LED_IOPORT, 2, "BRIQ Front Panel")) { | ||
| 218 | release_region(BRIQ_PANEL_VFD_IOPORT, 4); | ||
| 219 | return -EBUSY; | ||
| 220 | } | ||
| 221 | ledpb = inb(BRIQ_PANEL_LED_IOPORT) & 0x000c; | ||
| 222 | |||
| 223 | if (misc_register(&briq_panel_miscdev) < 0) { | ||
| 224 | release_region(BRIQ_PANEL_VFD_IOPORT, 4); | ||
| 225 | release_region(BRIQ_PANEL_LED_IOPORT, 2); | ||
| 226 | return -EBUSY; | ||
| 227 | } | ||
| 228 | |||
| 229 | outb(0x38, BRIQ_PANEL_VFD_IOPORT); /* Function set */ | ||
| 230 | outb(0x01, BRIQ_PANEL_VFD_IOPORT); /* Clear display */ | ||
| 231 | outb(0x0c, BRIQ_PANEL_VFD_IOPORT); /* Display on */ | ||
| 232 | outb(0x06, BRIQ_PANEL_VFD_IOPORT); /* Entry normal */ | ||
| 233 | for (i=0; i<40; i++) | ||
| 234 | vfd[i]=' '; | ||
| 235 | #ifndef MODULE | ||
| 236 | vfd[0] = 'L'; | ||
| 237 | vfd[1] = 'o'; | ||
| 238 | vfd[2] = 'a'; | ||
| 239 | vfd[3] = 'd'; | ||
| 240 | vfd[4] = 'i'; | ||
| 241 | vfd[5] = 'n'; | ||
| 242 | vfd[6] = 'g'; | ||
| 243 | vfd[7] = ' '; | ||
| 244 | vfd[8] = '.'; | ||
| 245 | vfd[9] = '.'; | ||
| 246 | vfd[10] = '.'; | ||
| 247 | #endif /* !MODULE */ | ||
| 248 | |||
| 249 | update_vfd(); | ||
| 250 | |||
| 251 | return 0; | ||
| 252 | } | ||
| 253 | |||
| 254 | static void __exit briq_panel_exit(void) | ||
| 255 | { | ||
| 256 | misc_deregister(&briq_panel_miscdev); | ||
| 257 | release_region(BRIQ_PANEL_VFD_IOPORT, 4); | ||
| 258 | release_region(BRIQ_PANEL_LED_IOPORT, 2); | ||
| 259 | } | ||
| 260 | |||
| 261 | module_init(briq_panel_init); | ||
| 262 | module_exit(briq_panel_exit); | ||
| 263 | |||
| 264 | MODULE_LICENSE("GPL"); | ||
| 265 | MODULE_AUTHOR("Karsten Jeppesen <karsten@jeppesens.com>"); | ||
| 266 | MODULE_DESCRIPTION("Driver for the Total Impact briQ front panel"); | ||
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 07f6a5abe372..f6453df4921c 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
| @@ -2484,7 +2484,7 @@ static int mgslpc_open(struct tty_struct *tty, struct file * filp) | |||
| 2484 | 2484 | ||
| 2485 | /* verify range of specified line number */ | 2485 | /* verify range of specified line number */ |
| 2486 | line = tty->index; | 2486 | line = tty->index; |
| 2487 | if ((line < 0) || (line >= mgslpc_device_count)) { | 2487 | if (line >= mgslpc_device_count) { |
| 2488 | printk("%s(%d):mgslpc_open with invalid line #%d.\n", | 2488 | printk("%s(%d):mgslpc_open with invalid line #%d.\n", |
| 2489 | __FILE__,__LINE__,line); | 2489 | __FILE__,__LINE__,line); |
| 2490 | return -ENODEV; | 2490 | return -ENODEV; |
| @@ -2836,7 +2836,6 @@ static int __init synclink_cs_init(void) | |||
| 2836 | 2836 | ||
| 2837 | /* Initialize the tty_driver structure */ | 2837 | /* Initialize the tty_driver structure */ |
| 2838 | 2838 | ||
| 2839 | serial_driver->owner = THIS_MODULE; | ||
| 2840 | serial_driver->driver_name = "synclink_cs"; | 2839 | serial_driver->driver_name = "synclink_cs"; |
| 2841 | serial_driver->name = "ttySLP"; | 2840 | serial_driver->name = "ttySLP"; |
| 2842 | serial_driver->major = ttymajor; | 2841 | serial_driver->major = ttymajor; |
diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c index eedd5474850c..46b77ede84c0 100644 --- a/drivers/char/ttyprintk.c +++ b/drivers/char/ttyprintk.c | |||
| @@ -184,12 +184,10 @@ static int __init ttyprintk_init(void) | |||
| 184 | if (!ttyprintk_driver) | 184 | if (!ttyprintk_driver) |
| 185 | return ret; | 185 | return ret; |
| 186 | 186 | ||
| 187 | ttyprintk_driver->owner = THIS_MODULE; | ||
| 188 | ttyprintk_driver->driver_name = "ttyprintk"; | 187 | ttyprintk_driver->driver_name = "ttyprintk"; |
| 189 | ttyprintk_driver->name = "ttyprintk"; | 188 | ttyprintk_driver->name = "ttyprintk"; |
| 190 | ttyprintk_driver->major = TTYAUX_MAJOR; | 189 | ttyprintk_driver->major = TTYAUX_MAJOR; |
| 191 | ttyprintk_driver->minor_start = 3; | 190 | ttyprintk_driver->minor_start = 3; |
| 192 | ttyprintk_driver->num = 1; | ||
| 193 | ttyprintk_driver->type = TTY_DRIVER_TYPE_CONSOLE; | 191 | ttyprintk_driver->type = TTY_DRIVER_TYPE_CONSOLE; |
| 194 | ttyprintk_driver->init_termios = tty_std_termios; | 192 | ttyprintk_driver->init_termios = tty_std_termios; |
| 195 | ttyprintk_driver->init_termios.c_oflag = OPOST | OCRNL | ONOCR | ONLRET; | 193 | ttyprintk_driver->init_termios.c_oflag = OPOST | OCRNL | ONOCR | ONLRET; |
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index e44933d58790..3a7905b06e53 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c | |||
| @@ -1013,16 +1013,12 @@ static const struct file_operations capi_fops = | |||
| 1013 | static int | 1013 | static int |
| 1014 | capinc_tty_install(struct tty_driver *driver, struct tty_struct *tty) | 1014 | capinc_tty_install(struct tty_driver *driver, struct tty_struct *tty) |
| 1015 | { | 1015 | { |
| 1016 | int idx = tty->index; | 1016 | struct capiminor *mp = capiminor_get(tty->index); |
| 1017 | struct capiminor *mp = capiminor_get(idx); | 1017 | int ret = tty_standard_install(driver, tty); |
| 1018 | int ret = tty_init_termios(tty); | ||
| 1019 | 1018 | ||
| 1020 | if (ret == 0) { | 1019 | if (ret == 0) |
| 1021 | tty_driver_kref_get(driver); | ||
| 1022 | tty->count++; | ||
| 1023 | tty->driver_data = mp; | 1020 | tty->driver_data = mp; |
| 1024 | driver->ttys[idx] = tty; | 1021 | else |
| 1025 | } else | ||
| 1026 | capiminor_put(mp); | 1022 | capiminor_put(mp); |
| 1027 | return ret; | 1023 | return ret; |
| 1028 | } | 1024 | } |
| @@ -1290,7 +1286,6 @@ static int __init capinc_tty_init(void) | |||
| 1290 | kfree(capiminors); | 1286 | kfree(capiminors); |
| 1291 | return -ENOMEM; | 1287 | return -ENOMEM; |
| 1292 | } | 1288 | } |
| 1293 | drv->owner = THIS_MODULE; | ||
| 1294 | drv->driver_name = "capi_nc"; | 1289 | drv->driver_name = "capi_nc"; |
| 1295 | drv->name = "capi"; | 1290 | drv->name = "capi"; |
| 1296 | drv->major = 0; | 1291 | drv->major = 0; |
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index db621db67f61..880f6ef0e18d 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c | |||
| @@ -720,12 +720,11 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | |||
| 720 | 720 | ||
| 721 | tasklet_init(&cs->event_tasklet, gigaset_handle_event, | 721 | tasklet_init(&cs->event_tasklet, gigaset_handle_event, |
| 722 | (unsigned long) cs); | 722 | (unsigned long) cs); |
| 723 | tty_port_init(&cs->port); | ||
| 723 | cs->commands_pending = 0; | 724 | cs->commands_pending = 0; |
| 724 | cs->cur_at_seq = 0; | 725 | cs->cur_at_seq = 0; |
| 725 | cs->gotfwver = -1; | 726 | cs->gotfwver = -1; |
| 726 | cs->open_count = 0; | ||
| 727 | cs->dev = NULL; | 727 | cs->dev = NULL; |
| 728 | cs->tty = NULL; | ||
| 729 | cs->tty_dev = NULL; | 728 | cs->tty_dev = NULL; |
| 730 | cs->cidmode = cidmode != 0; | 729 | cs->cidmode = cidmode != 0; |
| 731 | cs->tabnocid = gigaset_tab_nocid; | 730 | cs->tabnocid = gigaset_tab_nocid; |
| @@ -1051,8 +1050,6 @@ static struct cardstate *gigaset_get_cs_by_minor(unsigned minor) | |||
| 1051 | 1050 | ||
| 1052 | struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty) | 1051 | struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty) |
| 1053 | { | 1052 | { |
| 1054 | if (tty->index < 0 || tty->index >= tty->driver->num) | ||
| 1055 | return NULL; | ||
| 1056 | return gigaset_get_cs_by_minor(tty->index + tty->driver->minor_start); | 1053 | return gigaset_get_cs_by_minor(tty->index + tty->driver->minor_start); |
| 1057 | } | 1054 | } |
| 1058 | 1055 | ||
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h index 212efaf9a4e4..f877726d664b 100644 --- a/drivers/isdn/gigaset/gigaset.h +++ b/drivers/isdn/gigaset/gigaset.h | |||
| @@ -433,8 +433,7 @@ struct cardstate { | |||
| 433 | spinlock_t cmdlock; | 433 | spinlock_t cmdlock; |
| 434 | unsigned curlen, cmdbytes; | 434 | unsigned curlen, cmdbytes; |
| 435 | 435 | ||
| 436 | unsigned open_count; | 436 | struct tty_port port; |
| 437 | struct tty_struct *tty; | ||
| 438 | struct tasklet_struct if_wake_tasklet; | 437 | struct tasklet_struct if_wake_tasklet; |
| 439 | unsigned control_state; | 438 | unsigned control_state; |
| 440 | 439 | ||
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index ee0a549a933a..8f8814afce86 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c | |||
| @@ -146,13 +146,10 @@ static const struct tty_operations if_ops = { | |||
| 146 | static int if_open(struct tty_struct *tty, struct file *filp) | 146 | static int if_open(struct tty_struct *tty, struct file *filp) |
| 147 | { | 147 | { |
| 148 | struct cardstate *cs; | 148 | struct cardstate *cs; |
| 149 | unsigned long flags; | ||
| 150 | 149 | ||
| 151 | gig_dbg(DEBUG_IF, "%d+%d: %s()", | 150 | gig_dbg(DEBUG_IF, "%d+%d: %s()", |
| 152 | tty->driver->minor_start, tty->index, __func__); | 151 | tty->driver->minor_start, tty->index, __func__); |
| 153 | 152 | ||
| 154 | tty->driver_data = NULL; | ||
| 155 | |||
| 156 | cs = gigaset_get_cs_by_tty(tty); | 153 | cs = gigaset_get_cs_by_tty(tty); |
| 157 | if (!cs || !try_module_get(cs->driver->owner)) | 154 | if (!cs || !try_module_get(cs->driver->owner)) |
| 158 | return -ENODEV; | 155 | return -ENODEV; |
| @@ -163,12 +160,10 @@ static int if_open(struct tty_struct *tty, struct file *filp) | |||
| 163 | } | 160 | } |
| 164 | tty->driver_data = cs; | 161 | tty->driver_data = cs; |
| 165 | 162 | ||
| 166 | ++cs->open_count; | 163 | ++cs->port.count; |
| 167 | 164 | ||
| 168 | if (cs->open_count == 1) { | 165 | if (cs->port.count == 1) { |
| 169 | spin_lock_irqsave(&cs->lock, flags); | 166 | tty_port_tty_set(&cs->port, tty); |
| 170 | cs->tty = tty; | ||
| 171 | spin_unlock_irqrestore(&cs->lock, flags); | ||
| 172 | tty->low_latency = 1; | 167 | tty->low_latency = 1; |
| 173 | } | 168 | } |
| 174 | 169 | ||
| @@ -178,12 +173,10 @@ static int if_open(struct tty_struct *tty, struct file *filp) | |||
| 178 | 173 | ||
| 179 | static void if_close(struct tty_struct *tty, struct file *filp) | 174 | static void if_close(struct tty_struct *tty, struct file *filp) |
| 180 | { | 175 | { |
| 181 | struct cardstate *cs; | 176 | struct cardstate *cs = tty->driver_data; |
| 182 | unsigned long flags; | ||
| 183 | 177 | ||
| 184 | cs = (struct cardstate *) tty->driver_data; | 178 | if (!cs) { /* happens if we didn't find cs in open */ |
| 185 | if (!cs) { | 179 | printk(KERN_DEBUG "%s: no cardstate\n", __func__); |
| 186 | pr_err("%s: no cardstate\n", __func__); | ||
| 187 | return; | 180 | return; |
| 188 | } | 181 | } |
| 189 | 182 | ||
| @@ -193,15 +186,10 @@ static void if_close(struct tty_struct *tty, struct file *filp) | |||
| 193 | 186 | ||
| 194 | if (!cs->connected) | 187 | if (!cs->connected) |
| 195 | gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */ | 188 | gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */ |
| 196 | else if (!cs->open_count) | 189 | else if (!cs->port.count) |
| 197 | dev_warn(cs->dev, "%s: device not opened\n", __func__); | 190 | dev_warn(cs->dev, "%s: device not opened\n", __func__); |
| 198 | else { | 191 | else if (!--cs->port.count) |
| 199 | if (!--cs->open_count) { | 192 | tty_port_tty_set(&cs->port, NULL); |
| 200 | spin_lock_irqsave(&cs->lock, flags); | ||
| 201 | cs->tty = NULL; | ||
| 202 | spin_unlock_irqrestore(&cs->lock, flags); | ||
| 203 | } | ||
| 204 | } | ||
| 205 | 193 | ||
| 206 | mutex_unlock(&cs->mutex); | 194 | mutex_unlock(&cs->mutex); |
| 207 | 195 | ||
| @@ -211,18 +199,12 @@ static void if_close(struct tty_struct *tty, struct file *filp) | |||
| 211 | static int if_ioctl(struct tty_struct *tty, | 199 | static int if_ioctl(struct tty_struct *tty, |
| 212 | unsigned int cmd, unsigned long arg) | 200 | unsigned int cmd, unsigned long arg) |
| 213 | { | 201 | { |
| 214 | struct cardstate *cs; | 202 | struct cardstate *cs = tty->driver_data; |
| 215 | int retval = -ENODEV; | 203 | int retval = -ENODEV; |
| 216 | int int_arg; | 204 | int int_arg; |
| 217 | unsigned char buf[6]; | 205 | unsigned char buf[6]; |
| 218 | unsigned version[4]; | 206 | unsigned version[4]; |
| 219 | 207 | ||
| 220 | cs = (struct cardstate *) tty->driver_data; | ||
| 221 | if (!cs) { | ||
| 222 | pr_err("%s: no cardstate\n", __func__); | ||
| 223 | return -ENODEV; | ||
| 224 | } | ||
| 225 | |||
| 226 | gig_dbg(DEBUG_IF, "%u: %s(0x%x)", cs->minor_index, __func__, cmd); | 208 | gig_dbg(DEBUG_IF, "%u: %s(0x%x)", cs->minor_index, __func__, cmd); |
| 227 | 209 | ||
| 228 | if (mutex_lock_interruptible(&cs->mutex)) | 210 | if (mutex_lock_interruptible(&cs->mutex)) |
| @@ -231,9 +213,7 @@ static int if_ioctl(struct tty_struct *tty, | |||
| 231 | if (!cs->connected) { | 213 | if (!cs->connected) { |
| 232 | gig_dbg(DEBUG_IF, "not connected"); | 214 | gig_dbg(DEBUG_IF, "not connected"); |
| 233 | retval = -ENODEV; | 215 | retval = -ENODEV; |
| 234 | } else if (!cs->open_count) | 216 | } else { |
| 235 | dev_warn(cs->dev, "%s: device not opened\n", __func__); | ||
| 236 | else { | ||
| 237 | retval = 0; | 217 | retval = 0; |
| 238 | switch (cmd) { | 218 | switch (cmd) { |
| 239 | case GIGASET_REDIR: | 219 | case GIGASET_REDIR: |
| @@ -285,15 +265,9 @@ static int if_ioctl(struct tty_struct *tty, | |||
| 285 | 265 | ||
| 286 | static int if_tiocmget(struct tty_struct *tty) | 266 | static int if_tiocmget(struct tty_struct *tty) |
| 287 | { | 267 | { |
| 288 | struct cardstate *cs; | 268 | struct cardstate *cs = tty->driver_data; |
| 289 | int retval; | 269 | int retval; |
| 290 | 270 | ||
| 291 | cs = (struct cardstate *) tty->driver_data; | ||
| 292 | if (!cs) { | ||
| 293 | pr_err("%s: no cardstate\n", __func__); | ||
| 294 | return -ENODEV; | ||
| 295 | } | ||
| 296 | |||
| 297 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); | 271 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); |
| 298 | 272 | ||
| 299 | if (mutex_lock_interruptible(&cs->mutex)) | 273 | if (mutex_lock_interruptible(&cs->mutex)) |
| @@ -309,16 +283,10 @@ static int if_tiocmget(struct tty_struct *tty) | |||
| 309 | static int if_tiocmset(struct tty_struct *tty, | 283 | static int if_tiocmset(struct tty_struct *tty, |
| 310 | unsigned int set, unsigned int clear) | 284 | unsigned int set, unsigned int clear) |
| 311 | { | 285 | { |
| 312 | struct cardstate *cs; | 286 | struct cardstate *cs = tty->driver_data; |
| 313 | int retval; | 287 | int retval; |
| 314 | unsigned mc; | 288 | unsigned mc; |
| 315 | 289 | ||
| 316 | cs = (struct cardstate *) tty->driver_data; | ||
| 317 | if (!cs) { | ||
| 318 | pr_err("%s: no cardstate\n", __func__); | ||
| 319 | return -ENODEV; | ||
| 320 | } | ||
| 321 | |||
| 322 | gig_dbg(DEBUG_IF, "%u: %s(0x%x, 0x%x)", | 290 | gig_dbg(DEBUG_IF, "%u: %s(0x%x, 0x%x)", |
| 323 | cs->minor_index, __func__, set, clear); | 291 | cs->minor_index, __func__, set, clear); |
| 324 | 292 | ||
| @@ -341,16 +309,10 @@ static int if_tiocmset(struct tty_struct *tty, | |||
| 341 | 309 | ||
| 342 | static int if_write(struct tty_struct *tty, const unsigned char *buf, int count) | 310 | static int if_write(struct tty_struct *tty, const unsigned char *buf, int count) |
| 343 | { | 311 | { |
| 344 | struct cardstate *cs; | 312 | struct cardstate *cs = tty->driver_data; |
| 345 | struct cmdbuf_t *cb; | 313 | struct cmdbuf_t *cb; |
| 346 | int retval; | 314 | int retval; |
| 347 | 315 | ||
| 348 | cs = (struct cardstate *) tty->driver_data; | ||
| 349 | if (!cs) { | ||
| 350 | pr_err("%s: no cardstate\n", __func__); | ||
| 351 | return -ENODEV; | ||
| 352 | } | ||
| 353 | |||
| 354 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); | 316 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); |
| 355 | 317 | ||
| 356 | if (mutex_lock_interruptible(&cs->mutex)) | 318 | if (mutex_lock_interruptible(&cs->mutex)) |
| @@ -361,11 +323,6 @@ static int if_write(struct tty_struct *tty, const unsigned char *buf, int count) | |||
| 361 | retval = -ENODEV; | 323 | retval = -ENODEV; |
| 362 | goto done; | 324 | goto done; |
| 363 | } | 325 | } |
| 364 | if (!cs->open_count) { | ||
| 365 | dev_warn(cs->dev, "%s: device not opened\n", __func__); | ||
| 366 | retval = -ENODEV; | ||
| 367 | goto done; | ||
| 368 | } | ||
| 369 | if (cs->mstate != MS_LOCKED) { | 326 | if (cs->mstate != MS_LOCKED) { |
| 370 | dev_warn(cs->dev, "can't write to unlocked device\n"); | 327 | dev_warn(cs->dev, "can't write to unlocked device\n"); |
| 371 | retval = -EBUSY; | 328 | retval = -EBUSY; |
| @@ -397,15 +354,9 @@ done: | |||
| 397 | 354 | ||
| 398 | static int if_write_room(struct tty_struct *tty) | 355 | static int if_write_room(struct tty_struct *tty) |
| 399 | { | 356 | { |
| 400 | struct cardstate *cs; | 357 | struct cardstate *cs = tty->driver_data; |
| 401 | int retval = -ENODEV; | 358 | int retval = -ENODEV; |
| 402 | 359 | ||
| 403 | cs = (struct cardstate *) tty->driver_data; | ||
| 404 | if (!cs) { | ||
| 405 | pr_err("%s: no cardstate\n", __func__); | ||
| 406 | return -ENODEV; | ||
| 407 | } | ||
| 408 | |||
| 409 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); | 360 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); |
| 410 | 361 | ||
| 411 | if (mutex_lock_interruptible(&cs->mutex)) | 362 | if (mutex_lock_interruptible(&cs->mutex)) |
| @@ -414,9 +365,7 @@ static int if_write_room(struct tty_struct *tty) | |||
| 414 | if (!cs->connected) { | 365 | if (!cs->connected) { |
| 415 | gig_dbg(DEBUG_IF, "not connected"); | 366 | gig_dbg(DEBUG_IF, "not connected"); |
| 416 | retval = -ENODEV; | 367 | retval = -ENODEV; |
| 417 | } else if (!cs->open_count) | 368 | } else if (cs->mstate != MS_LOCKED) { |
| 418 | dev_warn(cs->dev, "%s: device not opened\n", __func__); | ||
| 419 | else if (cs->mstate != MS_LOCKED) { | ||
| 420 | dev_warn(cs->dev, "can't write to unlocked device\n"); | 369 | dev_warn(cs->dev, "can't write to unlocked device\n"); |
| 421 | retval = -EBUSY; | 370 | retval = -EBUSY; |
| 422 | } else | 371 | } else |
| @@ -429,23 +378,15 @@ static int if_write_room(struct tty_struct *tty) | |||
| 429 | 378 | ||
| 430 | static int if_chars_in_buffer(struct tty_struct *tty) | 379 | static int if_chars_in_buffer(struct tty_struct *tty) |
| 431 | { | 380 | { |
| 432 | struct cardstate *cs; | 381 | struct cardstate *cs = tty->driver_data; |
| 433 | int retval = 0; | 382 | int retval = 0; |
| 434 | 383 | ||
| 435 | cs = (struct cardstate *) tty->driver_data; | ||
| 436 | if (!cs) { | ||
| 437 | pr_err("%s: no cardstate\n", __func__); | ||
| 438 | return 0; | ||
| 439 | } | ||
| 440 | |||
| 441 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); | 384 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); |
| 442 | 385 | ||
| 443 | mutex_lock(&cs->mutex); | 386 | mutex_lock(&cs->mutex); |
| 444 | 387 | ||
| 445 | if (!cs->connected) | 388 | if (!cs->connected) |
| 446 | gig_dbg(DEBUG_IF, "not connected"); | 389 | gig_dbg(DEBUG_IF, "not connected"); |
| 447 | else if (!cs->open_count) | ||
| 448 | dev_warn(cs->dev, "%s: device not opened\n", __func__); | ||
| 449 | else if (cs->mstate != MS_LOCKED) | 390 | else if (cs->mstate != MS_LOCKED) |
| 450 | dev_warn(cs->dev, "can't write to unlocked device\n"); | 391 | dev_warn(cs->dev, "can't write to unlocked device\n"); |
| 451 | else | 392 | else |
| @@ -458,13 +399,7 @@ static int if_chars_in_buffer(struct tty_struct *tty) | |||
| 458 | 399 | ||
| 459 | static void if_throttle(struct tty_struct *tty) | 400 | static void if_throttle(struct tty_struct *tty) |
| 460 | { | 401 | { |
| 461 | struct cardstate *cs; | 402 | struct cardstate *cs = tty->driver_data; |
| 462 | |||
| 463 | cs = (struct cardstate *) tty->driver_data; | ||
| 464 | if (!cs) { | ||
| 465 | pr_err("%s: no cardstate\n", __func__); | ||
| 466 | return; | ||
| 467 | } | ||
| 468 | 403 | ||
| 469 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); | 404 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); |
| 470 | 405 | ||
| @@ -472,8 +407,6 @@ static void if_throttle(struct tty_struct *tty) | |||
| 472 | 407 | ||
| 473 | if (!cs->connected) | 408 | if (!cs->connected) |
| 474 | gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */ | 409 | gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */ |
| 475 | else if (!cs->open_count) | ||
| 476 | dev_warn(cs->dev, "%s: device not opened\n", __func__); | ||
| 477 | else | 410 | else |
| 478 | gig_dbg(DEBUG_IF, "%s: not implemented\n", __func__); | 411 | gig_dbg(DEBUG_IF, "%s: not implemented\n", __func__); |
| 479 | 412 | ||
| @@ -482,13 +415,7 @@ static void if_throttle(struct tty_struct *tty) | |||
| 482 | 415 | ||
| 483 | static void if_unthrottle(struct tty_struct *tty) | 416 | static void if_unthrottle(struct tty_struct *tty) |
| 484 | { | 417 | { |
| 485 | struct cardstate *cs; | 418 | struct cardstate *cs = tty->driver_data; |
| 486 | |||
| 487 | cs = (struct cardstate *) tty->driver_data; | ||
| 488 | if (!cs) { | ||
| 489 | pr_err("%s: no cardstate\n", __func__); | ||
| 490 | return; | ||
| 491 | } | ||
| 492 | 419 | ||
| 493 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); | 420 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); |
| 494 | 421 | ||
| @@ -496,8 +423,6 @@ static void if_unthrottle(struct tty_struct *tty) | |||
| 496 | 423 | ||
| 497 | if (!cs->connected) | 424 | if (!cs->connected) |
| 498 | gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */ | 425 | gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */ |
| 499 | else if (!cs->open_count) | ||
| 500 | dev_warn(cs->dev, "%s: device not opened\n", __func__); | ||
| 501 | else | 426 | else |
| 502 | gig_dbg(DEBUG_IF, "%s: not implemented\n", __func__); | 427 | gig_dbg(DEBUG_IF, "%s: not implemented\n", __func__); |
| 503 | 428 | ||
| @@ -506,18 +431,12 @@ static void if_unthrottle(struct tty_struct *tty) | |||
| 506 | 431 | ||
| 507 | static void if_set_termios(struct tty_struct *tty, struct ktermios *old) | 432 | static void if_set_termios(struct tty_struct *tty, struct ktermios *old) |
| 508 | { | 433 | { |
| 509 | struct cardstate *cs; | 434 | struct cardstate *cs = tty->driver_data; |
| 510 | unsigned int iflag; | 435 | unsigned int iflag; |
| 511 | unsigned int cflag; | 436 | unsigned int cflag; |
| 512 | unsigned int old_cflag; | 437 | unsigned int old_cflag; |
| 513 | unsigned int control_state, new_state; | 438 | unsigned int control_state, new_state; |
| 514 | 439 | ||
| 515 | cs = (struct cardstate *) tty->driver_data; | ||
| 516 | if (!cs) { | ||
| 517 | pr_err("%s: no cardstate\n", __func__); | ||
| 518 | return; | ||
| 519 | } | ||
| 520 | |||
| 521 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); | 440 | gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); |
| 522 | 441 | ||
| 523 | mutex_lock(&cs->mutex); | 442 | mutex_lock(&cs->mutex); |
| @@ -527,11 +446,6 @@ static void if_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
| 527 | goto out; | 446 | goto out; |
| 528 | } | 447 | } |
| 529 | 448 | ||
| 530 | if (!cs->open_count) { | ||
| 531 | dev_warn(cs->dev, "%s: device not opened\n", __func__); | ||
| 532 | goto out; | ||
| 533 | } | ||
| 534 | |||
| 535 | iflag = tty->termios->c_iflag; | 449 | iflag = tty->termios->c_iflag; |
| 536 | cflag = tty->termios->c_cflag; | 450 | cflag = tty->termios->c_cflag; |
| 537 | old_cflag = old ? old->c_cflag : cflag; | 451 | old_cflag = old ? old->c_cflag : cflag; |
| @@ -588,10 +502,13 @@ out: | |||
| 588 | /* wakeup tasklet for the write operation */ | 502 | /* wakeup tasklet for the write operation */ |
| 589 | static void if_wake(unsigned long data) | 503 | static void if_wake(unsigned long data) |
| 590 | { | 504 | { |
| 591 | struct cardstate *cs = (struct cardstate *) data; | 505 | struct cardstate *cs = (struct cardstate *)data; |
| 506 | struct tty_struct *tty = tty_port_tty_get(&cs->port); | ||
| 592 | 507 | ||
| 593 | if (cs->tty) | 508 | if (tty) { |
| 594 | tty_wakeup(cs->tty); | 509 | tty_wakeup(tty); |
| 510 | tty_kref_put(tty); | ||
| 511 | } | ||
| 595 | } | 512 | } |
| 596 | 513 | ||
| 597 | /*** interface to common ***/ | 514 | /*** interface to common ***/ |
| @@ -644,18 +561,16 @@ void gigaset_if_free(struct cardstate *cs) | |||
| 644 | void gigaset_if_receive(struct cardstate *cs, | 561 | void gigaset_if_receive(struct cardstate *cs, |
| 645 | unsigned char *buffer, size_t len) | 562 | unsigned char *buffer, size_t len) |
| 646 | { | 563 | { |
| 647 | unsigned long flags; | 564 | struct tty_struct *tty = tty_port_tty_get(&cs->port); |
| 648 | struct tty_struct *tty; | ||
| 649 | 565 | ||
| 650 | spin_lock_irqsave(&cs->lock, flags); | 566 | if (tty == NULL) { |
| 651 | tty = cs->tty; | ||
| 652 | if (tty == NULL) | ||
| 653 | gig_dbg(DEBUG_IF, "receive on closed device"); | 567 | gig_dbg(DEBUG_IF, "receive on closed device"); |
| 654 | else { | 568 | return; |
| 655 | tty_insert_flip_string(tty, buffer, len); | ||
| 656 | tty_flip_buffer_push(tty); | ||
| 657 | } | 569 | } |
| 658 | spin_unlock_irqrestore(&cs->lock, flags); | 570 | |
| 571 | tty_insert_flip_string(tty, buffer, len); | ||
| 572 | tty_flip_buffer_push(tty); | ||
| 573 | tty_kref_put(tty); | ||
| 659 | } | 574 | } |
| 660 | EXPORT_SYMBOL_GPL(gigaset_if_receive); | 575 | EXPORT_SYMBOL_GPL(gigaset_if_receive); |
| 661 | 576 | ||
| @@ -669,17 +584,15 @@ EXPORT_SYMBOL_GPL(gigaset_if_receive); | |||
| 669 | void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, | 584 | void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, |
| 670 | const char *devname) | 585 | const char *devname) |
| 671 | { | 586 | { |
| 672 | unsigned minors = drv->minors; | ||
| 673 | int ret; | 587 | int ret; |
| 674 | struct tty_driver *tty; | 588 | struct tty_driver *tty; |
| 675 | 589 | ||
| 676 | drv->have_tty = 0; | 590 | drv->have_tty = 0; |
| 677 | 591 | ||
| 678 | drv->tty = tty = alloc_tty_driver(minors); | 592 | drv->tty = tty = alloc_tty_driver(drv->minors); |
| 679 | if (tty == NULL) | 593 | if (tty == NULL) |
| 680 | goto enomem; | 594 | goto enomem; |
| 681 | 595 | ||
| 682 | tty->magic = TTY_DRIVER_MAGIC, | ||
| 683 | tty->type = TTY_DRIVER_TYPE_SERIAL, | 596 | tty->type = TTY_DRIVER_TYPE_SERIAL, |
| 684 | tty->subtype = SERIAL_TYPE_NORMAL, | 597 | tty->subtype = SERIAL_TYPE_NORMAL, |
| 685 | tty->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | 598 | tty->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
| @@ -687,9 +600,6 @@ void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, | |||
| 687 | tty->driver_name = procname; | 600 | tty->driver_name = procname; |
| 688 | tty->name = devname; | 601 | tty->name = devname; |
| 689 | tty->minor_start = drv->minor; | 602 | tty->minor_start = drv->minor; |
| 690 | tty->num = drv->minors; | ||
| 691 | |||
| 692 | tty->owner = THIS_MODULE; | ||
| 693 | 603 | ||
| 694 | tty->init_termios = tty_std_termios; | 604 | tty->init_termios = tty_std_termios; |
| 695 | tty->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 605 | tty->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 2c26b64ebbea..ac4840124bc0 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c | |||
| @@ -1590,12 +1590,9 @@ static int | |||
| 1590 | isdn_tty_open(struct tty_struct *tty, struct file *filp) | 1590 | isdn_tty_open(struct tty_struct *tty, struct file *filp) |
| 1591 | { | 1591 | { |
| 1592 | modem_info *info; | 1592 | modem_info *info; |
| 1593 | int retval, line; | 1593 | int retval; |
| 1594 | 1594 | ||
| 1595 | line = tty->index; | 1595 | info = &dev->mdm.info[tty->index]; |
| 1596 | if (line < 0 || line >= ISDN_MAX_CHANNELS) | ||
| 1597 | return -ENODEV; | ||
| 1598 | info = &dev->mdm.info[line]; | ||
| 1599 | if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_open")) | 1596 | if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_open")) |
| 1600 | return -ENODEV; | 1597 | return -ENODEV; |
| 1601 | if (!try_module_get(info->owner)) { | 1598 | if (!try_module_get(info->owner)) { |
diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c index 0b56e3f43573..383133b201a1 100644 --- a/drivers/misc/pti.c +++ b/drivers/misc/pti.c | |||
| @@ -481,13 +481,9 @@ static int pti_tty_install(struct tty_driver *driver, struct tty_struct *tty) | |||
| 481 | { | 481 | { |
| 482 | int idx = tty->index; | 482 | int idx = tty->index; |
| 483 | struct pti_tty *pti_tty_data; | 483 | struct pti_tty *pti_tty_data; |
| 484 | int ret = tty_init_termios(tty); | 484 | int ret = tty_standard_install(driver, tty); |
| 485 | 485 | ||
| 486 | if (ret == 0) { | 486 | if (ret == 0) { |
| 487 | tty_driver_kref_get(driver); | ||
| 488 | tty->count++; | ||
| 489 | driver->ttys[idx] = tty; | ||
| 490 | |||
| 491 | pti_tty_data = kmalloc(sizeof(struct pti_tty), GFP_KERNEL); | 487 | pti_tty_data = kmalloc(sizeof(struct pti_tty), GFP_KERNEL); |
| 492 | if (pti_tty_data == NULL) | 488 | if (pti_tty_data == NULL) |
| 493 | return -ENOMEM; | 489 | return -ENOMEM; |
| @@ -911,21 +907,17 @@ static int __init pti_init(void) | |||
| 911 | 907 | ||
| 912 | /* First register module as tty device */ | 908 | /* First register module as tty device */ |
| 913 | 909 | ||
| 914 | pti_tty_driver = alloc_tty_driver(1); | 910 | pti_tty_driver = alloc_tty_driver(PTITTY_MINOR_NUM); |
| 915 | if (pti_tty_driver == NULL) { | 911 | if (pti_tty_driver == NULL) { |
| 916 | pr_err("%s(%d): Memory allocation failed for ptiTTY driver\n", | 912 | pr_err("%s(%d): Memory allocation failed for ptiTTY driver\n", |
| 917 | __func__, __LINE__); | 913 | __func__, __LINE__); |
| 918 | return -ENOMEM; | 914 | return -ENOMEM; |
| 919 | } | 915 | } |
| 920 | 916 | ||
| 921 | pti_tty_driver->owner = THIS_MODULE; | ||
| 922 | pti_tty_driver->magic = TTY_DRIVER_MAGIC; | ||
| 923 | pti_tty_driver->driver_name = DRIVERNAME; | 917 | pti_tty_driver->driver_name = DRIVERNAME; |
| 924 | pti_tty_driver->name = TTYNAME; | 918 | pti_tty_driver->name = TTYNAME; |
| 925 | pti_tty_driver->major = 0; | 919 | pti_tty_driver->major = 0; |
| 926 | pti_tty_driver->minor_start = PTITTY_MINOR_START; | 920 | pti_tty_driver->minor_start = PTITTY_MINOR_START; |
| 927 | pti_tty_driver->minor_num = PTITTY_MINOR_NUM; | ||
| 928 | pti_tty_driver->num = PTITTY_MINOR_NUM; | ||
| 929 | pti_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM; | 921 | pti_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM; |
| 930 | pti_tty_driver->subtype = SYSTEM_TYPE_SYSCONS; | 922 | pti_tty_driver->subtype = SYSTEM_TYPE_SYSCONS; |
| 931 | pti_tty_driver->flags = TTY_DRIVER_REAL_RAW | | 923 | pti_tty_driver->flags = TTY_DRIVER_REAL_RAW | |
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index 2c151e18c9e8..5a2cbfac66d2 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c | |||
| @@ -750,15 +750,12 @@ static int sdio_uart_install(struct tty_driver *driver, struct tty_struct *tty) | |||
| 750 | { | 750 | { |
| 751 | int idx = tty->index; | 751 | int idx = tty->index; |
| 752 | struct sdio_uart_port *port = sdio_uart_port_get(idx); | 752 | struct sdio_uart_port *port = sdio_uart_port_get(idx); |
| 753 | int ret = tty_init_termios(tty); | 753 | int ret = tty_standard_install(driver, tty); |
| 754 | 754 | ||
| 755 | if (ret == 0) { | 755 | if (ret == 0) |
| 756 | tty_driver_kref_get(driver); | ||
| 757 | tty->count++; | ||
| 758 | /* This is the ref sdio_uart_port get provided */ | 756 | /* This is the ref sdio_uart_port get provided */ |
| 759 | tty->driver_data = port; | 757 | tty->driver_data = port; |
| 760 | driver->ttys[idx] = tty; | 758 | else |
| 761 | } else | ||
| 762 | sdio_uart_port_put(port); | 759 | sdio_uart_port_put(port); |
| 763 | return ret; | 760 | return ret; |
| 764 | } | 761 | } |
| @@ -1178,7 +1175,6 @@ static int __init sdio_uart_init(void) | |||
| 1178 | if (!tty_drv) | 1175 | if (!tty_drv) |
| 1179 | return -ENOMEM; | 1176 | return -ENOMEM; |
| 1180 | 1177 | ||
| 1181 | tty_drv->owner = THIS_MODULE; | ||
| 1182 | tty_drv->driver_name = "sdio_uart"; | 1178 | tty_drv->driver_name = "sdio_uart"; |
| 1183 | tty_drv->name = "ttySDIO"; | 1179 | tty_drv->name = "ttySDIO"; |
| 1184 | tty_drv->major = 0; /* dynamically allocated */ | 1180 | tty_drv->major = 0; /* dynamically allocated */ |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index e1324b4a0f66..2d2a6882ba33 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
| @@ -3313,7 +3313,6 @@ static int __init hso_init(void) | |||
| 3313 | 3313 | ||
| 3314 | /* fill in all needed values */ | 3314 | /* fill in all needed values */ |
| 3315 | tty_drv->magic = TTY_DRIVER_MAGIC; | 3315 | tty_drv->magic = TTY_DRIVER_MAGIC; |
| 3316 | tty_drv->owner = THIS_MODULE; | ||
| 3317 | tty_drv->driver_name = driver_name; | 3316 | tty_drv->driver_name = driver_name; |
| 3318 | tty_drv->name = tty_filename; | 3317 | tty_drv->name = tty_filename; |
| 3319 | 3318 | ||
| @@ -3322,7 +3321,6 @@ static int __init hso_init(void) | |||
| 3322 | tty_drv->major = tty_major; | 3321 | tty_drv->major = tty_major; |
| 3323 | 3322 | ||
| 3324 | tty_drv->minor_start = 0; | 3323 | tty_drv->minor_start = 0; |
| 3325 | tty_drv->num = HSO_SERIAL_TTY_MINORS; | ||
| 3326 | tty_drv->type = TTY_DRIVER_TYPE_SERIAL; | 3324 | tty_drv->type = TTY_DRIVER_TYPE_SERIAL; |
| 3327 | tty_drv->subtype = SERIAL_TYPE_NORMAL; | 3325 | tty_drv->subtype = SERIAL_TYPE_NORMAL; |
| 3328 | tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | 3326 | tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c index 1eeedd6a10b1..cb0f8d932b0c 100644 --- a/drivers/net/wan/pc300_drv.c +++ b/drivers/net/wan/pc300_drv.c | |||
| @@ -299,7 +299,6 @@ void cpc_tty_init(pc300dev_t * dev); | |||
| 299 | void cpc_tty_unregister_service(pc300dev_t * pc300dev); | 299 | void cpc_tty_unregister_service(pc300dev_t * pc300dev); |
| 300 | void cpc_tty_receive(pc300dev_t * pc300dev); | 300 | void cpc_tty_receive(pc300dev_t * pc300dev); |
| 301 | void cpc_tty_trigger_poll(pc300dev_t * pc300dev); | 301 | void cpc_tty_trigger_poll(pc300dev_t * pc300dev); |
| 302 | void cpc_tty_reset_var(void); | ||
| 303 | #endif | 302 | #endif |
| 304 | 303 | ||
| 305 | /************************/ | 304 | /************************/ |
| @@ -3232,7 +3231,7 @@ static void plx_init(pc300_t * card) | |||
| 3232 | 3231 | ||
| 3233 | } | 3232 | } |
| 3234 | 3233 | ||
| 3235 | static inline void show_version(void) | 3234 | static void show_version(void) |
| 3236 | { | 3235 | { |
| 3237 | char *rcsvers, *rcsdate, *tmp; | 3236 | char *rcsvers, *rcsdate, *tmp; |
| 3238 | 3237 | ||
| @@ -3413,19 +3412,10 @@ static void cpc_init_card(pc300_t * card) | |||
| 3413 | static int __devinit | 3412 | static int __devinit |
| 3414 | cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 3413 | cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
| 3415 | { | 3414 | { |
| 3416 | static int first_time = 1; | ||
| 3417 | int err, eeprom_outdated = 0; | 3415 | int err, eeprom_outdated = 0; |
| 3418 | u16 device_id; | 3416 | u16 device_id; |
| 3419 | pc300_t *card; | 3417 | pc300_t *card; |
| 3420 | 3418 | ||
| 3421 | if (first_time) { | ||
| 3422 | first_time = 0; | ||
| 3423 | show_version(); | ||
| 3424 | #ifdef CONFIG_PC300_MLPPP | ||
| 3425 | cpc_tty_reset_var(); | ||
| 3426 | #endif | ||
| 3427 | } | ||
| 3428 | |||
| 3429 | if ((err = pci_enable_device(pdev)) < 0) | 3419 | if ((err = pci_enable_device(pdev)) < 0) |
| 3430 | return err; | 3420 | return err; |
| 3431 | 3421 | ||
| @@ -3661,6 +3651,7 @@ static struct pci_driver cpc_driver = { | |||
| 3661 | 3651 | ||
| 3662 | static int __init cpc_init(void) | 3652 | static int __init cpc_init(void) |
| 3663 | { | 3653 | { |
| 3654 | show_version(); | ||
| 3664 | return pci_register_driver(&cpc_driver); | 3655 | return pci_register_driver(&cpc_driver); |
| 3665 | } | 3656 | } |
| 3666 | 3657 | ||
diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c index d47d2cd10475..4709f4228561 100644 --- a/drivers/net/wan/pc300_tty.c +++ b/drivers/net/wan/pc300_tty.c | |||
| @@ -139,7 +139,6 @@ void cpc_tty_init(pc300dev_t *dev); | |||
| 139 | void cpc_tty_unregister_service(pc300dev_t *pc300dev); | 139 | void cpc_tty_unregister_service(pc300dev_t *pc300dev); |
| 140 | void cpc_tty_receive(pc300dev_t *pc300dev); | 140 | void cpc_tty_receive(pc300dev_t *pc300dev); |
| 141 | void cpc_tty_trigger_poll(pc300dev_t *pc300dev); | 141 | void cpc_tty_trigger_poll(pc300dev_t *pc300dev); |
| 142 | void cpc_tty_reset_var(void); | ||
| 143 | 142 | ||
| 144 | /* | 143 | /* |
| 145 | * PC300 TTY clear "signal" | 144 | * PC300 TTY clear "signal" |
| @@ -1078,20 +1077,3 @@ void cpc_tty_trigger_poll(pc300dev_t *pc300dev) | |||
| 1078 | } | 1077 | } |
| 1079 | schedule_work(&(cpc_tty->tty_tx_work)); | 1078 | schedule_work(&(cpc_tty->tty_tx_work)); |
| 1080 | } | 1079 | } |
| 1081 | |||
| 1082 | /* | ||
| 1083 | * PC300 TTY reset var routine | ||
| 1084 | * This routine is called by pc300driver to init the TTY area. | ||
| 1085 | */ | ||
| 1086 | |||
| 1087 | void cpc_tty_reset_var(void) | ||
| 1088 | { | ||
| 1089 | int i ; | ||
| 1090 | |||
| 1091 | CPC_TTY_DBG("hdlcX-tty: reset variables\n"); | ||
| 1092 | /* reset the tty_driver structure - serial_drv */ | ||
| 1093 | memset(&serial_drv, 0, sizeof(struct tty_driver)); | ||
| 1094 | for (i=0; i < CPC_TTY_NPORTS; i++){ | ||
| 1095 | memset(&cpc_tty_area[i],0, sizeof(st_cpc_tty_area)); | ||
| 1096 | } | ||
| 1097 | } | ||
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index e71a50d4b221..4f9f1dcc1551 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c | |||
| @@ -933,13 +933,9 @@ console_initcall(con3215_init); | |||
| 933 | static int tty3215_open(struct tty_struct *tty, struct file * filp) | 933 | static int tty3215_open(struct tty_struct *tty, struct file * filp) |
| 934 | { | 934 | { |
| 935 | struct raw3215_info *raw; | 935 | struct raw3215_info *raw; |
| 936 | int retval, line; | 936 | int retval; |
| 937 | 937 | ||
| 938 | line = tty->index; | 938 | raw = raw3215[tty->index]; |
| 939 | if ((line < 0) || (line >= NR_3215)) | ||
| 940 | return -ENODEV; | ||
| 941 | |||
| 942 | raw = raw3215[line]; | ||
| 943 | if (raw == NULL) | 939 | if (raw == NULL) |
| 944 | return -ENODEV; | 940 | return -ENODEV; |
| 945 | 941 | ||
| @@ -1145,7 +1141,6 @@ static int __init tty3215_init(void) | |||
| 1145 | * proc_entry, set_termios, flush_buffer, set_ldisc, write_proc | 1141 | * proc_entry, set_termios, flush_buffer, set_ldisc, write_proc |
| 1146 | */ | 1142 | */ |
| 1147 | 1143 | ||
| 1148 | driver->owner = THIS_MODULE; | ||
| 1149 | driver->driver_name = "tty3215"; | 1144 | driver->driver_name = "tty3215"; |
| 1150 | driver->name = "ttyS"; | 1145 | driver->name = "ttyS"; |
| 1151 | driver->major = TTY_MAJOR; | 1146 | driver->major = TTY_MAJOR; |
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index a879c139926a..40a9d69c898e 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c | |||
| @@ -551,7 +551,6 @@ sclp_tty_init(void) | |||
| 551 | return rc; | 551 | return rc; |
| 552 | } | 552 | } |
| 553 | 553 | ||
| 554 | driver->owner = THIS_MODULE; | ||
| 555 | driver->driver_name = "sclp_line"; | 554 | driver->driver_name = "sclp_line"; |
| 556 | driver->name = "sclp_line"; | 555 | driver->name = "sclp_line"; |
| 557 | driver->major = TTY_MAJOR; | 556 | driver->major = TTY_MAJOR; |
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index 5d706e6c946f..b635472ae660 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c | |||
| @@ -685,7 +685,6 @@ static int __init sclp_vt220_tty_init(void) | |||
| 685 | if (rc) | 685 | if (rc) |
| 686 | goto out_driver; | 686 | goto out_driver; |
| 687 | 687 | ||
| 688 | driver->owner = THIS_MODULE; | ||
| 689 | driver->driver_name = SCLP_VT220_DRIVER_NAME; | 688 | driver->driver_name = SCLP_VT220_DRIVER_NAME; |
| 690 | driver->name = SCLP_VT220_DEVICE_NAME; | 689 | driver->name = SCLP_VT220_DEVICE_NAME; |
| 691 | driver->major = SCLP_VT220_MAJOR; | 690 | driver->major = SCLP_VT220_MAJOR; |
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index 2db1482b406e..b43445a55cb6 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c | |||
| @@ -1784,7 +1784,6 @@ static int __init tty3270_init(void) | |||
| 1784 | * Entries in tty3270_driver that are NOT initialized: | 1784 | * Entries in tty3270_driver that are NOT initialized: |
| 1785 | * proc_entry, set_termios, flush_buffer, set_ldisc, write_proc | 1785 | * proc_entry, set_termios, flush_buffer, set_ldisc, write_proc |
| 1786 | */ | 1786 | */ |
| 1787 | driver->owner = THIS_MODULE; | ||
| 1788 | driver->driver_name = "ttyTUB"; | 1787 | driver->driver_name = "ttyTUB"; |
| 1789 | driver->name = "ttyTUB"; | 1788 | driver->name = "ttyTUB"; |
| 1790 | driver->major = IBM_TTY3270_MAJOR; | 1789 | driver->major = IBM_TTY3270_MAJOR; |
diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c index c7b03f0ef2dd..92b34e29ad06 100644 --- a/drivers/staging/speakup/main.c +++ b/drivers/staging/speakup/main.c | |||
| @@ -1731,15 +1731,15 @@ static void do_handle_spec(struct vc_data *vc, u_char value, char up_flag) | |||
| 1731 | switch (value) { | 1731 | switch (value) { |
| 1732 | case KVAL(K_CAPS): | 1732 | case KVAL(K_CAPS): |
| 1733 | label = msg_get(MSG_KEYNAME_CAPSLOCK); | 1733 | label = msg_get(MSG_KEYNAME_CAPSLOCK); |
| 1734 | on_off = (vc_kbd_led(kbd_table + vc->vc_num, VC_CAPSLOCK)); | 1734 | on_off = vt_get_leds(fg_console, VC_CAPSLOCK); |
| 1735 | break; | 1735 | break; |
| 1736 | case KVAL(K_NUM): | 1736 | case KVAL(K_NUM): |
| 1737 | label = msg_get(MSG_KEYNAME_NUMLOCK); | 1737 | label = msg_get(MSG_KEYNAME_NUMLOCK); |
| 1738 | on_off = (vc_kbd_led(kbd_table + vc->vc_num, VC_NUMLOCK)); | 1738 | on_off = vt_get_leds(fg_console, VC_NUMLOCK); |
| 1739 | break; | 1739 | break; |
| 1740 | case KVAL(K_HOLD): | 1740 | case KVAL(K_HOLD): |
| 1741 | label = msg_get(MSG_KEYNAME_SCROLLLOCK); | 1741 | label = msg_get(MSG_KEYNAME_SCROLLLOCK); |
| 1742 | on_off = (vc_kbd_led(kbd_table + vc->vc_num, VC_SCROLLOCK)); | 1742 | on_off = vt_get_leds(fg_console, VC_SCROLLOCK); |
| 1743 | if (speakup_console[vc->vc_num]) | 1743 | if (speakup_console[vc->vc_num]) |
| 1744 | speakup_console[vc->vc_num]->tty_stopped = on_off; | 1744 | speakup_console[vc->vc_num]->tty_stopped = on_off; |
| 1745 | break; | 1745 | break; |
| @@ -2020,7 +2020,7 @@ speakup_key(struct vc_data *vc, int shift_state, int keycode, u_short keysym, | |||
| 2020 | if (type >= 0xf0) | 2020 | if (type >= 0xf0) |
| 2021 | type -= 0xf0; | 2021 | type -= 0xf0; |
| 2022 | if (type == KT_PAD | 2022 | if (type == KT_PAD |
| 2023 | && (vc_kbd_led(kbd_table + fg_console, VC_NUMLOCK))) { | 2023 | && (vt_get_leds(fg_console, VC_NUMLOCK))) { |
| 2024 | if (up_flag) { | 2024 | if (up_flag) { |
| 2025 | spk_keydown = 0; | 2025 | spk_keydown = 0; |
| 2026 | goto out; | 2026 | goto out; |
diff --git a/drivers/staging/speakup/serialio.c b/drivers/staging/speakup/serialio.c index 7f3d87bf5927..a97d3d5b58a4 100644 --- a/drivers/staging/speakup/serialio.c +++ b/drivers/staging/speakup/serialio.c | |||
| @@ -8,21 +8,20 @@ | |||
| 8 | 8 | ||
| 9 | static void start_serial_interrupt(int irq); | 9 | static void start_serial_interrupt(int irq); |
| 10 | 10 | ||
| 11 | static struct serial_state rs_table[] = { | 11 | static const struct old_serial_port rs_table[] = { |
| 12 | SERIAL_PORT_DFNS | 12 | SERIAL_PORT_DFNS |
| 13 | }; | 13 | }; |
| 14 | static struct serial_state *serstate; | 14 | static const struct old_serial_port *serstate; |
| 15 | static int timeouts; | 15 | static int timeouts; |
| 16 | 16 | ||
| 17 | struct serial_state *spk_serial_init(int index) | 17 | const struct old_serial_port *spk_serial_init(int index) |
| 18 | { | 18 | { |
| 19 | int baud = 9600, quot = 0; | 19 | int baud = 9600, quot = 0; |
| 20 | unsigned int cval = 0; | 20 | unsigned int cval = 0; |
| 21 | int cflag = CREAD | HUPCL | CLOCAL | B9600 | CS8; | 21 | int cflag = CREAD | HUPCL | CLOCAL | B9600 | CS8; |
| 22 | struct serial_state *ser = NULL; | 22 | const struct old_serial_port *ser = rs_table + index; |
| 23 | int err; | 23 | int err; |
| 24 | 24 | ||
| 25 | ser = rs_table + index; | ||
| 26 | /* Divisor, bytesize and parity */ | 25 | /* Divisor, bytesize and parity */ |
| 27 | quot = ser->baud_base / baud; | 26 | quot = ser->baud_base / baud; |
| 28 | cval = cflag & (CSIZE | CSTOPB); | 27 | cval = cflag & (CSIZE | CSTOPB); |
| @@ -41,7 +40,7 @@ struct serial_state *spk_serial_init(int index) | |||
| 41 | __release_region(&ioport_resource, ser->port, 8); | 40 | __release_region(&ioport_resource, ser->port, 8); |
| 42 | err = synth_request_region(ser->port, 8); | 41 | err = synth_request_region(ser->port, 8); |
| 43 | if (err) { | 42 | if (err) { |
| 44 | pr_warn("Unable to allocate port at %lx, errno %i", | 43 | pr_warn("Unable to allocate port at %x, errno %i", |
| 45 | ser->port, err); | 44 | ser->port, err); |
| 46 | return NULL; | 45 | return NULL; |
| 47 | } | 46 | } |
diff --git a/drivers/staging/speakup/serialio.h b/drivers/staging/speakup/serialio.h index d785b1f6a3b3..614271f9b99f 100644 --- a/drivers/staging/speakup/serialio.h +++ b/drivers/staging/speakup/serialio.h | |||
| @@ -4,11 +4,22 @@ | |||
| 4 | #include <linux/serial.h> /* for rs_table, serial constants & | 4 | #include <linux/serial.h> /* for rs_table, serial constants & |
| 5 | serial_uart_config */ | 5 | serial_uart_config */ |
| 6 | #include <linux/serial_reg.h> /* for more serial constants */ | 6 | #include <linux/serial_reg.h> /* for more serial constants */ |
| 7 | #include <linux/serialP.h> /* for struct serial_state */ | ||
| 8 | #ifndef __sparc__ | 7 | #ifndef __sparc__ |
| 9 | #include <asm/serial.h> | 8 | #include <asm/serial.h> |
| 10 | #endif | 9 | #endif |
| 11 | 10 | ||
| 11 | /* | ||
| 12 | * this is cut&paste from 8250.h. Get rid of the structure, the definitions | ||
| 13 | * and this whole broken driver. | ||
| 14 | */ | ||
| 15 | struct old_serial_port { | ||
| 16 | unsigned int uart; /* unused */ | ||
| 17 | unsigned int baud_base; | ||
| 18 | unsigned int port; | ||
| 19 | unsigned int irq; | ||
| 20 | unsigned int flags; /* unused */ | ||
| 21 | }; | ||
| 22 | |||
| 12 | /* countdown values for serial timeouts in us */ | 23 | /* countdown values for serial timeouts in us */ |
| 13 | #define SPK_SERIAL_TIMEOUT 100000 | 24 | #define SPK_SERIAL_TIMEOUT 100000 |
| 14 | /* countdown values transmitter/dsr timeouts in us */ | 25 | /* countdown values transmitter/dsr timeouts in us */ |
diff --git a/drivers/staging/speakup/spk_priv.h b/drivers/staging/speakup/spk_priv.h index 16ace4af68a9..a47c5b78d57d 100644 --- a/drivers/staging/speakup/spk_priv.h +++ b/drivers/staging/speakup/spk_priv.h | |||
| @@ -44,7 +44,7 @@ | |||
| 44 | 44 | ||
| 45 | #define KT_SPKUP 15 | 45 | #define KT_SPKUP 15 |
| 46 | 46 | ||
| 47 | extern struct serial_state *spk_serial_init(int index); | 47 | extern const struct old_serial_port *spk_serial_init(int index); |
| 48 | extern void stop_serial_interrupt(void); | 48 | extern void stop_serial_interrupt(void); |
| 49 | extern int wait_for_xmitr(void); | 49 | extern int wait_for_xmitr(void); |
| 50 | extern unsigned char spk_serial_in(void); | 50 | extern unsigned char spk_serial_in(void); |
diff --git a/drivers/staging/speakup/synth.c b/drivers/staging/speakup/synth.c index 2222d6919ef5..331eae788700 100644 --- a/drivers/staging/speakup/synth.c +++ b/drivers/staging/speakup/synth.c | |||
| @@ -34,7 +34,7 @@ static int do_synth_init(struct spk_synth *in_synth); | |||
| 34 | 34 | ||
| 35 | int serial_synth_probe(struct spk_synth *synth) | 35 | int serial_synth_probe(struct spk_synth *synth) |
| 36 | { | 36 | { |
| 37 | struct serial_state *ser; | 37 | const struct old_serial_port *ser; |
| 38 | int failed = 0; | 38 | int failed = 0; |
| 39 | 39 | ||
| 40 | if ((synth->ser >= SPK_LO_TTY) && (synth->ser <= SPK_HI_TTY)) { | 40 | if ((synth->ser >= SPK_LO_TTY) && (synth->ser <= SPK_HI_TTY)) { |
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index b84c83456dcc..afadcd43d14e 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c | |||
| @@ -45,7 +45,7 @@ | |||
| 45 | 45 | ||
| 46 | #if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) | 46 | #if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) |
| 47 | #define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \ | 47 | #define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \ |
| 48 | tty->name, (info->flags), serial_driver->refcount,info->count,tty->count,s) | 48 | tty->name, (info->tport.flags), serial_driver->refcount,info->count,tty->count,s) |
| 49 | #else | 49 | #else |
| 50 | #define DBG_CNT(s) | 50 | #define DBG_CNT(s) |
| 51 | #endif | 51 | #endif |
| @@ -58,7 +58,6 @@ | |||
| 58 | 58 | ||
| 59 | #include <linux/types.h> | 59 | #include <linux/types.h> |
| 60 | #include <linux/serial.h> | 60 | #include <linux/serial.h> |
| 61 | #include <linux/serialP.h> | ||
| 62 | #include <linux/serial_reg.h> | 61 | #include <linux/serial_reg.h> |
| 63 | static char *serial_version = "4.30"; | 62 | static char *serial_version = "4.30"; |
| 64 | 63 | ||
| @@ -70,6 +69,7 @@ static char *serial_version = "4.30"; | |||
| 70 | #include <linux/interrupt.h> | 69 | #include <linux/interrupt.h> |
| 71 | #include <linux/tty.h> | 70 | #include <linux/tty.h> |
| 72 | #include <linux/tty_flip.h> | 71 | #include <linux/tty_flip.h> |
| 72 | #include <linux/circ_buf.h> | ||
| 73 | #include <linux/console.h> | 73 | #include <linux/console.h> |
| 74 | #include <linux/major.h> | 74 | #include <linux/major.h> |
| 75 | #include <linux/string.h> | 75 | #include <linux/string.h> |
| @@ -92,6 +92,24 @@ static char *serial_version = "4.30"; | |||
| 92 | #include <asm/amigahw.h> | 92 | #include <asm/amigahw.h> |
| 93 | #include <asm/amigaints.h> | 93 | #include <asm/amigaints.h> |
| 94 | 94 | ||
| 95 | struct serial_state { | ||
| 96 | struct tty_port tport; | ||
| 97 | struct circ_buf xmit; | ||
| 98 | struct async_icount icount; | ||
| 99 | |||
| 100 | unsigned long port; | ||
| 101 | int baud_base; | ||
| 102 | int xmit_fifo_size; | ||
| 103 | int custom_divisor; | ||
| 104 | int read_status_mask; | ||
| 105 | int ignore_status_mask; | ||
| 106 | int timeout; | ||
| 107 | int quot; | ||
| 108 | int IER; /* Interrupt Enable Register */ | ||
| 109 | int MCR; /* Modem control register */ | ||
| 110 | int x_char; /* xon/xoff character */ | ||
| 111 | }; | ||
| 112 | |||
| 95 | #define custom amiga_custom | 113 | #define custom amiga_custom |
| 96 | static char *serial_name = "Amiga-builtin serial driver"; | 114 | static char *serial_name = "Amiga-builtin serial driver"; |
| 97 | 115 | ||
| @@ -100,11 +118,10 @@ static struct tty_driver *serial_driver; | |||
| 100 | /* number of characters left in xmit buffer before we ask for more */ | 118 | /* number of characters left in xmit buffer before we ask for more */ |
| 101 | #define WAKEUP_CHARS 256 | 119 | #define WAKEUP_CHARS 256 |
| 102 | 120 | ||
| 103 | static struct async_struct *IRQ_ports; | ||
| 104 | |||
| 105 | static unsigned char current_ctl_bits; | 121 | static unsigned char current_ctl_bits; |
| 106 | 122 | ||
| 107 | static void change_speed(struct async_struct *info, struct ktermios *old); | 123 | static void change_speed(struct tty_struct *tty, struct serial_state *info, |
| 124 | struct ktermios *old); | ||
| 108 | static void rs_wait_until_sent(struct tty_struct *tty, int timeout); | 125 | static void rs_wait_until_sent(struct tty_struct *tty, int timeout); |
| 109 | 126 | ||
| 110 | 127 | ||
| @@ -117,7 +134,7 @@ static struct serial_state rs_table[1]; | |||
| 117 | #define serial_isroot() (capable(CAP_SYS_ADMIN)) | 134 | #define serial_isroot() (capable(CAP_SYS_ADMIN)) |
| 118 | 135 | ||
| 119 | 136 | ||
| 120 | static inline int serial_paranoia_check(struct async_struct *info, | 137 | static inline int serial_paranoia_check(struct serial_state *info, |
| 121 | char *name, const char *routine) | 138 | char *name, const char *routine) |
| 122 | { | 139 | { |
| 123 | #ifdef SERIAL_PARANOIA_CHECK | 140 | #ifdef SERIAL_PARANOIA_CHECK |
| @@ -170,7 +187,7 @@ static __inline__ void rtsdtr_ctrl(int bits) | |||
| 170 | */ | 187 | */ |
| 171 | static void rs_stop(struct tty_struct *tty) | 188 | static void rs_stop(struct tty_struct *tty) |
| 172 | { | 189 | { |
| 173 | struct async_struct *info = tty->driver_data; | 190 | struct serial_state *info = tty->driver_data; |
| 174 | unsigned long flags; | 191 | unsigned long flags; |
| 175 | 192 | ||
| 176 | if (serial_paranoia_check(info, tty->name, "rs_stop")) | 193 | if (serial_paranoia_check(info, tty->name, "rs_stop")) |
| @@ -190,7 +207,7 @@ static void rs_stop(struct tty_struct *tty) | |||
| 190 | 207 | ||
| 191 | static void rs_start(struct tty_struct *tty) | 208 | static void rs_start(struct tty_struct *tty) |
| 192 | { | 209 | { |
| 193 | struct async_struct *info = tty->driver_data; | 210 | struct serial_state *info = tty->driver_data; |
| 194 | unsigned long flags; | 211 | unsigned long flags; |
| 195 | 212 | ||
| 196 | if (serial_paranoia_check(info, tty->name, "rs_start")) | 213 | if (serial_paranoia_check(info, tty->name, "rs_start")) |
| @@ -231,27 +248,16 @@ static void rs_start(struct tty_struct *tty) | |||
| 231 | * ----------------------------------------------------------------------- | 248 | * ----------------------------------------------------------------------- |
| 232 | */ | 249 | */ |
| 233 | 250 | ||
| 234 | /* | 251 | static void receive_chars(struct serial_state *info) |
| 235 | * This routine is used by the interrupt handler to schedule | ||
| 236 | * processing in the software interrupt portion of the driver. | ||
| 237 | */ | ||
| 238 | static void rs_sched_event(struct async_struct *info, | ||
| 239 | int event) | ||
| 240 | { | ||
| 241 | info->event |= 1 << event; | ||
| 242 | tasklet_schedule(&info->tlet); | ||
| 243 | } | ||
| 244 | |||
| 245 | static void receive_chars(struct async_struct *info) | ||
| 246 | { | 252 | { |
| 247 | int status; | 253 | int status; |
| 248 | int serdatr; | 254 | int serdatr; |
| 249 | struct tty_struct *tty = info->tty; | 255 | struct tty_struct *tty = info->tport.tty; |
| 250 | unsigned char ch, flag; | 256 | unsigned char ch, flag; |
| 251 | struct async_icount *icount; | 257 | struct async_icount *icount; |
| 252 | int oe = 0; | 258 | int oe = 0; |
| 253 | 259 | ||
| 254 | icount = &info->state->icount; | 260 | icount = &info->icount; |
| 255 | 261 | ||
| 256 | status = UART_LSR_DR; /* We obviously have a character! */ | 262 | status = UART_LSR_DR; /* We obviously have a character! */ |
| 257 | serdatr = custom.serdatr; | 263 | serdatr = custom.serdatr; |
| @@ -308,7 +314,7 @@ static void receive_chars(struct async_struct *info) | |||
| 308 | printk("handling break...."); | 314 | printk("handling break...."); |
| 309 | #endif | 315 | #endif |
| 310 | flag = TTY_BREAK; | 316 | flag = TTY_BREAK; |
| 311 | if (info->flags & ASYNC_SAK) | 317 | if (info->tport.flags & ASYNC_SAK) |
| 312 | do_SAK(tty); | 318 | do_SAK(tty); |
| 313 | } else if (status & UART_LSR_PE) | 319 | } else if (status & UART_LSR_PE) |
| 314 | flag = TTY_PARITY; | 320 | flag = TTY_PARITY; |
| @@ -331,20 +337,20 @@ out: | |||
| 331 | return; | 337 | return; |
| 332 | } | 338 | } |
| 333 | 339 | ||
| 334 | static void transmit_chars(struct async_struct *info) | 340 | static void transmit_chars(struct serial_state *info) |
| 335 | { | 341 | { |
| 336 | custom.intreq = IF_TBE; | 342 | custom.intreq = IF_TBE; |
| 337 | mb(); | 343 | mb(); |
| 338 | if (info->x_char) { | 344 | if (info->x_char) { |
| 339 | custom.serdat = info->x_char | 0x100; | 345 | custom.serdat = info->x_char | 0x100; |
| 340 | mb(); | 346 | mb(); |
| 341 | info->state->icount.tx++; | 347 | info->icount.tx++; |
| 342 | info->x_char = 0; | 348 | info->x_char = 0; |
| 343 | return; | 349 | return; |
| 344 | } | 350 | } |
| 345 | if (info->xmit.head == info->xmit.tail | 351 | if (info->xmit.head == info->xmit.tail |
| 346 | || info->tty->stopped | 352 | || info->tport.tty->stopped |
| 347 | || info->tty->hw_stopped) { | 353 | || info->tport.tty->hw_stopped) { |
| 348 | info->IER &= ~UART_IER_THRI; | 354 | info->IER &= ~UART_IER_THRI; |
| 349 | custom.intena = IF_TBE; | 355 | custom.intena = IF_TBE; |
| 350 | mb(); | 356 | mb(); |
| @@ -354,12 +360,12 @@ static void transmit_chars(struct async_struct *info) | |||
| 354 | custom.serdat = info->xmit.buf[info->xmit.tail++] | 0x100; | 360 | custom.serdat = info->xmit.buf[info->xmit.tail++] | 0x100; |
| 355 | mb(); | 361 | mb(); |
| 356 | info->xmit.tail = info->xmit.tail & (SERIAL_XMIT_SIZE-1); | 362 | info->xmit.tail = info->xmit.tail & (SERIAL_XMIT_SIZE-1); |
| 357 | info->state->icount.tx++; | 363 | info->icount.tx++; |
| 358 | 364 | ||
| 359 | if (CIRC_CNT(info->xmit.head, | 365 | if (CIRC_CNT(info->xmit.head, |
| 360 | info->xmit.tail, | 366 | info->xmit.tail, |
| 361 | SERIAL_XMIT_SIZE) < WAKEUP_CHARS) | 367 | SERIAL_XMIT_SIZE) < WAKEUP_CHARS) |
| 362 | rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); | 368 | tty_wakeup(info->tport.tty); |
| 363 | 369 | ||
| 364 | #ifdef SERIAL_DEBUG_INTR | 370 | #ifdef SERIAL_DEBUG_INTR |
| 365 | printk("THRE..."); | 371 | printk("THRE..."); |
| @@ -371,8 +377,9 @@ static void transmit_chars(struct async_struct *info) | |||
| 371 | } | 377 | } |
| 372 | } | 378 | } |
| 373 | 379 | ||
| 374 | static void check_modem_status(struct async_struct *info) | 380 | static void check_modem_status(struct serial_state *info) |
| 375 | { | 381 | { |
| 382 | struct tty_port *port = &info->tport; | ||
| 376 | unsigned char status = ciab.pra & (SER_DCD | SER_CTS | SER_DSR); | 383 | unsigned char status = ciab.pra & (SER_DCD | SER_CTS | SER_DSR); |
| 377 | unsigned char dstatus; | 384 | unsigned char dstatus; |
| 378 | struct async_icount *icount; | 385 | struct async_icount *icount; |
| @@ -382,52 +389,52 @@ static void check_modem_status(struct async_struct *info) | |||
| 382 | current_ctl_bits = status; | 389 | current_ctl_bits = status; |
| 383 | 390 | ||
| 384 | if (dstatus) { | 391 | if (dstatus) { |
| 385 | icount = &info->state->icount; | 392 | icount = &info->icount; |
| 386 | /* update input line counters */ | 393 | /* update input line counters */ |
| 387 | if (dstatus & SER_DSR) | 394 | if (dstatus & SER_DSR) |
| 388 | icount->dsr++; | 395 | icount->dsr++; |
| 389 | if (dstatus & SER_DCD) { | 396 | if (dstatus & SER_DCD) { |
| 390 | icount->dcd++; | 397 | icount->dcd++; |
| 391 | #ifdef CONFIG_HARD_PPS | 398 | #ifdef CONFIG_HARD_PPS |
| 392 | if ((info->flags & ASYNC_HARDPPS_CD) && | 399 | if ((port->flags & ASYNC_HARDPPS_CD) && |
| 393 | !(status & SER_DCD)) | 400 | !(status & SER_DCD)) |
| 394 | hardpps(); | 401 | hardpps(); |
| 395 | #endif | 402 | #endif |
| 396 | } | 403 | } |
| 397 | if (dstatus & SER_CTS) | 404 | if (dstatus & SER_CTS) |
| 398 | icount->cts++; | 405 | icount->cts++; |
| 399 | wake_up_interruptible(&info->delta_msr_wait); | 406 | wake_up_interruptible(&port->delta_msr_wait); |
| 400 | } | 407 | } |
| 401 | 408 | ||
| 402 | if ((info->flags & ASYNC_CHECK_CD) && (dstatus & SER_DCD)) { | 409 | if ((port->flags & ASYNC_CHECK_CD) && (dstatus & SER_DCD)) { |
| 403 | #if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) | 410 | #if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) |
| 404 | printk("ttyS%d CD now %s...", info->line, | 411 | printk("ttyS%d CD now %s...", info->line, |
| 405 | (!(status & SER_DCD)) ? "on" : "off"); | 412 | (!(status & SER_DCD)) ? "on" : "off"); |
| 406 | #endif | 413 | #endif |
| 407 | if (!(status & SER_DCD)) | 414 | if (!(status & SER_DCD)) |
| 408 | wake_up_interruptible(&info->open_wait); | 415 | wake_up_interruptible(&port->open_wait); |
| 409 | else { | 416 | else { |
| 410 | #ifdef SERIAL_DEBUG_OPEN | 417 | #ifdef SERIAL_DEBUG_OPEN |
| 411 | printk("doing serial hangup..."); | 418 | printk("doing serial hangup..."); |
| 412 | #endif | 419 | #endif |
| 413 | if (info->tty) | 420 | if (port->tty) |
| 414 | tty_hangup(info->tty); | 421 | tty_hangup(port->tty); |
| 415 | } | 422 | } |
| 416 | } | 423 | } |
| 417 | if (info->flags & ASYNC_CTS_FLOW) { | 424 | if (port->flags & ASYNC_CTS_FLOW) { |
| 418 | if (info->tty->hw_stopped) { | 425 | if (port->tty->hw_stopped) { |
| 419 | if (!(status & SER_CTS)) { | 426 | if (!(status & SER_CTS)) { |
| 420 | #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) | 427 | #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) |
| 421 | printk("CTS tx start..."); | 428 | printk("CTS tx start..."); |
| 422 | #endif | 429 | #endif |
| 423 | info->tty->hw_stopped = 0; | 430 | port->tty->hw_stopped = 0; |
| 424 | info->IER |= UART_IER_THRI; | 431 | info->IER |= UART_IER_THRI; |
| 425 | custom.intena = IF_SETCLR | IF_TBE; | 432 | custom.intena = IF_SETCLR | IF_TBE; |
| 426 | mb(); | 433 | mb(); |
| 427 | /* set a pending Tx Interrupt, transmitter should restart now */ | 434 | /* set a pending Tx Interrupt, transmitter should restart now */ |
| 428 | custom.intreq = IF_SETCLR | IF_TBE; | 435 | custom.intreq = IF_SETCLR | IF_TBE; |
| 429 | mb(); | 436 | mb(); |
| 430 | rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); | 437 | tty_wakeup(port->tty); |
| 431 | return; | 438 | return; |
| 432 | } | 439 | } |
| 433 | } else { | 440 | } else { |
| @@ -435,7 +442,7 @@ static void check_modem_status(struct async_struct *info) | |||
| 435 | #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) | 442 | #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) |
| 436 | printk("CTS tx stop..."); | 443 | printk("CTS tx stop..."); |
| 437 | #endif | 444 | #endif |
| 438 | info->tty->hw_stopped = 1; | 445 | port->tty->hw_stopped = 1; |
| 439 | info->IER &= ~UART_IER_THRI; | 446 | info->IER &= ~UART_IER_THRI; |
| 440 | /* disable Tx interrupt and remove any pending interrupts */ | 447 | /* disable Tx interrupt and remove any pending interrupts */ |
| 441 | custom.intena = IF_TBE; | 448 | custom.intena = IF_TBE; |
| @@ -450,7 +457,7 @@ static void check_modem_status(struct async_struct *info) | |||
| 450 | static irqreturn_t ser_vbl_int( int irq, void *data) | 457 | static irqreturn_t ser_vbl_int( int irq, void *data) |
| 451 | { | 458 | { |
| 452 | /* vbl is just a periodic interrupt we tie into to update modem status */ | 459 | /* vbl is just a periodic interrupt we tie into to update modem status */ |
| 453 | struct async_struct * info = IRQ_ports; | 460 | struct serial_state *info = data; |
| 454 | /* | 461 | /* |
| 455 | * TBD - is it better to unregister from this interrupt or to | 462 | * TBD - is it better to unregister from this interrupt or to |
| 456 | * ignore it if MSI is clear ? | 463 | * ignore it if MSI is clear ? |
| @@ -462,18 +469,16 @@ static irqreturn_t ser_vbl_int( int irq, void *data) | |||
| 462 | 469 | ||
| 463 | static irqreturn_t ser_rx_int(int irq, void *dev_id) | 470 | static irqreturn_t ser_rx_int(int irq, void *dev_id) |
| 464 | { | 471 | { |
| 465 | struct async_struct * info; | 472 | struct serial_state *info = dev_id; |
| 466 | 473 | ||
| 467 | #ifdef SERIAL_DEBUG_INTR | 474 | #ifdef SERIAL_DEBUG_INTR |
| 468 | printk("ser_rx_int..."); | 475 | printk("ser_rx_int..."); |
| 469 | #endif | 476 | #endif |
| 470 | 477 | ||
| 471 | info = IRQ_ports; | 478 | if (!info->tport.tty) |
| 472 | if (!info || !info->tty) | ||
| 473 | return IRQ_NONE; | 479 | return IRQ_NONE; |
| 474 | 480 | ||
| 475 | receive_chars(info); | 481 | receive_chars(info); |
| 476 | info->last_active = jiffies; | ||
| 477 | #ifdef SERIAL_DEBUG_INTR | 482 | #ifdef SERIAL_DEBUG_INTR |
| 478 | printk("end.\n"); | 483 | printk("end.\n"); |
| 479 | #endif | 484 | #endif |
| @@ -482,19 +487,17 @@ static irqreturn_t ser_rx_int(int irq, void *dev_id) | |||
| 482 | 487 | ||
| 483 | static irqreturn_t ser_tx_int(int irq, void *dev_id) | 488 | static irqreturn_t ser_tx_int(int irq, void *dev_id) |
| 484 | { | 489 | { |
| 485 | struct async_struct * info; | 490 | struct serial_state *info = dev_id; |
| 486 | 491 | ||
| 487 | if (custom.serdatr & SDR_TBE) { | 492 | if (custom.serdatr & SDR_TBE) { |
| 488 | #ifdef SERIAL_DEBUG_INTR | 493 | #ifdef SERIAL_DEBUG_INTR |
| 489 | printk("ser_tx_int..."); | 494 | printk("ser_tx_int..."); |
| 490 | #endif | 495 | #endif |
| 491 | 496 | ||
| 492 | info = IRQ_ports; | 497 | if (!info->tport.tty) |
| 493 | if (!info || !info->tty) | ||
| 494 | return IRQ_NONE; | 498 | return IRQ_NONE; |
| 495 | 499 | ||
| 496 | transmit_chars(info); | 500 | transmit_chars(info); |
| 497 | info->last_active = jiffies; | ||
| 498 | #ifdef SERIAL_DEBUG_INTR | 501 | #ifdef SERIAL_DEBUG_INTR |
| 499 | printk("end.\n"); | 502 | printk("end.\n"); |
| 500 | #endif | 503 | #endif |
| @@ -509,29 +512,6 @@ static irqreturn_t ser_tx_int(int irq, void *dev_id) | |||
| 509 | */ | 512 | */ |
| 510 | 513 | ||
| 511 | /* | 514 | /* |
| 512 | * This routine is used to handle the "bottom half" processing for the | ||
| 513 | * serial driver, known also the "software interrupt" processing. | ||
| 514 | * This processing is done at the kernel interrupt level, after the | ||
| 515 | * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This | ||
| 516 | * is where time-consuming activities which can not be done in the | ||
| 517 | * interrupt driver proper are done; the interrupt driver schedules | ||
| 518 | * them using rs_sched_event(), and they get done here. | ||
| 519 | */ | ||
| 520 | |||
| 521 | static void do_softint(unsigned long private_) | ||
| 522 | { | ||
| 523 | struct async_struct *info = (struct async_struct *) private_; | ||
| 524 | struct tty_struct *tty; | ||
| 525 | |||
| 526 | tty = info->tty; | ||
| 527 | if (!tty) | ||
| 528 | return; | ||
| 529 | |||
| 530 | if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) | ||
| 531 | tty_wakeup(tty); | ||
| 532 | } | ||
| 533 | |||
| 534 | /* | ||
| 535 | * --------------------------------------------------------------- | 515 | * --------------------------------------------------------------- |
| 536 | * Low level utility subroutines for the serial driver: routines to | 516 | * Low level utility subroutines for the serial driver: routines to |
| 537 | * figure out the appropriate timeout for an interrupt chain, routines | 517 | * figure out the appropriate timeout for an interrupt chain, routines |
| @@ -540,8 +520,9 @@ static void do_softint(unsigned long private_) | |||
| 540 | * --------------------------------------------------------------- | 520 | * --------------------------------------------------------------- |
| 541 | */ | 521 | */ |
| 542 | 522 | ||
| 543 | static int startup(struct async_struct * info) | 523 | static int startup(struct tty_struct *tty, struct serial_state *info) |
| 544 | { | 524 | { |
| 525 | struct tty_port *port = &info->tport; | ||
| 545 | unsigned long flags; | 526 | unsigned long flags; |
| 546 | int retval=0; | 527 | int retval=0; |
| 547 | unsigned long page; | 528 | unsigned long page; |
| @@ -552,7 +533,7 @@ static int startup(struct async_struct * info) | |||
| 552 | 533 | ||
| 553 | local_irq_save(flags); | 534 | local_irq_save(flags); |
| 554 | 535 | ||
| 555 | if (info->flags & ASYNC_INITIALIZED) { | 536 | if (port->flags & ASYNC_INITIALIZED) { |
| 556 | free_page(page); | 537 | free_page(page); |
| 557 | goto errout; | 538 | goto errout; |
| 558 | } | 539 | } |
| @@ -574,9 +555,7 @@ static int startup(struct async_struct * info) | |||
| 574 | retval = request_irq(IRQ_AMIGA_VERTB, ser_vbl_int, 0, "serial status", info); | 555 | retval = request_irq(IRQ_AMIGA_VERTB, ser_vbl_int, 0, "serial status", info); |
| 575 | if (retval) { | 556 | if (retval) { |
| 576 | if (serial_isroot()) { | 557 | if (serial_isroot()) { |
| 577 | if (info->tty) | 558 | set_bit(TTY_IO_ERROR, &tty->flags); |
| 578 | set_bit(TTY_IO_ERROR, | ||
| 579 | &info->tty->flags); | ||
| 580 | retval = 0; | 559 | retval = 0; |
| 581 | } | 560 | } |
| 582 | goto errout; | 561 | goto errout; |
| @@ -590,37 +569,32 @@ static int startup(struct async_struct * info) | |||
| 590 | /* remember current state of the DCD and CTS bits */ | 569 | /* remember current state of the DCD and CTS bits */ |
| 591 | current_ctl_bits = ciab.pra & (SER_DCD | SER_CTS | SER_DSR); | 570 | current_ctl_bits = ciab.pra & (SER_DCD | SER_CTS | SER_DSR); |
| 592 | 571 | ||
| 593 | IRQ_ports = info; | ||
| 594 | |||
| 595 | info->MCR = 0; | 572 | info->MCR = 0; |
| 596 | if (info->tty->termios->c_cflag & CBAUD) | 573 | if (C_BAUD(tty)) |
| 597 | info->MCR = SER_DTR | SER_RTS; | 574 | info->MCR = SER_DTR | SER_RTS; |
| 598 | rtsdtr_ctrl(info->MCR); | 575 | rtsdtr_ctrl(info->MCR); |
| 599 | 576 | ||
| 600 | if (info->tty) | 577 | clear_bit(TTY_IO_ERROR, &tty->flags); |
| 601 | clear_bit(TTY_IO_ERROR, &info->tty->flags); | ||
| 602 | info->xmit.head = info->xmit.tail = 0; | 578 | info->xmit.head = info->xmit.tail = 0; |
| 603 | 579 | ||
| 604 | /* | 580 | /* |
| 605 | * Set up the tty->alt_speed kludge | 581 | * Set up the tty->alt_speed kludge |
| 606 | */ | 582 | */ |
| 607 | if (info->tty) { | 583 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) |
| 608 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) | 584 | tty->alt_speed = 57600; |
| 609 | info->tty->alt_speed = 57600; | 585 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) |
| 610 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) | 586 | tty->alt_speed = 115200; |
| 611 | info->tty->alt_speed = 115200; | 587 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) |
| 612 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) | 588 | tty->alt_speed = 230400; |
| 613 | info->tty->alt_speed = 230400; | 589 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) |
| 614 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) | 590 | tty->alt_speed = 460800; |
| 615 | info->tty->alt_speed = 460800; | ||
| 616 | } | ||
| 617 | 591 | ||
| 618 | /* | 592 | /* |
| 619 | * and set the speed of the serial port | 593 | * and set the speed of the serial port |
| 620 | */ | 594 | */ |
| 621 | change_speed(info, NULL); | 595 | change_speed(tty, info, NULL); |
| 622 | 596 | ||
| 623 | info->flags |= ASYNC_INITIALIZED; | 597 | port->flags |= ASYNC_INITIALIZED; |
| 624 | local_irq_restore(flags); | 598 | local_irq_restore(flags); |
| 625 | return 0; | 599 | return 0; |
| 626 | 600 | ||
| @@ -633,15 +607,15 @@ errout: | |||
| 633 | * This routine will shutdown a serial port; interrupts are disabled, and | 607 | * This routine will shutdown a serial port; interrupts are disabled, and |
| 634 | * DTR is dropped if the hangup on close termio flag is on. | 608 | * DTR is dropped if the hangup on close termio flag is on. |
| 635 | */ | 609 | */ |
| 636 | static void shutdown(struct async_struct * info) | 610 | static void shutdown(struct tty_struct *tty, struct serial_state *info) |
| 637 | { | 611 | { |
| 638 | unsigned long flags; | 612 | unsigned long flags; |
| 639 | struct serial_state *state; | 613 | struct serial_state *state; |
| 640 | 614 | ||
| 641 | if (!(info->flags & ASYNC_INITIALIZED)) | 615 | if (!(info->tport.flags & ASYNC_INITIALIZED)) |
| 642 | return; | 616 | return; |
| 643 | 617 | ||
| 644 | state = info->state; | 618 | state = info; |
| 645 | 619 | ||
| 646 | #ifdef SERIAL_DEBUG_OPEN | 620 | #ifdef SERIAL_DEBUG_OPEN |
| 647 | printk("Shutting down serial port %d ....\n", info->line); | 621 | printk("Shutting down serial port %d ....\n", info->line); |
| @@ -653,9 +627,7 @@ static void shutdown(struct async_struct * info) | |||
| 653 | * clear delta_msr_wait queue to avoid mem leaks: we may free the irq | 627 | * clear delta_msr_wait queue to avoid mem leaks: we may free the irq |
| 654 | * here so the queue might never be waken up | 628 | * here so the queue might never be waken up |
| 655 | */ | 629 | */ |
| 656 | wake_up_interruptible(&info->delta_msr_wait); | 630 | wake_up_interruptible(&info->tport.delta_msr_wait); |
| 657 | |||
| 658 | IRQ_ports = NULL; | ||
| 659 | 631 | ||
| 660 | /* | 632 | /* |
| 661 | * Free the IRQ, if necessary | 633 | * Free the IRQ, if necessary |
| @@ -675,14 +647,13 @@ static void shutdown(struct async_struct * info) | |||
| 675 | custom.adkcon = AC_UARTBRK; | 647 | custom.adkcon = AC_UARTBRK; |
| 676 | mb(); | 648 | mb(); |
| 677 | 649 | ||
| 678 | if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) | 650 | if (tty->termios->c_cflag & HUPCL) |
| 679 | info->MCR &= ~(SER_DTR|SER_RTS); | 651 | info->MCR &= ~(SER_DTR|SER_RTS); |
| 680 | rtsdtr_ctrl(info->MCR); | 652 | rtsdtr_ctrl(info->MCR); |
| 681 | 653 | ||
| 682 | if (info->tty) | 654 | set_bit(TTY_IO_ERROR, &tty->flags); |
| 683 | set_bit(TTY_IO_ERROR, &info->tty->flags); | ||
| 684 | 655 | ||
| 685 | info->flags &= ~ASYNC_INITIALIZED; | 656 | info->tport.flags &= ~ASYNC_INITIALIZED; |
| 686 | local_irq_restore(flags); | 657 | local_irq_restore(flags); |
| 687 | } | 658 | } |
| 688 | 659 | ||
| @@ -691,17 +662,16 @@ static void shutdown(struct async_struct * info) | |||
| 691 | * This routine is called to set the UART divisor registers to match | 662 | * This routine is called to set the UART divisor registers to match |
| 692 | * the specified baud rate for a serial port. | 663 | * the specified baud rate for a serial port. |
| 693 | */ | 664 | */ |
| 694 | static void change_speed(struct async_struct *info, | 665 | static void change_speed(struct tty_struct *tty, struct serial_state *info, |
| 695 | struct ktermios *old_termios) | 666 | struct ktermios *old_termios) |
| 696 | { | 667 | { |
| 668 | struct tty_port *port = &info->tport; | ||
| 697 | int quot = 0, baud_base, baud; | 669 | int quot = 0, baud_base, baud; |
| 698 | unsigned cflag, cval = 0; | 670 | unsigned cflag, cval = 0; |
| 699 | int bits; | 671 | int bits; |
| 700 | unsigned long flags; | 672 | unsigned long flags; |
| 701 | 673 | ||
| 702 | if (!info->tty || !info->tty->termios) | 674 | cflag = tty->termios->c_cflag; |
| 703 | return; | ||
| 704 | cflag = info->tty->termios->c_cflag; | ||
| 705 | 675 | ||
| 706 | /* Byte size is always 8 bits plus parity bit if requested */ | 676 | /* Byte size is always 8 bits plus parity bit if requested */ |
| 707 | 677 | ||
| @@ -722,13 +692,12 @@ static void change_speed(struct async_struct *info, | |||
| 722 | #endif | 692 | #endif |
| 723 | 693 | ||
| 724 | /* Determine divisor based on baud rate */ | 694 | /* Determine divisor based on baud rate */ |
| 725 | baud = tty_get_baud_rate(info->tty); | 695 | baud = tty_get_baud_rate(tty); |
| 726 | if (!baud) | 696 | if (!baud) |
| 727 | baud = 9600; /* B0 transition handled in rs_set_termios */ | 697 | baud = 9600; /* B0 transition handled in rs_set_termios */ |
| 728 | baud_base = info->state->baud_base; | 698 | baud_base = info->baud_base; |
| 729 | if (baud == 38400 && | 699 | if (baud == 38400 && (port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) |
| 730 | ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) | 700 | quot = info->custom_divisor; |
| 731 | quot = info->state->custom_divisor; | ||
| 732 | else { | 701 | else { |
| 733 | if (baud == 134) | 702 | if (baud == 134) |
| 734 | /* Special case since 134 is really 134.5 */ | 703 | /* Special case since 134 is really 134.5 */ |
| @@ -739,14 +708,14 @@ static void change_speed(struct async_struct *info, | |||
| 739 | /* If the quotient is zero refuse the change */ | 708 | /* If the quotient is zero refuse the change */ |
| 740 | if (!quot && old_termios) { | 709 | if (!quot && old_termios) { |
| 741 | /* FIXME: Will need updating for new tty in the end */ | 710 | /* FIXME: Will need updating for new tty in the end */ |
| 742 | info->tty->termios->c_cflag &= ~CBAUD; | 711 | tty->termios->c_cflag &= ~CBAUD; |
| 743 | info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD); | 712 | tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD); |
| 744 | baud = tty_get_baud_rate(info->tty); | 713 | baud = tty_get_baud_rate(tty); |
| 745 | if (!baud) | 714 | if (!baud) |
| 746 | baud = 9600; | 715 | baud = 9600; |
| 747 | if (baud == 38400 && | 716 | if (baud == 38400 && |
| 748 | ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) | 717 | (port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) |
| 749 | quot = info->state->custom_divisor; | 718 | quot = info->custom_divisor; |
| 750 | else { | 719 | else { |
| 751 | if (baud == 134) | 720 | if (baud == 134) |
| 752 | /* Special case since 134 is really 134.5 */ | 721 | /* Special case since 134 is really 134.5 */ |
| @@ -764,17 +733,17 @@ static void change_speed(struct async_struct *info, | |||
| 764 | 733 | ||
| 765 | /* CTS flow control flag and modem status interrupts */ | 734 | /* CTS flow control flag and modem status interrupts */ |
| 766 | info->IER &= ~UART_IER_MSI; | 735 | info->IER &= ~UART_IER_MSI; |
| 767 | if (info->flags & ASYNC_HARDPPS_CD) | 736 | if (port->flags & ASYNC_HARDPPS_CD) |
| 768 | info->IER |= UART_IER_MSI; | 737 | info->IER |= UART_IER_MSI; |
| 769 | if (cflag & CRTSCTS) { | 738 | if (cflag & CRTSCTS) { |
| 770 | info->flags |= ASYNC_CTS_FLOW; | 739 | port->flags |= ASYNC_CTS_FLOW; |
| 771 | info->IER |= UART_IER_MSI; | 740 | info->IER |= UART_IER_MSI; |
| 772 | } else | 741 | } else |
| 773 | info->flags &= ~ASYNC_CTS_FLOW; | 742 | port->flags &= ~ASYNC_CTS_FLOW; |
| 774 | if (cflag & CLOCAL) | 743 | if (cflag & CLOCAL) |
| 775 | info->flags &= ~ASYNC_CHECK_CD; | 744 | port->flags &= ~ASYNC_CHECK_CD; |
| 776 | else { | 745 | else { |
| 777 | info->flags |= ASYNC_CHECK_CD; | 746 | port->flags |= ASYNC_CHECK_CD; |
| 778 | info->IER |= UART_IER_MSI; | 747 | info->IER |= UART_IER_MSI; |
| 779 | } | 748 | } |
| 780 | /* TBD: | 749 | /* TBD: |
| @@ -786,24 +755,24 @@ static void change_speed(struct async_struct *info, | |||
| 786 | */ | 755 | */ |
| 787 | 756 | ||
| 788 | info->read_status_mask = UART_LSR_OE | UART_LSR_DR; | 757 | info->read_status_mask = UART_LSR_OE | UART_LSR_DR; |
| 789 | if (I_INPCK(info->tty)) | 758 | if (I_INPCK(tty)) |
| 790 | info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; | 759 | info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; |
| 791 | if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) | 760 | if (I_BRKINT(tty) || I_PARMRK(tty)) |
| 792 | info->read_status_mask |= UART_LSR_BI; | 761 | info->read_status_mask |= UART_LSR_BI; |
| 793 | 762 | ||
| 794 | /* | 763 | /* |
| 795 | * Characters to ignore | 764 | * Characters to ignore |
| 796 | */ | 765 | */ |
| 797 | info->ignore_status_mask = 0; | 766 | info->ignore_status_mask = 0; |
| 798 | if (I_IGNPAR(info->tty)) | 767 | if (I_IGNPAR(tty)) |
| 799 | info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; | 768 | info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; |
| 800 | if (I_IGNBRK(info->tty)) { | 769 | if (I_IGNBRK(tty)) { |
| 801 | info->ignore_status_mask |= UART_LSR_BI; | 770 | info->ignore_status_mask |= UART_LSR_BI; |
| 802 | /* | 771 | /* |
| 803 | * If we're ignore parity and break indicators, ignore | 772 | * If we're ignore parity and break indicators, ignore |
| 804 | * overruns too. (For real raw support). | 773 | * overruns too. (For real raw support). |
| 805 | */ | 774 | */ |
| 806 | if (I_IGNPAR(info->tty)) | 775 | if (I_IGNPAR(tty)) |
| 807 | info->ignore_status_mask |= UART_LSR_OE; | 776 | info->ignore_status_mask |= UART_LSR_OE; |
| 808 | } | 777 | } |
| 809 | /* | 778 | /* |
| @@ -828,13 +797,12 @@ static void change_speed(struct async_struct *info, | |||
| 828 | mb(); | 797 | mb(); |
| 829 | } | 798 | } |
| 830 | 799 | ||
| 831 | info->LCR = cval; /* Save LCR */ | ||
| 832 | local_irq_restore(flags); | 800 | local_irq_restore(flags); |
| 833 | } | 801 | } |
| 834 | 802 | ||
| 835 | static int rs_put_char(struct tty_struct *tty, unsigned char ch) | 803 | static int rs_put_char(struct tty_struct *tty, unsigned char ch) |
| 836 | { | 804 | { |
| 837 | struct async_struct *info; | 805 | struct serial_state *info; |
| 838 | unsigned long flags; | 806 | unsigned long flags; |
| 839 | 807 | ||
| 840 | info = tty->driver_data; | 808 | info = tty->driver_data; |
| @@ -861,7 +829,7 @@ static int rs_put_char(struct tty_struct *tty, unsigned char ch) | |||
| 861 | 829 | ||
| 862 | static void rs_flush_chars(struct tty_struct *tty) | 830 | static void rs_flush_chars(struct tty_struct *tty) |
| 863 | { | 831 | { |
| 864 | struct async_struct *info = tty->driver_data; | 832 | struct serial_state *info = tty->driver_data; |
| 865 | unsigned long flags; | 833 | unsigned long flags; |
| 866 | 834 | ||
| 867 | if (serial_paranoia_check(info, tty->name, "rs_flush_chars")) | 835 | if (serial_paranoia_check(info, tty->name, "rs_flush_chars")) |
| @@ -886,11 +854,9 @@ static void rs_flush_chars(struct tty_struct *tty) | |||
| 886 | static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count) | 854 | static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count) |
| 887 | { | 855 | { |
| 888 | int c, ret = 0; | 856 | int c, ret = 0; |
| 889 | struct async_struct *info; | 857 | struct serial_state *info = tty->driver_data; |
| 890 | unsigned long flags; | 858 | unsigned long flags; |
| 891 | 859 | ||
| 892 | info = tty->driver_data; | ||
| 893 | |||
| 894 | if (serial_paranoia_check(info, tty->name, "rs_write")) | 860 | if (serial_paranoia_check(info, tty->name, "rs_write")) |
| 895 | return 0; | 861 | return 0; |
| 896 | 862 | ||
| @@ -934,7 +900,7 @@ static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count | |||
| 934 | 900 | ||
| 935 | static int rs_write_room(struct tty_struct *tty) | 901 | static int rs_write_room(struct tty_struct *tty) |
| 936 | { | 902 | { |
| 937 | struct async_struct *info = tty->driver_data; | 903 | struct serial_state *info = tty->driver_data; |
| 938 | 904 | ||
| 939 | if (serial_paranoia_check(info, tty->name, "rs_write_room")) | 905 | if (serial_paranoia_check(info, tty->name, "rs_write_room")) |
| 940 | return 0; | 906 | return 0; |
| @@ -943,7 +909,7 @@ static int rs_write_room(struct tty_struct *tty) | |||
| 943 | 909 | ||
| 944 | static int rs_chars_in_buffer(struct tty_struct *tty) | 910 | static int rs_chars_in_buffer(struct tty_struct *tty) |
| 945 | { | 911 | { |
| 946 | struct async_struct *info = tty->driver_data; | 912 | struct serial_state *info = tty->driver_data; |
| 947 | 913 | ||
| 948 | if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer")) | 914 | if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer")) |
| 949 | return 0; | 915 | return 0; |
| @@ -952,7 +918,7 @@ static int rs_chars_in_buffer(struct tty_struct *tty) | |||
| 952 | 918 | ||
| 953 | static void rs_flush_buffer(struct tty_struct *tty) | 919 | static void rs_flush_buffer(struct tty_struct *tty) |
| 954 | { | 920 | { |
| 955 | struct async_struct *info = tty->driver_data; | 921 | struct serial_state *info = tty->driver_data; |
| 956 | unsigned long flags; | 922 | unsigned long flags; |
| 957 | 923 | ||
| 958 | if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) | 924 | if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) |
| @@ -969,7 +935,7 @@ static void rs_flush_buffer(struct tty_struct *tty) | |||
| 969 | */ | 935 | */ |
| 970 | static void rs_send_xchar(struct tty_struct *tty, char ch) | 936 | static void rs_send_xchar(struct tty_struct *tty, char ch) |
| 971 | { | 937 | { |
| 972 | struct async_struct *info = tty->driver_data; | 938 | struct serial_state *info = tty->driver_data; |
| 973 | unsigned long flags; | 939 | unsigned long flags; |
| 974 | 940 | ||
| 975 | if (serial_paranoia_check(info, tty->name, "rs_send_char")) | 941 | if (serial_paranoia_check(info, tty->name, "rs_send_char")) |
| @@ -1004,7 +970,7 @@ static void rs_send_xchar(struct tty_struct *tty, char ch) | |||
| 1004 | */ | 970 | */ |
| 1005 | static void rs_throttle(struct tty_struct * tty) | 971 | static void rs_throttle(struct tty_struct * tty) |
| 1006 | { | 972 | { |
| 1007 | struct async_struct *info = tty->driver_data; | 973 | struct serial_state *info = tty->driver_data; |
| 1008 | unsigned long flags; | 974 | unsigned long flags; |
| 1009 | #ifdef SERIAL_DEBUG_THROTTLE | 975 | #ifdef SERIAL_DEBUG_THROTTLE |
| 1010 | char buf[64]; | 976 | char buf[64]; |
| @@ -1029,7 +995,7 @@ static void rs_throttle(struct tty_struct * tty) | |||
| 1029 | 995 | ||
| 1030 | static void rs_unthrottle(struct tty_struct * tty) | 996 | static void rs_unthrottle(struct tty_struct * tty) |
| 1031 | { | 997 | { |
| 1032 | struct async_struct *info = tty->driver_data; | 998 | struct serial_state *info = tty->driver_data; |
| 1033 | unsigned long flags; | 999 | unsigned long flags; |
| 1034 | #ifdef SERIAL_DEBUG_THROTTLE | 1000 | #ifdef SERIAL_DEBUG_THROTTLE |
| 1035 | char buf[64]; | 1001 | char buf[64]; |
| @@ -1060,25 +1026,22 @@ static void rs_unthrottle(struct tty_struct * tty) | |||
| 1060 | * ------------------------------------------------------------ | 1026 | * ------------------------------------------------------------ |
| 1061 | */ | 1027 | */ |
| 1062 | 1028 | ||
| 1063 | static int get_serial_info(struct async_struct * info, | 1029 | static int get_serial_info(struct tty_struct *tty, struct serial_state *state, |
| 1064 | struct serial_struct __user * retinfo) | 1030 | struct serial_struct __user * retinfo) |
| 1065 | { | 1031 | { |
| 1066 | struct serial_struct tmp; | 1032 | struct serial_struct tmp; |
| 1067 | struct serial_state *state = info->state; | ||
| 1068 | 1033 | ||
| 1069 | if (!retinfo) | 1034 | if (!retinfo) |
| 1070 | return -EFAULT; | 1035 | return -EFAULT; |
| 1071 | memset(&tmp, 0, sizeof(tmp)); | 1036 | memset(&tmp, 0, sizeof(tmp)); |
| 1072 | tty_lock(); | 1037 | tty_lock(); |
| 1073 | tmp.type = state->type; | 1038 | tmp.line = tty->index; |
| 1074 | tmp.line = state->line; | ||
| 1075 | tmp.port = state->port; | 1039 | tmp.port = state->port; |
| 1076 | tmp.irq = state->irq; | 1040 | tmp.flags = state->tport.flags; |
| 1077 | tmp.flags = state->flags; | ||
| 1078 | tmp.xmit_fifo_size = state->xmit_fifo_size; | 1041 | tmp.xmit_fifo_size = state->xmit_fifo_size; |
| 1079 | tmp.baud_base = state->baud_base; | 1042 | tmp.baud_base = state->baud_base; |
| 1080 | tmp.close_delay = state->close_delay; | 1043 | tmp.close_delay = state->tport.close_delay; |
| 1081 | tmp.closing_wait = state->closing_wait; | 1044 | tmp.closing_wait = state->tport.closing_wait; |
| 1082 | tmp.custom_divisor = state->custom_divisor; | 1045 | tmp.custom_divisor = state->custom_divisor; |
| 1083 | tty_unlock(); | 1046 | tty_unlock(); |
| 1084 | if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) | 1047 | if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) |
| @@ -1086,38 +1049,34 @@ static int get_serial_info(struct async_struct * info, | |||
| 1086 | return 0; | 1049 | return 0; |
| 1087 | } | 1050 | } |
| 1088 | 1051 | ||
| 1089 | static int set_serial_info(struct async_struct * info, | 1052 | static int set_serial_info(struct tty_struct *tty, struct serial_state *state, |
| 1090 | struct serial_struct __user * new_info) | 1053 | struct serial_struct __user * new_info) |
| 1091 | { | 1054 | { |
| 1055 | struct tty_port *port = &state->tport; | ||
| 1092 | struct serial_struct new_serial; | 1056 | struct serial_struct new_serial; |
| 1093 | struct serial_state old_state, *state; | 1057 | bool change_spd; |
| 1094 | unsigned int change_irq,change_port; | ||
| 1095 | int retval = 0; | 1058 | int retval = 0; |
| 1096 | 1059 | ||
| 1097 | if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) | 1060 | if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) |
| 1098 | return -EFAULT; | 1061 | return -EFAULT; |
| 1099 | 1062 | ||
| 1100 | tty_lock(); | 1063 | tty_lock(); |
| 1101 | state = info->state; | 1064 | change_spd = ((new_serial.flags ^ port->flags) & ASYNC_SPD_MASK) || |
| 1102 | old_state = *state; | 1065 | new_serial.custom_divisor != state->custom_divisor; |
| 1103 | 1066 | if (new_serial.irq || new_serial.port != state->port || | |
| 1104 | change_irq = new_serial.irq != state->irq; | 1067 | new_serial.xmit_fifo_size != state->xmit_fifo_size) { |
| 1105 | change_port = (new_serial.port != state->port); | 1068 | tty_unlock(); |
| 1106 | if(change_irq || change_port || (new_serial.xmit_fifo_size != state->xmit_fifo_size)) { | 1069 | return -EINVAL; |
| 1107 | tty_unlock(); | ||
| 1108 | return -EINVAL; | ||
| 1109 | } | 1070 | } |
| 1110 | 1071 | ||
| 1111 | if (!serial_isroot()) { | 1072 | if (!serial_isroot()) { |
| 1112 | if ((new_serial.baud_base != state->baud_base) || | 1073 | if ((new_serial.baud_base != state->baud_base) || |
| 1113 | (new_serial.close_delay != state->close_delay) || | 1074 | (new_serial.close_delay != port->close_delay) || |
| 1114 | (new_serial.xmit_fifo_size != state->xmit_fifo_size) || | 1075 | (new_serial.xmit_fifo_size != state->xmit_fifo_size) || |
| 1115 | ((new_serial.flags & ~ASYNC_USR_MASK) != | 1076 | ((new_serial.flags & ~ASYNC_USR_MASK) != |
| 1116 | (state->flags & ~ASYNC_USR_MASK))) | 1077 | (port->flags & ~ASYNC_USR_MASK))) |
| 1117 | return -EPERM; | 1078 | return -EPERM; |
| 1118 | state->flags = ((state->flags & ~ASYNC_USR_MASK) | | 1079 | port->flags = ((port->flags & ~ASYNC_USR_MASK) | |
| 1119 | (new_serial.flags & ASYNC_USR_MASK)); | ||
| 1120 | info->flags = ((info->flags & ~ASYNC_USR_MASK) | | ||
| 1121 | (new_serial.flags & ASYNC_USR_MASK)); | 1080 | (new_serial.flags & ASYNC_USR_MASK)); |
| 1122 | state->custom_divisor = new_serial.custom_divisor; | 1081 | state->custom_divisor = new_serial.custom_divisor; |
| 1123 | goto check_and_exit; | 1082 | goto check_and_exit; |
| @@ -1134,32 +1093,28 @@ static int set_serial_info(struct async_struct * info, | |||
| 1134 | */ | 1093 | */ |
| 1135 | 1094 | ||
| 1136 | state->baud_base = new_serial.baud_base; | 1095 | state->baud_base = new_serial.baud_base; |
| 1137 | state->flags = ((state->flags & ~ASYNC_FLAGS) | | 1096 | port->flags = ((port->flags & ~ASYNC_FLAGS) | |
| 1138 | (new_serial.flags & ASYNC_FLAGS)); | 1097 | (new_serial.flags & ASYNC_FLAGS)); |
| 1139 | info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) | | ||
| 1140 | (info->flags & ASYNC_INTERNAL_FLAGS)); | ||
| 1141 | state->custom_divisor = new_serial.custom_divisor; | 1098 | state->custom_divisor = new_serial.custom_divisor; |
| 1142 | state->close_delay = new_serial.close_delay * HZ/100; | 1099 | port->close_delay = new_serial.close_delay * HZ/100; |
| 1143 | state->closing_wait = new_serial.closing_wait * HZ/100; | 1100 | port->closing_wait = new_serial.closing_wait * HZ/100; |
| 1144 | info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 1101 | tty->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
| 1145 | 1102 | ||
| 1146 | check_and_exit: | 1103 | check_and_exit: |
| 1147 | if (info->flags & ASYNC_INITIALIZED) { | 1104 | if (port->flags & ASYNC_INITIALIZED) { |
| 1148 | if (((old_state.flags & ASYNC_SPD_MASK) != | 1105 | if (change_spd) { |
| 1149 | (state->flags & ASYNC_SPD_MASK)) || | 1106 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) |
| 1150 | (old_state.custom_divisor != state->custom_divisor)) { | 1107 | tty->alt_speed = 57600; |
| 1151 | if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) | 1108 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) |
| 1152 | info->tty->alt_speed = 57600; | 1109 | tty->alt_speed = 115200; |
| 1153 | if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) | 1110 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) |
| 1154 | info->tty->alt_speed = 115200; | 1111 | tty->alt_speed = 230400; |
| 1155 | if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) | 1112 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) |
| 1156 | info->tty->alt_speed = 230400; | 1113 | tty->alt_speed = 460800; |
| 1157 | if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) | 1114 | change_speed(tty, state, NULL); |
| 1158 | info->tty->alt_speed = 460800; | ||
| 1159 | change_speed(info, NULL); | ||
| 1160 | } | 1115 | } |
| 1161 | } else | 1116 | } else |
| 1162 | retval = startup(info); | 1117 | retval = startup(tty, state); |
| 1163 | tty_unlock(); | 1118 | tty_unlock(); |
| 1164 | return retval; | 1119 | return retval; |
| 1165 | } | 1120 | } |
| @@ -1175,7 +1130,7 @@ check_and_exit: | |||
| 1175 | * transmit holding register is empty. This functionality | 1130 | * transmit holding register is empty. This functionality |
| 1176 | * allows an RS485 driver to be written in user space. | 1131 | * allows an RS485 driver to be written in user space. |
| 1177 | */ | 1132 | */ |
| 1178 | static int get_lsr_info(struct async_struct * info, unsigned int __user *value) | 1133 | static int get_lsr_info(struct serial_state *info, unsigned int __user *value) |
| 1179 | { | 1134 | { |
| 1180 | unsigned char status; | 1135 | unsigned char status; |
| 1181 | unsigned int result; | 1136 | unsigned int result; |
| @@ -1194,7 +1149,7 @@ static int get_lsr_info(struct async_struct * info, unsigned int __user *value) | |||
| 1194 | 1149 | ||
| 1195 | static int rs_tiocmget(struct tty_struct *tty) | 1150 | static int rs_tiocmget(struct tty_struct *tty) |
| 1196 | { | 1151 | { |
| 1197 | struct async_struct * info = tty->driver_data; | 1152 | struct serial_state *info = tty->driver_data; |
| 1198 | unsigned char control, status; | 1153 | unsigned char control, status; |
| 1199 | unsigned long flags; | 1154 | unsigned long flags; |
| 1200 | 1155 | ||
| @@ -1217,7 +1172,7 @@ static int rs_tiocmget(struct tty_struct *tty) | |||
| 1217 | static int rs_tiocmset(struct tty_struct *tty, unsigned int set, | 1172 | static int rs_tiocmset(struct tty_struct *tty, unsigned int set, |
| 1218 | unsigned int clear) | 1173 | unsigned int clear) |
| 1219 | { | 1174 | { |
| 1220 | struct async_struct * info = tty->driver_data; | 1175 | struct serial_state *info = tty->driver_data; |
| 1221 | unsigned long flags; | 1176 | unsigned long flags; |
| 1222 | 1177 | ||
| 1223 | if (serial_paranoia_check(info, tty->name, "rs_ioctl")) | 1178 | if (serial_paranoia_check(info, tty->name, "rs_ioctl")) |
| @@ -1244,7 +1199,7 @@ static int rs_tiocmset(struct tty_struct *tty, unsigned int set, | |||
| 1244 | */ | 1199 | */ |
| 1245 | static int rs_break(struct tty_struct *tty, int break_state) | 1200 | static int rs_break(struct tty_struct *tty, int break_state) |
| 1246 | { | 1201 | { |
| 1247 | struct async_struct * info = tty->driver_data; | 1202 | struct serial_state *info = tty->driver_data; |
| 1248 | unsigned long flags; | 1203 | unsigned long flags; |
| 1249 | 1204 | ||
| 1250 | if (serial_paranoia_check(info, tty->name, "rs_break")) | 1205 | if (serial_paranoia_check(info, tty->name, "rs_break")) |
| @@ -1269,12 +1224,12 @@ static int rs_break(struct tty_struct *tty, int break_state) | |||
| 1269 | static int rs_get_icount(struct tty_struct *tty, | 1224 | static int rs_get_icount(struct tty_struct *tty, |
| 1270 | struct serial_icounter_struct *icount) | 1225 | struct serial_icounter_struct *icount) |
| 1271 | { | 1226 | { |
| 1272 | struct async_struct *info = tty->driver_data; | 1227 | struct serial_state *info = tty->driver_data; |
| 1273 | struct async_icount cnow; | 1228 | struct async_icount cnow; |
| 1274 | unsigned long flags; | 1229 | unsigned long flags; |
| 1275 | 1230 | ||
| 1276 | local_irq_save(flags); | 1231 | local_irq_save(flags); |
| 1277 | cnow = info->state->icount; | 1232 | cnow = info->icount; |
| 1278 | local_irq_restore(flags); | 1233 | local_irq_restore(flags); |
| 1279 | icount->cts = cnow.cts; | 1234 | icount->cts = cnow.cts; |
| 1280 | icount->dsr = cnow.dsr; | 1235 | icount->dsr = cnow.dsr; |
| @@ -1294,7 +1249,7 @@ static int rs_get_icount(struct tty_struct *tty, | |||
| 1294 | static int rs_ioctl(struct tty_struct *tty, | 1249 | static int rs_ioctl(struct tty_struct *tty, |
| 1295 | unsigned int cmd, unsigned long arg) | 1250 | unsigned int cmd, unsigned long arg) |
| 1296 | { | 1251 | { |
| 1297 | struct async_struct * info = tty->driver_data; | 1252 | struct serial_state *info = tty->driver_data; |
| 1298 | struct async_icount cprev, cnow; /* kernel counter temps */ | 1253 | struct async_icount cprev, cnow; /* kernel counter temps */ |
| 1299 | void __user *argp = (void __user *)arg; | 1254 | void __user *argp = (void __user *)arg; |
| 1300 | unsigned long flags; | 1255 | unsigned long flags; |
| @@ -1311,9 +1266,9 @@ static int rs_ioctl(struct tty_struct *tty, | |||
| 1311 | 1266 | ||
| 1312 | switch (cmd) { | 1267 | switch (cmd) { |
| 1313 | case TIOCGSERIAL: | 1268 | case TIOCGSERIAL: |
| 1314 | return get_serial_info(info, argp); | 1269 | return get_serial_info(tty, info, argp); |
| 1315 | case TIOCSSERIAL: | 1270 | case TIOCSSERIAL: |
| 1316 | return set_serial_info(info, argp); | 1271 | return set_serial_info(tty, info, argp); |
| 1317 | case TIOCSERCONFIG: | 1272 | case TIOCSERCONFIG: |
| 1318 | return 0; | 1273 | return 0; |
| 1319 | 1274 | ||
| @@ -1322,7 +1277,7 @@ static int rs_ioctl(struct tty_struct *tty, | |||
| 1322 | 1277 | ||
| 1323 | case TIOCSERGSTRUCT: | 1278 | case TIOCSERGSTRUCT: |
| 1324 | if (copy_to_user(argp, | 1279 | if (copy_to_user(argp, |
| 1325 | info, sizeof(struct async_struct))) | 1280 | info, sizeof(struct serial_state))) |
| 1326 | return -EFAULT; | 1281 | return -EFAULT; |
| 1327 | return 0; | 1282 | return 0; |
| 1328 | 1283 | ||
| @@ -1335,15 +1290,15 @@ static int rs_ioctl(struct tty_struct *tty, | |||
| 1335 | case TIOCMIWAIT: | 1290 | case TIOCMIWAIT: |
| 1336 | local_irq_save(flags); | 1291 | local_irq_save(flags); |
| 1337 | /* note the counters on entry */ | 1292 | /* note the counters on entry */ |
| 1338 | cprev = info->state->icount; | 1293 | cprev = info->icount; |
| 1339 | local_irq_restore(flags); | 1294 | local_irq_restore(flags); |
| 1340 | while (1) { | 1295 | while (1) { |
| 1341 | interruptible_sleep_on(&info->delta_msr_wait); | 1296 | interruptible_sleep_on(&info->tport.delta_msr_wait); |
| 1342 | /* see if a signal did it */ | 1297 | /* see if a signal did it */ |
| 1343 | if (signal_pending(current)) | 1298 | if (signal_pending(current)) |
| 1344 | return -ERESTARTSYS; | 1299 | return -ERESTARTSYS; |
| 1345 | local_irq_save(flags); | 1300 | local_irq_save(flags); |
| 1346 | cnow = info->state->icount; /* atomic copy */ | 1301 | cnow = info->icount; /* atomic copy */ |
| 1347 | local_irq_restore(flags); | 1302 | local_irq_restore(flags); |
| 1348 | if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && | 1303 | if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && |
| 1349 | cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) | 1304 | cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) |
| @@ -1372,11 +1327,11 @@ static int rs_ioctl(struct tty_struct *tty, | |||
| 1372 | 1327 | ||
| 1373 | static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | 1328 | static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) |
| 1374 | { | 1329 | { |
| 1375 | struct async_struct *info = tty->driver_data; | 1330 | struct serial_state *info = tty->driver_data; |
| 1376 | unsigned long flags; | 1331 | unsigned long flags; |
| 1377 | unsigned int cflag = tty->termios->c_cflag; | 1332 | unsigned int cflag = tty->termios->c_cflag; |
| 1378 | 1333 | ||
| 1379 | change_speed(info, old_termios); | 1334 | change_speed(tty, info, old_termios); |
| 1380 | 1335 | ||
| 1381 | /* Handle transition to B0 status */ | 1336 | /* Handle transition to B0 status */ |
| 1382 | if ((old_termios->c_cflag & CBAUD) && | 1337 | if ((old_termios->c_cflag & CBAUD) && |
| @@ -1432,64 +1387,23 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
| 1432 | */ | 1387 | */ |
| 1433 | static void rs_close(struct tty_struct *tty, struct file * filp) | 1388 | static void rs_close(struct tty_struct *tty, struct file * filp) |
| 1434 | { | 1389 | { |
| 1435 | struct async_struct * info = tty->driver_data; | 1390 | struct serial_state *state = tty->driver_data; |
| 1436 | struct serial_state *state; | 1391 | struct tty_port *port = &state->tport; |
| 1437 | unsigned long flags; | ||
| 1438 | 1392 | ||
| 1439 | if (!info || serial_paranoia_check(info, tty->name, "rs_close")) | 1393 | if (serial_paranoia_check(state, tty->name, "rs_close")) |
| 1440 | return; | 1394 | return; |
| 1441 | 1395 | ||
| 1442 | state = info->state; | 1396 | if (tty_port_close_start(port, tty, filp) == 0) |
| 1443 | |||
| 1444 | local_irq_save(flags); | ||
| 1445 | |||
| 1446 | if (tty_hung_up_p(filp)) { | ||
| 1447 | DBG_CNT("before DEC-hung"); | ||
| 1448 | local_irq_restore(flags); | ||
| 1449 | return; | 1397 | return; |
| 1450 | } | ||
| 1451 | 1398 | ||
| 1452 | #ifdef SERIAL_DEBUG_OPEN | ||
| 1453 | printk("rs_close ttys%d, count = %d\n", info->line, state->count); | ||
| 1454 | #endif | ||
| 1455 | if ((tty->count == 1) && (state->count != 1)) { | ||
| 1456 | /* | ||
| 1457 | * Uh, oh. tty->count is 1, which means that the tty | ||
| 1458 | * structure will be freed. state->count should always | ||
| 1459 | * be one in these conditions. If it's greater than | ||
| 1460 | * one, we've got real problems, since it means the | ||
| 1461 | * serial port won't be shutdown. | ||
| 1462 | */ | ||
| 1463 | printk("rs_close: bad serial port count; tty->count is 1, " | ||
| 1464 | "state->count is %d\n", state->count); | ||
| 1465 | state->count = 1; | ||
| 1466 | } | ||
| 1467 | if (--state->count < 0) { | ||
| 1468 | printk("rs_close: bad serial port count for ttys%d: %d\n", | ||
| 1469 | info->line, state->count); | ||
| 1470 | state->count = 0; | ||
| 1471 | } | ||
| 1472 | if (state->count) { | ||
| 1473 | DBG_CNT("before DEC-2"); | ||
| 1474 | local_irq_restore(flags); | ||
| 1475 | return; | ||
| 1476 | } | ||
| 1477 | info->flags |= ASYNC_CLOSING; | ||
| 1478 | /* | ||
| 1479 | * Now we wait for the transmit buffer to clear; and we notify | ||
| 1480 | * the line discipline to only process XON/XOFF characters. | ||
| 1481 | */ | ||
| 1482 | tty->closing = 1; | ||
| 1483 | if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) | ||
| 1484 | tty_wait_until_sent(tty, info->closing_wait); | ||
| 1485 | /* | 1399 | /* |
| 1486 | * At this point we stop accepting input. To do this, we | 1400 | * At this point we stop accepting input. To do this, we |
| 1487 | * disable the receive line status interrupts, and tell the | 1401 | * disable the receive line status interrupts, and tell the |
| 1488 | * interrupt driver to stop checking the data ready bit in the | 1402 | * interrupt driver to stop checking the data ready bit in the |
| 1489 | * line status register. | 1403 | * line status register. |
| 1490 | */ | 1404 | */ |
| 1491 | info->read_status_mask &= ~UART_LSR_DR; | 1405 | state->read_status_mask &= ~UART_LSR_DR; |
| 1492 | if (info->flags & ASYNC_INITIALIZED) { | 1406 | if (port->flags & ASYNC_INITIALIZED) { |
| 1493 | /* disable receive interrupts */ | 1407 | /* disable receive interrupts */ |
| 1494 | custom.intena = IF_RBF; | 1408 | custom.intena = IF_RBF; |
| 1495 | mb(); | 1409 | mb(); |
| @@ -1502,24 +1416,15 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
| 1502 | * has completely drained; this is especially | 1416 | * has completely drained; this is especially |
| 1503 | * important if there is a transmit FIFO! | 1417 | * important if there is a transmit FIFO! |
| 1504 | */ | 1418 | */ |
| 1505 | rs_wait_until_sent(tty, info->timeout); | 1419 | rs_wait_until_sent(tty, state->timeout); |
| 1506 | } | 1420 | } |
| 1507 | shutdown(info); | 1421 | shutdown(tty, state); |
| 1508 | rs_flush_buffer(tty); | 1422 | rs_flush_buffer(tty); |
| 1509 | 1423 | ||
| 1510 | tty_ldisc_flush(tty); | 1424 | tty_ldisc_flush(tty); |
| 1511 | tty->closing = 0; | 1425 | port->tty = NULL; |
| 1512 | info->event = 0; | 1426 | |
| 1513 | info->tty = NULL; | 1427 | tty_port_close_end(port, tty); |
| 1514 | if (info->blocked_open) { | ||
| 1515 | if (info->close_delay) { | ||
| 1516 | msleep_interruptible(jiffies_to_msecs(info->close_delay)); | ||
| 1517 | } | ||
| 1518 | wake_up_interruptible(&info->open_wait); | ||
| 1519 | } | ||
| 1520 | info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | ||
| 1521 | wake_up_interruptible(&info->close_wait); | ||
| 1522 | local_irq_restore(flags); | ||
| 1523 | } | 1428 | } |
| 1524 | 1429 | ||
| 1525 | /* | 1430 | /* |
| @@ -1527,7 +1432,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
| 1527 | */ | 1432 | */ |
| 1528 | static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | 1433 | static void rs_wait_until_sent(struct tty_struct *tty, int timeout) |
| 1529 | { | 1434 | { |
| 1530 | struct async_struct * info = tty->driver_data; | 1435 | struct serial_state *info = tty->driver_data; |
| 1531 | unsigned long orig_jiffies, char_time; | 1436 | unsigned long orig_jiffies, char_time; |
| 1532 | int lsr; | 1437 | int lsr; |
| 1533 | 1438 | ||
| @@ -1590,173 +1495,17 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | |||
| 1590 | */ | 1495 | */ |
| 1591 | static void rs_hangup(struct tty_struct *tty) | 1496 | static void rs_hangup(struct tty_struct *tty) |
| 1592 | { | 1497 | { |
| 1593 | struct async_struct * info = tty->driver_data; | 1498 | struct serial_state *info = tty->driver_data; |
| 1594 | struct serial_state *state = info->state; | ||
| 1595 | 1499 | ||
| 1596 | if (serial_paranoia_check(info, tty->name, "rs_hangup")) | 1500 | if (serial_paranoia_check(info, tty->name, "rs_hangup")) |
| 1597 | return; | 1501 | return; |
| 1598 | 1502 | ||
| 1599 | state = info->state; | ||
| 1600 | |||
| 1601 | rs_flush_buffer(tty); | 1503 | rs_flush_buffer(tty); |
| 1602 | shutdown(info); | 1504 | shutdown(tty, info); |
| 1603 | info->event = 0; | 1505 | info->tport.count = 0; |
| 1604 | state->count = 0; | 1506 | info->tport.flags &= ~ASYNC_NORMAL_ACTIVE; |
| 1605 | info->flags &= ~ASYNC_NORMAL_ACTIVE; | 1507 | info->tport.tty = NULL; |
| 1606 | info->tty = NULL; | 1508 | wake_up_interruptible(&info->tport.open_wait); |
| 1607 | wake_up_interruptible(&info->open_wait); | ||
| 1608 | } | ||
| 1609 | |||
| 1610 | /* | ||
| 1611 | * ------------------------------------------------------------ | ||
| 1612 | * rs_open() and friends | ||
| 1613 | * ------------------------------------------------------------ | ||
| 1614 | */ | ||
| 1615 | static int block_til_ready(struct tty_struct *tty, struct file * filp, | ||
| 1616 | struct async_struct *info) | ||
| 1617 | { | ||
| 1618 | #ifdef DECLARE_WAITQUEUE | ||
| 1619 | DECLARE_WAITQUEUE(wait, current); | ||
| 1620 | #else | ||
| 1621 | struct wait_queue wait = { current, NULL }; | ||
| 1622 | #endif | ||
| 1623 | struct serial_state *state = info->state; | ||
| 1624 | int retval; | ||
| 1625 | int do_clocal = 0, extra_count = 0; | ||
| 1626 | unsigned long flags; | ||
| 1627 | |||
| 1628 | /* | ||
| 1629 | * If the device is in the middle of being closed, then block | ||
| 1630 | * until it's done, and then try again. | ||
| 1631 | */ | ||
| 1632 | if (tty_hung_up_p(filp) || | ||
| 1633 | (info->flags & ASYNC_CLOSING)) { | ||
| 1634 | if (info->flags & ASYNC_CLOSING) | ||
| 1635 | interruptible_sleep_on(&info->close_wait); | ||
| 1636 | #ifdef SERIAL_DO_RESTART | ||
| 1637 | return ((info->flags & ASYNC_HUP_NOTIFY) ? | ||
| 1638 | -EAGAIN : -ERESTARTSYS); | ||
| 1639 | #else | ||
| 1640 | return -EAGAIN; | ||
| 1641 | #endif | ||
| 1642 | } | ||
| 1643 | |||
| 1644 | /* | ||
| 1645 | * If non-blocking mode is set, or the port is not enabled, | ||
| 1646 | * then make the check up front and then exit. | ||
| 1647 | */ | ||
| 1648 | if ((filp->f_flags & O_NONBLOCK) || | ||
| 1649 | (tty->flags & (1 << TTY_IO_ERROR))) { | ||
| 1650 | info->flags |= ASYNC_NORMAL_ACTIVE; | ||
| 1651 | return 0; | ||
| 1652 | } | ||
| 1653 | |||
| 1654 | if (tty->termios->c_cflag & CLOCAL) | ||
| 1655 | do_clocal = 1; | ||
| 1656 | |||
| 1657 | /* | ||
| 1658 | * Block waiting for the carrier detect and the line to become | ||
| 1659 | * free (i.e., not in use by the callout). While we are in | ||
| 1660 | * this loop, state->count is dropped by one, so that | ||
| 1661 | * rs_close() knows when to free things. We restore it upon | ||
| 1662 | * exit, either normal or abnormal. | ||
| 1663 | */ | ||
| 1664 | retval = 0; | ||
| 1665 | add_wait_queue(&info->open_wait, &wait); | ||
| 1666 | #ifdef SERIAL_DEBUG_OPEN | ||
| 1667 | printk("block_til_ready before block: ttys%d, count = %d\n", | ||
| 1668 | state->line, state->count); | ||
| 1669 | #endif | ||
| 1670 | local_irq_save(flags); | ||
| 1671 | if (!tty_hung_up_p(filp)) { | ||
| 1672 | extra_count = 1; | ||
| 1673 | state->count--; | ||
| 1674 | } | ||
| 1675 | local_irq_restore(flags); | ||
| 1676 | info->blocked_open++; | ||
| 1677 | while (1) { | ||
| 1678 | local_irq_save(flags); | ||
| 1679 | if (tty->termios->c_cflag & CBAUD) | ||
| 1680 | rtsdtr_ctrl(SER_DTR|SER_RTS); | ||
| 1681 | local_irq_restore(flags); | ||
| 1682 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 1683 | if (tty_hung_up_p(filp) || | ||
| 1684 | !(info->flags & ASYNC_INITIALIZED)) { | ||
| 1685 | #ifdef SERIAL_DO_RESTART | ||
| 1686 | if (info->flags & ASYNC_HUP_NOTIFY) | ||
| 1687 | retval = -EAGAIN; | ||
| 1688 | else | ||
| 1689 | retval = -ERESTARTSYS; | ||
| 1690 | #else | ||
| 1691 | retval = -EAGAIN; | ||
| 1692 | #endif | ||
| 1693 | break; | ||
| 1694 | } | ||
| 1695 | if (!(info->flags & ASYNC_CLOSING) && | ||
| 1696 | (do_clocal || (!(ciab.pra & SER_DCD)) )) | ||
| 1697 | break; | ||
| 1698 | if (signal_pending(current)) { | ||
| 1699 | retval = -ERESTARTSYS; | ||
| 1700 | break; | ||
| 1701 | } | ||
| 1702 | #ifdef SERIAL_DEBUG_OPEN | ||
| 1703 | printk("block_til_ready blocking: ttys%d, count = %d\n", | ||
| 1704 | info->line, state->count); | ||
| 1705 | #endif | ||
| 1706 | tty_unlock(); | ||
| 1707 | schedule(); | ||
| 1708 | tty_lock(); | ||
| 1709 | } | ||
| 1710 | __set_current_state(TASK_RUNNING); | ||
| 1711 | remove_wait_queue(&info->open_wait, &wait); | ||
| 1712 | if (extra_count) | ||
| 1713 | state->count++; | ||
| 1714 | info->blocked_open--; | ||
| 1715 | #ifdef SERIAL_DEBUG_OPEN | ||
| 1716 | printk("block_til_ready after blocking: ttys%d, count = %d\n", | ||
| 1717 | info->line, state->count); | ||
| 1718 | #endif | ||
| 1719 | if (retval) | ||
| 1720 | return retval; | ||
| 1721 | info->flags |= ASYNC_NORMAL_ACTIVE; | ||
| 1722 | return 0; | ||
| 1723 | } | ||
| 1724 | |||
| 1725 | static int get_async_struct(int line, struct async_struct **ret_info) | ||
| 1726 | { | ||
| 1727 | struct async_struct *info; | ||
| 1728 | struct serial_state *sstate; | ||
| 1729 | |||
| 1730 | sstate = rs_table + line; | ||
| 1731 | sstate->count++; | ||
| 1732 | if (sstate->info) { | ||
| 1733 | *ret_info = sstate->info; | ||
| 1734 | return 0; | ||
| 1735 | } | ||
| 1736 | info = kzalloc(sizeof(struct async_struct), GFP_KERNEL); | ||
| 1737 | if (!info) { | ||
| 1738 | sstate->count--; | ||
| 1739 | return -ENOMEM; | ||
| 1740 | } | ||
| 1741 | #ifdef DECLARE_WAITQUEUE | ||
| 1742 | init_waitqueue_head(&info->open_wait); | ||
| 1743 | init_waitqueue_head(&info->close_wait); | ||
| 1744 | init_waitqueue_head(&info->delta_msr_wait); | ||
| 1745 | #endif | ||
| 1746 | info->magic = SERIAL_MAGIC; | ||
| 1747 | info->port = sstate->port; | ||
| 1748 | info->flags = sstate->flags; | ||
| 1749 | info->xmit_fifo_size = sstate->xmit_fifo_size; | ||
| 1750 | info->line = line; | ||
| 1751 | tasklet_init(&info->tlet, do_softint, (unsigned long)info); | ||
| 1752 | info->state = sstate; | ||
| 1753 | if (sstate->info) { | ||
| 1754 | kfree(info); | ||
| 1755 | *ret_info = sstate->info; | ||
| 1756 | return 0; | ||
| 1757 | } | ||
| 1758 | *ret_info = sstate->info = info; | ||
| 1759 | return 0; | ||
| 1760 | } | 1509 | } |
| 1761 | 1510 | ||
| 1762 | /* | 1511 | /* |
| @@ -1767,91 +1516,42 @@ static int get_async_struct(int line, struct async_struct **ret_info) | |||
| 1767 | */ | 1516 | */ |
| 1768 | static int rs_open(struct tty_struct *tty, struct file * filp) | 1517 | static int rs_open(struct tty_struct *tty, struct file * filp) |
| 1769 | { | 1518 | { |
| 1770 | struct async_struct *info; | 1519 | struct serial_state *info = rs_table + tty->index; |
| 1771 | int retval, line; | 1520 | struct tty_port *port = &info->tport; |
| 1521 | int retval; | ||
| 1772 | 1522 | ||
| 1773 | line = tty->index; | 1523 | port->count++; |
| 1774 | if ((line < 0) || (line >= NR_PORTS)) { | 1524 | port->tty = tty; |
| 1775 | return -ENODEV; | ||
| 1776 | } | ||
| 1777 | retval = get_async_struct(line, &info); | ||
| 1778 | if (retval) { | ||
| 1779 | return retval; | ||
| 1780 | } | ||
| 1781 | tty->driver_data = info; | 1525 | tty->driver_data = info; |
| 1782 | info->tty = tty; | 1526 | tty->port = port; |
| 1783 | if (serial_paranoia_check(info, tty->name, "rs_open")) | 1527 | if (serial_paranoia_check(info, tty->name, "rs_open")) |
| 1784 | return -ENODEV; | 1528 | return -ENODEV; |
| 1785 | 1529 | ||
| 1786 | #ifdef SERIAL_DEBUG_OPEN | 1530 | tty->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
| 1787 | printk("rs_open %s, count = %d\n", tty->name, info->state->count); | ||
| 1788 | #endif | ||
| 1789 | info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | ||
| 1790 | 1531 | ||
| 1791 | /* | 1532 | retval = startup(tty, info); |
| 1792 | * If the port is the middle of closing, bail out now | ||
| 1793 | */ | ||
| 1794 | if (tty_hung_up_p(filp) || | ||
| 1795 | (info->flags & ASYNC_CLOSING)) { | ||
| 1796 | if (info->flags & ASYNC_CLOSING) | ||
| 1797 | interruptible_sleep_on(&info->close_wait); | ||
| 1798 | #ifdef SERIAL_DO_RESTART | ||
| 1799 | return ((info->flags & ASYNC_HUP_NOTIFY) ? | ||
| 1800 | -EAGAIN : -ERESTARTSYS); | ||
| 1801 | #else | ||
| 1802 | return -EAGAIN; | ||
| 1803 | #endif | ||
| 1804 | } | ||
| 1805 | |||
| 1806 | /* | ||
| 1807 | * Start up serial port | ||
| 1808 | */ | ||
| 1809 | retval = startup(info); | ||
| 1810 | if (retval) { | ||
| 1811 | return retval; | ||
| 1812 | } | ||
| 1813 | |||
| 1814 | retval = block_til_ready(tty, filp, info); | ||
| 1815 | if (retval) { | 1533 | if (retval) { |
| 1816 | #ifdef SERIAL_DEBUG_OPEN | ||
| 1817 | printk("rs_open returning after block_til_ready with %d\n", | ||
| 1818 | retval); | ||
| 1819 | #endif | ||
| 1820 | return retval; | 1534 | return retval; |
| 1821 | } | 1535 | } |
| 1822 | 1536 | ||
| 1823 | #ifdef SERIAL_DEBUG_OPEN | 1537 | return tty_port_block_til_ready(port, tty, filp); |
| 1824 | printk("rs_open %s successful...", tty->name); | ||
| 1825 | #endif | ||
| 1826 | return 0; | ||
| 1827 | } | 1538 | } |
| 1828 | 1539 | ||
| 1829 | /* | 1540 | /* |
| 1830 | * /proc fs routines.... | 1541 | * /proc fs routines.... |
| 1831 | */ | 1542 | */ |
| 1832 | 1543 | ||
| 1833 | static inline void line_info(struct seq_file *m, struct serial_state *state) | 1544 | static inline void line_info(struct seq_file *m, int line, |
| 1545 | struct serial_state *state) | ||
| 1834 | { | 1546 | { |
| 1835 | struct async_struct *info = state->info, scr_info; | ||
| 1836 | char stat_buf[30], control, status; | 1547 | char stat_buf[30], control, status; |
| 1837 | unsigned long flags; | 1548 | unsigned long flags; |
| 1838 | 1549 | ||
| 1839 | seq_printf(m, "%d: uart:amiga_builtin",state->line); | 1550 | seq_printf(m, "%d: uart:amiga_builtin", line); |
| 1840 | 1551 | ||
| 1841 | /* | ||
| 1842 | * Figure out the current RS-232 lines | ||
| 1843 | */ | ||
| 1844 | if (!info) { | ||
| 1845 | info = &scr_info; /* This is just for serial_{in,out} */ | ||
| 1846 | |||
| 1847 | info->magic = SERIAL_MAGIC; | ||
| 1848 | info->flags = state->flags; | ||
| 1849 | info->quot = 0; | ||
| 1850 | info->tty = NULL; | ||
| 1851 | } | ||
| 1852 | local_irq_save(flags); | 1552 | local_irq_save(flags); |
| 1853 | status = ciab.pra; | 1553 | status = ciab.pra; |
| 1854 | control = info ? info->MCR : status; | 1554 | control = (state->tport.flags & ASYNC_INITIALIZED) ? state->MCR : status; |
| 1855 | local_irq_restore(flags); | 1555 | local_irq_restore(flags); |
| 1856 | 1556 | ||
| 1857 | stat_buf[0] = 0; | 1557 | stat_buf[0] = 0; |
| @@ -1867,9 +1567,8 @@ static inline void line_info(struct seq_file *m, struct serial_state *state) | |||
| 1867 | if(!(status & SER_DCD)) | 1567 | if(!(status & SER_DCD)) |
| 1868 | strcat(stat_buf, "|CD"); | 1568 | strcat(stat_buf, "|CD"); |
| 1869 | 1569 | ||
| 1870 | if (info->quot) { | 1570 | if (state->quot) |
| 1871 | seq_printf(m, " baud:%d", state->baud_base / info->quot); | 1571 | seq_printf(m, " baud:%d", state->baud_base / state->quot); |
| 1872 | } | ||
| 1873 | 1572 | ||
| 1874 | seq_printf(m, " tx:%d rx:%d", state->icount.tx, state->icount.rx); | 1573 | seq_printf(m, " tx:%d rx:%d", state->icount.tx, state->icount.rx); |
| 1875 | 1574 | ||
| @@ -1894,7 +1593,7 @@ static inline void line_info(struct seq_file *m, struct serial_state *state) | |||
| 1894 | static int rs_proc_show(struct seq_file *m, void *v) | 1593 | static int rs_proc_show(struct seq_file *m, void *v) |
| 1895 | { | 1594 | { |
| 1896 | seq_printf(m, "serinfo:1.0 driver:%s\n", serial_version); | 1595 | seq_printf(m, "serinfo:1.0 driver:%s\n", serial_version); |
| 1897 | line_info(m, &rs_table[0]); | 1596 | line_info(m, 0, &rs_table[0]); |
| 1898 | return 0; | 1597 | return 0; |
| 1899 | } | 1598 | } |
| 1900 | 1599 | ||
| @@ -1955,6 +1654,32 @@ static const struct tty_operations serial_ops = { | |||
| 1955 | .proc_fops = &rs_proc_fops, | 1654 | .proc_fops = &rs_proc_fops, |
| 1956 | }; | 1655 | }; |
| 1957 | 1656 | ||
| 1657 | static int amiga_carrier_raised(struct tty_port *port) | ||
| 1658 | { | ||
| 1659 | return !(ciab.pra & SER_DCD); | ||
| 1660 | } | ||
| 1661 | |||
| 1662 | static void amiga_dtr_rts(struct tty_port *port, int raise) | ||
| 1663 | { | ||
| 1664 | struct serial_state *info = container_of(port, struct serial_state, | ||
| 1665 | tport); | ||
| 1666 | unsigned long flags; | ||
| 1667 | |||
| 1668 | if (raise) | ||
| 1669 | info->MCR |= SER_DTR|SER_RTS; | ||
| 1670 | else | ||
| 1671 | info->MCR &= ~(SER_DTR|SER_RTS); | ||
| 1672 | |||
| 1673 | local_irq_save(flags); | ||
| 1674 | rtsdtr_ctrl(info->MCR); | ||
| 1675 | local_irq_restore(flags); | ||
| 1676 | } | ||
| 1677 | |||
| 1678 | static const struct tty_port_operations amiga_port_ops = { | ||
| 1679 | .carrier_raised = amiga_carrier_raised, | ||
| 1680 | .dtr_rts = amiga_dtr_rts, | ||
| 1681 | }; | ||
| 1682 | |||
| 1958 | /* | 1683 | /* |
| 1959 | * The serial driver boot-time initialization code! | 1684 | * The serial driver boot-time initialization code! |
| 1960 | */ | 1685 | */ |
| @@ -1964,17 +1689,14 @@ static int __init amiga_serial_probe(struct platform_device *pdev) | |||
| 1964 | struct serial_state * state; | 1689 | struct serial_state * state; |
| 1965 | int error; | 1690 | int error; |
| 1966 | 1691 | ||
| 1967 | serial_driver = alloc_tty_driver(1); | 1692 | serial_driver = alloc_tty_driver(NR_PORTS); |
| 1968 | if (!serial_driver) | 1693 | if (!serial_driver) |
| 1969 | return -ENOMEM; | 1694 | return -ENOMEM; |
| 1970 | 1695 | ||
| 1971 | IRQ_ports = NULL; | ||
| 1972 | |||
| 1973 | show_serial_version(); | 1696 | show_serial_version(); |
| 1974 | 1697 | ||
| 1975 | /* Initialize the tty_driver structure */ | 1698 | /* Initialize the tty_driver structure */ |
| 1976 | 1699 | ||
| 1977 | serial_driver->owner = THIS_MODULE; | ||
| 1978 | serial_driver->driver_name = "amiserial"; | 1700 | serial_driver->driver_name = "amiserial"; |
| 1979 | serial_driver->name = "ttyS"; | 1701 | serial_driver->name = "ttyS"; |
| 1980 | serial_driver->major = TTY_MAJOR; | 1702 | serial_driver->major = TTY_MAJOR; |
| @@ -1992,20 +1714,17 @@ static int __init amiga_serial_probe(struct platform_device *pdev) | |||
| 1992 | goto fail_put_tty_driver; | 1714 | goto fail_put_tty_driver; |
| 1993 | 1715 | ||
| 1994 | state = rs_table; | 1716 | state = rs_table; |
| 1995 | state->magic = SSTATE_MAGIC; | ||
| 1996 | state->port = (int)&custom.serdatr; /* Just to give it a value */ | 1717 | state->port = (int)&custom.serdatr; /* Just to give it a value */ |
| 1997 | state->line = 0; | ||
| 1998 | state->custom_divisor = 0; | 1718 | state->custom_divisor = 0; |
| 1999 | state->close_delay = 5*HZ/10; | ||
| 2000 | state->closing_wait = 30*HZ; | ||
| 2001 | state->icount.cts = state->icount.dsr = | 1719 | state->icount.cts = state->icount.dsr = |
| 2002 | state->icount.rng = state->icount.dcd = 0; | 1720 | state->icount.rng = state->icount.dcd = 0; |
| 2003 | state->icount.rx = state->icount.tx = 0; | 1721 | state->icount.rx = state->icount.tx = 0; |
| 2004 | state->icount.frame = state->icount.parity = 0; | 1722 | state->icount.frame = state->icount.parity = 0; |
| 2005 | state->icount.overrun = state->icount.brk = 0; | 1723 | state->icount.overrun = state->icount.brk = 0; |
| 1724 | tty_port_init(&state->tport); | ||
| 1725 | state->tport.ops = &amiga_port_ops; | ||
| 2006 | 1726 | ||
| 2007 | printk(KERN_INFO "ttyS%d is the amiga builtin serial port\n", | 1727 | printk(KERN_INFO "ttyS0 is the amiga builtin serial port\n"); |
| 2008 | state->line); | ||
| 2009 | 1728 | ||
| 2010 | /* Hardware set up */ | 1729 | /* Hardware set up */ |
| 2011 | 1730 | ||
| @@ -2058,20 +1777,15 @@ static int __exit amiga_serial_remove(struct platform_device *pdev) | |||
| 2058 | { | 1777 | { |
| 2059 | int error; | 1778 | int error; |
| 2060 | struct serial_state *state = platform_get_drvdata(pdev); | 1779 | struct serial_state *state = platform_get_drvdata(pdev); |
| 2061 | struct async_struct *info = state->info; | ||
| 2062 | 1780 | ||
| 2063 | /* printk("Unloading %s: version %s\n", serial_name, serial_version); */ | 1781 | /* printk("Unloading %s: version %s\n", serial_name, serial_version); */ |
| 2064 | tasklet_kill(&info->tlet); | ||
| 2065 | if ((error = tty_unregister_driver(serial_driver))) | 1782 | if ((error = tty_unregister_driver(serial_driver))) |
| 2066 | printk("SERIAL: failed to unregister serial driver (%d)\n", | 1783 | printk("SERIAL: failed to unregister serial driver (%d)\n", |
| 2067 | error); | 1784 | error); |
| 2068 | put_tty_driver(serial_driver); | 1785 | put_tty_driver(serial_driver); |
| 2069 | 1786 | ||
| 2070 | rs_table[0].info = NULL; | 1787 | free_irq(IRQ_AMIGA_TBE, state); |
| 2071 | kfree(info); | 1788 | free_irq(IRQ_AMIGA_RBF, state); |
| 2072 | |||
| 2073 | free_irq(IRQ_AMIGA_TBE, rs_table); | ||
| 2074 | free_irq(IRQ_AMIGA_RBF, rs_table); | ||
| 2075 | 1789 | ||
| 2076 | platform_set_drvdata(pdev, NULL); | 1790 | platform_set_drvdata(pdev, NULL); |
| 2077 | 1791 | ||
diff --git a/drivers/tty/bfin_jtag_comm.c b/drivers/tty/bfin_jtag_comm.c index 3a997760ec32..946f799861f5 100644 --- a/drivers/tty/bfin_jtag_comm.c +++ b/drivers/tty/bfin_jtag_comm.c | |||
| @@ -257,7 +257,6 @@ static int __init bfin_jc_init(void) | |||
| 257 | if (!bfin_jc_driver) | 257 | if (!bfin_jc_driver) |
| 258 | goto err_driver; | 258 | goto err_driver; |
| 259 | 259 | ||
| 260 | bfin_jc_driver->owner = THIS_MODULE; | ||
| 261 | bfin_jc_driver->driver_name = DRV_NAME; | 260 | bfin_jc_driver->driver_name = DRV_NAME; |
| 262 | bfin_jc_driver->name = DEV_NAME; | 261 | bfin_jc_driver->name = DEV_NAME; |
| 263 | bfin_jc_driver->type = TTY_DRIVER_TYPE_SERIAL; | 262 | bfin_jc_driver->type = TTY_DRIVER_TYPE_SERIAL; |
diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c index c9bf779481d8..e61cabdd69df 100644 --- a/drivers/tty/cyclades.c +++ b/drivers/tty/cyclades.c | |||
| @@ -1515,13 +1515,9 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty) | |||
| 1515 | static int cy_open(struct tty_struct *tty, struct file *filp) | 1515 | static int cy_open(struct tty_struct *tty, struct file *filp) |
| 1516 | { | 1516 | { |
| 1517 | struct cyclades_port *info; | 1517 | struct cyclades_port *info; |
| 1518 | unsigned int i, line; | 1518 | unsigned int i, line = tty->index; |
| 1519 | int retval; | 1519 | int retval; |
| 1520 | 1520 | ||
| 1521 | line = tty->index; | ||
| 1522 | if (tty->index < 0 || NR_PORTS <= line) | ||
| 1523 | return -ENODEV; | ||
| 1524 | |||
| 1525 | for (i = 0; i < NR_CARDS; i++) | 1521 | for (i = 0; i < NR_CARDS; i++) |
| 1526 | if (line < cy_card[i].first_line + cy_card[i].nports && | 1522 | if (line < cy_card[i].first_line + cy_card[i].nports && |
| 1527 | line >= cy_card[i].first_line) | 1523 | line >= cy_card[i].first_line) |
| @@ -2413,7 +2409,7 @@ static int get_lsr_info(struct cyclades_port *info, unsigned int __user *value) | |||
| 2413 | /* Not supported yet */ | 2409 | /* Not supported yet */ |
| 2414 | return -EINVAL; | 2410 | return -EINVAL; |
| 2415 | } | 2411 | } |
| 2416 | return put_user(result, (unsigned long __user *)value); | 2412 | return put_user(result, value); |
| 2417 | } | 2413 | } |
| 2418 | 2414 | ||
| 2419 | static int cy_tiocmget(struct tty_struct *tty) | 2415 | static int cy_tiocmget(struct tty_struct *tty) |
| @@ -4090,7 +4086,6 @@ static int __init cy_init(void) | |||
| 4090 | 4086 | ||
| 4091 | /* Initialize the tty_driver structure */ | 4087 | /* Initialize the tty_driver structure */ |
| 4092 | 4088 | ||
| 4093 | cy_serial_driver->owner = THIS_MODULE; | ||
| 4094 | cy_serial_driver->driver_name = "cyclades"; | 4089 | cy_serial_driver->driver_name = "cyclades"; |
| 4095 | cy_serial_driver->name = "ttyC"; | 4090 | cy_serial_driver->name = "ttyC"; |
| 4096 | cy_serial_driver->major = CYCLADES_MAJOR; | 4091 | cy_serial_driver->major = CYCLADES_MAJOR; |
diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index 1595dba0072c..4813684cb634 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c | |||
| @@ -825,7 +825,6 @@ static int __init ehv_bc_init(void) | |||
| 825 | goto error; | 825 | goto error; |
| 826 | } | 826 | } |
| 827 | 827 | ||
| 828 | ehv_bc_driver->owner = THIS_MODULE; | ||
| 829 | ehv_bc_driver->driver_name = "ehv-bc"; | 828 | ehv_bc_driver->driver_name = "ehv-bc"; |
| 830 | ehv_bc_driver->name = ehv_bc_console.name; | 829 | ehv_bc_driver->name = ehv_bc_console.name; |
| 831 | ehv_bc_driver->type = TTY_DRIVER_TYPE_CONSOLE; | 830 | ehv_bc_driver->type = TTY_DRIVER_TYPE_CONSOLE; |
diff --git a/drivers/tty/hvc/hvc_beat.c b/drivers/tty/hvc/hvc_beat.c index 5fe4631e2a61..1560d235449e 100644 --- a/drivers/tty/hvc/hvc_beat.c +++ b/drivers/tty/hvc/hvc_beat.c | |||
| @@ -113,7 +113,7 @@ static int __init hvc_beat_init(void) | |||
| 113 | if (!firmware_has_feature(FW_FEATURE_BEAT)) | 113 | if (!firmware_has_feature(FW_FEATURE_BEAT)) |
| 114 | return -ENODEV; | 114 | return -ENODEV; |
| 115 | 115 | ||
| 116 | hp = hvc_alloc(0, NO_IRQ, &hvc_beat_get_put_ops, 16); | 116 | hp = hvc_alloc(0, 0, &hvc_beat_get_put_ops, 16); |
| 117 | if (IS_ERR(hp)) | 117 | if (IS_ERR(hp)) |
| 118 | return PTR_ERR(hp); | 118 | return PTR_ERR(hp); |
| 119 | hvc_beat_dev = hp; | 119 | hvc_beat_dev = hp; |
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index b6b2d18fa38d..8880adf5fc6f 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c | |||
| @@ -917,7 +917,6 @@ static int hvc_init(void) | |||
| 917 | goto out; | 917 | goto out; |
| 918 | } | 918 | } |
| 919 | 919 | ||
| 920 | drv->owner = THIS_MODULE; | ||
| 921 | drv->driver_name = "hvc"; | 920 | drv->driver_name = "hvc"; |
| 922 | drv->name = "hvc"; | 921 | drv->name = "hvc"; |
| 923 | drv->major = HVC_MAJOR; | 922 | drv->major = HVC_MAJOR; |
diff --git a/drivers/tty/hvc/hvc_rtas.c b/drivers/tty/hvc/hvc_rtas.c index 61c4a61558d9..0069bb86ba49 100644 --- a/drivers/tty/hvc/hvc_rtas.c +++ b/drivers/tty/hvc/hvc_rtas.c | |||
| @@ -94,7 +94,7 @@ static int __init hvc_rtas_init(void) | |||
| 94 | 94 | ||
| 95 | /* Allocate an hvc_struct for the console device we instantiated | 95 | /* Allocate an hvc_struct for the console device we instantiated |
| 96 | * earlier. Save off hp so that we can return it on exit */ | 96 | * earlier. Save off hp so that we can return it on exit */ |
| 97 | hp = hvc_alloc(hvc_rtas_cookie, NO_IRQ, &hvc_rtas_get_put_ops, 16); | 97 | hp = hvc_alloc(hvc_rtas_cookie, 0, &hvc_rtas_get_put_ops, 16); |
| 98 | if (IS_ERR(hp)) | 98 | if (IS_ERR(hp)) |
| 99 | return PTR_ERR(hp); | 99 | return PTR_ERR(hp); |
| 100 | 100 | ||
diff --git a/drivers/tty/hvc/hvc_udbg.c b/drivers/tty/hvc/hvc_udbg.c index b0957e61a7be..4c9b13e7748c 100644 --- a/drivers/tty/hvc/hvc_udbg.c +++ b/drivers/tty/hvc/hvc_udbg.c | |||
| @@ -69,7 +69,7 @@ static int __init hvc_udbg_init(void) | |||
| 69 | 69 | ||
| 70 | BUG_ON(hvc_udbg_dev); | 70 | BUG_ON(hvc_udbg_dev); |
| 71 | 71 | ||
| 72 | hp = hvc_alloc(0, NO_IRQ, &hvc_udbg_ops, 16); | 72 | hp = hvc_alloc(0, 0, &hvc_udbg_ops, 16); |
| 73 | if (IS_ERR(hp)) | 73 | if (IS_ERR(hp)) |
| 74 | return PTR_ERR(hp); | 74 | return PTR_ERR(hp); |
| 75 | 75 | ||
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index 52fdf60bdbe2..a1b0a75c3eae 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c | |||
| @@ -176,7 +176,7 @@ static int __init xen_hvc_init(void) | |||
| 176 | xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn); | 176 | xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn); |
| 177 | } | 177 | } |
| 178 | if (xencons_irq < 0) | 178 | if (xencons_irq < 0) |
| 179 | xencons_irq = 0; /* NO_IRQ */ | 179 | xencons_irq = 0; |
| 180 | else | 180 | else |
| 181 | irq_set_noprobe(xencons_irq); | 181 | irq_set_noprobe(xencons_irq); |
| 182 | 182 | ||
diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index b9040bec36bd..d23759183b47 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c | |||
| @@ -1090,27 +1090,23 @@ static int hvcs_enable_device(struct hvcs_struct *hvcsd, uint32_t unit_address, | |||
| 1090 | */ | 1090 | */ |
| 1091 | static struct hvcs_struct *hvcs_get_by_index(int index) | 1091 | static struct hvcs_struct *hvcs_get_by_index(int index) |
| 1092 | { | 1092 | { |
| 1093 | struct hvcs_struct *hvcsd = NULL; | 1093 | struct hvcs_struct *hvcsd; |
| 1094 | unsigned long flags; | 1094 | unsigned long flags; |
| 1095 | 1095 | ||
| 1096 | spin_lock(&hvcs_structs_lock); | 1096 | spin_lock(&hvcs_structs_lock); |
| 1097 | /* We can immediately discard OOB requests */ | 1097 | list_for_each_entry(hvcsd, &hvcs_structs, next) { |
| 1098 | if (index >= 0 && index < HVCS_MAX_SERVER_ADAPTERS) { | 1098 | spin_lock_irqsave(&hvcsd->lock, flags); |
| 1099 | list_for_each_entry(hvcsd, &hvcs_structs, next) { | 1099 | if (hvcsd->index == index) { |
| 1100 | spin_lock_irqsave(&hvcsd->lock, flags); | 1100 | kref_get(&hvcsd->kref); |
| 1101 | if (hvcsd->index == index) { | ||
| 1102 | kref_get(&hvcsd->kref); | ||
| 1103 | spin_unlock_irqrestore(&hvcsd->lock, flags); | ||
| 1104 | spin_unlock(&hvcs_structs_lock); | ||
| 1105 | return hvcsd; | ||
| 1106 | } | ||
| 1107 | spin_unlock_irqrestore(&hvcsd->lock, flags); | 1101 | spin_unlock_irqrestore(&hvcsd->lock, flags); |
| 1102 | spin_unlock(&hvcs_structs_lock); | ||
| 1103 | return hvcsd; | ||
| 1108 | } | 1104 | } |
| 1109 | hvcsd = NULL; | 1105 | spin_unlock_irqrestore(&hvcsd->lock, flags); |
| 1110 | } | 1106 | } |
| 1111 | |||
| 1112 | spin_unlock(&hvcs_structs_lock); | 1107 | spin_unlock(&hvcs_structs_lock); |
| 1113 | return hvcsd; | 1108 | |
| 1109 | return NULL; | ||
| 1114 | } | 1110 | } |
| 1115 | 1111 | ||
| 1116 | /* | 1112 | /* |
| @@ -1203,7 +1199,7 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp) | |||
| 1203 | { | 1199 | { |
| 1204 | struct hvcs_struct *hvcsd; | 1200 | struct hvcs_struct *hvcsd; |
| 1205 | unsigned long flags; | 1201 | unsigned long flags; |
| 1206 | int irq = NO_IRQ; | 1202 | int irq; |
| 1207 | 1203 | ||
| 1208 | /* | 1204 | /* |
| 1209 | * Is someone trying to close the file associated with this device after | 1205 | * Is someone trying to close the file associated with this device after |
| @@ -1264,7 +1260,7 @@ static void hvcs_hangup(struct tty_struct * tty) | |||
| 1264 | struct hvcs_struct *hvcsd = tty->driver_data; | 1260 | struct hvcs_struct *hvcsd = tty->driver_data; |
| 1265 | unsigned long flags; | 1261 | unsigned long flags; |
| 1266 | int temp_open_count; | 1262 | int temp_open_count; |
| 1267 | int irq = NO_IRQ; | 1263 | int irq; |
| 1268 | 1264 | ||
| 1269 | spin_lock_irqsave(&hvcsd->lock, flags); | 1265 | spin_lock_irqsave(&hvcsd->lock, flags); |
| 1270 | /* Preserve this so that we know how many kref refs to put */ | 1266 | /* Preserve this so that we know how many kref refs to put */ |
| @@ -1499,8 +1495,6 @@ static int __devinit hvcs_initialize(void) | |||
| 1499 | goto index_fail; | 1495 | goto index_fail; |
| 1500 | } | 1496 | } |
| 1501 | 1497 | ||
| 1502 | hvcs_tty_driver->owner = THIS_MODULE; | ||
| 1503 | |||
| 1504 | hvcs_tty_driver->driver_name = hvcs_driver_name; | 1498 | hvcs_tty_driver->driver_name = hvcs_driver_name; |
| 1505 | hvcs_tty_driver->name = hvcs_device_node; | 1499 | hvcs_tty_driver->name = hvcs_device_node; |
| 1506 | 1500 | ||
diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index cdfa3e02d627..a7488b748647 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c | |||
| @@ -737,14 +737,11 @@ static int hvsi_open(struct tty_struct *tty, struct file *filp) | |||
| 737 | { | 737 | { |
| 738 | struct hvsi_struct *hp; | 738 | struct hvsi_struct *hp; |
| 739 | unsigned long flags; | 739 | unsigned long flags; |
| 740 | int line = tty->index; | ||
| 741 | int ret; | 740 | int ret; |
| 742 | 741 | ||
| 743 | pr_debug("%s\n", __func__); | 742 | pr_debug("%s\n", __func__); |
| 744 | 743 | ||
| 745 | if (line < 0 || line >= hvsi_count) | 744 | hp = &hvsi_ports[tty->index]; |
| 746 | return -ENODEV; | ||
| 747 | hp = &hvsi_ports[line]; | ||
| 748 | 745 | ||
| 749 | tty->driver_data = hp; | 746 | tty->driver_data = hp; |
| 750 | 747 | ||
| @@ -1088,7 +1085,6 @@ static int __init hvsi_init(void) | |||
| 1088 | if (!hvsi_driver) | 1085 | if (!hvsi_driver) |
| 1089 | return -ENOMEM; | 1086 | return -ENOMEM; |
| 1090 | 1087 | ||
| 1091 | hvsi_driver->owner = THIS_MODULE; | ||
| 1092 | hvsi_driver->driver_name = "hvsi"; | 1088 | hvsi_driver->driver_name = "hvsi"; |
| 1093 | hvsi_driver->name = "hvsi"; | 1089 | hvsi_driver->name = "hvsi"; |
| 1094 | hvsi_driver->major = HVSI_MAJOR; | 1090 | hvsi_driver->major = HVSI_MAJOR; |
| @@ -1237,7 +1233,7 @@ static int __init hvsi_console_init(void) | |||
| 1237 | hp->state = HVSI_CLOSED; | 1233 | hp->state = HVSI_CLOSED; |
| 1238 | hp->vtermno = *vtermno; | 1234 | hp->vtermno = *vtermno; |
| 1239 | hp->virq = irq_create_mapping(NULL, irq[0]); | 1235 | hp->virq = irq_create_mapping(NULL, irq[0]); |
| 1240 | if (hp->virq == NO_IRQ) { | 1236 | if (hp->virq == 0) { |
| 1241 | printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n", | 1237 | printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n", |
| 1242 | __func__, irq[0]); | 1238 | __func__, irq[0]); |
| 1243 | continue; | 1239 | continue; |
diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c index ef92869502a7..77ceaa9c9e3f 100644 --- a/drivers/tty/ipwireless/tty.c +++ b/drivers/tty/ipwireless/tty.c | |||
| @@ -90,33 +90,23 @@ static void report_deregistering(struct ipw_tty *tty) | |||
| 90 | tty->index); | 90 | tty->index); |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | static struct ipw_tty *get_tty(int minor) | 93 | static struct ipw_tty *get_tty(int index) |
| 94 | { | 94 | { |
| 95 | if (minor < ipw_tty_driver->minor_start | 95 | /* |
| 96 | || minor >= ipw_tty_driver->minor_start + | 96 | * The 'ras_raw' channel is only available when 'loopback' mode |
| 97 | IPWIRELESS_PCMCIA_MINORS) | 97 | * is enabled. |
| 98 | * Number of minor starts with 16 (_RANGE * _RAS_RAW). | ||
| 99 | */ | ||
| 100 | if (!ipwireless_loopback && index >= | ||
| 101 | IPWIRELESS_PCMCIA_MINOR_RANGE * TTYTYPE_RAS_RAW) | ||
| 98 | return NULL; | 102 | return NULL; |
| 99 | else { | 103 | |
| 100 | int minor_offset = minor - ipw_tty_driver->minor_start; | 104 | return ttys[index]; |
| 101 | |||
| 102 | /* | ||
| 103 | * The 'ras_raw' channel is only available when 'loopback' mode | ||
| 104 | * is enabled. | ||
| 105 | * Number of minor starts with 16 (_RANGE * _RAS_RAW). | ||
| 106 | */ | ||
| 107 | if (!ipwireless_loopback && | ||
| 108 | minor_offset >= | ||
| 109 | IPWIRELESS_PCMCIA_MINOR_RANGE * TTYTYPE_RAS_RAW) | ||
| 110 | return NULL; | ||
| 111 | |||
| 112 | return ttys[minor_offset]; | ||
| 113 | } | ||
| 114 | } | 105 | } |
| 115 | 106 | ||
| 116 | static int ipw_open(struct tty_struct *linux_tty, struct file *filp) | 107 | static int ipw_open(struct tty_struct *linux_tty, struct file *filp) |
| 117 | { | 108 | { |
| 118 | int minor = linux_tty->index; | 109 | struct ipw_tty *tty = get_tty(linux_tty->index); |
| 119 | struct ipw_tty *tty = get_tty(minor); | ||
| 120 | 110 | ||
| 121 | if (!tty) | 111 | if (!tty) |
| 122 | return -ENODEV; | 112 | return -ENODEV; |
| @@ -510,7 +500,7 @@ static int add_tty(int j, | |||
| 510 | ipwireless_associate_network_tty(network, | 500 | ipwireless_associate_network_tty(network, |
| 511 | secondary_channel_idx, | 501 | secondary_channel_idx, |
| 512 | ttys[j]); | 502 | ttys[j]); |
| 513 | if (get_tty(j + ipw_tty_driver->minor_start) == ttys[j]) | 503 | if (get_tty(j) == ttys[j]) |
| 514 | report_registering(ttys[j]); | 504 | report_registering(ttys[j]); |
| 515 | return 0; | 505 | return 0; |
| 516 | } | 506 | } |
| @@ -570,7 +560,7 @@ void ipwireless_tty_free(struct ipw_tty *tty) | |||
| 570 | 560 | ||
| 571 | if (ttyj) { | 561 | if (ttyj) { |
| 572 | mutex_lock(&ttyj->ipw_tty_mutex); | 562 | mutex_lock(&ttyj->ipw_tty_mutex); |
| 573 | if (get_tty(j + ipw_tty_driver->minor_start) == ttyj) | 563 | if (get_tty(j) == ttyj) |
| 574 | report_deregistering(ttyj); | 564 | report_deregistering(ttyj); |
| 575 | ttyj->closing = 1; | 565 | ttyj->closing = 1; |
| 576 | if (ttyj->linux_tty != NULL) { | 566 | if (ttyj->linux_tty != NULL) { |
| @@ -614,7 +604,6 @@ int ipwireless_tty_init(void) | |||
| 614 | if (!ipw_tty_driver) | 604 | if (!ipw_tty_driver) |
| 615 | return -ENOMEM; | 605 | return -ENOMEM; |
| 616 | 606 | ||
| 617 | ipw_tty_driver->owner = THIS_MODULE; | ||
| 618 | ipw_tty_driver->driver_name = IPWIRELESS_PCCARD_NAME; | 607 | ipw_tty_driver->driver_name = IPWIRELESS_PCCARD_NAME; |
| 619 | ipw_tty_driver->name = "ttyIPWp"; | 608 | ipw_tty_driver->name = "ttyIPWp"; |
| 620 | ipw_tty_driver->major = 0; | 609 | ipw_tty_driver->major = 0; |
diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c index e5c295ab5dec..03c14979accf 100644 --- a/drivers/tty/isicom.c +++ b/drivers/tty/isicom.c | |||
| @@ -849,8 +849,6 @@ static struct tty_port *isicom_find_port(struct tty_struct *tty) | |||
| 849 | unsigned int board; | 849 | unsigned int board; |
| 850 | int line = tty->index; | 850 | int line = tty->index; |
| 851 | 851 | ||
| 852 | if (line < 0 || line > PORT_COUNT-1) | ||
| 853 | return NULL; | ||
| 854 | board = BOARD(line); | 852 | board = BOARD(line); |
| 855 | card = &isi_card[board]; | 853 | card = &isi_card[board]; |
| 856 | 854 | ||
| @@ -1678,7 +1676,6 @@ static int __init isicom_init(void) | |||
| 1678 | goto error; | 1676 | goto error; |
| 1679 | } | 1677 | } |
| 1680 | 1678 | ||
| 1681 | isicom_normal->owner = THIS_MODULE; | ||
| 1682 | isicom_normal->name = "ttyM"; | 1679 | isicom_normal->name = "ttyM"; |
| 1683 | isicom_normal->major = ISICOM_NMAJOR; | 1680 | isicom_normal->major = ISICOM_NMAJOR; |
| 1684 | isicom_normal->minor_start = 0; | 1681 | isicom_normal->minor_start = 0; |
diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index d15a071b1a54..8a8d0440bab0 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c | |||
| @@ -1036,7 +1036,6 @@ static int __init moxa_init(void) | |||
| 1036 | if (!moxaDriver) | 1036 | if (!moxaDriver) |
| 1037 | return -ENOMEM; | 1037 | return -ENOMEM; |
| 1038 | 1038 | ||
| 1039 | moxaDriver->owner = THIS_MODULE; | ||
| 1040 | moxaDriver->name = "ttyMX"; | 1039 | moxaDriver->name = "ttyMX"; |
| 1041 | moxaDriver->major = ttymajor; | 1040 | moxaDriver->major = ttymajor; |
| 1042 | moxaDriver->minor_start = 0; | 1041 | moxaDriver->minor_start = 0; |
| @@ -1331,7 +1330,7 @@ static void moxa_start(struct tty_struct *tty) | |||
| 1331 | if (ch == NULL) | 1330 | if (ch == NULL) |
| 1332 | return; | 1331 | return; |
| 1333 | 1332 | ||
| 1334 | if (!(ch->statusflags & TXSTOPPED)) | 1333 | if (!test_bit(TXSTOPPED, &ch->statusflags)) |
| 1335 | return; | 1334 | return; |
| 1336 | 1335 | ||
| 1337 | MoxaPortTxEnable(ch); | 1336 | MoxaPortTxEnable(ch); |
diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 8998d527232a..17ff377e4129 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c | |||
| @@ -1010,8 +1010,6 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) | |||
| 1010 | line = tty->index; | 1010 | line = tty->index; |
| 1011 | if (line == MXSER_PORTS) | 1011 | if (line == MXSER_PORTS) |
| 1012 | return 0; | 1012 | return 0; |
| 1013 | if (line < 0 || line > MXSER_PORTS) | ||
| 1014 | return -ENODEV; | ||
| 1015 | info = &mxser_boards[line / MXSER_PORTS_PER_BOARD].ports[line % MXSER_PORTS_PER_BOARD]; | 1013 | info = &mxser_boards[line / MXSER_PORTS_PER_BOARD].ports[line % MXSER_PORTS_PER_BOARD]; |
| 1016 | if (!info->ioaddr) | 1014 | if (!info->ioaddr) |
| 1017 | return -ENODEV; | 1015 | return -ENODEV; |
| @@ -2658,12 +2656,9 @@ static int __init mxser_module_init(void) | |||
| 2658 | MXSER_VERSION); | 2656 | MXSER_VERSION); |
| 2659 | 2657 | ||
| 2660 | /* Initialize the tty_driver structure */ | 2658 | /* Initialize the tty_driver structure */ |
| 2661 | mxvar_sdriver->owner = THIS_MODULE; | ||
| 2662 | mxvar_sdriver->magic = TTY_DRIVER_MAGIC; | ||
| 2663 | mxvar_sdriver->name = "ttyMI"; | 2659 | mxvar_sdriver->name = "ttyMI"; |
| 2664 | mxvar_sdriver->major = ttymajor; | 2660 | mxvar_sdriver->major = ttymajor; |
| 2665 | mxvar_sdriver->minor_start = 0; | 2661 | mxvar_sdriver->minor_start = 0; |
| 2666 | mxvar_sdriver->num = MXSER_PORTS + 1; | ||
| 2667 | mxvar_sdriver->type = TTY_DRIVER_TYPE_SERIAL; | 2662 | mxvar_sdriver->type = TTY_DRIVER_TYPE_SERIAL; |
| 2668 | mxvar_sdriver->subtype = SERIAL_TYPE_NORMAL; | 2663 | mxvar_sdriver->subtype = SERIAL_TYPE_NORMAL; |
| 2669 | mxvar_sdriver->init_termios = tty_std_termios; | 2664 | mxvar_sdriver->init_termios = tty_std_termios; |
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index fc7bbba585ce..c43b683b6eb8 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c | |||
| @@ -3120,7 +3120,6 @@ static int __init gsm_init(void) | |||
| 3120 | pr_err("gsm_init: tty allocation failed.\n"); | 3120 | pr_err("gsm_init: tty allocation failed.\n"); |
| 3121 | return -EINVAL; | 3121 | return -EINVAL; |
| 3122 | } | 3122 | } |
| 3123 | gsm_tty_driver->owner = THIS_MODULE; | ||
| 3124 | gsm_tty_driver->driver_name = "gsmtty"; | 3123 | gsm_tty_driver->driver_name = "gsmtty"; |
| 3125 | gsm_tty_driver->name = "gsmtty"; | 3124 | gsm_tty_driver->name = "gsmtty"; |
| 3126 | gsm_tty_driver->major = 0; /* Dynamic */ | 3125 | gsm_tty_driver->major = 0; /* Dynamic */ |
diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index fd347ff34d07..e7592f9037da 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c | |||
| @@ -1602,13 +1602,9 @@ static int ntty_install(struct tty_driver *driver, struct tty_struct *tty) | |||
| 1602 | int ret; | 1602 | int ret; |
| 1603 | if (!port || !dc || dc->state != NOZOMI_STATE_READY) | 1603 | if (!port || !dc || dc->state != NOZOMI_STATE_READY) |
| 1604 | return -ENODEV; | 1604 | return -ENODEV; |
| 1605 | ret = tty_init_termios(tty); | 1605 | ret = tty_standard_install(driver, tty); |
| 1606 | if (ret == 0) { | 1606 | if (ret == 0) |
| 1607 | tty_driver_kref_get(driver); | ||
| 1608 | tty->count++; | ||
| 1609 | tty->driver_data = port; | 1607 | tty->driver_data = port; |
| 1610 | driver->ttys[tty->index] = tty; | ||
| 1611 | } | ||
| 1612 | return ret; | 1608 | return ret; |
| 1613 | } | 1609 | } |
| 1614 | 1610 | ||
| @@ -1920,7 +1916,6 @@ static __init int nozomi_init(void) | |||
| 1920 | if (!ntty_driver) | 1916 | if (!ntty_driver) |
| 1921 | return -ENOMEM; | 1917 | return -ENOMEM; |
| 1922 | 1918 | ||
| 1923 | ntty_driver->owner = THIS_MODULE; | ||
| 1924 | ntty_driver->driver_name = NOZOMI_NAME_TTY; | 1919 | ntty_driver->driver_name = NOZOMI_NAME_TTY; |
| 1925 | ntty_driver->name = "noz"; | 1920 | ntty_driver->name = "noz"; |
| 1926 | ntty_driver->major = 0; | 1921 | ntty_driver->major = 0; |
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index d8653ab6f498..f96ecaec24f8 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c | |||
| @@ -21,7 +21,6 @@ | |||
| 21 | #include <linux/major.h> | 21 | #include <linux/major.h> |
| 22 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
| 23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
| 24 | #include <linux/sysctl.h> | ||
| 25 | #include <linux/device.h> | 24 | #include <linux/device.h> |
| 26 | #include <linux/uaccess.h> | 25 | #include <linux/uaccess.h> |
| 27 | #include <linux/bitops.h> | 26 | #include <linux/bitops.h> |
| @@ -394,7 +393,6 @@ static void __init legacy_pty_init(void) | |||
| 394 | if (!pty_slave_driver) | 393 | if (!pty_slave_driver) |
| 395 | panic("Couldn't allocate pty slave driver"); | 394 | panic("Couldn't allocate pty slave driver"); |
| 396 | 395 | ||
| 397 | pty_driver->owner = THIS_MODULE; | ||
| 398 | pty_driver->driver_name = "pty_master"; | 396 | pty_driver->driver_name = "pty_master"; |
| 399 | pty_driver->name = "pty"; | 397 | pty_driver->name = "pty"; |
| 400 | pty_driver->major = PTY_MASTER_MAJOR; | 398 | pty_driver->major = PTY_MASTER_MAJOR; |
| @@ -412,7 +410,6 @@ static void __init legacy_pty_init(void) | |||
| 412 | pty_driver->other = pty_slave_driver; | 410 | pty_driver->other = pty_slave_driver; |
| 413 | tty_set_operations(pty_driver, &master_pty_ops_bsd); | 411 | tty_set_operations(pty_driver, &master_pty_ops_bsd); |
| 414 | 412 | ||
| 415 | pty_slave_driver->owner = THIS_MODULE; | ||
| 416 | pty_slave_driver->driver_name = "pty_slave"; | 413 | pty_slave_driver->driver_name = "pty_slave"; |
| 417 | pty_slave_driver->name = "ttyp"; | 414 | pty_slave_driver->name = "ttyp"; |
| 418 | pty_slave_driver->major = PTY_SLAVE_MAJOR; | 415 | pty_slave_driver->major = PTY_SLAVE_MAJOR; |
| @@ -439,55 +436,9 @@ static inline void legacy_pty_init(void) { } | |||
| 439 | 436 | ||
| 440 | /* Unix98 devices */ | 437 | /* Unix98 devices */ |
| 441 | #ifdef CONFIG_UNIX98_PTYS | 438 | #ifdef CONFIG_UNIX98_PTYS |
| 442 | /* | ||
| 443 | * sysctl support for setting limits on the number of Unix98 ptys allocated. | ||
| 444 | * Otherwise one can eat up all kernel memory by opening /dev/ptmx repeatedly. | ||
| 445 | */ | ||
| 446 | int pty_limit = NR_UNIX98_PTY_DEFAULT; | ||
| 447 | static int pty_limit_min; | ||
| 448 | static int pty_limit_max = NR_UNIX98_PTY_MAX; | ||
| 449 | static int pty_count; | ||
| 450 | 439 | ||
| 451 | static struct cdev ptmx_cdev; | 440 | static struct cdev ptmx_cdev; |
| 452 | 441 | ||
| 453 | static struct ctl_table pty_table[] = { | ||
| 454 | { | ||
| 455 | .procname = "max", | ||
| 456 | .maxlen = sizeof(int), | ||
| 457 | .mode = 0644, | ||
| 458 | .data = &pty_limit, | ||
| 459 | .proc_handler = proc_dointvec_minmax, | ||
| 460 | .extra1 = &pty_limit_min, | ||
| 461 | .extra2 = &pty_limit_max, | ||
| 462 | }, { | ||
| 463 | .procname = "nr", | ||
| 464 | .maxlen = sizeof(int), | ||
| 465 | .mode = 0444, | ||
| 466 | .data = &pty_count, | ||
| 467 | .proc_handler = proc_dointvec, | ||
| 468 | }, | ||
| 469 | {} | ||
| 470 | }; | ||
| 471 | |||
| 472 | static struct ctl_table pty_kern_table[] = { | ||
| 473 | { | ||
| 474 | .procname = "pty", | ||
| 475 | .mode = 0555, | ||
| 476 | .child = pty_table, | ||
| 477 | }, | ||
| 478 | {} | ||
| 479 | }; | ||
| 480 | |||
| 481 | static struct ctl_table pty_root_table[] = { | ||
| 482 | { | ||
| 483 | .procname = "kernel", | ||
| 484 | .mode = 0555, | ||
| 485 | .child = pty_kern_table, | ||
| 486 | }, | ||
| 487 | {} | ||
| 488 | }; | ||
| 489 | |||
| 490 | |||
| 491 | static int pty_unix98_ioctl(struct tty_struct *tty, | 442 | static int pty_unix98_ioctl(struct tty_struct *tty, |
| 492 | unsigned int cmd, unsigned long arg) | 443 | unsigned int cmd, unsigned long arg) |
| 493 | { | 444 | { |
| @@ -515,10 +466,8 @@ static int pty_unix98_ioctl(struct tty_struct *tty, | |||
| 515 | static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver, | 466 | static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver, |
| 516 | struct inode *ptm_inode, int idx) | 467 | struct inode *ptm_inode, int idx) |
| 517 | { | 468 | { |
| 518 | struct tty_struct *tty = devpts_get_tty(ptm_inode, idx); | 469 | /* Master must be open via /dev/ptmx */ |
| 519 | if (tty) | 470 | return ERR_PTR(-EIO); |
| 520 | tty = tty->link; | ||
| 521 | return tty; | ||
| 522 | } | 471 | } |
| 523 | 472 | ||
| 524 | /** | 473 | /** |
| @@ -589,7 +538,6 @@ static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty) | |||
| 589 | */ | 538 | */ |
| 590 | tty_driver_kref_get(driver); | 539 | tty_driver_kref_get(driver); |
| 591 | tty->count++; | 540 | tty->count++; |
| 592 | pty_count++; | ||
| 593 | return 0; | 541 | return 0; |
| 594 | err_free_mem: | 542 | err_free_mem: |
| 595 | deinitialize_tty_struct(o_tty); | 543 | deinitialize_tty_struct(o_tty); |
| @@ -603,7 +551,6 @@ err_free_tty: | |||
| 603 | 551 | ||
| 604 | static void ptm_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) | 552 | static void ptm_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) |
| 605 | { | 553 | { |
| 606 | pty_count--; | ||
| 607 | } | 554 | } |
| 608 | 555 | ||
| 609 | static void pts_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) | 556 | static void pts_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) |
| @@ -677,7 +624,7 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
| 677 | 624 | ||
| 678 | mutex_lock(&tty_mutex); | 625 | mutex_lock(&tty_mutex); |
| 679 | tty_lock(); | 626 | tty_lock(); |
| 680 | tty = tty_init_dev(ptm_driver, index, 1); | 627 | tty = tty_init_dev(ptm_driver, index); |
| 681 | mutex_unlock(&tty_mutex); | 628 | mutex_unlock(&tty_mutex); |
| 682 | 629 | ||
| 683 | if (IS_ERR(tty)) { | 630 | if (IS_ERR(tty)) { |
| @@ -722,7 +669,6 @@ static void __init unix98_pty_init(void) | |||
| 722 | if (!pts_driver) | 669 | if (!pts_driver) |
| 723 | panic("Couldn't allocate Unix98 pts driver"); | 670 | panic("Couldn't allocate Unix98 pts driver"); |
| 724 | 671 | ||
| 725 | ptm_driver->owner = THIS_MODULE; | ||
| 726 | ptm_driver->driver_name = "pty_master"; | 672 | ptm_driver->driver_name = "pty_master"; |
| 727 | ptm_driver->name = "ptm"; | 673 | ptm_driver->name = "ptm"; |
| 728 | ptm_driver->major = UNIX98_PTY_MASTER_MAJOR; | 674 | ptm_driver->major = UNIX98_PTY_MASTER_MAJOR; |
| @@ -741,7 +687,6 @@ static void __init unix98_pty_init(void) | |||
| 741 | ptm_driver->other = pts_driver; | 687 | ptm_driver->other = pts_driver; |
| 742 | tty_set_operations(ptm_driver, &ptm_unix98_ops); | 688 | tty_set_operations(ptm_driver, &ptm_unix98_ops); |
| 743 | 689 | ||
| 744 | pts_driver->owner = THIS_MODULE; | ||
| 745 | pts_driver->driver_name = "pty_slave"; | 690 | pts_driver->driver_name = "pty_slave"; |
| 746 | pts_driver->name = "pts"; | 691 | pts_driver->name = "pts"; |
| 747 | pts_driver->major = UNIX98_PTY_SLAVE_MAJOR; | 692 | pts_driver->major = UNIX98_PTY_SLAVE_MAJOR; |
| @@ -762,8 +707,6 @@ static void __init unix98_pty_init(void) | |||
| 762 | if (tty_register_driver(pts_driver)) | 707 | if (tty_register_driver(pts_driver)) |
| 763 | panic("Couldn't register Unix98 pts driver"); | 708 | panic("Couldn't register Unix98 pts driver"); |
| 764 | 709 | ||
| 765 | register_sysctl_table(pty_root_table); | ||
| 766 | |||
| 767 | /* Now create the /dev/ptmx special device */ | 710 | /* Now create the /dev/ptmx special device */ |
| 768 | tty_default_fops(&ptmx_fops); | 711 | tty_default_fops(&ptmx_fops); |
| 769 | ptmx_fops.open = ptmx_open; | 712 | ptmx_fops.open = ptmx_open; |
diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c index de88aa5566e5..777d5f9cf6cc 100644 --- a/drivers/tty/rocket.c +++ b/drivers/tty/rocket.c | |||
| @@ -892,12 +892,12 @@ static int rp_open(struct tty_struct *tty, struct file *filp) | |||
| 892 | { | 892 | { |
| 893 | struct r_port *info; | 893 | struct r_port *info; |
| 894 | struct tty_port *port; | 894 | struct tty_port *port; |
| 895 | int line = 0, retval; | 895 | int retval; |
| 896 | CHANNEL_t *cp; | 896 | CHANNEL_t *cp; |
| 897 | unsigned long page; | 897 | unsigned long page; |
| 898 | 898 | ||
| 899 | line = tty->index; | 899 | info = rp_table[tty->index]; |
| 900 | if (line < 0 || line >= MAX_RP_PORTS || ((info = rp_table[line]) == NULL)) | 900 | if (info == NULL) |
| 901 | return -ENXIO; | 901 | return -ENXIO; |
| 902 | port = &info->port; | 902 | port = &info->port; |
| 903 | 903 | ||
| @@ -2277,7 +2277,6 @@ static int __init rp_init(void) | |||
| 2277 | * driver with the tty layer. | 2277 | * driver with the tty layer. |
| 2278 | */ | 2278 | */ |
| 2279 | 2279 | ||
| 2280 | rocket_driver->owner = THIS_MODULE; | ||
| 2281 | rocket_driver->flags = TTY_DRIVER_DYNAMIC_DEV; | 2280 | rocket_driver->flags = TTY_DRIVER_DYNAMIC_DEV; |
| 2282 | rocket_driver->name = "ttyR"; | 2281 | rocket_driver->name = "ttyR"; |
| 2283 | rocket_driver->driver_name = "Comtrol RocketPort"; | 2282 | rocket_driver->driver_name = "Comtrol RocketPort"; |
diff --git a/drivers/tty/serial/21285.c b/drivers/tty/serial/21285.c index 1b37626e8f13..f899996b4363 100644 --- a/drivers/tty/serial/21285.c +++ b/drivers/tty/serial/21285.c | |||
| @@ -331,7 +331,7 @@ static int serial21285_verify_port(struct uart_port *port, struct serial_struct | |||
| 331 | int ret = 0; | 331 | int ret = 0; |
| 332 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_21285) | 332 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_21285) |
| 333 | ret = -EINVAL; | 333 | ret = -EINVAL; |
| 334 | if (ser->irq != NO_IRQ) | 334 | if (ser->irq <= 0) |
| 335 | ret = -EINVAL; | 335 | ret = -EINVAL; |
| 336 | if (ser->baud_base != port->uartclk / 16) | 336 | if (ser->baud_base != port->uartclk / 16) |
| 337 | ret = -EINVAL; | 337 | ret = -EINVAL; |
| @@ -360,7 +360,7 @@ static struct uart_ops serial21285_ops = { | |||
| 360 | static struct uart_port serial21285_port = { | 360 | static struct uart_port serial21285_port = { |
| 361 | .mapbase = 0x42000160, | 361 | .mapbase = 0x42000160, |
| 362 | .iotype = UPIO_MEM, | 362 | .iotype = UPIO_MEM, |
| 363 | .irq = NO_IRQ, | 363 | .irq = 0, |
| 364 | .fifosize = 16, | 364 | .fifosize = 16, |
| 365 | .ops = &serial21285_ops, | 365 | .ops = &serial21285_ops, |
| 366 | .flags = UPF_BOOT_AUTOCONF, | 366 | .flags = UPF_BOOT_AUTOCONF, |
diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c index a88ef9782a4f..7398390e7e65 100644 --- a/drivers/tty/serial/68328serial.c +++ b/drivers/tty/serial/68328serial.c | |||
| @@ -1190,14 +1190,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
| 1190 | int rs_open(struct tty_struct *tty, struct file * filp) | 1190 | int rs_open(struct tty_struct *tty, struct file * filp) |
| 1191 | { | 1191 | { |
| 1192 | struct m68k_serial *info; | 1192 | struct m68k_serial *info; |
| 1193 | int retval, line; | 1193 | int retval; |
| 1194 | |||
| 1195 | line = tty->index; | ||
| 1196 | |||
| 1197 | if (line >= NR_PORTS || line < 0) /* we have exactly one */ | ||
| 1198 | return -ENODEV; | ||
| 1199 | 1194 | ||
| 1200 | info = &m68k_soft[line]; | 1195 | info = &m68k_soft[tty->index]; |
| 1201 | 1196 | ||
| 1202 | if (serial_paranoia_check(info, tty->name, "rs_open")) | 1197 | if (serial_paranoia_check(info, tty->name, "rs_open")) |
| 1203 | return -ENODEV; | 1198 | return -ENODEV; |
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c index 9b7336fcfbb3..5b149b466ec8 100644 --- a/drivers/tty/serial/8250/8250.c +++ b/drivers/tty/serial/8250/8250.c | |||
| @@ -38,16 +38,15 @@ | |||
| 38 | #include <linux/nmi.h> | 38 | #include <linux/nmi.h> |
| 39 | #include <linux/mutex.h> | 39 | #include <linux/mutex.h> |
| 40 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
| 41 | #ifdef CONFIG_SPARC | ||
| 42 | #include <linux/sunserialcore.h> | ||
| 43 | #endif | ||
| 41 | 44 | ||
| 42 | #include <asm/io.h> | 45 | #include <asm/io.h> |
| 43 | #include <asm/irq.h> | 46 | #include <asm/irq.h> |
| 44 | 47 | ||
| 45 | #include "8250.h" | 48 | #include "8250.h" |
| 46 | 49 | ||
| 47 | #ifdef CONFIG_SPARC | ||
| 48 | #include "../suncore.h" | ||
| 49 | #endif | ||
| 50 | |||
| 51 | /* | 50 | /* |
| 52 | * Configuration: | 51 | * Configuration: |
| 53 | * share_irqs - whether we pass IRQF_SHARED to request_irq(). This option | 52 | * share_irqs - whether we pass IRQF_SHARED to request_irq(). This option |
| @@ -86,13 +85,6 @@ static unsigned int skip_txen_test; /* force skip of txen test at init time */ | |||
| 86 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) | 85 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) |
| 87 | 86 | ||
| 88 | 87 | ||
| 89 | /* | ||
| 90 | * We default to IRQ0 for the "no irq" hack. Some | ||
| 91 | * machine types want others as well - they're free | ||
| 92 | * to redefine this in their header file. | ||
| 93 | */ | ||
| 94 | #define is_real_interrupt(irq) ((irq) != 0) | ||
| 95 | |||
| 96 | #ifdef CONFIG_SERIAL_8250_DETECT_IRQ | 88 | #ifdef CONFIG_SERIAL_8250_DETECT_IRQ |
| 97 | #define CONFIG_SERIAL_DETECT_IRQ 1 | 89 | #define CONFIG_SERIAL_DETECT_IRQ 1 |
| 98 | #endif | 90 | #endif |
| @@ -475,9 +467,8 @@ static void set_io_from_upio(struct uart_port *p) | |||
| 475 | } | 467 | } |
| 476 | 468 | ||
| 477 | static void | 469 | static void |
| 478 | serial_out_sync(struct uart_8250_port *up, int offset, int value) | 470 | serial_port_out_sync(struct uart_port *p, int offset, int value) |
| 479 | { | 471 | { |
| 480 | struct uart_port *p = &up->port; | ||
| 481 | switch (p->iotype) { | 472 | switch (p->iotype) { |
| 482 | case UPIO_MEM: | 473 | case UPIO_MEM: |
| 483 | case UPIO_MEM32: | 474 | case UPIO_MEM32: |
| @@ -490,30 +481,17 @@ serial_out_sync(struct uart_8250_port *up, int offset, int value) | |||
| 490 | } | 481 | } |
| 491 | } | 482 | } |
| 492 | 483 | ||
| 493 | #define serial_in(up, offset) \ | ||
| 494 | (up->port.serial_in(&(up)->port, (offset))) | ||
| 495 | #define serial_out(up, offset, value) \ | ||
| 496 | (up->port.serial_out(&(up)->port, (offset), (value))) | ||
| 497 | /* | ||
| 498 | * We used to support using pause I/O for certain machines. We | ||
| 499 | * haven't supported this for a while, but just in case it's badly | ||
| 500 | * needed for certain old 386 machines, I've left these #define's | ||
| 501 | * in.... | ||
| 502 | */ | ||
| 503 | #define serial_inp(up, offset) serial_in(up, offset) | ||
| 504 | #define serial_outp(up, offset, value) serial_out(up, offset, value) | ||
| 505 | |||
| 506 | /* Uart divisor latch read */ | 484 | /* Uart divisor latch read */ |
| 507 | static inline int _serial_dl_read(struct uart_8250_port *up) | 485 | static inline int _serial_dl_read(struct uart_8250_port *up) |
| 508 | { | 486 | { |
| 509 | return serial_inp(up, UART_DLL) | serial_inp(up, UART_DLM) << 8; | 487 | return serial_in(up, UART_DLL) | serial_in(up, UART_DLM) << 8; |
| 510 | } | 488 | } |
| 511 | 489 | ||
| 512 | /* Uart divisor latch write */ | 490 | /* Uart divisor latch write */ |
| 513 | static inline void _serial_dl_write(struct uart_8250_port *up, int value) | 491 | static inline void _serial_dl_write(struct uart_8250_port *up, int value) |
| 514 | { | 492 | { |
| 515 | serial_outp(up, UART_DLL, value & 0xff); | 493 | serial_out(up, UART_DLL, value & 0xff); |
| 516 | serial_outp(up, UART_DLM, value >> 8 & 0xff); | 494 | serial_out(up, UART_DLM, value >> 8 & 0xff); |
| 517 | } | 495 | } |
| 518 | 496 | ||
| 519 | #if defined(CONFIG_MIPS_ALCHEMY) | 497 | #if defined(CONFIG_MIPS_ALCHEMY) |
| @@ -583,10 +561,10 @@ static unsigned int serial_icr_read(struct uart_8250_port *up, int offset) | |||
| 583 | static void serial8250_clear_fifos(struct uart_8250_port *p) | 561 | static void serial8250_clear_fifos(struct uart_8250_port *p) |
| 584 | { | 562 | { |
| 585 | if (p->capabilities & UART_CAP_FIFO) { | 563 | if (p->capabilities & UART_CAP_FIFO) { |
| 586 | serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO); | 564 | serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO); |
| 587 | serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO | | 565 | serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO | |
| 588 | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); | 566 | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); |
| 589 | serial_outp(p, UART_FCR, 0); | 567 | serial_out(p, UART_FCR, 0); |
| 590 | } | 568 | } |
| 591 | } | 569 | } |
| 592 | 570 | ||
| @@ -599,15 +577,15 @@ static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) | |||
| 599 | { | 577 | { |
| 600 | if (p->capabilities & UART_CAP_SLEEP) { | 578 | if (p->capabilities & UART_CAP_SLEEP) { |
| 601 | if (p->capabilities & UART_CAP_EFR) { | 579 | if (p->capabilities & UART_CAP_EFR) { |
| 602 | serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_B); | 580 | serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); |
| 603 | serial_outp(p, UART_EFR, UART_EFR_ECB); | 581 | serial_out(p, UART_EFR, UART_EFR_ECB); |
| 604 | serial_outp(p, UART_LCR, 0); | 582 | serial_out(p, UART_LCR, 0); |
| 605 | } | 583 | } |
| 606 | serial_outp(p, UART_IER, sleep ? UART_IERX_SLEEP : 0); | 584 | serial_out(p, UART_IER, sleep ? UART_IERX_SLEEP : 0); |
| 607 | if (p->capabilities & UART_CAP_EFR) { | 585 | if (p->capabilities & UART_CAP_EFR) { |
| 608 | serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_B); | 586 | serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); |
| 609 | serial_outp(p, UART_EFR, 0); | 587 | serial_out(p, UART_EFR, 0); |
| 610 | serial_outp(p, UART_LCR, 0); | 588 | serial_out(p, UART_LCR, 0); |
| 611 | } | 589 | } |
| 612 | } | 590 | } |
| 613 | } | 591 | } |
| @@ -622,12 +600,12 @@ static int __enable_rsa(struct uart_8250_port *up) | |||
| 622 | unsigned char mode; | 600 | unsigned char mode; |
| 623 | int result; | 601 | int result; |
| 624 | 602 | ||
| 625 | mode = serial_inp(up, UART_RSA_MSR); | 603 | mode = serial_in(up, UART_RSA_MSR); |
| 626 | result = mode & UART_RSA_MSR_FIFO; | 604 | result = mode & UART_RSA_MSR_FIFO; |
| 627 | 605 | ||
| 628 | if (!result) { | 606 | if (!result) { |
| 629 | serial_outp(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO); | 607 | serial_out(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO); |
| 630 | mode = serial_inp(up, UART_RSA_MSR); | 608 | mode = serial_in(up, UART_RSA_MSR); |
| 631 | result = mode & UART_RSA_MSR_FIFO; | 609 | result = mode & UART_RSA_MSR_FIFO; |
| 632 | } | 610 | } |
| 633 | 611 | ||
| @@ -646,7 +624,7 @@ static void enable_rsa(struct uart_8250_port *up) | |||
| 646 | spin_unlock_irq(&up->port.lock); | 624 | spin_unlock_irq(&up->port.lock); |
| 647 | } | 625 | } |
| 648 | if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) | 626 | if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) |
| 649 | serial_outp(up, UART_RSA_FRR, 0); | 627 | serial_out(up, UART_RSA_FRR, 0); |
| 650 | } | 628 | } |
| 651 | } | 629 | } |
| 652 | 630 | ||
| @@ -665,12 +643,12 @@ static void disable_rsa(struct uart_8250_port *up) | |||
| 665 | up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) { | 643 | up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) { |
| 666 | spin_lock_irq(&up->port.lock); | 644 | spin_lock_irq(&up->port.lock); |
| 667 | 645 | ||
| 668 | mode = serial_inp(up, UART_RSA_MSR); | 646 | mode = serial_in(up, UART_RSA_MSR); |
| 669 | result = !(mode & UART_RSA_MSR_FIFO); | 647 | result = !(mode & UART_RSA_MSR_FIFO); |
| 670 | 648 | ||
| 671 | if (!result) { | 649 | if (!result) { |
| 672 | serial_outp(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO); | 650 | serial_out(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO); |
| 673 | mode = serial_inp(up, UART_RSA_MSR); | 651 | mode = serial_in(up, UART_RSA_MSR); |
| 674 | result = !(mode & UART_RSA_MSR_FIFO); | 652 | result = !(mode & UART_RSA_MSR_FIFO); |
| 675 | } | 653 | } |
| 676 | 654 | ||
| @@ -691,28 +669,28 @@ static int size_fifo(struct uart_8250_port *up) | |||
| 691 | unsigned short old_dl; | 669 | unsigned short old_dl; |
| 692 | int count; | 670 | int count; |
| 693 | 671 | ||
| 694 | old_lcr = serial_inp(up, UART_LCR); | 672 | old_lcr = serial_in(up, UART_LCR); |
| 695 | serial_outp(up, UART_LCR, 0); | 673 | serial_out(up, UART_LCR, 0); |
| 696 | old_fcr = serial_inp(up, UART_FCR); | 674 | old_fcr = serial_in(up, UART_FCR); |
| 697 | old_mcr = serial_inp(up, UART_MCR); | 675 | old_mcr = serial_in(up, UART_MCR); |
| 698 | serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | | 676 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | |
| 699 | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); | 677 | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); |
| 700 | serial_outp(up, UART_MCR, UART_MCR_LOOP); | 678 | serial_out(up, UART_MCR, UART_MCR_LOOP); |
| 701 | serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A); | 679 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); |
| 702 | old_dl = serial_dl_read(up); | 680 | old_dl = serial_dl_read(up); |
| 703 | serial_dl_write(up, 0x0001); | 681 | serial_dl_write(up, 0x0001); |
| 704 | serial_outp(up, UART_LCR, 0x03); | 682 | serial_out(up, UART_LCR, 0x03); |
| 705 | for (count = 0; count < 256; count++) | 683 | for (count = 0; count < 256; count++) |
| 706 | serial_outp(up, UART_TX, count); | 684 | serial_out(up, UART_TX, count); |
| 707 | mdelay(20);/* FIXME - schedule_timeout */ | 685 | mdelay(20);/* FIXME - schedule_timeout */ |
| 708 | for (count = 0; (serial_inp(up, UART_LSR) & UART_LSR_DR) && | 686 | for (count = 0; (serial_in(up, UART_LSR) & UART_LSR_DR) && |
| 709 | (count < 256); count++) | 687 | (count < 256); count++) |
| 710 | serial_inp(up, UART_RX); | 688 | serial_in(up, UART_RX); |
| 711 | serial_outp(up, UART_FCR, old_fcr); | 689 | serial_out(up, UART_FCR, old_fcr); |
| 712 | serial_outp(up, UART_MCR, old_mcr); | 690 | serial_out(up, UART_MCR, old_mcr); |
| 713 | serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A); | 691 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); |
| 714 | serial_dl_write(up, old_dl); | 692 | serial_dl_write(up, old_dl); |
| 715 | serial_outp(up, UART_LCR, old_lcr); | 693 | serial_out(up, UART_LCR, old_lcr); |
| 716 | 694 | ||
| 717 | return count; | 695 | return count; |
| 718 | } | 696 | } |
| @@ -727,20 +705,20 @@ static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p) | |||
| 727 | unsigned char old_dll, old_dlm, old_lcr; | 705 | unsigned char old_dll, old_dlm, old_lcr; |
| 728 | unsigned int id; | 706 | unsigned int id; |
| 729 | 707 | ||
| 730 | old_lcr = serial_inp(p, UART_LCR); | 708 | old_lcr = serial_in(p, UART_LCR); |
| 731 | serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_A); | 709 | serial_out(p, UART_LCR, UART_LCR_CONF_MODE_A); |
| 732 | 710 | ||
| 733 | old_dll = serial_inp(p, UART_DLL); | 711 | old_dll = serial_in(p, UART_DLL); |
| 734 | old_dlm = serial_inp(p, UART_DLM); | 712 | old_dlm = serial_in(p, UART_DLM); |
| 735 | 713 | ||
| 736 | serial_outp(p, UART_DLL, 0); | 714 | serial_out(p, UART_DLL, 0); |
| 737 | serial_outp(p, UART_DLM, 0); | 715 | serial_out(p, UART_DLM, 0); |
| 738 | 716 | ||
| 739 | id = serial_inp(p, UART_DLL) | serial_inp(p, UART_DLM) << 8; | 717 | id = serial_in(p, UART_DLL) | serial_in(p, UART_DLM) << 8; |
| 740 | 718 | ||
| 741 | serial_outp(p, UART_DLL, old_dll); | 719 | serial_out(p, UART_DLL, old_dll); |
| 742 | serial_outp(p, UART_DLM, old_dlm); | 720 | serial_out(p, UART_DLM, old_dlm); |
| 743 | serial_outp(p, UART_LCR, old_lcr); | 721 | serial_out(p, UART_LCR, old_lcr); |
| 744 | 722 | ||
| 745 | return id; | 723 | return id; |
| 746 | } | 724 | } |
| @@ -850,11 +828,11 @@ static void autoconfig_8250(struct uart_8250_port *up) | |||
| 850 | up->port.type = PORT_8250; | 828 | up->port.type = PORT_8250; |
| 851 | 829 | ||
| 852 | scratch = serial_in(up, UART_SCR); | 830 | scratch = serial_in(up, UART_SCR); |
| 853 | serial_outp(up, UART_SCR, 0xa5); | 831 | serial_out(up, UART_SCR, 0xa5); |
| 854 | status1 = serial_in(up, UART_SCR); | 832 | status1 = serial_in(up, UART_SCR); |
| 855 | serial_outp(up, UART_SCR, 0x5a); | 833 | serial_out(up, UART_SCR, 0x5a); |
| 856 | status2 = serial_in(up, UART_SCR); | 834 | status2 = serial_in(up, UART_SCR); |
| 857 | serial_outp(up, UART_SCR, scratch); | 835 | serial_out(up, UART_SCR, scratch); |
| 858 | 836 | ||
| 859 | if (status1 == 0xa5 && status2 == 0x5a) | 837 | if (status1 == 0xa5 && status2 == 0x5a) |
| 860 | up->port.type = PORT_16450; | 838 | up->port.type = PORT_16450; |
| @@ -885,7 +863,7 @@ static inline int ns16550a_goto_highspeed(struct uart_8250_port *up) | |||
| 885 | } else { | 863 | } else { |
| 886 | status &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */ | 864 | status &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */ |
| 887 | status |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ | 865 | status |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ |
| 888 | serial_outp(up, 0x04, status); | 866 | serial_out(up, 0x04, status); |
| 889 | } | 867 | } |
| 890 | return 1; | 868 | return 1; |
| 891 | } | 869 | } |
| @@ -908,9 +886,9 @@ static void autoconfig_16550a(struct uart_8250_port *up) | |||
| 908 | * Check for presence of the EFR when DLAB is set. | 886 | * Check for presence of the EFR when DLAB is set. |
| 909 | * Only ST16C650V1 UARTs pass this test. | 887 | * Only ST16C650V1 UARTs pass this test. |
| 910 | */ | 888 | */ |
| 911 | serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A); | 889 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); |
| 912 | if (serial_in(up, UART_EFR) == 0) { | 890 | if (serial_in(up, UART_EFR) == 0) { |
| 913 | serial_outp(up, UART_EFR, 0xA8); | 891 | serial_out(up, UART_EFR, 0xA8); |
| 914 | if (serial_in(up, UART_EFR) != 0) { | 892 | if (serial_in(up, UART_EFR) != 0) { |
| 915 | DEBUG_AUTOCONF("EFRv1 "); | 893 | DEBUG_AUTOCONF("EFRv1 "); |
| 916 | up->port.type = PORT_16650; | 894 | up->port.type = PORT_16650; |
| @@ -918,7 +896,7 @@ static void autoconfig_16550a(struct uart_8250_port *up) | |||
| 918 | } else { | 896 | } else { |
| 919 | DEBUG_AUTOCONF("Motorola 8xxx DUART "); | 897 | DEBUG_AUTOCONF("Motorola 8xxx DUART "); |
| 920 | } | 898 | } |
| 921 | serial_outp(up, UART_EFR, 0); | 899 | serial_out(up, UART_EFR, 0); |
| 922 | return; | 900 | return; |
| 923 | } | 901 | } |
| 924 | 902 | ||
| @@ -926,7 +904,7 @@ static void autoconfig_16550a(struct uart_8250_port *up) | |||
| 926 | * Maybe it requires 0xbf to be written to the LCR. | 904 | * Maybe it requires 0xbf to be written to the LCR. |
| 927 | * (other ST16C650V2 UARTs, TI16C752A, etc) | 905 | * (other ST16C650V2 UARTs, TI16C752A, etc) |
| 928 | */ | 906 | */ |
| 929 | serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); | 907 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
| 930 | if (serial_in(up, UART_EFR) == 0 && !broken_efr(up)) { | 908 | if (serial_in(up, UART_EFR) == 0 && !broken_efr(up)) { |
| 931 | DEBUG_AUTOCONF("EFRv2 "); | 909 | DEBUG_AUTOCONF("EFRv2 "); |
| 932 | autoconfig_has_efr(up); | 910 | autoconfig_has_efr(up); |
| @@ -940,23 +918,23 @@ static void autoconfig_16550a(struct uart_8250_port *up) | |||
| 940 | * switch back to bank 2, read it from EXCR1 again and check | 918 | * switch back to bank 2, read it from EXCR1 again and check |
| 941 | * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2 | 919 | * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2 |
| 942 | */ | 920 | */ |
| 943 | serial_outp(up, UART_LCR, 0); | 921 | serial_out(up, UART_LCR, 0); |
| 944 | status1 = serial_in(up, UART_MCR); | 922 | status1 = serial_in(up, UART_MCR); |
| 945 | serial_outp(up, UART_LCR, 0xE0); | 923 | serial_out(up, UART_LCR, 0xE0); |
| 946 | status2 = serial_in(up, 0x02); /* EXCR1 */ | 924 | status2 = serial_in(up, 0x02); /* EXCR1 */ |
| 947 | 925 | ||
| 948 | if (!((status2 ^ status1) & UART_MCR_LOOP)) { | 926 | if (!((status2 ^ status1) & UART_MCR_LOOP)) { |
| 949 | serial_outp(up, UART_LCR, 0); | 927 | serial_out(up, UART_LCR, 0); |
| 950 | serial_outp(up, UART_MCR, status1 ^ UART_MCR_LOOP); | 928 | serial_out(up, UART_MCR, status1 ^ UART_MCR_LOOP); |
| 951 | serial_outp(up, UART_LCR, 0xE0); | 929 | serial_out(up, UART_LCR, 0xE0); |
| 952 | status2 = serial_in(up, 0x02); /* EXCR1 */ | 930 | status2 = serial_in(up, 0x02); /* EXCR1 */ |
| 953 | serial_outp(up, UART_LCR, 0); | 931 | serial_out(up, UART_LCR, 0); |
| 954 | serial_outp(up, UART_MCR, status1); | 932 | serial_out(up, UART_MCR, status1); |
| 955 | 933 | ||
| 956 | if ((status2 ^ status1) & UART_MCR_LOOP) { | 934 | if ((status2 ^ status1) & UART_MCR_LOOP) { |
| 957 | unsigned short quot; | 935 | unsigned short quot; |
| 958 | 936 | ||
| 959 | serial_outp(up, UART_LCR, 0xE0); | 937 | serial_out(up, UART_LCR, 0xE0); |
| 960 | 938 | ||
| 961 | quot = serial_dl_read(up); | 939 | quot = serial_dl_read(up); |
| 962 | quot <<= 3; | 940 | quot <<= 3; |
| @@ -964,7 +942,7 @@ static void autoconfig_16550a(struct uart_8250_port *up) | |||
| 964 | if (ns16550a_goto_highspeed(up)) | 942 | if (ns16550a_goto_highspeed(up)) |
| 965 | serial_dl_write(up, quot); | 943 | serial_dl_write(up, quot); |
| 966 | 944 | ||
| 967 | serial_outp(up, UART_LCR, 0); | 945 | serial_out(up, UART_LCR, 0); |
| 968 | 946 | ||
| 969 | up->port.uartclk = 921600*16; | 947 | up->port.uartclk = 921600*16; |
| 970 | up->port.type = PORT_NS16550A; | 948 | up->port.type = PORT_NS16550A; |
| @@ -979,15 +957,15 @@ static void autoconfig_16550a(struct uart_8250_port *up) | |||
| 979 | * Try setting it with and without DLAB set. Cheap clones | 957 | * Try setting it with and without DLAB set. Cheap clones |
| 980 | * set bit 5 without DLAB set. | 958 | * set bit 5 without DLAB set. |
| 981 | */ | 959 | */ |
| 982 | serial_outp(up, UART_LCR, 0); | 960 | serial_out(up, UART_LCR, 0); |
| 983 | serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); | 961 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); |
| 984 | status1 = serial_in(up, UART_IIR) >> 5; | 962 | status1 = serial_in(up, UART_IIR) >> 5; |
| 985 | serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); | 963 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); |
| 986 | serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A); | 964 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); |
| 987 | serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); | 965 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); |
| 988 | status2 = serial_in(up, UART_IIR) >> 5; | 966 | status2 = serial_in(up, UART_IIR) >> 5; |
| 989 | serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); | 967 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); |
| 990 | serial_outp(up, UART_LCR, 0); | 968 | serial_out(up, UART_LCR, 0); |
| 991 | 969 | ||
| 992 | DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2); | 970 | DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2); |
| 993 | 971 | ||
| @@ -1006,13 +984,13 @@ static void autoconfig_16550a(struct uart_8250_port *up) | |||
| 1006 | * already a 1 and maybe locked there before we even start start. | 984 | * already a 1 and maybe locked there before we even start start. |
| 1007 | */ | 985 | */ |
| 1008 | iersave = serial_in(up, UART_IER); | 986 | iersave = serial_in(up, UART_IER); |
| 1009 | serial_outp(up, UART_IER, iersave & ~UART_IER_UUE); | 987 | serial_out(up, UART_IER, iersave & ~UART_IER_UUE); |
| 1010 | if (!(serial_in(up, UART_IER) & UART_IER_UUE)) { | 988 | if (!(serial_in(up, UART_IER) & UART_IER_UUE)) { |
| 1011 | /* | 989 | /* |
| 1012 | * OK it's in a known zero state, try writing and reading | 990 | * OK it's in a known zero state, try writing and reading |
| 1013 | * without disturbing the current state of the other bits. | 991 | * without disturbing the current state of the other bits. |
| 1014 | */ | 992 | */ |
| 1015 | serial_outp(up, UART_IER, iersave | UART_IER_UUE); | 993 | serial_out(up, UART_IER, iersave | UART_IER_UUE); |
| 1016 | if (serial_in(up, UART_IER) & UART_IER_UUE) { | 994 | if (serial_in(up, UART_IER) & UART_IER_UUE) { |
| 1017 | /* | 995 | /* |
| 1018 | * It's an Xscale. | 996 | * It's an Xscale. |
| @@ -1030,7 +1008,7 @@ static void autoconfig_16550a(struct uart_8250_port *up) | |||
| 1030 | */ | 1008 | */ |
| 1031 | DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 "); | 1009 | DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 "); |
| 1032 | } | 1010 | } |
| 1033 | serial_outp(up, UART_IER, iersave); | 1011 | serial_out(up, UART_IER, iersave); |
| 1034 | 1012 | ||
| 1035 | /* | 1013 | /* |
| 1036 | * Exar uarts have EFR in a weird location | 1014 | * Exar uarts have EFR in a weird location |
| @@ -1061,24 +1039,25 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
| 1061 | { | 1039 | { |
| 1062 | unsigned char status1, scratch, scratch2, scratch3; | 1040 | unsigned char status1, scratch, scratch2, scratch3; |
| 1063 | unsigned char save_lcr, save_mcr; | 1041 | unsigned char save_lcr, save_mcr; |
| 1042 | struct uart_port *port = &up->port; | ||
| 1064 | unsigned long flags; | 1043 | unsigned long flags; |
| 1065 | 1044 | ||
| 1066 | if (!up->port.iobase && !up->port.mapbase && !up->port.membase) | 1045 | if (!port->iobase && !port->mapbase && !port->membase) |
| 1067 | return; | 1046 | return; |
| 1068 | 1047 | ||
| 1069 | DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04lx, 0x%p): ", | 1048 | DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04lx, 0x%p): ", |
| 1070 | serial_index(&up->port), up->port.iobase, up->port.membase); | 1049 | serial_index(port), port->iobase, port->membase); |
| 1071 | 1050 | ||
| 1072 | /* | 1051 | /* |
| 1073 | * We really do need global IRQs disabled here - we're going to | 1052 | * We really do need global IRQs disabled here - we're going to |
| 1074 | * be frobbing the chips IRQ enable register to see if it exists. | 1053 | * be frobbing the chips IRQ enable register to see if it exists. |
| 1075 | */ | 1054 | */ |
| 1076 | spin_lock_irqsave(&up->port.lock, flags); | 1055 | spin_lock_irqsave(&port->lock, flags); |
| 1077 | 1056 | ||
| 1078 | up->capabilities = 0; | 1057 | up->capabilities = 0; |
| 1079 | up->bugs = 0; | 1058 | up->bugs = 0; |
| 1080 | 1059 | ||
| 1081 | if (!(up->port.flags & UPF_BUGGY_UART)) { | 1060 | if (!(port->flags & UPF_BUGGY_UART)) { |
| 1082 | /* | 1061 | /* |
| 1083 | * Do a simple existence test first; if we fail this, | 1062 | * Do a simple existence test first; if we fail this, |
| 1084 | * there's no point trying anything else. | 1063 | * there's no point trying anything else. |
| @@ -1092,8 +1071,8 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
| 1092 | * Note: this is safe as long as MCR bit 4 is clear | 1071 | * Note: this is safe as long as MCR bit 4 is clear |
| 1093 | * and the device is in "PC" mode. | 1072 | * and the device is in "PC" mode. |
| 1094 | */ | 1073 | */ |
| 1095 | scratch = serial_inp(up, UART_IER); | 1074 | scratch = serial_in(up, UART_IER); |
| 1096 | serial_outp(up, UART_IER, 0); | 1075 | serial_out(up, UART_IER, 0); |
| 1097 | #ifdef __i386__ | 1076 | #ifdef __i386__ |
| 1098 | outb(0xff, 0x080); | 1077 | outb(0xff, 0x080); |
| 1099 | #endif | 1078 | #endif |
| @@ -1101,13 +1080,13 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
| 1101 | * Mask out IER[7:4] bits for test as some UARTs (e.g. TL | 1080 | * Mask out IER[7:4] bits for test as some UARTs (e.g. TL |
| 1102 | * 16C754B) allow only to modify them if an EFR bit is set. | 1081 | * 16C754B) allow only to modify them if an EFR bit is set. |
| 1103 | */ | 1082 | */ |
| 1104 | scratch2 = serial_inp(up, UART_IER) & 0x0f; | 1083 | scratch2 = serial_in(up, UART_IER) & 0x0f; |
| 1105 | serial_outp(up, UART_IER, 0x0F); | 1084 | serial_out(up, UART_IER, 0x0F); |
| 1106 | #ifdef __i386__ | 1085 | #ifdef __i386__ |
| 1107 | outb(0, 0x080); | 1086 | outb(0, 0x080); |
| 1108 | #endif | 1087 | #endif |
| 1109 | scratch3 = serial_inp(up, UART_IER) & 0x0f; | 1088 | scratch3 = serial_in(up, UART_IER) & 0x0f; |
| 1110 | serial_outp(up, UART_IER, scratch); | 1089 | serial_out(up, UART_IER, scratch); |
| 1111 | if (scratch2 != 0 || scratch3 != 0x0F) { | 1090 | if (scratch2 != 0 || scratch3 != 0x0F) { |
| 1112 | /* | 1091 | /* |
| 1113 | * We failed; there's nothing here | 1092 | * We failed; there's nothing here |
| @@ -1130,10 +1109,10 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
| 1130 | * manufacturer would be stupid enough to design a board | 1109 | * manufacturer would be stupid enough to design a board |
| 1131 | * that conflicts with COM 1-4 --- we hope! | 1110 | * that conflicts with COM 1-4 --- we hope! |
| 1132 | */ | 1111 | */ |
| 1133 | if (!(up->port.flags & UPF_SKIP_TEST)) { | 1112 | if (!(port->flags & UPF_SKIP_TEST)) { |
| 1134 | serial_outp(up, UART_MCR, UART_MCR_LOOP | 0x0A); | 1113 | serial_out(up, UART_MCR, UART_MCR_LOOP | 0x0A); |
| 1135 | status1 = serial_inp(up, UART_MSR) & 0xF0; | 1114 | status1 = serial_in(up, UART_MSR) & 0xF0; |
| 1136 | serial_outp(up, UART_MCR, save_mcr); | 1115 | serial_out(up, UART_MCR, save_mcr); |
| 1137 | if (status1 != 0x90) { | 1116 | if (status1 != 0x90) { |
| 1138 | DEBUG_AUTOCONF("LOOP test failed (%02x) ", | 1117 | DEBUG_AUTOCONF("LOOP test failed (%02x) ", |
| 1139 | status1); | 1118 | status1); |
| @@ -1150,11 +1129,11 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
| 1150 | * We also initialise the EFR (if any) to zero for later. The | 1129 | * We also initialise the EFR (if any) to zero for later. The |
| 1151 | * EFR occupies the same register location as the FCR and IIR. | 1130 | * EFR occupies the same register location as the FCR and IIR. |
| 1152 | */ | 1131 | */ |
| 1153 | serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); | 1132 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
| 1154 | serial_outp(up, UART_EFR, 0); | 1133 | serial_out(up, UART_EFR, 0); |
| 1155 | serial_outp(up, UART_LCR, 0); | 1134 | serial_out(up, UART_LCR, 0); |
| 1156 | 1135 | ||
| 1157 | serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); | 1136 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); |
| 1158 | scratch = serial_in(up, UART_IIR) >> 6; | 1137 | scratch = serial_in(up, UART_IIR) >> 6; |
| 1159 | 1138 | ||
| 1160 | DEBUG_AUTOCONF("iir=%d ", scratch); | 1139 | DEBUG_AUTOCONF("iir=%d ", scratch); |
| @@ -1164,10 +1143,10 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
| 1164 | autoconfig_8250(up); | 1143 | autoconfig_8250(up); |
| 1165 | break; | 1144 | break; |
| 1166 | case 1: | 1145 | case 1: |
| 1167 | up->port.type = PORT_UNKNOWN; | 1146 | port->type = PORT_UNKNOWN; |
| 1168 | break; | 1147 | break; |
| 1169 | case 2: | 1148 | case 2: |
| 1170 | up->port.type = PORT_16550; | 1149 | port->type = PORT_16550; |
| 1171 | break; | 1150 | break; |
| 1172 | case 3: | 1151 | case 3: |
| 1173 | autoconfig_16550a(up); | 1152 | autoconfig_16550a(up); |
| @@ -1178,102 +1157,102 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
| 1178 | /* | 1157 | /* |
| 1179 | * Only probe for RSA ports if we got the region. | 1158 | * Only probe for RSA ports if we got the region. |
| 1180 | */ | 1159 | */ |
| 1181 | if (up->port.type == PORT_16550A && probeflags & PROBE_RSA) { | 1160 | if (port->type == PORT_16550A && probeflags & PROBE_RSA) { |
| 1182 | int i; | 1161 | int i; |
| 1183 | 1162 | ||
| 1184 | for (i = 0 ; i < probe_rsa_count; ++i) { | 1163 | for (i = 0 ; i < probe_rsa_count; ++i) { |
| 1185 | if (probe_rsa[i] == up->port.iobase && | 1164 | if (probe_rsa[i] == port->iobase && __enable_rsa(up)) { |
| 1186 | __enable_rsa(up)) { | 1165 | port->type = PORT_RSA; |
| 1187 | up->port.type = PORT_RSA; | ||
| 1188 | break; | 1166 | break; |
| 1189 | } | 1167 | } |
| 1190 | } | 1168 | } |
| 1191 | } | 1169 | } |
| 1192 | #endif | 1170 | #endif |
| 1193 | 1171 | ||
| 1194 | serial_outp(up, UART_LCR, save_lcr); | 1172 | serial_out(up, UART_LCR, save_lcr); |
| 1195 | 1173 | ||
| 1196 | if (up->capabilities != uart_config[up->port.type].flags) { | 1174 | if (up->capabilities != uart_config[port->type].flags) { |
| 1197 | printk(KERN_WARNING | 1175 | printk(KERN_WARNING |
| 1198 | "ttyS%d: detected caps %08x should be %08x\n", | 1176 | "ttyS%d: detected caps %08x should be %08x\n", |
| 1199 | serial_index(&up->port), up->capabilities, | 1177 | serial_index(port), up->capabilities, |
| 1200 | uart_config[up->port.type].flags); | 1178 | uart_config[port->type].flags); |
| 1201 | } | 1179 | } |
| 1202 | 1180 | ||
| 1203 | up->port.fifosize = uart_config[up->port.type].fifo_size; | 1181 | port->fifosize = uart_config[up->port.type].fifo_size; |
| 1204 | up->capabilities = uart_config[up->port.type].flags; | 1182 | up->capabilities = uart_config[port->type].flags; |
| 1205 | up->tx_loadsz = uart_config[up->port.type].tx_loadsz; | 1183 | up->tx_loadsz = uart_config[port->type].tx_loadsz; |
| 1206 | 1184 | ||
| 1207 | if (up->port.type == PORT_UNKNOWN) | 1185 | if (port->type == PORT_UNKNOWN) |
| 1208 | goto out; | 1186 | goto out; |
| 1209 | 1187 | ||
| 1210 | /* | 1188 | /* |
| 1211 | * Reset the UART. | 1189 | * Reset the UART. |
| 1212 | */ | 1190 | */ |
| 1213 | #ifdef CONFIG_SERIAL_8250_RSA | 1191 | #ifdef CONFIG_SERIAL_8250_RSA |
| 1214 | if (up->port.type == PORT_RSA) | 1192 | if (port->type == PORT_RSA) |
| 1215 | serial_outp(up, UART_RSA_FRR, 0); | 1193 | serial_out(up, UART_RSA_FRR, 0); |
| 1216 | #endif | 1194 | #endif |
| 1217 | serial_outp(up, UART_MCR, save_mcr); | 1195 | serial_out(up, UART_MCR, save_mcr); |
| 1218 | serial8250_clear_fifos(up); | 1196 | serial8250_clear_fifos(up); |
| 1219 | serial_in(up, UART_RX); | 1197 | serial_in(up, UART_RX); |
| 1220 | if (up->capabilities & UART_CAP_UUE) | 1198 | if (up->capabilities & UART_CAP_UUE) |
| 1221 | serial_outp(up, UART_IER, UART_IER_UUE); | 1199 | serial_out(up, UART_IER, UART_IER_UUE); |
| 1222 | else | 1200 | else |
| 1223 | serial_outp(up, UART_IER, 0); | 1201 | serial_out(up, UART_IER, 0); |
| 1224 | 1202 | ||
| 1225 | out: | 1203 | out: |
| 1226 | spin_unlock_irqrestore(&up->port.lock, flags); | 1204 | spin_unlock_irqrestore(&port->lock, flags); |
| 1227 | DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name); | 1205 | DEBUG_AUTOCONF("type=%s\n", uart_config[port->type].name); |
| 1228 | } | 1206 | } |
| 1229 | 1207 | ||
| 1230 | static void autoconfig_irq(struct uart_8250_port *up) | 1208 | static void autoconfig_irq(struct uart_8250_port *up) |
| 1231 | { | 1209 | { |
| 1210 | struct uart_port *port = &up->port; | ||
| 1232 | unsigned char save_mcr, save_ier; | 1211 | unsigned char save_mcr, save_ier; |
| 1233 | unsigned char save_ICP = 0; | 1212 | unsigned char save_ICP = 0; |
| 1234 | unsigned int ICP = 0; | 1213 | unsigned int ICP = 0; |
| 1235 | unsigned long irqs; | 1214 | unsigned long irqs; |
| 1236 | int irq; | 1215 | int irq; |
| 1237 | 1216 | ||
| 1238 | if (up->port.flags & UPF_FOURPORT) { | 1217 | if (port->flags & UPF_FOURPORT) { |
| 1239 | ICP = (up->port.iobase & 0xfe0) | 0x1f; | 1218 | ICP = (port->iobase & 0xfe0) | 0x1f; |
| 1240 | save_ICP = inb_p(ICP); | 1219 | save_ICP = inb_p(ICP); |
| 1241 | outb_p(0x80, ICP); | 1220 | outb_p(0x80, ICP); |
| 1242 | (void) inb_p(ICP); | 1221 | inb_p(ICP); |
| 1243 | } | 1222 | } |
| 1244 | 1223 | ||
| 1245 | /* forget possible initially masked and pending IRQ */ | 1224 | /* forget possible initially masked and pending IRQ */ |
| 1246 | probe_irq_off(probe_irq_on()); | 1225 | probe_irq_off(probe_irq_on()); |
| 1247 | save_mcr = serial_inp(up, UART_MCR); | 1226 | save_mcr = serial_in(up, UART_MCR); |
| 1248 | save_ier = serial_inp(up, UART_IER); | 1227 | save_ier = serial_in(up, UART_IER); |
| 1249 | serial_outp(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2); | 1228 | serial_out(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2); |
| 1250 | 1229 | ||
| 1251 | irqs = probe_irq_on(); | 1230 | irqs = probe_irq_on(); |
| 1252 | serial_outp(up, UART_MCR, 0); | 1231 | serial_out(up, UART_MCR, 0); |
| 1253 | udelay(10); | 1232 | udelay(10); |
| 1254 | if (up->port.flags & UPF_FOURPORT) { | 1233 | if (port->flags & UPF_FOURPORT) { |
| 1255 | serial_outp(up, UART_MCR, | 1234 | serial_out(up, UART_MCR, |
| 1256 | UART_MCR_DTR | UART_MCR_RTS); | 1235 | UART_MCR_DTR | UART_MCR_RTS); |
| 1257 | } else { | 1236 | } else { |
| 1258 | serial_outp(up, UART_MCR, | 1237 | serial_out(up, UART_MCR, |
| 1259 | UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2); | 1238 | UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2); |
| 1260 | } | 1239 | } |
| 1261 | serial_outp(up, UART_IER, 0x0f); /* enable all intrs */ | 1240 | serial_out(up, UART_IER, 0x0f); /* enable all intrs */ |
| 1262 | (void)serial_inp(up, UART_LSR); | 1241 | serial_in(up, UART_LSR); |
| 1263 | (void)serial_inp(up, UART_RX); | 1242 | serial_in(up, UART_RX); |
| 1264 | (void)serial_inp(up, UART_IIR); | 1243 | serial_in(up, UART_IIR); |
| 1265 | (void)serial_inp(up, UART_MSR); | 1244 | serial_in(up, UART_MSR); |
| 1266 | serial_outp(up, UART_TX, 0xFF); | 1245 | serial_out(up, UART_TX, 0xFF); |
| 1267 | udelay(20); | 1246 | udelay(20); |
| 1268 | irq = probe_irq_off(irqs); | 1247 | irq = probe_irq_off(irqs); |
| 1269 | 1248 | ||
| 1270 | serial_outp(up, UART_MCR, save_mcr); | 1249 | serial_out(up, UART_MCR, save_mcr); |
| 1271 | serial_outp(up, UART_IER, save_ier); | 1250 | serial_out(up, UART_IER, save_ier); |
| 1272 | 1251 | ||
| 1273 | if (up->port.flags & UPF_FOURPORT) | 1252 | if (port->flags & UPF_FOURPORT) |
| 1274 | outb_p(save_ICP, ICP); | 1253 | outb_p(save_ICP, ICP); |
| 1275 | 1254 | ||
| 1276 | up->port.irq = (irq > 0) ? irq : 0; | 1255 | port->irq = (irq > 0) ? irq : 0; |
| 1277 | } | 1256 | } |
| 1278 | 1257 | ||
| 1279 | static inline void __stop_tx(struct uart_8250_port *p) | 1258 | static inline void __stop_tx(struct uart_8250_port *p) |
| @@ -1294,7 +1273,7 @@ static void serial8250_stop_tx(struct uart_port *port) | |||
| 1294 | /* | 1273 | /* |
| 1295 | * We really want to stop the transmitter from sending. | 1274 | * We really want to stop the transmitter from sending. |
| 1296 | */ | 1275 | */ |
| 1297 | if (up->port.type == PORT_16C950) { | 1276 | if (port->type == PORT_16C950) { |
| 1298 | up->acr |= UART_ACR_TXDIS; | 1277 | up->acr |= UART_ACR_TXDIS; |
| 1299 | serial_icr_write(up, UART_ACR, up->acr); | 1278 | serial_icr_write(up, UART_ACR, up->acr); |
| 1300 | } | 1279 | } |
| @@ -1307,13 +1286,13 @@ static void serial8250_start_tx(struct uart_port *port) | |||
| 1307 | 1286 | ||
| 1308 | if (!(up->ier & UART_IER_THRI)) { | 1287 | if (!(up->ier & UART_IER_THRI)) { |
| 1309 | up->ier |= UART_IER_THRI; | 1288 | up->ier |= UART_IER_THRI; |
| 1310 | serial_out(up, UART_IER, up->ier); | 1289 | serial_port_out(port, UART_IER, up->ier); |
| 1311 | 1290 | ||
| 1312 | if (up->bugs & UART_BUG_TXEN) { | 1291 | if (up->bugs & UART_BUG_TXEN) { |
| 1313 | unsigned char lsr; | 1292 | unsigned char lsr; |
| 1314 | lsr = serial_in(up, UART_LSR); | 1293 | lsr = serial_in(up, UART_LSR); |
| 1315 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; | 1294 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; |
| 1316 | if ((up->port.type == PORT_RM9000) ? | 1295 | if ((port->type == PORT_RM9000) ? |
| 1317 | (lsr & UART_LSR_THRE) : | 1296 | (lsr & UART_LSR_THRE) : |
| 1318 | (lsr & UART_LSR_TEMT)) | 1297 | (lsr & UART_LSR_TEMT)) |
| 1319 | serial8250_tx_chars(up); | 1298 | serial8250_tx_chars(up); |
| @@ -1323,7 +1302,7 @@ static void serial8250_start_tx(struct uart_port *port) | |||
| 1323 | /* | 1302 | /* |
| 1324 | * Re-enable the transmitter if we disabled it. | 1303 | * Re-enable the transmitter if we disabled it. |
| 1325 | */ | 1304 | */ |
| 1326 | if (up->port.type == PORT_16C950 && up->acr & UART_ACR_TXDIS) { | 1305 | if (port->type == PORT_16C950 && up->acr & UART_ACR_TXDIS) { |
| 1327 | up->acr &= ~UART_ACR_TXDIS; | 1306 | up->acr &= ~UART_ACR_TXDIS; |
| 1328 | serial_icr_write(up, UART_ACR, up->acr); | 1307 | serial_icr_write(up, UART_ACR, up->acr); |
| 1329 | } | 1308 | } |
| @@ -1336,7 +1315,7 @@ static void serial8250_stop_rx(struct uart_port *port) | |||
| 1336 | 1315 | ||
| 1337 | up->ier &= ~UART_IER_RLSI; | 1316 | up->ier &= ~UART_IER_RLSI; |
| 1338 | up->port.read_status_mask &= ~UART_LSR_DR; | 1317 | up->port.read_status_mask &= ~UART_LSR_DR; |
| 1339 | serial_out(up, UART_IER, up->ier); | 1318 | serial_port_out(port, UART_IER, up->ier); |
| 1340 | } | 1319 | } |
| 1341 | 1320 | ||
| 1342 | static void serial8250_enable_ms(struct uart_port *port) | 1321 | static void serial8250_enable_ms(struct uart_port *port) |
| @@ -1349,7 +1328,7 @@ static void serial8250_enable_ms(struct uart_port *port) | |||
| 1349 | return; | 1328 | return; |
| 1350 | 1329 | ||
| 1351 | up->ier |= UART_IER_MSI; | 1330 | up->ier |= UART_IER_MSI; |
| 1352 | serial_out(up, UART_IER, up->ier); | 1331 | serial_port_out(port, UART_IER, up->ier); |
| 1353 | } | 1332 | } |
| 1354 | 1333 | ||
| 1355 | /* | 1334 | /* |
| @@ -1381,14 +1360,15 @@ static void clear_rx_fifo(struct uart_8250_port *up) | |||
| 1381 | unsigned char | 1360 | unsigned char |
| 1382 | serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) | 1361 | serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) |
| 1383 | { | 1362 | { |
| 1384 | struct tty_struct *tty = up->port.state->port.tty; | 1363 | struct uart_port *port = &up->port; |
| 1364 | struct tty_struct *tty = port->state->port.tty; | ||
| 1385 | unsigned char ch; | 1365 | unsigned char ch; |
| 1386 | int max_count = 256; | 1366 | int max_count = 256; |
| 1387 | char flag; | 1367 | char flag; |
| 1388 | 1368 | ||
| 1389 | do { | 1369 | do { |
| 1390 | if (likely(lsr & UART_LSR_DR)) | 1370 | if (likely(lsr & UART_LSR_DR)) |
| 1391 | ch = serial_inp(up, UART_RX); | 1371 | ch = serial_in(up, UART_RX); |
| 1392 | else | 1372 | else |
| 1393 | /* | 1373 | /* |
| 1394 | * Intel 82571 has a Serial Over Lan device that will | 1374 | * Intel 82571 has a Serial Over Lan device that will |
| @@ -1400,7 +1380,7 @@ serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) | |||
| 1400 | ch = 0; | 1380 | ch = 0; |
| 1401 | 1381 | ||
| 1402 | flag = TTY_NORMAL; | 1382 | flag = TTY_NORMAL; |
| 1403 | up->port.icount.rx++; | 1383 | port->icount.rx++; |
| 1404 | 1384 | ||
| 1405 | lsr |= up->lsr_saved_flags; | 1385 | lsr |= up->lsr_saved_flags; |
| 1406 | up->lsr_saved_flags = 0; | 1386 | up->lsr_saved_flags = 0; |
| @@ -1411,12 +1391,12 @@ serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) | |||
| 1411 | */ | 1391 | */ |
| 1412 | if (lsr & UART_LSR_BI) { | 1392 | if (lsr & UART_LSR_BI) { |
| 1413 | lsr &= ~(UART_LSR_FE | UART_LSR_PE); | 1393 | lsr &= ~(UART_LSR_FE | UART_LSR_PE); |
| 1414 | up->port.icount.brk++; | 1394 | port->icount.brk++; |
| 1415 | /* | 1395 | /* |
| 1416 | * If tegra port then clear the rx fifo to | 1396 | * If tegra port then clear the rx fifo to |
| 1417 | * accept another break/character. | 1397 | * accept another break/character. |
| 1418 | */ | 1398 | */ |
| 1419 | if (up->port.type == PORT_TEGRA) | 1399 | if (port->type == PORT_TEGRA) |
| 1420 | clear_rx_fifo(up); | 1400 | clear_rx_fifo(up); |
| 1421 | 1401 | ||
| 1422 | /* | 1402 | /* |
| @@ -1425,19 +1405,19 @@ serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) | |||
| 1425 | * may get masked by ignore_status_mask | 1405 | * may get masked by ignore_status_mask |
| 1426 | * or read_status_mask. | 1406 | * or read_status_mask. |
| 1427 | */ | 1407 | */ |
| 1428 | if (uart_handle_break(&up->port)) | 1408 | if (uart_handle_break(port)) |
| 1429 | goto ignore_char; | 1409 | goto ignore_char; |
| 1430 | } else if (lsr & UART_LSR_PE) | 1410 | } else if (lsr & UART_LSR_PE) |
| 1431 | up->port.icount.parity++; | 1411 | port->icount.parity++; |
| 1432 | else if (lsr & UART_LSR_FE) | 1412 | else if (lsr & UART_LSR_FE) |
| 1433 | up->port.icount.frame++; | 1413 | port->icount.frame++; |
| 1434 | if (lsr & UART_LSR_OE) | 1414 | if (lsr & UART_LSR_OE) |
| 1435 | up->port.icount.overrun++; | 1415 | port->icount.overrun++; |
| 1436 | 1416 | ||
| 1437 | /* | 1417 | /* |
| 1438 | * Mask off conditions which should be ignored. | 1418 | * Mask off conditions which should be ignored. |
| 1439 | */ | 1419 | */ |
| 1440 | lsr &= up->port.read_status_mask; | 1420 | lsr &= port->read_status_mask; |
| 1441 | 1421 | ||
| 1442 | if (lsr & UART_LSR_BI) { | 1422 | if (lsr & UART_LSR_BI) { |
| 1443 | DEBUG_INTR("handling break...."); | 1423 | DEBUG_INTR("handling break...."); |
| @@ -1447,34 +1427,35 @@ serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) | |||
| 1447 | else if (lsr & UART_LSR_FE) | 1427 | else if (lsr & UART_LSR_FE) |
| 1448 | flag = TTY_FRAME; | 1428 | flag = TTY_FRAME; |
| 1449 | } | 1429 | } |
| 1450 | if (uart_handle_sysrq_char(&up->port, ch)) | 1430 | if (uart_handle_sysrq_char(port, ch)) |
| 1451 | goto ignore_char; | 1431 | goto ignore_char; |
| 1452 | 1432 | ||
| 1453 | uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag); | 1433 | uart_insert_char(port, lsr, UART_LSR_OE, ch, flag); |
| 1454 | 1434 | ||
| 1455 | ignore_char: | 1435 | ignore_char: |
| 1456 | lsr = serial_inp(up, UART_LSR); | 1436 | lsr = serial_in(up, UART_LSR); |
| 1457 | } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0)); | 1437 | } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0)); |
| 1458 | spin_unlock(&up->port.lock); | 1438 | spin_unlock(&port->lock); |
| 1459 | tty_flip_buffer_push(tty); | 1439 | tty_flip_buffer_push(tty); |
| 1460 | spin_lock(&up->port.lock); | 1440 | spin_lock(&port->lock); |
| 1461 | return lsr; | 1441 | return lsr; |
| 1462 | } | 1442 | } |
| 1463 | EXPORT_SYMBOL_GPL(serial8250_rx_chars); | 1443 | EXPORT_SYMBOL_GPL(serial8250_rx_chars); |
| 1464 | 1444 | ||
| 1465 | void serial8250_tx_chars(struct uart_8250_port *up) | 1445 | void serial8250_tx_chars(struct uart_8250_port *up) |
| 1466 | { | 1446 | { |
| 1467 | struct circ_buf *xmit = &up->port.state->xmit; | 1447 | struct uart_port *port = &up->port; |
| 1448 | struct circ_buf *xmit = &port->state->xmit; | ||
| 1468 | int count; | 1449 | int count; |
| 1469 | 1450 | ||
| 1470 | if (up->port.x_char) { | 1451 | if (port->x_char) { |
| 1471 | serial_outp(up, UART_TX, up->port.x_char); | 1452 | serial_out(up, UART_TX, port->x_char); |
| 1472 | up->port.icount.tx++; | 1453 | port->icount.tx++; |
| 1473 | up->port.x_char = 0; | 1454 | port->x_char = 0; |
| 1474 | return; | 1455 | return; |
| 1475 | } | 1456 | } |
| 1476 | if (uart_tx_stopped(&up->port)) { | 1457 | if (uart_tx_stopped(port)) { |
| 1477 | serial8250_stop_tx(&up->port); | 1458 | serial8250_stop_tx(port); |
| 1478 | return; | 1459 | return; |
| 1479 | } | 1460 | } |
| 1480 | if (uart_circ_empty(xmit)) { | 1461 | if (uart_circ_empty(xmit)) { |
| @@ -1486,13 +1467,13 @@ void serial8250_tx_chars(struct uart_8250_port *up) | |||
| 1486 | do { | 1467 | do { |
| 1487 | serial_out(up, UART_TX, xmit->buf[xmit->tail]); | 1468 | serial_out(up, UART_TX, xmit->buf[xmit->tail]); |
| 1488 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | 1469 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); |
| 1489 | up->port.icount.tx++; | 1470 | port->icount.tx++; |
| 1490 | if (uart_circ_empty(xmit)) | 1471 | if (uart_circ_empty(xmit)) |
| 1491 | break; | 1472 | break; |
| 1492 | } while (--count > 0); | 1473 | } while (--count > 0); |
| 1493 | 1474 | ||
| 1494 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 1475 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
| 1495 | uart_write_wakeup(&up->port); | 1476 | uart_write_wakeup(port); |
| 1496 | 1477 | ||
| 1497 | DEBUG_INTR("THRE..."); | 1478 | DEBUG_INTR("THRE..."); |
| 1498 | 1479 | ||
| @@ -1503,22 +1484,23 @@ EXPORT_SYMBOL_GPL(serial8250_tx_chars); | |||
| 1503 | 1484 | ||
| 1504 | unsigned int serial8250_modem_status(struct uart_8250_port *up) | 1485 | unsigned int serial8250_modem_status(struct uart_8250_port *up) |
| 1505 | { | 1486 | { |
| 1487 | struct uart_port *port = &up->port; | ||
| 1506 | unsigned int status = serial_in(up, UART_MSR); | 1488 | unsigned int status = serial_in(up, UART_MSR); |
| 1507 | 1489 | ||
| 1508 | status |= up->msr_saved_flags; | 1490 | status |= up->msr_saved_flags; |
| 1509 | up->msr_saved_flags = 0; | 1491 | up->msr_saved_flags = 0; |
| 1510 | if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && | 1492 | if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && |
| 1511 | up->port.state != NULL) { | 1493 | port->state != NULL) { |
| 1512 | if (status & UART_MSR_TERI) | 1494 | if (status & UART_MSR_TERI) |
| 1513 | up->port.icount.rng++; | 1495 | port->icount.rng++; |
| 1514 | if (status & UART_MSR_DDSR) | 1496 | if (status & UART_MSR_DDSR) |
| 1515 | up->port.icount.dsr++; | 1497 | port->icount.dsr++; |
| 1516 | if (status & UART_MSR_DDCD) | 1498 | if (status & UART_MSR_DDCD) |
| 1517 | uart_handle_dcd_change(&up->port, status & UART_MSR_DCD); | 1499 | uart_handle_dcd_change(port, status & UART_MSR_DCD); |
| 1518 | if (status & UART_MSR_DCTS) | 1500 | if (status & UART_MSR_DCTS) |
| 1519 | uart_handle_cts_change(&up->port, status & UART_MSR_CTS); | 1501 | uart_handle_cts_change(port, status & UART_MSR_CTS); |
| 1520 | 1502 | ||
| 1521 | wake_up_interruptible(&up->port.state->port.delta_msr_wait); | 1503 | wake_up_interruptible(&port->state->port.delta_msr_wait); |
| 1522 | } | 1504 | } |
| 1523 | 1505 | ||
| 1524 | return status; | 1506 | return status; |
| @@ -1538,9 +1520,9 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) | |||
| 1538 | if (iir & UART_IIR_NO_INT) | 1520 | if (iir & UART_IIR_NO_INT) |
| 1539 | return 0; | 1521 | return 0; |
| 1540 | 1522 | ||
| 1541 | spin_lock_irqsave(&up->port.lock, flags); | 1523 | spin_lock_irqsave(&port->lock, flags); |
| 1542 | 1524 | ||
| 1543 | status = serial_inp(up, UART_LSR); | 1525 | status = serial_port_in(port, UART_LSR); |
| 1544 | 1526 | ||
| 1545 | DEBUG_INTR("status = %x...", status); | 1527 | DEBUG_INTR("status = %x...", status); |
| 1546 | 1528 | ||
| @@ -1550,16 +1532,14 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) | |||
| 1550 | if (status & UART_LSR_THRE) | 1532 | if (status & UART_LSR_THRE) |
| 1551 | serial8250_tx_chars(up); | 1533 | serial8250_tx_chars(up); |
| 1552 | 1534 | ||
| 1553 | spin_unlock_irqrestore(&up->port.lock, flags); | 1535 | spin_unlock_irqrestore(&port->lock, flags); |
| 1554 | return 1; | 1536 | return 1; |
| 1555 | } | 1537 | } |
| 1556 | EXPORT_SYMBOL_GPL(serial8250_handle_irq); | 1538 | EXPORT_SYMBOL_GPL(serial8250_handle_irq); |
| 1557 | 1539 | ||
| 1558 | static int serial8250_default_handle_irq(struct uart_port *port) | 1540 | static int serial8250_default_handle_irq(struct uart_port *port) |
| 1559 | { | 1541 | { |
| 1560 | struct uart_8250_port *up = | 1542 | unsigned int iir = serial_port_in(port, UART_IIR); |
| 1561 | container_of(port, struct uart_8250_port, port); | ||
| 1562 | unsigned int iir = serial_in(up, UART_IIR); | ||
| 1563 | 1543 | ||
| 1564 | return serial8250_handle_irq(port, iir); | 1544 | return serial8250_handle_irq(port, iir); |
| 1565 | } | 1545 | } |
| @@ -1750,7 +1730,7 @@ static void serial8250_backup_timeout(unsigned long data) | |||
| 1750 | * Must disable interrupts or else we risk racing with the interrupt | 1730 | * Must disable interrupts or else we risk racing with the interrupt |
| 1751 | * based handler. | 1731 | * based handler. |
| 1752 | */ | 1732 | */ |
| 1753 | if (is_real_interrupt(up->port.irq)) { | 1733 | if (up->port.irq) { |
| 1754 | ier = serial_in(up, UART_IER); | 1734 | ier = serial_in(up, UART_IER); |
| 1755 | serial_out(up, UART_IER, 0); | 1735 | serial_out(up, UART_IER, 0); |
| 1756 | } | 1736 | } |
| @@ -1775,7 +1755,7 @@ static void serial8250_backup_timeout(unsigned long data) | |||
| 1775 | if (!(iir & UART_IIR_NO_INT)) | 1755 | if (!(iir & UART_IIR_NO_INT)) |
| 1776 | serial8250_tx_chars(up); | 1756 | serial8250_tx_chars(up); |
| 1777 | 1757 | ||
| 1778 | if (is_real_interrupt(up->port.irq)) | 1758 | if (up->port.irq) |
| 1779 | serial_out(up, UART_IER, ier); | 1759 | serial_out(up, UART_IER, ier); |
| 1780 | 1760 | ||
| 1781 | spin_unlock_irqrestore(&up->port.lock, flags); | 1761 | spin_unlock_irqrestore(&up->port.lock, flags); |
| @@ -1792,10 +1772,10 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) | |||
| 1792 | unsigned long flags; | 1772 | unsigned long flags; |
| 1793 | unsigned int lsr; | 1773 | unsigned int lsr; |
| 1794 | 1774 | ||
| 1795 | spin_lock_irqsave(&up->port.lock, flags); | 1775 | spin_lock_irqsave(&port->lock, flags); |
| 1796 | lsr = serial_in(up, UART_LSR); | 1776 | lsr = serial_port_in(port, UART_LSR); |
| 1797 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; | 1777 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; |
| 1798 | spin_unlock_irqrestore(&up->port.lock, flags); | 1778 | spin_unlock_irqrestore(&port->lock, flags); |
| 1799 | 1779 | ||
| 1800 | return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0; | 1780 | return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0; |
| 1801 | } | 1781 | } |
| @@ -1840,7 +1820,7 @@ static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
| 1840 | 1820 | ||
| 1841 | mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr; | 1821 | mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr; |
| 1842 | 1822 | ||
| 1843 | serial_out(up, UART_MCR, mcr); | 1823 | serial_port_out(port, UART_MCR, mcr); |
| 1844 | } | 1824 | } |
| 1845 | 1825 | ||
| 1846 | static void serial8250_break_ctl(struct uart_port *port, int break_state) | 1826 | static void serial8250_break_ctl(struct uart_port *port, int break_state) |
| @@ -1849,13 +1829,13 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state) | |||
| 1849 | container_of(port, struct uart_8250_port, port); | 1829 | container_of(port, struct uart_8250_port, port); |
| 1850 | unsigned long flags; | 1830 | unsigned long flags; |
| 1851 | 1831 | ||
| 1852 | spin_lock_irqsave(&up->port.lock, flags); | 1832 | spin_lock_irqsave(&port->lock, flags); |
| 1853 | if (break_state == -1) | 1833 | if (break_state == -1) |
| 1854 | up->lcr |= UART_LCR_SBC; | 1834 | up->lcr |= UART_LCR_SBC; |
| 1855 | else | 1835 | else |
| 1856 | up->lcr &= ~UART_LCR_SBC; | 1836 | up->lcr &= ~UART_LCR_SBC; |
| 1857 | serial_out(up, UART_LCR, up->lcr); | 1837 | serial_port_out(port, UART_LCR, up->lcr); |
| 1858 | spin_unlock_irqrestore(&up->port.lock, flags); | 1838 | spin_unlock_irqrestore(&port->lock, flags); |
| 1859 | } | 1839 | } |
| 1860 | 1840 | ||
| 1861 | /* | 1841 | /* |
| @@ -1900,14 +1880,12 @@ static void wait_for_xmitr(struct uart_8250_port *up, int bits) | |||
| 1900 | 1880 | ||
| 1901 | static int serial8250_get_poll_char(struct uart_port *port) | 1881 | static int serial8250_get_poll_char(struct uart_port *port) |
| 1902 | { | 1882 | { |
| 1903 | struct uart_8250_port *up = | 1883 | unsigned char lsr = serial_port_in(port, UART_LSR); |
| 1904 | container_of(port, struct uart_8250_port, port); | ||
| 1905 | unsigned char lsr = serial_inp(up, UART_LSR); | ||
| 1906 | 1884 | ||
| 1907 | if (!(lsr & UART_LSR_DR)) | 1885 | if (!(lsr & UART_LSR_DR)) |
| 1908 | return NO_POLL_CHAR; | 1886 | return NO_POLL_CHAR; |
| 1909 | 1887 | ||
| 1910 | return serial_inp(up, UART_RX); | 1888 | return serial_port_in(port, UART_RX); |
| 1911 | } | 1889 | } |
| 1912 | 1890 | ||
| 1913 | 1891 | ||
| @@ -1921,21 +1899,21 @@ static void serial8250_put_poll_char(struct uart_port *port, | |||
| 1921 | /* | 1899 | /* |
| 1922 | * First save the IER then disable the interrupts | 1900 | * First save the IER then disable the interrupts |
| 1923 | */ | 1901 | */ |
| 1924 | ier = serial_in(up, UART_IER); | 1902 | ier = serial_port_in(port, UART_IER); |
| 1925 | if (up->capabilities & UART_CAP_UUE) | 1903 | if (up->capabilities & UART_CAP_UUE) |
| 1926 | serial_out(up, UART_IER, UART_IER_UUE); | 1904 | serial_port_out(port, UART_IER, UART_IER_UUE); |
| 1927 | else | 1905 | else |
| 1928 | serial_out(up, UART_IER, 0); | 1906 | serial_port_out(port, UART_IER, 0); |
| 1929 | 1907 | ||
| 1930 | wait_for_xmitr(up, BOTH_EMPTY); | 1908 | wait_for_xmitr(up, BOTH_EMPTY); |
| 1931 | /* | 1909 | /* |
| 1932 | * Send the character out. | 1910 | * Send the character out. |
| 1933 | * If a LF, also do CR... | 1911 | * If a LF, also do CR... |
| 1934 | */ | 1912 | */ |
| 1935 | serial_out(up, UART_TX, c); | 1913 | serial_port_out(port, UART_TX, c); |
| 1936 | if (c == 10) { | 1914 | if (c == 10) { |
| 1937 | wait_for_xmitr(up, BOTH_EMPTY); | 1915 | wait_for_xmitr(up, BOTH_EMPTY); |
| 1938 | serial_out(up, UART_TX, 13); | 1916 | serial_port_out(port, UART_TX, 13); |
| 1939 | } | 1917 | } |
| 1940 | 1918 | ||
| 1941 | /* | 1919 | /* |
| @@ -1943,7 +1921,7 @@ static void serial8250_put_poll_char(struct uart_port *port, | |||
| 1943 | * and restore the IER | 1921 | * and restore the IER |
| 1944 | */ | 1922 | */ |
| 1945 | wait_for_xmitr(up, BOTH_EMPTY); | 1923 | wait_for_xmitr(up, BOTH_EMPTY); |
| 1946 | serial_out(up, UART_IER, ier); | 1924 | serial_port_out(port, UART_IER, ier); |
| 1947 | } | 1925 | } |
| 1948 | 1926 | ||
| 1949 | #endif /* CONFIG_CONSOLE_POLL */ | 1927 | #endif /* CONFIG_CONSOLE_POLL */ |
| @@ -1956,25 +1934,25 @@ static int serial8250_startup(struct uart_port *port) | |||
| 1956 | unsigned char lsr, iir; | 1934 | unsigned char lsr, iir; |
| 1957 | int retval; | 1935 | int retval; |
| 1958 | 1936 | ||
| 1959 | up->port.fifosize = uart_config[up->port.type].fifo_size; | 1937 | port->fifosize = uart_config[up->port.type].fifo_size; |
| 1960 | up->tx_loadsz = uart_config[up->port.type].tx_loadsz; | 1938 | up->tx_loadsz = uart_config[up->port.type].tx_loadsz; |
| 1961 | up->capabilities = uart_config[up->port.type].flags; | 1939 | up->capabilities = uart_config[up->port.type].flags; |
| 1962 | up->mcr = 0; | 1940 | up->mcr = 0; |
| 1963 | 1941 | ||
| 1964 | if (up->port.iotype != up->cur_iotype) | 1942 | if (port->iotype != up->cur_iotype) |
| 1965 | set_io_from_upio(port); | 1943 | set_io_from_upio(port); |
| 1966 | 1944 | ||
| 1967 | if (up->port.type == PORT_16C950) { | 1945 | if (port->type == PORT_16C950) { |
| 1968 | /* Wake up and initialize UART */ | 1946 | /* Wake up and initialize UART */ |
| 1969 | up->acr = 0; | 1947 | up->acr = 0; |
| 1970 | serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); | 1948 | serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); |
| 1971 | serial_outp(up, UART_EFR, UART_EFR_ECB); | 1949 | serial_port_out(port, UART_EFR, UART_EFR_ECB); |
| 1972 | serial_outp(up, UART_IER, 0); | 1950 | serial_port_out(port, UART_IER, 0); |
| 1973 | serial_outp(up, UART_LCR, 0); | 1951 | serial_port_out(port, UART_LCR, 0); |
| 1974 | serial_icr_write(up, UART_CSR, 0); /* Reset the UART */ | 1952 | serial_icr_write(up, UART_CSR, 0); /* Reset the UART */ |
| 1975 | serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); | 1953 | serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); |
| 1976 | serial_outp(up, UART_EFR, UART_EFR_ECB); | 1954 | serial_port_out(port, UART_EFR, UART_EFR_ECB); |
| 1977 | serial_outp(up, UART_LCR, 0); | 1955 | serial_port_out(port, UART_LCR, 0); |
| 1978 | } | 1956 | } |
| 1979 | 1957 | ||
| 1980 | #ifdef CONFIG_SERIAL_8250_RSA | 1958 | #ifdef CONFIG_SERIAL_8250_RSA |
| @@ -1994,41 +1972,43 @@ static int serial8250_startup(struct uart_port *port) | |||
| 1994 | /* | 1972 | /* |
| 1995 | * Clear the interrupt registers. | 1973 | * Clear the interrupt registers. |
| 1996 | */ | 1974 | */ |
| 1997 | (void) serial_inp(up, UART_LSR); | 1975 | serial_port_in(port, UART_LSR); |
| 1998 | (void) serial_inp(up, UART_RX); | 1976 | serial_port_in(port, UART_RX); |
| 1999 | (void) serial_inp(up, UART_IIR); | 1977 | serial_port_in(port, UART_IIR); |
| 2000 | (void) serial_inp(up, UART_MSR); | 1978 | serial_port_in(port, UART_MSR); |
| 2001 | 1979 | ||
| 2002 | /* | 1980 | /* |
| 2003 | * At this point, there's no way the LSR could still be 0xff; | 1981 | * At this point, there's no way the LSR could still be 0xff; |
| 2004 | * if it is, then bail out, because there's likely no UART | 1982 | * if it is, then bail out, because there's likely no UART |
| 2005 | * here. | 1983 | * here. |
| 2006 | */ | 1984 | */ |
| 2007 | if (!(up->port.flags & UPF_BUGGY_UART) && | 1985 | if (!(port->flags & UPF_BUGGY_UART) && |
| 2008 | (serial_inp(up, UART_LSR) == 0xff)) { | 1986 | (serial_port_in(port, UART_LSR) == 0xff)) { |
| 2009 | printk_ratelimited(KERN_INFO "ttyS%d: LSR safety check engaged!\n", | 1987 | printk_ratelimited(KERN_INFO "ttyS%d: LSR safety check engaged!\n", |
| 2010 | serial_index(&up->port)); | 1988 | serial_index(port)); |
| 2011 | return -ENODEV; | 1989 | return -ENODEV; |
| 2012 | } | 1990 | } |
| 2013 | 1991 | ||
| 2014 | /* | 1992 | /* |
| 2015 | * For a XR16C850, we need to set the trigger levels | 1993 | * For a XR16C850, we need to set the trigger levels |
| 2016 | */ | 1994 | */ |
| 2017 | if (up->port.type == PORT_16850) { | 1995 | if (port->type == PORT_16850) { |
| 2018 | unsigned char fctr; | 1996 | unsigned char fctr; |
| 2019 | 1997 | ||
| 2020 | serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); | 1998 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
| 2021 | 1999 | ||
| 2022 | fctr = serial_inp(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX); | 2000 | fctr = serial_in(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX); |
| 2023 | serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_RX); | 2001 | serial_port_out(port, UART_FCTR, |
| 2024 | serial_outp(up, UART_TRG, UART_TRG_96); | 2002 | fctr | UART_FCTR_TRGD | UART_FCTR_RX); |
| 2025 | serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_TX); | 2003 | serial_port_out(port, UART_TRG, UART_TRG_96); |
| 2026 | serial_outp(up, UART_TRG, UART_TRG_96); | 2004 | serial_port_out(port, UART_FCTR, |
| 2005 | fctr | UART_FCTR_TRGD | UART_FCTR_TX); | ||
| 2006 | serial_port_out(port, UART_TRG, UART_TRG_96); | ||
| 2027 | 2007 | ||
| 2028 | serial_outp(up, UART_LCR, 0); | 2008 | serial_port_out(port, UART_LCR, 0); |
| 2029 | } | 2009 | } |
| 2030 | 2010 | ||
| 2031 | if (is_real_interrupt(up->port.irq)) { | 2011 | if (port->irq) { |
| 2032 | unsigned char iir1; | 2012 | unsigned char iir1; |
| 2033 | /* | 2013 | /* |
| 2034 | * Test for UARTs that do not reassert THRE when the | 2014 | * Test for UARTs that do not reassert THRE when the |
| @@ -2038,23 +2018,23 @@ static int serial8250_startup(struct uart_port *port) | |||
| 2038 | * the interrupt is enabled. Delays are necessary to | 2018 | * the interrupt is enabled. Delays are necessary to |
| 2039 | * allow register changes to become visible. | 2019 | * allow register changes to become visible. |
| 2040 | */ | 2020 | */ |
| 2041 | spin_lock_irqsave(&up->port.lock, flags); | 2021 | spin_lock_irqsave(&port->lock, flags); |
| 2042 | if (up->port.irqflags & IRQF_SHARED) | 2022 | if (up->port.irqflags & IRQF_SHARED) |
| 2043 | disable_irq_nosync(up->port.irq); | 2023 | disable_irq_nosync(port->irq); |
| 2044 | 2024 | ||
| 2045 | wait_for_xmitr(up, UART_LSR_THRE); | 2025 | wait_for_xmitr(up, UART_LSR_THRE); |
| 2046 | serial_out_sync(up, UART_IER, UART_IER_THRI); | 2026 | serial_port_out_sync(port, UART_IER, UART_IER_THRI); |
| 2047 | udelay(1); /* allow THRE to set */ | 2027 | udelay(1); /* allow THRE to set */ |
| 2048 | iir1 = serial_in(up, UART_IIR); | 2028 | iir1 = serial_port_in(port, UART_IIR); |
| 2049 | serial_out(up, UART_IER, 0); | 2029 | serial_port_out(port, UART_IER, 0); |
| 2050 | serial_out_sync(up, UART_IER, UART_IER_THRI); | 2030 | serial_port_out_sync(port, UART_IER, UART_IER_THRI); |
| 2051 | udelay(1); /* allow a working UART time to re-assert THRE */ | 2031 | udelay(1); /* allow a working UART time to re-assert THRE */ |
| 2052 | iir = serial_in(up, UART_IIR); | 2032 | iir = serial_port_in(port, UART_IIR); |
| 2053 | serial_out(up, UART_IER, 0); | 2033 | serial_port_out(port, UART_IER, 0); |
| 2054 | 2034 | ||
| 2055 | if (up->port.irqflags & IRQF_SHARED) | 2035 | if (port->irqflags & IRQF_SHARED) |
| 2056 | enable_irq(up->port.irq); | 2036 | enable_irq(port->irq); |
| 2057 | spin_unlock_irqrestore(&up->port.lock, flags); | 2037 | spin_unlock_irqrestore(&port->lock, flags); |
| 2058 | 2038 | ||
| 2059 | /* | 2039 | /* |
| 2060 | * If the interrupt is not reasserted, setup a timer to | 2040 | * If the interrupt is not reasserted, setup a timer to |
| @@ -2083,7 +2063,7 @@ static int serial8250_startup(struct uart_port *port) | |||
| 2083 | * hardware interrupt, we use a timer-based system. The original | 2063 | * hardware interrupt, we use a timer-based system. The original |
| 2084 | * driver used to do this with IRQ0. | 2064 | * driver used to do this with IRQ0. |
| 2085 | */ | 2065 | */ |
| 2086 | if (!is_real_interrupt(up->port.irq)) { | 2066 | if (!port->irq) { |
| 2087 | up->timer.data = (unsigned long)up; | 2067 | up->timer.data = (unsigned long)up; |
| 2088 | mod_timer(&up->timer, jiffies + uart_poll_timeout(port)); | 2068 | mod_timer(&up->timer, jiffies + uart_poll_timeout(port)); |
| 2089 | } else { | 2069 | } else { |
| @@ -2095,20 +2075,20 @@ static int serial8250_startup(struct uart_port *port) | |||
| 2095 | /* | 2075 | /* |
| 2096 | * Now, initialize the UART | 2076 | * Now, initialize the UART |
| 2097 | */ | 2077 | */ |
| 2098 | serial_outp(up, UART_LCR, UART_LCR_WLEN8); | 2078 | serial_port_out(port, UART_LCR, UART_LCR_WLEN8); |
| 2099 | 2079 | ||
| 2100 | spin_lock_irqsave(&up->port.lock, flags); | 2080 | spin_lock_irqsave(&port->lock, flags); |
| 2101 | if (up->port.flags & UPF_FOURPORT) { | 2081 | if (up->port.flags & UPF_FOURPORT) { |
| 2102 | if (!is_real_interrupt(up->port.irq)) | 2082 | if (!up->port.irq) |
| 2103 | up->port.mctrl |= TIOCM_OUT1; | 2083 | up->port.mctrl |= TIOCM_OUT1; |
| 2104 | } else | 2084 | } else |
| 2105 | /* | 2085 | /* |
| 2106 | * Most PC uarts need OUT2 raised to enable interrupts. | 2086 | * Most PC uarts need OUT2 raised to enable interrupts. |
| 2107 | */ | 2087 | */ |
| 2108 | if (is_real_interrupt(up->port.irq)) | 2088 | if (port->irq) |
| 2109 | up->port.mctrl |= TIOCM_OUT2; | 2089 | up->port.mctrl |= TIOCM_OUT2; |
| 2110 | 2090 | ||
| 2111 | serial8250_set_mctrl(&up->port, up->port.mctrl); | 2091 | serial8250_set_mctrl(port, port->mctrl); |
| 2112 | 2092 | ||
| 2113 | /* Serial over Lan (SoL) hack: | 2093 | /* Serial over Lan (SoL) hack: |
| 2114 | Intel 8257x Gigabit ethernet chips have a | 2094 | Intel 8257x Gigabit ethernet chips have a |
| @@ -2128,10 +2108,10 @@ static int serial8250_startup(struct uart_port *port) | |||
| 2128 | * Do a quick test to see if we receive an | 2108 | * Do a quick test to see if we receive an |
| 2129 | * interrupt when we enable the TX irq. | 2109 | * interrupt when we enable the TX irq. |
| 2130 | */ | 2110 | */ |
| 2131 | serial_outp(up, UART_IER, UART_IER_THRI); | 2111 | serial_port_out(port, UART_IER, UART_IER_THRI); |
| 2132 | lsr = serial_in(up, UART_LSR); | 2112 | lsr = serial_port_in(port, UART_LSR); |
| 2133 | iir = serial_in(up, UART_IIR); | 2113 | iir = serial_port_in(port, UART_IIR); |
| 2134 | serial_outp(up, UART_IER, 0); | 2114 | serial_port_out(port, UART_IER, 0); |
| 2135 | 2115 | ||
| 2136 | if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) { | 2116 | if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) { |
| 2137 | if (!(up->bugs & UART_BUG_TXEN)) { | 2117 | if (!(up->bugs & UART_BUG_TXEN)) { |
| @@ -2144,17 +2124,17 @@ static int serial8250_startup(struct uart_port *port) | |||
| 2144 | } | 2124 | } |
| 2145 | 2125 | ||
| 2146 | dont_test_tx_en: | 2126 | dont_test_tx_en: |
| 2147 | spin_unlock_irqrestore(&up->port.lock, flags); | 2127 | spin_unlock_irqrestore(&port->lock, flags); |
| 2148 | 2128 | ||
| 2149 | /* | 2129 | /* |
| 2150 | * Clear the interrupt registers again for luck, and clear the | 2130 | * Clear the interrupt registers again for luck, and clear the |
| 2151 | * saved flags to avoid getting false values from polling | 2131 | * saved flags to avoid getting false values from polling |
| 2152 | * routines or the previous session. | 2132 | * routines or the previous session. |
| 2153 | */ | 2133 | */ |
| 2154 | serial_inp(up, UART_LSR); | 2134 | serial_port_in(port, UART_LSR); |
| 2155 | serial_inp(up, UART_RX); | 2135 | serial_port_in(port, UART_RX); |
| 2156 | serial_inp(up, UART_IIR); | 2136 | serial_port_in(port, UART_IIR); |
| 2157 | serial_inp(up, UART_MSR); | 2137 | serial_port_in(port, UART_MSR); |
| 2158 | up->lsr_saved_flags = 0; | 2138 | up->lsr_saved_flags = 0; |
| 2159 | up->msr_saved_flags = 0; | 2139 | up->msr_saved_flags = 0; |
| 2160 | 2140 | ||
| @@ -2164,16 +2144,16 @@ dont_test_tx_en: | |||
| 2164 | * anyway, so we don't enable them here. | 2144 | * anyway, so we don't enable them here. |
| 2165 | */ | 2145 | */ |
| 2166 | up->ier = UART_IER_RLSI | UART_IER_RDI; | 2146 | up->ier = UART_IER_RLSI | UART_IER_RDI; |
| 2167 | serial_outp(up, UART_IER, up->ier); | 2147 | serial_port_out(port, UART_IER, up->ier); |
| 2168 | 2148 | ||
| 2169 | if (up->port.flags & UPF_FOURPORT) { | 2149 | if (port->flags & UPF_FOURPORT) { |
| 2170 | unsigned int icp; | 2150 | unsigned int icp; |
| 2171 | /* | 2151 | /* |
| 2172 | * Enable interrupts on the AST Fourport board | 2152 | * Enable interrupts on the AST Fourport board |
| 2173 | */ | 2153 | */ |
| 2174 | icp = (up->port.iobase & 0xfe0) | 0x01f; | 2154 | icp = (port->iobase & 0xfe0) | 0x01f; |
| 2175 | outb_p(0x80, icp); | 2155 | outb_p(0x80, icp); |
| 2176 | (void) inb_p(icp); | 2156 | inb_p(icp); |
| 2177 | } | 2157 | } |
| 2178 | 2158 | ||
| 2179 | return 0; | 2159 | return 0; |
| @@ -2189,23 +2169,24 @@ static void serial8250_shutdown(struct uart_port *port) | |||
| 2189 | * Disable interrupts from this port | 2169 | * Disable interrupts from this port |
| 2190 | */ | 2170 | */ |
| 2191 | up->ier = 0; | 2171 | up->ier = 0; |
| 2192 | serial_outp(up, UART_IER, 0); | 2172 | serial_port_out(port, UART_IER, 0); |
| 2193 | 2173 | ||
| 2194 | spin_lock_irqsave(&up->port.lock, flags); | 2174 | spin_lock_irqsave(&port->lock, flags); |
| 2195 | if (up->port.flags & UPF_FOURPORT) { | 2175 | if (port->flags & UPF_FOURPORT) { |
| 2196 | /* reset interrupts on the AST Fourport board */ | 2176 | /* reset interrupts on the AST Fourport board */ |
| 2197 | inb((up->port.iobase & 0xfe0) | 0x1f); | 2177 | inb((port->iobase & 0xfe0) | 0x1f); |
| 2198 | up->port.mctrl |= TIOCM_OUT1; | 2178 | port->mctrl |= TIOCM_OUT1; |
| 2199 | } else | 2179 | } else |
| 2200 | up->port.mctrl &= ~TIOCM_OUT2; | 2180 | port->mctrl &= ~TIOCM_OUT2; |
| 2201 | 2181 | ||
| 2202 | serial8250_set_mctrl(&up->port, up->port.mctrl); | 2182 | serial8250_set_mctrl(port, port->mctrl); |
| 2203 | spin_unlock_irqrestore(&up->port.lock, flags); | 2183 | spin_unlock_irqrestore(&port->lock, flags); |
| 2204 | 2184 | ||
| 2205 | /* | 2185 | /* |
| 2206 | * Disable break condition and FIFOs | 2186 | * Disable break condition and FIFOs |
| 2207 | */ | 2187 | */ |
| 2208 | serial_out(up, UART_LCR, serial_inp(up, UART_LCR) & ~UART_LCR_SBC); | 2188 | serial_port_out(port, UART_LCR, |
| 2189 | serial_port_in(port, UART_LCR) & ~UART_LCR_SBC); | ||
| 2209 | serial8250_clear_fifos(up); | 2190 | serial8250_clear_fifos(up); |
| 2210 | 2191 | ||
| 2211 | #ifdef CONFIG_SERIAL_8250_RSA | 2192 | #ifdef CONFIG_SERIAL_8250_RSA |
| @@ -2219,11 +2200,11 @@ static void serial8250_shutdown(struct uart_port *port) | |||
| 2219 | * Read data port to reset things, and then unlink from | 2200 | * Read data port to reset things, and then unlink from |
| 2220 | * the IRQ chain. | 2201 | * the IRQ chain. |
| 2221 | */ | 2202 | */ |
| 2222 | (void) serial_in(up, UART_RX); | 2203 | serial_port_in(port, UART_RX); |
| 2223 | 2204 | ||
| 2224 | del_timer_sync(&up->timer); | 2205 | del_timer_sync(&up->timer); |
| 2225 | up->timer.function = serial8250_timeout; | 2206 | up->timer.function = serial8250_timeout; |
| 2226 | if (is_real_interrupt(up->port.irq)) | 2207 | if (port->irq) |
| 2227 | serial_unlink_irq_chain(up); | 2208 | serial_unlink_irq_chain(up); |
| 2228 | } | 2209 | } |
| 2229 | 2210 | ||
| @@ -2298,11 +2279,11 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 2298 | if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0) | 2279 | if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0) |
| 2299 | quot++; | 2280 | quot++; |
| 2300 | 2281 | ||
| 2301 | if (up->capabilities & UART_CAP_FIFO && up->port.fifosize > 1) { | 2282 | if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) { |
| 2302 | if (baud < 2400) | 2283 | if (baud < 2400) |
| 2303 | fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1; | 2284 | fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1; |
| 2304 | else | 2285 | else |
| 2305 | fcr = uart_config[up->port.type].fcr; | 2286 | fcr = uart_config[port->type].fcr; |
| 2306 | } | 2287 | } |
| 2307 | 2288 | ||
| 2308 | /* | 2289 | /* |
| @@ -2313,7 +2294,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 2313 | * have sufficient FIFO entries for the latency of the remote | 2294 | * have sufficient FIFO entries for the latency of the remote |
| 2314 | * UART to respond. IOW, at least 32 bytes of FIFO. | 2295 | * UART to respond. IOW, at least 32 bytes of FIFO. |
| 2315 | */ | 2296 | */ |
| 2316 | if (up->capabilities & UART_CAP_AFE && up->port.fifosize >= 32) { | 2297 | if (up->capabilities & UART_CAP_AFE && port->fifosize >= 32) { |
| 2317 | up->mcr &= ~UART_MCR_AFE; | 2298 | up->mcr &= ~UART_MCR_AFE; |
| 2318 | if (termios->c_cflag & CRTSCTS) | 2299 | if (termios->c_cflag & CRTSCTS) |
| 2319 | up->mcr |= UART_MCR_AFE; | 2300 | up->mcr |= UART_MCR_AFE; |
| @@ -2323,40 +2304,40 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 2323 | * Ok, we're now changing the port state. Do it with | 2304 | * Ok, we're now changing the port state. Do it with |
| 2324 | * interrupts disabled. | 2305 | * interrupts disabled. |
| 2325 | */ | 2306 | */ |
| 2326 | spin_lock_irqsave(&up->port.lock, flags); | 2307 | spin_lock_irqsave(&port->lock, flags); |
| 2327 | 2308 | ||
| 2328 | /* | 2309 | /* |
| 2329 | * Update the per-port timeout. | 2310 | * Update the per-port timeout. |
| 2330 | */ | 2311 | */ |
| 2331 | uart_update_timeout(port, termios->c_cflag, baud); | 2312 | uart_update_timeout(port, termios->c_cflag, baud); |
| 2332 | 2313 | ||
| 2333 | up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; | 2314 | port->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; |
| 2334 | if (termios->c_iflag & INPCK) | 2315 | if (termios->c_iflag & INPCK) |
| 2335 | up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE; | 2316 | port->read_status_mask |= UART_LSR_FE | UART_LSR_PE; |
| 2336 | if (termios->c_iflag & (BRKINT | PARMRK)) | 2317 | if (termios->c_iflag & (BRKINT | PARMRK)) |
| 2337 | up->port.read_status_mask |= UART_LSR_BI; | 2318 | port->read_status_mask |= UART_LSR_BI; |
| 2338 | 2319 | ||
| 2339 | /* | 2320 | /* |
| 2340 | * Characteres to ignore | 2321 | * Characteres to ignore |
| 2341 | */ | 2322 | */ |
| 2342 | up->port.ignore_status_mask = 0; | 2323 | port->ignore_status_mask = 0; |
| 2343 | if (termios->c_iflag & IGNPAR) | 2324 | if (termios->c_iflag & IGNPAR) |
| 2344 | up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; | 2325 | port->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; |
| 2345 | if (termios->c_iflag & IGNBRK) { | 2326 | if (termios->c_iflag & IGNBRK) { |
| 2346 | up->port.ignore_status_mask |= UART_LSR_BI; | 2327 | port->ignore_status_mask |= UART_LSR_BI; |
| 2347 | /* | 2328 | /* |
| 2348 | * If we're ignoring parity and break indicators, | 2329 | * If we're ignoring parity and break indicators, |
| 2349 | * ignore overruns too (for real raw support). | 2330 | * ignore overruns too (for real raw support). |
| 2350 | */ | 2331 | */ |
| 2351 | if (termios->c_iflag & IGNPAR) | 2332 | if (termios->c_iflag & IGNPAR) |
| 2352 | up->port.ignore_status_mask |= UART_LSR_OE; | 2333 | port->ignore_status_mask |= UART_LSR_OE; |
| 2353 | } | 2334 | } |
| 2354 | 2335 | ||
| 2355 | /* | 2336 | /* |
| 2356 | * ignore all characters if CREAD is not set | 2337 | * ignore all characters if CREAD is not set |
| 2357 | */ | 2338 | */ |
| 2358 | if ((termios->c_cflag & CREAD) == 0) | 2339 | if ((termios->c_cflag & CREAD) == 0) |
| 2359 | up->port.ignore_status_mask |= UART_LSR_DR; | 2340 | port->ignore_status_mask |= UART_LSR_DR; |
| 2360 | 2341 | ||
| 2361 | /* | 2342 | /* |
| 2362 | * CTS flow control flag and modem status interrupts | 2343 | * CTS flow control flag and modem status interrupts |
| @@ -2370,7 +2351,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 2370 | if (up->capabilities & UART_CAP_RTOIE) | 2351 | if (up->capabilities & UART_CAP_RTOIE) |
| 2371 | up->ier |= UART_IER_RTOIE; | 2352 | up->ier |= UART_IER_RTOIE; |
| 2372 | 2353 | ||
| 2373 | serial_out(up, UART_IER, up->ier); | 2354 | serial_port_out(port, UART_IER, up->ier); |
| 2374 | 2355 | ||
| 2375 | if (up->capabilities & UART_CAP_EFR) { | 2356 | if (up->capabilities & UART_CAP_EFR) { |
| 2376 | unsigned char efr = 0; | 2357 | unsigned char efr = 0; |
| @@ -2382,11 +2363,11 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 2382 | if (termios->c_cflag & CRTSCTS) | 2363 | if (termios->c_cflag & CRTSCTS) |
| 2383 | efr |= UART_EFR_CTS; | 2364 | efr |= UART_EFR_CTS; |
| 2384 | 2365 | ||
| 2385 | serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); | 2366 | serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B); |
| 2386 | if (up->port.flags & UPF_EXAR_EFR) | 2367 | if (port->flags & UPF_EXAR_EFR) |
| 2387 | serial_outp(up, UART_XR_EFR, efr); | 2368 | serial_port_out(port, UART_XR_EFR, efr); |
| 2388 | else | 2369 | else |
| 2389 | serial_outp(up, UART_EFR, efr); | 2370 | serial_port_out(port, UART_EFR, efr); |
| 2390 | } | 2371 | } |
| 2391 | 2372 | ||
| 2392 | #ifdef CONFIG_ARCH_OMAP | 2373 | #ifdef CONFIG_ARCH_OMAP |
| @@ -2394,18 +2375,20 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 2394 | if (cpu_is_omap1510() && is_omap_port(up)) { | 2375 | if (cpu_is_omap1510() && is_omap_port(up)) { |
| 2395 | if (baud == 115200) { | 2376 | if (baud == 115200) { |
| 2396 | quot = 1; | 2377 | quot = 1; |
| 2397 | serial_out(up, UART_OMAP_OSC_12M_SEL, 1); | 2378 | serial_port_out(port, UART_OMAP_OSC_12M_SEL, 1); |
| 2398 | } else | 2379 | } else |
| 2399 | serial_out(up, UART_OMAP_OSC_12M_SEL, 0); | 2380 | serial_port_out(port, UART_OMAP_OSC_12M_SEL, 0); |
| 2400 | } | 2381 | } |
| 2401 | #endif | 2382 | #endif |
| 2402 | 2383 | ||
| 2403 | if (up->capabilities & UART_NATSEMI) { | 2384 | /* |
| 2404 | /* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */ | 2385 | * For NatSemi, switch to bank 2 not bank 1, to avoid resetting EXCR2, |
| 2405 | serial_outp(up, UART_LCR, 0xe0); | 2386 | * otherwise just set DLAB |
| 2406 | } else { | 2387 | */ |
| 2407 | serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ | 2388 | if (up->capabilities & UART_NATSEMI) |
| 2408 | } | 2389 | serial_port_out(port, UART_LCR, 0xe0); |
| 2390 | else | ||
| 2391 | serial_port_out(port, UART_LCR, cval | UART_LCR_DLAB); | ||
| 2409 | 2392 | ||
| 2410 | serial_dl_write(up, quot); | 2393 | serial_dl_write(up, quot); |
| 2411 | 2394 | ||
| @@ -2413,20 +2396,19 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 2413 | * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR | 2396 | * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR |
| 2414 | * is written without DLAB set, this mode will be disabled. | 2397 | * is written without DLAB set, this mode will be disabled. |
| 2415 | */ | 2398 | */ |
| 2416 | if (up->port.type == PORT_16750) | 2399 | if (port->type == PORT_16750) |
| 2417 | serial_outp(up, UART_FCR, fcr); | 2400 | serial_port_out(port, UART_FCR, fcr); |
| 2418 | 2401 | ||
| 2419 | serial_outp(up, UART_LCR, cval); /* reset DLAB */ | 2402 | serial_port_out(port, UART_LCR, cval); /* reset DLAB */ |
| 2420 | up->lcr = cval; /* Save LCR */ | 2403 | up->lcr = cval; /* Save LCR */ |
| 2421 | if (up->port.type != PORT_16750) { | 2404 | if (port->type != PORT_16750) { |
| 2422 | if (fcr & UART_FCR_ENABLE_FIFO) { | 2405 | /* emulated UARTs (Lucent Venus 167x) need two steps */ |
| 2423 | /* emulated UARTs (Lucent Venus 167x) need two steps */ | 2406 | if (fcr & UART_FCR_ENABLE_FIFO) |
| 2424 | serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); | 2407 | serial_port_out(port, UART_FCR, UART_FCR_ENABLE_FIFO); |
| 2425 | } | 2408 | serial_port_out(port, UART_FCR, fcr); /* set fcr */ |
| 2426 | serial_outp(up, UART_FCR, fcr); /* set fcr */ | 2409 | } |
| 2427 | } | 2410 | serial8250_set_mctrl(port, port->mctrl); |
| 2428 | serial8250_set_mctrl(&up->port, up->port.mctrl); | 2411 | spin_unlock_irqrestore(&port->lock, flags); |
| 2429 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
| 2430 | /* Don't rewrite B0 */ | 2412 | /* Don't rewrite B0 */ |
| 2431 | if (tty_termios_baud_rate(termios)) | 2413 | if (tty_termios_baud_rate(termios)) |
| 2432 | tty_termios_encode_baud_rate(termios, baud, baud); | 2414 | tty_termios_encode_baud_rate(termios, baud, baud); |
| @@ -2491,26 +2473,26 @@ static unsigned int serial8250_port_size(struct uart_8250_port *pt) | |||
| 2491 | static int serial8250_request_std_resource(struct uart_8250_port *up) | 2473 | static int serial8250_request_std_resource(struct uart_8250_port *up) |
| 2492 | { | 2474 | { |
| 2493 | unsigned int size = serial8250_port_size(up); | 2475 | unsigned int size = serial8250_port_size(up); |
| 2476 | struct uart_port *port = &up->port; | ||
| 2494 | int ret = 0; | 2477 | int ret = 0; |
| 2495 | 2478 | ||
| 2496 | switch (up->port.iotype) { | 2479 | switch (port->iotype) { |
| 2497 | case UPIO_AU: | 2480 | case UPIO_AU: |
| 2498 | case UPIO_TSI: | 2481 | case UPIO_TSI: |
| 2499 | case UPIO_MEM32: | 2482 | case UPIO_MEM32: |
| 2500 | case UPIO_MEM: | 2483 | case UPIO_MEM: |
| 2501 | if (!up->port.mapbase) | 2484 | if (!port->mapbase) |
| 2502 | break; | 2485 | break; |
| 2503 | 2486 | ||
| 2504 | if (!request_mem_region(up->port.mapbase, size, "serial")) { | 2487 | if (!request_mem_region(port->mapbase, size, "serial")) { |
| 2505 | ret = -EBUSY; | 2488 | ret = -EBUSY; |
| 2506 | break; | 2489 | break; |
| 2507 | } | 2490 | } |
| 2508 | 2491 | ||
| 2509 | if (up->port.flags & UPF_IOREMAP) { | 2492 | if (port->flags & UPF_IOREMAP) { |
| 2510 | up->port.membase = ioremap_nocache(up->port.mapbase, | 2493 | port->membase = ioremap_nocache(port->mapbase, size); |
| 2511 | size); | 2494 | if (!port->membase) { |
| 2512 | if (!up->port.membase) { | 2495 | release_mem_region(port->mapbase, size); |
| 2513 | release_mem_region(up->port.mapbase, size); | ||
| 2514 | ret = -ENOMEM; | 2496 | ret = -ENOMEM; |
| 2515 | } | 2497 | } |
| 2516 | } | 2498 | } |
| @@ -2518,7 +2500,7 @@ static int serial8250_request_std_resource(struct uart_8250_port *up) | |||
| 2518 | 2500 | ||
| 2519 | case UPIO_HUB6: | 2501 | case UPIO_HUB6: |
| 2520 | case UPIO_PORT: | 2502 | case UPIO_PORT: |
| 2521 | if (!request_region(up->port.iobase, size, "serial")) | 2503 | if (!request_region(port->iobase, size, "serial")) |
| 2522 | ret = -EBUSY; | 2504 | ret = -EBUSY; |
| 2523 | break; | 2505 | break; |
| 2524 | } | 2506 | } |
| @@ -2528,26 +2510,27 @@ static int serial8250_request_std_resource(struct uart_8250_port *up) | |||
| 2528 | static void serial8250_release_std_resource(struct uart_8250_port *up) | 2510 | static void serial8250_release_std_resource(struct uart_8250_port *up) |
| 2529 | { | 2511 | { |
| 2530 | unsigned int size = serial8250_port_size(up); | 2512 | unsigned int size = serial8250_port_size(up); |
| 2513 | struct uart_port *port = &up->port; | ||
| 2531 | 2514 | ||
| 2532 | switch (up->port.iotype) { | 2515 | switch (port->iotype) { |
| 2533 | case UPIO_AU: | 2516 | case UPIO_AU: |
| 2534 | case UPIO_TSI: | 2517 | case UPIO_TSI: |
| 2535 | case UPIO_MEM32: | 2518 | case UPIO_MEM32: |
| 2536 | case UPIO_MEM: | 2519 | case UPIO_MEM: |
| 2537 | if (!up->port.mapbase) | 2520 | if (!port->mapbase) |
| 2538 | break; | 2521 | break; |
| 2539 | 2522 | ||
| 2540 | if (up->port.flags & UPF_IOREMAP) { | 2523 | if (port->flags & UPF_IOREMAP) { |
| 2541 | iounmap(up->port.membase); | 2524 | iounmap(port->membase); |
| 2542 | up->port.membase = NULL; | 2525 | port->membase = NULL; |
| 2543 | } | 2526 | } |
| 2544 | 2527 | ||
| 2545 | release_mem_region(up->port.mapbase, size); | 2528 | release_mem_region(port->mapbase, size); |
| 2546 | break; | 2529 | break; |
| 2547 | 2530 | ||
| 2548 | case UPIO_HUB6: | 2531 | case UPIO_HUB6: |
| 2549 | case UPIO_PORT: | 2532 | case UPIO_PORT: |
| 2550 | release_region(up->port.iobase, size); | 2533 | release_region(port->iobase, size); |
| 2551 | break; | 2534 | break; |
| 2552 | } | 2535 | } |
| 2553 | } | 2536 | } |
| @@ -2556,12 +2539,13 @@ static int serial8250_request_rsa_resource(struct uart_8250_port *up) | |||
| 2556 | { | 2539 | { |
| 2557 | unsigned long start = UART_RSA_BASE << up->port.regshift; | 2540 | unsigned long start = UART_RSA_BASE << up->port.regshift; |
| 2558 | unsigned int size = 8 << up->port.regshift; | 2541 | unsigned int size = 8 << up->port.regshift; |
| 2542 | struct uart_port *port = &up->port; | ||
| 2559 | int ret = -EINVAL; | 2543 | int ret = -EINVAL; |
| 2560 | 2544 | ||
| 2561 | switch (up->port.iotype) { | 2545 | switch (port->iotype) { |
| 2562 | case UPIO_HUB6: | 2546 | case UPIO_HUB6: |
| 2563 | case UPIO_PORT: | 2547 | case UPIO_PORT: |
| 2564 | start += up->port.iobase; | 2548 | start += port->iobase; |
| 2565 | if (request_region(start, size, "serial-rsa")) | 2549 | if (request_region(start, size, "serial-rsa")) |
| 2566 | ret = 0; | 2550 | ret = 0; |
| 2567 | else | 2551 | else |
| @@ -2576,11 +2560,12 @@ static void serial8250_release_rsa_resource(struct uart_8250_port *up) | |||
| 2576 | { | 2560 | { |
| 2577 | unsigned long offset = UART_RSA_BASE << up->port.regshift; | 2561 | unsigned long offset = UART_RSA_BASE << up->port.regshift; |
| 2578 | unsigned int size = 8 << up->port.regshift; | 2562 | unsigned int size = 8 << up->port.regshift; |
| 2563 | struct uart_port *port = &up->port; | ||
| 2579 | 2564 | ||
| 2580 | switch (up->port.iotype) { | 2565 | switch (port->iotype) { |
| 2581 | case UPIO_HUB6: | 2566 | case UPIO_HUB6: |
| 2582 | case UPIO_PORT: | 2567 | case UPIO_PORT: |
| 2583 | release_region(up->port.iobase + offset, size); | 2568 | release_region(port->iobase + offset, size); |
| 2584 | break; | 2569 | break; |
| 2585 | } | 2570 | } |
| 2586 | } | 2571 | } |
| @@ -2591,7 +2576,7 @@ static void serial8250_release_port(struct uart_port *port) | |||
| 2591 | container_of(port, struct uart_8250_port, port); | 2576 | container_of(port, struct uart_8250_port, port); |
| 2592 | 2577 | ||
| 2593 | serial8250_release_std_resource(up); | 2578 | serial8250_release_std_resource(up); |
| 2594 | if (up->port.type == PORT_RSA) | 2579 | if (port->type == PORT_RSA) |
| 2595 | serial8250_release_rsa_resource(up); | 2580 | serial8250_release_rsa_resource(up); |
| 2596 | } | 2581 | } |
| 2597 | 2582 | ||
| @@ -2602,7 +2587,7 @@ static int serial8250_request_port(struct uart_port *port) | |||
| 2602 | int ret = 0; | 2587 | int ret = 0; |
| 2603 | 2588 | ||
| 2604 | ret = serial8250_request_std_resource(up); | 2589 | ret = serial8250_request_std_resource(up); |
| 2605 | if (ret == 0 && up->port.type == PORT_RSA) { | 2590 | if (ret == 0 && port->type == PORT_RSA) { |
| 2606 | ret = serial8250_request_rsa_resource(up); | 2591 | ret = serial8250_request_rsa_resource(up); |
| 2607 | if (ret < 0) | 2592 | if (ret < 0) |
| 2608 | serial8250_release_std_resource(up); | 2593 | serial8250_release_std_resource(up); |
| @@ -2630,22 +2615,22 @@ static void serial8250_config_port(struct uart_port *port, int flags) | |||
| 2630 | if (ret < 0) | 2615 | if (ret < 0) |
| 2631 | probeflags &= ~PROBE_RSA; | 2616 | probeflags &= ~PROBE_RSA; |
| 2632 | 2617 | ||
| 2633 | if (up->port.iotype != up->cur_iotype) | 2618 | if (port->iotype != up->cur_iotype) |
| 2634 | set_io_from_upio(port); | 2619 | set_io_from_upio(port); |
| 2635 | 2620 | ||
| 2636 | if (flags & UART_CONFIG_TYPE) | 2621 | if (flags & UART_CONFIG_TYPE) |
| 2637 | autoconfig(up, probeflags); | 2622 | autoconfig(up, probeflags); |
| 2638 | 2623 | ||
| 2639 | /* if access method is AU, it is a 16550 with a quirk */ | 2624 | /* if access method is AU, it is a 16550 with a quirk */ |
| 2640 | if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU) | 2625 | if (port->type == PORT_16550A && port->iotype == UPIO_AU) |
| 2641 | up->bugs |= UART_BUG_NOMSR; | 2626 | up->bugs |= UART_BUG_NOMSR; |
| 2642 | 2627 | ||
| 2643 | if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ) | 2628 | if (port->type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ) |
| 2644 | autoconfig_irq(up); | 2629 | autoconfig_irq(up); |
| 2645 | 2630 | ||
| 2646 | if (up->port.type != PORT_RSA && probeflags & PROBE_RSA) | 2631 | if (port->type != PORT_RSA && probeflags & PROBE_RSA) |
| 2647 | serial8250_release_rsa_resource(up); | 2632 | serial8250_release_rsa_resource(up); |
| 2648 | if (up->port.type == PORT_UNKNOWN) | 2633 | if (port->type == PORT_UNKNOWN) |
| 2649 | serial8250_release_std_resource(up); | 2634 | serial8250_release_std_resource(up); |
| 2650 | } | 2635 | } |
| 2651 | 2636 | ||
| @@ -2719,9 +2704,10 @@ static void __init serial8250_isa_init_ports(void) | |||
| 2719 | 2704 | ||
| 2720 | for (i = 0; i < nr_uarts; i++) { | 2705 | for (i = 0; i < nr_uarts; i++) { |
| 2721 | struct uart_8250_port *up = &serial8250_ports[i]; | 2706 | struct uart_8250_port *up = &serial8250_ports[i]; |
| 2707 | struct uart_port *port = &up->port; | ||
| 2722 | 2708 | ||
| 2723 | up->port.line = i; | 2709 | port->line = i; |
| 2724 | spin_lock_init(&up->port.lock); | 2710 | spin_lock_init(&port->lock); |
| 2725 | 2711 | ||
| 2726 | init_timer(&up->timer); | 2712 | init_timer(&up->timer); |
| 2727 | up->timer.function = serial8250_timeout; | 2713 | up->timer.function = serial8250_timeout; |
| @@ -2732,7 +2718,7 @@ static void __init serial8250_isa_init_ports(void) | |||
| 2732 | up->mcr_mask = ~ALPHA_KLUDGE_MCR; | 2718 | up->mcr_mask = ~ALPHA_KLUDGE_MCR; |
| 2733 | up->mcr_force = ALPHA_KLUDGE_MCR; | 2719 | up->mcr_force = ALPHA_KLUDGE_MCR; |
| 2734 | 2720 | ||
| 2735 | up->port.ops = &serial8250_pops; | 2721 | port->ops = &serial8250_pops; |
| 2736 | } | 2722 | } |
| 2737 | 2723 | ||
| 2738 | if (share_irqs) | 2724 | if (share_irqs) |
| @@ -2741,17 +2727,19 @@ static void __init serial8250_isa_init_ports(void) | |||
| 2741 | for (i = 0, up = serial8250_ports; | 2727 | for (i = 0, up = serial8250_ports; |
| 2742 | i < ARRAY_SIZE(old_serial_port) && i < nr_uarts; | 2728 | i < ARRAY_SIZE(old_serial_port) && i < nr_uarts; |
| 2743 | i++, up++) { | 2729 | i++, up++) { |
| 2744 | up->port.iobase = old_serial_port[i].port; | 2730 | struct uart_port *port = &up->port; |
| 2745 | up->port.irq = irq_canonicalize(old_serial_port[i].irq); | 2731 | |
| 2746 | up->port.irqflags = old_serial_port[i].irqflags; | 2732 | port->iobase = old_serial_port[i].port; |
| 2747 | up->port.uartclk = old_serial_port[i].baud_base * 16; | 2733 | port->irq = irq_canonicalize(old_serial_port[i].irq); |
| 2748 | up->port.flags = old_serial_port[i].flags; | 2734 | port->irqflags = old_serial_port[i].irqflags; |
| 2749 | up->port.hub6 = old_serial_port[i].hub6; | 2735 | port->uartclk = old_serial_port[i].baud_base * 16; |
| 2750 | up->port.membase = old_serial_port[i].iomem_base; | 2736 | port->flags = old_serial_port[i].flags; |
| 2751 | up->port.iotype = old_serial_port[i].io_type; | 2737 | port->hub6 = old_serial_port[i].hub6; |
| 2752 | up->port.regshift = old_serial_port[i].iomem_reg_shift; | 2738 | port->membase = old_serial_port[i].iomem_base; |
| 2753 | set_io_from_upio(&up->port); | 2739 | port->iotype = old_serial_port[i].io_type; |
| 2754 | up->port.irqflags |= irqflag; | 2740 | port->regshift = old_serial_port[i].iomem_reg_shift; |
| 2741 | set_io_from_upio(port); | ||
| 2742 | port->irqflags |= irqflag; | ||
| 2755 | if (serial8250_isa_config != NULL) | 2743 | if (serial8250_isa_config != NULL) |
| 2756 | serial8250_isa_config(i, &up->port, &up->capabilities); | 2744 | serial8250_isa_config(i, &up->port, &up->capabilities); |
| 2757 | 2745 | ||
| @@ -2799,7 +2787,7 @@ static void serial8250_console_putchar(struct uart_port *port, int ch) | |||
| 2799 | container_of(port, struct uart_8250_port, port); | 2787 | container_of(port, struct uart_8250_port, port); |
| 2800 | 2788 | ||
| 2801 | wait_for_xmitr(up, UART_LSR_THRE); | 2789 | wait_for_xmitr(up, UART_LSR_THRE); |
| 2802 | serial_out(up, UART_TX, ch); | 2790 | serial_port_out(port, UART_TX, ch); |
| 2803 | } | 2791 | } |
| 2804 | 2792 | ||
| 2805 | /* | 2793 | /* |
| @@ -2812,6 +2800,7 @@ static void | |||
| 2812 | serial8250_console_write(struct console *co, const char *s, unsigned int count) | 2800 | serial8250_console_write(struct console *co, const char *s, unsigned int count) |
| 2813 | { | 2801 | { |
| 2814 | struct uart_8250_port *up = &serial8250_ports[co->index]; | 2802 | struct uart_8250_port *up = &serial8250_ports[co->index]; |
| 2803 | struct uart_port *port = &up->port; | ||
| 2815 | unsigned long flags; | 2804 | unsigned long flags; |
| 2816 | unsigned int ier; | 2805 | unsigned int ier; |
| 2817 | int locked = 1; | 2806 | int locked = 1; |
| @@ -2819,32 +2808,32 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) | |||
| 2819 | touch_nmi_watchdog(); | 2808 | touch_nmi_watchdog(); |
| 2820 | 2809 | ||
| 2821 | local_irq_save(flags); | 2810 | local_irq_save(flags); |
| 2822 | if (up->port.sysrq) { | 2811 | if (port->sysrq) { |
| 2823 | /* serial8250_handle_irq() already took the lock */ | 2812 | /* serial8250_handle_irq() already took the lock */ |
| 2824 | locked = 0; | 2813 | locked = 0; |
| 2825 | } else if (oops_in_progress) { | 2814 | } else if (oops_in_progress) { |
| 2826 | locked = spin_trylock(&up->port.lock); | 2815 | locked = spin_trylock(&port->lock); |
| 2827 | } else | 2816 | } else |
| 2828 | spin_lock(&up->port.lock); | 2817 | spin_lock(&port->lock); |
| 2829 | 2818 | ||
| 2830 | /* | 2819 | /* |
| 2831 | * First save the IER then disable the interrupts | 2820 | * First save the IER then disable the interrupts |
| 2832 | */ | 2821 | */ |
| 2833 | ier = serial_in(up, UART_IER); | 2822 | ier = serial_port_in(port, UART_IER); |
| 2834 | 2823 | ||
| 2835 | if (up->capabilities & UART_CAP_UUE) | 2824 | if (up->capabilities & UART_CAP_UUE) |
| 2836 | serial_out(up, UART_IER, UART_IER_UUE); | 2825 | serial_port_out(port, UART_IER, UART_IER_UUE); |
| 2837 | else | 2826 | else |
| 2838 | serial_out(up, UART_IER, 0); | 2827 | serial_port_out(port, UART_IER, 0); |
| 2839 | 2828 | ||
| 2840 | uart_console_write(&up->port, s, count, serial8250_console_putchar); | 2829 | uart_console_write(port, s, count, serial8250_console_putchar); |
| 2841 | 2830 | ||
| 2842 | /* | 2831 | /* |
| 2843 | * Finally, wait for transmitter to become empty | 2832 | * Finally, wait for transmitter to become empty |
| 2844 | * and restore the IER | 2833 | * and restore the IER |
| 2845 | */ | 2834 | */ |
| 2846 | wait_for_xmitr(up, BOTH_EMPTY); | 2835 | wait_for_xmitr(up, BOTH_EMPTY); |
| 2847 | serial_out(up, UART_IER, ier); | 2836 | serial_port_out(port, UART_IER, ier); |
| 2848 | 2837 | ||
| 2849 | /* | 2838 | /* |
| 2850 | * The receive handling will happen properly because the | 2839 | * The receive handling will happen properly because the |
| @@ -2857,7 +2846,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) | |||
| 2857 | serial8250_modem_status(up); | 2846 | serial8250_modem_status(up); |
| 2858 | 2847 | ||
| 2859 | if (locked) | 2848 | if (locked) |
| 2860 | spin_unlock(&up->port.lock); | 2849 | spin_unlock(&port->lock); |
| 2861 | local_irq_restore(flags); | 2850 | local_irq_restore(flags); |
| 2862 | } | 2851 | } |
| 2863 | 2852 | ||
| @@ -3002,17 +2991,18 @@ void serial8250_suspend_port(int line) | |||
| 3002 | void serial8250_resume_port(int line) | 2991 | void serial8250_resume_port(int line) |
| 3003 | { | 2992 | { |
| 3004 | struct uart_8250_port *up = &serial8250_ports[line]; | 2993 | struct uart_8250_port *up = &serial8250_ports[line]; |
| 2994 | struct uart_port *port = &up->port; | ||
| 3005 | 2995 | ||
| 3006 | if (up->capabilities & UART_NATSEMI) { | 2996 | if (up->capabilities & UART_NATSEMI) { |
| 3007 | /* Ensure it's still in high speed mode */ | 2997 | /* Ensure it's still in high speed mode */ |
| 3008 | serial_outp(up, UART_LCR, 0xE0); | 2998 | serial_port_out(port, UART_LCR, 0xE0); |
| 3009 | 2999 | ||
| 3010 | ns16550a_goto_highspeed(up); | 3000 | ns16550a_goto_highspeed(up); |
| 3011 | 3001 | ||
| 3012 | serial_outp(up, UART_LCR, 0); | 3002 | serial_port_out(port, UART_LCR, 0); |
| 3013 | up->port.uartclk = 921600*16; | 3003 | port->uartclk = 921600*16; |
| 3014 | } | 3004 | } |
| 3015 | uart_resume_port(&serial8250_reg, &up->port); | 3005 | uart_resume_port(&serial8250_reg, port); |
| 3016 | } | 3006 | } |
| 3017 | 3007 | ||
| 3018 | /* | 3008 | /* |
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index ae027be57e25..2868a1da254d 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h | |||
| @@ -86,6 +86,16 @@ struct serial8250_config { | |||
| 86 | #define SERIAL8250_SHARE_IRQS 0 | 86 | #define SERIAL8250_SHARE_IRQS 0 |
| 87 | #endif | 87 | #endif |
| 88 | 88 | ||
| 89 | static inline int serial_in(struct uart_8250_port *up, int offset) | ||
| 90 | { | ||
| 91 | return up->port.serial_in(&up->port, offset); | ||
| 92 | } | ||
| 93 | |||
| 94 | static inline void serial_out(struct uart_8250_port *up, int offset, int value) | ||
| 95 | { | ||
| 96 | up->port.serial_out(&up->port, offset, value); | ||
| 97 | } | ||
| 98 | |||
| 89 | #if defined(__alpha__) && !defined(CONFIG_PCI) | 99 | #if defined(__alpha__) && !defined(CONFIG_PCI) |
| 90 | /* | 100 | /* |
| 91 | * Digital did something really horribly wrong with the OUT1 and OUT2 | 101 | * Digital did something really horribly wrong with the OUT1 and OUT2 |
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 2de99248dfae..76e7764488e6 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
| @@ -1347,4 +1347,17 @@ config SERIAL_AR933X_NR_UARTS | |||
| 1347 | Set this to the number of serial ports you want the driver | 1347 | Set this to the number of serial ports you want the driver |
| 1348 | to support. | 1348 | to support. |
| 1349 | 1349 | ||
| 1350 | config SERIAL_EFM32_UART | ||
| 1351 | tristate "EFM32 UART/USART port." | ||
| 1352 | depends on ARCH_EFM32 | ||
| 1353 | select SERIAL_CORE | ||
| 1354 | help | ||
| 1355 | This driver support the USART and UART ports on | ||
| 1356 | Energy Micro's efm32 SoCs. | ||
| 1357 | |||
| 1358 | config SERIAL_EFM32_UART_CONSOLE | ||
| 1359 | bool "EFM32 UART/USART console support" | ||
| 1360 | depends on SERIAL_EFM32_UART=y | ||
| 1361 | select SERIAL_CORE_CONSOLE | ||
| 1362 | |||
| 1350 | endmenu | 1363 | endmenu |
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index fef32e10c851..7257c5d898ae 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile | |||
| @@ -61,12 +61,12 @@ obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o | |||
| 61 | obj-$(CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL) += nwpserial.o | 61 | obj-$(CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL) += nwpserial.o |
| 62 | obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o | 62 | obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o |
| 63 | obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o | 63 | obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o |
| 64 | obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o | ||
| 64 | obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o | 65 | obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o |
| 65 | obj-$(CONFIG_SERIAL_QE) += ucc_uart.o | 66 | obj-$(CONFIG_SERIAL_QE) += ucc_uart.o |
| 66 | obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o | 67 | obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o |
| 67 | obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o | 68 | obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o |
| 68 | obj-$(CONFIG_SERIAL_ALTERA_JTAGUART) += altera_jtaguart.o | 69 | obj-$(CONFIG_SERIAL_ALTERA_JTAGUART) += altera_jtaguart.o |
| 69 | obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o | ||
| 70 | obj-$(CONFIG_SERIAL_VT8500) += vt8500_serial.o | 70 | obj-$(CONFIG_SERIAL_VT8500) += vt8500_serial.o |
| 71 | obj-$(CONFIG_SERIAL_MRST_MAX3110) += mrst_max3110.o | 71 | obj-$(CONFIG_SERIAL_MRST_MAX3110) += mrst_max3110.o |
| 72 | obj-$(CONFIG_SERIAL_MFD_HSU) += mfd.o | 72 | obj-$(CONFIG_SERIAL_MFD_HSU) += mfd.o |
| @@ -78,3 +78,4 @@ obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o | |||
| 78 | obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o | 78 | obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o |
| 79 | obj-$(CONFIG_SERIAL_SIRFSOC) += sirfsoc_uart.o | 79 | obj-$(CONFIG_SERIAL_SIRFSOC) += sirfsoc_uart.o |
| 80 | obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o | 80 | obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o |
| 81 | obj-$(CONFIG_SERIAL_EFM32_UART) += efm32-uart.o | ||
diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index 1d04c5037f25..e7903751e058 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c | |||
| @@ -377,6 +377,26 @@ static int altera_uart_verify_port(struct uart_port *port, | |||
| 377 | return 0; | 377 | return 0; |
| 378 | } | 378 | } |
| 379 | 379 | ||
| 380 | #ifdef CONFIG_CONSOLE_POLL | ||
| 381 | static int altera_uart_poll_get_char(struct uart_port *port) | ||
| 382 | { | ||
| 383 | while (!(altera_uart_readl(port, ALTERA_UART_STATUS_REG) & | ||
| 384 | ALTERA_UART_STATUS_RRDY_MSK)) | ||
| 385 | cpu_relax(); | ||
| 386 | |||
| 387 | return altera_uart_readl(port, ALTERA_UART_RXDATA_REG); | ||
| 388 | } | ||
| 389 | |||
| 390 | static void altera_uart_poll_put_char(struct uart_port *port, unsigned char c) | ||
| 391 | { | ||
| 392 | while (!(altera_uart_readl(port, ALTERA_UART_STATUS_REG) & | ||
| 393 | ALTERA_UART_STATUS_TRDY_MSK)) | ||
| 394 | cpu_relax(); | ||
| 395 | |||
| 396 | altera_uart_writel(port, c, ALTERA_UART_TXDATA_REG); | ||
| 397 | } | ||
| 398 | #endif | ||
| 399 | |||
| 380 | /* | 400 | /* |
| 381 | * Define the basic serial functions we support. | 401 | * Define the basic serial functions we support. |
| 382 | */ | 402 | */ |
| @@ -397,35 +417,16 @@ static struct uart_ops altera_uart_ops = { | |||
| 397 | .release_port = altera_uart_release_port, | 417 | .release_port = altera_uart_release_port, |
| 398 | .config_port = altera_uart_config_port, | 418 | .config_port = altera_uart_config_port, |
| 399 | .verify_port = altera_uart_verify_port, | 419 | .verify_port = altera_uart_verify_port, |
| 420 | #ifdef CONFIG_CONSOLE_POLL | ||
| 421 | .poll_get_char = altera_uart_poll_get_char, | ||
| 422 | .poll_put_char = altera_uart_poll_put_char, | ||
| 423 | #endif | ||
| 400 | }; | 424 | }; |
| 401 | 425 | ||
| 402 | static struct altera_uart altera_uart_ports[CONFIG_SERIAL_ALTERA_UART_MAXPORTS]; | 426 | static struct altera_uart altera_uart_ports[CONFIG_SERIAL_ALTERA_UART_MAXPORTS]; |
| 403 | 427 | ||
| 404 | #if defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE) | 428 | #if defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE) |
| 405 | 429 | ||
| 406 | int __init early_altera_uart_setup(struct altera_uart_platform_uart *platp) | ||
| 407 | { | ||
| 408 | struct uart_port *port; | ||
| 409 | int i; | ||
| 410 | |||
| 411 | for (i = 0; i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS && platp[i].mapbase; i++) { | ||
| 412 | port = &altera_uart_ports[i].port; | ||
| 413 | |||
| 414 | port->line = i; | ||
| 415 | port->type = PORT_ALTERA_UART; | ||
| 416 | port->mapbase = platp[i].mapbase; | ||
| 417 | port->membase = ioremap(port->mapbase, ALTERA_UART_SIZE); | ||
| 418 | port->iotype = SERIAL_IO_MEM; | ||
| 419 | port->irq = platp[i].irq; | ||
| 420 | port->uartclk = platp[i].uartclk; | ||
| 421 | port->flags = UPF_BOOT_AUTOCONF; | ||
| 422 | port->ops = &altera_uart_ops; | ||
| 423 | port->private_data = platp; | ||
| 424 | } | ||
| 425 | |||
| 426 | return 0; | ||
| 427 | } | ||
| 428 | |||
| 429 | static void altera_uart_console_putc(struct uart_port *port, const char c) | 430 | static void altera_uart_console_putc(struct uart_port *port, const char c) |
| 430 | { | 431 | { |
| 431 | while (!(altera_uart_readl(port, ALTERA_UART_STATUS_REG) & | 432 | while (!(altera_uart_readl(port, ALTERA_UART_STATUS_REG) & |
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 6800f5f26241..20d795d9b591 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c | |||
| @@ -827,7 +827,12 @@ static void pl011_dma_rx_callback(void *data) | |||
| 827 | { | 827 | { |
| 828 | struct uart_amba_port *uap = data; | 828 | struct uart_amba_port *uap = data; |
| 829 | struct pl011_dmarx_data *dmarx = &uap->dmarx; | 829 | struct pl011_dmarx_data *dmarx = &uap->dmarx; |
| 830 | struct dma_chan *rxchan = dmarx->chan; | ||
| 830 | bool lastbuf = dmarx->use_buf_b; | 831 | bool lastbuf = dmarx->use_buf_b; |
| 832 | struct pl011_sgbuf *sgbuf = dmarx->use_buf_b ? | ||
| 833 | &dmarx->sgbuf_b : &dmarx->sgbuf_a; | ||
| 834 | size_t pending; | ||
| 835 | struct dma_tx_state state; | ||
| 831 | int ret; | 836 | int ret; |
| 832 | 837 | ||
| 833 | /* | 838 | /* |
| @@ -838,11 +843,21 @@ static void pl011_dma_rx_callback(void *data) | |||
| 838 | * we immediately trigger the next DMA job. | 843 | * we immediately trigger the next DMA job. |
| 839 | */ | 844 | */ |
| 840 | spin_lock_irq(&uap->port.lock); | 845 | spin_lock_irq(&uap->port.lock); |
| 846 | /* | ||
| 847 | * Rx data can be taken by the UART interrupts during | ||
| 848 | * the DMA irq handler. So we check the residue here. | ||
| 849 | */ | ||
| 850 | rxchan->device->device_tx_status(rxchan, dmarx->cookie, &state); | ||
| 851 | pending = sgbuf->sg.length - state.residue; | ||
| 852 | BUG_ON(pending > PL011_DMA_BUFFER_SIZE); | ||
| 853 | /* Then we terminate the transfer - we now know our residue */ | ||
| 854 | dmaengine_terminate_all(rxchan); | ||
| 855 | |||
| 841 | uap->dmarx.running = false; | 856 | uap->dmarx.running = false; |
| 842 | dmarx->use_buf_b = !lastbuf; | 857 | dmarx->use_buf_b = !lastbuf; |
| 843 | ret = pl011_dma_rx_trigger_dma(uap); | 858 | ret = pl011_dma_rx_trigger_dma(uap); |
| 844 | 859 | ||
| 845 | pl011_dma_rx_chars(uap, PL011_DMA_BUFFER_SIZE, lastbuf, false); | 860 | pl011_dma_rx_chars(uap, pending, lastbuf, false); |
| 846 | spin_unlock_irq(&uap->port.lock); | 861 | spin_unlock_irq(&uap->port.lock); |
| 847 | /* | 862 | /* |
| 848 | * Do this check after we picked the DMA chars so we don't | 863 | * Do this check after we picked the DMA chars so we don't |
| @@ -1381,6 +1396,10 @@ static int pl011_startup(struct uart_port *port) | |||
| 1381 | 1396 | ||
| 1382 | uap->port.uartclk = clk_get_rate(uap->clk); | 1397 | uap->port.uartclk = clk_get_rate(uap->clk); |
| 1383 | 1398 | ||
| 1399 | /* Clear pending error and receive interrupts */ | ||
| 1400 | writew(UART011_OEIS | UART011_BEIS | UART011_PEIS | UART011_FEIS | | ||
| 1401 | UART011_RTIS | UART011_RXIS, uap->port.membase + UART011_ICR); | ||
| 1402 | |||
| 1384 | /* | 1403 | /* |
| 1385 | * Allocate the IRQ | 1404 | * Allocate the IRQ |
| 1386 | */ | 1405 | */ |
| @@ -1417,10 +1436,6 @@ static int pl011_startup(struct uart_port *port) | |||
| 1417 | cr |= UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE; | 1436 | cr |= UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE; |
| 1418 | writew(cr, uap->port.membase + UART011_CR); | 1437 | writew(cr, uap->port.membase + UART011_CR); |
| 1419 | 1438 | ||
| 1420 | /* Clear pending error interrupts */ | ||
| 1421 | writew(UART011_OEIS | UART011_BEIS | UART011_PEIS | UART011_FEIS, | ||
| 1422 | uap->port.membase + UART011_ICR); | ||
| 1423 | |||
| 1424 | /* | 1439 | /* |
| 1425 | * initialise the old status of the modem signals | 1440 | * initialise the old status of the modem signals |
| 1426 | */ | 1441 | */ |
| @@ -1435,6 +1450,9 @@ static int pl011_startup(struct uart_port *port) | |||
| 1435 | * as well. | 1450 | * as well. |
| 1436 | */ | 1451 | */ |
| 1437 | spin_lock_irq(&uap->port.lock); | 1452 | spin_lock_irq(&uap->port.lock); |
| 1453 | /* Clear out any spuriously appearing RX interrupts */ | ||
| 1454 | writew(UART011_RTIS | UART011_RXIS, | ||
| 1455 | uap->port.membase + UART011_ICR); | ||
| 1438 | uap->im = UART011_RTIM; | 1456 | uap->im = UART011_RTIM; |
| 1439 | if (!pl011_dma_rx_running(uap)) | 1457 | if (!pl011_dma_rx_running(uap)) |
| 1440 | uap->im |= UART011_RXIM; | 1458 | uap->im |= UART011_RXIM; |
| @@ -1927,6 +1945,10 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) | |||
| 1927 | goto unmap; | 1945 | goto unmap; |
| 1928 | } | 1946 | } |
| 1929 | 1947 | ||
| 1948 | /* Ensure interrupts from this UART are masked and cleared */ | ||
| 1949 | writew(0, uap->port.membase + UART011_IMSC); | ||
| 1950 | writew(0xffff, uap->port.membase + UART011_ICR); | ||
| 1951 | |||
| 1930 | uap->vendor = vendor; | 1952 | uap->vendor = vendor; |
| 1931 | uap->lcrh_rx = vendor->lcrh_rx; | 1953 | uap->lcrh_rx = vendor->lcrh_rx; |
| 1932 | uap->lcrh_tx = vendor->lcrh_tx; | 1954 | uap->lcrh_tx = vendor->lcrh_tx; |
diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c index 26953bfa6922..5832fdef11e9 100644 --- a/drivers/tty/serial/bfin_uart.c +++ b/drivers/tty/serial/bfin_uart.c | |||
| @@ -535,11 +535,13 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) | |||
| 535 | * when start a new tx. | 535 | * when start a new tx. |
| 536 | */ | 536 | */ |
| 537 | UART_CLEAR_IER(uart, ETBEI); | 537 | UART_CLEAR_IER(uart, ETBEI); |
| 538 | xmit->tail = (xmit->tail + uart->tx_count) & (UART_XMIT_SIZE - 1); | ||
| 539 | uart->port.icount.tx += uart->tx_count; | 538 | uart->port.icount.tx += uart->tx_count; |
| 539 | if (!uart_circ_empty(xmit)) { | ||
| 540 | xmit->tail = (xmit->tail + uart->tx_count) & (UART_XMIT_SIZE - 1); | ||
| 540 | 541 | ||
| 541 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 542 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
| 542 | uart_write_wakeup(&uart->port); | 543 | uart_write_wakeup(&uart->port); |
| 544 | } | ||
| 543 | 545 | ||
| 544 | bfin_serial_dma_tx_chars(uart); | 546 | bfin_serial_dma_tx_chars(uart); |
| 545 | } | 547 | } |
diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index 1dfba7b779c8..23d791696879 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c | |||
| @@ -4105,20 +4105,11 @@ static int | |||
| 4105 | rs_open(struct tty_struct *tty, struct file * filp) | 4105 | rs_open(struct tty_struct *tty, struct file * filp) |
| 4106 | { | 4106 | { |
| 4107 | struct e100_serial *info; | 4107 | struct e100_serial *info; |
| 4108 | int retval, line; | 4108 | int retval; |
| 4109 | unsigned long page; | 4109 | unsigned long page; |
| 4110 | int allocated_resources = 0; | 4110 | int allocated_resources = 0; |
| 4111 | 4111 | ||
| 4112 | /* find which port we want to open */ | 4112 | info = rs_table + tty->index; |
| 4113 | line = tty->index; | ||
| 4114 | |||
| 4115 | if (line < 0 || line >= NR_PORTS) | ||
| 4116 | return -ENODEV; | ||
| 4117 | |||
| 4118 | /* find the corresponding e100_serial struct in the table */ | ||
| 4119 | info = rs_table + line; | ||
| 4120 | |||
| 4121 | /* don't allow the opening of ports that are not enabled in the HW config */ | ||
| 4122 | if (!info->enabled) | 4113 | if (!info->enabled) |
| 4123 | return -ENODEV; | 4114 | return -ENODEV; |
| 4124 | 4115 | ||
| @@ -4131,7 +4122,7 @@ rs_open(struct tty_struct *tty, struct file * filp) | |||
| 4131 | tty->driver_data = info; | 4122 | tty->driver_data = info; |
| 4132 | info->port.tty = tty; | 4123 | info->port.tty = tty; |
| 4133 | 4124 | ||
| 4134 | info->port.tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 4125 | tty->low_latency = !!(info->flags & ASYNC_LOW_LATENCY); |
| 4135 | 4126 | ||
| 4136 | if (!tmp_buf) { | 4127 | if (!tmp_buf) { |
| 4137 | page = get_zeroed_page(GFP_KERNEL); | 4128 | page = get_zeroed_page(GFP_KERNEL); |
diff --git a/drivers/tty/serial/efm32-uart.c b/drivers/tty/serial/efm32-uart.c new file mode 100644 index 000000000000..615e46470491 --- /dev/null +++ b/drivers/tty/serial/efm32-uart.c | |||
| @@ -0,0 +1,830 @@ | |||
| 1 | #if defined(CONFIG_SERIAL_EFM32_UART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | ||
| 2 | #define SUPPORT_SYSRQ | ||
| 3 | #endif | ||
| 4 | |||
| 5 | #include <linux/kernel.h> | ||
| 6 | #include <linux/module.h> | ||
| 7 | #include <linux/io.h> | ||
| 8 | #include <linux/platform_device.h> | ||
| 9 | #include <linux/console.h> | ||
| 10 | #include <linux/sysrq.h> | ||
| 11 | #include <linux/serial_core.h> | ||
| 12 | #include <linux/tty_flip.h> | ||
| 13 | #include <linux/slab.h> | ||
| 14 | #include <linux/clk.h> | ||
| 15 | #include <linux/of.h> | ||
| 16 | #include <linux/of_device.h> | ||
| 17 | |||
| 18 | #include <linux/platform_data/efm32-uart.h> | ||
| 19 | |||
| 20 | #define DRIVER_NAME "efm32-uart" | ||
| 21 | #define DEV_NAME "ttyefm" | ||
| 22 | |||
| 23 | #define UARTn_CTRL 0x00 | ||
| 24 | #define UARTn_CTRL_SYNC 0x0001 | ||
| 25 | #define UARTn_CTRL_TXBIL 0x1000 | ||
| 26 | |||
| 27 | #define UARTn_FRAME 0x04 | ||
| 28 | #define UARTn_FRAME_DATABITS__MASK 0x000f | ||
| 29 | #define UARTn_FRAME_DATABITS(n) ((n) - 3) | ||
| 30 | #define UARTn_FRAME_PARITY_NONE 0x0000 | ||
| 31 | #define UARTn_FRAME_PARITY_EVEN 0x0200 | ||
| 32 | #define UARTn_FRAME_PARITY_ODD 0x0300 | ||
| 33 | #define UARTn_FRAME_STOPBITS_HALF 0x0000 | ||
| 34 | #define UARTn_FRAME_STOPBITS_ONE 0x1000 | ||
| 35 | #define UARTn_FRAME_STOPBITS_TWO 0x3000 | ||
| 36 | |||
| 37 | #define UARTn_CMD 0x0c | ||
| 38 | #define UARTn_CMD_RXEN 0x0001 | ||
| 39 | #define UARTn_CMD_RXDIS 0x0002 | ||
| 40 | #define UARTn_CMD_TXEN 0x0004 | ||
| 41 | #define UARTn_CMD_TXDIS 0x0008 | ||
| 42 | |||
| 43 | #define UARTn_STATUS 0x10 | ||
| 44 | #define UARTn_STATUS_TXENS 0x0002 | ||
| 45 | #define UARTn_STATUS_TXC 0x0020 | ||
| 46 | #define UARTn_STATUS_TXBL 0x0040 | ||
| 47 | #define UARTn_STATUS_RXDATAV 0x0080 | ||
| 48 | |||
| 49 | #define UARTn_CLKDIV 0x14 | ||
| 50 | |||
| 51 | #define UARTn_RXDATAX 0x18 | ||
| 52 | #define UARTn_RXDATAX_RXDATA__MASK 0x01ff | ||
| 53 | #define UARTn_RXDATAX_PERR 0x4000 | ||
| 54 | #define UARTn_RXDATAX_FERR 0x8000 | ||
| 55 | /* | ||
| 56 | * This is a software only flag used for ignore_status_mask and | ||
| 57 | * read_status_mask! It's used for breaks that the hardware doesn't report | ||
| 58 | * explicitly. | ||
| 59 | */ | ||
| 60 | #define SW_UARTn_RXDATAX_BERR 0x2000 | ||
| 61 | |||
| 62 | #define UARTn_TXDATA 0x34 | ||
| 63 | |||
| 64 | #define UARTn_IF 0x40 | ||
| 65 | #define UARTn_IF_TXC 0x0001 | ||
| 66 | #define UARTn_IF_TXBL 0x0002 | ||
| 67 | #define UARTn_IF_RXDATAV 0x0004 | ||
| 68 | #define UARTn_IF_RXOF 0x0010 | ||
| 69 | |||
| 70 | #define UARTn_IFS 0x44 | ||
| 71 | #define UARTn_IFC 0x48 | ||
| 72 | #define UARTn_IEN 0x4c | ||
| 73 | |||
| 74 | #define UARTn_ROUTE 0x54 | ||
| 75 | #define UARTn_ROUTE_LOCATION__MASK 0x0700 | ||
| 76 | #define UARTn_ROUTE_LOCATION(n) (((n) << 8) & UARTn_ROUTE_LOCATION__MASK) | ||
| 77 | #define UARTn_ROUTE_RXPEN 0x0001 | ||
| 78 | #define UARTn_ROUTE_TXPEN 0x0002 | ||
| 79 | |||
| 80 | struct efm32_uart_port { | ||
| 81 | struct uart_port port; | ||
| 82 | unsigned int txirq; | ||
| 83 | struct clk *clk; | ||
| 84 | }; | ||
| 85 | #define to_efm_port(_port) container_of(_port, struct efm32_uart_port, port) | ||
| 86 | #define efm_debug(efm_port, format, arg...) \ | ||
| 87 | dev_dbg(efm_port->port.dev, format, ##arg) | ||
| 88 | |||
| 89 | static void efm32_uart_write32(struct efm32_uart_port *efm_port, | ||
| 90 | u32 value, unsigned offset) | ||
| 91 | { | ||
| 92 | writel_relaxed(value, efm_port->port.membase + offset); | ||
| 93 | } | ||
| 94 | |||
| 95 | static u32 efm32_uart_read32(struct efm32_uart_port *efm_port, | ||
| 96 | unsigned offset) | ||
| 97 | { | ||
| 98 | return readl_relaxed(efm_port->port.membase + offset); | ||
| 99 | } | ||
| 100 | |||
| 101 | static unsigned int efm32_uart_tx_empty(struct uart_port *port) | ||
| 102 | { | ||
| 103 | struct efm32_uart_port *efm_port = to_efm_port(port); | ||
| 104 | u32 status = efm32_uart_read32(efm_port, UARTn_STATUS); | ||
| 105 | |||
| 106 | if (status & UARTn_STATUS_TXC) | ||
| 107 | return TIOCSER_TEMT; | ||
| 108 | else | ||
| 109 | return 0; | ||
| 110 | } | ||
| 111 | |||
| 112 | static void efm32_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
| 113 | { | ||
| 114 | /* sorry, neither handshaking lines nor loop functionallity */ | ||
| 115 | } | ||
| 116 | |||
| 117 | static unsigned int efm32_uart_get_mctrl(struct uart_port *port) | ||
| 118 | { | ||
| 119 | /* sorry, no handshaking lines available */ | ||
| 120 | return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR; | ||
| 121 | } | ||
| 122 | |||
| 123 | static void efm32_uart_stop_tx(struct uart_port *port) | ||
| 124 | { | ||
| 125 | struct efm32_uart_port *efm_port = to_efm_port(port); | ||
| 126 | u32 ien = efm32_uart_read32(efm_port, UARTn_IEN); | ||
| 127 | |||
| 128 | efm32_uart_write32(efm_port, UARTn_CMD_TXDIS, UARTn_CMD); | ||
| 129 | ien &= ~(UARTn_IF_TXC | UARTn_IF_TXBL); | ||
| 130 | efm32_uart_write32(efm_port, ien, UARTn_IEN); | ||
| 131 | } | ||
| 132 | |||
| 133 | static void efm32_uart_tx_chars(struct efm32_uart_port *efm_port) | ||
| 134 | { | ||
| 135 | struct uart_port *port = &efm_port->port; | ||
| 136 | struct circ_buf *xmit = &port->state->xmit; | ||
| 137 | |||
| 138 | while (efm32_uart_read32(efm_port, UARTn_STATUS) & | ||
| 139 | UARTn_STATUS_TXBL) { | ||
| 140 | if (port->x_char) { | ||
| 141 | port->icount.tx++; | ||
| 142 | efm32_uart_write32(efm_port, port->x_char, | ||
| 143 | UARTn_TXDATA); | ||
| 144 | port->x_char = 0; | ||
| 145 | continue; | ||
| 146 | } | ||
| 147 | if (!uart_circ_empty(xmit) && !uart_tx_stopped(port)) { | ||
| 148 | port->icount.tx++; | ||
| 149 | efm32_uart_write32(efm_port, xmit->buf[xmit->tail], | ||
| 150 | UARTn_TXDATA); | ||
| 151 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
| 152 | } else | ||
| 153 | break; | ||
| 154 | } | ||
| 155 | |||
| 156 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
| 157 | uart_write_wakeup(port); | ||
| 158 | |||
| 159 | if (!port->x_char && uart_circ_empty(xmit) && | ||
| 160 | efm32_uart_read32(efm_port, UARTn_STATUS) & | ||
| 161 | UARTn_STATUS_TXC) | ||
| 162 | efm32_uart_stop_tx(port); | ||
| 163 | } | ||
| 164 | |||
| 165 | static void efm32_uart_start_tx(struct uart_port *port) | ||
| 166 | { | ||
| 167 | struct efm32_uart_port *efm_port = to_efm_port(port); | ||
| 168 | u32 ien; | ||
| 169 | |||
| 170 | efm32_uart_write32(efm_port, | ||
| 171 | UARTn_IF_TXBL | UARTn_IF_TXC, UARTn_IFC); | ||
| 172 | ien = efm32_uart_read32(efm_port, UARTn_IEN); | ||
| 173 | efm32_uart_write32(efm_port, | ||
| 174 | ien | UARTn_IF_TXBL | UARTn_IF_TXC, UARTn_IEN); | ||
| 175 | efm32_uart_write32(efm_port, UARTn_CMD_TXEN, UARTn_CMD); | ||
| 176 | |||
| 177 | efm32_uart_tx_chars(efm_port); | ||
| 178 | } | ||
| 179 | |||
| 180 | static void efm32_uart_stop_rx(struct uart_port *port) | ||
| 181 | { | ||
| 182 | struct efm32_uart_port *efm_port = to_efm_port(port); | ||
| 183 | |||
| 184 | efm32_uart_write32(efm_port, UARTn_CMD_RXDIS, UARTn_CMD); | ||
| 185 | } | ||
| 186 | |||
| 187 | static void efm32_uart_enable_ms(struct uart_port *port) | ||
| 188 | { | ||
| 189 | /* no handshake lines, no modem status interrupts */ | ||
| 190 | } | ||
| 191 | |||
| 192 | static void efm32_uart_break_ctl(struct uart_port *port, int ctl) | ||
| 193 | { | ||
| 194 | /* not possible without fiddling with gpios */ | ||
| 195 | } | ||
| 196 | |||
| 197 | static void efm32_uart_rx_chars(struct efm32_uart_port *efm_port, | ||
| 198 | struct tty_struct *tty) | ||
| 199 | { | ||
| 200 | struct uart_port *port = &efm_port->port; | ||
| 201 | |||
| 202 | while (efm32_uart_read32(efm_port, UARTn_STATUS) & | ||
| 203 | UARTn_STATUS_RXDATAV) { | ||
| 204 | u32 rxdata = efm32_uart_read32(efm_port, UARTn_RXDATAX); | ||
| 205 | int flag = 0; | ||
| 206 | |||
| 207 | /* | ||
| 208 | * This is a reserved bit and I only saw it read as 0. But to be | ||
| 209 | * sure not to be confused too much by new devices adhere to the | ||
| 210 | * warning in the reference manual that reserverd bits might | ||
| 211 | * read as 1 in the future. | ||
| 212 | */ | ||
| 213 | rxdata &= ~SW_UARTn_RXDATAX_BERR; | ||
| 214 | |||
| 215 | port->icount.rx++; | ||
| 216 | |||
| 217 | if ((rxdata & UARTn_RXDATAX_FERR) && | ||
| 218 | !(rxdata & UARTn_RXDATAX_RXDATA__MASK)) { | ||
| 219 | rxdata |= SW_UARTn_RXDATAX_BERR; | ||
| 220 | port->icount.brk++; | ||
| 221 | if (uart_handle_break(port)) | ||
| 222 | continue; | ||
| 223 | } else if (rxdata & UARTn_RXDATAX_PERR) | ||
| 224 | port->icount.parity++; | ||
| 225 | else if (rxdata & UARTn_RXDATAX_FERR) | ||
| 226 | port->icount.frame++; | ||
| 227 | |||
| 228 | rxdata &= port->read_status_mask; | ||
| 229 | |||
| 230 | if (rxdata & SW_UARTn_RXDATAX_BERR) | ||
| 231 | flag = TTY_BREAK; | ||
| 232 | else if (rxdata & UARTn_RXDATAX_PERR) | ||
| 233 | flag = TTY_PARITY; | ||
| 234 | else if (rxdata & UARTn_RXDATAX_FERR) | ||
| 235 | flag = TTY_FRAME; | ||
| 236 | else if (uart_handle_sysrq_char(port, | ||
| 237 | rxdata & UARTn_RXDATAX_RXDATA__MASK)) | ||
| 238 | continue; | ||
| 239 | |||
| 240 | if (tty && (rxdata & port->ignore_status_mask) == 0) | ||
| 241 | tty_insert_flip_char(tty, | ||
| 242 | rxdata & UARTn_RXDATAX_RXDATA__MASK, flag); | ||
| 243 | } | ||
| 244 | } | ||
| 245 | |||
| 246 | static irqreturn_t efm32_uart_rxirq(int irq, void *data) | ||
| 247 | { | ||
| 248 | struct efm32_uart_port *efm_port = data; | ||
| 249 | u32 irqflag = efm32_uart_read32(efm_port, UARTn_IF); | ||
| 250 | int handled = IRQ_NONE; | ||
| 251 | struct uart_port *port = &efm_port->port; | ||
| 252 | struct tty_struct *tty; | ||
| 253 | |||
| 254 | spin_lock(&port->lock); | ||
| 255 | |||
| 256 | tty = tty_kref_get(port->state->port.tty); | ||
| 257 | |||
| 258 | if (irqflag & UARTn_IF_RXDATAV) { | ||
| 259 | efm32_uart_write32(efm_port, UARTn_IF_RXDATAV, UARTn_IFC); | ||
| 260 | efm32_uart_rx_chars(efm_port, tty); | ||
| 261 | |||
| 262 | handled = IRQ_HANDLED; | ||
| 263 | } | ||
| 264 | |||
| 265 | if (irqflag & UARTn_IF_RXOF) { | ||
| 266 | efm32_uart_write32(efm_port, UARTn_IF_RXOF, UARTn_IFC); | ||
| 267 | port->icount.overrun++; | ||
| 268 | if (tty) | ||
| 269 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
| 270 | |||
| 271 | handled = IRQ_HANDLED; | ||
| 272 | } | ||
| 273 | |||
| 274 | if (tty) { | ||
| 275 | tty_flip_buffer_push(tty); | ||
| 276 | tty_kref_put(tty); | ||
| 277 | } | ||
| 278 | |||
| 279 | spin_unlock(&port->lock); | ||
| 280 | |||
| 281 | return handled; | ||
| 282 | } | ||
| 283 | |||
| 284 | static irqreturn_t efm32_uart_txirq(int irq, void *data) | ||
| 285 | { | ||
| 286 | struct efm32_uart_port *efm_port = data; | ||
| 287 | u32 irqflag = efm32_uart_read32(efm_port, UARTn_IF); | ||
| 288 | |||
| 289 | /* TXBL doesn't need to be cleared */ | ||
| 290 | if (irqflag & UARTn_IF_TXC) | ||
| 291 | efm32_uart_write32(efm_port, UARTn_IF_TXC, UARTn_IFC); | ||
| 292 | |||
| 293 | if (irqflag & (UARTn_IF_TXC | UARTn_IF_TXBL)) { | ||
| 294 | efm32_uart_tx_chars(efm_port); | ||
| 295 | return IRQ_HANDLED; | ||
| 296 | } else | ||
| 297 | return IRQ_NONE; | ||
| 298 | } | ||
| 299 | |||
| 300 | static int efm32_uart_startup(struct uart_port *port) | ||
| 301 | { | ||
| 302 | struct efm32_uart_port *efm_port = to_efm_port(port); | ||
| 303 | u32 location = 0; | ||
| 304 | struct efm32_uart_pdata *pdata = dev_get_platdata(port->dev); | ||
| 305 | int ret; | ||
| 306 | |||
| 307 | if (pdata) | ||
| 308 | location = UARTn_ROUTE_LOCATION(pdata->location); | ||
| 309 | |||
| 310 | ret = clk_enable(efm_port->clk); | ||
| 311 | if (ret) { | ||
| 312 | efm_debug(efm_port, "failed to enable clk\n"); | ||
| 313 | goto err_clk_enable; | ||
| 314 | } | ||
| 315 | port->uartclk = clk_get_rate(efm_port->clk); | ||
| 316 | |||
| 317 | /* Enable pins at configured location */ | ||
| 318 | efm32_uart_write32(efm_port, location | UARTn_ROUTE_RXPEN | UARTn_ROUTE_TXPEN, | ||
| 319 | UARTn_ROUTE); | ||
| 320 | |||
| 321 | ret = request_irq(port->irq, efm32_uart_rxirq, 0, | ||
| 322 | DRIVER_NAME, efm_port); | ||
| 323 | if (ret) { | ||
| 324 | efm_debug(efm_port, "failed to register rxirq\n"); | ||
| 325 | goto err_request_irq_rx; | ||
| 326 | } | ||
| 327 | |||
| 328 | /* disable all irqs */ | ||
| 329 | efm32_uart_write32(efm_port, 0, UARTn_IEN); | ||
| 330 | |||
| 331 | ret = request_irq(efm_port->txirq, efm32_uart_txirq, 0, | ||
| 332 | DRIVER_NAME, efm_port); | ||
| 333 | if (ret) { | ||
| 334 | efm_debug(efm_port, "failed to register txirq\n"); | ||
| 335 | free_irq(port->irq, efm_port); | ||
| 336 | err_request_irq_rx: | ||
| 337 | |||
| 338 | clk_disable(efm_port->clk); | ||
| 339 | } else { | ||
| 340 | efm32_uart_write32(efm_port, | ||
| 341 | UARTn_IF_RXDATAV | UARTn_IF_RXOF, UARTn_IEN); | ||
| 342 | efm32_uart_write32(efm_port, UARTn_CMD_RXEN, UARTn_CMD); | ||
| 343 | } | ||
| 344 | |||
| 345 | err_clk_enable: | ||
| 346 | return ret; | ||
| 347 | } | ||
| 348 | |||
| 349 | static void efm32_uart_shutdown(struct uart_port *port) | ||
| 350 | { | ||
| 351 | struct efm32_uart_port *efm_port = to_efm_port(port); | ||
| 352 | |||
| 353 | efm32_uart_write32(efm_port, 0, UARTn_IEN); | ||
| 354 | free_irq(port->irq, efm_port); | ||
| 355 | |||
| 356 | clk_disable(efm_port->clk); | ||
| 357 | } | ||
| 358 | |||
| 359 | static void efm32_uart_set_termios(struct uart_port *port, | ||
| 360 | struct ktermios *new, struct ktermios *old) | ||
| 361 | { | ||
| 362 | struct efm32_uart_port *efm_port = to_efm_port(port); | ||
| 363 | unsigned long flags; | ||
| 364 | unsigned baud; | ||
| 365 | u32 clkdiv; | ||
| 366 | u32 frame = 0; | ||
| 367 | |||
| 368 | /* no modem control lines */ | ||
| 369 | new->c_cflag &= ~(CRTSCTS | CMSPAR); | ||
| 370 | |||
| 371 | baud = uart_get_baud_rate(port, new, old, | ||
| 372 | DIV_ROUND_CLOSEST(port->uartclk, 16 * 8192), | ||
| 373 | DIV_ROUND_CLOSEST(port->uartclk, 16)); | ||
| 374 | |||
| 375 | switch (new->c_cflag & CSIZE) { | ||
| 376 | case CS5: | ||
| 377 | frame |= UARTn_FRAME_DATABITS(5); | ||
| 378 | break; | ||
| 379 | case CS6: | ||
| 380 | frame |= UARTn_FRAME_DATABITS(6); | ||
| 381 | break; | ||
| 382 | case CS7: | ||
| 383 | frame |= UARTn_FRAME_DATABITS(7); | ||
| 384 | break; | ||
| 385 | case CS8: | ||
| 386 | frame |= UARTn_FRAME_DATABITS(8); | ||
| 387 | break; | ||
| 388 | } | ||
| 389 | |||
| 390 | if (new->c_cflag & CSTOPB) | ||
| 391 | /* the receiver only verifies the first stop bit */ | ||
| 392 | frame |= UARTn_FRAME_STOPBITS_TWO; | ||
| 393 | else | ||
| 394 | frame |= UARTn_FRAME_STOPBITS_ONE; | ||
| 395 | |||
| 396 | if (new->c_cflag & PARENB) { | ||
| 397 | if (new->c_cflag & PARODD) | ||
| 398 | frame |= UARTn_FRAME_PARITY_ODD; | ||
| 399 | else | ||
| 400 | frame |= UARTn_FRAME_PARITY_EVEN; | ||
| 401 | } else | ||
| 402 | frame |= UARTn_FRAME_PARITY_NONE; | ||
| 403 | |||
| 404 | /* | ||
| 405 | * the 6 lowest bits of CLKDIV are dc, bit 6 has value 0.25. | ||
| 406 | * port->uartclk <= 14e6, so 4 * port->uartclk doesn't overflow. | ||
| 407 | */ | ||
| 408 | clkdiv = (DIV_ROUND_CLOSEST(4 * port->uartclk, 16 * baud) - 4) << 6; | ||
| 409 | |||
| 410 | spin_lock_irqsave(&port->lock, flags); | ||
| 411 | |||
| 412 | efm32_uart_write32(efm_port, | ||
| 413 | UARTn_CMD_TXDIS | UARTn_CMD_RXDIS, UARTn_CMD); | ||
| 414 | |||
| 415 | port->read_status_mask = UARTn_RXDATAX_RXDATA__MASK; | ||
| 416 | if (new->c_iflag & INPCK) | ||
| 417 | port->read_status_mask |= | ||
| 418 | UARTn_RXDATAX_FERR | UARTn_RXDATAX_PERR; | ||
| 419 | if (new->c_iflag & (BRKINT | PARMRK)) | ||
| 420 | port->read_status_mask |= SW_UARTn_RXDATAX_BERR; | ||
| 421 | |||
| 422 | port->ignore_status_mask = 0; | ||
| 423 | if (new->c_iflag & IGNPAR) | ||
| 424 | port->ignore_status_mask |= | ||
| 425 | UARTn_RXDATAX_FERR | UARTn_RXDATAX_PERR; | ||
| 426 | if (new->c_iflag & IGNBRK) | ||
| 427 | port->ignore_status_mask |= SW_UARTn_RXDATAX_BERR; | ||
| 428 | |||
| 429 | uart_update_timeout(port, new->c_cflag, baud); | ||
| 430 | |||
| 431 | efm32_uart_write32(efm_port, UARTn_CTRL_TXBIL, UARTn_CTRL); | ||
| 432 | efm32_uart_write32(efm_port, frame, UARTn_FRAME); | ||
| 433 | efm32_uart_write32(efm_port, clkdiv, UARTn_CLKDIV); | ||
| 434 | |||
| 435 | efm32_uart_write32(efm_port, UARTn_CMD_TXEN | UARTn_CMD_RXEN, | ||
| 436 | UARTn_CMD); | ||
| 437 | |||
| 438 | spin_unlock_irqrestore(&port->lock, flags); | ||
| 439 | } | ||
| 440 | |||
| 441 | static const char *efm32_uart_type(struct uart_port *port) | ||
| 442 | { | ||
| 443 | return port->type == PORT_EFMUART ? "efm32-uart" : NULL; | ||
| 444 | } | ||
| 445 | |||
| 446 | static void efm32_uart_release_port(struct uart_port *port) | ||
| 447 | { | ||
| 448 | struct efm32_uart_port *efm_port = to_efm_port(port); | ||
| 449 | |||
| 450 | clk_unprepare(efm_port->clk); | ||
| 451 | clk_put(efm_port->clk); | ||
| 452 | iounmap(port->membase); | ||
| 453 | } | ||
| 454 | |||
| 455 | static int efm32_uart_request_port(struct uart_port *port) | ||
| 456 | { | ||
| 457 | struct efm32_uart_port *efm_port = to_efm_port(port); | ||
| 458 | int ret; | ||
| 459 | |||
| 460 | port->membase = ioremap(port->mapbase, 60); | ||
| 461 | if (!efm_port->port.membase) { | ||
| 462 | ret = -ENOMEM; | ||
| 463 | efm_debug(efm_port, "failed to remap\n"); | ||
| 464 | goto err_ioremap; | ||
| 465 | } | ||
| 466 | |||
| 467 | efm_port->clk = clk_get(port->dev, NULL); | ||
| 468 | if (IS_ERR(efm_port->clk)) { | ||
| 469 | ret = PTR_ERR(efm_port->clk); | ||
| 470 | efm_debug(efm_port, "failed to get clock\n"); | ||
| 471 | goto err_clk_get; | ||
| 472 | } | ||
| 473 | |||
| 474 | ret = clk_prepare(efm_port->clk); | ||
| 475 | if (ret) { | ||
| 476 | clk_put(efm_port->clk); | ||
| 477 | err_clk_get: | ||
| 478 | |||
| 479 | iounmap(port->membase); | ||
| 480 | err_ioremap: | ||
| 481 | return ret; | ||
| 482 | } | ||
| 483 | return 0; | ||
| 484 | } | ||
| 485 | |||
| 486 | static void efm32_uart_config_port(struct uart_port *port, int type) | ||
| 487 | { | ||
| 488 | if (type & UART_CONFIG_TYPE && | ||
| 489 | !efm32_uart_request_port(port)) | ||
| 490 | port->type = PORT_EFMUART; | ||
| 491 | } | ||
| 492 | |||
| 493 | static int efm32_uart_verify_port(struct uart_port *port, | ||
| 494 | struct serial_struct *serinfo) | ||
| 495 | { | ||
| 496 | int ret = 0; | ||
| 497 | |||
| 498 | if (serinfo->type != PORT_UNKNOWN && serinfo->type != PORT_EFMUART) | ||
| 499 | ret = -EINVAL; | ||
| 500 | |||
| 501 | return ret; | ||
| 502 | } | ||
| 503 | |||
| 504 | static struct uart_ops efm32_uart_pops = { | ||
| 505 | .tx_empty = efm32_uart_tx_empty, | ||
| 506 | .set_mctrl = efm32_uart_set_mctrl, | ||
| 507 | .get_mctrl = efm32_uart_get_mctrl, | ||
| 508 | .stop_tx = efm32_uart_stop_tx, | ||
| 509 | .start_tx = efm32_uart_start_tx, | ||
| 510 | .stop_rx = efm32_uart_stop_rx, | ||
| 511 | .enable_ms = efm32_uart_enable_ms, | ||
| 512 | .break_ctl = efm32_uart_break_ctl, | ||
| 513 | .startup = efm32_uart_startup, | ||
| 514 | .shutdown = efm32_uart_shutdown, | ||
| 515 | .set_termios = efm32_uart_set_termios, | ||
| 516 | .type = efm32_uart_type, | ||
| 517 | .release_port = efm32_uart_release_port, | ||
| 518 | .request_port = efm32_uart_request_port, | ||
| 519 | .config_port = efm32_uart_config_port, | ||
| 520 | .verify_port = efm32_uart_verify_port, | ||
| 521 | }; | ||
| 522 | |||
| 523 | static struct efm32_uart_port *efm32_uart_ports[5]; | ||
| 524 | |||
| 525 | #ifdef CONFIG_SERIAL_EFM32_UART_CONSOLE | ||
| 526 | static void efm32_uart_console_putchar(struct uart_port *port, int ch) | ||
| 527 | { | ||
| 528 | struct efm32_uart_port *efm_port = to_efm_port(port); | ||
| 529 | unsigned int timeout = 0x400; | ||
| 530 | u32 status; | ||
| 531 | |||
| 532 | while (1) { | ||
| 533 | status = efm32_uart_read32(efm_port, UARTn_STATUS); | ||
| 534 | |||
| 535 | if (status & UARTn_STATUS_TXBL) | ||
| 536 | break; | ||
| 537 | if (!timeout--) | ||
| 538 | return; | ||
| 539 | } | ||
| 540 | efm32_uart_write32(efm_port, ch, UARTn_TXDATA); | ||
| 541 | } | ||
| 542 | |||
| 543 | static void efm32_uart_console_write(struct console *co, const char *s, | ||
| 544 | unsigned int count) | ||
| 545 | { | ||
| 546 | struct efm32_uart_port *efm_port = efm32_uart_ports[co->index]; | ||
| 547 | u32 status = efm32_uart_read32(efm_port, UARTn_STATUS); | ||
| 548 | unsigned int timeout = 0x400; | ||
| 549 | |||
| 550 | if (!(status & UARTn_STATUS_TXENS)) | ||
| 551 | efm32_uart_write32(efm_port, UARTn_CMD_TXEN, UARTn_CMD); | ||
| 552 | |||
| 553 | uart_console_write(&efm_port->port, s, count, | ||
| 554 | efm32_uart_console_putchar); | ||
| 555 | |||
| 556 | /* Wait for the transmitter to become empty */ | ||
| 557 | while (1) { | ||
| 558 | u32 status = efm32_uart_read32(efm_port, UARTn_STATUS); | ||
| 559 | if (status & UARTn_STATUS_TXC) | ||
| 560 | break; | ||
| 561 | if (!timeout--) | ||
| 562 | break; | ||
| 563 | } | ||
| 564 | |||
| 565 | if (!(status & UARTn_STATUS_TXENS)) | ||
| 566 | efm32_uart_write32(efm_port, UARTn_CMD_TXDIS, UARTn_CMD); | ||
| 567 | } | ||
| 568 | |||
| 569 | static void efm32_uart_console_get_options(struct efm32_uart_port *efm_port, | ||
| 570 | int *baud, int *parity, int *bits) | ||
| 571 | { | ||
| 572 | u32 ctrl = efm32_uart_read32(efm_port, UARTn_CTRL); | ||
| 573 | u32 route, clkdiv, frame; | ||
| 574 | |||
| 575 | if (ctrl & UARTn_CTRL_SYNC) | ||
| 576 | /* not operating in async mode */ | ||
| 577 | return; | ||
| 578 | |||
| 579 | route = efm32_uart_read32(efm_port, UARTn_ROUTE); | ||
| 580 | if (!(route & UARTn_ROUTE_TXPEN)) | ||
| 581 | /* tx pin not routed */ | ||
| 582 | return; | ||
| 583 | |||
| 584 | clkdiv = efm32_uart_read32(efm_port, UARTn_CLKDIV); | ||
| 585 | |||
| 586 | *baud = DIV_ROUND_CLOSEST(4 * efm_port->port.uartclk, | ||
| 587 | 16 * (4 + (clkdiv >> 6))); | ||
| 588 | |||
| 589 | frame = efm32_uart_read32(efm_port, UARTn_FRAME); | ||
| 590 | if (frame & UARTn_FRAME_PARITY_ODD) | ||
| 591 | *parity = 'o'; | ||
| 592 | else if (frame & UARTn_FRAME_PARITY_EVEN) | ||
| 593 | *parity = 'e'; | ||
| 594 | else | ||
| 595 | *parity = 'n'; | ||
| 596 | |||
| 597 | *bits = (frame & UARTn_FRAME_DATABITS__MASK) - | ||
| 598 | UARTn_FRAME_DATABITS(4) + 4; | ||
| 599 | |||
| 600 | efm_debug(efm_port, "get_opts: options=%d%c%d\n", | ||
| 601 | *baud, *parity, *bits); | ||
| 602 | } | ||
| 603 | |||
| 604 | static int efm32_uart_console_setup(struct console *co, char *options) | ||
| 605 | { | ||
| 606 | struct efm32_uart_port *efm_port; | ||
| 607 | int baud = 115200; | ||
| 608 | int bits = 8; | ||
| 609 | int parity = 'n'; | ||
| 610 | int flow = 'n'; | ||
| 611 | int ret; | ||
| 612 | |||
| 613 | if (co->index < 0 || co->index >= ARRAY_SIZE(efm32_uart_ports)) { | ||
| 614 | unsigned i; | ||
| 615 | for (i = 0; i < ARRAY_SIZE(efm32_uart_ports); ++i) { | ||
| 616 | if (efm32_uart_ports[i]) { | ||
| 617 | pr_warn("efm32-console: fall back to console index %u (from %hhi)\n", | ||
| 618 | i, co->index); | ||
| 619 | co->index = i; | ||
| 620 | break; | ||
| 621 | } | ||
| 622 | } | ||
| 623 | } | ||
| 624 | |||
| 625 | efm_port = efm32_uart_ports[co->index]; | ||
| 626 | if (!efm_port) { | ||
| 627 | pr_warn("efm32-console: No port at %d\n", co->index); | ||
| 628 | return -ENODEV; | ||
| 629 | } | ||
| 630 | |||
| 631 | ret = clk_prepare(efm_port->clk); | ||
| 632 | if (ret) { | ||
| 633 | dev_warn(efm_port->port.dev, | ||
| 634 | "console: clk_prepare failed: %d\n", ret); | ||
| 635 | return ret; | ||
| 636 | } | ||
| 637 | |||
| 638 | efm_port->port.uartclk = clk_get_rate(efm_port->clk); | ||
| 639 | |||
| 640 | if (options) | ||
| 641 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
| 642 | else | ||
| 643 | efm32_uart_console_get_options(efm_port, | ||
| 644 | &baud, &parity, &bits); | ||
| 645 | |||
| 646 | return uart_set_options(&efm_port->port, co, baud, parity, bits, flow); | ||
| 647 | } | ||
| 648 | |||
| 649 | static struct uart_driver efm32_uart_reg; | ||
| 650 | |||
| 651 | static struct console efm32_uart_console = { | ||
| 652 | .name = DEV_NAME, | ||
| 653 | .write = efm32_uart_console_write, | ||
| 654 | .device = uart_console_device, | ||
| 655 | .setup = efm32_uart_console_setup, | ||
| 656 | .flags = CON_PRINTBUFFER, | ||
| 657 | .index = -1, | ||
| 658 | .data = &efm32_uart_reg, | ||
| 659 | }; | ||
| 660 | |||
| 661 | #else | ||
| 662 | #define efm32_uart_console (*(struct console *)NULL) | ||
| 663 | #endif /* ifdef CONFIG_SERIAL_EFM32_UART_CONSOLE / else */ | ||
| 664 | |||
| 665 | static struct uart_driver efm32_uart_reg = { | ||
| 666 | .owner = THIS_MODULE, | ||
| 667 | .driver_name = DRIVER_NAME, | ||
| 668 | .dev_name = DEV_NAME, | ||
| 669 | .nr = ARRAY_SIZE(efm32_uart_ports), | ||
| 670 | .cons = &efm32_uart_console, | ||
| 671 | }; | ||
| 672 | |||
| 673 | static int efm32_uart_probe_dt(struct platform_device *pdev, | ||
| 674 | struct efm32_uart_port *efm_port) | ||
| 675 | { | ||
| 676 | struct device_node *np = pdev->dev.of_node; | ||
| 677 | int ret; | ||
| 678 | |||
| 679 | if (!np) | ||
| 680 | return 1; | ||
| 681 | |||
| 682 | ret = of_alias_get_id(np, "serial"); | ||
| 683 | if (ret < 0) { | ||
| 684 | dev_err(&pdev->dev, "failed to get alias id: %d\n", ret); | ||
| 685 | return ret; | ||
| 686 | } else { | ||
| 687 | efm_port->port.line = ret; | ||
| 688 | return 0; | ||
| 689 | } | ||
| 690 | |||
| 691 | } | ||
| 692 | |||
| 693 | static int __devinit efm32_uart_probe(struct platform_device *pdev) | ||
| 694 | { | ||
| 695 | struct efm32_uart_port *efm_port; | ||
| 696 | struct resource *res; | ||
| 697 | int ret; | ||
| 698 | |||
| 699 | efm_port = kzalloc(sizeof(*efm_port), GFP_KERNEL); | ||
| 700 | if (!efm_port) { | ||
| 701 | dev_dbg(&pdev->dev, "failed to allocate private data\n"); | ||
| 702 | return -ENOMEM; | ||
| 703 | } | ||
| 704 | |||
| 705 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 706 | if (!res) { | ||
| 707 | ret = -ENODEV; | ||
| 708 | dev_dbg(&pdev->dev, "failed to determine base address\n"); | ||
| 709 | goto err_get_base; | ||
| 710 | } | ||
| 711 | |||
| 712 | if (resource_size(res) < 60) { | ||
| 713 | ret = -EINVAL; | ||
| 714 | dev_dbg(&pdev->dev, "memory resource too small\n"); | ||
| 715 | goto err_too_small; | ||
| 716 | } | ||
| 717 | |||
| 718 | ret = platform_get_irq(pdev, 0); | ||
| 719 | if (ret <= 0) { | ||
| 720 | dev_dbg(&pdev->dev, "failed to get rx irq\n"); | ||
| 721 | goto err_get_rxirq; | ||
| 722 | } | ||
| 723 | |||
| 724 | efm_port->port.irq = ret; | ||
| 725 | |||
| 726 | ret = platform_get_irq(pdev, 1); | ||
| 727 | if (ret <= 0) | ||
| 728 | ret = efm_port->port.irq + 1; | ||
| 729 | |||
| 730 | efm_port->txirq = ret; | ||
| 731 | |||
| 732 | efm_port->port.dev = &pdev->dev; | ||
| 733 | efm_port->port.mapbase = res->start; | ||
| 734 | efm_port->port.type = PORT_EFMUART; | ||
| 735 | efm_port->port.iotype = UPIO_MEM32; | ||
| 736 | efm_port->port.fifosize = 2; | ||
| 737 | efm_port->port.ops = &efm32_uart_pops; | ||
| 738 | efm_port->port.flags = UPF_BOOT_AUTOCONF; | ||
| 739 | |||
| 740 | ret = efm32_uart_probe_dt(pdev, efm_port); | ||
| 741 | if (ret > 0) | ||
| 742 | /* not created by device tree */ | ||
| 743 | efm_port->port.line = pdev->id; | ||
| 744 | |||
| 745 | if (efm_port->port.line >= 0 && | ||
| 746 | efm_port->port.line < ARRAY_SIZE(efm32_uart_ports)) | ||
| 747 | efm32_uart_ports[efm_port->port.line] = efm_port; | ||
| 748 | |||
| 749 | ret = uart_add_one_port(&efm32_uart_reg, &efm_port->port); | ||
| 750 | if (ret) { | ||
| 751 | dev_dbg(&pdev->dev, "failed to add port: %d\n", ret); | ||
| 752 | |||
| 753 | if (pdev->id >= 0 && pdev->id < ARRAY_SIZE(efm32_uart_ports)) | ||
| 754 | efm32_uart_ports[pdev->id] = NULL; | ||
| 755 | err_get_rxirq: | ||
| 756 | err_too_small: | ||
| 757 | err_get_base: | ||
| 758 | kfree(efm_port); | ||
| 759 | } else { | ||
| 760 | platform_set_drvdata(pdev, efm_port); | ||
| 761 | dev_dbg(&pdev->dev, "\\o/\n"); | ||
| 762 | } | ||
| 763 | |||
| 764 | return ret; | ||
| 765 | } | ||
| 766 | |||
| 767 | static int __devexit efm32_uart_remove(struct platform_device *pdev) | ||
| 768 | { | ||
| 769 | struct efm32_uart_port *efm_port = platform_get_drvdata(pdev); | ||
| 770 | |||
| 771 | platform_set_drvdata(pdev, NULL); | ||
| 772 | |||
| 773 | uart_remove_one_port(&efm32_uart_reg, &efm_port->port); | ||
| 774 | |||
| 775 | if (pdev->id >= 0 && pdev->id < ARRAY_SIZE(efm32_uart_ports)) | ||
| 776 | efm32_uart_ports[pdev->id] = NULL; | ||
| 777 | |||
| 778 | kfree(efm_port); | ||
| 779 | |||
| 780 | return 0; | ||
| 781 | } | ||
| 782 | |||
| 783 | static struct of_device_id efm32_uart_dt_ids[] = { | ||
| 784 | { | ||
| 785 | .compatible = "efm32,uart", | ||
| 786 | }, { | ||
| 787 | /* sentinel */ | ||
| 788 | } | ||
| 789 | }; | ||
| 790 | MODULE_DEVICE_TABLE(of, efm32_uart_dt_ids); | ||
| 791 | |||
| 792 | static struct platform_driver efm32_uart_driver = { | ||
| 793 | .probe = efm32_uart_probe, | ||
| 794 | .remove = __devexit_p(efm32_uart_remove), | ||
| 795 | |||
| 796 | .driver = { | ||
| 797 | .name = DRIVER_NAME, | ||
| 798 | .owner = THIS_MODULE, | ||
| 799 | .of_match_table = efm32_uart_dt_ids, | ||
| 800 | }, | ||
| 801 | }; | ||
| 802 | |||
| 803 | static int __init efm32_uart_init(void) | ||
| 804 | { | ||
| 805 | int ret; | ||
| 806 | |||
| 807 | ret = uart_register_driver(&efm32_uart_reg); | ||
| 808 | if (ret) | ||
| 809 | return ret; | ||
| 810 | |||
| 811 | ret = platform_driver_register(&efm32_uart_driver); | ||
| 812 | if (ret) | ||
| 813 | uart_unregister_driver(&efm32_uart_reg); | ||
| 814 | |||
| 815 | pr_info("EFM32 UART/USART driver\n"); | ||
| 816 | |||
| 817 | return ret; | ||
| 818 | } | ||
| 819 | module_init(efm32_uart_init); | ||
| 820 | |||
| 821 | static void __exit efm32_uart_exit(void) | ||
| 822 | { | ||
| 823 | platform_driver_unregister(&efm32_uart_driver); | ||
| 824 | uart_unregister_driver(&efm32_uart_reg); | ||
| 825 | } | ||
| 826 | |||
| 827 | MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>"); | ||
| 828 | MODULE_DESCRIPTION("EFM32 UART/USART driver"); | ||
| 829 | MODULE_LICENSE("GPL v2"); | ||
| 830 | MODULE_ALIAS("platform:" DRIVER_NAME); | ||
diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 7e925e20cbaa..144cd3987d4c 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c | |||
| @@ -1375,12 +1375,9 @@ static int __init ifx_spi_init(void) | |||
| 1375 | return -ENOMEM; | 1375 | return -ENOMEM; |
| 1376 | } | 1376 | } |
| 1377 | 1377 | ||
| 1378 | tty_drv->magic = TTY_DRIVER_MAGIC; | ||
| 1379 | tty_drv->owner = THIS_MODULE; | ||
| 1380 | tty_drv->driver_name = DRVNAME; | 1378 | tty_drv->driver_name = DRVNAME; |
| 1381 | tty_drv->name = TTYNAME; | 1379 | tty_drv->name = TTYNAME; |
| 1382 | tty_drv->minor_start = IFX_SPI_TTY_ID; | 1380 | tty_drv->minor_start = IFX_SPI_TTY_ID; |
| 1383 | tty_drv->num = 1; | ||
| 1384 | tty_drv->type = TTY_DRIVER_TYPE_SERIAL; | 1381 | tty_drv->type = TTY_DRIVER_TYPE_SERIAL; |
| 1385 | tty_drv->subtype = SERIAL_TYPE_NORMAL; | 1382 | tty_drv->subtype = SERIAL_TYPE_NORMAL; |
| 1386 | tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | 1383 | tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
diff --git a/drivers/tty/serial/ioc4_serial.c b/drivers/tty/serial/ioc4_serial.c index 6b36c1554d7e..e16894fb2ca3 100644 --- a/drivers/tty/serial/ioc4_serial.c +++ b/drivers/tty/serial/ioc4_serial.c | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | #include <linux/tty.h> | 16 | #include <linux/tty.h> |
| 17 | #include <linux/tty_flip.h> | 17 | #include <linux/tty_flip.h> |
| 18 | #include <linux/serial.h> | 18 | #include <linux/serial.h> |
| 19 | #include <linux/serialP.h> | ||
| 20 | #include <linux/circ_buf.h> | 19 | #include <linux/circ_buf.h> |
| 21 | #include <linux/serial_reg.h> | 20 | #include <linux/serial_reg.h> |
| 22 | #include <linux/module.h> | 21 | #include <linux/module.h> |
| @@ -975,7 +974,7 @@ intr_connect(struct ioc4_soft *soft, int type, | |||
| 975 | BUG_ON(!((type == IOC4_SIO_INTR_TYPE) | 974 | BUG_ON(!((type == IOC4_SIO_INTR_TYPE) |
| 976 | || (type == IOC4_OTHER_INTR_TYPE))); | 975 | || (type == IOC4_OTHER_INTR_TYPE))); |
| 977 | 976 | ||
| 978 | i = atomic_inc(&soft-> is_intr_type[type].is_num_intrs) - 1; | 977 | i = atomic_inc_return(&soft-> is_intr_type[type].is_num_intrs) - 1; |
| 979 | BUG_ON(!(i < MAX_IOC4_INTR_ENTS || (printk("i %d\n", i), 0))); | 978 | BUG_ON(!(i < MAX_IOC4_INTR_ENTS || (printk("i %d\n", i), 0))); |
| 980 | 979 | ||
| 981 | /* Save off the lower level interrupt handler */ | 980 | /* Save off the lower level interrupt handler */ |
diff --git a/drivers/tty/serial/m32r_sio.c b/drivers/tty/serial/m32r_sio.c index 94a6792bf97b..a0703624d5e5 100644 --- a/drivers/tty/serial/m32r_sio.c +++ b/drivers/tty/serial/m32r_sio.c | |||
| @@ -38,7 +38,6 @@ | |||
| 38 | #include <linux/console.h> | 38 | #include <linux/console.h> |
| 39 | #include <linux/sysrq.h> | 39 | #include <linux/sysrq.h> |
| 40 | #include <linux/serial.h> | 40 | #include <linux/serial.h> |
| 41 | #include <linux/serialP.h> | ||
| 42 | #include <linux/delay.h> | 41 | #include <linux/delay.h> |
| 43 | 42 | ||
| 44 | #include <asm/m32r.h> | 43 | #include <asm/m32r.h> |
| @@ -70,13 +69,6 @@ | |||
| 70 | 69 | ||
| 71 | #define PASS_LIMIT 256 | 70 | #define PASS_LIMIT 256 |
| 72 | 71 | ||
| 73 | /* | ||
| 74 | * We default to IRQ0 for the "no irq" hack. Some | ||
| 75 | * machine types want others as well - they're free | ||
| 76 | * to redefine this in their header file. | ||
| 77 | */ | ||
| 78 | #define is_real_interrupt(irq) ((irq) != 0) | ||
| 79 | |||
| 80 | #define BASE_BAUD 115200 | 72 | #define BASE_BAUD 115200 |
| 81 | 73 | ||
| 82 | /* Standard COM flags */ | 74 | /* Standard COM flags */ |
| @@ -640,7 +632,7 @@ static int m32r_sio_startup(struct uart_port *port) | |||
| 640 | * hardware interrupt, we use a timer-based system. The original | 632 | * hardware interrupt, we use a timer-based system. The original |
| 641 | * driver used to do this with IRQ0. | 633 | * driver used to do this with IRQ0. |
| 642 | */ | 634 | */ |
| 643 | if (!is_real_interrupt(up->port.irq)) { | 635 | if (!up->port.irq) { |
| 644 | unsigned int timeout = up->port.timeout; | 636 | unsigned int timeout = up->port.timeout; |
| 645 | 637 | ||
| 646 | timeout = timeout > 6 ? (timeout / 2 - 2) : 1; | 638 | timeout = timeout > 6 ? (timeout / 2 - 2) : 1; |
| @@ -687,7 +679,7 @@ static void m32r_sio_shutdown(struct uart_port *port) | |||
| 687 | 679 | ||
| 688 | sio_init(); | 680 | sio_init(); |
| 689 | 681 | ||
| 690 | if (!is_real_interrupt(up->port.irq)) | 682 | if (!up->port.irq) |
| 691 | del_timer_sync(&up->timer); | 683 | del_timer_sync(&up->timer); |
| 692 | else | 684 | else |
| 693 | serial_unlink_irq_chain(up); | 685 | serial_unlink_irq_chain(up); |
diff --git a/drivers/tty/serial/m32r_sio.h b/drivers/tty/serial/m32r_sio.h index e9b7e11793b1..8129824496c6 100644 --- a/drivers/tty/serial/m32r_sio.h +++ b/drivers/tty/serial/m32r_sio.h | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | * (at your option) any later version. | 15 | * (at your option) any later version. |
| 16 | */ | 16 | */ |
| 17 | 17 | ||
| 18 | #include <linux/pci.h> | ||
| 18 | 19 | ||
| 19 | struct m32r_sio_probe { | 20 | struct m32r_sio_probe { |
| 20 | struct module *owner; | 21 | struct module *owner; |
diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index 1093a88a1fe3..bedac0d4c9ce 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c | |||
| @@ -262,8 +262,9 @@ static unsigned int mpc5200b_psc_set_baudrate(struct uart_port *port, | |||
| 262 | port->uartclk / 4); | 262 | port->uartclk / 4); |
| 263 | divisor = (port->uartclk + 2 * baud) / (4 * baud); | 263 | divisor = (port->uartclk + 2 * baud) / (4 * baud); |
| 264 | 264 | ||
| 265 | /* select the proper prescaler and set the divisor */ | 265 | /* select the proper prescaler and set the divisor |
| 266 | if (divisor > 0xffff) { | 266 | * prefer high prescaler for more tolerance on low baudrates */ |
| 267 | if (divisor > 0xffff || baud <= 115200) { | ||
| 267 | divisor = (divisor + 4) / 8; | 268 | divisor = (divisor + 4) / 8; |
| 268 | prescaler = 0xdd00; /* /32 */ | 269 | prescaler = 0xdd00; /* /32 */ |
| 269 | } else | 270 | } else |
| @@ -507,7 +508,7 @@ static int __init mpc512x_psc_fifoc_init(void) | |||
| 507 | 508 | ||
| 508 | psc_fifoc_irq = irq_of_parse_and_map(np, 0); | 509 | psc_fifoc_irq = irq_of_parse_and_map(np, 0); |
| 509 | of_node_put(np); | 510 | of_node_put(np); |
| 510 | if (psc_fifoc_irq == NO_IRQ) { | 511 | if (psc_fifoc_irq == 0) { |
| 511 | pr_err("%s: Can't get FIFOC irq\n", __func__); | 512 | pr_err("%s: Can't get FIFOC irq\n", __func__); |
| 512 | iounmap(psc_fifoc); | 513 | iounmap(psc_fifoc); |
| 513 | return -ENODEV; | 514 | return -ENODEV; |
| @@ -1354,7 +1355,7 @@ static int __devinit mpc52xx_uart_of_probe(struct platform_device *op) | |||
| 1354 | } | 1355 | } |
| 1355 | 1356 | ||
| 1356 | psc_ops->get_irq(port, op->dev.of_node); | 1357 | psc_ops->get_irq(port, op->dev.of_node); |
| 1357 | if (port->irq == NO_IRQ) { | 1358 | if (port->irq == 0) { |
| 1358 | dev_dbg(&op->dev, "Could not get irq\n"); | 1359 | dev_dbg(&op->dev, "Could not get irq\n"); |
| 1359 | return -EINVAL; | 1360 | return -EINVAL; |
| 1360 | } | 1361 | } |
diff --git a/drivers/tty/serial/msm_smd_tty.c b/drivers/tty/serial/msm_smd_tty.c index 4f41dcdcb771..b25e6ee71443 100644 --- a/drivers/tty/serial/msm_smd_tty.c +++ b/drivers/tty/serial/msm_smd_tty.c | |||
| @@ -203,7 +203,6 @@ static int __init smd_tty_init(void) | |||
| 203 | if (smd_tty_driver == 0) | 203 | if (smd_tty_driver == 0) |
| 204 | return -ENOMEM; | 204 | return -ENOMEM; |
| 205 | 205 | ||
| 206 | smd_tty_driver->owner = THIS_MODULE; | ||
| 207 | smd_tty_driver->driver_name = "smd_tty_driver"; | 206 | smd_tty_driver->driver_name = "smd_tty_driver"; |
| 208 | smd_tty_driver->name = "smd"; | 207 | smd_tty_driver->name = "smd"; |
| 209 | smd_tty_driver->major = 0; | 208 | smd_tty_driver->major = 0; |
diff --git a/drivers/tty/serial/mux.c b/drivers/tty/serial/mux.c index 06f6aefd5ba6..7ea8a263fd9e 100644 --- a/drivers/tty/serial/mux.c +++ b/drivers/tty/serial/mux.c | |||
| @@ -17,7 +17,6 @@ | |||
| 17 | */ | 17 | */ |
| 18 | 18 | ||
| 19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
| 20 | #include <linux/tty.h> | ||
| 21 | #include <linux/ioport.h> | 20 | #include <linux/ioport.h> |
| 22 | #include <linux/init.h> | 21 | #include <linux/init.h> |
| 23 | #include <linux/serial.h> | 22 | #include <linux/serial.h> |
| @@ -499,7 +498,7 @@ static int __init mux_probe(struct parisc_device *dev) | |||
| 499 | port->membase = ioremap_nocache(port->mapbase, MUX_LINE_OFFSET); | 498 | port->membase = ioremap_nocache(port->mapbase, MUX_LINE_OFFSET); |
| 500 | port->iotype = UPIO_MEM; | 499 | port->iotype = UPIO_MEM; |
| 501 | port->type = PORT_MUX; | 500 | port->type = PORT_MUX; |
| 502 | port->irq = NO_IRQ; | 501 | port->irq = 0; |
| 503 | port->uartclk = 0; | 502 | port->uartclk = 0; |
| 504 | port->fifosize = MUX_FIFO_SIZE; | 503 | port->fifosize = MUX_FIFO_SIZE; |
| 505 | port->ops = &mux_pops; | 504 | port->ops = &mux_pops; |
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index f80904145fd4..0121486ac4fa 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c | |||
| @@ -159,7 +159,7 @@ static void serial_omap_stop_tx(struct uart_port *port) | |||
| 159 | serial_out(up, UART_IER, up->ier); | 159 | serial_out(up, UART_IER, up->ier); |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | if (!up->use_dma && pdata->set_forceidle) | 162 | if (!up->use_dma && pdata && pdata->set_forceidle) |
| 163 | pdata->set_forceidle(up->pdev); | 163 | pdata->set_forceidle(up->pdev); |
| 164 | 164 | ||
| 165 | pm_runtime_mark_last_busy(&up->pdev->dev); | 165 | pm_runtime_mark_last_busy(&up->pdev->dev); |
| @@ -298,7 +298,7 @@ static void serial_omap_start_tx(struct uart_port *port) | |||
| 298 | if (!up->use_dma) { | 298 | if (!up->use_dma) { |
| 299 | pm_runtime_get_sync(&up->pdev->dev); | 299 | pm_runtime_get_sync(&up->pdev->dev); |
| 300 | serial_omap_enable_ier_thri(up); | 300 | serial_omap_enable_ier_thri(up); |
| 301 | if (pdata->set_noidle) | 301 | if (pdata && pdata->set_noidle) |
| 302 | pdata->set_noidle(up->pdev); | 302 | pdata->set_noidle(up->pdev); |
| 303 | pm_runtime_mark_last_busy(&up->pdev->dev); | 303 | pm_runtime_mark_last_busy(&up->pdev->dev); |
| 304 | pm_runtime_put_autosuspend(&up->pdev->dev); | 304 | pm_runtime_put_autosuspend(&up->pdev->dev); |
| @@ -1613,7 +1613,7 @@ static int serial_omap_runtime_resume(struct device *dev) | |||
| 1613 | struct uart_omap_port *up = dev_get_drvdata(dev); | 1613 | struct uart_omap_port *up = dev_get_drvdata(dev); |
| 1614 | struct omap_uart_port_info *pdata = dev->platform_data; | 1614 | struct omap_uart_port_info *pdata = dev->platform_data; |
| 1615 | 1615 | ||
| 1616 | if (up) { | 1616 | if (up && pdata) { |
| 1617 | if (pdata->get_context_loss_count) { | 1617 | if (pdata->get_context_loss_count) { |
| 1618 | u32 loss_cnt = pdata->get_context_loss_count(dev); | 1618 | u32 loss_cnt = pdata->get_context_loss_count(dev); |
| 1619 | 1619 | ||
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 17ae65762d1a..332f2eb8abbc 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/nmi.h> | 29 | #include <linux/nmi.h> |
| 30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
| 31 | 31 | ||
| 32 | #include <linux/debugfs.h> | ||
| 32 | #include <linux/dmaengine.h> | 33 | #include <linux/dmaengine.h> |
| 33 | #include <linux/pch_dma.h> | 34 | #include <linux/pch_dma.h> |
| 34 | 35 | ||
| @@ -144,6 +145,8 @@ enum { | |||
| 144 | #define PCH_UART_DLL 0x00 | 145 | #define PCH_UART_DLL 0x00 |
| 145 | #define PCH_UART_DLM 0x01 | 146 | #define PCH_UART_DLM 0x01 |
| 146 | 147 | ||
| 148 | #define PCH_UART_BRCSR 0x0E | ||
| 149 | |||
| 147 | #define PCH_UART_IID_RLS (PCH_UART_IIR_REI) | 150 | #define PCH_UART_IID_RLS (PCH_UART_IIR_REI) |
| 148 | #define PCH_UART_IID_RDR (PCH_UART_IIR_RRI) | 151 | #define PCH_UART_IID_RDR (PCH_UART_IIR_RRI) |
| 149 | #define PCH_UART_IID_RDR_TO (PCH_UART_IIR_RRI | PCH_UART_IIR_TOI) | 152 | #define PCH_UART_IID_RDR_TO (PCH_UART_IIR_RRI | PCH_UART_IIR_TOI) |
| @@ -203,7 +206,10 @@ enum { | |||
| 203 | 206 | ||
| 204 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) | 207 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) |
| 205 | 208 | ||
| 206 | #define DEFAULT_BAUD_RATE 1843200 /* 1.8432MHz */ | 209 | #define DEFAULT_UARTCLK 1843200 /* 1.8432 MHz */ |
| 210 | #define CMITC_UARTCLK 192000000 /* 192.0000 MHz */ | ||
| 211 | #define FRI2_64_UARTCLK 64000000 /* 64.0000 MHz */ | ||
| 212 | #define FRI2_48_UARTCLK 48000000 /* 48.0000 MHz */ | ||
| 207 | 213 | ||
| 208 | struct pch_uart_buffer { | 214 | struct pch_uart_buffer { |
| 209 | unsigned char *buf; | 215 | unsigned char *buf; |
| @@ -218,7 +224,7 @@ struct eg20t_port { | |||
| 218 | unsigned int iobase; | 224 | unsigned int iobase; |
| 219 | struct pci_dev *pdev; | 225 | struct pci_dev *pdev; |
| 220 | int fifo_size; | 226 | int fifo_size; |
| 221 | int base_baud; | 227 | int uartclk; |
| 222 | int start_tx; | 228 | int start_tx; |
| 223 | int start_rx; | 229 | int start_rx; |
| 224 | int tx_empty; | 230 | int tx_empty; |
| @@ -243,6 +249,8 @@ struct eg20t_port { | |||
| 243 | int tx_dma_use; | 249 | int tx_dma_use; |
| 244 | void *rx_buf_virt; | 250 | void *rx_buf_virt; |
| 245 | dma_addr_t rx_buf_dma; | 251 | dma_addr_t rx_buf_dma; |
| 252 | |||
| 253 | struct dentry *debugfs; | ||
| 246 | }; | 254 | }; |
| 247 | 255 | ||
| 248 | /** | 256 | /** |
| @@ -287,26 +295,100 @@ static struct pch_uart_driver_data drv_dat[] = { | |||
| 287 | static struct eg20t_port *pch_uart_ports[PCH_UART_NR]; | 295 | static struct eg20t_port *pch_uart_ports[PCH_UART_NR]; |
| 288 | #endif | 296 | #endif |
| 289 | static unsigned int default_baud = 9600; | 297 | static unsigned int default_baud = 9600; |
| 298 | static unsigned int user_uartclk = 0; | ||
| 290 | static const int trigger_level_256[4] = { 1, 64, 128, 224 }; | 299 | static const int trigger_level_256[4] = { 1, 64, 128, 224 }; |
| 291 | static const int trigger_level_64[4] = { 1, 16, 32, 56 }; | 300 | static const int trigger_level_64[4] = { 1, 16, 32, 56 }; |
| 292 | static const int trigger_level_16[4] = { 1, 4, 8, 14 }; | 301 | static const int trigger_level_16[4] = { 1, 4, 8, 14 }; |
| 293 | static const int trigger_level_1[4] = { 1, 1, 1, 1 }; | 302 | static const int trigger_level_1[4] = { 1, 1, 1, 1 }; |
| 294 | 303 | ||
| 295 | static void pch_uart_hal_request(struct pci_dev *pdev, int fifosize, | 304 | #ifdef CONFIG_DEBUG_FS |
| 296 | int base_baud) | 305 | |
| 306 | #define PCH_REGS_BUFSIZE 1024 | ||
| 307 | static int pch_show_regs_open(struct inode *inode, struct file *file) | ||
| 297 | { | 308 | { |
| 298 | struct eg20t_port *priv = pci_get_drvdata(pdev); | 309 | file->private_data = inode->i_private; |
| 310 | return 0; | ||
| 311 | } | ||
| 299 | 312 | ||
| 300 | priv->trigger_level = 1; | 313 | static ssize_t port_show_regs(struct file *file, char __user *user_buf, |
| 301 | priv->fcr = 0; | 314 | size_t count, loff_t *ppos) |
| 315 | { | ||
| 316 | struct eg20t_port *priv = file->private_data; | ||
| 317 | char *buf; | ||
| 318 | u32 len = 0; | ||
| 319 | ssize_t ret; | ||
| 320 | unsigned char lcr; | ||
| 321 | |||
| 322 | buf = kzalloc(PCH_REGS_BUFSIZE, GFP_KERNEL); | ||
| 323 | if (!buf) | ||
| 324 | return 0; | ||
| 325 | |||
| 326 | len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, | ||
| 327 | "PCH EG20T port[%d] regs:\n", priv->port.line); | ||
| 328 | |||
| 329 | len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, | ||
| 330 | "=================================\n"); | ||
| 331 | len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, | ||
| 332 | "IER: \t0x%02x\n", ioread8(priv->membase + UART_IER)); | ||
| 333 | len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, | ||
| 334 | "IIR: \t0x%02x\n", ioread8(priv->membase + UART_IIR)); | ||
| 335 | len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, | ||
| 336 | "LCR: \t0x%02x\n", ioread8(priv->membase + UART_LCR)); | ||
| 337 | len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, | ||
| 338 | "MCR: \t0x%02x\n", ioread8(priv->membase + UART_MCR)); | ||
| 339 | len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, | ||
| 340 | "LSR: \t0x%02x\n", ioread8(priv->membase + UART_LSR)); | ||
| 341 | len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, | ||
| 342 | "MSR: \t0x%02x\n", ioread8(priv->membase + UART_MSR)); | ||
| 343 | len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, | ||
| 344 | "BRCSR: \t0x%02x\n", | ||
| 345 | ioread8(priv->membase + PCH_UART_BRCSR)); | ||
| 346 | |||
| 347 | lcr = ioread8(priv->membase + UART_LCR); | ||
| 348 | iowrite8(PCH_UART_LCR_DLAB, priv->membase + UART_LCR); | ||
| 349 | len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, | ||
| 350 | "DLL: \t0x%02x\n", ioread8(priv->membase + UART_DLL)); | ||
| 351 | len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, | ||
| 352 | "DLM: \t0x%02x\n", ioread8(priv->membase + UART_DLM)); | ||
| 353 | iowrite8(lcr, priv->membase + UART_LCR); | ||
| 354 | |||
| 355 | if (len > PCH_REGS_BUFSIZE) | ||
| 356 | len = PCH_REGS_BUFSIZE; | ||
| 357 | |||
| 358 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
| 359 | kfree(buf); | ||
| 360 | return ret; | ||
| 302 | } | 361 | } |
| 303 | 362 | ||
| 304 | static unsigned int get_msr(struct eg20t_port *priv, void __iomem *base) | 363 | static const struct file_operations port_regs_ops = { |
| 364 | .owner = THIS_MODULE, | ||
| 365 | .open = pch_show_regs_open, | ||
| 366 | .read = port_show_regs, | ||
| 367 | .llseek = default_llseek, | ||
| 368 | }; | ||
| 369 | #endif /* CONFIG_DEBUG_FS */ | ||
| 370 | |||
| 371 | /* Return UART clock, checking for board specific clocks. */ | ||
| 372 | static int pch_uart_get_uartclk(void) | ||
| 305 | { | 373 | { |
| 306 | unsigned int msr = ioread8(base + UART_MSR); | 374 | const char *cmp; |
| 307 | priv->dmsr |= msr & PCH_UART_MSR_DELTA; | 375 | |
| 376 | if (user_uartclk) | ||
| 377 | return user_uartclk; | ||
| 378 | |||
| 379 | cmp = dmi_get_system_info(DMI_BOARD_NAME); | ||
| 380 | if (cmp && strstr(cmp, "CM-iTC")) | ||
| 381 | return CMITC_UARTCLK; | ||
| 382 | |||
| 383 | cmp = dmi_get_system_info(DMI_BIOS_VERSION); | ||
| 384 | if (cmp && strnstr(cmp, "FRI2", 4)) | ||
| 385 | return FRI2_64_UARTCLK; | ||
| 386 | |||
| 387 | cmp = dmi_get_system_info(DMI_PRODUCT_NAME); | ||
| 388 | if (cmp && strstr(cmp, "Fish River Island II")) | ||
| 389 | return FRI2_48_UARTCLK; | ||
| 308 | 390 | ||
| 309 | return msr; | 391 | return DEFAULT_UARTCLK; |
| 310 | } | 392 | } |
| 311 | 393 | ||
| 312 | static void pch_uart_hal_enable_interrupt(struct eg20t_port *priv, | 394 | static void pch_uart_hal_enable_interrupt(struct eg20t_port *priv, |
| @@ -332,7 +414,7 @@ static int pch_uart_hal_set_line(struct eg20t_port *priv, int baud, | |||
| 332 | unsigned int dll, dlm, lcr; | 414 | unsigned int dll, dlm, lcr; |
| 333 | int div; | 415 | int div; |
| 334 | 416 | ||
| 335 | div = DIV_ROUND_CLOSEST(priv->base_baud / 16, baud); | 417 | div = DIV_ROUND_CLOSEST(priv->uartclk / 16, baud); |
| 336 | if (div < 0 || USHRT_MAX <= div) { | 418 | if (div < 0 || USHRT_MAX <= div) { |
| 337 | dev_err(priv->port.dev, "Invalid Baud(div=0x%x)\n", div); | 419 | dev_err(priv->port.dev, "Invalid Baud(div=0x%x)\n", div); |
| 338 | return -EINVAL; | 420 | return -EINVAL; |
| @@ -442,8 +524,9 @@ static int pch_uart_hal_set_fifo(struct eg20t_port *priv, | |||
| 442 | 524 | ||
| 443 | static u8 pch_uart_hal_get_modem(struct eg20t_port *priv) | 525 | static u8 pch_uart_hal_get_modem(struct eg20t_port *priv) |
| 444 | { | 526 | { |
| 445 | priv->dmsr = 0; | 527 | unsigned int msr = ioread8(priv->membase + UART_MSR); |
| 446 | return get_msr(priv, priv->membase); | 528 | priv->dmsr = msr & PCH_UART_MSR_DELTA; |
| 529 | return (u8)msr; | ||
| 447 | } | 530 | } |
| 448 | 531 | ||
| 449 | static void pch_uart_hal_write(struct eg20t_port *priv, | 532 | static void pch_uart_hal_write(struct eg20t_port *priv, |
| @@ -524,7 +607,7 @@ static int push_rx(struct eg20t_port *priv, const unsigned char *buf, | |||
| 524 | 607 | ||
| 525 | static int pop_tx_x(struct eg20t_port *priv, unsigned char *buf) | 608 | static int pop_tx_x(struct eg20t_port *priv, unsigned char *buf) |
| 526 | { | 609 | { |
| 527 | int ret; | 610 | int ret = 0; |
| 528 | struct uart_port *port = &priv->port; | 611 | struct uart_port *port = &priv->port; |
| 529 | 612 | ||
| 530 | if (port->x_char) { | 613 | if (port->x_char) { |
| @@ -533,8 +616,6 @@ static int pop_tx_x(struct eg20t_port *priv, unsigned char *buf) | |||
| 533 | buf[0] = port->x_char; | 616 | buf[0] = port->x_char; |
| 534 | port->x_char = 0; | 617 | port->x_char = 0; |
| 535 | ret = 1; | 618 | ret = 1; |
| 536 | } else { | ||
| 537 | ret = 0; | ||
| 538 | } | 619 | } |
| 539 | 620 | ||
| 540 | return ret; | 621 | return ret; |
| @@ -1032,14 +1113,12 @@ static irqreturn_t pch_uart_interrupt(int irq, void *dev_id) | |||
| 1032 | static unsigned int pch_uart_tx_empty(struct uart_port *port) | 1113 | static unsigned int pch_uart_tx_empty(struct uart_port *port) |
| 1033 | { | 1114 | { |
| 1034 | struct eg20t_port *priv; | 1115 | struct eg20t_port *priv; |
| 1035 | int ret; | 1116 | |
| 1036 | priv = container_of(port, struct eg20t_port, port); | 1117 | priv = container_of(port, struct eg20t_port, port); |
| 1037 | if (priv->tx_empty) | 1118 | if (priv->tx_empty) |
| 1038 | ret = TIOCSER_TEMT; | 1119 | return TIOCSER_TEMT; |
| 1039 | else | 1120 | else |
| 1040 | ret = 0; | 1121 | return 0; |
| 1041 | |||
| 1042 | return ret; | ||
| 1043 | } | 1122 | } |
| 1044 | 1123 | ||
| 1045 | /* Returns the current state of modem control inputs. */ | 1124 | /* Returns the current state of modem control inputs. */ |
| @@ -1153,9 +1232,9 @@ static int pch_uart_startup(struct uart_port *port) | |||
| 1153 | priv->tx_empty = 1; | 1232 | priv->tx_empty = 1; |
| 1154 | 1233 | ||
| 1155 | if (port->uartclk) | 1234 | if (port->uartclk) |
| 1156 | priv->base_baud = port->uartclk; | 1235 | priv->uartclk = port->uartclk; |
| 1157 | else | 1236 | else |
| 1158 | port->uartclk = priv->base_baud; | 1237 | port->uartclk = priv->uartclk; |
| 1159 | 1238 | ||
| 1160 | pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_ALL_INT); | 1239 | pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_ALL_INT); |
| 1161 | ret = pch_uart_hal_set_line(priv, default_baud, | 1240 | ret = pch_uart_hal_set_line(priv, default_baud, |
| @@ -1273,9 +1352,8 @@ static void pch_uart_set_termios(struct uart_port *port, | |||
| 1273 | else | 1352 | else |
| 1274 | parity = PCH_UART_HAL_PARITY_EVEN; | 1353 | parity = PCH_UART_HAL_PARITY_EVEN; |
| 1275 | 1354 | ||
| 1276 | } else { | 1355 | } else |
| 1277 | parity = PCH_UART_HAL_PARITY_NONE; | 1356 | parity = PCH_UART_HAL_PARITY_NONE; |
| 1278 | } | ||
| 1279 | 1357 | ||
| 1280 | /* Only UART0 has auto hardware flow function */ | 1358 | /* Only UART0 has auto hardware flow function */ |
| 1281 | if ((termios->c_cflag & CRTSCTS) && (priv->fifo_size == 256)) | 1359 | if ((termios->c_cflag & CRTSCTS) && (priv->fifo_size == 256)) |
| @@ -1447,7 +1525,6 @@ static void | |||
| 1447 | pch_console_write(struct console *co, const char *s, unsigned int count) | 1525 | pch_console_write(struct console *co, const char *s, unsigned int count) |
| 1448 | { | 1526 | { |
| 1449 | struct eg20t_port *priv; | 1527 | struct eg20t_port *priv; |
| 1450 | |||
| 1451 | unsigned long flags; | 1528 | unsigned long flags; |
| 1452 | u8 ier; | 1529 | u8 ier; |
| 1453 | int locked = 1; | 1530 | int locked = 1; |
| @@ -1489,7 +1566,7 @@ pch_console_write(struct console *co, const char *s, unsigned int count) | |||
| 1489 | static int __init pch_console_setup(struct console *co, char *options) | 1566 | static int __init pch_console_setup(struct console *co, char *options) |
| 1490 | { | 1567 | { |
| 1491 | struct uart_port *port; | 1568 | struct uart_port *port; |
| 1492 | int baud = 9600; | 1569 | int baud = default_baud; |
| 1493 | int bits = 8; | 1570 | int bits = 8; |
| 1494 | int parity = 'n'; | 1571 | int parity = 'n'; |
| 1495 | int flow = 'n'; | 1572 | int flow = 'n'; |
| @@ -1506,8 +1583,7 @@ static int __init pch_console_setup(struct console *co, char *options) | |||
| 1506 | if (!port || (!port->iobase && !port->membase)) | 1583 | if (!port || (!port->iobase && !port->membase)) |
| 1507 | return -ENODEV; | 1584 | return -ENODEV; |
| 1508 | 1585 | ||
| 1509 | /* setup uartclock */ | 1586 | port->uartclk = pch_uart_get_uartclk(); |
| 1510 | port->uartclk = DEFAULT_BAUD_RATE; | ||
| 1511 | 1587 | ||
| 1512 | if (options) | 1588 | if (options) |
| 1513 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 1589 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
| @@ -1550,10 +1626,10 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, | |||
| 1550 | unsigned int iobase; | 1626 | unsigned int iobase; |
| 1551 | unsigned int mapbase; | 1627 | unsigned int mapbase; |
| 1552 | unsigned char *rxbuf; | 1628 | unsigned char *rxbuf; |
| 1553 | int fifosize, base_baud; | 1629 | int fifosize; |
| 1554 | int port_type; | 1630 | int port_type; |
| 1555 | struct pch_uart_driver_data *board; | 1631 | struct pch_uart_driver_data *board; |
| 1556 | const char *board_name; | 1632 | char name[32]; /* for debugfs file name */ |
| 1557 | 1633 | ||
| 1558 | board = &drv_dat[id->driver_data]; | 1634 | board = &drv_dat[id->driver_data]; |
| 1559 | port_type = board->port_type; | 1635 | port_type = board->port_type; |
| @@ -1566,13 +1642,6 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, | |||
| 1566 | if (!rxbuf) | 1642 | if (!rxbuf) |
| 1567 | goto init_port_free_txbuf; | 1643 | goto init_port_free_txbuf; |
| 1568 | 1644 | ||
| 1569 | base_baud = DEFAULT_BAUD_RATE; | ||
| 1570 | |||
| 1571 | /* quirk for CM-iTC board */ | ||
| 1572 | board_name = dmi_get_system_info(DMI_BOARD_NAME); | ||
| 1573 | if (board_name && strstr(board_name, "CM-iTC")) | ||
| 1574 | base_baud = 192000000; /* 192.0MHz */ | ||
| 1575 | |||
| 1576 | switch (port_type) { | 1645 | switch (port_type) { |
| 1577 | case PORT_UNKNOWN: | 1646 | case PORT_UNKNOWN: |
| 1578 | fifosize = 256; /* EG20T/ML7213: UART0 */ | 1647 | fifosize = 256; /* EG20T/ML7213: UART0 */ |
| @@ -1597,7 +1666,7 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, | |||
| 1597 | priv->rxbuf.size = PAGE_SIZE; | 1666 | priv->rxbuf.size = PAGE_SIZE; |
| 1598 | 1667 | ||
| 1599 | priv->fifo_size = fifosize; | 1668 | priv->fifo_size = fifosize; |
| 1600 | priv->base_baud = base_baud; | 1669 | priv->uartclk = pch_uart_get_uartclk(); |
| 1601 | priv->port_type = PORT_MAX_8250 + port_type + 1; | 1670 | priv->port_type = PORT_MAX_8250 + port_type + 1; |
| 1602 | priv->port.dev = &pdev->dev; | 1671 | priv->port.dev = &pdev->dev; |
| 1603 | priv->port.iobase = iobase; | 1672 | priv->port.iobase = iobase; |
| @@ -1614,7 +1683,8 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, | |||
| 1614 | spin_lock_init(&priv->port.lock); | 1683 | spin_lock_init(&priv->port.lock); |
| 1615 | 1684 | ||
| 1616 | pci_set_drvdata(pdev, priv); | 1685 | pci_set_drvdata(pdev, priv); |
| 1617 | pch_uart_hal_request(pdev, fifosize, base_baud); | 1686 | priv->trigger_level = 1; |
| 1687 | priv->fcr = 0; | ||
| 1618 | 1688 | ||
| 1619 | #ifdef CONFIG_SERIAL_PCH_UART_CONSOLE | 1689 | #ifdef CONFIG_SERIAL_PCH_UART_CONSOLE |
| 1620 | pch_uart_ports[board->line_no] = priv; | 1690 | pch_uart_ports[board->line_no] = priv; |
| @@ -1623,6 +1693,12 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, | |||
| 1623 | if (ret < 0) | 1693 | if (ret < 0) |
| 1624 | goto init_port_hal_free; | 1694 | goto init_port_hal_free; |
| 1625 | 1695 | ||
| 1696 | #ifdef CONFIG_DEBUG_FS | ||
| 1697 | snprintf(name, sizeof(name), "uart%d_regs", board->line_no); | ||
| 1698 | priv->debugfs = debugfs_create_file(name, S_IFREG | S_IRUGO, | ||
| 1699 | NULL, priv, &port_regs_ops); | ||
| 1700 | #endif | ||
| 1701 | |||
| 1626 | return priv; | 1702 | return priv; |
| 1627 | 1703 | ||
| 1628 | init_port_hal_free: | 1704 | init_port_hal_free: |
| @@ -1639,6 +1715,11 @@ init_port_alloc_err: | |||
| 1639 | 1715 | ||
| 1640 | static void pch_uart_exit_port(struct eg20t_port *priv) | 1716 | static void pch_uart_exit_port(struct eg20t_port *priv) |
| 1641 | { | 1717 | { |
| 1718 | |||
| 1719 | #ifdef CONFIG_DEBUG_FS | ||
| 1720 | if (priv->debugfs) | ||
| 1721 | debugfs_remove(priv->debugfs); | ||
| 1722 | #endif | ||
| 1642 | uart_remove_one_port(&pch_uart_driver, &priv->port); | 1723 | uart_remove_one_port(&pch_uart_driver, &priv->port); |
| 1643 | pci_set_drvdata(priv->pdev, NULL); | 1724 | pci_set_drvdata(priv->pdev, NULL); |
| 1644 | free_page((unsigned long)priv->rxbuf.buf); | 1725 | free_page((unsigned long)priv->rxbuf.buf); |
| @@ -1646,9 +1727,7 @@ static void pch_uart_exit_port(struct eg20t_port *priv) | |||
| 1646 | 1727 | ||
| 1647 | static void pch_uart_pci_remove(struct pci_dev *pdev) | 1728 | static void pch_uart_pci_remove(struct pci_dev *pdev) |
| 1648 | { | 1729 | { |
| 1649 | struct eg20t_port *priv; | 1730 | struct eg20t_port *priv = pci_get_drvdata(pdev); |
| 1650 | |||
| 1651 | priv = (struct eg20t_port *)pci_get_drvdata(pdev); | ||
| 1652 | 1731 | ||
| 1653 | pci_disable_msi(pdev); | 1732 | pci_disable_msi(pdev); |
| 1654 | 1733 | ||
| @@ -1785,3 +1864,8 @@ module_exit(pch_uart_module_exit); | |||
| 1785 | MODULE_LICENSE("GPL v2"); | 1864 | MODULE_LICENSE("GPL v2"); |
| 1786 | MODULE_DESCRIPTION("Intel EG20T PCH UART PCI Driver"); | 1865 | MODULE_DESCRIPTION("Intel EG20T PCH UART PCI Driver"); |
| 1787 | module_param(default_baud, uint, S_IRUGO); | 1866 | module_param(default_baud, uint, S_IRUGO); |
| 1867 | MODULE_PARM_DESC(default_baud, | ||
| 1868 | "Default BAUD for initial driver state and console (default 9600)"); | ||
| 1869 | module_param(user_uartclk, uint, S_IRUGO); | ||
| 1870 | MODULE_PARM_DESC(user_uartclk, | ||
| 1871 | "Override UART default or board specific UART clock"); | ||
diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index e9c2dfe471a2..08ebe901bb59 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c | |||
| @@ -1506,7 +1506,7 @@ no_dma: | |||
| 1506 | * fixed up interrupt info, but we use the device-tree directly | 1506 | * fixed up interrupt info, but we use the device-tree directly |
| 1507 | * here due to early probing so we need the fixup too. | 1507 | * here due to early probing so we need the fixup too. |
| 1508 | */ | 1508 | */ |
| 1509 | if (uap->port.irq == NO_IRQ && | 1509 | if (uap->port.irq == 0 && |
| 1510 | np->parent && np->parent->parent && | 1510 | np->parent && np->parent->parent && |
| 1511 | of_device_is_compatible(np->parent->parent, "gatwick")) { | 1511 | of_device_is_compatible(np->parent->parent, "gatwick")) { |
| 1512 | /* IRQs on gatwick are offset by 64 */ | 1512 | /* IRQs on gatwick are offset by 64 */ |
diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index 5c8e3bba6c84..e2fd3d8e0ab4 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c | |||
| @@ -579,9 +579,9 @@ serial_pxa_pm(struct uart_port *port, unsigned int state, | |||
| 579 | struct uart_pxa_port *up = (struct uart_pxa_port *)port; | 579 | struct uart_pxa_port *up = (struct uart_pxa_port *)port; |
| 580 | 580 | ||
| 581 | if (!state) | 581 | if (!state) |
| 582 | clk_enable(up->clk); | 582 | clk_prepare_enable(up->clk); |
| 583 | else | 583 | else |
| 584 | clk_disable(up->clk); | 584 | clk_disable_unprepare(up->clk); |
| 585 | } | 585 | } |
| 586 | 586 | ||
| 587 | static void serial_pxa_release_port(struct uart_port *port) | 587 | static void serial_pxa_release_port(struct uart_port *port) |
| @@ -668,7 +668,7 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count) | |||
| 668 | struct uart_pxa_port *up = serial_pxa_ports[co->index]; | 668 | struct uart_pxa_port *up = serial_pxa_ports[co->index]; |
| 669 | unsigned int ier; | 669 | unsigned int ier; |
| 670 | 670 | ||
| 671 | clk_enable(up->clk); | 671 | clk_prepare_enable(up->clk); |
| 672 | 672 | ||
| 673 | /* | 673 | /* |
| 674 | * First save the IER then disable the interrupts | 674 | * First save the IER then disable the interrupts |
| @@ -685,7 +685,7 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count) | |||
| 685 | wait_for_xmitr(up); | 685 | wait_for_xmitr(up); |
| 686 | serial_out(up, UART_IER, ier); | 686 | serial_out(up, UART_IER, ier); |
| 687 | 687 | ||
| 688 | clk_disable(up->clk); | 688 | clk_disable_unprepare(up->clk); |
| 689 | } | 689 | } |
| 690 | 690 | ||
| 691 | static int __init | 691 | static int __init |
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index c55e5fb16fa3..de249d265bec 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c | |||
| @@ -1507,7 +1507,7 @@ static struct s3c24xx_serial_drv_data s3c2412_serial_drv_data = { | |||
| 1507 | #endif | 1507 | #endif |
| 1508 | 1508 | ||
| 1509 | #if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2416) || \ | 1509 | #if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2416) || \ |
| 1510 | defined(CONFIG_CPU_S3C2443) | 1510 | defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2442) |
| 1511 | static struct s3c24xx_serial_drv_data s3c2440_serial_drv_data = { | 1511 | static struct s3c24xx_serial_drv_data s3c2440_serial_drv_data = { |
| 1512 | .info = &(struct s3c24xx_uart_info) { | 1512 | .info = &(struct s3c24xx_uart_info) { |
| 1513 | .name = "Samsung S3C2440 UART", | 1513 | .name = "Samsung S3C2440 UART", |
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 13056180adf5..9c4c05b2825b 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c | |||
| @@ -2230,7 +2230,6 @@ int uart_register_driver(struct uart_driver *drv) | |||
| 2230 | 2230 | ||
| 2231 | drv->tty_driver = normal; | 2231 | drv->tty_driver = normal; |
| 2232 | 2232 | ||
| 2233 | normal->owner = drv->owner; | ||
| 2234 | normal->driver_name = drv->driver_name; | 2233 | normal->driver_name = drv->driver_name; |
| 2235 | normal->name = drv->dev_name; | 2234 | normal->name = drv->dev_name; |
| 2236 | normal->major = drv->major; | 2235 | normal->major = drv->major; |
diff --git a/drivers/tty/serial/sn_console.c b/drivers/tty/serial/sn_console.c index 238c7df73ef5..4e1b5515f881 100644 --- a/drivers/tty/serial/sn_console.c +++ b/drivers/tty/serial/sn_console.c | |||
| @@ -461,12 +461,12 @@ sn_receive_chars(struct sn_cons_port *port, unsigned long flags) | |||
| 461 | struct tty_struct *tty; | 461 | struct tty_struct *tty; |
| 462 | 462 | ||
| 463 | if (!port) { | 463 | if (!port) { |
| 464 | printk(KERN_ERR "sn_receive_chars - port NULL so can't receieve\n"); | 464 | printk(KERN_ERR "sn_receive_chars - port NULL so can't receive\n"); |
| 465 | return; | 465 | return; |
| 466 | } | 466 | } |
| 467 | 467 | ||
| 468 | if (!port->sc_ops) { | 468 | if (!port->sc_ops) { |
| 469 | printk(KERN_ERR "sn_receive_chars - port->sc_ops NULL so can't receieve\n"); | 469 | printk(KERN_ERR "sn_receive_chars - port->sc_ops NULL so can't receive\n"); |
| 470 | return; | 470 | return; |
| 471 | } | 471 | } |
| 472 | 472 | ||
diff --git a/drivers/tty/serial/suncore.c b/drivers/tty/serial/suncore.c index 6381a0282ee7..6e4ac8db2d79 100644 --- a/drivers/tty/serial/suncore.c +++ b/drivers/tty/serial/suncore.c | |||
| @@ -17,11 +17,11 @@ | |||
| 17 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
| 18 | #include <linux/string.h> | 18 | #include <linux/string.h> |
| 19 | #include <linux/serial_core.h> | 19 | #include <linux/serial_core.h> |
| 20 | #include <linux/sunserialcore.h> | ||
| 20 | #include <linux/init.h> | 21 | #include <linux/init.h> |
| 21 | 22 | ||
| 22 | #include <asm/prom.h> | 23 | #include <asm/prom.h> |
| 23 | 24 | ||
| 24 | #include "suncore.h" | ||
| 25 | 25 | ||
| 26 | static int sunserial_current_minor = 64; | 26 | static int sunserial_current_minor = 64; |
| 27 | 27 | ||
diff --git a/drivers/tty/serial/suncore.h b/drivers/tty/serial/suncore.h deleted file mode 100644 index db2057936c31..000000000000 --- a/drivers/tty/serial/suncore.h +++ /dev/null | |||
| @@ -1,33 +0,0 @@ | |||
| 1 | /* suncore.h | ||
| 2 | * | ||
| 3 | * Generic SUN serial/kbd/ms layer. Based entirely | ||
| 4 | * upon drivers/sbus/char/sunserial.h which is: | ||
| 5 | * | ||
| 6 | * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) | ||
| 7 | * | ||
| 8 | * Port to new UART layer is: | ||
| 9 | * | ||
| 10 | * Copyright (C) 2002 David S. Miller (davem@redhat.com) | ||
| 11 | */ | ||
| 12 | |||
| 13 | #ifndef _SERIAL_SUN_H | ||
| 14 | #define _SERIAL_SUN_H | ||
| 15 | |||
| 16 | /* Serial keyboard defines for L1-A processing... */ | ||
| 17 | #define SUNKBD_RESET 0xff | ||
| 18 | #define SUNKBD_L1 0x01 | ||
| 19 | #define SUNKBD_UP 0x80 | ||
| 20 | #define SUNKBD_A 0x4d | ||
| 21 | |||
| 22 | extern unsigned int suncore_mouse_baud_cflag_next(unsigned int, int *); | ||
| 23 | extern int suncore_mouse_baud_detection(unsigned char, int); | ||
| 24 | |||
| 25 | extern int sunserial_register_minors(struct uart_driver *, int); | ||
| 26 | extern void sunserial_unregister_minors(struct uart_driver *, int); | ||
| 27 | |||
| 28 | extern int sunserial_console_match(struct console *, struct device_node *, | ||
| 29 | struct uart_driver *, int, bool); | ||
| 30 | extern void sunserial_console_termios(struct console *, | ||
| 31 | struct device_node *); | ||
| 32 | |||
| 33 | #endif /* !(_SERIAL_SUN_H) */ | ||
diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c index c0b7246d7339..3ba5d285c2d0 100644 --- a/drivers/tty/serial/sunhv.c +++ b/drivers/tty/serial/sunhv.c | |||
| @@ -29,8 +29,7 @@ | |||
| 29 | #endif | 29 | #endif |
| 30 | 30 | ||
| 31 | #include <linux/serial_core.h> | 31 | #include <linux/serial_core.h> |
| 32 | 32 | #include <linux/sunserialcore.h> | |
| 33 | #include "suncore.h" | ||
| 34 | 33 | ||
| 35 | #define CON_BREAK ((long)-1) | 34 | #define CON_BREAK ((long)-1) |
| 36 | #define CON_HUP ((long)-2) | 35 | #define CON_HUP ((long)-2) |
diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index b5fa2a57b9da..62dacd0ba526 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c | |||
| @@ -43,8 +43,8 @@ | |||
| 43 | #endif | 43 | #endif |
| 44 | 44 | ||
| 45 | #include <linux/serial_core.h> | 45 | #include <linux/serial_core.h> |
| 46 | #include <linux/sunserialcore.h> | ||
| 46 | 47 | ||
| 47 | #include "suncore.h" | ||
| 48 | #include "sunsab.h" | 48 | #include "sunsab.h" |
| 49 | 49 | ||
| 50 | struct uart_sunsab_port { | 50 | struct uart_sunsab_port { |
diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index ad0f8f5f6ea1..d3ca6da129fe 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c | |||
| @@ -47,8 +47,7 @@ | |||
| 47 | #endif | 47 | #endif |
| 48 | 48 | ||
| 49 | #include <linux/serial_core.h> | 49 | #include <linux/serial_core.h> |
| 50 | 50 | #include <linux/sunserialcore.h> | |
| 51 | #include "suncore.h" | ||
| 52 | 51 | ||
| 53 | /* We are on a NS PC87303 clocked with 24.0 MHz, which results | 52 | /* We are on a NS PC87303 clocked with 24.0 MHz, which results |
| 54 | * in a UART clock of 1.8462 MHz. | 53 | * in a UART clock of 1.8462 MHz. |
diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c index 8e916e76b7b5..da4415842a43 100644 --- a/drivers/tty/serial/sunzilog.c +++ b/drivers/tty/serial/sunzilog.c | |||
| @@ -43,8 +43,8 @@ | |||
| 43 | #endif | 43 | #endif |
| 44 | 44 | ||
| 45 | #include <linux/serial_core.h> | 45 | #include <linux/serial_core.h> |
| 46 | #include <linux/sunserialcore.h> | ||
| 46 | 47 | ||
| 47 | #include "suncore.h" | ||
| 48 | #include "sunzilog.h" | 48 | #include "sunzilog.h" |
| 49 | 49 | ||
| 50 | /* On 32-bit sparcs we need to delay after register accesses | 50 | /* On 32-bit sparcs we need to delay after register accesses |
| @@ -1397,7 +1397,7 @@ static void __devinit sunzilog_init_hw(struct uart_sunzilog_port *up) | |||
| 1397 | #endif | 1397 | #endif |
| 1398 | } | 1398 | } |
| 1399 | 1399 | ||
| 1400 | static int zilog_irq = -1; | 1400 | static int zilog_irq; |
| 1401 | 1401 | ||
| 1402 | static int __devinit zs_probe(struct platform_device *op) | 1402 | static int __devinit zs_probe(struct platform_device *op) |
| 1403 | { | 1403 | { |
| @@ -1425,7 +1425,7 @@ static int __devinit zs_probe(struct platform_device *op) | |||
| 1425 | 1425 | ||
| 1426 | rp = sunzilog_chip_regs[inst]; | 1426 | rp = sunzilog_chip_regs[inst]; |
| 1427 | 1427 | ||
| 1428 | if (zilog_irq == -1) | 1428 | if (!zilog_irq) |
| 1429 | zilog_irq = op->archdata.irqs[0]; | 1429 | zilog_irq = op->archdata.irqs[0]; |
| 1430 | 1430 | ||
| 1431 | up = &sunzilog_port_table[inst * 2]; | 1431 | up = &sunzilog_port_table[inst * 2]; |
| @@ -1580,7 +1580,7 @@ static int __init sunzilog_init(void) | |||
| 1580 | if (err) | 1580 | if (err) |
| 1581 | goto out_unregister_uart; | 1581 | goto out_unregister_uart; |
| 1582 | 1582 | ||
| 1583 | if (zilog_irq != -1) { | 1583 | if (!zilog_irq) { |
| 1584 | struct uart_sunzilog_port *up = sunzilog_irq_chain; | 1584 | struct uart_sunzilog_port *up = sunzilog_irq_chain; |
| 1585 | err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED, | 1585 | err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED, |
| 1586 | "zs", sunzilog_irq_chain); | 1586 | "zs", sunzilog_irq_chain); |
| @@ -1621,7 +1621,7 @@ static void __exit sunzilog_exit(void) | |||
| 1621 | { | 1621 | { |
| 1622 | platform_driver_unregister(&zs_driver); | 1622 | platform_driver_unregister(&zs_driver); |
| 1623 | 1623 | ||
| 1624 | if (zilog_irq != -1) { | 1624 | if (!zilog_irq) { |
| 1625 | struct uart_sunzilog_port *up = sunzilog_irq_chain; | 1625 | struct uart_sunzilog_port *up = sunzilog_irq_chain; |
| 1626 | 1626 | ||
| 1627 | /* Disable Interrupts */ | 1627 | /* Disable Interrupts */ |
| @@ -1637,7 +1637,7 @@ static void __exit sunzilog_exit(void) | |||
| 1637 | } | 1637 | } |
| 1638 | 1638 | ||
| 1639 | free_irq(zilog_irq, sunzilog_irq_chain); | 1639 | free_irq(zilog_irq, sunzilog_irq_chain); |
| 1640 | zilog_irq = -1; | 1640 | zilog_irq = 0; |
| 1641 | } | 1641 | } |
| 1642 | 1642 | ||
| 1643 | if (sunzilog_reg.nr) { | 1643 | if (sunzilog_reg.nr) { |
diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index 2ebe606a2db1..f99b0c965f85 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c | |||
| @@ -1360,7 +1360,7 @@ static int ucc_uart_probe(struct platform_device *ofdev) | |||
| 1360 | } | 1360 | } |
| 1361 | 1361 | ||
| 1362 | qe_port->port.irq = irq_of_parse_and_map(np, 0); | 1362 | qe_port->port.irq = irq_of_parse_and_map(np, 0); |
| 1363 | if (qe_port->port.irq == NO_IRQ) { | 1363 | if (qe_port->port.irq == 0) { |
| 1364 | dev_err(&ofdev->dev, "could not map IRQ for UCC%u\n", | 1364 | dev_err(&ofdev->dev, "could not map IRQ for UCC%u\n", |
| 1365 | qe_port->ucc_num + 1); | 1365 | qe_port->ucc_num + 1); |
| 1366 | ret = -EINVAL; | 1366 | ret = -EINVAL; |
diff --git a/drivers/tty/serial/vr41xx_siu.c b/drivers/tty/serial/vr41xx_siu.c index 83148e79ca13..cf0d9485ec08 100644 --- a/drivers/tty/serial/vr41xx_siu.c +++ b/drivers/tty/serial/vr41xx_siu.c | |||
| @@ -61,7 +61,7 @@ | |||
| 61 | static struct uart_port siu_uart_ports[SIU_PORTS_MAX] = { | 61 | static struct uart_port siu_uart_ports[SIU_PORTS_MAX] = { |
| 62 | [0 ... SIU_PORTS_MAX-1] = { | 62 | [0 ... SIU_PORTS_MAX-1] = { |
| 63 | .lock = __SPIN_LOCK_UNLOCKED(siu_uart_ports->lock), | 63 | .lock = __SPIN_LOCK_UNLOCKED(siu_uart_ports->lock), |
| 64 | .irq = -1, | 64 | .irq = 0, |
| 65 | }, | 65 | }, |
| 66 | }; | 66 | }; |
| 67 | 67 | ||
| @@ -171,7 +171,7 @@ static inline unsigned int siu_check_type(struct uart_port *port) | |||
| 171 | { | 171 | { |
| 172 | if (port->line == 0) | 172 | if (port->line == 0) |
| 173 | return PORT_VR41XX_SIU; | 173 | return PORT_VR41XX_SIU; |
| 174 | if (port->line == 1 && port->irq != -1) | 174 | if (port->line == 1 && port->irq) |
| 175 | return PORT_VR41XX_DSIU; | 175 | return PORT_VR41XX_DSIU; |
| 176 | 176 | ||
| 177 | return PORT_UNKNOWN; | 177 | return PORT_UNKNOWN; |
diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index 026cb9ea5cd1..2be006fb3da0 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c | |||
| @@ -544,7 +544,7 @@ static struct uart_driver vt8500_uart_driver = { | |||
| 544 | .cons = VT8500_CONSOLE, | 544 | .cons = VT8500_CONSOLE, |
| 545 | }; | 545 | }; |
| 546 | 546 | ||
| 547 | static int __init vt8500_serial_probe(struct platform_device *pdev) | 547 | static int __devinit vt8500_serial_probe(struct platform_device *pdev) |
| 548 | { | 548 | { |
| 549 | struct vt8500_port *vt8500_port; | 549 | struct vt8500_port *vt8500_port; |
| 550 | struct resource *mmres, *irqres; | 550 | struct resource *mmres, *irqres; |
| @@ -605,7 +605,7 @@ static int __devexit vt8500_serial_remove(struct platform_device *pdev) | |||
| 605 | 605 | ||
| 606 | static struct platform_driver vt8500_platform_driver = { | 606 | static struct platform_driver vt8500_platform_driver = { |
| 607 | .probe = vt8500_serial_probe, | 607 | .probe = vt8500_serial_probe, |
| 608 | .remove = vt8500_serial_remove, | 608 | .remove = __devexit_p(vt8500_serial_remove), |
| 609 | .driver = { | 609 | .driver = { |
| 610 | .name = "vt8500_serial", | 610 | .name = "vt8500_serial", |
| 611 | .owner = THIS_MODULE, | 611 | .owner = THIS_MODULE, |
diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c index ff8017f87914..8e518da85fd5 100644 --- a/drivers/tty/synclink.c +++ b/drivers/tty/synclink.c | |||
| @@ -3381,7 +3381,7 @@ static int mgsl_open(struct tty_struct *tty, struct file * filp) | |||
| 3381 | 3381 | ||
| 3382 | /* verify range of specified line number */ | 3382 | /* verify range of specified line number */ |
| 3383 | line = tty->index; | 3383 | line = tty->index; |
| 3384 | if ((line < 0) || (line >= mgsl_device_count)) { | 3384 | if (line >= mgsl_device_count) { |
| 3385 | printk("%s(%d):mgsl_open with invalid line #%d.\n", | 3385 | printk("%s(%d):mgsl_open with invalid line #%d.\n", |
| 3386 | __FILE__,__LINE__,line); | 3386 | __FILE__,__LINE__,line); |
| 3387 | return -ENODEV; | 3387 | return -ENODEV; |
| @@ -4333,7 +4333,6 @@ static int mgsl_init_tty(void) | |||
| 4333 | if (!serial_driver) | 4333 | if (!serial_driver) |
| 4334 | return -ENOMEM; | 4334 | return -ENOMEM; |
| 4335 | 4335 | ||
| 4336 | serial_driver->owner = THIS_MODULE; | ||
| 4337 | serial_driver->driver_name = "synclink"; | 4336 | serial_driver->driver_name = "synclink"; |
| 4338 | serial_driver->name = "ttySL"; | 4337 | serial_driver->name = "ttySL"; |
| 4339 | serial_driver->major = ttymajor; | 4338 | serial_driver->major = ttymajor; |
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index 18b48cd3b41d..6bee4907c6a5 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c | |||
| @@ -654,7 +654,7 @@ static int open(struct tty_struct *tty, struct file *filp) | |||
| 654 | unsigned long flags; | 654 | unsigned long flags; |
| 655 | 655 | ||
| 656 | line = tty->index; | 656 | line = tty->index; |
| 657 | if ((line < 0) || (line >= slgt_device_count)) { | 657 | if (line >= slgt_device_count) { |
| 658 | DBGERR(("%s: open with invalid line #%d.\n", driver_name, line)); | 658 | DBGERR(("%s: open with invalid line #%d.\n", driver_name, line)); |
| 659 | return -ENODEV; | 659 | return -ENODEV; |
| 660 | } | 660 | } |
| @@ -3795,7 +3795,6 @@ static int __init slgt_init(void) | |||
| 3795 | 3795 | ||
| 3796 | /* Initialize the tty_driver structure */ | 3796 | /* Initialize the tty_driver structure */ |
| 3797 | 3797 | ||
| 3798 | serial_driver->owner = THIS_MODULE; | ||
| 3799 | serial_driver->driver_name = tty_driver_name; | 3798 | serial_driver->driver_name = tty_driver_name; |
| 3800 | serial_driver->name = tty_dev_prefix; | 3799 | serial_driver->name = tty_dev_prefix; |
| 3801 | serial_driver->major = ttymajor; | 3800 | serial_driver->major = ttymajor; |
diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c index a7efe538df00..4fb6c4b31b79 100644 --- a/drivers/tty/synclinkmp.c +++ b/drivers/tty/synclinkmp.c | |||
| @@ -721,7 +721,7 @@ static int open(struct tty_struct *tty, struct file *filp) | |||
| 721 | unsigned long flags; | 721 | unsigned long flags; |
| 722 | 722 | ||
| 723 | line = tty->index; | 723 | line = tty->index; |
| 724 | if ((line < 0) || (line >= synclinkmp_device_count)) { | 724 | if (line >= synclinkmp_device_count) { |
| 725 | printk("%s(%d): open with invalid line #%d.\n", | 725 | printk("%s(%d): open with invalid line #%d.\n", |
| 726 | __FILE__,__LINE__,line); | 726 | __FILE__,__LINE__,line); |
| 727 | return -ENODEV; | 727 | return -ENODEV; |
| @@ -3977,7 +3977,6 @@ static int __init synclinkmp_init(void) | |||
| 3977 | 3977 | ||
| 3978 | /* Initialize the tty_driver structure */ | 3978 | /* Initialize the tty_driver structure */ |
| 3979 | 3979 | ||
| 3980 | serial_driver->owner = THIS_MODULE; | ||
| 3981 | serial_driver->driver_name = "synclinkmp"; | 3980 | serial_driver->driver_name = "synclinkmp"; |
| 3982 | serial_driver->name = "ttySLM"; | 3981 | serial_driver->name = "ttySLM"; |
| 3983 | serial_driver->major = ttymajor; | 3982 | serial_driver->major = ttymajor; |
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 7867b7c4538e..ecb8e2203ac8 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c | |||
| @@ -110,11 +110,9 @@ static struct sysrq_key_op sysrq_SAK_op = { | |||
| 110 | #ifdef CONFIG_VT | 110 | #ifdef CONFIG_VT |
| 111 | static void sysrq_handle_unraw(int key) | 111 | static void sysrq_handle_unraw(int key) |
| 112 | { | 112 | { |
| 113 | struct kbd_struct *kbd = &kbd_table[fg_console]; | 113 | vt_reset_unicode(fg_console); |
| 114 | |||
| 115 | if (kbd) | ||
| 116 | kbd->kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE; | ||
| 117 | } | 114 | } |
| 115 | |||
| 118 | static struct sysrq_key_op sysrq_unraw_op = { | 116 | static struct sysrq_key_op sysrq_unraw_op = { |
| 119 | .handler = sysrq_handle_unraw, | 117 | .handler = sysrq_handle_unraw, |
| 120 | .help_msg = "unRaw", | 118 | .help_msg = "unRaw", |
| @@ -322,11 +320,16 @@ static void send_sig_all(int sig) | |||
| 322 | { | 320 | { |
| 323 | struct task_struct *p; | 321 | struct task_struct *p; |
| 324 | 322 | ||
| 323 | read_lock(&tasklist_lock); | ||
| 325 | for_each_process(p) { | 324 | for_each_process(p) { |
| 326 | if (p->mm && !is_global_init(p)) | 325 | if (p->flags & PF_KTHREAD) |
| 327 | /* Not swapper, init nor kernel thread */ | 326 | continue; |
| 328 | force_sig(sig, p); | 327 | if (is_global_init(p)) |
| 328 | continue; | ||
| 329 | |||
| 330 | force_sig(sig, p); | ||
| 329 | } | 331 | } |
| 332 | read_unlock(&tasklist_lock); | ||
| 330 | } | 333 | } |
| 331 | 334 | ||
| 332 | static void sysrq_handle_term(int key) | 335 | static void sysrq_handle_term(int key) |
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index e41b9bbc107d..dd8a938510ca 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
| @@ -1230,13 +1230,10 @@ static void tty_line_name(struct tty_driver *driver, int index, char *p) | |||
| 1230 | static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, | 1230 | static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, |
| 1231 | struct inode *inode, int idx) | 1231 | struct inode *inode, int idx) |
| 1232 | { | 1232 | { |
| 1233 | struct tty_struct *tty; | ||
| 1234 | |||
| 1235 | if (driver->ops->lookup) | 1233 | if (driver->ops->lookup) |
| 1236 | return driver->ops->lookup(driver, inode, idx); | 1234 | return driver->ops->lookup(driver, inode, idx); |
| 1237 | 1235 | ||
| 1238 | tty = driver->ttys[idx]; | 1236 | return driver->ttys[idx]; |
| 1239 | return tty; | ||
| 1240 | } | 1237 | } |
| 1241 | 1238 | ||
| 1242 | /** | 1239 | /** |
| @@ -1271,6 +1268,19 @@ int tty_init_termios(struct tty_struct *tty) | |||
| 1271 | } | 1268 | } |
| 1272 | EXPORT_SYMBOL_GPL(tty_init_termios); | 1269 | EXPORT_SYMBOL_GPL(tty_init_termios); |
| 1273 | 1270 | ||
| 1271 | int tty_standard_install(struct tty_driver *driver, struct tty_struct *tty) | ||
| 1272 | { | ||
| 1273 | int ret = tty_init_termios(tty); | ||
| 1274 | if (ret) | ||
| 1275 | return ret; | ||
| 1276 | |||
| 1277 | tty_driver_kref_get(driver); | ||
| 1278 | tty->count++; | ||
| 1279 | driver->ttys[tty->index] = tty; | ||
| 1280 | return 0; | ||
| 1281 | } | ||
| 1282 | EXPORT_SYMBOL_GPL(tty_standard_install); | ||
| 1283 | |||
| 1274 | /** | 1284 | /** |
| 1275 | * tty_driver_install_tty() - install a tty entry in the driver | 1285 | * tty_driver_install_tty() - install a tty entry in the driver |
| 1276 | * @driver: the driver for the tty | 1286 | * @driver: the driver for the tty |
| @@ -1286,21 +1296,8 @@ EXPORT_SYMBOL_GPL(tty_init_termios); | |||
| 1286 | static int tty_driver_install_tty(struct tty_driver *driver, | 1296 | static int tty_driver_install_tty(struct tty_driver *driver, |
| 1287 | struct tty_struct *tty) | 1297 | struct tty_struct *tty) |
| 1288 | { | 1298 | { |
| 1289 | int idx = tty->index; | 1299 | return driver->ops->install ? driver->ops->install(driver, tty) : |
| 1290 | int ret; | 1300 | tty_standard_install(driver, tty); |
| 1291 | |||
| 1292 | if (driver->ops->install) { | ||
| 1293 | ret = driver->ops->install(driver, tty); | ||
| 1294 | return ret; | ||
| 1295 | } | ||
| 1296 | |||
| 1297 | if (tty_init_termios(tty) == 0) { | ||
| 1298 | tty_driver_kref_get(driver); | ||
| 1299 | tty->count++; | ||
| 1300 | driver->ttys[idx] = tty; | ||
| 1301 | return 0; | ||
| 1302 | } | ||
| 1303 | return -ENOMEM; | ||
| 1304 | } | 1301 | } |
| 1305 | 1302 | ||
| 1306 | /** | 1303 | /** |
| @@ -1351,7 +1348,6 @@ static int tty_reopen(struct tty_struct *tty) | |||
| 1351 | tty->link->count++; | 1348 | tty->link->count++; |
| 1352 | } | 1349 | } |
| 1353 | tty->count++; | 1350 | tty->count++; |
| 1354 | tty->driver = driver; /* N.B. why do this every time?? */ | ||
| 1355 | 1351 | ||
| 1356 | mutex_lock(&tty->ldisc_mutex); | 1352 | mutex_lock(&tty->ldisc_mutex); |
| 1357 | WARN_ON(!test_bit(TTY_LDISC, &tty->flags)); | 1353 | WARN_ON(!test_bit(TTY_LDISC, &tty->flags)); |
| @@ -1365,7 +1361,6 @@ static int tty_reopen(struct tty_struct *tty) | |||
| 1365 | * @driver: tty driver we are opening a device on | 1361 | * @driver: tty driver we are opening a device on |
| 1366 | * @idx: device index | 1362 | * @idx: device index |
| 1367 | * @ret_tty: returned tty structure | 1363 | * @ret_tty: returned tty structure |
| 1368 | * @first_ok: ok to open a new device (used by ptmx) | ||
| 1369 | * | 1364 | * |
| 1370 | * Prepare a tty device. This may not be a "new" clean device but | 1365 | * Prepare a tty device. This may not be a "new" clean device but |
| 1371 | * could also be an active device. The pty drivers require special | 1366 | * could also be an active device. The pty drivers require special |
| @@ -1385,18 +1380,11 @@ static int tty_reopen(struct tty_struct *tty) | |||
| 1385 | * relaxed for the (most common) case of reopening a tty. | 1380 | * relaxed for the (most common) case of reopening a tty. |
| 1386 | */ | 1381 | */ |
| 1387 | 1382 | ||
| 1388 | struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, | 1383 | struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) |
| 1389 | int first_ok) | ||
| 1390 | { | 1384 | { |
| 1391 | struct tty_struct *tty; | 1385 | struct tty_struct *tty; |
| 1392 | int retval; | 1386 | int retval; |
| 1393 | 1387 | ||
| 1394 | /* Check if pty master is being opened multiple times */ | ||
| 1395 | if (driver->subtype == PTY_TYPE_MASTER && | ||
| 1396 | (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) { | ||
| 1397 | return ERR_PTR(-EIO); | ||
| 1398 | } | ||
| 1399 | |||
| 1400 | /* | 1388 | /* |
| 1401 | * First time open is complex, especially for PTY devices. | 1389 | * First time open is complex, especially for PTY devices. |
| 1402 | * This code guarantees that either everything succeeds and the | 1390 | * This code guarantees that either everything succeeds and the |
| @@ -1950,7 +1938,7 @@ retry_open: | |||
| 1950 | if (retval) | 1938 | if (retval) |
| 1951 | tty = ERR_PTR(retval); | 1939 | tty = ERR_PTR(retval); |
| 1952 | } else | 1940 | } else |
| 1953 | tty = tty_init_dev(driver, index, 0); | 1941 | tty = tty_init_dev(driver, index); |
| 1954 | 1942 | ||
| 1955 | mutex_unlock(&tty_mutex); | 1943 | mutex_unlock(&tty_mutex); |
| 1956 | if (driver) | 1944 | if (driver) |
| @@ -2941,7 +2929,6 @@ void initialize_tty_struct(struct tty_struct *tty, | |||
| 2941 | tty->session = NULL; | 2929 | tty->session = NULL; |
| 2942 | tty->pgrp = NULL; | 2930 | tty->pgrp = NULL; |
| 2943 | tty->overrun_time = jiffies; | 2931 | tty->overrun_time = jiffies; |
| 2944 | tty->buf.head = tty->buf.tail = NULL; | ||
| 2945 | tty_buffer_init(tty); | 2932 | tty_buffer_init(tty); |
| 2946 | mutex_init(&tty->termios_mutex); | 2933 | mutex_init(&tty->termios_mutex); |
| 2947 | mutex_init(&tty->ldisc_mutex); | 2934 | mutex_init(&tty->ldisc_mutex); |
| @@ -3058,7 +3045,7 @@ void tty_unregister_device(struct tty_driver *driver, unsigned index) | |||
| 3058 | } | 3045 | } |
| 3059 | EXPORT_SYMBOL(tty_unregister_device); | 3046 | EXPORT_SYMBOL(tty_unregister_device); |
| 3060 | 3047 | ||
| 3061 | struct tty_driver *alloc_tty_driver(int lines) | 3048 | struct tty_driver *__alloc_tty_driver(int lines, struct module *owner) |
| 3062 | { | 3049 | { |
| 3063 | struct tty_driver *driver; | 3050 | struct tty_driver *driver; |
| 3064 | 3051 | ||
| @@ -3067,11 +3054,12 @@ struct tty_driver *alloc_tty_driver(int lines) | |||
| 3067 | kref_init(&driver->kref); | 3054 | kref_init(&driver->kref); |
| 3068 | driver->magic = TTY_DRIVER_MAGIC; | 3055 | driver->magic = TTY_DRIVER_MAGIC; |
| 3069 | driver->num = lines; | 3056 | driver->num = lines; |
| 3057 | driver->owner = owner; | ||
| 3070 | /* later we'll move allocation of tables here */ | 3058 | /* later we'll move allocation of tables here */ |
| 3071 | } | 3059 | } |
| 3072 | return driver; | 3060 | return driver; |
| 3073 | } | 3061 | } |
| 3074 | EXPORT_SYMBOL(alloc_tty_driver); | 3062 | EXPORT_SYMBOL(__alloc_tty_driver); |
| 3075 | 3063 | ||
| 3076 | static void destruct_tty_driver(struct kref *kref) | 3064 | static void destruct_tty_driver(struct kref *kref) |
| 3077 | { | 3065 | { |
diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c index a0f3d6c4d39d..8308fc7cdc26 100644 --- a/drivers/tty/vt/consolemap.c +++ b/drivers/tty/vt/consolemap.c | |||
| @@ -516,6 +516,7 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list) | |||
| 516 | int err = 0, err1, i; | 516 | int err = 0, err1, i; |
| 517 | struct uni_pagedir *p, *q; | 517 | struct uni_pagedir *p, *q; |
| 518 | 518 | ||
| 519 | /* Save original vc_unipagdir_loc in case we allocate a new one */ | ||
| 519 | p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc; | 520 | p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc; |
| 520 | if (p->readonly) return -EIO; | 521 | if (p->readonly) return -EIO; |
| 521 | 522 | ||
| @@ -528,26 +529,57 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list) | |||
| 528 | err1 = con_clear_unimap(vc, NULL); | 529 | err1 = con_clear_unimap(vc, NULL); |
| 529 | if (err1) return err1; | 530 | if (err1) return err1; |
| 530 | 531 | ||
| 532 | /* | ||
| 533 | * Since refcount was > 1, con_clear_unimap() allocated a | ||
| 534 | * a new uni_pagedir for this vc. Re: p != q | ||
| 535 | */ | ||
| 531 | q = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc; | 536 | q = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc; |
| 532 | for (i = 0, l = 0; i < 32; i++) | 537 | |
| 538 | /* | ||
| 539 | * uni_pgdir is a 32*32*64 table with rows allocated | ||
| 540 | * when its first entry is added. The unicode value must | ||
| 541 | * still be incremented for empty rows. We are copying | ||
| 542 | * entries from "p" (old) to "q" (new). | ||
| 543 | */ | ||
| 544 | l = 0; /* unicode value */ | ||
| 545 | for (i = 0; i < 32; i++) | ||
| 533 | if ((p1 = p->uni_pgdir[i])) | 546 | if ((p1 = p->uni_pgdir[i])) |
| 534 | for (j = 0; j < 32; j++) | 547 | for (j = 0; j < 32; j++) |
| 535 | if ((p2 = p1[j])) | 548 | if ((p2 = p1[j])) { |
| 536 | for (k = 0; k < 64; k++, l++) | 549 | for (k = 0; k < 64; k++, l++) |
| 537 | if (p2[k] != 0xffff) { | 550 | if (p2[k] != 0xffff) { |
| 551 | /* | ||
| 552 | * Found one, copy entry for unicode | ||
| 553 | * l with fontpos value p2[k]. | ||
| 554 | */ | ||
| 538 | err1 = con_insert_unipair(q, l, p2[k]); | 555 | err1 = con_insert_unipair(q, l, p2[k]); |
| 539 | if (err1) { | 556 | if (err1) { |
| 540 | p->refcount++; | 557 | p->refcount++; |
| 541 | *vc->vc_uni_pagedir_loc = (unsigned long)p; | 558 | *vc->vc_uni_pagedir_loc = (unsigned long)p; |
| 542 | con_release_unimap(q); | 559 | con_release_unimap(q); |
| 543 | kfree(q); | 560 | kfree(q); |
| 544 | return err1; | 561 | return err1; |
| 545 | } | 562 | } |
| 546 | } | 563 | } |
| 547 | p = q; | 564 | } else { |
| 548 | } else if (p == dflt) | 565 | /* Account for row of 64 empty entries */ |
| 566 | l += 64; | ||
| 567 | } | ||
| 568 | else | ||
| 569 | /* Account for empty table */ | ||
| 570 | l += 32 * 64; | ||
| 571 | |||
| 572 | /* | ||
| 573 | * Finished copying font table, set vc_uni_pagedir to new table | ||
| 574 | */ | ||
| 575 | p = q; | ||
| 576 | } else if (p == dflt) { | ||
| 549 | dflt = NULL; | 577 | dflt = NULL; |
| 550 | 578 | } | |
| 579 | |||
| 580 | /* | ||
| 581 | * Insert user specified unicode pairs into new table. | ||
| 582 | */ | ||
| 551 | while (ct--) { | 583 | while (ct--) { |
| 552 | unsigned short unicode, fontpos; | 584 | unsigned short unicode, fontpos; |
| 553 | __get_user(unicode, &list->unicode); | 585 | __get_user(unicode, &list->unicode); |
| @@ -557,11 +589,14 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list) | |||
| 557 | list++; | 589 | list++; |
| 558 | } | 590 | } |
| 559 | 591 | ||
| 592 | /* | ||
| 593 | * Merge with fontmaps of any other virtual consoles. | ||
| 594 | */ | ||
| 560 | if (con_unify_unimap(vc, p)) | 595 | if (con_unify_unimap(vc, p)) |
| 561 | return err; | 596 | return err; |
| 562 | 597 | ||
| 563 | for (i = 0; i <= 3; i++) | 598 | for (i = 0; i <= 3; i++) |
| 564 | set_inverse_transl(vc, p, i); /* Update all inverse translations */ | 599 | set_inverse_transl(vc, p, i); /* Update inverse translations */ |
| 565 | set_inverse_trans_unicode(vc, p); | 600 | set_inverse_trans_unicode(vc, p); |
| 566 | 601 | ||
| 567 | return err; | 602 | return err; |
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index a605549ee28f..86dd1e302bb3 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | #include <linux/reboot.h> | 41 | #include <linux/reboot.h> |
| 42 | #include <linux/notifier.h> | 42 | #include <linux/notifier.h> |
| 43 | #include <linux/jiffies.h> | 43 | #include <linux/jiffies.h> |
| 44 | #include <linux/uaccess.h> | ||
| 44 | 45 | ||
| 45 | #include <asm/irq_regs.h> | 46 | #include <asm/irq_regs.h> |
| 46 | 47 | ||
| @@ -55,8 +56,8 @@ extern void ctrl_alt_del(void); | |||
| 55 | /* | 56 | /* |
| 56 | * Some laptops take the 789uiojklm,. keys as number pad when NumLock is on. | 57 | * Some laptops take the 789uiojklm,. keys as number pad when NumLock is on. |
| 57 | * This seems a good reason to start with NumLock off. On HIL keyboards | 58 | * This seems a good reason to start with NumLock off. On HIL keyboards |
| 58 | * of PARISC machines however there is no NumLock key and everyone expects the keypad | 59 | * of PARISC machines however there is no NumLock key and everyone expects the |
| 59 | * to be used for numbers. | 60 | * keypad to be used for numbers. |
| 60 | */ | 61 | */ |
| 61 | 62 | ||
| 62 | #if defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD)) | 63 | #if defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD)) |
| @@ -67,8 +68,6 @@ extern void ctrl_alt_del(void); | |||
| 67 | 68 | ||
| 68 | #define KBD_DEFLOCK 0 | 69 | #define KBD_DEFLOCK 0 |
| 69 | 70 | ||
| 70 | void compute_shiftstate(void); | ||
| 71 | |||
| 72 | /* | 71 | /* |
| 73 | * Handler Tables. | 72 | * Handler Tables. |
| 74 | */ | 73 | */ |
| @@ -99,35 +98,29 @@ static fn_handler_fn *fn_handler[] = { FN_HANDLERS }; | |||
| 99 | * Variables exported for vt_ioctl.c | 98 | * Variables exported for vt_ioctl.c |
| 100 | */ | 99 | */ |
| 101 | 100 | ||
| 102 | /* maximum values each key_handler can handle */ | ||
| 103 | const int max_vals[] = { | ||
| 104 | 255, ARRAY_SIZE(func_table) - 1, ARRAY_SIZE(fn_handler) - 1, NR_PAD - 1, | ||
| 105 | NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1, | ||
| 106 | 255, NR_LOCK - 1, 255, NR_BRL - 1 | ||
| 107 | }; | ||
| 108 | |||
| 109 | const int NR_TYPES = ARRAY_SIZE(max_vals); | ||
| 110 | |||
| 111 | struct kbd_struct kbd_table[MAX_NR_CONSOLES]; | ||
| 112 | EXPORT_SYMBOL_GPL(kbd_table); | ||
| 113 | static struct kbd_struct *kbd = kbd_table; | ||
| 114 | |||
| 115 | struct vt_spawn_console vt_spawn_con = { | 101 | struct vt_spawn_console vt_spawn_con = { |
| 116 | .lock = __SPIN_LOCK_UNLOCKED(vt_spawn_con.lock), | 102 | .lock = __SPIN_LOCK_UNLOCKED(vt_spawn_con.lock), |
| 117 | .pid = NULL, | 103 | .pid = NULL, |
| 118 | .sig = 0, | 104 | .sig = 0, |
| 119 | }; | 105 | }; |
| 120 | 106 | ||
| 121 | /* | ||
| 122 | * Variables exported for vt.c | ||
| 123 | */ | ||
| 124 | |||
| 125 | int shift_state = 0; | ||
| 126 | 107 | ||
| 127 | /* | 108 | /* |
| 128 | * Internal Data. | 109 | * Internal Data. |
| 129 | */ | 110 | */ |
| 130 | 111 | ||
| 112 | static struct kbd_struct kbd_table[MAX_NR_CONSOLES]; | ||
| 113 | static struct kbd_struct *kbd = kbd_table; | ||
| 114 | |||
| 115 | /* maximum values each key_handler can handle */ | ||
| 116 | static const int max_vals[] = { | ||
| 117 | 255, ARRAY_SIZE(func_table) - 1, ARRAY_SIZE(fn_handler) - 1, NR_PAD - 1, | ||
| 118 | NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1, | ||
| 119 | 255, NR_LOCK - 1, 255, NR_BRL - 1 | ||
| 120 | }; | ||
| 121 | |||
| 122 | static const int NR_TYPES = ARRAY_SIZE(max_vals); | ||
| 123 | |||
| 131 | static struct input_handler kbd_handler; | 124 | static struct input_handler kbd_handler; |
| 132 | static DEFINE_SPINLOCK(kbd_event_lock); | 125 | static DEFINE_SPINLOCK(kbd_event_lock); |
| 133 | static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */ | 126 | static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */ |
| @@ -137,6 +130,8 @@ static int npadch = -1; /* -1 or number assembled on pad */ | |||
| 137 | static unsigned int diacr; | 130 | static unsigned int diacr; |
| 138 | static char rep; /* flag telling character repeat */ | 131 | static char rep; /* flag telling character repeat */ |
| 139 | 132 | ||
| 133 | static int shift_state = 0; | ||
| 134 | |||
| 140 | static unsigned char ledstate = 0xff; /* undefined */ | 135 | static unsigned char ledstate = 0xff; /* undefined */ |
| 141 | static unsigned char ledioctl; | 136 | static unsigned char ledioctl; |
| 142 | 137 | ||
| @@ -187,7 +182,7 @@ static int getkeycode_helper(struct input_handle *handle, void *data) | |||
| 187 | return d->error == 0; /* stop as soon as we successfully get one */ | 182 | return d->error == 0; /* stop as soon as we successfully get one */ |
| 188 | } | 183 | } |
| 189 | 184 | ||
| 190 | int getkeycode(unsigned int scancode) | 185 | static int getkeycode(unsigned int scancode) |
| 191 | { | 186 | { |
| 192 | struct getset_keycode_data d = { | 187 | struct getset_keycode_data d = { |
| 193 | .ke = { | 188 | .ke = { |
| @@ -214,7 +209,7 @@ static int setkeycode_helper(struct input_handle *handle, void *data) | |||
| 214 | return d->error == 0; /* stop as soon as we successfully set one */ | 209 | return d->error == 0; /* stop as soon as we successfully set one */ |
| 215 | } | 210 | } |
| 216 | 211 | ||
| 217 | int setkeycode(unsigned int scancode, unsigned int keycode) | 212 | static int setkeycode(unsigned int scancode, unsigned int keycode) |
| 218 | { | 213 | { |
| 219 | struct getset_keycode_data d = { | 214 | struct getset_keycode_data d = { |
| 220 | .ke = { | 215 | .ke = { |
| @@ -382,9 +377,11 @@ static void to_utf8(struct vc_data *vc, uint c) | |||
| 382 | /* | 377 | /* |
| 383 | * Called after returning from RAW mode or when changing consoles - recompute | 378 | * Called after returning from RAW mode or when changing consoles - recompute |
| 384 | * shift_down[] and shift_state from key_down[] maybe called when keymap is | 379 | * shift_down[] and shift_state from key_down[] maybe called when keymap is |
| 385 | * undefined, so that shiftkey release is seen | 380 | * undefined, so that shiftkey release is seen. The caller must hold the |
| 381 | * kbd_event_lock. | ||
| 386 | */ | 382 | */ |
| 387 | void compute_shiftstate(void) | 383 | |
| 384 | static void do_compute_shiftstate(void) | ||
| 388 | { | 385 | { |
| 389 | unsigned int i, j, k, sym, val; | 386 | unsigned int i, j, k, sym, val; |
| 390 | 387 | ||
| @@ -417,6 +414,15 @@ void compute_shiftstate(void) | |||
| 417 | } | 414 | } |
| 418 | } | 415 | } |
| 419 | 416 | ||
| 417 | /* We still have to export this method to vt.c */ | ||
| 418 | void compute_shiftstate(void) | ||
| 419 | { | ||
| 420 | unsigned long flags; | ||
| 421 | spin_lock_irqsave(&kbd_event_lock, flags); | ||
| 422 | do_compute_shiftstate(); | ||
| 423 | spin_unlock_irqrestore(&kbd_event_lock, flags); | ||
| 424 | } | ||
| 425 | |||
| 420 | /* | 426 | /* |
| 421 | * We have a combining character DIACR here, followed by the character CH. | 427 | * We have a combining character DIACR here, followed by the character CH. |
| 422 | * If the combination occurs in the table, return the corresponding value. | 428 | * If the combination occurs in the table, return the corresponding value. |
| @@ -636,7 +642,7 @@ static void fn_SAK(struct vc_data *vc) | |||
| 636 | 642 | ||
| 637 | static void fn_null(struct vc_data *vc) | 643 | static void fn_null(struct vc_data *vc) |
| 638 | { | 644 | { |
| 639 | compute_shiftstate(); | 645 | do_compute_shiftstate(); |
| 640 | } | 646 | } |
| 641 | 647 | ||
| 642 | /* | 648 | /* |
| @@ -989,6 +995,8 @@ unsigned char getledstate(void) | |||
| 989 | 995 | ||
| 990 | void setledstate(struct kbd_struct *kbd, unsigned int led) | 996 | void setledstate(struct kbd_struct *kbd, unsigned int led) |
| 991 | { | 997 | { |
| 998 | unsigned long flags; | ||
| 999 | spin_lock_irqsave(&kbd_event_lock, flags); | ||
| 992 | if (!(led & ~7)) { | 1000 | if (!(led & ~7)) { |
| 993 | ledioctl = led; | 1001 | ledioctl = led; |
| 994 | kbd->ledmode = LED_SHOW_IOCTL; | 1002 | kbd->ledmode = LED_SHOW_IOCTL; |
| @@ -996,6 +1004,7 @@ void setledstate(struct kbd_struct *kbd, unsigned int led) | |||
| 996 | kbd->ledmode = LED_SHOW_FLAGS; | 1004 | kbd->ledmode = LED_SHOW_FLAGS; |
| 997 | 1005 | ||
| 998 | set_leds(); | 1006 | set_leds(); |
| 1007 | spin_unlock_irqrestore(&kbd_event_lock, flags); | ||
| 999 | } | 1008 | } |
| 1000 | 1009 | ||
| 1001 | static inline unsigned char getleds(void) | 1010 | static inline unsigned char getleds(void) |
| @@ -1035,6 +1044,75 @@ static int kbd_update_leds_helper(struct input_handle *handle, void *data) | |||
| 1035 | return 0; | 1044 | return 0; |
| 1036 | } | 1045 | } |
| 1037 | 1046 | ||
| 1047 | /** | ||
| 1048 | * vt_get_leds - helper for braille console | ||
| 1049 | * @console: console to read | ||
| 1050 | * @flag: flag we want to check | ||
| 1051 | * | ||
| 1052 | * Check the status of a keyboard led flag and report it back | ||
| 1053 | */ | ||
| 1054 | int vt_get_leds(int console, int flag) | ||
| 1055 | { | ||
| 1056 | unsigned long flags; | ||
| 1057 | struct kbd_struct * kbd = kbd_table + console; | ||
| 1058 | int ret; | ||
| 1059 | |||
| 1060 | spin_lock_irqsave(&kbd_event_lock, flags); | ||
| 1061 | ret = vc_kbd_led(kbd, flag); | ||
| 1062 | spin_unlock_irqrestore(&kbd_event_lock, flags); | ||
| 1063 | |||
| 1064 | return ret; | ||
| 1065 | } | ||
| 1066 | EXPORT_SYMBOL_GPL(vt_get_leds); | ||
| 1067 | |||
| 1068 | /** | ||
| 1069 | * vt_set_led_state - set LED state of a console | ||
| 1070 | * @console: console to set | ||
| 1071 | * @leds: LED bits | ||
| 1072 | * | ||
| 1073 | * Set the LEDs on a console. This is a wrapper for the VT layer | ||
| 1074 | * so that we can keep kbd knowledge internal | ||
| 1075 | */ | ||
| 1076 | void vt_set_led_state(int console, int leds) | ||
| 1077 | { | ||
| 1078 | struct kbd_struct * kbd = kbd_table + console; | ||
| 1079 | setledstate(kbd, leds); | ||
| 1080 | } | ||
| 1081 | |||
| 1082 | /** | ||
| 1083 | * vt_kbd_con_start - Keyboard side of console start | ||
| 1084 | * @console: console | ||
| 1085 | * | ||
| 1086 | * Handle console start. This is a wrapper for the VT layer | ||
| 1087 | * so that we can keep kbd knowledge internal | ||
| 1088 | */ | ||
| 1089 | void vt_kbd_con_start(int console) | ||
| 1090 | { | ||
| 1091 | struct kbd_struct * kbd = kbd_table + console; | ||
| 1092 | unsigned long flags; | ||
| 1093 | spin_lock_irqsave(&kbd_event_lock, flags); | ||
| 1094 | clr_vc_kbd_led(kbd, VC_SCROLLOCK); | ||
| 1095 | set_leds(); | ||
| 1096 | spin_unlock_irqrestore(&kbd_event_lock, flags); | ||
| 1097 | } | ||
| 1098 | |||
| 1099 | /** | ||
| 1100 | * vt_kbd_con_stop - Keyboard side of console stop | ||
| 1101 | * @console: console | ||
| 1102 | * | ||
| 1103 | * Handle console stop. This is a wrapper for the VT layer | ||
| 1104 | * so that we can keep kbd knowledge internal | ||
| 1105 | */ | ||
| 1106 | void vt_kbd_con_stop(int console) | ||
| 1107 | { | ||
| 1108 | struct kbd_struct * kbd = kbd_table + console; | ||
| 1109 | unsigned long flags; | ||
| 1110 | spin_lock_irqsave(&kbd_event_lock, flags); | ||
| 1111 | set_vc_kbd_led(kbd, VC_SCROLLOCK); | ||
| 1112 | set_leds(); | ||
| 1113 | spin_unlock_irqrestore(&kbd_event_lock, flags); | ||
| 1114 | } | ||
| 1115 | |||
| 1038 | /* | 1116 | /* |
| 1039 | * This is the tasklet that updates LED state on all keyboards | 1117 | * This is the tasklet that updates LED state on all keyboards |
| 1040 | * attached to the box. The reason we use tasklet is that we | 1118 | * attached to the box. The reason we use tasklet is that we |
| @@ -1254,7 +1332,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) | |||
| 1254 | if (rc == NOTIFY_STOP || !key_map) { | 1332 | if (rc == NOTIFY_STOP || !key_map) { |
| 1255 | atomic_notifier_call_chain(&keyboard_notifier_list, | 1333 | atomic_notifier_call_chain(&keyboard_notifier_list, |
| 1256 | KBD_UNBOUND_KEYCODE, ¶m); | 1334 | KBD_UNBOUND_KEYCODE, ¶m); |
| 1257 | compute_shiftstate(); | 1335 | do_compute_shiftstate(); |
| 1258 | kbd->slockstate = 0; | 1336 | kbd->slockstate = 0; |
| 1259 | return; | 1337 | return; |
| 1260 | } | 1338 | } |
| @@ -1404,14 +1482,14 @@ static void kbd_start(struct input_handle *handle) | |||
| 1404 | 1482 | ||
| 1405 | static const struct input_device_id kbd_ids[] = { | 1483 | static const struct input_device_id kbd_ids[] = { |
| 1406 | { | 1484 | { |
| 1407 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT, | 1485 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT, |
| 1408 | .evbit = { BIT_MASK(EV_KEY) }, | 1486 | .evbit = { BIT_MASK(EV_KEY) }, |
| 1409 | }, | 1487 | }, |
| 1410 | 1488 | ||
| 1411 | { | 1489 | { |
| 1412 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT, | 1490 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT, |
| 1413 | .evbit = { BIT_MASK(EV_SND) }, | 1491 | .evbit = { BIT_MASK(EV_SND) }, |
| 1414 | }, | 1492 | }, |
| 1415 | 1493 | ||
| 1416 | { }, /* Terminating entry */ | 1494 | { }, /* Terminating entry */ |
| 1417 | }; | 1495 | }; |
| @@ -1433,7 +1511,7 @@ int __init kbd_init(void) | |||
| 1433 | int i; | 1511 | int i; |
| 1434 | int error; | 1512 | int error; |
| 1435 | 1513 | ||
| 1436 | for (i = 0; i < MAX_NR_CONSOLES; i++) { | 1514 | for (i = 0; i < MAX_NR_CONSOLES; i++) { |
| 1437 | kbd_table[i].ledflagstate = KBD_DEFLEDS; | 1515 | kbd_table[i].ledflagstate = KBD_DEFLEDS; |
| 1438 | kbd_table[i].default_ledflagstate = KBD_DEFLEDS; | 1516 | kbd_table[i].default_ledflagstate = KBD_DEFLEDS; |
| 1439 | kbd_table[i].ledmode = LED_SHOW_FLAGS; | 1517 | kbd_table[i].ledmode = LED_SHOW_FLAGS; |
| @@ -1452,3 +1530,658 @@ int __init kbd_init(void) | |||
| 1452 | 1530 | ||
| 1453 | return 0; | 1531 | return 0; |
| 1454 | } | 1532 | } |
| 1533 | |||
| 1534 | /* Ioctl support code */ | ||
| 1535 | |||
| 1536 | /** | ||
| 1537 | * vt_do_diacrit - diacritical table updates | ||
| 1538 | * @cmd: ioctl request | ||
| 1539 | * @up: pointer to user data for ioctl | ||
| 1540 | * @perm: permissions check computed by caller | ||
| 1541 | * | ||
| 1542 | * Update the diacritical tables atomically and safely. Lock them | ||
| 1543 | * against simultaneous keypresses | ||
| 1544 | */ | ||
| 1545 | int vt_do_diacrit(unsigned int cmd, void __user *up, int perm) | ||
| 1546 | { | ||
| 1547 | struct kbdiacrs __user *a = up; | ||
| 1548 | unsigned long flags; | ||
| 1549 | int asize; | ||
| 1550 | int ret = 0; | ||
| 1551 | |||
| 1552 | switch (cmd) { | ||
| 1553 | case KDGKBDIACR: | ||
| 1554 | { | ||
| 1555 | struct kbdiacr *diacr; | ||
| 1556 | int i; | ||
| 1557 | |||
| 1558 | diacr = kmalloc(MAX_DIACR * sizeof(struct kbdiacr), | ||
| 1559 | GFP_KERNEL); | ||
| 1560 | if (diacr == NULL) | ||
| 1561 | return -ENOMEM; | ||
| 1562 | |||
| 1563 | /* Lock the diacriticals table, make a copy and then | ||
| 1564 | copy it after we unlock */ | ||
| 1565 | spin_lock_irqsave(&kbd_event_lock, flags); | ||
| 1566 | |||
| 1567 | asize = accent_table_size; | ||
| 1568 | for (i = 0; i < asize; i++) { | ||
| 1569 | diacr[i].diacr = conv_uni_to_8bit( | ||
| 1570 | accent_table[i].diacr); | ||
| 1571 | diacr[i].base = conv_uni_to_8bit( | ||
| 1572 | accent_table[i].base); | ||
| 1573 | diacr[i].result = conv_uni_to_8bit( | ||
| 1574 | accent_table[i].result); | ||
| 1575 | } | ||
| 1576 | spin_unlock_irqrestore(&kbd_event_lock, flags); | ||
| 1577 | |||
| 1578 | if (put_user(asize, &a->kb_cnt)) | ||
| 1579 | ret = -EFAULT; | ||
| 1580 | else if (copy_to_user(a->kbdiacr, diacr, | ||
| 1581 | asize * sizeof(struct kbdiacr))) | ||
| 1582 | ret = -EFAULT; | ||
| 1583 | kfree(diacr); | ||
| 1584 | return ret; | ||
| 1585 | } | ||
| 1586 | case KDGKBDIACRUC: | ||
| 1587 | { | ||
| 1588 | struct kbdiacrsuc __user *a = up; | ||
| 1589 | void *buf; | ||
| 1590 | |||
| 1591 | buf = kmalloc(MAX_DIACR * sizeof(struct kbdiacruc), | ||
| 1592 | GFP_KERNEL); | ||
| 1593 | if (buf == NULL) | ||
| 1594 | return -ENOMEM; | ||
| 1595 | |||
| 1596 | /* Lock the diacriticals table, make a copy and then | ||
| 1597 | copy it after we unlock */ | ||
| 1598 | spin_lock_irqsave(&kbd_event_lock, flags); | ||
| 1599 | |||
| 1600 | asize = accent_table_size; | ||
| 1601 | memcpy(buf, accent_table, asize * sizeof(struct kbdiacruc)); | ||
| 1602 | |||
| 1603 | spin_unlock_irqrestore(&kbd_event_lock, flags); | ||
| 1604 | |||
| 1605 | if (put_user(asize, &a->kb_cnt)) | ||
| 1606 | ret = -EFAULT; | ||
| 1607 | else if (copy_to_user(a->kbdiacruc, buf, | ||
| 1608 | asize*sizeof(struct kbdiacruc))) | ||
| 1609 | ret = -EFAULT; | ||
| 1610 | kfree(buf); | ||
| 1611 | return ret; | ||
| 1612 | } | ||
| 1613 | |||
| 1614 | case KDSKBDIACR: | ||
| 1615 | { | ||
| 1616 | struct kbdiacrs __user *a = up; | ||
| 1617 | struct kbdiacr *diacr = NULL; | ||
| 1618 | unsigned int ct; | ||
| 1619 | int i; | ||
| 1620 | |||
| 1621 | if (!perm) | ||
| 1622 | return -EPERM; | ||
| 1623 | if (get_user(ct, &a->kb_cnt)) | ||
| 1624 | return -EFAULT; | ||
| 1625 | if (ct >= MAX_DIACR) | ||
| 1626 | return -EINVAL; | ||
| 1627 | |||
| 1628 | if (ct) { | ||
| 1629 | diacr = kmalloc(sizeof(struct kbdiacr) * ct, | ||
| 1630 | GFP_KERNEL); | ||
| 1631 | if (diacr == NULL) | ||
| 1632 | return -ENOMEM; | ||
| 1633 | |||
| 1634 | if (copy_from_user(diacr, a->kbdiacr, | ||
| 1635 | sizeof(struct kbdiacr) * ct)) { | ||
| 1636 | kfree(diacr); | ||
| 1637 | return -EFAULT; | ||
| 1638 | } | ||
| 1639 | } | ||
| 1640 | |||
| 1641 | spin_lock_irqsave(&kbd_event_lock, flags); | ||
| 1642 | accent_table_size = ct; | ||
| 1643 | for (i = 0; i < ct; i++) { | ||
| 1644 | accent_table[i].diacr = | ||
| 1645 | conv_8bit_to_uni(diacr[i].diacr); | ||
| 1646 | accent_table[i].base = | ||
| 1647 | conv_8bit_to_uni(diacr[i].base); | ||
| 1648 | accent_table[i].result = | ||
| 1649 | conv_8bit_to_uni(diacr[i].result); | ||
| 1650 | } | ||
| 1651 | spin_unlock_irqrestore(&kbd_event_lock, flags); | ||
| 1652 | kfree(diacr); | ||
| 1653 | return 0; | ||
| 1654 | } | ||
| 1655 | |||
| 1656 | case KDSKBDIACRUC: | ||
| 1657 | { | ||
| 1658 | struct kbdiacrsuc __user *a = up; | ||
| 1659 | unsigned int ct; | ||
| 1660 | void *buf = NULL; | ||
| 1661 | |||
| 1662 | if (!perm) | ||
| 1663 | return -EPERM; | ||
| 1664 | |||
| 1665 | if (get_user(ct, &a->kb_cnt)) | ||
| 1666 | return -EFAULT; | ||
| 1667 | |||
| 1668 | if (ct >= MAX_DIACR) | ||
| 1669 | return -EINVAL; | ||
| 1670 | |||
| 1671 | if (ct) { | ||
| 1672 | buf = kmalloc(ct * sizeof(struct kbdiacruc), | ||
| 1673 | GFP_KERNEL); | ||
| 1674 | if (buf == NULL) | ||
| 1675 | return -ENOMEM; | ||
| 1676 | |||
| 1677 | if (copy_from_user(buf, a->kbdiacruc, | ||
| 1678 | ct * sizeof(struct kbdiacruc))) { | ||
| 1679 | kfree(buf); | ||
| 1680 | return -EFAULT; | ||
| 1681 | } | ||
| 1682 | } | ||
| 1683 | spin_lock_irqsave(&kbd_event_lock, flags); | ||
| 1684 | if (ct) | ||
| 1685 | memcpy(accent_table, buf, | ||
| 1686 | ct * sizeof(struct kbdiacruc)); | ||
| 1687 | accent_table_size = ct; | ||
| 1688 | spin_unlock_irqrestore(&kbd_event_lock, flags); | ||
| 1689 | kfree(buf); | ||
| 1690 | return 0; | ||
| 1691 | } | ||
| 1692 | } | ||
| 1693 | return ret; | ||
| 1694 | } | ||
| 1695 | |||
| 1696 | /** | ||
| 1697 | * vt_do_kdskbmode - set keyboard mode ioctl | ||
| 1698 | * @console: the console to use | ||
| 1699 | * @arg: the requested mode | ||
| 1700 | * | ||
| 1701 | * Update the keyboard mode bits while holding the correct locks. | ||
| 1702 | * Return 0 for success or an error code. | ||
| 1703 | */ | ||
| 1704 | int vt_do_kdskbmode(int console, unsigned int arg) | ||
| 1705 | { | ||
| 1706 | struct kbd_struct * kbd = kbd_table + console; | ||
| 1707 | int ret = 0; | ||
| 1708 | unsigned long flags; | ||
| 1709 | |||
| 1710 | spin_lock_irqsave(&kbd_event_lock, flags); | ||
| 1711 | switch(arg) { | ||
| 1712 | case K_RAW: | ||
| 1713 | kbd->kbdmode = VC_RAW; | ||
| 1714 | break; | ||
| 1715 | case K_MEDIUMRAW: | ||
| 1716 | kbd->kbdmode = VC_MEDIUMRAW; | ||
| 1717 | break; | ||
| 1718 | case K_XLATE: | ||
| 1719 | kbd->kbdmode = VC_XLATE; | ||
| 1720 | do_compute_shiftstate(); | ||
| 1721 | break; | ||
| 1722 | case K_UNICODE: | ||
| 1723 | kbd->kbdmode = VC_UNICODE; | ||
| 1724 | do_compute_shiftstate(); | ||
| 1725 | break; | ||
| 1726 | case K_OFF: | ||
| 1727 | kbd->kbdmode = VC_OFF; | ||
| 1728 | break; | ||
| 1729 | default: | ||
| 1730 | ret = -EINVAL; | ||
| 1731 | } | ||
| 1732 | spin_unlock_irqrestore(&kbd_event_lock, flags); | ||
| 1733 | return ret; | ||
| 1734 | } | ||
| 1735 | |||
| 1736 | /** | ||
| 1737 | * vt_do_kdskbmeta - set keyboard meta state | ||
| 1738 | * @console: the console to use | ||
| 1739 | * @arg: the requested meta state | ||
| 1740 | * | ||
| 1741 | * Update the keyboard meta bits while holding the correct locks. | ||
| 1742 | * Return 0 for success or an error code. | ||
| 1743 | */ | ||
| 1744 | int vt_do_kdskbmeta(int console, unsigned int arg) | ||
| 1745 | { | ||
| 1746 | struct kbd_struct * kbd = kbd_table + console; | ||
| 1747 | int ret = 0; | ||
| 1748 | unsigned long flags; | ||
| 1749 | |||
| 1750 | spin_lock_irqsave(&kbd_event_lock, flags); | ||
| 1751 | switch(arg) { | ||
| 1752 | case K_METABIT: | ||
| 1753 | clr_vc_kbd_mode(kbd, VC_META); | ||
| 1754 | break; | ||
| 1755 | case K_ESCPREFIX: | ||
| 1756 | set_vc_kbd_mode(kbd, VC_META); | ||
| 1757 | break; | ||
| 1758 | default: | ||
| 1759 | ret = -EINVAL; | ||
| 1760 | } | ||
| 1761 | spin_unlock_irqrestore(&kbd_event_lock, flags); | ||
| 1762 | return ret; | ||
| 1763 | } | ||
| 1764 | |||
| 1765 | int vt_do_kbkeycode_ioctl(int cmd, struct kbkeycode __user *user_kbkc, | ||
| 1766 | int perm) | ||
| 1767 | { | ||
| 1768 | struct kbkeycode tmp; | ||
| 1769 | int kc = 0; | ||
| 1770 | |||
| 1771 | if (copy_from_user(&tmp, user_kbkc, sizeof(struct kbkeycode))) | ||
| 1772 | return -EFAULT; | ||
| 1773 | switch (cmd) { | ||
| 1774 | case KDGETKEYCODE: | ||
| 1775 | kc = getkeycode(tmp.scancode); | ||
| 1776 | if (kc >= 0) | ||
| 1777 | kc = put_user(kc, &user_kbkc->keycode); | ||
| 1778 | break; | ||
| 1779 | case KDSETKEYCODE: | ||
| 1780 | if (!perm) | ||
| 1781 | return -EPERM; | ||
| 1782 | kc = setkeycode(tmp.scancode, tmp.keycode); | ||
| 1783 | break; | ||
| 1784 | } | ||
| 1785 | return kc; | ||
| 1786 | } | ||
| 1787 | |||
| 1788 | #define i (tmp.kb_index) | ||
| 1789 | #define s (tmp.kb_table) | ||
| 1790 | #define v (tmp.kb_value) | ||
| 1791 | |||
| 1792 | int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, | ||
| 1793 | int console) | ||
| 1794 | { | ||
| 1795 | struct kbd_struct * kbd = kbd_table + console; | ||
| 1796 | struct kbentry tmp; | ||
| 1797 | ushort *key_map, *new_map, val, ov; | ||
| 1798 | unsigned long flags; | ||
| 1799 | |||
| 1800 | if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry))) | ||
| 1801 | return -EFAULT; | ||
| 1802 | |||
| 1803 | if (!capable(CAP_SYS_TTY_CONFIG)) | ||
| 1804 | perm = 0; | ||
| 1805 | |||
| 1806 | switch (cmd) { | ||
| 1807 | case KDGKBENT: | ||
| 1808 | /* Ensure another thread doesn't free it under us */ | ||
| 1809 | spin_lock_irqsave(&kbd_event_lock, flags); | ||
| 1810 | key_map = key_maps[s]; | ||
| 1811 | if (key_map) { | ||
| 1812 | val = U(key_map[i]); | ||
| 1813 | if (kbd->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES) | ||
| 1814 | val = K_HOLE; | ||
| 1815 | } else | ||
| 1816 | val = (i ? K_HOLE : K_NOSUCHMAP); | ||
| 1817 | spin_unlock_irqrestore(&kbd_event_lock, flags); | ||
| 1818 | return put_user(val, &user_kbe->kb_value); | ||
| 1819 | case KDSKBENT: | ||
| 1820 | if (!perm) | ||
| 1821 | return -EPERM; | ||
| 1822 | if (!i && v == K_NOSUCHMAP) { | ||
| 1823 | spin_lock_irqsave(&kbd_event_lock, flags); | ||
| 1824 | /* deallocate map */ | ||
| 1825 | key_map = key_maps[s]; | ||
| 1826 | if (s && key_map) { | ||
| 1827 | key_maps[s] = NULL; | ||
| 1828 | if (key_map[0] == U(K_ALLOCATED)) { | ||
| 1829 | kfree(key_map); | ||
| 1830 | keymap_count--; | ||
| 1831 | } | ||
| 1832 | } | ||
| 1833 | spin_unlock_irqrestore(&kbd_event_lock, flags); | ||
| 1834 | break; | ||
| 1835 | } | ||
| 1836 | |||
| 1837 | if (KTYP(v) < NR_TYPES) { | ||
| 1838 | if (KVAL(v) > max_vals[KTYP(v)]) | ||
| 1839 | return -EINVAL; | ||
| 1840 | } else | ||
| 1841 | if (kbd->kbdmode != VC_UNICODE) | ||
| 1842 | return -EINVAL; | ||
| 1843 | |||
| 1844 | /* ++Geert: non-PC keyboards may generate keycode zero */ | ||
| 1845 | #if !defined(__mc68000__) && !defined(__powerpc__) | ||
| 1846 | /* assignment to entry 0 only tests validity of args */ | ||
| 1847 | if (!i) | ||
| 1848 | break; | ||
| 1849 | #endif | ||
| 1850 | |||
| 1851 | new_map = kmalloc(sizeof(plain_map), GFP_KERNEL); | ||
| 1852 | if (!new_map) | ||
| 1853 | return -ENOMEM; | ||
| 1854 | spin_lock_irqsave(&kbd_event_lock, flags); | ||
| 1855 | key_map = key_maps[s]; | ||
| 1856 | if (key_map == NULL) { | ||
| 1857 | int j; | ||
| 1858 | |||
| 1859 | if (keymap_count >= MAX_NR_OF_USER_KEYMAPS && | ||
| 1860 | !capable(CAP_SYS_RESOURCE)) { | ||
| 1861 | spin_unlock_irqrestore(&kbd_event_lock, flags); | ||
| 1862 | kfree(new_map); | ||
| 1863 | return -EPERM; | ||
| 1864 | } | ||
| 1865 | key_maps[s] = new_map; | ||
| 1866 | key_map = new_map; | ||
| 1867 | key_map[0] = U(K_ALLOCATED); | ||
| 1868 | for (j = 1; j < NR_KEYS; j++) | ||
| 1869 | key_map[j] = U(K_HOLE); | ||
| 1870 | keymap_count++; | ||
| 1871 | } else | ||
| 1872 | kfree(new_map); | ||
| 1873 | |||
| 1874 | ov = U(key_map[i]); | ||
| 1875 | if (v == ov) | ||
| 1876 | goto out; | ||
| 1877 | /* | ||
| 1878 | * Attention Key. | ||
| 1879 | */ | ||
| 1880 | if (((ov == K_SAK) || (v == K_SAK)) && !capable(CAP_SYS_ADMIN)) { | ||
| 1881 | spin_unlock_irqrestore(&kbd_event_lock, flags); | ||
| 1882 | return -EPERM; | ||
| 1883 | } | ||
| 1884 | key_map[i] = U(v); | ||
| 1885 | if (!s && (KTYP(ov) == KT_SHIFT || KTYP(v) == KT_SHIFT)) | ||
| 1886 | do_compute_shiftstate(); | ||
| 1887 | out: | ||
| 1888 | spin_unlock_irqrestore(&kbd_event_lock, flags); | ||
| 1889 | break; | ||
| 1890 | } | ||
| 1891 | return 0; | ||
| 1892 | } | ||
| 1893 | #undef i | ||
| 1894 | #undef s | ||
| 1895 | #undef v | ||
| 1896 | |||
| 1897 | /* FIXME: This one needs untangling and locking */ | ||
| 1898 | int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm) | ||
| 1899 | { | ||
| 1900 | struct kbsentry *kbs; | ||
| 1901 | char *p; | ||
| 1902 | u_char *q; | ||
| 1903 | u_char __user *up; | ||
| 1904 | int sz; | ||
| 1905 | int delta; | ||
| 1906 | char *first_free, *fj, *fnw; | ||
| 1907 | int i, j, k; | ||
| 1908 | int ret; | ||
| 1909 | |||
| 1910 | if (!capable(CAP_SYS_TTY_CONFIG)) | ||
| 1911 | perm = 0; | ||
| 1912 | |||
| 1913 | kbs = kmalloc(sizeof(*kbs), GFP_KERNEL); | ||
| 1914 | if (!kbs) { | ||
| 1915 | ret = -ENOMEM; | ||
| 1916 | goto reterr; | ||
| 1917 | } | ||
| 1918 | |||
| 1919 | /* we mostly copy too much here (512bytes), but who cares ;) */ | ||
| 1920 | if (copy_from_user(kbs, user_kdgkb, sizeof(struct kbsentry))) { | ||
| 1921 | ret = -EFAULT; | ||
| 1922 | goto reterr; | ||
| 1923 | } | ||
| 1924 | kbs->kb_string[sizeof(kbs->kb_string)-1] = '\0'; | ||
| 1925 | i = kbs->kb_func; | ||
| 1926 | |||
| 1927 | switch (cmd) { | ||
| 1928 | case KDGKBSENT: | ||
| 1929 | sz = sizeof(kbs->kb_string) - 1; /* sz should have been | ||
| 1930 | a struct member */ | ||
| 1931 | up = user_kdgkb->kb_string; | ||
| 1932 | p = func_table[i]; | ||
| 1933 | if(p) | ||
| 1934 | for ( ; *p && sz; p++, sz--) | ||
| 1935 | if (put_user(*p, up++)) { | ||
| 1936 | ret = -EFAULT; | ||
| 1937 | goto reterr; | ||
| 1938 | } | ||
| 1939 | if (put_user('\0', up)) { | ||
| 1940 | ret = -EFAULT; | ||
| 1941 | goto reterr; | ||
| 1942 | } | ||
| 1943 | kfree(kbs); | ||
| 1944 | return ((p && *p) ? -EOVERFLOW : 0); | ||
| 1945 | case KDSKBSENT: | ||
| 1946 | if (!perm) { | ||
| 1947 | ret = -EPERM; | ||
| 1948 | goto reterr; | ||
| 1949 | } | ||
| 1950 | |||
| 1951 | q = func_table[i]; | ||
| 1952 | first_free = funcbufptr + (funcbufsize - funcbufleft); | ||
| 1953 | for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++) | ||
| 1954 | ; | ||
| 1955 | if (j < MAX_NR_FUNC) | ||
| 1956 | fj = func_table[j]; | ||
| 1957 | else | ||
| 1958 | fj = first_free; | ||
| 1959 | |||
| 1960 | delta = (q ? -strlen(q) : 1) + strlen(kbs->kb_string); | ||
| 1961 | if (delta <= funcbufleft) { /* it fits in current buf */ | ||
| 1962 | if (j < MAX_NR_FUNC) { | ||
| 1963 | memmove(fj + delta, fj, first_free - fj); | ||
| 1964 | for (k = j; k < MAX_NR_FUNC; k++) | ||
| 1965 | if (func_table[k]) | ||
| 1966 | func_table[k] += delta; | ||
| 1967 | } | ||
| 1968 | if (!q) | ||
| 1969 | func_table[i] = fj; | ||
| 1970 | funcbufleft -= delta; | ||
| 1971 | } else { /* allocate a larger buffer */ | ||
| 1972 | sz = 256; | ||
| 1973 | while (sz < funcbufsize - funcbufleft + delta) | ||
| 1974 | sz <<= 1; | ||
| 1975 | fnw = kmalloc(sz, GFP_KERNEL); | ||
| 1976 | if(!fnw) { | ||
| 1977 | ret = -ENOMEM; | ||
| 1978 | goto reterr; | ||
| 1979 | } | ||
| 1980 | |||
| 1981 | if (!q) | ||
| 1982 | func_table[i] = fj; | ||
| 1983 | if (fj > funcbufptr) | ||
| 1984 | memmove(fnw, funcbufptr, fj - funcbufptr); | ||
| 1985 | for (k = 0; k < j; k++) | ||
| 1986 | if (func_table[k]) | ||
| 1987 | func_table[k] = fnw + (func_table[k] - funcbufptr); | ||
| 1988 | |||
| 1989 | if (first_free > fj) { | ||
| 1990 | memmove(fnw + (fj - funcbufptr) + delta, fj, first_free - fj); | ||
| 1991 | for (k = j; k < MAX_NR_FUNC; k++) | ||
| 1992 | if (func_table[k]) | ||
| 1993 | func_table[k] = fnw + (func_table[k] - funcbufptr) + delta; | ||
| 1994 | } | ||
| 1995 | if (funcbufptr != func_buf) | ||
| 1996 | kfree(funcbufptr); | ||
| 1997 | funcbufptr = fnw; | ||
| 1998 | funcbufleft = funcbufleft - delta + sz - funcbufsize; | ||
| 1999 | funcbufsize = sz; | ||
| 2000 | } | ||
| 2001 | strcpy(func_table[i], kbs->kb_string); | ||
| 2002 | break; | ||
| 2003 | } | ||
| 2004 | ret = 0; | ||
| 2005 | reterr: | ||
| 2006 | kfree(kbs); | ||
| 2007 | return ret; | ||
| 2008 | } | ||
| 2009 | |||
| 2010 | int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm) | ||
| 2011 | { | ||
| 2012 | struct kbd_struct * kbd = kbd_table + console; | ||
| 2013 | unsigned long flags; | ||
| 2014 | unsigned char ucval; | ||
| 2015 | |||
| 2016 | switch(cmd) { | ||
| 2017 | /* the ioctls below read/set the flags usually shown in the leds */ | ||
| 2018 | /* don't use them - they will go away without warning */ | ||
| 2019 | case KDGKBLED: | ||
| 2020 | spin_lock_irqsave(&kbd_event_lock, flags); | ||
| 2021 | ucval = kbd->ledflagstate | (kbd->default_ledflagstate << 4); | ||
| 2022 | spin_unlock_irqrestore(&kbd_event_lock, flags); | ||
| 2023 | return put_user(ucval, (char __user *)arg); | ||
| 2024 | |||
| 2025 | case KDSKBLED: | ||
| 2026 | if (!perm) | ||
| 2027 | return -EPERM; | ||
| 2028 | if (arg & ~0x77) | ||
| 2029 | return -EINVAL; | ||
| 2030 | spin_lock_irqsave(&kbd_event_lock, flags); | ||
| 2031 | kbd->ledflagstate = (arg & 7); | ||
| 2032 | kbd->default_ledflagstate = ((arg >> 4) & 7); | ||
| 2033 | set_leds(); | ||
| 2034 | spin_unlock_irqrestore(&kbd_event_lock, flags); | ||
| 2035 | break; | ||
| 2036 | |||
| 2037 | /* the ioctls below only set the lights, not the functions */ | ||
| 2038 | /* for those, see KDGKBLED and KDSKBLED above */ | ||
| 2039 | case KDGETLED: | ||
| 2040 | ucval = getledstate(); | ||
| 2041 | return put_user(ucval, (char __user *)arg); | ||
| 2042 | |||
| 2043 | case KDSETLED: | ||
| 2044 | if (!perm) | ||
| 2045 | return -EPERM; | ||
| 2046 | setledstate(kbd, arg); | ||
| 2047 | return 0; | ||
| 2048 | } | ||
| 2049 | return -ENOIOCTLCMD; | ||
| 2050 | } | ||
| 2051 | |||
| 2052 | int vt_do_kdgkbmode(int console) | ||
| 2053 | { | ||
| 2054 | struct kbd_struct * kbd = kbd_table + console; | ||
| 2055 | /* This is a spot read so needs no locking */ | ||
| 2056 | switch (kbd->kbdmode) { | ||
| 2057 | case VC_RAW: | ||
| 2058 | return K_RAW; | ||
| 2059 | case VC_MEDIUMRAW: | ||
| 2060 | return K_MEDIUMRAW; | ||
| 2061 | case VC_UNICODE: | ||
| 2062 | return K_UNICODE; | ||
| 2063 | case VC_OFF: | ||
| 2064 | return K_OFF; | ||
| 2065 | default: | ||
| 2066 | return K_XLATE; | ||
| 2067 | } | ||
| 2068 | } | ||
| 2069 | |||
| 2070 | /** | ||
| 2071 | * vt_do_kdgkbmeta - report meta status | ||
| 2072 | * @console: console to report | ||
| 2073 | * | ||
| 2074 | * Report the meta flag status of this console | ||
| 2075 | */ | ||
| 2076 | int vt_do_kdgkbmeta(int console) | ||
| 2077 | { | ||
| 2078 | struct kbd_struct * kbd = kbd_table + console; | ||
| 2079 | /* Again a spot read so no locking */ | ||
| 2080 | return vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT; | ||
| 2081 | } | ||
| 2082 | |||
| 2083 | /** | ||
| 2084 | * vt_reset_unicode - reset the unicode status | ||
| 2085 | * @console: console being reset | ||
| 2086 | * | ||
| 2087 | * Restore the unicode console state to its default | ||
| 2088 | */ | ||
| 2089 | void vt_reset_unicode(int console) | ||
| 2090 | { | ||
| 2091 | unsigned long flags; | ||
| 2092 | |||
| 2093 | spin_lock_irqsave(&kbd_event_lock, flags); | ||
| 2094 | kbd_table[console].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE; | ||
| 2095 | spin_unlock_irqrestore(&kbd_event_lock, flags); | ||
| 2096 | } | ||
| 2097 | |||
| 2098 | /** | ||
| 2099 | * vt_get_shiftstate - shift bit state | ||
| 2100 | * | ||
| 2101 | * Report the shift bits from the keyboard state. We have to export | ||
| 2102 | * this to support some oddities in the vt layer. | ||
| 2103 | */ | ||
| 2104 | int vt_get_shift_state(void) | ||
| 2105 | { | ||
| 2106 | /* Don't lock as this is a transient report */ | ||
| 2107 | return shift_state; | ||
| 2108 | } | ||
| 2109 | |||
| 2110 | /** | ||
| 2111 | * vt_reset_keyboard - reset keyboard state | ||
| 2112 | * @console: console to reset | ||
| 2113 | * | ||
| 2114 | * Reset the keyboard bits for a console as part of a general console | ||
| 2115 | * reset event | ||
| 2116 | */ | ||
| 2117 | void vt_reset_keyboard(int console) | ||
| 2118 | { | ||
| 2119 | struct kbd_struct * kbd = kbd_table + console; | ||
| 2120 | unsigned long flags; | ||
| 2121 | |||
| 2122 | spin_lock_irqsave(&kbd_event_lock, flags); | ||
| 2123 | set_vc_kbd_mode(kbd, VC_REPEAT); | ||
| 2124 | clr_vc_kbd_mode(kbd, VC_CKMODE); | ||
| 2125 | clr_vc_kbd_mode(kbd, VC_APPLIC); | ||
| 2126 | clr_vc_kbd_mode(kbd, VC_CRLF); | ||
| 2127 | kbd->lockstate = 0; | ||
| 2128 | kbd->slockstate = 0; | ||
| 2129 | kbd->ledmode = LED_SHOW_FLAGS; | ||
| 2130 | kbd->ledflagstate = kbd->default_ledflagstate; | ||
| 2131 | /* do not do set_leds here because this causes an endless tasklet loop | ||
| 2132 | when the keyboard hasn't been initialized yet */ | ||
| 2133 | spin_unlock_irqrestore(&kbd_event_lock, flags); | ||
| 2134 | } | ||
| 2135 | |||
| 2136 | /** | ||
| 2137 | * vt_get_kbd_mode_bit - read keyboard status bits | ||
| 2138 | * @console: console to read from | ||
| 2139 | * @bit: mode bit to read | ||
| 2140 | * | ||
| 2141 | * Report back a vt mode bit. We do this without locking so the | ||
| 2142 | * caller must be sure that there are no synchronization needs | ||
| 2143 | */ | ||
| 2144 | |||
| 2145 | int vt_get_kbd_mode_bit(int console, int bit) | ||
| 2146 | { | ||
| 2147 | struct kbd_struct * kbd = kbd_table + console; | ||
| 2148 | return vc_kbd_mode(kbd, bit); | ||
| 2149 | } | ||
| 2150 | |||
| 2151 | /** | ||
| 2152 | * vt_set_kbd_mode_bit - read keyboard status bits | ||
| 2153 | * @console: console to read from | ||
| 2154 | * @bit: mode bit to read | ||
| 2155 | * | ||
| 2156 | * Set a vt mode bit. We do this without locking so the | ||
| 2157 | * caller must be sure that there are no synchronization needs | ||
| 2158 | */ | ||
| 2159 | |||
| 2160 | void vt_set_kbd_mode_bit(int console, int bit) | ||
| 2161 | { | ||
| 2162 | struct kbd_struct * kbd = kbd_table + console; | ||
| 2163 | unsigned long flags; | ||
| 2164 | |||
| 2165 | spin_lock_irqsave(&kbd_event_lock, flags); | ||
| 2166 | set_vc_kbd_mode(kbd, bit); | ||
| 2167 | spin_unlock_irqrestore(&kbd_event_lock, flags); | ||
| 2168 | } | ||
| 2169 | |||
| 2170 | /** | ||
| 2171 | * vt_clr_kbd_mode_bit - read keyboard status bits | ||
| 2172 | * @console: console to read from | ||
| 2173 | * @bit: mode bit to read | ||
| 2174 | * | ||
| 2175 | * Report back a vt mode bit. We do this without locking so the | ||
| 2176 | * caller must be sure that there are no synchronization needs | ||
| 2177 | */ | ||
| 2178 | |||
| 2179 | void vt_clr_kbd_mode_bit(int console, int bit) | ||
| 2180 | { | ||
| 2181 | struct kbd_struct * kbd = kbd_table + console; | ||
| 2182 | unsigned long flags; | ||
| 2183 | |||
| 2184 | spin_lock_irqsave(&kbd_event_lock, flags); | ||
| 2185 | clr_vc_kbd_mode(kbd, bit); | ||
| 2186 | spin_unlock_irqrestore(&kbd_event_lock, flags); | ||
| 2187 | } | ||
diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c index 7a0a12ae5458..8e9b4be97a2d 100644 --- a/drivers/tty/vt/selection.c +++ b/drivers/tty/vt/selection.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | 30 | ||
| 31 | extern void poke_blanked_console(void); | 31 | extern void poke_blanked_console(void); |
| 32 | 32 | ||
| 33 | /* FIXME: all this needs locking */ | ||
| 33 | /* Variables for selection control. */ | 34 | /* Variables for selection control. */ |
| 34 | /* Use a dynamic buffer, instead of static (Dec 1994) */ | 35 | /* Use a dynamic buffer, instead of static (Dec 1994) */ |
| 35 | struct vc_data *sel_cons; /* must not be deallocated */ | 36 | struct vc_data *sel_cons; /* must not be deallocated */ |
| @@ -61,10 +62,14 @@ sel_pos(int n) | |||
| 61 | use_unicode); | 62 | use_unicode); |
| 62 | } | 63 | } |
| 63 | 64 | ||
| 64 | /* remove the current selection highlight, if any, | 65 | /** |
| 65 | from the console holding the selection. */ | 66 | * clear_selection - remove current selection |
| 66 | void | 67 | * |
| 67 | clear_selection(void) { | 68 | * Remove the current selection highlight, if any from the console |
| 69 | * holding the selection. The caller must hold the console lock. | ||
| 70 | */ | ||
| 71 | void clear_selection(void) | ||
| 72 | { | ||
| 68 | highlight_pointer(-1); /* hide the pointer */ | 73 | highlight_pointer(-1); /* hide the pointer */ |
| 69 | if (sel_start != -1) { | 74 | if (sel_start != -1) { |
| 70 | highlight(sel_start, sel_end); | 75 | highlight(sel_start, sel_end); |
| @@ -74,7 +79,7 @@ clear_selection(void) { | |||
| 74 | 79 | ||
| 75 | /* | 80 | /* |
| 76 | * User settable table: what characters are to be considered alphabetic? | 81 | * User settable table: what characters are to be considered alphabetic? |
| 77 | * 256 bits | 82 | * 256 bits. Locked by the console lock. |
| 78 | */ | 83 | */ |
| 79 | static u32 inwordLut[8]={ | 84 | static u32 inwordLut[8]={ |
| 80 | 0x00000000, /* control chars */ | 85 | 0x00000000, /* control chars */ |
| @@ -91,10 +96,20 @@ static inline int inword(const u16 c) { | |||
| 91 | return c > 0xff || (( inwordLut[c>>5] >> (c & 0x1F) ) & 1); | 96 | return c > 0xff || (( inwordLut[c>>5] >> (c & 0x1F) ) & 1); |
| 92 | } | 97 | } |
| 93 | 98 | ||
| 94 | /* set inwordLut contents. Invoked by ioctl(). */ | 99 | /** |
| 100 | * set loadlut - load the LUT table | ||
| 101 | * @p: user table | ||
| 102 | * | ||
| 103 | * Load the LUT table from user space. The caller must hold the console | ||
| 104 | * lock. Make a temporary copy so a partial update doesn't make a mess. | ||
| 105 | */ | ||
| 95 | int sel_loadlut(char __user *p) | 106 | int sel_loadlut(char __user *p) |
| 96 | { | 107 | { |
| 97 | return copy_from_user(inwordLut, (u32 __user *)(p+4), 32) ? -EFAULT : 0; | 108 | u32 tmplut[8]; |
| 109 | if (copy_from_user(tmplut, (u32 __user *)(p+4), 32)) | ||
| 110 | return -EFAULT; | ||
| 111 | memcpy(inwordLut, tmplut, 32); | ||
| 112 | return 0; | ||
| 98 | } | 113 | } |
| 99 | 114 | ||
| 100 | /* does screen address p correspond to character at LH/RH edge of screen? */ | 115 | /* does screen address p correspond to character at LH/RH edge of screen? */ |
| @@ -130,7 +145,16 @@ static int store_utf8(u16 c, char *p) | |||
| 130 | } | 145 | } |
| 131 | } | 146 | } |
| 132 | 147 | ||
| 133 | /* set the current selection. Invoked by ioctl() or by kernel code. */ | 148 | /** |
| 149 | * set_selection - set the current selection. | ||
| 150 | * @sel: user selection info | ||
| 151 | * @tty: the console tty | ||
| 152 | * | ||
| 153 | * Invoked by the ioctl handle for the vt layer. | ||
| 154 | * | ||
| 155 | * The entire selection process is managed under the console_lock. It's | ||
| 156 | * a lot under the lock but its hardly a performance path | ||
| 157 | */ | ||
| 134 | int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty) | 158 | int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty) |
| 135 | { | 159 | { |
| 136 | struct vc_data *vc = vc_cons[fg_console].d; | 160 | struct vc_data *vc = vc_cons[fg_console].d; |
| @@ -138,7 +162,7 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t | |||
| 138 | char *bp, *obp; | 162 | char *bp, *obp; |
| 139 | int i, ps, pe, multiplier; | 163 | int i, ps, pe, multiplier; |
| 140 | u16 c; | 164 | u16 c; |
| 141 | struct kbd_struct *kbd = kbd_table + fg_console; | 165 | int mode; |
| 142 | 166 | ||
| 143 | poke_blanked_console(); | 167 | poke_blanked_console(); |
| 144 | 168 | ||
| @@ -182,7 +206,11 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t | |||
| 182 | clear_selection(); | 206 | clear_selection(); |
| 183 | sel_cons = vc_cons[fg_console].d; | 207 | sel_cons = vc_cons[fg_console].d; |
| 184 | } | 208 | } |
| 185 | use_unicode = kbd && kbd->kbdmode == VC_UNICODE; | 209 | mode = vt_do_kdgkbmode(fg_console); |
| 210 | if (mode == K_UNICODE) | ||
| 211 | use_unicode = 1; | ||
| 212 | else | ||
| 213 | use_unicode = 0; | ||
| 186 | 214 | ||
| 187 | switch (sel_mode) | 215 | switch (sel_mode) |
| 188 | { | 216 | { |
| @@ -302,7 +330,8 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t | |||
| 302 | * queue of the tty associated with the current console. | 330 | * queue of the tty associated with the current console. |
| 303 | * Invoked by ioctl(). | 331 | * Invoked by ioctl(). |
| 304 | * | 332 | * |
| 305 | * Locking: always called with BTM from vt_ioctl | 333 | * Locking: called without locks. Calls the ldisc wrongly with |
| 334 | * unsafe methods, | ||
| 306 | */ | 335 | */ |
| 307 | int paste_selection(struct tty_struct *tty) | 336 | int paste_selection(struct tty_struct *tty) |
| 308 | { | 337 | { |
| @@ -317,13 +346,12 @@ int paste_selection(struct tty_struct *tty) | |||
| 317 | poke_blanked_console(); | 346 | poke_blanked_console(); |
| 318 | console_unlock(); | 347 | console_unlock(); |
| 319 | 348 | ||
| 349 | /* FIXME: wtf is this supposed to achieve ? */ | ||
| 320 | ld = tty_ldisc_ref(tty); | 350 | ld = tty_ldisc_ref(tty); |
| 321 | if (!ld) { | 351 | if (!ld) |
| 322 | tty_unlock(); | ||
| 323 | ld = tty_ldisc_ref_wait(tty); | 352 | ld = tty_ldisc_ref_wait(tty); |
| 324 | tty_lock(); | ||
| 325 | } | ||
| 326 | 353 | ||
| 354 | /* FIXME: this is completely unsafe */ | ||
| 327 | add_wait_queue(&vc->paste_wait, &wait); | 355 | add_wait_queue(&vc->paste_wait, &wait); |
| 328 | while (sel_buffer && sel_buffer_lth > pasted) { | 356 | while (sel_buffer && sel_buffer_lth > pasted) { |
| 329 | set_current_state(TASK_INTERRUPTIBLE); | 357 | set_current_state(TASK_INTERRUPTIBLE); |
diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index 7a367ff5122b..fa7268a93c06 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c | |||
| @@ -608,10 +608,10 @@ vcs_open(struct inode *inode, struct file *filp) | |||
| 608 | unsigned int currcons = iminor(inode) & 127; | 608 | unsigned int currcons = iminor(inode) & 127; |
| 609 | int ret = 0; | 609 | int ret = 0; |
| 610 | 610 | ||
| 611 | tty_lock(); | 611 | console_lock(); |
| 612 | if(currcons && !vc_cons_allocated(currcons-1)) | 612 | if(currcons && !vc_cons_allocated(currcons-1)) |
| 613 | ret = -ENXIO; | 613 | ret = -ENXIO; |
| 614 | tty_unlock(); | 614 | console_unlock(); |
| 615 | return ret; | 615 | return ret; |
| 616 | } | 616 | } |
| 617 | 617 | ||
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index e716839fab6e..84c4a7d5603e 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
| @@ -1028,9 +1028,9 @@ void vc_deallocate(unsigned int currcons) | |||
| 1028 | * VT102 emulator | 1028 | * VT102 emulator |
| 1029 | */ | 1029 | */ |
| 1030 | 1030 | ||
| 1031 | #define set_kbd(vc, x) set_vc_kbd_mode(kbd_table + (vc)->vc_num, (x)) | 1031 | #define set_kbd(vc, x) vt_set_kbd_mode_bit((vc)->vc_num, (x)) |
| 1032 | #define clr_kbd(vc, x) clr_vc_kbd_mode(kbd_table + (vc)->vc_num, (x)) | 1032 | #define clr_kbd(vc, x) vt_clr_kbd_mode_bit((vc)->vc_num, (x)) |
| 1033 | #define is_kbd(vc, x) vc_kbd_mode(kbd_table + (vc)->vc_num, (x)) | 1033 | #define is_kbd(vc, x) vt_get_kbd_mode_bit((vc)->vc_num, (x)) |
| 1034 | 1034 | ||
| 1035 | #define decarm VC_REPEAT | 1035 | #define decarm VC_REPEAT |
| 1036 | #define decckm VC_CKMODE | 1036 | #define decckm VC_CKMODE |
| @@ -1652,16 +1652,7 @@ static void reset_terminal(struct vc_data *vc, int do_clear) | |||
| 1652 | vc->vc_deccm = global_cursor_default; | 1652 | vc->vc_deccm = global_cursor_default; |
| 1653 | vc->vc_decim = 0; | 1653 | vc->vc_decim = 0; |
| 1654 | 1654 | ||
| 1655 | set_kbd(vc, decarm); | 1655 | vt_reset_keyboard(vc->vc_num); |
| 1656 | clr_kbd(vc, decckm); | ||
| 1657 | clr_kbd(vc, kbdapplic); | ||
| 1658 | clr_kbd(vc, lnm); | ||
| 1659 | kbd_table[vc->vc_num].lockstate = 0; | ||
| 1660 | kbd_table[vc->vc_num].slockstate = 0; | ||
| 1661 | kbd_table[vc->vc_num].ledmode = LED_SHOW_FLAGS; | ||
| 1662 | kbd_table[vc->vc_num].ledflagstate = kbd_table[vc->vc_num].default_ledflagstate; | ||
| 1663 | /* do not do set_leds here because this causes an endless tasklet loop | ||
| 1664 | when the keyboard hasn't been initialized yet */ | ||
| 1665 | 1656 | ||
| 1666 | vc->vc_cursor_type = cur_default; | 1657 | vc->vc_cursor_type = cur_default; |
| 1667 | vc->vc_complement_mask = vc->vc_s_complement_mask; | 1658 | vc->vc_complement_mask = vc->vc_s_complement_mask; |
| @@ -1979,7 +1970,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) | |||
| 1979 | case 'q': /* DECLL - but only 3 leds */ | 1970 | case 'q': /* DECLL - but only 3 leds */ |
| 1980 | /* map 0,1,2,3 to 0,1,2,4 */ | 1971 | /* map 0,1,2,3 to 0,1,2,4 */ |
| 1981 | if (vc->vc_par[0] < 4) | 1972 | if (vc->vc_par[0] < 4) |
| 1982 | setledstate(kbd_table + vc->vc_num, | 1973 | vt_set_led_state(vc->vc_num, |
| 1983 | (vc->vc_par[0] < 3) ? vc->vc_par[0] : 4); | 1974 | (vc->vc_par[0] < 3) ? vc->vc_par[0] : 4); |
| 1984 | return; | 1975 | return; |
| 1985 | case 'r': | 1976 | case 'r': |
| @@ -2632,7 +2623,9 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) | |||
| 2632 | console_unlock(); | 2623 | console_unlock(); |
| 2633 | break; | 2624 | break; |
| 2634 | case TIOCL_SELLOADLUT: | 2625 | case TIOCL_SELLOADLUT: |
| 2626 | console_lock(); | ||
| 2635 | ret = sel_loadlut(p); | 2627 | ret = sel_loadlut(p); |
| 2628 | console_unlock(); | ||
| 2636 | break; | 2629 | break; |
| 2637 | case TIOCL_GETSHIFTSTATE: | 2630 | case TIOCL_GETSHIFTSTATE: |
| 2638 | 2631 | ||
| @@ -2642,15 +2635,19 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) | |||
| 2642 | * kernel-internal variable; programs not closely | 2635 | * kernel-internal variable; programs not closely |
| 2643 | * related to the kernel should not use this. | 2636 | * related to the kernel should not use this. |
| 2644 | */ | 2637 | */ |
| 2645 | data = shift_state; | 2638 | data = vt_get_shift_state(); |
| 2646 | ret = __put_user(data, p); | 2639 | ret = __put_user(data, p); |
| 2647 | break; | 2640 | break; |
| 2648 | case TIOCL_GETMOUSEREPORTING: | 2641 | case TIOCL_GETMOUSEREPORTING: |
| 2642 | console_lock(); /* May be overkill */ | ||
| 2649 | data = mouse_reporting(); | 2643 | data = mouse_reporting(); |
| 2644 | console_unlock(); | ||
| 2650 | ret = __put_user(data, p); | 2645 | ret = __put_user(data, p); |
| 2651 | break; | 2646 | break; |
| 2652 | case TIOCL_SETVESABLANK: | 2647 | case TIOCL_SETVESABLANK: |
| 2648 | console_lock(); | ||
| 2653 | ret = set_vesa_blanking(p); | 2649 | ret = set_vesa_blanking(p); |
| 2650 | console_unlock(); | ||
| 2654 | break; | 2651 | break; |
| 2655 | case TIOCL_GETKMSGREDIRECT: | 2652 | case TIOCL_GETKMSGREDIRECT: |
| 2656 | data = vt_get_kmsg_redirect(); | 2653 | data = vt_get_kmsg_redirect(); |
| @@ -2667,13 +2664,21 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) | |||
| 2667 | } | 2664 | } |
| 2668 | break; | 2665 | break; |
| 2669 | case TIOCL_GETFGCONSOLE: | 2666 | case TIOCL_GETFGCONSOLE: |
| 2667 | /* No locking needed as this is a transiently | ||
| 2668 | correct return anyway if the caller hasn't | ||
| 2669 | disabled switching */ | ||
| 2670 | ret = fg_console; | 2670 | ret = fg_console; |
| 2671 | break; | 2671 | break; |
| 2672 | case TIOCL_SCROLLCONSOLE: | 2672 | case TIOCL_SCROLLCONSOLE: |
| 2673 | if (get_user(lines, (s32 __user *)(p+4))) { | 2673 | if (get_user(lines, (s32 __user *)(p+4))) { |
| 2674 | ret = -EFAULT; | 2674 | ret = -EFAULT; |
| 2675 | } else { | 2675 | } else { |
| 2676 | /* Need the console lock here. Note that lots | ||
| 2677 | of other calls need fixing before the lock | ||
| 2678 | is actually useful ! */ | ||
| 2679 | console_lock(); | ||
| 2676 | scrollfront(vc_cons[fg_console].d, lines); | 2680 | scrollfront(vc_cons[fg_console].d, lines); |
| 2681 | console_unlock(); | ||
| 2677 | ret = 0; | 2682 | ret = 0; |
| 2678 | } | 2683 | } |
| 2679 | break; | 2684 | break; |
| @@ -2753,8 +2758,7 @@ static void con_stop(struct tty_struct *tty) | |||
| 2753 | console_num = tty->index; | 2758 | console_num = tty->index; |
| 2754 | if (!vc_cons_allocated(console_num)) | 2759 | if (!vc_cons_allocated(console_num)) |
| 2755 | return; | 2760 | return; |
| 2756 | set_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK); | 2761 | vt_kbd_con_stop(console_num); |
| 2757 | set_leds(); | ||
| 2758 | } | 2762 | } |
| 2759 | 2763 | ||
| 2760 | /* | 2764 | /* |
| @@ -2768,8 +2772,7 @@ static void con_start(struct tty_struct *tty) | |||
| 2768 | console_num = tty->index; | 2772 | console_num = tty->index; |
| 2769 | if (!vc_cons_allocated(console_num)) | 2773 | if (!vc_cons_allocated(console_num)) |
| 2770 | return; | 2774 | return; |
| 2771 | clr_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK); | 2775 | vt_kbd_con_start(console_num); |
| 2772 | set_leds(); | ||
| 2773 | } | 2776 | } |
| 2774 | 2777 | ||
| 2775 | static void con_flush_chars(struct tty_struct *tty) | 2778 | static void con_flush_chars(struct tty_struct *tty) |
| @@ -2991,7 +2994,7 @@ int __init vty_init(const struct file_operations *console_fops) | |||
| 2991 | console_driver = alloc_tty_driver(MAX_NR_CONSOLES); | 2994 | console_driver = alloc_tty_driver(MAX_NR_CONSOLES); |
| 2992 | if (!console_driver) | 2995 | if (!console_driver) |
| 2993 | panic("Couldn't allocate console driver\n"); | 2996 | panic("Couldn't allocate console driver\n"); |
| 2994 | console_driver->owner = THIS_MODULE; | 2997 | |
| 2995 | console_driver->name = "tty"; | 2998 | console_driver->name = "tty"; |
| 2996 | console_driver->name_base = 1; | 2999 | console_driver->name_base = 1; |
| 2997 | console_driver->major = TTY_MAJOR; | 3000 | console_driver->major = TTY_MAJOR; |
| @@ -3980,9 +3983,6 @@ static int con_font_get(struct vc_data *vc, struct console_font_op *op) | |||
| 3980 | int rc = -EINVAL; | 3983 | int rc = -EINVAL; |
| 3981 | int c; | 3984 | int c; |
| 3982 | 3985 | ||
| 3983 | if (vc->vc_mode != KD_TEXT) | ||
| 3984 | return -EINVAL; | ||
| 3985 | |||
| 3986 | if (op->data) { | 3986 | if (op->data) { |
| 3987 | font.data = kmalloc(max_font_size, GFP_KERNEL); | 3987 | font.data = kmalloc(max_font_size, GFP_KERNEL); |
| 3988 | if (!font.data) | 3988 | if (!font.data) |
| @@ -3991,7 +3991,9 @@ static int con_font_get(struct vc_data *vc, struct console_font_op *op) | |||
| 3991 | font.data = NULL; | 3991 | font.data = NULL; |
| 3992 | 3992 | ||
| 3993 | console_lock(); | 3993 | console_lock(); |
| 3994 | if (vc->vc_sw->con_font_get) | 3994 | if (vc->vc_mode != KD_TEXT) |
| 3995 | rc = -EINVAL; | ||
| 3996 | else if (vc->vc_sw->con_font_get) | ||
| 3995 | rc = vc->vc_sw->con_font_get(vc, &font); | 3997 | rc = vc->vc_sw->con_font_get(vc, &font); |
| 3996 | else | 3998 | else |
| 3997 | rc = -ENOSYS; | 3999 | rc = -ENOSYS; |
| @@ -4073,7 +4075,9 @@ static int con_font_set(struct vc_data *vc, struct console_font_op *op) | |||
| 4073 | if (IS_ERR(font.data)) | 4075 | if (IS_ERR(font.data)) |
| 4074 | return PTR_ERR(font.data); | 4076 | return PTR_ERR(font.data); |
| 4075 | console_lock(); | 4077 | console_lock(); |
| 4076 | if (vc->vc_sw->con_font_set) | 4078 | if (vc->vc_mode != KD_TEXT) |
| 4079 | rc = -EINVAL; | ||
| 4080 | else if (vc->vc_sw->con_font_set) | ||
| 4077 | rc = vc->vc_sw->con_font_set(vc, &font, op->flags); | 4081 | rc = vc->vc_sw->con_font_set(vc, &font, op->flags); |
| 4078 | else | 4082 | else |
| 4079 | rc = -ENOSYS; | 4083 | rc = -ENOSYS; |
| @@ -4089,8 +4093,6 @@ static int con_font_default(struct vc_data *vc, struct console_font_op *op) | |||
| 4089 | char *s = name; | 4093 | char *s = name; |
| 4090 | int rc; | 4094 | int rc; |
| 4091 | 4095 | ||
| 4092 | if (vc->vc_mode != KD_TEXT) | ||
| 4093 | return -EINVAL; | ||
| 4094 | 4096 | ||
| 4095 | if (!op->data) | 4097 | if (!op->data) |
| 4096 | s = NULL; | 4098 | s = NULL; |
| @@ -4100,6 +4102,10 @@ static int con_font_default(struct vc_data *vc, struct console_font_op *op) | |||
| 4100 | name[MAX_FONT_NAME - 1] = 0; | 4102 | name[MAX_FONT_NAME - 1] = 0; |
| 4101 | 4103 | ||
| 4102 | console_lock(); | 4104 | console_lock(); |
| 4105 | if (vc->vc_mode != KD_TEXT) { | ||
| 4106 | console_unlock(); | ||
| 4107 | return -EINVAL; | ||
| 4108 | } | ||
| 4103 | if (vc->vc_sw->con_font_default) | 4109 | if (vc->vc_sw->con_font_default) |
| 4104 | rc = vc->vc_sw->con_font_default(vc, &font, s); | 4110 | rc = vc->vc_sw->con_font_default(vc, &font, s); |
| 4105 | else | 4111 | else |
| @@ -4117,11 +4123,11 @@ static int con_font_copy(struct vc_data *vc, struct console_font_op *op) | |||
| 4117 | int con = op->height; | 4123 | int con = op->height; |
| 4118 | int rc; | 4124 | int rc; |
| 4119 | 4125 | ||
| 4120 | if (vc->vc_mode != KD_TEXT) | ||
| 4121 | return -EINVAL; | ||
| 4122 | 4126 | ||
| 4123 | console_lock(); | 4127 | console_lock(); |
| 4124 | if (!vc->vc_sw->con_font_copy) | 4128 | if (vc->vc_mode != KD_TEXT) |
| 4129 | rc = -EINVAL; | ||
| 4130 | else if (!vc->vc_sw->con_font_copy) | ||
| 4125 | rc = -ENOSYS; | 4131 | rc = -ENOSYS; |
| 4126 | else if (con < 0 || !vc_cons_allocated(con)) | 4132 | else if (con < 0 || !vc_cons_allocated(con)) |
| 4127 | rc = -ENOTTY; | 4133 | rc = -ENOTTY; |
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 65447c5f91d7..ede2ef18d2fb 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c | |||
| @@ -130,7 +130,7 @@ static void vt_event_wait(struct vt_event_wait *vw) | |||
| 130 | list_add(&vw->list, &vt_events); | 130 | list_add(&vw->list, &vt_events); |
| 131 | spin_unlock_irqrestore(&vt_event_lock, flags); | 131 | spin_unlock_irqrestore(&vt_event_lock, flags); |
| 132 | /* Wait for it to pass */ | 132 | /* Wait for it to pass */ |
| 133 | wait_event_interruptible_tty(vt_event_waitqueue, vw->done); | 133 | wait_event_interruptible(vt_event_waitqueue, vw->done); |
| 134 | /* Dequeue it */ | 134 | /* Dequeue it */ |
| 135 | spin_lock_irqsave(&vt_event_lock, flags); | 135 | spin_lock_irqsave(&vt_event_lock, flags); |
| 136 | list_del(&vw->list); | 136 | list_del(&vw->list); |
| @@ -195,232 +195,7 @@ int vt_waitactive(int n) | |||
| 195 | #define GPLAST 0x3df | 195 | #define GPLAST 0x3df |
| 196 | #define GPNUM (GPLAST - GPFIRST + 1) | 196 | #define GPNUM (GPLAST - GPFIRST + 1) |
| 197 | 197 | ||
| 198 | #define i (tmp.kb_index) | ||
| 199 | #define s (tmp.kb_table) | ||
| 200 | #define v (tmp.kb_value) | ||
| 201 | static inline int | ||
| 202 | do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, struct kbd_struct *kbd) | ||
| 203 | { | ||
| 204 | struct kbentry tmp; | ||
| 205 | ushort *key_map, val, ov; | ||
| 206 | |||
| 207 | if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry))) | ||
| 208 | return -EFAULT; | ||
| 209 | 198 | ||
| 210 | if (!capable(CAP_SYS_TTY_CONFIG)) | ||
| 211 | perm = 0; | ||
| 212 | |||
| 213 | switch (cmd) { | ||
| 214 | case KDGKBENT: | ||
| 215 | key_map = key_maps[s]; | ||
| 216 | if (key_map) { | ||
| 217 | val = U(key_map[i]); | ||
| 218 | if (kbd->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES) | ||
| 219 | val = K_HOLE; | ||
| 220 | } else | ||
| 221 | val = (i ? K_HOLE : K_NOSUCHMAP); | ||
| 222 | return put_user(val, &user_kbe->kb_value); | ||
| 223 | case KDSKBENT: | ||
| 224 | if (!perm) | ||
| 225 | return -EPERM; | ||
| 226 | if (!i && v == K_NOSUCHMAP) { | ||
| 227 | /* deallocate map */ | ||
| 228 | key_map = key_maps[s]; | ||
| 229 | if (s && key_map) { | ||
| 230 | key_maps[s] = NULL; | ||
| 231 | if (key_map[0] == U(K_ALLOCATED)) { | ||
| 232 | kfree(key_map); | ||
| 233 | keymap_count--; | ||
| 234 | } | ||
| 235 | } | ||
| 236 | break; | ||
| 237 | } | ||
| 238 | |||
| 239 | if (KTYP(v) < NR_TYPES) { | ||
| 240 | if (KVAL(v) > max_vals[KTYP(v)]) | ||
| 241 | return -EINVAL; | ||
| 242 | } else | ||
| 243 | if (kbd->kbdmode != VC_UNICODE) | ||
| 244 | return -EINVAL; | ||
| 245 | |||
| 246 | /* ++Geert: non-PC keyboards may generate keycode zero */ | ||
| 247 | #if !defined(__mc68000__) && !defined(__powerpc__) | ||
| 248 | /* assignment to entry 0 only tests validity of args */ | ||
| 249 | if (!i) | ||
| 250 | break; | ||
| 251 | #endif | ||
| 252 | |||
| 253 | if (!(key_map = key_maps[s])) { | ||
| 254 | int j; | ||
| 255 | |||
| 256 | if (keymap_count >= MAX_NR_OF_USER_KEYMAPS && | ||
| 257 | !capable(CAP_SYS_RESOURCE)) | ||
| 258 | return -EPERM; | ||
| 259 | |||
| 260 | key_map = kmalloc(sizeof(plain_map), | ||
| 261 | GFP_KERNEL); | ||
| 262 | if (!key_map) | ||
| 263 | return -ENOMEM; | ||
| 264 | key_maps[s] = key_map; | ||
| 265 | key_map[0] = U(K_ALLOCATED); | ||
| 266 | for (j = 1; j < NR_KEYS; j++) | ||
| 267 | key_map[j] = U(K_HOLE); | ||
| 268 | keymap_count++; | ||
| 269 | } | ||
| 270 | ov = U(key_map[i]); | ||
| 271 | if (v == ov) | ||
| 272 | break; /* nothing to do */ | ||
| 273 | /* | ||
| 274 | * Attention Key. | ||
| 275 | */ | ||
| 276 | if (((ov == K_SAK) || (v == K_SAK)) && !capable(CAP_SYS_ADMIN)) | ||
| 277 | return -EPERM; | ||
| 278 | key_map[i] = U(v); | ||
| 279 | if (!s && (KTYP(ov) == KT_SHIFT || KTYP(v) == KT_SHIFT)) | ||
| 280 | compute_shiftstate(); | ||
| 281 | break; | ||
| 282 | } | ||
| 283 | return 0; | ||
| 284 | } | ||
| 285 | #undef i | ||
| 286 | #undef s | ||
| 287 | #undef v | ||
| 288 | |||
| 289 | static inline int | ||
| 290 | do_kbkeycode_ioctl(int cmd, struct kbkeycode __user *user_kbkc, int perm) | ||
| 291 | { | ||
| 292 | struct kbkeycode tmp; | ||
| 293 | int kc = 0; | ||
| 294 | |||
| 295 | if (copy_from_user(&tmp, user_kbkc, sizeof(struct kbkeycode))) | ||
| 296 | return -EFAULT; | ||
| 297 | switch (cmd) { | ||
| 298 | case KDGETKEYCODE: | ||
| 299 | kc = getkeycode(tmp.scancode); | ||
| 300 | if (kc >= 0) | ||
| 301 | kc = put_user(kc, &user_kbkc->keycode); | ||
| 302 | break; | ||
| 303 | case KDSETKEYCODE: | ||
| 304 | if (!perm) | ||
| 305 | return -EPERM; | ||
| 306 | kc = setkeycode(tmp.scancode, tmp.keycode); | ||
| 307 | break; | ||
| 308 | } | ||
| 309 | return kc; | ||
| 310 | } | ||
| 311 | |||
| 312 | static inline int | ||
| 313 | do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm) | ||
| 314 | { | ||
| 315 | struct kbsentry *kbs; | ||
| 316 | char *p; | ||
| 317 | u_char *q; | ||
| 318 | u_char __user *up; | ||
| 319 | int sz; | ||
| 320 | int delta; | ||
| 321 | char *first_free, *fj, *fnw; | ||
| 322 | int i, j, k; | ||
| 323 | int ret; | ||
| 324 | |||
| 325 | if (!capable(CAP_SYS_TTY_CONFIG)) | ||
| 326 | perm = 0; | ||
| 327 | |||
| 328 | kbs = kmalloc(sizeof(*kbs), GFP_KERNEL); | ||
| 329 | if (!kbs) { | ||
| 330 | ret = -ENOMEM; | ||
| 331 | goto reterr; | ||
| 332 | } | ||
| 333 | |||
| 334 | /* we mostly copy too much here (512bytes), but who cares ;) */ | ||
| 335 | if (copy_from_user(kbs, user_kdgkb, sizeof(struct kbsentry))) { | ||
| 336 | ret = -EFAULT; | ||
| 337 | goto reterr; | ||
| 338 | } | ||
| 339 | kbs->kb_string[sizeof(kbs->kb_string)-1] = '\0'; | ||
| 340 | i = kbs->kb_func; | ||
| 341 | |||
| 342 | switch (cmd) { | ||
| 343 | case KDGKBSENT: | ||
| 344 | sz = sizeof(kbs->kb_string) - 1; /* sz should have been | ||
| 345 | a struct member */ | ||
| 346 | up = user_kdgkb->kb_string; | ||
| 347 | p = func_table[i]; | ||
| 348 | if(p) | ||
| 349 | for ( ; *p && sz; p++, sz--) | ||
| 350 | if (put_user(*p, up++)) { | ||
| 351 | ret = -EFAULT; | ||
| 352 | goto reterr; | ||
| 353 | } | ||
| 354 | if (put_user('\0', up)) { | ||
| 355 | ret = -EFAULT; | ||
| 356 | goto reterr; | ||
| 357 | } | ||
| 358 | kfree(kbs); | ||
| 359 | return ((p && *p) ? -EOVERFLOW : 0); | ||
| 360 | case KDSKBSENT: | ||
| 361 | if (!perm) { | ||
| 362 | ret = -EPERM; | ||
| 363 | goto reterr; | ||
| 364 | } | ||
| 365 | |||
| 366 | q = func_table[i]; | ||
| 367 | first_free = funcbufptr + (funcbufsize - funcbufleft); | ||
| 368 | for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++) | ||
| 369 | ; | ||
| 370 | if (j < MAX_NR_FUNC) | ||
| 371 | fj = func_table[j]; | ||
| 372 | else | ||
| 373 | fj = first_free; | ||
| 374 | |||
| 375 | delta = (q ? -strlen(q) : 1) + strlen(kbs->kb_string); | ||
| 376 | if (delta <= funcbufleft) { /* it fits in current buf */ | ||
| 377 | if (j < MAX_NR_FUNC) { | ||
| 378 | memmove(fj + delta, fj, first_free - fj); | ||
| 379 | for (k = j; k < MAX_NR_FUNC; k++) | ||
| 380 | if (func_table[k]) | ||
| 381 | func_table[k] += delta; | ||
| 382 | } | ||
| 383 | if (!q) | ||
| 384 | func_table[i] = fj; | ||
| 385 | funcbufleft -= delta; | ||
| 386 | } else { /* allocate a larger buffer */ | ||
| 387 | sz = 256; | ||
| 388 | while (sz < funcbufsize - funcbufleft + delta) | ||
| 389 | sz <<= 1; | ||
| 390 | fnw = kmalloc(sz, GFP_KERNEL); | ||
| 391 | if(!fnw) { | ||
| 392 | ret = -ENOMEM; | ||
| 393 | goto reterr; | ||
| 394 | } | ||
| 395 | |||
| 396 | if (!q) | ||
| 397 | func_table[i] = fj; | ||
| 398 | if (fj > funcbufptr) | ||
| 399 | memmove(fnw, funcbufptr, fj - funcbufptr); | ||
| 400 | for (k = 0; k < j; k++) | ||
| 401 | if (func_table[k]) | ||
| 402 | func_table[k] = fnw + (func_table[k] - funcbufptr); | ||
| 403 | |||
| 404 | if (first_free > fj) { | ||
| 405 | memmove(fnw + (fj - funcbufptr) + delta, fj, first_free - fj); | ||
| 406 | for (k = j; k < MAX_NR_FUNC; k++) | ||
| 407 | if (func_table[k]) | ||
| 408 | func_table[k] = fnw + (func_table[k] - funcbufptr) + delta; | ||
| 409 | } | ||
| 410 | if (funcbufptr != func_buf) | ||
| 411 | kfree(funcbufptr); | ||
| 412 | funcbufptr = fnw; | ||
| 413 | funcbufleft = funcbufleft - delta + sz - funcbufsize; | ||
| 414 | funcbufsize = sz; | ||
| 415 | } | ||
| 416 | strcpy(func_table[i], kbs->kb_string); | ||
| 417 | break; | ||
| 418 | } | ||
| 419 | ret = 0; | ||
| 420 | reterr: | ||
| 421 | kfree(kbs); | ||
| 422 | return ret; | ||
| 423 | } | ||
| 424 | 199 | ||
| 425 | static inline int | 200 | static inline int |
| 426 | do_fontx_ioctl(int cmd, struct consolefontdesc __user *user_cfd, int perm, struct console_font_op *op) | 201 | do_fontx_ioctl(int cmd, struct consolefontdesc __user *user_cfd, int perm, struct console_font_op *op) |
| @@ -497,7 +272,6 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 497 | { | 272 | { |
| 498 | struct vc_data *vc = tty->driver_data; | 273 | struct vc_data *vc = tty->driver_data; |
| 499 | struct console_font_op op; /* used in multiple places here */ | 274 | struct console_font_op op; /* used in multiple places here */ |
| 500 | struct kbd_struct * kbd; | ||
| 501 | unsigned int console; | 275 | unsigned int console; |
| 502 | unsigned char ucval; | 276 | unsigned char ucval; |
| 503 | unsigned int uival; | 277 | unsigned int uival; |
| @@ -507,7 +281,6 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 507 | 281 | ||
| 508 | console = vc->vc_num; | 282 | console = vc->vc_num; |
| 509 | 283 | ||
| 510 | tty_lock(); | ||
| 511 | 284 | ||
| 512 | if (!vc_cons_allocated(console)) { /* impossible? */ | 285 | if (!vc_cons_allocated(console)) { /* impossible? */ |
| 513 | ret = -ENOIOCTLCMD; | 286 | ret = -ENOIOCTLCMD; |
| @@ -523,19 +296,18 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 523 | if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG)) | 296 | if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG)) |
| 524 | perm = 1; | 297 | perm = 1; |
| 525 | 298 | ||
| 526 | kbd = kbd_table + console; | ||
| 527 | switch (cmd) { | 299 | switch (cmd) { |
| 528 | case TIOCLINUX: | 300 | case TIOCLINUX: |
| 529 | ret = tioclinux(tty, arg); | 301 | ret = tioclinux(tty, arg); |
| 530 | break; | 302 | break; |
| 531 | case KIOCSOUND: | 303 | case KIOCSOUND: |
| 532 | if (!perm) | 304 | if (!perm) |
| 533 | goto eperm; | 305 | return -EPERM; |
| 534 | /* | 306 | /* |
| 535 | * The use of PIT_TICK_RATE is historic, it used to be | 307 | * The use of PIT_TICK_RATE is historic, it used to be |
| 536 | * the platform-dependent CLOCK_TICK_RATE between 2.6.12 | 308 | * the platform-dependent CLOCK_TICK_RATE between 2.6.12 |
| 537 | * and 2.6.36, which was a minor but unfortunate ABI | 309 | * and 2.6.36, which was a minor but unfortunate ABI |
| 538 | * change. | 310 | * change. kd_mksound is locked by the input layer. |
| 539 | */ | 311 | */ |
| 540 | if (arg) | 312 | if (arg) |
| 541 | arg = PIT_TICK_RATE / arg; | 313 | arg = PIT_TICK_RATE / arg; |
| @@ -544,7 +316,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 544 | 316 | ||
| 545 | case KDMKTONE: | 317 | case KDMKTONE: |
| 546 | if (!perm) | 318 | if (!perm) |
| 547 | goto eperm; | 319 | return -EPERM; |
| 548 | { | 320 | { |
| 549 | unsigned int ticks, count; | 321 | unsigned int ticks, count; |
| 550 | 322 | ||
| @@ -562,10 +334,11 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 562 | 334 | ||
| 563 | case KDGKBTYPE: | 335 | case KDGKBTYPE: |
| 564 | /* | 336 | /* |
| 565 | * this is naive. | 337 | * this is naïve. |
| 566 | */ | 338 | */ |
| 567 | ucval = KB_101; | 339 | ucval = KB_101; |
| 568 | goto setchar; | 340 | ret = put_user(ucval, (char __user *)arg); |
| 341 | break; | ||
| 569 | 342 | ||
| 570 | /* | 343 | /* |
| 571 | * These cannot be implemented on any machine that implements | 344 | * These cannot be implemented on any machine that implements |
| @@ -579,6 +352,8 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 579 | /* | 352 | /* |
| 580 | * KDADDIO and KDDELIO may be able to add ports beyond what | 353 | * KDADDIO and KDDELIO may be able to add ports beyond what |
| 581 | * we reject here, but to be safe... | 354 | * we reject here, but to be safe... |
| 355 | * | ||
| 356 | * These are locked internally via sys_ioperm | ||
| 582 | */ | 357 | */ |
| 583 | if (arg < GPFIRST || arg > GPLAST) { | 358 | if (arg < GPFIRST || arg > GPLAST) { |
| 584 | ret = -EINVAL; | 359 | ret = -EINVAL; |
| @@ -601,7 +376,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 601 | struct kbd_repeat kbrep; | 376 | struct kbd_repeat kbrep; |
| 602 | 377 | ||
| 603 | if (!capable(CAP_SYS_TTY_CONFIG)) | 378 | if (!capable(CAP_SYS_TTY_CONFIG)) |
| 604 | goto eperm; | 379 | return -EPERM; |
| 605 | 380 | ||
| 606 | if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat))) { | 381 | if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat))) { |
| 607 | ret = -EFAULT; | 382 | ret = -EFAULT; |
| @@ -625,7 +400,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 625 | * need to restore their engine state. --BenH | 400 | * need to restore their engine state. --BenH |
| 626 | */ | 401 | */ |
| 627 | if (!perm) | 402 | if (!perm) |
| 628 | goto eperm; | 403 | return -EPERM; |
| 629 | switch (arg) { | 404 | switch (arg) { |
| 630 | case KD_GRAPHICS: | 405 | case KD_GRAPHICS: |
| 631 | break; | 406 | break; |
| @@ -638,6 +413,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 638 | ret = -EINVAL; | 413 | ret = -EINVAL; |
| 639 | goto out; | 414 | goto out; |
| 640 | } | 415 | } |
| 416 | /* FIXME: this needs the console lock extending */ | ||
| 641 | if (vc->vc_mode == (unsigned char) arg) | 417 | if (vc->vc_mode == (unsigned char) arg) |
| 642 | break; | 418 | break; |
| 643 | vc->vc_mode = (unsigned char) arg; | 419 | vc->vc_mode = (unsigned char) arg; |
| @@ -669,69 +445,26 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 669 | 445 | ||
| 670 | case KDSKBMODE: | 446 | case KDSKBMODE: |
| 671 | if (!perm) | 447 | if (!perm) |
| 672 | goto eperm; | 448 | return -EPERM; |
| 673 | switch(arg) { | 449 | ret = vt_do_kdskbmode(console, arg); |
| 674 | case K_RAW: | 450 | if (ret == 0) |
| 675 | kbd->kbdmode = VC_RAW; | 451 | tty_ldisc_flush(tty); |
| 676 | break; | ||
| 677 | case K_MEDIUMRAW: | ||
| 678 | kbd->kbdmode = VC_MEDIUMRAW; | ||
| 679 | break; | ||
| 680 | case K_XLATE: | ||
| 681 | kbd->kbdmode = VC_XLATE; | ||
| 682 | compute_shiftstate(); | ||
| 683 | break; | ||
| 684 | case K_UNICODE: | ||
| 685 | kbd->kbdmode = VC_UNICODE; | ||
| 686 | compute_shiftstate(); | ||
| 687 | break; | ||
| 688 | case K_OFF: | ||
| 689 | kbd->kbdmode = VC_OFF; | ||
| 690 | break; | ||
| 691 | default: | ||
| 692 | ret = -EINVAL; | ||
| 693 | goto out; | ||
| 694 | } | ||
| 695 | tty_ldisc_flush(tty); | ||
| 696 | break; | 452 | break; |
| 697 | 453 | ||
| 698 | case KDGKBMODE: | 454 | case KDGKBMODE: |
| 699 | switch (kbd->kbdmode) { | 455 | uival = vt_do_kdgkbmode(console); |
| 700 | case VC_RAW: | 456 | ret = put_user(uival, (int __user *)arg); |
| 701 | uival = K_RAW; | 457 | break; |
| 702 | break; | ||
| 703 | case VC_MEDIUMRAW: | ||
| 704 | uival = K_MEDIUMRAW; | ||
| 705 | break; | ||
| 706 | case VC_UNICODE: | ||
| 707 | uival = K_UNICODE; | ||
| 708 | break; | ||
| 709 | case VC_OFF: | ||
| 710 | uival = K_OFF; | ||
| 711 | break; | ||
| 712 | default: | ||
| 713 | uival = K_XLATE; | ||
| 714 | break; | ||
| 715 | } | ||
| 716 | goto setint; | ||
| 717 | 458 | ||
| 718 | /* this could be folded into KDSKBMODE, but for compatibility | 459 | /* this could be folded into KDSKBMODE, but for compatibility |
| 719 | reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */ | 460 | reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */ |
| 720 | case KDSKBMETA: | 461 | case KDSKBMETA: |
| 721 | switch(arg) { | 462 | ret = vt_do_kdskbmeta(console, arg); |
| 722 | case K_METABIT: | ||
| 723 | clr_vc_kbd_mode(kbd, VC_META); | ||
| 724 | break; | ||
| 725 | case K_ESCPREFIX: | ||
| 726 | set_vc_kbd_mode(kbd, VC_META); | ||
| 727 | break; | ||
| 728 | default: | ||
| 729 | ret = -EINVAL; | ||
| 730 | } | ||
| 731 | break; | 463 | break; |
| 732 | 464 | ||
| 733 | case KDGKBMETA: | 465 | case KDGKBMETA: |
| 734 | uival = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT); | 466 | /* FIXME: should review whether this is worth locking */ |
| 467 | uival = vt_do_kdgkbmeta(console); | ||
| 735 | setint: | 468 | setint: |
| 736 | ret = put_user(uival, (int __user *)arg); | 469 | ret = put_user(uival, (int __user *)arg); |
| 737 | break; | 470 | break; |
| @@ -740,133 +473,35 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 740 | case KDSETKEYCODE: | 473 | case KDSETKEYCODE: |
| 741 | if(!capable(CAP_SYS_TTY_CONFIG)) | 474 | if(!capable(CAP_SYS_TTY_CONFIG)) |
| 742 | perm = 0; | 475 | perm = 0; |
| 743 | ret = do_kbkeycode_ioctl(cmd, up, perm); | 476 | ret = vt_do_kbkeycode_ioctl(cmd, up, perm); |
| 744 | break; | 477 | break; |
| 745 | 478 | ||
| 746 | case KDGKBENT: | 479 | case KDGKBENT: |
| 747 | case KDSKBENT: | 480 | case KDSKBENT: |
| 748 | ret = do_kdsk_ioctl(cmd, up, perm, kbd); | 481 | ret = vt_do_kdsk_ioctl(cmd, up, perm, console); |
| 749 | break; | 482 | break; |
| 750 | 483 | ||
| 751 | case KDGKBSENT: | 484 | case KDGKBSENT: |
| 752 | case KDSKBSENT: | 485 | case KDSKBSENT: |
| 753 | ret = do_kdgkb_ioctl(cmd, up, perm); | 486 | ret = vt_do_kdgkb_ioctl(cmd, up, perm); |
| 754 | break; | 487 | break; |
| 755 | 488 | ||
| 489 | /* Diacritical processing. Handled in keyboard.c as it has | ||
| 490 | to operate on the keyboard locks and structures */ | ||
| 756 | case KDGKBDIACR: | 491 | case KDGKBDIACR: |
| 757 | { | ||
| 758 | struct kbdiacrs __user *a = up; | ||
| 759 | struct kbdiacr diacr; | ||
| 760 | int i; | ||
| 761 | |||
| 762 | if (put_user(accent_table_size, &a->kb_cnt)) { | ||
| 763 | ret = -EFAULT; | ||
| 764 | break; | ||
| 765 | } | ||
| 766 | for (i = 0; i < accent_table_size; i++) { | ||
| 767 | diacr.diacr = conv_uni_to_8bit(accent_table[i].diacr); | ||
| 768 | diacr.base = conv_uni_to_8bit(accent_table[i].base); | ||
| 769 | diacr.result = conv_uni_to_8bit(accent_table[i].result); | ||
| 770 | if (copy_to_user(a->kbdiacr + i, &diacr, sizeof(struct kbdiacr))) { | ||
| 771 | ret = -EFAULT; | ||
| 772 | break; | ||
| 773 | } | ||
| 774 | } | ||
| 775 | break; | ||
| 776 | } | ||
| 777 | case KDGKBDIACRUC: | 492 | case KDGKBDIACRUC: |
| 778 | { | ||
| 779 | struct kbdiacrsuc __user *a = up; | ||
| 780 | |||
| 781 | if (put_user(accent_table_size, &a->kb_cnt)) | ||
| 782 | ret = -EFAULT; | ||
| 783 | else if (copy_to_user(a->kbdiacruc, accent_table, | ||
| 784 | accent_table_size*sizeof(struct kbdiacruc))) | ||
| 785 | ret = -EFAULT; | ||
| 786 | break; | ||
| 787 | } | ||
| 788 | |||
| 789 | case KDSKBDIACR: | 493 | case KDSKBDIACR: |
| 790 | { | ||
| 791 | struct kbdiacrs __user *a = up; | ||
| 792 | struct kbdiacr diacr; | ||
| 793 | unsigned int ct; | ||
| 794 | int i; | ||
| 795 | |||
| 796 | if (!perm) | ||
| 797 | goto eperm; | ||
| 798 | if (get_user(ct,&a->kb_cnt)) { | ||
| 799 | ret = -EFAULT; | ||
| 800 | break; | ||
| 801 | } | ||
| 802 | if (ct >= MAX_DIACR) { | ||
| 803 | ret = -EINVAL; | ||
| 804 | break; | ||
| 805 | } | ||
| 806 | accent_table_size = ct; | ||
| 807 | for (i = 0; i < ct; i++) { | ||
| 808 | if (copy_from_user(&diacr, a->kbdiacr + i, sizeof(struct kbdiacr))) { | ||
| 809 | ret = -EFAULT; | ||
| 810 | break; | ||
| 811 | } | ||
| 812 | accent_table[i].diacr = conv_8bit_to_uni(diacr.diacr); | ||
| 813 | accent_table[i].base = conv_8bit_to_uni(diacr.base); | ||
| 814 | accent_table[i].result = conv_8bit_to_uni(diacr.result); | ||
| 815 | } | ||
| 816 | break; | ||
| 817 | } | ||
| 818 | |||
| 819 | case KDSKBDIACRUC: | 494 | case KDSKBDIACRUC: |
| 820 | { | 495 | ret = vt_do_diacrit(cmd, up, perm); |
| 821 | struct kbdiacrsuc __user *a = up; | ||
| 822 | unsigned int ct; | ||
| 823 | |||
| 824 | if (!perm) | ||
| 825 | goto eperm; | ||
| 826 | if (get_user(ct,&a->kb_cnt)) { | ||
| 827 | ret = -EFAULT; | ||
| 828 | break; | ||
| 829 | } | ||
| 830 | if (ct >= MAX_DIACR) { | ||
| 831 | ret = -EINVAL; | ||
| 832 | break; | ||
| 833 | } | ||
| 834 | accent_table_size = ct; | ||
| 835 | if (copy_from_user(accent_table, a->kbdiacruc, ct*sizeof(struct kbdiacruc))) | ||
| 836 | ret = -EFAULT; | ||
| 837 | break; | 496 | break; |
| 838 | } | ||
| 839 | 497 | ||
| 840 | /* the ioctls below read/set the flags usually shown in the leds */ | 498 | /* the ioctls below read/set the flags usually shown in the leds */ |
| 841 | /* don't use them - they will go away without warning */ | 499 | /* don't use them - they will go away without warning */ |
| 842 | case KDGKBLED: | 500 | case KDGKBLED: |
| 843 | ucval = kbd->ledflagstate | (kbd->default_ledflagstate << 4); | ||
| 844 | goto setchar; | ||
| 845 | |||
| 846 | case KDSKBLED: | 501 | case KDSKBLED: |
| 847 | if (!perm) | ||
| 848 | goto eperm; | ||
| 849 | if (arg & ~0x77) { | ||
| 850 | ret = -EINVAL; | ||
| 851 | break; | ||
| 852 | } | ||
| 853 | kbd->ledflagstate = (arg & 7); | ||
| 854 | kbd->default_ledflagstate = ((arg >> 4) & 7); | ||
| 855 | set_leds(); | ||
| 856 | break; | ||
| 857 | |||
| 858 | /* the ioctls below only set the lights, not the functions */ | ||
| 859 | /* for those, see KDGKBLED and KDSKBLED above */ | ||
| 860 | case KDGETLED: | 502 | case KDGETLED: |
| 861 | ucval = getledstate(); | ||
| 862 | setchar: | ||
| 863 | ret = put_user(ucval, (char __user *)arg); | ||
| 864 | break; | ||
| 865 | |||
| 866 | case KDSETLED: | 503 | case KDSETLED: |
| 867 | if (!perm) | 504 | ret = vt_do_kdskled(console, cmd, arg, perm); |
| 868 | goto eperm; | ||
| 869 | setledstate(kbd, arg); | ||
| 870 | break; | 505 | break; |
| 871 | 506 | ||
| 872 | /* | 507 | /* |
| @@ -879,7 +514,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 879 | case KDSIGACCEPT: | 514 | case KDSIGACCEPT: |
| 880 | { | 515 | { |
| 881 | if (!perm || !capable(CAP_KILL)) | 516 | if (!perm || !capable(CAP_KILL)) |
| 882 | goto eperm; | 517 | return -EPERM; |
| 883 | if (!valid_signal(arg) || arg < 1 || arg == SIGKILL) | 518 | if (!valid_signal(arg) || arg < 1 || arg == SIGKILL) |
| 884 | ret = -EINVAL; | 519 | ret = -EINVAL; |
| 885 | else { | 520 | else { |
| @@ -897,7 +532,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 897 | struct vt_mode tmp; | 532 | struct vt_mode tmp; |
| 898 | 533 | ||
| 899 | if (!perm) | 534 | if (!perm) |
| 900 | goto eperm; | 535 | return -EPERM; |
| 901 | if (copy_from_user(&tmp, up, sizeof(struct vt_mode))) { | 536 | if (copy_from_user(&tmp, up, sizeof(struct vt_mode))) { |
| 902 | ret = -EFAULT; | 537 | ret = -EFAULT; |
| 903 | goto out; | 538 | goto out; |
| @@ -943,6 +578,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 943 | struct vt_stat __user *vtstat = up; | 578 | struct vt_stat __user *vtstat = up; |
| 944 | unsigned short state, mask; | 579 | unsigned short state, mask; |
| 945 | 580 | ||
| 581 | /* Review: FIXME: Console lock ? */ | ||
| 946 | if (put_user(fg_console + 1, &vtstat->v_active)) | 582 | if (put_user(fg_console + 1, &vtstat->v_active)) |
| 947 | ret = -EFAULT; | 583 | ret = -EFAULT; |
| 948 | else { | 584 | else { |
| @@ -960,6 +596,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 960 | * Returns the first available (non-opened) console. | 596 | * Returns the first available (non-opened) console. |
| 961 | */ | 597 | */ |
| 962 | case VT_OPENQRY: | 598 | case VT_OPENQRY: |
| 599 | /* FIXME: locking ? - but then this is a stupid API */ | ||
| 963 | for (i = 0; i < MAX_NR_CONSOLES; ++i) | 600 | for (i = 0; i < MAX_NR_CONSOLES; ++i) |
| 964 | if (! VT_IS_IN_USE(i)) | 601 | if (! VT_IS_IN_USE(i)) |
| 965 | break; | 602 | break; |
| @@ -973,7 +610,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 973 | */ | 610 | */ |
| 974 | case VT_ACTIVATE: | 611 | case VT_ACTIVATE: |
| 975 | if (!perm) | 612 | if (!perm) |
| 976 | goto eperm; | 613 | return -EPERM; |
| 977 | if (arg == 0 || arg > MAX_NR_CONSOLES) | 614 | if (arg == 0 || arg > MAX_NR_CONSOLES) |
| 978 | ret = -ENXIO; | 615 | ret = -ENXIO; |
| 979 | else { | 616 | else { |
| @@ -992,7 +629,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 992 | struct vt_setactivate vsa; | 629 | struct vt_setactivate vsa; |
| 993 | 630 | ||
| 994 | if (!perm) | 631 | if (!perm) |
| 995 | goto eperm; | 632 | return -EPERM; |
| 996 | 633 | ||
| 997 | if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg, | 634 | if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg, |
| 998 | sizeof(struct vt_setactivate))) { | 635 | sizeof(struct vt_setactivate))) { |
| @@ -1020,6 +657,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 1020 | if (ret) | 657 | if (ret) |
| 1021 | break; | 658 | break; |
| 1022 | /* Commence switch and lock */ | 659 | /* Commence switch and lock */ |
| 660 | /* Review set_console locks */ | ||
| 1023 | set_console(vsa.console); | 661 | set_console(vsa.console); |
| 1024 | } | 662 | } |
| 1025 | break; | 663 | break; |
| @@ -1030,7 +668,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 1030 | */ | 668 | */ |
| 1031 | case VT_WAITACTIVE: | 669 | case VT_WAITACTIVE: |
| 1032 | if (!perm) | 670 | if (!perm) |
| 1033 | goto eperm; | 671 | return -EPERM; |
| 1034 | if (arg == 0 || arg > MAX_NR_CONSOLES) | 672 | if (arg == 0 || arg > MAX_NR_CONSOLES) |
| 1035 | ret = -ENXIO; | 673 | ret = -ENXIO; |
| 1036 | else | 674 | else |
| @@ -1049,16 +687,17 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 1049 | */ | 687 | */ |
| 1050 | case VT_RELDISP: | 688 | case VT_RELDISP: |
| 1051 | if (!perm) | 689 | if (!perm) |
| 1052 | goto eperm; | 690 | return -EPERM; |
| 1053 | 691 | ||
| 692 | console_lock(); | ||
| 1054 | if (vc->vt_mode.mode != VT_PROCESS) { | 693 | if (vc->vt_mode.mode != VT_PROCESS) { |
| 694 | console_unlock(); | ||
| 1055 | ret = -EINVAL; | 695 | ret = -EINVAL; |
| 1056 | break; | 696 | break; |
| 1057 | } | 697 | } |
| 1058 | /* | 698 | /* |
| 1059 | * Switching-from response | 699 | * Switching-from response |
| 1060 | */ | 700 | */ |
| 1061 | console_lock(); | ||
| 1062 | if (vc->vt_newvt >= 0) { | 701 | if (vc->vt_newvt >= 0) { |
| 1063 | if (arg == 0) | 702 | if (arg == 0) |
| 1064 | /* | 703 | /* |
| @@ -1135,7 +774,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 1135 | 774 | ||
| 1136 | ushort ll,cc; | 775 | ushort ll,cc; |
| 1137 | if (!perm) | 776 | if (!perm) |
| 1138 | goto eperm; | 777 | return -EPERM; |
| 1139 | if (get_user(ll, &vtsizes->v_rows) || | 778 | if (get_user(ll, &vtsizes->v_rows) || |
| 1140 | get_user(cc, &vtsizes->v_cols)) | 779 | get_user(cc, &vtsizes->v_cols)) |
| 1141 | ret = -EFAULT; | 780 | ret = -EFAULT; |
| @@ -1146,6 +785,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 1146 | 785 | ||
| 1147 | if (vc) { | 786 | if (vc) { |
| 1148 | vc->vc_resize_user = 1; | 787 | vc->vc_resize_user = 1; |
| 788 | /* FIXME: review v tty lock */ | ||
| 1149 | vc_resize(vc_cons[i].d, cc, ll); | 789 | vc_resize(vc_cons[i].d, cc, ll); |
| 1150 | } | 790 | } |
| 1151 | } | 791 | } |
| @@ -1159,7 +799,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 1159 | struct vt_consize __user *vtconsize = up; | 799 | struct vt_consize __user *vtconsize = up; |
| 1160 | ushort ll,cc,vlin,clin,vcol,ccol; | 800 | ushort ll,cc,vlin,clin,vcol,ccol; |
| 1161 | if (!perm) | 801 | if (!perm) |
| 1162 | goto eperm; | 802 | return -EPERM; |
| 1163 | if (!access_ok(VERIFY_READ, vtconsize, | 803 | if (!access_ok(VERIFY_READ, vtconsize, |
| 1164 | sizeof(struct vt_consize))) { | 804 | sizeof(struct vt_consize))) { |
| 1165 | ret = -EFAULT; | 805 | ret = -EFAULT; |
| @@ -1215,7 +855,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 1215 | 855 | ||
| 1216 | case PIO_FONT: { | 856 | case PIO_FONT: { |
| 1217 | if (!perm) | 857 | if (!perm) |
| 1218 | goto eperm; | 858 | return -EPERM; |
| 1219 | op.op = KD_FONT_OP_SET; | 859 | op.op = KD_FONT_OP_SET; |
| 1220 | op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */ | 860 | op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */ |
| 1221 | op.width = 8; | 861 | op.width = 8; |
| @@ -1256,7 +896,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 1256 | case PIO_FONTRESET: | 896 | case PIO_FONTRESET: |
| 1257 | { | 897 | { |
| 1258 | if (!perm) | 898 | if (!perm) |
| 1259 | goto eperm; | 899 | return -EPERM; |
| 1260 | 900 | ||
| 1261 | #ifdef BROKEN_GRAPHICS_PROGRAMS | 901 | #ifdef BROKEN_GRAPHICS_PROGRAMS |
| 1262 | /* With BROKEN_GRAPHICS_PROGRAMS defined, the default | 902 | /* With BROKEN_GRAPHICS_PROGRAMS defined, the default |
| @@ -1282,7 +922,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 1282 | break; | 922 | break; |
| 1283 | } | 923 | } |
| 1284 | if (!perm && op.op != KD_FONT_OP_GET) | 924 | if (!perm && op.op != KD_FONT_OP_GET) |
| 1285 | goto eperm; | 925 | return -EPERM; |
| 1286 | ret = con_font_op(vc, &op); | 926 | ret = con_font_op(vc, &op); |
| 1287 | if (ret) | 927 | if (ret) |
| 1288 | break; | 928 | break; |
| @@ -1294,50 +934,65 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 1294 | case PIO_SCRNMAP: | 934 | case PIO_SCRNMAP: |
| 1295 | if (!perm) | 935 | if (!perm) |
| 1296 | ret = -EPERM; | 936 | ret = -EPERM; |
| 1297 | else | 937 | else { |
| 938 | tty_lock(); | ||
| 1298 | ret = con_set_trans_old(up); | 939 | ret = con_set_trans_old(up); |
| 940 | tty_unlock(); | ||
| 941 | } | ||
| 1299 | break; | 942 | break; |
| 1300 | 943 | ||
| 1301 | case GIO_SCRNMAP: | 944 | case GIO_SCRNMAP: |
| 945 | tty_lock(); | ||
| 1302 | ret = con_get_trans_old(up); | 946 | ret = con_get_trans_old(up); |
| 947 | tty_unlock(); | ||
| 1303 | break; | 948 | break; |
| 1304 | 949 | ||
| 1305 | case PIO_UNISCRNMAP: | 950 | case PIO_UNISCRNMAP: |
| 1306 | if (!perm) | 951 | if (!perm) |
| 1307 | ret = -EPERM; | 952 | ret = -EPERM; |
| 1308 | else | 953 | else { |
| 954 | tty_lock(); | ||
| 1309 | ret = con_set_trans_new(up); | 955 | ret = con_set_trans_new(up); |
| 956 | tty_unlock(); | ||
| 957 | } | ||
| 1310 | break; | 958 | break; |
| 1311 | 959 | ||
| 1312 | case GIO_UNISCRNMAP: | 960 | case GIO_UNISCRNMAP: |
| 961 | tty_lock(); | ||
| 1313 | ret = con_get_trans_new(up); | 962 | ret = con_get_trans_new(up); |
| 963 | tty_unlock(); | ||
| 1314 | break; | 964 | break; |
| 1315 | 965 | ||
| 1316 | case PIO_UNIMAPCLR: | 966 | case PIO_UNIMAPCLR: |
| 1317 | { struct unimapinit ui; | 967 | { struct unimapinit ui; |
| 1318 | if (!perm) | 968 | if (!perm) |
| 1319 | goto eperm; | 969 | return -EPERM; |
| 1320 | ret = copy_from_user(&ui, up, sizeof(struct unimapinit)); | 970 | ret = copy_from_user(&ui, up, sizeof(struct unimapinit)); |
| 1321 | if (ret) | 971 | if (ret) |
| 1322 | ret = -EFAULT; | 972 | ret = -EFAULT; |
| 1323 | else | 973 | else { |
| 974 | tty_lock(); | ||
| 1324 | con_clear_unimap(vc, &ui); | 975 | con_clear_unimap(vc, &ui); |
| 976 | tty_unlock(); | ||
| 977 | } | ||
| 1325 | break; | 978 | break; |
| 1326 | } | 979 | } |
| 1327 | 980 | ||
| 1328 | case PIO_UNIMAP: | 981 | case PIO_UNIMAP: |
| 1329 | case GIO_UNIMAP: | 982 | case GIO_UNIMAP: |
| 983 | tty_lock(); | ||
| 1330 | ret = do_unimap_ioctl(cmd, up, perm, vc); | 984 | ret = do_unimap_ioctl(cmd, up, perm, vc); |
| 985 | tty_unlock(); | ||
| 1331 | break; | 986 | break; |
| 1332 | 987 | ||
| 1333 | case VT_LOCKSWITCH: | 988 | case VT_LOCKSWITCH: |
| 1334 | if (!capable(CAP_SYS_TTY_CONFIG)) | 989 | if (!capable(CAP_SYS_TTY_CONFIG)) |
| 1335 | goto eperm; | 990 | return -EPERM; |
| 1336 | vt_dont_switch = 1; | 991 | vt_dont_switch = 1; |
| 1337 | break; | 992 | break; |
| 1338 | case VT_UNLOCKSWITCH: | 993 | case VT_UNLOCKSWITCH: |
| 1339 | if (!capable(CAP_SYS_TTY_CONFIG)) | 994 | if (!capable(CAP_SYS_TTY_CONFIG)) |
| 1340 | goto eperm; | 995 | return -EPERM; |
| 1341 | vt_dont_switch = 0; | 996 | vt_dont_switch = 0; |
| 1342 | break; | 997 | break; |
| 1343 | case VT_GETHIFONTMASK: | 998 | case VT_GETHIFONTMASK: |
| @@ -1351,17 +1006,13 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 1351 | ret = -ENOIOCTLCMD; | 1006 | ret = -ENOIOCTLCMD; |
| 1352 | } | 1007 | } |
| 1353 | out: | 1008 | out: |
| 1354 | tty_unlock(); | ||
| 1355 | return ret; | 1009 | return ret; |
| 1356 | eperm: | ||
| 1357 | ret = -EPERM; | ||
| 1358 | goto out; | ||
| 1359 | } | 1010 | } |
| 1360 | 1011 | ||
| 1361 | void reset_vc(struct vc_data *vc) | 1012 | void reset_vc(struct vc_data *vc) |
| 1362 | { | 1013 | { |
| 1363 | vc->vc_mode = KD_TEXT; | 1014 | vc->vc_mode = KD_TEXT; |
| 1364 | kbd_table[vc->vc_num].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE; | 1015 | vt_reset_unicode(vc->vc_num); |
| 1365 | vc->vt_mode.mode = VT_AUTO; | 1016 | vc->vt_mode.mode = VT_AUTO; |
| 1366 | vc->vt_mode.waitv = 0; | 1017 | vc->vt_mode.waitv = 0; |
| 1367 | vc->vt_mode.relsig = 0; | 1018 | vc->vt_mode.relsig = 0; |
| @@ -1384,6 +1035,7 @@ void vc_SAK(struct work_struct *work) | |||
| 1384 | console_lock(); | 1035 | console_lock(); |
| 1385 | vc = vc_con->d; | 1036 | vc = vc_con->d; |
| 1386 | if (vc) { | 1037 | if (vc) { |
| 1038 | /* FIXME: review tty ref counting */ | ||
| 1387 | tty = vc->port.tty; | 1039 | tty = vc->port.tty; |
| 1388 | /* | 1040 | /* |
| 1389 | * SAK should also work in all raw modes and reset | 1041 | * SAK should also work in all raw modes and reset |
| @@ -1516,8 +1168,6 @@ long vt_compat_ioctl(struct tty_struct *tty, | |||
| 1516 | 1168 | ||
| 1517 | console = vc->vc_num; | 1169 | console = vc->vc_num; |
| 1518 | 1170 | ||
| 1519 | tty_lock(); | ||
| 1520 | |||
| 1521 | if (!vc_cons_allocated(console)) { /* impossible? */ | 1171 | if (!vc_cons_allocated(console)) { /* impossible? */ |
| 1522 | ret = -ENOIOCTLCMD; | 1172 | ret = -ENOIOCTLCMD; |
| 1523 | goto out; | 1173 | goto out; |
| @@ -1546,7 +1196,9 @@ long vt_compat_ioctl(struct tty_struct *tty, | |||
| 1546 | 1196 | ||
| 1547 | case PIO_UNIMAP: | 1197 | case PIO_UNIMAP: |
| 1548 | case GIO_UNIMAP: | 1198 | case GIO_UNIMAP: |
| 1199 | tty_lock(); | ||
| 1549 | ret = compat_unimap_ioctl(cmd, up, perm, vc); | 1200 | ret = compat_unimap_ioctl(cmd, up, perm, vc); |
| 1201 | tty_unlock(); | ||
| 1550 | break; | 1202 | break; |
| 1551 | 1203 | ||
| 1552 | /* | 1204 | /* |
| @@ -1583,11 +1235,9 @@ long vt_compat_ioctl(struct tty_struct *tty, | |||
| 1583 | goto fallback; | 1235 | goto fallback; |
| 1584 | } | 1236 | } |
| 1585 | out: | 1237 | out: |
| 1586 | tty_unlock(); | ||
| 1587 | return ret; | 1238 | return ret; |
| 1588 | 1239 | ||
| 1589 | fallback: | 1240 | fallback: |
| 1590 | tty_unlock(); | ||
| 1591 | return vt_ioctl(tty, cmd, arg); | 1241 | return vt_ioctl(tty, cmd, arg); |
| 1592 | } | 1242 | } |
| 1593 | 1243 | ||
| @@ -1773,13 +1423,10 @@ int vt_move_to_console(unsigned int vt, int alloc) | |||
| 1773 | return -EIO; | 1423 | return -EIO; |
| 1774 | } | 1424 | } |
| 1775 | console_unlock(); | 1425 | console_unlock(); |
| 1776 | tty_lock(); | ||
| 1777 | if (vt_waitactive(vt + 1)) { | 1426 | if (vt_waitactive(vt + 1)) { |
| 1778 | pr_debug("Suspend: Can't switch VCs."); | 1427 | pr_debug("Suspend: Can't switch VCs."); |
| 1779 | tty_unlock(); | ||
| 1780 | return -EINTR; | 1428 | return -EINTR; |
| 1781 | } | 1429 | } |
| 1782 | tty_unlock(); | ||
| 1783 | return prev; | 1430 | return prev; |
| 1784 | } | 1431 | } |
| 1785 | 1432 | ||
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 9543b19d410c..6bb8472155c6 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
| @@ -508,17 +508,12 @@ static int acm_tty_install(struct tty_driver *driver, struct tty_struct *tty) | |||
| 508 | if (!acm) | 508 | if (!acm) |
| 509 | return -ENODEV; | 509 | return -ENODEV; |
| 510 | 510 | ||
| 511 | retval = tty_init_termios(tty); | 511 | retval = tty_standard_install(driver, tty); |
| 512 | if (retval) | 512 | if (retval) |
| 513 | goto error_init_termios; | 513 | goto error_init_termios; |
| 514 | 514 | ||
| 515 | tty->driver_data = acm; | 515 | tty->driver_data = acm; |
| 516 | 516 | ||
| 517 | /* Final install (we use the default method) */ | ||
| 518 | tty_driver_kref_get(driver); | ||
| 519 | tty->count++; | ||
| 520 | driver->ttys[tty->index] = tty; | ||
| 521 | |||
| 522 | return 0; | 517 | return 0; |
| 523 | 518 | ||
| 524 | error_init_termios: | 519 | error_init_termios: |
| @@ -1675,7 +1670,6 @@ static int __init acm_init(void) | |||
| 1675 | acm_tty_driver = alloc_tty_driver(ACM_TTY_MINORS); | 1670 | acm_tty_driver = alloc_tty_driver(ACM_TTY_MINORS); |
| 1676 | if (!acm_tty_driver) | 1671 | if (!acm_tty_driver) |
| 1677 | return -ENOMEM; | 1672 | return -ENOMEM; |
| 1678 | acm_tty_driver->owner = THIS_MODULE, | ||
| 1679 | acm_tty_driver->driver_name = "acm", | 1673 | acm_tty_driver->driver_name = "acm", |
| 1680 | acm_tty_driver->name = "ttyACM", | 1674 | acm_tty_driver->name = "ttyACM", |
| 1681 | acm_tty_driver->major = ACM_TTY_MAJOR, | 1675 | acm_tty_driver->major = ACM_TTY_MAJOR, |
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index 6597a6813e43..6c23938d2711 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c | |||
| @@ -725,9 +725,6 @@ static int gs_open(struct tty_struct *tty, struct file *file) | |||
| 725 | struct gs_port *port; | 725 | struct gs_port *port; |
| 726 | int status; | 726 | int status; |
| 727 | 727 | ||
| 728 | if (port_num < 0 || port_num >= n_ports) | ||
| 729 | return -ENXIO; | ||
| 730 | |||
| 731 | do { | 728 | do { |
| 732 | mutex_lock(&ports[port_num].lock); | 729 | mutex_lock(&ports[port_num].lock); |
| 733 | port = ports[port_num].port; | 730 | port = ports[port_num].port; |
| @@ -1087,7 +1084,6 @@ int __init gserial_setup(struct usb_gadget *g, unsigned count) | |||
| 1087 | if (!gs_tty_driver) | 1084 | if (!gs_tty_driver) |
| 1088 | return -ENOMEM; | 1085 | return -ENOMEM; |
| 1089 | 1086 | ||
| 1090 | gs_tty_driver->owner = THIS_MODULE; | ||
| 1091 | gs_tty_driver->driver_name = "g_serial"; | 1087 | gs_tty_driver->driver_name = "g_serial"; |
| 1092 | gs_tty_driver->name = PREFIX; | 1088 | gs_tty_driver->name = PREFIX; |
| 1093 | /* uses dynamically assigned dev_t values */ | 1089 | /* uses dynamically assigned dev_t values */ |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 611b206591cb..d4e724d9b1f4 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
| @@ -214,15 +214,14 @@ static int serial_install(struct tty_driver *driver, struct tty_struct *tty) | |||
| 214 | if (!try_module_get(serial->type->driver.owner)) | 214 | if (!try_module_get(serial->type->driver.owner)) |
| 215 | goto error_module_get; | 215 | goto error_module_get; |
| 216 | 216 | ||
| 217 | /* perform the standard setup */ | ||
| 218 | retval = tty_init_termios(tty); | ||
| 219 | if (retval) | ||
| 220 | goto error_init_termios; | ||
| 221 | |||
| 222 | retval = usb_autopm_get_interface(serial->interface); | 217 | retval = usb_autopm_get_interface(serial->interface); |
| 223 | if (retval) | 218 | if (retval) |
| 224 | goto error_get_interface; | 219 | goto error_get_interface; |
| 225 | 220 | ||
| 221 | retval = tty_standard_install(driver, tty); | ||
| 222 | if (retval) | ||
| 223 | goto error_init_termios; | ||
| 224 | |||
| 226 | mutex_unlock(&serial->disc_mutex); | 225 | mutex_unlock(&serial->disc_mutex); |
| 227 | 226 | ||
| 228 | /* allow the driver to update the settings */ | 227 | /* allow the driver to update the settings */ |
| @@ -231,14 +230,11 @@ static int serial_install(struct tty_driver *driver, struct tty_struct *tty) | |||
| 231 | 230 | ||
| 232 | tty->driver_data = port; | 231 | tty->driver_data = port; |
| 233 | 232 | ||
| 234 | /* Final install (we use the default method) */ | ||
| 235 | tty_driver_kref_get(driver); | ||
| 236 | tty->count++; | ||
| 237 | driver->ttys[idx] = tty; | ||
| 238 | return retval; | 233 | return retval; |
| 239 | 234 | ||
| 240 | error_get_interface: | ||
| 241 | error_init_termios: | 235 | error_init_termios: |
| 236 | usb_autopm_put_interface(serial->interface); | ||
| 237 | error_get_interface: | ||
| 242 | module_put(serial->type->driver.owner); | 238 | module_put(serial->type->driver.owner); |
| 243 | error_module_get: | 239 | error_module_get: |
| 244 | error_no_port: | 240 | error_no_port: |
| @@ -1239,7 +1235,6 @@ static int __init usb_serial_init(void) | |||
| 1239 | goto exit_bus; | 1235 | goto exit_bus; |
| 1240 | } | 1236 | } |
| 1241 | 1237 | ||
| 1242 | usb_serial_tty_driver->owner = THIS_MODULE; | ||
| 1243 | usb_serial_tty_driver->driver_name = "usbserial"; | 1238 | usb_serial_tty_driver->driver_name = "usbserial"; |
| 1244 | usb_serial_tty_driver->name = "ttyUSB"; | 1239 | usb_serial_tty_driver->name = "ttyUSB"; |
| 1245 | usb_serial_tty_driver->major = SERIAL_TTY_MAJOR; | 1240 | usb_serial_tty_driver->major = SERIAL_TTY_MAJOR; |
