1 /*
2  * Driver core for Samsung SoC onboard UARTs.
3  *
4  * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
5  *	http://armlinux.simtec.co.uk/
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10 */
11 
12 /* Hote on 2410 error handling
13  *
14  * The s3c2410 manual has a love/hate affair with the contents of the
15  * UERSTAT register in the UART blocks, and keeps marking some of the
16  * error bits as reserved. Having checked with the s3c2410x01,
17  * it copes with BREAKs properly, so I am happy to ignore the RESERVED
18  * feature from the latter versions of the manual.
19  *
20  * If it becomes aparrent that latter versions of the 2410 remove these
21  * bits, then action will have to be taken to differentiate the versions
22  * and change the policy on BREAK
23  *
24  * BJD, 04-Nov-2004
25 */
26 
27 #if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
28 #define SUPPORT_SYSRQ
29 #endif
30 
31 #include <linux/module.h>
32 #include <linux/ioport.h>
33 #include <linux/io.h>
34 #include <linux/platform_device.h>
35 #include <linux/init.h>
36 #include <linux/sysrq.h>
37 #include <linux/console.h>
38 #include <linux/tty.h>
39 #include <linux/tty_flip.h>
40 #include <linux/serial_core.h>
41 #include <linux/serial.h>
42 #include <linux/delay.h>
43 #include <linux/clk.h>
44 #include <linux/cpufreq.h>
45 #include <linux/of.h>
46 
47 #include <asm/irq.h>
48 
49 #include <mach/hardware.h>
50 #include <mach/map.h>
51 
52 #include <plat/regs-serial.h>
53 #include <plat/clock.h>
54 
55 #include "samsung.h"
56 
57 /* UART name and device definitions */
58 
59 #define S3C24XX_SERIAL_NAME	"ttySAC"
60 #define S3C24XX_SERIAL_MAJOR	204
61 #define S3C24XX_SERIAL_MINOR	64
62 
63 /* macros to change one thing to another */
64 
65 #define tx_enabled(port) ((port)->unused[0])
66 #define rx_enabled(port) ((port)->unused[1])
67 
68 /* flag to ignore all characters coming in */
69 #define RXSTAT_DUMMY_READ (0x10000000)
70 
to_ourport(struct uart_port * port)71 static inline struct s3c24xx_uart_port *to_ourport(struct uart_port *port)
72 {
73 	return container_of(port, struct s3c24xx_uart_port, port);
74 }
75 
76 /* translate a port to the device name */
77 
s3c24xx_serial_portname(struct uart_port * port)78 static inline const char *s3c24xx_serial_portname(struct uart_port *port)
79 {
80 	return to_platform_device(port->dev)->name;
81 }
82 
s3c24xx_serial_txempty_nofifo(struct uart_port * port)83 static int s3c24xx_serial_txempty_nofifo(struct uart_port *port)
84 {
85 	return (rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE);
86 }
87 
88 /*
89  * s3c64xx and later SoC's include the interrupt mask and status registers in
90  * the controller itself, unlike the s3c24xx SoC's which have these registers
91  * in the interrupt controller. Check if the port type is s3c64xx or higher.
92  */
s3c24xx_serial_has_interrupt_mask(struct uart_port * port)93 static int s3c24xx_serial_has_interrupt_mask(struct uart_port *port)
94 {
95 	return to_ourport(port)->info->type == PORT_S3C6400;
96 }
97 
s3c24xx_serial_rx_enable(struct uart_port * port)98 static void s3c24xx_serial_rx_enable(struct uart_port *port)
99 {
100 	unsigned long flags;
101 	unsigned int ucon, ufcon;
102 	int count = 10000;
103 
104 	spin_lock_irqsave(&port->lock, flags);
105 
106 	while (--count && !s3c24xx_serial_txempty_nofifo(port))
107 		udelay(100);
108 
109 	ufcon = rd_regl(port, S3C2410_UFCON);
110 	ufcon |= S3C2410_UFCON_RESETRX;
111 	wr_regl(port, S3C2410_UFCON, ufcon);
112 
113 	ucon = rd_regl(port, S3C2410_UCON);
114 	ucon |= S3C2410_UCON_RXIRQMODE;
115 	wr_regl(port, S3C2410_UCON, ucon);
116 
117 	rx_enabled(port) = 1;
118 	spin_unlock_irqrestore(&port->lock, flags);
119 }
120 
s3c24xx_serial_rx_disable(struct uart_port * port)121 static void s3c24xx_serial_rx_disable(struct uart_port *port)
122 {
123 	unsigned long flags;
124 	unsigned int ucon;
125 
126 	spin_lock_irqsave(&port->lock, flags);
127 
128 	ucon = rd_regl(port, S3C2410_UCON);
129 	ucon &= ~S3C2410_UCON_RXIRQMODE;
130 	wr_regl(port, S3C2410_UCON, ucon);
131 
132 	rx_enabled(port) = 0;
133 	spin_unlock_irqrestore(&port->lock, flags);
134 }
135 
s3c24xx_serial_stop_tx(struct uart_port * port)136 static void s3c24xx_serial_stop_tx(struct uart_port *port)
137 {
138 	struct s3c24xx_uart_port *ourport = to_ourport(port);
139 
140 	if (tx_enabled(port)) {
141 		if (s3c24xx_serial_has_interrupt_mask(port))
142 			__set_bit(S3C64XX_UINTM_TXD,
143 				portaddrl(port, S3C64XX_UINTM));
144 		else
145 			disable_irq_nosync(ourport->tx_irq);
146 		tx_enabled(port) = 0;
147 		if (port->flags & UPF_CONS_FLOW)
148 			s3c24xx_serial_rx_enable(port);
149 	}
150 }
151 
s3c24xx_serial_start_tx(struct uart_port * port)152 static void s3c24xx_serial_start_tx(struct uart_port *port)
153 {
154 	struct s3c24xx_uart_port *ourport = to_ourport(port);
155 
156 	if (!tx_enabled(port)) {
157 		if (port->flags & UPF_CONS_FLOW)
158 			s3c24xx_serial_rx_disable(port);
159 
160 		if (s3c24xx_serial_has_interrupt_mask(port))
161 			__clear_bit(S3C64XX_UINTM_TXD,
162 				portaddrl(port, S3C64XX_UINTM));
163 		else
164 			enable_irq(ourport->tx_irq);
165 		tx_enabled(port) = 1;
166 	}
167 }
168 
s3c24xx_serial_stop_rx(struct uart_port * port)169 static void s3c24xx_serial_stop_rx(struct uart_port *port)
170 {
171 	struct s3c24xx_uart_port *ourport = to_ourport(port);
172 
173 	if (rx_enabled(port)) {
174 		dbg("s3c24xx_serial_stop_rx: port=%p\n", port);
175 		if (s3c24xx_serial_has_interrupt_mask(port))
176 			__set_bit(S3C64XX_UINTM_RXD,
177 				portaddrl(port, S3C64XX_UINTM));
178 		else
179 			disable_irq_nosync(ourport->rx_irq);
180 		rx_enabled(port) = 0;
181 	}
182 }
183 
s3c24xx_serial_enable_ms(struct uart_port * port)184 static void s3c24xx_serial_enable_ms(struct uart_port *port)
185 {
186 }
187 
s3c24xx_port_to_info(struct uart_port * port)188 static inline struct s3c24xx_uart_info *s3c24xx_port_to_info(struct uart_port *port)
189 {
190 	return to_ourport(port)->info;
191 }
192 
s3c24xx_port_to_cfg(struct uart_port * port)193 static inline struct s3c2410_uartcfg *s3c24xx_port_to_cfg(struct uart_port *port)
194 {
195 	struct s3c24xx_uart_port *ourport;
196 
197 	if (port->dev == NULL)
198 		return NULL;
199 
200 	ourport = container_of(port, struct s3c24xx_uart_port, port);
201 	return ourport->cfg;
202 }
203 
s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port * ourport,unsigned long ufstat)204 static int s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port *ourport,
205 				     unsigned long ufstat)
206 {
207 	struct s3c24xx_uart_info *info = ourport->info;
208 
209 	if (ufstat & info->rx_fifofull)
210 		return ourport->port.fifosize;
211 
212 	return (ufstat & info->rx_fifomask) >> info->rx_fifoshift;
213 }
214 
215 
216 /* ? - where has parity gone?? */
217 #define S3C2410_UERSTAT_PARITY (0x1000)
218 
219 static irqreturn_t
s3c24xx_serial_rx_chars(int irq,void * dev_id)220 s3c24xx_serial_rx_chars(int irq, void *dev_id)
221 {
222 	struct s3c24xx_uart_port *ourport = dev_id;
223 	struct uart_port *port = &ourport->port;
224 	struct tty_struct *tty = port->state->port.tty;
225 	unsigned int ufcon, ch, flag, ufstat, uerstat;
226 	int max_count = 64;
227 
228 	while (max_count-- > 0) {
229 		ufcon = rd_regl(port, S3C2410_UFCON);
230 		ufstat = rd_regl(port, S3C2410_UFSTAT);
231 
232 		if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0)
233 			break;
234 
235 		uerstat = rd_regl(port, S3C2410_UERSTAT);
236 		ch = rd_regb(port, S3C2410_URXH);
237 
238 		if (port->flags & UPF_CONS_FLOW) {
239 			int txe = s3c24xx_serial_txempty_nofifo(port);
240 
241 			if (rx_enabled(port)) {
242 				if (!txe) {
243 					rx_enabled(port) = 0;
244 					continue;
245 				}
246 			} else {
247 				if (txe) {
248 					ufcon |= S3C2410_UFCON_RESETRX;
249 					wr_regl(port, S3C2410_UFCON, ufcon);
250 					rx_enabled(port) = 1;
251 					goto out;
252 				}
253 				continue;
254 			}
255 		}
256 
257 		/* insert the character into the buffer */
258 
259 		flag = TTY_NORMAL;
260 		port->icount.rx++;
261 
262 		if (unlikely(uerstat & S3C2410_UERSTAT_ANY)) {
263 			dbg("rxerr: port ch=0x%02x, rxs=0x%08x\n",
264 			    ch, uerstat);
265 
266 			/* check for break */
267 			if (uerstat & S3C2410_UERSTAT_BREAK) {
268 				dbg("break!\n");
269 				port->icount.brk++;
270 				if (uart_handle_break(port))
271 				    goto ignore_char;
272 			}
273 
274 			if (uerstat & S3C2410_UERSTAT_FRAME)
275 				port->icount.frame++;
276 			if (uerstat & S3C2410_UERSTAT_OVERRUN)
277 				port->icount.overrun++;
278 
279 			uerstat &= port->read_status_mask;
280 
281 			if (uerstat & S3C2410_UERSTAT_BREAK)
282 				flag = TTY_BREAK;
283 			else if (uerstat & S3C2410_UERSTAT_PARITY)
284 				flag = TTY_PARITY;
285 			else if (uerstat & (S3C2410_UERSTAT_FRAME |
286 					    S3C2410_UERSTAT_OVERRUN))
287 				flag = TTY_FRAME;
288 		}
289 
290 		if (uart_handle_sysrq_char(port, ch))
291 			goto ignore_char;
292 
293 		uart_insert_char(port, uerstat, S3C2410_UERSTAT_OVERRUN,
294 				 ch, flag);
295 
296  ignore_char:
297 		continue;
298 	}
299 	tty_flip_buffer_push(tty);
300 
301  out:
302 	return IRQ_HANDLED;
303 }
304 
s3c24xx_serial_tx_chars(int irq,void * id)305 static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
306 {
307 	struct s3c24xx_uart_port *ourport = id;
308 	struct uart_port *port = &ourport->port;
309 	struct circ_buf *xmit = &port->state->xmit;
310 	int count = 256;
311 
312 	if (port->x_char) {
313 		wr_regb(port, S3C2410_UTXH, port->x_char);
314 		port->icount.tx++;
315 		port->x_char = 0;
316 		goto out;
317 	}
318 
319 	/* if there isn't anything more to transmit, or the uart is now
320 	 * stopped, disable the uart and exit
321 	*/
322 
323 	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
324 		s3c24xx_serial_stop_tx(port);
325 		goto out;
326 	}
327 
328 	/* try and drain the buffer... */
329 
330 	while (!uart_circ_empty(xmit) && count-- > 0) {
331 		if (rd_regl(port, S3C2410_UFSTAT) & ourport->info->tx_fifofull)
332 			break;
333 
334 		wr_regb(port, S3C2410_UTXH, xmit->buf[xmit->tail]);
335 		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
336 		port->icount.tx++;
337 	}
338 
339 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
340 		uart_write_wakeup(port);
341 
342 	if (uart_circ_empty(xmit))
343 		s3c24xx_serial_stop_tx(port);
344 
345  out:
346 	return IRQ_HANDLED;
347 }
348 
349 /* interrupt handler for s3c64xx and later SoC's.*/
s3c64xx_serial_handle_irq(int irq,void * id)350 static irqreturn_t s3c64xx_serial_handle_irq(int irq, void *id)
351 {
352 	struct s3c24xx_uart_port *ourport = id;
353 	struct uart_port *port = &ourport->port;
354 	unsigned int pend = rd_regl(port, S3C64XX_UINTP);
355 	unsigned long flags;
356 	irqreturn_t ret = IRQ_HANDLED;
357 
358 	spin_lock_irqsave(&port->lock, flags);
359 	if (pend & S3C64XX_UINTM_RXD_MSK) {
360 		ret = s3c24xx_serial_rx_chars(irq, id);
361 		wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_RXD_MSK);
362 	}
363 	if (pend & S3C64XX_UINTM_TXD_MSK) {
364 		ret = s3c24xx_serial_tx_chars(irq, id);
365 		wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_TXD_MSK);
366 	}
367 	spin_unlock_irqrestore(&port->lock, flags);
368 	return ret;
369 }
370 
s3c24xx_serial_tx_empty(struct uart_port * port)371 static unsigned int s3c24xx_serial_tx_empty(struct uart_port *port)
372 {
373 	struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
374 	unsigned long ufstat = rd_regl(port, S3C2410_UFSTAT);
375 	unsigned long ufcon = rd_regl(port, S3C2410_UFCON);
376 
377 	if (ufcon & S3C2410_UFCON_FIFOMODE) {
378 		if ((ufstat & info->tx_fifomask) != 0 ||
379 		    (ufstat & info->tx_fifofull))
380 			return 0;
381 
382 		return 1;
383 	}
384 
385 	return s3c24xx_serial_txempty_nofifo(port);
386 }
387 
388 /* no modem control lines */
s3c24xx_serial_get_mctrl(struct uart_port * port)389 static unsigned int s3c24xx_serial_get_mctrl(struct uart_port *port)
390 {
391 	unsigned int umstat = rd_regb(port, S3C2410_UMSTAT);
392 
393 	if (umstat & S3C2410_UMSTAT_CTS)
394 		return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
395 	else
396 		return TIOCM_CAR | TIOCM_DSR;
397 }
398 
s3c24xx_serial_set_mctrl(struct uart_port * port,unsigned int mctrl)399 static void s3c24xx_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
400 {
401 	/* todo - possibly remove AFC and do manual CTS */
402 }
403 
s3c24xx_serial_break_ctl(struct uart_port * port,int break_state)404 static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state)
405 {
406 	unsigned long flags;
407 	unsigned int ucon;
408 
409 	spin_lock_irqsave(&port->lock, flags);
410 
411 	ucon = rd_regl(port, S3C2410_UCON);
412 
413 	if (break_state)
414 		ucon |= S3C2410_UCON_SBREAK;
415 	else
416 		ucon &= ~S3C2410_UCON_SBREAK;
417 
418 	wr_regl(port, S3C2410_UCON, ucon);
419 
420 	spin_unlock_irqrestore(&port->lock, flags);
421 }
422 
s3c24xx_serial_shutdown(struct uart_port * port)423 static void s3c24xx_serial_shutdown(struct uart_port *port)
424 {
425 	struct s3c24xx_uart_port *ourport = to_ourport(port);
426 
427 	if (ourport->tx_claimed) {
428 		if (!s3c24xx_serial_has_interrupt_mask(port))
429 			free_irq(ourport->tx_irq, ourport);
430 		tx_enabled(port) = 0;
431 		ourport->tx_claimed = 0;
432 	}
433 
434 	if (ourport->rx_claimed) {
435 		if (!s3c24xx_serial_has_interrupt_mask(port))
436 			free_irq(ourport->rx_irq, ourport);
437 		ourport->rx_claimed = 0;
438 		rx_enabled(port) = 0;
439 	}
440 
441 	/* Clear pending interrupts and mask all interrupts */
442 	if (s3c24xx_serial_has_interrupt_mask(port)) {
443 		wr_regl(port, S3C64XX_UINTP, 0xf);
444 		wr_regl(port, S3C64XX_UINTM, 0xf);
445 	}
446 }
447 
s3c24xx_serial_startup(struct uart_port * port)448 static int s3c24xx_serial_startup(struct uart_port *port)
449 {
450 	struct s3c24xx_uart_port *ourport = to_ourport(port);
451 	int ret;
452 
453 	dbg("s3c24xx_serial_startup: port=%p (%08lx,%p)\n",
454 	    port->mapbase, port->membase);
455 
456 	rx_enabled(port) = 1;
457 
458 	ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_chars, 0,
459 			  s3c24xx_serial_portname(port), ourport);
460 
461 	if (ret != 0) {
462 		printk(KERN_ERR "cannot get irq %d\n", ourport->rx_irq);
463 		return ret;
464 	}
465 
466 	ourport->rx_claimed = 1;
467 
468 	dbg("requesting tx irq...\n");
469 
470 	tx_enabled(port) = 1;
471 
472 	ret = request_irq(ourport->tx_irq, s3c24xx_serial_tx_chars, 0,
473 			  s3c24xx_serial_portname(port), ourport);
474 
475 	if (ret) {
476 		printk(KERN_ERR "cannot get irq %d\n", ourport->tx_irq);
477 		goto err;
478 	}
479 
480 	ourport->tx_claimed = 1;
481 
482 	dbg("s3c24xx_serial_startup ok\n");
483 
484 	/* the port reset code should have done the correct
485 	 * register setup for the port controls */
486 
487 	return ret;
488 
489  err:
490 	s3c24xx_serial_shutdown(port);
491 	return ret;
492 }
493 
s3c64xx_serial_startup(struct uart_port * port)494 static int s3c64xx_serial_startup(struct uart_port *port)
495 {
496 	struct s3c24xx_uart_port *ourport = to_ourport(port);
497 	int ret;
498 
499 	dbg("s3c64xx_serial_startup: port=%p (%08lx,%p)\n",
500 	    port->mapbase, port->membase);
501 
502 	ret = request_irq(port->irq, s3c64xx_serial_handle_irq, IRQF_SHARED,
503 			  s3c24xx_serial_portname(port), ourport);
504 	if (ret) {
505 		printk(KERN_ERR "cannot get irq %d\n", port->irq);
506 		return ret;
507 	}
508 
509 	/* For compatibility with s3c24xx Soc's */
510 	rx_enabled(port) = 1;
511 	ourport->rx_claimed = 1;
512 	tx_enabled(port) = 0;
513 	ourport->tx_claimed = 1;
514 
515 	/* Enable Rx Interrupt */
516 	__clear_bit(S3C64XX_UINTM_RXD, portaddrl(port, S3C64XX_UINTM));
517 	dbg("s3c64xx_serial_startup ok\n");
518 	return ret;
519 }
520 
521 /* power power management control */
522 
s3c24xx_serial_pm(struct uart_port * port,unsigned int level,unsigned int old)523 static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
524 			      unsigned int old)
525 {
526 	struct s3c24xx_uart_port *ourport = to_ourport(port);
527 
528 	ourport->pm_level = level;
529 
530 	switch (level) {
531 	case 3:
532 		if (!IS_ERR(ourport->baudclk) && ourport->baudclk != NULL)
533 			clk_disable(ourport->baudclk);
534 
535 		clk_disable(ourport->clk);
536 		break;
537 
538 	case 0:
539 		clk_enable(ourport->clk);
540 
541 		if (!IS_ERR(ourport->baudclk) && ourport->baudclk != NULL)
542 			clk_enable(ourport->baudclk);
543 
544 		break;
545 	default:
546 		printk(KERN_ERR "s3c24xx_serial: unknown pm %d\n", level);
547 	}
548 }
549 
550 /* baud rate calculation
551  *
552  * The UARTs on the S3C2410/S3C2440 can take their clocks from a number
553  * of different sources, including the peripheral clock ("pclk") and an
554  * external clock ("uclk"). The S3C2440 also adds the core clock ("fclk")
555  * with a programmable extra divisor.
556  *
557  * The following code goes through the clock sources, and calculates the
558  * baud clocks (and the resultant actual baud rates) and then tries to
559  * pick the closest one and select that.
560  *
561 */
562 
563 #define MAX_CLK_NAME_LENGTH 15
564 
s3c24xx_serial_getsource(struct uart_port * port)565 static inline int s3c24xx_serial_getsource(struct uart_port *port)
566 {
567 	struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
568 	unsigned int ucon;
569 
570 	if (info->num_clks == 1)
571 		return 0;
572 
573 	ucon = rd_regl(port, S3C2410_UCON);
574 	ucon &= info->clksel_mask;
575 	return ucon >> info->clksel_shift;
576 }
577 
s3c24xx_serial_setsource(struct uart_port * port,unsigned int clk_sel)578 static void s3c24xx_serial_setsource(struct uart_port *port,
579 			unsigned int clk_sel)
580 {
581 	struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
582 	unsigned int ucon;
583 
584 	if (info->num_clks == 1)
585 		return;
586 
587 	ucon = rd_regl(port, S3C2410_UCON);
588 	if ((ucon & info->clksel_mask) >> info->clksel_shift == clk_sel)
589 		return;
590 
591 	ucon &= ~info->clksel_mask;
592 	ucon |= clk_sel << info->clksel_shift;
593 	wr_regl(port, S3C2410_UCON, ucon);
594 }
595 
s3c24xx_serial_getclk(struct s3c24xx_uart_port * ourport,unsigned int req_baud,struct clk ** best_clk,unsigned int * clk_num)596 static unsigned int s3c24xx_serial_getclk(struct s3c24xx_uart_port *ourport,
597 			unsigned int req_baud, struct clk **best_clk,
598 			unsigned int *clk_num)
599 {
600 	struct s3c24xx_uart_info *info = ourport->info;
601 	struct clk *clk;
602 	unsigned long rate;
603 	unsigned int cnt, baud, quot, clk_sel, best_quot = 0;
604 	char clkname[MAX_CLK_NAME_LENGTH];
605 	int calc_deviation, deviation = (1 << 30) - 1;
606 
607 	*best_clk = NULL;
608 	clk_sel = (ourport->cfg->clk_sel) ? ourport->cfg->clk_sel :
609 			ourport->info->def_clk_sel;
610 	for (cnt = 0; cnt < info->num_clks; cnt++) {
611 		if (!(clk_sel & (1 << cnt)))
612 			continue;
613 
614 		sprintf(clkname, "clk_uart_baud%d", cnt);
615 		clk = clk_get(ourport->port.dev, clkname);
616 		if (IS_ERR_OR_NULL(clk))
617 			continue;
618 
619 		rate = clk_get_rate(clk);
620 		if (!rate)
621 			continue;
622 
623 		if (ourport->info->has_divslot) {
624 			unsigned long div = rate / req_baud;
625 
626 			/* The UDIVSLOT register on the newer UARTs allows us to
627 			 * get a divisor adjustment of 1/16th on the baud clock.
628 			 *
629 			 * We don't keep the UDIVSLOT value (the 16ths we
630 			 * calculated by not multiplying the baud by 16) as it
631 			 * is easy enough to recalculate.
632 			 */
633 
634 			quot = div / 16;
635 			baud = rate / div;
636 		} else {
637 			quot = (rate + (8 * req_baud)) / (16 * req_baud);
638 			baud = rate / (quot * 16);
639 		}
640 		quot--;
641 
642 		calc_deviation = req_baud - baud;
643 		if (calc_deviation < 0)
644 			calc_deviation = -calc_deviation;
645 
646 		if (calc_deviation < deviation) {
647 			*best_clk = clk;
648 			best_quot = quot;
649 			*clk_num = cnt;
650 			deviation = calc_deviation;
651 		}
652 	}
653 
654 	return best_quot;
655 }
656 
657 /* udivslot_table[]
658  *
659  * This table takes the fractional value of the baud divisor and gives
660  * the recommended setting for the UDIVSLOT register.
661  */
662 static u16 udivslot_table[16] = {
663 	[0] = 0x0000,
664 	[1] = 0x0080,
665 	[2] = 0x0808,
666 	[3] = 0x0888,
667 	[4] = 0x2222,
668 	[5] = 0x4924,
669 	[6] = 0x4A52,
670 	[7] = 0x54AA,
671 	[8] = 0x5555,
672 	[9] = 0xD555,
673 	[10] = 0xD5D5,
674 	[11] = 0xDDD5,
675 	[12] = 0xDDDD,
676 	[13] = 0xDFDD,
677 	[14] = 0xDFDF,
678 	[15] = 0xFFDF,
679 };
680 
s3c24xx_serial_set_termios(struct uart_port * port,struct ktermios * termios,struct ktermios * old)681 static void s3c24xx_serial_set_termios(struct uart_port *port,
682 				       struct ktermios *termios,
683 				       struct ktermios *old)
684 {
685 	struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
686 	struct s3c24xx_uart_port *ourport = to_ourport(port);
687 	struct clk *clk = NULL;
688 	unsigned long flags;
689 	unsigned int baud, quot, clk_sel = 0;
690 	unsigned int ulcon;
691 	unsigned int umcon;
692 	unsigned int udivslot = 0;
693 
694 	/*
695 	 * We don't support modem control lines.
696 	 */
697 	termios->c_cflag &= ~(HUPCL | CMSPAR);
698 	termios->c_cflag |= CLOCAL;
699 
700 	/*
701 	 * Ask the core to calculate the divisor for us.
702 	 */
703 
704 	baud = uart_get_baud_rate(port, termios, old, 0, 115200*8);
705 	quot = s3c24xx_serial_getclk(ourport, baud, &clk, &clk_sel);
706 	if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
707 		quot = port->custom_divisor;
708 	if (!clk)
709 		return;
710 
711 	/* check to see if we need  to change clock source */
712 
713 	if (ourport->baudclk != clk) {
714 		s3c24xx_serial_setsource(port, clk_sel);
715 
716 		if (ourport->baudclk != NULL && !IS_ERR(ourport->baudclk)) {
717 			clk_disable(ourport->baudclk);
718 			ourport->baudclk  = NULL;
719 		}
720 
721 		clk_enable(clk);
722 
723 		ourport->baudclk = clk;
724 		ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0;
725 	}
726 
727 	if (ourport->info->has_divslot) {
728 		unsigned int div = ourport->baudclk_rate / baud;
729 
730 		if (cfg->has_fracval) {
731 			udivslot = (div & 15);
732 			dbg("fracval = %04x\n", udivslot);
733 		} else {
734 			udivslot = udivslot_table[div & 15];
735 			dbg("udivslot = %04x (div %d)\n", udivslot, div & 15);
736 		}
737 	}
738 
739 	switch (termios->c_cflag & CSIZE) {
740 	case CS5:
741 		dbg("config: 5bits/char\n");
742 		ulcon = S3C2410_LCON_CS5;
743 		break;
744 	case CS6:
745 		dbg("config: 6bits/char\n");
746 		ulcon = S3C2410_LCON_CS6;
747 		break;
748 	case CS7:
749 		dbg("config: 7bits/char\n");
750 		ulcon = S3C2410_LCON_CS7;
751 		break;
752 	case CS8:
753 	default:
754 		dbg("config: 8bits/char\n");
755 		ulcon = S3C2410_LCON_CS8;
756 		break;
757 	}
758 
759 	/* preserve original lcon IR settings */
760 	ulcon |= (cfg->ulcon & S3C2410_LCON_IRM);
761 
762 	if (termios->c_cflag & CSTOPB)
763 		ulcon |= S3C2410_LCON_STOPB;
764 
765 	umcon = (termios->c_cflag & CRTSCTS) ? S3C2410_UMCOM_AFC : 0;
766 
767 	if (termios->c_cflag & PARENB) {
768 		if (termios->c_cflag & PARODD)
769 			ulcon |= S3C2410_LCON_PODD;
770 		else
771 			ulcon |= S3C2410_LCON_PEVEN;
772 	} else {
773 		ulcon |= S3C2410_LCON_PNONE;
774 	}
775 
776 	spin_lock_irqsave(&port->lock, flags);
777 
778 	dbg("setting ulcon to %08x, brddiv to %d, udivslot %08x\n",
779 	    ulcon, quot, udivslot);
780 
781 	wr_regl(port, S3C2410_ULCON, ulcon);
782 	wr_regl(port, S3C2410_UBRDIV, quot);
783 	wr_regl(port, S3C2410_UMCON, umcon);
784 
785 	if (ourport->info->has_divslot)
786 		wr_regl(port, S3C2443_DIVSLOT, udivslot);
787 
788 	dbg("uart: ulcon = 0x%08x, ucon = 0x%08x, ufcon = 0x%08x\n",
789 	    rd_regl(port, S3C2410_ULCON),
790 	    rd_regl(port, S3C2410_UCON),
791 	    rd_regl(port, S3C2410_UFCON));
792 
793 	/*
794 	 * Update the per-port timeout.
795 	 */
796 	uart_update_timeout(port, termios->c_cflag, baud);
797 
798 	/*
799 	 * Which character status flags are we interested in?
800 	 */
801 	port->read_status_mask = S3C2410_UERSTAT_OVERRUN;
802 	if (termios->c_iflag & INPCK)
803 		port->read_status_mask |= S3C2410_UERSTAT_FRAME | S3C2410_UERSTAT_PARITY;
804 
805 	/*
806 	 * Which character status flags should we ignore?
807 	 */
808 	port->ignore_status_mask = 0;
809 	if (termios->c_iflag & IGNPAR)
810 		port->ignore_status_mask |= S3C2410_UERSTAT_OVERRUN;
811 	if (termios->c_iflag & IGNBRK && termios->c_iflag & IGNPAR)
812 		port->ignore_status_mask |= S3C2410_UERSTAT_FRAME;
813 
814 	/*
815 	 * Ignore all characters if CREAD is not set.
816 	 */
817 	if ((termios->c_cflag & CREAD) == 0)
818 		port->ignore_status_mask |= RXSTAT_DUMMY_READ;
819 
820 	spin_unlock_irqrestore(&port->lock, flags);
821 }
822 
s3c24xx_serial_type(struct uart_port * port)823 static const char *s3c24xx_serial_type(struct uart_port *port)
824 {
825 	switch (port->type) {
826 	case PORT_S3C2410:
827 		return "S3C2410";
828 	case PORT_S3C2440:
829 		return "S3C2440";
830 	case PORT_S3C2412:
831 		return "S3C2412";
832 	case PORT_S3C6400:
833 		return "S3C6400/10";
834 	default:
835 		return NULL;
836 	}
837 }
838 
839 #define MAP_SIZE (0x100)
840 
s3c24xx_serial_release_port(struct uart_port * port)841 static void s3c24xx_serial_release_port(struct uart_port *port)
842 {
843 	release_mem_region(port->mapbase, MAP_SIZE);
844 }
845 
s3c24xx_serial_request_port(struct uart_port * port)846 static int s3c24xx_serial_request_port(struct uart_port *port)
847 {
848 	const char *name = s3c24xx_serial_portname(port);
849 	return request_mem_region(port->mapbase, MAP_SIZE, name) ? 0 : -EBUSY;
850 }
851 
s3c24xx_serial_config_port(struct uart_port * port,int flags)852 static void s3c24xx_serial_config_port(struct uart_port *port, int flags)
853 {
854 	struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
855 
856 	if (flags & UART_CONFIG_TYPE &&
857 	    s3c24xx_serial_request_port(port) == 0)
858 		port->type = info->type;
859 }
860 
861 /*
862  * verify the new serial_struct (for TIOCSSERIAL).
863  */
864 static int
s3c24xx_serial_verify_port(struct uart_port * port,struct serial_struct * ser)865 s3c24xx_serial_verify_port(struct uart_port *port, struct serial_struct *ser)
866 {
867 	struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
868 
869 	if (ser->type != PORT_UNKNOWN && ser->type != info->type)
870 		return -EINVAL;
871 
872 	return 0;
873 }
874 
875 
876 #ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
877 
878 static struct console s3c24xx_serial_console;
879 
880 #define S3C24XX_SERIAL_CONSOLE &s3c24xx_serial_console
881 #else
882 #define S3C24XX_SERIAL_CONSOLE NULL
883 #endif
884 
885 static struct uart_ops s3c24xx_serial_ops = {
886 	.pm		= s3c24xx_serial_pm,
887 	.tx_empty	= s3c24xx_serial_tx_empty,
888 	.get_mctrl	= s3c24xx_serial_get_mctrl,
889 	.set_mctrl	= s3c24xx_serial_set_mctrl,
890 	.stop_tx	= s3c24xx_serial_stop_tx,
891 	.start_tx	= s3c24xx_serial_start_tx,
892 	.stop_rx	= s3c24xx_serial_stop_rx,
893 	.enable_ms	= s3c24xx_serial_enable_ms,
894 	.break_ctl	= s3c24xx_serial_break_ctl,
895 	.startup	= s3c24xx_serial_startup,
896 	.shutdown	= s3c24xx_serial_shutdown,
897 	.set_termios	= s3c24xx_serial_set_termios,
898 	.type		= s3c24xx_serial_type,
899 	.release_port	= s3c24xx_serial_release_port,
900 	.request_port	= s3c24xx_serial_request_port,
901 	.config_port	= s3c24xx_serial_config_port,
902 	.verify_port	= s3c24xx_serial_verify_port,
903 };
904 
905 static struct uart_driver s3c24xx_uart_drv = {
906 	.owner		= THIS_MODULE,
907 	.driver_name	= "s3c2410_serial",
908 	.nr		= CONFIG_SERIAL_SAMSUNG_UARTS,
909 	.cons		= S3C24XX_SERIAL_CONSOLE,
910 	.dev_name	= S3C24XX_SERIAL_NAME,
911 	.major		= S3C24XX_SERIAL_MAJOR,
912 	.minor		= S3C24XX_SERIAL_MINOR,
913 };
914 
915 static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS] = {
916 	[0] = {
917 		.port = {
918 			.lock		= __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock),
919 			.iotype		= UPIO_MEM,
920 			.uartclk	= 0,
921 			.fifosize	= 16,
922 			.ops		= &s3c24xx_serial_ops,
923 			.flags		= UPF_BOOT_AUTOCONF,
924 			.line		= 0,
925 		}
926 	},
927 	[1] = {
928 		.port = {
929 			.lock		= __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[1].port.lock),
930 			.iotype		= UPIO_MEM,
931 			.uartclk	= 0,
932 			.fifosize	= 16,
933 			.ops		= &s3c24xx_serial_ops,
934 			.flags		= UPF_BOOT_AUTOCONF,
935 			.line		= 1,
936 		}
937 	},
938 #if CONFIG_SERIAL_SAMSUNG_UARTS > 2
939 
940 	[2] = {
941 		.port = {
942 			.lock		= __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[2].port.lock),
943 			.iotype		= UPIO_MEM,
944 			.uartclk	= 0,
945 			.fifosize	= 16,
946 			.ops		= &s3c24xx_serial_ops,
947 			.flags		= UPF_BOOT_AUTOCONF,
948 			.line		= 2,
949 		}
950 	},
951 #endif
952 #if CONFIG_SERIAL_SAMSUNG_UARTS > 3
953 	[3] = {
954 		.port = {
955 			.lock		= __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[3].port.lock),
956 			.iotype		= UPIO_MEM,
957 			.uartclk	= 0,
958 			.fifosize	= 16,
959 			.ops		= &s3c24xx_serial_ops,
960 			.flags		= UPF_BOOT_AUTOCONF,
961 			.line		= 3,
962 		}
963 	}
964 #endif
965 };
966 
967 /* s3c24xx_serial_resetport
968  *
969  * reset the fifos and other the settings.
970 */
971 
s3c24xx_serial_resetport(struct uart_port * port,struct s3c2410_uartcfg * cfg)972 static void s3c24xx_serial_resetport(struct uart_port *port,
973 				   struct s3c2410_uartcfg *cfg)
974 {
975 	struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
976 	unsigned long ucon = rd_regl(port, S3C2410_UCON);
977 	unsigned int ucon_mask;
978 
979 	ucon_mask = info->clksel_mask;
980 	if (info->type == PORT_S3C2440)
981 		ucon_mask |= S3C2440_UCON0_DIVMASK;
982 
983 	ucon &= ucon_mask;
984 	wr_regl(port, S3C2410_UCON,  ucon | cfg->ucon);
985 
986 	/* reset both fifos */
987 	wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
988 	wr_regl(port, S3C2410_UFCON, cfg->ufcon);
989 
990 	/* some delay is required after fifo reset */
991 	udelay(1);
992 }
993 
994 
995 #ifdef CONFIG_CPU_FREQ
996 
s3c24xx_serial_cpufreq_transition(struct notifier_block * nb,unsigned long val,void * data)997 static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb,
998 					     unsigned long val, void *data)
999 {
1000 	struct s3c24xx_uart_port *port;
1001 	struct uart_port *uport;
1002 
1003 	port = container_of(nb, struct s3c24xx_uart_port, freq_transition);
1004 	uport = &port->port;
1005 
1006 	/* check to see if port is enabled */
1007 
1008 	if (port->pm_level != 0)
1009 		return 0;
1010 
1011 	/* try and work out if the baudrate is changing, we can detect
1012 	 * a change in rate, but we do not have support for detecting
1013 	 * a disturbance in the clock-rate over the change.
1014 	 */
1015 
1016 	if (IS_ERR(port->clk))
1017 		goto exit;
1018 
1019 	if (port->baudclk_rate == clk_get_rate(port->clk))
1020 		goto exit;
1021 
1022 	if (val == CPUFREQ_PRECHANGE) {
1023 		/* we should really shut the port down whilst the
1024 		 * frequency change is in progress. */
1025 
1026 	} else if (val == CPUFREQ_POSTCHANGE) {
1027 		struct ktermios *termios;
1028 		struct tty_struct *tty;
1029 
1030 		if (uport->state == NULL)
1031 			goto exit;
1032 
1033 		tty = uport->state->port.tty;
1034 
1035 		if (tty == NULL)
1036 			goto exit;
1037 
1038 		termios = tty->termios;
1039 
1040 		if (termios == NULL) {
1041 			printk(KERN_WARNING "%s: no termios?\n", __func__);
1042 			goto exit;
1043 		}
1044 
1045 		s3c24xx_serial_set_termios(uport, termios, NULL);
1046 	}
1047 
1048  exit:
1049 	return 0;
1050 }
1051 
s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port * port)1052 static inline int s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port)
1053 {
1054 	port->freq_transition.notifier_call = s3c24xx_serial_cpufreq_transition;
1055 
1056 	return cpufreq_register_notifier(&port->freq_transition,
1057 					 CPUFREQ_TRANSITION_NOTIFIER);
1058 }
1059 
s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port * port)1060 static inline void s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port)
1061 {
1062 	cpufreq_unregister_notifier(&port->freq_transition,
1063 				    CPUFREQ_TRANSITION_NOTIFIER);
1064 }
1065 
1066 #else
s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port * port)1067 static inline int s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port)
1068 {
1069 	return 0;
1070 }
1071 
s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port * port)1072 static inline void s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port)
1073 {
1074 }
1075 #endif
1076 
1077 /* s3c24xx_serial_init_port
1078  *
1079  * initialise a single serial port from the platform device given
1080  */
1081 
s3c24xx_serial_init_port(struct s3c24xx_uart_port * ourport,struct platform_device * platdev)1082 static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
1083 				    struct platform_device *platdev)
1084 {
1085 	struct uart_port *port = &ourport->port;
1086 	struct s3c2410_uartcfg *cfg = ourport->cfg;
1087 	struct resource *res;
1088 	int ret;
1089 
1090 	dbg("s3c24xx_serial_init_port: port=%p, platdev=%p\n", port, platdev);
1091 
1092 	if (platdev == NULL)
1093 		return -ENODEV;
1094 
1095 	if (port->mapbase != 0)
1096 		return 0;
1097 
1098 	/* setup info for port */
1099 	port->dev	= &platdev->dev;
1100 
1101 	/* Startup sequence is different for s3c64xx and higher SoC's */
1102 	if (s3c24xx_serial_has_interrupt_mask(port))
1103 		s3c24xx_serial_ops.startup = s3c64xx_serial_startup;
1104 
1105 	port->uartclk = 1;
1106 
1107 	if (cfg->uart_flags & UPF_CONS_FLOW) {
1108 		dbg("s3c24xx_serial_init_port: enabling flow control\n");
1109 		port->flags |= UPF_CONS_FLOW;
1110 	}
1111 
1112 	/* sort our the physical and virtual addresses for each UART */
1113 
1114 	res = platform_get_resource(platdev, IORESOURCE_MEM, 0);
1115 	if (res == NULL) {
1116 		printk(KERN_ERR "failed to find memory resource for uart\n");
1117 		return -EINVAL;
1118 	}
1119 
1120 	dbg("resource %p (%lx..%lx)\n", res, res->start, res->end);
1121 
1122 	port->mapbase = res->start;
1123 	port->membase = S3C_VA_UART + (res->start & 0xfffff);
1124 	ret = platform_get_irq(platdev, 0);
1125 	if (ret < 0)
1126 		port->irq = 0;
1127 	else {
1128 		port->irq = ret;
1129 		ourport->rx_irq = ret;
1130 		ourport->tx_irq = ret + 1;
1131 	}
1132 
1133 	ret = platform_get_irq(platdev, 1);
1134 	if (ret > 0)
1135 		ourport->tx_irq = ret;
1136 
1137 	ourport->clk	= clk_get(&platdev->dev, "uart");
1138 
1139 	/* Keep all interrupts masked and cleared */
1140 	if (s3c24xx_serial_has_interrupt_mask(port)) {
1141 		wr_regl(port, S3C64XX_UINTM, 0xf);
1142 		wr_regl(port, S3C64XX_UINTP, 0xf);
1143 		wr_regl(port, S3C64XX_UINTSP, 0xf);
1144 	}
1145 
1146 	dbg("port: map=%08x, mem=%08x, irq=%d (%d,%d), clock=%ld\n",
1147 	    port->mapbase, port->membase, port->irq,
1148 	    ourport->rx_irq, ourport->tx_irq, port->uartclk);
1149 
1150 	/* reset the fifos (and setup the uart) */
1151 	s3c24xx_serial_resetport(port, cfg);
1152 	return 0;
1153 }
1154 
s3c24xx_serial_show_clksrc(struct device * dev,struct device_attribute * attr,char * buf)1155 static ssize_t s3c24xx_serial_show_clksrc(struct device *dev,
1156 					  struct device_attribute *attr,
1157 					  char *buf)
1158 {
1159 	struct uart_port *port = s3c24xx_dev_to_port(dev);
1160 	struct s3c24xx_uart_port *ourport = to_ourport(port);
1161 
1162 	return snprintf(buf, PAGE_SIZE, "* %s\n", ourport->baudclk->name);
1163 }
1164 
1165 static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL);
1166 
1167 
1168 /* Device driver serial port probe */
1169 
1170 static const struct of_device_id s3c24xx_uart_dt_match[];
1171 static int probe_index;
1172 
s3c24xx_get_driver_data(struct platform_device * pdev)1173 static inline struct s3c24xx_serial_drv_data *s3c24xx_get_driver_data(
1174 			struct platform_device *pdev)
1175 {
1176 #ifdef CONFIG_OF
1177 	if (pdev->dev.of_node) {
1178 		const struct of_device_id *match;
1179 		match = of_match_node(s3c24xx_uart_dt_match, pdev->dev.of_node);
1180 		return (struct s3c24xx_serial_drv_data *)match->data;
1181 	}
1182 #endif
1183 	return (struct s3c24xx_serial_drv_data *)
1184 			platform_get_device_id(pdev)->driver_data;
1185 }
1186 
s3c24xx_serial_probe(struct platform_device * pdev)1187 static int s3c24xx_serial_probe(struct platform_device *pdev)
1188 {
1189 	struct s3c24xx_uart_port *ourport;
1190 	int ret;
1191 
1192 	dbg("s3c24xx_serial_probe(%p) %d\n", pdev, probe_index);
1193 
1194 	ourport = &s3c24xx_serial_ports[probe_index];
1195 
1196 	ourport->drv_data = s3c24xx_get_driver_data(pdev);
1197 	if (!ourport->drv_data) {
1198 		dev_err(&pdev->dev, "could not find driver data\n");
1199 		return -ENODEV;
1200 	}
1201 
1202 	ourport->info = ourport->drv_data->info;
1203 	ourport->cfg = (pdev->dev.platform_data) ?
1204 			(struct s3c2410_uartcfg *)pdev->dev.platform_data :
1205 			ourport->drv_data->def_cfg;
1206 
1207 	ourport->port.fifosize = (ourport->info->fifosize) ?
1208 		ourport->info->fifosize :
1209 		ourport->drv_data->fifosize[probe_index];
1210 
1211 	probe_index++;
1212 
1213 	dbg("%s: initialising port %p...\n", __func__, ourport);
1214 
1215 	ret = s3c24xx_serial_init_port(ourport, pdev);
1216 	if (ret < 0)
1217 		goto probe_err;
1218 
1219 	dbg("%s: adding port\n", __func__);
1220 	uart_add_one_port(&s3c24xx_uart_drv, &ourport->port);
1221 	platform_set_drvdata(pdev, &ourport->port);
1222 
1223 	ret = device_create_file(&pdev->dev, &dev_attr_clock_source);
1224 	if (ret < 0)
1225 		dev_err(&pdev->dev, "failed to add clock source attr.\n");
1226 
1227 	ret = s3c24xx_serial_cpufreq_register(ourport);
1228 	if (ret < 0)
1229 		dev_err(&pdev->dev, "failed to add cpufreq notifier\n");
1230 
1231 	return 0;
1232 
1233  probe_err:
1234 	return ret;
1235 }
1236 
s3c24xx_serial_remove(struct platform_device * dev)1237 static int __devexit s3c24xx_serial_remove(struct platform_device *dev)
1238 {
1239 	struct uart_port *port = s3c24xx_dev_to_port(&dev->dev);
1240 
1241 	if (port) {
1242 		s3c24xx_serial_cpufreq_deregister(to_ourport(port));
1243 		device_remove_file(&dev->dev, &dev_attr_clock_source);
1244 		uart_remove_one_port(&s3c24xx_uart_drv, port);
1245 	}
1246 
1247 	return 0;
1248 }
1249 
1250 /* UART power management code */
1251 #ifdef CONFIG_PM_SLEEP
s3c24xx_serial_suspend(struct device * dev)1252 static int s3c24xx_serial_suspend(struct device *dev)
1253 {
1254 	struct uart_port *port = s3c24xx_dev_to_port(dev);
1255 
1256 	if (port)
1257 		uart_suspend_port(&s3c24xx_uart_drv, port);
1258 
1259 	return 0;
1260 }
1261 
s3c24xx_serial_resume(struct device * dev)1262 static int s3c24xx_serial_resume(struct device *dev)
1263 {
1264 	struct uart_port *port = s3c24xx_dev_to_port(dev);
1265 	struct s3c24xx_uart_port *ourport = to_ourport(port);
1266 
1267 	if (port) {
1268 		clk_enable(ourport->clk);
1269 		s3c24xx_serial_resetport(port, s3c24xx_port_to_cfg(port));
1270 		clk_disable(ourport->clk);
1271 
1272 		uart_resume_port(&s3c24xx_uart_drv, port);
1273 	}
1274 
1275 	return 0;
1276 }
1277 
1278 static const struct dev_pm_ops s3c24xx_serial_pm_ops = {
1279 	.suspend = s3c24xx_serial_suspend,
1280 	.resume = s3c24xx_serial_resume,
1281 };
1282 #define SERIAL_SAMSUNG_PM_OPS	(&s3c24xx_serial_pm_ops)
1283 
1284 #else /* !CONFIG_PM_SLEEP */
1285 
1286 #define SERIAL_SAMSUNG_PM_OPS	NULL
1287 #endif /* CONFIG_PM_SLEEP */
1288 
1289 /* Console code */
1290 
1291 #ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
1292 
1293 static struct uart_port *cons_uart;
1294 
1295 static int
s3c24xx_serial_console_txrdy(struct uart_port * port,unsigned int ufcon)1296 s3c24xx_serial_console_txrdy(struct uart_port *port, unsigned int ufcon)
1297 {
1298 	struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
1299 	unsigned long ufstat, utrstat;
1300 
1301 	if (ufcon & S3C2410_UFCON_FIFOMODE) {
1302 		/* fifo mode - check amount of data in fifo registers... */
1303 
1304 		ufstat = rd_regl(port, S3C2410_UFSTAT);
1305 		return (ufstat & info->tx_fifofull) ? 0 : 1;
1306 	}
1307 
1308 	/* in non-fifo mode, we go and use the tx buffer empty */
1309 
1310 	utrstat = rd_regl(port, S3C2410_UTRSTAT);
1311 	return (utrstat & S3C2410_UTRSTAT_TXE) ? 1 : 0;
1312 }
1313 
1314 static void
s3c24xx_serial_console_putchar(struct uart_port * port,int ch)1315 s3c24xx_serial_console_putchar(struct uart_port *port, int ch)
1316 {
1317 	unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON);
1318 	while (!s3c24xx_serial_console_txrdy(port, ufcon))
1319 		barrier();
1320 	wr_regb(cons_uart, S3C2410_UTXH, ch);
1321 }
1322 
1323 static void
s3c24xx_serial_console_write(struct console * co,const char * s,unsigned int count)1324 s3c24xx_serial_console_write(struct console *co, const char *s,
1325 			     unsigned int count)
1326 {
1327 	uart_console_write(cons_uart, s, count, s3c24xx_serial_console_putchar);
1328 }
1329 
1330 static void __init
s3c24xx_serial_get_options(struct uart_port * port,int * baud,int * parity,int * bits)1331 s3c24xx_serial_get_options(struct uart_port *port, int *baud,
1332 			   int *parity, int *bits)
1333 {
1334 	struct clk *clk;
1335 	unsigned int ulcon;
1336 	unsigned int ucon;
1337 	unsigned int ubrdiv;
1338 	unsigned long rate;
1339 	unsigned int clk_sel;
1340 	char clk_name[MAX_CLK_NAME_LENGTH];
1341 
1342 	ulcon  = rd_regl(port, S3C2410_ULCON);
1343 	ucon   = rd_regl(port, S3C2410_UCON);
1344 	ubrdiv = rd_regl(port, S3C2410_UBRDIV);
1345 
1346 	dbg("s3c24xx_serial_get_options: port=%p\n"
1347 	    "registers: ulcon=%08x, ucon=%08x, ubdriv=%08x\n",
1348 	    port, ulcon, ucon, ubrdiv);
1349 
1350 	if ((ucon & 0xf) != 0) {
1351 		/* consider the serial port configured if the tx/rx mode set */
1352 
1353 		switch (ulcon & S3C2410_LCON_CSMASK) {
1354 		case S3C2410_LCON_CS5:
1355 			*bits = 5;
1356 			break;
1357 		case S3C2410_LCON_CS6:
1358 			*bits = 6;
1359 			break;
1360 		case S3C2410_LCON_CS7:
1361 			*bits = 7;
1362 			break;
1363 		default:
1364 		case S3C2410_LCON_CS8:
1365 			*bits = 8;
1366 			break;
1367 		}
1368 
1369 		switch (ulcon & S3C2410_LCON_PMASK) {
1370 		case S3C2410_LCON_PEVEN:
1371 			*parity = 'e';
1372 			break;
1373 
1374 		case S3C2410_LCON_PODD:
1375 			*parity = 'o';
1376 			break;
1377 
1378 		case S3C2410_LCON_PNONE:
1379 		default:
1380 			*parity = 'n';
1381 		}
1382 
1383 		/* now calculate the baud rate */
1384 
1385 		clk_sel = s3c24xx_serial_getsource(port);
1386 		sprintf(clk_name, "clk_uart_baud%d", clk_sel);
1387 
1388 		clk = clk_get(port->dev, clk_name);
1389 		if (!IS_ERR(clk) && clk != NULL)
1390 			rate = clk_get_rate(clk);
1391 		else
1392 			rate = 1;
1393 
1394 		*baud = rate / (16 * (ubrdiv + 1));
1395 		dbg("calculated baud %d\n", *baud);
1396 	}
1397 
1398 }
1399 
1400 static int __init
s3c24xx_serial_console_setup(struct console * co,char * options)1401 s3c24xx_serial_console_setup(struct console *co, char *options)
1402 {
1403 	struct uart_port *port;
1404 	int baud = 9600;
1405 	int bits = 8;
1406 	int parity = 'n';
1407 	int flow = 'n';
1408 
1409 	dbg("s3c24xx_serial_console_setup: co=%p (%d), %s\n",
1410 	    co, co->index, options);
1411 
1412 	/* is this a valid port */
1413 
1414 	if (co->index == -1 || co->index >= CONFIG_SERIAL_SAMSUNG_UARTS)
1415 		co->index = 0;
1416 
1417 	port = &s3c24xx_serial_ports[co->index].port;
1418 
1419 	/* is the port configured? */
1420 
1421 	if (port->mapbase == 0x0)
1422 		return -ENODEV;
1423 
1424 	cons_uart = port;
1425 
1426 	dbg("s3c24xx_serial_console_setup: port=%p (%d)\n", port, co->index);
1427 
1428 	/*
1429 	 * Check whether an invalid uart number has been specified, and
1430 	 * if so, search for the first available port that does have
1431 	 * console support.
1432 	 */
1433 	if (options)
1434 		uart_parse_options(options, &baud, &parity, &bits, &flow);
1435 	else
1436 		s3c24xx_serial_get_options(port, &baud, &parity, &bits);
1437 
1438 	dbg("s3c24xx_serial_console_setup: baud %d\n", baud);
1439 
1440 	return uart_set_options(port, co, baud, parity, bits, flow);
1441 }
1442 
1443 static struct console s3c24xx_serial_console = {
1444 	.name		= S3C24XX_SERIAL_NAME,
1445 	.device		= uart_console_device,
1446 	.flags		= CON_PRINTBUFFER,
1447 	.index		= -1,
1448 	.write		= s3c24xx_serial_console_write,
1449 	.setup		= s3c24xx_serial_console_setup,
1450 	.data		= &s3c24xx_uart_drv,
1451 };
1452 #endif /* CONFIG_SERIAL_SAMSUNG_CONSOLE */
1453 
1454 #ifdef CONFIG_CPU_S3C2410
1455 static struct s3c24xx_serial_drv_data s3c2410_serial_drv_data = {
1456 	.info = &(struct s3c24xx_uart_info) {
1457 		.name		= "Samsung S3C2410 UART",
1458 		.type		= PORT_S3C2410,
1459 		.fifosize	= 16,
1460 		.rx_fifomask	= S3C2410_UFSTAT_RXMASK,
1461 		.rx_fifoshift	= S3C2410_UFSTAT_RXSHIFT,
1462 		.rx_fifofull	= S3C2410_UFSTAT_RXFULL,
1463 		.tx_fifofull	= S3C2410_UFSTAT_TXFULL,
1464 		.tx_fifomask	= S3C2410_UFSTAT_TXMASK,
1465 		.tx_fifoshift	= S3C2410_UFSTAT_TXSHIFT,
1466 		.def_clk_sel	= S3C2410_UCON_CLKSEL0,
1467 		.num_clks	= 2,
1468 		.clksel_mask	= S3C2410_UCON_CLKMASK,
1469 		.clksel_shift	= S3C2410_UCON_CLKSHIFT,
1470 	},
1471 	.def_cfg = &(struct s3c2410_uartcfg) {
1472 		.ucon		= S3C2410_UCON_DEFAULT,
1473 		.ufcon		= S3C2410_UFCON_DEFAULT,
1474 	},
1475 };
1476 #define S3C2410_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c2410_serial_drv_data)
1477 #else
1478 #define S3C2410_SERIAL_DRV_DATA (kernel_ulong_t)NULL
1479 #endif
1480 
1481 #ifdef CONFIG_CPU_S3C2412
1482 static struct s3c24xx_serial_drv_data s3c2412_serial_drv_data = {
1483 	.info = &(struct s3c24xx_uart_info) {
1484 		.name		= "Samsung S3C2412 UART",
1485 		.type		= PORT_S3C2412,
1486 		.fifosize	= 64,
1487 		.has_divslot	= 1,
1488 		.rx_fifomask	= S3C2440_UFSTAT_RXMASK,
1489 		.rx_fifoshift	= S3C2440_UFSTAT_RXSHIFT,
1490 		.rx_fifofull	= S3C2440_UFSTAT_RXFULL,
1491 		.tx_fifofull	= S3C2440_UFSTAT_TXFULL,
1492 		.tx_fifomask	= S3C2440_UFSTAT_TXMASK,
1493 		.tx_fifoshift	= S3C2440_UFSTAT_TXSHIFT,
1494 		.def_clk_sel	= S3C2410_UCON_CLKSEL2,
1495 		.num_clks	= 4,
1496 		.clksel_mask	= S3C2412_UCON_CLKMASK,
1497 		.clksel_shift	= S3C2412_UCON_CLKSHIFT,
1498 	},
1499 	.def_cfg = &(struct s3c2410_uartcfg) {
1500 		.ucon		= S3C2410_UCON_DEFAULT,
1501 		.ufcon		= S3C2410_UFCON_DEFAULT,
1502 	},
1503 };
1504 #define S3C2412_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c2412_serial_drv_data)
1505 #else
1506 #define S3C2412_SERIAL_DRV_DATA (kernel_ulong_t)NULL
1507 #endif
1508 
1509 #if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2416) || \
1510 	defined(CONFIG_CPU_S3C2443)
1511 static struct s3c24xx_serial_drv_data s3c2440_serial_drv_data = {
1512 	.info = &(struct s3c24xx_uart_info) {
1513 		.name		= "Samsung S3C2440 UART",
1514 		.type		= PORT_S3C2440,
1515 		.fifosize	= 64,
1516 		.has_divslot	= 1,
1517 		.rx_fifomask	= S3C2440_UFSTAT_RXMASK,
1518 		.rx_fifoshift	= S3C2440_UFSTAT_RXSHIFT,
1519 		.rx_fifofull	= S3C2440_UFSTAT_RXFULL,
1520 		.tx_fifofull	= S3C2440_UFSTAT_TXFULL,
1521 		.tx_fifomask	= S3C2440_UFSTAT_TXMASK,
1522 		.tx_fifoshift	= S3C2440_UFSTAT_TXSHIFT,
1523 		.def_clk_sel	= S3C2410_UCON_CLKSEL2,
1524 		.num_clks	= 4,
1525 		.clksel_mask	= S3C2412_UCON_CLKMASK,
1526 		.clksel_shift	= S3C2412_UCON_CLKSHIFT,
1527 	},
1528 	.def_cfg = &(struct s3c2410_uartcfg) {
1529 		.ucon		= S3C2410_UCON_DEFAULT,
1530 		.ufcon		= S3C2410_UFCON_DEFAULT,
1531 	},
1532 };
1533 #define S3C2440_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c2440_serial_drv_data)
1534 #else
1535 #define S3C2440_SERIAL_DRV_DATA (kernel_ulong_t)NULL
1536 #endif
1537 
1538 #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) || \
1539 	defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450) || \
1540 	defined(CONFIG_CPU_S5PC100)
1541 static struct s3c24xx_serial_drv_data s3c6400_serial_drv_data = {
1542 	.info = &(struct s3c24xx_uart_info) {
1543 		.name		= "Samsung S3C6400 UART",
1544 		.type		= PORT_S3C6400,
1545 		.fifosize	= 64,
1546 		.has_divslot	= 1,
1547 		.rx_fifomask	= S3C2440_UFSTAT_RXMASK,
1548 		.rx_fifoshift	= S3C2440_UFSTAT_RXSHIFT,
1549 		.rx_fifofull	= S3C2440_UFSTAT_RXFULL,
1550 		.tx_fifofull	= S3C2440_UFSTAT_TXFULL,
1551 		.tx_fifomask	= S3C2440_UFSTAT_TXMASK,
1552 		.tx_fifoshift	= S3C2440_UFSTAT_TXSHIFT,
1553 		.def_clk_sel	= S3C2410_UCON_CLKSEL2,
1554 		.num_clks	= 4,
1555 		.clksel_mask	= S3C6400_UCON_CLKMASK,
1556 		.clksel_shift	= S3C6400_UCON_CLKSHIFT,
1557 	},
1558 	.def_cfg = &(struct s3c2410_uartcfg) {
1559 		.ucon		= S3C2410_UCON_DEFAULT,
1560 		.ufcon		= S3C2410_UFCON_DEFAULT,
1561 	},
1562 };
1563 #define S3C6400_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c6400_serial_drv_data)
1564 #else
1565 #define S3C6400_SERIAL_DRV_DATA (kernel_ulong_t)NULL
1566 #endif
1567 
1568 #ifdef CONFIG_CPU_S5PV210
1569 static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
1570 	.info = &(struct s3c24xx_uart_info) {
1571 		.name		= "Samsung S5PV210 UART",
1572 		.type		= PORT_S3C6400,
1573 		.has_divslot	= 1,
1574 		.rx_fifomask	= S5PV210_UFSTAT_RXMASK,
1575 		.rx_fifoshift	= S5PV210_UFSTAT_RXSHIFT,
1576 		.rx_fifofull	= S5PV210_UFSTAT_RXFULL,
1577 		.tx_fifofull	= S5PV210_UFSTAT_TXFULL,
1578 		.tx_fifomask	= S5PV210_UFSTAT_TXMASK,
1579 		.tx_fifoshift	= S5PV210_UFSTAT_TXSHIFT,
1580 		.def_clk_sel	= S3C2410_UCON_CLKSEL0,
1581 		.num_clks	= 2,
1582 		.clksel_mask	= S5PV210_UCON_CLKMASK,
1583 		.clksel_shift	= S5PV210_UCON_CLKSHIFT,
1584 	},
1585 	.def_cfg = &(struct s3c2410_uartcfg) {
1586 		.ucon		= S5PV210_UCON_DEFAULT,
1587 		.ufcon		= S5PV210_UFCON_DEFAULT,
1588 	},
1589 	.fifosize = { 256, 64, 16, 16 },
1590 };
1591 #define S5PV210_SERIAL_DRV_DATA ((kernel_ulong_t)&s5pv210_serial_drv_data)
1592 #else
1593 #define S5PV210_SERIAL_DRV_DATA	(kernel_ulong_t)NULL
1594 #endif
1595 
1596 #if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS4212) || \
1597 	defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250)
1598 static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = {
1599 	.info = &(struct s3c24xx_uart_info) {
1600 		.name		= "Samsung Exynos4 UART",
1601 		.type		= PORT_S3C6400,
1602 		.has_divslot	= 1,
1603 		.rx_fifomask	= S5PV210_UFSTAT_RXMASK,
1604 		.rx_fifoshift	= S5PV210_UFSTAT_RXSHIFT,
1605 		.rx_fifofull	= S5PV210_UFSTAT_RXFULL,
1606 		.tx_fifofull	= S5PV210_UFSTAT_TXFULL,
1607 		.tx_fifomask	= S5PV210_UFSTAT_TXMASK,
1608 		.tx_fifoshift	= S5PV210_UFSTAT_TXSHIFT,
1609 		.def_clk_sel	= S3C2410_UCON_CLKSEL0,
1610 		.num_clks	= 1,
1611 		.clksel_mask	= 0,
1612 		.clksel_shift	= 0,
1613 	},
1614 	.def_cfg = &(struct s3c2410_uartcfg) {
1615 		.ucon		= S5PV210_UCON_DEFAULT,
1616 		.ufcon		= S5PV210_UFCON_DEFAULT,
1617 		.has_fracval	= 1,
1618 	},
1619 	.fifosize = { 256, 64, 16, 16 },
1620 };
1621 #define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos4210_serial_drv_data)
1622 #else
1623 #define EXYNOS4210_SERIAL_DRV_DATA (kernel_ulong_t)NULL
1624 #endif
1625 
1626 static struct platform_device_id s3c24xx_serial_driver_ids[] = {
1627 	{
1628 		.name		= "s3c2410-uart",
1629 		.driver_data	= S3C2410_SERIAL_DRV_DATA,
1630 	}, {
1631 		.name		= "s3c2412-uart",
1632 		.driver_data	= S3C2412_SERIAL_DRV_DATA,
1633 	}, {
1634 		.name		= "s3c2440-uart",
1635 		.driver_data	= S3C2440_SERIAL_DRV_DATA,
1636 	}, {
1637 		.name		= "s3c6400-uart",
1638 		.driver_data	= S3C6400_SERIAL_DRV_DATA,
1639 	}, {
1640 		.name		= "s5pv210-uart",
1641 		.driver_data	= S5PV210_SERIAL_DRV_DATA,
1642 	}, {
1643 		.name		= "exynos4210-uart",
1644 		.driver_data	= EXYNOS4210_SERIAL_DRV_DATA,
1645 	},
1646 	{ },
1647 };
1648 MODULE_DEVICE_TABLE(platform, s3c24xx_serial_driver_ids);
1649 
1650 #ifdef CONFIG_OF
1651 static const struct of_device_id s3c24xx_uart_dt_match[] = {
1652 	{ .compatible = "samsung,exynos4210-uart",
1653 		.data = (void *)EXYNOS4210_SERIAL_DRV_DATA },
1654 	{},
1655 };
1656 MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match);
1657 #else
1658 #define s3c24xx_uart_dt_match NULL
1659 #endif
1660 
1661 static struct platform_driver samsung_serial_driver = {
1662 	.probe		= s3c24xx_serial_probe,
1663 	.remove		= __devexit_p(s3c24xx_serial_remove),
1664 	.id_table	= s3c24xx_serial_driver_ids,
1665 	.driver		= {
1666 		.name	= "samsung-uart",
1667 		.owner	= THIS_MODULE,
1668 		.pm	= SERIAL_SAMSUNG_PM_OPS,
1669 		.of_match_table	= s3c24xx_uart_dt_match,
1670 	},
1671 };
1672 
1673 /* module initialisation code */
1674 
s3c24xx_serial_modinit(void)1675 static int __init s3c24xx_serial_modinit(void)
1676 {
1677 	int ret;
1678 
1679 	ret = uart_register_driver(&s3c24xx_uart_drv);
1680 	if (ret < 0) {
1681 		printk(KERN_ERR "failed to register UART driver\n");
1682 		return -1;
1683 	}
1684 
1685 	return platform_driver_register(&samsung_serial_driver);
1686 }
1687 
s3c24xx_serial_modexit(void)1688 static void __exit s3c24xx_serial_modexit(void)
1689 {
1690 	uart_unregister_driver(&s3c24xx_uart_drv);
1691 }
1692 
1693 module_init(s3c24xx_serial_modinit);
1694 module_exit(s3c24xx_serial_modexit);
1695 
1696 MODULE_ALIAS("platform:samsung-uart");
1697 MODULE_DESCRIPTION("Samsung SoC Serial port driver");
1698 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
1699 MODULE_LICENSE("GPL v2");
1700