diff options
-rw-r--r-- | drivers/tty/Kconfig | 18 | ||||
-rw-r--r-- | drivers/tty/Makefile | 1 | ||||
-rw-r--r-- | drivers/tty/mips_ejtag_fdc.c | 1126 |
3 files changed, 1145 insertions, 0 deletions
diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig index b24aa010f68c..39469ca4231c 100644 --- a/drivers/tty/Kconfig +++ b/drivers/tty/Kconfig | |||
@@ -419,4 +419,22 @@ config DA_CONSOLE | |||
419 | help | 419 | help |
420 | This enables a console on a Dash channel. | 420 | This enables a console on a Dash channel. |
421 | 421 | ||
422 | config MIPS_EJTAG_FDC_TTY | ||
423 | bool "MIPS EJTAG Fast Debug Channel TTY" | ||
424 | depends on MIPS_CDMM | ||
425 | help | ||
426 | This enables a TTY and console on the MIPS EJTAG Fast Debug Channels, | ||
427 | if they are present. This can be useful when working with an EJTAG | ||
428 | probe which supports it, to get console output and a login prompt via | ||
429 | EJTAG without needing to connect a serial cable. | ||
430 | |||
431 | TTY devices are named e.g. ttyFDC3c2 (for FDC channel 2 of the FDC on | ||
432 | CPU3). | ||
433 | |||
434 | The console can be enabled with console=fdc1 (for FDC channel 1 on all | ||
435 | CPUs). Do not use the console unless there is a debug probe attached | ||
436 | to drain the FDC TX FIFO. | ||
437 | |||
438 | If unsure, say N. | ||
439 | |||
422 | endif # TTY | 440 | endif # TTY |
diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile index 58ad1c05b7f8..5817e2397463 100644 --- a/drivers/tty/Makefile +++ b/drivers/tty/Makefile | |||
@@ -29,5 +29,6 @@ obj-$(CONFIG_SYNCLINK) += synclink.o | |||
29 | obj-$(CONFIG_PPC_EPAPR_HV_BYTECHAN) += ehv_bytechan.o | 29 | obj-$(CONFIG_PPC_EPAPR_HV_BYTECHAN) += ehv_bytechan.o |
30 | obj-$(CONFIG_GOLDFISH_TTY) += goldfish.o | 30 | obj-$(CONFIG_GOLDFISH_TTY) += goldfish.o |
31 | obj-$(CONFIG_DA_TTY) += metag_da.o | 31 | obj-$(CONFIG_DA_TTY) += metag_da.o |
32 | obj-$(CONFIG_MIPS_EJTAG_FDC_TTY) += mips_ejtag_fdc.o | ||
32 | 33 | ||
33 | obj-y += ipwireless/ | 34 | obj-y += ipwireless/ |
diff --git a/drivers/tty/mips_ejtag_fdc.c b/drivers/tty/mips_ejtag_fdc.c new file mode 100644 index 000000000000..51672cfe7e45 --- /dev/null +++ b/drivers/tty/mips_ejtag_fdc.c | |||
@@ -0,0 +1,1126 @@ | |||
1 | /* | ||
2 | * TTY driver for MIPS EJTAG Fast Debug Channels. | ||
3 | * | ||
4 | * Copyright (C) 2007-2015 Imagination Technologies Ltd | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file COPYING in the main directory of this archive for more | ||
8 | * details. | ||
9 | */ | ||
10 | |||
11 | #include <linux/atomic.h> | ||
12 | #include <linux/bitops.h> | ||
13 | #include <linux/completion.h> | ||
14 | #include <linux/console.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/export.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/kthread.h> | ||
21 | #include <linux/sched.h> | ||
22 | #include <linux/serial.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/spinlock.h> | ||
25 | #include <linux/string.h> | ||
26 | #include <linux/timer.h> | ||
27 | #include <linux/tty.h> | ||
28 | #include <linux/tty_driver.h> | ||
29 | #include <linux/tty_flip.h> | ||
30 | #include <linux/uaccess.h> | ||
31 | |||
32 | #include <asm/cdmm.h> | ||
33 | #include <asm/irq.h> | ||
34 | |||
35 | /* Register offsets */ | ||
36 | #define REG_FDACSR 0x00 /* FDC Access Control and Status Register */ | ||
37 | #define REG_FDCFG 0x08 /* FDC Configuration Register */ | ||
38 | #define REG_FDSTAT 0x10 /* FDC Status Register */ | ||
39 | #define REG_FDRX 0x18 /* FDC Receive Register */ | ||
40 | #define REG_FDTX(N) (0x20+0x8*(N)) /* FDC Transmit Register n (0..15) */ | ||
41 | |||
42 | /* Register fields */ | ||
43 | |||
44 | #define REG_FDCFG_TXINTTHRES_SHIFT 18 | ||
45 | #define REG_FDCFG_TXINTTHRES (0x3 << REG_FDCFG_TXINTTHRES_SHIFT) | ||
46 | #define REG_FDCFG_TXINTTHRES_DISABLED (0x0 << REG_FDCFG_TXINTTHRES_SHIFT) | ||
47 | #define REG_FDCFG_TXINTTHRES_EMPTY (0x1 << REG_FDCFG_TXINTTHRES_SHIFT) | ||
48 | #define REG_FDCFG_TXINTTHRES_NOTFULL (0x2 << REG_FDCFG_TXINTTHRES_SHIFT) | ||
49 | #define REG_FDCFG_TXINTTHRES_NEAREMPTY (0x3 << REG_FDCFG_TXINTTHRES_SHIFT) | ||
50 | #define REG_FDCFG_RXINTTHRES_SHIFT 16 | ||
51 | #define REG_FDCFG_RXINTTHRES (0x3 << REG_FDCFG_RXINTTHRES_SHIFT) | ||
52 | #define REG_FDCFG_RXINTTHRES_DISABLED (0x0 << REG_FDCFG_RXINTTHRES_SHIFT) | ||
53 | #define REG_FDCFG_RXINTTHRES_FULL (0x1 << REG_FDCFG_RXINTTHRES_SHIFT) | ||
54 | #define REG_FDCFG_RXINTTHRES_NOTEMPTY (0x2 << REG_FDCFG_RXINTTHRES_SHIFT) | ||
55 | #define REG_FDCFG_RXINTTHRES_NEARFULL (0x3 << REG_FDCFG_RXINTTHRES_SHIFT) | ||
56 | #define REG_FDCFG_TXFIFOSIZE_SHIFT 8 | ||
57 | #define REG_FDCFG_TXFIFOSIZE (0xff << REG_FDCFG_TXFIFOSIZE_SHIFT) | ||
58 | #define REG_FDCFG_RXFIFOSIZE_SHIFT 0 | ||
59 | #define REG_FDCFG_RXFIFOSIZE (0xff << REG_FDCFG_RXFIFOSIZE_SHIFT) | ||
60 | |||
61 | #define REG_FDSTAT_TXCOUNT_SHIFT 24 | ||
62 | #define REG_FDSTAT_TXCOUNT (0xff << REG_FDSTAT_TXCOUNT_SHIFT) | ||
63 | #define REG_FDSTAT_RXCOUNT_SHIFT 16 | ||
64 | #define REG_FDSTAT_RXCOUNT (0xff << REG_FDSTAT_RXCOUNT_SHIFT) | ||
65 | #define REG_FDSTAT_RXCHAN_SHIFT 4 | ||
66 | #define REG_FDSTAT_RXCHAN (0xf << REG_FDSTAT_RXCHAN_SHIFT) | ||
67 | #define REG_FDSTAT_RXE BIT(3) /* Rx Empty */ | ||
68 | #define REG_FDSTAT_RXF BIT(2) /* Rx Full */ | ||
69 | #define REG_FDSTAT_TXE BIT(1) /* Tx Empty */ | ||
70 | #define REG_FDSTAT_TXF BIT(0) /* Tx Full */ | ||
71 | |||
72 | #define NUM_TTY_CHANNELS 16 | ||
73 | |||
74 | #define RX_BUF_SIZE 1024 | ||
75 | |||
76 | /* | ||
77 | * When the IRQ is unavailable, the FDC state must be polled for incoming data | ||
78 | * and space becoming available in TX FIFO. | ||
79 | */ | ||
80 | #define FDC_TTY_POLL (HZ / 50) | ||
81 | |||
82 | struct mips_ejtag_fdc_tty; | ||
83 | |||
84 | /** | ||
85 | * struct mips_ejtag_fdc_tty_port - Wrapper struct for FDC tty_port. | ||
86 | * @port: TTY port data | ||
87 | * @driver: TTY driver. | ||
88 | * @rx_lock: Lock for rx_buf. | ||
89 | * This protects between the hard interrupt and user | ||
90 | * context. It's also held during read SWITCH operations. | ||
91 | * @rx_buf: Read buffer. | ||
92 | * @xmit_lock: Lock for xmit_*, and port.xmit_buf. | ||
93 | * This protects between user context and kernel thread. | ||
94 | * It is used from chars_in_buffer()/write_room() TTY | ||
95 | * callbacks which are used during wait operations, so a | ||
96 | * mutex is unsuitable. | ||
97 | * @xmit_cnt: Size of xmit buffer contents. | ||
98 | * @xmit_head: Head of xmit buffer where data is written. | ||
99 | * @xmit_tail: Tail of xmit buffer where data is read. | ||
100 | * @xmit_empty: Completion for xmit buffer being empty. | ||
101 | */ | ||
102 | struct mips_ejtag_fdc_tty_port { | ||
103 | struct tty_port port; | ||
104 | struct mips_ejtag_fdc_tty *driver; | ||
105 | raw_spinlock_t rx_lock; | ||
106 | void *rx_buf; | ||
107 | spinlock_t xmit_lock; | ||
108 | unsigned int xmit_cnt; | ||
109 | unsigned int xmit_head; | ||
110 | unsigned int xmit_tail; | ||
111 | struct completion xmit_empty; | ||
112 | }; | ||
113 | |||
114 | /** | ||
115 | * struct mips_ejtag_fdc_tty - Driver data for FDC as a whole. | ||
116 | * @dev: FDC device (for dev_*() logging). | ||
117 | * @driver: TTY driver. | ||
118 | * @cpu: CPU number for this FDC. | ||
119 | * @fdc_name: FDC name (not for base of channel names). | ||
120 | * @driver_name: Base of driver name. | ||
121 | * @ports: Per-channel data. | ||
122 | * @waitqueue: Wait queue for waiting for TX data, or for space in TX | ||
123 | * FIFO. | ||
124 | * @lock: Lock to protect FDCFG (interrupt enable). | ||
125 | * @thread: KThread for writing out data to FDC. | ||
126 | * @reg: FDC registers. | ||
127 | * @tx_fifo: TX FIFO size. | ||
128 | * @xmit_size: Size of each port's xmit buffer. | ||
129 | * @xmit_total: Total number of bytes (from all ports) to transmit. | ||
130 | * @xmit_next: Next port number to transmit from (round robin). | ||
131 | * @xmit_full: Indicates TX FIFO is full, we're waiting for space. | ||
132 | * @irq: IRQ number (negative if no IRQ). | ||
133 | * @removing: Indicates the device is being removed and @poll_timer | ||
134 | * should not be restarted. | ||
135 | * @poll_timer: Timer for polling for interrupt events when @irq < 0. | ||
136 | */ | ||
137 | struct mips_ejtag_fdc_tty { | ||
138 | struct device *dev; | ||
139 | struct tty_driver *driver; | ||
140 | unsigned int cpu; | ||
141 | char fdc_name[16]; | ||
142 | char driver_name[16]; | ||
143 | struct mips_ejtag_fdc_tty_port ports[NUM_TTY_CHANNELS]; | ||
144 | wait_queue_head_t waitqueue; | ||
145 | raw_spinlock_t lock; | ||
146 | struct task_struct *thread; | ||
147 | |||
148 | void __iomem *reg; | ||
149 | u8 tx_fifo; | ||
150 | |||
151 | unsigned int xmit_size; | ||
152 | atomic_t xmit_total; | ||
153 | unsigned int xmit_next; | ||
154 | bool xmit_full; | ||
155 | |||
156 | int irq; | ||
157 | bool removing; | ||
158 | struct timer_list poll_timer; | ||
159 | }; | ||
160 | |||
161 | /* Hardware access */ | ||
162 | |||
163 | static inline void mips_ejtag_fdc_write(struct mips_ejtag_fdc_tty *priv, | ||
164 | unsigned int offs, unsigned int data) | ||
165 | { | ||
166 | iowrite32(data, priv->reg + offs); | ||
167 | } | ||
168 | |||
169 | static inline unsigned int mips_ejtag_fdc_read(struct mips_ejtag_fdc_tty *priv, | ||
170 | unsigned int offs) | ||
171 | { | ||
172 | return ioread32(priv->reg + offs); | ||
173 | } | ||
174 | |||
175 | /* Encoding of byte stream in FDC words */ | ||
176 | |||
177 | /** | ||
178 | * struct fdc_word - FDC word encoding some number of bytes of data. | ||
179 | * @word: Raw FDC word. | ||
180 | * @bytes: Number of bytes encoded by @word. | ||
181 | */ | ||
182 | struct fdc_word { | ||
183 | u32 word; | ||
184 | unsigned int bytes; | ||
185 | }; | ||
186 | |||
187 | /* | ||
188 | * This is a compact encoding which allows every 1 byte, 2 byte, and 3 byte | ||
189 | * sequence to be encoded in a single word, while allowing the majority of 4 | ||
190 | * byte sequences (including all ASCII and common binary data) to be encoded in | ||
191 | * a single word too. | ||
192 | * _______________________ _____________ | ||
193 | * | FDC Word | | | ||
194 | * |31-24|23-16|15-8 | 7-0 | Bytes | | ||
195 | * |_____|_____|_____|_____|_____________| | ||
196 | * | | | | | | | ||
197 | * |0x80 |0x80 |0x80 | WW | WW | | ||
198 | * |0x81 |0x81 | XX | WW | WW XX | | ||
199 | * |0x82 | YY | XX | WW | WW XX YY | | ||
200 | * | ZZ | YY | XX | WW | WW XX YY ZZ | | ||
201 | * |_____|_____|_____|_____|_____________| | ||
202 | * | ||
203 | * Note that the 4-byte encoding can only be used where none of the other 3 | ||
204 | * encodings match, otherwise it must fall back to the 3 byte encoding. | ||
205 | */ | ||
206 | |||
207 | /* ranges >= 1 && sizes[0] >= 1 */ | ||
208 | static struct fdc_word mips_ejtag_fdc_encode(const char **ptrs, | ||
209 | unsigned int *sizes, | ||
210 | unsigned int ranges) | ||
211 | { | ||
212 | struct fdc_word word = { 0, 0 }; | ||
213 | const char **ptrs_end = ptrs + ranges; | ||
214 | |||
215 | for (; ptrs < ptrs_end; ++ptrs) { | ||
216 | const char *ptr = *(ptrs++); | ||
217 | const char *end = ptr + *(sizes++); | ||
218 | |||
219 | for (; ptr < end; ++ptr) { | ||
220 | word.word |= (u8)*ptr << (8*word.bytes); | ||
221 | ++word.bytes; | ||
222 | if (word.bytes == 4) | ||
223 | goto done; | ||
224 | } | ||
225 | } | ||
226 | done: | ||
227 | /* Choose the appropriate encoding */ | ||
228 | switch (word.bytes) { | ||
229 | case 4: | ||
230 | /* 4 byte encoding, but don't match the 1-3 byte encodings */ | ||
231 | if ((word.word >> 8) != 0x808080 && | ||
232 | (word.word >> 16) != 0x8181 && | ||
233 | (word.word >> 24) != 0x82) | ||
234 | break; | ||
235 | /* Fall back to a 3 byte encoding */ | ||
236 | word.bytes = 3; | ||
237 | word.word &= 0x00ffffff; | ||
238 | case 3: | ||
239 | /* 3 byte encoding */ | ||
240 | word.word |= 0x82000000; | ||
241 | break; | ||
242 | case 2: | ||
243 | /* 2 byte encoding */ | ||
244 | word.word |= 0x81810000; | ||
245 | break; | ||
246 | case 1: | ||
247 | /* 1 byte encoding */ | ||
248 | word.word |= 0x80808000; | ||
249 | break; | ||
250 | } | ||
251 | return word; | ||
252 | } | ||
253 | |||
254 | static unsigned int mips_ejtag_fdc_decode(u32 word, char *buf) | ||
255 | { | ||
256 | buf[0] = (u8)word; | ||
257 | word >>= 8; | ||
258 | if (word == 0x808080) | ||
259 | return 1; | ||
260 | buf[1] = (u8)word; | ||
261 | word >>= 8; | ||
262 | if (word == 0x8181) | ||
263 | return 2; | ||
264 | buf[2] = (u8)word; | ||
265 | word >>= 8; | ||
266 | if (word == 0x82) | ||
267 | return 3; | ||
268 | buf[3] = (u8)word; | ||
269 | return 4; | ||
270 | } | ||
271 | |||
272 | /* Console operations */ | ||
273 | |||
274 | /** | ||
275 | * struct mips_ejtag_fdc_console - Wrapper struct for FDC consoles. | ||
276 | * @cons: Console object. | ||
277 | * @tty_drv: TTY driver associated with this console. | ||
278 | * @lock: Lock to protect concurrent access to other fields. | ||
279 | * This is raw because it may be used very early. | ||
280 | * @initialised: Whether the console is initialised. | ||
281 | * @regs: Registers base address for each CPU. | ||
282 | */ | ||
283 | struct mips_ejtag_fdc_console { | ||
284 | struct console cons; | ||
285 | struct tty_driver *tty_drv; | ||
286 | raw_spinlock_t lock; | ||
287 | bool initialised; | ||
288 | void __iomem *regs[NR_CPUS]; | ||
289 | }; | ||
290 | |||
291 | /* Low level console write shared by early console and normal console */ | ||
292 | static void mips_ejtag_fdc_console_write(struct console *c, const char *s, | ||
293 | unsigned int count) | ||
294 | { | ||
295 | struct mips_ejtag_fdc_console *cons = | ||
296 | container_of(c, struct mips_ejtag_fdc_console, cons); | ||
297 | void __iomem *regs; | ||
298 | struct fdc_word word; | ||
299 | unsigned long flags; | ||
300 | unsigned int i, buf_len, cpu; | ||
301 | bool done_cr = false; | ||
302 | char buf[4]; | ||
303 | const char *buf_ptr = buf; | ||
304 | /* Number of bytes of input data encoded up to each byte in buf */ | ||
305 | u8 inc[4]; | ||
306 | |||
307 | local_irq_save(flags); | ||
308 | cpu = smp_processor_id(); | ||
309 | regs = cons->regs[cpu]; | ||
310 | /* First console output on this CPU? */ | ||
311 | if (!regs) { | ||
312 | regs = mips_cdmm_early_probe(0xfd); | ||
313 | cons->regs[cpu] = regs; | ||
314 | } | ||
315 | /* Already tried and failed to find FDC on this CPU? */ | ||
316 | if (IS_ERR(regs)) | ||
317 | goto out; | ||
318 | while (count) { | ||
319 | /* | ||
320 | * Copy the next few characters to a buffer so we can inject | ||
321 | * carriage returns before newlines. | ||
322 | */ | ||
323 | for (buf_len = 0, i = 0; buf_len < 4 && i < count; ++buf_len) { | ||
324 | if (s[i] == '\n' && !done_cr) { | ||
325 | buf[buf_len] = '\r'; | ||
326 | done_cr = true; | ||
327 | } else { | ||
328 | buf[buf_len] = s[i]; | ||
329 | done_cr = false; | ||
330 | ++i; | ||
331 | } | ||
332 | inc[buf_len] = i; | ||
333 | } | ||
334 | word = mips_ejtag_fdc_encode(&buf_ptr, &buf_len, 1); | ||
335 | count -= inc[word.bytes - 1]; | ||
336 | s += inc[word.bytes - 1]; | ||
337 | |||
338 | /* Busy wait until there's space in fifo */ | ||
339 | while (ioread32(regs + REG_FDSTAT) & REG_FDSTAT_TXF) | ||
340 | ; | ||
341 | iowrite32(word.word, regs + REG_FDTX(c->index)); | ||
342 | } | ||
343 | out: | ||
344 | local_irq_restore(flags); | ||
345 | } | ||
346 | |||
347 | static struct tty_driver *mips_ejtag_fdc_console_device(struct console *c, | ||
348 | int *index) | ||
349 | { | ||
350 | struct mips_ejtag_fdc_console *cons = | ||
351 | container_of(c, struct mips_ejtag_fdc_console, cons); | ||
352 | |||
353 | *index = c->index; | ||
354 | return cons->tty_drv; | ||
355 | } | ||
356 | |||
357 | /* Initialise an FDC console (early or normal */ | ||
358 | static int __init mips_ejtag_fdc_console_init(struct mips_ejtag_fdc_console *c) | ||
359 | { | ||
360 | void __iomem *regs; | ||
361 | unsigned long flags; | ||
362 | int ret = 0; | ||
363 | |||
364 | raw_spin_lock_irqsave(&c->lock, flags); | ||
365 | /* Don't init twice */ | ||
366 | if (c->initialised) | ||
367 | goto out; | ||
368 | /* Look for the FDC device */ | ||
369 | regs = mips_cdmm_early_probe(0xfd); | ||
370 | if (IS_ERR(regs)) { | ||
371 | ret = PTR_ERR(regs); | ||
372 | goto out; | ||
373 | } | ||
374 | |||
375 | c->initialised = true; | ||
376 | c->regs[smp_processor_id()] = regs; | ||
377 | register_console(&c->cons); | ||
378 | out: | ||
379 | raw_spin_unlock_irqrestore(&c->lock, flags); | ||
380 | return ret; | ||
381 | } | ||
382 | |||
383 | static struct mips_ejtag_fdc_console mips_ejtag_fdc_con = { | ||
384 | .cons = { | ||
385 | .name = "fdc", | ||
386 | .write = mips_ejtag_fdc_console_write, | ||
387 | .device = mips_ejtag_fdc_console_device, | ||
388 | .flags = CON_PRINTBUFFER, | ||
389 | .index = -1, | ||
390 | }, | ||
391 | .lock = __RAW_SPIN_LOCK_UNLOCKED(mips_ejtag_fdc_con.lock), | ||
392 | }; | ||
393 | |||
394 | /* TTY RX/TX operations */ | ||
395 | |||
396 | /** | ||
397 | * mips_ejtag_fdc_put_chan() - Write out a block of channel data. | ||
398 | * @priv: Pointer to driver private data. | ||
399 | * @chan: Channel number. | ||
400 | * | ||
401 | * Write a single block of data out to the debug adapter. If the circular buffer | ||
402 | * is wrapped then only the first block is written. | ||
403 | * | ||
404 | * Returns: The number of bytes that were written. | ||
405 | */ | ||
406 | static unsigned int mips_ejtag_fdc_put_chan(struct mips_ejtag_fdc_tty *priv, | ||
407 | unsigned int chan) | ||
408 | { | ||
409 | struct mips_ejtag_fdc_tty_port *dport; | ||
410 | struct tty_struct *tty; | ||
411 | const char *ptrs[2]; | ||
412 | unsigned int sizes[2] = { 0 }; | ||
413 | struct fdc_word word = { .bytes = 0 }; | ||
414 | unsigned long flags; | ||
415 | |||
416 | dport = &priv->ports[chan]; | ||
417 | spin_lock(&dport->xmit_lock); | ||
418 | if (dport->xmit_cnt) { | ||
419 | ptrs[0] = dport->port.xmit_buf + dport->xmit_tail; | ||
420 | sizes[0] = min_t(unsigned int, | ||
421 | priv->xmit_size - dport->xmit_tail, | ||
422 | dport->xmit_cnt); | ||
423 | ptrs[1] = dport->port.xmit_buf; | ||
424 | sizes[1] = dport->xmit_cnt - sizes[0]; | ||
425 | word = mips_ejtag_fdc_encode(ptrs, sizes, 1 + !!sizes[1]); | ||
426 | |||
427 | dev_dbg(priv->dev, "%s%u: out %08x: \"%*pE%*pE\"\n", | ||
428 | priv->driver_name, chan, word.word, | ||
429 | min_t(int, word.bytes, sizes[0]), ptrs[0], | ||
430 | max_t(int, 0, word.bytes - sizes[0]), ptrs[1]); | ||
431 | |||
432 | local_irq_save(flags); | ||
433 | /* Maybe we raced with the console and TX FIFO is full */ | ||
434 | if (mips_ejtag_fdc_read(priv, REG_FDSTAT) & REG_FDSTAT_TXF) | ||
435 | word.bytes = 0; | ||
436 | else | ||
437 | mips_ejtag_fdc_write(priv, REG_FDTX(chan), word.word); | ||
438 | local_irq_restore(flags); | ||
439 | |||
440 | dport->xmit_cnt -= word.bytes; | ||
441 | if (!dport->xmit_cnt) { | ||
442 | /* Reset pointers to avoid wraps */ | ||
443 | dport->xmit_head = 0; | ||
444 | dport->xmit_tail = 0; | ||
445 | complete(&dport->xmit_empty); | ||
446 | } else { | ||
447 | dport->xmit_tail += word.bytes; | ||
448 | if (dport->xmit_tail >= priv->xmit_size) | ||
449 | dport->xmit_tail -= priv->xmit_size; | ||
450 | } | ||
451 | atomic_sub(word.bytes, &priv->xmit_total); | ||
452 | } | ||
453 | spin_unlock(&dport->xmit_lock); | ||
454 | |||
455 | /* If we've made more data available, wake up tty */ | ||
456 | if (sizes[0] && word.bytes) { | ||
457 | tty = tty_port_tty_get(&dport->port); | ||
458 | if (tty) { | ||
459 | tty_wakeup(tty); | ||
460 | tty_kref_put(tty); | ||
461 | } | ||
462 | } | ||
463 | |||
464 | return word.bytes; | ||
465 | } | ||
466 | |||
467 | /** | ||
468 | * mips_ejtag_fdc_put() - Kernel thread to write out channel data to FDC. | ||
469 | * @arg: Driver pointer. | ||
470 | * | ||
471 | * This kernel thread runs while @priv->xmit_total != 0, and round robins the | ||
472 | * channels writing out blocks of buffered data to the FDC TX FIFO. | ||
473 | */ | ||
474 | static int mips_ejtag_fdc_put(void *arg) | ||
475 | { | ||
476 | struct mips_ejtag_fdc_tty *priv = arg; | ||
477 | struct mips_ejtag_fdc_tty_port *dport; | ||
478 | unsigned int ret; | ||
479 | u32 cfg; | ||
480 | |||
481 | __set_current_state(TASK_RUNNING); | ||
482 | while (!kthread_should_stop()) { | ||
483 | /* Wait for data to actually write */ | ||
484 | wait_event_interruptible(priv->waitqueue, | ||
485 | atomic_read(&priv->xmit_total) || | ||
486 | kthread_should_stop()); | ||
487 | if (kthread_should_stop()) | ||
488 | break; | ||
489 | |||
490 | /* Wait for TX FIFO space to write data */ | ||
491 | raw_spin_lock_irq(&priv->lock); | ||
492 | if (mips_ejtag_fdc_read(priv, REG_FDSTAT) & REG_FDSTAT_TXF) { | ||
493 | priv->xmit_full = true; | ||
494 | if (priv->irq >= 0) { | ||
495 | /* Enable TX interrupt */ | ||
496 | cfg = mips_ejtag_fdc_read(priv, REG_FDCFG); | ||
497 | cfg &= ~REG_FDCFG_TXINTTHRES; | ||
498 | cfg |= REG_FDCFG_TXINTTHRES_NOTFULL; | ||
499 | mips_ejtag_fdc_write(priv, REG_FDCFG, cfg); | ||
500 | } | ||
501 | } | ||
502 | raw_spin_unlock_irq(&priv->lock); | ||
503 | wait_event_interruptible(priv->waitqueue, | ||
504 | !(mips_ejtag_fdc_read(priv, REG_FDSTAT) | ||
505 | & REG_FDSTAT_TXF) || | ||
506 | kthread_should_stop()); | ||
507 | if (kthread_should_stop()) | ||
508 | break; | ||
509 | |||
510 | /* Find next channel with data to output */ | ||
511 | for (;;) { | ||
512 | dport = &priv->ports[priv->xmit_next]; | ||
513 | spin_lock(&dport->xmit_lock); | ||
514 | ret = dport->xmit_cnt; | ||
515 | spin_unlock(&dport->xmit_lock); | ||
516 | if (ret) | ||
517 | break; | ||
518 | /* Round robin */ | ||
519 | ++priv->xmit_next; | ||
520 | if (priv->xmit_next >= NUM_TTY_CHANNELS) | ||
521 | priv->xmit_next = 0; | ||
522 | } | ||
523 | |||
524 | /* Try writing data to the chosen channel */ | ||
525 | ret = mips_ejtag_fdc_put_chan(priv, priv->xmit_next); | ||
526 | |||
527 | /* | ||
528 | * If anything was output, move on to the next channel so as not | ||
529 | * to starve other channels. | ||
530 | */ | ||
531 | if (ret) { | ||
532 | ++priv->xmit_next; | ||
533 | if (priv->xmit_next >= NUM_TTY_CHANNELS) | ||
534 | priv->xmit_next = 0; | ||
535 | } | ||
536 | } | ||
537 | |||
538 | return 0; | ||
539 | } | ||
540 | |||
541 | /** | ||
542 | * mips_ejtag_fdc_handle() - Handle FDC events. | ||
543 | * @priv: Pointer to driver private data. | ||
544 | * | ||
545 | * Handle FDC events, such as new incoming data which needs draining out of the | ||
546 | * RX FIFO and feeding into the appropriate TTY ports, and space becoming | ||
547 | * available in the TX FIFO which would allow more data to be written out. | ||
548 | */ | ||
549 | static void mips_ejtag_fdc_handle(struct mips_ejtag_fdc_tty *priv) | ||
550 | { | ||
551 | struct mips_ejtag_fdc_tty_port *dport; | ||
552 | unsigned int stat, channel, data, cfg, i, flipped; | ||
553 | int len; | ||
554 | char buf[4]; | ||
555 | |||
556 | for (;;) { | ||
557 | /* Find which channel the next FDC word is destined for */ | ||
558 | stat = mips_ejtag_fdc_read(priv, REG_FDSTAT); | ||
559 | if (stat & REG_FDSTAT_RXE) | ||
560 | break; | ||
561 | channel = (stat & REG_FDSTAT_RXCHAN) >> REG_FDSTAT_RXCHAN_SHIFT; | ||
562 | dport = &priv->ports[channel]; | ||
563 | |||
564 | /* Read out the FDC word, decode it, and pass to tty layer */ | ||
565 | raw_spin_lock(&dport->rx_lock); | ||
566 | data = mips_ejtag_fdc_read(priv, REG_FDRX); | ||
567 | |||
568 | /* Check the port isn't being shut down */ | ||
569 | if (!dport->rx_buf) | ||
570 | goto unlock; | ||
571 | |||
572 | len = mips_ejtag_fdc_decode(data, buf); | ||
573 | dev_dbg(priv->dev, "%s%u: in %08x: \"%*pE\"\n", | ||
574 | priv->driver_name, channel, data, len, buf); | ||
575 | |||
576 | flipped = 0; | ||
577 | for (i = 0; i < len; ++i) | ||
578 | flipped += tty_insert_flip_char(&dport->port, buf[i], | ||
579 | TTY_NORMAL); | ||
580 | if (flipped) | ||
581 | tty_flip_buffer_push(&dport->port); | ||
582 | unlock: | ||
583 | raw_spin_unlock(&dport->rx_lock); | ||
584 | } | ||
585 | |||
586 | /* If TX FIFO no longer full we may be able to write more data */ | ||
587 | raw_spin_lock(&priv->lock); | ||
588 | if (priv->xmit_full && !(stat & REG_FDSTAT_TXF)) { | ||
589 | priv->xmit_full = false; | ||
590 | |||
591 | /* Disable TX interrupt */ | ||
592 | cfg = mips_ejtag_fdc_read(priv, REG_FDCFG); | ||
593 | cfg &= ~REG_FDCFG_TXINTTHRES; | ||
594 | cfg |= REG_FDCFG_TXINTTHRES_DISABLED; | ||
595 | mips_ejtag_fdc_write(priv, REG_FDCFG, cfg); | ||
596 | |||
597 | /* Wait the kthread so it can try writing more data */ | ||
598 | wake_up_interruptible(&priv->waitqueue); | ||
599 | } | ||
600 | raw_spin_unlock(&priv->lock); | ||
601 | } | ||
602 | |||
603 | /** | ||
604 | * mips_ejtag_fdc_isr() - Interrupt handler. | ||
605 | * @irq: IRQ number. | ||
606 | * @dev_id: Pointer to driver private data. | ||
607 | * | ||
608 | * This is the interrupt handler, used when interrupts are enabled. | ||
609 | * | ||
610 | * It simply triggers the common FDC handler code. | ||
611 | * | ||
612 | * Returns: IRQ_HANDLED if an FDC interrupt was pending. | ||
613 | * IRQ_NONE otherwise. | ||
614 | */ | ||
615 | static irqreturn_t mips_ejtag_fdc_isr(int irq, void *dev_id) | ||
616 | { | ||
617 | struct mips_ejtag_fdc_tty *priv = dev_id; | ||
618 | |||
619 | /* | ||
620 | * We're not using proper per-cpu IRQs, so we must be careful not to | ||
621 | * handle IRQs on CPUs we're not interested in. | ||
622 | * | ||
623 | * Ideally proper per-cpu IRQ handlers could be used, but that doesn't | ||
624 | * fit well with the whole sharing of the main CPU IRQ lines. When we | ||
625 | * have something with a GIC that routes the FDC IRQs (i.e. no sharing | ||
626 | * between handlers) then support could be added more easily. | ||
627 | */ | ||
628 | if (smp_processor_id() != priv->cpu) | ||
629 | return IRQ_NONE; | ||
630 | |||
631 | /* If no FDC interrupt pending, it wasn't for us */ | ||
632 | if (!(read_c0_cause() & CAUSEF_FDCI)) | ||
633 | return IRQ_NONE; | ||
634 | |||
635 | mips_ejtag_fdc_handle(priv); | ||
636 | return IRQ_HANDLED; | ||
637 | } | ||
638 | |||
639 | /** | ||
640 | * mips_ejtag_fdc_tty_timer() - Poll FDC for incoming data. | ||
641 | * @opaque: Pointer to driver private data. | ||
642 | * | ||
643 | * This is the timer handler for when interrupts are disabled and polling the | ||
644 | * FDC state is required. | ||
645 | * | ||
646 | * It simply triggers the common FDC handler code and arranges for further | ||
647 | * polling. | ||
648 | */ | ||
649 | static void mips_ejtag_fdc_tty_timer(unsigned long opaque) | ||
650 | { | ||
651 | struct mips_ejtag_fdc_tty *priv = (void *)opaque; | ||
652 | |||
653 | mips_ejtag_fdc_handle(priv); | ||
654 | if (!priv->removing) | ||
655 | mod_timer_pinned(&priv->poll_timer, jiffies + FDC_TTY_POLL); | ||
656 | } | ||
657 | |||
658 | /* TTY Port operations */ | ||
659 | |||
660 | static int mips_ejtag_fdc_tty_port_activate(struct tty_port *port, | ||
661 | struct tty_struct *tty) | ||
662 | { | ||
663 | struct mips_ejtag_fdc_tty_port *dport = | ||
664 | container_of(port, struct mips_ejtag_fdc_tty_port, port); | ||
665 | void *rx_buf; | ||
666 | |||
667 | /* Allocate the buffer we use for writing data */ | ||
668 | if (tty_port_alloc_xmit_buf(port) < 0) | ||
669 | goto err; | ||
670 | |||
671 | /* Allocate the buffer we use for reading data */ | ||
672 | rx_buf = kzalloc(RX_BUF_SIZE, GFP_KERNEL); | ||
673 | if (!rx_buf) | ||
674 | goto err_free_xmit; | ||
675 | |||
676 | raw_spin_lock_irq(&dport->rx_lock); | ||
677 | dport->rx_buf = rx_buf; | ||
678 | raw_spin_unlock_irq(&dport->rx_lock); | ||
679 | |||
680 | return 0; | ||
681 | err_free_xmit: | ||
682 | tty_port_free_xmit_buf(port); | ||
683 | err: | ||
684 | return -ENOMEM; | ||
685 | } | ||
686 | |||
687 | static void mips_ejtag_fdc_tty_port_shutdown(struct tty_port *port) | ||
688 | { | ||
689 | struct mips_ejtag_fdc_tty_port *dport = | ||
690 | container_of(port, struct mips_ejtag_fdc_tty_port, port); | ||
691 | struct mips_ejtag_fdc_tty *priv = dport->driver; | ||
692 | void *rx_buf; | ||
693 | unsigned int count; | ||
694 | |||
695 | spin_lock(&dport->xmit_lock); | ||
696 | count = dport->xmit_cnt; | ||
697 | spin_unlock(&dport->xmit_lock); | ||
698 | if (count) { | ||
699 | /* | ||
700 | * There's still data to write out, so wake and wait for the | ||
701 | * writer thread to drain the buffer. | ||
702 | */ | ||
703 | wake_up_interruptible(&priv->waitqueue); | ||
704 | wait_for_completion(&dport->xmit_empty); | ||
705 | } | ||
706 | |||
707 | /* Null the read buffer (timer could still be running!) */ | ||
708 | raw_spin_lock_irq(&dport->rx_lock); | ||
709 | rx_buf = dport->rx_buf; | ||
710 | dport->rx_buf = NULL; | ||
711 | raw_spin_unlock_irq(&dport->rx_lock); | ||
712 | /* Free the read buffer */ | ||
713 | kfree(rx_buf); | ||
714 | |||
715 | /* Free the write buffer */ | ||
716 | tty_port_free_xmit_buf(port); | ||
717 | } | ||
718 | |||
719 | static const struct tty_port_operations mips_ejtag_fdc_tty_port_ops = { | ||
720 | .activate = mips_ejtag_fdc_tty_port_activate, | ||
721 | .shutdown = mips_ejtag_fdc_tty_port_shutdown, | ||
722 | }; | ||
723 | |||
724 | /* TTY operations */ | ||
725 | |||
726 | static int mips_ejtag_fdc_tty_install(struct tty_driver *driver, | ||
727 | struct tty_struct *tty) | ||
728 | { | ||
729 | struct mips_ejtag_fdc_tty *priv = driver->driver_state; | ||
730 | |||
731 | tty->driver_data = &priv->ports[tty->index]; | ||
732 | return tty_port_install(&priv->ports[tty->index].port, driver, tty); | ||
733 | } | ||
734 | |||
735 | static int mips_ejtag_fdc_tty_open(struct tty_struct *tty, struct file *filp) | ||
736 | { | ||
737 | return tty_port_open(tty->port, tty, filp); | ||
738 | } | ||
739 | |||
740 | static void mips_ejtag_fdc_tty_close(struct tty_struct *tty, struct file *filp) | ||
741 | { | ||
742 | return tty_port_close(tty->port, tty, filp); | ||
743 | } | ||
744 | |||
745 | static void mips_ejtag_fdc_tty_hangup(struct tty_struct *tty) | ||
746 | { | ||
747 | struct mips_ejtag_fdc_tty_port *dport = tty->driver_data; | ||
748 | struct mips_ejtag_fdc_tty *priv = dport->driver; | ||
749 | |||
750 | /* Drop any data in the xmit buffer */ | ||
751 | spin_lock(&dport->xmit_lock); | ||
752 | if (dport->xmit_cnt) { | ||
753 | atomic_sub(dport->xmit_cnt, &priv->xmit_total); | ||
754 | dport->xmit_cnt = 0; | ||
755 | dport->xmit_head = 0; | ||
756 | dport->xmit_tail = 0; | ||
757 | complete(&dport->xmit_empty); | ||
758 | } | ||
759 | spin_unlock(&dport->xmit_lock); | ||
760 | |||
761 | tty_port_hangup(tty->port); | ||
762 | } | ||
763 | |||
764 | static int mips_ejtag_fdc_tty_write(struct tty_struct *tty, | ||
765 | const unsigned char *buf, int total) | ||
766 | { | ||
767 | int count, block; | ||
768 | struct mips_ejtag_fdc_tty_port *dport = tty->driver_data; | ||
769 | struct mips_ejtag_fdc_tty *priv = dport->driver; | ||
770 | |||
771 | /* | ||
772 | * Write to output buffer. | ||
773 | * | ||
774 | * The reason that we asynchronously write the buffer is because if we | ||
775 | * were to write the buffer synchronously then because the channels are | ||
776 | * per-CPU the buffer would be written to the channel of whatever CPU | ||
777 | * we're running on. | ||
778 | * | ||
779 | * What we actually want to happen is have all input and output done on | ||
780 | * one CPU. | ||
781 | */ | ||
782 | spin_lock(&dport->xmit_lock); | ||
783 | /* Work out how many bytes we can write to the xmit buffer */ | ||
784 | total = min(total, (int)(priv->xmit_size - dport->xmit_cnt)); | ||
785 | atomic_add(total, &priv->xmit_total); | ||
786 | dport->xmit_cnt += total; | ||
787 | /* Write the actual bytes (may need splitting if it wraps) */ | ||
788 | for (count = total; count; count -= block) { | ||
789 | block = min(count, (int)(priv->xmit_size - dport->xmit_head)); | ||
790 | memcpy(dport->port.xmit_buf + dport->xmit_head, buf, block); | ||
791 | dport->xmit_head += block; | ||
792 | if (dport->xmit_head >= priv->xmit_size) | ||
793 | dport->xmit_head -= priv->xmit_size; | ||
794 | buf += block; | ||
795 | } | ||
796 | count = dport->xmit_cnt; | ||
797 | /* Xmit buffer no longer empty? */ | ||
798 | if (count) | ||
799 | reinit_completion(&dport->xmit_empty); | ||
800 | spin_unlock(&dport->xmit_lock); | ||
801 | |||
802 | /* Wake up the kthread */ | ||
803 | if (total) | ||
804 | wake_up_interruptible(&priv->waitqueue); | ||
805 | return total; | ||
806 | } | ||
807 | |||
808 | static int mips_ejtag_fdc_tty_write_room(struct tty_struct *tty) | ||
809 | { | ||
810 | struct mips_ejtag_fdc_tty_port *dport = tty->driver_data; | ||
811 | struct mips_ejtag_fdc_tty *priv = dport->driver; | ||
812 | int room; | ||
813 | |||
814 | /* Report the space in the xmit buffer */ | ||
815 | spin_lock(&dport->xmit_lock); | ||
816 | room = priv->xmit_size - dport->xmit_cnt; | ||
817 | spin_unlock(&dport->xmit_lock); | ||
818 | |||
819 | return room; | ||
820 | } | ||
821 | |||
822 | static int mips_ejtag_fdc_tty_chars_in_buffer(struct tty_struct *tty) | ||
823 | { | ||
824 | struct mips_ejtag_fdc_tty_port *dport = tty->driver_data; | ||
825 | int chars; | ||
826 | |||
827 | /* Report the number of bytes in the xmit buffer */ | ||
828 | spin_lock(&dport->xmit_lock); | ||
829 | chars = dport->xmit_cnt; | ||
830 | spin_unlock(&dport->xmit_lock); | ||
831 | |||
832 | return chars; | ||
833 | } | ||
834 | |||
835 | static const struct tty_operations mips_ejtag_fdc_tty_ops = { | ||
836 | .install = mips_ejtag_fdc_tty_install, | ||
837 | .open = mips_ejtag_fdc_tty_open, | ||
838 | .close = mips_ejtag_fdc_tty_close, | ||
839 | .hangup = mips_ejtag_fdc_tty_hangup, | ||
840 | .write = mips_ejtag_fdc_tty_write, | ||
841 | .write_room = mips_ejtag_fdc_tty_write_room, | ||
842 | .chars_in_buffer = mips_ejtag_fdc_tty_chars_in_buffer, | ||
843 | }; | ||
844 | |||
845 | static int mips_ejtag_fdc_tty_probe(struct mips_cdmm_device *dev) | ||
846 | { | ||
847 | int ret, nport; | ||
848 | struct mips_ejtag_fdc_tty_port *dport; | ||
849 | struct mips_ejtag_fdc_tty *priv; | ||
850 | struct tty_driver *driver; | ||
851 | unsigned int cfg, tx_fifo; | ||
852 | |||
853 | priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL); | ||
854 | if (!priv) | ||
855 | return -ENOMEM; | ||
856 | priv->cpu = dev->cpu; | ||
857 | priv->dev = &dev->dev; | ||
858 | mips_cdmm_set_drvdata(dev, priv); | ||
859 | atomic_set(&priv->xmit_total, 0); | ||
860 | raw_spin_lock_init(&priv->lock); | ||
861 | |||
862 | priv->reg = devm_ioremap_nocache(priv->dev, dev->res.start, | ||
863 | resource_size(&dev->res)); | ||
864 | if (!priv->reg) { | ||
865 | dev_err(priv->dev, "ioremap failed for resource %pR\n", | ||
866 | &dev->res); | ||
867 | return -ENOMEM; | ||
868 | } | ||
869 | |||
870 | cfg = mips_ejtag_fdc_read(priv, REG_FDCFG); | ||
871 | tx_fifo = (cfg & REG_FDCFG_TXFIFOSIZE) >> REG_FDCFG_TXFIFOSIZE_SHIFT; | ||
872 | /* Disable interrupts */ | ||
873 | cfg &= ~(REG_FDCFG_TXINTTHRES | REG_FDCFG_RXINTTHRES); | ||
874 | cfg |= REG_FDCFG_TXINTTHRES_DISABLED; | ||
875 | cfg |= REG_FDCFG_RXINTTHRES_DISABLED; | ||
876 | mips_ejtag_fdc_write(priv, REG_FDCFG, cfg); | ||
877 | |||
878 | /* Make each port's xmit FIFO big enough to fill FDC TX FIFO */ | ||
879 | priv->xmit_size = min(tx_fifo * 4, (unsigned int)SERIAL_XMIT_SIZE); | ||
880 | |||
881 | driver = tty_alloc_driver(NUM_TTY_CHANNELS, TTY_DRIVER_REAL_RAW); | ||
882 | if (IS_ERR(driver)) | ||
883 | return PTR_ERR(driver); | ||
884 | priv->driver = driver; | ||
885 | |||
886 | driver->driver_name = "ejtag_fdc"; | ||
887 | snprintf(priv->fdc_name, sizeof(priv->fdc_name), "ttyFDC%u", dev->cpu); | ||
888 | snprintf(priv->driver_name, sizeof(priv->driver_name), "%sc", | ||
889 | priv->fdc_name); | ||
890 | driver->name = priv->driver_name; | ||
891 | driver->major = 0; /* Auto-allocate */ | ||
892 | driver->minor_start = 0; | ||
893 | driver->type = TTY_DRIVER_TYPE_SERIAL; | ||
894 | driver->subtype = SERIAL_TYPE_NORMAL; | ||
895 | driver->init_termios = tty_std_termios; | ||
896 | driver->init_termios.c_cflag |= CLOCAL; | ||
897 | driver->driver_state = priv; | ||
898 | |||
899 | tty_set_operations(driver, &mips_ejtag_fdc_tty_ops); | ||
900 | for (nport = 0; nport < NUM_TTY_CHANNELS; nport++) { | ||
901 | dport = &priv->ports[nport]; | ||
902 | dport->driver = priv; | ||
903 | tty_port_init(&dport->port); | ||
904 | dport->port.ops = &mips_ejtag_fdc_tty_port_ops; | ||
905 | raw_spin_lock_init(&dport->rx_lock); | ||
906 | spin_lock_init(&dport->xmit_lock); | ||
907 | /* The xmit buffer starts empty, i.e. completely written */ | ||
908 | init_completion(&dport->xmit_empty); | ||
909 | complete(&dport->xmit_empty); | ||
910 | } | ||
911 | |||
912 | /* Set up the console */ | ||
913 | mips_ejtag_fdc_con.regs[dev->cpu] = priv->reg; | ||
914 | if (dev->cpu == 0) | ||
915 | mips_ejtag_fdc_con.tty_drv = driver; | ||
916 | |||
917 | init_waitqueue_head(&priv->waitqueue); | ||
918 | priv->thread = kthread_create(mips_ejtag_fdc_put, priv, priv->fdc_name); | ||
919 | if (IS_ERR(priv->thread)) { | ||
920 | ret = PTR_ERR(priv->thread); | ||
921 | dev_err(priv->dev, "Couldn't create kthread (%d)\n", ret); | ||
922 | goto err_destroy_ports; | ||
923 | } | ||
924 | /* | ||
925 | * Bind the writer thread to the right CPU so it can't migrate. | ||
926 | * The channels are per-CPU and we want all channel I/O to be on a | ||
927 | * single predictable CPU. | ||
928 | */ | ||
929 | kthread_bind(priv->thread, dev->cpu); | ||
930 | wake_up_process(priv->thread); | ||
931 | |||
932 | /* Look for an FDC IRQ */ | ||
933 | priv->irq = -1; | ||
934 | if (get_c0_fdc_int) | ||
935 | priv->irq = get_c0_fdc_int(); | ||
936 | |||
937 | /* Try requesting the IRQ */ | ||
938 | if (priv->irq >= 0) { | ||
939 | /* | ||
940 | * IRQF_SHARED, IRQF_NO_SUSPEND: The FDC IRQ may be shared with | ||
941 | * other local interrupts such as the timer which sets | ||
942 | * IRQF_TIMER (including IRQF_NO_SUSPEND). | ||
943 | * | ||
944 | * IRQF_NO_THREAD: The FDC IRQ isn't individually maskable so it | ||
945 | * cannot be deferred and handled by a thread on RT kernels. For | ||
946 | * this reason any spinlocks used from the ISR are raw. | ||
947 | */ | ||
948 | ret = devm_request_irq(priv->dev, priv->irq, mips_ejtag_fdc_isr, | ||
949 | IRQF_PERCPU | IRQF_SHARED | | ||
950 | IRQF_NO_THREAD | IRQF_NO_SUSPEND, | ||
951 | priv->fdc_name, priv); | ||
952 | if (ret) | ||
953 | priv->irq = -1; | ||
954 | } | ||
955 | if (priv->irq >= 0) { | ||
956 | /* IRQ is usable, enable RX interrupt */ | ||
957 | raw_spin_lock_irq(&priv->lock); | ||
958 | cfg = mips_ejtag_fdc_read(priv, REG_FDCFG); | ||
959 | cfg &= ~REG_FDCFG_RXINTTHRES; | ||
960 | cfg |= REG_FDCFG_RXINTTHRES_NOTEMPTY; | ||
961 | mips_ejtag_fdc_write(priv, REG_FDCFG, cfg); | ||
962 | raw_spin_unlock_irq(&priv->lock); | ||
963 | } else { | ||
964 | /* If we didn't get an usable IRQ, poll instead */ | ||
965 | setup_timer(&priv->poll_timer, mips_ejtag_fdc_tty_timer, | ||
966 | (unsigned long)priv); | ||
967 | priv->poll_timer.expires = jiffies + FDC_TTY_POLL; | ||
968 | /* | ||
969 | * Always attach the timer to the right CPU. The channels are | ||
970 | * per-CPU so all polling should be from a single CPU. | ||
971 | */ | ||
972 | add_timer_on(&priv->poll_timer, dev->cpu); | ||
973 | |||
974 | dev_info(priv->dev, "No usable IRQ, polling enabled\n"); | ||
975 | } | ||
976 | |||
977 | ret = tty_register_driver(driver); | ||
978 | if (ret < 0) { | ||
979 | dev_err(priv->dev, "Couldn't install tty driver (%d)\n", ret); | ||
980 | goto err_stop_irq; | ||
981 | } | ||
982 | |||
983 | return 0; | ||
984 | |||
985 | err_stop_irq: | ||
986 | if (priv->irq >= 0) { | ||
987 | raw_spin_lock_irq(&priv->lock); | ||
988 | cfg = mips_ejtag_fdc_read(priv, REG_FDCFG); | ||
989 | /* Disable interrupts */ | ||
990 | cfg &= ~(REG_FDCFG_TXINTTHRES | REG_FDCFG_RXINTTHRES); | ||
991 | cfg |= REG_FDCFG_TXINTTHRES_DISABLED; | ||
992 | cfg |= REG_FDCFG_RXINTTHRES_DISABLED; | ||
993 | mips_ejtag_fdc_write(priv, REG_FDCFG, cfg); | ||
994 | raw_spin_unlock_irq(&priv->lock); | ||
995 | } else { | ||
996 | priv->removing = true; | ||
997 | del_timer_sync(&priv->poll_timer); | ||
998 | } | ||
999 | kthread_stop(priv->thread); | ||
1000 | err_destroy_ports: | ||
1001 | if (dev->cpu == 0) | ||
1002 | mips_ejtag_fdc_con.tty_drv = NULL; | ||
1003 | for (nport = 0; nport < NUM_TTY_CHANNELS; nport++) { | ||
1004 | dport = &priv->ports[nport]; | ||
1005 | tty_port_destroy(&dport->port); | ||
1006 | } | ||
1007 | put_tty_driver(priv->driver); | ||
1008 | return ret; | ||
1009 | } | ||
1010 | |||
1011 | static int mips_ejtag_fdc_tty_remove(struct mips_cdmm_device *dev) | ||
1012 | { | ||
1013 | struct mips_ejtag_fdc_tty *priv = mips_cdmm_get_drvdata(dev); | ||
1014 | struct mips_ejtag_fdc_tty_port *dport; | ||
1015 | int nport; | ||
1016 | unsigned int cfg; | ||
1017 | |||
1018 | if (priv->irq >= 0) { | ||
1019 | raw_spin_lock_irq(&priv->lock); | ||
1020 | cfg = mips_ejtag_fdc_read(priv, REG_FDCFG); | ||
1021 | /* Disable interrupts */ | ||
1022 | cfg &= ~(REG_FDCFG_TXINTTHRES | REG_FDCFG_RXINTTHRES); | ||
1023 | cfg |= REG_FDCFG_TXINTTHRES_DISABLED; | ||
1024 | cfg |= REG_FDCFG_RXINTTHRES_DISABLED; | ||
1025 | mips_ejtag_fdc_write(priv, REG_FDCFG, cfg); | ||
1026 | raw_spin_unlock_irq(&priv->lock); | ||
1027 | } else { | ||
1028 | priv->removing = true; | ||
1029 | del_timer_sync(&priv->poll_timer); | ||
1030 | } | ||
1031 | kthread_stop(priv->thread); | ||
1032 | if (dev->cpu == 0) | ||
1033 | mips_ejtag_fdc_con.tty_drv = NULL; | ||
1034 | tty_unregister_driver(priv->driver); | ||
1035 | for (nport = 0; nport < NUM_TTY_CHANNELS; nport++) { | ||
1036 | dport = &priv->ports[nport]; | ||
1037 | tty_port_destroy(&dport->port); | ||
1038 | } | ||
1039 | put_tty_driver(priv->driver); | ||
1040 | return 0; | ||
1041 | } | ||
1042 | |||
1043 | static int mips_ejtag_fdc_tty_cpu_down(struct mips_cdmm_device *dev) | ||
1044 | { | ||
1045 | struct mips_ejtag_fdc_tty *priv = mips_cdmm_get_drvdata(dev); | ||
1046 | unsigned int cfg; | ||
1047 | |||
1048 | if (priv->irq >= 0) { | ||
1049 | raw_spin_lock_irq(&priv->lock); | ||
1050 | cfg = mips_ejtag_fdc_read(priv, REG_FDCFG); | ||
1051 | /* Disable interrupts */ | ||
1052 | cfg &= ~(REG_FDCFG_TXINTTHRES | REG_FDCFG_RXINTTHRES); | ||
1053 | cfg |= REG_FDCFG_TXINTTHRES_DISABLED; | ||
1054 | cfg |= REG_FDCFG_RXINTTHRES_DISABLED; | ||
1055 | mips_ejtag_fdc_write(priv, REG_FDCFG, cfg); | ||
1056 | raw_spin_unlock_irq(&priv->lock); | ||
1057 | } else { | ||
1058 | priv->removing = true; | ||
1059 | del_timer_sync(&priv->poll_timer); | ||
1060 | } | ||
1061 | kthread_stop(priv->thread); | ||
1062 | |||
1063 | return 0; | ||
1064 | } | ||
1065 | |||
1066 | static int mips_ejtag_fdc_tty_cpu_up(struct mips_cdmm_device *dev) | ||
1067 | { | ||
1068 | struct mips_ejtag_fdc_tty *priv = mips_cdmm_get_drvdata(dev); | ||
1069 | unsigned int cfg; | ||
1070 | int ret = 0; | ||
1071 | |||
1072 | if (priv->irq >= 0) { | ||
1073 | /* | ||
1074 | * IRQ is usable, enable RX interrupt | ||
1075 | * This must be before kthread is restarted, as kthread may | ||
1076 | * enable TX interrupt. | ||
1077 | */ | ||
1078 | raw_spin_lock_irq(&priv->lock); | ||
1079 | cfg = mips_ejtag_fdc_read(priv, REG_FDCFG); | ||
1080 | cfg &= ~(REG_FDCFG_TXINTTHRES | REG_FDCFG_RXINTTHRES); | ||
1081 | cfg |= REG_FDCFG_TXINTTHRES_DISABLED; | ||
1082 | cfg |= REG_FDCFG_RXINTTHRES_NOTEMPTY; | ||
1083 | mips_ejtag_fdc_write(priv, REG_FDCFG, cfg); | ||
1084 | raw_spin_unlock_irq(&priv->lock); | ||
1085 | } else { | ||
1086 | /* Restart poll timer */ | ||
1087 | priv->removing = false; | ||
1088 | add_timer_on(&priv->poll_timer, dev->cpu); | ||
1089 | } | ||
1090 | |||
1091 | /* Restart the kthread */ | ||
1092 | priv->thread = kthread_create(mips_ejtag_fdc_put, priv, priv->fdc_name); | ||
1093 | if (IS_ERR(priv->thread)) { | ||
1094 | ret = PTR_ERR(priv->thread); | ||
1095 | dev_err(priv->dev, "Couldn't re-create kthread (%d)\n", ret); | ||
1096 | goto out; | ||
1097 | } | ||
1098 | /* Bind it back to the right CPU and set it off */ | ||
1099 | kthread_bind(priv->thread, dev->cpu); | ||
1100 | wake_up_process(priv->thread); | ||
1101 | out: | ||
1102 | return ret; | ||
1103 | } | ||
1104 | |||
1105 | static struct mips_cdmm_device_id mips_ejtag_fdc_tty_ids[] = { | ||
1106 | { .type = 0xfd }, | ||
1107 | { } | ||
1108 | }; | ||
1109 | |||
1110 | static struct mips_cdmm_driver mips_ejtag_fdc_tty_driver = { | ||
1111 | .drv = { | ||
1112 | .name = "mips_ejtag_fdc", | ||
1113 | }, | ||
1114 | .probe = mips_ejtag_fdc_tty_probe, | ||
1115 | .remove = mips_ejtag_fdc_tty_remove, | ||
1116 | .cpu_down = mips_ejtag_fdc_tty_cpu_down, | ||
1117 | .cpu_up = mips_ejtag_fdc_tty_cpu_up, | ||
1118 | .id_table = mips_ejtag_fdc_tty_ids, | ||
1119 | }; | ||
1120 | module_mips_cdmm_driver(mips_ejtag_fdc_tty_driver); | ||
1121 | |||
1122 | static int __init mips_ejtag_fdc_init_console(void) | ||
1123 | { | ||
1124 | return mips_ejtag_fdc_console_init(&mips_ejtag_fdc_con); | ||
1125 | } | ||
1126 | console_initcall(mips_ejtag_fdc_init_console); | ||