diff options
36 files changed, 978 insertions, 652 deletions
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index 4254457d3911..b861c08263a4 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -158,13 +158,11 @@ static unsigned int cy_isa_addresses[] = { | |||
158 | 158 | ||
159 | #define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses) | 159 | #define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses) |
160 | 160 | ||
161 | #ifdef MODULE | ||
162 | static long maddr[NR_CARDS]; | 161 | static long maddr[NR_CARDS]; |
163 | static int irq[NR_CARDS]; | 162 | static int irq[NR_CARDS]; |
164 | 163 | ||
165 | module_param_array(maddr, long, NULL, 0); | 164 | module_param_array(maddr, long, NULL, 0); |
166 | module_param_array(irq, int, NULL, 0); | 165 | module_param_array(irq, int, NULL, 0); |
167 | #endif | ||
168 | 166 | ||
169 | #endif /* CONFIG_ISA */ | 167 | #endif /* CONFIG_ISA */ |
170 | 168 | ||
@@ -598,12 +596,6 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip, | |||
598 | save_car = readb(base_addr + (CyCAR << index)); | 596 | save_car = readb(base_addr + (CyCAR << index)); |
599 | cy_writeb(base_addr + (CyCAR << index), save_xir); | 597 | cy_writeb(base_addr + (CyCAR << index), save_xir); |
600 | 598 | ||
601 | /* validate the port# (as configured and open) */ | ||
602 | if (channel + chip * 4 >= cinfo->nports) { | ||
603 | cy_writeb(base_addr + (CySRER << index), | ||
604 | readb(base_addr + (CySRER << index)) & ~CyTxRdy); | ||
605 | goto end; | ||
606 | } | ||
607 | info = &cinfo->ports[channel + chip * 4]; | 599 | info = &cinfo->ports[channel + chip * 4]; |
608 | tty = tty_port_tty_get(&info->port); | 600 | tty = tty_port_tty_get(&info->port); |
609 | if (tty == NULL) { | 601 | if (tty == NULL) { |
@@ -3316,13 +3308,10 @@ static int __init cy_detect_isa(void) | |||
3316 | unsigned short cy_isa_irq, nboard; | 3308 | unsigned short cy_isa_irq, nboard; |
3317 | void __iomem *cy_isa_address; | 3309 | void __iomem *cy_isa_address; |
3318 | unsigned short i, j, cy_isa_nchan; | 3310 | unsigned short i, j, cy_isa_nchan; |
3319 | #ifdef MODULE | ||
3320 | int isparam = 0; | 3311 | int isparam = 0; |
3321 | #endif | ||
3322 | 3312 | ||
3323 | nboard = 0; | 3313 | nboard = 0; |
3324 | 3314 | ||
3325 | #ifdef MODULE | ||
3326 | /* Check for module parameters */ | 3315 | /* Check for module parameters */ |
3327 | for (i = 0; i < NR_CARDS; i++) { | 3316 | for (i = 0; i < NR_CARDS; i++) { |
3328 | if (maddr[i] || i) { | 3317 | if (maddr[i] || i) { |
@@ -3332,7 +3321,6 @@ static int __init cy_detect_isa(void) | |||
3332 | if (!maddr[i]) | 3321 | if (!maddr[i]) |
3333 | break; | 3322 | break; |
3334 | } | 3323 | } |
3335 | #endif | ||
3336 | 3324 | ||
3337 | /* scan the address table probing for Cyclom-Y/ISA boards */ | 3325 | /* scan the address table probing for Cyclom-Y/ISA boards */ |
3338 | for (i = 0; i < NR_ISA_ADDRS; i++) { | 3326 | for (i = 0; i < NR_ISA_ADDRS; i++) { |
@@ -3353,11 +3341,10 @@ static int __init cy_detect_isa(void) | |||
3353 | iounmap(cy_isa_address); | 3341 | iounmap(cy_isa_address); |
3354 | continue; | 3342 | continue; |
3355 | } | 3343 | } |
3356 | #ifdef MODULE | 3344 | |
3357 | if (isparam && i < NR_CARDS && irq[i]) | 3345 | if (isparam && i < NR_CARDS && irq[i]) |
3358 | cy_isa_irq = irq[i]; | 3346 | cy_isa_irq = irq[i]; |
3359 | else | 3347 | else |
3360 | #endif | ||
3361 | /* find out the board's irq by probing */ | 3348 | /* find out the board's irq by probing */ |
3362 | cy_isa_irq = detect_isa_irq(cy_isa_address); | 3349 | cy_isa_irq = detect_isa_irq(cy_isa_address); |
3363 | if (cy_isa_irq == 0) { | 3350 | if (cy_isa_irq == 0) { |
@@ -4208,3 +4195,4 @@ module_exit(cy_cleanup_module); | |||
4208 | MODULE_LICENSE("GPL"); | 4195 | MODULE_LICENSE("GPL"); |
4209 | MODULE_VERSION(CY_VERSION); | 4196 | MODULE_VERSION(CY_VERSION); |
4210 | MODULE_ALIAS_CHARDEV_MAJOR(CYCLADES_MAJOR); | 4197 | MODULE_ALIAS_CHARDEV_MAJOR(CYCLADES_MAJOR); |
4198 | MODULE_FIRMWARE("cyzfirm.bin"); | ||
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 4c3b59be286a..465185fc0f52 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -146,7 +146,7 @@ static void hvc_console_print(struct console *co, const char *b, | |||
146 | return; | 146 | return; |
147 | 147 | ||
148 | /* This console adapter was removed so it is not usable. */ | 148 | /* This console adapter was removed so it is not usable. */ |
149 | if (vtermnos[index] < 0) | 149 | if (vtermnos[index] == -1) |
150 | return; | 150 | return; |
151 | 151 | ||
152 | while (count > 0 || i > 0) { | 152 | while (count > 0 || i > 0) { |
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index 517271c762e6..911e1da6def2 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -208,6 +208,7 @@ static int DumpFifoBuffer( char __user *, int); | |||
208 | 208 | ||
209 | static void ip2_init_board(int, const struct firmware *); | 209 | static void ip2_init_board(int, const struct firmware *); |
210 | static unsigned short find_eisa_board(int); | 210 | static unsigned short find_eisa_board(int); |
211 | static int ip2_setup(char *str); | ||
211 | 212 | ||
212 | /***************/ | 213 | /***************/ |
213 | /* Static Data */ | 214 | /* Static Data */ |
@@ -263,7 +264,7 @@ static int tracewrap; | |||
263 | /* Macros */ | 264 | /* Macros */ |
264 | /**********/ | 265 | /**********/ |
265 | 266 | ||
266 | #if defined(MODULE) && defined(IP2DEBUG_OPEN) | 267 | #ifdef IP2DEBUG_OPEN |
267 | #define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] ttyc=%d, modc=%x -> %s\n", \ | 268 | #define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] ttyc=%d, modc=%x -> %s\n", \ |
268 | tty->name,(pCh->flags), \ | 269 | tty->name,(pCh->flags), \ |
269 | tty->count,/*GET_USE_COUNT(module)*/0,s) | 270 | tty->count,/*GET_USE_COUNT(module)*/0,s) |
@@ -285,7 +286,10 @@ MODULE_AUTHOR("Doug McNash"); | |||
285 | MODULE_DESCRIPTION("Computone IntelliPort Plus Driver"); | 286 | MODULE_DESCRIPTION("Computone IntelliPort Plus Driver"); |
286 | MODULE_LICENSE("GPL"); | 287 | MODULE_LICENSE("GPL"); |
287 | 288 | ||
289 | #define MAX_CMD_STR 50 | ||
290 | |||
288 | static int poll_only; | 291 | static int poll_only; |
292 | static char cmd[MAX_CMD_STR]; | ||
289 | 293 | ||
290 | static int Eisa_irq; | 294 | static int Eisa_irq; |
291 | static int Eisa_slot; | 295 | static int Eisa_slot; |
@@ -309,6 +313,8 @@ module_param_array(io, int, NULL, 0); | |||
309 | MODULE_PARM_DESC(io, "I/O ports for IntelliPort Cards"); | 313 | MODULE_PARM_DESC(io, "I/O ports for IntelliPort Cards"); |
310 | module_param(poll_only, bool, 0); | 314 | module_param(poll_only, bool, 0); |
311 | MODULE_PARM_DESC(poll_only, "Do not use card interrupts"); | 315 | MODULE_PARM_DESC(poll_only, "Do not use card interrupts"); |
316 | module_param_string(ip2, cmd, MAX_CMD_STR, 0); | ||
317 | MODULE_PARM_DESC(ip2, "Contains module parameter passed with 'ip2='"); | ||
312 | 318 | ||
313 | /* for sysfs class support */ | 319 | /* for sysfs class support */ |
314 | static struct class *ip2_class; | 320 | static struct class *ip2_class; |
@@ -487,7 +493,6 @@ static const struct firmware *ip2_request_firmware(void) | |||
487 | return fw; | 493 | return fw; |
488 | } | 494 | } |
489 | 495 | ||
490 | #ifndef MODULE | ||
491 | /****************************************************************************** | 496 | /****************************************************************************** |
492 | * ip2_setup: | 497 | * ip2_setup: |
493 | * str: kernel command line string | 498 | * str: kernel command line string |
@@ -531,7 +536,6 @@ static int __init ip2_setup(char *str) | |||
531 | return 1; | 536 | return 1; |
532 | } | 537 | } |
533 | __setup("ip2=", ip2_setup); | 538 | __setup("ip2=", ip2_setup); |
534 | #endif /* !MODULE */ | ||
535 | 539 | ||
536 | static int __init ip2_loadmain(void) | 540 | static int __init ip2_loadmain(void) |
537 | { | 541 | { |
@@ -539,14 +543,20 @@ static int __init ip2_loadmain(void) | |||
539 | int err = 0; | 543 | int err = 0; |
540 | i2eBordStrPtr pB = NULL; | 544 | i2eBordStrPtr pB = NULL; |
541 | int rc = -1; | 545 | int rc = -1; |
542 | struct pci_dev *pdev = NULL; | ||
543 | const struct firmware *fw = NULL; | 546 | const struct firmware *fw = NULL; |
547 | char *str; | ||
548 | |||
549 | str = cmd; | ||
544 | 550 | ||
545 | if (poll_only) { | 551 | if (poll_only) { |
546 | /* Hard lock the interrupts to zero */ | 552 | /* Hard lock the interrupts to zero */ |
547 | irq[0] = irq[1] = irq[2] = irq[3] = poll_only = 0; | 553 | irq[0] = irq[1] = irq[2] = irq[3] = poll_only = 0; |
548 | } | 554 | } |
549 | 555 | ||
556 | /* Check module parameter with 'ip2=' has been passed or not */ | ||
557 | if (!poll_only && (!strncmp(str, "ip2=", 4))) | ||
558 | ip2_setup(str); | ||
559 | |||
550 | ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0); | 560 | ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0); |
551 | 561 | ||
552 | /* process command line arguments to modprobe or | 562 | /* process command line arguments to modprobe or |
@@ -612,6 +622,7 @@ static int __init ip2_loadmain(void) | |||
612 | case PCI: | 622 | case PCI: |
613 | #ifdef CONFIG_PCI | 623 | #ifdef CONFIG_PCI |
614 | { | 624 | { |
625 | struct pci_dev *pdev = NULL; | ||
615 | u32 addr; | 626 | u32 addr; |
616 | int status; | 627 | int status; |
617 | 628 | ||
@@ -626,7 +637,7 @@ static int __init ip2_loadmain(void) | |||
626 | 637 | ||
627 | if (pci_enable_device(pdev)) { | 638 | if (pci_enable_device(pdev)) { |
628 | dev_err(&pdev->dev, "can't enable device\n"); | 639 | dev_err(&pdev->dev, "can't enable device\n"); |
629 | break; | 640 | goto out; |
630 | } | 641 | } |
631 | ip2config.type[i] = PCI; | 642 | ip2config.type[i] = PCI; |
632 | ip2config.pci_dev[i] = pci_dev_get(pdev); | 643 | ip2config.pci_dev[i] = pci_dev_get(pdev); |
@@ -638,6 +649,8 @@ static int __init ip2_loadmain(void) | |||
638 | dev_err(&pdev->dev, "I/O address error\n"); | 649 | dev_err(&pdev->dev, "I/O address error\n"); |
639 | 650 | ||
640 | ip2config.irq[i] = pdev->irq; | 651 | ip2config.irq[i] = pdev->irq; |
652 | out: | ||
653 | pci_dev_put(pdev); | ||
641 | } | 654 | } |
642 | #else | 655 | #else |
643 | printk(KERN_ERR "IP2: PCI card specified but PCI " | 656 | printk(KERN_ERR "IP2: PCI card specified but PCI " |
@@ -656,7 +669,6 @@ static int __init ip2_loadmain(void) | |||
656 | break; | 669 | break; |
657 | } /* switch */ | 670 | } /* switch */ |
658 | } /* for */ | 671 | } /* for */ |
659 | pci_dev_put(pdev); | ||
660 | 672 | ||
661 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { | 673 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
662 | if (ip2config.addr[i]) { | 674 | if (ip2config.addr[i]) { |
@@ -3197,3 +3209,5 @@ static struct pci_device_id ip2main_pci_tbl[] __devinitdata = { | |||
3197 | }; | 3209 | }; |
3198 | 3210 | ||
3199 | MODULE_DEVICE_TABLE(pci, ip2main_pci_tbl); | 3211 | MODULE_DEVICE_TABLE(pci, ip2main_pci_tbl); |
3212 | |||
3213 | MODULE_FIRMWARE("intelliport2.bin"); | ||
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 300d5bd6cd06..be2e8f9a27c3 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -113,6 +113,8 @@ | |||
113 | * 64-bit verification | 113 | * 64-bit verification |
114 | */ | 114 | */ |
115 | 115 | ||
116 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
117 | |||
116 | #include <linux/module.h> | 118 | #include <linux/module.h> |
117 | #include <linux/firmware.h> | 119 | #include <linux/firmware.h> |
118 | #include <linux/kernel.h> | 120 | #include <linux/kernel.h> |
@@ -140,7 +142,6 @@ | |||
140 | #define InterruptTheCard(base) outw(0, (base) + 0xc) | 142 | #define InterruptTheCard(base) outw(0, (base) + 0xc) |
141 | #define ClearInterrupt(base) inw((base) + 0x0a) | 143 | #define ClearInterrupt(base) inw((base) + 0x0a) |
142 | 144 | ||
143 | #define pr_dbg(str...) pr_debug("ISICOM: " str) | ||
144 | #ifdef DEBUG | 145 | #ifdef DEBUG |
145 | #define isicom_paranoia_check(a, b, c) __isicom_paranoia_check((a), (b), (c)) | 146 | #define isicom_paranoia_check(a, b, c) __isicom_paranoia_check((a), (b), (c)) |
146 | #else | 147 | #else |
@@ -249,8 +250,7 @@ static int lock_card(struct isi_board *card) | |||
249 | spin_unlock_irqrestore(&card->card_lock, card->flags); | 250 | spin_unlock_irqrestore(&card->card_lock, card->flags); |
250 | msleep(10); | 251 | msleep(10); |
251 | } | 252 | } |
252 | printk(KERN_WARNING "ISICOM: Failed to lock Card (0x%lx)\n", | 253 | pr_warning("Failed to lock Card (0x%lx)\n", card->base); |
253 | card->base); | ||
254 | 254 | ||
255 | return 0; /* Failed to acquire the card! */ | 255 | return 0; /* Failed to acquire the card! */ |
256 | } | 256 | } |
@@ -379,13 +379,13 @@ static inline int __isicom_paranoia_check(struct isi_port const *port, | |||
379 | char *name, const char *routine) | 379 | char *name, const char *routine) |
380 | { | 380 | { |
381 | if (!port) { | 381 | if (!port) { |
382 | printk(KERN_WARNING "ISICOM: Warning: bad isicom magic for " | 382 | pr_warning("Warning: bad isicom magic for dev %s in %s.\n", |
383 | "dev %s in %s.\n", name, routine); | 383 | name, routine); |
384 | return 1; | 384 | return 1; |
385 | } | 385 | } |
386 | if (port->magic != ISICOM_MAGIC) { | 386 | if (port->magic != ISICOM_MAGIC) { |
387 | printk(KERN_WARNING "ISICOM: Warning: NULL isicom port for " | 387 | pr_warning("Warning: NULL isicom port for dev %s in %s.\n", |
388 | "dev %s in %s.\n", name, routine); | 388 | name, routine); |
389 | return 1; | 389 | return 1; |
390 | } | 390 | } |
391 | 391 | ||
@@ -450,8 +450,8 @@ static void isicom_tx(unsigned long _data) | |||
450 | if (!(inw(base + 0x02) & (1 << port->channel))) | 450 | if (!(inw(base + 0x02) & (1 << port->channel))) |
451 | continue; | 451 | continue; |
452 | 452 | ||
453 | pr_dbg("txing %d bytes, port%d.\n", txcount, | 453 | pr_debug("txing %d bytes, port%d.\n", |
454 | port->channel + 1); | 454 | txcount, port->channel + 1); |
455 | outw((port->channel << isi_card[card].shift_count) | txcount, | 455 | outw((port->channel << isi_card[card].shift_count) | txcount, |
456 | base); | 456 | base); |
457 | residue = NO; | 457 | residue = NO; |
@@ -547,8 +547,8 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
547 | byte_count = header & 0xff; | 547 | byte_count = header & 0xff; |
548 | 548 | ||
549 | if (channel + 1 > card->port_count) { | 549 | if (channel + 1 > card->port_count) { |
550 | printk(KERN_WARNING "ISICOM: isicom_interrupt(0x%lx): " | 550 | pr_warning("%s(0x%lx): %d(channel) > port_count.\n", |
551 | "%d(channel) > port_count.\n", base, channel+1); | 551 | __func__, base, channel+1); |
552 | outw(0x0000, base+0x04); /* enable interrupts */ | 552 | outw(0x0000, base+0x04); /* enable interrupts */ |
553 | spin_unlock(&card->card_lock); | 553 | spin_unlock(&card->card_lock); |
554 | return IRQ_HANDLED; | 554 | return IRQ_HANDLED; |
@@ -582,14 +582,15 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
582 | if (port->status & ISI_DCD) { | 582 | if (port->status & ISI_DCD) { |
583 | if (!(header & ISI_DCD)) { | 583 | if (!(header & ISI_DCD)) { |
584 | /* Carrier has been lost */ | 584 | /* Carrier has been lost */ |
585 | pr_dbg("interrupt: DCD->low.\n" | 585 | pr_debug("%s: DCD->low.\n", |
586 | ); | 586 | __func__); |
587 | port->status &= ~ISI_DCD; | 587 | port->status &= ~ISI_DCD; |
588 | tty_hangup(tty); | 588 | tty_hangup(tty); |
589 | } | 589 | } |
590 | } else if (header & ISI_DCD) { | 590 | } else if (header & ISI_DCD) { |
591 | /* Carrier has been detected */ | 591 | /* Carrier has been detected */ |
592 | pr_dbg("interrupt: DCD->high.\n"); | 592 | pr_debug("%s: DCD->high.\n", |
593 | __func__); | ||
593 | port->status |= ISI_DCD; | 594 | port->status |= ISI_DCD; |
594 | wake_up_interruptible(&port->port.open_wait); | 595 | wake_up_interruptible(&port->port.open_wait); |
595 | } | 596 | } |
@@ -641,17 +642,19 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
641 | break; | 642 | break; |
642 | 643 | ||
643 | case 2: /* Statistics */ | 644 | case 2: /* Statistics */ |
644 | pr_dbg("isicom_interrupt: stats!!!.\n"); | 645 | pr_debug("%s: stats!!!\n", __func__); |
645 | break; | 646 | break; |
646 | 647 | ||
647 | default: | 648 | default: |
648 | pr_dbg("Intr: Unknown code in status packet.\n"); | 649 | pr_debug("%s: Unknown code in status packet.\n", |
650 | __func__); | ||
649 | break; | 651 | break; |
650 | } | 652 | } |
651 | } else { /* Data Packet */ | 653 | } else { /* Data Packet */ |
652 | 654 | ||
653 | count = tty_prepare_flip_string(tty, &rp, byte_count & ~1); | 655 | count = tty_prepare_flip_string(tty, &rp, byte_count & ~1); |
654 | pr_dbg("Intr: Can rx %d of %d bytes.\n", count, byte_count); | 656 | pr_debug("%s: Can rx %d of %d bytes.\n", |
657 | __func__, count, byte_count); | ||
655 | word_count = count >> 1; | 658 | word_count = count >> 1; |
656 | insw(base, rp, word_count); | 659 | insw(base, rp, word_count); |
657 | byte_count -= (word_count << 1); | 660 | byte_count -= (word_count << 1); |
@@ -661,8 +664,8 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
661 | byte_count -= 2; | 664 | byte_count -= 2; |
662 | } | 665 | } |
663 | if (byte_count > 0) { | 666 | if (byte_count > 0) { |
664 | pr_dbg("Intr(0x%lx:%d): Flip buffer overflow! dropping " | 667 | pr_debug("%s(0x%lx:%d): Flip buffer overflow! dropping bytes...\n", |
665 | "bytes...\n", base, channel + 1); | 668 | __func__, base, channel + 1); |
666 | /* drain out unread xtra data */ | 669 | /* drain out unread xtra data */ |
667 | while (byte_count > 0) { | 670 | while (byte_count > 0) { |
668 | inw(base); | 671 | inw(base); |
@@ -888,8 +891,8 @@ static void isicom_shutdown_port(struct isi_port *port) | |||
888 | struct isi_board *card = port->card; | 891 | struct isi_board *card = port->card; |
889 | 892 | ||
890 | if (--card->count < 0) { | 893 | if (--card->count < 0) { |
891 | pr_dbg("isicom_shutdown_port: bad board(0x%lx) count %d.\n", | 894 | pr_debug("%s: bad board(0x%lx) count %d.\n", |
892 | card->base, card->count); | 895 | __func__, card->base, card->count); |
893 | card->count = 0; | 896 | card->count = 0; |
894 | } | 897 | } |
895 | /* last port was closed, shutdown that board too */ | 898 | /* last port was closed, shutdown that board too */ |
@@ -1681,13 +1684,13 @@ static int __init isicom_init(void) | |||
1681 | 1684 | ||
1682 | retval = tty_register_driver(isicom_normal); | 1685 | retval = tty_register_driver(isicom_normal); |
1683 | if (retval) { | 1686 | if (retval) { |
1684 | pr_dbg("Couldn't register the dialin driver\n"); | 1687 | pr_debug("Couldn't register the dialin driver\n"); |
1685 | goto err_puttty; | 1688 | goto err_puttty; |
1686 | } | 1689 | } |
1687 | 1690 | ||
1688 | retval = pci_register_driver(&isicom_driver); | 1691 | retval = pci_register_driver(&isicom_driver); |
1689 | if (retval < 0) { | 1692 | if (retval < 0) { |
1690 | printk(KERN_ERR "ISICOM: Unable to register pci driver.\n"); | 1693 | pr_err("Unable to register pci driver.\n"); |
1691 | goto err_unrtty; | 1694 | goto err_unrtty; |
1692 | } | 1695 | } |
1693 | 1696 | ||
@@ -1717,3 +1720,8 @@ module_exit(isicom_exit); | |||
1717 | MODULE_AUTHOR("MultiTech"); | 1720 | MODULE_AUTHOR("MultiTech"); |
1718 | MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech"); | 1721 | MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech"); |
1719 | MODULE_LICENSE("GPL"); | 1722 | MODULE_LICENSE("GPL"); |
1723 | MODULE_FIRMWARE("isi608.bin"); | ||
1724 | MODULE_FIRMWARE("isi608em.bin"); | ||
1725 | MODULE_FIRMWARE("isi616em.bin"); | ||
1726 | MODULE_FIRMWARE("isi4608.bin"); | ||
1727 | MODULE_FIRMWARE("isi4616.bin"); | ||
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index 63ee3bbc1ce4..166495d6a1d7 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c | |||
@@ -164,24 +164,25 @@ static unsigned int moxaFuncTout = HZ / 2; | |||
164 | static unsigned int moxaLowWaterChk; | 164 | static unsigned int moxaLowWaterChk; |
165 | static DEFINE_MUTEX(moxa_openlock); | 165 | static DEFINE_MUTEX(moxa_openlock); |
166 | static DEFINE_SPINLOCK(moxa_lock); | 166 | static DEFINE_SPINLOCK(moxa_lock); |
167 | /* Variables for insmod */ | 167 | |
168 | #ifdef MODULE | ||
169 | static unsigned long baseaddr[MAX_BOARDS]; | 168 | static unsigned long baseaddr[MAX_BOARDS]; |
170 | static unsigned int type[MAX_BOARDS]; | 169 | static unsigned int type[MAX_BOARDS]; |
171 | static unsigned int numports[MAX_BOARDS]; | 170 | static unsigned int numports[MAX_BOARDS]; |
172 | #endif | ||
173 | 171 | ||
174 | MODULE_AUTHOR("William Chen"); | 172 | MODULE_AUTHOR("William Chen"); |
175 | MODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver"); | 173 | MODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver"); |
176 | MODULE_LICENSE("GPL"); | 174 | MODULE_LICENSE("GPL"); |
177 | #ifdef MODULE | 175 | MODULE_FIRMWARE("c218tunx.cod"); |
176 | MODULE_FIRMWARE("cp204unx.cod"); | ||
177 | MODULE_FIRMWARE("c320tunx.cod"); | ||
178 | |||
178 | module_param_array(type, uint, NULL, 0); | 179 | module_param_array(type, uint, NULL, 0); |
179 | MODULE_PARM_DESC(type, "card type: C218=2, C320=4"); | 180 | MODULE_PARM_DESC(type, "card type: C218=2, C320=4"); |
180 | module_param_array(baseaddr, ulong, NULL, 0); | 181 | module_param_array(baseaddr, ulong, NULL, 0); |
181 | MODULE_PARM_DESC(baseaddr, "base address"); | 182 | MODULE_PARM_DESC(baseaddr, "base address"); |
182 | module_param_array(numports, uint, NULL, 0); | 183 | module_param_array(numports, uint, NULL, 0); |
183 | MODULE_PARM_DESC(numports, "numports (ignored for C218)"); | 184 | MODULE_PARM_DESC(numports, "numports (ignored for C218)"); |
184 | #endif | 185 | |
185 | module_param(ttymajor, int, 0); | 186 | module_param(ttymajor, int, 0); |
186 | 187 | ||
187 | /* | 188 | /* |
@@ -1024,6 +1025,8 @@ static int __init moxa_init(void) | |||
1024 | { | 1025 | { |
1025 | unsigned int isabrds = 0; | 1026 | unsigned int isabrds = 0; |
1026 | int retval = 0; | 1027 | int retval = 0; |
1028 | struct moxa_board_conf *brd = moxa_boards; | ||
1029 | unsigned int i; | ||
1027 | 1030 | ||
1028 | printk(KERN_INFO "MOXA Intellio family driver version %s\n", | 1031 | printk(KERN_INFO "MOXA Intellio family driver version %s\n", |
1029 | MOXA_VERSION); | 1032 | MOXA_VERSION); |
@@ -1051,10 +1054,7 @@ static int __init moxa_init(void) | |||
1051 | } | 1054 | } |
1052 | 1055 | ||
1053 | /* Find the boards defined from module args. */ | 1056 | /* Find the boards defined from module args. */ |
1054 | #ifdef MODULE | 1057 | |
1055 | { | ||
1056 | struct moxa_board_conf *brd = moxa_boards; | ||
1057 | unsigned int i; | ||
1058 | for (i = 0; i < MAX_BOARDS; i++) { | 1058 | for (i = 0; i < MAX_BOARDS; i++) { |
1059 | if (!baseaddr[i]) | 1059 | if (!baseaddr[i]) |
1060 | break; | 1060 | break; |
@@ -1087,8 +1087,6 @@ static int __init moxa_init(void) | |||
1087 | isabrds++; | 1087 | isabrds++; |
1088 | } | 1088 | } |
1089 | } | 1089 | } |
1090 | } | ||
1091 | #endif | ||
1092 | 1090 | ||
1093 | #ifdef CONFIG_PCI | 1091 | #ifdef CONFIG_PCI |
1094 | retval = pci_register_driver(&moxa_pci_driver); | 1092 | retval = pci_register_driver(&moxa_pci_driver); |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 3d923065d9a2..e0c5d2a69046 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -895,8 +895,7 @@ static int mxser_activate(struct tty_port *port, struct tty_struct *tty) | |||
895 | if (inb(info->ioaddr + UART_LSR) == 0xff) { | 895 | if (inb(info->ioaddr + UART_LSR) == 0xff) { |
896 | spin_unlock_irqrestore(&info->slock, flags); | 896 | spin_unlock_irqrestore(&info->slock, flags); |
897 | if (capable(CAP_SYS_ADMIN)) { | 897 | if (capable(CAP_SYS_ADMIN)) { |
898 | if (tty) | 898 | set_bit(TTY_IO_ERROR, &tty->flags); |
899 | set_bit(TTY_IO_ERROR, &tty->flags); | ||
900 | return 0; | 899 | return 0; |
901 | } else | 900 | } else |
902 | return -ENODEV; | 901 | return -ENODEV; |
diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index 2ad7d37afbd0..a3f32a15fde4 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c | |||
@@ -136,10 +136,6 @@ static int debug; | |||
136 | #define RECEIVE_BUF_MAX 4 | 136 | #define RECEIVE_BUF_MAX 4 |
137 | 137 | ||
138 | 138 | ||
139 | /* Define all types of vendors and devices to support */ | ||
140 | #define VENDOR1 0x1931 /* Vendor Option */ | ||
141 | #define DEVICE1 0x000c /* HSDPA card */ | ||
142 | |||
143 | #define R_IIR 0x0000 /* Interrupt Identity Register */ | 139 | #define R_IIR 0x0000 /* Interrupt Identity Register */ |
144 | #define R_FCR 0x0000 /* Flow Control Register */ | 140 | #define R_FCR 0x0000 /* Flow Control Register */ |
145 | #define R_IER 0x0004 /* Interrupt Enable Register */ | 141 | #define R_IER 0x0004 /* Interrupt Enable Register */ |
@@ -371,6 +367,8 @@ struct port { | |||
371 | struct mutex tty_sem; | 367 | struct mutex tty_sem; |
372 | wait_queue_head_t tty_wait; | 368 | wait_queue_head_t tty_wait; |
373 | struct async_icount tty_icount; | 369 | struct async_icount tty_icount; |
370 | |||
371 | struct nozomi *dc; | ||
374 | }; | 372 | }; |
375 | 373 | ||
376 | /* Private data one for each card in the system */ | 374 | /* Private data one for each card in the system */ |
@@ -405,7 +403,7 @@ struct buffer { | |||
405 | 403 | ||
406 | /* Global variables */ | 404 | /* Global variables */ |
407 | static const struct pci_device_id nozomi_pci_tbl[] __devinitconst = { | 405 | static const struct pci_device_id nozomi_pci_tbl[] __devinitconst = { |
408 | {PCI_DEVICE(VENDOR1, DEVICE1)}, | 406 | {PCI_DEVICE(0x1931, 0x000c)}, /* Nozomi HSDPA */ |
409 | {}, | 407 | {}, |
410 | }; | 408 | }; |
411 | 409 | ||
@@ -414,6 +412,8 @@ MODULE_DEVICE_TABLE(pci, nozomi_pci_tbl); | |||
414 | static struct nozomi *ndevs[NOZOMI_MAX_CARDS]; | 412 | static struct nozomi *ndevs[NOZOMI_MAX_CARDS]; |
415 | static struct tty_driver *ntty_driver; | 413 | static struct tty_driver *ntty_driver; |
416 | 414 | ||
415 | static const struct tty_port_operations noz_tty_port_ops; | ||
416 | |||
417 | /* | 417 | /* |
418 | * find card by tty_index | 418 | * find card by tty_index |
419 | */ | 419 | */ |
@@ -853,8 +853,6 @@ static int receive_data(enum port_type index, struct nozomi *dc) | |||
853 | goto put; | 853 | goto put; |
854 | } | 854 | } |
855 | 855 | ||
856 | tty_buffer_request_room(tty, size); | ||
857 | |||
858 | while (size > 0) { | 856 | while (size > 0) { |
859 | read_mem32((u32 *) buf, addr + offset, RECEIVE_BUF_MAX); | 857 | read_mem32((u32 *) buf, addr + offset, RECEIVE_BUF_MAX); |
860 | 858 | ||
@@ -1473,9 +1471,11 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
1473 | 1471 | ||
1474 | for (i = 0; i < MAX_PORT; i++) { | 1472 | for (i = 0; i < MAX_PORT; i++) { |
1475 | struct device *tty_dev; | 1473 | struct device *tty_dev; |
1476 | 1474 | struct port *port = &dc->port[i]; | |
1477 | mutex_init(&dc->port[i].tty_sem); | 1475 | port->dc = dc; |
1478 | tty_port_init(&dc->port[i].port); | 1476 | mutex_init(&port->tty_sem); |
1477 | tty_port_init(&port->port); | ||
1478 | port->port.ops = &noz_tty_port_ops; | ||
1479 | tty_dev = tty_register_device(ntty_driver, dc->index_start + i, | 1479 | tty_dev = tty_register_device(ntty_driver, dc->index_start + i, |
1480 | &pdev->dev); | 1480 | &pdev->dev); |
1481 | 1481 | ||
@@ -1600,67 +1600,74 @@ static void set_dtr(const struct tty_struct *tty, int dtr) | |||
1600 | * ---------------------------------------------------------------------------- | 1600 | * ---------------------------------------------------------------------------- |
1601 | */ | 1601 | */ |
1602 | 1602 | ||
1603 | /* Called when the userspace process opens the tty, /dev/noz*. */ | 1603 | static int ntty_install(struct tty_driver *driver, struct tty_struct *tty) |
1604 | static int ntty_open(struct tty_struct *tty, struct file *file) | ||
1605 | { | 1604 | { |
1606 | struct port *port = get_port_by_tty(tty); | 1605 | struct port *port = get_port_by_tty(tty); |
1607 | struct nozomi *dc = get_dc_by_tty(tty); | 1606 | struct nozomi *dc = get_dc_by_tty(tty); |
1608 | unsigned long flags; | 1607 | int ret; |
1609 | |||
1610 | if (!port || !dc || dc->state != NOZOMI_STATE_READY) | 1608 | if (!port || !dc || dc->state != NOZOMI_STATE_READY) |
1611 | return -ENODEV; | 1609 | return -ENODEV; |
1612 | 1610 | ret = tty_init_termios(tty); | |
1613 | if (mutex_lock_interruptible(&port->tty_sem)) | 1611 | if (ret == 0) { |
1614 | return -ERESTARTSYS; | 1612 | tty_driver_kref_get(driver); |
1615 | 1613 | driver->ttys[tty->index] = tty; | |
1616 | port->port.count++; | ||
1617 | dc->open_ttys++; | ||
1618 | |||
1619 | /* Enable interrupt downlink for channel */ | ||
1620 | if (port->port.count == 1) { | ||
1621 | tty->driver_data = port; | ||
1622 | tty_port_tty_set(&port->port, tty); | ||
1623 | DBG1("open: %d", port->token_dl); | ||
1624 | spin_lock_irqsave(&dc->spin_mutex, flags); | ||
1625 | dc->last_ier = dc->last_ier | port->token_dl; | ||
1626 | writew(dc->last_ier, dc->reg_ier); | ||
1627 | spin_unlock_irqrestore(&dc->spin_mutex, flags); | ||
1628 | } | 1614 | } |
1629 | mutex_unlock(&port->tty_sem); | 1615 | return ret; |
1630 | return 0; | ||
1631 | } | 1616 | } |
1632 | 1617 | ||
1633 | /* Called when the userspace process close the tty, /dev/noz*. Also | 1618 | static void ntty_cleanup(struct tty_struct *tty) |
1634 | called immediately if ntty_open fails in which case tty->driver_data | 1619 | { |
1635 | will be NULL an we exit by the first return */ | 1620 | tty->driver_data = NULL; |
1621 | } | ||
1636 | 1622 | ||
1637 | static void ntty_close(struct tty_struct *tty, struct file *file) | 1623 | static int ntty_activate(struct tty_port *tport, struct tty_struct *tty) |
1638 | { | 1624 | { |
1639 | struct nozomi *dc = get_dc_by_tty(tty); | 1625 | struct port *port = container_of(tport, struct port, port); |
1640 | struct port *nport = tty->driver_data; | 1626 | struct nozomi *dc = port->dc; |
1641 | struct tty_port *port = &nport->port; | ||
1642 | unsigned long flags; | 1627 | unsigned long flags; |
1643 | 1628 | ||
1644 | if (!dc || !nport) | 1629 | DBG1("open: %d", port->token_dl); |
1645 | return; | 1630 | spin_lock_irqsave(&dc->spin_mutex, flags); |
1631 | dc->last_ier = dc->last_ier | port->token_dl; | ||
1632 | writew(dc->last_ier, dc->reg_ier); | ||
1633 | dc->open_ttys++; | ||
1634 | spin_unlock_irqrestore(&dc->spin_mutex, flags); | ||
1635 | printk("noz: activated %d: %p\n", tty->index, tport); | ||
1636 | return 0; | ||
1637 | } | ||
1646 | 1638 | ||
1647 | /* Users cannot interrupt a close */ | 1639 | static int ntty_open(struct tty_struct *tty, struct file *filp) |
1648 | mutex_lock(&nport->tty_sem); | 1640 | { |
1641 | struct port *port = get_port_by_tty(tty); | ||
1642 | return tty_port_open(&port->port, tty, filp); | ||
1643 | } | ||
1649 | 1644 | ||
1650 | WARN_ON(!port->count); | 1645 | static void ntty_shutdown(struct tty_port *tport) |
1646 | { | ||
1647 | struct port *port = container_of(tport, struct port, port); | ||
1648 | struct nozomi *dc = port->dc; | ||
1649 | unsigned long flags; | ||
1651 | 1650 | ||
1651 | DBG1("close: %d", port->token_dl); | ||
1652 | spin_lock_irqsave(&dc->spin_mutex, flags); | ||
1653 | dc->last_ier &= ~(port->token_dl); | ||
1654 | writew(dc->last_ier, dc->reg_ier); | ||
1652 | dc->open_ttys--; | 1655 | dc->open_ttys--; |
1653 | port->count--; | 1656 | spin_unlock_irqrestore(&dc->spin_mutex, flags); |
1657 | printk("noz: shutdown %p\n", tport); | ||
1658 | } | ||
1654 | 1659 | ||
1655 | if (port->count == 0) { | 1660 | static void ntty_close(struct tty_struct *tty, struct file *filp) |
1656 | DBG1("close: %d", nport->token_dl); | 1661 | { |
1657 | tty_port_tty_set(port, NULL); | 1662 | struct port *port = tty->driver_data; |
1658 | spin_lock_irqsave(&dc->spin_mutex, flags); | 1663 | if (port) |
1659 | dc->last_ier &= ~(nport->token_dl); | 1664 | tty_port_close(&port->port, tty, filp); |
1660 | writew(dc->last_ier, dc->reg_ier); | 1665 | } |
1661 | spin_unlock_irqrestore(&dc->spin_mutex, flags); | 1666 | |
1662 | } | 1667 | static void ntty_hangup(struct tty_struct *tty) |
1663 | mutex_unlock(&nport->tty_sem); | 1668 | { |
1669 | struct port *port = tty->driver_data; | ||
1670 | tty_port_hangup(&port->port); | ||
1664 | } | 1671 | } |
1665 | 1672 | ||
1666 | /* | 1673 | /* |
@@ -1680,15 +1687,7 @@ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer, | |||
1680 | if (!dc || !port) | 1687 | if (!dc || !port) |
1681 | return -ENODEV; | 1688 | return -ENODEV; |
1682 | 1689 | ||
1683 | if (unlikely(!mutex_trylock(&port->tty_sem))) { | 1690 | mutex_lock(&port->tty_sem); |
1684 | /* | ||
1685 | * must test lock as tty layer wraps calls | ||
1686 | * to this function with BKL | ||
1687 | */ | ||
1688 | dev_err(&dc->pdev->dev, "Would have deadlocked - " | ||
1689 | "return EAGAIN\n"); | ||
1690 | return -EAGAIN; | ||
1691 | } | ||
1692 | 1691 | ||
1693 | if (unlikely(!port->port.count)) { | 1692 | if (unlikely(!port->port.count)) { |
1694 | DBG1(" "); | 1693 | DBG1(" "); |
@@ -1728,25 +1727,23 @@ exit: | |||
1728 | * This method is called by the upper tty layer. | 1727 | * This method is called by the upper tty layer. |
1729 | * #according to sources N_TTY.c it expects a value >= 0 and | 1728 | * #according to sources N_TTY.c it expects a value >= 0 and |
1730 | * does not check for negative values. | 1729 | * does not check for negative values. |
1730 | * | ||
1731 | * If the port is unplugged report lots of room and let the bits | ||
1732 | * dribble away so we don't block anything. | ||
1731 | */ | 1733 | */ |
1732 | static int ntty_write_room(struct tty_struct *tty) | 1734 | static int ntty_write_room(struct tty_struct *tty) |
1733 | { | 1735 | { |
1734 | struct port *port = tty->driver_data; | 1736 | struct port *port = tty->driver_data; |
1735 | int room = 0; | 1737 | int room = 4096; |
1736 | const struct nozomi *dc = get_dc_by_tty(tty); | 1738 | const struct nozomi *dc = get_dc_by_tty(tty); |
1737 | 1739 | ||
1738 | if (!dc || !port) | 1740 | if (dc) { |
1739 | return 0; | 1741 | mutex_lock(&port->tty_sem); |
1740 | if (!mutex_trylock(&port->tty_sem)) | 1742 | if (port->port.count) |
1741 | return 0; | 1743 | room = port->fifo_ul.size - |
1742 | 1744 | kfifo_len(&port->fifo_ul); | |
1743 | if (!port->port.count) | 1745 | mutex_unlock(&port->tty_sem); |
1744 | goto exit; | 1746 | } |
1745 | |||
1746 | room = port->fifo_ul.size - kfifo_len(&port->fifo_ul); | ||
1747 | |||
1748 | exit: | ||
1749 | mutex_unlock(&port->tty_sem); | ||
1750 | return room; | 1747 | return room; |
1751 | } | 1748 | } |
1752 | 1749 | ||
@@ -1906,10 +1903,16 @@ exit_in_buffer: | |||
1906 | return rval; | 1903 | return rval; |
1907 | } | 1904 | } |
1908 | 1905 | ||
1906 | static const struct tty_port_operations noz_tty_port_ops = { | ||
1907 | .activate = ntty_activate, | ||
1908 | .shutdown = ntty_shutdown, | ||
1909 | }; | ||
1910 | |||
1909 | static const struct tty_operations tty_ops = { | 1911 | static const struct tty_operations tty_ops = { |
1910 | .ioctl = ntty_ioctl, | 1912 | .ioctl = ntty_ioctl, |
1911 | .open = ntty_open, | 1913 | .open = ntty_open, |
1912 | .close = ntty_close, | 1914 | .close = ntty_close, |
1915 | .hangup = ntty_hangup, | ||
1913 | .write = ntty_write, | 1916 | .write = ntty_write, |
1914 | .write_room = ntty_write_room, | 1917 | .write_room = ntty_write_room, |
1915 | .unthrottle = ntty_unthrottle, | 1918 | .unthrottle = ntty_unthrottle, |
@@ -1917,6 +1920,8 @@ static const struct tty_operations tty_ops = { | |||
1917 | .chars_in_buffer = ntty_chars_in_buffer, | 1920 | .chars_in_buffer = ntty_chars_in_buffer, |
1918 | .tiocmget = ntty_tiocmget, | 1921 | .tiocmget = ntty_tiocmget, |
1919 | .tiocmset = ntty_tiocmset, | 1922 | .tiocmset = ntty_tiocmset, |
1923 | .install = ntty_install, | ||
1924 | .cleanup = ntty_cleanup, | ||
1920 | }; | 1925 | }; |
1921 | 1926 | ||
1922 | /* Module initialization */ | 1927 | /* Module initialization */ |
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index 452370af95de..986aa606a6b6 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c | |||
@@ -658,8 +658,7 @@ static irqreturn_t cd2401_rx_interrupt(int irq, void *dev_id) | |||
658 | info->mon.char_max = char_count; | 658 | info->mon.char_max = char_count; |
659 | info->mon.char_last = char_count; | 659 | info->mon.char_last = char_count; |
660 | #endif | 660 | #endif |
661 | len = tty_buffer_request_room(tty, char_count); | 661 | while (char_count--) { |
662 | while (len--) { | ||
663 | data = base_addr[CyRDR]; | 662 | data = base_addr[CyRDR]; |
664 | tty_insert_flip_char(tty, data, TTY_NORMAL); | 663 | tty_insert_flip_char(tty, data, TTY_NORMAL); |
665 | #ifdef CYCLOM_16Y_HACK | 664 | #ifdef CYCLOM_16Y_HACK |
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index 268e17f9ec3f..07ac14d949ce 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c | |||
@@ -646,8 +646,6 @@ static void sx_receive(struct specialix_board *bp) | |||
646 | dprintk(SX_DEBUG_RX, "port: %p: count: %d\n", port, count); | 646 | dprintk(SX_DEBUG_RX, "port: %p: count: %d\n", port, count); |
647 | port->hits[count > 8 ? 9 : count]++; | 647 | port->hits[count > 8 ? 9 : count]++; |
648 | 648 | ||
649 | tty_buffer_request_room(tty, count); | ||
650 | |||
651 | while (count--) | 649 | while (count--) |
652 | tty_insert_flip_char(tty, sx_in(bp, CD186x_RDR), TTY_NORMAL); | 650 | tty_insert_flip_char(tty, sx_in(bp, CD186x_RDR), TTY_NORMAL); |
653 | tty_flip_buffer_push(tty); | 651 | tty_flip_buffer_push(tty); |
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index 4846b73ef28d..0658fc548222 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c | |||
@@ -2031,7 +2031,7 @@ static int mgsl_put_char(struct tty_struct *tty, unsigned char ch) | |||
2031 | if (mgsl_paranoia_check(info, tty->name, "mgsl_put_char")) | 2031 | if (mgsl_paranoia_check(info, tty->name, "mgsl_put_char")) |
2032 | return 0; | 2032 | return 0; |
2033 | 2033 | ||
2034 | if (!tty || !info->xmit_buf) | 2034 | if (!info->xmit_buf) |
2035 | return 0; | 2035 | return 0; |
2036 | 2036 | ||
2037 | spin_lock_irqsave(&info->irq_spinlock, flags); | 2037 | spin_lock_irqsave(&info->irq_spinlock, flags); |
@@ -2121,7 +2121,7 @@ static int mgsl_write(struct tty_struct * tty, | |||
2121 | if (mgsl_paranoia_check(info, tty->name, "mgsl_write")) | 2121 | if (mgsl_paranoia_check(info, tty->name, "mgsl_write")) |
2122 | goto cleanup; | 2122 | goto cleanup; |
2123 | 2123 | ||
2124 | if (!tty || !info->xmit_buf) | 2124 | if (!info->xmit_buf) |
2125 | goto cleanup; | 2125 | goto cleanup; |
2126 | 2126 | ||
2127 | if ( info->params.mode == MGSL_MODE_HDLC || | 2127 | if ( info->params.mode == MGSL_MODE_HDLC || |
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index 8678f0c8699d..4561ce2fba6d 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -468,7 +468,7 @@ static unsigned int free_tbuf_count(struct slgt_info *info); | |||
468 | static unsigned int tbuf_bytes(struct slgt_info *info); | 468 | static unsigned int tbuf_bytes(struct slgt_info *info); |
469 | static void reset_tbufs(struct slgt_info *info); | 469 | static void reset_tbufs(struct slgt_info *info); |
470 | static void tdma_reset(struct slgt_info *info); | 470 | static void tdma_reset(struct slgt_info *info); |
471 | static void tx_load(struct slgt_info *info, const char *buf, unsigned int count); | 471 | static bool tx_load(struct slgt_info *info, const char *buf, unsigned int count); |
472 | 472 | ||
473 | static void get_signals(struct slgt_info *info); | 473 | static void get_signals(struct slgt_info *info); |
474 | static void set_signals(struct slgt_info *info); | 474 | static void set_signals(struct slgt_info *info); |
@@ -813,59 +813,32 @@ static int write(struct tty_struct *tty, | |||
813 | int ret = 0; | 813 | int ret = 0; |
814 | struct slgt_info *info = tty->driver_data; | 814 | struct slgt_info *info = tty->driver_data; |
815 | unsigned long flags; | 815 | unsigned long flags; |
816 | unsigned int bufs_needed; | ||
817 | 816 | ||
818 | if (sanity_check(info, tty->name, "write")) | 817 | if (sanity_check(info, tty->name, "write")) |
819 | goto cleanup; | 818 | return -EIO; |
819 | |||
820 | DBGINFO(("%s write count=%d\n", info->device_name, count)); | 820 | DBGINFO(("%s write count=%d\n", info->device_name, count)); |
821 | 821 | ||
822 | if (!info->tx_buf) | 822 | if (!info->tx_buf || (count > info->max_frame_size)) |
823 | goto cleanup; | 823 | return -EIO; |
824 | 824 | ||
825 | if (count > info->max_frame_size) { | 825 | if (!count || tty->stopped || tty->hw_stopped) |
826 | ret = -EIO; | 826 | return 0; |
827 | goto cleanup; | ||
828 | } | ||
829 | 827 | ||
830 | if (!count) | 828 | spin_lock_irqsave(&info->lock, flags); |
831 | goto cleanup; | ||
832 | 829 | ||
833 | if (!info->tx_active && info->tx_count) { | 830 | if (info->tx_count) { |
834 | /* send accumulated data from send_char() */ | 831 | /* send accumulated data from send_char() */ |
835 | tx_load(info, info->tx_buf, info->tx_count); | 832 | if (!tx_load(info, info->tx_buf, info->tx_count)) |
836 | goto start; | 833 | goto cleanup; |
834 | info->tx_count = 0; | ||
837 | } | 835 | } |
838 | bufs_needed = (count/DMABUFSIZE); | ||
839 | if (count % DMABUFSIZE) | ||
840 | ++bufs_needed; | ||
841 | if (bufs_needed > free_tbuf_count(info)) | ||
842 | goto cleanup; | ||
843 | 836 | ||
844 | ret = info->tx_count = count; | 837 | if (tx_load(info, buf, count)) |
845 | tx_load(info, buf, count); | 838 | ret = count; |
846 | goto start; | ||
847 | |||
848 | start: | ||
849 | if (info->tx_count && !tty->stopped && !tty->hw_stopped) { | ||
850 | spin_lock_irqsave(&info->lock,flags); | ||
851 | if (!info->tx_active) | ||
852 | tx_start(info); | ||
853 | else if (!(rd_reg32(info, TDCSR) & BIT0)) { | ||
854 | /* transmit still active but transmit DMA stopped */ | ||
855 | unsigned int i = info->tbuf_current; | ||
856 | if (!i) | ||
857 | i = info->tbuf_count; | ||
858 | i--; | ||
859 | /* if DMA buf unsent must try later after tx idle */ | ||
860 | if (desc_count(info->tbufs[i])) | ||
861 | ret = 0; | ||
862 | } | ||
863 | if (ret > 0) | ||
864 | update_tx_timer(info); | ||
865 | spin_unlock_irqrestore(&info->lock,flags); | ||
866 | } | ||
867 | 839 | ||
868 | cleanup: | 840 | cleanup: |
841 | spin_unlock_irqrestore(&info->lock, flags); | ||
869 | DBGINFO(("%s write rc=%d\n", info->device_name, ret)); | 842 | DBGINFO(("%s write rc=%d\n", info->device_name, ret)); |
870 | return ret; | 843 | return ret; |
871 | } | 844 | } |
@@ -882,7 +855,7 @@ static int put_char(struct tty_struct *tty, unsigned char ch) | |||
882 | if (!info->tx_buf) | 855 | if (!info->tx_buf) |
883 | return 0; | 856 | return 0; |
884 | spin_lock_irqsave(&info->lock,flags); | 857 | spin_lock_irqsave(&info->lock,flags); |
885 | if (!info->tx_active && (info->tx_count < info->max_frame_size)) { | 858 | if (info->tx_count < info->max_frame_size) { |
886 | info->tx_buf[info->tx_count++] = ch; | 859 | info->tx_buf[info->tx_count++] = ch; |
887 | ret = 1; | 860 | ret = 1; |
888 | } | 861 | } |
@@ -981,10 +954,8 @@ static void flush_chars(struct tty_struct *tty) | |||
981 | DBGINFO(("%s flush_chars start transmit\n", info->device_name)); | 954 | DBGINFO(("%s flush_chars start transmit\n", info->device_name)); |
982 | 955 | ||
983 | spin_lock_irqsave(&info->lock,flags); | 956 | spin_lock_irqsave(&info->lock,flags); |
984 | if (!info->tx_active && info->tx_count) { | 957 | if (info->tx_count && tx_load(info, info->tx_buf, info->tx_count)) |
985 | tx_load(info, info->tx_buf,info->tx_count); | 958 | info->tx_count = 0; |
986 | tx_start(info); | ||
987 | } | ||
988 | spin_unlock_irqrestore(&info->lock,flags); | 959 | spin_unlock_irqrestore(&info->lock,flags); |
989 | } | 960 | } |
990 | 961 | ||
@@ -997,10 +968,9 @@ static void flush_buffer(struct tty_struct *tty) | |||
997 | return; | 968 | return; |
998 | DBGINFO(("%s flush_buffer\n", info->device_name)); | 969 | DBGINFO(("%s flush_buffer\n", info->device_name)); |
999 | 970 | ||
1000 | spin_lock_irqsave(&info->lock,flags); | 971 | spin_lock_irqsave(&info->lock, flags); |
1001 | if (!info->tx_active) | 972 | info->tx_count = 0; |
1002 | info->tx_count = 0; | 973 | spin_unlock_irqrestore(&info->lock, flags); |
1003 | spin_unlock_irqrestore(&info->lock,flags); | ||
1004 | 974 | ||
1005 | tty_wakeup(tty); | 975 | tty_wakeup(tty); |
1006 | } | 976 | } |
@@ -1033,12 +1003,10 @@ static void tx_release(struct tty_struct *tty) | |||
1033 | if (sanity_check(info, tty->name, "tx_release")) | 1003 | if (sanity_check(info, tty->name, "tx_release")) |
1034 | return; | 1004 | return; |
1035 | DBGINFO(("%s tx_release\n", info->device_name)); | 1005 | DBGINFO(("%s tx_release\n", info->device_name)); |
1036 | spin_lock_irqsave(&info->lock,flags); | 1006 | spin_lock_irqsave(&info->lock, flags); |
1037 | if (!info->tx_active && info->tx_count) { | 1007 | if (info->tx_count && tx_load(info, info->tx_buf, info->tx_count)) |
1038 | tx_load(info, info->tx_buf, info->tx_count); | 1008 | info->tx_count = 0; |
1039 | tx_start(info); | 1009 | spin_unlock_irqrestore(&info->lock, flags); |
1040 | } | ||
1041 | spin_unlock_irqrestore(&info->lock,flags); | ||
1042 | } | 1010 | } |
1043 | 1011 | ||
1044 | /* | 1012 | /* |
@@ -1506,27 +1474,25 @@ static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb, | |||
1506 | 1474 | ||
1507 | DBGINFO(("%s hdlc_xmit\n", dev->name)); | 1475 | DBGINFO(("%s hdlc_xmit\n", dev->name)); |
1508 | 1476 | ||
1477 | if (!skb->len) | ||
1478 | return NETDEV_TX_OK; | ||
1479 | |||
1509 | /* stop sending until this frame completes */ | 1480 | /* stop sending until this frame completes */ |
1510 | netif_stop_queue(dev); | 1481 | netif_stop_queue(dev); |
1511 | 1482 | ||
1512 | /* copy data to device buffers */ | ||
1513 | info->tx_count = skb->len; | ||
1514 | tx_load(info, skb->data, skb->len); | ||
1515 | |||
1516 | /* update network statistics */ | 1483 | /* update network statistics */ |
1517 | dev->stats.tx_packets++; | 1484 | dev->stats.tx_packets++; |
1518 | dev->stats.tx_bytes += skb->len; | 1485 | dev->stats.tx_bytes += skb->len; |
1519 | 1486 | ||
1520 | /* done with socket buffer, so free it */ | ||
1521 | dev_kfree_skb(skb); | ||
1522 | |||
1523 | /* save start time for transmit timeout detection */ | 1487 | /* save start time for transmit timeout detection */ |
1524 | dev->trans_start = jiffies; | 1488 | dev->trans_start = jiffies; |
1525 | 1489 | ||
1526 | spin_lock_irqsave(&info->lock,flags); | 1490 | spin_lock_irqsave(&info->lock, flags); |
1527 | tx_start(info); | 1491 | tx_load(info, skb->data, skb->len); |
1528 | update_tx_timer(info); | 1492 | spin_unlock_irqrestore(&info->lock, flags); |
1529 | spin_unlock_irqrestore(&info->lock,flags); | 1493 | |
1494 | /* done with socket buffer, so free it */ | ||
1495 | dev_kfree_skb(skb); | ||
1530 | 1496 | ||
1531 | return NETDEV_TX_OK; | 1497 | return NETDEV_TX_OK; |
1532 | } | 1498 | } |
@@ -2180,7 +2146,7 @@ static void isr_serial(struct slgt_info *info) | |||
2180 | 2146 | ||
2181 | if (info->params.mode == MGSL_MODE_ASYNC) { | 2147 | if (info->params.mode == MGSL_MODE_ASYNC) { |
2182 | if (status & IRQ_TXIDLE) { | 2148 | if (status & IRQ_TXIDLE) { |
2183 | if (info->tx_count) | 2149 | if (info->tx_active) |
2184 | isr_txeom(info, status); | 2150 | isr_txeom(info, status); |
2185 | } | 2151 | } |
2186 | if (info->rx_pio && (status & IRQ_RXDATA)) | 2152 | if (info->rx_pio && (status & IRQ_RXDATA)) |
@@ -2276,13 +2242,42 @@ static void isr_tdma(struct slgt_info *info) | |||
2276 | } | 2242 | } |
2277 | } | 2243 | } |
2278 | 2244 | ||
2245 | /* | ||
2246 | * return true if there are unsent tx DMA buffers, otherwise false | ||
2247 | * | ||
2248 | * if there are unsent buffers then info->tbuf_start | ||
2249 | * is set to index of first unsent buffer | ||
2250 | */ | ||
2251 | static bool unsent_tbufs(struct slgt_info *info) | ||
2252 | { | ||
2253 | unsigned int i = info->tbuf_current; | ||
2254 | bool rc = false; | ||
2255 | |||
2256 | /* | ||
2257 | * search backwards from last loaded buffer (precedes tbuf_current) | ||
2258 | * for first unsent buffer (desc_count > 0) | ||
2259 | */ | ||
2260 | |||
2261 | do { | ||
2262 | if (i) | ||
2263 | i--; | ||
2264 | else | ||
2265 | i = info->tbuf_count - 1; | ||
2266 | if (!desc_count(info->tbufs[i])) | ||
2267 | break; | ||
2268 | info->tbuf_start = i; | ||
2269 | rc = true; | ||
2270 | } while (i != info->tbuf_current); | ||
2271 | |||
2272 | return rc; | ||
2273 | } | ||
2274 | |||
2279 | static void isr_txeom(struct slgt_info *info, unsigned short status) | 2275 | static void isr_txeom(struct slgt_info *info, unsigned short status) |
2280 | { | 2276 | { |
2281 | DBGISR(("%s txeom status=%04x\n", info->device_name, status)); | 2277 | DBGISR(("%s txeom status=%04x\n", info->device_name, status)); |
2282 | 2278 | ||
2283 | slgt_irq_off(info, IRQ_TXDATA + IRQ_TXIDLE + IRQ_TXUNDER); | 2279 | slgt_irq_off(info, IRQ_TXDATA + IRQ_TXIDLE + IRQ_TXUNDER); |
2284 | tdma_reset(info); | 2280 | tdma_reset(info); |
2285 | reset_tbufs(info); | ||
2286 | if (status & IRQ_TXUNDER) { | 2281 | if (status & IRQ_TXUNDER) { |
2287 | unsigned short val = rd_reg16(info, TCR); | 2282 | unsigned short val = rd_reg16(info, TCR); |
2288 | wr_reg16(info, TCR, (unsigned short)(val | BIT2)); /* set reset bit */ | 2283 | wr_reg16(info, TCR, (unsigned short)(val | BIT2)); /* set reset bit */ |
@@ -2297,8 +2292,12 @@ static void isr_txeom(struct slgt_info *info, unsigned short status) | |||
2297 | info->icount.txok++; | 2292 | info->icount.txok++; |
2298 | } | 2293 | } |
2299 | 2294 | ||
2295 | if (unsent_tbufs(info)) { | ||
2296 | tx_start(info); | ||
2297 | update_tx_timer(info); | ||
2298 | return; | ||
2299 | } | ||
2300 | info->tx_active = false; | 2300 | info->tx_active = false; |
2301 | info->tx_count = 0; | ||
2302 | 2301 | ||
2303 | del_timer(&info->tx_timer); | 2302 | del_timer(&info->tx_timer); |
2304 | 2303 | ||
@@ -3949,7 +3948,7 @@ static void tx_start(struct slgt_info *info) | |||
3949 | info->tx_enabled = true; | 3948 | info->tx_enabled = true; |
3950 | } | 3949 | } |
3951 | 3950 | ||
3952 | if (info->tx_count) { | 3951 | if (desc_count(info->tbufs[info->tbuf_start])) { |
3953 | info->drop_rts_on_tx_done = false; | 3952 | info->drop_rts_on_tx_done = false; |
3954 | 3953 | ||
3955 | if (info->params.mode != MGSL_MODE_ASYNC) { | 3954 | if (info->params.mode != MGSL_MODE_ASYNC) { |
@@ -4772,25 +4771,36 @@ static unsigned int tbuf_bytes(struct slgt_info *info) | |||
4772 | } | 4771 | } |
4773 | 4772 | ||
4774 | /* | 4773 | /* |
4775 | * load transmit DMA buffer(s) with data | 4774 | * load data into transmit DMA buffer ring and start transmitter if needed |
4775 | * return true if data accepted, otherwise false (buffers full) | ||
4776 | */ | 4776 | */ |
4777 | static void tx_load(struct slgt_info *info, const char *buf, unsigned int size) | 4777 | static bool tx_load(struct slgt_info *info, const char *buf, unsigned int size) |
4778 | { | 4778 | { |
4779 | unsigned short count; | 4779 | unsigned short count; |
4780 | unsigned int i; | 4780 | unsigned int i; |
4781 | struct slgt_desc *d; | 4781 | struct slgt_desc *d; |
4782 | 4782 | ||
4783 | if (size == 0) | 4783 | /* check required buffer space */ |
4784 | return; | 4784 | if (DIV_ROUND_UP(size, DMABUFSIZE) > free_tbuf_count(info)) |
4785 | return false; | ||
4785 | 4786 | ||
4786 | DBGDATA(info, buf, size, "tx"); | 4787 | DBGDATA(info, buf, size, "tx"); |
4787 | 4788 | ||
4789 | /* | ||
4790 | * copy data to one or more DMA buffers in circular ring | ||
4791 | * tbuf_start = first buffer for this data | ||
4792 | * tbuf_current = next free buffer | ||
4793 | * | ||
4794 | * Copy all data before making data visible to DMA controller by | ||
4795 | * setting descriptor count of the first buffer. | ||
4796 | * This prevents an active DMA controller from reading the first DMA | ||
4797 | * buffers of a frame and stopping before the final buffers are filled. | ||
4798 | */ | ||
4799 | |||
4788 | info->tbuf_start = i = info->tbuf_current; | 4800 | info->tbuf_start = i = info->tbuf_current; |
4789 | 4801 | ||
4790 | while (size) { | 4802 | while (size) { |
4791 | d = &info->tbufs[i]; | 4803 | d = &info->tbufs[i]; |
4792 | if (++i == info->tbuf_count) | ||
4793 | i = 0; | ||
4794 | 4804 | ||
4795 | count = (unsigned short)((size > DMABUFSIZE) ? DMABUFSIZE : size); | 4805 | count = (unsigned short)((size > DMABUFSIZE) ? DMABUFSIZE : size); |
4796 | memcpy(d->buf, buf, count); | 4806 | memcpy(d->buf, buf, count); |
@@ -4808,11 +4818,27 @@ static void tx_load(struct slgt_info *info, const char *buf, unsigned int size) | |||
4808 | else | 4818 | else |
4809 | set_desc_eof(*d, 0); | 4819 | set_desc_eof(*d, 0); |
4810 | 4820 | ||
4811 | set_desc_count(*d, count); | 4821 | /* set descriptor count for all but first buffer */ |
4822 | if (i != info->tbuf_start) | ||
4823 | set_desc_count(*d, count); | ||
4812 | d->buf_count = count; | 4824 | d->buf_count = count; |
4825 | |||
4826 | if (++i == info->tbuf_count) | ||
4827 | i = 0; | ||
4813 | } | 4828 | } |
4814 | 4829 | ||
4815 | info->tbuf_current = i; | 4830 | info->tbuf_current = i; |
4831 | |||
4832 | /* set first buffer count to make new data visible to DMA controller */ | ||
4833 | d = &info->tbufs[info->tbuf_start]; | ||
4834 | set_desc_count(*d, d->buf_count); | ||
4835 | |||
4836 | /* start transmitter if needed and update transmit timeout */ | ||
4837 | if (!info->tx_active) | ||
4838 | tx_start(info); | ||
4839 | update_tx_timer(info); | ||
4840 | |||
4841 | return true; | ||
4816 | } | 4842 | } |
4817 | 4843 | ||
4818 | static int register_test(struct slgt_info *info) | 4844 | static int register_test(struct slgt_info *info) |
@@ -4934,9 +4960,7 @@ static int loopback_test(struct slgt_info *info) | |||
4934 | spin_lock_irqsave(&info->lock,flags); | 4960 | spin_lock_irqsave(&info->lock,flags); |
4935 | async_mode(info); | 4961 | async_mode(info); |
4936 | rx_start(info); | 4962 | rx_start(info); |
4937 | info->tx_count = count; | ||
4938 | tx_load(info, buf, count); | 4963 | tx_load(info, buf, count); |
4939 | tx_start(info); | ||
4940 | spin_unlock_irqrestore(&info->lock, flags); | 4964 | spin_unlock_irqrestore(&info->lock, flags); |
4941 | 4965 | ||
4942 | /* wait for receive complete */ | 4966 | /* wait for receive complete */ |
diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c index 66fa4e10d76b..f27c4d6d956e 100644 --- a/drivers/char/tty_buffer.c +++ b/drivers/char/tty_buffer.c | |||
@@ -247,7 +247,8 @@ int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, | |||
247 | { | 247 | { |
248 | int copied = 0; | 248 | int copied = 0; |
249 | do { | 249 | do { |
250 | int space = tty_buffer_request_room(tty, size - copied); | 250 | int goal = min(size - copied, TTY_BUFFER_PAGE); |
251 | int space = tty_buffer_request_room(tty, goal); | ||
251 | struct tty_buffer *tb = tty->buf.tail; | 252 | struct tty_buffer *tb = tty->buf.tail; |
252 | /* If there is no space then tb may be NULL */ | 253 | /* If there is no space then tb may be NULL */ |
253 | if (unlikely(space == 0)) | 254 | if (unlikely(space == 0)) |
@@ -283,7 +284,8 @@ int tty_insert_flip_string_flags(struct tty_struct *tty, | |||
283 | { | 284 | { |
284 | int copied = 0; | 285 | int copied = 0; |
285 | do { | 286 | do { |
286 | int space = tty_buffer_request_room(tty, size - copied); | 287 | int goal = min(size - copied, TTY_BUFFER_PAGE); |
288 | int space = tty_buffer_request_room(tty, goal); | ||
287 | struct tty_buffer *tb = tty->buf.tail; | 289 | struct tty_buffer *tb = tty->buf.tail; |
288 | /* If there is no space then tb may be NULL */ | 290 | /* If there is no space then tb may be NULL */ |
289 | if (unlikely(space == 0)) | 291 | if (unlikely(space == 0)) |
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c index 3f653f7d849f..500e740ec5e4 100644 --- a/drivers/char/tty_ldisc.c +++ b/drivers/char/tty_ldisc.c | |||
@@ -706,12 +706,13 @@ static void tty_reset_termios(struct tty_struct *tty) | |||
706 | /** | 706 | /** |
707 | * tty_ldisc_reinit - reinitialise the tty ldisc | 707 | * tty_ldisc_reinit - reinitialise the tty ldisc |
708 | * @tty: tty to reinit | 708 | * @tty: tty to reinit |
709 | * @ldisc: line discipline to reinitialize | ||
709 | * | 710 | * |
710 | * Switch the tty back to N_TTY line discipline and leave the | 711 | * Switch the tty to a line discipline and leave the ldisc |
711 | * ldisc state closed | 712 | * state closed |
712 | */ | 713 | */ |
713 | 714 | ||
714 | static void tty_ldisc_reinit(struct tty_struct *tty) | 715 | static void tty_ldisc_reinit(struct tty_struct *tty, int ldisc) |
715 | { | 716 | { |
716 | struct tty_ldisc *ld; | 717 | struct tty_ldisc *ld; |
717 | 718 | ||
@@ -721,10 +722,10 @@ static void tty_ldisc_reinit(struct tty_struct *tty) | |||
721 | /* | 722 | /* |
722 | * Switch the line discipline back | 723 | * Switch the line discipline back |
723 | */ | 724 | */ |
724 | ld = tty_ldisc_get(N_TTY); | 725 | ld = tty_ldisc_get(ldisc); |
725 | BUG_ON(IS_ERR(ld)); | 726 | BUG_ON(IS_ERR(ld)); |
726 | tty_ldisc_assign(tty, ld); | 727 | tty_ldisc_assign(tty, ld); |
727 | tty_set_termios_ldisc(tty, N_TTY); | 728 | tty_set_termios_ldisc(tty, ldisc); |
728 | } | 729 | } |
729 | 730 | ||
730 | /** | 731 | /** |
@@ -745,6 +746,8 @@ static void tty_ldisc_reinit(struct tty_struct *tty) | |||
745 | void tty_ldisc_hangup(struct tty_struct *tty) | 746 | void tty_ldisc_hangup(struct tty_struct *tty) |
746 | { | 747 | { |
747 | struct tty_ldisc *ld; | 748 | struct tty_ldisc *ld; |
749 | int reset = tty->driver->flags & TTY_DRIVER_RESET_TERMIOS; | ||
750 | int err = 0; | ||
748 | 751 | ||
749 | /* | 752 | /* |
750 | * FIXME! What are the locking issues here? This may me overdoing | 753 | * FIXME! What are the locking issues here? This may me overdoing |
@@ -772,25 +775,32 @@ void tty_ldisc_hangup(struct tty_struct *tty) | |||
772 | wake_up_interruptible_poll(&tty->read_wait, POLLIN); | 775 | wake_up_interruptible_poll(&tty->read_wait, POLLIN); |
773 | /* | 776 | /* |
774 | * Shutdown the current line discipline, and reset it to | 777 | * Shutdown the current line discipline, and reset it to |
775 | * N_TTY. | 778 | * N_TTY if need be. |
779 | * | ||
780 | * Avoid racing set_ldisc or tty_ldisc_release | ||
776 | */ | 781 | */ |
777 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { | 782 | mutex_lock(&tty->ldisc_mutex); |
778 | /* Avoid racing set_ldisc or tty_ldisc_release */ | 783 | tty_ldisc_halt(tty); |
779 | mutex_lock(&tty->ldisc_mutex); | 784 | /* At this point we have a closed ldisc and we want to |
780 | tty_ldisc_halt(tty); | 785 | reopen it. We could defer this to the next open but |
781 | if (tty->ldisc) { /* Not yet closed */ | 786 | it means auditing a lot of other paths so this is |
782 | /* Switch back to N_TTY */ | 787 | a FIXME */ |
783 | tty_ldisc_reinit(tty); | 788 | if (tty->ldisc) { /* Not yet closed */ |
784 | /* At this point we have a closed ldisc and we want to | 789 | if (reset == 0) { |
785 | reopen it. We could defer this to the next open but | 790 | tty_ldisc_reinit(tty, tty->termios->c_line); |
786 | it means auditing a lot of other paths so this is | 791 | err = tty_ldisc_open(tty, tty->ldisc); |
787 | a FIXME */ | 792 | } |
793 | /* If the re-open fails or we reset then go to N_TTY. The | ||
794 | N_TTY open cannot fail */ | ||
795 | if (reset || err) { | ||
796 | tty_ldisc_reinit(tty, N_TTY); | ||
788 | WARN_ON(tty_ldisc_open(tty, tty->ldisc)); | 797 | WARN_ON(tty_ldisc_open(tty, tty->ldisc)); |
789 | tty_ldisc_enable(tty); | ||
790 | } | 798 | } |
791 | mutex_unlock(&tty->ldisc_mutex); | 799 | tty_ldisc_enable(tty); |
792 | tty_reset_termios(tty); | ||
793 | } | 800 | } |
801 | mutex_unlock(&tty->ldisc_mutex); | ||
802 | if (reset) | ||
803 | tty_reset_termios(tty); | ||
794 | } | 804 | } |
795 | 805 | ||
796 | /** | 806 | /** |
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 6aa10284104a..87778dcf8727 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -888,7 +888,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
888 | ret = -EFAULT; | 888 | ret = -EFAULT; |
889 | goto out; | 889 | goto out; |
890 | } | 890 | } |
891 | if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS) { | 891 | if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS && tmp.mode != VT_PROCESS_AUTO) { |
892 | ret = -EINVAL; | 892 | ret = -EINVAL; |
893 | goto out; | 893 | goto out; |
894 | } | 894 | } |
@@ -1622,7 +1622,7 @@ static void complete_change_console(struct vc_data *vc) | |||
1622 | * telling it that it has acquired. Also check if it has died and | 1622 | * telling it that it has acquired. Also check if it has died and |
1623 | * clean up (similar to logic employed in change_console()) | 1623 | * clean up (similar to logic employed in change_console()) |
1624 | */ | 1624 | */ |
1625 | if (vc->vt_mode.mode == VT_PROCESS) { | 1625 | if (vc->vt_mode.mode == VT_PROCESS || vc->vt_mode.mode == VT_PROCESS_AUTO) { |
1626 | /* | 1626 | /* |
1627 | * Send the signal as privileged - kill_pid() will | 1627 | * Send the signal as privileged - kill_pid() will |
1628 | * tell us if the process has gone or something else | 1628 | * tell us if the process has gone or something else |
@@ -1682,7 +1682,7 @@ void change_console(struct vc_data *new_vc) | |||
1682 | * vt to auto control. | 1682 | * vt to auto control. |
1683 | */ | 1683 | */ |
1684 | vc = vc_cons[fg_console].d; | 1684 | vc = vc_cons[fg_console].d; |
1685 | if (vc->vt_mode.mode == VT_PROCESS) { | 1685 | if (vc->vt_mode.mode == VT_PROCESS || vc->vt_mode.mode == VT_PROCESS_AUTO) { |
1686 | /* | 1686 | /* |
1687 | * Send the signal as privileged - kill_pid() will | 1687 | * Send the signal as privileged - kill_pid() will |
1688 | * tell us if the process has gone or something else | 1688 | * tell us if the process has gone or something else |
@@ -1693,27 +1693,28 @@ void change_console(struct vc_data *new_vc) | |||
1693 | */ | 1693 | */ |
1694 | vc->vt_newvt = new_vc->vc_num; | 1694 | vc->vt_newvt = new_vc->vc_num; |
1695 | if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) { | 1695 | if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) { |
1696 | if(vc->vt_mode.mode == VT_PROCESS) | ||
1697 | /* | ||
1698 | * It worked. Mark the vt to switch to and | ||
1699 | * return. The process needs to send us a | ||
1700 | * VT_RELDISP ioctl to complete the switch. | ||
1701 | */ | ||
1702 | return; | ||
1703 | } else { | ||
1696 | /* | 1704 | /* |
1697 | * It worked. Mark the vt to switch to and | 1705 | * The controlling process has died, so we revert back to |
1698 | * return. The process needs to send us a | 1706 | * normal operation. In this case, we'll also change back |
1699 | * VT_RELDISP ioctl to complete the switch. | 1707 | * to KD_TEXT mode. I'm not sure if this is strictly correct |
1708 | * but it saves the agony when the X server dies and the screen | ||
1709 | * remains blanked due to KD_GRAPHICS! It would be nice to do | ||
1710 | * this outside of VT_PROCESS but there is no single process | ||
1711 | * to account for and tracking tty count may be undesirable. | ||
1700 | */ | 1712 | */ |
1701 | return; | 1713 | reset_vc(vc); |
1702 | } | 1714 | } |
1703 | 1715 | ||
1704 | /* | 1716 | /* |
1705 | * The controlling process has died, so we revert back to | 1717 | * Fall through to normal (VT_AUTO and VT_PROCESS_AUTO) handling of the switch... |
1706 | * normal operation. In this case, we'll also change back | ||
1707 | * to KD_TEXT mode. I'm not sure if this is strictly correct | ||
1708 | * but it saves the agony when the X server dies and the screen | ||
1709 | * remains blanked due to KD_GRAPHICS! It would be nice to do | ||
1710 | * this outside of VT_PROCESS but there is no single process | ||
1711 | * to account for and tracking tty count may be undesirable. | ||
1712 | */ | ||
1713 | reset_vc(vc); | ||
1714 | |||
1715 | /* | ||
1716 | * Fall through to normal (VT_AUTO) handling of the switch... | ||
1717 | */ | 1718 | */ |
1718 | } | 1719 | } |
1719 | 1720 | ||
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index f53755533e7e..3fab78ba8952 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/gfp.h> | 37 | #include <linux/gfp.h> |
38 | #include <linux/tty.h> | 38 | #include <linux/tty.h> |
39 | #include <linux/tty_flip.h> | 39 | #include <linux/tty_flip.h> |
40 | #include <linux/kfifo.h> | ||
40 | 41 | ||
41 | #include <linux/mmc/core.h> | 42 | #include <linux/mmc/core.h> |
42 | #include <linux/mmc/card.h> | 43 | #include <linux/mmc/card.h> |
@@ -47,19 +48,9 @@ | |||
47 | #define UART_NR 8 /* Number of UARTs this driver can handle */ | 48 | #define UART_NR 8 /* Number of UARTs this driver can handle */ |
48 | 49 | ||
49 | 50 | ||
50 | #define UART_XMIT_SIZE PAGE_SIZE | 51 | #define FIFO_SIZE PAGE_SIZE |
51 | #define WAKEUP_CHARS 256 | 52 | #define WAKEUP_CHARS 256 |
52 | 53 | ||
53 | #define circ_empty(circ) ((circ)->head == (circ)->tail) | ||
54 | #define circ_clear(circ) ((circ)->head = (circ)->tail = 0) | ||
55 | |||
56 | #define circ_chars_pending(circ) \ | ||
57 | (CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE)) | ||
58 | |||
59 | #define circ_chars_free(circ) \ | ||
60 | (CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE)) | ||
61 | |||
62 | |||
63 | struct uart_icount { | 54 | struct uart_icount { |
64 | __u32 cts; | 55 | __u32 cts; |
65 | __u32 dsr; | 56 | __u32 dsr; |
@@ -82,7 +73,7 @@ struct sdio_uart_port { | |||
82 | struct mutex func_lock; | 73 | struct mutex func_lock; |
83 | struct task_struct *in_sdio_uart_irq; | 74 | struct task_struct *in_sdio_uart_irq; |
84 | unsigned int regs_offset; | 75 | unsigned int regs_offset; |
85 | struct circ_buf xmit; | 76 | struct kfifo xmit_fifo; |
86 | spinlock_t write_lock; | 77 | spinlock_t write_lock; |
87 | struct uart_icount icount; | 78 | struct uart_icount icount; |
88 | unsigned int uartclk; | 79 | unsigned int uartclk; |
@@ -105,6 +96,8 @@ static int sdio_uart_add_port(struct sdio_uart_port *port) | |||
105 | kref_init(&port->kref); | 96 | kref_init(&port->kref); |
106 | mutex_init(&port->func_lock); | 97 | mutex_init(&port->func_lock); |
107 | spin_lock_init(&port->write_lock); | 98 | spin_lock_init(&port->write_lock); |
99 | if (kfifo_alloc(&port->xmit_fifo, FIFO_SIZE, GFP_KERNEL)) | ||
100 | return -ENOMEM; | ||
108 | 101 | ||
109 | spin_lock(&sdio_uart_table_lock); | 102 | spin_lock(&sdio_uart_table_lock); |
110 | for (index = 0; index < UART_NR; index++) { | 103 | for (index = 0; index < UART_NR; index++) { |
@@ -140,6 +133,7 @@ static void sdio_uart_port_destroy(struct kref *kref) | |||
140 | { | 133 | { |
141 | struct sdio_uart_port *port = | 134 | struct sdio_uart_port *port = |
142 | container_of(kref, struct sdio_uart_port, kref); | 135 | container_of(kref, struct sdio_uart_port, kref); |
136 | kfifo_free(&port->xmit_fifo); | ||
143 | kfree(port); | 137 | kfree(port); |
144 | } | 138 | } |
145 | 139 | ||
@@ -456,9 +450,11 @@ static void sdio_uart_receive_chars(struct sdio_uart_port *port, | |||
456 | 450 | ||
457 | static void sdio_uart_transmit_chars(struct sdio_uart_port *port) | 451 | static void sdio_uart_transmit_chars(struct sdio_uart_port *port) |
458 | { | 452 | { |
459 | struct circ_buf *xmit = &port->xmit; | 453 | struct kfifo *xmit = &port->xmit_fifo; |
460 | int count; | 454 | int count; |
461 | struct tty_struct *tty; | 455 | struct tty_struct *tty; |
456 | u8 iobuf[16]; | ||
457 | int len; | ||
462 | 458 | ||
463 | if (port->x_char) { | 459 | if (port->x_char) { |
464 | sdio_out(port, UART_TX, port->x_char); | 460 | sdio_out(port, UART_TX, port->x_char); |
@@ -469,27 +465,25 @@ static void sdio_uart_transmit_chars(struct sdio_uart_port *port) | |||
469 | 465 | ||
470 | tty = tty_port_tty_get(&port->port); | 466 | tty = tty_port_tty_get(&port->port); |
471 | 467 | ||
472 | if (tty == NULL || circ_empty(xmit) || | 468 | if (tty == NULL || !kfifo_len(xmit) || |
473 | tty->stopped || tty->hw_stopped) { | 469 | tty->stopped || tty->hw_stopped) { |
474 | sdio_uart_stop_tx(port); | 470 | sdio_uart_stop_tx(port); |
475 | tty_kref_put(tty); | 471 | tty_kref_put(tty); |
476 | return; | 472 | return; |
477 | } | 473 | } |
478 | 474 | ||
479 | count = 16; | 475 | len = kfifo_out_locked(xmit, iobuf, 16, &port->write_lock); |
480 | do { | 476 | for (count = 0; count < len; count++) { |
481 | sdio_out(port, UART_TX, xmit->buf[xmit->tail]); | 477 | sdio_out(port, UART_TX, iobuf[count]); |
482 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
483 | port->icount.tx++; | 478 | port->icount.tx++; |
484 | if (circ_empty(xmit)) | 479 | } |
485 | break; | ||
486 | } while (--count > 0); | ||
487 | 480 | ||
488 | if (circ_chars_pending(xmit) < WAKEUP_CHARS) | 481 | len = kfifo_len(xmit); |
482 | if (len < WAKEUP_CHARS) { | ||
489 | tty_wakeup(tty); | 483 | tty_wakeup(tty); |
490 | 484 | if (len == 0) | |
491 | if (circ_empty(xmit)) | 485 | sdio_uart_stop_tx(port); |
492 | sdio_uart_stop_tx(port); | 486 | } |
493 | tty_kref_put(tty); | 487 | tty_kref_put(tty); |
494 | } | 488 | } |
495 | 489 | ||
@@ -632,7 +626,6 @@ static int sdio_uart_activate(struct tty_port *tport, struct tty_struct *tty) | |||
632 | { | 626 | { |
633 | struct sdio_uart_port *port = | 627 | struct sdio_uart_port *port = |
634 | container_of(tport, struct sdio_uart_port, port); | 628 | container_of(tport, struct sdio_uart_port, port); |
635 | unsigned long page; | ||
636 | int ret; | 629 | int ret; |
637 | 630 | ||
638 | /* | 631 | /* |
@@ -641,22 +634,17 @@ static int sdio_uart_activate(struct tty_port *tport, struct tty_struct *tty) | |||
641 | */ | 634 | */ |
642 | set_bit(TTY_IO_ERROR, &tty->flags); | 635 | set_bit(TTY_IO_ERROR, &tty->flags); |
643 | 636 | ||
644 | /* Initialise and allocate the transmit buffer. */ | 637 | kfifo_reset(&port->xmit_fifo); |
645 | page = __get_free_page(GFP_KERNEL); | ||
646 | if (!page) | ||
647 | return -ENOMEM; | ||
648 | port->xmit.buf = (unsigned char *)page; | ||
649 | circ_clear(&port->xmit); | ||
650 | 638 | ||
651 | ret = sdio_uart_claim_func(port); | 639 | ret = sdio_uart_claim_func(port); |
652 | if (ret) | 640 | if (ret) |
653 | goto err1; | 641 | return ret; |
654 | ret = sdio_enable_func(port->func); | 642 | ret = sdio_enable_func(port->func); |
655 | if (ret) | 643 | if (ret) |
656 | goto err2; | 644 | goto err1; |
657 | ret = sdio_claim_irq(port->func, sdio_uart_irq); | 645 | ret = sdio_claim_irq(port->func, sdio_uart_irq); |
658 | if (ret) | 646 | if (ret) |
659 | goto err3; | 647 | goto err2; |
660 | 648 | ||
661 | /* | 649 | /* |
662 | * Clear the FIFO buffers and disable them. | 650 | * Clear the FIFO buffers and disable them. |
@@ -700,12 +688,10 @@ static int sdio_uart_activate(struct tty_port *tport, struct tty_struct *tty) | |||
700 | sdio_uart_release_func(port); | 688 | sdio_uart_release_func(port); |
701 | return 0; | 689 | return 0; |
702 | 690 | ||
703 | err3: | ||
704 | sdio_disable_func(port->func); | ||
705 | err2: | 691 | err2: |
706 | sdio_uart_release_func(port); | 692 | sdio_disable_func(port->func); |
707 | err1: | 693 | err1: |
708 | free_page((unsigned long)port->xmit.buf); | 694 | sdio_uart_release_func(port); |
709 | return ret; | 695 | return ret; |
710 | } | 696 | } |
711 | 697 | ||
@@ -727,7 +713,7 @@ static void sdio_uart_shutdown(struct tty_port *tport) | |||
727 | 713 | ||
728 | ret = sdio_uart_claim_func(port); | 714 | ret = sdio_uart_claim_func(port); |
729 | if (ret) | 715 | if (ret) |
730 | goto skip; | 716 | return; |
731 | 717 | ||
732 | sdio_uart_stop_rx(port); | 718 | sdio_uart_stop_rx(port); |
733 | 719 | ||
@@ -749,10 +735,6 @@ static void sdio_uart_shutdown(struct tty_port *tport) | |||
749 | sdio_disable_func(port->func); | 735 | sdio_disable_func(port->func); |
750 | 736 | ||
751 | sdio_uart_release_func(port); | 737 | sdio_uart_release_func(port); |
752 | |||
753 | skip: | ||
754 | /* Free the transmit buffer page. */ | ||
755 | free_page((unsigned long)port->xmit.buf); | ||
756 | } | 738 | } |
757 | 739 | ||
758 | /** | 740 | /** |
@@ -822,27 +804,12 @@ static int sdio_uart_write(struct tty_struct *tty, const unsigned char *buf, | |||
822 | int count) | 804 | int count) |
823 | { | 805 | { |
824 | struct sdio_uart_port *port = tty->driver_data; | 806 | struct sdio_uart_port *port = tty->driver_data; |
825 | struct circ_buf *circ = &port->xmit; | 807 | int ret; |
826 | int c, ret = 0; | ||
827 | 808 | ||
828 | if (!port->func) | 809 | if (!port->func) |
829 | return -ENODEV; | 810 | return -ENODEV; |
830 | 811 | ||
831 | spin_lock(&port->write_lock); | 812 | ret = kfifo_in_locked(&port->xmit_fifo, buf, count, &port->write_lock); |
832 | while (1) { | ||
833 | c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE); | ||
834 | if (count < c) | ||
835 | c = count; | ||
836 | if (c <= 0) | ||
837 | break; | ||
838 | memcpy(circ->buf + circ->head, buf, c); | ||
839 | circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1); | ||
840 | buf += c; | ||
841 | count -= c; | ||
842 | ret += c; | ||
843 | } | ||
844 | spin_unlock(&port->write_lock); | ||
845 | |||
846 | if (!(port->ier & UART_IER_THRI)) { | 813 | if (!(port->ier & UART_IER_THRI)) { |
847 | int err = sdio_uart_claim_func(port); | 814 | int err = sdio_uart_claim_func(port); |
848 | if (!err) { | 815 | if (!err) { |
@@ -859,13 +826,13 @@ static int sdio_uart_write(struct tty_struct *tty, const unsigned char *buf, | |||
859 | static int sdio_uart_write_room(struct tty_struct *tty) | 826 | static int sdio_uart_write_room(struct tty_struct *tty) |
860 | { | 827 | { |
861 | struct sdio_uart_port *port = tty->driver_data; | 828 | struct sdio_uart_port *port = tty->driver_data; |
862 | return port ? circ_chars_free(&port->xmit) : 0; | 829 | return FIFO_SIZE - kfifo_len(&port->xmit_fifo); |
863 | } | 830 | } |
864 | 831 | ||
865 | static int sdio_uart_chars_in_buffer(struct tty_struct *tty) | 832 | static int sdio_uart_chars_in_buffer(struct tty_struct *tty) |
866 | { | 833 | { |
867 | struct sdio_uart_port *port = tty->driver_data; | 834 | struct sdio_uart_port *port = tty->driver_data; |
868 | return port ? circ_chars_pending(&port->xmit) : 0; | 835 | return kfifo_len(&port->xmit_fifo); |
869 | } | 836 | } |
870 | 837 | ||
871 | static void sdio_uart_send_xchar(struct tty_struct *tty, char ch) | 838 | static void sdio_uart_send_xchar(struct tty_struct *tty, char ch) |
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index ad113b0f62db..0950fa40684f 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c | |||
@@ -2908,6 +2908,7 @@ enum parport_pc_pci_cards { | |||
2908 | netmos_9805, | 2908 | netmos_9805, |
2909 | netmos_9815, | 2909 | netmos_9815, |
2910 | netmos_9901, | 2910 | netmos_9901, |
2911 | netmos_9865, | ||
2911 | quatech_sppxp100, | 2912 | quatech_sppxp100, |
2912 | }; | 2913 | }; |
2913 | 2914 | ||
@@ -2989,6 +2990,7 @@ static struct parport_pc_pci { | |||
2989 | /* netmos_9805 */ { 1, { { 0, -1 }, } }, | 2990 | /* netmos_9805 */ { 1, { { 0, -1 }, } }, |
2990 | /* netmos_9815 */ { 2, { { 0, -1 }, { 2, -1 }, } }, | 2991 | /* netmos_9815 */ { 2, { { 0, -1 }, { 2, -1 }, } }, |
2991 | /* netmos_9901 */ { 1, { { 0, -1 }, } }, | 2992 | /* netmos_9901 */ { 1, { { 0, -1 }, } }, |
2993 | /* netmos_9865 */ { 1, { { 0, -1 }, } }, | ||
2992 | /* quatech_sppxp100 */ { 1, { { 0, 1 }, } }, | 2994 | /* quatech_sppxp100 */ { 1, { { 0, 1 }, } }, |
2993 | }; | 2995 | }; |
2994 | 2996 | ||
@@ -3092,6 +3094,10 @@ static const struct pci_device_id parport_pc_pci_tbl[] = { | |||
3092 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9815 }, | 3094 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9815 }, |
3093 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901, | 3095 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901, |
3094 | 0xA000, 0x2000, 0, 0, netmos_9901 }, | 3096 | 0xA000, 0x2000, 0, 0, netmos_9901 }, |
3097 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, | ||
3098 | 0xA000, 0x1000, 0, 0, netmos_9865 }, | ||
3099 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, | ||
3100 | 0xA000, 0x2000, 0, 0, netmos_9865 }, | ||
3095 | /* Quatech SPPXP-100 Parallel port PCI ExpressCard */ | 3101 | /* Quatech SPPXP-100 Parallel port PCI ExpressCard */ |
3096 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SPPXP_100, | 3102 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SPPXP_100, |
3097 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, quatech_sppxp100 }, | 3103 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, quatech_sppxp100 }, |
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index d935b2d04f93..ae0251ef6f4e 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c | |||
@@ -153,8 +153,6 @@ static int baud_table[] = { | |||
153 | 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, | 153 | 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, |
154 | 9600, 19200, 38400, 57600, 115200, 0 }; | 154 | 9600, 19200, 38400, 57600, 115200, 0 }; |
155 | 155 | ||
156 | #define BAUD_TABLE_SIZE (sizeof(baud_table)/sizeof(baud_table[0])) | ||
157 | |||
158 | /* Sets or clears DTR/RTS on the requested line */ | 156 | /* Sets or clears DTR/RTS on the requested line */ |
159 | static inline void m68k_rtsdtr(struct m68k_serial *ss, int set) | 157 | static inline void m68k_rtsdtr(struct m68k_serial *ss, int set) |
160 | { | 158 | { |
@@ -1406,10 +1404,10 @@ static void m68328_set_baud(void) | |||
1406 | USTCNT = ustcnt & ~USTCNT_TXEN; | 1404 | USTCNT = ustcnt & ~USTCNT_TXEN; |
1407 | 1405 | ||
1408 | again: | 1406 | again: |
1409 | for (i = 0; i < sizeof(baud_table) / sizeof(baud_table[0]); i++) | 1407 | for (i = 0; i < ARRAY_SIZE(baud_table); i++) |
1410 | if (baud_table[i] == m68328_console_baud) | 1408 | if (baud_table[i] == m68328_console_baud) |
1411 | break; | 1409 | break; |
1412 | if (i >= sizeof(baud_table) / sizeof(baud_table[0])) { | 1410 | if (i >= ARRAY_SIZE(baud_table)) { |
1413 | m68328_console_baud = 9600; | 1411 | m68328_console_baud = 9600; |
1414 | goto again; | 1412 | goto again; |
1415 | } | 1413 | } |
@@ -1435,7 +1433,7 @@ int m68328_console_setup(struct console *cp, char *arg) | |||
1435 | if (arg) | 1433 | if (arg) |
1436 | n = simple_strtoul(arg,NULL,0); | 1434 | n = simple_strtoul(arg,NULL,0); |
1437 | 1435 | ||
1438 | for (i = 0; i < BAUD_TABLE_SIZE; i++) | 1436 | for (i = 0; i < ARRAY_SIZE(baud_table); i++) |
1439 | if (baud_table[i] == n) | 1437 | if (baud_table[i] == n) |
1440 | break; | 1438 | break; |
1441 | if (i < BAUD_TABLE_SIZE) { | 1439 | if (i < BAUD_TABLE_SIZE) { |
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index a81ff7bc5fa1..7c4ebe6ee18b 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -2690,6 +2690,15 @@ static void __init serial8250_isa_init_ports(void) | |||
2690 | } | 2690 | } |
2691 | } | 2691 | } |
2692 | 2692 | ||
2693 | static void | ||
2694 | serial8250_init_fixed_type_port(struct uart_8250_port *up, unsigned int type) | ||
2695 | { | ||
2696 | up->port.type = type; | ||
2697 | up->port.fifosize = uart_config[type].fifo_size; | ||
2698 | up->capabilities = uart_config[type].flags; | ||
2699 | up->tx_loadsz = uart_config[type].tx_loadsz; | ||
2700 | } | ||
2701 | |||
2693 | static void __init | 2702 | static void __init |
2694 | serial8250_register_ports(struct uart_driver *drv, struct device *dev) | 2703 | serial8250_register_ports(struct uart_driver *drv, struct device *dev) |
2695 | { | 2704 | { |
@@ -2706,6 +2715,10 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev) | |||
2706 | struct uart_8250_port *up = &serial8250_ports[i]; | 2715 | struct uart_8250_port *up = &serial8250_ports[i]; |
2707 | 2716 | ||
2708 | up->port.dev = dev; | 2717 | up->port.dev = dev; |
2718 | |||
2719 | if (up->port.flags & UPF_FIXED_TYPE) | ||
2720 | serial8250_init_fixed_type_port(up, up->port.type); | ||
2721 | |||
2709 | uart_add_one_port(drv, &up->port); | 2722 | uart_add_one_port(drv, &up->port); |
2710 | } | 2723 | } |
2711 | } | 2724 | } |
@@ -3118,12 +3131,8 @@ int serial8250_register_port(struct uart_port *port) | |||
3118 | if (port->dev) | 3131 | if (port->dev) |
3119 | uart->port.dev = port->dev; | 3132 | uart->port.dev = port->dev; |
3120 | 3133 | ||
3121 | if (port->flags & UPF_FIXED_TYPE) { | 3134 | if (port->flags & UPF_FIXED_TYPE) |
3122 | uart->port.type = port->type; | 3135 | serial8250_init_fixed_type_port(uart, port->type); |
3123 | uart->port.fifosize = uart_config[port->type].fifo_size; | ||
3124 | uart->capabilities = uart_config[port->type].flags; | ||
3125 | uart->tx_loadsz = uart_config[port->type].tx_loadsz; | ||
3126 | } | ||
3127 | 3136 | ||
3128 | set_io_from_upio(&uart->port); | 3137 | set_io_from_upio(&uart->port); |
3129 | /* Possibly override default I/O functions. */ | 3138 | /* Possibly override default I/O functions. */ |
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index b28af13c45a1..01c012da4e26 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c | |||
@@ -760,7 +760,8 @@ static int pci_netmos_init(struct pci_dev *dev) | |||
760 | /* subdevice 0x00PS means <P> parallel, <S> serial */ | 760 | /* subdevice 0x00PS means <P> parallel, <S> serial */ |
761 | unsigned int num_serial = dev->subsystem_device & 0xf; | 761 | unsigned int num_serial = dev->subsystem_device & 0xf; |
762 | 762 | ||
763 | if (dev->device == PCI_DEVICE_ID_NETMOS_9901) | 763 | if ((dev->device == PCI_DEVICE_ID_NETMOS_9901) || |
764 | (dev->device == PCI_DEVICE_ID_NETMOS_9865)) | ||
764 | return 0; | 765 | return 0; |
765 | if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM && | 766 | if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM && |
766 | dev->subsystem_device == 0x0299) | 767 | dev->subsystem_device == 0x0299) |
@@ -1479,6 +1480,7 @@ enum pci_board_num_t { | |||
1479 | 1480 | ||
1480 | pbn_b0_bt_1_115200, | 1481 | pbn_b0_bt_1_115200, |
1481 | pbn_b0_bt_2_115200, | 1482 | pbn_b0_bt_2_115200, |
1483 | pbn_b0_bt_4_115200, | ||
1482 | pbn_b0_bt_8_115200, | 1484 | pbn_b0_bt_8_115200, |
1483 | 1485 | ||
1484 | pbn_b0_bt_1_460800, | 1486 | pbn_b0_bt_1_460800, |
@@ -1703,6 +1705,12 @@ static struct pciserial_board pci_boards[] __devinitdata = { | |||
1703 | .base_baud = 115200, | 1705 | .base_baud = 115200, |
1704 | .uart_offset = 8, | 1706 | .uart_offset = 8, |
1705 | }, | 1707 | }, |
1708 | [pbn_b0_bt_4_115200] = { | ||
1709 | .flags = FL_BASE0|FL_BASE_BARS, | ||
1710 | .num_ports = 4, | ||
1711 | .base_baud = 115200, | ||
1712 | .uart_offset = 8, | ||
1713 | }, | ||
1706 | [pbn_b0_bt_8_115200] = { | 1714 | [pbn_b0_bt_8_115200] = { |
1707 | .flags = FL_BASE0|FL_BASE_BARS, | 1715 | .flags = FL_BASE0|FL_BASE_BARS, |
1708 | .num_ports = 8, | 1716 | .num_ports = 8, |
@@ -3191,6 +3199,15 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
3191 | 0x1208, 0x0004, 0, 0, | 3199 | 0x1208, 0x0004, 0, 0, |
3192 | pbn_b0_4_921600 }, | 3200 | pbn_b0_4_921600 }, |
3193 | 3201 | ||
3202 | { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF2, | ||
3203 | 0x1204, 0x0004, 0, 0, | ||
3204 | pbn_b0_4_921600 }, | ||
3205 | { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF2, | ||
3206 | 0x1208, 0x0004, 0, 0, | ||
3207 | pbn_b0_4_921600 }, | ||
3208 | { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF3, | ||
3209 | 0x1208, 0x0004, 0, 0, | ||
3210 | pbn_b0_4_921600 }, | ||
3194 | /* | 3211 | /* |
3195 | * Dell Remote Access Card 4 - Tim_T_Murphy@Dell.com | 3212 | * Dell Remote Access Card 4 - Tim_T_Murphy@Dell.com |
3196 | */ | 3213 | */ |
@@ -3649,6 +3666,18 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
3649 | 0, 0, pbn_b0_1_115200 }, | 3666 | 0, 0, pbn_b0_1_115200 }, |
3650 | 3667 | ||
3651 | /* | 3668 | /* |
3669 | * Best Connectivity PCI Multi I/O cards | ||
3670 | */ | ||
3671 | |||
3672 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, | ||
3673 | 0xA000, 0x1000, | ||
3674 | 0, 0, pbn_b0_1_115200 }, | ||
3675 | |||
3676 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, | ||
3677 | 0xA000, 0x3004, | ||
3678 | 0, 0, pbn_b0_bt_4_115200 }, | ||
3679 | |||
3680 | /* | ||
3652 | * These entries match devices with class COMMUNICATION_SERIAL, | 3681 | * These entries match devices with class COMMUNICATION_SERIAL, |
3653 | * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL | 3682 | * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL |
3654 | */ | 3683 | */ |
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 888a0ce91c4b..746e07033dce 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -1418,42 +1418,37 @@ config SERIAL_BFIN_SPORT | |||
1418 | To compile this driver as a module, choose M here: the | 1418 | To compile this driver as a module, choose M here: the |
1419 | module will be called bfin_sport_uart. | 1419 | module will be called bfin_sport_uart. |
1420 | 1420 | ||
1421 | choice | 1421 | config SERIAL_BFIN_SPORT_CONSOLE |
1422 | prompt "Baud rate for Blackfin SPORT UART" | 1422 | bool "Console on Blackfin sport emulated uart" |
1423 | depends on SERIAL_BFIN_SPORT | 1423 | depends on SERIAL_BFIN_SPORT=y |
1424 | default SERIAL_SPORT_BAUD_RATE_57600 | 1424 | select SERIAL_CORE_CONSOLE |
1425 | help | ||
1426 | Choose a baud rate for the SPORT UART, other uart settings are | ||
1427 | 8 bit, 1 stop bit, no parity, no flow control. | ||
1428 | |||
1429 | config SERIAL_SPORT_BAUD_RATE_115200 | ||
1430 | bool "115200" | ||
1431 | |||
1432 | config SERIAL_SPORT_BAUD_RATE_57600 | ||
1433 | bool "57600" | ||
1434 | 1425 | ||
1435 | config SERIAL_SPORT_BAUD_RATE_38400 | 1426 | config SERIAL_BFIN_SPORT0_UART |
1436 | bool "38400" | 1427 | bool "Enable UART over SPORT0" |
1428 | depends on SERIAL_BFIN_SPORT && !(BF542 || BF542M || BF544 || BF544M) | ||
1429 | help | ||
1430 | Enable UART over SPORT0 | ||
1437 | 1431 | ||
1438 | config SERIAL_SPORT_BAUD_RATE_19200 | 1432 | config SERIAL_BFIN_SPORT1_UART |
1439 | bool "19200" | 1433 | bool "Enable UART over SPORT1" |
1434 | depends on SERIAL_BFIN_SPORT | ||
1435 | help | ||
1436 | Enable UART over SPORT1 | ||
1440 | 1437 | ||
1441 | config SERIAL_SPORT_BAUD_RATE_9600 | 1438 | config SERIAL_BFIN_SPORT2_UART |
1442 | bool "9600" | 1439 | bool "Enable UART over SPORT2" |
1443 | endchoice | 1440 | depends on SERIAL_BFIN_SPORT && (BF54x || BF538 || BF539) |
1441 | help | ||
1442 | Enable UART over SPORT2 | ||
1444 | 1443 | ||
1445 | config SPORT_BAUD_RATE | 1444 | config SERIAL_BFIN_SPORT3_UART |
1446 | int | 1445 | bool "Enable UART over SPORT3" |
1447 | depends on SERIAL_BFIN_SPORT | 1446 | depends on SERIAL_BFIN_SPORT && (BF54x || BF538 || BF539) |
1448 | default 115200 if (SERIAL_SPORT_BAUD_RATE_115200) | 1447 | help |
1449 | default 57600 if (SERIAL_SPORT_BAUD_RATE_57600) | 1448 | Enable UART over SPORT3 |
1450 | default 38400 if (SERIAL_SPORT_BAUD_RATE_38400) | ||
1451 | default 19200 if (SERIAL_SPORT_BAUD_RATE_19200) | ||
1452 | default 9600 if (SERIAL_SPORT_BAUD_RATE_9600) | ||
1453 | 1449 | ||
1454 | config SERIAL_TIMBERDALE | 1450 | config SERIAL_TIMBERDALE |
1455 | tristate "Support for timberdale UART" | 1451 | tristate "Support for timberdale UART" |
1456 | depends on MFD_TIMBERDALE | ||
1457 | select SERIAL_CORE | 1452 | select SERIAL_CORE |
1458 | ---help--- | 1453 | ---help--- |
1459 | Add support for UART controller on timberdale. | 1454 | Add support for UART controller on timberdale. |
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c index 9d948bccafaf..2c9bf9b68327 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/serial/atmel_serial.c | |||
@@ -1213,6 +1213,24 @@ static int atmel_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
1213 | return ret; | 1213 | return ret; |
1214 | } | 1214 | } |
1215 | 1215 | ||
1216 | #ifdef CONFIG_CONSOLE_POLL | ||
1217 | static int atmel_poll_get_char(struct uart_port *port) | ||
1218 | { | ||
1219 | while (!(UART_GET_CSR(port) & ATMEL_US_RXRDY)) | ||
1220 | cpu_relax(); | ||
1221 | |||
1222 | return UART_GET_CHAR(port); | ||
1223 | } | ||
1224 | |||
1225 | static void atmel_poll_put_char(struct uart_port *port, unsigned char ch) | ||
1226 | { | ||
1227 | while (!(UART_GET_CSR(port) & ATMEL_US_TXRDY)) | ||
1228 | cpu_relax(); | ||
1229 | |||
1230 | UART_PUT_CHAR(port, ch); | ||
1231 | } | ||
1232 | #endif | ||
1233 | |||
1216 | static struct uart_ops atmel_pops = { | 1234 | static struct uart_ops atmel_pops = { |
1217 | .tx_empty = atmel_tx_empty, | 1235 | .tx_empty = atmel_tx_empty, |
1218 | .set_mctrl = atmel_set_mctrl, | 1236 | .set_mctrl = atmel_set_mctrl, |
@@ -1232,6 +1250,10 @@ static struct uart_ops atmel_pops = { | |||
1232 | .config_port = atmel_config_port, | 1250 | .config_port = atmel_config_port, |
1233 | .verify_port = atmel_verify_port, | 1251 | .verify_port = atmel_verify_port, |
1234 | .pm = atmel_serial_pm, | 1252 | .pm = atmel_serial_pm, |
1253 | #ifdef CONFIG_CONSOLE_POLL | ||
1254 | .poll_get_char = atmel_poll_get_char, | ||
1255 | .poll_put_char = atmel_poll_put_char, | ||
1256 | #endif | ||
1235 | }; | 1257 | }; |
1236 | 1258 | ||
1237 | /* | 1259 | /* |
diff --git a/drivers/serial/bcm63xx_uart.c b/drivers/serial/bcm63xx_uart.c index 37ad0c449937..a1a0e55d0807 100644 --- a/drivers/serial/bcm63xx_uart.c +++ b/drivers/serial/bcm63xx_uart.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <bcm63xx_regs.h> | 35 | #include <bcm63xx_regs.h> |
36 | #include <bcm63xx_io.h> | 36 | #include <bcm63xx_io.h> |
37 | 37 | ||
38 | #define BCM63XX_NR_UARTS 1 | 38 | #define BCM63XX_NR_UARTS 2 |
39 | 39 | ||
40 | static struct uart_port ports[BCM63XX_NR_UARTS]; | 40 | static struct uart_port ports[BCM63XX_NR_UARTS]; |
41 | 41 | ||
@@ -784,7 +784,7 @@ static struct uart_driver bcm_uart_driver = { | |||
784 | .dev_name = "ttyS", | 784 | .dev_name = "ttyS", |
785 | .major = TTY_MAJOR, | 785 | .major = TTY_MAJOR, |
786 | .minor = 64, | 786 | .minor = 64, |
787 | .nr = 1, | 787 | .nr = BCM63XX_NR_UARTS, |
788 | .cons = BCM63XX_CONSOLE, | 788 | .cons = BCM63XX_CONSOLE, |
789 | }; | 789 | }; |
790 | 790 | ||
@@ -826,11 +826,12 @@ static int __devinit bcm_uart_probe(struct platform_device *pdev) | |||
826 | port->dev = &pdev->dev; | 826 | port->dev = &pdev->dev; |
827 | port->fifosize = 16; | 827 | port->fifosize = 16; |
828 | port->uartclk = clk_get_rate(clk) / 2; | 828 | port->uartclk = clk_get_rate(clk) / 2; |
829 | port->line = pdev->id; | ||
829 | clk_put(clk); | 830 | clk_put(clk); |
830 | 831 | ||
831 | ret = uart_add_one_port(&bcm_uart_driver, port); | 832 | ret = uart_add_one_port(&bcm_uart_driver, port); |
832 | if (ret) { | 833 | if (ret) { |
833 | kfree(port); | 834 | ports[pdev->id].membase = 0; |
834 | return ret; | 835 | return ret; |
835 | } | 836 | } |
836 | platform_set_drvdata(pdev, port); | 837 | platform_set_drvdata(pdev, port); |
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index 50abb7e557f4..fcf273e3f48c 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c | |||
@@ -14,6 +14,7 @@ | |||
14 | 14 | ||
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/ioport.h> | 16 | #include <linux/ioport.h> |
17 | #include <linux/io.h> | ||
17 | #include <linux/init.h> | 18 | #include <linux/init.h> |
18 | #include <linux/console.h> | 19 | #include <linux/console.h> |
19 | #include <linux/sysrq.h> | 20 | #include <linux/sysrq.h> |
@@ -237,7 +238,8 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) | |||
237 | 238 | ||
238 | #if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ | 239 | #if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ |
239 | defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) | 240 | defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) |
240 | if (kgdb_connected && kgdboc_port_line == uart->port.line) | 241 | if (kgdb_connected && kgdboc_port_line == uart->port.line |
242 | && kgdboc_break_enabled) | ||
241 | if (ch == 0x3) {/* Ctrl + C */ | 243 | if (ch == 0x3) {/* Ctrl + C */ |
242 | kgdb_breakpoint(); | 244 | kgdb_breakpoint(); |
243 | return; | 245 | return; |
@@ -488,6 +490,7 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) | |||
488 | { | 490 | { |
489 | int x_pos, pos; | 491 | int x_pos, pos; |
490 | 492 | ||
493 | dma_disable_irq(uart->tx_dma_channel); | ||
491 | dma_disable_irq(uart->rx_dma_channel); | 494 | dma_disable_irq(uart->rx_dma_channel); |
492 | spin_lock_bh(&uart->port.lock); | 495 | spin_lock_bh(&uart->port.lock); |
493 | 496 | ||
@@ -521,6 +524,7 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) | |||
521 | } | 524 | } |
522 | 525 | ||
523 | spin_unlock_bh(&uart->port.lock); | 526 | spin_unlock_bh(&uart->port.lock); |
527 | dma_enable_irq(uart->tx_dma_channel); | ||
524 | dma_enable_irq(uart->rx_dma_channel); | 528 | dma_enable_irq(uart->rx_dma_channel); |
525 | 529 | ||
526 | mod_timer(&(uart->rx_dma_timer), jiffies + DMA_RX_FLUSH_JIFFIES); | 530 | mod_timer(&(uart->rx_dma_timer), jiffies + DMA_RX_FLUSH_JIFFIES); |
@@ -746,15 +750,6 @@ static int bfin_serial_startup(struct uart_port *port) | |||
746 | Status interrupt.\n"); | 750 | Status interrupt.\n"); |
747 | } | 751 | } |
748 | 752 | ||
749 | if (uart->cts_pin >= 0) { | ||
750 | gpio_request(uart->cts_pin, DRIVER_NAME); | ||
751 | gpio_direction_output(uart->cts_pin, 1); | ||
752 | } | ||
753 | if (uart->rts_pin >= 0) { | ||
754 | gpio_request(uart->rts_pin, DRIVER_NAME); | ||
755 | gpio_direction_output(uart->rts_pin, 0); | ||
756 | } | ||
757 | |||
758 | /* CTS RTS PINs are negative assertive. */ | 753 | /* CTS RTS PINs are negative assertive. */ |
759 | UART_PUT_MCR(uart, ACTS); | 754 | UART_PUT_MCR(uart, ACTS); |
760 | UART_SET_IER(uart, EDSSI); | 755 | UART_SET_IER(uart, EDSSI); |
@@ -801,10 +796,6 @@ static void bfin_serial_shutdown(struct uart_port *port) | |||
801 | gpio_free(uart->rts_pin); | 796 | gpio_free(uart->rts_pin); |
802 | #endif | 797 | #endif |
803 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | 798 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS |
804 | if (uart->cts_pin >= 0) | ||
805 | gpio_free(uart->cts_pin); | ||
806 | if (uart->rts_pin >= 0) | ||
807 | gpio_free(uart->rts_pin); | ||
808 | if (UART_GET_IER(uart) && EDSSI) | 799 | if (UART_GET_IER(uart) && EDSSI) |
809 | free_irq(uart->status_irq, uart); | 800 | free_irq(uart->status_irq, uart); |
810 | #endif | 801 | #endif |
@@ -1409,8 +1400,7 @@ static int bfin_serial_remove(struct platform_device *dev) | |||
1409 | continue; | 1400 | continue; |
1410 | uart_remove_one_port(&bfin_serial_reg, &bfin_serial_ports[i].port); | 1401 | uart_remove_one_port(&bfin_serial_reg, &bfin_serial_ports[i].port); |
1411 | bfin_serial_ports[i].port.dev = NULL; | 1402 | bfin_serial_ports[i].port.dev = NULL; |
1412 | #if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \ | 1403 | #if defined(CONFIG_SERIAL_BFIN_CTSRTS) |
1413 | defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS) | ||
1414 | gpio_free(bfin_serial_ports[i].cts_pin); | 1404 | gpio_free(bfin_serial_ports[i].cts_pin); |
1415 | gpio_free(bfin_serial_ports[i].rts_pin); | 1405 | gpio_free(bfin_serial_ports[i].rts_pin); |
1416 | #endif | 1406 | #endif |
diff --git a/drivers/serial/bfin_sport_uart.c b/drivers/serial/bfin_sport_uart.c index 088bb35475f1..7c72888fbf94 100644 --- a/drivers/serial/bfin_sport_uart.c +++ b/drivers/serial/bfin_sport_uart.c | |||
@@ -1,27 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * File: linux/drivers/serial/bfin_sport_uart.c | 2 | * Blackfin On-Chip Sport Emulated UART Driver |
3 | * | 3 | * |
4 | * Based on: drivers/serial/bfin_5xx.c by Aubrey Li. | 4 | * Copyright 2006-2009 Analog Devices Inc. |
5 | * Author: Roy Huang <roy.huang@analog.com> | ||
6 | * | 5 | * |
7 | * Created: Nov 22, 2006 | 6 | * Enter bugs at http://blackfin.uclinux.org/ |
8 | * Copyright: (c) 2006-2007 Analog Devices Inc. | ||
9 | * Description: this driver enable SPORTs on Blackfin emulate UART. | ||
10 | * | 7 | * |
11 | * This program is free software; you can redistribute it and/or modify | 8 | * Licensed under the GPL-2 or later. |
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, see the file COPYING, or write | ||
23 | * to the Free Software Foundation, Inc., | ||
24 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
25 | */ | 9 | */ |
26 | 10 | ||
27 | /* | 11 | /* |
@@ -29,39 +13,18 @@ | |||
29 | * http://www.analog.com/UploadedFiles/Application_Notes/399447663EE191.pdf | 13 | * http://www.analog.com/UploadedFiles/Application_Notes/399447663EE191.pdf |
30 | * This application note describe how to implement a UART on a Sharc DSP, | 14 | * This application note describe how to implement a UART on a Sharc DSP, |
31 | * but this driver is implemented on Blackfin Processor. | 15 | * but this driver is implemented on Blackfin Processor. |
16 | * Transmit Frame Sync is not used by this driver to transfer data out. | ||
32 | */ | 17 | */ |
33 | 18 | ||
34 | /* After reset, there is a prelude of low level pulse when transmit data first | 19 | /* #define DEBUG */ |
35 | * time. No addtional pulse in following transmit. | ||
36 | * According to document: | ||
37 | * The SPORTs are ready to start transmitting or receiving data no later than | ||
38 | * three serial clock cycles after they are enabled in the SPORTx_TCR1 or | ||
39 | * SPORTx_RCR1 register. No serial clock cycles are lost from this point on. | ||
40 | * The first internal frame sync will occur one frame sync delay after the | ||
41 | * SPORTs are ready. External frame syncs can occur as soon as the SPORT is | ||
42 | * ready. | ||
43 | */ | ||
44 | 20 | ||
45 | /* Thanks to Axel Alatalo <axel@rubico.se> for fixing sport rx bug. Sometimes | 21 | #define DRV_NAME "bfin-sport-uart" |
46 | * sport receives data incorrectly. The following is Axel's words. | 22 | #define DEVICE_NAME "ttySS" |
47 | * As EE-191, sport rx samples 3 times of the UART baudrate and takes the | 23 | #define pr_fmt(fmt) DRV_NAME ": " fmt |
48 | * middle smaple of every 3 samples as the data bit. For a 8-N-1 UART setting, | ||
49 | * 30 samples will be required for a byte. If transmitter sends a 1/3 bit short | ||
50 | * byte due to buadrate drift, then the 30th sample of a byte, this sample is | ||
51 | * also the third sample of the stop bit, will happens on the immediately | ||
52 | * following start bit which will be thrown away and missed. Thus since parts | ||
53 | * of the startbit will be missed and the receiver will begin to drift, the | ||
54 | * effect accumulates over time until synchronization is lost. | ||
55 | * If only require 2 samples of the stopbit (by sampling in total 29 samples), | ||
56 | * then a to short byte as in the case above will be tolerated. Then the 1/3 | ||
57 | * early startbit will trigger a framesync since the last read is complete | ||
58 | * after only 2/3 stopbit and framesync is active during the last 1/3 looking | ||
59 | * for a possible early startbit. */ | ||
60 | |||
61 | //#define DEBUG | ||
62 | 24 | ||
63 | #include <linux/module.h> | 25 | #include <linux/module.h> |
64 | #include <linux/ioport.h> | 26 | #include <linux/ioport.h> |
27 | #include <linux/io.h> | ||
65 | #include <linux/init.h> | 28 | #include <linux/init.h> |
66 | #include <linux/console.h> | 29 | #include <linux/console.h> |
67 | #include <linux/sysrq.h> | 30 | #include <linux/sysrq.h> |
@@ -75,23 +38,36 @@ | |||
75 | 38 | ||
76 | #include "bfin_sport_uart.h" | 39 | #include "bfin_sport_uart.h" |
77 | 40 | ||
41 | #ifdef CONFIG_SERIAL_BFIN_SPORT0_UART | ||
78 | unsigned short bfin_uart_pin_req_sport0[] = | 42 | unsigned short bfin_uart_pin_req_sport0[] = |
79 | {P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, \ | 43 | {P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, \ |
80 | P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0}; | 44 | P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0}; |
81 | 45 | #endif | |
46 | #ifdef CONFIG_SERIAL_BFIN_SPORT1_UART | ||
82 | unsigned short bfin_uart_pin_req_sport1[] = | 47 | unsigned short bfin_uart_pin_req_sport1[] = |
83 | {P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, \ | 48 | {P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, \ |
84 | P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0}; | 49 | P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0}; |
85 | 50 | #endif | |
86 | #define DRV_NAME "bfin-sport-uart" | 51 | #ifdef CONFIG_SERIAL_BFIN_SPORT2_UART |
52 | unsigned short bfin_uart_pin_req_sport2[] = | ||
53 | {P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, P_SPORT2_RFS, \ | ||
54 | P_SPORT2_DRPRI, P_SPORT2_RSCLK, P_SPORT2_DRSEC, P_SPORT2_DTSEC, 0}; | ||
55 | #endif | ||
56 | #ifdef CONFIG_SERIAL_BFIN_SPORT3_UART | ||
57 | unsigned short bfin_uart_pin_req_sport3[] = | ||
58 | {P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, P_SPORT3_RFS, \ | ||
59 | P_SPORT3_DRPRI, P_SPORT3_RSCLK, P_SPORT3_DRSEC, P_SPORT3_DTSEC, 0}; | ||
60 | #endif | ||
87 | 61 | ||
88 | struct sport_uart_port { | 62 | struct sport_uart_port { |
89 | struct uart_port port; | 63 | struct uart_port port; |
90 | char *name; | ||
91 | |||
92 | int tx_irq; | ||
93 | int rx_irq; | ||
94 | int err_irq; | 64 | int err_irq; |
65 | unsigned short csize; | ||
66 | unsigned short rxmask; | ||
67 | unsigned short txmask1; | ||
68 | unsigned short txmask2; | ||
69 | unsigned char stopb; | ||
70 | /* unsigned char parib; */ | ||
95 | }; | 71 | }; |
96 | 72 | ||
97 | static void sport_uart_tx_chars(struct sport_uart_port *up); | 73 | static void sport_uart_tx_chars(struct sport_uart_port *up); |
@@ -99,36 +75,42 @@ static void sport_stop_tx(struct uart_port *port); | |||
99 | 75 | ||
100 | static inline void tx_one_byte(struct sport_uart_port *up, unsigned int value) | 76 | static inline void tx_one_byte(struct sport_uart_port *up, unsigned int value) |
101 | { | 77 | { |
102 | pr_debug("%s value:%x\n", __func__, value); | 78 | pr_debug("%s value:%x, mask1=0x%x, mask2=0x%x\n", __func__, value, |
103 | /* Place a Start and Stop bit */ | 79 | up->txmask1, up->txmask2); |
80 | |||
81 | /* Place Start and Stop bits */ | ||
104 | __asm__ __volatile__ ( | 82 | __asm__ __volatile__ ( |
105 | "R2 = b#01111111100;" | 83 | "%[val] <<= 1;" |
106 | "R3 = b#10000000001;" | 84 | "%[val] = %[val] & %[mask1];" |
107 | "%0 <<= 2;" | 85 | "%[val] = %[val] | %[mask2];" |
108 | "%0 = %0 & R2;" | 86 | : [val]"+d"(value) |
109 | "%0 = %0 | R3;" | 87 | : [mask1]"d"(up->txmask1), [mask2]"d"(up->txmask2) |
110 | : "=d"(value) | 88 | : "ASTAT" |
111 | : "d"(value) | ||
112 | : "ASTAT", "R2", "R3" | ||
113 | ); | 89 | ); |
114 | pr_debug("%s value:%x\n", __func__, value); | 90 | pr_debug("%s value:%x\n", __func__, value); |
115 | 91 | ||
116 | SPORT_PUT_TX(up, value); | 92 | SPORT_PUT_TX(up, value); |
117 | } | 93 | } |
118 | 94 | ||
119 | static inline unsigned int rx_one_byte(struct sport_uart_port *up) | 95 | static inline unsigned char rx_one_byte(struct sport_uart_port *up) |
120 | { | 96 | { |
121 | unsigned int value, extract; | 97 | unsigned int value; |
98 | unsigned char extract; | ||
122 | u32 tmp_mask1, tmp_mask2, tmp_shift, tmp; | 99 | u32 tmp_mask1, tmp_mask2, tmp_shift, tmp; |
123 | 100 | ||
124 | value = SPORT_GET_RX32(up); | 101 | if ((up->csize + up->stopb) > 7) |
125 | pr_debug("%s value:%x\n", __func__, value); | 102 | value = SPORT_GET_RX32(up); |
103 | else | ||
104 | value = SPORT_GET_RX(up); | ||
105 | |||
106 | pr_debug("%s value:%x, cs=%d, mask=0x%x\n", __func__, value, | ||
107 | up->csize, up->rxmask); | ||
126 | 108 | ||
127 | /* Extract 8 bits data */ | 109 | /* Extract data */ |
128 | __asm__ __volatile__ ( | 110 | __asm__ __volatile__ ( |
129 | "%[extr] = 0;" | 111 | "%[extr] = 0;" |
130 | "%[mask1] = 0x1801(Z);" | 112 | "%[mask1] = %[rxmask];" |
131 | "%[mask2] = 0x0300(Z);" | 113 | "%[mask2] = 0x0200(Z);" |
132 | "%[shift] = 0;" | 114 | "%[shift] = 0;" |
133 | "LSETUP(.Lloop_s, .Lloop_e) LC0 = %[lc];" | 115 | "LSETUP(.Lloop_s, .Lloop_e) LC0 = %[lc];" |
134 | ".Lloop_s:" | 116 | ".Lloop_s:" |
@@ -138,9 +120,9 @@ static inline unsigned int rx_one_byte(struct sport_uart_port *up) | |||
138 | "%[mask1] = %[mask1] - %[mask2];" | 120 | "%[mask1] = %[mask1] - %[mask2];" |
139 | ".Lloop_e:" | 121 | ".Lloop_e:" |
140 | "%[shift] += 1;" | 122 | "%[shift] += 1;" |
141 | : [val]"=d"(value), [extr]"=d"(extract), [shift]"=d"(tmp_shift), [tmp]"=d"(tmp), | 123 | : [extr]"=&d"(extract), [shift]"=&d"(tmp_shift), [tmp]"=&d"(tmp), |
142 | [mask1]"=d"(tmp_mask1), [mask2]"=d"(tmp_mask2) | 124 | [mask1]"=&d"(tmp_mask1), [mask2]"=&d"(tmp_mask2) |
143 | : "d"(value), [lc]"a"(8) | 125 | : [val]"d"(value), [rxmask]"d"(up->rxmask), [lc]"a"(up->csize) |
144 | : "ASTAT", "LB0", "LC0", "LT0" | 126 | : "ASTAT", "LB0", "LC0", "LT0" |
145 | ); | 127 | ); |
146 | 128 | ||
@@ -148,29 +130,28 @@ static inline unsigned int rx_one_byte(struct sport_uart_port *up) | |||
148 | return extract; | 130 | return extract; |
149 | } | 131 | } |
150 | 132 | ||
151 | static int sport_uart_setup(struct sport_uart_port *up, int sclk, int baud_rate) | 133 | static int sport_uart_setup(struct sport_uart_port *up, int size, int baud_rate) |
152 | { | 134 | { |
153 | int tclkdiv, tfsdiv, rclkdiv; | 135 | int tclkdiv, rclkdiv; |
136 | unsigned int sclk = get_sclk(); | ||
154 | 137 | ||
155 | /* Set TCR1 and TCR2 */ | 138 | /* Set TCR1 and TCR2, TFSR is not enabled for uart */ |
156 | SPORT_PUT_TCR1(up, (LATFS | ITFS | TFSR | TLSBIT | ITCLK)); | 139 | SPORT_PUT_TCR1(up, (ITFS | TLSBIT | ITCLK)); |
157 | SPORT_PUT_TCR2(up, 10); | 140 | SPORT_PUT_TCR2(up, size + 1); |
158 | pr_debug("%s TCR1:%x, TCR2:%x\n", __func__, SPORT_GET_TCR1(up), SPORT_GET_TCR2(up)); | 141 | pr_debug("%s TCR1:%x, TCR2:%x\n", __func__, SPORT_GET_TCR1(up), SPORT_GET_TCR2(up)); |
159 | 142 | ||
160 | /* Set RCR1 and RCR2 */ | 143 | /* Set RCR1 and RCR2 */ |
161 | SPORT_PUT_RCR1(up, (RCKFE | LARFS | LRFS | RFSR | IRCLK)); | 144 | SPORT_PUT_RCR1(up, (RCKFE | LARFS | LRFS | RFSR | IRCLK)); |
162 | SPORT_PUT_RCR2(up, 28); | 145 | SPORT_PUT_RCR2(up, (size + 1) * 2 - 1); |
163 | pr_debug("%s RCR1:%x, RCR2:%x\n", __func__, SPORT_GET_RCR1(up), SPORT_GET_RCR2(up)); | 146 | pr_debug("%s RCR1:%x, RCR2:%x\n", __func__, SPORT_GET_RCR1(up), SPORT_GET_RCR2(up)); |
164 | 147 | ||
165 | tclkdiv = sclk/(2 * baud_rate) - 1; | 148 | tclkdiv = sclk / (2 * baud_rate) - 1; |
166 | tfsdiv = 12; | 149 | rclkdiv = sclk / (2 * baud_rate * 2) - 1; |
167 | rclkdiv = sclk/(2 * baud_rate * 3) - 1; | ||
168 | SPORT_PUT_TCLKDIV(up, tclkdiv); | 150 | SPORT_PUT_TCLKDIV(up, tclkdiv); |
169 | SPORT_PUT_TFSDIV(up, tfsdiv); | ||
170 | SPORT_PUT_RCLKDIV(up, rclkdiv); | 151 | SPORT_PUT_RCLKDIV(up, rclkdiv); |
171 | SSYNC(); | 152 | SSYNC(); |
172 | pr_debug("%s sclk:%d, baud_rate:%d, tclkdiv:%d, tfsdiv:%d, rclkdiv:%d\n", | 153 | pr_debug("%s sclk:%d, baud_rate:%d, tclkdiv:%d, rclkdiv:%d\n", |
173 | __func__, sclk, baud_rate, tclkdiv, tfsdiv, rclkdiv); | 154 | __func__, sclk, baud_rate, tclkdiv, rclkdiv); |
174 | 155 | ||
175 | return 0; | 156 | return 0; |
176 | } | 157 | } |
@@ -181,23 +162,29 @@ static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id) | |||
181 | struct tty_struct *tty = up->port.state->port.tty; | 162 | struct tty_struct *tty = up->port.state->port.tty; |
182 | unsigned int ch; | 163 | unsigned int ch; |
183 | 164 | ||
184 | do { | 165 | spin_lock(&up->port.lock); |
166 | |||
167 | while (SPORT_GET_STAT(up) & RXNE) { | ||
185 | ch = rx_one_byte(up); | 168 | ch = rx_one_byte(up); |
186 | up->port.icount.rx++; | 169 | up->port.icount.rx++; |
187 | 170 | ||
188 | if (uart_handle_sysrq_char(&up->port, ch)) | 171 | if (!uart_handle_sysrq_char(&up->port, ch)) |
189 | ; | ||
190 | else | ||
191 | tty_insert_flip_char(tty, ch, TTY_NORMAL); | 172 | tty_insert_flip_char(tty, ch, TTY_NORMAL); |
192 | } while (SPORT_GET_STAT(up) & RXNE); | 173 | } |
193 | tty_flip_buffer_push(tty); | 174 | tty_flip_buffer_push(tty); |
194 | 175 | ||
176 | spin_unlock(&up->port.lock); | ||
177 | |||
195 | return IRQ_HANDLED; | 178 | return IRQ_HANDLED; |
196 | } | 179 | } |
197 | 180 | ||
198 | static irqreturn_t sport_uart_tx_irq(int irq, void *dev_id) | 181 | static irqreturn_t sport_uart_tx_irq(int irq, void *dev_id) |
199 | { | 182 | { |
200 | sport_uart_tx_chars(dev_id); | 183 | struct sport_uart_port *up = dev_id; |
184 | |||
185 | spin_lock(&up->port.lock); | ||
186 | sport_uart_tx_chars(up); | ||
187 | spin_unlock(&up->port.lock); | ||
201 | 188 | ||
202 | return IRQ_HANDLED; | 189 | return IRQ_HANDLED; |
203 | } | 190 | } |
@@ -208,6 +195,8 @@ static irqreturn_t sport_uart_err_irq(int irq, void *dev_id) | |||
208 | struct tty_struct *tty = up->port.state->port.tty; | 195 | struct tty_struct *tty = up->port.state->port.tty; |
209 | unsigned int stat = SPORT_GET_STAT(up); | 196 | unsigned int stat = SPORT_GET_STAT(up); |
210 | 197 | ||
198 | spin_lock(&up->port.lock); | ||
199 | |||
211 | /* Overflow in RX FIFO */ | 200 | /* Overflow in RX FIFO */ |
212 | if (stat & ROVF) { | 201 | if (stat & ROVF) { |
213 | up->port.icount.overrun++; | 202 | up->port.icount.overrun++; |
@@ -216,15 +205,16 @@ static irqreturn_t sport_uart_err_irq(int irq, void *dev_id) | |||
216 | } | 205 | } |
217 | /* These should not happen */ | 206 | /* These should not happen */ |
218 | if (stat & (TOVF | TUVF | RUVF)) { | 207 | if (stat & (TOVF | TUVF | RUVF)) { |
219 | printk(KERN_ERR "SPORT Error:%s %s %s\n", | 208 | pr_err("SPORT Error:%s %s %s\n", |
220 | (stat & TOVF)?"TX overflow":"", | 209 | (stat & TOVF) ? "TX overflow" : "", |
221 | (stat & TUVF)?"TX underflow":"", | 210 | (stat & TUVF) ? "TX underflow" : "", |
222 | (stat & RUVF)?"RX underflow":""); | 211 | (stat & RUVF) ? "RX underflow" : ""); |
223 | SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN); | 212 | SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN); |
224 | SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) & ~RSPEN); | 213 | SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) & ~RSPEN); |
225 | } | 214 | } |
226 | SSYNC(); | 215 | SSYNC(); |
227 | 216 | ||
217 | spin_unlock(&up->port.lock); | ||
228 | return IRQ_HANDLED; | 218 | return IRQ_HANDLED; |
229 | } | 219 | } |
230 | 220 | ||
@@ -232,60 +222,37 @@ static irqreturn_t sport_uart_err_irq(int irq, void *dev_id) | |||
232 | static int sport_startup(struct uart_port *port) | 222 | static int sport_startup(struct uart_port *port) |
233 | { | 223 | { |
234 | struct sport_uart_port *up = (struct sport_uart_port *)port; | 224 | struct sport_uart_port *up = (struct sport_uart_port *)port; |
235 | char buffer[20]; | 225 | int ret; |
236 | int retval; | ||
237 | 226 | ||
238 | pr_debug("%s enter\n", __func__); | 227 | pr_debug("%s enter\n", __func__); |
239 | snprintf(buffer, 20, "%s rx", up->name); | 228 | ret = request_irq(up->port.irq, sport_uart_rx_irq, 0, |
240 | retval = request_irq(up->rx_irq, sport_uart_rx_irq, IRQF_SAMPLE_RANDOM, buffer, up); | 229 | "SPORT_UART_RX", up); |
241 | if (retval) { | 230 | if (ret) { |
242 | printk(KERN_ERR "Unable to request interrupt %s\n", buffer); | 231 | dev_err(port->dev, "unable to request SPORT RX interrupt\n"); |
243 | return retval; | 232 | return ret; |
244 | } | 233 | } |
245 | 234 | ||
246 | snprintf(buffer, 20, "%s tx", up->name); | 235 | ret = request_irq(up->port.irq+1, sport_uart_tx_irq, 0, |
247 | retval = request_irq(up->tx_irq, sport_uart_tx_irq, IRQF_SAMPLE_RANDOM, buffer, up); | 236 | "SPORT_UART_TX", up); |
248 | if (retval) { | 237 | if (ret) { |
249 | printk(KERN_ERR "Unable to request interrupt %s\n", buffer); | 238 | dev_err(port->dev, "unable to request SPORT TX interrupt\n"); |
250 | goto fail1; | 239 | goto fail1; |
251 | } | 240 | } |
252 | 241 | ||
253 | snprintf(buffer, 20, "%s err", up->name); | 242 | ret = request_irq(up->err_irq, sport_uart_err_irq, 0, |
254 | retval = request_irq(up->err_irq, sport_uart_err_irq, IRQF_SAMPLE_RANDOM, buffer, up); | 243 | "SPORT_UART_STATUS", up); |
255 | if (retval) { | 244 | if (ret) { |
256 | printk(KERN_ERR "Unable to request interrupt %s\n", buffer); | 245 | dev_err(port->dev, "unable to request SPORT status interrupt\n"); |
257 | goto fail2; | 246 | goto fail2; |
258 | } | 247 | } |
259 | 248 | ||
260 | if (port->line) { | ||
261 | if (peripheral_request_list(bfin_uart_pin_req_sport1, DRV_NAME)) | ||
262 | goto fail3; | ||
263 | } else { | ||
264 | if (peripheral_request_list(bfin_uart_pin_req_sport0, DRV_NAME)) | ||
265 | goto fail3; | ||
266 | } | ||
267 | |||
268 | sport_uart_setup(up, get_sclk(), port->uartclk); | ||
269 | |||
270 | /* Enable receive interrupt */ | ||
271 | SPORT_PUT_RCR1(up, (SPORT_GET_RCR1(up) | RSPEN)); | ||
272 | SSYNC(); | ||
273 | |||
274 | return 0; | 249 | return 0; |
250 | fail2: | ||
251 | free_irq(up->port.irq+1, up); | ||
252 | fail1: | ||
253 | free_irq(up->port.irq, up); | ||
275 | 254 | ||
276 | 255 | return ret; | |
277 | fail3: | ||
278 | printk(KERN_ERR DRV_NAME | ||
279 | ": Requesting Peripherals failed\n"); | ||
280 | |||
281 | free_irq(up->err_irq, up); | ||
282 | fail2: | ||
283 | free_irq(up->tx_irq, up); | ||
284 | fail1: | ||
285 | free_irq(up->rx_irq, up); | ||
286 | |||
287 | return retval; | ||
288 | |||
289 | } | 256 | } |
290 | 257 | ||
291 | static void sport_uart_tx_chars(struct sport_uart_port *up) | 258 | static void sport_uart_tx_chars(struct sport_uart_port *up) |
@@ -344,20 +311,17 @@ static void sport_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
344 | static void sport_stop_tx(struct uart_port *port) | 311 | static void sport_stop_tx(struct uart_port *port) |
345 | { | 312 | { |
346 | struct sport_uart_port *up = (struct sport_uart_port *)port; | 313 | struct sport_uart_port *up = (struct sport_uart_port *)port; |
347 | unsigned int stat; | ||
348 | 314 | ||
349 | pr_debug("%s enter\n", __func__); | 315 | pr_debug("%s enter\n", __func__); |
350 | 316 | ||
351 | stat = SPORT_GET_STAT(up); | ||
352 | while(!(stat & TXHRE)) { | ||
353 | udelay(1); | ||
354 | stat = SPORT_GET_STAT(up); | ||
355 | } | ||
356 | /* Although the hold register is empty, last byte is still in shift | 317 | /* Although the hold register is empty, last byte is still in shift |
357 | * register and not sent out yet. If baud rate is lower than default, | 318 | * register and not sent out yet. So, put a dummy data into TX FIFO. |
358 | * delay should be longer. For example, if the baud rate is 9600, | 319 | * Then, sport tx stops when last byte is shift out and the dummy |
359 | * the delay must be at least 2ms by experience */ | 320 | * data is moved into the shift register. |
360 | udelay(500); | 321 | */ |
322 | SPORT_PUT_TX(up, 0xffff); | ||
323 | while (!(SPORT_GET_STAT(up) & TXHRE)) | ||
324 | cpu_relax(); | ||
361 | 325 | ||
362 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN)); | 326 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN)); |
363 | SSYNC(); | 327 | SSYNC(); |
@@ -370,6 +334,7 @@ static void sport_start_tx(struct uart_port *port) | |||
370 | struct sport_uart_port *up = (struct sport_uart_port *)port; | 334 | struct sport_uart_port *up = (struct sport_uart_port *)port; |
371 | 335 | ||
372 | pr_debug("%s enter\n", __func__); | 336 | pr_debug("%s enter\n", __func__); |
337 | |||
373 | /* Write data into SPORT FIFO before enable SPROT to transmit */ | 338 | /* Write data into SPORT FIFO before enable SPROT to transmit */ |
374 | sport_uart_tx_chars(up); | 339 | sport_uart_tx_chars(up); |
375 | 340 | ||
@@ -403,37 +368,24 @@ static void sport_shutdown(struct uart_port *port) | |||
403 | { | 368 | { |
404 | struct sport_uart_port *up = (struct sport_uart_port *)port; | 369 | struct sport_uart_port *up = (struct sport_uart_port *)port; |
405 | 370 | ||
406 | pr_debug("%s enter\n", __func__); | 371 | dev_dbg(port->dev, "%s enter\n", __func__); |
407 | 372 | ||
408 | /* Disable sport */ | 373 | /* Disable sport */ |
409 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN)); | 374 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN)); |
410 | SPORT_PUT_RCR1(up, (SPORT_GET_RCR1(up) & ~RSPEN)); | 375 | SPORT_PUT_RCR1(up, (SPORT_GET_RCR1(up) & ~RSPEN)); |
411 | SSYNC(); | 376 | SSYNC(); |
412 | 377 | ||
413 | if (port->line) { | 378 | free_irq(up->port.irq, up); |
414 | peripheral_free_list(bfin_uart_pin_req_sport1); | 379 | free_irq(up->port.irq+1, up); |
415 | } else { | ||
416 | peripheral_free_list(bfin_uart_pin_req_sport0); | ||
417 | } | ||
418 | |||
419 | free_irq(up->rx_irq, up); | ||
420 | free_irq(up->tx_irq, up); | ||
421 | free_irq(up->err_irq, up); | 380 | free_irq(up->err_irq, up); |
422 | } | 381 | } |
423 | 382 | ||
424 | static void sport_set_termios(struct uart_port *port, | ||
425 | struct ktermios *termios, struct ktermios *old) | ||
426 | { | ||
427 | pr_debug("%s enter, c_cflag:%08x\n", __func__, termios->c_cflag); | ||
428 | uart_update_timeout(port, CS8 ,port->uartclk); | ||
429 | } | ||
430 | |||
431 | static const char *sport_type(struct uart_port *port) | 383 | static const char *sport_type(struct uart_port *port) |
432 | { | 384 | { |
433 | struct sport_uart_port *up = (struct sport_uart_port *)port; | 385 | struct sport_uart_port *up = (struct sport_uart_port *)port; |
434 | 386 | ||
435 | pr_debug("%s enter\n", __func__); | 387 | pr_debug("%s enter\n", __func__); |
436 | return up->name; | 388 | return up->port.type == PORT_BFIN_SPORT ? "BFIN-SPORT-UART" : NULL; |
437 | } | 389 | } |
438 | 390 | ||
439 | static void sport_release_port(struct uart_port *port) | 391 | static void sport_release_port(struct uart_port *port) |
@@ -461,6 +413,110 @@ static int sport_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
461 | return 0; | 413 | return 0; |
462 | } | 414 | } |
463 | 415 | ||
416 | static void sport_set_termios(struct uart_port *port, | ||
417 | struct ktermios *termios, struct ktermios *old) | ||
418 | { | ||
419 | struct sport_uart_port *up = (struct sport_uart_port *)port; | ||
420 | unsigned long flags; | ||
421 | int i; | ||
422 | |||
423 | pr_debug("%s enter, c_cflag:%08x\n", __func__, termios->c_cflag); | ||
424 | |||
425 | switch (termios->c_cflag & CSIZE) { | ||
426 | case CS8: | ||
427 | up->csize = 8; | ||
428 | break; | ||
429 | case CS7: | ||
430 | up->csize = 7; | ||
431 | break; | ||
432 | case CS6: | ||
433 | up->csize = 6; | ||
434 | break; | ||
435 | case CS5: | ||
436 | up->csize = 5; | ||
437 | break; | ||
438 | default: | ||
439 | pr_warning("requested word length not supported\n"); | ||
440 | } | ||
441 | |||
442 | if (termios->c_cflag & CSTOPB) { | ||
443 | up->stopb = 1; | ||
444 | } | ||
445 | if (termios->c_cflag & PARENB) { | ||
446 | pr_warning("PAREN bits is not supported yet\n"); | ||
447 | /* up->parib = 1; */ | ||
448 | } | ||
449 | |||
450 | port->read_status_mask = OE; | ||
451 | if (termios->c_iflag & INPCK) | ||
452 | port->read_status_mask |= (FE | PE); | ||
453 | if (termios->c_iflag & (BRKINT | PARMRK)) | ||
454 | port->read_status_mask |= BI; | ||
455 | |||
456 | /* | ||
457 | * Characters to ignore | ||
458 | */ | ||
459 | port->ignore_status_mask = 0; | ||
460 | if (termios->c_iflag & IGNPAR) | ||
461 | port->ignore_status_mask |= FE | PE; | ||
462 | if (termios->c_iflag & IGNBRK) { | ||
463 | port->ignore_status_mask |= BI; | ||
464 | /* | ||
465 | * If we're ignoring parity and break indicators, | ||
466 | * ignore overruns too (for real raw support). | ||
467 | */ | ||
468 | if (termios->c_iflag & IGNPAR) | ||
469 | port->ignore_status_mask |= OE; | ||
470 | } | ||
471 | |||
472 | /* RX extract mask */ | ||
473 | up->rxmask = 0x01 | (((up->csize + up->stopb) * 2 - 1) << 0x8); | ||
474 | /* TX masks, 8 bit data and 1 bit stop for example: | ||
475 | * mask1 = b#0111111110 | ||
476 | * mask2 = b#1000000000 | ||
477 | */ | ||
478 | for (i = 0, up->txmask1 = 0; i < up->csize; i++) | ||
479 | up->txmask1 |= (1<<i); | ||
480 | up->txmask2 = (1<<i); | ||
481 | if (up->stopb) { | ||
482 | ++i; | ||
483 | up->txmask2 |= (1<<i); | ||
484 | } | ||
485 | up->txmask1 <<= 1; | ||
486 | up->txmask2 <<= 1; | ||
487 | /* uart baud rate */ | ||
488 | port->uartclk = uart_get_baud_rate(port, termios, old, 0, get_sclk()/16); | ||
489 | |||
490 | spin_lock_irqsave(&up->port.lock, flags); | ||
491 | |||
492 | /* Disable UART */ | ||
493 | SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN); | ||
494 | SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) & ~RSPEN); | ||
495 | |||
496 | sport_uart_setup(up, up->csize + up->stopb, port->uartclk); | ||
497 | |||
498 | /* driver TX line high after config, one dummy data is | ||
499 | * necessary to stop sport after shift one byte | ||
500 | */ | ||
501 | SPORT_PUT_TX(up, 0xffff); | ||
502 | SPORT_PUT_TX(up, 0xffff); | ||
503 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) | TSPEN)); | ||
504 | SSYNC(); | ||
505 | while (!(SPORT_GET_STAT(up) & TXHRE)) | ||
506 | cpu_relax(); | ||
507 | SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN); | ||
508 | SSYNC(); | ||
509 | |||
510 | /* Port speed changed, update the per-port timeout. */ | ||
511 | uart_update_timeout(port, termios->c_cflag, port->uartclk); | ||
512 | |||
513 | /* Enable sport rx */ | ||
514 | SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) | RSPEN); | ||
515 | SSYNC(); | ||
516 | |||
517 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
518 | } | ||
519 | |||
464 | struct uart_ops sport_uart_ops = { | 520 | struct uart_ops sport_uart_ops = { |
465 | .tx_empty = sport_tx_empty, | 521 | .tx_empty = sport_tx_empty, |
466 | .set_mctrl = sport_set_mctrl, | 522 | .set_mctrl = sport_set_mctrl, |
@@ -480,138 +536,319 @@ struct uart_ops sport_uart_ops = { | |||
480 | .verify_port = sport_verify_port, | 536 | .verify_port = sport_verify_port, |
481 | }; | 537 | }; |
482 | 538 | ||
483 | static struct sport_uart_port sport_uart_ports[] = { | 539 | #define BFIN_SPORT_UART_MAX_PORTS 4 |
484 | { /* SPORT 0 */ | 540 | |
485 | .name = "SPORT0", | 541 | static struct sport_uart_port *bfin_sport_uart_ports[BFIN_SPORT_UART_MAX_PORTS]; |
486 | .tx_irq = IRQ_SPORT0_TX, | 542 | |
487 | .rx_irq = IRQ_SPORT0_RX, | 543 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE |
488 | .err_irq= IRQ_SPORT0_ERROR, | 544 | static int __init |
489 | .port = { | 545 | sport_uart_console_setup(struct console *co, char *options) |
490 | .type = PORT_BFIN_SPORT, | 546 | { |
491 | .iotype = UPIO_MEM, | 547 | struct sport_uart_port *up; |
492 | .membase = (void __iomem *)SPORT0_TCR1, | 548 | int baud = 57600; |
493 | .mapbase = SPORT0_TCR1, | 549 | int bits = 8; |
494 | .irq = IRQ_SPORT0_RX, | 550 | int parity = 'n'; |
495 | .uartclk = CONFIG_SPORT_BAUD_RATE, | 551 | int flow = 'n'; |
496 | .fifosize = 8, | 552 | |
497 | .ops = &sport_uart_ops, | 553 | /* Check whether an invalid uart number has been specified */ |
498 | .line = 0, | 554 | if (co->index < 0 || co->index >= BFIN_SPORT_UART_MAX_PORTS) |
499 | }, | 555 | return -ENODEV; |
500 | }, { /* SPORT 1 */ | 556 | |
501 | .name = "SPORT1", | 557 | up = bfin_sport_uart_ports[co->index]; |
502 | .tx_irq = IRQ_SPORT1_TX, | 558 | if (!up) |
503 | .rx_irq = IRQ_SPORT1_RX, | 559 | return -ENODEV; |
504 | .err_irq= IRQ_SPORT1_ERROR, | 560 | |
505 | .port = { | 561 | if (options) |
506 | .type = PORT_BFIN_SPORT, | 562 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
507 | .iotype = UPIO_MEM, | 563 | |
508 | .membase = (void __iomem *)SPORT1_TCR1, | 564 | return uart_set_options(&up->port, co, baud, parity, bits, flow); |
509 | .mapbase = SPORT1_TCR1, | 565 | } |
510 | .irq = IRQ_SPORT1_RX, | 566 | |
511 | .uartclk = CONFIG_SPORT_BAUD_RATE, | 567 | static void sport_uart_console_putchar(struct uart_port *port, int ch) |
512 | .fifosize = 8, | 568 | { |
513 | .ops = &sport_uart_ops, | 569 | struct sport_uart_port *up = (struct sport_uart_port *)port; |
514 | .line = 1, | 570 | |
515 | }, | 571 | while (SPORT_GET_STAT(up) & TXF) |
572 | barrier(); | ||
573 | |||
574 | tx_one_byte(up, ch); | ||
575 | } | ||
576 | |||
577 | /* | ||
578 | * Interrupts are disabled on entering | ||
579 | */ | ||
580 | static void | ||
581 | sport_uart_console_write(struct console *co, const char *s, unsigned int count) | ||
582 | { | ||
583 | struct sport_uart_port *up = bfin_sport_uart_ports[co->index]; | ||
584 | unsigned long flags; | ||
585 | |||
586 | spin_lock_irqsave(&up->port.lock, flags); | ||
587 | |||
588 | if (SPORT_GET_TCR1(up) & TSPEN) | ||
589 | uart_console_write(&up->port, s, count, sport_uart_console_putchar); | ||
590 | else { | ||
591 | /* dummy data to start sport */ | ||
592 | while (SPORT_GET_STAT(up) & TXF) | ||
593 | barrier(); | ||
594 | SPORT_PUT_TX(up, 0xffff); | ||
595 | /* Enable transmit, then an interrupt will generated */ | ||
596 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) | TSPEN)); | ||
597 | SSYNC(); | ||
598 | |||
599 | uart_console_write(&up->port, s, count, sport_uart_console_putchar); | ||
600 | |||
601 | /* Although the hold register is empty, last byte is still in shift | ||
602 | * register and not sent out yet. So, put a dummy data into TX FIFO. | ||
603 | * Then, sport tx stops when last byte is shift out and the dummy | ||
604 | * data is moved into the shift register. | ||
605 | */ | ||
606 | while (SPORT_GET_STAT(up) & TXF) | ||
607 | barrier(); | ||
608 | SPORT_PUT_TX(up, 0xffff); | ||
609 | while (!(SPORT_GET_STAT(up) & TXHRE)) | ||
610 | barrier(); | ||
611 | |||
612 | /* Stop sport tx transfer */ | ||
613 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN)); | ||
614 | SSYNC(); | ||
516 | } | 615 | } |
616 | |||
617 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
618 | } | ||
619 | |||
620 | static struct uart_driver sport_uart_reg; | ||
621 | |||
622 | static struct console sport_uart_console = { | ||
623 | .name = DEVICE_NAME, | ||
624 | .write = sport_uart_console_write, | ||
625 | .device = uart_console_device, | ||
626 | .setup = sport_uart_console_setup, | ||
627 | .flags = CON_PRINTBUFFER, | ||
628 | .index = -1, | ||
629 | .data = &sport_uart_reg, | ||
517 | }; | 630 | }; |
518 | 631 | ||
632 | #define SPORT_UART_CONSOLE (&sport_uart_console) | ||
633 | #else | ||
634 | #define SPORT_UART_CONSOLE NULL | ||
635 | #endif /* CONFIG_SERIAL_BFIN_SPORT_CONSOLE */ | ||
636 | |||
637 | |||
519 | static struct uart_driver sport_uart_reg = { | 638 | static struct uart_driver sport_uart_reg = { |
520 | .owner = THIS_MODULE, | 639 | .owner = THIS_MODULE, |
521 | .driver_name = "SPORT-UART", | 640 | .driver_name = DRV_NAME, |
522 | .dev_name = "ttySS", | 641 | .dev_name = DEVICE_NAME, |
523 | .major = 204, | 642 | .major = 204, |
524 | .minor = 84, | 643 | .minor = 84, |
525 | .nr = ARRAY_SIZE(sport_uart_ports), | 644 | .nr = BFIN_SPORT_UART_MAX_PORTS, |
526 | .cons = NULL, | 645 | .cons = SPORT_UART_CONSOLE, |
527 | }; | 646 | }; |
528 | 647 | ||
529 | static int sport_uart_suspend(struct platform_device *dev, pm_message_t state) | 648 | #ifdef CONFIG_PM |
649 | static int sport_uart_suspend(struct device *dev) | ||
530 | { | 650 | { |
531 | struct sport_uart_port *sport = platform_get_drvdata(dev); | 651 | struct sport_uart_port *sport = dev_get_drvdata(dev); |
532 | 652 | ||
533 | pr_debug("%s enter\n", __func__); | 653 | dev_dbg(dev, "%s enter\n", __func__); |
534 | if (sport) | 654 | if (sport) |
535 | uart_suspend_port(&sport_uart_reg, &sport->port); | 655 | uart_suspend_port(&sport_uart_reg, &sport->port); |
536 | 656 | ||
537 | return 0; | 657 | return 0; |
538 | } | 658 | } |
539 | 659 | ||
540 | static int sport_uart_resume(struct platform_device *dev) | 660 | static int sport_uart_resume(struct device *dev) |
541 | { | 661 | { |
542 | struct sport_uart_port *sport = platform_get_drvdata(dev); | 662 | struct sport_uart_port *sport = dev_get_drvdata(dev); |
543 | 663 | ||
544 | pr_debug("%s enter\n", __func__); | 664 | dev_dbg(dev, "%s enter\n", __func__); |
545 | if (sport) | 665 | if (sport) |
546 | uart_resume_port(&sport_uart_reg, &sport->port); | 666 | uart_resume_port(&sport_uart_reg, &sport->port); |
547 | 667 | ||
548 | return 0; | 668 | return 0; |
549 | } | 669 | } |
550 | 670 | ||
551 | static int sport_uart_probe(struct platform_device *dev) | 671 | static struct dev_pm_ops bfin_sport_uart_dev_pm_ops = { |
672 | .suspend = sport_uart_suspend, | ||
673 | .resume = sport_uart_resume, | ||
674 | }; | ||
675 | #endif | ||
676 | |||
677 | static int __devinit sport_uart_probe(struct platform_device *pdev) | ||
552 | { | 678 | { |
553 | pr_debug("%s enter\n", __func__); | 679 | struct resource *res; |
554 | sport_uart_ports[dev->id].port.dev = &dev->dev; | 680 | struct sport_uart_port *sport; |
555 | uart_add_one_port(&sport_uart_reg, &sport_uart_ports[dev->id].port); | 681 | int ret = 0; |
556 | platform_set_drvdata(dev, &sport_uart_ports[dev->id]); | ||
557 | 682 | ||
558 | return 0; | 683 | dev_dbg(&pdev->dev, "%s enter\n", __func__); |
684 | |||
685 | if (pdev->id < 0 || pdev->id >= BFIN_SPORT_UART_MAX_PORTS) { | ||
686 | dev_err(&pdev->dev, "Wrong sport uart platform device id.\n"); | ||
687 | return -ENOENT; | ||
688 | } | ||
689 | |||
690 | if (bfin_sport_uart_ports[pdev->id] == NULL) { | ||
691 | bfin_sport_uart_ports[pdev->id] = | ||
692 | kmalloc(sizeof(struct sport_uart_port), GFP_KERNEL); | ||
693 | sport = bfin_sport_uart_ports[pdev->id]; | ||
694 | if (!sport) { | ||
695 | dev_err(&pdev->dev, | ||
696 | "Fail to kmalloc sport_uart_port\n"); | ||
697 | return -ENOMEM; | ||
698 | } | ||
699 | |||
700 | ret = peripheral_request_list( | ||
701 | (unsigned short *)pdev->dev.platform_data, DRV_NAME); | ||
702 | if (ret) { | ||
703 | dev_err(&pdev->dev, | ||
704 | "Fail to request SPORT peripherals\n"); | ||
705 | goto out_error_free_mem; | ||
706 | } | ||
707 | |||
708 | spin_lock_init(&sport->port.lock); | ||
709 | sport->port.fifosize = SPORT_TX_FIFO_SIZE, | ||
710 | sport->port.ops = &sport_uart_ops; | ||
711 | sport->port.line = pdev->id; | ||
712 | sport->port.iotype = UPIO_MEM; | ||
713 | sport->port.flags = UPF_BOOT_AUTOCONF; | ||
714 | |||
715 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
716 | if (res == NULL) { | ||
717 | dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n"); | ||
718 | ret = -ENOENT; | ||
719 | goto out_error_free_peripherals; | ||
720 | } | ||
721 | |||
722 | sport->port.membase = ioremap(res->start, | ||
723 | res->end - res->start); | ||
724 | if (!sport->port.membase) { | ||
725 | dev_err(&pdev->dev, "Cannot map sport IO\n"); | ||
726 | ret = -ENXIO; | ||
727 | goto out_error_free_peripherals; | ||
728 | } | ||
729 | |||
730 | sport->port.irq = platform_get_irq(pdev, 0); | ||
731 | if (sport->port.irq < 0) { | ||
732 | dev_err(&pdev->dev, "No sport RX/TX IRQ specified\n"); | ||
733 | ret = -ENOENT; | ||
734 | goto out_error_unmap; | ||
735 | } | ||
736 | |||
737 | sport->err_irq = platform_get_irq(pdev, 1); | ||
738 | if (sport->err_irq < 0) { | ||
739 | dev_err(&pdev->dev, "No sport status IRQ specified\n"); | ||
740 | ret = -ENOENT; | ||
741 | goto out_error_unmap; | ||
742 | } | ||
743 | } | ||
744 | |||
745 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE | ||
746 | if (!is_early_platform_device(pdev)) { | ||
747 | #endif | ||
748 | sport = bfin_sport_uart_ports[pdev->id]; | ||
749 | sport->port.dev = &pdev->dev; | ||
750 | dev_set_drvdata(&pdev->dev, sport); | ||
751 | ret = uart_add_one_port(&sport_uart_reg, &sport->port); | ||
752 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE | ||
753 | } | ||
754 | #endif | ||
755 | if (!ret) | ||
756 | return 0; | ||
757 | |||
758 | if (sport) { | ||
759 | out_error_unmap: | ||
760 | iounmap(sport->port.membase); | ||
761 | out_error_free_peripherals: | ||
762 | peripheral_free_list( | ||
763 | (unsigned short *)pdev->dev.platform_data); | ||
764 | out_error_free_mem: | ||
765 | kfree(sport); | ||
766 | bfin_sport_uart_ports[pdev->id] = NULL; | ||
767 | } | ||
768 | |||
769 | return ret; | ||
559 | } | 770 | } |
560 | 771 | ||
561 | static int sport_uart_remove(struct platform_device *dev) | 772 | static int __devexit sport_uart_remove(struct platform_device *pdev) |
562 | { | 773 | { |
563 | struct sport_uart_port *sport = platform_get_drvdata(dev); | 774 | struct sport_uart_port *sport = platform_get_drvdata(pdev); |
564 | 775 | ||
565 | pr_debug("%s enter\n", __func__); | 776 | dev_dbg(&pdev->dev, "%s enter\n", __func__); |
566 | platform_set_drvdata(dev, NULL); | 777 | dev_set_drvdata(&pdev->dev, NULL); |
567 | 778 | ||
568 | if (sport) | 779 | if (sport) { |
569 | uart_remove_one_port(&sport_uart_reg, &sport->port); | 780 | uart_remove_one_port(&sport_uart_reg, &sport->port); |
781 | iounmap(sport->port.membase); | ||
782 | peripheral_free_list( | ||
783 | (unsigned short *)pdev->dev.platform_data); | ||
784 | kfree(sport); | ||
785 | bfin_sport_uart_ports[pdev->id] = NULL; | ||
786 | } | ||
570 | 787 | ||
571 | return 0; | 788 | return 0; |
572 | } | 789 | } |
573 | 790 | ||
574 | static struct platform_driver sport_uart_driver = { | 791 | static struct platform_driver sport_uart_driver = { |
575 | .probe = sport_uart_probe, | 792 | .probe = sport_uart_probe, |
576 | .remove = sport_uart_remove, | 793 | .remove = __devexit_p(sport_uart_remove), |
577 | .suspend = sport_uart_suspend, | ||
578 | .resume = sport_uart_resume, | ||
579 | .driver = { | 794 | .driver = { |
580 | .name = DRV_NAME, | 795 | .name = DRV_NAME, |
796 | #ifdef CONFIG_PM | ||
797 | .pm = &bfin_sport_uart_dev_pm_ops, | ||
798 | #endif | ||
581 | }, | 799 | }, |
582 | }; | 800 | }; |
583 | 801 | ||
802 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE | ||
803 | static __initdata struct early_platform_driver early_sport_uart_driver = { | ||
804 | .class_str = DRV_NAME, | ||
805 | .pdrv = &sport_uart_driver, | ||
806 | .requested_id = EARLY_PLATFORM_ID_UNSET, | ||
807 | }; | ||
808 | |||
809 | static int __init sport_uart_rs_console_init(void) | ||
810 | { | ||
811 | early_platform_driver_register(&early_sport_uart_driver, DRV_NAME); | ||
812 | |||
813 | early_platform_driver_probe(DRV_NAME, BFIN_SPORT_UART_MAX_PORTS, 0); | ||
814 | |||
815 | register_console(&sport_uart_console); | ||
816 | |||
817 | return 0; | ||
818 | } | ||
819 | console_initcall(sport_uart_rs_console_init); | ||
820 | #endif | ||
821 | |||
584 | static int __init sport_uart_init(void) | 822 | static int __init sport_uart_init(void) |
585 | { | 823 | { |
586 | int ret; | 824 | int ret; |
587 | 825 | ||
588 | pr_debug("%s enter\n", __func__); | 826 | pr_info("Serial: Blackfin uart over sport driver\n"); |
827 | |||
589 | ret = uart_register_driver(&sport_uart_reg); | 828 | ret = uart_register_driver(&sport_uart_reg); |
590 | if (ret != 0) { | 829 | if (ret) { |
591 | printk(KERN_ERR "Failed to register %s:%d\n", | 830 | pr_err("failed to register %s:%d\n", |
592 | sport_uart_reg.driver_name, ret); | 831 | sport_uart_reg.driver_name, ret); |
593 | return ret; | 832 | return ret; |
594 | } | 833 | } |
595 | 834 | ||
596 | ret = platform_driver_register(&sport_uart_driver); | 835 | ret = platform_driver_register(&sport_uart_driver); |
597 | if (ret != 0) { | 836 | if (ret) { |
598 | printk(KERN_ERR "Failed to register sport uart driver:%d\n", ret); | 837 | pr_err("failed to register sport uart driver:%d\n", ret); |
599 | uart_unregister_driver(&sport_uart_reg); | 838 | uart_unregister_driver(&sport_uart_reg); |
600 | } | 839 | } |
601 | 840 | ||
602 | |||
603 | pr_debug("%s exit\n", __func__); | ||
604 | return ret; | 841 | return ret; |
605 | } | 842 | } |
843 | module_init(sport_uart_init); | ||
606 | 844 | ||
607 | static void __exit sport_uart_exit(void) | 845 | static void __exit sport_uart_exit(void) |
608 | { | 846 | { |
609 | pr_debug("%s enter\n", __func__); | ||
610 | platform_driver_unregister(&sport_uart_driver); | 847 | platform_driver_unregister(&sport_uart_driver); |
611 | uart_unregister_driver(&sport_uart_reg); | 848 | uart_unregister_driver(&sport_uart_reg); |
612 | } | 849 | } |
613 | |||
614 | module_init(sport_uart_init); | ||
615 | module_exit(sport_uart_exit); | 850 | module_exit(sport_uart_exit); |
616 | 851 | ||
852 | MODULE_AUTHOR("Sonic Zhang, Roy Huang"); | ||
853 | MODULE_DESCRIPTION("Blackfin serial over SPORT driver"); | ||
617 | MODULE_LICENSE("GPL"); | 854 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/serial/bfin_sport_uart.h b/drivers/serial/bfin_sport_uart.h index 671d41cc1a3f..abe03614e4df 100644 --- a/drivers/serial/bfin_sport_uart.h +++ b/drivers/serial/bfin_sport_uart.h | |||
@@ -1,29 +1,23 @@ | |||
1 | /* | 1 | /* |
2 | * File: linux/drivers/serial/bfin_sport_uart.h | 2 | * Blackfin On-Chip Sport Emulated UART Driver |
3 | * | 3 | * |
4 | * Based on: include/asm-blackfin/mach-533/bfin_serial_5xx.h | 4 | * Copyright 2006-2008 Analog Devices Inc. |
5 | * Author: Roy Huang <roy.huang>analog.com> | ||
6 | * | 5 | * |
7 | * Created: Nov 22, 2006 | 6 | * Enter bugs at http://blackfin.uclinux.org/ |
8 | * Copyright: (C) Analog Device Inc. | ||
9 | * Description: this driver enable SPORTs on Blackfin emulate UART. | ||
10 | * | 7 | * |
11 | * This program is free software; you can redistribute it and/or modify | 8 | * Licensed under the GPL-2 or later. |
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, see the file COPYING, or write | ||
23 | * to the Free Software Foundation, Inc., | ||
24 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
25 | */ | 9 | */ |
26 | 10 | ||
11 | /* | ||
12 | * This driver and the hardware supported are in term of EE-191 of ADI. | ||
13 | * http://www.analog.com/UploadedFiles/Application_Notes/399447663EE191.pdf | ||
14 | * This application note describe how to implement a UART on a Sharc DSP, | ||
15 | * but this driver is implemented on Blackfin Processor. | ||
16 | * Transmit Frame Sync is not used by this driver to transfer data out. | ||
17 | */ | ||
18 | |||
19 | #ifndef _BFIN_SPORT_UART_H | ||
20 | #define _BFIN_SPORT_UART_H | ||
27 | 21 | ||
28 | #define OFFSET_TCR1 0x00 /* Transmit Configuration 1 Register */ | 22 | #define OFFSET_TCR1 0x00 /* Transmit Configuration 1 Register */ |
29 | #define OFFSET_TCR2 0x04 /* Transmit Configuration 2 Register */ | 23 | #define OFFSET_TCR2 0x04 /* Transmit Configuration 2 Register */ |
@@ -61,3 +55,7 @@ | |||
61 | #define SPORT_PUT_RCLKDIV(sport, v) bfin_write16(((sport)->port.membase + OFFSET_RCLKDIV), v) | 55 | #define SPORT_PUT_RCLKDIV(sport, v) bfin_write16(((sport)->port.membase + OFFSET_RCLKDIV), v) |
62 | #define SPORT_PUT_RFSDIV(sport, v) bfin_write16(((sport)->port.membase + OFFSET_RFSDIV), v) | 56 | #define SPORT_PUT_RFSDIV(sport, v) bfin_write16(((sport)->port.membase + OFFSET_RFSDIV), v) |
63 | #define SPORT_PUT_STAT(sport, v) bfin_write16(((sport)->port.membase + OFFSET_STAT), v) | 57 | #define SPORT_PUT_STAT(sport, v) bfin_write16(((sport)->port.membase + OFFSET_STAT), v) |
58 | |||
59 | #define SPORT_TX_FIFO_SIZE 8 | ||
60 | |||
61 | #endif /* _BFIN_SPORT_UART_H */ | ||
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c index 0028b6f89ce6..53a468227056 100644 --- a/drivers/serial/icom.c +++ b/drivers/serial/icom.c | |||
@@ -751,7 +751,6 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) | |||
751 | trace(icom_port, "FID_STATUS", status); | 751 | trace(icom_port, "FID_STATUS", status); |
752 | count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength); | 752 | count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength); |
753 | 753 | ||
754 | count = tty_buffer_request_room(tty, count); | ||
755 | trace(icom_port, "RCV_COUNT", count); | 754 | trace(icom_port, "RCV_COUNT", count); |
756 | 755 | ||
757 | trace(icom_port, "REAL_COUNT", count); | 756 | trace(icom_port, "REAL_COUNT", count); |
@@ -1654,4 +1653,6 @@ MODULE_DESCRIPTION("IBM iSeries Serial IOA driver"); | |||
1654 | MODULE_SUPPORTED_DEVICE | 1653 | MODULE_SUPPORTED_DEVICE |
1655 | ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters"); | 1654 | ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters"); |
1656 | MODULE_LICENSE("GPL"); | 1655 | MODULE_LICENSE("GPL"); |
1657 | 1656 | MODULE_FIRMWARE("icom_call_setup.bin"); | |
1657 | MODULE_FIRMWARE("icom_res_dce.bin"); | ||
1658 | MODULE_FIRMWARE("icom_asc.bin"); | ||
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 60d665a17a88..d00fcf8e6c70 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c | |||
@@ -1279,7 +1279,7 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
1279 | sport->use_irda = 1; | 1279 | sport->use_irda = 1; |
1280 | #endif | 1280 | #endif |
1281 | 1281 | ||
1282 | if (pdata->init) { | 1282 | if (pdata && pdata->init) { |
1283 | ret = pdata->init(pdev); | 1283 | ret = pdata->init(pdev); |
1284 | if (ret) | 1284 | if (ret) |
1285 | goto clkput; | 1285 | goto clkput; |
@@ -1292,7 +1292,7 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
1292 | 1292 | ||
1293 | return 0; | 1293 | return 0; |
1294 | deinit: | 1294 | deinit: |
1295 | if (pdata->exit) | 1295 | if (pdata && pdata->exit) |
1296 | pdata->exit(pdev); | 1296 | pdata->exit(pdev); |
1297 | clkput: | 1297 | clkput: |
1298 | clk_put(sport->clk); | 1298 | clk_put(sport->clk); |
@@ -1321,7 +1321,7 @@ static int serial_imx_remove(struct platform_device *pdev) | |||
1321 | 1321 | ||
1322 | clk_disable(sport->clk); | 1322 | clk_disable(sport->clk); |
1323 | 1323 | ||
1324 | if (pdata->exit) | 1324 | if (pdata && pdata->exit) |
1325 | pdata->exit(pdev); | 1325 | pdata->exit(pdev); |
1326 | 1326 | ||
1327 | iounmap(sport->port.membase); | 1327 | iounmap(sport->port.membase); |
diff --git a/drivers/serial/ioc3_serial.c b/drivers/serial/ioc3_serial.c index 85dc0410ac1a..23ba6b40b3ac 100644 --- a/drivers/serial/ioc3_serial.c +++ b/drivers/serial/ioc3_serial.c | |||
@@ -1411,8 +1411,7 @@ static int receive_chars(struct uart_port *the_port) | |||
1411 | read_count = do_read(the_port, ch, MAX_CHARS); | 1411 | read_count = do_read(the_port, ch, MAX_CHARS); |
1412 | if (read_count > 0) { | 1412 | if (read_count > 0) { |
1413 | flip = 1; | 1413 | flip = 1; |
1414 | read_room = tty_buffer_request_room(tty, read_count); | 1414 | read_room = tty_insert_flip_string(tty, ch, read_count); |
1415 | tty_insert_flip_string(tty, ch, read_room); | ||
1416 | the_port->icount.rx += read_count; | 1415 | the_port->icount.rx += read_count; |
1417 | } | 1416 | } |
1418 | spin_unlock_irqrestore(&the_port->lock, pflags); | 1417 | spin_unlock_irqrestore(&the_port->lock, pflags); |
diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/serial/jsm/jsm_driver.c index 108c3e0471fd..12cb5e446a4f 100644 --- a/drivers/serial/jsm/jsm_driver.c +++ b/drivers/serial/jsm/jsm_driver.c | |||
@@ -179,6 +179,7 @@ static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device | |||
179 | 179 | ||
180 | return 0; | 180 | return 0; |
181 | out_free_irq: | 181 | out_free_irq: |
182 | jsm_remove_uart_port(brd); | ||
182 | free_irq(brd->irq, brd); | 183 | free_irq(brd->irq, brd); |
183 | out_iounmap: | 184 | out_iounmap: |
184 | iounmap(brd->re_map_membase); | 185 | iounmap(brd->re_map_membase); |
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c index cd95e215550d..5673ca9dfdc8 100644 --- a/drivers/serial/jsm/jsm_tty.c +++ b/drivers/serial/jsm/jsm_tty.c | |||
@@ -432,7 +432,7 @@ int __devinit jsm_tty_init(struct jsm_board *brd) | |||
432 | 432 | ||
433 | int jsm_uart_port_init(struct jsm_board *brd) | 433 | int jsm_uart_port_init(struct jsm_board *brd) |
434 | { | 434 | { |
435 | int i; | 435 | int i, rc; |
436 | unsigned int line; | 436 | unsigned int line; |
437 | struct jsm_channel *ch; | 437 | struct jsm_channel *ch; |
438 | 438 | ||
@@ -467,8 +467,11 @@ int jsm_uart_port_init(struct jsm_board *brd) | |||
467 | } else | 467 | } else |
468 | set_bit(line, linemap); | 468 | set_bit(line, linemap); |
469 | brd->channels[i]->uart_port.line = line; | 469 | brd->channels[i]->uart_port.line = line; |
470 | if (uart_add_one_port (&jsm_uart_driver, &brd->channels[i]->uart_port)) | 470 | rc = uart_add_one_port (&jsm_uart_driver, &brd->channels[i]->uart_port); |
471 | printk(KERN_INFO "jsm: add device failed\n"); | 471 | if (rc){ |
472 | printk(KERN_INFO "jsm: Port %d failed. Aborting...\n", i); | ||
473 | return rc; | ||
474 | } | ||
472 | else | 475 | else |
473 | printk(KERN_INFO "jsm: Port %d added\n", i); | 476 | printk(KERN_INFO "jsm: Port %d added\n", i); |
474 | } | 477 | } |
diff --git a/drivers/serial/msm_serial.c b/drivers/serial/msm_serial.c index b05c5aa02cb4..ecdc0facf7ee 100644 --- a/drivers/serial/msm_serial.c +++ b/drivers/serial/msm_serial.c | |||
@@ -691,6 +691,7 @@ static int __init msm_serial_probe(struct platform_device *pdev) | |||
691 | struct msm_port *msm_port; | 691 | struct msm_port *msm_port; |
692 | struct resource *resource; | 692 | struct resource *resource; |
693 | struct uart_port *port; | 693 | struct uart_port *port; |
694 | int irq; | ||
694 | 695 | ||
695 | if (unlikely(pdev->id < 0 || pdev->id >= UART_NR)) | 696 | if (unlikely(pdev->id < 0 || pdev->id >= UART_NR)) |
696 | return -ENXIO; | 697 | return -ENXIO; |
@@ -711,9 +712,10 @@ static int __init msm_serial_probe(struct platform_device *pdev) | |||
711 | return -ENXIO; | 712 | return -ENXIO; |
712 | port->mapbase = resource->start; | 713 | port->mapbase = resource->start; |
713 | 714 | ||
714 | port->irq = platform_get_irq(pdev, 0); | 715 | irq = platform_get_irq(pdev, 0); |
715 | if (unlikely(port->irq < 0)) | 716 | if (unlikely(irq < 0)) |
716 | return -ENXIO; | 717 | return -ENXIO; |
718 | port->irq = irq; | ||
717 | 719 | ||
718 | platform_set_drvdata(pdev, port); | 720 | platform_set_drvdata(pdev, port); |
719 | 721 | ||
diff --git a/drivers/serial/timbuart.c b/drivers/serial/timbuart.c index 34b31da01d09..7bf10264a6ac 100644 --- a/drivers/serial/timbuart.c +++ b/drivers/serial/timbuart.c | |||
@@ -421,7 +421,7 @@ static struct uart_driver timbuart_driver = { | |||
421 | 421 | ||
422 | static int timbuart_probe(struct platform_device *dev) | 422 | static int timbuart_probe(struct platform_device *dev) |
423 | { | 423 | { |
424 | int err; | 424 | int err, irq; |
425 | struct timbuart_port *uart; | 425 | struct timbuart_port *uart; |
426 | struct resource *iomem; | 426 | struct resource *iomem; |
427 | 427 | ||
@@ -453,11 +453,12 @@ static int timbuart_probe(struct platform_device *dev) | |||
453 | uart->port.mapbase = iomem->start; | 453 | uart->port.mapbase = iomem->start; |
454 | uart->port.membase = NULL; | 454 | uart->port.membase = NULL; |
455 | 455 | ||
456 | uart->port.irq = platform_get_irq(dev, 0); | 456 | irq = platform_get_irq(dev, 0); |
457 | if (uart->port.irq < 0) { | 457 | if (irq < 0) { |
458 | err = -EINVAL; | 458 | err = -EINVAL; |
459 | goto err_register; | 459 | goto err_register; |
460 | } | 460 | } |
461 | uart->port.irq = irq; | ||
461 | 462 | ||
462 | tasklet_init(&uart->tasklet, timbuart_tasklet, (unsigned long)uart); | 463 | tasklet_init(&uart->tasklet, timbuart_tasklet, (unsigned long)uart); |
463 | 464 | ||
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 1296a097f5c3..84f08e968e0b 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c | |||
@@ -789,6 +789,13 @@ static int keyspan_pda_fake_startup(struct usb_serial *serial) | |||
789 | return 1; | 789 | return 1; |
790 | } | 790 | } |
791 | 791 | ||
792 | #ifdef KEYSPAN | ||
793 | MODULE_FIRMWARE("keyspan_pda/keyspan_pda.fw"); | ||
794 | #endif | ||
795 | #ifdef XIRCOM | ||
796 | MODULE_FIRMWARE("keyspan_pda/xircom_pgs.fw"); | ||
797 | #endif | ||
798 | |||
792 | static int keyspan_pda_startup(struct usb_serial *serial) | 799 | static int keyspan_pda_startup(struct usb_serial *serial) |
793 | { | 800 | { |
794 | 801 | ||
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index c0e207c0c45a..9f688d243b86 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -2332,6 +2332,8 @@ | |||
2332 | #define PCI_VENDOR_ID_KORENIX 0x1982 | 2332 | #define PCI_VENDOR_ID_KORENIX 0x1982 |
2333 | #define PCI_DEVICE_ID_KORENIX_JETCARDF0 0x1600 | 2333 | #define PCI_DEVICE_ID_KORENIX_JETCARDF0 0x1600 |
2334 | #define PCI_DEVICE_ID_KORENIX_JETCARDF1 0x16ff | 2334 | #define PCI_DEVICE_ID_KORENIX_JETCARDF1 0x16ff |
2335 | #define PCI_DEVICE_ID_KORENIX_JETCARDF2 0x1700 | ||
2336 | #define PCI_DEVICE_ID_KORENIX_JETCARDF3 0x17ff | ||
2335 | 2337 | ||
2336 | #define PCI_VENDOR_ID_QMI 0x1a32 | 2338 | #define PCI_VENDOR_ID_QMI 0x1a32 |
2337 | 2339 | ||
@@ -2696,6 +2698,7 @@ | |||
2696 | #define PCI_DEVICE_ID_NETMOS_9835 0x9835 | 2698 | #define PCI_DEVICE_ID_NETMOS_9835 0x9835 |
2697 | #define PCI_DEVICE_ID_NETMOS_9845 0x9845 | 2699 | #define PCI_DEVICE_ID_NETMOS_9845 0x9845 |
2698 | #define PCI_DEVICE_ID_NETMOS_9855 0x9855 | 2700 | #define PCI_DEVICE_ID_NETMOS_9855 0x9855 |
2701 | #define PCI_DEVICE_ID_NETMOS_9865 0x9865 | ||
2699 | #define PCI_DEVICE_ID_NETMOS_9901 0x9901 | 2702 | #define PCI_DEVICE_ID_NETMOS_9901 0x9901 |
2700 | 2703 | ||
2701 | #define PCI_VENDOR_ID_3COM_2 0xa727 | 2704 | #define PCI_VENDOR_ID_3COM_2 0xa727 |
diff --git a/include/linux/tty.h b/include/linux/tty.h index 6abfcf5b5887..d96e5882f129 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
@@ -68,6 +68,16 @@ struct tty_buffer { | |||
68 | unsigned long data[0]; | 68 | unsigned long data[0]; |
69 | }; | 69 | }; |
70 | 70 | ||
71 | /* | ||
72 | * We default to dicing tty buffer allocations to this many characters | ||
73 | * in order to avoid multiple page allocations. We assume tty_buffer itself | ||
74 | * is under 256 bytes. See tty_buffer_find for the allocation logic this | ||
75 | * must match | ||
76 | */ | ||
77 | |||
78 | #define TTY_BUFFER_PAGE ((PAGE_SIZE - 256) / 2) | ||
79 | |||
80 | |||
71 | struct tty_bufhead { | 81 | struct tty_bufhead { |
72 | struct delayed_work work; | 82 | struct delayed_work work; |
73 | spinlock_t lock; | 83 | spinlock_t lock; |
diff --git a/include/linux/vt.h b/include/linux/vt.h index d5dd0bc408fd..778b7b2a47d4 100644 --- a/include/linux/vt.h +++ b/include/linux/vt.h | |||
@@ -27,7 +27,7 @@ struct vt_mode { | |||
27 | #define VT_SETMODE 0x5602 /* set mode of active vt */ | 27 | #define VT_SETMODE 0x5602 /* set mode of active vt */ |
28 | #define VT_AUTO 0x00 /* auto vt switching */ | 28 | #define VT_AUTO 0x00 /* auto vt switching */ |
29 | #define VT_PROCESS 0x01 /* process controls switching */ | 29 | #define VT_PROCESS 0x01 /* process controls switching */ |
30 | #define VT_ACKACQ 0x02 /* acknowledge switch */ | 30 | #define VT_PROCESS_AUTO 0x02 /* process is notified of switching */ |
31 | 31 | ||
32 | struct vt_stat { | 32 | struct vt_stat { |
33 | unsigned short v_active; /* active vt */ | 33 | unsigned short v_active; /* active vt */ |
@@ -38,6 +38,7 @@ struct vt_stat { | |||
38 | #define VT_SENDSIG 0x5604 /* signal to send to bitmask of vts */ | 38 | #define VT_SENDSIG 0x5604 /* signal to send to bitmask of vts */ |
39 | 39 | ||
40 | #define VT_RELDISP 0x5605 /* release display */ | 40 | #define VT_RELDISP 0x5605 /* release display */ |
41 | #define VT_ACKACQ 0x02 /* acknowledge switch */ | ||
41 | 42 | ||
42 | #define VT_ACTIVATE 0x5606 /* make vt active */ | 43 | #define VT_ACTIVATE 0x5606 /* make vt active */ |
43 | #define VT_WAITACTIVE 0x5607 /* wait for vt active */ | 44 | #define VT_WAITACTIVE 0x5607 /* wait for vt active */ |