Commit de7053c77123940ac294508d2161f42063d4166a
Committed by
Greg Kroah-Hartman
1 parent
1df7e2491f
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
tty: serial: rp2: drop uart_port->lock before calling tty_flip_buffer_push()
The current driver triggers a lockdep warning for if tty_flip_buffer_push() is called with uart_port->lock locked. This never shows up on UP kernels and comes up only on SMP kernels. Crash looks like this (produced with samsung.c driver): ----- [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) [<c01b59ac>] (do_raw_spin_unlock+0xc4/0xd8) from [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0) [<c03627e4>] (_raw_spin_unlock_irqrestore+0xc/0x38) from [<c020a1a8>] (s3c24xx_serial_rx_chars+0) [<c020a1a8>] (s3c24xx_serial_rx_chars+0x12c/0x260) from [<c020aae8>] (s3c64xx_serial_handle_irq+) [<c020aae8>] (s3c64xx_serial_handle_irq+0x48/0x60) from [<c006aaa0>] (handle_irq_event_percpu+0x) [<c006aaa0>] (handle_irq_event_percpu+0x50/0x194) from [<c006ac20>] (handle_irq_event+0x3c/0x5c) [<c006ac20>] (handle_irq_event+0x3c/0x5c) from [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) [<c006d864>] (handle_fasteoi_irq+0x80/0x13c) from [<c006a4a4>] (generic_handle_irq+0x20/0x30) [<c006a4a4>] (generic_handle_irq+0x20/0x30) from [<c000f454>] (handle_IRQ+0x38/0x94) [<c000f454>] (handle_IRQ+0x38/0x94) from [<c0008538>] (gic_handle_irq+0x34/0x68) [<c0008538>] (gic_handle_irq+0x34/0x68) from [<c00123c0>] (__irq_svc+0x40/0x70) Exception stack(0xc04cdf70 to 0xc04cdfb8) df60: 00000000 00000000 0000166e 00000000 df80: c04cc000 c050278f c050278f 00000001 c04d444c 410fc0f4 c03649b0 00000000 dfa0: 00000001 c04cdfb8 c000f758 c000f75c 60070013 ffffffff [<c00123c0>] (__irq_svc+0x40/0x70) from [<c000f75c>] (arch_cpu_idle+0x28/0x30) [<c000f75c>] (arch_cpu_idle+0x28/0x30) from [<c0054888>] (cpu_startup_entry+0x5c/0x148) [<c0054888>] (cpu_startup_entry+0x5c/0x148) from [<c0497aa4>] (start_kernel+0x334/0x38c) BUG: spinlock lockup suspected on CPU#0, kworker/0:1/360 lock: s3c24xx_serial_ports+0x1d8/0x370, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1 CPU: 0 PID: 360 Comm: kworker/0:1 Not tainted 3.11.0-rc6-next-20130819-00003-g75485f1 #2 Workqueue: events flush_to_ldisc [<c0014d58>] (unwind_backtrace+0x0/0xf8) from [<c0011908>] (show_stack+0x10/0x14) [<c0011908>] (show_stack+0x10/0x14) from [<c035da34>] (dump_stack+0x6c/0xac) [<c035da34>] (dump_stack+0x6c/0xac) from [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) [<c01b581c>] (do_raw_spin_lock+0x100/0x17c) from [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) [<c03628a0>] (_raw_spin_lock_irqsave+0x20/0x28) from [<c0203224>] (uart_start+0x18/0x34) [<c0203224>] (uart_start+0x18/0x34) from [<c01ef890>] (__receive_buf+0x4b4/0x738) [<c01ef890>] (__receive_buf+0x4b4/0x738) from [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) [<c01efb44>] (n_tty_receive_buf2+0x30/0x98) from [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) [<c01f2ba8>] (flush_to_ldisc+0xec/0x138) from [<c0031af0>] (process_one_work+0xfc/0x348) [<c0031af0>] (process_one_work+0xfc/0x348) from [<c0032138>] (worker_thread+0x138/0x37c) [<c0032138>] (worker_thread+0x138/0x37c) from [<c0037a7c>] (kthread+0xa4/0xb0) [<c0037a7c>] (kthread+0xa4/0xb0) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) ----- Release the port lock before calling tty_flip_buffer_push() and reacquire it after the call. Similar stuff was already done for few other drivers in the past, like: commit 2389b272168ceec056ca1d8a870a97fa9c26e11a Author: Thomas Gleixner <tglx@linutronix.de> Date: Tue May 29 21:53:50 2007 +0100 [ARM] 4417/1: Serial: Fix AMBA drivers locking Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Showing 1 changed file with 2 additions and 0 deletions Inline Diff
drivers/tty/serial/rp2.c
1 | /* | 1 | /* |
2 | * Driver for Comtrol RocketPort EXPRESS/INFINITY cards | 2 | * Driver for Comtrol RocketPort EXPRESS/INFINITY cards |
3 | * | 3 | * |
4 | * Copyright (C) 2012 Kevin Cernekee <cernekee@gmail.com> | 4 | * Copyright (C) 2012 Kevin Cernekee <cernekee@gmail.com> |
5 | * | 5 | * |
6 | * Inspired by, and loosely based on: | 6 | * Inspired by, and loosely based on: |
7 | * | 7 | * |
8 | * ar933x_uart.c | 8 | * ar933x_uart.c |
9 | * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | 9 | * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> |
10 | * | 10 | * |
11 | * rocketport_infinity_express-linux-1.20.tar.gz | 11 | * rocketport_infinity_express-linux-1.20.tar.gz |
12 | * Copyright (C) 2004-2011 Comtrol, Inc. | 12 | * Copyright (C) 2004-2011 Comtrol, Inc. |
13 | * | 13 | * |
14 | * This program is free software; you can redistribute it and/or modify it | 14 | * This program is free software; you can redistribute it and/or modify it |
15 | * under the terms of the GNU General Public License version 2 as published | 15 | * under the terms of the GNU General Public License version 2 as published |
16 | * by the Free Software Foundation. | 16 | * by the Free Software Foundation. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/bitops.h> | 19 | #include <linux/bitops.h> |
20 | #include <linux/compiler.h> | 20 | #include <linux/compiler.h> |
21 | #include <linux/completion.h> | 21 | #include <linux/completion.h> |
22 | #include <linux/console.h> | 22 | #include <linux/console.h> |
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
24 | #include <linux/firmware.h> | 24 | #include <linux/firmware.h> |
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/io.h> | 26 | #include <linux/io.h> |
27 | #include <linux/ioport.h> | 27 | #include <linux/ioport.h> |
28 | #include <linux/irq.h> | 28 | #include <linux/irq.h> |
29 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <linux/log2.h> | 30 | #include <linux/log2.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/pci.h> | 32 | #include <linux/pci.h> |
33 | #include <linux/serial.h> | 33 | #include <linux/serial.h> |
34 | #include <linux/serial_core.h> | 34 | #include <linux/serial_core.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/sysrq.h> | 36 | #include <linux/sysrq.h> |
37 | #include <linux/tty.h> | 37 | #include <linux/tty.h> |
38 | #include <linux/tty_flip.h> | 38 | #include <linux/tty_flip.h> |
39 | #include <linux/types.h> | 39 | #include <linux/types.h> |
40 | 40 | ||
41 | #define DRV_NAME "rp2" | 41 | #define DRV_NAME "rp2" |
42 | 42 | ||
43 | #define RP2_FW_NAME "rp2.fw" | 43 | #define RP2_FW_NAME "rp2.fw" |
44 | #define RP2_UCODE_BYTES 0x3f | 44 | #define RP2_UCODE_BYTES 0x3f |
45 | 45 | ||
46 | #define PORTS_PER_ASIC 16 | 46 | #define PORTS_PER_ASIC 16 |
47 | #define ALL_PORTS_MASK (BIT(PORTS_PER_ASIC) - 1) | 47 | #define ALL_PORTS_MASK (BIT(PORTS_PER_ASIC) - 1) |
48 | 48 | ||
49 | #define UART_CLOCK 44236800 | 49 | #define UART_CLOCK 44236800 |
50 | #define DEFAULT_BAUD_DIV (UART_CLOCK / (9600 * 16)) | 50 | #define DEFAULT_BAUD_DIV (UART_CLOCK / (9600 * 16)) |
51 | #define FIFO_SIZE 512 | 51 | #define FIFO_SIZE 512 |
52 | 52 | ||
53 | /* BAR0 registers */ | 53 | /* BAR0 registers */ |
54 | #define RP2_FPGA_CTL0 0x110 | 54 | #define RP2_FPGA_CTL0 0x110 |
55 | #define RP2_FPGA_CTL1 0x11c | 55 | #define RP2_FPGA_CTL1 0x11c |
56 | #define RP2_IRQ_MASK 0x1ec | 56 | #define RP2_IRQ_MASK 0x1ec |
57 | #define RP2_IRQ_MASK_EN_m BIT(0) | 57 | #define RP2_IRQ_MASK_EN_m BIT(0) |
58 | #define RP2_IRQ_STATUS 0x1f0 | 58 | #define RP2_IRQ_STATUS 0x1f0 |
59 | 59 | ||
60 | /* BAR1 registers */ | 60 | /* BAR1 registers */ |
61 | #define RP2_ASIC_SPACING 0x1000 | 61 | #define RP2_ASIC_SPACING 0x1000 |
62 | #define RP2_ASIC_OFFSET(i) ((i) << ilog2(RP2_ASIC_SPACING)) | 62 | #define RP2_ASIC_OFFSET(i) ((i) << ilog2(RP2_ASIC_SPACING)) |
63 | 63 | ||
64 | #define RP2_PORT_BASE 0x000 | 64 | #define RP2_PORT_BASE 0x000 |
65 | #define RP2_PORT_SPACING 0x040 | 65 | #define RP2_PORT_SPACING 0x040 |
66 | 66 | ||
67 | #define RP2_UCODE_BASE 0x400 | 67 | #define RP2_UCODE_BASE 0x400 |
68 | #define RP2_UCODE_SPACING 0x80 | 68 | #define RP2_UCODE_SPACING 0x80 |
69 | 69 | ||
70 | #define RP2_CLK_PRESCALER 0xc00 | 70 | #define RP2_CLK_PRESCALER 0xc00 |
71 | #define RP2_CH_IRQ_STAT 0xc04 | 71 | #define RP2_CH_IRQ_STAT 0xc04 |
72 | #define RP2_CH_IRQ_MASK 0xc08 | 72 | #define RP2_CH_IRQ_MASK 0xc08 |
73 | #define RP2_ASIC_IRQ 0xd00 | 73 | #define RP2_ASIC_IRQ 0xd00 |
74 | #define RP2_ASIC_IRQ_EN_m BIT(20) | 74 | #define RP2_ASIC_IRQ_EN_m BIT(20) |
75 | #define RP2_GLOBAL_CMD 0xd0c | 75 | #define RP2_GLOBAL_CMD 0xd0c |
76 | #define RP2_ASIC_CFG 0xd04 | 76 | #define RP2_ASIC_CFG 0xd04 |
77 | 77 | ||
78 | /* port registers */ | 78 | /* port registers */ |
79 | #define RP2_DATA_DWORD 0x000 | 79 | #define RP2_DATA_DWORD 0x000 |
80 | 80 | ||
81 | #define RP2_DATA_BYTE 0x008 | 81 | #define RP2_DATA_BYTE 0x008 |
82 | #define RP2_DATA_BYTE_ERR_PARITY_m BIT(8) | 82 | #define RP2_DATA_BYTE_ERR_PARITY_m BIT(8) |
83 | #define RP2_DATA_BYTE_ERR_OVERRUN_m BIT(9) | 83 | #define RP2_DATA_BYTE_ERR_OVERRUN_m BIT(9) |
84 | #define RP2_DATA_BYTE_ERR_FRAMING_m BIT(10) | 84 | #define RP2_DATA_BYTE_ERR_FRAMING_m BIT(10) |
85 | #define RP2_DATA_BYTE_BREAK_m BIT(11) | 85 | #define RP2_DATA_BYTE_BREAK_m BIT(11) |
86 | 86 | ||
87 | /* This lets uart_insert_char() drop bytes received on a !CREAD port */ | 87 | /* This lets uart_insert_char() drop bytes received on a !CREAD port */ |
88 | #define RP2_DUMMY_READ BIT(16) | 88 | #define RP2_DUMMY_READ BIT(16) |
89 | 89 | ||
90 | #define RP2_DATA_BYTE_EXCEPTION_MASK (RP2_DATA_BYTE_ERR_PARITY_m | \ | 90 | #define RP2_DATA_BYTE_EXCEPTION_MASK (RP2_DATA_BYTE_ERR_PARITY_m | \ |
91 | RP2_DATA_BYTE_ERR_OVERRUN_m | \ | 91 | RP2_DATA_BYTE_ERR_OVERRUN_m | \ |
92 | RP2_DATA_BYTE_ERR_FRAMING_m | \ | 92 | RP2_DATA_BYTE_ERR_FRAMING_m | \ |
93 | RP2_DATA_BYTE_BREAK_m) | 93 | RP2_DATA_BYTE_BREAK_m) |
94 | 94 | ||
95 | #define RP2_RX_FIFO_COUNT 0x00c | 95 | #define RP2_RX_FIFO_COUNT 0x00c |
96 | #define RP2_TX_FIFO_COUNT 0x00e | 96 | #define RP2_TX_FIFO_COUNT 0x00e |
97 | 97 | ||
98 | #define RP2_CHAN_STAT 0x010 | 98 | #define RP2_CHAN_STAT 0x010 |
99 | #define RP2_CHAN_STAT_RXDATA_m BIT(0) | 99 | #define RP2_CHAN_STAT_RXDATA_m BIT(0) |
100 | #define RP2_CHAN_STAT_DCD_m BIT(3) | 100 | #define RP2_CHAN_STAT_DCD_m BIT(3) |
101 | #define RP2_CHAN_STAT_DSR_m BIT(4) | 101 | #define RP2_CHAN_STAT_DSR_m BIT(4) |
102 | #define RP2_CHAN_STAT_CTS_m BIT(5) | 102 | #define RP2_CHAN_STAT_CTS_m BIT(5) |
103 | #define RP2_CHAN_STAT_RI_m BIT(6) | 103 | #define RP2_CHAN_STAT_RI_m BIT(6) |
104 | #define RP2_CHAN_STAT_OVERRUN_m BIT(13) | 104 | #define RP2_CHAN_STAT_OVERRUN_m BIT(13) |
105 | #define RP2_CHAN_STAT_DSR_CHANGED_m BIT(16) | 105 | #define RP2_CHAN_STAT_DSR_CHANGED_m BIT(16) |
106 | #define RP2_CHAN_STAT_CTS_CHANGED_m BIT(17) | 106 | #define RP2_CHAN_STAT_CTS_CHANGED_m BIT(17) |
107 | #define RP2_CHAN_STAT_CD_CHANGED_m BIT(18) | 107 | #define RP2_CHAN_STAT_CD_CHANGED_m BIT(18) |
108 | #define RP2_CHAN_STAT_RI_CHANGED_m BIT(22) | 108 | #define RP2_CHAN_STAT_RI_CHANGED_m BIT(22) |
109 | #define RP2_CHAN_STAT_TXEMPTY_m BIT(25) | 109 | #define RP2_CHAN_STAT_TXEMPTY_m BIT(25) |
110 | 110 | ||
111 | #define RP2_CHAN_STAT_MS_CHANGED_MASK (RP2_CHAN_STAT_DSR_CHANGED_m | \ | 111 | #define RP2_CHAN_STAT_MS_CHANGED_MASK (RP2_CHAN_STAT_DSR_CHANGED_m | \ |
112 | RP2_CHAN_STAT_CTS_CHANGED_m | \ | 112 | RP2_CHAN_STAT_CTS_CHANGED_m | \ |
113 | RP2_CHAN_STAT_CD_CHANGED_m | \ | 113 | RP2_CHAN_STAT_CD_CHANGED_m | \ |
114 | RP2_CHAN_STAT_RI_CHANGED_m) | 114 | RP2_CHAN_STAT_RI_CHANGED_m) |
115 | 115 | ||
116 | #define RP2_TXRX_CTL 0x014 | 116 | #define RP2_TXRX_CTL 0x014 |
117 | #define RP2_TXRX_CTL_MSRIRQ_m BIT(0) | 117 | #define RP2_TXRX_CTL_MSRIRQ_m BIT(0) |
118 | #define RP2_TXRX_CTL_RXIRQ_m BIT(2) | 118 | #define RP2_TXRX_CTL_RXIRQ_m BIT(2) |
119 | #define RP2_TXRX_CTL_RX_TRIG_s 3 | 119 | #define RP2_TXRX_CTL_RX_TRIG_s 3 |
120 | #define RP2_TXRX_CTL_RX_TRIG_m (0x3 << RP2_TXRX_CTL_RX_TRIG_s) | 120 | #define RP2_TXRX_CTL_RX_TRIG_m (0x3 << RP2_TXRX_CTL_RX_TRIG_s) |
121 | #define RP2_TXRX_CTL_RX_TRIG_1 (0x1 << RP2_TXRX_CTL_RX_TRIG_s) | 121 | #define RP2_TXRX_CTL_RX_TRIG_1 (0x1 << RP2_TXRX_CTL_RX_TRIG_s) |
122 | #define RP2_TXRX_CTL_RX_TRIG_256 (0x2 << RP2_TXRX_CTL_RX_TRIG_s) | 122 | #define RP2_TXRX_CTL_RX_TRIG_256 (0x2 << RP2_TXRX_CTL_RX_TRIG_s) |
123 | #define RP2_TXRX_CTL_RX_TRIG_448 (0x3 << RP2_TXRX_CTL_RX_TRIG_s) | 123 | #define RP2_TXRX_CTL_RX_TRIG_448 (0x3 << RP2_TXRX_CTL_RX_TRIG_s) |
124 | #define RP2_TXRX_CTL_RX_EN_m BIT(5) | 124 | #define RP2_TXRX_CTL_RX_EN_m BIT(5) |
125 | #define RP2_TXRX_CTL_RTSFLOW_m BIT(6) | 125 | #define RP2_TXRX_CTL_RTSFLOW_m BIT(6) |
126 | #define RP2_TXRX_CTL_DTRFLOW_m BIT(7) | 126 | #define RP2_TXRX_CTL_DTRFLOW_m BIT(7) |
127 | #define RP2_TXRX_CTL_TX_TRIG_s 16 | 127 | #define RP2_TXRX_CTL_TX_TRIG_s 16 |
128 | #define RP2_TXRX_CTL_TX_TRIG_m (0x3 << RP2_TXRX_CTL_RX_TRIG_s) | 128 | #define RP2_TXRX_CTL_TX_TRIG_m (0x3 << RP2_TXRX_CTL_RX_TRIG_s) |
129 | #define RP2_TXRX_CTL_DSRFLOW_m BIT(18) | 129 | #define RP2_TXRX_CTL_DSRFLOW_m BIT(18) |
130 | #define RP2_TXRX_CTL_TXIRQ_m BIT(19) | 130 | #define RP2_TXRX_CTL_TXIRQ_m BIT(19) |
131 | #define RP2_TXRX_CTL_CTSFLOW_m BIT(23) | 131 | #define RP2_TXRX_CTL_CTSFLOW_m BIT(23) |
132 | #define RP2_TXRX_CTL_TX_EN_m BIT(24) | 132 | #define RP2_TXRX_CTL_TX_EN_m BIT(24) |
133 | #define RP2_TXRX_CTL_RTS_m BIT(25) | 133 | #define RP2_TXRX_CTL_RTS_m BIT(25) |
134 | #define RP2_TXRX_CTL_DTR_m BIT(26) | 134 | #define RP2_TXRX_CTL_DTR_m BIT(26) |
135 | #define RP2_TXRX_CTL_LOOP_m BIT(27) | 135 | #define RP2_TXRX_CTL_LOOP_m BIT(27) |
136 | #define RP2_TXRX_CTL_BREAK_m BIT(28) | 136 | #define RP2_TXRX_CTL_BREAK_m BIT(28) |
137 | #define RP2_TXRX_CTL_CMSPAR_m BIT(29) | 137 | #define RP2_TXRX_CTL_CMSPAR_m BIT(29) |
138 | #define RP2_TXRX_CTL_nPARODD_m BIT(30) | 138 | #define RP2_TXRX_CTL_nPARODD_m BIT(30) |
139 | #define RP2_TXRX_CTL_PARENB_m BIT(31) | 139 | #define RP2_TXRX_CTL_PARENB_m BIT(31) |
140 | 140 | ||
141 | #define RP2_UART_CTL 0x018 | 141 | #define RP2_UART_CTL 0x018 |
142 | #define RP2_UART_CTL_MODE_s 0 | 142 | #define RP2_UART_CTL_MODE_s 0 |
143 | #define RP2_UART_CTL_MODE_m (0x7 << RP2_UART_CTL_MODE_s) | 143 | #define RP2_UART_CTL_MODE_m (0x7 << RP2_UART_CTL_MODE_s) |
144 | #define RP2_UART_CTL_MODE_rs232 (0x1 << RP2_UART_CTL_MODE_s) | 144 | #define RP2_UART_CTL_MODE_rs232 (0x1 << RP2_UART_CTL_MODE_s) |
145 | #define RP2_UART_CTL_FLUSH_RX_m BIT(3) | 145 | #define RP2_UART_CTL_FLUSH_RX_m BIT(3) |
146 | #define RP2_UART_CTL_FLUSH_TX_m BIT(4) | 146 | #define RP2_UART_CTL_FLUSH_TX_m BIT(4) |
147 | #define RP2_UART_CTL_RESET_CH_m BIT(5) | 147 | #define RP2_UART_CTL_RESET_CH_m BIT(5) |
148 | #define RP2_UART_CTL_XMIT_EN_m BIT(6) | 148 | #define RP2_UART_CTL_XMIT_EN_m BIT(6) |
149 | #define RP2_UART_CTL_DATABITS_s 8 | 149 | #define RP2_UART_CTL_DATABITS_s 8 |
150 | #define RP2_UART_CTL_DATABITS_m (0x3 << RP2_UART_CTL_DATABITS_s) | 150 | #define RP2_UART_CTL_DATABITS_m (0x3 << RP2_UART_CTL_DATABITS_s) |
151 | #define RP2_UART_CTL_DATABITS_8 (0x3 << RP2_UART_CTL_DATABITS_s) | 151 | #define RP2_UART_CTL_DATABITS_8 (0x3 << RP2_UART_CTL_DATABITS_s) |
152 | #define RP2_UART_CTL_DATABITS_7 (0x2 << RP2_UART_CTL_DATABITS_s) | 152 | #define RP2_UART_CTL_DATABITS_7 (0x2 << RP2_UART_CTL_DATABITS_s) |
153 | #define RP2_UART_CTL_DATABITS_6 (0x1 << RP2_UART_CTL_DATABITS_s) | 153 | #define RP2_UART_CTL_DATABITS_6 (0x1 << RP2_UART_CTL_DATABITS_s) |
154 | #define RP2_UART_CTL_DATABITS_5 (0x0 << RP2_UART_CTL_DATABITS_s) | 154 | #define RP2_UART_CTL_DATABITS_5 (0x0 << RP2_UART_CTL_DATABITS_s) |
155 | #define RP2_UART_CTL_STOPBITS_m BIT(10) | 155 | #define RP2_UART_CTL_STOPBITS_m BIT(10) |
156 | 156 | ||
157 | #define RP2_BAUD 0x01c | 157 | #define RP2_BAUD 0x01c |
158 | 158 | ||
159 | /* ucode registers */ | 159 | /* ucode registers */ |
160 | #define RP2_TX_SWFLOW 0x02 | 160 | #define RP2_TX_SWFLOW 0x02 |
161 | #define RP2_TX_SWFLOW_ena 0x81 | 161 | #define RP2_TX_SWFLOW_ena 0x81 |
162 | #define RP2_TX_SWFLOW_dis 0x9d | 162 | #define RP2_TX_SWFLOW_dis 0x9d |
163 | 163 | ||
164 | #define RP2_RX_SWFLOW 0x0c | 164 | #define RP2_RX_SWFLOW 0x0c |
165 | #define RP2_RX_SWFLOW_ena 0x81 | 165 | #define RP2_RX_SWFLOW_ena 0x81 |
166 | #define RP2_RX_SWFLOW_dis 0x8d | 166 | #define RP2_RX_SWFLOW_dis 0x8d |
167 | 167 | ||
168 | #define RP2_RX_FIFO 0x37 | 168 | #define RP2_RX_FIFO 0x37 |
169 | #define RP2_RX_FIFO_ena 0x08 | 169 | #define RP2_RX_FIFO_ena 0x08 |
170 | #define RP2_RX_FIFO_dis 0x81 | 170 | #define RP2_RX_FIFO_dis 0x81 |
171 | 171 | ||
172 | static struct uart_driver rp2_uart_driver = { | 172 | static struct uart_driver rp2_uart_driver = { |
173 | .owner = THIS_MODULE, | 173 | .owner = THIS_MODULE, |
174 | .driver_name = DRV_NAME, | 174 | .driver_name = DRV_NAME, |
175 | .dev_name = "ttyRP", | 175 | .dev_name = "ttyRP", |
176 | .nr = CONFIG_SERIAL_RP2_NR_UARTS, | 176 | .nr = CONFIG_SERIAL_RP2_NR_UARTS, |
177 | }; | 177 | }; |
178 | 178 | ||
179 | struct rp2_card; | 179 | struct rp2_card; |
180 | 180 | ||
181 | struct rp2_uart_port { | 181 | struct rp2_uart_port { |
182 | struct uart_port port; | 182 | struct uart_port port; |
183 | int idx; | 183 | int idx; |
184 | int ignore_rx; | 184 | int ignore_rx; |
185 | struct rp2_card *card; | 185 | struct rp2_card *card; |
186 | void __iomem *asic_base; | 186 | void __iomem *asic_base; |
187 | void __iomem *base; | 187 | void __iomem *base; |
188 | void __iomem *ucode; | 188 | void __iomem *ucode; |
189 | }; | 189 | }; |
190 | 190 | ||
191 | struct rp2_card { | 191 | struct rp2_card { |
192 | struct pci_dev *pdev; | 192 | struct pci_dev *pdev; |
193 | struct rp2_uart_port *ports; | 193 | struct rp2_uart_port *ports; |
194 | int n_ports; | 194 | int n_ports; |
195 | int initialized_ports; | 195 | int initialized_ports; |
196 | int minor_start; | 196 | int minor_start; |
197 | int smpte; | 197 | int smpte; |
198 | void __iomem *bar0; | 198 | void __iomem *bar0; |
199 | void __iomem *bar1; | 199 | void __iomem *bar1; |
200 | spinlock_t card_lock; | 200 | spinlock_t card_lock; |
201 | struct completion fw_loaded; | 201 | struct completion fw_loaded; |
202 | }; | 202 | }; |
203 | 203 | ||
204 | #define RP_ID(prod) PCI_VDEVICE(RP, (prod)) | 204 | #define RP_ID(prod) PCI_VDEVICE(RP, (prod)) |
205 | #define RP_CAP(ports, smpte) (((ports) << 8) | ((smpte) << 0)) | 205 | #define RP_CAP(ports, smpte) (((ports) << 8) | ((smpte) << 0)) |
206 | 206 | ||
207 | static inline void rp2_decode_cap(const struct pci_device_id *id, | 207 | static inline void rp2_decode_cap(const struct pci_device_id *id, |
208 | int *ports, int *smpte) | 208 | int *ports, int *smpte) |
209 | { | 209 | { |
210 | *ports = id->driver_data >> 8; | 210 | *ports = id->driver_data >> 8; |
211 | *smpte = id->driver_data & 0xff; | 211 | *smpte = id->driver_data & 0xff; |
212 | } | 212 | } |
213 | 213 | ||
214 | static DEFINE_SPINLOCK(rp2_minor_lock); | 214 | static DEFINE_SPINLOCK(rp2_minor_lock); |
215 | static int rp2_minor_next; | 215 | static int rp2_minor_next; |
216 | 216 | ||
217 | static int rp2_alloc_ports(int n_ports) | 217 | static int rp2_alloc_ports(int n_ports) |
218 | { | 218 | { |
219 | int ret = -ENOSPC; | 219 | int ret = -ENOSPC; |
220 | 220 | ||
221 | spin_lock(&rp2_minor_lock); | 221 | spin_lock(&rp2_minor_lock); |
222 | if (rp2_minor_next + n_ports <= CONFIG_SERIAL_RP2_NR_UARTS) { | 222 | if (rp2_minor_next + n_ports <= CONFIG_SERIAL_RP2_NR_UARTS) { |
223 | /* sorry, no support for hot unplugging individual cards */ | 223 | /* sorry, no support for hot unplugging individual cards */ |
224 | ret = rp2_minor_next; | 224 | ret = rp2_minor_next; |
225 | rp2_minor_next += n_ports; | 225 | rp2_minor_next += n_ports; |
226 | } | 226 | } |
227 | spin_unlock(&rp2_minor_lock); | 227 | spin_unlock(&rp2_minor_lock); |
228 | 228 | ||
229 | return ret; | 229 | return ret; |
230 | } | 230 | } |
231 | 231 | ||
232 | static inline struct rp2_uart_port *port_to_up(struct uart_port *port) | 232 | static inline struct rp2_uart_port *port_to_up(struct uart_port *port) |
233 | { | 233 | { |
234 | return container_of(port, struct rp2_uart_port, port); | 234 | return container_of(port, struct rp2_uart_port, port); |
235 | } | 235 | } |
236 | 236 | ||
237 | static void rp2_rmw(struct rp2_uart_port *up, int reg, | 237 | static void rp2_rmw(struct rp2_uart_port *up, int reg, |
238 | u32 clr_bits, u32 set_bits) | 238 | u32 clr_bits, u32 set_bits) |
239 | { | 239 | { |
240 | u32 tmp = readl(up->base + reg); | 240 | u32 tmp = readl(up->base + reg); |
241 | tmp &= ~clr_bits; | 241 | tmp &= ~clr_bits; |
242 | tmp |= set_bits; | 242 | tmp |= set_bits; |
243 | writel(tmp, up->base + reg); | 243 | writel(tmp, up->base + reg); |
244 | } | 244 | } |
245 | 245 | ||
246 | static void rp2_rmw_clr(struct rp2_uart_port *up, int reg, u32 val) | 246 | static void rp2_rmw_clr(struct rp2_uart_port *up, int reg, u32 val) |
247 | { | 247 | { |
248 | rp2_rmw(up, reg, val, 0); | 248 | rp2_rmw(up, reg, val, 0); |
249 | } | 249 | } |
250 | 250 | ||
251 | static void rp2_rmw_set(struct rp2_uart_port *up, int reg, u32 val) | 251 | static void rp2_rmw_set(struct rp2_uart_port *up, int reg, u32 val) |
252 | { | 252 | { |
253 | rp2_rmw(up, reg, 0, val); | 253 | rp2_rmw(up, reg, 0, val); |
254 | } | 254 | } |
255 | 255 | ||
256 | static void rp2_mask_ch_irq(struct rp2_uart_port *up, int ch_num, | 256 | static void rp2_mask_ch_irq(struct rp2_uart_port *up, int ch_num, |
257 | int is_enabled) | 257 | int is_enabled) |
258 | { | 258 | { |
259 | unsigned long flags, irq_mask; | 259 | unsigned long flags, irq_mask; |
260 | 260 | ||
261 | spin_lock_irqsave(&up->card->card_lock, flags); | 261 | spin_lock_irqsave(&up->card->card_lock, flags); |
262 | 262 | ||
263 | irq_mask = readl(up->asic_base + RP2_CH_IRQ_MASK); | 263 | irq_mask = readl(up->asic_base + RP2_CH_IRQ_MASK); |
264 | if (is_enabled) | 264 | if (is_enabled) |
265 | irq_mask &= ~BIT(ch_num); | 265 | irq_mask &= ~BIT(ch_num); |
266 | else | 266 | else |
267 | irq_mask |= BIT(ch_num); | 267 | irq_mask |= BIT(ch_num); |
268 | writel(irq_mask, up->asic_base + RP2_CH_IRQ_MASK); | 268 | writel(irq_mask, up->asic_base + RP2_CH_IRQ_MASK); |
269 | 269 | ||
270 | spin_unlock_irqrestore(&up->card->card_lock, flags); | 270 | spin_unlock_irqrestore(&up->card->card_lock, flags); |
271 | } | 271 | } |
272 | 272 | ||
273 | static unsigned int rp2_uart_tx_empty(struct uart_port *port) | 273 | static unsigned int rp2_uart_tx_empty(struct uart_port *port) |
274 | { | 274 | { |
275 | struct rp2_uart_port *up = port_to_up(port); | 275 | struct rp2_uart_port *up = port_to_up(port); |
276 | unsigned long tx_fifo_bytes, flags; | 276 | unsigned long tx_fifo_bytes, flags; |
277 | 277 | ||
278 | /* | 278 | /* |
279 | * This should probably check the transmitter, not the FIFO. | 279 | * This should probably check the transmitter, not the FIFO. |
280 | * But the TXEMPTY bit doesn't seem to work unless the TX IRQ is | 280 | * But the TXEMPTY bit doesn't seem to work unless the TX IRQ is |
281 | * enabled. | 281 | * enabled. |
282 | */ | 282 | */ |
283 | spin_lock_irqsave(&up->port.lock, flags); | 283 | spin_lock_irqsave(&up->port.lock, flags); |
284 | tx_fifo_bytes = readw(up->base + RP2_TX_FIFO_COUNT); | 284 | tx_fifo_bytes = readw(up->base + RP2_TX_FIFO_COUNT); |
285 | spin_unlock_irqrestore(&up->port.lock, flags); | 285 | spin_unlock_irqrestore(&up->port.lock, flags); |
286 | 286 | ||
287 | return tx_fifo_bytes ? 0 : TIOCSER_TEMT; | 287 | return tx_fifo_bytes ? 0 : TIOCSER_TEMT; |
288 | } | 288 | } |
289 | 289 | ||
290 | static unsigned int rp2_uart_get_mctrl(struct uart_port *port) | 290 | static unsigned int rp2_uart_get_mctrl(struct uart_port *port) |
291 | { | 291 | { |
292 | struct rp2_uart_port *up = port_to_up(port); | 292 | struct rp2_uart_port *up = port_to_up(port); |
293 | u32 status; | 293 | u32 status; |
294 | 294 | ||
295 | status = readl(up->base + RP2_CHAN_STAT); | 295 | status = readl(up->base + RP2_CHAN_STAT); |
296 | return ((status & RP2_CHAN_STAT_DCD_m) ? TIOCM_CAR : 0) | | 296 | return ((status & RP2_CHAN_STAT_DCD_m) ? TIOCM_CAR : 0) | |
297 | ((status & RP2_CHAN_STAT_DSR_m) ? TIOCM_DSR : 0) | | 297 | ((status & RP2_CHAN_STAT_DSR_m) ? TIOCM_DSR : 0) | |
298 | ((status & RP2_CHAN_STAT_CTS_m) ? TIOCM_CTS : 0) | | 298 | ((status & RP2_CHAN_STAT_CTS_m) ? TIOCM_CTS : 0) | |
299 | ((status & RP2_CHAN_STAT_RI_m) ? TIOCM_RI : 0); | 299 | ((status & RP2_CHAN_STAT_RI_m) ? TIOCM_RI : 0); |
300 | } | 300 | } |
301 | 301 | ||
302 | static void rp2_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | 302 | static void rp2_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) |
303 | { | 303 | { |
304 | rp2_rmw(port_to_up(port), RP2_TXRX_CTL, | 304 | rp2_rmw(port_to_up(port), RP2_TXRX_CTL, |
305 | RP2_TXRX_CTL_DTR_m | RP2_TXRX_CTL_RTS_m | RP2_TXRX_CTL_LOOP_m, | 305 | RP2_TXRX_CTL_DTR_m | RP2_TXRX_CTL_RTS_m | RP2_TXRX_CTL_LOOP_m, |
306 | ((mctrl & TIOCM_DTR) ? RP2_TXRX_CTL_DTR_m : 0) | | 306 | ((mctrl & TIOCM_DTR) ? RP2_TXRX_CTL_DTR_m : 0) | |
307 | ((mctrl & TIOCM_RTS) ? RP2_TXRX_CTL_RTS_m : 0) | | 307 | ((mctrl & TIOCM_RTS) ? RP2_TXRX_CTL_RTS_m : 0) | |
308 | ((mctrl & TIOCM_LOOP) ? RP2_TXRX_CTL_LOOP_m : 0)); | 308 | ((mctrl & TIOCM_LOOP) ? RP2_TXRX_CTL_LOOP_m : 0)); |
309 | } | 309 | } |
310 | 310 | ||
311 | static void rp2_uart_start_tx(struct uart_port *port) | 311 | static void rp2_uart_start_tx(struct uart_port *port) |
312 | { | 312 | { |
313 | rp2_rmw_set(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_TXIRQ_m); | 313 | rp2_rmw_set(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_TXIRQ_m); |
314 | } | 314 | } |
315 | 315 | ||
316 | static void rp2_uart_stop_tx(struct uart_port *port) | 316 | static void rp2_uart_stop_tx(struct uart_port *port) |
317 | { | 317 | { |
318 | rp2_rmw_clr(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_TXIRQ_m); | 318 | rp2_rmw_clr(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_TXIRQ_m); |
319 | } | 319 | } |
320 | 320 | ||
321 | static void rp2_uart_stop_rx(struct uart_port *port) | 321 | static void rp2_uart_stop_rx(struct uart_port *port) |
322 | { | 322 | { |
323 | rp2_rmw_clr(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_RXIRQ_m); | 323 | rp2_rmw_clr(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_RXIRQ_m); |
324 | } | 324 | } |
325 | 325 | ||
326 | static void rp2_uart_break_ctl(struct uart_port *port, int break_state) | 326 | static void rp2_uart_break_ctl(struct uart_port *port, int break_state) |
327 | { | 327 | { |
328 | unsigned long flags; | 328 | unsigned long flags; |
329 | 329 | ||
330 | spin_lock_irqsave(&port->lock, flags); | 330 | spin_lock_irqsave(&port->lock, flags); |
331 | rp2_rmw(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_BREAK_m, | 331 | rp2_rmw(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_BREAK_m, |
332 | break_state ? RP2_TXRX_CTL_BREAK_m : 0); | 332 | break_state ? RP2_TXRX_CTL_BREAK_m : 0); |
333 | spin_unlock_irqrestore(&port->lock, flags); | 333 | spin_unlock_irqrestore(&port->lock, flags); |
334 | } | 334 | } |
335 | 335 | ||
336 | static void rp2_uart_enable_ms(struct uart_port *port) | 336 | static void rp2_uart_enable_ms(struct uart_port *port) |
337 | { | 337 | { |
338 | rp2_rmw_set(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_MSRIRQ_m); | 338 | rp2_rmw_set(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_MSRIRQ_m); |
339 | } | 339 | } |
340 | 340 | ||
341 | static void __rp2_uart_set_termios(struct rp2_uart_port *up, | 341 | static void __rp2_uart_set_termios(struct rp2_uart_port *up, |
342 | unsigned long cfl, | 342 | unsigned long cfl, |
343 | unsigned long ifl, | 343 | unsigned long ifl, |
344 | unsigned int baud_div) | 344 | unsigned int baud_div) |
345 | { | 345 | { |
346 | /* baud rate divisor (calculated elsewhere). 0 = divide-by-1 */ | 346 | /* baud rate divisor (calculated elsewhere). 0 = divide-by-1 */ |
347 | writew(baud_div - 1, up->base + RP2_BAUD); | 347 | writew(baud_div - 1, up->base + RP2_BAUD); |
348 | 348 | ||
349 | /* data bits and stop bits */ | 349 | /* data bits and stop bits */ |
350 | rp2_rmw(up, RP2_UART_CTL, | 350 | rp2_rmw(up, RP2_UART_CTL, |
351 | RP2_UART_CTL_STOPBITS_m | RP2_UART_CTL_DATABITS_m, | 351 | RP2_UART_CTL_STOPBITS_m | RP2_UART_CTL_DATABITS_m, |
352 | ((cfl & CSTOPB) ? RP2_UART_CTL_STOPBITS_m : 0) | | 352 | ((cfl & CSTOPB) ? RP2_UART_CTL_STOPBITS_m : 0) | |
353 | (((cfl & CSIZE) == CS8) ? RP2_UART_CTL_DATABITS_8 : 0) | | 353 | (((cfl & CSIZE) == CS8) ? RP2_UART_CTL_DATABITS_8 : 0) | |
354 | (((cfl & CSIZE) == CS7) ? RP2_UART_CTL_DATABITS_7 : 0) | | 354 | (((cfl & CSIZE) == CS7) ? RP2_UART_CTL_DATABITS_7 : 0) | |
355 | (((cfl & CSIZE) == CS6) ? RP2_UART_CTL_DATABITS_6 : 0) | | 355 | (((cfl & CSIZE) == CS6) ? RP2_UART_CTL_DATABITS_6 : 0) | |
356 | (((cfl & CSIZE) == CS5) ? RP2_UART_CTL_DATABITS_5 : 0)); | 356 | (((cfl & CSIZE) == CS5) ? RP2_UART_CTL_DATABITS_5 : 0)); |
357 | 357 | ||
358 | /* parity and hardware flow control */ | 358 | /* parity and hardware flow control */ |
359 | rp2_rmw(up, RP2_TXRX_CTL, | 359 | rp2_rmw(up, RP2_TXRX_CTL, |
360 | RP2_TXRX_CTL_PARENB_m | RP2_TXRX_CTL_nPARODD_m | | 360 | RP2_TXRX_CTL_PARENB_m | RP2_TXRX_CTL_nPARODD_m | |
361 | RP2_TXRX_CTL_CMSPAR_m | RP2_TXRX_CTL_DTRFLOW_m | | 361 | RP2_TXRX_CTL_CMSPAR_m | RP2_TXRX_CTL_DTRFLOW_m | |
362 | RP2_TXRX_CTL_DSRFLOW_m | RP2_TXRX_CTL_RTSFLOW_m | | 362 | RP2_TXRX_CTL_DSRFLOW_m | RP2_TXRX_CTL_RTSFLOW_m | |
363 | RP2_TXRX_CTL_CTSFLOW_m, | 363 | RP2_TXRX_CTL_CTSFLOW_m, |
364 | ((cfl & PARENB) ? RP2_TXRX_CTL_PARENB_m : 0) | | 364 | ((cfl & PARENB) ? RP2_TXRX_CTL_PARENB_m : 0) | |
365 | ((cfl & PARODD) ? 0 : RP2_TXRX_CTL_nPARODD_m) | | 365 | ((cfl & PARODD) ? 0 : RP2_TXRX_CTL_nPARODD_m) | |
366 | ((cfl & CMSPAR) ? RP2_TXRX_CTL_CMSPAR_m : 0) | | 366 | ((cfl & CMSPAR) ? RP2_TXRX_CTL_CMSPAR_m : 0) | |
367 | ((cfl & CRTSCTS) ? (RP2_TXRX_CTL_RTSFLOW_m | | 367 | ((cfl & CRTSCTS) ? (RP2_TXRX_CTL_RTSFLOW_m | |
368 | RP2_TXRX_CTL_CTSFLOW_m) : 0)); | 368 | RP2_TXRX_CTL_CTSFLOW_m) : 0)); |
369 | 369 | ||
370 | /* XON/XOFF software flow control */ | 370 | /* XON/XOFF software flow control */ |
371 | writeb((ifl & IXON) ? RP2_TX_SWFLOW_ena : RP2_TX_SWFLOW_dis, | 371 | writeb((ifl & IXON) ? RP2_TX_SWFLOW_ena : RP2_TX_SWFLOW_dis, |
372 | up->ucode + RP2_TX_SWFLOW); | 372 | up->ucode + RP2_TX_SWFLOW); |
373 | writeb((ifl & IXOFF) ? RP2_RX_SWFLOW_ena : RP2_RX_SWFLOW_dis, | 373 | writeb((ifl & IXOFF) ? RP2_RX_SWFLOW_ena : RP2_RX_SWFLOW_dis, |
374 | up->ucode + RP2_RX_SWFLOW); | 374 | up->ucode + RP2_RX_SWFLOW); |
375 | } | 375 | } |
376 | 376 | ||
377 | static void rp2_uart_set_termios(struct uart_port *port, | 377 | static void rp2_uart_set_termios(struct uart_port *port, |
378 | struct ktermios *new, | 378 | struct ktermios *new, |
379 | struct ktermios *old) | 379 | struct ktermios *old) |
380 | { | 380 | { |
381 | struct rp2_uart_port *up = port_to_up(port); | 381 | struct rp2_uart_port *up = port_to_up(port); |
382 | unsigned long flags; | 382 | unsigned long flags; |
383 | unsigned int baud, baud_div; | 383 | unsigned int baud, baud_div; |
384 | 384 | ||
385 | baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16); | 385 | baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16); |
386 | baud_div = uart_get_divisor(port, baud); | 386 | baud_div = uart_get_divisor(port, baud); |
387 | 387 | ||
388 | if (tty_termios_baud_rate(new)) | 388 | if (tty_termios_baud_rate(new)) |
389 | tty_termios_encode_baud_rate(new, baud, baud); | 389 | tty_termios_encode_baud_rate(new, baud, baud); |
390 | 390 | ||
391 | spin_lock_irqsave(&port->lock, flags); | 391 | spin_lock_irqsave(&port->lock, flags); |
392 | 392 | ||
393 | /* ignore all characters if CREAD is not set */ | 393 | /* ignore all characters if CREAD is not set */ |
394 | port->ignore_status_mask = (new->c_cflag & CREAD) ? 0 : RP2_DUMMY_READ; | 394 | port->ignore_status_mask = (new->c_cflag & CREAD) ? 0 : RP2_DUMMY_READ; |
395 | 395 | ||
396 | __rp2_uart_set_termios(up, new->c_cflag, new->c_iflag, baud_div); | 396 | __rp2_uart_set_termios(up, new->c_cflag, new->c_iflag, baud_div); |
397 | uart_update_timeout(port, new->c_cflag, baud); | 397 | uart_update_timeout(port, new->c_cflag, baud); |
398 | 398 | ||
399 | spin_unlock_irqrestore(&port->lock, flags); | 399 | spin_unlock_irqrestore(&port->lock, flags); |
400 | } | 400 | } |
401 | 401 | ||
402 | static void rp2_rx_chars(struct rp2_uart_port *up) | 402 | static void rp2_rx_chars(struct rp2_uart_port *up) |
403 | { | 403 | { |
404 | u16 bytes = readw(up->base + RP2_RX_FIFO_COUNT); | 404 | u16 bytes = readw(up->base + RP2_RX_FIFO_COUNT); |
405 | struct tty_port *port = &up->port.state->port; | 405 | struct tty_port *port = &up->port.state->port; |
406 | 406 | ||
407 | for (; bytes != 0; bytes--) { | 407 | for (; bytes != 0; bytes--) { |
408 | u32 byte = readw(up->base + RP2_DATA_BYTE) | RP2_DUMMY_READ; | 408 | u32 byte = readw(up->base + RP2_DATA_BYTE) | RP2_DUMMY_READ; |
409 | char ch = byte & 0xff; | 409 | char ch = byte & 0xff; |
410 | 410 | ||
411 | if (likely(!(byte & RP2_DATA_BYTE_EXCEPTION_MASK))) { | 411 | if (likely(!(byte & RP2_DATA_BYTE_EXCEPTION_MASK))) { |
412 | if (!uart_handle_sysrq_char(&up->port, ch)) | 412 | if (!uart_handle_sysrq_char(&up->port, ch)) |
413 | uart_insert_char(&up->port, byte, 0, ch, | 413 | uart_insert_char(&up->port, byte, 0, ch, |
414 | TTY_NORMAL); | 414 | TTY_NORMAL); |
415 | } else { | 415 | } else { |
416 | char flag = TTY_NORMAL; | 416 | char flag = TTY_NORMAL; |
417 | 417 | ||
418 | if (byte & RP2_DATA_BYTE_BREAK_m) | 418 | if (byte & RP2_DATA_BYTE_BREAK_m) |
419 | flag = TTY_BREAK; | 419 | flag = TTY_BREAK; |
420 | else if (byte & RP2_DATA_BYTE_ERR_FRAMING_m) | 420 | else if (byte & RP2_DATA_BYTE_ERR_FRAMING_m) |
421 | flag = TTY_FRAME; | 421 | flag = TTY_FRAME; |
422 | else if (byte & RP2_DATA_BYTE_ERR_PARITY_m) | 422 | else if (byte & RP2_DATA_BYTE_ERR_PARITY_m) |
423 | flag = TTY_PARITY; | 423 | flag = TTY_PARITY; |
424 | uart_insert_char(&up->port, byte, | 424 | uart_insert_char(&up->port, byte, |
425 | RP2_DATA_BYTE_ERR_OVERRUN_m, ch, flag); | 425 | RP2_DATA_BYTE_ERR_OVERRUN_m, ch, flag); |
426 | } | 426 | } |
427 | up->port.icount.rx++; | 427 | up->port.icount.rx++; |
428 | } | 428 | } |
429 | 429 | ||
430 | spin_unlock(&up->port.lock); | ||
430 | tty_flip_buffer_push(port); | 431 | tty_flip_buffer_push(port); |
432 | spin_lock(&up->port.lock); | ||
431 | } | 433 | } |
432 | 434 | ||
433 | static void rp2_tx_chars(struct rp2_uart_port *up) | 435 | static void rp2_tx_chars(struct rp2_uart_port *up) |
434 | { | 436 | { |
435 | u16 max_tx = FIFO_SIZE - readw(up->base + RP2_TX_FIFO_COUNT); | 437 | u16 max_tx = FIFO_SIZE - readw(up->base + RP2_TX_FIFO_COUNT); |
436 | struct circ_buf *xmit = &up->port.state->xmit; | 438 | struct circ_buf *xmit = &up->port.state->xmit; |
437 | 439 | ||
438 | if (uart_tx_stopped(&up->port)) { | 440 | if (uart_tx_stopped(&up->port)) { |
439 | rp2_uart_stop_tx(&up->port); | 441 | rp2_uart_stop_tx(&up->port); |
440 | return; | 442 | return; |
441 | } | 443 | } |
442 | 444 | ||
443 | for (; max_tx != 0; max_tx--) { | 445 | for (; max_tx != 0; max_tx--) { |
444 | if (up->port.x_char) { | 446 | if (up->port.x_char) { |
445 | writeb(up->port.x_char, up->base + RP2_DATA_BYTE); | 447 | writeb(up->port.x_char, up->base + RP2_DATA_BYTE); |
446 | up->port.x_char = 0; | 448 | up->port.x_char = 0; |
447 | up->port.icount.tx++; | 449 | up->port.icount.tx++; |
448 | continue; | 450 | continue; |
449 | } | 451 | } |
450 | if (uart_circ_empty(xmit)) { | 452 | if (uart_circ_empty(xmit)) { |
451 | rp2_uart_stop_tx(&up->port); | 453 | rp2_uart_stop_tx(&up->port); |
452 | break; | 454 | break; |
453 | } | 455 | } |
454 | writeb(xmit->buf[xmit->tail], up->base + RP2_DATA_BYTE); | 456 | writeb(xmit->buf[xmit->tail], up->base + RP2_DATA_BYTE); |
455 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | 457 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); |
456 | up->port.icount.tx++; | 458 | up->port.icount.tx++; |
457 | } | 459 | } |
458 | 460 | ||
459 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 461 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
460 | uart_write_wakeup(&up->port); | 462 | uart_write_wakeup(&up->port); |
461 | } | 463 | } |
462 | 464 | ||
463 | static void rp2_ch_interrupt(struct rp2_uart_port *up) | 465 | static void rp2_ch_interrupt(struct rp2_uart_port *up) |
464 | { | 466 | { |
465 | u32 status; | 467 | u32 status; |
466 | 468 | ||
467 | spin_lock(&up->port.lock); | 469 | spin_lock(&up->port.lock); |
468 | 470 | ||
469 | /* | 471 | /* |
470 | * The IRQ status bits are clear-on-write. Other status bits in | 472 | * The IRQ status bits are clear-on-write. Other status bits in |
471 | * this register aren't, so it's harmless to write to them. | 473 | * this register aren't, so it's harmless to write to them. |
472 | */ | 474 | */ |
473 | status = readl(up->base + RP2_CHAN_STAT); | 475 | status = readl(up->base + RP2_CHAN_STAT); |
474 | writel(status, up->base + RP2_CHAN_STAT); | 476 | writel(status, up->base + RP2_CHAN_STAT); |
475 | 477 | ||
476 | if (status & RP2_CHAN_STAT_RXDATA_m) | 478 | if (status & RP2_CHAN_STAT_RXDATA_m) |
477 | rp2_rx_chars(up); | 479 | rp2_rx_chars(up); |
478 | if (status & RP2_CHAN_STAT_TXEMPTY_m) | 480 | if (status & RP2_CHAN_STAT_TXEMPTY_m) |
479 | rp2_tx_chars(up); | 481 | rp2_tx_chars(up); |
480 | if (status & RP2_CHAN_STAT_MS_CHANGED_MASK) | 482 | if (status & RP2_CHAN_STAT_MS_CHANGED_MASK) |
481 | wake_up_interruptible(&up->port.state->port.delta_msr_wait); | 483 | wake_up_interruptible(&up->port.state->port.delta_msr_wait); |
482 | 484 | ||
483 | spin_unlock(&up->port.lock); | 485 | spin_unlock(&up->port.lock); |
484 | } | 486 | } |
485 | 487 | ||
486 | static int rp2_asic_interrupt(struct rp2_card *card, unsigned int asic_id) | 488 | static int rp2_asic_interrupt(struct rp2_card *card, unsigned int asic_id) |
487 | { | 489 | { |
488 | void __iomem *base = card->bar1 + RP2_ASIC_OFFSET(asic_id); | 490 | void __iomem *base = card->bar1 + RP2_ASIC_OFFSET(asic_id); |
489 | int ch, handled = 0; | 491 | int ch, handled = 0; |
490 | unsigned long status = readl(base + RP2_CH_IRQ_STAT) & | 492 | unsigned long status = readl(base + RP2_CH_IRQ_STAT) & |
491 | ~readl(base + RP2_CH_IRQ_MASK); | 493 | ~readl(base + RP2_CH_IRQ_MASK); |
492 | 494 | ||
493 | for_each_set_bit(ch, &status, PORTS_PER_ASIC) { | 495 | for_each_set_bit(ch, &status, PORTS_PER_ASIC) { |
494 | rp2_ch_interrupt(&card->ports[ch]); | 496 | rp2_ch_interrupt(&card->ports[ch]); |
495 | handled++; | 497 | handled++; |
496 | } | 498 | } |
497 | return handled; | 499 | return handled; |
498 | } | 500 | } |
499 | 501 | ||
500 | static irqreturn_t rp2_uart_interrupt(int irq, void *dev_id) | 502 | static irqreturn_t rp2_uart_interrupt(int irq, void *dev_id) |
501 | { | 503 | { |
502 | struct rp2_card *card = dev_id; | 504 | struct rp2_card *card = dev_id; |
503 | int handled; | 505 | int handled; |
504 | 506 | ||
505 | handled = rp2_asic_interrupt(card, 0); | 507 | handled = rp2_asic_interrupt(card, 0); |
506 | if (card->n_ports >= PORTS_PER_ASIC) | 508 | if (card->n_ports >= PORTS_PER_ASIC) |
507 | handled += rp2_asic_interrupt(card, 1); | 509 | handled += rp2_asic_interrupt(card, 1); |
508 | 510 | ||
509 | return handled ? IRQ_HANDLED : IRQ_NONE; | 511 | return handled ? IRQ_HANDLED : IRQ_NONE; |
510 | } | 512 | } |
511 | 513 | ||
512 | static inline void rp2_flush_fifos(struct rp2_uart_port *up) | 514 | static inline void rp2_flush_fifos(struct rp2_uart_port *up) |
513 | { | 515 | { |
514 | rp2_rmw_set(up, RP2_UART_CTL, | 516 | rp2_rmw_set(up, RP2_UART_CTL, |
515 | RP2_UART_CTL_FLUSH_RX_m | RP2_UART_CTL_FLUSH_TX_m); | 517 | RP2_UART_CTL_FLUSH_RX_m | RP2_UART_CTL_FLUSH_TX_m); |
516 | readl(up->base + RP2_UART_CTL); | 518 | readl(up->base + RP2_UART_CTL); |
517 | udelay(10); | 519 | udelay(10); |
518 | rp2_rmw_clr(up, RP2_UART_CTL, | 520 | rp2_rmw_clr(up, RP2_UART_CTL, |
519 | RP2_UART_CTL_FLUSH_RX_m | RP2_UART_CTL_FLUSH_TX_m); | 521 | RP2_UART_CTL_FLUSH_RX_m | RP2_UART_CTL_FLUSH_TX_m); |
520 | } | 522 | } |
521 | 523 | ||
522 | static int rp2_uart_startup(struct uart_port *port) | 524 | static int rp2_uart_startup(struct uart_port *port) |
523 | { | 525 | { |
524 | struct rp2_uart_port *up = port_to_up(port); | 526 | struct rp2_uart_port *up = port_to_up(port); |
525 | 527 | ||
526 | rp2_flush_fifos(up); | 528 | rp2_flush_fifos(up); |
527 | rp2_rmw(up, RP2_TXRX_CTL, RP2_TXRX_CTL_MSRIRQ_m, RP2_TXRX_CTL_RXIRQ_m); | 529 | rp2_rmw(up, RP2_TXRX_CTL, RP2_TXRX_CTL_MSRIRQ_m, RP2_TXRX_CTL_RXIRQ_m); |
528 | rp2_rmw(up, RP2_TXRX_CTL, RP2_TXRX_CTL_RX_TRIG_m, | 530 | rp2_rmw(up, RP2_TXRX_CTL, RP2_TXRX_CTL_RX_TRIG_m, |
529 | RP2_TXRX_CTL_RX_TRIG_1); | 531 | RP2_TXRX_CTL_RX_TRIG_1); |
530 | rp2_rmw(up, RP2_CHAN_STAT, 0, 0); | 532 | rp2_rmw(up, RP2_CHAN_STAT, 0, 0); |
531 | rp2_mask_ch_irq(up, up->idx, 1); | 533 | rp2_mask_ch_irq(up, up->idx, 1); |
532 | 534 | ||
533 | return 0; | 535 | return 0; |
534 | } | 536 | } |
535 | 537 | ||
536 | static void rp2_uart_shutdown(struct uart_port *port) | 538 | static void rp2_uart_shutdown(struct uart_port *port) |
537 | { | 539 | { |
538 | struct rp2_uart_port *up = port_to_up(port); | 540 | struct rp2_uart_port *up = port_to_up(port); |
539 | unsigned long flags; | 541 | unsigned long flags; |
540 | 542 | ||
541 | rp2_uart_break_ctl(port, 0); | 543 | rp2_uart_break_ctl(port, 0); |
542 | 544 | ||
543 | spin_lock_irqsave(&port->lock, flags); | 545 | spin_lock_irqsave(&port->lock, flags); |
544 | rp2_mask_ch_irq(up, up->idx, 0); | 546 | rp2_mask_ch_irq(up, up->idx, 0); |
545 | rp2_rmw(up, RP2_CHAN_STAT, 0, 0); | 547 | rp2_rmw(up, RP2_CHAN_STAT, 0, 0); |
546 | spin_unlock_irqrestore(&port->lock, flags); | 548 | spin_unlock_irqrestore(&port->lock, flags); |
547 | } | 549 | } |
548 | 550 | ||
549 | static const char *rp2_uart_type(struct uart_port *port) | 551 | static const char *rp2_uart_type(struct uart_port *port) |
550 | { | 552 | { |
551 | return (port->type == PORT_RP2) ? "RocketPort 2 UART" : NULL; | 553 | return (port->type == PORT_RP2) ? "RocketPort 2 UART" : NULL; |
552 | } | 554 | } |
553 | 555 | ||
554 | static void rp2_uart_release_port(struct uart_port *port) | 556 | static void rp2_uart_release_port(struct uart_port *port) |
555 | { | 557 | { |
556 | /* Nothing to release ... */ | 558 | /* Nothing to release ... */ |
557 | } | 559 | } |
558 | 560 | ||
559 | static int rp2_uart_request_port(struct uart_port *port) | 561 | static int rp2_uart_request_port(struct uart_port *port) |
560 | { | 562 | { |
561 | /* UARTs always present */ | 563 | /* UARTs always present */ |
562 | return 0; | 564 | return 0; |
563 | } | 565 | } |
564 | 566 | ||
565 | static void rp2_uart_config_port(struct uart_port *port, int flags) | 567 | static void rp2_uart_config_port(struct uart_port *port, int flags) |
566 | { | 568 | { |
567 | if (flags & UART_CONFIG_TYPE) | 569 | if (flags & UART_CONFIG_TYPE) |
568 | port->type = PORT_RP2; | 570 | port->type = PORT_RP2; |
569 | } | 571 | } |
570 | 572 | ||
571 | static int rp2_uart_verify_port(struct uart_port *port, | 573 | static int rp2_uart_verify_port(struct uart_port *port, |
572 | struct serial_struct *ser) | 574 | struct serial_struct *ser) |
573 | { | 575 | { |
574 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_RP2) | 576 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_RP2) |
575 | return -EINVAL; | 577 | return -EINVAL; |
576 | 578 | ||
577 | return 0; | 579 | return 0; |
578 | } | 580 | } |
579 | 581 | ||
580 | static const struct uart_ops rp2_uart_ops = { | 582 | static const struct uart_ops rp2_uart_ops = { |
581 | .tx_empty = rp2_uart_tx_empty, | 583 | .tx_empty = rp2_uart_tx_empty, |
582 | .set_mctrl = rp2_uart_set_mctrl, | 584 | .set_mctrl = rp2_uart_set_mctrl, |
583 | .get_mctrl = rp2_uart_get_mctrl, | 585 | .get_mctrl = rp2_uart_get_mctrl, |
584 | .stop_tx = rp2_uart_stop_tx, | 586 | .stop_tx = rp2_uart_stop_tx, |
585 | .start_tx = rp2_uart_start_tx, | 587 | .start_tx = rp2_uart_start_tx, |
586 | .stop_rx = rp2_uart_stop_rx, | 588 | .stop_rx = rp2_uart_stop_rx, |
587 | .enable_ms = rp2_uart_enable_ms, | 589 | .enable_ms = rp2_uart_enable_ms, |
588 | .break_ctl = rp2_uart_break_ctl, | 590 | .break_ctl = rp2_uart_break_ctl, |
589 | .startup = rp2_uart_startup, | 591 | .startup = rp2_uart_startup, |
590 | .shutdown = rp2_uart_shutdown, | 592 | .shutdown = rp2_uart_shutdown, |
591 | .set_termios = rp2_uart_set_termios, | 593 | .set_termios = rp2_uart_set_termios, |
592 | .type = rp2_uart_type, | 594 | .type = rp2_uart_type, |
593 | .release_port = rp2_uart_release_port, | 595 | .release_port = rp2_uart_release_port, |
594 | .request_port = rp2_uart_request_port, | 596 | .request_port = rp2_uart_request_port, |
595 | .config_port = rp2_uart_config_port, | 597 | .config_port = rp2_uart_config_port, |
596 | .verify_port = rp2_uart_verify_port, | 598 | .verify_port = rp2_uart_verify_port, |
597 | }; | 599 | }; |
598 | 600 | ||
599 | static void rp2_reset_asic(struct rp2_card *card, unsigned int asic_id) | 601 | static void rp2_reset_asic(struct rp2_card *card, unsigned int asic_id) |
600 | { | 602 | { |
601 | void __iomem *base = card->bar1 + RP2_ASIC_OFFSET(asic_id); | 603 | void __iomem *base = card->bar1 + RP2_ASIC_OFFSET(asic_id); |
602 | u32 clk_cfg; | 604 | u32 clk_cfg; |
603 | 605 | ||
604 | writew(1, base + RP2_GLOBAL_CMD); | 606 | writew(1, base + RP2_GLOBAL_CMD); |
605 | readw(base + RP2_GLOBAL_CMD); | 607 | readw(base + RP2_GLOBAL_CMD); |
606 | msleep(100); | 608 | msleep(100); |
607 | writel(0, base + RP2_CLK_PRESCALER); | 609 | writel(0, base + RP2_CLK_PRESCALER); |
608 | 610 | ||
609 | /* TDM clock configuration */ | 611 | /* TDM clock configuration */ |
610 | clk_cfg = readw(base + RP2_ASIC_CFG); | 612 | clk_cfg = readw(base + RP2_ASIC_CFG); |
611 | clk_cfg = (clk_cfg & ~BIT(8)) | BIT(9); | 613 | clk_cfg = (clk_cfg & ~BIT(8)) | BIT(9); |
612 | writew(clk_cfg, base + RP2_ASIC_CFG); | 614 | writew(clk_cfg, base + RP2_ASIC_CFG); |
613 | 615 | ||
614 | /* IRQ routing */ | 616 | /* IRQ routing */ |
615 | writel(ALL_PORTS_MASK, base + RP2_CH_IRQ_MASK); | 617 | writel(ALL_PORTS_MASK, base + RP2_CH_IRQ_MASK); |
616 | writel(RP2_ASIC_IRQ_EN_m, base + RP2_ASIC_IRQ); | 618 | writel(RP2_ASIC_IRQ_EN_m, base + RP2_ASIC_IRQ); |
617 | } | 619 | } |
618 | 620 | ||
619 | static void rp2_init_card(struct rp2_card *card) | 621 | static void rp2_init_card(struct rp2_card *card) |
620 | { | 622 | { |
621 | writel(4, card->bar0 + RP2_FPGA_CTL0); | 623 | writel(4, card->bar0 + RP2_FPGA_CTL0); |
622 | writel(0, card->bar0 + RP2_FPGA_CTL1); | 624 | writel(0, card->bar0 + RP2_FPGA_CTL1); |
623 | 625 | ||
624 | rp2_reset_asic(card, 0); | 626 | rp2_reset_asic(card, 0); |
625 | if (card->n_ports >= PORTS_PER_ASIC) | 627 | if (card->n_ports >= PORTS_PER_ASIC) |
626 | rp2_reset_asic(card, 1); | 628 | rp2_reset_asic(card, 1); |
627 | 629 | ||
628 | writel(RP2_IRQ_MASK_EN_m, card->bar0 + RP2_IRQ_MASK); | 630 | writel(RP2_IRQ_MASK_EN_m, card->bar0 + RP2_IRQ_MASK); |
629 | } | 631 | } |
630 | 632 | ||
631 | static void rp2_init_port(struct rp2_uart_port *up, const struct firmware *fw) | 633 | static void rp2_init_port(struct rp2_uart_port *up, const struct firmware *fw) |
632 | { | 634 | { |
633 | int i; | 635 | int i; |
634 | 636 | ||
635 | writel(RP2_UART_CTL_RESET_CH_m, up->base + RP2_UART_CTL); | 637 | writel(RP2_UART_CTL_RESET_CH_m, up->base + RP2_UART_CTL); |
636 | readl(up->base + RP2_UART_CTL); | 638 | readl(up->base + RP2_UART_CTL); |
637 | udelay(1); | 639 | udelay(1); |
638 | 640 | ||
639 | writel(0, up->base + RP2_TXRX_CTL); | 641 | writel(0, up->base + RP2_TXRX_CTL); |
640 | writel(0, up->base + RP2_UART_CTL); | 642 | writel(0, up->base + RP2_UART_CTL); |
641 | readl(up->base + RP2_UART_CTL); | 643 | readl(up->base + RP2_UART_CTL); |
642 | udelay(1); | 644 | udelay(1); |
643 | 645 | ||
644 | rp2_flush_fifos(up); | 646 | rp2_flush_fifos(up); |
645 | 647 | ||
646 | for (i = 0; i < min_t(int, fw->size, RP2_UCODE_BYTES); i++) | 648 | for (i = 0; i < min_t(int, fw->size, RP2_UCODE_BYTES); i++) |
647 | writeb(fw->data[i], up->ucode + i); | 649 | writeb(fw->data[i], up->ucode + i); |
648 | 650 | ||
649 | __rp2_uart_set_termios(up, CS8 | CREAD | CLOCAL, 0, DEFAULT_BAUD_DIV); | 651 | __rp2_uart_set_termios(up, CS8 | CREAD | CLOCAL, 0, DEFAULT_BAUD_DIV); |
650 | rp2_uart_set_mctrl(&up->port, 0); | 652 | rp2_uart_set_mctrl(&up->port, 0); |
651 | 653 | ||
652 | writeb(RP2_RX_FIFO_ena, up->ucode + RP2_RX_FIFO); | 654 | writeb(RP2_RX_FIFO_ena, up->ucode + RP2_RX_FIFO); |
653 | rp2_rmw(up, RP2_UART_CTL, RP2_UART_CTL_MODE_m, | 655 | rp2_rmw(up, RP2_UART_CTL, RP2_UART_CTL_MODE_m, |
654 | RP2_UART_CTL_XMIT_EN_m | RP2_UART_CTL_MODE_rs232); | 656 | RP2_UART_CTL_XMIT_EN_m | RP2_UART_CTL_MODE_rs232); |
655 | rp2_rmw_set(up, RP2_TXRX_CTL, | 657 | rp2_rmw_set(up, RP2_TXRX_CTL, |
656 | RP2_TXRX_CTL_TX_EN_m | RP2_TXRX_CTL_RX_EN_m); | 658 | RP2_TXRX_CTL_TX_EN_m | RP2_TXRX_CTL_RX_EN_m); |
657 | } | 659 | } |
658 | 660 | ||
659 | static void rp2_remove_ports(struct rp2_card *card) | 661 | static void rp2_remove_ports(struct rp2_card *card) |
660 | { | 662 | { |
661 | int i; | 663 | int i; |
662 | 664 | ||
663 | for (i = 0; i < card->initialized_ports; i++) | 665 | for (i = 0; i < card->initialized_ports; i++) |
664 | uart_remove_one_port(&rp2_uart_driver, &card->ports[i].port); | 666 | uart_remove_one_port(&rp2_uart_driver, &card->ports[i].port); |
665 | card->initialized_ports = 0; | 667 | card->initialized_ports = 0; |
666 | } | 668 | } |
667 | 669 | ||
668 | static void rp2_fw_cb(const struct firmware *fw, void *context) | 670 | static void rp2_fw_cb(const struct firmware *fw, void *context) |
669 | { | 671 | { |
670 | struct rp2_card *card = context; | 672 | struct rp2_card *card = context; |
671 | resource_size_t phys_base; | 673 | resource_size_t phys_base; |
672 | int i, rc = -ENOENT; | 674 | int i, rc = -ENOENT; |
673 | 675 | ||
674 | if (!fw) { | 676 | if (!fw) { |
675 | dev_err(&card->pdev->dev, "cannot find '%s' firmware image\n", | 677 | dev_err(&card->pdev->dev, "cannot find '%s' firmware image\n", |
676 | RP2_FW_NAME); | 678 | RP2_FW_NAME); |
677 | goto no_fw; | 679 | goto no_fw; |
678 | } | 680 | } |
679 | 681 | ||
680 | phys_base = pci_resource_start(card->pdev, 1); | 682 | phys_base = pci_resource_start(card->pdev, 1); |
681 | 683 | ||
682 | for (i = 0; i < card->n_ports; i++) { | 684 | for (i = 0; i < card->n_ports; i++) { |
683 | struct rp2_uart_port *rp = &card->ports[i]; | 685 | struct rp2_uart_port *rp = &card->ports[i]; |
684 | struct uart_port *p; | 686 | struct uart_port *p; |
685 | int j = (unsigned)i % PORTS_PER_ASIC; | 687 | int j = (unsigned)i % PORTS_PER_ASIC; |
686 | 688 | ||
687 | rp->asic_base = card->bar1; | 689 | rp->asic_base = card->bar1; |
688 | rp->base = card->bar1 + RP2_PORT_BASE + j*RP2_PORT_SPACING; | 690 | rp->base = card->bar1 + RP2_PORT_BASE + j*RP2_PORT_SPACING; |
689 | rp->ucode = card->bar1 + RP2_UCODE_BASE + j*RP2_UCODE_SPACING; | 691 | rp->ucode = card->bar1 + RP2_UCODE_BASE + j*RP2_UCODE_SPACING; |
690 | rp->card = card; | 692 | rp->card = card; |
691 | rp->idx = j; | 693 | rp->idx = j; |
692 | 694 | ||
693 | p = &rp->port; | 695 | p = &rp->port; |
694 | p->line = card->minor_start + i; | 696 | p->line = card->minor_start + i; |
695 | p->dev = &card->pdev->dev; | 697 | p->dev = &card->pdev->dev; |
696 | p->type = PORT_RP2; | 698 | p->type = PORT_RP2; |
697 | p->iotype = UPIO_MEM32; | 699 | p->iotype = UPIO_MEM32; |
698 | p->uartclk = UART_CLOCK; | 700 | p->uartclk = UART_CLOCK; |
699 | p->regshift = 2; | 701 | p->regshift = 2; |
700 | p->fifosize = FIFO_SIZE; | 702 | p->fifosize = FIFO_SIZE; |
701 | p->ops = &rp2_uart_ops; | 703 | p->ops = &rp2_uart_ops; |
702 | p->irq = card->pdev->irq; | 704 | p->irq = card->pdev->irq; |
703 | p->membase = rp->base; | 705 | p->membase = rp->base; |
704 | p->mapbase = phys_base + RP2_PORT_BASE + j*RP2_PORT_SPACING; | 706 | p->mapbase = phys_base + RP2_PORT_BASE + j*RP2_PORT_SPACING; |
705 | 707 | ||
706 | if (i >= PORTS_PER_ASIC) { | 708 | if (i >= PORTS_PER_ASIC) { |
707 | rp->asic_base += RP2_ASIC_SPACING; | 709 | rp->asic_base += RP2_ASIC_SPACING; |
708 | rp->base += RP2_ASIC_SPACING; | 710 | rp->base += RP2_ASIC_SPACING; |
709 | rp->ucode += RP2_ASIC_SPACING; | 711 | rp->ucode += RP2_ASIC_SPACING; |
710 | p->mapbase += RP2_ASIC_SPACING; | 712 | p->mapbase += RP2_ASIC_SPACING; |
711 | } | 713 | } |
712 | 714 | ||
713 | rp2_init_port(rp, fw); | 715 | rp2_init_port(rp, fw); |
714 | rc = uart_add_one_port(&rp2_uart_driver, p); | 716 | rc = uart_add_one_port(&rp2_uart_driver, p); |
715 | if (rc) { | 717 | if (rc) { |
716 | dev_err(&card->pdev->dev, | 718 | dev_err(&card->pdev->dev, |
717 | "error registering port %d: %d\n", i, rc); | 719 | "error registering port %d: %d\n", i, rc); |
718 | rp2_remove_ports(card); | 720 | rp2_remove_ports(card); |
719 | break; | 721 | break; |
720 | } | 722 | } |
721 | card->initialized_ports++; | 723 | card->initialized_ports++; |
722 | } | 724 | } |
723 | 725 | ||
724 | release_firmware(fw); | 726 | release_firmware(fw); |
725 | no_fw: | 727 | no_fw: |
726 | /* | 728 | /* |
727 | * rp2_fw_cb() is called from a workqueue long after rp2_probe() | 729 | * rp2_fw_cb() is called from a workqueue long after rp2_probe() |
728 | * has already returned success. So if something failed here, | 730 | * has already returned success. So if something failed here, |
729 | * we'll just leave the now-dormant device in place until somebody | 731 | * we'll just leave the now-dormant device in place until somebody |
730 | * unbinds it. | 732 | * unbinds it. |
731 | */ | 733 | */ |
732 | if (rc) | 734 | if (rc) |
733 | dev_warn(&card->pdev->dev, "driver initialization failed\n"); | 735 | dev_warn(&card->pdev->dev, "driver initialization failed\n"); |
734 | 736 | ||
735 | complete(&card->fw_loaded); | 737 | complete(&card->fw_loaded); |
736 | } | 738 | } |
737 | 739 | ||
738 | static int rp2_probe(struct pci_dev *pdev, | 740 | static int rp2_probe(struct pci_dev *pdev, |
739 | const struct pci_device_id *id) | 741 | const struct pci_device_id *id) |
740 | { | 742 | { |
741 | struct rp2_card *card; | 743 | struct rp2_card *card; |
742 | struct rp2_uart_port *ports; | 744 | struct rp2_uart_port *ports; |
743 | void __iomem * const *bars; | 745 | void __iomem * const *bars; |
744 | int rc; | 746 | int rc; |
745 | 747 | ||
746 | card = devm_kzalloc(&pdev->dev, sizeof(*card), GFP_KERNEL); | 748 | card = devm_kzalloc(&pdev->dev, sizeof(*card), GFP_KERNEL); |
747 | if (!card) | 749 | if (!card) |
748 | return -ENOMEM; | 750 | return -ENOMEM; |
749 | pci_set_drvdata(pdev, card); | 751 | pci_set_drvdata(pdev, card); |
750 | spin_lock_init(&card->card_lock); | 752 | spin_lock_init(&card->card_lock); |
751 | init_completion(&card->fw_loaded); | 753 | init_completion(&card->fw_loaded); |
752 | 754 | ||
753 | rc = pcim_enable_device(pdev); | 755 | rc = pcim_enable_device(pdev); |
754 | if (rc) | 756 | if (rc) |
755 | return rc; | 757 | return rc; |
756 | 758 | ||
757 | rc = pcim_iomap_regions_request_all(pdev, 0x03, DRV_NAME); | 759 | rc = pcim_iomap_regions_request_all(pdev, 0x03, DRV_NAME); |
758 | if (rc) | 760 | if (rc) |
759 | return rc; | 761 | return rc; |
760 | 762 | ||
761 | bars = pcim_iomap_table(pdev); | 763 | bars = pcim_iomap_table(pdev); |
762 | card->bar0 = bars[0]; | 764 | card->bar0 = bars[0]; |
763 | card->bar1 = bars[1]; | 765 | card->bar1 = bars[1]; |
764 | card->pdev = pdev; | 766 | card->pdev = pdev; |
765 | 767 | ||
766 | rp2_decode_cap(id, &card->n_ports, &card->smpte); | 768 | rp2_decode_cap(id, &card->n_ports, &card->smpte); |
767 | dev_info(&pdev->dev, "found new card with %d ports\n", card->n_ports); | 769 | dev_info(&pdev->dev, "found new card with %d ports\n", card->n_ports); |
768 | 770 | ||
769 | card->minor_start = rp2_alloc_ports(card->n_ports); | 771 | card->minor_start = rp2_alloc_ports(card->n_ports); |
770 | if (card->minor_start < 0) { | 772 | if (card->minor_start < 0) { |
771 | dev_err(&pdev->dev, | 773 | dev_err(&pdev->dev, |
772 | "too many ports (try increasing CONFIG_SERIAL_RP2_NR_UARTS)\n"); | 774 | "too many ports (try increasing CONFIG_SERIAL_RP2_NR_UARTS)\n"); |
773 | return -EINVAL; | 775 | return -EINVAL; |
774 | } | 776 | } |
775 | 777 | ||
776 | rp2_init_card(card); | 778 | rp2_init_card(card); |
777 | 779 | ||
778 | ports = devm_kzalloc(&pdev->dev, sizeof(*ports) * card->n_ports, | 780 | ports = devm_kzalloc(&pdev->dev, sizeof(*ports) * card->n_ports, |
779 | GFP_KERNEL); | 781 | GFP_KERNEL); |
780 | if (!ports) | 782 | if (!ports) |
781 | return -ENOMEM; | 783 | return -ENOMEM; |
782 | card->ports = ports; | 784 | card->ports = ports; |
783 | 785 | ||
784 | rc = devm_request_irq(&pdev->dev, pdev->irq, rp2_uart_interrupt, | 786 | rc = devm_request_irq(&pdev->dev, pdev->irq, rp2_uart_interrupt, |
785 | IRQF_SHARED, DRV_NAME, card); | 787 | IRQF_SHARED, DRV_NAME, card); |
786 | if (rc) | 788 | if (rc) |
787 | return rc; | 789 | return rc; |
788 | 790 | ||
789 | /* | 791 | /* |
790 | * Only catastrophic errors (e.g. ENOMEM) are reported here. | 792 | * Only catastrophic errors (e.g. ENOMEM) are reported here. |
791 | * If the FW image is missing, we'll find out in rp2_fw_cb() | 793 | * If the FW image is missing, we'll find out in rp2_fw_cb() |
792 | * and print an error message. | 794 | * and print an error message. |
793 | */ | 795 | */ |
794 | rc = request_firmware_nowait(THIS_MODULE, 1, RP2_FW_NAME, &pdev->dev, | 796 | rc = request_firmware_nowait(THIS_MODULE, 1, RP2_FW_NAME, &pdev->dev, |
795 | GFP_KERNEL, card, rp2_fw_cb); | 797 | GFP_KERNEL, card, rp2_fw_cb); |
796 | if (rc) | 798 | if (rc) |
797 | return rc; | 799 | return rc; |
798 | dev_dbg(&pdev->dev, "waiting for firmware blob...\n"); | 800 | dev_dbg(&pdev->dev, "waiting for firmware blob...\n"); |
799 | 801 | ||
800 | return 0; | 802 | return 0; |
801 | } | 803 | } |
802 | 804 | ||
803 | static void rp2_remove(struct pci_dev *pdev) | 805 | static void rp2_remove(struct pci_dev *pdev) |
804 | { | 806 | { |
805 | struct rp2_card *card = pci_get_drvdata(pdev); | 807 | struct rp2_card *card = pci_get_drvdata(pdev); |
806 | 808 | ||
807 | wait_for_completion(&card->fw_loaded); | 809 | wait_for_completion(&card->fw_loaded); |
808 | rp2_remove_ports(card); | 810 | rp2_remove_ports(card); |
809 | } | 811 | } |
810 | 812 | ||
811 | static DEFINE_PCI_DEVICE_TABLE(rp2_pci_tbl) = { | 813 | static DEFINE_PCI_DEVICE_TABLE(rp2_pci_tbl) = { |
812 | 814 | ||
813 | /* RocketPort INFINITY cards */ | 815 | /* RocketPort INFINITY cards */ |
814 | 816 | ||
815 | { RP_ID(0x0040), RP_CAP(8, 0) }, /* INF Octa, RJ45, selectable */ | 817 | { RP_ID(0x0040), RP_CAP(8, 0) }, /* INF Octa, RJ45, selectable */ |
816 | { RP_ID(0x0041), RP_CAP(32, 0) }, /* INF 32, ext interface */ | 818 | { RP_ID(0x0041), RP_CAP(32, 0) }, /* INF 32, ext interface */ |
817 | { RP_ID(0x0042), RP_CAP(8, 0) }, /* INF Octa, ext interface */ | 819 | { RP_ID(0x0042), RP_CAP(8, 0) }, /* INF Octa, ext interface */ |
818 | { RP_ID(0x0043), RP_CAP(16, 0) }, /* INF 16, ext interface */ | 820 | { RP_ID(0x0043), RP_CAP(16, 0) }, /* INF 16, ext interface */ |
819 | { RP_ID(0x0044), RP_CAP(4, 0) }, /* INF Quad, DB, selectable */ | 821 | { RP_ID(0x0044), RP_CAP(4, 0) }, /* INF Quad, DB, selectable */ |
820 | { RP_ID(0x0045), RP_CAP(8, 0) }, /* INF Octa, DB, selectable */ | 822 | { RP_ID(0x0045), RP_CAP(8, 0) }, /* INF Octa, DB, selectable */ |
821 | { RP_ID(0x0046), RP_CAP(4, 0) }, /* INF Quad, ext interface */ | 823 | { RP_ID(0x0046), RP_CAP(4, 0) }, /* INF Quad, ext interface */ |
822 | { RP_ID(0x0047), RP_CAP(4, 0) }, /* INF Quad, RJ45 */ | 824 | { RP_ID(0x0047), RP_CAP(4, 0) }, /* INF Quad, RJ45 */ |
823 | { RP_ID(0x004a), RP_CAP(4, 0) }, /* INF Plus, Quad */ | 825 | { RP_ID(0x004a), RP_CAP(4, 0) }, /* INF Plus, Quad */ |
824 | { RP_ID(0x004b), RP_CAP(8, 0) }, /* INF Plus, Octa */ | 826 | { RP_ID(0x004b), RP_CAP(8, 0) }, /* INF Plus, Octa */ |
825 | { RP_ID(0x004c), RP_CAP(8, 0) }, /* INF III, Octa */ | 827 | { RP_ID(0x004c), RP_CAP(8, 0) }, /* INF III, Octa */ |
826 | { RP_ID(0x004d), RP_CAP(4, 0) }, /* INF III, Quad */ | 828 | { RP_ID(0x004d), RP_CAP(4, 0) }, /* INF III, Quad */ |
827 | { RP_ID(0x004e), RP_CAP(2, 0) }, /* INF Plus, 2, RS232 */ | 829 | { RP_ID(0x004e), RP_CAP(2, 0) }, /* INF Plus, 2, RS232 */ |
828 | { RP_ID(0x004f), RP_CAP(2, 1) }, /* INF Plus, 2, SMPTE */ | 830 | { RP_ID(0x004f), RP_CAP(2, 1) }, /* INF Plus, 2, SMPTE */ |
829 | { RP_ID(0x0050), RP_CAP(4, 0) }, /* INF Plus, Quad, RJ45 */ | 831 | { RP_ID(0x0050), RP_CAP(4, 0) }, /* INF Plus, Quad, RJ45 */ |
830 | { RP_ID(0x0051), RP_CAP(8, 0) }, /* INF Plus, Octa, RJ45 */ | 832 | { RP_ID(0x0051), RP_CAP(8, 0) }, /* INF Plus, Octa, RJ45 */ |
831 | { RP_ID(0x0052), RP_CAP(8, 1) }, /* INF Octa, SMPTE */ | 833 | { RP_ID(0x0052), RP_CAP(8, 1) }, /* INF Octa, SMPTE */ |
832 | 834 | ||
833 | /* RocketPort EXPRESS cards */ | 835 | /* RocketPort EXPRESS cards */ |
834 | 836 | ||
835 | { RP_ID(0x0060), RP_CAP(8, 0) }, /* EXP Octa, RJ45, selectable */ | 837 | { RP_ID(0x0060), RP_CAP(8, 0) }, /* EXP Octa, RJ45, selectable */ |
836 | { RP_ID(0x0061), RP_CAP(32, 0) }, /* EXP 32, ext interface */ | 838 | { RP_ID(0x0061), RP_CAP(32, 0) }, /* EXP 32, ext interface */ |
837 | { RP_ID(0x0062), RP_CAP(8, 0) }, /* EXP Octa, ext interface */ | 839 | { RP_ID(0x0062), RP_CAP(8, 0) }, /* EXP Octa, ext interface */ |
838 | { RP_ID(0x0063), RP_CAP(16, 0) }, /* EXP 16, ext interface */ | 840 | { RP_ID(0x0063), RP_CAP(16, 0) }, /* EXP 16, ext interface */ |
839 | { RP_ID(0x0064), RP_CAP(4, 0) }, /* EXP Quad, DB, selectable */ | 841 | { RP_ID(0x0064), RP_CAP(4, 0) }, /* EXP Quad, DB, selectable */ |
840 | { RP_ID(0x0065), RP_CAP(8, 0) }, /* EXP Octa, DB, selectable */ | 842 | { RP_ID(0x0065), RP_CAP(8, 0) }, /* EXP Octa, DB, selectable */ |
841 | { RP_ID(0x0066), RP_CAP(4, 0) }, /* EXP Quad, ext interface */ | 843 | { RP_ID(0x0066), RP_CAP(4, 0) }, /* EXP Quad, ext interface */ |
842 | { RP_ID(0x0067), RP_CAP(4, 0) }, /* EXP Quad, RJ45 */ | 844 | { RP_ID(0x0067), RP_CAP(4, 0) }, /* EXP Quad, RJ45 */ |
843 | { RP_ID(0x0068), RP_CAP(8, 0) }, /* EXP Octa, RJ11 */ | 845 | { RP_ID(0x0068), RP_CAP(8, 0) }, /* EXP Octa, RJ11 */ |
844 | { RP_ID(0x0072), RP_CAP(8, 1) }, /* EXP Octa, SMPTE */ | 846 | { RP_ID(0x0072), RP_CAP(8, 1) }, /* EXP Octa, SMPTE */ |
845 | { } | 847 | { } |
846 | }; | 848 | }; |
847 | MODULE_DEVICE_TABLE(pci, rp2_pci_tbl); | 849 | MODULE_DEVICE_TABLE(pci, rp2_pci_tbl); |
848 | 850 | ||
849 | static struct pci_driver rp2_pci_driver = { | 851 | static struct pci_driver rp2_pci_driver = { |
850 | .name = DRV_NAME, | 852 | .name = DRV_NAME, |
851 | .id_table = rp2_pci_tbl, | 853 | .id_table = rp2_pci_tbl, |
852 | .probe = rp2_probe, | 854 | .probe = rp2_probe, |
853 | .remove = rp2_remove, | 855 | .remove = rp2_remove, |
854 | }; | 856 | }; |
855 | 857 | ||
856 | static int __init rp2_uart_init(void) | 858 | static int __init rp2_uart_init(void) |
857 | { | 859 | { |
858 | int rc; | 860 | int rc; |
859 | 861 | ||
860 | rc = uart_register_driver(&rp2_uart_driver); | 862 | rc = uart_register_driver(&rp2_uart_driver); |
861 | if (rc) | 863 | if (rc) |
862 | return rc; | 864 | return rc; |
863 | 865 | ||
864 | rc = pci_register_driver(&rp2_pci_driver); | 866 | rc = pci_register_driver(&rp2_pci_driver); |
865 | if (rc) { | 867 | if (rc) { |
866 | uart_unregister_driver(&rp2_uart_driver); | 868 | uart_unregister_driver(&rp2_uart_driver); |
867 | return rc; | 869 | return rc; |
868 | } | 870 | } |
869 | 871 | ||
870 | return 0; | 872 | return 0; |
871 | } | 873 | } |
872 | 874 | ||
873 | static void __exit rp2_uart_exit(void) | 875 | static void __exit rp2_uart_exit(void) |
874 | { | 876 | { |
875 | pci_unregister_driver(&rp2_pci_driver); | 877 | pci_unregister_driver(&rp2_pci_driver); |
876 | uart_unregister_driver(&rp2_uart_driver); | 878 | uart_unregister_driver(&rp2_uart_driver); |
877 | } | 879 | } |
878 | 880 | ||
879 | module_init(rp2_uart_init); | 881 | module_init(rp2_uart_init); |
880 | module_exit(rp2_uart_exit); | 882 | module_exit(rp2_uart_exit); |
881 | 883 | ||
882 | MODULE_DESCRIPTION("Comtrol RocketPort EXPRESS/INFINITY driver"); | 884 | MODULE_DESCRIPTION("Comtrol RocketPort EXPRESS/INFINITY driver"); |
883 | MODULE_AUTHOR("Kevin Cernekee <cernekee@gmail.com>"); | 885 | MODULE_AUTHOR("Kevin Cernekee <cernekee@gmail.com>"); |
884 | MODULE_LICENSE("GPL v2"); | 886 | MODULE_LICENSE("GPL v2"); |
885 | MODULE_FIRMWARE(RP2_FW_NAME); | 887 | MODULE_FIRMWARE(RP2_FW_NAME); |
886 | 888 |