* 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (79 commits) TTY: serial_core: Fix crash if DCD drop during suspend tty/serial: atmel_serial: bootconsole removed from auto-enumerates Revert "TTY: call tty_driver_lookup_tty unconditionally" tty/serial: atmel_serial: add device tree support tty/serial: atmel_serial: auto-enumerate ports tty/serial: atmel_serial: whitespace and braces modifications tty/serial: atmel_serial: change platform_data variable name tty/serial: RS485 bindings for device tree TTY: call tty_driver_lookup_tty unconditionally TTY: pty, release tty in all ptmx_open fail paths TTY: make tty_add_file non-failing TTY: drop driver reference in tty_open fail path 8250_pci: Fix kernel panic when pch_uart is disabled h8300: drivers/serial/Kconfig was moved parport_pc: release IO region properly if unsupported ITE887x card is found tty: Support compat_ioctl get/set termios_locked hvc_console: display printk messages on console. TTY: snyclinkmp: forever loop in tx_load_dma_buffer() tty/n_gsm: avoid fifo overflow in gsm_dlci_data_output tty/n_gsm: fix a bug in gsm_dlci_data_output (adaption = 2 case) ... Fix up Conflicts in: - drivers/tty/serial/8250_pci.c Trivial conflict with removed duplicate device ID - drivers/tty/serial/atmel_serial.c Annoying silly conflict between "specify the port num via platform_data" and other changes to atmel_console_init
Unified · Split
| @@ -0,0 +1,31 @@ | |||
| 1 | * RS485 serial communications | ||
| 2 | |||
| 3 | The RTS signal is capable of automatically controlling line direction for | ||
| 4 | the built-in half-duplex mode. | ||
| 5 | The properties described hereafter shall be given to a half-duplex capable | ||
| 6 | UART node. | ||
| 7 | |||
| 8 | Required properties: | ||
| 9 | - rs485-rts-delay: prop-encoded-array <a b> where: | ||
| 10 | * a is the delay beteween rts signal and beginning of data sent in milliseconds. | ||
| 11 | it corresponds to the delay before sending data. | ||
| 12 | * b is the delay between end of data sent and rts signal in milliseconds | ||
| 13 | it corresponds to the delay after sending data and actual release of the line. | ||
| 14 | |||
| 15 | Optional properties: | ||
| 16 | - linux,rs485-enabled-at-boot-time: empty property telling to enable the rs485 | ||
| 17 | feature at boot time. It can be disabled later with proper ioctl. | ||
| 18 | - rs485-rx-during-tx: empty property that enables the receiving of data even | ||
| 19 | whilst sending data. | ||
| 20 | |||
| 21 | RS485 example for Atmel USART: | ||
| 22 | usart0: serial@fff8c000 { | ||
| 23 | compatible = "atmel,at91sam9260-usart"; | ||
| 24 | reg = <0xfff8c000 0x4000>; | ||
| 25 | interrupts = <7>; | ||
| 26 | atmel,use-dma-rx; | ||
| 27 | atmel,use-dma-tx; | ||
| 28 | linux,rs485-enabled-at-boot-time; | ||
| 29 | rs485-rts-delay = <0 200>; // in milliseconds | ||
| 30 | }; | ||
| 31 | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | * Atmel Universal Synchronous Asynchronous Receiver/Transmitter (USART) | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible: Should be "atmel,<chip>-usart" | ||
| 5 | The compatible <chip> indicated will be the first SoC to support an | ||
| 6 | additional mode or an USART new feature. | ||
| 7 | - reg: Should contain registers location and length | ||
| 8 | - interrupts: Should contain interrupt | ||
| 9 | |||
| 10 | Optional properties: | ||
| 11 | - atmel,use-dma-rx: use of PDC or DMA for receiving data | ||
| 12 | - atmel,use-dma-tx: use of PDC or DMA for transmitting data | ||
| 13 | |||
| 14 | <chip> compatible description: | ||
| 15 | - at91rm9200: legacy USART support | ||
| 16 | - at91sam9260: generic USART implementation for SAM9 SoCs | ||
| 17 | |||
| 18 | Example: | ||
| 19 | |||
| 20 | usart0: serial@fff8c000 { | ||
| 21 | compatible = "atmel,at91sam9260-usart"; | ||
| 22 | reg = <0xfff8c000 0x4000>; | ||
| 23 | interrupts = <7>; | ||
| 24 | atmel,use-dma-rx; | ||
| 25 | atmel,use-dma-tx; | ||
| 26 | }; | ||
| 27 | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | * Synopsys DesignWare ABP UART | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible : "snps,dw-apb-uart" | ||
| 5 | - reg : offset and length of the register set for the device. | ||
| 6 | - interrupts : should contain uart interrupt. | ||
| 7 | - clock-frequency : the input clock frequency for the UART. | ||
| 8 | |||
| 9 | Optional properties: | ||
| 10 | - reg-shift : quantity to shift the register offsets by. If this property is | ||
| 11 | not present then the register offsets are not shifted. | ||
| 12 | - reg-io-width : the size (in bytes) of the IO accesses that should be | ||
| 13 | performed on the device. If this property is not present then single byte | ||
| 14 | accesses are used. | ||
| 15 | |||
| 16 | Example: | ||
| 17 | |||
| 18 | uart@80230000 { | ||
| 19 | compatible = "snps,dw-apb-uart"; | ||
| 20 | reg = <0x80230000 0x100>; | ||
| 21 | clock-frequency = <3686400>; | ||
| 22 | interrupts = <10>; | ||
| 23 | reg-shift = <2>; | ||
| 24 | reg-io-width = <4>; | ||
| 25 | }; | ||
| @@ -28,6 +28,10 @@ · 27 unmodified lines | |||
| 28 | RS485 communications. This data structure is used to set and configure RS485 | 28 | RS485 communications. This data structure is used to set and configure RS485 |
| 29 | parameters in the platform data and in ioctls. | 29 | parameters in the platform data and in ioctls. |
| 30 | 30 | ||
| 31 | The device tree can also provide RS485 boot time parameters (see [2] | ||
| 32 | for bindings). The driver is in charge of filling this data structure from | ||
| 33 | the values given by the device tree. | ||
| 34 | |||
| 31 | Any driver for devices capable of working both as RS232 and RS485 should | 35 | Any driver for devices capable of working both as RS232 and RS485 should |
| 32 | provide at least the following ioctls: | 36 | provide at least the following ioctls: |
| 33 | 37 | ||
| @@ -104,6 +108,9 @@ · 70 unmodified lines | |||
| 104 | rs485conf.flags |= SER_RS485_RTS_AFTER_SEND; | 108 | rs485conf.flags |= SER_RS485_RTS_AFTER_SEND; |
| 105 | rs485conf.delay_rts_after_send = ...; | 109 | rs485conf.delay_rts_after_send = ...; |
| 106 | 110 | ||
| 111 | /* Set this flag if you want to receive data even whilst sending data */ | ||
| 112 | rs485conf.flags |= SER_RS485_RX_DURING_TX; | ||
| 113 | |||
| 107 | if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) { | 114 | if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) { |
| 108 | /* Error handling. See errno. */ | 115 | /* Error handling. See errno. */ |
| 109 | } | 116 | } |
| @@ -118,3 +125,4 @@ · 8 unmodified lines | |||
| 118 | 5. REFERENCES | 125 | 5. REFERENCES |
| 119 | 126 | ||
| 120 | [1] include/linux/serial.h | 127 | [1] include/linux/serial.h |
| 128 | [2] Documentation/devicetree/bindings/serial/rs485.txt | ||
| @@ -727,7 +727,6 @@ config ARCH_S3C64XX · 726 unmodified lines | |||
| 727 | select ARCH_REQUIRE_GPIOLIB | 727 | select ARCH_REQUIRE_GPIOLIB |
| 728 | select SAMSUNG_CLKSRC | 728 | select SAMSUNG_CLKSRC |
| 729 | select SAMSUNG_IRQ_VIC_TIMER | 729 | select SAMSUNG_IRQ_VIC_TIMER |
| 730 | select SAMSUNG_IRQ_UART | ||
| 731 | select S3C_GPIO_TRACK | 730 | select S3C_GPIO_TRACK |
| 732 | select S3C_GPIO_PULL_UPDOWN | 731 | select S3C_GPIO_PULL_UPDOWN |
| 733 | select S3C_GPIO_CFG_S3C24XX | 732 | select S3C_GPIO_CFG_S3C24XX |
| @@ -37,21 +37,10 @@ static struct resource s3c64xx_uart0_resource[] = { · 36 unmodified lines | |||
| 37 | .flags = IORESOURCE_MEM, | 37 | .flags = IORESOURCE_MEM, |
| 38 | }, | 38 | }, |
| 39 | [1] = { | 39 | [1] = { |
| 40 | .start = IRQ_S3CUART_RX0, | 40 | .start = IRQ_UART0, |
| 41 | .end = IRQ_S3CUART_RX0, | 41 | .end = IRQ_UART0, |
| 42 | .flags = IORESOURCE_IRQ, | 42 | .flags = IORESOURCE_IRQ, |
| 43 | }, | 43 | }, |
| 44 | [2] = { | ||
| 45 | .start = IRQ_S3CUART_TX0, | ||
| 46 | .end = IRQ_S3CUART_TX0, | ||
| 47 | .flags = IORESOURCE_IRQ, | ||
| 48 | |||
| 49 | }, | ||
| 50 | [3] = { | ||
| 51 | .start = IRQ_S3CUART_ERR0, | ||
| 52 | .end = IRQ_S3CUART_ERR0, | ||
| 53 | .flags = IORESOURCE_IRQ, | ||
| 54 | } | ||
| 55 | }; | 44 | }; |
| 56 | 45 | ||
| 57 | static struct resource s3c64xx_uart1_resource[] = { | 46 | static struct resource s3c64xx_uart1_resource[] = { |
| @@ -61,19 +50,8 @@ static struct resource s3c64xx_uart1_resource[] = { · 3 unmodified lines | |||
| 61 | .flags = IORESOURCE_MEM, | 50 | .flags = IORESOURCE_MEM, |
| 62 | }, | 51 | }, |
| 63 | [1] = { | 52 | [1] = { |
| 64 | .start = IRQ_S3CUART_RX1, | 53 | .start = IRQ_UART1, |
| 65 | .end = IRQ_S3CUART_RX1, | 54 | .end = IRQ_UART1, |
| 66 | .flags = IORESOURCE_IRQ, | ||
| 67 | }, | ||
| 68 | [2] = { | ||
| 69 | .start = IRQ_S3CUART_TX1, | ||
| 70 | .end = IRQ_S3CUART_TX1, | ||
| 71 | .flags = IORESOURCE_IRQ, | ||
| 72 | |||
| 73 | }, | ||
| 74 | [3] = { | ||
| 75 | .start = IRQ_S3CUART_ERR1, | ||
| 76 | .end = IRQ_S3CUART_ERR1, | ||
| 77 | .flags = IORESOURCE_IRQ, | 55 | .flags = IORESOURCE_IRQ, |
| 78 | }, | 56 | }, |
| 79 | }; | 57 | }; |
| @@ -85,19 +63,8 @@ static struct resource s3c6xx_uart2_resource[] = { · 5 unmodified lines | |||
| 85 | .flags = IORESOURCE_MEM, | 63 | .flags = IORESOURCE_MEM, |
| 86 | }, | 64 | }, |
| 87 | [1] = { | 65 | [1] = { |
| 88 | .start = IRQ_S3CUART_RX2, | 66 | .start = IRQ_UART2, |
| 89 | .end = IRQ_S3CUART_RX2, | 67 | .end = IRQ_UART2, |
| 90 | .flags = IORESOURCE_IRQ, | ||
| 91 | }, | ||
| 92 | [2] = { | ||
| 93 | .start = IRQ_S3CUART_TX2, | ||
| 94 | .end = IRQ_S3CUART_TX2, | ||
| 95 | .flags = IORESOURCE_IRQ, | ||
| 96 | |||
| 97 | }, | ||
| 98 | [3] = { | ||
| 99 | .start = IRQ_S3CUART_ERR2, | ||
| 100 | .end = IRQ_S3CUART_ERR2, | ||
| 101 | .flags = IORESOURCE_IRQ, | 68 | .flags = IORESOURCE_IRQ, |
| 102 | }, | 69 | }, |
| 103 | }; | 70 | }; |
| @@ -109,19 +76,8 @@ static struct resource s3c64xx_uart3_resource[] = { · 5 unmodified lines | |||
| 109 | .flags = IORESOURCE_MEM, | 76 | .flags = IORESOURCE_MEM, |
| 110 | }, | 77 | }, |
| 111 | [1] = { | 78 | [1] = { |
| 112 | .start = IRQ_S3CUART_RX3, | 79 | .start = IRQ_UART3, |
| 113 | .end = IRQ_S3CUART_RX3, | 80 | .end = IRQ_UART3, |
| 114 | .flags = IORESOURCE_IRQ, | ||
| 115 | }, | ||
| 116 | [2] = { | ||
| 117 | .start = IRQ_S3CUART_TX3, | ||
| 118 | .end = IRQ_S3CUART_TX3, | ||
| 119 | .flags = IORESOURCE_IRQ, | ||
| 120 | |||
| 121 | }, | ||
| 122 | [3] = { | ||
| 123 | .start = IRQ_S3CUART_ERR3, | ||
| 124 | .end = IRQ_S3CUART_ERR3, | ||
| 125 | .flags = IORESOURCE_IRQ, | 81 | .flags = IORESOURCE_IRQ, |
| 126 | }, | 82 | }, |
| 127 | }; | 83 | }; |
| @@ -27,36 +27,6 @@ · 26 unmodified lines | |||
| 27 | #define IRQ_VIC0_BASE S3C_IRQ(0) | 27 | #define IRQ_VIC0_BASE S3C_IRQ(0) |
| 28 | #define IRQ_VIC1_BASE S3C_IRQ(32) | 28 | #define IRQ_VIC1_BASE S3C_IRQ(32) |
| 29 | 29 | ||
| 30 | /* UART interrupts, each UART has 4 intterupts per channel so | ||
| 31 | * use the space between the ISA and S3C main interrupts. Note, these | ||
| 32 | * are not in the same order as the S3C24XX series! */ | ||
| 33 | |||
| 34 | #define IRQ_S3CUART_BASE0 (16) | ||
| 35 | #define IRQ_S3CUART_BASE1 (20) | ||
| 36 | #define IRQ_S3CUART_BASE2 (24) | ||
| 37 | #define IRQ_S3CUART_BASE3 (28) | ||
| 38 | |||
| 39 | #define UART_IRQ_RXD (0) | ||
| 40 | #define UART_IRQ_ERR (1) | ||
| 41 | #define UART_IRQ_TXD (2) | ||
| 42 | #define UART_IRQ_MODEM (3) | ||
| 43 | |||
| 44 | #define IRQ_S3CUART_RX0 (IRQ_S3CUART_BASE0 + UART_IRQ_RXD) | ||
| 45 | #define IRQ_S3CUART_TX0 (IRQ_S3CUART_BASE0 + UART_IRQ_TXD) | ||
| 46 | #define IRQ_S3CUART_ERR0 (IRQ_S3CUART_BASE0 + UART_IRQ_ERR) | ||
| 47 | |||
| 48 | #define IRQ_S3CUART_RX1 (IRQ_S3CUART_BASE1 + UART_IRQ_RXD) | ||
| 49 | #define IRQ_S3CUART_TX1 (IRQ_S3CUART_BASE1 + UART_IRQ_TXD) | ||
| 50 | #define IRQ_S3CUART_ERR1 (IRQ_S3CUART_BASE1 + UART_IRQ_ERR) | ||
| 51 | |||
| 52 | #define IRQ_S3CUART_RX2 (IRQ_S3CUART_BASE2 + UART_IRQ_RXD) | ||
| 53 | #define IRQ_S3CUART_TX2 (IRQ_S3CUART_BASE2 + UART_IRQ_TXD) | ||
| 54 | #define IRQ_S3CUART_ERR2 (IRQ_S3CUART_BASE2 + UART_IRQ_ERR) | ||
| 55 | |||
| 56 | #define IRQ_S3CUART_RX3 (IRQ_S3CUART_BASE3 + UART_IRQ_RXD) | ||
| 57 | #define IRQ_S3CUART_TX3 (IRQ_S3CUART_BASE3 + UART_IRQ_TXD) | ||
| 58 | #define IRQ_S3CUART_ERR3 (IRQ_S3CUART_BASE3 + UART_IRQ_ERR) | ||
| 59 | |||
| 60 | /* VIC based IRQs */ | 30 | /* VIC based IRQs */ |
| 61 | 31 | ||
| 62 | #define S3C64XX_IRQ_VIC0(x) (IRQ_VIC0_BASE + (x)) | 32 | #define S3C64XX_IRQ_VIC0(x) (IRQ_VIC0_BASE + (x)) |
| @@ -25,29 +25,6 @@ · 24 unmodified lines | |||
| 25 | #include <plat/irq-uart.h> | 25 | #include <plat/irq-uart.h> |
| 26 | #include <plat/cpu.h> | 26 | #include <plat/cpu.h> |
| 27 | 27 | ||
| 28 | static struct s3c_uart_irq uart_irqs[] = { | ||
| 29 | [0] = { | ||
| 30 | .regs = S3C_VA_UART0, | ||
| 31 | .base_irq = IRQ_S3CUART_BASE0, | ||
| 32 | .parent_irq = IRQ_UART0, | ||
| 33 | }, | ||
| 34 | [1] = { | ||
| 35 | .regs = S3C_VA_UART1, | ||
| 36 | .base_irq = IRQ_S3CUART_BASE1, | ||
| 37 | .parent_irq = IRQ_UART1, | ||
| 38 | }, | ||
| 39 | [2] = { | ||
| 40 | .regs = S3C_VA_UART2, | ||
| 41 | .base_irq = IRQ_S3CUART_BASE2, | ||
| 42 | .parent_irq = IRQ_UART2, | ||
| 43 | }, | ||
| 44 | [3] = { | ||
| 45 | .regs = S3C_VA_UART3, | ||
| 46 | .base_irq = IRQ_S3CUART_BASE3, | ||
| 47 | .parent_irq = IRQ_UART3, | ||
| 48 | }, | ||
| 49 | }; | ||
| 50 | |||
| 51 | /* setup the sources the vic should advertise resume for, even though it | 28 | /* setup the sources the vic should advertise resume for, even though it |
| 52 | * is not doing the wake (set_irq_wake needs to be valid) */ | 29 | * is not doing the wake (set_irq_wake needs to be valid) */ |
| 53 | #define IRQ_VIC0_RESUME (1 << (IRQ_RTC_TIC - IRQ_VIC0_BASE)) | 30 | #define IRQ_VIC0_RESUME (1 << (IRQ_RTC_TIC - IRQ_VIC0_BASE)) |
| @@ -67,6 +44,4 @@ void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid) · 13 unmodified lines | |||
| 67 | 44 | ||
| 68 | /* add the timer sub-irqs */ | 45 | /* add the timer sub-irqs */ |
| 69 | s3c_init_vic_timer_irq(5, IRQ_TIMER0); | 46 | s3c_init_vic_timer_irq(5, IRQ_TIMER0); |
| 70 | |||
| 71 | s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs)); | ||
| 72 | } | 47 | } |
| @@ -22,7 +22,6 @@ config PLAT_S5P · 21 unmodified lines | |||
| 22 | select PLAT_SAMSUNG | 22 | select PLAT_SAMSUNG |
| 23 | select SAMSUNG_CLKSRC | 23 | select SAMSUNG_CLKSRC |
| 24 | select SAMSUNG_IRQ_VIC_TIMER | 24 | select SAMSUNG_IRQ_VIC_TIMER |
| 25 | select SAMSUNG_IRQ_UART | ||
| 26 | help | 25 | help |
| 27 | Base platform code for Samsung's S5P series SoC. | 26 | Base platform code for Samsung's S5P series SoC. |
| 28 | 27 | ||
| @@ -32,20 +32,10 @@ static struct resource s5p_uart0_resource[] = { · 31 unmodified lines | |||
| 32 | .flags = IORESOURCE_MEM, | 32 | .flags = IORESOURCE_MEM, |
| 33 | }, | 33 | }, |
| 34 | [1] = { | 34 | [1] = { |
| 35 | .start = IRQ_S5P_UART_RX0, | 35 | .start = IRQ_UART0, |
| 36 | .end = IRQ_S5P_UART_RX0, | 36 | .end = IRQ_UART0, |
| 37 | .flags = IORESOURCE_IRQ, | 37 | .flags = IORESOURCE_IRQ, |
| 38 | }, | 38 | }, |
| 39 | [2] = { | ||
| 40 | .start = IRQ_S5P_UART_TX0, | ||
| 41 | .end = IRQ_S5P_UART_TX0, | ||
| 42 | .flags = IORESOURCE_IRQ, | ||
| 43 | }, | ||
| 44 | [3] = { | ||
| 45 | .start = IRQ_S5P_UART_ERR0, | ||
| 46 | .end = IRQ_S5P_UART_ERR0, | ||
| 47 | .flags = IORESOURCE_IRQ, | ||
| 48 | } | ||
| 49 | }; | 39 | }; |
| 50 | 40 | ||
| 51 | static struct resource s5p_uart1_resource[] = { | 41 | static struct resource s5p_uart1_resource[] = { |
| @@ -55,18 +45,8 @@ static struct resource s5p_uart1_resource[] = { · 3 unmodified lines | |||
| 55 | .flags = IORESOURCE_MEM, | 45 | .flags = IORESOURCE_MEM, |
| 56 | }, | 46 | }, |
| 57 | [1] = { | 47 | [1] = { |
| 58 | .start = IRQ_S5P_UART_RX1, | 48 | .start = IRQ_UART1, |
| 59 | .end = IRQ_S5P_UART_RX1, | 49 | .end = IRQ_UART1, |
| 60 | .flags = IORESOURCE_IRQ, | ||
| 61 | }, | ||
| 62 | [2] = { | ||
| 63 | .start = IRQ_S5P_UART_TX1, | ||
| 64 | .end = IRQ_S5P_UART_TX1, | ||
| 65 | .flags = IORESOURCE_IRQ, | ||
| 66 | }, | ||
| 67 | [3] = { | ||
| 68 | .start = IRQ_S5P_UART_ERR1, | ||
| 69 | .end = IRQ_S5P_UART_ERR1, | ||
| 70 | .flags = IORESOURCE_IRQ, | 50 | .flags = IORESOURCE_IRQ, |
| 71 | }, | 51 | }, |
| 72 | }; | 52 | }; |
| @@ -78,18 +58,8 @@ static struct resource s5p_uart2_resource[] = { · 5 unmodified lines | |||
| 78 | .flags = IORESOURCE_MEM, | 58 | .flags = IORESOURCE_MEM, |
| 79 | }, | 59 | }, |
| 80 | [1] = { | 60 | [1] = { |
| 81 | .start = IRQ_S5P_UART_RX2, | 61 | .start = IRQ_UART2, |
| 82 | .end = IRQ_S5P_UART_RX2, | 62 | .end = IRQ_UART2, |
| 83 | .flags = IORESOURCE_IRQ, | ||
| 84 | }, | ||
| 85 | [2] = { | ||
| 86 | .start = IRQ_S5P_UART_TX2, | ||
| 87 | .end = IRQ_S5P_UART_TX2, | ||
| 88 | .flags = IORESOURCE_IRQ, | ||
| 89 | }, | ||
| 90 | [3] = { | ||
| 91 | .start = IRQ_S5P_UART_ERR2, | ||
| 92 | .end = IRQ_S5P_UART_ERR2, | ||
| 93 | .flags = IORESOURCE_IRQ, | 63 | .flags = IORESOURCE_IRQ, |
| 94 | }, | 64 | }, |
| 95 | }; | 65 | }; |
| @@ -102,18 +72,8 @@ static struct resource s5p_uart3_resource[] = { · 6 unmodified lines | |||
| 102 | .flags = IORESOURCE_MEM, | 72 | .flags = IORESOURCE_MEM, |
| 103 | }, | 73 | }, |
| 104 | [1] = { | 74 | [1] = { |
| 105 | .start = IRQ_S5P_UART_RX3, | 75 | .start = IRQ_UART3, |
| 106 | .end = IRQ_S5P_UART_RX3, | 76 | .end = IRQ_UART3, |
| 107 | .flags = IORESOURCE_IRQ, | ||
| 108 | }, | ||
| 109 | [2] = { | ||
| 110 | .start = IRQ_S5P_UART_TX3, | ||
| 111 | .end = IRQ_S5P_UART_TX3, | ||
| 112 | .flags = IORESOURCE_IRQ, | ||
| 113 | }, | ||
| 114 | [3] = { | ||
| 115 | .start = IRQ_S5P_UART_ERR3, | ||
| 116 | .end = IRQ_S5P_UART_ERR3, | ||
| 117 | .flags = IORESOURCE_IRQ, | 77 | .flags = IORESOURCE_IRQ, |
| 118 | }, | 78 | }, |
| 119 | #endif | 79 | #endif |
| @@ -127,18 +87,8 @@ static struct resource s5p_uart4_resource[] = { · 7 unmodified lines | |||
| 127 | .flags = IORESOURCE_MEM, | 87 | .flags = IORESOURCE_MEM, |
| 128 | }, | 88 | }, |
| 129 | [1] = { | 89 | [1] = { |
| 130 | .start = IRQ_S5P_UART_RX4, | 90 | .start = IRQ_UART4, |
| 131 | .end = IRQ_S5P_UART_RX4, | 91 | .end = IRQ_UART4, |
| 132 | .flags = IORESOURCE_IRQ, | ||
| 133 | }, | ||
| 134 | [2] = { | ||
| 135 | .start = IRQ_S5P_UART_TX4, | ||
| 136 | .end = IRQ_S5P_UART_TX4, | ||
| 137 | .flags = IORESOURCE_IRQ, | ||
| 138 | }, | ||
| 139 | [3] = { | ||
| 140 | .start = IRQ_S5P_UART_ERR4, | ||
| 141 | .end = IRQ_S5P_UART_ERR4, | ||
| 142 | .flags = IORESOURCE_IRQ, | 92 | .flags = IORESOURCE_IRQ, |
| 143 | }, | 93 | }, |
| 144 | #endif | 94 | #endif |
| @@ -152,18 +102,8 @@ static struct resource s5p_uart5_resource[] = { · 7 unmodified lines | |||
| 152 | .flags = IORESOURCE_MEM, | 102 | .flags = IORESOURCE_MEM, |
| 153 | }, | 103 | }, |
| 154 | [1] = { | 104 | [1] = { |
| 155 | .start = IRQ_S5P_UART_RX5, | 105 | .start = IRQ_UART5, |
| 156 | .end = IRQ_S5P_UART_RX5, | 106 | .end = IRQ_UART5, |
| 157 | .flags = IORESOURCE_IRQ, | ||
| 158 | }, | ||
| 159 | [2] = { | ||
| 160 | .start = IRQ_S5P_UART_TX5, | ||
| 161 | .end = IRQ_S5P_UART_TX5, | ||
| 162 | .flags = IORESOURCE_IRQ, | ||
| 163 | }, | ||
| 164 | [3] = { | ||
| 165 | .start = IRQ_S5P_UART_ERR5, | ||
| 166 | .end = IRQ_S5P_UART_ERR5, | ||
| 167 | .flags = IORESOURCE_IRQ, | 107 | .flags = IORESOURCE_IRQ, |
| 168 | }, | 108 | }, |
| 169 | #endif | 109 | #endif |
| @@ -37,41 +37,6 @@ · 36 unmodified lines | |||
| 37 | #define IRQ_VIC1_BASE S5P_VIC1_BASE | 37 | #define IRQ_VIC1_BASE S5P_VIC1_BASE |
| 38 | #define IRQ_VIC2_BASE S5P_VIC2_BASE | 38 | #define IRQ_VIC2_BASE S5P_VIC2_BASE |
| 39 | 39 | ||
| 40 | /* UART interrupts, each UART has 4 intterupts per channel so | ||
| 41 | * use the space between the ISA and S3C main interrupts. Note, these | ||
| 42 | * are not in the same order as the S3C24XX series! */ | ||
| 43 | |||
| 44 | #define IRQ_S5P_UART_BASE0 (16) | ||
| 45 | #define IRQ_S5P_UART_BASE1 (20) | ||
| 46 | #define IRQ_S5P_UART_BASE2 (24) | ||
| 47 | #define IRQ_S5P_UART_BASE3 (28) | ||
| 48 | |||
| 49 | #define UART_IRQ_RXD (0) | ||
| 50 | #define UART_IRQ_ERR (1) | ||
| 51 | #define UART_IRQ_TXD (2) | ||
| 52 | |||
| 53 | #define IRQ_S5P_UART_RX0 (IRQ_S5P_UART_BASE0 + UART_IRQ_RXD) | ||
| 54 | #define IRQ_S5P_UART_TX0 (IRQ_S5P_UART_BASE0 + UART_IRQ_TXD) | ||
| 55 | #define IRQ_S5P_UART_ERR0 (IRQ_S5P_UART_BASE0 + UART_IRQ_ERR) | ||
| 56 | |||
| 57 | #define IRQ_S5P_UART_RX1 (IRQ_S5P_UART_BASE1 + UART_IRQ_RXD) | ||
| 58 | #define IRQ_S5P_UART_TX1 (IRQ_S5P_UART_BASE1 + UART_IRQ_TXD) | ||
| 59 | #define IRQ_S5P_UART_ERR1 (IRQ_S5P_UART_BASE1 + UART_IRQ_ERR) | ||
| 60 | |||
| 61 | #define IRQ_S5P_UART_RX2 (IRQ_S5P_UART_BASE2 + UART_IRQ_RXD) | ||
| 62 | #define IRQ_S5P_UART_TX2 (IRQ_S5P_UART_BASE2 + UART_IRQ_TXD) | ||
| 63 | #define IRQ_S5P_UART_ERR2 (IRQ_S5P_UART_BASE2 + UART_IRQ_ERR) | ||
| 64 | |||
| 65 | #define IRQ_S5P_UART_RX3 (IRQ_S5P_UART_BASE3 + UART_IRQ_RXD) | ||
| 66 | #define IRQ_S5P_UART_TX3 (IRQ_S5P_UART_BASE3 + UART_IRQ_TXD) | ||
| 67 | #define IRQ_S5P_UART_ERR3 (IRQ_S5P_UART_BASE3 + UART_IRQ_ERR) | ||
| 68 | |||
| 69 | /* S3C compatibilty defines */ | ||
| 70 | #define IRQ_S3CUART_RX0 IRQ_S5P_UART_RX0 | ||
| 71 | #define IRQ_S3CUART_RX1 IRQ_S5P_UART_RX1 | ||
| 72 | #define IRQ_S3CUART_RX2 IRQ_S5P_UART_RX2 | ||
| 73 | #define IRQ_S3CUART_RX3 IRQ_S5P_UART_RX3 | ||
| 74 | |||
| 75 | /* VIC based IRQs */ | 40 | /* VIC based IRQs */ |
| 76 | 41 | ||
| 77 | #define S5P_IRQ_VIC0(x) (S5P_VIC0_BASE + (x)) | 42 | #define S5P_IRQ_VIC0(x) (S5P_VIC0_BASE + (x)) |
| @@ -17,42 +17,10 @@ · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | #include <asm/hardware/vic.h> | 18 | #include <asm/hardware/vic.h> |
| 19 | 19 | ||
| 20 | #include <linux/serial_core.h> | ||
| 21 | #include <mach/map.h> | 20 | #include <mach/map.h> |
| 22 | #include <plat/regs-timer.h> | 21 | #include <plat/regs-timer.h> |
| 23 | #include <plat/regs-serial.h> | ||
| 24 | #include <plat/cpu.h> | 22 | #include <plat/cpu.h> |
| 25 | #include <plat/irq-vic-timer.h> | 23 | #include <plat/irq-vic-timer.h> |
| 26 | #include <plat/irq-uart.h> | ||
| 27 | |||
| 28 | /* | ||
| 29 | * Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3] | ||
| 30 | * are consecutive when looking up the interrupt in the demux routines. | ||
| 31 | */ | ||
| 32 | static struct s3c_uart_irq uart_irqs[] = { | ||
| 33 | [0] = { | ||
| 34 | .regs = S5P_VA_UART0, | ||
| 35 | .base_irq = IRQ_S5P_UART_BASE0, | ||
| 36 | .parent_irq = IRQ_UART0, | ||
| 37 | }, | ||
| 38 | [1] = { | ||
| 39 | .regs = S5P_VA_UART1, | ||
| 40 | .base_irq = IRQ_S5P_UART_BASE1, | ||
| 41 | .parent_irq = IRQ_UART1, | ||
| 42 | }, | ||
| 43 | [2] = { | ||
| 44 | .regs = S5P_VA_UART2, | ||
| 45 | .base_irq = IRQ_S5P_UART_BASE2, | ||
| 46 | .parent_irq = IRQ_UART2, | ||
| 47 | }, | ||
| 48 | #if CONFIG_SERIAL_SAMSUNG_UARTS > 3 | ||
| 49 | [3] = { | ||
| 50 | .regs = S5P_VA_UART3, | ||
| 51 | .base_irq = IRQ_S5P_UART_BASE3, | ||
| 52 | .parent_irq = IRQ_UART3, | ||
| 53 | }, | ||
| 54 | #endif | ||
| 55 | }; | ||
| 56 | 24 | ||
| 57 | void __init s5p_init_irq(u32 *vic, u32 num_vic) | 25 | void __init s5p_init_irq(u32 *vic, u32 num_vic) |
| 58 | { | 26 | { |
| @@ -65,6 +33,4 @@ void __init s5p_init_irq(u32 *vic, u32 num_vic) · 6 unmodified lines | |||
| 65 | #endif | 33 | #endif |
| 66 | 34 | ||
| 67 | s3c_init_vic_timer_irq(5, IRQ_TIMER0); | 35 | s3c_init_vic_timer_irq(5, IRQ_TIMER0); |
| 68 | |||
| 69 | s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs)); | ||
| 70 | } | 36 | } |
| @@ -65,11 +65,6 @@ config SAMSUNG_IRQ_VIC_TIMER · 64 unmodified lines | |||
| 65 | help | 65 | help |
| 66 | Internal configuration to build the VIC timer interrupt code. | 66 | Internal configuration to build the VIC timer interrupt code. |
| 67 | 67 | ||
| 68 | config SAMSUNG_IRQ_UART | ||
| 69 | bool | ||
| 70 | help | ||
| 71 | Internal configuration to build the IRQ UART demux code. | ||
| 72 | |||
| 73 | # options for gpio configuration support | 68 | # options for gpio configuration support |
| 74 | 69 | ||
| 75 | config SAMSUNG_GPIOLIB_4BIT | 70 | config SAMSUNG_GPIOLIB_4BIT |
| @@ -21,7 +21,6 @@ obj-y += dev-asocdma.o · 20 unmodified lines | |||
| 21 | 21 | ||
| 22 | obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o | 22 | obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o |
| 23 | 23 | ||
| 24 | obj-$(CONFIG_SAMSUNG_IRQ_UART) += irq-uart.o | ||
| 25 | obj-$(CONFIG_SAMSUNG_IRQ_VIC_TIMER) += irq-vic-timer.o | 24 | obj-$(CONFIG_SAMSUNG_IRQ_VIC_TIMER) += irq-vic-timer.o |
| 26 | 25 | ||
| 27 | # ADC | 26 | # ADC |
| @@ -186,6 +186,11 @@ · 185 unmodified lines | |||
| 186 | #define S3C64XX_UINTSP 0x34 | 186 | #define S3C64XX_UINTSP 0x34 |
| 187 | #define S3C64XX_UINTM 0x38 | 187 | #define S3C64XX_UINTM 0x38 |
| 188 | 188 | ||
| 189 | #define S3C64XX_UINTM_RXD (0) | ||
| 190 | #define S3C64XX_UINTM_TXD (2) | ||
| 191 | #define S3C64XX_UINTM_RXD_MSK (1 << S3C64XX_UINTM_RXD) | ||
| 192 | #define S3C64XX_UINTM_TXD_MSK (1 << S3C64XX_UINTM_TXD) | ||
| 193 | |||
| 189 | /* Following are specific to S5PV210 */ | 194 | /* Following are specific to S5PV210 */ |
| 190 | #define S5PV210_UCON_CLKMASK (1<<10) | 195 | #define S5PV210_UCON_CLKMASK (1<<10) |
| 191 | #define S5PV210_UCON_PCLK (0<<10) | 196 | #define S5PV210_UCON_PCLK (0<<10) |
| @@ -1,96 +0,0 @@ | |||
| 1 | /* arch/arm/plat-samsung/irq-uart.c | ||
| 2 | * originally part of arch/arm/plat-s3c64xx/irq.c | ||
| 3 | * | ||
| 4 | * Copyright 2008 Openmoko, Inc. | ||
| 5 | * Copyright 2008 Simtec Electronics | ||
| 6 | * Ben Dooks <ben@simtec.co.uk> | ||
| 7 | * http://armlinux.simtec.co.uk/ | ||
| 8 | * | ||
| 9 | * Samsung- UART Interrupt handling | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License version 2 as | ||
| 13 | * published by the Free Software Foundation. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/interrupt.h> | ||
| 18 | #include <linux/serial_core.h> | ||
| 19 | #include <linux/irq.h> | ||
| 20 | #include <linux/io.h> | ||
| 21 | |||
| 22 | #include <asm/mach/irq.h> | ||
| 23 | |||
| 24 | #include <mach/map.h> | ||
| 25 | #include <plat/irq-uart.h> | ||
| 26 | #include <plat/regs-serial.h> | ||
| 27 | #include <plat/cpu.h> | ||
| 28 | |||
| 29 | /* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3] | ||
| 30 | * are consecutive when looking up the interrupt in the demux routines. | ||
| 31 | */ | ||
| 32 | static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc) | ||
| 33 | { | ||
| 34 | struct s3c_uart_irq *uirq = desc->irq_data.handler_data; | ||
| 35 | struct irq_chip *chip = irq_get_chip(irq); | ||
| 36 | u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP); | ||
| 37 | int base = uirq->base_irq; | ||
| 38 | |||
| 39 | chained_irq_enter(chip, desc); | ||
| 40 | |||
| 41 | if (pend & (1 << 0)) | ||
| 42 | generic_handle_irq(base); | ||
| 43 | if (pend & (1 << 1)) | ||
| 44 | generic_handle_irq(base + 1); | ||
| 45 | if (pend & (1 << 2)) | ||
| 46 | generic_handle_irq(base + 2); | ||
| 47 | if (pend & (1 << 3)) | ||
| 48 | generic_handle_irq(base + 3); | ||
| 49 | |||
| 50 | chained_irq_exit(chip, desc); | ||
| 51 | } | ||
| 52 | |||
| 53 | static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq) | ||
| 54 | { | ||
| 55 | void __iomem *reg_base = uirq->regs; | ||
| 56 | struct irq_chip_generic *gc; | ||
| 57 | struct irq_chip_type *ct; | ||
| 58 | |||
| 59 | /* mask all interrupts at the start. */ | ||
| 60 | __raw_writel(0xf, reg_base + S3C64XX_UINTM); | ||
| 61 | |||
| 62 | gc = irq_alloc_generic_chip("s3c-uart", 1, uirq->base_irq, reg_base, | ||
| 63 | handle_level_irq); | ||
| 64 | |||
| 65 | if (!gc) { | ||
| 66 | pr_err("%s: irq_alloc_generic_chip for IRQ %u failed\n", | ||
| 67 | __func__, uirq->base_irq); | ||
| 68 | return; | ||
| 69 | } | ||
| 70 | |||
| 71 | ct = gc->chip_types; | ||
| 72 | ct->chip.irq_ack = irq_gc_ack_set_bit; | ||
| 73 | ct->chip.irq_mask = irq_gc_mask_set_bit; | ||
| 74 | ct->chip.irq_unmask = irq_gc_mask_clr_bit; | ||
| 75 | ct->regs.ack = S3C64XX_UINTP; | ||
| 76 | ct->regs.mask = S3C64XX_UINTM; | ||
| 77 | irq_setup_generic_chip(gc, IRQ_MSK(4), IRQ_GC_INIT_MASK_CACHE, | ||
| 78 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); | ||
| 79 | |||
| 80 | irq_set_handler_data(uirq->parent_irq, uirq); | ||
| 81 | irq_set_chained_handler(uirq->parent_irq, s3c_irq_demux_uart); | ||
| 82 | } | ||
| 83 | |||
| 84 | /** | ||
| 85 | * s3c_init_uart_irqs() - initialise UART IRQs and the necessary demuxing | ||
| 86 | * @irq: The interrupt data for registering | ||
| 87 | * @nr_irqs: The number of interrupt descriptions in @irq. | ||
| 88 | * | ||
| 89 | * Register the UART interrupts specified by @irq including the demuxing | ||
| 90 | * routines. This supports the S3C6400 and newer style of devices. | ||
| 91 | */ | ||
| 92 | void __init s3c_init_uart_irqs(struct s3c_uart_irq *irq, unsigned int nr_irqs) | ||
| 93 | { | ||
| 94 | for (; nr_irqs > 0; nr_irqs--, irq++) | ||
| 95 | s3c_init_uart_irq(irq); | ||
| 96 | } | ||
| @@ -195,7 +195,7 @@ config UNIX98_PTYS · 194 unmodified lines | |||
| 195 | 195 | ||
| 196 | source "drivers/char/pcmcia/Kconfig" | 196 | source "drivers/char/pcmcia/Kconfig" |
| 197 | 197 | ||
| 198 | source "drivers/serial/Kconfig" | 198 | source "drivers/tty/serial/Kconfig" |
| 199 | 199 | ||
| 200 | source "drivers/i2c/Kconfig" | 200 | source "drivers/i2c/Kconfig" |
| 201 | 201 | ||
| @@ -27,6 +27,7 @@ · 26 unmodified lines | |||
| 27 | #include <linux/serial.h> | 27 | #include <linux/serial.h> |
| 28 | #include <linux/serial_core.h> | 28 | #include <linux/serial_core.h> |
| 29 | #include <linux/serial_reg.h> | 29 | #include <linux/serial_reg.h> |
| 30 | #include <linux/slab.h> | ||
| 30 | 31 | ||
| 31 | #include <asm/bootinfo.h> | 32 | #include <asm/bootinfo.h> |
| 32 | #include <asm/io.h> | 33 | #include <asm/io.h> |
| @@ -38,6 +39,55 @@ · 5 unmodified lines | |||
| 38 | #include <msp_int.h> | 39 | #include <msp_int.h> |
| 39 | #include <msp_regs.h> | 40 | #include <msp_regs.h> |
| 40 | 41 | ||
| 42 | struct msp_uart_data { | ||
| 43 | int last_lcr; | ||
| 44 | }; | ||
| 45 | |||
| 46 | static void msp_serial_out(struct uart_port *p, int offset, int value) | ||
| 47 | { | ||
| 48 | struct msp_uart_data *d = p->private_data; | ||
| 49 | |||
| 50 | if (offset == UART_LCR) | ||
| 51 | d->last_lcr = value; | ||
| 52 | |||
| 53 | offset <<= p->regshift; | ||
| 54 | writeb(value, p->membase + offset); | ||
| 55 | } | ||
| 56 | |||
| 57 | static unsigned int msp_serial_in(struct uart_port *p, int offset) | ||
| 58 | { | ||
| 59 | offset <<= p->regshift; | ||
| 60 | |||
| 61 | return readb(p->membase + offset); | ||
| 62 | } | ||
| 63 | |||
| 64 | static int msp_serial_handle_irq(struct uart_port *p) | ||
| 65 | { | ||
| 66 | struct msp_uart_data *d = p->private_data; | ||
| 67 | unsigned int iir = readb(p->membase + (UART_IIR << p->regshift)); | ||
| 68 | |||
| 69 | if (serial8250_handle_irq(p, iir)) { | ||
| 70 | return 1; | ||
| 71 | } else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) { | ||
| 72 | /* | ||
| 73 | * The DesignWare APB UART has an Busy Detect (0x07) interrupt | ||
| 74 | * meaning an LCR write attempt occurred while the UART was | ||
| 75 | * busy. The interrupt must be cleared by reading the UART | ||
| 76 | * status register (USR) and the LCR re-written. | ||
| 77 | * | ||
| 78 | * Note: MSP reserves 0x20 bytes of address space for the UART | ||
| 79 | * and the USR is mapped in a separate block at an offset of | ||
| 80 | * 0xc0 from the start of the UART. | ||
| 81 | */ | ||
| 82 | (void)readb(p->membase + 0xc0); | ||
| 83 | writeb(d->last_lcr, p->membase + (UART_LCR << p->regshift)); | ||
| 84 | |||
| 85 | return 1; | ||
| 86 | } | ||
| 87 | |||
| 88 | return 0; | ||
| 89 | } | ||
| 90 | |||
| 41 | void __init msp_serial_setup(void) | 91 | void __init msp_serial_setup(void) |
| 42 | { | 92 | { |
| 43 | char *s; | 93 | char *s; |
| @@ -59,13 +109,22 @@ void __init msp_serial_setup(void) · 15 unmodified lines | |||
| 59 | up.irq = MSP_INT_UART0; | 109 | up.irq = MSP_INT_UART0; |
| 60 | up.uartclk = uartclk; | 110 | up.uartclk = uartclk; |
| 61 | up.regshift = 2; | 111 | up.regshift = 2; |
| 62 | up.iotype = UPIO_DWAPB; /* UPIO_MEM like */ | 112 | up.iotype = UPIO_MEM; |
| 63 | up.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; | 113 | up.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; |
| 64 | up.type = PORT_16550A; | 114 | up.type = PORT_16550A; |
| 65 | up.line = 0; | 115 | up.line = 0; |
| 66 | up.private_data = (void*)UART0_STATUS_REG; | 116 | up.serial_out = msp_serial_out; |
| 67 | if (early_serial_setup(&up)) | 117 | up.serial_in = msp_serial_in; |
| 68 | printk(KERN_ERR "Early serial init of port 0 failed\n"); | 118 | up.handle_irq = msp_serial_handle_irq; |
| 119 | up.private_data = kzalloc(sizeof(struct msp_uart_data), GFP_KERNEL); | ||
| 120 | if (!up.private_data) { | ||
| 121 | pr_err("failed to allocate uart private data\n"); | ||
| 122 | return; | ||
| 123 | } | ||
| 124 | if (early_serial_setup(&up)) { | ||
| 125 | kfree(up.private_data); | ||
| 126 | pr_err("Early serial init of port 0 failed\n"); | ||
| 127 | } | ||
| 69 | 128 | ||
| 70 | /* Initialize the second serial port, if one exists */ | 129 | /* Initialize the second serial port, if one exists */ |
| 71 | switch (mips_machtype) { | 130 | switch (mips_machtype) { |
| @@ -88,6 +147,8 @@ void __init msp_serial_setup(void) · 16 unmodified lines | |||
| 88 | up.irq = MSP_INT_UART1; | 147 | up.irq = MSP_INT_UART1; |
| 89 | up.line = 1; | 148 | up.line = 1; |
| 90 | up.private_data = (void*)UART1_STATUS_REG; | 149 | up.private_data = (void*)UART1_STATUS_REG; |
| 91 | if (early_serial_setup(&up)) | 150 | if (early_serial_setup(&up)) { |
| 92 | printk(KERN_ERR "Early serial init of port 1 failed\n"); | 151 | kfree(up.private_data); |
| 152 | pr_err("Early serial init of port 1 failed\n"); | ||
| 153 | } | ||
| 93 | } | 154 | } |
| @@ -54,6 +54,7 @@ extern void __init udbg_init_40x_realmode(void); · 53 unmodified lines | |||
| 54 | extern void __init udbg_init_cpm(void); | 54 | extern void __init udbg_init_cpm(void); |
| 55 | extern void __init udbg_init_usbgecko(void); | 55 | extern void __init udbg_init_usbgecko(void); |
| 56 | extern void __init udbg_init_wsp(void); | 56 | extern void __init udbg_init_wsp(void); |
| 57 | extern void __init udbg_init_ehv_bc(void); | ||
| 57 | 58 | ||
| 58 | #endif /* __KERNEL__ */ | 59 | #endif /* __KERNEL__ */ |
| 59 | #endif /* _ASM_POWERPC_UDBG_H */ | 60 | #endif /* _ASM_POWERPC_UDBG_H */ |
| @@ -67,6 +67,8 @@ void __init udbg_early_init(void) · 66 unmodified lines | |||
| 67 | udbg_init_usbgecko(); | 67 | udbg_init_usbgecko(); |
| 68 | #elif defined(CONFIG_PPC_EARLY_DEBUG_WSP) | 68 | #elif defined(CONFIG_PPC_EARLY_DEBUG_WSP) |
| 69 | udbg_init_wsp(); | 69 | udbg_init_wsp(); |
| 70 | #elif defined(CONFIG_PPC_EARLY_DEBUG_EHV_BC) | ||
| 71 | udbg_init_ehv_bc(); | ||
| 70 | #endif | 72 | #endif |
| 71 | 73 | ||
| 72 | #ifdef CONFIG_PPC_EARLY_DEBUG | 74 | #ifdef CONFIG_PPC_EARLY_DEBUG |
| @@ -14,6 +14,8 @@ · 13 unmodified lines | |||
| 14 | 14 | ||
| 15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
| 16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| 17 | #include <linux/interrupt.h> | ||
| 18 | #include <linux/scatterlist.h> | ||
| 17 | #include <linux/sfi.h> | 19 | #include <linux/sfi.h> |
| 18 | #include <linux/intel_pmic_gpio.h> | 20 | #include <linux/intel_pmic_gpio.h> |
| 19 | #include <linux/spi/spi.h> | 21 | #include <linux/spi/spi.h> |
| @@ -392,6 +394,7 @@ static void __init *max3111_platform_data(void *info) · 372 unmodified lines | |||
| 392 | struct spi_board_info *spi_info = info; | 394 | struct spi_board_info *spi_info = info; |
| 393 | int intr = get_gpio_by_name("max3111_int"); | 395 | int intr = get_gpio_by_name("max3111_int"); |
| 394 | 396 | ||
| 397 | spi_info->mode = SPI_MODE_0; | ||
| 395 | if (intr == -1) | 398 | if (intr == -1) |
| 396 | return NULL; | 399 | return NULL; |
| 397 | spi_info->irq = intr + MRST_IRQ_OFFSET; | 400 | spi_info->irq = intr + MRST_IRQ_OFFSET; |
| @@ -1693,7 +1693,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp) · 1692 unmodified lines | |||
| 1693 | * line status register. | 1693 | * line status register. |
| 1694 | */ | 1694 | */ |
| 1695 | if (info->flags & ISDN_ASYNC_INITIALIZED) { | 1695 | if (info->flags & ISDN_ASYNC_INITIALIZED) { |
| 1696 | tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */ | 1696 | tty_wait_until_sent_from_close(tty, 3000); /* 30 seconds timeout */ |
| 1697 | /* | 1697 | /* |
| 1698 | * Before we drop DTR, make sure the UART transmitter | 1698 | * Before we drop DTR, make sure the UART transmitter |
| 1699 | * has completely drained; this is especially | 1699 | * has completely drained; this is especially |
| @@ -2595,14 +2595,17 @@ static int __devinit sio_ite_8872_probe(struct pci_dev *pdev, int autoirq, · 2594 unmodified lines | |||
| 2595 | break; | 2595 | break; |
| 2596 | case 0x6: | 2596 | case 0x6: |
| 2597 | printk(KERN_INFO "parport_pc: ITE8873 found (1S)\n"); | 2597 | printk(KERN_INFO "parport_pc: ITE8873 found (1S)\n"); |
| 2598 | release_region(inta_addr[i], 32); | ||
| 2598 | return 0; | 2599 | return 0; |
| 2599 | case 0x8: | 2600 | case 0x8: |
| 2600 | printk(KERN_INFO "parport_pc: ITE8874 found (2S)\n"); | 2601 | printk(KERN_INFO "parport_pc: ITE8874 found (2S)\n"); |
| 2602 | release_region(inta_addr[i], 32); | ||
| 2601 | return 0; | 2603 | return 0; |
| 2602 | default: | 2604 | default: |
| 2603 | printk(KERN_INFO "parport_pc: unknown ITE887x\n"); | 2605 | printk(KERN_INFO "parport_pc: unknown ITE887x\n"); |
| 2604 | printk(KERN_INFO "parport_pc: please mail 'lspci -nvv' " | 2606 | printk(KERN_INFO "parport_pc: please mail 'lspci -nvv' " |
| 2605 | "output to Rich.Liu@ite.com.tw\n"); | 2607 | "output to Rich.Liu@ite.com.tw\n"); |
| 2608 | release_region(inta_addr[i], 32); | ||
| 2606 | return 0; | 2609 | return 0; |
| 2607 | } | 2610 | } |
| 2608 | 2611 | ||
| @@ -24,6 +24,8 @@ menuconfig STAGING · 23 unmodified lines | |||
| 24 | 24 | ||
| 25 | if STAGING | 25 | if STAGING |
| 26 | 26 | ||
| 27 | source "drivers/staging/serial/Kconfig" | ||
| 28 | |||
| 27 | source "drivers/staging/et131x/Kconfig" | 29 | source "drivers/staging/et131x/Kconfig" |
| 28 | 30 | ||
| 29 | source "drivers/staging/slicoss/Kconfig" | 31 | source "drivers/staging/slicoss/Kconfig" |
| @@ -3,6 +3,7 @@ · 2 unmodified lines | |||
| 3 | # fix for build system bug... | 3 | # fix for build system bug... |
| 4 | obj-$(CONFIG_STAGING) += staging.o | 4 | obj-$(CONFIG_STAGING) += staging.o |
| 5 | 5 | ||
| 6 | obj-y += serial/ | ||
| 6 | obj-$(CONFIG_ET131X) += et131x/ | 7 | obj-$(CONFIG_ET131X) += et131x/ |
| 7 | obj-$(CONFIG_SLICOSS) += slicoss/ | 8 | obj-$(CONFIG_SLICOSS) += slicoss/ |
| 8 | obj-$(CONFIG_VIDEO_GO7007) += go7007/ | 9 | obj-$(CONFIG_VIDEO_GO7007) += go7007/ |
File renamed without changes.
| @@ -0,0 +1,16 @@ | |||
| 1 | config SERIAL_68360_SMC | ||
| 2 | bool "68360 SMC uart support" | ||
| 3 | depends on M68360 | ||
| 4 | help | ||
| 5 | This driver supports the SMC serial ports of the Motorola 68360 CPU. | ||
| 6 | |||
| 7 | config SERIAL_68360_SCC | ||
| 8 | bool "68360 SCC uart support" | ||
| 9 | depends on M68360 | ||
| 10 | help | ||
| 11 | This driver supports the SCC serial ports of the Motorola 68360 CPU. | ||
| 12 | |||
| 13 | config SERIAL_68360 | ||
| 14 | bool | ||
| 15 | depends on SERIAL_68360_SMC || SERIAL_68360_SCC | ||
| 16 | default y | ||
| @@ -0,0 +1 @@ | |||
| 1 | obj-$(CONFIG_SERIAL_68360) += 68360serial.o | ||
| @@ -0,0 +1,6 @@ | |||
| 1 | These are a few serial drivers that either do not build, or do not work if they | ||
| 2 | do build, or if they seem to work, are for obsolete hardware, or are full of | ||
| 3 | unfixable races and no one uses them anymore. | ||
| 4 | |||
| 5 | If no one steps up to adopt any of these drivers, they will be removed | ||
| 6 | in the 3.4 release. | ||
| @@ -354,3 +354,37 @@ config TRACE_SINK · 353 unmodified lines | |||
| 354 | 354 | ||
| 355 | If you select this option, you need to select | 355 | If you select this option, you need to select |
| 356 | "Trace data router for MIPI P1149.7 cJTAG standard". | 356 | "Trace data router for MIPI P1149.7 cJTAG standard". |
| 357 | |||
| 358 | config PPC_EPAPR_HV_BYTECHAN | ||
| 359 | tristate "ePAPR hypervisor byte channel driver" | ||
| 360 | depends on PPC | ||
| 361 | help | ||
| 362 | This driver creates /dev entries for each ePAPR hypervisor byte | ||
| 363 | channel, thereby allowing applications to communicate with byte | ||
| 364 | channels as if they were serial ports. | ||
| 365 | |||
| 366 | config PPC_EARLY_DEBUG_EHV_BC | ||
| 367 | bool "Early console (udbg) support for ePAPR hypervisors" | ||
| 368 | depends on PPC_EPAPR_HV_BYTECHAN | ||
| 369 | help | ||
| 370 | Select this option to enable early console (a.k.a. "udbg") support | ||
| 371 | via an ePAPR byte channel. You also need to choose the byte channel | ||
| 372 | handle below. | ||
| 373 | |||
| 374 | config PPC_EARLY_DEBUG_EHV_BC_HANDLE | ||
| 375 | int "Byte channel handle for early console (udbg)" | ||
| 376 | depends on PPC_EARLY_DEBUG_EHV_BC | ||
| 377 | default 0 | ||
| 378 | help | ||
| 379 | If you want early console (udbg) output through a byte channel, | ||
| 380 | specify the handle of the byte channel to use. | ||
| 381 | |||
| 382 | For this to work, the byte channel driver must be compiled | ||
| 383 | in-kernel, not as a module. | ||
| 384 | |||
| 385 | Note that only one early console driver can be enabled, so don't | ||
| 386 | enable any others if you enable this one. | ||
| 387 | |||
| 388 | If the number you specify is not a valid byte channel handle, then | ||
| 389 | there simply will be no early console output. This is true also | ||
| 390 | if you don't boot under a hypervisor at all. | ||
| @@ -26,5 +26,6 @@ obj-$(CONFIG_ROCKETPORT) += rocket.o · 25 unmodified lines | |||
| 26 | obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o | 26 | obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o |
| 27 | obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o | 27 | obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o |
| 28 | obj-$(CONFIG_SYNCLINK) += synclink.o | 28 | obj-$(CONFIG_SYNCLINK) += synclink.o |
| 29 | obj-$(CONFIG_PPC_EPAPR_HV_BYTECHAN) += ehv_bytechan.o | ||
| 29 | 30 | ||
| 30 | obj-y += ipwireless/ | 31 | obj-y += ipwireless/ |
| @@ -1529,7 +1529,6 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) · 1528 unmodified lines | |||
| 1529 | { | 1529 | { |
| 1530 | struct async_struct * info = tty->driver_data; | 1530 | struct async_struct * info = tty->driver_data; |
| 1531 | unsigned long orig_jiffies, char_time; | 1531 | unsigned long orig_jiffies, char_time; |
| 1532 | int tty_was_locked = tty_locked(); | ||
| 1533 | int lsr; | 1532 | int lsr; |
| 1534 | 1533 | ||
| 1535 | if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent")) | 1534 | if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent")) |
| @@ -1540,12 +1539,6 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) · 4 unmodified lines | |||
| 1540 | 1539 | ||
| 1541 | orig_jiffies = jiffies; | 1540 | orig_jiffies = jiffies; |
| 1542 | 1541 | ||
| 1543 | /* | ||
| 1544 | * tty_wait_until_sent is called from lots of places, | ||
| 1545 | * with or without the BTM. | ||
| 1546 | */ | ||
| 1547 | if (!tty_was_locked) | ||
| 1548 | tty_lock(); | ||
| 1549 | /* | 1542 | /* |
| 1550 | * Set the check interval to be 1/5 of the estimated time to | 1543 | * Set the check interval to be 1/5 of the estimated time to |
| 1551 | * send a single character, and make it at least 1. The check | 1544 | * send a single character, and make it at least 1. The check |
| @@ -1586,8 +1579,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) · 34 unmodified lines | |||
| 1586 | break; | 1579 | break; |
| 1587 | } | 1580 | } |
| 1588 | __set_current_state(TASK_RUNNING); | 1581 | __set_current_state(TASK_RUNNING); |
| 1589 | if (!tty_was_locked) | 1582 | |
| 1590 | tty_unlock(); | ||
| 1591 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT | 1583 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT |
| 1592 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); | 1584 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); |
| 1593 | #endif | 1585 | #endif |
| @@ -2025,7 +2017,7 @@ static int __init amiga_serial_probe(struct platform_device *pdev) · 431 unmodified lines | |||
| 2025 | if (error) | 2017 | if (error) |
| 2026 | goto fail_unregister; | 2018 | goto fail_unregister; |
| 2027 | 2019 | ||
| 2028 | error = request_irq(IRQ_AMIGA_RBF, ser_rx_int, IRQF_DISABLED, | 2020 | error = request_irq(IRQ_AMIGA_RBF, ser_rx_int, 0, |
| 2029 | "serial RX", state); | 2021 | "serial RX", state); |
| 2030 | if (error) | 2022 | if (error) |
| 2031 | goto fail_free_irq; | 2023 | goto fail_free_irq; |
| @@ -45,7 +45,6 @@ · 44 unmodified lines | |||
| 45 | #undef CY_DEBUG_IO | 45 | #undef CY_DEBUG_IO |
| 46 | #undef CY_DEBUG_COUNT | 46 | #undef CY_DEBUG_COUNT |
| 47 | #undef CY_DEBUG_DTR | 47 | #undef CY_DEBUG_DTR |
| 48 | #undef CY_DEBUG_WAIT_UNTIL_SENT | ||
| 49 | #undef CY_DEBUG_INTERRUPTS | 48 | #undef CY_DEBUG_INTERRUPTS |
| 50 | #undef CY_16Y_HACK | 49 | #undef CY_16Y_HACK |
| 51 | #undef CY_ENABLE_MONITORING | 50 | #undef CY_ENABLE_MONITORING |
| @@ -1678,16 +1677,10 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout) · 1626 unmodified lines | |||
| 1678 | */ | 1677 | */ |
| 1679 | if (!timeout || timeout > 2 * info->timeout) | 1678 | if (!timeout || timeout > 2 * info->timeout) |
| 1680 | timeout = 2 * info->timeout; | 1679 | timeout = 2 * info->timeout; |
| 1681 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT | 1680 | |
| 1682 | printk(KERN_DEBUG "In cy_wait_until_sent(%d) check=%d, jiff=%lu...", | ||
| 1683 | timeout, char_time, jiffies); | ||
| 1684 | #endif | ||
| 1685 | card = info->card; | 1681 | card = info->card; |
| 1686 | if (!cy_is_Z(card)) { | 1682 | if (!cy_is_Z(card)) { |
| 1687 | while (cyy_readb(info, CySRER) & CyTxRdy) { | 1683 | while (cyy_readb(info, CySRER) & CyTxRdy) { |
| 1688 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT | ||
| 1689 | printk(KERN_DEBUG "Not clean (jiff=%lu)...", jiffies); | ||
| 1690 | #endif | ||
| 1691 | if (msleep_interruptible(jiffies_to_msecs(char_time))) | 1684 | if (msleep_interruptible(jiffies_to_msecs(char_time))) |
| 1692 | break; | 1685 | break; |
| 1693 | if (timeout && time_after(jiffies, orig_jiffies + | 1686 | if (timeout && time_after(jiffies, orig_jiffies + |
| @@ -1697,9 +1690,6 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout) · 3 unmodified lines | |||
| 1697 | } | 1690 | } |
| 1698 | /* Run one more char cycle */ | 1691 | /* Run one more char cycle */ |
| 1699 | msleep_interruptible(jiffies_to_msecs(char_time * 5)); | 1692 | msleep_interruptible(jiffies_to_msecs(char_time * 5)); |
| 1700 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT | ||
| 1701 | printk(KERN_DEBUG "Clean (jiff=%lu)...done\n", jiffies); | ||
| 1702 | #endif | ||
| 1703 | } | 1693 | } |
| 1704 | 1694 | ||
| 1705 | static void cy_flush_buffer(struct tty_struct *tty) | 1695 | static void cy_flush_buffer(struct tty_struct *tty) |
| @@ -3377,7 +3367,7 @@ static int __init cy_detect_isa(void) · 1671 unmodified lines | |||
| 3377 | 3367 | ||
| 3378 | /* allocate IRQ */ | 3368 | /* allocate IRQ */ |
| 3379 | if (request_irq(cy_isa_irq, cyy_interrupt, | 3369 | if (request_irq(cy_isa_irq, cyy_interrupt, |
| 3380 | IRQF_DISABLED, "Cyclom-Y", &cy_card[j])) { | 3370 | 0, "Cyclom-Y", &cy_card[j])) { |
| 3381 | printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but " | 3371 | printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but " |
| 3382 | "could not allocate IRQ#%d.\n", | 3372 | "could not allocate IRQ#%d.\n", |
| 3383 | (unsigned long)cy_isa_address, cy_isa_irq); | 3373 | (unsigned long)cy_isa_address, cy_isa_irq); |
| @@ -0,0 +1,881 @@ | |||
| 1 | /* ePAPR hypervisor byte channel device driver | ||
| 2 | * | ||
| 3 | * Copyright 2009-2011 Freescale Semiconductor, Inc. | ||
| 4 | * | ||
| 5 | * Author: Timur Tabi <timur@freescale.com> | ||
| 6 | * | ||
| 7 | * This file is licensed under the terms of the GNU General Public License | ||
| 8 | * version 2. This program is licensed "as is" without any warranty of any | ||
| 9 | * kind, whether express or implied. | ||
| 10 | * | ||
| 11 | * This driver support three distinct interfaces, all of which are related to | ||
| 12 | * ePAPR hypervisor byte channels. | ||
| 13 | * | ||
| 14 | * 1) An early-console (udbg) driver. This provides early console output | ||
| 15 | * through a byte channel. The byte channel handle must be specified in a | ||
| 16 | * Kconfig option. | ||
| 17 | * | ||
| 18 | * 2) A normal console driver. Output is sent to the byte channel designated | ||
| 19 | * for stdout in the device tree. The console driver is for handling kernel | ||
| 20 | * printk calls. | ||
| 21 | * | ||
| 22 | * 3) A tty driver, which is used to handle user-space input and output. The | ||
| 23 | * byte channel used for the console is designated as the default tty. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #include <linux/module.h> | ||
| 27 | #include <linux/init.h> | ||
| 28 | #include <linux/slab.h> | ||
| 29 | #include <linux/err.h> | ||
| 30 | #include <linux/interrupt.h> | ||
| 31 | #include <linux/fs.h> | ||
| 32 | #include <linux/poll.h> | ||
| 33 | #include <asm/epapr_hcalls.h> | ||
| 34 | #include <linux/of.h> | ||
| 35 | #include <linux/platform_device.h> | ||
| 36 | #include <linux/cdev.h> | ||
| 37 | #include <linux/console.h> | ||
| 38 | #include <linux/tty.h> | ||
| 39 | #include <linux/tty_flip.h> | ||
| 40 | #include <linux/circ_buf.h> | ||
| 41 | #include <asm/udbg.h> | ||
| 42 | |||
| 43 | /* The size of the transmit circular buffer. This must be a power of two. */ | ||
| 44 | #define BUF_SIZE 2048 | ||
| 45 | |||
| 46 | /* Per-byte channel private data */ | ||
| 47 | struct ehv_bc_data { | ||
| 48 | struct device *dev; | ||
| 49 | struct tty_port port; | ||
| 50 | uint32_t handle; | ||
| 51 | unsigned int rx_irq; | ||
| 52 | unsigned int tx_irq; | ||
| 53 | |||
| 54 | spinlock_t lock; /* lock for transmit buffer */ | ||
| 55 | unsigned char buf[BUF_SIZE]; /* transmit circular buffer */ | ||
| 56 | unsigned int head; /* circular buffer head */ | ||
| 57 | unsigned int tail; /* circular buffer tail */ | ||
| 58 | |||
| 59 | int tx_irq_enabled; /* true == TX interrupt is enabled */ | ||
| 60 | }; | ||
| 61 | |||
| 62 | /* Array of byte channel objects */ | ||
| 63 | static struct ehv_bc_data *bcs; | ||
| 64 | |||
| 65 | /* Byte channel handle for stdout (and stdin), taken from device tree */ | ||
| 66 | static unsigned int stdout_bc; | ||
| 67 | |||
| 68 | /* Virtual IRQ for the byte channel handle for stdin, taken from device tree */ | ||
| 69 | static unsigned int stdout_irq; | ||
| 70 | |||
| 71 | /**************************** SUPPORT FUNCTIONS ****************************/ | ||
| 72 | |||
| 73 | /* | ||
| 74 | * Enable the transmit interrupt | ||
| 75 | * | ||
| 76 | * Unlike a serial device, byte channels have no mechanism for disabling their | ||
| 77 | * own receive or transmit interrupts. To emulate that feature, we toggle | ||
| 78 | * the IRQ in the kernel. | ||
| 79 | * | ||
| 80 | * We cannot just blindly call enable_irq() or disable_irq(), because these | ||
| 81 | * calls are reference counted. This means that we cannot call enable_irq() | ||
| 82 | * if interrupts are already enabled. This can happen in two situations: | ||
| 83 | * | ||
| 84 | * 1. The tty layer makes two back-to-back calls to ehv_bc_tty_write() | ||
| 85 | * 2. A transmit interrupt occurs while executing ehv_bc_tx_dequeue() | ||
| 86 | * | ||
| 87 | * To work around this, we keep a flag to tell us if the IRQ is enabled or not. | ||
| 88 | */ | ||
| 89 | static void enable_tx_interrupt(struct ehv_bc_data *bc) | ||
| 90 | { | ||
| 91 | if (!bc->tx_irq_enabled) { | ||
| 92 | enable_irq(bc->tx_irq); | ||
| 93 | bc->tx_irq_enabled = 1; | ||
| 94 | } | ||
| 95 | } | ||
| 96 | |||
| 97 | static void disable_tx_interrupt(struct ehv_bc_data *bc) | ||
| 98 | { | ||
| 99 | if (bc->tx_irq_enabled) { | ||
| 100 | disable_irq_nosync(bc->tx_irq); | ||
| 101 | bc->tx_irq_enabled = 0; | ||
| 102 | } | ||
| 103 | } | ||
| 104 | |||
| 105 | /* | ||
| 106 | * find the byte channel handle to use for the console | ||
| 107 | * | ||
| 108 | * The byte channel to be used for the console is specified via a "stdout" | ||
| 109 | * property in the /chosen node. | ||
| 110 | * | ||
| 111 | * For compatible with legacy device trees, we also look for a "stdout" alias. | ||
| 112 | */ | ||
| 113 | static int find_console_handle(void) | ||
| 114 | { | ||
| 115 | struct device_node *np, *np2; | ||
| 116 | const char *sprop = NULL; | ||
| 117 | const uint32_t *iprop; | ||
| 118 | |||
| 119 | np = of_find_node_by_path("/chosen"); | ||
| 120 | if (np) | ||
| 121 | sprop = of_get_property(np, "stdout-path", NULL); | ||
| 122 | |||
| 123 | if (!np || !sprop) { | ||
| 124 | of_node_put(np); | ||
| 125 | np = of_find_node_by_name(NULL, "aliases"); | ||
| 126 | if (np) | ||
| 127 | sprop = of_get_property(np, "stdout", NULL); | ||
| 128 | } | ||
| 129 | |||
| 130 | if (!sprop) { | ||
| 131 | of_node_put(np); | ||
| 132 | return 0; | ||
| 133 | } | ||
| 134 | |||
| 135 | /* We don't care what the aliased node is actually called. We only | ||
| 136 | * care if it's compatible with "epapr,hv-byte-channel", because that | ||
| 137 | * indicates that it's a byte channel node. We use a temporary | ||
| 138 | * variable, 'np2', because we can't release 'np' until we're done with | ||
| 139 | * 'sprop'. | ||
| 140 | */ | ||
| 141 | np2 = of_find_node_by_path(sprop); | ||
| 142 | of_node_put(np); | ||
| 143 | np = np2; | ||
| 144 | if (!np) { | ||
| 145 | pr_warning("ehv-bc: stdout node '%s' does not exist\n", sprop); | ||
| 146 | return 0; | ||
| 147 | } | ||
| 148 | |||
| 149 | /* Is it a byte channel? */ | ||
| 150 | if (!of_device_is_compatible(np, "epapr,hv-byte-channel")) { | ||
| 151 | of_node_put(np); | ||
| 152 | return 0; | ||
| 153 | } | ||
| 154 | |||
| 155 | stdout_irq = irq_of_parse_and_map(np, 0); | ||
| 156 | if (stdout_irq == NO_IRQ) { | ||
| 157 | pr_err("ehv-bc: no 'interrupts' property in %s node\n", sprop); | ||
| 158 | of_node_put(np); | ||
| 159 | return 0; | ||
| 160 | } | ||
| 161 | |||
| 162 | /* | ||
| 163 | * The 'hv-handle' property contains the handle for this byte channel. | ||
| 164 | */ | ||
| 165 | iprop = of_get_property(np, "hv-handle", NULL); | ||
| 166 | if (!iprop) { | ||
| 167 | pr_err("ehv-bc: no 'hv-handle' property in %s node\n", | ||
| 168 | np->name); | ||
| 169 | of_node_put(np); | ||
| 170 | return 0; | ||
| 171 | } | ||
| 172 | stdout_bc = be32_to_cpu(*iprop); | ||
| 173 | |||
| 174 | of_node_put(np); | ||
| 175 | return 1; | ||
| 176 | } | ||
| 177 | |||
| 178 | /*************************** EARLY CONSOLE DRIVER ***************************/ | ||
| 179 | |||
| 180 | #ifdef CONFIG_PPC_EARLY_DEBUG_EHV_BC | ||
| 181 | |||
| 182 | /* | ||
| 183 | * send a byte to a byte channel, wait if necessary | ||
| 184 | * | ||
| 185 | * This function sends a byte to a byte channel, and it waits and | ||
| 186 | * retries if the byte channel is full. It returns if the character | ||
| 187 | * has been sent, or if some error has occurred. | ||
| 188 | * | ||
| 189 | */ | ||
| 190 | static void byte_channel_spin_send(const char data) | ||
| 191 | { | ||
| 192 | int ret, count; | ||
| 193 | |||
| 194 | do { | ||
| 195 | count = 1; | ||
| 196 | ret = ev_byte_channel_send(CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE, | ||
| 197 | &count, &data); | ||
| 198 | } while (ret == EV_EAGAIN); | ||
| 199 | } | ||
| 200 | |||
| 201 | /* | ||
| 202 | * The udbg subsystem calls this function to display a single character. | ||
| 203 | * We convert CR to a CR/LF. | ||
| 204 | */ | ||
| 205 | static void ehv_bc_udbg_putc(char c) | ||
| 206 | { | ||
| 207 | if (c == '\n') | ||
| 208 | byte_channel_spin_send('\r'); | ||
| 209 | |||
| 210 | byte_channel_spin_send(c); | ||
| 211 | } | ||
| 212 | |||
| 213 | /* | ||
| 214 | * early console initialization | ||
| 215 | * | ||
| 216 | * PowerPC kernels support an early printk console, also known as udbg. | ||
| 217 | * This function must be called via the ppc_md.init_early function pointer. | ||
| 218 | * At this point, the device tree has been unflattened, so we can obtain the | ||
| 219 | * byte channel handle for stdout. | ||
| 220 | * | ||
| 221 | * We only support displaying of characters (putc). We do not support | ||
| 222 | * keyboard input. | ||
| 223 | */ | ||
| 224 | void __init udbg_init_ehv_bc(void) | ||
| 225 | { | ||
| 226 | unsigned int rx_count, tx_count; | ||
| 227 | unsigned int ret; | ||
| 228 | |||
| 229 | /* Verify the byte channel handle */ | ||
| 230 | ret = ev_byte_channel_poll(CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE, | ||
| 231 | &rx_count, &tx_count); | ||
| 232 | if (ret) | ||
| 233 | return; | ||
| 234 | |||
| 235 | udbg_putc = ehv_bc_udbg_putc; | ||
| 236 | register_early_udbg_console(); | ||
| 237 | |||
| 238 | udbg_printf("ehv-bc: early console using byte channel handle %u\n", | ||
| 239 | CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE); | ||
| 240 | } | ||
| 241 | |||
| 242 | #endif | ||
| 243 | |||
| 244 | /****************************** CONSOLE DRIVER ******************************/ | ||
| 245 | |||
| 246 | static struct tty_driver *ehv_bc_driver; | ||
| 247 | |||
| 248 | /* | ||
| 249 | * Byte channel console sending worker function. | ||
| 250 | * | ||
| 251 | * For consoles, if the output buffer is full, we should just spin until it | ||
| 252 | * clears. | ||
| 253 | */ | ||
| 254 | static int ehv_bc_console_byte_channel_send(unsigned int handle, const char *s, | ||
| 255 | unsigned int count) | ||
| 256 | { | ||
| 257 | unsigned int len; | ||
| 258 | int ret = 0; | ||
| 259 | |||
| 260 | while (count) { | ||
| 261 | len = min_t(unsigned int, count, EV_BYTE_CHANNEL_MAX_BYTES); | ||
| 262 | do { | ||
| 263 | ret = ev_byte_channel_send(handle, &len, s); | ||
| 264 | } while (ret == EV_EAGAIN); | ||
| 265 | count -= len; | ||
| 266 | s += len; | ||
| 267 | } | ||
| 268 | |||
| 269 | return ret; | ||
| 270 | } | ||
| 271 | |||
| 272 | /* | ||
| 273 | * write a string to the console | ||
| 274 | * | ||
| 275 | * This function gets called to write a string from the kernel, typically from | ||
| 276 | * a printk(). This function spins until all data is written. | ||
| 277 | * | ||
| 278 | * We copy the data to a temporary buffer because we need to insert a \r in | ||
| 279 | * front of every \n. It's more efficient to copy the data to the buffer than | ||
| 280 | * it is to make multiple hcalls for each character or each newline. | ||
| 281 | */ | ||
| 282 | static void ehv_bc_console_write(struct console *co, const char *s, | ||
| 283 | unsigned int count) | ||
| 284 | { | ||
| 285 | char s2[EV_BYTE_CHANNEL_MAX_BYTES]; | ||
| 286 | unsigned int i, j = 0; | ||
| 287 | char c; | ||
| 288 | |||
| 289 | for (i = 0; i < count; i++) { | ||
| 290 | c = *s++; | ||
| 291 | |||
| 292 | if (c == '\n') | ||
| 293 | s2[j++] = '\r'; | ||
| 294 | |||
| 295 | s2[j++] = c; | ||
| 296 | if (j >= (EV_BYTE_CHANNEL_MAX_BYTES - 1)) { | ||
| 297 | if (ehv_bc_console_byte_channel_send(stdout_bc, s2, j)) | ||
| 298 | return; | ||
| 299 | j = 0; | ||
| 300 | } | ||
| 301 | } | ||
| 302 | |||
| 303 | if (j) | ||
| 304 | ehv_bc_console_byte_channel_send(stdout_bc, s2, j); | ||
| 305 | } | ||
| 306 | |||
| 307 | /* | ||
| 308 | * When /dev/console is opened, the kernel iterates the console list looking | ||
| 309 | * for one with ->device and then calls that method. On success, it expects | ||
| 310 | * the passed-in int* to contain the minor number to use. | ||
| 311 | */ | ||
| 312 | static struct tty_driver *ehv_bc_console_device(struct console *co, int *index) | ||
| 313 | { | ||
| 314 | *index = co->index; | ||
| 315 | |||
| 316 | return ehv_bc_driver; | ||
| 317 | } | ||
| 318 | |||
| 319 | static struct console ehv_bc_console = { | ||
| 320 | .name = "ttyEHV", | ||
| 321 | .write = ehv_bc_console_write, | ||
| 322 | .device = ehv_bc_console_device, | ||
| 323 | .flags = CON_PRINTBUFFER | CON_ENABLED, | ||
| 324 | }; | ||
| 325 | |||
| 326 | /* | ||
| 327 | * Console initialization | ||
| 328 | * | ||
| 329 | * This is the first function that is called after the device tree is | ||
| 330 | * available, so here is where we determine the byte channel handle and IRQ for | ||
| 331 | * stdout/stdin, even though that information is used by the tty and character | ||
| 332 | * drivers. | ||
| 333 | */ | ||
| 334 | static int __init ehv_bc_console_init(void) | ||
| 335 | { | ||
| 336 | if (!find_console_handle()) { | ||
| 337 | pr_debug("ehv-bc: stdout is not a byte channel\n"); | ||
| 338 | return -ENODEV; | ||
| 339 | } | ||
| 340 | |||
| 341 | #ifdef CONFIG_PPC_EARLY_DEBUG_EHV_BC | ||
| 342 | /* Print a friendly warning if the user chose the wrong byte channel | ||
| 343 | * handle for udbg. | ||
| 344 | */ | ||
| 345 | if (stdout_bc != CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE) | ||
| 346 | pr_warning("ehv-bc: udbg handle %u is not the stdout handle\n", | ||
| 347 | CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE); | ||
| 348 | #endif | ||
| 349 | |||
| 350 | /* add_preferred_console() must be called before register_console(), | ||
| 351 | otherwise it won't work. However, we don't want to enumerate all the | ||
| 352 | byte channels here, either, since we only care about one. */ | ||
| 353 | |||
| 354 | add_preferred_console(ehv_bc_console.name, ehv_bc_console.index, NULL); | ||
| 355 | register_console(&ehv_bc_console); | ||
| 356 | |||
| 357 | pr_info("ehv-bc: registered console driver for byte channel %u\n", | ||
| 358 | stdout_bc); | ||
| 359 | |||
| 360 | return 0; | ||
| 361 | } | ||
| 362 | console_initcall(ehv_bc_console_init); | ||
| 363 | |||
| 364 | /******************************** TTY DRIVER ********************************/ | ||
| 365 | |||
| 366 | /* | ||
| 367 | * byte channel receive interupt handler | ||
| 368 | * | ||
| 369 | * This ISR is called whenever data is available on a byte channel. | ||
| 370 | */ | ||
| 371 | static irqreturn_t ehv_bc_tty_rx_isr(int irq, void *data) | ||
| 372 | { | ||
| 373 | struct ehv_bc_data *bc = data; | ||
| 374 | struct tty_struct *ttys = tty_port_tty_get(&bc->port); | ||
| 375 | unsigned int rx_count, tx_count, len; | ||
| 376 | int count; | ||
| 377 | char buffer[EV_BYTE_CHANNEL_MAX_BYTES]; | ||
| 378 | int ret; | ||
| 379 | |||
| 380 | /* ttys could be NULL during a hangup */ | ||
| 381 | if (!ttys) | ||
| 382 | return IRQ_HANDLED; | ||
| 383 | |||
| 384 | /* Find out how much data needs to be read, and then ask the TTY layer | ||
| 385 | * if it can handle that much. We want to ensure that every byte we | ||
| 386 | * read from the byte channel will be accepted by the TTY layer. | ||
| 387 | */ | ||
| 388 | ev_byte_channel_poll(bc->handle, &rx_count, &tx_count); | ||
| 389 | count = tty_buffer_request_room(ttys, rx_count); | ||
| 390 | |||
| 391 | /* 'count' is the maximum amount of data the TTY layer can accept at | ||
| 392 | * this time. However, during testing, I was never able to get 'count' | ||
| 393 | * to be less than 'rx_count'. I'm not sure whether I'm calling it | ||
| 394 | * correctly. | ||
| 395 | */ | ||
| 396 | |||
| 397 | while (count > 0) { | ||
| 398 | len = min_t(unsigned int, count, sizeof(buffer)); | ||
| 399 | |||
| 400 | /* Read some data from the byte channel. This function will | ||
| 401 | * never return more than EV_BYTE_CHANNEL_MAX_BYTES bytes. | ||
| 402 | */ | ||
| 403 | ev_byte_channel_receive(bc->handle, &len, buffer); | ||
| 404 | |||
| 405 | /* 'len' is now the amount of data that's been received. 'len' | ||
| 406 | * can't be zero, and most likely it's equal to one. | ||
| 407 | */ | ||
| 408 | |||
| 409 | /* Pass the received data to the tty layer. */ | ||
| 410 | ret = tty_insert_flip_string(ttys, buffer, len); | ||
| 411 | |||
| 412 | /* 'ret' is the number of bytes that the TTY layer accepted. | ||
| 413 | * If it's not equal to 'len', then it means the buffer is | ||
| 414 | * full, which should never happen. If it does happen, we can | ||
| 415 | * exit gracefully, but we drop the last 'len - ret' characters | ||
| 416 | * that we read from the byte channel. | ||
| 417 | */ | ||
| 418 | if (ret != len) | ||
| 419 | break; | ||
| 420 | |||
| 421 | count -= len; | ||
| 422 | } | ||
| 423 | |||
| 424 | /* Tell the tty layer that we're done. */ | ||
| 425 | tty_flip_buffer_push(ttys); | ||
| 426 | |||
| 427 | tty_kref_put(ttys); | ||
| 428 | |||
| 429 | return IRQ_HANDLED; | ||
| 430 | } | ||
| 431 | |||
| 432 | /* | ||
| 433 | * dequeue the transmit buffer to the hypervisor | ||
| 434 | * | ||
| 435 | * This function, which can be called in interrupt context, dequeues as much | ||
| 436 | * data as possible from the transmit buffer to the byte channel. | ||
| 437 | */ | ||
| 438 | static void ehv_bc_tx_dequeue(struct ehv_bc_data *bc) | ||
| 439 | { | ||
| 440 | unsigned int count; | ||
| 441 | unsigned int len, ret; | ||
| 442 | unsigned long flags; | ||
| 443 | |||
| 444 | do { | ||
| 445 | spin_lock_irqsave(&bc->lock, flags); | ||
| 446 | len = min_t(unsigned int, | ||
| 447 | CIRC_CNT_TO_END(bc->head, bc->tail, BUF_SIZE), | ||
| 448 | EV_BYTE_CHANNEL_MAX_BYTES); | ||
| 449 | |||
| 450 | ret = ev_byte_channel_send(bc->handle, &len, bc->buf + bc->tail); | ||
| 451 | |||
| 452 | /* 'len' is valid only if the return code is 0 or EV_EAGAIN */ | ||
| 453 | if (!ret || (ret == EV_EAGAIN)) | ||
| 454 | bc->tail = (bc->tail + len) & (BUF_SIZE - 1); | ||
| 455 | |||
| 456 | count = CIRC_CNT(bc->head, bc->tail, BUF_SIZE); | ||
| 457 | spin_unlock_irqrestore(&bc->lock, flags); | ||
| 458 | } while (count && !ret); | ||
| 459 | |||
| 460 | spin_lock_irqsave(&bc->lock, flags); | ||
| 461 | if (CIRC_CNT(bc->head, bc->tail, BUF_SIZE)) | ||
| 462 | /* | ||
| 463 | * If we haven't emptied the buffer, then enable the TX IRQ. | ||
| 464 | * We'll get an interrupt when there's more room in the | ||
| 465 | * hypervisor's output buffer. | ||
| 466 | */ | ||
| 467 | enable_tx_interrupt(bc); | ||
| 468 | else | ||
| 469 | disable_tx_interrupt(bc); | ||
| 470 | spin_unlock_irqrestore(&bc->lock, flags); | ||
| 471 | } | ||
| 472 | |||
| 473 | /* | ||
| 474 | * byte channel transmit interupt handler | ||
| 475 | * | ||
| 476 | * This ISR is called whenever space becomes available for transmitting | ||
| 477 | * characters on a byte channel. | ||
| 478 | */ | ||
| 479 | static irqreturn_t ehv_bc_tty_tx_isr(int irq, void *data) | ||
| 480 | { | ||
| 481 | struct ehv_bc_data *bc = data; | ||
| 482 | struct tty_struct *ttys = tty_port_tty_get(&bc->port); | ||
| 483 | |||
| 484 | ehv_bc_tx_dequeue(bc); | ||
| 485 | if (ttys) { | ||
| 486 | tty_wakeup(ttys); | ||
| 487 | tty_kref_put(ttys); | ||
| 488 | } | ||
| 489 | |||
| 490 | return IRQ_HANDLED; | ||
| 491 | } | ||
| 492 | |||
| 493 | /* | ||
| 494 | * This function is called when the tty layer has data for us send. We store | ||
| 495 | * the data first in a circular buffer, and then dequeue as much of that data | ||
| 496 | * as possible. | ||
| 497 | * | ||
| 498 | * We don't need to worry about whether there is enough room in the buffer for | ||
| 499 | * all the data. The purpose of ehv_bc_tty_write_room() is to tell the tty | ||
| 500 | * layer how much data it can safely send to us. We guarantee that | ||
| 501 | * ehv_bc_tty_write_room() will never lie, so the tty layer will never send us | ||
| 502 | * too much data. | ||
| 503 | */ | ||
| 504 | static int ehv_bc_tty_write(struct tty_struct *ttys, const unsigned char *s, | ||
| 505 | int count) | ||
| 506 | { | ||
| 507 | struct ehv_bc_data *bc = ttys->driver_data; | ||
| 508 | unsigned long flags; | ||
| 509 | unsigned int len; | ||
| 510 | unsigned int written = 0; | ||
| 511 | |||
| 512 | while (1) { | ||
| 513 | spin_lock_irqsave(&bc->lock, flags); | ||
| 514 | len = CIRC_SPACE_TO_END(bc->head, bc->tail, BUF_SIZE); | ||
| 515 | if (count < len) | ||
| 516 | len = count; | ||
| 517 | if (len) { | ||
| 518 | memcpy(bc->buf + bc->head, s, len); | ||
| 519 | bc->head = (bc->head + len) & (BUF_SIZE - 1); | ||
| 520 | } | ||
| 521 | spin_unlock_irqrestore(&bc->lock, flags); | ||
| 522 | if (!len) | ||
| 523 | break; | ||
| 524 | |||
| 525 | s += len; | ||
| 526 | count -= len; | ||
| 527 | written += len; | ||
| 528 | } | ||
| 529 | |||
| 530 | ehv_bc_tx_dequeue(bc); | ||
| 531 | |||
| 532 | return written; | ||
| 533 | } | ||
| 534 | |||
| 535 | /* | ||
| 536 | * This function can be called multiple times for a given tty_struct, which is | ||
| 537 | * why we initialize bc->ttys in ehv_bc_tty_port_activate() instead. | ||
| 538 | * | ||
| 539 | * The tty layer will still call this function even if the device was not | ||
| 540 | * registered (i.e. tty_register_device() was not called). This happens | ||
| 541 | * because tty_register_device() is optional and some legacy drivers don't | ||
| 542 | * use it. So we need to check for that. | ||
| 543 | */ | ||
| 544 | static int ehv_bc_tty_open(struct tty_struct *ttys, struct file *filp) | ||
| 545 | { | ||
| 546 | struct ehv_bc_data *bc = &bcs[ttys->index]; | ||
| 547 | |||
| 548 | if (!bc->dev) | ||
| 549 | return -ENODEV; | ||
| 550 | |||
| 551 | return tty_port_open(&bc->port, ttys, filp); | ||
| 552 | } | ||
| 553 | |||
| 554 | /* | ||
| 555 | * Amazingly, if ehv_bc_tty_open() returns an error code, the tty layer will | ||
| 556 | * still call this function to close the tty device. So we can't assume that | ||
| 557 | * the tty port has been initialized. | ||
| 558 | */ | ||
| 559 | static void ehv_bc_tty_close(struct tty_struct *ttys, struct file *filp) | ||
| 560 | { | ||
| 561 | struct ehv_bc_data *bc = &bcs[ttys->index]; | ||
| 562 | |||
| 563 | if (bc->dev) | ||
| 564 | tty_port_close(&bc->port, ttys, filp); | ||
| 565 | } | ||
| 566 | |||
| 567 | /* | ||
| 568 | * Return the amount of space in the output buffer | ||
| 569 | * | ||
| 570 | * This is actually a contract between the driver and the tty layer outlining | ||
| 571 | * how much write room the driver can guarantee will be sent OR BUFFERED. This | ||
| 572 | * driver MUST honor the return value. | ||
| 573 | */ | ||
| 574 | static int ehv_bc_tty_write_room(struct tty_struct *ttys) | ||
| 575 | { | ||
| 576 | struct ehv_bc_data *bc = ttys->driver_data; | ||
| 577 | unsigned long flags; | ||
| 578 | int count; | ||
| 579 | |||
| 580 | spin_lock_irqsave(&bc->lock, flags); | ||
| 581 | count = CIRC_SPACE(bc->head, bc->tail, BUF_SIZE); | ||
| 582 | spin_unlock_irqrestore(&bc->lock, flags); | ||
| 583 | |||
| 584 | return count; | ||
| 585 | } | ||
| 586 | |||
| 587 | /* | ||
| 588 | * Stop sending data to the tty layer | ||
| 589 | * | ||
| 590 | * This function is called when the tty layer's input buffers are getting full, | ||
| 591 | * so the driver should stop sending it data. The easiest way to do this is to | ||
| 592 | * disable the RX IRQ, which will prevent ehv_bc_tty_rx_isr() from being | ||
| 593 | * called. | ||
| 594 | * | ||
| 595 | * The hypervisor will continue to queue up any incoming data. If there is any | ||
| 596 | * data in the queue when the RX interrupt is enabled, we'll immediately get an | ||
| 597 | * RX interrupt. | ||
| 598 | */ | ||
| 599 | static void ehv_bc_tty_throttle(struct tty_struct *ttys) | ||
| 600 | { | ||
| 601 | struct ehv_bc_data *bc = ttys->driver_data; | ||
| 602 | |||
| 603 | disable_irq(bc->rx_irq); | ||
| 604 | } | ||
| 605 | |||
| 606 | /* | ||
| 607 | * Resume sending data to the tty layer | ||
| 608 | * | ||
| 609 | * This function is called after previously calling ehv_bc_tty_throttle(). The | ||
| 610 | * tty layer's input buffers now have more room, so the driver can resume | ||
| 611 | * sending it data. | ||
| 612 | */ | ||
| 613 | static void ehv_bc_tty_unthrottle(struct tty_struct *ttys) | ||
| 614 | { | ||
| 615 | struct ehv_bc_data *bc = ttys->driver_data; | ||
| 616 | |||
| 617 | /* If there is any data in the queue when the RX interrupt is enabled, | ||
| 618 | * we'll immediately get an RX interrupt. | ||
| 619 | */ | ||
| 620 | enable_irq(bc->rx_irq); | ||
| 621 | } | ||
| 622 | |||
| 623 | static void ehv_bc_tty_hangup(struct tty_struct *ttys) | ||
| 624 | { | ||
| 625 | struct ehv_bc_data *bc = ttys->driver_data; | ||
| 626 | |||
| 627 | ehv_bc_tx_dequeue(bc); | ||
| 628 | tty_port_hangup(&bc->port); | ||
| 629 | } | ||
| 630 | |||
| 631 | /* | ||
| 632 | * TTY driver operations | ||
| 633 | * | ||
| 634 | * If we could ask the hypervisor how much data is still in the TX buffer, or | ||
| 635 | * at least how big the TX buffers are, then we could implement the | ||
| 636 | * .wait_until_sent and .chars_in_buffer functions. | ||
| 637 | */ | ||
| 638 | static const struct tty_operations ehv_bc_ops = { | ||
| 639 | .open = ehv_bc_tty_open, | ||
| 640 | .close = ehv_bc_tty_close, | ||
| 641 | .write = ehv_bc_tty_write, | ||
| 642 | .write_room = ehv_bc_tty_write_room, | ||
| 643 | .throttle = ehv_bc_tty_throttle, | ||
| 644 | .unthrottle = ehv_bc_tty_unthrottle, | ||
| 645 | .hangup = ehv_bc_tty_hangup, | ||
| 646 | }; | ||
| 647 | |||
| 648 | /* | ||
| 649 | * initialize the TTY port | ||
| 650 | * | ||
| 651 | * This function will only be called once, no matter how many times | ||
| 652 | * ehv_bc_tty_open() is called. That's why we register the ISR here, and also | ||
| 653 | * why we initialize tty_struct-related variables here. | ||
| 654 | */ | ||
| 655 | static int ehv_bc_tty_port_activate(struct tty_port *port, | ||
| 656 | struct tty_struct *ttys) | ||
| 657 | { | ||
| 658 | struct ehv_bc_data *bc = container_of(port, struct ehv_bc_data, port); | ||
| 659 | int ret; | ||
| 660 | |||
| 661 | ttys->driver_data = bc; | ||
| 662 | |||
| 663 | ret = request_irq(bc->rx_irq, ehv_bc_tty_rx_isr, 0, "ehv-bc", bc); | ||
| 664 | if (ret < 0) { | ||
| 665 | dev_err(bc->dev, "could not request rx irq %u (ret=%i)\n", | ||
| 666 | bc->rx_irq, ret); | ||
| 667 | return ret; | ||
| 668 | } | ||
| 669 | |||
| 670 | /* request_irq also enables the IRQ */ | ||
| 671 | bc->tx_irq_enabled = 1; | ||
| 672 | |||
| 673 | ret = request_irq(bc->tx_irq, ehv_bc_tty_tx_isr, 0, "ehv-bc", bc); | ||
| 674 | if (ret < 0) { | ||
| 675 | dev_err(bc->dev, "could not request tx irq %u (ret=%i)\n", | ||
| 676 | bc->tx_irq, ret); | ||
| 677 | free_irq(bc->rx_irq, bc); | ||
| 678 | return ret; | ||
| 679 | } | ||
| 680 | |||
| 681 | /* The TX IRQ is enabled only when we can't write all the data to the | ||
| 682 | * byte channel at once, so by default it's disabled. | ||
| 683 | */ | ||
| 684 | disable_tx_interrupt(bc); | ||
| 685 | |||
| 686 | return 0; | ||
| 687 | } | ||
| 688 | |||
| 689 | static void ehv_bc_tty_port_shutdown(struct tty_port *port) | ||
| 690 | { | ||
| 691 | struct ehv_bc_data *bc = container_of(port, struct ehv_bc_data, port); | ||
| 692 | |||
| 693 | free_irq(bc->tx_irq, bc); | ||
| 694 | free_irq(bc->rx_irq, bc); | ||
| 695 | } | ||
| 696 | |||
| 697 | static const struct tty_port_operations ehv_bc_tty_port_ops = { | ||
| 698 | .activate = ehv_bc_tty_port_activate, | ||
| 699 | .shutdown = ehv_bc_tty_port_shutdown, | ||
| 700 | }; | ||
| 701 | |||
| 702 | static int __devinit ehv_bc_tty_probe(struct platform_device *pdev) | ||
| 703 | { | ||
| 704 | struct device_node *np = pdev->dev.of_node; | ||
| 705 | struct ehv_bc_data *bc; | ||
| 706 | const uint32_t *iprop; | ||
| 707 | unsigned int handle; | ||
| 708 | int ret; | ||
| 709 | static unsigned int index = 1; | ||
| 710 | unsigned int i; | ||
| 711 | |||
| 712 | iprop = of_get_property(np, "hv-handle", NULL); | ||
| 713 | if (!iprop) { | ||
| 714 | dev_err(&pdev->dev, "no 'hv-handle' property in %s node\n", | ||
| 715 | np->name); | ||
| 716 | return -ENODEV; | ||
| 717 | } | ||
| 718 | |||
| 719 | /* We already told the console layer that the index for the console | ||
| 720 | * device is zero, so we need to make sure that we use that index when | ||
| 721 | * we probe the console byte channel node. | ||
| 722 | */ | ||
| 723 | handle = be32_to_cpu(*iprop); | ||
| 724 | i = (handle == stdout_bc) ? 0 : index++; | ||
| 725 | bc = &bcs[i]; | ||
| 726 | |||
| 727 | bc->handle = handle; | ||
| 728 | bc->head = 0; | ||
| 729 | bc->tail = 0; | ||
| 730 | spin_lock_init(&bc->lock); | ||
| 731 | |||
| 732 | bc->rx_irq = irq_of_parse_and_map(np, 0); | ||
| 733 | bc->tx_irq = irq_of_parse_and_map(np, 1); | ||
| 734 | if ((bc->rx_irq == NO_IRQ) || (bc->tx_irq == NO_IRQ)) { | ||
| 735 | dev_err(&pdev->dev, "no 'interrupts' property in %s node\n", | ||
| 736 | np->name); | ||
| 737 | ret = -ENODEV; | ||
| 738 | goto error; | ||
| 739 | } | ||
| 740 | |||
| 741 | bc->dev = tty_register_device(ehv_bc_driver, i, &pdev->dev); | ||
| 742 | if (IS_ERR(bc->dev)) { | ||
| 743 | ret = PTR_ERR(bc->dev); | ||
| 744 | dev_err(&pdev->dev, "could not register tty (ret=%i)\n", ret); | ||
| 745 | goto error; | ||
| 746 | } | ||
| 747 | |||
| 748 | tty_port_init(&bc->port); | ||
| 749 | bc->port.ops = &ehv_bc_tty_port_ops; | ||
| 750 | |||
| 751 | dev_set_drvdata(&pdev->dev, bc); | ||
| 752 | |||
| 753 | dev_info(&pdev->dev, "registered /dev/%s%u for byte channel %u\n", | ||
| 754 | ehv_bc_driver->name, i, bc->handle); | ||
| 755 | |||
| 756 | return 0; | ||
| 757 | |||
| 758 | error: | ||
| 759 | irq_dispose_mapping(bc->tx_irq); | ||
| 760 | irq_dispose_mapping(bc->rx_irq); | ||
| 761 | |||
| 762 | memset(bc, 0, sizeof(struct ehv_bc_data)); | ||
| 763 | return ret; | ||
| 764 | } | ||
| 765 | |||
| 766 | static int ehv_bc_tty_remove(struct platform_device *pdev) | ||
| 767 | { | ||
| 768 | struct ehv_bc_data *bc = dev_get_drvdata(&pdev->dev); | ||
| 769 | |||
| 770 | tty_unregister_device(ehv_bc_driver, bc - bcs); | ||
| 771 | |||
| 772 | irq_dispose_mapping(bc->tx_irq); | ||
| 773 | irq_dispose_mapping(bc->rx_irq); | ||
| 774 | |||
| 775 | return 0; | ||
| 776 | } | ||
| 777 | |||
| 778 | static const struct of_device_id ehv_bc_tty_of_ids[] = { | ||
| 779 | { .compatible = "epapr,hv-byte-channel" }, | ||
| 780 | {} | ||
| 781 | }; | ||
| 782 | |||
| 783 | static struct platform_driver ehv_bc_tty_driver = { | ||
| 784 | .driver = { | ||
| 785 | .owner = THIS_MODULE, | ||
| 786 | .name = "ehv-bc", | ||
| 787 | .of_match_table = ehv_bc_tty_of_ids, | ||
| 788 | }, | ||
| 789 | .probe = ehv_bc_tty_probe, | ||
| 790 | .remove = ehv_bc_tty_remove, | ||
| 791 | }; | ||
| 792 | |||
| 793 | /** | ||
| 794 | * ehv_bc_init - ePAPR hypervisor byte channel driver initialization | ||
| 795 | * | ||
| 796 | * This function is called when this module is loaded. | ||
| 797 | */ | ||
| 798 | static int __init ehv_bc_init(void) | ||
| 799 | { | ||
| 800 | struct device_node *np; | ||
| 801 | unsigned int count = 0; /* Number of elements in bcs[] */ | ||
| 802 | int ret; | ||
| 803 | |||
| 804 | pr_info("ePAPR hypervisor byte channel driver\n"); | ||
| 805 | |||
| 806 | /* Count the number of byte channels */ | ||
| 807 | for_each_compatible_node(np, NULL, "epapr,hv-byte-channel") | ||
| 808 | count++; | ||
| 809 | |||
| 810 | if (!count) | ||
| 811 | return -ENODEV; | ||
| 812 | |||
| 813 | /* The array index of an element in bcs[] is the same as the tty index | ||
| 814 | * for that element. If you know the address of an element in the | ||
| 815 | * array, then you can use pointer math (e.g. "bc - bcs") to get its | ||
| 816 | * tty index. | ||
| 817 | */ | ||
| 818 | bcs = kzalloc(count * sizeof(struct ehv_bc_data), GFP_KERNEL); | ||
| 819 | if (!bcs) | ||
| 820 | return -ENOMEM; | ||
| 821 | |||
| 822 | ehv_bc_driver = alloc_tty_driver(count); | ||
| 823 | if (!ehv_bc_driver) { | ||
| 824 | ret = -ENOMEM; | ||
| 825 | goto error; | ||
| 826 | } | ||
| 827 | |||
| 828 | ehv_bc_driver->owner = THIS_MODULE; | ||
| 829 | ehv_bc_driver->driver_name = "ehv-bc"; | ||
| 830 | ehv_bc_driver->name = ehv_bc_console.name; | ||
| 831 | ehv_bc_driver->type = TTY_DRIVER_TYPE_CONSOLE; | ||
| 832 | ehv_bc_driver->subtype = SYSTEM_TYPE_CONSOLE; | ||
| 833 | ehv_bc_driver->init_termios = tty_std_termios; | ||
| 834 | ehv_bc_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | ||
| 835 | tty_set_operations(ehv_bc_driver, &ehv_bc_ops); | ||
| 836 | |||
| 837 | ret = tty_register_driver(ehv_bc_driver); | ||
| 838 | if (ret) { | ||
| 839 | pr_err("ehv-bc: could not register tty driver (ret=%i)\n", ret); | ||
| 840 | goto error; | ||
| 841 | } | ||
| 842 | |||
| 843 | ret = platform_driver_register(&ehv_bc_tty_driver); | ||
| 844 | if (ret) { | ||
| 845 | pr_err("ehv-bc: could not register platform driver (ret=%i)\n", | ||
| 846 | ret); | ||
| 847 | goto error; | ||
| 848 | } | ||
| 849 | |||
| 850 | return 0; | ||
| 851 | |||
| 852 | error: | ||
| 853 | if (ehv_bc_driver) { | ||
| 854 | tty_unregister_driver(ehv_bc_driver); | ||
| 855 | put_tty_driver(ehv_bc_driver); | ||
| 856 | } | ||
| 857 | |||
| 858 | kfree(bcs); | ||
| 859 | |||
| 860 | return ret; | ||
| 861 | } | ||
| 862 | |||
| 863 | |||
| 864 | /** | ||
| 865 | * ehv_bc_exit - ePAPR hypervisor byte channel driver termination | ||
| 866 | * | ||
| 867 | * This function is called when this driver is unloaded. | ||
| 868 | */ | ||
| 869 | static void __exit ehv_bc_exit(void) | ||
| 870 | { | ||
| 871 | tty_unregister_driver(ehv_bc_driver); | ||
| 872 | put_tty_driver(ehv_bc_driver); | ||
| 873 | kfree(bcs); | ||
| 874 | } | ||
| 875 | |||
| 876 | module_init(ehv_bc_init); | ||
| 877 | module_exit(ehv_bc_exit); | ||
| 878 | |||
| 879 | MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); | ||
| 880 | MODULE_DESCRIPTION("ePAPR hypervisor byte channel driver"); | ||
| 881 | MODULE_LICENSE("GPL v2"); | ||
| @@ -388,7 +388,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp) · 387 unmodified lines | |||
| 388 | * there is no buffered data otherwise sleeps on a wait queue | 388 | * there is no buffered data otherwise sleeps on a wait queue |
| 389 | * waking periodically to check chars_in_buffer(). | 389 | * waking periodically to check chars_in_buffer(). |
| 390 | */ | 390 | */ |
| 391 | tty_wait_until_sent(tty, HVC_CLOSE_WAIT); | 391 | tty_wait_until_sent_from_close(tty, HVC_CLOSE_WAIT); |
| 392 | } else { | 392 | } else { |
| 393 | if (hp->count < 0) | 393 | if (hp->count < 0) |
| 394 | printk(KERN_ERR "hvc_close %X: oops, count is %d\n", | 394 | printk(KERN_ERR "hvc_close %X: oops, count is %d\n", |
| @@ -852,7 +852,7 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data, · 457 unmodified lines | |||
| 852 | * find index to use: | 852 | * find index to use: |
| 853 | * see if this vterm id matches one registered for console. | 853 | * see if this vterm id matches one registered for console. |
| 854 | */ | 854 | */ |
| 855 | for (i=0; i < MAX_NR_HVC_CONSOLES; i++) | 855 | for (i = 0; i < MAX_NR_HVC_CONSOLES; i++) |
| 856 | if (vtermnos[i] == hp->vtermno && | 856 | if (vtermnos[i] == hp->vtermno && |
| 857 | cons_ops[i] == hp->ops) | 857 | cons_ops[i] == hp->ops) |
| 858 | break; | 858 | break; |
| @@ -862,9 +862,13 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data, · 3 unmodified lines | |||
| 862 | i = ++last_hvc; | 862 | i = ++last_hvc; |
| 863 | 863 | ||
| 864 | hp->index = i; | 864 | hp->index = i; |
| 865 | hvc_console.index = i; | ||
| 866 | vtermnos[i] = vtermno; | ||
| 867 | cons_ops[i] = ops; | ||
| 865 | 868 | ||
| 866 | list_add_tail(&(hp->next), &hvc_structs); | 869 | list_add_tail(&(hp->next), &hvc_structs); |
| 867 | spin_unlock(&hvc_structs_lock); | 870 | spin_unlock(&hvc_structs_lock); |
| 871 | register_console(&hvc_console); | ||
| 868 | 872 | ||
| 869 | return hp; | 873 | return hp; |
| 870 | } | 874 | } |
| @@ -875,6 +879,7 @@ int hvc_remove(struct hvc_struct *hp) · 4 unmodified lines | |||
| 875 | unsigned long flags; | 879 | unsigned long flags; |
| 876 | struct tty_struct *tty; | 880 | struct tty_struct *tty; |
| 877 | 881 | ||
| 882 | unregister_console(&hvc_console); | ||
| 878 | spin_lock_irqsave(&hp->lock, flags); | 883 | spin_lock_irqsave(&hp->lock, flags); |
| 879 | tty = tty_kref_get(hp->tty); | 884 | tty = tty_kref_get(hp->tty); |
| 880 | 885 | ||
| @@ -28,7 +28,7 @@ int notifier_add_irq(struct hvc_struct *hp, int irq) · 27 unmodified lines | |||
| 28 | hp->irq_requested = 0; | 28 | hp->irq_requested = 0; |
| 29 | return 0; | 29 | return 0; |
| 30 | } | 30 | } |
| 31 | rc = request_irq(irq, hvc_handle_interrupt, IRQF_DISABLED, | 31 | rc = request_irq(irq, hvc_handle_interrupt, 0, |
| 32 | "hvc_console", hp); | 32 | "hvc_console", hp); |
| 33 | if (!rc) | 33 | if (!rc) |
| 34 | hp->irq_requested = 1; | 34 | hp->irq_requested = 1; |
| @@ -1057,7 +1057,7 @@ static int hvcs_enable_device(struct hvcs_struct *hvcsd, uint32_t unit_address, · 1056 unmodified lines | |||
| 1057 | * the conn was registered and now. | 1057 | * the conn was registered and now. |
| 1058 | */ | 1058 | */ |
| 1059 | if (!(rc = request_irq(irq, &hvcs_handle_interrupt, | 1059 | if (!(rc = request_irq(irq, &hvcs_handle_interrupt, |
| 1060 | IRQF_DISABLED, "ibmhvcs", hvcsd))) { | 1060 | 0, "ibmhvcs", hvcsd))) { |
| 1061 | /* | 1061 | /* |
| 1062 | * It is possible the vty-server was removed after the irq was | 1062 | * It is possible the vty-server was removed after the irq was |
| 1063 | * requested but before we have time to enable interrupts. | 1063 | * requested but before we have time to enable interrupts. |
| @@ -1237,7 +1237,7 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp) · 173 unmodified lines | |||
| 1237 | irq = hvcsd->vdev->irq; | 1237 | irq = hvcsd->vdev->irq; |
| 1238 | spin_unlock_irqrestore(&hvcsd->lock, flags); | 1238 | spin_unlock_irqrestore(&hvcsd->lock, flags); |
| 1239 | 1239 | ||
| 1240 | tty_wait_until_sent(tty, HVCS_CLOSE_WAIT); | 1240 | tty_wait_until_sent_from_close(tty, HVCS_CLOSE_WAIT); |
| 1241 | 1241 | ||
| 1242 | /* | 1242 | /* |
| 1243 | * This line is important because it tells hvcs_open that this | 1243 | * This line is important because it tells hvcs_open that this |
| @@ -1105,7 +1105,7 @@ static int __init hvsi_init(void) · 1104 unmodified lines | |||
| 1105 | struct hvsi_struct *hp = &hvsi_ports[i]; | 1105 | struct hvsi_struct *hp = &hvsi_ports[i]; |
| 1106 | int ret = 1; | 1106 | int ret = 1; |
| 1107 | 1107 | ||
| 1108 | ret = request_irq(hp->virq, hvsi_interrupt, IRQF_DISABLED, "hvsi", hp); | 1108 | ret = request_irq(hp->virq, hvsi_interrupt, 0, "hvsi", hp); |
| 1109 | if (ret) | 1109 | if (ret) |
| 1110 | printk(KERN_ERR "HVSI: couldn't reserve irq 0x%x (error %i)\n", | 1110 | printk(KERN_ERR "HVSI: couldn't reserve irq 0x%x (error %i)\n", |
| 1111 | hp->virq, ret); | 1111 | hp->virq, ret); |
| @@ -1598,7 +1598,7 @@ static int __devinit isicom_probe(struct pci_dev *pdev, · 1597 unmodified lines | |||
| 1598 | } | 1598 | } |
| 1599 | 1599 | ||
| 1600 | retval = request_irq(board->irq, isicom_interrupt, | 1600 | retval = request_irq(board->irq, isicom_interrupt, |
| 1601 | IRQF_SHARED | IRQF_DISABLED, ISICOM_NAME, board); | 1601 | IRQF_SHARED, ISICOM_NAME, board); |
| 1602 | if (retval < 0) { | 1602 | if (retval < 0) { |
| 1603 | dev_err(&pdev->dev, "Could not install handler at Irq %d. " | 1603 | dev_err(&pdev->dev, "Could not install handler at Irq %d. " |
| 1604 | "Card%d will be disabled.\n", board->irq, index + 1); | 1604 | "Card%d will be disabled.\n", board->irq, index + 1); |
| @@ -2005,16 +2005,9 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout) · 2004 unmodified lines | |||
| 2005 | */ | 2005 | */ |
| 2006 | if (!timeout || timeout > 2 * info->timeout) | 2006 | if (!timeout || timeout > 2 * info->timeout) |
| 2007 | timeout = 2 * info->timeout; | 2007 | timeout = 2 * info->timeout; |
| 2008 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT | 2008 | |
| 2009 | printk(KERN_DEBUG "In rs_wait_until_sent(%d) check=%lu...", | ||
| 2010 | timeout, char_time); | ||
| 2011 | printk("jiff=%lu...", jiffies); | ||
| 2012 | #endif | ||
| 2013 | spin_lock_irqsave(&info->slock, flags); | 2009 | spin_lock_irqsave(&info->slock, flags); |
| 2014 | while (!((lsr = inb(info->ioaddr + UART_LSR)) & UART_LSR_TEMT)) { | 2010 | while (!((lsr = inb(info->ioaddr + UART_LSR)) & UART_LSR_TEMT)) { |
| 2015 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT | ||
| 2016 | printk("lsr = %d (jiff=%lu)...", lsr, jiffies); | ||
| 2017 | #endif | ||
| 2018 | spin_unlock_irqrestore(&info->slock, flags); | 2011 | spin_unlock_irqrestore(&info->slock, flags); |
| 2019 | schedule_timeout_interruptible(char_time); | 2012 | schedule_timeout_interruptible(char_time); |
| 2020 | spin_lock_irqsave(&info->slock, flags); | 2013 | spin_lock_irqsave(&info->slock, flags); |
| @@ -2025,10 +2018,6 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout) · 4 unmodified lines | |||
| 2025 | } | 2018 | } |
| 2026 | spin_unlock_irqrestore(&info->slock, flags); | 2019 | spin_unlock_irqrestore(&info->slock, flags); |
| 2027 | set_current_state(TASK_RUNNING); | 2020 | set_current_state(TASK_RUNNING); |
| 2028 | |||
| 2029 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT | ||
| 2030 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); | ||
| 2031 | #endif | ||
| 2032 | } | 2021 | } |
| 2033 | 2022 | ||
| 2034 | /* | 2023 | /* |
| @@ -21,7 +21,6 @@ · 20 unmodified lines | |||
| 21 | * Mostly done: ioctls for setting modes/timing | 21 | * Mostly done: ioctls for setting modes/timing |
| 22 | * Partly done: hooks so you can pull off frames to non tty devs | 22 | * Partly done: hooks so you can pull off frames to non tty devs |
| 23 | * Restart DLCI 0 when it closes ? | 23 | * Restart DLCI 0 when it closes ? |
| 24 | * Test basic encoding | ||
| 25 | * Improve the tx engine | 24 | * Improve the tx engine |
| 26 | * Resolve tx side locking by adding a queue_head and routing | 25 | * Resolve tx side locking by adding a queue_head and routing |
| 27 | * all control traffic via it | 26 | * all control traffic via it |
| @@ -810,38 +809,41 @@ static int gsm_dlci_data_output(struct gsm_mux *gsm, struct gsm_dlci *dlci) · 782 unmodified lines | |||
| 810 | { | 809 | { |
| 811 | struct gsm_msg *msg; | 810 | struct gsm_msg *msg; |
| 812 | u8 *dp; | 811 | u8 *dp; |
| 813 | int len, size; | 812 | int len, total_size, size; |
| 814 | int h = dlci->adaption - 1; | 813 | int h = dlci->adaption - 1; |
| 815 | 814 | ||
| 816 | len = kfifo_len(dlci->fifo); | 815 | total_size = 0; |
| 817 | if (len == 0) | 816 | while(1) { |
| 818 | return 0; | 817 | len = kfifo_len(dlci->fifo); |
| 819 | 818 | if (len == 0) | |
| 820 | /* MTU/MRU count only the data bits */ | 819 | return total_size; |
| 821 | if (len > gsm->mtu) | 820 | |
| 822 | len = gsm->mtu; | 821 | /* MTU/MRU count only the data bits */ |
| 823 | 822 | if (len > gsm->mtu) | |
| 824 | size = len + h; | 823 | len = gsm->mtu; |
| 825 | 824 | ||
| 826 | msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype); | 825 | size = len + h; |
| 827 | /* FIXME: need a timer or something to kick this so it can't | 826 | |
| 828 | get stuck with no work outstanding and no buffer free */ | 827 | msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype); |
| 829 | if (msg == NULL) | 828 | /* FIXME: need a timer or something to kick this so it can't |
| 830 | return -ENOMEM; | 829 | get stuck with no work outstanding and no buffer free */ |
| 831 | dp = msg->data; | 830 | if (msg == NULL) |
| 832 | switch (dlci->adaption) { | 831 | return -ENOMEM; |
| 833 | case 1: /* Unstructured */ | 832 | dp = msg->data; |
| 834 | break; | 833 | switch (dlci->adaption) { |
| 835 | case 2: /* Unstructed with modem bits. Always one byte as we never | 834 | case 1: /* Unstructured */ |
| 836 | send inline break data */ | 835 | break; |
| 837 | *dp += gsm_encode_modem(dlci); | 836 | case 2: /* Unstructed with modem bits. Always one byte as we never |
| 838 | len--; | 837 | send inline break data */ |
| 839 | break; | 838 | *dp++ = gsm_encode_modem(dlci); |
| 839 | break; | ||
| 840 | } | ||
| 841 | WARN_ON(kfifo_out_locked(dlci->fifo, dp , len, &dlci->lock) != len); | ||
| 842 | __gsm_data_queue(dlci, msg); | ||
| 843 | total_size += size; | ||
| 840 | } | 844 | } |
| 841 | WARN_ON(kfifo_out_locked(dlci->fifo, dp , len, &dlci->lock) != len); | ||
| 842 | __gsm_data_queue(dlci, msg); | ||
| 843 | /* Bytes of data we used up */ | 845 | /* Bytes of data we used up */ |
| 844 | return size; | 846 | return total_size; |
| 845 | } | 847 | } |
| 846 | 848 | ||
| 847 | /** | 849 | /** |
| @@ -2004,6 +2006,7 @@ void gsm_cleanup_mux(struct gsm_mux *gsm) · 1156 unmodified lines | |||
| 2004 | int i; | 2006 | int i; |
| 2005 | struct gsm_dlci *dlci = gsm->dlci[0]; | 2007 | struct gsm_dlci *dlci = gsm->dlci[0]; |
| 2006 | struct gsm_msg *txq; | 2008 | struct gsm_msg *txq; |
| 2009 | struct gsm_control *gc; | ||
| 2007 | 2010 | ||
| 2008 | gsm->dead = 1; | 2011 | gsm->dead = 1; |
| 2009 | 2012 | ||
| @@ -2017,6 +2020,13 @@ void gsm_cleanup_mux(struct gsm_mux *gsm) · 7 unmodified lines | |||
| 2017 | spin_unlock(&gsm_mux_lock); | 2020 | spin_unlock(&gsm_mux_lock); |
| 2018 | WARN_ON(i == MAX_MUX); | 2021 | WARN_ON(i == MAX_MUX); |
| 2019 | 2022 | ||
| 2023 | /* In theory disconnecting DLCI 0 is sufficient but for some | ||
| 2024 | modems this is apparently not the case. */ | ||
| 2025 | if (dlci) { | ||
| 2026 | gc = gsm_control_send(gsm, CMD_CLD, NULL, 0); | ||
| 2027 | if (gc) | ||
| 2028 | gsm_control_wait(gsm, gc); | ||
| 2029 | } | ||
| 2020 | del_timer_sync(&gsm->t2_timer); | 2030 | del_timer_sync(&gsm->t2_timer); |
| 2021 | /* Now we are sure T2 has stopped */ | 2031 | /* Now we are sure T2 has stopped */ |
| 2022 | if (dlci) { | 2032 | if (dlci) { |
| @@ -2982,7 +2992,7 @@ static int gsmtty_tiocmset(struct tty_struct *tty, · 959 unmodified lines | |||
| 2982 | struct gsm_dlci *dlci = tty->driver_data; | 2992 | struct gsm_dlci *dlci = tty->driver_data; |
| 2983 | unsigned int modem_tx = dlci->modem_tx; | 2993 | unsigned int modem_tx = dlci->modem_tx; |
| 2984 | 2994 | ||
| 2985 | modem_tx &= clear; | 2995 | modem_tx &= ~clear; |
| 2986 | modem_tx |= set; | 2996 | modem_tx |= set; |
| 2987 | 2997 | ||
| 2988 | if (modem_tx != dlci->modem_tx) { | 2998 | if (modem_tx != dlci->modem_tx) { |
| @@ -670,12 +670,18 @@ static int ptmx_open(struct inode *inode, struct file *filp) · 669 unmodified lines | |||
| 670 | 670 | ||
| 671 | nonseekable_open(inode, filp); | 671 | nonseekable_open(inode, filp); |
| 672 | 672 | ||
| 673 | retval = tty_alloc_file(filp); | ||
| 674 | if (retval) | ||
| 675 | return retval; | ||
| 676 | |||
| 673 | /* find a device that is not in use. */ | 677 | /* find a device that is not in use. */ |
| 674 | tty_lock(); | 678 | tty_lock(); |
| 675 | index = devpts_new_index(inode); | 679 | index = devpts_new_index(inode); |
| 676 | tty_unlock(); | 680 | tty_unlock(); |
| 677 | if (index < 0) | 681 | if (index < 0) { |
| 678 | return index; | 682 | retval = index; |
| 683 | goto err_file; | ||
| 684 | } | ||
| 679 | 685 | ||
| 680 | mutex_lock(&tty_mutex); | 686 | mutex_lock(&tty_mutex); |
| 681 | tty_lock(); | 687 | tty_lock(); |
| @@ -689,27 +695,27 @@ static int ptmx_open(struct inode *inode, struct file *filp) · 7 unmodified lines | |||
| 689 | 695 | ||
| 690 | set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ | 696 | set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ |
| 691 | 697 | ||
| 692 | retval = tty_add_file(tty, filp); | 698 | tty_add_file(tty, filp); |
| 693 | if (retval) | ||
| 694 | goto out; | ||
| 695 | 699 | ||
| 696 | retval = devpts_pty_new(inode, tty->link); | 700 | retval = devpts_pty_new(inode, tty->link); |
| 697 | if (retval) | 701 | if (retval) |
| 698 | goto out1; | 702 | goto err_release; |
| 699 | 703 | ||
| 700 | retval = ptm_driver->ops->open(tty, filp); | 704 | retval = ptm_driver->ops->open(tty, filp); |
| 701 | if (retval) | 705 | if (retval) |
| 702 | goto out2; | 706 | goto err_release; |
| 703 | out1: | 707 | |
| 704 | tty_unlock(); | 708 | tty_unlock(); |
| 705 | return retval; | 709 | return 0; |
| 706 | out2: | 710 | err_release: |
| 707 | tty_unlock(); | 711 | tty_unlock(); |
| 708 | tty_release(inode, filp); | 712 | tty_release(inode, filp); |
| 709 | return retval; | 713 | return retval; |
| 710 | out: | 714 | out: |
| 711 | devpts_kill_index(inode, index); | 715 | devpts_kill_index(inode, index); |
| 712 | tty_unlock(); | 716 | tty_unlock(); |
| 717 | err_file: | ||
| 718 | tty_free_file(filp); | ||
| 713 | return retval; | 719 | return retval; |
| 714 | } | 720 | } |
| 715 | 721 | ||
| @@ -235,22 +235,6 @@ static void batten_down_hatches(void) · 234 unmodified lines | |||
| 235 | 235 | ||
| 236 | static void status_handle(struct m68k_serial *info, unsigned short status) | 236 | static void status_handle(struct m68k_serial *info, unsigned short status) |
| 237 | { | 237 | { |
| 238 | #if 0 | ||
| 239 | if(status & DCD) { | ||
| 240 | if((info->port.tty->termios->c_cflag & CRTSCTS) && | ||
| 241 | ((info->curregs[3] & AUTO_ENAB)==0)) { | ||
| 242 | info->curregs[3] |= AUTO_ENAB; | ||
| 243 | info->pendregs[3] |= AUTO_ENAB; | ||
| 244 | write_zsreg(info->m68k_channel, 3, info->curregs[3]); | ||
| 245 | } | ||
| 246 | } else { | ||
| 247 | if((info->curregs[3] & AUTO_ENAB)) { | ||
| 248 | info->curregs[3] &= ~AUTO_ENAB; | ||
| 249 | info->pendregs[3] &= ~AUTO_ENAB; | ||
| 250 | write_zsreg(info->m68k_channel, 3, info->curregs[3]); | ||
| 251 | } | ||
| 252 | } | ||
| 253 | #endif | ||
| 254 | /* If this is console input and this is a | 238 | /* If this is console input and this is a |
| 255 | * 'break asserted' status change interrupt | 239 | * 'break asserted' status change interrupt |
| 256 | * see if we can drop into the debugger | 240 | * see if we can drop into the debugger |
| @@ -340,9 +324,6 @@ static void transmit_chars(struct m68k_serial *info) · 83 unmodified lines | |||
| 340 | info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); | 324 | info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); |
| 341 | info->xmit_cnt--; | 325 | info->xmit_cnt--; |
| 342 | 326 | ||
| 343 | if (info->xmit_cnt < WAKEUP_CHARS) | ||
| 344 | schedule_work(&info->tqueue); | ||
| 345 | |||
| 346 | if(info->xmit_cnt <= 0) { | 327 | if(info->xmit_cnt <= 0) { |
| 347 | /* All done for now... TX ints off */ | 328 | /* All done for now... TX ints off */ |
| 348 | uart->ustcnt &= ~USTCNT_TX_INTR_MASK; | 329 | uart->ustcnt &= ~USTCNT_TX_INTR_MASK; |
| @@ -378,21 +359,6 @@ irqreturn_t rs_interrupt(int irq, void *dev_id) · 29 unmodified lines | |||
| 378 | return IRQ_HANDLED; | 359 | return IRQ_HANDLED; |
| 379 | } | 360 | } |
| 380 | 361 | ||
| 381 | static void do_softint(struct work_struct *work) | ||
| 382 | { | ||
| 383 | struct m68k_serial *info = container_of(work, struct m68k_serial, tqueue); | ||
| 384 | struct tty_struct *tty; | ||
| 385 | |||
| 386 | tty = info->tty; | ||
| 387 | if (!tty) | ||
| 388 | return; | ||
| 389 | #if 0 | ||
| 390 | if (clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { | ||
| 391 | tty_wakeup(tty); | ||
| 392 | } | ||
| 393 | #endif | ||
| 394 | } | ||
| 395 | |||
| 396 | static int startup(struct m68k_serial * info) | 362 | static int startup(struct m68k_serial * info) |
| 397 | { | 363 | { |
| 398 | m68328_uart *uart = &uart_addr[info->line]; | 364 | m68328_uart *uart = &uart_addr[info->line]; |
| @@ -1324,7 +1290,6 @@ rs68328_init(void) · 925 unmodified lines | |||
| 1324 | info->event = 0; | 1290 | info->event = 0; |
| 1325 | info->count = 0; | 1291 | info->count = 0; |
| 1326 | info->blocked_open = 0; | 1292 | info->blocked_open = 0; |
| 1327 | INIT_WORK(&info->tqueue, do_softint); | ||
| 1328 | init_waitqueue_head(&info->open_wait); | 1293 | init_waitqueue_head(&info->open_wait); |
| 1329 | init_waitqueue_head(&info->close_wait); | 1294 | init_waitqueue_head(&info->close_wait); |
| 1330 | info->line = i; | 1295 | info->line = i; |
| @@ -1341,7 +1306,7 @@ rs68328_init(void) · 10 unmodified lines | |||
| 1341 | 1306 | ||
| 1342 | if (request_irq(uart_irqs[i], | 1307 | if (request_irq(uart_irqs[i], |
| 1343 | rs_interrupt, | 1308 | rs_interrupt, |
| 1344 | IRQF_DISABLED, | 1309 | 0, |
| 1345 | "M68328_UART", info)) | 1310 | "M68328_UART", info)) |
| 1346 | panic("Unable to attach 68328 serial interrupt\n"); | 1311 | panic("Unable to attach 68328 serial interrupt\n"); |
| 1347 | } | 1312 | } |
| @@ -158,7 +158,6 @@ struct m68k_serial { · 157 unmodified lines | |||
| 158 | int xmit_head; | 158 | int xmit_head; |
| 159 | int xmit_tail; | 159 | int xmit_tail; |
| 160 | int xmit_cnt; | 160 | int xmit_cnt; |
| 161 | struct work_struct tqueue; | ||
| 162 | wait_queue_head_t open_wait; | 161 | wait_queue_head_t open_wait; |
| 163 | wait_queue_head_t close_wait; | 162 | wait_queue_head_t close_wait; |
| 164 | }; | 163 | }; |
| @@ -309,6 +309,13 @@ static const struct serial8250_config uart_config[] = { · 308 unmodified lines | |||
| 309 | UART_FCR_T_TRIG_01, | 309 | UART_FCR_T_TRIG_01, |
| 310 | .flags = UART_CAP_FIFO | UART_CAP_RTOIE, | 310 | .flags = UART_CAP_FIFO | UART_CAP_RTOIE, |
| 311 | }, | 311 | }, |
| 312 | [PORT_XR17D15X] = { | ||
| 313 | .name = "XR17D15X", | ||
| 314 | .fifo_size = 64, | ||
| 315 | .tx_loadsz = 64, | ||
| 316 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | ||
| 317 | .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR, | ||
| 318 | }, | ||
| 312 | }; | 319 | }; |
| 313 | 320 | ||
| 314 | #if defined(CONFIG_MIPS_ALCHEMY) | 321 | #if defined(CONFIG_MIPS_ALCHEMY) |
| @@ -461,42 +468,6 @@ static void tsi_serial_out(struct uart_port *p, int offset, int value) · 146 unmodified lines | |||
| 461 | writeb(value, p->membase + offset); | 468 | writeb(value, p->membase + offset); |
| 462 | } | 469 | } |
| 463 | 470 | ||
| 464 | /* Save the LCR value so it can be re-written when a Busy Detect IRQ occurs. */ | ||
| 465 | static inline void dwapb_save_out_value(struct uart_port *p, int offset, | ||
| 466 | int value) | ||
| 467 | { | ||
| 468 | struct uart_8250_port *up = | ||
| 469 | container_of(p, struct uart_8250_port, port); | ||
| 470 | |||
| 471 | if (offset == UART_LCR) | ||
| 472 | up->lcr = value; | ||
| 473 | } | ||
| 474 | |||
| 475 | /* Read the IER to ensure any interrupt is cleared before returning from ISR. */ | ||
| 476 | static inline void dwapb_check_clear_ier(struct uart_port *p, int offset) | ||
| 477 | { | ||
| 478 | if (offset == UART_TX || offset == UART_IER) | ||
| 479 | p->serial_in(p, UART_IER); | ||
| 480 | } | ||
| 481 | |||
| 482 | static void dwapb_serial_out(struct uart_port *p, int offset, int value) | ||
| 483 | { | ||
| 484 | int save_offset = offset; | ||
| 485 | offset = map_8250_out_reg(p, offset) << p->regshift; | ||
| 486 | dwapb_save_out_value(p, save_offset, value); | ||
| 487 | writeb(value, p->membase + offset); | ||
| 488 | dwapb_check_clear_ier(p, save_offset); | ||
| 489 | } | ||
| 490 | |||
| 491 | static void dwapb32_serial_out(struct uart_port *p, int offset, int value) | ||
| 492 | { | ||
| 493 | int save_offset = offset; | ||
| 494 | offset = map_8250_out_reg(p, offset) << p->regshift; | ||
| 495 | dwapb_save_out_value(p, save_offset, value); | ||
| 496 | writel(value, p->membase + offset); | ||
| 497 | dwapb_check_clear_ier(p, save_offset); | ||
| 498 | } | ||
| 499 | |||
| 500 | static unsigned int io_serial_in(struct uart_port *p, int offset) | 471 | static unsigned int io_serial_in(struct uart_port *p, int offset) |
| 501 | { | 472 | { |
| 502 | offset = map_8250_in_reg(p, offset) << p->regshift; | 473 | offset = map_8250_in_reg(p, offset) << p->regshift; |
| @@ -509,6 +480,8 @@ static void io_serial_out(struct uart_port *p, int offset, int value) · 6 unmodified lines | |||
| 509 | outb(value, p->iobase + offset); | 480 | outb(value, p->iobase + offset); |
| 510 | } | 481 | } |
| 511 | 482 | ||
| 483 | static int serial8250_default_handle_irq(struct uart_port *port); | ||
| 484 | |||
| 512 | static void set_io_from_upio(struct uart_port *p) | 485 | static void set_io_from_upio(struct uart_port *p) |
| 513 | { | 486 | { |
| 514 | struct uart_8250_port *up = | 487 | struct uart_8250_port *up = |
| @@ -540,16 +513,6 @@ static void set_io_from_upio(struct uart_port *p) · 25 unmodified lines | |||
| 540 | p->serial_out = tsi_serial_out; | 513 | p->serial_out = tsi_serial_out; |
| 541 | break; | 514 | break; |
| 542 | 515 | ||
| 543 | case UPIO_DWAPB: | ||
| 544 | p->serial_in = mem_serial_in; | ||
| 545 | p->serial_out = dwapb_serial_out; | ||
| 546 | break; | ||
| 547 | |||
| 548 | case UPIO_DWAPB32: | ||
| 549 | p->serial_in = mem32_serial_in; | ||
| 550 | p->serial_out = dwapb32_serial_out; | ||
| 551 | break; | ||
| 552 | |||
| 553 | default: | 516 | default: |
| 554 | p->serial_in = io_serial_in; | 517 | p->serial_in = io_serial_in; |
| 555 | p->serial_out = io_serial_out; | 518 | p->serial_out = io_serial_out; |
| @@ -557,6 +520,7 @@ static void set_io_from_upio(struct uart_port *p) · 1 unmodified line | |||
| 557 | } | 520 | } |
| 558 | /* Remember loaded iotype */ | 521 | /* Remember loaded iotype */ |
| 559 | up->cur_iotype = p->iotype; | 522 | up->cur_iotype = p->iotype; |
| 523 | p->handle_irq = serial8250_default_handle_irq; | ||
| 560 | } | 524 | } |
| 561 | 525 | ||
| 562 | static void | 526 | static void |
| @@ -567,8 +531,6 @@ serial_out_sync(struct uart_8250_port *up, int offset, int value) · 4 unmodified lines | |||
| 567 | case UPIO_MEM: | 531 | case UPIO_MEM: |
| 568 | case UPIO_MEM32: | 532 | case UPIO_MEM32: |
| 569 | case UPIO_AU: | 533 | case UPIO_AU: |
| 570 | case UPIO_DWAPB: | ||
| 571 | case UPIO_DWAPB32: | ||
| 572 | p->serial_out(p, offset, value); | 534 | p->serial_out(p, offset, value); |
| 573 | p->serial_in(p, UART_LCR); /* safe, no side-effects */ | 535 | p->serial_in(p, UART_LCR); /* safe, no side-effects */ |
| 574 | break; | 536 | break; |
| @@ -1119,6 +1081,14 @@ static void autoconfig_16550a(struct uart_8250_port *up) · 544 unmodified lines | |||
| 1119 | } | 1081 | } |
| 1120 | serial_outp(up, UART_IER, iersave); | 1082 | serial_outp(up, UART_IER, iersave); |
| 1121 | 1083 | ||
| 1084 | /* | ||
| 1085 | * Exar uarts have EFR in a weird location | ||
| 1086 | */ | ||
| 1087 | if (up->port.flags & UPF_EXAR_EFR) { | ||
| 1088 | up->port.type = PORT_XR17D15X; | ||
| 1089 | up->capabilities |= UART_CAP_AFE | UART_CAP_EFR; | ||
| 1090 | } | ||
| 1091 | |||
| 1122 | /* | 1092 | /* |
| 1123 | * We distinguish between 16550A and U6 16550A by counting | 1093 | * We distinguish between 16550A and U6 16550A by counting |
| 1124 | * how many bytes are in the FIFO. | 1094 | * how many bytes are in the FIFO. |
| @@ -1621,6 +1591,29 @@ static void serial8250_handle_port(struct uart_8250_port *up) · 496 unmodified lines | |||
| 1621 | spin_unlock_irqrestore(&up->port.lock, flags); | 1591 | spin_unlock_irqrestore(&up->port.lock, flags); |
| 1622 | } | 1592 | } |
| 1623 | 1593 | ||
| 1594 | int serial8250_handle_irq(struct uart_port *port, unsigned int iir) | ||
| 1595 | { | ||
| 1596 | struct uart_8250_port *up = | ||
| 1597 | container_of(port, struct uart_8250_port, port); | ||
| 1598 | |||
| 1599 | if (!(iir & UART_IIR_NO_INT)) { | ||
| 1600 | serial8250_handle_port(up); | ||
| 1601 | return 1; | ||
| 1602 | } | ||
| 1603 | |||
| 1604 | return 0; | ||
| 1605 | } | ||
| 1606 | EXPORT_SYMBOL_GPL(serial8250_handle_irq); | ||
| 1607 | |||
| 1608 | static int serial8250_default_handle_irq(struct uart_port *port) | ||
| 1609 | { | ||
| 1610 | struct uart_8250_port *up = | ||
| 1611 | container_of(port, struct uart_8250_port, port); | ||
| 1612 | unsigned int iir = serial_in(up, UART_IIR); | ||
| 1613 | |||
| 1614 | return serial8250_handle_irq(port, iir); | ||
| 1615 | } | ||
| 1616 | |||
| 1624 | /* | 1617 | /* |
| 1625 | * This is the serial driver's interrupt routine. | 1618 | * This is the serial driver's interrupt routine. |
| 1626 | * | 1619 | * |
| @@ -1648,30 +1641,13 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id) · 21 unmodified lines | |||
| 1648 | l = i->head; | 1641 | l = i->head; |
| 1649 | do { | 1642 | do { |
| 1650 | struct uart_8250_port *up; | 1643 | struct uart_8250_port *up; |
| 1651 | unsigned int iir; | 1644 | struct uart_port *port; |
| 1652 | 1645 | ||
| 1653 | up = list_entry(l, struct uart_8250_port, list); | 1646 | up = list_entry(l, struct uart_8250_port, list); |
| 1647 | port = &up->port; | ||
| 1654 | 1648 | ||
| 1655 | iir = serial_in(up, UART_IIR); | 1649 | if (port->handle_irq(port)) { |
| 1656 | if (!(iir & UART_IIR_NO_INT)) { | ||
| 1657 | serial8250_handle_port(up); | ||
| 1658 | |||
| 1659 | handled = 1; | 1650 | handled = 1; |
| 1660 | |||
| 1661 | end = NULL; | ||
| 1662 | } else if ((up->port.iotype == UPIO_DWAPB || | ||
| 1663 | up->port.iotype == UPIO_DWAPB32) && | ||
| 1664 | (iir & UART_IIR_BUSY) == UART_IIR_BUSY) { | ||
| 1665 | /* The DesignWare APB UART has an Busy Detect (0x07) | ||
| 1666 | * interrupt meaning an LCR write attempt occurred while the | ||
| 1667 | * UART was busy. The interrupt must be cleared by reading | ||
| 1668 | * the UART status register (USR) and the LCR re-written. */ | ||
| 1669 | unsigned int status; | ||
| 1670 | status = *(volatile u32 *)up->port.private_data; | ||
| 1671 | serial_out(up, UART_LCR, up->lcr); | ||
| 1672 | |||
| 1673 | handled = 1; | ||
| 1674 | |||
| 1675 | end = NULL; | 1651 | end = NULL; |
| 1676 | } else if (end == NULL) | 1652 | } else if (end == NULL) |
| 1677 | end = l; | 1653 | end = l; |
| @@ -2081,8 +2057,8 @@ static int serial8250_startup(struct uart_port *port) · 403 unmodified lines | |||
| 2081 | */ | 2057 | */ |
| 2082 | if (!(up->port.flags & UPF_BUGGY_UART) && | 2058 | if (!(up->port.flags & UPF_BUGGY_UART) && |
| 2083 | (serial_inp(up, UART_LSR) == 0xff)) { | 2059 | (serial_inp(up, UART_LSR) == 0xff)) { |
| 2084 | printk(KERN_INFO "ttyS%d: LSR safety check engaged!\n", | 2060 | printk_ratelimited(KERN_INFO "ttyS%d: LSR safety check engaged!\n", |
| 2085 | serial_index(&up->port)); | 2061 | serial_index(&up->port)); |
| 2086 | return -ENODEV; | 2062 | return -ENODEV; |
| 2087 | } | 2063 | } |
| 2088 | 2064 | ||
| @@ -2458,7 +2434,10 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, · 369 unmodified lines | |||
| 2458 | efr |= UART_EFR_CTS; | 2434 | efr |= UART_EFR_CTS; |
| 2459 | 2435 | ||
| 2460 | serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); | 2436 | serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); |
| 2461 | serial_outp(up, UART_EFR, efr); | 2437 | if (up->port.flags & UPF_EXAR_EFR) |
| 2438 | serial_outp(up, UART_XR_EFR, efr); | ||
| 2439 | else | ||
| 2440 | serial_outp(up, UART_EFR, efr); | ||
| 2462 | } | 2441 | } |
| 2463 | 2442 | ||
| 2464 | #ifdef CONFIG_ARCH_OMAP | 2443 | #ifdef CONFIG_ARCH_OMAP |
| @@ -2570,8 +2549,6 @@ static int serial8250_request_std_resource(struct uart_8250_port *up) · 105 unmodified lines | |||
| 2570 | case UPIO_TSI: | 2549 | case UPIO_TSI: |
| 2571 | case UPIO_MEM32: | 2550 | case UPIO_MEM32: |
| 2572 | case UPIO_MEM: | 2551 | case UPIO_MEM: |
| 2573 | case UPIO_DWAPB: | ||
| 2574 | case UPIO_DWAPB32: | ||
| 2575 | if (!up->port.mapbase) | 2552 | if (!up->port.mapbase) |
| 2576 | break; | 2553 | break; |
| 2577 | 2554 | ||
| @@ -2608,8 +2585,6 @@ static void serial8250_release_std_resource(struct uart_8250_port *up) · 30 unmodified lines | |||
| 2608 | case UPIO_TSI: | 2585 | case UPIO_TSI: |
| 2609 | case UPIO_MEM32: | 2586 | case UPIO_MEM32: |
| 2610 | case UPIO_MEM: | 2587 | case UPIO_MEM: |
| 2611 | case UPIO_DWAPB: | ||
| 2612 | case UPIO_DWAPB32: | ||
| 2613 | if (!up->port.mapbase) | 2588 | if (!up->port.mapbase) |
| 2614 | break; | 2589 | break; |
| 2615 | 2590 | ||
| @@ -3050,6 +3025,10 @@ int __init early_serial_setup(struct uart_port *port) · 434 unmodified lines | |||
| 3050 | p->serial_in = port->serial_in; | 3025 | p->serial_in = port->serial_in; |
| 3051 | if (port->serial_out) | 3026 | if (port->serial_out) |
| 3052 | p->serial_out = port->serial_out; | 3027 | p->serial_out = port->serial_out; |
| 3028 | if (port->handle_irq) | ||
| 3029 | p->handle_irq = port->handle_irq; | ||
| 3030 | else | ||
| 3031 | p->handle_irq = serial8250_default_handle_irq; | ||
| 3053 | 3032 | ||
| 3054 | return 0; | 3033 | return 0; |
| 3055 | } | 3034 | } |
| @@ -3118,6 +3097,7 @@ static int __devinit serial8250_probe(struct platform_device *dev) · 62 unmodified lines | |||
| 3118 | port.type = p->type; | 3097 | port.type = p->type; |
| 3119 | port.serial_in = p->serial_in; | 3098 | port.serial_in = p->serial_in; |
| 3120 | port.serial_out = p->serial_out; | 3099 | port.serial_out = p->serial_out; |
| 3100 | port.handle_irq = p->handle_irq; | ||
| 3121 | port.set_termios = p->set_termios; | 3101 | port.set_termios = p->set_termios; |
| 3122 | port.pm = p->pm; | 3102 | port.pm = p->pm; |
| 3123 | port.dev = &dev->dev; | 3103 | port.dev = &dev->dev; |
| @@ -3283,6 +3263,8 @@ int serial8250_register_port(struct uart_port *port) · 159 unmodified lines | |||
| 3283 | uart->port.serial_in = port->serial_in; | 3263 | uart->port.serial_in = port->serial_in; |
| 3284 | if (port->serial_out) | 3264 | if (port->serial_out) |
| 3285 | uart->port.serial_out = port->serial_out; | 3265 | uart->port.serial_out = port->serial_out; |
| 3266 | if (port->handle_irq) | ||
| 3267 | uart->port.handle_irq = port->handle_irq; | ||
| 3286 | /* Possibly override set_termios call */ | 3268 | /* Possibly override set_termios call */ |
| 3287 | if (port->set_termios) | 3269 | if (port->set_termios) |
| 3288 | uart->port.set_termios = port->set_termios; | 3270 | uart->port.set_termios = port->set_termios; |
| @@ -0,0 +1,194 @@ | |||
| 1 | /* | ||
| 2 | * Synopsys DesignWare 8250 driver. | ||
| 3 | * | ||
| 4 | * Copyright 2011 Picochip, Jamie Iles. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * The Synopsys DesignWare 8250 has an extra feature whereby it detects if the | ||
| 12 | * LCR is written whilst busy. If it is, then a busy detect interrupt is | ||
| 13 | * raised, the LCR needs to be rewritten and the uart status register read. | ||
| 14 | */ | ||
| 15 | #include <linux/device.h> | ||
| 16 | #include <linux/init.h> | ||
| 17 | #include <linux/io.h> | ||
| 18 | #include <linux/module.h> | ||
| 19 | #include <linux/serial_8250.h> | ||
| 20 | #include <linux/serial_core.h> | ||
| 21 | #include <linux/serial_reg.h> | ||
| 22 | #include <linux/of.h> | ||
| 23 | #include <linux/of_irq.h> | ||
| 24 | #include <linux/of_platform.h> | ||
| 25 | #include <linux/platform_device.h> | ||
| 26 | #include <linux/slab.h> | ||
| 27 | |||
| 28 | struct dw8250_data { | ||
| 29 | int last_lcr; | ||
| 30 | int line; | ||
| 31 | }; | ||
| 32 | |||
| 33 | static void dw8250_serial_out(struct uart_port *p, int offset, int value) | ||
| 34 | { | ||
| 35 | struct dw8250_data *d = p->private_data; | ||
| 36 | |||
| 37 | if (offset == UART_LCR) | ||
| 38 | d->last_lcr = value; | ||
| 39 | |||
| 40 | offset <<= p->regshift; | ||
| 41 | writeb(value, p->membase + offset); | ||
| 42 | } | ||
| 43 | |||
| 44 | static unsigned int dw8250_serial_in(struct uart_port *p, int offset) | ||
| 45 | { | ||
| 46 | offset <<= p->regshift; | ||
| 47 | |||
| 48 | return readb(p->membase + offset); | ||
| 49 | } | ||
| 50 | |||
| 51 | static void dw8250_serial_out32(struct uart_port *p, int offset, int value) | ||
| 52 | { | ||
| 53 | struct dw8250_data *d = p->private_data; | ||
| 54 | |||
| 55 | if (offset == UART_LCR) | ||
| 56 | d->last_lcr = value; | ||
| 57 | |||
| 58 | offset <<= p->regshift; | ||
| 59 | writel(value, p->membase + offset); | ||
| 60 | } | ||
| 61 | |||
| 62 | static unsigned int dw8250_serial_in32(struct uart_port *p, int offset) | ||
| 63 | { | ||
| 64 | offset <<= p->regshift; | ||
| 65 | |||
| 66 | return readl(p->membase + offset); | ||
| 67 | } | ||
| 68 | |||
| 69 | /* Offset for the DesignWare's UART Status Register. */ | ||
| 70 | #define UART_USR 0x1f | ||
| 71 | |||
| 72 | static int dw8250_handle_irq(struct uart_port *p) | ||
| 73 | { | ||
| 74 | struct dw8250_data *d = p->private_data; | ||
| 75 | unsigned int iir = p->serial_in(p, UART_IIR); | ||
| 76 | |||
| 77 | if (serial8250_handle_irq(p, iir)) { | ||
| 78 | return 1; | ||
| 79 | } else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) { | ||
| 80 | /* Clear the USR and write the LCR again. */ | ||
| 81 | (void)p->serial_in(p, UART_USR); | ||
| 82 | p->serial_out(p, d->last_lcr, UART_LCR); | ||
| 83 | |||
| 84 | return 1; | ||
| 85 | } | ||
| 86 | |||
| 87 | return 0; | ||
| 88 | } | ||
| 89 | |||
| 90 | static int __devinit dw8250_probe(struct platform_device *pdev) | ||
| 91 | { | ||
| 92 | struct uart_port port = {}; | ||
| 93 | struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 94 | struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
| 95 | struct device_node *np = pdev->dev.of_node; | ||
| 96 | u32 val; | ||
| 97 | struct dw8250_data *data; | ||
| 98 | |||
| 99 | if (!regs || !irq) { | ||
| 100 | dev_err(&pdev->dev, "no registers/irq defined\n"); | ||
| 101 | return -EINVAL; | ||
| 102 | } | ||
| 103 | |||
| 104 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | ||
| 105 | if (!data) | ||
| 106 | return -ENOMEM; | ||
| 107 | port.private_data = data; | ||
| 108 | |||
| 109 | spin_lock_init(&port.lock); | ||
| 110 | port.mapbase = regs->start; | ||
| 111 | port.irq = irq->start; | ||
| 112 | port.handle_irq = dw8250_handle_irq; | ||
| 113 | port.type = PORT_8250; | ||
| 114 | port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP | | ||
| 115 | UPF_FIXED_PORT | UPF_FIXED_TYPE; | ||
| 116 | port.dev = &pdev->dev; | ||
| 117 | |||
| 118 | port.iotype = UPIO_MEM; | ||
| 119 | port.serial_in = dw8250_serial_in; | ||
| 120 | port.serial_out = dw8250_serial_out; | ||
| 121 | if (!of_property_read_u32(np, "reg-io-width", &val)) { | ||
| 122 | switch (val) { | ||
| 123 | case 1: | ||
| 124 | break; | ||
| 125 | case 4: | ||
| 126 | port.iotype = UPIO_MEM32; | ||
| 127 | port.serial_in = dw8250_serial_in32; | ||
| 128 | port.serial_out = dw8250_serial_out32; | ||
| 129 | break; | ||
| 130 | default: | ||
| 131 | dev_err(&pdev->dev, "unsupported reg-io-width (%u)\n", | ||
| 132 | val); | ||
| 133 | return -EINVAL; | ||
| 134 | } | ||
| 135 | } | ||
| 136 | |||
| 137 | if (!of_property_read_u32(np, "reg-shift", &val)) | ||
| 138 | port.regshift = val; | ||
| 139 | |||
| 140 | if (of_property_read_u32(np, "clock-frequency", &val)) { | ||
| 141 | dev_err(&pdev->dev, "no clock-frequency property set\n"); | ||
| 142 | return -EINVAL; | ||
| 143 | } | ||
| 144 | port.uartclk = val; | ||
| 145 | |||
| 146 | data->line = serial8250_register_port(&port); | ||
| 147 | if (data->line < 0) | ||
| 148 | return data->line; | ||
| 149 | |||
| 150 | platform_set_drvdata(pdev, data); | ||
| 151 | |||
| 152 | return 0; | ||
| 153 | } | ||
| 154 | |||
| 155 | static int __devexit dw8250_remove(struct platform_device *pdev) | ||
| 156 | { | ||
| 157 | struct dw8250_data *data = platform_get_drvdata(pdev); | ||
| 158 | |||
| 159 | serial8250_unregister_port(data->line); | ||
| 160 | |||
| 161 | return 0; | ||
| 162 | } | ||
| 163 | |||
| 164 | static const struct of_device_id dw8250_match[] = { | ||
| 165 | { .compatible = "snps,dw-apb-uart" }, | ||
| 166 | { /* Sentinel */ } | ||
| 167 | }; | ||
| 168 | MODULE_DEVICE_TABLE(of, dw8250_match); | ||
| 169 | |||
| 170 | static struct platform_driver dw8250_platform_driver = { | ||
| 171 | .driver = { | ||
| 172 | .name = "dw-apb-uart", | ||
| 173 | .owner = THIS_MODULE, | ||
| 174 | .of_match_table = dw8250_match, | ||
| 175 | }, | ||
| 176 | .probe = dw8250_probe, | ||
| 177 | .remove = __devexit_p(dw8250_remove), | ||
| 178 | }; | ||
| 179 | |||
| 180 | static int __init dw8250_init(void) | ||
| 181 | { | ||
| 182 | return platform_driver_register(&dw8250_platform_driver); | ||
| 183 | } | ||
| 184 | module_init(dw8250_init); | ||
| 185 | |||
| 186 | static void __exit dw8250_exit(void) | ||
| 187 | { | ||
| 188 | platform_driver_unregister(&dw8250_platform_driver); | ||
| 189 | } | ||
| 190 | module_exit(dw8250_exit); | ||
| 191 | |||
| 192 | MODULE_AUTHOR("Jamie Iles"); | ||
| 193 | MODULE_LICENSE("GPL"); | ||
| 194 | MODULE_DESCRIPTION("Synopsys DesignWare 8250 serial port driver"); | ||
| @@ -1101,6 +1101,15 @@ static int pci_eg20t_init(struct pci_dev *dev) · 1100 unmodified lines | |||
| 1101 | #endif | 1101 | #endif |
| 1102 | } | 1102 | } |
| 1103 | 1103 | ||
| 1104 | static int | ||
| 1105 | pci_xr17c154_setup(struct serial_private *priv, | ||
| 1106 | const struct pciserial_board *board, | ||
| 1107 | struct uart_port *port, int idx) | ||
| 1108 | { | ||
| 1109 | port->flags |= UPF_EXAR_EFR; | ||
| 1110 | return pci_default_setup(priv, board, port, idx); | ||
| 1111 | } | ||
| 1112 | |||
| 1104 | /* This should be in linux/pci_ids.h */ | 1113 | /* This should be in linux/pci_ids.h */ |
| 1105 | #define PCI_VENDOR_ID_SBSMODULARIO 0x124B | 1114 | #define PCI_VENDOR_ID_SBSMODULARIO 0x124B |
| 1106 | #define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B | 1115 | #define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B |
| @@ -1505,6 +1514,30 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { · 398 unmodified lines | |||
| 1505 | .subdevice = PCI_ANY_ID, | 1514 | .subdevice = PCI_ANY_ID, |
| 1506 | .setup = pci_timedia_setup, | 1515 | .setup = pci_timedia_setup, |
| 1507 | }, | 1516 | }, |
| 1517 | /* | ||
| 1518 | * Exar cards | ||
| 1519 | */ | ||
| 1520 | { | ||
| 1521 | .vendor = PCI_VENDOR_ID_EXAR, | ||
| 1522 | .device = PCI_DEVICE_ID_EXAR_XR17C152, | ||
| 1523 | .subvendor = PCI_ANY_ID, | ||
| 1524 | .subdevice = PCI_ANY_ID, | ||
| 1525 | .setup = pci_xr17c154_setup, | ||
| 1526 | }, | ||
| 1527 | { | ||
| 1528 | .vendor = PCI_VENDOR_ID_EXAR, | ||
| 1529 | .device = PCI_DEVICE_ID_EXAR_XR17C154, | ||
| 1530 | .subvendor = PCI_ANY_ID, | ||
| 1531 | .subdevice = PCI_ANY_ID, | ||
| 1532 | .setup = pci_xr17c154_setup, | ||
| 1533 | }, | ||
| 1534 | { | ||
| 1535 | .vendor = PCI_VENDOR_ID_EXAR, | ||
| 1536 | .device = PCI_DEVICE_ID_EXAR_XR17C158, | ||
| 1537 | .subvendor = PCI_ANY_ID, | ||
| 1538 | .subdevice = PCI_ANY_ID, | ||
| 1539 | .setup = pci_xr17c154_setup, | ||
| 1540 | }, | ||
| 1508 | /* | 1541 | /* |
| 1509 | * Xircom cards | 1542 | * Xircom cards |
| 1510 | */ | 1543 | */ |
| @@ -1558,46 +1591,55 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { · 47 unmodified lines | |||
| 1558 | .vendor = PCI_VENDOR_ID_INTEL, | 1591 | .vendor = PCI_VENDOR_ID_INTEL, |
| 1559 | .device = 0x8811, | 1592 | .device = 0x8811, |
| 1560 | .init = pci_eg20t_init, | 1593 | .init = pci_eg20t_init, |
| 1594 | .setup = pci_default_setup, | ||
| 1561 | }, | 1595 | }, |
| 1562 | { | 1596 | { |
| 1563 | .vendor = PCI_VENDOR_ID_INTEL, | 1597 | .vendor = PCI_VENDOR_ID_INTEL, |
| 1564 | .device = 0x8812, | 1598 | .device = 0x8812, |
| 1565 | .init = pci_eg20t_init, | 1599 | .init = pci_eg20t_init, |
| 1600 | .setup = pci_default_setup, | ||
| 1566 | }, | 1601 | }, |
| 1567 | { | 1602 | { |
| 1568 | .vendor = PCI_VENDOR_ID_INTEL, | 1603 | .vendor = PCI_VENDOR_ID_INTEL, |
| 1569 | .device = 0x8813, | 1604 | .device = 0x8813, |
| 1570 | .init = pci_eg20t_init, | 1605 | .init = pci_eg20t_init, |
| 1606 | .setup = pci_default_setup, | ||
| 1571 | }, | 1607 | }, |
| 1572 | { | 1608 | { |
| 1573 | .vendor = PCI_VENDOR_ID_INTEL, | 1609 | .vendor = PCI_VENDOR_ID_INTEL, |
| 1574 | .device = 0x8814, | 1610 | .device = 0x8814, |
| 1575 | .init = pci_eg20t_init, | 1611 | .init = pci_eg20t_init, |
| 1612 | .setup = pci_default_setup, | ||
| 1576 | }, | 1613 | }, |
| 1577 | { | 1614 | { |
| 1578 | .vendor = 0x10DB, | 1615 | .vendor = 0x10DB, |
| 1579 | .device = 0x8027, | 1616 | .device = 0x8027, |
| 1580 | .init = pci_eg20t_init, | 1617 | .init = pci_eg20t_init, |
| 1618 | .setup = pci_default_setup, | ||
| 1581 | }, | 1619 | }, |
| 1582 | { | 1620 | { |
| 1583 | .vendor = 0x10DB, | 1621 | .vendor = 0x10DB, |
| 1584 | .device = 0x8028, | 1622 | .device = 0x8028, |
| 1585 | .init = pci_eg20t_init, | 1623 | .init = pci_eg20t_init, |
| 1624 | .setup = pci_default_setup, | ||
| 1586 | }, | 1625 | }, |
| 1587 | { | 1626 | { |
| 1588 | .vendor = 0x10DB, | 1627 | .vendor = 0x10DB, |
| 1589 | .device = 0x8029, | 1628 | .device = 0x8029, |
| 1590 | .init = pci_eg20t_init, | 1629 | .init = pci_eg20t_init, |
| 1630 | .setup = pci_default_setup, | ||
| 1591 | }, | 1631 | }, |
| 1592 | { | 1632 | { |
| 1593 | .vendor = 0x10DB, | 1633 | .vendor = 0x10DB, |
| 1594 | .device = 0x800C, | 1634 | .device = 0x800C, |
| 1595 | .init = pci_eg20t_init, | 1635 | .init = pci_eg20t_init, |
| 1636 | .setup = pci_default_setup, | ||
| 1596 | }, | 1637 | }, |
| 1597 | { | 1638 | { |
| 1598 | .vendor = 0x10DB, | 1639 | .vendor = 0x10DB, |
| 1599 | .device = 0x800D, | 1640 | .device = 0x800D, |
| 1600 | .init = pci_eg20t_init, | 1641 | .init = pci_eg20t_init, |
| 1642 | .setup = pci_default_setup, | ||
| 1601 | }, | 1643 | }, |
| 1602 | /* | 1644 | /* |
| 1603 | * Cronyx Omega PCI (PLX-chip based) | 1645 | * Cronyx Omega PCI (PLX-chip based) |
| @@ -267,6 +267,13 @@ config SERIAL_8250_RM9K · 266 unmodified lines | |||
| 267 | port hardware found on MIPS RM9122 and similar processors. | 267 | port hardware found on MIPS RM9122 and similar processors. |
| 268 | If unsure, say N. | 268 | If unsure, say N. |
| 269 | 269 | ||
| 270 | config SERIAL_8250_DW | ||
| 271 | tristate "Support for Synopsys DesignWare 8250 quirks" | ||
| 272 | depends on SERIAL_8250 && OF | ||
| 273 | help | ||
| 274 | Selecting this option will enable handling of the extra features | ||
| 275 | present in the Synopsys DesignWare APB UART. | ||
| 276 | |||
| 270 | comment "Non-8250 serial port support" | 277 | comment "Non-8250 serial port support" |
| 271 | 278 | ||
| 272 | config SERIAL_AMBA_PL010 | 279 | config SERIAL_AMBA_PL010 |
| @@ -522,8 +529,8 @@ config SERIAL_S3C6400 · 249 unmodified lines | |||
| 522 | 529 | ||
| 523 | config SERIAL_S5PV210 | 530 | config SERIAL_S5PV210 |
| 524 | tristate "Samsung S5PV210 Serial port support" | 531 | tristate "Samsung S5PV210 Serial port support" |
| 525 | depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_EXYNOS4210) | 532 | depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_EXYNOS4210 || SOC_EXYNOS4212) |
| 526 | select SERIAL_SAMSUNG_UARTS_4 if (CPU_S5PV210 || CPU_EXYNOS4210) | 533 | select SERIAL_SAMSUNG_UARTS_4 if (CPU_S5PV210 || CPU_EXYNOS4210 || SOC_EXYNOS4212) |
| 527 | default y | 534 | default y |
| 528 | help | 535 | help |
| 529 | Serial port support for Samsung's S5P Family of SoC's | 536 | Serial port support for Samsung's S5P Family of SoC's |
| @@ -722,7 +729,7 @@ config SERIAL_BFIN · 192 unmodified lines | |||
| 722 | Add support for the built-in UARTs on the Blackfin. | 729 | Add support for the built-in UARTs on the Blackfin. |
| 723 | 730 | ||
| 724 | To compile this driver as a module, choose M here: the | 731 | To compile this driver as a module, choose M here: the |
| 725 | module will be called bfin_5xx. | 732 | module is named bfin_uart.ko. |
| 726 | 733 | ||
| 727 | config SERIAL_BFIN_CONSOLE | 734 | config SERIAL_BFIN_CONSOLE |
| 728 | bool "Console on Blackfin serial port" | 735 | bool "Console on Blackfin serial port" |
| @@ -1035,23 +1042,6 @@ config SERIAL_MCF_CONSOLE · 306 unmodified lines | |||
| 1035 | help | 1042 | help |
| 1036 | Enable a ColdFire internal serial port to be the system console. | 1043 | Enable a ColdFire internal serial port to be the system console. |
| 1037 | 1044 | ||
| 1038 | config SERIAL_68360_SMC | ||
| 1039 | bool "68360 SMC uart support" | ||
| 1040 | depends on M68360 | ||
| 1041 | help | ||
| 1042 | This driver supports the SMC serial ports of the Motorola 68360 CPU. | ||
| 1043 | |||
| 1044 | config SERIAL_68360_SCC | ||
| 1045 | bool "68360 SCC uart support" | ||
| 1046 | depends on M68360 | ||
| 1047 | help | ||
| 1048 | This driver supports the SCC serial ports of the Motorola 68360 CPU. | ||
| 1049 | |||
| 1050 | config SERIAL_68360 | ||
| 1051 | bool | ||
| 1052 | depends on SERIAL_68360_SMC || SERIAL_68360_SCC | ||
| 1053 | default y | ||
| 1054 | |||
| 1055 | config SERIAL_PMACZILOG | 1045 | config SERIAL_PMACZILOG |
| 1056 | tristate "Mac or PowerMac z85c30 ESCC support" | 1046 | tristate "Mac or PowerMac z85c30 ESCC support" |
| 1057 | depends on (M68K && MAC) || (PPC_OF && PPC_PMAC) | 1047 | depends on (M68K && MAC) || (PPC_OF && PPC_PMAC) |
| @@ -28,6 +28,7 @@ obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o · 27 unmodified lines | |||
| 28 | obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o | 28 | obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o |
| 29 | obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o | 29 | obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o |
| 30 | obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o | 30 | obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o |
| 31 | obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o | ||
| 31 | obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o | 32 | obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o |
| 32 | obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o | 33 | obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o |
| 33 | obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o | 34 | obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o |
| @@ -35,7 +36,7 @@ obj-$(CONFIG_SERIAL_PXA) += pxa.o · 1 unmodified line | |||
| 35 | obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o | 36 | obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o |
| 36 | obj-$(CONFIG_SERIAL_SA1100) += sa1100.o | 37 | obj-$(CONFIG_SERIAL_SA1100) += sa1100.o |
| 37 | obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o | 38 | obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o |
| 38 | obj-$(CONFIG_SERIAL_BFIN) += bfin_5xx.o | 39 | obj-$(CONFIG_SERIAL_BFIN) += bfin_uart.o |
| 39 | obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o | 40 | obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o |
| 40 | obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o | 41 | obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o |
| 41 | obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o | 42 | obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o |
| @@ -49,7 +50,6 @@ obj-$(CONFIG_SERIAL_MAX3107_AAVA) += max3107-aava.o · 7 unmodified lines | |||
| 49 | obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o | 50 | obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o |
| 50 | obj-$(CONFIG_SERIAL_MUX) += mux.o | 51 | obj-$(CONFIG_SERIAL_MUX) += mux.o |
| 51 | obj-$(CONFIG_SERIAL_68328) += 68328serial.o | 52 | obj-$(CONFIG_SERIAL_68328) += 68328serial.o |
| 52 | obj-$(CONFIG_SERIAL_68360) += 68360serial.o | ||
| 53 | obj-$(CONFIG_SERIAL_MCF) += mcf.o | 53 | obj-$(CONFIG_SERIAL_MCF) += mcf.o |
| 54 | obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o | 54 | obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o |
| 55 | obj-$(CONFIG_SERIAL_DZ) += dz.o | 55 | obj-$(CONFIG_SERIAL_DZ) += dz.o |
| @@ -218,7 +218,7 @@ static int altera_jtaguart_startup(struct uart_port *port) · 217 unmodified lines | |||
| 218 | unsigned long flags; | 218 | unsigned long flags; |
| 219 | int ret; | 219 | int ret; |
| 220 | 220 | ||
| 221 | ret = request_irq(port->irq, altera_jtaguart_interrupt, IRQF_DISABLED, | 221 | ret = request_irq(port->irq, altera_jtaguart_interrupt, 0, |
| 222 | DRV_NAME, port); | 222 | DRV_NAME, port); |
| 223 | if (ret) { | 223 | if (ret) { |
| 224 | pr_err(DRV_NAME ": unable to attach Altera JTAG UART %d " | 224 | pr_err(DRV_NAME ": unable to attach Altera JTAG UART %d " |
| @@ -315,7 +315,7 @@ static int altera_uart_startup(struct uart_port *port) · 314 unmodified lines | |||
| 315 | return 0; | 315 | return 0; |
| 316 | } | 316 | } |
| 317 | 317 | ||
| 318 | ret = request_irq(port->irq, altera_uart_interrupt, IRQF_DISABLED, | 318 | ret = request_irq(port->irq, altera_uart_interrupt, 0, |
| 319 | DRV_NAME, port); | 319 | DRV_NAME, port); |
| 320 | if (ret) { | 320 | if (ret) { |
| 321 | pr_err(DRV_NAME ": unable to attach Altera UART %d " | 321 | pr_err(DRV_NAME ": unable to attach Altera UART %d " |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | |||
| 16 | 16 | ||
| 17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
| 18 | #include <linux/tty.h> | 18 | #include <linux/tty.h> |
| 19 | #include <linux/tty_flip.h> | ||
| 19 | #include <linux/ioport.h> | 20 | #include <linux/ioport.h> |
| 20 | #include <linux/init.h> | 21 | #include <linux/init.h> |
| 21 | #include <linux/serial.h> | 22 | #include <linux/serial.h> |
| @@ -33,6 +33,8 @@ · 32 unmodified lines | |||
| 33 | #include <linux/sysrq.h> | 33 | #include <linux/sysrq.h> |
| 34 | #include <linux/tty_flip.h> | 34 | #include <linux/tty_flip.h> |
| 35 | #include <linux/platform_device.h> | 35 | #include <linux/platform_device.h> |
| 36 | #include <linux/of.h> | ||
| 37 | #include <linux/of_device.h> | ||
| 36 | #include <linux/dma-mapping.h> | 38 | #include <linux/dma-mapping.h> |
| 37 | #include <linux/atmel_pdc.h> | 39 | #include <linux/atmel_pdc.h> |
| 38 | #include <linux/atmel_serial.h> | 40 | #include <linux/atmel_serial.h> |
| @@ -157,11 +159,22 @@ struct atmel_uart_port { · 118 unmodified lines | |||
| 157 | }; | 159 | }; |
| 158 | 160 | ||
| 159 | static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART]; | 161 | static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART]; |
| 162 | static unsigned long atmel_ports_in_use; | ||
| 160 | 163 | ||
| 161 | #ifdef SUPPORT_SYSRQ | 164 | #ifdef SUPPORT_SYSRQ |
| 162 | static struct console atmel_console; | 165 | static struct console atmel_console; |
| 163 | #endif | 166 | #endif |
| 164 | 167 | ||
| 168 | #if defined(CONFIG_OF) | ||
| 169 | static const struct of_device_id atmel_serial_dt_ids[] = { | ||
| 170 | { .compatible = "atmel,at91rm9200-usart" }, | ||
| 171 | { .compatible = "atmel,at91sam9260-usart" }, | ||
| 172 | { /* sentinel */ } | ||
| 173 | }; | ||
| 174 | |||
| 175 | MODULE_DEVICE_TABLE(of, atmel_serial_dt_ids); | ||
| 176 | #endif | ||
| 177 | |||
| 165 | static inline struct atmel_uart_port * | 178 | static inline struct atmel_uart_port * |
| 166 | to_atmel_uart_port(struct uart_port *uart) | 179 | to_atmel_uart_port(struct uart_port *uart) |
| 167 | { | 180 | { |
| @@ -339,7 +352,8 @@ static void atmel_stop_tx(struct uart_port *port) · 171 unmodified lines | |||
| 339 | /* Disable interrupts */ | 352 | /* Disable interrupts */ |
| 340 | UART_PUT_IDR(port, atmel_port->tx_done_mask); | 353 | UART_PUT_IDR(port, atmel_port->tx_done_mask); |
| 341 | 354 | ||
| 342 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) | 355 | if ((atmel_port->rs485.flags & SER_RS485_ENABLED) && |
| 356 | !(atmel_port->rs485.flags & SER_RS485_RX_DURING_TX)) | ||
| 343 | atmel_start_rx(port); | 357 | atmel_start_rx(port); |
| 344 | } | 358 | } |
| 345 | 359 | ||
| @@ -356,7 +370,8 @@ static void atmel_start_tx(struct uart_port *port) · 10 unmodified lines | |||
| 356 | really need this.*/ | 370 | really need this.*/ |
| 357 | return; | 371 | return; |
| 358 | 372 | ||
| 359 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) | 373 | if ((atmel_port->rs485.flags & SER_RS485_ENABLED) && |
| 374 | !(atmel_port->rs485.flags & SER_RS485_RX_DURING_TX)) | ||
| 360 | atmel_stop_rx(port); | 375 | atmel_stop_rx(port); |
| 361 | 376 | ||
| 362 | /* re-enable PDC transmit */ | 377 | /* re-enable PDC transmit */ |
| @@ -680,7 +695,8 @@ static void atmel_tx_dma(struct uart_port *port) · 317 unmodified lines | |||
| 680 | /* Enable interrupts */ | 695 | /* Enable interrupts */ |
| 681 | UART_PUT_IER(port, atmel_port->tx_done_mask); | 696 | UART_PUT_IER(port, atmel_port->tx_done_mask); |
| 682 | } else { | 697 | } else { |
| 683 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) { | 698 | if ((atmel_port->rs485.flags & SER_RS485_ENABLED) && |
| 699 | !(atmel_port->rs485.flags & SER_RS485_RX_DURING_TX)) { | ||
| 684 | /* DMA done, stop TX, start RX for RS485 */ | 700 | /* DMA done, stop TX, start RX for RS485 */ |
| 685 | atmel_start_rx(port); | 701 | atmel_start_rx(port); |
| 686 | } | 702 | } |
| @@ -1407,6 +1423,48 @@ static struct uart_ops atmel_pops = { · 720 unmodified lines | |||
| 1407 | #endif | 1423 | #endif |
| 1408 | }; | 1424 | }; |
| 1409 | 1425 | ||
| 1426 | static void __devinit atmel_of_init_port(struct atmel_uart_port *atmel_port, | ||
| 1427 | struct device_node *np) | ||
| 1428 | { | ||
| 1429 | u32 rs485_delay[2]; | ||
| 1430 | |||
| 1431 | /* DMA/PDC usage specification */ | ||
| 1432 | if (of_get_property(np, "atmel,use-dma-rx", NULL)) | ||
| 1433 | atmel_port->use_dma_rx = 1; | ||
| 1434 | else | ||
| 1435 | atmel_port->use_dma_rx = 0; | ||
| 1436 | if (of_get_property(np, "atmel,use-dma-tx", NULL)) | ||
| 1437 | atmel_port->use_dma_tx = 1; | ||
| 1438 | else | ||
| 1439 | atmel_port->use_dma_tx = 0; | ||
| 1440 | |||
| 1441 | /* rs485 properties */ | ||
| 1442 | if (of_property_read_u32_array(np, "rs485-rts-delay", | ||
| 1443 | rs485_delay, 2) == 0) { | ||
| 1444 | struct serial_rs485 *rs485conf = &atmel_port->rs485; | ||
| 1445 | |||
| 1446 | rs485conf->delay_rts_before_send = rs485_delay[0]; | ||
| 1447 | rs485conf->delay_rts_after_send = rs485_delay[1]; | ||
| 1448 | rs485conf->flags = 0; | ||
| 1449 | |||
| 1450 | if (rs485conf->delay_rts_before_send == 0 && | ||
| 1451 | rs485conf->delay_rts_after_send == 0) { | ||
| 1452 | rs485conf->flags |= SER_RS485_RTS_ON_SEND; | ||
| 1453 | } else { | ||
| 1454 | if (rs485conf->delay_rts_before_send) | ||
| 1455 | rs485conf->flags |= SER_RS485_RTS_BEFORE_SEND; | ||
| 1456 | if (rs485conf->delay_rts_after_send) | ||
| 1457 | rs485conf->flags |= SER_RS485_RTS_AFTER_SEND; | ||
| 1458 | } | ||
| 1459 | |||
| 1460 | if (of_get_property(np, "rs485-rx-during-tx", NULL)) | ||
| 1461 | rs485conf->flags |= SER_RS485_RX_DURING_TX; | ||
| 1462 | |||
| 1463 | if (of_get_property(np, "linux,rs485-enabled-at-boot-time", NULL)) | ||
| 1464 | rs485conf->flags |= SER_RS485_ENABLED; | ||
| 1465 | } | ||
| 1466 | } | ||
| 1467 | |||
| 1410 | /* | 1468 | /* |
| 1411 | * Configure the port from the platform device resource info. | 1469 | * Configure the port from the platform device resource info. |
| 1412 | */ | 1470 | */ |
| @@ -1414,13 +1472,20 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port, · 1 unmodified line | |||
| 1414 | struct platform_device *pdev) | 1472 | struct platform_device *pdev) |
| 1415 | { | 1473 | { |
| 1416 | struct uart_port *port = &atmel_port->uart; | 1474 | struct uart_port *port = &atmel_port->uart; |
| 1417 | struct atmel_uart_data *data = pdev->dev.platform_data; | 1475 | struct atmel_uart_data *pdata = pdev->dev.platform_data; |
| 1476 | |||
| 1477 | if (pdev->dev.of_node) { | ||
| 1478 | atmel_of_init_port(atmel_port, pdev->dev.of_node); | ||
| 1479 | } else { | ||
| 1480 | atmel_port->use_dma_rx = pdata->use_dma_rx; | ||
| 1481 | atmel_port->use_dma_tx = pdata->use_dma_tx; | ||
| 1482 | atmel_port->rs485 = pdata->rs485; | ||
| 1483 | } | ||
| 1418 | 1484 | ||
| 1419 | port->iotype = UPIO_MEM; | 1485 | port->iotype = UPIO_MEM; |
| 1420 | port->flags = UPF_BOOT_AUTOCONF; | 1486 | port->flags = UPF_BOOT_AUTOCONF; |
| 1421 | port->ops = &atmel_pops; | 1487 | port->ops = &atmel_pops; |
| 1422 | port->fifosize = 1; | 1488 | port->fifosize = 1; |
| 1423 | port->line = data->num; | ||
| 1424 | port->dev = &pdev->dev; | 1489 | port->dev = &pdev->dev; |
| 1425 | port->mapbase = pdev->resource[0].start; | 1490 | port->mapbase = pdev->resource[0].start; |
| 1426 | port->irq = pdev->resource[1].start; | 1491 | port->irq = pdev->resource[1].start; |
| @@ -1430,10 +1495,10 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port, · 3 unmodified lines | |||
| 1430 | 1495 | ||
| 1431 | memset(&atmel_port->rx_ring, 0, sizeof(atmel_port->rx_ring)); | 1496 | memset(&atmel_port->rx_ring, 0, sizeof(atmel_port->rx_ring)); |
| 1432 | 1497 | ||
| 1433 | if (data->regs) | 1498 | if (pdata && pdata->regs) { |
| 1434 | /* Already mapped by setup code */ | 1499 | /* Already mapped by setup code */ |
| 1435 | port->membase = data->regs; | 1500 | port->membase = pdata->regs; |
| 1436 | else { | 1501 | } else { |
| 1437 | port->flags |= UPF_IOREMAP; | 1502 | port->flags |= UPF_IOREMAP; |
| 1438 | port->membase = NULL; | 1503 | port->membase = NULL; |
| 1439 | } | 1504 | } |
| @@ -1447,9 +1512,6 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port, · 7 unmodified lines | |||
| 1447 | /* only enable clock when USART is in use */ | 1512 | /* only enable clock when USART is in use */ |
| 1448 | } | 1513 | } |
| 1449 | 1514 | ||
| 1450 | atmel_port->use_dma_rx = data->use_dma_rx; | ||
| 1451 | atmel_port->use_dma_tx = data->use_dma_tx; | ||
| 1452 | atmel_port->rs485 = data->rs485; | ||
| 1453 | /* Use TXEMPTY for interrupt when rs485 else TXRDY or ENDTX|TXBUFE */ | 1515 | /* Use TXEMPTY for interrupt when rs485 else TXRDY or ENDTX|TXBUFE */ |
| 1454 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) | 1516 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) |
| 1455 | atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; | 1517 | atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; |
| @@ -1611,10 +1673,14 @@ static int __init atmel_console_init(void) · 155 unmodified lines | |||
| 1611 | if (atmel_default_console_device) { | 1673 | if (atmel_default_console_device) { |
| 1612 | struct atmel_uart_data *pdata = | 1674 | struct atmel_uart_data *pdata = |
| 1613 | atmel_default_console_device->dev.platform_data; | 1675 | atmel_default_console_device->dev.platform_data; |
| 1676 | int id = pdata->num; | ||
| 1677 | struct atmel_uart_port *port = &atmel_ports[id]; | ||
| 1678 | |||
| 1679 | port->backup_imr = 0; | ||
| 1680 | port->uart.line = id; | ||
| 1614 | 1681 | ||
| 1615 | add_preferred_console(ATMEL_DEVICENAME, pdata->num, NULL); | 1682 | add_preferred_console(ATMEL_DEVICENAME, id, NULL); |
| 1616 | atmel_init_port(&atmel_ports[pdata->num], | 1683 | atmel_init_port(port, atmel_default_console_device); |
| 1617 | atmel_default_console_device); | ||
| 1618 | register_console(&atmel_console); | 1684 | register_console(&atmel_console); |
| 1619 | } | 1685 | } |
| 1620 | 1686 | ||
| @@ -1711,14 +1777,39 @@ static int atmel_serial_resume(struct platform_device *pdev) · 90 unmodified lines | |||
| 1711 | static int __devinit atmel_serial_probe(struct platform_device *pdev) | 1777 | static int __devinit atmel_serial_probe(struct platform_device *pdev) |
| 1712 | { | 1778 | { |
| 1713 | struct atmel_uart_port *port; | 1779 | struct atmel_uart_port *port; |
| 1780 | struct device_node *np = pdev->dev.of_node; | ||
| 1714 | struct atmel_uart_data *pdata = pdev->dev.platform_data; | 1781 | struct atmel_uart_data *pdata = pdev->dev.platform_data; |
| 1715 | void *data; | 1782 | void *data; |
| 1716 | int ret; | 1783 | int ret = -ENODEV; |
| 1717 | 1784 | ||
| 1718 | BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1)); | 1785 | BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1)); |
| 1719 | 1786 | ||
| 1720 | port = &atmel_ports[pdata->num]; | 1787 | if (np) |
| 1788 | ret = of_alias_get_id(np, "serial"); | ||
| 1789 | else | ||
| 1790 | if (pdata) | ||
| 1791 | ret = pdata->num; | ||
| 1792 | |||
| 1793 | if (ret < 0) | ||
| 1794 | /* port id not found in platform data nor device-tree aliases: | ||
| 1795 | * auto-enumerate it */ | ||
| 1796 | ret = find_first_zero_bit(&atmel_ports_in_use, | ||
| 1797 | sizeof(atmel_ports_in_use)); | ||
| 1798 | |||
| 1799 | if (ret > ATMEL_MAX_UART) { | ||
| 1800 | ret = -ENODEV; | ||
| 1801 | goto err; | ||
| 1802 | } | ||
| 1803 | |||
| 1804 | if (test_and_set_bit(ret, &atmel_ports_in_use)) { | ||
| 1805 | /* port already in use */ | ||
| 1806 | ret = -EBUSY; | ||
| 1807 | goto err; | ||
| 1808 | } | ||
| 1809 | |||
| 1810 | port = &atmel_ports[ret]; | ||
| 1721 | port->backup_imr = 0; | 1811 | port->backup_imr = 0; |
| 1812 | port->uart.line = ret; | ||
| 1722 | 1813 | ||
| 1723 | atmel_init_port(port, pdev); | 1814 | atmel_init_port(port, pdev); |
| 1724 | 1815 | ||
| @@ -1764,7 +1855,7 @@ err_alloc_ring: · 39 unmodified lines | |||
| 1764 | clk_put(port->clk); | 1855 | clk_put(port->clk); |
| 1765 | port->clk = NULL; | 1856 | port->clk = NULL; |
| 1766 | } | 1857 | } |
| 1767 | 1858 | err: | |
| 1768 | return ret; | 1859 | return ret; |
| 1769 | } | 1860 | } |
| 1770 | 1861 | ||
| @@ -1784,6 +1875,8 @@ static int __devexit atmel_serial_remove(struct platform_device *pdev) · 13 unmodified lines | |||
| 1784 | 1875 | ||
| 1785 | /* "port" is allocated statically, so we shouldn't free it */ | 1876 | /* "port" is allocated statically, so we shouldn't free it */ |
| 1786 | 1877 | ||
| 1878 | clear_bit(port->line, &atmel_ports_in_use); | ||
| 1879 | |||
| 1787 | clk_put(atmel_port->clk); | 1880 | clk_put(atmel_port->clk); |
| 1788 | 1881 | ||
| 1789 | return ret; | 1882 | return ret; |
| @@ -1797,6 +1890,7 @@ static struct platform_driver atmel_serial_driver = { · 7 unmodified lines | |||
| 1797 | .driver = { | 1890 | .driver = { |
| 1798 | .name = "atmel_usart", | 1891 | .name = "atmel_usart", |
| 1799 | .owner = THIS_MODULE, | 1892 | .owner = THIS_MODULE, |
| 1893 | .of_match_table = of_match_ptr(atmel_serial_dt_ids), | ||
| 1800 | }, | 1894 | }, |
| 1801 | }; | 1895 | }; |
| 1802 | 1896 | ||
| @@ -294,7 +294,7 @@ static int sport_startup(struct uart_port *port) · 293 unmodified lines | |||
| 294 | if (request_irq(gpio_to_irq(up->cts_pin), | 294 | if (request_irq(gpio_to_irq(up->cts_pin), |
| 295 | sport_mctrl_cts_int, | 295 | sport_mctrl_cts_int, |
| 296 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | | 296 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | |
| 297 | IRQF_DISABLED, "BFIN_SPORT_UART_CTS", up)) { | 297 | 0, "BFIN_SPORT_UART_CTS", up)) { |
| 298 | up->cts_pin = -1; | 298 | up->cts_pin = -1; |
| 299 | dev_info(port->dev, "Unable to attach BlackFin UART over SPORT CTS interrupt. So, disable it.\n"); | 299 | dev_info(port->dev, "Unable to attach BlackFin UART over SPORT CTS interrupt. So, disable it.\n"); |
| 300 | } | 300 | } |
| @@ -234,8 +234,8 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) · 233 unmodified lines | |||
| 234 | status = UART_GET_LSR(uart); | 234 | status = UART_GET_LSR(uart); |
| 235 | UART_CLEAR_LSR(uart); | 235 | UART_CLEAR_LSR(uart); |
| 236 | 236 | ||
| 237 | ch = UART_GET_CHAR(uart); | 237 | ch = UART_GET_CHAR(uart); |
| 238 | uart->port.icount.rx++; | 238 | uart->port.icount.rx++; |
| 239 | 239 | ||
| 240 | #if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ | 240 | #if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ |
| 241 | defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) | 241 | defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) |
| @@ -667,17 +667,17 @@ static int bfin_serial_startup(struct uart_port *port) · 425 unmodified lines | |||
| 667 | kgdboc_break_enabled = 0; | 667 | kgdboc_break_enabled = 0; |
| 668 | else { | 668 | else { |
| 669 | # endif | 669 | # endif |
| 670 | if (request_irq(uart->port.irq, bfin_serial_rx_int, IRQF_DISABLED, | 670 | if (request_irq(uart->rx_irq, bfin_serial_rx_int, 0, |
| 671 | "BFIN_UART_RX", uart)) { | 671 | "BFIN_UART_RX", uart)) { |
| 672 | printk(KERN_NOTICE "Unable to attach BlackFin UART RX interrupt\n"); | 672 | printk(KERN_NOTICE "Unable to attach BlackFin UART RX interrupt\n"); |
| 673 | return -EBUSY; | 673 | return -EBUSY; |
| 674 | } | 674 | } |
| 675 | 675 | ||
| 676 | if (request_irq | 676 | if (request_irq |
| 677 | (uart->port.irq+1, bfin_serial_tx_int, IRQF_DISABLED, | 677 | (uart->tx_irq, bfin_serial_tx_int, 0, |
| 678 | "BFIN_UART_TX", uart)) { | 678 | "BFIN_UART_TX", uart)) { |
| 679 | printk(KERN_NOTICE "Unable to attach BlackFin UART TX interrupt\n"); | 679 | printk(KERN_NOTICE "Unable to attach BlackFin UART TX interrupt\n"); |
| 680 | free_irq(uart->port.irq, uart); | 680 | free_irq(uart->rx_irq, uart); |
| 681 | return -EBUSY; | 681 | return -EBUSY; |
| 682 | } | 682 | } |
| 683 | 683 | ||
| @@ -692,7 +692,7 @@ static int bfin_serial_startup(struct uart_port *port) · 8 unmodified lines | |||
| 692 | */ | 692 | */ |
| 693 | unsigned uart_dma_ch_rx, uart_dma_ch_tx; | 693 | unsigned uart_dma_ch_rx, uart_dma_ch_tx; |
| 694 | 694 | ||
| 695 | switch (uart->port.irq) { | 695 | switch (uart->rx_irq) { |
| 696 | case IRQ_UART3_RX: | 696 | case IRQ_UART3_RX: |
| 697 | uart_dma_ch_rx = CH_UART3_RX; | 697 | uart_dma_ch_rx = CH_UART3_RX; |
| 698 | uart_dma_ch_tx = CH_UART3_TX; | 698 | uart_dma_ch_tx = CH_UART3_TX; |
| @@ -709,16 +709,16 @@ static int bfin_serial_startup(struct uart_port *port) · 10 unmodified lines | |||
| 709 | if (uart_dma_ch_rx && | 709 | if (uart_dma_ch_rx && |
| 710 | request_dma(uart_dma_ch_rx, "BFIN_UART_RX") < 0) { | 710 | request_dma(uart_dma_ch_rx, "BFIN_UART_RX") < 0) { |
| 711 | printk(KERN_NOTICE"Fail to attach UART interrupt\n"); | 711 | printk(KERN_NOTICE"Fail to attach UART interrupt\n"); |
| 712 | free_irq(uart->port.irq, uart); | 712 | free_irq(uart->rx_irq, uart); |
| 713 | free_irq(uart->port.irq + 1, uart); | 713 | free_irq(uart->tx_irq, uart); |
| 714 | return -EBUSY; | 714 | return -EBUSY; |
| 715 | } | 715 | } |
| 716 | if (uart_dma_ch_tx && | 716 | if (uart_dma_ch_tx && |
| 717 | request_dma(uart_dma_ch_tx, "BFIN_UART_TX") < 0) { | 717 | request_dma(uart_dma_ch_tx, "BFIN_UART_TX") < 0) { |
| 718 | printk(KERN_NOTICE "Fail to attach UART interrupt\n"); | 718 | printk(KERN_NOTICE "Fail to attach UART interrupt\n"); |
| 719 | free_dma(uart_dma_ch_rx); | 719 | free_dma(uart_dma_ch_rx); |
| 720 | free_irq(uart->port.irq, uart); | 720 | free_irq(uart->rx_irq, uart); |
| 721 | free_irq(uart->port.irq + 1, uart); | 721 | free_irq(uart->tx_irq, uart); |
| 722 | return -EBUSY; | 722 | return -EBUSY; |
| 723 | } | 723 | } |
| 724 | } | 724 | } |
| @@ -734,19 +734,18 @@ static int bfin_serial_startup(struct uart_port *port) · 9 unmodified lines | |||
| 734 | if (request_irq(gpio_to_irq(uart->cts_pin), | 734 | if (request_irq(gpio_to_irq(uart->cts_pin), |
| 735 | bfin_serial_mctrl_cts_int, | 735 | bfin_serial_mctrl_cts_int, |
| 736 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | | 736 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | |
| 737 | IRQF_DISABLED, "BFIN_UART_CTS", uart)) { | 737 | 0, "BFIN_UART_CTS", uart)) { |
| 738 | uart->cts_pin = -1; | 738 | uart->cts_pin = -1; |
| 739 | pr_info("Unable to attach BlackFin UART CTS interrupt. So, disable it.\n"); | 739 | pr_info("Unable to attach BlackFin UART CTS interrupt. So, disable it.\n"); |
| 740 | } | 740 | } |
| 741 | } | 741 | } |
| 742 | if (uart->rts_pin >= 0) { | 742 | if (uart->rts_pin >= 0) |
| 743 | gpio_direction_output(uart->rts_pin, 0); | 743 | gpio_direction_output(uart->rts_pin, 0); |
| 744 | } | ||
| 745 | #endif | 744 | #endif |
| 746 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | 745 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS |
| 747 | if (uart->cts_pin >= 0 && request_irq(uart->status_irq, | 746 | if (uart->cts_pin >= 0 && request_irq(uart->status_irq, |
| 748 | bfin_serial_mctrl_cts_int, | 747 | bfin_serial_mctrl_cts_int, |
| 749 | IRQF_DISABLED, "BFIN_UART_MODEM_STATUS", uart)) { | 748 | 0, "BFIN_UART_MODEM_STATUS", uart)) { |
| 750 | uart->cts_pin = -1; | 749 | uart->cts_pin = -1; |
| 751 | pr_info("Unable to attach BlackFin UART Modem Status interrupt.\n"); | 750 | pr_info("Unable to attach BlackFin UART Modem Status interrupt.\n"); |
| 752 | } | 751 | } |
| @@ -786,8 +785,8 @@ static void bfin_serial_shutdown(struct uart_port *port) · 33 unmodified lines | |||
| 786 | break; | 785 | break; |
| 787 | }; | 786 | }; |
| 788 | #endif | 787 | #endif |
| 789 | free_irq(uart->port.irq, uart); | 788 | free_irq(uart->rx_irq, uart); |
| 790 | free_irq(uart->port.irq+1, uart); | 789 | free_irq(uart->tx_irq, uart); |
| 791 | #endif | 790 | #endif |
| 792 | 791 | ||
| 793 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | 792 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS |
| @@ -1091,10 +1090,18 @@ bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud, · 297 unmodified lines | |||
| 1091 | *parity = 'o'; | 1090 | *parity = 'o'; |
| 1092 | } | 1091 | } |
| 1093 | switch (lcr & 0x03) { | 1092 | switch (lcr & 0x03) { |
| 1094 | case 0: *bits = 5; break; | 1093 | case 0: |
| 1095 | case 1: *bits = 6; break; | 1094 | *bits = 5; |
| 1096 | case 2: *bits = 7; break; | 1095 | break; |
| 1097 | case 3: *bits = 8; break; | 1096 | case 1: |
| 1097 | *bits = 6; | ||
| 1098 | break; | ||
| 1099 | case 2: | ||
| 1100 | *bits = 7; | ||
| 1101 | break; | ||
| 1102 | case 3: | ||
| 1103 | *bits = 8; | ||
| 1104 | break; | ||
| 1098 | } | 1105 | } |
| 1099 | /* Set DLAB in LCR to Access DLL and DLH */ | 1106 | /* Set DLAB in LCR to Access DLL and DLH */ |
| 1100 | UART_SET_DLAB(uart); | 1107 | UART_SET_DLAB(uart); |
| @@ -1183,7 +1190,7 @@ static struct console bfin_serial_console = { · 82 unmodified lines | |||
| 1183 | .index = -1, | 1190 | .index = -1, |
| 1184 | .data = &bfin_serial_reg, | 1191 | .data = &bfin_serial_reg, |
| 1185 | }; | 1192 | }; |
| 1186 | #define BFIN_SERIAL_CONSOLE &bfin_serial_console | 1193 | #define BFIN_SERIAL_CONSOLE (&bfin_serial_console) |
| 1187 | #else | 1194 | #else |
| 1188 | #define BFIN_SERIAL_CONSOLE NULL | 1195 | #define BFIN_SERIAL_CONSOLE NULL |
| 1189 | #endif /* CONFIG_SERIAL_BFIN_CONSOLE */ | 1196 | #endif /* CONFIG_SERIAL_BFIN_CONSOLE */ |
| @@ -1312,14 +1319,22 @@ static int bfin_serial_probe(struct platform_device *pdev) · 122 unmodified lines | |||
| 1312 | } | 1319 | } |
| 1313 | uart->port.mapbase = res->start; | 1320 | uart->port.mapbase = res->start; |
| 1314 | 1321 | ||
| 1315 | uart->port.irq = platform_get_irq(pdev, 0); | 1322 | uart->tx_irq = platform_get_irq(pdev, 0); |
| 1316 | if (uart->port.irq < 0) { | 1323 | if (uart->tx_irq < 0) { |
| 1317 | dev_err(&pdev->dev, "No uart RX/TX IRQ specified\n"); | 1324 | dev_err(&pdev->dev, "No uart TX IRQ specified\n"); |
| 1325 | ret = -ENOENT; | ||
| 1326 | goto out_error_unmap; | ||
| 1327 | } | ||
| 1328 | |||
| 1329 | uart->rx_irq = platform_get_irq(pdev, 1); | ||
| 1330 | if (uart->rx_irq < 0) { | ||
| 1331 | dev_err(&pdev->dev, "No uart RX IRQ specified\n"); | ||
| 1318 | ret = -ENOENT; | 1332 | ret = -ENOENT; |
| 1319 | goto out_error_unmap; | 1333 | goto out_error_unmap; |
| 1320 | } | 1334 | } |
| 1335 | uart->port.irq = uart->rx_irq; | ||
| 1321 | 1336 | ||
| 1322 | uart->status_irq = platform_get_irq(pdev, 1); | 1337 | uart->status_irq = platform_get_irq(pdev, 2); |
| 1323 | if (uart->status_irq < 0) { | 1338 | if (uart->status_irq < 0) { |
| 1324 | dev_err(&pdev->dev, "No uart status IRQ specified\n"); | 1339 | dev_err(&pdev->dev, "No uart status IRQ specified\n"); |
| 1325 | ret = -ENOENT; | 1340 | ret = -ENOENT; |
| @@ -31,6 +31,7 @@ · 30 unmodified lines | |||
| 31 | 31 | ||
| 32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
| 33 | #include <linux/tty.h> | 33 | #include <linux/tty.h> |
| 34 | #include <linux/tty_flip.h> | ||
| 34 | #include <linux/ioport.h> | 35 | #include <linux/ioport.h> |
| 35 | #include <linux/init.h> | 36 | #include <linux/init.h> |
| 36 | #include <linux/serial.h> | 37 | #include <linux/serial.h> |
| @@ -258,7 +258,7 @@ static struct e100_serial rs_table[] = { · 257 unmodified lines | |||
| 258 | .dma_out_enabled = 1, | 258 | .dma_out_enabled = 1, |
| 259 | .dma_out_nbr = SER0_TX_DMA_NBR, | 259 | .dma_out_nbr = SER0_TX_DMA_NBR, |
| 260 | .dma_out_irq_nbr = SER0_DMA_TX_IRQ_NBR, | 260 | .dma_out_irq_nbr = SER0_DMA_TX_IRQ_NBR, |
| 261 | .dma_out_irq_flags = IRQF_DISABLED, | 261 | .dma_out_irq_flags = 0, |
| 262 | .dma_out_irq_description = "serial 0 dma tr", | 262 | .dma_out_irq_description = "serial 0 dma tr", |
| 263 | #else | 263 | #else |
| 264 | .dma_out_enabled = 0, | 264 | .dma_out_enabled = 0, |
| @@ -271,7 +271,7 @@ static struct e100_serial rs_table[] = { · 6 unmodified lines | |||
| 271 | .dma_in_enabled = 1, | 271 | .dma_in_enabled = 1, |
| 272 | .dma_in_nbr = SER0_RX_DMA_NBR, | 272 | .dma_in_nbr = SER0_RX_DMA_NBR, |
| 273 | .dma_in_irq_nbr = SER0_DMA_RX_IRQ_NBR, | 273 | .dma_in_irq_nbr = SER0_DMA_RX_IRQ_NBR, |
| 274 | .dma_in_irq_flags = IRQF_DISABLED, | 274 | .dma_in_irq_flags = 0, |
| 275 | .dma_in_irq_description = "serial 0 dma rec", | 275 | .dma_in_irq_description = "serial 0 dma rec", |
| 276 | #else | 276 | #else |
| 277 | .dma_in_enabled = 0, | 277 | .dma_in_enabled = 0, |
| @@ -313,7 +313,7 @@ static struct e100_serial rs_table[] = { · 35 unmodified lines | |||
| 313 | .dma_out_enabled = 1, | 313 | .dma_out_enabled = 1, |
| 314 | .dma_out_nbr = SER1_TX_DMA_NBR, | 314 | .dma_out_nbr = SER1_TX_DMA_NBR, |
| 315 | .dma_out_irq_nbr = SER1_DMA_TX_IRQ_NBR, | 315 | .dma_out_irq_nbr = SER1_DMA_TX_IRQ_NBR, |
| 316 | .dma_out_irq_flags = IRQF_DISABLED, | 316 | .dma_out_irq_flags = 0, |
| 317 | .dma_out_irq_description = "serial 1 dma tr", | 317 | .dma_out_irq_description = "serial 1 dma tr", |
| 318 | #else | 318 | #else |
| 319 | .dma_out_enabled = 0, | 319 | .dma_out_enabled = 0, |
| @@ -326,7 +326,7 @@ static struct e100_serial rs_table[] = { · 6 unmodified lines | |||
| 326 | .dma_in_enabled = 1, | 326 | .dma_in_enabled = 1, |
| 327 | .dma_in_nbr = SER1_RX_DMA_NBR, | 327 | .dma_in_nbr = SER1_RX_DMA_NBR, |
| 328 | .dma_in_irq_nbr = SER1_DMA_RX_IRQ_NBR, | 328 | .dma_in_irq_nbr = SER1_DMA_RX_IRQ_NBR, |
| 329 | .dma_in_irq_flags = IRQF_DISABLED, | 329 | .dma_in_irq_flags = 0, |
| 330 | .dma_in_irq_description = "serial 1 dma rec", | 330 | .dma_in_irq_description = "serial 1 dma rec", |
| 331 | #else | 331 | #else |
| 332 | .dma_in_enabled = 0, | 332 | .dma_in_enabled = 0, |
| @@ -369,7 +369,7 @@ static struct e100_serial rs_table[] = { · 36 unmodified lines | |||
| 369 | .dma_out_enabled = 1, | 369 | .dma_out_enabled = 1, |
| 370 | .dma_out_nbr = SER2_TX_DMA_NBR, | 370 | .dma_out_nbr = SER2_TX_DMA_NBR, |
| 371 | .dma_out_irq_nbr = SER2_DMA_TX_IRQ_NBR, | 371 | .dma_out_irq_nbr = SER2_DMA_TX_IRQ_NBR, |
| 372 | .dma_out_irq_flags = IRQF_DISABLED, | 372 | .dma_out_irq_flags = 0, |
| 373 | .dma_out_irq_description = "serial 2 dma tr", | 373 | .dma_out_irq_description = "serial 2 dma tr", |
| 374 | #else | 374 | #else |
| 375 | .dma_out_enabled = 0, | 375 | .dma_out_enabled = 0, |
| @@ -382,7 +382,7 @@ static struct e100_serial rs_table[] = { · 6 unmodified lines | |||
| 382 | .dma_in_enabled = 1, | 382 | .dma_in_enabled = 1, |
| 383 | .dma_in_nbr = SER2_RX_DMA_NBR, | 383 | .dma_in_nbr = SER2_RX_DMA_NBR, |
| 384 | .dma_in_irq_nbr = SER2_DMA_RX_IRQ_NBR, | 384 | .dma_in_irq_nbr = SER2_DMA_RX_IRQ_NBR, |
| 385 | .dma_in_irq_flags = IRQF_DISABLED, | 385 | .dma_in_irq_flags = 0, |
| 386 | .dma_in_irq_description = "serial 2 dma rec", | 386 | .dma_in_irq_description = "serial 2 dma rec", |
| 387 | #else | 387 | #else |
| 388 | .dma_in_enabled = 0, | 388 | .dma_in_enabled = 0, |
| @@ -423,7 +423,7 @@ static struct e100_serial rs_table[] = { · 34 unmodified lines | |||
| 423 | .dma_out_enabled = 1, | 423 | .dma_out_enabled = 1, |
| 424 | .dma_out_nbr = SER3_TX_DMA_NBR, | 424 | .dma_out_nbr = SER3_TX_DMA_NBR, |
| 425 | .dma_out_irq_nbr = SER3_DMA_TX_IRQ_NBR, | 425 | .dma_out_irq_nbr = SER3_DMA_TX_IRQ_NBR, |
| 426 | .dma_out_irq_flags = IRQF_DISABLED, | 426 | .dma_out_irq_flags = 0, |
| 427 | .dma_out_irq_description = "serial 3 dma tr", | 427 | .dma_out_irq_description = "serial 3 dma tr", |
| 428 | #else | 428 | #else |
| 429 | .dma_out_enabled = 0, | 429 | .dma_out_enabled = 0, |
| @@ -436,7 +436,7 @@ static struct e100_serial rs_table[] = { · 6 unmodified lines | |||
| 436 | .dma_in_enabled = 1, | 436 | .dma_in_enabled = 1, |
| 437 | .dma_in_nbr = SER3_RX_DMA_NBR, | 437 | .dma_in_nbr = SER3_RX_DMA_NBR, |
| 438 | .dma_in_irq_nbr = SER3_DMA_RX_IRQ_NBR, | 438 | .dma_in_irq_nbr = SER3_DMA_RX_IRQ_NBR, |
| 439 | .dma_in_irq_flags = IRQF_DISABLED, | 439 | .dma_in_irq_flags = 0, |
| 440 | .dma_in_irq_description = "serial 3 dma rec", | 440 | .dma_in_irq_description = "serial 3 dma rec", |
| 441 | #else | 441 | #else |
| 442 | .dma_in_enabled = 0, | 442 | .dma_in_enabled = 0, |
| @@ -1788,7 +1788,7 @@ static unsigned int handle_descr_data(struct e100_serial *info, · 1345 unmodified lines | |||
| 1788 | struct etrax_recv_buffer *buffer = phys_to_virt(descr->buf) - sizeof *buffer; | 1788 | struct etrax_recv_buffer *buffer = phys_to_virt(descr->buf) - sizeof *buffer; |
| 1789 | 1789 | ||
| 1790 | if (info->recv_cnt + recvl > 65536) { | 1790 | if (info->recv_cnt + recvl > 65536) { |
| 1791 | printk(KERN_CRIT | 1791 | printk(KERN_WARNING |
| 1792 | "%s: Too much pending incoming serial data! Dropping %u bytes.\n", __func__, recvl); | 1792 | "%s: Too much pending incoming serial data! Dropping %u bytes.\n", __func__, recvl); |
| 1793 | return 0; | 1793 | return 0; |
| 1794 | } | 1794 | } |
| @@ -3813,13 +3813,13 @@ rs_close(struct tty_struct *tty, struct file * filp) · 2018 unmodified lines | |||
| 3813 | * one, we've got real problems, since it means the | 3813 | * one, we've got real problems, since it means the |
| 3814 | * serial port won't be shutdown. | 3814 | * serial port won't be shutdown. |
| 3815 | */ | 3815 | */ |
| 3816 | printk(KERN_CRIT | 3816 | printk(KERN_ERR |
| 3817 | "rs_close: bad serial port count; tty->count is 1, " | 3817 | "rs_close: bad serial port count; tty->count is 1, " |
| 3818 | "info->count is %d\n", info->count); | 3818 | "info->count is %d\n", info->count); |
| 3819 | info->count = 1; | 3819 | info->count = 1; |
| 3820 | } | 3820 | } |
| 3821 | if (--info->count < 0) { | 3821 | if (--info->count < 0) { |
| 3822 | printk(KERN_CRIT "rs_close: bad serial port count for ttyS%d: %d\n", | 3822 | printk(KERN_ERR "rs_close: bad serial port count for ttyS%d: %d\n", |
| 3823 | info->line, info->count); | 3823 | info->line, info->count); |
| 3824 | info->count = 0; | 3824 | info->count = 0; |
| 3825 | } | 3825 | } |
| @@ -4452,7 +4452,7 @@ static int __init rs_init(void) · 626 unmodified lines | |||
| 4452 | #if defined(CONFIG_ETRAX_RS485_ON_PA) | 4452 | #if defined(CONFIG_ETRAX_RS485_ON_PA) |
| 4453 | if (cris_io_interface_allocate_pins(if_serial_0, 'a', rs485_pa_bit, | 4453 | if (cris_io_interface_allocate_pins(if_serial_0, 'a', rs485_pa_bit, |
| 4454 | rs485_pa_bit)) { | 4454 | rs485_pa_bit)) { |
| 4455 | printk(KERN_CRIT "ETRAX100LX serial: Could not allocate " | 4455 | printk(KERN_ERR "ETRAX100LX serial: Could not allocate " |
| 4456 | "RS485 pin\n"); | 4456 | "RS485 pin\n"); |
| 4457 | put_tty_driver(driver); | 4457 | put_tty_driver(driver); |
| 4458 | return -EBUSY; | 4458 | return -EBUSY; |
| @@ -4461,7 +4461,7 @@ static int __init rs_init(void) · 2 unmodified lines | |||
| 4461 | #if defined(CONFIG_ETRAX_RS485_ON_PORT_G) | 4461 | #if defined(CONFIG_ETRAX_RS485_ON_PORT_G) |
| 4462 | if (cris_io_interface_allocate_pins(if_serial_0, 'g', rs485_pa_bit, | 4462 | if (cris_io_interface_allocate_pins(if_serial_0, 'g', rs485_pa_bit, |
| 4463 | rs485_port_g_bit)) { | 4463 | rs485_port_g_bit)) { |
| 4464 | printk(KERN_CRIT "ETRAX100LX serial: Could not allocate " | 4464 | printk(KERN_ERR "ETRAX100LX serial: Could not allocate " |
| 4465 | "RS485 pin\n"); | 4465 | "RS485 pin\n"); |
| 4466 | put_tty_driver(driver); | 4466 | put_tty_driver(driver); |
| 4467 | return -EBUSY; | 4467 | return -EBUSY; |
| @@ -4494,7 +4494,7 @@ static int __init rs_init(void) · 26 unmodified lines | |||
| 4494 | if (info->enabled) { | 4494 | if (info->enabled) { |
| 4495 | if (cris_request_io_interface(info->io_if, | 4495 | if (cris_request_io_interface(info->io_if, |
| 4496 | info->io_if_description)) { | 4496 | info->io_if_description)) { |
| 4497 | printk(KERN_CRIT "ETRAX100LX async serial: " | 4497 | printk(KERN_ERR "ETRAX100LX async serial: " |
| 4498 | "Could not allocate IO pins for " | 4498 | "Could not allocate IO pins for " |
| 4499 | "%s, port %d\n", | 4499 | "%s, port %d\n", |
| 4500 | info->io_if_description, i); | 4500 | info->io_if_description, i); |
| @@ -4558,7 +4558,7 @@ static int __init rs_init(void) · 57 unmodified lines | |||
| 4558 | /* hook the irq's for DMA channel 6 and 7, serial output and input, and some more... */ | 4558 | /* hook the irq's for DMA channel 6 and 7, serial output and input, and some more... */ |
| 4559 | 4559 | ||
| 4560 | if (request_irq(SERIAL_IRQ_NBR, ser_interrupt, | 4560 | if (request_irq(SERIAL_IRQ_NBR, ser_interrupt, |
| 4561 | IRQF_SHARED | IRQF_DISABLED, "serial ", driver)) | 4561 | IRQF_SHARED, "serial ", driver)) |
| 4562 | panic("%s: Failed to request irq8", __func__); | 4562 | panic("%s: Failed to request irq8", __func__); |
| 4563 | 4563 | ||
| 4564 | #endif | 4564 | #endif |
| @@ -47,6 +47,7 @@ · 46 unmodified lines | |||
| 47 | #include <linux/serial_core.h> | 47 | #include <linux/serial_core.h> |
| 48 | #include <linux/sysrq.h> | 48 | #include <linux/sysrq.h> |
| 49 | #include <linux/tty.h> | 49 | #include <linux/tty.h> |
| 50 | #include <linux/tty_flip.h> | ||
| 50 | 51 | ||
| 51 | #include <linux/atomic.h> | 52 | #include <linux/atomic.h> |
| 52 | #include <asm/bootinfo.h> | 53 | #include <asm/bootinfo.h> |
| @@ -1554,7 +1554,7 @@ static int __devinit icom_probe(struct pci_dev *dev, · 1553 unmodified lines | |||
| 1554 | 1554 | ||
| 1555 | /* save off irq and request irq line */ | 1555 | /* save off irq and request irq line */ |
| 1556 | if ( (retval = request_irq(dev->irq, icom_interrupt, | 1556 | if ( (retval = request_irq(dev->irq, icom_interrupt, |
| 1557 | IRQF_DISABLED | IRQF_SHARED, ICOM_DRIVER_NAME, | 1557 | IRQF_SHARED, ICOM_DRIVER_NAME, |
| 1558 | (void *) icom_adapter))) { | 1558 | (void *) icom_adapter))) { |
| 1559 | goto probe_exit2; | 1559 | goto probe_exit2; |
| 1560 | } | 1560 | } |
| @@ -508,8 +508,10 @@ static irqreturn_t imx_rxint(int irq, void *dev_id) · 507 unmodified lines | |||
| 508 | if (uart_handle_sysrq_char(&sport->port, (unsigned char)rx)) | 508 | if (uart_handle_sysrq_char(&sport->port, (unsigned char)rx)) |
| 509 | continue; | 509 | continue; |
| 510 | 510 | ||
| 511 | if (rx & (URXD_PRERR | URXD_OVRRUN | URXD_FRMERR) ) { | 511 | if (unlikely(rx & URXD_ERR)) { |
| 512 | if (rx & URXD_PRERR) | 512 | if (rx & URXD_BRK) |
| 513 | sport->port.icount.brk++; | ||
| 514 | else if (rx & URXD_PRERR) | ||
| 513 | sport->port.icount.parity++; | 515 | sport->port.icount.parity++; |
| 514 | else if (rx & URXD_FRMERR) | 516 | else if (rx & URXD_FRMERR) |
| 515 | sport->port.icount.frame++; | 517 | sport->port.icount.frame++; |
| @@ -524,7 +526,9 @@ static irqreturn_t imx_rxint(int irq, void *dev_id) · 8 unmodified lines | |||
| 524 | 526 | ||
| 525 | rx &= sport->port.read_status_mask; | 527 | rx &= sport->port.read_status_mask; |
| 526 | 528 | ||
| 527 | if (rx & URXD_PRERR) | 529 | if (rx & URXD_BRK) |
| 530 | flg = TTY_BREAK; | ||
| 531 | else if (rx & URXD_PRERR) | ||
| 528 | flg = TTY_PARITY; | 532 | flg = TTY_PARITY; |
| 529 | else if (rx & URXD_FRMERR) | 533 | else if (rx & URXD_FRMERR) |
| 530 | flg = TTY_FRAME; | 534 | flg = TTY_FRAME; |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | |||
| 13 | */ | 13 | */ |
| 14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
| 15 | #include <linux/tty.h> | 15 | #include <linux/tty.h> |
| 16 | #include <linux/tty_flip.h> | ||
| 16 | #include <linux/serial.h> | 17 | #include <linux/serial.h> |
| 17 | #include <linux/circ_buf.h> | 18 | #include <linux/circ_buf.h> |
| 18 | #include <linux/serial_reg.h> | 19 | #include <linux/serial_reg.h> |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | |||
| 14 | */ | 14 | */ |
| 15 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
| 16 | #include <linux/tty.h> | 16 | #include <linux/tty.h> |
| 17 | #include <linux/tty_flip.h> | ||
| 17 | #include <linux/serial.h> | 18 | #include <linux/serial.h> |
| 18 | #include <linux/serialP.h> | 19 | #include <linux/serialP.h> |
| 19 | #include <linux/circ_buf.h> | 20 | #include <linux/circ_buf.h> |
| @@ -88,7 +88,6 @@ enum { · 87 unmodified lines | |||
| 88 | 88 | ||
| 89 | /* 4 extra for alignment play space */ | 89 | /* 4 extra for alignment play space */ |
| 90 | #define WRITEBUFLEN ((4096) + 4) | 90 | #define WRITEBUFLEN ((4096) + 4) |
| 91 | #define MYFLIPLEN N_TTY_BUF_SIZE | ||
| 92 | 91 | ||
| 93 | #define JSM_VERSION "jsm: 1.2-1-INKERNEL" | 92 | #define JSM_VERSION "jsm: 1.2-1-INKERNEL" |
| 94 | #define JSM_PARTNUM "40002438_A-INKERNEL" | 93 | #define JSM_PARTNUM "40002438_A-INKERNEL" |
| @@ -150,7 +149,6 @@ struct jsm_board · 55 unmodified lines | |||
| 150 | u32 bd_uart_offset; /* Space between each UART */ | 149 | u32 bd_uart_offset; /* Space between each UART */ |
| 151 | 150 | ||
| 152 | struct jsm_channel *channels[MAXPORTS]; /* array of pointers to our channels. */ | 151 | struct jsm_channel *channels[MAXPORTS]; /* array of pointers to our channels. */ |
| 153 | char *flipbuf; /* Our flip buffer, alloced if board is found */ | ||
| 154 | 152 | ||
| 155 | u32 bd_dividend; /* Board/UARTs specific dividend */ | 153 | u32 bd_dividend; /* Board/UARTs specific dividend */ |
| 156 | 154 | ||
| @@ -177,16 +175,13 @@ struct jsm_board · 20 unmodified lines | |||
| 177 | #define CH_TX_FIFO_LWM 0x0800 /* TX Fifo is below Low Water */ | 175 | #define CH_TX_FIFO_LWM 0x0800 /* TX Fifo is below Low Water */ |
| 178 | #define CH_BREAK_SENDING 0x1000 /* Break is being sent */ | 176 | #define CH_BREAK_SENDING 0x1000 /* Break is being sent */ |
| 179 | #define CH_LOOPBACK 0x2000 /* Channel is in lookback mode */ | 177 | #define CH_LOOPBACK 0x2000 /* Channel is in lookback mode */ |
| 180 | #define CH_FLIPBUF_IN_USE 0x4000 /* Channel's flipbuf is in use */ | ||
| 181 | #define CH_BAUD0 0x08000 /* Used for checking B0 transitions */ | 178 | #define CH_BAUD0 0x08000 /* Used for checking B0 transitions */ |
| 182 | 179 | ||
| 183 | /* Our Read/Error/Write queue sizes */ | 180 | /* Our Read/Error/Write queue sizes */ |
| 184 | #define RQUEUEMASK 0x1FFF /* 8 K - 1 */ | 181 | #define RQUEUEMASK 0x1FFF /* 8 K - 1 */ |
| 185 | #define EQUEUEMASK 0x1FFF /* 8 K - 1 */ | 182 | #define EQUEUEMASK 0x1FFF /* 8 K - 1 */ |
| 186 | #define WQUEUEMASK 0x0FFF /* 4 K - 1 */ | ||
| 187 | #define RQUEUESIZE (RQUEUEMASK + 1) | 183 | #define RQUEUESIZE (RQUEUEMASK + 1) |
| 188 | #define EQUEUESIZE RQUEUESIZE | 184 | #define EQUEUESIZE RQUEUESIZE |
| 189 | #define WQUEUESIZE (WQUEUEMASK + 1) | ||
| 190 | 185 | ||
| 191 | 186 | ||
| 192 | /************************************************************************ | 187 | /************************************************************************ |
| @@ -226,10 +221,6 @@ struct jsm_channel { · 33 unmodified lines | |||
| 226 | u16 ch_e_head; /* Head location of the error queue */ | 221 | u16 ch_e_head; /* Head location of the error queue */ |
| 227 | u16 ch_e_tail; /* Tail location of the error queue */ | 222 | u16 ch_e_tail; /* Tail location of the error queue */ |
| 228 | 223 | ||
| 229 | u8 *ch_wqueue; /* Our write queue buffer - malloc'ed */ | ||
| 230 | u16 ch_w_head; /* Head location of the write queue */ | ||
| 231 | u16 ch_w_tail; /* Tail location of the write queue */ | ||
| 232 | |||
| 233 | u64 ch_rxcount; /* total of data received so far */ | 224 | u64 ch_rxcount; /* total of data received so far */ |
| 234 | u64 ch_txcount; /* total of data transmitted so far */ | 225 | u64 ch_txcount; /* total of data transmitted so far */ |
| 235 | 226 | ||
| @@ -378,7 +369,6 @@ extern int jsm_debug; · 142 unmodified lines | |||
| 378 | * Prototypes for non-static functions used in more than one module | 369 | * Prototypes for non-static functions used in more than one module |
| 379 | * | 370 | * |
| 380 | *************************************************************************/ | 371 | *************************************************************************/ |
| 381 | int jsm_tty_write(struct uart_port *port); | ||
| 382 | int jsm_tty_init(struct jsm_board *); | 372 | int jsm_tty_init(struct jsm_board *); |
| 383 | int jsm_uart_port_init(struct jsm_board *); | 373 | int jsm_uart_port_init(struct jsm_board *); |
| 384 | int jsm_remove_uart_port(struct jsm_board *); | 374 | int jsm_remove_uart_port(struct jsm_board *); |
| @@ -160,27 +160,10 @@ static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device · 159 unmodified lines | |||
| 160 | dev_info(&pdev->dev, "board %d: Digi Neo (rev %d), irq %d\n", | 160 | dev_info(&pdev->dev, "board %d: Digi Neo (rev %d), irq %d\n", |
| 161 | adapter_count, brd->rev, brd->irq); | 161 | adapter_count, brd->rev, brd->irq); |
| 162 | 162 | ||
| 163 | /* | ||
| 164 | * allocate flip buffer for board. | ||
| 165 | * | ||
| 166 | * Okay to malloc with GFP_KERNEL, we are not at interrupt | ||
| 167 | * context, and there are no locks held. | ||
| 168 | */ | ||
| 169 | brd->flipbuf = kzalloc(MYFLIPLEN, GFP_KERNEL); | ||
| 170 | if (!brd->flipbuf) { | ||
| 171 | /* XXX: leaking all resources from jsm_tty_init and | ||
| 172 | jsm_uart_port_init here! */ | ||
| 173 | dev_err(&pdev->dev, "memory allocation for flipbuf failed\n"); | ||
| 174 | rc = -ENOMEM; | ||
| 175 | goto out_free_uart; | ||
| 176 | } | ||
| 177 | |||
| 178 | pci_set_drvdata(pdev, brd); | 163 | pci_set_drvdata(pdev, brd); |
| 179 | pci_save_state(pdev); | 164 | pci_save_state(pdev); |
| 180 | 165 | ||
| 181 | return 0; | 166 | return 0; |
| 182 | out_free_uart: | ||
| 183 | jsm_remove_uart_port(brd); | ||
| 184 | out_free_irq: | 167 | out_free_irq: |
| 185 | jsm_remove_uart_port(brd); | 168 | jsm_remove_uart_port(brd); |
| 186 | free_irq(brd->irq, brd); | 169 | free_irq(brd->irq, brd); |
| @@ -211,14 +194,12 @@ static void __devexit jsm_remove_one(struct pci_dev *pdev) · 24 unmodified lines | |||
| 211 | if (brd->channels[i]) { | 194 | if (brd->channels[i]) { |
| 212 | kfree(brd->channels[i]->ch_rqueue); | 195 | kfree(brd->channels[i]->ch_rqueue); |
| 213 | kfree(brd->channels[i]->ch_equeue); | 196 | kfree(brd->channels[i]->ch_equeue); |
| 214 | kfree(brd->channels[i]->ch_wqueue); | ||
| 215 | kfree(brd->channels[i]); | 197 | kfree(brd->channels[i]); |
| 216 | } | 198 | } |
| 217 | } | 199 | } |
| 218 | 200 | ||
| 219 | pci_release_regions(pdev); | 201 | pci_release_regions(pdev); |
| 220 | pci_disable_device(pdev); | 202 | pci_disable_device(pdev); |
| 221 | kfree(brd->flipbuf); | ||
| 222 | kfree(brd); | 203 | kfree(brd); |
| 223 | } | 204 | } |
| 224 | 205 | ||
| @@ -496,12 +496,15 @@ static void neo_copy_data_from_queue_to_uart(struct jsm_channel *ch) · 495 unmodified lines | |||
| 496 | int s; | 496 | int s; |
| 497 | int qlen; | 497 | int qlen; |
| 498 | u32 len_written = 0; | 498 | u32 len_written = 0; |
| 499 | struct circ_buf *circ; | ||
| 499 | 500 | ||
| 500 | if (!ch) | 501 | if (!ch) |
| 501 | return; | 502 | return; |
| 502 | 503 | ||
| 504 | circ = &ch->uart_port.state->xmit; | ||
| 505 | |||
| 503 | /* No data to write to the UART */ | 506 | /* No data to write to the UART */ |
| 504 | if (ch->ch_w_tail == ch->ch_w_head) | 507 | if (uart_circ_empty(circ)) |
| 505 | return; | 508 | return; |
| 506 | 509 | ||
| 507 | /* If port is "stopped", don't send any data to the UART */ | 510 | /* If port is "stopped", don't send any data to the UART */ |
| @@ -517,11 +520,10 @@ static void neo_copy_data_from_queue_to_uart(struct jsm_channel *ch) · 9 unmodified lines | |||
| 517 | if (ch->ch_cached_lsr & UART_LSR_THRE) { | 520 | if (ch->ch_cached_lsr & UART_LSR_THRE) { |
| 518 | ch->ch_cached_lsr &= ~(UART_LSR_THRE); | 521 | ch->ch_cached_lsr &= ~(UART_LSR_THRE); |
| 519 | 522 | ||
| 520 | writeb(ch->ch_wqueue[ch->ch_w_tail], &ch->ch_neo_uart->txrx); | 523 | writeb(circ->buf[circ->tail], &ch->ch_neo_uart->txrx); |
| 521 | jsm_printk(WRITE, INFO, &ch->ch_bd->pci_dev, | 524 | jsm_printk(WRITE, INFO, &ch->ch_bd->pci_dev, |
| 522 | "Tx data: %x\n", ch->ch_wqueue[ch->ch_w_head]); | 525 | "Tx data: %x\n", circ->buf[circ->tail]); |
| 523 | ch->ch_w_tail++; | 526 | circ->tail = (circ->tail + 1) & (UART_XMIT_SIZE - 1); |
| 524 | ch->ch_w_tail &= WQUEUEMASK; | ||
| 525 | ch->ch_txcount++; | 527 | ch->ch_txcount++; |
| 526 | } | 528 | } |
| 527 | return; | 529 | return; |
| @@ -536,36 +538,36 @@ static void neo_copy_data_from_queue_to_uart(struct jsm_channel *ch) · 8 unmodified lines | |||
| 536 | n = UART_17158_TX_FIFOSIZE - ch->ch_t_tlevel; | 538 | n = UART_17158_TX_FIFOSIZE - ch->ch_t_tlevel; |
| 537 | 539 | ||
| 538 | /* cache head and tail of queue */ | 540 | /* cache head and tail of queue */ |
| 539 | head = ch->ch_w_head & WQUEUEMASK; | 541 | head = circ->head & (UART_XMIT_SIZE - 1); |
| 540 | tail = ch->ch_w_tail & WQUEUEMASK; | 542 | tail = circ->tail & (UART_XMIT_SIZE - 1); |
| 541 | qlen = (head - tail) & WQUEUEMASK; | 543 | qlen = uart_circ_chars_pending(circ); |
| 542 | 544 | ||
| 543 | /* Find minimum of the FIFO space, versus queue length */ | 545 | /* Find minimum of the FIFO space, versus queue length */ |
| 544 | n = min(n, qlen); | 546 | n = min(n, qlen); |
| 545 | 547 | ||
| 546 | while (n > 0) { | 548 | while (n > 0) { |
| 547 | 549 | ||
| 548 | s = ((head >= tail) ? head : WQUEUESIZE) - tail; | 550 | s = ((head >= tail) ? head : UART_XMIT_SIZE) - tail; |
| 549 | s = min(s, n); | 551 | s = min(s, n); |
| 550 | 552 | ||
| 551 | if (s <= 0) | 553 | if (s <= 0) |
| 552 | break; | 554 | break; |
| 553 | 555 | ||
| 554 | memcpy_toio(&ch->ch_neo_uart->txrxburst, ch->ch_wqueue + tail, s); | 556 | memcpy_toio(&ch->ch_neo_uart->txrxburst, circ->buf + tail, s); |
| 555 | /* Add and flip queue if needed */ | 557 | /* Add and flip queue if needed */ |
| 556 | tail = (tail + s) & WQUEUEMASK; | 558 | tail = (tail + s) & (UART_XMIT_SIZE - 1); |
| 557 | n -= s; | 559 | n -= s; |
| 558 | ch->ch_txcount += s; | 560 | ch->ch_txcount += s; |
| 559 | len_written += s; | 561 | len_written += s; |
| 560 | } | 562 | } |
| 561 | 563 | ||
| 562 | /* Update the final tail */ | 564 | /* Update the final tail */ |
| 563 | ch->ch_w_tail = tail & WQUEUEMASK; | 565 | circ->tail = tail & (UART_XMIT_SIZE - 1); |
| 564 | 566 | ||
| 565 | if (len_written >= ch->ch_t_tlevel) | 567 | if (len_written >= ch->ch_t_tlevel) |
| 566 | ch->ch_flags &= ~(CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); | 568 | ch->ch_flags &= ~(CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); |
| 567 | 569 | ||
| 568 | if (!jsm_tty_write(&ch->uart_port)) | 570 | if (uart_circ_empty(circ)) |
| 569 | uart_write_wakeup(&ch->uart_port); | 571 | uart_write_wakeup(&ch->uart_port); |
| 570 | } | 572 | } |
| 571 | 573 | ||
| @@ -946,7 +948,6 @@ static void neo_param(struct jsm_channel *ch) · 374 unmodified lines | |||
| 946 | if ((ch->ch_c_cflag & (CBAUD)) == 0) { | 948 | if ((ch->ch_c_cflag & (CBAUD)) == 0) { |
| 947 | ch->ch_r_head = ch->ch_r_tail = 0; | 949 | ch->ch_r_head = ch->ch_r_tail = 0; |
| 948 | ch->ch_e_head = ch->ch_e_tail = 0; | 950 | ch->ch_e_head = ch->ch_e_tail = 0; |
| 949 | ch->ch_w_head = ch->ch_w_tail = 0; | ||
| 950 | 951 | ||
| 951 | neo_flush_uart_write(ch); | 952 | neo_flush_uart_write(ch); |
| 952 | neo_flush_uart_read(ch); | 953 | neo_flush_uart_read(ch); |
| @@ -118,6 +118,19 @@ static void jsm_tty_set_mctrl(struct uart_port *port, unsigned int mctrl) · 117 unmodified lines | |||
| 118 | udelay(10); | 118 | udelay(10); |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | /* | ||
| 122 | * jsm_tty_write() | ||
| 123 | * | ||
| 124 | * Take data from the user or kernel and send it out to the FEP. | ||
| 125 | * In here exists all the Transparent Print magic as well. | ||
| 126 | */ | ||
| 127 | static void jsm_tty_write(struct uart_port *port) | ||
| 128 | { | ||
| 129 | struct jsm_channel *channel; | ||
| 130 | channel = container_of(port, struct jsm_channel, uart_port); | ||
| 131 | channel->ch_bd->bd_ops->copy_data_from_queue_to_uart(channel); | ||
| 132 | } | ||
| 133 | |||
| 121 | static void jsm_tty_start_tx(struct uart_port *port) | 134 | static void jsm_tty_start_tx(struct uart_port *port) |
| 122 | { | 135 | { |
| 123 | struct jsm_channel *channel = (struct jsm_channel *)port; | 136 | struct jsm_channel *channel = (struct jsm_channel *)port; |
| @@ -216,14 +229,6 @@ static int jsm_tty_open(struct uart_port *port) · 92 unmodified lines | |||
| 216 | return -ENOMEM; | 229 | return -ENOMEM; |
| 217 | } | 230 | } |
| 218 | } | 231 | } |
| 219 | if (!channel->ch_wqueue) { | ||
| 220 | channel->ch_wqueue = kzalloc(WQUEUESIZE, GFP_KERNEL); | ||
| 221 | if (!channel->ch_wqueue) { | ||
| 222 | jsm_printk(INIT, ERR, &channel->ch_bd->pci_dev, | ||
| 223 | "unable to allocate write queue buf"); | ||
| 224 | return -ENOMEM; | ||
| 225 | } | ||
| 226 | } | ||
| 227 | 232 | ||
| 228 | channel->ch_flags &= ~(CH_OPENING); | 233 | channel->ch_flags &= ~(CH_OPENING); |
| 229 | /* | 234 | /* |
| @@ -237,7 +242,6 @@ static int jsm_tty_open(struct uart_port *port) · 7 unmodified lines | |||
| 237 | */ | 242 | */ |
| 238 | channel->ch_r_head = channel->ch_r_tail = 0; | 243 | channel->ch_r_head = channel->ch_r_tail = 0; |
| 239 | channel->ch_e_head = channel->ch_e_tail = 0; | 244 | channel->ch_e_head = channel->ch_e_tail = 0; |
| 240 | channel->ch_w_head = channel->ch_w_tail = 0; | ||
| 241 | 245 | ||
| 242 | brd->bd_ops->flush_uart_write(channel); | 246 | brd->bd_ops->flush_uart_write(channel); |
| 243 | brd->bd_ops->flush_uart_read(channel); | 247 | brd->bd_ops->flush_uart_read(channel); |
| @@ -836,75 +840,3 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch) · 592 unmodified lines | |||
| 836 | } | 840 | } |
| 837 | } | 841 | } |
| 838 | } | 842 | } |
| 839 | |||
| 840 | /* | ||
| 841 | * jsm_tty_write() | ||
| 842 | * | ||
| 843 | * Take data from the user or kernel and send it out to the FEP. | ||
| 844 | * In here exists all the Transparent Print magic as well. | ||
| 845 | */ | ||
| 846 | int jsm_tty_write(struct uart_port *port) | ||
| 847 | { | ||
| 848 | int bufcount; | ||
| 849 | int data_count = 0,data_count1 =0; | ||
| 850 | u16 head; | ||
| 851 | u16 tail; | ||
| 852 | u16 tmask; | ||
| 853 | u32 remain; | ||
| 854 | int temp_tail = port->state->xmit.tail; | ||
| 855 | struct jsm_channel *channel = (struct jsm_channel *)port; | ||
| 856 | |||
| 857 | tmask = WQUEUEMASK; | ||
| 858 | head = (channel->ch_w_head) & tmask; | ||
| 859 | tail = (channel->ch_w_tail) & tmask; | ||
| 860 | |||
| 861 | if ((bufcount = tail - head - 1) < 0) | ||
| 862 | bufcount += WQUEUESIZE; | ||
| 863 | |||
| 864 | bufcount = min(bufcount, 56); | ||
| 865 | remain = WQUEUESIZE - head; | ||
| 866 | |||
| 867 | data_count = 0; | ||
| 868 | if (bufcount >= remain) { | ||
| 869 | bufcount -= remain; | ||
| 870 | while ((port->state->xmit.head != temp_tail) && | ||
| 871 | (data_count < remain)) { | ||
| 872 | channel->ch_wqueue[head++] = | ||
| 873 | port->state->xmit.buf[temp_tail]; | ||
| 874 | |||
| 875 | temp_tail++; | ||
| 876 | temp_tail &= (UART_XMIT_SIZE - 1); | ||
| 877 | data_count++; | ||
| 878 | } | ||
| 879 | if (data_count == remain) head = 0; | ||
| 880 | } | ||
| 881 | |||
| 882 | data_count1 = 0; | ||
| 883 | if (bufcount > 0) { | ||
| 884 | remain = bufcount; | ||
| 885 | while ((port->state->xmit.head != temp_tail) && | ||
| 886 | (data_count1 < remain)) { | ||
| 887 | channel->ch_wqueue[head++] = | ||
| 888 | port->state->xmit.buf[temp_tail]; | ||
| 889 | |||
| 890 | temp_tail++; | ||
| 891 | temp_tail &= (UART_XMIT_SIZE - 1); | ||
| 892 | data_count1++; | ||
| 893 | |||
| 894 | } | ||
| 895 | } | ||
| 896 | |||
| 897 | port->state->xmit.tail = temp_tail; | ||
| 898 | |||
| 899 | data_count += data_count1; | ||
| 900 | if (data_count) { | ||
| 901 | head &= tmask; | ||
| 902 | channel->ch_w_head = head; | ||
| 903 | } | ||
| 904 | |||
| 905 | if (data_count) { | ||
| 906 | channel->ch_bd->bd_ops->copy_data_from_queue_to_uart(channel); | ||
| 907 | } | ||
| 908 | |||
| 909 | return data_count; | ||
| 910 | } | ||
| @@ -338,21 +338,21 @@ lqasc_startup(struct uart_port *port) · 337 unmodified lines | |||
| 338 | ASCCON_ROEN, port->membase + LTQ_ASC_CON); | 338 | ASCCON_ROEN, port->membase + LTQ_ASC_CON); |
| 339 | 339 | ||
| 340 | retval = request_irq(ltq_port->tx_irq, lqasc_tx_int, | 340 | retval = request_irq(ltq_port->tx_irq, lqasc_tx_int, |
| 341 | IRQF_DISABLED, "asc_tx", port); | 341 | 0, "asc_tx", port); |
| 342 | if (retval) { | 342 | if (retval) { |
| 343 | pr_err("failed to request lqasc_tx_int\n"); | 343 | pr_err("failed to request lqasc_tx_int\n"); |
| 344 | return retval; | 344 | return retval; |
| 345 | } | 345 | } |
| 346 | 346 | ||
| 347 | retval = request_irq(ltq_port->rx_irq, lqasc_rx_int, | 347 | retval = request_irq(ltq_port->rx_irq, lqasc_rx_int, |
| 348 | IRQF_DISABLED, "asc_rx", port); | 348 | 0, "asc_rx", port); |
| 349 | if (retval) { | 349 | if (retval) { |
| 350 | pr_err("failed to request lqasc_rx_int\n"); | 350 | pr_err("failed to request lqasc_rx_int\n"); |
| 351 | goto err1; | 351 | goto err1; |
| 352 | } | 352 | } |
| 353 | 353 | ||
| 354 | retval = request_irq(ltq_port->err_irq, lqasc_err_int, | 354 | retval = request_irq(ltq_port->err_irq, lqasc_err_int, |
| 355 | IRQF_DISABLED, "asc_err", port); | 355 | 0, "asc_err", port); |
| 356 | if (retval) { | 356 | if (retval) { |
| 357 | pr_err("failed to request lqasc_err_int\n"); | 357 | pr_err("failed to request lqasc_err_int\n"); |
| 358 | goto err2; | 358 | goto err2; |
| @@ -32,6 +32,7 @@ · 31 unmodified lines | |||
| 32 | 32 | ||
| 33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
| 34 | #include <linux/tty.h> | 34 | #include <linux/tty.h> |
| 35 | #include <linux/tty_flip.h> | ||
| 35 | #include <linux/ioport.h> | 36 | #include <linux/ioport.h> |
| 36 | #include <linux/init.h> | 37 | #include <linux/init.h> |
| 37 | #include <linux/console.h> | 38 | #include <linux/console.h> |
| @@ -47,6 +47,8 @@ · 46 unmodified lines | |||
| 47 | #include <linux/serial.h> | 47 | #include <linux/serial.h> |
| 48 | #include <linux/spi/spi.h> | 48 | #include <linux/spi/spi.h> |
| 49 | #include <linux/freezer.h> | 49 | #include <linux/freezer.h> |
| 50 | #include <linux/tty.h> | ||
| 51 | #include <linux/tty_flip.h> | ||
| 50 | 52 | ||
| 51 | #include <linux/serial_max3100.h> | 53 | #include <linux/serial_max3100.h> |
| 52 | 54 | ||
| @@ -31,6 +31,8 @@ · 30 unmodified lines | |||
| 31 | #include <linux/device.h> | 31 | #include <linux/device.h> |
| 32 | #include <linux/serial_core.h> | 32 | #include <linux/serial_core.h> |
| 33 | #include <linux/serial.h> | 33 | #include <linux/serial.h> |
| 34 | #include <linux/tty.h> | ||
| 35 | #include <linux/tty_flip.h> | ||
| 34 | #include <linux/gpio.h> | 36 | #include <linux/gpio.h> |
| 35 | #include <linux/spi/spi.h> | 37 | #include <linux/spi/spi.h> |
| 36 | #include <linux/freezer.h> | 38 | #include <linux/freezer.h> |
| @@ -380,7 +380,7 @@ static void mcf_config_port(struct uart_port *port, int flags) · 379 unmodified lines | |||
| 380 | /* Clear mask, so no surprise interrupts. */ | 380 | /* Clear mask, so no surprise interrupts. */ |
| 381 | writeb(0, port->membase + MCFUART_UIMR); | 381 | writeb(0, port->membase + MCFUART_UIMR); |
| 382 | 382 | ||
| 383 | if (request_irq(port->irq, mcf_interrupt, IRQF_DISABLED, "UART", port)) | 383 | if (request_irq(port->irq, mcf_interrupt, 0, "UART", port)) |
| 384 | printk(KERN_ERR "MCF: unable to attach ColdFire UART %d " | 384 | printk(KERN_ERR "MCF: unable to attach ColdFire UART %d " |
| 385 | "interrupt vector=%d\n", port->line, port->irq); | 385 | "interrupt vector=%d\n", port->line, port->irq); |
| 386 | } | 386 | } |
| @@ -38,6 +38,7 @@ · 37 unmodified lines | |||
| 38 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
| 39 | #include <linux/io.h> | 39 | #include <linux/io.h> |
| 40 | #include <linux/debugfs.h> | 40 | #include <linux/debugfs.h> |
| 41 | #include <linux/pm_runtime.h> | ||
| 41 | 42 | ||
| 42 | #define HSU_DMA_BUF_SIZE 2048 | 43 | #define HSU_DMA_BUF_SIZE 2048 |
| 43 | 44 | ||
| @@ -764,6 +765,8 @@ static int serial_hsu_startup(struct uart_port *port) · 720 unmodified lines | |||
| 764 | container_of(port, struct uart_hsu_port, port); | 765 | container_of(port, struct uart_hsu_port, port); |
| 765 | unsigned long flags; | 766 | unsigned long flags; |
| 766 | 767 | ||
| 768 | pm_runtime_get_sync(up->dev); | ||
| 769 | |||
| 767 | /* | 770 | /* |
| 768 | * Clear the FIFO buffers and disable them. | 771 | * Clear the FIFO buffers and disable them. |
| 769 | * (they will be reenabled in set_termios()) | 772 | * (they will be reenabled in set_termios()) |
| @@ -871,6 +874,8 @@ static void serial_hsu_shutdown(struct uart_port *port) · 101 unmodified lines | |||
| 871 | UART_FCR_CLEAR_RCVR | | 874 | UART_FCR_CLEAR_RCVR | |
| 872 | UART_FCR_CLEAR_XMIT); | 875 | UART_FCR_CLEAR_XMIT); |
| 873 | serial_out(up, UART_FCR, 0); | 876 | serial_out(up, UART_FCR, 0); |
| 877 | |||
| 878 | pm_runtime_put(up->dev); | ||
| 874 | } | 879 | } |
| 875 | 880 | ||
| 876 | static void | 881 | static void |
| @@ -1249,6 +1254,39 @@ static int serial_hsu_resume(struct pci_dev *pdev) · 372 unmodified lines | |||
| 1249 | #define serial_hsu_resume NULL | 1254 | #define serial_hsu_resume NULL |
| 1250 | #endif | 1255 | #endif |
| 1251 | 1256 | ||
| 1257 | #ifdef CONFIG_PM_RUNTIME | ||
| 1258 | static int serial_hsu_runtime_idle(struct device *dev) | ||
| 1259 | { | ||
| 1260 | int err; | ||
| 1261 | |||
| 1262 | err = pm_schedule_suspend(dev, 500); | ||
| 1263 | if (err) | ||
| 1264 | return -EBUSY; | ||
| 1265 | |||
| 1266 | return 0; | ||
| 1267 | } | ||
| 1268 | |||
| 1269 | static int serial_hsu_runtime_suspend(struct device *dev) | ||
| 1270 | { | ||
| 1271 | return 0; | ||
| 1272 | } | ||
| 1273 | |||
| 1274 | static int serial_hsu_runtime_resume(struct device *dev) | ||
| 1275 | { | ||
| 1276 | return 0; | ||
| 1277 | } | ||
| 1278 | #else | ||
| 1279 | #define serial_hsu_runtime_idle NULL | ||
| 1280 | #define serial_hsu_runtime_suspend NULL | ||
| 1281 | #define serial_hsu_runtime_resume NULL | ||
| 1282 | #endif | ||
| 1283 | |||
| 1284 | static const struct dev_pm_ops serial_hsu_pm_ops = { | ||
| 1285 | .runtime_suspend = serial_hsu_runtime_suspend, | ||
| 1286 | .runtime_resume = serial_hsu_runtime_resume, | ||
| 1287 | .runtime_idle = serial_hsu_runtime_idle, | ||
| 1288 | }; | ||
| 1289 | |||
| 1252 | /* temp global pointer before we settle down on using one or four PCI dev */ | 1290 | /* temp global pointer before we settle down on using one or four PCI dev */ |
| 1253 | static struct hsu_port *phsu; | 1291 | static struct hsu_port *phsu; |
| 1254 | 1292 | ||
| @@ -1315,6 +1353,9 @@ static int serial_hsu_probe(struct pci_dev *pdev, · 60 unmodified lines | |||
| 1315 | pci_set_drvdata(pdev, uport); | 1353 | pci_set_drvdata(pdev, uport); |
| 1316 | } | 1354 | } |
| 1317 | 1355 | ||
| 1356 | pm_runtime_put_noidle(&pdev->dev); | ||
| 1357 | pm_runtime_allow(&pdev->dev); | ||
| 1358 | |||
| 1318 | return 0; | 1359 | return 0; |
| 1319 | 1360 | ||
| 1320 | err_disable: | 1361 | err_disable: |
| @@ -1411,6 +1452,9 @@ static void serial_hsu_remove(struct pci_dev *pdev) · 90 unmodified lines | |||
| 1411 | if (!priv) | 1452 | if (!priv) |
| 1412 | return; | 1453 | return; |
| 1413 | 1454 | ||
| 1455 | pm_runtime_forbid(&pdev->dev); | ||
| 1456 | pm_runtime_get_noresume(&pdev->dev); | ||
| 1457 | |||
| 1414 | /* For port 0/1/2, priv is the address of uart_hsu_port */ | 1458 | /* For port 0/1/2, priv is the address of uart_hsu_port */ |
| 1415 | if (pdev->device != 0x081E) { | 1459 | if (pdev->device != 0x081E) { |
| 1416 | up = priv; | 1460 | up = priv; |
| @@ -1423,7 +1467,7 @@ static void serial_hsu_remove(struct pci_dev *pdev) · 6 unmodified lines | |||
| 1423 | } | 1467 | } |
| 1424 | 1468 | ||
| 1425 | /* First 3 are UART ports, and the 4th is the DMA */ | 1469 | /* First 3 are UART ports, and the 4th is the DMA */ |
| 1426 | static const struct pci_device_id pci_ids[] __devinitdata = { | 1470 | static const struct pci_device_id pci_ids[] __devinitconst = { |
| 1427 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081B) }, | 1471 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081B) }, |
| 1428 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081C) }, | 1472 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081C) }, |
| 1429 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081D) }, | 1473 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081D) }, |
| @@ -1438,6 +1482,9 @@ static struct pci_driver hsu_pci_driver = { · 8 unmodified lines | |||
| 1438 | .remove = __devexit_p(serial_hsu_remove), | 1482 | .remove = __devexit_p(serial_hsu_remove), |
| 1439 | .suspend = serial_hsu_suspend, | 1483 | .suspend = serial_hsu_suspend, |
| 1440 | .resume = serial_hsu_resume, | 1484 | .resume = serial_hsu_resume, |
| 1485 | .driver = { | ||
| 1486 | .pm = &serial_hsu_pm_ops, | ||
| 1487 | }, | ||
| 1441 | }; | 1488 | }; |
| 1442 | 1489 | ||
| 1443 | static int __init hsu_pci_init(void) | 1490 | static int __init hsu_pci_init(void) |
| @@ -34,6 +34,7 @@ · 33 unmodified lines | |||
| 34 | #include <linux/device.h> | 34 | #include <linux/device.h> |
| 35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
| 36 | #include <linux/tty.h> | 36 | #include <linux/tty.h> |
| 37 | #include <linux/tty_flip.h> | ||
| 37 | #include <linux/serial.h> | 38 | #include <linux/serial.h> |
| 38 | #include <linux/sysrq.h> | 39 | #include <linux/sysrq.h> |
| 39 | #include <linux/console.h> | 40 | #include <linux/console.h> |
| @@ -273,7 +274,7 @@ static unsigned int mpc5200b_psc_set_baudrate(struct uart_port *port, · 233 unmodified lines | |||
| 273 | 274 | ||
| 274 | static void mpc52xx_psc_get_irq(struct uart_port *port, struct device_node *np) | 275 | static void mpc52xx_psc_get_irq(struct uart_port *port, struct device_node *np) |
| 275 | { | 276 | { |
| 276 | port->irqflags = IRQF_DISABLED; | 277 | port->irqflags = 0; |
| 277 | port->irq = irq_of_parse_and_map(np, 0); | 278 | port->irq = irq_of_parse_and_map(np, 0); |
| 278 | } | 279 | } |
| 279 | 280 | ||
| @@ -27,6 +27,10 @@ · 26 unmodified lines | |||
| 27 | * interrupt for a low speed UART device | 27 | * interrupt for a low speed UART device |
| 28 | */ | 28 | */ |
| 29 | 29 | ||
| 30 | #ifdef CONFIG_MAGIC_SYSRQ | ||
| 31 | #define SUPPORT_SYSRQ | ||
| 32 | #endif | ||
| 33 | |||
| 30 | #include <linux/module.h> | 34 | #include <linux/module.h> |
| 31 | #include <linux/ioport.h> | 35 | #include <linux/ioport.h> |
| 32 | #include <linux/irq.h> | 36 | #include <linux/irq.h> |
| @@ -73,9 +77,9 @@ struct uart_max3110 { · 40 unmodified lines | |||
| 73 | /* global data structure, may need be removed */ | 77 | /* global data structure, may need be removed */ |
| 74 | static struct uart_max3110 *pmax; | 78 | static struct uart_max3110 *pmax; |
| 75 | 79 | ||
| 76 | static void receive_chars(struct uart_max3110 *max, | 80 | static int receive_chars(struct uart_max3110 *max, |
| 77 | unsigned char *str, int len); | 81 | unsigned short *str, int len); |
| 78 | static int max3110_read_multi(struct uart_max3110 *max, u8 *buf); | 82 | static int max3110_read_multi(struct uart_max3110 *max); |
| 79 | static void max3110_con_receive(struct uart_max3110 *max); | 83 | static void max3110_con_receive(struct uart_max3110 *max); |
| 80 | 84 | ||
| 81 | static int max3110_write_then_read(struct uart_max3110 *max, | 85 | static int max3110_write_then_read(struct uart_max3110 *max, |
| @@ -108,7 +112,6 @@ static int max3110_out(struct uart_max3110 *max, const u16 out) · 26 unmodified lines | |||
| 108 | { | 112 | { |
| 109 | void *buf; | 113 | void *buf; |
| 110 | u16 *obuf, *ibuf; | 114 | u16 *obuf, *ibuf; |
| 111 | u8 ch; | ||
| 112 | int ret; | 115 | int ret; |
| 113 | 116 | ||
| 114 | buf = kzalloc(8, GFP_KERNEL | GFP_DMA); | 117 | buf = kzalloc(8, GFP_KERNEL | GFP_DMA); |
| @@ -125,11 +128,7 @@ static int max3110_out(struct uart_max3110 *max, const u16 out) · 10 unmodified lines | |||
| 125 | goto exit; | 128 | goto exit; |
| 126 | } | 129 | } |
| 127 | 130 | ||
| 128 | /* If some valid data is read back */ | 131 | receive_chars(max, ibuf, 1); |
| 129 | if (*ibuf & MAX3110_READ_DATA_AVAILABLE) { | ||
| 130 | ch = *ibuf & 0xff; | ||
| 131 | receive_chars(max, &ch, 1); | ||
| 132 | } | ||
| 133 | 132 | ||
| 134 | exit: | 133 | exit: |
| 135 | kfree(buf); | 134 | kfree(buf); |
| @@ -142,12 +141,11 @@ exit: · 6 unmodified lines | |||
| 142 | * | 141 | * |
| 143 | * Return how many valide bytes are read back | 142 | * Return how many valide bytes are read back |
| 144 | */ | 143 | */ |
| 145 | static int max3110_read_multi(struct uart_max3110 *max, u8 *rxbuf) | 144 | static int max3110_read_multi(struct uart_max3110 *max) |
| 146 | { | 145 | { |
| 147 | void *buf; | 146 | void *buf; |
| 148 | u16 *obuf, *ibuf; | 147 | u16 *obuf, *ibuf; |
| 149 | u8 *pbuf, valid_str[M3110_RX_FIFO_DEPTH]; | 148 | int ret, blen; |
| 150 | int i, j, blen; | ||
| 151 | 149 | ||
| 152 | blen = M3110_RX_FIFO_DEPTH * sizeof(u16); | 150 | blen = M3110_RX_FIFO_DEPTH * sizeof(u16); |
| 153 | buf = kzalloc(blen * 2, GFP_KERNEL | GFP_DMA); | 151 | buf = kzalloc(blen * 2, GFP_KERNEL | GFP_DMA); |
| @@ -165,19 +163,10 @@ static int max3110_read_multi(struct uart_max3110 *max, u8 *rxbuf) · 11 unmodified lines | |||
| 165 | return 0; | 163 | return 0; |
| 166 | } | 164 | } |
| 167 | 165 | ||
| 168 | /* If caller doesn't provide a buffer, then handle received char */ | 166 | ret = receive_chars(max, ibuf, M3110_RX_FIFO_DEPTH); |
| 169 | pbuf = rxbuf ? rxbuf : valid_str; | ||
| 170 | |||
| 171 | for (i = 0, j = 0; i < M3110_RX_FIFO_DEPTH; i++) { | ||
| 172 | if (ibuf[i] & MAX3110_READ_DATA_AVAILABLE) | ||
| 173 | pbuf[j++] = ibuf[i] & 0xff; | ||
| 174 | } | ||
| 175 | |||
| 176 | if (j && (pbuf == valid_str)) | ||
| 177 | receive_chars(max, valid_str, j); | ||
| 178 | 167 | ||
| 179 | kfree(buf); | 168 | kfree(buf); |
| 180 | return j; | 169 | return ret; |
| 181 | } | 170 | } |
| 182 | 171 | ||
| 183 | static void serial_m3110_con_putchar(struct uart_port *port, int ch) | 172 | static void serial_m3110_con_putchar(struct uart_port *port, int ch) |
| @@ -207,7 +196,7 @@ static void serial_m3110_con_write(struct console *co, · 23 unmodified lines | |||
| 207 | uart_console_write(&pmax->port, s, count, serial_m3110_con_putchar); | 196 | uart_console_write(&pmax->port, s, count, serial_m3110_con_putchar); |
| 208 | 197 | ||
| 209 | if (!test_and_set_bit(CON_TX_NEEDED, &pmax->uart_flags)) | 198 | if (!test_and_set_bit(CON_TX_NEEDED, &pmax->uart_flags)) |
| 210 | wake_up_process(pmax->main_thread); | 199 | wake_up(&pmax->wq); |
| 211 | } | 200 | } |
| 212 | 201 | ||
| 213 | static int __init | 202 | static int __init |
| @@ -276,8 +265,7 @@ static void send_circ_buf(struct uart_max3110 *max, · 62 unmodified lines | |||
| 276 | { | 265 | { |
| 277 | void *buf; | 266 | void *buf; |
| 278 | u16 *obuf, *ibuf; | 267 | u16 *obuf, *ibuf; |
| 279 | u8 valid_str[WORDS_PER_XFER]; | 268 | int i, len, blen, dma_size, left, ret = 0; |
| 280 | int i, j, len, blen, dma_size, left, ret = 0; | ||
| 281 | 269 | ||
| 282 | 270 | ||
| 283 | dma_size = WORDS_PER_XFER * sizeof(u16) * 2; | 271 | dma_size = WORDS_PER_XFER * sizeof(u16) * 2; |
| @@ -301,18 +289,13 @@ static void send_circ_buf(struct uart_max3110 *max, · 17 unmodified lines | |||
| 301 | } | 289 | } |
| 302 | 290 | ||
| 303 | /* Fail to send msg to console is not very critical */ | 291 | /* Fail to send msg to console is not very critical */ |
| 292 | |||
| 304 | ret = max3110_write_then_read(max, obuf, ibuf, blen, 0); | 293 | ret = max3110_write_then_read(max, obuf, ibuf, blen, 0); |
| 305 | if (ret) | 294 | if (ret) |
| 306 | pr_warning(PR_FMT "%s(): get err msg %d\n", | 295 | pr_warning(PR_FMT "%s(): get err msg %d\n", |
| 307 | __func__, ret); | 296 | __func__, ret); |
| 308 | 297 | ||
| 309 | for (i = 0, j = 0; i < len; i++) { | 298 | receive_chars(max, ibuf, len); |
| 310 | if (ibuf[i] & MAX3110_READ_DATA_AVAILABLE) | ||
| 311 | valid_str[j++] = ibuf[i] & 0xff; | ||
| 312 | } | ||
| 313 | |||
| 314 | if (j) | ||
| 315 | receive_chars(max, valid_str, j); | ||
| 316 | 299 | ||
| 317 | max->port.icount.tx += len; | 300 | max->port.icount.tx += len; |
| 318 | left -= len; | 301 | left -= len; |
| @@ -349,33 +332,54 @@ static void serial_m3110_start_tx(struct uart_port *port) · 30 unmodified lines | |||
| 349 | container_of(port, struct uart_max3110, port); | 332 | container_of(port, struct uart_max3110, port); |
| 350 | 333 | ||
| 351 | if (!test_and_set_bit(UART_TX_NEEDED, &max->uart_flags)) | 334 | if (!test_and_set_bit(UART_TX_NEEDED, &max->uart_flags)) |
| 352 | wake_up_process(max->main_thread); | 335 | wake_up(&max->wq); |
| 353 | } | 336 | } |
| 354 | 337 | ||
| 355 | static void receive_chars(struct uart_max3110 *max, unsigned char *str, int len) | 338 | static int |
| 339 | receive_chars(struct uart_max3110 *max, unsigned short *str, int len) | ||
| 356 | { | 340 | { |
| 357 | struct uart_port *port = &max->port; | 341 | struct uart_port *port = &max->port; |
| 358 | struct tty_struct *tty; | 342 | struct tty_struct *tty; |
| 359 | int usable; | 343 | char buf[M3110_RX_FIFO_DEPTH]; |
| 344 | int r, w, usable; | ||
| 360 | 345 | ||
| 361 | /* If uart is not opened, just return */ | 346 | /* If uart is not opened, just return */ |
| 362 | if (!port->state) | 347 | if (!port->state) |
| 363 | return; | 348 | return 0; |
| 364 | 349 | ||
| 365 | tty = port->state->port.tty; | 350 | tty = tty_port_tty_get(&port->state->port); |
| 366 | if (!tty) | 351 | if (!tty) |
| 367 | return; | 352 | return 0; |
| 353 | |||
| 354 | for (r = 0, w = 0; r < len; r++) { | ||
| 355 | if (str[r] & MAX3110_BREAK && | ||
| 356 | uart_handle_break(port)) | ||
| 357 | continue; | ||
| 358 | |||
| 359 | if (str[r] & MAX3110_READ_DATA_AVAILABLE) { | ||
| 360 | if (uart_handle_sysrq_char(port, str[r] & 0xff)) | ||
| 361 | continue; | ||
| 362 | |||
| 363 | buf[w++] = str[r] & 0xff; | ||
| 364 | } | ||
| 365 | } | ||
| 366 | |||
| 367 | if (!w) { | ||
| 368 | tty_kref_put(tty); | ||
| 369 | return 0; | ||
| 370 | } | ||
| 368 | 371 | ||
| 369 | while (len) { | 372 | for (r = 0; w; r += usable, w -= usable) { |
| 370 | usable = tty_buffer_request_room(tty, len); | 373 | usable = tty_buffer_request_room(tty, w); |
| 371 | if (usable) { | 374 | if (usable) { |
| 372 | tty_insert_flip_string(tty, str, usable); | 375 | tty_insert_flip_string(tty, buf + r, usable); |
| 373 | str += usable; | ||
| 374 | port->icount.rx += usable; | 376 | port->icount.rx += usable; |
| 375 | } | 377 | } |
| 376 | len -= usable; | ||
| 377 | } | 378 | } |
| 378 | tty_flip_buffer_push(tty); | 379 | tty_flip_buffer_push(tty); |
| 380 | tty_kref_put(tty); | ||
| 381 | |||
| 382 | return r; | ||
| 379 | } | 383 | } |
| 380 | 384 | ||
| 381 | /* | 385 | /* |
| @@ -390,28 +394,15 @@ static void receive_chars(struct uart_max3110 *max, unsigned char *str, int len) · 8 unmodified lines | |||
| 390 | */ | 394 | */ |
| 391 | static void max3110_con_receive(struct uart_max3110 *max) | 395 | static void max3110_con_receive(struct uart_max3110 *max) |
| 392 | { | 396 | { |
| 393 | int loop = 1, num, total = 0; | 397 | int loop = 1, num; |
| 394 | u8 recv_buf[512], *pbuf; | ||
| 395 | 398 | ||
| 396 | pbuf = recv_buf; | ||
| 397 | do { | 399 | do { |
| 398 | num = max3110_read_multi(max, pbuf); | 400 | num = max3110_read_multi(max); |
| 399 | 401 | ||
| 400 | if (num) { | 402 | if (num) { |
| 401 | loop = 5; | 403 | loop = 5; |
| 402 | pbuf += num; | ||
| 403 | total += num; | ||
| 404 | |||
| 405 | if (total >= 504) { | ||
| 406 | receive_chars(max, recv_buf, total); | ||
| 407 | pbuf = recv_buf; | ||
| 408 | total = 0; | ||
| 409 | } | ||
| 410 | } | 404 | } |
| 411 | } while (--loop); | 405 | } while (--loop); |
| 412 | |||
| 413 | if (total) | ||
| 414 | receive_chars(max, recv_buf, total); | ||
| 415 | } | 406 | } |
| 416 | 407 | ||
| 417 | static int max3110_main_thread(void *_max) | 408 | static int max3110_main_thread(void *_max) |
| @@ -424,7 +415,8 @@ static int max3110_main_thread(void *_max) · 6 unmodified lines | |||
| 424 | pr_info(PR_FMT "start main thread\n"); | 415 | pr_info(PR_FMT "start main thread\n"); |
| 425 | 416 | ||
| 426 | do { | 417 | do { |
| 427 | wait_event_interruptible(*wq, max->uart_flags || kthread_should_stop()); | 418 | wait_event_interruptible(*wq, |
| 419 | max->uart_flags || kthread_should_stop()); | ||
| 428 | 420 | ||
| 429 | mutex_lock(&max->thread_mutex); | 421 | mutex_lock(&max->thread_mutex); |
| 430 | 422 | ||
| @@ -452,8 +444,9 @@ static irqreturn_t serial_m3110_irq(int irq, void *dev_id) · 21 unmodified lines | |||
| 452 | 444 | ||
| 453 | /* max3110's irq is a falling edge, not level triggered, | 445 | /* max3110's irq is a falling edge, not level triggered, |
| 454 | * so no need to disable the irq */ | 446 | * so no need to disable the irq */ |
| 447 | |||
| 455 | if (!test_and_set_bit(BIT_IRQ_PENDING, &max->uart_flags)) | 448 | if (!test_and_set_bit(BIT_IRQ_PENDING, &max->uart_flags)) |
| 456 | wake_up_process(max->main_thread); | 449 | wake_up(&max->wq); |
| 457 | 450 | ||
| 458 | return IRQ_HANDLED; | 451 | return IRQ_HANDLED; |
| 459 | } | 452 | } |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | |||
| 7 | /* status bits for all 4 MAX3110 operate modes */ | 7 | /* status bits for all 4 MAX3110 operate modes */ |
| 8 | #define MAX3110_READ_DATA_AVAILABLE (1 << 15) | 8 | #define MAX3110_READ_DATA_AVAILABLE (1 << 15) |
| 9 | #define MAX3110_WRITE_BUF_EMPTY (1 << 14) | 9 | #define MAX3110_WRITE_BUF_EMPTY (1 << 14) |
| 10 | #define MAX3110_BREAK (1 << 10) | ||
| 10 | 11 | ||
| 11 | #define WC_TAG (3 << 14) | 12 | #define WC_TAG (3 << 14) |
| 12 | #define RC_TAG (1 << 14) | 13 | #define RC_TAG (1 << 14) |
| @@ -804,8 +804,6 @@ static int __init msm_console_setup(struct console *co, char *options) · 803 unmodified lines | |||
| 804 | if (unlikely(!port->membase)) | 804 | if (unlikely(!port->membase)) |
| 805 | return -ENXIO; | 805 | return -ENXIO; |
| 806 | 806 | ||
| 807 | port->cons = co; | ||
| 808 | |||
| 809 | msm_init_clock(port); | 807 | msm_init_clock(port); |
| 810 | 808 | ||
| 811 | if (options) | 809 | if (options) |
| @@ -30,6 +30,8 @@ · 29 unmodified lines | |||
| 30 | 30 | ||
| 31 | #include <linux/serial.h> | 31 | #include <linux/serial.h> |
| 32 | #include <linux/serial_core.h> | 32 | #include <linux/serial_core.h> |
| 33 | #include <linux/tty.h> | ||
| 34 | #include <linux/tty_flip.h> | ||
| 33 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
| 34 | #include <linux/init.h> | 36 | #include <linux/init.h> |
| 35 | #include <linux/interrupt.h> | 37 | #include <linux/interrupt.h> |
| @@ -21,6 +21,8 @@ · 20 unmodified lines | |||
| 21 | #include <linux/ioport.h> | 21 | #include <linux/ioport.h> |
| 22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
| 23 | #include <linux/serial.h> | 23 | #include <linux/serial.h> |
| 24 | #include <linux/tty.h> | ||
| 25 | #include <linux/tty_flip.h> | ||
| 24 | #include <linux/console.h> | 26 | #include <linux/console.h> |
| 25 | #include <linux/delay.h> /* for udelay */ | 27 | #include <linux/delay.h> /* for udelay */ |
| 26 | #include <linux/device.h> | 28 | #include <linux/device.h> |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | |||
| 15 | #include <linux/serial_reg.h> | 15 | #include <linux/serial_reg.h> |
| 16 | #include <linux/serial_core.h> | 16 | #include <linux/serial_core.h> |
| 17 | #include <linux/tty.h> | 17 | #include <linux/tty.h> |
| 18 | #include <linux/tty_flip.h> | ||
| 18 | #include <linux/irqreturn.h> | 19 | #include <linux/irqreturn.h> |
| 19 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
| 20 | #include <linux/of_platform.h> | 21 | #include <linux/of_platform.h> |
| @@ -20,6 +20,8 @@ · 19 unmodified lines | |||
| 20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 21 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
| 22 | #include <linux/serial_core.h> | 22 | #include <linux/serial_core.h> |
| 23 | #include <linux/tty.h> | ||
| 24 | #include <linux/tty_flip.h> | ||
| 23 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
| 24 | #include <linux/io.h> | 26 | #include <linux/io.h> |
| 25 | #include <linux/dmi.h> | 27 | #include <linux/dmi.h> |
| @@ -100,6 +100,16 @@ static inline void receive_chars(struct uart_pxa_port *up, int *status) · 99 unmodified lines | |||
| 100 | int max_count = 256; | 100 | int max_count = 256; |
| 101 | 101 | ||
| 102 | do { | 102 | do { |
| 103 | /* work around Errata #20 according to | ||
| 104 | * Intel(R) PXA27x Processor Family | ||
| 105 | * Specification Update (May 2005) | ||
| 106 | * | ||
| 107 | * Step 2 | ||
| 108 | * Disable the Reciever Time Out Interrupt via IER[RTOEI] | ||
| 109 | */ | ||
| 110 | up->ier &= ~UART_IER_RTOIE; | ||
| 111 | serial_out(up, UART_IER, up->ier); | ||
| 112 | |||
| 103 | ch = serial_in(up, UART_RX); | 113 | ch = serial_in(up, UART_RX); |
| 104 | flag = TTY_NORMAL; | 114 | flag = TTY_NORMAL; |
| 105 | up->port.icount.rx++; | 115 | up->port.icount.rx++; |
| @@ -156,6 +166,16 @@ static inline void receive_chars(struct uart_pxa_port *up, int *status) · 50 unmodified lines | |||
| 156 | *status = serial_in(up, UART_LSR); | 166 | *status = serial_in(up, UART_LSR); |
| 157 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); | 167 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); |
| 158 | tty_flip_buffer_push(tty); | 168 | tty_flip_buffer_push(tty); |
| 169 | |||
| 170 | /* work around Errata #20 according to | ||
| 171 | * Intel(R) PXA27x Processor Family | ||
| 172 | * Specification Update (May 2005) | ||
| 173 | * | ||
| 174 | * Step 6: | ||
| 175 | * No more data in FIFO: Re-enable RTO interrupt via IER[RTOIE] | ||
| 176 | */ | ||
| 177 | up->ier |= UART_IER_RTOIE; | ||
| 178 | serial_out(up, UART_IER, up->ier); | ||
| 159 | } | 179 | } |
| 160 | 180 | ||
| 161 | static void transmit_chars(struct uart_pxa_port *up) | 181 | static void transmit_chars(struct uart_pxa_port *up) |
| @@ -83,6 +83,16 @@ static int s3c24xx_serial_txempty_nofifo(struct uart_port *port) · 82 unmodified lines | |||
| 83 | return (rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE); | 83 | return (rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE); |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | /* | ||
| 87 | * s3c64xx and later SoC's include the interrupt mask and status registers in | ||
| 88 | * the controller itself, unlike the s3c24xx SoC's which have these registers | ||
| 89 | * in the interrupt controller. Check if the port type is s3c64xx or higher. | ||
| 90 | */ | ||
| 91 | static int s3c24xx_serial_has_interrupt_mask(struct uart_port *port) | ||
| 92 | { | ||
| 93 | return to_ourport(port)->info->type == PORT_S3C6400; | ||
| 94 | } | ||
| 95 | |||
| 86 | static void s3c24xx_serial_rx_enable(struct uart_port *port) | 96 | static void s3c24xx_serial_rx_enable(struct uart_port *port) |
| 87 | { | 97 | { |
| 88 | unsigned long flags; | 98 | unsigned long flags; |
| @@ -126,7 +136,11 @@ static void s3c24xx_serial_stop_tx(struct uart_port *port) · 37 unmodified lines | |||
| 126 | struct s3c24xx_uart_port *ourport = to_ourport(port); | 136 | struct s3c24xx_uart_port *ourport = to_ourport(port); |
| 127 | 137 | ||
| 128 | if (tx_enabled(port)) { | 138 | if (tx_enabled(port)) { |
| 129 | disable_irq_nosync(ourport->tx_irq); | 139 | if (s3c24xx_serial_has_interrupt_mask(port)) |
| 140 | __set_bit(S3C64XX_UINTM_TXD, | ||
| 141 | portaddrl(port, S3C64XX_UINTM)); | ||
| 142 | else | ||
| 143 | disable_irq_nosync(ourport->tx_irq); | ||
| 130 | tx_enabled(port) = 0; | 144 | tx_enabled(port) = 0; |
| 131 | if (port->flags & UPF_CONS_FLOW) | 145 | if (port->flags & UPF_CONS_FLOW) |
| 132 | s3c24xx_serial_rx_enable(port); | 146 | s3c24xx_serial_rx_enable(port); |
| @@ -141,19 +155,26 @@ static void s3c24xx_serial_start_tx(struct uart_port *port) · 8 unmodified lines | |||
| 141 | if (port->flags & UPF_CONS_FLOW) | 155 | if (port->flags & UPF_CONS_FLOW) |
| 142 | s3c24xx_serial_rx_disable(port); | 156 | s3c24xx_serial_rx_disable(port); |
| 143 | 157 | ||
| 144 | enable_irq(ourport->tx_irq); | 158 | if (s3c24xx_serial_has_interrupt_mask(port)) |
| 159 | __clear_bit(S3C64XX_UINTM_TXD, | ||
| 160 | portaddrl(port, S3C64XX_UINTM)); | ||
| 161 | else | ||
| 162 | enable_irq(ourport->tx_irq); | ||
| 145 | tx_enabled(port) = 1; | 163 | tx_enabled(port) = 1; |
| 146 | } | 164 | } |
| 147 | } | 165 | } |
| 148 | 166 | ||
| 149 | |||
| 150 | static void s3c24xx_serial_stop_rx(struct uart_port *port) | 167 | static void s3c24xx_serial_stop_rx(struct uart_port *port) |
| 151 | { | 168 | { |
| 152 | struct s3c24xx_uart_port *ourport = to_ourport(port); | 169 | struct s3c24xx_uart_port *ourport = to_ourport(port); |
| 153 | 170 | ||
| 154 | if (rx_enabled(port)) { | 171 | if (rx_enabled(port)) { |
| 155 | dbg("s3c24xx_serial_stop_rx: port=%p\n", port); | 172 | dbg("s3c24xx_serial_stop_rx: port=%p\n", port); |
| 156 | disable_irq_nosync(ourport->rx_irq); | 173 | if (s3c24xx_serial_has_interrupt_mask(port)) |
| 174 | __set_bit(S3C64XX_UINTM_RXD, | ||
| 175 | portaddrl(port, S3C64XX_UINTM)); | ||
| 176 | else | ||
| 177 | disable_irq_nosync(ourport->rx_irq); | ||
| 157 | rx_enabled(port) = 0; | 178 | rx_enabled(port) = 0; |
| 158 | } | 179 | } |
| 159 | } | 180 | } |
| @@ -320,6 +341,28 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id) · 160 unmodified lines | |||
| 320 | return IRQ_HANDLED; | 341 | return IRQ_HANDLED; |
| 321 | } | 342 | } |
| 322 | 343 | ||
| 344 | /* interrupt handler for s3c64xx and later SoC's.*/ | ||
| 345 | static irqreturn_t s3c64xx_serial_handle_irq(int irq, void *id) | ||
| 346 | { | ||
| 347 | struct s3c24xx_uart_port *ourport = id; | ||
| 348 | struct uart_port *port = &ourport->port; | ||
| 349 | unsigned int pend = rd_regl(port, S3C64XX_UINTP); | ||
| 350 | unsigned long flags; | ||
| 351 | irqreturn_t ret = IRQ_HANDLED; | ||
| 352 | |||
| 353 | spin_lock_irqsave(&port->lock, flags); | ||
| 354 | if (pend & S3C64XX_UINTM_RXD_MSK) { | ||
| 355 | ret = s3c24xx_serial_rx_chars(irq, id); | ||
| 356 | wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_RXD_MSK); | ||
| 357 | } | ||
| 358 | if (pend & S3C64XX_UINTM_TXD_MSK) { | ||
| 359 | ret = s3c24xx_serial_tx_chars(irq, id); | ||
| 360 | wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_TXD_MSK); | ||
| 361 | } | ||
| 362 | spin_unlock_irqrestore(&port->lock, flags); | ||
| 363 | return ret; | ||
| 364 | } | ||
| 365 | |||
| 323 | static unsigned int s3c24xx_serial_tx_empty(struct uart_port *port) | 366 | static unsigned int s3c24xx_serial_tx_empty(struct uart_port *port) |
| 324 | { | 367 | { |
| 325 | struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); | 368 | struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); |
| @@ -377,18 +420,25 @@ static void s3c24xx_serial_shutdown(struct uart_port *port) · 51 unmodified lines | |||
| 377 | struct s3c24xx_uart_port *ourport = to_ourport(port); | 420 | struct s3c24xx_uart_port *ourport = to_ourport(port); |
| 378 | 421 | ||
| 379 | if (ourport->tx_claimed) { | 422 | if (ourport->tx_claimed) { |
| 380 | free_irq(ourport->tx_irq, ourport); | 423 | if (!s3c24xx_serial_has_interrupt_mask(port)) |
| 424 | free_irq(ourport->tx_irq, ourport); | ||
| 381 | tx_enabled(port) = 0; | 425 | tx_enabled(port) = 0; |
| 382 | ourport->tx_claimed = 0; | 426 | ourport->tx_claimed = 0; |
| 383 | } | 427 | } |
| 384 | 428 | ||
| 385 | if (ourport->rx_claimed) { | 429 | if (ourport->rx_claimed) { |
| 386 | free_irq(ourport->rx_irq, ourport); | 430 | if (!s3c24xx_serial_has_interrupt_mask(port)) |
| 431 | free_irq(ourport->rx_irq, ourport); | ||
| 387 | ourport->rx_claimed = 0; | 432 | ourport->rx_claimed = 0; |
| 388 | rx_enabled(port) = 0; | 433 | rx_enabled(port) = 0; |
| 389 | } | 434 | } |
| 390 | } | ||
| 391 | 435 | ||
| 436 | /* Clear pending interrupts and mask all interrupts */ | ||
| 437 | if (s3c24xx_serial_has_interrupt_mask(port)) { | ||
| 438 | wr_regl(port, S3C64XX_UINTP, 0xf); | ||
| 439 | wr_regl(port, S3C64XX_UINTM, 0xf); | ||
| 440 | } | ||
| 441 | } | ||
| 392 | 442 | ||
| 393 | static int s3c24xx_serial_startup(struct uart_port *port) | 443 | static int s3c24xx_serial_startup(struct uart_port *port) |
| 394 | { | 444 | { |
| @@ -436,6 +486,33 @@ static int s3c24xx_serial_startup(struct uart_port *port) · 41 unmodified lines | |||
| 436 | return ret; | 486 | return ret; |
| 437 | } | 487 | } |
| 438 | 488 | ||
| 489 | static int s3c64xx_serial_startup(struct uart_port *port) | ||
| 490 | { | ||
| 491 | struct s3c24xx_uart_port *ourport = to_ourport(port); | ||
| 492 | int ret; | ||
| 493 | |||
| 494 | dbg("s3c64xx_serial_startup: port=%p (%08lx,%p)\n", | ||
| 495 | port->mapbase, port->membase); | ||
| 496 | |||
| 497 | ret = request_irq(port->irq, s3c64xx_serial_handle_irq, IRQF_SHARED, | ||
| 498 | s3c24xx_serial_portname(port), ourport); | ||
| 499 | if (ret) { | ||
| 500 | printk(KERN_ERR "cannot get irq %d\n", port->irq); | ||
| 501 | return ret; | ||
| 502 | } | ||
| 503 | |||
| 504 | /* For compatibility with s3c24xx Soc's */ | ||
| 505 | rx_enabled(port) = 1; | ||
| 506 | ourport->rx_claimed = 1; | ||
| 507 | tx_enabled(port) = 0; | ||
| 508 | ourport->tx_claimed = 1; | ||
| 509 | |||
| 510 | /* Enable Rx Interrupt */ | ||
| 511 | __clear_bit(S3C64XX_UINTM_RXD, portaddrl(port, S3C64XX_UINTM)); | ||
| 512 | dbg("s3c64xx_serial_startup ok\n"); | ||
| 513 | return ret; | ||
| 514 | } | ||
| 515 | |||
| 439 | /* power power management control */ | 516 | /* power power management control */ |
| 440 | 517 | ||
| 441 | static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level, | 518 | static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level, |
| @@ -879,7 +956,6 @@ static struct uart_ops s3c24xx_serial_ops = { · 437 unmodified lines | |||
| 879 | .verify_port = s3c24xx_serial_verify_port, | 956 | .verify_port = s3c24xx_serial_verify_port, |
| 880 | }; | 957 | }; |
| 881 | 958 | ||
| 882 | |||
| 883 | static struct uart_driver s3c24xx_uart_drv = { | 959 | static struct uart_driver s3c24xx_uart_drv = { |
| 884 | .owner = THIS_MODULE, | 960 | .owner = THIS_MODULE, |
| 885 | .driver_name = "s3c2410_serial", | 961 | .driver_name = "s3c2410_serial", |
| @@ -895,7 +971,6 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS · 9 unmodified lines | |||
| 895 | .port = { | 971 | .port = { |
| 896 | .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock), | 972 | .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock), |
| 897 | .iotype = UPIO_MEM, | 973 | .iotype = UPIO_MEM, |
| 898 | .irq = IRQ_S3CUART_RX0, | ||
| 899 | .uartclk = 0, | 974 | .uartclk = 0, |
| 900 | .fifosize = 16, | 975 | .fifosize = 16, |
| 901 | .ops = &s3c24xx_serial_ops, | 976 | .ops = &s3c24xx_serial_ops, |
| @@ -907,7 +982,6 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS · 5 unmodified lines | |||
| 907 | .port = { | 982 | .port = { |
| 908 | .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[1].port.lock), | 983 | .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[1].port.lock), |
| 909 | .iotype = UPIO_MEM, | 984 | .iotype = UPIO_MEM, |
| 910 | .irq = IRQ_S3CUART_RX1, | ||
| 911 | .uartclk = 0, | 985 | .uartclk = 0, |
| 912 | .fifosize = 16, | 986 | .fifosize = 16, |
| 913 | .ops = &s3c24xx_serial_ops, | 987 | .ops = &s3c24xx_serial_ops, |
| @@ -921,7 +995,6 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS · 7 unmodified lines | |||
| 921 | .port = { | 995 | .port = { |
| 922 | .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[2].port.lock), | 996 | .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[2].port.lock), |
| 923 | .iotype = UPIO_MEM, | 997 | .iotype = UPIO_MEM, |
| 924 | .irq = IRQ_S3CUART_RX2, | ||
| 925 | .uartclk = 0, | 998 | .uartclk = 0, |
| 926 | .fifosize = 16, | 999 | .fifosize = 16, |
| 927 | .ops = &s3c24xx_serial_ops, | 1000 | .ops = &s3c24xx_serial_ops, |
| @@ -935,7 +1008,6 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS · 7 unmodified lines | |||
| 935 | .port = { | 1008 | .port = { |
| 936 | .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[3].port.lock), | 1009 | .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[3].port.lock), |
| 937 | .iotype = UPIO_MEM, | 1010 | .iotype = UPIO_MEM, |
| 938 | .irq = IRQ_S3CUART_RX3, | ||
| 939 | .uartclk = 0, | 1011 | .uartclk = 0, |
| 940 | .fifosize = 16, | 1012 | .fifosize = 16, |
| 941 | .ops = &s3c24xx_serial_ops, | 1013 | .ops = &s3c24xx_serial_ops, |
| @@ -1077,6 +1149,10 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, · 135 unmodified lines | |||
| 1077 | port->dev = &platdev->dev; | 1149 | port->dev = &platdev->dev; |
| 1078 | ourport->info = info; | 1150 | ourport->info = info; |
| 1079 | 1151 | ||
| 1152 | /* Startup sequence is different for s3c64xx and higher SoC's */ | ||
| 1153 | if (s3c24xx_serial_has_interrupt_mask(port)) | ||
| 1154 | s3c24xx_serial_ops.startup = s3c64xx_serial_startup; | ||
| 1155 | |||
| 1080 | /* copy the info in from provided structure */ | 1156 | /* copy the info in from provided structure */ |
| 1081 | ourport->port.fifosize = info->fifosize; | 1157 | ourport->port.fifosize = info->fifosize; |
| 1082 | 1158 | ||
| @@ -1116,6 +1192,13 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, · 33 unmodified lines | |||
| 1116 | 1192 | ||
| 1117 | ourport->clk = clk_get(&platdev->dev, "uart"); | 1193 | ourport->clk = clk_get(&platdev->dev, "uart"); |
| 1118 | 1194 | ||
| 1195 | /* Keep all interrupts masked and cleared */ | ||
| 1196 | if (s3c24xx_serial_has_interrupt_mask(port)) { | ||
| 1197 | wr_regl(port, S3C64XX_UINTM, 0xf); | ||
| 1198 | wr_regl(port, S3C64XX_UINTP, 0xf); | ||
| 1199 | wr_regl(port, S3C64XX_UINTSP, 0xf); | ||
| 1200 | } | ||
| 1201 | |||
| 1119 | dbg("port: map=%08x, mem=%08x, irq=%d (%d,%d), clock=%ld\n", | 1202 | dbg("port: map=%08x, mem=%08x, irq=%d (%d,%d), clock=%ld\n", |
| 1120 | port->mapbase, port->membase, port->irq, | 1203 | port->mapbase, port->membase, port->irq, |
| 1121 | ourport->rx_irq, ourport->tx_irq, port->uartclk); | 1204 | ourport->rx_irq, ourport->tx_irq, port->uartclk); |
| @@ -61,6 +61,7 @@ struct s3c24xx_uart_port { · 60 unmodified lines | |||
| 61 | /* register access controls */ | 61 | /* register access controls */ |
| 62 | 62 | ||
| 63 | #define portaddr(port, reg) ((port)->membase + (reg)) | 63 | #define portaddr(port, reg) ((port)->membase + (reg)) |
| 64 | #define portaddrl(port, reg) ((unsigned long *)((port)->membase + (reg))) | ||
| 64 | 65 | ||
| 65 | #define rd_regb(port, reg) (__raw_readb(portaddr(port, reg))) | 66 | #define rd_regb(port, reg) (__raw_readb(portaddr(port, reg))) |
| 66 | #define rd_regl(port, reg) (__raw_readl(portaddr(port, reg))) | 67 | #define rd_regl(port, reg) (__raw_readl(portaddr(port, reg))) |
| @@ -37,6 +37,7 @@ · 36 unmodified lines | |||
| 37 | #include <linux/spinlock.h> | 37 | #include <linux/spinlock.h> |
| 38 | #include <linux/sysrq.h> | 38 | #include <linux/sysrq.h> |
| 39 | #include <linux/tty.h> | 39 | #include <linux/tty.h> |
| 40 | #include <linux/tty_flip.h> | ||
| 40 | #include <linux/types.h> | 41 | #include <linux/types.h> |
| 41 | 42 | ||
| 42 | #include <linux/atomic.h> | 43 | #include <linux/atomic.h> |
| @@ -57,7 +57,7 @@ static struct lock_class_key port_lock_key; · 56 unmodified lines | |||
| 57 | 57 | ||
| 58 | static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, | 58 | static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, |
| 59 | struct ktermios *old_termios); | 59 | struct ktermios *old_termios); |
| 60 | static void __uart_wait_until_sent(struct uart_port *port, int timeout); | 60 | static void uart_wait_until_sent(struct tty_struct *tty, int timeout); |
| 61 | static void uart_change_pm(struct uart_state *state, int pm_state); | 61 | static void uart_change_pm(struct uart_state *state, int pm_state); |
| 62 | 62 | ||
| 63 | /* | 63 | /* |
| @@ -72,7 +72,7 @@ void uart_write_wakeup(struct uart_port *port) · 8 unmodified lines | |||
| 72 | * closed. No cookie for you. | 72 | * closed. No cookie for you. |
| 73 | */ | 73 | */ |
| 74 | BUG_ON(!state); | 74 | BUG_ON(!state); |
| 75 | tasklet_schedule(&state->tlet); | 75 | tty_wakeup(state->port.tty); |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | static void uart_stop(struct tty_struct *tty) | 78 | static void uart_stop(struct tty_struct *tty) |
| @@ -107,12 +107,6 @@ static void uart_start(struct tty_struct *tty) · 28 unmodified lines | |||
| 107 | spin_unlock_irqrestore(&port->lock, flags); | 107 | spin_unlock_irqrestore(&port->lock, flags); |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | static void uart_tasklet_action(unsigned long data) | ||
| 111 | { | ||
| 112 | struct uart_state *state = (struct uart_state *)data; | ||
| 113 | tty_wakeup(state->port.tty); | ||
| 114 | } | ||
| 115 | |||
| 116 | static inline void | 110 | static inline void |
| 117 | uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear) | 111 | uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear) |
| 118 | { | 112 | { |
| @@ -255,9 +249,11 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state) · 136 unmodified lines | |||
| 255 | } | 249 | } |
| 256 | 250 | ||
| 257 | /* | 251 | /* |
| 258 | * kill off our tasklet | 252 | * It's possible for shutdown to be called after suspend if we get |
| 253 | * a DCD drop (hangup) at just the right time. Clear suspended bit so | ||
| 254 | * we don't try to resume a port that has been shutdown. | ||
| 259 | */ | 255 | */ |
| 260 | tasklet_kill(&state->tlet); | 256 | clear_bit(ASYNCB_SUSPENDED, &port->flags); |
| 261 | 257 | ||
| 262 | /* | 258 | /* |
| 263 | * Free the transmit buffer page. | 259 | * Free the transmit buffer page. |
| @@ -1261,8 +1257,6 @@ static void uart_close(struct tty_struct *tty, struct file *filp) · 997 unmodified lines | |||
| 1261 | struct uart_port *uport; | 1257 | struct uart_port *uport; |
| 1262 | unsigned long flags; | 1258 | unsigned long flags; |
| 1263 | 1259 | ||
| 1264 | BUG_ON(!tty_locked()); | ||
| 1265 | |||
| 1266 | if (!state) | 1260 | if (!state) |
| 1267 | return; | 1261 | return; |
| 1268 | 1262 | ||
| @@ -1271,12 +1265,11 @@ static void uart_close(struct tty_struct *tty, struct file *filp) · 2 unmodified lines | |||
| 1271 | 1265 | ||
| 1272 | pr_debug("uart_close(%d) called\n", uport->line); | 1266 | pr_debug("uart_close(%d) called\n", uport->line); |
| 1273 | 1267 | ||
| 1274 | mutex_lock(&port->mutex); | ||
| 1275 | spin_lock_irqsave(&port->lock, flags); | 1268 | spin_lock_irqsave(&port->lock, flags); |
| 1276 | 1269 | ||
| 1277 | if (tty_hung_up_p(filp)) { | 1270 | if (tty_hung_up_p(filp)) { |
| 1278 | spin_unlock_irqrestore(&port->lock, flags); | 1271 | spin_unlock_irqrestore(&port->lock, flags); |
| 1279 | goto done; | 1272 | return; |
| 1280 | } | 1273 | } |
| 1281 | 1274 | ||
| 1282 | if ((tty->count == 1) && (port->count != 1)) { | 1275 | if ((tty->count == 1) && (port->count != 1)) { |
| @@ -1298,7 +1291,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp) · 15 unmodified lines | |||
| 1298 | } | 1291 | } |
| 1299 | if (port->count) { | 1292 | if (port->count) { |
| 1300 | spin_unlock_irqrestore(&port->lock, flags); | 1293 | spin_unlock_irqrestore(&port->lock, flags); |
| 1301 | goto done; | 1294 | return; |
| 1302 | } | 1295 | } |
| 1303 | 1296 | ||
| 1304 | /* | 1297 | /* |
| @@ -1306,19 +1299,13 @@ static void uart_close(struct tty_struct *tty, struct file *filp) · 1 unmodified line | |||
| 1306 | * the line discipline to only process XON/XOFF characters by | 1299 | * the line discipline to only process XON/XOFF characters by |
| 1307 | * setting tty->closing. | 1300 | * setting tty->closing. |
| 1308 | */ | 1301 | */ |
| 1302 | set_bit(ASYNCB_CLOSING, &port->flags); | ||
| 1309 | tty->closing = 1; | 1303 | tty->closing = 1; |
| 1310 | spin_unlock_irqrestore(&port->lock, flags); | 1304 | spin_unlock_irqrestore(&port->lock, flags); |
| 1311 | 1305 | ||
| 1312 | if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) { | 1306 | if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) |
| 1313 | /* | 1307 | tty_wait_until_sent_from_close(tty, |
| 1314 | * hack: open-coded tty_wait_until_sent to avoid | 1308 | msecs_to_jiffies(port->closing_wait)); |
| 1315 | * recursive tty_lock | ||
| 1316 | */ | ||
| 1317 | long timeout = msecs_to_jiffies(port->closing_wait); | ||
| 1318 | if (wait_event_interruptible_timeout(tty->write_wait, | ||
| 1319 | !tty_chars_in_buffer(tty), timeout) >= 0) | ||
| 1320 | __uart_wait_until_sent(uport, timeout); | ||
| 1321 | } | ||
| 1322 | 1309 | ||
| 1323 | /* | 1310 | /* |
| 1324 | * At this point, we stop accepting input. To do this, we | 1311 | * At this point, we stop accepting input. To do this, we |
| @@ -1334,9 +1321,10 @@ static void uart_close(struct tty_struct *tty, struct file *filp) · 9 unmodified lines | |||
| 1334 | * has completely drained; this is especially | 1321 | * has completely drained; this is especially |
| 1335 | * important if there is a transmit FIFO! | 1322 | * important if there is a transmit FIFO! |
| 1336 | */ | 1323 | */ |
| 1337 | __uart_wait_until_sent(uport, uport->timeout); | 1324 | uart_wait_until_sent(tty, uport->timeout); |
| 1338 | } | 1325 | } |
| 1339 | 1326 | ||
| 1327 | mutex_lock(&port->mutex); | ||
| 1340 | uart_shutdown(tty, state); | 1328 | uart_shutdown(tty, state); |
| 1341 | uart_flush_buffer(tty); | 1329 | uart_flush_buffer(tty); |
| 1342 | 1330 | ||
| @@ -1361,15 +1349,18 @@ static void uart_close(struct tty_struct *tty, struct file *filp) · 18 unmodified lines | |||
| 1361 | * Wake up anyone trying to open this port. | 1349 | * Wake up anyone trying to open this port. |
| 1362 | */ | 1350 | */ |
| 1363 | clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); | 1351 | clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); |
| 1352 | clear_bit(ASYNCB_CLOSING, &port->flags); | ||
| 1364 | spin_unlock_irqrestore(&port->lock, flags); | 1353 | spin_unlock_irqrestore(&port->lock, flags); |
| 1365 | wake_up_interruptible(&port->open_wait); | 1354 | wake_up_interruptible(&port->open_wait); |
| 1355 | wake_up_interruptible(&port->close_wait); | ||
| 1366 | 1356 | ||
| 1367 | done: | ||
| 1368 | mutex_unlock(&port->mutex); | 1357 | mutex_unlock(&port->mutex); |
| 1369 | } | 1358 | } |
| 1370 | 1359 | ||
| 1371 | static void __uart_wait_until_sent(struct uart_port *port, int timeout) | 1360 | static void uart_wait_until_sent(struct tty_struct *tty, int timeout) |
| 1372 | { | 1361 | { |
| 1362 | struct uart_state *state = tty->driver_data; | ||
| 1363 | struct uart_port *port = state->uart_port; | ||
| 1373 | unsigned long char_time, expire; | 1364 | unsigned long char_time, expire; |
| 1374 | 1365 | ||
| 1375 | if (port->type == PORT_UNKNOWN || port->fifosize == 0) | 1366 | if (port->type == PORT_UNKNOWN || port->fifosize == 0) |
| @@ -1421,16 +1412,6 @@ static void __uart_wait_until_sent(struct uart_port *port, int timeout) · 45 unmodified lines | |||
| 1421 | } | 1412 | } |
| 1422 | } | 1413 | } |
| 1423 | 1414 | ||
| 1424 | static void uart_wait_until_sent(struct tty_struct *tty, int timeout) | ||
| 1425 | { | ||
| 1426 | struct uart_state *state = tty->driver_data; | ||
| 1427 | struct uart_port *port = state->uart_port; | ||
| 1428 | |||
| 1429 | tty_lock(); | ||
| 1430 | __uart_wait_until_sent(port, timeout); | ||
| 1431 | tty_unlock(); | ||
| 1432 | } | ||
| 1433 | |||
| 1434 | /* | 1415 | /* |
| 1435 | * This is called with the BKL held in | 1416 | * This is called with the BKL held in |
| 1436 | * linux/drivers/char/tty_io.c:do_tty_hangup() | 1417 | * linux/drivers/char/tty_io.c:do_tty_hangup() |
| @@ -1443,7 +1424,6 @@ static void uart_hangup(struct tty_struct *tty) · 6 unmodified lines | |||
| 1443 | struct tty_port *port = &state->port; | 1424 | struct tty_port *port = &state->port; |
| 1444 | unsigned long flags; | 1425 | unsigned long flags; |
| 1445 | 1426 | ||
| 1446 | BUG_ON(!tty_locked()); | ||
| 1447 | pr_debug("uart_hangup(%d)\n", state->uart_port->line); | 1427 | pr_debug("uart_hangup(%d)\n", state->uart_port->line); |
| 1448 | 1428 | ||
| 1449 | mutex_lock(&port->mutex); | 1429 | mutex_lock(&port->mutex); |
| @@ -1530,7 +1510,6 @@ static int uart_open(struct tty_struct *tty, struct file *filp) · 80 unmodified lines | |||
| 1530 | struct tty_port *port; | 1510 | struct tty_port *port; |
| 1531 | int retval, line = tty->index; | 1511 | int retval, line = tty->index; |
| 1532 | 1512 | ||
| 1533 | BUG_ON(!tty_locked()); | ||
| 1534 | pr_debug("uart_open(%d) called\n", line); | 1513 | pr_debug("uart_open(%d) called\n", line); |
| 1535 | 1514 | ||
| 1536 | /* | 1515 | /* |
| @@ -2008,6 +1987,8 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) · 471 unmodified lines | |||
| 2008 | if (port->tty && port->tty->termios && termios.c_cflag == 0) | 1987 | if (port->tty && port->tty->termios && termios.c_cflag == 0) |
| 2009 | termios = *(port->tty->termios); | 1988 | termios = *(port->tty->termios); |
| 2010 | 1989 | ||
| 1990 | if (console_suspend_enabled) | ||
| 1991 | uart_change_pm(state, 0); | ||
| 2011 | uport->ops->set_termios(uport, &termios, NULL); | 1992 | uport->ops->set_termios(uport, &termios, NULL); |
| 2012 | if (console_suspend_enabled) | 1993 | if (console_suspend_enabled) |
| 2013 | console_start(uport->cons); | 1994 | console_start(uport->cons); |
| @@ -2068,8 +2049,6 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port) · 54 unmodified lines | |||
| 2068 | case UPIO_MEM32: | 2049 | case UPIO_MEM32: |
| 2069 | case UPIO_AU: | 2050 | case UPIO_AU: |
| 2070 | case UPIO_TSI: | 2051 | case UPIO_TSI: |
| 2071 | case UPIO_DWAPB: | ||
| 2072 | case UPIO_DWAPB32: | ||
| 2073 | snprintf(address, sizeof(address), | 2052 | snprintf(address, sizeof(address), |
| 2074 | "MMIO 0x%llx", (unsigned long long)port->mapbase); | 2053 | "MMIO 0x%llx", (unsigned long long)port->mapbase); |
| 2075 | break; | 2054 | break; |
| @@ -2298,8 +2277,6 @@ int uart_register_driver(struct uart_driver *drv) · 222 unmodified lines | |||
| 2298 | port->ops = &uart_port_ops; | 2277 | port->ops = &uart_port_ops; |
| 2299 | port->close_delay = 500; /* .5 seconds */ | 2278 | port->close_delay = 500; /* .5 seconds */ |
| 2300 | port->closing_wait = 30000; /* 30 seconds */ | 2279 | port->closing_wait = 30000; /* 30 seconds */ |
| 2301 | tasklet_init(&state->tlet, uart_tasklet_action, | ||
| 2302 | (unsigned long)state); | ||
| 2303 | } | 2280 | } |
| 2304 | 2281 | ||
| 2305 | retval = tty_register_driver(normal); | 2282 | retval = tty_register_driver(normal); |
| @@ -2460,11 +2437,6 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport) · 154 unmodified lines | |||
| 2460 | */ | 2437 | */ |
| 2461 | uport->type = PORT_UNKNOWN; | 2438 | uport->type = PORT_UNKNOWN; |
| 2462 | 2439 | ||
| 2463 | /* | ||
| 2464 | * Kill the tasklet, and free resources. | ||
| 2465 | */ | ||
| 2466 | tasklet_kill(&state->tlet); | ||
| 2467 | |||
| 2468 | state->uart_port = NULL; | 2440 | state->uart_port = NULL; |
| 2469 | mutex_unlock(&port_mutex); | 2441 | mutex_unlock(&port_mutex); |
| 2470 | 2442 | ||
| @@ -2489,8 +2461,6 @@ int uart_match_port(struct uart_port *port1, struct uart_port *port2) · 18 unmodified lines | |||
| 2489 | case UPIO_MEM32: | 2461 | case UPIO_MEM32: |
| 2490 | case UPIO_AU: | 2462 | case UPIO_AU: |
| 2491 | case UPIO_TSI: | 2463 | case UPIO_TSI: |
| 2492 | case UPIO_DWAPB: | ||
| 2493 | case UPIO_DWAPB32: | ||
| 2494 | return (port1->mapbase == port2->mapbase); | 2464 | return (port1->mapbase == port2->mapbase); |
| 2495 | } | 2465 | } |
| 2496 | return 0; | 2466 | return 0; |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | |||
| 13 | */ | 13 | */ |
| 14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 15 | #include <linux/tty.h> | 15 | #include <linux/tty.h> |
| 16 | #include <linux/tty_flip.h> | ||
| 16 | #include <linux/ioport.h> | 17 | #include <linux/ioport.h> |
| 17 | #include <linux/init.h> | 18 | #include <linux/init.h> |
| 18 | #include <linux/serial.h> | 19 | #include <linux/serial.h> |
| @@ -336,19 +337,19 @@ static int ks8695uart_startup(struct uart_port *port) · 317 unmodified lines | |||
| 336 | /* | 337 | /* |
| 337 | * Allocate the IRQ | 338 | * Allocate the IRQ |
| 338 | */ | 339 | */ |
| 339 | retval = request_irq(KS8695_IRQ_UART_TX, ks8695uart_tx_chars, IRQF_DISABLED, "UART TX", port); | 340 | retval = request_irq(KS8695_IRQ_UART_TX, ks8695uart_tx_chars, 0, "UART TX", port); |
| 340 | if (retval) | 341 | if (retval) |
| 341 | goto err_tx; | 342 | goto err_tx; |
| 342 | 343 | ||
| 343 | retval = request_irq(KS8695_IRQ_UART_RX, ks8695uart_rx_chars, IRQF_DISABLED, "UART RX", port); | 344 | retval = request_irq(KS8695_IRQ_UART_RX, ks8695uart_rx_chars, 0, "UART RX", port); |
| 344 | if (retval) | 345 | if (retval) |
| 345 | goto err_rx; | 346 | goto err_rx; |
| 346 | 347 | ||
| 347 | retval = request_irq(KS8695_IRQ_UART_LINE_STATUS, ks8695uart_rx_chars, IRQF_DISABLED, "UART LineStatus", port); | 348 | retval = request_irq(KS8695_IRQ_UART_LINE_STATUS, ks8695uart_rx_chars, 0, "UART LineStatus", port); |
| 348 | if (retval) | 349 | if (retval) |
| 349 | goto err_ls; | 350 | goto err_ls; |
| 350 | 351 | ||
| 351 | retval = request_irq(KS8695_IRQ_UART_MODEM_STATUS, ks8695uart_modem_status, IRQF_DISABLED, "UART ModemStatus", port); | 352 | retval = request_irq(KS8695_IRQ_UART_MODEM_STATUS, ks8695uart_modem_status, 0, "UART ModemStatus", port); |
| 352 | if (retval) | 353 | if (retval) |
| 353 | goto err_ms; | 354 | goto err_ms; |
| 354 | 355 | ||
| @@ -28,6 +28,8 @@ · 27 unmodified lines | |||
| 28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
| 29 | #include <linux/serial_core.h> | 29 | #include <linux/serial_core.h> |
| 30 | #include <linux/serial.h> | 30 | #include <linux/serial.h> |
| 31 | #include <linux/tty.h> | ||
| 32 | #include <linux/tty_flip.h> | ||
| 31 | 33 | ||
| 32 | #include <asm/io.h> | 34 | #include <asm/io.h> |
| 33 | 35 | ||
| @@ -1976,7 +1976,7 @@ static int __devinit sci_init_single(struct platform_device *dev, · 1975 unmodified lines | |||
| 1976 | * For the muxed case there's nothing more to do. | 1976 | * For the muxed case there's nothing more to do. |
| 1977 | */ | 1977 | */ |
| 1978 | port->irq = p->irqs[SCIx_RXI_IRQ]; | 1978 | port->irq = p->irqs[SCIx_RXI_IRQ]; |
| 1979 | port->irqflags = IRQF_DISABLED; | 1979 | port->irqflags = 0; |
| 1980 | 1980 | ||
| 1981 | port->serial_in = sci_serial_in; | 1981 | port->serial_in = sci_serial_in; |
| 1982 | port->serial_out = sci_serial_out; | 1982 | port->serial_out = sci_serial_out; |
| @@ -39,6 +39,7 @@ · 38 unmodified lines | |||
| 39 | 39 | ||
| 40 | #include <linux/interrupt.h> | 40 | #include <linux/interrupt.h> |
| 41 | #include <linux/tty.h> | 41 | #include <linux/tty.h> |
| 42 | #include <linux/tty_flip.h> | ||
| 42 | #include <linux/serial.h> | 43 | #include <linux/serial.h> |
| 43 | #include <linux/console.h> | 44 | #include <linux/console.h> |
| 44 | #include <linux/module.h> | 45 | #include <linux/module.h> |
| @@ -737,7 +738,7 @@ static void __init sn_sal_switch_to_interrupts(struct sn_cons_port *port) · 692 unmodified lines | |||
| 737 | DPRINTF("sn_console: switching to interrupt driven console\n"); | 738 | DPRINTF("sn_console: switching to interrupt driven console\n"); |
| 738 | 739 | ||
| 739 | if (request_irq(SGI_UART_VECTOR, sn_sal_interrupt, | 740 | if (request_irq(SGI_UART_VECTOR, sn_sal_interrupt, |
| 740 | IRQF_DISABLED | IRQF_SHARED, | 741 | IRQF_SHARED, |
| 741 | "SAL console driver", port) >= 0) { | 742 | "SAL console driver", port) >= 0) { |
| 742 | spin_lock_irqsave(&port->sc_port.lock, flags); | 743 | spin_lock_irqsave(&port->sc_port.lock, flags); |
| 743 | port->sc_port.irq = SGI_UART_VECTOR; | 744 | port->sc_port.irq = SGI_UART_VECTOR; |
| @@ -23,6 +23,8 @@ · 22 unmodified lines | |||
| 23 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
| 24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
| 25 | #include <linux/serial_core.h> | 25 | #include <linux/serial_core.h> |
| 26 | #include <linux/tty.h> | ||
| 27 | #include <linux/tty_flip.h> | ||
| 26 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
| 27 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
| 28 | #include <linux/ioport.h> | 30 | #include <linux/ioport.h> |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | |||
| 15 | #include <linux/serial.h> | 15 | #include <linux/serial.h> |
| 16 | #include <linux/serial_core.h> | 16 | #include <linux/serial_core.h> |
| 17 | #include <linux/tty.h> | 17 | #include <linux/tty.h> |
| 18 | #include <linux/tty_flip.h> | ||
| 18 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
| 19 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
| 20 | #include <linux/init.h> | 21 | #include <linux/init.h> |
| @@ -20,8 +20,10 @@ · 19 unmodified lines | |||
| 20 | 20 | ||
| 21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
| 22 | #include <linux/serial.h> | 22 | #include <linux/serial.h> |
| 23 | #include <linux/slab.h> | ||
| 24 | #include <linux/serial_core.h> | 23 | #include <linux/serial_core.h> |
| 24 | #include <linux/slab.h> | ||
| 25 | #include <linux/tty.h> | ||
| 26 | #include <linux/tty_flip.h> | ||
| 25 | #include <linux/io.h> | 27 | #include <linux/io.h> |
| 26 | #include <linux/of_platform.h> | 28 | #include <linux/of_platform.h> |
| 27 | #include <linux/dma-mapping.h> | 29 | #include <linux/dma-mapping.h> |
| @@ -12,9 +12,11 @@ · 11 unmodified lines | |||
| 12 | */ | 12 | */ |
| 13 | 13 | ||
| 14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
| 15 | #include <linux/serial.h> | ||
| 15 | #include <linux/serial_core.h> | 16 | #include <linux/serial_core.h> |
| 17 | #include <linux/tty.h> | ||
| 18 | #include <linux/tty_flip.h> | ||
| 16 | #include <linux/console.h> | 19 | #include <linux/console.h> |
| 17 | #include <linux/serial.h> | ||
| 18 | #include <linux/irq.h> | 20 | #include <linux/irq.h> |
| 19 | #include <linux/io.h> | 21 | #include <linux/io.h> |
| 20 | #include <linux/of.h> | 22 | #include <linux/of.h> |
| @@ -63,6 +63,7 @@ · 62 unmodified lines | |||
| 63 | #include <linux/spinlock.h> | 63 | #include <linux/spinlock.h> |
| 64 | #include <linux/sysrq.h> | 64 | #include <linux/sysrq.h> |
| 65 | #include <linux/tty.h> | 65 | #include <linux/tty.h> |
| 66 | #include <linux/tty_flip.h> | ||
| 66 | #include <linux/types.h> | 67 | #include <linux/types.h> |
| 67 | 68 | ||
| 68 | #include <linux/atomic.h> | 69 | #include <linux/atomic.h> |
| @@ -2124,7 +2124,6 @@ static int mgsl_write(struct tty_struct * tty, · 2123 unmodified lines | |||
| 2124 | if ( info->params.mode == MGSL_MODE_HDLC || | 2124 | if ( info->params.mode == MGSL_MODE_HDLC || |
| 2125 | info->params.mode == MGSL_MODE_RAW ) { | 2125 | info->params.mode == MGSL_MODE_RAW ) { |
| 2126 | /* operating in synchronous (frame oriented) mode */ | 2126 | /* operating in synchronous (frame oriented) mode */ |
| 2127 | /* operating in synchronous (frame oriented) mode */ | ||
| 2128 | if (info->tx_active) { | 2127 | if (info->tx_active) { |
| 2129 | 2128 | ||
| 2130 | if ( info->params.mode == MGSL_MODE_HDLC ) { | 2129 | if ( info->params.mode == MGSL_MODE_HDLC ) { |
| @@ -4950,7 +4950,7 @@ CheckAgain: · 4949 unmodified lines | |||
| 4950 | 4950 | ||
| 4951 | if ( debug_level >= DEBUG_LEVEL_DATA ) | 4951 | if ( debug_level >= DEBUG_LEVEL_DATA ) |
| 4952 | trace_block(info,info->rx_buf_list_ex[StartIndex].virt_addr, | 4952 | trace_block(info,info->rx_buf_list_ex[StartIndex].virt_addr, |
| 4953 | min_t(int, framesize,SCABUFSIZE),0); | 4953 | min_t(unsigned int, framesize, SCABUFSIZE), 0); |
| 4954 | 4954 | ||
| 4955 | if (framesize) { | 4955 | if (framesize) { |
| 4956 | if (framesize > info->max_frame_size) | 4956 | if (framesize > info->max_frame_size) |
| @@ -5015,14 +5015,14 @@ static void tx_load_dma_buffer(SLMP_INFO *info, const char *buf, unsigned int co · 58 unmodified lines | |||
| 5015 | SCADESC_EX *desc_ex; | 5015 | SCADESC_EX *desc_ex; |
| 5016 | 5016 | ||
| 5017 | if ( debug_level >= DEBUG_LEVEL_DATA ) | 5017 | if ( debug_level >= DEBUG_LEVEL_DATA ) |
| 5018 | trace_block(info,buf, min_t(int, count,SCABUFSIZE), 1); | 5018 | trace_block(info, buf, min_t(unsigned int, count, SCABUFSIZE), 1); |
| 5019 | 5019 | ||
| 5020 | /* Copy source buffer to one or more DMA buffers, starting with | 5020 | /* Copy source buffer to one or more DMA buffers, starting with |
| 5021 | * the first transmit dma buffer. | 5021 | * the first transmit dma buffer. |
| 5022 | */ | 5022 | */ |
| 5023 | for(i=0;;) | 5023 | for(i=0;;) |
| 5024 | { | 5024 | { |
| 5025 | copy_count = min_t(unsigned short,count,SCABUFSIZE); | 5025 | copy_count = min_t(unsigned int, count, SCABUFSIZE); |
| 5026 | 5026 | ||
| 5027 | desc = &info->tx_buf_list[i]; | 5027 | desc = &info->tx_buf_list[i]; |
| 5028 | desc_ex = &info->tx_buf_list_ex[i]; | 5028 | desc_ex = &info->tx_buf_list_ex[i]; |
| @@ -194,8 +194,7 @@ static inline struct tty_struct *file_tty(struct file *file) · 193 unmodified lines | |||
| 194 | return ((struct tty_file_private *)file->private_data)->tty; | 194 | return ((struct tty_file_private *)file->private_data)->tty; |
| 195 | } | 195 | } |
| 196 | 196 | ||
| 197 | /* Associate a new file with the tty structure */ | 197 | int tty_alloc_file(struct file *file) |
| 198 | int tty_add_file(struct tty_struct *tty, struct file *file) | ||
| 199 | { | 198 | { |
| 200 | struct tty_file_private *priv; | 199 | struct tty_file_private *priv; |
| 201 | 200 | ||
| @@ -203,15 +202,36 @@ int tty_add_file(struct tty_struct *tty, struct file *file) · 1 unmodified line | |||
| 203 | if (!priv) | 202 | if (!priv) |
| 204 | return -ENOMEM; | 203 | return -ENOMEM; |
| 205 | 204 | ||
| 205 | file->private_data = priv; | ||
| 206 | |||
| 207 | return 0; | ||
| 208 | } | ||
| 209 | |||
| 210 | /* Associate a new file with the tty structure */ | ||
| 211 | void tty_add_file(struct tty_struct *tty, struct file *file) | ||
| 212 | { | ||
| 213 | struct tty_file_private *priv = file->private_data; | ||
| 214 | |||
| 206 | priv->tty = tty; | 215 | priv->tty = tty; |
| 207 | priv->file = file; | 216 | priv->file = file; |
| 208 | file->private_data = priv; | ||
| 209 | 217 | ||
| 210 | spin_lock(&tty_files_lock); | 218 | spin_lock(&tty_files_lock); |
| 211 | list_add(&priv->list, &tty->tty_files); | 219 | list_add(&priv->list, &tty->tty_files); |
| 212 | spin_unlock(&tty_files_lock); | 220 | spin_unlock(&tty_files_lock); |
| 221 | } | ||
| 213 | 222 | ||
| 214 | return 0; | 223 | /** |
| 224 | * tty_free_file - free file->private_data | ||
| 225 | * | ||
| 226 | * This shall be used only for fail path handling when tty_add_file was not | ||
| 227 | * called yet. | ||
| 228 | */ | ||
| 229 | void tty_free_file(struct file *file) | ||
| 230 | { | ||
| 231 | struct tty_file_private *priv = file->private_data; | ||
| 232 | |||
| 233 | file->private_data = NULL; | ||
| 234 | kfree(priv); | ||
| 215 | } | 235 | } |
| 216 | 236 | ||
| 217 | /* Delete file from its tty */ | 237 | /* Delete file from its tty */ |
| @@ -222,8 +242,7 @@ void tty_del_file(struct file *file) · 4 unmodified lines | |||
| 222 | spin_lock(&tty_files_lock); | 242 | spin_lock(&tty_files_lock); |
| 223 | list_del(&priv->list); | 243 | list_del(&priv->list); |
| 224 | spin_unlock(&tty_files_lock); | 244 | spin_unlock(&tty_files_lock); |
| 225 | file->private_data = NULL; | 245 | tty_free_file(file); |
| 226 | kfree(priv); | ||
| 227 | } | 246 | } |
| 228 | 247 | ||
| 229 | 248 | ||
| @@ -1811,6 +1830,10 @@ static int tty_open(struct inode *inode, struct file *filp) · 1581 unmodified lines | |||
| 1811 | nonseekable_open(inode, filp); | 1830 | nonseekable_open(inode, filp); |
| 1812 | 1831 | ||
| 1813 | retry_open: | 1832 | retry_open: |
| 1833 | retval = tty_alloc_file(filp); | ||
| 1834 | if (retval) | ||
| 1835 | return -ENOMEM; | ||
| 1836 | |||
| 1814 | noctty = filp->f_flags & O_NOCTTY; | 1837 | noctty = filp->f_flags & O_NOCTTY; |
| 1815 | index = -1; | 1838 | index = -1; |
| 1816 | retval = 0; | 1839 | retval = 0; |
| @@ -1823,6 +1846,7 @@ retry_open: · 6 unmodified lines | |||
| 1823 | if (!tty) { | 1846 | if (!tty) { |
| 1824 | tty_unlock(); | 1847 | tty_unlock(); |
| 1825 | mutex_unlock(&tty_mutex); | 1848 | mutex_unlock(&tty_mutex); |
| 1849 | tty_free_file(filp); | ||
| 1826 | return -ENXIO; | 1850 | return -ENXIO; |
| 1827 | } | 1851 | } |
| 1828 | driver = tty_driver_kref_get(tty->driver); | 1852 | driver = tty_driver_kref_get(tty->driver); |
| @@ -1855,6 +1879,7 @@ retry_open: · 26 unmodified lines | |||
| 1855 | } | 1879 | } |
| 1856 | tty_unlock(); | 1880 | tty_unlock(); |
| 1857 | mutex_unlock(&tty_mutex); | 1881 | mutex_unlock(&tty_mutex); |
| 1882 | tty_free_file(filp); | ||
| 1858 | return -ENODEV; | 1883 | return -ENODEV; |
| 1859 | } | 1884 | } |
| 1860 | 1885 | ||
| @@ -1862,6 +1887,7 @@ retry_open: · 1 unmodified line | |||
| 1862 | if (!driver) { | 1887 | if (!driver) { |
| 1863 | tty_unlock(); | 1888 | tty_unlock(); |
| 1864 | mutex_unlock(&tty_mutex); | 1889 | mutex_unlock(&tty_mutex); |
| 1890 | tty_free_file(filp); | ||
| 1865 | return -ENODEV; | 1891 | return -ENODEV; |
| 1866 | } | 1892 | } |
| 1867 | got_driver: | 1893 | got_driver: |
| @@ -1872,6 +1898,8 @@ got_driver: · 4 unmodified lines | |||
| 1872 | if (IS_ERR(tty)) { | 1898 | if (IS_ERR(tty)) { |
| 1873 | tty_unlock(); | 1899 | tty_unlock(); |
| 1874 | mutex_unlock(&tty_mutex); | 1900 | mutex_unlock(&tty_mutex); |
| 1901 | tty_driver_kref_put(driver); | ||
| 1902 | tty_free_file(filp); | ||
| 1875 | return PTR_ERR(tty); | 1903 | return PTR_ERR(tty); |
| 1876 | } | 1904 | } |
| 1877 | } | 1905 | } |
| @@ -1887,15 +1915,11 @@ got_driver: · 9 unmodified lines | |||
| 1887 | tty_driver_kref_put(driver); | 1915 | tty_driver_kref_put(driver); |
| 1888 | if (IS_ERR(tty)) { | 1916 | if (IS_ERR(tty)) { |
| 1889 | tty_unlock(); | 1917 | tty_unlock(); |
| 1918 | tty_free_file(filp); | ||
| 1890 | return PTR_ERR(tty); | 1919 | return PTR_ERR(tty); |
| 1891 | } | 1920 | } |
| 1892 | 1921 | ||
| 1893 | retval = tty_add_file(tty, filp); | 1922 | tty_add_file(tty, filp); |
| 1894 | if (retval) { | ||
| 1895 | tty_unlock(); | ||
| 1896 | tty_release(inode, filp); | ||
| 1897 | return retval; | ||
| 1898 | } | ||
| 1899 | 1923 | ||
| 1900 | check_tty_count(tty, "tty_open"); | 1924 | check_tty_count(tty, "tty_open"); |
| 1901 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 1925 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
| @@ -2716,6 +2740,8 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd, · 814 unmodified lines | |||
| 2716 | ld = tty_ldisc_ref_wait(tty); | 2740 | ld = tty_ldisc_ref_wait(tty); |
| 2717 | if (ld->ops->compat_ioctl) | 2741 | if (ld->ops->compat_ioctl) |
| 2718 | retval = ld->ops->compat_ioctl(tty, file, cmd, arg); | 2742 | retval = ld->ops->compat_ioctl(tty, file, cmd, arg); |
| 2743 | else | ||
| 2744 | retval = n_tty_compat_ioctl_helper(tty, file, cmd, arg); | ||
| 2719 | tty_ldisc_deref(ld); | 2745 | tty_ldisc_deref(ld); |
| 2720 | 2746 | ||
| 2721 | return retval; | 2747 | return retval; |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
| 20 | #include <linux/bitops.h> | 20 | #include <linux/bitops.h> |
| 21 | #include <linux/mutex.h> | 21 | #include <linux/mutex.h> |
| 22 | #include <linux/compat.h> | ||
| 22 | 23 | ||
| 23 | #include <asm/io.h> | 24 | #include <asm/io.h> |
| 24 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
| @@ -1179,3 +1180,19 @@ int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, · 1154 unmodified lines | |||
| 1179 | } | 1180 | } |
| 1180 | } | 1181 | } |
| 1181 | EXPORT_SYMBOL(n_tty_ioctl_helper); | 1182 | EXPORT_SYMBOL(n_tty_ioctl_helper); |
| 1183 | |||
| 1184 | #ifdef CONFIG_COMPAT | ||
| 1185 | long n_tty_compat_ioctl_helper(struct tty_struct *tty, struct file *file, | ||
| 1186 | unsigned int cmd, unsigned long arg) | ||
| 1187 | { | ||
| 1188 | switch (cmd) { | ||
| 1189 | case TIOCGLCKTRMIOS: | ||
| 1190 | case TIOCSLCKTRMIOS: | ||
| 1191 | return tty_mode_ioctl(tty, file, cmd, (unsigned long) compat_ptr(arg)); | ||
| 1192 | default: | ||
| 1193 | return -ENOIOCTLCMD; | ||
| 1194 | } | ||
| 1195 | } | ||
| 1196 | EXPORT_SYMBOL(n_tty_compat_ioctl_helper); | ||
| 1197 | #endif | ||
| 1198 | |||
| @@ -450,7 +450,6 @@ static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld) · 449 unmodified lines | |||
| 450 | if (ld->ops->open) { | 450 | if (ld->ops->open) { |
| 451 | int ret; | 451 | int ret; |
| 452 | /* BTM here locks versus a hangup event */ | 452 | /* BTM here locks versus a hangup event */ |
| 453 | WARN_ON(!tty_locked()); | ||
| 454 | ret = ld->ops->open(tty); | 453 | ret = ld->ops->open(tty); |
| 455 | if (ret) | 454 | if (ret) |
| 456 | clear_bit(TTY_LDISC_OPEN, &tty->flags); | 455 | clear_bit(TTY_LDISC_OPEN, &tty->flags); |
| @@ -15,30 +15,18 @@ · 14 unmodified lines | |||
| 15 | * Don't use in new code. | 15 | * Don't use in new code. |
| 16 | */ | 16 | */ |
| 17 | static DEFINE_MUTEX(big_tty_mutex); | 17 | static DEFINE_MUTEX(big_tty_mutex); |
| 18 | struct task_struct *__big_tty_mutex_owner; | ||
| 19 | EXPORT_SYMBOL_GPL(__big_tty_mutex_owner); | ||
| 20 | 18 | ||
| 21 | /* | 19 | /* |
| 22 | * Getting the big tty mutex. | 20 | * Getting the big tty mutex. |
| 23 | */ | 21 | */ |
| 24 | void __lockfunc tty_lock(void) | 22 | void __lockfunc tty_lock(void) |
| 25 | { | 23 | { |
| 26 | struct task_struct *task = current; | ||
| 27 | |||
| 28 | WARN_ON(__big_tty_mutex_owner == task); | ||
| 29 | |||
| 30 | mutex_lock(&big_tty_mutex); | 24 | mutex_lock(&big_tty_mutex); |
| 31 | __big_tty_mutex_owner = task; | ||
| 32 | } | 25 | } |
| 33 | EXPORT_SYMBOL(tty_lock); | 26 | EXPORT_SYMBOL(tty_lock); |
| 34 | 27 | ||
| 35 | void __lockfunc tty_unlock(void) | 28 | void __lockfunc tty_unlock(void) |
| 36 | { | 29 | { |
| 37 | struct task_struct *task = current; | ||
| 38 | |||
| 39 | WARN_ON(__big_tty_mutex_owner != task); | ||
| 40 | __big_tty_mutex_owner = NULL; | ||
| 41 | |||
| 42 | mutex_unlock(&big_tty_mutex); | 30 | mutex_unlock(&big_tty_mutex); |
| 43 | } | 31 | } |
| 44 | EXPORT_SYMBOL(tty_unlock); | 32 | EXPORT_SYMBOL(tty_unlock); |
| @@ -350,7 +350,7 @@ int tty_port_close_start(struct tty_port *port, · 349 unmodified lines | |||
| 350 | tty_driver_flush_buffer(tty); | 350 | tty_driver_flush_buffer(tty); |
| 351 | if (test_bit(ASYNCB_INITIALIZED, &port->flags) && | 351 | if (test_bit(ASYNCB_INITIALIZED, &port->flags) && |
| 352 | port->closing_wait != ASYNC_CLOSING_WAIT_NONE) | 352 | port->closing_wait != ASYNC_CLOSING_WAIT_NONE) |
| 353 | tty_wait_until_sent(tty, port->closing_wait); | 353 | tty_wait_until_sent_from_close(tty, port->closing_wait); |
| 354 | if (port->drain_delay) { | 354 | if (port->drain_delay) { |
| 355 | unsigned int bps = tty_get_baud_rate(tty); | 355 | unsigned int bps = tty_get_baud_rate(tty); |
| 356 | long timeout; | 356 | long timeout; |
| @@ -33,7 +33,6 @@ · 32 unmodified lines | |||
| 33 | #include <linux/string.h> | 33 | #include <linux/string.h> |
| 34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
| 35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
| 36 | #include <linux/irq.h> | ||
| 37 | 36 | ||
| 38 | #include <linux/kbd_kern.h> | 37 | #include <linux/kbd_kern.h> |
| 39 | #include <linux/kbd_diacr.h> | 38 | #include <linux/kbd_diacr.h> |
| @@ -43,6 +42,8 @@ · 3 unmodified lines | |||
| 43 | #include <linux/notifier.h> | 42 | #include <linux/notifier.h> |
| 44 | #include <linux/jiffies.h> | 43 | #include <linux/jiffies.h> |
| 45 | 44 | ||
| 45 | #include <asm/irq_regs.h> | ||
| 46 | |||
| 46 | extern void ctrl_alt_del(void); | 47 | extern void ctrl_alt_del(void); |
| 47 | 48 | ||
| 48 | /* | 49 | /* |
| @@ -301,6 +301,8 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t · 300 unmodified lines | |||
| 301 | /* Insert the contents of the selection buffer into the | 301 | /* Insert the contents of the selection buffer into the |
| 302 | * queue of the tty associated with the current console. | 302 | * queue of the tty associated with the current console. |
| 303 | * Invoked by ioctl(). | 303 | * Invoked by ioctl(). |
| 304 | * | ||
| 305 | * Locking: always called with BTM from vt_ioctl | ||
| 304 | */ | 306 | */ |
| 305 | int paste_selection(struct tty_struct *tty) | 307 | int paste_selection(struct tty_struct *tty) |
| 306 | { | 308 | { |
| @@ -310,8 +312,6 @@ int paste_selection(struct tty_struct *tty) · 3 unmodified lines | |||
| 310 | struct tty_ldisc *ld; | 312 | struct tty_ldisc *ld; |
| 311 | DECLARE_WAITQUEUE(wait, current); | 313 | DECLARE_WAITQUEUE(wait, current); |
| 312 | 314 | ||
| 313 | /* always called with BTM from vt_ioctl */ | ||
| 314 | WARN_ON(!tty_locked()); | ||
| 315 | 315 | ||
| 316 | console_lock(); | 316 | console_lock(); |
| 317 | poke_blanked_console(); | 317 | poke_blanked_console(); |
| @@ -259,7 +259,7 @@ EXPORT_SYMBOL_GPL(unregister_vt_notifier); · 258 unmodified lines | |||
| 259 | 259 | ||
| 260 | static void notify_write(struct vc_data *vc, unsigned int unicode) | 260 | static void notify_write(struct vc_data *vc, unsigned int unicode) |
| 261 | { | 261 | { |
| 262 | struct vt_notifier_param param = { .vc = vc, unicode = unicode }; | 262 | struct vt_notifier_param param = { .vc = vc, .c = unicode }; |
| 263 | atomic_notifier_call_chain(&vt_notifier_list, VT_WRITE, ¶m); | 263 | atomic_notifier_call_chain(&vt_notifier_list, VT_WRITE, ¶m); |
| 264 | } | 264 | } |
| 265 | 265 | ||
| @@ -211,6 +211,7 @@ struct serial_rs485 { · 210 unmodified lines | |||
| 211 | #define SER_RS485_RTS_ON_SEND (1 << 1) | 211 | #define SER_RS485_RTS_ON_SEND (1 << 1) |
| 212 | #define SER_RS485_RTS_AFTER_SEND (1 << 2) | 212 | #define SER_RS485_RTS_AFTER_SEND (1 << 2) |
| 213 | #define SER_RS485_RTS_BEFORE_SEND (1 << 3) | 213 | #define SER_RS485_RTS_BEFORE_SEND (1 << 3) |
| 214 | #define SER_RS485_RX_DURING_TX (1 << 4) | ||
| 214 | __u32 delay_rts_before_send; /* Milliseconds */ | 215 | __u32 delay_rts_before_send; /* Milliseconds */ |
| 215 | __u32 delay_rts_after_send; /* Milliseconds */ | 216 | __u32 delay_rts_after_send; /* Milliseconds */ |
| 216 | __u32 padding[5]; /* Memory is cheap, new structs | 217 | __u32 padding[5]; /* Memory is cheap, new structs |
| @@ -35,6 +35,7 @@ struct plat_serial8250_port { · 34 unmodified lines | |||
| 35 | void (*set_termios)(struct uart_port *, | 35 | void (*set_termios)(struct uart_port *, |
| 36 | struct ktermios *new, | 36 | struct ktermios *new, |
| 37 | struct ktermios *old); | 37 | struct ktermios *old); |
| 38 | int (*handle_irq)(struct uart_port *); | ||
| 38 | void (*pm)(struct uart_port *, unsigned int state, | 39 | void (*pm)(struct uart_port *, unsigned int state, |
| 39 | unsigned old); | 40 | unsigned old); |
| 40 | }; | 41 | }; |
| @@ -80,6 +81,7 @@ extern void serial8250_do_set_termios(struct uart_port *port, · 39 unmodified lines | |||
| 80 | struct ktermios *termios, struct ktermios *old); | 81 | struct ktermios *termios, struct ktermios *old); |
| 81 | extern void serial8250_do_pm(struct uart_port *port, unsigned int state, | 82 | extern void serial8250_do_pm(struct uart_port *port, unsigned int state, |
| 82 | unsigned int oldstate); | 83 | unsigned int oldstate); |
| 84 | int serial8250_handle_irq(struct uart_port *port, unsigned int iir); | ||
| 83 | 85 | ||
| 84 | extern void serial8250_set_isa_configurator(void (*v) | 86 | extern void serial8250_set_isa_configurator(void (*v) |
| 85 | (int port, struct uart_port *up, | 87 | (int port, struct uart_port *up, |
| @@ -46,7 +46,8 @@ · 45 unmodified lines | |||
| 46 | #define PORT_AR7 18 /* Texas Instruments AR7 internal UART */ | 46 | #define PORT_AR7 18 /* Texas Instruments AR7 internal UART */ |
| 47 | #define PORT_U6_16550A 19 /* ST-Ericsson U6xxx internal UART */ | 47 | #define PORT_U6_16550A 19 /* ST-Ericsson U6xxx internal UART */ |
| 48 | #define PORT_TEGRA 20 /* NVIDIA Tegra internal UART */ | 48 | #define PORT_TEGRA 20 /* NVIDIA Tegra internal UART */ |
| 49 | #define PORT_MAX_8250 20 /* max port ID */ | 49 | #define PORT_XR17D15X 21 /* Exar XR17D15x UART */ |
| 50 | #define PORT_MAX_8250 21 /* max port ID */ | ||
| 50 | 51 | ||
| 51 | /* | 52 | /* |
| 52 | * ARM specific type numbers. These are not currently guaranteed | 53 | * ARM specific type numbers. These are not currently guaranteed |
| @@ -300,6 +301,7 @@ struct uart_port { · 247 unmodified lines | |||
| 300 | void (*set_termios)(struct uart_port *, | 301 | void (*set_termios)(struct uart_port *, |
| 301 | struct ktermios *new, | 302 | struct ktermios *new, |
| 302 | struct ktermios *old); | 303 | struct ktermios *old); |
| 304 | int (*handle_irq)(struct uart_port *); | ||
| 303 | void (*pm)(struct uart_port *, unsigned int state, | 305 | void (*pm)(struct uart_port *, unsigned int state, |
| 304 | unsigned int old); | 306 | unsigned int old); |
| 305 | unsigned int irq; /* irq number */ | 307 | unsigned int irq; /* irq number */ |
| @@ -317,9 +319,7 @@ struct uart_port { · 11 unmodified lines | |||
| 317 | #define UPIO_MEM32 (3) | 319 | #define UPIO_MEM32 (3) |
| 318 | #define UPIO_AU (4) /* Au1x00 type IO */ | 320 | #define UPIO_AU (4) /* Au1x00 type IO */ |
| 319 | #define UPIO_TSI (5) /* Tsi108/109 type IO */ | 321 | #define UPIO_TSI (5) /* Tsi108/109 type IO */ |
| 320 | #define UPIO_DWAPB (6) /* DesignWare APB UART */ | 322 | #define UPIO_RM9000 (6) /* RM9000 type IO */ |
| 321 | #define UPIO_RM9000 (7) /* RM9000 type IO */ | ||
| 322 | #define UPIO_DWAPB32 (8) /* DesignWare APB UART (32 bit accesses) */ | ||
| 323 | 323 | ||
| 324 | unsigned int read_status_mask; /* driver specific */ | 324 | unsigned int read_status_mask; /* driver specific */ |
| 325 | unsigned int ignore_status_mask; /* driver specific */ | 325 | unsigned int ignore_status_mask; /* driver specific */ |
| @@ -350,6 +350,7 @@ struct uart_port { · 24 unmodified lines | |||
| 350 | #define UPF_MAGIC_MULTIPLIER ((__force upf_t) (1 << 16)) | 350 | #define UPF_MAGIC_MULTIPLIER ((__force upf_t) (1 << 16)) |
| 351 | #define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) | 351 | #define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) |
| 352 | #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24)) | 352 | #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24)) |
| 353 | #define UPF_EXAR_EFR ((__force upf_t) (1 << 25)) | ||
| 353 | /* The exact UART type is known and should not be probed. */ | 354 | /* The exact UART type is known and should not be probed. */ |
| 354 | #define UPF_FIXED_TYPE ((__force upf_t) (1 << 27)) | 355 | #define UPF_FIXED_TYPE ((__force upf_t) (1 << 27)) |
| 355 | #define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28)) | 356 | #define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28)) |
| @@ -384,7 +385,6 @@ struct uart_state { · 28 unmodified lines | |||
| 384 | int pm_state; | 385 | int pm_state; |
| 385 | struct circ_buf xmit; | 386 | struct circ_buf xmit; |
| 386 | 387 | ||
| 387 | struct tasklet_struct tlet; | ||
| 388 | struct uart_port *uart_port; | 388 | struct uart_port *uart_port; |
| 389 | }; | 389 | }; |
| 390 | 390 | ||
| @@ -152,6 +152,7 @@ · 151 unmodified lines | |||
| 152 | * LCR=0xBF (or DLAB=1 for 16C660) | 152 | * LCR=0xBF (or DLAB=1 for 16C660) |
| 153 | */ | 153 | */ |
| 154 | #define UART_EFR 2 /* I/O: Extended Features Register */ | 154 | #define UART_EFR 2 /* I/O: Extended Features Register */ |
| 155 | #define UART_XR_EFR 9 /* I/O: Extended Features Register (XR17D15x) */ | ||
| 155 | #define UART_EFR_CTS 0x80 /* CTS flow control */ | 156 | #define UART_EFR_CTS 0x80 /* CTS flow control */ |
| 156 | #define UART_EFR_RTS 0x40 /* RTS flow control */ | 157 | #define UART_EFR_RTS 0x40 /* RTS flow control */ |
| 157 | #define UART_EFR_SCD 0x20 /* Special character detect */ | 158 | #define UART_EFR_SCD 0x20 /* Special character detect */ |
| @@ -473,7 +473,9 @@ extern void proc_clear_tty(struct task_struct *p); · 472 unmodified lines | |||
| 473 | extern struct tty_struct *get_current_tty(void); | 473 | extern struct tty_struct *get_current_tty(void); |
| 474 | extern void tty_default_fops(struct file_operations *fops); | 474 | extern void tty_default_fops(struct file_operations *fops); |
| 475 | extern struct tty_struct *alloc_tty_struct(void); | 475 | extern struct tty_struct *alloc_tty_struct(void); |
| 476 | extern int tty_add_file(struct tty_struct *tty, struct file *file); | 476 | extern int tty_alloc_file(struct file *file); |
| 477 | extern void tty_add_file(struct tty_struct *tty, struct file *file); | ||
| 478 | extern void tty_free_file(struct file *file); | ||
| 477 | extern void free_tty_struct(struct tty_struct *tty); | 479 | extern void free_tty_struct(struct tty_struct *tty); |
| 478 | extern void initialize_tty_struct(struct tty_struct *tty, | 480 | extern void initialize_tty_struct(struct tty_struct *tty, |
| 479 | struct tty_driver *driver, int idx); | 481 | struct tty_driver *driver, int idx); |
| @@ -581,6 +583,8 @@ extern int __init tty_init(void); · 101 unmodified lines | |||
| 581 | /* tty_ioctl.c */ | 583 | /* tty_ioctl.c */ |
| 582 | extern int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, | 584 | extern int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, |
| 583 | unsigned int cmd, unsigned long arg); | 585 | unsigned int cmd, unsigned long arg); |
| 586 | extern long n_tty_compat_ioctl_helper(struct tty_struct *tty, struct file *file, | ||
| 587 | unsigned int cmd, unsigned long arg); | ||
| 584 | 588 | ||
| 585 | /* serial.c */ | 589 | /* serial.c */ |
| 586 | 590 | ||
| @@ -602,8 +606,24 @@ extern long vt_compat_ioctl(struct tty_struct *tty, · 15 unmodified lines | |||
| 602 | /* functions for preparation of BKL removal */ | 606 | /* functions for preparation of BKL removal */ |
| 603 | extern void __lockfunc tty_lock(void) __acquires(tty_lock); | 607 | extern void __lockfunc tty_lock(void) __acquires(tty_lock); |
| 604 | extern void __lockfunc tty_unlock(void) __releases(tty_lock); | 608 | extern void __lockfunc tty_unlock(void) __releases(tty_lock); |
| 605 | extern struct task_struct *__big_tty_mutex_owner; | 609 | |
| 606 | #define tty_locked() (current == __big_tty_mutex_owner) | 610 | /* |
| 611 | * this shall be called only from where BTM is held (like close) | ||
| 612 | * | ||
| 613 | * We need this to ensure nobody waits for us to finish while we are waiting. | ||
| 614 | * Without this we were encountering system stalls. | ||
| 615 | * | ||
| 616 | * This should be indeed removed with BTM removal later. | ||
| 617 | * | ||
| 618 | * Locking: BTM required. Nobody is allowed to hold port->mutex. | ||
| 619 | */ | ||
| 620 | static inline void tty_wait_until_sent_from_close(struct tty_struct *tty, | ||
| 621 | long timeout) | ||
| 622 | { | ||
| 623 | tty_unlock(); /* tty->ops->close holds the BTM, drop it while waiting */ | ||
| 624 | tty_wait_until_sent(tty, timeout); | ||
| 625 | tty_lock(); | ||
| 626 | } | ||
| 607 | 627 | ||
| 608 | /* | 628 | /* |
| 609 | * wait_event_interruptible_tty -- wait for a condition with the tty lock held | 629 | * wait_event_interruptible_tty -- wait for a condition with the tty lock held |
| @@ -551,7 +551,7 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp) · 550 unmodified lines | |||
| 551 | */ | 551 | */ |
| 552 | tty->closing = 1; | 552 | tty->closing = 1; |
| 553 | if (self->closing_wait != ASYNC_CLOSING_WAIT_NONE) | 553 | if (self->closing_wait != ASYNC_CLOSING_WAIT_NONE) |
| 554 | tty_wait_until_sent(tty, self->closing_wait); | 554 | tty_wait_until_sent_from_close(tty, self->closing_wait); |
| 555 | 555 | ||
| 556 | ircomm_tty_shutdown(self); | 556 | ircomm_tty_shutdown(self); |
| 557 | 557 | ||