diff options
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/8250.c | 9 | ||||
-rw-r--r-- | drivers/serial/8250_pci.c | 86 | ||||
-rw-r--r-- | drivers/serial/Kconfig | 21 | ||||
-rw-r--r-- | drivers/serial/Makefile | 1 | ||||
-rw-r--r-- | drivers/serial/atmel_serial.c | 2 | ||||
-rw-r--r-- | drivers/serial/bcm63xx_uart.c | 890 | ||||
-rw-r--r-- | drivers/serial/cpm_uart/cpm_uart_core.c | 2 | ||||
-rw-r--r-- | drivers/serial/crisv10.c | 1 | ||||
-rw-r--r-- | drivers/serial/icom.c | 54 | ||||
-rw-r--r-- | drivers/serial/mpc52xx_uart.c | 2 | ||||
-rw-r--r-- | drivers/serial/pxa.c | 20 | ||||
-rw-r--r-- | drivers/serial/sa1100.c | 2 | ||||
-rw-r--r-- | drivers/serial/serial_core.c | 7 | ||||
-rw-r--r-- | drivers/serial/serial_txx9.c | 39 | ||||
-rw-r--r-- | drivers/serial/sh-sci.c | 2 |
15 files changed, 1076 insertions, 62 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 2209620d2349..737b4c960971 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -64,6 +64,8 @@ static int serial_index(struct uart_port *port) | |||
64 | return (serial8250_reg.minor - 64) + port->line; | 64 | return (serial8250_reg.minor - 64) + port->line; |
65 | } | 65 | } |
66 | 66 | ||
67 | static unsigned int skip_txen_test; /* force skip of txen test at init time */ | ||
68 | |||
67 | /* | 69 | /* |
68 | * Debugging. | 70 | * Debugging. |
69 | */ | 71 | */ |
@@ -1087,7 +1089,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
1087 | if (!up->port.iobase && !up->port.mapbase && !up->port.membase) | 1089 | if (!up->port.iobase && !up->port.mapbase && !up->port.membase) |
1088 | return; | 1090 | return; |
1089 | 1091 | ||
1090 | DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04x, 0x%p): ", | 1092 | DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04lx, 0x%p): ", |
1091 | serial_index(&up->port), up->port.iobase, up->port.membase); | 1093 | serial_index(&up->port), up->port.iobase, up->port.membase); |
1092 | 1094 | ||
1093 | /* | 1095 | /* |
@@ -2108,7 +2110,7 @@ static int serial8250_startup(struct uart_port *port) | |||
2108 | is variable. So, let's just don't test if we receive | 2110 | is variable. So, let's just don't test if we receive |
2109 | TX irq. This way, we'll never enable UART_BUG_TXEN. | 2111 | TX irq. This way, we'll never enable UART_BUG_TXEN. |
2110 | */ | 2112 | */ |
2111 | if (up->port.flags & UPF_NO_TXEN_TEST) | 2113 | if (skip_txen_test || up->port.flags & UPF_NO_TXEN_TEST) |
2112 | goto dont_test_tx_en; | 2114 | goto dont_test_tx_en; |
2113 | 2115 | ||
2114 | /* | 2116 | /* |
@@ -3248,6 +3250,9 @@ MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices" | |||
3248 | module_param(nr_uarts, uint, 0644); | 3250 | module_param(nr_uarts, uint, 0644); |
3249 | MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")"); | 3251 | MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")"); |
3250 | 3252 | ||
3253 | module_param(skip_txen_test, uint, 0644); | ||
3254 | MODULE_PARM_DESC(skip_txen_test, "Skip checking for the TXEN bug at init time"); | ||
3255 | |||
3251 | #ifdef CONFIG_SERIAL_8250_RSA | 3256 | #ifdef CONFIG_SERIAL_8250_RSA |
3252 | module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444); | 3257 | module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444); |
3253 | MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA"); | 3258 | MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA"); |
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index e7108e75653d..b28af13c45a1 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c | |||
@@ -1561,11 +1561,16 @@ enum pci_board_num_t { | |||
1561 | pbn_exar_XR17C152, | 1561 | pbn_exar_XR17C152, |
1562 | pbn_exar_XR17C154, | 1562 | pbn_exar_XR17C154, |
1563 | pbn_exar_XR17C158, | 1563 | pbn_exar_XR17C158, |
1564 | pbn_exar_ibm_saturn, | ||
1564 | pbn_pasemi_1682M, | 1565 | pbn_pasemi_1682M, |
1565 | pbn_ni8430_2, | 1566 | pbn_ni8430_2, |
1566 | pbn_ni8430_4, | 1567 | pbn_ni8430_4, |
1567 | pbn_ni8430_8, | 1568 | pbn_ni8430_8, |
1568 | pbn_ni8430_16, | 1569 | pbn_ni8430_16, |
1570 | pbn_ADDIDATA_PCIe_1_3906250, | ||
1571 | pbn_ADDIDATA_PCIe_2_3906250, | ||
1572 | pbn_ADDIDATA_PCIe_4_3906250, | ||
1573 | pbn_ADDIDATA_PCIe_8_3906250, | ||
1569 | }; | 1574 | }; |
1570 | 1575 | ||
1571 | /* | 1576 | /* |
@@ -2146,6 +2151,13 @@ static struct pciserial_board pci_boards[] __devinitdata = { | |||
2146 | .base_baud = 921600, | 2151 | .base_baud = 921600, |
2147 | .uart_offset = 0x200, | 2152 | .uart_offset = 0x200, |
2148 | }, | 2153 | }, |
2154 | [pbn_exar_ibm_saturn] = { | ||
2155 | .flags = FL_BASE0, | ||
2156 | .num_ports = 1, | ||
2157 | .base_baud = 921600, | ||
2158 | .uart_offset = 0x200, | ||
2159 | }, | ||
2160 | |||
2149 | /* | 2161 | /* |
2150 | * PA Semi PWRficient PA6T-1682M on-chip UART | 2162 | * PA Semi PWRficient PA6T-1682M on-chip UART |
2151 | */ | 2163 | */ |
@@ -2185,6 +2197,37 @@ static struct pciserial_board pci_boards[] __devinitdata = { | |||
2185 | .uart_offset = 0x10, | 2197 | .uart_offset = 0x10, |
2186 | .first_offset = 0x800, | 2198 | .first_offset = 0x800, |
2187 | }, | 2199 | }, |
2200 | /* | ||
2201 | * ADDI-DATA GmbH PCI-Express communication cards <info@addi-data.com> | ||
2202 | */ | ||
2203 | [pbn_ADDIDATA_PCIe_1_3906250] = { | ||
2204 | .flags = FL_BASE0, | ||
2205 | .num_ports = 1, | ||
2206 | .base_baud = 3906250, | ||
2207 | .uart_offset = 0x200, | ||
2208 | .first_offset = 0x1000, | ||
2209 | }, | ||
2210 | [pbn_ADDIDATA_PCIe_2_3906250] = { | ||
2211 | .flags = FL_BASE0, | ||
2212 | .num_ports = 2, | ||
2213 | .base_baud = 3906250, | ||
2214 | .uart_offset = 0x200, | ||
2215 | .first_offset = 0x1000, | ||
2216 | }, | ||
2217 | [pbn_ADDIDATA_PCIe_4_3906250] = { | ||
2218 | .flags = FL_BASE0, | ||
2219 | .num_ports = 4, | ||
2220 | .base_baud = 3906250, | ||
2221 | .uart_offset = 0x200, | ||
2222 | .first_offset = 0x1000, | ||
2223 | }, | ||
2224 | [pbn_ADDIDATA_PCIe_8_3906250] = { | ||
2225 | .flags = FL_BASE0, | ||
2226 | .num_ports = 8, | ||
2227 | .base_baud = 3906250, | ||
2228 | .uart_offset = 0x200, | ||
2229 | .first_offset = 0x1000, | ||
2230 | }, | ||
2188 | }; | 2231 | }; |
2189 | 2232 | ||
2190 | static const struct pci_device_id softmodem_blacklist[] = { | 2233 | static const struct pci_device_id softmodem_blacklist[] = { |
@@ -2340,7 +2383,7 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board) | |||
2340 | break; | 2383 | break; |
2341 | 2384 | ||
2342 | #ifdef SERIAL_DEBUG_PCI | 2385 | #ifdef SERIAL_DEBUG_PCI |
2343 | printk(KERN_DEBUG "Setup PCI port: port %x, irq %d, type %d\n", | 2386 | printk(KERN_DEBUG "Setup PCI port: port %lx, irq %d, type %d\n", |
2344 | serial_port.iobase, serial_port.irq, serial_port.iotype); | 2387 | serial_port.iobase, serial_port.irq, serial_port.iotype); |
2345 | #endif | 2388 | #endif |
2346 | 2389 | ||
@@ -2649,6 +2692,9 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
2649 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 2692 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
2650 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_485, 0, 0, | 2693 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_485, 0, 0, |
2651 | pbn_b0_8_1843200_200 }, | 2694 | pbn_b0_8_1843200_200 }, |
2695 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, | ||
2696 | PCI_VENDOR_ID_IBM, PCI_SUBDEVICE_ID_IBM_SATURN_SERIAL_ONE_PORT, | ||
2697 | 0, 0, pbn_exar_ibm_saturn }, | ||
2652 | 2698 | ||
2653 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_U530, | 2699 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_U530, |
2654 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 2700 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
@@ -3093,6 +3139,12 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
3093 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_B, | 3139 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_B, |
3094 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 3140 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
3095 | pbn_b0_bt_2_115200 }, | 3141 | pbn_b0_bt_2_115200 }, |
3142 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATTRO_A, | ||
3143 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3144 | pbn_b0_bt_2_115200 }, | ||
3145 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATTRO_B, | ||
3146 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3147 | pbn_b0_bt_2_115200 }, | ||
3096 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_OCTO_A, | 3148 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_OCTO_A, |
3097 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 3149 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
3098 | pbn_b0_bt_4_460800 }, | 3150 | pbn_b0_bt_4_460800 }, |
@@ -3556,6 +3608,38 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
3556 | 0, | 3608 | 0, |
3557 | pbn_b0_8_115200 }, | 3609 | pbn_b0_8_115200 }, |
3558 | 3610 | ||
3611 | { PCI_VENDOR_ID_ADDIDATA, | ||
3612 | PCI_DEVICE_ID_ADDIDATA_APCIe7500, | ||
3613 | PCI_ANY_ID, | ||
3614 | PCI_ANY_ID, | ||
3615 | 0, | ||
3616 | 0, | ||
3617 | pbn_ADDIDATA_PCIe_4_3906250 }, | ||
3618 | |||
3619 | { PCI_VENDOR_ID_ADDIDATA, | ||
3620 | PCI_DEVICE_ID_ADDIDATA_APCIe7420, | ||
3621 | PCI_ANY_ID, | ||
3622 | PCI_ANY_ID, | ||
3623 | 0, | ||
3624 | 0, | ||
3625 | pbn_ADDIDATA_PCIe_2_3906250 }, | ||
3626 | |||
3627 | { PCI_VENDOR_ID_ADDIDATA, | ||
3628 | PCI_DEVICE_ID_ADDIDATA_APCIe7300, | ||
3629 | PCI_ANY_ID, | ||
3630 | PCI_ANY_ID, | ||
3631 | 0, | ||
3632 | 0, | ||
3633 | pbn_ADDIDATA_PCIe_1_3906250 }, | ||
3634 | |||
3635 | { PCI_VENDOR_ID_ADDIDATA, | ||
3636 | PCI_DEVICE_ID_ADDIDATA_APCIe7800, | ||
3637 | PCI_ANY_ID, | ||
3638 | PCI_ANY_ID, | ||
3639 | 0, | ||
3640 | 0, | ||
3641 | pbn_ADDIDATA_PCIe_8_3906250 }, | ||
3642 | |||
3559 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835, | 3643 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835, |
3560 | PCI_VENDOR_ID_IBM, 0x0299, | 3644 | PCI_VENDOR_ID_IBM, 0x0299, |
3561 | 0, 0, pbn_b0_bt_2_115200 }, | 3645 | 0, 0, pbn_b0_bt_2_115200 }, |
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 03422ce878cf..e52257257279 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -862,7 +862,7 @@ config SERIAL_IMX_CONSOLE | |||
862 | 862 | ||
863 | config SERIAL_UARTLITE | 863 | config SERIAL_UARTLITE |
864 | tristate "Xilinx uartlite serial port support" | 864 | tristate "Xilinx uartlite serial port support" |
865 | depends on PPC32 || MICROBLAZE | 865 | depends on PPC32 || MICROBLAZE || MFD_TIMBERDALE |
866 | select SERIAL_CORE | 866 | select SERIAL_CORE |
867 | help | 867 | help |
868 | Say Y here if you want to use the Xilinx uartlite serial controller. | 868 | Say Y here if you want to use the Xilinx uartlite serial controller. |
@@ -1458,4 +1458,23 @@ config SERIAL_TIMBERDALE | |||
1458 | ---help--- | 1458 | ---help--- |
1459 | Add support for UART controller on timberdale. | 1459 | Add support for UART controller on timberdale. |
1460 | 1460 | ||
1461 | config SERIAL_BCM63XX | ||
1462 | tristate "bcm63xx serial port support" | ||
1463 | select SERIAL_CORE | ||
1464 | depends on BCM63XX | ||
1465 | help | ||
1466 | If you have a bcm63xx CPU, you can enable its onboard | ||
1467 | serial port by enabling this options. | ||
1468 | |||
1469 | To compile this driver as a module, choose M here: the | ||
1470 | module will be called bcm963xx_uart. | ||
1471 | |||
1472 | config SERIAL_BCM63XX_CONSOLE | ||
1473 | bool "Console on bcm63xx serial port" | ||
1474 | depends on SERIAL_BCM63XX=y | ||
1475 | select SERIAL_CORE_CONSOLE | ||
1476 | help | ||
1477 | If you have enabled the serial port on the bcm63xx CPU | ||
1478 | you can make it the console by answering Y to this option. | ||
1479 | |||
1461 | endmenu | 1480 | endmenu |
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 97f6fcc8b432..d21d5dd5d048 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile | |||
@@ -34,6 +34,7 @@ obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o | |||
34 | obj-$(CONFIG_SERIAL_PXA) += pxa.o | 34 | obj-$(CONFIG_SERIAL_PXA) += pxa.o |
35 | obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o | 35 | obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o |
36 | obj-$(CONFIG_SERIAL_SA1100) += sa1100.o | 36 | obj-$(CONFIG_SERIAL_SA1100) += sa1100.o |
37 | obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o | ||
37 | obj-$(CONFIG_SERIAL_BFIN) += bfin_5xx.o | 38 | obj-$(CONFIG_SERIAL_BFIN) += bfin_5xx.o |
38 | obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o | 39 | obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o |
39 | obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o | 40 | obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o |
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c index 3551c5cb7094..9d948bccafaf 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/serial/atmel_serial.c | |||
@@ -1531,7 +1531,7 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev) | |||
1531 | void *data; | 1531 | void *data; |
1532 | int ret; | 1532 | int ret; |
1533 | 1533 | ||
1534 | BUILD_BUG_ON(!is_power_of_2(ATMEL_SERIAL_RINGSIZE)); | 1534 | BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1)); |
1535 | 1535 | ||
1536 | port = &atmel_ports[pdev->id]; | 1536 | port = &atmel_ports[pdev->id]; |
1537 | port->backup_imr = 0; | 1537 | port->backup_imr = 0; |
diff --git a/drivers/serial/bcm63xx_uart.c b/drivers/serial/bcm63xx_uart.c new file mode 100644 index 000000000000..beddaa6e9069 --- /dev/null +++ b/drivers/serial/bcm63xx_uart.c | |||
@@ -0,0 +1,890 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Derived from many drivers using generic_serial interface. | ||
7 | * | ||
8 | * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> | ||
9 | * | ||
10 | * Serial driver for BCM63xx integrated UART. | ||
11 | * | ||
12 | * Hardware flow control was _not_ tested since I only have RX/TX on | ||
13 | * my board. | ||
14 | */ | ||
15 | |||
16 | #if defined(CONFIG_SERIAL_BCM63XX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | ||
17 | #define SUPPORT_SYSRQ | ||
18 | #endif | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/console.h> | ||
26 | #include <linux/clk.h> | ||
27 | #include <linux/tty.h> | ||
28 | #include <linux/tty_flip.h> | ||
29 | #include <linux/sysrq.h> | ||
30 | #include <linux/serial.h> | ||
31 | #include <linux/serial_core.h> | ||
32 | |||
33 | #include <bcm63xx_clk.h> | ||
34 | #include <bcm63xx_irq.h> | ||
35 | #include <bcm63xx_regs.h> | ||
36 | #include <bcm63xx_io.h> | ||
37 | |||
38 | #define BCM63XX_NR_UARTS 1 | ||
39 | |||
40 | static struct uart_port ports[BCM63XX_NR_UARTS]; | ||
41 | |||
42 | /* | ||
43 | * rx interrupt mask / stat | ||
44 | * | ||
45 | * mask: | ||
46 | * - rx fifo full | ||
47 | * - rx fifo above threshold | ||
48 | * - rx fifo not empty for too long | ||
49 | */ | ||
50 | #define UART_RX_INT_MASK (UART_IR_MASK(UART_IR_RXOVER) | \ | ||
51 | UART_IR_MASK(UART_IR_RXTHRESH) | \ | ||
52 | UART_IR_MASK(UART_IR_RXTIMEOUT)) | ||
53 | |||
54 | #define UART_RX_INT_STAT (UART_IR_STAT(UART_IR_RXOVER) | \ | ||
55 | UART_IR_STAT(UART_IR_RXTHRESH) | \ | ||
56 | UART_IR_STAT(UART_IR_RXTIMEOUT)) | ||
57 | |||
58 | /* | ||
59 | * tx interrupt mask / stat | ||
60 | * | ||
61 | * mask: | ||
62 | * - tx fifo empty | ||
63 | * - tx fifo below threshold | ||
64 | */ | ||
65 | #define UART_TX_INT_MASK (UART_IR_MASK(UART_IR_TXEMPTY) | \ | ||
66 | UART_IR_MASK(UART_IR_TXTRESH)) | ||
67 | |||
68 | #define UART_TX_INT_STAT (UART_IR_STAT(UART_IR_TXEMPTY) | \ | ||
69 | UART_IR_STAT(UART_IR_TXTRESH)) | ||
70 | |||
71 | /* | ||
72 | * external input interrupt | ||
73 | * | ||
74 | * mask: any edge on CTS, DCD | ||
75 | */ | ||
76 | #define UART_EXTINP_INT_MASK (UART_EXTINP_IRMASK(UART_EXTINP_IR_CTS) | \ | ||
77 | UART_EXTINP_IRMASK(UART_EXTINP_IR_DCD)) | ||
78 | |||
79 | /* | ||
80 | * handy uart register accessor | ||
81 | */ | ||
82 | static inline unsigned int bcm_uart_readl(struct uart_port *port, | ||
83 | unsigned int offset) | ||
84 | { | ||
85 | return bcm_readl(port->membase + offset); | ||
86 | } | ||
87 | |||
88 | static inline void bcm_uart_writel(struct uart_port *port, | ||
89 | unsigned int value, unsigned int offset) | ||
90 | { | ||
91 | bcm_writel(value, port->membase + offset); | ||
92 | } | ||
93 | |||
94 | /* | ||
95 | * serial core request to check if uart tx fifo is empty | ||
96 | */ | ||
97 | static unsigned int bcm_uart_tx_empty(struct uart_port *port) | ||
98 | { | ||
99 | unsigned int val; | ||
100 | |||
101 | val = bcm_uart_readl(port, UART_IR_REG); | ||
102 | return (val & UART_IR_STAT(UART_IR_TXEMPTY)) ? 1 : 0; | ||
103 | } | ||
104 | |||
105 | /* | ||
106 | * serial core request to set RTS and DTR pin state and loopback mode | ||
107 | */ | ||
108 | static void bcm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
109 | { | ||
110 | unsigned int val; | ||
111 | |||
112 | val = bcm_uart_readl(port, UART_MCTL_REG); | ||
113 | val &= ~(UART_MCTL_DTR_MASK | UART_MCTL_RTS_MASK); | ||
114 | /* invert of written value is reflected on the pin */ | ||
115 | if (!(mctrl & TIOCM_DTR)) | ||
116 | val |= UART_MCTL_DTR_MASK; | ||
117 | if (!(mctrl & TIOCM_RTS)) | ||
118 | val |= UART_MCTL_RTS_MASK; | ||
119 | bcm_uart_writel(port, val, UART_MCTL_REG); | ||
120 | |||
121 | val = bcm_uart_readl(port, UART_CTL_REG); | ||
122 | if (mctrl & TIOCM_LOOP) | ||
123 | val |= UART_CTL_LOOPBACK_MASK; | ||
124 | else | ||
125 | val &= ~UART_CTL_LOOPBACK_MASK; | ||
126 | bcm_uart_writel(port, val, UART_CTL_REG); | ||
127 | } | ||
128 | |||
129 | /* | ||
130 | * serial core request to return RI, CTS, DCD and DSR pin state | ||
131 | */ | ||
132 | static unsigned int bcm_uart_get_mctrl(struct uart_port *port) | ||
133 | { | ||
134 | unsigned int val, mctrl; | ||
135 | |||
136 | mctrl = 0; | ||
137 | val = bcm_uart_readl(port, UART_EXTINP_REG); | ||
138 | if (val & UART_EXTINP_RI_MASK) | ||
139 | mctrl |= TIOCM_RI; | ||
140 | if (val & UART_EXTINP_CTS_MASK) | ||
141 | mctrl |= TIOCM_CTS; | ||
142 | if (val & UART_EXTINP_DCD_MASK) | ||
143 | mctrl |= TIOCM_CD; | ||
144 | if (val & UART_EXTINP_DSR_MASK) | ||
145 | mctrl |= TIOCM_DSR; | ||
146 | return mctrl; | ||
147 | } | ||
148 | |||
149 | /* | ||
150 | * serial core request to disable tx ASAP (used for flow control) | ||
151 | */ | ||
152 | static void bcm_uart_stop_tx(struct uart_port *port) | ||
153 | { | ||
154 | unsigned int val; | ||
155 | |||
156 | val = bcm_uart_readl(port, UART_CTL_REG); | ||
157 | val &= ~(UART_CTL_TXEN_MASK); | ||
158 | bcm_uart_writel(port, val, UART_CTL_REG); | ||
159 | |||
160 | val = bcm_uart_readl(port, UART_IR_REG); | ||
161 | val &= ~UART_TX_INT_MASK; | ||
162 | bcm_uart_writel(port, val, UART_IR_REG); | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | * serial core request to (re)enable tx | ||
167 | */ | ||
168 | static void bcm_uart_start_tx(struct uart_port *port) | ||
169 | { | ||
170 | unsigned int val; | ||
171 | |||
172 | val = bcm_uart_readl(port, UART_IR_REG); | ||
173 | val |= UART_TX_INT_MASK; | ||
174 | bcm_uart_writel(port, val, UART_IR_REG); | ||
175 | |||
176 | val = bcm_uart_readl(port, UART_CTL_REG); | ||
177 | val |= UART_CTL_TXEN_MASK; | ||
178 | bcm_uart_writel(port, val, UART_CTL_REG); | ||
179 | } | ||
180 | |||
181 | /* | ||
182 | * serial core request to stop rx, called before port shutdown | ||
183 | */ | ||
184 | static void bcm_uart_stop_rx(struct uart_port *port) | ||
185 | { | ||
186 | unsigned int val; | ||
187 | |||
188 | val = bcm_uart_readl(port, UART_IR_REG); | ||
189 | val &= ~UART_RX_INT_MASK; | ||
190 | bcm_uart_writel(port, val, UART_IR_REG); | ||
191 | } | ||
192 | |||
193 | /* | ||
194 | * serial core request to enable modem status interrupt reporting | ||
195 | */ | ||
196 | static void bcm_uart_enable_ms(struct uart_port *port) | ||
197 | { | ||
198 | unsigned int val; | ||
199 | |||
200 | val = bcm_uart_readl(port, UART_IR_REG); | ||
201 | val |= UART_IR_MASK(UART_IR_EXTIP); | ||
202 | bcm_uart_writel(port, val, UART_IR_REG); | ||
203 | } | ||
204 | |||
205 | /* | ||
206 | * serial core request to start/stop emitting break char | ||
207 | */ | ||
208 | static void bcm_uart_break_ctl(struct uart_port *port, int ctl) | ||
209 | { | ||
210 | unsigned long flags; | ||
211 | unsigned int val; | ||
212 | |||
213 | spin_lock_irqsave(&port->lock, flags); | ||
214 | |||
215 | val = bcm_uart_readl(port, UART_CTL_REG); | ||
216 | if (ctl) | ||
217 | val |= UART_CTL_XMITBRK_MASK; | ||
218 | else | ||
219 | val &= ~UART_CTL_XMITBRK_MASK; | ||
220 | bcm_uart_writel(port, val, UART_CTL_REG); | ||
221 | |||
222 | spin_unlock_irqrestore(&port->lock, flags); | ||
223 | } | ||
224 | |||
225 | /* | ||
226 | * return port type in string format | ||
227 | */ | ||
228 | static const char *bcm_uart_type(struct uart_port *port) | ||
229 | { | ||
230 | return (port->type == PORT_BCM63XX) ? "bcm63xx_uart" : NULL; | ||
231 | } | ||
232 | |||
233 | /* | ||
234 | * read all chars in rx fifo and send them to core | ||
235 | */ | ||
236 | static void bcm_uart_do_rx(struct uart_port *port) | ||
237 | { | ||
238 | struct tty_struct *tty; | ||
239 | unsigned int max_count; | ||
240 | |||
241 | /* limit number of char read in interrupt, should not be | ||
242 | * higher than fifo size anyway since we're much faster than | ||
243 | * serial port */ | ||
244 | max_count = 32; | ||
245 | tty = port->info->port.tty; | ||
246 | do { | ||
247 | unsigned int iestat, c, cstat; | ||
248 | char flag; | ||
249 | |||
250 | /* get overrun/fifo empty information from ier | ||
251 | * register */ | ||
252 | iestat = bcm_uart_readl(port, UART_IR_REG); | ||
253 | if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY))) | ||
254 | break; | ||
255 | |||
256 | cstat = c = bcm_uart_readl(port, UART_FIFO_REG); | ||
257 | port->icount.rx++; | ||
258 | flag = TTY_NORMAL; | ||
259 | c &= 0xff; | ||
260 | |||
261 | if (unlikely((cstat & UART_FIFO_ANYERR_MASK))) { | ||
262 | /* do stats first */ | ||
263 | if (cstat & UART_FIFO_BRKDET_MASK) { | ||
264 | port->icount.brk++; | ||
265 | if (uart_handle_break(port)) | ||
266 | continue; | ||
267 | } | ||
268 | |||
269 | if (cstat & UART_FIFO_PARERR_MASK) | ||
270 | port->icount.parity++; | ||
271 | if (cstat & UART_FIFO_FRAMEERR_MASK) | ||
272 | port->icount.frame++; | ||
273 | |||
274 | /* update flag wrt read_status_mask */ | ||
275 | cstat &= port->read_status_mask; | ||
276 | if (cstat & UART_FIFO_BRKDET_MASK) | ||
277 | flag = TTY_BREAK; | ||
278 | if (cstat & UART_FIFO_FRAMEERR_MASK) | ||
279 | flag = TTY_FRAME; | ||
280 | if (cstat & UART_FIFO_PARERR_MASK) | ||
281 | flag = TTY_PARITY; | ||
282 | } | ||
283 | |||
284 | if (uart_handle_sysrq_char(port, c)) | ||
285 | continue; | ||
286 | |||
287 | if (unlikely(iestat & UART_IR_STAT(UART_IR_RXOVER))) { | ||
288 | port->icount.overrun++; | ||
289 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
290 | } | ||
291 | |||
292 | if ((cstat & port->ignore_status_mask) == 0) | ||
293 | tty_insert_flip_char(tty, c, flag); | ||
294 | |||
295 | } while (--max_count); | ||
296 | |||
297 | tty_flip_buffer_push(tty); | ||
298 | } | ||
299 | |||
300 | /* | ||
301 | * fill tx fifo with chars to send, stop when fifo is about to be full | ||
302 | * or when all chars have been sent. | ||
303 | */ | ||
304 | static void bcm_uart_do_tx(struct uart_port *port) | ||
305 | { | ||
306 | struct circ_buf *xmit; | ||
307 | unsigned int val, max_count; | ||
308 | |||
309 | if (port->x_char) { | ||
310 | bcm_uart_writel(port, port->x_char, UART_FIFO_REG); | ||
311 | port->icount.tx++; | ||
312 | port->x_char = 0; | ||
313 | return; | ||
314 | } | ||
315 | |||
316 | if (uart_tx_stopped(port)) { | ||
317 | bcm_uart_stop_tx(port); | ||
318 | return; | ||
319 | } | ||
320 | |||
321 | xmit = &port->info->xmit; | ||
322 | if (uart_circ_empty(xmit)) | ||
323 | goto txq_empty; | ||
324 | |||
325 | val = bcm_uart_readl(port, UART_MCTL_REG); | ||
326 | val = (val & UART_MCTL_TXFIFOFILL_MASK) >> UART_MCTL_TXFIFOFILL_SHIFT; | ||
327 | max_count = port->fifosize - val; | ||
328 | |||
329 | while (max_count--) { | ||
330 | unsigned int c; | ||
331 | |||
332 | c = xmit->buf[xmit->tail]; | ||
333 | bcm_uart_writel(port, c, UART_FIFO_REG); | ||
334 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
335 | port->icount.tx++; | ||
336 | if (uart_circ_empty(xmit)) | ||
337 | break; | ||
338 | } | ||
339 | |||
340 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
341 | uart_write_wakeup(port); | ||
342 | |||
343 | if (uart_circ_empty(xmit)) | ||
344 | goto txq_empty; | ||
345 | return; | ||
346 | |||
347 | txq_empty: | ||
348 | /* nothing to send, disable transmit interrupt */ | ||
349 | val = bcm_uart_readl(port, UART_IR_REG); | ||
350 | val &= ~UART_TX_INT_MASK; | ||
351 | bcm_uart_writel(port, val, UART_IR_REG); | ||
352 | return; | ||
353 | } | ||
354 | |||
355 | /* | ||
356 | * process uart interrupt | ||
357 | */ | ||
358 | static irqreturn_t bcm_uart_interrupt(int irq, void *dev_id) | ||
359 | { | ||
360 | struct uart_port *port; | ||
361 | unsigned int irqstat; | ||
362 | |||
363 | port = dev_id; | ||
364 | spin_lock(&port->lock); | ||
365 | |||
366 | irqstat = bcm_uart_readl(port, UART_IR_REG); | ||
367 | if (irqstat & UART_RX_INT_STAT) | ||
368 | bcm_uart_do_rx(port); | ||
369 | |||
370 | if (irqstat & UART_TX_INT_STAT) | ||
371 | bcm_uart_do_tx(port); | ||
372 | |||
373 | if (irqstat & UART_IR_MASK(UART_IR_EXTIP)) { | ||
374 | unsigned int estat; | ||
375 | |||
376 | estat = bcm_uart_readl(port, UART_EXTINP_REG); | ||
377 | if (estat & UART_EXTINP_IRSTAT(UART_EXTINP_IR_CTS)) | ||
378 | uart_handle_cts_change(port, | ||
379 | estat & UART_EXTINP_CTS_MASK); | ||
380 | if (estat & UART_EXTINP_IRSTAT(UART_EXTINP_IR_DCD)) | ||
381 | uart_handle_dcd_change(port, | ||
382 | estat & UART_EXTINP_DCD_MASK); | ||
383 | } | ||
384 | |||
385 | spin_unlock(&port->lock); | ||
386 | return IRQ_HANDLED; | ||
387 | } | ||
388 | |||
389 | /* | ||
390 | * enable rx & tx operation on uart | ||
391 | */ | ||
392 | static void bcm_uart_enable(struct uart_port *port) | ||
393 | { | ||
394 | unsigned int val; | ||
395 | |||
396 | val = bcm_uart_readl(port, UART_CTL_REG); | ||
397 | val |= (UART_CTL_BRGEN_MASK | UART_CTL_TXEN_MASK | UART_CTL_RXEN_MASK); | ||
398 | bcm_uart_writel(port, val, UART_CTL_REG); | ||
399 | } | ||
400 | |||
401 | /* | ||
402 | * disable rx & tx operation on uart | ||
403 | */ | ||
404 | static void bcm_uart_disable(struct uart_port *port) | ||
405 | { | ||
406 | unsigned int val; | ||
407 | |||
408 | val = bcm_uart_readl(port, UART_CTL_REG); | ||
409 | val &= ~(UART_CTL_BRGEN_MASK | UART_CTL_TXEN_MASK | | ||
410 | UART_CTL_RXEN_MASK); | ||
411 | bcm_uart_writel(port, val, UART_CTL_REG); | ||
412 | } | ||
413 | |||
414 | /* | ||
415 | * clear all unread data in rx fifo and unsent data in tx fifo | ||
416 | */ | ||
417 | static void bcm_uart_flush(struct uart_port *port) | ||
418 | { | ||
419 | unsigned int val; | ||
420 | |||
421 | /* empty rx and tx fifo */ | ||
422 | val = bcm_uart_readl(port, UART_CTL_REG); | ||
423 | val |= UART_CTL_RSTRXFIFO_MASK | UART_CTL_RSTTXFIFO_MASK; | ||
424 | bcm_uart_writel(port, val, UART_CTL_REG); | ||
425 | |||
426 | /* read any pending char to make sure all irq status are | ||
427 | * cleared */ | ||
428 | (void)bcm_uart_readl(port, UART_FIFO_REG); | ||
429 | } | ||
430 | |||
431 | /* | ||
432 | * serial core request to initialize uart and start rx operation | ||
433 | */ | ||
434 | static int bcm_uart_startup(struct uart_port *port) | ||
435 | { | ||
436 | unsigned int val; | ||
437 | int ret; | ||
438 | |||
439 | /* mask all irq and flush port */ | ||
440 | bcm_uart_disable(port); | ||
441 | bcm_uart_writel(port, 0, UART_IR_REG); | ||
442 | bcm_uart_flush(port); | ||
443 | |||
444 | /* clear any pending external input interrupt */ | ||
445 | (void)bcm_uart_readl(port, UART_EXTINP_REG); | ||
446 | |||
447 | /* set rx/tx fifo thresh to fifo half size */ | ||
448 | val = bcm_uart_readl(port, UART_MCTL_REG); | ||
449 | val &= ~(UART_MCTL_RXFIFOTHRESH_MASK | UART_MCTL_TXFIFOTHRESH_MASK); | ||
450 | val |= (port->fifosize / 2) << UART_MCTL_RXFIFOTHRESH_SHIFT; | ||
451 | val |= (port->fifosize / 2) << UART_MCTL_TXFIFOTHRESH_SHIFT; | ||
452 | bcm_uart_writel(port, val, UART_MCTL_REG); | ||
453 | |||
454 | /* set rx fifo timeout to 1 char time */ | ||
455 | val = bcm_uart_readl(port, UART_CTL_REG); | ||
456 | val &= ~UART_CTL_RXTMOUTCNT_MASK; | ||
457 | val |= 1 << UART_CTL_RXTMOUTCNT_SHIFT; | ||
458 | bcm_uart_writel(port, val, UART_CTL_REG); | ||
459 | |||
460 | /* report any edge on dcd and cts */ | ||
461 | val = UART_EXTINP_INT_MASK; | ||
462 | val |= UART_EXTINP_DCD_NOSENSE_MASK; | ||
463 | val |= UART_EXTINP_CTS_NOSENSE_MASK; | ||
464 | bcm_uart_writel(port, val, UART_EXTINP_REG); | ||
465 | |||
466 | /* register irq and enable rx interrupts */ | ||
467 | ret = request_irq(port->irq, bcm_uart_interrupt, 0, | ||
468 | bcm_uart_type(port), port); | ||
469 | if (ret) | ||
470 | return ret; | ||
471 | bcm_uart_writel(port, UART_RX_INT_MASK, UART_IR_REG); | ||
472 | bcm_uart_enable(port); | ||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | /* | ||
477 | * serial core request to flush & disable uart | ||
478 | */ | ||
479 | static void bcm_uart_shutdown(struct uart_port *port) | ||
480 | { | ||
481 | unsigned long flags; | ||
482 | |||
483 | spin_lock_irqsave(&port->lock, flags); | ||
484 | bcm_uart_writel(port, 0, UART_IR_REG); | ||
485 | spin_unlock_irqrestore(&port->lock, flags); | ||
486 | |||
487 | bcm_uart_disable(port); | ||
488 | bcm_uart_flush(port); | ||
489 | free_irq(port->irq, port); | ||
490 | } | ||
491 | |||
492 | /* | ||
493 | * serial core request to change current uart setting | ||
494 | */ | ||
495 | static void bcm_uart_set_termios(struct uart_port *port, | ||
496 | struct ktermios *new, | ||
497 | struct ktermios *old) | ||
498 | { | ||
499 | unsigned int ctl, baud, quot, ier; | ||
500 | unsigned long flags; | ||
501 | |||
502 | spin_lock_irqsave(&port->lock, flags); | ||
503 | |||
504 | /* disable uart while changing speed */ | ||
505 | bcm_uart_disable(port); | ||
506 | bcm_uart_flush(port); | ||
507 | |||
508 | /* update Control register */ | ||
509 | ctl = bcm_uart_readl(port, UART_CTL_REG); | ||
510 | ctl &= ~UART_CTL_BITSPERSYM_MASK; | ||
511 | |||
512 | switch (new->c_cflag & CSIZE) { | ||
513 | case CS5: | ||
514 | ctl |= (0 << UART_CTL_BITSPERSYM_SHIFT); | ||
515 | break; | ||
516 | case CS6: | ||
517 | ctl |= (1 << UART_CTL_BITSPERSYM_SHIFT); | ||
518 | break; | ||
519 | case CS7: | ||
520 | ctl |= (2 << UART_CTL_BITSPERSYM_SHIFT); | ||
521 | break; | ||
522 | default: | ||
523 | ctl |= (3 << UART_CTL_BITSPERSYM_SHIFT); | ||
524 | break; | ||
525 | } | ||
526 | |||
527 | ctl &= ~UART_CTL_STOPBITS_MASK; | ||
528 | if (new->c_cflag & CSTOPB) | ||
529 | ctl |= UART_CTL_STOPBITS_2; | ||
530 | else | ||
531 | ctl |= UART_CTL_STOPBITS_1; | ||
532 | |||
533 | ctl &= ~(UART_CTL_RXPAREN_MASK | UART_CTL_TXPAREN_MASK); | ||
534 | if (new->c_cflag & PARENB) | ||
535 | ctl |= (UART_CTL_RXPAREN_MASK | UART_CTL_TXPAREN_MASK); | ||
536 | ctl &= ~(UART_CTL_RXPAREVEN_MASK | UART_CTL_TXPAREVEN_MASK); | ||
537 | if (new->c_cflag & PARODD) | ||
538 | ctl |= (UART_CTL_RXPAREVEN_MASK | UART_CTL_TXPAREVEN_MASK); | ||
539 | bcm_uart_writel(port, ctl, UART_CTL_REG); | ||
540 | |||
541 | /* update Baudword register */ | ||
542 | baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16); | ||
543 | quot = uart_get_divisor(port, baud) - 1; | ||
544 | bcm_uart_writel(port, quot, UART_BAUD_REG); | ||
545 | |||
546 | /* update Interrupt register */ | ||
547 | ier = bcm_uart_readl(port, UART_IR_REG); | ||
548 | |||
549 | ier &= ~UART_IR_MASK(UART_IR_EXTIP); | ||
550 | if (UART_ENABLE_MS(port, new->c_cflag)) | ||
551 | ier |= UART_IR_MASK(UART_IR_EXTIP); | ||
552 | |||
553 | bcm_uart_writel(port, ier, UART_IR_REG); | ||
554 | |||
555 | /* update read/ignore mask */ | ||
556 | port->read_status_mask = UART_FIFO_VALID_MASK; | ||
557 | if (new->c_iflag & INPCK) { | ||
558 | port->read_status_mask |= UART_FIFO_FRAMEERR_MASK; | ||
559 | port->read_status_mask |= UART_FIFO_PARERR_MASK; | ||
560 | } | ||
561 | if (new->c_iflag & (BRKINT)) | ||
562 | port->read_status_mask |= UART_FIFO_BRKDET_MASK; | ||
563 | |||
564 | port->ignore_status_mask = 0; | ||
565 | if (new->c_iflag & IGNPAR) | ||
566 | port->ignore_status_mask |= UART_FIFO_PARERR_MASK; | ||
567 | if (new->c_iflag & IGNBRK) | ||
568 | port->ignore_status_mask |= UART_FIFO_BRKDET_MASK; | ||
569 | if (!(new->c_cflag & CREAD)) | ||
570 | port->ignore_status_mask |= UART_FIFO_VALID_MASK; | ||
571 | |||
572 | uart_update_timeout(port, new->c_cflag, baud); | ||
573 | bcm_uart_enable(port); | ||
574 | spin_unlock_irqrestore(&port->lock, flags); | ||
575 | } | ||
576 | |||
577 | /* | ||
578 | * serial core request to claim uart iomem | ||
579 | */ | ||
580 | static int bcm_uart_request_port(struct uart_port *port) | ||
581 | { | ||
582 | unsigned int size; | ||
583 | |||
584 | size = RSET_UART_SIZE; | ||
585 | if (!request_mem_region(port->mapbase, size, "bcm63xx")) { | ||
586 | dev_err(port->dev, "Memory region busy\n"); | ||
587 | return -EBUSY; | ||
588 | } | ||
589 | |||
590 | port->membase = ioremap(port->mapbase, size); | ||
591 | if (!port->membase) { | ||
592 | dev_err(port->dev, "Unable to map registers\n"); | ||
593 | release_mem_region(port->mapbase, size); | ||
594 | return -EBUSY; | ||
595 | } | ||
596 | return 0; | ||
597 | } | ||
598 | |||
599 | /* | ||
600 | * serial core request to release uart iomem | ||
601 | */ | ||
602 | static void bcm_uart_release_port(struct uart_port *port) | ||
603 | { | ||
604 | release_mem_region(port->mapbase, RSET_UART_SIZE); | ||
605 | iounmap(port->membase); | ||
606 | } | ||
607 | |||
608 | /* | ||
609 | * serial core request to do any port required autoconfiguration | ||
610 | */ | ||
611 | static void bcm_uart_config_port(struct uart_port *port, int flags) | ||
612 | { | ||
613 | if (flags & UART_CONFIG_TYPE) { | ||
614 | if (bcm_uart_request_port(port)) | ||
615 | return; | ||
616 | port->type = PORT_BCM63XX; | ||
617 | } | ||
618 | } | ||
619 | |||
620 | /* | ||
621 | * serial core request to check that port information in serinfo are | ||
622 | * suitable | ||
623 | */ | ||
624 | static int bcm_uart_verify_port(struct uart_port *port, | ||
625 | struct serial_struct *serinfo) | ||
626 | { | ||
627 | if (port->type != PORT_BCM63XX) | ||
628 | return -EINVAL; | ||
629 | if (port->irq != serinfo->irq) | ||
630 | return -EINVAL; | ||
631 | if (port->iotype != serinfo->io_type) | ||
632 | return -EINVAL; | ||
633 | if (port->mapbase != (unsigned long)serinfo->iomem_base) | ||
634 | return -EINVAL; | ||
635 | return 0; | ||
636 | } | ||
637 | |||
638 | /* serial core callbacks */ | ||
639 | static struct uart_ops bcm_uart_ops = { | ||
640 | .tx_empty = bcm_uart_tx_empty, | ||
641 | .get_mctrl = bcm_uart_get_mctrl, | ||
642 | .set_mctrl = bcm_uart_set_mctrl, | ||
643 | .start_tx = bcm_uart_start_tx, | ||
644 | .stop_tx = bcm_uart_stop_tx, | ||
645 | .stop_rx = bcm_uart_stop_rx, | ||
646 | .enable_ms = bcm_uart_enable_ms, | ||
647 | .break_ctl = bcm_uart_break_ctl, | ||
648 | .startup = bcm_uart_startup, | ||
649 | .shutdown = bcm_uart_shutdown, | ||
650 | .set_termios = bcm_uart_set_termios, | ||
651 | .type = bcm_uart_type, | ||
652 | .release_port = bcm_uart_release_port, | ||
653 | .request_port = bcm_uart_request_port, | ||
654 | .config_port = bcm_uart_config_port, | ||
655 | .verify_port = bcm_uart_verify_port, | ||
656 | }; | ||
657 | |||
658 | |||
659 | |||
660 | #ifdef CONFIG_SERIAL_BCM63XX_CONSOLE | ||
661 | static inline void wait_for_xmitr(struct uart_port *port) | ||
662 | { | ||
663 | unsigned int tmout; | ||
664 | |||
665 | /* Wait up to 10ms for the character(s) to be sent. */ | ||
666 | tmout = 10000; | ||
667 | while (--tmout) { | ||
668 | unsigned int val; | ||
669 | |||
670 | val = bcm_uart_readl(port, UART_IR_REG); | ||
671 | if (val & UART_IR_STAT(UART_IR_TXEMPTY)) | ||
672 | break; | ||
673 | udelay(1); | ||
674 | } | ||
675 | |||
676 | /* Wait up to 1s for flow control if necessary */ | ||
677 | if (port->flags & UPF_CONS_FLOW) { | ||
678 | tmout = 1000000; | ||
679 | while (--tmout) { | ||
680 | unsigned int val; | ||
681 | |||
682 | val = bcm_uart_readl(port, UART_EXTINP_REG); | ||
683 | if (val & UART_EXTINP_CTS_MASK) | ||
684 | break; | ||
685 | udelay(1); | ||
686 | } | ||
687 | } | ||
688 | } | ||
689 | |||
690 | /* | ||
691 | * output given char | ||
692 | */ | ||
693 | static void bcm_console_putchar(struct uart_port *port, int ch) | ||
694 | { | ||
695 | wait_for_xmitr(port); | ||
696 | bcm_uart_writel(port, ch, UART_FIFO_REG); | ||
697 | } | ||
698 | |||
699 | /* | ||
700 | * console core request to output given string | ||
701 | */ | ||
702 | static void bcm_console_write(struct console *co, const char *s, | ||
703 | unsigned int count) | ||
704 | { | ||
705 | struct uart_port *port; | ||
706 | unsigned long flags; | ||
707 | int locked; | ||
708 | |||
709 | port = &ports[co->index]; | ||
710 | |||
711 | local_irq_save(flags); | ||
712 | if (port->sysrq) { | ||
713 | /* bcm_uart_interrupt() already took the lock */ | ||
714 | locked = 0; | ||
715 | } else if (oops_in_progress) { | ||
716 | locked = spin_trylock(&port->lock); | ||
717 | } else { | ||
718 | spin_lock(&port->lock); | ||
719 | locked = 1; | ||
720 | } | ||
721 | |||
722 | /* call helper to deal with \r\n */ | ||
723 | uart_console_write(port, s, count, bcm_console_putchar); | ||
724 | |||
725 | /* and wait for char to be transmitted */ | ||
726 | wait_for_xmitr(port); | ||
727 | |||
728 | if (locked) | ||
729 | spin_unlock(&port->lock); | ||
730 | local_irq_restore(flags); | ||
731 | } | ||
732 | |||
733 | /* | ||
734 | * console core request to setup given console, find matching uart | ||
735 | * port and setup it. | ||
736 | */ | ||
737 | static int bcm_console_setup(struct console *co, char *options) | ||
738 | { | ||
739 | struct uart_port *port; | ||
740 | int baud = 9600; | ||
741 | int bits = 8; | ||
742 | int parity = 'n'; | ||
743 | int flow = 'n'; | ||
744 | |||
745 | if (co->index < 0 || co->index >= BCM63XX_NR_UARTS) | ||
746 | return -EINVAL; | ||
747 | port = &ports[co->index]; | ||
748 | if (!port->membase) | ||
749 | return -ENODEV; | ||
750 | if (options) | ||
751 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
752 | |||
753 | return uart_set_options(port, co, baud, parity, bits, flow); | ||
754 | } | ||
755 | |||
756 | static struct uart_driver bcm_uart_driver; | ||
757 | |||
758 | static struct console bcm63xx_console = { | ||
759 | .name = "ttyS", | ||
760 | .write = bcm_console_write, | ||
761 | .device = uart_console_device, | ||
762 | .setup = bcm_console_setup, | ||
763 | .flags = CON_PRINTBUFFER, | ||
764 | .index = -1, | ||
765 | .data = &bcm_uart_driver, | ||
766 | }; | ||
767 | |||
768 | static int __init bcm63xx_console_init(void) | ||
769 | { | ||
770 | register_console(&bcm63xx_console); | ||
771 | return 0; | ||
772 | } | ||
773 | |||
774 | console_initcall(bcm63xx_console_init); | ||
775 | |||
776 | #define BCM63XX_CONSOLE (&bcm63xx_console) | ||
777 | #else | ||
778 | #define BCM63XX_CONSOLE NULL | ||
779 | #endif /* CONFIG_SERIAL_BCM63XX_CONSOLE */ | ||
780 | |||
781 | static struct uart_driver bcm_uart_driver = { | ||
782 | .owner = THIS_MODULE, | ||
783 | .driver_name = "bcm63xx_uart", | ||
784 | .dev_name = "ttyS", | ||
785 | .major = TTY_MAJOR, | ||
786 | .minor = 64, | ||
787 | .nr = 1, | ||
788 | .cons = BCM63XX_CONSOLE, | ||
789 | }; | ||
790 | |||
791 | /* | ||
792 | * platform driver probe/remove callback | ||
793 | */ | ||
794 | static int __devinit bcm_uart_probe(struct platform_device *pdev) | ||
795 | { | ||
796 | struct resource *res_mem, *res_irq; | ||
797 | struct uart_port *port; | ||
798 | struct clk *clk; | ||
799 | int ret; | ||
800 | |||
801 | if (pdev->id < 0 || pdev->id >= BCM63XX_NR_UARTS) | ||
802 | return -EINVAL; | ||
803 | |||
804 | if (ports[pdev->id].membase) | ||
805 | return -EBUSY; | ||
806 | |||
807 | res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
808 | if (!res_mem) | ||
809 | return -ENODEV; | ||
810 | |||
811 | res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
812 | if (!res_irq) | ||
813 | return -ENODEV; | ||
814 | |||
815 | clk = clk_get(&pdev->dev, "periph"); | ||
816 | if (IS_ERR(clk)) | ||
817 | return -ENODEV; | ||
818 | |||
819 | port = &ports[pdev->id]; | ||
820 | memset(port, 0, sizeof(*port)); | ||
821 | port->iotype = UPIO_MEM; | ||
822 | port->mapbase = res_mem->start; | ||
823 | port->irq = res_irq->start; | ||
824 | port->ops = &bcm_uart_ops; | ||
825 | port->flags = UPF_BOOT_AUTOCONF; | ||
826 | port->dev = &pdev->dev; | ||
827 | port->fifosize = 16; | ||
828 | port->uartclk = clk_get_rate(clk) / 2; | ||
829 | clk_put(clk); | ||
830 | |||
831 | ret = uart_add_one_port(&bcm_uart_driver, port); | ||
832 | if (ret) { | ||
833 | kfree(port); | ||
834 | return ret; | ||
835 | } | ||
836 | platform_set_drvdata(pdev, port); | ||
837 | return 0; | ||
838 | } | ||
839 | |||
840 | static int __devexit bcm_uart_remove(struct platform_device *pdev) | ||
841 | { | ||
842 | struct uart_port *port; | ||
843 | |||
844 | port = platform_get_drvdata(pdev); | ||
845 | uart_remove_one_port(&bcm_uart_driver, port); | ||
846 | platform_set_drvdata(pdev, NULL); | ||
847 | /* mark port as free */ | ||
848 | ports[pdev->id].membase = 0; | ||
849 | return 0; | ||
850 | } | ||
851 | |||
852 | /* | ||
853 | * platform driver stuff | ||
854 | */ | ||
855 | static struct platform_driver bcm_uart_platform_driver = { | ||
856 | .probe = bcm_uart_probe, | ||
857 | .remove = __devexit_p(bcm_uart_remove), | ||
858 | .driver = { | ||
859 | .owner = THIS_MODULE, | ||
860 | .name = "bcm63xx_uart", | ||
861 | }, | ||
862 | }; | ||
863 | |||
864 | static int __init bcm_uart_init(void) | ||
865 | { | ||
866 | int ret; | ||
867 | |||
868 | ret = uart_register_driver(&bcm_uart_driver); | ||
869 | if (ret) | ||
870 | return ret; | ||
871 | |||
872 | ret = platform_driver_register(&bcm_uart_platform_driver); | ||
873 | if (ret) | ||
874 | uart_unregister_driver(&bcm_uart_driver); | ||
875 | |||
876 | return ret; | ||
877 | } | ||
878 | |||
879 | static void __exit bcm_uart_exit(void) | ||
880 | { | ||
881 | platform_driver_unregister(&bcm_uart_platform_driver); | ||
882 | uart_unregister_driver(&bcm_uart_driver); | ||
883 | } | ||
884 | |||
885 | module_init(bcm_uart_init); | ||
886 | module_exit(bcm_uart_exit); | ||
887 | |||
888 | MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>"); | ||
889 | MODULE_DESCRIPTION("Broadcom 63<xx integrated uart driver"); | ||
890 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 8d349b23249a..300cea768d74 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c | |||
@@ -649,7 +649,7 @@ static int cpm_uart_tx_pump(struct uart_port *port) | |||
649 | u8 *p; | 649 | u8 *p; |
650 | int count; | 650 | int count; |
651 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | 651 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; |
652 | struct circ_buf *xmit = &port->info->xmit; | 652 | struct circ_buf *xmit = &port->state->xmit; |
653 | 653 | ||
654 | /* Handle xon/xoff */ | 654 | /* Handle xon/xoff */ |
655 | if (port->x_char) { | 655 | if (port->x_char) { |
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c index 7be52fe288eb..31f172397af3 100644 --- a/drivers/serial/crisv10.c +++ b/drivers/serial/crisv10.c | |||
@@ -18,6 +18,7 @@ static char *serial_version = "$Revision: 1.25 $"; | |||
18 | #include <linux/tty.h> | 18 | #include <linux/tty.h> |
19 | #include <linux/tty_flip.h> | 19 | #include <linux/tty_flip.h> |
20 | #include <linux/major.h> | 20 | #include <linux/major.h> |
21 | #include <linux/smp_lock.h> | ||
21 | #include <linux/string.h> | 22 | #include <linux/string.h> |
22 | #include <linux/fcntl.h> | 23 | #include <linux/fcntl.h> |
23 | #include <linux/mm.h> | 24 | #include <linux/mm.h> |
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c index 2d7feecaf492..0028b6f89ce6 100644 --- a/drivers/serial/icom.c +++ b/drivers/serial/icom.c | |||
@@ -307,7 +307,7 @@ static void stop_processor(struct icom_port *icom_port) | |||
307 | if (port < 4) { | 307 | if (port < 4) { |
308 | temp = readl(stop_proc[port].global_control_reg); | 308 | temp = readl(stop_proc[port].global_control_reg); |
309 | temp = | 309 | temp = |
310 | (temp & ~start_proc[port].processor_id) | stop_proc[port].processor_id; | 310 | (temp & ~start_proc[port].processor_id) | stop_proc[port].processor_id; |
311 | writel(temp, stop_proc[port].global_control_reg); | 311 | writel(temp, stop_proc[port].global_control_reg); |
312 | 312 | ||
313 | /* write flush */ | 313 | /* write flush */ |
@@ -336,7 +336,7 @@ static void start_processor(struct icom_port *icom_port) | |||
336 | if (port < 4) { | 336 | if (port < 4) { |
337 | temp = readl(start_proc[port].global_control_reg); | 337 | temp = readl(start_proc[port].global_control_reg); |
338 | temp = | 338 | temp = |
339 | (temp & ~stop_proc[port].processor_id) | start_proc[port].processor_id; | 339 | (temp & ~stop_proc[port].processor_id) | start_proc[port].processor_id; |
340 | writel(temp, start_proc[port].global_control_reg); | 340 | writel(temp, start_proc[port].global_control_reg); |
341 | 341 | ||
342 | /* write flush */ | 342 | /* write flush */ |
@@ -509,8 +509,8 @@ static void load_code(struct icom_port *icom_port) | |||
509 | dev_err(&icom_port->adapter->pci_dev->dev,"Port not opertional\n"); | 509 | dev_err(&icom_port->adapter->pci_dev->dev,"Port not opertional\n"); |
510 | } | 510 | } |
511 | 511 | ||
512 | if (new_page != NULL) | 512 | if (new_page != NULL) |
513 | pci_free_consistent(dev, 4096, new_page, temp_pci); | 513 | pci_free_consistent(dev, 4096, new_page, temp_pci); |
514 | } | 514 | } |
515 | 515 | ||
516 | static int startup(struct icom_port *icom_port) | 516 | static int startup(struct icom_port *icom_port) |
@@ -1493,15 +1493,15 @@ static int __devinit icom_probe(struct pci_dev *dev, | |||
1493 | const struct pci_device_id *ent) | 1493 | const struct pci_device_id *ent) |
1494 | { | 1494 | { |
1495 | int index; | 1495 | int index; |
1496 | unsigned int command_reg; | 1496 | unsigned int command_reg; |
1497 | int retval; | 1497 | int retval; |
1498 | struct icom_adapter *icom_adapter; | 1498 | struct icom_adapter *icom_adapter; |
1499 | struct icom_port *icom_port; | 1499 | struct icom_port *icom_port; |
1500 | 1500 | ||
1501 | retval = pci_enable_device(dev); | 1501 | retval = pci_enable_device(dev); |
1502 | if (retval) { | 1502 | if (retval) { |
1503 | dev_err(&dev->dev, "Device enable FAILED\n"); | 1503 | dev_err(&dev->dev, "Device enable FAILED\n"); |
1504 | return retval; | 1504 | return retval; |
1505 | } | 1505 | } |
1506 | 1506 | ||
1507 | if ( (retval = pci_request_regions(dev, "icom"))) { | 1507 | if ( (retval = pci_request_regions(dev, "icom"))) { |
@@ -1510,23 +1510,23 @@ static int __devinit icom_probe(struct pci_dev *dev, | |||
1510 | return retval; | 1510 | return retval; |
1511 | } | 1511 | } |
1512 | 1512 | ||
1513 | pci_set_master(dev); | 1513 | pci_set_master(dev); |
1514 | 1514 | ||
1515 | if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) { | 1515 | if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) { |
1516 | dev_err(&dev->dev, "PCI Config read FAILED\n"); | 1516 | dev_err(&dev->dev, "PCI Config read FAILED\n"); |
1517 | return retval; | 1517 | return retval; |
1518 | } | 1518 | } |
1519 | 1519 | ||
1520 | pci_write_config_dword(dev, PCI_COMMAND, | 1520 | pci_write_config_dword(dev, PCI_COMMAND, |
1521 | command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | 1521 | command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
1522 | | PCI_COMMAND_PARITY | PCI_COMMAND_SERR); | 1522 | | PCI_COMMAND_PARITY | PCI_COMMAND_SERR); |
1523 | 1523 | ||
1524 | if (ent->driver_data == ADAPTER_V1) { | 1524 | if (ent->driver_data == ADAPTER_V1) { |
1525 | pci_write_config_dword(dev, 0x44, 0x8300830A); | 1525 | pci_write_config_dword(dev, 0x44, 0x8300830A); |
1526 | } else { | 1526 | } else { |
1527 | pci_write_config_dword(dev, 0x44, 0x42004200); | 1527 | pci_write_config_dword(dev, 0x44, 0x42004200); |
1528 | pci_write_config_dword(dev, 0x48, 0x42004200); | 1528 | pci_write_config_dword(dev, 0x48, 0x42004200); |
1529 | } | 1529 | } |
1530 | 1530 | ||
1531 | 1531 | ||
1532 | retval = icom_alloc_adapter(&icom_adapter); | 1532 | retval = icom_alloc_adapter(&icom_adapter); |
@@ -1536,10 +1536,10 @@ static int __devinit icom_probe(struct pci_dev *dev, | |||
1536 | goto probe_exit0; | 1536 | goto probe_exit0; |
1537 | } | 1537 | } |
1538 | 1538 | ||
1539 | icom_adapter->base_addr_pci = pci_resource_start(dev, 0); | 1539 | icom_adapter->base_addr_pci = pci_resource_start(dev, 0); |
1540 | icom_adapter->pci_dev = dev; | 1540 | icom_adapter->pci_dev = dev; |
1541 | icom_adapter->version = ent->driver_data; | 1541 | icom_adapter->version = ent->driver_data; |
1542 | icom_adapter->subsystem_id = ent->subdevice; | 1542 | icom_adapter->subsystem_id = ent->subdevice; |
1543 | 1543 | ||
1544 | 1544 | ||
1545 | retval = icom_init_ports(icom_adapter); | 1545 | retval = icom_init_ports(icom_adapter); |
@@ -1548,7 +1548,7 @@ static int __devinit icom_probe(struct pci_dev *dev, | |||
1548 | goto probe_exit1; | 1548 | goto probe_exit1; |
1549 | } | 1549 | } |
1550 | 1550 | ||
1551 | icom_adapter->base_addr = pci_ioremap_bar(dev, 0); | 1551 | icom_adapter->base_addr = pci_ioremap_bar(dev, 0); |
1552 | 1552 | ||
1553 | if (!icom_adapter->base_addr) | 1553 | if (!icom_adapter->base_addr) |
1554 | goto probe_exit1; | 1554 | goto probe_exit1; |
@@ -1562,7 +1562,7 @@ static int __devinit icom_probe(struct pci_dev *dev, | |||
1562 | 1562 | ||
1563 | retval = icom_load_ports(icom_adapter); | 1563 | retval = icom_load_ports(icom_adapter); |
1564 | 1564 | ||
1565 | for (index = 0; index < icom_adapter->numb_ports; index++) { | 1565 | for (index = 0; index < icom_adapter->numb_ports; index++) { |
1566 | icom_port = &icom_adapter->port_info[index]; | 1566 | icom_port = &icom_adapter->port_info[index]; |
1567 | 1567 | ||
1568 | if (icom_port->status == ICOM_PORT_ACTIVE) { | 1568 | if (icom_port->status == ICOM_PORT_ACTIVE) { |
@@ -1579,7 +1579,7 @@ static int __devinit icom_probe(struct pci_dev *dev, | |||
1579 | icom_port->status = ICOM_PORT_OFF; | 1579 | icom_port->status = ICOM_PORT_OFF; |
1580 | dev_err(&dev->dev, "Device add failed\n"); | 1580 | dev_err(&dev->dev, "Device add failed\n"); |
1581 | } else | 1581 | } else |
1582 | dev_info(&dev->dev, "Device added\n"); | 1582 | dev_info(&dev->dev, "Device added\n"); |
1583 | } | 1583 | } |
1584 | } | 1584 | } |
1585 | 1585 | ||
@@ -1595,9 +1595,7 @@ probe_exit0: | |||
1595 | pci_release_regions(dev); | 1595 | pci_release_regions(dev); |
1596 | pci_disable_device(dev); | 1596 | pci_disable_device(dev); |
1597 | 1597 | ||
1598 | return retval; | 1598 | return retval; |
1599 | |||
1600 | |||
1601 | } | 1599 | } |
1602 | 1600 | ||
1603 | static void __devexit icom_remove(struct pci_dev *dev) | 1601 | static void __devexit icom_remove(struct pci_dev *dev) |
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index d7bcd074d383..7ce9e9f567a3 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c | |||
@@ -705,7 +705,7 @@ mpc52xx_uart_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
705 | return -EINVAL; | 705 | return -EINVAL; |
706 | 706 | ||
707 | if ((ser->irq != port->irq) || | 707 | if ((ser->irq != port->irq) || |
708 | (ser->io_type != SERIAL_IO_MEM) || | 708 | (ser->io_type != UPIO_MEM) || |
709 | (ser->baud_base != port->uartclk) || | 709 | (ser->baud_base != port->uartclk) || |
710 | (ser->iomem_base != (void *)port->mapbase) || | 710 | (ser->iomem_base != (void *)port->mapbase) || |
711 | (ser->hub6 != 0)) | 711 | (ser->hub6 != 0)) |
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index 6443b7ff274a..b8629d74f6a2 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c | |||
@@ -726,9 +726,10 @@ static struct uart_driver serial_pxa_reg = { | |||
726 | .cons = PXA_CONSOLE, | 726 | .cons = PXA_CONSOLE, |
727 | }; | 727 | }; |
728 | 728 | ||
729 | static int serial_pxa_suspend(struct platform_device *dev, pm_message_t state) | 729 | #ifdef CONFIG_PM |
730 | static int serial_pxa_suspend(struct device *dev) | ||
730 | { | 731 | { |
731 | struct uart_pxa_port *sport = platform_get_drvdata(dev); | 732 | struct uart_pxa_port *sport = dev_get_drvdata(dev); |
732 | 733 | ||
733 | if (sport) | 734 | if (sport) |
734 | uart_suspend_port(&serial_pxa_reg, &sport->port); | 735 | uart_suspend_port(&serial_pxa_reg, &sport->port); |
@@ -736,9 +737,9 @@ static int serial_pxa_suspend(struct platform_device *dev, pm_message_t state) | |||
736 | return 0; | 737 | return 0; |
737 | } | 738 | } |
738 | 739 | ||
739 | static int serial_pxa_resume(struct platform_device *dev) | 740 | static int serial_pxa_resume(struct device *dev) |
740 | { | 741 | { |
741 | struct uart_pxa_port *sport = platform_get_drvdata(dev); | 742 | struct uart_pxa_port *sport = dev_get_drvdata(dev); |
742 | 743 | ||
743 | if (sport) | 744 | if (sport) |
744 | uart_resume_port(&serial_pxa_reg, &sport->port); | 745 | uart_resume_port(&serial_pxa_reg, &sport->port); |
@@ -746,6 +747,12 @@ static int serial_pxa_resume(struct platform_device *dev) | |||
746 | return 0; | 747 | return 0; |
747 | } | 748 | } |
748 | 749 | ||
750 | static struct dev_pm_ops serial_pxa_pm_ops = { | ||
751 | .suspend = serial_pxa_suspend, | ||
752 | .resume = serial_pxa_resume, | ||
753 | }; | ||
754 | #endif | ||
755 | |||
749 | static int serial_pxa_probe(struct platform_device *dev) | 756 | static int serial_pxa_probe(struct platform_device *dev) |
750 | { | 757 | { |
751 | struct uart_pxa_port *sport; | 758 | struct uart_pxa_port *sport; |
@@ -825,11 +832,12 @@ static struct platform_driver serial_pxa_driver = { | |||
825 | .probe = serial_pxa_probe, | 832 | .probe = serial_pxa_probe, |
826 | .remove = serial_pxa_remove, | 833 | .remove = serial_pxa_remove, |
827 | 834 | ||
828 | .suspend = serial_pxa_suspend, | ||
829 | .resume = serial_pxa_resume, | ||
830 | .driver = { | 835 | .driver = { |
831 | .name = "pxa2xx-uart", | 836 | .name = "pxa2xx-uart", |
832 | .owner = THIS_MODULE, | 837 | .owner = THIS_MODULE, |
838 | #ifdef CONFIG_PM | ||
839 | .pm = &serial_pxa_pm_ops, | ||
840 | #endif | ||
833 | }, | 841 | }, |
834 | }; | 842 | }; |
835 | 843 | ||
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c index 7f5e26873220..2199d819a987 100644 --- a/drivers/serial/sa1100.c +++ b/drivers/serial/sa1100.c | |||
@@ -638,7 +638,7 @@ static void __init sa1100_init_ports(void) | |||
638 | PPSR |= PPC_TXD1 | PPC_TXD3; | 638 | PPSR |= PPC_TXD1 | PPC_TXD3; |
639 | } | 639 | } |
640 | 640 | ||
641 | void __init sa1100_register_uart_fns(struct sa1100_port_fns *fns) | 641 | void __devinit sa1100_register_uart_fns(struct sa1100_port_fns *fns) |
642 | { | 642 | { |
643 | if (fns->get_mctrl) | 643 | if (fns->get_mctrl) |
644 | sa1100_pops.get_mctrl = fns->get_mctrl; | 644 | sa1100_pops.get_mctrl = fns->get_mctrl; |
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 1689bda1d13b..dcc72444e8e7 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
@@ -1270,6 +1270,9 @@ static void uart_close(struct tty_struct *tty, struct file *filp) | |||
1270 | 1270 | ||
1271 | BUG_ON(!kernel_locked()); | 1271 | BUG_ON(!kernel_locked()); |
1272 | 1272 | ||
1273 | if (!state) | ||
1274 | return; | ||
1275 | |||
1273 | uport = state->uart_port; | 1276 | uport = state->uart_port; |
1274 | port = &state->port; | 1277 | port = &state->port; |
1275 | 1278 | ||
@@ -1316,9 +1319,9 @@ static void uart_close(struct tty_struct *tty, struct file *filp) | |||
1316 | */ | 1319 | */ |
1317 | if (port->flags & ASYNC_INITIALIZED) { | 1320 | if (port->flags & ASYNC_INITIALIZED) { |
1318 | unsigned long flags; | 1321 | unsigned long flags; |
1319 | spin_lock_irqsave(&port->lock, flags); | 1322 | spin_lock_irqsave(&uport->lock, flags); |
1320 | uport->ops->stop_rx(uport); | 1323 | uport->ops->stop_rx(uport); |
1321 | spin_unlock_irqrestore(&port->lock, flags); | 1324 | spin_unlock_irqrestore(&uport->lock, flags); |
1322 | /* | 1325 | /* |
1323 | * Before we drop DTR, make sure the UART transmitter | 1326 | * Before we drop DTR, make sure the UART transmitter |
1324 | * has completely drained; this is especially | 1327 | * has completely drained; this is especially |
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index 0f7cf4c453e6..c50e9fbbf743 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c | |||
@@ -221,21 +221,26 @@ sio_quot_set(struct uart_txx9_port *up, int quot) | |||
221 | sio_out(up, TXX9_SIBGR, 0xff | TXX9_SIBGR_BCLK_T6); | 221 | sio_out(up, TXX9_SIBGR, 0xff | TXX9_SIBGR_BCLK_T6); |
222 | } | 222 | } |
223 | 223 | ||
224 | static struct uart_txx9_port *to_uart_txx9_port(struct uart_port *port) | ||
225 | { | ||
226 | return container_of(port, struct uart_txx9_port, port); | ||
227 | } | ||
228 | |||
224 | static void serial_txx9_stop_tx(struct uart_port *port) | 229 | static void serial_txx9_stop_tx(struct uart_port *port) |
225 | { | 230 | { |
226 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 231 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
227 | sio_mask(up, TXX9_SIDICR, TXX9_SIDICR_TIE); | 232 | sio_mask(up, TXX9_SIDICR, TXX9_SIDICR_TIE); |
228 | } | 233 | } |
229 | 234 | ||
230 | static void serial_txx9_start_tx(struct uart_port *port) | 235 | static void serial_txx9_start_tx(struct uart_port *port) |
231 | { | 236 | { |
232 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 237 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
233 | sio_set(up, TXX9_SIDICR, TXX9_SIDICR_TIE); | 238 | sio_set(up, TXX9_SIDICR, TXX9_SIDICR_TIE); |
234 | } | 239 | } |
235 | 240 | ||
236 | static void serial_txx9_stop_rx(struct uart_port *port) | 241 | static void serial_txx9_stop_rx(struct uart_port *port) |
237 | { | 242 | { |
238 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 243 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
239 | up->port.read_status_mask &= ~TXX9_SIDISR_RDIS; | 244 | up->port.read_status_mask &= ~TXX9_SIDISR_RDIS; |
240 | } | 245 | } |
241 | 246 | ||
@@ -246,7 +251,7 @@ static void serial_txx9_enable_ms(struct uart_port *port) | |||
246 | 251 | ||
247 | static void serial_txx9_initialize(struct uart_port *port) | 252 | static void serial_txx9_initialize(struct uart_port *port) |
248 | { | 253 | { |
249 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 254 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
250 | unsigned int tmout = 10000; | 255 | unsigned int tmout = 10000; |
251 | 256 | ||
252 | sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST); | 257 | sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST); |
@@ -414,7 +419,7 @@ static irqreturn_t serial_txx9_interrupt(int irq, void *dev_id) | |||
414 | 419 | ||
415 | static unsigned int serial_txx9_tx_empty(struct uart_port *port) | 420 | static unsigned int serial_txx9_tx_empty(struct uart_port *port) |
416 | { | 421 | { |
417 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 422 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
418 | unsigned long flags; | 423 | unsigned long flags; |
419 | unsigned int ret; | 424 | unsigned int ret; |
420 | 425 | ||
@@ -427,7 +432,7 @@ static unsigned int serial_txx9_tx_empty(struct uart_port *port) | |||
427 | 432 | ||
428 | static unsigned int serial_txx9_get_mctrl(struct uart_port *port) | 433 | static unsigned int serial_txx9_get_mctrl(struct uart_port *port) |
429 | { | 434 | { |
430 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 435 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
431 | unsigned int ret; | 436 | unsigned int ret; |
432 | 437 | ||
433 | /* no modem control lines */ | 438 | /* no modem control lines */ |
@@ -440,7 +445,7 @@ static unsigned int serial_txx9_get_mctrl(struct uart_port *port) | |||
440 | 445 | ||
441 | static void serial_txx9_set_mctrl(struct uart_port *port, unsigned int mctrl) | 446 | static void serial_txx9_set_mctrl(struct uart_port *port, unsigned int mctrl) |
442 | { | 447 | { |
443 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 448 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
444 | 449 | ||
445 | if (mctrl & TIOCM_RTS) | 450 | if (mctrl & TIOCM_RTS) |
446 | sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSSC); | 451 | sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSSC); |
@@ -450,7 +455,7 @@ static void serial_txx9_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
450 | 455 | ||
451 | static void serial_txx9_break_ctl(struct uart_port *port, int break_state) | 456 | static void serial_txx9_break_ctl(struct uart_port *port, int break_state) |
452 | { | 457 | { |
453 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 458 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
454 | unsigned long flags; | 459 | unsigned long flags; |
455 | 460 | ||
456 | spin_lock_irqsave(&up->port.lock, flags); | 461 | spin_lock_irqsave(&up->port.lock, flags); |
@@ -494,7 +499,7 @@ static int serial_txx9_get_poll_char(struct uart_port *port) | |||
494 | { | 499 | { |
495 | unsigned int ier; | 500 | unsigned int ier; |
496 | unsigned char c; | 501 | unsigned char c; |
497 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 502 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
498 | 503 | ||
499 | /* | 504 | /* |
500 | * First save the IER then disable the interrupts | 505 | * First save the IER then disable the interrupts |
@@ -520,7 +525,7 @@ static int serial_txx9_get_poll_char(struct uart_port *port) | |||
520 | static void serial_txx9_put_poll_char(struct uart_port *port, unsigned char c) | 525 | static void serial_txx9_put_poll_char(struct uart_port *port, unsigned char c) |
521 | { | 526 | { |
522 | unsigned int ier; | 527 | unsigned int ier; |
523 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 528 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
524 | 529 | ||
525 | /* | 530 | /* |
526 | * First save the IER then disable the interrupts | 531 | * First save the IER then disable the interrupts |
@@ -551,7 +556,7 @@ static void serial_txx9_put_poll_char(struct uart_port *port, unsigned char c) | |||
551 | 556 | ||
552 | static int serial_txx9_startup(struct uart_port *port) | 557 | static int serial_txx9_startup(struct uart_port *port) |
553 | { | 558 | { |
554 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 559 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
555 | unsigned long flags; | 560 | unsigned long flags; |
556 | int retval; | 561 | int retval; |
557 | 562 | ||
@@ -596,7 +601,7 @@ static int serial_txx9_startup(struct uart_port *port) | |||
596 | 601 | ||
597 | static void serial_txx9_shutdown(struct uart_port *port) | 602 | static void serial_txx9_shutdown(struct uart_port *port) |
598 | { | 603 | { |
599 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 604 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
600 | unsigned long flags; | 605 | unsigned long flags; |
601 | 606 | ||
602 | /* | 607 | /* |
@@ -636,7 +641,7 @@ static void | |||
636 | serial_txx9_set_termios(struct uart_port *port, struct ktermios *termios, | 641 | serial_txx9_set_termios(struct uart_port *port, struct ktermios *termios, |
637 | struct ktermios *old) | 642 | struct ktermios *old) |
638 | { | 643 | { |
639 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 644 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
640 | unsigned int cval, fcr = 0; | 645 | unsigned int cval, fcr = 0; |
641 | unsigned long flags; | 646 | unsigned long flags; |
642 | unsigned int baud, quot; | 647 | unsigned int baud, quot; |
@@ -814,19 +819,19 @@ static void serial_txx9_release_resource(struct uart_txx9_port *up) | |||
814 | 819 | ||
815 | static void serial_txx9_release_port(struct uart_port *port) | 820 | static void serial_txx9_release_port(struct uart_port *port) |
816 | { | 821 | { |
817 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 822 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
818 | serial_txx9_release_resource(up); | 823 | serial_txx9_release_resource(up); |
819 | } | 824 | } |
820 | 825 | ||
821 | static int serial_txx9_request_port(struct uart_port *port) | 826 | static int serial_txx9_request_port(struct uart_port *port) |
822 | { | 827 | { |
823 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 828 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
824 | return serial_txx9_request_resource(up); | 829 | return serial_txx9_request_resource(up); |
825 | } | 830 | } |
826 | 831 | ||
827 | static void serial_txx9_config_port(struct uart_port *port, int uflags) | 832 | static void serial_txx9_config_port(struct uart_port *port, int uflags) |
828 | { | 833 | { |
829 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 834 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
830 | int ret; | 835 | int ret; |
831 | 836 | ||
832 | /* | 837 | /* |
@@ -897,7 +902,7 @@ static void __init serial_txx9_register_ports(struct uart_driver *drv, | |||
897 | 902 | ||
898 | static void serial_txx9_console_putchar(struct uart_port *port, int ch) | 903 | static void serial_txx9_console_putchar(struct uart_port *port, int ch) |
899 | { | 904 | { |
900 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 905 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
901 | 906 | ||
902 | wait_for_xmitr(up); | 907 | wait_for_xmitr(up); |
903 | sio_out(up, TXX9_SITFIFO, ch); | 908 | sio_out(up, TXX9_SITFIFO, ch); |
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 85119fb7cb50..6498bd1fb6dd 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -1143,7 +1143,7 @@ static void serial_console_write(struct console *co, const char *s, | |||
1143 | while ((sci_in(port, SCxSR) & bits) != bits) | 1143 | while ((sci_in(port, SCxSR) & bits) != bits) |
1144 | cpu_relax(); | 1144 | cpu_relax(); |
1145 | 1145 | ||
1146 | if (sci_port->disable); | 1146 | if (sci_port->disable) |
1147 | sci_port->disable(port); | 1147 | sci_port->disable(port); |
1148 | } | 1148 | } |
1149 | 1149 | ||