Root/target/linux/ar71xx/patches-3.2/014-SERIAL-AR933X-Add-driver-for-the-built-in-UART-of-th.patch

1From 1de387abd06fb67aaa8e27a48e378ffd9aaddd74 Mon Sep 17 00:00:00 2001
2From: Gabor Juhos <juhosg@openwrt.org>
3Date: Mon, 20 Jun 2011 19:26:11 +0200
4Subject: [PATCH 14/27] SERIAL: AR933X: Add driver for the built-in UART of the SoC
5
6This patch adds the driver for the built-in UART of the
7Atheros AR933X SoCs.
8
9Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
10Cc: linux-mips@linux-mips.org
11Cc: Kathy Giori <kgiori@qca.qualcomm.com>
12Cc: "Luis R. Rodriguez" <rodrigue@qca.qualcomm.com>
13Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
14Cc: linux-serial@vger.kernel.org
15Patchwork: https://patchwork.linux-mips.org/patch/2526/
16Signed-off-by: Alan Cox <alan@linux.intel.com>
17Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
18---
19 .../include/asm/mach-ath79/ar933x_uart_platform.h | 18 +
20 drivers/tty/serial/Kconfig | 23 +
21 drivers/tty/serial/Makefile | 1 +
22 drivers/tty/serial/ar933x_uart.c | 688 ++++++++++++++++++++
23 include/linux/serial_core.h | 4 +
24 5 files changed, 734 insertions(+), 0 deletions(-)
25 create mode 100644 arch/mips/include/asm/mach-ath79/ar933x_uart_platform.h
26 create mode 100644 drivers/tty/serial/ar933x_uart.c
27
28--- /dev/null
29+++ b/arch/mips/include/asm/mach-ath79/ar933x_uart_platform.h
30@@ -0,0 +1,18 @@
31+/*
32+ * Platform data definition for Atheros AR933X UART
33+ *
34+ * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
35+ *
36+ * This program is free software; you can redistribute it and/or modify it
37+ * under the terms of the GNU General Public License version 2 as published
38+ * by the Free Software Foundation.
39+ */
40+
41+#ifndef _AR933X_UART_PLATFORM_H
42+#define _AR933X_UART_PLATFORM_H
43+
44+struct ar933x_uart_platform_data {
45+ unsigned uartclk;
46+};
47+
48+#endif /* _AR933X_UART_PLATFORM_H */
49--- a/drivers/tty/serial/Kconfig
50+++ b/drivers/tty/serial/Kconfig
51@@ -1610,4 +1610,27 @@ config SERIAL_XILINX_PS_UART_CONSOLE
52     help
53       Enable a Xilinx PS UART port to be the system console.
54 
55+config SERIAL_AR933X
56+ bool "AR933X serial port support"
57+ depends on SOC_AR933X
58+ select SERIAL_CORE
59+ help
60+ If you have an Atheros AR933X SOC based board and want to use the
61+ built-in UART of the SoC, say Y to this option.
62+
63+config SERIAL_AR933X_CONSOLE
64+ bool "Console on AR933X serial port"
65+ depends on SERIAL_AR933X=y
66+ select SERIAL_CORE_CONSOLE
67+ help
68+ Enable a built-in UART port of the AR933X to be the system console.
69+
70+config SERIAL_AR933X_NR_UARTS
71+ int "Maximum number of AR933X serial ports"
72+ depends on SERIAL_AR933X
73+ default "2"
74+ help
75+ Set this to the number of serial ports you want the driver
76+ to support.
77+
78 endmenu
79--- a/drivers/tty/serial/Makefile
80+++ b/drivers/tty/serial/Makefile
81@@ -94,3 +94,4 @@ obj-$(CONFIG_SERIAL_MSM_SMD) += msm_smd_
82 obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o
83 obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o
84 obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o
85+obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o
86--- /dev/null
87+++ b/drivers/tty/serial/ar933x_uart.c
88@@ -0,0 +1,688 @@
89+/*
90+ * Atheros AR933X SoC built-in UART driver
91+ *
92+ * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
93+ *
94+ * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
95+ *
96+ * This program is free software; you can redistribute it and/or modify it
97+ * under the terms of the GNU General Public License version 2 as published
98+ * by the Free Software Foundation.
99+ */
100+
101+#include <linux/module.h>
102+#include <linux/ioport.h>
103+#include <linux/init.h>
104+#include <linux/console.h>
105+#include <linux/sysrq.h>
106+#include <linux/delay.h>
107+#include <linux/platform_device.h>
108+#include <linux/tty.h>
109+#include <linux/tty_flip.h>
110+#include <linux/serial_core.h>
111+#include <linux/serial.h>
112+#include <linux/slab.h>
113+#include <linux/io.h>
114+#include <linux/irq.h>
115+
116+#include <asm/mach-ath79/ar933x_uart.h>
117+#include <asm/mach-ath79/ar933x_uart_platform.h>
118+
119+#define DRIVER_NAME "ar933x-uart"
120+
121+#define AR933X_DUMMY_STATUS_RD 0x01
122+
123+static struct uart_driver ar933x_uart_driver;
124+
125+struct ar933x_uart_port {
126+ struct uart_port port;
127+ unsigned int ier; /* shadow Interrupt Enable Register */
128+};
129+
130+static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up,
131+ int offset)
132+{
133+ return readl(up->port.membase + offset);
134+}
135+
136+static inline void ar933x_uart_write(struct ar933x_uart_port *up,
137+ int offset, unsigned int value)
138+{
139+ writel(value, up->port.membase + offset);
140+}
141+
142+static inline void ar933x_uart_rmw(struct ar933x_uart_port *up,
143+ unsigned int offset,
144+ unsigned int mask,
145+ unsigned int val)
146+{
147+ unsigned int t;
148+
149+ t = ar933x_uart_read(up, offset);
150+ t &= ~mask;
151+ t |= val;
152+ ar933x_uart_write(up, offset, t);
153+}
154+
155+static inline void ar933x_uart_rmw_set(struct ar933x_uart_port *up,
156+ unsigned int offset,
157+ unsigned int val)
158+{
159+ ar933x_uart_rmw(up, offset, 0, val);
160+}
161+
162+static inline void ar933x_uart_rmw_clear(struct ar933x_uart_port *up,
163+ unsigned int offset,
164+ unsigned int val)
165+{
166+ ar933x_uart_rmw(up, offset, val, 0);
167+}
168+
169+static inline void ar933x_uart_start_tx_interrupt(struct ar933x_uart_port *up)
170+{
171+ up->ier |= AR933X_UART_INT_TX_EMPTY;
172+ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
173+}
174+
175+static inline void ar933x_uart_stop_tx_interrupt(struct ar933x_uart_port *up)
176+{
177+ up->ier &= ~AR933X_UART_INT_TX_EMPTY;
178+ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
179+}
180+
181+static inline void ar933x_uart_putc(struct ar933x_uart_port *up, int ch)
182+{
183+ unsigned int rdata;
184+
185+ rdata = ch & AR933X_UART_DATA_TX_RX_MASK;
186+ rdata |= AR933X_UART_DATA_TX_CSR;
187+ ar933x_uart_write(up, AR933X_UART_DATA_REG, rdata);
188+}
189+
190+static unsigned int ar933x_uart_tx_empty(struct uart_port *port)
191+{
192+ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
193+ unsigned long flags;
194+ unsigned int rdata;
195+
196+ spin_lock_irqsave(&up->port.lock, flags);
197+ rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG);
198+ spin_unlock_irqrestore(&up->port.lock, flags);
199+
200+ return (rdata & AR933X_UART_DATA_TX_CSR) ? 0 : TIOCSER_TEMT;
201+}
202+
203+static unsigned int ar933x_uart_get_mctrl(struct uart_port *port)
204+{
205+ return TIOCM_CAR;
206+}
207+
208+static void ar933x_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
209+{
210+}
211+
212+static void ar933x_uart_start_tx(struct uart_port *port)
213+{
214+ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
215+
216+ ar933x_uart_start_tx_interrupt(up);
217+}
218+
219+static void ar933x_uart_stop_tx(struct uart_port *port)
220+{
221+ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
222+
223+ ar933x_uart_stop_tx_interrupt(up);
224+}
225+
226+static void ar933x_uart_stop_rx(struct uart_port *port)
227+{
228+ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
229+
230+ up->ier &= ~AR933X_UART_INT_RX_VALID;
231+ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
232+}
233+
234+static void ar933x_uart_break_ctl(struct uart_port *port, int break_state)
235+{
236+ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
237+ unsigned long flags;
238+
239+ spin_lock_irqsave(&up->port.lock, flags);
240+ if (break_state == -1)
241+ ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
242+ AR933X_UART_CS_TX_BREAK);
243+ else
244+ ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG,
245+ AR933X_UART_CS_TX_BREAK);
246+ spin_unlock_irqrestore(&up->port.lock, flags);
247+}
248+
249+static void ar933x_uart_enable_ms(struct uart_port *port)
250+{
251+}
252+
253+static void ar933x_uart_set_termios(struct uart_port *port,
254+ struct ktermios *new,
255+ struct ktermios *old)
256+{
257+ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
258+ unsigned int cs;
259+ unsigned long flags;
260+ unsigned int baud, scale;
261+
262+ /* Only CS8 is supported */
263+ new->c_cflag &= ~CSIZE;
264+ new->c_cflag |= CS8;
265+
266+ /* Only one stop bit is supported */
267+ new->c_cflag &= ~CSTOPB;
268+
269+ cs = 0;
270+ if (new->c_cflag & PARENB) {
271+ if (!(new->c_cflag & PARODD))
272+ cs |= AR933X_UART_CS_PARITY_EVEN;
273+ else
274+ cs |= AR933X_UART_CS_PARITY_ODD;
275+ } else {
276+ cs |= AR933X_UART_CS_PARITY_NONE;
277+ }
278+
279+ /* Mark/space parity is not supported */
280+ new->c_cflag &= ~CMSPAR;
281+
282+ baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16);
283+ scale = (port->uartclk / (16 * baud)) - 1;
284+
285+ /*
286+ * Ok, we're now changing the port state. Do it with
287+ * interrupts disabled.
288+ */
289+ spin_lock_irqsave(&up->port.lock, flags);
290+
291+ /* Update the per-port timeout. */
292+ uart_update_timeout(port, new->c_cflag, baud);
293+
294+ up->port.ignore_status_mask = 0;
295+
296+ /* ignore all characters if CREAD is not set */
297+ if ((new->c_cflag & CREAD) == 0)
298+ up->port.ignore_status_mask |= AR933X_DUMMY_STATUS_RD;
299+
300+ ar933x_uart_write(up, AR933X_UART_CLOCK_REG,
301+ scale << AR933X_UART_CLOCK_SCALE_S | 8192);
302+
303+ /* setup configuration register */
304+ ar933x_uart_rmw(up, AR933X_UART_CS_REG, AR933X_UART_CS_PARITY_M, cs);
305+
306+ /* enable host interrupt */
307+ ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
308+ AR933X_UART_CS_HOST_INT_EN);
309+
310+ spin_unlock_irqrestore(&up->port.lock, flags);
311+
312+ if (tty_termios_baud_rate(new))
313+ tty_termios_encode_baud_rate(new, baud, baud);
314+}
315+
316+static void ar933x_uart_rx_chars(struct ar933x_uart_port *up)
317+{
318+ struct tty_struct *tty;
319+ int max_count = 256;
320+
321+ tty = tty_port_tty_get(&up->port.state->port);
322+ do {
323+ unsigned int rdata;
324+ unsigned char ch;
325+
326+ rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG);
327+ if ((rdata & AR933X_UART_DATA_RX_CSR) == 0)
328+ break;
329+
330+ /* remove the character from the FIFO */
331+ ar933x_uart_write(up, AR933X_UART_DATA_REG,
332+ AR933X_UART_DATA_RX_CSR);
333+
334+ if (!tty) {
335+ /* discard the data if no tty available */
336+ continue;
337+ }
338+
339+ up->port.icount.rx++;
340+ ch = rdata & AR933X_UART_DATA_TX_RX_MASK;
341+
342+ if (uart_handle_sysrq_char(&up->port, ch))
343+ continue;
344+
345+ if ((up->port.ignore_status_mask & AR933X_DUMMY_STATUS_RD) == 0)
346+ tty_insert_flip_char(tty, ch, TTY_NORMAL);
347+ } while (max_count-- > 0);
348+
349+ if (tty) {
350+ tty_flip_buffer_push(tty);
351+ tty_kref_put(tty);
352+ }
353+}
354+
355+static void ar933x_uart_tx_chars(struct ar933x_uart_port *up)
356+{
357+ struct circ_buf *xmit = &up->port.state->xmit;
358+ int count;
359+
360+ if (uart_tx_stopped(&up->port))
361+ return;
362+
363+ count = up->port.fifosize;
364+ do {
365+ unsigned int rdata;
366+
367+ rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG);
368+ if ((rdata & AR933X_UART_DATA_TX_CSR) == 0)
369+ break;
370+
371+ if (up->port.x_char) {
372+ ar933x_uart_putc(up, up->port.x_char);
373+ up->port.icount.tx++;
374+ up->port.x_char = 0;
375+ continue;
376+ }
377+
378+ if (uart_circ_empty(xmit))
379+ break;
380+
381+ ar933x_uart_putc(up, xmit->buf[xmit->tail]);
382+
383+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
384+ up->port.icount.tx++;
385+ } while (--count > 0);
386+
387+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
388+ uart_write_wakeup(&up->port);
389+
390+ if (!uart_circ_empty(xmit))
391+ ar933x_uart_start_tx_interrupt(up);
392+}
393+
394+static irqreturn_t ar933x_uart_interrupt(int irq, void *dev_id)
395+{
396+ struct ar933x_uart_port *up = dev_id;
397+ unsigned int status;
398+
399+ status = ar933x_uart_read(up, AR933X_UART_CS_REG);
400+ if ((status & AR933X_UART_CS_HOST_INT) == 0)
401+ return IRQ_NONE;
402+
403+ spin_lock(&up->port.lock);
404+
405+ status = ar933x_uart_read(up, AR933X_UART_INT_REG);
406+ status &= ar933x_uart_read(up, AR933X_UART_INT_EN_REG);
407+
408+ if (status & AR933X_UART_INT_RX_VALID) {
409+ ar933x_uart_write(up, AR933X_UART_INT_REG,
410+ AR933X_UART_INT_RX_VALID);
411+ ar933x_uart_rx_chars(up);
412+ }
413+
414+ if (status & AR933X_UART_INT_TX_EMPTY) {
415+ ar933x_uart_write(up, AR933X_UART_INT_REG,
416+ AR933X_UART_INT_TX_EMPTY);
417+ ar933x_uart_stop_tx_interrupt(up);
418+ ar933x_uart_tx_chars(up);
419+ }
420+
421+ spin_unlock(&up->port.lock);
422+
423+ return IRQ_HANDLED;
424+}
425+
426+static int ar933x_uart_startup(struct uart_port *port)
427+{
428+ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
429+ unsigned long flags;
430+ int ret;
431+
432+ ret = request_irq(up->port.irq, ar933x_uart_interrupt,
433+ up->port.irqflags, dev_name(up->port.dev), up);
434+ if (ret)
435+ return ret;
436+
437+ spin_lock_irqsave(&up->port.lock, flags);
438+
439+ /* Enable HOST interrupts */
440+ ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
441+ AR933X_UART_CS_HOST_INT_EN);
442+
443+ /* Enable RX interrupts */
444+ up->ier = AR933X_UART_INT_RX_VALID;
445+ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
446+
447+ spin_unlock_irqrestore(&up->port.lock, flags);
448+
449+ return 0;
450+}
451+
452+static void ar933x_uart_shutdown(struct uart_port *port)
453+{
454+ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
455+
456+ /* Disable all interrupts */
457+ up->ier = 0;
458+ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
459+
460+ /* Disable break condition */
461+ ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG,
462+ AR933X_UART_CS_TX_BREAK);
463+
464+ free_irq(up->port.irq, up);
465+}
466+
467+static const char *ar933x_uart_type(struct uart_port *port)
468+{
469+ return (port->type == PORT_AR933X) ? "AR933X UART" : NULL;
470+}
471+
472+static void ar933x_uart_release_port(struct uart_port *port)
473+{
474+ /* Nothing to release ... */
475+}
476+
477+static int ar933x_uart_request_port(struct uart_port *port)
478+{
479+ /* UARTs always present */
480+ return 0;
481+}
482+
483+static void ar933x_uart_config_port(struct uart_port *port, int flags)
484+{
485+ if (flags & UART_CONFIG_TYPE)
486+ port->type = PORT_AR933X;
487+}
488+
489+static int ar933x_uart_verify_port(struct uart_port *port,
490+ struct serial_struct *ser)
491+{
492+ if (ser->type != PORT_UNKNOWN &&
493+ ser->type != PORT_AR933X)
494+ return -EINVAL;
495+
496+ if (ser->irq < 0 || ser->irq >= NR_IRQS)
497+ return -EINVAL;
498+
499+ if (ser->baud_base < 28800)
500+ return -EINVAL;
501+
502+ return 0;
503+}
504+
505+static struct uart_ops ar933x_uart_ops = {
506+ .tx_empty = ar933x_uart_tx_empty,
507+ .set_mctrl = ar933x_uart_set_mctrl,
508+ .get_mctrl = ar933x_uart_get_mctrl,
509+ .stop_tx = ar933x_uart_stop_tx,
510+ .start_tx = ar933x_uart_start_tx,
511+ .stop_rx = ar933x_uart_stop_rx,
512+ .enable_ms = ar933x_uart_enable_ms,
513+ .break_ctl = ar933x_uart_break_ctl,
514+ .startup = ar933x_uart_startup,
515+ .shutdown = ar933x_uart_shutdown,
516+ .set_termios = ar933x_uart_set_termios,
517+ .type = ar933x_uart_type,
518+ .release_port = ar933x_uart_release_port,
519+ .request_port = ar933x_uart_request_port,
520+ .config_port = ar933x_uart_config_port,
521+ .verify_port = ar933x_uart_verify_port,
522+};
523+
524+#ifdef CONFIG_SERIAL_AR933X_CONSOLE
525+
526+static struct ar933x_uart_port *
527+ar933x_console_ports[CONFIG_SERIAL_AR933X_NR_UARTS];
528+
529+static void ar933x_uart_wait_xmitr(struct ar933x_uart_port *up)
530+{
531+ unsigned int status;
532+ unsigned int timeout = 60000;
533+
534+ /* Wait up to 60ms for the character(s) to be sent. */
535+ do {
536+ status = ar933x_uart_read(up, AR933X_UART_DATA_REG);
537+ if (--timeout == 0)
538+ break;
539+ udelay(1);
540+ } while ((status & AR933X_UART_DATA_TX_CSR) == 0);
541+}
542+
543+static void ar933x_uart_console_putchar(struct uart_port *port, int ch)
544+{
545+ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
546+
547+ ar933x_uart_wait_xmitr(up);
548+ ar933x_uart_putc(up, ch);
549+}
550+
551+static void ar933x_uart_console_write(struct console *co, const char *s,
552+ unsigned int count)
553+{
554+ struct ar933x_uart_port *up = ar933x_console_ports[co->index];
555+ unsigned long flags;
556+ unsigned int int_en;
557+ int locked = 1;
558+
559+ local_irq_save(flags);
560+
561+ if (up->port.sysrq)
562+ locked = 0;
563+ else if (oops_in_progress)
564+ locked = spin_trylock(&up->port.lock);
565+ else
566+ spin_lock(&up->port.lock);
567+
568+ /*
569+ * First save the IER then disable the interrupts
570+ */
571+ int_en = ar933x_uart_read(up, AR933X_UART_INT_EN_REG);
572+ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, 0);
573+
574+ uart_console_write(&up->port, s, count, ar933x_uart_console_putchar);
575+
576+ /*
577+ * Finally, wait for transmitter to become empty
578+ * and restore the IER
579+ */
580+ ar933x_uart_wait_xmitr(up);
581+ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, int_en);
582+
583+ ar933x_uart_write(up, AR933X_UART_INT_REG, AR933X_UART_INT_ALLINTS);
584+
585+ if (locked)
586+ spin_unlock(&up->port.lock);
587+
588+ local_irq_restore(flags);
589+}
590+
591+static int ar933x_uart_console_setup(struct console *co, char *options)
592+{
593+ struct ar933x_uart_port *up;
594+ int baud = 115200;
595+ int bits = 8;
596+ int parity = 'n';
597+ int flow = 'n';
598+
599+ if (co->index < 0 || co->index >= CONFIG_SERIAL_AR933X_NR_UARTS)
600+ return -EINVAL;
601+
602+ up = ar933x_console_ports[co->index];
603+ if (!up)
604+ return -ENODEV;
605+
606+ if (options)
607+ uart_parse_options(options, &baud, &parity, &bits, &flow);
608+
609+ return uart_set_options(&up->port, co, baud, parity, bits, flow);
610+}
611+
612+static struct console ar933x_uart_console = {
613+ .name = "ttyATH",
614+ .write = ar933x_uart_console_write,
615+ .device = uart_console_device,
616+ .setup = ar933x_uart_console_setup,
617+ .flags = CON_PRINTBUFFER,
618+ .index = -1,
619+ .data = &ar933x_uart_driver,
620+};
621+
622+static void ar933x_uart_add_console_port(struct ar933x_uart_port *up)
623+{
624+ ar933x_console_ports[up->port.line] = up;
625+}
626+
627+#define AR933X_SERIAL_CONSOLE (&ar933x_uart_console)
628+
629+#else
630+
631+static inline void ar933x_uart_add_console_port(struct ar933x_uart_port *up) {}
632+
633+#define AR933X_SERIAL_CONSOLE NULL
634+
635+#endif /* CONFIG_SERIAL_AR933X_CONSOLE */
636+
637+static struct uart_driver ar933x_uart_driver = {
638+ .owner = THIS_MODULE,
639+ .driver_name = DRIVER_NAME,
640+ .dev_name = "ttyATH",
641+ .nr = CONFIG_SERIAL_AR933X_NR_UARTS,
642+ .cons = AR933X_SERIAL_CONSOLE,
643+};
644+
645+static int __devinit ar933x_uart_probe(struct platform_device *pdev)
646+{
647+ struct ar933x_uart_platform_data *pdata;
648+ struct ar933x_uart_port *up;
649+ struct uart_port *port;
650+ struct resource *mem_res;
651+ struct resource *irq_res;
652+ int id;
653+ int ret;
654+
655+ pdata = pdev->dev.platform_data;
656+ if (!pdata)
657+ return -EINVAL;
658+
659+ id = pdev->id;
660+ if (id == -1)
661+ id = 0;
662+
663+ if (id > CONFIG_SERIAL_AR933X_NR_UARTS)
664+ return -EINVAL;
665+
666+ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
667+ if (!mem_res) {
668+ dev_err(&pdev->dev, "no MEM resource\n");
669+ return -EINVAL;
670+ }
671+
672+ irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
673+ if (!irq_res) {
674+ dev_err(&pdev->dev, "no IRQ resource\n");
675+ return -EINVAL;
676+ }
677+
678+ up = kzalloc(sizeof(struct ar933x_uart_port), GFP_KERNEL);
679+ if (!up)
680+ return -ENOMEM;
681+
682+ port = &up->port;
683+ port->mapbase = mem_res->start;
684+
685+ port->membase = ioremap(mem_res->start, AR933X_UART_REGS_SIZE);
686+ if (!port->membase) {
687+ ret = -ENOMEM;
688+ goto err_free_up;
689+ }
690+
691+ port->line = id;
692+ port->irq = irq_res->start;
693+ port->dev = &pdev->dev;
694+ port->type = PORT_AR933X;
695+ port->iotype = UPIO_MEM32;
696+ port->uartclk = pdata->uartclk;
697+
698+ port->regshift = 2;
699+ port->fifosize = AR933X_UART_FIFO_SIZE;
700+ port->ops = &ar933x_uart_ops;
701+
702+ ar933x_uart_add_console_port(up);
703+
704+ ret = uart_add_one_port(&ar933x_uart_driver, &up->port);
705+ if (ret)
706+ goto err_unmap;
707+
708+ platform_set_drvdata(pdev, up);
709+ return 0;
710+
711+err_unmap:
712+ iounmap(up->port.membase);
713+err_free_up:
714+ kfree(up);
715+ return ret;
716+}
717+
718+static int __devexit ar933x_uart_remove(struct platform_device *pdev)
719+{
720+ struct ar933x_uart_port *up;
721+
722+ up = platform_get_drvdata(pdev);
723+ platform_set_drvdata(pdev, NULL);
724+
725+ if (up) {
726+ uart_remove_one_port(&ar933x_uart_driver, &up->port);
727+ iounmap(up->port.membase);
728+ kfree(up);
729+ }
730+
731+ return 0;
732+}
733+
734+static struct platform_driver ar933x_uart_platform_driver = {
735+ .probe = ar933x_uart_probe,
736+ .remove = __devexit_p(ar933x_uart_remove),
737+ .driver = {
738+ .name = DRIVER_NAME,
739+ .owner = THIS_MODULE,
740+ },
741+};
742+
743+static int __init ar933x_uart_init(void)
744+{
745+ int ret;
746+
747+ ar933x_uart_driver.nr = CONFIG_SERIAL_AR933X_NR_UARTS;
748+ ret = uart_register_driver(&ar933x_uart_driver);
749+ if (ret)
750+ goto err_out;
751+
752+ ret = platform_driver_register(&ar933x_uart_platform_driver);
753+ if (ret)
754+ goto err_unregister_uart_driver;
755+
756+ return 0;
757+
758+err_unregister_uart_driver:
759+ uart_unregister_driver(&ar933x_uart_driver);
760+err_out:
761+ return ret;
762+}
763+
764+static void __exit ar933x_uart_exit(void)
765+{
766+ platform_driver_unregister(&ar933x_uart_platform_driver);
767+ uart_unregister_driver(&ar933x_uart_driver);
768+}
769+
770+module_init(ar933x_uart_init);
771+module_exit(ar933x_uart_exit);
772+
773+MODULE_DESCRIPTION("Atheros AR933X UART driver");
774+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
775+MODULE_LICENSE("GPL v2");
776+MODULE_ALIAS("platform:" DRIVER_NAME);
777--- a/include/linux/serial_core.h
778+++ b/include/linux/serial_core.h
779@@ -207,6 +207,10 @@
780 /* Xilinx PSS UART */
781 #define PORT_XUARTPS 98
782 
783+/* Atheros AR933X SoC */
784+#define PORT_AR933X 99
785+
786+
787 #ifdef __KERNEL__
788 
789 #include <linux/compiler.h>
790

Archive Download this file



interactive