Pull tty/serial driver updates from Greg KH: "Here's the big tty/serial driver update for 3.19-rc1. There are a number of TTY core changes/fixes in here from Peter Hurley that have all been teted in linux-next for a long time now. There are also the normal serial driver updates as well, full details in the changelog below" * tag 'tty-3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (219 commits) serial: pxa: hold port.lock when reporting modem line changes tty-hvsi_lib: Deletion of an unnecessary check before the function call "tty_kref_put" tty: Deletion of unnecessary checks before two function calls n_tty: Fix read_buf race condition, increment read_head after pushing data serial: of-serial: add PM suspend/resume support Revert "serial: of-serial: add PM suspend/resume support" Revert "serial: of-serial: fix up PM ops on no_console_suspend and port type" serial: 8250: don't attempt a trylock if in sysrq serial: core: Add big-endian iotype serial: samsung: use port->fifosize instead of hardcoded values serial: samsung: prefer to use fifosize from driver data serial: samsung: fix style problems serial: samsung: wait for transfer completion before clock disable serial: icom: fix error return code serial: tegra: clean up tty-flag assignments serial: Fix io address assign flow with Fintek PCI-to-UART Product serial: mxs-auart: fix tx_empty against shift register serial: mxs-auart: fix gpio change detection on interrupt serial: mxs-auart: Fix mxs_auart_set_ldisc() serial: 8250_dw: Use 64-bit access for OCTEON. ...
Unified · Split
| @@ -0,0 +1,30 @@ | ||
| 1 | +* BCM63xx UART | |
| 2 | + | |
| 3 | +Required properties: | |
| 4 | + | |
| 5 | +- compatible: "brcm,bcm6345-uart" | |
| 6 | + | |
| 7 | +- reg: The base address of the UART register bank. | |
| 8 | + | |
| 9 | +- interrupts: A single interrupt specifier. | |
| 10 | + | |
| 11 | +- clocks: Clock driving the hardware; used to figure out the baud rate | |
| 12 | + divisor. | |
| 13 | + | |
| 14 | +Example: | |
| 15 | + | |
| 16 | + uart0: serial@14e00520 { | |
| 17 | + compatible = "brcm,bcm6345-uart"; | |
| 18 | + reg = <0x14e00520 0x18>; | |
| 19 | + interrupt-parent = <&periph_intc>; | |
| 20 | + interrupts = <2>; | |
| 21 | + clocks = <&periph_clk>; | |
| 22 | + }; | |
| 23 | + | |
| 24 | + clocks { | |
| 25 | + periph_clk: periph_clk@0 { | |
| 26 | + compatible = "fixed-clock"; | |
| 27 | + #clock-cells = <0>; | |
| 28 | + clock-frequency = <54000000>; | |
| 29 | + }; | |
| 30 | + }; | |
| @@ -11,8 +11,13 @@ Required properties: · 10 unmodified lines | ||
| 11 | 11 | - dma-names: "rx" for RX channel, "tx" for TX channel. |
| 12 | 12 | |
| 13 | 13 | Optional properties: |
| 14 | −- fsl,uart-has-rtscts : Indicate the UART has RTS and CTS lines, | |
| 14 | +- fsl,uart-has-rtscts : Indicate the UART has RTS and CTS lines | |
| 15 | + for hardware flow control, | |
| 15 | 16 | it also means you enable the DMA support for this UART. |
| 17 | +- {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD | |
| 18 | + line respectively. It will use specified PIO instead of the peripheral | |
| 19 | + function pin for the USART feature. | |
| 20 | + If unsure, don't specify this property. | |
| 16 | 21 | |
| 17 | 22 | Example: |
| 18 | 23 | auart0: serial@8006a000 { |
| @@ -21,6 +26,9 @@ auart0: serial@8006a000 { · 2 unmodified lines | ||
| 21 | 26 | interrupts = <112>; |
| 22 | 27 | dmas = <&dma_apbx 8>, <&dma_apbx 9>; |
| 23 | 28 | dma-names = "rx", "tx"; |
| 29 | + cts-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; | |
| 30 | + dsr-gpios = <&gpio1 16 GPIO_ACTIVE_LOW>; | |
| 31 | + dcd-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; | |
| 24 | 32 | }; |
| 25 | 33 | |
| 26 | 34 | Note: Each auart port should have an alias correctly numbered in "aliases" |
| @@ -10,6 +10,7 @@ Required properties: · 9 unmodified lines | ||
| 10 | 10 | - "ns16850" |
| 11 | 11 | - "nvidia,tegra20-uart" |
| 12 | 12 | - "nxp,lpc3220-uart" |
| 13 | + - "ralink,rt2880-uart" | |
| 13 | 14 | - "ibm,qpace-nwp-serial" |
| 14 | 15 | - "altr,16550-FIFO32" |
| 15 | 16 | - "altr,16550-FIFO64" |
| @@ -6,23 +6,35 @@ Required properties: · 5 unmodified lines | ||
| 6 | 6 | - interrupts: exactly one interrupt specifier |
| 7 | 7 | |
| 8 | 8 | Optional properties: |
| 9 | −- pinctrl: When present, must have one state named "default", | |
| 9 | +- pinctrl: | |
| 10 | + When present, must have one state named "default", | |
| 10 | 11 | and may contain a second name named "sleep". The former |
| 11 | 12 | state sets up pins for ordinary operation whereas |
| 12 | 13 | the latter state will put the associated pins to sleep |
| 13 | 14 | when the UART is unused |
| 14 | −- clocks: When present, the first clock listed must correspond to | |
| 15 | +- clocks: | |
| 16 | + When present, the first clock listed must correspond to | |
| 15 | 17 | the clock named UARTCLK on the IP block, i.e. the clock |
| 16 | 18 | to the external serial line, whereas the second clock |
| 17 | 19 | must correspond to the PCLK clocking the internal logic |
| 18 | 20 | of the block. Just listing one clock (the first one) is |
| 19 | 21 | deprecated. |
| 20 | −- clocks-names: When present, the first clock listed must be named | |
| 22 | +- clocks-names: | |
| 23 | + When present, the first clock listed must be named | |
| 21 | 24 | "uartclk" and the second clock listed must be named |
| 22 | 25 | "apb_pclk" |
| 23 | −- dmas: When present, may have one or two dma channels. | |
| 26 | +- dmas: | |
| 27 | + When present, may have one or two dma channels. | |
| 24 | 28 | The first one must be named "rx", the second one |
| 25 | 29 | must be named "tx". |
| 30 | +- auto-poll: | |
| 31 | + Enables polling when using RX DMA. | |
| 32 | +- poll-rate-ms: | |
| 33 | + Rate at which poll occurs when auto-poll is set, | |
| 34 | + default 100ms. | |
| 35 | +- poll-timeout-ms: | |
| 36 | + Poll timeout when auto-poll is set, default | |
| 37 | + 3000ms. | |
| 26 | 38 | |
| 27 | 39 | See also bindings/arm/primecell.txt |
| 28 | 40 | |
| @@ -27,27 +27,52 @@ Optional properties: · 26 unmodified lines | ||
| 27 | 27 | - dmas: Should contain dma specifiers for transmit and receive channels |
| 28 | 28 | - dma-names: Should contain "tx" for transmit and "rx" for receive channels |
| 29 | 29 | |
| 30 | +Note: Aliases may be defined to ensure the correct ordering of the UARTs. | |
| 31 | +The alias serialN will result in the UART being assigned port N. If any | |
| 32 | +serialN alias exists, then an alias must exist for each enabled UART. The | |
| 33 | +serialN aliases should be in a .dts file instead of in a .dtsi file. | |
| 34 | + | |
| 30 | 35 | Examples: |
| 31 | 36 | |
| 32 | −A uartdm v1.4 device with dma capabilities. | |
| 33 | − | |
| 34 | −serial@f991e000 { | |
| 35 | − compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; | |
| 36 | − reg = <0xf991e000 0x1000>; | |
| 37 | − interrupts = <0 108 0x0>; | |
| 38 | − clocks = <&blsp1_uart2_apps_cxc>, <&blsp1_ahb_cxc>; | |
| 39 | − clock-names = "core", "iface"; | |
| 40 | − dmas = <&dma0 0>, <&dma0 1>; | |
| 41 | − dma-names = "tx", "rx"; | |
| 42 | −}; | |
| 43 | − | |
| 44 | −A uartdm v1.3 device without dma capabilities and part of a GSBI complex. | |
| 45 | − | |
| 46 | −serial@19c40000 { | |
| 47 | − compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; | |
| 48 | − reg = <0x19c40000 0x1000>, | |
| 49 | − <0x19c00000 0x1000>; | |
| 50 | − interrupts = <0 195 0x0>; | |
| 51 | − clocks = <&gsbi5_uart_cxc>, <&gsbi5_ahb_cxc>; | |
| 52 | − clock-names = "core", "iface"; | |
| 53 | −}; | |
| 37 | +- A uartdm v1.4 device with dma capabilities. | |
| 38 | + | |
| 39 | + serial@f991e000 { | |
| 40 | + compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; | |
| 41 | + reg = <0xf991e000 0x1000>; | |
| 42 | + interrupts = <0 108 0x0>; | |
| 43 | + clocks = <&blsp1_uart2_apps_cxc>, <&blsp1_ahb_cxc>; | |
| 44 | + clock-names = "core", "iface"; | |
| 45 | + dmas = <&dma0 0>, <&dma0 1>; | |
| 46 | + dma-names = "tx", "rx"; | |
| 47 | + }; | |
| 48 | + | |
| 49 | +- A uartdm v1.3 device without dma capabilities and part of a GSBI complex. | |
| 50 | + | |
| 51 | + serial@19c40000 { | |
| 52 | + compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; | |
| 53 | + reg = <0x19c40000 0x1000>, | |
| 54 | + <0x19c00000 0x1000>; | |
| 55 | + interrupts = <0 195 0x0>; | |
| 56 | + clocks = <&gsbi5_uart_cxc>, <&gsbi5_ahb_cxc>; | |
| 57 | + clock-names = "core", "iface"; | |
| 58 | + }; | |
| 59 | + | |
| 60 | +- serialN alias. | |
| 61 | + | |
| 62 | + aliases { | |
| 63 | + serial0 = &uarta; | |
| 64 | + serial1 = &uartc; | |
| 65 | + serial2 = &uartb; | |
| 66 | + }; | |
| 67 | + | |
| 68 | + uarta: serial@12490000 { | |
| 69 | + status = "ok"; | |
| 70 | + }; | |
| 71 | + | |
| 72 | + uartb: serial@16340000 { | |
| 73 | + status = "ok"; | |
| 74 | + }; | |
| 75 | + | |
| 76 | + uartc: serial@1a240000 { | |
| 77 | + status = "ok"; | |
| 78 | + }; | |
| @@ -4,8 +4,7 @@ Required properties: · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | - compatible: Must contain one of the following: |
| 6 | 6 | |
| 7 | − - "renesas,scifa-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFA compatible UART. | |
| 8 | − - "renesas,scifb-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFB compatible UART. | |
| 7 | + - "renesas,scif-r7s72100" for R7S72100 (RZ/A1H) SCIF compatible UART. | |
| 9 | 8 | - "renesas,scifa-r8a73a4" for R8A73A4 (R-Mobile APE6) SCIFA compatible UART. |
| 10 | 9 | - "renesas,scifb-r8a73a4" for R8A73A4 (R-Mobile APE6) SCIFB compatible UART. |
| 11 | 10 | - "renesas,scifa-r8a7740" for R8A7740 (R-Mobile A1) SCIFA compatible UART. |
| @@ -20,6 +19,12 @@ Required properties: · 8 unmodified lines | ||
| 20 | 19 | - "renesas,scifa-r8a7791" for R8A7791 (R-Car M2) SCIFA compatible UART. |
| 21 | 20 | - "renesas,scifb-r8a7791" for R8A7791 (R-Car M2) SCIFB compatible UART. |
| 22 | 21 | - "renesas,hscif-r8a7791" for R8A7791 (R-Car M2) HSCIF compatible UART. |
| 22 | + - "renesas,scif-r8a7794" for R8A7794 (R-Car E2) SCIF compatible UART. | |
| 23 | + - "renesas,scifa-r8a7794" for R8A7794 (R-Car E2) SCIFA compatible UART. | |
| 24 | + - "renesas,scifb-r8a7794" for R8A7794 (R-Car E2) SCIFB compatible UART. | |
| 25 | + - "renesas,hscif-r8a7794" for R8A7794 (R-Car E2) HSCIF compatible UART. | |
| 26 | + - "renesas,scifa-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFA compatible UART. | |
| 27 | + - "renesas,scifb-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFB compatible UART. | |
| 23 | 28 | - "renesas,scif" for generic SCIF compatible UART. |
| 24 | 29 | - "renesas,scifa" for generic SCIFA compatible UART. |
| 25 | 30 | - "renesas,scifb" for generic SCIFB compatible UART. |
| @@ -1,7 +1,9 @@ | ||
| 1 | 1 | * CSR SiRFprimaII/atlasVI Universal Synchronous Asynchronous Receiver/Transmitter * |
| 2 | 2 | |
| 3 | 3 | Required properties: |
| 4 | −- compatible : Should be "sirf,prima2-uart" or "sirf, prima2-usp-uart" | |
| 4 | +- compatible : Should be "sirf,prima2-uart", "sirf, prima2-usp-uart", | |
| 5 | + "sirf,marco-uart" or "sirf,marco-bt-uart" which means | |
| 6 | + uart located in BT module and used for BT. | |
| 5 | 7 | - reg : Offset and length of the register set for the device |
| 6 | 8 | - interrupts : Should contain uart interrupt |
| 7 | 9 | - fifosize : Should define hardware rx/tx fifo size |
| @@ -31,3 +33,15 @@ usp@b0090000 { · 23 unmodified lines | ||
| 31 | 33 | rts-gpios = <&gpio 15 0>; |
| 32 | 34 | cts-gpios = <&gpio 46 0>; |
| 33 | 35 | }; |
| 36 | + | |
| 37 | +for uart use in BT module, | |
| 38 | +uart6: uart@11000000 { | |
| 39 | + cell-index = <6>; | |
| 40 | + compatible = "sirf,marco-bt-uart", "sirf,marco-uart"; | |
| 41 | + reg = <0x11000000 0x1000>; | |
| 42 | + interrupts = <0 100 0>; | |
| 43 | + clocks = <&clks 138>, <&clks 140>, <&clks 141>; | |
| 44 | + clock-names = "uart", "general", "noc"; | |
| 45 | + fifosize = <128>; | |
| 46 | + status = "disabled"; | |
| 47 | +} | |
| @@ -59,7 +59,9 @@ The core driver uses the info->tmpbuf_sem lock to prevent multi-threaded · 58 unmodified lines | ||
| 59 | 59 | access to the info->tmpbuf bouncebuffer used for port writes. |
| 60 | 60 | |
| 61 | 61 | The port_sem semaphore is used to protect against ports being added/ |
| 62 | −removed or reconfigured at inappropriate times. | |
| 62 | +removed or reconfigured at inappropriate times. Since v2.6.27, this | |
| 63 | +semaphore has been the 'mutex' member of the tty_port struct, and | |
| 64 | +commonly referred to as the port mutex (or port->mutex). | |
| 63 | 65 | |
| 64 | 66 | |
| 65 | 67 | uart_ops |
| @@ -248,7 +250,7 @@ hardware. · 182 unmodified lines | ||
| 248 | 250 | Other flags may be used (eg, xon/xoff characters) if your |
| 249 | 251 | hardware supports hardware "soft" flow control. |
| 250 | 252 | |
| 251 | − Locking: none. | |
| 253 | + Locking: caller holds port->mutex | |
| 252 | 254 | Interrupts: caller dependent. |
| 253 | 255 | This call must not sleep |
| 254 | 256 | |
| @@ -8026,6 +8026,12 @@ S: Maintained · 8025 unmodified lines | ||
| 8026 | 8026 | F: Documentation/serial/rocket.txt |
| 8027 | 8027 | F: drivers/tty/rocket* |
| 8028 | 8028 | |
| 8029 | +ROCKETPORT EXPRESS/INFINITY DRIVER | |
| 8030 | +M: Kevin Cernekee <cernekee@gmail.com> | |
| 8031 | +L: linux-serial@vger.kernel.org | |
| 8032 | +S: Odd Fixes | |
| 8033 | +F: drivers/tty/serial/rp2.* | |
| 8034 | + | |
| 8029 | 8035 | ROSE NETWORK LAYER |
| 8030 | 8036 | M: Ralf Baechle <ralf@linux-mips.org> |
| 8031 | 8037 | L: linux-hams@vger.kernel.org |
| @@ -9,8 +9,11 @@ · 8 unmodified lines | ||
| 9 | 9 | #ifndef __BFIN_ASM_SERIAL_H__ |
| 10 | 10 | #define __BFIN_ASM_SERIAL_H__ |
| 11 | 11 | |
| 12 | +#include <linux/circ_buf.h> | |
| 12 | 13 | #include <linux/serial_core.h> |
| 13 | 14 | #include <linux/spinlock.h> |
| 15 | +#include <linux/timer.h> | |
| 16 | +#include <linux/workqueue.h> | |
| 14 | 17 | #include <mach/anomaly.h> |
| 15 | 18 | #include <mach/bfin_serial.h> |
| 16 | 19 | |
| @@ -25,10 +28,6 @@ · 8 unmodified lines | ||
| 25 | 28 | # endif |
| 26 | 29 | #endif |
| 27 | 30 | |
| 28 | −struct circ_buf; | |
| 29 | −struct timer_list; | |
| 30 | −struct work_struct; | |
| 31 | − | |
| 32 | 31 | struct bfin_serial_port { |
| 33 | 32 | struct uart_port port; |
| 34 | 33 | unsigned int old_status; |
| @@ -632,6 +632,7 @@ static irqreturn_t winch_interrupt(int irq, void *data) · 631 unmodified lines | ||
| 632 | 632 | int fd = winch->fd; |
| 633 | 633 | int err; |
| 634 | 634 | char c; |
| 635 | + struct pid *pgrp; | |
| 635 | 636 | |
| 636 | 637 | if (fd != -1) { |
| 637 | 638 | err = generic_read(fd, &c, NULL); |
| @@ -657,7 +658,10 @@ static irqreturn_t winch_interrupt(int irq, void *data) · 19 unmodified lines | ||
| 657 | 658 | if (line != NULL) { |
| 658 | 659 | chan_window_size(line, &tty->winsize.ws_row, |
| 659 | 660 | &tty->winsize.ws_col); |
| 660 | − kill_pgrp(tty->pgrp, SIGWINCH, 1); | |
| 661 | + pgrp = tty_get_pgrp(tty); | |
| 662 | + if (pgrp) | |
| 663 | + kill_pgrp(pgrp, SIGWINCH, 1); | |
| 664 | + put_pid(pgrp); | |
| 661 | 665 | } |
| 662 | 666 | tty_kref_put(tty); |
| 663 | 667 | } |
| @@ -64,6 +64,7 @@ enum parport_pc_pci_cards { · 63 unmodified lines | ||
| 64 | 64 | timedia_9079c, |
| 65 | 65 | wch_ch353_1s1p, |
| 66 | 66 | wch_ch353_2s1p, |
| 67 | + wch_ch382_2s1p, | |
| 67 | 68 | sunix_2s1p, |
| 68 | 69 | }; |
| 69 | 70 | |
| @@ -151,6 +152,7 @@ static struct parport_pc_pci cards[] = { · 81 unmodified lines | ||
| 151 | 152 | /* timedia_9079c */ { 1, { { 2, 3 }, } }, |
| 152 | 153 | /* wch_ch353_1s1p*/ { 1, { { 1, -1}, } }, |
| 153 | 154 | /* wch_ch353_2s1p*/ { 1, { { 2, -1}, } }, |
| 155 | + /* wch_ch382_2s1p*/ { 1, { { 2, -1}, } }, | |
| 154 | 156 | /* sunix_2s1p */ { 1, { { 3, -1 }, } }, |
| 155 | 157 | }; |
| 156 | 158 | |
| @@ -257,6 +259,7 @@ static struct pci_device_id parport_serial_pci_tbl[] = { · 100 unmodified lines | ||
| 257 | 259 | /* WCH CARDS */ |
| 258 | 260 | { 0x4348, 0x5053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, wch_ch353_1s1p}, |
| 259 | 261 | { 0x4348, 0x7053, 0x4348, 0x3253, 0, 0, wch_ch353_2s1p}, |
| 262 | + { 0x1c00, 0x3250, 0x1c00, 0x3250, 0, 0, wch_ch382_2s1p}, | |
| 260 | 263 | |
| 261 | 264 | /* |
| 262 | 265 | * More SUNIX variations. At least one of these has part number |
| @@ -494,6 +497,13 @@ static struct pciserial_board pci_parport_serial_boards[] = { · 231 unmodified lines | ||
| 494 | 497 | .base_baud = 115200, |
| 495 | 498 | .uart_offset = 8, |
| 496 | 499 | }, |
| 500 | + [wch_ch382_2s1p] = { | |
| 501 | + .flags = FL_BASE0, | |
| 502 | + .num_ports = 2, | |
| 503 | + .base_baud = 115200, | |
| 504 | + .uart_offset = 8, | |
| 505 | + .first_offset = 0xC0, | |
| 506 | + }, | |
| 497 | 507 | [sunix_2s1p] = { |
| 498 | 508 | .flags = FL_BASE0|FL_BASE_BARS, |
| 499 | 509 | .num_ports = 2, |
| @@ -309,8 +309,8 @@ static int __init ehv_bc_console_init(void) · 308 unmodified lines | ||
| 309 | 309 | * handle for udbg. |
| 310 | 310 | */ |
| 311 | 311 | if (stdout_bc != CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE) |
| 312 | − pr_warning("ehv-bc: udbg handle %u is not the stdout handle\n", | |
| 313 | − CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE); | |
| 312 | + pr_warn("ehv-bc: udbg handle %u is not the stdout handle\n", | |
| 313 | + CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE); | |
| 314 | 314 | #endif |
| 315 | 315 | |
| 316 | 316 | /* add_preferred_console() must be called before register_console(), |
| @@ -155,9 +155,9 @@ static struct tty_driver *goldfish_tty_console_device(struct console *c, · 154 unmodified lines | ||
| 155 | 155 | |
| 156 | 156 | static int goldfish_tty_console_setup(struct console *co, char *options) |
| 157 | 157 | { |
| 158 | − if ((unsigned)co->index > goldfish_tty_line_count) | |
| 158 | + if ((unsigned)co->index >= goldfish_tty_line_count) | |
| 159 | 159 | return -ENODEV; |
| 160 | − if (goldfish_ttys[co->index].base == 0) | |
| 160 | + if (!goldfish_ttys[co->index].base) | |
| 161 | 161 | return -ENODEV; |
| 162 | 162 | return 0; |
| 163 | 163 | } |
| @@ -317,7 +317,7 @@ static int goldfish_tty_remove(struct platform_device *pdev) · 153 unmodified lines | ||
| 317 | 317 | unregister_console(&qtty->console); |
| 318 | 318 | tty_unregister_device(goldfish_tty_driver, pdev->id); |
| 319 | 319 | iounmap(qtty->base); |
| 320 | − qtty->base = 0; | |
| 320 | + qtty->base = NULL; | |
| 321 | 321 | free_irq(qtty->irq, pdev); |
| 322 | 322 | goldfish_tty_current_line_count--; |
| 323 | 323 | if (goldfish_tty_current_line_count == 0) |
| @@ -1575,7 +1575,7 @@ static int __init hvcs_module_init(void) · 1574 unmodified lines | ||
| 1575 | 1575 | */ |
| 1576 | 1576 | rc = driver_create_file(&(hvcs_vio_driver.driver), &driver_attr_rescan); |
| 1577 | 1577 | if (rc) |
| 1578 | − pr_warning(KERN_ERR "HVCS: Failed to create rescan file (err %d)\n", rc); | |
| 1578 | + pr_warning("HVCS: Failed to create rescan file (err %d)\n", rc); | |
| 1579 | 1579 | |
| 1580 | 1580 | return 0; |
| 1581 | 1581 | } |
| @@ -405,8 +405,7 @@ void hvsilib_close(struct hvsi_priv *pv, struct hvc_struct *hp) · 404 unmodified lines | ||
| 405 | 405 | hvsi_send_close(pv); |
| 406 | 406 | } |
| 407 | 407 | |
| 408 | − if (pv->tty) | |
| 409 | − tty_kref_put(pv->tty); | |
| 408 | + tty_kref_put(pv->tty); | |
| 410 | 409 | pv->tty = NULL; |
| 411 | 410 | } |
| 412 | 411 | |
| @@ -378,9 +378,9 @@ static void swap_packet_bitfield_to_le(unsigned char *data) · 377 unmodified lines | ||
| 378 | 378 | /* |
| 379 | 379 | * transform bits from aa.bbb.ccc to ccc.bbb.aa |
| 380 | 380 | */ |
| 381 | − ret |= tmp & 0xc0 >> 6; | |
| 382 | − ret |= tmp & 0x38 >> 1; | |
| 383 | − ret |= tmp & 0x07 << 5; | |
| 381 | + ret |= (tmp & 0xc0) >> 6; | |
| 382 | + ret |= (tmp & 0x38) >> 1; | |
| 383 | + ret |= (tmp & 0x07) << 5; | |
| 384 | 384 | *data = ret & 0xff; |
| 385 | 385 | #endif |
| 386 | 386 | } |
| @@ -393,9 +393,9 @@ static void swap_packet_bitfield_from_le(unsigned char *data) · 6 unmodified lines | ||
| 393 | 393 | /* |
| 394 | 394 | * transform bits from ccc.bbb.aa to aa.bbb.ccc |
| 395 | 395 | */ |
| 396 | − ret |= tmp & 0xe0 >> 5; | |
| 397 | − ret |= tmp & 0x1c << 1; | |
| 398 | − ret |= tmp & 0x03 << 6; | |
| 396 | + ret |= (tmp & 0xe0) >> 5; | |
| 397 | + ret |= (tmp & 0x1c) << 1; | |
| 398 | + ret |= (tmp & 0x03) << 6; | |
| 399 | 399 | *data = ret & 0xff; |
| 400 | 400 | #endif |
| 401 | 401 | } |
| @@ -249,7 +249,7 @@ static int lock_card(struct isi_board *card) · 248 unmodified lines | ||
| 249 | 249 | spin_unlock_irqrestore(&card->card_lock, card->flags); |
| 250 | 250 | msleep(10); |
| 251 | 251 | } |
| 252 | − pr_warning("Failed to lock Card (0x%lx)\n", card->base); | |
| 252 | + pr_warn("Failed to lock Card (0x%lx)\n", card->base); | |
| 253 | 253 | |
| 254 | 254 | return 0; /* Failed to acquire the card! */ |
| 255 | 255 | } |
| @@ -378,13 +378,13 @@ static inline int __isicom_paranoia_check(struct isi_port const *port, · 122 unmodified lines | ||
| 378 | 378 | char *name, const char *routine) |
| 379 | 379 | { |
| 380 | 380 | if (!port) { |
| 381 | − pr_warning("Warning: bad isicom magic for dev %s in %s.\n", | |
| 382 | − name, routine); | |
| 381 | + pr_warn("Warning: bad isicom magic for dev %s in %s\n", | |
| 382 | + name, routine); | |
| 383 | 383 | return 1; |
| 384 | 384 | } |
| 385 | 385 | if (port->magic != ISICOM_MAGIC) { |
| 386 | − pr_warning("Warning: NULL isicom port for dev %s in %s.\n", | |
| 387 | − name, routine); | |
| 386 | + pr_warn("Warning: NULL isicom port for dev %s in %s\n", | |
| 387 | + name, routine); | |
| 388 | 388 | return 1; |
| 389 | 389 | } |
| 390 | 390 | |
| @@ -546,8 +546,8 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) · 155 unmodified lines | ||
| 546 | 546 | byte_count = header & 0xff; |
| 547 | 547 | |
| 548 | 548 | if (channel + 1 > card->port_count) { |
| 549 | − pr_warning("%s(0x%lx): %d(channel) > port_count.\n", | |
| 550 | − __func__, base, channel+1); | |
| 549 | + pr_warn("%s(0x%lx): %d(channel) > port_count\n", | |
| 550 | + __func__, base, channel + 1); | |
| 551 | 551 | outw(0x0000, base+0x04); /* enable interrupts */ |
| 552 | 552 | spin_unlock(&card->card_lock); |
| 553 | 553 | return IRQ_HANDLED; |
| @@ -321,7 +321,8 @@ static void n_tty_check_unthrottle(struct tty_struct *tty) · 320 unmodified lines | ||
| 321 | 321 | |
| 322 | 322 | static inline void put_tty_queue(unsigned char c, struct n_tty_data *ldata) |
| 323 | 323 | { |
| 324 | − *read_buf_addr(ldata, ldata->read_head++) = c; | |
| 324 | + *read_buf_addr(ldata, ldata->read_head) = c; | |
| 325 | + ldata->read_head++; | |
| 325 | 326 | } |
| 326 | 327 | |
| 327 | 328 | /** |
| @@ -351,13 +352,13 @@ static void n_tty_packet_mode_flush(struct tty_struct *tty) · 23 unmodified lines | ||
| 351 | 352 | { |
| 352 | 353 | unsigned long flags; |
| 353 | 354 | |
| 354 | − spin_lock_irqsave(&tty->ctrl_lock, flags); | |
| 355 | 355 | if (tty->link->packet) { |
| 356 | + spin_lock_irqsave(&tty->ctrl_lock, flags); | |
| 356 | 357 | tty->ctrl_status |= TIOCPKT_FLUSHREAD; |
| 358 | + spin_unlock_irqrestore(&tty->ctrl_lock, flags); | |
| 357 | 359 | if (waitqueue_active(&tty->link->read_wait)) |
| 358 | 360 | wake_up_interruptible(&tty->link->read_wait); |
| 359 | 361 | } |
| 360 | − spin_unlock_irqrestore(&tty->ctrl_lock, flags); | |
| 361 | 362 | } |
| 362 | 363 | |
| 363 | 364 | /** |
| @@ -2128,7 +2129,6 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, · 1764 unmodified lines | ||
| 2128 | 2129 | int minimum, time; |
| 2129 | 2130 | ssize_t retval = 0; |
| 2130 | 2131 | long timeout; |
| 2131 | − unsigned long flags; | |
| 2132 | 2132 | int packet; |
| 2133 | 2133 | |
| 2134 | 2134 | c = job_control(tty, file); |
| @@ -2174,10 +2174,10 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, · 39 unmodified lines | ||
| 2174 | 2174 | unsigned char cs; |
| 2175 | 2175 | if (b != buf) |
| 2176 | 2176 | break; |
| 2177 | − spin_lock_irqsave(&tty->link->ctrl_lock, flags); | |
| 2177 | + spin_lock_irq(&tty->link->ctrl_lock); | |
| 2178 | 2178 | cs = tty->link->ctrl_status; |
| 2179 | 2179 | tty->link->ctrl_status = 0; |
| 2180 | − spin_unlock_irqrestore(&tty->link->ctrl_lock, flags); | |
| 2180 | + spin_unlock_irq(&tty->link->ctrl_lock); | |
| 2181 | 2181 | if (tty_put_user(tty, cs, b++)) { |
| 2182 | 2182 | retval = -EFAULT; |
| 2183 | 2183 | b--; |
| @@ -2193,45 +2193,29 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, · 9 unmodified lines | ||
| 2193 | 2193 | |
| 2194 | 2194 | if (!input_available_p(tty, 0)) { |
| 2195 | 2195 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { |
| 2196 | − up_read(&tty->termios_rwsem); | |
| 2197 | − tty_flush_to_ldisc(tty); | |
| 2198 | − down_read(&tty->termios_rwsem); | |
| 2199 | − if (!input_available_p(tty, 0)) { | |
| 2200 | − retval = -EIO; | |
| 2201 | − break; | |
| 2202 | − } | |
| 2203 | − } else { | |
| 2204 | − if (tty_hung_up_p(file)) | |
| 2205 | − break; | |
| 2206 | − if (!timeout) | |
| 2207 | − break; | |
| 2208 | − if (file->f_flags & O_NONBLOCK) { | |
| 2209 | − retval = -EAGAIN; | |
| 2210 | − break; | |
| 2211 | − } | |
| 2212 | − if (signal_pending(current)) { | |
| 2213 | − retval = -ERESTARTSYS; | |
| 2214 | − break; | |
| 2215 | − } | |
| 2216 | − n_tty_set_room(tty); | |
| 2217 | − up_read(&tty->termios_rwsem); | |
| 2218 | − | |
| 2219 | − timeout = wait_woken(&wait, TASK_INTERRUPTIBLE, | |
| 2220 | − timeout); | |
| 2221 | − | |
| 2222 | − down_read(&tty->termios_rwsem); | |
| 2223 | − continue; | |
| 2196 | + retval = -EIO; | |
| 2197 | + break; | |
| 2224 | 2198 | } |
| 2225 | − } | |
| 2226 | − | |
| 2227 | − /* Deal with packet mode. */ | |
| 2228 | − if (packet && b == buf) { | |
| 2229 | − if (tty_put_user(tty, TIOCPKT_DATA, b++)) { | |
| 2230 | − retval = -EFAULT; | |
| 2231 | − b--; | |
| 2199 | + if (tty_hung_up_p(file)) | |
| 2200 | + break; | |
| 2201 | + if (!timeout) | |
| 2202 | + break; | |
| 2203 | + if (file->f_flags & O_NONBLOCK) { | |
| 2204 | + retval = -EAGAIN; | |
| 2232 | 2205 | break; |
| 2233 | 2206 | } |
| 2234 | − nr--; | |
| 2207 | + if (signal_pending(current)) { | |
| 2208 | + retval = -ERESTARTSYS; | |
| 2209 | + break; | |
| 2210 | + } | |
| 2211 | + n_tty_set_room(tty); | |
| 2212 | + up_read(&tty->termios_rwsem); | |
| 2213 | + | |
| 2214 | + timeout = wait_woken(&wait, TASK_INTERRUPTIBLE, | |
| 2215 | + timeout); | |
| 2216 | + | |
| 2217 | + down_read(&tty->termios_rwsem); | |
| 2218 | + continue; | |
| 2235 | 2219 | } |
| 2236 | 2220 | |
| 2237 | 2221 | if (ldata->icanon && !L_EXTPROC(tty)) { |
| @@ -2243,8 +2227,17 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, · 5 unmodified lines | ||
| 2243 | 2227 | break; |
| 2244 | 2228 | } else { |
| 2245 | 2229 | int uncopied; |
| 2246 | − /* The copy function takes the read lock and handles | |
| 2247 | − locking internally for this case */ | |
| 2230 | + | |
| 2231 | + /* Deal with packet mode. */ | |
| 2232 | + if (packet && b == buf) { | |
| 2233 | + if (tty_put_user(tty, TIOCPKT_DATA, b++)) { | |
| 2234 | + retval = -EFAULT; | |
| 2235 | + b--; | |
| 2236 | + break; | |
| 2237 | + } | |
| 2238 | + nr--; | |
| 2239 | + } | |
| 2240 | + | |
| 2248 | 2241 | uncopied = copy_from_read_buf(tty, &b, &nr); |
| 2249 | 2242 | uncopied += copy_from_read_buf(tty, &b, &nr); |
| 2250 | 2243 | if (uncopied) { |
| @@ -47,10 +47,13 @@ static void pty_close(struct tty_struct *tty, struct file *filp) · 46 unmodified lines | ||
| 47 | 47 | set_bit(TTY_IO_ERROR, &tty->flags); |
| 48 | 48 | wake_up_interruptible(&tty->read_wait); |
| 49 | 49 | wake_up_interruptible(&tty->write_wait); |
| 50 | + spin_lock_irq(&tty->ctrl_lock); | |
| 50 | 51 | tty->packet = 0; |
| 52 | + spin_unlock_irq(&tty->ctrl_lock); | |
| 51 | 53 | /* Review - krefs on tty_link ?? */ |
| 52 | 54 | if (!tty->link) |
| 53 | 55 | return; |
| 56 | + tty_flush_to_ldisc(tty->link); | |
| 54 | 57 | set_bit(TTY_OTHER_CLOSED, &tty->link->flags); |
| 55 | 58 | wake_up_interruptible(&tty->link->read_wait); |
| 56 | 59 | wake_up_interruptible(&tty->link->write_wait); |
| @@ -64,9 +67,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp) · 7 unmodified lines | ||
| 64 | 67 | mutex_unlock(&devpts_mutex); |
| 65 | 68 | } |
| 66 | 69 | #endif |
| 67 | − tty_unlock(tty); | |
| 68 | 70 | tty_vhangup(tty->link); |
| 69 | − tty_lock(tty); | |
| 70 | 71 | } |
| 71 | 72 | } |
| 72 | 73 | |
| @@ -178,21 +179,21 @@ static int pty_get_lock(struct tty_struct *tty, int __user *arg) · 105 unmodified lines | ||
| 178 | 179 | /* Set the packet mode on a pty */ |
| 179 | 180 | static int pty_set_pktmode(struct tty_struct *tty, int __user *arg) |
| 180 | 181 | { |
| 181 | − unsigned long flags; | |
| 182 | 182 | int pktmode; |
| 183 | 183 | |
| 184 | 184 | if (get_user(pktmode, arg)) |
| 185 | 185 | return -EFAULT; |
| 186 | 186 | |
| 187 | − spin_lock_irqsave(&tty->ctrl_lock, flags); | |
| 187 | + spin_lock_irq(&tty->ctrl_lock); | |
| 188 | 188 | if (pktmode) { |
| 189 | 189 | if (!tty->packet) { |
| 190 | − tty->packet = 1; | |
| 191 | 190 | tty->link->ctrl_status = 0; |
| 191 | + smp_mb(); | |
| 192 | + tty->packet = 1; | |
| 192 | 193 | } |
| 193 | 194 | } else |
| 194 | 195 | tty->packet = 0; |
| 195 | − spin_unlock_irqrestore(&tty->ctrl_lock, flags); | |
| 196 | + spin_unlock_irq(&tty->ctrl_lock); | |
| 196 | 197 | |
| 197 | 198 | return 0; |
| 198 | 199 | } |
| @@ -207,15 +208,12 @@ static int pty_get_pktmode(struct tty_struct *tty, int __user *arg) · 8 unmodified lines | ||
| 207 | 208 | /* Send a signal to the slave */ |
| 208 | 209 | static int pty_signal(struct tty_struct *tty, int sig) |
| 209 | 210 | { |
| 210 | − unsigned long flags; | |
| 211 | 211 | struct pid *pgrp; |
| 212 | 212 | |
| 213 | 213 | if (tty->link) { |
| 214 | − spin_lock_irqsave(&tty->link->ctrl_lock, flags); | |
| 215 | − pgrp = get_pid(tty->link->pgrp); | |
| 216 | − spin_unlock_irqrestore(&tty->link->ctrl_lock, flags); | |
| 217 | − | |
| 218 | − kill_pgrp(pgrp, sig, 1); | |
| 214 | + pgrp = tty_get_pgrp(tty->link); | |
| 215 | + if (pgrp) | |
| 216 | + kill_pgrp(pgrp, sig, 1); | |
| 219 | 217 | put_pid(pgrp); |
| 220 | 218 | } |
| 221 | 219 | return 0; |
| @@ -224,16 +222,15 @@ static int pty_signal(struct tty_struct *tty, int sig) · 2 unmodified lines | ||
| 224 | 222 | static void pty_flush_buffer(struct tty_struct *tty) |
| 225 | 223 | { |
| 226 | 224 | struct tty_struct *to = tty->link; |
| 227 | − unsigned long flags; | |
| 228 | 225 | |
| 229 | 226 | if (!to) |
| 230 | 227 | return; |
| 231 | 228 | /* tty_buffer_flush(to); FIXME */ |
| 232 | 229 | if (to->packet) { |
| 233 | − spin_lock_irqsave(&tty->ctrl_lock, flags); | |
| 230 | + spin_lock_irq(&tty->ctrl_lock); | |
| 234 | 231 | tty->ctrl_status |= TIOCPKT_FLUSHWRITE; |
| 235 | 232 | wake_up_interruptible(&to->read_wait); |
| 236 | − spin_unlock_irqrestore(&tty->ctrl_lock, flags); | |
| 233 | + spin_unlock_irq(&tty->ctrl_lock); | |
| 237 | 234 | } |
| 238 | 235 | } |
| 239 | 236 | |
| @@ -262,6 +259,32 @@ out: · 22 unmodified lines | ||
| 262 | 259 | static void pty_set_termios(struct tty_struct *tty, |
| 263 | 260 | struct ktermios *old_termios) |
| 264 | 261 | { |
| 262 | + /* See if packet mode change of state. */ | |
| 263 | + if (tty->link && tty->link->packet) { | |
| 264 | + int extproc = (old_termios->c_lflag & EXTPROC) | | |
| 265 | + (tty->termios.c_lflag & EXTPROC); | |
| 266 | + int old_flow = ((old_termios->c_iflag & IXON) && | |
| 267 | + (old_termios->c_cc[VSTOP] == '\023') && | |
| 268 | + (old_termios->c_cc[VSTART] == '\021')); | |
| 269 | + int new_flow = (I_IXON(tty) && | |
| 270 | + STOP_CHAR(tty) == '\023' && | |
| 271 | + START_CHAR(tty) == '\021'); | |
| 272 | + if ((old_flow != new_flow) || extproc) { | |
| 273 | + spin_lock_irq(&tty->ctrl_lock); | |
| 274 | + if (old_flow != new_flow) { | |
| 275 | + tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP); | |
| 276 | + if (new_flow) | |
| 277 | + tty->ctrl_status |= TIOCPKT_DOSTOP; | |
| 278 | + else | |
| 279 | + tty->ctrl_status |= TIOCPKT_NOSTOP; | |
| 280 | + } | |
| 281 | + if (extproc) | |
| 282 | + tty->ctrl_status |= TIOCPKT_IOCTL; | |
| 283 | + spin_unlock_irq(&tty->ctrl_lock); | |
| 284 | + wake_up_interruptible(&tty->link->read_wait); | |
| 285 | + } | |
| 286 | + } | |
| 287 | + | |
| 265 | 288 | tty->termios.c_cflag &= ~(CSIZE | PARENB); |
| 266 | 289 | tty->termios.c_cflag |= (CS8 | CREAD); |
| 267 | 290 | } |
| @@ -278,7 +301,6 @@ static void pty_set_termios(struct tty_struct *tty, · 10 unmodified lines | ||
| 278 | 301 | static int pty_resize(struct tty_struct *tty, struct winsize *ws) |
| 279 | 302 | { |
| 280 | 303 | struct pid *pgrp, *rpgrp; |
| 281 | − unsigned long flags; | |
| 282 | 304 | struct tty_struct *pty = tty->link; |
| 283 | 305 | |
| 284 | 306 | /* For a PTY we need to lock the tty side */ |
| @@ -286,17 +308,9 @@ static int pty_resize(struct tty_struct *tty, struct winsize *ws) · 1 unmodified line | ||
| 286 | 308 | if (!memcmp(ws, &tty->winsize, sizeof(*ws))) |
| 287 | 309 | goto done; |
| 288 | 310 | |
| 289 | − /* Get the PID values and reference them so we can | |
| 290 | − avoid holding the tty ctrl lock while sending signals. | |
| 291 | − We need to lock these individually however. */ | |
| 292 | − | |
| 293 | − spin_lock_irqsave(&tty->ctrl_lock, flags); | |
| 294 | − pgrp = get_pid(tty->pgrp); | |
| 295 | − spin_unlock_irqrestore(&tty->ctrl_lock, flags); | |
| 296 | − | |
| 297 | − spin_lock_irqsave(&pty->ctrl_lock, flags); | |
| 298 | − rpgrp = get_pid(pty->pgrp); | |
| 299 | − spin_unlock_irqrestore(&pty->ctrl_lock, flags); | |
| 311 | + /* Signal the foreground process group of both ptys */ | |
| 312 | + pgrp = tty_get_pgrp(tty); | |
| 313 | + rpgrp = tty_get_pgrp(pty); | |
| 300 | 314 | |
| 301 | 315 | if (pgrp) |
| 302 | 316 | kill_pgrp(pgrp, SIGWINCH, 1); |
| @@ -327,26 +341,26 @@ static void pty_start(struct tty_struct *tty) · 24 unmodified lines | ||
| 327 | 341 | { |
| 328 | 342 | unsigned long flags; |
| 329 | 343 | |
| 330 | − spin_lock_irqsave(&tty->ctrl_lock, flags); | |
| 331 | 344 | if (tty->link && tty->link->packet) { |
| 345 | + spin_lock_irqsave(&tty->ctrl_lock, flags); | |
| 332 | 346 | tty->ctrl_status &= ~TIOCPKT_STOP; |
| 333 | 347 | tty->ctrl_status |= TIOCPKT_START; |
| 348 | + spin_unlock_irqrestore(&tty->ctrl_lock, flags); | |
| 334 | 349 | wake_up_interruptible_poll(&tty->link->read_wait, POLLIN); |
| 335 | 350 | } |
| 336 | − spin_unlock_irqrestore(&tty->ctrl_lock, flags); | |
| 337 | 351 | } |
| 338 | 352 | |
| 339 | 353 | static void pty_stop(struct tty_struct *tty) |
| 340 | 354 | { |
| 341 | 355 | unsigned long flags; |
| 342 | 356 | |
| 343 | − spin_lock_irqsave(&tty->ctrl_lock, flags); | |
| 344 | 357 | if (tty->link && tty->link->packet) { |
| 358 | + spin_lock_irqsave(&tty->ctrl_lock, flags); | |
| 345 | 359 | tty->ctrl_status &= ~TIOCPKT_START; |
| 346 | 360 | tty->ctrl_status |= TIOCPKT_STOP; |
| 361 | + spin_unlock_irqrestore(&tty->ctrl_lock, flags); | |
| 347 | 362 | wake_up_interruptible_poll(&tty->link->read_wait, POLLIN); |
| 348 | 363 | } |
| 349 | − spin_unlock_irqrestore(&tty->ctrl_lock, flags); | |
| 350 | 364 | } |
| 351 | 365 | |
| 352 | 366 | /** |
| @@ -368,6 +382,10 @@ static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty, · 15 unmodified lines | ||
| 368 | 382 | int idx = tty->index; |
| 369 | 383 | int retval = -ENOMEM; |
| 370 | 384 | |
| 385 | + /* Opening the slave first has always returned -EIO */ | |
| 386 | + if (driver->subtype != PTY_TYPE_MASTER) | |
| 387 | + return -EIO; | |
| 388 | + | |
| 371 | 389 | ports[0] = kmalloc(sizeof **ports, GFP_KERNEL); |
| 372 | 390 | ports[1] = kmalloc(sizeof **ports, GFP_KERNEL); |
| 373 | 391 | if (!ports[0] || !ports[1]) |
| @@ -380,6 +398,8 @@ static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty, · 6 unmodified lines | ||
| 380 | 398 | if (!o_tty) |
| 381 | 399 | goto err_put_module; |
| 382 | 400 | |
| 401 | + tty_set_lock_subclass(o_tty); | |
| 402 | + | |
| 383 | 403 | if (legacy) { |
| 384 | 404 | /* We always use new tty termios data so we can do this |
| 385 | 405 | the easy way .. */ |
| @@ -404,8 +424,6 @@ static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty, · 18 unmodified lines | ||
| 404 | 424 | * Everything allocated ... set up the o_tty structure. |
| 405 | 425 | */ |
| 406 | 426 | tty_driver_kref_get(driver->other); |
| 407 | − if (driver->subtype == PTY_TYPE_MASTER) | |
| 408 | − o_tty->count++; | |
| 409 | 427 | /* Establish the links in both directions */ |
| 410 | 428 | tty->link = o_tty; |
| 411 | 429 | o_tty->link = tty; |
| @@ -417,6 +435,7 @@ static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty, · 5 unmodified lines | ||
| 417 | 435 | |
| 418 | 436 | tty_driver_kref_get(driver); |
| 419 | 437 | tty->count++; |
| 438 | + o_tty->count++; | |
| 420 | 439 | return 0; |
| 421 | 440 | err_free_termios: |
| 422 | 441 | if (legacy) |
| @@ -489,7 +508,6 @@ static const struct tty_operations master_pty_ops_bsd = { · 66 unmodified lines | ||
| 489 | 508 | .flush_buffer = pty_flush_buffer, |
| 490 | 509 | .chars_in_buffer = pty_chars_in_buffer, |
| 491 | 510 | .unthrottle = pty_unthrottle, |
| 492 | − .set_termios = pty_set_termios, | |
| 493 | 511 | .ioctl = pty_bsd_ioctl, |
| 494 | 512 | .cleanup = pty_cleanup, |
| 495 | 513 | .resize = pty_resize, |
| @@ -666,7 +684,6 @@ static const struct tty_operations ptm_unix98_ops = { · 170 unmodified lines | ||
| 666 | 684 | .flush_buffer = pty_flush_buffer, |
| 667 | 685 | .chars_in_buffer = pty_chars_in_buffer, |
| 668 | 686 | .unthrottle = pty_unthrottle, |
| 669 | − .set_termios = pty_set_termios, | |
| 670 | 687 | .ioctl = pty_unix98_ioctl, |
| 671 | 688 | .resize = pty_resize, |
| 672 | 689 | .shutdown = pty_unix98_shutdown, |
| @@ -16,6 +16,9 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <linux/dmaengine.h> |
| 17 | 17 | |
| 18 | 18 | struct uart_8250_dma { |
| 19 | + int (*tx_dma)(struct uart_8250_port *p); | |
| 20 | + int (*rx_dma)(struct uart_8250_port *p, unsigned int iir); | |
| 21 | + | |
| 19 | 22 | /* Filter function */ |
| 20 | 23 | dma_filter_fn fn; |
| 21 | 24 | |
| @@ -41,6 +44,8 @@ struct uart_8250_dma { · 19 unmodified lines | ||
| 41 | 44 | size_t tx_size; |
| 42 | 45 | |
| 43 | 46 | unsigned char tx_running:1; |
| 47 | + unsigned char tx_err: 1; | |
| 48 | + unsigned char rx_running:1; | |
| 44 | 49 | }; |
| 45 | 50 | |
| 46 | 51 | struct old_serial_port { |
| @@ -51,7 +56,7 @@ struct old_serial_port { · 4 unmodified lines | ||
| 51 | 56 | unsigned int flags; |
| 52 | 57 | unsigned char hub6; |
| 53 | 58 | unsigned char io_type; |
| 54 | − unsigned char *iomem_base; | |
| 59 | + unsigned char __iomem *iomem_base; | |
| 55 | 60 | unsigned short iomem_reg_shift; |
| 56 | 61 | unsigned long irqflags; |
| 57 | 62 | }; |
| @@ -114,6 +119,8 @@ static inline void serial_dl_write(struct uart_8250_port *up, int value) · 56 unmodified lines | ||
| 114 | 119 | } |
| 115 | 120 | |
| 116 | 121 | struct uart_8250_port *serial8250_get_port(int line); |
| 122 | +void serial8250_rpm_get(struct uart_8250_port *p); | |
| 123 | +void serial8250_rpm_put(struct uart_8250_port *p); | |
| 117 | 124 | |
| 118 | 125 | #if defined(__alpha__) && !defined(CONFIG_PCI) |
| 119 | 126 | /* |
| @@ -541,23 +541,25 @@ void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p) · 540 unmodified lines | ||
| 541 | 541 | } |
| 542 | 542 | EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos); |
| 543 | 543 | |
| 544 | −static void serial8250_rpm_get(struct uart_8250_port *p) | |
| 544 | +void serial8250_rpm_get(struct uart_8250_port *p) | |
| 545 | 545 | { |
| 546 | 546 | if (!(p->capabilities & UART_CAP_RPM)) |
| 547 | 547 | return; |
| 548 | 548 | pm_runtime_get_sync(p->port.dev); |
| 549 | 549 | } |
| 550 | +EXPORT_SYMBOL_GPL(serial8250_rpm_get); | |
| 550 | 551 | |
| 551 | −static void serial8250_rpm_put(struct uart_8250_port *p) | |
| 552 | +void serial8250_rpm_put(struct uart_8250_port *p) | |
| 552 | 553 | { |
| 553 | 554 | if (!(p->capabilities & UART_CAP_RPM)) |
| 554 | 555 | return; |
| 555 | 556 | pm_runtime_mark_last_busy(p->port.dev); |
| 556 | 557 | pm_runtime_put_autosuspend(p->port.dev); |
| 557 | 558 | } |
| 559 | +EXPORT_SYMBOL_GPL(serial8250_rpm_put); | |
| 558 | 560 | |
| 559 | 561 | /* |
| 560 | − * This two wrapper ensure, that enable_runtime_pm_tx() can be called more than | |
| 562 | + * These two wrappers ensure that enable_runtime_pm_tx() can be called more than | |
| 561 | 563 | * once and disable_runtime_pm_tx() will still disable RPM because the fifo is |
| 562 | 564 | * empty and the HW can idle again. |
| 563 | 565 | */ |
| @@ -595,6 +597,7 @@ static void serial8250_rpm_put_tx(struct uart_8250_port *p) · 31 unmodified lines | ||
| 595 | 597 | */ |
| 596 | 598 | static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) |
| 597 | 599 | { |
| 600 | + unsigned char lcr = 0, efr = 0; | |
| 598 | 601 | /* |
| 599 | 602 | * Exar UARTs have a SLEEP register that enables or disables |
| 600 | 603 | * each UART to enter sleep mode separately. On the XR17V35x the |
| @@ -611,6 +614,8 @@ static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) · 10 unmodified lines | ||
| 611 | 614 | |
| 612 | 615 | if (p->capabilities & UART_CAP_SLEEP) { |
| 613 | 616 | if (p->capabilities & UART_CAP_EFR) { |
| 617 | + lcr = serial_in(p, UART_LCR); | |
| 618 | + efr = serial_in(p, UART_EFR); | |
| 614 | 619 | serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); |
| 615 | 620 | serial_out(p, UART_EFR, UART_EFR_ECB); |
| 616 | 621 | serial_out(p, UART_LCR, 0); |
| @@ -618,8 +623,8 @@ static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) · 1 unmodified line | ||
| 618 | 623 | serial_out(p, UART_IER, sleep ? UART_IERX_SLEEP : 0); |
| 619 | 624 | if (p->capabilities & UART_CAP_EFR) { |
| 620 | 625 | serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B); |
| 621 | − serial_out(p, UART_EFR, 0); | |
| 622 | − serial_out(p, UART_LCR, 0); | |
| 626 | + serial_out(p, UART_EFR, efr); | |
| 627 | + serial_out(p, UART_LCR, lcr); | |
| 623 | 628 | } |
| 624 | 629 | } |
| 625 | 630 | out: |
| @@ -1350,7 +1355,7 @@ static void serial8250_start_tx(struct uart_port *port) · 724 unmodified lines | ||
| 1350 | 1355 | struct uart_8250_port *up = up_to_u8250p(port); |
| 1351 | 1356 | |
| 1352 | 1357 | serial8250_rpm_get_tx(up); |
| 1353 | − if (up->dma && !serial8250_tx_dma(up)) { | |
| 1358 | + if (up->dma && !up->dma->tx_dma(up)) { | |
| 1354 | 1359 | return; |
| 1355 | 1360 | } else if (!(up->ier & UART_IER_THRI)) { |
| 1356 | 1361 | up->ier |= UART_IER_THRI; |
| @@ -1397,6 +1402,19 @@ static void serial8250_stop_rx(struct uart_port *port) · 40 unmodified lines | ||
| 1397 | 1402 | serial8250_rpm_put(up); |
| 1398 | 1403 | } |
| 1399 | 1404 | |
| 1405 | +static void serial8250_disable_ms(struct uart_port *port) | |
| 1406 | +{ | |
| 1407 | + struct uart_8250_port *up = | |
| 1408 | + container_of(port, struct uart_8250_port, port); | |
| 1409 | + | |
| 1410 | + /* no MSR capabilities */ | |
| 1411 | + if (up->bugs & UART_BUG_NOMSR) | |
| 1412 | + return; | |
| 1413 | + | |
| 1414 | + up->ier &= ~UART_IER_MSI; | |
| 1415 | + serial_port_out(port, UART_IER, up->ier); | |
| 1416 | +} | |
| 1417 | + | |
| 1400 | 1418 | static void serial8250_enable_ms(struct uart_port *port) |
| 1401 | 1419 | { |
| 1402 | 1420 | struct uart_8250_port *up = up_to_u8250p(port); |
| @@ -1483,7 +1501,7 @@ serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) · 80 unmodified lines | ||
| 1483 | 1501 | |
| 1484 | 1502 | ignore_char: |
| 1485 | 1503 | lsr = serial_in(up, UART_LSR); |
| 1486 | − } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0)); | |
| 1504 | + } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (--max_count > 0)); | |
| 1487 | 1505 | spin_unlock(&port->lock); |
| 1488 | 1506 | tty_flip_buffer_push(&port->state->port); |
| 1489 | 1507 | spin_lock(&port->lock); |
| @@ -1532,7 +1550,7 @@ void serial8250_tx_chars(struct uart_8250_port *up) · 42 unmodified lines | ||
| 1532 | 1550 | DEBUG_INTR("THRE..."); |
| 1533 | 1551 | |
| 1534 | 1552 | /* |
| 1535 | − * With RPM enabled, we have to wait once the FIFO is empty before the | |
| 1553 | + * With RPM enabled, we have to wait until the FIFO is empty before the | |
| 1536 | 1554 | * HW can go idle. So we get here once again with empty FIFO and disable |
| 1537 | 1555 | * the interrupt and RPM in __stop_tx() |
| 1538 | 1556 | */ |
| @@ -1588,13 +1606,14 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) · 49 unmodified lines | ||
| 1588 | 1606 | |
| 1589 | 1607 | if (status & (UART_LSR_DR | UART_LSR_BI)) { |
| 1590 | 1608 | if (up->dma) |
| 1591 | − dma_err = serial8250_rx_dma(up, iir); | |
| 1609 | + dma_err = up->dma->rx_dma(up, iir); | |
| 1592 | 1610 | |
| 1593 | 1611 | if (!up->dma || dma_err) |
| 1594 | 1612 | status = serial8250_rx_chars(up, status); |
| 1595 | 1613 | } |
| 1596 | 1614 | serial8250_modem_status(up); |
| 1597 | − if (!up->dma && (status & UART_LSR_THRE)) | |
| 1615 | + if ((!up->dma || (up->dma && up->dma->tx_err)) && | |
| 1616 | + (status & UART_LSR_THRE)) | |
| 1598 | 1617 | serial8250_tx_chars(up); |
| 1599 | 1618 | |
| 1600 | 1619 | spin_unlock_irqrestore(&port->lock, flags); |
| @@ -2603,13 +2622,21 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios, · 1002 unmodified lines | ||
| 2603 | 2622 | } |
| 2604 | 2623 | |
| 2605 | 2624 | static void |
| 2606 | −serial8250_set_ldisc(struct uart_port *port, int new) | |
| 2625 | +serial8250_set_ldisc(struct uart_port *port, struct ktermios *termios) | |
| 2607 | 2626 | { |
| 2608 | − if (new == N_PPS) { | |
| 2627 | + if (termios->c_line == N_PPS) { | |
| 2609 | 2628 | port->flags |= UPF_HARDPPS_CD; |
| 2629 | + spin_lock_irq(&port->lock); | |
| 2610 | 2630 | serial8250_enable_ms(port); |
| 2611 | − } else | |
| 2631 | + spin_unlock_irq(&port->lock); | |
| 2632 | + } else { | |
| 2612 | 2633 | port->flags &= ~UPF_HARDPPS_CD; |
| 2634 | + if (!UART_ENABLE_MS(port, termios->c_cflag)) { | |
| 2635 | + spin_lock_irq(&port->lock); | |
| 2636 | + serial8250_disable_ms(port); | |
| 2637 | + spin_unlock_irq(&port->lock); | |
| 2638 | + } | |
| 2639 | + } | |
| 2613 | 2640 | } |
| 2614 | 2641 | |
| 2615 | 2642 | |
| @@ -2634,8 +2661,11 @@ serial8250_pm(struct uart_port *port, unsigned int state, · 18 unmodified lines | ||
| 2634 | 2661 | |
| 2635 | 2662 | static unsigned int serial8250_port_size(struct uart_8250_port *pt) |
| 2636 | 2663 | { |
| 2637 | − if (pt->port.iotype == UPIO_AU) | |
| 2664 | + if (pt->port.iotype == UPIO_AU) { | |
| 2665 | + if (pt->port.type == PORT_RT2880) | |
| 2666 | + return 0x100; | |
| 2638 | 2667 | return 0x1000; |
| 2668 | + } | |
| 2639 | 2669 | if (is_omap1_8250(pt)) |
| 2640 | 2670 | return 0x16 << pt->port.regshift; |
| 2641 | 2671 | |
| @@ -2975,42 +3005,6 @@ serial8250_verify_port(struct uart_port *port, struct serial_struct *ser) · 333 unmodified lines | ||
| 2975 | 3005 | return 0; |
| 2976 | 3006 | } |
| 2977 | 3007 | |
| 2978 | −static int serial8250_ioctl(struct uart_port *port, unsigned int cmd, | |
| 2979 | − unsigned long arg) | |
| 2980 | −{ | |
| 2981 | − struct uart_8250_port *up = | |
| 2982 | − container_of(port, struct uart_8250_port, port); | |
| 2983 | − int ret; | |
| 2984 | − struct serial_rs485 rs485_config; | |
| 2985 | − | |
| 2986 | − if (!up->rs485_config) | |
| 2987 | − return -ENOIOCTLCMD; | |
| 2988 | − | |
| 2989 | − switch (cmd) { | |
| 2990 | − case TIOCSRS485: | |
| 2991 | − if (copy_from_user(&rs485_config, (void __user *)arg, | |
| 2992 | − sizeof(rs485_config))) | |
| 2993 | − return -EFAULT; | |
| 2994 | − | |
| 2995 | − ret = up->rs485_config(up, &rs485_config); | |
| 2996 | − if (ret) | |
| 2997 | − return ret; | |
| 2998 | − | |
| 2999 | − memcpy(&up->rs485, &rs485_config, sizeof(rs485_config)); | |
| 3000 | − | |
| 3001 | − return 0; | |
| 3002 | − case TIOCGRS485: | |
| 3003 | − if (copy_to_user((void __user *)arg, &up->rs485, | |
| 3004 | − sizeof(up->rs485))) | |
| 3005 | − return -EFAULT; | |
| 3006 | − return 0; | |
| 3007 | − default: | |
| 3008 | − break; | |
| 3009 | − } | |
| 3010 | − | |
| 3011 | − return -ENOIOCTLCMD; | |
| 3012 | −} | |
| 3013 | − | |
| 3014 | 3008 | static const char * |
| 3015 | 3009 | serial8250_type(struct uart_port *port) |
| 3016 | 3010 | { |
| @@ -3042,7 +3036,6 @@ static struct uart_ops serial8250_pops = { · 25 unmodified lines | ||
| 3042 | 3036 | .request_port = serial8250_request_port, |
| 3043 | 3037 | .config_port = serial8250_config_port, |
| 3044 | 3038 | .verify_port = serial8250_verify_port, |
| 3045 | − .ioctl = serial8250_ioctl, | |
| 3046 | 3039 | #ifdef CONFIG_CONSOLE_POLL |
| 3047 | 3040 | .poll_get_char = serial8250_get_poll_char, |
| 3048 | 3041 | .poll_put_char = serial8250_put_poll_char, |
| @@ -3198,7 +3191,9 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) · 149 unmodified lines | ||
| 3198 | 3191 | |
| 3199 | 3192 | serial8250_rpm_get(up); |
| 3200 | 3193 | |
| 3201 | − if (port->sysrq || oops_in_progress) | |
| 3194 | + if (port->sysrq) | |
| 3195 | + locked = 0; | |
| 3196 | + else if (oops_in_progress) | |
| 3202 | 3197 | locked = spin_trylock_irqsave(&port->lock, flags); |
| 3203 | 3198 | else |
| 3204 | 3199 | spin_lock_irqsave(&port->lock, flags); |
| @@ -3237,7 +3232,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) · 32 unmodified lines | ||
| 3237 | 3232 | serial8250_rpm_put(up); |
| 3238 | 3233 | } |
| 3239 | 3234 | |
| 3240 | −static int __init serial8250_console_setup(struct console *co, char *options) | |
| 3235 | +static int serial8250_console_setup(struct console *co, char *options) | |
| 3241 | 3236 | { |
| 3242 | 3237 | struct uart_port *port; |
| 3243 | 3238 | int baud = 9600; |
| @@ -3585,10 +3580,10 @@ int serial8250_register_8250_port(struct uart_8250_port *up) · 341 unmodified lines | ||
| 3585 | 3580 | uart->port.fifosize = up->port.fifosize; |
| 3586 | 3581 | uart->tx_loadsz = up->tx_loadsz; |
| 3587 | 3582 | uart->capabilities = up->capabilities; |
| 3588 | − uart->rs485_config = up->rs485_config; | |
| 3589 | − uart->rs485 = up->rs485; | |
| 3590 | 3583 | uart->port.throttle = up->port.throttle; |
| 3591 | 3584 | uart->port.unthrottle = up->port.unthrottle; |
| 3585 | + uart->port.rs485_config = up->port.rs485_config; | |
| 3586 | + uart->port.rs485 = up->port.rs485; | |
| 3592 | 3587 | |
| 3593 | 3588 | /* Take tx_loadsz from fifosize if it wasn't set separately */ |
| 3594 | 3589 | if (uart->port.fifosize && !uart->tx_loadsz) |
| @@ -3623,8 +3618,13 @@ int serial8250_register_8250_port(struct uart_8250_port *up) · 28 unmodified lines | ||
| 3623 | 3618 | uart->dl_read = up->dl_read; |
| 3624 | 3619 | if (up->dl_write) |
| 3625 | 3620 | uart->dl_write = up->dl_write; |
| 3626 | − if (up->dma) | |
| 3621 | + if (up->dma) { | |
| 3627 | 3622 | uart->dma = up->dma; |
| 3623 | + if (!uart->dma->tx_dma) | |
| 3624 | + uart->dma->tx_dma = serial8250_tx_dma; | |
| 3625 | + if (!uart->dma->rx_dma) | |
| 3626 | + uart->dma->rx_dma = serial8250_rx_dma; | |
| 3627 | + } | |
| 3628 | 3628 | |
| 3629 | 3629 | if (serial8250_isa_config != NULL) |
| 3630 | 3630 | serial8250_isa_config(0, &uart->port, |
| @@ -21,6 +21,7 @@ static void __dma_tx_complete(void *param) · 20 unmodified lines | ||
| 21 | 21 | struct uart_8250_dma *dma = p->dma; |
| 22 | 22 | struct circ_buf *xmit = &p->port.state->xmit; |
| 23 | 23 | unsigned long flags; |
| 24 | + int ret; | |
| 24 | 25 | |
| 25 | 26 | dma_sync_single_for_cpu(dma->txchan->device->dev, dma->tx_addr, |
| 26 | 27 | UART_XMIT_SIZE, DMA_TO_DEVICE); |
| @@ -36,8 +37,11 @@ static void __dma_tx_complete(void *param) · 9 unmodified lines | ||
| 36 | 37 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
| 37 | 38 | uart_write_wakeup(&p->port); |
| 38 | 39 | |
| 39 | − if (!uart_circ_empty(xmit) && !uart_tx_stopped(&p->port)) | |
| 40 | − serial8250_tx_dma(p); | |
| 40 | + ret = serial8250_tx_dma(p); | |
| 41 | + if (ret) { | |
| 42 | + p->ier |= UART_IER_THRI; | |
| 43 | + serial_port_out(&p->port, UART_IER, p->ier); | |
| 44 | + } | |
| 41 | 45 | |
| 42 | 46 | spin_unlock_irqrestore(&p->port.lock, flags); |
| 43 | 47 | } |
| @@ -53,6 +57,7 @@ static void __dma_rx_complete(void *param) · 9 unmodified lines | ||
| 53 | 57 | dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr, |
| 54 | 58 | dma->rx_size, DMA_FROM_DEVICE); |
| 55 | 59 | |
| 60 | + dma->rx_running = 0; | |
| 56 | 61 | dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); |
| 57 | 62 | dmaengine_terminate_all(dma->rxchan); |
| 58 | 63 | |
| @@ -69,6 +74,7 @@ int serial8250_tx_dma(struct uart_8250_port *p) · 10 unmodified lines | ||
| 69 | 74 | struct uart_8250_dma *dma = p->dma; |
| 70 | 75 | struct circ_buf *xmit = &p->port.state->xmit; |
| 71 | 76 | struct dma_async_tx_descriptor *desc; |
| 77 | + int ret; | |
| 72 | 78 | |
| 73 | 79 | if (uart_tx_stopped(&p->port) || dma->tx_running || |
| 74 | 80 | uart_circ_empty(xmit)) |
| @@ -80,11 +86,12 @@ int serial8250_tx_dma(struct uart_8250_port *p) · 5 unmodified lines | ||
| 80 | 86 | dma->tx_addr + xmit->tail, |
| 81 | 87 | dma->tx_size, DMA_MEM_TO_DEV, |
| 82 | 88 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
| 83 | − if (!desc) | |
| 84 | − return -EBUSY; | |
| 89 | + if (!desc) { | |
| 90 | + ret = -EBUSY; | |
| 91 | + goto err; | |
| 92 | + } | |
| 85 | 93 | |
| 86 | 94 | dma->tx_running = 1; |
| 87 | − | |
| 88 | 95 | desc->callback = __dma_tx_complete; |
| 89 | 96 | desc->callback_param = p; |
| 90 | 97 | |
| @@ -94,19 +101,23 @@ int serial8250_tx_dma(struct uart_8250_port *p) · 3 unmodified lines | ||
| 94 | 101 | UART_XMIT_SIZE, DMA_TO_DEVICE); |
| 95 | 102 | |
| 96 | 103 | dma_async_issue_pending(dma->txchan); |
| 97 | − | |
| 104 | + if (dma->tx_err) { | |
| 105 | + dma->tx_err = 0; | |
| 106 | + if (p->ier & UART_IER_THRI) { | |
| 107 | + p->ier &= ~UART_IER_THRI; | |
| 108 | + serial_out(p, UART_IER, p->ier); | |
| 109 | + } | |
| 110 | + } | |
| 98 | 111 | return 0; |
| 112 | +err: | |
| 113 | + dma->tx_err = 1; | |
| 114 | + return ret; | |
| 99 | 115 | } |
| 100 | −EXPORT_SYMBOL_GPL(serial8250_tx_dma); | |
| 101 | 116 | |
| 102 | 117 | int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir) |
| 103 | 118 | { |
| 104 | 119 | struct uart_8250_dma *dma = p->dma; |
| 105 | 120 | struct dma_async_tx_descriptor *desc; |
| 106 | − struct dma_tx_state state; | |
| 107 | − int dma_status; | |
| 108 | − | |
| 109 | − dma_status = dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); | |
| 110 | 121 | |
| 111 | 122 | switch (iir & 0x3f) { |
| 112 | 123 | case UART_IIR_RLSI: |
| @@ -117,7 +128,7 @@ int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir) · 4 unmodified lines | ||
| 117 | 128 | * If RCVR FIFO trigger level was not reached, complete the |
| 118 | 129 | * transfer and let 8250_core copy the remaining data. |
| 119 | 130 | */ |
| 120 | − if (dma_status == DMA_IN_PROGRESS) { | |
| 131 | + if (dma->rx_running) { | |
| 121 | 132 | dmaengine_pause(dma->rxchan); |
| 122 | 133 | __dma_rx_complete(p); |
| 123 | 134 | } |
| @@ -126,7 +137,7 @@ int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir) · 2 unmodified lines | ||
| 126 | 137 | break; |
| 127 | 138 | } |
| 128 | 139 | |
| 129 | − if (dma_status) | |
| 140 | + if (dma->rx_running) | |
| 130 | 141 | return 0; |
| 131 | 142 | |
| 132 | 143 | desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr, |
| @@ -135,6 +146,7 @@ int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir) · 2 unmodified lines | ||
| 135 | 146 | if (!desc) |
| 136 | 147 | return -EBUSY; |
| 137 | 148 | |
| 149 | + dma->rx_running = 1; | |
| 138 | 150 | desc->callback = __dma_rx_complete; |
| 139 | 151 | desc->callback_param = p; |
| 140 | 152 | |
| @@ -147,7 +159,6 @@ int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir) · 6 unmodified lines | ||
| 147 | 159 | |
| 148 | 160 | return 0; |
| 149 | 161 | } |
| 150 | −EXPORT_SYMBOL_GPL(serial8250_rx_dma); | |
| 151 | 162 | |
| 152 | 163 | int serial8250_request_dma(struct uart_8250_port *p) |
| 153 | 164 | { |
| @@ -122,13 +122,44 @@ static unsigned int dw8250_serial_in(struct uart_port *p, int offset) · 121 unmodified lines | ||
| 122 | 122 | return dw8250_modify_msr(p, offset, value); |
| 123 | 123 | } |
| 124 | 124 | |
| 125 | −/* Read Back (rb) version to ensure register access ording. */ | |
| 126 | −static void dw8250_serial_out_rb(struct uart_port *p, int offset, int value) | |
| 125 | +#ifdef CONFIG_64BIT | |
| 126 | +static unsigned int dw8250_serial_inq(struct uart_port *p, int offset) | |
| 127 | 127 | { |
| 128 | − dw8250_serial_out(p, offset, value); | |
| 129 | − dw8250_serial_in(p, UART_LCR); | |
| 128 | + unsigned int value; | |
| 129 | + | |
| 130 | + value = (u8)__raw_readq(p->membase + (offset << p->regshift)); | |
| 131 | + | |
| 132 | + return dw8250_modify_msr(p, offset, value); | |
| 130 | 133 | } |
| 131 | 134 | |
| 135 | +static void dw8250_serial_outq(struct uart_port *p, int offset, int value) | |
| 136 | +{ | |
| 137 | + struct dw8250_data *d = p->private_data; | |
| 138 | + | |
| 139 | + if (offset == UART_MCR) | |
| 140 | + d->last_mcr = value; | |
| 141 | + | |
| 142 | + value &= 0xff; | |
| 143 | + __raw_writeq(value, p->membase + (offset << p->regshift)); | |
| 144 | + /* Read back to ensure register write ordering. */ | |
| 145 | + __raw_readq(p->membase + (UART_LCR << p->regshift)); | |
| 146 | + | |
| 147 | + /* Make sure LCR write wasn't ignored */ | |
| 148 | + if (offset == UART_LCR) { | |
| 149 | + int tries = 1000; | |
| 150 | + while (tries--) { | |
| 151 | + unsigned int lcr = p->serial_in(p, UART_LCR); | |
| 152 | + if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR)) | |
| 153 | + return; | |
| 154 | + dw8250_force_idle(p); | |
| 155 | + __raw_writeq(value & 0xff, | |
| 156 | + p->membase + (UART_LCR << p->regshift)); | |
| 157 | + } | |
| 158 | + dev_err(p->dev, "Couldn't set LCR to %d\n", value); | |
| 159 | + } | |
| 160 | +} | |
| 161 | +#endif /* CONFIG_64BIT */ | |
| 162 | + | |
| 132 | 163 | static void dw8250_serial_out32(struct uart_port *p, int offset, int value) |
| 133 | 164 | { |
| 134 | 165 | struct dw8250_data *d = p->private_data; |
| @@ -258,22 +289,19 @@ static int dw8250_probe_of(struct uart_port *p, · 123 unmodified lines | ||
| 258 | 289 | struct uart_8250_port *up = up_to_u8250p(p); |
| 259 | 290 | u32 val; |
| 260 | 291 | bool has_ucv = true; |
| 292 | + int id; | |
| 261 | 293 | |
| 294 | +#ifdef CONFIG_64BIT | |
| 262 | 295 | if (of_device_is_compatible(np, "cavium,octeon-3860-uart")) { |
| 263 | −#ifdef __BIG_ENDIAN | |
| 264 | − /* | |
| 265 | − * Low order bits of these 64-bit registers, when | |
| 266 | − * accessed as a byte, are 7 bytes further down in the | |
| 267 | − * address space in big endian mode. | |
| 268 | − */ | |
| 269 | − p->membase += 7; | |
| 270 | −#endif | |
| 271 | − p->serial_out = dw8250_serial_out_rb; | |
| 296 | + p->serial_in = dw8250_serial_inq; | |
| 297 | + p->serial_out = dw8250_serial_outq; | |
| 272 | 298 | p->flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE; |
| 273 | 299 | p->type = PORT_OCTEON; |
| 274 | 300 | data->usr_reg = 0x27; |
| 275 | 301 | has_ucv = false; |
| 276 | − } else if (!of_property_read_u32(np, "reg-io-width", &val)) { | |
| 302 | + } else | |
| 303 | +#endif | |
| 304 | + if (!of_property_read_u32(np, "reg-io-width", &val)) { | |
| 277 | 305 | switch (val) { |
| 278 | 306 | case 1: |
| 279 | 307 | break; |
| @@ -290,9 +318,22 @@ static int dw8250_probe_of(struct uart_port *p, · 10 unmodified lines | ||
| 290 | 318 | if (has_ucv) |
| 291 | 319 | dw8250_setup_port(up); |
| 292 | 320 | |
| 321 | + /* if we have a valid fifosize, try hooking up DMA here */ | |
| 322 | + if (p->fifosize) { | |
| 323 | + up->dma = &data->dma; | |
| 324 | + | |
| 325 | + up->dma->rxconf.src_maxburst = p->fifosize / 4; | |
| 326 | + up->dma->txconf.dst_maxburst = p->fifosize / 4; | |
| 327 | + } | |
| 328 | + | |
| 293 | 329 | if (!of_property_read_u32(np, "reg-shift", &val)) |
| 294 | 330 | p->regshift = val; |
| 295 | 331 | |
| 332 | + /* get index of serial line, if found in DT aliases */ | |
| 333 | + id = of_alias_get_id(np, "serial"); | |
| 334 | + if (id >= 0) | |
| 335 | + p->line = id; | |
| 336 | + | |
| 296 | 337 | /* clock got configured through clk api, all done */ |
| 297 | 338 | if (p->uartclk) |
| 298 | 339 | return 0; |
| @@ -102,10 +102,8 @@ static int serial8250_em_probe(struct platform_device *pdev) · 101 unmodified lines | ||
| 102 | 102 | } |
| 103 | 103 | |
| 104 | 104 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); |
| 105 | − if (!priv) { | |
| 106 | − dev_err(&pdev->dev, "unable to allocate private data\n"); | |
| 105 | + if (!priv) | |
| 107 | 106 | return -ENOMEM; |
| 108 | − } | |
| 109 | 107 | |
| 110 | 108 | priv->sclk = devm_clk_get(&pdev->dev, "sclk"); |
| 111 | 109 | if (IS_ERR(priv->sclk)) { |
| @@ -89,11 +89,11 @@ static int fintek_8250_check_id(void) · 88 unmodified lines | ||
| 89 | 89 | return 0; |
| 90 | 90 | } |
| 91 | 91 | |
| 92 | −static int fintek_8250_rs4850_config(struct uart_8250_port *uart, | |
| 92 | +static int fintek_8250_rs485_config(struct uart_port *port, | |
| 93 | 93 | struct serial_rs485 *rs485) |
| 94 | 94 | { |
| 95 | 95 | uint8_t config = 0; |
| 96 | − int index = fintek_8250_get_index(uart->port.iobase); | |
| 96 | + int index = fintek_8250_get_index(port->iobase); | |
| 97 | 97 | |
| 98 | 98 | if (index < 0) |
| 99 | 99 | return -EINVAL; |
| @@ -134,6 +134,8 @@ static int fintek_8250_rs4850_config(struct uart_8250_port *uart, · 34 unmodified lines | ||
| 134 | 134 | outb(config, DATA_PORT); |
| 135 | 135 | fintek_8250_exit_key(); |
| 136 | 136 | |
| 137 | + port->rs485 = *rs485; | |
| 138 | + | |
| 137 | 139 | return 0; |
| 138 | 140 | } |
| 139 | 141 | |
| @@ -166,7 +168,7 @@ fintek_8250_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) · 26 unmodified lines | ||
| 166 | 168 | uart.port.irq = pnp_irq(dev, 0); |
| 167 | 169 | uart.port.iobase = pnp_port_start(dev, 0); |
| 168 | 170 | uart.port.iotype = UPIO_PORT; |
| 169 | − uart.rs485_config = fintek_8250_rs4850_config; | |
| 171 | + uart.port.rs485_config = fintek_8250_rs485_config; | |
| 170 | 172 | |
| 171 | 173 | uart.port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; |
| 172 | 174 | if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE) |
| @@ -88,10 +88,6 @@ extern int hp300_uart_scode; · 87 unmodified lines | ||
| 88 | 88 | /* |
| 89 | 89 | * Parse the bootinfo to find descriptions for headless console and |
| 90 | 90 | * debug serial ports and register them with the 8250 driver. |
| 91 | − * This function should be called before serial_console_init() is called | |
| 92 | − * to make sure the serial console will be available for use. IA-64 kernel | |
| 93 | − * calls this function from setup_arch() after the EFI and ACPI tables have | |
| 94 | − * been parsed. | |
| 95 | 91 | */ |
| 96 | 92 | int __init hp300_setup_serial_console(void) |
| 97 | 93 | { |
| @@ -74,14 +74,14 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios, · 73 unmodified lines | ||
| 74 | 74 | /* Set to next lower baudrate supported */ |
| 75 | 75 | if ((baud == 500000) || (baud == 576000)) |
| 76 | 76 | baud = 460800; |
| 77 | − quot = DIV_ROUND_CLOSEST(port->uartclk, 4 * baud); | |
| 77 | + quot = DIV_ROUND_UP(port->uartclk, 4 * baud); | |
| 78 | 78 | } else { |
| 79 | 79 | serial_port_out(port, UART_MTK_HIGHS, 0x3); |
| 80 | 80 | |
| 81 | 81 | /* Set to highest baudrate supported */ |
| 82 | 82 | if (baud >= 1152000) |
| 83 | 83 | baud = 921600; |
| 84 | − quot = (port->uartclk / (256 * baud)) + 1; | |
| 84 | + quot = DIV_ROUND_UP(port->uartclk, 256 * baud); | |
| 85 | 85 | } |
| 86 | 86 | |
| 87 | 87 | /* |
| @@ -0,0 +1,1281 @@ | ||
| 1 | +/* | |
| 2 | + * 8250-core based driver for the OMAP internal UART | |
| 3 | + * | |
| 4 | + * based on omap-serial.c, Copyright (C) 2010 Texas Instruments. | |
| 5 | + * | |
| 6 | + * Copyright (C) 2014 Sebastian Andrzej Siewior | |
| 7 | + * | |
| 8 | + */ | |
| 9 | + | |
| 10 | +#include <linux/device.h> | |
| 11 | +#include <linux/io.h> | |
| 12 | +#include <linux/module.h> | |
| 13 | +#include <linux/serial_8250.h> | |
| 14 | +#include <linux/serial_core.h> | |
| 15 | +#include <linux/serial_reg.h> | |
| 16 | +#include <linux/tty_flip.h> | |
| 17 | +#include <linux/platform_device.h> | |
| 18 | +#include <linux/slab.h> | |
| 19 | +#include <linux/of.h> | |
| 20 | +#include <linux/of_gpio.h> | |
| 21 | +#include <linux/of_irq.h> | |
| 22 | +#include <linux/delay.h> | |
| 23 | +#include <linux/pm_runtime.h> | |
| 24 | +#include <linux/console.h> | |
| 25 | +#include <linux/pm_qos.h> | |
| 26 | +#include <linux/dma-mapping.h> | |
| 27 | + | |
| 28 | +#include "8250.h" | |
| 29 | + | |
| 30 | +#define DEFAULT_CLK_SPEED 48000000 | |
| 31 | + | |
| 32 | +#define UART_ERRATA_i202_MDR1_ACCESS (1 << 0) | |
| 33 | +#define OMAP_UART_WER_HAS_TX_WAKEUP (1 << 1) | |
| 34 | +#define OMAP_DMA_TX_KICK (1 << 2) | |
| 35 | + | |
| 36 | +#define OMAP_UART_FCR_RX_TRIG 6 | |
| 37 | +#define OMAP_UART_FCR_TX_TRIG 4 | |
| 38 | + | |
| 39 | +/* SCR register bitmasks */ | |
| 40 | +#define OMAP_UART_SCR_RX_TRIG_GRANU1_MASK (1 << 7) | |
| 41 | +#define OMAP_UART_SCR_TX_TRIG_GRANU1_MASK (1 << 6) | |
| 42 | +#define OMAP_UART_SCR_TX_EMPTY (1 << 3) | |
| 43 | +#define OMAP_UART_SCR_DMAMODE_MASK (3 << 1) | |
| 44 | +#define OMAP_UART_SCR_DMAMODE_1 (1 << 1) | |
| 45 | +#define OMAP_UART_SCR_DMAMODE_CTL (1 << 0) | |
| 46 | + | |
| 47 | +/* MVR register bitmasks */ | |
| 48 | +#define OMAP_UART_MVR_SCHEME_SHIFT 30 | |
| 49 | +#define OMAP_UART_LEGACY_MVR_MAJ_MASK 0xf0 | |
| 50 | +#define OMAP_UART_LEGACY_MVR_MAJ_SHIFT 4 | |
| 51 | +#define OMAP_UART_LEGACY_MVR_MIN_MASK 0x0f | |
| 52 | +#define OMAP_UART_MVR_MAJ_MASK 0x700 | |
| 53 | +#define OMAP_UART_MVR_MAJ_SHIFT 8 | |
| 54 | +#define OMAP_UART_MVR_MIN_MASK 0x3f | |
| 55 | + | |
| 56 | +#define UART_TI752_TLR_TX 0 | |
| 57 | +#define UART_TI752_TLR_RX 4 | |
| 58 | + | |
| 59 | +#define TRIGGER_TLR_MASK(x) ((x & 0x3c) >> 2) | |
| 60 | +#define TRIGGER_FCR_MASK(x) (x & 3) | |
| 61 | + | |
| 62 | +/* Enable XON/XOFF flow control on output */ | |
| 63 | +#define OMAP_UART_SW_TX 0x08 | |
| 64 | +/* Enable XON/XOFF flow control on input */ | |
| 65 | +#define OMAP_UART_SW_RX 0x02 | |
| 66 | + | |
| 67 | +#define OMAP_UART_WER_MOD_WKUP 0x7f | |
| 68 | +#define OMAP_UART_TX_WAKEUP_EN (1 << 7) | |
| 69 | + | |
| 70 | +#define TX_TRIGGER 1 | |
| 71 | +#define RX_TRIGGER 48 | |
| 72 | + | |
| 73 | +#define OMAP_UART_TCR_RESTORE(x) ((x / 4) << 4) | |
| 74 | +#define OMAP_UART_TCR_HALT(x) ((x / 4) << 0) | |
| 75 | + | |
| 76 | +#define UART_BUILD_REVISION(x, y) (((x) << 8) | (y)) | |
| 77 | + | |
| 78 | +#define OMAP_UART_REV_46 0x0406 | |
| 79 | +#define OMAP_UART_REV_52 0x0502 | |
| 80 | +#define OMAP_UART_REV_63 0x0603 | |
| 81 | + | |
| 82 | +struct omap8250_priv { | |
| 83 | + int line; | |
| 84 | + u8 habit; | |
| 85 | + u8 mdr1; | |
| 86 | + u8 efr; | |
| 87 | + u8 scr; | |
| 88 | + u8 wer; | |
| 89 | + u8 xon; | |
| 90 | + u8 xoff; | |
| 91 | + u8 delayed_restore; | |
| 92 | + u16 quot; | |
| 93 | + | |
| 94 | + bool is_suspending; | |
| 95 | + int wakeirq; | |
| 96 | + int wakeups_enabled; | |
| 97 | + u32 latency; | |
| 98 | + u32 calc_latency; | |
| 99 | + struct pm_qos_request pm_qos_request; | |
| 100 | + struct work_struct qos_work; | |
| 101 | + struct uart_8250_dma omap8250_dma; | |
| 102 | +}; | |
| 103 | + | |
| 104 | +static u32 uart_read(struct uart_8250_port *up, u32 reg) | |
| 105 | +{ | |
| 106 | + return readl(up->port.membase + (reg << up->port.regshift)); | |
| 107 | +} | |
| 108 | + | |
| 109 | +/* | |
| 110 | + * Work Around for Errata i202 (2430, 3430, 3630, 4430 and 4460) | |
| 111 | + * The access to uart register after MDR1 Access | |
| 112 | + * causes UART to corrupt data. | |
| 113 | + * | |
| 114 | + * Need a delay = | |
| 115 | + * 5 L4 clock cycles + 5 UART functional clock cycle (@48MHz = ~0.2uS) | |
| 116 | + * give 10 times as much | |
| 117 | + */ | |
| 118 | +static void omap_8250_mdr1_errataset(struct uart_8250_port *up, | |
| 119 | + struct omap8250_priv *priv) | |
| 120 | +{ | |
| 121 | + u8 timeout = 255; | |
| 122 | + u8 old_mdr1; | |
| 123 | + | |
| 124 | + old_mdr1 = serial_in(up, UART_OMAP_MDR1); | |
| 125 | + if (old_mdr1 == priv->mdr1) | |
| 126 | + return; | |
| 127 | + | |
| 128 | + serial_out(up, UART_OMAP_MDR1, priv->mdr1); | |
| 129 | + udelay(2); | |
| 130 | + serial_out(up, UART_FCR, up->fcr | UART_FCR_CLEAR_XMIT | | |
| 131 | + UART_FCR_CLEAR_RCVR); | |
| 132 | + /* | |
| 133 | + * Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and | |
| 134 | + * TX_FIFO_E bit is 1. | |
| 135 | + */ | |
| 136 | + while (UART_LSR_THRE != (serial_in(up, UART_LSR) & | |
| 137 | + (UART_LSR_THRE | UART_LSR_DR))) { | |
| 138 | + timeout--; | |
| 139 | + if (!timeout) { | |
| 140 | + /* Should *never* happen. we warn and carry on */ | |
| 141 | + dev_crit(up->port.dev, "Errata i202: timedout %x\n", | |
| 142 | + serial_in(up, UART_LSR)); | |
| 143 | + break; | |
| 144 | + } | |
| 145 | + udelay(1); | |
| 146 | + } | |
| 147 | +} | |
| 148 | + | |
| 149 | +static void omap_8250_get_divisor(struct uart_port *port, unsigned int baud, | |
| 150 | + struct omap8250_priv *priv) | |
| 151 | +{ | |
| 152 | + unsigned int uartclk = port->uartclk; | |
| 153 | + unsigned int div_13, div_16; | |
| 154 | + unsigned int abs_d13, abs_d16; | |
| 155 | + | |
| 156 | + /* | |
| 157 | + * Old custom speed handling. | |
| 158 | + */ | |
| 159 | + if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST) { | |
| 160 | + priv->quot = port->custom_divisor & 0xffff; | |
| 161 | + /* | |
| 162 | + * I assume that nobody is using this. But hey, if somebody | |
| 163 | + * would like to specify the divisor _and_ the mode then the | |
| 164 | + * driver is ready and waiting for it. | |
| 165 | + */ | |
| 166 | + if (port->custom_divisor & (1 << 16)) | |
| 167 | + priv->mdr1 = UART_OMAP_MDR1_13X_MODE; | |
| 168 | + else | |
| 169 | + priv->mdr1 = UART_OMAP_MDR1_16X_MODE; | |
| 170 | + return; | |
| 171 | + } | |
| 172 | + div_13 = DIV_ROUND_CLOSEST(uartclk, 13 * baud); | |
| 173 | + div_16 = DIV_ROUND_CLOSEST(uartclk, 16 * baud); | |
| 174 | + | |
| 175 | + if (!div_13) | |
| 176 | + div_13 = 1; | |
| 177 | + if (!div_16) | |
| 178 | + div_16 = 1; | |
| 179 | + | |
| 180 | + abs_d13 = abs(baud - uartclk / 13 / div_13); | |
| 181 | + abs_d16 = abs(baud - uartclk / 16 / div_16); | |
| 182 | + | |
| 183 | + if (abs_d13 >= abs_d16) { | |
| 184 | + priv->mdr1 = UART_OMAP_MDR1_16X_MODE; | |
| 185 | + priv->quot = div_16; | |
| 186 | + } else { | |
| 187 | + priv->mdr1 = UART_OMAP_MDR1_13X_MODE; | |
| 188 | + priv->quot = div_13; | |
| 189 | + } | |
| 190 | +} | |
| 191 | + | |
| 192 | +static void omap8250_update_scr(struct uart_8250_port *up, | |
| 193 | + struct omap8250_priv *priv) | |
| 194 | +{ | |
| 195 | + u8 old_scr; | |
| 196 | + | |
| 197 | + old_scr = serial_in(up, UART_OMAP_SCR); | |
| 198 | + if (old_scr == priv->scr) | |
| 199 | + return; | |
| 200 | + | |
| 201 | + /* | |
| 202 | + * The manual recommends not to enable the DMA mode selector in the SCR | |
| 203 | + * (instead of the FCR) register _and_ selecting the DMA mode as one | |
| 204 | + * register write because this may lead to malfunction. | |
| 205 | + */ | |
| 206 | + if (priv->scr & OMAP_UART_SCR_DMAMODE_MASK) | |
| 207 | + serial_out(up, UART_OMAP_SCR, | |
| 208 | + priv->scr & ~OMAP_UART_SCR_DMAMODE_MASK); | |
| 209 | + serial_out(up, UART_OMAP_SCR, priv->scr); | |
| 210 | +} | |
| 211 | + | |
| 212 | +static void omap8250_restore_regs(struct uart_8250_port *up) | |
| 213 | +{ | |
| 214 | + struct omap8250_priv *priv = up->port.private_data; | |
| 215 | + struct uart_8250_dma *dma = up->dma; | |
| 216 | + | |
| 217 | + if (dma && dma->tx_running) { | |
| 218 | + /* | |
| 219 | + * TCSANOW requests the change to occur immediately however if | |
| 220 | + * we have a TX-DMA operation in progress then it has been | |
| 221 | + * observed that it might stall and never complete. Therefore we | |
| 222 | + * delay DMA completes to prevent this hang from happen. | |
| 223 | + */ | |
| 224 | + priv->delayed_restore = 1; | |
| 225 | + return; | |
| 226 | + } | |
| 227 | + | |
| 228 | + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | |
| 229 | + serial_out(up, UART_EFR, UART_EFR_ECB); | |
| 230 | + | |
| 231 | + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); | |
| 232 | + serial_out(up, UART_MCR, UART_MCR_TCRTLR); | |
| 233 | + serial_out(up, UART_FCR, up->fcr); | |
| 234 | + | |
| 235 | + omap8250_update_scr(up, priv); | |
| 236 | + | |
| 237 | + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | |
| 238 | + | |
| 239 | + serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_RESTORE(16) | | |
| 240 | + OMAP_UART_TCR_HALT(52)); | |
| 241 | + serial_out(up, UART_TI752_TLR, | |
| 242 | + TRIGGER_TLR_MASK(TX_TRIGGER) << UART_TI752_TLR_TX | | |
| 243 | + TRIGGER_TLR_MASK(RX_TRIGGER) << UART_TI752_TLR_RX); | |
| 244 | + | |
| 245 | + serial_out(up, UART_LCR, 0); | |
| 246 | + | |
| 247 | + /* drop TCR + TLR access, we setup XON/XOFF later */ | |
| 248 | + serial_out(up, UART_MCR, up->mcr); | |
| 249 | + serial_out(up, UART_IER, up->ier); | |
| 250 | + | |
| 251 | + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | |
| 252 | + serial_dl_write(up, priv->quot); | |
| 253 | + | |
| 254 | + serial_out(up, UART_EFR, priv->efr); | |
| 255 | + | |
| 256 | + /* Configure flow control */ | |
| 257 | + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | |
| 258 | + serial_out(up, UART_XON1, priv->xon); | |
| 259 | + serial_out(up, UART_XOFF1, priv->xoff); | |
| 260 | + | |
| 261 | + serial_out(up, UART_LCR, up->lcr); | |
| 262 | + /* need mode A for FCR */ | |
| 263 | + if (priv->habit & UART_ERRATA_i202_MDR1_ACCESS) | |
| 264 | + omap_8250_mdr1_errataset(up, priv); | |
| 265 | + else | |
| 266 | + serial_out(up, UART_OMAP_MDR1, priv->mdr1); | |
| 267 | + up->port.ops->set_mctrl(&up->port, up->port.mctrl); | |
| 268 | +} | |
| 269 | + | |
| 270 | +/* | |
| 271 | + * OMAP can use "CLK / (16 or 13) / div" for baud rate. And then we have have | |
| 272 | + * some differences in how we want to handle flow control. | |
| 273 | + */ | |
| 274 | +static void omap_8250_set_termios(struct uart_port *port, | |
| 275 | + struct ktermios *termios, | |
| 276 | + struct ktermios *old) | |
| 277 | +{ | |
| 278 | + struct uart_8250_port *up = | |
| 279 | + container_of(port, struct uart_8250_port, port); | |
| 280 | + struct omap8250_priv *priv = up->port.private_data; | |
| 281 | + unsigned char cval = 0; | |
| 282 | + unsigned int baud; | |
| 283 | + | |
| 284 | + switch (termios->c_cflag & CSIZE) { | |
| 285 | + case CS5: | |
| 286 | + cval = UART_LCR_WLEN5; | |
| 287 | + break; | |
| 288 | + case CS6: | |
| 289 | + cval = UART_LCR_WLEN6; | |
| 290 | + break; | |
| 291 | + case CS7: | |
| 292 | + cval = UART_LCR_WLEN7; | |
| 293 | + break; | |
| 294 | + default: | |
| 295 | + case CS8: | |
| 296 | + cval = UART_LCR_WLEN8; | |
| 297 | + break; | |
| 298 | + } | |
| 299 | + | |
| 300 | + if (termios->c_cflag & CSTOPB) | |
| 301 | + cval |= UART_LCR_STOP; | |
| 302 | + if (termios->c_cflag & PARENB) | |
| 303 | + cval |= UART_LCR_PARITY; | |
| 304 | + if (!(termios->c_cflag & PARODD)) | |
| 305 | + cval |= UART_LCR_EPAR; | |
| 306 | + if (termios->c_cflag & CMSPAR) | |
| 307 | + cval |= UART_LCR_SPAR; | |
| 308 | + | |
| 309 | + /* | |
| 310 | + * Ask the core to calculate the divisor for us. | |
| 311 | + */ | |
| 312 | + baud = uart_get_baud_rate(port, termios, old, | |
| 313 | + port->uartclk / 16 / 0xffff, | |
| 314 | + port->uartclk / 13); | |
| 315 | + omap_8250_get_divisor(port, baud, priv); | |
| 316 | + | |
| 317 | + /* | |
| 318 | + * Ok, we're now changing the port state. Do it with | |
| 319 | + * interrupts disabled. | |
| 320 | + */ | |
| 321 | + pm_runtime_get_sync(port->dev); | |
| 322 | + spin_lock_irq(&port->lock); | |
| 323 | + | |
| 324 | + /* | |
| 325 | + * Update the per-port timeout. | |
| 326 | + */ | |
| 327 | + uart_update_timeout(port, termios->c_cflag, baud); | |
| 328 | + | |
| 329 | + up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; | |
| 330 | + if (termios->c_iflag & INPCK) | |
| 331 | + up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE; | |
| 332 | + if (termios->c_iflag & (IGNBRK | PARMRK)) | |
| 333 | + up->port.read_status_mask |= UART_LSR_BI; | |
| 334 | + | |
| 335 | + /* | |
| 336 | + * Characters to ignore | |
| 337 | + */ | |
| 338 | + up->port.ignore_status_mask = 0; | |
| 339 | + if (termios->c_iflag & IGNPAR) | |
| 340 | + up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; | |
| 341 | + if (termios->c_iflag & IGNBRK) { | |
| 342 | + up->port.ignore_status_mask |= UART_LSR_BI; | |
| 343 | + /* | |
| 344 | + * If we're ignoring parity and break indicators, | |
| 345 | + * ignore overruns too (for real raw support). | |
| 346 | + */ | |
| 347 | + if (termios->c_iflag & IGNPAR) | |
| 348 | + up->port.ignore_status_mask |= UART_LSR_OE; | |
| 349 | + } | |
| 350 | + | |
| 351 | + /* | |
| 352 | + * ignore all characters if CREAD is not set | |
| 353 | + */ | |
| 354 | + if ((termios->c_cflag & CREAD) == 0) | |
| 355 | + up->port.ignore_status_mask |= UART_LSR_DR; | |
| 356 | + | |
| 357 | + /* | |
| 358 | + * Modem status interrupts | |
| 359 | + */ | |
| 360 | + up->ier &= ~UART_IER_MSI; | |
| 361 | + if (UART_ENABLE_MS(&up->port, termios->c_cflag)) | |
| 362 | + up->ier |= UART_IER_MSI; | |
| 363 | + | |
| 364 | + up->lcr = cval; | |
| 365 | + /* Up to here it was mostly serial8250_do_set_termios() */ | |
| 366 | + | |
| 367 | + /* | |
| 368 | + * We enable TRIG_GRANU for RX and TX and additionaly we set | |
| 369 | + * SCR_TX_EMPTY bit. The result is the following: | |
| 370 | + * - RX_TRIGGER amount of bytes in the FIFO will cause an interrupt. | |
| 371 | + * - less than RX_TRIGGER number of bytes will also cause an interrupt | |
| 372 | + * once the UART decides that there no new bytes arriving. | |
| 373 | + * - Once THRE is enabled, the interrupt will be fired once the FIFO is | |
| 374 | + * empty - the trigger level is ignored here. | |
| 375 | + * | |
| 376 | + * Once DMA is enabled: | |
| 377 | + * - UART will assert the TX DMA line once there is room for TX_TRIGGER | |
| 378 | + * bytes in the TX FIFO. On each assert the DMA engine will move | |
| 379 | + * TX_TRIGGER bytes into the FIFO. | |
| 380 | + * - UART will assert the RX DMA line once there are RX_TRIGGER bytes in | |
| 381 | + * the FIFO and move RX_TRIGGER bytes. | |
| 382 | + * This is because threshold and trigger values are the same. | |
| 383 | + */ | |
| 384 | + up->fcr = UART_FCR_ENABLE_FIFO; | |
| 385 | + up->fcr |= TRIGGER_FCR_MASK(TX_TRIGGER) << OMAP_UART_FCR_TX_TRIG; | |
| 386 | + up->fcr |= TRIGGER_FCR_MASK(RX_TRIGGER) << OMAP_UART_FCR_RX_TRIG; | |
| 387 | + | |
| 388 | + priv->scr = OMAP_UART_SCR_RX_TRIG_GRANU1_MASK | OMAP_UART_SCR_TX_EMPTY | | |
| 389 | + OMAP_UART_SCR_TX_TRIG_GRANU1_MASK; | |
| 390 | + | |
| 391 | + if (up->dma) | |
| 392 | + priv->scr |= OMAP_UART_SCR_DMAMODE_1 | | |
| 393 | + OMAP_UART_SCR_DMAMODE_CTL; | |
| 394 | + | |
| 395 | + priv->xon = termios->c_cc[VSTART]; | |
| 396 | + priv->xoff = termios->c_cc[VSTOP]; | |
| 397 | + | |
| 398 | + priv->efr = 0; | |
| 399 | + up->mcr &= ~(UART_MCR_RTS | UART_MCR_XONANY); | |
| 400 | + if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW) { | |
| 401 | + /* Enable AUTORTS and AUTOCTS */ | |
| 402 | + priv->efr |= UART_EFR_CTS | UART_EFR_RTS; | |
| 403 | + | |
| 404 | + /* Ensure MCR RTS is asserted */ | |
| 405 | + up->mcr |= UART_MCR_RTS; | |
| 406 | + } else if (up->port.flags & UPF_SOFT_FLOW) { | |
| 407 | + /* | |
| 408 | + * IXON Flag: | |
| 409 | + * Enable XON/XOFF flow control on input. | |
| 410 | + * Receiver compares XON1, XOFF1. | |
| 411 | + */ | |
| 412 | + if (termios->c_iflag & IXON) | |
| 413 | + priv->efr |= OMAP_UART_SW_RX; | |
| 414 | + | |
| 415 | + /* | |
| 416 | + * IXOFF Flag: | |
| 417 | + * Enable XON/XOFF flow control on output. | |
| 418 | + * Transmit XON1, XOFF1 | |
| 419 | + */ | |
| 420 | + if (termios->c_iflag & IXOFF) | |
| 421 | + priv->efr |= OMAP_UART_SW_TX; | |
| 422 | + | |
| 423 | + /* | |
| 424 | + * IXANY Flag: | |
| 425 | + * Enable any character to restart output. | |
| 426 | + * Operation resumes after receiving any | |
| 427 | + * character after recognition of the XOFF character | |
| 428 | + */ | |
| 429 | + if (termios->c_iflag & IXANY) | |
| 430 | + up->mcr |= UART_MCR_XONANY; | |
| 431 | + } | |
| 432 | + omap8250_restore_regs(up); | |
| 433 | + | |
| 434 | + spin_unlock_irq(&up->port.lock); | |
| 435 | + pm_runtime_mark_last_busy(port->dev); | |
| 436 | + pm_runtime_put_autosuspend(port->dev); | |
| 437 | + | |
| 438 | + /* calculate wakeup latency constraint */ | |
| 439 | + priv->calc_latency = USEC_PER_SEC * 64 * 8 / baud; | |
| 440 | + priv->latency = priv->calc_latency; | |
| 441 | + | |
| 442 | + schedule_work(&priv->qos_work); | |
| 443 | + | |
| 444 | + /* Don't rewrite B0 */ | |
| 445 | + if (tty_termios_baud_rate(termios)) | |
| 446 | + tty_termios_encode_baud_rate(termios, baud, baud); | |
| 447 | +} | |
| 448 | + | |
| 449 | +/* same as 8250 except that we may have extra flow bits set in EFR */ | |
| 450 | +static void omap_8250_pm(struct uart_port *port, unsigned int state, | |
| 451 | + unsigned int oldstate) | |
| 452 | +{ | |
| 453 | + struct uart_8250_port *up = | |
| 454 | + container_of(port, struct uart_8250_port, port); | |
| 455 | + struct omap8250_priv *priv = up->port.private_data; | |
| 456 | + | |
| 457 | + pm_runtime_get_sync(port->dev); | |
| 458 | + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | |
| 459 | + serial_out(up, UART_EFR, priv->efr | UART_EFR_ECB); | |
| 460 | + serial_out(up, UART_LCR, 0); | |
| 461 | + | |
| 462 | + serial_out(up, UART_IER, (state != 0) ? UART_IERX_SLEEP : 0); | |
| 463 | + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | |
| 464 | + serial_out(up, UART_EFR, priv->efr); | |
| 465 | + serial_out(up, UART_LCR, 0); | |
| 466 | + | |
| 467 | + pm_runtime_mark_last_busy(port->dev); | |
| 468 | + pm_runtime_put_autosuspend(port->dev); | |
| 469 | +} | |
| 470 | + | |
| 471 | +static void omap_serial_fill_features_erratas(struct uart_8250_port *up, | |
| 472 | + struct omap8250_priv *priv) | |
| 473 | +{ | |
| 474 | + u32 mvr, scheme; | |
| 475 | + u16 revision, major, minor; | |
| 476 | + | |
| 477 | + mvr = uart_read(up, UART_OMAP_MVER); | |
| 478 | + | |
| 479 | + /* Check revision register scheme */ | |
| 480 | + scheme = mvr >> OMAP_UART_MVR_SCHEME_SHIFT; | |
| 481 | + | |
| 482 | + switch (scheme) { | |
| 483 | + case 0: /* Legacy Scheme: OMAP2/3 */ | |
| 484 | + /* MINOR_REV[0:4], MAJOR_REV[4:7] */ | |
| 485 | + major = (mvr & OMAP_UART_LEGACY_MVR_MAJ_MASK) >> | |
| 486 | + OMAP_UART_LEGACY_MVR_MAJ_SHIFT; | |
| 487 | + minor = (mvr & OMAP_UART_LEGACY_MVR_MIN_MASK); | |
| 488 | + break; | |
| 489 | + case 1: | |
| 490 | + /* New Scheme: OMAP4+ */ | |
| 491 | + /* MINOR_REV[0:5], MAJOR_REV[8:10] */ | |
| 492 | + major = (mvr & OMAP_UART_MVR_MAJ_MASK) >> | |
| 493 | + OMAP_UART_MVR_MAJ_SHIFT; | |
| 494 | + minor = (mvr & OMAP_UART_MVR_MIN_MASK); | |
| 495 | + break; | |
| 496 | + default: | |
| 497 | + dev_warn(up->port.dev, | |
| 498 | + "Unknown revision, defaulting to highest\n"); | |
| 499 | + /* highest possible revision */ | |
| 500 | + major = 0xff; | |
| 501 | + minor = 0xff; | |
| 502 | + } | |
| 503 | + /* normalize revision for the driver */ | |
| 504 | + revision = UART_BUILD_REVISION(major, minor); | |
| 505 | + | |
| 506 | + switch (revision) { | |
| 507 | + case OMAP_UART_REV_46: | |
| 508 | + priv->habit = UART_ERRATA_i202_MDR1_ACCESS; | |
| 509 | + break; | |
| 510 | + case OMAP_UART_REV_52: | |
| 511 | + priv->habit = UART_ERRATA_i202_MDR1_ACCESS | | |
| 512 | + OMAP_UART_WER_HAS_TX_WAKEUP; | |
| 513 | + break; | |
| 514 | + case OMAP_UART_REV_63: | |
| 515 | + priv->habit = UART_ERRATA_i202_MDR1_ACCESS | | |
| 516 | + OMAP_UART_WER_HAS_TX_WAKEUP; | |
| 517 | + break; | |
| 518 | + default: | |
| 519 | + break; | |
| 520 | + } | |
| 521 | +} | |
| 522 | + | |
| 523 | +static void omap8250_uart_qos_work(struct work_struct *work) | |
| 524 | +{ | |
| 525 | + struct omap8250_priv *priv; | |
| 526 | + | |
| 527 | + priv = container_of(work, struct omap8250_priv, qos_work); | |
| 528 | + pm_qos_update_request(&priv->pm_qos_request, priv->latency); | |
| 529 | +} | |
| 530 | + | |
| 531 | +static irqreturn_t omap_wake_irq(int irq, void *dev_id) | |
| 532 | +{ | |
| 533 | + struct uart_port *port = dev_id; | |
| 534 | + int ret; | |
| 535 | + | |
| 536 | + ret = port->handle_irq(port); | |
| 537 | + if (ret) | |
| 538 | + return IRQ_HANDLED; | |
| 539 | + return IRQ_NONE; | |
| 540 | +} | |
| 541 | + | |
| 542 | +static int omap_8250_startup(struct uart_port *port) | |
| 543 | +{ | |
| 544 | + struct uart_8250_port *up = | |
| 545 | + container_of(port, struct uart_8250_port, port); | |
| 546 | + struct omap8250_priv *priv = port->private_data; | |
| 547 | + | |
| 548 | + int ret; | |
| 549 | + | |
| 550 | + if (priv->wakeirq) { | |
| 551 | + ret = request_irq(priv->wakeirq, omap_wake_irq, | |
| 552 | + port->irqflags, "uart wakeup irq", port); | |
| 553 | + if (ret) | |
| 554 | + return ret; | |
| 555 | + disable_irq(priv->wakeirq); | |
| 556 | + } | |
| 557 | + | |
| 558 | + pm_runtime_get_sync(port->dev); | |
| 559 | + | |
| 560 | + ret = serial8250_do_startup(port); | |
| 561 | + if (ret) | |
| 562 | + goto err; | |
| 563 | + | |
| 564 | +#ifdef CONFIG_PM_RUNTIME | |
| 565 | + up->capabilities |= UART_CAP_RPM; | |
| 566 | +#endif | |
| 567 | + | |
| 568 | + /* Enable module level wake up */ | |
| 569 | + priv->wer = OMAP_UART_WER_MOD_WKUP; | |
| 570 | + if (priv->habit & OMAP_UART_WER_HAS_TX_WAKEUP) | |
| 571 | + priv->wer |= OMAP_UART_TX_WAKEUP_EN; | |
| 572 | + serial_out(up, UART_OMAP_WER, priv->wer); | |
| 573 | + | |
| 574 | + if (up->dma) | |
| 575 | + up->dma->rx_dma(up, 0); | |
| 576 | + | |
| 577 | + pm_runtime_mark_last_busy(port->dev); | |
| 578 | + pm_runtime_put_autosuspend(port->dev); | |
| 579 | + return 0; | |
| 580 | +err: | |
| 581 | + pm_runtime_mark_last_busy(port->dev); | |
| 582 | + pm_runtime_put_autosuspend(port->dev); | |
| 583 | + if (priv->wakeirq) | |
| 584 | + free_irq(priv->wakeirq, port); | |
| 585 | + return ret; | |
| 586 | +} | |
| 587 | + | |
| 588 | +static void omap_8250_shutdown(struct uart_port *port) | |
| 589 | +{ | |
| 590 | + struct uart_8250_port *up = | |
| 591 | + container_of(port, struct uart_8250_port, port); | |
| 592 | + struct omap8250_priv *priv = port->private_data; | |
| 593 | + | |
| 594 | + flush_work(&priv->qos_work); | |
| 595 | + if (up->dma) | |
| 596 | + up->dma->rx_dma(up, UART_IIR_RX_TIMEOUT); | |
| 597 | + | |
| 598 | + pm_runtime_get_sync(port->dev); | |
| 599 | + | |
| 600 | + serial_out(up, UART_OMAP_WER, 0); | |
| 601 | + serial8250_do_shutdown(port); | |
| 602 | + | |
| 603 | + pm_runtime_mark_last_busy(port->dev); | |
| 604 | + pm_runtime_put_autosuspend(port->dev); | |
| 605 | + | |
| 606 | + if (priv->wakeirq) | |
| 607 | + free_irq(priv->wakeirq, port); | |
| 608 | +} | |
| 609 | + | |
| 610 | +static void omap_8250_throttle(struct uart_port *port) | |
| 611 | +{ | |
| 612 | + unsigned long flags; | |
| 613 | + struct uart_8250_port *up = | |
| 614 | + container_of(port, struct uart_8250_port, port); | |
| 615 | + | |
| 616 | + pm_runtime_get_sync(port->dev); | |
| 617 | + | |
| 618 | + spin_lock_irqsave(&port->lock, flags); | |
| 619 | + up->ier &= ~(UART_IER_RLSI | UART_IER_RDI); | |
| 620 | + serial_out(up, UART_IER, up->ier); | |
| 621 | + spin_unlock_irqrestore(&port->lock, flags); | |
| 622 | + | |
| 623 | + pm_runtime_mark_last_busy(port->dev); | |
| 624 | + pm_runtime_put_autosuspend(port->dev); | |
| 625 | +} | |
| 626 | + | |
| 627 | +static void omap_8250_unthrottle(struct uart_port *port) | |
| 628 | +{ | |
| 629 | + unsigned long flags; | |
| 630 | + struct uart_8250_port *up = | |
| 631 | + container_of(port, struct uart_8250_port, port); | |
| 632 | + | |
| 633 | + pm_runtime_get_sync(port->dev); | |
| 634 | + | |
| 635 | + spin_lock_irqsave(&port->lock, flags); | |
| 636 | + up->ier |= UART_IER_RLSI | UART_IER_RDI; | |
| 637 | + serial_out(up, UART_IER, up->ier); | |
| 638 | + spin_unlock_irqrestore(&port->lock, flags); | |
| 639 | + | |
| 640 | + pm_runtime_mark_last_busy(port->dev); | |
| 641 | + pm_runtime_put_autosuspend(port->dev); | |
| 642 | +} | |
| 643 | + | |
| 644 | +#ifdef CONFIG_SERIAL_8250_DMA | |
| 645 | +static int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir); | |
| 646 | + | |
| 647 | +static void __dma_rx_do_complete(struct uart_8250_port *p, bool error) | |
| 648 | +{ | |
| 649 | + struct uart_8250_dma *dma = p->dma; | |
| 650 | + struct tty_port *tty_port = &p->port.state->port; | |
| 651 | + struct dma_tx_state state; | |
| 652 | + int count; | |
| 653 | + | |
| 654 | + dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr, | |
| 655 | + dma->rx_size, DMA_FROM_DEVICE); | |
| 656 | + | |
| 657 | + dma->rx_running = 0; | |
| 658 | + dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); | |
| 659 | + dmaengine_terminate_all(dma->rxchan); | |
| 660 | + | |
| 661 | + count = dma->rx_size - state.residue; | |
| 662 | + | |
| 663 | + tty_insert_flip_string(tty_port, dma->rx_buf, count); | |
| 664 | + p->port.icount.rx += count; | |
| 665 | + if (!error) | |
| 666 | + omap_8250_rx_dma(p, 0); | |
| 667 | + | |
| 668 | + tty_flip_buffer_push(tty_port); | |
| 669 | +} | |
| 670 | + | |
| 671 | +static void __dma_rx_complete(void *param) | |
| 672 | +{ | |
| 673 | + __dma_rx_do_complete(param, false); | |
| 674 | +} | |
| 675 | + | |
| 676 | +static int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir) | |
| 677 | +{ | |
| 678 | + struct uart_8250_dma *dma = p->dma; | |
| 679 | + struct dma_async_tx_descriptor *desc; | |
| 680 | + | |
| 681 | + switch (iir & 0x3f) { | |
| 682 | + case UART_IIR_RLSI: | |
| 683 | + /* 8250_core handles errors and break interrupts */ | |
| 684 | + if (dma->rx_running) { | |
| 685 | + dmaengine_pause(dma->rxchan); | |
| 686 | + __dma_rx_do_complete(p, true); | |
| 687 | + } | |
| 688 | + return -EIO; | |
| 689 | + case UART_IIR_RX_TIMEOUT: | |
| 690 | + /* | |
| 691 | + * If RCVR FIFO trigger level was not reached, complete the | |
| 692 | + * transfer and let 8250_core copy the remaining data. | |
| 693 | + */ | |
| 694 | + if (dma->rx_running) { | |
| 695 | + dmaengine_pause(dma->rxchan); | |
| 696 | + __dma_rx_do_complete(p, true); | |
| 697 | + } | |
| 698 | + return -ETIMEDOUT; | |
| 699 | + case UART_IIR_RDI: | |
| 700 | + /* | |
| 701 | + * The OMAP UART is a special BEAST. If we receive RDI we _have_ | |
| 702 | + * a DMA transfer programmed but it didn't work. One reason is | |
| 703 | + * that we were too slow and there were too many bytes in the | |
| 704 | + * FIFO, the UART counted wrong and never kicked the DMA engine | |
| 705 | + * to do anything. That means once we receive RDI on OMAP then | |
| 706 | + * the DMA won't do anything soon so we have to cancel the DMA | |
| 707 | + * transfer and purge the FIFO manually. | |
| 708 | + */ | |
| 709 | + if (dma->rx_running) { | |
| 710 | + dmaengine_pause(dma->rxchan); | |
| 711 | + __dma_rx_do_complete(p, true); | |
| 712 | + } | |
| 713 | + return -ETIMEDOUT; | |
| 714 | + | |
| 715 | + default: | |
| 716 | + break; | |
| 717 | + } | |
| 718 | + | |
| 719 | + if (dma->rx_running) | |
| 720 | + return 0; | |
| 721 | + | |
| 722 | + desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr, | |
| 723 | + dma->rx_size, DMA_DEV_TO_MEM, | |
| 724 | + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | |
| 725 | + if (!desc) | |
| 726 | + return -EBUSY; | |
| 727 | + | |
| 728 | + dma->rx_running = 1; | |
| 729 | + desc->callback = __dma_rx_complete; | |
| 730 | + desc->callback_param = p; | |
| 731 | + | |
| 732 | + dma->rx_cookie = dmaengine_submit(desc); | |
| 733 | + | |
| 734 | + dma_sync_single_for_device(dma->rxchan->device->dev, dma->rx_addr, | |
| 735 | + dma->rx_size, DMA_FROM_DEVICE); | |
| 736 | + | |
| 737 | + dma_async_issue_pending(dma->rxchan); | |
| 738 | + return 0; | |
| 739 | +} | |
| 740 | + | |
| 741 | +static int omap_8250_tx_dma(struct uart_8250_port *p); | |
| 742 | + | |
| 743 | +static void omap_8250_dma_tx_complete(void *param) | |
| 744 | +{ | |
| 745 | + struct uart_8250_port *p = param; | |
| 746 | + struct uart_8250_dma *dma = p->dma; | |
| 747 | + struct circ_buf *xmit = &p->port.state->xmit; | |
| 748 | + unsigned long flags; | |
| 749 | + bool en_thri = false; | |
| 750 | + struct omap8250_priv *priv = p->port.private_data; | |
| 751 | + | |
| 752 | + dma_sync_single_for_cpu(dma->txchan->device->dev, dma->tx_addr, | |
| 753 | + UART_XMIT_SIZE, DMA_TO_DEVICE); | |
| 754 | + | |
| 755 | + spin_lock_irqsave(&p->port.lock, flags); | |
| 756 | + | |
| 757 | + dma->tx_running = 0; | |
| 758 | + | |
| 759 | + xmit->tail += dma->tx_size; | |
| 760 | + xmit->tail &= UART_XMIT_SIZE - 1; | |
| 761 | + p->port.icount.tx += dma->tx_size; | |
| 762 | + | |
| 763 | + if (priv->delayed_restore) { | |
| 764 | + priv->delayed_restore = 0; | |
| 765 | + omap8250_restore_regs(p); | |
| 766 | + } | |
| 767 | + | |
| 768 | + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | |
| 769 | + uart_write_wakeup(&p->port); | |
| 770 | + | |
| 771 | + if (!uart_circ_empty(xmit) && !uart_tx_stopped(&p->port)) { | |
| 772 | + int ret; | |
| 773 | + | |
| 774 | + ret = omap_8250_tx_dma(p); | |
| 775 | + if (ret) | |
| 776 | + en_thri = true; | |
| 777 | + | |
| 778 | + } else if (p->capabilities & UART_CAP_RPM) { | |
| 779 | + en_thri = true; | |
| 780 | + } | |
| 781 | + | |
| 782 | + if (en_thri) { | |
| 783 | + dma->tx_err = 1; | |
| 784 | + p->ier |= UART_IER_THRI; | |
| 785 | + serial_port_out(&p->port, UART_IER, p->ier); | |
| 786 | + } | |
| 787 | + | |
| 788 | + spin_unlock_irqrestore(&p->port.lock, flags); | |
| 789 | +} | |
| 790 | + | |
| 791 | +static int omap_8250_tx_dma(struct uart_8250_port *p) | |
| 792 | +{ | |
| 793 | + struct uart_8250_dma *dma = p->dma; | |
| 794 | + struct omap8250_priv *priv = p->port.private_data; | |
| 795 | + struct circ_buf *xmit = &p->port.state->xmit; | |
| 796 | + struct dma_async_tx_descriptor *desc; | |
| 797 | + unsigned int skip_byte = 0; | |
| 798 | + int ret; | |
| 799 | + | |
| 800 | + if (dma->tx_running) | |
| 801 | + return 0; | |
| 802 | + if (uart_tx_stopped(&p->port) || uart_circ_empty(xmit)) { | |
| 803 | + | |
| 804 | + /* | |
| 805 | + * Even if no data, we need to return an error for the two cases | |
| 806 | + * below so serial8250_tx_chars() is invoked and properly clears | |
| 807 | + * THRI and/or runtime suspend. | |
| 808 | + */ | |
| 809 | + if (dma->tx_err || p->capabilities & UART_CAP_RPM) { | |
| 810 | + ret = -EBUSY; | |
| 811 | + goto err; | |
| 812 | + } | |
| 813 | + if (p->ier & UART_IER_THRI) { | |
| 814 | + p->ier &= ~UART_IER_THRI; | |
| 815 | + serial_out(p, UART_IER, p->ier); | |
| 816 | + } | |
| 817 | + return 0; | |
| 818 | + } | |
| 819 | + | |
| 820 | + dma->tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); | |
| 821 | + if (priv->habit & OMAP_DMA_TX_KICK) { | |
| 822 | + u8 tx_lvl; | |
| 823 | + | |
| 824 | + /* | |
| 825 | + * We need to put the first byte into the FIFO in order to start | |
| 826 | + * the DMA transfer. For transfers smaller than four bytes we | |
| 827 | + * don't bother doing DMA at all. It seem not matter if there | |
| 828 | + * are still bytes in the FIFO from the last transfer (in case | |
| 829 | + * we got here directly from omap_8250_dma_tx_complete()). Bytes | |
| 830 | + * leaving the FIFO seem not to trigger the DMA transfer. It is | |
| 831 | + * really the byte that we put into the FIFO. | |
| 832 | + * If the FIFO is already full then we most likely got here from | |
| 833 | + * omap_8250_dma_tx_complete(). And this means the DMA engine | |
| 834 | + * just completed its work. We don't have to wait the complete | |
| 835 | + * 86us at 115200,8n1 but around 60us (not to mention lower | |
| 836 | + * baudrates). So in that case we take the interrupt and try | |
| 837 | + * again with an empty FIFO. | |
| 838 | + */ | |
| 839 | + tx_lvl = serial_in(p, UART_OMAP_TX_LVL); | |
| 840 | + if (tx_lvl == p->tx_loadsz) { | |
| 841 | + ret = -EBUSY; | |
| 842 | + goto err; | |
| 843 | + } | |
| 844 | + if (dma->tx_size < 4) { | |
| 845 | + ret = -EINVAL; | |
| 846 | + goto err; | |
| 847 | + } | |
| 848 | + skip_byte = 1; | |
| 849 | + } | |
| 850 | + | |
| 851 | + desc = dmaengine_prep_slave_single(dma->txchan, | |
| 852 | + dma->tx_addr + xmit->tail + skip_byte, | |
| 853 | + dma->tx_size - skip_byte, DMA_MEM_TO_DEV, | |
| 854 | + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | |
| 855 | + if (!desc) { | |
| 856 | + ret = -EBUSY; | |
| 857 | + goto err; | |
| 858 | + } | |
| 859 | + | |
| 860 | + dma->tx_running = 1; | |
| 861 | + | |
| 862 | + desc->callback = omap_8250_dma_tx_complete; | |
| 863 | + desc->callback_param = p; | |
| 864 | + | |
| 865 | + dma->tx_cookie = dmaengine_submit(desc); | |
| 866 | + | |
| 867 | + dma_sync_single_for_device(dma->txchan->device->dev, dma->tx_addr, | |
| 868 | + UART_XMIT_SIZE, DMA_TO_DEVICE); | |
| 869 | + | |
| 870 | + dma_async_issue_pending(dma->txchan); | |
| 871 | + if (dma->tx_err) | |
| 872 | + dma->tx_err = 0; | |
| 873 | + | |
| 874 | + if (p->ier & UART_IER_THRI) { | |
| 875 | + p->ier &= ~UART_IER_THRI; | |
| 876 | + serial_out(p, UART_IER, p->ier); | |
| 877 | + } | |
| 878 | + if (skip_byte) | |
| 879 | + serial_out(p, UART_TX, xmit->buf[xmit->tail]); | |
| 880 | + return 0; | |
| 881 | +err: | |
| 882 | + dma->tx_err = 1; | |
| 883 | + return ret; | |
| 884 | +} | |
| 885 | + | |
| 886 | +/* | |
| 887 | + * This is mostly serial8250_handle_irq(). We have a slightly different DMA | |
| 888 | + * hoook for RX/TX and need different logic for them in the ISR. Therefore we | |
| 889 | + * use the default routine in the non-DMA case and this one for with DMA. | |
| 890 | + */ | |
| 891 | +static int omap_8250_dma_handle_irq(struct uart_port *port) | |
| 892 | +{ | |
| 893 | + struct uart_8250_port *up = up_to_u8250p(port); | |
| 894 | + unsigned char status; | |
| 895 | + unsigned long flags; | |
| 896 | + u8 iir; | |
| 897 | + int dma_err = 0; | |
| 898 | + | |
| 899 | + serial8250_rpm_get(up); | |
| 900 | + | |
| 901 | + iir = serial_port_in(port, UART_IIR); | |
| 902 | + if (iir & UART_IIR_NO_INT) { | |
| 903 | + serial8250_rpm_put(up); | |
| 904 | + return 0; | |
| 905 | + } | |
| 906 | + | |
| 907 | + spin_lock_irqsave(&port->lock, flags); | |
| 908 | + | |
| 909 | + status = serial_port_in(port, UART_LSR); | |
| 910 | + | |
| 911 | + if (status & (UART_LSR_DR | UART_LSR_BI)) { | |
| 912 | + | |
| 913 | + dma_err = omap_8250_rx_dma(up, iir); | |
| 914 | + if (dma_err) { | |
| 915 | + status = serial8250_rx_chars(up, status); | |
| 916 | + omap_8250_rx_dma(up, 0); | |
| 917 | + } | |
| 918 | + } | |
| 919 | + serial8250_modem_status(up); | |
| 920 | + if (status & UART_LSR_THRE && up->dma->tx_err) { | |
| 921 | + if (uart_tx_stopped(&up->port) || | |
| 922 | + uart_circ_empty(&up->port.state->xmit)) { | |
| 923 | + up->dma->tx_err = 0; | |
| 924 | + serial8250_tx_chars(up); | |
| 925 | + } else { | |
| 926 | + /* | |
| 927 | + * try again due to an earlier failer which | |
| 928 | + * might have been resolved by now. | |
| 929 | + */ | |
| 930 | + dma_err = omap_8250_tx_dma(up); | |
| 931 | + if (dma_err) | |
| 932 | + serial8250_tx_chars(up); | |
| 933 | + } | |
| 934 | + } | |
| 935 | + | |
| 936 | + spin_unlock_irqrestore(&port->lock, flags); | |
| 937 | + serial8250_rpm_put(up); | |
| 938 | + return 1; | |
| 939 | +} | |
| 940 | + | |
| 941 | +static bool the_no_dma_filter_fn(struct dma_chan *chan, void *param) | |
| 942 | +{ | |
| 943 | + return false; | |
| 944 | +} | |
| 945 | + | |
| 946 | +#else | |
| 947 | + | |
| 948 | +static inline int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir) | |
| 949 | +{ | |
| 950 | + return -EINVAL; | |
| 951 | +} | |
| 952 | +#endif | |
| 953 | + | |
| 954 | +static int omap8250_probe(struct platform_device *pdev) | |
| 955 | +{ | |
| 956 | + struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 957 | + struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | |
| 958 | + struct omap8250_priv *priv; | |
| 959 | + struct uart_8250_port up; | |
| 960 | + int ret; | |
| 961 | + void __iomem *membase; | |
| 962 | + | |
| 963 | + if (!regs || !irq) { | |
| 964 | + dev_err(&pdev->dev, "missing registers or irq\n"); | |
| 965 | + return -EINVAL; | |
| 966 | + } | |
| 967 | + | |
| 968 | + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); | |
| 969 | + if (!priv) | |
| 970 | + return -ENOMEM; | |
| 971 | + | |
| 972 | + membase = devm_ioremap_nocache(&pdev->dev, regs->start, | |
| 973 | + resource_size(regs)); | |
| 974 | + if (!membase) | |
| 975 | + return -ENODEV; | |
| 976 | + | |
| 977 | + memset(&up, 0, sizeof(up)); | |
| 978 | + up.port.dev = &pdev->dev; | |
| 979 | + up.port.mapbase = regs->start; | |
| 980 | + up.port.membase = membase; | |
| 981 | + up.port.irq = irq->start; | |
| 982 | + /* | |
| 983 | + * It claims to be 16C750 compatible however it is a little different. | |
| 984 | + * It has EFR and has no FCR7_64byte bit. The AFE (which it claims to | |
| 985 | + * have) is enabled via EFR instead of MCR. The type is set here 8250 | |
| 986 | + * just to get things going. UNKNOWN does not work for a few reasons and | |
| 987 | + * we don't need our own type since we don't use 8250's set_termios() | |
| 988 | + * or pm callback. | |
| 989 | + */ | |
| 990 | + up.port.type = PORT_8250; | |
| 991 | + up.port.iotype = UPIO_MEM; | |
| 992 | + up.port.flags = UPF_FIXED_PORT | UPF_FIXED_TYPE | UPF_SOFT_FLOW | | |
| 993 | + UPF_HARD_FLOW; | |
| 994 | + up.port.private_data = priv; | |
| 995 | + | |
| 996 | + up.port.regshift = 2; | |
| 997 | + up.port.fifosize = 64; | |
| 998 | + up.tx_loadsz = 64; | |
| 999 | + up.capabilities = UART_CAP_FIFO; | |
| 1000 | +#ifdef CONFIG_PM_RUNTIME | |
| 1001 | + /* | |
| 1002 | + * PM_RUNTIME is mostly transparent. However to do it right we need to a | |
| 1003 | + * TX empty interrupt before we can put the device to auto idle. So if | |
| 1004 | + * PM_RUNTIME is not enabled we don't add that flag and can spare that | |
| 1005 | + * one extra interrupt in the TX path. | |
| 1006 | + */ | |
| 1007 | + up.capabilities |= UART_CAP_RPM; | |
| 1008 | +#endif | |
| 1009 | + up.port.set_termios = omap_8250_set_termios; | |
| 1010 | + up.port.pm = omap_8250_pm; | |
| 1011 | + up.port.startup = omap_8250_startup; | |
| 1012 | + up.port.shutdown = omap_8250_shutdown; | |
| 1013 | + up.port.throttle = omap_8250_throttle; | |
| 1014 | + up.port.unthrottle = omap_8250_unthrottle; | |
| 1015 | + | |
| 1016 | + if (pdev->dev.of_node) { | |
| 1017 | + ret = of_alias_get_id(pdev->dev.of_node, "serial"); | |
| 1018 | + | |
| 1019 | + of_property_read_u32(pdev->dev.of_node, "clock-frequency", | |
| 1020 | + &up.port.uartclk); | |
| 1021 | + priv->wakeirq = irq_of_parse_and_map(pdev->dev.of_node, 1); | |
| 1022 | + } else { | |
| 1023 | + ret = pdev->id; | |
| 1024 | + } | |
| 1025 | + if (ret < 0) { | |
| 1026 | + dev_err(&pdev->dev, "failed to get alias/pdev id\n"); | |
| 1027 | + return ret; | |
| 1028 | + } | |
| 1029 | + up.port.line = ret; | |
| 1030 | + | |
| 1031 | + if (!up.port.uartclk) { | |
| 1032 | + up.port.uartclk = DEFAULT_CLK_SPEED; | |
| 1033 | + dev_warn(&pdev->dev, | |
| 1034 | + "No clock speed specified: using default: %d\n", | |
| 1035 | + DEFAULT_CLK_SPEED); | |
| 1036 | + } | |
| 1037 | + | |
| 1038 | + priv->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; | |
| 1039 | + priv->calc_latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; | |
| 1040 | + pm_qos_add_request(&priv->pm_qos_request, PM_QOS_CPU_DMA_LATENCY, | |
| 1041 | + priv->latency); | |
| 1042 | + INIT_WORK(&priv->qos_work, omap8250_uart_qos_work); | |
| 1043 | + | |
| 1044 | + device_init_wakeup(&pdev->dev, true); | |
| 1045 | + pm_runtime_use_autosuspend(&pdev->dev); | |
| 1046 | + pm_runtime_set_autosuspend_delay(&pdev->dev, -1); | |
| 1047 | + | |
| 1048 | + pm_runtime_irq_safe(&pdev->dev); | |
| 1049 | + pm_runtime_enable(&pdev->dev); | |
| 1050 | + | |
| 1051 | + pm_runtime_get_sync(&pdev->dev); | |
| 1052 | + | |
| 1053 | + omap_serial_fill_features_erratas(&up, priv); | |
| 1054 | +#ifdef CONFIG_SERIAL_8250_DMA | |
| 1055 | + if (pdev->dev.of_node) { | |
| 1056 | + /* | |
| 1057 | + * Oh DMA support. If there are no DMA properties in the DT then | |
| 1058 | + * we will fall back to a generic DMA channel which does not | |
| 1059 | + * really work here. To ensure that we do not get a generic DMA | |
| 1060 | + * channel assigned, we have the the_no_dma_filter_fn() here. | |
| 1061 | + * To avoid "failed to request DMA" messages we check for DMA | |
| 1062 | + * properties in DT. | |
| 1063 | + */ | |
| 1064 | + ret = of_property_count_strings(pdev->dev.of_node, "dma-names"); | |
| 1065 | + if (ret == 2) { | |
| 1066 | + up.dma = &priv->omap8250_dma; | |
| 1067 | + up.port.handle_irq = omap_8250_dma_handle_irq; | |
| 1068 | + priv->omap8250_dma.fn = the_no_dma_filter_fn; | |
| 1069 | + priv->omap8250_dma.tx_dma = omap_8250_tx_dma; | |
| 1070 | + priv->omap8250_dma.rx_dma = omap_8250_rx_dma; | |
| 1071 | + priv->omap8250_dma.rx_size = RX_TRIGGER; | |
| 1072 | + priv->omap8250_dma.rxconf.src_maxburst = RX_TRIGGER; | |
| 1073 | + priv->omap8250_dma.txconf.dst_maxburst = TX_TRIGGER; | |
| 1074 | + | |
| 1075 | + if (of_machine_is_compatible("ti,am33xx")) | |
| 1076 | + priv->habit |= OMAP_DMA_TX_KICK; | |
| 1077 | + } | |
| 1078 | + } | |
| 1079 | +#endif | |
| 1080 | + ret = serial8250_register_8250_port(&up); | |
| 1081 | + if (ret < 0) { | |
| 1082 | + dev_err(&pdev->dev, "unable to register 8250 port\n"); | |
| 1083 | + goto err; | |
| 1084 | + } | |
| 1085 | + priv->line = ret; | |
| 1086 | + platform_set_drvdata(pdev, priv); | |
| 1087 | + pm_runtime_mark_last_busy(&pdev->dev); | |
| 1088 | + pm_runtime_put_autosuspend(&pdev->dev); | |
| 1089 | + return 0; | |
| 1090 | +err: | |
| 1091 | + pm_runtime_put(&pdev->dev); | |
| 1092 | + pm_runtime_disable(&pdev->dev); | |
| 1093 | + return ret; | |
| 1094 | +} | |
| 1095 | + | |
| 1096 | +static int omap8250_remove(struct platform_device *pdev) | |
| 1097 | +{ | |
| 1098 | + struct omap8250_priv *priv = platform_get_drvdata(pdev); | |
| 1099 | + | |
| 1100 | + pm_runtime_put_sync(&pdev->dev); | |
| 1101 | + pm_runtime_disable(&pdev->dev); | |
| 1102 | + serial8250_unregister_port(priv->line); | |
| 1103 | + pm_qos_remove_request(&priv->pm_qos_request); | |
| 1104 | + device_init_wakeup(&pdev->dev, false); | |
| 1105 | + return 0; | |
| 1106 | +} | |
| 1107 | + | |
| 1108 | +#if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM_RUNTIME) | |
| 1109 | + | |
| 1110 | +static inline void omap8250_enable_wakeirq(struct omap8250_priv *priv, | |
| 1111 | + bool enable) | |
| 1112 | +{ | |
| 1113 | + if (!priv->wakeirq) | |
| 1114 | + return; | |
| 1115 | + | |
| 1116 | + if (enable) | |
| 1117 | + enable_irq(priv->wakeirq); | |
| 1118 | + else | |
| 1119 | + disable_irq_nosync(priv->wakeirq); | |
| 1120 | +} | |
| 1121 | + | |
| 1122 | +static void omap8250_enable_wakeup(struct omap8250_priv *priv, | |
| 1123 | + bool enable) | |
| 1124 | +{ | |
| 1125 | + if (enable == priv->wakeups_enabled) | |
| 1126 | + return; | |
| 1127 | + | |
| 1128 | + omap8250_enable_wakeirq(priv, enable); | |
| 1129 | + priv->wakeups_enabled = enable; | |
| 1130 | +} | |
| 1131 | +#endif | |
| 1132 | + | |
| 1133 | +#ifdef CONFIG_PM_SLEEP | |
| 1134 | +static int omap8250_prepare(struct device *dev) | |
| 1135 | +{ | |
| 1136 | + struct omap8250_priv *priv = dev_get_drvdata(dev); | |
| 1137 | + | |
| 1138 | + if (!priv) | |
| 1139 | + return 0; | |
| 1140 | + priv->is_suspending = true; | |
| 1141 | + return 0; | |
| 1142 | +} | |
| 1143 | + | |
| 1144 | +static void omap8250_complete(struct device *dev) | |
| 1145 | +{ | |
| 1146 | + struct omap8250_priv *priv = dev_get_drvdata(dev); | |
| 1147 | + | |
| 1148 | + if (!priv) | |
| 1149 | + return; | |
| 1150 | + priv->is_suspending = false; | |
| 1151 | +} | |
| 1152 | + | |
| 1153 | +static int omap8250_suspend(struct device *dev) | |
| 1154 | +{ | |
| 1155 | + struct omap8250_priv *priv = dev_get_drvdata(dev); | |
| 1156 | + | |
| 1157 | + serial8250_suspend_port(priv->line); | |
| 1158 | + flush_work(&priv->qos_work); | |
| 1159 | + | |
| 1160 | + if (device_may_wakeup(dev)) | |
| 1161 | + omap8250_enable_wakeup(priv, true); | |
| 1162 | + else | |
| 1163 | + omap8250_enable_wakeup(priv, false); | |
| 1164 | + return 0; | |
| 1165 | +} | |
| 1166 | + | |
| 1167 | +static int omap8250_resume(struct device *dev) | |
| 1168 | +{ | |
| 1169 | + struct omap8250_priv *priv = dev_get_drvdata(dev); | |
| 1170 | + | |
| 1171 | + if (device_may_wakeup(dev)) | |
| 1172 | + omap8250_enable_wakeup(priv, false); | |
| 1173 | + | |
| 1174 | + serial8250_resume_port(priv->line); | |
| 1175 | + return 0; | |
| 1176 | +} | |
| 1177 | +#else | |
| 1178 | +#define omap8250_prepare NULL | |
| 1179 | +#define omap8250_complete NULL | |
| 1180 | +#endif | |
| 1181 | + | |
| 1182 | +#ifdef CONFIG_PM_RUNTIME | |
| 1183 | +static int omap8250_lost_context(struct uart_8250_port *up) | |
| 1184 | +{ | |
| 1185 | + u32 val; | |
| 1186 | + | |
| 1187 | + val = serial_in(up, UART_OMAP_MDR1); | |
| 1188 | + /* | |
| 1189 | + * If we lose context, then MDR1 is set to its reset value which is | |
| 1190 | + * UART_OMAP_MDR1_DISABLE. After set_termios() we set it either to 13x | |
| 1191 | + * or 16x but never to disable again. | |
| 1192 | + */ | |
| 1193 | + if (val == UART_OMAP_MDR1_DISABLE) | |
| 1194 | + return 1; | |
| 1195 | + return 0; | |
| 1196 | +} | |
| 1197 | + | |
| 1198 | +static int omap8250_runtime_suspend(struct device *dev) | |
| 1199 | +{ | |
| 1200 | + struct omap8250_priv *priv = dev_get_drvdata(dev); | |
| 1201 | + struct uart_8250_port *up; | |
| 1202 | + | |
| 1203 | + up = serial8250_get_port(priv->line); | |
| 1204 | + /* | |
| 1205 | + * When using 'no_console_suspend', the console UART must not be | |
| 1206 | + * suspended. Since driver suspend is managed by runtime suspend, | |
| 1207 | + * preventing runtime suspend (by returning error) will keep device | |
| 1208 | + * active during suspend. | |
| 1209 | + */ | |
| 1210 | + if (priv->is_suspending && !console_suspend_enabled) { | |
| 1211 | + if (uart_console(&up->port)) | |
| 1212 | + return -EBUSY; | |
| 1213 | + } | |
| 1214 | + | |
| 1215 | + omap8250_enable_wakeup(priv, true); | |
| 1216 | + if (up->dma) | |
| 1217 | + omap_8250_rx_dma(up, UART_IIR_RX_TIMEOUT); | |
| 1218 | + | |
| 1219 | + priv->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; | |
| 1220 | + schedule_work(&priv->qos_work); | |
| 1221 | + | |
| 1222 | + return 0; | |
| 1223 | +} | |
| 1224 | + | |
| 1225 | +static int omap8250_runtime_resume(struct device *dev) | |
| 1226 | +{ | |
| 1227 | + struct omap8250_priv *priv = dev_get_drvdata(dev); | |
| 1228 | + struct uart_8250_port *up; | |
| 1229 | + int loss_cntx; | |
| 1230 | + | |
| 1231 | + /* In case runtime-pm tries this before we are setup */ | |
| 1232 | + if (!priv) | |
| 1233 | + return 0; | |
| 1234 | + | |
| 1235 | + up = serial8250_get_port(priv->line); | |
| 1236 | + omap8250_enable_wakeup(priv, false); | |
| 1237 | + loss_cntx = omap8250_lost_context(up); | |
| 1238 | + | |
| 1239 | + if (loss_cntx) | |
| 1240 | + omap8250_restore_regs(up); | |
| 1241 | + | |
| 1242 | + if (up->dma) | |
| 1243 | + omap_8250_rx_dma(up, 0); | |
| 1244 | + | |
| 1245 | + priv->latency = priv->calc_latency; | |
| 1246 | + schedule_work(&priv->qos_work); | |
| 1247 | + return 0; | |
| 1248 | +} | |
| 1249 | +#endif | |
| 1250 | + | |
| 1251 | +static const struct dev_pm_ops omap8250_dev_pm_ops = { | |
| 1252 | + SET_SYSTEM_SLEEP_PM_OPS(omap8250_suspend, omap8250_resume) | |
| 1253 | + SET_RUNTIME_PM_OPS(omap8250_runtime_suspend, | |
| 1254 | + omap8250_runtime_resume, NULL) | |
| 1255 | + .prepare = omap8250_prepare, | |
| 1256 | + .complete = omap8250_complete, | |
| 1257 | +}; | |
| 1258 | + | |
| 1259 | +static const struct of_device_id omap8250_dt_ids[] = { | |
| 1260 | + { .compatible = "ti,omap2-uart" }, | |
| 1261 | + { .compatible = "ti,omap3-uart" }, | |
| 1262 | + { .compatible = "ti,omap4-uart" }, | |
| 1263 | + {}, | |
| 1264 | +}; | |
| 1265 | +MODULE_DEVICE_TABLE(of, omap8250_dt_ids); | |
| 1266 | + | |
| 1267 | +static struct platform_driver omap8250_platform_driver = { | |
| 1268 | + .driver = { | |
| 1269 | + .name = "omap8250", | |
| 1270 | + .pm = &omap8250_dev_pm_ops, | |
| 1271 | + .of_match_table = omap8250_dt_ids, | |
| 1272 | + .owner = THIS_MODULE, | |
| 1273 | + }, | |
| 1274 | + .probe = omap8250_probe, | |
| 1275 | + .remove = omap8250_remove, | |
| 1276 | +}; | |
| 1277 | +module_platform_driver(omap8250_platform_driver); | |
| 1278 | + | |
| 1279 | +MODULE_AUTHOR("Sebastian Andrzej Siewior"); | |
| 1280 | +MODULE_DESCRIPTION("OMAP 8250 Driver"); | |
| 1281 | +MODULE_LICENSE("GPL v2"); | |
| @@ -79,29 +79,24 @@ setup_port(struct serial_private *priv, struct uart_8250_port *port, · 78 unmodified lines | ||
| 79 | 79 | int bar, int offset, int regshift) |
| 80 | 80 | { |
| 81 | 81 | struct pci_dev *dev = priv->dev; |
| 82 | − unsigned long base, len; | |
| 83 | 82 | |
| 84 | 83 | if (bar >= PCI_NUM_BAR_RESOURCES) |
| 85 | 84 | return -EINVAL; |
| 86 | 85 | |
| 87 | − base = pci_resource_start(dev, bar); | |
| 88 | − | |
| 89 | 86 | if (pci_resource_flags(dev, bar) & IORESOURCE_MEM) { |
| 90 | − len = pci_resource_len(dev, bar); | |
| 91 | − | |
| 92 | 87 | if (!priv->remapped_bar[bar]) |
| 93 | − priv->remapped_bar[bar] = ioremap_nocache(base, len); | |
| 88 | + priv->remapped_bar[bar] = pci_ioremap_bar(dev, bar); | |
| 94 | 89 | if (!priv->remapped_bar[bar]) |
| 95 | 90 | return -ENOMEM; |
| 96 | 91 | |
| 97 | 92 | port->port.iotype = UPIO_MEM; |
| 98 | 93 | port->port.iobase = 0; |
| 99 | − port->port.mapbase = base + offset; | |
| 94 | + port->port.mapbase = pci_resource_start(dev, bar) + offset; | |
| 100 | 95 | port->port.membase = priv->remapped_bar[bar] + offset; |
| 101 | 96 | port->port.regshift = regshift; |
| 102 | 97 | } else { |
| 103 | 98 | port->port.iotype = UPIO_PORT; |
| 104 | − port->port.iobase = base + offset; | |
| 99 | + port->port.iobase = pci_resource_start(dev, bar) + offset; | |
| 105 | 100 | port->port.mapbase = 0; |
| 106 | 101 | port->port.membase = NULL; |
| 107 | 102 | port->port.regshift = 0; |
| @@ -317,7 +312,6 @@ static void pci_plx9050_exit(struct pci_dev *dev) · 209 unmodified lines | ||
| 317 | 312 | static void pci_ni8420_exit(struct pci_dev *dev) |
| 318 | 313 | { |
| 319 | 314 | void __iomem *p; |
| 320 | − unsigned long base, len; | |
| 321 | 315 | unsigned int bar = 0; |
| 322 | 316 | |
| 323 | 317 | if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) { |
| @@ -325,9 +319,7 @@ static void pci_ni8420_exit(struct pci_dev *dev) · 1 unmodified line | ||
| 325 | 319 | return; |
| 326 | 320 | } |
| 327 | 321 | |
| 328 | − base = pci_resource_start(dev, bar); | |
| 329 | − len = pci_resource_len(dev, bar); | |
| 330 | − p = ioremap_nocache(base, len); | |
| 322 | + p = pci_ioremap_bar(dev, bar); | |
| 331 | 323 | if (p == NULL) |
| 332 | 324 | return; |
| 333 | 325 | |
| @@ -349,7 +341,6 @@ static void pci_ni8420_exit(struct pci_dev *dev) · 15 unmodified lines | ||
| 349 | 341 | static void pci_ni8430_exit(struct pci_dev *dev) |
| 350 | 342 | { |
| 351 | 343 | void __iomem *p; |
| 352 | − unsigned long base, len; | |
| 353 | 344 | unsigned int bar = 0; |
| 354 | 345 | |
| 355 | 346 | if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) { |
| @@ -357,9 +348,7 @@ static void pci_ni8430_exit(struct pci_dev *dev) · 1 unmodified line | ||
| 357 | 348 | return; |
| 358 | 349 | } |
| 359 | 350 | |
| 360 | − base = pci_resource_start(dev, bar); | |
| 361 | − len = pci_resource_len(dev, bar); | |
| 362 | − p = ioremap_nocache(base, len); | |
| 351 | + p = pci_ioremap_bar(dev, bar); | |
| 363 | 352 | if (p == NULL) |
| 364 | 353 | return; |
| 365 | 354 | |
| @@ -682,7 +671,6 @@ static int pci_xircom_init(struct pci_dev *dev) · 316 unmodified lines | ||
| 682 | 671 | static int pci_ni8420_init(struct pci_dev *dev) |
| 683 | 672 | { |
| 684 | 673 | void __iomem *p; |
| 685 | − unsigned long base, len; | |
| 686 | 674 | unsigned int bar = 0; |
| 687 | 675 | |
| 688 | 676 | if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) { |
| @@ -690,9 +678,7 @@ static int pci_ni8420_init(struct pci_dev *dev) · 1 unmodified line | ||
| 690 | 678 | return 0; |
| 691 | 679 | } |
| 692 | 680 | |
| 693 | − base = pci_resource_start(dev, bar); | |
| 694 | − len = pci_resource_len(dev, bar); | |
| 695 | − p = ioremap_nocache(base, len); | |
| 681 | + p = pci_ioremap_bar(dev, bar); | |
| 696 | 682 | if (p == NULL) |
| 697 | 683 | return -ENOMEM; |
| 698 | 684 | |
| @@ -714,7 +700,7 @@ static int pci_ni8420_init(struct pci_dev *dev) · 15 unmodified lines | ||
| 714 | 700 | static int pci_ni8430_init(struct pci_dev *dev) |
| 715 | 701 | { |
| 716 | 702 | void __iomem *p; |
| 717 | − unsigned long base, len; | |
| 703 | + struct pci_bus_region region; | |
| 718 | 704 | u32 device_window; |
| 719 | 705 | unsigned int bar = 0; |
| 720 | 706 | |
| @@ -723,14 +709,17 @@ static int pci_ni8430_init(struct pci_dev *dev) · 2 unmodified lines | ||
| 723 | 709 | return 0; |
| 724 | 710 | } |
| 725 | 711 | |
| 726 | − base = pci_resource_start(dev, bar); | |
| 727 | − len = pci_resource_len(dev, bar); | |
| 728 | − p = ioremap_nocache(base, len); | |
| 712 | + p = pci_ioremap_bar(dev, bar); | |
| 729 | 713 | if (p == NULL) |
| 730 | 714 | return -ENOMEM; |
| 731 | 715 | |
| 732 | − /* Set device window address and size in BAR0 */ | |
| 733 | − device_window = ((base + MITE_IOWBSR1_WIN_OFFSET) & 0xffffff00) | |
| 716 | + /* | |
| 717 | + * Set device window address and size in BAR0, while acknowledging that | |
| 718 | + * the resource structure may contain a translated address that differs | |
| 719 | + * from the address the device responds to. | |
| 720 | + */ | |
| 721 | + pcibios_resource_to_bus(dev->bus, ®ion, &dev->resource[bar]); | |
| 722 | + device_window = ((region.start + MITE_IOWBSR1_WIN_OFFSET) & 0xffffff00) | |
| 734 | 723 | | MITE_IOWBSR1_WENAB | MITE_IOWBSR1_WSIZE; |
| 735 | 724 | writel(device_window, p + MITE_IOWBSR1); |
| 736 | 725 | |
| @@ -757,8 +746,8 @@ pci_ni8430_setup(struct serial_private *priv, · 20 unmodified lines | ||
| 757 | 746 | const struct pciserial_board *board, |
| 758 | 747 | struct uart_8250_port *port, int idx) |
| 759 | 748 | { |
| 749 | + struct pci_dev *dev = priv->dev; | |
| 760 | 750 | void __iomem *p; |
| 761 | − unsigned long base, len; | |
| 762 | 751 | unsigned int bar, offset = board->first_offset; |
| 763 | 752 | |
| 764 | 753 | if (idx >= board->num_ports) |
| @@ -767,9 +756,9 @@ pci_ni8430_setup(struct serial_private *priv, · 2 unmodified lines | ||
| 767 | 756 | bar = FL_GET_BASE(board->flags); |
| 768 | 757 | offset += idx * board->uart_offset; |
| 769 | 758 | |
| 770 | − base = pci_resource_start(priv->dev, bar); | |
| 771 | − len = pci_resource_len(priv->dev, bar); | |
| 772 | − p = ioremap_nocache(base, len); | |
| 759 | + p = pci_ioremap_bar(dev, bar); | |
| 760 | + if (!p) | |
| 761 | + return -ENOMEM; | |
| 773 | 762 | |
| 774 | 763 | /* enable the transceiver */ |
| 775 | 764 | writeb(readb(p + offset + NI8430_PORTCON) | NI8430_PORTCON_TXVR_ENABLE, |
| @@ -1002,6 +991,40 @@ static void pci_ite887x_exit(struct pci_dev *dev) · 226 unmodified lines | ||
| 1002 | 991 | release_region(ioport, ITE_887x_IOSIZE); |
| 1003 | 992 | } |
| 1004 | 993 | |
| 994 | +/* | |
| 995 | + * EndRun Technologies. | |
| 996 | + * Determine the number of ports available on the device. | |
| 997 | + */ | |
| 998 | +#define PCI_VENDOR_ID_ENDRUN 0x7401 | |
| 999 | +#define PCI_DEVICE_ID_ENDRUN_1588 0xe100 | |
| 1000 | + | |
| 1001 | +static int pci_endrun_init(struct pci_dev *dev) | |
| 1002 | +{ | |
| 1003 | + u8 __iomem *p; | |
| 1004 | + unsigned long deviceID; | |
| 1005 | + unsigned int number_uarts = 0; | |
| 1006 | + | |
| 1007 | + /* EndRun device is all 0xexxx */ | |
| 1008 | + if (dev->vendor == PCI_VENDOR_ID_ENDRUN && | |
| 1009 | + (dev->device & 0xf000) != 0xe000) | |
| 1010 | + return 0; | |
| 1011 | + | |
| 1012 | + p = pci_iomap(dev, 0, 5); | |
| 1013 | + if (p == NULL) | |
| 1014 | + return -ENOMEM; | |
| 1015 | + | |
| 1016 | + deviceID = ioread32(p); | |
| 1017 | + /* EndRun device */ | |
| 1018 | + if (deviceID == 0x07000200) { | |
| 1019 | + number_uarts = ioread8(p + 4); | |
| 1020 | + dev_dbg(&dev->dev, | |
| 1021 | + "%d ports detected on EndRun PCI Express device\n", | |
| 1022 | + number_uarts); | |
| 1023 | + } | |
| 1024 | + pci_iounmap(dev, p); | |
| 1025 | + return number_uarts; | |
| 1026 | +} | |
| 1027 | + | |
| 1005 | 1028 | /* |
| 1006 | 1029 | * Oxford Semiconductor Inc. |
| 1007 | 1030 | * Check that device is part of the Tornado range of devices, then determine |
| @@ -1531,25 +1554,48 @@ static int pci_fintek_setup(struct serial_private *priv, · 523 unmodified lines | ||
| 1531 | 1554 | unsigned long iobase; |
| 1532 | 1555 | unsigned long ciobase = 0; |
| 1533 | 1556 | u8 config_base; |
| 1557 | + u32 bar_data[3]; | |
| 1534 | 1558 | |
| 1535 | 1559 | /* |
| 1536 | − * We are supposed to be able to read these from the PCI config space, | |
| 1537 | − * but the values there don't seem to match what we need to use, so | |
| 1538 | − * just use these hard-coded values for now, as they are correct. | |
| 1560 | + * Find each UARTs offset in PCI configuraion space | |
| 1539 | 1561 | */ |
| 1540 | 1562 | switch (idx) { |
| 1541 | − case 0: iobase = 0xe000; config_base = 0x40; break; | |
| 1542 | − case 1: iobase = 0xe008; config_base = 0x48; break; | |
| 1543 | − case 2: iobase = 0xe010; config_base = 0x50; break; | |
| 1544 | − case 3: iobase = 0xe018; config_base = 0x58; break; | |
| 1545 | − case 4: iobase = 0xe020; config_base = 0x60; break; | |
| 1546 | − case 5: iobase = 0xe028; config_base = 0x68; break; | |
| 1547 | − case 6: iobase = 0xe030; config_base = 0x70; break; | |
| 1548 | − case 7: iobase = 0xe038; config_base = 0x78; break; | |
| 1549 | − case 8: iobase = 0xe040; config_base = 0x80; break; | |
| 1550 | − case 9: iobase = 0xe048; config_base = 0x88; break; | |
| 1551 | − case 10: iobase = 0xe050; config_base = 0x90; break; | |
| 1552 | − case 11: iobase = 0xe058; config_base = 0x98; break; | |
| 1563 | + case 0: | |
| 1564 | + config_base = 0x40; | |
| 1565 | + break; | |
| 1566 | + case 1: | |
| 1567 | + config_base = 0x48; | |
| 1568 | + break; | |
| 1569 | + case 2: | |
| 1570 | + config_base = 0x50; | |
| 1571 | + break; | |
| 1572 | + case 3: | |
| 1573 | + config_base = 0x58; | |
| 1574 | + break; | |
| 1575 | + case 4: | |
| 1576 | + config_base = 0x60; | |
| 1577 | + break; | |
| 1578 | + case 5: | |
| 1579 | + config_base = 0x68; | |
| 1580 | + break; | |
| 1581 | + case 6: | |
| 1582 | + config_base = 0x70; | |
| 1583 | + break; | |
| 1584 | + case 7: | |
| 1585 | + config_base = 0x78; | |
| 1586 | + break; | |
| 1587 | + case 8: | |
| 1588 | + config_base = 0x80; | |
| 1589 | + break; | |
| 1590 | + case 9: | |
| 1591 | + config_base = 0x88; | |
| 1592 | + break; | |
| 1593 | + case 10: | |
| 1594 | + config_base = 0x90; | |
| 1595 | + break; | |
| 1596 | + case 11: | |
| 1597 | + config_base = 0x98; | |
| 1598 | + break; | |
| 1553 | 1599 | default: |
| 1554 | 1600 | /* Unknown number of ports, get out of here */ |
| 1555 | 1601 | return -EINVAL; |
| @@ -1560,6 +1606,14 @@ static int pci_fintek_setup(struct serial_private *priv, · 4 unmodified lines | ||
| 1560 | 1606 | ciobase = (int)(base + (0x8 * idx)); |
| 1561 | 1607 | } |
| 1562 | 1608 | |
| 1609 | + /* Get the io address dispatch from the BIOS */ | |
| 1610 | + pci_read_config_dword(pdev, 0x24, &bar_data[0]); | |
| 1611 | + pci_read_config_dword(pdev, 0x20, &bar_data[1]); | |
| 1612 | + pci_read_config_dword(pdev, 0x1c, &bar_data[2]); | |
| 1613 | + | |
| 1614 | + /* Calculate Real IO Port */ | |
| 1615 | + iobase = (bar_data[idx/4] & 0xffffffe0) + (idx % 4) * 8; | |
| 1616 | + | |
| 1563 | 1617 | dev_dbg(&pdev->dev, "%s: idx=%d iobase=0x%lx ciobase=0x%lx config_base=0x%2x\n", |
| 1564 | 1618 | __func__, idx, iobase, ciobase, config_base); |
| 1565 | 1619 | |
| @@ -1760,6 +1814,16 @@ pci_wch_ch353_setup(struct serial_private *priv, · 194 unmodified lines | ||
| 1760 | 1814 | return pci_default_setup(priv, board, port, idx); |
| 1761 | 1815 | } |
| 1762 | 1816 | |
| 1817 | +static int | |
| 1818 | +pci_wch_ch382_setup(struct serial_private *priv, | |
| 1819 | + const struct pciserial_board *board, | |
| 1820 | + struct uart_8250_port *port, int idx) | |
| 1821 | +{ | |
| 1822 | + port->port.flags |= UPF_FIXED_TYPE; | |
| 1823 | + port->port.type = PORT_16850; | |
| 1824 | + return pci_default_setup(priv, board, port, idx); | |
| 1825 | +} | |
| 1826 | + | |
| 1763 | 1827 | #define PCI_VENDOR_ID_SBSMODULARIO 0x124B |
| 1764 | 1828 | #define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B |
| 1765 | 1829 | #define PCI_DEVICE_ID_OCTPRO 0x0001 |
| @@ -1814,6 +1878,8 @@ pci_wch_ch353_setup(struct serial_private *priv, · 48 unmodified lines | ||
| 1814 | 1878 | #define PCI_VENDOR_ID_SUNIX 0x1fd4 |
| 1815 | 1879 | #define PCI_DEVICE_ID_SUNIX_1999 0x1999 |
| 1816 | 1880 | |
| 1881 | +#define PCIE_VENDOR_ID_WCH 0x1c00 | |
| 1882 | +#define PCIE_DEVICE_ID_WCH_CH382_2S1P 0x3250 | |
| 1817 | 1883 | |
| 1818 | 1884 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ |
| 1819 | 1885 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 |
| @@ -2345,6 +2411,17 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { · 525 unmodified lines | ||
| 2345 | 2411 | .init = pci_netmos_init, |
| 2346 | 2412 | .setup = pci_netmos_9900_setup, |
| 2347 | 2413 | }, |
| 2414 | + /* | |
| 2415 | + * EndRun Technologies | |
| 2416 | + */ | |
| 2417 | + { | |
| 2418 | + .vendor = PCI_VENDOR_ID_ENDRUN, | |
| 2419 | + .device = PCI_ANY_ID, | |
| 2420 | + .subvendor = PCI_ANY_ID, | |
| 2421 | + .subdevice = PCI_ANY_ID, | |
| 2422 | + .init = pci_endrun_init, | |
| 2423 | + .setup = pci_default_setup, | |
| 2424 | + }, | |
| 2348 | 2425 | /* |
| 2349 | 2426 | * For Oxford Semiconductor Tornado based devices |
| 2350 | 2427 | */ |
| @@ -2494,6 +2571,14 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { · 143 unmodified lines | ||
| 2494 | 2571 | .subdevice = PCI_ANY_ID, |
| 2495 | 2572 | .setup = pci_wch_ch353_setup, |
| 2496 | 2573 | }, |
| 2574 | + /* WCH CH382 2S1P card (16750 clone) */ | |
| 2575 | + { | |
| 2576 | + .vendor = PCIE_VENDOR_ID_WCH, | |
| 2577 | + .device = PCIE_DEVICE_ID_WCH_CH382_2S1P, | |
| 2578 | + .subvendor = PCI_ANY_ID, | |
| 2579 | + .subdevice = PCI_ANY_ID, | |
| 2580 | + .setup = pci_wch_ch382_setup, | |
| 2581 | + }, | |
| 2497 | 2582 | /* |
| 2498 | 2583 | * ASIX devices with FIFO bug |
| 2499 | 2584 | */ |
| @@ -2754,6 +2839,7 @@ enum pci_board_num_t { · 254 unmodified lines | ||
| 2754 | 2839 | pbn_panacom2, |
| 2755 | 2840 | pbn_panacom4, |
| 2756 | 2841 | pbn_plx_romulus, |
| 2842 | + pbn_endrun_2_4000000, | |
| 2757 | 2843 | pbn_oxsemi, |
| 2758 | 2844 | pbn_oxsemi_1_4000000, |
| 2759 | 2845 | pbn_oxsemi_2_4000000, |
| @@ -3298,6 +3384,20 @@ static struct pciserial_board pci_boards[] = { · 538 unmodified lines | ||
| 3298 | 3384 | .first_offset = 0x03, |
| 3299 | 3385 | }, |
| 3300 | 3386 | |
| 3387 | + /* | |
| 3388 | + * EndRun Technologies | |
| 3389 | + * Uses the size of PCI Base region 0 to | |
| 3390 | + * signal now many ports are available | |
| 3391 | + * 2 port 952 Uart support | |
| 3392 | + */ | |
| 3393 | + [pbn_endrun_2_4000000] = { | |
| 3394 | + .flags = FL_BASE0, | |
| 3395 | + .num_ports = 2, | |
| 3396 | + .base_baud = 4000000, | |
| 3397 | + .uart_offset = 0x200, | |
| 3398 | + .first_offset = 0x1000, | |
| 3399 | + }, | |
| 3400 | + | |
| 3301 | 3401 | /* |
| 3302 | 3402 | * This board uses the size of PCI Base region 0 to |
| 3303 | 3403 | * signal now many ports are available |
| @@ -3586,6 +3686,7 @@ static const struct pci_device_id blacklist[] = { · 282 unmodified lines | ||
| 3586 | 3686 | /* multi-io cards handled by parport_serial */ |
| 3587 | 3687 | { PCI_DEVICE(0x4348, 0x7053), }, /* WCH CH353 2S1P */ |
| 3588 | 3688 | { PCI_DEVICE(0x4348, 0x5053), }, /* WCH CH353 1S1P */ |
| 3689 | + { PCI_DEVICE(0x1c00, 0x3250), }, /* WCH CH382 2S1P */ | |
| 3589 | 3690 | }; |
| 3590 | 3691 | |
| 3591 | 3692 | /* |
| @@ -4170,6 +4271,13 @@ static struct pci_device_id serial_pci_tbl[] = { · 578 unmodified lines | ||
| 4170 | 4271 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_ROMULUS, |
| 4171 | 4272 | 0x10b5, 0x106a, 0, 0, |
| 4172 | 4273 | pbn_plx_romulus }, |
| 4274 | + /* | |
| 4275 | + * EndRun Technologies. PCI express device range. | |
| 4276 | + * EndRun PTP/1588 has 2 Native UARTs. | |
| 4277 | + */ | |
| 4278 | + { PCI_VENDOR_ID_ENDRUN, PCI_DEVICE_ID_ENDRUN_1588, | |
| 4279 | + PCI_ANY_ID, PCI_ANY_ID, 0, 0, | |
| 4280 | + pbn_endrun_2_4000000 }, | |
| 4173 | 4281 | /* |
| 4174 | 4282 | * Quatech cards. These actually have configurable clocks but for |
| 4175 | 4283 | * now we just use the default. |
| @@ -293,12 +293,21 @@ config SERIAL_8250_EM · 292 unmodified lines | ||
| 293 | 293 | |
| 294 | 294 | config SERIAL_8250_RT288X |
| 295 | 295 | bool "Ralink RT288x/RT305x/RT3662/RT3883 serial port support" |
| 296 | − depends on SERIAL_8250 && (SOC_RT288X || SOC_RT305X || SOC_RT3883) | |
| 296 | + depends on SERIAL_8250 && (SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620) | |
| 297 | 297 | help |
| 298 | 298 | If you have a Ralink RT288x/RT305x SoC based board and want to use the |
| 299 | 299 | serial port, say Y to this option. The driver can handle up to 2 serial |
| 300 | 300 | ports. If unsure, say N. |
| 301 | 301 | |
| 302 | +config SERIAL_8250_OMAP | |
| 303 | + tristate "Support for OMAP internal UART (8250 based driver)" | |
| 304 | + depends on SERIAL_8250 && ARCH_OMAP2PLUS | |
| 305 | + help | |
| 306 | + If you have a machine based on an Texas Instruments OMAP CPU you | |
| 307 | + can enable its onboard serial ports by enabling this option. | |
| 308 | + | |
| 309 | + This driver uses ttyS instead of ttyO. | |
| 310 | + | |
| 302 | 311 | config SERIAL_8250_FINTEK |
| 303 | 312 | tristate "Support for Fintek F81216A LPC to 4 UART" |
| 304 | 313 | depends on SERIAL_8250 && PNP |
| @@ -20,5 +20,6 @@ obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o · 19 unmodified lines | ||
| 20 | 20 | obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o |
| 21 | 21 | obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o |
| 22 | 22 | obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o |
| 23 | +obj-$(CONFIG_SERIAL_8250_OMAP) += 8250_omap.o | |
| 23 | 24 | obj-$(CONFIG_SERIAL_8250_FINTEK) += 8250_fintek.o |
| 24 | 25 | obj-$(CONFIG_SERIAL_8250_MT6577) += 8250_mtk.o |
| @@ -1029,11 +1029,11 @@ config SERIAL_VR41XX_CONSOLE · 1028 unmodified lines | ||
| 1029 | 1029 | a console on a serial port, say Y. Otherwise, say N. |
| 1030 | 1030 | |
| 1031 | 1031 | config SERIAL_JSM |
| 1032 | − tristate "Digi International NEO PCI Support" | |
| 1032 | + tristate "Digi International NEO and Classic PCI Support" | |
| 1033 | 1033 | depends on PCI |
| 1034 | 1034 | select SERIAL_CORE |
| 1035 | 1035 | help |
| 1036 | − This is a driver for Digi International's Neo series | |
| 1036 | + This is a driver for Digi International's Neo and Classic series | |
| 1037 | 1037 | of cards which provide multiple serial ports. You would need |
| 1038 | 1038 | something like this to connect more than two modems to your Linux |
| 1039 | 1039 | box, for instance in order to become a dial-in server. This driver |
| @@ -1281,22 +1281,25 @@ config SERIAL_TIMBERDALE · 241 unmodified lines | ||
| 1281 | 1281 | Add support for UART controller on timberdale. |
| 1282 | 1282 | |
| 1283 | 1283 | config SERIAL_BCM63XX |
| 1284 | − tristate "bcm63xx serial port support" | |
| 1284 | + tristate "Broadcom BCM63xx/BCM33xx UART support" | |
| 1285 | 1285 | select SERIAL_CORE |
| 1286 | − depends on BCM63XX | |
| 1286 | + depends on MIPS || ARM || COMPILE_TEST | |
| 1287 | 1287 | help |
| 1288 | − If you have a bcm63xx CPU, you can enable its onboard | |
| 1289 | − serial port by enabling this options. | |
| 1288 | + This enables the driver for the onchip UART core found on | |
| 1289 | + the following chipsets: | |
| 1290 | 1290 | |
| 1291 | − To compile this driver as a module, choose M here: the | |
| 1292 | − module will be called bcm963xx_uart. | |
| 1291 | + BCM33xx (cable modem) | |
| 1292 | + BCM63xx/BCM63xxx (DSL) | |
| 1293 | + BCM68xx (PON) | |
| 1294 | + BCM7xxx (STB) - DOCSIS console | |
| 1293 | 1295 | |
| 1294 | 1296 | config SERIAL_BCM63XX_CONSOLE |
| 1295 | − bool "Console on bcm63xx serial port" | |
| 1297 | + bool "Console on BCM63xx serial port" | |
| 1296 | 1298 | depends on SERIAL_BCM63XX=y |
| 1297 | 1299 | select SERIAL_CORE_CONSOLE |
| 1300 | + select SERIAL_EARLYCON | |
| 1298 | 1301 | help |
| 1299 | − If you have enabled the serial port on the bcm63xx CPU | |
| 1302 | + If you have enabled the serial port on the BCM63xx CPU | |
| 1300 | 1303 | you can make it the console by answering Y to this option. |
| 1301 | 1304 | |
| 1302 | 1305 | config SERIAL_GRLIB_GAISLER_APBUART |
| @@ -1408,6 +1411,7 @@ config SERIAL_MXS_AUART · 105 unmodified lines | ||
| 1408 | 1411 | depends on ARCH_MXS |
| 1409 | 1412 | tristate "MXS AUART support" |
| 1410 | 1413 | select SERIAL_CORE |
| 1414 | + select SERIAL_MCTRL_GPIO if GPIOLIB | |
| 1411 | 1415 | help |
| 1412 | 1416 | This driver supports the MXS Application UART (AUART) port. |
| 1413 | 1417 | |
| @@ -75,7 +75,8 @@ struct uart_amba_port { · 74 unmodified lines | ||
| 75 | 75 | |
| 76 | 76 | static void pl010_stop_tx(struct uart_port *port) |
| 77 | 77 | { |
| 78 | − struct uart_amba_port *uap = (struct uart_amba_port *)port; | |
| 78 | + struct uart_amba_port *uap = | |
| 79 | + container_of(port, struct uart_amba_port, port); | |
| 79 | 80 | unsigned int cr; |
| 80 | 81 | |
| 81 | 82 | cr = readb(uap->port.membase + UART010_CR); |
| @@ -85,7 +86,8 @@ static void pl010_stop_tx(struct uart_port *port) · 3 unmodified lines | ||
| 85 | 86 | |
| 86 | 87 | static void pl010_start_tx(struct uart_port *port) |
| 87 | 88 | { |
| 88 | − struct uart_amba_port *uap = (struct uart_amba_port *)port; | |
| 89 | + struct uart_amba_port *uap = | |
| 90 | + container_of(port, struct uart_amba_port, port); | |
| 89 | 91 | unsigned int cr; |
| 90 | 92 | |
| 91 | 93 | cr = readb(uap->port.membase + UART010_CR); |
| @@ -95,7 +97,8 @@ static void pl010_start_tx(struct uart_port *port) · 3 unmodified lines | ||
| 95 | 97 | |
| 96 | 98 | static void pl010_stop_rx(struct uart_port *port) |
| 97 | 99 | { |
| 98 | − struct uart_amba_port *uap = (struct uart_amba_port *)port; | |
| 100 | + struct uart_amba_port *uap = | |
| 101 | + container_of(port, struct uart_amba_port, port); | |
| 99 | 102 | unsigned int cr; |
| 100 | 103 | |
| 101 | 104 | cr = readb(uap->port.membase + UART010_CR); |
| @@ -103,11 +106,22 @@ static void pl010_stop_rx(struct uart_port *port) · 1 unmodified line | ||
| 103 | 106 | writel(cr, uap->port.membase + UART010_CR); |
| 104 | 107 | } |
| 105 | 108 | |
| 106 | −static void pl010_enable_ms(struct uart_port *port) | |
| 109 | +static void pl010_disable_ms(struct uart_port *port) | |
| 107 | 110 | { |
| 108 | 111 | struct uart_amba_port *uap = (struct uart_amba_port *)port; |
| 109 | 112 | unsigned int cr; |
| 110 | 113 | |
| 114 | + cr = readb(uap->port.membase + UART010_CR); | |
| 115 | + cr &= ~UART010_CR_MSIE; | |
| 116 | + writel(cr, uap->port.membase + UART010_CR); | |
| 117 | +} | |
| 118 | + | |
| 119 | +static void pl010_enable_ms(struct uart_port *port) | |
| 120 | +{ | |
| 121 | + struct uart_amba_port *uap = | |
| 122 | + container_of(port, struct uart_amba_port, port); | |
| 123 | + unsigned int cr; | |
| 124 | + | |
| 111 | 125 | cr = readb(uap->port.membase + UART010_CR); |
| 112 | 126 | cr |= UART010_CR_MSIE; |
| 113 | 127 | writel(cr, uap->port.membase + UART010_CR); |
| @@ -259,14 +273,16 @@ static irqreturn_t pl010_int(int irq, void *dev_id) · 145 unmodified lines | ||
| 259 | 273 | |
| 260 | 274 | static unsigned int pl010_tx_empty(struct uart_port *port) |
| 261 | 275 | { |
| 262 | − struct uart_amba_port *uap = (struct uart_amba_port *)port; | |
| 276 | + struct uart_amba_port *uap = | |
| 277 | + container_of(port, struct uart_amba_port, port); | |
| 263 | 278 | unsigned int status = readb(uap->port.membase + UART01x_FR); |
| 264 | 279 | return status & UART01x_FR_BUSY ? 0 : TIOCSER_TEMT; |
| 265 | 280 | } |
| 266 | 281 | |
| 267 | 282 | static unsigned int pl010_get_mctrl(struct uart_port *port) |
| 268 | 283 | { |
| 269 | − struct uart_amba_port *uap = (struct uart_amba_port *)port; | |
| 284 | + struct uart_amba_port *uap = | |
| 285 | + container_of(port, struct uart_amba_port, port); | |
| 270 | 286 | unsigned int result = 0; |
| 271 | 287 | unsigned int status; |
| 272 | 288 | |
| @@ -283,7 +299,8 @@ static unsigned int pl010_get_mctrl(struct uart_port *port) · 10 unmodified lines | ||
| 283 | 299 | |
| 284 | 300 | static void pl010_set_mctrl(struct uart_port *port, unsigned int mctrl) |
| 285 | 301 | { |
| 286 | − struct uart_amba_port *uap = (struct uart_amba_port *)port; | |
| 302 | + struct uart_amba_port *uap = | |
| 303 | + container_of(port, struct uart_amba_port, port); | |
| 287 | 304 | |
| 288 | 305 | if (uap->data) |
| 289 | 306 | uap->data->set_mctrl(uap->dev, uap->port.membase, mctrl); |
| @@ -291,7 +308,8 @@ static void pl010_set_mctrl(struct uart_port *port, unsigned int mctrl) · 1 unmodified line | ||
| 291 | 308 | |
| 292 | 309 | static void pl010_break_ctl(struct uart_port *port, int break_state) |
| 293 | 310 | { |
| 294 | − struct uart_amba_port *uap = (struct uart_amba_port *)port; | |
| 311 | + struct uart_amba_port *uap = | |
| 312 | + container_of(port, struct uart_amba_port, port); | |
| 295 | 313 | unsigned long flags; |
| 296 | 314 | unsigned int lcr_h; |
| 297 | 315 | |
| @@ -307,7 +325,8 @@ static void pl010_break_ctl(struct uart_port *port, int break_state) · 9 unmodified lines | ||
| 307 | 325 | |
| 308 | 326 | static int pl010_startup(struct uart_port *port) |
| 309 | 327 | { |
| 310 | − struct uart_amba_port *uap = (struct uart_amba_port *)port; | |
| 328 | + struct uart_amba_port *uap = | |
| 329 | + container_of(port, struct uart_amba_port, port); | |
| 311 | 330 | int retval; |
| 312 | 331 | |
| 313 | 332 | /* |
| @@ -347,7 +366,8 @@ static int pl010_startup(struct uart_port *port) · 33 unmodified lines | ||
| 347 | 366 | |
| 348 | 367 | static void pl010_shutdown(struct uart_port *port) |
| 349 | 368 | { |
| 350 | − struct uart_amba_port *uap = (struct uart_amba_port *)port; | |
| 369 | + struct uart_amba_port *uap = | |
| 370 | + container_of(port, struct uart_amba_port, port); | |
| 351 | 371 | |
| 352 | 372 | /* |
| 353 | 373 | * Free the interrupt |
| @@ -374,7 +394,8 @@ static void · 20 unmodified lines | ||
| 374 | 394 | pl010_set_termios(struct uart_port *port, struct ktermios *termios, |
| 375 | 395 | struct ktermios *old) |
| 376 | 396 | { |
| 377 | − struct uart_amba_port *uap = (struct uart_amba_port *)port; | |
| 397 | + struct uart_amba_port *uap = | |
| 398 | + container_of(port, struct uart_amba_port, port); | |
| 378 | 399 | unsigned int lcr_h, old_cr; |
| 379 | 400 | unsigned long flags; |
| 380 | 401 | unsigned int baud, quot; |
| @@ -468,13 +489,21 @@ pl010_set_termios(struct uart_port *port, struct ktermios *termios, · 87 unmodified lines | ||
| 468 | 489 | spin_unlock_irqrestore(&uap->port.lock, flags); |
| 469 | 490 | } |
| 470 | 491 | |
| 471 | −static void pl010_set_ldisc(struct uart_port *port, int new) | |
| 492 | +static void pl010_set_ldisc(struct uart_port *port, struct ktermios *termios) | |
| 472 | 493 | { |
| 473 | − if (new == N_PPS) { | |
| 494 | + if (termios->c_line == N_PPS) { | |
| 474 | 495 | port->flags |= UPF_HARDPPS_CD; |
| 496 | + spin_lock_irq(&port->lock); | |
| 475 | 497 | pl010_enable_ms(port); |
| 476 | − } else | |
| 498 | + spin_unlock_irq(&port->lock); | |
| 499 | + } else { | |
| 477 | 500 | port->flags &= ~UPF_HARDPPS_CD; |
| 501 | + if (!UART_ENABLE_MS(port, termios->c_cflag)) { | |
| 502 | + spin_lock_irq(&port->lock); | |
| 503 | + pl010_disable_ms(port); | |
| 504 | + spin_unlock_irq(&port->lock); | |
| 505 | + } | |
| 506 | + } | |
| 478 | 507 | } |
| 479 | 508 | |
| 480 | 509 | static const char *pl010_type(struct uart_port *port) |
| @@ -551,7 +580,8 @@ static struct uart_amba_port *amba_ports[UART_NR]; · 70 unmodified lines | ||
| 551 | 580 | |
| 552 | 581 | static void pl010_console_putchar(struct uart_port *port, int ch) |
| 553 | 582 | { |
| 554 | − struct uart_amba_port *uap = (struct uart_amba_port *)port; | |
| 583 | + struct uart_amba_port *uap = | |
| 584 | + container_of(port, struct uart_amba_port, port); | |
| 555 | 585 | unsigned int status; |
| 556 | 586 | |
| 557 | 587 | do { |
| @@ -246,6 +246,7 @@ static int pl011_sgbuf_init(struct dma_chan *chan, struct pl011_sgbuf *sg, · 245 unmodified lines | ||
| 246 | 246 | sg_set_page(&sg->sg, phys_to_page(dma_addr), |
| 247 | 247 | PL011_DMA_BUFFER_SIZE, offset_in_page(dma_addr)); |
| 248 | 248 | sg_dma_address(&sg->sg) = dma_addr; |
| 249 | + sg_dma_len(&sg->sg) = PL011_DMA_BUFFER_SIZE; | |
| 249 | 250 | |
| 250 | 251 | return 0; |
| 251 | 252 | } |
| @@ -321,10 +322,26 @@ static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port * · 69 unmodified lines | ||
| 321 | 322 | .src_maxburst = uap->fifosize >> 2, |
| 322 | 323 | .device_fc = false, |
| 323 | 324 | }; |
| 325 | + struct dma_slave_caps caps; | |
| 324 | 326 | |
| 327 | + /* | |
| 328 | + * Some DMA controllers provide information on their capabilities. | |
| 329 | + * If the controller does, check for suitable residue processing | |
| 330 | + * otherwise assime all is well. | |
| 331 | + */ | |
| 332 | + if (0 == dma_get_slave_caps(chan, &caps)) { | |
| 333 | + if (caps.residue_granularity == | |
| 334 | + DMA_RESIDUE_GRANULARITY_DESCRIPTOR) { | |
| 335 | + dma_release_channel(chan); | |
| 336 | + dev_info(uap->port.dev, | |
| 337 | + "RX DMA disabled - no residue processing\n"); | |
| 338 | + return; | |
| 339 | + } | |
| 340 | + } | |
| 325 | 341 | dmaengine_slave_config(chan, &rx_conf); |
| 326 | 342 | uap->dmarx.chan = chan; |
| 327 | 343 | |
| 344 | + uap->dmarx.auto_poll_rate = false; | |
| 328 | 345 | if (plat && plat->dma_rx_poll_enable) { |
| 329 | 346 | /* Set poll rate if specified. */ |
| 330 | 347 | if (plat->dma_rx_poll_rate) { |
| @@ -345,9 +362,24 @@ static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port * · 14 unmodified lines | ||
| 345 | 362 | plat->dma_rx_poll_timeout; |
| 346 | 363 | else |
| 347 | 364 | uap->dmarx.poll_timeout = 3000; |
| 348 | − } else | |
| 349 | − uap->dmarx.auto_poll_rate = false; | |
| 350 | − | |
| 365 | + } else if (!plat && dev->of_node) { | |
| 366 | + uap->dmarx.auto_poll_rate = of_property_read_bool( | |
| 367 | + dev->of_node, "auto-poll"); | |
| 368 | + if (uap->dmarx.auto_poll_rate) { | |
| 369 | + u32 x; | |
| 370 | + | |
| 371 | + if (0 == of_property_read_u32(dev->of_node, | |
| 372 | + "poll-rate-ms", &x)) | |
| 373 | + uap->dmarx.poll_rate = x; | |
| 374 | + else | |
| 375 | + uap->dmarx.poll_rate = 100; | |
| 376 | + if (0 == of_property_read_u32(dev->of_node, | |
| 377 | + "poll-timeout-ms", &x)) | |
| 378 | + uap->dmarx.poll_timeout = x; | |
| 379 | + else | |
| 380 | + uap->dmarx.poll_timeout = 3000; | |
| 381 | + } | |
| 382 | + } | |
| 351 | 383 | dev_info(uap->port.dev, "DMA channel RX %s\n", |
| 352 | 384 | dma_chan_name(uap->dmarx.chan)); |
| 353 | 385 | } |
| @@ -501,7 +533,11 @@ static int pl011_dma_tx_refill(struct uart_amba_port *uap) · 147 unmodified lines | ||
| 501 | 533 | memcpy(&dmatx->buf[0], &xmit->buf[xmit->tail], count); |
| 502 | 534 | else { |
| 503 | 535 | size_t first = UART_XMIT_SIZE - xmit->tail; |
| 504 | − size_t second = xmit->head; | |
| 536 | + size_t second; | |
| 537 | + | |
| 538 | + if (first > count) | |
| 539 | + first = count; | |
| 540 | + second = count - first; | |
| 505 | 541 | |
| 506 | 542 | memcpy(&dmatx->buf[0], &xmit->buf[xmit->tail], first); |
| 507 | 543 | if (second) |
| @@ -988,7 +1024,7 @@ static void pl011_dma_startup(struct uart_amba_port *uap) · 480 unmodified lines | ||
| 988 | 1024 | if (!uap->dmatx.chan) |
| 989 | 1025 | return; |
| 990 | 1026 | |
| 991 | − uap->dmatx.buf = kmalloc(PL011_DMA_BUFFER_SIZE, GFP_KERNEL); | |
| 1027 | + uap->dmatx.buf = kmalloc(PL011_DMA_BUFFER_SIZE, GFP_KERNEL | __GFP_DMA); | |
| 992 | 1028 | if (!uap->dmatx.buf) { |
| 993 | 1029 | dev_err(uap->port.dev, "no memory for DMA TX buffer\n"); |
| 994 | 1030 | uap->port.fifosize = uap->fifosize; |
| @@ -1689,6 +1725,8 @@ static void pl011_shutdown(struct uart_port *port) · 694 unmodified lines | ||
| 1689 | 1725 | plat->exit(); |
| 1690 | 1726 | } |
| 1691 | 1727 | |
| 1728 | + if (uap->port.ops->flush_buffer) | |
| 1729 | + uap->port.ops->flush_buffer(port); | |
| 1692 | 1730 | } |
| 1693 | 1731 | |
| 1694 | 1732 | static void |
| @@ -119,7 +119,8 @@ static inline void ar933x_uart_putc(struct ar933x_uart_port *up, int ch) · 118 unmodified lines | ||
| 119 | 119 | |
| 120 | 120 | static unsigned int ar933x_uart_tx_empty(struct uart_port *port) |
| 121 | 121 | { |
| 122 | − struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; | |
| 122 | + struct ar933x_uart_port *up = | |
| 123 | + container_of(port, struct ar933x_uart_port, port); | |
| 123 | 124 | unsigned long flags; |
| 124 | 125 | unsigned int rdata; |
| 125 | 126 | |
| @@ -141,21 +142,24 @@ static void ar933x_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) · 15 unmodified lines | ||
| 141 | 142 | |
| 142 | 143 | static void ar933x_uart_start_tx(struct uart_port *port) |
| 143 | 144 | { |
| 144 | − struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; | |
| 145 | + struct ar933x_uart_port *up = | |
| 146 | + container_of(port, struct ar933x_uart_port, port); | |
| 145 | 147 | |
| 146 | 148 | ar933x_uart_start_tx_interrupt(up); |
| 147 | 149 | } |
| 148 | 150 | |
| 149 | 151 | static void ar933x_uart_stop_tx(struct uart_port *port) |
| 150 | 152 | { |
| 151 | − struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; | |
| 153 | + struct ar933x_uart_port *up = | |
| 154 | + container_of(port, struct ar933x_uart_port, port); | |
| 152 | 155 | |
| 153 | 156 | ar933x_uart_stop_tx_interrupt(up); |
| 154 | 157 | } |
| 155 | 158 | |
| 156 | 159 | static void ar933x_uart_stop_rx(struct uart_port *port) |
| 157 | 160 | { |
| 158 | − struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; | |
| 161 | + struct ar933x_uart_port *up = | |
| 162 | + container_of(port, struct ar933x_uart_port, port); | |
| 159 | 163 | |
| 160 | 164 | up->ier &= ~AR933X_UART_INT_RX_VALID; |
| 161 | 165 | ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier); |
| @@ -163,7 +167,8 @@ static void ar933x_uart_stop_rx(struct uart_port *port) · 1 unmodified line | ||
| 163 | 167 | |
| 164 | 168 | static void ar933x_uart_break_ctl(struct uart_port *port, int break_state) |
| 165 | 169 | { |
| 166 | − struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; | |
| 170 | + struct ar933x_uart_port *up = | |
| 171 | + container_of(port, struct ar933x_uart_port, port); | |
| 167 | 172 | unsigned long flags; |
| 168 | 173 | |
| 169 | 174 | spin_lock_irqsave(&up->port.lock, flags); |
| @@ -231,7 +236,8 @@ static void ar933x_uart_set_termios(struct uart_port *port, · 61 unmodified lines | ||
| 231 | 236 | struct ktermios *new, |
| 232 | 237 | struct ktermios *old) |
| 233 | 238 | { |
| 234 | − struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; | |
| 239 | + struct ar933x_uart_port *up = | |
| 240 | + container_of(port, struct ar933x_uart_port, port); | |
| 235 | 241 | unsigned int cs; |
| 236 | 242 | unsigned long flags; |
| 237 | 243 | unsigned int baud, scale, step; |
| @@ -404,7 +410,8 @@ static irqreturn_t ar933x_uart_interrupt(int irq, void *dev_id) · 166 unmodified lines | ||
| 404 | 410 | |
| 405 | 411 | static int ar933x_uart_startup(struct uart_port *port) |
| 406 | 412 | { |
| 407 | − struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; | |
| 413 | + struct ar933x_uart_port *up = | |
| 414 | + container_of(port, struct ar933x_uart_port, port); | |
| 408 | 415 | unsigned long flags; |
| 409 | 416 | int ret; |
| 410 | 417 | |
| @@ -430,7 +437,8 @@ static int ar933x_uart_startup(struct uart_port *port) · 19 unmodified lines | ||
| 430 | 437 | |
| 431 | 438 | static void ar933x_uart_shutdown(struct uart_port *port) |
| 432 | 439 | { |
| 433 | − struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; | |
| 440 | + struct ar933x_uart_port *up = | |
| 441 | + container_of(port, struct ar933x_uart_port, port); | |
| 434 | 442 | |
| 435 | 443 | /* Disable all interrupts */ |
| 436 | 444 | up->ier = 0; |
| @@ -468,7 +476,8 @@ static void ar933x_uart_config_port(struct uart_port *port, int flags) · 31 unmodified lines | ||
| 468 | 476 | static int ar933x_uart_verify_port(struct uart_port *port, |
| 469 | 477 | struct serial_struct *ser) |
| 470 | 478 | { |
| 471 | − struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; | |
| 479 | + struct ar933x_uart_port *up = | |
| 480 | + container_of(port, struct ar933x_uart_port, port); | |
| 472 | 481 | |
| 473 | 482 | if (ser->type != PORT_UNKNOWN && |
| 474 | 483 | ser->type != PORT_AR933X) |
| @@ -521,7 +530,8 @@ static void ar933x_uart_wait_xmitr(struct ar933x_uart_port *up) · 46 unmodified lines | ||
| 521 | 530 | |
| 522 | 531 | static void ar933x_uart_console_putchar(struct uart_port *port, int ch) |
| 523 | 532 | { |
| 524 | − struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; | |
| 533 | + struct ar933x_uart_port *up = | |
| 534 | + container_of(port, struct ar933x_uart_port, port); | |
| 525 | 535 | |
| 526 | 536 | ar933x_uart_wait_xmitr(up); |
| 527 | 537 | ar933x_uart_putc(up, ch); |
| @@ -167,7 +167,6 @@ struct atmel_uart_port { · 166 unmodified lines | ||
| 167 | 167 | |
| 168 | 168 | struct circ_buf rx_ring; |
| 169 | 169 | |
| 170 | − struct serial_rs485 rs485; /* rs485 settings */ | |
| 171 | 170 | struct mctrl_gpios *gpios; |
| 172 | 171 | int gpio_irq[UART_GPIO_MAX]; |
| 173 | 172 | unsigned int tx_done_mask; |
| @@ -290,13 +289,11 @@ static unsigned int atmel_get_lines_status(struct uart_port *port) · 116 unmodified lines | ||
| 290 | 289 | } |
| 291 | 290 | |
| 292 | 291 | /* Enable or disable the rs485 support */ |
| 293 | −void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) | |
| 292 | +static int atmel_config_rs485(struct uart_port *port, | |
| 293 | + struct serial_rs485 *rs485conf) | |
| 294 | 294 | { |
| 295 | 295 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
| 296 | 296 | unsigned int mode; |
| 297 | − unsigned long flags; | |
| 298 | − | |
| 299 | − spin_lock_irqsave(&port->lock, flags); | |
| 300 | 297 | |
| 301 | 298 | /* Disable interrupts */ |
| 302 | 299 | UART_PUT_IDR(port, atmel_port->tx_done_mask); |
| @@ -306,7 +303,7 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) · 3 unmodified lines | ||
| 306 | 303 | /* Resetting serial mode to RS232 (0x0) */ |
| 307 | 304 | mode &= ~ATMEL_US_USMODE; |
| 308 | 305 | |
| 309 | − atmel_port->rs485 = *rs485conf; | |
| 306 | + port->rs485 = *rs485conf; | |
| 310 | 307 | |
| 311 | 308 | if (rs485conf->flags & SER_RS485_ENABLED) { |
| 312 | 309 | dev_dbg(port->dev, "Setting UART to RS485\n"); |
| @@ -327,8 +324,7 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) · 14 unmodified lines | ||
| 327 | 324 | /* Enable interrupts */ |
| 328 | 325 | UART_PUT_IER(port, atmel_port->tx_done_mask); |
| 329 | 326 | |
| 330 | − spin_unlock_irqrestore(&port->lock, flags); | |
| 331 | − | |
| 327 | + return 0; | |
| 332 | 328 | } |
| 333 | 329 | |
| 334 | 330 | /* |
| @@ -372,11 +368,10 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl) · 37 unmodified lines | ||
| 372 | 368 | /* Resetting serial mode to RS232 (0x0) */ |
| 373 | 369 | mode &= ~ATMEL_US_USMODE; |
| 374 | 370 | |
| 375 | − if (atmel_port->rs485.flags & SER_RS485_ENABLED) { | |
| 371 | + if (port->rs485.flags & SER_RS485_ENABLED) { | |
| 376 | 372 | dev_dbg(port->dev, "Setting UART to RS485\n"); |
| 377 | − if ((atmel_port->rs485.delay_rts_after_send) > 0) | |
| 378 | − UART_PUT_TTGR(port, | |
| 379 | − atmel_port->rs485.delay_rts_after_send); | |
| 373 | + if ((port->rs485.delay_rts_after_send) > 0) | |
| 374 | + UART_PUT_TTGR(port, port->rs485.delay_rts_after_send); | |
| 380 | 375 | mode |= ATMEL_US_USMODE_RS485; |
| 381 | 376 | } else { |
| 382 | 377 | dev_dbg(port->dev, "Setting UART to RS232\n"); |
| @@ -423,8 +418,8 @@ static void atmel_stop_tx(struct uart_port *port) · 40 unmodified lines | ||
| 423 | 418 | /* Disable interrupts */ |
| 424 | 419 | UART_PUT_IDR(port, atmel_port->tx_done_mask); |
| 425 | 420 | |
| 426 | − if ((atmel_port->rs485.flags & SER_RS485_ENABLED) && | |
| 427 | − !(atmel_port->rs485.flags & SER_RS485_RX_DURING_TX)) | |
| 421 | + if ((port->rs485.flags & SER_RS485_ENABLED) && | |
| 422 | + !(port->rs485.flags & SER_RS485_RX_DURING_TX)) | |
| 428 | 423 | atmel_start_rx(port); |
| 429 | 424 | } |
| 430 | 425 | |
| @@ -441,8 +436,8 @@ static void atmel_start_tx(struct uart_port *port) · 10 unmodified lines | ||
| 441 | 436 | really need this.*/ |
| 442 | 437 | return; |
| 443 | 438 | |
| 444 | − if ((atmel_port->rs485.flags & SER_RS485_ENABLED) && | |
| 445 | − !(atmel_port->rs485.flags & SER_RS485_RX_DURING_TX)) | |
| 439 | + if ((port->rs485.flags & SER_RS485_ENABLED) && | |
| 440 | + !(port->rs485.flags & SER_RS485_RX_DURING_TX)) | |
| 446 | 441 | atmel_stop_rx(port); |
| 447 | 442 | |
| 448 | 443 | /* re-enable PDC transmit */ |
| @@ -807,7 +802,7 @@ static void atmel_tx_dma(struct uart_port *port) · 358 unmodified lines | ||
| 807 | 802 | atmel_port->cookie_tx = dmaengine_submit(desc); |
| 808 | 803 | |
| 809 | 804 | } else { |
| 810 | − if (atmel_port->rs485.flags & SER_RS485_ENABLED) { | |
| 805 | + if (port->rs485.flags & SER_RS485_ENABLED) { | |
| 811 | 806 | /* DMA done, stop TX, start RX for RS485 */ |
| 812 | 807 | atmel_start_rx(port); |
| 813 | 808 | } |
| @@ -862,9 +857,8 @@ static int atmel_prepare_tx_dma(struct uart_port *port) · 48 unmodified lines | ||
| 862 | 857 | config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; |
| 863 | 858 | config.dst_addr = port->mapbase + ATMEL_US_THR; |
| 864 | 859 | |
| 865 | − ret = dmaengine_device_control(atmel_port->chan_tx, | |
| 866 | − DMA_SLAVE_CONFIG, | |
| 867 | − (unsigned long)&config); | |
| 860 | + ret = dmaengine_slave_config(atmel_port->chan_tx, | |
| 861 | + &config); | |
| 868 | 862 | if (ret) { |
| 869 | 863 | dev_err(port->dev, "DMA tx slave configuration failed\n"); |
| 870 | 864 | goto chan_err; |
| @@ -880,32 +874,6 @@ chan_err: · 9 unmodified lines | ||
| 880 | 874 | return -EINVAL; |
| 881 | 875 | } |
| 882 | 876 | |
| 883 | −static void atmel_flip_buffer_rx_dma(struct uart_port *port, | |
| 884 | − char *buf, size_t count) | |
| 885 | −{ | |
| 886 | − struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | |
| 887 | − struct tty_port *tport = &port->state->port; | |
| 888 | − | |
| 889 | − dma_sync_sg_for_cpu(port->dev, | |
| 890 | − &atmel_port->sg_rx, | |
| 891 | − 1, | |
| 892 | − DMA_DEV_TO_MEM); | |
| 893 | − | |
| 894 | − tty_insert_flip_string(tport, buf, count); | |
| 895 | − | |
| 896 | − dma_sync_sg_for_device(port->dev, | |
| 897 | − &atmel_port->sg_rx, | |
| 898 | − 1, | |
| 899 | − DMA_DEV_TO_MEM); | |
| 900 | − /* | |
| 901 | − * Drop the lock here since it might end up calling | |
| 902 | − * uart_start(), which takes the lock. | |
| 903 | − */ | |
| 904 | − spin_unlock(&port->lock); | |
| 905 | − tty_flip_buffer_push(tport); | |
| 906 | − spin_lock(&port->lock); | |
| 907 | −} | |
| 908 | − | |
| 909 | 877 | static void atmel_complete_rx_dma(void *arg) |
| 910 | 878 | { |
| 911 | 879 | struct uart_port *port = arg; |
| @@ -934,11 +902,12 @@ static void atmel_release_rx_dma(struct uart_port *port) · 22 unmodified lines | ||
| 934 | 902 | static void atmel_rx_from_dma(struct uart_port *port) |
| 935 | 903 | { |
| 936 | 904 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
| 905 | + struct tty_port *tport = &port->state->port; | |
| 937 | 906 | struct circ_buf *ring = &atmel_port->rx_ring; |
| 938 | 907 | struct dma_chan *chan = atmel_port->chan_rx; |
| 939 | 908 | struct dma_tx_state state; |
| 940 | 909 | enum dma_status dmastat; |
| 941 | − size_t pending, count; | |
| 910 | + size_t count; | |
| 942 | 911 | |
| 943 | 912 | |
| 944 | 913 | /* Reset the UART timeout early so that we don't miss one */ |
| @@ -953,27 +922,68 @@ static void atmel_rx_from_dma(struct uart_port *port) · 8 unmodified lines | ||
| 953 | 922 | tasklet_schedule(&atmel_port->tasklet); |
| 954 | 923 | return; |
| 955 | 924 | } |
| 956 | − /* current transfer size should no larger than dma buffer */ | |
| 957 | − pending = sg_dma_len(&atmel_port->sg_rx) - state.residue; | |
| 958 | − BUG_ON(pending > sg_dma_len(&atmel_port->sg_rx)); | |
| 925 | + | |
| 926 | + /* CPU claims ownership of RX DMA buffer */ | |
| 927 | + dma_sync_sg_for_cpu(port->dev, | |
| 928 | + &atmel_port->sg_rx, | |
| 929 | + 1, | |
| 930 | + DMA_DEV_TO_MEM); | |
| 959 | 931 | |
| 960 | 932 | /* |
| 961 | − * This will take the chars we have so far, | |
| 962 | − * ring->head will record the transfer size, only new bytes come | |
| 963 | − * will insert into the framework. | |
| 933 | + * ring->head points to the end of data already written by the DMA. | |
| 934 | + * ring->tail points to the beginning of data to be read by the | |
| 935 | + * framework. | |
| 936 | + * The current transfer size should not be larger than the dma buffer | |
| 937 | + * length. | |
| 964 | 938 | */ |
| 965 | − if (pending > ring->head) { | |
| 966 | − count = pending - ring->head; | |
| 939 | + ring->head = sg_dma_len(&atmel_port->sg_rx) - state.residue; | |
| 940 | + BUG_ON(ring->head > sg_dma_len(&atmel_port->sg_rx)); | |
| 941 | + /* | |
| 942 | + * At this point ring->head may point to the first byte right after the | |
| 943 | + * last byte of the dma buffer: | |
| 944 | + * 0 <= ring->head <= sg_dma_len(&atmel_port->sg_rx) | |
| 945 | + * | |
| 946 | + * However ring->tail must always points inside the dma buffer: | |
| 947 | + * 0 <= ring->tail <= sg_dma_len(&atmel_port->sg_rx) - 1 | |
| 948 | + * | |
| 949 | + * Since we use a ring buffer, we have to handle the case | |
| 950 | + * where head is lower than tail. In such a case, we first read from | |
| 951 | + * tail to the end of the buffer then reset tail. | |
| 952 | + */ | |
| 953 | + if (ring->head < ring->tail) { | |
| 954 | + count = sg_dma_len(&atmel_port->sg_rx) - ring->tail; | |
| 955 | + | |
| 956 | + tty_insert_flip_string(tport, ring->buf + ring->tail, count); | |
| 957 | + ring->tail = 0; | |
| 958 | + port->icount.rx += count; | |
| 959 | + } | |
| 967 | 960 | |
| 968 | − atmel_flip_buffer_rx_dma(port, ring->buf + ring->head, count); | |
| 961 | + /* Finally we read data from tail to head */ | |
| 962 | + if (ring->tail < ring->head) { | |
| 963 | + count = ring->head - ring->tail; | |
| 969 | 964 | |
| 970 | − ring->head += count; | |
| 971 | − if (ring->head == sg_dma_len(&atmel_port->sg_rx)) | |
| 965 | + tty_insert_flip_string(tport, ring->buf + ring->tail, count); | |
| 966 | + /* Wrap ring->head if needed */ | |
| 967 | + if (ring->head >= sg_dma_len(&atmel_port->sg_rx)) | |
| 972 | 968 | ring->head = 0; |
| 973 | − | |
| 969 | + ring->tail = ring->head; | |
| 974 | 970 | port->icount.rx += count; |
| 975 | 971 | } |
| 976 | 972 | |
| 973 | + /* USART retreives ownership of RX DMA buffer */ | |
| 974 | + dma_sync_sg_for_device(port->dev, | |
| 975 | + &atmel_port->sg_rx, | |
| 976 | + 1, | |
| 977 | + DMA_DEV_TO_MEM); | |
| 978 | + | |
| 979 | + /* | |
| 980 | + * Drop the lock here since it might end up calling | |
| 981 | + * uart_start(), which takes the lock. | |
| 982 | + */ | |
| 983 | + spin_unlock(&port->lock); | |
| 984 | + tty_flip_buffer_push(tport); | |
| 985 | + spin_lock(&port->lock); | |
| 986 | + | |
| 977 | 987 | UART_PUT_IER(port, ATMEL_US_TIMEOUT); |
| 978 | 988 | } |
| 979 | 989 | |
| @@ -1026,9 +1036,8 @@ static int atmel_prepare_rx_dma(struct uart_port *port) · 46 unmodified lines | ||
| 1026 | 1036 | config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; |
| 1027 | 1037 | config.src_addr = port->mapbase + ATMEL_US_RHR; |
| 1028 | 1038 | |
| 1029 | − ret = dmaengine_device_control(atmel_port->chan_rx, | |
| 1030 | − DMA_SLAVE_CONFIG, | |
| 1031 | − (unsigned long)&config); | |
| 1039 | + ret = dmaengine_slave_config(atmel_port->chan_rx, | |
| 1040 | + &config); | |
| 1032 | 1041 | if (ret) { |
| 1033 | 1042 | dev_err(port->dev, "DMA rx slave configuration failed\n"); |
| 1034 | 1043 | goto chan_err; |
| @@ -1240,8 +1249,8 @@ static void atmel_tx_pdc(struct uart_port *port) · 205 unmodified lines | ||
| 1240 | 1249 | /* Enable interrupts */ |
| 1241 | 1250 | UART_PUT_IER(port, atmel_port->tx_done_mask); |
| 1242 | 1251 | } else { |
| 1243 | − if ((atmel_port->rs485.flags & SER_RS485_ENABLED) && | |
| 1244 | − !(atmel_port->rs485.flags & SER_RS485_RX_DURING_TX)) { | |
| 1252 | + if ((port->rs485.flags & SER_RS485_ENABLED) && | |
| 1253 | + !(port->rs485.flags & SER_RS485_RX_DURING_TX)) { | |
| 1245 | 1254 | /* DMA done, stop TX, start RX for RS485 */ |
| 1246 | 1255 | atmel_start_rx(port); |
| 1247 | 1256 | } |
| @@ -1552,7 +1561,7 @@ static int atmel_init_property(struct atmel_uart_port *atmel_port, · 304 unmodified lines | ||
| 1552 | 1561 | return 0; |
| 1553 | 1562 | } |
| 1554 | 1563 | |
| 1555 | −static void atmel_init_rs485(struct atmel_uart_port *atmel_port, | |
| 1564 | +static void atmel_init_rs485(struct uart_port *port, | |
| 1556 | 1565 | struct platform_device *pdev) |
| 1557 | 1566 | { |
| 1558 | 1567 | struct device_node *np = pdev->dev.of_node; |
| @@ -1563,7 +1572,7 @@ static void atmel_init_rs485(struct atmel_uart_port *atmel_port, · 4 unmodified lines | ||
| 1563 | 1572 | /* rs485 properties */ |
| 1564 | 1573 | if (of_property_read_u32_array(np, "rs485-rts-delay", |
| 1565 | 1574 | rs485_delay, 2) == 0) { |
| 1566 | − struct serial_rs485 *rs485conf = &atmel_port->rs485; | |
| 1575 | + struct serial_rs485 *rs485conf = &port->rs485; | |
| 1567 | 1576 | |
| 1568 | 1577 | rs485conf->delay_rts_before_send = rs485_delay[0]; |
| 1569 | 1578 | rs485conf->delay_rts_after_send = rs485_delay[1]; |
| @@ -1577,7 +1586,7 @@ static void atmel_init_rs485(struct atmel_uart_port *atmel_port, · 7 unmodified lines | ||
| 1577 | 1586 | rs485conf->flags |= SER_RS485_ENABLED; |
| 1578 | 1587 | } |
| 1579 | 1588 | } else { |
| 1580 | − atmel_port->rs485 = pdata->rs485; | |
| 1589 | + port->rs485 = pdata->rs485; | |
| 1581 | 1590 | } |
| 1582 | 1591 | |
| 1583 | 1592 | } |
| @@ -1801,6 +1810,20 @@ free_irq: · 217 unmodified lines | ||
| 1801 | 1810 | return retval; |
| 1802 | 1811 | } |
| 1803 | 1812 | |
| 1813 | +/* | |
| 1814 | + * Flush any TX data submitted for DMA. Called when the TX circular | |
| 1815 | + * buffer is reset. | |
| 1816 | + */ | |
| 1817 | +static void atmel_flush_buffer(struct uart_port *port) | |
| 1818 | +{ | |
| 1819 | + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | |
| 1820 | + | |
| 1821 | + if (atmel_use_pdc_tx(port)) { | |
| 1822 | + UART_PUT_TCR(port, 0); | |
| 1823 | + atmel_port->pdc_tx.ofs = 0; | |
| 1824 | + } | |
| 1825 | +} | |
| 1826 | + | |
| 1804 | 1827 | /* |
| 1805 | 1828 | * Disable the port |
| 1806 | 1829 | */ |
| @@ -1852,20 +1875,8 @@ static void atmel_shutdown(struct uart_port *port) · 45 unmodified lines | ||
| 1852 | 1875 | atmel_free_gpio_irq(port); |
| 1853 | 1876 | |
| 1854 | 1877 | atmel_port->ms_irq_enabled = false; |
| 1855 | −} | |
| 1856 | 1878 | |
| 1857 | −/* | |
| 1858 | − * Flush any TX data submitted for DMA. Called when the TX circular | |
| 1859 | − * buffer is reset. | |
| 1860 | − */ | |
| 1861 | −static void atmel_flush_buffer(struct uart_port *port) | |
| 1862 | −{ | |
| 1863 | − struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | |
| 1864 | − | |
| 1865 | − if (atmel_use_pdc_tx(port)) { | |
| 1866 | − UART_PUT_TCR(port, 0); | |
| 1867 | − atmel_port->pdc_tx.ofs = 0; | |
| 1868 | − } | |
| 1879 | + atmel_flush_buffer(port); | |
| 1869 | 1880 | } |
| 1870 | 1881 | |
| 1871 | 1882 | /* |
| @@ -1911,7 +1922,6 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, · 39 unmodified lines | ||
| 1911 | 1922 | { |
| 1912 | 1923 | unsigned long flags; |
| 1913 | 1924 | unsigned int mode, imr, quot, baud; |
| 1914 | − struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | |
| 1915 | 1925 | |
| 1916 | 1926 | /* Get current mode register */ |
| 1917 | 1927 | mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL |
| @@ -2013,10 +2023,9 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, · 95 unmodified lines | ||
| 2013 | 2023 | /* Resetting serial mode to RS232 (0x0) */ |
| 2014 | 2024 | mode &= ~ATMEL_US_USMODE; |
| 2015 | 2025 | |
| 2016 | − if (atmel_port->rs485.flags & SER_RS485_ENABLED) { | |
| 2017 | − if ((atmel_port->rs485.delay_rts_after_send) > 0) | |
| 2018 | − UART_PUT_TTGR(port, | |
| 2019 | − atmel_port->rs485.delay_rts_after_send); | |
| 2026 | + if (port->rs485.flags & SER_RS485_ENABLED) { | |
| 2027 | + if ((port->rs485.delay_rts_after_send) > 0) | |
| 2028 | + UART_PUT_TTGR(port, port->rs485.delay_rts_after_send); | |
| 2020 | 2029 | mode |= ATMEL_US_USMODE_RS485; |
| 2021 | 2030 | } |
| 2022 | 2031 | |
| @@ -2040,13 +2049,20 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, · 17 unmodified lines | ||
| 2040 | 2049 | spin_unlock_irqrestore(&port->lock, flags); |
| 2041 | 2050 | } |
| 2042 | 2051 | |
| 2043 | −static void atmel_set_ldisc(struct uart_port *port, int new) | |
| 2052 | +static void atmel_set_ldisc(struct uart_port *port, struct ktermios *termios) | |
| 2044 | 2053 | { |
| 2045 | − if (new == N_PPS) { | |
| 2054 | + if (termios->c_line == N_PPS) { | |
| 2046 | 2055 | port->flags |= UPF_HARDPPS_CD; |
| 2056 | + spin_lock_irq(&port->lock); | |
| 2047 | 2057 | atmel_enable_ms(port); |
| 2058 | + spin_unlock_irq(&port->lock); | |
| 2048 | 2059 | } else { |
| 2049 | 2060 | port->flags &= ~UPF_HARDPPS_CD; |
| 2061 | + if (!UART_ENABLE_MS(port, termios->c_cflag)) { | |
| 2062 | + spin_lock_irq(&port->lock); | |
| 2063 | + atmel_disable_ms(port); | |
| 2064 | + spin_unlock_irq(&port->lock); | |
| 2065 | + } | |
| 2050 | 2066 | } |
| 2051 | 2067 | } |
| 2052 | 2068 | |
| @@ -2148,35 +2164,6 @@ static void atmel_poll_put_char(struct uart_port *port, unsigned char ch) · 95 unmodified lines | ||
| 2148 | 2164 | } |
| 2149 | 2165 | #endif |
| 2150 | 2166 | |
| 2151 | −static int | |
| 2152 | −atmel_ioctl(struct uart_port *port, unsigned int cmd, unsigned long arg) | |
| 2153 | −{ | |
| 2154 | − struct serial_rs485 rs485conf; | |
| 2155 | − | |
| 2156 | − switch (cmd) { | |
| 2157 | − case TIOCSRS485: | |
| 2158 | − if (copy_from_user(&rs485conf, (struct serial_rs485 *) arg, | |
| 2159 | − sizeof(rs485conf))) | |
| 2160 | − return -EFAULT; | |
| 2161 | − | |
| 2162 | − atmel_config_rs485(port, &rs485conf); | |
| 2163 | − break; | |
| 2164 | − | |
| 2165 | − case TIOCGRS485: | |
| 2166 | − if (copy_to_user((struct serial_rs485 *) arg, | |
| 2167 | − &(to_atmel_uart_port(port)->rs485), | |
| 2168 | − sizeof(rs485conf))) | |
| 2169 | − return -EFAULT; | |
| 2170 | − break; | |
| 2171 | − | |
| 2172 | − default: | |
| 2173 | − return -ENOIOCTLCMD; | |
| 2174 | − } | |
| 2175 | − return 0; | |
| 2176 | −} | |
| 2177 | − | |
| 2178 | − | |
| 2179 | − | |
| 2180 | 2167 | static struct uart_ops atmel_pops = { |
| 2181 | 2168 | .tx_empty = atmel_tx_empty, |
| 2182 | 2169 | .set_mctrl = atmel_set_mctrl, |
| @@ -2197,7 +2184,6 @@ static struct uart_ops atmel_pops = { · 14 unmodified lines | ||
| 2197 | 2184 | .config_port = atmel_config_port, |
| 2198 | 2185 | .verify_port = atmel_verify_port, |
| 2199 | 2186 | .pm = atmel_serial_pm, |
| 2200 | − .ioctl = atmel_ioctl, | |
| 2201 | 2187 | #ifdef CONFIG_CONSOLE_POLL |
| 2202 | 2188 | .poll_get_char = atmel_poll_get_char, |
| 2203 | 2189 | .poll_put_char = atmel_poll_put_char, |
| @@ -2217,7 +2203,7 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port, · 13 unmodified lines | ||
| 2217 | 2203 | if (!atmel_init_property(atmel_port, pdev)) |
| 2218 | 2204 | atmel_set_ops(port); |
| 2219 | 2205 | |
| 2220 | − atmel_init_rs485(atmel_port, pdev); | |
| 2206 | + atmel_init_rs485(port, pdev); | |
| 2221 | 2207 | |
| 2222 | 2208 | port->iotype = UPIO_MEM; |
| 2223 | 2209 | port->flags = UPF_BOOT_AUTOCONF; |
| @@ -2226,6 +2212,7 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port, · 2 unmodified lines | ||
| 2226 | 2212 | port->dev = &pdev->dev; |
| 2227 | 2213 | port->mapbase = pdev->resource[0].start; |
| 2228 | 2214 | port->irq = pdev->resource[1].start; |
| 2215 | + port->rs485_config = atmel_config_rs485; | |
| 2229 | 2216 | |
| 2230 | 2217 | tasklet_init(&atmel_port->tasklet, atmel_tasklet_func, |
| 2231 | 2218 | (unsigned long)port); |
| @@ -2260,7 +2247,7 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port, · 28 unmodified lines | ||
| 2260 | 2247 | } |
| 2261 | 2248 | |
| 2262 | 2249 | /* Use TXEMPTY for interrupt when rs485 else TXRDY or ENDTX|TXBUFE */ |
| 2263 | − if (atmel_port->rs485.flags & SER_RS485_ENABLED) | |
| 2250 | + if (port->rs485.flags & SER_RS485_ENABLED) | |
| 2264 | 2251 | atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; |
| 2265 | 2252 | else if (atmel_use_pdc_tx(port)) { |
| 2266 | 2253 | port->fifosize = PDC_BUFFER_SIZE; |
| @@ -2541,6 +2528,7 @@ static int atmel_serial_probe(struct platform_device *pdev) · 274 unmodified lines | ||
| 2541 | 2528 | struct atmel_uart_data *pdata = dev_get_platdata(&pdev->dev); |
| 2542 | 2529 | void *data; |
| 2543 | 2530 | int ret = -ENODEV; |
| 2531 | + bool rs485_enabled; | |
| 2544 | 2532 | |
| 2545 | 2533 | BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1)); |
| 2546 | 2534 | |
| @@ -2588,6 +2576,8 @@ static int atmel_serial_probe(struct platform_device *pdev) · 41 unmodified lines | ||
| 2588 | 2576 | port->rx_ring.buf = data; |
| 2589 | 2577 | } |
| 2590 | 2578 | |
| 2579 | + rs485_enabled = port->uart.rs485.flags & SER_RS485_ENABLED; | |
| 2580 | + | |
| 2591 | 2581 | ret = uart_add_one_port(&atmel_uart, &port->uart); |
| 2592 | 2582 | if (ret) |
| 2593 | 2583 | goto err_add_port; |
| @@ -2606,7 +2596,7 @@ static int atmel_serial_probe(struct platform_device *pdev) · 12 unmodified lines | ||
| 2606 | 2596 | device_init_wakeup(&pdev->dev, 1); |
| 2607 | 2597 | platform_set_drvdata(pdev, port); |
| 2608 | 2598 | |
| 2609 | − if (port->rs485.flags & SER_RS485_ENABLED) { | |
| 2599 | + if (rs485_enabled) { | |
| 2610 | 2600 | UART_PUT_MR(&port->uart, ATMEL_US_USMODE_NORMAL); |
| 2611 | 2601 | UART_PUT_CR(&port->uart, ATMEL_US_RTSEN); |
| 2612 | 2602 | } |
| @@ -588,20 +588,7 @@ static void bcm_uart_set_termios(struct uart_port *port, · 587 unmodified lines | ||
| 588 | 588 | */ |
| 589 | 589 | static int bcm_uart_request_port(struct uart_port *port) |
| 590 | 590 | { |
| 591 | − unsigned int size; | |
| 592 | − | |
| 593 | − size = UART_REG_SIZE; | |
| 594 | − if (!request_mem_region(port->mapbase, size, "bcm63xx")) { | |
| 595 | − dev_err(port->dev, "Memory region busy\n"); | |
| 596 | − return -EBUSY; | |
| 597 | − } | |
| 598 | − | |
| 599 | − port->membase = ioremap(port->mapbase, size); | |
| 600 | − if (!port->membase) { | |
| 601 | − dev_err(port->dev, "Unable to map registers\n"); | |
| 602 | − release_mem_region(port->mapbase, size); | |
| 603 | − return -EBUSY; | |
| 604 | − } | |
| 591 | + /* UARTs always present */ | |
| 605 | 592 | return 0; |
| 606 | 593 | } |
| 607 | 594 | |
| @@ -610,8 +597,7 @@ static int bcm_uart_request_port(struct uart_port *port) · 2 unmodified lines | ||
| 610 | 597 | */ |
| 611 | 598 | static void bcm_uart_release_port(struct uart_port *port) |
| 612 | 599 | { |
| 613 | − release_mem_region(port->mapbase, UART_REG_SIZE); | |
| 614 | − iounmap(port->membase); | |
| 600 | + /* Nothing to release ... */ | |
| 615 | 601 | } |
| 616 | 602 | |
| 617 | 603 | /* |
| @@ -782,6 +768,26 @@ static int __init bcm63xx_console_init(void) · 164 unmodified lines | ||
| 782 | 768 | |
| 783 | 769 | console_initcall(bcm63xx_console_init); |
| 784 | 770 | |
| 771 | +static void bcm_early_write(struct console *con, const char *s, unsigned n) | |
| 772 | +{ | |
| 773 | + struct earlycon_device *dev = con->data; | |
| 774 | + | |
| 775 | + uart_console_write(&dev->port, s, n, bcm_console_putchar); | |
| 776 | + wait_for_xmitr(&dev->port); | |
| 777 | +} | |
| 778 | + | |
| 779 | +static int __init bcm_early_console_setup(struct earlycon_device *device, | |
| 780 | + const char *opt) | |
| 781 | +{ | |
| 782 | + if (!device->port.membase) | |
| 783 | + return -ENODEV; | |
| 784 | + | |
| 785 | + device->con->write = bcm_early_write; | |
| 786 | + return 0; | |
| 787 | +} | |
| 788 | + | |
| 789 | +OF_EARLYCON_DECLARE(bcm63xx_uart, "brcm,bcm6345-uart", bcm_early_console_setup); | |
| 790 | + | |
| 785 | 791 | #define BCM63XX_CONSOLE (&bcm63xx_console) |
| 786 | 792 | #else |
| 787 | 793 | #define BCM63XX_CONSOLE NULL |
| @@ -813,25 +819,30 @@ static int bcm_uart_probe(struct platform_device *pdev) · 25 unmodified lines | ||
| 813 | 819 | if (pdev->id < 0 || pdev->id >= BCM63XX_NR_UARTS) |
| 814 | 820 | return -EINVAL; |
| 815 | 821 | |
| 816 | − if (ports[pdev->id].membase) | |
| 822 | + port = &ports[pdev->id]; | |
| 823 | + if (port->membase) | |
| 817 | 824 | return -EBUSY; |
| 825 | + memset(port, 0, sizeof(*port)); | |
| 818 | 826 | |
| 819 | 827 | res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 820 | 828 | if (!res_mem) |
| 821 | 829 | return -ENODEV; |
| 822 | 830 | |
| 831 | + port->mapbase = res_mem->start; | |
| 832 | + port->membase = devm_ioremap_resource(&pdev->dev, res_mem); | |
| 833 | + if (IS_ERR(port->membase)) | |
| 834 | + return PTR_ERR(port->membase); | |
| 835 | + | |
| 823 | 836 | res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
| 824 | 837 | if (!res_irq) |
| 825 | 838 | return -ENODEV; |
| 826 | 839 | |
| 827 | − clk = clk_get(&pdev->dev, "periph"); | |
| 840 | + clk = pdev->dev.of_node ? of_clk_get(pdev->dev.of_node, 0) : | |
| 841 | + clk_get(&pdev->dev, "periph"); | |
| 828 | 842 | if (IS_ERR(clk)) |
| 829 | 843 | return -ENODEV; |
| 830 | 844 | |
| 831 | − port = &ports[pdev->id]; | |
| 832 | − memset(port, 0, sizeof(*port)); | |
| 833 | 845 | port->iotype = UPIO_MEM; |
| 834 | − port->mapbase = res_mem->start; | |
| 835 | 846 | port->irq = res_irq->start; |
| 836 | 847 | port->ops = &bcm_uart_ops; |
| 837 | 848 | port->flags = UPF_BOOT_AUTOCONF; |
| @@ -905,5 +916,5 @@ module_init(bcm_uart_init); · 67 unmodified lines | ||
| 905 | 916 | module_exit(bcm_uart_exit); |
| 906 | 917 | |
| 907 | 918 | MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>"); |
| 908 | −MODULE_DESCRIPTION("Broadcom 63<xx integrated uart driver"); | |
| 919 | +MODULE_DESCRIPTION("Broadcom 63xx integrated uart driver"); | |
| 909 | 920 | MODULE_LICENSE("GPL"); |
| @@ -517,14 +517,15 @@ static void sport_set_termios(struct uart_port *port, · 516 unmodified lines | ||
| 517 | 517 | up->csize = 5; |
| 518 | 518 | break; |
| 519 | 519 | default: |
| 520 | − pr_warning("requested word length not supported\n"); | |
| 520 | + pr_warn("requested word length not supported\n"); | |
| 521 | + break; | |
| 521 | 522 | } |
| 522 | 523 | |
| 523 | 524 | if (termios->c_cflag & CSTOPB) { |
| 524 | 525 | up->stopb = 1; |
| 525 | 526 | } |
| 526 | 527 | if (termios->c_cflag & PARENB) { |
| 527 | − pr_warning("PAREN bits is not supported yet\n"); | |
| 528 | + pr_warn("PAREN bit is not supported yet\n"); | |
| 528 | 529 | /* up->parib = 1; */ |
| 529 | 530 | } |
| 530 | 531 | |
| @@ -944,12 +944,13 @@ bfin_serial_verify_port(struct uart_port *port, struct serial_struct *ser) · 943 unmodified lines | ||
| 944 | 944 | * Enable the IrDA function if tty->ldisc.num is N_IRDA. |
| 945 | 945 | * In other cases, disable IrDA function. |
| 946 | 946 | */ |
| 947 | −static void bfin_serial_set_ldisc(struct uart_port *port, int ld) | |
| 947 | +static void bfin_serial_set_ldisc(struct uart_port *port, | |
| 948 | + struct ktermios *termios) | |
| 948 | 949 | { |
| 949 | 950 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; |
| 950 | 951 | unsigned int val; |
| 951 | 952 | |
| 952 | − switch (ld) { | |
| 953 | + switch (termios->c_line) { | |
| 953 | 954 | case N_IRDA: |
| 954 | 955 | val = UART_GET_GCTL(uart); |
| 955 | 956 | val |= (UMOD_IRDA | RPOLC); |
| @@ -225,13 +225,14 @@ static void uart_clps711x_break_ctl(struct uart_port *port, int break_state) · 224 unmodified lines | ||
| 225 | 225 | writel(ubrlcr, port->membase + UBRLCR_OFFSET); |
| 226 | 226 | } |
| 227 | 227 | |
| 228 | −static void uart_clps711x_set_ldisc(struct uart_port *port, int ld) | |
| 228 | +static void uart_clps711x_set_ldisc(struct uart_port *port, | |
| 229 | + struct ktermios *termios) | |
| 229 | 230 | { |
| 230 | 231 | if (!port->line) { |
| 231 | 232 | struct clps711x_port *s = dev_get_drvdata(port->dev); |
| 232 | 233 | |
| 233 | 234 | regmap_update_bits(s->syscon, SYSCON_OFFSET, SYSCON1_SIREN, |
| 234 | − (ld == N_IRDA) ? SYSCON1_SIREN : 0); | |
| 235 | + (termios->c_line == N_IRDA) ? SYSCON1_SIREN : 0); | |
| 235 | 236 | } |
| 236 | 237 | } |
| 237 | 238 | |
| @@ -80,7 +80,8 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo); · 79 unmodified lines | ||
| 80 | 80 | */ |
| 81 | 81 | static unsigned int cpm_uart_tx_empty(struct uart_port *port) |
| 82 | 82 | { |
| 83 | − struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | |
| 83 | + struct uart_cpm_port *pinfo = | |
| 84 | + container_of(port, struct uart_cpm_port, port); | |
| 84 | 85 | cbd_t __iomem *bdp = pinfo->tx_bd_base; |
| 85 | 86 | int ret = 0; |
| 86 | 87 | |
| @@ -102,7 +103,8 @@ static unsigned int cpm_uart_tx_empty(struct uart_port *port) · 15 unmodified lines | ||
| 102 | 103 | |
| 103 | 104 | static void cpm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) |
| 104 | 105 | { |
| 105 | − struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | |
| 106 | + struct uart_cpm_port *pinfo = | |
| 107 | + container_of(port, struct uart_cpm_port, port); | |
| 106 | 108 | |
| 107 | 109 | if (pinfo->gpios[GPIO_RTS] >= 0) |
| 108 | 110 | gpio_set_value(pinfo->gpios[GPIO_RTS], !(mctrl & TIOCM_RTS)); |
| @@ -113,7 +115,8 @@ static void cpm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) · 4 unmodified lines | ||
| 113 | 115 | |
| 114 | 116 | static unsigned int cpm_uart_get_mctrl(struct uart_port *port) |
| 115 | 117 | { |
| 116 | − struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | |
| 118 | + struct uart_cpm_port *pinfo = | |
| 119 | + container_of(port, struct uart_cpm_port, port); | |
| 117 | 120 | unsigned int mctrl = TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; |
| 118 | 121 | |
| 119 | 122 | if (pinfo->gpios[GPIO_CTS] >= 0) { |
| @@ -144,7 +147,8 @@ static unsigned int cpm_uart_get_mctrl(struct uart_port *port) · 24 unmodified lines | ||
| 144 | 147 | */ |
| 145 | 148 | static void cpm_uart_stop_tx(struct uart_port *port) |
| 146 | 149 | { |
| 147 | − struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | |
| 150 | + struct uart_cpm_port *pinfo = | |
| 151 | + container_of(port, struct uart_cpm_port, port); | |
| 148 | 152 | smc_t __iomem *smcp = pinfo->smcp; |
| 149 | 153 | scc_t __iomem *sccp = pinfo->sccp; |
| 150 | 154 | |
| @@ -161,7 +165,8 @@ static void cpm_uart_stop_tx(struct uart_port *port) · 10 unmodified lines | ||
| 161 | 165 | */ |
| 162 | 166 | static void cpm_uart_start_tx(struct uart_port *port) |
| 163 | 167 | { |
| 164 | − struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | |
| 168 | + struct uart_cpm_port *pinfo = | |
| 169 | + container_of(port, struct uart_cpm_port, port); | |
| 165 | 170 | smc_t __iomem *smcp = pinfo->smcp; |
| 166 | 171 | scc_t __iomem *sccp = pinfo->sccp; |
| 167 | 172 | |
| @@ -189,7 +194,8 @@ static void cpm_uart_start_tx(struct uart_port *port) · 21 unmodified lines | ||
| 189 | 194 | */ |
| 190 | 195 | static void cpm_uart_stop_rx(struct uart_port *port) |
| 191 | 196 | { |
| 192 | − struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | |
| 197 | + struct uart_cpm_port *pinfo = | |
| 198 | + container_of(port, struct uart_cpm_port, port); | |
| 193 | 199 | smc_t __iomem *smcp = pinfo->smcp; |
| 194 | 200 | scc_t __iomem *sccp = pinfo->sccp; |
| 195 | 201 | |
| @@ -206,7 +212,8 @@ static void cpm_uart_stop_rx(struct uart_port *port) · 10 unmodified lines | ||
| 206 | 212 | */ |
| 207 | 213 | static void cpm_uart_break_ctl(struct uart_port *port, int break_state) |
| 208 | 214 | { |
| 209 | − struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | |
| 215 | + struct uart_cpm_port *pinfo = | |
| 216 | + container_of(port, struct uart_cpm_port, port); | |
| 210 | 217 | |
| 211 | 218 | pr_debug("CPM uart[%d]:break ctrl, break_state: %d\n", port->line, |
| 212 | 219 | break_state); |
| @@ -240,7 +247,8 @@ static void cpm_uart_int_rx(struct uart_port *port) · 27 unmodified lines | ||
| 240 | 247 | unsigned char ch; |
| 241 | 248 | u8 *cp; |
| 242 | 249 | struct tty_port *tport = &port->state->port; |
| 243 | − struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | |
| 250 | + struct uart_cpm_port *pinfo = | |
| 251 | + container_of(port, struct uart_cpm_port, port); | |
| 244 | 252 | cbd_t __iomem *bdp; |
| 245 | 253 | u16 status; |
| 246 | 254 | unsigned int flg; |
| @@ -397,7 +405,8 @@ static irqreturn_t cpm_uart_int(int irq, void *data) · 150 unmodified lines | ||
| 397 | 405 | static int cpm_uart_startup(struct uart_port *port) |
| 398 | 406 | { |
| 399 | 407 | int retval; |
| 400 | − struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | |
| 408 | + struct uart_cpm_port *pinfo = | |
| 409 | + container_of(port, struct uart_cpm_port, port); | |
| 401 | 410 | |
| 402 | 411 | pr_debug("CPM uart[%d]:startup\n", port->line); |
| 403 | 412 | |
| @@ -442,7 +451,8 @@ inline void cpm_uart_wait_until_send(struct uart_cpm_port *pinfo) · 38 unmodified lines | ||
| 442 | 451 | */ |
| 443 | 452 | static void cpm_uart_shutdown(struct uart_port *port) |
| 444 | 453 | { |
| 445 | − struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | |
| 454 | + struct uart_cpm_port *pinfo = | |
| 455 | + container_of(port, struct uart_cpm_port, port); | |
| 446 | 456 | |
| 447 | 457 | pr_debug("CPM uart[%d]:shutdown\n", port->line); |
| 448 | 458 | |
| @@ -492,7 +502,8 @@ static void cpm_uart_set_termios(struct uart_port *port, · 43 unmodified lines | ||
| 492 | 502 | unsigned long flags; |
| 493 | 503 | u16 cval, scval, prev_mode; |
| 494 | 504 | int bits, sbits; |
| 495 | − struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | |
| 505 | + struct uart_cpm_port *pinfo = | |
| 506 | + container_of(port, struct uart_cpm_port, port); | |
| 496 | 507 | smc_t __iomem *smcp = pinfo->smcp; |
| 497 | 508 | scc_t __iomem *sccp = pinfo->sccp; |
| 498 | 509 | int maxidl; |
| @@ -675,7 +686,8 @@ static int cpm_uart_tx_pump(struct uart_port *port) · 176 unmodified lines | ||
| 675 | 686 | cbd_t __iomem *bdp; |
| 676 | 687 | u8 *p; |
| 677 | 688 | int count; |
| 678 | − struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | |
| 689 | + struct uart_cpm_port *pinfo = | |
| 690 | + container_of(port, struct uart_cpm_port, port); | |
| 679 | 691 | struct circ_buf *xmit = &port->state->xmit; |
| 680 | 692 | |
| 681 | 693 | /* Handle xon/xoff */ |
| @@ -906,7 +918,8 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) · 224 unmodified lines | ||
| 906 | 918 | */ |
| 907 | 919 | static int cpm_uart_request_port(struct uart_port *port) |
| 908 | 920 | { |
| 909 | − struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | |
| 921 | + struct uart_cpm_port *pinfo = | |
| 922 | + container_of(port, struct uart_cpm_port, port); | |
| 910 | 923 | int ret; |
| 911 | 924 | |
| 912 | 925 | pr_debug("CPM uart[%d]:request port\n", port->line); |
| @@ -938,7 +951,8 @@ static int cpm_uart_request_port(struct uart_port *port) · 25 unmodified lines | ||
| 938 | 951 | |
| 939 | 952 | static void cpm_uart_release_port(struct uart_port *port) |
| 940 | 953 | { |
| 941 | − struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | |
| 954 | + struct uart_cpm_port *pinfo = | |
| 955 | + container_of(port, struct uart_cpm_port, port); | |
| 942 | 956 | |
| 943 | 957 | if (!(pinfo->flags & FLAG_CONSOLE)) |
| 944 | 958 | cpm_uart_freebuf(pinfo); |
| @@ -1082,7 +1096,8 @@ static int poll_wait_key(char *obuf, struct uart_cpm_port *pinfo) · 137 unmodified lines | ||
| 1082 | 1096 | |
| 1083 | 1097 | static int cpm_get_poll_char(struct uart_port *port) |
| 1084 | 1098 | { |
| 1085 | − struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | |
| 1099 | + struct uart_cpm_port *pinfo = | |
| 1100 | + container_of(port, struct uart_cpm_port, port); | |
| 1086 | 1101 | |
| 1087 | 1102 | if (!serial_polled) { |
| 1088 | 1103 | serial_polled = 1; |
| @@ -1099,7 +1114,8 @@ static int cpm_get_poll_char(struct uart_port *port) · 10 unmodified lines | ||
| 1099 | 1114 | static void cpm_put_poll_char(struct uart_port *port, |
| 1100 | 1115 | unsigned char c) |
| 1101 | 1116 | { |
| 1102 | − struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | |
| 1117 | + struct uart_cpm_port *pinfo = | |
| 1118 | + container_of(port, struct uart_cpm_port, port); | |
| 1103 | 1119 | static char ch[2]; |
| 1104 | 1120 | |
| 1105 | 1121 | ch[0] = (char)c; |
| @@ -3675,12 +3675,6 @@ rs_close(struct tty_struct *tty, struct file * filp) · 3674 unmodified lines | ||
| 3675 | 3675 | return; |
| 3676 | 3676 | } |
| 3677 | 3677 | info->port.flags |= ASYNC_CLOSING; |
| 3678 | − /* | |
| 3679 | − * Save the termios structure, since this port may have | |
| 3680 | − * separate termios for callout and dialin. | |
| 3681 | − */ | |
| 3682 | − if (info->port.flags & ASYNC_NORMAL_ACTIVE) | |
| 3683 | − info->normal_termios = tty->termios; | |
| 3684 | 3678 | /* |
| 3685 | 3679 | * Now we wait for the transmit buffer to clear; and we notify |
| 3686 | 3680 | * the line discipline to only process XON/XOFF characters. |
| @@ -4076,11 +4070,6 @@ rs_open(struct tty_struct *tty, struct file * filp) · 389 unmodified lines | ||
| 4076 | 4070 | return retval; |
| 4077 | 4071 | } |
| 4078 | 4072 | |
| 4079 | − if ((info->port.count == 1) && (info->port.flags & ASYNC_SPLIT_TERMIOS)) { | |
| 4080 | − tty->termios = info->normal_termios; | |
| 4081 | − change_speed(info); | |
| 4082 | − } | |
| 4083 | − | |
| 4084 | 4073 | #ifdef SERIAL_DEBUG_OPEN |
| 4085 | 4074 | printk("rs_open ttyS%d successful...\n", info->line); |
| 4086 | 4075 | #endif |
| @@ -4327,7 +4316,6 @@ static int __init rs_init(void) · 240 unmodified lines | ||
| 4327 | 4316 | info->custom_divisor = 0; |
| 4328 | 4317 | info->x_char = 0; |
| 4329 | 4318 | info->event = 0; |
| 4330 | − info->normal_termios = driver->init_termios; | |
| 4331 | 4319 | info->xmit.buf = NULL; |
| 4332 | 4320 | info->xmit.tail = info->xmit.head = 0; |
| 4333 | 4321 | info->first_recv_buffer = info->last_recv_buffer = NULL; |
| @@ -98,7 +98,6 @@ struct e100_serial { · 97 unmodified lines | ||
| 98 | 98 | |
| 99 | 99 | struct work_struct work; |
| 100 | 100 | struct async_icount icount; /* error-statistics etc.*/ |
| 101 | − struct ktermios normal_termios; | |
| 102 | 101 | |
| 103 | 102 | unsigned long char_time_usec; /* The time for 1 char, in usecs */ |
| 104 | 103 | unsigned long flush_time_usec; /* How often we should flush */ |
| @@ -98,7 +98,7 @@ static int __init parse_options(struct earlycon_device *device, · 97 unmodified lines | ||
| 98 | 98 | strlcpy(device->options, options, length); |
| 99 | 99 | } |
| 100 | 100 | |
| 101 | − if (mmio || mmio32) | |
| 101 | + if (port->iotype == UPIO_MEM || port->iotype == UPIO_MEM32) | |
| 102 | 102 | pr_info("Early serial console at MMIO%s 0x%llx (options '%s')\n", |
| 103 | 103 | mmio32 ? "32" : "", |
| 104 | 104 | (unsigned long long)port->mapbase, |
| @@ -1786,15 +1786,13 @@ static int lpuart_probe(struct platform_device *pdev) · 1785 unmodified lines | ||
| 1786 | 1786 | } |
| 1787 | 1787 | sport->port.line = ret; |
| 1788 | 1788 | sport->lpuart32 = of_device_is_compatible(np, "fsl,ls1021a-lpuart"); |
| 1789 | − res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 1790 | − if (!res) | |
| 1791 | − return -ENODEV; | |
| 1792 | 1789 | |
| 1793 | − sport->port.mapbase = res->start; | |
| 1790 | + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 1794 | 1791 | sport->port.membase = devm_ioremap_resource(&pdev->dev, res); |
| 1795 | 1792 | if (IS_ERR(sport->port.membase)) |
| 1796 | 1793 | return PTR_ERR(sport->port.membase); |
| 1797 | 1794 | |
| 1795 | + sport->port.mapbase = res->start; | |
| 1798 | 1796 | sport->port.dev = &pdev->dev; |
| 1799 | 1797 | sport->port.type = PORT_LPUART; |
| 1800 | 1798 | sport->port.iotype = UPIO_MEM; |
| @@ -1862,6 +1860,20 @@ static int lpuart_suspend(struct device *dev) · 61 unmodified lines | ||
| 1862 | 1860 | static int lpuart_resume(struct device *dev) |
| 1863 | 1861 | { |
| 1864 | 1862 | struct lpuart_port *sport = dev_get_drvdata(dev); |
| 1863 | + unsigned long temp; | |
| 1864 | + | |
| 1865 | + if (sport->lpuart32) { | |
| 1866 | + lpuart32_setup_watermark(sport); | |
| 1867 | + temp = lpuart32_read(sport->port.membase + UARTCTRL); | |
| 1868 | + temp |= (UARTCTRL_RIE | UARTCTRL_TIE | UARTCTRL_RE | | |
| 1869 | + UARTCTRL_TE | UARTCTRL_ILIE); | |
| 1870 | + lpuart32_write(temp, sport->port.membase + UARTCTRL); | |
| 1871 | + } else { | |
| 1872 | + lpuart_setup_watermark(sport); | |
| 1873 | + temp = readb(sport->port.membase + UARTCR2); | |
| 1874 | + temp |= (UARTCR2_RIE | UARTCR2_TIE | UARTCR2_RE | UARTCR2_TE); | |
| 1875 | + writeb(temp, sport->port.membase + UARTCR2); | |
| 1876 | + } | |
| 1865 | 1877 | |
| 1866 | 1878 | uart_resume_port(&lpuart_reg, &sport->port); |
| 1867 | 1879 | |
| @@ -1884,11 +1896,8 @@ static struct platform_driver lpuart_driver = { · 16 unmodified lines | ||
| 1884 | 1896 | |
| 1885 | 1897 | static int __init lpuart_serial_init(void) |
| 1886 | 1898 | { |
| 1887 | − int ret; | |
| 1888 | − | |
| 1889 | − pr_info("serial: Freescale lpuart driver\n"); | |
| 1899 | + int ret = uart_register_driver(&lpuart_reg); | |
| 1890 | 1900 | |
| 1891 | − ret = uart_register_driver(&lpuart_reg); | |
| 1892 | 1901 | if (ret) |
| 1893 | 1902 | return ret; |
| 1894 | 1903 | |
| @@ -1550,8 +1550,10 @@ static int icom_probe(struct pci_dev *dev, · 1549 unmodified lines | ||
| 1550 | 1550 | |
| 1551 | 1551 | icom_adapter->base_addr = pci_ioremap_bar(dev, 0); |
| 1552 | 1552 | |
| 1553 | − if (!icom_adapter->base_addr) | |
| 1553 | + if (!icom_adapter->base_addr) { | |
| 1554 | + retval = -ENOMEM; | |
| 1554 | 1555 | goto probe_exit1; |
| 1556 | + } | |
| 1555 | 1557 | |
| 1556 | 1558 | /* save off irq and request irq line */ |
| 1557 | 1559 | if ( (retval = request_irq(dev->irq, icom_interrupt, |
| @@ -302,7 +302,7 @@ static inline int is_imx6q_uart(struct imx_port *sport) · 301 unmodified lines | ||
| 302 | 302 | /* |
| 303 | 303 | * Save and restore functions for UCR1, UCR2 and UCR3 registers |
| 304 | 304 | */ |
| 305 | −#if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_IMX_CONSOLE) | |
| 305 | +#if defined(CONFIG_SERIAL_IMX_CONSOLE) | |
| 306 | 306 | static void imx_port_ucrs_save(struct uart_port *port, |
| 307 | 307 | struct imx_port_ucrs *ucr) |
| 308 | 308 | { |
| @@ -991,7 +991,6 @@ static int imx_uart_dma_init(struct imx_port *sport) · 682 unmodified lines | ||
| 991 | 991 | |
| 992 | 992 | sport->rx_buf = kzalloc(PAGE_SIZE, GFP_KERNEL); |
| 993 | 993 | if (!sport->rx_buf) { |
| 994 | − dev_err(dev, "cannot alloc DMA buffer.\n"); | |
| 995 | 994 | ret = -ENOMEM; |
| 996 | 995 | goto err; |
| 997 | 996 | } |
| @@ -1076,11 +1075,11 @@ static int imx_startup(struct uart_port *port) · 78 unmodified lines | ||
| 1076 | 1075 | |
| 1077 | 1076 | retval = clk_prepare_enable(sport->clk_per); |
| 1078 | 1077 | if (retval) |
| 1079 | − goto error_out1; | |
| 1078 | + return retval; | |
| 1080 | 1079 | retval = clk_prepare_enable(sport->clk_ipg); |
| 1081 | 1080 | if (retval) { |
| 1082 | 1081 | clk_disable_unprepare(sport->clk_per); |
| 1083 | − goto error_out1; | |
| 1082 | + return retval; | |
| 1084 | 1083 | } |
| 1085 | 1084 | |
| 1086 | 1085 | imx_setup_ufcr(sport, 0); |
| @@ -1109,37 +1108,6 @@ static int imx_startup(struct uart_port *port) · 22 unmodified lines | ||
| 1109 | 1108 | while (!(readl(sport->port.membase + UCR2) & UCR2_SRST) && (--i > 0)) |
| 1110 | 1109 | udelay(1); |
| 1111 | 1110 | |
| 1112 | − /* | |
| 1113 | − * Allocate the IRQ(s) i.MX1 has three interrupts whereas later | |
| 1114 | − * chips only have one interrupt. | |
| 1115 | − */ | |
| 1116 | − if (sport->txirq > 0) { | |
| 1117 | − retval = request_irq(sport->rxirq, imx_rxint, 0, | |
| 1118 | − dev_name(port->dev), sport); | |
| 1119 | − if (retval) | |
| 1120 | − goto error_out1; | |
| 1121 | − | |
| 1122 | − retval = request_irq(sport->txirq, imx_txint, 0, | |
| 1123 | − dev_name(port->dev), sport); | |
| 1124 | − if (retval) | |
| 1125 | − goto error_out2; | |
| 1126 | − | |
| 1127 | − /* do not use RTS IRQ on IrDA */ | |
| 1128 | − if (!USE_IRDA(sport)) { | |
| 1129 | − retval = request_irq(sport->rtsirq, imx_rtsint, 0, | |
| 1130 | − dev_name(port->dev), sport); | |
| 1131 | − if (retval) | |
| 1132 | − goto error_out3; | |
| 1133 | − } | |
| 1134 | − } else { | |
| 1135 | − retval = request_irq(sport->port.irq, imx_int, 0, | |
| 1136 | − dev_name(port->dev), sport); | |
| 1137 | − if (retval) { | |
| 1138 | − free_irq(sport->port.irq, sport); | |
| 1139 | − goto error_out1; | |
| 1140 | − } | |
| 1141 | − } | |
| 1142 | − | |
| 1143 | 1111 | spin_lock_irqsave(&sport->port.lock, flags); |
| 1144 | 1112 | /* |
| 1145 | 1113 | * Finally, clear and enable interrupts |
| @@ -1201,15 +1169,6 @@ static int imx_startup(struct uart_port *port) · 55 unmodified lines | ||
| 1201 | 1169 | } |
| 1202 | 1170 | |
| 1203 | 1171 | return 0; |
| 1204 | − | |
| 1205 | −error_out3: | |
| 1206 | − if (sport->txirq) | |
| 1207 | − free_irq(sport->txirq, sport); | |
| 1208 | −error_out2: | |
| 1209 | − if (sport->rxirq) | |
| 1210 | − free_irq(sport->rxirq, sport); | |
| 1211 | −error_out1: | |
| 1212 | − return retval; | |
| 1213 | 1172 | } |
| 1214 | 1173 | |
| 1215 | 1174 | static void imx_shutdown(struct uart_port *port) |
| @@ -1254,17 +1213,6 @@ static void imx_shutdown(struct uart_port *port) · 38 unmodified lines | ||
| 1254 | 1213 | */ |
| 1255 | 1214 | del_timer_sync(&sport->timer); |
| 1256 | 1215 | |
| 1257 | − /* | |
| 1258 | − * Free the interrupts | |
| 1259 | − */ | |
| 1260 | − if (sport->txirq > 0) { | |
| 1261 | − if (!USE_IRDA(sport)) | |
| 1262 | − free_irq(sport->rtsirq, sport); | |
| 1263 | − free_irq(sport->txirq, sport); | |
| 1264 | − free_irq(sport->rxirq, sport); | |
| 1265 | − } else | |
| 1266 | − free_irq(sport->port.irq, sport); | |
| 1267 | − | |
| 1268 | 1216 | /* |
| 1269 | 1217 | * Disable all interrupts, port and break condition. |
| 1270 | 1218 | */ |
| @@ -1507,44 +1455,65 @@ imx_verify_port(struct uart_port *port, struct serial_struct *ser) · 236 unmodified lines | ||
| 1507 | 1455 | } |
| 1508 | 1456 | |
| 1509 | 1457 | #if defined(CONFIG_CONSOLE_POLL) |
| 1458 | + | |
| 1459 | +static int imx_poll_init(struct uart_port *port) | |
| 1460 | +{ | |
| 1461 | + struct imx_port *sport = (struct imx_port *)port; | |
| 1462 | + unsigned long flags; | |
| 1463 | + unsigned long temp; | |
| 1464 | + int retval; | |
| 1465 | + | |
| 1466 | + retval = clk_prepare_enable(sport->clk_ipg); | |
| 1467 | + if (retval) | |
| 1468 | + return retval; | |
| 1469 | + retval = clk_prepare_enable(sport->clk_per); | |
| 1470 | + if (retval) | |
| 1471 | + clk_disable_unprepare(sport->clk_ipg); | |
| 1472 | + | |
| 1473 | + imx_setup_ufcr(sport, 0); | |
| 1474 | + | |
| 1475 | + spin_lock_irqsave(&sport->port.lock, flags); | |
| 1476 | + | |
| 1477 | + temp = readl(sport->port.membase + UCR1); | |
| 1478 | + if (is_imx1_uart(sport)) | |
| 1479 | + temp |= IMX1_UCR1_UARTCLKEN; | |
| 1480 | + temp |= UCR1_UARTEN | UCR1_RRDYEN; | |
| 1481 | + temp &= ~(UCR1_TXMPTYEN | UCR1_RTSDEN); | |
| 1482 | + writel(temp, sport->port.membase + UCR1); | |
| 1483 | + | |
| 1484 | + temp = readl(sport->port.membase + UCR2); | |
| 1485 | + temp |= UCR2_RXEN; | |
| 1486 | + writel(temp, sport->port.membase + UCR2); | |
| 1487 | + | |
| 1488 | + spin_unlock_irqrestore(&sport->port.lock, flags); | |
| 1489 | + | |
| 1490 | + return 0; | |
| 1491 | +} | |
| 1492 | + | |
| 1510 | 1493 | static int imx_poll_get_char(struct uart_port *port) |
| 1511 | 1494 | { |
| 1512 | − if (!(readl(port->membase + USR2) & USR2_RDR)) | |
| 1495 | + if (!(readl_relaxed(port->membase + USR2) & USR2_RDR)) | |
| 1513 | 1496 | return NO_POLL_CHAR; |
| 1514 | 1497 | |
| 1515 | − return readl(port->membase + URXD0) & URXD_RX_DATA; | |
| 1498 | + return readl_relaxed(port->membase + URXD0) & URXD_RX_DATA; | |
| 1516 | 1499 | } |
| 1517 | 1500 | |
| 1518 | 1501 | static void imx_poll_put_char(struct uart_port *port, unsigned char c) |
| 1519 | 1502 | { |
| 1520 | − struct imx_port_ucrs old_ucr; | |
| 1521 | 1503 | unsigned int status; |
| 1522 | 1504 | |
| 1523 | − /* save control registers */ | |
| 1524 | − imx_port_ucrs_save(port, &old_ucr); | |
| 1525 | − | |
| 1526 | − /* disable interrupts */ | |
| 1527 | − writel(UCR1_UARTEN, port->membase + UCR1); | |
| 1528 | − writel(old_ucr.ucr2 & ~(UCR2_ATEN | UCR2_RTSEN | UCR2_ESCI), | |
| 1529 | − port->membase + UCR2); | |
| 1530 | − writel(old_ucr.ucr3 & ~(UCR3_DCD | UCR3_RI | UCR3_DTREN), | |
| 1531 | − port->membase + UCR3); | |
| 1532 | − | |
| 1533 | 1505 | /* drain */ |
| 1534 | 1506 | do { |
| 1535 | − status = readl(port->membase + USR1); | |
| 1507 | + status = readl_relaxed(port->membase + USR1); | |
| 1536 | 1508 | } while (~status & USR1_TRDY); |
| 1537 | 1509 | |
| 1538 | 1510 | /* write */ |
| 1539 | − writel(c, port->membase + URTX0); | |
| 1511 | + writel_relaxed(c, port->membase + URTX0); | |
| 1540 | 1512 | |
| 1541 | 1513 | /* flush */ |
| 1542 | 1514 | do { |
| 1543 | − status = readl(port->membase + USR2); | |
| 1515 | + status = readl_relaxed(port->membase + USR2); | |
| 1544 | 1516 | } while (~status & USR2_TXDC); |
| 1545 | − | |
| 1546 | − /* restore control registers */ | |
| 1547 | − imx_port_ucrs_restore(port, &old_ucr); | |
| 1548 | 1517 | } |
| 1549 | 1518 | #endif |
| 1550 | 1519 | |
| @@ -1565,6 +1534,7 @@ static struct uart_ops imx_pops = { · 14 unmodified lines | ||
| 1565 | 1534 | .config_port = imx_config_port, |
| 1566 | 1535 | .verify_port = imx_verify_port, |
| 1567 | 1536 | #if defined(CONFIG_CONSOLE_POLL) |
| 1537 | + .poll_init = imx_poll_init, | |
| 1568 | 1538 | .poll_get_char = imx_poll_get_char, |
| 1569 | 1539 | .poll_put_char = imx_poll_put_char, |
| 1570 | 1540 | #endif |
| @@ -1929,6 +1899,36 @@ static int serial_imx_probe(struct platform_device *pdev) · 358 unmodified lines | ||
| 1929 | 1899 | |
| 1930 | 1900 | sport->port.uartclk = clk_get_rate(sport->clk_per); |
| 1931 | 1901 | |
| 1902 | + /* | |
| 1903 | + * Allocate the IRQ(s) i.MX1 has three interrupts whereas later | |
| 1904 | + * chips only have one interrupt. | |
| 1905 | + */ | |
| 1906 | + if (sport->txirq > 0) { | |
| 1907 | + ret = devm_request_irq(&pdev->dev, sport->rxirq, imx_rxint, 0, | |
| 1908 | + dev_name(&pdev->dev), sport); | |
| 1909 | + if (ret) | |
| 1910 | + return ret; | |
| 1911 | + | |
| 1912 | + ret = devm_request_irq(&pdev->dev, sport->txirq, imx_txint, 0, | |
| 1913 | + dev_name(&pdev->dev), sport); | |
| 1914 | + if (ret) | |
| 1915 | + return ret; | |
| 1916 | + | |
| 1917 | + /* do not use RTS IRQ on IrDA */ | |
| 1918 | + if (!USE_IRDA(sport)) { | |
| 1919 | + ret = devm_request_irq(&pdev->dev, sport->rtsirq, | |
| 1920 | + imx_rtsint, 0, | |
| 1921 | + dev_name(&pdev->dev), sport); | |
| 1922 | + if (ret) | |
| 1923 | + return ret; | |
| 1924 | + } | |
| 1925 | + } else { | |
| 1926 | + ret = devm_request_irq(&pdev->dev, sport->port.irq, imx_int, 0, | |
| 1927 | + dev_name(&pdev->dev), sport); | |
| 1928 | + if (ret) | |
| 1929 | + return ret; | |
| 1930 | + } | |
| 1931 | + | |
| 1932 | 1932 | imx_ports[sport->port.line] = sport; |
| 1933 | 1933 | |
| 1934 | 1934 | platform_set_drvdata(pdev, sport); |
| @@ -1959,11 +1959,8 @@ static struct platform_driver serial_imx_driver = { · 24 unmodified lines | ||
| 1959 | 1959 | |
| 1960 | 1960 | static int __init imx_serial_init(void) |
| 1961 | 1961 | { |
| 1962 | − int ret; | |
| 1963 | − | |
| 1964 | − pr_info("Serial: IMX driver\n"); | |
| 1962 | + int ret = uart_register_driver(&imx_reg); | |
| 1965 | 1963 | |
| 1966 | − ret = uart_register_driver(&imx_reg); | |
| 1967 | 1964 | if (ret) |
| 1968 | 1965 | return ret; |
| 1969 | 1966 | |
| @@ -544,7 +544,8 @@ static unsigned int ip22zilog_get_mctrl(struct uart_port *port) · 543 unmodified lines | ||
| 544 | 544 | /* The port lock is held and interrupts are disabled. */ |
| 545 | 545 | static void ip22zilog_set_mctrl(struct uart_port *port, unsigned int mctrl) |
| 546 | 546 | { |
| 547 | − struct uart_ip22zilog_port *up = (struct uart_ip22zilog_port *) port; | |
| 547 | + struct uart_ip22zilog_port *up = | |
| 548 | + container_of(port, struct uart_ip22zilog_port, port); | |
| 548 | 549 | struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port); |
| 549 | 550 | unsigned char set_bits, clear_bits; |
| 550 | 551 | |
| @@ -568,7 +569,8 @@ static void ip22zilog_set_mctrl(struct uart_port *port, unsigned int mctrl) · 17 unmodified lines | ||
| 568 | 569 | /* The port lock is held and interrupts are disabled. */ |
| 569 | 570 | static void ip22zilog_stop_tx(struct uart_port *port) |
| 570 | 571 | { |
| 571 | − struct uart_ip22zilog_port *up = (struct uart_ip22zilog_port *) port; | |
| 572 | + struct uart_ip22zilog_port *up = | |
| 573 | + container_of(port, struct uart_ip22zilog_port, port); | |
| 572 | 574 | |
| 573 | 575 | up->flags |= IP22ZILOG_FLAG_TX_STOPPED; |
| 574 | 576 | } |
| @@ -576,7 +578,8 @@ static void ip22zilog_stop_tx(struct uart_port *port) · 1 unmodified line | ||
| 576 | 578 | /* The port lock is held and interrupts are disabled. */ |
| 577 | 579 | static void ip22zilog_start_tx(struct uart_port *port) |
| 578 | 580 | { |
| 579 | − struct uart_ip22zilog_port *up = (struct uart_ip22zilog_port *) port; | |
| 581 | + struct uart_ip22zilog_port *up = | |
| 582 | + container_of(port, struct uart_ip22zilog_port, port); | |
| 580 | 583 | struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port); |
| 581 | 584 | unsigned char status; |
| 582 | 585 | |
| @@ -636,7 +639,8 @@ static void ip22zilog_stop_rx(struct uart_port *port) · 53 unmodified lines | ||
| 636 | 639 | /* The port lock is held. */ |
| 637 | 640 | static void ip22zilog_enable_ms(struct uart_port *port) |
| 638 | 641 | { |
| 639 | − struct uart_ip22zilog_port *up = (struct uart_ip22zilog_port *) port; | |
| 642 | + struct uart_ip22zilog_port *up = | |
| 643 | + container_of(port, struct uart_ip22zilog_port, port); | |
| 640 | 644 | struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port); |
| 641 | 645 | unsigned char new_reg; |
| 642 | 646 | |
| @@ -652,7 +656,8 @@ static void ip22zilog_enable_ms(struct uart_port *port) · 9 unmodified lines | ||
| 652 | 656 | /* The port lock is not held. */ |
| 653 | 657 | static void ip22zilog_break_ctl(struct uart_port *port, int break_state) |
| 654 | 658 | { |
| 655 | − struct uart_ip22zilog_port *up = (struct uart_ip22zilog_port *) port; | |
| 659 | + struct uart_ip22zilog_port *up = | |
| 660 | + container_of(port, struct uart_ip22zilog_port, port); | |
| 656 | 661 | struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port); |
| 657 | 662 | unsigned char set_bits, clear_bits, new_reg; |
| 658 | 663 | unsigned long flags; |
| @@ -873,7 +878,8 @@ static void · 214 unmodified lines | ||
| 873 | 878 | ip22zilog_set_termios(struct uart_port *port, struct ktermios *termios, |
| 874 | 879 | struct ktermios *old) |
| 875 | 880 | { |
| 876 | − struct uart_ip22zilog_port *up = (struct uart_ip22zilog_port *) port; | |
| 881 | + struct uart_ip22zilog_port *up = | |
| 882 | + container_of(port, struct uart_ip22zilog_port, port); | |
| 877 | 883 | unsigned long flags; |
| 878 | 884 | int baud, brg; |
| 879 | 885 | |
| @@ -4,5 +4,5 @@ · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | obj-$(CONFIG_SERIAL_JSM) += jsm.o |
| 6 | 6 | |
| 7 | −jsm-objs := jsm_driver.o jsm_neo.o jsm_tty.o | |
| 7 | +jsm-objs := jsm_driver.o jsm_neo.o jsm_tty.o jsm_cls.o | |
| 8 | 8 | |
| @@ -13,11 +13,6 @@ · 12 unmodified lines | ||
| 13 | 13 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
| 14 | 14 | * PURPOSE. See the GNU General Public License for more details. |
| 15 | 15 | * |
| 16 | − * You should have received a copy of the GNU General Public License | |
| 17 | − * along with this program; if not, write to the Free Software | |
| 18 | − * Foundation, Inc., 59 * Temple Place - Suite 330, Boston, | |
| 19 | − * MA 02111-1307, USA. | |
| 20 | − * | |
| 21 | 16 | * Contact Information: |
| 22 | 17 | * Scott H Kilau <Scott_Kilau@digi.com> |
| 23 | 18 | * Wendy Xiong <wendyx@us.ibm.com> |
| @@ -68,6 +63,10 @@ do { \ · 44 unmodified lines | ||
| 68 | 63 | #define MAX_STOPS_SENT 5 |
| 69 | 64 | |
| 70 | 65 | /* Board ids */ |
| 66 | +#define PCI_DEVICE_ID_CLASSIC_4 0x0028 | |
| 67 | +#define PCI_DEVICE_ID_CLASSIC_8 0x0029 | |
| 68 | +#define PCI_DEVICE_ID_CLASSIC_4_422 0x00D0 | |
| 69 | +#define PCI_DEVICE_ID_CLASSIC_8_422 0x00D1 | |
| 71 | 70 | #define PCI_DEVICE_ID_NEO_4 0x00B0 |
| 72 | 71 | #define PCI_DEVICE_ID_NEO_1_422 0x00CC |
| 73 | 72 | #define PCI_DEVICE_ID_NEO_1_422_485 0x00CD |
| @@ -112,21 +111,21 @@ struct jsm_channel; · 38 unmodified lines | ||
| 112 | 111 | ************************************************************************/ |
| 113 | 112 | struct board_ops { |
| 114 | 113 | irq_handler_t intr; |
| 115 | − void (*uart_init) (struct jsm_channel *ch); | |
| 116 | − void (*uart_off) (struct jsm_channel *ch); | |
| 117 | − void (*param) (struct jsm_channel *ch); | |
| 118 | − void (*assert_modem_signals) (struct jsm_channel *ch); | |
| 119 | − void (*flush_uart_write) (struct jsm_channel *ch); | |
| 120 | − void (*flush_uart_read) (struct jsm_channel *ch); | |
| 121 | − void (*disable_receiver) (struct jsm_channel *ch); | |
| 122 | − void (*enable_receiver) (struct jsm_channel *ch); | |
| 123 | − void (*send_break) (struct jsm_channel *ch); | |
| 124 | − void (*clear_break) (struct jsm_channel *ch, int); | |
| 125 | − void (*send_start_character) (struct jsm_channel *ch); | |
| 126 | − void (*send_stop_character) (struct jsm_channel *ch); | |
| 127 | − void (*copy_data_from_queue_to_uart) (struct jsm_channel *ch); | |
| 128 | − u32 (*get_uart_bytes_left) (struct jsm_channel *ch); | |
| 129 | − void (*send_immediate_char) (struct jsm_channel *ch, unsigned char); | |
| 114 | + void (*uart_init)(struct jsm_channel *ch); | |
| 115 | + void (*uart_off)(struct jsm_channel *ch); | |
| 116 | + void (*param)(struct jsm_channel *ch); | |
| 117 | + void (*assert_modem_signals)(struct jsm_channel *ch); | |
| 118 | + void (*flush_uart_write)(struct jsm_channel *ch); | |
| 119 | + void (*flush_uart_read)(struct jsm_channel *ch); | |
| 120 | + void (*disable_receiver)(struct jsm_channel *ch); | |
| 121 | + void (*enable_receiver)(struct jsm_channel *ch); | |
| 122 | + void (*send_break)(struct jsm_channel *ch); | |
| 123 | + void (*clear_break)(struct jsm_channel *ch); | |
| 124 | + void (*send_start_character)(struct jsm_channel *ch); | |
| 125 | + void (*send_stop_character)(struct jsm_channel *ch); | |
| 126 | + void (*copy_data_from_queue_to_uart)(struct jsm_channel *ch); | |
| 127 | + u32 (*get_uart_bytes_left)(struct jsm_channel *ch); | |
| 128 | + void (*send_immediate_char)(struct jsm_channel *ch, unsigned char); | |
| 130 | 129 | }; |
| 131 | 130 | |
| 132 | 131 | |
| @@ -189,7 +188,7 @@ struct jsm_board · 56 unmodified lines | ||
| 189 | 188 | #define CH_LOOPBACK 0x2000 /* Channel is in lookback mode */ |
| 190 | 189 | #define CH_BAUD0 0x08000 /* Used for checking B0 transitions */ |
| 191 | 190 | |
| 192 | −/* Our Read/Error/Write queue sizes */ | |
| 191 | +/* Our Read/Error queue sizes */ | |
| 193 | 192 | #define RQUEUEMASK 0x1FFF /* 8 K - 1 */ |
| 194 | 193 | #define EQUEUEMASK 0x1FFF /* 8 K - 1 */ |
| 195 | 194 | #define RQUEUESIZE (RQUEUEMASK + 1) |
| @@ -222,7 +221,10 @@ struct jsm_channel { · 26 unmodified lines | ||
| 222 | 221 | u8 ch_mostat; /* FEP output modem status */ |
| 223 | 222 | u8 ch_mistat; /* FEP input modem status */ |
| 224 | 223 | |
| 225 | − struct neo_uart_struct __iomem *ch_neo_uart; /* Pointer to the "mapped" UART struct */ | |
| 224 | + /* Pointers to the "mapped" UART structs */ | |
| 225 | + struct neo_uart_struct __iomem *ch_neo_uart; /* NEO card */ | |
| 226 | + struct cls_uart_struct __iomem *ch_cls_uart; /* Classic card */ | |
| 227 | + | |
| 226 | 228 | u8 ch_cached_lsr; /* Cached value of the LSR register */ |
| 227 | 229 | |
| 228 | 230 | u8 *ch_rqueue; /* Our read queue buffer - malloc'ed */ |
| @@ -254,6 +256,60 @@ struct jsm_channel { · 25 unmodified lines | ||
| 254 | 256 | u64 ch_xoff_sends; /* Count of xoffs transmitted */ |
| 255 | 257 | }; |
| 256 | 258 | |
| 259 | +/************************************************************************ | |
| 260 | + * Per channel/port Classic UART structures * | |
| 261 | + ************************************************************************ | |
| 262 | + * Base Structure Entries Usage Meanings to Host * | |
| 263 | + * * | |
| 264 | + * W = read write R = read only * | |
| 265 | + * U = Unused. * | |
| 266 | + ************************************************************************/ | |
| 267 | + | |
| 268 | +struct cls_uart_struct { | |
| 269 | + u8 txrx; /* WR RHR/THR - Holding Reg */ | |
| 270 | + u8 ier; /* WR IER - Interrupt Enable Reg */ | |
| 271 | + u8 isr_fcr; /* WR ISR/FCR - Interrupt Status Reg/Fifo Control Reg*/ | |
| 272 | + u8 lcr; /* WR LCR - Line Control Reg */ | |
| 273 | + u8 mcr; /* WR MCR - Modem Control Reg */ | |
| 274 | + u8 lsr; /* WR LSR - Line Status Reg */ | |
| 275 | + u8 msr; /* WR MSR - Modem Status Reg */ | |
| 276 | + u8 spr; /* WR SPR - Scratch Pad Reg */ | |
| 277 | +}; | |
| 278 | + | |
| 279 | +/* Where to read the interrupt register (8bits) */ | |
| 280 | +#define UART_CLASSIC_POLL_ADDR_OFFSET 0x40 | |
| 281 | + | |
| 282 | +#define UART_EXAR654_ENHANCED_REGISTER_SET 0xBF | |
| 283 | + | |
| 284 | +#define UART_16654_FCR_TXTRIGGER_8 0x0 | |
| 285 | +#define UART_16654_FCR_TXTRIGGER_16 0x10 | |
| 286 | +#define UART_16654_FCR_TXTRIGGER_32 0x20 | |
| 287 | +#define UART_16654_FCR_TXTRIGGER_56 0x30 | |
| 288 | + | |
| 289 | +#define UART_16654_FCR_RXTRIGGER_8 0x0 | |
| 290 | +#define UART_16654_FCR_RXTRIGGER_16 0x40 | |
| 291 | +#define UART_16654_FCR_RXTRIGGER_56 0x80 | |
| 292 | +#define UART_16654_FCR_RXTRIGGER_60 0xC0 | |
| 293 | + | |
| 294 | +#define UART_IIR_CTSRTS 0x20 /* Received CTS/RTS change of state */ | |
| 295 | +#define UART_IIR_RDI_TIMEOUT 0x0C /* Receiver data TIMEOUT */ | |
| 296 | + | |
| 297 | +/* | |
| 298 | + * These are the EXTENDED definitions for the Exar 654's Interrupt | |
| 299 | + * Enable Register. | |
| 300 | + */ | |
| 301 | +#define UART_EXAR654_EFR_ECB 0x10 /* Enhanced control bit */ | |
| 302 | +#define UART_EXAR654_EFR_IXON 0x2 /* Receiver compares Xon1/Xoff1 */ | |
| 303 | +#define UART_EXAR654_EFR_IXOFF 0x8 /* Transmit Xon1/Xoff1 */ | |
| 304 | +#define UART_EXAR654_EFR_RTSDTR 0x40 /* Auto RTS/DTR Flow Control Enable */ | |
| 305 | +#define UART_EXAR654_EFR_CTSDSR 0x80 /* Auto CTS/DSR Flow COntrol Enable */ | |
| 306 | + | |
| 307 | +#define UART_EXAR654_XOFF_DETECT 0x1 /* Indicates whether chip saw an incoming XOFF char */ | |
| 308 | +#define UART_EXAR654_XON_DETECT 0x2 /* Indicates whether chip saw an incoming XON char */ | |
| 309 | + | |
| 310 | +#define UART_EXAR654_IER_XOFF 0x20 /* Xoff Interrupt Enable */ | |
| 311 | +#define UART_EXAR654_IER_RTSDTR 0x40 /* Output Interrupt Enable */ | |
| 312 | +#define UART_EXAR654_IER_CTSDSR 0x80 /* Input Interrupt Enable */ | |
| 257 | 313 | |
| 258 | 314 | /************************************************************************ |
| 259 | 315 | * Per channel/port NEO UART structure * |
| @@ -374,6 +430,7 @@ struct neo_uart_struct { · 114 unmodified lines | ||
| 374 | 430 | */ |
| 375 | 431 | extern struct uart_driver jsm_uart_driver; |
| 376 | 432 | extern struct board_ops jsm_neo_ops; |
| 433 | +extern struct board_ops jsm_cls_ops; | |
| 377 | 434 | extern int jsm_debug; |
| 378 | 435 | |
| 379 | 436 | /************************************************************************* |
| @@ -0,0 +1,982 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2003 Digi International (www.digi.com) | |
| 3 | + * Scott H Kilau <Scott_Kilau at digi dot com> | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify | |
| 6 | + * it under the terms of the GNU General Public License as published by | |
| 7 | + * the Free Software Foundation; either version 2, or (at your option) | |
| 8 | + * any later version. | |
| 9 | + * | |
| 10 | + * This program is distributed in the hope that it will be useful, | |
| 11 | + * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the | |
| 12 | + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |
| 13 | + * PURPOSE. See the GNU General Public License for more details. | |
| 14 | + * | |
| 15 | + * NOTE TO LINUX KERNEL HACKERS: DO NOT REFORMAT THIS CODE! | |
| 16 | + * | |
| 17 | + * This is shared code between Digi's CVS archive and the | |
| 18 | + * Linux Kernel sources. | |
| 19 | + * Changing the source just for reformatting needlessly breaks | |
| 20 | + * our CVS diff history. | |
| 21 | + * | |
| 22 | + * Send any bug fixes/changes to: Eng.Linux at digi dot com. | |
| 23 | + * Thank you. | |
| 24 | + * | |
| 25 | + */ | |
| 26 | + | |
| 27 | +#include <linux/delay.h> /* For udelay */ | |
| 28 | +#include <linux/io.h> /* For read[bwl]/write[bwl] */ | |
| 29 | +#include <linux/serial.h> /* For struct async_serial */ | |
| 30 | +#include <linux/serial_reg.h> /* For the various UART offsets */ | |
| 31 | +#include <linux/pci.h> | |
| 32 | +#include <linux/tty.h> | |
| 33 | + | |
| 34 | +#include "jsm.h" /* Driver main header file */ | |
| 35 | + | |
| 36 | +static struct { | |
| 37 | + unsigned int rate; | |
| 38 | + unsigned int cflag; | |
| 39 | +} baud_rates[] = { | |
| 40 | + { 921600, B921600 }, | |
| 41 | + { 460800, B460800 }, | |
| 42 | + { 230400, B230400 }, | |
| 43 | + { 115200, B115200 }, | |
| 44 | + { 57600, B57600 }, | |
| 45 | + { 38400, B38400 }, | |
| 46 | + { 19200, B19200 }, | |
| 47 | + { 9600, B9600 }, | |
| 48 | + { 4800, B4800 }, | |
| 49 | + { 2400, B2400 }, | |
| 50 | + { 1200, B1200 }, | |
| 51 | + { 600, B600 }, | |
| 52 | + { 300, B300 }, | |
| 53 | + { 200, B200 }, | |
| 54 | + { 150, B150 }, | |
| 55 | + { 134, B134 }, | |
| 56 | + { 110, B110 }, | |
| 57 | + { 75, B75 }, | |
| 58 | + { 50, B50 }, | |
| 59 | +}; | |
| 60 | + | |
| 61 | +static void cls_set_cts_flow_control(struct jsm_channel *ch) | |
| 62 | +{ | |
| 63 | + u8 lcrb = readb(&ch->ch_cls_uart->lcr); | |
| 64 | + u8 ier = readb(&ch->ch_cls_uart->ier); | |
| 65 | + u8 isr_fcr = 0; | |
| 66 | + | |
| 67 | + /* | |
| 68 | + * The Enhanced Register Set may only be accessed when | |
| 69 | + * the Line Control Register is set to 0xBFh. | |
| 70 | + */ | |
| 71 | + writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr); | |
| 72 | + | |
| 73 | + isr_fcr = readb(&ch->ch_cls_uart->isr_fcr); | |
| 74 | + | |
| 75 | + /* Turn on CTS flow control, turn off IXON flow control */ | |
| 76 | + isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_CTSDSR); | |
| 77 | + isr_fcr &= ~(UART_EXAR654_EFR_IXON); | |
| 78 | + | |
| 79 | + writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr); | |
| 80 | + | |
| 81 | + /* Write old LCR value back out, which turns enhanced access off */ | |
| 82 | + writeb(lcrb, &ch->ch_cls_uart->lcr); | |
| 83 | + | |
| 84 | + /* | |
| 85 | + * Enable interrupts for CTS flow, turn off interrupts for | |
| 86 | + * received XOFF chars | |
| 87 | + */ | |
| 88 | + ier |= (UART_EXAR654_IER_CTSDSR); | |
| 89 | + ier &= ~(UART_EXAR654_IER_XOFF); | |
| 90 | + writeb(ier, &ch->ch_cls_uart->ier); | |
| 91 | + | |
| 92 | + /* Set the usual FIFO values */ | |
| 93 | + writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr); | |
| 94 | + | |
| 95 | + writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_56 | | |
| 96 | + UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR), | |
| 97 | + &ch->ch_cls_uart->isr_fcr); | |
| 98 | + | |
| 99 | + ch->ch_t_tlevel = 16; | |
| 100 | +} | |
| 101 | + | |
| 102 | +static void cls_set_ixon_flow_control(struct jsm_channel *ch) | |
| 103 | +{ | |
| 104 | + u8 lcrb = readb(&ch->ch_cls_uart->lcr); | |
| 105 | + u8 ier = readb(&ch->ch_cls_uart->ier); | |
| 106 | + u8 isr_fcr = 0; | |
| 107 | + | |
| 108 | + /* | |
| 109 | + * The Enhanced Register Set may only be accessed when | |
| 110 | + * the Line Control Register is set to 0xBFh. | |
| 111 | + */ | |
| 112 | + writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr); | |
| 113 | + | |
| 114 | + isr_fcr = readb(&ch->ch_cls_uart->isr_fcr); | |
| 115 | + | |
| 116 | + /* Turn on IXON flow control, turn off CTS flow control */ | |
| 117 | + isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_IXON); | |
| 118 | + isr_fcr &= ~(UART_EXAR654_EFR_CTSDSR); | |
| 119 | + | |
| 120 | + writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr); | |
| 121 | + | |
| 122 | + /* Now set our current start/stop chars while in enhanced mode */ | |
| 123 | + writeb(ch->ch_startc, &ch->ch_cls_uart->mcr); | |
| 124 | + writeb(0, &ch->ch_cls_uart->lsr); | |
| 125 | + writeb(ch->ch_stopc, &ch->ch_cls_uart->msr); | |
| 126 | + writeb(0, &ch->ch_cls_uart->spr); | |
| 127 | + | |
| 128 | + /* Write old LCR value back out, which turns enhanced access off */ | |
| 129 | + writeb(lcrb, &ch->ch_cls_uart->lcr); | |
| 130 | + | |
| 131 | + /* | |
| 132 | + * Disable interrupts for CTS flow, turn on interrupts for | |
| 133 | + * received XOFF chars | |
| 134 | + */ | |
| 135 | + ier &= ~(UART_EXAR654_IER_CTSDSR); | |
| 136 | + ier |= (UART_EXAR654_IER_XOFF); | |
| 137 | + writeb(ier, &ch->ch_cls_uart->ier); | |
| 138 | + | |
| 139 | + /* Set the usual FIFO values */ | |
| 140 | + writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr); | |
| 141 | + | |
| 142 | + writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 | | |
| 143 | + UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR), | |
| 144 | + &ch->ch_cls_uart->isr_fcr); | |
| 145 | +} | |
| 146 | + | |
| 147 | +static void cls_set_no_output_flow_control(struct jsm_channel *ch) | |
| 148 | +{ | |
| 149 | + u8 lcrb = readb(&ch->ch_cls_uart->lcr); | |
| 150 | + u8 ier = readb(&ch->ch_cls_uart->ier); | |
| 151 | + u8 isr_fcr = 0; | |
| 152 | + | |
| 153 | + /* | |
| 154 | + * The Enhanced Register Set may only be accessed when | |
| 155 | + * the Line Control Register is set to 0xBFh. | |
| 156 | + */ | |
| 157 | + writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr); | |
| 158 | + | |
| 159 | + isr_fcr = readb(&ch->ch_cls_uart->isr_fcr); | |
| 160 | + | |
| 161 | + /* Turn off IXON flow control, turn off CTS flow control */ | |
| 162 | + isr_fcr |= (UART_EXAR654_EFR_ECB); | |
| 163 | + isr_fcr &= ~(UART_EXAR654_EFR_CTSDSR | UART_EXAR654_EFR_IXON); | |
| 164 | + | |
| 165 | + writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr); | |
| 166 | + | |
| 167 | + /* Write old LCR value back out, which turns enhanced access off */ | |
| 168 | + writeb(lcrb, &ch->ch_cls_uart->lcr); | |
| 169 | + | |
| 170 | + /* | |
| 171 | + * Disable interrupts for CTS flow, turn off interrupts for | |
| 172 | + * received XOFF chars | |
| 173 | + */ | |
| 174 | + ier &= ~(UART_EXAR654_IER_CTSDSR); | |
| 175 | + ier &= ~(UART_EXAR654_IER_XOFF); | |
| 176 | + writeb(ier, &ch->ch_cls_uart->ier); | |
| 177 | + | |
| 178 | + /* Set the usual FIFO values */ | |
| 179 | + writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr); | |
| 180 | + | |
| 181 | + writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 | | |
| 182 | + UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR), | |
| 183 | + &ch->ch_cls_uart->isr_fcr); | |
| 184 | + | |
| 185 | + ch->ch_r_watermark = 0; | |
| 186 | + ch->ch_t_tlevel = 16; | |
| 187 | + ch->ch_r_tlevel = 16; | |
| 188 | +} | |
| 189 | + | |
| 190 | +static void cls_set_rts_flow_control(struct jsm_channel *ch) | |
| 191 | +{ | |
| 192 | + u8 lcrb = readb(&ch->ch_cls_uart->lcr); | |
| 193 | + u8 ier = readb(&ch->ch_cls_uart->ier); | |
| 194 | + u8 isr_fcr = 0; | |
| 195 | + | |
| 196 | + /* | |
| 197 | + * The Enhanced Register Set may only be accessed when | |
| 198 | + * the Line Control Register is set to 0xBFh. | |
| 199 | + */ | |
| 200 | + writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr); | |
| 201 | + | |
| 202 | + isr_fcr = readb(&ch->ch_cls_uart->isr_fcr); | |
| 203 | + | |
| 204 | + /* Turn on RTS flow control, turn off IXOFF flow control */ | |
| 205 | + isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_RTSDTR); | |
| 206 | + isr_fcr &= ~(UART_EXAR654_EFR_IXOFF); | |
| 207 | + | |
| 208 | + writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr); | |
| 209 | + | |
| 210 | + /* Write old LCR value back out, which turns enhanced access off */ | |
| 211 | + writeb(lcrb, &ch->ch_cls_uart->lcr); | |
| 212 | + | |
| 213 | + /* Enable interrupts for RTS flow */ | |
| 214 | + ier |= (UART_EXAR654_IER_RTSDTR); | |
| 215 | + writeb(ier, &ch->ch_cls_uart->ier); | |
| 216 | + | |
| 217 | + /* Set the usual FIFO values */ | |
| 218 | + writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr); | |
| 219 | + | |
| 220 | + writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_56 | | |
| 221 | + UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR), | |
| 222 | + &ch->ch_cls_uart->isr_fcr); | |
| 223 | + | |
| 224 | + ch->ch_r_watermark = 4; | |
| 225 | + ch->ch_r_tlevel = 8; | |
| 226 | +} | |
| 227 | + | |
| 228 | +static void cls_set_ixoff_flow_control(struct jsm_channel *ch) | |
| 229 | +{ | |
| 230 | + u8 lcrb = readb(&ch->ch_cls_uart->lcr); | |
| 231 | + u8 ier = readb(&ch->ch_cls_uart->ier); | |
| 232 | + u8 isr_fcr = 0; | |
| 233 | + | |
| 234 | + /* | |
| 235 | + * The Enhanced Register Set may only be accessed when | |
| 236 | + * the Line Control Register is set to 0xBFh. | |
| 237 | + */ | |
| 238 | + writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr); | |
| 239 | + | |
| 240 | + isr_fcr = readb(&ch->ch_cls_uart->isr_fcr); | |
| 241 | + | |
| 242 | + /* Turn on IXOFF flow control, turn off RTS flow control */ | |
| 243 | + isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_IXOFF); | |
| 244 | + isr_fcr &= ~(UART_EXAR654_EFR_RTSDTR); | |
| 245 | + | |
| 246 | + writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr); | |
| 247 | + | |
| 248 | + /* Now set our current start/stop chars while in enhanced mode */ | |
| 249 | + writeb(ch->ch_startc, &ch->ch_cls_uart->mcr); | |
| 250 | + writeb(0, &ch->ch_cls_uart->lsr); | |
| 251 | + writeb(ch->ch_stopc, &ch->ch_cls_uart->msr); | |
| 252 | + writeb(0, &ch->ch_cls_uart->spr); | |
| 253 | + | |
| 254 | + /* Write old LCR value back out, which turns enhanced access off */ | |
| 255 | + writeb(lcrb, &ch->ch_cls_uart->lcr); | |
| 256 | + | |
| 257 | + /* Disable interrupts for RTS flow */ | |
| 258 | + ier &= ~(UART_EXAR654_IER_RTSDTR); | |
| 259 | + writeb(ier, &ch->ch_cls_uart->ier); | |
| 260 | + | |
| 261 | + /* Set the usual FIFO values */ | |
| 262 | + writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr); | |
| 263 | + | |
| 264 | + writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 | | |
| 265 | + UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR), | |
| 266 | + &ch->ch_cls_uart->isr_fcr); | |
| 267 | +} | |
| 268 | + | |
| 269 | +static void cls_set_no_input_flow_control(struct jsm_channel *ch) | |
| 270 | +{ | |
| 271 | + u8 lcrb = readb(&ch->ch_cls_uart->lcr); | |
| 272 | + u8 ier = readb(&ch->ch_cls_uart->ier); | |
| 273 | + u8 isr_fcr = 0; | |
| 274 | + | |
| 275 | + /* | |
| 276 | + * The Enhanced Register Set may only be accessed when | |
| 277 | + * the Line Control Register is set to 0xBFh. | |
| 278 | + */ | |
| 279 | + writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr); | |
| 280 | + | |
| 281 | + isr_fcr = readb(&ch->ch_cls_uart->isr_fcr); | |
| 282 | + | |
| 283 | + /* Turn off IXOFF flow control, turn off RTS flow control */ | |
| 284 | + isr_fcr |= (UART_EXAR654_EFR_ECB); | |
| 285 | + isr_fcr &= ~(UART_EXAR654_EFR_RTSDTR | UART_EXAR654_EFR_IXOFF); | |
| 286 | + | |
| 287 | + writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr); | |
| 288 | + | |
| 289 | + /* Write old LCR value back out, which turns enhanced access off */ | |
| 290 | + writeb(lcrb, &ch->ch_cls_uart->lcr); | |
| 291 | + | |
| 292 | + /* Disable interrupts for RTS flow */ | |
| 293 | + ier &= ~(UART_EXAR654_IER_RTSDTR); | |
| 294 | + writeb(ier, &ch->ch_cls_uart->ier); | |
| 295 | + | |
| 296 | + /* Set the usual FIFO values */ | |
| 297 | + writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr); | |
| 298 | + | |
| 299 | + writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 | | |
| 300 | + UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR), | |
| 301 | + &ch->ch_cls_uart->isr_fcr); | |
| 302 | + | |
| 303 | + ch->ch_t_tlevel = 16; | |
| 304 | + ch->ch_r_tlevel = 16; | |
| 305 | +} | |
| 306 | + | |
| 307 | +/* | |
| 308 | + * cls_clear_break. | |
| 309 | + * Determines whether its time to shut off break condition. | |
| 310 | + * | |
| 311 | + * No locks are assumed to be held when calling this function. | |
| 312 | + * channel lock is held and released in this function. | |
| 313 | + */ | |
| 314 | +static void cls_clear_break(struct jsm_channel *ch) | |
| 315 | +{ | |
| 316 | + unsigned long lock_flags; | |
| 317 | + | |
| 318 | + spin_lock_irqsave(&ch->ch_lock, lock_flags); | |
| 319 | + | |
| 320 | + /* Turn break off, and unset some variables */ | |
| 321 | + if (ch->ch_flags & CH_BREAK_SENDING) { | |
| 322 | + u8 temp = readb(&ch->ch_cls_uart->lcr); | |
| 323 | + | |
| 324 | + writeb((temp & ~UART_LCR_SBC), &ch->ch_cls_uart->lcr); | |
| 325 | + | |
| 326 | + ch->ch_flags &= ~(CH_BREAK_SENDING); | |
| 327 | + jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, | |
| 328 | + "clear break Finishing UART_LCR_SBC! finished: %lx\n", | |
| 329 | + jiffies); | |
| 330 | + } | |
| 331 | + spin_unlock_irqrestore(&ch->ch_lock, lock_flags); | |
| 332 | +} | |
| 333 | + | |
| 334 | +static void cls_disable_receiver(struct jsm_channel *ch) | |
| 335 | +{ | |
| 336 | + u8 tmp = readb(&ch->ch_cls_uart->ier); | |
| 337 | + | |
| 338 | + tmp &= ~(UART_IER_RDI); | |
| 339 | + writeb(tmp, &ch->ch_cls_uart->ier); | |
| 340 | +} | |
| 341 | + | |
| 342 | +static void cls_enable_receiver(struct jsm_channel *ch) | |
| 343 | +{ | |
| 344 | + u8 tmp = readb(&ch->ch_cls_uart->ier); | |
| 345 | + | |
| 346 | + tmp |= (UART_IER_RDI); | |
| 347 | + writeb(tmp, &ch->ch_cls_uart->ier); | |
| 348 | +} | |
| 349 | + | |
| 350 | +/* Make the UART raise any of the output signals we want up */ | |
| 351 | +static void cls_assert_modem_signals(struct jsm_channel *ch) | |
| 352 | +{ | |
| 353 | + if (!ch) | |
| 354 | + return; | |
| 355 | + | |
| 356 | + writeb(ch->ch_mostat, &ch->ch_cls_uart->mcr); | |
| 357 | +} | |
| 358 | + | |
| 359 | +static void cls_copy_data_from_uart_to_queue(struct jsm_channel *ch) | |
| 360 | +{ | |
| 361 | + int qleft = 0; | |
| 362 | + u8 linestatus = 0; | |
| 363 | + u8 error_mask = 0; | |
| 364 | + u16 head; | |
| 365 | + u16 tail; | |
| 366 | + unsigned long flags; | |
| 367 | + | |
| 368 | + if (!ch) | |
| 369 | + return; | |
| 370 | + | |
| 371 | + spin_lock_irqsave(&ch->ch_lock, flags); | |
| 372 | + | |
| 373 | + /* cache head and tail of queue */ | |
| 374 | + head = ch->ch_r_head & RQUEUEMASK; | |
| 375 | + tail = ch->ch_r_tail & RQUEUEMASK; | |
| 376 | + | |
| 377 | + /* Get our cached LSR */ | |
| 378 | + linestatus = ch->ch_cached_lsr; | |
| 379 | + ch->ch_cached_lsr = 0; | |
| 380 | + | |
| 381 | + /* Store how much space we have left in the queue */ | |
| 382 | + qleft = tail - head - 1; | |
| 383 | + if (qleft < 0) | |
| 384 | + qleft += RQUEUEMASK + 1; | |
| 385 | + | |
| 386 | + /* | |
| 387 | + * Create a mask to determine whether we should | |
| 388 | + * insert the character (if any) into our queue. | |
| 389 | + */ | |
| 390 | + if (ch->ch_c_iflag & IGNBRK) | |
| 391 | + error_mask |= UART_LSR_BI; | |
| 392 | + | |
| 393 | + while (1) { | |
| 394 | + /* | |
| 395 | + * Grab the linestatus register, we need to | |
| 396 | + * check to see if there is any data to read | |
| 397 | + */ | |
| 398 | + linestatus = readb(&ch->ch_cls_uart->lsr); | |
| 399 | + | |
| 400 | + /* Break out if there is no data to fetch */ | |
| 401 | + if (!(linestatus & UART_LSR_DR)) | |
| 402 | + break; | |
| 403 | + | |
| 404 | + /* | |
| 405 | + * Discard character if we are ignoring the error mask | |
| 406 | + * which in this case is the break signal. | |
| 407 | + */ | |
| 408 | + if (linestatus & error_mask) { | |
| 409 | + u8 discard; | |
| 410 | + | |
| 411 | + linestatus = 0; | |
| 412 | + discard = readb(&ch->ch_cls_uart->txrx); | |
| 413 | + continue; | |
| 414 | + } | |
| 415 | + | |
| 416 | + /* | |
| 417 | + * If our queue is full, we have no choice but to drop some | |
| 418 | + * data. The assumption is that HWFLOW or SWFLOW should have | |
| 419 | + * stopped things way way before we got to this point. | |
| 420 | + * | |
| 421 | + * I decided that I wanted to ditch the oldest data first, | |
| 422 | + * I hope thats okay with everyone? Yes? Good. | |
| 423 | + */ | |
| 424 | + while (qleft < 1) { | |
| 425 | + tail = (tail + 1) & RQUEUEMASK; | |
| 426 | + ch->ch_r_tail = tail; | |
| 427 | + ch->ch_err_overrun++; | |
| 428 | + qleft++; | |
| 429 | + } | |
| 430 | + | |
| 431 | + ch->ch_equeue[head] = linestatus & (UART_LSR_BI | UART_LSR_PE | |
| 432 | + | UART_LSR_FE); | |
| 433 | + ch->ch_rqueue[head] = readb(&ch->ch_cls_uart->txrx); | |
| 434 | + | |
| 435 | + qleft--; | |
| 436 | + | |
| 437 | + if (ch->ch_equeue[head] & UART_LSR_PE) | |
| 438 | + ch->ch_err_parity++; | |
| 439 | + if (ch->ch_equeue[head] & UART_LSR_BI) | |
| 440 | + ch->ch_err_break++; | |
| 441 | + if (ch->ch_equeue[head] & UART_LSR_FE) | |
| 442 | + ch->ch_err_frame++; | |
| 443 | + | |
| 444 | + /* Add to, and flip head if needed */ | |
| 445 | + head = (head + 1) & RQUEUEMASK; | |
| 446 | + ch->ch_rxcount++; | |
| 447 | + } | |
| 448 | + | |
| 449 | + /* | |
| 450 | + * Write new final heads to channel structure. | |
| 451 | + */ | |
| 452 | + ch->ch_r_head = head & RQUEUEMASK; | |
| 453 | + ch->ch_e_head = head & EQUEUEMASK; | |
| 454 | + | |
| 455 | + spin_unlock_irqrestore(&ch->ch_lock, flags); | |
| 456 | +} | |
| 457 | + | |
| 458 | +static void cls_copy_data_from_queue_to_uart(struct jsm_channel *ch) | |
| 459 | +{ | |
| 460 | + u16 tail; | |
| 461 | + int n; | |
| 462 | + int qlen; | |
| 463 | + u32 len_written = 0; | |
| 464 | + struct circ_buf *circ; | |
| 465 | + | |
| 466 | + if (!ch) | |
| 467 | + return; | |
| 468 | + | |
| 469 | + circ = &ch->uart_port.state->xmit; | |
| 470 | + | |
| 471 | + /* No data to write to the UART */ | |
| 472 | + if (uart_circ_empty(circ)) | |
| 473 | + return; | |
| 474 | + | |
| 475 | + /* If port is "stopped", don't send any data to the UART */ | |
| 476 | + if ((ch->ch_flags & CH_STOP) || (ch->ch_flags & CH_BREAK_SENDING)) | |
| 477 | + return; | |
| 478 | + | |
| 479 | + /* We have to do it this way, because of the EXAR TXFIFO count bug. */ | |
| 480 | + if (!(ch->ch_flags & (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM))) | |
| 481 | + return; | |
| 482 | + | |
| 483 | + n = 32; | |
| 484 | + | |
| 485 | + /* cache tail of queue */ | |
| 486 | + tail = circ->tail & (UART_XMIT_SIZE - 1); | |
| 487 | + qlen = uart_circ_chars_pending(circ); | |
| 488 | + | |
| 489 | + /* Find minimum of the FIFO space, versus queue length */ | |
| 490 | + n = min(n, qlen); | |
| 491 | + | |
| 492 | + while (n > 0) { | |
| 493 | + writeb(circ->buf[tail], &ch->ch_cls_uart->txrx); | |
| 494 | + tail = (tail + 1) & (UART_XMIT_SIZE - 1); | |
| 495 | + n--; | |
| 496 | + ch->ch_txcount++; | |
| 497 | + len_written++; | |
| 498 | + } | |
| 499 | + | |
| 500 | + /* Update the final tail */ | |
| 501 | + circ->tail = tail & (UART_XMIT_SIZE - 1); | |
| 502 | + | |
| 503 | + if (len_written > ch->ch_t_tlevel) | |
| 504 | + ch->ch_flags &= ~(CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); | |
| 505 | + | |
| 506 | + if (uart_circ_empty(circ)) | |
| 507 | + uart_write_wakeup(&ch->uart_port); | |
| 508 | +} | |
| 509 | + | |
| 510 | +static void cls_parse_modem(struct jsm_channel *ch, u8 signals) | |
| 511 | +{ | |
| 512 | + u8 msignals = signals; | |
| 513 | + | |
| 514 | + jsm_dbg(MSIGS, &ch->ch_bd->pci_dev, | |
| 515 | + "neo_parse_modem: port: %d msignals: %x\n", | |
| 516 | + ch->ch_portnum, msignals); | |
| 517 | + | |
| 518 | + /* | |
| 519 | + * Scrub off lower bits. | |
| 520 | + * They signify delta's, which I don't care about | |
| 521 | + * Keep DDCD and DDSR though | |
| 522 | + */ | |
| 523 | + msignals &= 0xf8; | |
| 524 | + | |
| 525 | + if (msignals & UART_MSR_DDCD) | |
| 526 | + uart_handle_dcd_change(&ch->uart_port, msignals & UART_MSR_DCD); | |
| 527 | + if (msignals & UART_MSR_DDSR) | |
| 528 | + uart_handle_dcd_change(&ch->uart_port, msignals & UART_MSR_CTS); | |
| 529 | + | |
| 530 | + if (msignals & UART_MSR_DCD) | |
| 531 | + ch->ch_mistat |= UART_MSR_DCD; | |
| 532 | + else | |
| 533 | + ch->ch_mistat &= ~UART_MSR_DCD; | |
| 534 | + | |
| 535 | + if (msignals & UART_MSR_DSR) | |
| 536 | + ch->ch_mistat |= UART_MSR_DSR; | |
| 537 | + else | |
| 538 | + ch->ch_mistat &= ~UART_MSR_DSR; | |
| 539 | + | |
| 540 | + if (msignals & UART_MSR_RI) | |
| 541 | + ch->ch_mistat |= UART_MSR_RI; | |
| 542 | + else | |
| 543 | + ch->ch_mistat &= ~UART_MSR_RI; | |
| 544 | + | |
| 545 | + if (msignals & UART_MSR_CTS) | |
| 546 | + ch->ch_mistat |= UART_MSR_CTS; | |
| 547 | + else | |
| 548 | + ch->ch_mistat &= ~UART_MSR_CTS; | |
| 549 | + | |
| 550 | + jsm_dbg(MSIGS, &ch->ch_bd->pci_dev, | |
| 551 | + "Port: %d DTR: %d RTS: %d CTS: %d DSR: %d " "RI: %d CD: %d\n", | |
| 552 | + ch->ch_portnum, | |
| 553 | + !!((ch->ch_mistat | ch->ch_mostat) & UART_MCR_DTR), | |
| 554 | + !!((ch->ch_mistat | ch->ch_mostat) & UART_MCR_RTS), | |
| 555 | + !!((ch->ch_mistat | ch->ch_mostat) & UART_MSR_CTS), | |
| 556 | + !!((ch->ch_mistat | ch->ch_mostat) & UART_MSR_DSR), | |
| 557 | + !!((ch->ch_mistat | ch->ch_mostat) & UART_MSR_RI), | |
| 558 | + !!((ch->ch_mistat | ch->ch_mostat) & UART_MSR_DCD)); | |
| 559 | +} | |
| 560 | + | |
| 561 | +/* Parse the ISR register for the specific port */ | |
| 562 | +static inline void cls_parse_isr(struct jsm_board *brd, uint port) | |
| 563 | +{ | |
| 564 | + struct jsm_channel *ch; | |
| 565 | + u8 isr = 0; | |
| 566 | + unsigned long flags; | |
| 567 | + | |
| 568 | + /* | |
| 569 | + * No need to verify board pointer, it was already | |
| 570 | + * verified in the interrupt routine. | |
| 571 | + */ | |
| 572 | + | |
| 573 | + if (port > brd->nasync) | |
| 574 | + return; | |
| 575 | + | |
| 576 | + ch = brd->channels[port]; | |
| 577 | + if (!ch) | |
| 578 | + return; | |
| 579 | + | |
| 580 | + /* Here we try to figure out what caused the interrupt to happen */ | |
| 581 | + while (1) { | |
| 582 | + isr = readb(&ch->ch_cls_uart->isr_fcr); | |
| 583 | + | |
| 584 | + /* Bail if no pending interrupt on port */ | |
| 585 | + if (isr & UART_IIR_NO_INT) | |
| 586 | + break; | |
| 587 | + | |
| 588 | + /* Receive Interrupt pending */ | |
| 589 | + if (isr & (UART_IIR_RDI | UART_IIR_RDI_TIMEOUT)) { | |
| 590 | + /* Read data from uart -> queue */ | |
| 591 | + cls_copy_data_from_uart_to_queue(ch); | |
| 592 | + jsm_check_queue_flow_control(ch); | |
| 593 | + } | |
| 594 | + | |
| 595 | + /* Transmit Hold register empty pending */ | |
| 596 | + if (isr & UART_IIR_THRI) { | |
| 597 | + /* Transfer data (if any) from Write Queue -> UART. */ | |
| 598 | + spin_lock_irqsave(&ch->ch_lock, flags); | |
| 599 | + ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); | |
| 600 | + spin_unlock_irqrestore(&ch->ch_lock, flags); | |
| 601 | + cls_copy_data_from_queue_to_uart(ch); | |
| 602 | + } | |
| 603 | + | |
| 604 | + /* | |
| 605 | + * CTS/RTS change of state: | |
| 606 | + * Don't need to do anything, the cls_parse_modem | |
| 607 | + * below will grab the updated modem signals. | |
| 608 | + */ | |
| 609 | + | |
| 610 | + /* Parse any modem signal changes */ | |
| 611 | + cls_parse_modem(ch, readb(&ch->ch_cls_uart->msr)); | |
| 612 | + } | |
| 613 | +} | |
| 614 | + | |
| 615 | +/* Channel lock MUST be held before calling this function! */ | |
| 616 | +static void cls_flush_uart_write(struct jsm_channel *ch) | |
| 617 | +{ | |
| 618 | + u8 tmp = 0; | |
| 619 | + u8 i = 0; | |
| 620 | + | |
| 621 | + if (!ch) | |
| 622 | + return; | |
| 623 | + | |
| 624 | + writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_XMIT), | |
| 625 | + &ch->ch_cls_uart->isr_fcr); | |
| 626 | + | |
| 627 | + for (i = 0; i < 10; i++) { | |
| 628 | + /* Check to see if the UART feels it completely flushed FIFO */ | |
| 629 | + tmp = readb(&ch->ch_cls_uart->isr_fcr); | |
| 630 | + if (tmp & UART_FCR_CLEAR_XMIT) { | |
| 631 | + jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, | |
| 632 | + "Still flushing TX UART... i: %d\n", i); | |
| 633 | + udelay(10); | |
| 634 | + } else | |
| 635 | + break; | |
| 636 | + } | |
| 637 | + | |
| 638 | + ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); | |
| 639 | +} | |
| 640 | + | |
| 641 | +/* Channel lock MUST be held before calling this function! */ | |
| 642 | +static void cls_flush_uart_read(struct jsm_channel *ch) | |
| 643 | +{ | |
| 644 | + if (!ch) | |
| 645 | + return; | |
| 646 | + | |
| 647 | + /* | |
| 648 | + * For complete POSIX compatibility, we should be purging the | |
| 649 | + * read FIFO in the UART here. | |
| 650 | + * | |
| 651 | + * However, clearing the read FIFO (UART_FCR_CLEAR_RCVR) also | |
| 652 | + * incorrectly flushes write data as well as just basically trashing the | |
| 653 | + * FIFO. | |
| 654 | + * | |
| 655 | + * Presumably, this is a bug in this UART. | |
| 656 | + */ | |
| 657 | + | |
| 658 | + udelay(10); | |
| 659 | +} | |
| 660 | + | |
| 661 | +static void cls_send_start_character(struct jsm_channel *ch) | |
| 662 | +{ | |
| 663 | + if (!ch) | |
| 664 | + return; | |
| 665 | + | |
| 666 | + if (ch->ch_startc != __DISABLED_CHAR) { | |
| 667 | + ch->ch_xon_sends++; | |
| 668 | + writeb(ch->ch_startc, &ch->ch_cls_uart->txrx); | |
| 669 | + } | |
| 670 | +} | |
| 671 | + | |
| 672 | +static void cls_send_stop_character(struct jsm_channel *ch) | |
| 673 | +{ | |
| 674 | + if (!ch) | |
| 675 | + return; | |
| 676 | + | |
| 677 | + if (ch->ch_stopc != __DISABLED_CHAR) { | |
| 678 | + ch->ch_xoff_sends++; | |
| 679 | + writeb(ch->ch_stopc, &ch->ch_cls_uart->txrx); | |
| 680 | + } | |
| 681 | +} | |
| 682 | + | |
| 683 | +/* | |
| 684 | + * cls_param() | |
| 685 | + * Send any/all changes to the line to the UART. | |
| 686 | + */ | |
| 687 | +static void cls_param(struct jsm_channel *ch) | |
| 688 | +{ | |
| 689 | + u8 lcr = 0; | |
| 690 | + u8 uart_lcr = 0; | |
| 691 | + u8 ier = 0; | |
| 692 | + u32 baud = 9600; | |
| 693 | + int quot = 0; | |
| 694 | + struct jsm_board *bd; | |
| 695 | + int i; | |
| 696 | + unsigned int cflag; | |
| 697 | + | |
| 698 | + bd = ch->ch_bd; | |
| 699 | + if (!bd) | |
| 700 | + return; | |
| 701 | + | |
| 702 | + /* | |
| 703 | + * If baud rate is zero, flush queues, and set mval to drop DTR. | |
| 704 | + */ | |
| 705 | + if ((ch->ch_c_cflag & (CBAUD)) == 0) { | |
| 706 | + ch->ch_r_head = 0; | |
| 707 | + ch->ch_r_tail = 0; | |
| 708 | + ch->ch_e_head = 0; | |
| 709 | + ch->ch_e_tail = 0; | |
| 710 | + | |
| 711 | + cls_flush_uart_write(ch); | |
| 712 | + cls_flush_uart_read(ch); | |
| 713 | + | |
| 714 | + /* The baudrate is B0 so all modem lines are to be dropped. */ | |
| 715 | + ch->ch_flags |= (CH_BAUD0); | |
| 716 | + ch->ch_mostat &= ~(UART_MCR_RTS | UART_MCR_DTR); | |
| 717 | + cls_assert_modem_signals(ch); | |
| 718 | + return; | |
| 719 | + } | |
| 720 | + | |
| 721 | + cflag = C_BAUD(ch->uart_port.state->port.tty); | |
| 722 | + baud = 9600; | |
| 723 | + for (i = 0; i < ARRAY_SIZE(baud_rates); i++) { | |
| 724 | + if (baud_rates[i].cflag == cflag) { | |
| 725 | + baud = baud_rates[i].rate; | |
| 726 | + break; | |
| 727 | + } | |
| 728 | + } | |
| 729 | + | |
| 730 | + if (ch->ch_flags & CH_BAUD0) | |
| 731 | + ch->ch_flags &= ~(CH_BAUD0); | |
| 732 | + | |
| 733 | + if (ch->ch_c_cflag & PARENB) | |
| 734 | + lcr |= UART_LCR_PARITY; | |
| 735 | + | |
| 736 | + if (!(ch->ch_c_cflag & PARODD)) | |
| 737 | + lcr |= UART_LCR_EPAR; | |
| 738 | + | |
| 739 | + /* | |
| 740 | + * Not all platforms support mark/space parity, | |
| 741 | + * so this will hide behind an ifdef. | |
| 742 | + */ | |
| 743 | +#ifdef CMSPAR | |
| 744 | + if (ch->ch_c_cflag & CMSPAR) | |
| 745 | + lcr |= UART_LCR_SPAR; | |
| 746 | +#endif | |
| 747 | + | |
| 748 | + if (ch->ch_c_cflag & CSTOPB) | |
| 749 | + lcr |= UART_LCR_STOP; | |
| 750 | + | |
| 751 | + switch (ch->ch_c_cflag & CSIZE) { | |
| 752 | + case CS5: | |
| 753 | + lcr |= UART_LCR_WLEN5; | |
| 754 | + break; | |
| 755 | + case CS6: | |
| 756 | + lcr |= UART_LCR_WLEN6; | |
| 757 | + break; | |
| 758 | + case CS7: | |
| 759 | + lcr |= UART_LCR_WLEN7; | |
| 760 | + break; | |
| 761 | + case CS8: | |
| 762 | + default: | |
| 763 | + lcr |= UART_LCR_WLEN8; | |
| 764 | + break; | |
| 765 | + } | |
| 766 | + | |
| 767 | + ier = readb(&ch->ch_cls_uart->ier); | |
| 768 | + uart_lcr = readb(&ch->ch_cls_uart->lcr); | |
| 769 | + | |
| 770 | + quot = ch->ch_bd->bd_dividend / baud; | |
| 771 | + | |
| 772 | + if (quot != 0) { | |
| 773 | + writeb(UART_LCR_DLAB, &ch->ch_cls_uart->lcr); | |
| 774 | + writeb((quot & 0xff), &ch->ch_cls_uart->txrx); | |
| 775 | + writeb((quot >> 8), &ch->ch_cls_uart->ier); | |
| 776 | + writeb(lcr, &ch->ch_cls_uart->lcr); | |
| 777 | + } | |
| 778 | + | |
| 779 | + if (uart_lcr != lcr) | |
| 780 | + writeb(lcr, &ch->ch_cls_uart->lcr); | |
| 781 | + | |
| 782 | + if (ch->ch_c_cflag & CREAD) | |
| 783 | + ier |= (UART_IER_RDI | UART_IER_RLSI); | |
| 784 | + | |
| 785 | + ier |= (UART_IER_THRI | UART_IER_MSI); | |
| 786 | + | |
| 787 | + writeb(ier, &ch->ch_cls_uart->ier); | |
| 788 | + | |
| 789 | + if (ch->ch_c_cflag & CRTSCTS) | |
| 790 | + cls_set_cts_flow_control(ch); | |
| 791 | + else if (ch->ch_c_iflag & IXON) { | |
| 792 | + /* | |
| 793 | + * If start/stop is set to disable, | |
| 794 | + * then we should disable flow control. | |
| 795 | + */ | |
| 796 | + if ((ch->ch_startc == __DISABLED_CHAR) || | |
| 797 | + (ch->ch_stopc == __DISABLED_CHAR)) | |
| 798 | + cls_set_no_output_flow_control(ch); | |
| 799 | + else | |
| 800 | + cls_set_ixon_flow_control(ch); | |
| 801 | + } else | |
| 802 | + cls_set_no_output_flow_control(ch); | |
| 803 | + | |
| 804 | + if (ch->ch_c_cflag & CRTSCTS) | |
| 805 | + cls_set_rts_flow_control(ch); | |
| 806 | + else if (ch->ch_c_iflag & IXOFF) { | |
| 807 | + /* | |
| 808 | + * If start/stop is set to disable, | |
| 809 | + * then we should disable flow control. | |
| 810 | + */ | |
| 811 | + if ((ch->ch_startc == __DISABLED_CHAR) || | |
| 812 | + (ch->ch_stopc == __DISABLED_CHAR)) | |
| 813 | + cls_set_no_input_flow_control(ch); | |
| 814 | + else | |
| 815 | + cls_set_ixoff_flow_control(ch); | |
| 816 | + } else | |
| 817 | + cls_set_no_input_flow_control(ch); | |
| 818 | + | |
| 819 | + cls_assert_modem_signals(ch); | |
| 820 | + | |
| 821 | + /* get current status of the modem signals now */ | |
| 822 | + cls_parse_modem(ch, readb(&ch->ch_cls_uart->msr)); | |
| 823 | +} | |
| 824 | + | |
| 825 | +/* | |
| 826 | + * cls_intr() | |
| 827 | + * | |
| 828 | + * Classic specific interrupt handler. | |
| 829 | + */ | |
| 830 | +static irqreturn_t cls_intr(int irq, void *voidbrd) | |
| 831 | +{ | |
| 832 | + struct jsm_board *brd = voidbrd; | |
| 833 | + unsigned long lock_flags; | |
| 834 | + unsigned char uart_poll; | |
| 835 | + uint i = 0; | |
| 836 | + | |
| 837 | + /* Lock out the slow poller from running on this board. */ | |
| 838 | + spin_lock_irqsave(&brd->bd_intr_lock, lock_flags); | |
| 839 | + | |
| 840 | + /* | |
| 841 | + * Check the board's global interrupt offset to see if we | |
| 842 | + * acctually do have an interrupt pending on us. | |
| 843 | + */ | |
| 844 | + uart_poll = readb(brd->re_map_membase + UART_CLASSIC_POLL_ADDR_OFFSET); | |
| 845 | + | |
| 846 | + jsm_dbg(INTR, &brd->pci_dev, "%s:%d uart_poll: %x\n", | |
| 847 | + __FILE__, __LINE__, uart_poll); | |
| 848 | + | |
| 849 | + if (!uart_poll) { | |
| 850 | + jsm_dbg(INTR, &brd->pci_dev, | |
| 851 | + "Kernel interrupted to me, but no pending interrupts...\n"); | |
| 852 | + spin_unlock_irqrestore(&brd->bd_intr_lock, lock_flags); | |
| 853 | + return IRQ_NONE; | |
| 854 | + } | |
| 855 | + | |
| 856 | + /* At this point, we have at least SOMETHING to service, dig further. */ | |
| 857 | + | |
| 858 | + /* Parse each port to find out what caused the interrupt */ | |
| 859 | + for (i = 0; i < brd->nasync; i++) | |
| 860 | + cls_parse_isr(brd, i); | |
| 861 | + | |
| 862 | + spin_unlock_irqrestore(&brd->bd_intr_lock, lock_flags); | |
| 863 | + | |
| 864 | + return IRQ_HANDLED; | |
| 865 | +} | |
| 866 | + | |
| 867 | +/* Inits UART */ | |
| 868 | +static void cls_uart_init(struct jsm_channel *ch) | |
| 869 | +{ | |
| 870 | + unsigned char lcrb = readb(&ch->ch_cls_uart->lcr); | |
| 871 | + unsigned char isr_fcr = 0; | |
| 872 | + | |
| 873 | + writeb(0, &ch->ch_cls_uart->ier); | |
| 874 | + | |
| 875 | + /* | |
| 876 | + * The Enhanced Register Set may only be accessed when | |
| 877 | + * the Line Control Register is set to 0xBFh. | |
| 878 | + */ | |
| 879 | + writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr); | |
| 880 | + | |
| 881 | + isr_fcr = readb(&ch->ch_cls_uart->isr_fcr); | |
| 882 | + | |
| 883 | + /* Turn on Enhanced/Extended controls */ | |
| 884 | + isr_fcr |= (UART_EXAR654_EFR_ECB); | |
| 885 | + | |
| 886 | + writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr); | |
| 887 | + | |
| 888 | + /* Write old LCR value back out, which turns enhanced access off */ | |
| 889 | + writeb(lcrb, &ch->ch_cls_uart->lcr); | |
| 890 | + | |
| 891 | + /* Clear out UART and FIFO */ | |
| 892 | + readb(&ch->ch_cls_uart->txrx); | |
| 893 | + | |
| 894 | + writeb((UART_FCR_ENABLE_FIFO|UART_FCR_CLEAR_RCVR|UART_FCR_CLEAR_XMIT), | |
| 895 | + &ch->ch_cls_uart->isr_fcr); | |
| 896 | + udelay(10); | |
| 897 | + | |
| 898 | + ch->ch_flags |= (CH_FIFO_ENABLED | CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); | |
| 899 | + | |
| 900 | + readb(&ch->ch_cls_uart->lsr); | |
| 901 | + readb(&ch->ch_cls_uart->msr); | |
| 902 | +} | |
| 903 | + | |
| 904 | +/* | |
| 905 | + * Turns off UART. | |
| 906 | + */ | |
| 907 | +static void cls_uart_off(struct jsm_channel *ch) | |
| 908 | +{ | |
| 909 | + /* Stop all interrupts from accurring. */ | |
| 910 | + writeb(0, &ch->ch_cls_uart->ier); | |
| 911 | +} | |
| 912 | + | |
| 913 | +/* | |
| 914 | + * cls_get_uarts_bytes_left. | |
| 915 | + * Returns 0 is nothing left in the FIFO, returns 1 otherwise. | |
| 916 | + * | |
| 917 | + * The channel lock MUST be held by the calling function. | |
| 918 | + */ | |
| 919 | +static u32 cls_get_uart_bytes_left(struct jsm_channel *ch) | |
| 920 | +{ | |
| 921 | + u8 left = 0; | |
| 922 | + u8 lsr = readb(&ch->ch_cls_uart->lsr); | |
| 923 | + | |
| 924 | + /* Determine whether the Transmitter is empty or not */ | |
| 925 | + if (!(lsr & UART_LSR_TEMT)) | |
| 926 | + left = 1; | |
| 927 | + else { | |
| 928 | + ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); | |
| 929 | + left = 0; | |
| 930 | + } | |
| 931 | + | |
| 932 | + return left; | |
| 933 | +} | |
| 934 | + | |
| 935 | +/* | |
| 936 | + * cls_send_break. | |
| 937 | + * Starts sending a break thru the UART. | |
| 938 | + * | |
| 939 | + * The channel lock MUST be held by the calling function. | |
| 940 | + */ | |
| 941 | +static void cls_send_break(struct jsm_channel *ch) | |
| 942 | +{ | |
| 943 | + /* Tell the UART to start sending the break */ | |
| 944 | + if (!(ch->ch_flags & CH_BREAK_SENDING)) { | |
| 945 | + u8 temp = readb(&ch->ch_cls_uart->lcr); | |
| 946 | + | |
| 947 | + writeb((temp | UART_LCR_SBC), &ch->ch_cls_uart->lcr); | |
| 948 | + ch->ch_flags |= (CH_BREAK_SENDING); | |
| 949 | + } | |
| 950 | +} | |
| 951 | + | |
| 952 | +/* | |
| 953 | + * cls_send_immediate_char. | |
| 954 | + * Sends a specific character as soon as possible to the UART, | |
| 955 | + * jumping over any bytes that might be in the write queue. | |
| 956 | + * | |
| 957 | + * The channel lock MUST be held by the calling function. | |
| 958 | + */ | |
| 959 | +static void cls_send_immediate_char(struct jsm_channel *ch, unsigned char c) | |
| 960 | +{ | |
| 961 | + writeb(c, &ch->ch_cls_uart->txrx); | |
| 962 | +} | |
| 963 | + | |
| 964 | +struct board_ops jsm_cls_ops = { | |
| 965 | + .intr = cls_intr, | |
| 966 | + .uart_init = cls_uart_init, | |
| 967 | + .uart_off = cls_uart_off, | |
| 968 | + .param = cls_param, | |
| 969 | + .assert_modem_signals = cls_assert_modem_signals, | |
| 970 | + .flush_uart_write = cls_flush_uart_write, | |
| 971 | + .flush_uart_read = cls_flush_uart_read, | |
| 972 | + .disable_receiver = cls_disable_receiver, | |
| 973 | + .enable_receiver = cls_enable_receiver, | |
| 974 | + .send_break = cls_send_break, | |
| 975 | + .clear_break = cls_clear_break, | |
| 976 | + .send_start_character = cls_send_start_character, | |
| 977 | + .send_stop_character = cls_send_stop_character, | |
| 978 | + .copy_data_from_queue_to_uart = cls_copy_data_from_queue_to_uart, | |
| 979 | + .get_uart_bytes_left = cls_get_uart_bytes_left, | |
| 980 | + .send_immediate_char = cls_send_immediate_char | |
| 981 | +}; | |
| 982 | + | |
| @@ -13,11 +13,6 @@ · 12 unmodified lines | ||
| 13 | 13 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
| 14 | 14 | * PURPOSE. See the GNU General Public License for more details. |
| 15 | 15 | * |
| 16 | − * You should have received a copy of the GNU General Public License | |
| 17 | − * along with this program; if not, write to the Free Software | |
| 18 | − * Foundation, Inc., 59 * Temple Place - Suite 330, Boston, | |
| 19 | − * MA 02111-1307, USA. | |
| 20 | − * | |
| 21 | 16 | * Contact Information: |
| 22 | 17 | * Scott H Kilau <Scott_Kilau@digi.com> |
| 23 | 18 | * Wendy Xiong <wendyx@us.ibm.com> |
| @@ -31,8 +26,7 @@ · 7 unmodified lines | ||
| 31 | 26 | #include "jsm.h" |
| 32 | 27 | |
| 33 | 28 | MODULE_AUTHOR("Digi International, http://www.digi.com"); |
| 34 | −MODULE_DESCRIPTION("Driver for the Digi International " | |
| 35 | − "Neo PCI based product line"); | |
| 29 | +MODULE_DESCRIPTION("Driver for the Digi International Neo and Classic PCI based product line"); | |
| 36 | 30 | MODULE_LICENSE("GPL"); |
| 37 | 31 | MODULE_SUPPORTED_DEVICE("jsm"); |
| 38 | 32 | |
| @@ -50,7 +44,7 @@ struct uart_driver jsm_uart_driver = { · 11 unmodified lines | ||
| 50 | 44 | }; |
| 51 | 45 | |
| 52 | 46 | static pci_ers_result_t jsm_io_error_detected(struct pci_dev *pdev, |
| 53 | − pci_channel_state_t state); | |
| 47 | + pci_channel_state_t state); | |
| 54 | 48 | static pci_ers_result_t jsm_io_slot_reset(struct pci_dev *pdev); |
| 55 | 49 | static void jsm_io_resume(struct pci_dev *pdev); |
| 56 | 50 | |
| @@ -68,7 +62,7 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 11 unmodified lines | ||
| 68 | 62 | { |
| 69 | 63 | int rc = 0; |
| 70 | 64 | struct jsm_board *brd; |
| 71 | − static int adapter_count = 0; | |
| 65 | + static int adapter_count; | |
| 72 | 66 | |
| 73 | 67 | rc = pci_enable_device(pdev); |
| 74 | 68 | if (rc) { |
| @@ -82,10 +76,8 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 7 unmodified lines | ||
| 82 | 76 | goto out_disable_device; |
| 83 | 77 | } |
| 84 | 78 | |
| 85 | − brd = kzalloc(sizeof(struct jsm_board), GFP_KERNEL); | |
| 79 | + brd = kzalloc(sizeof(*brd), GFP_KERNEL); | |
| 86 | 80 | if (!brd) { |
| 87 | − dev_err(&pdev->dev, | |
| 88 | − "memory allocation for board structure failed\n"); | |
| 89 | 81 | rc = -ENOMEM; |
| 90 | 82 | goto out_release_regions; |
| 91 | 83 | } |
| @@ -95,7 +87,6 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 3 unmodified lines | ||
| 95 | 87 | brd->pci_dev = pdev; |
| 96 | 88 | |
| 97 | 89 | switch (pdev->device) { |
| 98 | − | |
| 99 | 90 | case PCI_DEVICE_ID_NEO_2DB9: |
| 100 | 91 | case PCI_DEVICE_ID_NEO_2DB9PRI: |
| 101 | 92 | case PCI_DEVICE_ID_NEO_2RJ45: |
| @@ -104,6 +95,8 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 2 unmodified lines | ||
| 104 | 95 | brd->maxports = 2; |
| 105 | 96 | break; |
| 106 | 97 | |
| 98 | + case PCI_DEVICE_ID_CLASSIC_4: | |
| 99 | + case PCI_DEVICE_ID_CLASSIC_4_422: | |
| 107 | 100 | case PCI_DEVICE_ID_NEO_4: |
| 108 | 101 | case PCIE_DEVICE_ID_NEO_4: |
| 109 | 102 | case PCIE_DEVICE_ID_NEO_4RJ45: |
| @@ -111,6 +104,8 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 1 unmodified line | ||
| 111 | 104 | brd->maxports = 4; |
| 112 | 105 | break; |
| 113 | 106 | |
| 107 | + case PCI_DEVICE_ID_CLASSIC_8: | |
| 108 | + case PCI_DEVICE_ID_CLASSIC_8_422: | |
| 114 | 109 | case PCI_DEVICE_ID_DIGI_NEO_8: |
| 115 | 110 | case PCIE_DEVICE_ID_NEO_8: |
| 116 | 111 | case PCIE_DEVICE_ID_NEO_8RJ45: |
| @@ -129,36 +124,109 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 12 unmodified lines | ||
| 129 | 124 | |
| 130 | 125 | brd->irq = pdev->irq; |
| 131 | 126 | |
| 132 | − jsm_dbg(INIT, &brd->pci_dev, "jsm_found_board - NEO adapter\n"); | |
| 127 | + switch (pdev->device) { | |
| 128 | + case PCI_DEVICE_ID_CLASSIC_4: | |
| 129 | + case PCI_DEVICE_ID_CLASSIC_4_422: | |
| 130 | + case PCI_DEVICE_ID_CLASSIC_8: | |
| 131 | + case PCI_DEVICE_ID_CLASSIC_8_422: | |
| 132 | + | |
| 133 | + jsm_dbg(INIT, &brd->pci_dev, | |
| 134 | + "jsm_found_board - Classic adapter\n"); | |
| 135 | + | |
| 136 | + /* | |
| 137 | + * For PCI ClassicBoards | |
| 138 | + * PCI Local Address (.i.e. "resource" number) space | |
| 139 | + * 0 PLX Memory Mapped Config | |
| 140 | + * 1 PLX I/O Mapped Config | |
| 141 | + * 2 I/O Mapped UARTs and Status | |
| 142 | + * 3 Memory Mapped VPD | |
| 143 | + * 4 Memory Mapped UARTs and Status | |
| 144 | + */ | |
| 145 | + | |
| 146 | + /* Get the PCI Base Address Registers */ | |
| 147 | + brd->membase = pci_resource_start(pdev, 4); | |
| 148 | + brd->membase_end = pci_resource_end(pdev, 4); | |
| 149 | + | |
| 150 | + if (brd->membase & 0x1) | |
| 151 | + brd->membase &= ~0x3; | |
| 152 | + else | |
| 153 | + brd->membase &= ~0xF; | |
| 154 | + | |
| 155 | + brd->iobase = pci_resource_start(pdev, 1); | |
| 156 | + brd->iobase_end = pci_resource_end(pdev, 1); | |
| 157 | + brd->iobase = ((unsigned int)(brd->iobase)) & 0xFFFE; | |
| 158 | + | |
| 159 | + /* Assign the board_ops struct */ | |
| 160 | + brd->bd_ops = &jsm_cls_ops; | |
| 161 | + | |
| 162 | + brd->bd_uart_offset = 0x8; | |
| 163 | + brd->bd_dividend = 921600; | |
| 164 | + | |
| 165 | + brd->re_map_membase = ioremap(brd->membase, | |
| 166 | + pci_resource_len(pdev, 4)); | |
| 167 | + if (!brd->re_map_membase) { | |
| 168 | + dev_err(&pdev->dev, | |
| 169 | + "Card has no PCI Memory resources, failing board.\n"); | |
| 170 | + rc = -ENOMEM; | |
| 171 | + goto out_kfree_brd; | |
| 172 | + } | |
| 173 | + | |
| 174 | + /* | |
| 175 | + * Enable Local Interrupt 1 (0x1), | |
| 176 | + * Local Interrupt 1 Polarity Active high (0x2), | |
| 177 | + * Enable PCI interrupt (0x43) | |
| 178 | + */ | |
| 179 | + outb(0x43, brd->iobase + 0x4c); | |
| 180 | + | |
| 181 | + break; | |
| 182 | + | |
| 183 | + case PCI_DEVICE_ID_NEO_2DB9: | |
| 184 | + case PCI_DEVICE_ID_NEO_2DB9PRI: | |
| 185 | + case PCI_DEVICE_ID_NEO_2RJ45: | |
| 186 | + case PCI_DEVICE_ID_NEO_2RJ45PRI: | |
| 187 | + case PCI_DEVICE_ID_NEO_2_422_485: | |
| 188 | + case PCI_DEVICE_ID_NEO_4: | |
| 189 | + case PCIE_DEVICE_ID_NEO_4: | |
| 190 | + case PCIE_DEVICE_ID_NEO_4RJ45: | |
| 191 | + case PCIE_DEVICE_ID_NEO_4_IBM: | |
| 192 | + case PCI_DEVICE_ID_DIGI_NEO_8: | |
| 193 | + case PCIE_DEVICE_ID_NEO_8: | |
| 194 | + case PCIE_DEVICE_ID_NEO_8RJ45: | |
| 195 | + | |
| 196 | + jsm_dbg(INIT, &brd->pci_dev, "jsm_found_board - NEO adapter\n"); | |
| 133 | 197 | |
| 134 | − /* get the PCI Base Address Registers */ | |
| 135 | − brd->membase = pci_resource_start(pdev, 0); | |
| 136 | − brd->membase_end = pci_resource_end(pdev, 0); | |
| 198 | + /* get the PCI Base Address Registers */ | |
| 199 | + brd->membase = pci_resource_start(pdev, 0); | |
| 200 | + brd->membase_end = pci_resource_end(pdev, 0); | |
| 137 | 201 | |
| 138 | − if (brd->membase & 1) | |
| 139 | − brd->membase &= ~3; | |
| 140 | − else | |
| 141 | − brd->membase &= ~15; | |
| 202 | + if (brd->membase & 1) | |
| 203 | + brd->membase &= ~0x3; | |
| 204 | + else | |
| 205 | + brd->membase &= ~0xF; | |
| 142 | 206 | |
| 143 | − /* Assign the board_ops struct */ | |
| 144 | − brd->bd_ops = &jsm_neo_ops; | |
| 207 | + /* Assign the board_ops struct */ | |
| 208 | + brd->bd_ops = &jsm_neo_ops; | |
| 145 | 209 | |
| 146 | − brd->bd_uart_offset = 0x200; | |
| 147 | − brd->bd_dividend = 921600; | |
| 210 | + brd->bd_uart_offset = 0x200; | |
| 211 | + brd->bd_dividend = 921600; | |
| 148 | 212 | |
| 149 | − brd->re_map_membase = ioremap(brd->membase, pci_resource_len(pdev, 0)); | |
| 150 | − if (!brd->re_map_membase) { | |
| 151 | − dev_err(&pdev->dev, | |
| 152 | − "card has no PCI Memory resources, " | |
| 153 | − "failing board.\n"); | |
| 154 | − rc = -ENOMEM; | |
| 155 | − goto out_kfree_brd; | |
| 213 | + brd->re_map_membase = ioremap(brd->membase, | |
| 214 | + pci_resource_len(pdev, 0)); | |
| 215 | + if (!brd->re_map_membase) { | |
| 216 | + dev_err(&pdev->dev, | |
| 217 | + "Card has no PCI Memory resources, failing board.\n"); | |
| 218 | + rc = -ENOMEM; | |
| 219 | + goto out_kfree_brd; | |
| 220 | + } | |
| 221 | + | |
| 222 | + break; | |
| 223 | + default: | |
| 224 | + return -ENXIO; | |
| 156 | 225 | } |
| 157 | 226 | |
| 158 | − rc = request_irq(brd->irq, brd->bd_ops->intr, | |
| 159 | − IRQF_SHARED, "JSM", brd); | |
| 227 | + rc = request_irq(brd->irq, brd->bd_ops->intr, IRQF_SHARED, "JSM", brd); | |
| 160 | 228 | if (rc) { |
| 161 | − printk(KERN_WARNING "Failed to hook IRQ %d\n",brd->irq); | |
| 229 | + dev_warn(&pdev->dev, "Failed to hook IRQ %d\n", brd->irq); | |
| 162 | 230 | goto out_iounmap; |
| 163 | 231 | } |
| 164 | 232 | |
| @@ -178,7 +246,7 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 13 unmodified lines | ||
| 178 | 246 | } |
| 179 | 247 | |
| 180 | 248 | /* Log the information about the board */ |
| 181 | − dev_info(&pdev->dev, "board %d: Digi Neo (rev %d), irq %d\n", | |
| 249 | + dev_info(&pdev->dev, "board %d: Digi Classic/Neo (rev %d), irq %d\n", | |
| 182 | 250 | adapter_count, brd->rev, brd->irq); |
| 183 | 251 | |
| 184 | 252 | pci_set_drvdata(pdev, brd); |
| @@ -205,6 +273,18 @@ static void jsm_remove_one(struct pci_dev *pdev) · 20 unmodified lines | ||
| 205 | 273 | struct jsm_board *brd = pci_get_drvdata(pdev); |
| 206 | 274 | int i = 0; |
| 207 | 275 | |
| 276 | + switch (pdev->device) { | |
| 277 | + case PCI_DEVICE_ID_CLASSIC_4: | |
| 278 | + case PCI_DEVICE_ID_CLASSIC_4_422: | |
| 279 | + case PCI_DEVICE_ID_CLASSIC_8: | |
| 280 | + case PCI_DEVICE_ID_CLASSIC_8_422: | |
| 281 | + /* Tell card not to interrupt anymore. */ | |
| 282 | + outb(0x0, brd->iobase + 0x4c); | |
| 283 | + break; | |
| 284 | + default: | |
| 285 | + break; | |
| 286 | + } | |
| 287 | + | |
| 208 | 288 | jsm_remove_uart_port(brd); |
| 209 | 289 | |
| 210 | 290 | free_irq(brd->irq, brd); |
| @@ -239,6 +319,10 @@ static struct pci_device_id jsm_pci_tbl[] = { · 28 unmodified lines | ||
| 239 | 319 | { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_4), 0, 0, 11 }, |
| 240 | 320 | { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_4RJ45), 0, 0, 12 }, |
| 241 | 321 | { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_8RJ45), 0, 0, 13 }, |
| 322 | + { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_CLASSIC_4), 0, 0, 14 }, | |
| 323 | + { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_CLASSIC_4_422), 0, 0, 15 }, | |
| 324 | + { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_CLASSIC_8), 0, 0, 16 }, | |
| 325 | + { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_CLASSIC_8_422), 0, 0, 17 }, | |
| 242 | 326 | { 0, } |
| 243 | 327 | }; |
| 244 | 328 | MODULE_DEVICE_TABLE(pci, jsm_pci_tbl); |
| @@ -13,11 +13,6 @@ · 12 unmodified lines | ||
| 13 | 13 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
| 14 | 14 | * PURPOSE. See the GNU General Public License for more details. |
| 15 | 15 | * |
| 16 | − * You should have received a copy of the GNU General Public License | |
| 17 | − * along with this program; if not, write to the Free Software | |
| 18 | − * Foundation, Inc., 59 * Temple Place - Suite 330, Boston, | |
| 19 | − * MA 02111-1307, USA. | |
| 20 | − * | |
| 21 | 16 | * Contact Information: |
| 22 | 17 | * Scott H Kilau <Scott_Kilau@digi.com> |
| 23 | 18 | * Wendy Xiong <wendyx@us.ibm.com> |
| @@ -649,7 +644,7 @@ static void neo_flush_uart_write(struct jsm_channel *ch) · 625 unmodified lines | ||
| 649 | 644 | |
| 650 | 645 | /* Check to see if the UART feels it completely flushed the FIFO. */ |
| 651 | 646 | tmp = readb(&ch->ch_neo_uart->isr_fcr); |
| 652 | − if (tmp & 4) { | |
| 647 | + if (tmp & UART_FCR_CLEAR_XMIT) { | |
| 653 | 648 | jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, |
| 654 | 649 | "Still flushing TX UART... i: %d\n", i); |
| 655 | 650 | udelay(10); |
| @@ -694,7 +689,7 @@ static void neo_flush_uart_read(struct jsm_channel *ch) · 38 unmodified lines | ||
| 694 | 689 | /* |
| 695 | 690 | * No locks are assumed to be held when calling this function. |
| 696 | 691 | */ |
| 697 | −static void neo_clear_break(struct jsm_channel *ch, int force) | |
| 692 | +static void neo_clear_break(struct jsm_channel *ch) | |
| 698 | 693 | { |
| 699 | 694 | unsigned long lock_flags; |
| 700 | 695 | |
| @@ -1024,27 +1019,24 @@ static void neo_param(struct jsm_channel *ch) · 323 unmodified lines | ||
| 1024 | 1019 | lcr |= UART_LCR_STOP; |
| 1025 | 1020 | |
| 1026 | 1021 | switch (ch->ch_c_cflag & CSIZE) { |
| 1027 | − case CS5: | |
| 1028 | − lcr |= UART_LCR_WLEN5; | |
| 1029 | − break; | |
| 1030 | − case CS6: | |
| 1031 | − lcr |= UART_LCR_WLEN6; | |
| 1032 | − break; | |
| 1033 | − case CS7: | |
| 1034 | − lcr |= UART_LCR_WLEN7; | |
| 1035 | − break; | |
| 1036 | − case CS8: | |
| 1037 | − default: | |
| 1038 | − lcr |= UART_LCR_WLEN8; | |
| 1022 | + case CS5: | |
| 1023 | + lcr |= UART_LCR_WLEN5; | |
| 1039 | 1024 | break; |
| 1025 | + case CS6: | |
| 1026 | + lcr |= UART_LCR_WLEN6; | |
| 1027 | + break; | |
| 1028 | + case CS7: | |
| 1029 | + lcr |= UART_LCR_WLEN7; | |
| 1030 | + break; | |
| 1031 | + case CS8: | |
| 1032 | + default: | |
| 1033 | + lcr |= UART_LCR_WLEN8; | |
| 1034 | + break; | |
| 1040 | 1035 | } |
| 1041 | 1036 | |
| 1042 | 1037 | ier = readb(&ch->ch_neo_uart->ier); |
| 1043 | 1038 | uart_lcr = readb(&ch->ch_neo_uart->lcr); |
| 1044 | 1039 | |
| 1045 | − if (baud == 0) | |
| 1046 | − baud = 9600; | |
| 1047 | − | |
| 1048 | 1040 | quot = ch->ch_bd->bd_dividend / baud; |
| 1049 | 1041 | |
| 1050 | 1042 | if (quot != 0) { |
| @@ -13,11 +13,6 @@ · 12 unmodified lines | ||
| 13 | 13 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
| 14 | 14 | * PURPOSE. See the GNU General Public License for more details. |
| 15 | 15 | * |
| 16 | − * You should have received a copy of the GNU General Public License | |
| 17 | − * along with this program; if not, write to the Free Software | |
| 18 | − * Foundation, Inc., 59 * Temple Place - Suite 330, Boston, | |
| 19 | − * MA 02111-1307, USA. | |
| 20 | − * | |
| 21 | 16 | * Contact Information: |
| 22 | 17 | * Scott H Kilau <Scott_Kilau@digi.com> |
| 23 | 18 | * Ananda Venkatarman <mansarov@us.ibm.com> |
| @@ -77,7 +72,8 @@ static unsigned int jsm_tty_tx_empty(struct uart_port *port) · 53 unmodified lines | ||
| 77 | 72 | static unsigned int jsm_tty_get_mctrl(struct uart_port *port) |
| 78 | 73 | { |
| 79 | 74 | int result; |
| 80 | − struct jsm_channel *channel = (struct jsm_channel *)port; | |
| 75 | + struct jsm_channel *channel = | |
| 76 | + container_of(port, struct jsm_channel, uart_port); | |
| 81 | 77 | |
| 82 | 78 | jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "start\n"); |
| 83 | 79 | |
| @@ -98,7 +94,8 @@ static unsigned int jsm_tty_get_mctrl(struct uart_port *port) · 14 unmodified lines | ||
| 98 | 94 | */ |
| 99 | 95 | static void jsm_tty_set_mctrl(struct uart_port *port, unsigned int mctrl) |
| 100 | 96 | { |
| 101 | − struct jsm_channel *channel = (struct jsm_channel *)port; | |
| 97 | + struct jsm_channel *channel = | |
| 98 | + container_of(port, struct jsm_channel, uart_port); | |
| 102 | 99 | |
| 103 | 100 | jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "start\n"); |
| 104 | 101 | |
| @@ -133,7 +130,8 @@ static void jsm_tty_write(struct uart_port *port) · 28 unmodified lines | ||
| 133 | 130 | |
| 134 | 131 | static void jsm_tty_start_tx(struct uart_port *port) |
| 135 | 132 | { |
| 136 | − struct jsm_channel *channel = (struct jsm_channel *)port; | |
| 133 | + struct jsm_channel *channel = | |
| 134 | + container_of(port, struct jsm_channel, uart_port); | |
| 137 | 135 | |
| 138 | 136 | jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "start\n"); |
| 139 | 137 | |
| @@ -145,7 +143,8 @@ static void jsm_tty_start_tx(struct uart_port *port) · 5 unmodified lines | ||
| 145 | 143 | |
| 146 | 144 | static void jsm_tty_stop_tx(struct uart_port *port) |
| 147 | 145 | { |
| 148 | − struct jsm_channel *channel = (struct jsm_channel *)port; | |
| 146 | + struct jsm_channel *channel = | |
| 147 | + container_of(port, struct jsm_channel, uart_port); | |
| 149 | 148 | |
| 150 | 149 | jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "start\n"); |
| 151 | 150 | |
| @@ -157,7 +156,8 @@ static void jsm_tty_stop_tx(struct uart_port *port) · 5 unmodified lines | ||
| 157 | 156 | static void jsm_tty_send_xchar(struct uart_port *port, char ch) |
| 158 | 157 | { |
| 159 | 158 | unsigned long lock_flags; |
| 160 | − struct jsm_channel *channel = (struct jsm_channel *)port; | |
| 159 | + struct jsm_channel *channel = | |
| 160 | + container_of(port, struct jsm_channel, uart_port); | |
| 161 | 161 | struct ktermios *termios; |
| 162 | 162 | |
| 163 | 163 | spin_lock_irqsave(&port->lock, lock_flags); |
| @@ -172,7 +172,8 @@ static void jsm_tty_send_xchar(struct uart_port *port, char ch) · 8 unmodified lines | ||
| 172 | 172 | |
| 173 | 173 | static void jsm_tty_stop_rx(struct uart_port *port) |
| 174 | 174 | { |
| 175 | − struct jsm_channel *channel = (struct jsm_channel *)port; | |
| 175 | + struct jsm_channel *channel = | |
| 176 | + container_of(port, struct jsm_channel, uart_port); | |
| 176 | 177 | |
| 177 | 178 | channel->ch_bd->bd_ops->disable_receiver(channel); |
| 178 | 179 | } |
| @@ -180,13 +181,14 @@ static void jsm_tty_stop_rx(struct uart_port *port) · 1 unmodified line | ||
| 180 | 181 | static void jsm_tty_break(struct uart_port *port, int break_state) |
| 181 | 182 | { |
| 182 | 183 | unsigned long lock_flags; |
| 183 | − struct jsm_channel *channel = (struct jsm_channel *)port; | |
| 184 | + struct jsm_channel *channel = | |
| 185 | + container_of(port, struct jsm_channel, uart_port); | |
| 184 | 186 | |
| 185 | 187 | spin_lock_irqsave(&port->lock, lock_flags); |
| 186 | 188 | if (break_state == -1) |
| 187 | 189 | channel->ch_bd->bd_ops->send_break(channel); |
| 188 | 190 | else |
| 189 | − channel->ch_bd->bd_ops->clear_break(channel, 0); | |
| 191 | + channel->ch_bd->bd_ops->clear_break(channel); | |
| 190 | 192 | |
| 191 | 193 | spin_unlock_irqrestore(&port->lock, lock_flags); |
| 192 | 194 | } |
| @@ -194,7 +196,8 @@ static void jsm_tty_break(struct uart_port *port, int break_state) · 1 unmodified line | ||
| 194 | 196 | static int jsm_tty_open(struct uart_port *port) |
| 195 | 197 | { |
| 196 | 198 | struct jsm_board *brd; |
| 197 | − struct jsm_channel *channel = (struct jsm_channel *)port; | |
| 199 | + struct jsm_channel *channel = | |
| 200 | + container_of(port, struct jsm_channel, uart_port); | |
| 198 | 201 | struct ktermios *termios; |
| 199 | 202 | |
| 200 | 203 | /* Get board pointer from our array of majors we have allocated */ |
| @@ -273,7 +276,8 @@ static void jsm_tty_close(struct uart_port *port) · 72 unmodified lines | ||
| 273 | 276 | { |
| 274 | 277 | struct jsm_board *bd; |
| 275 | 278 | struct ktermios *ts; |
| 276 | − struct jsm_channel *channel = (struct jsm_channel *)port; | |
| 279 | + struct jsm_channel *channel = | |
| 280 | + container_of(port, struct jsm_channel, uart_port); | |
| 277 | 281 | |
| 278 | 282 | jsm_dbg(CLOSE, &channel->ch_bd->pci_dev, "start\n"); |
| 279 | 283 | |
| @@ -307,7 +311,8 @@ static void jsm_tty_set_termios(struct uart_port *port, · 27 unmodified lines | ||
| 307 | 311 | struct ktermios *old_termios) |
| 308 | 312 | { |
| 309 | 313 | unsigned long lock_flags; |
| 310 | − struct jsm_channel *channel = (struct jsm_channel *)port; | |
| 314 | + struct jsm_channel *channel = | |
| 315 | + container_of(port, struct jsm_channel, uart_port); | |
| 311 | 316 | |
| 312 | 317 | spin_lock_irqsave(&port->lock, lock_flags); |
| 313 | 318 | channel->ch_c_cflag = termios->c_cflag; |
| @@ -415,6 +420,8 @@ int jsm_tty_init(struct jsm_board *brd) · 101 unmodified lines | ||
| 415 | 420 | |
| 416 | 421 | if (brd->bd_uart_offset == 0x200) |
| 417 | 422 | ch->ch_neo_uart = vaddr + (brd->bd_uart_offset * i); |
| 423 | + else | |
| 424 | + ch->ch_cls_uart = vaddr + (brd->bd_uart_offset * i); | |
| 418 | 425 | |
| 419 | 426 | ch->ch_bd = brd; |
| 420 | 427 | ch->ch_portnum = i; |
| @@ -497,8 +497,10 @@ lqasc_type(struct uart_port *port) · 496 unmodified lines | ||
| 497 | 497 | static void |
| 498 | 498 | lqasc_release_port(struct uart_port *port) |
| 499 | 499 | { |
| 500 | + struct platform_device *pdev = to_platform_device(port->dev); | |
| 501 | + | |
| 500 | 502 | if (port->flags & UPF_IOREMAP) { |
| 501 | − iounmap(port->membase); | |
| 503 | + devm_iounmap(&pdev->dev, port->membase); | |
| 502 | 504 | port->membase = NULL; |
| 503 | 505 | } |
| 504 | 506 | } |
| @@ -249,7 +249,8 @@ static void serial_out(struct uart_sio_port *up, int offset, int value) · 248 unmodified lines | ||
| 249 | 249 | |
| 250 | 250 | static void m32r_sio_stop_tx(struct uart_port *port) |
| 251 | 251 | { |
| 252 | − struct uart_sio_port *up = (struct uart_sio_port *)port; | |
| 252 | + struct uart_sio_port *up = | |
| 253 | + container_of(port, struct uart_sio_port, port); | |
| 253 | 254 | |
| 254 | 255 | if (up->ier & UART_IER_THRI) { |
| 255 | 256 | up->ier &= ~UART_IER_THRI; |
| @@ -260,7 +261,8 @@ static void m32r_sio_stop_tx(struct uart_port *port) · 4 unmodified lines | ||
| 260 | 261 | static void m32r_sio_start_tx(struct uart_port *port) |
| 261 | 262 | { |
| 262 | 263 | #ifdef CONFIG_SERIAL_M32R_PLDSIO |
| 263 | − struct uart_sio_port *up = (struct uart_sio_port *)port; | |
| 264 | + struct uart_sio_port *up = | |
| 265 | + container_of(port, struct uart_sio_port, port); | |
| 264 | 266 | struct circ_buf *xmit = &up->port.state->xmit; |
| 265 | 267 | |
| 266 | 268 | if (!(up->ier & UART_IER_THRI)) { |
| @@ -274,7 +276,8 @@ static void m32r_sio_start_tx(struct uart_port *port) · 7 unmodified lines | ||
| 274 | 276 | } |
| 275 | 277 | while((serial_in(up, UART_LSR) & UART_EMPTY) != UART_EMPTY); |
| 276 | 278 | #else |
| 277 | − struct uart_sio_port *up = (struct uart_sio_port *)port; | |
| 279 | + struct uart_sio_port *up = | |
| 280 | + container_of(port, struct uart_sio_port, port); | |
| 278 | 281 | |
| 279 | 282 | if (!(up->ier & UART_IER_THRI)) { |
| 280 | 283 | up->ier |= UART_IER_THRI; |
| @@ -285,7 +288,8 @@ static void m32r_sio_start_tx(struct uart_port *port) · 4 unmodified lines | ||
| 285 | 288 | |
| 286 | 289 | static void m32r_sio_stop_rx(struct uart_port *port) |
| 287 | 290 | { |
| 288 | − struct uart_sio_port *up = (struct uart_sio_port *)port; | |
| 291 | + struct uart_sio_port *up = | |
| 292 | + container_of(port, struct uart_sio_port, port); | |
| 289 | 293 | |
| 290 | 294 | up->ier &= ~UART_IER_RLSI; |
| 291 | 295 | up->port.read_status_mask &= ~UART_LSR_DR; |
| @@ -294,7 +298,8 @@ static void m32r_sio_stop_rx(struct uart_port *port) · 2 unmodified lines | ||
| 294 | 298 | |
| 295 | 299 | static void m32r_sio_enable_ms(struct uart_port *port) |
| 296 | 300 | { |
| 297 | − struct uart_sio_port *up = (struct uart_sio_port *)port; | |
| 301 | + struct uart_sio_port *up = | |
| 302 | + container_of(port, struct uart_sio_port, port); | |
| 298 | 303 | |
| 299 | 304 | up->ier |= UART_IER_MSI; |
| 300 | 305 | serial_out(up, UART_IER, up->ier); |
| @@ -581,7 +586,8 @@ static void m32r_sio_timeout(unsigned long data) · 280 unmodified lines | ||
| 581 | 586 | |
| 582 | 587 | static unsigned int m32r_sio_tx_empty(struct uart_port *port) |
| 583 | 588 | { |
| 584 | − struct uart_sio_port *up = (struct uart_sio_port *)port; | |
| 589 | + struct uart_sio_port *up = | |
| 590 | + container_of(port, struct uart_sio_port, port); | |
| 585 | 591 | unsigned long flags; |
| 586 | 592 | unsigned int ret; |
| 587 | 593 | |
| @@ -609,7 +615,8 @@ static void m32r_sio_break_ctl(struct uart_port *port, int break_state) · 21 unmodified lines | ||
| 609 | 615 | |
| 610 | 616 | static int m32r_sio_startup(struct uart_port *port) |
| 611 | 617 | { |
| 612 | − struct uart_sio_port *up = (struct uart_sio_port *)port; | |
| 618 | + struct uart_sio_port *up = | |
| 619 | + container_of(port, struct uart_sio_port, port); | |
| 613 | 620 | int retval; |
| 614 | 621 | |
| 615 | 622 | sio_init(); |
| @@ -652,7 +659,8 @@ static int m32r_sio_startup(struct uart_port *port) · 36 unmodified lines | ||
| 652 | 659 | |
| 653 | 660 | static void m32r_sio_shutdown(struct uart_port *port) |
| 654 | 661 | { |
| 655 | − struct uart_sio_port *up = (struct uart_sio_port *)port; | |
| 662 | + struct uart_sio_port *up = | |
| 663 | + container_of(port, struct uart_sio_port, port); | |
| 656 | 664 | |
| 657 | 665 | /* |
| 658 | 666 | * Disable interrupts from this port |
| @@ -681,7 +689,8 @@ static unsigned int m32r_sio_get_divisor(struct uart_port *port, · 22 unmodified lines | ||
| 681 | 689 | static void m32r_sio_set_termios(struct uart_port *port, |
| 682 | 690 | struct ktermios *termios, struct ktermios *old) |
| 683 | 691 | { |
| 684 | − struct uart_sio_port *up = (struct uart_sio_port *)port; | |
| 692 | + struct uart_sio_port *up = | |
| 693 | + container_of(port, struct uart_sio_port, port); | |
| 685 | 694 | unsigned char cval = 0; |
| 686 | 695 | unsigned long flags; |
| 687 | 696 | unsigned int baud, quot; |
| @@ -780,7 +789,8 @@ static void m32r_sio_set_termios(struct uart_port *port, · 92 unmodified lines | ||
| 780 | 789 | static void m32r_sio_pm(struct uart_port *port, unsigned int state, |
| 781 | 790 | unsigned int oldstate) |
| 782 | 791 | { |
| 783 | − struct uart_sio_port *up = (struct uart_sio_port *)port; | |
| 792 | + struct uart_sio_port *up = | |
| 793 | + container_of(port, struct uart_sio_port, port); | |
| 784 | 794 | |
| 785 | 795 | if (up->pm) |
| 786 | 796 | up->pm(port, state, oldstate); |
| @@ -825,7 +835,8 @@ m32r_sio_request_std_resource(struct uart_sio_port *up, struct resource **res) · 38 unmodified lines | ||
| 825 | 835 | |
| 826 | 836 | static void m32r_sio_release_port(struct uart_port *port) |
| 827 | 837 | { |
| 828 | − struct uart_sio_port *up = (struct uart_sio_port *)port; | |
| 838 | + struct uart_sio_port *up = | |
| 839 | + container_of(port, struct uart_sio_port, port); | |
| 829 | 840 | unsigned long start, offset = 0, size = 0; |
| 830 | 841 | |
| 831 | 842 | size <<= up->port.regshift; |
| @@ -862,7 +873,8 @@ static void m32r_sio_release_port(struct uart_port *port) · 30 unmodified lines | ||
| 862 | 873 | |
| 863 | 874 | static int m32r_sio_request_port(struct uart_port *port) |
| 864 | 875 | { |
| 865 | − struct uart_sio_port *up = (struct uart_sio_port *)port; | |
| 876 | + struct uart_sio_port *up = | |
| 877 | + container_of(port, struct uart_sio_port, port); | |
| 866 | 878 | struct resource *res = NULL; |
| 867 | 879 | int ret = 0; |
| 868 | 880 | |
| @@ -889,7 +901,8 @@ static int m32r_sio_request_port(struct uart_port *port) · 20 unmodified lines | ||
| 889 | 901 | |
| 890 | 902 | static void m32r_sio_config_port(struct uart_port *port, int unused) |
| 891 | 903 | { |
| 892 | − struct uart_sio_port *up = (struct uart_sio_port *)port; | |
| 904 | + struct uart_sio_port *up = | |
| 905 | + container_of(port, struct uart_sio_port, port); | |
| 893 | 906 | unsigned long flags; |
| 894 | 907 | |
| 895 | 908 | spin_lock_irqsave(&up->port.lock, flags); |
| @@ -1000,7 +1013,8 @@ static inline void wait_for_xmitr(struct uart_sio_port *up) · 104 unmodified lines | ||
| 1000 | 1013 | |
| 1001 | 1014 | static void m32r_sio_console_putchar(struct uart_port *port, int ch) |
| 1002 | 1015 | { |
| 1003 | − struct uart_sio_port *up = (struct uart_sio_port *)port; | |
| 1016 | + struct uart_sio_port *up = | |
| 1017 | + container_of(port, struct uart_sio_port, port); | |
| 1004 | 1018 | |
| 1005 | 1019 | wait_for_xmitr(up); |
| 1006 | 1020 | sio_out(up, SIOTXB, ch); |
| @@ -346,10 +346,13 @@ static int max3109_detect(struct device *dev) · 345 unmodified lines | ||
| 346 | 346 | unsigned int val = 0; |
| 347 | 347 | int ret; |
| 348 | 348 | |
| 349 | − ret = regmap_read(s->regmap, MAX310X_REVID_REG, &val); | |
| 349 | + ret = regmap_write(s->regmap, MAX310X_GLOBALCMD_REG, | |
| 350 | + MAX310X_EXTREG_ENBL); | |
| 350 | 351 | if (ret) |
| 351 | 352 | return ret; |
| 352 | 353 | |
| 354 | + regmap_read(s->regmap, MAX310X_REVID_EXTREG, &val); | |
| 355 | + regmap_write(s->regmap, MAX310X_GLOBALCMD_REG, MAX310X_EXTREG_DSBL); | |
| 353 | 356 | if (((val & MAX310x_REV_MASK) != MAX3109_REV_ID)) { |
| 354 | 357 | dev_err(dev, |
| 355 | 358 | "%s ID 0x%02x does not match\n", s->devtype->name, val); |
| @@ -874,55 +877,37 @@ static void max310x_set_termios(struct uart_port *port, · 518 unmodified lines | ||
| 874 | 877 | uart_update_timeout(port, termios->c_cflag, baud); |
| 875 | 878 | } |
| 876 | 879 | |
| 877 | −static int max310x_ioctl(struct uart_port *port, unsigned int cmd, | |
| 878 | − unsigned long arg) | |
| 880 | +static int max310x_rs485_config(struct uart_port *port, | |
| 881 | + struct serial_rs485 *rs485) | |
| 879 | 882 | { |
| 880 | −#if defined(TIOCSRS485) && defined(TIOCGRS485) | |
| 881 | − struct serial_rs485 rs485; | |
| 882 | 883 | unsigned int val; |
| 883 | 884 | |
| 884 | − switch (cmd) { | |
| 885 | − case TIOCSRS485: | |
| 886 | − if (copy_from_user(&rs485, (void __user *)arg, sizeof(rs485))) | |
| 887 | − return -EFAULT; | |
| 888 | − if (rs485.delay_rts_before_send > 0x0f || | |
| 889 | − rs485.delay_rts_after_send > 0x0f) | |
| 890 | − return -ERANGE; | |
| 891 | − val = (rs485.delay_rts_before_send << 4) | | |
| 892 | − rs485.delay_rts_after_send; | |
| 893 | − max310x_port_write(port, MAX310X_HDPIXDELAY_REG, val); | |
| 894 | − if (rs485.flags & SER_RS485_ENABLED) { | |
| 895 | − max310x_port_update(port, MAX310X_MODE1_REG, | |
| 896 | − MAX310X_MODE1_TRNSCVCTRL_BIT, | |
| 897 | − MAX310X_MODE1_TRNSCVCTRL_BIT); | |
| 898 | − max310x_port_update(port, MAX310X_MODE2_REG, | |
| 899 | − MAX310X_MODE2_ECHOSUPR_BIT, | |
| 900 | − MAX310X_MODE2_ECHOSUPR_BIT); | |
| 901 | − } else { | |
| 902 | − max310x_port_update(port, MAX310X_MODE1_REG, | |
| 903 | − MAX310X_MODE1_TRNSCVCTRL_BIT, 0); | |
| 904 | − max310x_port_update(port, MAX310X_MODE2_REG, | |
| 905 | − MAX310X_MODE2_ECHOSUPR_BIT, 0); | |
| 906 | − } | |
| 907 | − return 0; | |
| 908 | − case TIOCGRS485: | |
| 909 | − memset(&rs485, 0, sizeof(rs485)); | |
| 910 | − val = max310x_port_read(port, MAX310X_MODE1_REG); | |
| 911 | − rs485.flags = (val & MAX310X_MODE1_TRNSCVCTRL_BIT) ? | |
| 912 | − SER_RS485_ENABLED : 0; | |
| 913 | − rs485.flags |= SER_RS485_RTS_ON_SEND; | |
| 914 | − val = max310x_port_read(port, MAX310X_HDPIXDELAY_REG); | |
| 915 | − rs485.delay_rts_before_send = val >> 4; | |
| 916 | − rs485.delay_rts_after_send = val & 0x0f; | |
| 917 | − if (copy_to_user((void __user *)arg, &rs485, sizeof(rs485))) | |
| 918 | − return -EFAULT; | |
| 919 | − return 0; | |
| 920 | − default: | |
| 921 | − break; | |
| 885 | + if (rs485->delay_rts_before_send > 0x0f || | |
| 886 | + rs485->delay_rts_after_send > 0x0f) | |
| 887 | + return -ERANGE; | |
| 888 | + | |
| 889 | + val = (rs485->delay_rts_before_send << 4) | | |
| 890 | + rs485->delay_rts_after_send; | |
| 891 | + max310x_port_write(port, MAX310X_HDPIXDELAY_REG, val); | |
| 892 | + if (rs485->flags & SER_RS485_ENABLED) { | |
| 893 | + max310x_port_update(port, MAX310X_MODE1_REG, | |
| 894 | + MAX310X_MODE1_TRNSCVCTRL_BIT, | |
| 895 | + MAX310X_MODE1_TRNSCVCTRL_BIT); | |
| 896 | + max310x_port_update(port, MAX310X_MODE2_REG, | |
| 897 | + MAX310X_MODE2_ECHOSUPR_BIT, | |
| 898 | + MAX310X_MODE2_ECHOSUPR_BIT); | |
| 899 | + } else { | |
| 900 | + max310x_port_update(port, MAX310X_MODE1_REG, | |
| 901 | + MAX310X_MODE1_TRNSCVCTRL_BIT, 0); | |
| 902 | + max310x_port_update(port, MAX310X_MODE2_REG, | |
| 903 | + MAX310X_MODE2_ECHOSUPR_BIT, 0); | |
| 922 | 904 | } |
| 923 | −#endif | |
| 924 | 905 | |
| 925 | − return -ENOIOCTLCMD; | |
| 906 | + rs485->flags &= SER_RS485_RTS_ON_SEND | SER_RS485_ENABLED; | |
| 907 | + memset(rs485->padding, 0, sizeof(rs485->padding)); | |
| 908 | + port->rs485 = *rs485; | |
| 909 | + | |
| 910 | + return 0; | |
| 926 | 911 | } |
| 927 | 912 | |
| 928 | 913 | static int max310x_startup(struct uart_port *port) |
| @@ -1017,7 +1002,6 @@ static const struct uart_ops max310x_ops = { · 88 unmodified lines | ||
| 1017 | 1002 | .release_port = max310x_null_void, |
| 1018 | 1003 | .config_port = max310x_config_port, |
| 1019 | 1004 | .verify_port = max310x_verify_port, |
| 1020 | − .ioctl = max310x_ioctl, | |
| 1021 | 1005 | }; |
| 1022 | 1006 | |
| 1023 | 1007 | static int __maybe_unused max310x_suspend(struct device *dev) |
| @@ -1218,6 +1202,7 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, · 194 unmodified lines | ||
| 1218 | 1202 | s->p[i].port.iobase = i * 0x20; |
| 1219 | 1203 | s->p[i].port.membase = (void __iomem *)~0; |
| 1220 | 1204 | s->p[i].port.uartclk = uartclk; |
| 1205 | + s->p[i].port.rs485_config = max310x_rs485_config; | |
| 1221 | 1206 | s->p[i].port.ops = &max310x_ops; |
| 1222 | 1207 | /* Disable all interrupts */ |
| 1223 | 1208 | max310x_port_write(&s->p[i].port, MAX310X_IRQEN_REG, 0); |
| @@ -57,7 +57,6 @@ struct mcf_uart { · 56 unmodified lines | ||
| 57 | 57 | struct uart_port port; |
| 58 | 58 | unsigned int sigs; /* Local copy of line sigs */ |
| 59 | 59 | unsigned char imr; /* Local IMR mirror */ |
| 60 | − struct serial_rs485 rs485; /* RS485 settings */ | |
| 61 | 60 | }; |
| 62 | 61 | |
| 63 | 62 | /****************************************************************************/ |
| @@ -104,7 +103,7 @@ static void mcf_start_tx(struct uart_port *port) · 40 unmodified lines | ||
| 104 | 103 | { |
| 105 | 104 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); |
| 106 | 105 | |
| 107 | − if (pp->rs485.flags & SER_RS485_ENABLED) { | |
| 106 | + if (port->rs485.flags & SER_RS485_ENABLED) { | |
| 108 | 107 | /* Enable Transmitter */ |
| 109 | 108 | writeb(MCFUART_UCR_TXENABLE, port->membase + MCFUART_UCR); |
| 110 | 109 | /* Manually assert RTS */ |
| @@ -258,12 +257,12 @@ static void mcf_set_termios(struct uart_port *port, struct ktermios *termios, · 147 unmodified lines | ||
| 258 | 257 | mr2 |= MCFUART_MR2_TXCTS; |
| 259 | 258 | } |
| 260 | 259 | |
| 261 | − if (pp->rs485.flags & SER_RS485_ENABLED) { | |
| 260 | + spin_lock_irqsave(&port->lock, flags); | |
| 261 | + if (port->rs485.flags & SER_RS485_ENABLED) { | |
| 262 | 262 | dev_dbg(port->dev, "Setting UART to RS485\n"); |
| 263 | 263 | mr2 |= MCFUART_MR2_TXRTS; |
| 264 | 264 | } |
| 265 | 265 | |
| 266 | − spin_lock_irqsave(&port->lock, flags); | |
| 267 | 266 | uart_update_timeout(port, termios->c_cflag, baud); |
| 268 | 267 | writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); |
| 269 | 268 | writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR); |
| @@ -360,7 +359,7 @@ static void mcf_tx_chars(struct mcf_uart *pp) · 90 unmodified lines | ||
| 360 | 359 | pp->imr &= ~MCFUART_UIR_TXREADY; |
| 361 | 360 | writeb(pp->imr, port->membase + MCFUART_UIMR); |
| 362 | 361 | /* Disable TX to negate RTS automatically */ |
| 363 | − if (pp->rs485.flags & SER_RS485_ENABLED) | |
| 362 | + if (port->rs485.flags & SER_RS485_ENABLED) | |
| 364 | 363 | writeb(MCFUART_UCR_TXDISABLE, |
| 365 | 364 | port->membase + MCFUART_UCR); |
| 366 | 365 | } |
| @@ -440,13 +439,11 @@ static int mcf_verify_port(struct uart_port *port, struct serial_struct *ser) · 73 unmodified lines | ||
| 440 | 439 | /****************************************************************************/ |
| 441 | 440 | |
| 442 | 441 | /* Enable or disable the RS485 support */ |
| 443 | −static void mcf_config_rs485(struct uart_port *port, struct serial_rs485 *rs485) | |
| 442 | +static int mcf_config_rs485(struct uart_port *port, struct serial_rs485 *rs485) | |
| 444 | 443 | { |
| 445 | 444 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); |
| 446 | − unsigned long flags; | |
| 447 | 445 | unsigned char mr1, mr2; |
| 448 | 446 | |
| 449 | − spin_lock_irqsave(&port->lock, flags); | |
| 450 | 447 | /* Get mode registers */ |
| 451 | 448 | mr1 = readb(port->membase + MCFUART_UMR); |
| 452 | 449 | mr2 = readb(port->membase + MCFUART_UMR); |
| @@ -460,32 +457,8 @@ static void mcf_config_rs485(struct uart_port *port, struct serial_rs485 *rs485) · 7 unmodified lines | ||
| 460 | 457 | } |
| 461 | 458 | writeb(mr1, port->membase + MCFUART_UMR); |
| 462 | 459 | writeb(mr2, port->membase + MCFUART_UMR); |
| 463 | − pp->rs485 = *rs485; | |
| 464 | − spin_unlock_irqrestore(&port->lock, flags); | |
| 465 | −} | |
| 460 | + port->rs485 = *rs485; | |
| 466 | 461 | |
| 467 | −static int mcf_ioctl(struct uart_port *port, unsigned int cmd, | |
| 468 | − unsigned long arg) | |
| 469 | −{ | |
| 470 | − switch (cmd) { | |
| 471 | − case TIOCSRS485: { | |
| 472 | − struct serial_rs485 rs485; | |
| 473 | − if (copy_from_user(&rs485, (struct serial_rs485 *)arg, | |
| 474 | − sizeof(struct serial_rs485))) | |
| 475 | − return -EFAULT; | |
| 476 | − mcf_config_rs485(port, &rs485); | |
| 477 | − break; | |
| 478 | − } | |
| 479 | − case TIOCGRS485: { | |
| 480 | − struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | |
| 481 | − if (copy_to_user((struct serial_rs485 *)arg, &pp->rs485, | |
| 482 | − sizeof(struct serial_rs485))) | |
| 483 | − return -EFAULT; | |
| 484 | − break; | |
| 485 | − } | |
| 486 | − default: | |
| 487 | − return -ENOIOCTLCMD; | |
| 488 | − } | |
| 489 | 462 | return 0; |
| 490 | 463 | } |
| 491 | 464 | |
| @@ -510,7 +483,6 @@ static const struct uart_ops mcf_uart_ops = { · 18 unmodified lines | ||
| 510 | 483 | .release_port = mcf_release_port, |
| 511 | 484 | .config_port = mcf_config_port, |
| 512 | 485 | .verify_port = mcf_verify_port, |
| 513 | − .ioctl = mcf_ioctl, | |
| 514 | 486 | }; |
| 515 | 487 | |
| 516 | 488 | static struct mcf_uart mcf_ports[4]; |
| @@ -538,6 +510,7 @@ int __init early_mcf_setup(struct mcf_platform_uart *platp) · 21 unmodified lines | ||
| 538 | 510 | port->irq = platp[i].irq; |
| 539 | 511 | port->uartclk = MCF_BUSCLK; |
| 540 | 512 | port->flags = UPF_BOOT_AUTOCONF; |
| 513 | + port->rs485_config = mcf_config_rs485; | |
| 541 | 514 | port->ops = &mcf_uart_ops; |
| 542 | 515 | } |
| 543 | 516 | |
| @@ -663,6 +636,7 @@ static int mcf_probe(struct platform_device *pdev) · 119 unmodified lines | ||
| 663 | 636 | port->uartclk = MCF_BUSCLK; |
| 664 | 637 | port->ops = &mcf_uart_ops; |
| 665 | 638 | port->flags = UPF_BOOT_AUTOCONF; |
| 639 | + port->rs485_config = mcf_config_rs485; | |
| 666 | 640 | |
| 667 | 641 | uart_add_one_port(&mcf_driver, port); |
| 668 | 642 | } |
| @@ -809,6 +809,7 @@ static void men_z135_remove(struct mcb_device *mdev) · 808 unmodified lines | ||
| 809 | 809 | |
| 810 | 810 | static const struct mcb_device_id men_z135_ids[] = { |
| 811 | 811 | { .device = 0x87 }, |
| 812 | + { } | |
| 812 | 813 | }; |
| 813 | 814 | MODULE_DEVICE_TABLE(mcb, men_z135_ids); |
| 814 | 815 | |
| @@ -1371,7 +1371,7 @@ static void hsu_global_init(void) · 1370 unmodified lines | ||
| 1371 | 1371 | hsu->iolen = 0x1000; |
| 1372 | 1372 | |
| 1373 | 1373 | if (!(request_mem_region(hsu->paddr, hsu->iolen, "HSU global"))) |
| 1374 | − pr_warning("HSU: error in request mem region\n"); | |
| 1374 | + pr_warn("HSU: error in request mem region\n"); | |
| 1375 | 1375 | |
| 1376 | 1376 | hsu->reg = ioremap_nocache((unsigned long)hsu->paddr, hsu->iolen); |
| 1377 | 1377 | if (!hsu->reg) { |
| @@ -1246,7 +1246,8 @@ static irqreturn_t mpsc_sdma_intr(int irq, void *dev_id) · 1245 unmodified lines | ||
| 1246 | 1246 | */ |
| 1247 | 1247 | static uint mpsc_tx_empty(struct uart_port *port) |
| 1248 | 1248 | { |
| 1249 | − struct mpsc_port_info *pi = (struct mpsc_port_info *)port; | |
| 1249 | + struct mpsc_port_info *pi = | |
| 1250 | + container_of(port, struct mpsc_port_info, port); | |
| 1250 | 1251 | ulong iflags; |
| 1251 | 1252 | uint rc; |
| 1252 | 1253 | |
| @@ -1264,7 +1265,8 @@ static void mpsc_set_mctrl(struct uart_port *port, uint mctrl) · 11 unmodified lines | ||
| 1264 | 1265 | |
| 1265 | 1266 | static uint mpsc_get_mctrl(struct uart_port *port) |
| 1266 | 1267 | { |
| 1267 | − struct mpsc_port_info *pi = (struct mpsc_port_info *)port; | |
| 1268 | + struct mpsc_port_info *pi = | |
| 1269 | + container_of(port, struct mpsc_port_info, port); | |
| 1268 | 1270 | u32 mflags, status; |
| 1269 | 1271 | |
| 1270 | 1272 | status = (pi->mirror_regs) ? pi->MPSC_CHR_10_m |
| @@ -1281,7 +1283,8 @@ static uint mpsc_get_mctrl(struct uart_port *port) · 10 unmodified lines | ||
| 1281 | 1283 | |
| 1282 | 1284 | static void mpsc_stop_tx(struct uart_port *port) |
| 1283 | 1285 | { |
| 1284 | − struct mpsc_port_info *pi = (struct mpsc_port_info *)port; | |
| 1286 | + struct mpsc_port_info *pi = | |
| 1287 | + container_of(port, struct mpsc_port_info, port); | |
| 1285 | 1288 | |
| 1286 | 1289 | pr_debug("mpsc_stop_tx[%d]\n", port->line); |
| 1287 | 1290 | |
| @@ -1290,7 +1293,8 @@ static void mpsc_stop_tx(struct uart_port *port) · 2 unmodified lines | ||
| 1290 | 1293 | |
| 1291 | 1294 | static void mpsc_start_tx(struct uart_port *port) |
| 1292 | 1295 | { |
| 1293 | − struct mpsc_port_info *pi = (struct mpsc_port_info *)port; | |
| 1296 | + struct mpsc_port_info *pi = | |
| 1297 | + container_of(port, struct mpsc_port_info, port); | |
| 1294 | 1298 | unsigned long iflags; |
| 1295 | 1299 | |
| 1296 | 1300 | spin_lock_irqsave(&pi->tx_lock, iflags); |
| @@ -1316,7 +1320,8 @@ static void mpsc_start_rx(struct mpsc_port_info *pi) · 19 unmodified lines | ||
| 1316 | 1320 | |
| 1317 | 1321 | static void mpsc_stop_rx(struct uart_port *port) |
| 1318 | 1322 | { |
| 1319 | − struct mpsc_port_info *pi = (struct mpsc_port_info *)port; | |
| 1323 | + struct mpsc_port_info *pi = | |
| 1324 | + container_of(port, struct mpsc_port_info, port); | |
| 1320 | 1325 | |
| 1321 | 1326 | pr_debug("mpsc_stop_rx[%d]: Stopping...\n", port->line); |
| 1322 | 1327 | |
| @@ -1338,7 +1343,8 @@ static void mpsc_stop_rx(struct uart_port *port) · 15 unmodified lines | ||
| 1338 | 1343 | |
| 1339 | 1344 | static void mpsc_break_ctl(struct uart_port *port, int ctl) |
| 1340 | 1345 | { |
| 1341 | − struct mpsc_port_info *pi = (struct mpsc_port_info *)port; | |
| 1346 | + struct mpsc_port_info *pi = | |
| 1347 | + container_of(port, struct mpsc_port_info, port); | |
| 1342 | 1348 | ulong flags; |
| 1343 | 1349 | u32 v; |
| 1344 | 1350 | |
| @@ -1353,7 +1359,8 @@ static void mpsc_break_ctl(struct uart_port *port, int ctl) · 8 unmodified lines | ||
| 1353 | 1359 | |
| 1354 | 1360 | static int mpsc_startup(struct uart_port *port) |
| 1355 | 1361 | { |
| 1356 | − struct mpsc_port_info *pi = (struct mpsc_port_info *)port; | |
| 1362 | + struct mpsc_port_info *pi = | |
| 1363 | + container_of(port, struct mpsc_port_info, port); | |
| 1357 | 1364 | u32 flag = 0; |
| 1358 | 1365 | int rc; |
| 1359 | 1366 | |
| @@ -1383,7 +1390,8 @@ static int mpsc_startup(struct uart_port *port) · 23 unmodified lines | ||
| 1383 | 1390 | |
| 1384 | 1391 | static void mpsc_shutdown(struct uart_port *port) |
| 1385 | 1392 | { |
| 1386 | − struct mpsc_port_info *pi = (struct mpsc_port_info *)port; | |
| 1393 | + struct mpsc_port_info *pi = | |
| 1394 | + container_of(port, struct mpsc_port_info, port); | |
| 1387 | 1395 | |
| 1388 | 1396 | pr_debug("mpsc_shutdown[%d]: Shutting down MPSC\n", port->line); |
| 1389 | 1397 | |
| @@ -1394,7 +1402,8 @@ static void mpsc_shutdown(struct uart_port *port) · 4 unmodified lines | ||
| 1394 | 1402 | static void mpsc_set_termios(struct uart_port *port, struct ktermios *termios, |
| 1395 | 1403 | struct ktermios *old) |
| 1396 | 1404 | { |
| 1397 | − struct mpsc_port_info *pi = (struct mpsc_port_info *)port; | |
| 1405 | + struct mpsc_port_info *pi = | |
| 1406 | + container_of(port, struct mpsc_port_info, port); | |
| 1398 | 1407 | u32 baud; |
| 1399 | 1408 | ulong flags; |
| 1400 | 1409 | u32 chr_bits, stop_bits, par; |
| @@ -1498,7 +1507,8 @@ static int mpsc_request_port(struct uart_port *port) · 97 unmodified lines | ||
| 1498 | 1507 | |
| 1499 | 1508 | static void mpsc_release_port(struct uart_port *port) |
| 1500 | 1509 | { |
| 1501 | − struct mpsc_port_info *pi = (struct mpsc_port_info *)port; | |
| 1510 | + struct mpsc_port_info *pi = | |
| 1511 | + container_of(port, struct mpsc_port_info, port); | |
| 1502 | 1512 | |
| 1503 | 1513 | if (pi->ready) { |
| 1504 | 1514 | mpsc_uninit_rings(pi); |
| @@ -1513,7 +1523,8 @@ static void mpsc_config_port(struct uart_port *port, int flags) · 8 unmodified lines | ||
| 1513 | 1523 | |
| 1514 | 1524 | static int mpsc_verify_port(struct uart_port *port, struct serial_struct *ser) |
| 1515 | 1525 | { |
| 1516 | − struct mpsc_port_info *pi = (struct mpsc_port_info *)port; | |
| 1526 | + struct mpsc_port_info *pi = | |
| 1527 | + container_of(port, struct mpsc_port_info, port); | |
| 1517 | 1528 | int rc = 0; |
| 1518 | 1529 | |
| 1519 | 1530 | pr_debug("mpsc_verify_port[%d]: Verifying port data\n", pi->port.line); |
| @@ -1548,7 +1559,8 @@ static void mpsc_put_poll_char(struct uart_port *port, · 28 unmodified lines | ||
| 1548 | 1559 | |
| 1549 | 1560 | static int mpsc_get_poll_char(struct uart_port *port) |
| 1550 | 1561 | { |
| 1551 | − struct mpsc_port_info *pi = (struct mpsc_port_info *)port; | |
| 1562 | + struct mpsc_port_info *pi = | |
| 1563 | + container_of(port, struct mpsc_port_info, port); | |
| 1552 | 1564 | struct mpsc_rx_desc *rxre; |
| 1553 | 1565 | u32 cmdstat, bytes_in, i; |
| 1554 | 1566 | u8 *bp; |
| @@ -1648,7 +1660,8 @@ static int mpsc_get_poll_char(struct uart_port *port) · 93 unmodified lines | ||
| 1648 | 1660 | static void mpsc_put_poll_char(struct uart_port *port, |
| 1649 | 1661 | unsigned char c) |
| 1650 | 1662 | { |
| 1651 | − struct mpsc_port_info *pi = (struct mpsc_port_info *)port; | |
| 1663 | + struct mpsc_port_info *pi = | |
| 1664 | + container_of(port, struct mpsc_port_info, port); | |
| 1652 | 1665 | u32 data; |
| 1653 | 1666 | |
| 1654 | 1667 | data = readl(pi->mpsc_base + MPSC_MPCR); |
| @@ -27,6 +27,8 @@ · 26 unmodified lines | ||
| 27 | 27 | * interrupt for a low speed UART device |
| 28 | 28 | */ |
| 29 | 29 | |
| 30 | +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
| 31 | + | |
| 30 | 32 | #ifdef CONFIG_MAGIC_SYSRQ |
| 31 | 33 | #define SUPPORT_SYSRQ |
| 32 | 34 | #endif |
| @@ -47,8 +49,6 @@ · 14 unmodified lines | ||
| 47 | 49 | |
| 48 | 50 | #include "mrst_max3110.h" |
| 49 | 51 | |
| 50 | −#define PR_FMT "mrst_max3110: " | |
| 51 | − | |
| 52 | 52 | #define UART_TX_NEEDED 1 |
| 53 | 53 | #define CON_TX_NEEDED 2 |
| 54 | 54 | #define BIT_IRQ_PENDING 3 |
| @@ -127,8 +127,8 @@ static int max3110_out(struct uart_max3110 *max, const u16 out) · 72 unmodified lines | ||
| 127 | 127 | *obuf = out; |
| 128 | 128 | ret = max3110_write_then_read(max, obuf, ibuf, 2, 1); |
| 129 | 129 | if (ret) { |
| 130 | − pr_warning(PR_FMT "%s(): get err msg %d when sending 0x%x\n", | |
| 131 | − __func__, ret, out); | |
| 130 | + pr_warn("%s: get err msg %d when sending 0x%x\n", | |
| 131 | + __func__, ret, out); | |
| 132 | 132 | goto exit; |
| 133 | 133 | } |
| 134 | 134 | |
| @@ -153,10 +153,8 @@ static int max3110_read_multi(struct uart_max3110 *max) · 18 unmodified lines | ||
| 153 | 153 | |
| 154 | 154 | blen = M3110_RX_FIFO_DEPTH * sizeof(u16); |
| 155 | 155 | buf = kzalloc(blen * 2, GFP_KERNEL | GFP_DMA); |
| 156 | − if (!buf) { | |
| 157 | − pr_warning(PR_FMT "%s(): fail to alloc dma buffer\n", __func__); | |
| 156 | + if (!buf) | |
| 158 | 157 | return 0; |
| 159 | − } | |
| 160 | 158 | |
| 161 | 159 | /* tx/rx always have the same length */ |
| 162 | 160 | obuf = buf; |
| @@ -212,13 +210,13 @@ serial_m3110_con_setup(struct console *co, char *options) · 49 unmodified lines | ||
| 212 | 210 | int parity = 'n'; |
| 213 | 211 | int flow = 'n'; |
| 214 | 212 | |
| 215 | − pr_info(PR_FMT "setting up console\n"); | |
| 213 | + pr_info("setting up console\n"); | |
| 216 | 214 | |
| 217 | 215 | if (co->index == -1) |
| 218 | 216 | co->index = 0; |
| 219 | 217 | |
| 220 | 218 | if (!max) { |
| 221 | − pr_err(PR_FMT "pmax is NULL, return"); | |
| 219 | + pr_err("pmax is NULL, return\n"); | |
| 222 | 220 | return -ENODEV; |
| 223 | 221 | } |
| 224 | 222 | |
| @@ -296,8 +294,7 @@ static void send_circ_buf(struct uart_max3110 *max, · 71 unmodified lines | ||
| 296 | 294 | |
| 297 | 295 | ret = max3110_write_then_read(max, obuf, ibuf, blen, 0); |
| 298 | 296 | if (ret) |
| 299 | − pr_warning(PR_FMT "%s(): get err msg %d\n", | |
| 300 | − __func__, ret); | |
| 297 | + pr_warn("%s: get err msg %d\n", __func__, ret); | |
| 301 | 298 | |
| 302 | 299 | receive_chars(max, ibuf, len); |
| 303 | 300 | |
| @@ -411,7 +408,7 @@ static int max3110_main_thread(void *_max) · 107 unmodified lines | ||
| 411 | 408 | int ret = 0; |
| 412 | 409 | struct circ_buf *xmit = &max->con_xmit; |
| 413 | 410 | |
| 414 | − pr_info(PR_FMT "start main thread\n"); | |
| 411 | + pr_info("start main thread\n"); | |
| 415 | 412 | |
| 416 | 413 | do { |
| 417 | 414 | wait_event_interruptible(*wq, |
| @@ -455,7 +452,7 @@ static int max3110_read_thread(void *_max) · 37 unmodified lines | ||
| 455 | 452 | { |
| 456 | 453 | struct uart_max3110 *max = _max; |
| 457 | 454 | |
| 458 | − pr_info(PR_FMT "start read thread\n"); | |
| 455 | + pr_info("start read thread\n"); | |
| 459 | 456 | do { |
| 460 | 457 | /* |
| 461 | 458 | * If can't acquire the mutex, it means the main thread |
| @@ -481,7 +478,7 @@ static int serial_m3110_startup(struct uart_port *port) · 19 unmodified lines | ||
| 481 | 478 | int ret = 0; |
| 482 | 479 | |
| 483 | 480 | if (port->line != 0) { |
| 484 | − pr_err(PR_FMT "uart port startup failed\n"); | |
| 481 | + pr_err("uart port startup failed\n"); | |
| 485 | 482 | return -1; |
| 486 | 483 | } |
| 487 | 484 | |
| @@ -504,7 +501,7 @@ static int serial_m3110_startup(struct uart_port *port) · 16 unmodified lines | ||
| 504 | 501 | if (IS_ERR(max->read_thread)) { |
| 505 | 502 | ret = PTR_ERR(max->read_thread); |
| 506 | 503 | max->read_thread = NULL; |
| 507 | − pr_err(PR_FMT "Can't create read thread!\n"); | |
| 504 | + pr_err("Can't create read thread!\n"); | |
| 508 | 505 | return ret; |
| 509 | 506 | } |
| 510 | 507 | } |
| @@ -54,6 +54,7 @@ struct msm_port { · 53 unmodified lines | ||
| 54 | 54 | unsigned int imr; |
| 55 | 55 | int is_uartdm; |
| 56 | 56 | unsigned int old_snap_state; |
| 57 | + bool break_detected; | |
| 57 | 58 | }; |
| 58 | 59 | |
| 59 | 60 | static inline void wait_for_xmitr(struct uart_port *port) |
| @@ -126,23 +127,38 @@ static void handle_rx_dm(struct uart_port *port, unsigned int misr) · 66 unmodified lines | ||
| 126 | 127 | |
| 127 | 128 | while (count > 0) { |
| 128 | 129 | unsigned char buf[4]; |
| 130 | + int sysrq, r_count, i; | |
| 129 | 131 | |
| 130 | 132 | sr = msm_read(port, UART_SR); |
| 131 | 133 | if ((sr & UART_SR_RX_READY) == 0) { |
| 132 | 134 | msm_port->old_snap_state -= count; |
| 133 | 135 | break; |
| 134 | 136 | } |
| 137 | + | |
| 135 | 138 | ioread32_rep(port->membase + UARTDM_RF, buf, 1); |
| 136 | − if (sr & UART_SR_RX_BREAK) { | |
| 137 | − port->icount.brk++; | |
| 138 | − if (uart_handle_break(port)) | |
| 139 | − continue; | |
| 140 | − } else if (sr & UART_SR_PAR_FRAME_ERR) | |
| 141 | − port->icount.frame++; | |
| 139 | + r_count = min_t(int, count, sizeof(buf)); | |
| 142 | 140 | |
| 143 | − /* TODO: handle sysrq */ | |
| 144 | − tty_insert_flip_string(tport, buf, min(count, 4)); | |
| 145 | − count -= 4; | |
| 141 | + for (i = 0; i < r_count; i++) { | |
| 142 | + char flag = TTY_NORMAL; | |
| 143 | + | |
| 144 | + if (msm_port->break_detected && buf[i] == 0) { | |
| 145 | + port->icount.brk++; | |
| 146 | + flag = TTY_BREAK; | |
| 147 | + msm_port->break_detected = false; | |
| 148 | + if (uart_handle_break(port)) | |
| 149 | + continue; | |
| 150 | + } | |
| 151 | + | |
| 152 | + if (!(port->read_status_mask & UART_SR_RX_BREAK)) | |
| 153 | + flag = TTY_NORMAL; | |
| 154 | + | |
| 155 | + spin_unlock(&port->lock); | |
| 156 | + sysrq = uart_handle_sysrq_char(port, buf[i]); | |
| 157 | + spin_lock(&port->lock); | |
| 158 | + if (!sysrq) | |
| 159 | + tty_insert_flip_char(tport, buf[i], flag); | |
| 160 | + } | |
| 161 | + count -= r_count; | |
| 146 | 162 | } |
| 147 | 163 | |
| 148 | 164 | spin_unlock(&port->lock); |
| @@ -174,6 +190,7 @@ static void handle_rx(struct uart_port *port) · 25 unmodified lines | ||
| 174 | 190 | while ((sr = msm_read(port, UART_SR)) & UART_SR_RX_READY) { |
| 175 | 191 | unsigned int c; |
| 176 | 192 | char flag = TTY_NORMAL; |
| 193 | + int sysrq; | |
| 177 | 194 | |
| 178 | 195 | c = msm_read(port, UART_RF); |
| 179 | 196 | |
| @@ -195,7 +212,10 @@ static void handle_rx(struct uart_port *port) · 15 unmodified lines | ||
| 195 | 212 | else if (sr & UART_SR_PAR_FRAME_ERR) |
| 196 | 213 | flag = TTY_FRAME; |
| 197 | 214 | |
| 198 | − if (!uart_handle_sysrq_char(port, c)) | |
| 215 | + spin_unlock(&port->lock); | |
| 216 | + sysrq = uart_handle_sysrq_char(port, c); | |
| 217 | + spin_lock(&port->lock); | |
| 218 | + if (!sysrq) | |
| 199 | 219 | tty_insert_flip_char(tport, c, flag); |
| 200 | 220 | } |
| 201 | 221 | |
| @@ -287,6 +307,11 @@ static irqreturn_t msm_irq(int irq, void *dev_id) · 85 unmodified lines | ||
| 287 | 307 | misr = msm_read(port, UART_MISR); |
| 288 | 308 | msm_write(port, 0, UART_IMR); /* disable interrupt */ |
| 289 | 309 | |
| 310 | + if (misr & UART_IMR_RXBREAK_START) { | |
| 311 | + msm_port->break_detected = true; | |
| 312 | + msm_write(port, UART_CR_CMD_RESET_RXBREAK_START, UART_CR); | |
| 313 | + } | |
| 314 | + | |
| 290 | 315 | if (misr & (UART_IMR_RXLEV | UART_IMR_RXSTALE)) { |
| 291 | 316 | if (msm_port->is_uartdm) |
| 292 | 317 | handle_rx_dm(port, misr); |
| @@ -402,9 +427,6 @@ static int msm_set_baud_rate(struct uart_port *port, unsigned int baud) · 109 unmodified lines | ||
| 402 | 427 | |
| 403 | 428 | entry = msm_find_best_baud(port, baud); |
| 404 | 429 | |
| 405 | − if (msm_port->is_uartdm) | |
| 406 | − msm_write(port, UART_CR_CMD_RESET_RX, UART_CR); | |
| 407 | − | |
| 408 | 430 | msm_write(port, entry->code, UART_CSR); |
| 409 | 431 | |
| 410 | 432 | /* RX stale watermark */ |
| @@ -421,6 +443,18 @@ static int msm_set_baud_rate(struct uart_port *port, unsigned int baud) · 10 unmodified lines | ||
| 421 | 443 | /* set TX watermark */ |
| 422 | 444 | msm_write(port, 10, UART_TFWR); |
| 423 | 445 | |
| 446 | + msm_write(port, UART_CR_CMD_PROTECTION_EN, UART_CR); | |
| 447 | + msm_reset(port); | |
| 448 | + | |
| 449 | + /* Enable RX and TX */ | |
| 450 | + msm_write(port, UART_CR_TX_ENABLE | UART_CR_RX_ENABLE, UART_CR); | |
| 451 | + | |
| 452 | + /* turn on RX and CTS interrupts */ | |
| 453 | + msm_port->imr = UART_IMR_RXLEV | UART_IMR_RXSTALE | | |
| 454 | + UART_IMR_CURRENT_CTS | UART_IMR_RXBREAK_START; | |
| 455 | + | |
| 456 | + msm_write(port, msm_port->imr, UART_IMR); | |
| 457 | + | |
| 424 | 458 | if (msm_port->is_uartdm) { |
| 425 | 459 | msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR); |
| 426 | 460 | msm_write(port, 0xFFFFFF, UARTDM_DMRX); |
| @@ -467,40 +501,6 @@ static int msm_startup(struct uart_port *port) · 40 unmodified lines | ||
| 467 | 501 | data |= UART_MR1_AUTO_RFR_LEVEL1 & (rfr_level << 2); |
| 468 | 502 | data |= UART_MR1_AUTO_RFR_LEVEL0 & rfr_level; |
| 469 | 503 | msm_write(port, data, UART_MR1); |
| 470 | − | |
| 471 | − /* make sure that RXSTALE count is non-zero */ | |
| 472 | − data = msm_read(port, UART_IPR); | |
| 473 | − if (unlikely(!data)) { | |
| 474 | − data |= UART_IPR_RXSTALE_LAST; | |
| 475 | − data |= UART_IPR_STALE_LSB; | |
| 476 | − msm_write(port, data, UART_IPR); | |
| 477 | − } | |
| 478 | − | |
| 479 | − data = 0; | |
| 480 | − if (!port->cons || (port->cons && !(port->cons->flags & CON_ENABLED))) { | |
| 481 | − msm_write(port, UART_CR_CMD_PROTECTION_EN, UART_CR); | |
| 482 | − msm_reset(port); | |
| 483 | − data = UART_CR_TX_ENABLE; | |
| 484 | − } | |
| 485 | − | |
| 486 | − data |= UART_CR_RX_ENABLE; | |
| 487 | − msm_write(port, data, UART_CR); /* enable TX & RX */ | |
| 488 | − | |
| 489 | − /* Make sure IPR is not 0 to start with*/ | |
| 490 | − if (msm_port->is_uartdm) | |
| 491 | − msm_write(port, UART_IPR_STALE_LSB, UART_IPR); | |
| 492 | − | |
| 493 | − /* turn on RX and CTS interrupts */ | |
| 494 | − msm_port->imr = UART_IMR_RXLEV | UART_IMR_RXSTALE | | |
| 495 | − UART_IMR_CURRENT_CTS; | |
| 496 | − | |
| 497 | − if (msm_port->is_uartdm) { | |
| 498 | − msm_write(port, 0xFFFFFF, UARTDM_DMRX); | |
| 499 | − msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR); | |
| 500 | − msm_write(port, UART_CR_CMD_STALE_EVENT_ENABLE, UART_CR); | |
| 501 | − } | |
| 502 | − | |
| 503 | − msm_write(port, msm_port->imr, UART_IMR); | |
| 504 | 504 | return 0; |
| 505 | 505 | } |
| 506 | 506 | |
| @@ -1044,17 +1044,22 @@ static int msm_serial_probe(struct platform_device *pdev) · 537 unmodified lines | ||
| 1044 | 1044 | struct resource *resource; |
| 1045 | 1045 | struct uart_port *port; |
| 1046 | 1046 | const struct of_device_id *id; |
| 1047 | − int irq; | |
| 1047 | + int irq, line; | |
| 1048 | + | |
| 1049 | + if (pdev->dev.of_node) | |
| 1050 | + line = of_alias_get_id(pdev->dev.of_node, "serial"); | |
| 1051 | + else | |
| 1052 | + line = pdev->id; | |
| 1048 | 1053 | |
| 1049 | − if (pdev->id == -1) | |
| 1050 | − pdev->id = atomic_inc_return(&msm_uart_next_id) - 1; | |
| 1054 | + if (line < 0) | |
| 1055 | + line = atomic_inc_return(&msm_uart_next_id) - 1; | |
| 1051 | 1056 | |
| 1052 | − if (unlikely(pdev->id < 0 || pdev->id >= UART_NR)) | |
| 1057 | + if (unlikely(line < 0 || line >= UART_NR)) | |
| 1053 | 1058 | return -ENXIO; |
| 1054 | 1059 | |
| 1055 | − dev_info(&pdev->dev, "msm_serial: detected port #%d\n", pdev->id); | |
| 1060 | + dev_info(&pdev->dev, "msm_serial: detected port #%d\n", line); | |
| 1056 | 1061 | |
| 1057 | − port = get_port_from_line(pdev->id); | |
| 1062 | + port = get_port_from_line(line); | |
| 1058 | 1063 | port->dev = &pdev->dev; |
| 1059 | 1064 | msm_port = UART_TO_MSM(port); |
| 1060 | 1065 | |
| @@ -65,6 +65,7 @@ · 64 unmodified lines | ||
| 65 | 65 | #define UART_CR_TX_ENABLE (1 << 2) |
| 66 | 66 | #define UART_CR_RX_DISABLE (1 << 1) |
| 67 | 67 | #define UART_CR_RX_ENABLE (1 << 0) |
| 68 | +#define UART_CR_CMD_RESET_RXBREAK_START ((1 << 11) | (2 << 4)) | |
| 68 | 69 | |
| 69 | 70 | #define UART_IMR 0x0014 |
| 70 | 71 | #define UART_IMR_TXLEV (1 << 0) |
| @@ -72,6 +73,7 @@ · 1 unmodified line | ||
| 72 | 73 | #define UART_IMR_RXLEV (1 << 4) |
| 73 | 74 | #define UART_IMR_DELTA_CTS (1 << 5) |
| 74 | 75 | #define UART_IMR_CURRENT_CTS (1 << 6) |
| 76 | +#define UART_IMR_RXBREAK_START (1 << 10) | |
| 75 | 77 | |
| 76 | 78 | #define UART_IPR_RXSTALE_LAST 0x20 |
| 77 | 79 | #define UART_IPR_STALE_LSB 0x1F |
| @@ -14,6 +14,10 @@ · 13 unmodified lines | ||
| 14 | 14 | * http://www.gnu.org/copyleft/gpl.html |
| 15 | 15 | */ |
| 16 | 16 | |
| 17 | +#if defined(CONFIG_SERIAL_MXS_AUART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | |
| 18 | +#define SUPPORT_SYSRQ | |
| 19 | +#endif | |
| 20 | + | |
| 17 | 21 | #include <linux/kernel.h> |
| 18 | 22 | #include <linux/errno.h> |
| 19 | 23 | #include <linux/init.h> |
| @@ -38,6 +42,12 @@ · 18 unmodified lines | ||
| 38 | 42 | |
| 39 | 43 | #include <asm/cacheflush.h> |
| 40 | 44 | |
| 45 | +#include <linux/gpio.h> | |
| 46 | +#include <linux/gpio/consumer.h> | |
| 47 | +#include <linux/err.h> | |
| 48 | +#include <linux/irq.h> | |
| 49 | +#include "serial_mctrl_gpio.h" | |
| 50 | + | |
| 41 | 51 | #define MXS_AUART_PORTS 5 |
| 42 | 52 | #define MXS_AUART_FIFO_SIZE 16 |
| 43 | 53 | |
| @@ -139,7 +149,7 @@ struct mxs_auart_port { · 95 unmodified lines | ||
| 139 | 149 | #define MXS_AUART_DMA_RX_READY 3 /* bit 3 */ |
| 140 | 150 | #define MXS_AUART_RTSCTS 4 /* bit 4 */ |
| 141 | 151 | unsigned long flags; |
| 142 | − unsigned int ctrl; | |
| 152 | + unsigned int mctrl_prev; | |
| 143 | 153 | enum mxs_auart_type devtype; |
| 144 | 154 | |
| 145 | 155 | unsigned int irq; |
| @@ -155,6 +165,10 @@ struct mxs_auart_port { · 9 unmodified lines | ||
| 155 | 165 | struct scatterlist rx_sgl; |
| 156 | 166 | struct dma_chan *rx_dma_chan; |
| 157 | 167 | void *rx_dma_buf; |
| 168 | + | |
| 169 | + struct mctrl_gpios *gpios; | |
| 170 | + int gpio_irq[UART_GPIO_MAX]; | |
| 171 | + bool ms_irq_enabled; | |
| 158 | 172 | }; |
| 159 | 173 | |
| 160 | 174 | static struct platform_device_id mxs_auart_devtype[] = { |
| @@ -414,25 +428,102 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl) · 253 unmodified lines | ||
| 414 | 428 | ctrl |= AUART_CTRL2_RTS; |
| 415 | 429 | } |
| 416 | 430 | |
| 417 | − s->ctrl = mctrl; | |
| 418 | 431 | writel(ctrl, u->membase + AUART_CTRL2); |
| 432 | + | |
| 433 | + mctrl_gpio_set(s->gpios, mctrl); | |
| 434 | +} | |
| 435 | + | |
| 436 | +#define MCTRL_ANY_DELTA (TIOCM_RI | TIOCM_DSR | TIOCM_CD | TIOCM_CTS) | |
| 437 | +static u32 mxs_auart_modem_status(struct mxs_auart_port *s, u32 mctrl) | |
| 438 | +{ | |
| 439 | + u32 mctrl_diff; | |
| 440 | + | |
| 441 | + mctrl_diff = mctrl ^ s->mctrl_prev; | |
| 442 | + s->mctrl_prev = mctrl; | |
| 443 | + if (mctrl_diff & MCTRL_ANY_DELTA && s->ms_irq_enabled && | |
| 444 | + s->port.state != NULL) { | |
| 445 | + if (mctrl_diff & TIOCM_RI) | |
| 446 | + s->port.icount.rng++; | |
| 447 | + if (mctrl_diff & TIOCM_DSR) | |
| 448 | + s->port.icount.dsr++; | |
| 449 | + if (mctrl_diff & TIOCM_CD) | |
| 450 | + uart_handle_dcd_change(&s->port, mctrl & TIOCM_CD); | |
| 451 | + if (mctrl_diff & TIOCM_CTS) | |
| 452 | + uart_handle_cts_change(&s->port, mctrl & TIOCM_CTS); | |
| 453 | + | |
| 454 | + wake_up_interruptible(&s->port.state->port.delta_msr_wait); | |
| 455 | + } | |
| 456 | + return mctrl; | |
| 419 | 457 | } |
| 420 | 458 | |
| 421 | 459 | static u32 mxs_auart_get_mctrl(struct uart_port *u) |
| 422 | 460 | { |
| 423 | 461 | struct mxs_auart_port *s = to_auart_port(u); |
| 424 | 462 | u32 stat = readl(u->membase + AUART_STAT); |
| 425 | − int ctrl2 = readl(u->membase + AUART_CTRL2); | |
| 426 | − u32 mctrl = s->ctrl; | |
| 463 | + u32 mctrl = 0; | |
| 427 | 464 | |
| 428 | − mctrl &= ~TIOCM_CTS; | |
| 429 | 465 | if (stat & AUART_STAT_CTS) |
| 430 | 466 | mctrl |= TIOCM_CTS; |
| 431 | 467 | |
| 432 | − if (ctrl2 & AUART_CTRL2_RTS) | |
| 433 | − mctrl |= TIOCM_RTS; | |
| 468 | + return mctrl_gpio_get(s->gpios, &mctrl); | |
| 469 | +} | |
| 470 | + | |
| 471 | +/* | |
| 472 | + * Enable modem status interrupts | |
| 473 | + */ | |
| 474 | +static void mxs_auart_enable_ms(struct uart_port *port) | |
| 475 | +{ | |
| 476 | + struct mxs_auart_port *s = to_auart_port(port); | |
| 434 | 477 | |
| 435 | − return mctrl; | |
| 478 | + /* | |
| 479 | + * Interrupt should not be enabled twice | |
| 480 | + */ | |
| 481 | + if (s->ms_irq_enabled) | |
| 482 | + return; | |
| 483 | + | |
| 484 | + s->ms_irq_enabled = true; | |
| 485 | + | |
| 486 | + if (s->gpio_irq[UART_GPIO_CTS] >= 0) | |
| 487 | + enable_irq(s->gpio_irq[UART_GPIO_CTS]); | |
| 488 | + /* TODO: enable AUART_INTR_CTSMIEN otherwise */ | |
| 489 | + | |
| 490 | + if (s->gpio_irq[UART_GPIO_DSR] >= 0) | |
| 491 | + enable_irq(s->gpio_irq[UART_GPIO_DSR]); | |
| 492 | + | |
| 493 | + if (s->gpio_irq[UART_GPIO_RI] >= 0) | |
| 494 | + enable_irq(s->gpio_irq[UART_GPIO_RI]); | |
| 495 | + | |
| 496 | + if (s->gpio_irq[UART_GPIO_DCD] >= 0) | |
| 497 | + enable_irq(s->gpio_irq[UART_GPIO_DCD]); | |
| 498 | +} | |
| 499 | + | |
| 500 | +/* | |
| 501 | + * Disable modem status interrupts | |
| 502 | + */ | |
| 503 | +static void mxs_auart_disable_ms(struct uart_port *port) | |
| 504 | +{ | |
| 505 | + struct mxs_auart_port *s = to_auart_port(port); | |
| 506 | + | |
| 507 | + /* | |
| 508 | + * Interrupt should not be disabled twice | |
| 509 | + */ | |
| 510 | + if (!s->ms_irq_enabled) | |
| 511 | + return; | |
| 512 | + | |
| 513 | + s->ms_irq_enabled = false; | |
| 514 | + | |
| 515 | + if (s->gpio_irq[UART_GPIO_CTS] >= 0) | |
| 516 | + disable_irq(s->gpio_irq[UART_GPIO_CTS]); | |
| 517 | + /* TODO: disable AUART_INTR_CTSMIEN otherwise */ | |
| 518 | + | |
| 519 | + if (s->gpio_irq[UART_GPIO_DSR] >= 0) | |
| 520 | + disable_irq(s->gpio_irq[UART_GPIO_DSR]); | |
| 521 | + | |
| 522 | + if (s->gpio_irq[UART_GPIO_RI] >= 0) | |
| 523 | + disable_irq(s->gpio_irq[UART_GPIO_RI]); | |
| 524 | + | |
| 525 | + if (s->gpio_irq[UART_GPIO_DCD] >= 0) | |
| 526 | + disable_irq(s->gpio_irq[UART_GPIO_DCD]); | |
| 436 | 527 | } |
| 437 | 528 | |
| 438 | 529 | static int mxs_auart_dma_prep_rx(struct mxs_auart_port *s); |
| @@ -560,6 +651,10 @@ err_out: · 121 unmodified lines | ||
| 560 | 651 | |
| 561 | 652 | } |
| 562 | 653 | |
| 654 | +#define RTS_AT_AUART() IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(s->gpios, \ | |
| 655 | + UART_GPIO_RTS)) | |
| 656 | +#define CTS_AT_AUART() IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(s->gpios, \ | |
| 657 | + UART_GPIO_CTS)) | |
| 563 | 658 | static void mxs_auart_settermios(struct uart_port *u, |
| 564 | 659 | struct ktermios *termios, |
| 565 | 660 | struct ktermios *old) |
| @@ -636,6 +731,7 @@ static void mxs_auart_settermios(struct uart_port *u, · 70 unmodified lines | ||
| 636 | 731 | ctrl |= AUART_LINECTRL_STP2; |
| 637 | 732 | |
| 638 | 733 | /* figure out the hardware flow control settings */ |
| 734 | + ctrl2 &= ~(AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN); | |
| 639 | 735 | if (cflag & CRTSCTS) { |
| 640 | 736 | /* |
| 641 | 737 | * The DMA has a bug(see errata:2836) in mx23. |
| @@ -650,9 +746,11 @@ static void mxs_auart_settermios(struct uart_port *u, · 8 unmodified lines | ||
| 650 | 746 | ctrl2 |= AUART_CTRL2_TXDMAE | AUART_CTRL2_RXDMAE |
| 651 | 747 | | AUART_CTRL2_DMAONERR; |
| 652 | 748 | } |
| 653 | − ctrl2 |= AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN; | |
| 654 | − } else { | |
| 655 | − ctrl2 &= ~(AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN); | |
| 749 | + /* Even if RTS is GPIO line RTSEN can be enabled because | |
| 750 | + * the pinctrl configuration decides about RTS pin function */ | |
| 751 | + ctrl2 |= AUART_CTRL2_RTSEN; | |
| 752 | + if (CTS_AT_AUART()) | |
| 753 | + ctrl2 |= AUART_CTRL2_CTSEN; | |
| 656 | 754 | } |
| 657 | 755 | |
| 658 | 756 | /* set baud rate */ |
| @@ -678,12 +776,30 @@ static void mxs_auart_settermios(struct uart_port *u, · 19 unmodified lines | ||
| 678 | 776 | dev_err(s->dev, "We can not start up the DMA.\n"); |
| 679 | 777 | } |
| 680 | 778 | } |
| 779 | + | |
| 780 | + /* CTS flow-control and modem-status interrupts */ | |
| 781 | + if (UART_ENABLE_MS(u, termios->c_cflag)) | |
| 782 | + mxs_auart_enable_ms(u); | |
| 783 | + else | |
| 784 | + mxs_auart_disable_ms(u); | |
| 785 | +} | |
| 786 | + | |
| 787 | +static void mxs_auart_set_ldisc(struct uart_port *port, | |
| 788 | + struct ktermios *termios) | |
| 789 | +{ | |
| 790 | + if (termios->c_line == N_PPS) { | |
| 791 | + port->flags |= UPF_HARDPPS_CD; | |
| 792 | + mxs_auart_enable_ms(port); | |
| 793 | + } else { | |
| 794 | + port->flags &= ~UPF_HARDPPS_CD; | |
| 795 | + } | |
| 681 | 796 | } |
| 682 | 797 | |
| 683 | 798 | static irqreturn_t mxs_auart_irq_handle(int irq, void *context) |
| 684 | 799 | { |
| 685 | 800 | u32 istat; |
| 686 | 801 | struct mxs_auart_port *s = context; |
| 802 | + u32 mctrl_temp = s->mctrl_prev; | |
| 687 | 803 | u32 stat = readl(s->port.membase + AUART_STAT); |
| 688 | 804 | |
| 689 | 805 | istat = readl(s->port.membase + AUART_INTR); |
| @@ -695,8 +811,20 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context) · 5 unmodified lines | ||
| 695 | 811 | | AUART_INTR_CTSMIS), |
| 696 | 812 | s->port.membase + AUART_INTR_CLR); |
| 697 | 813 | |
| 814 | + /* | |
| 815 | + * Dealing with GPIO interrupt | |
| 816 | + */ | |
| 817 | + if (irq == s->gpio_irq[UART_GPIO_CTS] || | |
| 818 | + irq == s->gpio_irq[UART_GPIO_DCD] || | |
| 819 | + irq == s->gpio_irq[UART_GPIO_DSR] || | |
| 820 | + irq == s->gpio_irq[UART_GPIO_RI]) | |
| 821 | + mxs_auart_modem_status(s, | |
| 822 | + mctrl_gpio_get(s->gpios, &mctrl_temp)); | |
| 823 | + | |
| 698 | 824 | if (istat & AUART_INTR_CTSMIS) { |
| 699 | − uart_handle_cts_change(&s->port, stat & AUART_STAT_CTS); | |
| 825 | + if (CTS_AT_AUART() && s->ms_irq_enabled) | |
| 826 | + uart_handle_cts_change(&s->port, | |
| 827 | + stat & AUART_STAT_CTS); | |
| 700 | 828 | writel(AUART_INTR_CTSMIS, |
| 701 | 829 | s->port.membase + AUART_INTR_CLR); |
| 702 | 830 | istat &= ~AUART_INTR_CTSMIS; |
| @@ -757,6 +885,10 @@ static int mxs_auart_startup(struct uart_port *u) · 54 unmodified lines | ||
| 757 | 885 | */ |
| 758 | 886 | writel(AUART_LINECTRL_FEN, u->membase + AUART_LINECTRL_SET); |
| 759 | 887 | |
| 888 | + /* get initial status of modem lines */ | |
| 889 | + mctrl_gpio_get(s->gpios, &s->mctrl_prev); | |
| 890 | + | |
| 891 | + s->ms_irq_enabled = false; | |
| 760 | 892 | return 0; |
| 761 | 893 | } |
| 762 | 894 | |
| @@ -764,6 +896,8 @@ static void mxs_auart_shutdown(struct uart_port *u) · 1 unmodified line | ||
| 764 | 896 | { |
| 765 | 897 | struct mxs_auart_port *s = to_auart_port(u); |
| 766 | 898 | |
| 899 | + mxs_auart_disable_ms(u); | |
| 900 | + | |
| 767 | 901 | if (auart_dma_enabled(s)) |
| 768 | 902 | mxs_auart_dma_exit(s); |
| 769 | 903 | |
| @@ -779,10 +913,11 @@ static void mxs_auart_shutdown(struct uart_port *u) · 9 unmodified lines | ||
| 779 | 913 | |
| 780 | 914 | static unsigned int mxs_auart_tx_empty(struct uart_port *u) |
| 781 | 915 | { |
| 782 | − if (readl(u->membase + AUART_STAT) & AUART_STAT_TXFE) | |
| 916 | + if ((readl(u->membase + AUART_STAT) & | |
| 917 | + (AUART_STAT_TXFE | AUART_STAT_BUSY)) == AUART_STAT_TXFE) | |
| 783 | 918 | return TIOCSER_TEMT; |
| 784 | − else | |
| 785 | − return 0; | |
| 919 | + | |
| 920 | + return 0; | |
| 786 | 921 | } |
| 787 | 922 | |
| 788 | 923 | static void mxs_auart_start_tx(struct uart_port *u) |
| @@ -820,12 +955,14 @@ static struct uart_ops mxs_auart_ops = { · 31 unmodified lines | ||
| 820 | 955 | .start_tx = mxs_auart_start_tx, |
| 821 | 956 | .stop_tx = mxs_auart_stop_tx, |
| 822 | 957 | .stop_rx = mxs_auart_stop_rx, |
| 958 | + .enable_ms = mxs_auart_enable_ms, | |
| 823 | 959 | .break_ctl = mxs_auart_break_ctl, |
| 824 | 960 | .set_mctrl = mxs_auart_set_mctrl, |
| 825 | 961 | .get_mctrl = mxs_auart_get_mctrl, |
| 826 | 962 | .startup = mxs_auart_startup, |
| 827 | 963 | .shutdown = mxs_auart_shutdown, |
| 828 | 964 | .set_termios = mxs_auart_settermios, |
| 965 | + .set_ldisc = mxs_auart_set_ldisc, | |
| 829 | 966 | .type = mxs_auart_type, |
| 830 | 967 | .release_port = mxs_auart_release_port, |
| 831 | 968 | .request_port = mxs_auart_request_port, |
| @@ -1020,6 +1157,71 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s, · 188 unmodified lines | ||
| 1020 | 1157 | return 0; |
| 1021 | 1158 | } |
| 1022 | 1159 | |
| 1160 | +static bool mxs_auart_init_gpios(struct mxs_auart_port *s, struct device *dev) | |
| 1161 | +{ | |
| 1162 | + enum mctrl_gpio_idx i; | |
| 1163 | + struct gpio_desc *gpiod; | |
| 1164 | + | |
| 1165 | + s->gpios = mctrl_gpio_init(dev, 0); | |
| 1166 | + if (IS_ERR_OR_NULL(s->gpios)) | |
| 1167 | + return false; | |
| 1168 | + | |
| 1169 | + /* Block (enabled before) DMA option if RTS or CTS is GPIO line */ | |
| 1170 | + if (!RTS_AT_AUART() || !CTS_AT_AUART()) { | |
| 1171 | + if (test_bit(MXS_AUART_RTSCTS, &s->flags)) | |
| 1172 | + dev_warn(dev, | |
| 1173 | + "DMA and flow control via gpio may cause some problems. DMA disabled!\n"); | |
| 1174 | + clear_bit(MXS_AUART_RTSCTS, &s->flags); | |
| 1175 | + } | |
| 1176 | + | |
| 1177 | + for (i = 0; i < UART_GPIO_MAX; i++) { | |
| 1178 | + gpiod = mctrl_gpio_to_gpiod(s->gpios, i); | |
| 1179 | + if (gpiod && (gpiod_get_direction(gpiod) == GPIOF_DIR_IN)) | |
| 1180 | + s->gpio_irq[i] = gpiod_to_irq(gpiod); | |
| 1181 | + else | |
| 1182 | + s->gpio_irq[i] = -EINVAL; | |
| 1183 | + } | |
| 1184 | + | |
| 1185 | + return true; | |
| 1186 | +} | |
| 1187 | + | |
| 1188 | +static void mxs_auart_free_gpio_irq(struct mxs_auart_port *s) | |
| 1189 | +{ | |
| 1190 | + enum mctrl_gpio_idx i; | |
| 1191 | + | |
| 1192 | + for (i = 0; i < UART_GPIO_MAX; i++) | |
| 1193 | + if (s->gpio_irq[i] >= 0) | |
| 1194 | + free_irq(s->gpio_irq[i], s); | |
| 1195 | +} | |
| 1196 | + | |
| 1197 | +static int mxs_auart_request_gpio_irq(struct mxs_auart_port *s) | |
| 1198 | +{ | |
| 1199 | + int *irq = s->gpio_irq; | |
| 1200 | + enum mctrl_gpio_idx i; | |
| 1201 | + int err = 0; | |
| 1202 | + | |
| 1203 | + for (i = 0; (i < UART_GPIO_MAX) && !err; i++) { | |
| 1204 | + if (irq[i] < 0) | |
| 1205 | + continue; | |
| 1206 | + | |
| 1207 | + irq_set_status_flags(irq[i], IRQ_NOAUTOEN); | |
| 1208 | + err = request_irq(irq[i], mxs_auart_irq_handle, | |
| 1209 | + IRQ_TYPE_EDGE_BOTH, dev_name(s->dev), s); | |
| 1210 | + if (err) | |
| 1211 | + dev_err(s->dev, "%s - Can't get %d irq\n", | |
| 1212 | + __func__, irq[i]); | |
| 1213 | + } | |
| 1214 | + | |
| 1215 | + /* | |
| 1216 | + * If something went wrong, rollback. | |
| 1217 | + */ | |
| 1218 | + while (err && (--i >= 0)) | |
| 1219 | + if (irq[i] >= 0) | |
| 1220 | + free_irq(irq[i], s); | |
| 1221 | + | |
| 1222 | + return err; | |
| 1223 | +} | |
| 1224 | + | |
| 1023 | 1225 | static int mxs_auart_probe(struct platform_device *pdev) |
| 1024 | 1226 | { |
| 1025 | 1227 | const struct of_device_id *of_id = |
| @@ -1067,7 +1269,7 @@ static int mxs_auart_probe(struct platform_device *pdev) · 41 unmodified lines | ||
| 1067 | 1269 | s->port.type = PORT_IMX; |
| 1068 | 1270 | s->port.dev = s->dev = &pdev->dev; |
| 1069 | 1271 | |
| 1070 | − s->ctrl = 0; | |
| 1272 | + s->mctrl_prev = 0; | |
| 1071 | 1273 | |
| 1072 | 1274 | s->irq = platform_get_irq(pdev, 0); |
| 1073 | 1275 | s->port.irq = s->irq; |
| @@ -1077,13 +1279,24 @@ static int mxs_auart_probe(struct platform_device *pdev) · 3 unmodified lines | ||
| 1077 | 1279 | |
| 1078 | 1280 | platform_set_drvdata(pdev, s); |
| 1079 | 1281 | |
| 1282 | + if (!mxs_auart_init_gpios(s, &pdev->dev)) | |
| 1283 | + dev_err(&pdev->dev, | |
| 1284 | + "Failed to initialize GPIOs. The serial port may not work as expected\n"); | |
| 1285 | + | |
| 1286 | + /* | |
| 1287 | + * Get the GPIO lines IRQ | |
| 1288 | + */ | |
| 1289 | + ret = mxs_auart_request_gpio_irq(s); | |
| 1290 | + if (ret) | |
| 1291 | + goto out_free_irq; | |
| 1292 | + | |
| 1080 | 1293 | auart_port[s->port.line] = s; |
| 1081 | 1294 | |
| 1082 | 1295 | mxs_auart_reset(&s->port); |
| 1083 | 1296 | |
| 1084 | 1297 | ret = uart_add_one_port(&auart_driver, &s->port); |
| 1085 | 1298 | if (ret) |
| 1086 | − goto out_free_irq; | |
| 1299 | + goto out_free_gpio_irq; | |
| 1087 | 1300 | |
| 1088 | 1301 | version = readl(s->port.membase + AUART_VERSION); |
| 1089 | 1302 | dev_info(&pdev->dev, "Found APPUART %d.%d.%d\n", |
| @@ -1092,6 +1305,8 @@ static int mxs_auart_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 1092 | 1305 | |
| 1093 | 1306 | return 0; |
| 1094 | 1307 | |
| 1308 | +out_free_gpio_irq: | |
| 1309 | + mxs_auart_free_gpio_irq(s); | |
| 1095 | 1310 | out_free_irq: |
| 1096 | 1311 | auart_port[pdev->id] = NULL; |
| 1097 | 1312 | free_irq(s->irq, s); |
| @@ -1111,6 +1326,7 @@ static int mxs_auart_remove(struct platform_device *pdev) · 13 unmodified lines | ||
| 1111 | 1326 | |
| 1112 | 1327 | auart_port[pdev->id] = NULL; |
| 1113 | 1328 | |
| 1329 | + mxs_auart_free_gpio_irq(s); | |
| 1114 | 1330 | clk_put(s->clk); |
| 1115 | 1331 | free_irq(s->irq, s); |
| 1116 | 1332 | kfree(s); |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | * 2 of the License, or (at your option) any later version. |
| 10 | 10 | * |
| 11 | 11 | */ |
| 12 | +#include <linux/console.h> | |
| 12 | 13 | #include <linux/module.h> |
| 13 | 14 | #include <linux/slab.h> |
| 14 | 15 | #include <linux/delay.h> |
| @@ -129,8 +130,15 @@ static int of_platform_serial_setup(struct platform_device *ofdev, · 114 unmodified lines | ||
| 129 | 130 | |
| 130 | 131 | port->dev = &ofdev->dev; |
| 131 | 132 | |
| 132 | − if (type == PORT_TEGRA) | |
| 133 | + switch (type) { | |
| 134 | + case PORT_TEGRA: | |
| 133 | 135 | port->handle_break = tegra_serial_handle_break; |
| 136 | + break; | |
| 137 | + | |
| 138 | + case PORT_RT2880: | |
| 139 | + port->iotype = UPIO_AU; | |
| 140 | + break; | |
| 141 | + } | |
| 134 | 142 | |
| 135 | 143 | return 0; |
| 136 | 144 | out: |
| @@ -240,6 +248,70 @@ static int of_platform_serial_remove(struct platform_device *ofdev) · 103 unmodified lines | ||
| 240 | 248 | return 0; |
| 241 | 249 | } |
| 242 | 250 | |
| 251 | +#ifdef CONFIG_PM_SLEEP | |
| 252 | +#ifdef CONFIG_SERIAL_8250 | |
| 253 | +static void of_serial_suspend_8250(struct of_serial_info *info) | |
| 254 | +{ | |
| 255 | + struct uart_8250_port *port8250 = serial8250_get_port(info->line); | |
| 256 | + struct uart_port *port = &port8250->port; | |
| 257 | + | |
| 258 | + serial8250_suspend_port(info->line); | |
| 259 | + if (info->clk && (!uart_console(port) || console_suspend_enabled)) | |
| 260 | + clk_disable_unprepare(info->clk); | |
| 261 | +} | |
| 262 | + | |
| 263 | +static void of_serial_resume_8250(struct of_serial_info *info) | |
| 264 | +{ | |
| 265 | + struct uart_8250_port *port8250 = serial8250_get_port(info->line); | |
| 266 | + struct uart_port *port = &port8250->port; | |
| 267 | + | |
| 268 | + if (info->clk && (!uart_console(port) || console_suspend_enabled)) | |
| 269 | + clk_prepare_enable(info->clk); | |
| 270 | + | |
| 271 | + serial8250_resume_port(info->line); | |
| 272 | +} | |
| 273 | +#else | |
| 274 | +static inline void of_serial_suspend_8250(struct of_serial_info *info) | |
| 275 | +{ | |
| 276 | +} | |
| 277 | + | |
| 278 | +static inline void of_serial_resume_8250(struct of_serial_info *info) | |
| 279 | +{ | |
| 280 | +} | |
| 281 | +#endif | |
| 282 | + | |
| 283 | +static int of_serial_suspend(struct device *dev) | |
| 284 | +{ | |
| 285 | + struct of_serial_info *info = dev_get_drvdata(dev); | |
| 286 | + | |
| 287 | + switch (info->type) { | |
| 288 | + case PORT_8250 ... PORT_MAX_8250: | |
| 289 | + of_serial_suspend_8250(info); | |
| 290 | + break; | |
| 291 | + default: | |
| 292 | + break; | |
| 293 | + } | |
| 294 | + | |
| 295 | + return 0; | |
| 296 | +} | |
| 297 | + | |
| 298 | +static int of_serial_resume(struct device *dev) | |
| 299 | +{ | |
| 300 | + struct of_serial_info *info = dev_get_drvdata(dev); | |
| 301 | + | |
| 302 | + switch (info->type) { | |
| 303 | + case PORT_8250 ... PORT_MAX_8250: | |
| 304 | + of_serial_resume_8250(info); | |
| 305 | + break; | |
| 306 | + default: | |
| 307 | + break; | |
| 308 | + } | |
| 309 | + | |
| 310 | + return 0; | |
| 311 | +} | |
| 312 | +#endif | |
| 313 | +static SIMPLE_DEV_PM_OPS(of_serial_pm_ops, of_serial_suspend, of_serial_resume); | |
| 314 | + | |
| 243 | 315 | /* |
| 244 | 316 | * A few common types, add more as needed. |
| 245 | 317 | */ |
| @@ -252,6 +324,7 @@ static struct of_device_id of_platform_serial_table[] = { · 6 unmodified lines | ||
| 252 | 324 | { .compatible = "ns16850", .data = (void *)PORT_16850, }, |
| 253 | 325 | { .compatible = "nvidia,tegra20-uart", .data = (void *)PORT_TEGRA, }, |
| 254 | 326 | { .compatible = "nxp,lpc3220-uart", .data = (void *)PORT_LPC3220, }, |
| 327 | + { .compatible = "ralink,rt2880-uart", .data = (void *)PORT_RT2880, }, | |
| 255 | 328 | { .compatible = "altr,16550-FIFO32", |
| 256 | 329 | .data = (void *)PORT_ALTR_16550_F32, }, |
| 257 | 330 | { .compatible = "altr,16550-FIFO64", |
| @@ -46,7 +46,7 @@ · 45 unmodified lines | ||
| 46 | 46 | |
| 47 | 47 | #include <dt-bindings/gpio/gpio.h> |
| 48 | 48 | |
| 49 | −#define OMAP_MAX_HSUART_PORTS 6 | |
| 49 | +#define OMAP_MAX_HSUART_PORTS 10 | |
| 50 | 50 | |
| 51 | 51 | #define UART_BUILD_REVISION(x, y) (((x) << 8) | (y)) |
| 52 | 52 | |
| @@ -163,7 +163,6 @@ struct uart_omap_port { · 110 unmodified lines | ||
| 163 | 163 | u8 wakeups_enabled; |
| 164 | 164 | u32 features; |
| 165 | 165 | |
| 166 | − struct serial_rs485 rs485; | |
| 167 | 166 | int rts_gpio; |
| 168 | 167 | |
| 169 | 168 | struct pm_qos_request pm_qos_request; |
| @@ -316,7 +315,7 @@ static void serial_omap_stop_tx(struct uart_port *port) · 146 unmodified lines | ||
| 316 | 315 | pm_runtime_get_sync(up->dev); |
| 317 | 316 | |
| 318 | 317 | /* Handle RS-485 */ |
| 319 | − if (up->rs485.flags & SER_RS485_ENABLED) { | |
| 318 | + if (port->rs485.flags & SER_RS485_ENABLED) { | |
| 320 | 319 | if (up->scr & OMAP_UART_SCR_TX_EMPTY) { |
| 321 | 320 | /* THR interrupt is fired when both TX FIFO and TX |
| 322 | 321 | * shift register are empty. This means there's nothing |
| @@ -327,10 +326,12 @@ static void serial_omap_stop_tx(struct uart_port *port) · 4 unmodified lines | ||
| 327 | 326 | */ |
| 328 | 327 | up->scr &= ~OMAP_UART_SCR_TX_EMPTY; |
| 329 | 328 | serial_out(up, UART_OMAP_SCR, up->scr); |
| 330 | − res = (up->rs485.flags & SER_RS485_RTS_AFTER_SEND) ? 1 : 0; | |
| 329 | + res = (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) ? | |
| 330 | + 1 : 0; | |
| 331 | 331 | if (gpio_get_value(up->rts_gpio) != res) { |
| 332 | − if (up->rs485.delay_rts_after_send > 0) | |
| 333 | − mdelay(up->rs485.delay_rts_after_send); | |
| 332 | + if (port->rs485.delay_rts_after_send > 0) | |
| 333 | + mdelay( | |
| 334 | + port->rs485.delay_rts_after_send); | |
| 334 | 335 | gpio_set_value(up->rts_gpio, res); |
| 335 | 336 | } |
| 336 | 337 | } else { |
| @@ -353,8 +354,8 @@ static void serial_omap_stop_tx(struct uart_port *port) · 16 unmodified lines | ||
| 353 | 354 | serial_out(up, UART_IER, up->ier); |
| 354 | 355 | } |
| 355 | 356 | |
| 356 | − if ((up->rs485.flags & SER_RS485_ENABLED) && | |
| 357 | − !(up->rs485.flags & SER_RS485_RX_DURING_TX)) { | |
| 357 | + if ((port->rs485.flags & SER_RS485_ENABLED) && | |
| 358 | + !(port->rs485.flags & SER_RS485_RX_DURING_TX)) { | |
| 358 | 359 | /* |
| 359 | 360 | * Empty the RX FIFO, we are not interested in anything |
| 360 | 361 | * received during the half-duplex transmission. |
| @@ -429,22 +430,22 @@ static void serial_omap_start_tx(struct uart_port *port) · 68 unmodified lines | ||
| 429 | 430 | pm_runtime_get_sync(up->dev); |
| 430 | 431 | |
| 431 | 432 | /* Handle RS-485 */ |
| 432 | − if (up->rs485.flags & SER_RS485_ENABLED) { | |
| 433 | + if (port->rs485.flags & SER_RS485_ENABLED) { | |
| 433 | 434 | /* Fire THR interrupts when FIFO is below trigger level */ |
| 434 | 435 | up->scr &= ~OMAP_UART_SCR_TX_EMPTY; |
| 435 | 436 | serial_out(up, UART_OMAP_SCR, up->scr); |
| 436 | 437 | |
| 437 | 438 | /* if rts not already enabled */ |
| 438 | − res = (up->rs485.flags & SER_RS485_RTS_ON_SEND) ? 1 : 0; | |
| 439 | + res = (port->rs485.flags & SER_RS485_RTS_ON_SEND) ? 1 : 0; | |
| 439 | 440 | if (gpio_get_value(up->rts_gpio) != res) { |
| 440 | 441 | gpio_set_value(up->rts_gpio, res); |
| 441 | − if (up->rs485.delay_rts_before_send > 0) | |
| 442 | − mdelay(up->rs485.delay_rts_before_send); | |
| 442 | + if (port->rs485.delay_rts_before_send > 0) | |
| 443 | + mdelay(port->rs485.delay_rts_before_send); | |
| 443 | 444 | } |
| 444 | 445 | } |
| 445 | 446 | |
| 446 | − if ((up->rs485.flags & SER_RS485_ENABLED) && | |
| 447 | − !(up->rs485.flags & SER_RS485_RX_DURING_TX)) | |
| 447 | + if ((port->rs485.flags & SER_RS485_ENABLED) && | |
| 448 | + !(port->rs485.flags & SER_RS485_RX_DURING_TX)) | |
| 448 | 449 | serial_omap_stop_rx(port); |
| 449 | 450 | |
| 450 | 451 | serial_omap_enable_ier_thri(up); |
| @@ -1355,16 +1356,14 @@ static inline void serial_omap_add_console_port(struct uart_omap_port *up) · 904 unmodified lines | ||
| 1355 | 1356 | #endif |
| 1356 | 1357 | |
| 1357 | 1358 | /* Enable or disable the rs485 support */ |
| 1358 | −static void | |
| 1359 | +static int | |
| 1359 | 1360 | serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) |
| 1360 | 1361 | { |
| 1361 | 1362 | struct uart_omap_port *up = to_uart_omap_port(port); |
| 1362 | − unsigned long flags; | |
| 1363 | 1363 | unsigned int mode; |
| 1364 | 1364 | int val; |
| 1365 | 1365 | |
| 1366 | 1366 | pm_runtime_get_sync(up->dev); |
| 1367 | − spin_lock_irqsave(&up->port.lock, flags); | |
| 1368 | 1367 | |
| 1369 | 1368 | /* Disable interrupts from this port */ |
| 1370 | 1369 | mode = up->ier; |
| @@ -1372,7 +1371,7 @@ serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) · 1 unmodified line | ||
| 1372 | 1371 | serial_out(up, UART_IER, 0); |
| 1373 | 1372 | |
| 1374 | 1373 | /* store new config */ |
| 1375 | − up->rs485 = *rs485conf; | |
| 1374 | + port->rs485 = *rs485conf; | |
| 1376 | 1375 | |
| 1377 | 1376 | /* |
| 1378 | 1377 | * Just as a precaution, only allow rs485 |
| @@ -1380,12 +1379,12 @@ serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) · 1 unmodified line | ||
| 1380 | 1379 | */ |
| 1381 | 1380 | if (gpio_is_valid(up->rts_gpio)) { |
| 1382 | 1381 | /* enable / disable rts */ |
| 1383 | − val = (up->rs485.flags & SER_RS485_ENABLED) ? | |
| 1382 | + val = (port->rs485.flags & SER_RS485_ENABLED) ? | |
| 1384 | 1383 | SER_RS485_RTS_AFTER_SEND : SER_RS485_RTS_ON_SEND; |
| 1385 | − val = (up->rs485.flags & val) ? 1 : 0; | |
| 1384 | + val = (port->rs485.flags & val) ? 1 : 0; | |
| 1386 | 1385 | gpio_set_value(up->rts_gpio, val); |
| 1387 | 1386 | } else |
| 1388 | − up->rs485.flags &= ~SER_RS485_ENABLED; | |
| 1387 | + port->rs485.flags &= ~SER_RS485_ENABLED; | |
| 1389 | 1388 | |
| 1390 | 1389 | /* Enable interrupts */ |
| 1391 | 1390 | up->ier = mode; |
| @@ -1394,45 +1393,18 @@ serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) · 2 unmodified lines | ||
| 1394 | 1393 | /* If RS-485 is disabled, make sure the THR interrupt is fired when |
| 1395 | 1394 | * TX FIFO is below the trigger level. |
| 1396 | 1395 | */ |
| 1397 | − if (!(up->rs485.flags & SER_RS485_ENABLED) && | |
| 1396 | + if (!(port->rs485.flags & SER_RS485_ENABLED) && | |
| 1398 | 1397 | (up->scr & OMAP_UART_SCR_TX_EMPTY)) { |
| 1399 | 1398 | up->scr &= ~OMAP_UART_SCR_TX_EMPTY; |
| 1400 | 1399 | serial_out(up, UART_OMAP_SCR, up->scr); |
| 1401 | 1400 | } |
| 1402 | 1401 | |
| 1403 | − spin_unlock_irqrestore(&up->port.lock, flags); | |
| 1404 | 1402 | pm_runtime_mark_last_busy(up->dev); |
| 1405 | 1403 | pm_runtime_put_autosuspend(up->dev); |
| 1406 | −} | |
| 1407 | − | |
| 1408 | −static int | |
| 1409 | −serial_omap_ioctl(struct uart_port *port, unsigned int cmd, unsigned long arg) | |
| 1410 | −{ | |
| 1411 | − struct serial_rs485 rs485conf; | |
| 1412 | − | |
| 1413 | − switch (cmd) { | |
| 1414 | − case TIOCSRS485: | |
| 1415 | − if (copy_from_user(&rs485conf, (void __user *) arg, | |
| 1416 | − sizeof(rs485conf))) | |
| 1417 | − return -EFAULT; | |
| 1418 | 1404 | |
| 1419 | − serial_omap_config_rs485(port, &rs485conf); | |
| 1420 | − break; | |
| 1421 | − | |
| 1422 | − case TIOCGRS485: | |
| 1423 | − if (copy_to_user((void __user *) arg, | |
| 1424 | − &(to_uart_omap_port(port)->rs485), | |
| 1425 | − sizeof(rs485conf))) | |
| 1426 | − return -EFAULT; | |
| 1427 | − break; | |
| 1428 | − | |
| 1429 | − default: | |
| 1430 | − return -ENOIOCTLCMD; | |
| 1431 | − } | |
| 1432 | 1405 | return 0; |
| 1433 | 1406 | } |
| 1434 | 1407 | |
| 1435 | − | |
| 1436 | 1408 | static struct uart_ops serial_omap_pops = { |
| 1437 | 1409 | .tx_empty = serial_omap_tx_empty, |
| 1438 | 1410 | .set_mctrl = serial_omap_set_mctrl, |
| @@ -1453,7 +1425,6 @@ static struct uart_ops serial_omap_pops = { · 14 unmodified lines | ||
| 1453 | 1425 | .request_port = serial_omap_request_port, |
| 1454 | 1426 | .config_port = serial_omap_config_port, |
| 1455 | 1427 | .verify_port = serial_omap_verify_port, |
| 1456 | − .ioctl = serial_omap_ioctl, | |
| 1457 | 1428 | #ifdef CONFIG_CONSOLE_POLL |
| 1458 | 1429 | .poll_put_char = serial_omap_poll_put_char, |
| 1459 | 1430 | .poll_get_char = serial_omap_poll_get_char, |
| @@ -1587,7 +1558,7 @@ static struct omap_uart_port_info *of_get_uart_port_info(struct device *dev) · 127 unmodified lines | ||
| 1587 | 1558 | static int serial_omap_probe_rs485(struct uart_omap_port *up, |
| 1588 | 1559 | struct device_node *np) |
| 1589 | 1560 | { |
| 1590 | − struct serial_rs485 *rs485conf = &up->rs485; | |
| 1561 | + struct serial_rs485 *rs485conf = &up->port.rs485; | |
| 1591 | 1562 | u32 rs485_delay[2]; |
| 1592 | 1563 | enum of_gpio_flags flags; |
| 1593 | 1564 | int ret; |
| @@ -1682,14 +1653,21 @@ static int serial_omap_probe(struct platform_device *pdev) · 88 unmodified lines | ||
| 1682 | 1653 | up->port.ops = &serial_omap_pops; |
| 1683 | 1654 | |
| 1684 | 1655 | if (pdev->dev.of_node) |
| 1685 | − up->port.line = of_alias_get_id(pdev->dev.of_node, "serial"); | |
| 1656 | + ret = of_alias_get_id(pdev->dev.of_node, "serial"); | |
| 1686 | 1657 | else |
| 1687 | − up->port.line = pdev->id; | |
| 1658 | + ret = pdev->id; | |
| 1688 | 1659 | |
| 1689 | − if (up->port.line < 0) { | |
| 1660 | + if (ret < 0) { | |
| 1690 | 1661 | dev_err(&pdev->dev, "failed to get alias/pdev id, errno %d\n", |
| 1691 | − up->port.line); | |
| 1692 | − ret = -ENODEV; | |
| 1662 | + ret); | |
| 1663 | + goto err_port_line; | |
| 1664 | + } | |
| 1665 | + up->port.line = ret; | |
| 1666 | + | |
| 1667 | + if (up->port.line >= OMAP_MAX_HSUART_PORTS) { | |
| 1668 | + dev_err(&pdev->dev, "uart ID %d > MAX %d.\n", up->port.line, | |
| 1669 | + OMAP_MAX_HSUART_PORTS); | |
| 1670 | + ret = -ENXIO; | |
| 1693 | 1671 | goto err_port_line; |
| 1694 | 1672 | } |
| 1695 | 1673 | |
| @@ -1702,6 +1680,7 @@ static int serial_omap_probe(struct platform_device *pdev) · 6 unmodified lines | ||
| 1702 | 1680 | up->port.membase = base; |
| 1703 | 1681 | up->port.flags = omap_up_info->flags; |
| 1704 | 1682 | up->port.uartclk = omap_up_info->uartclk; |
| 1683 | + up->port.rs485_config = serial_omap_config_rs485; | |
| 1705 | 1684 | if (!up->port.uartclk) { |
| 1706 | 1685 | up->port.uartclk = DEFAULT_CLK_SPEED; |
| 1707 | 1686 | dev_warn(&pdev->dev, |
| @@ -1747,8 +1726,6 @@ err_add_port: · 39 unmodified lines | ||
| 1747 | 1726 | pm_runtime_disable(&pdev->dev); |
| 1748 | 1727 | err_rs485: |
| 1749 | 1728 | err_port_line: |
| 1750 | − dev_err(&pdev->dev, "[UART%d]: failure [%s]: %d\n", | |
| 1751 | − pdev->id, __func__, ret); | |
| 1752 | 1729 | return ret; |
| 1753 | 1730 | } |
| 1754 | 1731 | |
| @@ -1352,7 +1352,8 @@ static int pmz_verify_port(struct uart_port *port, struct serial_struct *ser) · 1351 unmodified lines | ||
| 1352 | 1352 | |
| 1353 | 1353 | static int pmz_poll_get_char(struct uart_port *port) |
| 1354 | 1354 | { |
| 1355 | − struct uart_pmac_port *uap = (struct uart_pmac_port *)port; | |
| 1355 | + struct uart_pmac_port *uap = | |
| 1356 | + container_of(port, struct uart_pmac_port, port); | |
| 1356 | 1357 | int tries = 2; |
| 1357 | 1358 | |
| 1358 | 1359 | while (tries) { |
| @@ -1367,7 +1368,8 @@ static int pmz_poll_get_char(struct uart_port *port) · 8 unmodified lines | ||
| 1367 | 1368 | |
| 1368 | 1369 | static void pmz_poll_put_char(struct uart_port *port, unsigned char c) |
| 1369 | 1370 | { |
| 1370 | − struct uart_pmac_port *uap = (struct uart_pmac_port *)port; | |
| 1371 | + struct uart_pmac_port *uap = | |
| 1372 | + container_of(port, struct uart_pmac_port, port); | |
| 1371 | 1373 | |
| 1372 | 1374 | /* Wait for the transmit buffer to empty. */ |
| 1373 | 1375 | while ((read_zsreg(uap, R0) & Tx_BUF_EMP) == 0) |
| @@ -1954,7 +1956,8 @@ static void __exit exit_pmz(void) · 580 unmodified lines | ||
| 1954 | 1956 | |
| 1955 | 1957 | static void pmz_console_putchar(struct uart_port *port, int ch) |
| 1956 | 1958 | { |
| 1957 | − struct uart_pmac_port *uap = (struct uart_pmac_port *)port; | |
| 1959 | + struct uart_pmac_port *uap = | |
| 1960 | + container_of(port, struct uart_pmac_port, port); | |
| 1958 | 1961 | |
| 1959 | 1962 | /* Wait for the transmit buffer to empty. */ |
| 1960 | 1963 | while ((read_zsreg(uap, R0) & Tx_BUF_EMP) == 0) |
| @@ -126,7 +126,8 @@ static void pnx8xxx_timeout(unsigned long data) · 125 unmodified lines | ||
| 126 | 126 | */ |
| 127 | 127 | static void pnx8xxx_stop_tx(struct uart_port *port) |
| 128 | 128 | { |
| 129 | − struct pnx8xxx_port *sport = (struct pnx8xxx_port *)port; | |
| 129 | + struct pnx8xxx_port *sport = | |
| 130 | + container_of(port, struct pnx8xxx_port, port); | |
| 130 | 131 | u32 ien; |
| 131 | 132 | |
| 132 | 133 | /* Disable TX intr */ |
| @@ -142,7 +143,8 @@ static void pnx8xxx_stop_tx(struct uart_port *port) · 9 unmodified lines | ||
| 142 | 143 | */ |
| 143 | 144 | static void pnx8xxx_start_tx(struct uart_port *port) |
| 144 | 145 | { |
| 145 | − struct pnx8xxx_port *sport = (struct pnx8xxx_port *)port; | |
| 146 | + struct pnx8xxx_port *sport = | |
| 147 | + container_of(port, struct pnx8xxx_port, port); | |
| 146 | 148 | u32 ien; |
| 147 | 149 | |
| 148 | 150 | /* Clear all pending TX intr */ |
| @@ -158,7 +160,8 @@ static void pnx8xxx_start_tx(struct uart_port *port) · 9 unmodified lines | ||
| 158 | 160 | */ |
| 159 | 161 | static void pnx8xxx_stop_rx(struct uart_port *port) |
| 160 | 162 | { |
| 161 | − struct pnx8xxx_port *sport = (struct pnx8xxx_port *)port; | |
| 163 | + struct pnx8xxx_port *sport = | |
| 164 | + container_of(port, struct pnx8xxx_port, port); | |
| 162 | 165 | u32 ien; |
| 163 | 166 | |
| 164 | 167 | /* Disable RX intr */ |
| @@ -174,7 +177,8 @@ static void pnx8xxx_stop_rx(struct uart_port *port) · 9 unmodified lines | ||
| 174 | 177 | */ |
| 175 | 178 | static void pnx8xxx_enable_ms(struct uart_port *port) |
| 176 | 179 | { |
| 177 | − struct pnx8xxx_port *sport = (struct pnx8xxx_port *)port; | |
| 180 | + struct pnx8xxx_port *sport = | |
| 181 | + container_of(port, struct pnx8xxx_port, port); | |
| 178 | 182 | |
| 179 | 183 | mod_timer(&sport->timer, jiffies); |
| 180 | 184 | } |
| @@ -313,14 +317,16 @@ static irqreturn_t pnx8xxx_int(int irq, void *dev_id) · 132 unmodified lines | ||
| 313 | 317 | */ |
| 314 | 318 | static unsigned int pnx8xxx_tx_empty(struct uart_port *port) |
| 315 | 319 | { |
| 316 | − struct pnx8xxx_port *sport = (struct pnx8xxx_port *)port; | |
| 320 | + struct pnx8xxx_port *sport = | |
| 321 | + container_of(port, struct pnx8xxx_port, port); | |
| 317 | 322 | |
| 318 | 323 | return serial_in(sport, PNX8XXX_FIFO) & PNX8XXX_UART_FIFO_TXFIFO_STA ? 0 : TIOCSER_TEMT; |
| 319 | 324 | } |
| 320 | 325 | |
| 321 | 326 | static unsigned int pnx8xxx_get_mctrl(struct uart_port *port) |
| 322 | 327 | { |
| 323 | − struct pnx8xxx_port *sport = (struct pnx8xxx_port *)port; | |
| 328 | + struct pnx8xxx_port *sport = | |
| 329 | + container_of(port, struct pnx8xxx_port, port); | |
| 324 | 330 | unsigned int mctrl = TIOCM_DSR; |
| 325 | 331 | unsigned int msr; |
| 326 | 332 | |
| @@ -347,7 +353,8 @@ static void pnx8xxx_set_mctrl(struct uart_port *port, unsigned int mctrl) · 20 unmodified lines | ||
| 347 | 353 | */ |
| 348 | 354 | static void pnx8xxx_break_ctl(struct uart_port *port, int break_state) |
| 349 | 355 | { |
| 350 | − struct pnx8xxx_port *sport = (struct pnx8xxx_port *)port; | |
| 356 | + struct pnx8xxx_port *sport = | |
| 357 | + container_of(port, struct pnx8xxx_port, port); | |
| 351 | 358 | unsigned long flags; |
| 352 | 359 | unsigned int lcr; |
| 353 | 360 | |
| @@ -363,7 +370,8 @@ static void pnx8xxx_break_ctl(struct uart_port *port, int break_state) · 9 unmodified lines | ||
| 363 | 370 | |
| 364 | 371 | static int pnx8xxx_startup(struct uart_port *port) |
| 365 | 372 | { |
| 366 | − struct pnx8xxx_port *sport = (struct pnx8xxx_port *)port; | |
| 373 | + struct pnx8xxx_port *sport = | |
| 374 | + container_of(port, struct pnx8xxx_port, port); | |
| 367 | 375 | int retval; |
| 368 | 376 | |
| 369 | 377 | /* |
| @@ -397,7 +405,8 @@ static int pnx8xxx_startup(struct uart_port *port) · 27 unmodified lines | ||
| 397 | 405 | |
| 398 | 406 | static void pnx8xxx_shutdown(struct uart_port *port) |
| 399 | 407 | { |
| 400 | − struct pnx8xxx_port *sport = (struct pnx8xxx_port *)port; | |
| 408 | + struct pnx8xxx_port *sport = | |
| 409 | + container_of(port, struct pnx8xxx_port, port); | |
| 401 | 410 | int lcr; |
| 402 | 411 | |
| 403 | 412 | /* |
| @@ -434,7 +443,8 @@ static void · 30 unmodified lines | ||
| 434 | 443 | pnx8xxx_set_termios(struct uart_port *port, struct ktermios *termios, |
| 435 | 444 | struct ktermios *old) |
| 436 | 445 | { |
| 437 | − struct pnx8xxx_port *sport = (struct pnx8xxx_port *)port; | |
| 446 | + struct pnx8xxx_port *sport = | |
| 447 | + container_of(port, struct pnx8xxx_port, port); | |
| 438 | 448 | unsigned long flags; |
| 439 | 449 | unsigned int lcr_fcr, old_ien, baud, quot; |
| 440 | 450 | unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; |
| @@ -551,7 +561,8 @@ pnx8xxx_set_termios(struct uart_port *port, struct ktermios *termios, · 110 unmodified lines | ||
| 551 | 561 | |
| 552 | 562 | static const char *pnx8xxx_type(struct uart_port *port) |
| 553 | 563 | { |
| 554 | − struct pnx8xxx_port *sport = (struct pnx8xxx_port *)port; | |
| 564 | + struct pnx8xxx_port *sport = | |
| 565 | + container_of(port, struct pnx8xxx_port, port); | |
| 555 | 566 | |
| 556 | 567 | return sport->port.type == PORT_PNX8XXX ? "PNX8XXX" : NULL; |
| 557 | 568 | } |
| @@ -561,7 +572,8 @@ static const char *pnx8xxx_type(struct uart_port *port) · 3 unmodified lines | ||
| 561 | 572 | */ |
| 562 | 573 | static void pnx8xxx_release_port(struct uart_port *port) |
| 563 | 574 | { |
| 564 | − struct pnx8xxx_port *sport = (struct pnx8xxx_port *)port; | |
| 575 | + struct pnx8xxx_port *sport = | |
| 576 | + container_of(port, struct pnx8xxx_port, port); | |
| 565 | 577 | |
| 566 | 578 | release_mem_region(sport->port.mapbase, UART_PORT_SIZE); |
| 567 | 579 | } |
| @@ -571,7 +583,8 @@ static void pnx8xxx_release_port(struct uart_port *port) · 3 unmodified lines | ||
| 571 | 583 | */ |
| 572 | 584 | static int pnx8xxx_request_port(struct uart_port *port) |
| 573 | 585 | { |
| 574 | − struct pnx8xxx_port *sport = (struct pnx8xxx_port *)port; | |
| 586 | + struct pnx8xxx_port *sport = | |
| 587 | + container_of(port, struct pnx8xxx_port, port); | |
| 575 | 588 | return request_mem_region(sport->port.mapbase, UART_PORT_SIZE, |
| 576 | 589 | "pnx8xxx-uart") != NULL ? 0 : -EBUSY; |
| 577 | 590 | } |
| @@ -581,7 +594,8 @@ static int pnx8xxx_request_port(struct uart_port *port) · 3 unmodified lines | ||
| 581 | 594 | */ |
| 582 | 595 | static void pnx8xxx_config_port(struct uart_port *port, int flags) |
| 583 | 596 | { |
| 584 | − struct pnx8xxx_port *sport = (struct pnx8xxx_port *)port; | |
| 597 | + struct pnx8xxx_port *sport = | |
| 598 | + container_of(port, struct pnx8xxx_port, port); | |
| 585 | 599 | |
| 586 | 600 | if (flags & UART_CONFIG_TYPE && |
| 587 | 601 | pnx8xxx_request_port(&sport->port) == 0) |
| @@ -596,7 +610,8 @@ static void pnx8xxx_config_port(struct uart_port *port, int flags) · 8 unmodified lines | ||
| 596 | 610 | static int |
| 597 | 611 | pnx8xxx_verify_port(struct uart_port *port, struct serial_struct *ser) |
| 598 | 612 | { |
| 599 | − struct pnx8xxx_port *sport = (struct pnx8xxx_port *)port; | |
| 613 | + struct pnx8xxx_port *sport = | |
| 614 | + container_of(port, struct pnx8xxx_port, port); | |
| 600 | 615 | int ret = 0; |
| 601 | 616 | |
| 602 | 617 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_PNX8XXX) |
| @@ -662,7 +677,8 @@ static void __init pnx8xxx_init_ports(void) · 59 unmodified lines | ||
| 662 | 677 | |
| 663 | 678 | static void pnx8xxx_console_putchar(struct uart_port *port, int ch) |
| 664 | 679 | { |
| 665 | − struct pnx8xxx_port *sport = (struct pnx8xxx_port *)port; | |
| 680 | + struct pnx8xxx_port *sport = | |
| 681 | + container_of(port, struct pnx8xxx_port, port); | |
| 666 | 682 | int status; |
| 667 | 683 | |
| 668 | 684 | do { |
| @@ -223,6 +223,7 @@ static void serial_pxa_start_tx(struct uart_port *port) · 222 unmodified lines | ||
| 223 | 223 | } |
| 224 | 224 | } |
| 225 | 225 | |
| 226 | +/* should hold up->port.lock */ | |
| 226 | 227 | static inline void check_modem_status(struct uart_pxa_port *up) |
| 227 | 228 | { |
| 228 | 229 | int status; |
| @@ -255,12 +256,14 @@ static inline irqreturn_t serial_pxa_irq(int irq, void *dev_id) · 26 unmodified lines | ||
| 255 | 256 | iir = serial_in(up, UART_IIR); |
| 256 | 257 | if (iir & UART_IIR_NO_INT) |
| 257 | 258 | return IRQ_NONE; |
| 259 | + spin_lock(&up->port.lock); | |
| 258 | 260 | lsr = serial_in(up, UART_LSR); |
| 259 | 261 | if (lsr & UART_LSR_DR) |
| 260 | 262 | receive_chars(up, &lsr); |
| 261 | 263 | check_modem_status(up); |
| 262 | 264 | if (lsr & UART_LSR_THRE) |
| 263 | 265 | transmit_chars(up); |
| 266 | + spin_unlock(&up->port.lock); | |
| 264 | 267 | return IRQ_HANDLED; |
| 265 | 268 | } |
| 266 | 269 | |
| @@ -142,7 +142,8 @@ static void sa1100_timeout(unsigned long data) · 141 unmodified lines | ||
| 142 | 142 | */ |
| 143 | 143 | static void sa1100_stop_tx(struct uart_port *port) |
| 144 | 144 | { |
| 145 | − struct sa1100_port *sport = (struct sa1100_port *)port; | |
| 145 | + struct sa1100_port *sport = | |
| 146 | + container_of(port, struct sa1100_port, port); | |
| 146 | 147 | u32 utcr3; |
| 147 | 148 | |
| 148 | 149 | utcr3 = UART_GET_UTCR3(sport); |
| @@ -155,7 +156,8 @@ static void sa1100_stop_tx(struct uart_port *port) · 6 unmodified lines | ||
| 155 | 156 | */ |
| 156 | 157 | static void sa1100_start_tx(struct uart_port *port) |
| 157 | 158 | { |
| 158 | − struct sa1100_port *sport = (struct sa1100_port *)port; | |
| 159 | + struct sa1100_port *sport = | |
| 160 | + container_of(port, struct sa1100_port, port); | |
| 159 | 161 | u32 utcr3; |
| 160 | 162 | |
| 161 | 163 | utcr3 = UART_GET_UTCR3(sport); |
| @@ -168,7 +170,8 @@ static void sa1100_start_tx(struct uart_port *port) · 6 unmodified lines | ||
| 168 | 170 | */ |
| 169 | 171 | static void sa1100_stop_rx(struct uart_port *port) |
| 170 | 172 | { |
| 171 | − struct sa1100_port *sport = (struct sa1100_port *)port; | |
| 173 | + struct sa1100_port *sport = | |
| 174 | + container_of(port, struct sa1100_port, port); | |
| 172 | 175 | u32 utcr3; |
| 173 | 176 | |
| 174 | 177 | utcr3 = UART_GET_UTCR3(sport); |
| @@ -180,7 +183,8 @@ static void sa1100_stop_rx(struct uart_port *port) · 5 unmodified lines | ||
| 180 | 183 | */ |
| 181 | 184 | static void sa1100_enable_ms(struct uart_port *port) |
| 182 | 185 | { |
| 183 | − struct sa1100_port *sport = (struct sa1100_port *)port; | |
| 186 | + struct sa1100_port *sport = | |
| 187 | + container_of(port, struct sa1100_port, port); | |
| 184 | 188 | |
| 185 | 189 | mod_timer(&sport->timer, jiffies); |
| 186 | 190 | } |
| @@ -323,7 +327,8 @@ static irqreturn_t sa1100_int(int irq, void *dev_id) · 136 unmodified lines | ||
| 323 | 327 | */ |
| 324 | 328 | static unsigned int sa1100_tx_empty(struct uart_port *port) |
| 325 | 329 | { |
| 326 | − struct sa1100_port *sport = (struct sa1100_port *)port; | |
| 330 | + struct sa1100_port *sport = | |
| 331 | + container_of(port, struct sa1100_port, port); | |
| 327 | 332 | |
| 328 | 333 | return UART_GET_UTSR1(sport) & UTSR1_TBY ? 0 : TIOCSER_TEMT; |
| 329 | 334 | } |
| @@ -342,7 +347,8 @@ static void sa1100_set_mctrl(struct uart_port *port, unsigned int mctrl) · 12 unmodified lines | ||
| 342 | 347 | */ |
| 343 | 348 | static void sa1100_break_ctl(struct uart_port *port, int break_state) |
| 344 | 349 | { |
| 345 | − struct sa1100_port *sport = (struct sa1100_port *)port; | |
| 350 | + struct sa1100_port *sport = | |
| 351 | + container_of(port, struct sa1100_port, port); | |
| 346 | 352 | unsigned long flags; |
| 347 | 353 | unsigned int utcr3; |
| 348 | 354 | |
| @@ -358,7 +364,8 @@ static void sa1100_break_ctl(struct uart_port *port, int break_state) · 9 unmodified lines | ||
| 358 | 364 | |
| 359 | 365 | static int sa1100_startup(struct uart_port *port) |
| 360 | 366 | { |
| 361 | − struct sa1100_port *sport = (struct sa1100_port *)port; | |
| 367 | + struct sa1100_port *sport = | |
| 368 | + container_of(port, struct sa1100_port, port); | |
| 362 | 369 | int retval; |
| 363 | 370 | |
| 364 | 371 | /* |
| @@ -387,7 +394,8 @@ static int sa1100_startup(struct uart_port *port) · 22 unmodified lines | ||
| 387 | 394 | |
| 388 | 395 | static void sa1100_shutdown(struct uart_port *port) |
| 389 | 396 | { |
| 390 | − struct sa1100_port *sport = (struct sa1100_port *)port; | |
| 397 | + struct sa1100_port *sport = | |
| 398 | + container_of(port, struct sa1100_port, port); | |
| 391 | 399 | |
| 392 | 400 | /* |
| 393 | 401 | * Stop our timer. |
| @@ -409,7 +417,8 @@ static void · 15 unmodified lines | ||
| 409 | 417 | sa1100_set_termios(struct uart_port *port, struct ktermios *termios, |
| 410 | 418 | struct ktermios *old) |
| 411 | 419 | { |
| 412 | − struct sa1100_port *sport = (struct sa1100_port *)port; | |
| 420 | + struct sa1100_port *sport = | |
| 421 | + container_of(port, struct sa1100_port, port); | |
| 413 | 422 | unsigned long flags; |
| 414 | 423 | unsigned int utcr0, old_utcr3, baud, quot; |
| 415 | 424 | unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; |
| @@ -512,7 +521,8 @@ sa1100_set_termios(struct uart_port *port, struct ktermios *termios, · 96 unmodified lines | ||
| 512 | 521 | |
| 513 | 522 | static const char *sa1100_type(struct uart_port *port) |
| 514 | 523 | { |
| 515 | − struct sa1100_port *sport = (struct sa1100_port *)port; | |
| 524 | + struct sa1100_port *sport = | |
| 525 | + container_of(port, struct sa1100_port, port); | |
| 516 | 526 | |
| 517 | 527 | return sport->port.type == PORT_SA1100 ? "SA1100" : NULL; |
| 518 | 528 | } |
| @@ -522,7 +532,8 @@ static const char *sa1100_type(struct uart_port *port) · 3 unmodified lines | ||
| 522 | 532 | */ |
| 523 | 533 | static void sa1100_release_port(struct uart_port *port) |
| 524 | 534 | { |
| 525 | − struct sa1100_port *sport = (struct sa1100_port *)port; | |
| 535 | + struct sa1100_port *sport = | |
| 536 | + container_of(port, struct sa1100_port, port); | |
| 526 | 537 | |
| 527 | 538 | release_mem_region(sport->port.mapbase, UART_PORT_SIZE); |
| 528 | 539 | } |
| @@ -532,7 +543,8 @@ static void sa1100_release_port(struct uart_port *port) · 3 unmodified lines | ||
| 532 | 543 | */ |
| 533 | 544 | static int sa1100_request_port(struct uart_port *port) |
| 534 | 545 | { |
| 535 | − struct sa1100_port *sport = (struct sa1100_port *)port; | |
| 546 | + struct sa1100_port *sport = | |
| 547 | + container_of(port, struct sa1100_port, port); | |
| 536 | 548 | |
| 537 | 549 | return request_mem_region(sport->port.mapbase, UART_PORT_SIZE, |
| 538 | 550 | "sa11x0-uart") != NULL ? 0 : -EBUSY; |
| @@ -543,7 +555,8 @@ static int sa1100_request_port(struct uart_port *port) · 4 unmodified lines | ||
| 543 | 555 | */ |
| 544 | 556 | static void sa1100_config_port(struct uart_port *port, int flags) |
| 545 | 557 | { |
| 546 | − struct sa1100_port *sport = (struct sa1100_port *)port; | |
| 558 | + struct sa1100_port *sport = | |
| 559 | + container_of(port, struct sa1100_port, port); | |
| 547 | 560 | |
| 548 | 561 | if (flags & UART_CONFIG_TYPE && |
| 549 | 562 | sa1100_request_port(&sport->port) == 0) |
| @@ -558,7 +571,8 @@ static void sa1100_config_port(struct uart_port *port, int flags) · 8 unmodified lines | ||
| 558 | 571 | static int |
| 559 | 572 | sa1100_verify_port(struct uart_port *port, struct serial_struct *ser) |
| 560 | 573 | { |
| 561 | − struct sa1100_port *sport = (struct sa1100_port *)port; | |
| 574 | + struct sa1100_port *sport = | |
| 575 | + container_of(port, struct sa1100_port, port); | |
| 562 | 576 | int ret = 0; |
| 563 | 577 | |
| 564 | 578 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_SA1100) |
| @@ -691,7 +705,8 @@ void __init sa1100_register_uart(int idx, int port) · 126 unmodified lines | ||
| 691 | 705 | #ifdef CONFIG_SERIAL_SA1100_CONSOLE |
| 692 | 706 | static void sa1100_console_putchar(struct uart_port *port, int ch) |
| 693 | 707 | { |
| 694 | − struct sa1100_port *sport = (struct sa1100_port *)port; | |
| 708 | + struct sa1100_port *sport = | |
| 709 | + container_of(port, struct sa1100_port, port); | |
| 695 | 710 | |
| 696 | 711 | while (!(UART_GET_UTSR1(sport) & UTSR1_TNF)) |
| 697 | 712 | barrier(); |
| @@ -199,12 +199,14 @@ static void s3c24xx_serial_stop_rx(struct uart_port *port) · 198 unmodified lines | ||
| 199 | 199 | } |
| 200 | 200 | } |
| 201 | 201 | |
| 202 | −static inline struct s3c24xx_uart_info *s3c24xx_port_to_info(struct uart_port *port) | |
| 202 | +static inline struct s3c24xx_uart_info | |
| 203 | + *s3c24xx_port_to_info(struct uart_port *port) | |
| 203 | 204 | { |
| 204 | 205 | return to_ourport(port)->info; |
| 205 | 206 | } |
| 206 | 207 | |
| 207 | −static inline struct s3c2410_uartcfg *s3c24xx_port_to_cfg(struct uart_port *port) | |
| 208 | +static inline struct s3c2410_uartcfg | |
| 209 | + *s3c24xx_port_to_cfg(struct uart_port *port) | |
| 208 | 210 | { |
| 209 | 211 | struct s3c24xx_uart_port *ourport; |
| 210 | 212 | |
| @@ -237,7 +239,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id) · 26 unmodified lines | ||
| 237 | 239 | struct uart_port *port = &ourport->port; |
| 238 | 240 | unsigned int ufcon, ch, flag, ufstat, uerstat; |
| 239 | 241 | unsigned long flags; |
| 240 | − int max_count = 64; | |
| 242 | + int max_count = port->fifosize; | |
| 241 | 243 | |
| 242 | 244 | spin_lock_irqsave(&port->lock, flags); |
| 243 | 245 | |
| @@ -311,14 +313,14 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id) · 67 unmodified lines | ||
| 311 | 313 | uart_insert_char(port, uerstat, S3C2410_UERSTAT_OVERRUN, |
| 312 | 314 | ch, flag); |
| 313 | 315 | |
| 314 | − ignore_char: | |
| 316 | +ignore_char: | |
| 315 | 317 | continue; |
| 316 | 318 | } |
| 317 | 319 | |
| 318 | 320 | spin_unlock_irqrestore(&port->lock, flags); |
| 319 | 321 | tty_flip_buffer_push(&port->state->port); |
| 320 | 322 | |
| 321 | − out: | |
| 323 | +out: | |
| 322 | 324 | return IRQ_HANDLED; |
| 323 | 325 | } |
| 324 | 326 | |
| @@ -328,7 +330,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id) · 3 unmodified lines | ||
| 328 | 330 | struct uart_port *port = &ourport->port; |
| 329 | 331 | struct circ_buf *xmit = &port->state->xmit; |
| 330 | 332 | unsigned long flags; |
| 331 | − int count = 256; | |
| 333 | + int count = port->fifosize; | |
| 332 | 334 | |
| 333 | 335 | spin_lock_irqsave(&port->lock, flags); |
| 334 | 336 | |
| @@ -368,7 +370,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id) · 33 unmodified lines | ||
| 368 | 370 | if (uart_circ_empty(xmit)) |
| 369 | 371 | s3c24xx_serial_stop_tx(port); |
| 370 | 372 | |
| 371 | − out: | |
| 373 | +out: | |
| 372 | 374 | spin_unlock_irqrestore(&port->lock, flags); |
| 373 | 375 | return IRQ_HANDLED; |
| 374 | 376 | } |
| @@ -519,7 +521,7 @@ static int s3c24xx_serial_startup(struct uart_port *port) · 144 unmodified lines | ||
| 519 | 521 | |
| 520 | 522 | return ret; |
| 521 | 523 | |
| 522 | − err: | |
| 524 | +err: | |
| 523 | 525 | s3c24xx_serial_shutdown(port); |
| 524 | 526 | return ret; |
| 525 | 527 | } |
| @@ -559,11 +561,15 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level, · 33 unmodified lines | ||
| 559 | 561 | unsigned int old) |
| 560 | 562 | { |
| 561 | 563 | struct s3c24xx_uart_port *ourport = to_ourport(port); |
| 564 | + int timeout = 10000; | |
| 562 | 565 | |
| 563 | 566 | ourport->pm_level = level; |
| 564 | 567 | |
| 565 | 568 | switch (level) { |
| 566 | 569 | case 3: |
| 570 | + while (--timeout && !s3c24xx_serial_txempty_nofifo(port)) | |
| 571 | + udelay(100); | |
| 572 | + | |
| 567 | 573 | if (!IS_ERR(ourport->baudclk)) |
| 568 | 574 | clk_disable_unprepare(ourport->baudclk); |
| 569 | 575 | |
| @@ -841,8 +847,8 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, · 271 unmodified lines | ||
| 841 | 847 | */ |
| 842 | 848 | port->read_status_mask = S3C2410_UERSTAT_OVERRUN; |
| 843 | 849 | if (termios->c_iflag & INPCK) |
| 844 | − port->read_status_mask |= S3C2410_UERSTAT_FRAME | S3C2410_UERSTAT_PARITY; | |
| 845 | − | |
| 850 | + port->read_status_mask |= S3C2410_UERSTAT_FRAME | | |
| 851 | + S3C2410_UERSTAT_PARITY; | |
| 846 | 852 | /* |
| 847 | 853 | * Which character status flags should we ignore? |
| 848 | 854 | */ |
| @@ -969,10 +975,13 @@ static struct uart_driver s3c24xx_uart_drv = { · 120 unmodified lines | ||
| 969 | 975 | .minor = S3C24XX_SERIAL_MINOR, |
| 970 | 976 | }; |
| 971 | 977 | |
| 972 | −static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS] = { | |
| 978 | +#define __PORT_LOCK_UNLOCKED(i) \ | |
| 979 | + __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[i].port.lock) | |
| 980 | +static struct s3c24xx_uart_port | |
| 981 | +s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS] = { | |
| 973 | 982 | [0] = { |
| 974 | 983 | .port = { |
| 975 | − .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock), | |
| 984 | + .lock = __PORT_LOCK_UNLOCKED(0), | |
| 976 | 985 | .iotype = UPIO_MEM, |
| 977 | 986 | .uartclk = 0, |
| 978 | 987 | .fifosize = 16, |
| @@ -983,7 +992,7 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS · 4 unmodified lines | ||
| 983 | 992 | }, |
| 984 | 993 | [1] = { |
| 985 | 994 | .port = { |
| 986 | − .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[1].port.lock), | |
| 995 | + .lock = __PORT_LOCK_UNLOCKED(1), | |
| 987 | 996 | .iotype = UPIO_MEM, |
| 988 | 997 | .uartclk = 0, |
| 989 | 998 | .fifosize = 16, |
| @@ -996,7 +1005,7 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS · 6 unmodified lines | ||
| 996 | 1005 | |
| 997 | 1006 | [2] = { |
| 998 | 1007 | .port = { |
| 999 | − .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[2].port.lock), | |
| 1008 | + .lock = __PORT_LOCK_UNLOCKED(2), | |
| 1000 | 1009 | .iotype = UPIO_MEM, |
| 1001 | 1010 | .uartclk = 0, |
| 1002 | 1011 | .fifosize = 16, |
| @@ -1009,7 +1018,7 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS · 6 unmodified lines | ||
| 1009 | 1018 | #if CONFIG_SERIAL_SAMSUNG_UARTS > 3 |
| 1010 | 1019 | [3] = { |
| 1011 | 1020 | .port = { |
| 1012 | − .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[3].port.lock), | |
| 1021 | + .lock = __PORT_LOCK_UNLOCKED(3), | |
| 1013 | 1022 | .iotype = UPIO_MEM, |
| 1014 | 1023 | .uartclk = 0, |
| 1015 | 1024 | .fifosize = 16, |
| @@ -1020,6 +1029,7 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS · 4 unmodified lines | ||
| 1020 | 1029 | } |
| 1021 | 1030 | #endif |
| 1022 | 1031 | }; |
| 1032 | +#undef __PORT_LOCK_UNLOCKED | |
| 1023 | 1033 | |
| 1024 | 1034 | /* s3c24xx_serial_resetport |
| 1025 | 1035 | * |
| @@ -1102,11 +1112,12 @@ static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb, · 76 unmodified lines | ||
| 1102 | 1112 | s3c24xx_serial_set_termios(uport, termios, NULL); |
| 1103 | 1113 | } |
| 1104 | 1114 | |
| 1105 | − exit: | |
| 1115 | +exit: | |
| 1106 | 1116 | return 0; |
| 1107 | 1117 | } |
| 1108 | 1118 | |
| 1109 | −static inline int s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port) | |
| 1119 | +static inline int | |
| 1120 | +s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port) | |
| 1110 | 1121 | { |
| 1111 | 1122 | port->freq_transition.notifier_call = s3c24xx_serial_cpufreq_transition; |
| 1112 | 1123 | |
| @@ -1114,19 +1125,22 @@ static inline int s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port · 1 unmodified line | ||
| 1114 | 1125 | CPUFREQ_TRANSITION_NOTIFIER); |
| 1115 | 1126 | } |
| 1116 | 1127 | |
| 1117 | −static inline void s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port) | |
| 1128 | +static inline void | |
| 1129 | +s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port) | |
| 1118 | 1130 | { |
| 1119 | 1131 | cpufreq_unregister_notifier(&port->freq_transition, |
| 1120 | 1132 | CPUFREQ_TRANSITION_NOTIFIER); |
| 1121 | 1133 | } |
| 1122 | 1134 | |
| 1123 | 1135 | #else |
| 1124 | −static inline int s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port) | |
| 1136 | +static inline int | |
| 1137 | +s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port) | |
| 1125 | 1138 | { |
| 1126 | 1139 | return 0; |
| 1127 | 1140 | } |
| 1128 | 1141 | |
| 1129 | −static inline void s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port) | |
| 1142 | +static inline void | |
| 1143 | +s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port) | |
| 1130 | 1144 | { |
| 1131 | 1145 | } |
| 1132 | 1146 | #endif |
| @@ -1226,24 +1240,6 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, · 93 unmodified lines | ||
| 1226 | 1240 | return 0; |
| 1227 | 1241 | } |
| 1228 | 1242 | |
| 1229 | −#ifdef CONFIG_SAMSUNG_CLOCK | |
| 1230 | −static ssize_t s3c24xx_serial_show_clksrc(struct device *dev, | |
| 1231 | − struct device_attribute *attr, | |
| 1232 | − char *buf) | |
| 1233 | −{ | |
| 1234 | − struct uart_port *port = s3c24xx_dev_to_port(dev); | |
| 1235 | − struct s3c24xx_uart_port *ourport = to_ourport(port); | |
| 1236 | − | |
| 1237 | − if (IS_ERR(ourport->baudclk)) | |
| 1238 | − return -EINVAL; | |
| 1239 | − | |
| 1240 | − return snprintf(buf, PAGE_SIZE, "* %s\n", | |
| 1241 | − ourport->baudclk->name ?: "(null)"); | |
| 1242 | −} | |
| 1243 | − | |
| 1244 | −static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL); | |
| 1245 | −#endif | |
| 1246 | − | |
| 1247 | 1243 | /* Device driver serial port probe */ |
| 1248 | 1244 | |
| 1249 | 1245 | static const struct of_device_id s3c24xx_uart_dt_match[]; |
| @@ -1296,11 +1292,10 @@ static int s3c24xx_serial_probe(struct platform_device *pdev) · 46 unmodified lines | ||
| 1296 | 1292 | of_property_read_u32(np, |
| 1297 | 1293 | "samsung,uart-fifosize", &ourport->port.fifosize); |
| 1298 | 1294 | |
| 1299 | − if (!ourport->port.fifosize) { | |
| 1300 | − ourport->port.fifosize = (ourport->info->fifosize) ? | |
| 1301 | − ourport->info->fifosize : | |
| 1302 | − ourport->drv_data->fifosize[index]; | |
| 1303 | − } | |
| 1295 | + if (ourport->drv_data->fifosize[index]) | |
| 1296 | + ourport->port.fifosize = ourport->drv_data->fifosize[index]; | |
| 1297 | + else if (ourport->info->fifosize) | |
| 1298 | + ourport->port.fifosize = ourport->info->fifosize; | |
| 1304 | 1299 | |
| 1305 | 1300 | probe_index++; |
| 1306 | 1301 | |
| @@ -1329,12 +1324,6 @@ static int s3c24xx_serial_probe(struct platform_device *pdev) · 22 unmodified lines | ||
| 1329 | 1324 | */ |
| 1330 | 1325 | clk_disable_unprepare(ourport->clk); |
| 1331 | 1326 | |
| 1332 | −#ifdef CONFIG_SAMSUNG_CLOCK | |
| 1333 | − ret = device_create_file(&pdev->dev, &dev_attr_clock_source); | |
| 1334 | − if (ret < 0) | |
| 1335 | − dev_err(&pdev->dev, "failed to add clock source attr.\n"); | |
| 1336 | −#endif | |
| 1337 | − | |
| 1338 | 1327 | ret = s3c24xx_serial_cpufreq_register(ourport); |
| 1339 | 1328 | if (ret < 0) |
| 1340 | 1329 | dev_err(&pdev->dev, "failed to add cpufreq notifier\n"); |
| @@ -1348,9 +1337,6 @@ static int s3c24xx_serial_remove(struct platform_device *dev) · 7 unmodified lines | ||
| 1348 | 1337 | |
| 1349 | 1338 | if (port) { |
| 1350 | 1339 | s3c24xx_serial_cpufreq_deregister(to_ourport(port)); |
| 1351 | −#ifdef CONFIG_SAMSUNG_CLOCK | |
| 1352 | − device_remove_file(&dev->dev, &dev_attr_clock_source); | |
| 1353 | −#endif | |
| 1354 | 1340 | uart_remove_one_port(&s3c24xx_uart_drv, port); |
| 1355 | 1341 | } |
| 1356 | 1342 | |
| @@ -304,8 +304,6 @@ struct sc16is7xx_one { · 303 unmodified lines | ||
| 304 | 304 | struct uart_port port; |
| 305 | 305 | struct work_struct tx_work; |
| 306 | 306 | struct work_struct md_work; |
| 307 | − | |
| 308 | − struct serial_rs485 rs485; | |
| 309 | 307 | }; |
| 310 | 308 | |
| 311 | 309 | struct sc16is7xx_port { |
| @@ -657,15 +655,15 @@ static void sc16is7xx_stop_tx(struct uart_port* port) · 345 unmodified lines | ||
| 657 | 655 | struct circ_buf *xmit = &one->port.state->xmit; |
| 658 | 656 | |
| 659 | 657 | /* handle rs485 */ |
| 660 | − if (one->rs485.flags & SER_RS485_ENABLED) { | |
| 658 | + if (port->rs485.flags & SER_RS485_ENABLED) { | |
| 661 | 659 | /* do nothing if current tx not yet completed */ |
| 662 | 660 | int lsr = sc16is7xx_port_read(port, SC16IS7XX_LSR_REG); |
| 663 | 661 | if (!(lsr & SC16IS7XX_LSR_TEMT_BIT)) |
| 664 | 662 | return; |
| 665 | 663 | |
| 666 | 664 | if (uart_circ_empty(xmit) && |
| 667 | − (one->rs485.delay_rts_after_send > 0)) | |
| 668 | − mdelay(one->rs485.delay_rts_after_send); | |
| 665 | + (port->rs485.delay_rts_after_send > 0)) | |
| 666 | + mdelay(port->rs485.delay_rts_after_send); | |
| 669 | 667 | } |
| 670 | 668 | |
| 671 | 669 | sc16is7xx_port_update(port, SC16IS7XX_IER_REG, |
| @@ -688,9 +686,9 @@ static void sc16is7xx_start_tx(struct uart_port *port) · 16 unmodified lines | ||
| 688 | 686 | struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); |
| 689 | 687 | |
| 690 | 688 | /* handle rs485 */ |
| 691 | − if ((one->rs485.flags & SER_RS485_ENABLED) && | |
| 692 | − (one->rs485.delay_rts_before_send > 0)) { | |
| 693 | − mdelay(one->rs485.delay_rts_before_send); | |
| 689 | + if ((port->rs485.flags & SER_RS485_ENABLED) && | |
| 690 | + (port->rs485.delay_rts_before_send > 0)) { | |
| 691 | + mdelay(port->rs485.delay_rts_before_send); | |
| 694 | 692 | } |
| 695 | 693 | |
| 696 | 694 | if (!work_pending(&one->tx_work)) |
| @@ -830,51 +828,20 @@ static void sc16is7xx_set_termios(struct uart_port *port, · 133 unmodified lines | ||
| 830 | 828 | uart_update_timeout(port, termios->c_cflag, baud); |
| 831 | 829 | } |
| 832 | 830 | |
| 833 | −#if defined(TIOCSRS485) && defined(TIOCGRS485) | |
| 834 | −static void sc16is7xx_config_rs485(struct uart_port *port, | |
| 831 | +static int sc16is7xx_config_rs485(struct uart_port *port, | |
| 835 | 832 | struct serial_rs485 *rs485) |
| 836 | 833 | { |
| 837 | − struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); | |
| 838 | − | |
| 839 | − one->rs485 = *rs485; | |
| 840 | − | |
| 841 | − if (one->rs485.flags & SER_RS485_ENABLED) { | |
| 834 | + if (port->rs485.flags & SER_RS485_ENABLED) | |
| 842 | 835 | sc16is7xx_port_update(port, SC16IS7XX_EFCR_REG, |
| 843 | 836 | SC16IS7XX_EFCR_AUTO_RS485_BIT, |
| 844 | 837 | SC16IS7XX_EFCR_AUTO_RS485_BIT); |
| 845 | − } else { | |
| 838 | + else | |
| 846 | 839 | sc16is7xx_port_update(port, SC16IS7XX_EFCR_REG, |
| 847 | 840 | SC16IS7XX_EFCR_AUTO_RS485_BIT, |
| 848 | 841 | 0); |
| 849 | − } | |
| 850 | −} | |
| 851 | −#endif | |
| 852 | − | |
| 853 | −static int sc16is7xx_ioctl(struct uart_port *port, unsigned int cmd, | |
| 854 | − unsigned long arg) | |
| 855 | −{ | |
| 856 | −#if defined(TIOCSRS485) && defined(TIOCGRS485) | |
| 857 | − struct serial_rs485 rs485; | |
| 842 | + port->rs485 = *rs485; | |
| 858 | 843 | |
| 859 | − switch (cmd) { | |
| 860 | − case TIOCSRS485: | |
| 861 | − if (copy_from_user(&rs485, (void __user *)arg, sizeof(rs485))) | |
| 862 | − return -EFAULT; | |
| 863 | − | |
| 864 | − sc16is7xx_config_rs485(port, &rs485); | |
| 865 | − return 0; | |
| 866 | − case TIOCGRS485: | |
| 867 | − if (copy_to_user((void __user *)arg, | |
| 868 | − &(to_sc16is7xx_one(port, port)->rs485), | |
| 869 | − sizeof(rs485))) | |
| 870 | − return -EFAULT; | |
| 871 | − return 0; | |
| 872 | − default: | |
| 873 | − break; | |
| 874 | − } | |
| 875 | −#endif | |
| 876 | − | |
| 877 | − return -ENOIOCTLCMD; | |
| 844 | + return 0; | |
| 878 | 845 | } |
| 879 | 846 | |
| 880 | 847 | static int sc16is7xx_startup(struct uart_port *port) |
| @@ -1000,7 +967,6 @@ static const struct uart_ops sc16is7xx_ops = { · 119 unmodified lines | ||
| 1000 | 967 | .release_port = sc16is7xx_null_void, |
| 1001 | 968 | .config_port = sc16is7xx_config_port, |
| 1002 | 969 | .verify_port = sc16is7xx_verify_port, |
| 1003 | − .ioctl = sc16is7xx_ioctl, | |
| 1004 | 970 | .pm = sc16is7xx_pm, |
| 1005 | 971 | }; |
| 1006 | 972 | |
| @@ -1130,6 +1096,7 @@ static int sc16is7xx_probe(struct device *dev, · 123 unmodified lines | ||
| 1130 | 1096 | s->p[i].port.flags = UPF_FIXED_TYPE | UPF_LOW_LATENCY; |
| 1131 | 1097 | s->p[i].port.iotype = UPIO_PORT; |
| 1132 | 1098 | s->p[i].port.uartclk = freq; |
| 1099 | + s->p[i].port.rs485_config = sc16is7xx_config_rs485; | |
| 1133 | 1100 | s->p[i].port.ops = &sc16is7xx_ops; |
| 1134 | 1101 | /* Disable all interrupts */ |
| 1135 | 1102 | sc16is7xx_port_write(&s->p[i].port, SC16IS7XX_IER_REG, 0); |
| @@ -319,16 +319,16 @@ static char tegra_uart_decode_rx_error(struct tegra_uart_port *tup, · 318 unmodified lines | ||
| 319 | 319 | if (unlikely(lsr & TEGRA_UART_LSR_ANY)) { |
| 320 | 320 | if (lsr & UART_LSR_OE) { |
| 321 | 321 | /* Overrrun error */ |
| 322 | − flag |= TTY_OVERRUN; | |
| 322 | + flag = TTY_OVERRUN; | |
| 323 | 323 | tup->uport.icount.overrun++; |
| 324 | 324 | dev_err(tup->uport.dev, "Got overrun errors\n"); |
| 325 | 325 | } else if (lsr & UART_LSR_PE) { |
| 326 | 326 | /* Parity error */ |
| 327 | − flag |= TTY_PARITY; | |
| 327 | + flag = TTY_PARITY; | |
| 328 | 328 | tup->uport.icount.parity++; |
| 329 | 329 | dev_err(tup->uport.dev, "Got Parity errors\n"); |
| 330 | 330 | } else if (lsr & UART_LSR_FE) { |
| 331 | − flag |= TTY_FRAME; | |
| 331 | + flag = TTY_FRAME; | |
| 332 | 332 | tup->uport.icount.frame++; |
| 333 | 333 | dev_err(tup->uport.dev, "Got frame errors\n"); |
| 334 | 334 | } else if (lsr & UART_LSR_BI) { |
| @@ -1034,6 +1034,20 @@ fail_rx_dma: · 699 unmodified lines | ||
| 1034 | 1034 | return ret; |
| 1035 | 1035 | } |
| 1036 | 1036 | |
| 1037 | +/* | |
| 1038 | + * Flush any TX data submitted for DMA and PIO. Called when the | |
| 1039 | + * TX circular buffer is reset. | |
| 1040 | + */ | |
| 1041 | +static void tegra_uart_flush_buffer(struct uart_port *u) | |
| 1042 | +{ | |
| 1043 | + struct tegra_uart_port *tup = to_tegra_uport(u); | |
| 1044 | + | |
| 1045 | + tup->tx_bytes = 0; | |
| 1046 | + if (tup->tx_dma_chan) | |
| 1047 | + dmaengine_terminate_all(tup->tx_dma_chan); | |
| 1048 | + return; | |
| 1049 | +} | |
| 1050 | + | |
| 1037 | 1051 | static void tegra_uart_shutdown(struct uart_port *u) |
| 1038 | 1052 | { |
| 1039 | 1053 | struct tegra_uart_port *tup = to_tegra_uport(u); |
| @@ -1046,6 +1060,8 @@ static void tegra_uart_shutdown(struct uart_port *u) · 6 unmodified lines | ||
| 1046 | 1060 | tegra_uart_dma_channel_free(tup, true); |
| 1047 | 1061 | tegra_uart_dma_channel_free(tup, false); |
| 1048 | 1062 | free_irq(u->irq, tup); |
| 1063 | + | |
| 1064 | + tegra_uart_flush_buffer(u); | |
| 1049 | 1065 | } |
| 1050 | 1066 | |
| 1051 | 1067 | static void tegra_uart_enable_ms(struct uart_port *u) |
| @@ -1174,20 +1190,6 @@ static void tegra_uart_set_termios(struct uart_port *u, · 122 unmodified lines | ||
| 1174 | 1190 | return; |
| 1175 | 1191 | } |
| 1176 | 1192 | |
| 1177 | −/* | |
| 1178 | − * Flush any TX data submitted for DMA and PIO. Called when the | |
| 1179 | − * TX circular buffer is reset. | |
| 1180 | − */ | |
| 1181 | −static void tegra_uart_flush_buffer(struct uart_port *u) | |
| 1182 | −{ | |
| 1183 | − struct tegra_uart_port *tup = to_tegra_uport(u); | |
| 1184 | − | |
| 1185 | − tup->tx_bytes = 0; | |
| 1186 | − if (tup->tx_dma_chan) | |
| 1187 | − dmaengine_terminate_all(tup->tx_dma_chan); | |
| 1188 | − return; | |
| 1189 | −} | |
| 1190 | − | |
| 1191 | 1193 | static const char *tegra_uart_type(struct uart_port *u) |
| 1192 | 1194 | { |
| 1193 | 1195 | return TEGRA_UART_TYPE; |
| @@ -61,7 +61,7 @@ static void uart_port_shutdown(struct tty_port *port); · 60 unmodified lines | ||
| 61 | 61 | |
| 62 | 62 | static int uart_dcd_enabled(struct uart_port *uport) |
| 63 | 63 | { |
| 64 | − return uport->status & UPSTAT_DCD_ENABLE; | |
| 64 | + return !!(uport->status & UPSTAT_DCD_ENABLE); | |
| 65 | 65 | } |
| 66 | 66 | |
| 67 | 67 | /* |
| @@ -436,7 +436,7 @@ uart_get_divisor(struct uart_port *port, unsigned int baud) · 368 unmodified lines | ||
| 436 | 436 | |
| 437 | 437 | EXPORT_SYMBOL(uart_get_divisor); |
| 438 | 438 | |
| 439 | −/* FIXME: Consistent locking policy */ | |
| 439 | +/* Caller holds port mutex */ | |
| 440 | 440 | static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, |
| 441 | 441 | struct ktermios *old_termios) |
| 442 | 442 | { |
| @@ -537,9 +537,10 @@ static int uart_write(struct tty_struct *tty, · 94 unmodified lines | ||
| 537 | 537 | count -= c; |
| 538 | 538 | ret += c; |
| 539 | 539 | } |
| 540 | + | |
| 541 | + __uart_start(tty); | |
| 540 | 542 | spin_unlock_irqrestore(&port->lock, flags); |
| 541 | 543 | |
| 542 | − uart_start(tty); | |
| 543 | 544 | return ret; |
| 544 | 545 | } |
| 545 | 546 | |
| @@ -618,7 +619,7 @@ static void uart_throttle(struct tty_struct *tty) · 72 unmodified lines | ||
| 618 | 619 | { |
| 619 | 620 | struct uart_state *state = tty->driver_data; |
| 620 | 621 | struct uart_port *port = state->uart_port; |
| 621 | − uint32_t mask = 0; | |
| 622 | + upf_t mask = 0; | |
| 622 | 623 | |
| 623 | 624 | if (I_IXOFF(tty)) |
| 624 | 625 | mask |= UPF_SOFT_FLOW; |
| @@ -641,7 +642,7 @@ static void uart_unthrottle(struct tty_struct *tty) · 16 unmodified lines | ||
| 641 | 642 | { |
| 642 | 643 | struct uart_state *state = tty->driver_data; |
| 643 | 644 | struct uart_port *port = state->uart_port; |
| 644 | − uint32_t mask = 0; | |
| 645 | + upf_t mask = 0; | |
| 645 | 646 | |
| 646 | 647 | if (I_IXOFF(tty)) |
| 647 | 648 | mask |= UPF_SOFT_FLOW; |
| @@ -1151,6 +1152,47 @@ static int uart_get_icount(struct tty_struct *tty, · 503 unmodified lines | ||
| 1151 | 1152 | return 0; |
| 1152 | 1153 | } |
| 1153 | 1154 | |
| 1155 | +static int uart_get_rs485_config(struct uart_port *port, | |
| 1156 | + struct serial_rs485 __user *rs485) | |
| 1157 | +{ | |
| 1158 | + unsigned long flags; | |
| 1159 | + struct serial_rs485 aux; | |
| 1160 | + | |
| 1161 | + spin_lock_irqsave(&port->lock, flags); | |
| 1162 | + aux = port->rs485; | |
| 1163 | + spin_unlock_irqrestore(&port->lock, flags); | |
| 1164 | + | |
| 1165 | + if (copy_to_user(rs485, &aux, sizeof(aux))) | |
| 1166 | + return -EFAULT; | |
| 1167 | + | |
| 1168 | + return 0; | |
| 1169 | +} | |
| 1170 | + | |
| 1171 | +static int uart_set_rs485_config(struct uart_port *port, | |
| 1172 | + struct serial_rs485 __user *rs485_user) | |
| 1173 | +{ | |
| 1174 | + struct serial_rs485 rs485; | |
| 1175 | + int ret; | |
| 1176 | + unsigned long flags; | |
| 1177 | + | |
| 1178 | + if (!port->rs485_config) | |
| 1179 | + return -ENOIOCTLCMD; | |
| 1180 | + | |
| 1181 | + if (copy_from_user(&rs485, rs485_user, sizeof(*rs485_user))) | |
| 1182 | + return -EFAULT; | |
| 1183 | + | |
| 1184 | + spin_lock_irqsave(&port->lock, flags); | |
| 1185 | + ret = port->rs485_config(port, &rs485); | |
| 1186 | + spin_unlock_irqrestore(&port->lock, flags); | |
| 1187 | + if (ret) | |
| 1188 | + return ret; | |
| 1189 | + | |
| 1190 | + if (copy_to_user(rs485_user, &port->rs485, sizeof(port->rs485))) | |
| 1191 | + return -EFAULT; | |
| 1192 | + | |
| 1193 | + return 0; | |
| 1194 | +} | |
| 1195 | + | |
| 1154 | 1196 | /* |
| 1155 | 1197 | * Called via sys_ioctl. We can use spin_lock_irq() here. |
| 1156 | 1198 | */ |
| @@ -1173,11 +1215,15 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, · 16 unmodified lines | ||
| 1173 | 1215 | break; |
| 1174 | 1216 | |
| 1175 | 1217 | case TIOCSSERIAL: |
| 1218 | + down_write(&tty->termios_rwsem); | |
| 1176 | 1219 | ret = uart_set_info_user(tty, state, uarg); |
| 1220 | + up_write(&tty->termios_rwsem); | |
| 1177 | 1221 | break; |
| 1178 | 1222 | |
| 1179 | 1223 | case TIOCSERCONFIG: |
| 1224 | + down_write(&tty->termios_rwsem); | |
| 1180 | 1225 | ret = uart_do_autoconfig(tty, state); |
| 1226 | + up_write(&tty->termios_rwsem); | |
| 1181 | 1227 | break; |
| 1182 | 1228 | |
| 1183 | 1229 | case TIOCSERGWILD: /* obsolete */ |
| @@ -1217,11 +1263,19 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, · 33 unmodified lines | ||
| 1217 | 1263 | * All these rely on hardware being present and need to be |
| 1218 | 1264 | * protected against the tty being hung up. |
| 1219 | 1265 | */ |
| 1266 | + | |
| 1220 | 1267 | switch (cmd) { |
| 1221 | 1268 | case TIOCSERGETLSR: /* Get line status register */ |
| 1222 | 1269 | ret = uart_get_lsr_info(tty, state, uarg); |
| 1223 | 1270 | break; |
| 1224 | 1271 | |
| 1272 | + case TIOCGRS485: | |
| 1273 | + ret = uart_get_rs485_config(state->uart_port, uarg); | |
| 1274 | + break; | |
| 1275 | + | |
| 1276 | + case TIOCSRS485: | |
| 1277 | + ret = uart_set_rs485_config(state->uart_port, uarg); | |
| 1278 | + break; | |
| 1225 | 1279 | default: { |
| 1226 | 1280 | struct uart_port *uport = state->uart_port; |
| 1227 | 1281 | if (uport->ops->ioctl) |
| @@ -1240,8 +1294,11 @@ static void uart_set_ldisc(struct tty_struct *tty) · 12 unmodified lines | ||
| 1240 | 1294 | struct uart_state *state = tty->driver_data; |
| 1241 | 1295 | struct uart_port *uport = state->uart_port; |
| 1242 | 1296 | |
| 1243 | − if (uport->ops->set_ldisc) | |
| 1244 | − uport->ops->set_ldisc(uport, tty->termios.c_line); | |
| 1297 | + if (uport->ops->set_ldisc) { | |
| 1298 | + mutex_lock(&state->port.mutex); | |
| 1299 | + uport->ops->set_ldisc(uport, &tty->termios); | |
| 1300 | + mutex_unlock(&state->port.mutex); | |
| 1301 | + } | |
| 1245 | 1302 | } |
| 1246 | 1303 | |
| 1247 | 1304 | static void uart_set_termios(struct tty_struct *tty, |
| @@ -1278,7 +1335,9 @@ static void uart_set_termios(struct tty_struct *tty, · 30 unmodified lines | ||
| 1278 | 1335 | return; |
| 1279 | 1336 | } |
| 1280 | 1337 | |
| 1338 | + mutex_lock(&state->port.mutex); | |
| 1281 | 1339 | uart_change_speed(tty, state, old_termios); |
| 1340 | + mutex_unlock(&state->port.mutex); | |
| 1282 | 1341 | /* reload cflag from termios; port driver may have overriden flags */ |
| 1283 | 1342 | cflag = tty->termios.c_cflag; |
| 1284 | 1343 | |
| @@ -1331,8 +1390,16 @@ static void uart_close(struct tty_struct *tty, struct file *filp) · 46 unmodified lines | ||
| 1331 | 1390 | struct uart_port *uport; |
| 1332 | 1391 | unsigned long flags; |
| 1333 | 1392 | |
| 1334 | − if (!state) | |
| 1393 | + if (!state) { | |
| 1394 | + struct uart_driver *drv = tty->driver->driver_state; | |
| 1395 | + | |
| 1396 | + state = drv->state + tty->index; | |
| 1397 | + port = &state->port; | |
| 1398 | + spin_lock_irq(&port->lock); | |
| 1399 | + --port->count; | |
| 1400 | + spin_unlock_irq(&port->lock); | |
| 1335 | 1401 | return; |
| 1402 | + } | |
| 1336 | 1403 | |
| 1337 | 1404 | uport = state->uart_port; |
| 1338 | 1405 | port = &state->port; |
| @@ -1361,10 +1428,6 @@ static void uart_close(struct tty_struct *tty, struct file *filp) · 22 unmodified lines | ||
| 1361 | 1428 | |
| 1362 | 1429 | mutex_lock(&port->mutex); |
| 1363 | 1430 | uart_shutdown(tty, state); |
| 1364 | − uart_flush_buffer(tty); | |
| 1365 | − | |
| 1366 | − tty_ldisc_flush(tty); | |
| 1367 | − | |
| 1368 | 1431 | tty_port_tty_set(port, NULL); |
| 1369 | 1432 | tty->closing = 0; |
| 1370 | 1433 | spin_lock_irqsave(&port->lock, flags); |
| @@ -1372,8 +1435,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp) · 1 unmodified line | ||
| 1372 | 1435 | if (port->blocked_open) { |
| 1373 | 1436 | spin_unlock_irqrestore(&port->lock, flags); |
| 1374 | 1437 | if (port->close_delay) |
| 1375 | − msleep_interruptible( | |
| 1376 | − jiffies_to_msecs(port->close_delay)); | |
| 1438 | + msleep_interruptible(jiffies_to_msecs(port->close_delay)); | |
| 1377 | 1439 | spin_lock_irqsave(&port->lock, flags); |
| 1378 | 1440 | } else if (!uart_console(uport)) { |
| 1379 | 1441 | spin_unlock_irqrestore(&port->lock, flags); |
| @@ -1391,6 +1453,8 @@ static void uart_close(struct tty_struct *tty, struct file *filp) · 11 unmodified lines | ||
| 1391 | 1453 | wake_up_interruptible(&port->close_wait); |
| 1392 | 1454 | |
| 1393 | 1455 | mutex_unlock(&port->mutex); |
| 1456 | + | |
| 1457 | + tty_ldisc_flush(tty); | |
| 1394 | 1458 | } |
| 1395 | 1459 | |
| 1396 | 1460 | static void uart_wait_until_sent(struct tty_struct *tty, int timeout) |
| @@ -1552,6 +1616,10 @@ static int uart_open(struct tty_struct *tty, struct file *filp) · 155 unmodified lines | ||
| 1552 | 1616 | |
| 1553 | 1617 | pr_debug("uart_open(%d) called\n", line); |
| 1554 | 1618 | |
| 1619 | + spin_lock_irq(&port->lock); | |
| 1620 | + ++port->count; | |
| 1621 | + spin_unlock_irq(&port->lock); | |
| 1622 | + | |
| 1555 | 1623 | /* |
| 1556 | 1624 | * We take the semaphore here to guarantee that we won't be re-entered |
| 1557 | 1625 | * while allocating the state structure, or while we request any IRQs |
| @@ -1564,17 +1632,11 @@ static int uart_open(struct tty_struct *tty, struct file *filp) · 6 unmodified lines | ||
| 1564 | 1632 | goto end; |
| 1565 | 1633 | } |
| 1566 | 1634 | |
| 1567 | − port->count++; | |
| 1568 | 1635 | if (!state->uart_port || state->uart_port->flags & UPF_DEAD) { |
| 1569 | 1636 | retval = -ENXIO; |
| 1570 | − goto err_dec_count; | |
| 1637 | + goto err_unlock; | |
| 1571 | 1638 | } |
| 1572 | 1639 | |
| 1573 | − /* | |
| 1574 | − * Once we set tty->driver_data here, we are guaranteed that | |
| 1575 | − * uart_close() will decrement the driver module use count. | |
| 1576 | − * Any failures from here onwards should not touch the count. | |
| 1577 | − */ | |
| 1578 | 1640 | tty->driver_data = state; |
| 1579 | 1641 | state->uart_port->state = state; |
| 1580 | 1642 | state->port.low_latency = |
| @@ -1595,8 +1657,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp) · 14 unmodified lines | ||
| 1595 | 1657 | |
| 1596 | 1658 | end: |
| 1597 | 1659 | return retval; |
| 1598 | −err_dec_count: | |
| 1599 | − port->count--; | |
| 1660 | +err_unlock: | |
| 1600 | 1661 | mutex_unlock(&port->mutex); |
| 1601 | 1662 | goto end; |
| 1602 | 1663 | } |
| @@ -2092,6 +2153,7 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port) · 489 unmodified lines | ||
| 2092 | 2153 | break; |
| 2093 | 2154 | case UPIO_MEM: |
| 2094 | 2155 | case UPIO_MEM32: |
| 2156 | + case UPIO_MEM32BE: | |
| 2095 | 2157 | case UPIO_AU: |
| 2096 | 2158 | case UPIO_TSI: |
| 2097 | 2159 | snprintf(address, sizeof(address), |
| @@ -2339,8 +2401,6 @@ int uart_register_driver(struct uart_driver *drv) · 241 unmodified lines | ||
| 2339 | 2401 | |
| 2340 | 2402 | tty_port_init(port); |
| 2341 | 2403 | port->ops = &uart_port_ops; |
| 2342 | − port->close_delay = HZ / 2; /* .5 seconds */ | |
| 2343 | − port->closing_wait = 30 * HZ;/* 30 seconds */ | |
| 2344 | 2404 | } |
| 2345 | 2405 | |
| 2346 | 2406 | retval = tty_register_driver(normal); |
| @@ -2589,11 +2649,12 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) · 242 unmodified lines | ||
| 2589 | 2649 | goto out; |
| 2590 | 2650 | } |
| 2591 | 2651 | |
| 2652 | + /* Link the port to the driver state table and vice versa */ | |
| 2592 | 2653 | state->uart_port = uport; |
| 2593 | − state->pm_state = UART_PM_STATE_UNDEFINED; | |
| 2654 | + uport->state = state; | |
| 2594 | 2655 | |
| 2656 | + state->pm_state = UART_PM_STATE_UNDEFINED; | |
| 2595 | 2657 | uport->cons = drv->cons; |
| 2596 | − uport->state = state; | |
| 2597 | 2658 | |
| 2598 | 2659 | /* |
| 2599 | 2660 | * If this port is a console, then the spinlock is already |
| @@ -2736,6 +2797,7 @@ int uart_match_port(struct uart_port *port1, struct uart_port *port2) · 136 unmodified lines | ||
| 2736 | 2797 | (port1->hub6 == port2->hub6); |
| 2737 | 2798 | case UPIO_MEM: |
| 2738 | 2799 | case UPIO_MEM32: |
| 2800 | + case UPIO_MEM32BE: | |
| 2739 | 2801 | case UPIO_AU: |
| 2740 | 2802 | case UPIO_TSI: |
| 2741 | 2803 | return (port1->mapbase == port2->mapbase); |
| @@ -1812,9 +1812,6 @@ static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, · 1811 unmodified lines | ||
| 1812 | 1812 | err = DIV_ROUND_CLOSEST(freq, ((br + 1) * bps * sr * |
| 1813 | 1813 | (1 << (2 * c + 1)) / 1000)) - |
| 1814 | 1814 | 1000; |
| 1815 | − if (err < 0) | |
| 1816 | − continue; | |
| 1817 | − | |
| 1818 | 1815 | /* Calc recv margin |
| 1819 | 1816 | * M: Receive margin (%) |
| 1820 | 1817 | * N: Ratio of bit rate to clock (N = sampling rate) |
| @@ -1829,7 +1826,7 @@ static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, · 8 unmodified lines | ||
| 1829 | 1826 | */ |
| 1830 | 1827 | recv_margin = abs((500 - |
| 1831 | 1828 | DIV_ROUND_CLOSEST(1000, sr << 1)) / 10); |
| 1832 | − if (min_err > err) { | |
| 1829 | + if (abs(min_err) > abs(err)) { | |
| 1833 | 1830 | min_err = err; |
| 1834 | 1831 | recv_max_margin = recv_margin; |
| 1835 | 1832 | } else if ((min_err == err) && |
| @@ -1032,10 +1032,19 @@ static void sirfsoc_uart_pm(struct uart_port *port, unsigned int state, · 1031 unmodified lines | ||
| 1032 | 1032 | unsigned int oldstate) |
| 1033 | 1033 | { |
| 1034 | 1034 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); |
| 1035 | − if (!state) | |
| 1035 | + if (!state) { | |
| 1036 | + if (sirfport->is_bt_uart) { | |
| 1037 | + clk_prepare_enable(sirfport->clk_noc); | |
| 1038 | + clk_prepare_enable(sirfport->clk_general); | |
| 1039 | + } | |
| 1036 | 1040 | clk_prepare_enable(sirfport->clk); |
| 1037 | − else | |
| 1041 | + } else { | |
| 1038 | 1042 | clk_disable_unprepare(sirfport->clk); |
| 1043 | + if (sirfport->is_bt_uart) { | |
| 1044 | + clk_disable_unprepare(sirfport->clk_general); | |
| 1045 | + clk_disable_unprepare(sirfport->clk_noc); | |
| 1046 | + } | |
| 1047 | + } | |
| 1039 | 1048 | } |
| 1040 | 1049 | |
| 1041 | 1050 | static int sirfsoc_uart_startup(struct uart_port *port) |
| @@ -1378,12 +1387,26 @@ usp_no_flow_control: · 336 unmodified lines | ||
| 1378 | 1387 | } |
| 1379 | 1388 | port->irq = res->start; |
| 1380 | 1389 | |
| 1381 | − sirfport->clk = clk_get(&pdev->dev, NULL); | |
| 1390 | + sirfport->clk = devm_clk_get(&pdev->dev, NULL); | |
| 1382 | 1391 | if (IS_ERR(sirfport->clk)) { |
| 1383 | 1392 | ret = PTR_ERR(sirfport->clk); |
| 1384 | 1393 | goto err; |
| 1385 | 1394 | } |
| 1386 | 1395 | port->uartclk = clk_get_rate(sirfport->clk); |
| 1396 | + if (of_device_is_compatible(pdev->dev.of_node, "sirf,marco-bt-uart")) { | |
| 1397 | + sirfport->clk_general = devm_clk_get(&pdev->dev, "general"); | |
| 1398 | + if (IS_ERR(sirfport->clk_general)) { | |
| 1399 | + ret = PTR_ERR(sirfport->clk_general); | |
| 1400 | + goto err; | |
| 1401 | + } | |
| 1402 | + sirfport->clk_noc = devm_clk_get(&pdev->dev, "noc"); | |
| 1403 | + if (IS_ERR(sirfport->clk_noc)) { | |
| 1404 | + ret = PTR_ERR(sirfport->clk_noc); | |
| 1405 | + goto err; | |
| 1406 | + } | |
| 1407 | + sirfport->is_bt_uart = true; | |
| 1408 | + } else | |
| 1409 | + sirfport->is_bt_uart = false; | |
| 1387 | 1410 | |
| 1388 | 1411 | port->ops = &sirfsoc_uart_ops; |
| 1389 | 1412 | spin_lock_init(&port->lock); |
| @@ -1392,7 +1415,7 @@ usp_no_flow_control: · 2 unmodified lines | ||
| 1392 | 1415 | ret = uart_add_one_port(&sirfsoc_uart_drv, port); |
| 1393 | 1416 | if (ret != 0) { |
| 1394 | 1417 | dev_err(&pdev->dev, "Cannot add UART port(%d).\n", pdev->id); |
| 1395 | − goto port_err; | |
| 1418 | + goto err; | |
| 1396 | 1419 | } |
| 1397 | 1420 | |
| 1398 | 1421 | sirfport->rx_dma_chan = dma_request_slave_channel(port->dev, "rx"); |
| @@ -1421,8 +1444,6 @@ alloc_coherent_err: · 22 unmodified lines | ||
| 1421 | 1444 | sirfport->rx_dma_items[j].xmit.buf, |
| 1422 | 1445 | sirfport->rx_dma_items[j].dma_addr); |
| 1423 | 1446 | dma_release_channel(sirfport->rx_dma_chan); |
| 1424 | −port_err: | |
| 1425 | − clk_put(sirfport->clk); | |
| 1426 | 1447 | err: |
| 1427 | 1448 | return ret; |
| 1428 | 1449 | } |
| @@ -1431,7 +1452,6 @@ static int sirfsoc_uart_remove(struct platform_device *pdev) · 2 unmodified lines | ||
| 1431 | 1452 | { |
| 1432 | 1453 | struct sirfsoc_uart_port *sirfport = platform_get_drvdata(pdev); |
| 1433 | 1454 | struct uart_port *port = &sirfport->port; |
| 1434 | − clk_put(sirfport->clk); | |
| 1435 | 1455 | uart_remove_one_port(&sirfsoc_uart_drv, port); |
| 1436 | 1456 | if (sirfport->rx_dma_chan) { |
| 1437 | 1457 | int i; |
| @@ -417,6 +417,10 @@ struct sirfsoc_uart_port { · 416 unmodified lines | ||
| 417 | 417 | |
| 418 | 418 | struct uart_port port; |
| 419 | 419 | struct clk *clk; |
| 420 | + /* UART6 for BT usage in A7DA platform need multi-clock source */ | |
| 421 | + bool is_bt_uart; | |
| 422 | + struct clk *clk_general; | |
| 423 | + struct clk *clk_noc; | |
| 420 | 424 | /* for SiRFmarco, there are SET/CLR for UART_INT_EN */ |
| 421 | 425 | bool is_marco; |
| 422 | 426 | struct sirfsoc_uart_register *uart_reg; |
| @@ -345,7 +345,8 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id) · 344 unmodified lines | ||
| 345 | 345 | /* port->lock is not held. */ |
| 346 | 346 | static unsigned int sunsab_tx_empty(struct uart_port *port) |
| 347 | 347 | { |
| 348 | − struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; | |
| 348 | + struct uart_sunsab_port *up = | |
| 349 | + container_of(port, struct uart_sunsab_port, port); | |
| 349 | 350 | int ret; |
| 350 | 351 | |
| 351 | 352 | /* Do not need a lock for a state test like this. */ |
| @@ -360,7 +361,8 @@ static unsigned int sunsab_tx_empty(struct uart_port *port) · 8 unmodified lines | ||
| 360 | 361 | /* port->lock held by caller. */ |
| 361 | 362 | static void sunsab_set_mctrl(struct uart_port *port, unsigned int mctrl) |
| 362 | 363 | { |
| 363 | − struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; | |
| 364 | + struct uart_sunsab_port *up = | |
| 365 | + container_of(port, struct uart_sunsab_port, port); | |
| 364 | 366 | |
| 365 | 367 | if (mctrl & TIOCM_RTS) { |
| 366 | 368 | up->cached_mode &= ~SAB82532_MODE_FRTS; |
| @@ -383,7 +385,8 @@ static void sunsab_set_mctrl(struct uart_port *port, unsigned int mctrl) · 16 unmodified lines | ||
| 383 | 385 | /* port->lock is held by caller and interrupts are disabled. */ |
| 384 | 386 | static unsigned int sunsab_get_mctrl(struct uart_port *port) |
| 385 | 387 | { |
| 386 | − struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; | |
| 388 | + struct uart_sunsab_port *up = | |
| 389 | + container_of(port, struct uart_sunsab_port, port); | |
| 387 | 390 | unsigned char val; |
| 388 | 391 | unsigned int result; |
| 389 | 392 | |
| @@ -404,7 +407,8 @@ static unsigned int sunsab_get_mctrl(struct uart_port *port) · 14 unmodified lines | ||
| 404 | 407 | /* port->lock held by caller. */ |
| 405 | 408 | static void sunsab_stop_tx(struct uart_port *port) |
| 406 | 409 | { |
| 407 | − struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; | |
| 410 | + struct uart_sunsab_port *up = | |
| 411 | + container_of(port, struct uart_sunsab_port, port); | |
| 408 | 412 | |
| 409 | 413 | up->interrupt_mask1 |= SAB82532_IMR1_XPR; |
| 410 | 414 | writeb(up->interrupt_mask1, &up->regs->w.imr1); |
| @@ -432,7 +436,8 @@ static void sunsab_tx_idle(struct uart_sunsab_port *up) · 21 unmodified lines | ||
| 432 | 436 | /* port->lock held by caller. */ |
| 433 | 437 | static void sunsab_start_tx(struct uart_port *port) |
| 434 | 438 | { |
| 435 | − struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; | |
| 439 | + struct uart_sunsab_port *up = | |
| 440 | + container_of(port, struct uart_sunsab_port, port); | |
| 436 | 441 | struct circ_buf *xmit = &up->port.state->xmit; |
| 437 | 442 | int i; |
| 438 | 443 | |
| @@ -465,7 +470,8 @@ static void sunsab_start_tx(struct uart_port *port) · 26 unmodified lines | ||
| 465 | 470 | /* port->lock is not held. */ |
| 466 | 471 | static void sunsab_send_xchar(struct uart_port *port, char ch) |
| 467 | 472 | { |
| 468 | − struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; | |
| 473 | + struct uart_sunsab_port *up = | |
| 474 | + container_of(port, struct uart_sunsab_port, port); | |
| 469 | 475 | unsigned long flags; |
| 470 | 476 | |
| 471 | 477 | if (ch == __DISABLED_CHAR) |
| @@ -482,7 +488,8 @@ static void sunsab_send_xchar(struct uart_port *port, char ch) · 10 unmodified lines | ||
| 482 | 488 | /* port->lock held by caller. */ |
| 483 | 489 | static void sunsab_stop_rx(struct uart_port *port) |
| 484 | 490 | { |
| 485 | − struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; | |
| 491 | + struct uart_sunsab_port *up = | |
| 492 | + container_of(port, struct uart_sunsab_port, port); | |
| 486 | 493 | |
| 487 | 494 | up->interrupt_mask0 |= SAB82532_IMR0_TCD; |
| 488 | 495 | writeb(up->interrupt_mask1, &up->regs->w.imr0); |
| @@ -491,7 +498,8 @@ static void sunsab_stop_rx(struct uart_port *port) · 2 unmodified lines | ||
| 491 | 498 | /* port->lock is not held. */ |
| 492 | 499 | static void sunsab_break_ctl(struct uart_port *port, int break_state) |
| 493 | 500 | { |
| 494 | − struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; | |
| 501 | + struct uart_sunsab_port *up = | |
| 502 | + container_of(port, struct uart_sunsab_port, port); | |
| 495 | 503 | unsigned long flags; |
| 496 | 504 | unsigned char val; |
| 497 | 505 | |
| @@ -514,7 +522,8 @@ static void sunsab_break_ctl(struct uart_port *port, int break_state) · 16 unmodified lines | ||
| 514 | 522 | /* port->lock is not held. */ |
| 515 | 523 | static int sunsab_startup(struct uart_port *port) |
| 516 | 524 | { |
| 517 | − struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; | |
| 525 | + struct uart_sunsab_port *up = | |
| 526 | + container_of(port, struct uart_sunsab_port, port); | |
| 518 | 527 | unsigned long flags; |
| 519 | 528 | unsigned char tmp; |
| 520 | 529 | int err = request_irq(up->port.irq, sunsab_interrupt, |
| @@ -585,7 +594,8 @@ static int sunsab_startup(struct uart_port *port) · 64 unmodified lines | ||
| 585 | 594 | /* port->lock is not held. */ |
| 586 | 595 | static void sunsab_shutdown(struct uart_port *port) |
| 587 | 596 | { |
| 588 | − struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; | |
| 597 | + struct uart_sunsab_port *up = | |
| 598 | + container_of(port, struct uart_sunsab_port, port); | |
| 589 | 599 | unsigned long flags; |
| 590 | 600 | |
| 591 | 601 | spin_lock_irqsave(&up->port.lock, flags); |
| @@ -771,7 +781,8 @@ static void sunsab_convert_to_sab(struct uart_sunsab_port *up, unsigned int cfla · 179 unmodified lines | ||
| 771 | 781 | static void sunsab_set_termios(struct uart_port *port, struct ktermios *termios, |
| 772 | 782 | struct ktermios *old) |
| 773 | 783 | { |
| 774 | − struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; | |
| 784 | + struct uart_sunsab_port *up = | |
| 785 | + container_of(port, struct uart_sunsab_port, port); | |
| 775 | 786 | unsigned long flags; |
| 776 | 787 | unsigned int baud = uart_get_baud_rate(port, termios, old, 0, 4000000); |
| 777 | 788 | unsigned int quot = uart_get_divisor(port, baud); |
| @@ -840,7 +851,8 @@ static struct uart_sunsab_port *sunsab_ports; · 62 unmodified lines | ||
| 840 | 851 | |
| 841 | 852 | static void sunsab_console_putchar(struct uart_port *port, int c) |
| 842 | 853 | { |
| 843 | − struct uart_sunsab_port *up = (struct uart_sunsab_port *)port; | |
| 854 | + struct uart_sunsab_port *up = | |
| 855 | + container_of(port, struct uart_sunsab_port, port); | |
| 844 | 856 | |
| 845 | 857 | sunsab_tec_wait(up); |
| 846 | 858 | writeb(c, &up->regs->w.tic); |
| @@ -264,7 +264,8 @@ static inline void __stop_tx(struct uart_sunsu_port *p) · 263 unmodified lines | ||
| 264 | 264 | |
| 265 | 265 | static void sunsu_stop_tx(struct uart_port *port) |
| 266 | 266 | { |
| 267 | − struct uart_sunsu_port *up = (struct uart_sunsu_port *) port; | |
| 267 | + struct uart_sunsu_port *up = | |
| 268 | + container_of(port, struct uart_sunsu_port, port); | |
| 268 | 269 | |
| 269 | 270 | __stop_tx(up); |
| 270 | 271 | |
| @@ -279,7 +280,8 @@ static void sunsu_stop_tx(struct uart_port *port) · 8 unmodified lines | ||
| 279 | 280 | |
| 280 | 281 | static void sunsu_start_tx(struct uart_port *port) |
| 281 | 282 | { |
| 282 | − struct uart_sunsu_port *up = (struct uart_sunsu_port *) port; | |
| 283 | + struct uart_sunsu_port *up = | |
| 284 | + container_of(port, struct uart_sunsu_port, port); | |
| 283 | 285 | |
| 284 | 286 | if (!(up->ier & UART_IER_THRI)) { |
| 285 | 287 | up->ier |= UART_IER_THRI; |
| @@ -297,7 +299,8 @@ static void sunsu_start_tx(struct uart_port *port) · 11 unmodified lines | ||
| 297 | 299 | |
| 298 | 300 | static void sunsu_stop_rx(struct uart_port *port) |
| 299 | 301 | { |
| 300 | − struct uart_sunsu_port *up = (struct uart_sunsu_port *) port; | |
| 302 | + struct uart_sunsu_port *up = | |
| 303 | + container_of(port, struct uart_sunsu_port, port); | |
| 301 | 304 | |
| 302 | 305 | up->ier &= ~UART_IER_RLSI; |
| 303 | 306 | up->port.read_status_mask &= ~UART_LSR_DR; |
| @@ -306,7 +309,8 @@ static void sunsu_stop_rx(struct uart_port *port) · 2 unmodified lines | ||
| 306 | 309 | |
| 307 | 310 | static void sunsu_enable_ms(struct uart_port *port) |
| 308 | 311 | { |
| 309 | − struct uart_sunsu_port *up = (struct uart_sunsu_port *) port; | |
| 312 | + struct uart_sunsu_port *up = | |
| 313 | + container_of(port, struct uart_sunsu_port, port); | |
| 310 | 314 | unsigned long flags; |
| 311 | 315 | |
| 312 | 316 | spin_lock_irqsave(&up->port.lock, flags); |
| @@ -543,7 +547,8 @@ static irqreturn_t sunsu_kbd_ms_interrupt(int irq, void *dev_id) · 230 unmodified lines | ||
| 543 | 547 | |
| 544 | 548 | static unsigned int sunsu_tx_empty(struct uart_port *port) |
| 545 | 549 | { |
| 546 | − struct uart_sunsu_port *up = (struct uart_sunsu_port *) port; | |
| 550 | + struct uart_sunsu_port *up = | |
| 551 | + container_of(port, struct uart_sunsu_port, port); | |
| 547 | 552 | unsigned long flags; |
| 548 | 553 | unsigned int ret; |
| 549 | 554 | |
| @@ -556,7 +561,8 @@ static unsigned int sunsu_tx_empty(struct uart_port *port) · 6 unmodified lines | ||
| 556 | 561 | |
| 557 | 562 | static unsigned int sunsu_get_mctrl(struct uart_port *port) |
| 558 | 563 | { |
| 559 | − struct uart_sunsu_port *up = (struct uart_sunsu_port *) port; | |
| 564 | + struct uart_sunsu_port *up = | |
| 565 | + container_of(port, struct uart_sunsu_port, port); | |
| 560 | 566 | unsigned char status; |
| 561 | 567 | unsigned int ret; |
| 562 | 568 | |
| @@ -576,7 +582,8 @@ static unsigned int sunsu_get_mctrl(struct uart_port *port) · 13 unmodified lines | ||
| 576 | 582 | |
| 577 | 583 | static void sunsu_set_mctrl(struct uart_port *port, unsigned int mctrl) |
| 578 | 584 | { |
| 579 | − struct uart_sunsu_port *up = (struct uart_sunsu_port *) port; | |
| 585 | + struct uart_sunsu_port *up = | |
| 586 | + container_of(port, struct uart_sunsu_port, port); | |
| 580 | 587 | unsigned char mcr = 0; |
| 581 | 588 | |
| 582 | 589 | if (mctrl & TIOCM_RTS) |
| @@ -595,7 +602,8 @@ static void sunsu_set_mctrl(struct uart_port *port, unsigned int mctrl) · 12 unmodified lines | ||
| 595 | 602 | |
| 596 | 603 | static void sunsu_break_ctl(struct uart_port *port, int break_state) |
| 597 | 604 | { |
| 598 | − struct uart_sunsu_port *up = (struct uart_sunsu_port *) port; | |
| 605 | + struct uart_sunsu_port *up = | |
| 606 | + container_of(port, struct uart_sunsu_port, port); | |
| 599 | 607 | unsigned long flags; |
| 600 | 608 | |
| 601 | 609 | spin_lock_irqsave(&up->port.lock, flags); |
| @@ -609,7 +617,8 @@ static void sunsu_break_ctl(struct uart_port *port, int break_state) · 7 unmodified lines | ||
| 609 | 617 | |
| 610 | 618 | static int sunsu_startup(struct uart_port *port) |
| 611 | 619 | { |
| 612 | − struct uart_sunsu_port *up = (struct uart_sunsu_port *) port; | |
| 620 | + struct uart_sunsu_port *up = | |
| 621 | + container_of(port, struct uart_sunsu_port, port); | |
| 613 | 622 | unsigned long flags; |
| 614 | 623 | int retval; |
| 615 | 624 | |
| @@ -719,7 +728,8 @@ static int sunsu_startup(struct uart_port *port) · 103 unmodified lines | ||
| 719 | 728 | |
| 720 | 729 | static void sunsu_shutdown(struct uart_port *port) |
| 721 | 730 | { |
| 722 | − struct uart_sunsu_port *up = (struct uart_sunsu_port *) port; | |
| 731 | + struct uart_sunsu_port *up = | |
| 732 | + container_of(port, struct uart_sunsu_port, port); | |
| 723 | 733 | unsigned long flags; |
| 724 | 734 | |
| 725 | 735 | /* |
| @@ -767,7 +777,8 @@ static void · 41 unmodified lines | ||
| 767 | 777 | sunsu_change_speed(struct uart_port *port, unsigned int cflag, |
| 768 | 778 | unsigned int iflag, unsigned int quot) |
| 769 | 779 | { |
| 770 | − struct uart_sunsu_port *up = (struct uart_sunsu_port *) port; | |
| 780 | + struct uart_sunsu_port *up = | |
| 781 | + container_of(port, struct uart_sunsu_port, port); | |
| 771 | 782 | unsigned char cval, fcr = 0; |
| 772 | 783 | unsigned long flags; |
| 773 | 784 | |
| @@ -918,7 +929,8 @@ static int sunsu_request_port(struct uart_port *port) · 144 unmodified lines | ||
| 918 | 929 | |
| 919 | 930 | static void sunsu_config_port(struct uart_port *port, int flags) |
| 920 | 931 | { |
| 921 | − struct uart_sunsu_port *up = (struct uart_sunsu_port *) port; | |
| 932 | + struct uart_sunsu_port *up = | |
| 933 | + container_of(port, struct uart_sunsu_port, port); | |
| 922 | 934 | |
| 923 | 935 | if (flags & UART_CONFIG_TYPE) { |
| 924 | 936 | /* |
| @@ -1277,7 +1289,8 @@ static __inline__ void wait_for_xmitr(struct uart_sunsu_port *up) · 352 unmodified lines | ||
| 1277 | 1289 | |
| 1278 | 1290 | static void sunsu_console_putchar(struct uart_port *port, int ch) |
| 1279 | 1291 | { |
| 1280 | − struct uart_sunsu_port *up = (struct uart_sunsu_port *)port; | |
| 1292 | + struct uart_sunsu_port *up = | |
| 1293 | + container_of(port, struct uart_sunsu_port, port); | |
| 1281 | 1294 | |
| 1282 | 1295 | wait_for_xmitr(up); |
| 1283 | 1296 | serial_out(up, UART_TX, ch); |
| @@ -644,7 +644,8 @@ static unsigned int sunzilog_get_mctrl(struct uart_port *port) · 643 unmodified lines | ||
| 644 | 644 | /* The port lock is held and interrupts are disabled. */ |
| 645 | 645 | static void sunzilog_set_mctrl(struct uart_port *port, unsigned int mctrl) |
| 646 | 646 | { |
| 647 | − struct uart_sunzilog_port *up = (struct uart_sunzilog_port *) port; | |
| 647 | + struct uart_sunzilog_port *up = | |
| 648 | + container_of(port, struct uart_sunzilog_port, port); | |
| 648 | 649 | struct zilog_channel __iomem *channel = ZILOG_CHANNEL_FROM_PORT(port); |
| 649 | 650 | unsigned char set_bits, clear_bits; |
| 650 | 651 | |
| @@ -668,7 +669,8 @@ static void sunzilog_set_mctrl(struct uart_port *port, unsigned int mctrl) · 17 unmodified lines | ||
| 668 | 669 | /* The port lock is held and interrupts are disabled. */ |
| 669 | 670 | static void sunzilog_stop_tx(struct uart_port *port) |
| 670 | 671 | { |
| 671 | − struct uart_sunzilog_port *up = (struct uart_sunzilog_port *) port; | |
| 672 | + struct uart_sunzilog_port *up = | |
| 673 | + container_of(port, struct uart_sunzilog_port, port); | |
| 672 | 674 | |
| 673 | 675 | up->flags |= SUNZILOG_FLAG_TX_STOPPED; |
| 674 | 676 | } |
| @@ -676,7 +678,8 @@ static void sunzilog_stop_tx(struct uart_port *port) · 1 unmodified line | ||
| 676 | 678 | /* The port lock is held and interrupts are disabled. */ |
| 677 | 679 | static void sunzilog_start_tx(struct uart_port *port) |
| 678 | 680 | { |
| 679 | − struct uart_sunzilog_port *up = (struct uart_sunzilog_port *) port; | |
| 681 | + struct uart_sunzilog_port *up = | |
| 682 | + container_of(port, struct uart_sunzilog_port, port); | |
| 680 | 683 | struct zilog_channel __iomem *channel = ZILOG_CHANNEL_FROM_PORT(port); |
| 681 | 684 | unsigned char status; |
| 682 | 685 | |
| @@ -736,7 +739,8 @@ static void sunzilog_stop_rx(struct uart_port *port) · 53 unmodified lines | ||
| 736 | 739 | /* The port lock is held. */ |
| 737 | 740 | static void sunzilog_enable_ms(struct uart_port *port) |
| 738 | 741 | { |
| 739 | − struct uart_sunzilog_port *up = (struct uart_sunzilog_port *) port; | |
| 742 | + struct uart_sunzilog_port *up = | |
| 743 | + container_of(port, struct uart_sunzilog_port, port); | |
| 740 | 744 | struct zilog_channel __iomem *channel = ZILOG_CHANNEL_FROM_PORT(port); |
| 741 | 745 | unsigned char new_reg; |
| 742 | 746 | |
| @@ -752,7 +756,8 @@ static void sunzilog_enable_ms(struct uart_port *port) · 9 unmodified lines | ||
| 752 | 756 | /* The port lock is not held. */ |
| 753 | 757 | static void sunzilog_break_ctl(struct uart_port *port, int break_state) |
| 754 | 758 | { |
| 755 | − struct uart_sunzilog_port *up = (struct uart_sunzilog_port *) port; | |
| 759 | + struct uart_sunzilog_port *up = | |
| 760 | + container_of(port, struct uart_sunzilog_port, port); | |
| 756 | 761 | struct zilog_channel __iomem *channel = ZILOG_CHANNEL_FROM_PORT(port); |
| 757 | 762 | unsigned char set_bits, clear_bits, new_reg; |
| 758 | 763 | unsigned long flags; |
| @@ -938,7 +943,8 @@ static void · 179 unmodified lines | ||
| 938 | 943 | sunzilog_set_termios(struct uart_port *port, struct ktermios *termios, |
| 939 | 944 | struct ktermios *old) |
| 940 | 945 | { |
| 941 | − struct uart_sunzilog_port *up = (struct uart_sunzilog_port *) port; | |
| 946 | + struct uart_sunzilog_port *up = | |
| 947 | + container_of(port, struct uart_sunzilog_port, port); | |
| 942 | 948 | unsigned long flags; |
| 943 | 949 | int baud, brg; |
| 944 | 950 | |
| @@ -998,7 +1004,8 @@ static int sunzilog_verify_port(struct uart_port *port, struct serial_struct *se · 53 unmodified lines | ||
| 998 | 1004 | static int sunzilog_get_poll_char(struct uart_port *port) |
| 999 | 1005 | { |
| 1000 | 1006 | unsigned char ch, r1; |
| 1001 | − struct uart_sunzilog_port *up = (struct uart_sunzilog_port *) port; | |
| 1007 | + struct uart_sunzilog_port *up = | |
| 1008 | + container_of(port, struct uart_sunzilog_port, port); | |
| 1002 | 1009 | struct zilog_channel __iomem *channel |
| 1003 | 1010 | = ZILOG_CHANNEL_FROM_PORT(&up->port); |
| 1004 | 1011 | |
| @@ -1032,7 +1039,8 @@ static int sunzilog_get_poll_char(struct uart_port *port) · 27 unmodified lines | ||
| 1032 | 1039 | static void sunzilog_put_poll_char(struct uart_port *port, |
| 1033 | 1040 | unsigned char ch) |
| 1034 | 1041 | { |
| 1035 | − struct uart_sunzilog_port *up = (struct uart_sunzilog_port *)port; | |
| 1042 | + struct uart_sunzilog_port *up = | |
| 1043 | + container_of(port, struct uart_sunzilog_port, port); | |
| 1036 | 1044 | |
| 1037 | 1045 | sunzilog_putchar(&up->port, ch); |
| 1038 | 1046 | } |
| @@ -273,6 +273,8 @@ static void timbuart_shutdown(struct uart_port *port) · 272 unmodified lines | ||
| 273 | 273 | dev_dbg(port->dev, "%s\n", __func__); |
| 274 | 274 | free_irq(port->irq, uart); |
| 275 | 275 | iowrite32(0, port->membase + TIMBUART_IER); |
| 276 | + | |
| 277 | + timbuart_flush_buffer(port); | |
| 276 | 278 | } |
| 277 | 279 | |
| 278 | 280 | static int get_bindex(int baud) |
| @@ -132,6 +132,15 @@ MODULE_PARM_DESC(rx_timeout, "Rx timeout, 1-255"); · 131 unmodified lines | ||
| 132 | 132 | /* Goes in read_status_mask for break detection as the HW doesn't do it*/ |
| 133 | 133 | #define CDNS_UART_IXR_BRK 0x80000000 |
| 134 | 134 | |
| 135 | +/* | |
| 136 | + * Modem Control register: | |
| 137 | + * The read/write Modem Control register controls the interface with the modem | |
| 138 | + * or data set, or a peripheral device emulating a modem. | |
| 139 | + */ | |
| 140 | +#define CDNS_UART_MODEMCR_FCM 0x00000020 /* Automatic flow control mode */ | |
| 141 | +#define CDNS_UART_MODEMCR_RTS 0x00000002 /* Request to send output control */ | |
| 142 | +#define CDNS_UART_MODEMCR_DTR 0x00000001 /* Data Terminal Ready */ | |
| 143 | + | |
| 135 | 144 | /* |
| 136 | 145 | * Channel Status Register: |
| 137 | 146 | * The channel status register (CSR) is provided to enable the control logic |
| @@ -915,7 +924,18 @@ static unsigned int cdns_uart_get_mctrl(struct uart_port *port) · 777 unmodified lines | ||
| 915 | 924 | |
| 916 | 925 | static void cdns_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) |
| 917 | 926 | { |
| 918 | − /* N/A */ | |
| 927 | + u32 val; | |
| 928 | + | |
| 929 | + val = cdns_uart_readl(CDNS_UART_MODEMCR_OFFSET); | |
| 930 | + | |
| 931 | + val &= ~(CDNS_UART_MODEMCR_RTS | CDNS_UART_MODEMCR_DTR); | |
| 932 | + | |
| 933 | + if (mctrl & TIOCM_RTS) | |
| 934 | + val |= CDNS_UART_MODEMCR_RTS; | |
| 935 | + if (mctrl & TIOCM_DTR) | |
| 936 | + val |= CDNS_UART_MODEMCR_DTR; | |
| 937 | + | |
| 938 | + cdns_uart_writel(val, CDNS_UART_MODEMCR_OFFSET); | |
| 919 | 939 | } |
| 920 | 940 | |
| 921 | 941 | #ifdef CONFIG_CONSOLE_POLL |
| @@ -202,14 +202,16 @@ static void tty_buffer_free(struct tty_port *port, struct tty_buffer *b) · 201 unmodified lines | ||
| 202 | 202 | /** |
| 203 | 203 | * tty_buffer_flush - flush full tty buffers |
| 204 | 204 | * @tty: tty to flush |
| 205 | + * @ld: optional ldisc ptr (must be referenced) | |
| 205 | 206 | * |
| 206 | − * flush all the buffers containing receive data. | |
| 207 | + * flush all the buffers containing receive data. If ld != NULL, | |
| 208 | + * flush the ldisc input buffer. | |
| 207 | 209 | * |
| 208 | 210 | * Locking: takes buffer lock to ensure single-threaded flip buffer |
| 209 | 211 | * 'consumer' |
| 210 | 212 | */ |
| 211 | 213 | |
| 212 | −void tty_buffer_flush(struct tty_struct *tty) | |
| 214 | +void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld) | |
| 213 | 215 | { |
| 214 | 216 | struct tty_port *port = tty->port; |
| 215 | 217 | struct tty_bufhead *buf = &port->buf; |
| @@ -223,6 +225,10 @@ void tty_buffer_flush(struct tty_struct *tty) · 7 unmodified lines | ||
| 223 | 225 | buf->head = next; |
| 224 | 226 | } |
| 225 | 227 | buf->head->read = buf->head->commit; |
| 228 | + | |
| 229 | + if (ld && ld->ops->flush_buffer) | |
| 230 | + ld->ops->flush_buffer(tty); | |
| 231 | + | |
| 226 | 232 | atomic_dec(&buf->priority); |
| 227 | 233 | mutex_unlock(&buf->lock); |
| 228 | 234 | } |
| @@ -153,8 +153,6 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd, · 152 unmodified lines | ||
| 153 | 153 | static int __tty_fasync(int fd, struct file *filp, int on); |
| 154 | 154 | static int tty_fasync(int fd, struct file *filp, int on); |
| 155 | 155 | static void release_tty(struct tty_struct *tty, int idx); |
| 156 | −static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); | |
| 157 | −static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); | |
| 158 | 156 | |
| 159 | 157 | /** |
| 160 | 158 | * free_tty_struct - free a disused tty |
| @@ -169,8 +167,7 @@ void free_tty_struct(struct tty_struct *tty) · 8 unmodified lines | ||
| 169 | 167 | { |
| 170 | 168 | if (!tty) |
| 171 | 169 | return; |
| 172 | − if (tty->dev) | |
| 173 | − put_device(tty->dev); | |
| 170 | + put_device(tty->dev); | |
| 174 | 171 | kfree(tty->write_buf); |
| 175 | 172 | tty->magic = 0xDEADDEAD; |
| 176 | 173 | kfree(tty); |
| @@ -277,6 +274,7 @@ int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, · 100 unmodified lines | ||
| 277 | 274 | return 0; |
| 278 | 275 | } |
| 279 | 276 | |
| 277 | +/* Caller must hold tty_lock */ | |
| 280 | 278 | static int check_tty_count(struct tty_struct *tty, const char *routine) |
| 281 | 279 | { |
| 282 | 280 | #ifdef CHECK_TTY_COUNT |
| @@ -492,6 +490,78 @@ static const struct file_operations hung_up_tty_fops = { · 209 unmodified lines | ||
| 492 | 490 | static DEFINE_SPINLOCK(redirect_lock); |
| 493 | 491 | static struct file *redirect; |
| 494 | 492 | |
| 493 | + | |
| 494 | +void proc_clear_tty(struct task_struct *p) | |
| 495 | +{ | |
| 496 | + unsigned long flags; | |
| 497 | + struct tty_struct *tty; | |
| 498 | + spin_lock_irqsave(&p->sighand->siglock, flags); | |
| 499 | + tty = p->signal->tty; | |
| 500 | + p->signal->tty = NULL; | |
| 501 | + spin_unlock_irqrestore(&p->sighand->siglock, flags); | |
| 502 | + tty_kref_put(tty); | |
| 503 | +} | |
| 504 | + | |
| 505 | +/** | |
| 506 | + * proc_set_tty - set the controlling terminal | |
| 507 | + * | |
| 508 | + * Only callable by the session leader and only if it does not already have | |
| 509 | + * a controlling terminal. | |
| 510 | + * | |
| 511 | + * Caller must hold: tty_lock() | |
| 512 | + * a readlock on tasklist_lock | |
| 513 | + * sighand lock | |
| 514 | + */ | |
| 515 | +static void __proc_set_tty(struct tty_struct *tty) | |
| 516 | +{ | |
| 517 | + unsigned long flags; | |
| 518 | + | |
| 519 | + spin_lock_irqsave(&tty->ctrl_lock, flags); | |
| 520 | + /* | |
| 521 | + * The session and fg pgrp references will be non-NULL if | |
| 522 | + * tiocsctty() is stealing the controlling tty | |
| 523 | + */ | |
| 524 | + put_pid(tty->session); | |
| 525 | + put_pid(tty->pgrp); | |
| 526 | + tty->pgrp = get_pid(task_pgrp(current)); | |
| 527 | + spin_unlock_irqrestore(&tty->ctrl_lock, flags); | |
| 528 | + tty->session = get_pid(task_session(current)); | |
| 529 | + if (current->signal->tty) { | |
| 530 | + printk(KERN_DEBUG "tty not NULL!!\n"); | |
| 531 | + tty_kref_put(current->signal->tty); | |
| 532 | + } | |
| 533 | + put_pid(current->signal->tty_old_pgrp); | |
| 534 | + current->signal->tty = tty_kref_get(tty); | |
| 535 | + current->signal->tty_old_pgrp = NULL; | |
| 536 | +} | |
| 537 | + | |
| 538 | +static void proc_set_tty(struct tty_struct *tty) | |
| 539 | +{ | |
| 540 | + spin_lock_irq(¤t->sighand->siglock); | |
| 541 | + __proc_set_tty(tty); | |
| 542 | + spin_unlock_irq(¤t->sighand->siglock); | |
| 543 | +} | |
| 544 | + | |
| 545 | +struct tty_struct *get_current_tty(void) | |
| 546 | +{ | |
| 547 | + struct tty_struct *tty; | |
| 548 | + unsigned long flags; | |
| 549 | + | |
| 550 | + spin_lock_irqsave(¤t->sighand->siglock, flags); | |
| 551 | + tty = tty_kref_get(current->signal->tty); | |
| 552 | + spin_unlock_irqrestore(¤t->sighand->siglock, flags); | |
| 553 | + return tty; | |
| 554 | +} | |
| 555 | +EXPORT_SYMBOL_GPL(get_current_tty); | |
| 556 | + | |
| 557 | +static void session_clear_tty(struct pid *session) | |
| 558 | +{ | |
| 559 | + struct task_struct *p; | |
| 560 | + do_each_pid_task(session, PIDTYPE_SID, p) { | |
| 561 | + proc_clear_tty(p); | |
| 562 | + } while_each_pid_task(session, PIDTYPE_SID, p); | |
| 563 | +} | |
| 564 | + | |
| 495 | 565 | /** |
| 496 | 566 | * tty_wakeup - request more data |
| 497 | 567 | * @tty: terminal |
| @@ -620,9 +690,6 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session) · 122 unmodified lines | ||
| 620 | 690 | return; |
| 621 | 691 | } |
| 622 | 692 | |
| 623 | − /* some functions below drop BTM, so we need this bit */ | |
| 624 | − set_bit(TTY_HUPPING, &tty->flags); | |
| 625 | − | |
| 626 | 693 | /* inuse_filps is protected by the single tty lock, |
| 627 | 694 | this really needs to change if we want to flush the |
| 628 | 695 | workqueue with the lock held */ |
| @@ -647,10 +714,6 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session) · 18 unmodified lines | ||
| 647 | 714 | while (refs--) |
| 648 | 715 | tty_kref_put(tty); |
| 649 | 716 | |
| 650 | − /* | |
| 651 | − * it drops BTM and thus races with reopen | |
| 652 | − * we protect the race by TTY_HUPPING | |
| 653 | − */ | |
| 654 | 717 | tty_ldisc_hangup(tty); |
| 655 | 718 | |
| 656 | 719 | spin_lock_irq(&tty->ctrl_lock); |
| @@ -682,8 +745,6 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session) · 25 unmodified lines | ||
| 682 | 745 | * can't yet guarantee all that. |
| 683 | 746 | */ |
| 684 | 747 | set_bit(TTY_HUPPED, &tty->flags); |
| 685 | − clear_bit(TTY_HUPPING, &tty->flags); | |
| 686 | − | |
| 687 | 748 | tty_unlock(tty); |
| 688 | 749 | |
| 689 | 750 | if (f) |
| @@ -792,14 +853,6 @@ int tty_hung_up_p(struct file *filp) · 102 unmodified lines | ||
| 792 | 853 | |
| 793 | 854 | EXPORT_SYMBOL(tty_hung_up_p); |
| 794 | 855 | |
| 795 | −static void session_clear_tty(struct pid *session) | |
| 796 | −{ | |
| 797 | − struct task_struct *p; | |
| 798 | − do_each_pid_task(session, PIDTYPE_SID, p) { | |
| 799 | − proc_clear_tty(p); | |
| 800 | − } while_each_pid_task(session, PIDTYPE_SID, p); | |
| 801 | −} | |
| 802 | − | |
| 803 | 856 | /** |
| 804 | 857 | * disassociate_ctty - disconnect controlling tty |
| 805 | 858 | * @on_exit: true if exiting so need to "hang up" the session |
| @@ -927,7 +980,7 @@ void __stop_tty(struct tty_struct *tty) · 121 unmodified lines | ||
| 927 | 980 | return; |
| 928 | 981 | tty->stopped = 1; |
| 929 | 982 | if (tty->ops->stop) |
| 930 | − (tty->ops->stop)(tty); | |
| 983 | + tty->ops->stop(tty); | |
| 931 | 984 | } |
| 932 | 985 | |
| 933 | 986 | void stop_tty(struct tty_struct *tty) |
| @@ -958,7 +1011,7 @@ void __start_tty(struct tty_struct *tty) · 24 unmodified lines | ||
| 958 | 1011 | return; |
| 959 | 1012 | tty->stopped = 0; |
| 960 | 1013 | if (tty->ops->start) |
| 961 | − (tty->ops->start)(tty); | |
| 1014 | + tty->ops->start(tty); | |
| 962 | 1015 | tty_wakeup(tty); |
| 963 | 1016 | } |
| 964 | 1017 | |
| @@ -1012,7 +1065,7 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, · 47 unmodified lines | ||
| 1012 | 1065 | situation */ |
| 1013 | 1066 | ld = tty_ldisc_ref_wait(tty); |
| 1014 | 1067 | if (ld->ops->read) |
| 1015 | − i = (ld->ops->read)(tty, file, buf, count); | |
| 1068 | + i = ld->ops->read(tty, file, buf, count); | |
| 1016 | 1069 | else |
| 1017 | 1070 | i = -EIO; |
| 1018 | 1071 | tty_ldisc_deref(ld); |
| @@ -1024,14 +1077,12 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, · 5 unmodified lines | ||
| 1024 | 1077 | } |
| 1025 | 1078 | |
| 1026 | 1079 | static void tty_write_unlock(struct tty_struct *tty) |
| 1027 | − __releases(&tty->atomic_write_lock) | |
| 1028 | 1080 | { |
| 1029 | 1081 | mutex_unlock(&tty->atomic_write_lock); |
| 1030 | 1082 | wake_up_interruptible_poll(&tty->write_wait, POLLOUT); |
| 1031 | 1083 | } |
| 1032 | 1084 | |
| 1033 | 1085 | static int tty_write_lock(struct tty_struct *tty, int ndelay) |
| 1034 | − __acquires(&tty->atomic_write_lock) | |
| 1035 | 1086 | { |
| 1036 | 1087 | if (!mutex_trylock(&tty->atomic_write_lock)) { |
| 1037 | 1088 | if (ndelay) |
| @@ -1146,7 +1197,7 @@ void tty_write_message(struct tty_struct *tty, char *msg) · 108 unmodified lines | ||
| 1146 | 1197 | if (tty) { |
| 1147 | 1198 | mutex_lock(&tty->atomic_write_lock); |
| 1148 | 1199 | tty_lock(tty); |
| 1149 | − if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) { | |
| 1200 | + if (tty->ops->write && tty->count > 0) { | |
| 1150 | 1201 | tty_unlock(tty); |
| 1151 | 1202 | tty->ops->write(tty, msg, strlen(msg)); |
| 1152 | 1203 | } else |
| @@ -1293,19 +1344,24 @@ static ssize_t tty_line_name(struct tty_driver *driver, int index, char *p) · 140 unmodified lines | ||
| 1293 | 1344 | * @driver: the driver for the tty |
| 1294 | 1345 | * @idx: the minor number |
| 1295 | 1346 | * |
| 1296 | − * Return the tty, if found or ERR_PTR() otherwise. | |
| 1347 | + * Return the tty, if found. If not found, return NULL or ERR_PTR() if the | |
| 1348 | + * driver lookup() method returns an error. | |
| 1297 | 1349 | * |
| 1298 | − * Locking: tty_mutex must be held. If tty is found, the mutex must | |
| 1299 | − * be held until the 'fast-open' is also done. Will change once we | |
| 1300 | − * have refcounting in the driver and per driver locking | |
| 1350 | + * Locking: tty_mutex must be held. If the tty is found, bump the tty kref. | |
| 1301 | 1351 | */ |
| 1302 | 1352 | static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, |
| 1303 | 1353 | struct inode *inode, int idx) |
| 1304 | 1354 | { |
| 1355 | + struct tty_struct *tty; | |
| 1356 | + | |
| 1305 | 1357 | if (driver->ops->lookup) |
| 1306 | − return driver->ops->lookup(driver, inode, idx); | |
| 1358 | + tty = driver->ops->lookup(driver, inode, idx); | |
| 1359 | + else | |
| 1360 | + tty = driver->ttys[idx]; | |
| 1307 | 1361 | |
| 1308 | − return driver->ttys[idx]; | |
| 1362 | + if (!IS_ERR(tty)) | |
| 1363 | + tty_kref_get(tty); | |
| 1364 | + return tty; | |
| 1309 | 1365 | } |
| 1310 | 1366 | |
| 1311 | 1367 | /** |
| @@ -1393,29 +1449,21 @@ void tty_driver_remove_tty(struct tty_driver *driver, struct tty_struct *tty) · 81 unmodified lines | ||
| 1393 | 1449 | * @tty - the tty to open |
| 1394 | 1450 | * |
| 1395 | 1451 | * Return 0 on success, -errno on error. |
| 1452 | + * Re-opens on master ptys are not allowed and return -EIO. | |
| 1396 | 1453 | * |
| 1397 | − * Locking: tty_mutex must be held from the time the tty was found | |
| 1398 | − * till this open completes. | |
| 1454 | + * Locking: Caller must hold tty_lock | |
| 1399 | 1455 | */ |
| 1400 | 1456 | static int tty_reopen(struct tty_struct *tty) |
| 1401 | 1457 | { |
| 1402 | 1458 | struct tty_driver *driver = tty->driver; |
| 1403 | 1459 | |
| 1404 | − if (test_bit(TTY_CLOSING, &tty->flags) || | |
| 1405 | − test_bit(TTY_HUPPING, &tty->flags)) | |
| 1460 | + if (!tty->count) | |
| 1406 | 1461 | return -EIO; |
| 1407 | 1462 | |
| 1408 | 1463 | if (driver->type == TTY_DRIVER_TYPE_PTY && |
| 1409 | − driver->subtype == PTY_TYPE_MASTER) { | |
| 1410 | − /* | |
| 1411 | − * special case for PTY masters: only one open permitted, | |
| 1412 | − * and the slave side open count is incremented as well. | |
| 1413 | − */ | |
| 1414 | − if (tty->count) | |
| 1415 | − return -EIO; | |
| 1464 | + driver->subtype == PTY_TYPE_MASTER) | |
| 1465 | + return -EIO; | |
| 1416 | 1466 | |
| 1417 | − tty->link->count++; | |
| 1418 | − } | |
| 1419 | 1467 | tty->count++; |
| 1420 | 1468 | |
| 1421 | 1469 | WARN_ON(!tty->ldisc); |
| @@ -1535,15 +1583,19 @@ void tty_free_termios(struct tty_struct *tty) · 113 unmodified lines | ||
| 1535 | 1583 | EXPORT_SYMBOL(tty_free_termios); |
| 1536 | 1584 | |
| 1537 | 1585 | /** |
| 1538 | − * tty_flush_works - flush all works of a tty | |
| 1539 | − * @tty: tty device to flush works for | |
| 1586 | + * tty_flush_works - flush all works of a tty/pty pair | |
| 1587 | + * @tty: tty device to flush works for (or either end of a pty pair) | |
| 1540 | 1588 | * |
| 1541 | − * Sync flush all works belonging to @tty. | |
| 1589 | + * Sync flush all works belonging to @tty (and the 'other' tty). | |
| 1542 | 1590 | */ |
| 1543 | 1591 | static void tty_flush_works(struct tty_struct *tty) |
| 1544 | 1592 | { |
| 1545 | 1593 | flush_work(&tty->SAK_work); |
| 1546 | 1594 | flush_work(&tty->hangup_work); |
| 1595 | + if (tty->link) { | |
| 1596 | + flush_work(&tty->link->SAK_work); | |
| 1597 | + flush_work(&tty->link->hangup_work); | |
| 1598 | + } | |
| 1547 | 1599 | } |
| 1548 | 1600 | |
| 1549 | 1601 | /** |
| @@ -1635,8 +1687,7 @@ static void release_tty(struct tty_struct *tty, int idx) · 85 unmodified lines | ||
| 1635 | 1687 | tty->link->port->itty = NULL; |
| 1636 | 1688 | cancel_work_sync(&tty->port->buf.work); |
| 1637 | 1689 | |
| 1638 | − if (tty->link) | |
| 1639 | − tty_kref_put(tty->link); | |
| 1690 | + tty_kref_put(tty->link); | |
| 1640 | 1691 | tty_kref_put(tty); |
| 1641 | 1692 | } |
| 1642 | 1693 | |
| @@ -1649,8 +1700,7 @@ static void release_tty(struct tty_struct *tty, int idx) · 6 unmodified lines | ||
| 1649 | 1700 | * Performs some paranoid checking before true release of the @tty. |
| 1650 | 1701 | * This is a no-op unless TTY_PARANOIA_CHECK is defined. |
| 1651 | 1702 | */ |
| 1652 | −static int tty_release_checks(struct tty_struct *tty, struct tty_struct *o_tty, | |
| 1653 | − int idx) | |
| 1703 | +static int tty_release_checks(struct tty_struct *tty, int idx) | |
| 1654 | 1704 | { |
| 1655 | 1705 | #ifdef TTY_PARANOIA_CHECK |
| 1656 | 1706 | if (idx < 0 || idx >= tty->driver->num) { |
| @@ -1669,6 +1719,8 @@ static int tty_release_checks(struct tty_struct *tty, struct tty_struct *o_tty, · 12 unmodified lines | ||
| 1669 | 1719 | return -1; |
| 1670 | 1720 | } |
| 1671 | 1721 | if (tty->driver->other) { |
| 1722 | + struct tty_struct *o_tty = tty->link; | |
| 1723 | + | |
| 1672 | 1724 | if (o_tty != tty->driver->other->ttys[idx]) { |
| 1673 | 1725 | printk(KERN_DEBUG "%s: other->table[%d] not o_tty for (%s)\n", |
| 1674 | 1726 | __func__, idx, tty->name); |
| @@ -1705,8 +1757,8 @@ static int tty_release_checks(struct tty_struct *tty, struct tty_struct *o_tty, · 30 unmodified lines | ||
| 1705 | 1757 | int tty_release(struct inode *inode, struct file *filp) |
| 1706 | 1758 | { |
| 1707 | 1759 | struct tty_struct *tty = file_tty(filp); |
| 1708 | − struct tty_struct *o_tty; | |
| 1709 | − int pty_master, tty_closing, o_tty_closing, do_sleep; | |
| 1760 | + struct tty_struct *o_tty = NULL; | |
| 1761 | + int do_sleep, final; | |
| 1710 | 1762 | int idx; |
| 1711 | 1763 | char buf[64]; |
| 1712 | 1764 | long timeout = 0; |
| @@ -1721,12 +1773,11 @@ int tty_release(struct inode *inode, struct file *filp) · 8 unmodified lines | ||
| 1721 | 1773 | __tty_fasync(-1, filp, 0); |
| 1722 | 1774 | |
| 1723 | 1775 | idx = tty->index; |
| 1724 | − pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && | |
| 1725 | − tty->driver->subtype == PTY_TYPE_MASTER); | |
| 1726 | − /* Review: parallel close */ | |
| 1727 | − o_tty = tty->link; | |
| 1776 | + if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | |
| 1777 | + tty->driver->subtype == PTY_TYPE_MASTER) | |
| 1778 | + o_tty = tty->link; | |
| 1728 | 1779 | |
| 1729 | − if (tty_release_checks(tty, o_tty, idx)) { | |
| 1780 | + if (tty_release_checks(tty, idx)) { | |
| 1730 | 1781 | tty_unlock(tty); |
| 1731 | 1782 | return 0; |
| 1732 | 1783 | } |
| @@ -1739,7 +1790,9 @@ int tty_release(struct inode *inode, struct file *filp) · 6 unmodified lines | ||
| 1739 | 1790 | if (tty->ops->close) |
| 1740 | 1791 | tty->ops->close(tty, filp); |
| 1741 | 1792 | |
| 1742 | − tty_unlock(tty); | |
| 1793 | + /* If tty is pty master, lock the slave pty (stable lock order) */ | |
| 1794 | + tty_lock_slave(o_tty); | |
| 1795 | + | |
| 1743 | 1796 | /* |
| 1744 | 1797 | * Sanity check: if tty->count is going to zero, there shouldn't be |
| 1745 | 1798 | * any waiters on tty->read_wait or tty->write_wait. We test the |
| @@ -1750,25 +1803,13 @@ int tty_release(struct inode *inode, struct file *filp) · 4 unmodified lines | ||
| 1750 | 1803 | * The test for the o_tty closing is necessary, since the master and |
| 1751 | 1804 | * slave sides may close in any order. If the slave side closes out |
| 1752 | 1805 | * first, its count will be one, since the master side holds an open. |
| 1753 | − * Thus this test wouldn't be triggered at the time the slave closes, | |
| 1806 | + * Thus this test wouldn't be triggered at the time the slave closed, | |
| 1754 | 1807 | * so we do it now. |
| 1755 | − * | |
| 1756 | − * Note that it's possible for the tty to be opened again while we're | |
| 1757 | − * flushing out waiters. By recalculating the closing flags before | |
| 1758 | − * each iteration we avoid any problems. | |
| 1759 | 1808 | */ |
| 1760 | 1809 | while (1) { |
| 1761 | − /* Guard against races with tty->count changes elsewhere and | |
| 1762 | − opens on /dev/tty */ | |
| 1763 | − | |
| 1764 | − mutex_lock(&tty_mutex); | |
| 1765 | − tty_lock_pair(tty, o_tty); | |
| 1766 | − tty_closing = tty->count <= 1; | |
| 1767 | − o_tty_closing = o_tty && | |
| 1768 | − (o_tty->count <= (pty_master ? 1 : 0)); | |
| 1769 | 1810 | do_sleep = 0; |
| 1770 | 1811 | |
| 1771 | − if (tty_closing) { | |
| 1812 | + if (tty->count <= 1) { | |
| 1772 | 1813 | if (waitqueue_active(&tty->read_wait)) { |
| 1773 | 1814 | wake_up_poll(&tty->read_wait, POLLIN); |
| 1774 | 1815 | do_sleep++; |
| @@ -1778,7 +1819,7 @@ int tty_release(struct inode *inode, struct file *filp) · 3 unmodified lines | ||
| 1778 | 1819 | do_sleep++; |
| 1779 | 1820 | } |
| 1780 | 1821 | } |
| 1781 | − if (o_tty_closing) { | |
| 1822 | + if (o_tty && o_tty->count <= 1) { | |
| 1782 | 1823 | if (waitqueue_active(&o_tty->read_wait)) { |
| 1783 | 1824 | wake_up_poll(&o_tty->read_wait, POLLIN); |
| 1784 | 1825 | do_sleep++; |
| @@ -1796,8 +1837,6 @@ int tty_release(struct inode *inode, struct file *filp) · 11 unmodified lines | ||
| 1796 | 1837 | printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", |
| 1797 | 1838 | __func__, tty_name(tty, buf)); |
| 1798 | 1839 | } |
| 1799 | − tty_unlock_pair(tty, o_tty); | |
| 1800 | − mutex_unlock(&tty_mutex); | |
| 1801 | 1840 | schedule_timeout_killable(timeout); |
| 1802 | 1841 | if (timeout < 120 * HZ) |
| 1803 | 1842 | timeout = 2 * timeout + 1; |
| @@ -1805,15 +1844,7 @@ int tty_release(struct inode *inode, struct file *filp) · 1 unmodified line | ||
| 1805 | 1844 | timeout = MAX_SCHEDULE_TIMEOUT; |
| 1806 | 1845 | } |
| 1807 | 1846 | |
| 1808 | − /* | |
| 1809 | − * The closing flags are now consistent with the open counts on | |
| 1810 | − * both sides, and we've completed the last operation that could | |
| 1811 | − * block, so it's safe to proceed with closing. | |
| 1812 | − * | |
| 1813 | − * We must *not* drop the tty_mutex until we ensure that a further | |
| 1814 | − * entry into tty_open can not pick up this tty. | |
| 1815 | − */ | |
| 1816 | − if (pty_master) { | |
| 1847 | + if (o_tty) { | |
| 1817 | 1848 | if (--o_tty->count < 0) { |
| 1818 | 1849 | printk(KERN_WARNING "%s: bad pty slave count (%d) for %s\n", |
| 1819 | 1850 | __func__, o_tty->count, tty_name(o_tty, buf)); |
| @@ -1840,21 +1871,11 @@ int tty_release(struct inode *inode, struct file *filp) · 20 unmodified lines | ||
| 1840 | 1871 | /* |
| 1841 | 1872 | * Perform some housekeeping before deciding whether to return. |
| 1842 | 1873 | * |
| 1843 | − * Set the TTY_CLOSING flag if this was the last open. In the | |
| 1844 | − * case of a pty we may have to wait around for the other side | |
| 1845 | − * to close, and TTY_CLOSING makes sure we can't be reopened. | |
| 1846 | − */ | |
| 1847 | − if (tty_closing) | |
| 1848 | − set_bit(TTY_CLOSING, &tty->flags); | |
| 1849 | − if (o_tty_closing) | |
| 1850 | − set_bit(TTY_CLOSING, &o_tty->flags); | |
| 1851 | − | |
| 1852 | − /* | |
| 1853 | 1874 | * If _either_ side is closing, make sure there aren't any |
| 1854 | 1875 | * processes that still think tty or o_tty is their controlling |
| 1855 | 1876 | * tty. |
| 1856 | 1877 | */ |
| 1857 | − if (tty_closing || o_tty_closing) { | |
| 1878 | + if (!tty->count) { | |
| 1858 | 1879 | read_lock(&tasklist_lock); |
| 1859 | 1880 | session_clear_tty(tty->session); |
| 1860 | 1881 | if (o_tty) |
| @@ -1862,13 +1883,16 @@ int tty_release(struct inode *inode, struct file *filp) · 1 unmodified line | ||
| 1862 | 1883 | read_unlock(&tasklist_lock); |
| 1863 | 1884 | } |
| 1864 | 1885 | |
| 1865 | − mutex_unlock(&tty_mutex); | |
| 1866 | − tty_unlock_pair(tty, o_tty); | |
| 1867 | − /* At this point the TTY_CLOSING flag should ensure a dead tty | |
| 1886 | + /* check whether both sides are closing ... */ | |
| 1887 | + final = !tty->count && !(o_tty && o_tty->count); | |
| 1888 | + | |
| 1889 | + tty_unlock_slave(o_tty); | |
| 1890 | + tty_unlock(tty); | |
| 1891 | + | |
| 1892 | + /* At this point, the tty->count == 0 should ensure a dead tty | |
| 1868 | 1893 | cannot be re-opened by a racing opener */ |
| 1869 | 1894 | |
| 1870 | − /* check whether both sides are closing ... */ | |
| 1871 | − if (!tty_closing || (o_tty && !o_tty_closing)) | |
| 1895 | + if (!final) | |
| 1872 | 1896 | return 0; |
| 1873 | 1897 | |
| 1874 | 1898 | #ifdef TTY_DEBUG_HANGUP |
| @@ -1877,12 +1901,10 @@ int tty_release(struct inode *inode, struct file *filp) · 2 unmodified lines | ||
| 1877 | 1901 | /* |
| 1878 | 1902 | * Ask the line discipline code to release its structures |
| 1879 | 1903 | */ |
| 1880 | − tty_ldisc_release(tty, o_tty); | |
| 1904 | + tty_ldisc_release(tty); | |
| 1881 | 1905 | |
| 1882 | 1906 | /* Wait for pending work before tty destruction commmences */ |
| 1883 | 1907 | tty_flush_works(tty); |
| 1884 | − if (o_tty) | |
| 1885 | − tty_flush_works(o_tty); | |
| 1886 | 1908 | |
| 1887 | 1909 | #ifdef TTY_DEBUG_HANGUP |
| 1888 | 1910 | printk(KERN_DEBUG "%s: %s: freeing structure...\n", __func__, tty_name(tty, buf)); |
| @@ -1901,20 +1923,20 @@ int tty_release(struct inode *inode, struct file *filp) · 12 unmodified lines | ||
| 1901 | 1923 | } |
| 1902 | 1924 | |
| 1903 | 1925 | /** |
| 1904 | − * tty_open_current_tty - get tty of current task for open | |
| 1926 | + * tty_open_current_tty - get locked tty of current task | |
| 1905 | 1927 | * @device: device number |
| 1906 | 1928 | * @filp: file pointer to tty |
| 1907 | − * @return: tty of the current task iff @device is /dev/tty | |
| 1929 | + * @return: locked tty of the current task iff @device is /dev/tty | |
| 1930 | + * | |
| 1931 | + * Performs a re-open of the current task's controlling tty. | |
| 1908 | 1932 | * |
| 1909 | 1933 | * We cannot return driver and index like for the other nodes because |
| 1910 | 1934 | * devpts will not work then. It expects inodes to be from devpts FS. |
| 1911 | − * | |
| 1912 | − * We need to move to returning a refcounted object from all the lookup | |
| 1913 | − * paths including this one. | |
| 1914 | 1935 | */ |
| 1915 | 1936 | static struct tty_struct *tty_open_current_tty(dev_t device, struct file *filp) |
| 1916 | 1937 | { |
| 1917 | 1938 | struct tty_struct *tty; |
| 1939 | + int retval; | |
| 1918 | 1940 | |
| 1919 | 1941 | if (device != MKDEV(TTYAUX_MAJOR, 0)) |
| 1920 | 1942 | return NULL; |
| @@ -1925,9 +1947,14 @@ static struct tty_struct *tty_open_current_tty(dev_t device, struct file *filp) · 4 unmodified lines | ||
| 1925 | 1947 | |
| 1926 | 1948 | filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ |
| 1927 | 1949 | /* noctty = 1; */ |
| 1928 | − tty_kref_put(tty); | |
| 1929 | − /* FIXME: we put a reference and return a TTY! */ | |
| 1930 | − /* This is only safe because the caller holds tty_mutex */ | |
| 1950 | + tty_lock(tty); | |
| 1951 | + tty_kref_put(tty); /* safe to drop the kref now */ | |
| 1952 | + | |
| 1953 | + retval = tty_reopen(tty); | |
| 1954 | + if (retval < 0) { | |
| 1955 | + tty_unlock(tty); | |
| 1956 | + tty = ERR_PTR(retval); | |
| 1957 | + } | |
| 1931 | 1958 | return tty; |
| 1932 | 1959 | } |
| 1933 | 1960 | |
| @@ -2025,13 +2052,9 @@ retry_open: · 91 unmodified lines | ||
| 2025 | 2052 | index = -1; |
| 2026 | 2053 | retval = 0; |
| 2027 | 2054 | |
| 2028 | − mutex_lock(&tty_mutex); | |
| 2029 | − /* This is protected by the tty_mutex */ | |
| 2030 | 2055 | tty = tty_open_current_tty(device, filp); |
| 2031 | − if (IS_ERR(tty)) { | |
| 2032 | − retval = PTR_ERR(tty); | |
| 2033 | − goto err_unlock; | |
| 2034 | − } else if (!tty) { | |
| 2056 | + if (!tty) { | |
| 2057 | + mutex_lock(&tty_mutex); | |
| 2035 | 2058 | driver = tty_lookup_driver(device, filp, &noctty, &index); |
| 2036 | 2059 | if (IS_ERR(driver)) { |
| 2037 | 2060 | retval = PTR_ERR(driver); |
| @@ -2044,21 +2067,25 @@ retry_open: · 6 unmodified lines | ||
| 2044 | 2067 | retval = PTR_ERR(tty); |
| 2045 | 2068 | goto err_unlock; |
| 2046 | 2069 | } |
| 2047 | − } | |
| 2048 | 2070 | |
| 2049 | − if (tty) { | |
| 2050 | − tty_lock(tty); | |
| 2051 | − retval = tty_reopen(tty); | |
| 2052 | − if (retval < 0) { | |
| 2053 | − tty_unlock(tty); | |
| 2054 | − tty = ERR_PTR(retval); | |
| 2071 | + if (tty) { | |
| 2072 | + mutex_unlock(&tty_mutex); | |
| 2073 | + tty_lock(tty); | |
| 2074 | + /* safe to drop the kref from tty_driver_lookup_tty() */ | |
| 2075 | + tty_kref_put(tty); | |
| 2076 | + retval = tty_reopen(tty); | |
| 2077 | + if (retval < 0) { | |
| 2078 | + tty_unlock(tty); | |
| 2079 | + tty = ERR_PTR(retval); | |
| 2080 | + } | |
| 2081 | + } else { /* Returns with the tty_lock held for now */ | |
| 2082 | + tty = tty_init_dev(driver, index); | |
| 2083 | + mutex_unlock(&tty_mutex); | |
| 2055 | 2084 | } |
| 2056 | − } else /* Returns with the tty_lock held for now */ | |
| 2057 | − tty = tty_init_dev(driver, index); | |
| 2058 | 2085 | |
| 2059 | − mutex_unlock(&tty_mutex); | |
| 2060 | − if (driver) | |
| 2061 | 2086 | tty_driver_kref_put(driver); |
| 2087 | + } | |
| 2088 | + | |
| 2062 | 2089 | if (IS_ERR(tty)) { |
| 2063 | 2090 | retval = PTR_ERR(tty); |
| 2064 | 2091 | goto err_file; |
| @@ -2100,25 +2127,23 @@ retry_open: · 35 unmodified lines | ||
| 2100 | 2127 | /* |
| 2101 | 2128 | * Need to reset f_op in case a hangup happened. |
| 2102 | 2129 | */ |
| 2103 | − if (filp->f_op == &hung_up_tty_fops) | |
| 2130 | + if (tty_hung_up_p(filp)) | |
| 2104 | 2131 | filp->f_op = &tty_fops; |
| 2105 | 2132 | goto retry_open; |
| 2106 | 2133 | } |
| 2107 | 2134 | clear_bit(TTY_HUPPED, &tty->flags); |
| 2108 | − tty_unlock(tty); | |
| 2109 | 2135 | |
| 2110 | 2136 | |
| 2111 | − mutex_lock(&tty_mutex); | |
| 2112 | − tty_lock(tty); | |
| 2137 | + read_lock(&tasklist_lock); | |
| 2113 | 2138 | spin_lock_irq(¤t->sighand->siglock); |
| 2114 | 2139 | if (!noctty && |
| 2115 | 2140 | current->signal->leader && |
| 2116 | 2141 | !current->signal->tty && |
| 2117 | 2142 | tty->session == NULL) |
| 2118 | − __proc_set_tty(current, tty); | |
| 2143 | + __proc_set_tty(tty); | |
| 2119 | 2144 | spin_unlock_irq(¤t->sighand->siglock); |
| 2145 | + read_unlock(&tasklist_lock); | |
| 2120 | 2146 | tty_unlock(tty); |
| 2121 | − mutex_unlock(&tty_mutex); | |
| 2122 | 2147 | return 0; |
| 2123 | 2148 | err_unlock: |
| 2124 | 2149 | mutex_unlock(&tty_mutex); |
| @@ -2155,7 +2180,7 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait) · 30 unmodified lines | ||
| 2155 | 2180 | |
| 2156 | 2181 | ld = tty_ldisc_ref_wait(tty); |
| 2157 | 2182 | if (ld->ops->poll) |
| 2158 | − ret = (ld->ops->poll)(tty, filp, wait); | |
| 2183 | + ret = ld->ops->poll(tty, filp, wait); | |
| 2159 | 2184 | tty_ldisc_deref(ld); |
| 2160 | 2185 | return ret; |
| 2161 | 2186 | } |
| @@ -2283,18 +2308,14 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg) · 121 unmodified lines | ||
| 2283 | 2308 | int tty_do_resize(struct tty_struct *tty, struct winsize *ws) |
| 2284 | 2309 | { |
| 2285 | 2310 | struct pid *pgrp; |
| 2286 | − unsigned long flags; | |
| 2287 | 2311 | |
| 2288 | 2312 | /* Lock the tty */ |
| 2289 | 2313 | mutex_lock(&tty->winsize_mutex); |
| 2290 | 2314 | if (!memcmp(ws, &tty->winsize, sizeof(*ws))) |
| 2291 | 2315 | goto done; |
| 2292 | − /* Get the PID values and reference them so we can | |
| 2293 | − avoid holding the tty ctrl lock while sending signals */ | |
| 2294 | − spin_lock_irqsave(&tty->ctrl_lock, flags); | |
| 2295 | − pgrp = get_pid(tty->pgrp); | |
| 2296 | − spin_unlock_irqrestore(&tty->ctrl_lock, flags); | |
| 2297 | 2316 | |
| 2317 | + /* Signal the foreground process group */ | |
| 2318 | + pgrp = tty_get_pgrp(tty); | |
| 2298 | 2319 | if (pgrp) |
| 2299 | 2320 | kill_pgrp(pgrp, SIGWINCH, 1); |
| 2300 | 2321 | put_pid(pgrp); |
| @@ -2403,7 +2424,7 @@ static int fionbio(struct file *file, int __user *p) · 102 unmodified lines | ||
| 2403 | 2424 | * leader to set this tty as the controlling tty for the session. |
| 2404 | 2425 | * |
| 2405 | 2426 | * Locking: |
| 2406 | − * Takes tty_mutex() to protect tty instance | |
| 2427 | + * Takes tty_lock() to serialize proc_set_tty() for this tty | |
| 2407 | 2428 | * Takes tasklist_lock internally to walk sessions |
| 2408 | 2429 | * Takes ->siglock() when updating signal->tty |
| 2409 | 2430 | */ |
| @@ -2411,10 +2432,13 @@ static int fionbio(struct file *file, int __user *p) · 1 unmodified line | ||
| 2411 | 2432 | static int tiocsctty(struct tty_struct *tty, int arg) |
| 2412 | 2433 | { |
| 2413 | 2434 | int ret = 0; |
| 2435 | + | |
| 2436 | + tty_lock(tty); | |
| 2437 | + read_lock(&tasklist_lock); | |
| 2438 | + | |
| 2414 | 2439 | if (current->signal->leader && (task_session(current) == tty->session)) |
| 2415 | − return ret; | |
| 2440 | + goto unlock; | |
| 2416 | 2441 | |
| 2417 | − mutex_lock(&tty_mutex); | |
| 2418 | 2442 | /* |
| 2419 | 2443 | * The process must be a session leader and |
| 2420 | 2444 | * not have a controlling tty already. |
| @@ -2433,17 +2457,16 @@ static int tiocsctty(struct tty_struct *tty, int arg) · 12 unmodified lines | ||
| 2433 | 2457 | /* |
| 2434 | 2458 | * Steal it away |
| 2435 | 2459 | */ |
| 2436 | − read_lock(&tasklist_lock); | |
| 2437 | 2460 | session_clear_tty(tty->session); |
| 2438 | − read_unlock(&tasklist_lock); | |
| 2439 | 2461 | } else { |
| 2440 | 2462 | ret = -EPERM; |
| 2441 | 2463 | goto unlock; |
| 2442 | 2464 | } |
| 2443 | 2465 | } |
| 2444 | − proc_set_tty(current, tty); | |
| 2466 | + proc_set_tty(tty); | |
| 2445 | 2467 | unlock: |
| 2446 | − mutex_unlock(&tty_mutex); | |
| 2468 | + read_unlock(&tasklist_lock); | |
| 2469 | + tty_unlock(tty); | |
| 2447 | 2470 | return ret; |
| 2448 | 2471 | } |
| 2449 | 2472 | |
| @@ -2468,6 +2491,27 @@ struct pid *tty_get_pgrp(struct tty_struct *tty) · 18 unmodified lines | ||
| 2468 | 2491 | } |
| 2469 | 2492 | EXPORT_SYMBOL_GPL(tty_get_pgrp); |
| 2470 | 2493 | |
| 2494 | +/* | |
| 2495 | + * This checks not only the pgrp, but falls back on the pid if no | |
| 2496 | + * satisfactory pgrp is found. I dunno - gdb doesn't work correctly | |
| 2497 | + * without this... | |
| 2498 | + * | |
| 2499 | + * The caller must hold rcu lock or the tasklist lock. | |
| 2500 | + */ | |
| 2501 | +static struct pid *session_of_pgrp(struct pid *pgrp) | |
| 2502 | +{ | |
| 2503 | + struct task_struct *p; | |
| 2504 | + struct pid *sid = NULL; | |
| 2505 | + | |
| 2506 | + p = pid_task(pgrp, PIDTYPE_PGID); | |
| 2507 | + if (p == NULL) | |
| 2508 | + p = pid_task(pgrp, PIDTYPE_PID); | |
| 2509 | + if (p != NULL) | |
| 2510 | + sid = task_session(p); | |
| 2511 | + | |
| 2512 | + return sid; | |
| 2513 | +} | |
| 2514 | + | |
| 2471 | 2515 | /** |
| 2472 | 2516 | * tiocgpgrp - get process group |
| 2473 | 2517 | * @tty: tty passed by user |
| @@ -2714,23 +2758,35 @@ static int tty_tiocgicount(struct tty_struct *tty, void __user *arg) · 240 unmodified lines | ||
| 2714 | 2758 | return 0; |
| 2715 | 2759 | } |
| 2716 | 2760 | |
| 2717 | −struct tty_struct *tty_pair_get_tty(struct tty_struct *tty) | |
| 2761 | +static void tty_warn_deprecated_flags(struct serial_struct __user *ss) | |
| 2718 | 2762 | { |
| 2719 | − if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | |
| 2720 | − tty->driver->subtype == PTY_TYPE_MASTER) | |
| 2721 | − tty = tty->link; | |
| 2722 | − return tty; | |
| 2763 | + static DEFINE_RATELIMIT_STATE(depr_flags, | |
| 2764 | + DEFAULT_RATELIMIT_INTERVAL, | |
| 2765 | + DEFAULT_RATELIMIT_BURST); | |
| 2766 | + char comm[TASK_COMM_LEN]; | |
| 2767 | + int flags; | |
| 2768 | + | |
| 2769 | + if (get_user(flags, &ss->flags)) | |
| 2770 | + return; | |
| 2771 | + | |
| 2772 | + flags &= ASYNC_DEPRECATED; | |
| 2773 | + | |
| 2774 | + if (flags && __ratelimit(&depr_flags)) | |
| 2775 | + pr_warning("%s: '%s' is using deprecated serial flags (with no effect): %.8x\n", | |
| 2776 | + __func__, get_task_comm(comm, current), flags); | |
| 2723 | 2777 | } |
| 2724 | −EXPORT_SYMBOL(tty_pair_get_tty); | |
| 2725 | 2778 | |
| 2726 | −struct tty_struct *tty_pair_get_pty(struct tty_struct *tty) | |
| 2779 | +/* | |
| 2780 | + * if pty, return the slave side (real_tty) | |
| 2781 | + * otherwise, return self | |
| 2782 | + */ | |
| 2783 | +static struct tty_struct *tty_pair_get_tty(struct tty_struct *tty) | |
| 2727 | 2784 | { |
| 2728 | 2785 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
| 2729 | 2786 | tty->driver->subtype == PTY_TYPE_MASTER) |
| 2730 | − return tty; | |
| 2731 | − return tty->link; | |
| 2787 | + tty = tty->link; | |
| 2788 | + return tty; | |
| 2732 | 2789 | } |
| 2733 | −EXPORT_SYMBOL(tty_pair_get_pty); | |
| 2734 | 2790 | |
| 2735 | 2791 | /* |
| 2736 | 2792 | * Split this up, as gcc can choke on it otherwise.. |
| @@ -2859,13 +2915,16 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) · 122 unmodified lines | ||
| 2859 | 2915 | case TCIFLUSH: |
| 2860 | 2916 | case TCIOFLUSH: |
| 2861 | 2917 | /* flush tty buffer and allow ldisc to process ioctl */ |
| 2862 | − tty_buffer_flush(tty); | |
| 2918 | + tty_buffer_flush(tty, NULL); | |
| 2863 | 2919 | break; |
| 2864 | 2920 | } |
| 2865 | 2921 | break; |
| 2922 | + case TIOCSSERIAL: | |
| 2923 | + tty_warn_deprecated_flags(p); | |
| 2924 | + break; | |
| 2866 | 2925 | } |
| 2867 | 2926 | if (tty->ops->ioctl) { |
| 2868 | − retval = (tty->ops->ioctl)(tty, cmd, arg); | |
| 2927 | + retval = tty->ops->ioctl(tty, cmd, arg); | |
| 2869 | 2928 | if (retval != -ENOIOCTLCMD) |
| 2870 | 2929 | return retval; |
| 2871 | 2930 | } |
| @@ -2892,7 +2951,7 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd, · 20 unmodified lines | ||
| 2892 | 2951 | return -EINVAL; |
| 2893 | 2952 | |
| 2894 | 2953 | if (tty->ops->compat_ioctl) { |
| 2895 | − retval = (tty->ops->compat_ioctl)(tty, cmd, arg); | |
| 2954 | + retval = tty->ops->compat_ioctl(tty, cmd, arg); | |
| 2896 | 2955 | if (retval != -ENOIOCTLCMD) |
| 2897 | 2956 | return retval; |
| 2898 | 2957 | } |
| @@ -3443,59 +3502,6 @@ dev_t tty_devnum(struct tty_struct *tty) · 544 unmodified lines | ||
| 3443 | 3502 | } |
| 3444 | 3503 | EXPORT_SYMBOL(tty_devnum); |
| 3445 | 3504 | |
| 3446 | −void proc_clear_tty(struct task_struct *p) | |
| 3447 | −{ | |
| 3448 | − unsigned long flags; | |
| 3449 | − struct tty_struct *tty; | |
| 3450 | − spin_lock_irqsave(&p->sighand->siglock, flags); | |
| 3451 | − tty = p->signal->tty; | |
| 3452 | − p->signal->tty = NULL; | |
| 3453 | − spin_unlock_irqrestore(&p->sighand->siglock, flags); | |
| 3454 | − tty_kref_put(tty); | |
| 3455 | −} | |
| 3456 | − | |
| 3457 | −/* Called under the sighand lock */ | |
| 3458 | − | |
| 3459 | −static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) | |
| 3460 | −{ | |
| 3461 | − if (tty) { | |
| 3462 | − unsigned long flags; | |
| 3463 | − /* We should not have a session or pgrp to put here but.... */ | |
| 3464 | − spin_lock_irqsave(&tty->ctrl_lock, flags); | |
| 3465 | − put_pid(tty->session); | |
| 3466 | − put_pid(tty->pgrp); | |
| 3467 | − tty->pgrp = get_pid(task_pgrp(tsk)); | |
| 3468 | − spin_unlock_irqrestore(&tty->ctrl_lock, flags); | |
| 3469 | − tty->session = get_pid(task_session(tsk)); | |
| 3470 | − if (tsk->signal->tty) { | |
| 3471 | − printk(KERN_DEBUG "tty not NULL!!\n"); | |
| 3472 | − tty_kref_put(tsk->signal->tty); | |
| 3473 | − } | |
| 3474 | − } | |
| 3475 | − put_pid(tsk->signal->tty_old_pgrp); | |
| 3476 | − tsk->signal->tty = tty_kref_get(tty); | |
| 3477 | − tsk->signal->tty_old_pgrp = NULL; | |
| 3478 | −} | |
| 3479 | − | |
| 3480 | −static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) | |
| 3481 | −{ | |
| 3482 | − spin_lock_irq(&tsk->sighand->siglock); | |
| 3483 | − __proc_set_tty(tsk, tty); | |
| 3484 | − spin_unlock_irq(&tsk->sighand->siglock); | |
| 3485 | −} | |
| 3486 | − | |
| 3487 | −struct tty_struct *get_current_tty(void) | |
| 3488 | −{ | |
| 3489 | − struct tty_struct *tty; | |
| 3490 | − unsigned long flags; | |
| 3491 | − | |
| 3492 | − spin_lock_irqsave(¤t->sighand->siglock, flags); | |
| 3493 | − tty = tty_kref_get(current->signal->tty); | |
| 3494 | − spin_unlock_irqrestore(¤t->sighand->siglock, flags); | |
| 3495 | − return tty; | |
| 3496 | −} | |
| 3497 | −EXPORT_SYMBOL_GPL(get_current_tty); | |
| 3498 | − | |
| 3499 | 3505 | void tty_default_fops(struct file_operations *fops) |
| 3500 | 3506 | { |
| 3501 | 3507 | *fops = tty_fops; |
| @@ -524,9 +524,8 @@ EXPORT_SYMBOL(tty_termios_hw_change); · 523 unmodified lines | ||
| 524 | 524 | * @tty: tty to update |
| 525 | 525 | * @new_termios: desired new value |
| 526 | 526 | * |
| 527 | − * Perform updates to the termios values set on this terminal. There | |
| 528 | − * is a bit of layering violation here with n_tty in terms of the | |
| 529 | − * internal knowledge of this function. | |
| 527 | + * Perform updates to the termios values set on this terminal. | |
| 528 | + * A master pty's termios should never be set. | |
| 530 | 529 | * |
| 531 | 530 | * Locking: termios_rwsem |
| 532 | 531 | */ |
| @@ -535,8 +534,9 @@ int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios) · 2 unmodified lines | ||
| 535 | 534 | { |
| 536 | 535 | struct ktermios old_termios; |
| 537 | 536 | struct tty_ldisc *ld; |
| 538 | − unsigned long flags; | |
| 539 | 537 | |
| 538 | + WARN_ON(tty->driver->type == TTY_DRIVER_TYPE_PTY && | |
| 539 | + tty->driver->subtype == PTY_TYPE_MASTER); | |
| 540 | 540 | /* |
| 541 | 541 | * Perform the actual termios internal changes under lock. |
| 542 | 542 | */ |
| @@ -549,41 +549,15 @@ int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios) · 6 unmodified lines | ||
| 549 | 549 | tty->termios = *new_termios; |
| 550 | 550 | unset_locked_termios(&tty->termios, &old_termios, &tty->termios_locked); |
| 551 | 551 | |
| 552 | − /* See if packet mode change of state. */ | |
| 553 | − if (tty->link && tty->link->packet) { | |
| 554 | − int extproc = (old_termios.c_lflag & EXTPROC) | | |
| 555 | − (tty->termios.c_lflag & EXTPROC); | |
| 556 | − int old_flow = ((old_termios.c_iflag & IXON) && | |
| 557 | − (old_termios.c_cc[VSTOP] == '\023') && | |
| 558 | − (old_termios.c_cc[VSTART] == '\021')); | |
| 559 | − int new_flow = (I_IXON(tty) && | |
| 560 | − STOP_CHAR(tty) == '\023' && | |
| 561 | − START_CHAR(tty) == '\021'); | |
| 562 | − if ((old_flow != new_flow) || extproc) { | |
| 563 | − spin_lock_irqsave(&tty->ctrl_lock, flags); | |
| 564 | − if (old_flow != new_flow) { | |
| 565 | − tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP); | |
| 566 | − if (new_flow) | |
| 567 | − tty->ctrl_status |= TIOCPKT_DOSTOP; | |
| 568 | − else | |
| 569 | − tty->ctrl_status |= TIOCPKT_NOSTOP; | |
| 570 | − } | |
| 571 | − if (extproc) | |
| 572 | − tty->ctrl_status |= TIOCPKT_IOCTL; | |
| 573 | − spin_unlock_irqrestore(&tty->ctrl_lock, flags); | |
| 574 | − wake_up_interruptible(&tty->link->read_wait); | |
| 575 | − } | |
| 576 | − } | |
| 577 | − | |
| 578 | 552 | if (tty->ops->set_termios) |
| 579 | − (*tty->ops->set_termios)(tty, &old_termios); | |
| 553 | + tty->ops->set_termios(tty, &old_termios); | |
| 580 | 554 | else |
| 581 | 555 | tty_termios_copy_hw(&tty->termios, &old_termios); |
| 582 | 556 | |
| 583 | 557 | ld = tty_ldisc_ref(tty); |
| 584 | 558 | if (ld != NULL) { |
| 585 | 559 | if (ld->ops->set_termios) |
| 586 | − (ld->ops->set_termios)(tty, &old_termios); | |
| 560 | + ld->ops->set_termios(tty, &old_termios); | |
| 587 | 561 | tty_ldisc_deref(ld); |
| 588 | 562 | } |
| 589 | 563 | up_write(&tty->termios_rwsem); |
| @@ -308,23 +308,41 @@ EXPORT_SYMBOL_GPL(tty_ldisc_deref); · 307 unmodified lines | ||
| 308 | 308 | |
| 309 | 309 | |
| 310 | 310 | static inline int __lockfunc |
| 311 | −tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout) | |
| 311 | +__tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout) | |
| 312 | 312 | { |
| 313 | 313 | return ldsem_down_write(&tty->ldisc_sem, timeout); |
| 314 | 314 | } |
| 315 | 315 | |
| 316 | 316 | static inline int __lockfunc |
| 317 | −tty_ldisc_lock_nested(struct tty_struct *tty, unsigned long timeout) | |
| 317 | +__tty_ldisc_lock_nested(struct tty_struct *tty, unsigned long timeout) | |
| 318 | 318 | { |
| 319 | 319 | return ldsem_down_write_nested(&tty->ldisc_sem, |
| 320 | 320 | LDISC_SEM_OTHER, timeout); |
| 321 | 321 | } |
| 322 | 322 | |
| 323 | −static inline void tty_ldisc_unlock(struct tty_struct *tty) | |
| 323 | +static inline void __tty_ldisc_unlock(struct tty_struct *tty) | |
| 324 | 324 | { |
| 325 | 325 | return ldsem_up_write(&tty->ldisc_sem); |
| 326 | 326 | } |
| 327 | 327 | |
| 328 | +static int __lockfunc | |
| 329 | +tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout) | |
| 330 | +{ | |
| 331 | + int ret; | |
| 332 | + | |
| 333 | + ret = __tty_ldisc_lock(tty, timeout); | |
| 334 | + if (!ret) | |
| 335 | + return -EBUSY; | |
| 336 | + set_bit(TTY_LDISC_HALTED, &tty->flags); | |
| 337 | + return 0; | |
| 338 | +} | |
| 339 | + | |
| 340 | +static void tty_ldisc_unlock(struct tty_struct *tty) | |
| 341 | +{ | |
| 342 | + clear_bit(TTY_LDISC_HALTED, &tty->flags); | |
| 343 | + __tty_ldisc_unlock(tty); | |
| 344 | +} | |
| 345 | + | |
| 328 | 346 | static int __lockfunc |
| 329 | 347 | tty_ldisc_lock_pair_timeout(struct tty_struct *tty, struct tty_struct *tty2, |
| 330 | 348 | unsigned long timeout) |
| @@ -332,24 +350,24 @@ tty_ldisc_lock_pair_timeout(struct tty_struct *tty, struct tty_struct *tty2, · 1 unmodified line | ||
| 332 | 350 | int ret; |
| 333 | 351 | |
| 334 | 352 | if (tty < tty2) { |
| 335 | − ret = tty_ldisc_lock(tty, timeout); | |
| 353 | + ret = __tty_ldisc_lock(tty, timeout); | |
| 336 | 354 | if (ret) { |
| 337 | − ret = tty_ldisc_lock_nested(tty2, timeout); | |
| 355 | + ret = __tty_ldisc_lock_nested(tty2, timeout); | |
| 338 | 356 | if (!ret) |
| 339 | − tty_ldisc_unlock(tty); | |
| 357 | + __tty_ldisc_unlock(tty); | |
| 340 | 358 | } |
| 341 | 359 | } else { |
| 342 | 360 | /* if this is possible, it has lots of implications */ |
| 343 | 361 | WARN_ON_ONCE(tty == tty2); |
| 344 | 362 | if (tty2 && tty != tty2) { |
| 345 | − ret = tty_ldisc_lock(tty2, timeout); | |
| 363 | + ret = __tty_ldisc_lock(tty2, timeout); | |
| 346 | 364 | if (ret) { |
| 347 | − ret = tty_ldisc_lock_nested(tty, timeout); | |
| 365 | + ret = __tty_ldisc_lock_nested(tty, timeout); | |
| 348 | 366 | if (!ret) |
| 349 | − tty_ldisc_unlock(tty2); | |
| 367 | + __tty_ldisc_unlock(tty2); | |
| 350 | 368 | } |
| 351 | 369 | } else |
| 352 | − ret = tty_ldisc_lock(tty, timeout); | |
| 370 | + ret = __tty_ldisc_lock(tty, timeout); | |
| 353 | 371 | } |
| 354 | 372 | |
| 355 | 373 | if (!ret) |
| @@ -370,38 +388,26 @@ tty_ldisc_lock_pair(struct tty_struct *tty, struct tty_struct *tty2) · 14 unmodified lines | ||
| 370 | 388 | static void __lockfunc tty_ldisc_unlock_pair(struct tty_struct *tty, |
| 371 | 389 | struct tty_struct *tty2) |
| 372 | 390 | { |
| 373 | − tty_ldisc_unlock(tty); | |
| 374 | − if (tty2) | |
| 375 | − tty_ldisc_unlock(tty2); | |
| 376 | −} | |
| 377 | − | |
| 378 | −static void __lockfunc tty_ldisc_enable_pair(struct tty_struct *tty, | |
| 379 | − struct tty_struct *tty2) | |
| 380 | −{ | |
| 381 | − clear_bit(TTY_LDISC_HALTED, &tty->flags); | |
| 391 | + __tty_ldisc_unlock(tty); | |
| 382 | 392 | if (tty2) |
| 383 | − clear_bit(TTY_LDISC_HALTED, &tty2->flags); | |
| 384 | − | |
| 385 | − tty_ldisc_unlock_pair(tty, tty2); | |
| 393 | + __tty_ldisc_unlock(tty2); | |
| 386 | 394 | } |
| 387 | 395 | |
| 388 | 396 | /** |
| 389 | 397 | * tty_ldisc_flush - flush line discipline queue |
| 390 | 398 | * @tty: tty |
| 391 | 399 | * |
| 392 | − * Flush the line discipline queue (if any) for this tty. If there | |
| 393 | − * is no line discipline active this is a no-op. | |
| 400 | + * Flush the line discipline queue (if any) and the tty flip buffers | |
| 401 | + * for this tty. | |
| 394 | 402 | */ |
| 395 | 403 | |
| 396 | 404 | void tty_ldisc_flush(struct tty_struct *tty) |
| 397 | 405 | { |
| 398 | 406 | struct tty_ldisc *ld = tty_ldisc_ref(tty); |
| 399 | − if (ld) { | |
| 400 | − if (ld->ops->flush_buffer) | |
| 401 | − ld->ops->flush_buffer(tty); | |
| 407 | + | |
| 408 | + tty_buffer_flush(tty, ld); | |
| 409 | + if (ld) | |
| 402 | 410 | tty_ldisc_deref(ld); |
| 403 | − } | |
| 404 | − tty_buffer_flush(tty); | |
| 405 | 411 | } |
| 406 | 412 | EXPORT_SYMBOL_GPL(tty_ldisc_flush); |
| 407 | 413 | |
| @@ -517,15 +523,16 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) · 109 unmodified lines | ||
| 517 | 523 | { |
| 518 | 524 | int retval; |
| 519 | 525 | struct tty_ldisc *old_ldisc, *new_ldisc; |
| 520 | − struct tty_struct *o_tty = tty->link; | |
| 521 | 526 | |
| 522 | 527 | new_ldisc = tty_ldisc_get(tty, ldisc); |
| 523 | 528 | if (IS_ERR(new_ldisc)) |
| 524 | 529 | return PTR_ERR(new_ldisc); |
| 525 | 530 | |
| 526 | − retval = tty_ldisc_lock_pair_timeout(tty, o_tty, 5 * HZ); | |
| 531 | + tty_lock(tty); | |
| 532 | + retval = tty_ldisc_lock(tty, 5 * HZ); | |
| 527 | 533 | if (retval) { |
| 528 | 534 | tty_ldisc_put(new_ldisc); |
| 535 | + tty_unlock(tty); | |
| 529 | 536 | return retval; |
| 530 | 537 | } |
| 531 | 538 | |
| @@ -534,19 +541,18 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) · 2 unmodified lines | ||
| 534 | 541 | */ |
| 535 | 542 | |
| 536 | 543 | if (tty->ldisc->ops->num == ldisc) { |
| 537 | − tty_ldisc_enable_pair(tty, o_tty); | |
| 544 | + tty_ldisc_unlock(tty); | |
| 538 | 545 | tty_ldisc_put(new_ldisc); |
| 546 | + tty_unlock(tty); | |
| 539 | 547 | return 0; |
| 540 | 548 | } |
| 541 | 549 | |
| 542 | 550 | old_ldisc = tty->ldisc; |
| 543 | − tty_lock(tty); | |
| 544 | 551 | |
| 545 | − if (test_bit(TTY_HUPPING, &tty->flags) || | |
| 546 | − test_bit(TTY_HUPPED, &tty->flags)) { | |
| 552 | + if (test_bit(TTY_HUPPED, &tty->flags)) { | |
| 547 | 553 | /* We were raced by the hangup method. It will have stomped |
| 548 | 554 | the ldisc data and closed the ldisc down */ |
| 549 | − tty_ldisc_enable_pair(tty, o_tty); | |
| 555 | + tty_ldisc_unlock(tty); | |
| 550 | 556 | tty_ldisc_put(new_ldisc); |
| 551 | 557 | tty_unlock(tty); |
| 552 | 558 | return -EIO; |
| @@ -566,8 +572,11 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) · 13 unmodified lines | ||
| 566 | 572 | tty_ldisc_restore(tty, old_ldisc); |
| 567 | 573 | } |
| 568 | 574 | |
| 569 | − if (tty->ldisc->ops->num != old_ldisc->ops->num && tty->ops->set_ldisc) | |
| 575 | + if (tty->ldisc->ops->num != old_ldisc->ops->num && tty->ops->set_ldisc) { | |
| 576 | + down_read(&tty->termios_rwsem); | |
| 570 | 577 | tty->ops->set_ldisc(tty); |
| 578 | + up_read(&tty->termios_rwsem); | |
| 579 | + } | |
| 571 | 580 | |
| 572 | 581 | /* At this point we hold a reference to the new ldisc and a |
| 573 | 582 | reference to the old ldisc, or we hold two references to |
| @@ -580,13 +589,11 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) · 6 unmodified lines | ||
| 580 | 589 | /* |
| 581 | 590 | * Allow ldisc referencing to occur again |
| 582 | 591 | */ |
| 583 | − tty_ldisc_enable_pair(tty, o_tty); | |
| 592 | + tty_ldisc_unlock(tty); | |
| 584 | 593 | |
| 585 | 594 | /* Restart the work queue in case no characters kick it off. Safe if |
| 586 | 595 | already running */ |
| 587 | 596 | schedule_work(&tty->port->buf.work); |
| 588 | − if (o_tty) | |
| 589 | − schedule_work(&o_tty->port->buf.work); | |
| 590 | 597 | |
| 591 | 598 | tty_unlock(tty); |
| 592 | 599 | return retval; |
| @@ -675,16 +682,13 @@ void tty_ldisc_hangup(struct tty_struct *tty) · 82 unmodified lines | ||
| 675 | 682 | wake_up_interruptible_poll(&tty->write_wait, POLLOUT); |
| 676 | 683 | wake_up_interruptible_poll(&tty->read_wait, POLLIN); |
| 677 | 684 | |
| 678 | − tty_unlock(tty); | |
| 679 | − | |
| 680 | 685 | /* |
| 681 | 686 | * Shutdown the current line discipline, and reset it to |
| 682 | 687 | * N_TTY if need be. |
| 683 | 688 | * |
| 684 | 689 | * Avoid racing set_ldisc or tty_ldisc_release |
| 685 | 690 | */ |
| 686 | − tty_ldisc_lock_pair(tty, tty->link); | |
| 687 | − tty_lock(tty); | |
| 691 | + tty_ldisc_lock(tty, MAX_SCHEDULE_TIMEOUT); | |
| 688 | 692 | |
| 689 | 693 | if (tty->ldisc) { |
| 690 | 694 | |
| @@ -706,7 +710,7 @@ void tty_ldisc_hangup(struct tty_struct *tty) · 15 unmodified lines | ||
| 706 | 710 | WARN_ON(tty_ldisc_open(tty, tty->ldisc)); |
| 707 | 711 | } |
| 708 | 712 | } |
| 709 | − tty_ldisc_enable_pair(tty, tty->link); | |
| 713 | + tty_ldisc_unlock(tty); | |
| 710 | 714 | if (reset) |
| 711 | 715 | tty_reset_termios(tty); |
| 712 | 716 | |
| @@ -758,16 +762,17 @@ static void tty_ldisc_kill(struct tty_struct *tty) · 45 unmodified lines | ||
| 758 | 762 | |
| 759 | 763 | /** |
| 760 | 764 | * tty_ldisc_release - release line discipline |
| 761 | − * @tty: tty being shut down | |
| 762 | − * @o_tty: pair tty for pty/tty pairs | |
| 765 | + * @tty: tty being shut down (or one end of pty pair) | |
| 763 | 766 | * |
| 764 | − * Called during the final close of a tty/pty pair in order to shut down | |
| 765 | − * the line discpline layer. On exit the ldisc assigned is N_TTY and the | |
| 766 | − * ldisc has not been opened. | |
| 767 | + * Called during the final close of a tty or a pty pair in order to shut | |
| 768 | + * down the line discpline layer. On exit, each ldisc assigned is N_TTY and | |
| 769 | + * each ldisc has not been opened. | |
| 767 | 770 | */ |
| 768 | 771 | |
| 769 | −void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) | |
| 772 | +void tty_ldisc_release(struct tty_struct *tty) | |
| 770 | 773 | { |
| 774 | + struct tty_struct *o_tty = tty->link; | |
| 775 | + | |
| 771 | 776 | /* |
| 772 | 777 | * Shutdown this line discipline. As this is the final close, |
| 773 | 778 | * it does not race with the set_ldisc code path. |
| @@ -776,13 +781,9 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) · 2 unmodified lines | ||
| 776 | 781 | tty_ldisc_debug(tty, "closing ldisc: %p\n", tty->ldisc); |
| 777 | 782 | |
| 778 | 783 | tty_ldisc_lock_pair(tty, o_tty); |
| 779 | − tty_lock_pair(tty, o_tty); | |
| 780 | − | |
| 781 | 784 | tty_ldisc_kill(tty); |
| 782 | 785 | if (o_tty) |
| 783 | 786 | tty_ldisc_kill(o_tty); |
| 784 | − | |
| 785 | − tty_unlock_pair(tty, o_tty); | |
| 786 | 787 | tty_ldisc_unlock_pair(tty, o_tty); |
| 787 | 788 | |
| 788 | 789 | /* And the memory resources remaining (buffers, termios) will be |
| @@ -4,19 +4,23 @@ · 3 unmodified lines | ||
| 4 | 4 | #include <linux/semaphore.h> |
| 5 | 5 | #include <linux/sched.h> |
| 6 | 6 | |
| 7 | +/* | |
| 8 | + * Nested tty locks are necessary for releasing pty pairs. | |
| 9 | + * The stable lock order is master pty first, then slave pty. | |
| 10 | + */ | |
| 11 | + | |
| 7 | 12 | /* Legacy tty mutex glue */ |
| 8 | 13 | |
| 9 | 14 | enum { |
| 10 | 15 | TTY_MUTEX_NORMAL, |
| 11 | − TTY_MUTEX_NESTED, | |
| 16 | + TTY_MUTEX_SLAVE, | |
| 12 | 17 | }; |
| 13 | 18 | |
| 14 | 19 | /* |
| 15 | 20 | * Getting the big tty mutex. |
| 16 | 21 | */ |
| 17 | 22 | |
| 18 | −static void __lockfunc tty_lock_nested(struct tty_struct *tty, | |
| 19 | − unsigned int subclass) | |
| 23 | +void __lockfunc tty_lock(struct tty_struct *tty) | |
| 20 | 24 | { |
| 21 | 25 | if (tty->magic != TTY_MAGIC) { |
| 22 | 26 | pr_err("L Bad %p\n", tty); |
| @@ -24,12 +28,7 @@ static void __lockfunc tty_lock_nested(struct tty_struct *tty, · 1 unmodified line | ||
| 24 | 28 | return; |
| 25 | 29 | } |
| 26 | 30 | tty_kref_get(tty); |
| 27 | − mutex_lock_nested(&tty->legacy_mutex, subclass); | |
| 28 | −} | |
| 29 | − | |
| 30 | −void __lockfunc tty_lock(struct tty_struct *tty) | |
| 31 | −{ | |
| 32 | − return tty_lock_nested(tty, TTY_MUTEX_NORMAL); | |
| 31 | + mutex_lock(&tty->legacy_mutex); | |
| 33 | 32 | } |
| 34 | 33 | EXPORT_SYMBOL(tty_lock); |
| 35 | 34 | |
| @@ -45,29 +44,23 @@ void __lockfunc tty_unlock(struct tty_struct *tty) · 9 unmodified lines | ||
| 45 | 44 | } |
| 46 | 45 | EXPORT_SYMBOL(tty_unlock); |
| 47 | 46 | |
| 48 | −/* | |
| 49 | − * Getting the big tty mutex for a pair of ttys with lock ordering | |
| 50 | − * On a non pty/tty pair tty2 can be NULL which is just fine. | |
| 51 | − */ | |
| 52 | −void __lockfunc tty_lock_pair(struct tty_struct *tty, | |
| 53 | − struct tty_struct *tty2) | |
| 47 | +void __lockfunc tty_lock_slave(struct tty_struct *tty) | |
| 54 | 48 | { |
| 55 | − if (tty < tty2) { | |
| 49 | + if (tty && tty != tty->link) { | |
| 50 | + WARN_ON(!mutex_is_locked(&tty->link->legacy_mutex) || | |
| 51 | + !tty->driver->type == TTY_DRIVER_TYPE_PTY || | |
| 52 | + !tty->driver->type == PTY_TYPE_SLAVE); | |
| 56 | 53 | tty_lock(tty); |
| 57 | − tty_lock_nested(tty2, TTY_MUTEX_NESTED); | |
| 58 | − } else { | |
| 59 | − if (tty2 && tty2 != tty) | |
| 60 | − tty_lock(tty2); | |
| 61 | − tty_lock_nested(tty, TTY_MUTEX_NESTED); | |
| 62 | 54 | } |
| 63 | 55 | } |
| 64 | −EXPORT_SYMBOL(tty_lock_pair); | |
| 65 | 56 | |
| 66 | −void __lockfunc tty_unlock_pair(struct tty_struct *tty, | |
| 67 | − struct tty_struct *tty2) | |
| 57 | +void __lockfunc tty_unlock_slave(struct tty_struct *tty) | |
| 58 | +{ | |
| 59 | + if (tty && tty != tty->link) | |
| 60 | + tty_unlock(tty); | |
| 61 | +} | |
| 62 | + | |
| 63 | +void tty_set_lock_subclass(struct tty_struct *tty) | |
| 68 | 64 | { |
| 69 | − tty_unlock(tty); | |
| 70 | − if (tty2 && tty2 != tty) | |
| 71 | − tty_unlock(tty2); | |
| 65 | + lockdep_set_subclass(&tty->legacy_mutex, TTY_MUTEX_SLAVE); | |
| 72 | 66 | } |
| 73 | −EXPORT_SYMBOL(tty_unlock_pair); | |
| @@ -193,8 +193,7 @@ void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty) · 192 unmodified lines | ||
| 193 | 193 | unsigned long flags; |
| 194 | 194 | |
| 195 | 195 | spin_lock_irqsave(&port->lock, flags); |
| 196 | − if (port->tty) | |
| 197 | − tty_kref_put(port->tty); | |
| 196 | + tty_kref_put(port->tty); | |
| 198 | 197 | port->tty = tty_kref_get(tty); |
| 199 | 198 | spin_unlock_irqrestore(&port->lock, flags); |
| 200 | 199 | } |
| @@ -473,12 +472,10 @@ int tty_port_close_start(struct tty_port *port, · 272 unmodified lines | ||
| 473 | 472 | { |
| 474 | 473 | unsigned long flags; |
| 475 | 474 | |
| 476 | − spin_lock_irqsave(&port->lock, flags); | |
| 477 | − if (tty_hung_up_p(filp)) { | |
| 478 | − spin_unlock_irqrestore(&port->lock, flags); | |
| 475 | + if (tty_hung_up_p(filp)) | |
| 479 | 476 | return 0; |
| 480 | − } | |
| 481 | 477 | |
| 478 | + spin_lock_irqsave(&port->lock, flags); | |
| 482 | 479 | if (tty->count == 1 && port->count != 1) { |
| 483 | 480 | printk(KERN_WARNING |
| 484 | 481 | "tty_port_close_start: tty->count = 1 port count = %d.\n", |
| @@ -522,6 +519,7 @@ void tty_port_close_end(struct tty_port *port, struct tty_struct *tty) · 37 unmodified lines | ||
| 522 | 519 | { |
| 523 | 520 | unsigned long flags; |
| 524 | 521 | |
| 522 | + tty_ldisc_flush(tty); | |
| 525 | 523 | tty->closing = 0; |
| 526 | 524 | |
| 527 | 525 | spin_lock_irqsave(&port->lock, flags); |
| @@ -924,7 +924,7 @@ static void k_brl(struct vc_data *vc, unsigned char value, char up_flag) · 923 unmodified lines | ||
| 924 | 924 | |
| 925 | 925 | if (kbd->kbdmode != VC_UNICODE) { |
| 926 | 926 | if (!up_flag) |
| 927 | − pr_warning("keyboard mode must be unicode for braille patterns\n"); | |
| 927 | + pr_warn("keyboard mode must be unicode for braille patterns\n"); | |
| 928 | 928 | return; |
| 929 | 929 | } |
| 930 | 930 | |
| @@ -1253,8 +1253,8 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) · 322 unmodified lines | ||
| 1253 | 1253 | if (raw_mode && !hw_raw) |
| 1254 | 1254 | if (emulate_raw(vc, keycode, !down << 7)) |
| 1255 | 1255 | if (keycode < BTN_MISC && printk_ratelimit()) |
| 1256 | − pr_warning("can't emulate rawmode for keycode %d\n", | |
| 1257 | − keycode); | |
| 1256 | + pr_warn("can't emulate rawmode for keycode %d\n", | |
| 1257 | + keycode); | |
| 1258 | 1258 | |
| 1259 | 1259 | #ifdef CONFIG_SPARC |
| 1260 | 1260 | if (keycode == KEY_A && sparc_l1_a_state) { |
| @@ -156,6 +156,8 @@ static void console_callback(struct work_struct *ignored); · 155 unmodified lines | ||
| 156 | 156 | static void blank_screen_t(unsigned long dummy); |
| 157 | 157 | static void set_palette(struct vc_data *vc); |
| 158 | 158 | |
| 159 | +#define vt_get_kmsg_redirect() vt_kmsg_redirect(-1) | |
| 160 | + | |
| 159 | 161 | static int printable; /* Is console ready for printing? */ |
| 160 | 162 | int default_utf8 = true; |
| 161 | 163 | module_param(default_utf8, int, S_IRUGO | S_IWUSR); |
| @@ -1367,9 +1369,11 @@ static void csi_m(struct vc_data *vc) · 1205 unmodified lines | ||
| 1367 | 1369 | rgb_from_256(vc->vc_par[i])); |
| 1368 | 1370 | } else if (vc->vc_par[i] == 2 && /* 24 bit */ |
| 1369 | 1371 | i <= vc->vc_npar + 3) {/* extremely rare */ |
| 1370 | − struct rgb c = {r:vc->vc_par[i+1], | |
| 1371 | − g:vc->vc_par[i+2], | |
| 1372 | − b:vc->vc_par[i+3]}; | |
| 1372 | + struct rgb c = { | |
| 1373 | + .r = vc->vc_par[i + 1], | |
| 1374 | + .g = vc->vc_par[i + 2], | |
| 1375 | + .b = vc->vc_par[i + 3], | |
| 1376 | + }; | |
| 1373 | 1377 | rgb_foreground(vc, c); |
| 1374 | 1378 | i += 3; |
| 1375 | 1379 | } |
| @@ -1388,9 +1392,11 @@ static void csi_m(struct vc_data *vc) · 12 unmodified lines | ||
| 1388 | 1392 | rgb_from_256(vc->vc_par[i])); |
| 1389 | 1393 | } else if (vc->vc_par[i] == 2 && /* 24 bit */ |
| 1390 | 1394 | i <= vc->vc_npar + 3) { |
| 1391 | − struct rgb c = {r:vc->vc_par[i+1], | |
| 1392 | − g:vc->vc_par[i+2], | |
| 1393 | − b:vc->vc_par[i+3]}; | |
| 1395 | + struct rgb c = { | |
| 1396 | + .r = vc->vc_par[i + 1], | |
| 1397 | + .g = vc->vc_par[i + 2], | |
| 1398 | + .b = vc->vc_par[i + 3], | |
| 1399 | + }; | |
| 1394 | 1400 | rgb_background(vc, c); |
| 1395 | 1401 | i += 3; |
| 1396 | 1402 | } |
| @@ -3849,8 +3855,8 @@ void do_unblank_screen(int leaving_gfx) · 2452 unmodified lines | ||
| 3849 | 3855 | return; |
| 3850 | 3856 | if (!vc_cons_allocated(fg_console)) { |
| 3851 | 3857 | /* impossible */ |
| 3852 | − pr_warning("unblank_screen: tty %d not allocated ??\n", | |
| 3853 | − fg_console+1); | |
| 3858 | + pr_warn("unblank_screen: tty %d not allocated ??\n", | |
| 3859 | + fg_console + 1); | |
| 3854 | 3860 | return; |
| 3855 | 3861 | } |
| 3856 | 3862 | vc = vc_cons[fg_console].d; |
| @@ -416,9 +416,6 @@ extern int __kernel_text_address(unsigned long addr); · 415 unmodified lines | ||
| 416 | 416 | extern int kernel_text_address(unsigned long addr); |
| 417 | 417 | extern int func_ptr_is_kernel_text(void *ptr); |
| 418 | 418 | |
| 419 | −struct pid; | |
| 420 | −extern struct pid *session_of_pgrp(struct pid *pgrp); | |
| 421 | − | |
| 422 | 419 | unsigned long int_sqrt(unsigned long); |
| 423 | 420 | |
| 424 | 421 | extern void bust_spinlocks(int yes); |
| @@ -97,13 +97,10 @@ struct uart_8250_port { · 96 unmodified lines | ||
| 97 | 97 | unsigned char msr_saved_flags; |
| 98 | 98 | |
| 99 | 99 | struct uart_8250_dma *dma; |
| 100 | − struct serial_rs485 rs485; | |
| 101 | 100 | |
| 102 | 101 | /* 8250 specific callbacks */ |
| 103 | 102 | int (*dl_read)(struct uart_8250_port *); |
| 104 | 103 | void (*dl_write)(struct uart_8250_port *, int); |
| 105 | − int (*rs485_config)(struct uart_8250_port *, | |
| 106 | − struct serial_rs485 *rs485); | |
| 107 | 104 | }; |
| 108 | 105 | |
| 109 | 106 | static inline struct uart_8250_port *up_to_u8250p(struct uart_port *up) |
| @@ -116,6 +116,4 @@ · 115 unmodified lines | ||
| 116 | 116 | UART_FIFO_PARERR_MASK | \ |
| 117 | 117 | UART_FIFO_BRKDET_MASK) |
| 118 | 118 | |
| 119 | −#define UART_REG_SIZE 24 | |
| 120 | − | |
| 121 | 119 | #endif /* _LINUX_SERIAL_BCM63XX_H */ |
| @@ -63,7 +63,7 @@ struct uart_ops { · 62 unmodified lines | ||
| 63 | 63 | void (*flush_buffer)(struct uart_port *); |
| 64 | 64 | void (*set_termios)(struct uart_port *, struct ktermios *new, |
| 65 | 65 | struct ktermios *old); |
| 66 | − void (*set_ldisc)(struct uart_port *, int new); | |
| 66 | + void (*set_ldisc)(struct uart_port *, struct ktermios *); | |
| 67 | 67 | void (*pm)(struct uart_port *, unsigned int state, |
| 68 | 68 | unsigned int oldstate); |
| 69 | 69 | |
| @@ -131,6 +131,8 @@ struct uart_port { · 61 unmodified lines | ||
| 131 | 131 | void (*pm)(struct uart_port *, unsigned int state, |
| 132 | 132 | unsigned int old); |
| 133 | 133 | void (*handle_break)(struct uart_port *); |
| 134 | + int (*rs485_config)(struct uart_port *, | |
| 135 | + struct serial_rs485 *rs485); | |
| 134 | 136 | unsigned int irq; /* irq number */ |
| 135 | 137 | unsigned long irqflags; /* irq flags */ |
| 136 | 138 | unsigned int uartclk; /* base uart clock */ |
| @@ -140,12 +142,13 @@ struct uart_port { · 3 unmodified lines | ||
| 140 | 142 | unsigned char iotype; /* io access style */ |
| 141 | 143 | unsigned char unused1; |
| 142 | 144 | |
| 143 | −#define UPIO_PORT (0) | |
| 144 | −#define UPIO_HUB6 (1) | |
| 145 | −#define UPIO_MEM (2) | |
| 146 | −#define UPIO_MEM32 (3) | |
| 147 | −#define UPIO_AU (4) /* Au1x00 and RT288x type IO */ | |
| 148 | −#define UPIO_TSI (5) /* Tsi108/109 type IO */ | |
| 145 | +#define UPIO_PORT (0) /* 8b I/O port access */ | |
| 146 | +#define UPIO_HUB6 (1) /* Hub6 ISA card */ | |
| 147 | +#define UPIO_MEM (2) /* 8b MMIO access */ | |
| 148 | +#define UPIO_MEM32 (3) /* 32b little endian */ | |
| 149 | +#define UPIO_MEM32BE (4) /* 32b big endian */ | |
| 150 | +#define UPIO_AU (5) /* Au1x00 and RT288x type IO */ | |
| 151 | +#define UPIO_TSI (6) /* Tsi108/109 type IO */ | |
| 149 | 152 | |
| 150 | 153 | unsigned int read_status_mask; /* driver specific */ |
| 151 | 154 | unsigned int ignore_status_mask; /* driver specific */ |
| @@ -160,21 +163,33 @@ struct uart_port { · 8 unmodified lines | ||
| 160 | 163 | /* flags must be updated while holding port mutex */ |
| 161 | 164 | upf_t flags; |
| 162 | 165 | |
| 163 | −#define UPF_FOURPORT ((__force upf_t) (1 << 1)) | |
| 164 | −#define UPF_SAK ((__force upf_t) (1 << 2)) | |
| 165 | −#define UPF_SPD_MASK ((__force upf_t) (0x1030)) | |
| 166 | −#define UPF_SPD_HI ((__force upf_t) (0x0010)) | |
| 167 | −#define UPF_SPD_VHI ((__force upf_t) (0x0020)) | |
| 168 | −#define UPF_SPD_CUST ((__force upf_t) (0x0030)) | |
| 169 | −#define UPF_SPD_SHI ((__force upf_t) (0x1000)) | |
| 170 | −#define UPF_SPD_WARP ((__force upf_t) (0x1010)) | |
| 171 | −#define UPF_SKIP_TEST ((__force upf_t) (1 << 6)) | |
| 172 | −#define UPF_AUTO_IRQ ((__force upf_t) (1 << 7)) | |
| 173 | −#define UPF_HARDPPS_CD ((__force upf_t) (1 << 11)) | |
| 174 | −#define UPF_LOW_LATENCY ((__force upf_t) (1 << 13)) | |
| 175 | −#define UPF_BUGGY_UART ((__force upf_t) (1 << 14)) | |
| 166 | + /* | |
| 167 | + * These flags must be equivalent to the flags defined in | |
| 168 | + * include/uapi/linux/tty_flags.h which are the userspace definitions | |
| 169 | + * assigned from the serial_struct flags in uart_set_info() | |
| 170 | + * [for bit definitions in the UPF_CHANGE_MASK] | |
| 171 | + * | |
| 172 | + * Bits [0..UPF_LAST_USER] are userspace defined/visible/changeable | |
| 173 | + * except bit 15 (UPF_NO_TXEN_TEST) which is masked off. | |
| 174 | + * The remaining bits are serial-core specific and not modifiable by | |
| 175 | + * userspace. | |
| 176 | + */ | |
| 177 | +#define UPF_FOURPORT ((__force upf_t) ASYNC_FOURPORT /* 1 */ ) | |
| 178 | +#define UPF_SAK ((__force upf_t) ASYNC_SAK /* 2 */ ) | |
| 179 | +#define UPF_SPD_HI ((__force upf_t) ASYNC_SPD_HI /* 4 */ ) | |
| 180 | +#define UPF_SPD_VHI ((__force upf_t) ASYNC_SPD_VHI /* 5 */ ) | |
| 181 | +#define UPF_SPD_CUST ((__force upf_t) ASYNC_SPD_CUST /* 0x0030 */ ) | |
| 182 | +#define UPF_SPD_WARP ((__force upf_t) ASYNC_SPD_WARP /* 0x1010 */ ) | |
| 183 | +#define UPF_SPD_MASK ((__force upf_t) ASYNC_SPD_MASK /* 0x1030 */ ) | |
| 184 | +#define UPF_SKIP_TEST ((__force upf_t) ASYNC_SKIP_TEST /* 6 */ ) | |
| 185 | +#define UPF_AUTO_IRQ ((__force upf_t) ASYNC_AUTO_IRQ /* 7 */ ) | |
| 186 | +#define UPF_HARDPPS_CD ((__force upf_t) ASYNC_HARDPPS_CD /* 11 */ ) | |
| 187 | +#define UPF_SPD_SHI ((__force upf_t) ASYNC_SPD_SHI /* 12 */ ) | |
| 188 | +#define UPF_LOW_LATENCY ((__force upf_t) ASYNC_LOW_LATENCY /* 13 */ ) | |
| 189 | +#define UPF_BUGGY_UART ((__force upf_t) ASYNC_BUGGY_UART /* 14 */ ) | |
| 176 | 190 | #define UPF_NO_TXEN_TEST ((__force upf_t) (1 << 15)) |
| 177 | −#define UPF_MAGIC_MULTIPLIER ((__force upf_t) (1 << 16)) | |
| 191 | +#define UPF_MAGIC_MULTIPLIER ((__force upf_t) ASYNC_MAGIC_MULTIPLIER /* 16 */ ) | |
| 192 | + | |
| 178 | 193 | /* Port has hardware-assisted h/w flow control (iow, auto-RTS *not* auto-CTS) */ |
| 179 | 194 | #define UPF_HARD_FLOW ((__force upf_t) (1 << 21)) |
| 180 | 195 | /* Port has hardware-assisted s/w flow control */ |
| @@ -190,9 +205,14 @@ struct uart_port { · 9 unmodified lines | ||
| 190 | 205 | #define UPF_DEAD ((__force upf_t) (1 << 30)) |
| 191 | 206 | #define UPF_IOREMAP ((__force upf_t) (1 << 31)) |
| 192 | 207 | |
| 193 | −#define UPF_CHANGE_MASK ((__force upf_t) (0x17fff)) | |
| 208 | +#define __UPF_CHANGE_MASK 0x17fff | |
| 209 | +#define UPF_CHANGE_MASK ((__force upf_t) __UPF_CHANGE_MASK) | |
| 194 | 210 | #define UPF_USR_MASK ((__force upf_t) (UPF_SPD_MASK|UPF_LOW_LATENCY)) |
| 195 | 211 | |
| 212 | +#if __UPF_CHANGE_MASK > ASYNC_FLAGS | |
| 213 | +#error Change mask not equivalent to userspace-visible bit defines | |
| 214 | +#endif | |
| 215 | + | |
| 196 | 216 | /* status must be updated while holding port lock */ |
| 197 | 217 | upstat_t status; |
| 198 | 218 | |
| @@ -214,6 +234,7 @@ struct uart_port { · 15 unmodified lines | ||
| 214 | 234 | unsigned char unused[2]; |
| 215 | 235 | struct attribute_group *attr_group; /* port specific attributes */ |
| 216 | 236 | const struct attribute_group **tty_groups; /* all attributes (serial core use only) */ |
| 237 | + struct serial_rs485 rs485; | |
| 217 | 238 | void *private_data; /* generic platform data pointer */ |
| 218 | 239 | }; |
| 219 | 240 | |
| @@ -367,7 +388,7 @@ static inline int uart_tx_stopped(struct uart_port *port) · 147 unmodified lines | ||
| 367 | 388 | |
| 368 | 389 | static inline bool uart_cts_enabled(struct uart_port *uport) |
| 369 | 390 | { |
| 370 | − return uport->status & UPSTAT_CTS_ENABLE; | |
| 391 | + return !!(uport->status & UPSTAT_CTS_ENABLE); | |
| 371 | 392 | } |
| 372 | 393 | |
| 373 | 394 | /* |
| @@ -284,7 +284,7 @@ struct tty_struct { · 283 unmodified lines | ||
| 284 | 284 | |
| 285 | 285 | #define N_TTY_BUF_SIZE 4096 |
| 286 | 286 | |
| 287 | − unsigned char closing:1; | |
| 287 | + int closing; | |
| 288 | 288 | unsigned char *write_buf; |
| 289 | 289 | int write_cnt; |
| 290 | 290 | /* If the tty has a pending do_SAK, queue it here - akpm */ |
| @@ -316,12 +316,10 @@ struct tty_file_private { · 25 unmodified lines | ||
| 316 | 316 | #define TTY_EXCLUSIVE 3 /* Exclusive open mode */ |
| 317 | 317 | #define TTY_DEBUG 4 /* Debugging */ |
| 318 | 318 | #define TTY_DO_WRITE_WAKEUP 5 /* Call write_wakeup after queuing new */ |
| 319 | −#define TTY_CLOSING 7 /* ->close() in progress */ | |
| 320 | 319 | #define TTY_LDISC_OPEN 11 /* Line discipline is open */ |
| 321 | 320 | #define TTY_PTY_LOCK 16 /* pty private */ |
| 322 | 321 | #define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */ |
| 323 | 322 | #define TTY_HUPPED 18 /* Post driver->hangup() */ |
| 324 | −#define TTY_HUPPING 21 /* ->hangup() in progress */ | |
| 325 | 323 | #define TTY_LDISC_HALTED 22 /* Line discipline is halted */ |
| 326 | 324 | |
| 327 | 325 | #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) |
| @@ -437,14 +435,13 @@ extern int is_ignored(int sig); · 109 unmodified lines | ||
| 437 | 435 | extern int tty_signal(int sig, struct tty_struct *tty); |
| 438 | 436 | extern void tty_hangup(struct tty_struct *tty); |
| 439 | 437 | extern void tty_vhangup(struct tty_struct *tty); |
| 440 | −extern void tty_unhangup(struct file *filp); | |
| 441 | 438 | extern int tty_hung_up_p(struct file *filp); |
| 442 | 439 | extern void do_SAK(struct tty_struct *tty); |
| 443 | 440 | extern void __do_SAK(struct tty_struct *tty); |
| 444 | 441 | extern void no_tty(void); |
| 445 | 442 | extern void tty_flush_to_ldisc(struct tty_struct *tty); |
| 446 | 443 | extern void tty_buffer_free_all(struct tty_port *port); |
| 447 | −extern void tty_buffer_flush(struct tty_struct *tty); | |
| 444 | +extern void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld); | |
| 448 | 445 | extern void tty_buffer_init(struct tty_port *port); |
| 449 | 446 | extern speed_t tty_termios_baud_rate(struct ktermios *termios); |
| 450 | 447 | extern speed_t tty_termios_input_baud_rate(struct ktermios *termios); |
| @@ -498,9 +495,6 @@ extern int tty_init_termios(struct tty_struct *tty); · 47 unmodified lines | ||
| 498 | 495 | extern int tty_standard_install(struct tty_driver *driver, |
| 499 | 496 | struct tty_struct *tty); |
| 500 | 497 | |
| 501 | −extern struct tty_struct *tty_pair_get_tty(struct tty_struct *tty); | |
| 502 | −extern struct tty_struct *tty_pair_get_pty(struct tty_struct *tty); | |
| 503 | − | |
| 504 | 498 | extern struct mutex tty_mutex; |
| 505 | 499 | extern spinlock_t tty_files_lock; |
| 506 | 500 | |
| @@ -562,7 +556,7 @@ extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc); · 55 unmodified lines | ||
| 562 | 556 | extern int tty_unregister_ldisc(int disc); |
| 563 | 557 | extern int tty_set_ldisc(struct tty_struct *tty, int ldisc); |
| 564 | 558 | extern int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty); |
| 565 | −extern void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty); | |
| 559 | +extern void tty_ldisc_release(struct tty_struct *tty); | |
| 566 | 560 | extern void tty_ldisc_init(struct tty_struct *tty); |
| 567 | 561 | extern void tty_ldisc_deinit(struct tty_struct *tty); |
| 568 | 562 | extern void tty_ldisc_begin(void); |
| @@ -623,14 +617,6 @@ extern int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, · 54 unmodified lines | ||
| 623 | 617 | extern long n_tty_compat_ioctl_helper(struct tty_struct *tty, struct file *file, |
| 624 | 618 | unsigned int cmd, unsigned long arg); |
| 625 | 619 | |
| 626 | −/* serial.c */ | |
| 627 | − | |
| 628 | −extern void serial_console_init(void); | |
| 629 | − | |
| 630 | −/* pcxx.c */ | |
| 631 | − | |
| 632 | −extern int pcxe_open(struct tty_struct *tty, struct file *filp); | |
| 633 | − | |
| 634 | 620 | /* vt.c */ |
| 635 | 621 | |
| 636 | 622 | extern int vt_ioctl(struct tty_struct *tty, |
| @@ -643,11 +629,9 @@ extern long vt_compat_ioctl(struct tty_struct *tty, · 6 unmodified lines | ||
| 643 | 629 | /* functions for preparation of BKL removal */ |
| 644 | 630 | extern void __lockfunc tty_lock(struct tty_struct *tty); |
| 645 | 631 | extern void __lockfunc tty_unlock(struct tty_struct *tty); |
| 646 | −extern void __lockfunc tty_lock_pair(struct tty_struct *tty, | |
| 647 | − struct tty_struct *tty2); | |
| 648 | −extern void __lockfunc tty_unlock_pair(struct tty_struct *tty, | |
| 649 | − struct tty_struct *tty2); | |
| 650 | − | |
| 632 | +extern void __lockfunc tty_lock_slave(struct tty_struct *tty); | |
| 633 | +extern void __lockfunc tty_unlock_slave(struct tty_struct *tty); | |
| 634 | +extern void tty_set_lock_subclass(struct tty_struct *tty); | |
| 651 | 635 | /* |
| 652 | 636 | * this shall be called only from where BTM is held (like close) |
| 653 | 637 | * |
| @@ -54,7 +54,8 @@ · 53 unmodified lines | ||
| 54 | 54 | #define PORT_ALTR_16550_F32 26 /* Altera 16550 UART with 32 FIFOs */ |
| 55 | 55 | #define PORT_ALTR_16550_F64 27 /* Altera 16550 UART with 64 FIFOs */ |
| 56 | 56 | #define PORT_ALTR_16550_F128 28 /* Altera 16550 UART with 128 FIFOs */ |
| 57 | −#define PORT_MAX_8250 28 /* max port ID */ | |
| 57 | +#define PORT_RT2880 29 /* Ralink RT2880 internal UART */ | |
| 58 | +#define PORT_MAX_8250 29 /* max port ID */ | |
| 58 | 59 | |
| 59 | 60 | /* |
| 60 | 61 | * ARM specific type numbers. These are not currently guaranteed |
| @@ -359,6 +359,7 @@ · 358 unmodified lines | ||
| 359 | 359 | #define UART_OMAP_SYSC 0x15 /* System configuration register */ |
| 360 | 360 | #define UART_OMAP_SYSS 0x16 /* System status register */ |
| 361 | 361 | #define UART_OMAP_WER 0x17 /* Wake-up enable register */ |
| 362 | +#define UART_OMAP_TX_LVL 0x1a /* TX FIFO level register */ | |
| 362 | 363 | |
| 363 | 364 | /* |
| 364 | 365 | * These are the definitions for the MDR1 register |
| @@ -6,27 +6,31 @@ · 5 unmodified lines | ||
| 6 | 6 | * shared by the tty_port flags structures. |
| 7 | 7 | * |
| 8 | 8 | * Define ASYNCB_* for convenient use with {test,set,clear}_bit. |
| 9 | + * | |
| 10 | + * Bits [0..ASYNCB_LAST_USER] are userspace defined/visible/changeable | |
| 11 | + * [x] in the bit comments indicates the flag is defunct and no longer used. | |
| 9 | 12 | */ |
| 10 | 13 | #define ASYNCB_HUP_NOTIFY 0 /* Notify getty on hangups and closes |
| 11 | 14 | * on the callout port */ |
| 12 | 15 | #define ASYNCB_FOURPORT 1 /* Set OU1, OUT2 per AST Fourport settings */ |
| 13 | 16 | #define ASYNCB_SAK 2 /* Secure Attention Key (Orange book) */ |
| 14 | −#define ASYNCB_SPLIT_TERMIOS 3 /* Separate termios for dialin/callout */ | |
| 17 | +#define ASYNCB_SPLIT_TERMIOS 3 /* [x] Separate termios for dialin/callout */ | |
| 15 | 18 | #define ASYNCB_SPD_HI 4 /* Use 56000 instead of 38400 bps */ |
| 16 | 19 | #define ASYNCB_SPD_VHI 5 /* Use 115200 instead of 38400 bps */ |
| 17 | 20 | #define ASYNCB_SKIP_TEST 6 /* Skip UART test during autoconfiguration */ |
| 18 | 21 | #define ASYNCB_AUTO_IRQ 7 /* Do automatic IRQ during |
| 19 | 22 | * autoconfiguration */ |
| 20 | −#define ASYNCB_SESSION_LOCKOUT 8 /* Lock out cua opens based on session */ | |
| 21 | −#define ASYNCB_PGRP_LOCKOUT 9 /* Lock out cua opens based on pgrp */ | |
| 22 | −#define ASYNCB_CALLOUT_NOHUP 10 /* Don't do hangups for cua device */ | |
| 23 | +#define ASYNCB_SESSION_LOCKOUT 8 /* [x] Lock out cua opens based on session */ | |
| 24 | +#define ASYNCB_PGRP_LOCKOUT 9 /* [x] Lock out cua opens based on pgrp */ | |
| 25 | +#define ASYNCB_CALLOUT_NOHUP 10 /* [x] Don't do hangups for cua device */ | |
| 23 | 26 | #define ASYNCB_HARDPPS_CD 11 /* Call hardpps when CD goes high */ |
| 24 | 27 | #define ASYNCB_SPD_SHI 12 /* Use 230400 instead of 38400 bps */ |
| 25 | 28 | #define ASYNCB_LOW_LATENCY 13 /* Request low latency behaviour */ |
| 26 | 29 | #define ASYNCB_BUGGY_UART 14 /* This is a buggy UART, skip some safety |
| 27 | 30 | * checks. Note: can be dangerous! */ |
| 28 | −#define ASYNCB_AUTOPROBE 15 /* Port was autoprobed by PCI or PNP code */ | |
| 29 | −#define ASYNCB_LAST_USER 15 | |
| 31 | +#define ASYNCB_AUTOPROBE 15 /* [x] Port was autoprobed by PCI/PNP code */ | |
| 32 | +#define ASYNCB_MAGIC_MULTIPLIER 16 /* Use special CLK or divisor */ | |
| 33 | +#define ASYNCB_LAST_USER 16 | |
| 30 | 34 | |
| 31 | 35 | /* Internal flags used only by kernel */ |
| 32 | 36 | #define ASYNCB_INITIALIZED 31 /* Serial port was initialized */ |
| @@ -57,8 +61,11 @@ · 24 unmodified lines | ||
| 57 | 61 | #define ASYNC_LOW_LATENCY (1U << ASYNCB_LOW_LATENCY) |
| 58 | 62 | #define ASYNC_BUGGY_UART (1U << ASYNCB_BUGGY_UART) |
| 59 | 63 | #define ASYNC_AUTOPROBE (1U << ASYNCB_AUTOPROBE) |
| 64 | +#define ASYNC_MAGIC_MULTIPLIER (1U << ASYNCB_MAGIC_MULTIPLIER) | |
| 60 | 65 | |
| 61 | 66 | #define ASYNC_FLAGS ((1U << (ASYNCB_LAST_USER + 1)) - 1) |
| 67 | +#define ASYNC_DEPRECATED (ASYNC_SESSION_LOCKOUT | ASYNC_PGRP_LOCKOUT | \ | |
| 68 | + ASYNC_CALLOUT_NOHUP | ASYNC_AUTOPROBE) | |
| 62 | 69 | #define ASYNC_USR_MASK (ASYNC_SPD_MASK|ASYNC_CALLOUT_NOHUP| \ |
| 63 | 70 | ASYNC_LOW_LATENCY) |
| 64 | 71 | #define ASYNC_SPD_CUST (ASYNC_SPD_HI|ASYNC_SPD_VHI) |
| @@ -84,7 +84,4 @@ struct vt_setactivate { · 83 unmodified lines | ||
| 84 | 84 | |
| 85 | 85 | #define VT_SETACTIVATE 0x560F /* Activate and set the mode of a console */ |
| 86 | 86 | |
| 87 | − | |
| 88 | −#define vt_get_kmsg_redirect() vt_kmsg_redirect(-1) | |
| 89 | − | |
| 90 | 87 | #endif /* _UAPI_LINUX_VT_H */ |
| @@ -211,27 +211,6 @@ repeat: · 210 unmodified lines | ||
| 211 | 211 | goto repeat; |
| 212 | 212 | } |
| 213 | 213 | |
| 214 | −/* | |
| 215 | − * This checks not only the pgrp, but falls back on the pid if no | |
| 216 | − * satisfactory pgrp is found. I dunno - gdb doesn't work correctly | |
| 217 | − * without this... | |
| 218 | − * | |
| 219 | − * The caller must hold rcu lock or the tasklist lock. | |
| 220 | − */ | |
| 221 | −struct pid *session_of_pgrp(struct pid *pgrp) | |
| 222 | −{ | |
| 223 | − struct task_struct *p; | |
| 224 | − struct pid *sid = NULL; | |
| 225 | − | |
| 226 | − p = pid_task(pgrp, PIDTYPE_PGID); | |
| 227 | − if (p == NULL) | |
| 228 | − p = pid_task(pgrp, PIDTYPE_PID); | |
| 229 | − if (p != NULL) | |
| 230 | − sid = task_session(p); | |
| 231 | − | |
| 232 | − return sid; | |
| 233 | −} | |
| 234 | − | |
| 235 | 214 | /* |
| 236 | 215 | * Determine if a process group is "orphaned", according to the POSIX |
| 237 | 216 | * definition in 2.2.2.52. Orphaned process groups are not to be affected |