diff options
Diffstat (limited to 'drivers')
95 files changed, 3185 insertions, 509 deletions
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 320f71803a2b..b3f01996318f 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c | |||
@@ -355,26 +355,29 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty) | |||
355 | * flags pointer to flags for data | 355 | * flags pointer to flags for data |
356 | * count count of received data in bytes | 356 | * count count of received data in bytes |
357 | * | 357 | * |
358 | * Return Value: None | 358 | * Return Value: Number of bytes received |
359 | */ | 359 | */ |
360 | static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count) | 360 | static unsigned int hci_uart_tty_receive(struct tty_struct *tty, |
361 | const u8 *data, char *flags, int count) | ||
361 | { | 362 | { |
362 | int ret; | ||
363 | struct hci_uart *hu = (void *)tty->disc_data; | 363 | struct hci_uart *hu = (void *)tty->disc_data; |
364 | int received; | ||
364 | 365 | ||
365 | if (!hu || tty != hu->tty) | 366 | if (!hu || tty != hu->tty) |
366 | return; | 367 | return -ENODEV; |
367 | 368 | ||
368 | if (!test_bit(HCI_UART_PROTO_SET, &hu->flags)) | 369 | if (!test_bit(HCI_UART_PROTO_SET, &hu->flags)) |
369 | return; | 370 | return -EINVAL; |
370 | 371 | ||
371 | spin_lock(&hu->rx_lock); | 372 | spin_lock(&hu->rx_lock); |
372 | ret = hu->proto->recv(hu, (void *) data, count); | 373 | received = hu->proto->recv(hu, (void *) data, count); |
373 | if (ret > 0) | 374 | if (received > 0) |
374 | hu->hdev->stat.byte_rx += count; | 375 | hu->hdev->stat.byte_rx += received; |
375 | spin_unlock(&hu->rx_lock); | 376 | spin_unlock(&hu->rx_lock); |
376 | 377 | ||
377 | tty_unthrottle(tty); | 378 | tty_unthrottle(tty); |
379 | |||
380 | return received; | ||
378 | } | 381 | } |
379 | 382 | ||
380 | static int hci_uart_register_dev(struct hci_uart *hu) | 383 | static int hci_uart_register_dev(struct hci_uart *hu) |
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index 8755f5f3ad37..f3698967edf6 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c | |||
@@ -120,17 +120,21 @@ static void serport_ldisc_close(struct tty_struct *tty) | |||
120 | * 'interrupt' routine. | 120 | * 'interrupt' routine. |
121 | */ | 121 | */ |
122 | 122 | ||
123 | static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) | 123 | static unsigned int serport_ldisc_receive(struct tty_struct *tty, |
124 | const unsigned char *cp, char *fp, int count) | ||
124 | { | 125 | { |
125 | struct serport *serport = (struct serport*) tty->disc_data; | 126 | struct serport *serport = (struct serport*) tty->disc_data; |
126 | unsigned long flags; | 127 | unsigned long flags; |
127 | unsigned int ch_flags; | 128 | unsigned int ch_flags; |
129 | int ret = 0; | ||
128 | int i; | 130 | int i; |
129 | 131 | ||
130 | spin_lock_irqsave(&serport->lock, flags); | 132 | spin_lock_irqsave(&serport->lock, flags); |
131 | 133 | ||
132 | if (!test_bit(SERPORT_ACTIVE, &serport->flags)) | 134 | if (!test_bit(SERPORT_ACTIVE, &serport->flags)) { |
135 | ret = -EINVAL; | ||
133 | goto out; | 136 | goto out; |
137 | } | ||
134 | 138 | ||
135 | for (i = 0; i < count; i++) { | 139 | for (i = 0; i < count; i++) { |
136 | switch (fp[i]) { | 140 | switch (fp[i]) { |
@@ -152,6 +156,8 @@ static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *c | |||
152 | 156 | ||
153 | out: | 157 | out: |
154 | spin_unlock_irqrestore(&serport->lock, flags); | 158 | spin_unlock_irqrestore(&serport->lock, flags); |
159 | |||
160 | return ret == 0 ? count : ret; | ||
155 | } | 161 | } |
156 | 162 | ||
157 | /* | 163 | /* |
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c index 86a5c4f7775e..1d44d470897c 100644 --- a/drivers/isdn/gigaset/ser-gigaset.c +++ b/drivers/isdn/gigaset/ser-gigaset.c | |||
@@ -674,7 +674,7 @@ gigaset_tty_ioctl(struct tty_struct *tty, struct file *file, | |||
674 | * cflags buffer containing error flags for received characters (ignored) | 674 | * cflags buffer containing error flags for received characters (ignored) |
675 | * count number of received characters | 675 | * count number of received characters |
676 | */ | 676 | */ |
677 | static void | 677 | static unsigned int |
678 | gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf, | 678 | gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf, |
679 | char *cflags, int count) | 679 | char *cflags, int count) |
680 | { | 680 | { |
@@ -683,12 +683,12 @@ gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf, | |||
683 | struct inbuf_t *inbuf; | 683 | struct inbuf_t *inbuf; |
684 | 684 | ||
685 | if (!cs) | 685 | if (!cs) |
686 | return; | 686 | return -ENODEV; |
687 | inbuf = cs->inbuf; | 687 | inbuf = cs->inbuf; |
688 | if (!inbuf) { | 688 | if (!inbuf) { |
689 | dev_err(cs->dev, "%s: no inbuf\n", __func__); | 689 | dev_err(cs->dev, "%s: no inbuf\n", __func__); |
690 | cs_put(cs); | 690 | cs_put(cs); |
691 | return; | 691 | return -EINVAL; |
692 | } | 692 | } |
693 | 693 | ||
694 | tail = inbuf->tail; | 694 | tail = inbuf->tail; |
@@ -725,6 +725,8 @@ gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf, | |||
725 | gig_dbg(DEBUG_INTR, "%s-->BH", __func__); | 725 | gig_dbg(DEBUG_INTR, "%s-->BH", __func__); |
726 | gigaset_schedule_event(cs); | 726 | gigaset_schedule_event(cs); |
727 | cs_put(cs); | 727 | cs_put(cs); |
728 | |||
729 | return count; | ||
728 | } | 730 | } |
729 | 731 | ||
730 | /* | 732 | /* |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index d80dcdee88f3..4e349cd98bcf 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -144,6 +144,19 @@ config PHANTOM | |||
144 | If you choose to build module, its name will be phantom. If unsure, | 144 | If you choose to build module, its name will be phantom. If unsure, |
145 | say N here. | 145 | say N here. |
146 | 146 | ||
147 | config INTEL_MID_PTI | ||
148 | tristate "Parallel Trace Interface for MIPI P1149.7 cJTAG standard" | ||
149 | default n | ||
150 | help | ||
151 | The PTI (Parallel Trace Interface) driver directs | ||
152 | trace data routed from various parts in the system out | ||
153 | through an Intel Penwell PTI port and out of the mobile | ||
154 | device for analysis with a debugging tool (Lauterbach or Fido). | ||
155 | |||
156 | You should select this driver if the target kernel is meant for | ||
157 | an Intel Atom (non-netbook) mobile device containing a MIPI | ||
158 | P1149.7 standard implementation. | ||
159 | |||
147 | config SGI_IOC4 | 160 | config SGI_IOC4 |
148 | tristate "SGI IOC4 Base IO support" | 161 | tristate "SGI IOC4 Base IO support" |
149 | depends on PCI | 162 | depends on PCI |
@@ -459,7 +472,7 @@ config BMP085 | |||
459 | module will be called bmp085. | 472 | module will be called bmp085. |
460 | 473 | ||
461 | config PCH_PHUB | 474 | config PCH_PHUB |
462 | tristate "PCH Packet Hub of Intel Topcliff / OKI SEMICONDUCTOR ML7213" | 475 | tristate "Intel EG20T PCH / OKI SEMICONDUCTOR IOH(ML7213/ML7223) PHUB" |
463 | depends on PCI | 476 | depends on PCI |
464 | help | 477 | help |
465 | This driver is for PCH(Platform controller Hub) PHUB(Packet Hub) of | 478 | This driver is for PCH(Platform controller Hub) PHUB(Packet Hub) of |
@@ -467,10 +480,12 @@ config PCH_PHUB | |||
467 | processor. The Topcliff has MAC address and Option ROM data in SROM. | 480 | processor. The Topcliff has MAC address and Option ROM data in SROM. |
468 | This driver can access MAC address and Option ROM data in SROM. | 481 | This driver can access MAC address and Option ROM data in SROM. |
469 | 482 | ||
470 | This driver also can be used for OKI SEMICONDUCTOR's ML7213 which is | 483 | This driver also can be used for OKI SEMICONDUCTOR IOH(Input/ |
471 | for IVI(In-Vehicle Infotainment) use. | 484 | Output Hub), ML7213 and ML7223. |
472 | ML7213 is companion chip for Intel Atom E6xx series. | 485 | ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is |
473 | ML7213 is completely compatible for Intel EG20T PCH. | 486 | for MP(Media Phone) use. |
487 | ML7213/ML7223 is companion chip for Intel Atom E6xx series. | ||
488 | ML7213/ML7223 is completely compatible for Intel EG20T PCH. | ||
474 | 489 | ||
475 | To compile this driver as a module, choose M here: the module will | 490 | To compile this driver as a module, choose M here: the module will |
476 | be called pch_phub. | 491 | be called pch_phub. |
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 848e8464faab..5f03172cc0b5 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile | |||
@@ -6,6 +6,7 @@ obj-$(CONFIG_IBM_ASM) += ibmasm/ | |||
6 | obj-$(CONFIG_AD525X_DPOT) += ad525x_dpot.o | 6 | obj-$(CONFIG_AD525X_DPOT) += ad525x_dpot.o |
7 | obj-$(CONFIG_AD525X_DPOT_I2C) += ad525x_dpot-i2c.o | 7 | obj-$(CONFIG_AD525X_DPOT_I2C) += ad525x_dpot-i2c.o |
8 | obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_dpot-spi.o | 8 | obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_dpot-spi.o |
9 | 0bj-$(CONFIG_INTEL_MID_PTI) += pti.o | ||
9 | obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o | 10 | obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o |
10 | obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o | 11 | obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o |
11 | obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o | 12 | obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o |
diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c index a19cb710a246..5fe79df44838 100644 --- a/drivers/misc/pch_phub.c +++ b/drivers/misc/pch_phub.c | |||
@@ -34,12 +34,18 @@ | |||
34 | #define PHUB_TIMEOUT 0x05 /* Time out value for Status Register */ | 34 | #define PHUB_TIMEOUT 0x05 /* Time out value for Status Register */ |
35 | #define PCH_PHUB_ROM_WRITE_ENABLE 0x01 /* Enabling for writing ROM */ | 35 | #define PCH_PHUB_ROM_WRITE_ENABLE 0x01 /* Enabling for writing ROM */ |
36 | #define PCH_PHUB_ROM_WRITE_DISABLE 0x00 /* Disabling for writing ROM */ | 36 | #define PCH_PHUB_ROM_WRITE_DISABLE 0x00 /* Disabling for writing ROM */ |
37 | #define PCH_PHUB_MAC_START_ADDR 0x20C /* MAC data area start address offset */ | 37 | #define PCH_PHUB_MAC_START_ADDR_EG20T 0x14 /* MAC data area start address |
38 | #define PCH_PHUB_ROM_START_ADDR_EG20T 0x14 /* ROM data area start address offset | 38 | offset */ |
39 | #define PCH_PHUB_MAC_START_ADDR_ML7223 0x20C /* MAC data area start address | ||
40 | offset */ | ||
41 | #define PCH_PHUB_ROM_START_ADDR_EG20T 0x80 /* ROM data area start address offset | ||
39 | (Intel EG20T PCH)*/ | 42 | (Intel EG20T PCH)*/ |
40 | #define PCH_PHUB_ROM_START_ADDR_ML7213 0x400 /* ROM data area start address | 43 | #define PCH_PHUB_ROM_START_ADDR_ML7213 0x400 /* ROM data area start address |
41 | offset(OKI SEMICONDUCTOR ML7213) | 44 | offset(OKI SEMICONDUCTOR ML7213) |
42 | */ | 45 | */ |
46 | #define PCH_PHUB_ROM_START_ADDR_ML7223 0x400 /* ROM data area start address | ||
47 | offset(OKI SEMICONDUCTOR ML7223) | ||
48 | */ | ||
43 | 49 | ||
44 | /* MAX number of INT_REDUCE_CONTROL registers */ | 50 | /* MAX number of INT_REDUCE_CONTROL registers */ |
45 | #define MAX_NUM_INT_REDUCE_CONTROL_REG 128 | 51 | #define MAX_NUM_INT_REDUCE_CONTROL_REG 128 |
@@ -63,6 +69,10 @@ | |||
63 | #define PCI_VENDOR_ID_ROHM 0x10db | 69 | #define PCI_VENDOR_ID_ROHM 0x10db |
64 | #define PCI_DEVICE_ID_ROHM_ML7213_PHUB 0x801A | 70 | #define PCI_DEVICE_ID_ROHM_ML7213_PHUB 0x801A |
65 | 71 | ||
72 | /* Macros for ML7223 */ | ||
73 | #define PCI_DEVICE_ID_ROHM_ML7223_mPHUB 0x8012 /* for Bus-m */ | ||
74 | #define PCI_DEVICE_ID_ROHM_ML7223_nPHUB 0x8002 /* for Bus-n */ | ||
75 | |||
66 | /* SROM ACCESS Macro */ | 76 | /* SROM ACCESS Macro */ |
67 | #define PCH_WORD_ADDR_MASK (~((1 << 2) - 1)) | 77 | #define PCH_WORD_ADDR_MASK (~((1 << 2) - 1)) |
68 | 78 | ||
@@ -100,6 +110,9 @@ | |||
100 | * @clkcfg_reg: CLK CFG register val | 110 | * @clkcfg_reg: CLK CFG register val |
101 | * @pch_phub_base_address: Register base address | 111 | * @pch_phub_base_address: Register base address |
102 | * @pch_phub_extrom_base_address: external rom base address | 112 | * @pch_phub_extrom_base_address: external rom base address |
113 | * @pch_mac_start_address: MAC address area start address | ||
114 | * @pch_opt_rom_start_address: Option ROM start address | ||
115 | * @ioh_type: Save IOH type | ||
103 | */ | 116 | */ |
104 | struct pch_phub_reg { | 117 | struct pch_phub_reg { |
105 | u32 phub_id_reg; | 118 | u32 phub_id_reg; |
@@ -117,6 +130,9 @@ struct pch_phub_reg { | |||
117 | u32 clkcfg_reg; | 130 | u32 clkcfg_reg; |
118 | void __iomem *pch_phub_base_address; | 131 | void __iomem *pch_phub_base_address; |
119 | void __iomem *pch_phub_extrom_base_address; | 132 | void __iomem *pch_phub_extrom_base_address; |
133 | u32 pch_mac_start_address; | ||
134 | u32 pch_opt_rom_start_address; | ||
135 | int ioh_type; | ||
120 | }; | 136 | }; |
121 | 137 | ||
122 | /* SROM SPEC for MAC address assignment offset */ | 138 | /* SROM SPEC for MAC address assignment offset */ |
@@ -319,7 +335,7 @@ static void pch_phub_read_serial_rom_val(struct pch_phub_reg *chip, | |||
319 | { | 335 | { |
320 | unsigned int mem_addr; | 336 | unsigned int mem_addr; |
321 | 337 | ||
322 | mem_addr = PCH_PHUB_ROM_START_ADDR_EG20T + | 338 | mem_addr = chip->pch_mac_start_address + |
323 | pch_phub_mac_offset[offset_address]; | 339 | pch_phub_mac_offset[offset_address]; |
324 | 340 | ||
325 | pch_phub_read_serial_rom(chip, mem_addr, data); | 341 | pch_phub_read_serial_rom(chip, mem_addr, data); |
@@ -336,7 +352,7 @@ static int pch_phub_write_serial_rom_val(struct pch_phub_reg *chip, | |||
336 | int retval; | 352 | int retval; |
337 | unsigned int mem_addr; | 353 | unsigned int mem_addr; |
338 | 354 | ||
339 | mem_addr = PCH_PHUB_ROM_START_ADDR_EG20T + | 355 | mem_addr = chip->pch_mac_start_address + |
340 | pch_phub_mac_offset[offset_address]; | 356 | pch_phub_mac_offset[offset_address]; |
341 | 357 | ||
342 | retval = pch_phub_write_serial_rom(chip, mem_addr, data); | 358 | retval = pch_phub_write_serial_rom(chip, mem_addr, data); |
@@ -384,6 +400,48 @@ static int pch_phub_gbe_serial_rom_conf(struct pch_phub_reg *chip) | |||
384 | return retval; | 400 | return retval; |
385 | } | 401 | } |
386 | 402 | ||
403 | /* pch_phub_gbe_serial_rom_conf_mp - makes SerialROM header format configuration | ||
404 | * for Gigabit Ethernet MAC address | ||
405 | */ | ||
406 | static int pch_phub_gbe_serial_rom_conf_mp(struct pch_phub_reg *chip) | ||
407 | { | ||
408 | int retval; | ||
409 | u32 offset_addr; | ||
410 | |||
411 | offset_addr = 0x200; | ||
412 | retval = pch_phub_write_serial_rom(chip, 0x03 + offset_addr, 0xbc); | ||
413 | retval |= pch_phub_write_serial_rom(chip, 0x02 + offset_addr, 0x00); | ||
414 | retval |= pch_phub_write_serial_rom(chip, 0x01 + offset_addr, 0x40); | ||
415 | retval |= pch_phub_write_serial_rom(chip, 0x00 + offset_addr, 0x02); | ||
416 | |||
417 | retval |= pch_phub_write_serial_rom(chip, 0x07 + offset_addr, 0x00); | ||
418 | retval |= pch_phub_write_serial_rom(chip, 0x06 + offset_addr, 0x00); | ||
419 | retval |= pch_phub_write_serial_rom(chip, 0x05 + offset_addr, 0x00); | ||
420 | retval |= pch_phub_write_serial_rom(chip, 0x04 + offset_addr, 0x80); | ||
421 | |||
422 | retval |= pch_phub_write_serial_rom(chip, 0x0b + offset_addr, 0xbc); | ||
423 | retval |= pch_phub_write_serial_rom(chip, 0x0a + offset_addr, 0x00); | ||
424 | retval |= pch_phub_write_serial_rom(chip, 0x09 + offset_addr, 0x40); | ||
425 | retval |= pch_phub_write_serial_rom(chip, 0x08 + offset_addr, 0x18); | ||
426 | |||
427 | retval |= pch_phub_write_serial_rom(chip, 0x13 + offset_addr, 0xbc); | ||
428 | retval |= pch_phub_write_serial_rom(chip, 0x12 + offset_addr, 0x00); | ||
429 | retval |= pch_phub_write_serial_rom(chip, 0x11 + offset_addr, 0x40); | ||
430 | retval |= pch_phub_write_serial_rom(chip, 0x10 + offset_addr, 0x19); | ||
431 | |||
432 | retval |= pch_phub_write_serial_rom(chip, 0x1b + offset_addr, 0xbc); | ||
433 | retval |= pch_phub_write_serial_rom(chip, 0x1a + offset_addr, 0x00); | ||
434 | retval |= pch_phub_write_serial_rom(chip, 0x19 + offset_addr, 0x40); | ||
435 | retval |= pch_phub_write_serial_rom(chip, 0x18 + offset_addr, 0x3a); | ||
436 | |||
437 | retval |= pch_phub_write_serial_rom(chip, 0x1f + offset_addr, 0x01); | ||
438 | retval |= pch_phub_write_serial_rom(chip, 0x1e + offset_addr, 0x00); | ||
439 | retval |= pch_phub_write_serial_rom(chip, 0x1d + offset_addr, 0x00); | ||
440 | retval |= pch_phub_write_serial_rom(chip, 0x1c + offset_addr, 0x00); | ||
441 | |||
442 | return retval; | ||
443 | } | ||
444 | |||
387 | /** | 445 | /** |
388 | * pch_phub_read_gbe_mac_addr() - Read Gigabit Ethernet MAC address | 446 | * pch_phub_read_gbe_mac_addr() - Read Gigabit Ethernet MAC address |
389 | * @offset_address: Gigabit Ethernet MAC address offset value. | 447 | * @offset_address: Gigabit Ethernet MAC address offset value. |
@@ -406,7 +464,10 @@ static int pch_phub_write_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data) | |||
406 | int retval; | 464 | int retval; |
407 | int i; | 465 | int i; |
408 | 466 | ||
409 | retval = pch_phub_gbe_serial_rom_conf(chip); | 467 | if (chip->ioh_type == 1) /* EG20T */ |
468 | retval = pch_phub_gbe_serial_rom_conf(chip); | ||
469 | else /* ML7223 */ | ||
470 | retval = pch_phub_gbe_serial_rom_conf_mp(chip); | ||
410 | if (retval) | 471 | if (retval) |
411 | return retval; | 472 | return retval; |
412 | 473 | ||
@@ -441,12 +502,16 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj, | |||
441 | } | 502 | } |
442 | 503 | ||
443 | /* Get Rom signature */ | 504 | /* Get Rom signature */ |
444 | pch_phub_read_serial_rom(chip, 0x80, (unsigned char *)&rom_signature); | 505 | pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address, |
506 | (unsigned char *)&rom_signature); | ||
445 | rom_signature &= 0xff; | 507 | rom_signature &= 0xff; |
446 | pch_phub_read_serial_rom(chip, 0x81, (unsigned char *)&tmp); | 508 | pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address + 1, |
509 | (unsigned char *)&tmp); | ||
447 | rom_signature |= (tmp & 0xff) << 8; | 510 | rom_signature |= (tmp & 0xff) << 8; |
448 | if (rom_signature == 0xAA55) { | 511 | if (rom_signature == 0xAA55) { |
449 | pch_phub_read_serial_rom(chip, 0x82, &rom_length); | 512 | pch_phub_read_serial_rom(chip, |
513 | chip->pch_opt_rom_start_address + 2, | ||
514 | &rom_length); | ||
450 | orom_size = rom_length * 512; | 515 | orom_size = rom_length * 512; |
451 | if (orom_size < off) { | 516 | if (orom_size < off) { |
452 | addr_offset = 0; | 517 | addr_offset = 0; |
@@ -458,8 +523,9 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj, | |||
458 | } | 523 | } |
459 | 524 | ||
460 | for (addr_offset = 0; addr_offset < count; addr_offset++) { | 525 | for (addr_offset = 0; addr_offset < count; addr_offset++) { |
461 | pch_phub_read_serial_rom(chip, 0x80 + addr_offset + off, | 526 | pch_phub_read_serial_rom(chip, |
462 | &buf[addr_offset]); | 527 | chip->pch_opt_rom_start_address + addr_offset + off, |
528 | &buf[addr_offset]); | ||
463 | } | 529 | } |
464 | } else { | 530 | } else { |
465 | err = -ENODATA; | 531 | err = -ENODATA; |
@@ -502,8 +568,9 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj, | |||
502 | if (PCH_PHUB_OROM_SIZE < off + addr_offset) | 568 | if (PCH_PHUB_OROM_SIZE < off + addr_offset) |
503 | goto return_ok; | 569 | goto return_ok; |
504 | 570 | ||
505 | ret = pch_phub_write_serial_rom(chip, 0x80 + addr_offset + off, | 571 | ret = pch_phub_write_serial_rom(chip, |
506 | buf[addr_offset]); | 572 | chip->pch_opt_rom_start_address + addr_offset + off, |
573 | buf[addr_offset]); | ||
507 | if (ret) { | 574 | if (ret) { |
508 | err = ret; | 575 | err = ret; |
509 | goto return_err; | 576 | goto return_err; |
@@ -603,19 +670,22 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev, | |||
603 | dev_dbg(&pdev->dev, "%s : pci_iomap SUCCESS and value " | 670 | dev_dbg(&pdev->dev, "%s : pci_iomap SUCCESS and value " |
604 | "in pch_phub_base_address variable is %p\n", __func__, | 671 | "in pch_phub_base_address variable is %p\n", __func__, |
605 | chip->pch_phub_base_address); | 672 | chip->pch_phub_base_address); |
606 | chip->pch_phub_extrom_base_address = pci_map_rom(pdev, &rom_size); | ||
607 | 673 | ||
608 | if (chip->pch_phub_extrom_base_address == 0) { | 674 | if (id->driver_data != 3) { |
609 | dev_err(&pdev->dev, "%s : pci_map_rom FAILED", __func__); | 675 | chip->pch_phub_extrom_base_address =\ |
610 | ret = -ENOMEM; | 676 | pci_map_rom(pdev, &rom_size); |
611 | goto err_pci_map; | 677 | if (chip->pch_phub_extrom_base_address == 0) { |
678 | dev_err(&pdev->dev, "%s: pci_map_rom FAILED", __func__); | ||
679 | ret = -ENOMEM; | ||
680 | goto err_pci_map; | ||
681 | } | ||
682 | dev_dbg(&pdev->dev, "%s : " | ||
683 | "pci_map_rom SUCCESS and value in " | ||
684 | "pch_phub_extrom_base_address variable is %p\n", | ||
685 | __func__, chip->pch_phub_extrom_base_address); | ||
612 | } | 686 | } |
613 | dev_dbg(&pdev->dev, "%s : " | ||
614 | "pci_map_rom SUCCESS and value in " | ||
615 | "pch_phub_extrom_base_address variable is %p\n", __func__, | ||
616 | chip->pch_phub_extrom_base_address); | ||
617 | 687 | ||
618 | if (id->driver_data == 1) { | 688 | if (id->driver_data == 1) { /* EG20T PCH */ |
619 | retval = sysfs_create_file(&pdev->dev.kobj, | 689 | retval = sysfs_create_file(&pdev->dev.kobj, |
620 | &dev_attr_pch_mac.attr); | 690 | &dev_attr_pch_mac.attr); |
621 | if (retval) | 691 | if (retval) |
@@ -642,7 +712,9 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev, | |||
642 | iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14); | 712 | iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14); |
643 | /* set the interrupt delay value */ | 713 | /* set the interrupt delay value */ |
644 | iowrite32(0x25, chip->pch_phub_base_address + 0x44); | 714 | iowrite32(0x25, chip->pch_phub_base_address + 0x44); |
645 | } else if (id->driver_data == 2) { | 715 | chip->pch_opt_rom_start_address = PCH_PHUB_ROM_START_ADDR_EG20T; |
716 | chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_EG20T; | ||
717 | } else if (id->driver_data == 2) { /* ML7213 IOH */ | ||
646 | retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); | 718 | retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); |
647 | if (retval) | 719 | if (retval) |
648 | goto err_sysfs_create; | 720 | goto err_sysfs_create; |
@@ -653,7 +725,38 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev, | |||
653 | * Device8(USB OHCI #0/ USB EHCI #0):a | 725 | * Device8(USB OHCI #0/ USB EHCI #0):a |
654 | */ | 726 | */ |
655 | iowrite32(0x000affa0, chip->pch_phub_base_address + 0x14); | 727 | iowrite32(0x000affa0, chip->pch_phub_base_address + 0x14); |
728 | chip->pch_opt_rom_start_address =\ | ||
729 | PCH_PHUB_ROM_START_ADDR_ML7213; | ||
730 | } else if (id->driver_data == 3) { /* ML7223 IOH Bus-m*/ | ||
731 | /* set the prefech value | ||
732 | * Device8(GbE) | ||
733 | */ | ||
734 | iowrite32(0x000a0000, chip->pch_phub_base_address + 0x14); | ||
735 | chip->pch_opt_rom_start_address =\ | ||
736 | PCH_PHUB_ROM_START_ADDR_ML7223; | ||
737 | chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223; | ||
738 | } else if (id->driver_data == 4) { /* ML7223 IOH Bus-n*/ | ||
739 | retval = sysfs_create_file(&pdev->dev.kobj, | ||
740 | &dev_attr_pch_mac.attr); | ||
741 | if (retval) | ||
742 | goto err_sysfs_create; | ||
743 | retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); | ||
744 | if (retval) | ||
745 | goto exit_bin_attr; | ||
746 | /* set the prefech value | ||
747 | * Device2(USB OHCI #0,1,2,3/ USB EHCI #0):a | ||
748 | * Device4(SDIO #0,1):f | ||
749 | * Device6(SATA 2):f | ||
750 | */ | ||
751 | iowrite32(0x0000ffa0, chip->pch_phub_base_address + 0x14); | ||
752 | /* set the interrupt delay value */ | ||
753 | iowrite32(0x25, chip->pch_phub_base_address + 0x140); | ||
754 | chip->pch_opt_rom_start_address =\ | ||
755 | PCH_PHUB_ROM_START_ADDR_ML7223; | ||
756 | chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223; | ||
656 | } | 757 | } |
758 | |||
759 | chip->ioh_type = id->driver_data; | ||
657 | pci_set_drvdata(pdev, chip); | 760 | pci_set_drvdata(pdev, chip); |
658 | 761 | ||
659 | return 0; | 762 | return 0; |
@@ -733,6 +836,8 @@ static int pch_phub_resume(struct pci_dev *pdev) | |||
733 | static struct pci_device_id pch_phub_pcidev_id[] = { | 836 | static struct pci_device_id pch_phub_pcidev_id[] = { |
734 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH1_PHUB), 1, }, | 837 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH1_PHUB), 1, }, |
735 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7213_PHUB), 2, }, | 838 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7213_PHUB), 2, }, |
839 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_mPHUB), 3, }, | ||
840 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_nPHUB), 4, }, | ||
736 | { } | 841 | { } |
737 | }; | 842 | }; |
738 | MODULE_DEVICE_TABLE(pci, pch_phub_pcidev_id); | 843 | MODULE_DEVICE_TABLE(pci, pch_phub_pcidev_id); |
@@ -759,5 +864,5 @@ static void __exit pch_phub_pci_exit(void) | |||
759 | module_init(pch_phub_pci_init); | 864 | module_init(pch_phub_pci_init); |
760 | module_exit(pch_phub_pci_exit); | 865 | module_exit(pch_phub_pci_exit); |
761 | 866 | ||
762 | MODULE_DESCRIPTION("PCH Packet Hub PCI Driver"); | 867 | MODULE_DESCRIPTION("Intel EG20T PCH/OKI SEMICONDUCTOR IOH(ML7213/ML7223) PHUB"); |
763 | MODULE_LICENSE("GPL"); | 868 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c new file mode 100644 index 000000000000..bb6f9255c17c --- /dev/null +++ b/drivers/misc/pti.c | |||
@@ -0,0 +1,980 @@ | |||
1 | /* | ||
2 | * pti.c - PTI driver for cJTAG data extration | ||
3 | * | ||
4 | * Copyright (C) Intel 2010 | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
16 | * | ||
17 | * The PTI (Parallel Trace Interface) driver directs trace data routed from | ||
18 | * various parts in the system out through the Intel Penwell PTI port and | ||
19 | * out of the mobile device for analysis with a debugging tool | ||
20 | * (Lauterbach, Fido). This is part of a solution for the MIPI P1149.7, | ||
21 | * compact JTAG, standard. | ||
22 | */ | ||
23 | |||
24 | #include <linux/init.h> | ||
25 | #include <linux/sched.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/console.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/module.h> | ||
30 | #include <linux/tty.h> | ||
31 | #include <linux/tty_driver.h> | ||
32 | #include <linux/pci.h> | ||
33 | #include <linux/mutex.h> | ||
34 | #include <linux/miscdevice.h> | ||
35 | #include <linux/pti.h> | ||
36 | |||
37 | #define DRIVERNAME "pti" | ||
38 | #define PCINAME "pciPTI" | ||
39 | #define TTYNAME "ttyPTI" | ||
40 | #define CHARNAME "pti" | ||
41 | #define PTITTY_MINOR_START 0 | ||
42 | #define PTITTY_MINOR_NUM 2 | ||
43 | #define MAX_APP_IDS 16 /* 128 channel ids / u8 bit size */ | ||
44 | #define MAX_OS_IDS 16 /* 128 channel ids / u8 bit size */ | ||
45 | #define MAX_MODEM_IDS 16 /* 128 channel ids / u8 bit size */ | ||
46 | #define MODEM_BASE_ID 71 /* modem master ID address */ | ||
47 | #define CONTROL_ID 72 /* control master ID address */ | ||
48 | #define CONSOLE_ID 73 /* console master ID address */ | ||
49 | #define OS_BASE_ID 74 /* base OS master ID address */ | ||
50 | #define APP_BASE_ID 80 /* base App master ID address */ | ||
51 | #define CONTROL_FRAME_LEN 32 /* PTI control frame maximum size */ | ||
52 | #define USER_COPY_SIZE 8192 /* 8Kb buffer for user space copy */ | ||
53 | #define APERTURE_14 0x3800000 /* offset to first OS write addr */ | ||
54 | #define APERTURE_LEN 0x400000 /* address length */ | ||
55 | |||
56 | struct pti_tty { | ||
57 | struct pti_masterchannel *mc; | ||
58 | }; | ||
59 | |||
60 | struct pti_dev { | ||
61 | struct tty_port port; | ||
62 | unsigned long pti_addr; | ||
63 | unsigned long aperture_base; | ||
64 | void __iomem *pti_ioaddr; | ||
65 | u8 ia_app[MAX_APP_IDS]; | ||
66 | u8 ia_os[MAX_OS_IDS]; | ||
67 | u8 ia_modem[MAX_MODEM_IDS]; | ||
68 | }; | ||
69 | |||
70 | /* | ||
71 | * This protects access to ia_app, ia_os, and ia_modem, | ||
72 | * which keeps track of channels allocated in | ||
73 | * an aperture write id. | ||
74 | */ | ||
75 | static DEFINE_MUTEX(alloclock); | ||
76 | |||
77 | static struct pci_device_id pci_ids[] __devinitconst = { | ||
78 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x82B)}, | ||
79 | {0} | ||
80 | }; | ||
81 | |||
82 | static struct tty_driver *pti_tty_driver; | ||
83 | static struct pti_dev *drv_data; | ||
84 | |||
85 | static unsigned int pti_console_channel; | ||
86 | static unsigned int pti_control_channel; | ||
87 | |||
88 | /** | ||
89 | * pti_write_to_aperture()- The private write function to PTI HW. | ||
90 | * | ||
91 | * @mc: The 'aperture'. It's part of a write address that holds | ||
92 | * a master and channel ID. | ||
93 | * @buf: Data being written to the HW that will ultimately be seen | ||
94 | * in a debugging tool (Fido, Lauterbach). | ||
95 | * @len: Size of buffer. | ||
96 | * | ||
97 | * Since each aperture is specified by a unique | ||
98 | * master/channel ID, no two processes will be writing | ||
99 | * to the same aperture at the same time so no lock is required. The | ||
100 | * PTI-Output agent will send these out in the order that they arrived, and | ||
101 | * thus, it will intermix these messages. The debug tool can then later | ||
102 | * regroup the appropriate message segments together reconstituting each | ||
103 | * message. | ||
104 | */ | ||
105 | static void pti_write_to_aperture(struct pti_masterchannel *mc, | ||
106 | u8 *buf, | ||
107 | int len) | ||
108 | { | ||
109 | int dwordcnt; | ||
110 | int final; | ||
111 | int i; | ||
112 | u32 ptiword; | ||
113 | u32 __iomem *aperture; | ||
114 | u8 *p = buf; | ||
115 | |||
116 | /* | ||
117 | * calculate the aperture offset from the base using the master and | ||
118 | * channel id's. | ||
119 | */ | ||
120 | aperture = drv_data->pti_ioaddr + (mc->master << 15) | ||
121 | + (mc->channel << 8); | ||
122 | |||
123 | dwordcnt = len >> 2; | ||
124 | final = len - (dwordcnt << 2); /* final = trailing bytes */ | ||
125 | if (final == 0 && dwordcnt != 0) { /* always need a final dword */ | ||
126 | final += 4; | ||
127 | dwordcnt--; | ||
128 | } | ||
129 | |||
130 | for (i = 0; i < dwordcnt; i++) { | ||
131 | ptiword = be32_to_cpu(*(u32 *)p); | ||
132 | p += 4; | ||
133 | iowrite32(ptiword, aperture); | ||
134 | } | ||
135 | |||
136 | aperture += PTI_LASTDWORD_DTS; /* adding DTS signals that is EOM */ | ||
137 | |||
138 | ptiword = 0; | ||
139 | for (i = 0; i < final; i++) | ||
140 | ptiword |= *p++ << (24-(8*i)); | ||
141 | |||
142 | iowrite32(ptiword, aperture); | ||
143 | return; | ||
144 | } | ||
145 | |||
146 | /** | ||
147 | * pti_control_frame_built_and_sent()- control frame build and send function. | ||
148 | * | ||
149 | * @mc: The master / channel structure on which the function | ||
150 | * built a control frame. | ||
151 | * | ||
152 | * To be able to post process the PTI contents on host side, a control frame | ||
153 | * is added before sending any PTI content. So the host side knows on | ||
154 | * each PTI frame the name of the thread using a dedicated master / channel. | ||
155 | * The thread name is retrieved from the 'current' global variable. | ||
156 | * This function builds this frame and sends it to a master ID CONTROL_ID. | ||
157 | * The overhead is only 32 bytes since the driver only writes to HW | ||
158 | * in 32 byte chunks. | ||
159 | */ | ||
160 | |||
161 | static void pti_control_frame_built_and_sent(struct pti_masterchannel *mc) | ||
162 | { | ||
163 | struct pti_masterchannel mccontrol = {.master = CONTROL_ID, | ||
164 | .channel = 0}; | ||
165 | const char *control_format = "%3d %3d %s"; | ||
166 | u8 control_frame[CONTROL_FRAME_LEN]; | ||
167 | |||
168 | /* | ||
169 | * Since we access the comm member in current's task_struct, | ||
170 | * we only need to be as large as what 'comm' in that | ||
171 | * structure is. | ||
172 | */ | ||
173 | char comm[TASK_COMM_LEN]; | ||
174 | |||
175 | if (!in_interrupt()) | ||
176 | get_task_comm(comm, current); | ||
177 | else | ||
178 | strncpy(comm, "Interrupt", TASK_COMM_LEN); | ||
179 | |||
180 | /* Absolutely ensure our buffer is zero terminated. */ | ||
181 | comm[TASK_COMM_LEN-1] = 0; | ||
182 | |||
183 | mccontrol.channel = pti_control_channel; | ||
184 | pti_control_channel = (pti_control_channel + 1) & 0x7f; | ||
185 | |||
186 | snprintf(control_frame, CONTROL_FRAME_LEN, control_format, mc->master, | ||
187 | mc->channel, comm); | ||
188 | pti_write_to_aperture(&mccontrol, control_frame, strlen(control_frame)); | ||
189 | } | ||
190 | |||
191 | /** | ||
192 | * pti_write_full_frame_to_aperture()- high level function to | ||
193 | * write to PTI. | ||
194 | * | ||
195 | * @mc: The 'aperture'. It's part of a write address that holds | ||
196 | * a master and channel ID. | ||
197 | * @buf: Data being written to the HW that will ultimately be seen | ||
198 | * in a debugging tool (Fido, Lauterbach). | ||
199 | * @len: Size of buffer. | ||
200 | * | ||
201 | * All threads sending data (either console, user space application, ...) | ||
202 | * are calling the high level function to write to PTI meaning that it is | ||
203 | * possible to add a control frame before sending the content. | ||
204 | */ | ||
205 | static void pti_write_full_frame_to_aperture(struct pti_masterchannel *mc, | ||
206 | const unsigned char *buf, | ||
207 | int len) | ||
208 | { | ||
209 | pti_control_frame_built_and_sent(mc); | ||
210 | pti_write_to_aperture(mc, (u8 *)buf, len); | ||
211 | } | ||
212 | |||
213 | /** | ||
214 | * get_id()- Allocate a master and channel ID. | ||
215 | * | ||
216 | * @id_array: an array of bits representing what channel | ||
217 | * id's are allocated for writing. | ||
218 | * @max_ids: The max amount of available write IDs to use. | ||
219 | * @base_id: The starting SW channel ID, based on the Intel | ||
220 | * PTI arch. | ||
221 | * | ||
222 | * Returns: | ||
223 | * pti_masterchannel struct with master, channel ID address | ||
224 | * 0 for error | ||
225 | * | ||
226 | * Each bit in the arrays ia_app and ia_os correspond to a master and | ||
227 | * channel id. The bit is one if the id is taken and 0 if free. For | ||
228 | * every master there are 128 channel id's. | ||
229 | */ | ||
230 | static struct pti_masterchannel *get_id(u8 *id_array, int max_ids, int base_id) | ||
231 | { | ||
232 | struct pti_masterchannel *mc; | ||
233 | int i, j, mask; | ||
234 | |||
235 | mc = kmalloc(sizeof(struct pti_masterchannel), GFP_KERNEL); | ||
236 | if (mc == NULL) | ||
237 | return NULL; | ||
238 | |||
239 | /* look for a byte with a free bit */ | ||
240 | for (i = 0; i < max_ids; i++) | ||
241 | if (id_array[i] != 0xff) | ||
242 | break; | ||
243 | if (i == max_ids) { | ||
244 | kfree(mc); | ||
245 | return NULL; | ||
246 | } | ||
247 | /* find the bit in the 128 possible channel opportunities */ | ||
248 | mask = 0x80; | ||
249 | for (j = 0; j < 8; j++) { | ||
250 | if ((id_array[i] & mask) == 0) | ||
251 | break; | ||
252 | mask >>= 1; | ||
253 | } | ||
254 | |||
255 | /* grab it */ | ||
256 | id_array[i] |= mask; | ||
257 | mc->master = base_id; | ||
258 | mc->channel = ((i & 0xf)<<3) + j; | ||
259 | /* write new master Id / channel Id allocation to channel control */ | ||
260 | pti_control_frame_built_and_sent(mc); | ||
261 | return mc; | ||
262 | } | ||
263 | |||
264 | /* | ||
265 | * The following three functions: | ||
266 | * pti_request_mastercahannel(), mipi_release_masterchannel() | ||
267 | * and pti_writedata() are an API for other kernel drivers to | ||
268 | * access PTI. | ||
269 | */ | ||
270 | |||
271 | /** | ||
272 | * pti_request_masterchannel()- Kernel API function used to allocate | ||
273 | * a master, channel ID address | ||
274 | * to write to PTI HW. | ||
275 | * | ||
276 | * @type: 0- request Application master, channel aperture ID write address. | ||
277 | * 1- request OS master, channel aperture ID write | ||
278 | * address. | ||
279 | * 2- request Modem master, channel aperture ID | ||
280 | * write address. | ||
281 | * Other values, error. | ||
282 | * | ||
283 | * Returns: | ||
284 | * pti_masterchannel struct | ||
285 | * 0 for error | ||
286 | */ | ||
287 | struct pti_masterchannel *pti_request_masterchannel(u8 type) | ||
288 | { | ||
289 | struct pti_masterchannel *mc; | ||
290 | |||
291 | mutex_lock(&alloclock); | ||
292 | |||
293 | switch (type) { | ||
294 | |||
295 | case 0: | ||
296 | mc = get_id(drv_data->ia_app, MAX_APP_IDS, APP_BASE_ID); | ||
297 | break; | ||
298 | |||
299 | case 1: | ||
300 | mc = get_id(drv_data->ia_os, MAX_OS_IDS, OS_BASE_ID); | ||
301 | break; | ||
302 | |||
303 | case 2: | ||
304 | mc = get_id(drv_data->ia_modem, MAX_MODEM_IDS, MODEM_BASE_ID); | ||
305 | break; | ||
306 | default: | ||
307 | mc = NULL; | ||
308 | } | ||
309 | |||
310 | mutex_unlock(&alloclock); | ||
311 | return mc; | ||
312 | } | ||
313 | EXPORT_SYMBOL_GPL(pti_request_masterchannel); | ||
314 | |||
315 | /** | ||
316 | * pti_release_masterchannel()- Kernel API function used to release | ||
317 | * a master, channel ID address | ||
318 | * used to write to PTI HW. | ||
319 | * | ||
320 | * @mc: master, channel apeture ID address to be released. | ||
321 | */ | ||
322 | void pti_release_masterchannel(struct pti_masterchannel *mc) | ||
323 | { | ||
324 | u8 master, channel, i; | ||
325 | |||
326 | mutex_lock(&alloclock); | ||
327 | |||
328 | if (mc) { | ||
329 | master = mc->master; | ||
330 | channel = mc->channel; | ||
331 | |||
332 | if (master == APP_BASE_ID) { | ||
333 | i = channel >> 3; | ||
334 | drv_data->ia_app[i] &= ~(0x80>>(channel & 0x7)); | ||
335 | } else if (master == OS_BASE_ID) { | ||
336 | i = channel >> 3; | ||
337 | drv_data->ia_os[i] &= ~(0x80>>(channel & 0x7)); | ||
338 | } else { | ||
339 | i = channel >> 3; | ||
340 | drv_data->ia_modem[i] &= ~(0x80>>(channel & 0x7)); | ||
341 | } | ||
342 | |||
343 | kfree(mc); | ||
344 | } | ||
345 | |||
346 | mutex_unlock(&alloclock); | ||
347 | } | ||
348 | EXPORT_SYMBOL_GPL(pti_release_masterchannel); | ||
349 | |||
350 | /** | ||
351 | * pti_writedata()- Kernel API function used to write trace | ||
352 | * debugging data to PTI HW. | ||
353 | * | ||
354 | * @mc: Master, channel aperture ID address to write to. | ||
355 | * Null value will return with no write occurring. | ||
356 | * @buf: Trace debuging data to write to the PTI HW. | ||
357 | * Null value will return with no write occurring. | ||
358 | * @count: Size of buf. Value of 0 or a negative number will | ||
359 | * return with no write occuring. | ||
360 | */ | ||
361 | void pti_writedata(struct pti_masterchannel *mc, u8 *buf, int count) | ||
362 | { | ||
363 | /* | ||
364 | * since this function is exported, this is treated like an | ||
365 | * API function, thus, all parameters should | ||
366 | * be checked for validity. | ||
367 | */ | ||
368 | if ((mc != NULL) && (buf != NULL) && (count > 0)) | ||
369 | pti_write_to_aperture(mc, buf, count); | ||
370 | return; | ||
371 | } | ||
372 | EXPORT_SYMBOL_GPL(pti_writedata); | ||
373 | |||
374 | /** | ||
375 | * pti_pci_remove()- Driver exit method to remove PTI from | ||
376 | * PCI bus. | ||
377 | * @pdev: variable containing pci info of PTI. | ||
378 | */ | ||
379 | static void __devexit pti_pci_remove(struct pci_dev *pdev) | ||
380 | { | ||
381 | struct pti_dev *drv_data; | ||
382 | |||
383 | drv_data = pci_get_drvdata(pdev); | ||
384 | if (drv_data != NULL) { | ||
385 | pci_iounmap(pdev, drv_data->pti_ioaddr); | ||
386 | pci_set_drvdata(pdev, NULL); | ||
387 | kfree(drv_data); | ||
388 | pci_release_region(pdev, 1); | ||
389 | pci_disable_device(pdev); | ||
390 | } | ||
391 | } | ||
392 | |||
393 | /* | ||
394 | * for the tty_driver_*() basic function descriptions, see tty_driver.h. | ||
395 | * Specific header comments made for PTI-related specifics. | ||
396 | */ | ||
397 | |||
398 | /** | ||
399 | * pti_tty_driver_open()- Open an Application master, channel aperture | ||
400 | * ID to the PTI device via tty device. | ||
401 | * | ||
402 | * @tty: tty interface. | ||
403 | * @filp: filp interface pased to tty_port_open() call. | ||
404 | * | ||
405 | * Returns: | ||
406 | * int, 0 for success | ||
407 | * otherwise, fail value | ||
408 | * | ||
409 | * The main purpose of using the tty device interface is for | ||
410 | * each tty port to have a unique PTI write aperture. In an | ||
411 | * example use case, ttyPTI0 gets syslogd and an APP aperture | ||
412 | * ID and ttyPTI1 is where the n_tracesink ldisc hooks to route | ||
413 | * modem messages into PTI. Modem trace data does not have to | ||
414 | * go to ttyPTI1, but ttyPTI0 and ttyPTI1 do need to be distinct | ||
415 | * master IDs. These messages go through the PTI HW and out of | ||
416 | * the handheld platform and to the Fido/Lauterbach device. | ||
417 | */ | ||
418 | static int pti_tty_driver_open(struct tty_struct *tty, struct file *filp) | ||
419 | { | ||
420 | /* | ||
421 | * we actually want to allocate a new channel per open, per | ||
422 | * system arch. HW gives more than plenty channels for a single | ||
423 | * system task to have its own channel to write trace data. This | ||
424 | * also removes a locking requirement for the actual write | ||
425 | * procedure. | ||
426 | */ | ||
427 | return tty_port_open(&drv_data->port, tty, filp); | ||
428 | } | ||
429 | |||
430 | /** | ||
431 | * pti_tty_driver_close()- close tty device and release Application | ||
432 | * master, channel aperture ID to the PTI device via tty device. | ||
433 | * | ||
434 | * @tty: tty interface. | ||
435 | * @filp: filp interface pased to tty_port_close() call. | ||
436 | * | ||
437 | * The main purpose of using the tty device interface is to route | ||
438 | * syslog daemon messages to the PTI HW and out of the handheld platform | ||
439 | * and to the Fido/Lauterbach device. | ||
440 | */ | ||
441 | static void pti_tty_driver_close(struct tty_struct *tty, struct file *filp) | ||
442 | { | ||
443 | tty_port_close(&drv_data->port, tty, filp); | ||
444 | } | ||
445 | |||
446 | /** | ||
447 | * pti_tty_intstall()- Used to set up specific master-channels | ||
448 | * to tty ports for organizational purposes when | ||
449 | * tracing viewed from debuging tools. | ||
450 | * | ||
451 | * @driver: tty driver information. | ||
452 | * @tty: tty struct containing pti information. | ||
453 | * | ||
454 | * Returns: | ||
455 | * 0 for success | ||
456 | * otherwise, error | ||
457 | */ | ||
458 | static int pti_tty_install(struct tty_driver *driver, struct tty_struct *tty) | ||
459 | { | ||
460 | int idx = tty->index; | ||
461 | struct pti_tty *pti_tty_data; | ||
462 | int ret = tty_init_termios(tty); | ||
463 | |||
464 | if (ret == 0) { | ||
465 | tty_driver_kref_get(driver); | ||
466 | tty->count++; | ||
467 | driver->ttys[idx] = tty; | ||
468 | |||
469 | pti_tty_data = kmalloc(sizeof(struct pti_tty), GFP_KERNEL); | ||
470 | if (pti_tty_data == NULL) | ||
471 | return -ENOMEM; | ||
472 | |||
473 | if (idx == PTITTY_MINOR_START) | ||
474 | pti_tty_data->mc = pti_request_masterchannel(0); | ||
475 | else | ||
476 | pti_tty_data->mc = pti_request_masterchannel(2); | ||
477 | |||
478 | if (pti_tty_data->mc == NULL) | ||
479 | return -ENXIO; | ||
480 | tty->driver_data = pti_tty_data; | ||
481 | } | ||
482 | |||
483 | return ret; | ||
484 | } | ||
485 | |||
486 | /** | ||
487 | * pti_tty_cleanup()- Used to de-allocate master-channel resources | ||
488 | * tied to tty's of this driver. | ||
489 | * | ||
490 | * @tty: tty struct containing pti information. | ||
491 | */ | ||
492 | static void pti_tty_cleanup(struct tty_struct *tty) | ||
493 | { | ||
494 | struct pti_tty *pti_tty_data = tty->driver_data; | ||
495 | if (pti_tty_data == NULL) | ||
496 | return; | ||
497 | pti_release_masterchannel(pti_tty_data->mc); | ||
498 | kfree(tty->driver_data); | ||
499 | tty->driver_data = NULL; | ||
500 | } | ||
501 | |||
502 | /** | ||
503 | * pti_tty_driver_write()- Write trace debugging data through the char | ||
504 | * interface to the PTI HW. Part of the misc device implementation. | ||
505 | * | ||
506 | * @filp: Contains private data which is used to obtain | ||
507 | * master, channel write ID. | ||
508 | * @data: trace data to be written. | ||
509 | * @len: # of byte to write. | ||
510 | * | ||
511 | * Returns: | ||
512 | * int, # of bytes written | ||
513 | * otherwise, error | ||
514 | */ | ||
515 | static int pti_tty_driver_write(struct tty_struct *tty, | ||
516 | const unsigned char *buf, int len) | ||
517 | { | ||
518 | struct pti_tty *pti_tty_data = tty->driver_data; | ||
519 | if ((pti_tty_data != NULL) && (pti_tty_data->mc != NULL)) { | ||
520 | pti_write_to_aperture(pti_tty_data->mc, (u8 *)buf, len); | ||
521 | return len; | ||
522 | } | ||
523 | /* | ||
524 | * we can't write to the pti hardware if the private driver_data | ||
525 | * and the mc address is not there. | ||
526 | */ | ||
527 | else | ||
528 | return -EFAULT; | ||
529 | } | ||
530 | |||
531 | /** | ||
532 | * pti_tty_write_room()- Always returns 2048. | ||
533 | * | ||
534 | * @tty: contains tty info of the pti driver. | ||
535 | */ | ||
536 | static int pti_tty_write_room(struct tty_struct *tty) | ||
537 | { | ||
538 | return 2048; | ||
539 | } | ||
540 | |||
541 | /** | ||
542 | * pti_char_open()- Open an Application master, channel aperture | ||
543 | * ID to the PTI device. Part of the misc device implementation. | ||
544 | * | ||
545 | * @inode: not used. | ||
546 | * @filp: Output- will have a masterchannel struct set containing | ||
547 | * the allocated application PTI aperture write address. | ||
548 | * | ||
549 | * Returns: | ||
550 | * int, 0 for success | ||
551 | * otherwise, a fail value | ||
552 | */ | ||
553 | static int pti_char_open(struct inode *inode, struct file *filp) | ||
554 | { | ||
555 | struct pti_masterchannel *mc; | ||
556 | |||
557 | /* | ||
558 | * We really do want to fail immediately if | ||
559 | * pti_request_masterchannel() fails, | ||
560 | * before assigning the value to filp->private_data. | ||
561 | * Slightly easier to debug if this driver needs debugging. | ||
562 | */ | ||
563 | mc = pti_request_masterchannel(0); | ||
564 | if (mc == NULL) | ||
565 | return -ENOMEM; | ||
566 | filp->private_data = mc; | ||
567 | return 0; | ||
568 | } | ||
569 | |||
570 | /** | ||
571 | * pti_char_release()- Close a char channel to the PTI device. Part | ||
572 | * of the misc device implementation. | ||
573 | * | ||
574 | * @inode: Not used in this implementaiton. | ||
575 | * @filp: Contains private_data that contains the master, channel | ||
576 | * ID to be released by the PTI device. | ||
577 | * | ||
578 | * Returns: | ||
579 | * always 0 | ||
580 | */ | ||
581 | static int pti_char_release(struct inode *inode, struct file *filp) | ||
582 | { | ||
583 | pti_release_masterchannel(filp->private_data); | ||
584 | kfree(filp->private_data); | ||
585 | return 0; | ||
586 | } | ||
587 | |||
588 | /** | ||
589 | * pti_char_write()- Write trace debugging data through the char | ||
590 | * interface to the PTI HW. Part of the misc device implementation. | ||
591 | * | ||
592 | * @filp: Contains private data which is used to obtain | ||
593 | * master, channel write ID. | ||
594 | * @data: trace data to be written. | ||
595 | * @len: # of byte to write. | ||
596 | * @ppose: Not used in this function implementation. | ||
597 | * | ||
598 | * Returns: | ||
599 | * int, # of bytes written | ||
600 | * otherwise, error value | ||
601 | * | ||
602 | * Notes: From side discussions with Alan Cox and experimenting | ||
603 | * with PTI debug HW like Nokia's Fido box and Lauterbach | ||
604 | * devices, 8192 byte write buffer used by USER_COPY_SIZE was | ||
605 | * deemed an appropriate size for this type of usage with | ||
606 | * debugging HW. | ||
607 | */ | ||
608 | static ssize_t pti_char_write(struct file *filp, const char __user *data, | ||
609 | size_t len, loff_t *ppose) | ||
610 | { | ||
611 | struct pti_masterchannel *mc; | ||
612 | void *kbuf; | ||
613 | const char __user *tmp; | ||
614 | size_t size = USER_COPY_SIZE; | ||
615 | size_t n = 0; | ||
616 | |||
617 | tmp = data; | ||
618 | mc = filp->private_data; | ||
619 | |||
620 | kbuf = kmalloc(size, GFP_KERNEL); | ||
621 | if (kbuf == NULL) { | ||
622 | pr_err("%s(%d): buf allocation failed\n", | ||
623 | __func__, __LINE__); | ||
624 | return -ENOMEM; | ||
625 | } | ||
626 | |||
627 | do { | ||
628 | if (len - n > USER_COPY_SIZE) | ||
629 | size = USER_COPY_SIZE; | ||
630 | else | ||
631 | size = len - n; | ||
632 | |||
633 | if (copy_from_user(kbuf, tmp, size)) { | ||
634 | kfree(kbuf); | ||
635 | return n ? n : -EFAULT; | ||
636 | } | ||
637 | |||
638 | pti_write_to_aperture(mc, kbuf, size); | ||
639 | n += size; | ||
640 | tmp += size; | ||
641 | |||
642 | } while (len > n); | ||
643 | |||
644 | kfree(kbuf); | ||
645 | return len; | ||
646 | } | ||
647 | |||
648 | static const struct tty_operations pti_tty_driver_ops = { | ||
649 | .open = pti_tty_driver_open, | ||
650 | .close = pti_tty_driver_close, | ||
651 | .write = pti_tty_driver_write, | ||
652 | .write_room = pti_tty_write_room, | ||
653 | .install = pti_tty_install, | ||
654 | .cleanup = pti_tty_cleanup | ||
655 | }; | ||
656 | |||
657 | static const struct file_operations pti_char_driver_ops = { | ||
658 | .owner = THIS_MODULE, | ||
659 | .write = pti_char_write, | ||
660 | .open = pti_char_open, | ||
661 | .release = pti_char_release, | ||
662 | }; | ||
663 | |||
664 | static struct miscdevice pti_char_driver = { | ||
665 | .minor = MISC_DYNAMIC_MINOR, | ||
666 | .name = CHARNAME, | ||
667 | .fops = &pti_char_driver_ops | ||
668 | }; | ||
669 | |||
670 | /** | ||
671 | * pti_console_write()- Write to the console that has been acquired. | ||
672 | * | ||
673 | * @c: Not used in this implementaiton. | ||
674 | * @buf: Data to be written. | ||
675 | * @len: Length of buf. | ||
676 | */ | ||
677 | static void pti_console_write(struct console *c, const char *buf, unsigned len) | ||
678 | { | ||
679 | static struct pti_masterchannel mc = {.master = CONSOLE_ID, | ||
680 | .channel = 0}; | ||
681 | |||
682 | mc.channel = pti_console_channel; | ||
683 | pti_console_channel = (pti_console_channel + 1) & 0x7f; | ||
684 | |||
685 | pti_write_full_frame_to_aperture(&mc, buf, len); | ||
686 | } | ||
687 | |||
688 | /** | ||
689 | * pti_console_device()- Return the driver tty structure and set the | ||
690 | * associated index implementation. | ||
691 | * | ||
692 | * @c: Console device of the driver. | ||
693 | * @index: index associated with c. | ||
694 | * | ||
695 | * Returns: | ||
696 | * always value of pti_tty_driver structure when this function | ||
697 | * is called. | ||
698 | */ | ||
699 | static struct tty_driver *pti_console_device(struct console *c, int *index) | ||
700 | { | ||
701 | *index = c->index; | ||
702 | return pti_tty_driver; | ||
703 | } | ||
704 | |||
705 | /** | ||
706 | * pti_console_setup()- Initialize console variables used by the driver. | ||
707 | * | ||
708 | * @c: Not used. | ||
709 | * @opts: Not used. | ||
710 | * | ||
711 | * Returns: | ||
712 | * always 0. | ||
713 | */ | ||
714 | static int pti_console_setup(struct console *c, char *opts) | ||
715 | { | ||
716 | pti_console_channel = 0; | ||
717 | pti_control_channel = 0; | ||
718 | return 0; | ||
719 | } | ||
720 | |||
721 | /* | ||
722 | * pti_console struct, used to capture OS printk()'s and shift | ||
723 | * out to the PTI device for debugging. This cannot be | ||
724 | * enabled upon boot because of the possibility of eating | ||
725 | * any serial console printk's (race condition discovered). | ||
726 | * The console should be enabled upon when the tty port is | ||
727 | * used for the first time. Since the primary purpose for | ||
728 | * the tty port is to hook up syslog to it, the tty port | ||
729 | * will be open for a really long time. | ||
730 | */ | ||
731 | static struct console pti_console = { | ||
732 | .name = TTYNAME, | ||
733 | .write = pti_console_write, | ||
734 | .device = pti_console_device, | ||
735 | .setup = pti_console_setup, | ||
736 | .flags = CON_PRINTBUFFER, | ||
737 | .index = 0, | ||
738 | }; | ||
739 | |||
740 | /** | ||
741 | * pti_port_activate()- Used to start/initialize any items upon | ||
742 | * first opening of tty_port(). | ||
743 | * | ||
744 | * @port- The tty port number of the PTI device. | ||
745 | * @tty- The tty struct associated with this device. | ||
746 | * | ||
747 | * Returns: | ||
748 | * always returns 0 | ||
749 | * | ||
750 | * Notes: The primary purpose of the PTI tty port 0 is to hook | ||
751 | * the syslog daemon to it; thus this port will be open for a | ||
752 | * very long time. | ||
753 | */ | ||
754 | static int pti_port_activate(struct tty_port *port, struct tty_struct *tty) | ||
755 | { | ||
756 | if (port->tty->index == PTITTY_MINOR_START) | ||
757 | console_start(&pti_console); | ||
758 | return 0; | ||
759 | } | ||
760 | |||
761 | /** | ||
762 | * pti_port_shutdown()- Used to stop/shutdown any items upon the | ||
763 | * last tty port close. | ||
764 | * | ||
765 | * @port- The tty port number of the PTI device. | ||
766 | * | ||
767 | * Notes: The primary purpose of the PTI tty port 0 is to hook | ||
768 | * the syslog daemon to it; thus this port will be open for a | ||
769 | * very long time. | ||
770 | */ | ||
771 | static void pti_port_shutdown(struct tty_port *port) | ||
772 | { | ||
773 | if (port->tty->index == PTITTY_MINOR_START) | ||
774 | console_stop(&pti_console); | ||
775 | } | ||
776 | |||
777 | static const struct tty_port_operations tty_port_ops = { | ||
778 | .activate = pti_port_activate, | ||
779 | .shutdown = pti_port_shutdown, | ||
780 | }; | ||
781 | |||
782 | /* | ||
783 | * Note the _probe() call sets everything up and ties the char and tty | ||
784 | * to successfully detecting the PTI device on the pci bus. | ||
785 | */ | ||
786 | |||
787 | /** | ||
788 | * pti_pci_probe()- Used to detect pti on the pci bus and set | ||
789 | * things up in the driver. | ||
790 | * | ||
791 | * @pdev- pci_dev struct values for pti. | ||
792 | * @ent- pci_device_id struct for pti driver. | ||
793 | * | ||
794 | * Returns: | ||
795 | * 0 for success | ||
796 | * otherwise, error | ||
797 | */ | ||
798 | static int __devinit pti_pci_probe(struct pci_dev *pdev, | ||
799 | const struct pci_device_id *ent) | ||
800 | { | ||
801 | int retval = -EINVAL; | ||
802 | int pci_bar = 1; | ||
803 | |||
804 | dev_dbg(&pdev->dev, "%s %s(%d): PTI PCI ID %04x:%04x\n", __FILE__, | ||
805 | __func__, __LINE__, pdev->vendor, pdev->device); | ||
806 | |||
807 | retval = misc_register(&pti_char_driver); | ||
808 | if (retval) { | ||
809 | pr_err("%s(%d): CHAR registration failed of pti driver\n", | ||
810 | __func__, __LINE__); | ||
811 | pr_err("%s(%d): Error value returned: %d\n", | ||
812 | __func__, __LINE__, retval); | ||
813 | return retval; | ||
814 | } | ||
815 | |||
816 | retval = pci_enable_device(pdev); | ||
817 | if (retval != 0) { | ||
818 | dev_err(&pdev->dev, | ||
819 | "%s: pci_enable_device() returned error %d\n", | ||
820 | __func__, retval); | ||
821 | return retval; | ||
822 | } | ||
823 | |||
824 | drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL); | ||
825 | |||
826 | if (drv_data == NULL) { | ||
827 | retval = -ENOMEM; | ||
828 | dev_err(&pdev->dev, | ||
829 | "%s(%d): kmalloc() returned NULL memory.\n", | ||
830 | __func__, __LINE__); | ||
831 | return retval; | ||
832 | } | ||
833 | drv_data->pti_addr = pci_resource_start(pdev, pci_bar); | ||
834 | |||
835 | retval = pci_request_region(pdev, pci_bar, dev_name(&pdev->dev)); | ||
836 | if (retval != 0) { | ||
837 | dev_err(&pdev->dev, | ||
838 | "%s(%d): pci_request_region() returned error %d\n", | ||
839 | __func__, __LINE__, retval); | ||
840 | kfree(drv_data); | ||
841 | return retval; | ||
842 | } | ||
843 | drv_data->aperture_base = drv_data->pti_addr+APERTURE_14; | ||
844 | drv_data->pti_ioaddr = | ||
845 | ioremap_nocache((u32)drv_data->aperture_base, | ||
846 | APERTURE_LEN); | ||
847 | if (!drv_data->pti_ioaddr) { | ||
848 | pci_release_region(pdev, pci_bar); | ||
849 | retval = -ENOMEM; | ||
850 | kfree(drv_data); | ||
851 | return retval; | ||
852 | } | ||
853 | |||
854 | pci_set_drvdata(pdev, drv_data); | ||
855 | |||
856 | tty_port_init(&drv_data->port); | ||
857 | drv_data->port.ops = &tty_port_ops; | ||
858 | |||
859 | tty_register_device(pti_tty_driver, 0, &pdev->dev); | ||
860 | tty_register_device(pti_tty_driver, 1, &pdev->dev); | ||
861 | |||
862 | register_console(&pti_console); | ||
863 | |||
864 | return retval; | ||
865 | } | ||
866 | |||
867 | static struct pci_driver pti_pci_driver = { | ||
868 | .name = PCINAME, | ||
869 | .id_table = pci_ids, | ||
870 | .probe = pti_pci_probe, | ||
871 | .remove = pti_pci_remove, | ||
872 | }; | ||
873 | |||
874 | /** | ||
875 | * | ||
876 | * pti_init()- Overall entry/init call to the pti driver. | ||
877 | * It starts the registration process with the kernel. | ||
878 | * | ||
879 | * Returns: | ||
880 | * int __init, 0 for success | ||
881 | * otherwise value is an error | ||
882 | * | ||
883 | */ | ||
884 | static int __init pti_init(void) | ||
885 | { | ||
886 | int retval = -EINVAL; | ||
887 | |||
888 | /* First register module as tty device */ | ||
889 | |||
890 | pti_tty_driver = alloc_tty_driver(1); | ||
891 | if (pti_tty_driver == NULL) { | ||
892 | pr_err("%s(%d): Memory allocation failed for ptiTTY driver\n", | ||
893 | __func__, __LINE__); | ||
894 | return -ENOMEM; | ||
895 | } | ||
896 | |||
897 | pti_tty_driver->owner = THIS_MODULE; | ||
898 | pti_tty_driver->magic = TTY_DRIVER_MAGIC; | ||
899 | pti_tty_driver->driver_name = DRIVERNAME; | ||
900 | pti_tty_driver->name = TTYNAME; | ||
901 | pti_tty_driver->major = 0; | ||
902 | pti_tty_driver->minor_start = PTITTY_MINOR_START; | ||
903 | pti_tty_driver->minor_num = PTITTY_MINOR_NUM; | ||
904 | pti_tty_driver->num = PTITTY_MINOR_NUM; | ||
905 | pti_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM; | ||
906 | pti_tty_driver->subtype = SYSTEM_TYPE_SYSCONS; | ||
907 | pti_tty_driver->flags = TTY_DRIVER_REAL_RAW | | ||
908 | TTY_DRIVER_DYNAMIC_DEV; | ||
909 | pti_tty_driver->init_termios = tty_std_termios; | ||
910 | |||
911 | tty_set_operations(pti_tty_driver, &pti_tty_driver_ops); | ||
912 | |||
913 | retval = tty_register_driver(pti_tty_driver); | ||
914 | if (retval) { | ||
915 | pr_err("%s(%d): TTY registration failed of pti driver\n", | ||
916 | __func__, __LINE__); | ||
917 | pr_err("%s(%d): Error value returned: %d\n", | ||
918 | __func__, __LINE__, retval); | ||
919 | |||
920 | pti_tty_driver = NULL; | ||
921 | return retval; | ||
922 | } | ||
923 | |||
924 | retval = pci_register_driver(&pti_pci_driver); | ||
925 | |||
926 | if (retval) { | ||
927 | pr_err("%s(%d): PCI registration failed of pti driver\n", | ||
928 | __func__, __LINE__); | ||
929 | pr_err("%s(%d): Error value returned: %d\n", | ||
930 | __func__, __LINE__, retval); | ||
931 | |||
932 | tty_unregister_driver(pti_tty_driver); | ||
933 | pr_err("%s(%d): Unregistering TTY part of pti driver\n", | ||
934 | __func__, __LINE__); | ||
935 | pti_tty_driver = NULL; | ||
936 | return retval; | ||
937 | } | ||
938 | |||
939 | return retval; | ||
940 | } | ||
941 | |||
942 | /** | ||
943 | * pti_exit()- Unregisters this module as a tty and pci driver. | ||
944 | */ | ||
945 | static void __exit pti_exit(void) | ||
946 | { | ||
947 | int retval; | ||
948 | |||
949 | tty_unregister_device(pti_tty_driver, 0); | ||
950 | tty_unregister_device(pti_tty_driver, 1); | ||
951 | |||
952 | retval = tty_unregister_driver(pti_tty_driver); | ||
953 | if (retval) { | ||
954 | pr_err("%s(%d): TTY unregistration failed of pti driver\n", | ||
955 | __func__, __LINE__); | ||
956 | pr_err("%s(%d): Error value returned: %d\n", | ||
957 | __func__, __LINE__, retval); | ||
958 | } | ||
959 | |||
960 | pci_unregister_driver(&pti_pci_driver); | ||
961 | |||
962 | retval = misc_deregister(&pti_char_driver); | ||
963 | if (retval) { | ||
964 | pr_err("%s(%d): CHAR unregistration failed of pti driver\n", | ||
965 | __func__, __LINE__); | ||
966 | pr_err("%s(%d): Error value returned: %d\n", | ||
967 | __func__, __LINE__, retval); | ||
968 | } | ||
969 | |||
970 | unregister_console(&pti_console); | ||
971 | return; | ||
972 | } | ||
973 | |||
974 | module_init(pti_init); | ||
975 | module_exit(pti_exit); | ||
976 | |||
977 | MODULE_LICENSE("GPL"); | ||
978 | MODULE_AUTHOR("Ken Mills, Jay Freyensee"); | ||
979 | MODULE_DESCRIPTION("PTI Driver"); | ||
980 | |||
diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index f91f82eabda7..1a05fe08e2cb 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c | |||
@@ -747,8 +747,8 @@ static void st_tty_close(struct tty_struct *tty) | |||
747 | pr_debug("%s: done ", __func__); | 747 | pr_debug("%s: done ", __func__); |
748 | } | 748 | } |
749 | 749 | ||
750 | static void st_tty_receive(struct tty_struct *tty, const unsigned char *data, | 750 | static unsigned int st_tty_receive(struct tty_struct *tty, |
751 | char *tty_flags, int count) | 751 | const unsigned char *data, char *tty_flags, int count) |
752 | { | 752 | { |
753 | #ifdef VERBOSE | 753 | #ifdef VERBOSE |
754 | print_hex_dump(KERN_DEBUG, ">in>", DUMP_PREFIX_NONE, | 754 | print_hex_dump(KERN_DEBUG, ">in>", DUMP_PREFIX_NONE, |
@@ -761,6 +761,8 @@ static void st_tty_receive(struct tty_struct *tty, const unsigned char *data, | |||
761 | */ | 761 | */ |
762 | st_recv(tty->disc_data, data, count); | 762 | st_recv(tty->disc_data, data, count); |
763 | pr_debug("done %s", __func__); | 763 | pr_debug("done %s", __func__); |
764 | |||
765 | return count; | ||
764 | } | 766 | } |
765 | 767 | ||
766 | /* wake-up function called in from the TTY layer | 768 | /* wake-up function called in from the TTY layer |
diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index 3df0c0f8b8bf..73c7e03617ec 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c | |||
@@ -167,8 +167,8 @@ static inline void debugfs_tx(struct ser_device *ser, const u8 *data, int size) | |||
167 | 167 | ||
168 | #endif | 168 | #endif |
169 | 169 | ||
170 | static void ldisc_receive(struct tty_struct *tty, const u8 *data, | 170 | static unsigned int ldisc_receive(struct tty_struct *tty, |
171 | char *flags, int count) | 171 | const u8 *data, char *flags, int count) |
172 | { | 172 | { |
173 | struct sk_buff *skb = NULL; | 173 | struct sk_buff *skb = NULL; |
174 | struct ser_device *ser; | 174 | struct ser_device *ser; |
@@ -215,6 +215,8 @@ static void ldisc_receive(struct tty_struct *tty, const u8 *data, | |||
215 | } else | 215 | } else |
216 | ++ser->dev->stats.rx_dropped; | 216 | ++ser->dev->stats.rx_dropped; |
217 | update_tty_status(ser); | 217 | update_tty_status(ser); |
218 | |||
219 | return count; | ||
218 | } | 220 | } |
219 | 221 | ||
220 | static int handle_tx(struct ser_device *ser) | 222 | static int handle_tx(struct ser_device *ser) |
diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index 1b49df6b2470..75622d54581f 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c | |||
@@ -425,16 +425,17 @@ static void slc_setup(struct net_device *dev) | |||
425 | * in parallel | 425 | * in parallel |
426 | */ | 426 | */ |
427 | 427 | ||
428 | static void slcan_receive_buf(struct tty_struct *tty, | 428 | static unsigned int slcan_receive_buf(struct tty_struct *tty, |
429 | const unsigned char *cp, char *fp, int count) | 429 | const unsigned char *cp, char *fp, int count) |
430 | { | 430 | { |
431 | struct slcan *sl = (struct slcan *) tty->disc_data; | 431 | struct slcan *sl = (struct slcan *) tty->disc_data; |
432 | int bytes = count; | ||
432 | 433 | ||
433 | if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev)) | 434 | if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev)) |
434 | return; | 435 | return -ENODEV; |
435 | 436 | ||
436 | /* Read the characters out of the buffer */ | 437 | /* Read the characters out of the buffer */ |
437 | while (count--) { | 438 | while (bytes--) { |
438 | if (fp && *fp++) { | 439 | if (fp && *fp++) { |
439 | if (!test_and_set_bit(SLF_ERROR, &sl->flags)) | 440 | if (!test_and_set_bit(SLF_ERROR, &sl->flags)) |
440 | sl->dev->stats.rx_errors++; | 441 | sl->dev->stats.rx_errors++; |
@@ -443,6 +444,8 @@ static void slcan_receive_buf(struct tty_struct *tty, | |||
443 | } | 444 | } |
444 | slcan_unesc(sl, *cp++); | 445 | slcan_unesc(sl, *cp++); |
445 | } | 446 | } |
447 | |||
448 | return count; | ||
446 | } | 449 | } |
447 | 450 | ||
448 | /************************************ | 451 | /************************************ |
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 3e5d0b6b6516..992089639ea4 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c | |||
@@ -456,7 +456,7 @@ out: | |||
456 | * a block of 6pack data has been received, which can now be decapsulated | 456 | * a block of 6pack data has been received, which can now be decapsulated |
457 | * and sent on to some IP layer for further processing. | 457 | * and sent on to some IP layer for further processing. |
458 | */ | 458 | */ |
459 | static void sixpack_receive_buf(struct tty_struct *tty, | 459 | static unsigned int sixpack_receive_buf(struct tty_struct *tty, |
460 | const unsigned char *cp, char *fp, int count) | 460 | const unsigned char *cp, char *fp, int count) |
461 | { | 461 | { |
462 | struct sixpack *sp; | 462 | struct sixpack *sp; |
@@ -464,11 +464,11 @@ static void sixpack_receive_buf(struct tty_struct *tty, | |||
464 | int count1; | 464 | int count1; |
465 | 465 | ||
466 | if (!count) | 466 | if (!count) |
467 | return; | 467 | return 0; |
468 | 468 | ||
469 | sp = sp_get(tty); | 469 | sp = sp_get(tty); |
470 | if (!sp) | 470 | if (!sp) |
471 | return; | 471 | return -ENODEV; |
472 | 472 | ||
473 | memcpy(buf, cp, count < sizeof(buf) ? count : sizeof(buf)); | 473 | memcpy(buf, cp, count < sizeof(buf) ? count : sizeof(buf)); |
474 | 474 | ||
@@ -487,6 +487,8 @@ static void sixpack_receive_buf(struct tty_struct *tty, | |||
487 | 487 | ||
488 | sp_put(sp); | 488 | sp_put(sp); |
489 | tty_unthrottle(tty); | 489 | tty_unthrottle(tty); |
490 | |||
491 | return count1; | ||
490 | } | 492 | } |
491 | 493 | ||
492 | /* | 494 | /* |
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 4c628393c8b1..0e4f23531140 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c | |||
@@ -923,13 +923,14 @@ static long mkiss_compat_ioctl(struct tty_struct *tty, struct file *file, | |||
923 | * a block of data has been received, which can now be decapsulated | 923 | * a block of data has been received, which can now be decapsulated |
924 | * and sent on to the AX.25 layer for further processing. | 924 | * and sent on to the AX.25 layer for further processing. |
925 | */ | 925 | */ |
926 | static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp, | 926 | static unsigned int mkiss_receive_buf(struct tty_struct *tty, |
927 | char *fp, int count) | 927 | const unsigned char *cp, char *fp, int count) |
928 | { | 928 | { |
929 | struct mkiss *ax = mkiss_get(tty); | 929 | struct mkiss *ax = mkiss_get(tty); |
930 | int bytes = count; | ||
930 | 931 | ||
931 | if (!ax) | 932 | if (!ax) |
932 | return; | 933 | return -ENODEV; |
933 | 934 | ||
934 | /* | 935 | /* |
935 | * Argh! mtu change time! - costs us the packet part received | 936 | * Argh! mtu change time! - costs us the packet part received |
@@ -939,7 +940,7 @@ static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
939 | ax_changedmtu(ax); | 940 | ax_changedmtu(ax); |
940 | 941 | ||
941 | /* Read the characters out of the buffer */ | 942 | /* Read the characters out of the buffer */ |
942 | while (count--) { | 943 | while (bytes--) { |
943 | if (fp != NULL && *fp++) { | 944 | if (fp != NULL && *fp++) { |
944 | if (!test_and_set_bit(AXF_ERROR, &ax->flags)) | 945 | if (!test_and_set_bit(AXF_ERROR, &ax->flags)) |
945 | ax->dev->stats.rx_errors++; | 946 | ax->dev->stats.rx_errors++; |
@@ -952,6 +953,8 @@ static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
952 | 953 | ||
953 | mkiss_put(ax); | 954 | mkiss_put(ax); |
954 | tty_unthrottle(tty); | 955 | tty_unthrottle(tty); |
956 | |||
957 | return count; | ||
955 | } | 958 | } |
956 | 959 | ||
957 | /* | 960 | /* |
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index 3352b2443e58..035861d8acb1 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c | |||
@@ -216,23 +216,23 @@ static int irtty_do_write(struct sir_dev *dev, const unsigned char *ptr, size_t | |||
216 | * usbserial: urb-complete-interrupt / softint | 216 | * usbserial: urb-complete-interrupt / softint |
217 | */ | 217 | */ |
218 | 218 | ||
219 | static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | 219 | static unsigned int irtty_receive_buf(struct tty_struct *tty, |
220 | char *fp, int count) | 220 | const unsigned char *cp, char *fp, int count) |
221 | { | 221 | { |
222 | struct sir_dev *dev; | 222 | struct sir_dev *dev; |
223 | struct sirtty_cb *priv = tty->disc_data; | 223 | struct sirtty_cb *priv = tty->disc_data; |
224 | int i; | 224 | int i; |
225 | 225 | ||
226 | IRDA_ASSERT(priv != NULL, return;); | 226 | IRDA_ASSERT(priv != NULL, return -ENODEV;); |
227 | IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return;); | 227 | IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -EINVAL;); |
228 | 228 | ||
229 | if (unlikely(count==0)) /* yes, this happens */ | 229 | if (unlikely(count==0)) /* yes, this happens */ |
230 | return; | 230 | return 0; |
231 | 231 | ||
232 | dev = priv->dev; | 232 | dev = priv->dev; |
233 | if (!dev) { | 233 | if (!dev) { |
234 | IRDA_WARNING("%s(), not ready yet!\n", __func__); | 234 | IRDA_WARNING("%s(), not ready yet!\n", __func__); |
235 | return; | 235 | return -ENODEV; |
236 | } | 236 | } |
237 | 237 | ||
238 | for (i = 0; i < count; i++) { | 238 | for (i = 0; i < count; i++) { |
@@ -242,11 +242,13 @@ static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
242 | if (fp && *fp++) { | 242 | if (fp && *fp++) { |
243 | IRDA_DEBUG(0, "Framing or parity error!\n"); | 243 | IRDA_DEBUG(0, "Framing or parity error!\n"); |
244 | sirdev_receive(dev, NULL, 0); /* notify sir_dev (updating stats) */ | 244 | sirdev_receive(dev, NULL, 0); /* notify sir_dev (updating stats) */ |
245 | return; | 245 | return -EINVAL; |
246 | } | 246 | } |
247 | } | 247 | } |
248 | 248 | ||
249 | sirdev_receive(dev, cp, count); | 249 | sirdev_receive(dev, cp, count); |
250 | |||
251 | return count; | ||
250 | } | 252 | } |
251 | 253 | ||
252 | /* | 254 | /* |
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c index a1b82c9c67d2..53872d7d7382 100644 --- a/drivers/net/ppp_async.c +++ b/drivers/net/ppp_async.c | |||
@@ -340,7 +340,7 @@ ppp_asynctty_poll(struct tty_struct *tty, struct file *file, poll_table *wait) | |||
340 | } | 340 | } |
341 | 341 | ||
342 | /* May sleep, don't call from interrupt level or with interrupts disabled */ | 342 | /* May sleep, don't call from interrupt level or with interrupts disabled */ |
343 | static void | 343 | static unsigned int |
344 | ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf, | 344 | ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf, |
345 | char *cflags, int count) | 345 | char *cflags, int count) |
346 | { | 346 | { |
@@ -348,7 +348,7 @@ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf, | |||
348 | unsigned long flags; | 348 | unsigned long flags; |
349 | 349 | ||
350 | if (!ap) | 350 | if (!ap) |
351 | return; | 351 | return -ENODEV; |
352 | spin_lock_irqsave(&ap->recv_lock, flags); | 352 | spin_lock_irqsave(&ap->recv_lock, flags); |
353 | ppp_async_input(ap, buf, cflags, count); | 353 | ppp_async_input(ap, buf, cflags, count); |
354 | spin_unlock_irqrestore(&ap->recv_lock, flags); | 354 | spin_unlock_irqrestore(&ap->recv_lock, flags); |
@@ -356,6 +356,8 @@ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf, | |||
356 | tasklet_schedule(&ap->tsk); | 356 | tasklet_schedule(&ap->tsk); |
357 | ap_put(ap); | 357 | ap_put(ap); |
358 | tty_unthrottle(tty); | 358 | tty_unthrottle(tty); |
359 | |||
360 | return count; | ||
359 | } | 361 | } |
360 | 362 | ||
361 | static void | 363 | static void |
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c index 2573f525f11c..0815790a5cf9 100644 --- a/drivers/net/ppp_synctty.c +++ b/drivers/net/ppp_synctty.c | |||
@@ -381,7 +381,7 @@ ppp_sync_poll(struct tty_struct *tty, struct file *file, poll_table *wait) | |||
381 | } | 381 | } |
382 | 382 | ||
383 | /* May sleep, don't call from interrupt level or with interrupts disabled */ | 383 | /* May sleep, don't call from interrupt level or with interrupts disabled */ |
384 | static void | 384 | static unsigned int |
385 | ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf, | 385 | ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf, |
386 | char *cflags, int count) | 386 | char *cflags, int count) |
387 | { | 387 | { |
@@ -389,7 +389,7 @@ ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf, | |||
389 | unsigned long flags; | 389 | unsigned long flags; |
390 | 390 | ||
391 | if (!ap) | 391 | if (!ap) |
392 | return; | 392 | return -ENODEV; |
393 | spin_lock_irqsave(&ap->recv_lock, flags); | 393 | spin_lock_irqsave(&ap->recv_lock, flags); |
394 | ppp_sync_input(ap, buf, cflags, count); | 394 | ppp_sync_input(ap, buf, cflags, count); |
395 | spin_unlock_irqrestore(&ap->recv_lock, flags); | 395 | spin_unlock_irqrestore(&ap->recv_lock, flags); |
@@ -397,6 +397,8 @@ ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf, | |||
397 | tasklet_schedule(&ap->tsk); | 397 | tasklet_schedule(&ap->tsk); |
398 | sp_put(ap); | 398 | sp_put(ap); |
399 | tty_unthrottle(tty); | 399 | tty_unthrottle(tty); |
400 | |||
401 | return count; | ||
400 | } | 402 | } |
401 | 403 | ||
402 | static void | 404 | static void |
diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 8ec1a9a0bb9a..584809c656d5 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c | |||
@@ -670,16 +670,17 @@ static void sl_setup(struct net_device *dev) | |||
670 | * in parallel | 670 | * in parallel |
671 | */ | 671 | */ |
672 | 672 | ||
673 | static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, | 673 | static unsigned int slip_receive_buf(struct tty_struct *tty, |
674 | char *fp, int count) | 674 | const unsigned char *cp, char *fp, int count) |
675 | { | 675 | { |
676 | struct slip *sl = tty->disc_data; | 676 | struct slip *sl = tty->disc_data; |
677 | int bytes = count; | ||
677 | 678 | ||
678 | if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) | 679 | if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) |
679 | return; | 680 | return -ENODEV; |
680 | 681 | ||
681 | /* Read the characters out of the buffer */ | 682 | /* Read the characters out of the buffer */ |
682 | while (count--) { | 683 | while (bytes--) { |
683 | if (fp && *fp++) { | 684 | if (fp && *fp++) { |
684 | if (!test_and_set_bit(SLF_ERROR, &sl->flags)) | 685 | if (!test_and_set_bit(SLF_ERROR, &sl->flags)) |
685 | sl->dev->stats.rx_errors++; | 686 | sl->dev->stats.rx_errors++; |
@@ -693,6 +694,8 @@ static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
693 | #endif | 694 | #endif |
694 | slip_unesc(sl, *cp++); | 695 | slip_unesc(sl, *cp++); |
695 | } | 696 | } |
697 | |||
698 | return count; | ||
696 | } | 699 | } |
697 | 700 | ||
698 | /************************************ | 701 | /************************************ |
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index 24297b274cd4..40398bf7d036 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c | |||
@@ -517,17 +517,18 @@ static int x25_asy_close(struct net_device *dev) | |||
517 | * and sent on to some IP layer for further processing. | 517 | * and sent on to some IP layer for further processing. |
518 | */ | 518 | */ |
519 | 519 | ||
520 | static void x25_asy_receive_buf(struct tty_struct *tty, | 520 | static unsigned int x25_asy_receive_buf(struct tty_struct *tty, |
521 | const unsigned char *cp, char *fp, int count) | 521 | const unsigned char *cp, char *fp, int count) |
522 | { | 522 | { |
523 | struct x25_asy *sl = tty->disc_data; | 523 | struct x25_asy *sl = tty->disc_data; |
524 | int bytes = count; | ||
524 | 525 | ||
525 | if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev)) | 526 | if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev)) |
526 | return; | 527 | return; |
527 | 528 | ||
528 | 529 | ||
529 | /* Read the characters out of the buffer */ | 530 | /* Read the characters out of the buffer */ |
530 | while (count--) { | 531 | while (bytes--) { |
531 | if (fp && *fp++) { | 532 | if (fp && *fp++) { |
532 | if (!test_and_set_bit(SLF_ERROR, &sl->flags)) | 533 | if (!test_and_set_bit(SLF_ERROR, &sl->flags)) |
533 | sl->dev->stats.rx_errors++; | 534 | sl->dev->stats.rx_errors++; |
@@ -536,6 +537,8 @@ static void x25_asy_receive_buf(struct tty_struct *tty, | |||
536 | } | 537 | } |
537 | x25_asy_unesc(sl, *cp++); | 538 | x25_asy_unesc(sl, *cp++); |
538 | } | 539 | } |
540 | |||
541 | return count; | ||
539 | } | 542 | } |
540 | 543 | ||
541 | /* | 544 | /* |
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index bc8ce48f0778..f330338c2f22 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c | |||
@@ -1621,7 +1621,7 @@ static void __devinit detect_and_report_it87(void) | |||
1621 | u8 origval, r; | 1621 | u8 origval, r; |
1622 | if (verbose_probing) | 1622 | if (verbose_probing) |
1623 | printk(KERN_DEBUG "IT8705 Super-IO detection, now testing port 2E ...\n"); | 1623 | printk(KERN_DEBUG "IT8705 Super-IO detection, now testing port 2E ...\n"); |
1624 | if (!request_region(0x2e, 2, __func__)) | 1624 | if (!request_muxed_region(0x2e, 2, __func__)) |
1625 | return; | 1625 | return; |
1626 | origval = inb(0x2e); /* Save original value */ | 1626 | origval = inb(0x2e); /* Save original value */ |
1627 | outb(0x87, 0x2e); | 1627 | outb(0x87, 0x2e); |
diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig index 3fd7199301b6..bd7cc0527999 100644 --- a/drivers/tty/Kconfig +++ b/drivers/tty/Kconfig | |||
@@ -319,3 +319,34 @@ config N_GSM | |||
319 | This line discipline provides support for the GSM MUX protocol and | 319 | This line discipline provides support for the GSM MUX protocol and |
320 | presents the mux as a set of 61 individual tty devices. | 320 | presents the mux as a set of 61 individual tty devices. |
321 | 321 | ||
322 | config TRACE_ROUTER | ||
323 | tristate "Trace data router for MIPI P1149.7 cJTAG standard" | ||
324 | depends on TRACE_SINK | ||
325 | default n | ||
326 | help | ||
327 | The trace router uses the Linux tty line discipline framework to | ||
328 | route trace data coming from a tty port (say UART for example) to | ||
329 | the trace sink line discipline driver and to another tty port (say | ||
330 | USB). This is part of a solution for the MIPI P1149.7, compact JTAG, | ||
331 | standard, which is for debugging mobile devices. The PTI driver in | ||
332 | drivers/misc/pti.c defines the majority of this MIPI solution. | ||
333 | |||
334 | You should select this driver if the target kernel is meant for | ||
335 | a mobile device containing a modem. Then you will need to select | ||
336 | "Trace data sink for MIPI P1149.7 cJTAG standard" line discipline | ||
337 | driver. | ||
338 | |||
339 | config TRACE_SINK | ||
340 | tristate "Trace data sink for MIPI P1149.7 cJTAG standard" | ||
341 | default n | ||
342 | help | ||
343 | The trace sink uses the Linux line discipline framework to receive | ||
344 | trace data coming from the trace router line discipline driver | ||
345 | to a user-defined tty port target, like USB. | ||
346 | This is to provide a way to extract modem trace data on | ||
347 | devices that do not have a PTI HW module, or just need modem | ||
348 | trace data to come out of a different HW output port. | ||
349 | This is part of a solution for the P1149.7, compact JTAG, standard. | ||
350 | |||
351 | If you select this option, you need to select | ||
352 | "Trace data router for MIPI P1149.7 cJTAG standard". | ||
diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile index 690522fcb338..ea89b0bd15fe 100644 --- a/drivers/tty/Makefile +++ b/drivers/tty/Makefile | |||
@@ -6,6 +6,8 @@ obj-$(CONFIG_AUDIT) += tty_audit.o | |||
6 | obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o | 6 | obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o |
7 | obj-$(CONFIG_N_HDLC) += n_hdlc.o | 7 | obj-$(CONFIG_N_HDLC) += n_hdlc.o |
8 | obj-$(CONFIG_N_GSM) += n_gsm.o | 8 | obj-$(CONFIG_N_GSM) += n_gsm.o |
9 | obj-$(CONFIG_TRACE_ROUTER) += n_tracerouter.o | ||
10 | obj-$(CONFIG_TRACE_SINK) += n_tracesink.o | ||
9 | obj-$(CONFIG_R3964) += n_r3964.o | 11 | obj-$(CONFIG_R3964) += n_r3964.o |
10 | 12 | ||
11 | obj-y += vt/ | 13 | obj-y += vt/ |
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index f214e5022472..220579592c20 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/char/amiserial.c | ||
3 | * | ||
4 | * Serial driver for the amiga builtin port. | 2 | * Serial driver for the amiga builtin port. |
5 | * | 3 | * |
6 | * This code was created by taking serial.c version 4.30 from kernel | 4 | * This code was created by taking serial.c version 4.30 from kernel |
diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c index c99728f0cd9f..bfa05e801823 100644 --- a/drivers/tty/cyclades.c +++ b/drivers/tty/cyclades.c | |||
@@ -3,8 +3,6 @@ | |||
3 | #undef Z_EXT_CHARS_IN_BUFFER | 3 | #undef Z_EXT_CHARS_IN_BUFFER |
4 | 4 | ||
5 | /* | 5 | /* |
6 | * linux/drivers/char/cyclades.c | ||
7 | * | ||
8 | * This file contains the driver for the Cyclades async multiport | 6 | * This file contains the driver for the Cyclades async multiport |
9 | * serial boards. | 7 | * serial boards. |
10 | * | 8 | * |
@@ -1445,13 +1443,11 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty) | |||
1445 | { | 1443 | { |
1446 | struct cyclades_card *card; | 1444 | struct cyclades_card *card; |
1447 | unsigned long flags; | 1445 | unsigned long flags; |
1448 | int channel; | ||
1449 | 1446 | ||
1450 | if (!(info->port.flags & ASYNC_INITIALIZED)) | 1447 | if (!(info->port.flags & ASYNC_INITIALIZED)) |
1451 | return; | 1448 | return; |
1452 | 1449 | ||
1453 | card = info->card; | 1450 | card = info->card; |
1454 | channel = info->line - card->first_line; | ||
1455 | if (!cy_is_Z(card)) { | 1451 | if (!cy_is_Z(card)) { |
1456 | spin_lock_irqsave(&card->card_lock, flags); | 1452 | spin_lock_irqsave(&card->card_lock, flags); |
1457 | 1453 | ||
@@ -1476,6 +1472,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty) | |||
1476 | spin_unlock_irqrestore(&card->card_lock, flags); | 1472 | spin_unlock_irqrestore(&card->card_lock, flags); |
1477 | } else { | 1473 | } else { |
1478 | #ifdef CY_DEBUG_OPEN | 1474 | #ifdef CY_DEBUG_OPEN |
1475 | int channel = info->line - card->first_line; | ||
1479 | printk(KERN_DEBUG "cyc shutdown Z card %d, channel %d, " | 1476 | printk(KERN_DEBUG "cyc shutdown Z card %d, channel %d, " |
1480 | "base_addr %p\n", card, channel, card->base_addr); | 1477 | "base_addr %p\n", card, channel, card->base_addr); |
1481 | #endif | 1478 | #endif |
diff --git a/drivers/tty/ipwireless/Makefile b/drivers/tty/ipwireless/Makefile index db80873d7f20..fe2e1730986b 100644 --- a/drivers/tty/ipwireless/Makefile +++ b/drivers/tty/ipwireless/Makefile | |||
@@ -1,6 +1,4 @@ | |||
1 | # | 1 | # |
2 | # drivers/char/pcmcia/ipwireless/Makefile | ||
3 | # | ||
4 | # Makefile for the IPWireless driver | 2 | # Makefile for the IPWireless driver |
5 | # | 3 | # |
6 | 4 | ||
diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index 35b0c38590e6..ba679ce0a774 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c | |||
@@ -371,7 +371,7 @@ static int moxa_ioctl(struct tty_struct *tty, | |||
371 | tmp.cflag = p->cflag; | 371 | tmp.cflag = p->cflag; |
372 | else | 372 | else |
373 | tmp.cflag = ttyp->termios->c_cflag; | 373 | tmp.cflag = ttyp->termios->c_cflag; |
374 | tty_kref_put(tty); | 374 | tty_kref_put(ttyp); |
375 | copy: | 375 | copy: |
376 | if (copy_to_user(argm, &tmp, sizeof(tmp))) | 376 | if (copy_to_user(argm, &tmp, sizeof(tmp))) |
377 | return -EFAULT; | 377 | return -EFAULT; |
@@ -1129,7 +1129,6 @@ static void moxa_shutdown(struct tty_port *port) | |||
1129 | struct moxa_port *ch = container_of(port, struct moxa_port, port); | 1129 | struct moxa_port *ch = container_of(port, struct moxa_port, port); |
1130 | MoxaPortDisable(ch); | 1130 | MoxaPortDisable(ch); |
1131 | MoxaPortFlushData(ch, 2); | 1131 | MoxaPortFlushData(ch, 2); |
1132 | clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); | ||
1133 | } | 1132 | } |
1134 | 1133 | ||
1135 | static int moxa_carrier_raised(struct tty_port *port) | 1134 | static int moxa_carrier_raised(struct tty_port *port) |
@@ -1155,7 +1154,6 @@ static int moxa_open(struct tty_struct *tty, struct file *filp) | |||
1155 | struct moxa_board_conf *brd; | 1154 | struct moxa_board_conf *brd; |
1156 | struct moxa_port *ch; | 1155 | struct moxa_port *ch; |
1157 | int port; | 1156 | int port; |
1158 | int retval; | ||
1159 | 1157 | ||
1160 | port = tty->index; | 1158 | port = tty->index; |
1161 | if (port == MAX_PORTS) { | 1159 | if (port == MAX_PORTS) { |
@@ -1190,10 +1188,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp) | |||
1190 | mutex_unlock(&ch->port.mutex); | 1188 | mutex_unlock(&ch->port.mutex); |
1191 | mutex_unlock(&moxa_openlock); | 1189 | mutex_unlock(&moxa_openlock); |
1192 | 1190 | ||
1193 | retval = tty_port_block_til_ready(&ch->port, tty, filp); | 1191 | return tty_port_block_til_ready(&ch->port, tty, filp); |
1194 | if (retval == 0) | ||
1195 | set_bit(ASYNCB_NORMAL_ACTIVE, &ch->port.flags); | ||
1196 | return retval; | ||
1197 | } | 1192 | } |
1198 | 1193 | ||
1199 | static void moxa_close(struct tty_struct *tty, struct file *filp) | 1194 | static void moxa_close(struct tty_struct *tty, struct file *filp) |
@@ -1207,14 +1202,15 @@ static int moxa_write(struct tty_struct *tty, | |||
1207 | const unsigned char *buf, int count) | 1202 | const unsigned char *buf, int count) |
1208 | { | 1203 | { |
1209 | struct moxa_port *ch = tty->driver_data; | 1204 | struct moxa_port *ch = tty->driver_data; |
1205 | unsigned long flags; | ||
1210 | int len; | 1206 | int len; |
1211 | 1207 | ||
1212 | if (ch == NULL) | 1208 | if (ch == NULL) |
1213 | return 0; | 1209 | return 0; |
1214 | 1210 | ||
1215 | spin_lock_bh(&moxa_lock); | 1211 | spin_lock_irqsave(&moxa_lock, flags); |
1216 | len = MoxaPortWriteData(tty, buf, count); | 1212 | len = MoxaPortWriteData(tty, buf, count); |
1217 | spin_unlock_bh(&moxa_lock); | 1213 | spin_unlock_irqrestore(&moxa_lock, flags); |
1218 | 1214 | ||
1219 | set_bit(LOWWAIT, &ch->statusflags); | 1215 | set_bit(LOWWAIT, &ch->statusflags); |
1220 | return len; | 1216 | return len; |
@@ -1281,10 +1277,8 @@ static int moxa_tiocmset(struct tty_struct *tty, | |||
1281 | unsigned int set, unsigned int clear) | 1277 | unsigned int set, unsigned int clear) |
1282 | { | 1278 | { |
1283 | struct moxa_port *ch; | 1279 | struct moxa_port *ch; |
1284 | int port; | ||
1285 | int dtr, rts; | 1280 | int dtr, rts; |
1286 | 1281 | ||
1287 | port = tty->index; | ||
1288 | mutex_lock(&moxa_openlock); | 1282 | mutex_lock(&moxa_openlock); |
1289 | ch = tty->driver_data; | 1283 | ch = tty->driver_data; |
1290 | if (!ch) { | 1284 | if (!ch) { |
@@ -1756,11 +1750,9 @@ static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio, | |||
1756 | speed_t baud) | 1750 | speed_t baud) |
1757 | { | 1751 | { |
1758 | void __iomem *ofsAddr; | 1752 | void __iomem *ofsAddr; |
1759 | tcflag_t cflag; | ||
1760 | tcflag_t mode = 0; | 1753 | tcflag_t mode = 0; |
1761 | 1754 | ||
1762 | ofsAddr = port->tableAddr; | 1755 | ofsAddr = port->tableAddr; |
1763 | cflag = termio->c_cflag; /* termio->c_cflag */ | ||
1764 | 1756 | ||
1765 | mode = termio->c_cflag & CSIZE; | 1757 | mode = termio->c_cflag & CSIZE; |
1766 | if (mode == CS5) | 1758 | if (mode == CS5) |
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 77623b936538..a4c42a75a3bf 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c | |||
@@ -526,19 +526,6 @@ static int gsm_stuff_frame(const u8 *input, u8 *output, int len) | |||
526 | return olen; | 526 | return olen; |
527 | } | 527 | } |
528 | 528 | ||
529 | static void hex_packet(const unsigned char *p, int len) | ||
530 | { | ||
531 | int i; | ||
532 | for (i = 0; i < len; i++) { | ||
533 | if (i && (i % 16) == 0) { | ||
534 | pr_cont("\n"); | ||
535 | pr_debug(""); | ||
536 | } | ||
537 | pr_cont("%02X ", *p++); | ||
538 | } | ||
539 | pr_cont("\n"); | ||
540 | } | ||
541 | |||
542 | /** | 529 | /** |
543 | * gsm_send - send a control frame | 530 | * gsm_send - send a control frame |
544 | * @gsm: our GSM mux | 531 | * @gsm: our GSM mux |
@@ -685,10 +672,10 @@ static void gsm_data_kick(struct gsm_mux *gsm) | |||
685 | len = msg->len + 2; | 672 | len = msg->len + 2; |
686 | } | 673 | } |
687 | 674 | ||
688 | if (debug & 4) { | 675 | if (debug & 4) |
689 | pr_debug("gsm_data_kick:\n"); | 676 | print_hex_dump_bytes("gsm_data_kick: ", |
690 | hex_packet(gsm->txframe, len); | 677 | DUMP_PREFIX_OFFSET, |
691 | } | 678 | gsm->txframe, len); |
692 | 679 | ||
693 | if (gsm->output(gsm, gsm->txframe + skip_sof, | 680 | if (gsm->output(gsm, gsm->txframe + skip_sof, |
694 | len - skip_sof) < 0) | 681 | len - skip_sof) < 0) |
@@ -2095,10 +2082,9 @@ static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len) | |||
2095 | set_bit(TTY_DO_WRITE_WAKEUP, &gsm->tty->flags); | 2082 | set_bit(TTY_DO_WRITE_WAKEUP, &gsm->tty->flags); |
2096 | return -ENOSPC; | 2083 | return -ENOSPC; |
2097 | } | 2084 | } |
2098 | if (debug & 4) { | 2085 | if (debug & 4) |
2099 | pr_debug("-->%d bytes out\n", len); | 2086 | print_hex_dump_bytes("gsmld_output: ", DUMP_PREFIX_OFFSET, |
2100 | hex_packet(data, len); | 2087 | data, len); |
2101 | } | ||
2102 | gsm->tty->ops->write(gsm->tty, data, len); | 2088 | gsm->tty->ops->write(gsm->tty, data, len); |
2103 | return len; | 2089 | return len; |
2104 | } | 2090 | } |
@@ -2142,8 +2128,8 @@ static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm) | |||
2142 | gsm->tty = NULL; | 2128 | gsm->tty = NULL; |
2143 | } | 2129 | } |
2144 | 2130 | ||
2145 | static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp, | 2131 | static unsigned int gsmld_receive_buf(struct tty_struct *tty, |
2146 | char *fp, int count) | 2132 | const unsigned char *cp, char *fp, int count) |
2147 | { | 2133 | { |
2148 | struct gsm_mux *gsm = tty->disc_data; | 2134 | struct gsm_mux *gsm = tty->disc_data; |
2149 | const unsigned char *dp; | 2135 | const unsigned char *dp; |
@@ -2152,10 +2138,9 @@ static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
2152 | char buf[64]; | 2138 | char buf[64]; |
2153 | char flags; | 2139 | char flags; |
2154 | 2140 | ||
2155 | if (debug & 4) { | 2141 | if (debug & 4) |
2156 | pr_debug("Inbytes %dd\n", count); | 2142 | print_hex_dump_bytes("gsmld_receive: ", DUMP_PREFIX_OFFSET, |
2157 | hex_packet(cp, count); | 2143 | cp, count); |
2158 | } | ||
2159 | 2144 | ||
2160 | for (i = count, dp = cp, f = fp; i; i--, dp++) { | 2145 | for (i = count, dp = cp, f = fp; i; i--, dp++) { |
2161 | flags = *f++; | 2146 | flags = *f++; |
@@ -2177,6 +2162,8 @@ static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
2177 | } | 2162 | } |
2178 | /* FASYNC if needed ? */ | 2163 | /* FASYNC if needed ? */ |
2179 | /* If clogged call tty_throttle(tty); */ | 2164 | /* If clogged call tty_throttle(tty); */ |
2165 | |||
2166 | return count; | ||
2180 | } | 2167 | } |
2181 | 2168 | ||
2182 | /** | 2169 | /** |
diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index cea56033b34c..cac666314aef 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c | |||
@@ -188,8 +188,8 @@ static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp, | |||
188 | poll_table *wait); | 188 | poll_table *wait); |
189 | static int n_hdlc_tty_open(struct tty_struct *tty); | 189 | static int n_hdlc_tty_open(struct tty_struct *tty); |
190 | static void n_hdlc_tty_close(struct tty_struct *tty); | 190 | static void n_hdlc_tty_close(struct tty_struct *tty); |
191 | static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *cp, | 191 | static unsigned int n_hdlc_tty_receive(struct tty_struct *tty, |
192 | char *fp, int count); | 192 | const __u8 *cp, char *fp, int count); |
193 | static void n_hdlc_tty_wakeup(struct tty_struct *tty); | 193 | static void n_hdlc_tty_wakeup(struct tty_struct *tty); |
194 | 194 | ||
195 | #define bset(p,b) ((p)[(b) >> 5] |= (1 << ((b) & 0x1f))) | 195 | #define bset(p,b) ((p)[(b) >> 5] |= (1 << ((b) & 0x1f))) |
@@ -509,8 +509,8 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty) | |||
509 | * Called by tty low level driver when receive data is available. Data is | 509 | * Called by tty low level driver when receive data is available. Data is |
510 | * interpreted as one HDLC frame. | 510 | * interpreted as one HDLC frame. |
511 | */ | 511 | */ |
512 | static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data, | 512 | static unsigned int n_hdlc_tty_receive(struct tty_struct *tty, |
513 | char *flags, int count) | 513 | const __u8 *data, char *flags, int count) |
514 | { | 514 | { |
515 | register struct n_hdlc *n_hdlc = tty2n_hdlc (tty); | 515 | register struct n_hdlc *n_hdlc = tty2n_hdlc (tty); |
516 | register struct n_hdlc_buf *buf; | 516 | register struct n_hdlc_buf *buf; |
@@ -521,20 +521,20 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data, | |||
521 | 521 | ||
522 | /* This can happen if stuff comes in on the backup tty */ | 522 | /* This can happen if stuff comes in on the backup tty */ |
523 | if (!n_hdlc || tty != n_hdlc->tty) | 523 | if (!n_hdlc || tty != n_hdlc->tty) |
524 | return; | 524 | return -ENODEV; |
525 | 525 | ||
526 | /* verify line is using HDLC discipline */ | 526 | /* verify line is using HDLC discipline */ |
527 | if (n_hdlc->magic != HDLC_MAGIC) { | 527 | if (n_hdlc->magic != HDLC_MAGIC) { |
528 | printk("%s(%d) line not using HDLC discipline\n", | 528 | printk("%s(%d) line not using HDLC discipline\n", |
529 | __FILE__,__LINE__); | 529 | __FILE__,__LINE__); |
530 | return; | 530 | return -EINVAL; |
531 | } | 531 | } |
532 | 532 | ||
533 | if ( count>maxframe ) { | 533 | if ( count>maxframe ) { |
534 | if (debuglevel >= DEBUG_LEVEL_INFO) | 534 | if (debuglevel >= DEBUG_LEVEL_INFO) |
535 | printk("%s(%d) rx count>maxframesize, data discarded\n", | 535 | printk("%s(%d) rx count>maxframesize, data discarded\n", |
536 | __FILE__,__LINE__); | 536 | __FILE__,__LINE__); |
537 | return; | 537 | return -EINVAL; |
538 | } | 538 | } |
539 | 539 | ||
540 | /* get a free HDLC buffer */ | 540 | /* get a free HDLC buffer */ |
@@ -550,7 +550,7 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data, | |||
550 | if (debuglevel >= DEBUG_LEVEL_INFO) | 550 | if (debuglevel >= DEBUG_LEVEL_INFO) |
551 | printk("%s(%d) no more rx buffers, data discarded\n", | 551 | printk("%s(%d) no more rx buffers, data discarded\n", |
552 | __FILE__,__LINE__); | 552 | __FILE__,__LINE__); |
553 | return; | 553 | return -EINVAL; |
554 | } | 554 | } |
555 | 555 | ||
556 | /* copy received data to HDLC buffer */ | 556 | /* copy received data to HDLC buffer */ |
@@ -565,6 +565,8 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data, | |||
565 | if (n_hdlc->tty->fasync != NULL) | 565 | if (n_hdlc->tty->fasync != NULL) |
566 | kill_fasync (&n_hdlc->tty->fasync, SIGIO, POLL_IN); | 566 | kill_fasync (&n_hdlc->tty->fasync, SIGIO, POLL_IN); |
567 | 567 | ||
568 | return count; | ||
569 | |||
568 | } /* end of n_hdlc_tty_receive() */ | 570 | } /* end of n_hdlc_tty_receive() */ |
569 | 571 | ||
570 | /** | 572 | /** |
diff --git a/drivers/tty/n_r3964.c b/drivers/tty/n_r3964.c index 5c6c31459a2f..a4bc39c21a43 100644 --- a/drivers/tty/n_r3964.c +++ b/drivers/tty/n_r3964.c | |||
@@ -139,8 +139,8 @@ static int r3964_ioctl(struct tty_struct *tty, struct file *file, | |||
139 | static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old); | 139 | static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old); |
140 | static unsigned int r3964_poll(struct tty_struct *tty, struct file *file, | 140 | static unsigned int r3964_poll(struct tty_struct *tty, struct file *file, |
141 | struct poll_table_struct *wait); | 141 | struct poll_table_struct *wait); |
142 | static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, | 142 | static unsigned int r3964_receive_buf(struct tty_struct *tty, |
143 | char *fp, int count); | 143 | const unsigned char *cp, char *fp, int count); |
144 | 144 | ||
145 | static struct tty_ldisc_ops tty_ldisc_N_R3964 = { | 145 | static struct tty_ldisc_ops tty_ldisc_N_R3964 = { |
146 | .owner = THIS_MODULE, | 146 | .owner = THIS_MODULE, |
@@ -1239,8 +1239,8 @@ static unsigned int r3964_poll(struct tty_struct *tty, struct file *file, | |||
1239 | return result; | 1239 | return result; |
1240 | } | 1240 | } |
1241 | 1241 | ||
1242 | static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, | 1242 | static unsigned int r3964_receive_buf(struct tty_struct *tty, |
1243 | char *fp, int count) | 1243 | const unsigned char *cp, char *fp, int count) |
1244 | { | 1244 | { |
1245 | struct r3964_info *pInfo = tty->disc_data; | 1245 | struct r3964_info *pInfo = tty->disc_data; |
1246 | const unsigned char *p; | 1246 | const unsigned char *p; |
@@ -1257,6 +1257,8 @@ static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
1257 | } | 1257 | } |
1258 | 1258 | ||
1259 | } | 1259 | } |
1260 | |||
1261 | return count; | ||
1260 | } | 1262 | } |
1261 | 1263 | ||
1262 | MODULE_LICENSE("GPL"); | 1264 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/tty/n_tracerouter.c b/drivers/tty/n_tracerouter.c new file mode 100644 index 000000000000..1f063d3aa32f --- /dev/null +++ b/drivers/tty/n_tracerouter.c | |||
@@ -0,0 +1,243 @@ | |||
1 | /* | ||
2 | * n_tracerouter.c - Trace data router through tty space | ||
3 | * | ||
4 | * Copyright (C) Intel 2011 | ||
5 | * | ||
6 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 | ||
10 | * as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
18 | * | ||
19 | * This trace router uses the Linux line discipline framework to route | ||
20 | * trace data coming from a HW Modem to a PTI (Parallel Trace Module) port. | ||
21 | * The solution is not specific to a HW modem and this line disciple can | ||
22 | * be used to route any stream of data in kernel space. | ||
23 | * This is part of a solution for the P1149.7, compact JTAG, standard. | ||
24 | */ | ||
25 | |||
26 | #include <linux/init.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/types.h> | ||
30 | #include <linux/ioctl.h> | ||
31 | #include <linux/tty.h> | ||
32 | #include <linux/tty_ldisc.h> | ||
33 | #include <linux/errno.h> | ||
34 | #include <linux/string.h> | ||
35 | #include <linux/mutex.h> | ||
36 | #include <linux/slab.h> | ||
37 | #include <asm-generic/bug.h> | ||
38 | #include "n_tracesink.h" | ||
39 | |||
40 | /* | ||
41 | * Other ldisc drivers use 65536 which basically means, | ||
42 | * 'I can always accept 64k' and flow control is off. | ||
43 | * This number is deemed appropriate for this driver. | ||
44 | */ | ||
45 | #define RECEIVE_ROOM 65536 | ||
46 | #define DRIVERNAME "n_tracerouter" | ||
47 | |||
48 | /* | ||
49 | * struct to hold private configuration data for this ldisc. | ||
50 | * opencalled is used to hold if this ldisc has been opened. | ||
51 | * kref_tty holds the tty reference the ldisc sits on top of. | ||
52 | */ | ||
53 | struct tracerouter_data { | ||
54 | u8 opencalled; | ||
55 | struct tty_struct *kref_tty; | ||
56 | }; | ||
57 | static struct tracerouter_data *tr_data; | ||
58 | |||
59 | /* lock for when tty reference is being used */ | ||
60 | static DEFINE_MUTEX(routelock); | ||
61 | |||
62 | /** | ||
63 | * n_tracerouter_open() - Called when a tty is opened by a SW entity. | ||
64 | * @tty: terminal device to the ldisc. | ||
65 | * | ||
66 | * Return: | ||
67 | * 0 for success. | ||
68 | * | ||
69 | * Caveats: This should only be opened one time per SW entity. | ||
70 | */ | ||
71 | static int n_tracerouter_open(struct tty_struct *tty) | ||
72 | { | ||
73 | int retval = -EEXIST; | ||
74 | |||
75 | mutex_lock(&routelock); | ||
76 | if (tr_data->opencalled == 0) { | ||
77 | |||
78 | tr_data->kref_tty = tty_kref_get(tty); | ||
79 | if (tr_data->kref_tty == NULL) { | ||
80 | retval = -EFAULT; | ||
81 | } else { | ||
82 | tr_data->opencalled = 1; | ||
83 | tty->disc_data = tr_data; | ||
84 | tty->receive_room = RECEIVE_ROOM; | ||
85 | tty_driver_flush_buffer(tty); | ||
86 | retval = 0; | ||
87 | } | ||
88 | } | ||
89 | mutex_unlock(&routelock); | ||
90 | return retval; | ||
91 | } | ||
92 | |||
93 | /** | ||
94 | * n_tracerouter_close() - close connection | ||
95 | * @tty: terminal device to the ldisc. | ||
96 | * | ||
97 | * Called when a software entity wants to close a connection. | ||
98 | */ | ||
99 | static void n_tracerouter_close(struct tty_struct *tty) | ||
100 | { | ||
101 | struct tracerouter_data *tptr = tty->disc_data; | ||
102 | |||
103 | mutex_lock(&routelock); | ||
104 | WARN_ON(tptr->kref_tty != tr_data->kref_tty); | ||
105 | tty_driver_flush_buffer(tty); | ||
106 | tty_kref_put(tr_data->kref_tty); | ||
107 | tr_data->kref_tty = NULL; | ||
108 | tr_data->opencalled = 0; | ||
109 | tty->disc_data = NULL; | ||
110 | mutex_unlock(&routelock); | ||
111 | } | ||
112 | |||
113 | /** | ||
114 | * n_tracerouter_read() - read request from user space | ||
115 | * @tty: terminal device passed into the ldisc. | ||
116 | * @file: pointer to open file object. | ||
117 | * @buf: pointer to the data buffer that gets eventually returned. | ||
118 | * @nr: number of bytes of the data buffer that is returned. | ||
119 | * | ||
120 | * function that allows read() functionality in userspace. By default if this | ||
121 | * is not implemented it returns -EIO. This module is functioning like a | ||
122 | * router via n_tracerouter_receivebuf(), and there is no real requirement | ||
123 | * to implement this function. However, an error return value other than | ||
124 | * -EIO should be used just to show that there was an intent not to have | ||
125 | * this function implemented. Return value based on read() man pages. | ||
126 | * | ||
127 | * Return: | ||
128 | * -EINVAL | ||
129 | */ | ||
130 | static ssize_t n_tracerouter_read(struct tty_struct *tty, struct file *file, | ||
131 | unsigned char __user *buf, size_t nr) { | ||
132 | return -EINVAL; | ||
133 | } | ||
134 | |||
135 | /** | ||
136 | * n_tracerouter_write() - Function that allows write() in userspace. | ||
137 | * @tty: terminal device passed into the ldisc. | ||
138 | * @file: pointer to open file object. | ||
139 | * @buf: pointer to the data buffer that gets eventually returned. | ||
140 | * @nr: number of bytes of the data buffer that is returned. | ||
141 | * | ||
142 | * By default if this is not implemented, it returns -EIO. | ||
143 | * This should not be implemented, ever, because | ||
144 | * 1. this driver is functioning like a router via | ||
145 | * n_tracerouter_receivebuf() | ||
146 | * 2. No writes to HW will ever go through this line discpline driver. | ||
147 | * However, an error return value other than -EIO should be used | ||
148 | * just to show that there was an intent not to have this function | ||
149 | * implemented. Return value based on write() man pages. | ||
150 | * | ||
151 | * Return: | ||
152 | * -EINVAL | ||
153 | */ | ||
154 | static ssize_t n_tracerouter_write(struct tty_struct *tty, struct file *file, | ||
155 | const unsigned char *buf, size_t nr) { | ||
156 | return -EINVAL; | ||
157 | } | ||
158 | |||
159 | /** | ||
160 | * n_tracerouter_receivebuf() - Routing function for driver. | ||
161 | * @tty: terminal device passed into the ldisc. It's assumed | ||
162 | * tty will never be NULL. | ||
163 | * @cp: buffer, block of characters to be eventually read by | ||
164 | * someone, somewhere (user read() call or some kernel function). | ||
165 | * @fp: flag buffer. | ||
166 | * @count: number of characters (aka, bytes) in cp. | ||
167 | * | ||
168 | * This function takes the input buffer, cp, and passes it to | ||
169 | * an external API function for processing. | ||
170 | */ | ||
171 | static void n_tracerouter_receivebuf(struct tty_struct *tty, | ||
172 | const unsigned char *cp, | ||
173 | char *fp, int count) | ||
174 | { | ||
175 | mutex_lock(&routelock); | ||
176 | n_tracesink_datadrain((u8 *) cp, count); | ||
177 | mutex_unlock(&routelock); | ||
178 | } | ||
179 | |||
180 | /* | ||
181 | * Flush buffer is not impelemented as the ldisc has no internal buffering | ||
182 | * so the tty_driver_flush_buffer() is sufficient for this driver's needs. | ||
183 | */ | ||
184 | |||
185 | static struct tty_ldisc_ops tty_ptirouter_ldisc = { | ||
186 | .owner = THIS_MODULE, | ||
187 | .magic = TTY_LDISC_MAGIC, | ||
188 | .name = DRIVERNAME, | ||
189 | .open = n_tracerouter_open, | ||
190 | .close = n_tracerouter_close, | ||
191 | .read = n_tracerouter_read, | ||
192 | .write = n_tracerouter_write, | ||
193 | .receive_buf = n_tracerouter_receivebuf | ||
194 | }; | ||
195 | |||
196 | /** | ||
197 | * n_tracerouter_init - module initialisation | ||
198 | * | ||
199 | * Registers this module as a line discipline driver. | ||
200 | * | ||
201 | * Return: | ||
202 | * 0 for success, any other value error. | ||
203 | */ | ||
204 | static int __init n_tracerouter_init(void) | ||
205 | { | ||
206 | int retval; | ||
207 | |||
208 | tr_data = kzalloc(sizeof(struct tracerouter_data), GFP_KERNEL); | ||
209 | if (tr_data == NULL) | ||
210 | return -ENOMEM; | ||
211 | |||
212 | |||
213 | /* Note N_TRACEROUTER is defined in linux/tty.h */ | ||
214 | retval = tty_register_ldisc(N_TRACEROUTER, &tty_ptirouter_ldisc); | ||
215 | if (retval < 0) { | ||
216 | pr_err("%s: Registration failed: %d\n", __func__, retval); | ||
217 | kfree(tr_data); | ||
218 | } | ||
219 | return retval; | ||
220 | } | ||
221 | |||
222 | /** | ||
223 | * n_tracerouter_exit - module unload | ||
224 | * | ||
225 | * Removes this module as a line discipline driver. | ||
226 | */ | ||
227 | static void __exit n_tracerouter_exit(void) | ||
228 | { | ||
229 | int retval = tty_unregister_ldisc(N_TRACEROUTER); | ||
230 | |||
231 | if (retval < 0) | ||
232 | pr_err("%s: Unregistration failed: %d\n", __func__, retval); | ||
233 | else | ||
234 | kfree(tr_data); | ||
235 | } | ||
236 | |||
237 | module_init(n_tracerouter_init); | ||
238 | module_exit(n_tracerouter_exit); | ||
239 | |||
240 | MODULE_LICENSE("GPL"); | ||
241 | MODULE_AUTHOR("Jay Freyensee"); | ||
242 | MODULE_ALIAS_LDISC(N_TRACEROUTER); | ||
243 | MODULE_DESCRIPTION("Trace router ldisc driver"); | ||
diff --git a/drivers/tty/n_tracesink.c b/drivers/tty/n_tracesink.c new file mode 100644 index 000000000000..ddce58b973d2 --- /dev/null +++ b/drivers/tty/n_tracesink.c | |||
@@ -0,0 +1,238 @@ | |||
1 | /* | ||
2 | * n_tracesink.c - Trace data router and sink path through tty space. | ||
3 | * | ||
4 | * Copyright (C) Intel 2011 | ||
5 | * | ||
6 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 | ||
10 | * as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
18 | * | ||
19 | * The trace sink uses the Linux line discipline framework to receive | ||
20 | * trace data coming from the PTI source line discipline driver | ||
21 | * to a user-desired tty port, like USB. | ||
22 | * This is to provide a way to extract modem trace data on | ||
23 | * devices that do not have a PTI HW module, or just need modem | ||
24 | * trace data to come out of a different HW output port. | ||
25 | * This is part of a solution for the P1149.7, compact JTAG, standard. | ||
26 | */ | ||
27 | |||
28 | #include <linux/init.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/types.h> | ||
32 | #include <linux/ioctl.h> | ||
33 | #include <linux/tty.h> | ||
34 | #include <linux/tty_ldisc.h> | ||
35 | #include <linux/errno.h> | ||
36 | #include <linux/string.h> | ||
37 | #include <asm-generic/bug.h> | ||
38 | #include "n_tracesink.h" | ||
39 | |||
40 | /* | ||
41 | * Other ldisc drivers use 65536 which basically means, | ||
42 | * 'I can always accept 64k' and flow control is off. | ||
43 | * This number is deemed appropriate for this driver. | ||
44 | */ | ||
45 | #define RECEIVE_ROOM 65536 | ||
46 | #define DRIVERNAME "n_tracesink" | ||
47 | |||
48 | /* | ||
49 | * there is a quirk with this ldisc is he can write data | ||
50 | * to a tty from anyone calling his kernel API, which | ||
51 | * meets customer requirements in the drivers/misc/pti.c | ||
52 | * project. So he needs to know when he can and cannot write when | ||
53 | * the API is called. In theory, the API can be called | ||
54 | * after an init() but before a successful open() which | ||
55 | * would crash the system if tty is not checked. | ||
56 | */ | ||
57 | static struct tty_struct *this_tty; | ||
58 | static DEFINE_MUTEX(writelock); | ||
59 | |||
60 | /** | ||
61 | * n_tracesink_open() - Called when a tty is opened by a SW entity. | ||
62 | * @tty: terminal device to the ldisc. | ||
63 | * | ||
64 | * Return: | ||
65 | * 0 for success, | ||
66 | * -EFAULT = couldn't get a tty kref n_tracesink will sit | ||
67 | * on top of | ||
68 | * -EEXIST = open() called successfully once and it cannot | ||
69 | * be called again. | ||
70 | * | ||
71 | * Caveats: open() should only be successful the first time a | ||
72 | * SW entity calls it. | ||
73 | */ | ||
74 | static int n_tracesink_open(struct tty_struct *tty) | ||
75 | { | ||
76 | int retval = -EEXIST; | ||
77 | |||
78 | mutex_lock(&writelock); | ||
79 | if (this_tty == NULL) { | ||
80 | this_tty = tty_kref_get(tty); | ||
81 | if (this_tty == NULL) { | ||
82 | retval = -EFAULT; | ||
83 | } else { | ||
84 | tty->disc_data = this_tty; | ||
85 | tty_driver_flush_buffer(tty); | ||
86 | retval = 0; | ||
87 | } | ||
88 | } | ||
89 | mutex_unlock(&writelock); | ||
90 | |||
91 | return retval; | ||
92 | } | ||
93 | |||
94 | /** | ||
95 | * n_tracesink_close() - close connection | ||
96 | * @tty: terminal device to the ldisc. | ||
97 | * | ||
98 | * Called when a software entity wants to close a connection. | ||
99 | */ | ||
100 | static void n_tracesink_close(struct tty_struct *tty) | ||
101 | { | ||
102 | mutex_lock(&writelock); | ||
103 | tty_driver_flush_buffer(tty); | ||
104 | tty_kref_put(this_tty); | ||
105 | this_tty = NULL; | ||
106 | tty->disc_data = NULL; | ||
107 | mutex_unlock(&writelock); | ||
108 | } | ||
109 | |||
110 | /** | ||
111 | * n_tracesink_read() - read request from user space | ||
112 | * @tty: terminal device passed into the ldisc. | ||
113 | * @file: pointer to open file object. | ||
114 | * @buf: pointer to the data buffer that gets eventually returned. | ||
115 | * @nr: number of bytes of the data buffer that is returned. | ||
116 | * | ||
117 | * function that allows read() functionality in userspace. By default if this | ||
118 | * is not implemented it returns -EIO. This module is functioning like a | ||
119 | * router via n_tracesink_receivebuf(), and there is no real requirement | ||
120 | * to implement this function. However, an error return value other than | ||
121 | * -EIO should be used just to show that there was an intent not to have | ||
122 | * this function implemented. Return value based on read() man pages. | ||
123 | * | ||
124 | * Return: | ||
125 | * -EINVAL | ||
126 | */ | ||
127 | static ssize_t n_tracesink_read(struct tty_struct *tty, struct file *file, | ||
128 | unsigned char __user *buf, size_t nr) { | ||
129 | return -EINVAL; | ||
130 | } | ||
131 | |||
132 | /** | ||
133 | * n_tracesink_write() - Function that allows write() in userspace. | ||
134 | * @tty: terminal device passed into the ldisc. | ||
135 | * @file: pointer to open file object. | ||
136 | * @buf: pointer to the data buffer that gets eventually returned. | ||
137 | * @nr: number of bytes of the data buffer that is returned. | ||
138 | * | ||
139 | * By default if this is not implemented, it returns -EIO. | ||
140 | * This should not be implemented, ever, because | ||
141 | * 1. this driver is functioning like a router via | ||
142 | * n_tracesink_receivebuf() | ||
143 | * 2. No writes to HW will ever go through this line discpline driver. | ||
144 | * However, an error return value other than -EIO should be used | ||
145 | * just to show that there was an intent not to have this function | ||
146 | * implemented. Return value based on write() man pages. | ||
147 | * | ||
148 | * Return: | ||
149 | * -EINVAL | ||
150 | */ | ||
151 | static ssize_t n_tracesink_write(struct tty_struct *tty, struct file *file, | ||
152 | const unsigned char *buf, size_t nr) { | ||
153 | return -EINVAL; | ||
154 | } | ||
155 | |||
156 | /** | ||
157 | * n_tracesink_datadrain() - Kernel API function used to route | ||
158 | * trace debugging data to user-defined | ||
159 | * port like USB. | ||
160 | * | ||
161 | * @buf: Trace debuging data buffer to write to tty target | ||
162 | * port. Null value will return with no write occurring. | ||
163 | * @count: Size of buf. Value of 0 or a negative number will | ||
164 | * return with no write occuring. | ||
165 | * | ||
166 | * Caveat: If this line discipline does not set the tty it sits | ||
167 | * on top of via an open() call, this API function will not | ||
168 | * call the tty's write() call because it will have no pointer | ||
169 | * to call the write(). | ||
170 | */ | ||
171 | void n_tracesink_datadrain(u8 *buf, int count) | ||
172 | { | ||
173 | mutex_lock(&writelock); | ||
174 | |||
175 | if ((buf != NULL) && (count > 0) && (this_tty != NULL)) | ||
176 | this_tty->ops->write(this_tty, buf, count); | ||
177 | |||
178 | mutex_unlock(&writelock); | ||
179 | } | ||
180 | EXPORT_SYMBOL_GPL(n_tracesink_datadrain); | ||
181 | |||
182 | /* | ||
183 | * Flush buffer is not impelemented as the ldisc has no internal buffering | ||
184 | * so the tty_driver_flush_buffer() is sufficient for this driver's needs. | ||
185 | */ | ||
186 | |||
187 | /* | ||
188 | * tty_ldisc function operations for this driver. | ||
189 | */ | ||
190 | static struct tty_ldisc_ops tty_n_tracesink = { | ||
191 | .owner = THIS_MODULE, | ||
192 | .magic = TTY_LDISC_MAGIC, | ||
193 | .name = DRIVERNAME, | ||
194 | .open = n_tracesink_open, | ||
195 | .close = n_tracesink_close, | ||
196 | .read = n_tracesink_read, | ||
197 | .write = n_tracesink_write | ||
198 | }; | ||
199 | |||
200 | /** | ||
201 | * n_tracesink_init- module initialisation | ||
202 | * | ||
203 | * Registers this module as a line discipline driver. | ||
204 | * | ||
205 | * Return: | ||
206 | * 0 for success, any other value error. | ||
207 | */ | ||
208 | static int __init n_tracesink_init(void) | ||
209 | { | ||
210 | /* Note N_TRACESINK is defined in linux/tty.h */ | ||
211 | int retval = tty_register_ldisc(N_TRACESINK, &tty_n_tracesink); | ||
212 | |||
213 | if (retval < 0) | ||
214 | pr_err("%s: Registration failed: %d\n", __func__, retval); | ||
215 | |||
216 | return retval; | ||
217 | } | ||
218 | |||
219 | /** | ||
220 | * n_tracesink_exit - module unload | ||
221 | * | ||
222 | * Removes this module as a line discipline driver. | ||
223 | */ | ||
224 | static void __exit n_tracesink_exit(void) | ||
225 | { | ||
226 | int retval = tty_unregister_ldisc(N_TRACESINK); | ||
227 | |||
228 | if (retval < 0) | ||
229 | pr_err("%s: Unregistration failed: %d\n", __func__, retval); | ||
230 | } | ||
231 | |||
232 | module_init(n_tracesink_init); | ||
233 | module_exit(n_tracesink_exit); | ||
234 | |||
235 | MODULE_LICENSE("GPL"); | ||
236 | MODULE_AUTHOR("Jay Freyensee"); | ||
237 | MODULE_ALIAS_LDISC(N_TRACESINK); | ||
238 | MODULE_DESCRIPTION("Trace sink ldisc driver"); | ||
diff --git a/drivers/tty/n_tracesink.h b/drivers/tty/n_tracesink.h new file mode 100644 index 000000000000..a68bb44f1ef5 --- /dev/null +++ b/drivers/tty/n_tracesink.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | * n_tracesink.h - Kernel driver API to route trace data in kernel space. | ||
3 | * | ||
4 | * Copyright (C) Intel 2011 | ||
5 | * | ||
6 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 | ||
10 | * as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
18 | * | ||
19 | * The PTI (Parallel Trace Interface) driver directs trace data routed from | ||
20 | * various parts in the system out through the Intel Penwell PTI port and | ||
21 | * out of the mobile device for analysis with a debugging tool | ||
22 | * (Lauterbach, Fido). This is part of a solution for the MIPI P1149.7, | ||
23 | * compact JTAG, standard. | ||
24 | * | ||
25 | * This header file is used by n_tracerouter to be able to send the | ||
26 | * data of it's tty port to the tty port this module sits. This | ||
27 | * mechanism can also be used independent of the PTI module. | ||
28 | * | ||
29 | */ | ||
30 | |||
31 | #ifndef N_TRACESINK_H_ | ||
32 | #define N_TRACESINK_H_ | ||
33 | |||
34 | void n_tracesink_datadrain(u8 *buf, int count); | ||
35 | |||
36 | #endif | ||
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 0ad32888091c..95d0a9c2dd13 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
@@ -81,38 +81,6 @@ static inline int tty_put_user(struct tty_struct *tty, unsigned char x, | |||
81 | return put_user(x, ptr); | 81 | return put_user(x, ptr); |
82 | } | 82 | } |
83 | 83 | ||
84 | /** | ||
85 | * n_tty_set__room - receive space | ||
86 | * @tty: terminal | ||
87 | * | ||
88 | * Called by the driver to find out how much data it is | ||
89 | * permitted to feed to the line discipline without any being lost | ||
90 | * and thus to manage flow control. Not serialized. Answers for the | ||
91 | * "instant". | ||
92 | */ | ||
93 | |||
94 | static void n_tty_set_room(struct tty_struct *tty) | ||
95 | { | ||
96 | /* tty->read_cnt is not read locked ? */ | ||
97 | int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; | ||
98 | int old_left; | ||
99 | |||
100 | /* | ||
101 | * If we are doing input canonicalization, and there are no | ||
102 | * pending newlines, let characters through without limit, so | ||
103 | * that erase characters will be handled. Other excess | ||
104 | * characters will be beeped. | ||
105 | */ | ||
106 | if (left <= 0) | ||
107 | left = tty->icanon && !tty->canon_data; | ||
108 | old_left = tty->receive_room; | ||
109 | tty->receive_room = left; | ||
110 | |||
111 | /* Did this open up the receive buffer? We may need to flip */ | ||
112 | if (left && !old_left) | ||
113 | schedule_work(&tty->buf.work); | ||
114 | } | ||
115 | |||
116 | static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) | 84 | static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) |
117 | { | 85 | { |
118 | if (tty->read_cnt < N_TTY_BUF_SIZE) { | 86 | if (tty->read_cnt < N_TTY_BUF_SIZE) { |
@@ -184,7 +152,6 @@ static void reset_buffer_flags(struct tty_struct *tty) | |||
184 | 152 | ||
185 | tty->canon_head = tty->canon_data = tty->erasing = 0; | 153 | tty->canon_head = tty->canon_data = tty->erasing = 0; |
186 | memset(&tty->read_flags, 0, sizeof tty->read_flags); | 154 | memset(&tty->read_flags, 0, sizeof tty->read_flags); |
187 | n_tty_set_room(tty); | ||
188 | check_unthrottle(tty); | 155 | check_unthrottle(tty); |
189 | } | 156 | } |
190 | 157 | ||
@@ -1360,17 +1327,19 @@ static void n_tty_write_wakeup(struct tty_struct *tty) | |||
1360 | * calls one at a time and in order (or using flush_to_ldisc) | 1327 | * calls one at a time and in order (or using flush_to_ldisc) |
1361 | */ | 1328 | */ |
1362 | 1329 | ||
1363 | static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | 1330 | static unsigned int n_tty_receive_buf(struct tty_struct *tty, |
1364 | char *fp, int count) | 1331 | const unsigned char *cp, char *fp, int count) |
1365 | { | 1332 | { |
1366 | const unsigned char *p; | 1333 | const unsigned char *p; |
1367 | char *f, flags = TTY_NORMAL; | 1334 | char *f, flags = TTY_NORMAL; |
1368 | int i; | 1335 | int i; |
1369 | char buf[64]; | 1336 | char buf[64]; |
1370 | unsigned long cpuflags; | 1337 | unsigned long cpuflags; |
1338 | int left; | ||
1339 | int ret = 0; | ||
1371 | 1340 | ||
1372 | if (!tty->read_buf) | 1341 | if (!tty->read_buf) |
1373 | return; | 1342 | return 0; |
1374 | 1343 | ||
1375 | if (tty->real_raw) { | 1344 | if (tty->real_raw) { |
1376 | spin_lock_irqsave(&tty->read_lock, cpuflags); | 1345 | spin_lock_irqsave(&tty->read_lock, cpuflags); |
@@ -1380,6 +1349,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
1380 | memcpy(tty->read_buf + tty->read_head, cp, i); | 1349 | memcpy(tty->read_buf + tty->read_head, cp, i); |
1381 | tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1); | 1350 | tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1); |
1382 | tty->read_cnt += i; | 1351 | tty->read_cnt += i; |
1352 | ret += i; | ||
1383 | cp += i; | 1353 | cp += i; |
1384 | count -= i; | 1354 | count -= i; |
1385 | 1355 | ||
@@ -1389,8 +1359,10 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
1389 | memcpy(tty->read_buf + tty->read_head, cp, i); | 1359 | memcpy(tty->read_buf + tty->read_head, cp, i); |
1390 | tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1); | 1360 | tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1); |
1391 | tty->read_cnt += i; | 1361 | tty->read_cnt += i; |
1362 | ret += i; | ||
1392 | spin_unlock_irqrestore(&tty->read_lock, cpuflags); | 1363 | spin_unlock_irqrestore(&tty->read_lock, cpuflags); |
1393 | } else { | 1364 | } else { |
1365 | ret = count; | ||
1394 | for (i = count, p = cp, f = fp; i; i--, p++) { | 1366 | for (i = count, p = cp, f = fp; i; i--, p++) { |
1395 | if (f) | 1367 | if (f) |
1396 | flags = *f++; | 1368 | flags = *f++; |
@@ -1418,8 +1390,6 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
1418 | tty->ops->flush_chars(tty); | 1390 | tty->ops->flush_chars(tty); |
1419 | } | 1391 | } |
1420 | 1392 | ||
1421 | n_tty_set_room(tty); | ||
1422 | |||
1423 | if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) || | 1393 | if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) || |
1424 | L_EXTPROC(tty)) { | 1394 | L_EXTPROC(tty)) { |
1425 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); | 1395 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); |
@@ -1432,8 +1402,12 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
1432 | * mode. We don't want to throttle the driver if we're in | 1402 | * mode. We don't want to throttle the driver if we're in |
1433 | * canonical mode and don't have a newline yet! | 1403 | * canonical mode and don't have a newline yet! |
1434 | */ | 1404 | */ |
1435 | if (tty->receive_room < TTY_THRESHOLD_THROTTLE) | 1405 | left = N_TTY_BUF_SIZE - tty->read_cnt - 1; |
1406 | |||
1407 | if (left < TTY_THRESHOLD_THROTTLE) | ||
1436 | tty_throttle(tty); | 1408 | tty_throttle(tty); |
1409 | |||
1410 | return ret; | ||
1437 | } | 1411 | } |
1438 | 1412 | ||
1439 | int is_ignored(int sig) | 1413 | int is_ignored(int sig) |
@@ -1477,7 +1451,6 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
1477 | if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { | 1451 | if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { |
1478 | tty->raw = 1; | 1452 | tty->raw = 1; |
1479 | tty->real_raw = 1; | 1453 | tty->real_raw = 1; |
1480 | n_tty_set_room(tty); | ||
1481 | return; | 1454 | return; |
1482 | } | 1455 | } |
1483 | if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) || | 1456 | if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) || |
@@ -1530,7 +1503,6 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
1530 | else | 1503 | else |
1531 | tty->real_raw = 0; | 1504 | tty->real_raw = 0; |
1532 | } | 1505 | } |
1533 | n_tty_set_room(tty); | ||
1534 | /* The termios change make the tty ready for I/O */ | 1506 | /* The termios change make the tty ready for I/O */ |
1535 | wake_up_interruptible(&tty->write_wait); | 1507 | wake_up_interruptible(&tty->write_wait); |
1536 | wake_up_interruptible(&tty->read_wait); | 1508 | wake_up_interruptible(&tty->read_wait); |
@@ -1812,8 +1784,6 @@ do_it_again: | |||
1812 | retval = -ERESTARTSYS; | 1784 | retval = -ERESTARTSYS; |
1813 | break; | 1785 | break; |
1814 | } | 1786 | } |
1815 | /* FIXME: does n_tty_set_room need locking ? */ | ||
1816 | n_tty_set_room(tty); | ||
1817 | timeout = schedule_timeout(timeout); | 1787 | timeout = schedule_timeout(timeout); |
1818 | continue; | 1788 | continue; |
1819 | } | 1789 | } |
@@ -1885,10 +1855,8 @@ do_it_again: | |||
1885 | * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode, | 1855 | * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode, |
1886 | * we won't get any more characters. | 1856 | * we won't get any more characters. |
1887 | */ | 1857 | */ |
1888 | if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) { | 1858 | if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) |
1889 | n_tty_set_room(tty); | ||
1890 | check_unthrottle(tty); | 1859 | check_unthrottle(tty); |
1891 | } | ||
1892 | 1860 | ||
1893 | if (b - buf >= minimum) | 1861 | if (b - buf >= minimum) |
1894 | break; | 1862 | break; |
@@ -1910,7 +1878,6 @@ do_it_again: | |||
1910 | } else if (test_and_clear_bit(TTY_PUSH, &tty->flags)) | 1878 | } else if (test_and_clear_bit(TTY_PUSH, &tty->flags)) |
1911 | goto do_it_again; | 1879 | goto do_it_again; |
1912 | 1880 | ||
1913 | n_tty_set_room(tty); | ||
1914 | return retval; | 1881 | return retval; |
1915 | } | 1882 | } |
1916 | 1883 | ||
diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index fd0a98524d51..b1aecc7bb32a 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c | |||
@@ -364,8 +364,6 @@ struct port { | |||
364 | u8 toggle_ul; | 364 | u8 toggle_ul; |
365 | u16 token_dl; | 365 | u16 token_dl; |
366 | 366 | ||
367 | /* mutex to ensure one access patch to this port */ | ||
368 | struct mutex tty_sem; | ||
369 | wait_queue_head_t tty_wait; | 367 | wait_queue_head_t tty_wait; |
370 | struct async_icount tty_icount; | 368 | struct async_icount tty_icount; |
371 | 369 | ||
@@ -1431,8 +1429,8 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
1431 | } | 1429 | } |
1432 | 1430 | ||
1433 | for (i = PORT_MDM; i < MAX_PORT; i++) { | 1431 | for (i = PORT_MDM; i < MAX_PORT; i++) { |
1434 | if (kfifo_alloc(&dc->port[i].fifo_ul, | 1432 | if (kfifo_alloc(&dc->port[i].fifo_ul, FIFO_BUFFER_SIZE_UL, |
1435 | FIFO_BUFFER_SIZE_UL, GFP_ATOMIC)) { | 1433 | GFP_KERNEL)) { |
1436 | dev_err(&pdev->dev, | 1434 | dev_err(&pdev->dev, |
1437 | "Could not allocate kfifo buffer\n"); | 1435 | "Could not allocate kfifo buffer\n"); |
1438 | ret = -ENOMEM; | 1436 | ret = -ENOMEM; |
@@ -1474,7 +1472,6 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
1474 | struct device *tty_dev; | 1472 | struct device *tty_dev; |
1475 | struct port *port = &dc->port[i]; | 1473 | struct port *port = &dc->port[i]; |
1476 | port->dc = dc; | 1474 | port->dc = dc; |
1477 | mutex_init(&port->tty_sem); | ||
1478 | tty_port_init(&port->port); | 1475 | tty_port_init(&port->port); |
1479 | port->port.ops = &noz_tty_port_ops; | 1476 | port->port.ops = &noz_tty_port_ops; |
1480 | tty_dev = tty_register_device(ntty_driver, dc->index_start + i, | 1477 | tty_dev = tty_register_device(ntty_driver, dc->index_start + i, |
@@ -1688,13 +1685,6 @@ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer, | |||
1688 | if (!dc || !port) | 1685 | if (!dc || !port) |
1689 | return -ENODEV; | 1686 | return -ENODEV; |
1690 | 1687 | ||
1691 | mutex_lock(&port->tty_sem); | ||
1692 | |||
1693 | if (unlikely(!port->port.count)) { | ||
1694 | DBG1(" "); | ||
1695 | goto exit; | ||
1696 | } | ||
1697 | |||
1698 | rval = kfifo_in(&port->fifo_ul, (unsigned char *)buffer, count); | 1688 | rval = kfifo_in(&port->fifo_ul, (unsigned char *)buffer, count); |
1699 | 1689 | ||
1700 | /* notify card */ | 1690 | /* notify card */ |
@@ -1719,7 +1709,6 @@ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer, | |||
1719 | spin_unlock_irqrestore(&dc->spin_mutex, flags); | 1709 | spin_unlock_irqrestore(&dc->spin_mutex, flags); |
1720 | 1710 | ||
1721 | exit: | 1711 | exit: |
1722 | mutex_unlock(&port->tty_sem); | ||
1723 | return rval; | 1712 | return rval; |
1724 | } | 1713 | } |
1725 | 1714 | ||
@@ -1738,12 +1727,9 @@ static int ntty_write_room(struct tty_struct *tty) | |||
1738 | int room = 4096; | 1727 | int room = 4096; |
1739 | const struct nozomi *dc = get_dc_by_tty(tty); | 1728 | const struct nozomi *dc = get_dc_by_tty(tty); |
1740 | 1729 | ||
1741 | if (dc) { | 1730 | if (dc) |
1742 | mutex_lock(&port->tty_sem); | 1731 | room = kfifo_avail(&port->fifo_ul); |
1743 | if (port->port.count) | 1732 | |
1744 | room = kfifo_avail(&port->fifo_ul); | ||
1745 | mutex_unlock(&port->tty_sem); | ||
1746 | } | ||
1747 | return room; | 1733 | return room; |
1748 | } | 1734 | } |
1749 | 1735 | ||
@@ -1889,11 +1875,6 @@ static s32 ntty_chars_in_buffer(struct tty_struct *tty) | |||
1889 | goto exit_in_buffer; | 1875 | goto exit_in_buffer; |
1890 | } | 1876 | } |
1891 | 1877 | ||
1892 | if (unlikely(!port->port.count)) { | ||
1893 | dev_err(&dc->pdev->dev, "No tty open?\n"); | ||
1894 | goto exit_in_buffer; | ||
1895 | } | ||
1896 | |||
1897 | rval = kfifo_len(&port->fifo_ul); | 1878 | rval = kfifo_len(&port->fifo_ul); |
1898 | 1879 | ||
1899 | exit_in_buffer: | 1880 | exit_in_buffer: |
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 210774726add..98b6e3bdb000 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/char/pty.c | ||
3 | * | ||
4 | * Copyright (C) 1991, 1992 Linus Torvalds | 2 | * Copyright (C) 1991, 1992 Linus Torvalds |
5 | * | 3 | * |
6 | * Added support for a Unix98-style ptmx device. | 4 | * Added support for a Unix98-style ptmx device. |
@@ -295,8 +293,8 @@ static int pty_install(struct tty_driver *driver, struct tty_struct *tty) | |||
295 | return -ENOMEM; | 293 | return -ENOMEM; |
296 | if (!try_module_get(driver->other->owner)) { | 294 | if (!try_module_get(driver->other->owner)) { |
297 | /* This cannot in fact currently happen */ | 295 | /* This cannot in fact currently happen */ |
298 | free_tty_struct(o_tty); | 296 | retval = -ENOMEM; |
299 | return -ENOMEM; | 297 | goto err_free_tty; |
300 | } | 298 | } |
301 | initialize_tty_struct(o_tty, driver->other, idx); | 299 | initialize_tty_struct(o_tty, driver->other, idx); |
302 | 300 | ||
@@ -304,13 +302,11 @@ static int pty_install(struct tty_driver *driver, struct tty_struct *tty) | |||
304 | the easy way .. */ | 302 | the easy way .. */ |
305 | retval = tty_init_termios(tty); | 303 | retval = tty_init_termios(tty); |
306 | if (retval) | 304 | if (retval) |
307 | goto free_mem_out; | 305 | goto err_deinit_tty; |
308 | 306 | ||
309 | retval = tty_init_termios(o_tty); | 307 | retval = tty_init_termios(o_tty); |
310 | if (retval) { | 308 | if (retval) |
311 | tty_free_termios(tty); | 309 | goto err_free_termios; |
312 | goto free_mem_out; | ||
313 | } | ||
314 | 310 | ||
315 | /* | 311 | /* |
316 | * Everything allocated ... set up the o_tty structure. | 312 | * Everything allocated ... set up the o_tty structure. |
@@ -327,10 +323,14 @@ static int pty_install(struct tty_driver *driver, struct tty_struct *tty) | |||
327 | tty->count++; | 323 | tty->count++; |
328 | driver->ttys[idx] = tty; | 324 | driver->ttys[idx] = tty; |
329 | return 0; | 325 | return 0; |
330 | free_mem_out: | 326 | err_free_termios: |
327 | tty_free_termios(tty); | ||
328 | err_deinit_tty: | ||
329 | deinitialize_tty_struct(o_tty); | ||
331 | module_put(o_tty->driver->owner); | 330 | module_put(o_tty->driver->owner); |
331 | err_free_tty: | ||
332 | free_tty_struct(o_tty); | 332 | free_tty_struct(o_tty); |
333 | return -ENOMEM; | 333 | return retval; |
334 | } | 334 | } |
335 | 335 | ||
336 | static int pty_bsd_ioctl(struct tty_struct *tty, | 336 | static int pty_bsd_ioctl(struct tty_struct *tty, |
@@ -559,20 +559,19 @@ static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty) | |||
559 | return -ENOMEM; | 559 | return -ENOMEM; |
560 | if (!try_module_get(driver->other->owner)) { | 560 | if (!try_module_get(driver->other->owner)) { |
561 | /* This cannot in fact currently happen */ | 561 | /* This cannot in fact currently happen */ |
562 | free_tty_struct(o_tty); | 562 | goto err_free_tty; |
563 | return -ENOMEM; | ||
564 | } | 563 | } |
565 | initialize_tty_struct(o_tty, driver->other, idx); | 564 | initialize_tty_struct(o_tty, driver->other, idx); |
566 | 565 | ||
567 | tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); | 566 | tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); |
568 | if (tty->termios == NULL) | 567 | if (tty->termios == NULL) |
569 | goto free_mem_out; | 568 | goto err_free_mem; |
570 | *tty->termios = driver->init_termios; | 569 | *tty->termios = driver->init_termios; |
571 | tty->termios_locked = tty->termios + 1; | 570 | tty->termios_locked = tty->termios + 1; |
572 | 571 | ||
573 | o_tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); | 572 | o_tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); |
574 | if (o_tty->termios == NULL) | 573 | if (o_tty->termios == NULL) |
575 | goto free_mem_out; | 574 | goto err_free_mem; |
576 | *o_tty->termios = driver->other->init_termios; | 575 | *o_tty->termios = driver->other->init_termios; |
577 | o_tty->termios_locked = o_tty->termios + 1; | 576 | o_tty->termios_locked = o_tty->termios + 1; |
578 | 577 | ||
@@ -591,11 +590,13 @@ static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty) | |||
591 | tty->count++; | 590 | tty->count++; |
592 | pty_count++; | 591 | pty_count++; |
593 | return 0; | 592 | return 0; |
594 | free_mem_out: | 593 | err_free_mem: |
594 | deinitialize_tty_struct(o_tty); | ||
595 | kfree(o_tty->termios); | 595 | kfree(o_tty->termios); |
596 | kfree(tty->termios); | ||
596 | module_put(o_tty->driver->owner); | 597 | module_put(o_tty->driver->owner); |
598 | err_free_tty: | ||
597 | free_tty_struct(o_tty); | 599 | free_tty_struct(o_tty); |
598 | kfree(tty->termios); | ||
599 | return -ENOMEM; | 600 | return -ENOMEM; |
600 | } | 601 | } |
601 | 602 | ||
diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c index 036feeb5e3f6..13043e8d37fe 100644 --- a/drivers/tty/rocket.c +++ b/drivers/tty/rocket.c | |||
@@ -1380,7 +1380,6 @@ static void rp_send_xchar(struct tty_struct *tty, char ch) | |||
1380 | static void rp_throttle(struct tty_struct *tty) | 1380 | static void rp_throttle(struct tty_struct *tty) |
1381 | { | 1381 | { |
1382 | struct r_port *info = tty->driver_data; | 1382 | struct r_port *info = tty->driver_data; |
1383 | CHANNEL_t *cp; | ||
1384 | 1383 | ||
1385 | #ifdef ROCKET_DEBUG_THROTTLE | 1384 | #ifdef ROCKET_DEBUG_THROTTLE |
1386 | printk(KERN_INFO "throttle %s: %d....\n", tty->name, | 1385 | printk(KERN_INFO "throttle %s: %d....\n", tty->name, |
@@ -1390,7 +1389,6 @@ static void rp_throttle(struct tty_struct *tty) | |||
1390 | if (rocket_paranoia_check(info, "rp_throttle")) | 1389 | if (rocket_paranoia_check(info, "rp_throttle")) |
1391 | return; | 1390 | return; |
1392 | 1391 | ||
1393 | cp = &info->channel; | ||
1394 | if (I_IXOFF(tty)) | 1392 | if (I_IXOFF(tty)) |
1395 | rp_send_xchar(tty, STOP_CHAR(tty)); | 1393 | rp_send_xchar(tty, STOP_CHAR(tty)); |
1396 | 1394 | ||
@@ -1400,7 +1398,6 @@ static void rp_throttle(struct tty_struct *tty) | |||
1400 | static void rp_unthrottle(struct tty_struct *tty) | 1398 | static void rp_unthrottle(struct tty_struct *tty) |
1401 | { | 1399 | { |
1402 | struct r_port *info = tty->driver_data; | 1400 | struct r_port *info = tty->driver_data; |
1403 | CHANNEL_t *cp; | ||
1404 | #ifdef ROCKET_DEBUG_THROTTLE | 1401 | #ifdef ROCKET_DEBUG_THROTTLE |
1405 | printk(KERN_INFO "unthrottle %s: %d....\n", tty->name, | 1402 | printk(KERN_INFO "unthrottle %s: %d....\n", tty->name, |
1406 | tty->ldisc.chars_in_buffer(tty)); | 1403 | tty->ldisc.chars_in_buffer(tty)); |
@@ -1409,7 +1406,6 @@ static void rp_unthrottle(struct tty_struct *tty) | |||
1409 | if (rocket_paranoia_check(info, "rp_throttle")) | 1406 | if (rocket_paranoia_check(info, "rp_throttle")) |
1410 | return; | 1407 | return; |
1411 | 1408 | ||
1412 | cp = &info->channel; | ||
1413 | if (I_IXOFF(tty)) | 1409 | if (I_IXOFF(tty)) |
1414 | rp_send_xchar(tty, START_CHAR(tty)); | 1410 | rp_send_xchar(tty, START_CHAR(tty)); |
1415 | 1411 | ||
@@ -1722,13 +1718,10 @@ static int rp_write_room(struct tty_struct *tty) | |||
1722 | static int rp_chars_in_buffer(struct tty_struct *tty) | 1718 | static int rp_chars_in_buffer(struct tty_struct *tty) |
1723 | { | 1719 | { |
1724 | struct r_port *info = tty->driver_data; | 1720 | struct r_port *info = tty->driver_data; |
1725 | CHANNEL_t *cp; | ||
1726 | 1721 | ||
1727 | if (rocket_paranoia_check(info, "rp_chars_in_buffer")) | 1722 | if (rocket_paranoia_check(info, "rp_chars_in_buffer")) |
1728 | return 0; | 1723 | return 0; |
1729 | 1724 | ||
1730 | cp = &info->channel; | ||
1731 | |||
1732 | #ifdef ROCKET_DEBUG_WRITE | 1725 | #ifdef ROCKET_DEBUG_WRITE |
1733 | printk(KERN_INFO "rp_chars_in_buffer returns %d...\n", info->xmit_cnt); | 1726 | printk(KERN_INFO "rp_chars_in_buffer returns %d...\n", info->xmit_cnt); |
1734 | #endif | 1727 | #endif |
@@ -1779,7 +1772,6 @@ static __init int register_PCI(int i, struct pci_dev *dev) | |||
1779 | { | 1772 | { |
1780 | int num_aiops, aiop, max_num_aiops, num_chan, chan; | 1773 | int num_aiops, aiop, max_num_aiops, num_chan, chan; |
1781 | unsigned int aiopio[MAX_AIOPS_PER_BOARD]; | 1774 | unsigned int aiopio[MAX_AIOPS_PER_BOARD]; |
1782 | char *str, *board_type; | ||
1783 | CONTROLLER_t *ctlp; | 1775 | CONTROLLER_t *ctlp; |
1784 | 1776 | ||
1785 | int fast_clock = 0; | 1777 | int fast_clock = 0; |
@@ -1800,7 +1792,6 @@ static __init int register_PCI(int i, struct pci_dev *dev) | |||
1800 | /* Depending on the model, set up some config variables */ | 1792 | /* Depending on the model, set up some config variables */ |
1801 | switch (dev->device) { | 1793 | switch (dev->device) { |
1802 | case PCI_DEVICE_ID_RP4QUAD: | 1794 | case PCI_DEVICE_ID_RP4QUAD: |
1803 | str = "Quadcable"; | ||
1804 | max_num_aiops = 1; | 1795 | max_num_aiops = 1; |
1805 | ports_per_aiop = 4; | 1796 | ports_per_aiop = 4; |
1806 | rocketModel[i].model = MODEL_RP4QUAD; | 1797 | rocketModel[i].model = MODEL_RP4QUAD; |
@@ -1808,42 +1799,36 @@ static __init int register_PCI(int i, struct pci_dev *dev) | |||
1808 | rocketModel[i].numPorts = 4; | 1799 | rocketModel[i].numPorts = 4; |
1809 | break; | 1800 | break; |
1810 | case PCI_DEVICE_ID_RP8OCTA: | 1801 | case PCI_DEVICE_ID_RP8OCTA: |
1811 | str = "Octacable"; | ||
1812 | max_num_aiops = 1; | 1802 | max_num_aiops = 1; |
1813 | rocketModel[i].model = MODEL_RP8OCTA; | 1803 | rocketModel[i].model = MODEL_RP8OCTA; |
1814 | strcpy(rocketModel[i].modelString, "RocketPort 8 port w/octa cable"); | 1804 | strcpy(rocketModel[i].modelString, "RocketPort 8 port w/octa cable"); |
1815 | rocketModel[i].numPorts = 8; | 1805 | rocketModel[i].numPorts = 8; |
1816 | break; | 1806 | break; |
1817 | case PCI_DEVICE_ID_URP8OCTA: | 1807 | case PCI_DEVICE_ID_URP8OCTA: |
1818 | str = "Octacable"; | ||
1819 | max_num_aiops = 1; | 1808 | max_num_aiops = 1; |
1820 | rocketModel[i].model = MODEL_UPCI_RP8OCTA; | 1809 | rocketModel[i].model = MODEL_UPCI_RP8OCTA; |
1821 | strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/octa cable"); | 1810 | strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/octa cable"); |
1822 | rocketModel[i].numPorts = 8; | 1811 | rocketModel[i].numPorts = 8; |
1823 | break; | 1812 | break; |
1824 | case PCI_DEVICE_ID_RP8INTF: | 1813 | case PCI_DEVICE_ID_RP8INTF: |
1825 | str = "8"; | ||
1826 | max_num_aiops = 1; | 1814 | max_num_aiops = 1; |
1827 | rocketModel[i].model = MODEL_RP8INTF; | 1815 | rocketModel[i].model = MODEL_RP8INTF; |
1828 | strcpy(rocketModel[i].modelString, "RocketPort 8 port w/external I/F"); | 1816 | strcpy(rocketModel[i].modelString, "RocketPort 8 port w/external I/F"); |
1829 | rocketModel[i].numPorts = 8; | 1817 | rocketModel[i].numPorts = 8; |
1830 | break; | 1818 | break; |
1831 | case PCI_DEVICE_ID_URP8INTF: | 1819 | case PCI_DEVICE_ID_URP8INTF: |
1832 | str = "8"; | ||
1833 | max_num_aiops = 1; | 1820 | max_num_aiops = 1; |
1834 | rocketModel[i].model = MODEL_UPCI_RP8INTF; | 1821 | rocketModel[i].model = MODEL_UPCI_RP8INTF; |
1835 | strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/external I/F"); | 1822 | strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/external I/F"); |
1836 | rocketModel[i].numPorts = 8; | 1823 | rocketModel[i].numPorts = 8; |
1837 | break; | 1824 | break; |
1838 | case PCI_DEVICE_ID_RP8J: | 1825 | case PCI_DEVICE_ID_RP8J: |
1839 | str = "8J"; | ||
1840 | max_num_aiops = 1; | 1826 | max_num_aiops = 1; |
1841 | rocketModel[i].model = MODEL_RP8J; | 1827 | rocketModel[i].model = MODEL_RP8J; |
1842 | strcpy(rocketModel[i].modelString, "RocketPort 8 port w/RJ11 connectors"); | 1828 | strcpy(rocketModel[i].modelString, "RocketPort 8 port w/RJ11 connectors"); |
1843 | rocketModel[i].numPorts = 8; | 1829 | rocketModel[i].numPorts = 8; |
1844 | break; | 1830 | break; |
1845 | case PCI_DEVICE_ID_RP4J: | 1831 | case PCI_DEVICE_ID_RP4J: |
1846 | str = "4J"; | ||
1847 | max_num_aiops = 1; | 1832 | max_num_aiops = 1; |
1848 | ports_per_aiop = 4; | 1833 | ports_per_aiop = 4; |
1849 | rocketModel[i].model = MODEL_RP4J; | 1834 | rocketModel[i].model = MODEL_RP4J; |
@@ -1851,56 +1836,48 @@ static __init int register_PCI(int i, struct pci_dev *dev) | |||
1851 | rocketModel[i].numPorts = 4; | 1836 | rocketModel[i].numPorts = 4; |
1852 | break; | 1837 | break; |
1853 | case PCI_DEVICE_ID_RP8SNI: | 1838 | case PCI_DEVICE_ID_RP8SNI: |
1854 | str = "8 (DB78 Custom)"; | ||
1855 | max_num_aiops = 1; | 1839 | max_num_aiops = 1; |
1856 | rocketModel[i].model = MODEL_RP8SNI; | 1840 | rocketModel[i].model = MODEL_RP8SNI; |
1857 | strcpy(rocketModel[i].modelString, "RocketPort 8 port w/ custom DB78"); | 1841 | strcpy(rocketModel[i].modelString, "RocketPort 8 port w/ custom DB78"); |
1858 | rocketModel[i].numPorts = 8; | 1842 | rocketModel[i].numPorts = 8; |
1859 | break; | 1843 | break; |
1860 | case PCI_DEVICE_ID_RP16SNI: | 1844 | case PCI_DEVICE_ID_RP16SNI: |
1861 | str = "16 (DB78 Custom)"; | ||
1862 | max_num_aiops = 2; | 1845 | max_num_aiops = 2; |
1863 | rocketModel[i].model = MODEL_RP16SNI; | 1846 | rocketModel[i].model = MODEL_RP16SNI; |
1864 | strcpy(rocketModel[i].modelString, "RocketPort 16 port w/ custom DB78"); | 1847 | strcpy(rocketModel[i].modelString, "RocketPort 16 port w/ custom DB78"); |
1865 | rocketModel[i].numPorts = 16; | 1848 | rocketModel[i].numPorts = 16; |
1866 | break; | 1849 | break; |
1867 | case PCI_DEVICE_ID_RP16INTF: | 1850 | case PCI_DEVICE_ID_RP16INTF: |
1868 | str = "16"; | ||
1869 | max_num_aiops = 2; | 1851 | max_num_aiops = 2; |
1870 | rocketModel[i].model = MODEL_RP16INTF; | 1852 | rocketModel[i].model = MODEL_RP16INTF; |
1871 | strcpy(rocketModel[i].modelString, "RocketPort 16 port w/external I/F"); | 1853 | strcpy(rocketModel[i].modelString, "RocketPort 16 port w/external I/F"); |
1872 | rocketModel[i].numPorts = 16; | 1854 | rocketModel[i].numPorts = 16; |
1873 | break; | 1855 | break; |
1874 | case PCI_DEVICE_ID_URP16INTF: | 1856 | case PCI_DEVICE_ID_URP16INTF: |
1875 | str = "16"; | ||
1876 | max_num_aiops = 2; | 1857 | max_num_aiops = 2; |
1877 | rocketModel[i].model = MODEL_UPCI_RP16INTF; | 1858 | rocketModel[i].model = MODEL_UPCI_RP16INTF; |
1878 | strcpy(rocketModel[i].modelString, "RocketPort UPCI 16 port w/external I/F"); | 1859 | strcpy(rocketModel[i].modelString, "RocketPort UPCI 16 port w/external I/F"); |
1879 | rocketModel[i].numPorts = 16; | 1860 | rocketModel[i].numPorts = 16; |
1880 | break; | 1861 | break; |
1881 | case PCI_DEVICE_ID_CRP16INTF: | 1862 | case PCI_DEVICE_ID_CRP16INTF: |
1882 | str = "16"; | ||
1883 | max_num_aiops = 2; | 1863 | max_num_aiops = 2; |
1884 | rocketModel[i].model = MODEL_CPCI_RP16INTF; | 1864 | rocketModel[i].model = MODEL_CPCI_RP16INTF; |
1885 | strcpy(rocketModel[i].modelString, "RocketPort Compact PCI 16 port w/external I/F"); | 1865 | strcpy(rocketModel[i].modelString, "RocketPort Compact PCI 16 port w/external I/F"); |
1886 | rocketModel[i].numPorts = 16; | 1866 | rocketModel[i].numPorts = 16; |
1887 | break; | 1867 | break; |
1888 | case PCI_DEVICE_ID_RP32INTF: | 1868 | case PCI_DEVICE_ID_RP32INTF: |
1889 | str = "32"; | ||
1890 | max_num_aiops = 4; | 1869 | max_num_aiops = 4; |
1891 | rocketModel[i].model = MODEL_RP32INTF; | 1870 | rocketModel[i].model = MODEL_RP32INTF; |
1892 | strcpy(rocketModel[i].modelString, "RocketPort 32 port w/external I/F"); | 1871 | strcpy(rocketModel[i].modelString, "RocketPort 32 port w/external I/F"); |
1893 | rocketModel[i].numPorts = 32; | 1872 | rocketModel[i].numPorts = 32; |
1894 | break; | 1873 | break; |
1895 | case PCI_DEVICE_ID_URP32INTF: | 1874 | case PCI_DEVICE_ID_URP32INTF: |
1896 | str = "32"; | ||
1897 | max_num_aiops = 4; | 1875 | max_num_aiops = 4; |
1898 | rocketModel[i].model = MODEL_UPCI_RP32INTF; | 1876 | rocketModel[i].model = MODEL_UPCI_RP32INTF; |
1899 | strcpy(rocketModel[i].modelString, "RocketPort UPCI 32 port w/external I/F"); | 1877 | strcpy(rocketModel[i].modelString, "RocketPort UPCI 32 port w/external I/F"); |
1900 | rocketModel[i].numPorts = 32; | 1878 | rocketModel[i].numPorts = 32; |
1901 | break; | 1879 | break; |
1902 | case PCI_DEVICE_ID_RPP4: | 1880 | case PCI_DEVICE_ID_RPP4: |
1903 | str = "Plus Quadcable"; | ||
1904 | max_num_aiops = 1; | 1881 | max_num_aiops = 1; |
1905 | ports_per_aiop = 4; | 1882 | ports_per_aiop = 4; |
1906 | altChanRingIndicator++; | 1883 | altChanRingIndicator++; |
@@ -1910,7 +1887,6 @@ static __init int register_PCI(int i, struct pci_dev *dev) | |||
1910 | rocketModel[i].numPorts = 4; | 1887 | rocketModel[i].numPorts = 4; |
1911 | break; | 1888 | break; |
1912 | case PCI_DEVICE_ID_RPP8: | 1889 | case PCI_DEVICE_ID_RPP8: |
1913 | str = "Plus Octacable"; | ||
1914 | max_num_aiops = 2; | 1890 | max_num_aiops = 2; |
1915 | ports_per_aiop = 4; | 1891 | ports_per_aiop = 4; |
1916 | altChanRingIndicator++; | 1892 | altChanRingIndicator++; |
@@ -1920,7 +1896,6 @@ static __init int register_PCI(int i, struct pci_dev *dev) | |||
1920 | rocketModel[i].numPorts = 8; | 1896 | rocketModel[i].numPorts = 8; |
1921 | break; | 1897 | break; |
1922 | case PCI_DEVICE_ID_RP2_232: | 1898 | case PCI_DEVICE_ID_RP2_232: |
1923 | str = "Plus 2 (RS-232)"; | ||
1924 | max_num_aiops = 1; | 1899 | max_num_aiops = 1; |
1925 | ports_per_aiop = 2; | 1900 | ports_per_aiop = 2; |
1926 | altChanRingIndicator++; | 1901 | altChanRingIndicator++; |
@@ -1930,7 +1905,6 @@ static __init int register_PCI(int i, struct pci_dev *dev) | |||
1930 | rocketModel[i].numPorts = 2; | 1905 | rocketModel[i].numPorts = 2; |
1931 | break; | 1906 | break; |
1932 | case PCI_DEVICE_ID_RP2_422: | 1907 | case PCI_DEVICE_ID_RP2_422: |
1933 | str = "Plus 2 (RS-422)"; | ||
1934 | max_num_aiops = 1; | 1908 | max_num_aiops = 1; |
1935 | ports_per_aiop = 2; | 1909 | ports_per_aiop = 2; |
1936 | altChanRingIndicator++; | 1910 | altChanRingIndicator++; |
@@ -1943,7 +1917,6 @@ static __init int register_PCI(int i, struct pci_dev *dev) | |||
1943 | 1917 | ||
1944 | max_num_aiops = 1; | 1918 | max_num_aiops = 1; |
1945 | ports_per_aiop = 6; | 1919 | ports_per_aiop = 6; |
1946 | str = "6-port"; | ||
1947 | 1920 | ||
1948 | /* If revision is 1, the rocketmodem flash must be loaded. | 1921 | /* If revision is 1, the rocketmodem flash must be loaded. |
1949 | * If it is 2 it is a "socketed" version. */ | 1922 | * If it is 2 it is a "socketed" version. */ |
@@ -1961,7 +1934,6 @@ static __init int register_PCI(int i, struct pci_dev *dev) | |||
1961 | case PCI_DEVICE_ID_RP4M: | 1934 | case PCI_DEVICE_ID_RP4M: |
1962 | max_num_aiops = 1; | 1935 | max_num_aiops = 1; |
1963 | ports_per_aiop = 4; | 1936 | ports_per_aiop = 4; |
1964 | str = "4-port"; | ||
1965 | if (dev->revision == 1) { | 1937 | if (dev->revision == 1) { |
1966 | rcktpt_type[i] = ROCKET_TYPE_MODEMII; | 1938 | rcktpt_type[i] = ROCKET_TYPE_MODEMII; |
1967 | rocketModel[i].loadrm2 = 1; | 1939 | rocketModel[i].loadrm2 = 1; |
@@ -1974,7 +1946,6 @@ static __init int register_PCI(int i, struct pci_dev *dev) | |||
1974 | rocketModel[i].numPorts = 4; | 1946 | rocketModel[i].numPorts = 4; |
1975 | break; | 1947 | break; |
1976 | default: | 1948 | default: |
1977 | str = "(unknown/unsupported)"; | ||
1978 | max_num_aiops = 0; | 1949 | max_num_aiops = 0; |
1979 | break; | 1950 | break; |
1980 | } | 1951 | } |
@@ -2000,14 +1971,12 @@ static __init int register_PCI(int i, struct pci_dev *dev) | |||
2000 | if (! | 1971 | if (! |
2001 | (sInW(ConfigIO + _PCI_9030_GPIO_CTRL) & | 1972 | (sInW(ConfigIO + _PCI_9030_GPIO_CTRL) & |
2002 | PCI_GPIO_CTRL_8PORT)) { | 1973 | PCI_GPIO_CTRL_8PORT)) { |
2003 | str = "Quadcable"; | ||
2004 | ports_per_aiop = 4; | 1974 | ports_per_aiop = 4; |
2005 | rocketModel[i].numPorts = 4; | 1975 | rocketModel[i].numPorts = 4; |
2006 | } | 1976 | } |
2007 | } | 1977 | } |
2008 | break; | 1978 | break; |
2009 | case PCI_DEVICE_ID_UPCI_RM3_8PORT: | 1979 | case PCI_DEVICE_ID_UPCI_RM3_8PORT: |
2010 | str = "8 ports"; | ||
2011 | max_num_aiops = 1; | 1980 | max_num_aiops = 1; |
2012 | rocketModel[i].model = MODEL_UPCI_RM3_8PORT; | 1981 | rocketModel[i].model = MODEL_UPCI_RM3_8PORT; |
2013 | strcpy(rocketModel[i].modelString, "RocketModem III 8 port"); | 1982 | strcpy(rocketModel[i].modelString, "RocketModem III 8 port"); |
@@ -2018,7 +1987,6 @@ static __init int register_PCI(int i, struct pci_dev *dev) | |||
2018 | rcktpt_type[i] = ROCKET_TYPE_MODEMIII; | 1987 | rcktpt_type[i] = ROCKET_TYPE_MODEMIII; |
2019 | break; | 1988 | break; |
2020 | case PCI_DEVICE_ID_UPCI_RM3_4PORT: | 1989 | case PCI_DEVICE_ID_UPCI_RM3_4PORT: |
2021 | str = "4 ports"; | ||
2022 | max_num_aiops = 1; | 1990 | max_num_aiops = 1; |
2023 | rocketModel[i].model = MODEL_UPCI_RM3_4PORT; | 1991 | rocketModel[i].model = MODEL_UPCI_RM3_4PORT; |
2024 | strcpy(rocketModel[i].modelString, "RocketModem III 4 port"); | 1992 | strcpy(rocketModel[i].modelString, "RocketModem III 4 port"); |
@@ -2032,21 +2000,6 @@ static __init int register_PCI(int i, struct pci_dev *dev) | |||
2032 | break; | 2000 | break; |
2033 | } | 2001 | } |
2034 | 2002 | ||
2035 | switch (rcktpt_type[i]) { | ||
2036 | case ROCKET_TYPE_MODEM: | ||
2037 | board_type = "RocketModem"; | ||
2038 | break; | ||
2039 | case ROCKET_TYPE_MODEMII: | ||
2040 | board_type = "RocketModem II"; | ||
2041 | break; | ||
2042 | case ROCKET_TYPE_MODEMIII: | ||
2043 | board_type = "RocketModem III"; | ||
2044 | break; | ||
2045 | default: | ||
2046 | board_type = "RocketPort"; | ||
2047 | break; | ||
2048 | } | ||
2049 | |||
2050 | if (fast_clock) { | 2003 | if (fast_clock) { |
2051 | sClockPrescale = 0x12; /* mod 2 (divide by 3) */ | 2004 | sClockPrescale = 0x12; /* mod 2 (divide by 3) */ |
2052 | rp_baud_base[i] = 921600; | 2005 | rp_baud_base[i] = 921600; |
diff --git a/drivers/tty/serial/21285.c b/drivers/tty/serial/21285.c index d89aa38c5cf0..1b37626e8f13 100644 --- a/drivers/tty/serial/21285.c +++ b/drivers/tty/serial/21285.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/serial/21285.c | ||
3 | * | ||
4 | * Driver for the serial port on the 21285 StrongArm-110 core logic chip. | 2 | * Driver for the serial port on the 21285 StrongArm-110 core logic chip. |
5 | * | 3 | * |
6 | * Based on drivers/char/serial.c | 4 | * Based on drivers/char/serial.c |
diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c index 6611535f4440..b40f7b90c81d 100644 --- a/drivers/tty/serial/8250.c +++ b/drivers/tty/serial/8250.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/char/8250.c | ||
3 | * | ||
4 | * Driver for 8250/16550-type serial ports | 2 | * Driver for 8250/16550-type serial ports |
5 | * | 3 | * |
6 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. | 4 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. |
@@ -273,7 +271,7 @@ static const struct serial8250_config uart_config[] = { | |||
273 | .fifo_size = 32, | 271 | .fifo_size = 32, |
274 | .tx_loadsz = 32, | 272 | .tx_loadsz = 32, |
275 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 273 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
276 | .flags = UART_CAP_FIFO | UART_CAP_UUE, | 274 | .flags = UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE, |
277 | }, | 275 | }, |
278 | [PORT_RM9000] = { | 276 | [PORT_RM9000] = { |
279 | .name = "RM9000", | 277 | .name = "RM9000", |
@@ -303,6 +301,14 @@ static const struct serial8250_config uart_config[] = { | |||
303 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 301 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
304 | .flags = UART_CAP_FIFO | UART_CAP_AFE, | 302 | .flags = UART_CAP_FIFO | UART_CAP_AFE, |
305 | }, | 303 | }, |
304 | [PORT_TEGRA] = { | ||
305 | .name = "Tegra", | ||
306 | .fifo_size = 32, | ||
307 | .tx_loadsz = 8, | ||
308 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | | ||
309 | UART_FCR_T_TRIG_01, | ||
310 | .flags = UART_CAP_FIFO | UART_CAP_RTOIE, | ||
311 | }, | ||
306 | }; | 312 | }; |
307 | 313 | ||
308 | #if defined(CONFIG_MIPS_ALCHEMY) | 314 | #if defined(CONFIG_MIPS_ALCHEMY) |
@@ -1427,6 +1433,27 @@ static void serial8250_enable_ms(struct uart_port *port) | |||
1427 | serial_out(up, UART_IER, up->ier); | 1433 | serial_out(up, UART_IER, up->ier); |
1428 | } | 1434 | } |
1429 | 1435 | ||
1436 | /* | ||
1437 | * Clear the Tegra rx fifo after a break | ||
1438 | * | ||
1439 | * FIXME: This needs to become a port specific callback once we have a | ||
1440 | * framework for this | ||
1441 | */ | ||
1442 | static void clear_rx_fifo(struct uart_8250_port *up) | ||
1443 | { | ||
1444 | unsigned int status, tmout = 10000; | ||
1445 | do { | ||
1446 | status = serial_in(up, UART_LSR); | ||
1447 | if (status & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS)) | ||
1448 | status = serial_in(up, UART_RX); | ||
1449 | else | ||
1450 | break; | ||
1451 | if (--tmout == 0) | ||
1452 | break; | ||
1453 | udelay(1); | ||
1454 | } while (1); | ||
1455 | } | ||
1456 | |||
1430 | static void | 1457 | static void |
1431 | receive_chars(struct uart_8250_port *up, unsigned int *status) | 1458 | receive_chars(struct uart_8250_port *up, unsigned int *status) |
1432 | { | 1459 | { |
@@ -1462,6 +1489,13 @@ receive_chars(struct uart_8250_port *up, unsigned int *status) | |||
1462 | lsr &= ~(UART_LSR_FE | UART_LSR_PE); | 1489 | lsr &= ~(UART_LSR_FE | UART_LSR_PE); |
1463 | up->port.icount.brk++; | 1490 | up->port.icount.brk++; |
1464 | /* | 1491 | /* |
1492 | * If tegra port then clear the rx fifo to | ||
1493 | * accept another break/character. | ||
1494 | */ | ||
1495 | if (up->port.type == PORT_TEGRA) | ||
1496 | clear_rx_fifo(up); | ||
1497 | |||
1498 | /* | ||
1465 | * We do the SysRQ and SAK checking | 1499 | * We do the SysRQ and SAK checking |
1466 | * here because otherwise the break | 1500 | * here because otherwise the break |
1467 | * may get masked by ignore_status_mask | 1501 | * may get masked by ignore_status_mask |
@@ -2405,7 +2439,9 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2405 | UART_ENABLE_MS(&up->port, termios->c_cflag)) | 2439 | UART_ENABLE_MS(&up->port, termios->c_cflag)) |
2406 | up->ier |= UART_IER_MSI; | 2440 | up->ier |= UART_IER_MSI; |
2407 | if (up->capabilities & UART_CAP_UUE) | 2441 | if (up->capabilities & UART_CAP_UUE) |
2408 | up->ier |= UART_IER_UUE | UART_IER_RTOIE; | 2442 | up->ier |= UART_IER_UUE; |
2443 | if (up->capabilities & UART_CAP_RTOIE) | ||
2444 | up->ier |= UART_IER_RTOIE; | ||
2409 | 2445 | ||
2410 | serial_out(up, UART_IER, up->ier); | 2446 | serial_out(up, UART_IER, up->ier); |
2411 | 2447 | ||
diff --git a/drivers/tty/serial/8250.h b/drivers/tty/serial/8250.h index 6e19ea3e48d5..6edf4a6a22d4 100644 --- a/drivers/tty/serial/8250.h +++ b/drivers/tty/serial/8250.h | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/char/8250.h | ||
3 | * | ||
4 | * Driver for 8250/16550-type serial ports | 2 | * Driver for 8250/16550-type serial ports |
5 | * | 3 | * |
6 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. | 4 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. |
@@ -44,6 +42,7 @@ struct serial8250_config { | |||
44 | #define UART_CAP_SLEEP (1 << 10) /* UART has IER sleep */ | 42 | #define UART_CAP_SLEEP (1 << 10) /* UART has IER sleep */ |
45 | #define UART_CAP_AFE (1 << 11) /* MCR-based hw flow control */ | 43 | #define UART_CAP_AFE (1 << 11) /* MCR-based hw flow control */ |
46 | #define UART_CAP_UUE (1 << 12) /* UART needs IER bit 6 set (Xscale) */ | 44 | #define UART_CAP_UUE (1 << 12) /* UART needs IER bit 6 set (Xscale) */ |
45 | #define UART_CAP_RTOIE (1 << 13) /* UART needs IER bit 4 set (Xscale, Tegra) */ | ||
47 | 46 | ||
48 | #define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */ | 47 | #define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */ |
49 | #define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */ | 48 | #define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */ |
diff --git a/drivers/tty/serial/8250_accent.c b/drivers/tty/serial/8250_accent.c index 9c10262f2469..34b51c651192 100644 --- a/drivers/tty/serial/8250_accent.c +++ b/drivers/tty/serial/8250_accent.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/serial/8250_accent.c | ||
3 | * | ||
4 | * Copyright (C) 2005 Russell King. | 2 | * Copyright (C) 2005 Russell King. |
5 | * Data taken from include/asm-i386/serial.h | 3 | * Data taken from include/asm-i386/serial.h |
6 | * | 4 | * |
diff --git a/drivers/tty/serial/8250_boca.c b/drivers/tty/serial/8250_boca.c index 3bfe0f7b26fb..d125dc107985 100644 --- a/drivers/tty/serial/8250_boca.c +++ b/drivers/tty/serial/8250_boca.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/serial/8250_boca.c | ||
3 | * | ||
4 | * Copyright (C) 2005 Russell King. | 2 | * Copyright (C) 2005 Russell King. |
5 | * Data taken from include/asm-i386/serial.h | 3 | * Data taken from include/asm-i386/serial.h |
6 | * | 4 | * |
diff --git a/drivers/tty/serial/8250_exar_st16c554.c b/drivers/tty/serial/8250_exar_st16c554.c index 567143ace159..bf53aabf9b5e 100644 --- a/drivers/tty/serial/8250_exar_st16c554.c +++ b/drivers/tty/serial/8250_exar_st16c554.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/serial/8250_exar.c | ||
3 | * | ||
4 | * Written by Paul B Schroeder < pschroeder "at" uplogix "dot" com > | 2 | * Written by Paul B Schroeder < pschroeder "at" uplogix "dot" com > |
5 | * Based on 8250_boca. | 3 | * Based on 8250_boca. |
6 | * | 4 | * |
diff --git a/drivers/tty/serial/8250_fourport.c b/drivers/tty/serial/8250_fourport.c index 6375d68b7913..be1582609626 100644 --- a/drivers/tty/serial/8250_fourport.c +++ b/drivers/tty/serial/8250_fourport.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/serial/8250_fourport.c | ||
3 | * | ||
4 | * Copyright (C) 2005 Russell King. | 2 | * Copyright (C) 2005 Russell King. |
5 | * Data taken from include/asm-i386/serial.h | 3 | * Data taken from include/asm-i386/serial.h |
6 | * | 4 | * |
diff --git a/drivers/tty/serial/8250_hub6.c b/drivers/tty/serial/8250_hub6.c index 7609150e7d5e..a5c778e83de0 100644 --- a/drivers/tty/serial/8250_hub6.c +++ b/drivers/tty/serial/8250_hub6.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/serial/8250_hub6.c | ||
3 | * | ||
4 | * Copyright (C) 2005 Russell King. | 2 | * Copyright (C) 2005 Russell King. |
5 | * Data taken from include/asm-i386/serial.h | 3 | * Data taken from include/asm-i386/serial.h |
6 | * | 4 | * |
diff --git a/drivers/tty/serial/8250_mca.c b/drivers/tty/serial/8250_mca.c index d10be944ad44..d20abf04541e 100644 --- a/drivers/tty/serial/8250_mca.c +++ b/drivers/tty/serial/8250_mca.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/serial/8250_mca.c | ||
3 | * | ||
4 | * Copyright (C) 2005 Russell King. | 2 | * Copyright (C) 2005 Russell King. |
5 | * Data taken from include/asm-i386/serial.h | 3 | * Data taken from include/asm-i386/serial.h |
6 | * | 4 | * |
diff --git a/drivers/tty/serial/8250_pci.c b/drivers/tty/serial/8250_pci.c index 738cec9807d3..4b4968a294b2 100644 --- a/drivers/tty/serial/8250_pci.c +++ b/drivers/tty/serial/8250_pci.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/char/8250_pci.c | ||
3 | * | ||
4 | * Probe module for 8250/16550-type PCI serial ports. | 2 | * Probe module for 8250/16550-type PCI serial ports. |
5 | * | 3 | * |
6 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. | 4 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. |
@@ -973,6 +971,14 @@ ce4100_serial_setup(struct serial_private *priv, | |||
973 | return ret; | 971 | return ret; |
974 | } | 972 | } |
975 | 973 | ||
974 | static int | ||
975 | pci_omegapci_setup(struct serial_private *priv, | ||
976 | struct pciserial_board *board, | ||
977 | struct uart_port *port, int idx) | ||
978 | { | ||
979 | return setup_port(priv, port, 2, idx * 8, 0); | ||
980 | } | ||
981 | |||
976 | static int skip_tx_en_setup(struct serial_private *priv, | 982 | static int skip_tx_en_setup(struct serial_private *priv, |
977 | const struct pciserial_board *board, | 983 | const struct pciserial_board *board, |
978 | struct uart_port *port, int idx) | 984 | struct uart_port *port, int idx) |
@@ -1012,6 +1018,8 @@ static int skip_tx_en_setup(struct serial_private *priv, | |||
1012 | #define PCI_DEVICE_ID_TITAN_200EI 0xA016 | 1018 | #define PCI_DEVICE_ID_TITAN_200EI 0xA016 |
1013 | #define PCI_DEVICE_ID_TITAN_200EISI 0xA017 | 1019 | #define PCI_DEVICE_ID_TITAN_200EISI 0xA017 |
1014 | #define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538 | 1020 | #define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538 |
1021 | #define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6 | ||
1022 | #define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001 | ||
1015 | 1023 | ||
1016 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ | 1024 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ |
1017 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 | 1025 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 |
@@ -1412,7 +1420,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1412 | .setup = pci_default_setup, | 1420 | .setup = pci_default_setup, |
1413 | }, | 1421 | }, |
1414 | /* | 1422 | /* |
1415 | * For Oxford Semiconductor and Mainpine | 1423 | * For Oxford Semiconductor Tornado based devices |
1416 | */ | 1424 | */ |
1417 | { | 1425 | { |
1418 | .vendor = PCI_VENDOR_ID_OXSEMI, | 1426 | .vendor = PCI_VENDOR_ID_OXSEMI, |
@@ -1430,6 +1438,24 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1430 | .init = pci_oxsemi_tornado_init, | 1438 | .init = pci_oxsemi_tornado_init, |
1431 | .setup = pci_default_setup, | 1439 | .setup = pci_default_setup, |
1432 | }, | 1440 | }, |
1441 | { | ||
1442 | .vendor = PCI_VENDOR_ID_DIGI, | ||
1443 | .device = PCIE_DEVICE_ID_NEO_2_OX_IBM, | ||
1444 | .subvendor = PCI_SUBVENDOR_ID_IBM, | ||
1445 | .subdevice = PCI_ANY_ID, | ||
1446 | .init = pci_oxsemi_tornado_init, | ||
1447 | .setup = pci_default_setup, | ||
1448 | }, | ||
1449 | /* | ||
1450 | * Cronyx Omega PCI (PLX-chip based) | ||
1451 | */ | ||
1452 | { | ||
1453 | .vendor = PCI_VENDOR_ID_PLX, | ||
1454 | .device = PCI_DEVICE_ID_PLX_CRONYX_OMEGA, | ||
1455 | .subvendor = PCI_ANY_ID, | ||
1456 | .subdevice = PCI_ANY_ID, | ||
1457 | .setup = pci_omegapci_setup, | ||
1458 | }, | ||
1433 | /* | 1459 | /* |
1434 | * Default "match everything" terminator entry | 1460 | * Default "match everything" terminator entry |
1435 | */ | 1461 | */ |
@@ -1617,6 +1643,7 @@ enum pci_board_num_t { | |||
1617 | pbn_ADDIDATA_PCIe_4_3906250, | 1643 | pbn_ADDIDATA_PCIe_4_3906250, |
1618 | pbn_ADDIDATA_PCIe_8_3906250, | 1644 | pbn_ADDIDATA_PCIe_8_3906250, |
1619 | pbn_ce4100_1_115200, | 1645 | pbn_ce4100_1_115200, |
1646 | pbn_omegapci, | ||
1620 | }; | 1647 | }; |
1621 | 1648 | ||
1622 | /* | 1649 | /* |
@@ -2312,6 +2339,12 @@ static struct pciserial_board pci_boards[] __devinitdata = { | |||
2312 | .base_baud = 921600, | 2339 | .base_baud = 921600, |
2313 | .reg_shift = 2, | 2340 | .reg_shift = 2, |
2314 | }, | 2341 | }, |
2342 | [pbn_omegapci] = { | ||
2343 | .flags = FL_BASE0, | ||
2344 | .num_ports = 8, | ||
2345 | .base_baud = 115200, | ||
2346 | .uart_offset = 0x200, | ||
2347 | }, | ||
2315 | }; | 2348 | }; |
2316 | 2349 | ||
2317 | static const struct pci_device_id softmodem_blacklist[] = { | 2350 | static const struct pci_device_id softmodem_blacklist[] = { |
@@ -3075,6 +3108,14 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
3075 | { PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 8 Port V.34 Super-G3 Fax */ | 3108 | { PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 8 Port V.34 Super-G3 Fax */ |
3076 | PCI_VENDOR_ID_MAINPINE, 0x4008, 0, 0, | 3109 | PCI_VENDOR_ID_MAINPINE, 0x4008, 0, 0, |
3077 | pbn_oxsemi_8_4000000 }, | 3110 | pbn_oxsemi_8_4000000 }, |
3111 | |||
3112 | /* | ||
3113 | * Digi/IBM PCIe 2-port Async EIA-232 Adapter utilizing OxSemi Tornado | ||
3114 | */ | ||
3115 | { PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_2_OX_IBM, | ||
3116 | PCI_SUBVENDOR_ID_IBM, PCI_ANY_ID, 0, 0, | ||
3117 | pbn_oxsemi_2_4000000 }, | ||
3118 | |||
3078 | /* | 3119 | /* |
3079 | * SBS Technologies, Inc. P-Octal and PMC-OCTPRO cards, | 3120 | * SBS Technologies, Inc. P-Octal and PMC-OCTPRO cards, |
3080 | * from skokodyn@yahoo.com | 3121 | * from skokodyn@yahoo.com |
@@ -3801,6 +3842,12 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
3801 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 3842 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
3802 | pbn_ce4100_1_115200 }, | 3843 | pbn_ce4100_1_115200 }, |
3803 | 3844 | ||
3845 | /* | ||
3846 | * Cronyx Omega PCI | ||
3847 | */ | ||
3848 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_CRONYX_OMEGA, | ||
3849 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3850 | pbn_omegapci }, | ||
3804 | 3851 | ||
3805 | /* | 3852 | /* |
3806 | * These entries match devices with class COMMUNICATION_SERIAL, | 3853 | * These entries match devices with class COMMUNICATION_SERIAL, |
diff --git a/drivers/tty/serial/8250_pnp.c b/drivers/tty/serial/8250_pnp.c index 4822cb50cd0f..fc301f6722e1 100644 --- a/drivers/tty/serial/8250_pnp.c +++ b/drivers/tty/serial/8250_pnp.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/char/8250_pnp.c | ||
3 | * | ||
4 | * Probe module for 8250/16550-type ISAPNP serial ports. | 2 | * Probe module for 8250/16550-type ISAPNP serial ports. |
5 | * | 3 | * |
6 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. | 4 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. |
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index b1f0f83b870d..636144cea932 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
@@ -537,7 +537,7 @@ config SERIAL_S3C6400 | |||
537 | 537 | ||
538 | config SERIAL_S5PV210 | 538 | config SERIAL_S5PV210 |
539 | tristate "Samsung S5PV210 Serial port support" | 539 | tristate "Samsung S5PV210 Serial port support" |
540 | depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_S5P6442 || CPU_EXYNOS4210) | 540 | depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_EXYNOS4210) |
541 | select SERIAL_SAMSUNG_UARTS_4 if (CPU_S5PV210 || CPU_EXYNOS4210) | 541 | select SERIAL_SAMSUNG_UARTS_4 if (CPU_S5PV210 || CPU_EXYNOS4210) |
542 | default y | 542 | default y |
543 | help | 543 | help |
@@ -1585,7 +1585,7 @@ config SERIAL_IFX6X60 | |||
1585 | Support for the IFX6x60 modem devices on Intel MID platforms. | 1585 | Support for the IFX6x60 modem devices on Intel MID platforms. |
1586 | 1586 | ||
1587 | config SERIAL_PCH_UART | 1587 | config SERIAL_PCH_UART |
1588 | tristate "Intel EG20T PCH UART/OKI SEMICONDUCTOR ML7213 IOH" | 1588 | tristate "Intel EG20T PCH / OKI SEMICONDUCTOR IOH(ML7213/ML7223) UART" |
1589 | depends on PCI | 1589 | depends on PCI |
1590 | select SERIAL_CORE | 1590 | select SERIAL_CORE |
1591 | help | 1591 | help |
@@ -1593,10 +1593,12 @@ config SERIAL_PCH_UART | |||
1593 | which is an IOH(Input/Output Hub) for x86 embedded processor. | 1593 | which is an IOH(Input/Output Hub) for x86 embedded processor. |
1594 | Enabling PCH_DMA, this PCH UART works as DMA mode. | 1594 | Enabling PCH_DMA, this PCH UART works as DMA mode. |
1595 | 1595 | ||
1596 | This driver also can be used for OKI SEMICONDUCTOR ML7213 IOH(Input/ | 1596 | This driver also can be used for OKI SEMICONDUCTOR IOH(Input/ |
1597 | Output Hub) which is for IVI(In-Vehicle Infotainment) use. | 1597 | Output Hub), ML7213 and ML7223. |
1598 | ML7213 is companion chip for Intel Atom E6xx series. | 1598 | ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is |
1599 | ML7213 is completely compatible for Intel EG20T PCH. | 1599 | for MP(Media Phone) use. |
1600 | ML7213/ML7223 is companion chip for Intel Atom E6xx series. | ||
1601 | ML7213/ML7223 is completely compatible for Intel EG20T PCH. | ||
1600 | 1602 | ||
1601 | config SERIAL_MSM_SMD | 1603 | config SERIAL_MSM_SMD |
1602 | bool "Enable tty device interface for some SMD ports" | 1604 | bool "Enable tty device interface for some SMD ports" |
@@ -1620,4 +1622,17 @@ config SERIAL_MXS_AUART_CONSOLE | |||
1620 | help | 1622 | help |
1621 | Enable a MXS AUART port to be the system console. | 1623 | Enable a MXS AUART port to be the system console. |
1622 | 1624 | ||
1625 | config SERIAL_XILINX_PS_UART | ||
1626 | tristate "Xilinx PS UART support" | ||
1627 | select SERIAL_CORE | ||
1628 | help | ||
1629 | This driver supports the Xilinx PS UART port. | ||
1630 | |||
1631 | config SERIAL_XILINX_PS_UART_CONSOLE | ||
1632 | bool "Xilinx PS UART console support" | ||
1633 | depends on SERIAL_XILINX_PS_UART=y | ||
1634 | select SERIAL_CORE_CONSOLE | ||
1635 | help | ||
1636 | Enable a Xilinx PS UART port to be the system console. | ||
1637 | |||
1623 | endmenu | 1638 | endmenu |
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index 35276043d9d1..cb2628fee4c7 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile | |||
@@ -95,3 +95,4 @@ obj-$(CONFIG_SERIAL_PCH_UART) += pch_uart.o | |||
95 | obj-$(CONFIG_SERIAL_MSM_SMD) += msm_smd_tty.o | 95 | obj-$(CONFIG_SERIAL_MSM_SMD) += msm_smd_tty.o |
96 | obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o | 96 | obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o |
97 | obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o | 97 | obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o |
98 | obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o | ||
diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index 6d5b036ac783..50bc5a5ac653 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c | |||
@@ -540,11 +540,14 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) | |||
540 | int i = pdev->id; | 540 | int i = pdev->id; |
541 | int ret; | 541 | int ret; |
542 | 542 | ||
543 | /* -1 emphasizes that the platform must have one port, no .N suffix */ | 543 | /* if id is -1 scan for a free id and use that one */ |
544 | if (i == -1) | 544 | if (i == -1) { |
545 | i = 0; | 545 | for (i = 0; i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS; i++) |
546 | if (altera_uart_ports[i].port.mapbase == 0) | ||
547 | break; | ||
548 | } | ||
546 | 549 | ||
547 | if (i >= CONFIG_SERIAL_ALTERA_UART_MAXPORTS) | 550 | if (i < 0 || i >= CONFIG_SERIAL_ALTERA_UART_MAXPORTS) |
548 | return -EINVAL; | 551 | return -EINVAL; |
549 | 552 | ||
550 | port = &altera_uart_ports[i].port; | 553 | port = &altera_uart_ports[i].port; |
@@ -587,6 +590,8 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) | |||
587 | port->ops = &altera_uart_ops; | 590 | port->ops = &altera_uart_ops; |
588 | port->flags = UPF_BOOT_AUTOCONF; | 591 | port->flags = UPF_BOOT_AUTOCONF; |
589 | 592 | ||
593 | dev_set_drvdata(&pdev->dev, port); | ||
594 | |||
590 | uart_add_one_port(&altera_uart_driver, port); | 595 | uart_add_one_port(&altera_uart_driver, port); |
591 | 596 | ||
592 | return 0; | 597 | return 0; |
@@ -594,14 +599,13 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) | |||
594 | 599 | ||
595 | static int __devexit altera_uart_remove(struct platform_device *pdev) | 600 | static int __devexit altera_uart_remove(struct platform_device *pdev) |
596 | { | 601 | { |
597 | struct uart_port *port; | 602 | struct uart_port *port = dev_get_drvdata(&pdev->dev); |
598 | int i = pdev->id; | ||
599 | 603 | ||
600 | if (i == -1) | 604 | if (port) { |
601 | i = 0; | 605 | uart_remove_one_port(&altera_uart_driver, port); |
602 | 606 | dev_set_drvdata(&pdev->dev, NULL); | |
603 | port = &altera_uart_ports[i].port; | 607 | port->mapbase = 0; |
604 | uart_remove_one_port(&altera_uart_driver, port); | 608 | } |
605 | 609 | ||
606 | return 0; | 610 | return 0; |
607 | } | 611 | } |
diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c index d742dd2c525c..c0d10c4ddb73 100644 --- a/drivers/tty/serial/amba-pl010.c +++ b/drivers/tty/serial/amba-pl010.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/char/amba.c | ||
3 | * | ||
4 | * Driver for AMBA serial ports | 2 | * Driver for AMBA serial ports |
5 | * | 3 | * |
6 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. | 4 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. |
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 6deee4e546be..8dc0541feecc 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/char/amba.c | ||
3 | * | ||
4 | * Driver for AMBA serial ports | 2 | * Driver for AMBA serial ports |
5 | * | 3 | * |
6 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. | 4 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. |
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index f119d1761106..652bdac8ce8e 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/char/atmel_serial.c | ||
3 | * | ||
4 | * Driver for Atmel AT91 / AT32 Serial ports | 2 | * Driver for Atmel AT91 / AT32 Serial ports |
5 | * Copyright (C) 2003 Rick Bronson | 3 | * Copyright (C) 2003 Rick Bronson |
6 | * | 4 | * |
diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index b6acd19b458e..e6c3dbd781d6 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/char/clps711x.c | ||
3 | * | ||
4 | * Driver for CLPS711x serial ports | 2 | * Driver for CLPS711x serial ports |
5 | * | 3 | * |
6 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. | 4 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. |
diff --git a/drivers/tty/serial/cpm_uart/cpm_uart.h b/drivers/tty/serial/cpm_uart/cpm_uart.h index b754dcf0fda5..cf34d26ff6cd 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart.h +++ b/drivers/tty/serial/cpm_uart/cpm_uart.h | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/serial/cpm_uart.h | ||
3 | * | ||
4 | * Driver for CPM (SCC/SMC) serial ports | 2 | * Driver for CPM (SCC/SMC) serial ports |
5 | * | 3 | * |
6 | * Copyright (C) 2004 Freescale Semiconductor, Inc. | 4 | * Copyright (C) 2004 Freescale Semiconductor, Inc. |
diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index a9a6a5fd169e..9488da74d4f7 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/serial/cpm_uart.c | ||
3 | * | ||
4 | * Driver for CPM (SCC/SMC) serial ports; core driver | 2 | * Driver for CPM (SCC/SMC) serial ports; core driver |
5 | * | 3 | * |
6 | * Based on arch/ppc/cpm2_io/uart.c by Dan Malek | 4 | * Based on arch/ppc/cpm2_io/uart.c by Dan Malek |
diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c index 3fc1d66e32c6..18f79575894a 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/serial/cpm_uart.c | ||
3 | * | ||
4 | * Driver for CPM (SCC/SMC) serial ports; CPM1 definitions | 2 | * Driver for CPM (SCC/SMC) serial ports; CPM1 definitions |
5 | * | 3 | * |
6 | * Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2) | 4 | * Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2) |
diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.h b/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.h index 10eecd6af6d4..60c7e94cde1e 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.h +++ b/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.h | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/serial/cpm_uart/cpm_uart_cpm1.h | ||
3 | * | ||
4 | * Driver for CPM (SCC/SMC) serial ports | 2 | * Driver for CPM (SCC/SMC) serial ports |
5 | * | 3 | * |
6 | * definitions for cpm1 | 4 | * definitions for cpm1 |
diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c index 814ac006393f..a4927e66e741 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/serial/cpm_uart_cpm2.c | ||
3 | * | ||
4 | * Driver for CPM (SCC/SMC) serial ports; CPM2 definitions | 2 | * Driver for CPM (SCC/SMC) serial ports; CPM2 definitions |
5 | * | 3 | * |
6 | * Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2) | 4 | * Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2) |
diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.h b/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.h index 7194c63dcf5f..51e651a69938 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.h +++ b/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.h | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/serial/cpm_uart/cpm_uart_cpm2.h | ||
3 | * | ||
4 | * Driver for CPM (SCC/SMC) serial ports | 2 | * Driver for CPM (SCC/SMC) serial ports |
5 | * | 3 | * |
6 | * definitions for cpm2 | 4 | * definitions for cpm2 |
diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 8ee5a41d340d..5315525220fb 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #include <linux/tty.h> | 41 | #include <linux/tty.h> |
42 | #include <linux/device.h> | 42 | #include <linux/device.h> |
43 | #include <linux/spi/spi.h> | 43 | #include <linux/spi/spi.h> |
44 | #include <linux/tty.h> | ||
45 | #include <linux/kfifo.h> | 44 | #include <linux/kfifo.h> |
46 | #include <linux/tty_flip.h> | 45 | #include <linux/tty_flip.h> |
47 | #include <linux/timer.h> | 46 | #include <linux/timer.h> |
@@ -56,7 +55,6 @@ | |||
56 | #include <linux/sched.h> | 55 | #include <linux/sched.h> |
57 | #include <linux/time.h> | 56 | #include <linux/time.h> |
58 | #include <linux/wait.h> | 57 | #include <linux/wait.h> |
59 | #include <linux/tty.h> | ||
60 | #include <linux/pm.h> | 58 | #include <linux/pm.h> |
61 | #include <linux/pm_runtime.h> | 59 | #include <linux/pm_runtime.h> |
62 | #include <linux/spi/ifx_modem.h> | 60 | #include <linux/spi/ifx_modem.h> |
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 62df72d9f0aa..a54473123e0a 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/serial/imx.c | ||
3 | * | ||
4 | * Driver for Motorola IMX serial ports | 2 | * Driver for Motorola IMX serial ports |
5 | * | 3 | * |
6 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. | 4 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. |
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index bfee9b4c6661..e6ba83876508 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/serial/msm_serial.c - driver for msm7k serial device and console | 2 | * Driver for msm7k serial device and console |
3 | * | 3 | * |
4 | * Copyright (C) 2007 Google, Inc. | 4 | * Copyright (C) 2007 Google, Inc. |
5 | * Author: Robert Love <rlove@google.com> | 5 | * Author: Robert Love <rlove@google.com> |
diff --git a/drivers/tty/serial/msm_serial.h b/drivers/tty/serial/msm_serial.h index 9b8dc5d0d855..e4acef5de77e 100644 --- a/drivers/tty/serial/msm_serial.h +++ b/drivers/tty/serial/msm_serial.h | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/serial/msm_serial.h | ||
3 | * | ||
4 | * Copyright (C) 2007 Google, Inc. | 2 | * Copyright (C) 2007 Google, Inc. |
5 | * Author: Robert Love <rlove@google.com> | 3 | * Author: Robert Love <rlove@google.com> |
6 | * Copyright (c) 2011, Code Aurora Forum. All rights reserved. | 4 | * Copyright (c) 2011, Code Aurora Forum. All rights reserved. |
diff --git a/drivers/tty/serial/msm_smd_tty.c b/drivers/tty/serial/msm_smd_tty.c index beeff1e86093..4f41dcdcb771 100644 --- a/drivers/tty/serial/msm_smd_tty.c +++ b/drivers/tty/serial/msm_smd_tty.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* drivers/tty/serial/msm_smd_tty.c | 1 | /* |
2 | * | ||
3 | * Copyright (C) 2007 Google, Inc. | 2 | * Copyright (C) 2007 Google, Inc. |
4 | * Copyright (c) 2011, Code Aurora Forum. All rights reserved. | 3 | * Copyright (c) 2011, Code Aurora Forum. All rights reserved. |
5 | * Author: Brian Swetland <swetland@google.com> | 4 | * Author: Brian Swetland <swetland@google.com> |
diff --git a/drivers/tty/serial/netx-serial.c b/drivers/tty/serial/netx-serial.c index 7735c9f35fa0..d40da78e7c85 100644 --- a/drivers/tty/serial/netx-serial.c +++ b/drivers/tty/serial/netx-serial.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/serial/netx-serial.c | ||
3 | * | ||
4 | * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix | 2 | * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix |
5 | * | 3 | * |
6 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 26403b8e4b9b..c63d0d152af6 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c | |||
@@ -253,6 +253,8 @@ enum pch_uart_num_t { | |||
253 | pch_ml7213_uart0, | 253 | pch_ml7213_uart0, |
254 | pch_ml7213_uart1, | 254 | pch_ml7213_uart1, |
255 | pch_ml7213_uart2, | 255 | pch_ml7213_uart2, |
256 | pch_ml7223_uart0, | ||
257 | pch_ml7223_uart1, | ||
256 | }; | 258 | }; |
257 | 259 | ||
258 | static struct pch_uart_driver_data drv_dat[] = { | 260 | static struct pch_uart_driver_data drv_dat[] = { |
@@ -263,6 +265,8 @@ static struct pch_uart_driver_data drv_dat[] = { | |||
263 | [pch_ml7213_uart0] = {PCH_UART_8LINE, 0}, | 265 | [pch_ml7213_uart0] = {PCH_UART_8LINE, 0}, |
264 | [pch_ml7213_uart1] = {PCH_UART_2LINE, 1}, | 266 | [pch_ml7213_uart1] = {PCH_UART_2LINE, 1}, |
265 | [pch_ml7213_uart2] = {PCH_UART_2LINE, 2}, | 267 | [pch_ml7213_uart2] = {PCH_UART_2LINE, 2}, |
268 | [pch_ml7223_uart0] = {PCH_UART_8LINE, 0}, | ||
269 | [pch_ml7223_uart1] = {PCH_UART_2LINE, 1}, | ||
266 | }; | 270 | }; |
267 | 271 | ||
268 | static unsigned int default_baud = 9600; | 272 | static unsigned int default_baud = 9600; |
@@ -1534,6 +1538,10 @@ static DEFINE_PCI_DEVICE_TABLE(pch_uart_pci_id) = { | |||
1534 | .driver_data = pch_ml7213_uart1}, | 1538 | .driver_data = pch_ml7213_uart1}, |
1535 | {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8029), | 1539 | {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8029), |
1536 | .driver_data = pch_ml7213_uart2}, | 1540 | .driver_data = pch_ml7213_uart2}, |
1541 | {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x800C), | ||
1542 | .driver_data = pch_ml7223_uart0}, | ||
1543 | {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x800D), | ||
1544 | .driver_data = pch_ml7223_uart1}, | ||
1537 | {0,}, | 1545 | {0,}, |
1538 | }; | 1546 | }; |
1539 | 1547 | ||
diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index e1c8d4f1ce58..5acd24a27d08 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/serial/pmac_zilog.c | ||
3 | * | ||
4 | * Driver for PowerMac Z85c30 based ESCC cell found in the | 2 | * Driver for PowerMac Z85c30 based ESCC cell found in the |
5 | * "macio" ASICs of various PowerMac models | 3 | * "macio" ASICs of various PowerMac models |
6 | * | 4 | * |
diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index 1102a39b44f5..4302e6e3768e 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/serial/pxa.c | ||
3 | * | ||
4 | * Based on drivers/serial/8250.c by Russell King. | 2 | * Based on drivers/serial/8250.c by Russell King. |
5 | * | 3 | * |
6 | * Author: Nicolas Pitre | 4 | * Author: Nicolas Pitre |
diff --git a/drivers/tty/serial/s3c2400.c b/drivers/tty/serial/s3c2400.c index fed1a9a1ffb4..d13051b3df87 100644 --- a/drivers/tty/serial/s3c2400.c +++ b/drivers/tty/serial/s3c2400.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* linux/drivers/serial/s3c240.c | 1 | /* |
2 | * | ||
3 | * Driver for Samsung SoC onboard UARTs. | 2 | * Driver for Samsung SoC onboard UARTs. |
4 | * | 3 | * |
5 | * Ben Dooks, Copyright (c) 2003-2005 Simtec Electronics | 4 | * Ben Dooks, Copyright (c) 2003-2005 Simtec Electronics |
diff --git a/drivers/tty/serial/s3c2410.c b/drivers/tty/serial/s3c2410.c index 73f089d3efd6..bffe6ff9b158 100644 --- a/drivers/tty/serial/s3c2410.c +++ b/drivers/tty/serial/s3c2410.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* linux/drivers/serial/s3c2410.c | 1 | /* |
2 | * | ||
3 | * Driver for Samsung S3C2410 SoC onboard UARTs. | 2 | * Driver for Samsung S3C2410 SoC onboard UARTs. |
4 | * | 3 | * |
5 | * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics | 4 | * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics |
diff --git a/drivers/tty/serial/s3c2412.c b/drivers/tty/serial/s3c2412.c index 1700b1a2fb7e..7e2b9504a687 100644 --- a/drivers/tty/serial/s3c2412.c +++ b/drivers/tty/serial/s3c2412.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* linux/drivers/serial/s3c2412.c | 1 | /* |
2 | * | ||
3 | * Driver for Samsung S3C2412 and S3C2413 SoC onboard UARTs. | 2 | * Driver for Samsung S3C2412 and S3C2413 SoC onboard UARTs. |
4 | * | 3 | * |
5 | * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics | 4 | * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics |
diff --git a/drivers/tty/serial/s3c2440.c b/drivers/tty/serial/s3c2440.c index 094cc3904b13..9e10d415d5fd 100644 --- a/drivers/tty/serial/s3c2440.c +++ b/drivers/tty/serial/s3c2440.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* linux/drivers/serial/s3c2440.c | 1 | /* |
2 | * | ||
3 | * Driver for Samsung S3C2440 and S3C2442 SoC onboard UARTs. | 2 | * Driver for Samsung S3C2440 and S3C2442 SoC onboard UARTs. |
4 | * | 3 | * |
5 | * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics | 4 | * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics |
diff --git a/drivers/tty/serial/s3c24a0.c b/drivers/tty/serial/s3c24a0.c index fad6083ca427..914eff22e499 100644 --- a/drivers/tty/serial/s3c24a0.c +++ b/drivers/tty/serial/s3c24a0.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* linux/drivers/serial/s3c24a0.c | 1 | /* |
2 | * | ||
3 | * Driver for Samsung S3C24A0 SoC onboard UARTs. | 2 | * Driver for Samsung S3C24A0 SoC onboard UARTs. |
4 | * | 3 | * |
5 | * Based on drivers/serial/s3c2410.c | 4 | * Based on drivers/serial/s3c2410.c |
diff --git a/drivers/tty/serial/s3c6400.c b/drivers/tty/serial/s3c6400.c index 4be92ab50058..ded26c42ff37 100644 --- a/drivers/tty/serial/s3c6400.c +++ b/drivers/tty/serial/s3c6400.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* linux/drivers/serial/s3c6400.c | 1 | /* |
2 | * | ||
3 | * Driver for Samsung S3C6400 and S3C6410 SoC onboard UARTs. | 2 | * Driver for Samsung S3C6400 and S3C6410 SoC onboard UARTs. |
4 | * | 3 | * |
5 | * Copyright 2008 Openmoko, Inc. | 4 | * Copyright 2008 Openmoko, Inc. |
diff --git a/drivers/tty/serial/s5pv210.c b/drivers/tty/serial/s5pv210.c index 6ebccd70a707..fb2619f93d84 100644 --- a/drivers/tty/serial/s5pv210.c +++ b/drivers/tty/serial/s5pv210.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* linux/drivers/serial/s5pv210.c | 1 | /* |
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | 2 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. |
4 | * http://www.samsung.com/ | 3 | * http://www.samsung.com/ |
5 | * | 4 | * |
diff --git a/drivers/tty/serial/sa1100.c b/drivers/tty/serial/sa1100.c index 2199d819a987..ef7a21a6a01b 100644 --- a/drivers/tty/serial/sa1100.c +++ b/drivers/tty/serial/sa1100.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/char/sa1100.c | ||
3 | * | ||
4 | * Driver for SA11x0 serial ports | 2 | * Driver for SA11x0 serial ports |
5 | * | 3 | * |
6 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. | 4 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. |
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 9e2fa8d784e2..f66f64829303 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* linux/drivers/serial/samsuing.c | 1 | /* |
2 | * | ||
3 | * Driver core for Samsung SoC onboard UARTs. | 2 | * Driver core for Samsung SoC onboard UARTs. |
4 | * | 3 | * |
5 | * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics | 4 | * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics |
diff --git a/drivers/tty/serial/samsung.h b/drivers/tty/serial/samsung.h index 0ac06a07d25f..5b098cd76040 100644 --- a/drivers/tty/serial/samsung.h +++ b/drivers/tty/serial/samsung.h | |||
@@ -1,5 +1,4 @@ | |||
1 | /* linux/drivers/serial/samsung.h | 1 | /* |
2 | * | ||
3 | * Driver for Samsung SoC onboard UARTs. | 2 | * Driver for Samsung SoC onboard UARTs. |
4 | * | 3 | * |
5 | * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics | 4 | * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics |
diff --git a/drivers/tty/serial/sb1250-duart.c b/drivers/tty/serial/sb1250-duart.c index 602d9845c52f..ea2340b814e9 100644 --- a/drivers/tty/serial/sb1250-duart.c +++ b/drivers/tty/serial/sb1250-duart.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/serial/sb1250-duart.c | ||
3 | * | ||
4 | * Support for the asynchronous serial interface (DUART) included | 2 | * Support for the asynchronous serial interface (DUART) included |
5 | * in the BCM1250 and derived System-On-a-Chip (SOC) devices. | 3 | * in the BCM1250 and derived System-On-a-Chip (SOC) devices. |
6 | * | 4 | * |
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 733fe8e73f0f..db7912cb7ae0 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/char/core.c | ||
3 | * | ||
4 | * Driver core for serial ports | 2 | * Driver core for serial ports |
5 | * | 3 | * |
6 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. | 4 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. |
@@ -172,12 +170,16 @@ static int uart_startup(struct tty_struct *tty, struct uart_state *state, int in | |||
172 | 170 | ||
173 | retval = uport->ops->startup(uport); | 171 | retval = uport->ops->startup(uport); |
174 | if (retval == 0) { | 172 | if (retval == 0) { |
175 | if (init_hw) { | 173 | if (uart_console(uport) && uport->cons->cflag) { |
176 | /* | 174 | tty->termios->c_cflag = uport->cons->cflag; |
177 | * Initialise the hardware port settings. | 175 | uport->cons->cflag = 0; |
178 | */ | 176 | } |
179 | uart_change_speed(tty, state, NULL); | 177 | /* |
178 | * Initialise the hardware port settings. | ||
179 | */ | ||
180 | uart_change_speed(tty, state, NULL); | ||
180 | 181 | ||
182 | if (init_hw) { | ||
181 | /* | 183 | /* |
182 | * Setup the RTS and DTR signals once the | 184 | * Setup the RTS and DTR signals once the |
183 | * port is open and ready to respond. | 185 | * port is open and ready to respond. |
@@ -1240,17 +1242,6 @@ static void uart_set_termios(struct tty_struct *tty, | |||
1240 | } | 1242 | } |
1241 | spin_unlock_irqrestore(&state->uart_port->lock, flags); | 1243 | spin_unlock_irqrestore(&state->uart_port->lock, flags); |
1242 | } | 1244 | } |
1243 | #if 0 | ||
1244 | /* | ||
1245 | * No need to wake up processes in open wait, since they | ||
1246 | * sample the CLOCAL flag once, and don't recheck it. | ||
1247 | * XXX It's not clear whether the current behavior is correct | ||
1248 | * or not. Hence, this may change..... | ||
1249 | */ | ||
1250 | if (!(old_termios->c_cflag & CLOCAL) && | ||
1251 | (tty->termios->c_cflag & CLOCAL)) | ||
1252 | wake_up_interruptible(&state->uart_port.open_wait); | ||
1253 | #endif | ||
1254 | } | 1245 | } |
1255 | 1246 | ||
1256 | /* | 1247 | /* |
@@ -1423,7 +1414,6 @@ static void __uart_wait_until_sent(struct uart_port *port, int timeout) | |||
1423 | if (time_after(jiffies, expire)) | 1414 | if (time_after(jiffies, expire)) |
1424 | break; | 1415 | break; |
1425 | } | 1416 | } |
1426 | set_current_state(TASK_RUNNING); /* might not be needed */ | ||
1427 | } | 1417 | } |
1428 | 1418 | ||
1429 | static void uart_wait_until_sent(struct tty_struct *tty, int timeout) | 1419 | static void uart_wait_until_sent(struct tty_struct *tty, int timeout) |
@@ -1466,45 +1456,6 @@ static void uart_hangup(struct tty_struct *tty) | |||
1466 | mutex_unlock(&port->mutex); | 1456 | mutex_unlock(&port->mutex); |
1467 | } | 1457 | } |
1468 | 1458 | ||
1469 | /** | ||
1470 | * uart_update_termios - update the terminal hw settings | ||
1471 | * @tty: tty associated with UART | ||
1472 | * @state: UART to update | ||
1473 | * | ||
1474 | * Copy across the serial console cflag setting into the termios settings | ||
1475 | * for the initial open of the port. This allows continuity between the | ||
1476 | * kernel settings, and the settings init adopts when it opens the port | ||
1477 | * for the first time. | ||
1478 | */ | ||
1479 | static void uart_update_termios(struct tty_struct *tty, | ||
1480 | struct uart_state *state) | ||
1481 | { | ||
1482 | struct uart_port *port = state->uart_port; | ||
1483 | |||
1484 | if (uart_console(port) && port->cons->cflag) { | ||
1485 | tty->termios->c_cflag = port->cons->cflag; | ||
1486 | port->cons->cflag = 0; | ||
1487 | } | ||
1488 | |||
1489 | /* | ||
1490 | * If the device failed to grab its irq resources, | ||
1491 | * or some other error occurred, don't try to talk | ||
1492 | * to the port hardware. | ||
1493 | */ | ||
1494 | if (!(tty->flags & (1 << TTY_IO_ERROR))) { | ||
1495 | /* | ||
1496 | * Make termios settings take effect. | ||
1497 | */ | ||
1498 | uart_change_speed(tty, state, NULL); | ||
1499 | |||
1500 | /* | ||
1501 | * And finally enable the RTS and DTR signals. | ||
1502 | */ | ||
1503 | if (tty->termios->c_cflag & CBAUD) | ||
1504 | uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS); | ||
1505 | } | ||
1506 | } | ||
1507 | |||
1508 | static int uart_carrier_raised(struct tty_port *port) | 1459 | static int uart_carrier_raised(struct tty_port *port) |
1509 | { | 1460 | { |
1510 | struct uart_state *state = container_of(port, struct uart_state, port); | 1461 | struct uart_state *state = container_of(port, struct uart_state, port); |
@@ -1524,16 +1475,8 @@ static void uart_dtr_rts(struct tty_port *port, int onoff) | |||
1524 | struct uart_state *state = container_of(port, struct uart_state, port); | 1475 | struct uart_state *state = container_of(port, struct uart_state, port); |
1525 | struct uart_port *uport = state->uart_port; | 1476 | struct uart_port *uport = state->uart_port; |
1526 | 1477 | ||
1527 | if (onoff) { | 1478 | if (onoff) |
1528 | uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS); | 1479 | uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS); |
1529 | |||
1530 | /* | ||
1531 | * If this is the first open to succeed, | ||
1532 | * adjust things to suit. | ||
1533 | */ | ||
1534 | if (!test_and_set_bit(ASYNCB_NORMAL_ACTIVE, &port->flags)) | ||
1535 | uart_update_termios(port->tty, state); | ||
1536 | } | ||
1537 | else | 1480 | else |
1538 | uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); | 1481 | uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); |
1539 | } | 1482 | } |
@@ -1586,15 +1529,6 @@ static int uart_open(struct tty_struct *tty, struct file *filp) | |||
1586 | pr_debug("uart_open(%d) called\n", line); | 1529 | pr_debug("uart_open(%d) called\n", line); |
1587 | 1530 | ||
1588 | /* | 1531 | /* |
1589 | * tty->driver->num won't change, so we won't fail here with | ||
1590 | * tty->driver_data set to something non-NULL (and therefore | ||
1591 | * we won't get caught by uart_close()). | ||
1592 | */ | ||
1593 | retval = -ENODEV; | ||
1594 | if (line >= tty->driver->num) | ||
1595 | goto fail; | ||
1596 | |||
1597 | /* | ||
1598 | * We take the semaphore inside uart_get to guarantee that we won't | 1532 | * We take the semaphore inside uart_get to guarantee that we won't |
1599 | * be re-entered while allocating the state structure, or while we | 1533 | * be re-entered while allocating the state structure, or while we |
1600 | * request any IRQs that the driver may need. This also has the nice | 1534 | * request any IRQs that the driver may need. This also has the nice |
@@ -1972,13 +1906,9 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) | |||
1972 | struct tty_port *port = &state->port; | 1906 | struct tty_port *port = &state->port; |
1973 | struct device *tty_dev; | 1907 | struct device *tty_dev; |
1974 | struct uart_match match = {uport, drv}; | 1908 | struct uart_match match = {uport, drv}; |
1975 | struct tty_struct *tty; | ||
1976 | 1909 | ||
1977 | mutex_lock(&port->mutex); | 1910 | mutex_lock(&port->mutex); |
1978 | 1911 | ||
1979 | /* Must be inside the mutex lock until we convert to tty_port */ | ||
1980 | tty = port->tty; | ||
1981 | |||
1982 | tty_dev = device_find_child(uport->dev, &match, serial_match_port); | 1912 | tty_dev = device_find_child(uport->dev, &match, serial_match_port); |
1983 | if (device_may_wakeup(tty_dev)) { | 1913 | if (device_may_wakeup(tty_dev)) { |
1984 | if (!enable_irq_wake(uport->irq)) | 1914 | if (!enable_irq_wake(uport->irq)) |
diff --git a/drivers/tty/serial/serial_ks8695.c b/drivers/tty/serial/serial_ks8695.c index b1962025b1aa..2430319f2f52 100644 --- a/drivers/tty/serial/serial_ks8695.c +++ b/drivers/tty/serial/serial_ks8695.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/serial/serial_ks8695.c | ||
3 | * | ||
4 | * Driver for KS8695 serial ports | 2 | * Driver for KS8695 serial ports |
5 | * | 3 | * |
6 | * Based on drivers/serial/serial_amba.c, by Kam Lee. | 4 | * Based on drivers/serial/serial_amba.c, by Kam Lee. |
diff --git a/drivers/tty/serial/serial_txx9.c b/drivers/tty/serial/serial_txx9.c index c50e9fbbf743..8e3fc1944e6d 100644 --- a/drivers/tty/serial/serial_txx9.c +++ b/drivers/tty/serial/serial_txx9.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/serial/serial_txx9.c | ||
3 | * | ||
4 | * Derived from many drivers using generic_serial interface, | 2 | * Derived from many drivers using generic_serial interface, |
5 | * especially serial_tx3912.c by Steven J. Hill and r39xx_serial.c | 3 | * especially serial_tx3912.c by Steven J. Hill and r39xx_serial.c |
6 | * (was in Linux/VR tree) by Jim Pick. | 4 | * (was in Linux/VR tree) by Jim Pick. |
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 920a6f929c8b..f35b8fb94b83 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/serial/sh-sci.c | ||
3 | * | ||
4 | * SuperH on-chip serial module support. (SCI with no FIFO / with FIFO) | 2 | * SuperH on-chip serial module support. (SCI with no FIFO / with FIFO) |
5 | * | 3 | * |
6 | * Copyright (C) 2002 - 2011 Paul Mundt | 4 | * Copyright (C) 2002 - 2011 Paul Mundt |
diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index 322bf56c0d89..37fc4e3d487c 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/serial/vt8500_serial.c | ||
3 | * | ||
4 | * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> | 2 | * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> |
5 | * | 3 | * |
6 | * Based on msm_serial.c, which is: | 4 | * Based on msm_serial.c, which is: |
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c new file mode 100644 index 000000000000..19cc1e8149dd --- /dev/null +++ b/drivers/tty/serial/xilinx_uartps.c | |||
@@ -0,0 +1,1113 @@ | |||
1 | /* | ||
2 | * Xilinx PS UART driver | ||
3 | * | ||
4 | * 2011 (c) Xilinx Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it | ||
7 | * and/or modify it under the terms of the GNU General Public | ||
8 | * License as published by the Free Software Foundation; | ||
9 | * either version 2 of the License, or (at your option) any | ||
10 | * later version. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/serial_core.h> | ||
16 | #include <linux/console.h> | ||
17 | #include <linux/serial.h> | ||
18 | #include <linux/irq.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <linux/of.h> | ||
21 | |||
22 | #define XUARTPS_TTY_NAME "ttyPS" | ||
23 | #define XUARTPS_NAME "xuartps" | ||
24 | #define XUARTPS_MAJOR 0 /* use dynamic node allocation */ | ||
25 | #define XUARTPS_MINOR 0 /* works best with devtmpfs */ | ||
26 | #define XUARTPS_NR_PORTS 2 | ||
27 | #define XUARTPS_FIFO_SIZE 16 /* FIFO size */ | ||
28 | #define XUARTPS_REGISTER_SPACE 0xFFF | ||
29 | |||
30 | #define xuartps_readl(offset) ioread32(port->membase + offset) | ||
31 | #define xuartps_writel(val, offset) iowrite32(val, port->membase + offset) | ||
32 | |||
33 | /********************************Register Map********************************/ | ||
34 | /** UART | ||
35 | * | ||
36 | * Register offsets for the UART. | ||
37 | * | ||
38 | */ | ||
39 | #define XUARTPS_CR_OFFSET 0x00 /* Control Register [8:0] */ | ||
40 | #define XUARTPS_MR_OFFSET 0x04 /* Mode Register [10:0] */ | ||
41 | #define XUARTPS_IER_OFFSET 0x08 /* Interrupt Enable [10:0] */ | ||
42 | #define XUARTPS_IDR_OFFSET 0x0C /* Interrupt Disable [10:0] */ | ||
43 | #define XUARTPS_IMR_OFFSET 0x10 /* Interrupt Mask [10:0] */ | ||
44 | #define XUARTPS_ISR_OFFSET 0x14 /* Interrupt Status [10:0]*/ | ||
45 | #define XUARTPS_BAUDGEN_OFFSET 0x18 /* Baud Rate Generator [15:0] */ | ||
46 | #define XUARTPS_RXTOUT_OFFSET 0x1C /* RX Timeout [7:0] */ | ||
47 | #define XUARTPS_RXWM_OFFSET 0x20 /* RX FIFO Trigger Level [5:0] */ | ||
48 | #define XUARTPS_MODEMCR_OFFSET 0x24 /* Modem Control [5:0] */ | ||
49 | #define XUARTPS_MODEMSR_OFFSET 0x28 /* Modem Status [8:0] */ | ||
50 | #define XUARTPS_SR_OFFSET 0x2C /* Channel Status [11:0] */ | ||
51 | #define XUARTPS_FIFO_OFFSET 0x30 /* FIFO [15:0] or [7:0] */ | ||
52 | #define XUARTPS_BAUDDIV_OFFSET 0x34 /* Baud Rate Divider [7:0] */ | ||
53 | #define XUARTPS_FLOWDEL_OFFSET 0x38 /* Flow Delay [15:0] */ | ||
54 | #define XUARTPS_IRRX_PWIDTH_OFFSET 0x3C /* IR Minimum Received Pulse | ||
55 | Width [15:0] */ | ||
56 | #define XUARTPS_IRTX_PWIDTH_OFFSET 0x40 /* IR Transmitted pulse | ||
57 | Width [7:0] */ | ||
58 | #define XUARTPS_TXWM_OFFSET 0x44 /* TX FIFO Trigger Level [5:0] */ | ||
59 | |||
60 | /** Control Register | ||
61 | * | ||
62 | * The Control register (CR) controls the major functions of the device. | ||
63 | * | ||
64 | * Control Register Bit Definitions | ||
65 | */ | ||
66 | #define XUARTPS_CR_STOPBRK 0x00000100 /* Stop TX break */ | ||
67 | #define XUARTPS_CR_STARTBRK 0x00000080 /* Set TX break */ | ||
68 | #define XUARTPS_CR_TX_DIS 0x00000020 /* TX disabled. */ | ||
69 | #define XUARTPS_CR_TX_EN 0x00000010 /* TX enabled */ | ||
70 | #define XUARTPS_CR_RX_DIS 0x00000008 /* RX disabled. */ | ||
71 | #define XUARTPS_CR_RX_EN 0x00000004 /* RX enabled */ | ||
72 | #define XUARTPS_CR_TXRST 0x00000002 /* TX logic reset */ | ||
73 | #define XUARTPS_CR_RXRST 0x00000001 /* RX logic reset */ | ||
74 | #define XUARTPS_CR_RST_TO 0x00000040 /* Restart Timeout Counter */ | ||
75 | |||
76 | /** Mode Register | ||
77 | * | ||
78 | * The mode register (MR) defines the mode of transfer as well as the data | ||
79 | * format. If this register is modified during transmission or reception, | ||
80 | * data validity cannot be guaranteed. | ||
81 | * | ||
82 | * Mode Register Bit Definitions | ||
83 | * | ||
84 | */ | ||
85 | #define XUARTPS_MR_CLKSEL 0x00000001 /* Pre-scalar selection */ | ||
86 | #define XUARTPS_MR_CHMODE_L_LOOP 0x00000200 /* Local loop back mode */ | ||
87 | #define XUARTPS_MR_CHMODE_NORM 0x00000000 /* Normal mode */ | ||
88 | |||
89 | #define XUARTPS_MR_STOPMODE_2_BIT 0x00000080 /* 2 stop bits */ | ||
90 | #define XUARTPS_MR_STOPMODE_1_BIT 0x00000000 /* 1 stop bit */ | ||
91 | |||
92 | #define XUARTPS_MR_PARITY_NONE 0x00000020 /* No parity mode */ | ||
93 | #define XUARTPS_MR_PARITY_MARK 0x00000018 /* Mark parity mode */ | ||
94 | #define XUARTPS_MR_PARITY_SPACE 0x00000010 /* Space parity mode */ | ||
95 | #define XUARTPS_MR_PARITY_ODD 0x00000008 /* Odd parity mode */ | ||
96 | #define XUARTPS_MR_PARITY_EVEN 0x00000000 /* Even parity mode */ | ||
97 | |||
98 | #define XUARTPS_MR_CHARLEN_6_BIT 0x00000006 /* 6 bits data */ | ||
99 | #define XUARTPS_MR_CHARLEN_7_BIT 0x00000004 /* 7 bits data */ | ||
100 | #define XUARTPS_MR_CHARLEN_8_BIT 0x00000000 /* 8 bits data */ | ||
101 | |||
102 | /** Interrupt Registers | ||
103 | * | ||
104 | * Interrupt control logic uses the interrupt enable register (IER) and the | ||
105 | * interrupt disable register (IDR) to set the value of the bits in the | ||
106 | * interrupt mask register (IMR). The IMR determines whether to pass an | ||
107 | * interrupt to the interrupt status register (ISR). | ||
108 | * Writing a 1 to IER Enables an interrupt, writing a 1 to IDR disables an | ||
109 | * interrupt. IMR and ISR are read only, and IER and IDR are write only. | ||
110 | * Reading either IER or IDR returns 0x00. | ||
111 | * | ||
112 | * All four registers have the same bit definitions. | ||
113 | */ | ||
114 | #define XUARTPS_IXR_TOUT 0x00000100 /* RX Timeout error interrupt */ | ||
115 | #define XUARTPS_IXR_PARITY 0x00000080 /* Parity error interrupt */ | ||
116 | #define XUARTPS_IXR_FRAMING 0x00000040 /* Framing error interrupt */ | ||
117 | #define XUARTPS_IXR_OVERRUN 0x00000020 /* Overrun error interrupt */ | ||
118 | #define XUARTPS_IXR_TXFULL 0x00000010 /* TX FIFO Full interrupt */ | ||
119 | #define XUARTPS_IXR_TXEMPTY 0x00000008 /* TX FIFO empty interrupt */ | ||
120 | #define XUARTPS_ISR_RXEMPTY 0x00000002 /* RX FIFO empty interrupt */ | ||
121 | #define XUARTPS_IXR_RXTRIG 0x00000001 /* RX FIFO trigger interrupt */ | ||
122 | #define XUARTPS_IXR_RXFULL 0x00000004 /* RX FIFO full interrupt. */ | ||
123 | #define XUARTPS_IXR_RXEMPTY 0x00000002 /* RX FIFO empty interrupt. */ | ||
124 | #define XUARTPS_IXR_MASK 0x00001FFF /* Valid bit mask */ | ||
125 | |||
126 | /** Channel Status Register | ||
127 | * | ||
128 | * The channel status register (CSR) is provided to enable the control logic | ||
129 | * to monitor the status of bits in the channel interrupt status register, | ||
130 | * even if these are masked out by the interrupt mask register. | ||
131 | */ | ||
132 | #define XUARTPS_SR_RXEMPTY 0x00000002 /* RX FIFO empty */ | ||
133 | #define XUARTPS_SR_TXEMPTY 0x00000008 /* TX FIFO empty */ | ||
134 | #define XUARTPS_SR_TXFULL 0x00000010 /* TX FIFO full */ | ||
135 | #define XUARTPS_SR_RXTRIG 0x00000001 /* Rx Trigger */ | ||
136 | |||
137 | /** | ||
138 | * xuartps_isr - Interrupt handler | ||
139 | * @irq: Irq number | ||
140 | * @dev_id: Id of the port | ||
141 | * | ||
142 | * Returns IRQHANDLED | ||
143 | **/ | ||
144 | static irqreturn_t xuartps_isr(int irq, void *dev_id) | ||
145 | { | ||
146 | struct uart_port *port = (struct uart_port *)dev_id; | ||
147 | struct tty_struct *tty; | ||
148 | unsigned long flags; | ||
149 | unsigned int isrstatus, numbytes; | ||
150 | unsigned int data; | ||
151 | char status = TTY_NORMAL; | ||
152 | |||
153 | /* Get the tty which could be NULL so don't assume it's valid */ | ||
154 | tty = tty_port_tty_get(&port->state->port); | ||
155 | |||
156 | spin_lock_irqsave(&port->lock, flags); | ||
157 | |||
158 | /* Read the interrupt status register to determine which | ||
159 | * interrupt(s) is/are active. | ||
160 | */ | ||
161 | isrstatus = xuartps_readl(XUARTPS_ISR_OFFSET); | ||
162 | |||
163 | /* drop byte with parity error if IGNPAR specified */ | ||
164 | if (isrstatus & port->ignore_status_mask & XUARTPS_IXR_PARITY) | ||
165 | isrstatus &= ~(XUARTPS_IXR_RXTRIG | XUARTPS_IXR_TOUT); | ||
166 | |||
167 | isrstatus &= port->read_status_mask; | ||
168 | isrstatus &= ~port->ignore_status_mask; | ||
169 | |||
170 | if ((isrstatus & XUARTPS_IXR_TOUT) || | ||
171 | (isrstatus & XUARTPS_IXR_RXTRIG)) { | ||
172 | /* Receive Timeout Interrupt */ | ||
173 | while ((xuartps_readl(XUARTPS_SR_OFFSET) & | ||
174 | XUARTPS_SR_RXEMPTY) != XUARTPS_SR_RXEMPTY) { | ||
175 | data = xuartps_readl(XUARTPS_FIFO_OFFSET); | ||
176 | port->icount.rx++; | ||
177 | |||
178 | if (isrstatus & XUARTPS_IXR_PARITY) { | ||
179 | port->icount.parity++; | ||
180 | status = TTY_PARITY; | ||
181 | } else if (isrstatus & XUARTPS_IXR_FRAMING) { | ||
182 | port->icount.frame++; | ||
183 | status = TTY_FRAME; | ||
184 | } else if (isrstatus & XUARTPS_IXR_OVERRUN) | ||
185 | port->icount.overrun++; | ||
186 | |||
187 | if (tty) | ||
188 | uart_insert_char(port, isrstatus, | ||
189 | XUARTPS_IXR_OVERRUN, data, | ||
190 | status); | ||
191 | } | ||
192 | spin_unlock(&port->lock); | ||
193 | if (tty) | ||
194 | tty_flip_buffer_push(tty); | ||
195 | spin_lock(&port->lock); | ||
196 | } | ||
197 | |||
198 | /* Dispatch an appropriate handler */ | ||
199 | if ((isrstatus & XUARTPS_IXR_TXEMPTY) == XUARTPS_IXR_TXEMPTY) { | ||
200 | if (uart_circ_empty(&port->state->xmit)) { | ||
201 | xuartps_writel(XUARTPS_IXR_TXEMPTY, | ||
202 | XUARTPS_IDR_OFFSET); | ||
203 | } else { | ||
204 | numbytes = port->fifosize; | ||
205 | /* Break if no more data available in the UART buffer */ | ||
206 | while (numbytes--) { | ||
207 | if (uart_circ_empty(&port->state->xmit)) | ||
208 | break; | ||
209 | /* Get the data from the UART circular buffer | ||
210 | * and write it to the xuartps's TX_FIFO | ||
211 | * register. | ||
212 | */ | ||
213 | xuartps_writel( | ||
214 | port->state->xmit.buf[port->state->xmit. | ||
215 | tail], XUARTPS_FIFO_OFFSET); | ||
216 | |||
217 | port->icount.tx++; | ||
218 | |||
219 | /* Adjust the tail of the UART buffer and wrap | ||
220 | * the buffer if it reaches limit. | ||
221 | */ | ||
222 | port->state->xmit.tail = | ||
223 | (port->state->xmit.tail + 1) & \ | ||
224 | (UART_XMIT_SIZE - 1); | ||
225 | } | ||
226 | |||
227 | if (uart_circ_chars_pending( | ||
228 | &port->state->xmit) < WAKEUP_CHARS) | ||
229 | uart_write_wakeup(port); | ||
230 | } | ||
231 | } | ||
232 | |||
233 | xuartps_writel(isrstatus, XUARTPS_ISR_OFFSET); | ||
234 | |||
235 | /* be sure to release the lock and tty before leaving */ | ||
236 | spin_unlock_irqrestore(&port->lock, flags); | ||
237 | tty_kref_put(tty); | ||
238 | |||
239 | return IRQ_HANDLED; | ||
240 | } | ||
241 | |||
242 | /** | ||
243 | * xuartps_set_baud_rate - Calculate and set the baud rate | ||
244 | * @port: Handle to the uart port structure | ||
245 | * @baud: Baud rate to set | ||
246 | * | ||
247 | * Returns baud rate, requested baud when possible, or actual baud when there | ||
248 | * was too much error | ||
249 | **/ | ||
250 | static unsigned int xuartps_set_baud_rate(struct uart_port *port, | ||
251 | unsigned int baud) | ||
252 | { | ||
253 | unsigned int sel_clk; | ||
254 | unsigned int calc_baud = 0; | ||
255 | unsigned int brgr_val, brdiv_val; | ||
256 | unsigned int bauderror; | ||
257 | |||
258 | /* Formula to obtain baud rate is | ||
259 | * baud_tx/rx rate = sel_clk/CD * (BDIV + 1) | ||
260 | * input_clk = (Uart User Defined Clock or Apb Clock) | ||
261 | * depends on UCLKEN in MR Reg | ||
262 | * sel_clk = input_clk or input_clk/8; | ||
263 | * depends on CLKS in MR reg | ||
264 | * CD and BDIV depends on values in | ||
265 | * baud rate generate register | ||
266 | * baud rate clock divisor register | ||
267 | */ | ||
268 | sel_clk = port->uartclk; | ||
269 | if (xuartps_readl(XUARTPS_MR_OFFSET) & XUARTPS_MR_CLKSEL) | ||
270 | sel_clk = sel_clk / 8; | ||
271 | |||
272 | /* Find the best values for baud generation */ | ||
273 | for (brdiv_val = 4; brdiv_val < 255; brdiv_val++) { | ||
274 | |||
275 | brgr_val = sel_clk / (baud * (brdiv_val + 1)); | ||
276 | if (brgr_val < 2 || brgr_val > 65535) | ||
277 | continue; | ||
278 | |||
279 | calc_baud = sel_clk / (brgr_val * (brdiv_val + 1)); | ||
280 | |||
281 | if (baud > calc_baud) | ||
282 | bauderror = baud - calc_baud; | ||
283 | else | ||
284 | bauderror = calc_baud - baud; | ||
285 | |||
286 | /* use the values when percent error is acceptable */ | ||
287 | if (((bauderror * 100) / baud) < 3) { | ||
288 | calc_baud = baud; | ||
289 | break; | ||
290 | } | ||
291 | } | ||
292 | |||
293 | /* Set the values for the new baud rate */ | ||
294 | xuartps_writel(brgr_val, XUARTPS_BAUDGEN_OFFSET); | ||
295 | xuartps_writel(brdiv_val, XUARTPS_BAUDDIV_OFFSET); | ||
296 | |||
297 | return calc_baud; | ||
298 | } | ||
299 | |||
300 | /*----------------------Uart Operations---------------------------*/ | ||
301 | |||
302 | /** | ||
303 | * xuartps_start_tx - Start transmitting bytes | ||
304 | * @port: Handle to the uart port structure | ||
305 | * | ||
306 | **/ | ||
307 | static void xuartps_start_tx(struct uart_port *port) | ||
308 | { | ||
309 | unsigned int status, numbytes = port->fifosize; | ||
310 | |||
311 | if (uart_circ_empty(&port->state->xmit) || uart_tx_stopped(port)) | ||
312 | return; | ||
313 | |||
314 | status = xuartps_readl(XUARTPS_CR_OFFSET); | ||
315 | /* Set the TX enable bit and clear the TX disable bit to enable the | ||
316 | * transmitter. | ||
317 | */ | ||
318 | xuartps_writel((status & ~XUARTPS_CR_TX_DIS) | XUARTPS_CR_TX_EN, | ||
319 | XUARTPS_CR_OFFSET); | ||
320 | |||
321 | while (numbytes-- && ((xuartps_readl(XUARTPS_SR_OFFSET) | ||
322 | & XUARTPS_SR_TXFULL)) != XUARTPS_SR_TXFULL) { | ||
323 | |||
324 | /* Break if no more data available in the UART buffer */ | ||
325 | if (uart_circ_empty(&port->state->xmit)) | ||
326 | break; | ||
327 | |||
328 | /* Get the data from the UART circular buffer and | ||
329 | * write it to the xuartps's TX_FIFO register. | ||
330 | */ | ||
331 | xuartps_writel( | ||
332 | port->state->xmit.buf[port->state->xmit.tail], | ||
333 | XUARTPS_FIFO_OFFSET); | ||
334 | port->icount.tx++; | ||
335 | |||
336 | /* Adjust the tail of the UART buffer and wrap | ||
337 | * the buffer if it reaches limit. | ||
338 | */ | ||
339 | port->state->xmit.tail = (port->state->xmit.tail + 1) & | ||
340 | (UART_XMIT_SIZE - 1); | ||
341 | } | ||
342 | |||
343 | /* Enable the TX Empty interrupt */ | ||
344 | xuartps_writel(XUARTPS_IXR_TXEMPTY, XUARTPS_IER_OFFSET); | ||
345 | |||
346 | if (uart_circ_chars_pending(&port->state->xmit) < WAKEUP_CHARS) | ||
347 | uart_write_wakeup(port); | ||
348 | } | ||
349 | |||
350 | /** | ||
351 | * xuartps_stop_tx - Stop TX | ||
352 | * @port: Handle to the uart port structure | ||
353 | * | ||
354 | **/ | ||
355 | static void xuartps_stop_tx(struct uart_port *port) | ||
356 | { | ||
357 | unsigned int regval; | ||
358 | |||
359 | regval = xuartps_readl(XUARTPS_CR_OFFSET); | ||
360 | regval |= XUARTPS_CR_TX_DIS; | ||
361 | /* Disable the transmitter */ | ||
362 | xuartps_writel(regval, XUARTPS_CR_OFFSET); | ||
363 | } | ||
364 | |||
365 | /** | ||
366 | * xuartps_stop_rx - Stop RX | ||
367 | * @port: Handle to the uart port structure | ||
368 | * | ||
369 | **/ | ||
370 | static void xuartps_stop_rx(struct uart_port *port) | ||
371 | { | ||
372 | unsigned int regval; | ||
373 | |||
374 | regval = xuartps_readl(XUARTPS_CR_OFFSET); | ||
375 | regval |= XUARTPS_CR_RX_DIS; | ||
376 | /* Disable the receiver */ | ||
377 | xuartps_writel(regval, XUARTPS_CR_OFFSET); | ||
378 | } | ||
379 | |||
380 | /** | ||
381 | * xuartps_tx_empty - Check whether TX is empty | ||
382 | * @port: Handle to the uart port structure | ||
383 | * | ||
384 | * Returns TIOCSER_TEMT on success, 0 otherwise | ||
385 | **/ | ||
386 | static unsigned int xuartps_tx_empty(struct uart_port *port) | ||
387 | { | ||
388 | unsigned int status; | ||
389 | |||
390 | status = xuartps_readl(XUARTPS_ISR_OFFSET) & XUARTPS_IXR_TXEMPTY; | ||
391 | return status ? TIOCSER_TEMT : 0; | ||
392 | } | ||
393 | |||
394 | /** | ||
395 | * xuartps_break_ctl - Based on the input ctl we have to start or stop | ||
396 | * transmitting char breaks | ||
397 | * @port: Handle to the uart port structure | ||
398 | * @ctl: Value based on which start or stop decision is taken | ||
399 | * | ||
400 | **/ | ||
401 | static void xuartps_break_ctl(struct uart_port *port, int ctl) | ||
402 | { | ||
403 | unsigned int status; | ||
404 | unsigned long flags; | ||
405 | |||
406 | spin_lock_irqsave(&port->lock, flags); | ||
407 | |||
408 | status = xuartps_readl(XUARTPS_CR_OFFSET); | ||
409 | |||
410 | if (ctl == -1) | ||
411 | xuartps_writel(XUARTPS_CR_STARTBRK | status, | ||
412 | XUARTPS_CR_OFFSET); | ||
413 | else { | ||
414 | if ((status & XUARTPS_CR_STOPBRK) == 0) | ||
415 | xuartps_writel(XUARTPS_CR_STOPBRK | status, | ||
416 | XUARTPS_CR_OFFSET); | ||
417 | } | ||
418 | spin_unlock_irqrestore(&port->lock, flags); | ||
419 | } | ||
420 | |||
421 | /** | ||
422 | * xuartps_set_termios - termios operations, handling data length, parity, | ||
423 | * stop bits, flow control, baud rate | ||
424 | * @port: Handle to the uart port structure | ||
425 | * @termios: Handle to the input termios structure | ||
426 | * @old: Values of the previously saved termios structure | ||
427 | * | ||
428 | **/ | ||
429 | static void xuartps_set_termios(struct uart_port *port, | ||
430 | struct ktermios *termios, struct ktermios *old) | ||
431 | { | ||
432 | unsigned int cval = 0; | ||
433 | unsigned int baud; | ||
434 | unsigned long flags; | ||
435 | unsigned int ctrl_reg, mode_reg; | ||
436 | |||
437 | spin_lock_irqsave(&port->lock, flags); | ||
438 | |||
439 | /* Empty the receive FIFO 1st before making changes */ | ||
440 | while ((xuartps_readl(XUARTPS_SR_OFFSET) & | ||
441 | XUARTPS_SR_RXEMPTY) != XUARTPS_SR_RXEMPTY) { | ||
442 | xuartps_readl(XUARTPS_FIFO_OFFSET); | ||
443 | } | ||
444 | |||
445 | /* Disable the TX and RX to set baud rate */ | ||
446 | xuartps_writel(xuartps_readl(XUARTPS_CR_OFFSET) | | ||
447 | (XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS), | ||
448 | XUARTPS_CR_OFFSET); | ||
449 | |||
450 | /* Min baud rate = 6bps and Max Baud Rate is 10Mbps for 100Mhz clk */ | ||
451 | baud = uart_get_baud_rate(port, termios, old, 0, 10000000); | ||
452 | baud = xuartps_set_baud_rate(port, baud); | ||
453 | if (tty_termios_baud_rate(termios)) | ||
454 | tty_termios_encode_baud_rate(termios, baud, baud); | ||
455 | |||
456 | /* | ||
457 | * Update the per-port timeout. | ||
458 | */ | ||
459 | uart_update_timeout(port, termios->c_cflag, baud); | ||
460 | |||
461 | /* Set TX/RX Reset */ | ||
462 | xuartps_writel(xuartps_readl(XUARTPS_CR_OFFSET) | | ||
463 | (XUARTPS_CR_TXRST | XUARTPS_CR_RXRST), | ||
464 | XUARTPS_CR_OFFSET); | ||
465 | |||
466 | ctrl_reg = xuartps_readl(XUARTPS_CR_OFFSET); | ||
467 | |||
468 | /* Clear the RX disable and TX disable bits and then set the TX enable | ||
469 | * bit and RX enable bit to enable the transmitter and receiver. | ||
470 | */ | ||
471 | xuartps_writel( | ||
472 | (ctrl_reg & ~(XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS)) | ||
473 | | (XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN), | ||
474 | XUARTPS_CR_OFFSET); | ||
475 | |||
476 | xuartps_writel(10, XUARTPS_RXTOUT_OFFSET); | ||
477 | |||
478 | port->read_status_mask = XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_RXTRIG | | ||
479 | XUARTPS_IXR_OVERRUN | XUARTPS_IXR_TOUT; | ||
480 | port->ignore_status_mask = 0; | ||
481 | |||
482 | if (termios->c_iflag & INPCK) | ||
483 | port->read_status_mask |= XUARTPS_IXR_PARITY | | ||
484 | XUARTPS_IXR_FRAMING; | ||
485 | |||
486 | if (termios->c_iflag & IGNPAR) | ||
487 | port->ignore_status_mask |= XUARTPS_IXR_PARITY | | ||
488 | XUARTPS_IXR_FRAMING | XUARTPS_IXR_OVERRUN; | ||
489 | |||
490 | /* ignore all characters if CREAD is not set */ | ||
491 | if ((termios->c_cflag & CREAD) == 0) | ||
492 | port->ignore_status_mask |= XUARTPS_IXR_RXTRIG | | ||
493 | XUARTPS_IXR_TOUT | XUARTPS_IXR_PARITY | | ||
494 | XUARTPS_IXR_FRAMING | XUARTPS_IXR_OVERRUN; | ||
495 | |||
496 | mode_reg = xuartps_readl(XUARTPS_MR_OFFSET); | ||
497 | |||
498 | /* Handling Data Size */ | ||
499 | switch (termios->c_cflag & CSIZE) { | ||
500 | case CS6: | ||
501 | cval |= XUARTPS_MR_CHARLEN_6_BIT; | ||
502 | break; | ||
503 | case CS7: | ||
504 | cval |= XUARTPS_MR_CHARLEN_7_BIT; | ||
505 | break; | ||
506 | default: | ||
507 | case CS8: | ||
508 | cval |= XUARTPS_MR_CHARLEN_8_BIT; | ||
509 | termios->c_cflag &= ~CSIZE; | ||
510 | termios->c_cflag |= CS8; | ||
511 | break; | ||
512 | } | ||
513 | |||
514 | /* Handling Parity and Stop Bits length */ | ||
515 | if (termios->c_cflag & CSTOPB) | ||
516 | cval |= XUARTPS_MR_STOPMODE_2_BIT; /* 2 STOP bits */ | ||
517 | else | ||
518 | cval |= XUARTPS_MR_STOPMODE_1_BIT; /* 1 STOP bit */ | ||
519 | |||
520 | if (termios->c_cflag & PARENB) { | ||
521 | /* Mark or Space parity */ | ||
522 | if (termios->c_cflag & CMSPAR) { | ||
523 | if (termios->c_cflag & PARODD) | ||
524 | cval |= XUARTPS_MR_PARITY_MARK; | ||
525 | else | ||
526 | cval |= XUARTPS_MR_PARITY_SPACE; | ||
527 | } else if (termios->c_cflag & PARODD) | ||
528 | cval |= XUARTPS_MR_PARITY_ODD; | ||
529 | else | ||
530 | cval |= XUARTPS_MR_PARITY_EVEN; | ||
531 | } else | ||
532 | cval |= XUARTPS_MR_PARITY_NONE; | ||
533 | xuartps_writel(cval , XUARTPS_MR_OFFSET); | ||
534 | |||
535 | spin_unlock_irqrestore(&port->lock, flags); | ||
536 | } | ||
537 | |||
538 | /** | ||
539 | * xuartps_startup - Called when an application opens a xuartps port | ||
540 | * @port: Handle to the uart port structure | ||
541 | * | ||
542 | * Returns 0 on success, negative error otherwise | ||
543 | **/ | ||
544 | static int xuartps_startup(struct uart_port *port) | ||
545 | { | ||
546 | unsigned int retval = 0, status = 0; | ||
547 | |||
548 | retval = request_irq(port->irq, xuartps_isr, 0, XUARTPS_NAME, | ||
549 | (void *)port); | ||
550 | if (retval) | ||
551 | return retval; | ||
552 | |||
553 | /* Disable the TX and RX */ | ||
554 | xuartps_writel(XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS, | ||
555 | XUARTPS_CR_OFFSET); | ||
556 | |||
557 | /* Set the Control Register with TX/RX Enable, TX/RX Reset, | ||
558 | * no break chars. | ||
559 | */ | ||
560 | xuartps_writel(XUARTPS_CR_TXRST | XUARTPS_CR_RXRST, | ||
561 | XUARTPS_CR_OFFSET); | ||
562 | |||
563 | status = xuartps_readl(XUARTPS_CR_OFFSET); | ||
564 | |||
565 | /* Clear the RX disable and TX disable bits and then set the TX enable | ||
566 | * bit and RX enable bit to enable the transmitter and receiver. | ||
567 | */ | ||
568 | xuartps_writel((status & ~(XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS)) | ||
569 | | (XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN | | ||
570 | XUARTPS_CR_STOPBRK), XUARTPS_CR_OFFSET); | ||
571 | |||
572 | /* Set the Mode Register with normal mode,8 data bits,1 stop bit, | ||
573 | * no parity. | ||
574 | */ | ||
575 | xuartps_writel(XUARTPS_MR_CHMODE_NORM | XUARTPS_MR_STOPMODE_1_BIT | ||
576 | | XUARTPS_MR_PARITY_NONE | XUARTPS_MR_CHARLEN_8_BIT, | ||
577 | XUARTPS_MR_OFFSET); | ||
578 | |||
579 | /* Set the RX FIFO Trigger level to 14 assuming FIFO size as 16 */ | ||
580 | xuartps_writel(14, XUARTPS_RXWM_OFFSET); | ||
581 | |||
582 | /* Receive Timeout register is enabled with value of 10 */ | ||
583 | xuartps_writel(10, XUARTPS_RXTOUT_OFFSET); | ||
584 | |||
585 | |||
586 | /* Set the Interrupt Registers with desired interrupts */ | ||
587 | xuartps_writel(XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_PARITY | | ||
588 | XUARTPS_IXR_FRAMING | XUARTPS_IXR_OVERRUN | | ||
589 | XUARTPS_IXR_RXTRIG | XUARTPS_IXR_TOUT, XUARTPS_IER_OFFSET); | ||
590 | xuartps_writel(~(XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_PARITY | | ||
591 | XUARTPS_IXR_FRAMING | XUARTPS_IXR_OVERRUN | | ||
592 | XUARTPS_IXR_RXTRIG | XUARTPS_IXR_TOUT), XUARTPS_IDR_OFFSET); | ||
593 | |||
594 | return retval; | ||
595 | } | ||
596 | |||
597 | /** | ||
598 | * xuartps_shutdown - Called when an application closes a xuartps port | ||
599 | * @port: Handle to the uart port structure | ||
600 | * | ||
601 | **/ | ||
602 | static void xuartps_shutdown(struct uart_port *port) | ||
603 | { | ||
604 | int status; | ||
605 | |||
606 | /* Disable interrupts */ | ||
607 | status = xuartps_readl(XUARTPS_IMR_OFFSET); | ||
608 | xuartps_writel(status, XUARTPS_IDR_OFFSET); | ||
609 | |||
610 | /* Disable the TX and RX */ | ||
611 | xuartps_writel(XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS, | ||
612 | XUARTPS_CR_OFFSET); | ||
613 | free_irq(port->irq, port); | ||
614 | } | ||
615 | |||
616 | /** | ||
617 | * xuartps_type - Set UART type to xuartps port | ||
618 | * @port: Handle to the uart port structure | ||
619 | * | ||
620 | * Returns string on success, NULL otherwise | ||
621 | **/ | ||
622 | static const char *xuartps_type(struct uart_port *port) | ||
623 | { | ||
624 | return port->type == PORT_XUARTPS ? XUARTPS_NAME : NULL; | ||
625 | } | ||
626 | |||
627 | /** | ||
628 | * xuartps_verify_port - Verify the port params | ||
629 | * @port: Handle to the uart port structure | ||
630 | * @ser: Handle to the structure whose members are compared | ||
631 | * | ||
632 | * Returns 0 if success otherwise -EINVAL | ||
633 | **/ | ||
634 | static int xuartps_verify_port(struct uart_port *port, | ||
635 | struct serial_struct *ser) | ||
636 | { | ||
637 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_XUARTPS) | ||
638 | return -EINVAL; | ||
639 | if (port->irq != ser->irq) | ||
640 | return -EINVAL; | ||
641 | if (ser->io_type != UPIO_MEM) | ||
642 | return -EINVAL; | ||
643 | if (port->iobase != ser->port) | ||
644 | return -EINVAL; | ||
645 | if (ser->hub6 != 0) | ||
646 | return -EINVAL; | ||
647 | return 0; | ||
648 | } | ||
649 | |||
650 | /** | ||
651 | * xuartps_request_port - Claim the memory region attached to xuartps port, | ||
652 | * called when the driver adds a xuartps port via | ||
653 | * uart_add_one_port() | ||
654 | * @port: Handle to the uart port structure | ||
655 | * | ||
656 | * Returns 0, -ENOMEM if request fails | ||
657 | **/ | ||
658 | static int xuartps_request_port(struct uart_port *port) | ||
659 | { | ||
660 | if (!request_mem_region(port->mapbase, XUARTPS_REGISTER_SPACE, | ||
661 | XUARTPS_NAME)) { | ||
662 | return -ENOMEM; | ||
663 | } | ||
664 | |||
665 | port->membase = ioremap(port->mapbase, XUARTPS_REGISTER_SPACE); | ||
666 | if (!port->membase) { | ||
667 | dev_err(port->dev, "Unable to map registers\n"); | ||
668 | release_mem_region(port->mapbase, XUARTPS_REGISTER_SPACE); | ||
669 | return -ENOMEM; | ||
670 | } | ||
671 | return 0; | ||
672 | } | ||
673 | |||
674 | /** | ||
675 | * xuartps_release_port - Release the memory region attached to a xuartps | ||
676 | * port, called when the driver removes a xuartps | ||
677 | * port via uart_remove_one_port(). | ||
678 | * @port: Handle to the uart port structure | ||
679 | * | ||
680 | **/ | ||
681 | static void xuartps_release_port(struct uart_port *port) | ||
682 | { | ||
683 | release_mem_region(port->mapbase, XUARTPS_REGISTER_SPACE); | ||
684 | iounmap(port->membase); | ||
685 | port->membase = NULL; | ||
686 | } | ||
687 | |||
688 | /** | ||
689 | * xuartps_config_port - Configure xuartps, called when the driver adds a | ||
690 | * xuartps port | ||
691 | * @port: Handle to the uart port structure | ||
692 | * @flags: If any | ||
693 | * | ||
694 | **/ | ||
695 | static void xuartps_config_port(struct uart_port *port, int flags) | ||
696 | { | ||
697 | if (flags & UART_CONFIG_TYPE && xuartps_request_port(port) == 0) | ||
698 | port->type = PORT_XUARTPS; | ||
699 | } | ||
700 | |||
701 | /** | ||
702 | * xuartps_get_mctrl - Get the modem control state | ||
703 | * | ||
704 | * @port: Handle to the uart port structure | ||
705 | * | ||
706 | * Returns the modem control state | ||
707 | * | ||
708 | **/ | ||
709 | static unsigned int xuartps_get_mctrl(struct uart_port *port) | ||
710 | { | ||
711 | return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; | ||
712 | } | ||
713 | |||
714 | static void xuartps_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
715 | { | ||
716 | /* N/A */ | ||
717 | } | ||
718 | |||
719 | static void xuartps_enable_ms(struct uart_port *port) | ||
720 | { | ||
721 | /* N/A */ | ||
722 | } | ||
723 | |||
724 | /** The UART operations structure | ||
725 | */ | ||
726 | static struct uart_ops xuartps_ops = { | ||
727 | .set_mctrl = xuartps_set_mctrl, | ||
728 | .get_mctrl = xuartps_get_mctrl, | ||
729 | .enable_ms = xuartps_enable_ms, | ||
730 | |||
731 | .start_tx = xuartps_start_tx, /* Start transmitting */ | ||
732 | .stop_tx = xuartps_stop_tx, /* Stop transmission */ | ||
733 | .stop_rx = xuartps_stop_rx, /* Stop reception */ | ||
734 | .tx_empty = xuartps_tx_empty, /* Transmitter busy? */ | ||
735 | .break_ctl = xuartps_break_ctl, /* Start/stop | ||
736 | * transmitting break | ||
737 | */ | ||
738 | .set_termios = xuartps_set_termios, /* Set termios */ | ||
739 | .startup = xuartps_startup, /* App opens xuartps */ | ||
740 | .shutdown = xuartps_shutdown, /* App closes xuartps */ | ||
741 | .type = xuartps_type, /* Set UART type */ | ||
742 | .verify_port = xuartps_verify_port, /* Verification of port | ||
743 | * params | ||
744 | */ | ||
745 | .request_port = xuartps_request_port, /* Claim resources | ||
746 | * associated with a | ||
747 | * xuartps port | ||
748 | */ | ||
749 | .release_port = xuartps_release_port, /* Release resources | ||
750 | * associated with a | ||
751 | * xuartps port | ||
752 | */ | ||
753 | .config_port = xuartps_config_port, /* Configure when driver | ||
754 | * adds a xuartps port | ||
755 | */ | ||
756 | }; | ||
757 | |||
758 | static struct uart_port xuartps_port[2]; | ||
759 | |||
760 | /** | ||
761 | * xuartps_get_port - Configure the port from the platform device resource | ||
762 | * info | ||
763 | * | ||
764 | * Returns a pointer to a uart_port or NULL for failure | ||
765 | **/ | ||
766 | static struct uart_port *xuartps_get_port(void) | ||
767 | { | ||
768 | struct uart_port *port; | ||
769 | int id; | ||
770 | |||
771 | /* Find the next unused port */ | ||
772 | for (id = 0; id < XUARTPS_NR_PORTS; id++) | ||
773 | if (xuartps_port[id].mapbase == 0) | ||
774 | break; | ||
775 | |||
776 | if (id >= XUARTPS_NR_PORTS) | ||
777 | return NULL; | ||
778 | |||
779 | port = &xuartps_port[id]; | ||
780 | |||
781 | /* At this point, we've got an empty uart_port struct, initialize it */ | ||
782 | spin_lock_init(&port->lock); | ||
783 | port->membase = NULL; | ||
784 | port->iobase = 1; /* mark port in use */ | ||
785 | port->irq = 0; | ||
786 | port->type = PORT_UNKNOWN; | ||
787 | port->iotype = UPIO_MEM32; | ||
788 | port->flags = UPF_BOOT_AUTOCONF; | ||
789 | port->ops = &xuartps_ops; | ||
790 | port->fifosize = XUARTPS_FIFO_SIZE; | ||
791 | port->line = id; | ||
792 | port->dev = NULL; | ||
793 | return port; | ||
794 | } | ||
795 | |||
796 | /*-----------------------Console driver operations--------------------------*/ | ||
797 | |||
798 | #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE | ||
799 | /** | ||
800 | * xuartps_console_wait_tx - Wait for the TX to be full | ||
801 | * @port: Handle to the uart port structure | ||
802 | * | ||
803 | **/ | ||
804 | static void xuartps_console_wait_tx(struct uart_port *port) | ||
805 | { | ||
806 | while ((xuartps_readl(XUARTPS_SR_OFFSET) & XUARTPS_SR_TXEMPTY) | ||
807 | != XUARTPS_SR_TXEMPTY) | ||
808 | barrier(); | ||
809 | } | ||
810 | |||
811 | /** | ||
812 | * xuartps_console_putchar - write the character to the FIFO buffer | ||
813 | * @port: Handle to the uart port structure | ||
814 | * @ch: Character to be written | ||
815 | * | ||
816 | **/ | ||
817 | static void xuartps_console_putchar(struct uart_port *port, int ch) | ||
818 | { | ||
819 | xuartps_console_wait_tx(port); | ||
820 | xuartps_writel(ch, XUARTPS_FIFO_OFFSET); | ||
821 | } | ||
822 | |||
823 | /** | ||
824 | * xuartps_console_write - perform write operation | ||
825 | * @port: Handle to the uart port structure | ||
826 | * @s: Pointer to character array | ||
827 | * @count: No of characters | ||
828 | **/ | ||
829 | static void xuartps_console_write(struct console *co, const char *s, | ||
830 | unsigned int count) | ||
831 | { | ||
832 | struct uart_port *port = &xuartps_port[co->index]; | ||
833 | unsigned long flags; | ||
834 | unsigned int imr; | ||
835 | int locked = 1; | ||
836 | |||
837 | if (oops_in_progress) | ||
838 | locked = spin_trylock_irqsave(&port->lock, flags); | ||
839 | else | ||
840 | spin_lock_irqsave(&port->lock, flags); | ||
841 | |||
842 | /* save and disable interrupt */ | ||
843 | imr = xuartps_readl(XUARTPS_IMR_OFFSET); | ||
844 | xuartps_writel(imr, XUARTPS_IDR_OFFSET); | ||
845 | |||
846 | uart_console_write(port, s, count, xuartps_console_putchar); | ||
847 | xuartps_console_wait_tx(port); | ||
848 | |||
849 | /* restore interrupt state, it seems like there may be a h/w bug | ||
850 | * in that the interrupt enable register should not need to be | ||
851 | * written based on the data sheet | ||
852 | */ | ||
853 | xuartps_writel(~imr, XUARTPS_IDR_OFFSET); | ||
854 | xuartps_writel(imr, XUARTPS_IER_OFFSET); | ||
855 | |||
856 | if (locked) | ||
857 | spin_unlock_irqrestore(&port->lock, flags); | ||
858 | } | ||
859 | |||
860 | /** | ||
861 | * xuartps_console_setup - Initialize the uart to default config | ||
862 | * @co: Console handle | ||
863 | * @options: Initial settings of uart | ||
864 | * | ||
865 | * Returns 0, -ENODEV if no device | ||
866 | **/ | ||
867 | static int __init xuartps_console_setup(struct console *co, char *options) | ||
868 | { | ||
869 | struct uart_port *port = &xuartps_port[co->index]; | ||
870 | int baud = 9600; | ||
871 | int bits = 8; | ||
872 | int parity = 'n'; | ||
873 | int flow = 'n'; | ||
874 | |||
875 | if (co->index < 0 || co->index >= XUARTPS_NR_PORTS) | ||
876 | return -EINVAL; | ||
877 | |||
878 | if (!port->mapbase) { | ||
879 | pr_debug("console on ttyPS%i not present\n", co->index); | ||
880 | return -ENODEV; | ||
881 | } | ||
882 | |||
883 | if (options) | ||
884 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
885 | |||
886 | return uart_set_options(port, co, baud, parity, bits, flow); | ||
887 | } | ||
888 | |||
889 | static struct uart_driver xuartps_uart_driver; | ||
890 | |||
891 | static struct console xuartps_console = { | ||
892 | .name = XUARTPS_TTY_NAME, | ||
893 | .write = xuartps_console_write, | ||
894 | .device = uart_console_device, | ||
895 | .setup = xuartps_console_setup, | ||
896 | .flags = CON_PRINTBUFFER, | ||
897 | .index = -1, /* Specified on the cmdline (e.g. console=ttyPS ) */ | ||
898 | .data = &xuartps_uart_driver, | ||
899 | }; | ||
900 | |||
901 | /** | ||
902 | * xuartps_console_init - Initialization call | ||
903 | * | ||
904 | * Returns 0 on success, negative error otherwise | ||
905 | **/ | ||
906 | static int __init xuartps_console_init(void) | ||
907 | { | ||
908 | register_console(&xuartps_console); | ||
909 | return 0; | ||
910 | } | ||
911 | |||
912 | console_initcall(xuartps_console_init); | ||
913 | |||
914 | #endif /* CONFIG_SERIAL_XILINX_PS_UART_CONSOLE */ | ||
915 | |||
916 | /** Structure Definitions | ||
917 | */ | ||
918 | static struct uart_driver xuartps_uart_driver = { | ||
919 | .owner = THIS_MODULE, /* Owner */ | ||
920 | .driver_name = XUARTPS_NAME, /* Driver name */ | ||
921 | .dev_name = XUARTPS_TTY_NAME, /* Node name */ | ||
922 | .major = XUARTPS_MAJOR, /* Major number */ | ||
923 | .minor = XUARTPS_MINOR, /* Minor number */ | ||
924 | .nr = XUARTPS_NR_PORTS, /* Number of UART ports */ | ||
925 | #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE | ||
926 | .cons = &xuartps_console, /* Console */ | ||
927 | #endif | ||
928 | }; | ||
929 | |||
930 | /* --------------------------------------------------------------------- | ||
931 | * Platform bus binding | ||
932 | */ | ||
933 | /** | ||
934 | * xuartps_probe - Platform driver probe | ||
935 | * @pdev: Pointer to the platform device structure | ||
936 | * | ||
937 | * Returns 0 on success, negative error otherwise | ||
938 | **/ | ||
939 | static int __devinit xuartps_probe(struct platform_device *pdev) | ||
940 | { | ||
941 | int rc; | ||
942 | struct uart_port *port; | ||
943 | struct resource *res, *res2; | ||
944 | int clk = 0; | ||
945 | |||
946 | #ifdef CONFIG_OF | ||
947 | const unsigned int *prop; | ||
948 | |||
949 | prop = of_get_property(pdev->dev.of_node, "clock", NULL); | ||
950 | if (prop) | ||
951 | clk = be32_to_cpup(prop); | ||
952 | #else | ||
953 | clk = *((unsigned int *)(pdev->dev.platform_data)); | ||
954 | #endif | ||
955 | if (!clk) { | ||
956 | dev_err(&pdev->dev, "no clock specified\n"); | ||
957 | return -ENODEV; | ||
958 | } | ||
959 | |||
960 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
961 | if (!res) | ||
962 | return -ENODEV; | ||
963 | |||
964 | res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
965 | if (!res2) | ||
966 | return -ENODEV; | ||
967 | |||
968 | /* Initialize the port structure */ | ||
969 | port = xuartps_get_port(); | ||
970 | |||
971 | if (!port) { | ||
972 | dev_err(&pdev->dev, "Cannot get uart_port structure\n"); | ||
973 | return -ENODEV; | ||
974 | } else { | ||
975 | /* Register the port. | ||
976 | * This function also registers this device with the tty layer | ||
977 | * and triggers invocation of the config_port() entry point. | ||
978 | */ | ||
979 | port->mapbase = res->start; | ||
980 | port->irq = res2->start; | ||
981 | port->dev = &pdev->dev; | ||
982 | port->uartclk = clk; | ||
983 | dev_set_drvdata(&pdev->dev, port); | ||
984 | rc = uart_add_one_port(&xuartps_uart_driver, port); | ||
985 | if (rc) { | ||
986 | dev_err(&pdev->dev, | ||
987 | "uart_add_one_port() failed; err=%i\n", rc); | ||
988 | dev_set_drvdata(&pdev->dev, NULL); | ||
989 | return rc; | ||
990 | } | ||
991 | return 0; | ||
992 | } | ||
993 | } | ||
994 | |||
995 | /** | ||
996 | * xuartps_remove - called when the platform driver is unregistered | ||
997 | * @pdev: Pointer to the platform device structure | ||
998 | * | ||
999 | * Returns 0 on success, negative error otherwise | ||
1000 | **/ | ||
1001 | static int __devexit xuartps_remove(struct platform_device *pdev) | ||
1002 | { | ||
1003 | struct uart_port *port = dev_get_drvdata(&pdev->dev); | ||
1004 | int rc = 0; | ||
1005 | |||
1006 | /* Remove the xuartps port from the serial core */ | ||
1007 | if (port) { | ||
1008 | rc = uart_remove_one_port(&xuartps_uart_driver, port); | ||
1009 | dev_set_drvdata(&pdev->dev, NULL); | ||
1010 | port->mapbase = 0; | ||
1011 | } | ||
1012 | return rc; | ||
1013 | } | ||
1014 | |||
1015 | /** | ||
1016 | * xuartps_suspend - suspend event | ||
1017 | * @pdev: Pointer to the platform device structure | ||
1018 | * @state: State of the device | ||
1019 | * | ||
1020 | * Returns 0 | ||
1021 | **/ | ||
1022 | static int xuartps_suspend(struct platform_device *pdev, pm_message_t state) | ||
1023 | { | ||
1024 | /* Call the API provided in serial_core.c file which handles | ||
1025 | * the suspend. | ||
1026 | */ | ||
1027 | uart_suspend_port(&xuartps_uart_driver, &xuartps_port[pdev->id]); | ||
1028 | return 0; | ||
1029 | } | ||
1030 | |||
1031 | /** | ||
1032 | * xuartps_resume - Resume after a previous suspend | ||
1033 | * @pdev: Pointer to the platform device structure | ||
1034 | * | ||
1035 | * Returns 0 | ||
1036 | **/ | ||
1037 | static int xuartps_resume(struct platform_device *pdev) | ||
1038 | { | ||
1039 | uart_resume_port(&xuartps_uart_driver, &xuartps_port[pdev->id]); | ||
1040 | return 0; | ||
1041 | } | ||
1042 | |||
1043 | /* Match table for of_platform binding */ | ||
1044 | |||
1045 | #ifdef CONFIG_OF | ||
1046 | static struct of_device_id xuartps_of_match[] __devinitdata = { | ||
1047 | { .compatible = "xlnx,xuartps", }, | ||
1048 | {} | ||
1049 | }; | ||
1050 | MODULE_DEVICE_TABLE(of, xuartps_of_match); | ||
1051 | #else | ||
1052 | #define xuartps_of_match NULL | ||
1053 | #endif | ||
1054 | |||
1055 | static struct platform_driver xuartps_platform_driver = { | ||
1056 | .probe = xuartps_probe, /* Probe method */ | ||
1057 | .remove = __exit_p(xuartps_remove), /* Detach method */ | ||
1058 | .suspend = xuartps_suspend, /* Suspend */ | ||
1059 | .resume = xuartps_resume, /* Resume after a suspend */ | ||
1060 | .driver = { | ||
1061 | .owner = THIS_MODULE, | ||
1062 | .name = XUARTPS_NAME, /* Driver name */ | ||
1063 | .of_match_table = xuartps_of_match, | ||
1064 | }, | ||
1065 | }; | ||
1066 | |||
1067 | /* --------------------------------------------------------------------- | ||
1068 | * Module Init and Exit | ||
1069 | */ | ||
1070 | /** | ||
1071 | * xuartps_init - Initial driver registration call | ||
1072 | * | ||
1073 | * Returns whether the registration was successful or not | ||
1074 | **/ | ||
1075 | static int __init xuartps_init(void) | ||
1076 | { | ||
1077 | int retval = 0; | ||
1078 | |||
1079 | /* Register the xuartps driver with the serial core */ | ||
1080 | retval = uart_register_driver(&xuartps_uart_driver); | ||
1081 | if (retval) | ||
1082 | return retval; | ||
1083 | |||
1084 | /* Register the platform driver */ | ||
1085 | retval = platform_driver_register(&xuartps_platform_driver); | ||
1086 | if (retval) | ||
1087 | uart_unregister_driver(&xuartps_uart_driver); | ||
1088 | |||
1089 | return retval; | ||
1090 | } | ||
1091 | |||
1092 | /** | ||
1093 | * xuartps_exit - Driver unregistration call | ||
1094 | **/ | ||
1095 | static void __exit xuartps_exit(void) | ||
1096 | { | ||
1097 | /* The order of unregistration is important. Unregister the | ||
1098 | * UART driver before the platform driver crashes the system. | ||
1099 | */ | ||
1100 | |||
1101 | /* Unregister the platform driver */ | ||
1102 | platform_driver_unregister(&xuartps_platform_driver); | ||
1103 | |||
1104 | /* Unregister the xuartps driver */ | ||
1105 | uart_unregister_driver(&xuartps_uart_driver); | ||
1106 | } | ||
1107 | |||
1108 | module_init(xuartps_init); | ||
1109 | module_exit(xuartps_exit); | ||
1110 | |||
1111 | MODULE_DESCRIPTION("Driver for PS UART"); | ||
1112 | MODULE_AUTHOR("Xilinx Inc."); | ||
1113 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c index 27da23d98e3f..272e417a9b0d 100644 --- a/drivers/tty/synclink.c +++ b/drivers/tty/synclink.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/char/synclink.c | ||
3 | * | ||
4 | * $Id: synclink.c,v 4.38 2005/11/07 16:30:34 paulkf Exp $ | 2 | * $Id: synclink.c,v 4.38 2005/11/07 16:30:34 paulkf Exp $ |
5 | * | 3 | * |
6 | * Device driver for Microgate SyncLink ISA and PCI | 4 | * Device driver for Microgate SyncLink ISA and PCI |
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index f1a7918d71aa..46de2e075dac 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c | |||
@@ -416,6 +416,7 @@ static void flush_to_ldisc(struct work_struct *work) | |||
416 | struct tty_buffer *head, *tail = tty->buf.tail; | 416 | struct tty_buffer *head, *tail = tty->buf.tail; |
417 | int seen_tail = 0; | 417 | int seen_tail = 0; |
418 | while ((head = tty->buf.head) != NULL) { | 418 | while ((head = tty->buf.head) != NULL) { |
419 | int copied; | ||
419 | int count; | 420 | int count; |
420 | char *char_buf; | 421 | char *char_buf; |
421 | unsigned char *flag_buf; | 422 | unsigned char *flag_buf; |
@@ -442,17 +443,19 @@ static void flush_to_ldisc(struct work_struct *work) | |||
442 | line discipline as we want to empty the queue */ | 443 | line discipline as we want to empty the queue */ |
443 | if (test_bit(TTY_FLUSHPENDING, &tty->flags)) | 444 | if (test_bit(TTY_FLUSHPENDING, &tty->flags)) |
444 | break; | 445 | break; |
445 | if (!tty->receive_room || seen_tail) | ||
446 | break; | ||
447 | if (count > tty->receive_room) | ||
448 | count = tty->receive_room; | ||
449 | char_buf = head->char_buf_ptr + head->read; | 446 | char_buf = head->char_buf_ptr + head->read; |
450 | flag_buf = head->flag_buf_ptr + head->read; | 447 | flag_buf = head->flag_buf_ptr + head->read; |
451 | head->read += count; | ||
452 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 448 | spin_unlock_irqrestore(&tty->buf.lock, flags); |
453 | disc->ops->receive_buf(tty, char_buf, | 449 | copied = disc->ops->receive_buf(tty, char_buf, |
454 | flag_buf, count); | 450 | flag_buf, count); |
455 | spin_lock_irqsave(&tty->buf.lock, flags); | 451 | spin_lock_irqsave(&tty->buf.lock, flags); |
452 | |||
453 | head->read += copied; | ||
454 | |||
455 | if (copied == 0 || seen_tail) { | ||
456 | schedule_work(&tty->buf.work); | ||
457 | break; | ||
458 | } | ||
456 | } | 459 | } |
457 | clear_bit(TTY_FLUSHING, &tty->flags); | 460 | clear_bit(TTY_FLUSHING, &tty->flags); |
458 | } | 461 | } |
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index d7d50b48287e..6556f7452ba6 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/char/tty_io.c | ||
3 | * | ||
4 | * Copyright (C) 1991, 1992 Linus Torvalds | 2 | * Copyright (C) 1991, 1992 Linus Torvalds |
5 | */ | 3 | */ |
6 | 4 | ||
@@ -964,12 +962,14 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, | |||
964 | } | 962 | } |
965 | 963 | ||
966 | void tty_write_unlock(struct tty_struct *tty) | 964 | void tty_write_unlock(struct tty_struct *tty) |
965 | __releases(&tty->atomic_write_lock) | ||
967 | { | 966 | { |
968 | mutex_unlock(&tty->atomic_write_lock); | 967 | mutex_unlock(&tty->atomic_write_lock); |
969 | wake_up_interruptible_poll(&tty->write_wait, POLLOUT); | 968 | wake_up_interruptible_poll(&tty->write_wait, POLLOUT); |
970 | } | 969 | } |
971 | 970 | ||
972 | int tty_write_lock(struct tty_struct *tty, int ndelay) | 971 | int tty_write_lock(struct tty_struct *tty, int ndelay) |
972 | __acquires(&tty->atomic_write_lock) | ||
973 | { | 973 | { |
974 | if (!mutex_trylock(&tty->atomic_write_lock)) { | 974 | if (!mutex_trylock(&tty->atomic_write_lock)) { |
975 | if (ndelay) | 975 | if (ndelay) |
@@ -1391,16 +1391,15 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, | |||
1391 | return ERR_PTR(-ENODEV); | 1391 | return ERR_PTR(-ENODEV); |
1392 | 1392 | ||
1393 | tty = alloc_tty_struct(); | 1393 | tty = alloc_tty_struct(); |
1394 | if (!tty) | 1394 | if (!tty) { |
1395 | goto fail_no_mem; | 1395 | retval = -ENOMEM; |
1396 | goto err_module_put; | ||
1397 | } | ||
1396 | initialize_tty_struct(tty, driver, idx); | 1398 | initialize_tty_struct(tty, driver, idx); |
1397 | 1399 | ||
1398 | retval = tty_driver_install_tty(driver, tty); | 1400 | retval = tty_driver_install_tty(driver, tty); |
1399 | if (retval < 0) { | 1401 | if (retval < 0) |
1400 | free_tty_struct(tty); | 1402 | goto err_deinit_tty; |
1401 | module_put(driver->owner); | ||
1402 | return ERR_PTR(retval); | ||
1403 | } | ||
1404 | 1403 | ||
1405 | /* | 1404 | /* |
1406 | * Structures all installed ... call the ldisc open routines. | 1405 | * Structures all installed ... call the ldisc open routines. |
@@ -1409,15 +1408,18 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, | |||
1409 | */ | 1408 | */ |
1410 | retval = tty_ldisc_setup(tty, tty->link); | 1409 | retval = tty_ldisc_setup(tty, tty->link); |
1411 | if (retval) | 1410 | if (retval) |
1412 | goto release_mem_out; | 1411 | goto err_release_tty; |
1413 | return tty; | 1412 | return tty; |
1414 | 1413 | ||
1415 | fail_no_mem: | 1414 | err_deinit_tty: |
1415 | deinitialize_tty_struct(tty); | ||
1416 | free_tty_struct(tty); | ||
1417 | err_module_put: | ||
1416 | module_put(driver->owner); | 1418 | module_put(driver->owner); |
1417 | return ERR_PTR(-ENOMEM); | 1419 | return ERR_PTR(retval); |
1418 | 1420 | ||
1419 | /* call the tty release_tty routine to clean out this slot */ | 1421 | /* call the tty release_tty routine to clean out this slot */ |
1420 | release_mem_out: | 1422 | err_release_tty: |
1421 | if (printk_ratelimit()) | 1423 | if (printk_ratelimit()) |
1422 | printk(KERN_INFO "tty_init_dev: ldisc open failed, " | 1424 | printk(KERN_INFO "tty_init_dev: ldisc open failed, " |
1423 | "clearing slot %d\n", idx); | 1425 | "clearing slot %d\n", idx); |
@@ -1892,6 +1894,7 @@ got_driver: | |||
1892 | retval = tty_add_file(tty, filp); | 1894 | retval = tty_add_file(tty, filp); |
1893 | if (retval) { | 1895 | if (retval) { |
1894 | tty_unlock(); | 1896 | tty_unlock(); |
1897 | tty_release(inode, filp); | ||
1895 | return retval; | 1898 | return retval; |
1896 | } | 1899 | } |
1897 | 1900 | ||
@@ -1902,12 +1905,10 @@ got_driver: | |||
1902 | #ifdef TTY_DEBUG_HANGUP | 1905 | #ifdef TTY_DEBUG_HANGUP |
1903 | printk(KERN_DEBUG "opening %s...", tty->name); | 1906 | printk(KERN_DEBUG "opening %s...", tty->name); |
1904 | #endif | 1907 | #endif |
1905 | if (!retval) { | 1908 | if (tty->ops->open) |
1906 | if (tty->ops->open) | 1909 | retval = tty->ops->open(tty, filp); |
1907 | retval = tty->ops->open(tty, filp); | 1910 | else |
1908 | else | 1911 | retval = -ENODEV; |
1909 | retval = -ENODEV; | ||
1910 | } | ||
1911 | filp->f_flags = saved_flags; | 1912 | filp->f_flags = saved_flags; |
1912 | 1913 | ||
1913 | if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && | 1914 | if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && |
@@ -2888,6 +2889,20 @@ void initialize_tty_struct(struct tty_struct *tty, | |||
2888 | } | 2889 | } |
2889 | 2890 | ||
2890 | /** | 2891 | /** |
2892 | * deinitialize_tty_struct | ||
2893 | * @tty: tty to deinitialize | ||
2894 | * | ||
2895 | * This subroutine deinitializes a tty structure that has been newly | ||
2896 | * allocated but tty_release cannot be called on that yet. | ||
2897 | * | ||
2898 | * Locking: none - tty in question must not be exposed at this point | ||
2899 | */ | ||
2900 | void deinitialize_tty_struct(struct tty_struct *tty) | ||
2901 | { | ||
2902 | tty_ldisc_deinit(tty); | ||
2903 | } | ||
2904 | |||
2905 | /** | ||
2891 | * tty_put_char - write one character to a tty | 2906 | * tty_put_char - write one character to a tty |
2892 | * @tty: tty | 2907 | * @tty: tty |
2893 | * @ch: character | 2908 | * @ch: character |
diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 620c971422b6..53f2442c6099 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/char/tty_ioctl.c | ||
3 | * | ||
4 | * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds | 2 | * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds |
5 | * | 3 | * |
6 | * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines | 4 | * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines |
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index e19e13647116..5d01d32e2cf0 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c | |||
@@ -956,6 +956,19 @@ void tty_ldisc_init(struct tty_struct *tty) | |||
956 | tty_ldisc_assign(tty, ld); | 956 | tty_ldisc_assign(tty, ld); |
957 | } | 957 | } |
958 | 958 | ||
959 | /** | ||
960 | * tty_ldisc_init - ldisc cleanup for new tty | ||
961 | * @tty: tty that was allocated recently | ||
962 | * | ||
963 | * The tty structure must not becompletely set up (tty_ldisc_setup) when | ||
964 | * this call is made. | ||
965 | */ | ||
966 | void tty_ldisc_deinit(struct tty_struct *tty) | ||
967 | { | ||
968 | put_ldisc(tty->ldisc); | ||
969 | tty_ldisc_assign(tty, NULL); | ||
970 | } | ||
971 | |||
959 | void tty_ldisc_begin(void) | 972 | void tty_ldisc_begin(void) |
960 | { | 973 | { |
961 | /* Setup the default TTY line discipline. */ | 974 | /* Setup the default TTY line discipline. */ |
diff --git a/drivers/tty/tty_mutex.c b/drivers/tty/tty_mutex.c index 133697540c73..3b2bb7719442 100644 --- a/drivers/tty/tty_mutex.c +++ b/drivers/tty/tty_mutex.c | |||
@@ -1,6 +1,3 @@ | |||
1 | /* | ||
2 | * drivers/char/tty_lock.c | ||
3 | */ | ||
4 | #include <linux/tty.h> | 1 | #include <linux/tty.h> |
5 | #include <linux/module.h> | 2 | #include <linux/module.h> |
6 | #include <linux/kallsyms.h> | 3 | #include <linux/kallsyms.h> |
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index d6b342b5b423..3761ccf0f340 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/char/keyboard.c | ||
3 | * | ||
4 | * Written for linux by Johan Myreen as a translation from | 2 | * Written for linux by Johan Myreen as a translation from |
5 | * the assembly version by Linus (with diacriticals added) | 3 | * the assembly version by Linus (with diacriticals added) |
6 | * | 4 | * |
diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c index adf0ad2a8851..67b1d0d7c8ac 100644 --- a/drivers/tty/vt/selection.c +++ b/drivers/tty/vt/selection.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/char/selection.c | ||
3 | * | ||
4 | * This module exports the functions: | 2 | * This module exports the functions: |
5 | * | 3 | * |
6 | * 'int set_selection(struct tiocl_selection __user *, struct tty_struct *)' | 4 | * 'int set_selection(struct tiocl_selection __user *, struct tty_struct *)' |
@@ -334,8 +332,7 @@ int paste_selection(struct tty_struct *tty) | |||
334 | continue; | 332 | continue; |
335 | } | 333 | } |
336 | count = sel_buffer_lth - pasted; | 334 | count = sel_buffer_lth - pasted; |
337 | count = min(count, tty->receive_room); | 335 | count = tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted, |
338 | tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted, | ||
339 | NULL, count); | 336 | NULL, count); |
340 | pasted += count; | 337 | pasted += count; |
341 | } | 338 | } |
diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index 1564261e80c8..66825c9f516a 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/char/vc_screen.c | ||
3 | * | ||
4 | * Provide access to virtual console memory. | 2 | * Provide access to virtual console memory. |
5 | * /dev/vcs0: the screen as it is being viewed right now (possibly scrolled) | 3 | * /dev/vcs0: the screen as it is being viewed right now (possibly scrolled) |
6 | * /dev/vcsN: the screen of /dev/ttyN (1 <= N <= 63) | 4 | * /dev/vcsN: the screen of /dev/ttyN (1 <= N <= 63) |
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 4bea1efaec98..b3915b7ad3e2 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/char/vt.c | ||
3 | * | ||
4 | * Copyright (C) 1991, 1992 Linus Torvalds | 2 | * Copyright (C) 1991, 1992 Linus Torvalds |
5 | */ | 3 | */ |
6 | 4 | ||
@@ -858,7 +856,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, | |||
858 | { | 856 | { |
859 | unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0; | 857 | unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0; |
860 | unsigned long end; | 858 | unsigned long end; |
861 | unsigned int old_cols, old_rows, old_row_size, old_screen_size; | 859 | unsigned int old_rows, old_row_size; |
862 | unsigned int new_cols, new_rows, new_row_size, new_screen_size; | 860 | unsigned int new_cols, new_rows, new_row_size, new_screen_size; |
863 | unsigned int user; | 861 | unsigned int user; |
864 | unsigned short *newscreen; | 862 | unsigned short *newscreen; |
@@ -887,9 +885,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, | |||
887 | return -ENOMEM; | 885 | return -ENOMEM; |
888 | 886 | ||
889 | old_rows = vc->vc_rows; | 887 | old_rows = vc->vc_rows; |
890 | old_cols = vc->vc_cols; | ||
891 | old_row_size = vc->vc_size_row; | 888 | old_row_size = vc->vc_size_row; |
892 | old_screen_size = vc->vc_screenbuf_size; | ||
893 | 889 | ||
894 | err = resize_screen(vc, new_cols, new_rows, user); | 890 | err = resize_screen(vc, new_cols, new_rows, user); |
895 | if (err) { | 891 | if (err) { |
@@ -1197,6 +1193,13 @@ static void csi_J(struct vc_data *vc, int vpar) | |||
1197 | vc->vc_x + 1); | 1193 | vc->vc_x + 1); |
1198 | } | 1194 | } |
1199 | break; | 1195 | break; |
1196 | case 3: /* erase scroll-back buffer (and whole display) */ | ||
1197 | scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char, | ||
1198 | vc->vc_screenbuf_size >> 1); | ||
1199 | set_origin(vc); | ||
1200 | if (CON_IS_VISIBLE(vc)) | ||
1201 | update_screen(vc); | ||
1202 | /* fall through */ | ||
1200 | case 2: /* erase whole display */ | 1203 | case 2: /* erase whole display */ |
1201 | count = vc->vc_cols * vc->vc_rows; | 1204 | count = vc->vc_cols * vc->vc_rows; |
1202 | start = (unsigned short *)vc->vc_origin; | 1205 | start = (unsigned short *)vc->vc_origin; |
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 937d17219984..5e096f43bcea 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/char/vt_ioctl.c | ||
3 | * | ||
4 | * Copyright (C) 1992 obz under the linux copyright | 2 | * Copyright (C) 1992 obz under the linux copyright |
5 | * | 3 | * |
6 | * Dynamic diacritical handling - aeb@cwi.nl - Dec 1993 | 4 | * Dynamic diacritical handling - aeb@cwi.nl - Dec 1993 |
@@ -698,10 +696,23 @@ int vt_ioctl(struct tty_struct *tty, | |||
698 | break; | 696 | break; |
699 | 697 | ||
700 | case KDGKBMODE: | 698 | case KDGKBMODE: |
701 | uival = ((kbd->kbdmode == VC_RAW) ? K_RAW : | 699 | switch (kbd->kbdmode) { |
702 | (kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW : | 700 | case VC_RAW: |
703 | (kbd->kbdmode == VC_UNICODE) ? K_UNICODE : | 701 | uival = K_RAW; |
704 | K_XLATE); | 702 | break; |
703 | case VC_MEDIUMRAW: | ||
704 | uival = K_MEDIUMRAW; | ||
705 | break; | ||
706 | case VC_UNICODE: | ||
707 | uival = K_UNICODE; | ||
708 | break; | ||
709 | case VC_OFF: | ||
710 | uival = K_OFF; | ||
711 | break; | ||
712 | default: | ||
713 | uival = K_XLATE; | ||
714 | break; | ||
715 | } | ||
705 | goto setint; | 716 | goto setint; |
706 | 717 | ||
707 | /* this could be folded into KDSKBMODE, but for compatibility | 718 | /* this could be folded into KDSKBMODE, but for compatibility |
@@ -1499,7 +1510,6 @@ long vt_compat_ioctl(struct tty_struct *tty, | |||
1499 | { | 1510 | { |
1500 | struct vc_data *vc = tty->driver_data; | 1511 | struct vc_data *vc = tty->driver_data; |
1501 | struct console_font_op op; /* used in multiple places here */ | 1512 | struct console_font_op op; /* used in multiple places here */ |
1502 | struct kbd_struct *kbd; | ||
1503 | unsigned int console; | 1513 | unsigned int console; |
1504 | void __user *up = (void __user *)arg; | 1514 | void __user *up = (void __user *)arg; |
1505 | int perm; | 1515 | int perm; |
@@ -1522,7 +1532,6 @@ long vt_compat_ioctl(struct tty_struct *tty, | |||
1522 | if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG)) | 1532 | if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG)) |
1523 | perm = 1; | 1533 | perm = 1; |
1524 | 1534 | ||
1525 | kbd = kbd_table + console; | ||
1526 | switch (cmd) { | 1535 | switch (cmd) { |
1527 | /* | 1536 | /* |
1528 | * these need special handlers for incompatible data structures | 1537 | * these need special handlers for incompatible data structures |